ZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2ludm1hc3Rlci5jIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvaW52bWFzdGVyLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDZjY2RhMAotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2ludm1hc3Rlci5jCkBAIC0wLDAgKzEsNDY0IEBACisvLyBpbnZtYXN0ZXIuYyBieSBOYWNodHdpbmRATUcgVjEuMSAoNS4zLjIwMDEpCisvLyBBIHNtYWxsIG1hc3RlciB0aGF0IHByb3ZpZGVzIGEgZ3JhcGhpY2FsIGRpc3BsYXkgb2YgdGhlIHBsYXllcrRzCisvLyBlcXVpcG1lbnQuIAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcyxydHRfY2hlY2tzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNpbmNsdWRlIDxpbnB1dF90by5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxhbnNpLmg+CisjaW5jbHVkZSA8Y29tYmF0Lmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKyNpbmNsdWRlICJpbnZtYXN0ZXIuaCIKKworCittYXBwaW5nIGRhdGE7CitjbG9zdXJlIGFiYnJldmlhdGU7CisKKworLy8gaSdtIGF3YXJlIHRoaXMgY2FuIGJlIGRldGVybWluZWQgd2l0aCBtX2luZGljZXMoVkFMSURfQVJNT1VSX1RZUEUpLAorLy8gYnV0IHRoZSBwb3NpdGlvbiBpbiB0aGUgYXJyYXlzIGlzIGltcG9ydGFudCBmb3IgdGhlIGRyYXdpbmcgb3JkZXIuCisvLyBmaXJzdCBpdGVtIGluIHRoZSBhcnJheSBpcyBkcmF3biBsYXN0CitzdGF0aWMgc3RyaW5nICphcm1vdXJfdHlwZXMgPSAKKyh7QVRfQkVMVCwKKyAgQVRfU0hJRUxELAorICBBVF9IRUxNRVQsCisgIEFUX0JPT1QsCisgIEFUX1RST1VTRVJTLAorICBBVF9BTVVMRVQsCisgIEFUX1JJTkcsCisgIEFUX0dMT1ZFLAorICBBVF9RVUlWRVIsCisgIEFUX0NMT0FLLAorICBBVF9BUk1PVVJ9KTsKKworc3RhdGljIG1hcHBpbmcgY29sb3JzID0gCisoWzA6QU5TSV9CTEFDSywKKyAgMTpBTlNJX1JFRCwgCisgIDI6QU5TSV9HUkVFTiwKKyAgMzpBTlNJX1lFTExPVywKKyAgNDpBTlNJX0JMVUUsCisgIDU6QU5TSV9QVVJQTEUsCisgIDY6QU5TSV9DWUFOLAorICA3OkFOU0lfV0hJVEUsCisgIDg6IiJdKTsKKyAgCitzdGF0aWMgbWFwcGluZyBiZ2NvbG9ycyA9IAorKFswOkFOU0lfQkdfQkxBQ0ssCisgIDE6QU5TSV9CR19SRUQsIAorICAyOkFOU0lfQkdfR1JFRU4sCisgIDM6QU5TSV9CR19ZRUxMT1csCisgIDQ6QU5TSV9CR19CTFVFLAorICA1OkFOU0lfQkdfUFVSUExFLAorICA2OkFOU0lfQkdfQ1lBTiwKKyAgNzpBTlNJX0JHX1dISVRFLAorICA4OiIiXSk7CisgIAorCisKK3N0YXRpYyBzdHJpbmcgTWFwcGluZzJDb2xvcmVkVGV4dChtYXBwaW5nIHBpYywgb2JqZWN0IHBsYXllcik7CitzdGF0aWMgc3RyaW5nIE1hcHBpbmcyUGxhaW5UZXh0KG1hcHBpbmcgcGljKTsKK3N0YXRpYyB2b2lkIEFkZERlc2NyaXB0aW9uKG1hcHBpbmcgcGljLCBzdHJpbmcgdHlwZSwgb2JqZWN0IGl0ZW0pOworc3RhdGljIHN0cmluZyBDb21wb3NlRGVzYyhvYmplY3QgaXRlbSk7CitzdGF0aWMgdm9pZCBDb25maWd1cmVDb2xvcnMoc3RyaW5nIHRleHQpOworCit2b2lkIFNob3dJbnYob2JqZWN0IHBsYXllciwgc3RyaW5nIGFyZyk7CisKKy8vIG9rLCBsZXS0cyBqdXN0IHJlYWQgaW4gdGhlIGdyYXBoaWNzLi4uCisvLyByZWFsbHkgdGFrZXMgc29tZSB0aW1lICh+MjUwIGV2YWwgdGlja3MpIGJ1dCBpcyBvbmx5IGRvbmUKKy8vIG9uY2UgaW4gYW4gdXB0aW1lCit2b2lkIGNyZWF0ZSgpCit7CisgIG1hcHBpbmcgcGljOworICBzdHJpbmcgKmZpbGVzLCAqbGluZXMsIHRleHQ7CisgIGludCBpLGosaywgaW5kZW50eCxpbmRlbnR5LCBjb2xvcjsKKworICBkYXRhPShbXSk7CisgIAorICBEQigiVHJ5aW5nIHRvIGZpcmUgdXAgbWFzdGVyLCBwYXRoIGlzICciK0lOVlBBVEgrIicuLi4iKTsKKyAgZmlsZXM9Z2V0X2RpcihJTlZQQVRIKyJnZngvKiIpLSh7Ii4iLCAiLi4ifSk7CisgIERCKHNwcmludGYoIkZpbGVzIGZvdW5kIGluICdnZngvJzogXG4lTyIsIGZpbGVzKSk7CisgIGZvciAoaT1zaXplb2YoZmlsZXMpLTE7aT49MDtpLS0pCisgIHsKKyAgICBEQigiUmVhZGluZyAnIitmaWxlc1tpXSsiJyAuLi4iKTsKKyAgICB0ZXh0PXJlYWRfZmlsZShJTlZQQVRIKyJnZngvIitmaWxlc1tpXSk7CisgICAgaWYgKCFzdHJpbmdwKHRleHQpKQorICAgIHsKKyAgICAgIERCKCJGYWlsZWQgdG8gcmVhZCBmaWxlLiIpOworICAgICAgY29udGludWU7CisgICAgfQorICAgIGxpbmVzPWV4cGxvZGUodGV4dCwgIlxuIik7CisgICAgaWYgKHNpemVvZihsaW5lcykgPCA0KQorICAgIHsKKyAgICAgIERCKCJGaWxlIGNvcnJ1cHQuIik7CisgICAgICBjb250aW51ZTsKKyAgICB9CisgICAgaW5kZW50eD10b19pbnQobGluZXNbMV0pOworICAgIGluZGVudHk9dG9faW50KGxpbmVzWzJdKTsKKyAgICBjb2xvcj10b19pbnQobGluZXNbMF0pOworICAgIHBpYz0oW10pOworICAgIGZvciAoaj1zaXplb2YobGluZXMpLTE7aj4yO2otLSkKKyAgICB7CisgICAgICBmb3IgKGs9c2l6ZW9mKGxpbmVzW2pdKS0xO2s+PTA7ay0tKQorICAgICAgeworICAgICAgICBpZiAobGluZXNbal1bay4ua10hPSI/IikKKyAgICAgICAgICBwaWMrPShbKGotMytpbmRlbnR5KSo4MCtrK2luZGVudHg6bGluZXNbal1bay4ua107Y29sb3JdKTsKKyAgICAgIH0KKyAgICB9CisgICAgZGF0YSs9KFtmaWxlc1tpXTpwaWNdKTsKKyAgICBEQigiRmlsZSBzdWNjZXNzZnVsbHkgcmVhZC4iKTsKKyAgfQorICBEQihzcHJpbnRmKCJUeXBlcyBjb3ZlcmVkOlxuJU9cbiIsIG1faW5kaWNlcyhkYXRhKSkpOworCisgIC8vIGNyZWF0ZSBjbG9zdXJlIG9ubHkgb25jZSB0byBzYXZlIHRpbWUKKyAgLy8gbmVlZGVkIGJ5IENvbXBvc2VEZXNjKCkKKyAgLy8gdGhlIGNsb3N1cmUgaXN0IG5vdCBhcyBjb21wbGljYXRlZCBhcyBpdCBzZWVtcyA7KQorICAvLyBpdCBqdXN0IGNoZWNrcyBldmVyeSB3b3JkIG9mIHRoZSBuYW1lLCBpZiBpdCBkb2VzIG5vdCBiZWdpbgorICAvLyB3aXRoIGEgY2FwaXRhbCBsZXR0ZXIsIGl0IGlzIGFiYnJldmlhdGVkCisgIC8vIHRoaXMgaGFwcGVucyBvbmx5IGlmIHRoZSBuYW1lIGxlbmd0aCBleGNlZWRzIDIwIGNoYXJzLi4uCisgIGFiYnJldmlhdGU9bGFtYmRhKCh7J3h9KSwgCisgICAgICAoeyMnPywgKHsjJz4sICh7IydtZW1iZXIsIHF1b3RlKCh7ImRlciIsICJkZXMifSkpLCAneH0pLCAwfSksCisgICAgICAgICJkLiIsCisgICAgICAgICh7Iyc/LCAoeyMnPiwgKHsjJ3NpemVvZiwgJ3h9KSwgM30pLCAKKyAgICAgICAgICAoeyMnPywgKHsjJywsICh7Iyc9LCAnYSwgKHsjJ2FsbG9jYXRlLCAxfSkgfSksCisgICAgICAgICAgICAgICAgICAgICAgICAoeyMnPSwgKHsjJ1ssICdhLCAwfSksICd4IH0pLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICh7IydzaXplb2YsICh7IydyZWdleHAsICdhLCAiXlthLXpdLioifSkgfSkgCisgICAgICAgICAgICAgICAgIH0pLCAKKyAgICAgICAgICAgICh7IycrLCAoeyMnWy4uXSwgJ3gsIDAsIDF9KSwgIi4ifSksCisgICAgICAgICAgICAneAorICAgICAgICAgIH0pLCAKKyAgICAgICAgICAneAorICAgICAgICB9KQorICAgICAgfSkpOworfQorCisvLyBmdW5jdGlvbiB0aGF0IHRyaWVzIHRvIGd1ZXNzIGEgZ29vZCBpdGVtIG5hbWUgYW5kIHVzZSBhYmJyZXZhdGlvbnMKKy8vIHdoZXJlIHBvc3NpYmxlCitzdGF0aWMgc3RyaW5nIENvbXBvc2VEZXNjKG9iamVjdCBpdGVtKQoreworICBpbnQgaTsKKyAgc3RyaW5nIHRleHQsICpidWZmOworICAKKyAgdGV4dD1yZWdyZXBsYWNlKGl0ZW0tPlF1ZXJ5UHJvcChQX1NIT1JUKQorICAgICAgICAgICAgICAgIHx8aXRlbS0+UXVlcnlQcm9wKFBfTkFNRSkKKyAgICAgICAgICAgICAgICB8fCI8Pz4iLAorICAgICAgICAgICAgICAgICJeKEVpbiBQYWFyfEVpbnxFaW5lfERlcnxEaWV8RGFzKSAiLCIiLDApOworICAgICAgICAgICAgICAgIAorLy8gdHJ5IHRvIHNob3J0ZW4gdGhlIG5hbWUgd2l0aCB0aGUgY2xvc3VyZQorICBpZiAoc2l6ZW9mKHRleHQpID4gMjApCisgICAgcmV0dXJuIGltcGxvZGUobWFwKGV4cGxvZGUodGV4dCwgIiAiKSwgYWJicmV2aWF0ZSksICIgIik7CisgIGVsc2UgICAgICAKKyAgICByZXR1cm4gdGV4dDsKK30KKworLy8gY29udmVydHMgYSBtYXBwaW5nIHdpdGggY2hhcmFjdGVycyBhbmQgY29sb3IgaW5mbyBpbnRvIGEKKy8vIHRleHQuIGRhdGEgaW4gdGhlIG1hcHBpbmcgaXMgc3RvcmVkIGluIGEgb25lLWRpbWVuc2lvbmFsIAorLy8gb3JkZXIgd2l0aCB0aGUgcG9zaXRpb24gYXMga2V5ICh5cG9zIGlzIHBvcy84MCwgeHBvcyBwb3MlODApCisvLyB0aGlzIHNldHVwIGhhcyBhIGh1Z2UgYWR2YW50YWdlOiBjb21iaW5pbmcgc2V2ZXJhbAorLy8gZ3JhcGhpY3MganVzdCB0YWtlcyBhICIrIiBvcGVyYXRvciwgdGhlIHJlc3QgaXMgaGFuZGxlZAorLy8gYnkgdGhlIGdhbWUgZHJpdmVyLiBmcmVha2luJyBmYXN0LCBtdWNoIGJldHRlciB0aGFuIGRvaW5nIGFuCisvLyBpdGVyYXRpb24gb3ZlciBvbmUgb3IgbW9yZSBhcnJheSBpbiBscGMuCitzdGF0aWMgc3RyaW5nIE1hcHBpbmcyQ29sb3JlZFRleHQobWFwcGluZyBwaWMsIG9iamVjdCBwbGF5ZXIpCit7CisgIHN0cmluZyB0ZXh0OworICBtYXBwaW5nIGNvbmZpZ21hcDsKKyAgaW50IGksaixjb2xvcjsKKyAgCisgIGNvbmZpZ21hcD1kZWZhdWx0X2NvbmZpZysocGxheWVyLT5RdWVyeVByb3AoUF9JTlZNQVNURVJfQ09ORklHKXx8KFtdKSk7CisKKyAgdGV4dD0iIjsKKyAgY29sb3I9MDsKKyAgZm9yIChpPTA7aTwyMjtpKyspCisgIHsKKyAgICB0ZXh0Kz1iZ2NvbG9yc1tjb25maWdtYXBbOF1dOworICAgIGZvciAoaj0wO2o8Nzg7aisrKQorICAgIHsgCisgICAgICBpZiAocGljW2kqODAraiwxXSE9Y29sb3IpCisgICAgICB7CisgICAgICAgIGNvbG9yPXBpY1tpKjgwK2osMV07CisgICAgICAgIHRleHQrPWNvbG9yc1tjb25maWdtYXBbY29sb3JdXTsKKyAgICAgIH0KKyAgICAgIHRleHQrPXBpY1tpKjgwK2pdOworICAgIH0KKyAgICB0ZXh0Kz1BTlNJX05PUk1BTCsiXG4iOworICAgIGNvbG9yPTA7CisgIH0KKyAgcmV0dXJuIHRleHQ7Cit9CisKK3N0YXRpYyBzdHJpbmcgTWFwcGluZzJQbGFpblRleHQobWFwcGluZyBwaWMpCit7CisgIHN0cmluZyB0ZXh0OworICBpbnQgaSxqOworICAKKyAgdGV4dD0iIjsKKworICBmb3IgKGk9MDtpPDIyO2krKykKKyAgeworICAgIGZvciAoaj0wO2o8Nzg7aisrKQorICAgICAgdGV4dCs9cGljW2kqODAral07CisgICAgdGV4dCs9IlxuIjsKKyAgfQorICByZXR1cm4gdGV4dDsKK30KK3N0YXRpYyB2b2lkIEFkZERlc2NyaXB0aW9uKG1hcHBpbmcgcGljLCBzdHJpbmcgdHlwZSwgb2JqZWN0IGl0ZW0pCit7CisgIGludCBpbmRlbnR4LCBpbmRlbnR5LCBpOworICBzdHJpbmcgdGV4dDsKKworICBzd2l0Y2godHlwZSkKKyAgeworICAgY2FzZSBBVF9IRUxNRVQ6CisgICAgICBpbmRlbnR4PTQ3OworICAgICAgaW5kZW50eT0wOworICAgICAgdGV4dD1zcHJpbnRmKCIlLTMwcyIsQ29tcG9zZURlc2MoaXRlbSlbMC4uMzBdKTticmVhazsKKyAgICBjYXNlIEFUX1FVSVZFUjoKKyAgICAgIGluZGVudHg9NDk7CisgICAgICBpbmRlbnR5PTI7CisgICAgICB0ZXh0PXNwcmludGYoIiUtMjhzIixDb21wb3NlRGVzYyhpdGVtKVswLi4yOF0pO2JyZWFrOyAgICAgCisgICAgY2FzZSBBVF9BTVVMRVQ6CisgICAgICBpbmRlbnR4PTQ5OworICAgICAgaW5kZW50eT00OyAgICAgCisgICAgICB0ZXh0PXNwcmludGYoIiUtMjdzIixDb21wb3NlRGVzYyhpdGVtKVswLi4yOF0pO2JyZWFrOyAgICAgCisgICAgY2FzZSBBVF9BUk1PVVI6CisgICAgICBpbmRlbnR4PTUzOworICAgICAgaW5kZW50eT03OworICAgICAgdGV4dD1zcHJpbnRmKCIlLTI0cyIsQ29tcG9zZURlc2MoaXRlbSlbMC4uMjVdKTticmVhazsgICAgICAgICAgCisgICAgY2FzZSBBVF9TSElFTEQ6CisgICAgICBpbmRlbnR4PTU0OworICAgICAgaW5kZW50eT0xMDsgICAKKyAgICAgIHRleHQ9c3ByaW50ZigiJS0yMHMiLENvbXBvc2VEZXNjKGl0ZW0pWzAuLjI0XSk7YnJlYWs7CisgICAgY2FzZSBBVF9DTE9BSzoKKyAgICAgIGluZGVudHg9NTM7CisgICAgICBpbmRlbnR5PTE1OworICAgICAgdGV4dD1zcHJpbnRmKCIlLTIwcyIsQ29tcG9zZURlc2MoaXRlbSlbMC4uMjVdKTticmVhazsKKyAgICBjYXNlIEFUX1RST1VTRVJTOgorICAgICAgaW5kZW50eD00OTsKKyAgICAgIGluZGVudHk9MTc7CisgICAgICB0ZXh0PXNwcmludGYoIiUtMjBzIixDb21wb3NlRGVzYyhpdGVtKVswLi4yMF0pO2JyZWFrOyAgICAgCisgICAgY2FzZSBBVF9SSU5HOgorICAgICAgaW5kZW50eD0wOworICAgICAgaW5kZW50eT05OworICAgICAgdGV4dD1zcHJpbnRmKCIlMTRzIixDb21wb3NlRGVzYyhpdGVtKVswLi4xN10pO2JyZWFrOworICAgIGNhc2UgQVRfR0xPVkU6CisgICAgICBpbmRlbnR4PTA7CisgICAgICBpbmRlbnR5PTExOworICAgICAgdGV4dD1zcHJpbnRmKCIlMTRzIixDb21wb3NlRGVzYyhpdGVtKVswLi4xN10pO2JyZWFrOworICAgIGNhc2UgQVRfQkVMVDoKKyAgICAgIGluZGVudHg9MTsKKyAgICAgIGluZGVudHk9MTM7CisgICAgICB0ZXh0PXNwcmludGYoIiUxNHMiLENvbXBvc2VEZXNjKGl0ZW0pWzAuLjE4XSk7YnJlYWs7ICAgICAKKyAgICBjYXNlIEFUX0JPT1Q6CisgICAgICBpbmRlbnR4PTE7CisgICAgICBpbmRlbnR5PTIwOworICAgICAgdGV4dD1zcHJpbnRmKCIlMThzIixDb21wb3NlRGVzYyhpdGVtKVswLi4xOF0pO2JyZWFrOworICAgIGNhc2UgIldhZmZlIjoKKyAgICAgIGluZGVudHg9MTsKKyAgICAgIGluZGVudHk9MTsKKyAgICAgIHRleHQ9c3ByaW50ZigiJTE4cyIsQ29tcG9zZURlc2MoaXRlbSlbMC4uMjVdKTsKKyAgICAgIGlmIChpdGVtLT5RdWVyeVByb3AoUF9OUl9IQU5EUykgPiAxICYmCisgICAgICAgICAgdGhpc19wbGF5ZXIoKSAmJgorICAgICAgICAgICEodGhpc19wbGF5ZXIoKS0+UXVlcnlBcm1vckJ5VHlwZShBVF9TSElFTEQpKSkKKyAgICAgICAgQWRkRGVzY3JpcHRpb24ocGljLCBBVF9TSElFTEQsIGl0ZW0pO2JyZWFrOworICAgIGRlZmF1bHQ6IHJldHVybjsKKyAgfQorICBmb3IgKGk9MDtpPHNpemVvZih0ZXh0KTtpKyspCisgICAgcGljKz0oWyg4MCppbmRlbnR5K2luZGVudHgraSk6dGV4dFtpLi5pXTsyXSk7Cit9CisKK3ZhcmFyZ3Mgc3RhdGljIHZvaWQgQ29uZmlndXJlQ29sb3JzKHN0cmluZyB0ZXh0KQoreyAKKyAgbWFwcGluZyBjb25maWcsIGRpc3BsYXk7CisgIHN0cmluZyAqc3RyczsKKyAgCisgIGlmICghb2JqZWN0cCh0aGlzX3BsYXllcigpKSkgcmV0dXJuOworICAKKyAgaWYgKHRoaXNfcGxheWVyKCktPkluRmlnaHQoKSkKKyAgeworICAgIHdyaXRlKGJyZWFrX3N0cmluZygKKyAgICAgICJJbSBLYW1wZj8gTmEgRHUgaGFzdCBOZXJ2ZW4sIGRhcyBsYXNzZW4gd2lyIGRvY2ggbWFsIGxpZWJlciEgIgorICAgICAgIlByb2JpZXIgZXMgZGFuYWNoIG5vY2htYWwuLi4iLCA3OCkpOworICAgIHJldHVybjsKKyAgfQorICAKKyAgaWYgKHN0cmluZ3AodGV4dCkpIHRleHQ9bG93ZXJfY2FzZSh0ZXh0KTsKKyAgCisgIGlmICh0ZXh0PT0ib2siKQorICB7CisgICAgd3JpdGUoIkZhcmJrb25maWd1cmF0aW9uIGJlZW5kZXQuXG4iKTsKKyAgICByZXR1cm47CisgIH0KKworICAvLyJhbnNpX2NvbmZpZyIsIGRlZiBpbiBpbnZtYXN0ZXIuaAorICBjb25maWc9dGhpc19wbGF5ZXIoKS0+UXVlcnlQcm9wKFBfSU5WTUFTVEVSX0NPTkZJRyl8fChbXSk7CisgIGRpc3BsYXk9ZGVmYXVsdF9jb25maWcrY29uZmlnOworICAKKyAgaWYgKCF0ZXh0IHx8IHRleHQ9PSIiKQorICB7CisgICAgd3JpdGUoIAorICAgICIqKiogRmFyYmtvbmZpZ3VyYXRpb24gZnVlciBkZW4gQXVzcnVlc3R1bmdzYmVmZWhsICoqKlxuXG4iCisgICAgIiBGYXJiZTogICAgICAgICAgICAgICAgICAgICB3aXJkIGRhcmdlc3RlbGx0IG1pdDpcbiIKKyAgICAiLS0tLS0tLS0tLS0tLS0tLS0tICAgICAgICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iCisgICAgIiBIaW50ZXJncnVuZCAgICAgICAgICAgICAgICAgIitDT0xPUk5BTUVTW2Rpc3BsYXlbOF1dKyJcbiIKKyAgICAiIFNjaHdhcnogICAgICAgICAgICAgICAgICAgICAiK0NPTE9STkFNRVNbZGlzcGxheVswXV0rIlxuIgorICAgICIgUm90ICAgICAgICAgICAgICAgICAgICAgICAgICIrQ09MT1JOQU1FU1tkaXNwbGF5WzFdXSsiXG4iCisgICAgIiBHcnVlbiAgICAgICAgICAgICAgICAgICAgICAgIitDT0xPUk5BTUVTW2Rpc3BsYXlbMl1dKyJcbiIKKyAgICAiIEdlbGIgICAgICAgICAgICAgICAgICAgICAgICAiK0NPTE9STkFNRVNbZGlzcGxheVszXV0rIlxuIgorICAgICIgQmxhdSAgICAgICAgICAgICAgICAgICAgICAgICIrQ09MT1JOQU1FU1tkaXNwbGF5WzRdXSsiXG4iCisgICAgIiBNYWdlbnRhICAgICAgICAgICAgICAgICAgICAgIitDT0xPUk5BTUVTW2Rpc3BsYXlbNV1dKyJcbiIKKyAgICAiIFR1ZXJraXMgICAgICAgICAgICAgICAgICAgICAiK0NPTE9STkFNRVNbZGlzcGxheVs2XV0rIlxuIgorICAgICIgV2Vpc3MgICAgICAgICAgICAgICAgICAgICAgICIrQ09MT1JOQU1FU1tkaXNwbGF5WzddXSsiXG5cbiIKKyAgICAiRmFyYmUgYWVuZGVybiBtaXQgJzxmYXJiZT4gPGdld3VlbnNjaHRlIGZhcmJlPicuXG4iCisgICAgIkJlaXNwaWVsOiAnZ2VsYiByb3QnLlxuIgorICAgICJBbGxlcywgd2FzIHN0YW5kYXJkbWFlc3NpZyBnZWxiIHdhZXJlLCB3dWVyZGUgZGFubiBtaXQgZGVyIEFOU0ktRmFyYmUgXG4iCisgICAgIlJvdCBkYXJnZXN0ZWxsdC5cbiIKKyAgICAiRGVyIEhpbnRlcmdydW5kIGthbm4genVzYWV0emxpY2ggZGllIEZhcmJlICdrZWluZScgaGFiZW4sIGJlaSBkZXIgZGVyIFxuIgorICAgICJIaW50ZXJncnVuZCBlYmVuIHVlYmVyaGF1cHQgbmljaHQgZ2VmYWVyYnQgd2lyZC5cbiIKKyAgICAiQmVpc3BpZWw6ICdoaW50ZXJncnVuZCBrZWluZScuIFNjaGFsdGV0IGRpZSBIaW50ZXJncnVuZGZhcmJlIGF1cy5cblxuIgorICAgICJCZWVuZGVuIG1pdCAnb2snLiBcbiIKKyAgICAiV2llZGVyaG9sdW5nIGRlciBGYXJibGlzdGUgbWl0IDxSZXR1cm4+LlxuIgorICAgICJGYXJibGlzdGUgYXVmIFN0YW5kYXJkIHp1cnVlY2tzZXR6ZW4gbWl0ICdyZXNldCcuXG4iKTsKKyAgfQorICBlbHNlCisgIGlmICh0ZXh0PT0icmVzZXQiKQorICB7CisgICAgdGhpc19wbGF5ZXIoKS0+U2V0KFBfSU5WTUFTVEVSX0NPTkZJRywgU0FWRSwgRl9NT0RFX0FEKTsgICAgCisgICAgdGhpc19wbGF5ZXIoKS0+U2V0UHJvcChQX0lOVk1BU1RFUl9DT05GSUcsIDApOworICAgIHdyaXRlKCJGYXJiZW4genVydWVja2dlc2V0enQhXG4iKTsgICAgCisgIH0KKyAgZWxzZQorICB7CisgICAgaWYgKCBzaXplb2Yoc3Rycz1leHBsb2RlKHRleHQsICIgIiktKHsiIn0pKSAhPTIgCisgICAgICB8fCAhbWVtYmVyKChDT0xPUkNPREVTLShbImtlaW5lIl0pKSwgc3Ryc1swXSkKKyAgICAgIHx8ICFtZW1iZXIoKENPTE9SQ09ERVMtKFsiaGludGVyZ3J1bmQiXSkpLCBzdHJzWzFdKQorICAgICAgfHwgKChzdHJzWzBdIT0iaGludGVyZ3J1bmQiKSAmJiAoc3Ryc1sxXT09ImtlaW5lIikpICkgCisgICAgeworICAgICAgd3JpdGUoIkZhbHNjaGUgRWluZ2FiZS5cbiIKKyAgICAgICAgICAgICJGb3JtYXQ6IDxmYXJiZXxoaW50ZXJncnVuZD4gPHp1Z2V3aWVzZW5lIEZhcmJlPlxuIgorICAgICAgICAgICAgIkFiYnJlY2hlbiBtaXQgJ29rJy5cbiIpOworICAgIH0KKyAgICBlbHNlCisgICAgeworICAgICAgaWYgKENPTE9SQ09ERVNbc3Ryc1sxXV09PWRlZmF1bHRfY29uZmlnW0NPTE9SQ09ERVNbc3Ryc1swXV1dKQorICAgICAgICBjb25maWctPShbQ09MT1JDT0RFU1tzdHJzWzBdXV0pOworICAgICAgZWxzZQorICAgICAgICBjb25maWcrPShbQ09MT1JDT0RFU1tzdHJzWzBdXTpDT0xPUkNPREVTW3N0cnNbMV1dXSk7CisgICAgICBpZiAoIXNpemVvZihjb25maWcpKQorICAgICAgeworICAgICAgICB0aGlzX3BsYXllcigpLT5TZXQoUF9JTlZNQVNURVJfQ09ORklHLCBTQVZFLCBGX01PREVfQUQpOyAgICAKKyAgICAgICAgdGhpc19wbGF5ZXIoKS0+U2V0UHJvcChQX0lOVk1BU1RFUl9DT05GSUcsIDApOworICAgICAgfQorICAgICAgZWxzZQorICAgICAgeworICAgICAgICB0aGlzX3BsYXllcigpLT5TZXRQcm9wKFBfSU5WTUFTVEVSX0NPTkZJRywgZGVlcF9jb3B5KGNvbmZpZykpOworICAgICAgICB0aGlzX3BsYXllcigpLT5TZXQoUF9JTlZNQVNURVJfQ09ORklHLCBTQVZFLCBGX01PREVfQVMpOyAgICAgICAgCisgICAgICB9CisgICAgICB3cml0ZSgiT2ssIEZhcmJlIGdld2FlaGx0IVxuIik7CisgICAgfQorICB9CisgIGlucHV0X3RvKCJDb25maWd1cmVDb2xvcnMiLCBJTlBVVF9QUk9NUFQsICJcbkVpbmdhYmU6ICIpOworfQorCisKK3N0cmluZyogYXJtb3VyX29yZGVyPSh7IAorICAgIEFUX0hFTE1FVCwgQVRfQU1VTEVULCBBVF9RVUlWRVIsIEFUX0FSTU9VUiwgQVRfQ0xPQUssCisgIEFUX0dMT1ZFLCBBVF9SSU5HLCBBVF9CRUxULAorICBBVF9UUk9VU0VSUywgQVRfQk9PVCwgQVRfU0hJRUxELCBBVF9NSVNDfSk7IAorCittYXBwaW5nIHdlYXBvbl9uYW1lcz0oWworCQkgICAgICAgV1RfU1BFQVIgOiAiU3BlZXIiLAorCQkgICAgICAgV1RfU1dPUkQgOiAiU2Nod2VydCIsCisJCSAgICAgICBXVF9TVEFGRiA6ICJLYW1wZnN0YWIiLAorCQkgICAgICAgV1RfV0hJUCAgOiAiUGVpdHNjaGUiLAorCQkgICAgICAgV1RfQ0xVQiAgOiAiS2V1bGUiLAorCQkgICAgICAgV1RfS05JRkUgOiAiTWVzc2VyIiwKKwkJICAgICAgIFdUX01JU0MgIDogIklyZ2VuZHdhcyIsCisJCSAgICAgICBXVF9NQUdJQyA6ICJBcnRlZmFrdCIsCisJCSAgICAgICBXVF9BWEUgICA6ICJBeHQiLAorCSAgICAgICBXVF9SQU5HRURfV0VBUE9OIDogIkZlcm53YWZmZSIKKwkJICAgICAgIF0pOworCitzdHJpbmcgU2ltcGxlSW52KG9iamVjdCBwbGF5ZXIpIHsKKyAgb2JqZWN0KiBhcm1vdXJzPXBsYXllci0+UXVlcnlQcm9wKFBfQVJNT1VSUyk7CisgIGludCBjb3VudD1zaXplb2YoYXJtb3VyX29yZGVyKTsKKyAgc3RyaW5nKiBsaXN0PWFsbG9jYXRlKGNvdW50KTsKKyAgc3RyaW5nIHJlc3VsdD0iQXVzcnVlc3R1bmdcbiI7CisgIGludCBpOworCisgIGZvcmVhY2gob2JqZWN0IG9iOiBhcm1vdXJzKSB7CisgICAgaWYgKCFvYmplY3RwKG9iKSkgY29udGludWU7CisgICAgICBpbnQgaWR4ID0gbWVtYmVyKGFybW91cl9vcmRlciwgb2ItPlF1ZXJ5UHJvcChQX0FSTU9VUl9UWVBFKSk7CSAgICAgIAorICAgICAgaWYgKGlkeD49MCkKKyAgICAgICAgbGlzdFtpZHhdPW9iLT5RdWVyeVByb3AoUF9TSE9SVCk7CisgIH0KKworICAvLyBBVF9NSVNDIChsZXR6dGVzIEVsZW1lbnQgaW4gbGlzdCB1bmQgYXJtb3VyX29yZGVyKSB3ZWdsYXNzZW4uCisgIGZvciAoaT0wO2k8Y291bnQtMTtpKyspIHsKKyAgICByZXN1bHQrPXNwcmludGYoIiUtMjBzICUtNTdzXG4iLGFybW91cl9vcmRlcltpXSxsaXN0W2ldIHx8ICIiKTsKKyAgfQorCisgIG9iamVjdCBvYj1vYj1wbGF5ZXItPlF1ZXJ5UHJvcChQX1dFQVBPTik7CisgIGlmIChvYmplY3RwKG9iKSkgeworICAgIHJlc3VsdCs9c3ByaW50ZigiJS0yMHMgJS01N3NcbiIsCisJCSAgICAob2ItPlF1ZXJ5UHJvcChQX05SX0hBTkRTKT09MSA/ICJFaW5oYW5kLSI6Ilp3ZWloYW5kLSIpCisJCSAgICArd2VhcG9uX25hbWVzW29iLT5RdWVyeVByb3AoUF9XRUFQT05fVFlQRSldLAorCQkgICAgb2ItPlF1ZXJ5UHJvcChQX1NIT1JUKSk7CisgIH0gZWxzZSByZXN1bHQrPSJLZWluZSBXYWZmZVxuIjsKKworICByZXR1cm4gcmVzdWx0OworfQorLy8gdGhlIG1haW4gZnVuY3Rpb24gY2FsbGVkIGJ5IHRoZSBwbGF5ZXIgb2JqZWN0LgorLy8gZGV0ZXJtaW5lcyBnZW5kZXIsIHRoZW4gYWRkcyBhcm1vci93ZWFwb24gZ3JhcGhpY3MKKy8vIGR5bmFtaWNhbGx5LiBzdGlsbCB2ZXJ5IGZhc3QgZHVlIHRvIHRoZSB1c2Ugb2YgdGhlICIrIiBvcGVyYXRvciwKKy8vIHNlZSBhYm92ZS4KK3ZvaWQgU2hvd0ludihvYmplY3QgcGxheWVyLCBzdHJpbmcgYXJnKQoreworICBzdHJpbmcgZ2VuZGVyLCB0eXBlOworICBtYXBwaW5nIHBpYzsKKyAgaW50IGk7CisgIG9iamVjdCBpdGVtOworCisgIGlmICghb2JqZWN0cChwbGF5ZXIpfHwhaW50ZXJhY3RpdmUocGxheWVyKSkgcmV0dXJuOworCisgIC8vIHNwbGl0IGFyZ3MuCisgIHN0cmluZyAqYXJnczsKKyAgaWYgKHN0cmluZ3AoYXJnKSkKKyAgICBhcmdzID0gZXhwbG9kZShsb3dlcl9jYXNlKGFyZyksICIgIikgLSAoeyIgIn0pOworICBlbHNlCisgICAgYXJncyA9ICh7fSk7CisKKyAgaWYgKG1lbWJlcihhcmdzLCAiZmFyYmVuIikgPiAtMSkgeworICAgICAgQ29uZmlndXJlQ29sb3JzKCk7CisgICAgICByZXR1cm47CisgIH0KKworICBpZiAobWVtYmVyKGFyZ3MsICItayIpID4gLTEgfHwgcGxheWVyLT5RdWVyeVByb3AoUF9OT19BU0NJSV9BUlQpKSB7CisgICAgdGVsbF9vYmplY3QocGxheWVyLCBTaW1wbGVJbnYocGxheWVyKSk7CisgICAgcmV0dXJuOworICB9CisKKyAgZ2VuZGVyPXBsYXllci0+UXVlcnlQcm9wKFBfR0VOREVSKT09RkVNQUxFPyJfZmVtYWxlIjoiX21hbGUiOworICBwaWM9ZGVlcF9jb3B5KGRhdGFbImJhc2UiK2dlbmRlcl0pOworICBwaWMrPWRhdGFbIkJlc2NocmlmdHVuZyJdOworICBmb3IgKGk9c2l6ZW9mKGFybW91cl90eXBlcyktMTtpPj0wO2ktLSkKKyAgICBpZiAob2JqZWN0cChpdGVtPXBsYXllci0+UXVlcnlBcm1vdXJCeVR5cGUoYXJtb3VyX3R5cGVzW2ldKSkpCisgICAgeworICAgICAgcGljKz1kYXRhW2FybW91cl90eXBlc1tpXStnZW5kZXJdOworICAgICAgQWRkRGVzY3JpcHRpb24ocGljLCBhcm1vdXJfdHlwZXNbaV0sIGl0ZW0pOworICAgIH0KKyAgaWYgKGl0ZW09cGxheWVyLT5RdWVyeVByb3AoUF9XRUFQT04pKQorICB7CisgICAgcGljKz1kYXRhWyhWQUxJRF9XRUFQT05fVFlQRSh0eXBlPWl0ZW0tPlF1ZXJ5UHJvcChQX1dFQVBPTl9UWVBFKSkpPworICAgICAgdHlwZTpXVF9NSVNDXTsKKyAgICBBZGREZXNjcmlwdGlvbihwaWMsICJXYWZmZSIsIGl0ZW0pOworICB9ICAgICAgCisgIGlmIChwbGF5ZXItPlF1ZXJ5UHJvcChQX1RUWSkhPSJhbnNpIikKKyAgICBwbGF5ZXItPk1vcmUoTWFwcGluZzJQbGFpblRleHQocGljKSk7CisgIGVsc2UKKyAgICBwbGF5ZXItPk1vcmUoTWFwcGluZzJDb2xvcmVkVGV4dChwaWMsIHBsYXllcikpOworICBEQihnZXRldWlkKHBsYXllcikrIiBldmFsIGNvc3Q6ICIrKDEwMDAwMDAtZ2V0X2V2YWxfY29zdCgpKSsiIHRpY2tzLlxuIik7Cit9CisK