LyoKICogbXNpZXhlYy5leGUgaW1wbGVtZW50YXRpb24KICoKICogQ29weXJpZ2h0IDIwMDQgVmluY2VudCBC6XJvbgogKiBDb3B5cmlnaHQgMjAwNSBNaWtlIE1jQ29ybWFjawogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojaW5jbHVkZSA8d2luZG93cy5oPgojaW5jbHVkZSA8bXNpLmg+CiNpbmNsdWRlIDxvYmpiYXNlLmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKI2luY2x1ZGUgIm1zaWV4ZWMuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJ3aW5lL3VuaWNvZGUuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG1zaWV4ZWMpOwoKc3RydWN0IHN0cmluZ19saXN0CnsKCXN0cnVjdCBzdHJpbmdfbGlzdCAqbmV4dDsKCVdDSEFSIHN0clsxXTsKfTsKCnN0YXRpYyBjb25zdCBjaGFyIFVzYWdlU3RyW10gPQoiVXNhZ2U6XG4iCiIgIEluc3RhbGwgYSBwcm9kdWN0OlxuIgoiICAgIG1zaWV4ZWMge3BhY2thZ2V8cHJvZHVjdGNvZGV9IFtwcm9wZXJ0eV1cbiIKIiAgICBtc2lleGVjIC9pIHtwYWNrYWdlfHByb2R1Y3Rjb2RlfSBbcHJvcGVydHldXG4iCiIgICAgbXNpZXhlYyAvYSBwYWNrYWdlIFtwcm9wZXJ0eV1cbiIKIiAgUmVwYWlyIGFuIGluc3RhbGxhdGlvbjpcbiIKIiAgICBtc2lleGVjIC9mW3B8b3xlfGR8Y3xhfHV8bXxzfHZdIHtwYWNrYWdlfHByb2R1Y3Rjb2RlfVxuIgoiICBVbmluc3RhbGwgYSBwcm9kdWN0OlxuIgoiICAgIG1zaWV4ZWMgL3gge3BhY2thZ2V8cHJvZHVjdGNvZGV9IFtwcm9wZXJ0eV1cbiIKIiAgQWR2ZXJ0aXNlIGEgcHJvZHVjdDpcbiIKIiAgICBtc2lleGVjIC9qW3V8bV0gcGFja2FnZSBbL3QgdHJhbnNmb3JtXSBbL2cgbGFuZ3VhZ2VpZF1cbiIKIiAgICBtc2lleGVjIHt1fG19IHBhY2thZ2UgWy90IHRyYW5zZm9ybV0gWy9nIGxhbmd1YWdlaWRdXG4iCiIgIEFwcGx5IGEgcGF0Y2g6XG4iCiIgICAgbXNpZXhlYyAvcCBwYXRjaHBhY2thZ2UgW3Byb3BlcnR5XVxuIgoiICAgIG1zaWV4ZWMgL3AgcGF0Y2hwYWNrYWdlIC9hIHBhY2thZ2UgW3Byb3BlcnR5XVxuIgoiICBNb2RpZmllcnMgZm9yIGFib3ZlIG9wZXJhdGlvbnM6XG4iCiIgICAgbXNpZXhlYyAvbFsqXVtpfHd8ZXxhfHJ8dXxjfG18b3xwfHZ8XVsrfCFdIGxvZ2ZpbGVcbiIKIiAgICBtc2lleGVjIC9xe3xufGJ8cnxmfG4rfGIrfGItfVxuIgoiICBSZWdpc3RlciBhIG1vZHVsZTpcbiIKIiAgICBtc2lleGVjIC95IG1vZHVsZVxuIgoiICBVbnJlZ2lzdGVyIGEgbW9kdWxlOlxuIgoiICAgIG1zaWV4ZWMgL3ogbW9kdWxlXG4iCiIgIERpc3BsYXkgdXNhZ2UgYW5kIGNvcHlyaWdodDpcbiIKIiAgICBtc2lleGVjIHsvaHwvP31cbiIKIk5PVEU6IFByb2R1Y3QgY29kZSBvbiBjb21tYW5kbGluZSB1bmltcGxlbWVudGVkIGFzIG9mIHlldFxuIgoiXG4iCiJDb3B5cmlnaHQgMjAwNCBWaW5jZW50IELpcm9uXG4iOwoKc3RhdGljIGNvbnN0IFdDSEFSIEFjdGlvbkFkbWluW10gPSB7CiAgICdBJywnQycsJ1QnLCdJJywnTycsJ04nLCc9JywnQScsJ0QnLCdNJywnSScsJ04nLDAgfTsKc3RhdGljIGNvbnN0IFdDSEFSIFJlbW92ZUFsbFtdID0gewogICAnUicsJ0UnLCdNJywnTycsJ1YnLCdFJywnPScsJ0EnLCdMJywnTCcsMCB9OwoKc3RhdGljIGNvbnN0IFdDSEFSIEluc3RhbGxSdW5PbmNlW10gPSB7CiAgICdTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsJ1xcJywKICAgJ00nLCdpJywnYycsJ3InLCdvJywncycsJ28nLCdmJywndCcsJ1xcJywKICAgJ1cnLCdpJywnbicsJ2QnLCdvJywndycsJ3MnLCdcXCcsCiAgICdDJywndScsJ3InLCdyJywnZScsJ24nLCd0JywnVicsJ2UnLCdyJywncycsJ2knLCdvJywnbicsJ1xcJywKICAgJ0knLCduJywncycsJ3QnLCdhJywnbCcsJ2wnLCdlJywncicsJ1xcJywKICAgJ1InLCd1JywnbicsJ08nLCduJywnYycsJ2UnLCdFJywnbicsJ3QnLCdyJywnaScsJ2UnLCdzJywwfTsKCnN0YXRpYyB2b2lkIFNob3dVc2FnZShpbnQgRXhpdENvZGUpCnsKCXByaW50ZihVc2FnZVN0cik7CglFeGl0UHJvY2VzcyhFeGl0Q29kZSk7Cn0KCnN0YXRpYyBCT09MIElzUHJvZHVjdENvZGUoTFBXU1RSIHN0cikKewoJR1VJRCBQcm9kdWN0Q29kZTsKCglpZihsc3RybGVuVyhzdHIpICE9IDM4KQoJCXJldHVybiBGQUxTRTsKCXJldHVybiAoIChDTFNJREZyb21TdHJpbmcoc3RyLCAmUHJvZHVjdENvZGUpID09IE5PRVJST1IpICk7Cgp9CgpzdGF0aWMgVk9JRCBTdHJpbmdMaXN0QXBwZW5kKHN0cnVjdCBzdHJpbmdfbGlzdCAqKmxpc3QsIExQQ1dTVFIgc3RyKQp7CglzdHJ1Y3Qgc3RyaW5nX2xpc3QgKmVudHJ5OwoJRFdPUkQgc2l6ZTsKCglzaXplID0gc2l6ZW9mICplbnRyeSArIGxzdHJsZW5XKHN0cikgKiBzaXplb2YgKFdDSEFSKTsKCWVudHJ5ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUpOwoJaWYoIWVudHJ5KQoJewoJCVdJTkVfRVJSKCJPdXQgb2YgbWVtb3J5IVxuIik7CgkJRXhpdFByb2Nlc3MoMSk7Cgl9Cglsc3RyY3B5VyhlbnRyeS0+c3RyLCBzdHIpOwoJZW50cnktPm5leHQgPSBOVUxMOwoKCS8qCgkgKiBJZ25vcmluZyBvKG5eMikgdGltZSBjb21wbGV4aXR5IHRvIGFkZCBuIHN0cmluZ3MgZm9yIHNpbXBsaWNpdHksCgkgKiAgYWRkIHRoZSBzdHJpbmcgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdCB0byBwcmVzZXJ2ZSB0aGUgb3JkZXIuCgkgKi8KCXdoaWxlKCAqbGlzdCApCgkJbGlzdCA9ICYoKmxpc3QpLT5uZXh0OwoJKmxpc3QgPSBlbnRyeTsKfQoKc3RhdGljIExQV1NUUiBidWlsZF9wcm9wZXJ0aWVzKHN0cnVjdCBzdHJpbmdfbGlzdCAqcHJvcGVydHlfbGlzdCkKewoJc3RydWN0IHN0cmluZ19saXN0ICpsaXN0OwoJTFBXU1RSIHJldCwgcCwgdmFsdWU7CglEV09SRCBsZW47CglCT09MIG5lZWRzX3F1b3RlOwoKCWlmKCFwcm9wZXJ0eV9saXN0KQoJCXJldHVybiBOVUxMOwoKCS8qIGNvdW50IHRoZSBzcGFjZSB3ZSBuZWVkICovCglsZW4gPSAxOwoJZm9yKGxpc3QgPSBwcm9wZXJ0eV9saXN0OyBsaXN0OyBsaXN0ID0gbGlzdC0+bmV4dCkKCQlsZW4gKz0gbHN0cmxlblcobGlzdC0+c3RyKSArIDM7CgoJcmV0ID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4qc2l6ZW9mKFdDSEFSKSApOwoKCS8qIGFkZCBhIHNwYWNlIGJlZm9yZSBlYWNoIHN0cmluZywgYW5kIHF1b3RlIHRoZSB2YWx1ZSAqLwoJcCA9IHJldDsKCWZvcihsaXN0ID0gcHJvcGVydHlfbGlzdDsgbGlzdDsgbGlzdCA9IGxpc3QtPm5leHQpCgl7CgkJdmFsdWUgPSBzdHJjaHJXKGxpc3QtPnN0ciwnPScpOwoJCWlmKCF2YWx1ZSkKCQkJY29udGludWU7CgkJbGVuID0gdmFsdWUgLSBsaXN0LT5zdHI7CgkJKnArKyA9ICcgJzsKCQltZW1jcHkocCwgbGlzdC0+c3RyLCBsZW4gKiBzaXplb2YoV0NIQVIpKTsKCQlwICs9IGxlbjsKCQkqcCsrID0gJz0nOwoKCQkvKiBjaGVjayBpZiB0aGUgdmFsdWUgY29udGFpbnMgc3BhY2VzIGFuZCBtYXliZSBxdW90ZSBpdCAqLwoJCXZhbHVlKys7CgkJbmVlZHNfcXVvdGUgPSBzdHJjaHJXKHZhbHVlLCcgJykgPyAxIDogMDsKCQlpZihuZWVkc19xdW90ZSkKCQkJKnArKyA9ICciJzsKCQlsZW4gPSBsc3RybGVuVyh2YWx1ZSk7CgkJbWVtY3B5KHAsIHZhbHVlLCBsZW4gKiBzaXplb2YoV0NIQVIpKTsKCQlwICs9IGxlbjsKCQlpZihuZWVkc19xdW90ZSkKCQkJKnArKyA9ICciJzsKCX0KCSpwID0gMDsKCglXSU5FX1RSQUNFKCJwcm9wZXJ0aWVzIC0+ICVzXG4iLCB3aW5lX2RiZ3N0cl93KHJldCkgKTsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgTFBXU1RSIGJ1aWxkX3RyYW5zZm9ybXMoc3RydWN0IHN0cmluZ19saXN0ICp0cmFuc2Zvcm1fbGlzdCkKewoJc3RydWN0IHN0cmluZ19saXN0ICpsaXN0OwoJTFBXU1RSIHJldCwgcDsKCURXT1JEIGxlbjsKCgkvKiBjb3VudCB0aGUgc3BhY2Ugd2UgbmVlZCAqLwoJbGVuID0gMTsKCWZvcihsaXN0ID0gdHJhbnNmb3JtX2xpc3Q7IGxpc3Q7IGxpc3QgPSBsaXN0LT5uZXh0KQoJCWxlbiArPSBsc3RybGVuVyhsaXN0LT5zdHIpICsgMTsKCglyZXQgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbipzaXplb2YoV0NIQVIpICk7CgoJLyogYWRkIGFsbCB0aGUgdHJhbnNmb3JtcyB3aXRoIGEgc2VtaWNvbG9uIGJldHdlZW4gZWFjaCBvbmUgKi8KCXAgPSByZXQ7Cglmb3IobGlzdCA9IHRyYW5zZm9ybV9saXN0OyBsaXN0OyBsaXN0ID0gbGlzdC0+bmV4dCkKCXsKCQlsZW4gPSBsc3RybGVuVyhsaXN0LT5zdHIpOwoJCWxzdHJjcHluVyhwLCBsaXN0LT5zdHIsIGxlbiApOwoJCXAgKz0gbGVuOwoJCWlmKGxpc3QtPm5leHQpCgkJCSpwKysgPSAnOyc7Cgl9CgkqcCA9IDA7CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIERXT1JEIG1zaV9hdG91KExQQ1dTVFIgc3RyKQp7CglEV09SRCByZXQgPSAwOwoJd2hpbGUoKnN0ciA+PSAnMCcgJiYgKnN0ciA8PSAnOScpCgl7CgkJcmV0ICo9IDEwOwoJCXJldCArPSAoKnN0ciAtICcwJyk7CgkJc3RyKys7Cgl9CglyZXR1cm4gMDsKfQoKc3RhdGljIExQV1NUUiBtc2lfc3RyZHVwKExQQ1dTVFIgc3RyKQp7CglEV09SRCBsZW4gPSBsc3RybGVuVyhzdHIpKzE7CglMUFdTVFIgcmV0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihXQ0hBUikqbGVuKTsKCWxzdHJjcHlXKHJldCwgc3RyKTsKCXJldHVybiByZXQ7Cn0KCi8qIHN0cjEgaXMgdGhlIHNhbWUgYXMgc3RyMiwgaWdub3JpbmcgY2FzZSAqLwpzdGF0aWMgQk9PTCBtc2lfc3RyZXF1YWwoTFBDV1NUUiBzdHIxLCBMUENTVFIgc3RyMikKewoJRFdPUkQgbGVuLCByZXQ7CglMUFdTVFIgc3RyVzsKCglsZW4gPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKCBDUF9BQ1AsIDAsIHN0cjIsIC0xLCBOVUxMLCAwKTsKCWlmKCAhbGVuICkKCQlyZXR1cm4gVFJVRTsKCWlmKCBsc3RybGVuVyhzdHIxKSAhPSAobGVuLTEpICkKCQlyZXR1cm4gVFJVRTsKCXN0clcgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKFdDSEFSKSpsZW4pOwoJTXVsdGlCeXRlVG9XaWRlQ2hhciggQ1BfQUNQLCAwLCBzdHIyLCAtMSwgc3RyVywgbGVuKTsKCXJldCA9IENvbXBhcmVTdHJpbmdXKEdldFRocmVhZExvY2FsZSgpLCBOT1JNX0lHTk9SRUNBU0UsIHN0cjEsIGxlbiwgc3RyVywgbGVuKTsKCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHN0clcpOwoJcmV0dXJuIChyZXQgIT0gQ1NUUl9FUVVBTCk7Cn0KCi8qIHN0cjIgaXMgYXQgdGhlIGJlZ2lubmluZyBvZiBzdHIxLCBpZ25vcmluZyBjYXNlICovCnN0YXRpYyBCT09MIG1zaV9zdHJwcmVmaXgoTFBDV1NUUiBzdHIxLCBMUENTVFIgc3RyMikKewoJRFdPUkQgbGVuLCByZXQ7CglMUFdTVFIgc3RyVzsKCglsZW4gPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKCBDUF9BQ1AsIDAsIHN0cjIsIC0xLCBOVUxMLCAwKTsKCWlmKCAhbGVuICkKCQlyZXR1cm4gVFJVRTsKCWlmKCBsc3RybGVuVyhzdHIxKSA8IChsZW4tMSkgKQoJCXJldHVybiBUUlVFOwoJc3RyVyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoV0NIQVIpKmxlbik7CglNdWx0aUJ5dGVUb1dpZGVDaGFyKCBDUF9BQ1AsIDAsIHN0cjIsIC0xLCBzdHJXLCBsZW4pOwoJcmV0ID0gQ29tcGFyZVN0cmluZ1coR2V0VGhyZWFkTG9jYWxlKCksIE5PUk1fSUdOT1JFQ0FTRSwgc3RyMSwgbGVuLTEsIHN0clcsIGxlbi0xKTsKCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHN0clcpOwoJcmV0dXJuIChyZXQgIT0gQ1NUUl9FUVVBTCk7Cn0KCnN0YXRpYyBWT0lEICpMb2FkUHJvYyhMUENXU1RSIERsbE5hbWUsIExQQ1NUUiBQcm9jTmFtZSwgSE1PRFVMRSogRGxsSGFuZGxlKQp7CglWT0lEKiAoKnByb2MpKHZvaWQpOwoKCSpEbGxIYW5kbGUgPSBMb2FkTGlicmFyeUV4VyhEbGxOYW1lLCBOVUxMLCBMT0FEX1dJVEhfQUxURVJFRF9TRUFSQ0hfUEFUSCk7CglpZighKkRsbEhhbmRsZSkKCXsKCQlmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb2FkIGRsbCAlc1xuIiwgd2luZV9kYmdzdHJfdyhEbGxOYW1lKSk7CgkJRXhpdFByb2Nlc3MoMSk7Cgl9Cglwcm9jID0gKFZPSUQgKikgR2V0UHJvY0FkZHJlc3MoKkRsbEhhbmRsZSwgUHJvY05hbWUpOwoJaWYoIXByb2MpCgl7CgkJZnByaW50ZihzdGRlcnIsICJEbGwgJXMgZG9lcyBub3QgaW1wbGVtZW50IGZ1bmN0aW9uICVzXG4iLAoJCQl3aW5lX2RiZ3N0cl93KERsbE5hbWUpLCBQcm9jTmFtZSk7CgkJRnJlZUxpYnJhcnkoKkRsbEhhbmRsZSk7CgkJRXhpdFByb2Nlc3MoMSk7Cgl9CgoJcmV0dXJuIHByb2M7Cn0KCnN0YXRpYyBEV09SRCBEb0RsbFJlZ2lzdGVyU2VydmVyKExQQ1dTVFIgRGxsTmFtZSkKewoJSFJFU1VMVCBocjsKCURMTFJFR0lTVEVSU0VSVkVSIHBmRGxsUmVnaXN0ZXJTZXJ2ZXIgPSBOVUxMOwoJSE1PRFVMRSBEbGxIYW5kbGUgPSBOVUxMOwoKCXBmRGxsUmVnaXN0ZXJTZXJ2ZXIgPSBMb2FkUHJvYyhEbGxOYW1lLCAiRGxsUmVnaXN0ZXJTZXJ2ZXIiLCAmRGxsSGFuZGxlKTsKCglociA9IHBmRGxsUmVnaXN0ZXJTZXJ2ZXIoKTsKCWlmKEZBSUxFRChocikpCgl7CgkJZnByaW50ZihzdGRlcnIsICJGYWlsZWQgdG8gcmVnaXN0ZXIgZGxsICVzXG4iLCB3aW5lX2RiZ3N0cl93KERsbE5hbWUpKTsKCQlyZXR1cm4gMTsKCX0KCXByaW50ZigiU3VjY2Vzc2Z1bGx5IHJlZ2lzdGVyZWQgZGxsICVzXG4iLCB3aW5lX2RiZ3N0cl93KERsbE5hbWUpKTsKCWlmKERsbEhhbmRsZSkKCQlGcmVlTGlicmFyeShEbGxIYW5kbGUpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBEV09SRCBEb0RsbFVucmVnaXN0ZXJTZXJ2ZXIoTFBDV1NUUiBEbGxOYW1lKQp7CglIUkVTVUxUIGhyOwoJRExMVU5SRUdJU1RFUlNFUlZFUiBwZkRsbFVucmVnaXN0ZXJTZXJ2ZXIgPSBOVUxMOwoJSE1PRFVMRSBEbGxIYW5kbGUgPSBOVUxMOwoKCXBmRGxsVW5yZWdpc3RlclNlcnZlciA9IExvYWRQcm9jKERsbE5hbWUsICJEbGxVbnJlZ2lzdGVyU2VydmVyIiwgJkRsbEhhbmRsZSk7CgoJaHIgPSBwZkRsbFVucmVnaXN0ZXJTZXJ2ZXIoKTsKCWlmKEZBSUxFRChocikpCgl7CgkJZnByaW50ZihzdGRlcnIsICJGYWlsZWQgdG8gdW5yZWdpc3RlciBkbGwgJXNcbiIsIHdpbmVfZGJnc3RyX3coRGxsTmFtZSkpOwoJCXJldHVybiAxOwoJfQoJcHJpbnRmKCJTdWNjZXNzZnVsbHkgdW5yZWdpc3RlcmVkIGRsbCAlc1xuIiwgd2luZV9kYmdzdHJfdyhEbGxOYW1lKSk7CglpZihEbGxIYW5kbGUpCgkJRnJlZUxpYnJhcnkoRGxsSGFuZGxlKTsKCXJldHVybiAwOwp9CgovKgogKiBzdGF0ZSBtYWNoaW5lIHRvIGJyZWFrIHVwIHRoZSBjb21tYW5kIGxpbmUgcHJvcGVybHkKICovCgplbnVtIGNob21wX3N0YXRlCnsKCWNzX3doaXRlc3BhY2UsCgljc190b2tlbiwKCWNzX3F1b3RlCn07CgpzdGF0aWMgaW50IGNob21wKCBXQ0hBUiAqc3RyICkKewoJZW51bSBjaG9tcF9zdGF0ZSBzdGF0ZSA9IGNzX3doaXRlc3BhY2U7CglXQ0hBUiAqcCwgKm91dDsKCWludCBjb3VudCA9IDAsIGlnbm9yZTsKCglmb3IoIHAgPSBzdHIsIG91dCA9IHN0cjsgKnA7IHArKyApCgl7CgkJaWdub3JlID0gMTsKCQlzd2l0Y2goIHN0YXRlICkKCQl7CgkJY2FzZSBjc193aGl0ZXNwYWNlOgoJCQlzd2l0Y2goICpwICkKCQkJewoJCQljYXNlICcgJzoKCQkJCWJyZWFrOwoJCQljYXNlICciJzoKCQkJCXN0YXRlID0gY3NfcXVvdGU7CgkJCQljb3VudCsrOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQljb3VudCsrOwoJCQkJaWdub3JlID0gMDsKCQkJCXN0YXRlID0gY3NfdG9rZW47CgkJCX0KCQkJYnJlYWs7CgoJCWNhc2UgY3NfdG9rZW46CgkJCXN3aXRjaCggKnAgKQoJCQl7CgkJCWNhc2UgJyInOgoJCQkJc3RhdGUgPSBjc19xdW90ZTsKCQkJCWJyZWFrOwoJCQljYXNlICcgJzoKCQkJCXN0YXRlID0gY3Nfd2hpdGVzcGFjZTsKCQkJCSpvdXQrKyA9IDA7CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCWlnbm9yZSA9IDA7CgkJCX0KCQkJYnJlYWs7CgoJCWNhc2UgY3NfcXVvdGU6CgkJCXN3aXRjaCggKnAgKQoJCQl7CgkJCWNhc2UgJyInOgoJCQkJc3RhdGUgPSBjc190b2tlbjsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJaWdub3JlID0gMDsKCQkJfQoJCQlicmVhazsKCQl9CgkJaWYoICFpZ25vcmUgKQoJCQkqb3V0KysgPSAqcDsKCX0KCgkqb3V0ID0gMDsKCglyZXR1cm4gY291bnQ7Cn0KCnN0YXRpYyB2b2lkIHByb2Nlc3NfYXJncyggV0NIQVIgKmNtZGxpbmUsIGludCAqcGFyZ2MsIFdDSEFSICoqKnBhcmd2ICkKewoJV0NIQVIgKiphcmd2LCAqcCA9IG1zaV9zdHJkdXAoY21kbGluZSk7CglpbnQgaSwgbjsKCgluID0gY2hvbXAoIHAgKTsKCWFyZ3YgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mIChXQ0hBUiopKihuKzEpKTsKCWZvciggaT0wOyBpPG47IGkrKyApCgl7CgkJYXJndltpXSA9IHA7CgkJcCArPSBsc3RybGVuVyhwKSArIDE7Cgl9Cglhcmd2W2ldID0gTlVMTDsKCgkqcGFyZ2MgPSBuOwoJKnBhcmd2ID0gYXJndjsKfQoKc3RhdGljIEJPT0wgcHJvY2Vzc19hcmdzX2Zyb21fcmVnKCBMUFdTVFIgaWRlbnQsIGludCAqcGFyZ2MsIFdDSEFSICoqKnBhcmd2ICkKewoJTE9ORyByOwoJSEtFWSBoa2V5ID0gMCwgaGtleUFyZ3MgPSAwOwoJRFdPUkQgc3ogPSAwLCB0eXBlID0gMDsKCUxQV1NUUiBidWYgPSBOVUxMOwoJQk9PTCByZXQgPSBGQUxTRTsKCglyID0gUmVnT3BlbktleVcoSEtFWV9MT0NBTF9NQUNISU5FLCBJbnN0YWxsUnVuT25jZSwgJmhrZXkpOwoJaWYociAhPSBFUlJPUl9TVUNDRVNTKQoJCXJldHVybiBGQUxTRTsKCXIgPSBSZWdRdWVyeVZhbHVlRXhXKGhrZXksIGlkZW50LCAwLCAmdHlwZSwgMCwgJnN6KTsKCWlmKHIgPT0gRVJST1JfU1VDQ0VTUyAmJiB0eXBlID09IFJFR19TWikKCXsKCQlidWYgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3opOwoJCXIgPSBSZWdRdWVyeVZhbHVlRXhXKGhrZXksIGlkZW50LCAwLCAmdHlwZSwgKExQQllURSlidWYsICZzeik7CgkJaWYoIHIgPT0gRVJST1JfU1VDQ0VTUyApCgkJewoJCQlwcm9jZXNzX2FyZ3MoYnVmLCBwYXJnYywgcGFyZ3YpOwoJCQlyZXQgPSBUUlVFOwoJCX0KCX0KCVJlZ0Nsb3NlS2V5KGhrZXlBcmdzKTsKCXJldHVybiByZXQ7Cn0KCmludCBtYWluKGludCBhcmdjLCBjaGFyICoqYXJndikKewoJaW50IGk7CglCT09MIEZ1bmN0aW9uSW5zdGFsbCA9IEZBTFNFOwoJQk9PTCBGdW5jdGlvbkluc3RhbGxBZG1pbiA9IEZBTFNFOwoJQk9PTCBGdW5jdGlvblJlcGFpciA9IEZBTFNFOwoJQk9PTCBGdW5jdGlvbkFkdmVydGlzZSA9IEZBTFNFOwoJQk9PTCBGdW5jdGlvblBhdGNoID0gRkFMU0U7CglCT09MIEZ1bmN0aW9uRGxsUmVnaXN0ZXJTZXJ2ZXIgPSBGQUxTRTsKCUJPT0wgRnVuY3Rpb25EbGxVbnJlZ2lzdGVyU2VydmVyID0gRkFMU0U7CglCT09MIEZ1bmN0aW9uUmVnU2VydmVyID0gRkFMU0U7CglCT09MIEZ1bmN0aW9uVW5yZWdTZXJ2ZXIgPSBGQUxTRTsKCUJPT0wgRnVuY3Rpb25Vbmtub3duID0gRkFMU0U7CgoJTFBXU1RSIFBhY2thZ2VOYW1lID0gTlVMTDsKCUxQV1NUUiBQcm9wZXJ0aWVzID0gTlVMTDsKCXN0cnVjdCBzdHJpbmdfbGlzdCAqcHJvcGVydHlfbGlzdCA9IE5VTEw7CgoJRFdPUkQgUmVwYWlyTW9kZSA9IDA7CgoJRFdPUkQgQWR2ZXJ0aXNlTW9kZSA9IDA7CglMUFdTVFIgVHJhbnNmb3JtcyA9IE5VTEw7CglzdHJ1Y3Qgc3RyaW5nX2xpc3QgKnRyYW5zZm9ybV9saXN0ID0gTlVMTDsKCUxBTkdJRCBMYW5ndWFnZSA9IDA7CgoJRFdPUkQgTG9nTW9kZSA9IDA7CglMUFdTVFIgTG9nRmlsZU5hbWUgPSBOVUxMOwoJRFdPUkQgTG9nQXR0cmlidXRlcyA9IDA7CgoJTFBXU1RSIFBhdGNoRmlsZU5hbWUgPSBOVUxMOwoJSU5TVEFMTFRZUEUgSW5zdGFsbFR5cGUgPSBJTlNUQUxMVFlQRV9ERUZBVUxUOwoKCUlOU1RBTExVSUxFVkVMIEluc3RhbGxVSUxldmVsID0gSU5TVEFMTFVJTEVWRUxfRlVMTDsKCglMUFdTVFIgRGxsTmFtZSA9IE5VTEw7CglEV09SRCBSZXR1cm5Db2RlOwoJTFBXU1RSICphcmd2VyA9IE5VTEw7CgoJLyogb3ZlcndyaXRlIHRoZSBjb21tYW5kIGxpbmUgKi8KCXByb2Nlc3NfYXJncyggR2V0Q29tbWFuZExpbmVXKCksICZhcmdjLCAmYXJndlcgKTsKCgkvKgoJICogSWYgdGhlIGFyZ3MgYmVnaW4gd2l0aCAvQCBJREVOVCB0aGVuIHdlIG5lZWQgdG8gbG9hZCB0aGUgcmVhbAoJICogY29tbWFuZCBsaW5lIG91dCBvZiB0aGUgUnVuT25jZUVudHJpZXMga2V5IGluIHRoZSByZWdpc3RyeS4KCSAqICBXZSBkbyB0aGF0IGJlZm9yZSBzdGFydGluZyB0byBwcm9jZXNzIHRoZSByZWFsIGNvbW1hbmRsaW5lLAoJICogdGhlbiBvdmVyd3JpdGUgdGhlIGNvbW1hbmRsaW5lIGFnYWluLgoJICovCglpZighbXNpX3N0cmVxdWFsKGFyZ3ZXWzFdLCAiL0AiKSkKCXsKCQlpZighcHJvY2Vzc19hcmdzX2Zyb21fcmVnKCBhcmd2V1syXSwgJmFyZ2MsICZhcmd2VyApKQoJCQlyZXR1cm4gMTsKCX0KCglmb3IoaSA9IDE7IGkgPCBhcmdjOyBpKyspCgl7CgkJV0lORV9UUkFDRSgiYXJndldbJWRdID0gJXNcbiIsIGksIHdpbmVfZGJnc3RyX3coYXJndldbaV0pKTsKCgkJaWYgKCFtc2lfc3RyZXF1YWwoYXJndldbaV0sICIvcmVnc2VydmVyIikpCgkJewoJCQlGdW5jdGlvblJlZ1NlcnZlciA9IFRSVUU7CgkJfQoJCWVsc2UgaWYgKCFtc2lfc3RyZXF1YWwoYXJndldbaV0sICIvdW5yZWdzZXJ2ZXIiKSB8fCAhbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldLCAiL3VucmVnaXN0ZXIiKSkKCQl7CgkJCUZ1bmN0aW9uVW5yZWdTZXJ2ZXIgPSBUUlVFOwoJCX0KCQllbHNlIGlmKCFtc2lfc3RycHJlZml4KGFyZ3ZXW2ldLCAiL2kiKSkKCQl7CgkJCUxQV1NUUiBhcmd2V2kgPSBhcmd2V1tpXTsKCQkJRnVuY3Rpb25JbnN0YWxsID0gVFJVRTsKCQkJaWYobHN0cmxlblcoYXJndldpKSA+IDIpCgkJCQlhcmd2V2kgKz0gMjsKCQkJZWxzZQoJCQl7CgkJCQlpKys7CgkJCQlpZihpID49IGFyZ2MpCgkJCQkJU2hvd1VzYWdlKDEpOwoJCQkJV0lORV9UUkFDRSgiYXJndldbJWRdID0gJXNcbiIsIGksIHdpbmVfZGJnc3RyX3coYXJndldbaV0pKTsKCQkJCWFyZ3ZXaSA9IGFyZ3ZXW2ldOwoJCQl9CgkJCVBhY2thZ2VOYW1lID0gYXJndldpOwoJCX0KCQllbHNlIGlmKCFtc2lfc3RyZXF1YWwoYXJndldbaV0sICIvYSIpKQoJCXsKCQkJRnVuY3Rpb25JbnN0YWxsID0gVFJVRTsKCQkJRnVuY3Rpb25JbnN0YWxsQWRtaW4gPSBUUlVFOwoJCQlJbnN0YWxsVHlwZSA9IElOU1RBTExUWVBFX05FVFdPUktfSU1BR0U7CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoJCQlQYWNrYWdlTmFtZSA9IGFyZ3ZXW2ldOwoJCQlTdHJpbmdMaXN0QXBwZW5kKCZwcm9wZXJ0eV9saXN0LCBBY3Rpb25BZG1pbik7CgkJfQoJCWVsc2UgaWYoIW1zaV9zdHJwcmVmaXgoYXJndldbaV0sICIvZiIpKQoJCXsKCQkJaW50IGo7CgkJCWludCBsZW4gPSBsc3RybGVuVyhhcmd2V1tpXSk7CgkJCUZ1bmN0aW9uUmVwYWlyID0gVFJVRTsKCQkJZm9yKGogPSAyOyBqIDwgbGVuOyBqKyspCgkJCXsKCQkJCXN3aXRjaChhcmd2V1tpXVtqXSkKCQkJCXsKCQkJCQljYXNlICdQJzoKCQkJCQljYXNlICdwJzoKCQkJCQkJUmVwYWlyTW9kZSB8PSBSRUlOU1RBTExNT0RFX0ZJTEVNSVNTSU5HOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdPJzoKCQkJCQljYXNlICdvJzoKCQkJCQkJUmVwYWlyTW9kZSB8PSBSRUlOU1RBTExNT0RFX0ZJTEVPTERFUlZFUlNJT047CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ0UnOgoJCQkJCWNhc2UgJ2UnOgoJCQkJCQlSZXBhaXJNb2RlIHw9IFJFSU5TVEFMTE1PREVfRklMRUVRVUFMVkVSU0lPTjsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnRCc6CgkJCQkJY2FzZSAnZCc6CgkJCQkJCVJlcGFpck1vZGUgfD0gUkVJTlNUQUxMTU9ERV9GSUxFRVhBQ1Q7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ0MnOgoJCQkJCWNhc2UgJ2MnOgoJCQkJCQlSZXBhaXJNb2RlIHw9IFJFSU5TVEFMTE1PREVfRklMRVZFUklGWTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnQSc6CgkJCQkJY2FzZSAnYSc6CgkJCQkJCVJlcGFpck1vZGUgfD0gUkVJTlNUQUxMTU9ERV9GSUxFUkVQTEFDRTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnVSc6CgkJCQkJY2FzZSAndSc6CgkJCQkJCVJlcGFpck1vZGUgfD0gUkVJTlNUQUxMTU9ERV9VU0VSREFUQTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnTSc6CgkJCQkJY2FzZSAnbSc6CgkJCQkJCVJlcGFpck1vZGUgfD0gUkVJTlNUQUxMTU9ERV9NQUNISU5FREFUQTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnUyc6CgkJCQkJY2FzZSAncyc6CgkJCQkJCVJlcGFpck1vZGUgfD0gUkVJTlNUQUxMTU9ERV9TSE9SVENVVDsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnVic6CgkJCQkJY2FzZSAndic6CgkJCQkJCVJlcGFpck1vZGUgfD0gUkVJTlNUQUxMTU9ERV9QQUNLQUdFOwoJCQkJCQlicmVhazsKCQkJCQlkZWZhdWx0OgoJCQkJCQlmcHJpbnRmKHN0ZGVyciwgIlVua25vd24gb3B0aW9uIFwiJWNcIiBpbiBSZXBhaXIgbW9kZVxuIiwgYXJndldbaV1bal0pOwoJCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCQlpZihsZW4gPT0gMikKCQkJewoJCQkJUmVwYWlyTW9kZSA9IFJFSU5TVEFMTE1PREVfRklMRU1JU1NJTkcgfAoJCQkJCVJFSU5TVEFMTE1PREVfRklMRUVRVUFMVkVSU0lPTiB8CgkJCQkJUkVJTlNUQUxMTU9ERV9GSUxFVkVSSUZZIHwKCQkJCQlSRUlOU1RBTExNT0RFX01BQ0hJTkVEQVRBIHwKCQkJCQlSRUlOU1RBTExNT0RFX1NIT1JUQ1VUOwoJCQl9CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoJCQlQYWNrYWdlTmFtZSA9IGFyZ3ZXW2ldOwoJCX0KCQllbHNlIGlmKCFtc2lfc3RyZXF1YWwoYXJndldbaV0sICIveCIpKQoJCXsKCQkJRnVuY3Rpb25JbnN0YWxsID0gVFJVRTsKCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgkJCVBhY2thZ2VOYW1lID0gYXJndldbaV07CgkJCVN0cmluZ0xpc3RBcHBlbmQoJnByb3BlcnR5X2xpc3QsIFJlbW92ZUFsbCk7CgkJfQoJCWVsc2UgaWYoIW1zaV9zdHJwcmVmaXgoYXJndldbaV0sICIvaiIpKQoJCXsKCQkJaW50IGo7CgkJCWludCBsZW4gPSBsc3RybGVuVyhhcmd2V1tpXSk7CgkJCUZ1bmN0aW9uQWR2ZXJ0aXNlID0gVFJVRTsKCQkJZm9yKGogPSAyOyBqIDwgbGVuOyBqKyspCgkJCXsKCQkJCXN3aXRjaChhcmd2V1tpXVtqXSkKCQkJCXsKCQkJCQljYXNlICdVJzoKCQkJCQljYXNlICd1JzoKCQkJCQkJQWR2ZXJ0aXNlTW9kZSA9IEFEVkVSVElTRUZMQUdTX1VTRVJBU1NJR047CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ00nOgoJCQkJCWNhc2UgJ20nOgoJCQkJCQlBZHZlcnRpc2VNb2RlID0gQURWRVJUSVNFRkxBR1NfTUFDSElORUFTU0lHTjsKCQkJCQkJYnJlYWs7CgkJCQkJZGVmYXVsdDoKCQkJCQkJZnByaW50ZihzdGRlcnIsICJVbmtub3duIG9wdGlvbiBcIiVjXCIgaW4gQWR2ZXJ0aXNlIG1vZGVcbiIsIGFyZ3ZXW2ldW2pdKTsKCQkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgkJCVBhY2thZ2VOYW1lID0gYXJndldbaV07CgkJfQoJCWVsc2UgaWYoIW1zaV9zdHJlcXVhbChhcmd2V1tpXSwgInUiKSkKCQl7CgkJCUZ1bmN0aW9uQWR2ZXJ0aXNlID0gVFJVRTsKCQkJQWR2ZXJ0aXNlTW9kZSA9IEFEVkVSVElTRUZMQUdTX1VTRVJBU1NJR047CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoJCQlQYWNrYWdlTmFtZSA9IGFyZ3ZXW2ldOwoJCX0KCQllbHNlIGlmKCFtc2lfc3RyZXF1YWwoYXJndldbaV0sICJtIikpCgkJewoJCQlGdW5jdGlvbkFkdmVydGlzZSA9IFRSVUU7CgkJCUFkdmVydGlzZU1vZGUgPSBBRFZFUlRJU0VGTEFHU19NQUNISU5FQVNTSUdOOwoJCQlpKys7CgkJCWlmKGkgPj0gYXJnYykKCQkJCVNob3dVc2FnZSgxKTsKCQkJV0lORV9UUkFDRSgiYXJndldbJWRdID0gJXNcbiIsIGksIHdpbmVfZGJnc3RyX3coYXJndldbaV0pKTsKCQkJUGFja2FnZU5hbWUgPSBhcmd2V1tpXTsKCQl9CgkJZWxzZSBpZighbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldLCAiL3QiKSkKCQl7CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoJCQlTdHJpbmdMaXN0QXBwZW5kKCZ0cmFuc2Zvcm1fbGlzdCwgYXJndldbaV0pOwoJCX0KCQllbHNlIGlmKCFtc2lfc3RycHJlZml4KGFyZ3ZXW2ldLCAiVFJBTlNGT1JNUz0iKSkKCQl7CgkJCVN0cmluZ0xpc3RBcHBlbmQoJnRyYW5zZm9ybV9saXN0LCBhcmd2V1tpXSsxMSk7CgkJfQoJCWVsc2UgaWYoIW1zaV9zdHJlcXVhbChhcmd2V1tpXSwgIi9nIikpCgkJewoJCQlpKys7CgkJCWlmKGkgPj0gYXJnYykKCQkJCVNob3dVc2FnZSgxKTsKCQkJV0lORV9UUkFDRSgiYXJndldbJWRdID0gJXNcbiIsIGksIHdpbmVfZGJnc3RyX3coYXJndldbaV0pKTsKCQkJTGFuZ3VhZ2UgPSBtc2lfYXRvdShhcmd2V1tpXSk7CgkJfQoJCWVsc2UgaWYoIW1zaV9zdHJwcmVmaXgoYXJndldbaV0sICIvbCIpKQoJCXsKCQkJaW50IGo7CgkJCWludCBsZW4gPSBsc3RybGVuVyhhcmd2V1tpXSk7CgkJCWZvcihqID0gMjsgaiA8IGxlbjsgaisrKQoJCQl7CgkJCQlzd2l0Y2goYXJndldbaV1bal0pCgkJCQl7CgkJCQkJY2FzZSAnSSc6CgkJCQkJY2FzZSAnaSc6CgkJCQkJCUxvZ01vZGUgfD0gSU5TVEFMTExPR01PREVfSU5GTzsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnVyc6CgkJCQkJY2FzZSAndyc6CgkJCQkJCUxvZ01vZGUgfD0gSU5TVEFMTExPR01PREVfV0FSTklORzsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnRSc6CgkJCQkJY2FzZSAnZSc6CgkJCQkJCUxvZ01vZGUgfD0gSU5TVEFMTExPR01PREVfRVJST1I7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ0EnOgoJCQkJCWNhc2UgJ2EnOgoJCQkJCQlMb2dNb2RlIHw9IElOU1RBTExMT0dNT0RFX0FDVElPTlNUQVJUOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdSJzoKCQkJCQljYXNlICdyJzoKCQkJCQkJTG9nTW9kZSB8PSBJTlNUQUxMTE9HTU9ERV9BQ1RJT05EQVRBOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdVJzoKCQkJCQljYXNlICd1JzoKCQkJCQkJTG9nTW9kZSB8PSBJTlNUQUxMTE9HTU9ERV9VU0VSOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdDJzoKCQkJCQljYXNlICdjJzoKCQkJCQkJTG9nTW9kZSB8PSBJTlNUQUxMTE9HTU9ERV9DT01NT05EQVRBOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdNJzoKCQkJCQljYXNlICdtJzoKCQkJCQkJTG9nTW9kZSB8PSBJTlNUQUxMTE9HTU9ERV9GQVRBTEVYSVQ7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ08nOgoJCQkJCWNhc2UgJ28nOgoJCQkJCQlMb2dNb2RlIHw9IElOU1RBTExMT0dNT0RFX09VVE9GRElTS1NQQUNFOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdQJzoKCQkJCQljYXNlICdwJzoKCQkJCQkJTG9nTW9kZSB8PSBJTlNUQUxMTE9HTU9ERV9QUk9QRVJUWURVTVA7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ1YnOgoJCQkJCWNhc2UgJ3YnOgoJCQkJCQlMb2dNb2RlIHw9IElOU1RBTExMT0dNT0RFX1ZFUkJPU0U7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJyonOgoJCQkJCQlMb2dNb2RlID0gSU5TVEFMTExPR01PREVfRkFUQUxFWElUIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX0VSUk9SIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX1dBUk5JTkcgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfVVNFUiB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9JTkZPIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX1JFU09MVkVTT1VSQ0UgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfT1VUT0ZESVNLU1BBQ0UgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfQUNUSU9OU1RBUlQgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfQUNUSU9OREFUQSB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9DT01NT05EQVRBIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX1BST1BFUlRZRFVNUCB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9QUk9HUkVTUyB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9JTklUSUFMSVpFIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX1RFUk1JTkFURSB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9TSE9XRElBTE9HOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICcrJzoKCQkJCQkJTG9nQXR0cmlidXRlcyB8PSBJTlNUQUxMTE9HQVRUUklCVVRFU19BUFBFTkQ7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJyEnOgoJCQkJCQlMb2dBdHRyaWJ1dGVzIHw9IElOU1RBTExMT0dBVFRSSUJVVEVTX0ZMVVNIRUFDSExJTkU7CgkJCQkJCWJyZWFrOwoJCQkJCWRlZmF1bHQ6CgkJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoJCQlMb2dGaWxlTmFtZSA9IGFyZ3ZXW2ldOwoJCQlpZihNc2lFbmFibGVMb2dXKExvZ01vZGUsIExvZ0ZpbGVOYW1lLCBMb2dBdHRyaWJ1dGVzKSAhPSBFUlJPUl9TVUNDRVNTKQoJCQl7CgkJCQlmcHJpbnRmKHN0ZGVyciwgIkxvZ2dpbmcgaW4gJXMgKDB4JTA4bHgsICVsdSkgZmFpbGVkXG4iLAoJCQkJCSB3aW5lX2RiZ3N0cl93KExvZ0ZpbGVOYW1lKSwgTG9nTW9kZSwgTG9nQXR0cmlidXRlcyk7CgkJCQlFeGl0UHJvY2VzcygxKTsKCQkJfQoJCX0KCQllbHNlIGlmKCFtc2lfc3RyZXF1YWwoYXJndldbaV0sICIvcCIpKQoJCXsKCQkJRnVuY3Rpb25QYXRjaCA9IFRSVUU7CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoJCQlQYXRjaEZpbGVOYW1lID0gYXJndldbaV07CgkJfQoJCWVsc2UgaWYoIW1zaV9zdHJwcmVmaXgoYXJndldbaV0sICIvcSIpKQoJCXsKCQkJaWYobHN0cmxlblcoYXJndldbaV0pID09IDIgfHwgIW1zaV9zdHJlcXVhbChhcmd2V1tpXSsyLCAibiIpKQoJCQl7CgkJCQlJbnN0YWxsVUlMZXZlbCA9IElOU1RBTExVSUxFVkVMX05PTkU7CgkJCX0KCQkJZWxzZSBpZighbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldKzIsICJiIikpCgkJCXsKCQkJCUluc3RhbGxVSUxldmVsID0gSU5TVEFMTFVJTEVWRUxfQkFTSUM7CgkJCX0KCQkJZWxzZSBpZighbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldKzIsICJyIikpCgkJCXsKCQkJCUluc3RhbGxVSUxldmVsID0gSU5TVEFMTFVJTEVWRUxfUkVEVUNFRDsKCQkJfQoJCQllbHNlIGlmKCFtc2lfc3RyZXF1YWwoYXJndldbaV0rMiwgImYiKSkKCQkJewoJCQkJSW5zdGFsbFVJTGV2ZWwgPSBJTlNUQUxMVUlMRVZFTF9GVUxMfElOU1RBTExVSUxFVkVMX0VORERJQUxPRzsKCQkJfQoJCQllbHNlIGlmKCFtc2lfc3RyZXF1YWwoYXJndldbaV0rMiwgIm4rIikpCgkJCXsKCQkJCUluc3RhbGxVSUxldmVsID0gSU5TVEFMTFVJTEVWRUxfTk9ORXxJTlNUQUxMVUlMRVZFTF9FTkRESUFMT0c7CgkJCX0KCQkJZWxzZSBpZighbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldKzIsICJiKyIpKQoJCQl7CgkJCQlJbnN0YWxsVUlMZXZlbCA9IElOU1RBTExVSUxFVkVMX0JBU0lDfElOU1RBTExVSUxFVkVMX0VORERJQUxPRzsKCQkJfQoJCQllbHNlIGlmKCFtc2lfc3RyZXF1YWwoYXJndldbaV0rMiwgImItIikpCgkJCXsKCQkJCUluc3RhbGxVSUxldmVsID0gSU5TVEFMTFVJTEVWRUxfQkFTSUN8SU5TVEFMTFVJTEVWRUxfUFJPR1JFU1NPTkxZOwoJCQl9CgkJCWVsc2UgaWYoIW1zaV9zdHJlcXVhbChhcmd2V1tpXSsyLCAiYishIikpCgkJCXsKCQkJCUluc3RhbGxVSUxldmVsID0gSU5TVEFMTFVJTEVWRUxfQkFTSUN8SU5TVEFMTFVJTEVWRUxfRU5ERElBTE9HOwoJCQkJV0lORV9GSVhNRSgiVW5rbm93biBtb2RpZmllcjogIVxuIik7CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQlmcHJpbnRmKHN0ZGVyciwgIlVua25vd24gb3B0aW9uIFwiJXNcIiBmb3IgVUkgbGV2ZWxcbiIsCgkJCQkJIHdpbmVfZGJnc3RyX3coYXJndldbaV0rMikpOwoJCQl9CgkJfQoJCWVsc2UgaWYoIW1zaV9zdHJlcXVhbChhcmd2V1tpXSwgIi95IikpCgkJewoJCQlGdW5jdGlvbkRsbFJlZ2lzdGVyU2VydmVyID0gVFJVRTsKCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgkJCURsbE5hbWUgPSBhcmd2V1tpXTsKCQl9CgkJZWxzZSBpZighbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldLCAiL3oiKSkKCQl7CgkJCUZ1bmN0aW9uRGxsVW5yZWdpc3RlclNlcnZlciA9IFRSVUU7CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoJCQlEbGxOYW1lID0gYXJndldbaV07CgkJfQoJCWVsc2UgaWYoIW1zaV9zdHJlcXVhbChhcmd2V1tpXSwgIi9oIikgfHwgIW1zaV9zdHJlcXVhbChhcmd2V1tpXSwgIi8/IikpCgkJewoJCQlTaG93VXNhZ2UoMCk7CgkJfQoJCWVsc2UgaWYoIW1zaV9zdHJlcXVhbChhcmd2V1tpXSwgIi9tIikpCgkJewoJCQlGdW5jdGlvblVua25vd24gPSBUUlVFOwoJCQlXSU5FX0ZJWE1FKCJVbmtub3duIHBhcmFtZXRlciAvbVxuIik7CgkJfQoJCWVsc2UgaWYoIW1zaV9zdHJlcXVhbChhcmd2V1tpXSwgIi9EIikpCgkJewoJCQlGdW5jdGlvblVua25vd24gPSBUUlVFOwoJCQlXSU5FX0ZJWE1FKCJVbmtub3duIHBhcmFtZXRlciAvRFxuIik7CgkJfQoJCWVsc2UgaWYoc3RyY2hyVyhhcmd2V1tpXSwgJz0nKSkKCQl7CgkJCVN0cmluZ0xpc3RBcHBlbmQoJnByb3BlcnR5X2xpc3QsIGFyZ3ZXW2ldKTsKCQl9CgkJZWxzZQoJCXsKCQkJRnVuY3Rpb25JbnN0YWxsID0gVFJVRTsKCQkJUGFja2FnZU5hbWUgPSBhcmd2V1tpXTsKCQl9Cgl9CgoJLyogc3RhcnQgdGhlIEdVSSAqLwoJTXNpU2V0SW50ZXJuYWxVSShJbnN0YWxsVUlMZXZlbCwgTlVMTCk7CgoJUHJvcGVydGllcyA9IGJ1aWxkX3Byb3BlcnRpZXMoIHByb3BlcnR5X2xpc3QgKTsKCVRyYW5zZm9ybXMgPSBidWlsZF90cmFuc2Zvcm1zKCB0cmFuc2Zvcm1fbGlzdCApOwoKCWlmKEZ1bmN0aW9uSW5zdGFsbEFkbWluICYmIEZ1bmN0aW9uUGF0Y2gpCgkJRnVuY3Rpb25JbnN0YWxsID0gRkFMU0U7CgoJUmV0dXJuQ29kZSA9IDE7CglpZihGdW5jdGlvbkluc3RhbGwpCgl7CgkJaWYoSXNQcm9kdWN0Q29kZShQYWNrYWdlTmFtZSkpCgkJCVJldHVybkNvZGUgPSBNc2lDb25maWd1cmVQcm9kdWN0RXhXKFBhY2thZ2VOYW1lLCAwLCBJTlNUQUxMU1RBVEVfREVGQVVMVCwgUHJvcGVydGllcyk7CgkJZWxzZQoJCQlSZXR1cm5Db2RlID0gTXNpSW5zdGFsbFByb2R1Y3RXKFBhY2thZ2VOYW1lLCBQcm9wZXJ0aWVzKTsKCX0KCWVsc2UgaWYoRnVuY3Rpb25SZXBhaXIpCgl7CgkJaWYoSXNQcm9kdWN0Q29kZShQYWNrYWdlTmFtZSkpCgkJCVdJTkVfRklYTUUoIlByb2R1Y3QgY29kZSB0cmVhdG1lbnQgbm90IGltcGxlbWVudGVkIHlldFxuIik7CgkJZWxzZQoJCQlSZXR1cm5Db2RlID0gTXNpUmVpbnN0YWxsUHJvZHVjdFcoUGFja2FnZU5hbWUsIFJlcGFpck1vZGUpOwoJfQoJZWxzZSBpZihGdW5jdGlvbkFkdmVydGlzZSkKCXsKCQlSZXR1cm5Db2RlID0gTXNpQWR2ZXJ0aXNlUHJvZHVjdFcoUGFja2FnZU5hbWUsIChMUFdTVFIpIEFkdmVydGlzZU1vZGUsIFRyYW5zZm9ybXMsIExhbmd1YWdlKTsKCX0KCWVsc2UgaWYoRnVuY3Rpb25QYXRjaCkKCXsKCQlSZXR1cm5Db2RlID0gTXNpQXBwbHlQYXRjaFcoUGF0Y2hGaWxlTmFtZSwgUGFja2FnZU5hbWUsIEluc3RhbGxUeXBlLCBQcm9wZXJ0aWVzKTsKCX0KCWVsc2UgaWYoRnVuY3Rpb25EbGxSZWdpc3RlclNlcnZlcikKCXsKCQlSZXR1cm5Db2RlID0gRG9EbGxSZWdpc3RlclNlcnZlcihEbGxOYW1lKTsKCX0KCWVsc2UgaWYoRnVuY3Rpb25EbGxVbnJlZ2lzdGVyU2VydmVyKQoJewoJCVJldHVybkNvZGUgPSBEb0RsbFVucmVnaXN0ZXJTZXJ2ZXIoRGxsTmFtZSk7Cgl9CgllbHNlIGlmIChGdW5jdGlvblJlZ1NlcnZlcikKCXsKCQlXSU5FX0ZJWE1FKCAiL3JlZ3NlcnZlciBub3QgaW1wbGVtZW50ZWQgeWV0LCBpZ25vcmluZ1xuIiApOwoJfQoJZWxzZSBpZiAoRnVuY3Rpb25VbnJlZ1NlcnZlcikKCXsKCQlXSU5FX0ZJWE1FKCAiL3VucmVnc2VydmVyIG5vdCBpbXBsZW1lbnRlZCB5ZXQsIGlnbm9yaW5nXG4iICk7Cgl9CgllbHNlIGlmIChGdW5jdGlvblVua25vd24pCgl7CgkJV0lORV9GSVhNRSggIlVua25vd24gZnVuY3Rpb24sIGlnbm9yaW5nXG4iICk7Cgl9CgllbHNlCgkJU2hvd1VzYWdlKDEpOwoKCXJldHVybiBSZXR1cm5Db2RlOwp9Cg==