ZGlmZiAtLWdpdCBhL3N0ZC9zaGVsbHMvbWFnaWVyL3VwZC5jIGIvc3RkL3NoZWxscy9tYWdpZXIvdXBkLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjA5ZWE5YQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9zaGVsbHMvbWFnaWVyL3VwZC5jCkBAIC0wLDAgKzEsNTYzIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gdXBkLmMKKy8vCisvLyAkSWQ6IHVwZC5jIDg4NTAgMjAxNC0wNi0xMyAyMTozNDo0NFogWmVzc3RyYSAkCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8bWFnaWVyLmg+CisjaW5jbHVkZSA8cGxheWVyLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8ZGVidWdfaW5mby5oPgorI2luY2x1ZGUgPHdpemxldmVscy5oPgorI2luY2x1ZGUgPG1vdmluZy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxsb2dnaW5nLmg+CisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorCit2YXJhcmdzIHN0YXRpYyBpbnQgX21ha2Uoc3RyaW5nIGZpbGUsIGludCBmbGFncywgaW50IHJlY3Vyc2l2ZSk7CisKK3N0YXRpYyBtaXhlZCBfcXVlcnlfbG9jYWxjbWRzKCkKK3sKKyAgcmV0dXJuICh7KHsidXBkIiwiX3VwZCIsMCxMRUFSTkVSX0xWTH0pLAorICAgICAgICAgICAoeyJsb2FkIiwiX2xvYWQiLDAsTEVBUk5FUl9MVkx9KX0pOworfQorCisvLworLy8gX3NhdmUoKTogU3BpZWxlciBpbiBSZXR0dW5nc3JhdW0gcmV0dGVuCisvLyBvYmo6ICAgICAgU3BpZWxlcm9iamVrdCg/KQorLy8gaW52X3NhdmU6IFJldHR1bmdzcmF1bW5hbWUgCisvLyBSdWVja2dhYmU6IDAgd2VubiBrZWluIFNwaWVsZXJvYmpla3QKKy8vICAgICAgICAgICAgU3BpZWxlcm9iamVrdCwgZmFsbHMgZG9jaAorLy8KKworc3RhdGljIG1peGVkIF9zYXZlKCBvYmplY3Qgb2JqLCBvYmplY3QgaW52X3NhdmVyICkKK3sgCisgICAgaWYgKCBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKG9iaikgKQorICAgICAgeyAKKyAgICAgICAgb2JqLT5tb3ZlKCBpbnZfc2F2ZXIsIE5PX0NIRUNLICk7CisgICAgICAgIHJldHVybiBvYmo7CisgICAgICB9CisgICAgcmV0dXJuIDA7Cit9CisKKworLy8KKy8vIF9yZWxvYWQoKTogT2JqZWt0IGxhZGVuCisvLyBmaWxlOiAgRmlsZW5hbWUuIE11c3MgaW4gZGVyIEZvcm0gL3h4L3h4L3h4LmMgdm9ybGllZ2VuCisvLyBjbG9uZTogID4gMCAtPiBFcyBzb2xsIGdlY2xvbnQgd2VyZGVuLCBlbnRoYWVsdCBPYmpla3RudW1tZXIgZGVzCisvLyAgICAgICAgICAgICAgICBWb3JnYWVuZ2Vyb2JqZWt0ZXMKKy8vIGZsYWdzOiBLb21tYW5kb3plaWxlbm9wdGlvbmVuCisvLyBlcnI6ICAgTGVlcnN0cmluZyBhbHMgUmVmZXJlbnogdWViZXJnZWJlbi4gRW50aGFlbHQgbmFjaCBkZW0KKy8vICAgICAgICBBdWZydWYgdm9tIF9yZWxvYWQoKSBkaWUgRmVobGVybWVsZHVuZ2VuIGFscyBTdHJpbmcuCisvLyBSdWVja2dhYmU6IERhcyBuZXUgZXJ6ZXVndGUgT2JqZWt0IGJ6dy4gZGFzIHNjaG9uIHZvcmhhbmRlbmUgT2JqZWt0CisvLyAgICAgICAgICAgIGJ6dy4gMCwgd2VubiBGZWhsZXIgYXVmdHJhdC4KKy8vCisKK3ByaXZhdGUgb2JqZWN0IF9yZWxvYWQoc3RyaW5nIGZpbGUsIGludCBjbG9uZSwgaW50IGZsYWdzLCBzdHJpbmcgZXJyKQoreworICBvYmplY3Qgb2JqOworICAKKyAgaWYgKCFvYmo9ZmluZF9vYmplY3QoZmlsZVswLi48M10rKGNsb25lPygiIyIrY2xvbmUpOiIiKSkpCisgIHsKKyAgICBpbnQgcG9zLHBvczI7CisgICAgc3RyaW5nIGJ0OworCisgICAgaWYoZmlsZV9zaXplKGZpbGUpPDApCisgICAgeworICAgICAgaWYgKGZpbGVfc2l6ZShmaWxlKT09LTEpCisgICAgICAgIGVyciA9IHNwcmludGYoInVwZDogJXM6IERhdGVpIGV4aXN0aWVydCBuaWNodC5cbiIsIGZpbGUpOworICAgICAgZWxzZSAvLyBkaXJlY3RvcnkKKyAgICAgICAgZXJyID0gc3ByaW50ZigidXBkOiAlczogVmVyemVpY2huaXNzZSBrb2VubmVuIG5pY2h0IGdlbGFkZW4gIgorICAgICAgICAgICAgICAgICAgICAgICJ3ZXJkZW4uXG4iLGZpbGUpOworICAgICAgcmV0dXJuIG9iajsgLy8gMAorICAgIH0KKyAgICBwb3MgPSBtYXgoZmlsZV9zaXplKF9fREVCVUdfTE9HX18pLDApOworCisgICAgaWYgKChlcnIgPSAoY2xvbmU/Y2F0Y2gob2JqID0gY2xvbmVfb2JqZWN0KGZpbGUpKToKKyAgICAgICAgICAgICAgICBjYXRjaChsb2FkX29iamVjdChmaWxlKSkgKSkgJiYgKGZsYWdzICYgVVBEX0IpKSAgICAgICAgCisgICAgeyAgICAgCisgICAgICBpZiAoKCBwb3MyPWZpbGVfc2l6ZShfX0RFQlVHX0xPR19fKSkgPiBwb3MgKQorICAgICAgICBlcnIrPXNwcmludGYoIlxuQmFja3RyYWNlOlxuJXMiLAorICAgICAgICAgICAgICAgICAgICAgcmVhZF9ieXRlcyhfX0RFQlVHX0xPR19fLHBvcywgcG9zMi1wb3MgKSk7CisgICAgICBlbHNlCisgICAgICAgIGVycis9c3ByaW50ZigiXG5LRUlOIEJBQ0tUUkFDRSBWRVJGVUVHQkFSIVxuIik7CisgICAgfQorICAgIGlmICghZXJyJiYhb2JqJiYoIW9iaiA9IGZpbmRfb2JqZWN0KGZpbGVbMC4uPDNdKSkpCisgICAgICBlcnIgKz0gc3ByaW50ZiggInVwZDogJXM6IEJsdWVwcmludCBuYWNoIGRlbSBMYWRlbiB6ZXJzdG9lcnQuXG4iLGZpbGUgKTsKKyAgfQorICBlbHNlCisgICAgZXJyPXNwcmludGYoInVwZDogT2JqZWt0IGV4aXN0aWVydCBzY2hvbjogJU9cbiIsb2JqKTsKKyAgcmV0dXJuIG9iajsKK30KKworCisvLworLy8gX3VwZGF0ZSgpOiBGaWxlIHVwZGF0ZW4gLT4gQmx1ZXByaW50IGRlc3RydWN0ZW4KKy8vIGZpbGU6ICBGaWxlbmFtZQorLy8gZHVtbXk6IHNpbXVsaWVyZW4/ICgxLT53aXJkIG5pY2h0IGFrdHVhbGlzaWVydCkKKy8vIGZsYWdzOiBLb21tYW5kb3plaWxlbm9wdGlvbmVuCisvLyBSdWVja2dhYmU6IC0xOiBLZWluZSBWb2xsenVncmlmZgorLy8gICAgICAgICAgICAgMDogT2JqZWt0IGlzdCBuaWNodCBnZWxhZGVuCisvLyAgICAgICAgICAgICAxOiBPcGVyYXRpb24gd2lyZCBkdXJjaGdlZnVlaHJ0CisvLworCitwcml2YXRlIHZhcmFyZ3MgaW50IF91cGRhdGUoc3RyaW5nIGZpbGUsIGludCBkdW1teSwgaW50IGZsYWdzKQoreworICBvYmplY3Qgb2JqOworICBzdHJpbmcgZXJyOworICBpZiAoIWR1bW15ICYmICFvYmplY3RwKG9iaiA9IGZpbmRfb2JqZWN0KGZpbGUpKSkgcmV0dXJuIDA7CisgIGlmICghSVNfQVJDSCh0aGlzX29iamVjdCgpKSkKKyAgeworICAgIC8vIFNjaHJlaWJyZWNodGUgbnVyIHBydWVmZW4sIHdlbm4gZWNodCBha3R1YWxpc2llcnQgd2VyZGVuIHNvbGwuCisgICAgaWYoIWR1bW15ICYmICFNQVlfV1JJVEUoZmlsZSkpCisgICAgICByZXR1cm4gKHByaW50ZigidXBkOqAlczogS2VpbmUgU2NocmVpYnJlY2h0ZSFcbiIsZmlsZSksIC0xKTsKKyAgICBpZighTUFZX1JFQUQoZmlsZSkpIAorICAgICAgcmV0dXJuIChwcmludGYoInVwZDogJXM6IEtlaW5lIExlc2VyZWNodGUhXG4iLCBmaWxlKSwgLTEpOworICB9CisgIGlmIChkdW1teSkgcmV0dXJuIDE7CisgIAorICBpZiAoIGZsYWdzICYgVVBEX0QgKQorICB7CisgICAgb2JqZWN0ICppbnY7CisgICAgaWYgKHNpemVvZihpbnYgPSBkZWVwX2ludmVudG9yeShvYmopKSkKKyAgICB7CisgICAgICBwcmludGYoInVwZDogJXM6IEVudGZlcm5lIE9iamVrdGUgaW0gSW52ZW50YXJcbiIsIGZpbGUgKTsKKyAgICAgIGlmICghKGZsYWdzJlVQRF9IKSkKKyAgICAgIHsKKyAgICAgICAgaWYoZXJyPWNhdGNoKGZpbHRlcl9vYmplY3RzKCBpbnYsICJyZW1vdmUiLCAxICkpKQorICAgICAgICAgIHByaW50ZigidXBkOiAlczogRmVobGdlc2NobGFnZW4uIEdydW5kOlxuJXNcbiIsCisgICAgICAgICAgICAgICAgIGZpbGUsZXJyKTsKKyAgICAgIH0KKyAgICAgIGlmIChzaXplb2YoaW52ID0gZGVlcF9pbnZlbnRvcnkob2JqKSkpCisgICAgICAgIGZpbHRlcihpbnYsIGZ1bmN0aW9uIHZvaWQgKG9iamVjdCBvYikKKyAgICAgICAgICAgIHtkZXN0cnVjdChvYik7fSk7CisgICAgfQorICB9CisgIGlmICghKGZsYWdzJlVQRF9IKSkKKyAgeworICAgIGlmKGVyciA9IGNhdGNoKG9iai0+cmVtb3ZlKCkpKQorICAgICAgcHJpbnRmKCJ1cGQ6ICVzOiByZW1vdmUoKSBmZWhsZ2VzY2hsYWdlbi4gQXVmcnVmIHZvbiAiICsKKyAgICAgICAgICAgICAiZGVzdHJ1Y3QoKS5cbiIsZmlsZSk7CisgIH0KKyAgaWYob2JqZWN0cChvYmopKSBkZXN0cnVjdChvYmopOworICByZXR1cm4gMTsKK30KKworCisvLworLy8gX2luc3RhbmNlX3VwZCgpOiBBbGxlIE9iamVrdGUgbmFjaCBDbG9uZXMgZGVzIE9iamVrdHMgZHVyY2hzdWNoZW4KKy8vIGZpbGU6ICBGaWxlbmFtZSBkZXMgT2JqZWt0ZXMKKy8vIGZsYWdzOiBLb21tYW5kb3plaWxlbmFyZ3VtZW50ZQorLy8gb2JqOiAgIEFrdHVlbGxlcyBPYmpla3QKKy8vIGluc3RhbmNlczogWmFobCBkZXIgZ2VmdW5kZW5lbiBJbnN0YW56ZW4KKy8vCisKK3ByaXZhdGUgdm9pZCBfaW5zdGFuY2VfdXBkKHN0cmluZyBmaWxlLCBpbnQgZmxhZ3MsIG1peGVkIG9iaiwgaW50IGluc3RhbmNlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmaXJzdGNhbGwpCit7CisgaW50IGk7CisgaWYgKGZpcnN0Y2FsbCkKKyAgICBwcmludGYoInVwZDogJXM6ICVzIEluc3Rhbnplbi5cbiIsZmlsZSxmbGFncyZVUERfQT8iQWt0dWFsaXNpZXJlIjoiU3VjaGUiKTsKKyAgCisgIHdoaWxlIChnZXRfZXZhbF9jb3N0KCk+MjIwMDAwICYmIGkgPCBzaXplb2Yob2JqKSkKKyAgeworICAgIGlmICghb2JqZWN0cChvYmpbaV0pKQorICAgICAgaW5zdGFuY2VzLS07CisgICAgZWxzZQorICAgIHsKKyAgICAgIGlmIChmbGFncyZVUERfRiYmIShmbGFncyZVUERfUykpCisgICAgICAgIHByaW50ZiggInVwZDogJU8gZ2VmdW5kZW4gaW4gJXNcbiIsIG9ialtpXSwKKyAgICAgICAgICAgICAgICBlbnZpcm9ubWVudChvYmpbaV0pP29iamVjdF9uYW1lKGVudmlyb25tZW50KG9ialtpXSkpIAorICAgICAgICAgICAgICAgIDogImtlaW5lciBVbWdlYnVuZyIgKTsKKyAgICAgIGlmIChmbGFncyZVUERfQSkgX21ha2Uob2JqZWN0X25hbWUob2JqW2ldKSwgZmxhZ3MgJiB+KFVQRF9BfFVQRF9GKSwxICk7CisgICAgfQorICAgIGkrKzsKKyAgfQorICBpZiAoaSA8IHNpemVvZihvYmopKSAKKyAgICBjYWxsX291dCggIydfaW5zdGFuY2VfdXBkLyonKi8sMixmaWxlLGZsYWdzLG9ialtpLi5dLGluc3RhbmNlcywwKTsKKyAgZWxzZQorICAgIHByaW50ZiggInVwZDogJXM6ICVkIEluc3RhbnplbiAlc1xuIiwgZmlsZSwgaW5zdGFuY2VzLAorICAgICAgICAgICAgKGZsYWdzICYgVVBEX0EpID8gImFrdHVhbGlzaWVydCIgOiAiZ2VmdW5kZW4iICk7CisgIHJldHVybjsKK30KKyAgCisgIAorLy8KKy8vIF9kb19tYWtlKCk6IEFsbGUgZ2VlcmJ0ZW4gT2JqZWt0ZSBiZWFyYmVpdGVuIChmdWVyIC1tLy12KQorLy8gZmlsZTogIE5hbWUgZGVzIEZpbGVzCisvLyBjbG9uZTogMCwgd2VubiBibHVlcHJpbnQsIGFuc29uc3RlbiBDbG9uZW51bW1lcgorLy8gZmxhZ3M6IEtvbW1hbmRvemVpbGVucGFyYW1ldGVyCisvLyBkZXA6ICAgZ2VzY2hhY2h0ZWx0ZXMgQXJyYXkgbWl0IE1lbGR1bmdlbiAod2cuIFJla3Vyc2lvbikKKy8vIHJlYWR5OiBBcnJheSBkZXIgc2Nob24gYmVhcmJlaXRldGVuIE9iamVrdGUgKHdnLiBSZWt1cnNpb24pCisvLyBSdWVja2dhYmU6IEFycmF5IGRlciBPYmpla3RuYW1lbiwgZGllIGJlYXJiZWl0ZXQgd3VyZGVuCisvLyAgICAgICAgICAgIChBcnJheSBpbiBBcnJheSBpbiAuLi4pCisvLyAKKwordmFyYXJncyBwcml2YXRlIGludCBfZG9fbWFrZSggc3RyaW5nIGZpbGUsaW50IGNsb25lLGludCBmbGFncyxtaXhlZCBkZXAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgKnJlYWR5ICkKK3sKKyAgb2JqZWN0IG9iajsKKyAgc3RyaW5nIGVycjsKKyAgc3RyaW5nICppbGlzdDsKKyAgbWl4ZWQgZG93bmRlcHM7CisgIGludCByZXQ7CisgIAorICBpZiAoIXBvaW50ZXJwKHJlYWR5KSkgcmVhZHkgPSAoe30pOworICByZWFkeSArPSAoeyBmaWxlIH0pOworICAKKyAgaWYgKCAhKG9iaiA9IF9yZWxvYWQoZmlsZSxjbG9uZSxmbGFncywmZXJyKSkpCisgIHsKKyAgICBkZXAgKz0gKHsgZXJyIH0pOworICAgIHJldHVybiAwOworICB9CisgIAorICBpbGlzdCA9IGluaGVyaXRfbGlzdChvYmopLXJlYWR5OworICAKKyAgZG93bmRlcHMgPSAoe30pOworICAKKyAgd2hpbGUgKHNpemVvZihpbGlzdCkpCisgIHsKKyAgICByZXQgPSBfZG9fbWFrZSggaWxpc3RbMF0sMCxmbGFncywgJmRvd25kZXBzLCAmcmVhZHkgKXx8cmV0OworICAgIGlsaXN0WzAuLjBdID0gKHt9KTsKKyAgICBpbGlzdCAtPSByZWFkeTsKKyAgfQorICAKKyAgaWYgKCByZXR8fGZpbGVfdGltZShmaWxlKT5wcm9ncmFtX3RpbWUob2JqKXx8KGZsYWdzICZVUERfSSkpCisgICAgaWYgKCBfbWFrZSggZmlsZSwgZmxhZ3MgJiB+KFVQRF9NfFVQRF9JKSAsMSkgPCAwICkgCisgICAgICBkZXAgPSAoeyAieyIgKyBleHBsb2RlKGZpbGUsIi8iKVs8MV0gKyAifSIsIGRvd25kZXBzIH0pOworICAgIGVsc2V7CisgICAgICBkZXAgPSAoeyAiWyIgKyBleHBsb2RlKGZpbGUsIi8iKVs8MV0gKyAiXSIsIGRvd25kZXBzIH0pOworICAgICAgcmV0ID0gMTsKKyAgICB9CisgIGVsc2UgaWYgKGZsYWdzJlVQRF9WKSBkZXAgKz0gKHsgZXhwbG9kZShmaWxlLCIvIilbPDFdLCBkb3duZGVwcyB9KTsKKyAgcmV0dXJuIHJldDsKK30KKworCisvLworLy8gX21ha2VfZGVwKCk6IEF1c2dhYmUgZGVzIEVyZXJidW5nc2JhdW1lcworLy8gT2JqZWt0ZSBpbSBBcnJheSBkZXAKKy8vIHByZWZpeCBlbnRoYWVsdCBaZWlsZW5hbmZhbmcgKGZ1ZXIgUmVrdXJzaW9uKQorLy8gUnVlY2tnYWJlOiBTdHJpbmcgbWl0IGRlbSBWZXJlcmJ1bmdzYmF1bSBkZXMgT2JqZWt0ZXMKKy8vCisKK3ByaXZhdGUgc3RyaW5nIF9tYWtlX2RlcCggbWl4ZWQgZGVwLCBzdHJpbmcgcHJlZml4ICkKK3sKKyAgc3RyaW5nIHJldDsKKyAgaW50IGksIHNpemU7CisgIAorICByZXQ9IiI7CisgIHNpemU9c2l6ZW9mKGRlcCk7CisgIGZvciAoaT0wOyBpPHNpemU7aSsrKQorICAgIGlmIChwb2ludGVycChkZXBbaV0pKQorICAgICAgcmV0ICs9IF9tYWtlX2RlcChkZXBbaV0scHJlZml4ICsgKGkgPCAoc2l6ZS0xKSA/ICJ8ICI6IiAiKSk7CisgICAgZWxzZSAKKyAgICAgIHJldCArPSBwcmVmaXggKyAiKy0iICsgZGVwW2ldICsgIlxuIjsKKyAgcmV0dXJuIHJldDsKK30KKworCisvLworLy8gX2lsbGVnYWxfY2xvc3VyZSgpOiBpc3QgY2xvc3VyZSBpbiBhcmcgYW4gb2JqZWt0IGdlYnVuZGVuPworLy8gYXJnOiBjbG9zdXJlKC1hcnJheS9tYXBwaW5nKQorLy8gUnVlY2tnYWJlOiAwIHdlbm4gYWxsZXMgb2theQorLy8gICAgICAgICAgICAxIHdlbm4gY2xvc3VyZSBnZWxvZXNjaHQgd2VyZGVuIG11c3MKKy8vCisKK3ByaXZhdGUgaW50IF9pbGxlZ2FsX2Nsb3N1cmUoIG1peGVkIGFyZyApCit7CisgIGludCBpLCBqOworICBzdHJpbmcgKmluZGljZXM7CisgIAorICBpZiAoIGNsb3N1cmVwKGFyZykgJiYgIW9iamVjdHAocXVlcnlfY2xvc3VyZV9vYmplY3QoYXJnKSkgKQorICAgIHJldHVybiAxOworICAKKyAgaWYgKCBwb2ludGVycChhcmcpICl7CisgICAgZm9yICggaSA9IHNpemVvZihhcmcpOyBpLS07ICkKKyAgICAgIGlmICggX2lsbGVnYWxfY2xvc3VyZShhcmdbaV0pICkKKyAgICAgICAgcmV0dXJuIDE7CisgIH0KKyAgZWxzZSBpZiAoIG1hcHBpbmdwKGFyZykgKXsKKyAgICBpbmRpY2VzID0gbV9pbmRpY2VzKGFyZyk7CisgICAgZm9yICggaSA9IHNpemVvZihpbmRpY2VzKTsgaS0tOyApCisgICAgICBmb3IgKCBqID0gZ2V0X3R5cGVfaW5mbyggYXJnLCAxICk7IGotLTsgKQorICAgICAgICBpZiAoIF9pbGxlZ2FsX2Nsb3N1cmUoYXJnW2luZGljZXNbaV0sIGpdKSApCisgICAgICAgICAgcmV0dXJuIDE7CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKKy8vCisvLyBfbWFrZSgpOiBVcGRhdGUgZmlsZQorLy8gZmlsZTogIEZpbGVuYW1lCisvLyBmbGFnczogS29tbWFuZG96ZWlsZW5hcmd1bWVudGUKKy8vCisKK3ZhcmFyZ3Mgc3RhdGljIGludCBfbWFrZShzdHJpbmcgZmlsZSwgaW50IGZsYWdzLGludCByZWN1cnNpdmUpCit7CisgIHN0cmluZyBtc2csIGVyciwgYmx1ZTsKKyAgaW50IGluc3Q7CisgIG9iamVjdCBvYmosIGludl9zYXZlcjsKKyAgbWl4ZWQgdG1wOworICAKKyAgbXNnID0gIiI7CisKKyAgaWYgKCFmaWxlKSByZXR1cm4gcHJpbnRmKCAidXBkOiBLZWluIEZpbGVuYW1lIHVlYmVyZ2ViZW4hXG4iICksIFJFVF9GQUlMOworICAgIAorLy8gRmlsZW5hbWUgaW4gQmx1ZSwgT2JqZWt0bmFtZSBpbiBibHVlLCBJbnN0YW56bnVtbWVyIGluIGluc3QKKworICBpZiAoc3NjYW5mKGZpbGUsIiVzIyVkIixibHVlLGluc3QpPT0yKSBibHVlICs9ICIuYyI7CisgIGVsc2UgYmx1ZSA9IGZpbGUgKyAoZmlsZVs8Mi4uXT09Ii5jIiA/ICIiIDogIi5jIik7CisKKy8vIEFsbGUgSW5zdGFuemVuIGR1cmNoc3VjaGVuIGltIEZhbGxlIHZvbiAtYSBvZGVyIC1mIAorCisgIGlmICgoZmxhZ3MgJiBVUERfTE9BRCkmJmZpbmRfb2JqZWN0KGZpbGUpKQorICAgIHJldHVybiBwcmludGYoImxvYWQ6ICVzOiBPYmpla3QgaXN0IHNjaG9uIGdlbGFkZW4uXG4iLGZpbGUpLFJFVF9PSzsKKyAgCisgIGlmICggZmxhZ3MgJiAoVVBEX0Z8VVBEX0EpKQorICB7CisgICAgaWYgKGluc3QpIHJldHVybiBwcmludGYoICJ1cGQ6ICVzOiBFaW5lIEluc3Rhbnoga2FubiBrZWluZSAiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNsb25lcyBoYWJlbi5cbiIsZmlsZSApLCBSRVRfRkFJTDsKKyAgICBpZiAoKHRtcD1fdXBkYXRlKGZpbGUsIDEsZmxhZ3MpKT09LTEpIAorICAgICAgcmV0dXJuIHByaW50ZiggInVwZDogJXM6IEtlaW4gVm9sbHp1Z3JpZmYgYXVmIGRpZSAiICsKKyAgICAgICAgICAgICAgICAgICAgICJEYXRlaSBlcmxhdWJ0LlxuIixmaWxlKSwgUkVUX0ZBSUw7CisgICAgaWYgKHRtcD09MCkgcmV0dXJuIFJFVF9GQUlMOworCisgICB0bXA9Y2xvbmVzKGJsdWVbMC4uPDNdLDIpOworICAgIGlmIChzaXplb2YodG1wKSkKKyAgICAgIGNhbGxfb3V0KCAjJ19pbnN0YW5jZV91cGQvKicqLywgMCwgZmlsZSxmbGFncyx0bXAsc2l6ZW9mKHRtcCksMSk7CisgICAgZWxzZQorICAgICAgcHJpbnRmKCAidXBkOiAlczogS2VpbmUgQ2xvbmVzIHZvcmhhbmRlbiFcbiIsIGJsdWVbMC4uPDNdKTsKKworICAgIGlmICggKGZsYWdzICYgVVBEX0YpICYmICEoZmxhZ3MgJihVUERfUnxVUERfTHxVUERfTE9BRCkpKSByZXR1cm4gUkVUX09LOyAKKyAgICAvLyBOaWNodHMgbGFkZW4gLT4gQXVjaCBrZWluIEJhY2t1cAorICB9CisKKy8vIEJhY2t1cHJhdW0gZmVzdGxlZ2VuCisgICAKKyAgaWYoIGJsdWU9PUlOVl9TQVZFICkgeworICAgICAgICAgICAgICAgIHByaW50ZigidXBkOiBBY2h0dW5nOiBSYXVtIHp1bSBad2lzY2hlbnNwZWljaGVybiBzb2xsIGdlbGFkZW4gd2VyZGVuPyFcbiIpOworICAgICAgICB9IAorICBpZiAoICEoaW52X3NhdmVyPWxvYWRfb2JqZWN0KElOVl9TQVZFKSkgKQorICB7CisgICAgcHJpbnRmKCJ1cGQ6ICVzOiBSYXVtIHp1bSBad2lzY2hlbnNwZWljaGVybiBkZXMgIiArCisgICAgICAgICAgICJSYXVtaW5oYWx0cyBpc3QgbmljaHQgbGFkYmFyLlxuIiArCisgICAgICAgICAgICIgICAgICAgICAlc1xuIixmaWxlLElOVl9TQVZFKTsKKyAgICByZXR1cm4gUkVUX0ZBSUw7CisgIH0KKworLy8gV2VubiBkYXMgT2JqZWt0IGV4aXN0aWVydCBiencuIERlZXAgYWt0dWFsaXNpZXJ0IHdlcmRlbiBzb2xsCisKKyAgaWYgKCAoIShmbGFncyZVUERfTE9BRCkpJiYKKyAgICAgICAoKG9iaiA9IGZpbmRfb2JqZWN0KGZpbGUpKSB8fCAoZmxhZ3MgJiAoVVBEX018VVBEX0kpKSkpCisgIHsKKyAgICBvYmplY3QgKmludiwgZW52LCAqcGxfaW52OworICAgIG1hcHBpbmcgcHJvOworICAgIGludCBpOworICAgIG1peGVkIGNvbmZpZ2RhdGE7CisgICAgaW50IHJlc3RvcmVfY29uZmlnOworCisgICAgLy8gV2VubiBPYmpla3QgZXhpc3RpZXJ0LCBkYW5uIEluaGFsdCB1bmQgZ2dmLiBEYXRlbiBhdXMgQ29uZmlndXJlKCkgb2RlcgorICAgIC8vIFByb3BzIHNpY2hlcm46CisgICAgaWYgKG9iaikKKyAgICB7CisgICAgICAvLyBpbSBGYWxsIFVQRF9DIGVyZm9sZ3QgX2tlaW5fIEF1c2xlc2VuIHVuZCBfa2VpbmVfIFJlc3RhdXJhdGlvbgorICAgICAgLy8gbWl0dGVscyBDb25maWd1cmUoKQorICAgICAgaWYgKCAhIChmbGFncyAmIFVQRF9DICkgKQorICAgICAgeworICAgICAgICBjYXRjaChyZXN0b3JlX2NvbmZpZz0obWl4ZWQpY2FsbF9yZXNvbHZlZCgmY29uZmlnZGF0YSxvYmosCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDb25maWd1cmUiLDApOworICAgICAgICAgICAgICBwdWJsaXNoKTsKKyAgICAgICAgLy8gV2VubiBVUERfQ09ORiBnZXNldHp0IHdpcmQsIF9tdXNzXyBkYXMgT2JqZWt0IGVpbiBvZWZmZW50bGljaGVzCisgICAgICAgIC8vIENvbmZpZ3VyZSgpIGRlZmluaWVyZW4sIHNvbnN0IGVyZm9sZ3QgQWJicnVjaC4KKyAgICAgICAgaWYgKChmbGFncyAmIFVQRF9DT05GKSAmJiAhcmVzdG9yZV9jb25maWcpCisgICAgICAgIHsKKyAgICAgICAgICBwcmludGYoInVwZDogJXM6IGhhdCBrZWluIENvbmZpZ3VyZSgpLCBaZXJzdG9lcnVuZyBhYmdlYnJvY2hlbi5cbiIsZmlsZSk7CisgICAgICAgICAgcmV0dXJuIFJFVF9GQUlMOworICAgICAgICB9CisgICAgICB9CisgICAgICBpZiAoIShmbGFncyZVUERfRCkmJihmbGFncyYoVVBEX0x8VVBEX1IpKSkKKyAgICAgIHsKKyAgICAgICAgaWYgKGk9c2l6ZW9mKGludj0oYWxsX2ludmVudG9yeShvYmopLSh7MH0pKSkpCisgICAgICAgIHsKKyAgICAgICAgICBtaXhlZCBpdGVtczsKKyAgICAgICAgICAvLyBIZXJhdXNiZWtvbW1lbiwgb2IgaGllciBJdGVtcyBleGlzdGllcmVuLCBkaWUgcGVyIEFkZEl0ZW0gCisgICAgICAgICAgLy8gZXJ6ZXVndCB3ZXJkZW4uIERpZSBkdWVyZmVuIG5pY2h0IGdlc2ljaGVydCB3ZXJkZW4uCisgICAgICAgICAgaXRlbXM9KG1peGVkKW9iai0+UXVlcnlQcm9wKFBfSVRFTVMpOyAvLyBtaXhlZCwgZGEgYXJyYXkgb2YgYXJyYXlzCisgICAgICAgICAgaWYgKHBvaW50ZXJwKGl0ZW1zKSYmc2l6ZW9mKGl0ZW1zKSkKKyAgICAgICAgICB7CisgICAgICAgICAgICBpdGVtcz10cmFuc3Bvc2VfYXJyYXkoaXRlbXMpWzBdOworICAgICAgICAgICAgd2hpbGUgKGktLSkKKyAgICAgICAgICAgICAgaWYgKG1lbWJlcihpdGVtcywgaW52W2ldKT09LTEpCisgICAgICAgICAgICAgICAgICAgIGludltpXS0+bW92ZShpbnZfc2F2ZXIsTk9fQ0hFQ0spOworICAgICAgICAgIH0KKyAgICAgICAgICBlbHNlIC8vIEluIGRpZXNlbSBPYmpla3Qgc2luZCBrZWluZSBJdGVtcyBnZXNldHp0LgorICAgICAgICAgICAgd2hpbGUgKGktLSkgaW52W2ldLT5tb3ZlKGludl9zYXZlcixOT19DSEVDSyk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGVsc2UKKyAgICAgIHsKKyAgICAgICAgaW52PW1hcCggZGVlcF9pbnZlbnRvcnkob2JqKSwgIydfc2F2ZS8qJyovLCBpbnZfc2F2ZXIgKS0oezB9KTsKKyAgICAgIH0KKyAgICAgIGVudiA9IGVudmlyb25tZW50KG9iaik7CisgICAgICBpZiAoIGZsYWdzICYgVVBEX0MgKQorICAgICAgeworICAgICAgICBwcm8gPSAobWFwcGluZykob2JqLT5RdWVyeVByb3BlcnRpZXMoKSk7CisgICAgICB9CisgICAgfQorICAgIGVsc2UgaW52ID0gKHt9KTsKKworLy8gRXJlcmJ0ZSBPYmpla3RlIGR1cmNoc3VjaGVuLgorICAgIGlmICggZmxhZ3MgJiAoVVBEX018VVBEX0kpICkKKyAgICB7CisgICAgICBtaXhlZCBkZXA7CisgICAgICBkZXAgPSAoe30pOworICAgICAgX2RvX21ha2UoIGJsdWUsIGluc3QsIGZsYWdzICYgfihVUERfTXxVUERfTHxVUERfUnxVUERfRnxVUERfQSksICZkZXAgKTsKKyAgICAgIHByaW50ZiggX21ha2VfZGVwKCBkZXAsICIiICkgKyAiXG4iICk7CisgICAgfQorICAgCisvLyBUYXRzYWVjaGxpY2hlbiBVcGRhdGUgZHVyY2hmdWVocmVuCisgICAKKyAgICBpZiAoIF91cGRhdGUoZmlsZSwgMCwgZmxhZ3MpPCAwKSByZXR1cm4gUkVUX0ZBSUw7CisgICAgbXNnICs9IChpbnN0ID8gInplcnN0b2VydCIgOiAiYWt0dWFsaXNpZXJ0Iik7CisgICAgCisvLyBOZXUgbGFkZW4gPz8KKyAgICBpZiAoIGZsYWdzICYgKFVQRF9SfFVQRF9MKSApCisgICAgeworICAgICAgaWYgKCBvYmogPSBfcmVsb2FkKCBibHVlLGluc3QsZmxhZ3MsICZlcnIgKSApCisgICAgICAgIG1zZyArPSAiLCAiICsgKGluc3QgPyAibmV1IGdlY2xvbnQiIDogIm5ldSBnZWxhZGVuIik7CisgICAgIAorLy8gTmV1IGdlbGFkZW46IFByb3BlcnRpZXMgd2llZGVyaGVyc3RlbGxlbiwgQ2xvc3VyZXMgZmlsdGVybiAKKyAgICAgIGlmICghZXJyKQorICAgICAgeworICAgICAgICBpZiAoIW9iaikgb2JqID0gZmluZF9vYmplY3QoZmlsZSk7CisgICAgICAgIC8vIFdlbm4gZ2V3dWVuc2NodCwgUHJvcHMgenVydWVja3NjaHJlaWJlbiAoaGF0IFByaW9yaXRhZXQgdm9yCisgICAgICAgIC8vIENvbmZpZ3VyZSgpLCB3ZWlsIGV4cGxpeml0IHZvbSBNYWdpZXIgYW5nZWZvcmRlcnQpLgorICAgICAgICBpZiAoIHBybyAmJiAoZmxhZ3MgJiBVUERfQykgKQorICAgICAgICB7CisgICAgICAgICAgc3RyaW5nICpuYW1lczsKKyAgICAgICAgICAKKyAgICAgICAgICBuYW1lcyA9IG1faW5kaWNlcyhwcm8pOworICAgICAgICAgIAorICAgICAgICAgIC8vIENsb3N1cmVzIGluIChtaXR0bGVyd2VpbGUpIHplcnN0b2VydGVuIE9iamVrdGVuCisgICAgICAgICAgLy8gcmF1c2ZpbHRlcm4sIGRhbWl0IGRpZSAoaG9mZmVudGxpY2gga29ycmVrdGVuKSBDbG9zdXJlcworICAgICAgICAgIC8vIGltIG5ldSBnZWNsb250ZW4gT2JqZWt0IGVyaGFsdGVuIGJsZWliZW4KKyAgICAgICAgICBmb3IgKCBpID0gc2l6ZW9mKG5hbWVzKTsgaS0tOyApCisgICAgICAgICAgICBpZiAoIF9pbGxlZ2FsX2Nsb3N1cmUocHJvW25hbWVzW2ldLCBGX1ZBTFVFXSkgfHwKKyAgICAgICAgICAgICAgICAgX2lsbGVnYWxfY2xvc3VyZShwcm9bbmFtZXNbaV0sIEZfUVVFUllfTUVUSE9EXSkgfHwKKyAgICAgICAgICAgICAgICAgX2lsbGVnYWxfY2xvc3VyZShwcm9bbmFtZXNbaV0sIEZfU0VUX01FVEhPRF0pICkKKyAgICAgICAgICAgICAgbV9kZWxldGUoIHBybywgbmFtZXNbaV0gKTsKKyAgICAgICAgICAKKyAgICAgICAgICBvYmotPlNldFByb3BlcnRpZXMocHJvKTsKKyAgICAgICAgICBtc2cgKz0gIiwgUHJvcGVydGllcyBnZXNldHp0IjsKKyAgICAgICAgfQorICAgICAgICAvLyBXZW5uIGtlaW4gVVBEX0MsIHdpcmQgZ2dmLiBkYXMgRXJnZWJuaXMgdm9uIENvbmZpZ3VyZSgpIHdpZWRlcgorICAgICAgICAvLyB1ZWJlcmdlYmVuLgorICAgICAgICBlbHNlIGlmIChyZXN0b3JlX2NvbmZpZykKKyAgICAgICAgeworICAgICAgICAgIGludCBjb25mX3JlczsKKyAgICAgICAgICBpZiAoIWNhdGNoKGNvbmZfcmVzPShpbnQpb2JqLT5Db25maWd1cmUoY29uZmlnZGF0YSk7IHB1Ymxpc2gpCisgICAgICAgICAgICAgICYmIGNvbmZfcmVzID09IDEpCisgICAgICAgICAgeworICAgICAgICAgICAgbXNnICs9ICIsIChyZS0pa29uZmlndXJpZXJ0IjsKKyAgICAgICAgICB9CisgICAgICAgICAgZWxzZQorICAgICAgICAgIHsKKyAgICAgICAgICAgIG1zZyArPSAiLCAoUmUtKUtvbmZpZ3VyYXRpb24gZmVobGdlc2NobGFnZW4iOworICAgICAgICAgICAgaWYgKGZsYWdzICYgVVBEX0NPTkYpCisgICAgICAgICAgICAgIHByaW50ZigidXBkOiBEYXRlbiB2b24gJXMga29ubnRlbiBuaWNodCByZWtvbmZpZ3VyaWVydCB3ZXJkZW46ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICIlT1xuIiwgZmlsZSwgY29uZmlnZGF0YSk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChlbnYpCisgICAgICAgIHsKKyAgICAgICAgICBpZiAoIG9iai0+bW92ZSggZW52LCBOT19DSEVDSyApIDw9IDAgKQorICAgICAgICAgICAgcHJpbnRmKCAidXBkOiAvJU8ga29ubnRlIG5pY2h0IGluIC8lTyB6dXJ1ZWNrYmV3ZWd0IHdlcmRlblxuIiwKKyAgICAgICAgICAgICAgICAgICAgb2JqLCBlbnYgKTsKKyAgICAgICAgICBlbHNlCisgICAgICAgICAgICBtc2cgKz0gIiwgYmV3ZWd0IjsKKyAgICAgICAgfQorICAgICAgICBpZiAoaT1zaXplb2YoaW52KSkKKyAgICAgICAgeworICAgICAgICAgIHdoaWxlKGktLSkgaWYgKGludltpXSkgaW52W2ldLT5tb3ZlKG9iaiwgTk9fQ0hFQ0sgKTsKKyAgICAgICAgICBtc2cgKz0gIiwgSW5oYWx0IHp1cnVlY2tiZXdlZ3QiOworICAgICAgICB9CisgICAgICB9CisgICAgICBlbHNlIAorICAgICAgICByZXR1cm4gcHJpbnRmKCAidXBkOiAlczogJXMiLCBmaWxlLCBlcnIgKSwgUkVUX0ZBSUw7CisgICAgfQorICB9CisgIGVsc2UgCisgICAgaWYgKCAhX3VwZGF0ZShmaWxlLCAwLCBmbGFncykgJiYgKGZsYWdzICYgKFVQRF9MfFVQRF9MT0FEKSkgKQorICAgICAgaWYgKCAhX3JlbG9hZCggYmx1ZSwgaW5zdCwgZmxhZ3MsICZlcnIgKSApCisgICAgICAgIHJldHVybiBwcmludGYoICIlczogJXM6ICVzIiwgKGZsYWdzJlVQRF9MT0FEPyJsb2FkIjoidXBkIiksZmlsZSwgZXJyICksCisgICAgICAgICAgUkVUX0ZBSUw7CisgICAgICBlbHNlCisgICAgICAgIG1zZyArPSAiZ2VsYWRlbiI7CisgIAorICBpZiAoIHNpemVvZihtc2cpJiYhKGZsYWdzJlVQRF9TJiZyZWN1cnNpdmUpICkKKyAgICBwcmludGYoIiVzOiAlczogJXMuXG4iLChmbGFncyZVUERfTE9BRD8ibG9hZCI6InVwZCIpLGZpbGUsbXNnKTsKKyAgcmV0dXJuIFJFVF9PSzsKK30KKworLy8KKy8vIF91cGQ6IE9iamVrdGUgbGFkZW4sIHplcnN0b2VyZW4gdW5kIGFrdHVhbGlzaWVyZW4KKy8vCisKK3N0YXRpYyBpbnQgX3VwZChzdHJpbmcgY21kbGluZSkKK3sKKyAgaW50IGZsYWdzOworICBtaXhlZCAqYXJnczsKKworICBjbWRsaW5lPV91bnBhcnNlZF9hcmdzKCk7CisgIGFyZ3M9cGFyc2VhcmdzKGNtZGxpbmUsJmZsYWdzLFVQRF9PUFRTLDEpOworICBpZihmbGFncz09LTF8fCFzaXplb2YoYXJncykpCisgICAgcmV0dXJuIFVTQUdFKCJ1cGQgWy0iK1VQRF9PUFRTKyJdIDxkYXRlaT4gWzxkYXRlaT4gLi5dIik7CisgIGlmICgoZmxhZ3MgJiBVUERfQykgJiYgKGZsYWdzICYgVVBEX0NPTkYpKQorICB7CisgICAgcHJpbnRmKCJ1cGQ6IC1jIHVuZCAtQyBnbGVpY2h6ZWl0aWcgd2VyZGVuIG5pY2h0IHVudGVyc3R1ZXR6dC5cbiIpOworICAgIHJldHVybiAxOworICB9CisgIGFyZ3M9ZmlsZV9saXN0KGFyZ3MsTU9ERV9VUEQsMCwiLyIpOworICBpZighc2l6ZW9mKGFyZ3MpKSByZXR1cm4gcHJpbnRmKCJ1cGQ6IEtlaW5lIHBhc3NlbmRlIERhdGVpIGdlZnVuZGVuIVxuIiksMTsKKworICBhcmdzPW1hcChhcmdzLCg6ICQxW0ZVTExOQU1FXSA6KSktKHswfSk7CisKKyAgaWYoIXNpemVvZihhcmdzKSkKKyAgeworICAgIHByaW50ZigidXBkOiBWZXJ6ZWljaG5pc3NlIGtvZW5uZW4gbmljaHQgYWt0dWFsaXNpZXJ0IHdlcmRlbiFcbiIpOworICAgIHJldHVybiAxOworICB9CisgIGFzeW5jaHJvbihhcmdzLCMnX21ha2UsZmxhZ3MsMCwwKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8vCisvLyBfbG9hZDogT2JqZWt0ZSBsYWRlbgorLy8KKworc3RhdGljIGludCBfbG9hZChzdHJpbmcgY21kbGluZSkKK3sKKyAgaW50IGZsYWdzOworICBtaXhlZCAqYXJnczsKKworICBjbWRsaW5lPV91bnBhcnNlZF9hcmdzKCk7CisgIGFyZ3M9cGFyc2VhcmdzKGNtZGxpbmUsJmZsYWdzLCIiLDEpOworICBpZihmbGFncz09LTF8fCFzaXplb2YoYXJncykpCisgICAgcmV0dXJuIFVTQUdFKCJsb2FkIDxkYXRlaT4gWzxkYXRlaT4gLi5dIik7CisgIGFyZ3M9ZmlsZV9saXN0KGFyZ3MsTU9ERV9VUEQsMCwiLyIpOworICBpZighc2l6ZW9mKGFyZ3MpKSByZXR1cm4gcHJpbnRmKCJsb2FkOiBLZWluZSBwYXNzZW5kZSBEYXRlaSBnZWZ1bmRlbiFcbiIpLDE7CisgIGFyZ3M9bWFwKGFyZ3MsKDogKCgkMVtGSUxFU0laRV0hPS0yfHxmaW5kX29iamVjdCgkMVtGVUxMTkFNRV0pKT8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgJDFbRlVMTE5BTUVdOjApIDopKS0oezB9KTsKKworICBpZighc2l6ZW9mKGFyZ3MpKQorICAgIHJldHVybiBwcmludGYoImxvYWQ6IFZlcnplaWNobmlzc2Uga29lbm5lbiBuaWNodCBnZWxhZGVuIHdlcmRlbiFcbiIpLDE7CisgIGFzeW5jaHJvbihhcmdzLCMnX21ha2UsVVBEX0xPQUQsMCwwKTsKKyAgcmV0dXJuIDE7Cit9Cg==