LyoKICogbXNpZXhlYy5leGUgaW1wbGVtZW50YXRpb24KICoKICogQ29weXJpZ2h0IDIwMDQgVmluY2VudCBC6XJvbgogKiBDb3B5cmlnaHQgMjAwNSBNaWtlIE1jQ29ybWFjawogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojZGVmaW5lIFdJTjMyX0xFQU5fQU5EX01FQU4KCiNpbmNsdWRlIDx3aW5kb3dzLmg+CiNpbmNsdWRlIDxtc2kuaD4KI2luY2x1ZGUgPG9iamJhc2UuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChtc2lleGVjKTsKCnR5cGVkZWYgSFJFU1VMVCAoV0lOQVBJICpETExSRUdJU1RFUlNFUlZFUikodm9pZCk7CnR5cGVkZWYgSFJFU1VMVCAoV0lOQVBJICpETExVTlJFR0lTVEVSU0VSVkVSKSh2b2lkKTsKCkRXT1JEIERvU2VydmljZSh2b2lkKTsKCnN0cnVjdCBzdHJpbmdfbGlzdAp7CglzdHJ1Y3Qgc3RyaW5nX2xpc3QgKm5leHQ7CglXQ0hBUiBzdHJbMV07Cn07CgpzdGF0aWMgY29uc3QgY2hhciBVc2FnZVN0cltdID0KIlVzYWdlOlxuIgoiICBJbnN0YWxsIGEgcHJvZHVjdDpcbiIKIiAgICBtc2lleGVjIHtwYWNrYWdlfHByb2R1Y3Rjb2RlfSBbcHJvcGVydHldXG4iCiIgICAgbXNpZXhlYyAvaSB7cGFja2FnZXxwcm9kdWN0Y29kZX0gW3Byb3BlcnR5XVxuIgoiICAgIG1zaWV4ZWMgL2EgcGFja2FnZSBbcHJvcGVydHldXG4iCiIgIFJlcGFpciBhbiBpbnN0YWxsYXRpb246XG4iCiIgICAgbXNpZXhlYyAvZltwfG98ZXxkfGN8YXx1fG18c3x2XSB7cGFja2FnZXxwcm9kdWN0Y29kZX1cbiIKIiAgVW5pbnN0YWxsIGEgcHJvZHVjdDpcbiIKIiAgICBtc2lleGVjIC94IHtwYWNrYWdlfHByb2R1Y3Rjb2RlfSBbcHJvcGVydHldXG4iCiIgIEFkdmVydGlzZSBhIHByb2R1Y3Q6XG4iCiIgICAgbXNpZXhlYyAvalt1fG1dIHBhY2thZ2UgWy90IHRyYW5zZm9ybV0gWy9nIGxhbmd1YWdlaWRdXG4iCiIgICAgbXNpZXhlYyB7dXxtfSBwYWNrYWdlIFsvdCB0cmFuc2Zvcm1dIFsvZyBsYW5ndWFnZWlkXVxuIgoiICBBcHBseSBhIHBhdGNoOlxuIgoiICAgIG1zaWV4ZWMgL3AgcGF0Y2hwYWNrYWdlIFtwcm9wZXJ0eV1cbiIKIiAgICBtc2lleGVjIC9wIHBhdGNocGFja2FnZSAvYSBwYWNrYWdlIFtwcm9wZXJ0eV1cbiIKIiAgTW9kaWZpZXJzIGZvciBhYm92ZSBvcGVyYXRpb25zOlxuIgoiICAgIG1zaWV4ZWMgL2xbKl1baXx3fGV8YXxyfHV8Y3xtfG98cHx2fF1bK3whXSBsb2dmaWxlXG4iCiIgICAgbXNpZXhlYyAvcXt8bnxifHJ8ZnxuK3xiK3xiLX1cbiIKIiAgUmVnaXN0ZXIgYSBtb2R1bGU6XG4iCiIgICAgbXNpZXhlYyAveSBtb2R1bGVcbiIKIiAgVW5yZWdpc3RlciBhIG1vZHVsZTpcbiIKIiAgICBtc2lleGVjIC96IG1vZHVsZVxuIgoiICBEaXNwbGF5IHVzYWdlIGFuZCBjb3B5cmlnaHQ6XG4iCiIgICAgbXNpZXhlYyB7L2h8Lz99XG4iCiJOT1RFOiBQcm9kdWN0IGNvZGUgb24gY29tbWFuZGxpbmUgdW5pbXBsZW1lbnRlZCBhcyBvZiB5ZXRcbiIKIlxuIgoiQ29weXJpZ2h0IDIwMDQgVmluY2VudCBC6XJvblxuIjsKCnN0YXRpYyBjb25zdCBXQ0hBUiBBY3Rpb25BZG1pbltdID0gewogICAnQScsJ0MnLCdUJywnSScsJ08nLCdOJywnPScsJ0EnLCdEJywnTScsJ0knLCdOJywwIH07CnN0YXRpYyBjb25zdCBXQ0hBUiBSZW1vdmVBbGxbXSA9IHsKICAgJ1InLCdFJywnTScsJ08nLCdWJywnRScsJz0nLCdBJywnTCcsJ0wnLDAgfTsKCnN0YXRpYyBjb25zdCBXQ0hBUiBJbnN0YWxsUnVuT25jZVtdID0gewogICAnUycsJ28nLCdmJywndCcsJ3cnLCdhJywncicsJ2UnLCdcXCcsCiAgICdNJywnaScsJ2MnLCdyJywnbycsJ3MnLCdvJywnZicsJ3QnLCdcXCcsCiAgICdXJywnaScsJ24nLCdkJywnbycsJ3cnLCdzJywnXFwnLAogICAnQycsJ3UnLCdyJywncicsJ2UnLCduJywndCcsJ1YnLCdlJywncicsJ3MnLCdpJywnbycsJ24nLCdcXCcsCiAgICdJJywnbicsJ3MnLCd0JywnYScsJ2wnLCdsJywnZScsJ3InLCdcXCcsCiAgICdSJywndScsJ24nLCdPJywnbicsJ2MnLCdlJywnRScsJ24nLCd0JywncicsJ2knLCdlJywncycsMH07CgpzdGF0aWMgdm9pZCBTaG93VXNhZ2UoaW50IEV4aXRDb2RlKQp7CglwcmludGYoVXNhZ2VTdHIpOwoJRXhpdFByb2Nlc3MoRXhpdENvZGUpOwp9CgpzdGF0aWMgQk9PTCBJc1Byb2R1Y3RDb2RlKExQV1NUUiBzdHIpCnsKCUdVSUQgUHJvZHVjdENvZGU7CgoJaWYobHN0cmxlblcoc3RyKSAhPSAzOCkKCQlyZXR1cm4gRkFMU0U7CglyZXR1cm4gKCAoQ0xTSURGcm9tU3RyaW5nKHN0ciwgJlByb2R1Y3RDb2RlKSA9PSBOT0VSUk9SKSApOwoKfQoKc3RhdGljIFZPSUQgU3RyaW5nTGlzdEFwcGVuZChzdHJ1Y3Qgc3RyaW5nX2xpc3QgKipsaXN0LCBMUENXU1RSIHN0cikKewoJc3RydWN0IHN0cmluZ19saXN0ICplbnRyeTsKCURXT1JEIHNpemU7CgoJc2l6ZSA9IHNpemVvZiAqZW50cnkgKyBsc3RybGVuVyhzdHIpICogc2l6ZW9mIChXQ0hBUik7CgllbnRyeSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplKTsKCWlmKCFlbnRyeSkKCXsKCQlXSU5FX0VSUigiT3V0IG9mIG1lbW9yeSFcbiIpOwoJCUV4aXRQcm9jZXNzKDEpOwoJfQoJbHN0cmNweVcoZW50cnktPnN0ciwgc3RyKTsKCWVudHJ5LT5uZXh0ID0gTlVMTDsKCgkvKgoJICogSWdub3JpbmcgbyhuXjIpIHRpbWUgY29tcGxleGl0eSB0byBhZGQgbiBzdHJpbmdzIGZvciBzaW1wbGljaXR5LAoJICogIGFkZCB0aGUgc3RyaW5nIHRvIHRoZSBlbmQgb2YgdGhlIGxpc3QgdG8gcHJlc2VydmUgdGhlIG9yZGVyLgoJICovCgl3aGlsZSggKmxpc3QgKQoJCWxpc3QgPSAmKCpsaXN0KS0+bmV4dDsKCSpsaXN0ID0gZW50cnk7Cn0KCnN0YXRpYyBMUFdTVFIgYnVpbGRfcHJvcGVydGllcyhzdHJ1Y3Qgc3RyaW5nX2xpc3QgKnByb3BlcnR5X2xpc3QpCnsKCXN0cnVjdCBzdHJpbmdfbGlzdCAqbGlzdDsKCUxQV1NUUiByZXQsIHAsIHZhbHVlOwoJRFdPUkQgbGVuOwoJQk9PTCBuZWVkc19xdW90ZTsKCglpZighcHJvcGVydHlfbGlzdCkKCQlyZXR1cm4gTlVMTDsKCgkvKiBjb3VudCB0aGUgc3BhY2Ugd2UgbmVlZCAqLwoJbGVuID0gMTsKCWZvcihsaXN0ID0gcHJvcGVydHlfbGlzdDsgbGlzdDsgbGlzdCA9IGxpc3QtPm5leHQpCgkJbGVuICs9IGxzdHJsZW5XKGxpc3QtPnN0cikgKyAzOwoKCXJldCA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKnNpemVvZihXQ0hBUikgKTsKCgkvKiBhZGQgYSBzcGFjZSBiZWZvcmUgZWFjaCBzdHJpbmcsIGFuZCBxdW90ZSB0aGUgdmFsdWUgKi8KCXAgPSByZXQ7Cglmb3IobGlzdCA9IHByb3BlcnR5X2xpc3Q7IGxpc3Q7IGxpc3QgPSBsaXN0LT5uZXh0KQoJewoJCXZhbHVlID0gc3RyY2hyVyhsaXN0LT5zdHIsJz0nKTsKCQlpZighdmFsdWUpCgkJCWNvbnRpbnVlOwoJCWxlbiA9IHZhbHVlIC0gbGlzdC0+c3RyOwoJCSpwKysgPSAnICc7CgkJbWVtY3B5KHAsIGxpc3QtPnN0ciwgbGVuICogc2l6ZW9mKFdDSEFSKSk7CgkJcCArPSBsZW47CgkJKnArKyA9ICc9JzsKCgkJLyogY2hlY2sgaWYgdGhlIHZhbHVlIGNvbnRhaW5zIHNwYWNlcyBhbmQgbWF5YmUgcXVvdGUgaXQgKi8KCQl2YWx1ZSsrOwoJCW5lZWRzX3F1b3RlID0gc3RyY2hyVyh2YWx1ZSwnICcpID8gMSA6IDA7CgkJaWYobmVlZHNfcXVvdGUpCgkJCSpwKysgPSAnIic7CgkJbGVuID0gbHN0cmxlblcodmFsdWUpOwoJCW1lbWNweShwLCB2YWx1ZSwgbGVuICogc2l6ZW9mKFdDSEFSKSk7CgkJcCArPSBsZW47CgkJaWYobmVlZHNfcXVvdGUpCgkJCSpwKysgPSAnIic7Cgl9CgkqcCA9IDA7CgoJV0lORV9UUkFDRSgicHJvcGVydGllcyAtPiAlc1xuIiwgd2luZV9kYmdzdHJfdyhyZXQpICk7CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIExQV1NUUiBidWlsZF90cmFuc2Zvcm1zKHN0cnVjdCBzdHJpbmdfbGlzdCAqdHJhbnNmb3JtX2xpc3QpCnsKCXN0cnVjdCBzdHJpbmdfbGlzdCAqbGlzdDsKCUxQV1NUUiByZXQsIHA7CglEV09SRCBsZW47CgoJLyogY291bnQgdGhlIHNwYWNlIHdlIG5lZWQgKi8KCWxlbiA9IDE7Cglmb3IobGlzdCA9IHRyYW5zZm9ybV9saXN0OyBsaXN0OyBsaXN0ID0gbGlzdC0+bmV4dCkKCQlsZW4gKz0gbHN0cmxlblcobGlzdC0+c3RyKSArIDE7CgoJcmV0ID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4qc2l6ZW9mKFdDSEFSKSApOwoKCS8qIGFkZCBhbGwgdGhlIHRyYW5zZm9ybXMgd2l0aCBhIHNlbWljb2xvbiBiZXR3ZWVuIGVhY2ggb25lICovCglwID0gcmV0OwoJZm9yKGxpc3QgPSB0cmFuc2Zvcm1fbGlzdDsgbGlzdDsgbGlzdCA9IGxpc3QtPm5leHQpCgl7CgkJbGVuID0gbHN0cmxlblcobGlzdC0+c3RyKTsKCQlsc3RyY3B5blcocCwgbGlzdC0+c3RyLCBsZW4gKTsKCQlwICs9IGxlbjsKCQlpZihsaXN0LT5uZXh0KQoJCQkqcCsrID0gJzsnOwoJfQoJKnAgPSAwOwoKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBEV09SRCBtc2lfYXRvdShMUENXU1RSIHN0cikKewoJRFdPUkQgcmV0ID0gMDsKCXdoaWxlKCpzdHIgPj0gJzAnICYmICpzdHIgPD0gJzknKQoJewoJCXJldCAqPSAxMDsKCQlyZXQgKz0gKCpzdHIgLSAnMCcpOwoJCXN0cisrOwoJfQoJcmV0dXJuIHJldDsKfQoKc3RhdGljIExQV1NUUiBtc2lfc3RyZHVwKExQQ1dTVFIgc3RyKQp7CglEV09SRCBsZW4gPSBsc3RybGVuVyhzdHIpKzE7CglMUFdTVFIgcmV0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihXQ0hBUikqbGVuKTsKCWxzdHJjcHlXKHJldCwgc3RyKTsKCXJldHVybiByZXQ7Cn0KCi8qIHN0cjEgaXMgdGhlIHNhbWUgYXMgc3RyMiwgaWdub3JpbmcgY2FzZSAqLwpzdGF0aWMgQk9PTCBtc2lfc3RyZXF1YWwoTFBDV1NUUiBzdHIxLCBMUENTVFIgc3RyMikKewoJRFdPUkQgbGVuLCByZXQ7CglMUFdTVFIgc3RyVzsKCglsZW4gPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKCBDUF9BQ1AsIDAsIHN0cjIsIC0xLCBOVUxMLCAwKTsKCWlmKCAhbGVuICkKCQlyZXR1cm4gRkFMU0U7CglpZiggbHN0cmxlblcoc3RyMSkgIT0gKGxlbi0xKSApCgkJcmV0dXJuIEZBTFNFOwoJc3RyVyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoV0NIQVIpKmxlbik7CglNdWx0aUJ5dGVUb1dpZGVDaGFyKCBDUF9BQ1AsIDAsIHN0cjIsIC0xLCBzdHJXLCBsZW4pOwoJcmV0ID0gQ29tcGFyZVN0cmluZ1coR2V0VGhyZWFkTG9jYWxlKCksIE5PUk1fSUdOT1JFQ0FTRSwgc3RyMSwgbGVuLCBzdHJXLCBsZW4pOwoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RyVyk7CglyZXR1cm4gKHJldCA9PSBDU1RSX0VRVUFMKTsKfQoKLyogcHJlZml4IGlzIGh5cGhlbiBvciBkYXNoLCBhbmQgc3RyMSBpcyB0aGUgc2FtZSBhcyBzdHIyLCBpZ25vcmluZyBjYXNlICovCnN0YXRpYyBCT09MIG1zaV9vcHRpb25fZXF1YWwoTFBDV1NUUiBzdHIxLCBMUENTVFIgc3RyMikKewogICAgaWYgKHN0cjFbMF0gIT0gJy8nICYmIHN0cjFbMF0gIT0gJy0nKQogICAgICAgIHJldHVybiBGQUxTRTsKCiAgICAvKiBza2lwIG92ZXIgdGhlIGh5cGhlbiBvciBzbGFzaCAqLwogICAgcmV0dXJuIG1zaV9zdHJlcXVhbChzdHIxICsgMSwgc3RyMik7Cn0KCi8qIHN0cjIgaXMgYXQgdGhlIGJlZ2lubmluZyBvZiBzdHIxLCBpZ25vcmluZyBjYXNlICovCnN0YXRpYyBCT09MIG1zaV9zdHJwcmVmaXgoTFBDV1NUUiBzdHIxLCBMUENTVFIgc3RyMikKewoJRFdPUkQgbGVuLCByZXQ7CglMUFdTVFIgc3RyVzsKCglsZW4gPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKCBDUF9BQ1AsIDAsIHN0cjIsIC0xLCBOVUxMLCAwKTsKCWlmKCAhbGVuICkKCQlyZXR1cm4gRkFMU0U7CglpZiggbHN0cmxlblcoc3RyMSkgPCAobGVuLTEpICkKCQlyZXR1cm4gRkFMU0U7CglzdHJXID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihXQ0hBUikqbGVuKTsKCU11bHRpQnl0ZVRvV2lkZUNoYXIoIENQX0FDUCwgMCwgc3RyMiwgLTEsIHN0clcsIGxlbik7CglyZXQgPSBDb21wYXJlU3RyaW5nVyhHZXRUaHJlYWRMb2NhbGUoKSwgTk9STV9JR05PUkVDQVNFLCBzdHIxLCBsZW4tMSwgc3RyVywgbGVuLTEpOwoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RyVyk7CglyZXR1cm4gKHJldCA9PSBDU1RSX0VRVUFMKTsKfQoKLyogcHJlZml4IGlzIGh5cGhlbiBvciBkYXNoLCBhbmQgc3RyMiBpcyBhdCB0aGUgYmVnaW5uaW5nIG9mIHN0cjEsIGlnbm9yaW5nIGNhc2UgKi8Kc3RhdGljIEJPT0wgbXNpX29wdGlvbl9wcmVmaXgoTFBDV1NUUiBzdHIxLCBMUENTVFIgc3RyMikKewogICAgaWYgKHN0cjFbMF0gIT0gJy8nICYmIHN0cjFbMF0gIT0gJy0nKQogICAgICAgIHJldHVybiBGQUxTRTsKCiAgICAvKiBza2lwIG92ZXIgdGhlIGh5cGhlbiBvciBzbGFzaCAqLwogICAgcmV0dXJuIG1zaV9zdHJwcmVmaXgoc3RyMSArIDEsIHN0cjIpOwp9CgpzdGF0aWMgVk9JRCAqTG9hZFByb2MoTFBDV1NUUiBEbGxOYW1lLCBMUENTVFIgUHJvY05hbWUsIEhNT0RVTEUqIERsbEhhbmRsZSkKewoJVk9JRCogKCpwcm9jKSh2b2lkKTsKCgkqRGxsSGFuZGxlID0gTG9hZExpYnJhcnlFeFcoRGxsTmFtZSwgTlVMTCwgTE9BRF9XSVRIX0FMVEVSRURfU0VBUkNIX1BBVEgpOwoJaWYoISpEbGxIYW5kbGUpCgl7CgkJZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9hZCBkbGwgJXNcbiIsIHdpbmVfZGJnc3RyX3coRGxsTmFtZSkpOwoJCUV4aXRQcm9jZXNzKDEpOwoJfQoJcHJvYyA9IChWT0lEICopIEdldFByb2NBZGRyZXNzKCpEbGxIYW5kbGUsIFByb2NOYW1lKTsKCWlmKCFwcm9jKQoJewoJCWZwcmludGYoc3RkZXJyLCAiRGxsICVzIGRvZXMgbm90IGltcGxlbWVudCBmdW5jdGlvbiAlc1xuIiwKCQkJd2luZV9kYmdzdHJfdyhEbGxOYW1lKSwgUHJvY05hbWUpOwoJCUZyZWVMaWJyYXJ5KCpEbGxIYW5kbGUpOwoJCUV4aXRQcm9jZXNzKDEpOwoJfQoKCXJldHVybiBwcm9jOwp9CgpzdGF0aWMgRFdPUkQgRG9EbGxSZWdpc3RlclNlcnZlcihMUENXU1RSIERsbE5hbWUpCnsKCUhSRVNVTFQgaHI7CglETExSRUdJU1RFUlNFUlZFUiBwZkRsbFJlZ2lzdGVyU2VydmVyID0gTlVMTDsKCUhNT0RVTEUgRGxsSGFuZGxlID0gTlVMTDsKCglwZkRsbFJlZ2lzdGVyU2VydmVyID0gTG9hZFByb2MoRGxsTmFtZSwgIkRsbFJlZ2lzdGVyU2VydmVyIiwgJkRsbEhhbmRsZSk7CgoJaHIgPSBwZkRsbFJlZ2lzdGVyU2VydmVyKCk7CglpZihGQUlMRUQoaHIpKQoJewoJCWZwcmludGYoc3RkZXJyLCAiRmFpbGVkIHRvIHJlZ2lzdGVyIGRsbCAlc1xuIiwgd2luZV9kYmdzdHJfdyhEbGxOYW1lKSk7CgkJcmV0dXJuIDE7Cgl9CglwcmludGYoIlN1Y2Nlc3NmdWxseSByZWdpc3RlcmVkIGRsbCAlc1xuIiwgd2luZV9kYmdzdHJfdyhEbGxOYW1lKSk7CglpZihEbGxIYW5kbGUpCgkJRnJlZUxpYnJhcnkoRGxsSGFuZGxlKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgRFdPUkQgRG9EbGxVbnJlZ2lzdGVyU2VydmVyKExQQ1dTVFIgRGxsTmFtZSkKewoJSFJFU1VMVCBocjsKCURMTFVOUkVHSVNURVJTRVJWRVIgcGZEbGxVbnJlZ2lzdGVyU2VydmVyID0gTlVMTDsKCUhNT0RVTEUgRGxsSGFuZGxlID0gTlVMTDsKCglwZkRsbFVucmVnaXN0ZXJTZXJ2ZXIgPSBMb2FkUHJvYyhEbGxOYW1lLCAiRGxsVW5yZWdpc3RlclNlcnZlciIsICZEbGxIYW5kbGUpOwoKCWhyID0gcGZEbGxVbnJlZ2lzdGVyU2VydmVyKCk7CglpZihGQUlMRUQoaHIpKQoJewoJCWZwcmludGYoc3RkZXJyLCAiRmFpbGVkIHRvIHVucmVnaXN0ZXIgZGxsICVzXG4iLCB3aW5lX2RiZ3N0cl93KERsbE5hbWUpKTsKCQlyZXR1cm4gMTsKCX0KCXByaW50ZigiU3VjY2Vzc2Z1bGx5IHVucmVnaXN0ZXJlZCBkbGwgJXNcbiIsIHdpbmVfZGJnc3RyX3coRGxsTmFtZSkpOwoJaWYoRGxsSGFuZGxlKQoJCUZyZWVMaWJyYXJ5KERsbEhhbmRsZSk7CglyZXR1cm4gMDsKfQoKc3RhdGljIERXT1JEIERvUmVnU2VydmVyKHZvaWQpCnsKICAgIFNDX0hBTkRMRSBzY20sIHNlcnZpY2U7CiAgICBDSEFSIHBhdGhbTUFYX1BBVEgrMTJdOwogICAgRFdPUkQgcmV0ID0gMDsKCiAgICBzY20gPSBPcGVuU0NNYW5hZ2VyKE5VTEwsIFNFUlZJQ0VTX0FDVElWRV9EQVRBQkFTRSwgU0NfTUFOQUdFUl9DUkVBVEVfU0VSVklDRSk7CiAgICBpZiAoIXNjbSkKICAgIHsKICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIkZhaWxlZCB0byBvcGVuIHRoZSBzZXJ2aWNlIGNvbnRyb2wgbWFuYWdlci5cbiIpOwogICAgICAgIHJldHVybiAxOwogICAgfQoKICAgIEdldFN5c3RlbURpcmVjdG9yeShwYXRoLCBNQVhfUEFUSCk7CiAgICBsc3RyY2F0QShwYXRoLCAiXFxtc2lleGVjLmV4ZSAvViIpOwoKICAgIHNlcnZpY2UgPSBDcmVhdGVTZXJ2aWNlQShzY20sICJNU0lTZXJ2ZXIiLCAiTVNJU2VydmVyIiwgR0VORVJJQ19BTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0VSVklDRV9XSU4zMl9TSEFSRV9QUk9DRVNTLCBTRVJWSUNFX0RFTUFORF9TVEFSVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTRVJWSUNFX0VSUk9SX05PUk1BTCwgcGF0aCwgTlVMTCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMLCBOVUxMKTsKCiAgICBpZiAoc2VydmljZSkgQ2xvc2VTZXJ2aWNlSGFuZGxlKHNlcnZpY2UpOwogICAgZWxzZSBpZiAoR2V0TGFzdEVycm9yKCkgIT0gRVJST1JfU0VSVklDRV9FWElTVFMpCiAgICB7CiAgICAgICAgZnByaW50ZihzdGRlcnIsICJGYWlsZWQgdG8gY3JlYXRlIE1TSSBzZXJ2aWNlXG4iKTsKICAgICAgICByZXQgPSAxOwogICAgfQogICAgQ2xvc2VTZXJ2aWNlSGFuZGxlKHNjbSk7CiAgICByZXR1cm4gcmV0Owp9CgpzdGF0aWMgSU5UIERvRW1iZWRkaW5nKCBMUFdTVFIga2V5ICkKewoJcHJpbnRmKCJSZW1vdGUgY3VzdG9tIGFjdGlvbnMgYXJlIG5vdCBzdXBwb3J0ZWQgeWV0XG4iKTsKCXJldHVybiAxOwp9CgovKgogKiBzdGF0ZSBtYWNoaW5lIHRvIGJyZWFrIHVwIHRoZSBjb21tYW5kIGxpbmUgcHJvcGVybHkKICovCgplbnVtIGNob21wX3N0YXRlCnsKCWNzX3doaXRlc3BhY2UsCgljc190b2tlbiwKCWNzX3F1b3RlCn07CgpzdGF0aWMgaW50IGNob21wKCBXQ0hBUiAqc3RyICkKewoJZW51bSBjaG9tcF9zdGF0ZSBzdGF0ZSA9IGNzX3doaXRlc3BhY2U7CglXQ0hBUiAqcCwgKm91dDsKCWludCBjb3VudCA9IDAsIGlnbm9yZTsKCglmb3IoIHAgPSBzdHIsIG91dCA9IHN0cjsgKnA7IHArKyApCgl7CgkJaWdub3JlID0gMTsKCQlzd2l0Y2goIHN0YXRlICkKCQl7CgkJY2FzZSBjc193aGl0ZXNwYWNlOgoJCQlzd2l0Y2goICpwICkKCQkJewoJCQljYXNlICcgJzoKCQkJCWJyZWFrOwoJCQljYXNlICciJzoKCQkJCXN0YXRlID0gY3NfcXVvdGU7CgkJCQljb3VudCsrOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQljb3VudCsrOwoJCQkJaWdub3JlID0gMDsKCQkJCXN0YXRlID0gY3NfdG9rZW47CgkJCX0KCQkJYnJlYWs7CgoJCWNhc2UgY3NfdG9rZW46CgkJCXN3aXRjaCggKnAgKQoJCQl7CgkJCWNhc2UgJyInOgoJCQkJc3RhdGUgPSBjc19xdW90ZTsKCQkJCWJyZWFrOwoJCQljYXNlICcgJzoKCQkJCXN0YXRlID0gY3Nfd2hpdGVzcGFjZTsKCQkJCSpvdXQrKyA9IDA7CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCWlnbm9yZSA9IDA7CgkJCX0KCQkJYnJlYWs7CgoJCWNhc2UgY3NfcXVvdGU6CgkJCXN3aXRjaCggKnAgKQoJCQl7CgkJCWNhc2UgJyInOgoJCQkJc3RhdGUgPSBjc190b2tlbjsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJaWdub3JlID0gMDsKCQkJfQoJCQlicmVhazsKCQl9CgkJaWYoICFpZ25vcmUgKQoJCQkqb3V0KysgPSAqcDsKCX0KCgkqb3V0ID0gMDsKCglyZXR1cm4gY291bnQ7Cn0KCnN0YXRpYyB2b2lkIHByb2Nlc3NfYXJncyggV0NIQVIgKmNtZGxpbmUsIGludCAqcGFyZ2MsIFdDSEFSICoqKnBhcmd2ICkKewoJV0NIQVIgKiphcmd2LCAqcCA9IG1zaV9zdHJkdXAoY21kbGluZSk7CglpbnQgaSwgbjsKCgluID0gY2hvbXAoIHAgKTsKCWFyZ3YgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mIChXQ0hBUiopKihuKzEpKTsKCWZvciggaT0wOyBpPG47IGkrKyApCgl7CgkJYXJndltpXSA9IHA7CgkJcCArPSBsc3RybGVuVyhwKSArIDE7Cgl9Cglhcmd2W2ldID0gTlVMTDsKCgkqcGFyZ2MgPSBuOwoJKnBhcmd2ID0gYXJndjsKfQoKc3RhdGljIEJPT0wgcHJvY2Vzc19hcmdzX2Zyb21fcmVnKCBMUFdTVFIgaWRlbnQsIGludCAqcGFyZ2MsIFdDSEFSICoqKnBhcmd2ICkKewoJTE9ORyByOwoJSEtFWSBoa2V5ID0gMCwgaGtleUFyZ3MgPSAwOwoJRFdPUkQgc3ogPSAwLCB0eXBlID0gMDsKCUxQV1NUUiBidWYgPSBOVUxMOwoJQk9PTCByZXQgPSBGQUxTRTsKCglyID0gUmVnT3BlbktleVcoSEtFWV9MT0NBTF9NQUNISU5FLCBJbnN0YWxsUnVuT25jZSwgJmhrZXkpOwoJaWYociAhPSBFUlJPUl9TVUNDRVNTKQoJCXJldHVybiBGQUxTRTsKCXIgPSBSZWdRdWVyeVZhbHVlRXhXKGhrZXksIGlkZW50LCAwLCAmdHlwZSwgMCwgJnN6KTsKCWlmKHIgPT0gRVJST1JfU1VDQ0VTUyAmJiB0eXBlID09IFJFR19TWikKCXsKCQlidWYgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3opOwoJCXIgPSBSZWdRdWVyeVZhbHVlRXhXKGhrZXksIGlkZW50LCAwLCAmdHlwZSwgKExQQllURSlidWYsICZzeik7CgkJaWYoIHIgPT0gRVJST1JfU1VDQ0VTUyApCgkJewoJCQlwcm9jZXNzX2FyZ3MoYnVmLCBwYXJnYywgcGFyZ3YpOwoJCQlyZXQgPSBUUlVFOwoJCX0KCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBidWYpOwoJfQoJUmVnQ2xvc2VLZXkoaGtleUFyZ3MpOwoJcmV0dXJuIHJldDsKfQoKaW50IG1haW4oaW50IGFyZ2MsIGNoYXIgKiphcmd2KQp7CglpbnQgaTsKCUJPT0wgRnVuY3Rpb25JbnN0YWxsID0gRkFMU0U7CglCT09MIEZ1bmN0aW9uSW5zdGFsbEFkbWluID0gRkFMU0U7CglCT09MIEZ1bmN0aW9uUmVwYWlyID0gRkFMU0U7CglCT09MIEZ1bmN0aW9uQWR2ZXJ0aXNlID0gRkFMU0U7CglCT09MIEZ1bmN0aW9uUGF0Y2ggPSBGQUxTRTsKCUJPT0wgRnVuY3Rpb25EbGxSZWdpc3RlclNlcnZlciA9IEZBTFNFOwoJQk9PTCBGdW5jdGlvbkRsbFVucmVnaXN0ZXJTZXJ2ZXIgPSBGQUxTRTsKCUJPT0wgRnVuY3Rpb25SZWdTZXJ2ZXIgPSBGQUxTRTsKCUJPT0wgRnVuY3Rpb25VbnJlZ1NlcnZlciA9IEZBTFNFOwoJQk9PTCBGdW5jdGlvblNlcnZlciA9IEZBTFNFOwoJQk9PTCBGdW5jdGlvblVua25vd24gPSBGQUxTRTsKCglMUFdTVFIgUGFja2FnZU5hbWUgPSBOVUxMOwoJTFBXU1RSIFByb3BlcnRpZXMgPSBOVUxMOwoJc3RydWN0IHN0cmluZ19saXN0ICpwcm9wZXJ0eV9saXN0ID0gTlVMTDsKCglEV09SRCBSZXBhaXJNb2RlID0gMDsKCglEV09SRF9QVFIgQWR2ZXJ0aXNlTW9kZSA9IDA7CglzdHJ1Y3Qgc3RyaW5nX2xpc3QgKnRyYW5zZm9ybV9saXN0ID0gTlVMTDsKCUxBTkdJRCBMYW5ndWFnZSA9IDA7CgoJRFdPUkQgTG9nTW9kZSA9IDA7CglMUFdTVFIgTG9nRmlsZU5hbWUgPSBOVUxMOwoJRFdPUkQgTG9nQXR0cmlidXRlcyA9IDA7CgoJTFBXU1RSIFBhdGNoRmlsZU5hbWUgPSBOVUxMOwoJSU5TVEFMTFRZUEUgSW5zdGFsbFR5cGUgPSBJTlNUQUxMVFlQRV9ERUZBVUxUOwoKCUlOU1RBTExVSUxFVkVMIEluc3RhbGxVSUxldmVsID0gSU5TVEFMTFVJTEVWRUxfRlVMTDsKCglMUFdTVFIgRGxsTmFtZSA9IE5VTEw7CglEV09SRCBSZXR1cm5Db2RlOwoJTFBXU1RSICphcmd2VyA9IE5VTEw7CgoJLyogb3ZlcndyaXRlIHRoZSBjb21tYW5kIGxpbmUgKi8KCXByb2Nlc3NfYXJncyggR2V0Q29tbWFuZExpbmVXKCksICZhcmdjLCAmYXJndlcgKTsKCgkvKgoJICogSWYgdGhlIGFyZ3MgYmVnaW4gd2l0aCAvQCBJREVOVCB0aGVuIHdlIG5lZWQgdG8gbG9hZCB0aGUgcmVhbAoJICogY29tbWFuZCBsaW5lIG91dCBvZiB0aGUgUnVuT25jZUVudHJpZXMga2V5IGluIHRoZSByZWdpc3RyeS4KCSAqICBXZSBkbyB0aGF0IGJlZm9yZSBzdGFydGluZyB0byBwcm9jZXNzIHRoZSByZWFsIGNvbW1hbmRsaW5lLAoJICogdGhlbiBvdmVyd3JpdGUgdGhlIGNvbW1hbmRsaW5lIGFnYWluLgoJICovCglpZihhcmdjPjEgJiYgbXNpX29wdGlvbl9lcXVhbChhcmd2V1sxXSwgIkAiKSkKCXsKCQlpZighcHJvY2Vzc19hcmdzX2Zyb21fcmVnKCBhcmd2V1syXSwgJmFyZ2MsICZhcmd2VyApKQoJCQlyZXR1cm4gMTsKCX0KCglpZiAoYXJnYyA9PSAzICYmIG1zaV9vcHRpb25fZXF1YWwoYXJndldbMV0sICJFbWJlZGRpbmciKSkKCQlyZXR1cm4gRG9FbWJlZGRpbmcoIGFyZ3ZXWzJdICk7CgoJZm9yKGkgPSAxOyBpIDwgYXJnYzsgaSsrKQoJewoJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgoJCWlmIChtc2lfb3B0aW9uX2VxdWFsKGFyZ3ZXW2ldLCAicmVnc2VydmVyIikpCgkJewoJCQlGdW5jdGlvblJlZ1NlcnZlciA9IFRSVUU7CgkJfQoJCWVsc2UgaWYgKG1zaV9vcHRpb25fZXF1YWwoYXJndldbaV0sICJ1bnJlZ3NlcnZlciIpIHx8IG1zaV9vcHRpb25fZXF1YWwoYXJndldbaV0sICJ1bnJlZ2lzdGVyIikpCgkJewoJCQlGdW5jdGlvblVucmVnU2VydmVyID0gVFJVRTsKCQl9CgkJZWxzZSBpZihtc2lfb3B0aW9uX3ByZWZpeChhcmd2V1tpXSwgImkiKSkKCQl7CgkJCUxQV1NUUiBhcmd2V2kgPSBhcmd2V1tpXTsKCQkJRnVuY3Rpb25JbnN0YWxsID0gVFJVRTsKCQkJaWYobHN0cmxlblcoYXJndldpKSA+IDIpCgkJCQlhcmd2V2kgKz0gMjsKCQkJZWxzZQoJCQl7CgkJCQlpKys7CgkJCQlpZihpID49IGFyZ2MpCgkJCQkJU2hvd1VzYWdlKDEpOwoJCQkJV0lORV9UUkFDRSgiYXJndldbJWRdID0gJXNcbiIsIGksIHdpbmVfZGJnc3RyX3coYXJndldbaV0pKTsKCQkJCWFyZ3ZXaSA9IGFyZ3ZXW2ldOwoJCQl9CgkJCVBhY2thZ2VOYW1lID0gYXJndldpOwoJCX0KCQllbHNlIGlmKG1zaV9vcHRpb25fZXF1YWwoYXJndldbaV0sICJhIikpCgkJewoJCQlGdW5jdGlvbkluc3RhbGwgPSBUUlVFOwoJCQlGdW5jdGlvbkluc3RhbGxBZG1pbiA9IFRSVUU7CgkJCUluc3RhbGxUeXBlID0gSU5TVEFMTFRZUEVfTkVUV09SS19JTUFHRTsKCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgkJCVBhY2thZ2VOYW1lID0gYXJndldbaV07CgkJCVN0cmluZ0xpc3RBcHBlbmQoJnByb3BlcnR5X2xpc3QsIEFjdGlvbkFkbWluKTsKCQl9CgkJZWxzZSBpZihtc2lfb3B0aW9uX3ByZWZpeChhcmd2V1tpXSwgImYiKSkKCQl7CgkJCWludCBqOwoJCQlpbnQgbGVuID0gbHN0cmxlblcoYXJndldbaV0pOwoJCQlGdW5jdGlvblJlcGFpciA9IFRSVUU7CgkJCWZvcihqID0gMjsgaiA8IGxlbjsgaisrKQoJCQl7CgkJCQlzd2l0Y2goYXJndldbaV1bal0pCgkJCQl7CgkJCQkJY2FzZSAnUCc6CgkJCQkJY2FzZSAncCc6CgkJCQkJCVJlcGFpck1vZGUgfD0gUkVJTlNUQUxMTU9ERV9GSUxFTUlTU0lORzsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnTyc6CgkJCQkJY2FzZSAnbyc6CgkJCQkJCVJlcGFpck1vZGUgfD0gUkVJTlNUQUxMTU9ERV9GSUxFT0xERVJWRVJTSU9OOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdFJzoKCQkJCQljYXNlICdlJzoKCQkJCQkJUmVwYWlyTW9kZSB8PSBSRUlOU1RBTExNT0RFX0ZJTEVFUVVBTFZFUlNJT047CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ0QnOgoJCQkJCWNhc2UgJ2QnOgoJCQkJCQlSZXBhaXJNb2RlIHw9IFJFSU5TVEFMTE1PREVfRklMRUVYQUNUOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdDJzoKCQkJCQljYXNlICdjJzoKCQkJCQkJUmVwYWlyTW9kZSB8PSBSRUlOU1RBTExNT0RFX0ZJTEVWRVJJRlk7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ0EnOgoJCQkJCWNhc2UgJ2EnOgoJCQkJCQlSZXBhaXJNb2RlIHw9IFJFSU5TVEFMTE1PREVfRklMRVJFUExBQ0U7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ1UnOgoJCQkJCWNhc2UgJ3UnOgoJCQkJCQlSZXBhaXJNb2RlIHw9IFJFSU5TVEFMTE1PREVfVVNFUkRBVEE7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ00nOgoJCQkJCWNhc2UgJ20nOgoJCQkJCQlSZXBhaXJNb2RlIHw9IFJFSU5TVEFMTE1PREVfTUFDSElORURBVEE7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ1MnOgoJCQkJCWNhc2UgJ3MnOgoJCQkJCQlSZXBhaXJNb2RlIHw9IFJFSU5TVEFMTE1PREVfU0hPUlRDVVQ7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ1YnOgoJCQkJCWNhc2UgJ3YnOgoJCQkJCQlSZXBhaXJNb2RlIHw9IFJFSU5TVEFMTE1PREVfUEFDS0FHRTsKCQkJCQkJYnJlYWs7CgkJCQkJZGVmYXVsdDoKCQkJCQkJZnByaW50ZihzdGRlcnIsICJVbmtub3duIG9wdGlvbiBcIiVjXCIgaW4gUmVwYWlyIG1vZGVcbiIsIGFyZ3ZXW2ldW2pdKTsKCQkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQkJaWYobGVuID09IDIpCgkJCXsKCQkJCVJlcGFpck1vZGUgPSBSRUlOU1RBTExNT0RFX0ZJTEVNSVNTSU5HIHwKCQkJCQlSRUlOU1RBTExNT0RFX0ZJTEVFUVVBTFZFUlNJT04gfAoJCQkJCVJFSU5TVEFMTE1PREVfRklMRVZFUklGWSB8CgkJCQkJUkVJTlNUQUxMTU9ERV9NQUNISU5FREFUQSB8CgkJCQkJUkVJTlNUQUxMTU9ERV9TSE9SVENVVDsKCQkJfQoJCQlpKys7CgkJCWlmKGkgPj0gYXJnYykKCQkJCVNob3dVc2FnZSgxKTsKCQkJV0lORV9UUkFDRSgiYXJndldbJWRdID0gJXNcbiIsIGksIHdpbmVfZGJnc3RyX3coYXJndldbaV0pKTsKCQkJUGFja2FnZU5hbWUgPSBhcmd2V1tpXTsKCQl9CgkJZWxzZSBpZihtc2lfb3B0aW9uX3ByZWZpeChhcmd2V1tpXSwgIngiKSkKCQl7CgkJCUZ1bmN0aW9uSW5zdGFsbCA9IFRSVUU7CgkJCVBhY2thZ2VOYW1lID0gYXJndldbaV0rMjsKCQkJaWYgKCFQYWNrYWdlTmFtZVswXSkKCQkJewoJCQkJaSsrOwoJCQkJaWYgKGkgPj0gYXJnYykKCQkJCQlTaG93VXNhZ2UoMSk7CgkJCQlQYWNrYWdlTmFtZSA9IGFyZ3ZXW2ldOwoJCQl9CgkJCVdJTkVfVFJBQ0UoIlBhY2thZ2VOYW1lID0gJXNcbiIsIHdpbmVfZGJnc3RyX3coUGFja2FnZU5hbWUpKTsKCQkJU3RyaW5nTGlzdEFwcGVuZCgmcHJvcGVydHlfbGlzdCwgUmVtb3ZlQWxsKTsKCQl9CgkJZWxzZSBpZihtc2lfb3B0aW9uX3ByZWZpeChhcmd2V1tpXSwgImoiKSkKCQl7CgkJCWludCBqOwoJCQlpbnQgbGVuID0gbHN0cmxlblcoYXJndldbaV0pOwoJCQlGdW5jdGlvbkFkdmVydGlzZSA9IFRSVUU7CgkJCWZvcihqID0gMjsgaiA8IGxlbjsgaisrKQoJCQl7CgkJCQlzd2l0Y2goYXJndldbaV1bal0pCgkJCQl7CgkJCQkJY2FzZSAnVSc6CgkJCQkJY2FzZSAndSc6CgkJCQkJCUFkdmVydGlzZU1vZGUgPSBBRFZFUlRJU0VGTEFHU19VU0VSQVNTSUdOOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdNJzoKCQkJCQljYXNlICdtJzoKCQkJCQkJQWR2ZXJ0aXNlTW9kZSA9IEFEVkVSVElTRUZMQUdTX01BQ0hJTkVBU1NJR047CgkJCQkJCWJyZWFrOwoJCQkJCWRlZmF1bHQ6CgkJCQkJCWZwcmludGYoc3RkZXJyLCAiVW5rbm93biBvcHRpb24gXCIlY1wiIGluIEFkdmVydGlzZSBtb2RlXG4iLCBhcmd2V1tpXVtqXSk7CgkJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoJCQlQYWNrYWdlTmFtZSA9IGFyZ3ZXW2ldOwoJCX0KCQllbHNlIGlmKG1zaV9zdHJlcXVhbChhcmd2V1tpXSwgInUiKSkKCQl7CgkJCUZ1bmN0aW9uQWR2ZXJ0aXNlID0gVFJVRTsKCQkJQWR2ZXJ0aXNlTW9kZSA9IEFEVkVSVElTRUZMQUdTX1VTRVJBU1NJR047CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoJCQlQYWNrYWdlTmFtZSA9IGFyZ3ZXW2ldOwoJCX0KCQllbHNlIGlmKG1zaV9zdHJlcXVhbChhcmd2V1tpXSwgIm0iKSkKCQl7CgkJCUZ1bmN0aW9uQWR2ZXJ0aXNlID0gVFJVRTsKCQkJQWR2ZXJ0aXNlTW9kZSA9IEFEVkVSVElTRUZMQUdTX01BQ0hJTkVBU1NJR047CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoJCQlQYWNrYWdlTmFtZSA9IGFyZ3ZXW2ldOwoJCX0KCQllbHNlIGlmKG1zaV9vcHRpb25fZXF1YWwoYXJndldbaV0sICJ0IikpCgkJewoJCQlpKys7CgkJCWlmKGkgPj0gYXJnYykKCQkJCVNob3dVc2FnZSgxKTsKCQkJV0lORV9UUkFDRSgiYXJndldbJWRdID0gJXNcbiIsIGksIHdpbmVfZGJnc3RyX3coYXJndldbaV0pKTsKCQkJU3RyaW5nTGlzdEFwcGVuZCgmdHJhbnNmb3JtX2xpc3QsIGFyZ3ZXW2ldKTsKCQl9CgkJZWxzZSBpZihtc2lfb3B0aW9uX2VxdWFsKGFyZ3ZXW2ldLCAiZyIpKQoJCXsKCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgkJCUxhbmd1YWdlID0gbXNpX2F0b3UoYXJndldbaV0pOwoJCX0KCQllbHNlIGlmKG1zaV9vcHRpb25fcHJlZml4KGFyZ3ZXW2ldLCAibCIpKQoJCXsKCQkJaW50IGo7CgkJCWludCBsZW4gPSBsc3RybGVuVyhhcmd2V1tpXSk7CgkJCWZvcihqID0gMjsgaiA8IGxlbjsgaisrKQoJCQl7CgkJCQlzd2l0Y2goYXJndldbaV1bal0pCgkJCQl7CgkJCQkJY2FzZSAnSSc6CgkJCQkJY2FzZSAnaSc6CgkJCQkJCUxvZ01vZGUgfD0gSU5TVEFMTExPR01PREVfSU5GTzsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnVyc6CgkJCQkJY2FzZSAndyc6CgkJCQkJCUxvZ01vZGUgfD0gSU5TVEFMTExPR01PREVfV0FSTklORzsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnRSc6CgkJCQkJY2FzZSAnZSc6CgkJCQkJCUxvZ01vZGUgfD0gSU5TVEFMTExPR01PREVfRVJST1I7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ0EnOgoJCQkJCWNhc2UgJ2EnOgoJCQkJCQlMb2dNb2RlIHw9IElOU1RBTExMT0dNT0RFX0FDVElPTlNUQVJUOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdSJzoKCQkJCQljYXNlICdyJzoKCQkJCQkJTG9nTW9kZSB8PSBJTlNUQUxMTE9HTU9ERV9BQ1RJT05EQVRBOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdVJzoKCQkJCQljYXNlICd1JzoKCQkJCQkJTG9nTW9kZSB8PSBJTlNUQUxMTE9HTU9ERV9VU0VSOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdDJzoKCQkJCQljYXNlICdjJzoKCQkJCQkJTG9nTW9kZSB8PSBJTlNUQUxMTE9HTU9ERV9DT01NT05EQVRBOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdNJzoKCQkJCQljYXNlICdtJzoKCQkJCQkJTG9nTW9kZSB8PSBJTlNUQUxMTE9HTU9ERV9GQVRBTEVYSVQ7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ08nOgoJCQkJCWNhc2UgJ28nOgoJCQkJCQlMb2dNb2RlIHw9IElOU1RBTExMT0dNT0RFX09VVE9GRElTS1NQQUNFOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdQJzoKCQkJCQljYXNlICdwJzoKCQkJCQkJTG9nTW9kZSB8PSBJTlNUQUxMTE9HTU9ERV9QUk9QRVJUWURVTVA7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ1YnOgoJCQkJCWNhc2UgJ3YnOgoJCQkJCQlMb2dNb2RlIHw9IElOU1RBTExMT0dNT0RFX1ZFUkJPU0U7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJyonOgoJCQkJCQlMb2dNb2RlID0gSU5TVEFMTExPR01PREVfRkFUQUxFWElUIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX0VSUk9SIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX1dBUk5JTkcgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfVVNFUiB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9JTkZPIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX1JFU09MVkVTT1VSQ0UgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfT1VUT0ZESVNLU1BBQ0UgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfQUNUSU9OU1RBUlQgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfQUNUSU9OREFUQSB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9DT01NT05EQVRBIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX1BST1BFUlRZRFVNUCB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9QUk9HUkVTUyB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9JTklUSUFMSVpFIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX1RFUk1JTkFURSB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9TSE9XRElBTE9HOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICcrJzoKCQkJCQkJTG9nQXR0cmlidXRlcyB8PSBJTlNUQUxMTE9HQVRUUklCVVRFU19BUFBFTkQ7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJyEnOgoJCQkJCQlMb2dBdHRyaWJ1dGVzIHw9IElOU1RBTExMT0dBVFRSSUJVVEVTX0ZMVVNIRUFDSExJTkU7CgkJCQkJCWJyZWFrOwoJCQkJCWRlZmF1bHQ6CgkJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoJCQlMb2dGaWxlTmFtZSA9IGFyZ3ZXW2ldOwoJCQlpZihNc2lFbmFibGVMb2dXKExvZ01vZGUsIExvZ0ZpbGVOYW1lLCBMb2dBdHRyaWJ1dGVzKSAhPSBFUlJPUl9TVUNDRVNTKQoJCQl7CgkJCQlmcHJpbnRmKHN0ZGVyciwgIkxvZ2dpbmcgaW4gJXMgKDB4JTA4eCwgJXUpIGZhaWxlZFxuIiwKCQkJCQkgd2luZV9kYmdzdHJfdyhMb2dGaWxlTmFtZSksIExvZ01vZGUsIExvZ0F0dHJpYnV0ZXMpOwoJCQkJRXhpdFByb2Nlc3MoMSk7CgkJCX0KCQl9CgkJZWxzZSBpZihtc2lfb3B0aW9uX2VxdWFsKGFyZ3ZXW2ldLCAicCIpKQoJCXsKCQkJRnVuY3Rpb25QYXRjaCA9IFRSVUU7CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoJCQlQYXRjaEZpbGVOYW1lID0gYXJndldbaV07CgkJfQoJCWVsc2UgaWYobXNpX29wdGlvbl9wcmVmaXgoYXJndldbaV0sICJxIikpCgkJewoJCQlpZihsc3RybGVuVyhhcmd2V1tpXSkgPT0gMiB8fCBtc2lfc3RyZXF1YWwoYXJndldbaV0rMiwgIm4iKSB8fAoJCQkgICBtc2lfc3RyZXF1YWwoYXJndldbaV0gKyAyLCAidWlldCIpKQoJCQl7CgkJCQlJbnN0YWxsVUlMZXZlbCA9IElOU1RBTExVSUxFVkVMX05PTkU7CgkJCX0KCQkJZWxzZSBpZihtc2lfc3RyZXF1YWwoYXJndldbaV0rMiwgImIiKSkKCQkJewoJCQkJSW5zdGFsbFVJTGV2ZWwgPSBJTlNUQUxMVUlMRVZFTF9CQVNJQzsKCQkJfQoJCQllbHNlIGlmKG1zaV9zdHJlcXVhbChhcmd2V1tpXSsyLCAiciIpKQoJCQl7CgkJCQlJbnN0YWxsVUlMZXZlbCA9IElOU1RBTExVSUxFVkVMX1JFRFVDRUQ7CgkJCX0KCQkJZWxzZSBpZihtc2lfc3RyZXF1YWwoYXJndldbaV0rMiwgImYiKSkKCQkJewoJCQkJSW5zdGFsbFVJTGV2ZWwgPSBJTlNUQUxMVUlMRVZFTF9GVUxMfElOU1RBTExVSUxFVkVMX0VORERJQUxPRzsKCQkJfQoJCQllbHNlIGlmKG1zaV9zdHJlcXVhbChhcmd2V1tpXSsyLCAibisiKSkKCQkJewoJCQkJSW5zdGFsbFVJTGV2ZWwgPSBJTlNUQUxMVUlMRVZFTF9OT05FfElOU1RBTExVSUxFVkVMX0VORERJQUxPRzsKCQkJfQoJCQllbHNlIGlmKG1zaV9zdHJlcXVhbChhcmd2V1tpXSsyLCAiYisiKSkKCQkJewoJCQkJSW5zdGFsbFVJTGV2ZWwgPSBJTlNUQUxMVUlMRVZFTF9CQVNJQ3xJTlNUQUxMVUlMRVZFTF9FTkRESUFMT0c7CgkJCX0KCQkJZWxzZSBpZihtc2lfc3RyZXF1YWwoYXJndldbaV0rMiwgImItIikpCgkJCXsKCQkJCUluc3RhbGxVSUxldmVsID0gSU5TVEFMTFVJTEVWRUxfQkFTSUN8SU5TVEFMTFVJTEVWRUxfUFJPR1JFU1NPTkxZOwoJCQl9CgkJCWVsc2UgaWYobXNpX3N0cmVxdWFsKGFyZ3ZXW2ldKzIsICJiKyEiKSkKCQkJewoJCQkJSW5zdGFsbFVJTGV2ZWwgPSBJTlNUQUxMVUlMRVZFTF9CQVNJQ3xJTlNUQUxMVUlMRVZFTF9FTkRESUFMT0c7CgkJCQlXSU5FX0ZJWE1FKCJVbmtub3duIG1vZGlmaWVyOiAhXG4iKTsKCQkJfQoJCQllbHNlCgkJCXsKCQkJCWZwcmludGYoc3RkZXJyLCAiVW5rbm93biBvcHRpb24gXCIlc1wiIGZvciBVSSBsZXZlbFxuIiwKCQkJCQkgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSsyKSk7CgkJCX0KCQl9CgkJZWxzZSBpZihtc2lfb3B0aW9uX2VxdWFsKGFyZ3ZXW2ldLCAieSIpKQoJCXsKCQkJRnVuY3Rpb25EbGxSZWdpc3RlclNlcnZlciA9IFRSVUU7CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoJCQlEbGxOYW1lID0gYXJndldbaV07CgkJfQoJCWVsc2UgaWYobXNpX29wdGlvbl9lcXVhbChhcmd2V1tpXSwgInoiKSkKCQl7CgkJCUZ1bmN0aW9uRGxsVW5yZWdpc3RlclNlcnZlciA9IFRSVUU7CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoJCQlEbGxOYW1lID0gYXJndldbaV07CgkJfQoJCWVsc2UgaWYobXNpX29wdGlvbl9lcXVhbChhcmd2V1tpXSwgImgiKSB8fCBtc2lfb3B0aW9uX2VxdWFsKGFyZ3ZXW2ldLCAiPyIpKQoJCXsKCQkJU2hvd1VzYWdlKDApOwoJCX0KCQllbHNlIGlmKG1zaV9vcHRpb25fZXF1YWwoYXJndldbaV0sICJtIikpCgkJewoJCQlGdW5jdGlvblVua25vd24gPSBUUlVFOwoJCQlXSU5FX0ZJWE1FKCJVbmtub3duIHBhcmFtZXRlciAvbVxuIik7CgkJfQoJCWVsc2UgaWYobXNpX29wdGlvbl9lcXVhbChhcmd2V1tpXSwgIkQiKSkKCQl7CgkJCUZ1bmN0aW9uVW5rbm93biA9IFRSVUU7CgkJCVdJTkVfRklYTUUoIlVua25vd24gcGFyYW1ldGVyIC9EXG4iKTsKCQl9CgkJZWxzZSBpZiAobXNpX29wdGlvbl9lcXVhbChhcmd2V1tpXSwgIlYiKSkKCQl7CgkJICAgIEZ1bmN0aW9uU2VydmVyID0gVFJVRTsKCQl9CgkJZWxzZQoJCQlTdHJpbmdMaXN0QXBwZW5kKCZwcm9wZXJ0eV9saXN0LCBhcmd2V1tpXSk7Cgl9CgoJLyogc3RhcnQgdGhlIEdVSSAqLwoJTXNpU2V0SW50ZXJuYWxVSShJbnN0YWxsVUlMZXZlbCwgTlVMTCk7CgoJUHJvcGVydGllcyA9IGJ1aWxkX3Byb3BlcnRpZXMoIHByb3BlcnR5X2xpc3QgKTsKCglpZihGdW5jdGlvbkluc3RhbGxBZG1pbiAmJiBGdW5jdGlvblBhdGNoKQoJCUZ1bmN0aW9uSW5zdGFsbCA9IEZBTFNFOwoKCVJldHVybkNvZGUgPSAxOwoJaWYoRnVuY3Rpb25JbnN0YWxsKQoJewoJCWlmKElzUHJvZHVjdENvZGUoUGFja2FnZU5hbWUpKQoJCQlSZXR1cm5Db2RlID0gTXNpQ29uZmlndXJlUHJvZHVjdEV4VyhQYWNrYWdlTmFtZSwgMCwgSU5TVEFMTFNUQVRFX0RFRkFVTFQsIFByb3BlcnRpZXMpOwoJCWVsc2UKCQkJUmV0dXJuQ29kZSA9IE1zaUluc3RhbGxQcm9kdWN0VyhQYWNrYWdlTmFtZSwgUHJvcGVydGllcyk7Cgl9CgllbHNlIGlmKEZ1bmN0aW9uUmVwYWlyKQoJewoJCWlmKElzUHJvZHVjdENvZGUoUGFja2FnZU5hbWUpKQoJCQlXSU5FX0ZJWE1FKCJQcm9kdWN0IGNvZGUgdHJlYXRtZW50IG5vdCBpbXBsZW1lbnRlZCB5ZXRcbiIpOwoJCWVsc2UKCQkJUmV0dXJuQ29kZSA9IE1zaVJlaW5zdGFsbFByb2R1Y3RXKFBhY2thZ2VOYW1lLCBSZXBhaXJNb2RlKTsKCX0KCWVsc2UgaWYoRnVuY3Rpb25BZHZlcnRpc2UpCgl7CgkJTFBXU1RSIFRyYW5zZm9ybXMgPSBidWlsZF90cmFuc2Zvcm1zKCBwcm9wZXJ0eV9saXN0ICk7CgkJUmV0dXJuQ29kZSA9IE1zaUFkdmVydGlzZVByb2R1Y3RXKFBhY2thZ2VOYW1lLCAoTFBXU1RSKSBBZHZlcnRpc2VNb2RlLCBUcmFuc2Zvcm1zLCBMYW5ndWFnZSk7Cgl9CgllbHNlIGlmKEZ1bmN0aW9uUGF0Y2gpCgl7CgkJUmV0dXJuQ29kZSA9IE1zaUFwcGx5UGF0Y2hXKFBhdGNoRmlsZU5hbWUsIFBhY2thZ2VOYW1lLCBJbnN0YWxsVHlwZSwgUHJvcGVydGllcyk7Cgl9CgllbHNlIGlmKEZ1bmN0aW9uRGxsUmVnaXN0ZXJTZXJ2ZXIpCgl7CgkJUmV0dXJuQ29kZSA9IERvRGxsUmVnaXN0ZXJTZXJ2ZXIoRGxsTmFtZSk7Cgl9CgllbHNlIGlmKEZ1bmN0aW9uRGxsVW5yZWdpc3RlclNlcnZlcikKCXsKCQlSZXR1cm5Db2RlID0gRG9EbGxVbnJlZ2lzdGVyU2VydmVyKERsbE5hbWUpOwoJfQoJZWxzZSBpZiAoRnVuY3Rpb25SZWdTZXJ2ZXIpCgl7CgkJUmV0dXJuQ29kZSA9IERvUmVnU2VydmVyKCk7Cgl9CgllbHNlIGlmIChGdW5jdGlvblVucmVnU2VydmVyKQoJewoJCVdJTkVfRklYTUUoICIvdW5yZWdzZXJ2ZXIgbm90IGltcGxlbWVudGVkIHlldCwgaWdub3JpbmdcbiIgKTsKCX0KCWVsc2UgaWYgKEZ1bmN0aW9uU2VydmVyKQoJewoJICAgIFJldHVybkNvZGUgPSBEb1NlcnZpY2UoKTsKCX0KCWVsc2UgaWYgKEZ1bmN0aW9uVW5rbm93bikKCXsKCQlXSU5FX0ZJWE1FKCAiVW5rbm93biBmdW5jdGlvbiwgaWdub3JpbmdcbiIgKTsKCX0KCWVsc2UKCQlTaG93VXNhZ2UoMSk7CgoJcmV0dXJuIFJldHVybkNvZGU7Cn0K