ZGlmZiAtLWdpdCBhL3N0ZC9saXZpbmcvYXR0cmlidXRlcy5jIGIvc3RkL2xpdmluZy9hdHRyaWJ1dGVzLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTAwMjdhNAotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9saXZpbmcvYXR0cmlidXRlcy5jCkBAIC0wLDAgKzEsNjcxIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gbGl2aW5nL2F0dHJpYnV0ZXMuYyAtLSBhdHRyaWJ1dGVzIGZvciBsaXZpbmcgb2JqZWN0cworLy8KKy8vICRJZDogYXR0cmlidXRlcy5jIDgzNzUgMjAxMy0wMi0xMiAyMTo1Mjo1OFogWmVzc3RyYSAkCisKKyNpbmNsdWRlIDxzeXNfZGVidWcuaD4KKworLy8gYXR0cmlidXRlIGhhbmRsaW5nCisvLworLy8gICBmaWx0ZXJfbGRmaWVkOiBzdHIsIGRleCwgY29uLCBpbnQKKy8vCisvLyBJbiBkZW4gQXR0cmlidXRlbiB1bmQgQWJpbGl0ZXMgd2VyZGVuIFJhc3NlbnNwemlmaXNjaGUgdW5kIGVyd29yYmVuZQorLy8gRmFlaGlna2VpdGVuIChtaXQgYXV0b2xvYWQtRWlnZW5zY2hhZnQpIGFiZ2Vwc2VpY2hlcnQuCisvLworLy8gRnVua3Rpb25lbjoKKy8vICAgU2V0QXR0cmlidXRlKCBhdHRyLCB2YWwgKSAoRXJ6ZXVnZSB1bmQpIHNldHplIGRhcyBBdHRyaWJ1dCBhdWYgdmFsLgorLy8gICBRdWVyeUF0dHJpYnV0ZSggYXR0ciApICAgIEdlYmUgZGVuIFdlcnQgZGVzIEF0dHJpYnV0ZXMgenVydWVjay4KKy8vCisvLyAgIFdlbm4gZWluIE9iamVrdCBlaW5lIEZ1bmt0aW9uIF9maWx0ZXJhdHRyXzxuYW1lPiBiZWl0enQsIHdpcmQgYmVpbSBTZXR6ZW4KKy8vICAgZGVzIEF0dHJpYnV0ZXMgPG5hbWU+LCBkZXIgdm9yZ2VzY2hsYWdlbmUgV2VydCB1ZWJlcmdlYmVuIHVuZCBkZXIgdm9uCisvLyAgIGRpZXNlciBGdW5rdGlvbiB6dXJ1ZWNrZ2VnZWJlbmUgZ2VzZXR6dC4gKGZ1ZXIgdWViZXJwcnVlZnVuZ3N6d2Vja2UpCisvLyAgIEdsZWljaGVzIGdpbHQgZnVlciBfZmlsdGVyYWJpbF88bmFtZT4uCisKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8YXR0cmlidXRlcy5oPgorI2luY2x1ZGUgPHBsYXllci9nbWNwLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDxjb25maWcuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisKK21hcHBpbmcgYXR0cmlidXRlczsgLy8gRGllcyBzaW5kIGRpZSBtaXQgWlRzIHZlcmFlbmRlcmJhcmVuIEF0dHJpYnV0ZQorbWFwcGluZyBhdHRyaWJ1dGVzX21vZGlmaWVyOyAvLyBNb2RpZmllciBzb2xsZW4gZ2VzcGVpY2hlcnQgd2VyZGVuCitub3NhdmUgbWl4ZWQqIGF0dHJpYnV0ZXNfdGltZWRfbW9kczsgLy9QX1RJTUVEX0FUVFJfTU9ECitub3NhdmUgbWFwcGluZyBhdHRyaWJ1dGVzX29mZnNldHM7IC8vIE9mZnNldHMgTklDSFQgc3BlaWNoZXJuIQorbm9zYXZlIG1hcHBpbmcgdXNlZF9hdHRyaWJ1dGVzX29mZnNldHM7IC8vIFp1ciBCZXNjaGxldW5pZ3VuZyBkZXIgQmVyZWNobnVuZworbm9zYXZlIG9iamVjdCogYWxsX21vZGlmaWVyczsgLy8gb2JqZWt0ZSBtaXQgUF9YL01fQVRUUl9NT0QsIFBfWC9NX0hFQUxUSF9NT0QKK25vc2F2ZSBvYmplY3QqIGludmFsaWRfbW9kaWZpZXJzOyAvLyBvYmpla3RlIHdlbGNoZSBkYXMgbGltaXQgdWViZXJzY2hyZWl0ZW4KK25vc2F2ZSBpbnQgY3VtdWxhdGl2ZV9tb2Q7IC8vIGJpbGFueiBkZXIgUF9YL01fQVRUUl9NT0QKK25vc2F2ZSBpbnQgaHBfb2ZmOworbm9zYXZlIGludCBzcF9vZmY7CisKKworbm9tYXNrIHB1YmxpYyBpbnQgU2V0VGltZWRBdHRyTW9kaWZpZXIoc3RyaW5nIGtleSwgbWFwcGluZyBtb2RpZmllciwgCisgICAgaW50IG91dGRhdGVkLCBvYmplY3QgZGVwZW5kZW50LCBtaXhlZCBub3RpZnkpIHsKKyAgaWYoIWtleSB8fCBrZXk9PSIiIHx8ICFtb2RpZmllciB8fCAob3V0ZGF0ZWQ+MCAmJiBvdXRkYXRlZDx0aW1lKCkpIHx8IAorICAgICAgKG5vdGlmeSAmJiAhc3RyaW5ncChub3RpZnkpICYmICFvYmplY3RwKG5vdGlmeSkpICkgeworICAgIHJldHVybiBUQVRUUl9JTlZBTElEX0FSR1M7CisgIH0KKyAgCisgIAorICBpZihtZW1iZXIoYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX0VOVFJJRVNdLGtleSkpIHsKKyAgICAvLyBjaGFuZ2UgZW50cnkKKyAgICBhdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfRU5UUklFU11ba2V5LFRBVFRSX01PRF09bW9kaWZpZXI7CisgICAgYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX0VOVFJJRVNdW2tleSxUQVRUUl9PVVREQVRFRF09b3V0ZGF0ZWQ7CisgICAgYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX0VOVFJJRVNdW2tleSxUQVRUUl9ERVBFTkRFTlRdPWRlcGVuZGVudDsKKyAgICBhdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfRU5UUklFU11ba2V5LFRBVFRSX05PVElGWV09bm90aWZ5OworICB9CisgIGVsc2UgeworICAgIC8vIGFkZCBlbnRyeQorICAgIGF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9FTlRSSUVTXSs9KFtrZXk6bW9kaWZpZXI7b3V0ZGF0ZWQ7ZGVwZW5kZW50O25vdGlmeV0pOworICB9CisgIAorICAvLyBhZGQgb3V0ZGF0ZQorICBpZihvdXRkYXRlZD4wICYmIG1lbWJlcihhdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfT1VUREFURV0sb3V0ZGF0ZWQpPT0tMSkKKyAgeworICAgIGF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9PVVREQVRFXSs9KHtvdXRkYXRlZH0pOworICAgIGF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9PVVREQVRFXT0KKyAgICAgIHNvcnRfYXJyYXkoYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX09VVERBVEVdLCMnPCk7CisgIH0KKyAgCisgIC8vIGFkZCBkZXBlbmRlbnQKKyAgaWYob2JqZWN0cChkZXBlbmRlbnQpKQorICB7CisgIAlpZihtZW1iZXIoYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX0RFUEVOREVOVFNdLGtleSkpCisgIAl7CisJICBhdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfREVQRU5ERU5UU11ba2V5XT1kZXBlbmRlbnQ7CisgIAl9CisgIAllbHNlCisgIAl7CisgICAgICAgICAgYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX0RFUEVOREVOVFNdKz0oW2tleTpkZXBlbmRlbnRdKTsKKyAgCX0KKyAgfQorICBlbHNlCisgIHsKKyAgCS8vIHJlbW92ZSBwcmV2aW91c2x5IHNldCBkZXBlbmRlbnQKKyAgCWlmKG1lbWJlcihhdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfREVQRU5ERU5UU10sa2V5KSkKKyAgCXsKKwkgIGF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9ERVBFTkRFTlRTXS09KFtrZXldKTsKKyAgCX0KKyAgfQorICAKKyAgVXBkYXRlQXR0cmlidXRlcygpOworCisgIHJldHVybiBUQVRUUl9PSzsKK30KKworbm9tYXNrIHB1YmxpYyBtYXBwaW5nIFF1ZXJ5VGltZWRBdHRyTW9kaWZpZXIoc3RyaW5nIGtleSkKK3sKKyAgaW50IG91dGRhdGVkOworICBvYmplY3QgZGVwZW5kZW50OworICBtaXhlZCBub3RpZnk7CisgIG1hcHBpbmcgbW9kOworICAKKyAgaWYoIWtleSB8fCBrZXk9PSIiKQorICB7CisgICAgcmV0dXJuIChbXSk7CisgIH0KKworICBpZighbWVtYmVyKGF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9FTlRSSUVTXSxrZXkpKQorICB7IAorICAgIHJldHVybiAoW10pOworICB9CisKKyAgbW9kPWRlZXBfY29weShhdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfRU5UUklFU11ba2V5LFRBVFRSX01PRF0pOworICBvdXRkYXRlZD1hdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfRU5UUklFU11ba2V5LFRBVFRSX09VVERBVEVEXTsKKyAgZGVwZW5kZW50PWF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9FTlRSSUVTXVtrZXksVEFUVFJfREVQRU5ERU5UXTsKKyAgbm90aWZ5PWF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9FTlRSSUVTXVtrZXksVEFUVFJfTk9USUZZXTsKKyAgCisgIHJldHVybiAoW2tleTptb2Q7b3V0ZGF0ZWQ7ZGVwZW5kZW50O25vdGlmeSBdKTsKK30KKworbm9tYXNrIHB1YmxpYyBpbnQgRGVsZXRlVGltZWRBdHRyTW9kaWZpZXIoc3RyaW5nIGtleSkKK3sKKyAgaWYoIWtleSB8fCBrZXk9PSIiKQorICB7CisgICAgcmV0dXJuIFRBVFRSX0lOVkFMSURfQVJHUzsKKyAgfQorCisgIGlmKCFtZW1iZXIoYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX0VOVFJJRVNdLGtleSkpCisgIHsgCisgICAgcmV0dXJuIFRBVFRSX05PX1NVQ0hfTU9ESUZJRVI7CisgIH0KKyAgCisgIGF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9ERVBFTkRFTlRTXS09KFtrZXldKTsKKyAgYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX0VOVFJJRVNdLT0oW2tleV0pOworICBVcGRhdGVBdHRyaWJ1dGVzKCk7CisgIAorICByZXR1cm4gVEFUVFJfT0s7Cit9CisKK25vbWFzayBwcm90ZWN0ZWQgdm9pZCBhdHRyaWJ1dGVfaGIoKQoreworICBpbnQgbm93LGksayx1cGRhdGUsb3V0ZGF0ZWQ7CisgIHN0cmluZyoga2V5czsKKyAgbWFwcGluZyB0b25vdGlmeTsKKwkKKyAgLy8gaW5pdGlhbGl6ZQorICBub3c9dGltZSgpOworICB0b25vdGlmeT0oW10pOworCisgIGtleXM9bV9pbmRpY2VzKGF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9FTlRSSUVTXSk7CisgIAorICAvLyBkZWxldGUgb3V0ZGF0ZWQgCisgIGZvcihpPXNpemVvZihhdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfT1VUREFURV0pLTE7aT49MDtpLS0pCisgIHsKKyAgCW91dGRhdGVkPWF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9PVVREQVRFXVtpXTsKKyAgCWlmKG91dGRhdGVkPm5vdykKKyAgCXsKKyAgCSAgYnJlYWs7CisgIAl9CisgIAkKKyAgCWZvcihrPXNpemVvZihrZXlzKS0xO2s+PTA7ay0tKQorICAJeworICAJICBpZihhdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfRU5UUklFU11ba2V5c1trXSxUQVRUUl9PVVREQVRFRF09PW91dGRhdGVkKQorICAJICB7CisgIAkgICAgLy8gYmVpIGZlaGxlbmRlbSBub3RpZmllciB3dXJkZSBkYXMgenVtIHZlcmhhZW5nbmlzCisgIAkgICAgLy8gZGFuayBhbiBnbG9pbnNvbgorICAJICAgIC8qCisgIAkgICAgaWYob2JqZWN0cChhdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfRU5UUklFU11ba2V5c1trXSxUQVRUUl9OT1RJRlldKSkKKyAgCSAgICB7CisgIAkgICAgKi8KKyAgCSAgICB0b25vdGlmeSs9KFtrZXlzW2tdOmF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9FTlRSSUVTXVtrZXlzW2tdLFRBVFRSX05PVElGWV1dKTsKKyAgCSAgICAvL30KKyAgCSAgICAKKwkgICAgYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX0RFUEVOREVOVFNdLT0oW2tleXNba11dKTsKKyAJICAgIGF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9FTlRSSUVTXS09KFtrZXlzW2tdXSk7CisgIAkgICAga2V5cy09KHtrZXlzW2tdfSk7CisgIAkgIH0KKyAgCX0KKyAgCQorICAJYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX09VVERBVEVdLT0oe291dGRhdGVkfSk7CisgIH0KKyAgCisgIC8vIGRlbGV0ZSBkZXBlbmRpbmcKKyAga2V5cz1tX2luZGljZXMoYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX0RFUEVOREVOVFNdKTsKKyAgZm9yKGk9c2l6ZW9mKGtleXMpLTE7aT49MDtpLS0pCisgIHsKKyAgCWlmKCFvYmplY3RwKGF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9ERVBFTkRFTlRTXVtrZXlzW2ldXSkpCisgIAl7CisgIAkgICAgLy8gc2llaGUgb2JlbgorICAJICAgIC8qCisgIAkgICAgaWYob2JqZWN0cChhdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfRU5UUklFU11ba2V5c1tpXSxUQVRUUl9OT1RJRlldKSkKKyAgCSAgICB7CisgIAkgICAgKi8KKyAgCSAgICB0b25vdGlmeSs9KFtrZXlzW2ldOmF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9FTlRSSUVTXVtrZXlzW2ldLFRBVFRSX05PVElGWV1dKTsKKyAgCSAgICAvL30KKworCSAgICBhdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfREVQRU5ERU5UU10tPShba2V5c1tpXV0pOworIAkgICAgYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX0VOVFJJRVNdLT0oW2tleXNbaV1dKTsKKyAgCSAgICBrZXlzLT0oe2tleXNbaV19KTsKKyAgCX0KKyAgfQorICAKKyAgCisgIC8vIHVwZGF0ZQorICBpZihzaXplb2YodG9ub3RpZnkpKQorICB7CisgICAgVXBkYXRlQXR0cmlidXRlcygpOworICAgIGNhbGxfb3V0KCMnbm90aWZ5RXhwaXJlZE1vZGlmaWVycywwLHRvbm90aWZ5KTsKKyAgfQorfQorCitub21hc2sgcHJvdGVjdGVkIHZvaWQgbm90aWZ5RXhwaXJlZE1vZGlmaWVycyhtYXBwaW5nIG5vdHMpCit7CisgIGludCBpOworICBzdHJpbmcqIGtleXM7CisgIHdoaWxlKHJlbW92ZV9jYWxsX291dCgjJ25vdGlmeUV4cGlyZWRNb2RpZmllcnMpIT0tMSk7CisgIAorICBpZighbm90cykKKyAgeworICAgIHJldHVybjsKKyAgfQorICAKKyAga2V5cz1tX2luZGljZXMobm90cyk7CisgIGZvcihpPXNpemVvZihub3RzKS0xO2k+PTA7aS0tKQorICB7CisgIAlpZihub3RzW2tleXNbaV1dICYmIAorCSAgICAoIG9iamVjdHAobm90c1trZXlzW2ldXSl8fHN0cmluZ3Aobm90c1trZXlzW2ldXSkgKSApCisgIAl7CisgIAkgICBjYWxsX290aGVyKG5vdHNba2V5c1tpXV0sIk5vdGlmeVRpbWVkQXR0ck1vZEV4cGlyZWQiLGtleXNbaV0pOworICAJfQorICB9Cit9CisKKworLy8gaW52YWxpZGUgbW9kaWZpZXIgYmVuYWNocmljaHRpZ2VuCitub21hc2sgcHJvdGVjdGVkIHZvaWQgbm90aWZ5SW52YWxpZE1vZGlmaWVycygpIHsKKworICB3aGlsZShyZW1vdmVfY2FsbF9vdXQoIydub3RpZnlJbnZhbGlkTW9kaWZpZXJzKSE9LTEpOworICAKKyAgaWYoIWludmFsaWRfbW9kaWZpZXJzKSB7CisgICAgaW52YWxpZF9tb2RpZmllcnM9KHt9KTsKKyAgfQorICAKKyAgY2FsbF9vdGhlcihpbnZhbGlkX21vZGlmaWVycywiTm90aWZ5WE1BdHRyTW9kTGltaXRWaW9sYXRpb24iKTsKKworfQorCisKKy8vIHdlbGNoZSBNb2RpZmllciAvIG1vZGlmLiBPYmpla3RlIHdpcmtlbiBudW4/Citwcm90ZWN0ZWQgbm9tYXNrIHZvaWQgY2FsY3VsYXRlX3ZhbGlkX21vZGlmaWVycygpIHsKKyAgY2xvc3VyZSBxcDsKKyAgbWFwcGluZyByZXM7CQorICBzdHJpbmcga2V5OwkKKyAgaW50IHdlcnQ7CisgIC8vIFVudGVyc2NoZWlkdW5nIEJvbnVzIDwtPiBNYWx1cywgd2VpbCBkZXIgTWFsdXMgdm9sbCBlaW5nZWhlbiBzb2xsCQorICBpbnQgaHBfbWFsdXMsIHNwX21hbHVzOworIAorICB1c2VkX2F0dHJpYnV0ZXNfb2Zmc2V0cz0oW10pOworICBjdW11bGF0aXZlX21vZD0wOworICBocF9vZmY9c3Bfb2ZmPTA7CisgIGludmFsaWRfbW9kaWZpZXJzPSh7fSk7CisKKyAgLy8gcmFzc2Vuc3BlemlmaXNjaGUgYm9uaSBQX0FUVFJJQlVURVNfT0ZGU0VUUyAgCisgIGlmICggbWFwcGluZ3AoYXR0cmlidXRlc19vZmZzZXRzKSApCisgICAgdXNlZF9hdHRyaWJ1dGVzX29mZnNldHMrPWF0dHJpYnV0ZXNfb2Zmc2V0czsKKworICBpZiAoIXBvaW50ZXJwKGFsbF9tb2RpZmllcnMpIHx8ICFzaXplb2YoYWxsX21vZGlmaWVycykpIHsKKyAgICAvLyBpbiBkaWVzZW0gRmFsbCBrb2VubmVuIHdpciBoaWVyIGRpcmVrdCBtaXQgZGllc2VyIEZ1bmt0aW9uIFNjaGx1c3MKKyAgICAvLyBtYWNoZW4uIDstKQorICAgIHJldHVybjsKKyAgfQorICBlbHNlCisgICAgYWxsX21vZGlmaWVycy09KHswfSk7IC8vemVyc3RvZXJ0ZSBPYmpla3RlIHJhdXN3ZXJmZW4uCisgICAgCisgIC8vIGVpbm1hbCB1ZWJlciBhbGxlIG1vZGlmaXppZXJlbmRlbiBPYmpla3QgaXRlcmllcmVuIHVuZCBhdWZhZGRpZXJlbgorICBmb3JlYWNoKG9iamVjdCBvYjogYWxsX21vZGlmaWVycykgeworICAgIHFwID0gc3ltYm9sX2Z1bmN0aW9uKCJRdWVyeVByb3AiLG9iKTsKKyAKKyAgICBpZiAoIW9iamVjdHAob2IpIHx8IGVudmlyb25tZW50KG9iKSE9dGhpc19vYmplY3QoKSkgeworICAgICAgYWxsX21vZGlmaWVycy09KHtvYn0pOworICAgICAgY29udGludWU7CisgICAgfQorIAkJCisgICAgLy8gZXh0LiBBdHRyaWJ1dC1Nb2RpZmllcgorICAgIGlmICggbWFwcGluZ3AocmVzPWZ1bmNhbGwocXAsUF9YX0FUVFJfTU9EKSkgKSB7CQkKKyAgICAgIGZvcmVhY2goa2V5LCB3ZXJ0OiByZXMpIHsKKyAgICAgICAgY3VtdWxhdGl2ZV9tb2QrPXdlcnQ7CisgICAgICB9CisgICAgfQorCisgICAgLy8gbWFnaWMgQXR0cmlidXQtTW9kaWZpZXIKKyAgICBpZiAoIG1hcHBpbmdwKHJlcz1mdW5jYWxsKHFwLFBfTV9BVFRSX01PRCkpCisgICAgICAgICYmICggZnVuY2FsbChxcCxQX1dPUk4pCisgICAgICAgICAgICB8fCBmdW5jYWxsKHFwLFBfV0lFTERFRCkgKSApIHsJCQorICAgICAgZm9yZWFjaChrZXksIHdlcnQ6IHJlcykgeworICAgICAgICBjdW11bGF0aXZlX21vZCs9d2VydDsKKyAgICAgIH0KKyAgICB9CisgICAgLy8gTWFnaWMgSGVhbHRoLU1vZGlmaWVyIAkJCisgICAgaWYgKCBtYXBwaW5ncChyZXM9ZnVuY2FsbChxcCxQX01fSEVBTFRIX01PRCkpCisgICAgICAgICYmICggZnVuY2FsbChxcCxQX1dPUk4pCisgICAgICAgICAgICB8fCBmdW5jYWxsKHFwLFBfV0lFTERFRCkgKSApIHsKKyAgICAgIGlmIChyZXNbUF9IUF0gPCAwKQorICAgICAgICBocF9tYWx1cyArPSByZXNbUF9IUF07CisgICAgICBlbHNlCisgICAgICAgIGhwX29mZis9cmVzW1BfSFBdOworCisgICAgICBpZiAocmVzW1BfU1BdIDwgMCkKKyAgICAgICAgc3BfbWFsdXMgKz0gcmVzW1BfU1BdOworICAgICAgZWxzZQorICAgICAgICBzcF9vZmYrPXJlc1tQX1NQXTsKKyAgICAgIH0KKwkgICAgICAKKyAgICAvLyBleHRlcm5hbCBIZWFsdGggTW9kaWZpZXIKKyAgICBpZiAoIG1hcHBpbmdwKHJlcz1mdW5jYWxsKHFwLFBfWF9IRUFMVEhfTU9EKSkgKSB7CisgICAgICBpZiAocmVzW1BfSFBdIDwgMCkKKyAgICAgICAgaHBfbWFsdXMgKz0gcmVzW1BfSFBdOworICAgICAgZWxzZQorICAgICAgICBocF9vZmYrPXJlc1tQX0hQXTsKKworICAgICAgaWYgKHJlc1tQX1NQXSA8IDApCisgICAgICAgIHNwX21hbHVzICs9IHJlc1tQX1NQXTsKKyAgICAgIGVsc2UKKyAgICAgICAgc3Bfb2ZmKz1yZXNbUF9TUF07CSAgICAKKyAgICB9CQorICAKKyAgfSAvLyBFbmRlIDEuIGZvcmVhY2goKQorICAKKyAKKyAgLy8gdW5kIG5vY2htYWwsIHNvdmllbGUgT2JqZWt0IHdpZWRlciByYXVzc2NobWVpc3NlbiwgYmlzIGRhcyBMaW1pdCB3aWVkZXIKKyAgLy8gdW50ZXJzY2hyaXR0ZW4gd2lyZC4gKFZlcmJlc3NlcnVuZ3N2b3JzY2hsYWVnZSBlcnd1ZW5zY2h0LikgOi0oCisgIGZvcmVhY2gob2JqZWN0IG9iOiBhbGxfbW9kaWZpZXJzKSB7CisKKyAgICBxcCA9IHN5bWJvbF9mdW5jdGlvbigiUXVlcnlQcm9wIixvYik7CisgCisgICAgaWYgKCBtYXBwaW5ncChyZXM9ZnVuY2FsbChxcCxQX1hfQVRUUl9NT0QpKSApIHsKKyAgICAgIGlmKGN1bXVsYXRpdmVfbW9kPkNVTVVMQVRJVkVfQVRUUl9MSU1JVCkgeyAKKyAgICAgICAgaW52YWxpZF9tb2RpZmllcnMrPSh7b2J9KTsJICAKKwlmb3JlYWNoKGtleSwgd2VydDogcmVzKSB7CisgICAgICAgICAgY3VtdWxhdGl2ZV9tb2QtPXdlcnQ7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGVsc2UgeworICAgICAgICBhZGRfb2Zmc2V0cyhyZXMpOworICAgICAgfQorICAgIH0KKworICAgIGlmICggbWFwcGluZ3AocmVzPWZ1bmNhbGwocXAsUF9NX0FUVFJfTU9EKSkKKyAgICAgICAgJiYgKCBmdW5jYWxsKHFwLFBfV09STikKKyAgICAgICAgICAgIHx8IGZ1bmNhbGwocXAsUF9XSUVMREVEKSApICkgeworICAgICAgaWYoY3VtdWxhdGl2ZV9tb2Q+Q1VNVUxBVElWRV9BVFRSX0xJTUlUKSB7ICAgICAKKyAgICAgICAgaWYobWVtYmVyKGludmFsaWRfbW9kaWZpZXJzLG9iKT09LTEpIHsKKyAgICAgICAgICBpbnZhbGlkX21vZGlmaWVycys9KHtvYn0pOworICAgICAgICB9CQkJCisJZm9yZWFjaChrZXksIHdlcnQ6IHJlcykgeworICAgICAgICAgIGN1bXVsYXRpdmVfbW9kLT13ZXJ0OworICAgICAgICB9CisgICAgICB9CisgICAgICBlbHNlIHsKKyAgICAgICAgYWRkX29mZnNldHMocmVzKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvLyBIRUFMVEhfTU9EIHdlcmRlbiBkdXJjaCBlaW5lIEZvcm1lbCAnZW50c2NoYWVyZnQnLCBkYW1pdCBtYW4gbnVyIHNjaHdlcgorICAvLyBkYXMgTWF4aW11bSB2b24gMTUwIGVycmVpY2hlbiBrYW5uLiAoRm9ybWVsIHZvbiBIdW1uaSwgYmVzY2hsb3NzZW4gYXVmIDMuCisgIC8vIEVNLVRyZWZmZW4pCisgIC8vIE1hbGkgZ2VoZW4gYWJlciB2b2xsIGVpbgorICBocF9vZmYgPSAoaW50KSgxNTAgLSAoMTUwKjE1MC4wLygxNTAgKyBocF9vZmYpKSkgKyBocF9tYWx1czsKKyAgc3Bfb2ZmID0gKGludCkoMTUwIC0gKDE1MCoxNTAuMC8oMTUwICsgc3Bfb2ZmKSkpICsgc3BfbWFsdXM7CisKKyAgLyogYWx0ZSBWZXJzaW9uCisgICAgaHBfb2ZmICs9IGhwX21hbHVzOworICAgIHNwX29mZiArPSBzcF9tYWx1czsKKyAgKi8KKyAKKyAgLy8gbm90aWZ5IGludmFsaWQgbW9kaWZpZXJzCisgIGlmKHNpemVvZihpbnZhbGlkX21vZGlmaWVycyk+MCkgeworICAgIGNhbGxfb3V0KCMnbm90aWZ5SW52YWxpZE1vZGlmaWVycywwKTsKKyAgfQorfQorCisvLyBhYm1lbGRlbiBlaW5lcyBtb2RpZmllcnMgCitub21hc2sgcHVibGljIHZvaWQgZGVyZWdpc3Rlcl9tb2RpZmllcihvYmplY3QgbW9kaWZpZXIpCit7IAorICBpZiAoIXBvaW50ZXJwKGFsbF9tb2RpZmllcnMpKSB7CisgICAgcmV0dXJuOworICB9CisKKyAgLy8gdmFsaWQgb2JqZWN0PworICBpZiAoIW9iamVjdHAobW9kaWZpZXIpIHx8IG1lbWJlcihhbGxfbW9kaWZpZXJzLG1vZGlmaWVyKT09LTEpIHsKKyAgICByZXR1cm47CisgIH0KKyAgCisgIGFsbF9tb2RpZmllcnMtPSh7bW9kaWZpZXJ9KTsKKyAgaWYgKGludmFsaWRfbW9kaWZpZXJzKSB7CisgICAgaW52YWxpZF9tb2RpZmllcnMtPSh7bW9kaWZpZXJ9KTsKKyAgfQorfQorCisvLyBhbm1lbGRlbiBlaW5lcyBtb2RpZmllcnMgCitub21hc2sgcHVibGljIHZvaWQgcmVnaXN0ZXJfbW9kaWZpZXIob2JqZWN0IG1vZGlmaWVyKSB7IAorICBjbG9zdXJlIHFwOworICAKKyAgaWYgKCFwb2ludGVycChhbGxfbW9kaWZpZXJzKSkgeworICAgIGFsbF9tb2RpZmllcnM9KHt9KTsKKyAgfQorCisgIC8vIHZhbGlkIG9iamVjdD8KKyAgaWYgKCFvYmplY3RwKG1vZGlmaWVyKSB8fCBlbnZpcm9ubWVudChtb2RpZmllcikhPXRoaXNfb2JqZWN0KCkgfHwgCisgICAgICBtZW1iZXIoYWxsX21vZGlmaWVycyxtb2RpZmllcikhPS0xKSB7CisgICAgcmV0dXJuOworICB9CisgIAorICBxcCA9IHN5bWJvbF9mdW5jdGlvbigiUXVlcnlQcm9wIixtb2RpZmllcik7CisgIC8vIG1vZGlmaWVyIGFmdGVyIGFsbD8gRGllIFBfTV8qIG11ZXNzZW4gZ2V0cmFnZW4vZ2V6dWVja3Qgc2Vpbi4KKyAgaWYobWFwcGluZ3AoZnVuY2FsbChxcCxQX1hfQVRUUl9NT0QpKSB8fAorICAgICBtYXBwaW5ncChmdW5jYWxsKHFwLFBfWF9IRUFMVEhfTU9EKSkgfHwKKyAgICAoKG1hcHBpbmdwKGZ1bmNhbGwocXAsUF9NX0FUVFJfTU9EKSkgfHwKKyAgICAgICBtYXBwaW5ncChmdW5jYWxsKHFwLFBfTV9IRUFMVEhfTU9EKSkpICYmCisgICAgICAoZnVuY2FsbChxcCxQX1dPUk4pIHx8IGZ1bmNhbGwocXAsUF9XSUVMREVEKSkgKSApIHsKKyAgICBhbGxfbW9kaWZpZXJzKz0oe21vZGlmaWVyfSk7CisgIH0KK30KKworcHJvdGVjdGVkIHZvaWQgYWRkX29mZnNldHMobWFwcGluZyBhcnIpIHsKKyAgbWl4ZWQgKmluZDsKKyAgaW50IGk7CisgIAorICBpZiAoICFtYXBwaW5ncChhcnIpICkKKyAgICByZXR1cm47CisKKyAgZm9yZWFjaChzdHJpbmcga2V5LCBpbnQgd2VydDogYXJyKSB7CisgICAgdXNlZF9hdHRyaWJ1dGVzX29mZnNldHNba2V5XSs9d2VydDsKKyAgfQorfQorCitwdWJsaWMgdm9pZCBVcGRhdGVBdHRyaWJ1dGVzKCkgeworICBtaXhlZCAgICppbmQ7CisgIGludCAgICAgaTsKKyAgCisgIC8vIGFsbGUgZ3VlbHRpZ2VuIE1vZGlmaWVyIGVybWl0dGVsbiBhdXMgT2JqZWt0ZW4gaW0gSW52ZW50YXIuCisgIGNhbGN1bGF0ZV92YWxpZF9tb2RpZmllcnMoKTsKKworICAvLyBwZXJzaXN0ZW50ZSBtb2RpZmllciBkcmF1ZiAoZnJvc2NoIHpiKQorICAvLyBhdXMgUF9BVFRSSUJVVEVTX01PRElGSUVSUworICBpZiAoIG1hcHBpbmdwKGF0dHJpYnV0ZXNfbW9kaWZpZXIpICkgeworICAgIGZvcmVhY2gobWl4ZWQga2V5LCBtYXBwaW5nIHdlcnQ6IGF0dHJpYnV0ZXNfbW9kaWZpZXIpIHsKKyAgICAgIGFkZF9vZmZzZXRzKHdlcnQpOyAvLyBNb2RpZmllciBhZGRpZXJlbi4uLgkJCisgICAgfQorICB9CisgIC8vIHRpbWVkIG1vZGlmaWVyIGRyYXVmIGF1cyBQX1RJTUVEX0FUVFJfTU9ECisgIGluZD1tX2luZGljZXMoYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX0VOVFJJRVNdKTsKKyAgZm9yICggaT1zaXplb2YoaW5kKS0xIDsgaT49MCA7IGktLSApIHsKKyAgICAvLyBNb2RpZmllciBhZGRpZXJlbi4uLgorICAgIGFkZF9vZmZzZXRzKGF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9FTlRSSUVTXVtpbmRbaV0sMF0pOworICB9CisgIC8vIEJlaSBNb25zdGVybiB3ZXJkZW4gZGllIEhQL1NQIHVlYmxpY2hlcndlaXNlIHNlbGJzdCBnZXNldHp0CisgIGlmICggIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUodGhpc19vYmplY3QoKSkpCisgICAgcmV0dXJuOworCisgIFNldFByb3AoUF9NQVhfSFAsIFF1ZXJ5QXR0cmlidXRlKEFfQ09OKSo4KzQyK2hwX29mZik7CisgIFNldFByb3AoUF9NQVhfU1AsIFF1ZXJ5QXR0cmlidXRlKEFfSU5UKSo4KzQyK3NwX29mZik7CisgIAorICBpZihRdWVyeVByb3AoUF9IUCk+UXVlcnlQcm9wKFBfTUFYX0hQKSkgeworICAgIFNldFByb3AoUF9IUCxRdWVyeVByb3AoUF9NQVhfSFApKTsKKyAgfQorICAKKyAgaWYoUXVlcnlQcm9wKFBfU1ApPlF1ZXJ5UHJvcChQX01BWF9TUCkpIHsKKyAgICBTZXRQcm9wKFBfU1AsUXVlcnlQcm9wKFBfTUFYX1NQKSk7CisgIH0KKworICBHTUNQX0NoYXIoIChbIEFfSU5UOiBRdWVyeUF0dHJpYnV0ZShBX0lOVCksCisgICAgICAgICAgICAgICAgQV9ERVg6IFF1ZXJ5QXR0cmlidXRlKEFfREVYKSwKKyAgICAgICAgICAgICAgICBBX1NUUjogUXVlcnlBdHRyaWJ1dGUoQV9TVFIpLAorICAgICAgICAgICAgICAgIEFfQ09OOiBRdWVyeUF0dHJpYnV0ZShBX0NPTikgXSkgKTsKK30KKworCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKSB7CisgIGhwX29mZj1zcF9vZmY9MDsKKyAgdXNlZF9hdHRyaWJ1dGVzX29mZnNldHM9KFtdKTsKKyAgYWxsX21vZGlmaWVycz0oe30pOworICBpbnZhbGlkX21vZGlmaWVycz0oe30pOworICBjdW11bGF0aXZlX21vZD0wOworICAKKyAgU2V0KFBfQVRUUklCVVRFU19NT0RJRklFUiwgYXR0cmlidXRlc19tb2RpZmllcj0oW10pKTsgLy8gbmljaHQgZ2VzY2h1ZXR6dAorICBTZXQoUF9BVFRSSUJVVEVTX09GRlNFVFMsIGF0dHJpYnV0ZXNfb2Zmc2V0cz0oW10pKTsKKyAgU2V0KFBfQVRUUklCVVRFU19PRkZTRVRTLCBQUk9URUNURUQsIEZfTU9ERSk7CisgIFNldChQX0FUVFJJQlVURVMsIGF0dHJpYnV0ZXM9KFtdKSk7CisgIFNldChQX0FUVFJJQlVURVMsIFBST1RFQ1RFRCwgRl9NT0RFKTsKKworICBTZXQoUF9USU1FRF9BVFRSX01PRCwgYXR0cmlidXRlc190aW1lZF9tb2RzPSh7ICh7fSksKFtdKSwoW10pIH0pKTsKKyAgU2V0KFBfVElNRURfQVRUUl9NT0QsIE5PU0VUTUVUSE9EfFNFQ1VSRUQsIEZfTU9ERV9BUyk7Cit9CisKK3N0YXRpYyBtaXhlZCBfcXVlcnlfdGltZWRfYXR0cl9tb2QoKSB7CisgIG1peGVkIHJldDsKKyAgcmV0dXJuIFNldChQX1RJTUVEX0FUVFJfTU9ELAkgICAgCisgICAgICAoe2F0dHJpYnV0ZXNfdGltZWRfbW9kc1swXSwKKwlkZWVwX2NvcHkoYXR0cmlidXRlc190aW1lZF9tb2RzWzFdKSwKKwlkZWVwX2NvcHkoYXR0cmlidXRlc190aW1lZF9tb2RzWzJdKX0pKTsKK30KKworc3RhdGljIG1hcHBpbmcgX3NldF9hdHRyaWJ1dGVzKG1hcHBpbmcgYXJyKSAKK3sKKyAgU2V0KFBfQVRUUklCVVRFUywgYXR0cmlidXRlcz1hcnIpOworICBVcGRhdGVBdHRyaWJ1dGVzKCk7CisgIHJldHVybiBhcnI7Cit9CisKK3N0YXRpYyBtYXBwaW5nIF9xdWVyeV9hdHRyaWJ1dGVzKCkgCit7CisgIHJldHVybiBkZWVwX2NvcHkoU2V0KFBfQVRUUklCVVRFUywgYXR0cmlidXRlcykpOyAKK30KKworc3RhdGljIG1hcHBpbmcgX3NldF9hdHRyaWJ1dGVzX29mZnNldHMobWFwcGluZyBhcnIpIAoreworICBTZXQoUF9BVFRSSUJVVEVTX09GRlNFVFMsIGF0dHJpYnV0ZXNfb2Zmc2V0cz1hcnIpOworICBVcGRhdGVBdHRyaWJ1dGVzKCk7CisgIHJldHVybiBhdHRyaWJ1dGVzX29mZnNldHM7Cit9CisKK3N0YXRpYyBtYXBwaW5nIF9xdWVyeV9hdHRyaWJ1dGVzX29mZnNldHMoKSAKK3sgCisgIHJldHVybiBkZWVwX2NvcHkoU2V0KFBfQVRUUklCVVRFU19PRkZTRVRTLCBhdHRyaWJ1dGVzX29mZnNldHMpKTsKK30KKworc3RhdGljIG1peGVkIF9zZXRfYXR0cmlidXRlc19tb2RpZmllcihtaXhlZCBhcnIpIAoreyBzdHJpbmcgZm47CisgIG1peGVkIHByZTsKKyAgbWFwcGluZyBtYXBfbGRmaWVkOworICAKKyAgaWYgKCBwb2ludGVycChhcnIpICYmIChzaXplb2YoYXJyKT49MikgKQorICB7CisgICAgcHJlPWFyclswXTsKKyAgICBtYXBfbGRmaWVkPWFyclsxXTsKKyAgfQorICBlbHNlIAorICB7CisgICAgcHJlPXByZXZpb3VzX29iamVjdCgpOworICAgIG1hcF9sZGZpZWQ9YXJyOworICB9CisKKyAgaWYgKCBvYmplY3RwKHByZSkgKQorICAgIGZuPW9sZF9leHBsb2RlKG9iamVjdF9uYW1lKHByZSksIiMiKVswXTsKKyAgZWxzZQorICAgIGZuPXByZTsKKworICBpZiAoICFzdHJpbmdwKGZuKSApCisgICAgcmV0dXJuIDA7CisKKyAgLy8gd2VubiBNb2RpZmllciBrZWluIG1hcHBpbmcgb2RlciBlaW4gbGVlcmVzIE1hcHBpbmc6IGxvZXNjaGVuCisgIGlmICggIW1hcHBpbmdwKG1hcF9sZGZpZWQpIHx8ICFzaXplb2YobWFwX2xkZmllZCkpCisgICAgbV9kZWxldGUoYXR0cmlidXRlc19tb2RpZmllcixmbik7CisgIGVsc2UKKyAgICBhdHRyaWJ1dGVzX21vZGlmaWVyW2ZuXT1tYXBfbGRmaWVkOworCisgIFNldChQX0FUVFJJQlVURVNfTU9ESUZJRVIsIGF0dHJpYnV0ZXNfbW9kaWZpZXIpOworICBVcGRhdGVBdHRyaWJ1dGVzKCk7CisgIHJldHVybiBhdHRyaWJ1dGVzX21vZGlmaWVyW2ZuXTsKK30KKworc3RhdGljIG1hcHBpbmcgX3F1ZXJ5X2F0dHJpYnV0ZXNfbW9kaWZpZXIoKSAKK3sKKyAgcmV0dXJuIGRlZXBfY29weShhdHRyaWJ1dGVzX21vZGlmaWVyKTsgIAorfQorCitwdWJsaWMgaW50IFNldEF0dHIoc3RyaW5nIGF0dHIsIGludCB2YWwpIAoreyBjbG9zdXJlIGZpbHRlcl9sZGZpZWQ7CisKKyAgaWYgKCBmaWx0ZXJfbGRmaWVkID0gc3ltYm9sX2Z1bmN0aW9uKCJfZmlsdGVyYXR0cl8iK2F0dHIsIHRoaXNfb2JqZWN0KCkpICkgCisgICAgdmFsID0gZnVuY2FsbChmaWx0ZXJfbGRmaWVkLCB2YWwgKTsKKworICBhdHRyaWJ1dGVzW2F0dHJdID0gdmFsOworICBVcGRhdGVBdHRyaWJ1dGVzKCk7CisgIHJldHVybiB2YWw7Cit9CisKK3B1YmxpYyBpbnQgU2V0QXR0cmlidXRlKHN0cmluZyBhdHRyLCBpbnQgdmFsKSAKK3sKKyAgcmV0dXJuIFNldEF0dHIoYXR0ciwgdmFsLXVzZWRfYXR0cmlidXRlc19vZmZzZXRzW2F0dHJdKTsKK30KKworLy8gRGllc2UgRnVua3Rpb24gc29sbHRlIHp1bSBBYmZyYWdlbiB2ZXJ3ZW5kZXQgd2VyZGVuOgorcHVibGljIGludCBRdWVyeUF0dHJpYnV0ZShzdHJpbmcgYXR0cikgCit7IGludCByZTsKKworICByZT1hdHRyaWJ1dGVzW2F0dHJdK3VzZWRfYXR0cmlidXRlc19vZmZzZXRzW2F0dHJdOworCisgIGlmICggcXVlcnlfb25jZV9pbnRlcmFjdGl2ZSh0aGlzX29iamVjdCgpKSAmJiAocmU+MzApICkKKyAgICByZT0zMDsKKworICByZXR1cm4gcmU7Cit9CisKK3B1YmxpYyBpbnQgUXVlcnlSZWFsQXR0cmlidXRlKHN0cmluZyBhdHRyKSAKK3sKKyAgcmV0dXJuIGF0dHJpYnV0ZXNbYXR0cl07Cit9CisKK3B1YmxpYyBpbnQgU2V0UmVhbEF0dHJpYnV0ZShzdHJpbmcgYXR0ciwgaW50IHZhbCkgCit7CisgIHJldHVybiBTZXRBdHRyKGF0dHIsIHZhbCk7Cit9CisKK3B1YmxpYyBpbnQgUXVlcnlBdHRyaWJ1dGVPZmZzZXQoc3RyaW5nIGF0dHIpIAoreworICByZXR1cm4gdXNlZF9hdHRyaWJ1dGVzX29mZnNldHNbYXR0cl07Cit9CisKK3B1YmxpYyBzdGF0dXMgVGVzdExpbWl0VmlvbGF0aW9uKG1hcHBpbmcgY2hlY2spCit7CisgIGludCBrLHRlc3Q7CisgIG1peGVkKiBpbmQ7CisgICAgCisgIGlmKCFjaGVjayB8fCAhbWFwcGluZ3AoY2hlY2spKQorICB7CisgICAgcmV0dXJuIDA7CisgIH0KKworICB0ZXN0PTA7CisgIGluZD1tX2luZGljZXMoY2hlY2spOworICBmb3IoIGs9c2l6ZW9mKGluZCktMSA7IGs+PTAgOyBrLS0gKQorICB7CisgICAgdGVzdCs9Y2hlY2tbaW5kW2tdXTsKKyAgfQorICAKKyAgdGVzdCs9Y3VtdWxhdGl2ZV9tb2Q7CisgIGlmKHRlc3Q+Q1VNVUxBVElWRV9BVFRSX0xJTUlUKQorICB7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgCisgIHJldHVybiAwOworfQorCisvKgorICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAqIGF0dHJpYnV0ZXMgY29tcGF0aWJpbGl0eSBmdW5jdGlvbnMKKyAqLworCitwcm90ZWN0ZWQgaW50IF9maWx0ZXJhdHRyX3N0cihpbnQgdmFsKQoreworICByZXR1cm4gKCAodmFsPDApID8gMCA6ICh2YWw+MjApID8gMjAgOiB2YWwgKTsKK30KKworcHJvdGVjdGVkIGludCBfZmlsdGVyYXR0cl9kZXgoaW50IHZhbCkKK3sKKyAgcmV0dXJuICggKHZhbDwwKSA/IDAgOiAodmFsPjIwKSA/IDIwIDogdmFsICk7Cit9CisKK3Byb3RlY3RlZCBpbnQgX2ZpbHRlcmF0dHJfaW50KGludCB2YWwpCit7CisgIHJldHVybiAoICh2YWw8MCkgPyAwIDogKHZhbD4yMCkgPyAyMCA6IHZhbCApOworfQorCitwcm90ZWN0ZWQgaW50IF9maWx0ZXJhdHRyX2NvbihpbnQgdmFsKQoreworICByZXR1cm4gKCAodmFsPDApID8gMCA6ICh2YWw+MjApID8gMjAgOiB2YWwgKTsKK30KZGlmZiAtLWdpdCBhL3N0ZC9saXZpbmcvY2xvdGhpbmcuYyBiL3N0ZC9saXZpbmcvY2xvdGhpbmcuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NmFmZjQ0Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL2xpdmluZy9jbG90aGluZy5jCkBAIC0wLDAgKzEsOTYgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBsaXZpbmcvY2xvdGhpbmcuYyAtLSBNb2R1bCBmdWVyIEJla2xlaWR1bmdzZnJhZ2VuLiA7LSkKKy8vCisvLyAkSWQ6IGFybW91ci5jLHYgMy44IDIwMDMvMDgvMjUgMDk6MzY6MDQgUmlrdXMgRXhwICQKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8bGl2aW5nL2Nsb3RoaW5nLmg+CisjaW5jbHVkZSA8bGl2aW5nL2NvbWJhdC5oPgorI2luY2x1ZGUgPGFybW91ci5oPgorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKSB7CisgIFNldFByb3AoUF9DTE9USElORywgKHt9KSk7CisgIFNldChQX0NMT1RISU5HLCBQUk9URUNURUQsIEZfTU9ERV9BUyk7Cit9CisKK3B1YmxpYyBvYmplY3QgKkZpbHRlckNsb3RoaW5nKGNsb3N1cmUgZmlsdGVyZnVuLCB2YXJhcmdzIG1peGVkKiBleHRyYSkgeworICBpZiAoIWNsb3N1cmVwKGZpbHRlcmZ1bikpCisgICAgcmV0dXJuICh7fSk7CisgIHJldHVybiBhcHBseSgjJ2ZpbHRlciwgUXVlcnlQcm9wKFBfQ0xPVEhJTkcpLCBmaWx0ZXJmdW4sIGV4dHJhKTsKK30KKworcHVibGljIG9iamVjdCAqRmlsdGVyQXJtb3VycyhjbG9zdXJlIGZpbHRlcmZ1biwgdmFyYXJncyBtaXhlZCogZXh0cmEpIHsKKyAgaWYgKCFjbG9zdXJlcChmaWx0ZXJmdW4pKQorICAgIHJldHVybiAoe30pOworICByZXR1cm4gYXBwbHkoIydmaWx0ZXIsIFF1ZXJ5UHJvcChQX0FSTU9VUlMpLSh7MH0pLCBmaWx0ZXJmdW4sIGV4dHJhKTsKK30KKworcHVibGljIGludCBXZWFyQ2xvdGhpbmcob2JqZWN0IG9iKSB7CisgIG9iamVjdCAqY2xvdGhpbmcgPSBRdWVyeVByb3AoUF9DTE9USElORyk7CisgIGlmIChtZW1iZXIoY2xvdGhpbmcsIG9iKSAhPSAtMSkKKyAgICByZXR1cm4gMDsKKyAgY2xvdGhpbmcgKz0gKHtvYn0pOworICBTZXRQcm9wKFBfQ0xPVEhJTkcsIGNsb3RoaW5nKTsKKyAgcmV0dXJuIDE7Cit9CisKK3B1YmxpYyBpbnQgV2VhckFybW91cihvYmplY3Qgb2IpIHsKKyAgaWYgKCFWQUxJRF9BUk1PVVJfVFlQRShvYi0+UXVlcnlQcm9wKFBfQVJNT1VSX1RZUEUpKSkKKyAgICByZXR1cm4gMDsKKworICBvYmplY3QgKmFybW91cnMgPSBRdWVyeVByb3AoUF9BUk1PVVJTKTsKKyAgaWYgKG1lbWJlcihhcm1vdXJzLCBvYikgIT0gLTEpCisgICAgcmV0dXJuIDA7CisKKyAgYXJtb3VycyArPSAoe29ifSk7CisgIFNldFByb3AoUF9BUk1PVVJTLCBhcm1vdXJzKTsKKyAgcmV0dXJuIDE7Cit9CisKK3B1YmxpYyBpbnQgV2VhcihvYmplY3Qgb2IpIHsKKyAgLy8gcmVpaGVuZm9sZ2UgaXN0IHdpY2h0aWchIFJ1ZXN0dW5nIHNpbmQgX2F1Y2hfIEtsZWlkdW5nLCBhYmVyIEtsZWlkdW5nCisgIC8vIGtlaW5lIFJ1ZXN0dW5nLgorICBpZiAob2ItPklzQXJtb3VyKCkpCisgICAgcmV0dXJuIFdlYXJBcm1vdXIob2IpOworICBlbHNlIGlmIChvYi0+SXNDbG90aGluZygpKQorICAgIHJldHVybiBXZWFyQ2xvdGhpbmcob2IpOworICByZXR1cm4gMDsKK30KKworcHVibGljIGludCBVbndlYXJDbG90aGluZyhvYmplY3Qgb2IpIHsKK29iamVjdCAqY2xvdGhpbmcgPSBRdWVyeVByb3AoUF9DTE9USElORyk7CisgIGlmIChtZW1iZXIoY2xvdGhpbmcsIG9iKSA9PSAtMSkKKyAgICByZXR1cm4gMDsKKyAgY2xvdGhpbmcgLT0gKHtvYn0pOworICBTZXRQcm9wKFBfQ0xPVEhJTkcsIGNsb3RoaW5nKTsKKyAgcmV0dXJuIDE7Cit9CisKK3B1YmxpYyBpbnQgVW53ZWFyQXJtb3VyKG9iamVjdCBvYikgeworICBvYmplY3QgKmFybW91cnMgPSBRdWVyeVByb3AoUF9BUk1PVVJTKTsKKyAgaWYgKG1lbWJlcihhcm1vdXJzLCBvYikgPT0gLTEpCisgICAgcmV0dXJuIDA7CisKKyAgYXJtb3VycyAtPSAoe29ifSk7CisgIFNldFByb3AoUF9BUk1PVVJTLCBhcm1vdXJzKTsKKyAgcmV0dXJuIDE7Cit9CisKK3B1YmxpYyBpbnQgVW53ZWFyKG9iamVjdCBvYikgeworICAvLyByZWloZW5mb2xnZSBpc3Qgd2ljaHRpZyEgUnVlc3R1bmcgc2luZCBfYXVjaF8gS2xlaWR1bmcsIGFiZXIgS2xlaWR1bmcKKyAgLy8ga2VpbmUgUnVlc3R1bmcuCisgIGlmIChvYi0+SXNBcm1vdXIoKSkKKyAgICByZXR1cm4gVW53ZWFyQXJtb3VyKG9iKTsKKyAgZWxzZSBpZiAob2ItPklzQ2xvdGhpbmcoKSkKKyAgICByZXR1cm4gVW53ZWFyQ2xvdGhpbmcob2IpOworICByZXR1cm4gMDsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL2xpdmluZy9jb21iYXQuYyBiL3N0ZC9saXZpbmcvY29tYmF0LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODgwZjNmNgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9saXZpbmcvY29tYmF0LmMKQEAgLTAsMCArMSwyMzExIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gbGl2aW5nL2NvbWJhdC5jIC0tIEJhc2lzLUthbXBmbW9kdWwKKy8vCisvLyAkSWQ6IGNvbWJhdC5jIDk1NjggMjAxNi0wNi0wNSAxODo1MzoxMFogWmVzc3RyYSAkCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKK2luaGVyaXQgIi9zdGQvbGl2aW5nL3NraWxsX3V0aWxzIjsKK2luaGVyaXQgIi9zdGQvbGl2aW5nL2ludmVudG9yeSI7Citpbmhlcml0ICIvc3RkL2xpdmluZy90ZWFtIjsKKworI2luY2x1ZGUgPHN5c19kZWJ1Zy5oPgorI2luY2x1ZGUgPGRlYnVnX21lc3NhZ2UuaD4KKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDxob29rLmg+CisjaW5jbHVkZSA8bGl2aW5nL3NraWxscy5oPgorI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxwbGF5ZXIvY29tbS5oPgorI2luY2x1ZGUgPGxpdmluZy9za2lsbF9hdHRyaWJ1dGVzLmg+CisjaW5jbHVkZSA8Y29tYmF0Lmg+CisjaW5jbHVkZSA8bGl2aW5nLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDxjb25maWcuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxhdHRyaWJ1dGVzLmg+CisjaW5jbHVkZSA8bmV3X3NraWxscy5oPgorCisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorCisjaW5jbHVkZSA8c2Vuc2l0aXZlLmg+CisKKyNkZWZpbmUgSFVOVFRJTUUgMzAwIC8vMzAwIEhCcyBzaW5kIDEwIE1pbnV0ZW4KKyNkZWZpbmUgUk5BTUUoeCkgY2FwaXRhbGl6ZShnZXR1aWQoeCkpCisKKy8vICdwcml2YXRlJy1Qcm90b3R5cGVzCitwcml2YXRlIHN0cmluZyBfa2lsbF9hbGlhcyggc3RyaW5nIHN0ciApOworCisvLyBnbG9iYWxlIFZhcmlhYmxlbgorbm9zYXZlIG1hcHBpbmcgZW5lbWllczsKK3ByaXZhdGUgbm9zYXZlIHN0cmluZyBtYWdpY19hdHRhY2s7Citwcml2YXRlIG5vc2F2ZSBpbnQgYXR0YWNrX2J1c3k7Citub3NhdmUgaW50IG5vX21vcmVfYXR0YWNrczsKK3ByaXZhdGUgbm9zYXZlIGludCByZW1haW5pbmdfaGVhcnRfYmVhdHM7Citwcml2YXRlIG5vc2F2ZSBpbnQgYXR0Ml90aW1lOworcHJpdmF0ZSBub3NhdmUgc3RyaW5nIGxhc3RfYXR0YWNrX21zZzsKK3ByaXZhdGUgbm9zYXZlIG9iamVjdCAqbWlzc2luZ19hdHRhY2tzOworcHJpdmF0ZSBub3NhdmUgbWFwcGluZyBwZWFjZV90cmllczsKKy8vIENhY2hlIGZ1ZXIgUXVlcnlBcm1vdXJCeVR5cGUoKQorcHJpdmF0ZSBub3NhdmUgbWFwcGluZyBRQUJUQ2FjaGU7CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpCit7CisgIFNldChQX1dJTVBZLCBTQVZFLCBGX01PREVfQVMpOworICBTZXQoUF9UT1RBTF9BQywgUFJPVEVDVEVELCBGX01PREVfQVMpOworICBTZXQoUF9IQU5EUywgU0FWRSwgRl9NT0RFX0FTKTsKKyAgU2V0KFBfU0hPV19BVFRBQ0tfTVNHLFNBVkUsRl9NT0RFX0FTKTsKKyAgU2V0KFBfUkVTSVNUQU5DRSwgKHt9KSk7CisgIFNldChQX1ZVTE5FUkFCSUxJVFksICh7fSkpOworICBTZXQoUF9HVUlMRF9QUkVQQVJFQkxPQ0ssIFNBVkUsIEZfTU9ERV9BUyk7CisgIC8vIEtlaW4gU2V0emVuIHZvbiBQX0FSTU9VUlMgdm9uIGF1c3NlbiBwZXIgU2V0KCkuIChQZXIgU2V0UHJvcCgpIGdlaHQgZXMKKyAgLy8gZHVyY2ggZGllIFNldG1ldGhvZGUpLgorICBTZXQoUF9BUk1PVVJTLFBST1RFQ1RFRCxGX01PREVfQVMpOworICBTZXRQcm9wKFBfQVJNT1VSUywgKHt9KSk7CisgIGF0dGFja19idXN5PTEwMDsKKyAgYXR0Ml90aW1lPTA7CisgIGVuZW1pZXM9KFtdKTsKKyAgcGVhY2VfdHJpZXM9KFtdKTsKKyAgdGVhbTo6Y3JlYXRlKCk7IAorICBvZmZlckhvb2soSF9IT09LX0RFRkVORCwxKTsKKyAgb2ZmZXJIb29rKEhfSE9PS19BVFRBQ0ssMSk7CisgIG9mZmVySG9vayhIX0hPT0tfQVRUQUNLX01PRCwxKTsKK30KKworI3VuZGVmIERFQlVHCisjZGVmaW5lIERFQlVHKHgpIGlmIChmaW5kX29iamVjdCgiemVzc3RyYSIpKSBcCisgIHRlbGxfb2JqZWN0KGZpbmRfcGxheWVyKCJ6ZXNzdHJhIikseCkKKworcHVibGljIHZvaWQgVXBkYXRlUmVzaXN0YW5jZVN0cmVuZ3RocygpIHsgCisgIG1hcHBpbmcgcmVzbW9kcywgc3RybWFwOworCisgIGlmICggIW1hcHBpbmdwKHJlc21vZHM9UXVlcnkoUF9SRVNJU1RBTkNFX01PRElGSUVSKSkgKQorICAgIHJldHVybjsKKworICAvL2Vyc3RtYWwgZGllIGFsdGUgQXVmc3VtbWF0aW9uIGxvZXNjaGVuCisgIG1fZGVsZXRlKHJlc21vZHMsIm1lIik7CisKKyAgLy93ZW5uIGpldHp0IGxlZXI6IEFiYnJ1Y2gsIGtlaW5lIFJlcy1Nb2RpZmllciBkYS4KKyAgaWYgKCFzaXplb2YocmVzbW9kcykpCisgICAgICByZXR1cm4oU2V0KFBfUkVTSVNUQU5DRV9NT0RJRklFUiwwKSk7CisKKyAgc3RybWFwID0gKFtdKTsKKworICAvLyB1ZWJlciBhbGxlIGdlc2V0enRlbiBSZXNNb2RpZmllciBnZWhlbgorICBmb3JlYWNoKHN0cmluZyBtb2QsIG1hcHBpbmcgcmVzbWFwLCBvYmplY3Qgb2I6IHJlc21vZHMpIHsKKyAgICBpZiAoICFtYXBwaW5ncChyZXNtYXApIHx8ICFzaXplb2YocmVzbWFwKQorICAgICAgICB8fCAhb2JqZWN0cChvYikgKSB7CisgICAgICBtX2RlbGV0ZShyZXNtb2RzLCBtb2QpOworICAgICAgY29udGludWU7IC8vIFJlc2kgdW5ndWVsdGlnLCB3ZWcgZGFtaXQuCisgICAgfQorICAgIC8vIGpldHp0IG5vY2ggdWViZXIgZGllIFN1Ym1hcHBpbmdzIGxhdWZlbiwgZGllIGRpZSBSZXNpcyBkZXIgT2JqZWt0ZQorICAgIC8vIGJlaW5oYWx0ZW4uCisgICAgZm9yZWFjaChzdHJpbmcgcmVza2V5LCBmbG9hdCByZXNpOiByZXNtYXApIHsKKyAgICAgICAgc3RybWFwW3Jlc2tleV0gPSAoKHN0cm1hcFtyZXNrZXldKzEuMCkqKHJlc2krMS4wKSktMS4wOworICAgIH0KKyAgfQorCisgIGlmICggIXNpemVvZihzdHJtYXApICkKKyAgICBTZXQoUF9SRVNJU1RBTkNFX01PRElGSUVSLCAwKTsKKyAgZWxzZQorICAgIFNldChQX1JFU0lTVEFOQ0VfTU9ESUZJRVIsIHJlc21vZHMrKFsgIm1lIiA6IHN0cm1hcDsgMCBdKSApOworfQorCitwdWJsaWMgdmFyYXJncyBpbnQgQWRkUmVzaXN0YW5jZU1vZGlmaWVyKG1hcHBpbmcgbW9kLCBzdHJpbmcgYWRkKQoreyBzdHJpbmcgIGtleTsKKyAgbWFwcGluZyByZXM7CisKKyAgaWYgKCAhbWFwcGluZ3AobW9kKSB8fCAhc2l6ZW9mKG1vZCkgfHwgIXByZXZpb3VzX29iamVjdCgpICkKKyAgICByZXR1cm4gMDsKKworICBrZXkgPSBleHBsb2RlKG9iamVjdF9uYW1lKHByZXZpb3VzX29iamVjdCgpKSwiIyIpWzBdOworCisgIGlmICggYWRkICkKKyAgICBrZXkgKz0gKCIjIithZGQpOworCisgIHJlcyA9IFF1ZXJ5KFBfUkVTSVNUQU5DRV9NT0RJRklFUik7CisgIG1vZCA9IGRlZXBfY29weShtb2QpOworCisgIGlmICggIW1hcHBpbmdwKHJlcykgKQorICAgIHJlcyA9IChbIGtleSA6IG1vZDsgcHJldmlvdXNfb2JqZWN0KCkgXSk7CisgIGVsc2UKKyAgICByZXMgKz0gKFsga2V5IDogbW9kOyBwcmV2aW91c19vYmplY3QoKSBdKTsKKworICBTZXQoUF9SRVNJU1RBTkNFX01PRElGSUVSLCByZXMpOworICBVcGRhdGVSZXNpc3RhbmNlU3RyZW5ndGhzKCk7CisKKyAgcmV0dXJuIDE7Cit9CisKK3B1YmxpYyB2YXJhcmdzIHZvaWQgUmVtb3ZlUmVzaXN0YW5jZU1vZGlmaWVyKHN0cmluZyBhZGQpCit7IHN0cmluZyAga2V5OworICBtYXBwaW5nIHJlczsKKworICBpZiAoICFwcmV2aW91c19vYmplY3QoKSApCisgICAgcmV0dXJuOworCisgIGtleSA9IGV4cGxvZGUob2JqZWN0X25hbWUocHJldmlvdXNfb2JqZWN0KCkpLCIjIilbMF07CisKKyAgaWYgKCBhZGQgKQorICAgIGtleSArPSAoIiMiK2FkZCk7CisKKyAgaWYgKCAhbWFwcGluZ3AocmVzID0gUXVlcnkoUF9SRVNJU1RBTkNFX01PRElGSUVSKSkgKQorICAgIHJldHVybjsKKworICBtX2RlbGV0ZShyZXMsIGtleSk7CisgIFNldChQX1JFU0lTVEFOQ0VfTU9ESUZJRVIsIHJlcyk7CisgIFVwZGF0ZVJlc2lzdGFuY2VTdHJlbmd0aHMoKTsKK30KKworLy8gdmVyYWx0ZXRlIFByb3AsIGF1cyBLb21wYXRpYmlsaXRhZXRzZ3J1ZW5kZW4gbm9jaCB2b3JoYW5kZW4uCitzdGF0aWMgbWl4ZWQgX3NldF9yZXNpc3RhbmNlKG1peGVkIGFyZykKK3sgaW50ICAgICBpOworICBtYXBwaW5nIHJlc2ltYXA7CisgIG1peGVkICAgb2xkOworCisgIGlmICggIXBvaW50ZXJwKGFyZykgKQorICAgIGFyZz0oe2FyZ30pOworCisgIGlmICggIW1hcHBpbmdwKHJlc2ltYXA9UXVlcnkoUF9SRVNJU1RBTkNFX1NUUkVOR1RIUykpICkKKyAgICByZXNpbWFwPShbXSk7CisKKyAgaWYgKCBwb2ludGVycChvbGQ9UXVlcnlQcm9wKFBfUkVTSVNUQU5DRSkpICkKKyAgICBmb3IgKCBpPXNpemVvZihvbGQpLTEgOyBpPj0wIDsgaS0tICkKKyAgICAgIHJlc2ltYXBbb2xkW2ldXT0oMS4wKygoZmxvYXQpcmVzaW1hcFtvbGRbaV1dKSkqMi4wLTEuMDsKKworICBmb3IgKCBpPXNpemVvZihhcmcpLTEgOyBpPj0wIDsgaS0tICkKKyAgICByZXNpbWFwW2FyZ1tpXV09KDEuMCsoKGZsb2F0KXJlc2ltYXBbYXJnW2ldXSkpKjAuNS0xLjA7CisKKyAgU2V0UHJvcChQX1JFU0lTVEFOQ0VfU1RSRU5HVEhTLHJlc2ltYXApOworCisgIHJldHVybiBTZXQoUF9SRVNJU1RBTkNFLGFyZyk7Cit9CisKKy8vIHZlcmFsdGV0ZSBQcm9wLCBhdXMgS29tcGF0aWJpbGl0YWV0c2dydWVuZGVuIG5vY2ggdm9yaGFuZGVuLgorc3RhdGljIG1peGVkIF9zZXRfdnVsbmVyYWJpbGl0eShtaXhlZCBhcmcpCit7IGludCAgICAgaTsKKyAgbWFwcGluZyByZXNpbWFwOworICBtaXhlZCAgIG9sZDsKKworICBpZiAoICFwb2ludGVycChhcmcpICkKKyAgICBhcmc9KHthcmd9KTsKKworICBpZiAoICFtYXBwaW5ncChyZXNpbWFwPVF1ZXJ5KFBfUkVTSVNUQU5DRV9TVFJFTkdUSFMpKSApCisgICAgcmVzaW1hcD0oW10pOworCisgIGlmICggcG9pbnRlcnAob2xkPVF1ZXJ5UHJvcChQX1ZVTE5FUkFCSUxJVFkpKSApCisgICAgZm9yICggaT1zaXplb2Yob2xkKS0xIDsgaT49MCA7IGktLSApCisgICAgICByZXNpbWFwW29sZFtpXV09KDEuMCsoKGZsb2F0KXJlc2ltYXBbb2xkW2ldXSkpKjAuNS0xLjA7CisKKyAgZm9yICggaT1zaXplb2YoYXJnKS0xIDsgaT49MCA7IGktLSApCisgICAgcmVzaW1hcFthcmdbaV1dPSgxLjArKChmbG9hdClyZXNpbWFwW2FyZ1tpXV0pKSoyLjAtMS4wOworCisgIFNldFByb3AoUF9SRVNJU1RBTkNFX1NUUkVOR1RIUyxyZXNpbWFwKTsKKworICByZXR1cm4gU2V0KFBfVlVMTkVSQUJJTElUWSxhcmcpOworfQorCisKKy8qKiBraWxsIC0gS2FtcGYgc3RhcnRlbi4KKyAqIEZ1ZWd0IG9iIGRlciBGZWluZGVzbGlzdGUgaGluenUuCisgKi8KK3B1YmxpYyBpbnQgS2lsbChvYmplY3Qgb2IpCit7IGludCAgIHJlcywgYXJlbmE7CisgIGludHxzdHJpbmcgbm9fYXR0YWNrOworCisgIGlmICggIW9iamVjdHAob2IpICkKKyAgICByZXR1cm4gMDsKKworICBpZiAoIG9iLT5RdWVyeVByb3AoUF9HSE9TVCkgKQorICB7CisgICAgdGVsbF9vYmplY3QoTUUsb2ItPk5hbWUoV0VSKSsiIGlzdCBkb2NoIHNjaG9uIHRvdCFcbiIpOworICAgIHJldHVybiAtMTsKKyAgfQorCisgIGlmICggbm9fYXR0YWNrID0gb2ItPlF1ZXJ5UHJvcChQX05PX0FUVEFDSykgKQorICB7CisgICAgaWYgKCBzdHJpbmdwKG5vX2F0dGFjaykgKQorICAgICAgdGVsbF9vYmplY3QoTUUsIG5vX2F0dGFjayk7CisgICAgZWxzZQorICAgICAgdGVsbF9vYmplY3QoTUUsIG9iLT5OYW1lKFdFUiwxKSsiIGxhZXNzdCBzaWNoIG5pY2h0IGFuZ3JlaWZlbiFcbiIpOworCisgICAgcmV0dXJuIC0yOworICB9CisKKyAgaWYgKCBRdWVyeVByb3AoUF9OT19BVFRBQ0spICkKKyAgICByZXR1cm4gLTM7CisKKyAgcmVzPUluc2VydEVuZW15KG9iKTsKKyAgaWYgKHJlcykKKyAgICB0ZWxsX29iamVjdChNRSwgIk9rLlxuIik7CisgIGVsc2UgaWYgKElzRW5lbXkob2IpKQorICAgIHRlbGxfb2JqZWN0KE1FLCAiSmFqYWphLCBtYWNoc3QgRHUgZG9jaCBzY2hvbiFcbiIpOworICAvL2Vsc2UgLy9rZWluIGd1ZWx0aWdlciBGZWluZCwgb2Igd3VyZGUgbmljaHQgZWluZ2V0cmFnZW4uCisKKyAgaWYgKCAhcmVzICkKKyAgICByZXR1cm4gLTQ7ICAvLyBuaWNodCBhZW5kZXJuIG9obmUgS2lsbCBpbiBwbGF5ZXIvY29tYmF0LmMKKworICByZXR1cm4gMTsKK30KKworcHVibGljIGludCBJbnNlcnRTaW5nbGVFbmVteShvYmplY3Qgb2IpCit7CisgICAgaWYgKCAhbGl2aW5nKG9iKSApCisgICAgICAgIHJldHVybiAwOworCisgICAgLy8gV2llIGxhbmdlIHZlcmZvbGd0IGRpZXNlcyBMaXZpbmc/IFdlbm4gUHJvcCBuaWNodCBnZXNldHp0IG9kZXIgCisgICAgLy8gdW5ndWVsdGlnLCBkLmguIGtlaW4gaW50IG9kZXIgPD0gMCwgZGFubiB3aXJkIGRpZSBEZWZhdWx0emVpdCBnZW5vbW1lbi4KKyAgICBpbnQgaHVudHRpbWUgPSAoaW50KVF1ZXJ5UHJvcChQX0hVTlRUSU1FKTsKKyAgICBodW50dGltZSA9IChpbnRwKGh1bnR0aW1lKSAmJiBodW50dGltZSA+IDApID8gCisgICAgICAgICAgICAgICAgIGh1bnR0aW1lIC8gX19IRUFSVF9CRUFUX0lOVEVSVkFMX18gOiBIVU5UVElNRTsKKworICAgIC8vIEF1Y2ggd2VubiBlaW4gT2JqZWt0IHNjaG9uIGFscyBHZWduZXIgZWluZ2V0cmFnZW4gaXN0LCB0cm90emRlbSBkaWUKKyAgICAvLyBIVU5UVElNRSBlcm5ldWVybi4gRGFzICJyZXR1cm4gMDsiIG11c3MgYWJlciBibGVpYmVuLCBkYSBkZXIgR2VnbmVyCisgICAgLy8gamEgbmljaHQgbmV1IGlzdC4KKyAgICAvLworICAgIC8vIDA5LjEyLjIwMDAsIFRpYW1haworICAgIGlmICggbWVtYmVyKCBlbmVtaWVzLCBvYiApICkgeworICAgICAgICBlbmVtaWVzW29iLEVORU1ZX0hVTlRUSU1FXSA9IGh1bnR0aW1lOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBpZiAoIChvYj09TUUpIHx8IFF1ZXJ5UHJvcChQX05PX0FUVEFDSykKKyAgICAgICAgIHx8ICFvYmplY3RwKG9iKSB8fCAob2ItPlF1ZXJ5UHJvcChQX05PX0FUVEFDSykpCisgICAgICAgICB8fCAob2ItPlF1ZXJ5UHJvcChQX0dIT1NUKSkgKQorICAgICAgICByZXR1cm4gMDsKKworICAgIG9iamVjdCB0ZWFtOworICAgIGlmICggKCBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKE1FKSB8fCBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKG9iKSApCisgICAgICAgICAmJiBvYmplY3RwKHRlYW09UXVlcnkoUF9URUFNKSkgJiYgKHRlYW09PShvYi0+UXVlcnkoUF9URUFNKSkpICkKKyAgICAgICAgcmV0dXJuIDA7CisKKyAgICBzZXRfaGVhcnRfYmVhdCgxKTsKKworICAgIGxhc3RfYXR0YWNrX21zZz0wOworCisgICAgZW5lbWllc1tvYixFTkVNWV9IVU5UVElNRV0gPSBodW50dGltZTsKKyAgICBTZXQoUF9MQVNUX0NPTUJBVF9USU1FLHRpbWUoKSk7CisKKyAgICByZXR1cm4gMTsKK30KKworcHVibGljIGludCBJbnNlcnRFbmVteShvYmplY3Qgb2IpCit7IGludCByZXM7CisKKyAgaWYgKCByZXM9SW5zZXJ0U2luZ2xlRW5lbXkob2IpICkKKyAgICBJbnNlcnRFbmVteVRlYW0ob2IpOworCisgIHJldHVybiByZXM7Cit9CisKK3B1YmxpYyBvYmplY3QgUXVlcnlQcmVmZXJlZEVuZW15KCkKK3sgaW50ICAgIHN6LHI7CisgIDxpbnR8b2JqZWN0PiogIHByZWY7CisgIG9iamVjdCBlbmVteTsKKworICBlbmVteT0wOworICBpZiAoIHBvaW50ZXJwKHByZWY9UXVlcnlQcm9wKFBfUFJFRkVSRURfRU5FTVkpKSAmJiAoKHN6PXNpemVvZihwcmVmKSk+MSkKKyAgICAgICYmIGludHAocj1wcmVmWzBdKSAmJiAocmFuZG9tKDEwMCk8cikgKQorICB7CisgICAgZW5lbXk9cHJlZlsxK3JhbmRvbShzei0xKV07CisKKyAgICBpZiAoICFvYmplY3RwKGVuZW15KSApCisgICAgeworICAgICAgcHJlZi09KHtlbmVteX0pOworCisgICAgICBpZiAoIHNpemVvZihwcmVmKTwyICkKKyAgICAgICAgcHJlZj0wOworCisgICAgICBTZXRQcm9wKFBfUFJFRkVSRURfRU5FTVkscHJlZik7CisKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIGlmICggIUlzRW5lbXkoZW5lbXkpICkKKyAgICAgIHJldHVybiAwOworICB9CisKKyAgcmV0dXJuIGVuZW15OworfQorCitwdWJsaWMgb2JqZWN0ICpQcmVzZW50RW5lbWllcygpIHsKKworICBvYmplY3QgKmhlcmU9KHt9KTsKKyAgb2JqZWN0ICpuZXRkZWFkPSh7fSk7CisgIG1peGVkIG5vX2F0dGFjazsKKyAgZm9yZWFjaChvYmplY3QgcGw6IGVuZW1pZXMpIHsKKyAgICBpZiAobm9fYXR0YWNrID0gKG1peGVkKXBsLT5RdWVyeVByb3AoUF9OT19BVFRBQ0spKSB7CisgICAgICBtX2RlbGV0ZShlbmVtaWVzLHBsKTsKKyAgICAgIC8vIFVuZCBhdWNoIGltIEdlZ25lciBhdXN0cmFnZW4sIHNvbnN0IGhhdXQgZGVyIHdlaXRlciB6dSB1bmQgZGllc2VzCisgICAgICAvLyBMaXZpbmcgd2VocnQgc2ljaCBuaWNodC4gKFplc3N0cmEsIDI2LjExLjIwMDYpCisgICAgICBpZiAoc3RyaW5ncChub19hdHRhY2spKSB7CisgICAgICAgIHRlbGxfb2JqZWN0KE1FLCBub19hdHRhY2spOworICAgICAgICBwbC0+U3RvcEh1bnRGb3IoTUUsIDEpOworICAgICAgfQorICAgICAgZWxzZSBwbC0+U3RvcEh1bnRGb3IoTUUsIDApOworICAgIH0KKyAgICBlbHNlIGlmICggZW52aXJvbm1lbnQoKT09ZW52aXJvbm1lbnQocGwpICkKKyAgICB7CisgICAgICBpZiAoIGludGVyYWN0aXZlKHBsKSB8fCAhcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShwbCkgKQorICAgICAgICBoZXJlKz0oe3BsfSk7CisgICAgICBlbHNlCisgICAgICAgIG5ldGRlYWQrPSh7cGx9KTsKKyAgICB9CisgIH0KKworICBpZiAoICFzaXplb2YoaGVyZSkgKSAvLyBOZXR6dG90ZSBzaW5kIG51ciBGZWluZGUsIGZhbGxzIGtlaW5lIGFuZGVyZW4gZGEgc2luZAorICAgIHJldHVybiBuZXRkZWFkOworCisgIHJldHVybiBoZXJlOworfQorCitwdWJsaWMgdmFyYXJncyBvYmplY3QgU2VsZWN0RW5lbXkob2JqZWN0ICpoZXJlKQoreyBvYmplY3QgZW5lbXk7CisKKyAgaWYgKCAhcG9pbnRlcnAoaGVyZSkgKQorICAgIGhlcmU9UHJlc2VudEVuZW1pZXMoKTsKKworICBpZiAoICFzaXplb2YoaGVyZSkgKQorICAgIHJldHVybiAwOworCisgIGlmICggIW9iamVjdHAoZW5lbXk9UXVlcnlQcmVmZXJlZEVuZW15KCkpCisgICAgICB8fCAoZW52aXJvbm1lbnQoZW5lbXkpIT1lbnZpcm9ubWVudCgpKSApCisgICAgZW5lbXk9aGVyZVtyYW5kb20oc2l6ZW9mKGhlcmUpKV07CisKKyAgcmV0dXJuIGVuZW15OworfQorCitwcm90ZWN0ZWQgdm9pZCBoZWFydF9iZWF0KCkgeworICBpbnQgaGJzOyAKKyAgLy8gbGVpZGVyIHJ1ZmVuIHZpZWxlIExldXRlIGVpbmZhY2ggZGFzIGdlZXJidGUgaGVhcnRfYmVhdCgpIG9id29obCBzaWUKKyAgLy8gc2Nob24gdG90IHNpbmQgdW5kIGRhbWl0IGRhcyBPYmpla3QgemVyc3RvZXJ0IGlzdC4KKyAgaWYgKCFsaXZpbmcodGhpc19vYmplY3QoKSkpCisgICAgICByZXR1cm47CisKKyAgLy8gUGFyYWx5c2UgcHJ1ZWZlbiwgZ2dmLiByZWR1emllcmVuCisgIGludCBkaXNfYXR0YWNrID0gUXVlcnlQcm9wKFBfRElTQUJMRV9BVFRBQ0spOworICBpZiAoIGludHAoZGlzX2F0dGFjaykgJiYgKGRpc19hdHRhY2sgPiAwKSApCisgIHsKKyAgICAgIFNldFByb3AoUF9ESVNBQkxFX0FUVEFDSywgLS1kaXNfYXR0YWNrKTsKKyAgfQorCisgIC8vIEF0dGFja2VuIGVybWl0dGVsbjogU0FfU1BFRUQgKyBSZXN0IGF1cyBkZW0gbGV0enRlbiBIQgorICBoYnMgPSByZW1haW5pbmdfaGVhcnRfYmVhdHMgKyBRdWVyeVNraWxsQXR0cmlidXRlKFNBX1NQRUVEKTsKKyAgaWYgKCBoYnMgPD0gMCApCisgICAgaGJzID0gMTAwOyAKKworICAvLyBQX0FUVEFDS19CVVNZIGJlc3RpbW1lbgorICBpZiAoIGF0dGFja19idXN5ID4gOTkpIAorICAgYXR0YWNrX2J1c3kgPSAxMDAgKyBoYnM7CisgIGVsc2UKKyAgICBhdHRhY2tfYnVzeSArPSAxMDAgKyBoYnM7CisgIC8vIG1laHIgZnVlciBTZWhlci4uLgorICBpZiAoIElTX1NFRVIoTUUpICkKKyAgICBhdHRhY2tfYnVzeSs9KDEwMCtRdWVyeVByb3AoUF9MRVZFTCkpOyAKKyAgLy8gbWF4LiA1MDAsIGQuaC4gNSBBdHRhY2tlbgorICBpZiAoIGF0dGFja19idXN5PjUwMCApCisgICAgYXR0YWNrX2J1c3k9NTAwOworCisgIC8vIHVuZ2FuenphaGxpZ2VuIFJlc3QgZnVlciBuYWVjaHN0ZW4gSEIgc3BlaWNoZXJuCisgIHJlbWFpbmluZ19oZWFydF9iZWF0cyA9IGhicyAlIDEwMDsKKyAgaGJzIC89IDEwMDsgLy8gZ2FuemUgQXR0YWNrZW4uIDstKQorCisgIGlmICggaGJzID4gMTAgKSAvLyBuaWNodCBtZWhyIGFscyAxMCBBdHRhY2tlbi4KKyAgICBoYnMgPSAxMDsgCisKKyAgLy8gRmFsbHMgamVtYW5kIHNlaXQgZGVtIGxldHp0ZW4gSEIgaW4gZGllc2VtIExpdmluZyB2b24gYXVzc2VuIEF0dGFjaygpCisgIC8vIGdlcnVmZW4gaGF0IChuaWNodCBFeHRyYUF0dGFjaygpKSwgd2lyZCBqZXR6dCB3YXMgYWJnZXpvZ2VuLgorICBoYnMgLT0gbm9fbW9yZV9hdHRhY2tzOworICBub19tb3JlX2F0dGFja3MgPSAwOworCisgIC8vIFdpZSBsYW5nZSB2ZXJmb2xndCBkaWVzZXIgTlBDPyBXZW5uIFByb3AgbmljaHQgZ2VzZXR6dCBvZGVyIHVuZ3VlbHRpZywKKyAgLy8gZC5oLiBrZWluIGludCBvZGVyIDw9IDAsIGRhbm4gd2lyZCBkaWUgRGVmYXVsdHplaXQgZ2Vub21tZW4uCisgIGludCBodW50dGltZSA9IChpbnQpUXVlcnlQcm9wKFBfSFVOVFRJTUUpOworICBodW50dGltZSA9IChpbnRwKGh1bnR0aW1lKSAmJiBodW50dGltZSA+IDApID8gCisgICAgICAgICAgICAgIGh1bnR0aW1lIC8gX19IRUFSVF9CRUFUX0lOVEVSVkFMX18gOiBIVU5UVElNRTsKKyAgLy8gZXJzdG1hbCBkaWUgSHVudHRpbWVzIGRlciBHZWduZXIgYWt0dWFsaXNpZXJlbiB1bmQgbmViZW5iZWkgZGllCisgIC8vIGFud2VzZW5kZW4gRmVpbmRlIG1lcmtlbi4gQXVzc2VyZGVtIGdnZi4gS2FtcGYgYWJicmVjaGVuLCB3ZW5uCisgIC8vIFBfTk9fQVRUQUNLIGdlc2V0enQgaXN0LgorICAvLyBlaWdlbnRsaWNoIGlzdCBkaWVzZSBnYW56ZSBTY2hsZWlmZSBmYXN0IGRhcyBnbGVpY2hlIHdpZQorICAvLyBQcmVzZW50RW5lbWllcygpLCBhYmVyIGxlaWRlciBtdWVzc2VuIGphIGRpZSBIdW50dGltZXMgYWt0dWxpc2llcnQgd2VyZGUsCisgIC8vIGRhaGVyIGthbm4gbWFuIG5pY2h0IGRpcmVrdCBQcmVzZW50RW5lbWllcygpIG5laG1lbi4KKyAgLy8gVE9ETzogRGllc2UgU2NobGVpZmUgdW5kIFByZXNlbnRFbm1pZXMoKSBpcmdlbmR3aWUgdmVyZWluaWdlbi4KKyAgb2JqZWN0ICpuZXRkZWFkPSh7fSk7CisgIG9iamVjdCAqaGVyZT0oe30pOworICBvYmplY3QgZW5lbXk7CisgIG1peGVkIG5vX2F0dGFjazsKKyAgZm9yZWFjaChlbmVteSwgaW50IGh0aW1lOiAmZW5lbWllcykgeyAvLyBLZXlzIGluIGVuZW15CisgICAgLy8gZ2dmLiBNZWxkdW5nZW4gYXVzZ2ViZW4gdW5kIEdlZ25lciBhdXN0cmFnZW4gdW5kIGRpZXNlcyBMaXZpbmcgYmVpbQorICAgIC8vIEdlZ25lciBhdXN0cmFnZW4uCisgICAgaWYgKG5vX2F0dGFjaz1lbmVteS0+UXVlcnlQcm9wKFBfTk9fQVRUQUNLKSkgeworICAgICAgbV9kZWxldGUoZW5lbWllcyxlbmVteSk7CisgICAgICAgIGlmICggc3RyaW5ncChub19hdHRhY2spICkgeworICAgICAgICAgICAgd3JpdGUoIG5vX2F0dGFjayApOworICAgICAgICAgICAgZW5lbXktPlN0b3BIdW50Rm9yKCBNRSwgMSApOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIGVuZW15LT5TdG9wSHVudEZvciggTUUsIDAgKTsKKyAgICB9CisgICAgZWxzZSBpZiAoIGVudmlyb25tZW50KCk9PWVudmlyb25tZW50KGVuZW15KSApIHsKKyAgICAgIC8vIEdlZ25lciBhbndlc2VuZCwgYWxzIEZlaW5kIG1lcmtlbi4uLgorICAgICAgaWYgKCBpbnRlcmFjdGl2ZShlbmVteSkgfHwgIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoZW5lbXkpICkKKyAgICAgICAgaGVyZSs9KHtlbmVteX0pOworICAgICAgZWxzZQorICAgICAgICBuZXRkZWFkKz0oe2VuZW15fSk7CisgICAgICAvLyAuLi4gdW5kIEh1bnR0aW1lIGVybmV1ZXJuLgorICAgICAgaHRpbWUgPSBodW50dGltZTsKKyAgICB9CisgICAgLy8gRmVpbmQgbmljaHQgYW53ZXNlbmQuIFRpbWVyIGRla3JlbWVudGllcmVuIHVuZCBGZWluZCBhdXN0cmFnZW4sIHdlbm4KKyAgICAvLyBKYWdkemVpdCBhYmdlbGF1ZmVuLgorICAgIGVsc2UgaWYgKCAoLS1odGltZSkgPD0gMCApCisgICAgICBTdG9wSHVudEZvcihlbmVteSk7CisgIH0KKyAgLy8gTmV0enRvdGUgc2luZCBudXIgRmVpbmRlLCB3ZW5uIHNvbnN0IGtlaW5lIGRhIHNpbmQuCisgIGlmICggIXNpemVvZihoZXJlKSApCisgICAgaGVyZT1uZXRkZWFkOworCisgIC8vIHNjaG9ubWFsIGFiZnJhZ2VuLCBvYiBlaW4gU3BlbGwgdm9yYmVyZWl0ZXQgd2lyZC4KKyAgbWl4ZWQgcHNwZWxsPVF1ZXJ5UHJvcChQX1BSRVBBUkVEX1NQRUxMKTsKKworICAvL0RhIGhicyAwIHVuZCBub19tb3JlX2F0dGFja3MgZHVyY2ggZWluZW4gbWFudWVsbGVuIEF1ZnJ1ZiB2b24gQXR0YWNrKCkgaW0KKyAgLy9TcGllbGVyID4wIHNlaW4ga2Fubiwga2FubiBqZXR6dCBoYnMgPDAgc2Vpbi4gKHMuby4pCisgIGlmIChoYnMgPiAwICYmIHNpemVvZihoZXJlKSkgeworICAgIGZvcmVhY2goaW50IGk6IGhicykgeworICAgICAgLy8gRmVpbmQgaW4gTmFoa2FtcGZyZWljaHdlaXRlIGZpbmRlbgorICAgICAgaWYgKCBvYmplY3RwKGVuZW15PVNlbGVjdE5lYXJFbmVteShoZXJlKSkgKSB7CisgICAgICAgIC8vIEZsdWNodCBlcnd1ZW5zY2h0PworICAgICAgICBpZiAoIFF1ZXJ5UHJvcChQX1dJTVBZKSA+IFF1ZXJ5UHJvcChQX0hQKSApIHsKKyAgICAgICAgICBGbGVlKCk7CisgICAgICAgICAgLy8gRmx1Y2h0IGdlbHVuZ2VuPworICAgICAgICAgIGlmICggZW5lbXkgJiYgKGVudmlyb25tZW50KGVuZW15KSE9ZW52aXJvbm1lbnQoKSkgKSB7CisgICAgICAgICAgICBoZXJlID0gMDsgLy8gbmFlY2hzdGUgUnVuZGUgbmV1ZSBGZWluZGUgc3VjaGVuCisgICAgICAgICAgICBlbmVteSA9IDA7CisgICAgICAgICAgICBjb250aW51ZTsgLy8ga2VpbiBLYW1wZiwgUnVuZGUgdWViZXJzcHJpbmdlbgorICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgICAgZWxzZSB7CisgICAgICAgIC8vIGtlaW5lIEZlaW5kZSBnZWZ1bmRlbi4uLiBBYmJyZWNoZW4uCisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgLy8gUGFyYWx5c2UgZ2VzZXR6dD8gLT4gQWJicmVjaGVuLiBEaWVzZXMgUHJ1ZWZ1bmcgbXVzcyBoaWVyIHBhc3NpZXJlbiwKKyAgICAgIC8vIGRhbWl0IGdnZi4gZGllIGF1dG9tYXRpc2NoZSBGbHVjaHQgZGVzIExlYmV3ZXNlbnMgZHVyY2hnZWZ1ZWhydCB3aXJkLAorICAgICAgLy8gYXVjaCB3ZW5uIGVzIHBhcmFseXNpZXJ0IGlzdC4KKyAgICAgIGlmIChkaXNfYXR0YWNrID4gMCkgYnJlYWs7CisKKyAgICAgIC8vIEthbXBmIGR1cmNoIFNwZWxsLVByZXBhcmUgYmxvY2tpZXJ0PworICAgICAgLy8gS2VpbmUgZ2VuYXVlIEFiZnJhZ2UsIHdpcmQgc3BhZXRlciBub2NoIGdlbmF1IGdlcHJ1ZWZ0LgorICAgICAgaWYgKCBwc3BlbGwgJiYgUXVlcnlQcm9wKFBfR1VJTERfUFJFUEFSRUJMT0NLKSApCisgICAgICAgIGJyZWFrOyAvLyBrZWluZSBBbmdyaWZmZSBpbiBkaWVzZW0gSEIuCisgICAgICAvLyB3ZW5uIEZlaW5kIGRhOiBoaXQnZW0gaGFyZC4KKyAgICAgIGlmICggb2JqZWN0cChlbmVteSkgKQorICAgICAgICBBdHRhY2soZW5lbXkpOworICAgICAgLy8gZ2dmLiBoYXQgQXR0YWNrKCkgbm9fbW9yZV9hdHRhY2tzIGdlc2V0enQuIFp1cnVlY2tzZXR6ZW4KKyAgICAgIG5vX21vcmVfYXR0YWNrcyA9IDA7CisgICAgICAvLyBuYWVjaHN0ZSBLYW1wZnJ1bmRlIG5ldWUgRmVpbmRlIHN1Y2hlbgorICAgICAgaGVyZSA9IDA7CisgICAgfSAgLy8gZm9yZWFjaAorICB9CisKKyAgbm9fbW9yZV9hdHRhY2tzPTA7CisKKyAgLy8gSXN0IGVpbiBTcGVsbCBpbiBWb3JiZXJlaXR1bmcgdW5kIGV2dGwuIGpldHp0IGZlcnRpZyB2b3JiZXJlaXRldD8KKyAgaWYgKCBwb2ludGVycChwc3BlbGwpCisgICAgICAmJiAoc2l6ZW9mKHBzcGVsbCk+PTMpICYmIGludHAocHNwZWxsWzBdKSAmJiBzdHJpbmdwKHBzcGVsbFsxXSkgKSB7CisgICAgaWYgKCB0aW1lKCk+PXBzcGVsbFswXSApIC8vIEthbm4gZGVyIFNwcnVjaCBqZXR6dCBhdXNnZWZ1ZWhydCB3ZXJkZW4/CisgICAgeworICAgICAgVXNlU3BlbGwocHNwZWxsWzJdLHBzcGVsbFsxXSk7IC8vIERhbm4gbG9zCisgICAgICBTZXRQcm9wKFBfUFJFUEFSRURfU1BFTEwsMCk7CisgICAgfQorICB9CisgIGVsc2UgaWYgKCBwc3BlbGwgKSAvLyBVbmJyYXVjaGJhcmVyIFdlcnQsIGxvZXNjaGVuCisgICAgU2V0UHJvcChQX1BSRVBBUkVEX1NQRUxMLDApOworCit9IC8vIEVuZGUgaGVhcnRfYmVhdAorCisvLyB3aXJkIHZvbiBOUEMgZ2VydWZlbiwgZGllIEhlYXJ0YmVhdHMgbmFjaGhvbGVuIHVuZCBkYWJlaSBkaWUgSHVudHRpbWVzIHVtCisvLyBkaWUgQW56YWhsIHZlcnBhc3N0ZXIgSGVhcnRiZWF0cyByZWR1emllcmVuIG11ZXNzZW4uCisvLyBXaXJkIHZvbiBTcGllbGVyb2JqZWt0ZW4gZ2VydWZlbiwgd2VubiBzaWUgbmFjaCAnc2NobGFmZSBlaW4nIGF1ZndhY2hlbiwgdW0KKy8vIGRpZSBub3R3ZW5kaWdlIEFuemFobCBhbiBIQiBoaWVyIGFienV6aWVoZW4gdW5kIGdnZi4gZGllIEZlaW5kZSB6dSBleHBpcmVuLAorLy8gZGEgU3BpZWxlciBqYSBuZXR6dG90IGtlaW5lbiBIZWFydGJlYXQgaGFiZW4uCitwcm90ZWN0ZWQgdm9pZCB1cGRhdGVfaHVudF90aW1lcyhpbnQgYmVhdHMpIHsKKyAgaWYgKCFtYXBwaW5ncChlbmVtaWVzKSkgcmV0dXJuOworICBmb3JlYWNoKG9iamVjdCBlbiwgaW50IGh0aW1lOiAmZW5lbWllcykgeyAvLyBNYXBwaW5nLUtleXMgaW4gZW4KKyAgICBodGltZSAtPSBiZWF0czsKKyAgICBpZiAoIGh0aW1lIDw9IDAgKQorICAgICAgU3RvcEh1bnRGb3IoZW4pOworICB9Cit9CisKK3B1YmxpYyBpbnQgSXNFbmVteShvYmplY3Qgd2VyKQoreworICByZXR1cm4gKG1lbWJlcihlbmVtaWVzLHdlcikpOworfQorCitwdWJsaWMgdm9pZCBTdG9wSHVudFRleHQob2JqZWN0IGFyZykKK3sKKyAgdGVsbF9vYmplY3QoYXJnLAorICAgIE5hbWUoV0VSLDEpKyIgIisoUXVlcnlQcm9wKFBfUExVUkFMKT8iamFnZW4gIjoiamFndCAiKSsKKyAgICAgICAgICAgICAgIChhcmctPlF1ZXJ5UHJvcChQX1BMVVJBTCk/IkV1Y2giOiJEaWNoIikrIiBuaWNodCBtZWhyLlxuIik7CisgIHRlbGxfb2JqZWN0KE1FLChRdWVyeVByb3AoUF9QTFVSQUwpPyJJaHIgamFndCAiOiJEdSBqYWdzdCAiKSsKKyAgICAgICAgICAgICAgICAgYXJnLT5uYW1lKFdFTiwxKSsiIG5pY2h0IG1laHIuXG4iKTsKK30KKworcHVibGljIHZhcmFyZ3MgaW50IFN0b3BIdW50Rm9yKG9iamVjdCBhcmcsIGludCBzaWxlbnQpCit7CisgIGlmICggIW9iamVjdHAoYXJnKSB8fCAhSXNFbmVteShhcmcpICkKKyAgICByZXR1cm4gMDsKKworICBpZiAoIXNpbGVudCkKKyAgICBTdG9wSHVudFRleHQoYXJnKTsKKworICBtX2RlbGV0ZShlbmVtaWVzLGFyZyk7CisgIGxhc3RfYXR0YWNrX21zZz0wOworCisgIHJldHVybiAxOworfQorCisvLyBCZWdydWVzc3VuZ3NzY2hsYWcgbnVyIGVpbm1hbCBwcm8gSEIKK3B1YmxpYyB2b2lkIEF0dGFjazIob2JqZWN0IGVuZW15KQoreworICBpZiAoIGF0dDJfdGltZSA+IHRpbWUoKSApCisgICAgcmV0dXJuOworCisgIGF0dDJfdGltZT10aW1lKCkgKyBfX0hFQVJUX0JFQVRfSU5URVJWQUxfXzsKKyAgQXR0YWNrKGVuZW15KTsKK30KKworLy8gRnVlciBldnRsLiBBdHRhY2stQWVuZGVydW5nZW4sIG9obmUgZGFzcyBtYW4gZ2xlaWNoIGRhcyBnYW56ZQorLy8gQXR0YWNrIHVlYmVybGFnZXJuIG11c3M6Citwcm90ZWN0ZWQgdm9pZCBJbnRlcm5hbE1vZGlmeUF0dGFjayhtYXBwaW5nIGFpbmZvKQoreworICByZXR1cm47IC8vIFZvcmVyc3QhCisvKgorICBpbnQgICBmYWM7CisgIG1peGVkIHJlczsKKworICBmYWM9MTAwOworCisgIGlmIChDYW5ub3RTZWUoMSkpCisgICAgZmFjIC09IDUwOworCisgIC8vIFdlaXRlcmUgTWFsaT8KKworICBpZiAoZmFjPDEwMCkKKyAgICBhaW5mb1tTSV9TS0lMTERBTUFHRV0gPSBhaW5mb1tTSV9TS0lMTERBTUFHRV0qZmFjLzEwMDsKKyAgLy8gRmVydGlnCisqLworfQorCisvLyBBdXNmdWVocmVuIEVpbmVzIEFuZ3JpZmZzIGF1Y2ggd2VubiBlcyBiZXJlaXRzIGVpbmVuIEFuZ3JpZmYKKy8vIGluIGRpZXNlciBSdW5kZSBnZWdlYmVuIGhhdC4gRGllc2VyIEFuZ3JpZmYgd2lyZCBhdWNoIG5pY2h0CisvLyBnZXphZWhsdC4gRGllIE51dHp1bmcgZGllc2VyIEZ1bmt0aW9uIGlzdCBudXIgZnVlciBTcGV6aWFsZmFlbGxlCisvLyBnZWRhY2h0IHVuZCBpbW1lciBCQUxBTkNFUEZMSUNIVElHIQordmFyYXJncyBwdWJsaWMgdm9pZCBFeHRyYUF0dGFjayhvYmplY3QgZW5lbXksIGludCBpZ25vcmVfcHJldmlvdXMpCit7CisgIGludCBzYXZlZF9ub19tb3JlX2F0dGFja3M7CisKKyAgLy8gRXJzdHNjaGxhZ3NpbmZvIHNwZWljaGVybi4KKyAgc2F2ZWRfbm9fbW9yZV9hdHRhY2tzID0gbm9fbW9yZV9hdHRhY2tzOworCisgIC8vIEJlaSBCZWRhcmYgYmlzaGVyIHNjaG9uIGR1cmNoZ2VmdWVocnRlIEVyc3RzY2hsYWVnZSBpZ25vcmllcmVuCisgIGlmIChpZ25vcmVfcHJldmlvdXMpIG5vX21vcmVfYXR0YWNrcz0wOworCisgIC8vIE5vcm1hbGVuIEFuZ3JpZmYgZHVyY2hmdWVocmVuCisgIEF0dGFjayAoZW5lbXkpOworCisgIC8vIEdlc3BlaWNoZXJ0ZW4gV2VydCB6dXJ1ZWNrc2V0emVuCisgIG5vX21vcmVfYXR0YWNrcyA9IHNhdmVkX25vX21vcmVfYXR0YWNrczsKKworICByZXR1cm47Cit9CisKK3B1YmxpYyB2b2lkIEF0dGFjayhvYmplY3QgZW5lbXkpCit7CisgIGNsb3N1cmUgY2w7CisgIG1peGVkICAgcmVzOworICBtYXBwaW5nIGFpbmZvOworICBtYXBwaW5nIGVkZWZlbmRpbmZvOyAvLyBlcndlaXRlcnRlIERlZmVuZC1JbmZvcworICBtaXhlZCBob29rRGF0YTsKKyAgbWl4ZWQgaG9va1JlczsKKworICBpZiAoIG5vX21vcmVfYXR0YWNrcyB8fCBRdWVyeVByb3AoUF9HSE9TVCkgfHwgCisgICAgICAhb2JqZWN0cChlbmVteSkgfHwgIW9iamVjdHAodGhpc19vYmplY3QoKSkgfHwgCisgICAgICAoUXVlcnlQcm9wKFBfRElTQUJMRV9BVFRBQ0spID4gMCkgfHwgZW5lbXktPlF1ZXJ5UHJvcChQX05PX0FUVEFDSykgfHwgCisgICAgICAocXVlcnlfb25jZV9pbnRlcmFjdGl2ZSh0aGlzX29iamVjdCgpKSAmJiAhaW50ZXJhY3RpdmUodGhpc19vYmplY3QoKSkpICkKKyAgICByZXR1cm47CisKKyAgZWRlZmVuZGluZm89KFtdKTsKKworICBTZXQoUF9MQVNUX0NPTUJBVF9USU1FLHRpbWUoKSk7CisKKyAgLy8gaW5rcmVtZW50aWVyZW4uIERpZXNlIFZhcmlhYmxlIHdpcmQgaW0gSEIgbmFjaCBkZW4gQW5ncmlmZmVuIGdlbnVsbHQuCisgIC8vIERpZXNlIFZhcmlhYmxlIHdpcmQgaW0gbmFlY2hzdGVuIEhlYXJ0YmVhdCB2b24gZGVyIEFuemFobCBhbiB2ZXJmdWVnYmFyZW4KKyAgLy8gQW5ncmlmZmVuIGRlcyBMaXZpbmdzIGFiZ2V6b2dlbi4gRGllcyBiZXJ1ZWNrc2ljaHRpZ3QgYWxzbyB6d2lzY2hlbiBkZW4KKyAgLy8gSEJzICh6LkIuIGV4dGVybikgZ2VydWZlbmUgQXR0YWNrcygpLgorICBub19tb3JlX2F0dGFja3MrKzsKKworICAvLyBXaXJkIGRhcyBBdHRhY2sgZHVyY2ggZWluZW4gdGVtcG9yYWVyZW4gQXR0YWNrLUhvb2sgZXJzZXR6dD8KKyAgaWYgKCByZXM9UXVlcnlQcm9wKFBfVE1QX0FUVEFDS19IT09LKSApCisgIHsKKyAgICBpZiAoIHBvaW50ZXJwKHJlcykgJiYgKHNpemVvZihyZXMpPj0zKSAmJiBpbnRwKHJlc1swXSkgJiYgKHRpbWUoKTxyZXNbMF0pCisgICAgICAgICYmIG9iamVjdHAocmVzWzFdKSAmJiBzdHJpbmdwKHJlc1syXSkgKQorICAgIHsKKyAgICAgIGlmICggIShyZXM9Y2FsbF9vdGhlcihyZXNbMV0scmVzWzJdLGVuZW15KSkgKQorICAgICAgICByZXR1cm47CisgICAgfQorICAgIGVsc2UKKyAgICAgIFNldFByb3AoUF9UTVBfQVRUQUNLX0hPT0ssMCk7CisgIH0KKworICAvLyB0cmlnZ2VyIGF0dGFjayBob29rCisgIGhvb2tEYXRhPSh7ZW5lbXl9KTsKKyAgaG9va1Jlcz1Ib29rRmxvdyhIX0hPT0tfQVRUQUNLLGhvb2tEYXRhKTsKKyAgaWYoaG9va1JlcyAmJiBwb2ludGVycChob29rUmVzKSAmJiBzaXplb2YoaG9va1Jlcyk+SF9SRVREQVRBKXsKKyAgICBpZihob29rUmVzW0hfUkVUQ09ERV09PUhfQ0FOQ0VMTEVEKXsKKyAgICAgIHJldHVybjsKKyAgICB9CisgIH0KKworICBhaW5mbyA9IChbIFNJX0VORU1ZIDogZW5lbXksCisgICAgICAgICAgICAgU0lfU1BFTEwgOiAwLAorICAgICAgICAgICBdKTsKKworICBpZiAoIG9iamVjdHAoYWluZm9bUF9XRUFQT05dPVF1ZXJ5UHJvcChQX1dFQVBPTikpICkKKyAgeworICAgIGFpbmZvW1BfV0VBUE9OXS0+VGFrZUZsYXcoZW5lbXkpOworCisgICAgLy8gQWJmcmFnZSBmdWVyIGRlbiBGYWxsLCBkYXNzIFdhZmZlIGR1cmNoIGRhcyBUYWtlRmxhdygpIHplcnN0b2VydAorICAgIC8vIHd1cmRlLiBEYW5uIHdpcmQgZGFzIEF0dGFjayBhYmdlYnJvY2hlbi4KKyAgICBpZiAoICFvYmplY3RwKGFpbmZvW1BfV0VBUE9OXSkgKQorICAgICAgcmV0dXJuOworCisgICAgY2w9c3ltYm9sX2Z1bmN0aW9uKCJuYW1lIixhaW5mb1tQX1dFQVBPTl0pOworICAgIGFpbmZvW1NJX1NLSUxMREFNQUdFX01TR10gPSAoIiBtaXQgIisoc3RyaW5nKWZ1bmNhbGwoY2wsV0VNLDApKTsKKyAgICBhaW5mb1tTSV9TS0lMTERBTUFHRV9NU0cyXSA9ICgiIG1pdCAiKyhzdHJpbmcpZnVuY2FsbChjbCxXRU0sMSkpOworCisgICAgYWluZm9bU0lfU0tJTExEQU1BR0VdID0gKGludClhaW5mb1tQX1dFQVBPTl0tPlF1ZXJ5RGFtYWdlKGVuZW15KTsKKworICAgIGNsPXN5bWJvbF9mdW5jdGlvbigiUXVlcnlQcm9wIixhaW5mb1tQX1dFQVBPTl0pOworICAgIGFpbmZvW1NJX1NLSUxMREFNQUdFX1RZUEVdID0gZnVuY2FsbChjbCxQX0RBTV9UWVBFKTsKKyAgICBhaW5mb1tQX1dFQVBPTl9UWVBFXSA9IChzdHJpbmcpZnVuY2FsbChjbCxQX1dFQVBPTl9UWVBFKTsKKyAgICBhaW5mb1tQX05SX0hBTkRTXSA9IChpbnQpZnVuY2FsbChjbCxQX05SX0hBTkRTKTsKKyAgICBhaW5mb1tQX1dDXSA9IChpbnQpZnVuY2FsbChjbCxQX1dDKTsKKworICAgIC8vIFp3ZWloYWVuZGlnZSBXYWZmZT8KKyAgICBpZiAoIGFpbmZvW1BfTlJfSEFORFNdPT0yCisgICAgICAgICYmIG1hcHBpbmdwKHJlcz1Vc2VTa2lsbChTS19UV09IQU5ERUQsZGVlcF9jb3B5KGFpbmZvKSkpCisgICAgICAgICYmIG1lbWJlcihyZXMsU0lfU0tJTExEQU1BR0UpICkKKyAgICB7CisgICAgICAvLyBOdXIgZGVuIG5ldWVuIFNjaGFkZW5zd2VydCB1ZWJlcm5laG1lbi4KKyAgICAgIGFpbmZvW1NJX1NLSUxMREFNQUdFXT0oKGludCkocmVzW1NJX1NLSUxMREFNQUdFXSkpOworICAgIH0KKyAgfQorICBlbHNlIC8vIEtlaW5lIFdhZmZlIGdlenVlY2t0CisgIHsKKyAgICAvKiBDaGVjayBpZiB0aGVyZSBpcyBhIG1hZ2ljYWwgYXR0YWNrICovCisgICAgaWYgKCBtYXBwaW5ncChyZXM9VXNlU2tpbGwoU0tfTUFHSUNfQVRUQUNLLChbU0lfRU5FTVk6ZW5lbXldKSkpICkKKyAgICB7CisgICAgICBhaW5mb1tTSV9TS0lMTERBTUFHRV09KGludClyZXNbU0lfU0tJTExEQU1BR0VdOworICAgICAgYWluZm9bU0lfU0tJTExEQU1BR0VfVFlQRV09cmVzW1NJX1NLSUxMREFNQUdFX1RZUEVdOworCisgICAgICBpZiAoIHN0cmluZ3AocmVzW1NJX1NLSUxMREFNQUdFX01TR10pICkKKyAgICAgICAgYWluZm9bU0lfU0tJTExEQU1BR0VfTVNHXSA9ICIgbWl0ICIrKHN0cmluZylyZXNbU0lfU0tJTExEQU1BR0VfTVNHXTsKKyAgICAgIGVsc2UKKyAgICAgICAgYWluZm9bU0lfU0tJTExEQU1BR0VfTVNHXSA9ICIgbWl0IG1hZ2lzY2hlbiBGYWVoaWdrZWl0ZW4iOworCisgICAgICBpZiAoIHN0cmluZ3AocmVzW1NJX1NLSUxMREFNQUdFX01TRzJdKSApCisgICAgICAgIGFpbmZvW1NJX1NLSUxMREFNQUdFX01TRzJdID0gIiBtaXQgIisoc3RyaW5nKXJlc1tTSV9TS0lMTERBTUFHRV9NU0cyXTsKKyAgICAgIGVsc2UKKyAgICAgICAgYWluZm9bU0lfU0tJTExEQU1BR0VfTVNHMl0gPSAoc3RyaW5nKWFpbmZvW1NJX1NLSUxMREFNQUdFX01TR107CisKKyAgICAgIGlmICggIShhaW5mb1tQX1dFQVBPTl9UWVBFXT1yZXNbUF9XRUFQT05fVFlQRV0pICkKKyAgICAgICAgYWluZm9bUF9XRUFQT05fVFlQRV09V1RfTUFHSUM7CisKKyAgICAgIGlmICggbWVtYmVyKHJlcyxTSV9TUEVMTCkgKQorICAgICAgICBhaW5mb1tTSV9TUEVMTF09cmVzW1NJX1NQRUxMXTsKKyAgICB9CisgICAgZWxzZQorICAgIHsKKyAgICAgIC8qIE9obmUgKGZyZWllKSBIYWVuZGUgd2lyZCBhdWNoIG5pY2h0IGFuZ2VncmlmZmVuICovCisgICAgICBpZiAoIGludGVyYWN0aXZlKHRoaXNfb2JqZWN0KCkpCisgICAgICAgICAgJiYgKFF1ZXJ5UHJvcChQX1VTRURfSEFORFMpID49IFF1ZXJ5UHJvcChQX01BWF9IQU5EUykpICkKKyAgICAgICAgcmV0dXJuIDsKKworICAgICAgaWYgKCAhcG9pbnRlcnAocmVzPVF1ZXJ5UHJvcChQX0hBTkRTKSkgfHwgKHNpemVvZihyZXMpPDIpICkKKyAgICAgICAgcmV0dXJuOworCisgICAgICBhaW5mb1tTSV9TS0lMTERBTUFHRV0gPSAoKCAyKnJhbmRvbSgoKGludClyZXNbMV0pKzEpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIDEwKihRdWVyeUF0dHJpYnV0ZShBX1NUUikpICkvMyk7CisgICAgICBhaW5mb1tTSV9TS0lMTERBTUFHRV9UWVBFXSA9IHJlc1syXTsKKyAgICAgIGFpbmZvW1NJX1NLSUxMREFNQUdFX01TR10gPSBhaW5mb1tTSV9TS0lMTERBTUFHRV9NU0cyXQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICgoc3RyaW5nKXJlc1swXSk7CisgICAgICBhaW5mb1tQX1dFQVBPTl9UWVBFXSA9IFdUX0hBTkRTOworICAgICAgYWluZm9bUF9XQ10gPSAoaW50KXJlc1sxXTsKKyAgICB9CisgIH0gIC8vIGJlc29uZGVyZSBGYWVoaWdrZWl0ZW4gbWl0IGRpZXNlbSBXYWZmZW50eXA/CisgIGlmICggbWFwcGluZ3AocmVzPVVzZVNraWxsKEZJR0hUKGFpbmZvW1BfV0VBUE9OX1RZUEVdKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVlcF9jb3B5KGFpbmZvKSkpICkKKyAgICBTa2lsbFJlc1RyYW5zZmVyKHJlcyxhaW5mbyk7CisKKyAgLy8gYmVzb25kZXJlIGFsbGdlbWVpbmUgS2FtcGZmYWVoaWdrZWl0ZW4/CisgIGlmICggbWFwcGluZ3AocmVzPVVzZVNraWxsKFNLX0ZJR0hULGRlZXBfY29weShhaW5mbykpKSApCisgICAgU2tpbGxSZXNUcmFuc2ZlcihyZXMsYWluZm8pOworCisgIC8vIFZlcmFlbmRlcnVuZ2VuIGR1cmNoIGVpbmVuIEF0dGFjay1Nb2RpZmllcj8KKyAgaWYgKCAocmVzPVF1ZXJ5UHJvcChQX1RNUF9BVFRBQ0tfTU9EKSkgKQorICB7CisgICAgaWYgKCBwb2ludGVycChyZXMpICYmIChzaXplb2YocmVzKT49MykgJiYgaW50cChyZXNbMF0pCisgICAgICAgICYmICh0aW1lKCk8cmVzWzBdKSAmJiBvYmplY3RwKHJlc1sxXSkgJiYgc3RyaW5ncChyZXNbMl0pICkKKyAgICB7CisgICAgICBpZiAoICEocmVzPWNhbGxfb3RoZXIocmVzWzFdLHJlc1syXSxkZWVwX2NvcHkoYWluZm8pKSkKKyAgICAgICAgICB8fCAhbWFwcGluZ3AocmVzKSApCisgICAgICAgIHJldHVybjsKKyAgICAgIGVsc2UKKyAgICAgICAgU2tpbGxSZXNUcmFuc2ZlcihyZXMsYWluZm8pOworICAgIH0KKyAgICBlbHNlCisgICAgICBTZXRQcm9wKFBfVE1QX0FUVEFDS19NT0QsMCk7CisgIH0KKworICAvLyB0cmlnZ2VyIGF0dGFjayBtb2QgaG9vaworICBob29rRGF0YT1kZWVwX2NvcHkoYWluZm8pOworICBob29rUmVzPUhvb2tGbG93KEhfSE9PS19BVFRBQ0tfTU9ELGhvb2tEYXRhKTsKKyAgaWYoaG9va1JlcyAmJiBwb2ludGVycChob29rUmVzKSAmJiBzaXplb2YoaG9va1Jlcyk+SF9SRVREQVRBKXsKKyAgICBpZihob29rUmVzW0hfUkVUQ09ERV09PUhfQ0FOQ0VMTEVEKXsKKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgZWxzZSBpZihob29rUmVzW0hfUkVUQ09ERV09PUhfQUxURVJFRCAmJiBob29rUmVzW0hfUkVUREFUQV0gJiYKKyAgICAgICAgICAgICBtYXBwaW5ncChob29rUmVzW0hfUkVUREFUQV0pKXsKKyAgICAgICAgU2tpbGxSZXNUcmFuc2Zlcihob29rUmVzW0hfUkVUREFUQV0sYWluZm8pOworICAgIH0KKyAgfQorCisgIC8vIEludGVybmUgTW9kaWZpa2F0aW9uZW4gZGVyIEFuZ3JpZmZzd2VydGUKKyAgSW50ZXJuYWxNb2RpZnlBdHRhY2soYWluZm8pOworCisgIGlmICggIW9iamVjdHAoZW5lbXkpICkKKyAgICByZXR1cm47CisKKyAgLy8gaGllciBtYWwgYmV3dXNzdCBuaWNodCBhdWYgUF9QTFVSQUwgenVlcnN0IHRlc3Rlbi4gaW4gOTAlIGRlciBGYWVsbGUKKyAgLy8gd2lyZCBlaCBrZWluZSBBbmdyaWZmc21lbGR1bmcgbWVociBhdXNnZWdlYmVuLCBhbHNvIHBydWVmZW4gd2lyIGRhcworICAvLyBsaWViZXIgenVlcnN0LiBQbHVyYWwgdGVzdGVuIHppZWh0IHNjaG9uIGdlbnVnIFJlY2hlbnplaXQgOi8KKyAgLy8gTmljaHQgbWVpbmUgSWRlZSEgTmljaHQgbWVpbmUgSWRlZSEgTmFjaHR3aW5kIDcuNy4yMDAxCisgIGlmICggYWluZm9bU0lfU0tJTExEQU1BR0VfTVNHMl0hPWxhc3RfYXR0YWNrX21zZyApCisgIHsKKyAgICBsYXN0X2F0dGFja19tc2cgPSBhaW5mb1tTSV9TS0lMTERBTUFHRV9NU0cyXTsKKyAgICBpZiAoUXVlcnlQcm9wKFBfUExVUkFMKSkKKyAgICB7CisgICAgICB0ZWxsX29iamVjdCggTUUsICIgIElociBncmVpZnQgIiArIGVuZW15LT5uYW1lKFdFTiwxKQorICAgICAgICAgICAgICAgICAgICsgYWluZm9bU0lfU0tJTExEQU1BR0VfTVNHMl0gKyAiIGFuLlxuIiApOworICAgICAgc2F5KCIgICIrKE5hbWUoV0VSLDEpKSsiIGdyZWlmZW4gIisoZW5lbXktPm5hbWUoV0VOLDEpKSsKKyAgICAgICAgICBhaW5mb1tTSV9TS0lMTERBTUFHRV9NU0ddKyIgYW4uXG4iLCBlbmVteSApOworICAgICAgdGVsbF9vYmplY3QoIGVuZW15LCAiICAiKyhOYW1lKFdFUiwxKSkrIiBncmVpZmVuICIrCisgICAgICAgICAgICAgICAgICAoZW5lbXktPlF1ZXJ5UHJvcChQX1BMVVJBTCk/IkV1Y2giOiJEaWNoIikrCisgICAgICAgICAgICAgICAgICAgYWluZm9bU0lfU0tJTExEQU1BR0VfTVNHMl0rIiBhbi5cbiIgKTsKKyAgICB9CisgICAgZWxzZQorICAgIHsKKyAgICAgIHRlbGxfb2JqZWN0KCBNRSwgIiAgRHUgZ3JlaWZzdCAiICsgZW5lbXktPm5hbWUoV0VOLDEpCisgICAgICAgICAgICAgICAgICAgKyBhaW5mb1tTSV9TS0lMTERBTUFHRV9NU0cyXSArICIgYW4uXG4iICk7CisgICAgICBzYXkoIiAgIisoTmFtZShXRVIsMikpKyIgZ3JlaWZ0ICIrKGVuZW15LT5uYW1lKFdFTiwxKSkrCisgICAgICAgICAgYWluZm9bU0lfU0tJTExEQU1BR0VfTVNHXSsiIGFuLlxuIiwgZW5lbXkgKTsKKyAgICAgIHRlbGxfb2JqZWN0KCBlbmVteSwgIiAgIisoTmFtZShXRVIsMSkpKyIgZ3JlaWZ0ICIrCisgICAgICAgICAgICAgICAgICAoZW5lbXktPlF1ZXJ5UHJvcChQX1BMVVJBTCk/IkV1Y2giOiJEaWNoIikrCisgICAgICAgICAgICAgICAgICAgYWluZm9bU0lfU0tJTExEQU1BR0VfTVNHMl0rIiBhbi5cbiIgKTsgICAgfQorICB9CisgIGVsc2UgaWYgKCBRdWVyeShQX1NIT1dfQVRUQUNLX01TRykgKQorICAgIGlmIChRdWVyeVByb3AoUF9QTFVSQUwpKQorICAgICAgdGVsbF9vYmplY3QoIE1FLCAiICBJaHIgZ3JlaWZ0ICIgKyBlbmVteS0+bmFtZShXRU4sMSkKKyAgICAgICAgICAgICAgICAgICArIGFpbmZvW1NJX1NLSUxMREFNQUdFX01TRzJdICsgIiBhbi5cbiIgKTsKKyAgICBlbHNlCisgICAgICB0ZWxsX29iamVjdCggTUUsICIgIER1IGdyZWlmc3QgIiArIGVuZW15LT5uYW1lKFdFTiwxKQorICAgICAgICAgICAgICAgICAgICsgYWluZm9bU0lfU0tJTExEQU1BR0VfTVNHMl0gKyAiIGFuLlxuIiApOworCisgIC8vIGFpbmZvIGluIGRlZmVuZGluZm8gbWVya2VuCisgIGVkZWZlbmRpbmZvWyBPUklHSU5BTF9BSU5GT109IGRlZXBfY29weShhaW5mbyk7CisgIGVkZWZlbmRpbmZvWyBPUklHSU5BTF9EQU1dPSBhaW5mb1tTSV9TS0lMTERBTUFHRV07CisgIGVkZWZlbmRpbmZvWyBPUklHSU5BTF9EQU1UWVBFXT0gYWluZm9bU0lfU0tJTExEQU1BR0VfVFlQRV07CisgIGVkZWZlbmRpbmZvWyBDVVJSRU5UX0RBTV09IGFpbmZvW1NJX1NLSUxMREFNQUdFXTsKKyAgZWRlZmVuZGluZm9bIENVUlJFTlRfREFNVFlQRV09IGFpbmZvW1NJX1NLSUxMREFNQUdFX1RZUEVdOworCisgIC8vIGFpbmZvW1NJX1NQRUxMXSBhdWYgZWluIG1hcHBpbmcgbm9ybWllcmVuCisgIGlmICggaW50cChhaW5mb1tTSV9TUEVMTF0pICkKKyAgeworICAgIGFpbmZvW1NJX1NQRUxMXSA9IChbIFNQX1BIWVNJQ0FMX0FUVEFDSyA6ICFhaW5mb1tTSV9TUEVMTF0sCisgICAgICAgICAgICAgICBTUF9TSE9XX0RBTUFHRSAgICAgOiAhYWluZm9bU0lfU1BFTExdLAorICAgICAgICAgICAgICAgU1BfUkVEVUNFX0FSTU9VUiAgIDogKFsgXSkgIF0pOworICB9CisKKyAgLy8gZGVmZW5kaW5mbyBhbmhhZW5nZW4sIGZhbGxzIGFpbmZvW1NJX1NQRUxMXSBlaW4gbWFwcGluZyBpc3QKKyAgaWYoIG1hcHBpbmdwKGFpbmZvW1NJX1NQRUxMXSkpCisgIHsKKyAgICBhaW5mb1tTSV9TUEVMTF1bRUlORk9fREVGRU5EXT1lZGVmZW5kaW5mbzsKKyAgfQorCisKKyAgZW5lbXktPkRlZmVuZChhaW5mb1tTSV9TS0lMTERBTUFHRV0sIGFpbmZvW1NJX1NLSUxMREFNQUdFX1RZUEVdLAorICAgICAgICAgICAgICAgIGFpbmZvW1NJX1NQRUxMXSwgICAgICAgdGhpc19vYmplY3QoKSk7CisKKworICAvL2VkZWZlbmRpbmZvPShbXSk7CisKKyAgLyogRG9uZSBhdHRhY2tpbmcgKi8KK30KKworcHVibGljIHZvaWQgQWRkRGVmZW5kZXIob2JqZWN0IGZyaWVuZCkKK3sgb2JqZWN0ICpkZWZzOworCisgIGlmICggIW9iamVjdHAoZnJpZW5kKSApCisgICAgcmV0dXJuOworCisgIGlmICggIXBvaW50ZXJwKGRlZnM9UXVlcnlQcm9wKFBfREVGRU5ERVJTKSkgKQorICAgIGRlZnM9KHt9KTsKKworICBpZiAoIG1lbWJlcihkZWZzLGZyaWVuZCk+PTAgKQorICAgIHJldHVybjsKKworICBkZWZzKz0oe2ZyaWVuZH0pOworICBTZXRQcm9wKFBfREVGRU5ERVJTLGRlZnMpOworfQorCitwdWJsaWMgdm9pZCBSZW1vdmVEZWZlbmRlcihvYmplY3QgZnJpZW5kKQoreyBvYmplY3QgKmRlZnM7CisKKyAgaWYgKCAhb2JqZWN0cChmcmllbmQpICkKKyAgICByZXR1cm47CisKKyAgaWYgKCAhcG9pbnRlcnAoZGVmcz1RdWVyeVByb3AoUF9ERUZFTkRFUlMpKSApCisgICAgZGVmcz0oe30pOworCisgIGlmICggbWVtYmVyKGRlZnMsZnJpZW5kKT09LTEgKQorICAgIHJldHVybjsKKworICBkZWZzIC09ICh7ZnJpZW5kfSk7CisgIFNldFByb3AoUF9ERUZFTkRFUlMsZGVmcyk7Cit9CisKK3B1YmxpYyB2b2lkIEluZm9ybURlZmVuZChvYmplY3QgZW5lbXkpCit7CisgIFVzZVNraWxsKFNLX0lORk9STV9ERUZFTkQsKFsgU0lfRU5FTVkgIDogZW5lbXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0lfRlJJRU5EIDogcHJldmlvdXNfb2JqZWN0KCkgXSkpOworICAvLyBPaCwgb2ggLSBpY2ggaG9mZmUgbWFsLCBkYXNzIEluZm9ybURlZmVuZCB3aXJrbGljaCBOVVIgYXVzIERlZmVuZAorICAvLyBlaW5lcyBiZWZyZXVuZGV0ZW4gbGl2aW5ncyBhdWZnZXJ1ZmVuIHdpcmQuLi4gKFNpbHZhbmEpCisgIC8vIFRoaXMgaXMgb25seSBleHBlcmltZW50YWwuLi4gOykKK30KKworcHVibGljIDxpbnR8c3RyaW5nKnxtYXBwaW5nPiogRGVmZW5kT3RoZXIoaW50IGRhbSwgc3RyaW5nfHN0cmluZyogZGFtX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnR8bWFwcGluZyBzcGVsbCwgb2JqZWN0IGVuZW15KQoreworICA8aW50fHN0cmluZyp8bWFwcGluZz4qIHJlczsKKworICBpZiAoIChyZXM9VXNlU2tpbGwoU0tfREVGRU5EX09USEVSLChbIFNJX1NLSUxMREFNQUdFIDogZGFtLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNJX1NLSUxMREFNQUdFX1RZUEUgOiBkYW1fdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTSV9TUEVMTCA6IHNwZWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNJX0ZSSUVORCA6IHByZXZpb3VzX29iamVjdCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNJX0VORU1ZIDogZW5lbXkgXSkpKQorICAgICAgJiYgcG9pbnRlcnAocmVzKSApCisgICAgcmV0dXJuIHJlczsKKworICByZXR1cm4gMDsKK30KKworcHVibGljIHZvaWQgQ2hlY2tXaW1weUFuZEZsZWUoKQoreworICBpZiAoIChRdWVyeVByb3AoUF9XSU1QWSk+UXVlcnlQcm9wKFBfSFApKSAmJiAhVGVhbUZsZWUoKQorICAgICAgJiYgZmluZF9jYWxsX291dCgiRmxlZSIpPDAgKQorICAgIGNhbGxfb3V0KCMnRmxlZSwwLGVudmlyb25tZW50KCkpOworfQorCitwcm90ZWN0ZWQgc3RyaW5nIG1lc3Moc3RyaW5nIG1zZyxvYmplY3QgbWUsb2JqZWN0IGVuZW15KQoreyBjbG9zdXJlIG1uYW1lLCBlbmFtZTsKKyAgc3RyaW5nICAqcGFydHMseDsKKyAgaW50ICAgICBpOworCisgIG1uYW1lID0gc3ltYm9sX2Z1bmN0aW9uKCJuYW1lIiwgbWUpOworICBlbmFtZSA9IHN5bWJvbF9mdW5jdGlvbigibmFtZSIsIGVuZW15KTsKKworICBwYXJ0cz1yZWdleHBsb2RlKG1zZywiQFdFW0EtWl0qWzEyXSIpOworICBmb3IgKCBpPXNpemVvZihwYXJ0cyktMiA7IGk+PTEgOyBpLT0yICkKKyAgeworICAgIHN3aXRjaChwYXJ0c1tpXSkKKyAgICB7CisgICAgICBjYXNlICJAV0VSMSI6ICAgIHBhcnRzW2ldPWZ1bmNhbGwobW5hbWUsV0VSLDEpOyAgICBicmVhazsKKyAgICAgIGNhc2UgIkBXRVNTRU4xIjogcGFydHNbaV09ZnVuY2FsbChtbmFtZSxXRVNTRU4sMSk7IGJyZWFrOworICAgICAgY2FzZSAiQFdFTTEiOiAgICBwYXJ0c1tpXT1mdW5jYWxsKG1uYW1lLFdFTSwxKTsgICAgYnJlYWs7CisgICAgICBjYXNlICJAV0VOMSI6ICAgIHBhcnRzW2ldPWZ1bmNhbGwobW5hbWUsV0VOLDEpOyAgICBicmVhazsKKyAgICAgIGNhc2UgIkBXRVIyIjogICAgcGFydHNbaV09ZnVuY2FsbChlbmFtZSxXRVIsMSk7ICAgIGJyZWFrOworICAgICAgY2FzZSAiQFdFU1NFTjIiOiBwYXJ0c1tpXT1mdW5jYWxsKGVuYW1lLFdFU1NFTiwxKTsgYnJlYWs7CisgICAgICBjYXNlICJAV0VNMiI6ICAgIHBhcnRzW2ldPWZ1bmNhbGwoZW5hbWUsV0VNLDEpOyAgICBicmVhazsKKyAgICAgIGNhc2UgIkBXRU4yIjogICAgcGFydHNbaV09ZnVuY2FsbChlbmFtZSxXRU4sMSk7ICAgIGJyZWFrOworICAgICAgZGVmYXVsdDogOworICAgIH0KKyAgfQorCisgIHJldHVybiBicmVha19zdHJpbmcoY2FwaXRhbGl6ZShpbXBsb2RlKHBhcnRzLCIiKSksNzgsIiAgIiwxKTsKK30KKworLy8gRnVlciBldnRsLiBEZWZlbmQtQWVuZGVydW5nZW4sIG9obmUgZGFzcyBtYW4gZ2xlaWNoIGRhcyBnYW56ZQorLy8gQXR0YWNrIHVlYmVybGFnZXJuIG11c3M6Citwcm90ZWN0ZWQgdm9pZCBJbnRlcm5hbE1vZGlmeURlZmVuZChpbnQgZGFtLCBzdHJpbmcqIGR0LCBtYXBwaW5nIHNwZWxsLCBvYmplY3QgZW5lbXkpCit7CisgIHJldHVybjsKK30KKworcHVibGljIGludCBEZWZlbmQoaW50IGRhbSwgc3RyaW5nfHN0cmluZyogZGFtX3R5cGUsIGludHxtYXBwaW5nIHNwZWxsLCBvYmplY3QgZW5lbXkpCit7CisgIGludCAgICAgaSxrOworICBtaXhlZCAgIHJlcyxyZXMyOworICBvYmplY3QgICphcm1vdXJzLHRtcDsKKyAgbWl4ZWQgaG9va0RhdGE7CisgIG1peGVkIGhvb2tSZXM7CisgIAorICAvLyAgc3RyaW5nICB3aGF0LCBob3c7CisgIHN0cmluZyBlbm5hbWUsIG15bmFtZTsKKworICAvLyB0aGlzX3BsYXllcigpLCB3ZW5uIGtlaW4gZW5lbXkgYmVrYW5udC4uLgorICBlbmVteSB8fD0gdGhpc19wbGF5ZXIoKTsKKyAgLy8gVGVzdGVuLCBvYiBkaWVzZXMgTGViZXdlc2VuIHVlYmVyaGF1cHQgYW5nZWdyaWZmZW4gd2VyZGVuIGRhcmYKKyAgaWYgKCAhdGhpc19vYmplY3QoKSB8fCAhZW5lbXkgfHwgUXVlcnlQcm9wKFBfTk9fQVRUQUNLKQorICAgICAgfHwgKCBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKGVuZW15KSAmJiAhIGludGVyYWN0aXZlKGVuZW15KSApICkKKyAgICByZXR1cm4gMDsKKworICBpZiAoIGludHAoc3BlbGwpICkKKyAgICBzcGVsbCA9IChbIFNQX1BIWVNJQ0FMX0FUVEFDSyA6ICFzcGVsbCwKKyAgICAgICAgICAgICAgIFNQX1NIT1dfREFNQUdFICAgICA6ICFzcGVsbCwKKyAgICAgICAgICAgICAgIFNQX1JFRFVDRV9BUk1PVVIgICA6IChbIF0pICBdKTsKKyAgZWxzZSBpZiAoICFtYXBwaW5ncChzcGVsbCkgKSAvLyBJbGxlZ2FsZXIgc3BlbGwtUGFyYW1ldGVyCisgICAgcmV0dXJuIDA7CisKKyAgLy8gdGVzdGVuIG9iIGVpbmUgZXJ3ZWl0ZXJ0ZSBkZWZlbmRpbmZvIHZvcmhhbmRlbiBpc3QKKyAgaWYoIW1lbWJlcihzcGVsbCxFSU5GT19ERUZFTkQpKQorICB7CisgICAgICAgICAgLy9zcGVsbCs9KFtFSU5GT19ERUZFTkQ6KFtdKV0pOyAvLyBnZ2YgaGluenVmdWVnZW4KKyAgICAgICAgLy8gdXNlIGEgdGVtcG9yYXJ5IG1hcHBpbmcgdG8gYXZvaWQgcmVjdXJzaXZlCisgICAgICAgIC8vIHZhbFt4XVt5XSA9IGRlZXBfY29weSh2YWwpOworICAgICAgICBtYXBwaW5nIHRtcGRlZmVuZCA9IChbCisgICAgICAgICAgICAgICAgT1JJR0lOQUxfQUlORk86ZGVlcF9jb3B5KHNwZWxsKSwKKyAgICAgICAgICAgICAgICBPUklHSU5BTF9EQU06ZGFtLAorICAgICAgICAgICAgICAgICAgT1JJR0lOQUxfREFNVFlQRTpkYW1fdHlwZSwKKyAgICAgICAgXSk7CisgICAgICAgICAgc3BlbGxbRUlORk9fREVGRU5EXT10bXBkZWZlbmQ7CisgIH0KKworICAvLyBTY2hhZGVuc3R5cCB1ZWJlcnBydWVmZW4KKyAgaWYgKCAhcG9pbnRlcnAoZGFtX3R5cGUpICkKKyAgICBkYW1fdHlwZSA9ICh7IGRhbV90eXBlIH0pOworCisgIHNwZWxsW0VJTkZPX0RFRkVORF1bQ1VSUkVOVF9EQU1UWVBFXT1kYW1fdHlwZTsKKyAgc3BlbGxbRUlORk9fREVGRU5EXVtDVVJSRU5UX0RBTV09ZGFtOworCisgIC8vIFRlc3Rlbiwgb2IgZGVyIEFuZ3JlaWZlciBzY2hvbiBhbHMgRmVpbmQgcmVnaXN0cmllcnQgd29yZGVuIGlzdC4KKyAgLy8gV2VubiBuZWluLCByZWdpc3RyaWVyZW4uCisgIGlmICggIUlzRW5lbXkoZW5lbXkpICYmICFzcGVsbFtTUF9OT19FTkVNWV0gKQorICB7CisgICAgc3BlbGxbRUlORk9fREVGRU5EXVtFTkVNWV9JTlNFUlRFRF09MTsKKyAgICBJbnNlcnRFbmVteShlbmVteSk7CisgIH0KKworICAvLyBSRlItVGFrdGlrIGFiZmFuZ2VuCisgIGlmICggIVF1ZXJ5UHJvcChQX0VOQUJMRV9JTl9BVFRBQ0tfT1VUKSApCisgIHsKKyAgICBpPXRpbWUoKS0oZW5lbXktPlF1ZXJ5UHJvcChQX0xBU1RfTU9WRSkpOworICAgIC8vIEdlZ25lciBoYXQgc2ljaCBiZXdlZ3QsIG1hbiBzZWxic3QgbmljaHQKKyAgICBpZiAoIChpPDMpICYmICh0aW1lKCktUXVlcnlQcm9wKFBfTEFTVF9NT1ZFKT49NSkgKQorICAgIHsKKyAgICAgIC8vIEJlaSBFcnN0ZXIgS2FtcGZydW5kZSB3ZW5pZ2UgU2NoYWRlbgorICAgICAgZGFtLz0oNC1pKTsKKyAgICAgIHNwZWxsW0VJTkZPX0RFRkVORF1bUkZSX1JFRFVDRV09ZGFtOworICAgICAgc3BlbGxbRUlORk9fREVGRU5EXVtDVVJSRU5UX0RBTV09ZGFtOworICAgIH0KKyAgfQorCisgIC8vIE1hbiBrYW5uIFZlcnRlaWRpZ2VyIGhhYmVuLiBEaWVzZSBrb21tZW4gYWxzIGVyc3RlIHp1bSBadWdlCisgIGlmICggcmVzPVF1ZXJ5UHJvcChQX0RFRkVOREVSUykgKQorICB7IG9iamVjdCAqZGVmcywqZGVmc19oZXJlOworCisgICAgZGVmcz0oe30pOworICAgIGRlZnNfaGVyZT0oe30pOworICAgIGlmICggIXBvaW50ZXJwKHJlcykgKQorICAgICAgcmVzPSh7cmVzfSk7CisgICAgLy8gZXJzdCBhbGxlIGFud2VzZW5kZW4gZmluZGVuLgorICAgIGZvcmVhY2gob2JqZWN0IGRlZmVuZGVyOiByZXMpIHsKKyAgICAgIGlmICggb2JqZWN0cChkZWZlbmRlcikgJiYgKG1lbWJlcihkZWZzLGRlZmVuZGVyKTwwKSApCisgICAgICB7CisgICAgICAgIGRlZnMrPSh7ZGVmZW5kZXJ9KTsKKyAgICAgICAgLy8gIFZlcnRlaWRpZ2VyIG11ZXNzZW4gaW0gZ2xlaWNoZW4gUmF1bSBvZGVyIGltIExpdmluZyBzZWxiZXIKKyAgICAgICAgLy8gIGVudGhhbHRlbiBzZWluLgorICAgICAgICBpZiAoIGVudmlyb25tZW50KGRlZmVuZGVyKSA9PSBlbnZpcm9ubWVudCgpCisgICAgICAgICAgICB8fCBlbnZpcm9ubWVudChkZWZlbmRlcikgPT0gTUUpCisgICAgICAgIHsKKyAgICAgICAgICBjYWxsX290aGVyKGRlZmVuZGVyLCJJbmZvcm1EZWZlbmQiLGVuZW15KTsKKyAgICAgICAgICBpZiAoZGVmZW5kZXIpCisgICAgICAgICAgICBkZWZzX2hlcmUgKz0gKHsgZGVmZW5kZXIgfSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgLy9Bbndlc2VuZGUgVmVydGVpZGlnZXIgZWludHJhZ2VuLgorICAgIHNwZWxsW0VJTkZPX0RFRkVORF1bUFJFU0VOVF9ERUZFTkRFUlNdPWRlZnNfaGVyZTsKKworICAgIC8vIFBfREVGRU5ERVJTIGF1Y2ggZ2xlaWNoIGFrdHVhbGlzaWVyZW4KKyAgICBpZiAoIHNpemVvZihkZWZzKTwxICkKKyAgICAgIGRlZnM9MDsKKyAgICBTZXRQcm9wKFBfREVGRU5ERVJTLGRlZnMpOworCisgICAgaWYgKCBzcGVsbFtTUF9QSFlTSUNBTF9BVFRBQ0tdICkgeworICAgICAgLy8gQmVpIHBoeXNpc2NoZW4gQW5ncmlmZmVuIG51ciBWZXJ0ZWlkaWdlciBhdXMgUmVpaGUgMQorICAgICAgLy8gbmVobWVuICh6LkIuIGZ1ZXIgUnVlY2tlbmRlY2t1bmcpCisgICAgICBmb3JlYWNoKG9iamVjdCBkZWZlbmRlcjogZGVmc19oZXJlKSB7CisgICAgICAgIGlmICggKGRlZmVuZGVyLT5QcmVzZW50UG9zaXRpb24oKSk+MSApIHsKKyAgICAgICAgICBkZWZzX2hlcmUtPSh7ZGVmZW5kZXJ9KTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAKKyAgICBpZiAoIChpPXNpemVvZihkZWZzX2hlcmUpKSApCisgICAgeworICAgICAgbWl4ZWQgZWRlZmVuZHRtcD0oe2RlZnNfaGVyZVtyYW5kb20oaSldLDAsMCwwfSk7IAorICAgICAgcmVzPWNhbGxfb3RoZXIoZWRlZmVuZHRtcFtERUZfREVGRU5ERVJdLCJEZWZlbmRPdGhlciIsCisgICAgICAgICAgICAgICAgICAgICBkYW0sZGFtX3R5cGUsc3BlbGwsZW5lbXkpOworICAgICAgaWYgKCBwb2ludGVycChyZXMpICYmIChzaXplb2YocmVzKT49MykgJiYgaW50cChyZXNbMF0pCisgICAgICAgICAgJiYgcG9pbnRlcnAocmVzWzFdKSkKKyAgICAgIHsKKyAgICAgICAgLy8gSGVsZmVyIGtvZW5uZW4gZGVuIFNjaGFkZW4gb2RlciBTY2hhZGVuc3R5cCBhZW5kZXJuLAorICAgICAgICAvLyB6LkIuIFVtd2FuZGx1bmcgdm9uIEZldWVyIG5hY2ggRWlzIG9kZXIgc28uLi4KKyAgICAgICAgZGFtPXJlc1swXTsKKyAgICAgICAgZWRlZmVuZHRtcFtERUZfREFNXT1kYW07CisgICAgICAgIGRhbV90eXBlPXJlc1sxXTsKKyAgICAgICAgZWRlZmVuZHRtcFtERUZfREFNVFlQRV09ZGFtX3R5cGU7CisKKyAgICAgICAgaWYgKCBtYXBwaW5ncChyZXNbMl0pICkKKyAgICAgICAgeworICAgICAgICAgIHNwZWxsPXJlc1syXTsKKyAgICAgICAgICAvLyB0ZXVlciwgYWJlciBnZWh0IG5pY2h0IGFuZGVycyAoUmVrdXJzaW9uIHZlcm1laWRlbikKKyAgICAgICAgICBlZGVmZW5kdG1wW0RFRl9TUEVMTF09ZGVlcF9jb3B5KHJlc1syXSk7CisgICAgICAgIH0KKyAgICAgICAgc3BlbGxbRUlORk9fREVGRU5EXVtDVVJSRU5UX0RBTVRZUEVdPWRhbV90eXBlOworICAgICAgICBzcGVsbFtFSU5GT19ERUZFTkRdW0NVUlJFTlRfREFNXT1kYW07CisgICAgICB9CisgICAgICBzcGVsbFtFSU5GT19ERUZFTkRdW0RFRkVORElOR19ERUZFTkRFUl09ZWRlZmVuZHRtcDsKKyAgICB9CisgIH0gLy8gRW5kZSBEZWZlbmRlci1WZXJhcmJlaXR1bmcKKworCisgIC8vIFVlYmVyIGVpbmVuIFBfVE1QX0RFRkVORF9IT09LIHdlcmRlbiB6LkIuIFNjaHV0enphdWJlciBnZWhhbmRoYWJ0CisgIHNwZWxsW0VJTkZPX0RFRkVORF1bREVGRU5EX0hPT0tdPURJX05PSE9PSzsKKyAgaWYgKCByZXM9UXVlcnlQcm9wKFBfVE1QX0RFRkVORF9IT09LKSApCisgIHsKKyAgICBpZiAoIHBvaW50ZXJwKHJlcykgJiYgKHNpemVvZihyZXMpPj0zKSAmJiBpbnRwKHJlc1swXSkgJiYgKHRpbWUoKTxyZXNbMF0pCisgICAgICAgICYmIG9iamVjdHAocmVzWzFdKSAmJiBzdHJpbmdwKHJlc1syXSkgKQorICAgIHsKKyAgICAgIGlmICggIShyZXM9Y2FsbF9vdGhlcihyZXNbMV0scmVzWzJdLGRhbSxkYW1fdHlwZSxzcGVsbCxlbmVteSkpICkKKyAgICAgIHsKKyAgICAgICAgLy8gRWluIFBfVE1QX0RFRkVORF9IT09LIGthbm4gZGVuIFNjaGFkZW4gdm9sbHN0YWVuZGlnIGFiZmFuZ2VuLAorICAgICAgICAvLyBkYXMgRGVmZW5kIHdpcmQgZGFubiBoaWVyIGFiZ2Vicm9jaGVuICpTSUNLKiB1bmQgZXMgd2lyZCBudXIKKyAgICAgICAgLy8gbm9jaCBnZXRlc3RldCwgb2IgbWFuIGluIGRpZSBGbHVjaHQgZ2VzY2hsYWdlbiB3dXJkZQorICAgICAgICBzcGVsbFtFSU5GT19ERUZFTkRdW0RFRkVORF9IT09LXT1ESV9IT09LSU5URVJSVVBUOworICAgICAgICBDaGVja1dpbXB5QW5kRmxlZSgpOworICAgICAgICByZXR1cm4gMDsKKyAgICAgIH0KKyAgICAgIGVsc2UKKyAgICAgIHsKKyAgICAgICAgc3BlbGxbRUlORk9fREVGRU5EXVtERUZFTkRfSE9PS109RElfSE9PSzsKKyAgICAgICAgaWYgKCBwb2ludGVycChyZXMpICYmIChzaXplb2YocmVzKT49MykKKyAgICAgICAgICAgICYmIGludHAocmVzWzBdICYmIHBvaW50ZXJwKHJlc1sxXSkpICkKKyAgICAgICAgeworICAgICAgICAgIG1peGVkIGVkZWZlbmR0bXA9KHswLDAsMH0pOworICAgICAgICAgIC8vIERlciBQX1RNUF9ERUZFTkRfSE9PSyBrYW5uIGViZW5mYWxscyBTY2hhZGVuc2hvZWhlIHVuZAorICAgICAgICAgIC8vIC1hcnQgc293aWUgZGllIFNwZWxsLUluZm9zIHZlcmFlbmRlcm4KKyAgICAgICAgICBkYW09cmVzWzBdOworICAgICAgICAgIGVkZWZlbmR0bXBbSE9PS19EQU1dPWRhbTsKKyAgICAgICAgICBkYW1fdHlwZT1yZXNbMV07CisgICAgICAgICAgZWRlZmVuZHRtcFtIT09LX0RBTVRZUEVdPWRhbV90eXBlOworCisgICAgICAgICAgaWYgKCBtYXBwaW5ncChyZXNbMl0pICkKKyAgICAgICAgICB7CisgICAgICAgICAgICBzcGVsbD1yZXNbMl07CisgICAgICAgICAgICAvLyBXYWVoLiBUZXVlci4gQWJlciBnZWh0IG5pY2h0IGFuZGVycy4KKyAgICAgICAgICAgIGVkZWZlbmR0bXBbSE9PS19TUEVMTF09ZGVlcF9jb3B5KHNwZWxsKTsKKyAgICAgICAgICB9CisgICAgICAgICAgc3BlbGxbRUlORk9fREVGRU5EXVtERUZFTkRfSE9PS109ZWRlZmVuZHRtcDsKKyAgICAgICAgICBzcGVsbFtFSU5GT19ERUZFTkRdW0NVUlJFTlRfREFNVFlQRV09ZGFtX3R5cGU7CisgICAgICAgICAgc3BlbGxbRUlORk9fREVGRU5EXVtDVVJSRU5UX0RBTV09ZGFtOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIGVsc2UKKyAgICAgIFNldFByb3AoUF9UTVBfREVGRU5EX0hPT0ssMCk7CisgIH0gLy8gUF9UTVBfREVGRU5EX0hPT0sKKworICAvLyB0cmlnZ2VyIGRlZmVuZCBob29rCisgIGhvb2tEYXRhPSh7ZGFtLGRhbV90eXBlLHNwZWxsLGVuZW15fSk7CisgIGhvb2tSZXM9SG9va0Zsb3coSF9IT09LX0RFRkVORCxob29rRGF0YSk7CisgIGlmKGhvb2tSZXMgJiYgcG9pbnRlcnAoaG9va1JlcykgJiYgc2l6ZW9mKGhvb2tSZXMpPkhfUkVUREFUQSl7CisgICAgaWYoaG9va1Jlc1tIX1JFVENPREVdPT1IX0NBTkNFTExFRCl7CisgICAgICAgIHNwZWxsW0VJTkZPX0RFRkVORF1bREVGRU5EX0hPT0tdPURJX0hPT0tJTlRFUlJVUFQ7CisgICAgICAgIENoZWNrV2ltcHlBbmRGbGVlKCk7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBlbHNlIGlmKGhvb2tSZXNbSF9SRVRDT0RFXT09SF9BTFRFUkVEICYmIGhvb2tSZXNbSF9SRVREQVRBXSl7CisgICAgICAgIHNwZWxsW0VJTkZPX0RFRkVORF1bREVGRU5EX0hPT0tdPURJX0hPT0s7CisgICAgICAgIGlmICggcG9pbnRlcnAoaG9va1Jlc1tIX1JFVERBVEFdKSAmJiAoc2l6ZW9mKGhvb2tSZXNbSF9SRVREQVRBXSk+PTMpCisgICAgICAgICAgICAmJiBpbnRwKGhvb2tSZXNbSF9SRVREQVRBXVswXSAmJiBwb2ludGVycChob29rUmVzW0hfUkVUREFUQV1bMV0pKSApCisgICAgICAgIHsKKyAgICAgICAgICBtaXhlZCBlZGVmZW5kdG1wPSh7MCwwLDB9KTsKKyAgICAgICAgICAvLyBEZXIgUF9UTVBfREVGRU5EX0hPT0sga2FubiBlYmVuZmFsbHMgU2NoYWRlbnNob2VoZSB1bmQKKyAgICAgICAgICAvLyAtYXJ0IHNvd2llIGRpZSBTcGVsbC1JbmZvcyB2ZXJhZW5kZXJuCisgICAgICAgICAgZGFtPWhvb2tSZXNbSF9SRVREQVRBXVswXTsKKyAgICAgICAgICBlZGVmZW5kdG1wW0hPT0tfREFNXT1kYW07CisgICAgICAgICAgZGFtX3R5cGU9aG9va1Jlc1tIX1JFVERBVEFdWzFdOworICAgICAgICAgIGVkZWZlbmR0bXBbSE9PS19EQU1UWVBFXT1kYW1fdHlwZTsKKworICAgICAgICAgIGlmICggbWFwcGluZ3AoaG9va1Jlc1tIX1JFVERBVEFdWzJdKSApCisgICAgICAgICAgeworICAgICAgICAgICAgc3BlbGw9aG9va1Jlc1tIX1JFVERBVEFdWzJdOworICAgICAgICAgICAgLy8gVGV1ZXIsIHRldWVyLi4uIDotKAorICAgICAgICAgICAgZWRlZmVuZHRtcFtIT09LX1NQRUxMXT1kZWVwX2NvcHkoc3BlbGwpOworICAgICAgICAgIH0KKyAgICAgICAgICBzcGVsbFtFSU5GT19ERUZFTkRdW0RFRkVORF9IT09LXT1lZGVmZW5kdG1wOworICAgICAgICAgIHNwZWxsW0VJTkZPX0RFRkVORF1bQ1VSUkVOVF9EQU1UWVBFXT1kYW1fdHlwZTsKKyAgICAgICAgICBzcGVsbFtFSU5GT19ERUZFTkRdW0NVUlJFTlRfREFNXT1kYW07CisgICAgICAgIH0KKyAgICB9CisgIH0gLy8gRW5kZSBIb29rLUJlaGFuZGx1bmcKKworICBpZiAoICFtZW1iZXIoc3BlbGwsU1BfUkVEVUNFX0FSTU9VUikgfHwgIW1hcHBpbmdwKHNwZWxsW1NQX1JFRFVDRV9BUk1PVVJdKSApCisgICAgICAgIHNwZWxsW1NQX1JFRFVDRV9BUk1PVVJdID0gKFtdKTsKKworICAvLyBFcyBnaWJ0IGF1Y2ggUGFyaWVyd2FmZmVuLAorICBpZiAoIG9iamVjdHAodG1wPVF1ZXJ5UHJvcChQX1BBUlJZX1dFQVBPTikpICkKKyAgeworICAgIHJlczI9dG1wLT5RdWVyeURlZmVuZChkYW1fdHlwZSwgc3BlbGwsIGVuZW15KTsKKworICAgIC8vIFJlZHV6aWVyYmFyZSBXaXJrc2Fta2VpdCBkZXIgUGFyaWVyd2FmZmU/CisgICAgaWYgKCBtZW1iZXIoc3BlbGxbU1BfUkVEVUNFX0FSTU9VUl0sUF9QQVJSWV9XRUFQT04pCisgICAgICAgICYmIGludHAocmVzPXNwZWxsW1NQX1JFRFVDRV9BUk1PVVJdW1BfUEFSUllfV0VBUE9OXSkgJiYgKHJlcz49MCkgKQorICAgIHsKKyAgICAgIHJlczI9KHJlczIqcmVzKS8xMDA7CisgICAgfQorCisgICAgZGFtLT1yZXMyOworICAgIHNwZWxsW0VJTkZPX0RFRkVORF1bQ1VSUkVOVF9EQU1dPWRhbTsKKyAgfQorCisgIC8vIEpldHp0IGtvbW1lbiBkaWUgUnVlc3R1bmdlbiBkZXMgTGViZXdlc2VucyBpbnMgU3BpZWwgKHdlbm4gZXMgZGVubgorICAvLyB3ZWxjaGUgdHJhZWd0KQorCisgIGFybW91cnM9UXVlcnlQcm9wKFBfQVJNT1VSUyktKHswfSk7CisgIGlmICggKGk9c2l6ZW9mKGFybW91cnMpKT4wICkgeyAKKyAgICBzdHJpbmcgYXR5OworCisgICAgdG1wPWFybW91cnNbcmFuZG9tKGkpXTsKKworICAgIGlmICggb2JqZWN0cCh0bXApICkKKyAgICAgIC8vVWViZXJnYWJlIGRlcyBNYXBwaW5ncyBlaCBhbHMgUG9pbnRlci9SZWZlcmVueiwgZGFoZXIgYmlsbGlnCisgICAgICB0bXAtPlRha2VGbGF3KGRhbV90eXBlLHNwZWxsW0VJTkZPX0RFRkVORF0pOworCisgICAgLy8gcHJvIFJ1ZXN0dW5nIGVpbiBLZXkgYW4gUGxhdHogcmVzZXJ2aWVyZW4KKyAgICBzcGVsbFtFSU5GT19ERUZFTkRdW0RFRkVORF9BUk1PVVJTXT1tX2FsbG9jYXRlKGksMik7CisgICAgZm9yZWFjaChvYmplY3QgYXJtb3VyIDogYXJtb3VycykgeworICAgICAgaWYgKCBvYmplY3RwKGFybW91cikgKSB7CisgICAgICAgIGF0eT0oc3RyaW5nKWFybW91ci0+UXVlcnlQcm9wKFBfQVJNT1VSX1RZUEUpOworCisgICAgICAgIGlmICggbWVtYmVyKHNwZWxsW1NQX1JFRFVDRV9BUk1PVVJdLGF0eSkKKyAgICAgICAgICAgICYmIGludHAocmVzMj1zcGVsbFtTUF9SRURVQ0VfQVJNT1VSXVthdHldKSAmJiAocmVzMj49MCkgKQorICAgICAgICAgIGRhbSAtPSAocmVzMiphcm1vdXItPlF1ZXJ5RGVmZW5kKGRhbV90eXBlLCBzcGVsbCwgZW5lbXkpKS8xMDA7CisgICAgICAgIGVsc2UKKyAgICAgICAgICBkYW0gLT0gKGludCkoYXJtb3VyLT5RdWVyeURlZmVuZChkYW1fdHlwZSwgc3BlbGwsIGVuZW15KSk7CisgICAgICAgIC8vIFNjaGFkZW4gTkFDSCBEZWZlbmRGdW5jIHZlcm1lcmtlbi4gCisgICAgICAgIC8vIFNjaHV0endpcmt1bmcgVk9SIERlZmVuZEZ1bmMgKERFRl9BUk1PVVJfUFJPVCkgdmVybWVya3QKKyAgICAgICAgLy8gZGFzIFF1ZXJ5RGVmZW5kKCkgc2VsYmVyLgorICAgICAgICBzcGVsbFtFSU5GT19ERUZFTkRdW0RFRkVORF9BUk1PVVJTXVthcm1vdXIsREVGX0FSTU9VUl9EQU1dPWRhbTsKKyAgICAgICAgLy8gYWt0LiBTY2hhZGVuIHZlcm1lcmtlbiB1bmQgU2NodXR6IGRlciBha3R1ZWxsZW4gUnVlc3R1bmcgKHZvcgorICAgICAgICAvLyBEZWZlbmRGdW5jKSB3aWVkZXIgYXVmIDAgc2V0emVuIGZ1ZXIgZGVuIG5hZWNoc3RlbiBEdXJjaGxhdWYuCisgICAgICAgIHNwZWxsW0VJTkZPX0RFRkVORF1bQ1VSUkVOVF9EQU1dPWRhbTsKKyAgICAgICAgc3BlbGxbRUlORk9fREVGRU5EXVtERUZFTkRfQ1VSX0FSTU9VUl9QUk9UXT0wOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8vIE1hbmNoZSBHaWxkZW4gaGFiZW4gZWluZW4gVmVydGVpZGlndW5nc3NraWxsLiBEZXIga29tbXQgamV0enQgenVtCisgIC8vIHRyYWdlbi4gRGVyIFNraWxsIGthbm4gZGllIFNjaGFkZW5zaG9laGUgdW5kIC1hcnQgYmVlaW5mbHVzc2VuLgorICBzcGVsbFtFSU5GT19ERUZFTkRdKz0oW0RFRkVORF9HVUlMRDooe30pXSk7CisgIGlmICggbWFwcGluZ3AocmVzPVVzZVNraWxsKFNLX01BR0lDX0RFRkVOU0UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFsgU0lfRU5FTVkgICAgICAgICAgICA6IGVuZW15LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNJX1NLSUxMREFNQUdFICAgICAgOiBkYW0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0lfU0tJTExEQU1BR0VfVFlQRSA6IGRhbV90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNJX1NQRUxMICAgICAgICAgICAgOiBzcGVsbCAgICAgXSkpKSApCisgIHsKKyAgICBkYW09KGludClyZXNbU0lfU0tJTExEQU1BR0VdOworCisgICAgaWYgKCBwb2ludGVycChyZXNbU0lfU0tJTExEQU1BR0VfVFlQRV0pICkKKyAgICAgICAgZGFtX3R5cGU9cmVzW1NJX1NLSUxMREFNQUdFX1RZUEVdOworCisgICAgc3BlbGxbRUlORk9fREVGRU5EXVtDVVJSRU5UX0RBTVRZUEVdPWRhbV90eXBlOworICAgIHNwZWxsW0VJTkZPX0RFRkVORF1bQ1VSUkVOVF9EQU1dPWRhbTsKKyAgICBzcGVsbFtFSU5GT19ERUZFTkRdW0RFRkVORF9HVUlMRF09KHtkYW0sZGFtX3R5cGV9KTsKKyAgfQorCisgIC8vIEV2dGwuIGludGVybmUgTW9kaWZpa2F0aW9uZW4KKyAgSW50ZXJuYWxNb2RpZnlEZWZlbmQoJmRhbSwgJmRhbV90eXBlLCAmc3BlbGwsICZlbmVteSk7CisKKyAgc3BlbGxbRUlORk9fREVGRU5EXVtDVVJSRU5UX0RBTVRZUEVdPWRhbV90eXBlOworICBzcGVsbFtFSU5GT19ERUZFTkRdW0NVUlJFTlRfREFNXT1kYW07CisKKyAgLy8gVGVzdGVuLCBvYiBpcmdlbmR3YXMgaW0gSW52ZW50b3J5IGRlcyBMZWJld2VzZW4gYXVmIGRlbiBBbmdyaWZmCisgIC8vICJyZWFnaWVydCIKKyAgQ2hlY2tTZW5zaXRpdmVBdHRhY2soZGFtLGRhbV90eXBlLHNwZWxsLGVuZW15KTsKKworICBpZiAoICFvYmplY3RwKGVuZW15KSApCisgICAgcmV0dXJuIDA7CisKKyAgLy8gQW5ncmlmZnN6ZWl0IGltIEdlZ25lciBzZXR6ZW4KKyAgZW5lbXktPlNldFByb3AoUF9MQVNUX0NPTUJBVF9USU1FLHRpbWUoKSk7CisKKyAgLy8gRGllIFJlc2lzdGVuemVuIGRlcyBMZWJld2VzZW5zIChuYXR1ZXJsaWNoZSB1bmQgZHVyY2ggUnVlc3R1bmdlbgorICAvLyBnZXNldHp0ZSkgYmVydWVja3NpY2h0aWdlbgorICBkYW0gPSB0b19pbnQoQ2hlY2tSZXNpc3RhbmNlKGRhbV90eXBlKSpkYW0pOworICBzcGVsbFtFSU5GT19ERUZFTkRdW0RFRkVORF9SRVNJXT1kYW07CisKKyAgc3BlbGxbRUlORk9fREVGRU5EXVtDVVJSRU5UX0RBTV09ZGFtOworCisgIC8vIEJlaSBwaHlzaWthbGlzY2hlbiBBbmdyaWZmZW4gd2lyZCBkaWUgbmF0dWVybGljaGUgUGFuemVydW5nIHVuZCBkaWUKKyAgLy8gR2VzY2hpY2tsaWNoa2VpdCBkZXMgTGViZXdlc2VucyBiZXJ1ZWNrc2ljaHRpZ3QKKyAgb2JqZWN0IHN0YXQgPSBmaW5kX29iamVjdCgiL2QvZXJ6bWFnaWVyL3plc3N0cmEvcGFjc3RhdCIpOyAvLyBUT0RPOiByZW1vdmUKKyAgaWYgKCBzcGVsbFtTUF9QSFlTSUNBTF9BVFRBQ0tdICkKKyAgeworICAgIC8vIE1pbmltdW0gaXN0IGF1Y2ggaGllciAxLgorICAgIGludCBib2R5ID0gUXVlcnlQcm9wKFBfQk9EWSkrUXVlcnlBdHRyaWJ1dGUoQV9ERVgpOworICAgIHJlczIgPSAoYm9keS80ICsgcmFuZG9tKGJvZHkqMy80ICsgMSkpIHx8IDE7CisgICAgaWYgKHN0YXQpCisgICAgICBzdGF0LT5ib2R5c3RhdChib2R5LCByZXMyLCByYW5kb20oYm9keSkrMSk7CisKKyAgICAvLyBSZWR1emllcmJhcmUgV2lya3NhbWtlaXQgZGVzIEJvZGllcz8KKyAgICBpZiAoIG1lbWJlcihzcGVsbFtTUF9SRURVQ0VfQVJNT1VSXSwgUF9CT0RZKQorICAgICAgICAmJiBpbnRwKHJlcz1zcGVsbFtTUF9SRURVQ0VfQVJNT1VSXVtQX0JPRFldKSAmJiAocmVzPj0wKSApCisgICAgICByZXMyPShyZXMyKnJlcykvMTAwOworCisgICAgZGFtLT1yZXMyOworICB9CisgIHNwZWxsW0VJTkZPX0RFRkVORF1bREVGRU5EX0JPRFldPWRhbTsKKyAgc3BlbGxbRUlORk9fREVGRU5EXVtDVVJSRU5UX0RBTV09ZGFtOworCisgIC8vIElzdCB1ZWJlcmhhdXB0IG5vY2ggZXR3YXMgdm9tIFNjaGFkZW4gdWVicmlnIGdlYmxpZWJlbj8KKyAgaWYgKCBkYW08MCApCisgICAgZGFtID0gMDsKKyAgc3BlbGxbRUlORk9fREVGRU5EXVtDVVJSRU5UX0RBTV09ZGFtOworCisgIC8vIGZ1ZXIgZGllIFN0YXRpc3RpaworICAvLyBUT0RPOiBlbnRmZXJuZW4gbmFjaCBUZXN0LVVwdGltZQorICBpZiAoc3RhdCkKKyAgICBzdGF0LT5kYW1hZ2VzdGF0KHNwZWxsW0VJTkZPX0RFRkVORF0pOworCisgIC8vIERpZSBBbnphaGwgZGVyIGFienV6aWVoZW5kZW4gTGViZW5zcHVua3RlIGlzdCBkZXIgZHVyY2ggMTAgZ2V0ZWlsdGUKKyAgLy8gU2NoYWRlbnN3ZXJ0CisgIGRhbSA9IGRhbSAvIDEwOworICBzcGVsbFtFSU5GT19ERUZFTkRdW0RFRkVORF9MT1NUTFBdPWRhbTsKKworICAvLyBldnRsLiBoYXQgZW50d2VkZXIgZGVyIEF1ZnJ1ZmVyIG9kZXIgZGFzIExlYmV3ZXNlbiBzZWxiZXIgZWlnZW5lCisgIC8vIFNjaGFkZW5zbWVsZHVuZ2VuIGRlZmluaWVydC4gRGllIHZvbSBBdWZydWZlciBoYWJlbiBQcmlvcml0YWV0LgorICBtaXhlZCBkYW1fbXNnID0gc3BlbGxbU1BfU0hPV19EQU1BR0VdOworICAvLyBXZW5uICE9IDAgKGQuaC4gVHJlZmZlcm1lbGR1bmdlbiBncnVuZHNhZXR6bGljaCBlcnd1ZW5zY2h0KSwgYWJlciBrZWluCisgIC8vIEFycmF5LCBoaWVyIGltIExpdmluZyBmcmFnZW4uCisgIGlmIChkYW1fbXNnICYmICFwb2ludGVycChkYW1fbXNnKSkKKyAgICBkYW1fbXNnID0gUXVlcnlQcm9wKFBfREFNQUdFX01TRyk7CisKKyAgLy8gSW4gZGVuIG1laXN0ZW4gRmFlbGxlbiBzb2xsIGF1Y2ggZWluZSBTY2hhZGVuc21lbGR1bmcgYXVzZ2VnZWJlbgorICAvLyB3ZXJkZW4sIGRpZSBkaWUgSG9laGUgZGVzIFNjaGFkZW5zIChncm9iKSBhbnplaWd0CisgIGlmIChzcGVsbFtTUF9TSE9XX0RBTUFHRV0gJiYgIXBvaW50ZXJwKGRhbV9tc2cpKSB7CisgICAgbXluYW1lPW5hbWUoV0VOKTsKKyAgICBlbm5hbWU9ZW5lbXktPk5hbWUoV0VSKTsKKyAgICBpZiAoZW5lbXktPlF1ZXJ5UHJvcChQX1BMVVJBTCkpIHsKKyAgICAgIHN3aXRjaCAoZGFtKSB7CisgICAgICBjYXNlIDA6CisgICAgICAgIHRlbGxfb2JqZWN0KGVuZW15LHNwcmludGYoIiAgSWhyIHZlcmZlaGx0ICVzLlxuIixteW5hbWUpKTsKKyAgICAgICAgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSxzcHJpbnRmKCIgICVzIHZlcmZlaGxlbiBEaWNoLlxuIixlbm5hbWUpKTsKKyAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVuZW15KXx8ZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgIHNwcmludGYoIiAgJXMgdmVyZmVobGVuICVzLlxuIixlbm5hbWUsbXluYW1lKSwKKyAgICAgICAgICAgICAgICAgICh7IGVuZW15LCB0aGlzX29iamVjdCgpIH0pKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIDE6CisgICAgICAgIHRlbGxfb2JqZWN0KGVuZW15LHNwcmludGYoIiAgSWhyIGtpdHplbHQgJXMgYW0gQmF1Y2guXG4iLG15bmFtZSkpOworICAgICAgICB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLAorICAgICAgICAgIHNwcmludGYoIiAgJXMga2l0emVsbiBEaWNoIGFtIEJhdWNoLlxuIixlbm5hbWUpKTsKKyAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVuZW15KXx8ZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgc3ByaW50ZigiICAlcyBraXR6ZWxuICVzIGFtIEJhdWNoLlxuIixlbm5hbWUsbXluYW1lKSwKKyAgICAgICAgICAgICAgICAgICh7IGVuZW15LCB0aGlzX29iamVjdCgpIH0pKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIDIuLjM6CisgICAgICAgIHRlbGxfb2JqZWN0KGVuZW15LHNwcmludGYoIiAgSWhyIGtyYXR6dCAlcy5cbiIsbXluYW1lKSk7CisgICAgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksc3ByaW50ZigiICAlcyBrcmF0emVuIERpY2guXG4iLGVubmFtZSkpOworICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoZW5lbXkpfHxlbnZpcm9ubWVudCh0aGlzX29iamVjdCgpKSwKKyAgICAgICAgICBzcHJpbnRmKCIgICVzIGtyYXR6ZW4gJXMuXG4iLGVubmFtZSxteW5hbWUpLAorICAgICAgICAgICAgICAgICAgKHsgZW5lbXksIHRoaXNfb2JqZWN0KCkgfSkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgNC4uNToKKyAgICAgICAgdGVsbF9vYmplY3QoZW5lbXksc3ByaW50ZigiICBJaHIgdHJlZmZ0ICVzLlxuIixteW5hbWUpKTsKKyAgICAgICAgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSxzcHJpbnRmKCIgICVzIHRyZWZmZW4gRGljaC5cbiIsZW5uYW1lKSk7CisgICAgICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudChlbmVteSl8fGVudmlyb25tZW50KHRoaXNfb2JqZWN0KCkpLAorICAgICAgICAgIHNwcmludGYoIiAgJXMgdHJlZmZlbiAlcy5cbiIsZW5uYW1lLG15bmFtZSksCisgICAgICAgICAgICAgICAgICAoeyBlbmVteSwgdGhpc19vYmplY3QoKSB9KSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSA2Li4xMDoKKyAgICAgICAgdGVsbF9vYmplY3QoZW5lbXksc3ByaW50ZigiICBJaHIgdHJlZmZ0ICVzIGhhcnQuXG4iLG15bmFtZSkpOworICAgICAgICB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLHNwcmludGYoIiAgJXMgdHJlZmZlbiBEaWNoIGhhcnQuXG4iLGVubmFtZSkpOworICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoZW5lbXkpfHxlbnZpcm9ubWVudCh0aGlzX29iamVjdCgpKSwKKyAgICAgICAgICBzcHJpbnRmKCIgICVzIHRyZWZmZW4gJXMgaGFydC5cbiIsZW5uYW1lLG15bmFtZSksCisgICAgICAgICAgICAgICAgICAoeyBlbmVteSwgdGhpc19vYmplY3QoKSB9KSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSAxMS4uMjA6CisgICAgICAgIHRlbGxfb2JqZWN0KGVuZW15LHNwcmludGYoIiAgSWhyIHRyZWZmdCAlcyBzZWhyIGhhcnQuXG4iLG15bmFtZSkpOworICAgICAgICB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLAorICAgICAgICAgIHNwcmludGYoIiAgJXMgdHJlZmZlbiBEaWNoIHNlaHIgaGFydC5cbiIsZW5uYW1lKSk7CisgICAgICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudChlbmVteSl8fGVudmlyb25tZW50KHRoaXNfb2JqZWN0KCkpLAorICAgICAgICAgIHNwcmludGYoIiAgJXMgdHJlZmZlbiAlcyBzZWhyIGhhcnQuXG4iLGVubmFtZSxteW5hbWUpLAorICAgICAgICAgICAgICAgICAgKHsgZW5lbXksIHRoaXNfb2JqZWN0KCkgfSkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgMjEuLjMwOgorICAgICAgICB0ZWxsX29iamVjdChlbmVteSwKKyAgICAgICAgICBzcHJpbnRmKCIgIElociBzY2hsYWd0ICVzIG1pdCBkZW0gS3JhY2hlbiBicmVjaGVuZGVyIEtub2NoZW4uXG4iLAorICAgICAgICAgICAgICAgICAgbXluYW1lKSk7CisgICAgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksCisgICAgICAgICAgc3ByaW50ZigiICAlcyBzY2hsYWdlbiBEaWNoIG1pdCBkZW0gS3JhY2hlbiBicmVjaGVuZGVyIEtub2NoZW4uXG4iLAorICAgICAgICAgICAgICAgICAgZW5uYW1lKSk7CisgICAgICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudChlbmVteSl8fGVudmlyb25tZW50KHRoaXNfb2JqZWN0KCkpLAorICAgICAgICAgIHNwcmludGYoIiAgJXMgc2NobGFnZW4gJXMgbWl0IGRlbSBLcmFjaGVuIGJyZWNoZW5kZXIgS25vY2hlbi5cbiIsCisgICAgICAgICAgICAgICAgICBlbm5hbWUsbXluYW1lKSwgKHsgZW5lbXksIHRoaXNfb2JqZWN0KCkgfSkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgMzEuLjUwOgorICAgICAgICB0ZWxsX29iamVjdChlbmVteSwKKyAgICAgICAgICBzcHJpbnRmKCIgIElociB6ZXJzY2htZXR0ZXJ0ICVzIGluIGtsZWluZSBTdHVlY2tjaGVuLlxuIixteW5hbWUpKTsKKyAgICAgICAgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSwKKyAgICAgICAgICBzcHJpbnRmKCIgICVzIHplcnNjaG1ldHRlcm4gRGljaCBpbiBrbGVpbmUgU3R1ZWNrY2hlbi5cbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbm5hbWUpKTsKKyAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVuZW15KXx8ZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgc3ByaW50ZigiICAlcyB6ZXJzY2htZXR0ZXJuICVzIGluIGtsZWluZSBTdHVlY2tjaGVuLlxuIiwKKyAgICAgICAgICAgICAgICAgIGVubmFtZSxteW5hbWUpLCAoeyBlbmVteSwgdGhpc19vYmplY3QoKSB9KSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSA1MS4uNzU6CisgICAgICAgIHRlbGxfb2JqZWN0KGVuZW15LHNwcmludGYoIiAgSWhyIHNjaGxhZ3QgJXMgenUgQnJlaS5cbiIsbXluYW1lKSk7CisgICAgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksCisgICAgICAgICAgc3ByaW50ZigiICAlcyBzY2hsYWdlbiBEaWNoIHp1IEJyZWkuXG4iLGVubmFtZSkpOworICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoZW5lbXkpfHxlbnZpcm9ubWVudCh0aGlzX29iamVjdCgpKSwKKyAgICAgICAgICBzcHJpbnRmKCIgICVzIHNjaGxhZ2VuICVzIHp1IEJyZWkuXG4iLGVubmFtZSxteW5hbWUpLAorICAgICAgICAgICAgICAgICAgKHsgZW5lbXksIHRoaXNfb2JqZWN0KCkgfSkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgNzYuLjEwMDoKKyAgICAgICAgdGVsbF9vYmplY3QoZW5lbXksc3ByaW50ZigiICBJaHIgcHVsdmVyaXNpZXJ0ICVzLlxuIixteW5hbWUpKTsKKyAgICAgICAgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSxzcHJpbnRmKCIgICVzIHB1bHZlcmlzaWVyZW4gRGljaC5cbiIsZW5uYW1lKSk7CisgICAgICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudChlbmVteSl8fGVudmlyb25tZW50KHRoaXNfb2JqZWN0KCkpLAorICAgICAgICAgIHNwcmludGYoIiAgJXMgcHVsdmVyaXNpZXJlbiAlcy5cbiIsZW5uYW1lLG15bmFtZSksCisgICAgICAgICAgICAgICAgICAoeyBlbmVteSwgdGhpc19vYmplY3QoKSB9KSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSAxMDEuLjE1MDoKKyAgICAgICAgdGVsbF9vYmplY3QoZW5lbXksc3ByaW50ZigiICBJaHIgemVyc3RhZXVidCAlcy5cbiIsbXluYW1lKSk7CisgICAgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksc3ByaW50ZigiICAlcyB6ZXJzdGFldWJlbiBEaWNoLlxuIixlbm5hbWUpKTsKKyAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVuZW15KXx8ZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgc3ByaW50ZigiICAlcyB6ZXJzdGFldWJlbiAlcy5cbiIsZW5uYW1lLG15bmFtZSksCisgICAgICAgICAgICAgICAgICAoeyBlbmVteSwgdGhpc19vYmplY3QoKSB9KSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSAxNTEuLjIwMDoKKyAgICAgICAgdGVsbF9vYmplY3QoZW5lbXksc3ByaW50ZigiICBJaHIgYXRvbWlzaWVydCAlcy5cbiIsbXluYW1lKSk7CisgICAgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksc3ByaW50ZigiICAlcyBhdG9taXNpZXJlbiBEaWNoLlxuIixlbm5hbWUpKTsKKyAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVuZW15KXx8ZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgc3ByaW50ZigiICAlcyBhdG9taXNpZXJlbiAlcy5cbiIsZW5uYW1lLG15bmFtZSksCisgICAgICAgICAgICAgICAgICAoeyBlbmVteSwgdGhpc19vYmplY3QoKSB9KSk7CisgICAgICAgIGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGVsbF9vYmplY3QoZW5lbXksc3ByaW50ZigiICBJaHIgdmVybmljaHRldCAlcy5cbiIsbXluYW1lKSk7CisgICAgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksc3ByaW50ZigiICAlcyB2ZXJuaWNodGVuIERpY2guXG4iLGVubmFtZSkpOworICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoZW5lbXkpfHxlbnZpcm9ubWVudCh0aGlzX29iamVjdCgpKSwKKyAgICAgICAgICBzcHJpbnRmKCIgICVzIHZlcm5pY2h0ZW4gJXMuXG4iLGVubmFtZSxteW5hbWUpLAorICAgICAgICAgICAgICAgICAgKHsgZW5lbXksIHRoaXNfb2JqZWN0KCkgfSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgIHN3aXRjaCAoZGFtKSB7CisgICAgICBjYXNlIDA6CisgICAgICAgIHRlbGxfb2JqZWN0KGVuZW15LHNwcmludGYoIiAgRHUgdmVyZmVobHN0ICVzLlxuIixteW5hbWUpKTsKKyAgICAgICAgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSxzcHJpbnRmKCIgICVzIHZlcmZlaGx0IERpY2guXG4iLGVubmFtZSkpOworICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoZW5lbXkpfHxlbnZpcm9ubWVudCh0aGlzX29iamVjdCgpKSwKKyAgICAgICAgICBzcHJpbnRmKCIgICVzIHZlcmZlaGx0ICVzLlxuIixlbm5hbWUsbXluYW1lKSwKKyAgICAgICAgICAgICAgICAgICh7IGVuZW15LCB0aGlzX29iamVjdCgpIH0pKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIDE6CisgICAgICAgIHRlbGxfb2JqZWN0KGVuZW15LHNwcmludGYoIiAgRHUga2l0emVsc3QgJXMgYW0gQmF1Y2guXG4iLG15bmFtZSkpOworICAgICAgICB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLAorICAgICAgICAgIHNwcmludGYoIiAgJXMga2l0emVsdCBEaWNoIGFtIEJhdWNoLlxuIixlbm5hbWUpKTsKKyAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVuZW15KXx8ZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgc3ByaW50ZigiICAlcyBraXR6ZWx0ICVzIGFtIEJhdWNoLlxuIixlbm5hbWUsbXluYW1lKSwKKyAgICAgICAgICAgICAgICAgICh7IGVuZW15LCB0aGlzX29iamVjdCgpIH0pKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIDIuLjM6CisgICAgICAgIHRlbGxfb2JqZWN0KGVuZW15LHNwcmludGYoIiAgRHUga3JhdHp0ICVzLlxuIixteW5hbWUpKTsKKyAgICAgICAgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSxzcHJpbnRmKCIgICVzIGtyYXR6dCBEaWNoLlxuIixlbm5hbWUpKTsKKyAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVuZW15KXx8ZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgc3ByaW50ZigiICAlcyBrcmF0enQgJXMuXG4iLGVubmFtZSxteW5hbWUpLAorICAgICAgICAgICAgICAgICAgKHsgZW5lbXksIHRoaXNfb2JqZWN0KCkgfSkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgNC4uNToKKyAgICAgICAgdGVsbF9vYmplY3QoZW5lbXksc3ByaW50ZigiICBEdSB0cmlmZnN0ICVzLlxuIixteW5hbWUpKTsKKyAgICAgICAgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSxzcHJpbnRmKCIgICVzIHRyaWZmdCBEaWNoLlxuIixlbm5hbWUpKTsKKyAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVuZW15KXx8ZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgc3ByaW50ZigiICAlcyB0cmlmZnQgJXMuXG4iLGVubmFtZSxteW5hbWUpLAorICAgICAgICAgICAgICAgICAgKHsgZW5lbXksIHRoaXNfb2JqZWN0KCkgfSkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgNi4uMTA6CisgICAgICAgIHRlbGxfb2JqZWN0KGVuZW15LHNwcmludGYoIiAgRHUgdHJpZmZzdCAlcyBoYXJ0LlxuIixteW5hbWUpKTsKKyAgICAgICAgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSxzcHJpbnRmKCIgICVzIHRyaWZmdCBEaWNoIGhhcnQuXG4iLGVubmFtZSkpOworICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoZW5lbXkpfHxlbnZpcm9ubWVudCh0aGlzX29iamVjdCgpKSwKKyAgICAgICAgICBzcHJpbnRmKCIgICVzIHRyaWZmdCAlcyBoYXJ0LlxuIixlbm5hbWUsbXluYW1lKSwKKyAgICAgICAgICAgICh7IGVuZW15LCB0aGlzX29iamVjdCgpIH0pKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIDExLi4yMDoKKyAgICAgICAgdGVsbF9vYmplY3QoZW5lbXksc3ByaW50ZigiICBEdSB0cmlmZnN0ICVzIHNlaHIgaGFydC5cbiIsbXluYW1lKSk7CisgICAgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksCisgICAgICAgICAgc3ByaW50ZigiICAlcyB0cmlmZnQgRGljaCBzZWhyIGhhcnQuXG4iLGVubmFtZSkpOworICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoZW5lbXkpfHxlbnZpcm9ubWVudCh0aGlzX29iamVjdCgpKSwKKyAgICAgICAgICBzcHJpbnRmKCIgICVzIHRyaWZmdCAlcyBzZWhyIGhhcnQuXG4iLGVubmFtZSxteW5hbWUpLAorICAgICAgICAgICAgICAgICAgKHsgZW5lbXksIHRoaXNfb2JqZWN0KCkgfSkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgMjEuLjMwOgorICAgICAgICB0ZWxsX29iamVjdChlbmVteSwKKyAgICAgICAgICBzcHJpbnRmKCIgIER1IHNjaGxhZWdzdCAlcyBtaXQgZGVtIEtyYWNoZW4gYnJlY2hlbmRlciBLbm9jaGVuLlxuIiwKKyAgICAgICAgICAgICAgICAgIG15bmFtZSkpOworICAgICAgICB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLAorICAgICAgICAgIHNwcmludGYoIiAgJXMgc2NobGFlZ3QgRGljaCBtaXQgZGVtIEtyYWNoZW4gYnJlY2hlbmRlciBLbm9jaGVuLlxuIiwKKyAgICAgICAgICAgICAgICAgIGVubmFtZSkpOworICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoZW5lbXkpfHxlbnZpcm9ubWVudCh0aGlzX29iamVjdCgpKSwKKyAgICAgICAgICBzcHJpbnRmKCIgICVzIHNjaGxhZWd0ICVzIG1pdCBkZW0gS3JhY2hlbiBicmVjaGVuZGVyIEtub2NoZW4uXG4iLAorICAgICAgICAgICAgICAgICAgZW5uYW1lLG15bmFtZSksICh7IGVuZW15LCB0aGlzX29iamVjdCgpIH0pKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIDMxLi41MDoKKyAgICAgICAgdGVsbF9vYmplY3QoZW5lbXksCisgICAgICAgICAgc3ByaW50ZigiICBEdSB6ZXJzY2htZXR0ZXJzdCAlcyBpbiBrbGVpbmUgU3R1ZWNrY2hlbi5cbiIsbXluYW1lKSk7CisgICAgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksCisgICAgICAgICAgc3ByaW50ZigiICAlcyB6ZXJzY2htZXR0ZXJ0IERpY2ggaW4ga2xlaW5lIFN0dWVja2NoZW4uXG4iLGVubmFtZSkpOworICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoZW5lbXkpfHxlbnZpcm9ubWVudCh0aGlzX29iamVjdCgpKSwKKyAgICAgICAgICBzcHJpbnRmKCIgICVzIHplcnNjaG1ldHRlcnQgJXMgaW4ga2xlaW5lIFN0dWVja2NoZW4uXG4iLAorICAgICAgICAgICAgICAgICAgZW5uYW1lLG15bmFtZSksICh7IGVuZW15LCB0aGlzX29iamVjdCgpIH0pKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIDUxLi43NToKKyAgICAgICAgdGVsbF9vYmplY3QoZW5lbXksc3ByaW50ZigiICBEdSBzY2hsYWVnc3QgJXMgenUgQnJlaS5cbiIsbXluYW1lKSk7CisgICAgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksCisgICAgICAgICAgc3ByaW50ZigiICAlcyBzY2hsYWVndCBEaWNoIHp1IEJyZWkuXG4iLGVubmFtZSkpOworICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoZW5lbXkpfHxlbnZpcm9ubWVudCh0aGlzX29iamVjdCgpKSwKKyAgICAgICAgICBzcHJpbnRmKCIgICVzIHNjaGxhZWd0ICVzIHp1IEJyZWkuXG4iLGVubmFtZSxteW5hbWUpLAorICAgICAgICAgICAgICAgICAgKHsgZW5lbXksIHRoaXNfb2JqZWN0KCkgfSkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgNzYuLjEwMDoKKyAgICAgICAgdGVsbF9vYmplY3QoZW5lbXksc3ByaW50ZigiICBEdSBwdWx2ZXJpc2llcnN0ICVzLlxuIixteW5hbWUpKTsKKyAgICAgICAgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSxzcHJpbnRmKCIgICVzIHB1bHZlcmlzaWVydCBEaWNoLlxuIixlbm5hbWUpKTsKKyAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVuZW15KXx8ZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgc3ByaW50ZigiICAlcyBwdWx2ZXJpc2llcnQgJXMuXG4iLGVubmFtZSxteW5hbWUpLAorICAgICAgICAgICAgICAgICAgKHsgZW5lbXksIHRoaXNfb2JqZWN0KCkgfSkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgMTAxLi4xNTA6CisgICAgICAgIHRlbGxfb2JqZWN0KGVuZW15LHNwcmludGYoIiAgRHUgemVyc3RhZXVic3QgJXMuXG4iLG15bmFtZSkpOworICAgICAgICB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLHNwcmludGYoIiAgJXMgemVyc3RhZXVidCBEaWNoLlxuIixlbm5hbWUpKTsKKyAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVuZW15KXx8ZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgc3ByaW50ZigiICAlcyB6ZXJzdGFldWJ0ICVzLlxuIixlbm5hbWUsbXluYW1lKSwKKyAgICAgICAgICAgICAgICAgICh7IGVuZW15LCB0aGlzX29iamVjdCgpIH0pKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIDE1MS4uMjAwOgorICAgICAgICB0ZWxsX29iamVjdChlbmVteSxzcHJpbnRmKCIgIER1IGF0b21pc2llcnN0ICVzLlxuIixteW5hbWUpKTsKKyAgICAgICAgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSxzcHJpbnRmKCIgICVzIGF0b21pc2llcnQgRGljaC5cbiIsZW5uYW1lKSk7CisgICAgICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudChlbmVteSl8fGVudmlyb25tZW50KHRoaXNfb2JqZWN0KCkpLAorICAgICAgICAgIHNwcmludGYoIiAgJXMgYXRvbWlzaWVydCAlcy5cbiIsZW5uYW1lLG15bmFtZSksCisgICAgICAgICAgICAgICAgICAoeyBlbmVteSwgdGhpc19vYmplY3QoKSB9KSk7CisgICAgICAgIGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGVsbF9vYmplY3QoZW5lbXksc3ByaW50ZigiICBEdSB2ZXJuaWNodGVzdCAlcy5cbiIsbXluYW1lKSk7CisgICAgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksc3ByaW50ZigiICAlcyB2ZXJuaWNodGV0IERpY2guXG4iLGVubmFtZSkpOworICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoZW5lbXkpfHxlbnZpcm9ubWVudCh0aGlzX29iamVjdCgpKSwKKyAgICAgICAgICBzcHJpbnRmKCIgICVzIHZlcm5pY2h0ZXQgJXMuXG4iLGVubmFtZSxteW5hbWUpLAorICAgICAgICAgICAgICAgICAgKHsgZW5lbXksIHRoaXNfb2JqZWN0KCkgfSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvLyBNYW4ga2FubiBhdWNoIHNlbGJzdC1kZWZpbmllcnRlIFNjaGFkZW5zbWVsZHVuZ2VuIGF1c2dlYmVuIGxhc3NlbgorICBlbHNlIGlmKCBzcGVsbFtTUF9TSE9XX0RBTUFHRV0gJiYgcG9pbnRlcnAoZGFtX21zZykgKQorICB7CisgICAgZm9yKCBpPXNpemVvZihkYW1fbXNnKSA7IC0taSA+PSAwIDsgKQorICAgIHsKKyAgICAgIGlmICggZGFtPmRhbV9tc2dbaV1bMF0gKQorICAgICAgeworICAgICAgICB0ZWxsX29iamVjdChNRSxtZXNzKGRhbV9tc2dbaV1bMV0sTUUsZW5lbXkpKTsKKyAgICAgICAgdGVsbF9vYmplY3QoZW5lbXksbWVzcyhkYW1fbXNnW2ldWzJdLE1FLGVuZW15KSk7CisgICAgICAgIHNheShtZXNzKGRhbV9tc2dbaV1bM10sTUUsZW5lbXkpLCBlbmVteSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorICAvLyBlbHNlICghc3BlbGxbU1BfU0hPV19EQU1BR0VdKSBrZWluZSBTY2hhZGVuc21lbGR1bmcuCisKKyAgLy8gSW5mb3JtYXRpb25lbiB1ZWJlciBkZW4gbGV0enRlbiBBbmdyaWZmIGZlc3RoYWx0ZW4KKyAgU2V0KFBfTEFTVF9EQU1UWVBFUywgZGFtX3R5cGUpOworICBTZXQoUF9MQVNUX0RBTVRJTUUsICB0aW1lKCkpOworICBTZXQoUF9MQVNUX0RBTUFHRSwgICBkYW0pOworCisgIC8vIEJlaSBBbmdyaWZmZW4gbWl0IFNQX05PX0VORU1ZLUZsYWcga2FubiBtYW4gbmljaHQgc3RlcmJlbiAuLi4KKyAgaWYgKCBzcGVsbFtTUF9OT19FTkVNWV0gKQorICAgIHJlZHVjZV9oaXRfcG9pbnRzKGRhbSk7CisgIC8vIC4uLiBiZWkgYWxsZW4gYW5kZXJlbiBuYXR1ZXJsaWNoIHNjaG9uCisgIGVsc2UKKyAgICBkb19kYW1hZ2UoZGFtLGVuZW15KTsKKworICAvLyBldnRsLiBpc3QgZGllcyBPYmpla3QgaGllciB0b3QuLi4KKyAgaWYgKCFvYmplY3RwKE1FKSkgcmV0dXJuIGRhbTsKKworICAvLyBUZXN0ZW4sIG9iIG1hbiBpbiBkaWUgRnVjaHQgZ2VzY2hsYWdlbiB3aXJkCisgIENoZWNrV2ltcHlBbmRGbGVlKCk7CisKKyAgLy8gVmVydXJzYWNodGVuIFNjaGFkZW4gKGluIExQKSB6dXJ1ZWNrZ2ViZW4KKyAgcmV0dXJuIGRhbTsKK30KKworcHVibGljIGZsb2F0IENoZWNrUmVzaXN0YW5jZShzdHJpbmcgKmRhbV90eXBlKSB7CisgICAgLy9mdW5rdGlvbiBrcmllZ3QgZGllIHNjaGFkZW5zYXJ0ZW4gdWViZXJnZWJlbiwgc2NoYXV0IHNpY2ggZGllc2VzCisgICAgLy9zb3dpZSBQX1JFU0lTVEVOQ0VfU1RSRU5HVEggdW5kIFBfUkVTSVRFTkNFX01PREZJRklFUiBhbiB1bmQgYmVyZWNobmV0CisgICAgLy9laW5lbiBGYWt0b3IsIG1pdCBkZW0gZGllIHVyc3BydWVuZ2xpY2hlIFNjaGFkZW5zbWVuZ2UgbXVsdGlwbGl6aWVydAorICAgIC8vd2lyZCwgdW0gZGVuIFNjaGFkZW4gbmFjaCBCZXJ1ZWNrc2ljaHRpZ3VuZyBkZXIgUmVzaXMvQW5mYWVsbGlna2VpdGVuIHp1CisgICAgLy9lcmhhbHRlbi4gUnVlY2tnYWJld2VydCBub3JtYWxlcndlaXNlIChzLnUuKSA+PTAuCisgIG1hcHBpbmcgcnN0cmVuLCBtb2Q7CisgIGZsb2F0ICAgZmFrdG9yLG47CisgIGludCAgICAgaTsKKworICBtb2QgPSBRdWVyeShQX1JFU0lTVEFOQ0VfTU9ESUZJRVIpOworICBpZiAoIG1hcHBpbmdwKG1vZCkgKQorICAgIG1vZCA9IG1vZFsibWUiXTsKKworICBpZiAoICFtYXBwaW5ncChyc3RyZW49UXVlcnkoUF9SRVNJU1RBTkNFX1NUUkVOR1RIUykpICkKKyAgeworICAgIGlmICghbWFwcGluZ3AobW9kKSkKKyAgICAgIHJldHVybiAxLjA7CisgICAgZWxzZQorICAgICAgcnN0cmVuID0gKFtdKTsKKyAgfQorCisgIGlmICggIW1hcHBpbmdwKG1vZCkgKQorICAgIG1vZCA9IChbXSk7CisKKyAgaWYgKCAoaT1zaXplb2YoZGFtX3R5cGUpKTwxICkKKyAgICByZXR1cm4gMS4wOworCisgIG49dG9fZmxvYXQoaSk7CisgIGZha3Rvcj0wLjA7CisKKyAgLy9kaWVzIGhpZXIgdHV0IG5pY2h0IG1laHIgZGFzIGdld3VlbnNjaHRlLCB3ZW5uIGluIFBfUkVTSVNURU5DRV9TVFJFTkdUSFMKKyAgLy9GYWt0b3JlbiA8LTEuMCBhbmdlZ2ViZW4gd2VyZGVuLiBSdWVja2dhYmV3ZXJ0ZSA8MCBzaW5kIGRhbm4gbW9lZ2xpY2ggdW5kCisgIC8vbGVpZGVyIHdlcmRlbiBkaWUgU2NoYWRlbnNhcnRlbiBvaG5lIFJlc2lzIG5pY2h0IG1laHIgcmljaHRpZyB2ZXJ3dXJzdGV0LiA6LS8KKyAgZm9yZWFjaChzdHJpbmcgZHQ6IGRhbV90eXBlKSB7CisgICAgZmFrdG9yID0gZmFrdG9yICsgKDEuMCArIHRvX2Zsb2F0KHJzdHJlbltkdF0pKQorICAgICAgICAgICAqICgxLjAgKyB0b19mbG9hdChtb2RbZHRdKSktMS4wOworICB9CisgIHJldHVybiAxLjArKGZha3Rvci9uKTsKK30KKworcHVibGljIHZhcmFyZ3MgbWFwcGluZyBTdG9wSHVudGluZ01vZGUoaW50IHNpbGVudCkKK3sgbWFwcGluZyBzYXZlX2VuZW15OworICBpbnQgICAgIGk7CisKKyAgc2F2ZV9lbmVteT1lbmVtaWVzOworICBpZiAoICFzaWxlbnQgKQorICAgIHdhbGtfbWFwcGluZyhlbmVtaWVzLCAjJ1N0b3BIdW50VGV4dCk7IC8vIycpOworCisgIGVuZW1pZXM9bV9hbGxvY2F0ZSgwLDEpOworICBsYXN0X2F0dGFja19tc2c9MDsKKworICByZXR1cm4gc2F2ZV9lbmVteTsKK30KKworcHVibGljIDxvYmplY3QqfGludCo+KiBRdWVyeUVuZW1pZXMoKQoreworICByZXR1cm4gKHttX2luZGljZXMoZW5lbWllcyksbV92YWx1ZXMoZW5lbWllcyl9KTsKK30KKworcHVibGljIG1hcHBpbmcgR2V0RW5lbWllcygpCit7CisgIHJldHVybiBlbmVtaWVzOworfQorCitwdWJsaWMgbWFwcGluZyBTZXRFbmVtaWVzKDxvYmplY3QqfGludCo+KiBteWVuZW1pZXMpCit7CisgIGVuZW1pZXM9bWttYXBwaW5nKG15ZW5lbWllc1swXSxteWVuZW1pZXNbMV0pOworICByZXR1cm4gZW5lbWllczsKK30KKworcHJpdmF0ZSBzdHJpbmcgX2tpbGxfYWxpYXMoIHN0cmluZyBzdHIgKQoreworICAgIHJldHVybiAiXFwiICsgc3RyOworfQorCitwdWJsaWMgdmFyYXJncyB2b2lkIEZsZWUoIG9iamVjdCBvbGRlbnYsIGludCBmb3JjZSApCit7IG1peGVkICAgKmV4aXRzLCBleGl0LCBkZXg7CisgIG1hcHBpbmcgdG1wOworICBpbnQgICAgIGk7CisgIG9iamVjdCAgZW52OworCisgIGlmICggIWVudmlyb25tZW50KCkgKQorICAgIHJldHVybjsKKworICAvLyBtaXQgJ2ZvcmNlJyBrYW5uIG1hbiBkaWUgQ2hlY2tzIHVtZ2VoZW4sIGRhbWl0IGRlciBTcGllbGVyIGF1ZiBqZWRlbgorICAvLyBGYWxsIGZsdWVjaHRldCAuLi4KKyAgaWYgKCAhZm9yY2UgJiYgKCBvbGRlbnYgJiYgKG9sZGVudiAhPSBlbnZpcm9ubWVudCgpKSB8fAorICAgICAgICAgICAgICAgICAgIHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoTUUpICYmICghRW5lbXlQcmVzZW50KCkgfHwKKyAgICAgICAgICAgICAgICAgICAoUXVlcnlQcm9wKFBfSFApID49IFF1ZXJ5UHJvcChQX1dJTVBZKSkpICkgKQorICAgIHJldHVybjsKKworICAvLyAuLi4gYWJlciBNYWdpZXIgZmx1ZWNodGVuIHp1IGxhc3NlbiBpc3QgbmljaHQgZ2FueiBzbyBlaW5mYWNoIDstKQorICBpZiAoIHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUodGhpc19vYmplY3QoKSkgJiYgSVNfTEVBUk5JTkcodGhpc19vYmplY3QoKSkgKQorICAgIHJldHVybjsKKworICAvLyBHZWlzdGVyIGJyYXVjaGVuIG5pY2h0IHVtIGlociBMZWJlbiB6dSBmdWVyY2h0ZW4KKyAgaWYgKCBRdWVyeVByb3AoUF9HSE9TVCkgKQorICAgIHJldHVybjsKKworICB0ZWxsX29iamVjdCggTUUsICJEaWUgQW5nc3QgaXN0IHN0YWVya2VyIGFscyBEdSAuLi4gIisKKyAgICAgICAgICAgICAgICAgICAiRHUgd2lsbHN0IG51ciBub2NoIHdlZyBoaWVyLlxuIik7CisKKyAgaWYgKCBUZWFtRmxlZSgpICkgLy8gRXJmb2xncmVpY2hlIEZsdWNodCBpbiBoaW50ZXJlIEthbXBmcmVpaGU/CisgICAgcmV0dXJuOworCisgIGVudiA9IGVudmlyb25tZW50KCk7CisgIHRtcCA9IGVudmlyb25tZW50KCktPlF1ZXJ5UHJvcChQX0VYSVRTKTsKKyAgZXhpdHMgPSBtX2luZGljZXModG1wKTsKKyAgdG1wID0gZW52aXJvbm1lbnQoKS0+UXVlcnlQcm9wKFBfU1BFQ0lBTF9FWElUUyk7CisgIGV4aXRzICs9IG1faW5kaWNlcyh0bXApOworCisgIGlmICggcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkgKQorICAgICAgICBleGl0cyA9IG1hcCggZXhpdHMsICMnX2tpbGxfYWxpYXMvKicqLyApOworCisgIC8vIGRpZSBGbHVjaHRyaWNodHVuZyB2b24gTWFnaWVybiB3aXJkIGF1cyBTaWNoZXJoZWl0c2dydWVuZGVuCisgIC8vIG5pY2h0IGF1c2dld2VydGV0CisgIGlmICggaW50ZXJhY3RpdmUoTUUpICYmIElTX1NFRVIoTUUpICYmICFJU19MRUFSTkVSKE1FKQorICAgICAgJiYgKGRleD1RdWVyeVByb3AoUF9XSU1QWV9ESVJFQ1RJT04pKSApCisgIHsKKyAgICBpID0gNjAgKyA0ICogKFF1ZXJ5UHJvcChQX0xFVkVMKSAtIDMwKSAvIDM7CisgICAgZXhpdHMgKz0gKHtkZXh9KTsgLy8gYmV2b3J6dWd0ZSBGbHVjaHRyaWNodHVuZyBtaW5kZXN0ZW5zIGVpbm1hbAorICB9CisKKyAgaWYgKCAhc2l6ZW9mKGV4aXRzKSApCisgIHsKKyAgICB0ZWxsX29iamVjdCggTUUsICJEdSB2ZXJzdWNoc3QgenUgZmxpZWhlbiwgc2NoYWZmc3QgZXMgYWJlciBuaWNodC5cbiIgKTsKKworICAgIHJldHVybjsKKyAgfQorCisgIHdoaWxlICggc2l6ZW9mKGV4aXRzKSAmJiAoZW52aXJvbm1lbnQoKT09ZW52KSApCisgIHsKKyAgICBpZiAoIGRleCAgICAgICAgICAgICAgICAgICAgICAgICAvLyBWb3J6dWdzd2Vpc2UgRmx1Y2h0cmljaHR1bmc/CisgICAgICAgICYmIChtZW1iZXIoZXhpdHMsZGV4KSA+PSAwKSAgLy8gbW9lZ2xpY2g/CisgICAgICAgICYmIChyYW5kb20oMTAwKSA8PSBpKSkgICAgICAgLy8gdW5kIFdhaHJzY2hlaW5saWNoa2VpdCBncm9zcyBnZW51Zz8KKyAgICAgIGV4aXQgPSBkZXg7CisgICAgZWxzZQorICAgICAgZXhpdCA9IGV4aXRzW3JhbmRvbShzaXplb2YoZXhpdHMpKV07CisKKyAgICBjYXRjaChjb21tYW5kKGV4aXQpO3B1Ymxpc2gpOworICAgIGV4aXRzIC09ICh7ZXhpdH0pOworICB9CisKKyAgaWYgKCBlbnZpcm9ubWVudCgpPT1lbnYgKQorICAgIHRlbGxfb2JqZWN0KCBNRSwgIkRlaW4gRmx1Y2h0dmVyc3VjaCBpc3QgZ2VzY2hlaXRlcnQuXG4iICk7Cit9CisKK3B1YmxpYyBvYmplY3QgRW5lbXlQcmVzZW50KCkKK3sKKyAgZm9yZWFjaChvYmplY3QgZW46IGVuZW1pZXMpIHsKKyAgICBpZiAoZW52aXJvbm1lbnQoKT09ZW52aXJvbm1lbnQoZW4pKQorICAgICAgcmV0dXJuIGVuOworICB9CisgIHJldHVybiAwOworfQorCitwdWJsaWMgb2JqZWN0IEluRmlnaHQoKQoreworICByZXR1cm4gRW5lbXlQcmVzZW50KCk7Cit9CisKK3B1YmxpYyB2YXJhcmdzIGludCBTdG9wSHVudElEKHN0cmluZyBzdHIsIGludCBzaWxlbnQpIHsgCisKKyAgaWYgKCAhc3RyaW5ncChzdHIpICkKKyAgICByZXR1cm4gMDsKKworICBpbnQgajsKKyAgZm9yZWFjaChvYmplY3QgZW46IGVuZW1pZXMpIHsKKyAgICBpZiAoZW4tPmlkKHN0cikpIHsKKyAgICAgIFN0b3BIdW50Rm9yKGVuLHNpbGVudCk7CisgICAgICBqKys7CisgICAgfQorICB9CisKKyAgcmV0dXJuIGo7Cit9CisKK3B1YmxpYyBpbnQgU3BlbGxEZWZlbmQob2JqZWN0IGNhc3RlciwgbWFwcGluZyBzaW5mbykKK3sgaW50ICAgIHJlOworICBtaXhlZCAgcmVzOworICBzdHJpbmcgKmluZDsKKworICByZSA9IFVzZVNraWxsKFNLX1NQRUxMX0RFRkVORCwoWyBTSV9TS0lMTEFSRyA6IHNpbmZvICwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0lfRU5FTVkgICAgOiBjYXN0ZXIgXSkgKTsKKworICBpZiAoIChyZXM9UXVlcnlQcm9wKFBfTUFHSUNfUkVTSVNUQU5DRV9PRkZTRVQpKSAmJiBtYXBwaW5ncChyZXMpCisgICAgICAmJiBwb2ludGVycChzaW5mb1tTSV9NQUdJQ19UWVBFXSkpCisgIHsKKyAgICBpbmQgPSBtX2luZGljZXMocmVzKSAmIHNpbmZvW1NJX01BR0lDX1RZUEVdOworCisgICAgaWYgKHBvaW50ZXJwKGluZCkgJiYgc2l6ZW9mKGluZCkgKSB7CisgICAgICBmb3JlYWNoKHN0cmluZyBpbmRleCA6IGluZCkKKyAgICAgICAgcmUrPXJlc1tpbmRleF07CisgICAgfQorICB9CisgIGVsc2UgaWYocmVzICYmIGludHAocmVzKSkKKyAgICByZSs9cmVzOworCisgIGlmICggKHJlPjMzMzMpICYmIHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUodGhpc19vYmplY3QoKSkgKQorICAgIHJlPTMzMzM7IC8qIE1heGltYWwgMzMlIEFid2VocmNoYW5jZSBiZWkgU3BpZWxlcm4gKi8KKyAgcmV0dXJuIHJlOworfQorCisvLyAqKioqIHRoaXMgaXMgcHJvcGVydHktbGlrZQorCitzdGF0aWMgaW50IF9zZXRfYXR0YWNrX2J1c3kobWl4ZWQgdmFsKQoreworICBpZiAoICgodG9faW50KHZhbCkpPjUpICYmIHByZXZpb3VzX29iamVjdCgxKQorICAgICAgJiYgcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShwcmV2aW91c19vYmplY3QoMSkpICkKKyAgICBsb2dfZmlsZSgiQVRUQUNLQlVTWSIsc3ByaW50ZigiJXMgJWQgVGFldGVyOiAlTyBPcGZlcjogJU9cbiIsCisgICAgICAgICAgICAgZHRpbWUodGltZSgpKSx0b19pbnQodmFsKSxwcmV2aW91c19vYmplY3QoMSksdGhpc19vYmplY3QoKSkpOworCisgIGF0dGFja19idXN5LT10b19pbnQodmFsKjEwMC4wKTsKKworICBpZiAoIGF0dGFja19idXN5PC0yMDAwICkKKyAgICBhdHRhY2tfYnVzeT0tMjAwMDsKKworICByZXR1cm4gYXR0YWNrX2J1c3k7Cit9CisKK3N0YXRpYyBpbnQgX3F1ZXJ5X2F0dGFja19idXN5KCkKK3sKKyAgaWYgKElTX0xFQVJOSU5HKE1FKSkKKyAgICByZXR1cm4gMDsKKworICByZXR1cm4gKGF0dGFja19idXN5PDEwMCk7Cit9CisKKy8vICoqKiogbG9jYWwgcHJvcGVydHkgbWV0aG9kcworc3RhdGljIGludCBfc2V0X3dpbXB5KGludCBpKQoreworICBpZiAoICFpbnRwKGkpIHx8IChpPlF1ZXJ5UHJvcChQX01BWF9IUCkpIHx8IChpPDApICkKKyAgICByZXR1cm4gMDsKKworICAvLyBnZ2YuIFN0YXR1c3JlcG9ydCBhdXNnZWJlbgorICBpZiAoaW50ZXJhY3RpdmUoTUUpKQorICAgIHN0YXR1c19yZXBvcnQoRE9fUkVQT1JUX1dJTVBZLCBpKTsKKworICByZXR1cm4gU2V0KFBfV0lNUFksIGkpOworfQorCitzdGF0aWMgc3RyaW5nIF9zZXRfd2ltcHlfZGlyKHN0cmluZyBzKSB7CisgIC8vIGdnZi4gU3RhdHVzcmVwb3J0IGF1c2dlYmVuCisgIGlmIChpbnRlcmFjdGl2ZShNRSkpCisgICAgc3RhdHVzX3JlcG9ydChET19SRVBPUlRfV0lNUFlfRElSLCBzKTsKKyAgcmV0dXJuIFNldChQX1dJTVBZX0RJUkVDVElPTiwgcywgRl9WQUxVRSk7Cit9CisKK3N0YXRpYyBtaXhlZCBfc2V0X2hhbmRzKG1peGVkIGgpCit7IAorICBpZiAoIHNpemVvZihoKT09MiApCisgICAgaCArPSAoeyAoe0RUX0JMVURHRU9OfSkgfSk7CisgIGlmICghcG9pbnRlcnAoaFsyXSkpCisgICAgaFsyXSA9ICh7aFsyXX0pOworICByZXR1cm4gU2V0KFBfSEFORFMsIGgsIEZfVkFMVUUpOworfQorCisvL1RPRE8gbm9ybWFsaXNpZXJlbi9rb3JyaWdpZXJlbiBpbiB1cGRhdGVzX2FmdGVyX3Jlc3RvcmUoKS4KK3N0YXRpYyBtaXhlZCBfcXVlcnlfaGFuZHMoKQoreworICBtaXhlZCAqaGFuZHMgPSBRdWVyeShQX0hBTkRTKTsKKyAgaWYgKCAhaGFuZHMgKQorICAgIHJldHVybiBTZXQoUF9IQU5EUywgKHsgIiBtaXQgYmxvc3NlbiBIYWVuZGVuIiwgMzAsICh7RFRfQkxVREdFT059KX0pKTsKKyAgZWxzZSBpZiAoIHNpemVvZihoYW5kcyk8MyApCisgICAgcmV0dXJuIFNldChQX0hBTkRTLCAoe2hhbmRzWzBdLCBoYW5kc1sxXSwgKHtEVF9CTFVER0VPTn0pfSkpOworICBlbHNlIGlmICggIXBvaW50ZXJwKGhhbmRzWzJdKSApCisgICAgcmV0dXJuIFNldChQX0hBTkRTLCAoe2hhbmRzWzBdLCBoYW5kc1sxXSwgKHsgaGFuZHNbMl0gfSl9KSk7CisKKyAgcmV0dXJuIFF1ZXJ5KFBfSEFORFMpOworfQorCitzdGF0aWMgaW50IF9xdWVyeV90b3RhbF93YygpCit7IG1peGVkIHJlczsKKyAgaW50ICAgdG90d2M7CisKKyAgaWYgKCBvYmplY3RwKHJlcz1RdWVyeVByb3AoUF9XRUFQT04pKSApCisgICAgdG90d2MgPSAoKGludCkocmVzLT5RdWVyeVByb3AoUF9XQykpKTsKKyAgZWxzZSBpZiAoIHBvaW50ZXJwKHJlcz1RdWVyeVByb3AoUF9IQU5EUykpICYmIHNpemVvZihyZXMpPjEKKyAgICAgICAgICAgJiYgaW50cChyZXNbMV0pICkKKyAgICB0b3R3Yz0oKGludClyZXNbMV0pOworICBlbHNlCisgICAgdG90d2M9MzA7CisKKyAgdG90d2MgPSAoKDIqdG90d2MpKygxMCpRdWVyeUF0dHJpYnV0ZShBX1NUUikpKS8zOworCisgIHJldHVybiBTZXQoUF9UT1RBTF9XQywgdG90d2MsIEZfVkFMVUUpOworfQorCitzdGF0aWMgaW50IF9xdWVyeV90b3RhbF9hYygpIHsKKworICBpbnQgdG90YWMgPSAwOworICBvYmplY3QgKmFybW91cnMgPSBRdWVyeVByb3AoUF9BUk1PVVJTKTsKKyAgb2JqZWN0IHBhcnJ5ID0gUXVlcnlQcm9wKFBfUEFSUllfV0VBUE9OKTsKKworICBpZiAoIG1lbWJlcihhcm1vdXJzLDApPj0wICkgeworICAgIGFybW91cnMgLT0gKHsgMCB9KTsgCisgIH0KKworICBmb3JlYWNoKG9iamVjdCBhcm1vdXI6IGFybW91cnMpCisgICAgdG90YWMgKz0gKChpbnQpYXJtb3VyLT5RdWVyeVByb3AoUF9BQykpOworCisgIGlmICggb2JqZWN0cChwYXJyeSkgKQorICAgIHRvdGFjICs9IHBhcnJ5LT5RdWVyeVByb3AoUF9BQyk7CisKKyAgdG90YWMgKz0gKFF1ZXJ5UHJvcChQX0JPRFkpK1F1ZXJ5QXR0cmlidXRlKEFfREVYKSk7CisKKyAgcmV0dXJuIFNldChQX1RPVEFMX0FDLCB0b3RhYywgRl9WQUxVRSk7Cit9CisKK3N0YXRpYyBtYXBwaW5nIF9xdWVyeV9yZXNpc3RhbmNlX3N0cmVuZ3RocygpIHsKKworICBVcGRhdGVSZXNpc3RhbmNlU3RyZW5ndGhzKCk7CisKKyAgbWFwcGluZyByc3RyZW4gPSBjb3B5KFF1ZXJ5KFBfUkVTSVNUQU5DRV9TVFJFTkdUSFMsIEZfVkFMVUUpKTsKKyAgbWFwcGluZyBtb2QgPSBRdWVyeShQX1JFU0lTVEFOQ0VfTU9ESUZJRVIsIEZfVkFMVUUpOworCisgIGlmICggIW1hcHBpbmdwKHJzdHJlbikgKQorICAgIHJzdHJlbiA9IChbXSk7CisKKyAgaWYgKCAhbWFwcGluZ3AobW9kKSB8fCAhbWFwcGluZ3AobW9kPW1vZFsibWUiXSkgfHwgIXNpemVvZihtb2QpICkKKyAgICByZXR1cm4gcnN0cmVuOworCisgIGZvcmVhY2goc3RyaW5nIG1vZGtleSwgZmxvYXQgbW9kdmFsdWUgOiBtb2QpCisgICAgcnN0cmVuW21vZGtleV0gPSAoKDEuMCtyc3RyZW5bbW9ka2V5XSkqKDEuMCttb2R2YWx1ZSkpLTEuMDsKKworICByZXR1cm4gcnN0cmVuOworfQorCitzdGF0aWMgaW50IF9zZXRfZGlzYWJsZV9hdHRhY2soaW50IHZhbCkKK3sKKyAgaWYgKHZhbDwtMTAwMDAwKQorICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICBsb2dfZmlsZSgiUEFSQUxZU0VfVE9PX0xPVyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIHNwcmludGYoIldlcnQgenUga2xlaW46ICVzLCBXZXJ0OiAlZCwgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBdWZydWZlcjogJU8sIE9wZmVyOiAlTyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3RpbWUodGltZSgpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbCxwcmV2aW91c19vYmplY3QoMSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzX29iamVjdCgpKSk7CisgICAgICAgICAgIH0KKyAgaWYgKCB2YWw+MzAgKQorICAgIHZhbD0zMDsKKyAgaWYgKCAodmFsPj0yMCkgJiYgcHJldmlvdXNfb2JqZWN0KDEpIT1NRSAmJiBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKE1FKSApCisgICAgbG9nX2ZpbGUoIlBBUkFMWVNFIixzcHJpbnRmKCIlcyAlZCBUYWV0ZXI6ICVPIE9wZmVyOiAlT1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3RpbWUodGltZSgpKVs0Li4xNV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbCxwcmV2aW91c19vYmplY3QoMSksdGhpc19vYmplY3QoKSkpOworIAorICBpZiAodGltZSgpPFF1ZXJ5UHJvcChQX05FWFRfRElTQUJMRV9BVFRBQ0spKQorICB7CisgICAgLy8gZ3VlbHRpZ2UgWmVpdHNwZXJyZSBleGlzdGllcnQuCisgICAgLy8gRXJob2VoZW4gdm9uIFBfRElTQUJMRV9BVFRBQ0sgZ2VodCBkYW5uIG5pY2h0LiAoSmEsIGF1Y2ggbmljaHQgZXJob2VoZW4KKyAgICAvLyBlaW5lcyBuZWdhdGl2ZW4gUF9ESVNBQkxFX0FUVEFDSykKKyAgICBpZiAodmFsID49IFF1ZXJ5UHJvcChQX0RJU0FCTEVfQVRUQUNLKSkKKyAgICAgIHJldHVybiBESVNBQkxFX1RPT19FQVJMWTsKKyAgICAvLyB2YWwgaXN0IGtsZWluZXIgYWxzIGFrdHVlbGxlcyBQX0RJU0FCTEVfQVRUQUNLIC0gZGFzIGlzdCBlcmxhdWJ0LCBBQkVSIGVzCisgICAgLy8gZGFyZiBkaWUgYmVzdGVoZW5kZSBaZWl0c3BlcnJlIG5pY2h0IHZlcnJpbmdlcm4sIGRhaGVyIHdpcmQgc2llIG5pY2h0CisgICAgLy8gZ2VhZW5kZXJ0LgorICAgIHJldHVybiBTZXQoUF9ESVNBQkxFX0FUVEFDSyx2YWwsRl9WQUxVRSk7CisgIH0KKyAgLy8gZXMgZXhpc3RpZXJ0IGtlaW5lIGd1ZWx0aWdlIFplaXRzcGVycmUgLSBkYW5uIHdpcmQgc2llIG51biBnZXNldHp0LgorICAvLyAoU29sbHRlIHZhbCA8IDAgc2Vpbiwgd2lyZCBlaW5lIFplaXRzcGVycmUgaW4gZGVyIFZlcmdhbmdlbmhlaXQgZ2VzZXR6dCwKKyAgLy8gZGllIHNjaG9uIGFiZ2VsYXVmZW4gaXN0LiBEYXMgaXN0IHVlYmVyZmx1ZXNzaWcsIHNjaGFkZXQgYWJlciBhdWNoCisgIC8vIG5pY2h0LikKKyAgU2V0UHJvcChQX05FWFRfRElTQUJMRV9BVFRBQ0ssdGltZSgpK3ZhbCoyKl9fSEVBUlRfQkVBVF9JTlRFUlZBTF9fKTsKKyAgcmV0dXJuIFNldChQX0RJU0FCTEVfQVRUQUNLLHZhbCk7Cit9CisKKy8vIE5ldWUgVmVyd2FsdHVuZyBkZXIgSGFlbmRlOgorCisvLyBQX0hBTkRTX1VTRURfQlkgZW5oYWVsdCBlaW4gQXJyYXkgbWl0IGFsbGVuIE9iamVrdGVuLCBkaWUgSGFlbmRlCisvLyBiZWxlZ2VuLCBqZWRlcyBrb21tdCBzbyBvZnQgdm9yIHdpZSBIYWVuZGUgYmVsZWd0IHdlcmRlbi4KKworc3RhdGljIG1peGVkICpfcXVlcnlfaGFuZHNfdXNlZF9ieSgpCit7CisgIHJldHVybiAoKFF1ZXJ5KFBfSEFORFNfVVNFRF9CWSwgRl9WQUxVRSkgfHwgKHt9KSApIC0gKHswfSkpOworfQorCitzdGF0aWMgaW50IF9xdWVyeV91c2VkX2hhbmRzKCkKK3sKKyAgcmV0dXJuIHNpemVvZihRdWVyeVByb3AoUF9IQU5EU19VU0VEX0JZKSk7Cit9CisKK3N0YXRpYyBpbnQgX3F1ZXJ5X2ZyZWVfaGFuZHMoKQoreworICByZXR1cm4gKFF1ZXJ5UHJvcChQX01BWF9IQU5EUyktUXVlcnlQcm9wKFBfVVNFRF9IQU5EUykpOworfQorCitwdWJsaWMgdmFyYXJncyBpbnQgVXNlSGFuZHMob2JqZWN0IG9iLCBpbnQgbnVtKQoreyBtaXhlZCAqaDsKKworICBpZiAoICFvYiAmJiAhKG9iPXByZXZpb3VzX29iamVjdCgxKSkgKQorICAgIHJldHVybiAwOworCisgIGlmICggKG51bTw9MCkgJiYgKChudW09b2ItPlF1ZXJ5UHJvcChQX0hBTkRTKSk8PTApICkKKyAgICByZXR1cm4gMDsKKworICBoPVF1ZXJ5UHJvcChQX0hBTkRTX1VTRURfQlkpLSh7b2J9KTsKKworICBpZiAoIChzaXplb2YoaCkrbnVtKT5RdWVyeVByb3AoUF9NQVhfSEFORFMpICkKKyAgICByZXR1cm4gMDsKKworICBmb3JlYWNoKGludCBpOiBudW0pCisgICAgaCs9KHtvYn0pOworCisgIFNldFByb3AoUF9IQU5EU19VU0VEX0JZLGgpOworCisgIHJldHVybiAxOworfQorCitwdWJsaWMgdmFyYXJncyBpbnQgRnJlZUhhbmRzKG9iamVjdCBvYikKK3sKKyAgaWYgKCAhb2IgJiYgIShvYj1wcmV2aW91c19vYmplY3QoMSkpICkKKyAgICByZXR1cm4gMDsKKworICBTZXRQcm9wKFBfSEFORFNfVVNFRF9CWSxRdWVyeVByb3AoUF9IQU5EU19VU0VEX0JZKS0oe29ifSkpOworCisgIHJldHVybiAxOworfQorCisvLyBLb21wYXRpYmxpdGFldHNmdW5rdGlvbmVuOgorCitzdGF0aWMgaW50IF9zZXRfdXNlZF9oYW5kcyhpbnQgbmV3X251bSkKK3sgaW50ICAgIG9sZF9udW0sIGRpZjsKKyAgb2JqZWN0IG9iOworCisgIG9sZF9udW09UXVlcnlQcm9wKFBfVVNFRF9IQU5EUyk7CisKKyAgaWYgKCAhb2JqZWN0cChvYj1wcmV2aW91c19vYmplY3QoMSkpICkKKyAgICByZXR1cm4gb2xkX251bTsKKworICAvLyBNZWxkdW5nIGlucyBEZWJ1Z2xvZyBzY2hyZWliZW4uIEF1ZnJ1ZmVyIHNvbGx0ZSBnZWZpeHQgd2VyZGVuLgorICBkZWJ1Z19tZXNzYWdlKHNwcmludGYoIlBfVVNFRF9IQU5EUyBpbiAlTyB3aXJkIGdlc2V0enQgZHVyY2ggJU9cbiIsCisgICAgICAgIHRoaXNfb2JqZWN0KCksIG9iKSwgRE1TR19MT0dGSUxFfERNU0dfU1RBTVApOworCisgIGlmICggIShkaWY9bmV3X251bS1vbGRfbnVtKSApCisgICAgcmV0dXJuIG5ld19udW07CisKKyAgaWYgKCBkaWY+MCApCisgICAgVXNlSGFuZHMob2IsZGlmKTsKKyAgZWxzZQorICAgIEZyZWVIYW5kcyhvYik7CisKKyAgcmV0dXJuIFF1ZXJ5UHJvcChQX1VTRURfSEFORFMpOworfQorCisvLyBGdW5rdGlvbmVuIGZ1ZXIgQmVncnVlc3N1bmdzc2NobGFnIC8gTmFja2Vuc2NobGFnOgorCitwdWJsaWMgaW50IENoZWNrRW5lbXkob2JqZWN0IG9iKQoreworICByZXR1cm4gKGxpdmluZyhvYikgJiYgSXNFbmVteShvYikpOworfQorCitwdWJsaWMgdmFyYXJncyB2b2lkIEV4ZWN1dGVNaXNzaW5nQXR0YWNrcyhvYmplY3QgKnJlbW92ZV9hdHRhY2tlcnMpCit7CisgIGlmICggIXBvaW50ZXJwKG1pc3NpbmdfYXR0YWNrcykgKQorICAgIG1pc3NpbmdfYXR0YWNrcz0oe30pOworCisgIGlmICggcG9pbnRlcnAocmVtb3ZlX2F0dGFja2VycykgKQorICAgIG1pc3NpbmdfYXR0YWNrcy09cmVtb3ZlX2F0dGFja2VyczsKKworICBmb3JlYWNoKG9iamVjdCBvYiA6IG1pc3NpbmdfYXR0YWNrcykgeworICAgIGlmICggb2JqZWN0cChvYikgJiYgKGVudmlyb25tZW50KG9iKT09ZW52aXJvbm1lbnQoKSkgKQorICAgICAgb2ItPkF0dGFjazIoTUUpOworICB9CisgIG1pc3NpbmdfYXR0YWNrcz0oe30pOworfQorCitwdWJsaWMgdm9pZCBJbml0QXR0YWNrKCkKK3sgb2JqZWN0IG9iLG5leHQ7CisgIGNsb3N1cmUgY2I7CisKKyAgaWYgKCAhbGl2aW5nKE1FKSApCisgICAgcmV0dXJuOworCisgIEV4ZWN1dGVNaXNzaW5nQXR0YWNrcygpOworICAvL0VNQSBrYW5uIGRhcyBMaXZpbmcgemVyc3RvZXJlbiBvZGVyIHRvZXRlbi4uLgorICBpZiAoIWxpdmluZyhNRSkgfHwgUXVlcnlQcm9wKFBfR0hPU1QpKSByZXR1cm47CisKKyAgaWYgKCBvYmplY3RwKG9iPUlzVGVhbU1vdmUoKSkgKQorICAgIGNiPXN5bWJvbF9mdW5jdGlvbigiSW5pdEF0dGFja19DYWxsYmFjayIsb2IpOworICBlbHNlCisgICAgY2I9MDsKKworICBmb3IgKCBvYj1maXJzdF9pbnZlbnRvcnkoZW52aXJvbm1lbnQoKSkgOyBvYmplY3RwKG9iKSA7IG9iPW5leHQpCisgIHsKKyAgICBuZXh0PW5leHRfaW52ZW50b3J5KG9iKTsKKworICAgIGlmICggIWxpdmluZyhvYikgKQorICAgICAgY29udGludWU7CisKKyAgICBpZiAob2ItPklzRW5lbXkoTUUpKQorICAgIHsKKyAgICAgIC8vIERhcyBpc3QgbmljaHQgc28gc2lubmxvcyB3aWUgZXMgYXVzc2llaHQuIGEpIHdlcmRlbiBkaWUgSHVudHRpbWVzCisgICAgICAvLyBha3R1YWxpc2llcnQgdW5kIGIpIHdlcmRlbiBUZWFtbWl0Z2xpZWRlciB2b24gbWlyIGJlaSBkaWVzZW0KKyAgICAgIC8vIEluc2VydEVuZW15KCkgZ2dmLiBlcmZhc3N0LgorICAgICAgb2ItPkluc2VydEVuZW15KE1FKTsKKworICAgICAgaWYgKCBjbG9zdXJlcChjYikgJiYgZnVuY2FsbChjYixvYikgKSAvLyBXaXJkIGdhbnplcyBUZWFtIGdlbW92ZWQ/CisgICAgICAgIG1pc3NpbmdfYXR0YWNrcyArPSAoeyBvYiB9KTsgLy8gRGFubiBlcnN0bWFsIHdhcnRlbiBiaXMgYWxsZSBkYSBzaW5kCisgICAgICBlbHNlCisgICAgICAgIG9iLT5BdHRhY2syKE1FKTsKKworICAgIH0KKyAgICBlbHNlIGlmICggSXNFbmVteShvYikgKQorICAgIHsKKyAgICAgIC8vIERhcyBpc3QgbmljaHQgc28gc2lubmxvcyB3aWUgZXMgYXVzc2llaHQuIGEpIHdlcmRlbiBkaWUgSHVudHRpbWVzCisgICAgICAvLyBha3R1YWxpc2llcnQgdW5kIGIpIHdlcmRlbiBUZWFtbWl0Z2xpZWRlciB2b24gb2IgYmVpIGRpZXNlbSAKKyAgICAgIC8vIEluc2VydEVuZW15KCkgZ2dmLiBlcmZhc3N0LgorICAgICAgSW5zZXJ0RW5lbXkob2IpOworICAgICAgQXR0YWNrMihvYik7CisgICAgfQorICAgIC8vQXR0YWNrMiBrYW5uIGRpZXNlcyBPYmpla3QgemVyc3RvZXJlbiBvZGVyIHRvZXRlbi4gV2VubiBqYTogYWJicnVjaAorICAgIGlmICggIWxpdmluZyhNRSkgfHwgUXVlcnlQcm9wKFBfR0hPU1QpKSBicmVhazsKKyAgfQorfQorCitwdWJsaWMgdm9pZCBFeGl0QXR0YWNrKCkKK3sKKyAgaWYgKCAhbGl2aW5nKE1FKSApCisgICAgcmV0dXJuOworCisgIC8vIE5vY2ggbmFjaHp1aG9sZW5kZSBCZWdydWVzc3VuZ3NzY2hsYWVnZToKKyAgRXhlY3V0ZU1pc3NpbmdBdHRhY2tzKCk7Cit9CisKK3B1YmxpYyBvYmplY3R8b2JqZWN0KnxtYXBwaW5nIFF1ZXJ5QXJtb3VyQnlUeXBlKHN0cmluZyB0eXBlKQoreworICAvLyBSdWVja2dhYmV3ZXJ0OgorICAvLyBESUUgUnVlc3R1bmcgdm9tIFR5cCA8dHlwZT4sIGZhbGxzIDx0eXBlPiBuaWNodCBBVF9NSVNDLAorICAvLyBBcnJheSBhbGxlciBBVF9NSVNDLVJ1ZXN0dW5nZW4gZmFsbHMgPHR5cGU+IEFUX01JU0MgKGF1Y2ggbGVlciksCisgIC8vIE1hcHBpbmcgbWl0IGFsbGVuIG9iZW4gZ2VuYW5udGVuIEluZm9zLCBmYWxscyA8dHlwZT4gTnVsbAorCisgIG9iamVjdCAqYXJtb3VyczsKKyAgc3RyaW5nIHR5cDI7CisKKyAgLy8gV2VubiBDYWNoZSB2b3JoYW5kZW4sIGRhbm4gQ2FjaGUgbGllZmVybi4KKyAgaWYgKG1hcHBpbmdwKFFBQlRDYWNoZSkpIHsKKyAgICBpZiAodHlwZSA9PSBBVF9NSVNDKQorICAgICAgcmV0dXJuIFFBQlRDYWNoZVtBVF9NSVNDXSAtICh7MH0pOworICAgIGVsc2UgaWYgKHR5cGUpCisgICAgICByZXR1cm4gUUFCVENhY2hlW3R5cGVdOworICAgIGVsc2UKKyAgICAgIHJldHVybiBjb3B5KFFBQlRDYWNoZSk7CisgIH0KKworICBpZiAoICFwb2ludGVycChhcm1vdXJzPVF1ZXJ5UHJvcChQX0FSTU9VUlMpKSApCisgICAgYXJtb3Vycz0oe30pOworCisgIC8vIENhY2hlIGVyemV1Z2VuCisgIFFBQlRDYWNoZSA9IChbIEFUX01JU0M6ICh7fSkgXSk7CisgIGZvcmVhY2gob2JqZWN0IG9iOiBhcm1vdXJzIC0gKHswfSkgKSB7CisgICAgaWYgKCAhc3RyaW5ncCh0eXAyPW9iLT5RdWVyeVByb3AoUF9BUk1PVVJfVFlQRSkpICkKKyAgICAgIGNvbnRpbnVlOworICAgIGlmICggdHlwMj09QVRfTUlTQyApCisgICAgICBRQUJUQ2FjaGVbQVRfTUlTQ10gKz0gKHtvYn0pOworICAgIGVsc2UKKyAgICAgIFFBQlRDYWNoZVt0eXAyXSA9IG9iOworICB9CisgIC8vIFVuZCBnZXd1ZW5zY2h0ZXMgRGF0dW0gbGllZmVybi4KKyAgaWYgKHR5cGUpCisgICAgcmV0dXJuIFFBQlRDYWNoZVt0eXBlXTsKKyAgZWxzZQorICAgIHJldHVybiBjb3B5KFFBQlRDYWNoZSk7Cit9CisKKy8vVE9ETzogbGFuZ2ZyaXN0aWcgd2FlcnMgYmVzc2VyLCB3ZW5uIGhpZXIgbmljaHQgamVkZXIgcGVyIFNldFByb3AoKSBkcmF1ZgorLy9sb3Mgc2NocmVpYmVuIHd1ZXJkZS4KK3N0YXRpYyBvYmplY3QgKl9zZXRfYXJtb3VycyhvYmplY3QgKmFybW91cnMpIHsKKyAgaWYgKHBvaW50ZXJwKGFybW91cnMpKSB7CisgICAgLy8gQ2FjaGUgd2Vnd2VyZmVuCisgICAgUUFCVENhY2hlID0gMDsKKyAgICAvLyBhcm1vdXJzIGdnZi4gdW5pZml6aWVyZW4uIEF1c3NlcmRlbSBLb3BpZSByZWluc2NocmVpYmVuLgorICAgIHJldHVybiBTZXQoUF9BUk1PVVJTLCBtX2luZGljZXMobWttYXBwaW5nKGFybW91cnMpKSwgRl9WQUxVRSk7CisgIH0KKyAgcmV0dXJuIFF1ZXJ5UHJvcChQX0FSTU9VUlMpOworfQorCisvKiogUmVkdXppZXJ0IGRpZSBCZWZyaWVkZXphZWhsZXIgcHJvIFJlc2V0IGltIER1cmNoc2Nobml0dCB1bSAyLjUuCisgIEJlcmVjaG5ldCBnYW56emFobGlnZSBkdXJjaHNjaG5pdHRsaWNoZSBSZXNldHMgc2VpdCBkZW0gbGV0enRlbiBFeHBpcmUgdW5kCisgIGVyaG9laHQgZGllIGxldHp0ZSBFeHBpcmV6ZWl0IHVtIFJlc2V0cypfX1JFU0VUX1RJTUVfXyAoU3RhbmRhcmQgSW50ZXJ2YWxsCisgIGZ1ZXIgUmVzZXQgaXN0IG1vbWVudGFuIDM2MDBzLCBpbSBEdXJjaHNjaG5pdHQga29tbWVuIGRhbm4gMjcwMCB6d2lzY2hlbiAyCisgIFJlc2V0cyBiZWkgcmF1cykuIFNvIHdpcmQgZGVyIHVuZ2FuenphaGxpZ2UgUmVzdCBiZWltIG5hZWNoc3RlbiBBdWZydWYKKyAgYmVydWVja3NpY2h0aWd0LgorICBEaWVzZSBWYXJpYW50ZSBkZXMgRXhwaXJlcyB3dXJkZSBnZXdhZWhsdCwgdW0genUgdmVybWVpZGVuLCBjb21iYXQuYyBlaW5lbgorICByZXNldCgpIHp1IGdlYmVuIHVuZCBpbiBqZWRlbSBSZXNldCBpbiBqZWRlbSBMZWJld2VzZW4gZWluIEV4cGlyZSBtYWNoZW4genUKKyAgbXVlc3NlbiwgYXVjaCB3ZW5uIG51ciBpbiBzZWhyIHdlbmlnZW4gTGViZXdlc2VuIHdhcyBnZW1hY2h0IHdlcmRlbiBtdXNzLgorICBAcGFyYW1baW4sb3V0XSBwaCBNYXBwaW5nIGF1cyBQX1BFQUNFX0hJU1RPUlkuIFdpcmQgZGlyZWt0IGFrdHVhbGlzaWVydC4KKyAgQGF0dGVudGlvbiBNdXNzIGVpbiBndWVsdGlnZXMgUF9QRUFDRV9ISVNUT1JZIHVlYmVyZ2ViZW4gYmVrb21tZW4sIGFuZGVyZW0KKyAgRGF0ZW50eXAgaW5rbC4gMCB3aXJkIGRpZSBGdW5rdGlvbiBidWdnZW4uCisgICovCitwcml2YXRlIHZvaWQgX2RlY2F5X3BlYWNlX2hpc3RvcnkobWl4ZWQgcGgpIHsKKyAgLy8gR2FuenphaGxpZ2UgcmVzZXRzIHNlaXQgbGV0enRlbSBFeHBpcmUgZXJtaXR0ZWxuLiAoRHVyY2hzY2huaXR0KQorICBpbnQgcmVzZXRzID0gKHRpbWUoKSAtIHBoWzBdKSAvIChfX1JFU0VUX1RJTUVfXyo3NS8xMDApOworICAvLyBhdWYgWmVpdHN0ZW1wZWwgZHJhdWZyZWNobmVuLCBkYW1pdCBkZXIgdW5nYW56emFobGlnZSBSZXN0IG5pY2h0CisgIC8vIHZlcmxvcmVuZ2VodCwgZGVyIHdpcmQgYmVpbSBuYWVjaHN0ZW4gRXhwaXJlIGRhbm4gYmVydWVja3NpY2h0aWd0LgorICBwaFswXSArPSByZXNldHMgKiAoX19SRVNFVF9USU1FX18gKiA3NSAvIDEwMCk7CisgIC8vIHBybyBSZXNldCB3ZXJkZW4gaW0gRHVyY2hzY2huaXR0IDIuNSBWZXJzdWNoZSBhYmdlem9nZW4uIChIaWVyIHdlcmRlbgorICAvLyBiZWltIEV4cGlyZSBtYWwgMiB1bmQgbWFsIDMgVmVyc3VjaGUgcHJvIFJlc2V0IGdlcmVjaG5ldC4gQWJlciBmYWxscyBoaWVyCisgIC8vIHZpZWxlIFJlc2V0cyB2ZXJnYW5nZW4gc2luZCwgaXN0IGVzIHZlcm11dGxpY2ggZWggZWdhbCwgd2VpbCBkaWUgQ291bnRlcgorICAvLyBhdWYgMCBmYWxsZW4uKQorICBpbnQgZXhwaXJlID0gcmVzZXRzICogKHJhbmRvbSgyKSArIDIpOworICAvLyB1ZWJlciBhbGxlIEdpbGRlbgorICBtYXBwaW5nIHRtcD1waFsxXTsKKyAgZm9yZWFjaChzdHJpbmcga2V5LCBpbnQgY291bnQ6ICZ0bXAgKSB7CisgICAgY291bnQtPWV4cGlyZTsKKyAgICBpZiAoY291bnQgPCAwKSBjb3VudCA9IDA7CisgIH0KK30KKworLyoqIFBhY2lmeSgpIGRpZW50IHp1ciBCZXN0aW1tdW5nLCBvYiBzaWNoIGVpbiBMZWJld2VzZW4gZ2VyYWRlIAorICogYmVmcmllZGVuIGxhc3NlbiB3aWxsLgorICogQmVyZWNobmV0IGVpbmUgV2FocnNjaGVpbmxpY2hrZWl0IG5hY2ggdW50ZW4gc3RlaGVuZGVyIEZvcm1lbCwgd2VsY2hlIGRpZQorICogSW50ZWxsaWdlbnogZGllc2VzIExlYmVud2VzZW5zLCBkaWUgSW50ZWxsaWdlbnogZGVzIENhc3RlcnMgdW5kIGRpZQorICogYmlzaGVyaWdlIEFuemFobCBlcmZvbGdyZWljaGVyIEJlZnJpZWR1bmdzdmVyc3VjaGUgZGllc2VyIEdpbGRlIGVpbmdlaHQuCisgKiBBbnNjaGxpZXNzZW5kIHdpcmQgYXVzIGRlciBXYWhyc2NoZWlubGljaGtlaXQgdW5kIHJhbmRvbSgpIGJlc3RpbW10LCBvYgorICogZGllc2VyIFZlcnN1Y2ggZXJmb2xncmVpY2ggaXN0LgorRm9ybWVsOiB3ID0gKElOVF9DQVNURVIgKyAxMCAtIEFOWio0KSAvIChJTlRfTUUgKyAxMCkKK0lOVF9DQVNURVI6IENhc3Rlci1JbnRlbGxpZ2VueiwgSU5UX01FOiBJbnRlbGxpZ2VueiBkaWVzZXMgTGl2aW5ncworQU5aOiBBbnphaGwgZXJmb2xncmVpY2hlciBCZWZyaWVkdW5nc3ZlcnN1Y2hlCisKK0FubmFobWU6IElOVF9DQVNURVIgPT09IDIyLCBhbGxlIFdhaHJzY2hlaW5saWNoa2VpdGVuICogMTAwCisKK0lOVF9NRSAgIEVyZm9sZ3N3YWhyc2NoZWlubGljaGtlaXRlbiBqZSBuYWNoIEFuemFobCBlcmZvbGdyZWljaGVyIFZlcnN1Y2hlCisgICAgICAgICAgICAgIDEgICAgICAgMiAgICAgICAzICAgICAgIDQgICAgICAgNSAgICAgICA2ICAgICAgIDcgICAgICAgOAorICAgICAgMCAgICAgMjgwICAgICAyNDAgICAgIDIwMCAgICAgMTYwICAgICAxMjAgICAgICA4MCAgICAgIDQwICAgICAgIDAKKyAgICAgIDIgIDIzMywzMyAgICAgMjAwICAxNjYsNjcgIDEzMywzMyAgICAgMTAwICAgNjYsNjcgICAzMywzMyAgICAgICAwCisgICAgICA0ICAgICAyMDAgIDE3MSw0MyAgMTQyLDg2ICAxMTQsMjkgICA4NSw3MSAgIDU3LDE0ICAgMjgsNTcgICAgICAgMAorICAgICAgNiAgICAgMTc1ICAgICAxNTAgICAgIDEyNSAgICAgMTAwICAgICAgNzUgICAgICA1MCAgICAgIDI1ICAgICAgIDAKKyAgICAgIDggIDE1NSw1NiAgMTMzLDMzICAxMTEsMTEgICA4OCw4OSAgIDY2LDY3ICAgNDQsNDQgICAyMiwyMiAgICAgICAwCisgICAgIDEwICAgICAxNDAgICAgIDEyMCAgICAgMTAwICAgICAgODAgICAgICA2MCAgICAgIDQwICAgICAgMjAgICAgICAgMAorICAgICAxMiAgMTI3LDI3ICAxMDksMDkgICA5MCw5MSAgIDcyLDczICAgNTQsNTUgICAzNiwzNiAgIDE4LDE4ICAgICAgIDAKKyAgICAgMTQgIDExNiw2NyAgICAgMTAwICAgODMsMzMgICA2Niw2NyAgICAgIDUwICAgMzMsMzMgICAxNiw2NyAgICAgICAwCisgICAgIDE2ICAxMDcsNjkgICA5MiwzMSAgIDc2LDkyICAgNjEsNTQgICA0NiwxNSAgIDMwLDc3ICAgMTUsMzggICAgICAgMAorICAgICAxOCAgICAgMTAwICAgODUsNzEgICA3MSw0MyAgIDU3LDE0ICAgNDIsODYgICAyOCw1NyAgIDE0LDI5ICAgICAgIDAKKyAgICAgMjAgICA5MywzMyAgICAgIDgwICAgNjYsNjcgICA1MywzMyAgICAgIDQwICAgMjYsNjcgICAxMywzMyAgICAgICAwCisgICAgIDIyICAgIDg3LDUgICAgICA3NSAgICA2Miw1ICAgICAgNTAgICAgMzcsNSAgICAgIDI1ICAgIDEyLDUgICAgICAgMAorICAgICAyNCAgIDgyLDM1ICAgNzAsNTkgICA1OCw4MiAgIDQ3LDA2ICAgMzUsMjkgICAyMyw1MyAgIDExLDc2ICAgICAgIDAKKyAgICAgMjYgICA3Nyw3OCAgIDY2LDY3ICAgNTUsNTYgICA0NCw0NCAgIDMzLDMzICAgMjIsMjIgICAxMSwxMSAgICAgICAwCisgICAgIDI4ICAgNzMsNjggICA2MywxNiAgIDUyLDYzICAgNDIsMTEgICAzMSw1OCAgIDIxLDA1ICAgMTAsNTMgICAgICAgMAorICAgICAzMCAgICAgIDcwICAgICAgNjAgICAgICA1MCAgICAgIDQwICAgICAgMzAgICAgICAyMCAgICAgIDEwICAgICAgIDAKKyAgICAgMzIgICA2Niw2NyAgIDU3LDE0ICAgNDcsNjIgICAgMzgsMSAgIDI4LDU3ICAgMTksMDUgICAgOSw1MiAgICAgICAwCisgICAgIDM0ICAgNjMsNjQgICA1NCw1NSAgIDQ1LDQ1ICAgMzYsMzYgICAyNywyNyAgIDE4LDE4ICAgIDksMDkgICAgICAgMAorICAgICAzNSAgIDYyLDIyICAgNTMsMzMgICA0NCw0NCAgIDM1LDU2ICAgMjYsNjcgICAxNyw3OCAgICA4LDg5ICAgICAgIDAKKyAgICAgMzYgICA2MCw4NyAgIDUyLDE3ICAgNDMsNDggICAzNCw3OCAgIDI2LDA5ICAgMTcsMzkgICAgIDgsNyAgICAgICAwCisgICAgIDM4ICAgNTgsMzMgICAgICA1MCAgIDQxLDY3ICAgMzMsMzMgICAgICAyNSAgIDE2LDY3ICAgIDgsMzMgICAgICAgMAorICAgICA0MCAgICAgIDU2ICAgICAgNDggICAgICA0MCAgICAgIDMyICAgICAgMjQgICAgICAxNiAgICAgICA4ICAgICAgIDAKKyAgICAgNDIgICA1Myw4NSAgIDQ2LDE1ICAgMzgsNDYgICAzMCw3NyAgIDIzLDA4ICAgMTUsMzggICAgNyw2OSAgICAgICAwCisgICAgIDQ0ICAgNTEsODUgICA0NCw0NCAgIDM3LDA0ICAgMjksNjMgICAyMiwyMiAgIDE0LDgxICAgIDcsNDEgICAgICAgMAorICAgICA0NiAgICAgIDUwICAgNDIsODYgICAzNSw3MSAgIDI4LDU3ICAgMjEsNDMgICAxNCwyOSAgICA3LDE0ICAgICAgIDAKKyAgICAgNDggICA0OCwyOCAgIDQxLDM4ICAgMzQsNDggICAyNyw1OSAgIDIwLDY5ICAgMTMsNzkgICAgIDYsOSAgICAgICAwCisgICAgIDUwICAgNDYsNjcgICAgICA0MCAgIDMzLDMzICAgMjYsNjcgICAgICAyMCAgIDEzLDMzICAgIDYsNjcgICAgICAgMAorICAgICA1MiAgIDQ1LDE2ICAgMzgsNzEgICAzMiwyNiAgIDI1LDgxICAgMTksMzUgICAgMTIsOSAgICA2LDQ1ICAgICAgIDAKKyAgICAgNTQgICA0Myw3NSAgICAzNyw1ICAgMzEsMjUgICAgICAyNSAgIDE4LDc1ICAgIDEyLDUgICAgNiwyNSAgICAgICAwCisgICAgIDU2ICAgNDIsNDIgICAzNiwzNiAgICAzMCwzICAgMjQsMjQgICAxOCwxOCAgIDEyLDEyICAgIDYsMDYgICAgICAgMAorICAgICA1OCAgIDQxLDE4ICAgMzUsMjkgICAyOSw0MSAgIDIzLDUzICAgMTcsNjUgICAxMSw3NiAgICA1LDg4ICAgICAgIDAKKyAgICAgNjAgICAgICA0MCAgIDM0LDI5ICAgMjgsNTcgICAyMiw4NiAgIDE3LDE0ICAgMTEsNDMgICAgNSw3MSAgICAgICAwCisgICAgIDYyICAgMzgsODkgICAzMywzMyAgIDI3LDc4ICAgMjIsMjIgICAxNiw2NyAgIDExLDExICAgIDUsNTYgICAgICAgMAorICAgICA2NCAgIDM3LDg0ICAgMzIsNDMgICAyNywwMyAgIDIxLDYyICAgMTYsMjIgICAxMCw4MSAgICA1LDQxICAgICAgIDAKKyAgICAgNjYgICAzNiw4NCAgIDMxLDU4ICAgMjYsMzIgICAyMSwwNSAgIDE1LDc5ICAgMTAsNTMgICAgNSwyNiAgICAgICAwCisgICAgIDY4ICAgIDM1LDkgICAzMCw3NyAgIDI1LDY0ICAgMjAsNTEgICAxNSwzOCAgIDEwLDI2ICAgIDUsMTMgICAgICAgMAorICAgICA3MCAgICAgIDM1ICAgICAgMzAgICAgICAyNSAgICAgIDIwICAgICAgMTUgICAgICAxMCAgICAgICA1ICAgICAgIDAKKyAgICAgNzIgICAzNCwxNSAgIDI5LDI3ICAgMjQsMzkgICAxOSw1MSAgIDE0LDYzICAgIDksNzYgICAgNCw4OCAgICAgICAwCisgICAgIDc0ICAgMzMsMzMgICAyOCw1NyAgIDIzLDgxICAgMTksMDUgICAxNCwyOSAgICA5LDUyICAgIDQsNzYgICAgICAgMAorICAgICA3NiAgIDMyLDU2ICAgMjcsOTEgICAyMywyNiAgICAxOCw2ICAgMTMsOTUgICAgIDksMyAgICA0LDY1ICAgICAgIDAKKyAgICAgNzggICAzMSw4MiAgIDI3LDI3ICAgMjIsNzMgICAxOCwxOCAgIDEzLDY0ICAgIDksMDkgICAgNCw1NSAgICAgICAwCisgICAgIDgwICAgMzEsMTEgICAyNiw2NyAgIDIyLDIyICAgMTcsNzggICAxMywzMyAgICA4LDg5ICAgIDQsNDQgICAgICAgMAorICAgICA4MiAgIDMwLDQzICAgMjYsMDkgICAyMSw3NCAgIDE3LDM5ICAgMTMsMDQgICAgIDgsNyAgICA0LDM1ICAgICAgIDAKKyAgICAgODQgICAyOSw3OSAgIDI1LDUzICAgMjEsMjggICAxNywwMiAgIDEyLDc3ICAgIDgsNTEgICAgNCwyNiAgICAgICAwCisgICAgIDg2ICAgMjksMTcgICAgICAyNSAgIDIwLDgzICAgMTYsNjcgICAgMTIsNSAgICA4LDMzICAgIDQsMTcgICAgICAgMAorICAgICA4OCAgIDI4LDU3ICAgMjQsNDkgICAyMCw0MSAgIDE2LDMzICAgMTIsMjQgICAgOCwxNiAgICA0LDA4ICAgICAgIDAKKyAgICAgOTAgICAgICAyOCAgICAgIDI0ICAgICAgMjAgICAgICAxNiAgICAgIDEyICAgICAgIDggICAgICAgNCAgICAgICAwCisgICAgIDkyICAgMjcsNDUgICAyMyw1MyAgIDE5LDYxICAgMTUsNjkgICAxMSw3NiAgICA3LDg0ICAgIDMsOTIgICAgICAgMAorICAgICA5NCAgIDI2LDkyICAgMjMsMDggICAxOSwyMyAgIDE1LDM4ICAgMTEsNTQgICAgNyw2OSAgICAzLDg1ICAgICAgIDAKKyAgICAgOTYgICAyNiw0MiAgIDIyLDY0ICAgMTgsODcgICAxNSwwOSAgIDExLDMyICAgIDcsNTUgICAgMyw3NyAgICAgICAwCisgICAgIDk4ICAgMjUsOTMgICAyMiwyMiAgIDE4LDUyICAgMTQsODEgICAxMSwxMSAgICA3LDQxICAgICAzLDcgICAgICAgMAorICAgIDEwMCAgIDI1LDQ1ICAgMjEsODIgICAxOCwxOCAgIDE0LDU1ICAgMTAsOTEgICAgNywyNyAgICAzLDY0ICAgICAgIDAKKyAqIEByZXR1cm4gMSwgZmFsbHMgQmVmcmllZGVuIGVybGF1YnQgaXN0LCAwIHNvbnN0LgorICogQHBhcmFtW2luXSBjYXN0ZXIgRGVyamVuaWdlLCBkZXIgZGVuIFNwcnVjaCBhdXNmdWVocnQuCisgKiBAYXR0ZW50aW9uIFdlbm4gYWNpZnkoKSAxIHp1cnVlY2tsaWVmZXJ0LCB6YWVobHQgZGllcyBhbHMKKyAqIGVyZm9sZ3JlaWNoZXIgQmVmcmllZHVuZ3N2ZXJzdWNoIHVuZCBpbiBkaWVzZW0gTGViZXdlc2VuIHd1cmRlCisgKiBTdG9wSHVudGluZ01vZGUoMSkgYXVmZ2VydWZlbi4KKyovCitwdWJsaWMgaW50IFBhY2lmeShvYmplY3QgY2FzdGVyKSB7CisgIAorICAvLyB3ZW5uIGRhcyBWaWVjaCBrZWluZSBHZWduZXIgaGF0LCBkYW5uIHdpdHpsb3MuIDstKSBPaG5lIENhc3RlciBnZWh0cyBhdWNoCisgIC8vIGRpcmVrdCByYXVzLgorICBpZiAoIW1hcHBpbmdwKGVuZW1pZXMpIHx8ICFzaXplb2YoZW5lbWllcykKKyAgICAgIHx8ICFvYmplY3RwKGNhc3RlcikpIHsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIC8vIFdlbm4gUF9BQ0NFUFRfUEVBQ0UgZ2VzZXR6dCBpc3QsIGFsdGVzIFZlcmhhbHRlbiB3aWVkZXJzcGllZ2VsbgorICAvLyAtPiBkZXIgTlBDIGlzdCBlaW5mYWNoIGltbWVyIGJlZnJpZWRiYXIuIEdsZWljaGVzIGdpbHQgZnVlciBkZW4gQ2FzdGVyCisgIC8vIHNlbGJlciwgZGVyIHdpcmQgc2ljaCBqYSBuaWNodCBnZWdlbiBkYXMgZWlnZW5lIEJlZnJpZWRlIHdlaHJlbi4gVW5kIGF1Y2gKKyAgLy8gaW0gdGVhbSB3ZWhydCBtYW4gc2ljaCBuaWNodCBnZWdlbiBkYXMgQmVmcmllZGUgZWluZXMgVGVhbWtvbGxlZ2VuCisgIGlmIChRdWVyeVByb3AoUF9BQ0NFUFRfUEVBQ0UpPT0xIHx8IGNhc3Rlcj09TUUKKyAgICAgIHx8IG1lbWJlcihUZWFtTWVtYmVycygpLCBjYXN0ZXIpID4gLTEpIHsKKyAgICBTdG9wSHVudGluZ01vZGUoMSk7IC8vIENhc3Rlci9HaWxkZSBzb2xsdGUgZWlnZW5lIE1lbGR1bmcgYXVzZ2ViZW4KKyAgICByZXR1cm4gMTsKKyAgfQorCisgIHN0cmluZyBnaWxkZSA9IGNhc3Rlci0+UXVlcnlQcm9wKFBfR1VJTEQpIHx8ICJBTlkiOworCisgIC8vIGdnZi4gUF9QRUFDRV9ISVNUT1JZIGluaXRpYWxpc2llcmVuCisgIG1peGVkIHBoID0gKG1peGVkKVF1ZXJ5UHJvcChQX1BFQUNFX0hJU1RPUlkpOworICBpZiAoIXBvaW50ZXJwKHBoKSkKKyAgICBTZXRQcm9wKFBfUEVBQ0VfSElTVE9SWSwgcGg9KHt0aW1lKCksIChbXSkgfSkgKTsKKyAgCisgIC8vIGdnZi4gZGllIFphZWhsZXIgcmVkdXppZXJlbi4KKyAgaWYgKCBwaFswXSArIF9fUkVTRVRfVElNRV9fICogNzUvMTAwIDwgdGltZSgpKSB7CisgICAgX2RlY2F5X3BlYWNlX2hpc3RvcnkoJnBoKTsKKyAgfQorICAKKyAgZmxvYXQgdyA9IChjYXN0ZXItPlF1ZXJ5QXR0cmlidXRlKEFfSU5UKSArIDEwIC0gcGhbMV1bZ2lsZGVdICogNC4wKSAvIAorICAgICAgICAgICAgIChRdWVyeUF0dHJpYnV0ZShBX0lOVCkgKyAxMCk7CisgIC8vIGF1ZiBbMCwxXSBiZWdyZW56ZW4uCisgIGlmICh3PDApIHc9MC4wOworICBlbHNlIGlmICh3PjEpIHc9MS4wOworICAvLyB3ICogbiBpc3QgZWluZSBaYWhsIHp3aXNjaGVuIDAgdW5kIG4sIHdlbm4gdyAqIG4gPiByYW5kb20obikrMSwKKyAgLy8gZGFyZiBiZWZyaWVkZXQgd2VyZGVuLiBEYSBkYXMgUmFuZG9tIGZ1ZXIgZ3Jvc3NlIFphaGxlbgorICAvLyBiZXNzZXIgdmVydGVpbHQgaXN0LCBuZWhtIGljaCBuID0gX19JTlRfTUFYX18gdW5kIHZlcm5hY2hsYWVzc2lnZQorICAvLyBhdXNzZXJkZW0gZGllICsxIGJlaW0gcmFuZG9tKCkuCisgIGlmIChjZWlsKHcgKiBfX0lOVF9NQVhfXykgPiByYW5kb20oX19JTlRfTUFYX18pICkgeworICAgIHBoWzFdW2dpbGRlXSsrOworICAgIFN0b3BIdW50aW5nTW9kZSgxKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICAvLyBlaW4gU2V0UHJvcChQX1BFQUNFX0hJU1RPUlkpIGthbm4gZW50ZmFsbGVuLCBkYSBkYXMgTWFwcGluZyBkaXJla3QKKyAgLy8gZ2VhZW5kZXJ0IHdpcmQuIFNvbGx0ZSBkaWUgUHJvcCBhbGxlcmRpbmdzIG1hbCBuZSBRdWVyeW1ldGhvZGUgaGFiZW4sCisgIC8vIHdlbGNoZSBlaW5lIEtvcGllIGRhdm9uIGxpZWZlcnQsIG11c3MgZGFzIGhpZXIgZ2VhZW5kZXJ0IG9kZXIgZGllCisgIC8vIFByb3AgcGVyIFF1ZXJ5KCkgYWJnZWZyYWd0IHdlcmRlbi4KKyAgcmV0dXJuIDA7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9saXZpbmcvY29tbS5jIGIvc3RkL2xpdmluZy9jb21tLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjAwMWZmZAotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9saXZpbmcvY29tbS5jCkBAIC0wLDAgKzEsMTMzIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gbGl2aW5nL2NvbW0uYyAtLSBjb21tdW5pY3Rpb24gbW9kdWxlIGZvciBsaXZpbmdzCisvLworLy8gJElkJAorCisjcHJhZ21hIHN0cm9uZ190eXBlcyxzYXZlX3R5cGVzCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisjcHJhZ21hIHJhbmdlX2NoZWNrCisKKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8bGl2aW5nL2NvbW0uaD4KKwordm9pZCBjcmVhdGVfc3VwZXIoKQoreworICBzZXRfbmV4dF9yZXNldCgtMSk7Cit9CisKK3Byb3RlY3RlZCBzdHJpbmcgY29tbV9ndWVzc19hY3Rpb24oKSB7CisgIHN0cmluZyBjbWQ7CisgIHN0cmluZyBhY3Rpb24gPSBxdWVyeV92ZXJiKCk7CisgIC8vIERpZSBBa3Rpb25lbiBzaW5kIGludGVybiBpbiBkZXIgUmVnZWwgbmFjaCBkZW4gaGFldWZpZ3N0ZW4gS29tbWFuZG92ZXJiZW4KKyAgLy8gZGllc2VyIEFrdGlvbiBiZW5hbm50LiBCZWkgZWluaWdlbiBBa3Rpb25lbiBzaW5kIG1laHJlcmUgS29tbWFuZG92ZXJiZW4KKyAgLy8gdWVibGljaCwgZGllIHNvbGxlbiBoaWVyIG5vY2ggYWJnZWhhbmRlbHQgd2VyZGVuLgorICBzd2l0Y2goYWN0aW9uKSB7CisgICAgY2FzZSAibmVobWUiOgorICAgICAgLy8gTUFfVEFLRSA9PSBuaW1tCisgICAgICBhY3Rpb24gPSBNQV9UQUtFOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlICJub3JkZW4iOgorICAgIGNhc2UgIm5vcmRvc3RlbiI6CisgICAgY2FzZSAib3N0ZW4iOgorICAgIGNhc2UgInN1ZWRvc3RlbiI6CisgICAgY2FzZSAic3VlZGVuIjoKKyAgICBjYXNlICJzdWVkd2VzdGVuIjoKKyAgICBjYXNlICJ3ZXN0ZW4iOgorICAgIGNhc2UgIm5vcmR3ZXN0ZW4iOgorICAgIGNhc2UgIm9iZW4iOgorICAgIGNhc2UgInVudGVuIjoKKyAgICBjYXNlICJiZXRyZXRlIjoKKyAgICBjYXNlICJ2ZXJsYXNzZSI6CisgICAgY2FzZSAidGVsZXBvcnQiOgorICAgIGNhc2UgInRlbGVwb3J0aWVyZSI6CisgICAgICBhY3Rpb24gPSBNQV9NT1ZFOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlICJ1bnQiOgorICAgICAgYWN0aW9uID0gTUFfTE9PSzsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSAid2lyZiI6CisgICAgICBpZiAoc3Ryc3RyKHF1ZXJ5X2NvbW1hbmQoKSwgIiB3ZWciKSA+IC0xKQorICAgICAgICBhY3Rpb24gPSBNQV9QVVQ7CisgICAgICBicmVhazsKKworICAgIGNhc2UgInN0ZWNrZSI6CisgICAgICBjbWQgPSBxdWVyeV9jb21tYW5kKCk7CisgICAgICBpZiAoc3Ryc3RyKGNtZCwgIiB3ZWciKSA+IC0xKQorICAgICAgICBhY3Rpb24gPSBNQV9VTldJRUxEOworICAgICAgZWxzZSBpZiAoc3Ryc3RyKGNtZCwiIGluICIpID4gLTEpCisgICAgICAgIGFjdGlvbiA9IE1BX1BVVDsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSAiemllaGUiOgorICAgICAgY21kID0gcXVlcnlfY29tbWFuZCgpOworICAgICAgaWYgKHN0cnN0cihjbWQsICIgYW4iKSA+IC0xKQorICAgICAgICBhY3Rpb24gPSBNQV9XRUFSOworICAgICAgZWxzZSBpZiAoc3Ryc3RyKGNtZCwgIiBhdXMiKSA+IC0xKQorICAgICAgICBhY3Rpb24gPSBNQV9VTldFQVI7CisgICAgICBicmVhazsKKworICAgIGNhc2UgImVzc2UiOgorICAgIGNhc2UgImZyaXNzIjoKKyAgICAgIGFjdGlvbiA9IE1BX0VBVDsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSAic2F1ZmUiOgorICAgICAgYWN0aW9uID0gTUFfRFJJTks7CisgICAgICBicmVhazsKKworICAgIGNhc2UgImhvZXJlIjoKKyAgICAgIC8vTUFfTElTVEVOID09IGxhdXNjaGUKKyAgICAgIGFjdGlvbiA9IE1BX0xJU1RFTjsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgImxlc2UiOgorICAgICAgYWN0aW9uID0gTUFfUkVBRDsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSAiOiI6CisgICAgY2FzZSAiOyI6CisgICAgICBhY3Rpb24gPSBNQV9FTU9URTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSAiemVyYnJlY2hlIjoKKyAgICBjYXNlICJ6ZXJzdG9lcmUiOgorICAgIGNhc2UgInZlcmJyZW5uZSI6CisgICAgY2FzZSAiZW50c29yZ2UiOgorICAgICAgYWN0aW9uID0gTUFfUkVNT1ZFOworICAgICAgYnJlYWs7CisgIH0KKyAgcmV0dXJuIGFjdGlvbjsKK30KKworcHJvdGVjdGVkIGludCBjb21tX2d1ZXNzX21lc3NhZ2VfdHlwZShzdHJpbmcgYWN0aW9uLCBtaXhlZCBvcmlnaW4pIHsKKyAgLy8gZXZlcnl0aGluZyBub3QgbWVudGlvbmVkIGluIHRoZSBzd2l0Y2ggYmVjb21lcyBNVF9MT09LLgorICBzd2l0Y2goYWN0aW9uKSB7CisgICAgY2FzZSBNQV9GSUdIVDoKKyAgICAgIC8vIEthbXBmIGthbm4gbWFuIG1laXN0ZW4gc293b2hsIHNlaGVuIGFscyBhdWNoIGhvZXJlbi4KKyAgICAgIHJldHVybiBNVF9MT09LIHwgTVRfTElTVEVOOworICAgIGNhc2UgTUFfTElTVEVOOgorICAgIGNhc2UgTUFfU0FZOgorICAgICAgcmV0dXJuIE1UX0xJU1RFTjsKKyAgICBjYXNlIE1BX0ZFRUw6CisgICAgICByZXR1cm4gTVRfRkVFTDsKKyAgICBjYXNlIE1BX1NNRUxMOgorICAgICAgcmV0dXJuIE1UX1NNRUxMOworICAgIGNhc2UgTUFfQ0hBTk5FTDoKKyAgICAgIHJldHVybiBNVF9DT01NIHwgTVRfRkFSOworICAgIGNhc2UgTUFfRU1PVEU6CisgICAgICBpZiAob2JqZWN0cChvcmlnaW4pCisgICAgICAgICAgJiYgZW52aXJvbm1lbnQob3JpZ2luKSA9PSBlbnZpcm9ubWVudCgpKQorICAgICAgICByZXR1cm4gTVRfQ09NTTsKKyAgICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIE1UX0NPTU0gfCBNVF9GQVI7CisgICAgY2FzZSBNQV9TSE9VVDoKKyAgICAgIHJldHVybiBNVF9MSVNURU4gfCBNVF9GQVI7CisgIH0KKyAgLy8gZGllIG1laXN0ZW4gQWt0aW9uZW4gc2luZCB6dW1pbmRlc3Qgc2ljaHRiYXIuLi4KKyAgcmV0dXJuIE1UX0xPT0s7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9saXZpbmcvZGVzY3JpcHRpb24uYyBiL3N0ZC9saXZpbmcvZGVzY3JpcHRpb24uYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MzUzY2E5Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL2xpdmluZy9kZXNjcmlwdGlvbi5jCkBAIC0wLDAgKzEsMzMyIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gbGl2aW5nL2Rlc2NyaXB0aW9uLmMgLS0gZGVzY3JpcHRpb24gZm9yIGxpdmluZyBvYmplY3RzCisvLworLy8gJElkOiBkZXNjcmlwdGlvbi5jIDkzOTUgMjAxNS0xMi0wOCAyMzowNDozOFogWmVzc3RyYSAkCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKK2luaGVyaXQgIi9zdGQvY29udGFpbmVyL2Rlc2NyaXB0aW9uIjsKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKworI2luY2x1ZGUgPGxpdmluZy9za2lsbHMuaD4KKyNpbmNsdWRlIDxsaXZpbmcvY2xvdGhpbmcuaD4KKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8d2l6bGV2ZWxzLmg+CisjaW5jbHVkZSA8bmV3X3NraWxscy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxsYW5ndWFnZS5oPgorI2luY2x1ZGUgPGRlZmluZXMuaD4KKyNpbmNsdWRlIDxjbGFzcy5oPgorI2luY2x1ZGUgPHN5c19kZWJ1Zy5oPgorCitwdWJsaWMgc3RyaW5nIF9xdWVyeV9pbnRlcm5hbF9leHRyYWxvb2soKSB7CisgIG1peGVkIHhsOworICBpbnQgemVpdDsKKyAgc3RyaW5nIHJlcywgbG9vaz0iIjsKKworICB4bD1RdWVyeShQX0lOVEVSTkFMX0VYVFJBX0xPT0ssRl9WQUxVRSk7CisgIGlmICghbWFwcGluZ3AoeGwpKQorICAgIHJldHVybigwKTsKKworICBmb3JlYWNoKHN0cmluZyBrZXksIG1hcHBpbmcgeGxkOiB4bCkgeworICAgIGlmIChpbnRwKHplaXQ9eGxkWyJ4bGR1cmF0aW9uIl0pKSB7CisgICAgICAvL2hhdCBvZmZlbmJhciBuZW4gQWJsYXVmZGF0dW0KKyAgICAgIGlmICggKHplaXQgPiAwICYmIHplaXQgPCB0aW1lKCkpIHx8CisgICAgICAgICAgICh6ZWl0IDwgMCAmJiBhYnMoemVpdCkgPCBvYmplY3RfdGltZShNRSkpICkgeworICAgICAgICAvLyBaZWl0IGFiZ2VsYXVmZW4gb2RlcgorICAgICAgICAvLyBuZWdhdGl2ZSAiQWJsYXVmemVpdCIgdW5kIGRhcyBPYmpla3QgaXN0IG5ldWVyIGFscyBkaWUKKyAgICAgICAgLy8gRWludHJhZ3plaXQsIGFsc28gbG9lc2NoZW4gdW5kIHdlaXRlciAoamEsIGRhcyBnZWh0LiA7LSkgdW5kIHhsZAorICAgICAgICAvLyBoYXQgZGFzIEVpbnRyYWdzbWFwcGluZyBqYSBub2NoLCB3ZWl0ZXJlIEJlbnV0enVuZyBhbHNvIG1vZWdsaWNoLikKKyAgICAgICAgbV9kZWxldGUoeGwsa2V5KTsKKyAgICAgICAgLy8gZ2dmLiBNZWxkdW5nIGF1c2dlYmVuCisgICAgICAgIGlmIChpbnRlcmFjdGl2ZShNRSkpIHsKKyAgICAgICAgICBpZiAoc2l6ZW9mKHhsZFsieGxlbmRlIl0pKSB7CisgICAgICAgICAgICB0ZWxsX29iamVjdChNRSx4bGRbInhsZW5kZSJdKTsKKyAgICAgICAgICB9CisgICAgICAgICAgLy9rZWluIGVpbmZhY2hlciBTdHJpbmcsIGFiZXIgT2JqZWt0K0Z1bmt0aW9uIGdlZ2ViZW4/CisgICAgICAgICAgZWxzZSBpZiAoc2l6ZW9mKHhsZFsieGxlbmRlZnVuIl0pICYmIHNpemVvZih4bGRbInhsb2JqZWN0bmFtZSJdKSAmJgorICAgICAgICAgICAgKCFjYXRjaChyZXM9Y2FsbF9vdGhlcih4bGRbInhsb2JqZWN0bmFtZSJdLHhsZFsieGxlbmRlZnVuIl0sTUUpCisgICAgICAgICAgICAgICAgICAgIDtwdWJsaXNoKSkpIHsKKyAgICAgICAgICAgICAgaWYgKHN0cmluZ3AocmVzKSAmJiBzaXplb2YocmVzKSkKKyAgICAgICAgICAgICAgICB0ZWxsX29iamVjdChNRSxyZXMpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorICAgIH0KKyAgICAvLyBEZXIgRWludHJhZyBpc3Qgb2ZmZW5iYXIgbm9jaCBndWVsdGlnLCBNZWxkdW5nIGFuaGFlbmdlbiwgYnp3LiB2aWEKKyAgICAvLyBGdW5rdGlvbnNhdWZydWYgYmVzY2hhZmZlbi4KKyAgICBpZiAoc2l6ZW9mKHhsZFsieGxsb29rIl0pKQorICAgICAgbG9vays9eGxkWyJ4bGxvb2siXTsKKyAgICBlbHNlIGlmIChzaXplb2YoeGxkWyJ4bGZ1biJdKSAmJiBzaXplb2YoeGxkWyJ4bG9iamVjdG5hbWUiXSkpIHsKKyAgICAgIGNsb3N1cmUgY2w7CisgICAgICBpZiAoY2F0Y2goY2w9c3ltYm9sX2Z1bmN0aW9uKHhsZFsieGxmdW4iXSx4bGRbInhsb2JqZWN0bmFtZSJdKTtwdWJsaXNoKQorICAgICAgICAgIHx8ICFjbCkgeworICAgICAgICAgIC8vIHdlbm4gRmVobGVyIGJlaW0gTGFkZW4vQ2xvc3VyZSBlcnN0ZWxsZW4sIGRhbm4gRWludHJhZyBsb2VzY2hlbgorICAgICAgICAgIC8vIC0+IEFubmFobWUsIGRhc3MgZGllc2VyIEZlaGxlciBwZXJtYW5lbnQgc2VpbiB3aXJkLCB6LkIuIEVpbnRyYWcKKyAgICAgICAgICAvLyB2b24gQ2xvbmVuCisgICAgICAgICAgbV9kZWxldGUoeGwsa2V5KTsKKyAgICAgICAgICBjb250aW51ZTsKKyAgICAgIH0KKyAgICAgIGVsc2UgaWYgKCFjYXRjaChyZXM9ZnVuY2FsbChjbCwgTUUpOyBwdWJsaXNoKSkgeworICAgICAgICBpZiAoIXN0cmluZ3AocmVzKSB8fCAhc2l6ZW9mKHJlcykpIHsKKyAgICAgICAgICAvLyBrZWluZW4gU3RyaW5nIG9kZXIgbGVlcmVuIFN0cmluZyBnZWtyaWVndCAtPiB1ZWJlcnNwcmluZ2VuLgorICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICBsb29rKz1yZXM7CisgICAgICB9CisgICAgfQorICB9CisgIC8vIGZlcnRpZy4gV2VubiBsb29rIG5pY2h0IGxlZXIgaXN0LCB6dXJ1ZWNrZ2ViZW4sIHNvbnN0IDAuCisgIGlmIChzaXplb2YobG9vaykpCisgICAgcmV0dXJuKGxvb2spOworICBlbHNlCisgICAgcmV0dXJuKDApOworfQorCitwdWJsaWMgdmFyYXJncyBpbnQgQWRkRXh0cmFMb29rKHN0cmluZyBsb29rLCBpbnQgZHVyYXRpb24sIHN0cmluZyBrZXksIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgbG9va2VuZGUsIG9iamVjdCBvYikgeworICBtYXBwaW5nIHhsOworICBzdHJpbmcgb25hbWU7CisgIGlmICghc3RyaW5ncChrZXkpIHx8ICFzaXplb2Yoa2V5KSkgeworICAgIC8vIEF1dG9tYXRpc2NoIGVyemV1Z2VuLCB3ZW5uIG1vZWdsaWNoCisgICAgaWYgKCFvYmplY3RwKHByZXZpb3VzX29iamVjdCgpKSB8fCAKKyAgICAgICAgIXN0cmluZ3Aoa2V5PW9iamVjdF9uYW1lKHByZXZpb3VzX29iamVjdCgpKSkgfHwgIXNpemVvZihrZXkpKQorICAgICAgcmV0dXJuKC0xKTsKKyAgfQorCisgIGlmICghc3RyaW5ncChsb29rKSB8fCAhc2l6ZW9mKGxvb2spKQorICAgIHJldHVybigtMik7CisgIGlmICghaW50cChkdXJhdGlvbikpCisgICAgcmV0dXJuKC0zKTsKKworICB4bD1RdWVyeShQX0lOVEVSTkFMX0VYVFJBX0xPT0ssRl9WQUxVRSk7IC8vIGRyYW4gZGVua2VuOiBsaWVmZXJ0IHJlZmVyZW56IHp1cnVlY2sKKyAgaWYgKCFtYXBwaW5ncCh4bCkpIHsKKyAgICBTZXQoUF9JTlRFUk5BTF9FWFRSQV9MT09LLCB4bD0oW10pICk7CisgIH0KKworICAvLyBrZWluIEF1dG9tYXRpc2NoZXMgVWViZXJzY2hyZWliZW4uCisgIGlmIChtZW1iZXIoeGwsa2V5KSkKKyAgICByZXR1cm4oLTQpOworCisgIC8vIG5lZy4gV2VydGU6ICJiaXMgRW5kZS9yZWJvb3QiLCBhYnMoZHVyYXRpb24pID09IEVpbnRyYWd6ZWl0CisgIC8vIDA6ICJmdWVyIGV3aWciLCA+MDogWmVpdGRhdWVyIGluIFNla3VuZGVuCisgIGlmIChkdXJhdGlvbiA+IDApCisgICAgZHVyYXRpb24rPXRpbWUoKTsgIC8vIGhvZmZlbnRsaWNoIGdpYnQgZXMgcmVpY2h0emVpdGlnIDY0Yml0LUludHMKKyAgZWxzZSBpZiAoZHVyYXRpb24gPCAwKQorICAgIGR1cmF0aW9uPW5lZ2F0ZSh0aW1lKCkpOworICAvLyAwIGJsZWlidCwgd2llIGVzIGlzdC4KKworICBpZiAob2JqZWN0cChvYikpIHsKKyAgICAvLyBGdW5rdGlvbnNuYW1lIHVuZCBPYmpla3RuYW1lIChhbHMgTmFtZSwgZGFtaXQgZXMgYXVjaCBub2NoIGdlaHQsIHdlbm4KKyAgICAvLyBkYXMgT2JqZWt0IGVudGxhZGVuIHd1cmRlLCBDcmFzaC9yZWJvb3Qgd2FyIGV0Yy4pIHNwZWljaGVybgorICAgIC8vIENsb25lIHdlcmRlbiBhdWNoIGdlc3BlaWNoZXJ0LCBhYmVyIGVzIHdpcmQgZGlyZWt0IGVpbiBoYXJ0ZXIgRmVobGVyCisgICAgLy8gYXVzZ2Vsb2VzdCwgd2VubiBlaW4gcGVybWFuZW50ZXIgWGxvb2sgZnVlciBlaW5lbiBDbG9uZSByZWdpc3RyaWVydAorICAgIC8vIHdlcmRlbiBzb2xsOiBkYXMga2FubiBuaWNodCBnZWhlbi4KKyAgICBpZiAoIWR1cmF0aW9uICYmIGNsb25lcChvYikpCisgICAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoCisgICAgICAgICAgICJBZGRFeHRyYUxvb2soKTogRmVobGVyaGFmdGVzIEFyZ3VtZW50IDxkdXJhdGlvbj46ICVkLCAiCisgICAgICAgICAgICJwZXJtYW5lbnRlIEV4dHJhbG9va3MgZHVyY2ggQ2xvbmUgKCVzKSBuaWNodCByZWdpc3RyaWVyYmFyLlxuIiwKKyAgICAgICAgICAgZHVyYXRpb24sIG9iamVjdF9uYW1lKG9iKSkpOworCisgICAgeGxba2V5XT0oWyJ4bG9iamVjdG5hbWUiOm9iamVjdF9uYW1lKG9iKSwKKyAgICAgICAgICAgICAgInhsZnVuIjogbG9vaywKKyAgICAgICAgICAgICBdKTsKKyAgICAvLyBnZ2YuIE5hbWUgZGVyIEZ1bmt0aW9uIHNwZWljaGVybiwgZGllIGJlaSBBYmxhdWYgYXVmZ2VydWZlbiB3aXJkLgorICAgIGlmIChzdHJpbmdwKGxvb2tlbmRlKSAmJiBzaXplb2YobG9va2VuZGUpKQorICAgICAgICB4bFtrZXldWyJ4bGVuZGVmdW4iXT1sb29rZW5kZTsKKyAgfQorICBlbHNlIHsKKyAgICAvLyBFaW5mYWNoZXIgRWludHJhZywgbnVyIGRlbiBiZWFyYmVpdGV0ZW4gU3RyaW5nIG1lcmtlbi4gOy0pCisgICAgeGxba2V5XT0oWyJ4bGxvb2siOiBicmVha19zdHJpbmcocmVwbGFjZV9wZXJzb25hbChsb29rLCh7TUV9KSwxKSw3OCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIixCU19MRUFWRV9NWV9MRlMpLAorICAgICAgICAgICAgIF0pOworICAgIC8vIGdnZi4gTWVsZHVuZyBzcGVpY2hlcm4sIGRpZSBiZWkgQWJsYXVmIGF1c2dlZ2ViZW4gd2VyZGVuIHNvbGwuCisgICAgaWYgKHN0cmluZ3AobG9va2VuZGUpICYmIHNpemVvZihsb29rZW5kZSkpIHsKKyAgICAgIHhsW2tleV1bInhsZW5kZSJdPWJyZWFrX3N0cmluZyhyZXBsYWNlX3BlcnNvbmFsKGxvb2tlbmRlLCh7TUV9KSwxKSw3OCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIixCU19MRUFWRV9NWV9MRlMpOworICAgIH0KKyAgfQorICAvLyBFbmRlemVpdCB2ZXJtZXJrZW4uCisgIGlmIChkdXJhdGlvbiAhPSAwKQorICAgIHhsW2tleV1bInhsZHVyYXRpb24iXT1kdXJhdGlvbjsKKworICAvLyBLZWluIFNldCBub2V0aWcsIHdlaWwgUXVlcnkgZGFzIE1hcHBpbmcgamEgYWxzIFJlZmVyZW56IGxpZWZlcnRlLgorICByZXR1cm4oMSk7Cit9CisKK3B1YmxpYyBpbnQgUmVtb3ZlRXh0cmFMb29rKHN0cmluZyBrZXkpIHsKKyAgbWFwcGluZyB4bDsKKyAgaWYgKCFzdHJpbmdwKGtleSkgfHwgIXNpemVvZihrZXkpKSB7CisgICAgLy8gQXV0b21hdGlzY2ggZXJ6ZXVnZW4sIHdlbm4gbW9lZ2xpY2gKKyAgICBpZiAoIW9iamVjdHAocHJldmlvdXNfb2JqZWN0KCkpIHx8CisgICAgICAgICFzdHJpbmdwKGtleT1vYmplY3RfbmFtZShwcmV2aW91c19vYmplY3QoKSkpIHx8ICFzaXplb2Yoa2V5KSkKKyAgICAgIHJldHVybigtMSk7CisgIH0KKyAgeGw9UXVlcnkoUF9JTlRFUk5BTF9FWFRSQV9MT09LLEZfVkFMVUUpOyAvLyBkcmFuIGRlbmtlbjogbGllZmVydCByZWZlcmVueiB6dXJ1ZWNrCisgIGlmICghbWFwcGluZ3AoeGwpKQorICAgIHJldHVybiAoLTIpOworICBpZiAoIW1lbWJlcih4bCxrZXkpKQorICAgIHJldHVybigtMik7CisKKyAgbV9kZWxldGUoeGwsa2V5KTsKKyAgLy8gS2VpbiBTZXQgbm9ldGlnLCB3ZWlsIFF1ZXJ5IGRhcyBNYXBwaW5nIGphIGFscyBSZWZlcmVueiBsaWVmZXJ0ZS4KKyAgcmV0dXJuKDEpOworfQorCit2b2lkIGNyZWF0ZSgpCit7IAorICA6OmNyZWF0ZSgpOworICBTZXQoUF9HRU5ERVIsIFNBVkUsIEZfTU9ERSk7CisgIC8vIEV4dHJhbG9vay1Qcm9wZXJ0eSBzcGVpY2hlcm4gdW5kIHZvciBtYW51ZWxsZXIgQWVuZGVydW5nIHNjaHVldHplbgorICAvLyBFTXMgZHVlcmZlbiwgZGllIHdpc3NlbiBob2ZmZW50bGljaCwgd2FzIHNpZSB0dW4uCisgIFNldChQX0lOVEVSTkFMX0VYVFJBX0xPT0ssIFNBVkV8UFJPVEVDVEVELCBGX01PREVfQVMpOworICBTZXRQcm9wKFBfQ0xPVEhJTkcsKHt9KSk7CisgIEFkZElkKCJMaXZpbmciKTsKK30KKworc3RyaW5nIGNvbmRpdGlvbigpCit7CisgIGludCBocG50LCBtYXhfaHBudCwgcGVyYzsKKworICBocG50ICAgICAgICA9IFF1ZXJ5UHJvcCggUF9IUCApOworICBtYXhfaHBudCAgICA9IFF1ZXJ5UHJvcCggUF9NQVhfSFAgKTsKKworICBpZihtYXhfaHBudD4wICYmIGhwbnQ+MCkKKyAgICBwZXJjPTEwMCpocG50L21heF9ocG50OworIAorICBzd2l0Y2gocGVyYykgeworICAgIGNhc2UgMC4uOToKKyAgICAgICAgcmV0dXJuIGNhcGl0YWxpemUoUXVlcnlQcm9ub3VuKFdFUikpKyIgc3RlaHQgYXVmIGRlciBTY2h3ZWxsZSBkZXMgVG9kZXMuXG4iOworICAgIGNhc2UgMTAuLjE5OgorICAgICAgICByZXR1cm4gY2FwaXRhbGl6ZShRdWVyeVByb25vdW4oV0VSKSkrIiBicmF1Y2h0IGRyaW5nZW5kIGVpbmVuIEFyenQuXG4iOworICAgIGNhc2UgMjAuLjI5OgorICAgICAgICByZXR1cm4gY2FwaXRhbGl6ZShRdWVyeVByb25vdW4oV0VSKSkrIiBpc3QgaW4ga2VpbmVyIGd1dGVuIFZlcmZhc3N1bmcuXG4iOworICAgIGNhc2UgMzAuLjM5OgorICAgICAgICByZXR1cm4gY2FwaXRhbGl6ZShRdWVyeVByb25vdW4oV0VSKSkrIiB3YW5rdCBiZXJlaXRzIGJlZGVua2xpY2guXG4iOworICAgIGNhc2UgNDAuLjQ5OgorICAgICAgICByZXR1cm4gY2FwaXRhbGl6ZShRdWVyeVByb25vdW4oV0VSKSkrIiBtYWNodCBlaW5lbiBtaXRnZW5vbW1lbmVuIEVpbmRydWNrLlxuIjsKKyAgICBjYXNlIDUwLi41OToKKyAgICAgICAgcmV0dXJuIGNhcGl0YWxpemUoUXVlcnlQcm9ub3VuKFdFUikpKyIgc2llaHQgbmljaHQgbWVociB0YXVmcmlzY2ggYXVzLlxuIjsKKyAgICBjYXNlIDYwLi42OToKKyAgICAgICAgcmV0dXJuIGNhcGl0YWxpemUoUXVlcnlQcm9ub3VuKFdFUikpKyIgaXN0IGxlaWNodCBhbmdlc2NobGFnZW4uXG4iOworICAgIGNhc2UgNzAuLjc5OgorICAgICAgICByZXR1cm4gY2FwaXRhbGl6ZShRdWVyeVByb25vdW4oV0VSKSkrIiBmdWVobHRlIHNpY2ggaGV1dGUgc2Nob24gYmVzc2VyLlxuIjsKKyAgICBjYXNlIDgwLi44OToKKyAgICAgICAgcmV0dXJuIGNhcGl0YWxpemUoUXVlcnlQcm9ub3VuKFdFUikpKyIgaXN0IHNjaG9uIGV0d2FzIGdlc2Nod2FlY2h0LlxuIjsKKyAgfQorICAvL2ZhbGwtdGhyb3VnaAorICByZXR1cm4gY2FwaXRhbGl6ZShRdWVyeVByb25vdW4oV0VSKSkrIiBpc3QgYWJzb2x1dCBmaXQuXG4iOworfQorCit2YXJhcmdzIHN0cmluZyBsb25nKCkgeworICBzdHJpbmcgc3RyLCBjYXBfcHJvbm91bjsKKyAgc3RyaW5nIGRlc2NyLCBpbnZsLHRtcCxleGw7CisgIGludCBocG50LCBtYXhfaHBudDsKKyAgbWl4ZWQgZmlsdGVyX2xkZmllZDsKKyAgb2JqZWN0IG9iOworCisgIHN0ciA9IHByb2Nlc3Nfc3RyaW5nKCBRdWVyeVByb3AoUF9MT05HKSApOworICBpZighc3RyaW5ncChzdHIpKSBzdHIgPSAiIjsKKworICBzdHIgKz0gY29uZGl0aW9uKCk7CisKKyAgLy8gRXh0cmFsb29rCisgIGlmKHN0cmluZ3AodG1wID0gUXVlcnlQcm9wKFBfRVhUUkFfTE9PSykpKQorICAgIHN0ciArPSB0bXA7CisgIGlmIChzdHJpbmdwKHRtcCA9IFF1ZXJ5UHJvcChQX0lOVEVSTkFMX0VYVFJBX0xPT0spKSkKKyAgICBzdHIgKz0gdG1wOworICBmb3Iob2IgPSBmaXJzdF9pbnZlbnRvcnkoTUUpOyBvYjsgb2IgPSBuZXh0X2ludmVudG9yeShvYikpCisgICAgaWYoZXhsID0gb2ItPlF1ZXJ5UHJvcChQX0VYVFJBX0xPT0spKSAKKyAgICAgIHN0ciArPSBleGw7CisgICAgZWxzZSBpZihleGwgPSBvYi0+ZXh0cmFfbG9vaygpKSAKKyAgICAgIHN0ciArPSBleGw7IC8vIFRPIEJFIFJFTU9WRUQKKworICAKKyAgaWYoZmlsdGVyX2xkZmllZCA9IFF1ZXJ5UHJvcChQX1RSQU5TUEFSRU5UKSkKKyAgeworICAgIGludmwgPSBtYWtlX2ludmxpc3QoUEwsIGFsbF9pbnZlbnRvcnkoTUUpKTsKKyAgICBpZihpbnZsICE9ICIiKQorICAgICAgc3RyICs9IGNhcGl0YWxpemUoUXVlcnlQcm9ub3VuKFdFUikpKyIgdHJhZWd0IGJlaSBzaWNoOlxuIiArIGludmw7CisgIH0KKyAgcmV0dXJuIHN0cjsKK30KKwordmFyYXJncyBzdHJpbmcgbmFtZShpbnQgY2FzdXMsIGludCBkZW1vbnN0KQoreyAKKyAgaWYoIFF1ZXJ5UHJvcCggUF9JTlZJUyApICkKKyAgeworICAgIGlmKCBjYXN1cyA9PSBSQVcgKSByZXR1cm4gIkplbWFuZCI7CisgICAgcmV0dXJuICh7IkplbWFuZCIsIkplbWFuZHMiLCJKZW1hbmRlbSIsIkplbWFuZGVuIn0pW2Nhc3VzXTsKKyAgfQorICBpZiAoUXVlcnlQcm9wKFBfRlJPRykgJiYgY2FzdXMgIT0gUkFXICkKKyAgeworICAgIHN0cmluZyBzPVF1ZXJ5QXJ0aWNsZShjYXN1cywgMCwgMSkrIkZyb3NjaCI7CisgICAgaWYgKGNhc3VzPT1XRVNTRU4pIHMgKz0gImVzIjsKKyAgICByZXR1cm4gczsKKyAgfQorICByZXR1cm4gOjpuYW1lKCBjYXN1cywgZGVtb25zdCApOworfQorCitzdGF0aWMgaW50IF9xdWVyeV9nZW5kZXIoKQoreworICBpZiAoUXVlcnlQcm9wKFBfRlJPRykpIHJldHVybiAxOworICByZXR1cm4gUXVlcnkoUF9HRU5ERVIpOworfQorCisvLyBOUEMgc29sbGVuIGF1cyBLb21wYXRpYmlsaXRhZXRzZ3J1ZW5kZW4gYXVjaCBlaW5lICJlY2h0ZSIgUmFzc2UgaGFiZW4uCisvLyBEZWZhdWx0IGlzdCBoaWVyIGRpZSBSYXNzZSwgbWFuIGthbm4gYWJlciBoaWVybWl0IGF1Y2ggZWluZW4gTlBDIGZha2VuLAorLy8gZGVyIHNpY2ggdGFybnQsIGluZGVtIG1hbiBQX1JFQUxfUkFDRSBwZXIgSGFuZCBzZXR6dC4KK3N0YXRpYyBzdHJpbmcgX3F1ZXJ5X3JlYWxfcmFjZSgpCit7CisgIHJldHVybiBRdWVyeShQX1JFQUxfUkFDRSxGX1ZBTFVFKXx8UXVlcnlQcm9wKFBfUkFDRSk7Cit9CisKK3N0YXRpYyBtaXhlZCBfc2V0X25hbWUobWl4ZWQgbm0gKQoreworICBzdHJpbmcgbHZuYW07CisgIGx2bmFtID0gbm07CisgIGlmKHBvaW50ZXJwKG5tKSkgbHZuYW0gPSBubVswXTsKKyAgc2V0X2xpdmluZ19uYW1lKGxvd2VyX2Nhc2UobHZuYW0pKTsKKyAgcmV0dXJuIFNldChQX05BTUUsIG5tKTsKK30KKworaW50IF9xdWVyeV9jb250YWluZXIoKQoreworICByZXR1cm4gMDsKK30KKworaW50IGlzX2NsYXNzX21lbWJlcihtaXhlZCBzdHIpIHsKKyAgLy8gS2VpbmUgS2xhc3NlLCBrZWluZSBNaXRnbGllZHNjaGFmdCAuLi4KKyAgaWYgKCFzdHIgfHwgKCFzdHJpbmdwKHN0cikgJiYgIXBvaW50ZXJwKHN0cikpIHx8IHN0cj09IiIpIAorICAgICAgcmV0dXJuIDA7CisKKyAgaWYgKDo6aXNfY2xhc3NfbWVtYmVyKHN0cikpCisgICAgcmV0dXJuIDE7CisKKyAgaWYgKHN0cmluZ3Aoc3RyKSkKKyAgICBzdHIgPSAoe3N0cn0pOworCisgIC8vIFJhc3NlbiB3ZXJkZW4gYWxzIGltcGxpeml0ZSBLbGFzc2VuIGF1ZmdlZmFzc3QuCisgIC8vIFRPRE86IFBydWVmZW4sIG9iIGRhcyB1bmJlZGluZ3QgaGFydC1rb2RpZXJ0IHNlaW4gbXVzcy4KKyAgc3RyaW5nIHJhY2UgPSBRdWVyeVByb3AoUF9SQUNFKTsKKyAgaWYgKCBzdHJpbmdwKHJhY2UpICYmIG1lbWJlciggc3RyLCBsb3dlcl9jYXNlKHJhY2UpICkgPiAtMSApCisgICAgcmV0dXJuIDE7CisgIGVsc2UKKyAgICByZXR1cm4gMDsKK30KKworbWFwcGluZyBfcXVlcnlfbWF0ZXJpYWwoKSB7CisgIG1peGVkIHJlczsKKworICBpZiAobWFwcGluZ3AocmVzPVF1ZXJ5KFBfTUFURVJJQUwpKSkKKyAgICByZXR1cm4gcmVzOworICByZXR1cm4gKFtNQVRfTUlTQ19MSVZJTkc6MTAwXSk7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9saXZpbmcvaGVscGVycy5jIGIvc3RkL2xpdmluZy9oZWxwZXJzLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2QyOTJjMAotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9saXZpbmcvaGVscGVycy5jCkBAIC0wLDAgKzEsMTQ5IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gbGl2aW5nL2hlbHBlcnMuYyAtLSAoUXVlcnkpTWV0aG9kZW4gZnVlciBIaWxmc29iamVrdGUsIHouQi4genVtIFRhdWNoZW4KKy8vCisvLyAkSWQ6IG1vbmV5aGFuZGxlci5oLHYgMy4xIDE5OTcvMDIvMTIgMTM6Mjk6MDkgV2FyZ29uIEV4cCAlCisKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworI2luY2x1ZGUgPGxpdmluZy9oZWxwZXJzLmg+CisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyN1bmRlZiBORUVEX1BST1RPVFlQRVMKKworcHVibGljIGludCBSZWdpc3RlckhlbHBlck9iamVjdChvYmplY3QgaGVscGVyLCBpbnQgdHlwZSwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3xjbG9zdXJlIGNhbGxiYWNrKSAKK3sKKyAgLy8gY2I6IGNsb3N1cmUgYXVmIGRpZSBDYWxsYmFjay1GdW5rdGlvbiBpbiBwcmV2aW91c19vYmplY3QoKQorICBjbG9zdXJlIGNiOworICAvLyBoZWxwZXJzOiBNYXBwaW5nIGFsbGVyIGVpbmdldHJhZ2VuZW4gSGVsZmVyLU9iamVrdGUKKyAgbWFwcGluZyBoZWxwZXJzOworCisgIC8vIEtlaW4gcG9zaXRpdmVyIEludGVnZXJ3ZXJ0IGFscyBIZWxmZXJ0eXAgdWViZXJnZWJlbj8KKyAgaWYgKCAhaW50cCh0eXBlKSB8fCB0eXBlIDwgMSApCisgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoICJXcm9uZyBhcmd1bWVudCAxIHRvIFJlZ2lzdGVySGVscGVyT2JqZWN0KCkuICIKKyAgICAgICAgIkV4cGVjdGVkIHBvc2l0aXZlIDxpbnQ+LCBnb3QgJU8uXG4iLCB0eXBlKSk7CisgIC8vIEtlaW4gT2JqZWt0IHZvcmhhbmRlbiwgYW4gZGVtIGRpZSBDYWxsYmFjay1GdW5rdGlvbiBnZXJ1ZmVuIHdlcmRlbiBzb2xsPworICBpZiAoICFvYmplY3RwKGhlbHBlcikgKQorICAgIHJldHVybiBIRUxQRVJfTk9fQ0FMTEJBQ0tfT0JKRUNUOworCisgIC8vIEZ1bmt0aW9uc25hbWUgenVtIFp3ZWNrIGRlcyBDYWxsYmFja3MgdWViZXJnZWJlbj8KKyAgaWYgKCBzdHJpbmdwKGNhbGxiYWNrKSApIHsKKyAgICAvLyBEYW5uIENsb3N1cmUgZGF2b24gZXJzdGVsbGVuLgorICAgIGNiID0gc3ltYm9sX2Z1bmN0aW9uKGNhbGxiYWNrLCBoZWxwZXIpOworICAgIC8vIFdlbm4gZGFzIG5pY2h0IGtsYXBwdCAoekIgd2VpbCBkaWUgRnVua3Rpb24gcHJpdmF0ZSBpc3QpLCBkYW5uCisgICAgLy8gRmVobGVyIHdlcmZlbiB1bmQgYWJicmVjaGVuLgorICAgIGlmICggIWNsb3N1cmVwKGNiKSApCisgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKCJFcnJvciBpbiBSZWdpc3RlckhlbHBlck9iamVjdCgpOiBVbmFibGUgdG8gY2FsbCAiCisgICAgICAgICJmdW5jdGlvbiAlcyBpbiBvYmplY3QgJU8uXG4iLCBjYWxsYmFjaywgaGVscGVyKSk7CisgIH0KKyAgLy8gV2VubiBzY2hvbiBlaW5lIENsb3N1cmUgdWViZXJnZWJlbiB3dXJkZSwgZGFubiBkaWVzZSBkaXJla3Qgc3BlaWNoZXJuLgorICBlbHNlIGlmICggY2xvc3VyZXAoY2FsbGJhY2spICkgeworICAgIGNiID0gY2FsbGJhY2s7CisgIH0KKyAgLy8gV2VkZXIgRnVua3Rpb25zbmFtZSwgbm9jaCBDbG9zdXJlLCBkYW5uIEZlaGxlciB3ZXJmZW4gdW5kIGFiYnJlY2hlbi4KKyAgZWxzZQorICAgIHJhaXNlX2Vycm9yKHNwcmludGYoIldyb25nIGFyZ3VtZW50IDIgdG8gUmVnaXN0ZXJIZWxwZXJPYmplY3QoKS4gIgorICAgICAgIkV4cGVjdGVkIDxzdHJpbmcvY2xvc3VyZT4sIGdvdCAlTy5cbiIsY2FsbGJhY2spKTsKKworICAvLyBQcm9wZXJ0eSBhdXNsZXNlbiB1bmQgendpc2NoZW5zcGVpY2hlcm4KKyAgaGVscGVycyA9IFF1ZXJ5UHJvcChQX0hFTFBFUl9PQkpFQ1RTKTsKKyAgLy8gV2VubiBkaWUgUHJvcCBsZWVyIGlzdCwgaGllciBpbml0aWFsaXNpZXJlbgorICBpZiAoICFoZWxwZXJzICkgeworICAgIGhlbHBlcnMgPSAoW3R5cGU6KHt9KV0pOworICB9CisgIC8vIFdlbm4gZGVyIFR5cCBub2NoIG5pY2h0IGV4aXN0aWVydCwgaGllciBuYWNodHJhZ2VuLgorICBlbHNlIGlmICggIXBvaW50ZXJwKGhlbHBlcnNbdHlwZV0pICkgeworICAgIGhlbHBlcnNbdHlwZV0gPSAoe30pOworICB9CisKKyAgLy8gQ2xvc3VyZSBlaW50cmFnZW4sIHdlbm4gbm9jaCBuaWNodCB2b3JoYW5kZW4KKyAgaWYgKCBtZW1iZXIoaGVscGVyc1t0eXBlXSwgY2IpPT0tMSApIHsKKyAgICBoZWxwZXJzW3R5cGVdID0gaGVscGVyc1t0eXBlXSsoe2NifSk7CisgICAgU2V0UHJvcChQX0hFTFBFUl9PQkpFQ1RTLCBoZWxwZXJzKTsKKyAgICByZXR1cm4gSEVMUEVSX1NVQ0NFU1M7CisgIH0KKyAgZWxzZQorICAgIHJldHVybiBIRUxQRVJfQUxSRUFEWV9MSVNURUQ7Cit9CisKK3B1YmxpYyBpbnQgVW5yZWdpc3RlckhlbHBlck9iamVjdChvYmplY3QgaGVscGVyLCBpbnQgdHlwZSkgeworICBpZiAoICFpbnRwKHR5cGUpIHx8IHR5cGUgPCAxICkKKyAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZiggIldyb25nIGFyZ3VtZW50IDIgdG8gVW5yZWdpc3RlckhlbHBlck9iamVjdCgpLiAiCisgICAgICAgICJFeHBlY3RlZCBwb3NpdGl2ZSA8aW50PiwgZ290ICVPLlxuIiwgdHlwZSkpOworICBpZiAoICFvYmplY3RwKGhlbHBlcikgKQorICAgIHJldHVybiBIRUxQRVJfTk9fQ0FMTEJBQ0tfT0JKRUNUOworCisgIG1hcHBpbmcgaGVscGVycyA9IFF1ZXJ5KFBfSEVMUEVSX09CSkVDVFMsIEZfVkFMVUUpOworCisgIGlmICggbWFwcGluZ3AoaGVscGVycykgKSB7CisgICAgZm9yZWFjaChjbG9zdXJlIGNsOiBoZWxwZXJzW3R5cGVdKSB7CisgICAgICBpZiAoIGdldF90eXBlX2luZm8oY2wsMikgPT0gaGVscGVyICkgeworICAgICAgICBoZWxwZXJzW3R5cGVdID0gaGVscGVyc1t0eXBlXS0oe2NsfSk7CisgICAgICAgIHJldHVybiBIRUxQRVJfU1VDQ0VTUzsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgcmV0dXJuIEhFTFBFUl9OT1RISU5HX1RPX1VOUkVHSVNURVI7Cit9CisKKy8vIFF1ZXJ5bWV0aG9kZSBmdWVyIFBfQVFVQVRJQ19IRUxQRVJTCitwdWJsaWMgbWFwcGluZyBfcXVlcnlfbGliX3BfYXF1YXRpY19oZWxwZXJzKCkgeworICBtYXBwaW5nIHJldCA9IChbXSk7CisgIC8vIGVpbmdldHJhZ2VuZSBDYWxsYmFjay1DbG9zdXJlcyBhdXNsZXNlbgorICBjbG9zdXJlICpoZWxwZXJzID0gCisgICAgKCBRdWVyeShQX0hFTFBFUl9PQkpFQ1RTLCBGX1ZBTFVFKSB8fCAoW10pIClbSEVMUEVSX1RZUEVfQVFVQVRJQ107CisgIC8vIEVzIHNpbmQgZ2FyIGtlaW5lIFdlcnRlIGVpbmdldHJhZ2VuPyBEYW5uIGdsZWljaCByYXVzc3ByaW5nZW4uCisgIGlmICggIXBvaW50ZXJwKGhlbHBlcnMpICkKKyAgICByZXR1cm4gcmV0OworCisgIC8vIE51bGxlbGVtZW50IHN1YnN0cmFoaWVyZW4KKyAgaGVscGVycyAtPSAoezB9KTsKKworICBpZiAoIHNpemVvZihoZWxwZXJzKSApIHsKKyAgICAvLyBNYXBwaW5nIGVyc3RlbGxlbjogS2V5cyBzaW5kIGRpZSBPYmpla3RlLCBkZXJlbiBDbG9zdXJlcyBlaW5nZXRyYWdlbgorICAgIC8vIHNpbmQuIFZhbHVlcyBzaW5kIGRpZSBSdWVja2dhYmV3ZXJ0ZSBkZXIgQ2xvc3VyZXMsCisgICAgLy8gZGllIGRhYmVpIGRhcyBTcGllbGVyb2JqZWt0IHVuZCBkYXMgYWJmcmFnZW5kZSBPYmpla3QgdWViZXJnZWJlbgorICAgIC8vIGJla29tbWVuLgorICAgIG9iamVjdCAqa2V5cyA9IG1hcChoZWxwZXJzLCAjJ2dldF90eXBlX2luZm8sIDIpOworICAgIGludCAqdmFscyA9IG1hcChoZWxwZXJzLCAjJ2Z1bmNhbGwsIHRoaXNfb2JqZWN0KCksIHByZXZpb3VzX29iamVjdCgxKSk7CisgICAgcmV0ID0gbWttYXBwaW5nKGtleXMsdmFscyk7CisgIH0KKyAgcmV0dXJuIHJldDsKK30KKworLy8gUXVlcnltZXRob2RlIGZ1ZXIgUF9BRVJJQUxfSEVMUEVSUworcHVibGljIG1hcHBpbmcgX3F1ZXJ5X2xpYl9wX2FlcmlhbF9oZWxwZXJzKCkgeworICBtYXBwaW5nIHJldCA9IChbXSk7CisgIC8vIGVpbmdldHJhZ2VuZSBDYWxsYmFjay1DbG9zdXJlcyBhdXNsZXNlbgorICBjbG9zdXJlICpoZWxwZXJzID0gCisgICAgKCBRdWVyeShQX0hFTFBFUl9PQkpFQ1RTLCBGX1ZBTFVFKSB8fCAoW10pIClbSEVMUEVSX1RZUEVfQUVSSUFMXTsKKworICAvLyBFcyBzaW5kIGdhciBrZWluZSBXZXJ0ZSBlaW5nZXRyYWdlbj8gRGFubiBnbGVpY2ggcmF1c3NwcmluZ2VuLgorICBpZiAoICFwb2ludGVycChoZWxwZXJzKSApCisgICAgcmV0dXJuIHJldDsKKyAgCisgIC8vIE51bGxlbGVtZW50IHN1YnN0cmFoaWVyZW4KKyAgaGVscGVycyAtPSAoezB9KTsKKworICBpZiAoIHNpemVvZihoZWxwZXJzKSApIHsKKyAgICAvLyBNYXBwaW5nIGVyc3RlbGxlbjogS2V5cyBzaW5kIGRpZSBPYmpla3RlLCBkZXJlbiBDbG9zdXJlcyBlaW5nZXRyYWdlbgorICAgIC8vIHNpbmQuIFZhbHVlcyBzaW5kIGRpZSBSdWVja2dhYmV3ZXJ0ZSBkZXIgQ2xvc3VyZXMsCisgICAgLy8gZGllIGRhYmVpIGRhcyBTcGllbGVyb2JqZWt0IHVuZCBkYXMgYWJmcmFnZW5kZSBPYmpla3QgdWViZXJnZWJlbgorICAgIC8vIGJla29tbWVuLgorICAgIG9iamVjdCAqa2V5cyA9IG1hcChoZWxwZXJzLCMnZ2V0X3R5cGVfaW5mbywgMik7CisgICAgaW50ICp2YWxzID0gbWFwKGhlbHBlcnMsICMnZnVuY2FsbCwgdGhpc19vYmplY3QoKSwgcHJldmlvdXNfb2JqZWN0KDEpKTsKKyAgICByZXQgPSBta21hcHBpbmcoa2V5cyx2YWxzKTsKKyAgfQorICByZXR1cm4gcmV0OworfQorCisvLyBRdWVyeW1ldGhvZGUgZnVlciBQX0hFTFBFUl9PQkpFQ1RTCitwdWJsaWMgbWFwcGluZyBfcXVlcnlfbGliX3BfaGVscGVyX29iamVjdHMoKSB7CisgIHJldHVybiBkZWVwX2NvcHkoUXVlcnkoUF9IRUxQRVJfT0JKRUNUUyxGX1ZBTFVFKSk7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9saXZpbmcvaW52ZW50b3J5LmMgYi9zdGQvbGl2aW5nL2ludmVudG9yeS5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUzMDI3ZTQKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvbGl2aW5nL2ludmVudG9yeS5jCkBAIC0wLDAgKzEsNjYgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBjb250YWluZXIvaW52ZW50b3J5LmMgLS0gVW1nYW5nIG1pdCBiZXNvbmRlcmVuIE9iamVrdGVuIGltIEludmVudG9yeQorLy8KKy8vICRJZDogaW52ZW50b3J5LmMgNjU1NCAyMDA3LTEwLTE3IDIyOjQ1OjUzWiBaZXNzdHJhICQKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworaW5oZXJpdCAiL3N0ZC9jb250YWluZXIvaW52ZW50b3J5IjsKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKworI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxzZW5zaXRpdmUuaD4KKyNpbmNsdWRlIDxhdHRyaWJ1dGVzLmg+CisKKyNkZWZpbmUgTUUgdGhpc19vYmplY3QoKQorCitwdWJsaWMgdm9pZCBSZW1vdmVTZW5zaXRpdmVPYmplY3Qob2JqZWN0IG9iKSB7CisgIDo6UmVtb3ZlU2Vuc2l0aXZlT2JqZWN0KG9iKTsKKyAgUmVtb3ZlU2Vuc2l0aXZlT2JqZWN0RnJvbUxpc3Qob2IsU0VOU0lUSVZFX0FUVEFDSyk7CisgIGlmIChvYmplY3RwKG9iKSAmJiAob2ItPlF1ZXJ5UHJvcChQX1hfQVRUUl9NT0QpICAgfHwKKyAgICAgICAgICAgICAgICAgICAgICBvYi0+UXVlcnlQcm9wKFBfWF9IRUFMVEhfTU9EKSApKQorICB7CisgICAgZGVyZWdpc3Rlcl9tb2RpZmllcihvYik7CisgICAgLy8gRXJzdCB3ZW5uIGRhcyBPYmpla3QgZGVuIFNwaWVsZXIgdmVybGFzc2VuIGtvbm50ZSwgZGllIEF0dHJpYnV0ZQorICAgIC8vIG5ldSBiZXJlY2huZW4uCisgICAgaWYgKGZpbmRfY2FsbF9vdXQoIlVwZGF0ZUF0dHJpYnV0ZXMiKT09LTEpCisgICAgICBjYWxsX291dCgiVXBkYXRlQXR0cmlidXRlcyIsMCk7IAorICB9Cit9CisKK3B1YmxpYyB2b2lkIEluc2VydFNlbnNpdGl2ZU9iamVjdChvYmplY3Qgb2IsIG1peGVkIGFyZykgeworICA6Okluc2VydFNlbnNpdGl2ZU9iamVjdChvYixhcmcpOworICBpZiAob2JqZWN0cChvYikgJiYgKG9iLT5RdWVyeVByb3AoUF9YX0FUVFJfTU9EKSAgIHx8CisgICAgICAgICAgICAgICAgICAgICAgb2ItPlF1ZXJ5UHJvcChQX1hfSEVBTFRIX01PRCkgKSkKKyAgeworICAgIHJlZ2lzdGVyX21vZGlmaWVyKG9iKTsKKyAgICBVcGRhdGVBdHRyaWJ1dGVzKCk7CisgIH0KK30KKworcHVibGljIHZvaWQgQ2hlY2tTZW5zaXRpdmVBdHRhY2soaW50IGRhbSwgbWl4ZWQgZGFtX3R5cGUsIG1peGVkIHNwZWxsLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdCBlbmVteSkgeworICBtaXhlZCBhLHg7CisgIGludCBpOworICAKKyAgaWYgKCFwb2ludGVycChhPVF1ZXJ5UHJvcChQX1NFTlNJVElWRV9BVFRBQ0spKSkKKyAgICByZXR1cm47CisgIGlmICghcG9pbnRlcnAoZGFtX3R5cGUpKQorICAgIGRhbV90eXBlPSh7ZGFtX3R5cGV9KTsKKyAgZm9yIChpPXNpemVvZihhKS0xO2k+PTA7aS0tKQorICAgIGlmIChwb2ludGVycCh4PWFbaV0pICYmCisJZGFtPnhbU0VOU19USFJFU0hPTERdICYmCisJbWVtYmVyKGRhbV90eXBlLHhbU0VOU19LRVldKT49MCAmJgorCW9iamVjdHAoeFtTRU5TX09CSkVDVF0pICYmCisJZW52aXJvbm1lbnQoeFtTRU5TX09CSkVDVF0pPT1NRSAmJgorCWNsb3N1cmVwKHhbU0VOU19DTE9TVVJFXSkpCisgICAgICBmdW5jYWxsKHhbU0VOU19DTE9TVVJFXSwKKwkgICAgICBlbmVteSx4W1NFTlNfS0VZXSxkYW0sCisJICAgICAgc3BlbGwseFtTRU5TX09QVF0pOworfQorCmRpZmYgLS1naXQgYS9zdGQvbGl2aW5nL2xpZmUuYyBiL3N0ZC9saXZpbmcvbGlmZS5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYzYTcyZjUKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvbGl2aW5nL2xpZmUuYwpAQCAtMCwwICsxLDE1NzIgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBsaXZpbmcvbGlmZS5jIC0tIGxpZmUgdmFyaWFibGVzCisvLworLy8gJElkOiBsaWZlLmMgOTQyNiAyMDE2LTAxLTAzIDEwOjAyOjU3WiBaZXNzdHJhICQKKworLy8gbGl2aW5nIG9iamVjdCBsaWZlIHZhcmlhYmxlcworLy8KKy8vICBQX0FMSUdOICAgICAgICAgLS0gYWxpZ25tZW50IHZhbHVlCisvLyAgUF9OUEMgICAgICAgICAgIC0tIGlmIGxpdmluZyBpcyBhbiBOUEMKKy8vICBQX0hQICAgICAgICAgICAgLS0gSGl0UG9pbnRzCisvLyAgUF9TUCAgICAgICAgICAgIC0tIFNwZWxsUG9pbnRzCisvLyAgUF9BTENPSE9MICAgICAgIC0tIHZhbHVlIG9mIGludG94aWNhdGlvbgorLy8gIFBfRFJJTksgICAgICAgICAtLSB2YWx1ZSBvZiBzb2FrbmVzcworLy8gIFBfRk9PRCAgICAgICAgICAtLSB2YWx1ZSBvZiBzdHVmZm5lc3MKKy8vICBQX1hQICAgICAgICAgICAgLS0gZXhwZXJpZW5jZQorLy8gIFBfUE9JU09OICAgICAgICAtLSBsZXZlbCBvZiBwb2lzb24KKy8vICBQX0NPUlBTRSAgICAgICAgLS0gY29ycHNlLW9iamVjdAorLy8gIFBfREVBRiAgICAgICAgICAtLSBpZiBsaXZpbmcgaXMgZGVhZgorI3ByYWdtYSBzdHJvbmdfdHlwZXMsc2F2ZV90eXBlcyxydHRfY2hlY2tzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8aG9vay5oPgorI2luY2x1ZGUgPGxpdmluZy9za2lsbHMuaD4KKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8bGl2aW5nL2xpZmUuaD4KKyNpbmNsdWRlIDxsaXZpbmcvbW92aW5nLmg+CisjaW5jbHVkZSA8bGl2aW5nL2NvbWJhdC5oPgorI2luY2x1ZGUgPGxpdmluZy9hdHRyaWJ1dGVzLmg+CisjaW5jbHVkZSA8dGhpbmcvZGVzY3JpcHRpb24uaD4KKyNpbmNsdWRlIDx0aGluZy9sYW5ndWFnZS5oPgorI3VuZGVmIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPGhlYWx0aC5oPgorI2luY2x1ZGUgPGRlZmluZXMuaD4KKyNpbmNsdWRlIDxuZXdfc2tpbGxzLmg+CisjaW5jbHVkZSA8c2NvcmVtYXN0ZXIuaD4KKyNpbmNsdWRlIDxkZWZ1ZWwuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8ZXZlbnRzLmg+CisjaW5jbHVkZSA8d2l6bGV2ZWxzLmg+CisKKyNkZWZpbmUgQUxDT0hPTF9WQUxVRShuKSBuCisKKyNpbmNsdWRlIDxkZWJ1Z19pbmZvLmg+IC8vdm9ydWViZXJnZWhlbmQKKworCisvLyAncHJpdmF0ZSctUHJvdG90eXBlbgorcHJpdmF0ZSB2b2lkIERpc3RyaWJ1dGVFeHAob2JqZWN0IGVuZW15LCBpbnQgZXhwX3RvX2dpdmUpOworCisvLyBWYXJpYWJsZW4KK25vc2F2ZSBpbnQgZGVsYXlfYWxjb2hvbDsgLyogdGltZSB1bnRpbCBuZXh0IGFsY29ob2wgZWZmZWN0ICovCitub3NhdmUgaW50IGRlbGF5X2RyaW5rOyAgIC8qIHRpbWUgdW50aWwgbmV4dCBkcmluayBlZmZlY3QgKi8KK25vc2F2ZSBpbnQgZGVsYXlfZm9vZDsgICAgLyogdGltZSB1bnRpbCBuZXh0IGZvb2QgZWZmZWN0ICovCitub3NhdmUgaW50IGRlbGF5X2hlYWw7ICAgIC8qIHRpbWUgdW50aWwgbmV4dCBoZWFsIGVmZmVjdCAqLworbm9zYXZlIGludCBkZWxheV9zcDsgICAgICAvKiB0aW1lIHVudGlsIG5leHQgc3AgcmVnZW5lcmF0aW9uICovCitub3NhdmUgaW50IGRlbGF5X3BvaXNvbjsgIC8qIHRpbWUgdW50aWwgbmV4dCBwb2lzb24gZWZmZWN0ICovCitub3NhdmUgaW50IGRyb3BfcG9pc29uOworbm9zYXZlIG1hcHBpbmcgZW5lbXlfZGFtYWdlOworbm9zYXZlIG1hcHBpbmcgaHBfYnVmZmVyOworbm9zYXZlIG1hcHBpbmcgc3BfYnVmZmVyOworbm9zYXZlIGludCByZW1vdmVfbWU7CitpbnQgbmV4dGRlZnVlbHRpbWVmb29kOworaW50IG5leHRkZWZ1ZWx0aW1lZHJpbms7CisKKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkKK3sKKyAgU2V0KFBfR0hPU1QsIFNBVkUsIEZfTU9ERSk7CisgIFNldChQX0ZST0csIFNBVkUsIEZfTU9ERSk7CisgIFNldChQX0FMSUdOLCBTQVZFLCBGX01PREUpOworICBTZXQoUF9IUCwgU0FWRSwgRl9NT0RFKTsKKyAgU2V0KFBfU1AsIFNBVkUsIEZfTU9ERSk7CisgIFNldChQX1hQLCBTQVZFLCBGX01PREUpOworICBTZXQoIFBfTEFTVF9YUCwgKHsgIiIsIDAgfSkgKTsKKyAgU2V0KCBQX0xBU1RfWFAsIFBST1RFQ1RFRCwgRl9NT0RFX0FTICk7CisKKyAgU2V0KFBfQUxDT0hPTCwgU0FWRSwgRl9NT0RFKTsKKyAgU2V0KFBfRFJJTkssIFNBVkUsIEZfTU9ERSk7CisgIFNldChQX0ZPT0QsIFNBVkUsIEZfTU9ERSk7CisgIFNldChQX1BPSVNPTiwgU0FWRSwgRl9NT0RFKTsKKyAgU2V0KFBfREVBRiwgU0FWRSwgRl9NT0RFKTsKKworICBTZXRQcm9wKFBfRk9PRF9ERUxBWSwgRk9PRF9ERUxBWSk7CisgIFNldFByb3AoUF9EUklOS19ERUxBWSwgRFJJTktfREVMQVkpOworICBTZXRQcm9wKFBfQUxDT0hPTF9ERUxBWSwgQUxDT0hPTF9ERUxBWSk7CisgIFNldFByb3AoUF9IUF9ERUxBWSxIRUFMX0RFTEFZKTsKKyAgU2V0UHJvcChQX1NQX0RFTEFZLEhFQUxfREVMQVkpOworICBTZXRQcm9wKFBfUE9JU09OX0RFTEFZLFBPSVNPTl9ERUxBWSk7CisgIC8vIGRlZmF1bHQgZnVlciBhbGxlIExlYmV3ZXNlbiAoTlBDICsgU3BpZWxlcik6CisgIFNldFByb3AoUF9NQVhfUE9JU09OLCAxMCk7CisgIFNldFByb3AoUF9DT1JQU0UsICIvc3RkL2NvcnBzZSIpOworCisgIG5leHRkZWZ1ZWx0aW1lZm9vZD10aW1lKCkrUXVlcnlQcm9wKFBfREVGVUVMX1RJTUVfRk9PRCk7CisgIG5leHRkZWZ1ZWx0aW1lZHJpbms9dGltZSgpK1F1ZXJ5UHJvcChQX0RFRlVFTF9USU1FX0RSSU5LKTsKKworICBlbmVteV9kYW1hZ2U9KFs6MiBdKTsKKyAgaHBfYnVmZmVyPShbXSk7CisgIHNwX2J1ZmZlcj0oW10pOworCisgIFNldFByb3AoUF9ERUZVRUxfTElNSVRfRk9PRCwxKTsKKyAgU2V0UHJvcChQX0RFRlVFTF9MSU1JVF9EUklOSywxKTsKKyAgU2V0UHJvcChQX0RFRlVFTF9USU1FX0ZPT0QsMSk7CisgIFNldFByb3AoUF9ERUZVRUxfVElNRV9EUklOSywxKTsKKyAgU2V0UHJvcChQX0RFRlVFTF9BTU9VTlRfRk9PRCwxKTsKKyAgU2V0UHJvcChQX0RFRlVFTF9BTU9VTlRfRFJJTkssMSk7CisKKyAgb2ZmZXJIb29rKEhfSE9PS19ESUUsMSk7CisKKyAgb2ZmZXJIb29rKEhfSE9PS19GT09ELDEpOworICBvZmZlckhvb2soSF9IT09LX0RSSU5LLDEpOworICBvZmZlckhvb2soSF9IT09LX0FMQ09IT0wsMSk7CisgIG9mZmVySG9vayhIX0hPT0tfUE9JU09OLDEpOworICBvZmZlckhvb2soSF9IT09LX0NPTlNVTUUsMSk7Cit9CisKKy8vIFdlbm4gZGVyIGxldHp0ZSBLYW1wZiBsYW5nIGhlciBpc3QgdW5kIGRhcyBMZWJld2VzZW4gd2llZGVyIHZvbGxnZWhlaWx0CisvLyBpc3QsIHdpcmQgUF9FTkVNWV9EQU1BR0UgenVydWVja2dlc2V0enQuCitwcm90ZWN0ZWQgdm9pZCBSZXNldEVuZW15RGFtYWdlKCkgeworICBpZiAodGltZSgpID4gUXVlcnlQcm9wKFBfTEFTVF9DT01CQVRfVElNRSkgKyBfX1JFU0VUX1RJTUVfXyAqIDQKKyAgICAgICYmIFF1ZXJ5UHJvcChQX0hQKSA9PSBRdWVyeVByb3AoUF9NQVhfSFApKQorICAgIGVuZW15X2RhbWFnZT0oWzoyIF0pOworfQorCitwcml2YXRlIHZvaWQgRGlzdHJpYnV0ZUV4cChvYmplY3QgZW5lbXksIGludCBleHBfdG9fZ2l2ZSkgeworICBpbnQgdG90YWxfZGFtYWdlLCB0bXAsIGV4OworICBtYXBwaW5nIHByZXNlbnRfZW5lbWllczsKKworICBpZiAoIGV4cF90b19naXZlPD0wICkKKyAgICByZXR1cm47CisKKyAgbWFwcGluZyBlbmRtZz1kZWVwX2NvcHkoZW5lbXlfZGFtYWdlKTsKKworICAvLyBNaXRnbGllZGVyIGltIFRlYW0gZGVzIEtpbGxlcnMgYmVrb21tZW46CisgIC8vCisgIC8vICAgICAgICAgICAgICAgICAgR2VzYW10YW50ZWlsIGRlcyBUZWFtcworICAvLyBFaWdlbmVuIEFudGVpbCArIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gICAgICAgICAgICAgICAgICBBbnphaGwgIFRlYW1taXRnbGllZGVyCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyAgICAgICAgICAgICAgICAyCisgIC8vCisgIG9iamVjdCAqaW52ID0gZW5lbXktPlRlYW1NZW1iZXJzKCk7CisgIGlmICggcG9pbnRlcnAoaW52KSApCisgIHsKKyAgICBwcmVzZW50X2VuZW1pZXM9bV9hbGxvY2F0ZShzaXplb2YoaW52KSwgMSk7CisgICAgZm9yZWFjaChvYmplY3Qgb2I6IGludikKKyAgICB7CisgICAgICBpZiAoIG9iamVjdHAob2IpICYmIChlbnZpcm9ubWVudChvYik9PWVudmlyb25tZW50KCkpICkKKyAgICAgIHsKKyAgICAgICAgdG1wPWVuZG1nW29iamVjdF9uYW1lKG9iKV07CisgICAgICAgIHRvdGFsX2RhbWFnZSs9dG1wOworICAgICAgICBwcmVzZW50X2VuZW1pZXNbb2JdID0gdG1wLzI7CisgICAgICAgIG1fZGVsZXRlKGVuZG1nLG9iamVjdF9uYW1lKG9iKSk7IC8vcy51LgorICAgICAgfQorICAgIH0KKyAgICBpbnQgbWl0Z2xpZWRlciA9IHNpemVvZihwcmVzZW50X2VuZW1pZXMpOworICAgIGlmICggbWl0Z2xpZWRlciApCisgICAgeworICAgICAgdG1wPXRvdGFsX2RhbWFnZS8oMiptaXRnbGllZGVyKTsKKyAgICAgIGZvcmVhY2gob2JqZWN0IG9iLCBpbnQgcHVua3RlOiAmcHJlc2VudF9lbmVtaWVzKQorICAgICAgICBwdW5rdGUgKz0gdG1wOworICAgIH0KKyAgfQorICBlbHNlIHsKKyAgICAvLyBvaG5lIFRlYW0gd2lyZCB0cm90emRlbSBlaW4gTWFwcGluZyBnZWJyYXVjaHQuIERhIEdyb2Vzc2VudmVyYWVuZGVydW5nCisgICAgLy8gcmVsLiB0ZXVlciBzaW5kLCBrYW5uIGVpbmZhY2ggbWFsIGZ1ZXIgMyBFaW50cmFlZ2UgUGxhdHogcmVzZXJ2aWVyZW4uCisgICAgcHJlc2VudF9lbmVtaWVzPW1fYWxsb2NhdGUoMywgMSk7CisgIH0KKyAgLy8gVW5kIG5vY2ggZGllIExlYmV3ZXNlbiBpbSBSYXVtIG9obmUgVGVhbS4KKyAgZm9yZWFjaChvYmplY3Qgb2I6IGFsbF9pbnZlbnRvcnkoZW52aXJvbm1lbnQoKSkpCisgIHsKKyAgICBpZiAoIHRtcD1lbmRtZ1tvYmplY3RfbmFtZShvYildICkKKyAgICB7CisgICAgICB0b3RhbF9kYW1hZ2UgKz0gdG1wOworICAgICAgcHJlc2VudF9lbmVtaWVzW29iXSA9IHRtcDsKKyAgICAgIG1fZGVsZXRlKGVuZG1nLG9iamVjdF9uYW1lKG9iKSk7IC8vIE51ciBlaW5tYWwgcHJvIExlYmVuIFB1bmt0ZSA6KQorICAgIH0KKyAgfQorICBpZiAoICF0b3RhbF9kYW1hZ2UgKQorICB7CisgICAgZW5lbXktPkFkZEV4cChleHBfdG9fZ2l2ZSk7CisgIH0KKyAgZWxzZQorICB7CisgICAgZm9yZWFjaChvYmplY3Qgb2IsIGludCBkYW1hZ2U6IHByZXNlbnRfZW5lbWllcykKKyAgICB7CisgICAgICBpZiAoICFvYmplY3RwKG9iKSApCisgICAgICAgIGNvbnRpbnVlOworICAgICAgaWYgKCBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKG9iKSAmJiAoICFpbnRlcmFjdGl2ZShvYikKKyAgICAgICAgICAgICAgfHwgKHF1ZXJ5X2lkbGUob2IpPjYwMCkgKSApCisgICAgICAgIGNvbnRpbnVlOworICAgICAgLy9leHBfdG9fZ2l2ZSpwcmVzZW50X2VuZW1pZXNbaV1bMV0vdG90YWxfZGFtYWdlIGdpYnQgYmVpIHZpZWwgU2NoYWRlbgorICAgICAgLy9laW5lbiBudW1lcmljYWwgb3ZlcmZsb3cuIERhaGVyIG11ZXNzZW4gd2lyIGhpZXIgd29obCBkb2NoCisgICAgICAvL3p3aXNjaGVuemVpdGxpY2ggbWl0IGZsb2F0cyByZWNobmVuLCBhdWNoIHdlbm4gZGFzIDAtMSBYUCBWZXJsdXN0CisgICAgICAvL2R1cmNoIGZsb2F0LT5pbnQtS29udmVyc2lvbiBnaWJ0LiAoY2VpbCgpIGxvaG50IHNpY2ggSU1ITyBuaWNodC4pCisgICAgICBleCA9IChpbnQpKGV4cF90b19naXZlKigoZmxvYXQpZGFtYWdlLyhmbG9hdCl0b3RhbF9kYW1hZ2UpKTsKKyAgICAgIG9iLT5BZGRFeHAoZXgpOworICAgIH0KKyAgfQorfQorCisvKgorICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgZnJvbSBvdGhlciBwbGF5ZXJzIHdoZW4gdGhleSB3YW50IHRvIG1ha2UKKyAqIGRhbWFnZSB0byB1cy4gQnV0IGl0IHdpbGwgb25seSBiZSBjYWxsZWQgaW5kaXJlY3RseS4KKyAqIFdlIHJldHVybiBob3cgbXVjaCBkYW1hZ2Ugd2UgcmVjZWl2ZWQsIHdoaWNoIHdpbGwKKyAqIGNoYW5nZSB0aGUgYXR0YWNrZXJzIHNjb3JlLiBUaGlzIHJvdXRpbmUgaXMgcHJvYmFibHkgY2FsbGVkIGZyb20KKyAqIGhlYXJ0X2JlYXQoKSBmcm9tIGFub3RoZXIgcGxheWVyLgorICogQ29tcGFyZSB0aGlzIGZ1bmN0aW9uIHRvIHJlZHVjZV9oaXRfcG9pbnRzKGRhbSkuCisgKi8KK3B1YmxpYyBpbnQgZG9fZGFtYWdlKGludCBkYW0sIG9iamVjdCBlbmVteSkKK3sgaW50IGhpdF9wb2ludCxhbCxhbDI7CisKKyAgaWYgKCBleHRlcm5fY2FsbCgpCisgICAgICAmJiBvYmplY3RwKGVuZW15KQorICAgICAgJiYgbGl2aW5nKGVuZW15KQorICAgICAgJiYgIVF1ZXJ5UHJvcChQX0VOQUJMRV9JTl9BVFRBQ0tfT1VUKSkKKyAgeworICAgIGFsPXRpbWUoKS1lbmVteS0+UXVlcnlQcm9wKFBfTEFTVF9NT1ZFKTsKKyAgICBpZiAoYWw8MykgICAgICAvLyBFcnN0ZSBLYW1wZnJ1bmRlIG5hY2ggQmV0cmV0ZW4gZGVzIFJhdW1lcz8KKyAgICAgIGRhbS89KDQtYWwpOyAvLyBHZWdlbiBSZWluLUZldWVyYmFsbC1SYXVzLVRha3RpaworICB9CisKKyAgaWYgKCBRdWVyeVByb3AoUF9HSE9TVCkgfHwgUXVlcnlQcm9wKFBfTk9fQVRUQUNLKSB8fCAoZGFtPD0wKQorICAgICAgfHwgKCBvYmplY3RwKGVuZW15KQorICAgICAgICAgICYmICggZW5lbXktPlF1ZXJ5UHJvcChQX0dIT1NUKQorICAgICAgICAgICAgICB8fCBlbmVteS0+UXVlcnlQcm9wKFBfTk9fQVRUQUNLKSApICkgKQorICAgIHJldHVybiAwOworCisgIGhpdF9wb2ludCA9IFF1ZXJ5UHJvcChQX0hQKS1kYW07CisKKyAgaWYgKCBRdWVyeVByb3AoUF9YUCkgJiYgb2JqZWN0cChlbmVteSkgKQorICB7CisgICAgaWYgKCAhUXVlcnlQcm9wKFBfTk9fWFApICkKKyAgICAgIGVuZW15LT5BZGRFeHAoZGFtKihpbnQpUXVlcnlQcm9wKFBfVE9UQUxfV0MpLzEwKTsKKyAgfQorCisgIGlmIChsaXZpbmcoZW5lbXkpKSB7CisgICAgICBzdHJpbmcgZW5uYW1lID0gb2JqZWN0X25hbWUoZW5lbXkpOworICAgICAgLy8gSG1wZi4gQmx1ZXByaW50cyBzaW5kIGRvb2YuIERpZSBDaGFuY2UgaXN0IHp3YXIgZ2VyaW5nLCBhYmVyIGtvZW5udGUKKyAgICAgIC8vIHNlaW4sIGRhc3MgZWluIFVuaXF1ZS1OUEMgbWl0IHp3ZWkgdmVyc2NoaWVkZW5lbiBTcGllbGVybiBhbSBnbGVpY2hlbgorICAgICAgLy8gTlBDIG1ldHplbHQuCisgICAgICAvLyBUT0RPOiBNSG1tLiB3aWUgZ3Jvc3MgaXN0IGRhcyBSaXNpa28gd2lya2xpY2g/CisgICAgICAvL2lmICghY2xvbmVwKGVuZW15KSkKKyAgICAgIC8vICAgIGVubmFtZSA9IGVubmFtZSArICJfIiArIHRvX3N0cmluZyhvYmplY3RfdGltZShlbmVteSkpOworICAgICAgLy8gbnVyIHdlbm4gZ2VnbmVyIE5QQyBpc3QgdW5kIG5vY2ggbmljaHQgZHJpbnN0ZWh0OiBEYXRlbiBhdXMKKyAgICAgIC8vIFBfSEVMUEVSX05QQyBhdXN3ZXJ0ZW4KKyAgICAgIGlmICghbWVtYmVyKGVuZW15X2RhbWFnZSxlbmVteSkgJiYgIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoZW5lbXkpKSB7CisgICAgICAgICAgbWl4ZWQgaGVscGVyID0gZW5lbXktPlF1ZXJ5UHJvcChQX0hFTFBFUl9OUEMpOworICAgICAgICAgIGlmIChwb2ludGVycChoZWxwZXIpICYmIG9iamVjdHAoaGVscGVyWzBdKSkKKyAgICAgICAgICAgICAgZW5lbXlfZGFtYWdlW2VubmFtZSwxXSA9IGhlbHBlclswXTsKKyAgICAgIH0KKyAgICAgIGVuZW15X2RhbWFnZVtlbm5hbWUsMF0rPWRhbTsKKyAgfQorCisgIFNldFByb3AoUF9IUCwgaGl0X3BvaW50KTsKKworICBpZiAoIGhpdF9wb2ludDwwICkKKyAgeworICAgIC8vVE9ETzogV2FydW0gbmljaHQgZGFzIGdhbnplIFpldWcgaW5zIGRpZSgpIHZlcmxlZ2VuPworICAgIGlmICggZW5lbXkgKQorICAgIHsKKyAgICAgIGVuZW15LT5TdG9wSHVudEZvcihNRSwxKTsKKyAgICAgIGlmICggIVF1ZXJ5UHJvcChQX05PX1hQKSApCisgICAgICAgIERpc3RyaWJ1dGVFeHAoZW5lbXksUXVlcnlQcm9wKFBfWFApLzEwMCk7CisgICAgICBpZiAoICFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKE1FKSApCisgICAgICAgIGxvZ19maWxlICgiTlBDX1hQIiwgc3ByaW50ZigKKwkgICAgIlslc10gJXMsIFhQOiAlZCwgSFAqV0M6ICVkLCBLaWxsZXI6ICVzXG4iLAorCSAgICBkdGltZSh0aW1lKCkpLCBvYmplY3RfbmFtZShNRSksIChRdWVyeVByb3AoUF9YUCkvMTAwKSwKKyAgICAgICAgICAgICAgICAgIFF1ZXJ5UHJvcChQX1RPVEFMX1dDKSpRdWVyeVByb3AoUF9NQVhfSFApLzEwLAorICAgICAgICAgICAgICAgICAgZW5lbXktPm5hbWUoKXx8Ik5vTmFtZSIgKSk7CisgICAgICBhbCA9IFF1ZXJ5UHJvcChQX0FMSUdOKS81MCArIGVuZW15LT5RdWVyeVByb3AoUF9BTElHTikvMjAwOworICAgICAgaWYgKGFsPjIwKQorICAgICAgICBhbD0yMDsKKyAgICAgIGVsc2UgaWYoYWw8LTIwKQorICAgICAgICBhbD0tMjA7CisgICAgICBlbmVteS0+U2V0UHJvcChQX0FMSUdOLGVuZW15LT5RdWVyeVByb3AoUF9BTElHTiktYWwpOworICAgIH0KKyAgICBTZXRQcm9wKFBfS0lMTEVSLCBlbmVteSk7CisgICAgCisgICAgZGllKCk7CisgIH0KKyAgcmV0dXJuIGRhbTsKK30KKworCitwcml2YXRlIHZvaWQgX3RyYW5zZmVyKCBvYmplY3QgKm9icywgc3RyaW5nfG9iamVjdCBkZXN0LCBpbnQgZmxhZyApCit7ICAgaW50IGk7CisKKyAgICBpID0gc2l6ZW9mKG9icyk7CisKKyAgICAvLyBFaW5lIFNjaGxlaWZlIGlzdCB6d2FyIGxhbmdzYW1lciBhbHMgZmlsdGVyKCkgby5hZS4sIGFiZXIKKyAgICAvLyBzZWxic3QgbWl0IGVpbmVyIG5vY2ggc28gc2NobmVsbGVuIExvZXN1bmcga2FubiBsZWlkZXIgbmljaHQKKyAgICAvLyBhdXNnZXNjaGxvc3NlbiB3ZXJkZW4sIGRhc3MgaXJnZW5kd28gZWluIHRvby1sb25nLWV2YWwtQnVnIGRhendpc2NoZW4KKyAgICAvLyBrb21tdC4gRGF6dSBzaW5kIGRpZSBLYWVtcGZlIG1pdCBHaWxkZW4tTlBDcyBldGMuIGVpbmZhY2ggenUgdGV1ZXIgLi4uCisgICAgLy8gUHJ1ZWZ1bmcgYXVmIHplcnN0b2VydGUgT2JqZWt0ZSwgZGEgZWluaWdlIHNpY2ggZXZ0bC4gaW0gTm90aWZ5UGxheWVyRGVhdGgoKSAKKyAgICAvLyB6ZXJzdG9lcmVuLgorICAgd2hpbGUgKCBpICYmIGdldF9ldmFsX2Nvc3QoKSA+IDMwMDAwMCApCisgICAgICAgIGlmICggb2JqZWN0cChvYnNbLS1pXSkgJiYgIW9ic1tpXS0+UXVlcnlQcm9wKFBfTkVWRVJEUk9QKSApCisgICAgICAgIC8vIEpldHp0IHdpcmQncyBub2NoIGV0d2FzIHRldXJlciBtaXQgY2F0Y2goKSAtIGFiZXIgbWFuY2hlIFNhY2hlbgorICAgICAgICAvLyBkdWVyZmVuIGVpbmZhY2ggbmljaHQgYnVnZ2VuCisgICAgICAgICAgICBjYXRjaCggb2JzW2ldLT5tb3ZlKCBkZXN0LCBmbGFnICk7cHVibGlzaCApOworCisgICAgaWYgKCBpID4gMCApCisgICAgICAgIC8vIFp1dmllbCBSZWNoZW56ZWl0IHZlcmJyYXRlbiwgZXMgbXVlc3NlbiBub2NoIE9iamVrdGUgYmV3ZWd0IHdlcmRlbgorICAgICAgICBjYWxsX291dCggIydfdHJhbnNmZXIsIDAsIG9ic1swLi5pLTFdLCBkZXN0LCBmbGFnICk7CisgICAgZWxzZSB7CisgICAgICAgIGlmICggcmVtb3ZlX21lICkKKyAgICAgICAgICAgIHJlbW92ZSgpOworICAgIH0KK30KKworCitwdWJsaWMgdmFyYXJncyB2b2lkIHRyYW5zZmVyX2FsbF90byggc3RyaW5nfG9iamVjdCBkZXN0LCBpbnQgaXNucGMgKSB7CisgICAgaW50IGZsYWdzOworICAgIG9iamVjdCAqb2JzOworCisgICAgaWYgKCAhb2JqZWN0cChNRSkgKQorICAgICAgICByZXR1cm47CisKKyAgICAvLyBEYXMgRmxhZyAiaXNucGMiIGlzdCBmdWVyIE5QQ3MgZ2VkYWNodC4gRGVyZW4gQXVzcnVlc3R1bmcgZGFyZiBuaWNodAorICAgIC8vIG1pdCBNX05PQ0hFQ0sgYmV3ZWd0IHdlcmRlbiwgZGEgU3BpZWxlciBkYXMgYmVpIE5pY2h0LVN0YW5kYXJkLUxlaWNoZW4KKyAgICAvLyBzb25zdCB1LlUuIGF1c251dHplbiBrb2VubnRlbi4KKyAgICBpZiAoIGlzbnBjICkKKyAgICAgICAgZmxhZ3MgPSBNX1NJTEVOVDsKKyAgICBlbHNlCisgICAgICAgIGZsYWdzID0gTV9TSUxFTlR8TV9OT0NIRUNLOworCisgICAgb2JzID0gYWxsX2ludmVudG9yeShNRSkgfHwgKHt9KTsKKworICAgIC8vIHVubm9ldGlnLCB3ZWlsIF90cmFuc2ZlcigpIGF1Y2ggYXVmIFBfTkVWRVJEUk9QIHBydWVmdC4gWmVzc3RyYQorICAgIC8vb2JzIC09IGZpbHRlcl9vYmplY3RzKCBvYnMsICJRdWVyeVByb3AiLCBQX05FVkVSRFJPUCApOworCisgICAgX3RyYW5zZmVyKCBvYnMsIGRlc3QsIGZsYWdzICk7Cit9CisKKworcHJvdGVjdGVkIHZhcmFyZ3Mgdm9pZCBjcmVhdGVfa2lsbF9sb2dfZW50cnkoc3RyaW5nIGtpbGxlciwgb2JqZWN0IGVuZW15KSB7CisgIGludCBsZXZlbCxsb3N0X2V4cDsKKworICBpZiAoIChsZXZlbD1RdWVyeVByb3AoUF9MRVZFTCkpPDIwIHx8ICFJU19TRUVSKE1FKSApCisgICAgbG9zdF9leHAgPSBRdWVyeVByb3AoUF9YUCkvMzsKKyAgZWxzZQorICAgIGxvc3RfZXhwID0gUXVlcnlQcm9wKFBfWFApLyhsZXZlbC0xNyk7CisgIAorICBsb2dfZmlsZSgiS0lMTFMiLHNwcmludGYoIiVzICVzICglZCwlZCkgJXNcbiIsIHN0cmZ0aW1lKCIlZSAlYiAlSDolTSIpLAorICAgICAgICAgICAgICAgY2FwaXRhbGl6ZShSRUFMX1VJRChNRSkpLCBsZXZlbCwgbG9zdF9leHAvMTAwMCwga2lsbGVyKSk7IAorfQorCisvLyBMaWVmZXJ0IGltIFRvZCAobmFjaCBkZW0gdG9ldGVuZGVuIGRvX2RhbWFnZSgpKSBkYXMgU3BpZWxlcm9iamVrdCwgd2FzIGRlbgorLy8gVG9kIHdvaGwgenUgdmVyYW50d29ydGVuIGhhdCwgZmFsbHMgZXMgZXJtaXR0ZWx0IHdlcmRlbiBrYW5uLiBFcyB3ZXJkZW4gdm9yCisvLyBhbGxlbSByZWdpc3RyaWVydGUgSGVsZmVyLU5QQyB1bmQgZWluaWdlIFNvbmRlcm9iamVrdGUgYmVydWVja3NpY2h0aWd0LgorcHJvdGVjdGVkIG9iamVjdCBnZXRfa2lsbGluZ19wbGF5ZXIoKQoreworICBvYmplY3Qga2lsbGVyPVF1ZXJ5UHJvcChQX0tJTExFUik7CisgIC8vIGtvZW5udGUgc2Vpbiwgd2VubiBhdXNzZXJoYWxiIGRlcyBUb2RlcyBnZXJ1ZmVuIG9kZXIgZWluZSBWZXJnaWZ0dW5nIHVucworICAvLyB1bWdlYnJhY2h0IGhhdC4KKyAgaWYgKCFvYmplY3RwKGtpbGxlcikpCisgICAgcmV0dXJuIDA7CisKKyAgd2hpbGUgKGtpbGxlciAmJiAhcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShraWxsZXIpKQorICAgIGtpbGxlciA9IGtpbGxlci0+UXVlcnlVc2VyKCk7CisKKyAgcmV0dXJuIGtpbGxlcjsKK30KKworcHJvdGVjdGVkIG9iamVjdCBHaXZlS2lsbFNjb3JlKG9iamVjdCBwbCwgaW50IG5wY251bSkKK3sKKyAgLy8gU3R1ZmVucHVua3QgZnVlciBkZW4gS2lsbCB2ZXJnZWJlbi4KKyAgLy8gRmFsbHMgZGVyIEtpbGxlciBkZW4gUHVua3Qgc2Nob24gaGF0LCB3aXJkCisgIC8vIHp1ZmFlbGxpZyBlaW4gTWl0Z2xpZWQgc2VpbmVzIFRlYW1zIGF1c2dld2FlaGx0CisgIC8vIHVuZCBkaWVzZW0gZGVyIFB1bmt0IGdlZ2ViZW4uCisgIG9iamVjdCAqb2JzLG9iOworICBtaXhlZCAqZnI7CisgIGludCBpLGosc3o7CisKKyAgaWYgKCBwb2ludGVycChvYnM9cGwtPlRlYW1NZW1iZXJzKCkpICYmIChtZW1iZXIob2JzLHBsKT49MCkgKQorICB7CisgICAgaWYgKCAhcG9pbnRlcnAoZnI9cGwtPlByZXNlbnRUZWFtUm93cygpKQorICAgICAgICB8fCAhc2l6ZW9mKGZyKQorICAgICAgICB8fCAhcG9pbnRlcnAoZnI9ZnJbMF0pKSAvLyBFcnN0ZSBSZWloZSBkZXMgVGVhbXMKKyAgICAgIGZyPSh7fSk7CisgICAgZnItPSh7cGwsMH0pOworICAgIG9icy09KHtwbCwwfSk7CisgICAgb2JzLT1mcjsKKyAgICBpPXN6PXNpemVvZihvYnMpOyAvLyByZXN0bGljaGUgVGVhbW1pdGdsaWVkZXIgaW4genVmYWVsbGlnZXIgUmVpaGVuZm9sZ2U6CisgICAgZm9yICggLS1pIDsgaT49MCA7IGktLSApCisgICAgeworICAgICAgaj1yYW5kb20oc3opOworICAgICAgb2I9b2JzW2pdOworICAgICAgb2JzW2pdPW9ic1swXTsKKyAgICAgIG9ic1swXT1vYjsKKyAgICB9CisgICAgaT1zej1zaXplb2YoZnIpOyAgLy8gRXJzdGUgUmVpaGUgaW4genVmYWVsbGlnZXIgUmVpaGVuZm9sZ2U6CisgICAgZm9yICggLS1pIDsgaT49MCA7IGktLSApCisgICAgeworICAgICAgaj1yYW5kb20oc3opOworICAgICAgb2I9ZnJbal07CisgICAgICBmcltqXT1mclswXTsKKyAgICAgIGZyWzBdPW9iOworICAgIH0KKworICAgIG9icys9ZnI7ICAgICAvLyBFcnN0ZSBSZWloZSB3aXJkIHZvciBSZXN0IGdldGVzdGV0CisgICAgb2JzKz0oe3BsfSk7IC8vIEtpbGxlciB3aXJkIGFscyBlcnN0ZXMgZ2V0ZXN0ZXQKKyAgfQorICBlbHNlCisgIHsKKyAgICBvYnM9KHtwbH0pOworICB9CisgIGZvciAoIGk9c2l6ZW9mKG9icyktMSA7IGk+PTAgOyBpLS0gKQorICAgIGlmICggb2JqZWN0cChvYj1vYnNbaV0gKQorICAgICAgICAmJiBpbnRlcmFjdGl2ZShvYikgICAgIC8vIE51ciBuZXR6dG90IGRhYmVpIHN0ZWhlbiBnaWx0IG5pY2h0IDopCisgICAgICAgICYmIHF1ZXJ5X2lkbGUob2IpPDYwMCAgLy8gZ2VnZW4gTGV1dGUgZGllIHNpY2ggbnVyIG1pdHNjaGxlcHBlbiBsYXNzZW4KKyAgICAgICAgJiYgZW52aXJvbm1lbnQob2IpPT1lbnZpcm9ubWVudChwbCkgLy8gTnVyIGFud2VzZW5kZSBUZWFtbWl0Z2xpZWRlcgorICAgICAgICAmJiAhSVNfTEVBUk5FUihvYikKKy8vICAgICAgICAmJiAhb2ItPlF1ZXJ5UHJvcChQX1RFU1RQTEFZRVIpCisgICAgICAgICYmICEoU0NPUkVNQVNURVItPkhhc0tpbGwob2IsTUUpKSApCisgICAgICByZXR1cm4gU0NPUkVNQVNURVItPkdpdmVLaWxsKG9iLG5wY251bSksb2I7CisKKyAgcmV0dXJuIFNDT1JFTUFTVEVSLT5HaXZlS2lsbChwbCxucGNudW0pLHBsOworfQorCisvLyB6dW0gdWViZXJzY2hyZWliZW4gaW4gU3BpZWxlcm4KK3B1YmxpYyBpbnQgZGVhdGhfc3VmZmVyaW5nKCkgeworICByZXR1cm4gMDsgLy8gTlBDIGhhYmVuIGtlaW5lIFRvZGVzZm9sZ2VuCit9CisKKy8vIGtlaW4gMi4gTGViZW4gZnVlciBOaWNodC1TcGllbGVyLiA7LSkKK3ZhcmFyZ3MgcHJvdGVjdGVkIGludCBzZWNvbmRfbGlmZSggb2JqZWN0IGNvcnBzZSApIHsKKyAgICByZXR1cm4gMDsKK30KKworcHVibGljIHZhcmFyZ3Mgdm9pZCBkaWUoIGludCBwb2lzb25kZWF0aCwgaW50IGV4dGVybiApCit7ICAgb2JqZWN0IGNvcnBzZTsKKyAgICBzdHJpbmcgZGllX21zZywgdG1wOworICAgIG1peGVkIHJlczsKKyAgICBtaXhlZCBob29rRGF0YTsKKyAgICBtaXhlZCBob29rUmVzOworCisgICAgaWYgKCAhb2JqZWN0cCh0aGlzX29iamVjdCgpKSB8fCBRdWVyeVByb3AoUF9HSE9TVCkgKQorICAgICAgICByZXR1cm47IC8vIEdob3N0cyBkb250IGRpZSAuLi4KKworICAgIC8vIGRpcmVrdCB2b24gZXh0ZXJuIGF1ZmdlcnVmZW4gdW5kIG5pY2h0IHVlYmVyIGhlYXJ0X2JlYXQoKSBvZGVyCisgICAgLy8gZG9fZGFtYWdlKCkgaGllcmhlciBnZWxhbmd0PworICAgIGlmIChleHRlcm5fY2FsbCgpICYmIHByZXZpb3VzX29iamVjdCgpICE9IHRoaXNfb2JqZWN0KCkpIHsKKyAgICAgIGV4dGVybj0xOworICAgICAgU2V0UHJvcChQX0tJTExFUiwgcHJldmlvdXNfb2JqZWN0KCkpOworICAgIH0KKworICAgIGlmICggcmVzID0gUXVlcnlQcm9wKFBfVE1QX0RJRV9IT09LKSApeworICAgICAgICBpZiAoIHBvaW50ZXJwKHJlcykgJiYgc2l6ZW9mKHJlcyk+PTMKKyAgICAgICAgICAgICYmIGludHAocmVzWzBdKSAmJiB0aW1lKCk8cmVzWzBdCisgICAgICAgICAgICAmJiBvYmplY3RwKHJlc1sxXSkgJiYgc3RyaW5ncChyZXNbMl0pICkKKyAgICAgICAgeworICAgICAgICAgICAgaWYgKCByZXMgPSBjYWxsX290aGVyKCByZXNbMV0sIHJlc1syXSwgcG9pc29uZGVhdGggKSApIHsKKyAgICAgICAgICAgICAgU2V0UHJvcChQX0tJTExFUiwwKTsKKyAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIFNldFByb3AoUF9UTVBfRElFX0hPT0ssMCk7CisgICAgfQorCisgICAgLy8gdHJpZ2dlciBkaWUgaG9vaworICAgIGhvb2tEYXRhPXBvaXNvbmRlYXRoOworICAgIGhvb2tSZXM9SG9va0Zsb3coSF9IT09LX0RJRSxob29rRGF0YSk7CisgICAgaWYgKHBvaW50ZXJwKGhvb2tSZXMpICYmIHNpemVvZihob29rUmVzKT5IX1JFVERBVEEpeworICAgICAgaWYoaG9va1Jlc1tIX1JFVENPREVdPT1IX0NBTkNFTExFRCkgeworICAgICAgICBTZXRQcm9wKFBfS0lMTEVSLDApOworICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgICBlbHNlIGlmIChob29rUmVzW0hfUkVUQ09ERV09PUhfQUxURVJFRCkKKyAgICAgICAgICBwb2lzb25kZWF0aCA9IGhvb2tSZXNbSF9SRVREQVRBXTsKKyAgICB9CisKKyAgICBpZiAoIElTX0xFQVJOSU5HKE1FKSAmJiBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKE1FKSApeworICAgICAgIHRlbGxfb2JqZWN0KCBNRSwgIlNlaSBmcm9oIGRhc3MgRHUgdW5zdGVyYmxpY2ggYmlzdCwgc29uc3Qgd2FlcmUgZXMgIgorICAgICAgICAgICAgICAgICAgICAgICAgImViZW4gRGVpbiBFbmRlIGdld2VzZW4uXG4iKTsKKyAgICAgICBTZXRQcm9wKFBfS0lMTEVSLDApOworICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICAvLyBHZWduZXIgYmVmcmllZGVuLgorICAgIG1hcF9vYmplY3RzKCBRdWVyeUVuZW1pZXMoKVswXSwgIlN0b3BIdW50Rm9yIiwgTUUsIDEgKTsKKyAgICBTdG9wSHVudGluZ01vZGUoMSk7CisKKyAgICAvLyBGYWxscyBkaWUoKSBkaXJla3QgYXVmZ2VydWZlbiB3dXJkZSB1bmQgZGllcyBlaW4gU3BpZWxlciBpc3QsIG11c3MgZGFzCisgICAgLy8gZGllKCkgbm9jaCBFaW50cmFlZ2UgaW4gL2xvZy9LSUxMUyB2aWEgY3JlYXRlX2tpbGxfbG9nX2VudHJ5IGJ6dy4gaW4KKyAgICAvLyAvbG9nL0tJTExFUiBlcnN0ZWxsZW4uCisgICAgaWYgKCBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKE1FKSAmJiBleHRlcm4gKQorICAgIHsKKyAgICAgIG9iamVjdCBraWxsZXIgPSBRdWVyeVByb3AoUF9LSUxMRVIpIAorICAgICAgICAgICAgICAgICAgICAgfHwgcHJldmlvdXNfb2JqZWN0KCkgfHwgdGhpc19pbnRlcmFjdGl2ZSgpIHx8IHRoaXNfcGxheWVyKCk7CisgICAgICBpZiAoIGtpbGxlciAmJiAhcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShraWxsZXIpICkKKyAgICAgIHsKKyAgICAgICAgICB0bXAgPSBleHBsb2RlKCBvYmplY3RfbmFtZShraWxsZXIpLCAiIyIpWzBdICsgIiAoZGlyZWt0ICEpIjsKKworICAgICAgICAgIGNyZWF0ZV9raWxsX2xvZ19lbnRyeSggdG1wICsgIiAoIiArIFJFQUxfVUlEKGtpbGxlcikgKyAiKSIsIGtpbGxlciApOworICAgICAgfQorICAgICAgZWxzZSBpZiAoIGtpbGxlciAmJiAhUXVlcnlQcm9wKFBfVEVTVFBMQVlFUikgJiYgIUlTX0xFQVJORVIoTUUpICkKKyAgICAgIHsKKyAgICAgICAgICBsb2dfZmlsZSggIktJTExFUiIsIHNwcmludGYoICIlcyAlcyAoJWQvJWQpIHRvZXRldGUgJXMgKCVkLyVkKVxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0aW1lKHRpbWUoKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXBpdGFsaXplKGdldHVpZChraWxsZXIpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1ZXJ5X3dpel9sZXZlbChraWxsZXIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2lsbGVyLT5RdWVyeVByb3AoUF9MRVZFTCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXBpdGFsaXplKGdldHVpZChNRSkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVlcnlfd2l6X2xldmVsKE1FKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFF1ZXJ5UHJvcChQX0xFVkVMKSApICk7CisKKyAgICAgICAgICBraWxsZXItPlNldFByb3AoIFBfS0lMTFMsIC0xICk7CisgICAgICB9CisgICAgfQorCisgIC8vIEJlaSBOUEMgRUtzIHZlcmdlYmVuIHVuZCBnZ2YuIGluIGRlciBHaWxkZSBkZXMgS2lsbGVycyB1bmQgaW0gUmF1bQorICAvLyBOUENfS2lsbGVkX0J5KCkgcnVmZW4uCisgIGlmICggIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoTUUpICkKKyAgeworICAgIG9iamVjdCBraWxsZXIgPSAoKG9iamVjdCkgUXVlcnlQcm9wKFBfS0lMTEVSKSkgfHwgcHJldmlvdXNfb2JqZWN0KCkgfHwKKyAgICAgIHRoaXNfaW50ZXJhY3RpdmUoKSB8fCB0aGlzX3BsYXllcigpOworCisgICAgaWYgKCBraWxsZXIgJiYgcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShraWxsZXIpICkKKyAgICB7CisgICAgICBpZiAoc3RyaW5ncChyZXM9a2lsbGVyLT5RdWVyeVByb3AoUF9HVUlMRCkpCisgICAgICAgICAgJiYgb2JqZWN0cChyZXM9ZmluZF9vYmplY3QoIi9naWxkZW4vIityZXMpKSkKKyAgICAgICAgcmVzLT5OUENfS2lsbGVkX0J5KGtpbGxlcik7CisKKyAgICAgIGlmIChlbnZpcm9ubWVudCgpKQorICAgICAgICAgIGVudmlyb25tZW50KCktPk5QQ19LaWxsZWRfQnkoa2lsbGVyKTsKKworICAgICAgcmVzID0gUXVlcnlQcm9wKFBfWFApOworICAgICAgcmVzID0gKHJlcyA8IFNDT1JFX0xPV19NQVJLKSA/IDAgOiAoKHJlcyA+IFNDT1JFX0hJR0hfTUFSSykgPyAyIDogMSk7CisgICAgICBpZiAoICFRdWVyeVByb3AoUF9OT19TQ09SRSkgJiYgIUlTX0xFQVJORVIoa2lsbGVyKSAmJgorICAgICAgICAgICAvLyAha2lsbGVyLT5RdWVyeVByb3AoUF9URVNUUExBWUVSKSAmJgorICAgICAgICAgICBwb2ludGVycCggcmVzID0gU0NPUkVNQVNURVItPlF1ZXJ5TlBDKHJlcykpICkKKyAgICAgICAgR2l2ZUtpbGxTY29yZSgga2lsbGVyLCByZXNbMF0gKTsKKyAgICB9CisgIH0KKworICBpZiggIShkaWVfbXNnID0gUXVlcnlQcm9wKFBfRElFX01TRykpICkKKyAgICBpZiAoUXVlcnlQcm9wKFBfUExVUkFMKSkKKyAgICAgIGRpZV9tc2cgPSAiIGZhbGxlbiB0b3QgenUgQm9kZW4uXG4iOworICAgIGVsc2UKKyAgICAgIGRpZV9tc2cgPSAiIGZhZWxsdCB0b3QgenUgQm9kZW4uXG4iOworCisgIGlmICggcG9pc29uZGVhdGggKQorICB7CisgICAgICBTZXQoIFBfTEFTVF9EQU1UWVBFUywgKHsgRFRfUE9JU09OIH0pICk7CisgICAgICBTZXQoIFBfTEFTVF9EQU1USU1FLCB0aW1lKCkgKTsKKyAgICAgIFNldCggUF9MQVNUX0RBTUFHRSwgMSApOworICAgICAgZGllX21zZyA9ICIgd2lyZCB2b24gR2lmdCBoaW53ZWdnZXJhZmZ0IHVuZCBraXBwdCB1bS5cbiI7CisgIH0KKworICBzYXkoIGNhcGl0YWxpemUobmFtZShXRVIsMSkpICsgZGllX21zZyApOworCisgIC8vIFdlbm4ga2VpbmUgTGVpY2hlLCBkYW5uIEtyYW0gaW5zIEVudiBsZWdlbi4KKyAgaWYgKCBRdWVyeVByb3AoUF9OT0NPUlBTRSkgfHwgISh0bXAgPSBRdWVyeVByb3AoUF9DT1JQU0UpKQorICAgICAgfHwgY2F0Y2goY29ycHNlID0gY2xvbmVfb2JqZWN0KHRtcCk7cHVibGlzaCkgCisgICAgICB8fCAhb2JqZWN0cChjb3Jwc2UpICkKKyAgeworICAgICAgLy8gTWFnaWVyIG9kZXIgVGVzdHNwaWVsZXIgYmVoYWx0ZW4gaWhyZSBBdXNydWVzdHVuZy4KKyAgICAgIC8vIFNvbnN0IGthZW1lbiB1LlUuIFNwaWVsZXIgYW4gTWFnaWVydG9vbHMgZXRjLiBoZXJhbgorICAgICAgaWYgKCAhKElTX0xFQVJORVIoTUUpIHx8ICh0bXAgPSBRdWVyeShQX1RFU1RQTEFZRVIpKSAmJgorICAgICAgICAgICAgICghc3RyaW5ncCh0bXApIHx8IElTX0xFQVJORVIoIGxvd2VyX2Nhc2UodG1wKSApKSkgKQorICAgICAgICAgIHRyYW5zZmVyX2FsbF90byggZW52aXJvbm1lbnQoKSwgMCApOworICAgICAgZWxzZQorICAgICAgICAgIC8vIEFiZXIgc2llIHppZWhlbiBzaWNoIGF1cy4KKyAgICAgICAgICBmaWx0ZXJfb2JqZWN0cyhRdWVyeVByb3AoUF9BUk1PVVJTKSwiRG9VbndlYXIiLE1fTk9DSEVDSywwKTsKKyAgfQorICBlbHNlCisgIC8vIHNvbnN0IGluIGRpZSBMZWljaGUgbGVnZW4uCisgIHsKKyAgICAgIGNvcnBzZS0+SWRlbnRpZnkoTUUpOworICAgICAgY29ycHNlLT5tb3ZlKCBlbnZpcm9ubWVudCgpLCBNX05PQ0hFQ0t8TV9TSUxFTlQgKTsKKyAgICAgIC8vIE1hZ2llciBvZGVyIFRlc3RzcGllbGVyIGJlaGFsdGVuIGlocmUgQXVzcnVlc3R1bmcuCisgICAgICAvLyBTb25zdCBrYWVtZW4gdS5VLiBTcGllbGVyIGFuIE1hZ2llcnRvb2xzIGV0Yy4gaGVyYW4KKyAgICAgIGlmICggIShJU19MRUFSTkVSKE1FKSB8fCAodG1wID0gUXVlcnkoUF9URVNUUExBWUVSKSkgJiYKKyAgICAgICAgICAgICAoIXN0cmluZ3AodG1wKSB8fCBJU19MRUFSTkVSKCBsb3dlcl9jYXNlKHRtcCkgKSkpICkKKyAgICAgICAgICB0cmFuc2Zlcl9hbGxfdG8oIGNvcnBzZSwgIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoTUUpICk7CisgICAgICBlbHNlCisgICAgICAgICAgLy8gQWJlciBzaWUgemllaGVuIHNpY2ggYXVzLgorICAgICAgICAgIGZpbHRlcl9vYmplY3RzKFF1ZXJ5UHJvcChQX0FSTU9VUlMpLCJEb1Vud2VhciIsTV9OT0NIRUNLLDApOworICB9CisKKyAgaWYgKCBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKE1FKSApIHsKKyAgICAgIFNldCggUF9ERUFEUywgUXVlcnkoUF9ERUFEUykgKyAxICk7CisgICAgICAvLyBTcGllbGVyLVRvZC1ldmVudCBhdXNsb2VzZW4KKyAgICAgIEVWRU5URC0+VHJpZ2dlckV2ZW50KEVWVF9MSUJfUExBWUVSX0RFQVRILCAoWworICAgICAgRV9PQkpFQ1Q6IE1FLCBFX1BMTkFNRTogZ2V0dWlkKE1FKSwKKyAgICAgIEVfRU5WSVJPTk1FTlQ6IGVudmlyb25tZW50KCksIEVfVElNRTogdGltZSgpLAorICAgICAgUF9LSUxMRVI6IFF1ZXJ5UHJvcChQX0tJTExFUiksCisgICAgICBQX0xBU1RfREFNQUdFOiBRdWVyeVByb3AoUF9MQVNUX0RBTUFHRSksCisgICAgICBQX0xBU1RfREFNVFlQRVM6IGNvcHkoUXVlcnlQcm9wKFBfTEFTVF9EQU1UWVBFUykpLAorICAgICAgRV9FWFRFUk5BTF9ERUFUSDogZXh0ZXJuLAorICAgICAgRV9QT0lTT05fREVBVEg6IHBvaXNvbmRlYXRoLCAKKyAgICAgIEVfQ09SUFNFOiAob2JqZWN0cChjb3Jwc2UpP2NvcnBzZTowKSBdKSApOworICB9CisgIGVsc2UgeworICAgICAgLy8gTlBDLVRvZGVzLUV2ZW50IGF1c2xvZXNlbi4gRGl2LiBNYXBwaW5ncy9BcnJheXMgd2VyZGVuIG5pY2h0IGtvcGllcnQsCisgICAgICAvLyB3ZWlsIGRlciBOUEMgamEgamV0enQgZWggemVyc3RvZXJ0IHdpcmQuCisgICAgICBtYXBwaW5nIGRhdGEgPSAoWworICAgICAgICAgICAgRV9PQk5BTUU6IG9iamVjdF9uYW1lKE1FKSwKKyAgICAgICAgICAgIEVfRU5WSVJPTk1FTlQ6IGVudmlyb25tZW50KCksIEVfVElNRTogdGltZSgpLAorICAgICAgICAgICAgUF9OQU1FOiBRdWVyeVByb3AoUF9OQU1FKSwKKyAgICAgICAgICAgIFBfS0lMTEVSOiBRdWVyeVByb3AoUF9LSUxMRVIpLAorICAgICAgICAgICAgUF9FTkVNWV9EQU1BR0U6IFF1ZXJ5UHJvcChQX0VORU1ZX0RBTUFHRSksCisgICAgICAgICAgICBQX0xBU1RfREFNQUdFOiBRdWVyeVByb3AoUF9MQVNUX0RBTUFHRSksCisgICAgICAgICAgICBQX0xBU1RfREFNVFlQRVM6IFF1ZXJ5UHJvcChQX0xBU1RfREFNVFlQRVMpLAorICAgICAgICAgICAgRV9FWFRFUk5BTF9ERUFUSDogZXh0ZXJuLAorICAgICAgICAgICAgRV9QT0lTT05fREVBVEg6IHBvaXNvbmRlYXRoLAorICAgICAgICAgICAgRV9DT1JQU0U6IChvYmplY3RwKGNvcnBzZSk/Y29ycHNlOjApLAorICAgICAgICAgICAgUF9YUDogUXVlcnlQcm9wKFBfWFApLAorICAgICAgICAgICAgUF9BVFRSSUJVVEVTOiBRdWVyeVByb3AoUF9BVFRSSUJVVEVTKSwKKyAgICAgICAgICAgIFBfTUFYX0hQOiBRdWVyeVByb3AoUF9NQVhfSFApLAorICAgICAgICAgICAgUF9IQU5EUzogUXVlcnlQcm9wKFBfSEFORFMpLAorICAgICAgICAgICAgUF9BTElHTjogUXVlcnlQcm9wKFBfQUxJR04pLAorICAgICAgICAgICAgUF9SQUNFOiBRdWVyeVByb3AoUF9SQUNFKSwKKyAgICAgICAgICAgIFBfQ0xBU1M6IFF1ZXJ5UHJvcChQX0NMQVNTKSwKKyAgICAgICAgICAgIF0pOworICAgICAgRVZFTlRELT5UcmlnZ2VyRXZlbnQoRVZUX0xJQl9OUENfREVBVEgoIiIpLCBkYXRhKTsKKyAgICAgIEVWRU5URC0+VHJpZ2dlckV2ZW50KAorICAgICAgICAgIEVWVF9MSUJfTlBDX0RFQVRIKGxvYWRfbmFtZShNRSkpLCBkYXRhKTsKKyAgfQorCisgIC8vIHRyYW5zZmVyX2FsbF90bygpIGlzdCBldnRsLiAod2VubiB6dXZpZWxlIE9iamVrdGUgYmV3ZWd0IHdlcmRlbiBtdXNzdGVuKQorICAvLyBub2NoIG5pY2h0IGdhbnogZmVydGlnIHVuZCB3aXJkIHBlciBjYWxsX291dCgpIGRlbiBSZXN0IGVybGVkaWdlbi4KKyAgLy8gU29sbHRlIGRpZSBMZWljaGUgZGFubiBuaWNodCBtZWhyIGV4aXN0aWVyZW4sIHZlcmJsZWliZW4gZGllIHJlc3RsaWNoZW4KKyAgLy8gT2JqZWt0ZSBpbSBTcGllbGVyLgorICAvLyBFcyBibGVpYmVuIGFiZXIgYXVmIGplZGVuIEZhbGwgbm9jaCBydW5kIDMwMGsgRXZhbC1UaWNrcyB1ZWJlciwgZGFtaXQKKyAgLy8ga2VpbiBTcGllbGVyIGRhbmsgImV2YWxjb3N0IHRvbyBoaWdoIiB1bmdlc2Nob3JlbiBkYXZvbiBrb21tdC4KKyAgaWYgKCAhKHNlY29uZF9saWZlKGNvcnBzZSkpICkKKyAgeworICAgICAgU2V0KCBQX0dIT1NULCAxICk7IC8vIEZ1ZXIga29ycmVrdGUgQXVzZ2FiZSBhdWYgVGVhbWthbmFsLgorCisgICAgICBpZiAoIGZpbmRfY2FsbF9vdXQoIydfdHJhbnNmZXIpID09IC0xICkKKyAgICAgICAgICAvLyBGYWxscyBrZWluIGNhbGxfb3V0KCkgbWVociBsYWV1ZnQsIHNvZm9ydCBkZXN0cnVjdGVuIC4uLgorICAgICAgICAgIHJlbW92ZSgpOworICAgICAgZWxzZQorICAgICAgICAgIC8vIC4uLiBhbnNvbnN0ZW4gdm9ybWVya2VuCisgICAgICAgICAgcmVtb3ZlX21lID0gMTsKKyAgfQorfQorCitwdWJsaWMgdm9pZCBoZWFsX3NlbGYoaW50IGgpCit7CisgIGlmICggaDw9MCApCisgICAgcmV0dXJuOworICBTZXRQcm9wKFBfSFAsIFF1ZXJ5UHJvcChQX0hQKStoKTsKKyAgU2V0UHJvcChQX1NQLCBRdWVyeVByb3AoUF9TUCkraCk7Cit9CisKKworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8KKy8vICAgaW50IGRlZnVlbF9mb29kKCAvKiB2b2lkICovICkKKy8vCisvLyAgIEVudHRhbmt0IGRlbiBTcGllbGVyIHVtIGVpbmVuIGdld2lzc2VuIEVzc2Vucy1XZXJ0LgorLy8gICBTb2xsdGUgbnVyIHZvbiBUb2lsZXR0ZW4gYXVmZ2VydWZlbiB3ZXJkZW4uCisvLworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorcHVibGljIGludCBkZWZ1ZWxfZm9vZCgpCit7CisgIGludCBmb29kOworCisgIGZvb2Q9UXVlcnlQcm9wKFBfRk9PRCk7CisKKy8vIHdlbm4gc3BpZWxlciBrZWluIGZvb2QgaGF0OiByZXR1cm4gMAorICBpZiAoICFmb29kICkKKyAgIHJldHVybiBOT19ERUZVRUw7CisKKy8vIHdlbm4gc3BpZWxlciB1bnRlciBlbnR0YW5rLWdyZW56ZTogcmV0dXJuIC0xCisgIGlmICggZm9vZCA8IFF1ZXJ5UHJvcChQX0RFRlVFTF9MSU1JVF9GT09EKSApCisgICByZXR1cm4gREVGVUVMX1RPT19MT1c7CisKKy8vIHdlbm4gbGV0enRlcyBlbnR0YW5rZW4gbmljaHQgbGFuZ2UgZ2VudWcgenVydWVja2xpZWd0OiByZXR1cm4gLTIKKyAgaWYgKCB0aW1lKCkgPCBuZXh0ZGVmdWVsdGltZWZvb2QgKQorICAgcmV0dXJuIERFRlVFTF9UT09fU09PTjsKKworICBmb29kPXRvX2ludCgoKGZvb2QqUXVlcnlQcm9wKFBfREVGVUVMX0FNT1VOVF9GT09EKSkvMikpOworICBmb29kKz1yYW5kb20oZm9vZCk7CisKKy8vIHNpY2hlcmhlaXRzaGFsYmVyCisgIGlmICggZm9vZCA+IFF1ZXJ5UHJvcChQX0ZPT0QpICkKKyAgIGZvb2Q9UXVlcnlQcm9wKFBfRk9PRCk7CisKKyAgU2V0UHJvcChQX0ZPT0QsKFF1ZXJ5UHJvcChQX0ZPT0QpLWZvb2QpKTsKKworICBuZXh0ZGVmdWVsdGltZWZvb2Q9dGltZSgpK1F1ZXJ5UHJvcChQX0RFRlVFTF9USU1FX0ZPT0QpOworCisgIHJldHVybiBmb29kOworfQorCisKKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vCisvLyAgIGludCBkZWZ1ZWxfZHJpbmsoIC8qIHZvaWQgKi8gKQorLy8KKy8vICAgRW50dGFua3QgZGVuIFNwaWVsZXIgdW0gZWluZW4gZ2V3aXNzZW4gRmx1ZXNzaWdrZWl0cy1XZXJ0LgorLy8gICBHbGVpY2h6ZWl0aWcgd2lyZCBlaW5lIGdld2lzc2UgTWVuZ2UgQWxrb2hvbCByZWR1emllcnQuCisvLyAgIFNvbGx0ZSBudXIgdm9uIFRvaWxldHRlbiBhdWZnZXJ1ZmVuIHdlcmRlbi4KKy8vCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitwdWJsaWMgaW50IGRlZnVlbF9kcmluaygpCit7CisgIGludCBhbGMsIGRyaW5rOworCisgIGRyaW5rPVF1ZXJ5UHJvcChQX0RSSU5LKTsKKworLy8gd2VubiBzcGllbGVyIGtlaW4gZHJpbmsgaGF0OiByZXR1cm4gMAorICBpZiAoICFkcmluayApCisgICByZXR1cm4gTk9fREVGVUVMOworCisvLyB3ZW5uIHNwaWVsZXIgdW50ZXIgZW50dGFuay1ncmVuemU6IHJldHVybiAtMQorICBpZiAoIGRyaW5rIDwgUXVlcnlQcm9wKFBfREVGVUVMX0xJTUlUX0RSSU5LKSApCisgICByZXR1cm4gREVGVUVMX1RPT19MT1c7CisKKy8vIHdlbm4gbGV0enRlcyBlbnR0YW5rZW4gbmljaHQgbGFuZ2UgZ2VudWcgenVydWVja2xpZWd0OiByZXR1cm4gLTIKKyAgaWYgKCB0aW1lKCkgPCBuZXh0ZGVmdWVsdGltZWRyaW5rICkKKyAgIHJldHVybiBERUZVRUxfVE9PX1NPT047CisgICAgCisgIGRyaW5rPXRvX2ludCgoKGRyaW5rKlF1ZXJ5UHJvcChQX0RFRlVFTF9BTU9VTlRfRFJJTkspKS8yKSk7CisgIGRyaW5rKz1yYW5kb20oZHJpbmspOworCisvLyBzaWNoZXJoZWl0c2hhbGJlcgorICBpZiAoIGRyaW5rID4gUXVlcnlQcm9wKFBfRFJJTkspICkKKyAgIGRyaW5rPVF1ZXJ5UHJvcChQX0RSSU5LKTsKKworICBTZXRQcm9wKFBfRFJJTkssKFF1ZXJ5UHJvcChQX0RSSU5LKS1kcmluaykpOworCisvLyBqZWRlcyBmbHVlc3NpZ2UgRW50dGFua2VuIG1hY2h0IGF1Y2ggZXR3YXMgbnVlY2h0ZXJuZXIgOl4pCisvLyBiZWkgc2VociBrbGVpbmVuIE1lbmdlbiBlbnR0YW5rdCBtYW4ga2VpbmVuIEFsa29ob2wKKy8vIGFuc29uc3RlbiBpbiBBYmhhZW5naWdrZWl0IHZvbiBlbnR0YW5rdGVyIE1lbmdlLCBQX0FMQ09IT0wgdW5kIFBfV0VJR0hUCisKKyAgaWYgKCBkcmluayA+IDkgJiYgUXVlcnlQcm9wKFBfQUxDT0hPTCkgPiAwICkKKyAgIHsKKyAgICBhbGM9KHRvX2ludChleHAobG9nKDEuMSkqKGRyaW5rKSkpKgorICAgICAgICAgdG9faW50KGV4cChsb2coMC42NykqKFF1ZXJ5UHJvcChQX0FMQ09IT0wpKSkpKS8KKyAgICAgICAgIChRdWVyeVByb3AoUF9NQVhfRFJJTkspKlF1ZXJ5UHJvcChQX01BWF9BTENPSE9MKSkqCisgICAgICAgICAodG9faW50KFF1ZXJ5UHJvcChQX1dFSUdIVCkvMTAwMCkpOworCisgICAgIFNldFByb3AoUF9BTENPSE9MLFF1ZXJ5UHJvcChQX0FMQ09IT0wpLShhbGMrcmFuZG9tKGFsYykpKTsKKyAgIH0KKworICBuZXh0ZGVmdWVsdGltZWRyaW5rPXRpbWUoKStRdWVyeVByb3AoUF9ERUZVRUxfVElNRV9EUklOSyk7CisgCisgIHJldHVybiBkcmluazsKK30KKworCitwdWJsaWMgdm9pZCByZWR1Y2Vfc3BlbGxfcG9pbnRzKGludCBoKQoreworICBTZXRQcm9wKFBfU1AsIFF1ZXJ5UHJvcChQX1NQKS1oKTsKK30KKworcHVibGljIHZvaWQgcmVzdG9yZV9zcGVsbF9wb2ludHMoaW50IGgpCit7CisgIFNldFByb3AoUF9TUCwgUXVlcnlQcm9wKFBfU1ApK2gpOworfQorCisvKiBSZWR1Y2UgaGl0cG9pbnRzLiBMb2cgd2hvIGlzIGRvaW5nIGl0LiAqLworcHVibGljIGludCByZWR1Y2VfaGl0X3BvaW50cyhpbnQgZGFtKQoreyBvYmplY3QgbzsKKyAgaW50IGk7CisKKyNpZmRlZiBMT0dfUkVEVUNFX0hQCisgIGlmICh0aGlzX3BsYXllcigpIT1NRSkKKyAgeworICAgIGxvZ19maWxlKCJSRURVQ0VfSFAiLCBuYW1lKCkrIiBieSAiKTsKKyAgICBpZighdGhpc19wbGF5ZXIoKSkgbG9nX2ZpbGUoIlJFRFVDRV9IUCIsIj9cbiIpOworICAgIGVsc2UgeworICAgICAgbG9nX2ZpbGUoIlJFRFVDRV9IUCIsdGhpc19wbGF5ZXIoKS0+bmFtZSgpKTsKKyAgICAgIG89cHJldmlvdXNfb2JqZWN0KCk7CisgICAgICBpZiAobykKKyAgICAgICAgbG9nX2ZpbGUoIlJFRFVDRV9IUCIsICIgIiArIG9iamVjdF9uYW1lKG8pICsgIiwgIiArCisgICAgICAgICAgICAgICAgIG8tPm5hbWUoV0VSLDApICsgIiAoIiArIGNyZWF0b3IobykgKyAiKVxuIik7CisgICAgICBlbHNlCisgICAgICAgIGxvZ19maWxlKCJSRURVQ0VfSFAiLCAiID8/XG4iKTsKKyAgICB9CisgIH0KKyNlbmRpZgorICBpZiAoKGk9UXVlcnlQcm9wKFBfSFApKSA8PSBkYW0pCisgICAgcmV0dXJuIFNldFByb3AoUF9IUCwxKTsKKyAgcmV0dXJuIFNldFByb3AoUF9IUCwgaSAtIGRhbSk7Cit9CisKK3B1YmxpYyBpbnQgcmVzdG9yZV9oaXRfcG9pbnRzKGludCBoZWFsKQoreworICByZXR1cm4gcmVkdWNlX2hpdF9wb2ludHMoLWhlYWwpOworfQorCitwdWJsaWMgdmFyYXJncyBpbnQgZHJpbmtfYWxjb2hvbChpbnQgc3RyZW5ndGgsaW50IHRlc3Rvbmx5LCBzdHJpbmcgbXl0ZXh0KQoreyBpbnQgYWxjLGFkZCxyZXM7CisKKyAgYWRkPUFMQ09IT0xfVkFMVUUoc3RyZW5ndGgpOworICByZXM9VXNlU2tpbGwoU0tfQk9PWkUsKFsKKyAgICAgIFNJX1NLSUxMQVJHIDogYWRkLAorICAgICAgU0lfVEVTVEZMQUcgOiAxXSkpOyAvLyBLYW5uIGRlciBTcGllbGVyIGd1dCBzYXVmZW4/CisgIGlmIChpbnRwKHJlcykgJiYgcmVzPjApIGFkZD1yZXM7CisgIGFsYz1RdWVyeVByb3AoUF9BTENPSE9MKSthZGQ7CisgIGlmICgoYWxjID49IFF1ZXJ5UHJvcChQX01BWF9BTENPSE9MKSkgJiYgIUlTX0xFQVJOSU5HKHRoaXNfb2JqZWN0KCkpKXsKKyAgICBpZighdGVzdG9ubHkpCisgICAgICB0ZWxsX29iamVjdChNRSxteXRleHR8fCJTbyBlaW4gUGVjaCwgRHUgaGFzdCBhbGxlcyB2ZXJzY2h1ZXR0ZXQuXG4iKTsKKyAgICByZXR1cm4gMDsKKyAgfQorICBpZih0ZXN0b25seSlyZXR1cm4gMTsKKyAgVXNlU2tpbGwoU0tfQk9PWkUsKFsgU0lfU0tJTExBUkcgOiBBTENPSE9MX1ZBTFVFKHN0cmVuZ3RoKSBdKSk7CisgIGlmKGFsYyA8IDApIGFsYyA9IDA7CisgIGlmKCFhbGMpIHRlbGxfb2JqZWN0KE1FLCAiRHUgYmlzdCBzdG9ja251ZWNodGVybi5cbiIpOworICBTZXRQcm9wKFBfQUxDT0hPTCwgYWxjKTsKKyAgcmV0dXJuIDE7Cit9CisKK3B1YmxpYyB2YXJhcmdzIGludCBkcmlua19zb2Z0KGludCBzdHJlbmd0aCwgaW50IHRlc3Rvbmx5LCBzdHJpbmcgbXl0ZXh0KQoreyBpbnQgc29ha2VkOworCisgIHNvYWtlZCA9IFF1ZXJ5UHJvcChQX0RSSU5LKTsKKyAgaWYoKHNvYWtlZCArIHN0cmVuZ3RoID4gUXVlcnlQcm9wKFBfTUFYX0RSSU5LKSkgJiYKKyAgICAgIUlTX0xFQVJOSU5HKHRoaXNfb2JqZWN0KCkpKXsKKyAgICBpZighdGVzdG9ubHkpCisgICAgIHRlbGxfb2JqZWN0KE1FLCBteXRleHR8fAorICAgICAgICJOZWUsIHNvIHZpZWwga2FubnN0IER1IG1vbWVudGFuIGVjaHQgbmljaHQgdHJpbmtlbi5cbiIgKTsKKyAgICByZXR1cm4gMDsKKyAgfQorICBpZih0ZXN0b25seSlyZXR1cm4gMTsKKyAgaWYoKHNvYWtlZCArPSBEUklOS19WQUxVRShzdHJlbmd0aCkpIDwgMCkgc29ha2VkID0gMDsKKyAgaWYoIXNvYWtlZCkgdGVsbF9vYmplY3QoTUUsICJEaXIga2xlYnQgZGllIFp1bmdlIGFtIEdhdW1lbi5cbiIpOworICBTZXRQcm9wKFBfRFJJTkssIHNvYWtlZCk7CisgIHJldHVybiAxOworfQorCitwdWJsaWMgdmFyYXJncyBpbnQgZWF0X2Zvb2QoaW50IHN0cmVuZ3RoLCBpbnQgdGVzdG9ubHksIHN0cmluZyBteXRleHQpCit7IGludCBzdHVmZmVkOworCisgIHN0dWZmZWQgPSBRdWVyeVByb3AoUF9GT09EKTsKKyAgaWYgKChzdHVmZmVkICsgc3RyZW5ndGggPiBRdWVyeVByb3AoUF9NQVhfRk9PRCkpICYmCisgICAgICAhSVNfTEVBUk5JTkcodGhpc19vYmplY3QoKSkpCisgIHsKKyAgICBpZighdGVzdG9ubHkpCisgICAgICAgIHRlbGxfb2JqZWN0KE1FLAorICAgICAgICAgICAgbXl0ZXh0IHx8ICJEYXMgaXN0IHZpZWwgenUgdmllbCBmdWVyIERpY2ghIFdpZSB3YWVycyBtaXQgZXR3YXMgIgorICAgICAgICAgICAgImxlaWNodGVyZW0/XG4iKTsKKyAgICByZXR1cm4gMDsKKyAgfQorICBpZih0ZXN0b25seSlyZXR1cm4gMTsKKyAgc3R1ZmZlZCArPSBGT09EX1ZBTFVFKHN0cmVuZ3RoKTsKKyAgaWYoc3R1ZmZlZCA8IDApIHN0dWZmZWQgPSAwOworICBpZighc3R1ZmZlZCkgdGVsbF9vYmplY3QoTUUsICJXYXMgcnVtcGVsdCBkZW5uIGRhIGluIERlaW5lbSBCYXVjaD9cbiIpOworICBTZXRQcm9wKFBfRk9PRCwgc3R1ZmZlZCk7CisgIHJldHVybiAxOworfQorCitwdWJsaWMgaW50IGJ1ZmZlcl9ocChpbnQgdmFsLGludCByYXRlKQoreworICBpbnQgZGlmOworCisgIGlmKHZhbDw9MCB8fCByYXRlPD0wKXJldHVybiAwOworICBpZih2YWwgPCByYXRlKXJhdGUgPSB2YWw7CisgIGlmKHJhdGU+MjApIHJhdGU9MjA7CisKKyAgLyogQ2hlY2sgZm9yIEJ1ZmZlck92ZXJmbG93ICovCisgIGlmKChkaWY9KGhwX2J1ZmZlclswXSt2YWwpLVF1ZXJ5UHJvcChQX01BWF9IUCkpID4gMCl2YWwtPWRpZjsKKyAgaWYodmFsPD0wKXJldHVybiAwOworCisgIGhwX2J1ZmZlclswXSArPSB2YWw7CisgIGhwX2J1ZmZlclsxK3JhdGVdICs9IHZhbDsKKyAgaWYocmF0ZSA+IGhwX2J1ZmZlclsxXSlocF9idWZmZXJbMV0gPSByYXRlOworCisgIHJldHVybiBocF9idWZmZXJbMF07Cit9CisKK3B1YmxpYyBpbnQgYnVmZmVyX3NwKGludCB2YWwsaW50IHJhdGUpCit7CisgIGludCBkaWY7CisKKyAgaWYodmFsPD0wIHx8IHJhdGU8PTApcmV0dXJuIDA7CisgIGlmKHZhbCA8IHJhdGUpcmF0ZSA9IHZhbDsKKyAgaWYocmF0ZT4yMCkgcmF0ZT0yMDsKKworICAvKiBDaGVjayBmb3IgQnVmZmVyT3ZlcmZsb3cgKi8KKyAgaWYoKGRpZj0oc3BfYnVmZmVyWzBdK3ZhbCktUXVlcnlQcm9wKFBfTUFYX1NQKSkgPiAwKXZhbC09ZGlmOworICBpZih2YWw8PTApcmV0dXJuIDA7CisKKyAgc3BfYnVmZmVyWzBdICs9IHZhbDsKKyAgc3BfYnVmZmVyWzErcmF0ZV0gKz0gdmFsOworICBpZihyYXRlID4gc3BfYnVmZmVyWzFdKXNwX2J1ZmZlclsxXSA9IHJhdGU7CisKKyAgcmV0dXJuIHNwX2J1ZmZlclswXTsKK30KKworcHJvdGVjdGVkIHZvaWQgdXBkYXRlX2J1ZmZlcnMoKQoreyBpbnQgaSwgcmF0ZSwgbWF4OworCisgIHJhdGU9MDsKKyAgbWF4PTA7CisgIGZvcihpPTE7aTw9MjA7aSsrKXsKKyAgICBpZihtZW1iZXIoaHBfYnVmZmVyLCBpKzEpKQorICAgICAgaWYoaHBfYnVmZmVyW2krMV08PTApCisgICAgICAgIGhwX2J1ZmZlciA9IG1fZGVsZXRlKGhwX2J1ZmZlcixpKzEpOworICAgICAgZWxzZXsKKyAgICAgICAgbWF4Kz1ocF9idWZmZXJbaSsxXTsKKyAgICAgICAgcmF0ZT1pOworICAgICAgfQorICB9CisKKyAgaHBfYnVmZmVyWzBdPW1heDsKKyAgaHBfYnVmZmVyWzFdPXJhdGU7CisgIHJhdGU9MDsKKyAgbWF4PTA7CisgIGZvcihpPTE7aTw9MjA7aSsrKXsKKyAgICBpZihtZW1iZXIoc3BfYnVmZmVyLCBpKzEpKQorICAgICAgaWYoc3BfYnVmZmVyW2krMV08PTApCisgICAgICAgIHNwX2J1ZmZlciA9IG1fZGVsZXRlKHNwX2J1ZmZlcixpKzEpOworICAgICAgZWxzZXsKKyAgICAgICAgbWF4Kz1zcF9idWZmZXJbaSsxXTsKKyAgICAgICAgcmF0ZT1pOworICAgICAgfQorICB9CisgIHNwX2J1ZmZlclswXT1tYXg7CisgIHNwX2J1ZmZlclsxXT1yYXRlOworfQorCitwdWJsaWMgaW50IGNoZWNrX3RpbWVkX2tleShzdHJpbmcga2V5KSB7CisKKyAgLy8ga2VpbmUgMCBhbHMga2V5IChUeXAgd2lyZCBwZXIgUlRUQyBnZXBydWVmdCkKKyAgaWYgKCFrZXkpCisgICAgcmV0dXJuIDA7CisgIG1hcHBpbmcgdG1hcD1RdWVyeShQX1RJTUlOR19NQVAsIEZfVkFMVUUpOworICBpZiAoIW1hcHBpbmdwKHRtYXApKSB7CisgICAgdG1hcD0oW10pOworICAgIFNldChQX1RJTUlOR19NQVAsIHRtYXAsIEZfVkFMVUUpOworICB9CisgIC8vIFdlbm4ga2V5IG5vY2ggbmljaHQgYWJnZWxhdWZlbiwgQWJsYXVmemVpdHB1bmt0IHp1cnVlY2tnZWJlbi4KKyAgLy8gU29uc3QgMCAoa2V5IGZyZWkpCisgIHJldHVybiAodGltZSgpIDwgdG1hcFtrZXldKSAmJiB0bWFwW2tleV07Cit9CisKK3B1YmxpYyBpbnQgY2hlY2tfYW5kX3VwZGF0ZV90aW1lZF9rZXkoaW50IGR1cmF0aW9uLHN0cmluZyBrZXkpIHsKKworICAvLyB3ZW5uIGtleSBub2NoIGdlc3BlcnJ0LCBkaWUgemVpdCBkZXIgbmFlY2hzdGVuIFZlcmZ1ZWdiYXJrZWl0CisgIC8vIHp1cnVlY2tnZWJlbi4KKyAgaW50IHJlcyA9IGNoZWNrX3RpbWVkX2tleShrZXkpOworICBpZiAocmVzKSB7CisgICAgcmV0dXJuIHJlczsKKyAgfQorCisgIC8vIGR1cmF0aW9uIDw9IDAgaXN0IHVuc2lubmlnLiBBYmVyIGtleSBpc3QgbmljaHQgbWVociBnZXNwZXJydCwgZC5oLiB0aW1lKCkKKyAgLy8gaXN0IGVpbiBzaW5udm9sbGVyIFJ1ZWNrZ2FiZXdlcnQuCisgIGlmIChkdXJhdGlvbiA8PSAwKQorICAgIHJldHVybiB0aW1lKCk7CisgCisgIG1hcHBpbmcgdG1hcCA9IFF1ZXJ5KFBfVElNSU5HX01BUCxGX1ZBTFVFKTsKKyAgdG1hcFtrZXldPXRpbWUoKStkdXJhdGlvbjsKKyAgCisgIC8vIHNwZWljaGVybiBwZXIgU2V0UHJvcCgpIHVubm9ldGlnLCBkYSBtYW4gZGFzIE1hcHBpbmcgZGlyZWt0IGFlbmRlcnQsCisgIC8vIGtlaW5lIEtvcGllLgorICAvL1NldFByb3AoUF9USU1JTkdfTUFQLCB0bWFwKTsKKyAgCisgIHJldHVybiAtMTsgLy8gRXJmb2xnLgorfQorCitwcm90ZWN0ZWQgdm9pZCBleHBpcmVfdGltaW5nX21hcCgpIHsKKyAgCisgIG1hcHBpbmcgdG1hcCA9IFF1ZXJ5KFBfVElNSU5HX01BUCwgRl9WQUxVRSk7CisgIGlmICghbWFwcGluZ3AodG1hcCkgfHwgIXNpemVvZih0bWFwKSkKKyAgICByZXR1cm47CisgIGZvcmVhY2goc3RyaW5nIGtleSwgaW50IGVuZHRpbWU6IHRtYXApIHsKKyAgICBpZiAoZW5kdGltZSA8IHRpbWUoKSkKKyAgICAgIG1fZGVsZXRlKHRtYXAsIGtleSk7CisgIH0KKyAgLy8gc3BlaWNoZXJuIHBlciBTZXRQcm9wKCkgdW5ub2V0aWcsIGRhIG1hbiBkYXMgTWFwcGluZyBkaXJla3QgYWVuZGVydCwKKyAgLy8ga2VpbmUgS29waWUuCit9CisKK3Byb3RlY3RlZCB2b2lkIGhlYXJ0X2JlYXQoKQoreworICAgIGlmICggIXRoaXNfb2JqZWN0KCkgKQorICAgICAgICByZXR1cm47CisKKyAgICBhdHRyaWJ1dGVfaGIoKTsKKworICAgIC8vIEFscyBHZWlzdCBsZWlkZXQgbWFuIG5pY2h0IHVudGVyIHNvIHdlbHRsaWNoZW4gRGluZ2VuIHdpZQorICAgIC8vIEFsa29ob2wsIEdpZnQmQ28gLi4uCisgICAgaWYgKCBRdWVyeVByb3AoUF9HSE9TVCkgKQorICAgICAgICByZXR1cm47CisKKyAgICBpbnQgaHBvaXNvbiA9IFF1ZXJ5UHJvcChQX1BPSVNPTik7CisgICAgaW50IHJsb2NrID0gUXVlcnlQcm9wKFBfTk9fUkVHRU5FUkFUSU9OKTsKKyAgICBpbnQgaHAgPSBRdWVyeVByb3AoUF9IUCk7CisgICAgaW50IHNwID0gUXVlcnlQcm9wKFBfU1ApOworICAgIGludCBhbGM7CisKKyAgICAvLyBXZW5uIEFsa29ob2wgZ2V0cnVua2VuOiBBbGtvaG9sYXVzd2lya3VuZ2VuPworICAgIGlmICggKGFsYyA9IFF1ZXJ5UHJvcChQX0FMQ09IT0wpKSAmJiAhcmFuZG9tKDQwKSApeworICAgICAgICBpbnQgbjsKKyAgICAgICAgc3RyaW5nIGdpbGRlOworICAgICAgICBvYmplY3Qgb2I7CisKKyAgICAgICAgbiA9IHJhbmRvbSggNSAqIChhbGMgLSAxKS9RdWVyeVByb3AoUF9NQVhfQUxDT0hPTCkgKTsKKworICAgICAgICBzd2l0Y2ggKG4peworICAgICAgICBjYXNlIEFMQ19FRkZFQ1RfSElDSzoKKyAgICAgICAgICAgIHNheSggY2FwaXRhbGl6ZShuYW1lKCBXRVIsIDEgKSkgKyAiIHNhZ3Q6IDxIaWNrPiFcbiIgKTsKKyAgICAgICAgICAgIHdyaXRlKCAiPEhpY2s+ISBPaCwgVHNjaHVsZGlndW5nLlxuIiApOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAKKyAgICAgICAgY2FzZSBBTENfRUZGRUNUX1NUVU1CTEU6CisgICAgICAgICAgICBzYXkoIGNhcGl0YWxpemUobmFtZSggV0VSLCAxICkpICsgIiBzdG9scGVydCB1ZWJlciAiICsKKyAgICAgICAgICAgICAgICAgUXVlcnlQb3NzUHJvbm91biggRkVNQUxFLCBXRU4gKSArICIgRnVlc3NlLlxuIiApOworICAgICAgICAgICAgd3JpdGUoICJEdSBzdG9scGVyc3QuXG4iICk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIAorICAgICAgICBjYXNlIEFMQ19FRkZFQ1RfTE9PS0RSVU5LOgorICAgICAgICAgICAgc2F5KCBjYXBpdGFsaXplKG5hbWUoIFdFUiwgMSApKSArICIgc2llaHQgYmV0cnVua2VuIGF1cy5cbiIgKTsKKyAgICAgICAgICAgIHdyaXRlKCAiRHUgZnVlaGxzdCBEaWNoIGJlbm9tbWVuLlxuIiApOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAKKyAgICAgICAgY2FzZSBBTENfRUZGRUNUX1JVRUxQUzoKKyAgICAgICAgICAgIHNheSggY2FwaXRhbGl6ZShuYW1lKCBXRVIsIDEgKSkgKyAiIHJ1ZWxwc3QuXG4iICk7CisgICAgICAgICAgICB3cml0ZSggIkR1IHJ1ZWxwc3QuXG4iICk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgIAorICAgICAgICAvLyBHaWxkZSB1bmQgRW52aXJvbm1lbnQgaW5mb3JtaWVyZW4gdWViZXIgQWxrb2hvbGF1c3dpcmt1bmcuCisgICAgICAgIGlmICggc3RyaW5ncChnaWxkZSA9IFF1ZXJ5UHJvcChQX0dVSUxEKSkKKyAgICAgICAgICAgICAmJiBvYmplY3RwKG9iID0gZmluZF9vYmplY3QoICIvZ2lsZGVuLyIgKyBnaWxkZSApKSApCisgICAgICAgICAgICBvYi0+SW5mb3JtQWxjb2hvbEVmZmVjdCggTUUsIG4sIEFMQ19FRkZFQ1RfQVJFQV9HVUlMRCApOworICAgICAgICAKKyAgICAgICAgaWYgKCBlbnZpcm9ubWVudCgpICkKKyAgICAgICAgICAgIGVudmlyb25tZW50KCktPkluZm9ybUFsY29ob2xFZmZlY3QoIE1FLCBuLCBBTENfRUZGRUNUX0FSRUFfRU5WICk7CisgICAgfQorICAgIAorICAgIC8vIEFsa29ob2wgYWJiYXVlbiB1bmQgZXR3YXMgZXh0cmEgaGVpbGVuLCBmYWxscyBlcmxhdWJ0LgorICAgIGlmICggYWxjICYmICgtLWRlbGF5X2FsY29ob2wgPCAwKQorICAgICAgICAgJiYgIShybG9jayAmIE5PX1JFR19BTENPSE9MKSApeworCisgICAgICAgIFNldFByb3AoIFBfQUxDT0hPTCwgYWxjIC0gMSApOworICAgICAgICAKKyAgICAgICAgaWYgKCAhaHBvaXNvbiApeworICAgICAgICAgICAgaHArKzsKKyAgICAgICAgICAgIHNwKys7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIGRlbGF5X2FsY29ob2wgPSBRdWVyeVByb3AoUF9BTENPSE9MX0RFTEFZKTsKKyAgICB9CisKKyAgICAvLyBQX0RSSU5LIHJlZHV6aWVyZW4sIGZhbGxzIGVybGF1YnQuCisgICAgaWYgKCAoLS1kZWxheV9kcmluayA8IDApICYmICEocmxvY2sgJiBOT19SRUdfRFJJTkspICl7CisgICAgICAgIGRlbGF5X2RyaW5rID0gUXVlcnlQcm9wKFBfRFJJTktfREVMQVkpOworICAgICAgICBTZXRQcm9wKCBQX0RSSU5LLCBRdWVyeVByb3AoUF9EUklOSykgLSAxICk7CisgICAgfQorCisgICAgLy8gUF9GT09EIHJlZHV6aWVyZW4sIGZhbGxzIGVybGF1YnQuCisgICAgaWYgKCAoLS1kZWxheV9mb29kIDwgMCkgJiYgIShybG9jayAmIE5PX1JFR19GT09EKSApeworICAgICAgICBkZWxheV9mb29kID0gUXVlcnlQcm9wKFBfRk9PRF9ERUxBWSk7CisgICAgICAgIFNldFByb3AoIFBfRk9PRCwgUXVlcnlQcm9wKFBfRk9PRCkgLSAxICk7CisgICAgfQorCisgICAgLy8gUmVnZW5lcmF0aW9uIGF1cyBkZW0gSFAtUHVmZmVyCisgICAgLy8gSGllcmJlaSB3aXJkIHp3YXIgbnVyIGdlaGVpbHQsIHdlbm4gZGFzIGVybGF1YnQgaXN0LCBhYmVyIGRlciBQdWZmZXIKKyAgICAvLyBtdXNzIHRyb3R6ZGVtIGFiZ2VhcmJlaXRldC9yZWR1emllcnQgd2VyZGVuLCBkYSBEZWxmZW4gc29uc3QgZWluZQorICAgIC8vIG1vYmlsZSBUYW5rZSBrcmllZ2VuLiAoS2VpbmUgSGVpbHVuZyBpbSBIZWxsZW4sIFB1ZmZlciBibGVpYnQgc29uc3QKKyAgICAvLyBrb25zdGFudCB1bmQga2FubiBiZWkgQmVkYXJmIHVlYmVyIGR1bmtlbG1hY2hlbmRlIEl0ZW1zIGFiZ2VydWZlbgorICAgIC8vIHdlcmRlbi4pCisgICAgaW50IHZhbDsKKyAgICBpZiAoaHBfYnVmZmVyWzBdKSB7CisgICAgICAgIGludCByYXRlID0gaHBfYnVmZmVyWzFdOworICAgICAgICB2YWwgPSBocF9idWZmZXJbcmF0ZSArIDFdOworICAgIAorICAgICAgICBpZiAoIHZhbCA+IHJhdGUgKQorICAgICAgICAgICAgdmFsID0gcmF0ZTsKKyAgICAgICAgaHBfYnVmZmVyWzBdIC09IHZhbDsKKyAgICAgICAgaHBfYnVmZmVyW3JhdGUgKyAxXSAtPSB2YWw7CisgICAgICAgIGlmICggaHBfYnVmZmVyW3JhdGUgKyAxXSA8PSAwICkKKyAgICAgICAgICAgIHVwZGF0ZV9idWZmZXJzKCk7CisgICAgfQorICAgIC8vIEpldHp0IFJlZ2VuZXJhdGlvbiBhdXMgZGVtIFB1ZmZlciBkdXJjaGZ1ZWhyZW4sIGFiZXIgbnVyIHdlbm4gZXJsYXVidC4KKyAgICBpZiAoIHZhbCAmJiAhKHJsb2NrICYgTk9fUkVHX0JVRkZFUl9IUCkgKQorICAgICAgICBocCArPSB2YWw7IAorICAgIC8vIG5vcm1hbGVzIEhlaWxlbiwgZmFsbHMga2VpbmUgUmVnZW5lcmF0aW9uIGF1cyBkZW0gUHVmZmVyIGVyZm9sZ3RlIHVuZAorICAgIC8vIGVzIGVybGF1YnQgaXN0LgorICAgIGVsc2UgaWYgKCAoLS1kZWxheV9oZWFsIDwgMCkgJiYgIShybG9jayAmIE5PX1JFR19IUCkgKXsKKyAgICAgICAgZGVsYXlfaGVhbCA9IFF1ZXJ5UHJvcChQX0hQX0RFTEFZKTsKKyAgICAgICAgaWYgKCAhaHBvaXNvbiApCisgICAgICAgICAgICBocCsrOworICAgIH0KKworICAgIC8vIEdsZWljaGVzIFNwaWVsIGpldHp0IGZ1ZXIgZGVuIFNQLVB1ZmZlciAocy5vLikKKyAgICB2YWw9MDsKKyAgICBpZiAoIHNwX2J1ZmZlclswXSApIHsKKyAgICAgICAgaW50IHJhdGUgPSBzcF9idWZmZXJbMV07CisgICAgICAgIHZhbCA9IHNwX2J1ZmZlcltyYXRlICsgMV07CisgICAgICAgIAorICAgICAgICBpZiAoIHZhbCA+IHJhdGUgKQorICAgICAgICAgICAgdmFsID0gcmF0ZTsKKyAgICAgICAgCisgICAgICAgIHNwX2J1ZmZlclswXSAtPSB2YWw7CisgICAgICAgIHNwX2J1ZmZlcltyYXRlICsgMV0gLT0gdmFsOworIAorICAgICAgICBpZiAoIHNwX2J1ZmZlcltyYXRlICsgMV0gPD0gMCApCisgICAgICAgICAgICB1cGRhdGVfYnVmZmVycygpOworICAgIH0KKyAgICAvLyBSZWdlbmVyYXRpb24gZXJsYXVidD8KKyAgICBpZiAoIHZhbCAmJiAhKHJsb2NrICYgTk9fUkVHX0JVRkZFUl9TUCkgKQorICAgICAgICAgc3AgKz0gdmFsOworICAgIC8vIFdlbm4gbmljaHQsIG5vcm1hbGVzIEhvY2hpZGVsbiB2ZXJzdWNoZW4uCisgICAgZWxzZSBpZiAoICgtLWRlbGF5X3NwIDwgMCkgJiYgIShybG9jayAmIE5PX1JFR19TUCkgKXsKKyAgICAgICAgZGVsYXlfc3AgPSBRdWVyeVByb3AoUF9TUF9ERUxBWSk7CisgICAgICAgIGlmICggIWhwb2lzb24gKQorICAgICAgICAgICAgc3ArKzsKKyAgICB9CisKKyAgICBpZiAoIGhwb2lzb24gJiYgKGludGVyYWN0aXZlKE1FKSB8fCAhcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkpICl7CisgICAgICAgIC8vIFZhbmlvbiwgMjYuMTAuMDMKKyAgICAgICAgLy8gV2VubiBfc2V0X3BvaXNvbigpIHBlciBTRVRfTUVUSE9EIHVlYmVyc2NocmllYmVuIHdpcmQsIGthbm4KKyAgICAgICAgLy8gbmljaHQgc2ljaGVyZ2VzdGVsbHQgd2VyZGVuLCBkYXNzIHBvaXNvbiBpbW1lciBncm9lc3NlciAwIGlzdAorICAgICAgICAvLyBEYWhlciBtdXNzIGhpZXIgZWluIFRlc3QgcmVpbiwgc28gdGV1ZXIgZGFzIGF1Y2ggaXN0IDooCisgICAgICAgIGlmICgtLWhwb2lzb24gPCAwKQorICAgICAgICAgIGhwb2lzb249MDsKKyAgICAgICAgCisgICAgICAgIGlmICggLS1kZWxheV9wb2lzb24gPCAwICl7CisgICAgICAgICAgICBkZWxheV9wb2lzb24gPSBRdWVyeVByb3AoUF9QT0lTT05fREVMQVkpCisgICAgICAgICAgICAgICAgKyByYW5kb20oUE9JU09OX01FUkNZX0RFTEFZKTsKKyAgICAgICAgICAgIGhwIC09IGhwb2lzb247CisKKyAgICAgICAgICAgIGlmICggaHAgPCAwICl7CisgICAgICAgICAgICAgICAgdGVsbF9vYmplY3QoIE1FLCAiT2ggd2VoIC0gZGFzIEdpZnQgd2FyIHp1dmllbCBmdWVyIERpY2ghXG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIkR1IHN0aXJic3QuXG4iICk7CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgaWYgKCBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKE1FKSApeworICAgICAgICAgICAgICAgICAgICBjcmVhdGVfa2lsbF9sb2dfZW50cnkoICJWZXJnaWZ0dW5nIiwgMCApOworICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgLy8gQmVpbSBHaWZ0dG9kIGdpYnQgZXMga2VpbmVuIEtpbGxlci4gQWJlciBhdWYgZGllc2UgQXJ0CisgICAgICAgICAgICAgICAgICAgIC8vIGVya2VubnQgZGVyIFRvZGVzcmF1bSBkaWUgVXJzYWNoZSBrb3JyZWt0IHVuZCBnaWJ0IGRpZQorICAgICAgICAgICAgICAgICAgICAvLyByaWNodGlnZSBNZWxkdW5nIGF1cy4KKyAgICAgICAgICAgICAgICAgICAgU2V0UHJvcCggUF9LSUxMRVIsICJnaWZ0IiApOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICBkaWUoMSk7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICAgICAgCisgICAgICAgICAgICBpZiAoIChocG9pc29uIDwgMyB8fCAhcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkgKQorICAgICAgICAgICAgICAgICAmJiAtLWRyb3BfcG9pc29uIDwgMCkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAvLyBHaWZ0bGV2ZWwgZWlucyByZWR1emllcmVuLiBocG9pc29uIHd1cmRlIG9iZW4gc2Nob24KKyAgICAgICAgICAgICAgICAvLyByZWR1emllcnQsIGQuaC4gZWluZmFjaCBocG9pc29uIGluIFBfUE9JU09OIHNjaHJlaWJlbi4KKyAgICAgICAgICAgICAgICAvLyBkYWJlaSB3aXJkIGRhbm4gYXVjaCBnZ2YuIGRyb3BfcG9pc29uIHJpY2h0aWcgZ2VzZXR6dC4KKyAgICAgICAgICAgICAgICBTZXRQcm9wKCBQX1BPSVNPTiwgaHBvaXNvbiApOworICAgICAgICAgICAgICAgIGlmICggIWhwb2lzb24gKQorICAgICAgICAgICAgICAgICAgICB0ZWxsX29iamVjdCggTUUsICJEdSBzY2hlaW5zdCBkaWUgVmVyZ2lmdHVuZyAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInVlYmVyd3VuZGVuIHp1IGhhYmVuLlxuIiApOyAgCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIGlmICggaHBvaXNvbiAmJiAhcmFuZG9tKDE1KSApCisgICAgICAgICAgICBzd2l0Y2ggKCBocCoxMDAvUXVlcnlQcm9wKFBfTUFYX0hQKSApeworICAgICAgICAgICAgY2FzZSA3MS4uMTAwIDoKKyAgICAgICAgICAgICAgICB3cml0ZSggIkR1IGZ1ZWhsc3QgRGljaCBuaWNodCBndXQuXG4iICk7CisgICAgICAgICAgICAgICAgc2F5KCBjYXBpdGFsaXplKG5hbWUoV0VSKSkgKworICAgICAgICAgICAgICAgICAgICAgIiBzaWVodCBldHdhcyBiZW5vbW1lbiBhdXMuXG4iICk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICBjYXNlIDQ2Li43MCA6CisgICAgICAgICAgICAgICAgd3JpdGUoICJEaXIgaXN0IHNjaHdpbmRsaWcgdW5kIERlaW4gTWFnZW4gcmV2b2x0aWVydC5cbiIgKTsKKyAgICAgICAgICAgICAgICBzYXkoIGNhcGl0YWxpemUobmFtZShXRVIpKSArICIgdGF1bWVsdCBlaW4gd2VuaWcuXG4iICk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICBjYXNlIDI2Li40NSA6CisgICAgICAgICAgICAgICAgd3JpdGUoICJEaXIgaXN0IGhlaXNzLiBEdSBmdWVobHN0IERpY2ggc2Nod2FjaC4gS29wZndlaCAiCisgICAgICAgICAgICAgICAgICAgICAgICJoYXN0IER1IGF1Y2guXG4iICk7CisgICAgICAgICAgICAgICAgc2F5KCBjYXBpdGFsaXplKG5hbWUoV0VSKSkgKyAiIGdsdWVodCBkaXJla3QgdW5kIHNjaGVpbnQgIgorICAgICAgICAgICAgICAgICAgICAgImdyb3NzZSBTY2h3aWVyaWdrZWl0ZW4genUgaGFiZW4uXG4iICk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICBjYXNlIDExLi4yNSA6CisgICAgICAgICAgICAgICAgd3JpdGUoICJEdSBmdWVobHN0IERpY2ggYmVzY2hpc3Nlbi4gQWxsZXMgdHV0IHdlaCwgdW5kIER1ICIKKyAgICAgICAgICAgICAgICAgICAgICAgInNpZWhzdCBudXIgbm9jaCB1bnNjaGFyZi5cbiIgKTsKKyAgICAgICAgICAgICAgICBzYXkoIGNhcGl0YWxpemUobmFtZShXRVIpKSArICIgdGF1bWVsdCB1bmQgc3RvZWhudCB1bmQgIgorICAgICAgICAgICAgICAgICAgICAgImthbm4gZ2VyYWRlIG5vY2ggdmVybWVpZGVuLCBoaW56dWZhbGxlbi5cbiIgKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgIGNhc2UgMC4uMTAgOgorICAgICAgICAgICAgICAgIHdyaXRlKCBicmVha19zdHJpbmcoICJEdSBzaWVoc3QgZmFzdCBuaWNodHMgbWVociB1bmQga2FubnN0ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGljaCBudXIgbm9jaCB1bnRlciBncm9lc3N0ZW4gU2NobWVyemVuICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmV3ZWdlbi4gQWJlciBiYWxkIHR1dCBuaWNodHMgbWVociB3ZWgiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIi4uLiIsIDc4ICkgKTsKKyAgICAgICAgICAgICAgICBzYXkoIGJyZWFrX3N0cmluZyggY2FwaXRhbGl6ZShuYW1lKFdFUikpICsgIiBnbHVlaHQgd2llICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImltIEZpZWJlciwga2FubiBzaWNoIGthdW0gbm9jaCBydWVocmVuICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInVuZCBoYXQgZWluIHNjaG1lcnp2ZXJ6ZXJydGVzIEdlc2ljaHQuXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA3OCApICk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgfQorCisgICAgU2V0UHJvcCggUF9IUCwgaHAgKTsKKyAgICBTZXRQcm9wKCBQX1NQLCBzcCApOworfQorCitwdWJsaWMgaW50IEFkZEV4cCggaW50IGUgKQoreworICBpbnQgZXhwZXJpZW5jZTsKKyAgc3RyaW5nIGZuOworICBtaXhlZCBsYXN0OworCisgIGV4cGVyaWVuY2UgPSBRdWVyeVByb3AoUF9YUCk7CisKKyAgaWYgKCBRdWVyeVByb3AoUF9LSUxMUykgPiAxICYmIGUgPiAwICkKKyAgICAgIHJldHVybiBleHBlcmllbmNlOworCisgIGZuID0gaW1wbG9kZSggZXhwbG9kZSggb2JqZWN0X25hbWUoIGVudmlyb25tZW50KCkgfHwgdGhpc19vYmplY3QoKSApLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIvIiApWzAuLjwyXSwgIi8iICk7CisKKyAgaWYgKCBwb2ludGVycChsYXN0ID0gUXVlcnkoUF9MQVNUX1hQKSkgJiYgc2l6ZW9mKGxhc3QpID09IDIgJiYgbGFzdFswXSA9PSBmbiApCisgICAgICBTZXQoIFBfTEFTVF9YUCwgKHsgZm4sIGxhc3RbMV0rZSB9KSApOworICBlbHNlCisgICAgICBTZXQoIFBfTEFTVF9YUCwgKHsgZm4sIGUgfSkgKTsKKworICBpZiAoIChleHBlcmllbmNlICs9IGUpIDwgMCApCisgICAgICBleHBlcmllbmNlID0gMDsKKworICByZXR1cm4gU2V0UHJvcCggUF9YUCwgZXhwZXJpZW5jZSApOworfQorCitzdGF0aWMgPHN0cmluZ3xpbnQ+KiBfc2V0X2xhc3RfeHAoIDxpbnR8c3RyaW5nPiogbGFzdCApCit7CisgICAgaWYgKCAhcG9pbnRlcnAobGFzdCkgfHwgc2l6ZW9mKGxhc3QpICE9IDIgfHwgIXN0cmluZ3AobGFzdFswXSkgfHwKKyAgICAgICAgICFpbnRwKGxhc3RbMV0pICkKKyAgICAgICAgcmV0dXJuIFF1ZXJ5KFBfTEFTVF9YUCk7CisgICAgZWxzZQorICAgICAgICByZXR1cm4gU2V0KCBQX0xBU1RfWFAsIGxhc3QgKTsKK30KKworCitzdGF0aWMgaW50IF9zZXRfYWxpZ24oaW50IGEpCit7CisgIGlmIChhPC0xMDAwKSBhID0gLTEwMDA7CisgIGlmIChhPjEwMDApIGEgPSAxMDAwOworICByZXR1cm4gU2V0KFBfQUxJR04sIGEpOworfQorCisKK3N0YXRpYyBpbnQgX3NldF9ocCggaW50IGhwICkKK3sKKyAgICBpZiAoIFF1ZXJ5UHJvcChQX0dIT1NUKSApCisgICAgICAgIHJldHVybiBRdWVyeVByb3AoUF9IUCk7CisKKyAgICBpZiAoIGhwIDwgMCApCisgICAgICAgIHJldHVybiBTZXQoIFBfSFAsIDAgKTsKKworICAgIGlmICggaHAgPiBRdWVyeVByb3AoUF9NQVhfSFApICkKKyAgICAgICAgcmV0dXJuIFNldCggUF9IUCwgUXVlcnlQcm9wKFBfTUFYX0hQKSwgRl9WQUxVRSApOworCisgICAgcmV0dXJuIFNldCggUF9IUCwgaHAsIEZfVkFMVUUgKTsKK30KKworc3RhdGljIGludCBfc2V0X3NwKCBpbnQgc3AgKQoreworICAgIC8vZWluaWdlIExldXRlIHNjaHJlaWJlbiBmbG9hdHMgaW4gZGllIFBfSFAuIDotKAorICAgIGlmICghaW50cChzcCkpIHsKKwlzcD10b19pbnQoc3ApOworCS8vamEsIGVzIGlzdCB0ZXVlci4gQWJlciBpY2ggd2lsbCB3aXNzZW4sIHdlcnMgaXN0LiBLYW5uIHZvcgorCS8vbmFlY2hzdGVtIFJlYm9vdCB3aWVkZXIgcmF1cy4KKwlsb2dfZmlsZSgiSUxMRUdBTF9UWVBFLmxvZyIsc3ByaW50ZigKKwkgICAgICAiVmVyc3VjaCwgZWluZW4gbmljaHQtaW50IGluIFBfU1AgaW4gJU8genUgc2NocmVpYmVuOiBcbiVPXG4iLAorCSAgICAgIHRoaXNfb2JqZWN0KCksCisJICAgICAgZGVidWdfaW5mbyhESU5GT19UUkFDRSxESVRfU1RSX0NVUlJFTlQpKSk7CisgICAgfQorCisgICAgaWYgKCBRdWVyeVByb3AoUF9HSE9TVCkgKQorICAgICAgICBRdWVyeVByb3AoUF9TUCk7CisKKyAgICBpZiAoIHNwIDwgMCApCisgICAgICAgIHJldHVybiBTZXQoIFBfU1AsIDAgKTsKKworICAgIGlmICggc3AgPiBRdWVyeVByb3AoUF9NQVhfU1ApICkKKyAgICAgICAgcmV0dXJuIFNldCggUF9TUCwgUXVlcnlQcm9wKFBfTUFYX1NQKSwgRl9WQUxVRSApOworCisgICAgcmV0dXJuIFNldCggUF9TUCwgc3AsIEZfVkFMVUUgKTsKK30KKworc3RhdGljIGludCBfc2V0X2FsY29ob2woaW50IG4pCit7CisgIGlmKCFpbnRwKG4pKQorICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigKKyAgICAgICAgIl9zZXRfYWxjb2hvbCgpOiBleHBlY3RlZCA8aW50PiwgZ290ICUuNTBPXG4iLCBuKSk7CisKKyAgaWYgKFF1ZXJ5UHJvcChQX0dIT1NUKSkKKyAgICByZXR1cm4gUXVlcnkoUF9BTENPSE9MLCBGX1ZBTFVFKTsKKworICAvLyBudXIgxG5kZXJ1bmdlbiB1bmQgV2VydGUgPj0wIHdlcmRlbiBnZXNldHp0Li4uCisgIG4gPSBuIDwgMCA/IDAgOiBuOworICBpbnQgb2xkID0gUXVlcnkoUF9BTENPSE9MLCBGX1ZBTFVFKTsKKyAgaWYgKCBvbGQgPT0gbikKKyAgICByZXR1cm4gb2xkOworCisgIC8vIEhvb2tzIGF1ZnJ1ZmVuCisgIGludCAqcmV0ID0gSG9va0Zsb3coSF9IT09LX0FMQ09IT0wsIG4pOworICAvLyBCZWkgQWJicnVjaCBhbHRlbiBXZXJ0IHp1cnVlY2tnZWJlbgorICBzd2l0Y2ggKHJldFtIX1JFVENPREVdKSB7CisgICAgY2FzZSBIX0NBTkNFTExFRDoKKyAgICAgIHJldHVybiBvbGQ7CisgICAgY2FzZSBIX0FMVEVSRUQ6CisgICAgICAvLyBzb25zdCBuZXVlbiBXZXJ0IHNldHplbgorICAgICAgaWYoIWludHAocmV0W0hfUkVUREFUQV0pKQorICAgICAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoCisgICAgICAgICAgICAiX3NldF9hbGNvaG9sKCk6IGRhdGEgZnJvbSBIb29rRmxvdygpICE9IDxpbnQ+OiAlLjUwT1xuIiwKKyAgICAgICAgICAgIHJldFtIX1JFVERBVEFdKSk7CisgICAgICBuID0gcmV0W0hfUkVUREFUQV07CisgICAgICBuID0gbiA8IDAgPyAwIDogbjsKKworICAgIC8vIEhfTk9fTU9EIGlzIGZhbGx0aHJvdWdoCisgIH0KKworICByZXR1cm4gU2V0KFBfQUxDT0hPTCwgbiwgRl9WQUxVRSk7Cit9CisKK3N0YXRpYyBpbnQgX3NldF9kcmluayhpbnQgbikKK3sKKyAgaWYoIWludHAobikpCisgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKAorICAgICAgICAiX3NldF9kcmluaygpOiBleHBlY3RlZCA8aW50PiwgZ290ICUuNTBPXG4iLCBuKSk7CisKKyAgaWYgKFF1ZXJ5UHJvcChQX0dIT1NUKSkKKyAgICByZXR1cm4gUXVlcnkoUF9EUklOSywgRl9WQUxVRSk7CisKKyAgLy8gbnVyIMRuZGVydW5nZW4gdW5kIFdlcnRlID49MCB3ZXJkZW4gZ2VzZXR6dC4uLgorICBuID0gbiA8IDAgPyAwIDogbjsKKyAgaW50IG9sZCA9IFF1ZXJ5KFBfRFJJTkssIEZfVkFMVUUpOworICBpZiAoIG9sZCA9PSBuKQorICAgIHJldHVybiBvbGQ7CisKKyAgLy8gSG9va3MgYXVmcnVmZW4KKyAgaW50ICpyZXQgPSBIb29rRmxvdyhIX0hPT0tfRFJJTkssIG4pOworICAvLyBCZWkgQWJicnVjaCBhbHRlbiBXZXJ0IHp1cnVlY2tnZWJlbgorICBzd2l0Y2ggKHJldFtIX1JFVENPREVdKSB7CisgICAgY2FzZSBIX0NBTkNFTExFRDoKKyAgICAgIHJldHVybiBvbGQ7CisgICAgY2FzZSBIX0FMVEVSRUQ6CisgICAgICAvLyBzb25zdCBuZXVlbiBXZXJ0IHNldHplbgorICAgICAgaWYoIWludHAocmV0W0hfUkVUREFUQV0pKQorICAgICAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoCisgICAgICAgICAgICAiX3NldF9kcmluaygpOiBkYXRhIGZyb20gSG9va0Zsb3coKSAhPSA8aW50PjogJS41ME9cbiIsCisgICAgICAgICAgICByZXRbSF9SRVREQVRBXSkpOworICAgICAgbiA9IHJldFtIX1JFVERBVEFdOworICAgICAgbiA9IG4gPCAwID8gMCA6IG47CisKKyAgICAvLyBIX05PX01PRCBpcyBmYWxsdGhyb3VnaAorICB9CisKKyAgcmV0dXJuIFNldChQX0RSSU5LLCBuLCBGX1ZBTFVFKTsKK30KKworc3RhdGljIGludCBfc2V0X2Zvb2QoaW50IG4pCit7CisgIGlmKCFpbnRwKG4pKQorICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigKKyAgICAgICAgIl9zZXRfZm9vZCgpOiBleHBlY3RlZCA8aW50PiwgZ290ICUuNTBPXG4iLCBuKSk7CisKKyAgaWYgKFF1ZXJ5UHJvcChQX0dIT1NUKSkKKyAgICByZXR1cm4gUXVlcnkoUF9GT09ELCBGX1ZBTFVFKTsKKworICAvLyBudXIgxG5kZXJ1bmdlbiB1bmQgV2VydGUgPj0wIHdlcmRlbiBnZXNldHp0Li4uCisgIG4gPSBuIDwgMCA/IDAgOiBuOworICBpbnQgb2xkID0gUXVlcnkoUF9GT09ELCBGX1ZBTFVFKTsKKyAgaWYgKCBvbGQgPT0gbikKKyAgICByZXR1cm4gb2xkOworCisgIC8vIEhvb2tzIGF1ZnJ1ZmVuCisgIGludCAqcmV0ID0gSG9va0Zsb3coSF9IT09LX0ZPT0QsIG4pOworICAvLyBCZWkgQWJicnVjaCBhbHRlbiBXZXJ0IHp1cnVlY2tnZWJlbgorICBzd2l0Y2ggKHJldFtIX1JFVENPREVdKSB7CisgICAgY2FzZSBIX0NBTkNFTExFRDoKKyAgICAgIHJldHVybiBvbGQ7CisgICAgY2FzZSBIX0FMVEVSRUQ6CisgICAgICAvLyBzb25zdCBuZXVlbiBXZXJ0IHNldHplbgorICAgICAgaWYoIWludHAocmV0W0hfUkVUREFUQV0pKQorICAgICAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoCisgICAgICAgICAgICAiX3NldF9mb29kKCk6IGRhdGEgZnJvbSBIb29rRmxvdygpICE9IDxpbnQ+OiAlLjUwT1xuIiwKKyAgICAgICAgICAgIHJldFtIX1JFVERBVEFdKSk7CisgICAgICBuID0gcmV0W0hfUkVUREFUQV07CisgICAgICBuID0gbiA8IDAgPyAwIDogbjsKKworICAgIC8vIEhfTk9fTU9EIGlzIGZhbGx0aHJvdWdoCisgIH0KKworICByZXR1cm4gU2V0KFBfRk9PRCwgbiwgRl9WQUxVRSk7Cit9CisKK3N0YXRpYyBpbnQgX3NldF9wb2lzb24oaW50IG4pCit7CisgICAgaWYoIWludHAobikpCisgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKAorICAgICAgICAiX3NldF9wb2lzb24oKTogZXhwZWN0ZWQgPGludD4sIGdvdCAlLjUwT1xuIiwgbikpOworCisgIGlmIChRdWVyeVByb3AoUF9HSE9TVCkpCisgICAgcmV0dXJuIFF1ZXJ5KFBfUE9JU09OLCBGX1ZBTFVFKTsKKworICBpbnQgbXAgPSBRdWVyeVByb3AoUF9NQVhfUE9JU09OKTsKKyAgbiA9IChuPDAgPyAwIDogKG4+bXAgPyBtcCA6IG4pKTsKKworICAvLyBudXIgPj0wIHp1bGFzc2VuLgorICBuID0gbiA8IDAgPyAwIDogbjsKKworICBpbnQgb2xkID0gUXVlcnkoUF9QT0lTT04sIEZfVkFMVUUpOworICBpZiAoIG9sZCA9PSAwICYmIG4gPT0gMCkKKyAgICByZXR1cm4gb2xkOworCisgIC8vIEhvb2tzIGF1ZnJ1ZmVuCisgIGludCAqcmV0ID0gSG9va0Zsb3coSF9IT09LX1BPSVNPTiwgbik7CisgIC8vIEJlaSBBYmJydWNoIGFsdGVuIFdlcnQgenVydWVja2dlYmVuCisgIHN3aXRjaCAocmV0W0hfUkVUQ09ERV0pIHsKKyAgICBjYXNlIEhfQ0FOQ0VMTEVEOgorICAgICAgcmV0dXJuIG9sZDsKKyAgICBjYXNlIEhfQUxURVJFRDoKKyAgICAgIC8vIHNvbnN0IG5ldWVuIFdlcnQgc2V0emVuCisgICAgICBpZighaW50cChyZXRbSF9SRVREQVRBXSkpCisgICAgICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigKKyAgICAgICAgICAgICJfc2V0X3BvaXNvbigpOiBkYXRhIGZyb20gSG9va0Zsb3coKSAhPSA8aW50PjogJS41ME9cbiIsCisgICAgICAgICAgICByZXRbSF9SRVREQVRBXSkpOworICAgICAgbiA9IHJldFtIX1JFVERBVEFdOworICAgICAgbiA9IG4gPCAwID8gMCA6IG47CisKKyAgICAvLyBIX05PX01PRCBpcyBmYWxsdGhyb3VnaAorICB9CisKKyAgLy8gRnVlciBkaWUgU2VsYnN0aGVpbHVuZy4KKyAgc3dpdGNoKG4pIHsKKyAgY2FzZSAxOgorICAgIGRyb3BfcG9pc29uID0gNDArcmFuZG9tKDE2KTsKKyAgICBicmVhazsKKyAgY2FzZSAyOgorICAgIGRyb3BfcG9pc29uID0gMjUrcmFuZG9tKDgpOworICAgIGJyZWFrOworICBjYXNlIDM6CisgICAgZHJvcF9wb2lzb24gPSAxOCtyYW5kb20oNCk7CisgICAgYnJlYWs7CisgIGRlZmF1bHQ6CisgICAgLy8gbnVyIHJlbGV2YW50IGZ1ZXIgTlBDLCBkYSBTcGllbGVyIGJlaSA+MyBHaWZ0IG5pY2h0IG1laHIgcmVnZWdlbmllcmVuLgorICAgIGRyb3BfcG9pc29uID0gMjIgLSAyKm4gKyByYW5kb20oNDMgLSAzKm4pOworICAgIGJyZWFrOworICB9CisKKyAgLy8gZnVlciBTZXR6ZW4gZGVyIFByb3Agdm9uIGF1c3NlbiBlaW4gTG9nIHNjaHJlaWJlbgorICBpZiAocHJldmlvdXNfb2JqZWN0KDEpICE9IE1FKQorICAgIGxvZ19maWxlKCJQT0lTT04iLCBzcHJpbnRmKCIlcyAtICVzOiAlZCB2b24gJU8gKCVzKVxuIiwKKyAgICAgICAgICAgZHRpbWUodGltZSgpKVs1Li5dLAorICAgICAgICAgICAocXVlcnlfb25jZV9pbnRlcmFjdGl2ZSh0aGlzX29iamVjdCgpKSA/CisgICAgICAgICAgICAgY2FwaXRhbGl6ZShnZXRldWlkKHRoaXNfb2JqZWN0KCkpKSA6CisgICAgICAgICAgICAgY2FwaXRhbGl6ZShuYW1lKFdFUikpKSwKKyAgICAgICAgICAgbiwKKyAgICAgICAgICAgKHByZXZpb3VzX29iamVjdCgyKSA/IHByZXZpb3VzX29iamVjdCgyKSA6IHByZXZpb3VzX29iamVjdCgxKSksCisgICAgICAgICAgICh0aGlzX3BsYXllcigpID8gY2FwaXRhbGl6ZShnZXRldWlkKHRoaXNfcGxheWVyKCkpKSA6ICI/Pz8iKSkpOworCisgIHJldHVybiBTZXQoUF9QT0lTT04sIG4sIEZfVkFMVUUpOworfQorCitzdGF0aWMgaW50IF9zZXRfeHAoaW50IHhwKSB7IHJldHVybiBTZXQoUF9YUCwgeHAgPCAwID8gMCA6IHhwLCBGX1ZBTFVFKTsgfQorCitzdGF0aWMgbWl4ZWQgX3NldF9kaWVfaG9vayhtaXhlZCBob29rKQoreworICBpZihob29rICYmIHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUodGhpc19vYmplY3QoKSkpCisgICAgbG9nX2ZpbGUoIkRJRV9IT09LIiwKKyAgICAgICAgICAgICBzcHJpbnRmKCIlcyA6IERJRV9IT09LIGdlc2V0enQgdm9uICVPIGluICVPICglcylcbiIsCisgICAgICAgICAgICAgICAgICAgICBkdGltZSh0aW1lKCkpWzUuLl0sCisgICAgICAgICAgICAgICAgICAgICAocHJldmlvdXNfb2JqZWN0KDIpID8gcHJldmlvdXNfb2JqZWN0KDIpOnByZXZpb3VzX29iamVjdCgxKSksCisgICAgICAgICAgICAgICAgICAgICB0aGlzX29iamVjdCgpLGdldHVpZCh0aGlzX29iamVjdCgpKSkpOworICByZXR1cm4gU2V0KFBfVE1QX0RJRV9IT09LLGhvb2ssIEZfVkFMVUUpOworfQorCitzdGF0aWMgbWFwcGluZyBfcXVlcnlfZW5lbXlfZGFtYWdlKCkKK3sKKyAgcmV0dXJuIGNvcHkoZW5lbXlfZGFtYWdlKTsKK30KKworLy8gbnVyIG5lIEtvcGllIGxpZWZlcm4sIHNvbnN0IGthbm4gZGFzIGplZGVyIHZvbiBhdXNzZW4gYWVuZGVybi4KK3N0YXRpYyBtYXBwaW5nIF9xdWVyeV90aW1pbmdfbWFwKCkgeworICByZXR1cm4gY29weShRdWVyeShQX1RJTUlOR19NQVApKTsKK30KKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqIENvbnN1bWUtRnVua3Rpb24sIHVtIHplbnRyYWwgZHVyY2gga29uc3VtaWVyYmFyZSBEaW5nZSBhdXNnZWxvZXN0ZQorICogQWVuZGVydW5nZW4gZGVzIEdlc3VuZGhlaXRzenVzdGFuZGVzIGhlcmJlaXp1ZnVlaHJlbi4KKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8qIEtvbnN1bWllcnQgZXR3YXMKKyAqCisgKiBSdWVja2dhYmV3ZXJ0CisgKiAgICAgIDEgICAgICAgZXJmb2xncmVpY2gga29uc3VtaWVydAorICogICAgICAwICAgICAgIGZlaGxlbmRlIG9kZXIgZmFsc2NoZSBQYXJhbWV0ZXIKKyAqICAgICA8MCAgICAgICBCZWRpbmd1bmcgZnVlciBrb25zdW1pZXJlbiBuaWNodCBlcmZ1ZWxsdCwgQml0c2V0IGF1czoKKyAqICAgICAgMSAgICAgICBLYW5uIG5pY2h0cyBtZWhyIGVzc2VuCisgKiAgICAgIDIgICAgICAgS2FubiBuaWNodHMgbWVociB0cmlua2VuCisgKiAgICAgIDQgICAgICAgS2FubiBuaWNodHMgbWVociBzYXVmZW4KKyAqICAgICAgOCAgICAgICBBYmdlYnJvY2hlbiBkdXJjaCBIb29rIEhfSE9PS19DT05TVU1FCisgKi8KK3B1YmxpYyB2YXJhcmdzIGludCBjb25zdW1lKG1hcHBpbmcgY2luZm8sIGludCB0ZXN0b25seSkKK3sKKyAgaW50IHJldHZhbCA9IDA7CisgIC8vIG51ciB3YXMgdHVuLCB3ZW5uIGF1Y2ggSW5mb3MgcmVpbmtvbW1lbgorICBpZiAobWFwcGluZ3AoY2luZm8pICYmIHNpemVvZihjaW5mbykpIHsKKyAgICAvLyBIb29rcyBhdWZydWZlbiwgc2llIGFlbmRlcm4gZ2dmLiBub2NoIHdhcyBpbiBjaW5mby4KKyAgICBtaXhlZCAqaHJldCA9IEhvb2tGbG93KEhfSE9PS19DT05TVU1FLCAoe2NpbmZvLCB0ZXN0b25seX0pICk7CisgICAgc3dpdGNoKGhyZXRbSF9SRVRDT0RFXSkKKyAgICB7CisgICAgICAgIGNhc2UgSF9DQU5DRUxMRUQ6CisgICAgICAgICAgcmV0dXJuIC1IQ19IT09LX0NBTkNFTExBVElPTjsKKyAgICAgICAgY2FzZSBIX0FMVEVSRUQ6CisgICAgICAgICAgLy8gdGVzdG9ubHkga2FubiBuaWNodCBnZWFlbmRlcnQgd2VyZGVuLgorICAgICAgICAgIGNpbmZvID0gaHJldFtIX1JFVERBVEFdWzBdOworICAgIH0KKyAgICAvLyBMZWdhY3ktTWFwcGluZ3MgKGZsYWNoZSkgbmViZW4gc3RydWt0dXJpZXJ0ZW4gTWFwcGluZ3MgenVsYXNzZW4KKyAgICAvLyBmbGFjaGUgS29waWVuIGVyemV1Z2VuIChUT0RPPzogdW5kIGZ1ZXIgVGVpbG1hcHBpbmdzIG5pY2h0IHJlbGV2YW50ZQorICAgIC8vIEVpbnRyYWVnZSBsb2VzY2hlbikKKyAgICBtYXBwaW5nIGNvbmRpdGlvbnM7CisgICAgaWYgKG1hcHBpbmdwKGNpbmZvW0hfQ09ORElUSU9OU10pKSB7CisgICAgICBjb25kaXRpb25zID0gY29weShjaW5mb1tIX0NPTkRJVElPTlNdKTsKKyAgICB9IGVsc2UgeworICAgICAgY29uZGl0aW9ucyA9IGNvcHkoY2luZm8pOworICAgIH0KKyAgICBtYXBwaW5nIGVmZmVjdHM7CisgICAgaWYgKG1hcHBpbmdwKGNpbmZvW0hfRUZGRUNUU10pKSB7CisgICAgICBlZmZlY3RzID0gZmlsdGVyKGNpbmZvW0hfRUZGRUNUU10sICg6IG1lbWJlcihIX0FMTE9XRURfRUZGRUNUUywgJDEpID4gLTEgOikpOworICAgIH0gZWxzZSB7CisgICAgICBlZmZlY3RzID0gZmlsdGVyKGNpbmZvLCAoOiBtZW1iZXIoSF9BTExPV0VEX0VGRkVDVFMsICQxKSA+IC0xIDopKTsKKyAgICB9CisKKyAgICAvLyBCZWRpbmd1bmdlbiBwcnVlZmVuCisgICAgaWYgKG1hcHBpbmdwKGNvbmRpdGlvbnMpICYmIHNpemVvZihjb25kaXRpb25zKSkgeworICAgICAgLy8gQmVkaW5ndW5nZW4gZnVlciBLb25zdW0gYXVzd2VydGVuCisgICAgICBpZiAoY29uZGl0aW9uc1tQX0ZPT0RdICYmICFlYXRfZm9vZChjb25kaXRpb25zW1BfRk9PRF0sIDEpKQorICAgICAgICByZXR2YWwgfD0gSENfTUFYX0ZPT0RfUkVBQ0hFRDsKKyAgICAgIGVsc2UgaWYgKGNvbmRpdGlvbnNbUF9EUklOS10gJiYgIWRyaW5rX3NvZnQoY29uZGl0aW9uc1tQX0RSSU5LXSwgMSkpCisgICAgICAgIHJldHZhbCB8PSBIQ19NQVhfRFJJTktfUkVBQ0hFRDsKKyAgICAgIGVsc2UgaWYgKGNvbmRpdGlvbnNbUF9BTENPSE9MXSAmJiAhZHJpbmtfYWxjb2hvbChjb25kaXRpb25zW1BfQUxDT0hPTF0sIDEpKQorICAgICAgICByZXR2YWwgfD0gSENfTUFYX0FMQ09IT0xfUkVBQ0hFRDsKKyAgICAgIC8vIHJldHZhbCBuZWdhdGl2IG1hY2hlbiwgZGFtaXQgRmVobGVyIGxlaWNodCBlcmtlbm5iYXIgaXN0CisgICAgICByZXR2YWwgPSAtcmV0dmFsOworICAgIH0KKyAgICAvLyBCZWRpbmd1bmdlbiB3dXJkZW4gYWJnZWFyYmVpdGV0LCBqZXR6dCBkaWUgSGVpbHVuZyBkdXJjaGZ1ZWhyZW4KKyAgICBpZiAoIXJldHZhbCkgeworICAgICAgaWYgKCF0ZXN0b25seSkgeworICAgICAgICAvLyBCZWRpbmd1bmdlbiBlcmZ1ZWxsZW4sIHdlbm4gYWxsZXMgcGFzc3QgdW5kIGtlaW4gVGVzdAorICAgICAgICBpZiAoY29uZGl0aW9uc1tQX0FMQ09IT0xdKQorICAgICAgICAgIGRyaW5rX2FsY29ob2woY29uZGl0aW9uc1tQX0FMQ09IT0xdKTsKKyAgICAgICAgaWYgKGNvbmRpdGlvbnNbUF9EUklOS10pCisgICAgICAgICAgZHJpbmtfc29mdChjb25kaXRpb25zW1BfRFJJTktdKTsKKyAgICAgICAgaWYgKGNvbmRpdGlvbnNbUF9GT09EXSkKKyAgICAgICAgICBlYXRfZm9vZChjb25kaXRpb25zW1BfRk9PRF0pOworICAgICAgICAvLyBVbmQgamV0enQgZGllIFdpcmt1bmdlbgorICAgICAgICBpZiAoZWZmZWN0c1tQX1BPSVNPTl0pCisgICAgICAgICAgU2V0UHJvcChQX1BPSVNPTiwgUXVlcnlQcm9wKFBfUE9JU09OKSArIGVmZmVjdHNbUF9QT0lTT05dKTsKKyAgICAgICAgLy8gVW5kIG51biB3aXJrbGljaCBoZWlsZW4KKyAgICAgICAgc3dpdGNoIChjaW5mb1tIX0RJU1RSSUJVVElPTl0pIHsKKyAgICAgICAgY2FzZSBIRF9JTlNUQU5UOgorICAgICAgICAgIG1hcChlZmZlY3RzLCAoOiBTZXRQcm9wKCQxLCBRdWVyeVByb3AoJDEpICsgJDIpIDopKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAxLi41MDoKKyAgICAgICAgICBidWZmZXJfaHAoZWZmZWN0c1tQX0hQXSwgY2luZm9bSF9ESVNUUklCVVRJT05dKTsKKyAgICAgICAgICBidWZmZXJfc3AoZWZmZWN0c1tQX1NQXSwgY2luZm9bSF9ESVNUUklCVVRJT05dKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICBidWZmZXJfaHAoZWZmZWN0c1tQX0hQXSwgSERfU1RBTkRBUkQpOworICAgICAgICAgIGJ1ZmZlcl9zcChlZmZlY3RzW1BfU1BdLCBIRF9TVEFOREFSRCk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHJldHZhbCA9IDE7CisgICAgfQorICB9CisgIHJldHVybiByZXR2YWw7Cit9CmRpZmYgLS1naXQgYS9zdGQvbGl2aW5nL2xpZ2h0LmMgYi9zdGQvbGl2aW5nL2xpZ2h0LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWIxMmUxZgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9saXZpbmcvbGlnaHQuYwpAQCAtMCwwICsxLDU1IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gbGl2aW5nL2Rlc2NyaXB0aW9uLmMgLS0gZGVzY3JpcHRpb24gZm9yIGxpdmluZyBvYmplY3RzCisvLworLy8gJElkOiBkZXNjcmlwdGlvbi5jIDczNDAgMjAwOS0xMS0xOSAyMTo0NDo1MVogWmVzc3RyYSAkCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8bGl2aW5nL2Rlc2NyaXB0aW9uLmg+CisjaW5jbHVkZSA8bGl2aW5nL3NraWxscy5oPgorI3VuZGVmIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8cGxheWVyL3ZpZXdjbWQuaD4KKyNpbmNsdWRlIDxuZXdfc2tpbGxzLmg+CisjaW5jbHVkZSA8Y29udGFpbmVyLmg+CisjaW5jbHVkZSA8cGxheWVyL2Jhc2UuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKworaW5oZXJpdCAiL3N0ZC9jb250YWluZXIvbGlnaHQiOworCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKSB7CisgIDo6Y3JlYXRlKCk7CisgIFNldFByb3AoUF9MSUdIVF9UUkFOU1BBUkVOQ1ksIDApOworfQorCitzdGF0aWMgaW50IF9xdWVyeV9wbGF5ZXJfbGlnaHQoKQoreworICBpZiAoZW52aXJvbm1lbnQoKSkKKyAgICByZXR1cm4gZW52aXJvbm1lbnQoKS0+UXVlcnlQcm9wKFBfSU5UX0xJR0hUKSArIFF1ZXJ5UHJvcChQX0xJR0hUX01PRElGSUVSKTsKK30KKwordmFyYXJncyBpbnQgQ2Fubm90U2VlKGludCBzaWxlbnQpCit7CisgICBzdHJpbmcgaXNfYmxpbmQ7CisgICBpZiAoaXNfYmxpbmQgPSBRdWVyeVByb3AoUF9CTElORCkpIHsKKyAgICAgIGlmICghc2lsZW50KSB7CisgICAgICAgICBpZiAoc3RyaW5ncChpc19ibGluZCkpCisgICAgICAgICAgICB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLCBpc19ibGluZCk7CisgICAgICAgICBlbHNlIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksICJEdSBiaXN0IGJsaW5kIVxuIik7CisgICAgICB9CisgICAgICByZXR1cm4gMjsKKyAgIH0KKyAgIGlmIChVc2VTa2lsbChTS19OSUdIVFZJU0lPTik8PTAgJiYKKyAgICAgICBlbnZpcm9ubWVudCgpICYmIFF1ZXJ5UHJvcChQX1BMQVlFUl9MSUdIVCk8PTAgJiYKKyAgICAgICAoIUlTX0xFQVJORVIodGhpc19vYmplY3QoKSkgfHwgIVF1ZXJ5KFBfV0FOVFNfVE9fTEVBUk4pKSkKKyAgIHsKKyAgICAgICBpZiAoIXNpbGVudCkgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSwgIkVzIGlzdCB6dSBkdW5rZWwhXG4iKTsKKyAgICAgICByZXR1cm4gMTsKKyAgIH0KKyAgIHJldHVybiAwOworfQpkaWZmIC0tZ2l0IGEvc3RkL2xpdmluZy9tb25leWhhbmRsZXIuYyBiL3N0ZC9saXZpbmcvbW9uZXloYW5kbGVyLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2EyMjIyNgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9saXZpbmcvbW9uZXloYW5kbGVyLmMKQEAgLTAsMCArMSwyNiBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGxpdmluZy9tb25leWhhbmRsZXIuYyAtLSBtb25leSBoYW5kbGVyIGZvciBsaXZpbmdzCisvLworLy8gJElkOiBtb25leWhhbmRsZXIuYyA2NzM4IDIwMDgtMDItMTkgMTg6NDY6MTRaIEh1bW5pICQKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworaW5oZXJpdCAiL3N0ZC9jb250YWluZXIvbW9uZXloYW5kbGVyIjsKKworLy8gRnVua3Rpb25lbiBzb2xsZW4gbnVyIGRhcyBQcm9ncmFtbSBlcnNldHplbiwgbmF0dWVybGljaCBudXIgaW4gZGVyCisvLyBCbHVlcHJpbnQgX2RpZXNlc18gT2JqZWt0ZXMsIG5pY2h0IGluIGFuZGVyZW4uIDstKSBCVFc6IE5vcm1hbGVyd2Vpc2UKKy8vIHNvbGx0ZSBuaWVtYW5kIGhpZXJkcmluIGNyZWF0ZSgpIHJ1ZmVuLCBkZXIgZGFzIERpbmcgaGllciBlcmJ0LgorcHJvdGVjdGVkIHZvaWQgY3JlYXRlX3N1cGVyKCkgeworICBpZiAob2JqZWN0X25hbWUodGhpc19vYmplY3QoKSkgPT0gX19GSUxFX19bLi48M10pCisgICAgcmVwbGFjZV9wcm9ncmFtKCk7Cit9CisKKy8vIHdpcmQgbmljaHQgdm9uIGVyYmVuZGVuIE9iamVrdGVuIGdlcnVmZW4uIChXb3p1IGF1Y2guKQorcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkgeworICBjcmVhdGVfc3VwZXIoKTsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL2xpdmluZy9tb3ZpbmcuYyBiL3N0ZC9saXZpbmcvbW92aW5nLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzYxNDlmZgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9saXZpbmcvbW92aW5nLmMKQEAgLTAsMCArMSw0NTcgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBsaXZpbmcvbW92aW5nLmMgLS0gbW92aW5nIG9mIGxpdmluZyBvYmplY3RzCisvLworLy8gJElkOiBtb3ZpbmcuYyA5NDQ4IDIwMTYtMDEtMjIgMTc6NTI6MjhaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCitpbmhlcml0ICIvc3RkL3RoaW5nL21vdmluZyI7CisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8aG9vay5oPgorI2luY2x1ZGUgPGxpdmluZy9tb3ZpbmcuaD4KKyNpbmNsdWRlIDxsaXZpbmcvc2tpbGxzLmg+CisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHRoaW5nL2Rlc2NyaXB0aW9uLmg+CisjaW5jbHVkZSA8bW92aW5nLmg+CisjaW5jbHVkZSA8bmV3X3NraWxscy5oPgorI2luY2x1ZGUgPGxpdmluZy5oPgorCisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDxjb25maWcuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisKKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkKK3sKKyAgICBpZiAob2JqZWN0X25hbWUodGhpc19vYmplY3QoKSkgPT0gX19GSUxFX19bMC4uPDNdKQorICAgIHsKKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgb2ZmZXJIb29rKEhfSE9PS19NT1ZFLDEpOworfQorCitwdWJsaWMgdm9pZCBBZGRQdXJzdWVyKG9iamVjdCBvYikKK3sKKyAgbWl4ZWQgKnB1cjsKKworICBpZiAoIW9iamVjdHAob2IpKQorICAgIHJldHVybjsKKworICBpZiAoIXBvaW50ZXJwKHB1cj1RdWVyeShQX1BVUlNVRVJTKSkpCisgICAgcHVyPSh7MCwoe30pfSk7CisgIGVsc2UgaWYgKG1lbWJlcihwdXJbMV0sb2IpIT0tMSkKKyAgICByZXR1cm47CisgIAorICBTZXRQcm9wKFBfUFVSU1VFUlMsKHsgcHVyWzBdLCBwdXJbMV0rKHtvYn0pLSh7MH0pIH0pKTsKKyAgb2ItPl9TZXRQdXJzdWVkKE1FKTsKK30KKworcHVibGljIHZvaWQgUmVtb3ZlUHVyc3VlcihvYmplY3Qgb2IpCit7CisgIG1peGVkICpwdXI7CisKKyAgaWYgKHBvaW50ZXJwKHB1cj1RdWVyeShQX1BVUlNVRVJTLEZfVkFMVUUpKSAKKyAgICAgICYmIG1lbWJlcihwdXJbMV0sb2IpIT0tMSkKKyAgeworICAgIHB1clsxXS09KHtvYiwwfSk7CisgICAgaWYgKG9iKQorICAgICAgb2ItPl9SZW1vdmVQdXJzdWVkKE1FKTsKKyAgICBpZiAoIXB1clswXSYmIXNpemVvZihwdXJbMV0pKQorICAgICAgcHVyPTA7CisgICAgU2V0UHJvcChQX1BVUlNVRVJTLHB1cik7CisgIH0KK30KKworcHVibGljIHZvaWQgX1NldFB1cnN1ZWQob2JqZWN0IG9iKQoreworICBtaXhlZCAqcHVyOworCisgIGlmICghcG9pbnRlcnAocHVyPVF1ZXJ5KFBfUFVSU1VFUlMpKSkKKyAgICBwdXI9KHswLCh7fSl9KTsKKyAgZWxzZQorICAgIGlmIChvYmplY3RwKHB1clswXSkpCisgICAgICBwdXJbMF0tPlJlbW92ZVB1cnN1ZXIoTUUpOworICBwdXJbMF09b2I7CisgIHB1clsxXS09KHswfSk7CisgIFNldChQX1BVUlNVRVJTLHB1cik7Cit9CisKK3B1YmxpYyB2b2lkIF9SZW1vdmVQdXJzdWVkKG9iamVjdCBvYikKK3sKKyAgbWl4ZWQgKnB1cjsKKworICBpZiAoIXBvaW50ZXJwKHB1cj1RdWVyeShQX1BVUlNVRVJTKSkgfHwgcHVyWzBdIT1vYikKKyAgICByZXR1cm47CisgIHB1clswXT0wOworICBwdXJbMV0tPSh7MH0pOworICBpZiAoIXNpemVvZihwdXJbMV0pKQorICAgIHB1cj0wOworICBTZXQoUF9QVVJTVUVSUyxwdXIpOworfQorCisKK3ByaXZhdGUgdm9pZCBrYW1wZmVuZGUoIG9iamVjdCBlbiApIHsKKyAgaWYgKCFvYmplY3RwKGVuKSkgcmV0dXJuOworICB0ZWxsX29iamVjdCggTUUsIGNhcGl0YWxpemUoZW4tPm5hbWUoKSkgKworICAgICAgIiBpc3QgamV0enQgaGludGVyIERpciBoZXIuXG4iICk7CisgIHRlbGxfb2JqZWN0KCBlbiwgIkR1IHZlcmZvbGdzdCBqZXR6dCAiICsgbmFtZShXRU4pICsgIi5cbiIgKTsgICAgICAKKyAgZW4tPkluc2VydFNpbmdsZUVuZW15KE1FKTsKK30KKworcHJpdmF0ZSBpbnQgX2lzX2xlYXJuZXIob2JqZWN0IHBsKSB7CisgIHJldHVybiBJU19MRUFSTkVSKHBsKTsgCit9CisKKworLy8gYSkgUHJ1ZWZ1bmdlbiwgb2IgZGFzIG1vdmUgZXJsYXVidCBpc3QuCisvLyBiKSB6dW0gVWViZXJzY2hyZWliZW4KK3Byb3RlY3RlZCBpbnQgUHJldmVudE1vdmUob2JqZWN0IGRlc3QsIG9iamVjdCBvbGRlbnYsIGludCBtZXRob2QpIHsKKworICAvLyBNX05PQ0hFQ0s/IC0+IEJld2VndW5nIGVoIGVybGF1YnQgKHVuZCBSdWVja2dhYmV3ZXJ0IHd1ZXJkZSBpZ25vcmllcnQpLAorICAvLyBhYmVyIFByZXZlbnRJbnNlcnQvUHJldmVudExlYXZlKCkgcnVmZW4gdW5kIGlnbm9yaWVyZW4uCisgIGlmICgobWV0aG9kJk1fTk9DSEVDSykpIHsKKyAgICAgIC8vIGVyc3QgUHJldmVudExlYXZlTGl2aW5nKCkgcnVmZW4uLi4KKyAgICAgIGlmKGVudmlyb25tZW50KCkpICAgICAgICAKKyAgICAgICAgICBlbnZpcm9ubWVudCgpLT5QcmV2ZW50TGVhdmVMaXZpbmcodGhpc19vYmplY3QoKSwgZGVzdCk7CisgICAgICAvLyBkYW5uIFByZXZlbnRJbnNlcnRMaXZpbmcoKSBpbSBaaWVsLUVudi4KKyAgICAgIGRlc3QtPlByZXZlbnRJbnNlcnRMaXZpbmcodGhpc19vYmplY3QoKSk7CisgICAgICAvLyB1bmQgcmF1cy4uLgorICAgICAgcmV0dXJuKDApOworICB9CisKKyAgLy8gYmVpIExlYmV3ZXNlbiBtdXNzIGRpZSBCZXdlZ3VuZ3NtZXRob2RlIE1fR08gdW5kIE1fVFBPUlQgc2Vpbi4gRGllcyBpc3QKKyAgLy8gZ2xlaWNoemVpZ3QgZGllIFJlc3RyaWt0aW9uIGdlZ2VuIGRhcyBOZWhtZW4gdm9uIExlYmV3ZXNlbiwgZGEgZG9ydAorICAvLyBNX0dFVC9NX0dJVkUvTV9QVVQgZXRjLiB2ZXJ3ZW5kZXQgd3VlcmRlLiBCZWkgTV9HTyB1bmQgTV9UUE9SVCBmaW5kZXQKKyAgLy8ga2VpbmUgUHJ1ZWZ1bmcgc3RhdHQsIG9iIGRhcyBPYmpla3QgaW5zIFppZWwgJ3JlaW5wYXNzdCcgKEdld2ljaHQsIEFuemFobAorICAvLyBPYmpla3RlIHVzdy4pLgorICAvLyBJY2ggZmluZGUgZXMgZXR3YXMgbWVya3d1ZXJkaWcgZ2ViYXV0IChaZXNzdHJhKS4KKyAgaWYgKCAhKG1ldGhvZCAmIChNX0dPIHwgTV9UUE9SVCkpICkKKyAgICAgIHJldHVybiBNRV9QTEFZRVI7CisgIAorICAvLyBhbHRlIHVuZCBuZXVlIFVtZ2VidW5nIGF1ZiBOT19UUE9SVCBwcnVlZmVuLgorICBpZiAoIChtZXRob2QgJiBNX1RQT1JUKSApIHsKKyAgICBpZiAoIGVudmlyb25tZW50KCkgJiYKKyAgICAgICAgKGVudmlyb25tZW50KCktPlF1ZXJ5UHJvcChQX05PX1RQT1JUKSAmIChOT19UUE9SVF9PVVR8Tk9fVFBPUlQpKSApCisgICAgICAgICAgcmV0dXJuIE1FX0NBTlRfVFBPUlRfT1VUOworICAgIGVsc2UgaWYgKCBkZXN0LT5RdWVyeVByb3AoUF9OT19UUE9SVCkgJiAoTk9fVFBPUlRfSU58Tk9fVFBPUlQpICkKKyAgICAgICAgICByZXR1cm4gTUVfQ0FOVF9UUE9SVF9JTjsKKyAgfQorCisgIC8vIGVyc3QgUHJldmVudExlYXZlTGl2aW5nKCkgdGVzdGVuLi4uCisgIGlmKCBlbnZpcm9ubWVudCgpICYmIGVudmlyb25tZW50KCktPlByZXZlbnRMZWF2ZUxpdmluZyh0aGlzX29iamVjdCgpLCBkZXN0KSkKKyAgICAgIHJldHVybiBNRV9DQU5UX0xFQVZFX0VOVjsKKyAgLy8gZGFubiBQcmV2ZW50SW5zZXJ0TGl2aW5nKCkgaW0gWmllbC1FbnYKKyAgaWYgKGRlc3QtPlByZXZlbnRJbnNlcnRMaXZpbmcodGhpc19vYmplY3QoKSkpIAorICAgICAgcmV0dXJuIE1FX0NBTlRfQkVfSU5TRVJURUQ7CisKKyAgcmV0dXJuIDA7Cit9CisKKy8vIEtyYW1zIG5hY2ggZGVtIE1vdmUgbWFjaGVuIHVuZCBuZWJlbmJlaSB6dW0gVWViZXJzY2hyZWliZW4uCitwcm90ZWN0ZWQgdm9pZCBOb3RpZnlNb3ZlKG9iamVjdCBkZXN0LCBvYmplY3Qgb2xkZW52LCBpbnQgbWV0aG9kKSB7CisgIG1peGVkIHJlczsKKyAgb2JqZWN0IGVuZW07CisKKyAgLy8gQmVncnVlc3N1bmdzc2NobGFnIGZ1ZXIgZGllIEdlZ2VuZXIKKyAgaWYgKCAhKG1ldGhvZCAmIE1fTk9fQVRUQUNLKSApCisgICAgICBJbml0QXR0YWNrKCk7CisKKyAgaWYgKCFvYmplY3RwKE1FKSkgcmV0dXJuOworCisgIC8vIFZlcmZvbGdlciBuYWNoaG9sZW4uCisgIGlmICggcG9pbnRlcnAocmVzID0gUXVlcnkoUF9QVVJTVUVSUykpICYmIHNpemVvZihyZXNbMV0pICkgeworICAgICAgd2hpbGUgKCByZW1vdmVfY2FsbF9vdXQoICJUYWtlRm9sbG93ZXJzIiApID49IDAgKTsKKworICAgICAgY2FsbF9vdXQoICJUYWtlRm9sbG93ZXJzIiwgMCApOworICB9CisKKyAgLy8gdW5kIG5vY2ggZGFzIFRlYW0gbmFjaGhvbGVuLgorICBpZiAoIG9sZGVudiAhPSBkZXN0CisgICAgICAmJiBvYmplY3RwKE1FKQorICAgICAgJiYgUXVlcnlQcm9wKFBfVEVBTV9BVVRPRk9MTE9XKQorICAgICAgJiYgb2JqZWN0cCggZW5lbSA9IElzVGVhbUxlYWRlcigpICkgKQorICAgICAgZW5lbS0+U3RhcnRGb2xsb3cob2xkZW52KTsgLy8gVGVhbXZlcmZvbGd1bmcKKworfQorCit2YXJhcmdzIHB1YmxpYyBpbnQgbW92ZSggb2JqZWN0fHN0cmluZyBkZXN0LCBpbnQgbWV0aG9kLCBzdHJpbmcgZGlyZWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyB0ZXh0b3V0LCBzdHJpbmcgdGV4dGluICkKK3sKKyAgICBpbnQgcGFyYSwgbmlnaHR2aXMsIGludmlzLCB0bXA7CisgICAgb2JqZWN0IG9sZGVudiwgKmludjsKKyAgICBzdHJpbmcgZm4sdmM7CisgICAgbWl4ZWQgcmVzOworICAgIG1peGVkIGhvb2tEYXRhLCBob29rUmVzOworCisgICAgaWYgKCFvYmplY3RwKGRlc3QpICYmICFzdHJpbmdwKGRlc3QpKQorICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigiV3JvbmcgYXJndW1lbnQgMSB0byBtb3ZlKCkuICdkZXN0JyBtdXN0IGJlIGEgIgorICAgICAgICAgICAgInN0cmluZyBvciBvYmplY3QhIEFyZ3VtZW50IHdhczogJS4xMDBPXG4iLAorICAgICAgICAgICAgZGVzdCkpOworCisgICAgLy8gYWx0ZXMgRW52IGVyc3RtYWwgbWVya2VuLgorICAgIG9sZGVudiA9IGVudmlyb25tZW50KCk7CisgICAgCisgICAgLy9lcnN0bWFsIGRlbiByaWNodGlnZW4gWmllbHJhdW0gc3VjaGVuLCBiZXZvciBpcmdlbmR3ZWxjaGUgQ2hlY2tzIGdlbWFjaHQKKyAgICAvL3dlcmRlbi4uLgorICAgIC8vIElzdCBkZXIgU3BpZWxlciBpbiBlaW5lciBQYXJhbGxlbHdlbHQ/CisgICAgaWYgKCAocGFyYSA9IFF1ZXJ5UHJvcChQX1BBUkEpKSAmJiBpbnRwKHBhcmEpICkgeworICAgICAgICBmbiA9IG9iamVjdHAoZGVzdCkgPyBvYmplY3RfbmFtZShkZXN0KSA6IGRlc3Q7CisKKyAgICAgICAgLy8gRmFsbHMgZGVyIFppZWxyYXVtIG5pY2h0IHNjaG9uIGV4cGxpeml0IGluIGRlciBQYXJhbGxlbHdlbHQgaXN0LAorICAgICAgICAvLyBuZXVlbiBaaWVscmF1bSBzdWNoZW4uIEFiZXIgbnVyLCB3ZW5uIGZuIGtlaW4gIyBlbnRoYWVsdCAoYWxzbyBrZWluCisgICAgICAgIC8vIENsb25lIGlzdCksIHNvbnN0IHd1ZXJkZSBlaW5lIEJld2VndW5nIG5hY2ggcmF1bSM0Ml5wYXJhIHZlcnN1Y2h0LAorICAgICAgICAvLyB3YXMgZGFubiBidWdndC4gOy0pIFByb2JsZW0gd2lyZCBvZmZlbmJhciwgd2VubiBlaW4gUGFyYS1MZWJld2VzZW4KKyAgICAgICAgLy8gaW0gY3JlYXRlKCkgZWluZXMgVkMtUmF1bXMgaW4gUGFyYSBpbiBkZW4gUmF1bSBiZXdlZ3Qgd2lyZCwgZGEKKyAgICAgICAgLy8gZGllc2VyIGRhbm4gbm9jaCBuaWNodCB2b20gRHJpdmVyIHVtYmVuYW5udCB3dXJkZSB1bmQgcmF1bSM0MgorICAgICAgICAvLyBoZWlzc3QuCisgICAgICAgIGlmICggIXNpemVvZihyZWdleHAoICh7IGZuIH0pLCAiXFxeWzEtOV1bMC05XSokIiApKSAmJgorICAgICAgICAgICAgc3RycnN0cihmbiwiIyIpPT0tMSApCisgICAgICAgIHsKKyAgICAgICAgICAgIGZuICs9ICJeIiArIHBhcmE7CisKKyAgICAgICAgICAvLyBEZXIgUGFyYWxsZWx3ZWx0LVJhdW0gbXVzcyBleGlzdGllcmVuIHVuZCBmdWVyIFNwaWVsZXIKKyAgICAgICAgICAvLyBmcmVpZ2VnZWJlbiBzZWluLCBkYW1pdCBlciB6dW0gbmV1ZW4gWmllbCB3aXJkLiBBbnNvbnN0ZW4KKyAgICAgICAgICAvLyBkdWVyZmVuIG51ciBOUENzLCBUZXN0c3BpZWxlciB1bmQgTWFnaWVyIGhlcmVpbi4KKyAgICAgICAgICBpZiAoIChmaW5kX29iamVjdChmbikgCisgICAgICAgICAgICAgICAgfHwgKChmaWxlX3NpemUoZm4rIi5jIik+MCB8fAorICAgICAgICAgICAgICAgICAgICAoZmlsZV9zaXplKHZjPWltcGxvZGUoZXhwbG9kZShmbiwiLyIpWzAuLjwyXSwiLyIpKworICAgICAgICAgICAgICAgICAgICAgICAgICAiL3ZpcnR1YWxfY29tcGlsZXIuYyIpPjAgJiYKKyAgICAgICAgICAgICAgICAgICAgIWNhdGNoKHRtcD0oaW50KWNhbGxfb3RoZXIodmMsIlF1ZXJ5VmFsaWRPYmplY3QiLGZuKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2gpICYmIHRtcD4wKSkgJiYKKyAgICAgICAgICAgICAgICAgICAgIWNhdGNoKGxvYWRfb2JqZWN0KGZuKTtwdWJsaXNoKSApKSAmJgorICAgICAgICAgICAgICAgICAgKCFpbnRlcmFjdGl2ZShNRSkgfHwgIWZuLT5RdWVyeVByb3AoUF9OT19QTEFZRVJTKSB8fCAKKyAgICAgICAgICAgICAgICAgIChtZXRob2QgJiBNX05PQ0hFQ0spIHx8IElTX0xFQVJORVIoTUUpIHx8CisgICAgICAgICAgICAgICAgICAoc3RyaW5ncChyZXMgPSBRdWVyeVByb3AoUF9URVNUUExBWUVSKSkgJiYKKyAgICAgICAgICAgICAgICAgICBJU19MRUFSTkVSKCBsb3dlcl9jYXNlKHJlcykgKSkpICkKKyAgICAgICAgICB7CisgICAgICAgICAgICAgIGRlc3QgPSBmbjsKKyAgICAgICAgICB9CisgICAgICAgICAgZWxzZQorICAgICAgICAgIHsKKyAgICAgICAgICAgICAgLy8gV2lyIGJsZWliZW4gaW4gZGVyIE5vcm1hbHdlbHQuCisgICAgICAgICAgICAgIHBhcmEgPSAwOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIGpldHp0IGVyc3RtYWwgSG9va3MgYWJwcnVlZmVuLCBkYSBzaWUgZ2dmLiBkaWUgRGF0ZW4gYWVuZGVybi4KKyAgICAvLyBhbHRlbiBQX1RNUF9NT1ZFX0hPT0sgcHJ1ZWZlbi4KKyAgICBpZiAoIHJlcyA9IFF1ZXJ5UHJvcChQX1RNUF9NT1ZFX0hPT0spICl7CisgICAgICAgIGlmICggcG9pbnRlcnAocmVzKSAmJiBzaXplb2YocmVzKSA+PSAzCisgICAgICAgICAgICAgJiYgaW50cChyZXNbMF0pICYmIHRpbWUoKTxyZXNbMF0KKyAgICAgICAgICAgICAmJiBvYmplY3RwKHJlc1sxXSkgJiYgc3RyaW5ncChyZXNbMl0pICl7CisgICAgICAgICAgICBpZiAoIHJlcyA9IGNhbGxfb3RoZXIoIHJlc1sxXSwgcmVzWzJdLCBkZXN0LCBtZXRob2QsIGRpcmVjdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dG91dCwgdGV4dGluICkgKXsKKyAgICAgICAgICAgICAgICBpZiAoIHBvaW50ZXJwKHJlcykgJiYgc2l6ZW9mKHJlcykgPT0gNSApeworICAgICAgICAgICAgICAgICAgICBkZXN0ID0gcmVzWzBdOworICAgICAgICAgICAgICAgICAgICBtZXRob2QgPSByZXNbMV07CisgICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbiA9IHJlc1syXTsKKyAgICAgICAgICAgICAgICAgICAgdGV4dG91dCA9IHJlc1szXTsKKyAgICAgICAgICAgICAgICAgICAgdGV4dGluID0gcmVzWzRdOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBlbHNlIGlmICggaW50cChyZXMpICYmIHJlcyA9PSAtMSApCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBNRV9DQU5UX0xFQVZFX0VOVjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlCisgICAgICAgICAgICBTZXRQcm9wKCBQX1RNUF9NT1ZFX0hPT0ssIDAgKTsKKyAgICB9CisgICAgLy8gbW92ZSBob29rIG5hY2ggbmV1ZW0gSG9va3N5c3RlbSB0cmlnZ2Vybi4KKyAgICBob29rRGF0YT0oe2Rlc3QsbWV0aG9kLGRpcmVjdGlvbix0ZXh0b3V0LHRleHRpbn0pOworICAgIGhvb2tSZXM9SG9va0Zsb3coSF9IT09LX01PVkUsaG9va0RhdGEpOworICAgIGlmKGhvb2tSZXMgJiYgcG9pbnRlcnAoaG9va1JlcykgJiYgc2l6ZW9mKGhvb2tSZXMpPkhfUkVUREFUQSkgeworICAgICAgaWYoaG9va1Jlc1tIX1JFVENPREVdPT1IX0NBTkNFTExFRCkgeworICAgICAgICByZXR1cm4gTUVfQ0FOVF9MRUFWRV9FTlY7CisgICAgICB9CisgICAgZWxzZSBpZihob29rUmVzW0hfUkVUQ09ERV09PUhfQUxURVJFRCAmJiBob29rUmVzW0hfUkVUREFUQV0gJiYKKyAgICAgICAgICBwb2ludGVycChob29rUmVzW0hfUkVUREFUQV0pICYmIHNpemVvZihob29rUmVzW0hfUkVUREFUQV0pPj01ICl7CisgICAgICBkZXN0ID0gaG9va1Jlc1tIX1JFVERBVEFdWzBdOworICAgICAgbWV0aG9kID0gaG9va1Jlc1tIX1JFVERBVEFdWzFdOworICAgICAgZGlyZWN0aW9uID0gaG9va1Jlc1tIX1JFVERBVEFdWzJdOworICAgICAgdGV4dG91dCA9IGhvb2tSZXNbSF9SRVREQVRBXVszXTsKKyAgICAgIHRleHRpbiA9IGhvb2tSZXNbSF9SRVREQVRBXVs0XTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBkZXN0IGF1ZiBPYmplY3Qgbm9ybWllcmVuCisgICAgaWYgKHN0cmluZ3AoZGVzdCkpIGRlc3Q9bG9hZF9vYmplY3QoZGVzdCk7CisKKyAgICAvLyBqZXR6dCBDaGVja3MgZHVyY2hmdWVocmVuLCBvYiBkYXMgTW92ZSBkdXJjaGdlZnVlaHJ0IHdlcmRlbiBkYXJmLgorICAgIGlmICh0bXA9UHJldmVudE1vdmUoZGVzdCwgb2xkZW52LCBtZXRob2QpKSB7CisgICAgICAvLyBhdWYgZ3VlbHRpZ2VuIEZlaGxlciBwcnVlZmVuLCB3ZXIgd2Vpc3MsIHdhcyBNYWdpZXIgZGEgZXZ0bC4KKyAgICAgIC8vIHZlcnNlaGVudGxpY2ggenVydWVja2dlYmVuLgorICAgICAgaWYgKFZBTElEX01PVkVfRVJST1IodG1wKSkKKyAgICAgICAgcmV0dXJuKHRtcCk7CisgICAgICBlbHNlCisgICAgICAgIHJldHVybihNRV9ET05UX1dBTlRfVE9fQkVfTU9WRUQpOworICAgIH0KKyAgCisgICAgaWYgKCBpbnZpcyA9IFF1ZXJ5UHJvcChQX0lOVklTKSApCisgICAgICAgIG1ldGhvZCB8PSBNX1NJTEVOVDsKKworICAgIGlmICggb2JqZWN0cChvbGRlbnYpICkgeworICAgICAgICBpZiAoICEobWV0aG9kICYgTV9TSUxFTlQpICkgeworICAgICAgICAgICAgc3RyaW5nICptb3V0OworICAgICAgICAgICAgaWYgKCAhdGV4dG91dCApeworICAgICAgICAgICAgICAgIGlmICggbWV0aG9kICYgTV9UUE9SVCApCisgICAgICAgICAgICAgICAgICAgIHRleHRvdXQgPSAoc3RyaW5nKSBRdWVyeVByb3AoUF9NTVNHT1VUKSB8fAorICAgICAgICAgICAgICAgICAgICAgICAgKHN0cmluZykgUXVlcnlQcm9wKFBfTVNHT1VUKTsKKyAgICAgICAgICAgICAgICBlbHNlIAorICAgICAgICAgICAgICAgICAgICB0ZXh0b3V0ID0gKG1vdXQgPSBleHBsb2RlKCAoc3RyaW5nKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUXVlcnlQcm9wKFBfTVNHT1VUKSB8fCAiIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIjIiApKVswXQorICAgICAgICAgICAgICAgICAgICAgICAgIHx8IChzdHJpbmcpUXVlcnlQcm9wKFBfTU1TR09VVCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmICggIXNpemVvZihkaXJlY3Rpb24pICkKKyAgICAgICAgICAgICAgICBkaXJlY3Rpb24gPSAwOworCisgICAgICAgICAgICBpbnYgPSBhbGxfaW52ZW50b3J5KGVudmlyb25tZW50KCkpIC0gKHsgdGhpc19vYmplY3QoKSB9KTsKKyAgICAgICAgICAgIGludiA9IGZpbHRlciggaW52LCAjJ2xpdmluZy8qJyovICk7CisgICAgICAgICAgICBpbnYgLT0gZmlsdGVyX29iamVjdHMoIGludiwgIkNhbm5vdFNlZSIsIDEgKTsKKworICAgICAgICAgICAgZmlsdGVyKCBpbnYsICMndGVsbF9vYmplY3QvKicqLywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgTmFtZSggV0VSLCAyICkgKyAiICIgKyB0ZXh0b3V0ICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgKGRpcmVjdGlvbiA/ICIgIiArIGRpcmVjdGlvbiA6ICIiKSArCisgICAgICAgICAgICAgICAgICAgICAgICAgIChzaXplb2YobW91dCkgPiAxID8gbW91dFsxXSA6ICIiKSArICIuXG4iICk7CisgICAgICAgIH0KKyAgICAgICAgLy8gTWFnaWVyIHNlaGVuIGF1Y2ggQmV3ZWd1bmdlbiwgZGllIE1fU0lMRU5UIHNpbmQKKyAgICAgICAgZWxzZSBpZiAoIGludGVyYWN0aXZlKE1FKSApeworICAgICAgICAgICAgaW52ID0gKGFsbF9pbnZlbnRvcnkoZW52aXJvbm1lbnQoKSkgJiB1c2VycygpKQorICAgICAgICAgICAgICAgIC0gKHsgdGhpc19vYmplY3QoKSB9KTsKKyAgICAgICAgICAgIGludiA9IGZpbHRlciggaW52LCAjJ19pc19sZWFybmVyLyonKi8gKTsKKworICAgICAgICAgICAgaWYgKCBpbnZpcyApCisgICAgICAgICAgICAgICAgZm4gPSAiKCIgKyBjYXBpdGFsaXplKGdldHVpZChNRSkpICsgIikgdmVyc2Nod2luZGV0ICIKKyAgICAgICAgICAgICAgICAgICAgInVuc2ljaHRiYXIuXG4iOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIGZuID0gY2FwaXRhbGl6ZShnZXR1aWQoTUUpKSArICIgdmVyc2Nod2luZGV0IGdhbnogbGVpc2UuXG4iOworICAgICAgICAgICAgCisgICAgICAgICAgICBmaWx0ZXIoIGludiwgIyd0ZWxsX29iamVjdC8qJyovLCBmbiApOworICAgICAgICB9CisgICAgICAgIAorICAgICAgICAvLyBOYWNrZW5zY2hsYWcgYmVpbSBGbHVlY2h0ZW46CisgICAgICAgIGlmICggIShtZXRob2QgJiBNX05PX0FUVEFDSykgJiYgb2JqZWN0cChNRSkgKQorICAgICAgICAgICAgRXhpdEF0dGFjaygpOworICAgICAgICAvL2ZhbGxzIG5hY2ggRXhpdEF0dGFjaygpIGRhcyBMaXZpbmcgbmljaHQgbWVociBleGlzdGllcnQsIG11c3MgZGFzCisgICAgICAgIC8vbW92ZSgpIGF1Y2ggbmljaHQgbWVociBmb3J0Z2VzZXR6dCB3ZXJkZW4uIFdlaXRlciB1bnRlbiBnaWJ0IGVzIGF1Y2gKKyAgICAgICAgLy9taW4uIGVpbmUgU3RlbGxlLCBkaWUgbmljaHQgcHJ1ZWZ0IHVuZCBnZ2YuIGJ1Z2d0LiBEYWhlciBlcmZvbGd0CisgICAgICAgIC8vaGllciBnZ2YuIGVpbiBBYmJydWNoLiAxNS4xMS4wNiBaZXNzdHJhCisgICAgICAgIGlmICghb2JqZWN0cChNRSkpIHJldHVybihNRV9XQVNfREVTVFJVQ1RFRCk7CisKKyAgICAgICAgLy8gTmFja2Vuc2NobGFnIGthbm4gTUUgaW4gZGVuIFRvZGVzcmF1bSBiZXdlZ3QgaGFiZW4uLi4KKyAgICAgICAgaWYgKCBvbGRlbnYgPT0gZW52aXJvbm1lbnQoKSApIHsKKyAgICAgICAgICAgIC8vIEZ1ZXIgYWxsZSBhbndlc2VuZGVuIGdlZ25lciBrYW1wZmVuZGUoKSBhdWZydWZlbgorICAgICAgICAgICAgZmlsdGVyKChRdWVyeUVuZW1pZXMoKVswXSAmIGFsbF9pbnZlbnRvcnkob2xkZW52KSktKHswfSksCisgICAgICAgICAgICAgICAgIydrYW1wZmVuZGUpOworICAgICAgICAgICAgLy8gQnVncyBpbSBleGl0KCkgc2luZCBvaG5lIGNhdGNoKCkgZWluZmFjaCBtaXN0LgorICAgICAgICAgICAgY2F0Y2goZW52aXJvbm1lbnQoKS0+ZXhpdChNRSwgZGVzdCk7cHVibGlzaCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBpcmdlbmR3YXMga2FubiBkYXMgT2JqZWt0IHplcnN0b2VydCBoYWJlbiwgei5CLiBlbnYtPmV4aXQoKS4KKyAgICBpZiAoIW9iamVjdHAoTUUpKSByZXR1cm4oTUVfV0FTX0RFU1RSVUNURUQpOworCisgICAgaWYgKCBvbGRlbnYgIT0gZW52aXJvbm1lbnQoKSApCisgICAgICAgIC8vIERlciBOYWNrZW5zY2hsYWcgb2RlciBleGl0KCkga29lbm5lbiBlaW5lbiBzY2hvbiBiZXdlZ3QgaGFiZW4uCisgICAgICAgIC8vIFVuZCB3ZW5uIGVzIGluIGRlbiBUb2Rlc3JhdW0gaXN0LiA7XikKKyAgICAgICAgcmV0dXJuIE1PVkVfT0s7CisgICAgCisgICAgU2V0UHJvcCggUF9QUkVQQVJFRF9TUEVMTCwgMCApOyAvLyBTcHJ1Y2h2b3JiZXJlaXR1bmcgYWJnZWJyb2NoZW4KKyAgICBTZXRQcm9wKCBQX0xBU1RfTU9WRSwgdGltZSgpICk7IC8vIFplaXRwdW5rdCBkZXIgbGV0enRlbiBCZXdlZ3VuZworICAgIAorICAgIG1vdmVfb2JqZWN0KE1FLCBkZXN0KTsKKyAgICBpZiAoIW9iamVjdHAoTUUpKQorICAgICAgcmV0dXJuKE1FX1dBU19ERVNUUlVDVEVEKTsKKworICAgIGRlc3QgPSBlbnZpcm9ubWVudCgpOworICAgIAorICAgIG5pZ2h0dmlzID0gVXNlU2tpbGwoU0tfTklHSFRWSVNJT04pOworICAgIC8vIE1lbGR1bmdlbiBhbiBuaWNodC1CbGluZGUgYXVzZ2ViZW4sIGZhbGxzIGtlaW5lICdzdGlsbGUnIEJld2VndW5nCisgICAgaWYgKCAhKG1ldGhvZCAmIE1fU0lMRU5UKSApIHsKKyAgICAgIGlmICggIXRleHRpbiApIHsgICAgICAgIAorICAgICAgICBpZiAoIG1ldGhvZCAmIE1fVFBPUlQgKQorICAgICAgICAgICAgICB0ZXh0aW4gPSAoc3RyaW5nKSBRdWVyeVByb3AoUF9NTVNHSU4pOworICAgICAgICBlbHNlCisgICAgICAgICAgICAgIHRleHRpbiA9IChzdHJpbmcpIFF1ZXJ5UHJvcChQX01TR0lOKTsKKyAgICAgIH0KKyAgICAgICAgICAgIAorICAgICAgaW52ID0gYWxsX2ludmVudG9yeShlbnZpcm9ubWVudCgpKSAtICh7IHRoaXNfb2JqZWN0KCkgfSk7CisgICAgICBpbnYgPSBmaWx0ZXIoIGludiwgIydsaXZpbmcvKicqLyApOworICAgICAgICAgICAgaW52IC09IGZpbHRlcl9vYmplY3RzKCBpbnYsICJDYW5ub3RTZWUiLCAxICk7CisgICAgICAgICAgICBmaWx0ZXIoIGludiwgIyd0ZWxsX29iamVjdC8qJyovLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjYXBpdGFsaXplKG5hbWUoIFdFUiwgMCApKSArICIgIiArIHRleHRpbiArICIuXG4iICk7CisgICAgfQorICAgIC8vIHNvbnN0OiBNYWdpZXIgc2VoZW4gYXVjaCBNX1NJTEVOVC1CZXdlZ3VuZ2VuLCBoaWVyIGFsc28gbnVyIGFuIE1hZ2llcgorICAgIC8vIGF1c2dlYmVuLCBhbGxlIGFuZGVyZW4gc2VoZW4gZWggbml4LgorICAgIGVsc2UgaWYgKCBpbnRlcmFjdGl2ZShNRSkgKSB7ICAKKyAgICAgIGludiA9IChhbGxfaW52ZW50b3J5KGVudmlyb25tZW50KCkpICYgdXNlcnMoKSkgLSAoe3RoaXNfb2JqZWN0KCl9KTsgICAgICAgIAorICAgICAgaW52ID0gZmlsdGVyKCBpbnYsICMnX2lzX2xlYXJuZXIvKicqLyApOyAgICAgICAgCisgICAgICBpZiAoIGludmlzICkKKyAgICAgICAgZm4gPSAiKCIgKyBjYXBpdGFsaXplKGdldHVpZChNRSkpICsgIikgdGF1Y2h0IHVuc2ljaHRiYXIgYXVmLlxuIjsKKyAgICAgIGVsc2UKKyAgICAgICAgZm4gPSBjYXBpdGFsaXplKGdldHVpZChNRSkpICsgIiBzY2hsZWljaHQgbGVpc2UgaGVyZWluLlxuIjsgICAgICAgIAorICAgICAgZmlsdGVyKCBpbnYsICMndGVsbF9vYmplY3QsIGZuICk7ICAgIAorICAgIH0KKworICAgIC8vICJPYmpla3QiIHVlYmVyIGRhcyBNb3ZlIGluZm9ybWllcmVuLgorICAgIE5vdGlmeU1vdmUoZGVzdCwgb2xkZW52LCBtZXRob2QpOworCisgICAgLy8gSW5pdEF0dGFjaygpIGluIE5vdGlmeU1vdmUoKSBrYW5uIGRhcyBPYmpla3QgemVyc3RvZXJ0IGhhYmVuLgorICAgIGlmICghb2JqZWN0cChNRSkpCisgICAgICByZXR1cm4oTUVfV0FTX0RFU1RSVUNURUQpOworCisgICAgLy9zY2hlaW50IHdvaGwgZ2VrbGFwcHQgenUgaGFiZW4uCisgICAgcmV0dXJuIE1PVkVfT0s7Cit9CisKK3B1YmxpYyB2b2lkIFRha2VGb2xsb3dlcnMoKQoreworICBtaXhlZCAqZixlbnY7CisgIGludCBtZXRoLGkscjsKKworICBmPVF1ZXJ5KFBfUFVSU1VFUlMpOworICBpZiAoIXBvaW50ZXJwKGYpKQorICAgIHJldHVybjsKKyAgZW52PWVudmlyb25tZW50KCk7CisgIGlmKG9iamVjdF9uYW1lKGVudikgPT0gIi9yb29tL25ldHp0b3QiKSByZXR1cm47CisgIGZvcmVhY2gob2JqZWN0IGZvbGxvd2VyOiBmWzFdLSh7MH0pICkgeworICAgIC8vIGRpZSBwcnVlZnVuZyBhdWYgb2JqZWN0cCBpc3QgbmljaHQgdmVycnVlY2t0LCBlcyBrYW5uIHRoZW8uIHNlaW4sIGRhc3MKKyAgICAvLyBWZXJmb2xnZXIgaW0gUHJldmVudEZvbGxvdygpIG9kZXIgaW4gaWhyZW0gbW92ZS9pbml0IGFuZGVyZSBWZXJmb2xnZXIKKyAgICAvLyB6ZXJzdG9lcmVuLgorICAgIGlmIChvYmplY3RwKGZvbGxvd2VyKSAmJiBlbnZpcm9ubWVudChmb2xsb3dlcikhPWVudikgeworICAgICAgLy9tZXRoPU1fTk9DSEVDSzsKKyAgICAgIG1ldGg9TV9HTzsKKyAgICAgIGlmIChmb2xsb3dlci0+UXVlcnkoUF9GT0xMT1dfU0lMRU5UKSkKKyAgICAgICAgICBtZXRofD1NX1NJTEVOVHxNX05PX1NIT1c7CisgICAgICBjYXRjaChyPWZvbGxvd2VyLT5QcmV2ZW50Rm9sbG93KGVudik7cHVibGlzaCk7CisgICAgICBpZiAoIXIpCisgICAgICAgICAgZm9sbG93ZXItPm1vdmUoZW52LG1ldGgpOworICAgICAgZWxzZSBpZiAocj09MikKKyAgICAgICAgICBSZW1vdmVQdXJzdWVyKGZvbGxvd2VyKTsKKyAgICB9CisgIH0KK30KKwordmFyYXJncyBwdWJsaWMgaW50IHJlbW92ZSgpCit7IG9iamVjdCB0ZWFtOworCisgIGlmIChlbnZpcm9ubWVudCgpKQorICB7CisgICAgaWYgKCBvYmplY3RwKHRlYW09UXVlcnkoUF9URUFNKSkgKQorICAgICAgY2F0Y2godGVhbS0+UmVtb3ZlTWVtYmVyKE1FKTtwdWJsaXNoKTsKKworICAgIGVudmlyb25tZW50KCktPk5vdGlmeVJlbW92ZShNRSk7CisgIH0KKyAgZGVzdHJ1Y3QoTUUpOworICByZXR1cm4gMTsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL2xpdmluZy9wdXRfYW5kX2dldC5jIGIvc3RkL2xpdmluZy9wdXRfYW5kX2dldC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRlMWE5N2YKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvbGl2aW5nL3B1dF9hbmRfZ2V0LmMKQEAgLTAsMCArMSwxMjQzIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gbGl2aW5nL3B1dF9hbmRfZ2V0LmMgLS0gdGFraW5nIGFuZCBwdXR0aW5nIHRoaW5ncworLy8KKy8vICRJZDogcHV0X2FuZF9nZXQuYyA4NzU1IDIwMTQtMDQtMjYgMTM6MTM6NDBaIFplc3N0cmEgJAorCisvKgorICBHcnVuZGxlZ2VuZCBuZXUgc3RydWt0dXJpZXJ0IHZvbiBBbXludGhvciBpbSBBcHJpbC1KdW5pIDIwMDcKKworRGllIGVpZ2VudGxpY2hlbiBGdW5rdGlvbmVuOgorCisgIHByaXZhdGUgc3RyaW5nIHB1dF9vcl9nZXQob2JqZWN0IG8sIG9iamVjdCBkZXN0KQorICAgIEJld2VndCBlaW4gZWluemVsbmVzIE9iamVrdCBtaXQgYXV0b21hdGlzY2ggYmVzdGltbXRlciBNZXRob2QuIEdpYnQgaW0KKyAgICBFcmZvbGdzZmFsbCAwIHp1cnVlY2ssIHNvbnN0IGRpZSBhdXN6dWdlYmVuZGUgRmVobGVybWVsZHVuZy4KKworICB2YXJhcmdzIGludCBkcm9wKG9iamVjdCBvLCBtaXhlZCBtc2cpCisgIHZhcmFyZ3MgaW50IHB1dChvYmplY3Qgbywgb2JqZWN0IGRlc3QsIG1peGVkIG1zZykKKyAgdmFyYXJncyBpbnQgcGljayhvYmplY3QgbywgbWl4ZWQgbXNnKQorICB2YXJhcmdzIGludCBnaXZlKG9iamVjdCBvLCBvYmplY3QgZGVzdCwgbWl4ZWQgbXNnKQorICB2YXJhcmdzIGludCBzaG93KG9iamVjdCBvLCBvYmplY3QgZGVzdCwgbWl4ZWQgbXNnKQorICAgIERlciBTcGllbGVyIG5pbW10L2xlZ3QvZ2lidC96ZWlndC9sYWVzc3QgZWluIE9iamVrdCBmYWxsZW4sIHdvYmVpIGRpZQorICAgIGVudHNwcmVjaGVuZGVuIG9kZXIgb3B0aW9uYWwgYWJ3ZWljaGVuZGUgKGltIEZvcm1hdCB2b24gUF9YWFhfTVNHKSBvZGVyCisgICAgZ2FyIGtlaW5lIChtc2cgPT0gMSkgTWVsZHVuZ2VuIGF1c2dlZ2ViZW4gd2VyZGVuLiBFcyBsaWVndCBpbiBkZXIKKyAgICBWZXJhbnR3b3J0dW5nIGRlcyBSdWZlbmRlbiwgc2lubnZvbGxlIFdlcnRlIHp1IHVlYmVyZ2ViZW47IGluc2Jlc29uZGVyZQorICAgIHdpcmQgbmljaHQgZ2VwcnVlZnQsIG9iIHNpY2ggZGllIE9iamVrdGUgaW4gZGVyIFJlaWNod2VpdGUgZGVzIFNwaWVsZXJzCisgICAgYmVmaW5kZW4uIEdpYnQgMSB6dXJ1ZWNrLCB3ZW5uIGRhcyBPYmpla3QgYmV3ZWd0IHd1cmRlLCBzb25zdCAwLgorCitIaWxmc2Z1bmt0aW9uZW46CisKKyAgcHJpdmF0ZSBvYmplY3QgKl9fZmluZF9vYmplY3RzKHN0cmluZyAqdG9rZW5zLCBvYmplY3QgZW52LCBpbnQgaXNfc291cmNlKQorICBvYmplY3QgKmZpbmRfb2JqZWN0cyhzdHJpbmcgd2hhdCwgb2JqZWN0IGVudiwgaW50IGlzX3NvdXJjZSkKKyAgICBTdWNodCBpbSBSYXVtIHVuZCBpbSBTcGllbGVyIChvZGVyIGFsdGVybmF0aXYgaW4gZGVyIGFuZ2VnZWJlbmVuIFVtZ2VidW5nKQorICAgIG5hY2ggZGVuIGluIHRva2Vucy93aGF0IGJlemVpY2huZXRlbiBPYmpla3Rlbi4gaXNfc291cmNlIGJlc3RpbW10IGRpZQorICAgIGVyd2FydGV0ZSBncmFtbWF0aXNjaGUgRm9ybSAoMCBmdWVyICJ0b3BmIGF1ZiBoZXJkIiB1bmQgMSBmdWVyICJ0b3BmIHZvbgorICAgIGhlcmQiLCBzaWVoZSBNYW5wYWdlKS4KKworICB2YXJhcmdzIGludCBkcm9wX29iamVjdHMoc3RyaW5nIHN0ciwgbWl4ZWQgbXNnKQorICB2YXJhcmdzIGludCBwdXRfb2JqZWN0cyhzdHJpbmcgc3RyLCBpbnQgY2FzdXMsIHN0cmluZyB2ZXJiLCBtaXhlZCBtc2cpCisgIHZhcmFyZ3MgaW50IHBpY2tfb2JqZWN0cyhzdHJpbmcgc3RyLCBtaXhlZCBtc2csIGludCBmbGFnKQorICB2YXJhcmdzIGludCBnaXZlX29iamVjdHMoc3RyaW5nIHN0ciwgbWl4ZWQgbXNnKQorICB2YXJhcmdzIGludCBzaG93X29iamVjdHMoc3RyaW5nIHN0ciwgbWl4ZWQgbXNnKQorICAgIEVpbiBCZWZlaGwgd2llICJ3aXJmIHdhZmZlbiB3ZWciIHJlc3VsdGllcnQgaW4gZWluZW0gQXVmcnVmIHZvbgorICAgIGRyb3Bfb2JqZWN0cygid2FmZmVuIikuIERpZXNlIEZ1bmt0aW9uZW4gc2luZCBoYXVwdHNhZWNobGljaCBmdWVyIGRpZQorICAgIEJlaGFuZGx1bmcgZGVyIGpld2VpbGlnZW4gS29tbWFuZG9zIHZvcmdlc2VoZW4sIGtvZW5uZW4gamVkb2NoIGF1Y2ggZnVlcgorICAgIGVpZ2VuZSBCZWZlaGxlIHZlcndlbmRldCB3ZXJkZW4uIHB1dF9vYmplY3RzKCkgZXJ3YXJ0ZXQgYXVzc2VyZGVtIGRlbgorICAgIEthc3VzICgiRHUga2FubnN0IG5pY2h0cyBhbiBERVIgUGlud2FuZCBiZWZlc3RpZ2VuLiIpIHVuZCBkYXMgdmVyd2VuZGV0ZQorICAgIFZlcmIgaW4gZGVyIEd1bmRmb3JtICgiYmVmZXN0aWdlbiIpLiBEYXMgRmxhZyBmdWVyIHBpY2tfb2JqZWN0cygpIGdpYnQKKyAgICBhbiwgb2IgZGFzIE9iamVrdCBhdWNoIGVpbmZhY2ggaGVydW1saWVnZW4gZGFyZiAoIm5pbW0gLi4uIikgb2RlciBuaWNodAorICAgICgiaG9sZSAuLi4iKS4gR2lidCBiZWkgRXJmb2xnIDEsIHNvbnN0IDAgenVydWVjay4KKworICBvYmplY3QgKm1vdmVkX29iamVjdHMoKQorICBvYmplY3QgbW92ZWRfd2hlcmUoKQorICAgIEdpYnQgZGllIGViZW4gZmFsbGVuZ2VsYXNzZW5lbi9nZXN0ZWNrdGVuLy4uLiBPYmpla3RlIHp1cnVlY2sgdW5kIHdvaGluCisgICAgc2llIGdlc3RlY2t0L3dlbSBzaWUgZ2VnZWJlbi9nZXplaWd0IHd1cmRlbi4gRnVlciBkZW4gRmFsbCwgZGFzcyBtYW4KKyAgICBhbnNjaGxpZXNzZW5kIG5vY2ggZXR3YXMgbWl0IGlobmVuIG1hY2hlbiBtb2VjaHRlLgorCitEaWUgZWluemVsbmVuIEtvbW1hbmRvczoKKyAgc3RhdGljIGludCBmYWxsZW5sYXNzZW4oc3RyaW5nIHN0cikKKyAgc3RhdGljIGludCB3ZXJmZW4oc3RyaW5nIHN0cikKKyAgc3RhdGljIGludCBsZWdlbihzdHJpbmcgc3RyKQorICBzdGF0aWMgaW50IHN0ZWNrZW4oc3RyaW5nIHN0cikKKyAgc3RhdGljIGludCBob2xlbihzdHJpbmcgc3RyKQorICBzdGF0aWMgaW50IG5laG1lbihzdHJpbmcgc3RyKQorICBzdGF0aWMgaW50IGdlYmVuKHN0cmluZyBzdHIpCisgICAgTWluaW1hbGUgV3JhcHBlciBmdWVyIFhYWF9vYmplY3RzKCksIGVudGZlcm5lbiAiZmFsbGVuIiwgIndlZyIgYnp3LiAiYWIiCisgICAgYXVzIGRlbiBBcmd1bWVudGVuIHVuZCBzZXR6ZW4gZW50c3ByZWNoZW5kZSBTdGFuZGFyZC1GZWhsZXJtZWxkdW5nZW4uCisgICAgCisgIHByb3RlY3RlZCB2b2lkIGFkZF9wdXRfYW5kX2dldF9jb21tYW5kcygpCisgICAgUmVnaXN0cmllcnQgb2JpZ2UgRnVua3Rpb25lbiBwZXIgYWRkX2FjdGlvbigpLgorCitBdXMgcmVpbmVuIEtvbXBhdGliaWxpdGFldHNncnVlbmRlbiB3ZWl0ZXJoaW4gZW50aGFsdGVuOgorCisgIG9iamVjdCogZmluZF9vYnMoc3RyaW5nIHN0ciwgaW50IG1ldGgpCisgIGludCBwaWNrX29iaihvYmplY3Qgb2IpCisgIGludCBkcm9wX29iaihvYmplY3Qgb2IpCisgIGludCBwdXRfb2JqKG9iamVjdCBvYiwgb2JqZWN0IHdoZXJlKQorICBpbnQgZ2l2ZV9vYmoob2JqZWN0IG9iLCBvYmplY3Qgd2hlcmUpCisgICAgc2llaGUgTWFucGFnZXMKKworKi8KKworLyoKKyAgMjEuIE9rdCAxOTk4IGtvbXBsZXR0ZSBuZXUgcHJvZ3JhbW1pZXJ1bmcgdm9uIHB1dF9hbmRfZ2V0LmMgKFBhZHJlaWMpCistIGRpZSBHcnVwcGVuYXVzd2FobGVuIGFsbGVzLCB3YWZmZW4gdW5kIHJ1ZXN0dW5nZW4gc2luZCBqZXR6dCBpbW1lciBtb2VnbGljaAorICBkaWUgR3J1cHBlbiBzaW5kIHNlaHIgbGVpY2h0IGVyd2VpdGVyYmFyIHVuZCBtYW4gc29sbHRlIHNpY2ggbmljaHQgc2NoZXVlbgorICBkYXZvbiBnZWJyYXVjaCB6dSBtYWNoZW4uLi4KKy0gbWl0ICJpbiBtaXIiIHVuZCAiaW0gcmF1bSIga2FubiBtYW4gZGVuIGFienVzdWNoZW5kZW4gUmF1bSBzZWxic3QgZWluZ3JlbnplbgorLSBtaXQgImFsbGV8amVkZXxqZWRlbnxqZWRlcyA8aWQ+IiBrYW5uIG1hbiBhdWNoIGdhbnplIG9iamVrdGdydXBwZW4gYXVzd2FlaGxlbgorKi8KKworI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjaW5jbHVkZSA8dGhpbmcvZGVzY3JpcHRpb24uaD4KKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8bW92aW5nLmg+CisjaW5jbHVkZSA8Y29udGFpbmVyLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHdpemxldmVscy5oPgorCisjZGVmaW5lIFRNRShzdHIpIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksIFwKKyAgICBicmVha19zdHJpbmcoc3RyLCA3OCwgMCwgQlNfTEVBVkVfTVlfTEZTKSkKKyNkZWZpbmUgVE9CKG9iLHN0cikgdGVsbF9vYmplY3Qob2IsIGJyZWFrX3N0cmluZyhzdHIsIDc4LCAwLCBCU19MRUFWRV9NWV9MRlMpKQorI2RlZmluZSBTQVkoc3RyKSB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoKSwgXAorICAgIGJyZWFrX3N0cmluZyhzdHIsIDc4LCAwLCBCU19MRUFWRV9NWV9MRlMpLCAoe3RoaXNfb2JqZWN0KCl9KSkKKyNkZWZpbmUgU0FZMihvYnMsIHN0cikgdGVsbF9yb29tKGVudmlyb25tZW50KCksIFwKKyAgICBicmVha19zdHJpbmcoc3RyLCA3OCwgMCwgQlNfTEVBVkVfTVlfTEZTKSwgKHt0aGlzX29iamVjdCgpfSkgKyBvYnMpCisjZGVmaW5lIE5GKHN0cikgX25vdGlmeV9mYWlsKGJyZWFrX3N0cmluZyhzdHIsIDc4LCAwLCBCU19MRUFWRV9NWV9MRlMpKQorCitwcml2YXRlIG5vc2F2ZSBjbG9zdXJlIGNsOworcHJpdmF0ZSBub3NhdmUgc3RyaW5nIHdlbjAsIHdlbjEsIHdlcjA7Citwcml2YXRlIG5vc2F2ZSBvYmplY3QgKmxhc3RfbW92ZWRfb2JqZWN0czsKK3ByaXZhdGUgbm9zYXZlIG9iamVjdCBsYXN0X21vdmVkX3doZXJlOworCisKKy8qKioqKioqKioqKioqKioqKioqKioqKiBEaWUgZWlnZW50bGljaGVuIEZ1bmt0aW9uZW4gKioqKioqKioqKioqKioqKioqKioqKioqLworCitwcml2YXRlIHN0cmluZyBwdXRfb3JfZ2V0KG9iamVjdCBvLCBvYmplY3QgZGVzdCkKKworLyogQmV3ZWd0IGVpbiBlaW56ZWxuZXMgT2JqZWt0IDxvPiBpbiBkYXMgWmllbG9iamVrdCA8ZGVzdD4uIFZlcndlbmRldCBkYXp1CisgKiBqZSBuYWNoIFVtc3RhZW5kZW4gKFppZWwgaXN0IGRlciBTcGllbGVyLCBkaWUgVW1nZWJ1bmcsIGVpbiBMZWJld2VzZW4pIGRlbgorICogZW50c3ByZWNoZW5kZW4gV2VydCBmdWVyIDxtZXRob2Q+LiBHaWJ0IGltIEVyZm9sZ3NmYWxsIDAgenVydWVjaywgZXJzdGVsbHQKKyAqIHNvbnN0IGRpZSBhdXN6dWdlYmVuZGUgRmVobGVybWVsZHVuZyB1bmQgZ2lidCBkaWVzZSB6dXJ1ZWNrLgorICovCisKK3sKKyAgICBpbnQgbWV0aG9kLCByZXQ7CisgICAgc3RyaW5nIHN0cjsKKworICAgIC8vaWYgKGxpdmluZyhvKSkKKyAgICAvLyAgICByYWlzZV9lcnJvcihzcHJpbnRmKCJMZWJlbmRlcyBBcmd1bWVudCBmdWVyIHB1dF9vcl9nZXQ6ICVPXG4iLCBvKSk7CisKKyAgICBpZiAoZGVzdCA9PSB0aGlzX29iamVjdCgpKSAgICAgICAgICAvKiBwaWNrICovCisgICAgICAgIG1ldGhvZCA9IE1fR0VUOworICAgIGVsc2UgaWYgKGRlc3QgPT0gZW52aXJvbm1lbnQoKSkgICAgIC8qIGRyb3AgKi8KKyAgICAgICAgbWV0aG9kID0gTV9QVVQ7CisgICAgZWxzZSBpZiAobGl2aW5nKGRlc3QpKSAgICAgICAgICAgICAgLyogZ2l2ZSAqLworICAgICAgICBtZXRob2QgPSBNX0dJVkU7CisgICAgZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogcHV0ICovCisgICAgICAgIG1ldGhvZCA9IE1fUFVUIHwgTV9HRVQ7CisgICAgICAgIGlmIChmaXJzdF9pbnZlbnRvcnkobykpCisgICAgICAgICAgICByZXR1cm4gby0+TmFtZShXRVIsIDEpICsgIiBpc3QgbmljaHQgbGVlciEiOworICAgIH0KKworICAgIGlmICgocmV0ID0gby0+bW92ZShkZXN0LCBtZXRob2QpKSA+IDApCisgICAgICAgIHJldHVybiAwOworCisgICAgc3dpdGNoIChyZXQpIHsKKyAgICAgICAgY2FzZSBNRV9UT09fSEVBVlk6CisgICAgICAgICAgICBpZiAoZGVzdCA9PSB0aGlzX29iamVjdCgpKQorICAgICAgICAgICAgICAgIGlmIChRdWVyeVByb3AoUF9HSE9TVCkpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiAiQWxzIEdlaXN0IGthbm5zdCBEdSBuaWNodHMgbWl0bmVobWVuLiI7CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gIkR1IGthbm5zdCAiICsgd2VuMSArICIgbmljaHQgbWVociB0cmFnZW4uIjsKKworICAgICAgICAgICAgaWYgKHN0cmluZ3Aoc3RyID0gZGVzdC0+UXVlcnlQcm9wKFBfVE9PX0hFQVZZX01TRykpKQorICAgICAgICAgICAgICAgIHJldHVybiBjYXBpdGFsaXplKHJlcGxhY2VfcGVyc29uYWwoc3RyLCAoe28sIGRlc3R9KSwgMSkpOworCisgICAgICAgICAgICBpZiAobGl2aW5nKGRlc3QpKSB7CisgICAgICAgICAgICAgICAgaWYgKGRlc3QtPlF1ZXJ5UHJvcChQX0dIT1NUKSkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJBbHMgR2Vpc3Qga2FubiAiICsgZGVzdC0+bmFtZShXRVIsIDEpICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICIgbmljaHRzIG1pdG5laG1lbi4iOworICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlc3QtPk5hbWUoV0VSLCAxKSArICIga2FubiAiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHdlbjAgKyAiIG5pY2h0IG1laHIgdHJhZ2VuLiI7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChkZXN0ID09IGVudmlyb25tZW50KCkpCisgICAgICAgICAgICAgICAgcmV0dXJuIChzdHJpbmdwKHN0ciA9IGRlc3QtPk5hbWUoV0VSLCAxKSkgJiYgc2l6ZW9mKHN0cikgPworICAgICAgICAgICAgICAgICAgICAgICAgc3RyIDogIkRlciBSYXVtIikgKyAiIHd1ZXJkZSBkYW5uIHp1IHNjaHdlciB3ZXJkZW4uIjsKKworICAgICAgICAgICAgcmV0dXJuIGNhcGl0YWxpemUod2VyMCArICIgcGFzc3QgaW4gIiArIGRlc3QtPm5hbWUoV0VOLCAxKSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIG5pY2h0IG1laHIgcmVpbi4iKTsKKworICAgICAgICBjYXNlIE1FX0NBTlRfQkVfRFJPUFBFRDoKKyAgICAgICAgICAgIGlmIChvICYmIHN0cmluZ3Aoc3RyID0gby0+UXVlcnlQcm9wKFBfTk9EUk9QKSkpCisgICAgICAgICAgICAgICAgcmV0dXJuIHN0cjsKKworICAgICAgICAgICAgaWYgKGRlc3QgPT0gZW52aXJvbm1lbnQoKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gIkR1IGthbm5zdCAiICsgd2VuMSArICIgbmljaHQgd2Vnd2VyZmVuISI7CisKKyAgICAgICAgICAgIGlmIChsaXZpbmcoZGVzdCkpCisgICAgICAgICAgICAgICAgcmV0dXJuICJEdSBrYW5uc3QgIiArIHdlbjEgKyAiIG5pY2h0IHdlZ2dlYmVuLiI7CisKKyAgICAgICAgICAgIHJldHVybiAiU28gd2lyc3QgRHUgIiArIHdlbjEgKyAiIG5pY2h0IGxvcy4uLiI7CisKKyAgICAgICAgY2FzZSBNRV9DQU5UX0JFX1RBS0VOOgorICAgICAgICAgICAgaWYgKG8gJiYgc3RyaW5ncChzdHIgPSBvLT5RdWVyeVByb3AoUF9OT0dFVCkpKQorICAgICAgICAgICAgICAgIHJldHVybiBzdHI7CisKKyAgICAgICAgICAgIGlmIChzdHJpbmdwKHN0ciA9IGVudmlyb25tZW50KG8pLT5RdWVyeVByb3AoUF9OT0xFQVZFX01TRykpKQorICAgICAgICAgICAgICAgIHJldHVybiBjYXBpdGFsaXplKAorICAgICAgICAgICAgICAgICAgICByZXBsYWNlX3BlcnNvbmFsKHN0ciwgKHtvLCBlbnZpcm9ubWVudChvKX0pLCAxKSk7CisKKyAgICAgICAgICAgIC8vaWYgKGRlc3QgIT0gZW52aXJvbm1lbnQoKSkKKyAgICAgICAgICAgIC8vICAgIHJldHVybiAiRHUga2FubnN0ICIgKyB3ZW4xICsgIiBuaWNodCBlaW5tYWwgbmVobWVuLiI7CisKKyAgICAgICAgICAgIHJldHVybiAiRHUga2FubnN0ICIgKyB3ZW4xICsgIiBuaWNodCBuZWhtZW4uIjsKKworICAgICAgICBjYXNlIE1FX0NBTlRfQkVfSU5TRVJURUQ6CisgICAgICAgICAgICBpZiAoc3RyaW5ncChzdHIgPSBkZXN0LT5RdWVyeVByb3AoUF9OT0lOU0VSVF9NU0cpKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gY2FwaXRhbGl6ZShyZXBsYWNlX3BlcnNvbmFsKHN0ciwgKHtvLCBkZXN0fSksIDEpKTsKKworICAgICAgICAgICAgaWYgKGRlc3QgPT0gZW52aXJvbm1lbnQoKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gIkRhcyBkYXJmc3QgRHUgaGllciBuaWNodCBhYmxlZ2VuLiI7CisKKyAgICAgICAgICAgIGlmIChkZXN0ID09IHRoaXNfb2JqZWN0KCkpCisgICAgICAgICAgICAgICAgcmV0dXJuICJEdSBrYW5uc3QgIiArIHdlbjEgKyAiIG5pY2h0IG5laG1lbi4iOworCisgICAgICAgICAgICBpZiAobGl2aW5nKGRlc3QpKQorICAgICAgICAgICAgICAgIHJldHVybiAiRGFzIGthbm5zdCBEdSAiICsgZGVzdC0+bmFtZShXRU0sIDEpICsgIiBuaWNodCBnZWJlbi4iOworCisgICAgICAgICAgICByZXR1cm4gY2FwaXRhbGl6ZSh3ZW4wICsgIiBrYW5uc3QgRHUgZG9ydCBuaWNodCBoaW5laW5zdGVja2VuLiIpOworCisgICAgICAgIGNhc2UgTUVfQ0FOVF9MRUFWRV9FTlY6CisgICAgICAgICAgICAvLyBNRV9DQU5UX0xFQVZFX0VOViBrYW5uIG51ciBhdWZ0cmV0ZW4sIHdlbm4gbyBlaW4gRW52aXJvbm1lbnQKKyAgICAgICAgICAgIC8vIGhhdCwgZGVzaGFsYiBrZWluIENoZWNrIGRhZHJhdWYKKyAgICAgICAgICAgIGlmIChzdHJpbmdwKHN0ciA9IGVudmlyb25tZW50KG8pLT5RdWVyeVByb3AoUF9OT0xFQVZFX01TRykpKQorICAgICAgICAgICAgICAgIHJldHVybiBjYXBpdGFsaXplKAorICAgICAgICAgICAgICAgICAgICByZXBsYWNlX3BlcnNvbmFsKHN0ciwgKHtvLCBlbnZpcm9ubWVudChvKX0pLCAxKSk7CisKKyAgICAgICAgICAgIGlmIChlbnZpcm9ubWVudChvKSAhPSB0aGlzX29iamVjdCgpKQorICAgICAgICAgICAgICAgIHJldHVybiAiRHUga2FubnN0ICIgKyB3ZW4xICsgIiBuaWNodCBuZWhtZW4uIjsKKworICAgICAgICAgICAgaWYgKGRlc3QgPT0gZW52aXJvbm1lbnQoKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gIkR1IGthbm5zdCAiICsgd2VuMSArICIgbmljaHQgd2Vnd2VyZmVuISI7CisKKyAgICAgICAgICAgIGlmIChsaXZpbmcoZGVzdCkpCisgICAgICAgICAgICAgICAgcmV0dXJuICJEdSBrYW5uc3QgIiArIHdlbjEgKyAiIG5pY2h0IHdlZ2dlYmVuLiI7CisKKyAgICAgICAgICAgIHJldHVybiAiU28gd2lyc3QgRHUgIiArIHdlbjEgKyAiIG5pY2h0IGxvcy4uLiI7CisKKyAgICAgICAgY2FzZSBNRV9UT09fSEVBVllfRk9SX0VOVjoKKyAgICAgICAgICAgIGlmIChzdHJpbmdwKHN0ciA9IGRlc3QtPlF1ZXJ5UHJvcChQX0VOVl9UT09fSEVBVllfTVNHKSkpCisgICAgICAgICAgICAgICAgcmV0dXJuIGNhcGl0YWxpemUocmVwbGFjZV9wZXJzb25hbChzdHIsICh7bywgZGVzdH0pLCAxKSk7CisKKyAgICAgICAgICAgIGlmIChlbnZpcm9ubWVudChkZXN0KSA9PSB0aGlzX29iamVjdCgpKQorICAgICAgICAgICAgICAgIHJldHVybiBkZXN0LT5OYW1lKFdFUiwgMSkgKworICAgICAgICAgICAgICAgICAgICAgICAiIHd1ZXJkZSBEaXIgZGFubiB6dSBzY2h3ZXIgd2VyZGVuLiI7CisKKyAgICAgICAgICAgIHJldHVybiAoc3RyaW5ncChzdHIgPSBlbnZpcm9ubWVudChkZXN0KS0+TmFtZShXRVIsIDEpKQorICAgICAgICAgICAgICAgICAgICAgICAgJiYgc2l6ZW9mKHN0cikgPyBzdHIgOiAiRGVyIFJhdW0iKSArCisgICAgICAgICAgICAgICAgICAgICIgd3VlcmRlIGRhbm4genUgc2Nod2VyIHdlcmRlbi4iOworCisgICAgICAgIGNhc2UgVE9PX01BTllfT0JKRUNUUzoKKyAgICAgICAgICAgIGlmIChzdHJpbmdwKHN0ciA9IGRlc3QtPlF1ZXJ5UHJvcChQX1RPT19NQU5ZX01TRykpKQorICAgICAgICAgICAgICAgIHJldHVybiBjYXBpdGFsaXplKHJlcGxhY2VfcGVyc29uYWwoc3RyLCAoe28sIGRlc3R9KSwgMSkpOworCisgICAgICAgICAgICBpZiAoZGVzdCA9PSB0aGlzX29iamVjdCgpKQorICAgICAgICAgICAgICAgIHJldHVybiAiU292aWVsZSBHZWdlbnN0YWVuZGUga2FubnN0IER1IHVubW9lZ2xpY2ggdHJhZ2VuISI7CisKKyAgICAgICAgICAgIGlmIChkZXN0ID09IGVudmlyb25tZW50KCkpCisgICAgICAgICAgICAgICAgcmV0dXJuICJEYWZ1ZXIgaXN0IGhpZXIgbmljaHQgbWVociBnZW51ZyBQbGF0ei4iOworCisgICAgICAgICAgICBpZiAobGl2aW5nKGRlc3QpKQorICAgICAgICAgICAgICAgIHJldHVybiBkZXN0LT5OYW1lKFdFUiwgMSkgKyAiIGthbm4gIiAgKyB3ZW4wICsKKyAgICAgICAgICAgICAgICAgICAgICAgIiBuaWNodCBtZWhyIHRyYWdlbi4iOworCisgICAgICAgICAgICByZXR1cm4gIkRhZnVlciBpc3QgbmljaHQgbWVociBnZW51ZyBQbGF0eiBpbiAiICsKKyAgICAgICAgICAgICAgICAgICBkZXN0LT5uYW1lKFdFTSwgMSkgKyAiLiI7CisKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIGlmIChkZXN0ID09IHRoaXNfb2JqZWN0KCkpCisgICAgICAgICAgICAgICAgcmV0dXJuICJEdSBrYW5uc3QgIiArIHdlbjEgKyAiIG5pY2h0IG5laG1lbi4iOworCisgICAgICAgICAgICBpZiAoZGVzdCA9PSBlbnZpcm9ubWVudCgpKQorICAgICAgICAgICAgICAgIHJldHVybiAiRHUga2FubnN0ICIgKyB3ZW4xICsgIiBuaWNodCB3ZWd3ZXJmZW4hIjsKKworICAgICAgICAgICAgaWYgKGxpdmluZyhkZXN0KSkKKyAgICAgICAgICAgICAgICByZXR1cm4gIkR1IGthbm5zdCAiICsgd2VuMSArICIgbmljaHQgd2VnZ2ViZW4uIjsKKworICAgICAgICAgICAgcmV0dXJuIGNhcGl0YWxpemUod2VuMCArICIga2FubnN0IER1IGRvcnQgbmljaHQgaGluZWluc3RlY2tlbi4iKTsKKyAgICB9CisgICAgcmV0dXJuIDA7IC8vIE5PVCBSRUFDSEVECit9CisKKworLyogdmFyYXJncyBpbnQgZHJvcChvYmplY3QgbywgbWl4ZWQgbXNnKQorICogdmFyYXJncyBpbnQgcHV0KG9iamVjdCBvLCBvYmplY3QgZGVzdCwgbWl4ZWQgbXNnKQorICogdmFyYXJncyBpbnQgcGljayhvYmplY3QgbywgbWl4ZWQgbXNnKQorICogdmFyYXJncyBpbnQgZ2l2ZShvYmplY3Qgbywgb2JqZWN0IGRlc3QsIG1peGVkIG1zZykKKyAqIHZhcmFyZ3MgaW50IHNob3cob2JqZWN0IG8sIG9iamVjdCBkZXN0LCBtaXhlZCBtc2cpCisgKgorICogRGVyIFNwaWVsZXIgbmltbXQvbGVndC9naWJ0L3plaWd0L2xhZXNzdCBlaW4gT2JqZWt0IGZhbGxlbiwgd29iZWkgZGllCisgKiBlbnRzcHJlY2hlbmRlbiBvZGVyIG9wdGlvbmFsIGFid2VpY2hlbmRlIChpbSBGb3JtYXQgdm9uIFBfWFhYX01TRykgb2RlcgorICogZ2FyIGtlaW5lIChtc2cgPT0gMSkgTWVsZHVuZ2VuIGF1c2dlZ2ViZW4gd2VyZGVuLiBFcyBsaWVndCBpbiBkZXIKKyAqIFZlcmFudHdvcnR1bmcgZGVzIFJ1ZmVuZGVuLCBzaW5udm9sbGUgV2VydGUgenUgdWViZXJnZWJlbjsgaW5zYmVzb25kZXJlCisgKiB3aXJkIG5pY2h0IGdlcHJ1ZWZ0LCBvYiBzaWNoIGRpZSBPYmpla3RlIGluIGRlciBSZWljaHdlaXRlIGRlcyBTcGllbGVycworICogYmVmaW5kZW4uIEdpYnQgMSB6dXJ1ZWNrLCB3ZW5uIGRhcyBPYmpla3QgYmV3ZWd0IHd1cmRlLCBzb25zdCAwLgorICovCisKK3ZhcmFyZ3MgaW50IGRyb3Aob2JqZWN0IG8sIG1peGVkIG1zZykKK3sKKyAgICBzdHJpbmcgc3RyOworCisgICAgLy8gdm9yaGVyIHNwZWljaGVybiwgZmFsbHMgZGFzIE9iamVrdCB6ZXJzdG9lcnQgd2lyZAorICAgIGNsID0gc3ltYm9sX2Z1bmN0aW9uKCJuYW1lIiwgbyk7CisgICAgd2VuMCA9IGZ1bmNhbGwoY2wsIFdFTiwgMCk7CisgICAgd2VuMSA9IGZ1bmNhbGwoY2wsIFdFTiwgMSk7CisgICAgd2VyMCA9IDA7CisKKyAgICBpZiAoIW1zZykKKyAgICAgICAgbXNnID0gby0+UXVlcnlQcm9wKFBfRFJPUF9NU0cpOworCisgICAgaWYgKHN0ciA9IHB1dF9vcl9nZXQobywgZW52aXJvbm1lbnQoKSkpIHsKKyAgICAgICAgVE1FKHN0cik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIGlmICghbXNnKSB7CisgICAgICAgIFRNRSgiRHUgbGFlc3N0ICIgKyB3ZW4xICsgIiBmYWxsZW4uIik7CisgICAgICAgIFNBWShOYW1lKFdFUiwxKSArICIgbGFlc3N0ICIgKyB3ZW4wICsgIiBmYWxsZW4uIik7CisgICAgfSBlbHNlIGlmIChwb2ludGVycChtc2cpKQorICAgICAgICBzd2l0Y2ggKHNpemVvZihtc2cpKSB7CisgICAgICAgICAgLy8gV2VubiBlcyB6d2VpIFN0cmluZ3MgZ2lidCwgZ2VodCBkaWUgMi4gYW5zIEVudmlyb25tZW50CisgICAgICAgICAgY2FzZSAyOgorICAgICAgICAgICAgU0FZKHJlcGxhY2VfcGVyc29uYWwobXNnWzFdLCAoe3RoaXNfb2JqZWN0KCksIG98fHdlbjB9KSwgMSkpOworICAgICAgICAgIGNhc2UgMToKKyAgICAgICAgICAgIFRNRShyZXBsYWNlX3BlcnNvbmFsKG1zZ1swXSwgKHt0aGlzX29iamVjdCgpLCBvfHx3ZW4xfSksIDEpKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKAorICAgICAgICAgICAgICAgICJGYWxzY2hlcyBGb3JtYXQgZnVlciBQX0RST1BfTVNHOiAlT1xuIiwgb3x8d2VuMSkpOworICAgICAgICB9CisKKyAgICByZXR1cm4gMTsKK30KKwordmFyYXJncyBpbnQgcHV0KG9iamVjdCBvLCBvYmplY3QgZGVzdCwgbWl4ZWQgbXNnKQoreworICAgIHN0cmluZyBzdHI7CisKKyAgICAvLyBGYWxscyBkYXMgamVtYW5kIHZvbiBhdXNzZW4gcnVmdCB1bmQgU2Nocm90dCB1ZWJlcmdpYnQuLi4KKyAgICAvL2lmIChsaXZpbmcoZGVzdCkpCisgICAgLy8gICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigiTGViZW5kZXMgWmllbCBmdWVyIHB1dCgpOiAlT1xuIiwgZGVzdCkpOworICAgIGlmIChkZXN0ID09IGVudmlyb25tZW50KCkpCisgICAgICAgIHJhaXNlX2Vycm9yKCJaaWVsIGZ1ZXIgcHV0KCkgaXN0IFVtZ2VidW5nIGRlcyBTcGllbGVyc1xuIik7CisKKyAgICAvLyB2b3JoZXIgc3BlaWNoZXJuLCBmYWxscyBkYXMgT2JqZWt0IHplcnN0b2VydCB3aXJkCisgICAgY2wgPSBzeW1ib2xfZnVuY3Rpb24oIm5hbWUiLCBvKTsKKyAgICB3ZW4wID0gZnVuY2FsbChjbCwgV0VOLCAwKTsKKyAgICB3ZW4xID0gZnVuY2FsbChjbCwgV0VOLCAxKTsKKyAgICB3ZXIwID0gZnVuY2FsbChjbCwgV0VSLCAwKTsKKworICAgIGlmICghbXNnKQorICAgICAgICBtc2cgPSBvLT5RdWVyeVByb3AoUF9QVVRfTVNHKTsKKworICAgIGlmIChzdHIgPSBwdXRfb3JfZ2V0KG8sIGRlc3QpKSB7CisgICAgICAgIFRNRShzdHIpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgCisgICAgaWYgKCFtc2cpIHsKKyAgICAgICAgVE1FKCJEdSBzdGVja3N0ICIgKyB3ZW4xICsgIiBpbiAiICsgZGVzdC0+bmFtZShXRU4sIDEpICsgIi4iKTsKKyAgICAgICAgaWYgKGVudmlyb25tZW50KCkpCisJICBTQVkoTmFtZShXRVIsIDEpICsgIiBzdGVja3QgIiArIHdlbjAgKworCSAgICAgICIgaW4gIiArIGRlc3QtPm5hbWUoV0VOLCAwKSArICIuIik7CisgICAgfQorICAgIGVsc2UgaWYgKHBvaW50ZXJwKG1zZykpIHsKKyAgICAgICAgc3dpdGNoIChzaXplb2YobXNnKSkgeworICAgICAgICAgIGNhc2UgMjoKKyAgICAgICAgICAgIGlmIChlbnZpcm9ubWVudCgpKQorCSAgICAgIFNBWShyZXBsYWNlX3BlcnNvbmFsKG1zZ1sxXSwgKHt0aGlzX29iamVjdCgpLCBvfHx3ZW4wLCBkZXN0fSksIDEpKTsKKyAgICAgICAgICBjYXNlIDE6CisgICAgICAgICAgICBUTUUocmVwbGFjZV9wZXJzb25hbChtc2dbMF0sICh7dGhpc19vYmplY3QoKSwgb3x8d2VuMSwgZGVzdH0pLCAxKSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigKKyAgICAgICAgICAgICAgICAiRmFsc2NoZXMgRm9ybWF0IGZ1ZXIgUF9QVVRfTVNHOiAlT1xuIixvfHx3ZW4xKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gMTsKK30KKwordmFyYXJncyBpbnQgcGljayhvYmplY3QgbywgbWl4ZWQgbXNnKQoreworICAgIHN0cmluZyBzdHI7CisKKyAgICAvLyB2b3JoZXIgc3BlaWNoZXJuLCBmYWxscyBkYXMgT2JqZWt0IHplcnN0b2VydCB3aXJkCisgICAgY2wgPSBzeW1ib2xfZnVuY3Rpb24oIm5hbWUiLCBvKTsKKyAgICB3ZW4wID0gMDsKKyAgICB3ZW4xID0gZnVuY2FsbChjbCwgV0VOLCAxKTsKKyAgICB3ZXIwID0gMDsKKworICAgIGlmICghbXNnKQorICAgICAgICBtc2cgPSBvLT5RdWVyeVByb3AoUF9QSUNLX01TRyk7CisKKyAgICBpZiAoc3RyID0gcHV0X29yX2dldChvLCB0aGlzX29iamVjdCgpKSkgeworICAgICAgICBUTUUoc3RyKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgaWYgKCFtc2cpIHsKKyAgICAgICAgVE1FKCJEdSBuaW1tc3QgIiArIHdlbjEgKyAiLiIpOworICAgICAgICBTQVkoTmFtZShXRVIsIDEpICsgIiBuaW1tdCAiICsgd2VuMSArICIuIik7CisgICAgfSBlbHNlIGlmIChwb2ludGVycChtc2cpKQorICAgICAgICBzd2l0Y2ggKHNpemVvZihtc2cpKSB7CisgICAgICAgICAgY2FzZSAyOgorICAgICAgICAgICAgU0FZKHJlcGxhY2VfcGVyc29uYWwobXNnWzFdLCAoe3RoaXNfb2JqZWN0KCksIG98fHdlbjF9KSwgMSkpOworICAgICAgICAgIGNhc2UgMToKKyAgICAgICAgICAgIFRNRShyZXBsYWNlX3BlcnNvbmFsKG1zZ1swXSwgKHt0aGlzX29iamVjdCgpLCBvfHx3ZW4xfSksIDEpKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKAorICAgICAgICAgICAgICAgICJGYWxzY2hlcyBGb3JtYXQgZnVlciBQX1BJQ0tfTVNHOiAlT1xuIiwgb3x8d2VuMSkpOworICAgICAgICB9CisKKyAgICByZXR1cm4gMTsKK30KKwordmFyYXJncyBpbnQgZ2l2ZShvYmplY3Qgbywgb2JqZWN0IGRlc3QsIG1peGVkIG1zZykKK3sKKyAgICBzdHJpbmcgem5hbWUsIGduYW1lOworICAgIHN0cmluZyBzdHI7CisKKyAgICAvLyBGYWxscyBkYXMgamVtYW5kIHZvbiBhdXNzZW4gcnVmdCB1bmQgU2Nocm90dCB1ZWJlcmdpYnQuLi4KKyAgICBpZiAoIWxpdmluZyhkZXN0KSkKKyAgICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigiVG90ZXMgWmllbCBmdWVyIGdpdmUoKTogJU9cbiIsIGRlc3QpKTsKKworICAgIHpuYW1lID0gZGVzdC0+bmFtZShXRU0sIDEpOworICAgIGduYW1lID0gTmFtZShXRVIsIDEpOworCisgICAgLy8gdm9yaGVyIHNwZWljaGVybiwgZmFsbHMgZGFzIE9iamVrdCB6ZXJzdG9lcnQgd2lyZAorICAgIGNsID0gc3ltYm9sX2Z1bmN0aW9uKCJuYW1lIiwgbyk7CisgICAgd2VuMCA9IGZ1bmNhbGwoY2wsIFdFTiwgMCk7CisgICAgd2VuMSA9IGZ1bmNhbGwoY2wsIFdFTiwgMSk7CisgICAgd2VyMCA9IDA7CisKKyAgICBpZiAoIW1zZykKKyAgICAgICAgbXNnID0gby0+UXVlcnlQcm9wKFBfR0lWRV9NU0cpOworCisgICAgaWYgKHN0ciA9IHB1dF9vcl9nZXQobywgZGVzdCkpIHsKKyAgICAgICAgVE1FKHN0cik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIGlmICghbXNnKSB7CisgICAgICAgIFRNRSgiRHUgZ2lic3QgIiArIHpuYW1lICsgIiAiICsgd2VuMSArICIuIik7CisgICAgICAgIFRPQihkZXN0LCBnbmFtZSArICIgZ2lidCBEaXIgIiArIHdlbjAgKyAiLiIpOworICAgICAgICBTQVkyKCh7ZGVzdH0pLCBnbmFtZSArICIgZ2lidCAiICsgem5hbWUgKyAiICIgKyB3ZW4wICsgIi4iKTsKKyAgICB9IGVsc2UgaWYgKHBvaW50ZXJwKG1zZykpCisgICAgICAgIHN3aXRjaCAoc2l6ZW9mKG1zZykpIHsKKyAgICAgICAgICBjYXNlIDM6CisgICAgICAgICAgICBUT0IoZGVzdCwgcmVwbGFjZV9wZXJzb25hbCgKKyAgICAgICAgICAgICAgICBtc2dbMl0sICh7dGhpc19vYmplY3QoKSwgb3x8d2VuMCwgZGVzdHx8em5hbWV9KSwgMSkpOworICAgICAgICAgIGNhc2UgMjoKKyAgICAgICAgICAgIFNBWTIoKHtkZXN0LCB0aGlzX29iamVjdCgpfSksIHJlcGxhY2VfcGVyc29uYWwoCisgICAgICAgICAgICAgICAgIG1zZ1sxXSwgKHt0aGlzX29iamVjdCgpLCBvfHx3ZW4wLCBkZXN0fHx6bmFtZX0pLCAxKSk7CisgICAgICAgICAgY2FzZSAxOgorICAgICAgICAgICAgVE1FKHJlcGxhY2VfcGVyc29uYWwoCisgICAgICAgICAgICAgICAgbXNnWzBdLCAoe3RoaXNfb2JqZWN0KCksIG98fHdlbjEsIGRlc3R8fHpuYW1lfSksIDEpKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKAorICAgICAgICAgICAgICAgICJGYWxzY2hlcyBGb3JtYXQgZnVlciBQX0dJVkVfTVNHOiAlT1xuIiwgb3x8d2VuMSkpOworICAgICAgICB9CisKKyAgICBpZiAoIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoZGVzdCkpCisgICAgICAgIGRlc3QtPmdpdmVfbm90aWZ5KG8pOworCisgICAgcmV0dXJuIDE7Cit9CisKK3ZhcmFyZ3MgaW50IHNob3cob2JqZWN0IG8sIG9iamVjdCB3aG9tLCBtaXhlZCBtc2cpCit7CisgICAgc3RyaW5nIHpuYW1lLCBnbmFtZTsKKyAgICBzdHJpbmcgd2VuMCwgd2VuMiwgbG9uZzsKKworICAgIHpuYW1lID0gd2hvbSA/IHdob20tPm5hbWUoV0VNLCAxKSA6ICJhbGxlbiI7CisgICAgZ25hbWUgPSBOYW1lKFdFUiwgMSk7CisKKyAgICBpZiAoIW1zZykKKyAgICAgICAgbXNnID0gby0+UXVlcnlQcm9wKFBfU0hPV19NU0cpOworCisgICAgaWYgKGVudmlyb25tZW50KG8pID09IHRoaXNfb2JqZWN0KCkgfHwKKyAgICAgICAgZW52aXJvbm1lbnQoZW52aXJvbm1lbnQobykpID09IHRoaXNfb2JqZWN0KCkpIHsKKyAgICAgICAgd2VuMCA9IG8tPm5hbWUoV0VOLCAwKTsKKworICAgICAgICAvKiBEZXIgQWtrdXNhdGl2IG11c3MgbWl0IGRlbSB1bmJlc3RpbW10ZW4gQXJ0aWtlbCBnZWJpbGRldCB3ZXJkZW4sCisgICAgICAgICAqIGRhbWl0IGV2ZW50dWVsbGUgQWRqZWt0aXZlIGRpZSByaWNodGlnZSBFbmR1bmcgYmVzaXR6ZW4uCisgICAgICAgICAqIChlaW4ga2xlaW5lcyBTY2h3ZXJ0IC0+IGtsZWluZXMgU2Nod2VydCAtPiBEZWluIGtsZWluZXMgU2Nod2VydCkKKyAgICAgICAgICovCisKKyAgICAgICAgaWYgKG8tPlF1ZXJ5UHJvcChQX0FSVElDTEUpICYmIG1lbWJlcih3ZW4wLCAnICcpID49IDApIHsKKyAgICAgICAgICAgIGludCBvYmdlbmRlciA9IG8tPlF1ZXJ5UHJvcChQX0dFTkRFUik7CisgICAgICAgICAgICBpbnQgb2JudW0gPSBvLT5RdWVyeVByb3AoUF9BTU9VTlQpID4gMSA/IFBMVVJBTCA6IFNJTkdVTEFSOworCisgICAgICAgICAgICAvLyBXaWNodGlnOiBQX0FNT1VOVCBpc3QgMCBmdWVyIE9iamVrdGUsIGRpZSBuaWNodCB2b24gdW5pdCBlcmJlbi4KKyAgICAgICAgICAgIC8vIERhIHVuaXQuYyBrZWluIFBfQU1PVU5UPT0wIHp1bGFlc3N0LCBuZWhtZW4gd2lyIGRpZXNlbiBGYWxsIGFscworICAgICAgICAgICAgLy8gc2luZ3VsYXIgYW4uICpSdW1hdGEKKworICAgICAgICAgICAgd2VuMiA9IHdlbjBbbWVtYmVyKHdlbjAsICcgJykuLl07CisgICAgICAgICAgICB3ZW4wID0gUXVlcnlQb3NzUHJvbm91bihvLCBXRU4sIG9ibnVtKSArIHdlbjI7CisKKyAgICAgICAgICAgIGlmIChvYm51bSA9PSBQTFVSQUwgfHwgb2JnZW5kZXIgPT0gRkVNQUxFKQorICAgICAgICAgICAgICAgIHdlbjIgPSAiRGVpbmUiICsgd2VuMjsKKyAgICAgICAgICAgIGVsc2UgaWYgKG9iZ2VuZGVyID09IE1BTEUpCisgICAgICAgICAgICAgICAgd2VuMiA9ICJEZWluZW4iICsgd2VuMjsKKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICB3ZW4yID0gIkRlaW4iICsgd2VuMjsKKyAgICAgICAgfSBlbHNlCisgICAgICAgICAgICB3ZW4yID0gd2VuMDsKKyAgICB9IGVsc2UKKyAgICAgICAgd2VuMiA9IHdlbjAgPSBvLT5uYW1lKFdFTiwgMSk7CisKKyAgICAvLyB2b3JoZXIgc3BlaWNoZXJuLCBmYWxscyBkYXMgT2JqZWt0IGltIGNhdGNoX3RlbGwoKSB6ZXJzdG9lcnQgd2lyZAorICAgIGxvbmcgPSBvLT5sb25nKDQpOworCisgICAgaWYgKCFtc2cpIHsKKyAgICAgICAgVE1FKCJEdSB6ZWlnc3QgIiArIHpuYW1lICsgIiAiICsgd2VuMiArICIuIik7CisgICAgICAgIGlmICghd2hvbSkKKyAgICAgICAgICAgIFNBWShnbmFtZSArICIgemVpZ3QgRGlyICIgKyB3ZW4wICsgIi4iKTsKKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICBUT0Iod2hvbSwgZ25hbWUgKyAiIHplaWd0IERpciAiICsgd2VuMCArICIuIik7CisgICAgICAgICAgICBTQVkyKCh7d2hvbX0pLCBnbmFtZSArICIgemVpZ3QgIiArIHpuYW1lICsgIiAiICsgd2VuMCArICIuIik7CisgICAgICAgIH0KKyAgICB9IGVsc2UgaWYgKHBvaW50ZXJwKG1zZykpCisgICAgICAgIHN3aXRjaCAoc2l6ZW9mKG1zZykpIHsKKyAgICAgICAgICBjYXNlIDM6CisgICAgICAgICAgICBpZiAod2hvbSkKKyAgICAgICAgICAgICAgICBUT0Iod2hvbSwgcmVwbGFjZV9wZXJzb25hbCgKKyAgICAgICAgICAgICAgICAgICAgbXNnWzJdLCAoe3RoaXNfb2JqZWN0KCksIG98fHdlbjAsIHdob218fHpuYW1lfSksIDEpKTsKKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICBTQVkocmVwbGFjZV9wZXJzb25hbCgKKyAgICAgICAgICAgICAgICAgICAgbXNnWzJdLCAoe3RoaXNfb2JqZWN0KCksIG98fHdlbjAsIHdob218fHpuYW1lfSksIDEpKTsKKyAgICAgICAgICBjYXNlIDI6CisgICAgICAgICAgICBpZiAod2hvbSkKKyAgICAgICAgICAgICAgICBTQVkyKCh7d2hvbSwgdGhpc19vYmplY3QoKX0pLCByZXBsYWNlX3BlcnNvbmFsKAorICAgICAgICAgICAgICAgICAgICAgbXNnWzFdLCAoe3RoaXNfb2JqZWN0KCksIG98fHdlbjAsIHdob218fHpuYW1lfSksIDEpKTsKKyAgICAgICAgICBjYXNlIDE6CisgICAgICAgICAgICBUTUUocmVwbGFjZV9wZXJzb25hbCgKKyAgICAgICAgICAgICAgICBtc2dbMF0sICh7dGhpc19vYmplY3QoKSwgb3x8d2VuMiwgd2hvbXx8em5hbWV9KSwgMSkpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoCisgICAgICAgICAgICAgICAgIkZhbHNjaGVzIEZvcm1hdCBmdWVyIFBfU0hPV19NU0c6ICVPXG4iLCBvfHx3ZW4wKSk7CisgICAgICAgIH0KKworICAgIGlmICghd2hvbSkKKyAgICAgICAgU0FZKGxvbmcpOworICAgIGVsc2UgeworICAgICAgICBUT0Iod2hvbSwgbG9uZyk7CisgICAgICAgIGlmICghcXVlcnlfb25jZV9pbnRlcmFjdGl2ZSh3aG9tKSkKKyAgICAgICAgICAgIHdob20tPnNob3dfbm90aWZ5KG8pOworICAgIH0KKworICAgIHJldHVybiAxOworfQorCisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKiBIaWxmc2Z1bmt0aW9uZW4gKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8qIHByaXZhdGUgb2JqZWN0ICpfX2ZpbmRfb2JqZWN0cyhzdHJpbmcgKnRva2Vucywgb2JqZWN0IGVudiwgaW50IGlzX3NvdXJjZSk7CisgKiBvYmplY3QgKmZpbmRfb2JqZWN0cyhzdHJpbmcgd2hhdCwgb2JqZWN0IGVudiwgaW50IGlzX3NvdXJjZSk7CisgKgorICogU3VjaHQgaW0gUmF1bSB1bmQgaW0gU3BpZWxlciAob2RlciBhbHRlcm5hdGl2IGluIGRlciBhbmdlZ2ViZW5lbiBVbWdlYnVuZykKKyAqIG5hY2ggZGVuIGluIHRva2Vucy93aGF0IGJlemVpY2huZXRlbiBPYmpla3Rlbi4gaXNfc291cmNlIGJlc3RpbW10IGRpZQorICogZXJ3YXJ0ZXRlIGdyYW1tYXRpc2NoZSBGb3JtICgwIGZ1ZXIgInRvcGYgYXVmIGhlcmQiIHVuZCAxIGZ1ZXIgInRvcGYgdm9uCisgKiBoZXJkIiwgc2llaGUgTWFucGFnZSkuCisgKi8KKyAKK3ByaXZhdGUgb2JqZWN0ICpfX2ZpbmRfb2JqZWN0cyhzdHJpbmcgKnRva2Vucywgb2JqZWN0IGVudiwgaW50IGlzX3NvdXJjZSkKK3sKKyAgICBvYmplY3Qgb2IsICpvYnM7CisKKyAgICAvLyBpc19zb3VyY2UgPT0gMDogT2JqZWt0IHNvbGwgbmljaHQgYmV3ZWd0IHdlcmRlbiAoInRvcGYgYXVmIGhlcmQiKQorICAgIC8vICAgICAgICAgICAgICAxOiBPYmpla3Qgc29sbCBiZXdlZ3Qgd2VyZGVuICgidG9wZiB2b24gaGVyZCIpCisgICAgLy8gICAgICAgICAgICAgIDI6IGludGVybgorCisgICAgaWYgKCFlbnYgJiYgc2l6ZW9mKHRva2VucykgPiAxICYmIHRva2Vuc1s8MV0gPT0gImhpZXIiKSB7CisgICAgICAgIHRva2VucyA9IHRva2Vuc1suLjwyXTsKKyAgICAgICAgZW52ID0gZW52aXJvbm1lbnQoKTsKKyAgICB9CisgICAgZWxzZSBpZiAoIWVudiAmJiBzaXplb2YodG9rZW5zKSA+IDIgJiYgdG9rZW5zWzwyXSA9PSAiaW4iKQorICAgIHsKKyAgICAgICAgaWYgKHRva2Vuc1s8MV0gPT0gIm1pciIgfHwKKyAgICAgICAgICAgIHRva2Vuc1s8MV0gPT0gImRpciIpIHsKKyAgICAgICAgICAgIHRva2VucyA9IHRva2Vuc1suLjwzXTsKKyAgICAgICAgICAgIGVudiA9IHRoaXNfb2JqZWN0KCk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAodG9rZW5zWzwxXSA9PSAicmF1bSIpIHsKKyAgICAgICAgICAgIHRva2VucyA9IHRva2Vuc1suLjwzXTsKKyAgICAgICAgICAgIGVudiA9IGVudmlyb25tZW50KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBmb3IgKGludCBpID0gc2l6ZW9mKHRva2VucyktMTsgaSA+IDE7IGktLSkgeworICAgICAgICBpZiAoZW52KQorICAgICAgICAgICAgb2IgPSBwcmVzZW50KGltcGxvZGUodG9rZW5zW2kuLl0sICIgIiksIGVudik7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIG9iID0gcHJlc2VudChpbXBsb2RlKHRva2Vuc1tpLi5dLCAiICIpLCBlbnZpcm9ubWVudCgpKSB8fAorICAgICAgICAgICAgICAgICBwcmVzZW50KGltcGxvZGUodG9rZW5zW2kuLl0sICIgIiksIHRoaXNfb2JqZWN0KCkpOworCisgICAgICAgIGlmICghb2IpCisgICAgICAgICAgICBjb250aW51ZTsKKworICAgICAgICBpZiAobGl2aW5nKG9iKSkgeworICAgICAgICAgICAgTkYoIkFiZXIgIiArIG9iLT5uYW1lKFdFUiwgMSkgKyAiIGxlYnQgZG9jaCEiKTsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKG9iLT5RdWVyeVByb3AoUF9DTlRfU1RBVFVTKSkgeworICAgICAgICAgICAgTkYoIkFiZXIgIiArIG9iLT5uYW1lKFdFUiwgMSkgKyAiIGlzdCBkb2NoIGdlc2NobG9zc2VuISIpOworICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKworICAgICAgICBpZiAoaXNfc291cmNlICE9IDAgJiYKKyAgICAgICAgICAgIHRva2Vuc1tpLTFdID09IG9iLT5RdWVyeVByb3AoUF9TT1VSQ0VfUFJFUE9TSVRJT04pKQorICAgICAgICAgICAgcmV0dXJuIG9iLT5wcmVzZW50X29iamVjdHMoaW1wbG9kZSh0b2tlbnNbLi5pLTJdLCAiICIpKTsKKworICAgICAgICBpZiAodG9rZW5zW2ktMV0gPT0gb2ItPlF1ZXJ5UHJvcChQX1BSRVBPU0lUSU9OKSkKKyAgICAgICAgICAgIHJldHVybiBfX2ZpbmRfb2JqZWN0cyh0b2tlbnNbLi5pLTJdLCBvYiwgaXNfc291cmNlID8gMiA6IDApOworCisgICAgICAgIE5GKCJEdSBrYW5uc3QgbmljaHRzICIgKyB0b2tlbnNbaS0xXSArICIgIiArCisgICAgICAgICAgIG9iLT5uYW1lKFdFTSwgMSkgKyAiIG5laG1lbi4iKTsKKyAgICB9CisKKyAgICBpZiAoaXNfc291cmNlID09IDIpCisgICAgICAgIHJldHVybiAoe30pOworCisgICAgaWYgKGVudikKKyAgICAgICAgcmV0dXJuIGVudi0+cHJlc2VudF9vYmplY3RzKGltcGxvZGUodG9rZW5zLCAiICIpKTsKKworICAgIGlmIChlbnZpcm9ubWVudCgpICYmCisgICAgICAgIHNpemVvZihvYnMgPSBlbnZpcm9ubWVudCgpLT5wcmVzZW50X29iamVjdHMoaW1wbG9kZSh0b2tlbnMsICIgIikpKSkKKyAgICAgICAgcmV0dXJuIG9iczsKKworICAgIHJldHVybiBwcmVzZW50X29iamVjdHMoaW1wbG9kZSh0b2tlbnMsICIgIikpOworfQorCitvYmplY3QgKmZpbmRfb2JqZWN0cyhzdHJpbmcgd2hhdCwgb2JqZWN0IGVudiwgaW50IGlzX3NvdXJjZSkKK3sKKyAgaWYgKCFzdHJpbmdwKHdoYXQpIHx8ICFzaXplb2Yod2hhdCkpCisgICAgcmV0dXJuICh7fSk7CisgIHJldHVybiBfX2ZpbmRfb2JqZWN0cyhleHBsb2RlKHdoYXQsICIgIiksIGVudiwgaXNfc291cmNlKTsKK30KKworCisvKiB2YXJhcmdzIGludCBkcm9wX29iamVjdHMoc3RyaW5nIHN0ciwgbWl4ZWQgbXNnKTsKKyAqIHZhcmFyZ3MgaW50IHB1dF9vYmplY3RzKHN0cmluZyBzdHIsIGludCBjYXN1cywgc3RyaW5nIHZlcmIsIG1peGVkIG1zZyk7CisgKiB2YXJhcmdzIGludCBwaWNrX29iamVjdHMoc3RyaW5nIHN0ciwgaW50IGZsYWcsIG1peGVkIG1zZyk7CisgKiB2YXJhcmdzIGludCBnaXZlX29iamVjdHMoc3RyaW5nIHN0ciwgbWl4ZWQgbXNnKTsKKyAqIHZhcmFyZ3MgaW50IHNob3dfb2JqZWN0cyhzdHJpbmcgc3RyLCBtaXhlZCBtc2cpOworICoKKyAqIEVpbiBCZWZlaGwgd2llICJ3aXJmIHdhZmZlbiB3ZWciIHJlc3VsdGllcnQgaW4gZWluZW0gQXVmcnVmIHZvbgorICogZHJvcF9vYmplY3RzKCJ3YWZmZW4iKS4gRGllc2UgRnVua3Rpb25lbiBzaW5kIGhhdXB0c2FlY2hsaWNoIGZ1ZXIgZGllCisgKiBCZWhhbmRsdW5nIGRlciBqZXdlaWxpZ2VuIEtvbW1hbmRvcyB2b3JnZXNlaGVuLCBrb2VubmVuIGplZG9jaCBhdWNoIGZ1ZXIKKyAqIGVpZ2VuZSBCZWZlaGxlIHZlcndlbmRldCB3ZXJkZW4uIHB1dF9vYmplY3RzKCkgZXJ3YXJ0ZXQgYXVzc2VyZGVtIGRlbgorICogS2FzdXMgKCJEdSBrYW5uc3QgbmljaHRzIGFuIERFUiBQaW53YW5kIGJlZmVzdGlnZW4uIikgdW5kIGRhcyB2ZXJ3ZW5kZXRlCisgKiBWZXJiIGluIGRlciBHdW5kZm9ybSAoImJlZmVzdGlnZW4iKS4gRGFzIEZsYWcgZnVlciBwaWNrX29iamVjdHMoKSBnaWJ0CisgKiBhbiwgb2IgZGFzIE9iamVrdCBhdWNoIGVpbmZhY2ggaGVydW1saWVnZW4gZGFyZiAoIm5pbW0gLi4uIikgb2RlciBuaWNodAorICogKCJob2xlIC4uLiIpLiBHaWJ0IGJlaSBFcmZvbGcgMSwgc29uc3QgMCB6dXJ1ZWNrLgorICovCisKK3ZhcmFyZ3MgaW50IGRyb3Bfb2JqZWN0cyhzdHJpbmcgc3RyLCBtaXhlZCBtc2cpCit7CisgICAgb2JqZWN0ICpvYnM7CisKKyAgICBpZiAoIXNpemVvZihvYnMgPSBmaW5kX29iamVjdHMoc3RyLCB0aGlzX29iamVjdCgpLCAxKSkpCisgICAgICAgIHJldHVybiAwOworCisgICAgZm9yZWFjaCAob2JqZWN0IG86IG9icykgeworICAgICAgICBpZiAob2JqZWN0cChvKSkKKyAgICAgICAgICAgIGRyb3AobywgbXNnKTsKKworICAgICAgICBpZiAoZ2V0X2V2YWxfY29zdCgpIDwgMTAwMDAwKSB7CisgICAgICAgICAgICBUTUUoIkRlbiBSZXN0IGJlaGFlbHRzdCBEdSBlcnN0IG1hbC4iKTsKKyAgICAgICAgICAgIGxhc3RfbW92ZWRfb2JqZWN0cyA9IG9ic1suLm1lbWJlcihvYnMsIG8pXTsKKyAgICAgICAgICAgIGxhc3RfbW92ZWRfd2hlcmUgPSAwOworICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBsYXN0X21vdmVkX29iamVjdHMgPSBvYnM7CisgICAgbGFzdF9tb3ZlZF93aGVyZSA9IDA7CisgICAgcmV0dXJuIDE7Cit9CisKK3ZhcmFyZ3MgaW50IHB1dF9vYmplY3RzKHN0cmluZyBzdHIsIGludCBjYXN1cywgc3RyaW5nIHZlcmIsIG1peGVkIG1zZykKK3sKKyAgICBvYmplY3QgKm9icywgZGVzdCwgKm5vX21vdmU7CisgICAgCisgICAgaWYgKCFzdHJpbmdwKHN0cikgfHwgIXNpemVvZihzdHIpKSByZXR1cm4gMDsKKworICAgIHN0cmluZyAqdG9rZW5zID0gZXhwbG9kZShzdHIsICIgIik7CisgICAgaW50IGFsbG93X3Jvb20gPSAxOworICAgIGludCBhbGxvd19tZSA9IDE7CisKKyAgICBpZiAoc2l6ZW9mKHRva2VucykgPiAxICYmIHRva2Vuc1s8MV0gPT0gImhpZXIiKSB7CisgICAgICAgIHRva2VucyA9IHRva2Vuc1suLjwyXTsKKyAgICAgICAgYWxsb3dfbWUgPSAwOworICAgIH0gZWxzZSBpZiAoc2l6ZW9mKHRva2VucykgPiAyICYmIHRva2Vuc1s8Ml0gPT0gImluIikKKyAgICAgICAgaWYgKHRva2Vuc1s8MV0gPT0gIm1pciIgfHwKKyAgICAgICAgICAgIHRva2Vuc1s8MV0gPT0gImRpciIpIHsKKyAgICAgICAgICAgIHRva2VucyA9IHRva2Vuc1suLjwzXTsKKyAgICAgICAgICAgIGFsbG93X3Jvb20gPSAwOworICAgICAgICB9IGVsc2UgaWYgKHRva2Vuc1s8MV0gPT0gInJhdW0iKSB7CisgICAgICAgICAgICB0b2tlbnMgPSB0b2tlbnNbLi48M107CisgICAgICAgICAgICBhbGxvd19tZSA9IDA7CisgICAgICAgIH0KKworICAgIGZvciAoaW50IGkgPSBzaXplb2YodG9rZW5zKS0xOyBpID4gMTsgaS0tKSB7CisgICAgICAgIGlmICghKGRlc3QgPSBhbGxvd19yb29tICYmIHByZXNlbnQoaW1wbG9kZSh0b2tlbnNbaS4uXSwgIiAiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnZpcm9ubWVudCgpKSkgJiYKKyAgICAgICAgICAgICEoZGVzdCA9IGFsbG93X21lICYmIHByZXNlbnQoaW1wbG9kZSh0b2tlbnNbaS4uXSwgIiAiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpc19vYmplY3QoKSkpKQorICAgICAgICAgICAgY29udGludWU7CisKKyAgICAgICAgaWYgKGxpdmluZyhkZXN0KSkgeworICAgICAgICAgICAgTkYoIkFiZXIgIiArIGRlc3QtPm5hbWUoV0VSLCAxKSArICIgbGVidCBkb2NoISIpOworICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKy8qCisgICAgICAgIGlmICh2ZXJiID09ICJsZWdlbiIgJiYgIWRlc3QtPlF1ZXJ5UHJvcChQX1RSQVkpKSB7CisgICAgICAgICAgICBORigiRHUga2FubnN0IG5pY2h0cyBhdWYgIiArIGRlc3QtPm5hbWUoV0VOLCAxKSArICIgbGVnZW4uIik7CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorKi8KKyAgICAgICAgaWYgKHZlcmIgPT0gInN0ZWNrZW4iICYmICFkZXN0LT5RdWVyeVByb3AoUF9DT05UQUlORVIpKSB7CisgICAgICAgICAgICBORigiRHUga2FubnN0IGluICIgKyBkZXN0LT5uYW1lKFdFTiwgMSkgKyAiIG5pY2h0cyByZWluc3RlY2tlbi4iKTsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGRlc3QtPlF1ZXJ5UHJvcChQX0NOVF9TVEFUVVMpKSB7CisgICAgICAgICAgICBORigiQWJlciAiICsgZGVzdC0+bmFtZShXRVIsIDEpICsgIiBpc3QgZG9jaCBnZXNjaGxvc3NlbiEiKTsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHRva2Vuc1tpLTFdICE9IGRlc3QtPlF1ZXJ5UHJvcChQX0RFU1RfUFJFUE9TSVRJT04pKSB7CisgICAgICAgICAgICBORigiRHUga2FubnN0IG5pY2h0cyAiICsgdG9rZW5zW2ktMV0gKyAiICIgKworICAgICAgICAgICAgICAgZGVzdC0+bmFtZShjYXN1cywgMSkgKyAiICIgKyB2ZXJiICsgIi4iKTsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKCFzaXplb2Yob2JzID0gX19maW5kX29iamVjdHModG9rZW5zWy4uaS0yXSwgMCwgMSkgLSAoeyBkZXN0IH0pKSkgeworICAgICAgICAgICAgTkYoIldBUyBtb2VjaHRlc3QgRHUgIiArIHRva2Vuc1tpLTFdICsgIiAiICsKKyAgICAgICAgICAgICAgIGRlc3QtPm5hbWUoY2FzdXMsIDEpICsgIiAiICsgdmVyYiArICI/Iik7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzaXplb2Yobm9fbW92ZSA9IG9icyAmIGFsbF9pbnZlbnRvcnkoZGVzdCkpKSB7CisgICAgICAgICAgICBUTUUoY2FwaXRhbGl6ZShDb3VudFVwKG1hcF9vYmplY3RzKG5vX21vdmUsICJuYW1lIiwgV0VSLCAxKSkpICsKKyAgICAgICAgICAgICAgICAoc2l6ZW9mKG5vX21vdmUpID09IDEgPyAiIGlzdCIgOiAiIHNpbmQiKSArCisgICAgICAgICAgICAgICAgIiBkb2NoIGJlcmVpdHMgaW4gIiArIGRlc3QtPm5hbWUoV0VNLDEpICsgIi4iKTsKKyAgICAgICAgICAgIGlmICghc2l6ZW9mKG9icyAtPSBub19tb3ZlKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIGZvcmVhY2ggKG9iamVjdCBvOiBvYnMpIHsKKyAgICAgICAgICAgIGlmIChvYmplY3RwKG8pKQorICAgICAgICAgICAgICAgIHB1dChvLCBkZXN0LCBtc2cpOworCisgICAgICAgICAgICBpZiAoZ2V0X2V2YWxfY29zdCgpIDwgMTAwMDAwKSB7CisgICAgICAgICAgICAgICAgVE1FKCJEZW4gUmVzdCBsYWVzc3QgRHUgZXJzdCBtYWwsIHdvIGVyIGlzdC4iKTsKKyAgICAgICAgICAgICAgICBsYXN0X21vdmVkX29iamVjdHMgPSBvYnNbLi5tZW1iZXIob2JzLCBvKV07CisgICAgICAgICAgICAgICAgbGFzdF9tb3ZlZF93aGVyZSA9IGRlc3Q7CisgICAgICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBsYXN0X21vdmVkX29iamVjdHMgPSBvYnM7CisgICAgICAgIGxhc3RfbW92ZWRfd2hlcmUgPSBkZXN0OworICAgICAgICByZXR1cm4gMTsKKyAgICB9CisgICAgCisgICAgcmV0dXJuIDA7Cit9CisKK3ZhcmFyZ3MgaW50IHBpY2tfb2JqZWN0cyhzdHJpbmcgc3RyLCBpbnQgZmxhZywgbWl4ZWQgbXNnKQoreworICAgIG9iamVjdCAqb2JzOworCisgICAgaWYgKCgoaW50KVF1ZXJ5UHJvcChQX01BWF9IQU5EUykpIDwgMSl7CisgICAgICAgIE5GKCJPaG5lIEhhZW5kZSBrYW5uc3QgRHUgbmljaHRzIG5laG1lbi4iKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgaWYgKCFzaXplb2Yob2JzID0gZmluZF9vYmplY3RzKHN0ciwgMCwgMSkgLSBhbGxfaW52ZW50b3J5KCkKKwkgIC0gKGZsYWcgPyBhbGxfaW52ZW50b3J5KGVudmlyb25tZW50KCkpIDogKHt9KSkpKQorICAgICAgICByZXR1cm4gMDsKKworICAgIGZvcmVhY2ggKG9iamVjdCBvOiBvYnMpIHsKKyAgICAgICAgaWYgKG9iamVjdHAobykpCisgICAgICAgICAgICBwaWNrKG8sIG1zZyk7CisKKyAgICAgICAgaWYgKGdldF9ldmFsX2Nvc3QoKSA8IDEwMDAwMCkgeworICAgICAgICAgICAgVE1FKCJEZW4gUmVzdCBsYWVzc3QgRHUgZXJzdCBtYWwgbGllZ2VuLiIpOworICAgICAgICAgICAgbGFzdF9tb3ZlZF9vYmplY3RzID0gb2JzWy4ubWVtYmVyKG9icywgbyldOworICAgICAgICAgICAgbGFzdF9tb3ZlZF93aGVyZSA9IDA7CisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGxhc3RfbW92ZWRfb2JqZWN0cyA9IG9iczsKKyAgICBsYXN0X21vdmVkX3doZXJlID0gMDsKKyAgICByZXR1cm4gMTsKK30KKwordmFyYXJncyBpbnQgZ2l2ZV9vYmplY3RzKHN0cmluZyBzdHIsIG1peGVkIG1zZykKK3sKKyAgICBvYmplY3QgKm9icywgZGVzdDsKKyAgICAKKyAgICBpZiAoIXN0cmluZ3Aoc3RyKSB8fCAhc2l6ZW9mKHN0cikpIHJldHVybiAwOworCisgICAgc3RyaW5nICp0b2tlbnMgPSBleHBsb2RlKHN0ciwgIiAiKTsKKworICAgIGlmICgoKGludClRdWVyeVByb3AoUF9NQVhfSEFORFMpKSA8IDEpeworICAgICAgICBORigiT2huZSBIYWVuZGUga2FubnN0IER1IG5pY2h0cyB3ZWdnZWJlbi4iKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplb2YodG9rZW5zKS0xOyBpKyspIHsKKyAgICAgICAgaWYgKCEoZGVzdCA9IHByZXNlbnQoaW1wbG9kZSh0b2tlbnNbLi5pXSwgIiAiKSwgZW52aXJvbm1lbnQoKSkpKQorICAgICAgICAgICAgY29udGludWU7CisKKyAgICAgICAgaWYgKCFsaXZpbmcoZGVzdCkpIHsKKyAgICAgICAgICAgIE5GKCJBYmVyICIgKyBkZXN0LT5uYW1lKFdFUiwgMSkgKyAiIGxlYnQgZG9jaCBnYXIgbmljaHQhIik7CisgICAgICAgICAgICBkZXN0ID0gMDsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKCFzaXplb2Yob2JzID0gX19maW5kX29iamVjdHModG9rZW5zW2krMS4uXSwgMCwgMSkpKSB7CisgICAgICAgICAgICBORigiV0FTIG1vZWNodGVzdCBEdSAiICsgZGVzdC0+bmFtZShXRU0sIDEpKyIgZ2ViZW4/Iik7CisgICAgICAgICAgICBkZXN0ID0gMDsKKyAgICAgICAgfSBlbHNlCisgICAgICAgICAgICBicmVhazsKKyAgICB9CisKKyAgICBpZiAoIWRlc3QpIHsKKyAgICAgICAgaW50IHBvczsKKworICAgICAgICBpZiAoKHBvcyA9IHN0cnJzdHIoc3RyLCAiIGFuICIpKSA+PSAwKSB7CisgICAgICAgICAgICBkZXN0ID0gcHJlc2VudChzdHJbcG9zKzQuLl0sIGVudmlyb25tZW50KCkpOworICAgICAgICAgICAgLy8genUgZ2ViZW5kZSBPYmpla3RlIGluIEVudiArIExpdmluZyBzdWNoZW4KKyAgICAgICAgICAgIG9icyA9IGZpbmRfb2JqZWN0cyhzdHJbLi5wb3MtMV0sIDAsIDEpOworICAgICAgICB9CisgICAgfQorCisgICAgaWYgKCFkZXN0IHx8ICFsaXZpbmcoZGVzdCkgfHwgIXNpemVvZihvYnMpKQorICAgICAgICByZXR1cm4gMDsKKworICAgIGZvcmVhY2ggKG9iamVjdCBvOiBvYnMpIHsKKyAgICAgICAgaWYgKG9iamVjdHAobykpCisgICAgICAgICAgICBnaXZlKG8sIGRlc3QsIG1zZyk7CisKKyAgICAgICAgaWYgKGdldF9ldmFsX2Nvc3QoKSA8IDEwMDAwMCkgeworICAgICAgICAgICAgVE1FKCJEZW4gUmVzdCBiZWhhZWx0c3QgRHUgZXJzdCBtYWwuIik7CisgICAgICAgICAgICBsYXN0X21vdmVkX29iamVjdHMgPSBvYnNbLi5tZW1iZXIob2JzLCBvKV07CisgICAgICAgICAgICBsYXN0X21vdmVkX3doZXJlID0gZGVzdDsKKyAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICB9CisgICAgfQorCisgICAgbGFzdF9tb3ZlZF9vYmplY3RzID0gb2JzOworICAgIGxhc3RfbW92ZWRfd2hlcmUgPSBkZXN0OworICAgIHJldHVybiAxOworfQorCit2YXJhcmdzIGludCBzaG93X29iamVjdHMoc3RyaW5nIHN0ciwgbWl4ZWQgbXNnKQoreworICAgIG9iamVjdCAqb2JzLCB3aG9tOworICAgIAorICAgIGlmICghc3RyaW5ncChzdHIpIHx8ICFzaXplb2Yoc3RyKSkKKyAgICAgIHJldHVybiAwOworCisgICAgc3RyaW5nICp0b2tlbnMgPSBleHBsb2RlKHN0ciwgIiAiKTsKKworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZW9mKHRva2VucyktMTsgaSsrKSB7CisgICAgICAgIGlmICh3aG9tID0gcHJlc2VudChpbXBsb2RlKHRva2Vuc1suLmldLCAiICIpLCBlbnZpcm9ubWVudCgpKSkgeworICAgICAgICAgICAgaWYgKCFsaXZpbmcod2hvbSkpIHsKKyAgICAgICAgICAgICAgICBORigiQWJlciAiICsgd2hvbS0+bmFtZShXRVIsIDEpICsgIiBsZWJ0IGRvY2ggZ2FyIG5pY2h0ISIpOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKGkgIT0gMCB8fCB0b2tlbnNbMF0gIT0gImFsbGVuIikKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKworICAgICAgICAgICAgaWYgKCFzaXplb2YoZmlsdGVyKGFsbF9pbnZlbnRvcnkoZW52aXJvbm1lbnQoKSkgLQorICAgICAgICAgICAgICAgICAgICAoeyB0aGlzX29iamVjdCgpIH0pLCAjJ2xpdmluZykpKSB7CisgICAgICAgICAgICAgICAgTkYoIkhpZXIgaXN0IG5pZW1hbmQsIGRlbSBEdSBldHdhcyB6ZWlnZW4ga29lbm50ZXN0ISIpOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKHdob20gPT0gdGhpc19vYmplY3QoKSkgeworICAgICAgICAgICAgTkYoIkRhenUgc29sbHRlc3QgRHUgZGFubiBiZXNzZXIgJ3NjaGF1JyBiZW51dHplbiFcbiIpOworICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIXNpemVvZihvYnMgPSBfX2ZpbmRfb2JqZWN0cyh0b2tlbnNbaSsxLi5dLCB0aGlzX29iamVjdCgpLCAwKSkgJiYKKyAgICAgICAgICAgICFzaXplb2Yob2JzID0gX19maW5kX29iamVjdHModG9rZW5zW2krMS4uXSwgMCwgMCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAtICh7IHRoaXNfb2JqZWN0KCksIHdob20gfSkpKSB7CisgICAgICAgICAgICBORigiV0FTIG1vZWNodGVzdCBEdSAiICsgKHdob20gPyB3aG9tLT5uYW1lKFdFTSwgMSkgOiAiYWxsZW4iKSArCisgICAgICAgICAgICAgICAiIHplaWdlbj8iKTsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisKKyAgICAgICAgZm9yZWFjaCAob2JqZWN0IG86IG9icykgeworICAgICAgICAgICAgaWYgKG9iamVjdHAobykpCisgICAgICAgICAgICAgICAgc2hvdyhvLCB3aG9tLCBtc2cpOworCisgICAgICAgICAgICBpZiAoZ2V0X2V2YWxfY29zdCgpIDwgMTAwMDAwKSB7CisgICAgICAgICAgICAgICAgVE1FKCJEYXMgcmVpY2h0IGVyc3QgbWFsLiIpOworICAgICAgICAgICAgICAgIGxhc3RfbW92ZWRfb2JqZWN0cyA9IG9ic1suLm1lbWJlcihvYnMsIG8pXTsKKyAgICAgICAgICAgICAgICBsYXN0X21vdmVkX3doZXJlID0gd2hvbTsKKyAgICAgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGxhc3RfbW92ZWRfb2JqZWN0cyA9IG9iczsKKyAgICAgICAgbGFzdF9tb3ZlZF93aGVyZSA9IHdob207CisgICAgICAgIHJldHVybiAxOworICAgIH0KKworICAgIHJldHVybiAwOworfQorCitvYmplY3QgKm1vdmVkX29iamVjdHModm9pZCkKK3sKKyAgICByZXR1cm4gbGFzdF9tb3ZlZF9vYmplY3RzOworfQorCitvYmplY3QgbW92ZWRfd2hlcmUodm9pZCkKK3sKKyAgICByZXR1cm4gbGFzdF9tb3ZlZF93aGVyZTsKK30KKworCisvKioqKioqKioqKioqKioqKioqKioqKioqKiBEaWUgZWluemVsbmVuIEtvbW1hbmRvcyAqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLyogc3RhdGljIGludCBmYWxsZW5sYXNzZW4oc3RyaW5nIHN0cikKKyAqIHN0YXRpYyBpbnQgd2VyZmVuKHN0cmluZyBzdHIpCisgKiBzdGF0aWMgaW50IGxlZ2VuKHN0cmluZyBzdHIpCisgKiBzdGF0aWMgaW50IHN0ZWNrZW4oc3RyaW5nIHN0cikKKyAqIHN0YXRpYyBpbnQgaG9sZW4oc3RyaW5nIHN0cikKKyAqIHN0YXRpYyBpbnQgbmVobWVuKHN0cmluZyBzdHIpCisgKiBzdGF0aWMgaW50IGdlYmVuKHN0cmluZyBzdHIpCisgKiAgIE1pbmltYWxlIFdyYXBwZXIgZnVlciBYWFhfb2JqZWN0cygpLCBlbnRmZXJuZW4gImZhbGxlbiIsICJ3ZWciIGJ6dy4gImFiIgorICogICBhdXMgZGVuIEFyZ3VtZW50ZW4gdW5kIHNldHplbiBlbnRzcHJlY2hlbmRlIFN0YW5kYXJkLUZlaGxlcm1lbGR1bmdlbi4KKyAqICAgCisgKiBwcm90ZWN0ZWQgdm9pZCBhZGRfcHV0X2FuZF9nZXRfY29tbWFuZHMoKQorICogICBSZWdpc3RyaWVydCBvYmlnZSBGdW5rdGlvbmVuIHBlciBhZGRfYWN0aW9uKCkuCisgKi8KKworc3RhdGljIGludCBmYWxsZW5sYXNzZW4oc3RyaW5nIHN0cikKK3sKKyAgICBpZiAoUXVlcnlQcm9wKFBfR0hPU1QpKSB7CisgICAgICAgIF9ub3RpZnlfZmFpbCgiQWxzIEdlaXN0IGthbm5zdCBEdSBuaWNodHMgZmFsbGVubGFzc2VuLlxuIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIGlmICghc3RyIHx8IHN0cls8Ny4uXSAhPSAiIGZhbGxlbiIpIHsKKyAgICAgICAgX25vdGlmeV9mYWlsKCJMYXNzIGV0d2FzIEZBTExFTiwgb2RlciB3YXMgbWVpbnN0IER1P1xuIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIF9ub3RpZnlfZmFpbCgiV0FTIG1vZWNodGVzdCBEdSBmYWxsZW5sYXNzZW4/XG4iKTsKKyAgICByZXR1cm4gZHJvcF9vYmplY3RzKHN0clswLi48OF0pOworfQorCitzdGF0aWMgaW50IHdlcmZlbihzdHJpbmcgc3RyKQoreworICAgIGlmIChRdWVyeVByb3AoUF9HSE9TVCkpIHsKKyAgICAgICAgX25vdGlmeV9mYWlsKCJBbHMgR2Vpc3Qga2FubnN0IER1IG5pY2h0cyB3ZWd3ZXJmZW4uXG4iKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgaWYgKCFzdHIgfHwgc3RyWzw0Li5dICE9ICIgd2VnIikgeworICAgICAgICBfbm90aWZ5X2ZhaWwoIldpcmYgZXR3YXMgV0VHLCBvZGVyIHdhcyBtZWluc3QgRHU/XG4iKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgX25vdGlmeV9mYWlsKCJXQVMgbW9lY2h0ZXN0IER1IGxvc3dlcmRlbj9cbiIpOworICAgIHJldHVybiBkcm9wX29iamVjdHMoc3RyWzAuLjw1XSk7Cit9CisKK3N0YXRpYyBpbnQgbGVnZW4oc3RyaW5nIHN0cikKK3sKKyAgICBpZiAoUXVlcnlQcm9wKFBfR0hPU1QpKSB7CisgICAgICAgIF9ub3RpZnlfZmFpbCgiQWxzIEdlaXN0IGthbm5zdCBEdSBuaWNodHMgd2VnbGVnZW4uXG4iKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgaWYgKCFzdHIpIHsKKyAgICAgICAgX25vdGlmeV9mYWlsKCJMZWdlIGV0d2FzIEFCLCBvZGVyIHdhcyBtZWluc3QgRHU/XG4iKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgaWYgKHN0cls8My4uXSA9PSAiIGFiIikgeworICAgICAgICBfbm90aWZ5X2ZhaWwoIldBUyBtb2VjaHRlc3QgRHUgYWJsZWdlbj9cbiIpOworICAgICAgICByZXR1cm4gZHJvcF9vYmplY3RzKHN0clswLi48NF0pOworICAgIH0KKworICAgIGlmIChzdHJbPDQuLl0gPT0gIiB3ZWciKSB7CisgICAgICAgIF9ub3RpZnlfZmFpbCgiV0FTIG1vZWNodGVzdCBEdSB3ZWdsZWdlbj9cbiIpOworICAgICAgICByZXR1cm4gZHJvcF9vYmplY3RzKHN0clswLi48NV0pOworICAgIH0KKworICAgIF9ub3RpZnlfZmFpbCgiV0FTIG1vZWNodGVzdCBEdSBXT0hJTiBsZWdlbj9cbiIpOworICAgIHJldHVybiBwdXRfb2JqZWN0cyhzdHIsIFdFTiwgImxlZ2VuIik7Cit9CisKK3N0YXRpYyBpbnQgc3RlY2tlbihzdHJpbmcgc3RyKQoreworICAgIGlmIChRdWVyeVByb3AoUF9HSE9TVCkpIHsKKyAgICAgICAgX25vdGlmeV9mYWlsKCJEYXMga2FubnN0IER1IGluIERlaW5lbSBpbW1hdGVyaWVsbGVuIFp1c3RhbmQgbmljaHQuXG4iKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgX25vdGlmeV9mYWlsKCJXQVMgbW9lY2h0ZXN0IER1IFdPSElOIHN0ZWNrZW4/XG4iKTsKKyAgICByZXR1cm4gcHV0X29iamVjdHMoc3RyLCBXRU4sICJzdGVja2VuIik7Cit9CisKK3N0YXRpYyBpbnQgaG9sZW4oc3RyaW5nIHN0cikKK3sKKyAgICBpZiAoUXVlcnlQcm9wKFBfR0hPU1QpKSB7CisgICAgICAgIF9ub3RpZnlfZmFpbCgiQWxzIEdlaXN0IGthbm5zdCBEdSBuaWNodHMgbmVobWVuLlxuIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIF9ub3RpZnlfZmFpbCgiV0FTIG1vZWNodGVzdCBEdSBhdXMgV0FTIGhvbGVuP1xuIik7CisgICAgcmV0dXJuIHBpY2tfb2JqZWN0cyhzdHIsIDEpOworfQorCitzdGF0aWMgaW50IG5laG1lbihzdHJpbmcgc3RyKQoreworICAgIGlmIChRdWVyeVByb3AoUF9HSE9TVCkpIHsKKyAgICAgICAgX25vdGlmeV9mYWlsKCJBbHMgR2Vpc3Qga2FubnN0IER1IG5pY2h0cyBuZWhtZW4uXG4iKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgX25vdGlmeV9mYWlsKCJXQVMgbW9lY2h0ZXN0IER1IG5laG1lbj9cbiIpOworICAgIHJldHVybiBwaWNrX29iamVjdHMoc3RyLCAwKTsKK30KKworc3RhdGljIGludCBnZWJlbihzdHJpbmcgc3RyKQoreworICAgIGlmIChRdWVyeVByb3AoUF9HSE9TVCkpIHsKKyAgICAgICAgX25vdGlmeV9mYWlsKCJBbHMgR2Vpc3Qga2FubnN0IER1IG5pY2h0cyB3ZWdnZWJlbi5cbiIpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBfbm90aWZ5X2ZhaWwoIldFTSBtb2VjaHRlc3QgRHUgV0FTIGdlYmVuP1xuIik7CisgICAgcmV0dXJuIGdpdmVfb2JqZWN0cyhzdHIpOworfQorCitzdGF0aWMgaW50IHplaWdlbihzdHJpbmcgc3RyKQoreworICAgIGlmIChRdWVyeVByb3AoUF9HSE9TVCkpIHsKKyAgICAgICAgX25vdGlmeV9mYWlsKCJBbHMgR2Vpc3Qga2FubnN0IER1IG5pZW1hbmRlbSBldHdhcyB6ZWlnZW4uXG4iKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgX25vdGlmeV9mYWlsKCJXRU0gbW9lY2h0ZXN0IER1IFdBUyB6ZWlnZW4/XG4iKTsKKyAgICByZXR1cm4gc2hvd19vYmplY3RzKHN0cik7Cit9CisKK3Byb3RlY3RlZCB2b2lkIGFkZF9wdXRfYW5kX2dldF9jb21tYW5kcyh2b2lkKQoreworICAgIGFkZF9hY3Rpb24oImZhbGxlbmxhc3NlbiIsICJsYXNzIik7CisgICAgYWRkX2FjdGlvbigiZmFsbGVubGFzc2VuIiwgImxhc3NlIik7CisgICAgYWRkX2FjdGlvbigid2VyZmVuIiwgICAgICAgIndpcmYiKTsKKyAgICBhZGRfYWN0aW9uKCJ3ZXJmZW4iLCAgICAgICAid2VyZiIpOworICAgIGFkZF9hY3Rpb24oIndlcmZlbiIsICAgICAgICJ3ZXJmZSIpOworICAgIGFkZF9hY3Rpb24oImxlZ2VuIiwgICAgICAgICJsZWciKTsKKyAgICBhZGRfYWN0aW9uKCJsZWdlbiIsICAgICAgICAibGVnZSIpOworICAgIGFkZF9hY3Rpb24oInN0ZWNrZW4iLCAgICAgICJzdGVjayIpOworICAgIGFkZF9hY3Rpb24oInN0ZWNrZW4iLCAgICAgICJzdGVja2UiKTsKKyAgICBhZGRfYWN0aW9uKCJob2xlbiIsICAgICAgICAiaG9sIik7CisgICAgYWRkX2FjdGlvbigiaG9sZW4iLCAgICAgICAgImhvbGUiKTsKKyAgICBhZGRfYWN0aW9uKCJuZWhtZW4iLCAgICAgICAibmltbSIpOworICAgIGFkZF9hY3Rpb24oIm5laG1lbiIsICAgICAgICJuZWhtIik7CisgICAgYWRkX2FjdGlvbigibmVobWVuIiwgICAgICAgIm5laG1lIik7CisgICAgYWRkX2FjdGlvbigiZ2ViZW4iLCAgICAgICAgImdlYmUiKTsKKyAgICBhZGRfYWN0aW9uKCJnZWJlbiIsICAgICAgICAiZ2liIik7CisgICAgYWRkX2FjdGlvbigiemVpZ2VuIiwgICAgICAgInplaWciKTsKKyAgICBhZGRfYWN0aW9uKCJ6ZWlnZW4iLCAgICAgICAiemVpZ2UiKTsKK30KKworCisvKioqKioqKioqKiBBdXMgcmVpbmVuIEtvbXBhdGliaWxpdGFldHNncnVlbmRlbiB3ZWl0ZXJoaW4gZW50aGFsdGVuICoqKioqKioqKi8KKworb2JqZWN0KiBmaW5kX29icyhzdHJpbmcgc3RyLCBpbnQgbWV0aCkKKy8vIGdpYnQgZWluIGFycmF5IHp1cnVlY2sgbWl0IGFsbGVuIE9iamVrdGVuIGRpZSBtaXQgc3RyIGFuZ2VzcHJvY2hlbiB3ZXJkZW4KK3sKKyAgIG9iamVjdCBpbnY7CisgICBpZiAoIXN0cikgcmV0dXJuIDA7CisgICBpZiAoc3RyWzw3Li5dPT0iIGluIG1pciIpIHsKKyAgICAgaW52PU1FOworICAgICBzdHI9c3RyWzAuLjw4XTsKKyAgIH0KKyAgIGVsc2UgaWYgKHN0cls8OC4uXT09IiBpbiByYXVtIikgeworICAgICBpZiAobWV0aCAmIFBVVF9HRVRfRFJPUCkgeyAvLyBtYW4ga2FubiBuaWNodHMgYXVzIGRlbSBSYXVtIHdlZ3dlcmZlbgorICAgICAgIF9ub3RpZnlfZmFpbCgiRHUga2FubnN0IG5pY2h0cyB3ZWd3ZXJmZW4sIGRhcyBEdSBnYXIgbmljaHQgaGFzdC5cbiIpOworICAgICAgIHJldHVybiAwOworICAgICB9CisgICAgIGludj1lbnZpcm9ubWVudCgpOworICAgICBzdHI9c3RyWzAuLjw5XTsKKyAgIH0KKyAgIGVsc2UgaWYgKG1ldGggJiBQVVRfR0VUX0RST1ApIGludj1NRTsgLy8gUmF1bSBiZWkgZHJvcCB1bmludGVyZXNzYW50CisgICAvLyBlbHNlIGtlaW4gYmVzb25kZXJlcyBpbnYgYXVzZ2V3YWVobHQgYWxzbyBpbnY9MAorICAgaWYgKCFzaXplb2Yoc3RyKSkKKyAgICAgcmV0dXJuIDA7IC8vIGhpZXIgcGFzc3QgZGllIGJlcmVpdHMgZ2VzZXR6dGUgX25vdGlmeV9mYWlsCisgICBlbHNlIHsKKyAgICAgb2JqZWN0ICpvYnM7CisgICAgIHN0cmluZyBjb247CisgICAgIGlmIChzc2NhbmYoc3RyLCAiJXMgYXVzICVzIiwgc3RyLCBjb24pPT0yIHx8CisgICAgICAgICBzc2NhbmYoc3RyLCAiJXMgaW4gJXMiLCBzdHIsIGNvbik9PTIgfHwKKyAgICAgICAgIHNzY2FuZihzdHIsICIlcyB2b24gJXMiLCBzdHIsIGNvbik9PTIgfHwKKyAgICAgICAgIHNzY2FuZihzdHIsICIlcyB2b20gJXMiLCBzdHIsIGNvbik9PTIpIHsKKyAgICAgICBpZiAoIWludikgeworICAgICAgICAgaWYgKCFlbnZpcm9ubWVudCgpIHx8ICEoaW52PXByZXNlbnQoY29uLCBlbnZpcm9ubWVudCgpKSkpCisgICAgICAgICAgICBpbnY9cHJlc2VudChjb24sIE1FKTsgLy8gc293b2hsIGltIGVudiBhbHMgYXVjaCBpbSBpbnYgc3VjaGVuCisgICAgICAgfQorICAgICAgIGVsc2UgaW52PXByZXNlbnQoY29uLCBpbnYpOyAvLyBudXIgaW4gYXVzZ2V3YWVobHRlbSBpbnYgc3VjaGVuCisgICAgICAgaWYgKGludj09TUUpIGludj0wOworICAgICAgIGlmICghaW52IHx8ICEoaW52LT5zaG9ydCgpKSkgeworICAgICAgICAgX25vdGlmeV9mYWlsKGJyZWFrX3N0cmluZygiRHUgaGFzdCBoaWVyIGFiZXIga2VpbiAnIitjYXBpdGFsaXplKGNvbikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsiJy4iLDc4KSk7CisgICAgICAgICByZXR1cm4gMDsKKyAgICAgICB9CisgICAgICAgaWYgKGxpdmluZyhpbnYpKSB7CisgICAgICAgICBfbm90aWZ5X2ZhaWwoYnJlYWtfc3RyaW5nKCJBYmVyICIraW52LT5uYW1lKFdFUiwxKSsiIGxlYnQgZG9jaCEiLDc4KSk7CisgICAgICAgICByZXR1cm4gMDsKKyAgICAgICB9CisgICAgICAgLy8gd2llc28gbWFuIGF1cyBPYmpla3RlbiBkaWUgdm9uIHN0ZC90cmF5IGFiZ2VsZWl0ZXQgd2VyZGVuIGV0d2FzCisgICAgICAgLy8gbmVobWVuIGtvZW5uZW4gc29sbCwgdmVyc3RlaCBpY2ggendhciBuaWNodCBzbyBnYW56Li4uCisgICAgICAgaWYgKCEoaW52LT5RdWVyeVByb3AoUF9DT05UQUlORVIpKSAmJiAhKGludi0+UXVlcnlQcm9wKFBfVFJBWSkpKSB7CisgICAgICAgICBfbm90aWZ5X2ZhaWwoYnJlYWtfc3RyaW5nKCJEdSBrYW5uc3QgbmljaHRzIGF1cyAiK2ludi0+bmFtZShXRU0sMSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsiIG5laG1lbi4iLDc4KSk7CisgICAgICAgICByZXR1cm4gMDsKKyAgICAgICB9CisgICAgICAgaWYgKGludi0+UXVlcnlQcm9wKFBfQ05UX1NUQVRVUykpIHsgLy8gQ29udGFpbmVyIGlzdCBnZXNjaGxvc3NlbgorICAgICAgICAgX25vdGlmeV9mYWlsKGJyZWFrX3N0cmluZygiQWJlciAiK2ludi0+bmFtZShXRVIsMSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsiIGlzdCBkb2NoIGdlc2NobG9zc2VuLiIsIDc4KSk7CisgICAgICAgICByZXR1cm4gMDsKKyAgICAgICB9CisgICAgIH0KKyAgICAgZWxzZSBpZiAoaW52PT1NRSAmJiAobWV0aCAmIFBVVF9HRVRfVEFLRSkpIHsgLy8gbmljaHRzIGF1cyBzaWNoIG5laG1lbgorICAgICAgIF9ub3RpZnlfZmFpbCgiRHUga2FubnN0IG5pY2h0cyBuZWhtZW4sICIKKyAgICAgICAgICAgICAgICAgICAgIndhcyBEdSBzY2hvbiBiZWkgRGlyIHRyYWVnc3QuXG4iKTsKKyAgICAgICByZXR1cm4gMDsKKyAgICAgfQorICAgICBpZiAoIWludiAmJiAobWV0aCAmIFBVVF9HRVRfVEFLRSkpCisgICAgICAgaW52PWVudmlyb25tZW50KCk7IC8vIG5pY2h0cyBuZWhtZW4gd2FzIG1hbiBzY2hvbiBoYXQKKworICAgICBpZiAoIWludikgeworICAgICAgIGlmIChlbnZpcm9ubWVudCgpKSB7CisgICAgICAgICBvYnM9KGVudmlyb25tZW50KCktPnByZXNlbnRfb2JqZWN0cyhzdHIpfHwoe30pKTsKKyAgICAgICAgIGlmICghc2l6ZW9mKG9icykpIG9icys9KE1FLT5wcmVzZW50X29iamVjdHMoc3RyKXx8KHt9KSk7CisgICAgICAgfQorICAgICAgIGVsc2Ugb2JzPShNRS0+cHJlc2VudF9vYmplY3RzKHN0cikgfHwgKHt9KSk7CisgICAgIH0KKyAgICAgZWxzZSBvYnM9KGludi0+cHJlc2VudF9vYmplY3RzKHN0cikgfHwgKHt9KSk7CisgICAgIHJldHVybiBvYnMtKHsgTUUgfSk7CisgICB9CisgICByZXR1cm4oMCk7Cit9CisKK2ludCBwaWNrX29iaihvYmplY3Qgb2IpCit7CisgIG9iamVjdCBlbnY7CisKKyAgaWYgKCFvYiB8fCBvYiA9PSB0aGlzX29iamVjdCgpIHx8IGVudmlyb25tZW50KG9iKSA9PSB0aGlzX29iamVjdCgpKSByZXR1cm4gMDsKKyAgaWYgKChlbnY9ZW52aXJvbm1lbnQob2IpKSAhPSBlbnZpcm9ubWVudCgpKSB7CisgICAgaWYgKCFlbnYtPlF1ZXJ5UHJvcChQX0NPTlRBSU5FUikgJiYgIWVudi0+UXVlcnlQcm9wKFBfVFJBWSkpIHsKKyAgICAgIFRNRSgiRHUga2FubnN0IG5pY2h0cyBhdXMgIiArIGVudi0+bmFtZShXRU0sMSkgKyAiIG5laG1lbi4iKTsKKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgICBlbHNlIGlmIChlbnYtPlF1ZXJ5UHJvcChQX0NOVF9TVEFUVVMpKSB7ICAvLyBDb250YWluZXIgaXN0IGdlc2NobG9zc2VuCisgICAgICBUTUUoIkFiZXIgIiArIGVudi0+bmFtZShXRVIsIDEpICsgIiBpc3QgZG9jaCBnZXNjaGxvc3Nlbi4iKTsKKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgfQorICBpZiAob2ItPklzVW5pdCgpICYmIG9iLT5RdWVyeVByb3AoUF9BTU9VTlQpPDApIHsKKyAgICBUTUUoIkR1IGthbm5zdCBuaWNodCBtZWhyIG5laG1lbiBhbHMgZGEgaXN0LiIpOworICAgIHJldHVybiAxOworICB9CisgIHBpY2sob2IpOworICByZXR1cm4gMTsKK30KKworaW50IGRyb3Bfb2JqKG9iamVjdCBvYikKK3sKKyAgaWYgKCFvYiB8fCBvYj09dGhpc19vYmplY3QoKSB8fCBlbnZpcm9ubWVudChvYikhPXRoaXNfb2JqZWN0KCkpIHJldHVybiAwOworICBkcm9wKG9iKTsKKyAgcmV0dXJuIDE7Cit9CisKK2ludCBwdXRfb2JqKG9iamVjdCBvYiwgb2JqZWN0IHdoZXJlKQoreworICBvYmplY3QgZW52OworCisgIGlmIChvYiA9PSB0aGlzX29iamVjdCgpIHx8IG9iID09IHdoZXJlIHx8IGVudmlyb25tZW50KG9iKSA9PSB3aGVyZSkgcmV0dXJuIDA7CisgIGVudj1lbnZpcm9ubWVudChvYik7CisgIGlmICghd2hlcmUtPlF1ZXJ5UHJvcChQX0NPTlRBSU5FUikpIHsKKyAgICBUTUUoIkR1IGthbm5zdCBpbiAiICsgd2hlcmUtPm5hbWUoV0VOLDEpICsgIiBuaXggcmVpbnN0ZWNrZW4uIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaWYgKHdoZXJlLT5RdWVyeVByb3AoUF9DTlRfU1RBVFVTKSkgeyAgLy8gQ29udGFpbmVyIGlzdCBnZXNjaGxvc3NlbgorICAgIFRNRSgiQWJlciAiICsgd2hlcmUtPm5hbWUoV0VSLCAxKSArICIgaXN0IGRvY2ggZ2VzY2hsb3NzZW4uIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaWYgKGVudiE9ZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSkgJiYgZW52IT10aGlzX29iamVjdCgpKSB7CisgICAgX25vdGlmeV9mYWlsKCJEYSBrb21tc3QgZHUgc28gbmljaHQgcmFuLlxuIik7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgcHV0KG9iLCB3aGVyZSk7CisgIHJldHVybiAxOworfQorCitpbnQgZ2l2ZV9vYmoob2JqZWN0IG9iLCBvYmplY3Qgd2hlcmUpCit7CisgIG9iamVjdCBlbnY7CisKKyAgaWYgKGVudmlyb25tZW50KG9iKSE9dGhpc19vYmplY3QoKSkgeworICAgIFRNRSgiRGFzIHNvbGx0ZXN0IER1IGVyc3RtYWwgbmVobWVuLiIpOworICAgIHJldHVybiAxOworICB9CisgIGlmICghb2IgfHwgb2IgPT0gdGhpc19vYmplY3QoKSB8fCBvYiA9PSB3aGVyZSB8fAorICAgICAgZW52aXJvbm1lbnQod2hlcmUpIT1lbnZpcm9ubWVudCgpKQorICAgIHJldHVybiAwOworICBpZiAoZW52aXJvbm1lbnQob2IpID09IHdoZXJlKSB7CisgICAgX25vdGlmeV9mYWlsKCJEYXMgWmllbCBpc3QgaW4gZGVtIHp1IGdlYmVuZGVuIE9iamVjdCBlbnRoYWx0ZW4hXG4iKTsKKyAgICByZXR1cm4gMDsKKyAgfQorICBpZiAoZW52aXJvbm1lbnQob2IpIT10aGlzX29iamVjdCgpKSB7CisgICAgVE1FKCJEYXMgaGFzdCBEdSBuaWNodC4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBnaXZlKG9iLCB3aGVyZSk7CisgIHJldHVybiAxOworfQpkaWZmIC0tZ2l0IGEvc3RkL2xpdmluZy9za2lsbF9hdHRyaWJ1dGVzLmMgYi9zdGQvbGl2aW5nL3NraWxsX2F0dHJpYnV0ZXMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZDkwYWEwCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL2xpdmluZy9za2lsbF9hdHRyaWJ1dGVzLmMKQEAgLTAsMCArMSwzNzkgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBsaXZpbmcvc2tpbGxzX2F0dHJpYnV0ZXMuYyAtIFZlcndhbHR1bmcgZGVyIFNraWxsYXR0cmlidXRlIHZvbiBMZWJld2VzZW4KKy8vCisvLyAkSWQ6IHNraWxscy5jIDY2NzMgMjAwOC0wMS0wNSAyMDo1Nzo0M1ogWmVzc3RyYSAkCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKK2luaGVyaXQgIi9zdGQvdXRpbC9leGVjdXRlciI7CisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8bGl2aW5nL3NraWxsX2F0dHJpYnV0ZXMuaD4KKyNpbmNsdWRlIDxwbGF5ZXIvbGlmZS5oPgorI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyN1bmRlZiBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGRlZmluZXMuaD4KKworLy8jZGVmaW5lIFpERUJVRyh4KSBpZiAoZmluZF9wbGF5ZXIoInplc3N0cmEiKSkgdGVsbF9vYmplY3QoZmluZF9wbGF5ZXIoInplc3N0cmEiKSx4KQorI2RlZmluZSBaREVCVUcoeCkKKy8vI2RlZmluZSBTQVNFVExPRyh4KSBsb2dfZmlsZSgiU0FTRVQuTE9HIiwgeCwgMjUwMDAwKQorCisvLyNkZWZpbmUgX19ERUJVR19fCisKKy8vIFZhcmlhYmxlIGZ1ZXIgZGllIFNraWxsLUF0dHJpYnV0ZSwgRGF0ZW5zdHJ1a3R1cjoKKy8qICAoWyBTQV9BVFRSOiAoe1N1bW1lX1N0YXRfTW9kaWZpZXIsIFplaXRwdW5rdCwgQW56YWhsTW9kaWZpZXIsIH0pOworICAgICAgICAgICAgICAoWyBvYjE6dmFsdWU7ZHVyYXRpb24sCisgICAgICAgICAgICAgICAgIG9iMjp2YWx1ZTtkdXJhdGlvbiwgLi4uXSk7ICAvLyBzdGF0LiBNb2RpZmllcgorICAgICAgICAgICAgICAoWyBvYjE6Y2xvc3VyZTtkdXJhdGlvbiwKKyAgICAgICAgICAgICAgICAgb2IyOmNsb3N1cmU7ZHVyYXRpb24sIC4uLl0pICAgICAvLyBkeW4uIE1vZGlmaWVyCisgICAgICAgICAgICAgLAorICAgICBTQV9BVFRSMjogKHsuLi59KTsgKFtdKTsgKFtdKSwKKyAgIF0pICovCitwcml2YXRlIG5vc2F2ZSBtYXBwaW5nIHNraWxsYXR0cnM7CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpIHsKKyAgU2V0KFBfU0tJTExfQVRUUklCVVRFUywgU0VDVVJFRCwgRl9NT0RFX0FTKTsKK30KKworLy8gdm9uIGF1c3NlbiBQcm9wIHNldHplbiBpc3QgbmljaHQuLi4KK21hcHBpbmcgX3NldF9za2lsbF9hdHRyKG1hcHBpbmcgc2EpIHsKKyAgcmV0dXJuIGRlZXBfY29weShza2lsbGF0dHJzKTsKK30KKy8vIHVuZCBhdWNoIGJlaW0gQWJmcmFnZW4gbnVyIGtvcGllbiBsaWVmZXJuLiA7LSkKK21hcHBpbmcgX3F1ZXJ5X3NraWxsX2F0dHIoKSB7CisgIHJldHVybiBkZWVwX2NvcHkoc2tpbGxhdHRycyk7CisKKy8vVE9ETzogRXZ0bC4gZXh0LiBTZXR6ZW4gdm9uIFBfU0tJTExfQVRUUklCVVRFX09GRlNFVFMgbWl0bG9nZ2VuPworfQorCitwcml2YXRlIHZvaWQgVXBkYXRlU0FDYWNoZShzdHJpbmcgKmF0dHJzKSB7CisjaWZkZWYgX19ERUJVR19fCisgICAgaWYgKGdldHVpZCh0aGlzX29iamVjdCgpKSA9PSAiemVzc3RyYSIpCisgICAgWkRFQlVHKHNwcmludGYoIiVPXG4iLHNraWxsYXR0cnMpKTsKKyNlbmRpZgorICBpZiAoIW1hcHBpbmdwKHNraWxsYXR0cnMpKSByZXR1cm47CisgIGlmICghcG9pbnRlcnAoYXR0cnMpIHx8IHNpemVvZihhdHRycykpCisgICAgYXR0cnMgPSBtX2luZGljZXMoc2tpbGxhdHRycyk7IC8vIGFsbGUKKyAgLy8gc29uc3Qgc2Nobml0dG1lbmdlIGF1cyBleGlzdGllcmVuZGVuIHVuZCBkZW4gdWViZXJnZWJlbmVuLgorICBhdHRycyA9IG1faW5kaWNlcyhza2lsbGF0dHJzKSAmIGF0dHJzOworCisgIC8vIHVuZCBqZXR6dCB1ZWJlciBhbGxlIGdld3VlbnNjaHRlbiBTQXMgZHJ1ZWJlcgorICBmb3JlYWNoKHN0cmluZyBhdHRyIDogYXR0cnMpIHsKKyAgICBpbnQgKmNhY2hlID0gc2tpbGxhdHRyc1thdHRyLCBTQU1fQ0FDSEVdOworICAgIG1hcHBpbmcgc3RhdCA9IHNraWxsYXR0cnNbYXR0ciwgU0FNX1NUQVRJQ107CisgICAgbWFwcGluZyBkeW4gPSBza2lsbGF0dHJzW2F0dHIsIFNBTV9EWU5BTUlDXTsKKyAgICBpbnQgc3VtID0gMDsKKyAgICBpbnQgdGltZW91dCA9IF9fSU5UX01BWF9fOworIAorICAgIC8vIHVlYmVyIHN0YXQuIE1vZHMgaXRlcmllcmVuIHVuZCBBdWZzdW1taWVyZW4sIGtsZWluc3RlbiBUaW1lb3V0CisgICAgLy8gZXJtaXR0ZWxuLgorICAgIGZvcmVhY2gob2JqZWN0IG9iLCBpbnQgdmFsdWUsIGludCBkdXJhdGlvbjogc3RhdCkgeworICAgICAgLy8gZ3VlbHRpZ2UgTW9kcyBhdWZhZGRpZXJlbiwgYWJnZWxhdWZlbmUgcmF1c3dlcmZlbgorICAgICAgaWYgKGR1cmF0aW9uID49IHRpbWUoKSkgeworICAgICAgICBzdW0gKz0gdmFsdWU7CisgICAgICAgIGlmIChkdXJhdGlvbiA8IHRpbWVvdXQpCisgICAgICAgICAgdGltZW91dCA9IGR1cmF0aW9uOworICAgICAgfQorICAgICAgZWxzZQorICAgICAgICBtX2RlbGV0ZShzdGF0LCBvYik7IC8vIGphLCBnZWh0IGltIGZvcmVhY2ggOy0pCisgICAgfQorICAgIC8vIEFibGF1ZnplaXRlbiBkZXIgZHluLiBNb2RzIHBydWVmZW4sIHdhZXJlIGhpZXIgendhciBuaWNodCB1bmJlZGluZ3QKKyAgICAvLyBub2V0aWcgc29uZGVybiBrb2VubnRlIG1hbiBhdXNzY2hsaWVzc2xpY2ggaW0gUXVlcnlTa2lsbEF0dHJpYnV0ZSgpCisgICAgLy8gbWFjaGVuLCBhYmVyIGRhbm4gd2FlcmUgZGllIEVybWl0dGx1bmcgZGVyIFN1bW1lIGRlciBNb2RzIHNjaHdpZXJpZ2VyLgorICAgIGZvcmVhY2gob2JqZWN0IG9iLCBjbG9zdXJlIHZhbHVlLCBpbnQgZHVyYXRpb246IGR5bikgeworICAgICAgaWYgKGR1cmF0aW9uIDwgdGltZSgpKQorICAgICAgICBtX2RlbGV0ZShkeW4sIG9iKTsgLy8gdW5ndWVsdGlnLCB3ZWcgZGFtaXQuCisgICAgfQorICAgIC8vIGdlc2FtdHphaGwgTW9kcz8KKyAgICBjYWNoZVtTQU1fQ09VTlRdID0gc2l6ZW9mKHN0YXQpICsgc2l6ZW9mKGR5bik7CisgICAgaWYgKCFjYWNoZVtTQU1fQ09VTlRdKSB7CisgICAgICAvLyBrZWluZSBtb2RzIGRhLCBTdWJtYXBwaW5nIGZ1ZXIgZGllc2VzIFNBIGtvbXBsZXR0IGxvZXNjaGVuLgorICAgICAgbV9kZWxldGUoc2tpbGxhdHRycywgYXR0cik7CisgICAgICBjb250aW51ZTsKKyAgICB9CisgICAgLy8gc29uc3QgZGllIGFuZGVyZW4gQ2FjaGUtV2VydGUgc2V0emVuLgorICAgIGNhY2hlW1NBTV9TVU1dID0gc3VtOworICAgIGNhY2hlW1NBTV9DQUNIRV9USU1FT1VUXSA9IHRpbWVvdXQ7CisgIH0KKyAgLy8gd2VubiBhbGxlIE1vZHMgZ2Vsb2VzY2h0IHd1cmRlbi4KKyAgaWYgKCFzaXplb2Yoc2tpbGxhdHRycykpIHNraWxsYXR0cnM9MDsKKyNpZmRlZiBfX0RFQlVHX18KKyAgaWYgKGdldHVpZCh0aGlzX29iamVjdCgpKSA9PSAiemVzc3RyYSIpCisgICAgWkRFQlVHKHNwcmludGYoIiVPXG4iLHNraWxsYXR0cnMpKTsKKyNlbmRpZgorfQorCitwcml2YXRlIGludCBJbnRlcm5hbE1vZGlmeVNraWxsQXR0cmlidXRlKG9iamVjdCBjYXN0ZXIsIHN0cmluZyBhdHJuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaXhlZCB2YWx1ZSwgaW50IGR1cmF0aW9uKSB7CisgIGludCB6ZWl0ID0gdXRpbWUoKVsxXTsKKyAgaW50IHRpY2tzID0gZ2V0X2V2YWxfY29zdCgpOworCisgIC8vIG51ciBleGlzdGllcmVuZGUgU0FzLi4uCisgIGlmICghc3RyaW5ncChhdHJuYW1lKQorICAgICAgfHwgbWVtYmVyKFZBTElEX1NLSUxMX0FUVFJJQlVURVMsIGF0cm5hbWUpID09IC0xKQorICAgIHJldHVybiBTQV9NT0RfSU5WQUxJRF9BVFRSOworCisgIGlmICghb2JqZWN0cChjYXN0ZXIpKSByZXR1cm4gU0FfTU9EX0lOVkFMSURfT0JKRUNUOworCisgIGlmICghbWFwcGluZ3Aoc2tpbGxhdHRycykpIHNraWxsYXR0cnM9bV9hbGxvY2F0ZSgxLDMpOworICAKKyAgaWYgKCFtZW1iZXIoc2tpbGxhdHRycywgYXRybmFtZSkpIHsKKyAgICBza2lsbGF0dHJzW2F0cm5hbWUsU0FNX0NBQ0hFXSA9ICh7MCwgMCwgMH0pOworICAgIC8vIGRpZSBtZWlzdGVuIE1vZHMgc2luZCBzdGF0aXNjaCwgZGFoZXIgYXVmIFZlcmRhY2h0IGhpZXIgZnVlciBlaW5lbgorICAgIC8vIEVpbnRyYWcgUGxhdHogcmVzZXJ2aWVyZW4sIGFiZXIgbmljaHQgZnVlciBkZW4gZHluLiBUZWlsLgorICAgIHNraWxsYXR0cnNbYXRybmFtZSxTQU1fU1RBVElDXSA9IG1fYWxsb2NhdGUoMSwyKTsKKyAgICBza2lsbGF0dHJzW2F0cm5hbWUsU0FNX0RZTkFNSUNdID0gbV9hbGxvY2F0ZSgwLDIpOworICB9CisgIC8vIHBydWVmZW4sIG9iIE1heGltYWx6YWhsIGFuIEVpbnRyYWVnZW4gZHJpbiBpc3QKKyAgZWxzZSBpZiAoc2tpbGxhdHRyc1thdHJuYW1lLFNBTV9DQUNIRV1bU0FNX0NPVU5UXSA+PSBTQU1fTUFYX01PRFMpIHsKKyAgICAvLyBsZXR6dGUgQ2hhbmNlOiBkZXN0cnVjdGV0ZSBPYmpla3RlIGRyaW4/CisgICAgc2tpbGxhdHRyc1thdHJuYW1lLFNBTV9DQUNIRV1bU0FNX0NPVU5UXSA9IAorICAgICAgc2l6ZW9mKHNraWxsYXR0cnNbYXRybmFtZSxTQU1fU1RBVElDXSkKKyAgICArc2l6ZW9mKHNraWxsYXR0cnNbYXRybmFtZSxTQU1fRFlOQU1JQ10pOworICAgIC8vIGVzIGthbm4gc2VpbiwgZGFzcyBub2NoIGFiZ2VsYXVmZW5lIE9iamVrdGUgZHJpbnN0ZWhlbiwKKyAgICAvLyBhYmVyIGRpZSBQcnVlZnVuZyBpc3QgbWlyIGdlcmFkZSB6dSB0ZXVlci4gVE9ETworICAgIC8vIG5vY2htYWwgZ3Vja2VuIChyZXN0IHZvbSBjYWNoZSB3aXJkIGdnZi4gdW50ZW4gZ2VwcnVlZnQuKQorICAgIGlmIChza2lsbGF0dHJzW2F0cm5hbWUsU0FNX0NBQ0hFXVtTQU1fQ09VTlRdID49IFNBTV9NQVhfTU9EUykKKyAgICAgIHJldHVybiBTQV9UT09fTUFOWV9NT0RTOyAvLyBkYW5uIG5pY2h0LgorICB9CisKKyAgLy8gRGF1ZXIgZGFyZiBudXIgZWluIGludCBzZWluLgorICBpZiAoIWludHAoZHVyYXRpb24pKQorICAgIHJhaXNlX2Vycm9yKHNwcmludGYoIldyb25nIGFyZ3VtZW50IDMgdG8gTW9kaWZ5U2tpbGxBdHRyaWJ1dGU6ICIKKyAgICAiZXhwZWN0ZWQgJ2ludCcsIGdvdCAlLjEwT1xuIiwgZHVyYXRpb24pKTsKKyAgLy8gWmVpdHN0ZW1wZWwgZXJtaXR0ZWxuCisgIGR1cmF0aW9uICs9IHRpbWUoKTsKKworICAvLyBzdGF0aXNjaGVyIG9kZXIgZHluLiBNb2RpZmllcj8KKyAgaWYgKGludHAodmFsdWUpKSB7CisgICAgLy8gTW9kIGRhcmYgbmljaHQgenUgZ3Jvc3Mgb2RlciB6dSBrbGVpbiBzZWluLiBUT0RPOiBHcmVuemVuPworICAgIGlmICh2YWx1ZSA8IC0xMDAwKQorICAgICAgcmV0dXJuIFNBX01PRF9UT09fU01BTEw7CisgICAgZWxzZSBpZiAodmFsdWUgPiAxMDAwKQorICAgICAgcmV0dXJuIFNBX01PRF9UT09fQklHOworICAgIGVsc2UgaWYgKCF2YWx1ZSkKKyAgICAgIHJldHVybiBTQV9NT0RfSU5WQUxJRF9WQUxVRTsgCisgICAgLy8gamVkZXMgT2JqZWt0IGRhcmYgbnVyIGVpbmVuIG1vZCBoYWJlbi4gV2VubiBkaWVzZXMgc2Nob24gZWluZW4gZHluLgorICAgIC8vIGhhdCwgbXVzcyBkZXIgZ2Vsb2VzY2h0IHdlcmRlbiAoc3RhdC4gd2VyZGVuIGphIGVoIGVyc2V0enQpLgorICAgIGlmIChtZW1iZXIoc2tpbGxhdHRyc1thdHJuYW1lLFNBTV9EWU5BTUlDXSwgY2FzdGVyKSkKKyAgICAgIG1fZGVsZXRlKHNraWxsYXR0cnNbYXRybmFtZSxTQU1fRFlOQU1JQ10sIGNhc3Rlcik7CisgICAgLy8gc29uc3QgZWludHJhZ2VuCisgICAgc2tpbGxhdHRyc1thdHJuYW1lLCBTQU1fU1RBVElDXSArPSAoW2Nhc3RlcjogdmFsdWU7IGR1cmF0aW9uXSk7CisgIH0KKyAgZWxzZSBpZiAoY2xvc3VyZXAodmFsdWUpKSB7CisgICAgLy8gbnVyIGVpbiBNb2QgcHJvIE9iamVrdCwgcy5vLgorICAgIGlmIChtZW1iZXIoc2tpbGxhdHRyc1thdHJuYW1lLFNBTV9TVEFUSUNdLCBjYXN0ZXIpKQorICAgICAgbV9kZWxldGUoc2tpbGxhdHRyc1thdHJuYW1lLFNBTV9TVEFUSUNdLCBjYXN0ZXIpOworICAgIC8vIGRpcmVrdCBvaG5lIHdlaXRlcmUgUHJ1ZWZ1bmcgZWludHJhZ2VuCisgICAgc2tpbGxhdHRyc1thdHJuYW1lLCBTQU1fRFlOQU1JQ10gKz0gKFtjYXN0ZXI6IHZhbHVlOyBkdXJhdGlvbl0pOworICB9CisgIGVsc2UKKyAgICByYWlzZV9lcnJvcihzcHJpbnRmKCJXcm9uZyBhcmd1bWVudCAyIHRvIE1vZGlmeVNraWxsQXR0cmlidXRlKCk6ICIKKyAgICAiZXhwZWN0ZWQgJ2ludCcgb3IgJ2Nsb3N1cmUnLCBnb3QgJS4xME9cbiIsdmFsdWUpKTsKKworI2lmZGVmIFNBU0VUTE9HCisgIGlmIChxdWVyeV9vbmNlX2ludGVyYWN0aXZlKHRoaXNfb2JqZWN0KCkpKQorICAgIFNBU0VUTE9HKHNwcmludGYoIiVzOiAlTywgJXMsICVPLCAlT1xuIiwgCisgICAgICAgIHN0cmZ0aW1lKCIleSVtJWQtJUglTSVTIiksIHRoaXNfb2JqZWN0KCksIGF0cm5hbWUsIGNhc3RlciwgdmFsdWUpKTsKKyNlbmRpZgorI2lmZGVmIFNBU1RBVEQKKyAgb2JqZWN0IGRhZW1vbjsKKyAgaWYgKHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoTUUpCisgICAgICAmJiBvYmplY3RwKGRhZW1vbj1maW5kX29iamVjdChTQVNUQVREKSkpCisgICAgZGFlbW9uLT5Mb2dNb2RpZmllcihjYXN0ZXIsIGF0cm5hbWUsIHZhbHVlLCBkdXJhdGlvbik7CisjZW5kaWYKKyAgLy8gbm9jaCBkZW4gQ2FjaGUgZnVlciBkaWVzZXMgU0EgbmV1IGJlcmVjaG5lbgorICAvLyBUT0RPOiBDYWNoZSBudXIgaW52YWxpZGllcmVuLCBkYW1pdCBlciBlcnN0IGJlaSBkZXIgbmFlY2hzdGVuIEFiZnJhZ2UKKyAgLy8gYWt0dWFsaXNpZXJ0IHdpcmQuIFNwYXJ0IFplaXQsIHdlbm4gYmlzIGRhaGluIG1laHJlcmUgTW9kcworICAvLyBlbnRmZXJudC9hZGRpZXJ0IHdlcmRlbi4gRGFmdWVyIGlzdCBkaWUgZ2VjYWNoZSBBbnphaGwgYW4gTW9kcworICAvLyBpbmtvbnNpc3RlbnQuCisgIFVwZGF0ZVNBQ2FjaGUoICh7YXRybmFtZX0pICk7CisKKyAgWkRFQlVHKHNwcmludGYoIk1TQTogJU8sIFplaXQ6ICVkLCBUaWNrczogJWRcbiIsCisJdGhpc19vYmplY3QoKSwKKwl1dGltZSgpWzFdLXplaXQsIHRpY2tzLWdldF9ldmFsX2Nvc3QoKSkpOworCisgIHJldHVybiBTQV9NT0RfT0s7Cit9CisKK3B1YmxpYyBpbnQgTW9kaWZ5U2tpbGxBdHRyaWJ1dGUoc3RyaW5nIGF0cm5hbWUsIG1peGVkIHZhbHVlLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBkdXJhdGlvbikgeworICByZXR1cm4gSW50ZXJuYWxNb2RpZnlTa2lsbEF0dHJpYnV0ZSgKKyAgICAgIChleHRlcm5fY2FsbCgpP3ByZXZpb3VzX29iamVjdCgpOk1FKSwgYXRybmFtZSwgdmFsdWUsIGR1cmF0aW9uKTsKK30KKworcHVibGljIGludCBSZW1vdmVTa2lsbEF0dHJpYnV0ZU1vZGlmaWVyKG9iamVjdCBjYXN0ZXIsIHN0cmluZyBhdHRybmFtZSkgeworICBpZiAoIXN0cmluZ3AoYXR0cm5hbWUpIHx8ICFtYXBwaW5ncChza2lsbGF0dHJzKSB8fCAhb2JqZWN0cChjYXN0ZXIpCisgICAgICB8fCAhbWVtYmVyKHNraWxsYXR0cnMsIGF0dHJuYW1lKSkKKyAgICByZXR1cm4gU0FfTU9EX05PVF9GT1VORDsKKyAgLy8gVE9ETzogQmVyZWNodGlndW5nIHBydWVmZW4uIDstKQorCisgIGlmIChtZW1iZXIoc2tpbGxhdHRyc1thdHRybmFtZSwgU0FNX1NUQVRJQ10sIGNhc3RlcikpIHsKKyAgICBtX2RlbGV0ZShza2lsbGF0dHJzW2F0dHJuYW1lLCBTQU1fU1RBVElDXSwgY2FzdGVyKTsKKyAgfQorICBlbHNlIGlmIChtZW1iZXIoc2tpbGxhdHRyc1thdHRybmFtZSwgU0FNX0RZTkFNSUNdLCBjYXN0ZXIpKSB7CisgICAgbV9kZWxldGUoc2tpbGxhdHRyc1thdHRybmFtZSwgU0FNX0RZTkFNSUNdLCBjYXN0ZXIpOworICB9CisgIGVsc2UKKyAgICByZXR1cm4gU0FfTU9EX05PVF9GT1VORDsKKyAgCisgIC8vIFRPRE86IENhY2hlIG51ciBpbnZhbGlkaWVyZW4sIGRhbWl0IGVyIGVyc3QgYmVpIGRlciBuYWVjaHN0ZW4gQWJmcmFnZQorICAvLyBha3R1YWxpc2llcnQgd2lyZC4gU3BhcnQgWmVpdCwgd2VubiBiaXMgZGFoaW4gbWVocmVyZSBNb2RzCisgIC8vIGVudGZlcm50L2FkZGllcnQgd2VyZGVuLiBEYWZ1ZXIgaXN0IGRpZSBnZWNhY2hlIEFuemFobCBhbiBNb2RzCisgIC8vIGlua29uc2lzdGVudC4KKyAgVXBkYXRlU0FDYWNoZSggKHthdHRybmFtZX0pICk7CisKKyAgcmV0dXJuIFNBX01PRF9SRU1PVkVEOworfQorCitwdWJsaWMgaW50IFF1ZXJ5U2tpbGxBdHRyaWJ1dGUoc3RyaW5nIGF0cm5hbWUpCit7CisgIG1peGVkIG9mZnNldHMsIGF0dHI7CisgIGludCBtb2RzdW1tZSwgcXVhbCwgcmV0LCBjdmFsOworCisgIGlmICghc3RyaW5ncChhdHJuYW1lKSkgLy8gVkFMSURfU0tJTExfQVRUUklCVVRFUyBiZXJ1ZWNrc2ljaHRpZ2VuPworICAgIHJldHVybiAxMDA7CisKKyAgLy8gd2VubiBuaWNodCBTQV9RVUFMSVRZIGdlZnJhZ3QgaXN0LCBlcnN0bWFsIGplbmVzIGVybWl0dGVsbiwgd2VpbCBlcyBkZW4KKyAgLy8gZXJzdGVuIE1vZGlmaWVyIGF1ZiBhbGxlIGFuZGVyZW4gU0FzIGRhcnN0ZWxsdC4gU29uc3QgZGVuIFN0YXJ0d2VydCBmdWVyCisgIC8vIFNBX1FVQUxJVFkgKDEwMCkgbW9kaWZpemllcnQgZHVyY2ggZXZ0bC4gVG9kZXNmb2xnZW4gZXJtaXR0ZWxuLgorICBpZiAoIGF0cm5hbWUgIT0gU0FfUVVBTElUWSApCisgICAgcXVhbCA9IFF1ZXJ5U2tpbGxBdHRyaWJ1dGUoU0FfUVVBTElUWSk7CisgIGVsc2UKKyAgICAvLyBiZWkgU0FfUVVBTElUWSBnZWhlbiBkaWUgVG9kZXNmb2xnZW4gZWluCisgICAgcXVhbCA9IHRvX2ludCgxMDAgKiBwb3coMC45LCBkZWF0aF9zdWZmZXJpbmcoKS8xMC4wKSk7CisKKyAgLy8gRGllIE9mZnNldHMgc2luZCBzb3p1c2FnZW4gZGVyIEJhc2lzd2VydCBkZXIgU0FzLiBBbHMgZXJzdGVzIHZlcnd1cnN0ZW4sCisgIC8vIHNvZmVybiB2b3JoYW5kZW4sIG5lbiBpbnQgZHJpbnN0ZWh0IHVuZCBkZXIgb2Zmc2V0ICE9IDAgaXN0LgorICBpZiAoIG1hcHBpbmdwKG9mZnNldHMgPSBRdWVyeShQX1NLSUxMX0FUVFJJQlVURV9PRkZTRVRTKSkKKyAgICAgICAmJiBpbnRwKGF0dHI9b2Zmc2V0c1thdHJuYW1lXSkgCisgICAgICAgJiYgYXR0cikKKyAgICByZXQgPSBhdHRyOworICBlbHNlCisgICAgcmV0ID0gMTAwOworCisgIC8vIHdlbm4ga2VpbmUgTW9kcyBnZXNldHp0IHNpbmQsIHdhcnMgZGFzIGpldHp0LiA7LSkKKyAgaWYgKCAhbWFwcGluZ3Aoc2tpbGxhdHRycykKKyAgICAgICB8fCAhbWVtYmVyKHNraWxsYXR0cnMsIGF0cm5hbWUpICkKKyAgICByZXR1cm4gKHJldCpxdWFsKS8xMDA7CisKKyAgLy8gd2VubiBDYWNoZSBkZXIgc3RhdC4gTW9kcyBhYmdlbGF1ZmVuIG9kZXIgb2ZmZW5iYXIgT2JqZWt0ZSB6ZXJzdG9lcnQKKyAgLy8gd3VyZGVuLCBtdXNzIGRlciBDYWNoZSBuZXUgYmVyZWNobmV0IHdlcmRlbi4KKyAgaWYgKCBza2lsbGF0dHJzW2F0cm5hbWUsU0FNX0NBQ0hFXVtTQU1fQ0FDSEVfVElNRU9VVF0gPCB0aW1lKCkKKyAgICAgIHx8IHNpemVvZihza2lsbGF0dHJzW2F0cm5hbWUsU0FNX1NUQVRJQ10pCisgICAgICAgICArc2l6ZW9mKHNraWxsYXR0cnNbYXRybmFtZSxTQU1fRFlOQU1JQ10pICE9CisgICAgICAgICAgIHNraWxsYXR0cnNbYXRybmFtZSxTQU1fQ0FDSEVdW1NBTV9DT1VOVF0gKQorICB7CisgICAgVXBkYXRlU0FDYWNoZSggKHthdHJuYW1lfSkgKTsKKyAgICAvLyBVcGRhdGVTQUNhY2hlKCkgbG9lc2NodCB1VSBkYXMgU0EtTWFwcGluZyBvZGVyIEVpbnRyYWVnZSBkYXJhdXMuCisgICAgaWYgKCAhbWFwcGluZ3Aoc2tpbGxhdHRycykKKyAgICAgICAgIHx8ICFtZW1iZXIoc2tpbGxhdHRycywgYXRybmFtZSkgKQorICAgIHJldHVybiAocmV0KnF1YWwpLzEwMDsKKyAgfQorICAvLyBTdW1tZSBkZXIgc3RhdGlzY2hlbiBNb2RzLgorICBtb2RzdW1tZSA9IHNraWxsYXR0cnNbYXRybmFtZSxTQU1fQ0FDSEVdW1NBTV9TVU1dOworCisgIC8vIFRPRE8hIEV2dGwuIGFuZGVyZSBEYXRlbiBhbHMgTUUgYW4gZGllIEZ1bmt0aW9uIHVlYmVyZ2ViZW4KKyAgLy8gVE9ETyEgYmVyZWl0cyBuYWNoIEFkZGl0aW9uIGRlcyBGdW5rdGlvbnNydWVja2dhYmV3ZXJ0ZXMgcHJ1ZWZlbiwgb2IgZGVyCisgIC8vICAgICAgIFdlcnRlYmVyZWljaCBkZXMgU0EtTW9kaWZpZXJzIHVlYmVyc2Nocml0dGVuIGlzdCwgb2RlciBmcmVpZW4KKyAgLy8gICAgICAgV2VydGViZXJlaWNoIGVybGF1YmVuIHVuZCBlcnN0IGFtIEVuZGUgZGVja2VsbiAoYWt0dWVsbGUgVmFyaWFudGUpCisgIC8vIER5bmFtaXNjaGUgTW9kaWZpZXIgYXVzd2VydGVuCisgIGZvcmVhY2goIG9iamVjdCBvYiwgY2xvc3VyZSBjbCwgaW50IGR1cmF0aW9uOgorICAgICAgICAgICBza2lsbGF0dHJzW2F0cm5hbWUsU0FNX0RZTkFNSUNdICkKKyAgeworICAgIGlmICggZHVyYXRpb24gPiB0aW1lKCkgICAgICAgICAgICAgICAvLyBOb2NoIG5pY2h0IGFiZ2VsYXVmZW4gdW5kCisgICAgICAgICAmJiBpbnRwKGN2YWw9ZnVuY2FsbChjbCwgTUUpKSApIC8vIEZ1bmt0aW9uIGxpZWZlcnQgaW50IHp1cnVlY2sKKyAgICAgIG1vZHN1bW1lICs9IGN2YWw7CisgICAgZWxzZSB7CisgICAgICBtX2RlbGV0ZShza2lsbGF0dHJzW2F0cm5hbWUsU0FNX0RZTkFNSUNdLCBvYik7CisgICAgICBza2lsbGF0dHJzW2F0cm5hbWUsU0FNX0NBQ0hFXVtTQU1fQ09VTlRdLS07CisgICAgfQorICB9CisgIHJldCA9ICgocmV0K21vZHN1bW1lKSpxdWFsKS8xMDA7CisgIGlmICggcmV0IDwgMTAgKQorICAgIHJldCA9IDEwOworICBlbHNlIGlmICggcmV0ID4gMTAwMCApCisgICAgcmV0ID0gMTAwMDsKKworICByZXR1cm4gcmV0OworfQorCitwdWJsaWMgdmFyYXJncyBtYXBwaW5nIFF1ZXJ5U2tpbGxBdHRyaWJ1dGVNb2RpZmllcihvYmplY3QgY2FzdGVyLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyAqYXR0cm5hbWVzKSB7CisgIAorICAvLyBhdWYgYWJnZWxhdWZlbmUgTW9kaWZpa2F0b3JlbiBwcnVlZmVuCisgIGlmICghcG9pbnRlcnAoYXR0cm5hbWVzKSkKKyAgICBVcGRhdGVTQUNhY2hlKCAoe30pICk7CisgIGVsc2UKKyAgICBVcGRhdGVTQUNhY2hlKGF0dHJuYW1lcyk7CisKKyAgaWYgKCFtYXBwaW5ncChza2lsbGF0dHJzKSkKKyAgICByZXR1cm4gKFtdKTsKKyAgaWYgKCFwb2ludGVycChhdHRybmFtZXMpIHx8ICFzaXplb2YoYXR0cm5hbWVzKSkKKyAgICBhdHRybmFtZXMgPSBtX2luZGljZXMoc2tpbGxhdHRycyk7IC8vIGFsbGUgZHVyY2hzdWNoZW4KKyAgZWxzZSAvLyBzY2huaXR0bWVuZ2UgZGVyIGdldy4gdW5kIHZvcmhhbmRlbmVuIGJpbGRlbgorICAgIGF0dHJuYW1lcyA9IG1faW5kaWNlcyhza2lsbGF0dHJzKSAmIGF0dHJuYW1lczsKKyAgCisgIG1hcHBpbmcgcmVzPW1fYWxsb2NhdGUoc2l6ZW9mKGF0dHJuYW1lcyksIDEpOworCisgIGZvcmVhY2goc3RyaW5nIGF0cjogYXR0cm5hbWVzKSB7CisgICAgcmVzW2F0cl0gPSBtX2FsbG9jYXRlKDUsIDIpOyAvLyBtYWwgZnVlciA1IFdlcnRlIFBsYXR6IHJlc2VydmllcmVuCisgICAgaWYgKCFvYmplY3RwKGNhc3RlcikpIHsKKyAgICAgIC8vIHdlbm4ga2VpbiBiZXN0aW1tdGVyIGNhc3RlciBhbmdlZnJhZ3QgaXN0LCBhbGxlIG1vZHMgbGllZmVybgorICAgICAgZm9yZWFjaChvYmplY3QgYywgaW50IHZhbHVlLCBpbnQgZHVyOiBza2lsbGF0dHJzW2F0ciwgU0FNX1NUQVRJQ10pIHsKKwlyZXNbYXRyXSArPSAoW2M6IHZhbHVlOyBkdXJdKTsKKyAgICAgIH0KKyAgICAgIGZvcmVhY2gob2JqZWN0IGMsIGNsb3N1cmUgdmFsdWUsIGludCBkdXI6IHNraWxsYXR0cnNbYXRyLCBTQU1fRFlOQU1JQ10pIHsKKwlyZXNbYXRyXSArPSAoW2M6IHZhbHVlOyBkdXJdKTsKKyAgICAgIH0KKyAgICB9CisgICAgZWxzZSB7CisgICAgICAvLyBzb25zdCBudXIgZGVuIE1vZCB2b24gY2FzdGVyCisgICAgICBpZiAobWVtYmVyKHNraWxsYXR0cnNbYXRyLCBTQU1fU1RBVElDXSwgY2FzdGVyKSkgeworCXJlc1thdHJdICs9IChbY2FzdGVyOiAKKwkJCSBza2lsbGF0dHJzW2F0ciwgU0FNX1NUQVRJQ11bY2FzdGVyLCBTQU1fVkFMVUVdOworCSAgICAgICAgICAgICAgICAgc2tpbGxhdHRyc1thdHIsIFNBTV9TVEFUSUNdW2Nhc3RlciwgU0FNX0RVUkFUSU9OXQorCQkgICAgXSk7CisgICAgICB9CisgICAgICBlbHNlIGlmIChtZW1iZXIoc2tpbGxhdHRyc1thdHIsIFNBTV9EWU5BTUlDXSwgY2FzdGVyKSkgeworCXJlc1thdHJdICs9IChbY2FzdGVyOgorCQkJIHNraWxsYXR0cnNbYXRyLCBTQU1fRFlOQU1JQ11bY2FzdGVyLCBTQU1fVkFMVUVdOworCSAgICAgICAgICAgICAgICAgc2tpbGxhdHRyc1thdHIsIFNBTV9EWU5BTUlDXVtjYXN0ZXIsIFNBTV9EVVJBVElPTl0KKwkJICAgIF0pOworICAgICAgfQorICAgIH0KKyAgfQorICByZXR1cm4gcmVzOworfQorCisvLyBLb21wYXRpYmlsaXRhZXRzZnVua3Rpb24gbWl0IGFsdGVtIEludGVyZmFjZS4gSXN0IG51ciBlaW4gV3JhcHBlciwgZGVyCisvLyB2YWx1ZSB1bXJlY2huZXQgdW5kICdhbHRlJyBSdWVja2dhYmV3ZXJ0ZSBsaWVmZXJ0LgorCitwdWJsaWMgdmFyYXJncyBpbnQgTW9kaWZ5U2tpbGxBdHRyaWJ1dGVPbGQob2JqZWN0IGNhc3Rlciwgc3RyaW5nIGF0cm5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB2YWx1ZSwgaW50IGR1cmF0aW9uLCBtaXhlZCBmdW4pIHsKKyAgaW50IHJlczsKKyAgLy8gQ2FsbGVyIGVybWl0dGVsbgorICBpZiAoZXh0ZXJuX2NhbGwoKSkgY2FzdGVyPXByZXZpb3VzX29iamVjdCgpOworICBlbHNlIGNhc3Rlcj1NRTsKKworICAvLyBDbG9zdXJlcyBrb2VubmVuIHZpYSBNb2RpZnlTa2lsbEF0dHJpYnV0ZU9sZCgpIG5pY2h0IG1laHIgZ2VzZXR6dCB3ZXJkZW4sCisgIC8vIGRhIGRlcmVuIFJ1ZWNrZ2FiZXdlcnQgbmljaHQgc2lubnZvbGwgdW1nZXJlY2huZXQgd2VyZGVuIGtvZW5uZW4uIChNYW4KKyAgLy8gd2Vpc3MgbmljaHQsIG9iIGVzIGVpbmUgbmV1ZSBvZGVyIGFsdGUgQ2xvc3VyZSBpc3QuKQorICBpZiAocG9pbnRlcnAoZnVuKSB8fCBjbG9zdXJlcChmdW4pKQorICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigiQ2xvc3VyZXMgZm9yIFNBIG1vZGlmaWVycyBjYW4ndCBiZSBzZXQgYnkgIgorICAgICAgIk1vZGlmeVNraWxsQXR0cmlidXRlT2xkKCkhIFVzZSBNb2RpZnlTa2lsbEF0dHJpYnV0ZSgpIVxuIikpOworICAKKyAgcmVzID0gSW50ZXJuYWxNb2RpZnlTa2lsbEF0dHJpYnV0ZShjYXN0ZXIsIGF0cm5hbWUsIHZhbHVlLTEwMCwgZHVyYXRpb24pOworICAvLyBkaWUgYWx0ZSBmdW5rdGlvbiBoYXR0ZSBudXIgMCBmdWVyIHVuZ3VlbHRpZ2VuIFdlcnQgdW5kIDwgMCBmdWVyIHp1CisgIC8vIGtsZWluZXMgTGV2ZWwgYWxzIFJ1ZWNrZ2FiZXdlcnQuIFp1IGtsZWluZXMgTGV2ZWwgZ2lidCBuaWNodCBtZWhyLCBhbHNvCisgIC8vIGJsZWlidCBudXIgMCBhbHMgU2FtbWVsLUZlaGxlcmNvZGUgdWVicmlnLiAqc2V1ZnoqCisgIGlmIChyZXMgPCAwKSByZXR1cm4gMDsKKyAgcmV0dXJuIHJlczsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL2xpdmluZy9za2lsbF91dGlscy5jIGIvc3RkL2xpdmluZy9za2lsbF91dGlscy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI0Y2FmNzUKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvbGl2aW5nL3NraWxsX3V0aWxzLmMKQEAgLTAsMCArMSwzNSBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGxpdmluZy9za2lsbF91dGlscyAtLSBzb21lIGhlbHBlciBmdW5jdGlvbnMgZm9yIG1hbmlwdWxhdGluZyBza2lsbCBkYXRhIAorLy8gICAgICAgICAgICAgICAgICAgICAgIG5lZWRlZCBpbiBtb3JlIHRoYW4gb25lIHByb2dyYW0uCisvLworLy8gJElkOiBza2lsbF91dGlscy5jIDY3MzggMjAwOC0wMi0xOSAxODo0NjoxNFogSHVtbmkgJAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjaW5jbHVkZSA8bmV3X3NraWxscy5oPgorCitwcm90ZWN0ZWQgdm9pZCBTa2lsbFJlc1RyYW5zZmVyKG1hcHBpbmcgZnJvbV9NLCBtYXBwaW5nIHRvX00pCit7CisgIGlmICggIW1hcHBpbmdwKGZyb21fTSkgfHwgIW1hcHBpbmdwKHRvX00pICkKKyAgICByZXR1cm47CisKKyAgaWYgKCBtZW1iZXIoZnJvbV9NLFNJX1NLSUxMREFNQUdFKSApCisgICAgdG9fTVtTSV9TS0lMTERBTUFHRV0gPSB0b19pbnQoZnJvbV9NW1NJX1NLSUxMREFNQUdFXSk7CisKKyAgaWYgKCBtZW1iZXIoZnJvbV9NLFNJX1NLSUxMREFNQUdFX01TRykgKQorICAgIHRvX01bU0lfU0tJTExEQU1BR0VfTVNHXSA9IHRvX3N0cmluZyhmcm9tX01bU0lfU0tJTExEQU1BR0VfTVNHXSk7CisKKyAgaWYgKCBtZW1iZXIoZnJvbV9NLFNJX1NLSUxMREFNQUdFX01TRzIpICkKKyAgICB0b19NW1NJX1NLSUxMREFNQUdFX01TRzJdID0gdG9fc3RyaW5nKGZyb21fTVtTSV9TS0lMTERBTUFHRV9NU0cyXSk7CisKKyAgaWYgKCBtZW1iZXIoZnJvbV9NLFNJX1NLSUxMREFNQUdFX1RZUEUpICkKKyAgICB0b19NW1NJX1NLSUxMREFNQUdFX1RZUEVdID0gZnJvbV9NW1NJX1NLSUxMREFNQUdFX1RZUEVdOworCisgIGlmICggbWVtYmVyKGZyb21fTSxTSV9TUEVMTCkgKQorICAgIHRvX01bU0lfU1BFTExdID0gZnJvbV9NW1NJX1NQRUxMXTsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL2xpdmluZy9za2lsbHMuYyBiL3N0ZC9saXZpbmcvc2tpbGxzLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTNjOWRjYwotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9saXZpbmcvc2tpbGxzLmMKQEAgLTAsMCArMSw1OTUgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBsaXZpbmcvc2tpbGxzLmMgLS0gR2lsZGVuLSwgU2tpbGwtIHVuZCBTcGVsbGZ1bmt0aW9uZW4gZnVlciBMZWJld2VzZW4KKy8vCisvLyAkSWQ6IHNraWxscy5jIDg3NTUgMjAxNC0wNC0yNiAxMzoxMzo0MFogWmVzc3RyYSAkCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKK2luaGVyaXQgIi9zdGQvbGl2aW5nL3N0ZF9za2lsbHMiOworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPGxpdmluZy9za2lsbHMuaD4KKyNpbmNsdWRlIDxsaXZpbmcvc2tpbGxfYXR0cmlidXRlcy5oPgorI2luY2x1ZGUgPHBsYXllci9saWZlLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPG5ld19za2lsbHMuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKworLy8gc3BlaWNoZXJ0IGRpZSBTcGVsbC1GYXRpZ3VlcyAoZ2xvYmFsLCBTcHJ1Y2hncnVwcGVuLCBFaW56ZWxzcHJ1ZWNoZSkKK3ByaXZhdGUgbWFwcGluZyBzcGVsbF9mYXRpZ3VlcyA9IChbXSk7CisKKy8vIFByb3RvdHlwZW4KK3ByaXZhdGUgdm9pZCBleHBpcmVfc3BlbGxfZmF0aWd1ZXMoKTsKKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkKK3sKKyAgLy8gbWFpbmx5IG5lY2Vzc2FyeSBmb3IgcGxheWVycywgYnV0IHRoZXJlIG1heSBiZSBzb21lIE5QQyB3aXRoIHNhdmVmaWxlcy4KKyAgLy8gQWRkaXRpb25hbGx5LCBpdCBzaW1wbGlmaWVzIGV4cGlyYXRpb24gb2Ygb2xkIGtleXMgdG8gaGF2ZSBpdCBoZXJlLgorICBjYWxsX291dCgjJ2V4cGlyZV9zcGVsbF9mYXRpZ3VlcywgNCk7Cit9CisKKworLy8gRGllc2UgLSBoaWVyIHNjaGVpbmJhciBzaW5ubG9zZSAtIEZ1bmt0aW9uIHdpcmQgdm9uIC9zdGQvcGxheWVyL3NraWxscy5jIGRhbm4gCisvLyB1ZWJlcmxhZGVuLgorcHVibGljIGludCBpc19kZWFjdGl2YXRlZF9za2lsbChzdHJpbmcgc25hbWUsIHN0cmluZyBnaWxkZSkKK3sKKwlyZXR1cm4gMDsKK30KKworCisKK3N0YXRpYyBzdHJpbmcgX3F1ZXJ5X3Zpc2libGVfZ3VpbGQoKQoreyBzdHJpbmcgcmVzOworCisgIGlmICggc3RyaW5ncChyZXM9UXVlcnkoUF9WSVNJQkxFX0dVSUxEKSkgKQorICAgIHJldHVybiByZXM7CisKKyAgcmV0dXJuIFF1ZXJ5UHJvcChQX0dVSUxEKTsKK30KKworc3RhdGljIHN0cmluZyBfcXVlcnlfdmlzaWJsZV9zdWJndWlsZF90aXRsZSgpCit7IHN0cmluZyByZXM7CisKKyAgaWYgKCBzdHJpbmdwKHJlcz1RdWVyeShQX1ZJU0lCTEVfU1VCR1VJTERfVElUTEUpKSApCisgICAgcmV0dXJuIHJlczsKKworICByZXR1cm4gUXVlcnlQcm9wKFBfU1VCR1VJTERfVElUTEUpOworfQorCitzdGF0aWMgbWl4ZWQgX3F1ZXJ5X2d1aWxkX3ByZXBhcmVibG9jaygpCit7IG1hcHBpbmcgcmVzOworICBzdHJpbmcgIGdpbGRlOworCisgIGlmICggIXN0cmluZ3AoZ2lsZGU9UXVlcnlQcm9wKFBfR1VJTEQpKSApCisgICAgcmV0dXJuIDA7CisgIGlmICggIW1hcHBpbmdwKHJlcz1RdWVyeShQX0dVSUxEX1BSRVBBUkVCTE9DSykpIAorICAgICAgfHwgIW1lbWJlcihyZXMsZ2lsZGUpICkKKyAgICByZXR1cm4gMDsKKyAgcmV0dXJuIHJlc1tnaWxkZV07Cit9CisKK3N0YXRpYyBtaXhlZCBfc2V0X2d1aWxkX3ByZXBhcmVibG9jayhtaXhlZCBhcmcpCit7IG1hcHBpbmcgcmVzOworICBzdHJpbmcgIGdpbGRlOworCisgIGlmICggIXN0cmluZ3AoZ2lsZGU9UXVlcnlQcm9wKFBfR1VJTEQpKSApCisgICAgcmV0dXJuIDA7CisgIGlmICggIW1hcHBpbmdwKHJlcz1RdWVyeShQX0dVSUxEX1BSRVBBUkVCTE9DSykpICkKKyAgICByZXM9KFtdKTsKKworICByZXNbZ2lsZGVdPWFyZzsKKyAgU2V0KFBfR1VJTERfUFJFUEFSRUJMT0NLLHJlcyk7CisKKyAgcmV0dXJuIGFyZzsKK30KKworCitwcml2YXRlIG5vc2F2ZSBpbnQgdmFsaWRfc2V0c2tpbGxzX292ZXJyaWRlOworLy8gTWFuIHNvbGx0ZSBlaWdlbnRsaWNoIGphIG5pY2h0IFBhcmFtZXRlciBhbHMgZ2xvYmFsZSBWYXJpYWJsZW4KKy8vIHVlYmVyZ2ViZW4sIGFiZXIgaGllciBnaW5nIGVzIG5pY2h0IGFuZGVycworbm9tYXNrIHByaXZhdGUgaW50IHZhbGlkX3NldHNraWxscyhzdHJpbmcgZ2lsZGUpCit7IHN0cmluZyBmbjsKKworICBpZiAoICFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKHRoaXNfb2JqZWN0KCkpICkKKyAgICByZXR1cm4gMTsgLy8gTW9uc3RlciBkdWVyZmVuIHNpY2ggc2VsYmVyIFNraWxscyBzZXR6ZW4gOikKKworICBpZiAoIFF1ZXJ5UHJvcChQX1RFU1RQTEFZRVIpIHx8IElTX1dJWkFSRCh0aGlzX29iamVjdCgpKSApCisgICAgICByZXR1cm4gMTsgLy8gVGVzdHNwaWVsZXIgdW5kIE1hZ2llciBzaW5kIHNjaHV0emxvc2UgT3BmZXIgOy0pCisKKyAgaWYgKCBwcmV2aW91c19vYmplY3QoKSApCisgIHsKKyAgICBpZiAoIHByZXZpb3VzX29iamVjdCgpPT10aGlzX29iamVjdCgpCisgICAgICAgICYmIHRoaXNfaW50ZXJhY3RpdmUoKT09dGhpc19vYmplY3QoKSApCisgICAgICByZXR1cm4gMTsKKworICAgIGZuPW9iamVjdF9uYW1lKHByZXZpb3VzX29iamVjdCgpKTsKKyAgICBpZiAoIGZuWzAuLjddPT0iL2dpbGRlbi8iCisgICAgICAgIHx8IGZuWzAuLjExXT09Ii9zcGVsbGJvb2tzLyIKKyAgICAgICAgfHwgZm5bMC4uN109PSIvc2VjdXJlLyIKKyAgICAgICAgfHwgZm5bMC4uMTFdPT0iL3AvemF1YmVyZXIvIiApCisgICAgICByZXR1cm4gMTsgLy8gRGllIHNvbGx0ZW4gcHJvYmxlbWxvcyBhZW5kZXJuIGR1ZXJmZW4KKworICAgIGlmICggZmlsZV9zaXplKCIvZ2lsZGVuL2FjY2Vzc19yaWdodHMiKT4wCisgICAgICAgJiYgY2FsbF9vdGhlcigiL2dpbGRlbi9hY2Nlc3NfcmlnaHRzIiwKKyAgICAgICAgICAgICAgICAgICAgImFjY2Vzc19yaWdodHMiLAorICAgICAgICAgICAgICAgICAgICBnZXR1aWQocHJldmlvdXNfb2JqZWN0KCkpLAorICAgICAgICAgICAgICAgICAgICBnaWxkZSsiLmMiKSkKKyAgICAgIHJldHVybiAxOyAvLyBTZXR6ZW5kZXMgT2JqZWt0IGtvbW10IHZvbSBHaWxkZW5wcm9ncmFtbWllcmVyCisKKyAgICBpZiAoIGZpbGVfc2l6ZSgiL2dpbGRlbi8iK2dpbGRlKyIuYyIpPjAKKyAgICAgICAgJiYgY2FsbF9vdGhlcigiL2dpbGRlbi8iK2dpbGRlLAorICAgICAgICAgICAgICAgICAgICAgICJ2YWxpZF9zZXRza2lsbHMiLAorICAgICAgICAgICAgICAgICAgICAgICAgZXhwbG9kZShmbiwiIyIpWzBdKSApCisgICAgICByZXR1cm4gMTsgLy8gRGllIEdpbGRlIHNlbGJlciBrYW5uIEF1c25haG1lbiB6dWxhc3NlbgorICB9CisKKyAgaWYgKHZhbGlkX3NldHNraWxsc19vdmVycmlkZSkKKyAgeworICAgIHZhbGlkX3NldHNraWxsc19vdmVycmlkZT0wOworICAgIHJldHVybiAxOyAvLyBGdWVycyBTZXR6ZW4gZGVyIENsb3N1cmUKKyAgfQorCisgIGlmICggdGhpc19pbnRlcmFjdGl2ZSgpICkKKyAgeworICAgIGlmICggSVNfQVJDSCh0aGlzX2ludGVyYWN0aXZlKCkpICkKKyAgICAgIHJldHVybiAxOyAvLyBFcnptYWdpZXIgZHVlcmZlbiBpbW1lciBhZW5kZXJuCisKKyAgICBpZiAoIGNhbGxfb3RoZXIoIi9naWxkZW4vYWNjZXNzX3JpZ2h0cyIsCisgICAgICAgICAgICAgICAgICAgICJhY2Nlc3NfcmlnaHRzIiwKKyAgICAgICAgICAgICAgICAgICAgZ2V0dWlkKHRoaXNfaW50ZXJhY3RpdmUoKSksCisgICAgICAgICAgICAgICAgICAgIGdpbGRlKyIuYyIpKQorICAgICAgcmV0dXJuIDE7ICAvLyBEZXIgR2lsZGVucHJvZ3JhbW1pZXJlciBzZWxiZXIgYXVjaAorICB9CisKKyAgLy8gRnVlciBkaWUgV2FmZmVuc2tpbGxzLCBkaWUgc29sbGVuIHNpY2ggc2VsYnN0IGF1Y2ggc2V0emVuIGR1ZXJmZW4KKyAgaWYgKCF0aGlzX2ludGVyYWN0aXZlKCkgJiYgdGhpc19vYmplY3QoKT09cHJldmlvdXNfb2JqZWN0KCkpCisJICByZXR1cm4gMTsKKyAgCisgIAorICBsb2dfZmlsZSgiU0VUU0tJTExTIixzcHJpbnRmKCIqKioqKlxuJXMgUE86JU8tPlRPOiVPIFRJOiVPXG4gR1VJTEQ6JXMgVkVSQl9BUkdTOiclcydcbiIsCisgICAgICAgICAgICBjdGltZSh0aW1lKCkpWzQuLjE1XSwKKyAgICAgICAgICAgIHByZXZpb3VzX29iamVjdCgpLAorICAgICAgICAgICAgdGhpc19vYmplY3QoKSwKKyAgICAgICAgICAgIHRoaXNfaW50ZXJhY3RpdmUoKSwKKyAgICAgICAgICAgIGdpbGRlLAorICAgICAgICAgICAgKCB0aGlzX2ludGVyYWN0aXZlKCkgPyBxdWVyeV92ZXJiKCkgKyAiICIgKworICAgICAgICAgICAgICAgIHRoaXNfaW50ZXJhY3RpdmUoKS0+X3VucGFyc2VkX2FyZ3MoKSA6ICIiKSApKTsKKworICByZXR1cm4gMDsKK30KKworLy8gTnVyIGludGVybmUgVmVyd2VuZHVuZywgdmFsdWUgd2lyZCBuaWNodCB3ZWl0ZXIgcHJ1ZWZ0LCBtdXNzIG9rIHNlaW4uCisvLyBFcyB3aXJkIGtlaW5lIEtvcGllIHZvbiB2YWx1ZSBnZW1hY2h0LCB3ZW5uIGVzIGlucyBNYXBwaW5nIGdlc2NocmllYmVuCisvLyB3aXJkIQorcHJpdmF0ZSBtYXBwaW5nIGludGVybmFsX3NldF9uZXdza2lsbHMobWFwcGluZyB2YWx1ZSwgc3RyaW5nIGdpbGRlKSB7CisgIG1hcHBpbmcgc2tpbGxzOworCisgIC8vIGluIGRlciByaWNodGlnZW4gR2lsZGUgc2V0emVuLgorICBpZiAoICFnaWxkZSAmJiAhKGdpbGRlPVF1ZXJ5UHJvcChQX0dVSUxEKSkgKQorICAgIGdpbGRlPSJBTlkiOworCisgIC8vIFF1ZXJ5KCksIGhpZXIgaXN0IGVpbmUgS29waWUgbmljaHQgc2lubnZvbGwuCisgIGlmICggIW1hcHBpbmdwKHNraWxscz1RdWVyeShQX05FV1NLSUxMUyxGX1ZBTFVFKSkgKSB7CisgICAgc2tpbGxzPShbXSk7CisgICAgU2V0KFBfTkVXU0tJTExTLCBza2lsbHMsIEZfVkFMVUUpOworICB9CisKKyAgLy8gRmFsbHMgZGllcyBoaWVyIG1hbCBhdXNnZXdlcnRldCB3ZXJkZW4gc29sbHRlLCBuaWNodCB2ZXJnZXNzZW4sIGRhc3MKKyAgLy8gZWluaWdlIEZ1bmt0aW9uIGhpZXIgaW0gRmlsZSBkaWUgUHJvcCBldnRsLiB2aWEKKyAgLy8gaW50ZXJuYWxfcXVlcnlfbmV3c2tpbGxzKCkgYWJydWZlbiB1bmQgZGlyZWt0IGFlbmRlcm4uLi4KKyAgdmFsaWRfc2V0c2tpbGxzKGdpbGRlKTsgLy8gU2ljaGVyaGVpdHN1ZWJlcnBydWVmdW5nCisgIAorICAvLyBTa2lsbHMgc2V0emVuLiBTZXQoKSB1bm5vZXRpZywgd2VpbCB3aXIgZGFzIHZvbiBRdWVyeSgpIGdlbGllZmVydGUKKyAgLy8gTWFwcGluZyBhZW5kZXJuIHVuZCBkYXMgamEgdmlhIFJlZmVyZW56IGJla29tbWVuIGhhYmVuLgorICBza2lsbHNbZ2lsZGVdPXZhbHVlOworICAvL1NldChQX05FV1NLSUxMUyxza2lsbHMpOworCisgIHJldHVybih2YWx1ZSk7Cit9CisKKy8vIG51ciB6dXIgaW50ZXJuZW4gVmVyd2VuZHVuZywgZXMgd2lyZCBrZWluZSBLb3BpZSBkZXMgU2tpbGxtYXBwaW5ncyBnZW1hY2h0IQorcHJpdmF0ZSBtYXBwaW5nIGludGVybmFsX3F1ZXJ5X25ld3NraWxscyhzdHJpbmcgZ2lsZGUpIHsKKyAgbWFwcGluZyBza2lsbHM7CisKKyAgLy8gcmljaHRpZ2UgR2lsZGUgYWJmcmFnZW4uCisgIGlmICggIWdpbGRlICYmICEoZ2lsZGU9UXVlcnlQcm9wKFBfR1VJTEQpKSApCisgICAgZ2lsZGU9IkFOWSI7CisKKyAgc2tpbGxzPVF1ZXJ5KFBfTkVXU0tJTExTKTsKKworICBpZiAoIW1hcHBpbmdwKHNraWxscykgfHwgIW1hcHBpbmdwKHNraWxscz1za2lsbHNbZ2lsZGVdKSApCisgICAgcmV0dXJuIChbXSk7CisKKyAgcmV0dXJuKHNraWxscyk7Cit9CisKKy8vIEVpZ2VudGxpY2ggc29sbHRlIG1hbiBkZW4gX3F1ZXJ5LUZ1bmt0aW9uZW4ga2VpbmUgUGFyYW1ldGVyIGdlYmVuLi4uCitzdGF0aWMgdmFyYXJncyBtYXBwaW5nIF9xdWVyeV9uZXdza2lsbHMoc3RyaW5nIGdpbGRlKSB7CisKKyAgLy8gc29uc3QgS29waWUgZGVzIHNwZWxsbWFwcGluZ3MgbGllZmVybiEgS29zdGV0IHp3YXIsIGFiZXIgdmVyaGluZGVydAorICAvLyBlaW5pZ2UgYW5kZXJlIEJ1Z3MgdW5kIHZlcnNlaGVudGxpY2hlIEFlbmRlcnVuZ2VuIGFuIGRlbiBTa2lsbHMhCisgIHJldHVybihkZWVwX2NvcHkoaW50ZXJuYWxfcXVlcnlfbmV3c2tpbGxzKGdpbGRlKSkpOworfQorCisvLyBFaWdlbnRsaWNoIHNvbGx0ZSBtYW4gZGVuIF9zZXQtRnVua3Rpb25lbiBrZWluZSB3ZWl0ZXJlbiBQYXJhbWV0ZXIgZ2ViZW4KK3N0YXRpYyB2YXJhcmdzIG1hcHBpbmcgX3NldF9uZXdza2lsbHMobWFwcGluZyB2YWx1ZSwgc3RyaW5nIGdpbGRlKSB7CisKKyAgLy8gdmFsdWUgYXVmIE1hcHBpbmdzIG5vcm1hbGlzaWVyZW4sIGdnZi4gS29waWVyZW4KKyAgaWYgKCAhbWFwcGluZ3AodmFsdWUpICkKKyAgICAgIHZhbHVlPShbXSk7CisgIGVsc2UKKyAgICAgIC8venVyIFNpY2hlcmhlaXQsIHdlciB3ZWlzcywgd2FzIGRlciBzZXR6ZW5kZSBub2NoIGRhbWl0IG1hY2h0Li4uCisgICAgICB2YWx1ZT1kZWVwX2NvcHkodmFsdWUpOworCisgIC8vIHVuZCBzZXR6ZW4uLi4KKyAgaW50ZXJuYWxfc2V0X25ld3NraWxscyh2YWx1ZSwgZ2lsZGUpOworCisgIC8vIHVuZCBub2NoIG5lIEtvcGllIHZvbiBkZW0gTGllZmVybiwgd2FzIHdpciBnZXNldHp0IGhhYmVuIChrZWluZSBSZWZlcmVueiwKKyAgLy8gc29uc3Qga29lbm50ZSBkZXIgQXVmcnVmZW5kZSBqYSBub2NoIGltIE5hY2hoaW5laW4gYWVuZGVybikuCisgIHJldHVybihfcXVlcnlfbmV3c2tpbGxzKGdpbGRlKSk7Cit9CisKK3ByaXZhdGUgbWFwcGluZyBJbnRlcm5hbFF1ZXJ5U2tpbGwoc3RyaW5nIHNuYW1lLCBzdHJpbmcgZ2lsZGUpIHsKKyAgbWl4ZWQgc2tpbGwsIHNraWxsczsKKyAgLy8gSW4gaXNfYW55IHdpcmQgZ2VzcGVpY2hlcnQsIG9iIGVzIGVpbiBnaWxkZW51bmFiaGFlbmdpZXIgU2tpbGwgaXN0LAorICAvLyBmdWVyIGRpZSBpc19kZWFjdGl2YXRlX3NraWxsLUFiZnJhZ2UuCisgIGludCBpc19hbnk7CisKKyAgLy8gU2tpbGxzIGtvbXBsZXR0IGFiZnJhZ2VuLCBrZWluZSBzcGV6LiBHaWxkZQorICBpZiAoIW1hcHBpbmdwKHNraWxscz1RdWVyeShQX05FV1NLSUxMUyxGX1ZBTFVFKSkpCisgICAgICByZXR1cm4gMDsKKworICBpZiAoc3RyaW5ncChnaWxkZSkgJiYgc2l6ZW9mKGdpbGRlKSkgeworICAgIC8vYmVzdGltbXRlIEdpbGRlIGFuZ2VnZWJlbiwgZ3V0LCBkb3J0IGd1Y2tlbi4KKyAgICBpZiAobWFwcGluZ3Aoc2tpbGxzW2dpbGRlXSkpCisgICAgICBza2lsbD1za2lsbHNbZ2lsZGVdW3NuYW1lXTsgCisgIH0KKyAgZWxzZSB7CisgICAgZ2lsZGU9UXVlcnlQcm9wKFBfR1VJTEQpOyAvL3JlYWxlIEdpbGRlIGhvbGVuCisgICAgaWYgKGdpbGRlICYmIG1hcHBpbmdwKHNraWxsc1tnaWxkZV0pICYmIAorCShza2lsbD1za2lsbHNbZ2lsZGVdW3NuYW1lXSkpIHsKKyAgICAgIC8vIGdpYnQgZXMgZGVuIFNwZWxsIGluIGRlciBHaWxkZSBkZXMgU3BpZWxlcnM/CisgICAgICAvLyBkYW5uIGhpZXIgbml4IG1hY2hlbi4uLgorICAgIH0KKyAgICBlbHNlIGlmIChtYXBwaW5ncChza2lsbHNbIkFOWSJdKSkgeworICAgICAvLyBadW0gU2NobHVzczogR2lidCBlcyBkZW4gU2tpbGwgdmllbGxlaWNodCBHaWxkZW51bmFiaGFlbmdpZz8KKyAgICAgIHNraWxsPXNraWxsc1siQU5ZIl1bc25hbWVdOworICAgICAgLy8gd2VubiBtYW4gaGllciByZWlua29tbXQsIGRhbm4gc3BhZXRlciBtaXQgaXNfZGVhY3RpdmF0ZWRfc2tpbGwoKSAKKyAgICAgIC8vIHBydWVmZW4hCisgICAgICBpc19hbnk9MTsKKyAgICB9CisgIH0KKworICAvLyB3ZW5uIGtlaW4gU2tpbGwgZ2VmdW5kZW4sIG1pdCAwIGRpcmVrdCByYXVzCisgIGlmICghc2tpbGwpIHJldHVybiAwOworCisgIC8vIEJlaSBnaWxkZW51bmFiaGFlbmdpZ2VuIGF1Y2ggaW0gU2tpbGxtYXBwaW5nIHZlcm1lcmtlbgorICBpZiAoIGlzX2FueSApIHsJCisgICAgICBza2lsbCs9KFtTSV9HVUlMRDoiQU5ZIl0pOwkKKyAgICAgIC8vIElzdCBlciB2aWVsbGVpY2h0IGluIGRlciBHaWxkZSBkZXMgU3BpZWxlcnMgZGVha3RpdmllcnQ/IAkJCisgICAgICAvLyBEaWVzIGthbm4gbnVyIGRlciBGYWxsIHNlaW4sIHdlbm4gZXMga2VpbiBHaWxkZW5za2lsbCBpc3QuCQkKKyAgICAgIGlmIChpc19kZWFjdGl2YXRlZF9za2lsbChzbmFtZSxnaWxkZSkpIHsJCSAgICAKKwkgIHJldHVybiAwOwkJCisgICAgICB9CisgIH0KKworICByZXR1cm4oc2tpbGwpOworfQorCitwdWJsaWMgdmFyYXJncyBtYXBwaW5nIFF1ZXJ5U2tpbGwoc3RyaW5nIHNuYW1lLCBzdHJpbmcgZ2lsZGUpIHsKKyAKKyAgICBpZiAoIXN0cmluZ3Aoc25hbWUpIHx8ICFzaXplb2Yoc25hbWUpKQorCXJldHVybiAwOworCisgICAgLy9Lb3BpZSB6dXJ1ZWNrbGllZmVybgorICAgIHJldHVybihkZWVwX2NvcHkoSW50ZXJuYWxRdWVyeVNraWxsKHNuYW1lLGdpbGRlKSkpOworfQorCisjZGVmaW5lIFNNVUwoeCx5KSAoKHg8MCAmJiB5PDApPygtMSp4KnkpOih4KnkpKQorcHVibGljIHZhcmFyZ3MgaW50IFF1ZXJ5U2tpbGxBYmlsaXR5KHN0cmluZyBzbmFtZSwgc3RyaW5nIGdpbGRlKQoreyBtYXBwaW5nIHNraWxsOworICBzdHJpbmcgc2tpbGwyOworCisgIGlmICggIShza2lsbD1JbnRlcm5hbFF1ZXJ5U2tpbGwoc25hbWUsIGdpbGRlKSkgKQorICAgIHJldHVybiAwOworCisgIGludCB2YWw9c2tpbGxbU0lfU0tJTExBQklMSVRZXTsKKworICBpZiAoc2tpbGwyPXNraWxsW1NJX0lOSEVSSVRdKQorICB7CisgICAgaW50IHZhbDI7CisgICAgdmFsMj1RdWVyeVNraWxsQWJpbGl0eShza2lsbDIpOworICAgIHZhbD0odmFsKk1BWF9BQklMSVRZK1NNVUwodmFsLHZhbDIpKS8oMipNQVhfQUJJTElUWSk7CisgIH0KKworICByZXR1cm4gdmFsOworfQorCitwcm90ZWN0ZWQgdmFyYXJncyBtaXhlZCBMaW1pdEFiaWxpdHkobWFwcGluZyBzaW5mbywgaW50IGRpZmYpCit7IG1peGVkIGFiaWw7CisgIGludCBtYXgsb2xkLGQyOworCisgIGFiaWw9c2luZm9bU0lfU0tJTExBQklMSVRZXTsKKworICBpZiAoICFpbnRwKGFiaWwpICkKKyAgICByZXR1cm4gc2luZm87CisgIG9sZD1hYmlsOworCisgIC8vIEJlaW0gU3BpZWxlciBlaW5nZXRyYWdlbmUgU2Nod2llcmlna2VpdCBnaWx0IHZvciBhbmdlZ2ViZW5lci4KKyAgaWYgKCAoZDI9c2luZm9bU0lfRElGRklDVUxUWV0pICkKKyAgICBkaWZmPWQyOworCisgIC8vIGRpZmYgPC0xMDAgc29sbCBuaWNodCBoZW1tZW4gdW5kIG1hY2h0IGtlaW5lbiBTaW5uCisgIGRpZmY9KGRpZmY8KC0xMDApKT8oLTEwMCk6ZGlmZjsKKyAgCisgIG1heD1NQVhfQUJJTElUWS0oZGlmZisxMDApKigzNS1RdWVyeVByb3AoUF9MRVZFTCkpOworCisvLyBkaWZmfGx2bCAxOnwgICAzOnwJNzp8IDEwOnwgMTM6fCAxNjp8IDE5OnwgMjI6fCAyNTp8IDI4OnwgMzE6fCAzNDp8CisvLyAtLS0tKy0tLS0tLSstLS0tLSstLS0tLSstLS0tKy0tLS0rLS0tLSstLS0tKy0tLS0rLS0tLSstLS0tKy0tLS0rLS0tLSsKKy8vICAtNTB8ICAgODMlfCAgODQlfCAgODYlfCA4NyV8IDg5JXwgOTAlfCA5MiV8IDkzJXwgOTUlfCA5NiV8IDk4JXwgOTklfAorLy8gIC0xMHwgICA2OSV8ICA3MiV8ICA3NCV8IDc3JXwgODAlfCA4MiV8IDg1JXwgODglfCA5MSV8IDkzJXwgOTYlfCA5OSV8CisvLyAgICAwfCAgIDY2JXwgIDY5JXwgIDcyJXwgNzUlfCA3OCV8IDgxJXwgODQlfCA4NyV8IDkwJXwgOTMlfCA5NiV8IDk5JXwKKy8vICAgMTB8ICAgNjIlfCAgNjUlfCAgNjklfCA3MiV8IDc1JXwgNzklfCA4MiV8IDg1JXwgODklfCA5MiV8IDk1JXwgOTglfAorLy8gICAyMHwgICA1OSV8ICA2MiV8ICA2NiV8IDcwJXwgNzMlfCA3NyV8IDgwJXwgODQlfCA4OCV8IDkxJXwgOTUlfCA5OCV8CisvLyAgIDMwfCAgIDU1JXwgIDU5JXwgIDYzJXwgNjclfCA3MSV8IDc1JXwgNzklfCA4MyV8IDg3JXwgOTAlfCA5NCV8IDk4JXwKKy8vICAgNDB8ICAgNTIlfCAgNTYlfCAgNjAlfCA2NSV8IDY5JXwgNzMlfCA3NyV8IDgxJXwgODYlfCA5MCV8IDk0JXwgOTglfAorLy8gICA1MHwgICA0OSV8ICA1MyV8ICA1OCV8IDYyJXwgNjclfCA3MSV8IDc2JXwgODAlfCA4NSV8IDg5JXwgOTQlfCA5OCV8CisvLyAgMTAwfCAgIDMyJXwgIDM4JXwgIDQ0JXwgNTAlfCA1NiV8IDYyJXwgNjglfCA3NCV8IDgwJXwgODYlfCA5MiV8IDk4JXwKKy8vICAxNTB8ICAgMTUlfCAgMjIlfCAgMzAlfCAzNyV8IDQ1JXwgNTIlfCA2MCV8IDY3JXwgNzUlfCA4MiV8IDkwJXwgOTclfAorLy8gIDIwMHwgICAtMiV8ICAgNyV8ICAxNiV8IDI1JXwgMzQlfCA0MyV8IDUyJXwgNjElfCA3MCV8IDc5JXwgODglfCA5NyV8CisvLyAgMjUwfCAgLTE5JXwgIC04JXwJMiV8IDEyJXwgMjMlfCAzMyV8IDQ0JXwgNTQlfCA2NSV8IDc1JXwgODYlfCA5NiV8CisvLyAgMzAwfCAgLTM2JXwgLTI0JXwgLTEyJXwgIDAlfCAxMiV8IDI0JXwgMzYlfCA0OCV8IDYwJXwgNzIlfCA4NCV8IDk2JXwKKy8vICA0MDB8ICAtNzAlfCAtNTUlfCAtNDAlfC0yNSV8LTEwJXwgIDUlfCAyMCV8IDM1JXwgNTAlfCA2NSV8IDgwJXwgOTUlfAorLy8gIDUwMHwgLTEwNCV8IC04NiV8IC02OCV8LTUwJXwtMzIlfC0xNCV8ICA0JXwgMjIlfCA0MCV8IDU4JXwgNzYlfCA5NCV8CisvLyAgNjAwfCAtMTM4JXwtMTE3JXwgLTk2JXwtNzUlfC01NCV8LTMzJXwtMTIlfCAgOSV8IDMwJXwgNTElfCA3MiV8IDkzJXwKKworICBpZiAoIGFiaWw+bWF4ICkKKyAgICBhYmlsPW1heDsKKyAgaWYgKCBhYmlsPk1BWF9BQklMSVRZCisgICAgKSBhYmlsPU1BWF9BQklMSVRZOworICBlbHNlIGlmICggYWJpbDwtTUFYX0FCSUxJVFkgKQorICAgIGFiaWw9LU1BWF9BQklMSVRZOworCisgIGlmICggb2xkICYmICFhYmlsICkKKyAgICBhYmlsPTE7CisgIC8vIEZhZWhpZ2tlaXRlbiBzb2xsZW4gbmljaHQgZHVyY2ggZGllIEJlZ3Jlbnp1bmcgdmVyc2Nod2luZGVuCisKKyAgc2luZm9bU0lfU0tJTExBQklMSVRZXT1hYmlsOworCisgIHJldHVybiBzaW5mbzsKK30KKworcHVibGljIHZhcmFyZ3Mgdm9pZCBNb2RpZnlTa2lsbChzdHJpbmcgc25hbWUsIG1peGVkIHZhbCwgaW50IGRpZmYsIHN0cmluZyBnaWxkZSkKK3sgCisgIG1hcHBpbmcgc2tpbGxzOworICBtaXhlZCBza2lsbDsKKworICBpZiAoICFzdHJpbmdwKHNuYW1lKSB8fCAhc2l6ZW9mKHNuYW1lKSApCisgICAgcmV0dXJuOworCisgIC8vIGludGVybmFsX3F1ZXJ5X25ld3NraWxscygpIG1hY2h0IGtlaW5lIEtvcGllCisgIHNraWxscz1pbnRlcm5hbF9xdWVyeV9uZXdza2lsbHMoZ2lsZGUpOworCisgIC8vIFNraWxsIGVybWl0dGVsbiwgd2VubiBuaWNodCBleGlzdGllcnQsIHdpcmQgZXIgYW5nZWxlZ3QuCisgIGlmICghc2tpbGw9c2tpbGxzW3NuYW1lXSkgeworICAgICAgc2tpbGw9KFtdKTsgCisgIH0KKyAgCisgIC8vIFp1ciBTaWNoZXJoZWl0IG1hbCBkYXMgTWFwcGluZyBrb3BpZXJlbiwgd2VyIHdlaXNzLCB3YXMgZGVyCQorICAvLyBBdWZydWZlbmRlIGRpZXNlciBGdW5rdGlvbiBzZWxiZXIgc3BhZXRlciBkYW1pdCBub2NoIG1hY2h0LgorICAvLyBpc3Qgb2ssIHdlbm4gdmFsIGtlaW4gTWFwcGluZyBpc3QsIGRhbm4gbWFjaHQgZGVlcF9jb3B5IG5peC4KKyAgdmFsPWRlZXBfY29weSh2YWwpOworCisgIC8vIFNraWxsIHVuZCB2YWwgdmVyZWluaWdlbgorICBpZiAoIG1hcHBpbmdwKHZhbCkgKQorICAgIHNraWxsKz12YWw7CisgIGVsc2UgaWYgKGludHAodmFsKSkKKyAgICBza2lsbFtTSV9TS0lMTEFCSUxJVFldPXZhbDsKKyAgZWxzZQorICAgIHJhaXNlX2Vycm9yKHNwcmludGYoIkJhZCBhcmcgMiB0byBNb2RpZnlTa2lsbCgpOiBleHBlY3RlZCAnaW50JywgIgorICAgICAgICAgICJnb3QgJS4xME8uXG4iLHZhbCkpOworCisgIC8vIExlcm5lbiBlbnRzcHJlY2hlbmQgU0lfRElGRklDVUxUWSBiZWdyZW56ZW4uCisgIGlmKGRpZmYgJiYgIW1lbWJlcihza2lsbCxTSV9ESUZGSUNVTFRZKSkKKyAgICBza2lsbFtTSV9ESUZGSUNVTFRZXT1kaWZmOworICBza2lsbD1MaW1pdEFiaWxpdHkoc2tpbGwsZGlmZiB8fCBza2lsbFtTSV9ESUZGSUNVTFRZXSk7CisgIAorICAvLyBzY2hsaWVzc2xpY2ggaW0gU2tpbGxtYXBwaW5nIHZlcm1lcmtlbi4gSW0gTm9ybWFsZmFsbCBpc3QgZGVyIFNraWxsIGpldHp0CisgIC8vIHNjaG9uIGdlYWVuZGVydCwgbmljaHQgZXJzdCBuYWNoIGRlbSBpbnRlcm5hbF9zZXRfbmV3c2tpbGxzKCkuCisgIHNraWxsc1tzbmFtZV09c2tpbGw7CisKKyAgLy8gZXhwbGl6aXRlcyBBYnNwZWljaGVybiBmYXN0IHVlYmVyZmx1ZXNzaWcsIHdlaWwgd2lyIG9iZW4gZWluZSBSZWZlcmVuegorICAvLyBhdWYgZGFzIFNraWxsbWFwcGluZyBnZWtyaWVndCBoYWJlbi4uLgorICAvLyBBYmVyIGVzIGtvZW5udGUgc2VpbiwgZGFzcyBkaWVzIGRlciBlcnN0ZSBTa2lsbCBmdWVyIGRpZXNlIEdpbGRlIGlzdCwKKyAgLy8gZGFubiBpc3QgZXMgbm9ldGlnLiBadW0gYW5kZXJlbiB3aXJkIGludGVybmFsX3NldF9uZXdza2lsbHMoKSBub2NobWFsCisgIC8vIGdlbG9nZ3QuCisgIGludGVybmFsX3NldF9uZXdza2lsbHMoc2tpbGxzLGdpbGRlKTsKK30KKworcHVibGljIHZhcmFyZ3Mgdm9pZCBMZWFyblNraWxsKHN0cmluZyBzbmFtZSwgaW50IGFkZCwgaW50IGRpZmYpCit7IG1hcHBpbmcgc2tpbGw7CisgIHN0cmluZyBza2lsbDIsZ2lsZGU7CisgIGludCB2YWw7CisKKyAgLy8gU3BpZWxlciBzb2xsZW4gbnVyIGxlcm5lbiwgd2VubiBzaWUgaW50ZXJhY3RpdmUgc2luZC4gRGFzIHNvbGwKKyAgLy8gbmF0dWVybGljaCBudXIgZnVlciBTcGllbGVyIGdlbHRlbi4KKyAgaWYgKHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUodGhpc19vYmplY3QoKSkgJiYgIWludGVyYWN0aXZlKCkpCisJICByZXR1cm47CisKKyAgaWYgKCBhZGQ+TUFYX1NLSUxMRUFSTiApCisgICAgYWRkPU1BWF9TS0lMTEVBUk47CisgIGVsc2UgaWYgKCBhZGQ8MSApCisgICAgYWRkPTE7CisKKyAgLy8gU2tpbGxtYXBwaW5nIGVybWl0dGVsbiAoaGllciBrb21tdCBrZWluZSBLb3BpZSB6dXJ1ZWNrKQorICBza2lsbD1JbnRlcm5hbFF1ZXJ5U2tpbGwoc25hbWUsIDApOworICAvLyB3ZW5uIGtlaW4gU2tpbGwsIGRhbm4gQWJicnVjaAorICBpZiAoIXNraWxsKSByZXR1cm47CisKKyAgdmFsPXNraWxsW1NJX1NLSUxMQUJJTElUWV07CisgIGdpbGRlPXNraWxsW1NJX0dVSUxEXTsKKyAKKyAgdmFsKz1hZGQ7CisKKyAgTW9kaWZ5U2tpbGwoc25hbWUsdmFsLGRpZmYsZ2lsZGUpOworICBpZiAoIHNraWxsMj1za2lsbFtTSV9JTkhFUklUXSApCisgICAgTGVhcm5Ta2lsbChza2lsbDIsYWRkLzMsZGlmZik7Cit9CisKK3B1YmxpYyB2YXJhcmdzIGludCBVc2VTcGVsbChzdHJpbmcgc3RyLCBzdHJpbmcgc3BlbGwpCit7IHN0cmluZyBnaWxkZSxzYm9vazsKKyAgbWFwcGluZyBzaW5mbzsKKyAgY2xvc3VyZSBjbDsKKyAgCisgIGlmICggIXNwZWxsICYmICEoc3BlbGw9cXVlcnlfdmVyYigpKSApCisgICAgcmV0dXJuIDA7CisKKyAgc3BlbGw9bG93ZXJfY2FzZShzcGVsbCk7CisKKyAgLy8gUXVlcnlTa2lsbCgpIGxpZWZlcnQgZWluZSBLb3BpZSBkZXMgU2tpbGxtYXBwaW5ncy4KKyAgLy8gd2VubiBza2lsbCB1bmJla2FubnQgb2RlciBBYmlsaXR5IDw9IDAsIGlzdCBkZXIgU3BlbGwgbmljaHQgbnV0emJhci4KKyAgaWYgKCAhKHNpbmZvPVF1ZXJ5U2tpbGwoc3BlbGwsMCkpCisgICAgICAgIHx8IHNpbmZvW1NJX1NLSUxMQUJJTElUWV0gPD0gMCApCisgICAgcmV0dXJuIDA7CisKKyAgc2luZm9bU0lfU0tJTExBUkddPXN0cjsgLy8gQXJndW1lbnQgZWludHJhZ2VuCisKKyAgaWYgKCAhY2xvc3VyZXAoY2w9c2luZm9bU0lfQ0xPU1VSRV0pICkKKyAgeworICAgIC8vIFdlbm4gZWluIFNwZWxsYm9vayBhbmdlZ2ViZW4gaXN0IHdpcmQgZGVyIFNwZWxsIGRpcmVrdCBhdXNnZWZ1ZWhydAorICAgIGlmICggc3RyaW5ncChzYm9vaz1zaW5mb1tTSV9TUEVMTEJPT0tdKSApCisgICAgICBjbD1zeW1ib2xfZnVuY3Rpb24oIlVzZVNwZWxsIixTUEVMTEJPT0tfRElSK3Nib29rKTsKKworICAgIC8vIFdlbm4gZGVyIFNwaWVsZXIgaW4gZWluZXIgR2lsZGUgaXN0LCBzbyB3ZWlzcyBkaWVzZSwgaW4gd2VsY2hlbQorICAgIC8vIFNwZWxsYm9vayBkZXIgU3BlbGwgenUgZmluZGVuIGlzdC4uLgorICAgIGVsc2UgaWYgKCAoZ2lsZGU9UXVlcnlQcm9wKFBfR1VJTEQpKSAmJiAKKyAgICAgICggZmluZF9vYmplY3QoR1VJTERfRElSK2dpbGRlKSB8fCBmaWxlX3NpemUoR1VJTERfRElSK2dpbGRlKyIuYyIpPi0xKSkKKyAgICAgIGNsPXN5bWJvbF9mdW5jdGlvbigiVXNlU3BlbGwiLEdVSUxEX0RJUitnaWxkZSk7CisgICAgZWxzZQorICAgICAgY2w9ZnVuY3Rpb24gaW50ICgpIHtyZXR1cm4gMDt9OworCisgICAgc2luZm9bU0lfQ0xPU1VSRV09Y2w7CisgICAgdmFsaWRfc2V0c2tpbGxzX292ZXJyaWRlPTE7CisgICAgTW9kaWZ5U2tpbGwoc3BlbGwsKFtTSV9DTE9TVVJFOmNsXSksMCxzaW5mb1tTSV9HVUlMRF0pOworICAgIHZhbGlkX3NldHNraWxsc19vdmVycmlkZT0wOworICB9CisgIHJldHVybiBmdW5jYWxsKGNsLHRoaXNfb2JqZWN0KCksc3BlbGwsc2luZm8pOworfQorCitwdWJsaWMgdmFyYXJncyBtaXhlZCBVc2VTa2lsbChzdHJpbmcgc2tpbGwsIG1hcHBpbmcgYXJncykKK3sgbWFwcGluZyBzaW5mbzsKKyAgc3RyaW5nIGdpbGRlLCBmdW5jLHNraWxsMjsKKyAgbWl4ZWQgcmVzOworICBjbG9zdXJlIGNsOworICAKKyAgaWYgKCAhc2tpbGwgfHwKKyAgICAgICBRdWVyeVByb3AoUF9HSE9TVCkpCisgICAgcmV0dXJuIDA7CisKKyAgc2tpbGw9Y2FwaXRhbGl6ZShza2lsbCk7CisgIC8vIFF1ZXJ5U2tpbGwoKSBsaWVmZXJ0IGVpbmUgS29waWUgZGVzIFNraWxsbWFwcGluZ3MKKyAgaWYgKCAhKHNpbmZvPVF1ZXJ5U2tpbGwoc2tpbGwsMCkpICkKKyAgICByZXR1cm4gMDsKKworICBpZiAoYXJncykKKyAgICBzaW5mbys9YXJnczsKKworICBpZiAoICFjbG9zdXJlcChjbD1zaW5mb1tTSV9DTE9TVVJFXSkgKQorICB7CisgICAgaWYgKCAhKGZ1bmM9c2luZm9bU0lfU0tJTExGVU5DXSkgICAgLy8gS2VpbmUgRnVua3Rpb24gYW5nZWdlYmVuPworICAgICAgICB8fCAhKGdpbGRlPVF1ZXJ5UHJvcChQX0dVSUxEKSkpIC8vIEtlaW5lIEdpbGRlIGFuZ2VnZWJlbj8KKyAgICB7CisgICAgICAvLyBEYW5uIFN0YW5kYXJkLUZ1bmt0aW9uIG5laG1lbiwgd2VubiBlcyBkaWUgbmljaHQgZ2lidCwgZGVuCisgICAgICAvLyBBYmlsaXR5LVdlcnQgenVydWVja2xpZWZlcm4uCisgICAgICBpZiAoIWNsb3N1cmVwKGNsID0gc3ltYm9sX2Z1bmN0aW9uKCJTdGRTa2lsbF8iK3NraWxsLHRoaXNfb2JqZWN0KCkpKSkKKyAgICAgICAgY2w9ZnVuY3Rpb24gaW50IChvYmplY3Qgb2IsIHN0cmluZyBzbmFtZSkKKyAgICAgICAgICAgICB7cmV0dXJuIFF1ZXJ5U2tpbGxBYmlsaXR5KHNuYW1lKTt9IDsKKyAgICB9CisgICAgZWxzZQorICAgIHsKKyAgICAgIC8vIFNvbnN0IGRpZXNlIEZ1bmt0aW9uIGltIEdpbGRlbm9iamVrdCBhdWZydWZlbgorICAgICAgY2w9c3ltYm9sX2Z1bmN0aW9uKGZ1bmMsR1VJTERfRElSK2dpbGRlKTsKKyAgICB9CisKKyAgICBzaW5mb1tTSV9DTE9TVVJFXT1jbDsKKyAgICB2YWxpZF9zZXRza2lsbHNfb3ZlcnJpZGU9MTsKKyAgICBNb2RpZnlTa2lsbChza2lsbCwoW1NJX0NMT1NVUkU6Y2xdKSwwLHNpbmZvW1NJX0dVSUxEXSk7CisgICAgdmFsaWRfc2V0c2tpbGxzX292ZXJyaWRlPTA7CisgIH0KKworICByZXM9ZnVuY2FsbChjbCx0aGlzX29iamVjdCgpLHNraWxsLHNpbmZvKTsKKyAgaWYgKCAoc2tpbGwyPXNpbmZvW1NJX0lOSEVSSVRdKSAmJiBtYXBwaW5ncChyZXMpICkKKyAgICByZXM9VXNlU2tpbGwoc2tpbGwyLHJlcyk7IC8vIEZ1ZXIgU2tpbGxzLCBkaWUgdm9uIGFuZGVyZW4gYWJoYWVuZ2VuCisKKyAgcmV0dXJuIHJlczsKK30KKworLy8gKioqKioqKioqKioqKiogU3BlbGxmYXRpZ3VlcyAqKioqKioqKioqKioqKioKKworLyogIFBydWVmdCBkaWUgU3BlbGxmYXRpZ3VlIGZ1ZXIgU3BydWNoKGdydXBwZSkgPGtleT4uCisgKiAgPGtleT4gZGFyZiAwIHNlaW4gKGdsb2JhbGUgU3BydWNoc3BlcnJlKS4KKyAqICBMaWVmZXJ0IDAsIHdlbm4ga2VpbmUgU3BlcnJlIHVuZCBkaWUgQWJsYXVmemVpdCwgd2VubiBlaW5lIFNwZXJyZSBub2NoCisgKiAgZ3VlbHRpZy4gaXN0LgorICovCitwdWJsaWMgdmFyYXJncyBpbnQgQ2hlY2tTcGVsbEZhdGlndWUoc3RyaW5nIGtleSkgeworICAvLyBrZXk9PTAgaXMgdGhlIChkZWZhdWx0KSBnbG9iYWwgc3BlbGxmYXRpZ3VlLgorICBpZiAoc3BlbGxfZmF0aWd1ZXNba2V5XSA+IHRpbWUoKSkKKyAgICByZXR1cm4gc3BlbGxfZmF0aWd1ZXNba2V5XTsgLy8gQWJsYXVmemVpdCB6dXJ1ZWNrZ2ViZW4uCisKKyAgcmV0dXJuIDA7IC8vIG9rLCBrZWluZSBTcGVycmUuCit9CisKKy8qKiBTcGVpY2hlcnQgZWluZSBTcGVsbGZhdGlndWUgdm9uIDxkdXJhdGlvbj4gU2VrdW5kZW4gZnVlciA8a2V5Pi4KKyAqIDxrZXk+IGRhcmYgMCBzZWluIHVuZCBiZXplaWNobmV0IGRhcyBnbG9iYWxlIFNwZWxsZmF0aWd1ZS4KKyAqIFJ1ZWNrZ2FiZXdlcnQ6IEFibGF1ZnplaXQgZGVyIGdlc2V0enRlbiBTcGVycmUKKyAgICAgICAgICAgICAgICAgIC0xLCB3ZW5uIG5vY2ggZWluZSBuaWNodC1hYmdlbGF1ZmVuZSBTcGVycmUgYXVmIGRlbSA8a2V5PiBsYWcuCisgICAgICAgICAgICAgICAgICAwLCB3ZW5uIGR1cmF0aW9uIDAgaXN0LgorICovCitwdWJsaWMgdmFyYXJncyBpbnQgU2V0U3BlbGxGYXRpZ3VlKGludCBkdXJhdGlvbiwgc3RyaW5nIGtleSkgeworICAvLyBha3R1ZWxsZSBTcGVycmUgYWJnZWxhdWZlbj8KKyAgaWYgKENoZWNrU3BlbGxGYXRpZ3VlKGtleSkpCisgICAgcmV0dXJuIC0xOyAvLyBhbHRlIFNwZXJyZSBub2NoIGFrdGl2LgorCisgIGR1cmF0aW9uICs9IHRpbWUoKTsKKyAgLy8gMCBpcyBPSyBmb3IgPGtleT4sIGl0IGlzIHRoZSBrZXkgZm9yIGdsb2JhbCBzcGVsbCBmYXRpZ3VlcworICBzcGVsbF9mYXRpZ3Vlc1trZXldID0gZHVyYXRpb247CisgIHJldHVybiBkdXJhdGlvbjsKK30KKworLyogIFBydWVmdCBkaWUgU3BlbGxmYXRpZ3VlIGZ1ZXIgU3BydWNoKGdydXBwZSkgPGtleT4uCisgKiAgPGtleT4gZGFyZiBmdWVyIGRpZXNlIEZ1bmt0aW9uIDAgKGdsb2JhbGUgU3BydWNoc3BlcnJlKSBzZWluLCBhYmVyIG1hbgorICogIGRhcmYgZGFzIEFyZ3VtZW50IG5pY2h0IHdlZ2xhc3NlbiwgZGFtaXQgbmljaHQgZWluIHZlcnBlaWx0ZXIgTWFnaWVyCisgKiAgdmVyc2VoZW50bGljaCBkaWUgZ2xvYmFsZSBTcHJ1Y2hzcGVycmUgbnVsbHQuCisgKi8KK3B1YmxpYyB2b2lkIERlbGV0ZVNwZWxsRmF0aWd1ZShzdHJpbmcga2V5KSB7CisgIC8vIGtleT09MCBpcyB0aGUgKGRlZmF1bHQpIGdsb2JhbCBzcGVsbGZhdGlndWUuCisgIG1fZGVsZXRlKHNwZWxsX2ZhdGlndWVzLCBrZXkpOworfQorCisvKiogTG9lc2NodCBhYmdlbGF1ZmVuZSBLZXlzIGF1cyBkZW0gc3BlbGxfZmF0aWd1ZSBtYXBwaW5nLgorICovCitwcml2YXRlIHZvaWQgZXhwaXJlX3NwZWxsX2ZhdGlndWVzKCkgeworICBmb3JlYWNoKHN0cmluZyBrZXksIGludCBlbmR0aW1lOiBzcGVsbF9mYXRpZ3VlcykgeworICAgIGlmIChlbmR0aW1lIDw9IHRpbWUoKSkKKyAgICAgIG1fZGVsZXRlKHNwZWxsX2ZhdGlndWVzLCBrZXkpOworICB9Cit9CisKKy8qKiBTZXRtZXRob2RlIGZ1ZXIgUF9ORVhUX1NQRUxMX1RJTUUuCisgICovCitzdGF0aWMgaW50IF9zZXRfbmV4dF9zcGVsbChpbnQgZmF0aWd1ZSkgeworICByZXR1cm4gU2V0U3BlbGxGYXRpZ3VlKGZhdGlndWUgLSB0aW1lKCkpOworfQorLyoqIFF1ZXJ5bWV0aG9kZSBmdWVyIFBfTkVYVF9TUEVMTF9USU1FLgorICAqLworc3RhdGljIGludCBfcXVlcnlfbmV4dF9zcGVsbCgpIHsKKyAgcmV0dXJuIENoZWNrU3BlbGxGYXRpZ3VlKCk7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9saXZpbmcvc3RkX3NraWxscy5jIGIvc3RkL2xpdmluZy9zdGRfc2tpbGxzLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDEzMmVmYwotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9saXZpbmcvc3RkX3NraWxscy5jCkBAIC0wLDAgKzEsMTA0IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gbGl2aW5nL3N0ZF9za2lsbHMuYyAtLSBTdGFuZGFyZGZhZWhpZ2tlaXRlbgorLy8KKy8vICRJZDogc3RkX3NraWxscy5jIDY2NzMgMjAwOC0wMS0wNSAyMDo1Nzo0M1ogWmVzc3RyYSAkCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8bGl2aW5nL3NraWxscy5oPgorI2luY2x1ZGUgPGxpdmluZy9za2lsbF9hdHRyaWJ1dGVzLmg+CisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGF0dHJpYnV0ZXMuaD4KKyN1bmRlZiBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8bmV3X3NraWxscy5oPgorCisjZGVmaW5lIFNJRyh4KSAoeD8oeD4wPzE6LTEpOjApCisKK3Byb3RlY3RlZCBpbnQgU3RkU2tpbGxfTmlnaHR2aXNpb24ob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1peGVkIHNpbmZvKSB7CisgIGludCBhYmlsLGxpZ2h0LGxsdCxkdCxyZXM7CisKKyAgaWYgKCFzaW5mbyB8fCAhZW52aXJvbm1lbnQoKSkgcmV0dXJuIDA7CisgIGlmIChpbnRwKHNpbmZvKSkgc2luZm89KFtTSV9TS0lMTEFCSUxJVFk6c2luZm9dKTsKKyAgaWYgKCFtYXBwaW5ncChzaW5mbykpIHJldHVybiAwOworICBpZiAoKGxpZ2h0PVF1ZXJ5UHJvcChQX1BMQVlFUl9MSUdIVCkpPjApIHsKKyAgICBNb2RpZnlTa2lsbChzbmFtZSwoW1NJX0xBU1RMSUdIVDp0aW1lKCldKSk7CisgICAgcmV0dXJuIGxpZ2h0OworICB9CisgIGFiaWw9c2luZm9bU0lfU0tJTExBQklMSVRZXTsKKyAgaWYgKCEobGx0PXNpbmZvW1NJX0xBU1RMSUdIVF0pKSB7CisgICAgTW9kaWZ5U2tpbGwoc25hbWUsKFtTSV9MQVNUTElHSFQ6dGltZSgpXSkpOworICAgIGR0PTA7CisgIH0gZWxzZSB7CisgICAgZHQ9dGltZSgpLWxsdDsKKyAgICBpZiAoZHQ8MCkgZHQ9MDsKKyAgICBpZiAoZHQ+ODY0MDApIGR0PTg2NDAwOworICB9CisKKyAgcmVzPShhYmlsKmR0KS8oMjAqTUFYX0FCSUxJVFkpK2xpZ2h0OworICBpZiAocmVzPD0wKSB7CisgICAgcmVzLS07IC8vIFdlcnQgbXVzcyAhPTAgc2VpbgorICAgIGlmIChyZXM8LU1BWF9BQklMSVRZKSByZXM9LU1BWF9BQklMSVRZOworICB9IGVsc2UgeworICAgIGlmIChyZXM+TUFYX0FCSUxJVFkpIHJlcz1NQVhfQUJJTElUWTsKKyAgfQorICByZXR1cm4gcmVzOworfQorCitwcm90ZWN0ZWQgbWFwcGluZyBTdGRTa2lsbF9CaWhhbmQob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2luZm8pIHsKKyAgaW50IGFiaWwsdmFsOworCisgIC8vIHByaW50ZigiQmloYW5kOiAlT1xuIixzaW5mbyk7CisgIGlmICghc2luZm8pIHJldHVybiAwOworICBhYmlsPXNpbmZvW1NJX1NLSUxMQUJJTElUWV07CisgIHZhbD0oYWJpbCooUXVlcnlBdHRyaWJ1dGUoQV9TVFIpKzMzKSkvTUFYX0FCSUxJVFk7CisgIHZhbD0odmFsKlF1ZXJ5U2tpbGxBdHRyaWJ1dGUoU0FfREFNQUdFKSkvMTAwOworICBzaW5mb1tTSV9TS0lMTERBTUFHRV0rPXZhbDsKKyAgLy8gKyBtYXguIDUzCisgIHJldHVybiBzaW5mbzsKK30KKworcHJvdGVjdGVkIG1hcHBpbmcgU3RkU2tpbGxfRmlnaHRfc3dvcmQob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2luZm8pIHsKKyAgaW50IGFiaWwsYXNpZyx2YWw7CisKKyAgYWJpbD1zaW5mb1tTSV9TS0lMTEFCSUxJVFldO2FzaWc9U0lHKGFiaWwpOworICB2YWw9KGFiaWwqKFF1ZXJ5QXR0cmlidXRlKEFfU1RSKSArCisgICAgICAgICAgICAgUXVlcnlBdHRyaWJ1dGUoQV9ERVgpKmFzaWcgKworICAgICAgICAgICAgIDMzKSkvTUFYX0FCSUxJVFk7CisgIHZhbD0odmFsKlF1ZXJ5U2tpbGxBdHRyaWJ1dGUoU0FfREFNQUdFKSkvMTAwOworICBzaW5mb1tTSV9TS0lMTERBTUFHRV0rPXZhbDsKKyAgLy8gKyBtYXguIDczCisgIHJldHVybiBzaW5mbzsKK30KKworcHJvdGVjdGVkIG1hcHBpbmcgU3RkU2tpbGxfRmlnaHRfaGFuZHMob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2luZm8pIHsKKyAgaW50IGFiaWwsYXNpZyx2YWw7CisKKyAgaWYgKCFzaW5mbykgcmV0dXJuIDA7CisgIGFiaWw9c2luZm9bU0lfU0tJTExBQklMSVRZXTthc2lnPVNJRyhhYmlsKTsKKyAgdmFsPShhYmlsKihRdWVyeUF0dHJpYnV0ZShBX1NUUikgKworICAgICAgICAgICAgIFF1ZXJ5QXR0cmlidXRlKEFfREVYKSozKmFzaWcgKworICAgICAgICAgICAgIDEwMCkpL01BWF9BQklMSVRZOworICB2YWw9KHZhbCpRdWVyeVNraWxsQXR0cmlidXRlKFNBX0RBTUFHRSkpLzEwMDsKKyAgc2luZm9bU0lfU0tJTExEQU1BR0VdKz12YWw7CisgIC8vICsgbWF4LiAxODAKKyAgcmV0dXJuIHNpbmZvOworfQorCitwcm90ZWN0ZWQgaW50IFN0ZFNraWxsX0Jvb3plKG9iamVjdCBtZSwgc3RyaW5nIHNuYW1lLCBtYXBwaW5nIHNpbmZvKSB7CisgIGludCBhYmlsLHZhbDsKKworICB2YWw9MDsKKyAgaWYgKCFzaW5mbyB8fCAodmFsPXNpbmZvW1NJX1NLSUxMQVJHXSk8PTApCisgICAgcmV0dXJuIHZhbDsKKyAgYWJpbD1zaW5mb1tTSV9TS0lMTEFCSUxJVFldOworICB2YWwtPSh2YWwqYWJpbCkvKE1BWF9BQklMSVRZKzI1MDApOyAvLyBCaXMgenUgODAlIEFienVnIGJlaSBBbGtvaG9saWtlcm4uCisgIGlmICh2YWw8PTApIHZhbD0xOworICByZXR1cm4gdmFsOworfQorCmRpZmYgLS1naXQgYS9zdGQvbGl2aW5nL3RlYW0uYyBiL3N0ZC9saXZpbmcvdGVhbS5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJiMzFkYjkKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvbGl2aW5nL3RlYW0uYwpAQCAtMCwwICsxLDY1MCBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGxpdmluZy90ZWFtLmMKKy8vCisvLyAkSWQ6IHRlYW0uYyA5MTM4IDIwMTUtMDItMDMgMjE6NDY6NTZaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxsaXZpbmcvY29tYmF0Lmg+CisjaW5jbHVkZSA8Y29tYmF0Lmg+CisjaW5jbHVkZSA8bGl2aW5nL3RlYW0uaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxob29rLmg+CisKKyNkZWZpbmUgTUUgdGhpc19vYmplY3QoKQorI2RlZmluZSBUUCB0aGlzX3BsYXllcigpCisjZGVmaW5lIFBPIHByZXZpb3VzX29iamVjdCgpCisjZGVmaW5lIEVOViBlbnZpcm9ubWVudCgpCisKK3ByaXZhdGUgbm9zYXZlIHN0cmluZyB0ZWFtX2F0dGFja19jbWQ7Citwcml2YXRlIG5vc2F2ZSBtYXBwaW5nIHRlYW1fZm9sbG93X3RvZG87Citwcml2YXRlIG5vc2F2ZSBpbnQgdGVhbV9hdXRvZm9sbG93OworcHJpdmF0ZSBub3NhdmUgb2JqZWN0IHRlYW1tb3ZlOworCit2b2lkIGNyZWF0ZSgpIHsKKyAgU2V0KFBfVEVBTV9BVFRBQ0tfQ01ELC0xLEZfU0VUX01FVEhPRCk7CisgIFNldChQX1RFQU1fQVRUQUNLX0NNRCxQUk9URUNURUQsRl9NT0RFX0FTKTsKKyAgU2V0KFBfVEVBTV9BVVRPRk9MTE9XLC0xLEZfU0VUX01FVEhPRCk7CisgIFNldChQX1RFQU1fQVVUT0ZPTExPVyxQUk9URUNURUQsRl9NT0RFX0FTKTsKKyAgdGVhbW1vdmU9MDsKKyAgb2ZmZXJIb29rKEhfSE9PS19URUFNUk9XQ0hBTkdFLCAxKTsKK30KKwordm9pZCBhZGRfdGVhbV9jb21tYW5kcygpIHsKKyAgYWRkX2FjdGlvbigidGVhbWNtZCIsImdydXBwZSIpOworICBhZGRfYWN0aW9uKCJ0ZWFtY21kIiwiZyIpOworICBhZGRfYWN0aW9uKCJ0ZWFtY21kIiwidGVhbSIpOworfQorCitzdHJpbmcgX3F1ZXJ5X3RlYW1fYXR0YWNrX2NtZCgpIHsKKyAgcmV0dXJuIFNldChQX1RFQU1fQVRUQUNLX0NNRCx0ZWFtX2F0dGFja19jbWQpOworfQorCitpbnQgX3F1ZXJ5X3RlYW1fYXV0b2ZvbGxvdygpIHsKKyAgcmV0dXJuIFNldChQX1RFQU1fQVVUT0ZPTExPVyx0ZWFtX2F1dG9mb2xsb3cpOworfQorCitwcml2YXRlIGludCB0ZWFtX2hlbHAoKSB7CisgIC8vIFN5bnRheC1Lb21wYXRpYmxpdGFldCAoQXZhbG9uKSBpc3QgZ2FueiBuZXR0IDotKQorICB3cml0ZSgiXAorKEJlZmVobGUgZGVzIFRlYW1sZWl0ZXJzIHNpbmQgbWl0ICogZ2VrZW5uemVpY2huZXRcblwKK1xuXAorKiB0ZWFtIGFuZ3JpZmZcblwKKyAgdGVhbSBhbmdyaWZmc2JlZmVobCA8YmVmZWhsPlxuXAorKiB0ZWFtIGF1Zm5haG1lIDxuYW1lPlxuXAorICB0ZWFtIGF1dG9mW29sZ2VdIDxlaW4vYXVzPlxuXAorKiB0ZWFtIGF1dG9pW25mb10gPGVpbi9hdXM+IFsrW2xwXV0gWytba3BdXSBbc29mb3J0XVxuXAorKiB0ZWFtIGVudGxhc3NlIDxuYW1lPlxuXAorICB0ZWFtIGZhcmJlbiBscF9yb3QgbHBfZ2VsYiBrcF9yb3Qga3BfZ2VsYlxuXAorICB0ZWFtIGZsdWNodFtyZWloZV0gPHJlaWhlPlxuXAorICB0ZWFtIGZvbGdlIDxuYW1lPlxuXAorKiB0ZWFtIGZvcm1hdGlvbiA8bWluWy1tYXhdPiBbPG1pblstbWF4XT4gLi4uXVxuXAorICB0ZWFtIGhpbGZlfD9cblwKKyAgdGVhbSBbaW5mb10gW3NvcnRpZXJ0fGFscGhhYmV0aXNjaF1cblwKKyAgdGVhbSBba2FtcGZdcmVpaGUgPHJlaWhlPlxuXAorKiB0ZWFtIGxlaXRlcltpbl0gPG5hbWU+XG5cCisgIHRlYW0gbGlzdGVcblwKKyogdGVhbSBuYW1lIDxncnVwcGVubmFtZT5cblwKKyAgdGVhbSBvcnRlIFthbGxlXVxuXAorICB0ZWFtIHJ1ZltlXVxuXAorICB0ZWFtIHVlYmVyc2ljaHRcblwKKyAgdGVhbSB2ZXJsYXNzZVxuIik7CisgIHJldHVybiAxOworfQorCitvYmplY3QgSXNUZWFtTGVhZGVyKCkgeworICBvYmplY3QgdGVhbTsKKworICBpZiAoIW9iamVjdHAodGVhbT1RdWVyeShQX1RFQU0pKQorICAgICAgfHwgdGVhbSE9UXVlcnkoUF9URUFNX0xFQURFUikKKyAgICAgIHx8IHRlYW0tPkxlYWRlcigpIT1NRSkKKyAgICByZXR1cm4gMDsKKyAgcmV0dXJuIHRlYW07Cit9CisKK29iamVjdCAqVGVhbU1lbWJlcnMoKSB7CisgIG9iamVjdCB0ZWFtOworCisgIGlmICghb2JqZWN0cCh0ZWFtPVF1ZXJ5KFBfVEVBTSkpKQorICAgIHJldHVybiAoe01FfSk7CisgIHJldHVybiB0ZWFtLT5NZW1iZXJzKCk7Cit9CisKK3N0cmluZyBUZWFtUHJlZml4KCkgeworICBvYmplY3QgdGVhbTsKKworICBpZiAoIW9iamVjdHAodGVhbT1RdWVyeShQX1RFQU0pKSkKKyAgICByZXR1cm4gIiI7CisgIHJldHVybiAiWyIrdGVhbS0+TmFtZSgpKyJdICI7Cit9CisKKworcHJpdmF0ZSBpbnQgdGVhbV9hdWZuYWhtZXd1bnNjaChzdHJpbmcgYXJnKSB7CisgIG9iamVjdCBwbDsKKworICBpZiAoKCFvYmplY3RwKHBsPWZpbmRfcGxheWVyKGFyZykpICYmICFvYmplY3RwKHBsPXByZXNlbnQoYXJnLEVOVikpKQorICAgICAgfHwgcGwtPlF1ZXJ5UHJvcChQX0lOVklTKSB8fCBlbnZpcm9ubWVudChwbCkhPUVOVikKKyAgICByZXR1cm4gbm90aWZ5X2ZhaWwoY2FwaXRhbGl6ZShhcmcpKyIgbmljaHQgZ2VmdW5kZW4uXG4iKSwwOworICBpZiAoIWxpdmluZyhwbCkpCisgICAgcmV0dXJuIG5vdGlmeV9mYWlsKHBsLT5OYW1lKFdFUikrIiBpc3QgZXR3YXMgenUgaW5ha3Rpdi5cbiIpLDA7CisgIGlmIChwbD09TUUpCisgICAgcmV0dXJuIG5vdGlmeV9mYWlsKCJEdSBiaXN0IGVpbmUgUGVyc29uIHp1IHdlbmlnIGZ1ZXIgZWluIFRlYW0uXG4iKSwwOworICBTZXRQcm9wKFBfVEVBTV9ORVdNRU1CRVIscGwpOworICBpZiAocGwtPklzVGVhbUxlYWRlcigpKSB7CisgICAgd3JpdGUoIkR1IGJpdHRlc3QgIitwbC0+bmFtZShXRU4pKyIgdW0gQXVmbmFobWUgaW5zIFRlYW0uXG4iKTsKKyAgICB0ZWxsX29iamVjdChwbCxUUC0+TmFtZShXRVIpKyIgYml0dGV0IERpY2ggdW0gQXVmbmFobWUgaW5zIFRlYW0uXG4iKTsKKyAgfSBlbHNlIHsKKyAgICB3cml0ZSgiRHUgYml0dGVzdCAiK3BsLT5uYW1lKFdFTikrIiB1bSBHcnVlbmR1bmcgZWluZXMgVGVhbXMuXG4iKTsKKyAgICB0ZWxsX29iamVjdChwbCxUUC0+TmFtZShXRVIpKyIgYml0dGV0IERpY2ggdW0gR3J1ZW5kdW5nIGVpbmVzIFRlYW1zLlxuIik7CisgIH0KKyAgcmV0dXJuIDE7Cit9CisKK3ByaXZhdGUgaW50IHRlYW1fYXVmbmFobWUoc3RyaW5nIGFyZykgeworICBvYmplY3QgcGwsdGVhbTsKKyAgaW50IHJlczsKKworICBpZiAoKCFvYmplY3RwKHBsPWZpbmRfcGxheWVyKGFyZykpICYmICFvYmplY3RwKHBsPXByZXNlbnQoYXJnLEVOVikpKQorICAgICAgfHwgcGwtPlF1ZXJ5UHJvcChQX0lOVklTKSB8fCBlbnZpcm9ubWVudChwbCkhPUVOVikKKyAgICByZXR1cm4gbm90aWZ5X2ZhaWwoY2FwaXRhbGl6ZShhcmcpKyIgbmljaHQgZ2VmdW5kZW4uXG4iKSwwOworICBpZiAocGwtPlF1ZXJ5UHJvcChQX1RFQU1fTkVXTUVNQkVSKSE9TUUpCisgICAgcmV0dXJuIG5vdGlmeV9mYWlsKHBsLT5OYW1lKFdFUikrIiBoYXQgRGljaCBuaWNodCB1bSBBdWZuYWhtZSBnZWJldGVuLlxuIiksCisgICAgICAwOworICBpZiAocGw9PU1FKQorICAgIHJldHVybiBub3RpZnlfZmFpbCgiRHUgYmlzdCBlaW5lIFBlcnNvbiB6dSB3ZW5pZyBmdWVyIGVpbiBUZWFtLlxuIiksMDsKKyAgaWYgKCFvYmplY3RwKHRlYW09UXVlcnlQcm9wKFBfVEVBTSkpKQorICAgIHRlYW09Y2xvbmVfb2JqZWN0KFRFQU1fT0JKRUNUKTsKKyAgcmVzPXRlYW0tPkFkZE1lbWJlcihwbCk7CisgIGlmICghc2l6ZW9mKHRlYW0tPk1lbWJlcnMoKSkpCisgICAgdGVhbS0+cmVtb3ZlKCk7CisgIHJldHVybiByZXM7Cit9CisKK29iamVjdCBJc1RlYW1Nb3ZlKCkgeworICBpZiAoIW9iamVjdHAodGVhbW1vdmUpIHx8ICh0ZWFtbW92ZSE9UXVlcnkoUF9URUFNKSkpCisgICAgdGVhbW1vdmU9MDsKKyAgcmV0dXJuIHRlYW1tb3ZlOworfQorCitzdGF0aWMgdm9pZCBEb1RlYW1BdHRhY2sob2JqZWN0IGVudiwgb2JqZWN0IGNhbGxiYWNrdG8pIHsKKyAgaWYgKGVudj09RU5WICYmIHN0cmluZ3AodGVhbV9hdHRhY2tfY21kKSAmJiAhSVNfTEVBUk5FUihNRSkKKyAgICAgICYmIChpbnRlcmFjdGl2ZShNRSkgfHwgIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoTUUpKQorICAgICAgJiYgb2JqZWN0cChjYWxsYmFja3RvKSAmJiBjYWxsYmFja3RvPT1RdWVyeShQX1RFQU0pKSB7CisgICAgdGVhbW1vdmU9Y2FsbGJhY2t0bzsKKyAgICBjb21tYW5kKHRlYW1fYXR0YWNrX2NtZCk7CisgIH0KKyAgaWYgKG9iamVjdHAoY2FsbGJhY2t0bykpCisgICAgY2FsbGJhY2t0by0+VGVhbUF0dGFja0V4ZWN1dGVkX0NhbGxiYWNrKHRlYW1tb3ZlPzE6MCk7CisgIHRlYW1tb3ZlPTA7Cit9CisKK2ludCBDYWxsVGVhbUF0dGFjayhvYmplY3QgZW52KSB7CisgIGlmIChzdHJpbmdwKHRlYW1fYXR0YWNrX2NtZCkKKyAgICAgICYmIGZpbmRfY2FsbF9vdXQoIkRvVGVhbUF0dGFjayIpPDAKKyAgICAgICYmIFBPCisgICAgICAmJiBQTz09UXVlcnkoUF9URUFNKSkKKyAgICByZXR1cm4gY2FsbF9vdXQoIkRvVGVhbUF0dGFjayIsMCxlbnYsUE8pLDE7CisgIHJldHVybiAwOworfQorCitzdGF0aWMgaW50IERvVGVhbUZvbGxvdygpIHsKKyAgc3RyaW5nIGNtZDsKKworICBpZiAoIXRlYW1fYXV0b2ZvbGxvdworICAgICAgfHwgKCFpbnRlcmFjdGl2ZShNRSkgJiYgcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkpCisgICAgICB8fCBJU19MRUFSTkVSKE1FKQorICAgICAgfHwgIW1hcHBpbmdwKHRlYW1fZm9sbG93X3RvZG8pKQorICAgIHJldHVybiAwOworICBpZiAoIXN0cmluZ3AoY21kPXRlYW1fZm9sbG93X3RvZG9bRU5WXSkpCisgICAgcmV0dXJuIHRlYW1fZm9sbG93X3RvZG89MDsKKworICBkbyB7CisgICAgbV9kZWxldGUodGVhbV9mb2xsb3dfdG9kbyxFTlYpOworICAgIHRlbGxfb2JqZWN0KE1FLHNwcmludGYoIkR1IGZvbGdzdCBEZWluZW0gVGVhbSBtaXQgXCIlc1wiLlxuIixjbWQpKTsKKyAgICBjb21tYW5kKGNtZCk7CisgIH0gd2hpbGUgKGdldF9ldmFsX2Nvc3QoKT45MDAwMDAgJiYgcmFuZG9tKDEwMDApPjIwICYmIG9iamVjdHAoTUUpCisgICAgICAgICAgICYmIHN0cmluZ3AoY21kPXRlYW1fZm9sbG93X3RvZG9bRU5WXSkpOworCisgIC8vIElzdCBTcGllbGVyIGluIFVtZ2VidW5nIGdlbGFuZGV0LCBmdWVyIGRpZSBub2NoIGVpbgorICAvLyBCZWZlaGwgYXVzenVmdWVocmVuIGlzdD8KKyAgaWYgKCFvYmplY3RwKE1FKSB8fCAhc3RyaW5ncCh0ZWFtX2ZvbGxvd190b2RvW0VOVl0pKQorICAgIHJldHVybiB0ZWFtX2ZvbGxvd190b2RvPTA7CisgIHdoaWxlICAocmVtb3ZlX2NhbGxfb3V0KCJEb1RlYW1Gb2xsb3ciKSE9LTEpIDsKKyAgY2FsbF9vdXQoIkRvVGVhbUZvbGxvdyIsMCk7CisgIHJldHVybiAwOworfQorCitpbnQgQ2FsbFRlYW1Gb2xsb3cob2JqZWN0IGVudiwgc3RyaW5nIGNtZCkgeworICBpZiAoIXRlYW1fYXV0b2ZvbGxvdworICAgICAgfHwgUE8hPVF1ZXJ5KFBfVEVBTSkKKyAgICAgIHx8ICFQTworICAgICAgfHwgIW9iamVjdHAoZW52KQorICAgICAgfHwgIXN0cmluZ3AoY21kKSkKKyAgICByZXR1cm4gMDsKKyAgaWYgKCFtYXBwaW5ncCh0ZWFtX2ZvbGxvd190b2RvKSkKKyAgICB0ZWFtX2ZvbGxvd190b2RvPShbXSk7CisgIGlmIChFTlYhPWVudiAmJiAhdGVhbV9mb2xsb3dfdG9kb1tFTlZdKQorICAgIHJldHVybiAwOworICB0ZWFtX2ZvbGxvd190b2RvW2Vudl09Y21kOworICBpZiAoZmluZF9jYWxsX291dCgiRG9UZWFtRm9sbG93Iik8MCkKKyAgICBjYWxsX291dCgiRG9UZWFtRm9sbG93IiwwKTsKKyAgcmV0dXJuIDE7Cit9CisKK2ludCBDbGVhclRlYW1Gb2xsb3coKSB7CisgIGlmIChQTyE9UXVlcnkoUF9URUFNKSB8fCAhUE8pCisgICAgcmV0dXJuIDA7CisgIHRlYW1fZm9sbG93X3RvZG89KFtdKTsKKyAgcmV0dXJuIDE7Cit9CisKK21peGVkICpQcmVzZW50VGVhbVJvd3MoKSB7CisgIG9iamVjdCB0ZWFtOworICBtaXhlZCAqcmVzOworICBpbnQgaTsKKworICBpZiAoIW9iamVjdHAodGVhbT1RdWVyeShQX1RFQU0pKSkgeworICAgIHJlcz1FTVBUWV9URUFNQVJSQVk7CisgICAgcmVzWzBdPSh7TUV9KTsKKyAgICByZXR1cm4gcmVzOworICB9CisgIHJlcz10ZWFtLT5QcmVzZW50Um93cyhFTlYpOworICBmb3IgKGk9MDtpPE1BWF9URUFNUk9XUztpKyspCisgICAgaWYgKG1lbWJlcihyZXNbaV0sTUUpPj0wKQorICAgICAgcmV0dXJuIHJlczsKKyAgcmVzWzBdKz0oe01FfSk7CisgIHJldHVybiByZXM7Cit9CisKK3ZhcmFyZ3MgbWl4ZWQgKlByZXNlbnRFbmVteVJvd3Mob2JqZWN0ICpoZXJlKSB7CisgIG1peGVkICpyZXMsKnJvd3M7CisgIG1hcHBpbmcgYWRkZWRfdGVhbXM7CisgIGludCBpLGo7CisgIG9iamVjdCBvYix0ZWFtOworCisgIGFkZGVkX3RlYW1zPShbUXVlcnkoUF9URUFNKToxXSk7IC8vIE5pY2h0IGF1ZiBlaWdlbmVzIFRlYW0gaGF1ZW4KKyAgcmVzPUVNUFRZX1RFQU1BUlJBWTsKKyAgaWYgKCFwb2ludGVycChoZXJlKSkKKyAgICBoZXJlPVByZXNlbnRFbmVtaWVzKCk7CisgIGZvciAoaT1zaXplb2YoaGVyZSktMTtpPj0wO2ktLSkgeworICAgIGlmICghb2JqZWN0cChvYj1oZXJlW2ldKSkKKyAgICAgIGNvbnRpbnVlOworICAgIGlmICghb2JqZWN0cCh0ZWFtPW9iLT5RdWVyeVByb3AoUF9URUFNKSkpIHsKKyAgICAgIHJlc1swXSs9KHtvYn0pOworICAgICAgY29udGludWU7CisgICAgfQorICAgIGlmIChhZGRlZF90ZWFtc1t0ZWFtXSkKKyAgICAgIGNvbnRpbnVlOworICAgIGFkZGVkX3RlYW1zW3RlYW1dPTE7CisgICAgcm93cz10ZWFtLT5QcmVzZW50Um93cyhFTlYpOworICAgIGZvciAoaj0wO2o8TUFYX1RFQU1ST1dTO2orKykKKyAgICAgIHJlc1tqXSs9cm93c1tqXTsKKyAgfQorICByZXR1cm4gcmVzOworfQorCit2YXJhcmdzIG9iamVjdCBTZWxlY3ROZWFyRW5lbXkob2JqZWN0ICpoZXJlLCBpbnQgZm9yY2Vmcm9tKSB7CisgIG9iamVjdCBvYixlbix0ZWFtOworICBtaXhlZCAqcm93czsKKyAgaW50ICpwcm9iLHByb3QsaSxyLHN6LHVwc3osc3VtOworCisgIGlmICghcG9pbnRlcnAoaGVyZSkpCisgICAgaGVyZT1QcmVzZW50RW5lbWllcygpOworICBpZiAoIW9iamVjdHAob2I9U2VsZWN0RW5lbXkoaGVyZSkpKQorICAgIHJldHVybiAwOworICBlbj1vYi0+UXVlcnlQcm9wKFBfVEVBTSk7ICAgICAgICAgIC8vIEZlaW5kbGljaGVzIFRlYW0KKyAgaWYgKG9iamVjdHAodGVhbT1RdWVyeShQX1RFQU0pKSkgeyAvLyBFaWdlbmVzIFRlYW0KKyAgICBpZiAoZW49PXRlYW0pIC8vIEZlaW5kIGltIGVpZ2VuZW4gVGVhbSwga2VpbiBBTkRFUkVTIE1pdGdsaWVkIHdhZWhsZW4uCisgICAgICByZXR1cm4gb2I7ICAvLyBBYmVyIGF1Y2ggYXVzc2VyaGFsYiBSZWloZSAxIGRyYXVmaGF1ZW4KKyAgICByb3dzPXRlYW0tPlByZXNlbnRSb3dzKEVOVik7CisgICAgaWYgKG1lbWJlcihyb3dzWzBdLE1FKTwwKSAvLyBTdGVoZSBpY2ggaW4gZGVyIGVyc3RlbiBSZWloZT8KKyAgICAgIHJldHVybiAwOyAvLyBGYWxscyBuZWluIGlzdCBhdWNoIGtlaW4gR2VnbmVyIG5haGUuCisgIH0KKyAgaWYgKCFvYmplY3RwKGVuKSkKKyAgICByZXR1cm4gb2I7IC8vIElzdCBuaWNodCBpbiBlaW5lbSBUZWFtLCBhbHNvIGRyYXVmLgorICByb3dzPWVuLT5QcmVzZW50Um93cyhlbnZpcm9ubWVudChvYikpOworICBwcm9iPSh7MSwwLDAsMCwwfSk7CisgIHByb3Q9c3VtPTA7CisgIGZvciAoaT0wO2k8TUFYX1RFQU1ST1dTO2krKykgeworICAgIGlmIChwcm90PjApIHByb3QtLTsgICAgICAgICAgICAgICAgLy8gU2NodXR6a2VnZWwgbmltbXQgYWIuCisgICAgaWYgKCFzej1zaXplb2Yocm93c1tpXSkpIGNvbnRpbnVlOyAvLyBHZWduZXIgaW4gZGllc2VyIFJlaWhlCisgICAgdXBzej1zei1wcm90O2lmICh1cHN6PDApIGNvbnRpbnVlOyAvLyBBbnphaGwgdW5nZXNjaHVldHp0ZXIgR2VnbmVyCisgICAgcHJvYltpXSs9KHVwc3orc3VtKTsgICAgICAgICAgICAgICAvLyBXYWhyc2NoZWlubGljaGtlaXQgKz0gdW5nZXNjaHVldHp0CisgICAgc3VtPXByb2JbaV07ICAgICAgICAgICAgICAgICAgICAgICAvLyBTdW1tZSBiaXNoZXJpZ2VyIFdhaHJzY2hlaW5saWNoa2VpdGVuCisgICAgaWYgKHN6PnByb3QpIHByb3Q9c3o7ICAgICAgICAgICAgICAvLyBOZXVlciBTY2h1dHprZWdlbAorICB9CisgIHI9cmFuZG9tKHN1bSk7CisgIGZvciAoaT0wO2k8TUFYX1RFQU1ST1dTO2krKykKKyAgICBpZiAocjxwcm9iW2ldKQorICAgICAgYnJlYWs7CisgIGlmIChpPj1NQVhfVEVBTVJPV1MpCisgICAgaT0wOworICBpZiAob2JqZWN0cChlbj1TZWxlY3RFbmVteShmb3JjZWZyb20/KGhlcmUmcm93c1tpXSk6cm93c1tpXSkpKQorICAgIHJldHVybiBlbjsKKyAgaWYgKGkgJiYgb2JqZWN0cChlbj1TZWxlY3RFbmVteShmb3JjZWZyb20/KGhlcmUmcm93c1swXSk6cm93c1swXSkpKQorICAgIHJldHVybiBlbjsKKyAgcmV0dXJuIG9iOworfQorCit2YXJhcmdzIG9iamVjdCBTZWxlY3RGYXJFbmVteShvYmplY3QgKmhlcmUsIGludCBtaW4sIGludCBtYXgsIGludCBmb3JjZWZyb20pIHsKKyAgbWl4ZWQgKnJvd3M7CisgIGludCAqcHJvYixpLHIsc3VtOworICBvYmplY3QgZW47CisKKyAgaWYgKG1heDwwIHx8IG1pbj49TUFYX1RFQU1ST1dTIHx8IG1heDxtaW4pCisgICAgcmV0dXJuIDA7CisgIGlmIChtaW48MCkgbWluPTA7CisgIGlmIChtYXg+PU1BWF9URUFNUk9XUykgbWF4PU1BWF9URUFNUk9XUy0xOworICBpZiAoIXBvaW50ZXJwKGhlcmUpKQorICAgIGhlcmU9UHJlc2VudEVuZW1pZXMoKTsKKyAgcm93cz1QcmVzZW50RW5lbXlSb3dzKGhlcmUpOworICBwcm9iPSh7MCwwLDAsMCwwfSk7CisgIHN1bT0wOworICBmb3IgKGk9bWluO2k8PW1heDtpKyspCisgICAgc3VtPXByb2JbaV09c3VtK3NpemVvZihyb3dzW2ldKSttYXgtaTsKKworICByPXJhbmRvbShzdW0pOworICBmb3IgKGk9bWluO2k8PW1heDtpKyspCisgICAgaWYgKHI8cHJvYltpXSkKKyAgICAgIGJyZWFrOworICBpZiAoaT5tYXgpCisgICAgaT1taW47CisgIGlmIChvYmplY3RwKGVuPVNlbGVjdEVuZW15KGZvcmNlZnJvbT8oaGVyZSZyb3dzW2ldKTpyb3dzW2ldKSkpCisgICAgcmV0dXJuIGVuOworICBmb3IgKGk9bWluO2k8PW1heDtpKyspCisgICAgaWYgKG9iamVjdHAoZW49U2VsZWN0RW5lbXkoZm9yY2Vmcm9tPyhoZXJlJnJvd3NbaV0pOnJvd3NbaV0pKSkKKyAgICAgIHJldHVybiBlbjsKKyAgcmV0dXJuIDA7Cit9CisKK21peGVkIF9xdWVyeV9mcmllbmQoKSB7CisgIG1peGVkIHJlczsKKworICBpZiAocmVzPVF1ZXJ5KFBfRlJJRU5EKSkKKyAgICByZXR1cm4gcmVzOworICBpZiAob2JqZWN0cChyZXM9UXVlcnkoUF9URUFNX0FTU09DX01FTUJFUlMpKQorICAgICAgJiYgcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShyZXMpKQorICAgIHJldHVybiByZXM7CisgIHJldHVybiAwOworfQorCitpbnQgRGVBc3NvY01lbWJlcihvYmplY3QgbnBjKSB7CisgIG1peGVkIG9iczsKKyAgb2JqZWN0IHRlYW07CisKKyAgaWYgKGV4dGVybl9jYWxsKCkgJiYgUE8hPW5wYyAmJgorICAgICAgbWVtYmVyKCh7ImdpbGRlbiIsInNwZWxsYm9va3MifSksCisgICAgICAgICAgICAgZXhwbG9kZShvYmplY3RfbmFtZShQTyksIi8iKVsxXSk8MCkKKyAgICByZXR1cm4gMDsKKyAgb2JzPVF1ZXJ5UHJvcChQX1RFQU1fQVNTT0NfTUVNQkVSUyk7CisgIGlmICghcG9pbnRlcnAob2JzKSkKKyAgICByZXR1cm4gMDsKKyAgb2JzLT0oe25wYywwfSk7CisgIFNldFByb3AoUF9URUFNX0FTU09DX01FTUJFUlMsb2JzKTsKKyAgaWYgKG9iamVjdHAodGVhbT1RdWVyeVByb3AoUF9URUFNKSkpCisgICAgdGVhbS0+UmVtb3ZlQXNzb2NNZW1iZXIoTUUsbnBjKTsKKyAgcmV0dXJuIDE7Cit9CisKK2ludCBBc3NvY01lbWJlcihvYmplY3QgbnBjKSB7CisgIG1peGVkIG9iczsKKyAgb2JqZWN0IHRlYW07CisKKyAgaWYgKGV4dGVybl9jYWxsKCkgJiYgUE8hPW5wYyAmJgorICAgICAgbWVtYmVyKCh7ImdpbGRlbiIsInNwZWxsYm9va3MifSksCisgICAgICAgICAgICAgZXhwbG9kZShvYmplY3RfbmFtZShQTyksIi8iKVsxXSk8MCkKKyAgICByZXR1cm4gMDsKKyAgaWYgKCFvYmplY3RwKG5wYykKKyAgICAgIHx8IG5wYy0+UXVlcnlQcm9wKFBfVEVBTV9BU1NPQ19NRU1CRVJTKQorICAgICAgfHwgSXNFbmVteShucGMpCisgICAgICB8fCBucGM9PU1FCisgICAgICB8fCBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKG5wYykpCisgICAgcmV0dXJuIDA7CisgIG9icz1RdWVyeVByb3AoUF9URUFNX0FTU09DX01FTUJFUlMpOworICBpZiAob2JqZWN0cChvYnMpKQorICAgIHJldHVybiAwOworICBpZiAoIXBvaW50ZXJwKG9icykpCisgICAgb2JzPSh7fSk7CisgIG9icz0ob2JzLSh7bnBjLDB9KSkrKHtucGN9KTsKKyAgU2V0UHJvcChQX1RFQU1fQVNTT0NfTUVNQkVSUyxvYnMpOworICBucGMtPlNldFByb3AoUF9URUFNX0FTU09DX01FTUJFUlMsTUUpOworICBpZiAob2JqZWN0cCh0ZWFtPVF1ZXJ5UHJvcChQX1RFQU0pKSkKKyAgICB0ZWFtLT5BZGRBc3NvY01lbWJlcihNRSxucGMpOworICByZXR1cm4gMTsKK30KKwordmFyYXJncyB2b2lkIEluc2VydEVuZW15VGVhbShtaXhlZCBlbnMsIGludCByZWspIHsKKyAgb2JqZWN0ICpvYnMsb2IsZXRlYW0sdGVhbTsKKyAgaW50IGk7CisKKyAgdGVhbT1RdWVyeShQX1RFQU0pOworICAvLyBBbGxlIFRlYW1taXRnbGllZGVyIGRlcyBHZWduZXJzIHNpbmQgRmVpbmQ6CisgIGlmIChvYmplY3RwKGVucykpIHsKKyAgICBpZiAob2JqZWN0cChldGVhbT1lbnMtPlF1ZXJ5UHJvcChQX1RFQU0pKSkgeworICAgICAgaWYgKGV0ZWFtPT10ZWFtKSAvLyBmZWluZGxpY2hlcyBUZWFtID0gZWlnZW5lcyBUZWFtPworICAgICAgICByZXR1cm47ICAgICAgICAvLyBhbHNvIG5pY2h0IGFsbGUgVGVhbW1pdGdsaWVkZXIgZ2VnZW5laW5hbmRlciBoZXR6ZW4KKyAgICAgIGVucz1ldGVhbS0+TWVtYmVycygpOworICAgIH0gZWxzZSB7CisgICAgICBlbnM9KHtlbnN9KTsKKyAgICB9CisgIH0KKyAgaWYgKCFwb2ludGVycChlbnMpKQorICAgIHJldHVybjsKKyAgZW5zLT0oe01FfSk7CisKKyAgLy8gSW50ZXJhY3RpdmVzIHNvbGxlbiBrZWluZSBJbnRlcmFjdGl2ZXMgZHVyY2ggVGVhbSBhbmdyZWlmZW46CisgIGlmIChxdWVyeV9vbmNlX2ludGVyYWN0aXZlKE1FKSkgeworICAgIGZvciAoaT1zaXplb2YoZW5zKS0xO2k+PTA7aS0tKQorICAgICAgaWYgKG9iamVjdHAob2I9ZW5zW2ldKSAmJiBlbnZpcm9ubWVudChvYik9PWVudmlyb25tZW50KCkKKyAgICAgICAgICAmJiAhcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShvYikpCisgICAgICAgIEluc2VydFNpbmdsZUVuZW15KG9iKTsKKyAgfSBlbHNlIHsKKyAgICBmb3IgKGk9c2l6ZW9mKGVucyktMTtpPj0wO2ktLSkKKyAgICAgIGlmIChvYmplY3RwKG9iPWVuc1tpXSkgJiYgZW52aXJvbm1lbnQob2IpPT1lbnZpcm9ubWVudCgpKQorICAgICAgICBJbnNlcnRTaW5nbGVFbmVteShvYik7CisgIH0KKworICAvLyBBbGxlIGFuZGVyZW4gVGVhbW1pdGdsaWVkZXIgSW5mb3JtaWVyZW46CisgIGlmIChyZWsgfHwgIW9iamVjdHAodGVhbSkgfHwgIXBvaW50ZXJwKG9icz10ZWFtLT5NZW1iZXJzKCkpKQorICAgIHJldHVybjsKKyAgb2JzLT0oe01FfSk7CisgIG9icy09ZW5zOworICBmb3IgKGk9c2l6ZW9mKG9icyktMTtpPj0wO2ktLSkKKyAgICBpZiAob2JqZWN0cChvYj1vYnNbaV0pKQorICAgICAgb2ItPkluc2VydEVuZW15VGVhbShlbnMsMSk7Cit9CisKK2ludCBUZWFtRmxlZSgpIHsKKyAgb2JqZWN0IHRlYW07CisKKyAgaWYgKFF1ZXJ5KFBfVEVBTV9XSU1QWV9ST1cpPDIgfHwgIW9iamVjdHAodGVhbT1RdWVyeShQX1RFQU0pKSkKKyAgICByZXR1cm4gMDsKKyAgaWYgKCF0ZWFtLT5GbGVlVG9Sb3coTUUpKQorICAgICByZXR1cm4gMDsKKyAgaWYgKFF1ZXJ5KFBfVEVBTV9MRUFERVIpPT10ZWFtKSB7CisgICAgaWYgKHRlYW1fYXV0b2ZvbGxvdykKKyAgICAgIHRlbGxfb2JqZWN0KE1FLCJEdSB2ZXJzdWNoc3QgenUgZmxpZWhlbiwgIisKKyAgICAgICAgICAgICAgICAgICJEZWluIFRlYW0gZm9sZ3QgRGlyIG5pY2h0IG1laHIuXG4iKTsKKyAgICB0ZWFtX2F1dG9mb2xsb3c9MDsKKyAgfQorICByZXR1cm4gMTsKK30KKwordmFyYXJncyBtYXBwaW5nIFByZXNlbnRUZWFtUG9zaXRpb25zKG1peGVkIHByZXNfcm93cykgeworICBtYXBwaW5nIHJlczsKKyAgaW50IGksajsKKyAgb2JqZWN0ICpvYnMsb2I7CisKKyAgcmVzPShbXSk7CisgIGlmICghcG9pbnRlcnAocHJlc19yb3dzKSkKKyAgICBwcmVzX3Jvd3M9UHJlc2VudFRlYW1Sb3dzKCk7CisgIGZvciAoaT0wO2k8TUFYX1RFQU1ST1dTO2krKykgeworICAgIG9icz1wcmVzX3Jvd3NbaV07CisgICAgZm9yIChqPXNpemVvZihvYnMpLTE7aj49MDtqLS0pCisgICAgICBpZiAob2JqZWN0cChvYj1vYnNbal0pICYmICFyZXNbb2JdKQorICAgICAgICByZXNbb2JdPWkrMTsKKyAgfQorICByZXR1cm4gcmVzOworfQorCit2YXJhcmdzIGludCBQcmVzZW50UG9zaXRpb24obWl4ZWQgcG1hcCkgeworICBvYmplY3QgdGVhbTsKKyAgaW50IGk7CisKKyAgaWYgKCFvYmplY3RwKHRlYW09UXVlcnkoUF9URUFNKSkpCisgICAgcmV0dXJuIDE7CisgIGlmIChtYXBwaW5ncChwbWFwKSkKKyAgICByZXR1cm4gcG1hcFtNRV07CisgIGlmICghcG9pbnRlcnAocG1hcCkpCisgICAgcG1hcD10ZWFtLT5QcmVzZW50Um93cyhFTlYpOworICBmb3IgKGk9MTtpPE1BWF9URUFNUk9XUztpKyspCisgICAgaWYgKG1lbWJlcihwbWFwW2ldLE1FKT49MCkKKyAgICAgIHJldHVybiBpKzE7CisgIHJldHVybiAxOworfQorCisjZGVmaW5lIEZJTExTVFJJTkcgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiCit2YXJhcmdzIHByaXZhdGUgc3RyaW5nIGNlbnRlcl9zdHJpbmcoc3RyaW5nIHN0ciwgaW50IHcpIHsKKyAgcmV0dXJuIChGSUxMU1RSSU5HWzAuLigody1zaXplb2Yoc3RyKSkvMi0xKV0rc3RyK0ZJTExTVFJJTkcpWzAuLih3LTEpXTsKK30KKworcHJpdmF0ZSBpbnQgU2hvd1RlYW1Sb3dzKCkgeworICBpbnQgaSxqLHN6OworICBtaXhlZCAqcHJlc19yb3dzOworICBvYmplY3QgKm9icyxvYjsKKyAgc3RyaW5nIHN0cjsKKworICBwcmVzX3Jvd3M9UHJlc2VudEVuZW15Um93cygpOworICBmb3IgKHN6PU1BWF9URUFNUk9XUy0xO3N6Pj0wO3N6LS0pCisgICAgaWYgKHNpemVvZihwcmVzX3Jvd3Nbc3pdKSkKKyAgICAgIGJyZWFrOworICBmb3IgKGk9c3o7aT49MDtpLS0pIHsKKyAgICBvYnM9cHJlc19yb3dzW2ldO3N0cj0iIjsKKyAgICBmb3IgKGo9c2l6ZW9mKG9icyktMTtqPj0wO2otLSkKKyAgICAgIGlmIChvYmplY3RwKG9iPW9ic1tqXSkpIHsKKyAgICAgICAgaWYgKHN0ciE9IiIpIHN0cis9IiAvICI7CisgICAgICAgIHN0cis9b2ItPk5hbWUoUkFXKTsKKyAgICAgIH0KKyAgICBwcmludGYoIiVkLiAlc1xuIixpKzEsY2VudGVyX3N0cmluZyhzdHIsNzUpKTsKKyAgfQorICBpZiAoc3o+PTApCisgICAgd3JpdGUoIiAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuIik7CisgIHByZXNfcm93cz1QcmVzZW50VGVhbVJvd3MoKTsKKyAgZm9yIChzej1NQVhfVEVBTVJPV1MtMTtzej4wO3N6LS0pCisgICAgaWYgKHNpemVvZihwcmVzX3Jvd3Nbc3pdKSkKKyAgICAgIGJyZWFrOworICBmb3IgKGk9MDtpPD1zejtpKyspIHsKKyAgICBvYnM9cHJlc19yb3dzW2ldO3N0cj0iIjsKKyAgICBmb3IgKGo9c2l6ZW9mKG9icyktMTtqPj0wO2otLSkKKyAgICAgIGlmIChvYmplY3RwKG9iPW9ic1tqXSkpIHsKKyAgICAgICAgaWYgKHN0ciE9IiIpIHN0cis9IiAvICI7CisgICAgICAgIHN0cis9b2ItPk5hbWUoUkFXKTsKKyAgICAgIH0KKyAgICBwcmludGYoIiVkLiAlc1xuIixpKzEsY2VudGVyX3N0cmluZyhzdHIsNzUpKTsKKyAgfQorICByZXR1cm4gMTsKK30KKwordmFyYXJncyBpbnQgdGVhbV9saXN0KHN0cmluZyBhcmcpIHsKKyAgb2JqZWN0ICp0b2JzLCpvYnMsdG9iLG9iLGxkOworICBzdHJpbmcgKm5tcywqdG5tcyxzdHI7CisgIGludCBpLGo7CisKKyAgaWYgKCFwb2ludGVycCh0b2JzPVRFQU1fTUFTVEVSLT5MaXN0VGVhbU9iamVjdHMoKSkpIHJldHVybiAwOworICBpZiAoYXJnIT0iYWxsZSIpIGFyZz0wOworICB0bm1zPSh7fSk7CisgIGZvciAoaT1zaXplb2YodG9icyktMTtpPj0wO2ktLSkgeworICAgIGlmICghb2JqZWN0cCh0b2I9dG9ic1tpXSkKKyAgICAgICAgfHwgIW9iamVjdHAobGQ9dG9iLT5MZWFkZXIoKSkKKyAgICAgICAgfHwgKCFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKGxkKSAmJiAhYXJnKQorICAgICAgICB8fCAhcG9pbnRlcnAob2JzPXRvYi0+TWVtYmVycygpKSkKKyAgICAgIGNvbnRpbnVlOworICAgIG5tcz0oe30pOworICAgIGZvciAoaj1zaXplb2Yob2JzKS0xO2o+PTA7ai0tKSB7CisgICAgICBpZiAoIW9iamVjdHAob2I9b2JzW2pdKQorICAgICAgICAgIHx8ICghcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShvYikgJiYhYXJnKSkKKyAgICAgICAgY29udGludWU7CisgICAgICBpZiAoIXN0cmluZ3Aoc3RyPW9iLT5OYW1lKFdFUikpKSBzdHI9Ij8iOworICAgICAgaWYgKG9iPT1sZCkgc3RyKz0iKCopIjsKKyAgICAgIG5tcys9KHtzdHJ9KTsKKyAgICAgIG5tcz1zb3J0X2FycmF5KG5tcywjJz4pOworICAgIH0KKyAgICBpZiAoIXN0cmluZ3Aoc3RyPXRvYi0+TmFtZSgpKSkgc3RyPSJUZWFtID8iOworICAgIHN0cis9IjogIjsKKyAgICB0bm1zKz0oe2JyZWFrX3N0cmluZyhpbXBsb2RlKG5tcywiLCAiKSw3OCxzdHIpfSk7CisgICAgdG5tcz1zb3J0X2FycmF5KHRubXMsIyc8KTsKKyAgfQorICBpZiAoc2l6ZW9mKHRubXMpKQorICAgIHRlbGxfb2JqZWN0KE1FLCBzcHJpbnRmKCIlQHNcbiIsIHRubXMpKTsKKyAgZWxzZQorICAgIHRlbGxfb2JqZWN0KE1FLCAiS2VpbmUgVGVhbXMgZ2VmdW5kZW4uXG4iKTsgCisgIAorICByZXR1cm4gMTsKK30KKwordmFyYXJncyBpbnQgdGVhbWNtZChzdHJpbmcgYXJnKSB7CisgIHN0cmluZyAqd29yZHMsbmFyZzsKKyAgb2JqZWN0IHRlYW07CisKKyAgaWYgKCFhcmcpCisgICAgYXJnPSIiOworICBpZiAoIXN0cmluZ3AobmFyZz1UUC0+X3VucGFyc2VkX2FyZ3MoKSkpCisgICAgbmFyZyA9IGFyZzsKKyAgaWYgKCFzaXplb2Yod29yZHM9ZXhwbG9kZShhcmcsIiAiKSkpCisgICAgcmV0dXJuIDA7CisgCisgIGlmIChzaXplb2Yod29yZHMpID4gMSkgeworICAgICAgYXJnPWltcGxvZGUod29yZHNbMS4uXSwiICIpOworICAgICAgbmFyZyA9IGltcGxvZGUoZXhwbG9kZShuYXJnLCAiICIpWzEuLl0sICIgIik7CisgIH0KKyAgZWxzZQorICAgICAgYXJnID0gbmFyZyA9ICIiOworCisgIHN3aXRjaCh3b3Jkc1swXSkgeyAvLyBCZWZlaGxlIGRpZSBrZWluZSBNaXRnbGllZHNjaGFmdCBlcmZvcmRlcm46CisgIGNhc2UgImF1Zm5haG1lIjoKKyAgICByZXR1cm4gdGVhbV9hdWZuYWhtZShhcmcpOworICBjYXNlICJmb2xnZSI6CisgICAgcmV0dXJuIHRlYW1fYXVmbmFobWV3dW5zY2goYXJnKTsKKyAgY2FzZSAiPyI6CisgIGNhc2UgImhpbGZlIjoKKyAgICByZXR1cm4gdGVhbV9oZWxwKCk7CisgIGNhc2UgImxpc3RlIjoKKyAgICByZXR1cm4gdGVhbV9saXN0KGFyZyk7ICAKKyAgY2FzZSAidWViZXJzaWNodCI6CisgICAgcmV0dXJuIFNob3dUZWFtUm93cygpOworICBkZWZhdWx0OjsKKyAgfQorCisgIGlmICghb2JqZWN0cCh0ZWFtPVF1ZXJ5UHJvcChQX1RFQU0pKSkKKyAgICByZXR1cm4gbm90aWZ5X2ZhaWwoIkR1IGJpc3QgaW4ga2VpbmVtIFRlYW0uXG4iKSwwOworCisgIHN3aXRjaCh3b3Jkc1swXSkgeworICBjYXNlICJhbmdyaWZmc2JlZmVobCI6CisgICAgaWYgKG5hcmc9PSIiKSBuYXJnPTA7CisgICAgdGVhbV9hdHRhY2tfY21kPW5hcmc7CisgICAgaWYgKHN0cmluZ3AobmFyZykpCisgICAgICB3cml0ZSgiRHUgYmVnaW5uc3QgZGVuIEthbXBmIG1pdCBcIiIrbmFyZysiXCJcbiIpOworICAgIGVsc2UKKyAgICAgIHdyaXRlKCJEdSBoYXN0IGRlbiBUZWFtYW5ncmlmZnNiZWZlaGwgZGVha3RpdmllcnQuXG4iKTsKKyAgICBicmVhazsgLy8gTklDSFQgcmV0dXJuIQorICBjYXNlICJhdXRvZm9sZ2UiOgorICBjYXNlICJhdXRvZiI6CisgICAgaWYgKGFyZz09ImVpbiIgfHwgYXJnPT0iYW4iKSB7CisgICAgICB0ZWFtX2F1dG9mb2xsb3c9MTsKKyAgICAgIGlmIChJc1RlYW1MZWFkZXIoKSkKKyAgICAgICAgd3JpdGUoIkRlaW4gVGVhbSBmb2xndCBEaXIuXG4iKTsKKyAgICAgIGVsc2UKKyAgICAgICAgd3JpdGUoIkR1IGZvbGdzdCBqZXR6dCBkZW0gVGVhbWxlaXRlci5cbiIpOworICAgIH0gZWxzZSB7CisgICAgICB0ZWFtX2F1dG9mb2xsb3c9MDsKKyAgICAgIGlmIChJc1RlYW1MZWFkZXIoKSkKKyAgICAgICAgd3JpdGUoIkRlaW4gVGVhbSBmb2xndCBEaXIgbmljaHQgbWVoci5cbiIpOworICAgICAgZWxzZQorICAgICAgICB3cml0ZSgiRHUgZm9sZ3N0IGpldHp0IG5pY2h0IG1laHIgZGVtIFRlYW1sZWl0ZXIuXG4iKTsKKyAgICB9CisgICAgYnJlYWs7IC8vIE5JQ0hUIHJldHVybiEKKyAgZGVmYXVsdDogOworICB9CisgIHJldHVybiB0ZWFtLT5UZWFtQ21kKHdvcmRzWzBdLG5hcmcpOyAvLyBCZWZlaGxlIGRpZSBNaXRnbGllZHNjaGFmdCBlcmZvcmRlcm46Cit9CisKK3ZhcmFyZ3Mgdm9pZCBJbmZvcm1Sb3dDaGFuZ2UoaW50IGZyb20sIGludCB0bywgb2JqZWN0IGNhc3RlcikgeworCisgIGlmIChjYXN0ZXIpIHJldHVybjsgLy8gRnVlciBkZW4gRmFsbCwgZGFzcyBHaWxkZW5vYmpla3Q9PU1FIGlzdAorICBpZiAoUE8hPVF1ZXJ5KFBfVEVBTSkpIHJldHVybjsKKyNpZiBfX0JPT1RfVElNRV9fIDwgMTI4MTkwNDQzNworICBtaXhlZCBnaWxkZSA9IFF1ZXJ5UHJvcChQX0dVSUxEKTsKKyAgaWYgKCFzdHJpbmdwKGdpbGRlKSkgcmV0dXJuOworICBpZiAoIW9iamVjdHAoZ2lsZGU9ZmluZF9vYmplY3QoIi9naWxkZW4vIitnaWxkZSkpKSByZXR1cm47CisgIGdpbGRlLT5JbmZvcm1Sb3dDaGFuZ2UoZnJvbSx0byxNRSk7CisjZW5kaWYKKyAgSG9va0Zsb3coSF9IT09LX1RFQU1ST1dDSEFOR0UsICh7ZnJvbSx0b30pICk7Cit9Cg==