Lyogdmk6IHNldCBzdz00IHRzPTQ6ICovCi8qCiAqICByZWFkcHJvZmlsZS5jIC0gdXNlZCB0byByZWFkIC9wcm9jL3Byb2ZpbGUKICoKICogIENvcHlyaWdodCAoQykgMTk5NCwxOTk2IEFsZXNzYW5kcm8gUnViaW5pIChydWJpbmlAaXB2dmlzLnVuaXB2Lml0KQogKgogKiBMaWNlbnNlZCB1bmRlciBHUEx2MiBvciBsYXRlciwgc2VlIGZpbGUgTElDRU5TRSBpbiB0aGlzIHRhcmJhbGwgZm9yIGRldGFpbHMuCiAqLwoKLyoKICogMTk5OS0wMi0yMiBBcmthZGl1c3ogTWm2a2lld2ljeiA8bWlzaWVrQHBsZC5PUkcuUEw+CiAqIC0gYWRkZWQgTmF0aXZlIExhbmd1YWdlIFN1cHBvcnQKICogMTk5OS0wOS0wMSBTdGVwaGFuZSBFcmFuaWFuIDxlcmFuaWFuQGNlbGxvLmhwbC5ocC5jb20+CiAqIC0gNjRiaXQgY2xlYW4gcGF0Y2gKICogM0ZlYjIwMDEgQW5kcmV3IE1vcnRvbiA8YW5kcmV3bUB1b3cuZWR1LmF1PgogKiAtIC1NIG9wdGlvbiB0byB3cml0ZSBwcm9maWxlIG11bHRpcGxpZXIuCiAqIDIwMDEtMTEtMDcgV2VybmVyIEFsbWVzYmVyZ2VyIDx3YUBhbG1lc2Jlcmdlci5uZXQ+CiAqIC0gYnl0ZSBvcmRlciBhdXRvLWRldGVjdGlvbiBhbmQgLW4gb3B0aW9uCiAqIDIwMDEtMTEtMDkgV2VybmVyIEFsbWVzYmVyZ2VyIDx3YUBhbG1lc2Jlcmdlci5uZXQ+CiAqIC0gc2tpcCBzdGVwIHNpemUgKGluZGV4IDApCiAqIDIwMDItMDMtMDkgSm9obiBMZXZvbiA8bW96QGNvbXBzb2MubWFuLmFjLnVrPgogKiAtIG1ha2UgbWFwbGluZW5vIGRvIHNvbWV0aGluZwogKiAyMDAyLTExLTI4IE1hZHMgTWFydGluIEpvZXJnZW5zZW4gKwogKiAtIGFsc28gdHJ5IC9ib290L1N5c3RlbS5tYXAtYHVuYW1lIC1yYAogKiAyMDAzLTA0LTA5IFdlcm5lciBBbG1lc2JlcmdlciA8d2FAYWxtZXNiZXJnZXIubmV0PgogKiAtIGZpeGVkIG9mZi1ieSBlaWdodCBlcnJvciBhbmQgaW1wcm92ZWQgaGV1cmlzdGljcyBpbiBieXRlIG9yZGVyIGRldGVjdGlvbgogKiAyMDAzLTA4LTEyIE5pa2l0YSBEYW5pbG92IDxOaWtpdGFATmFtZXN5cy5DT00+CiAqIC0gYWRkZWQgLXMgb3B0aW9uOyBleGFtcGxlIG9mIHVzZToKICogInJlYWRwcm9maWxlIC1zIC1tIC9ib290L1N5c3RlbS5tYXAtdGVzdCB8IGdyZXAgX19kX2xvb2t1cCB8IHNvcnQgLW4gLWszIgogKgogKiBUYWtlbiBmcm9tIHV0aWwtbGludXggYW5kIGFkYXB0ZWQgZm9yIGJ1c3lib3ggYnkKICogUGF1bCBNdW5kdCA8bGV0aGFsQGxpbnV4LXNoLm9yZz4uCiAqLwoKI2luY2x1ZGUgImxpYmJiLmgiCiNpbmNsdWRlIDxzeXMvdXRzbmFtZS5oPgoKI2RlZmluZSBTX0xFTiAxMjgKCi8qIFRoZXNlIGFyZSB0aGUgZGVmYXVsdHMgKi8Kc3RhdGljIGNvbnN0IGNoYXIgZGVmYXVsdG1hcFtdID0gIi9ib290L1N5c3RlbS5tYXAiOwpzdGF0aWMgY29uc3QgY2hhciBkZWZhdWx0cHJvW10gPSAiL3Byb2MvcHJvZmlsZSI7CgppbnQgcmVhZHByb2ZpbGVfbWFpbihpbnQgYXJnYywgY2hhciAqKmFyZ3YpOwppbnQgcmVhZHByb2ZpbGVfbWFpbihpbnQgYXJnYywgY2hhciAqKmFyZ3YpCnsKCUZJTEUgKm1hcDsKCWNvbnN0IGNoYXIgKm1hcEZpbGUsICpwcm9GaWxlLCAqbXVsdCA9IDA7Cgl1bnNpZ25lZCBsb25nIGluZHggPSAxOwoJc2l6ZV90IGxlbjsKCXVpbnQ2NF90IGFkZDAgPSAwOwoJdW5zaWduZWQgaW50IHN0ZXA7Cgl1bnNpZ25lZCBpbnQgKmJ1ZiwgdG90YWwsIGZuX2xlbjsKCXVuc2lnbmVkIGxvbmcgbG9uZyBmbl9hZGQsIG5leHRfYWRkOyAgICAgLyogY3VycmVudCBhbmQgbmV4dCBhZGRyZXNzICovCgljaGFyIGZuX25hbWVbU19MRU5dLCBuZXh0X25hbWVbU19MRU5dOyAgIC8qIGN1cnJlbnQgYW5kIG5leHQgbmFtZSAqLwoJY2hhciBtYXBsaW5lW1NfTEVOXTsKCWNoYXIgbW9kZVs4XTsKCWludCBvcHRBbGwgPSAwLCBvcHRJbmZvID0gMCwgb3B0UmVzZXQgPSAwOwoJaW50IG9wdFZlcmJvc2UgPSAwLCBvcHROYXRpdmUgPSAwOwoJaW50IG9wdEJpbnMgPSAwLCBvcHRTdWIgPSAwOwoJaW50IG1hcGxpbmVubyA9IDE7CglpbnQgaGVhZGVyX3ByaW50ZWQ7CgojZGVmaW5lIG5leHQgKGN1cnJlbnReMSkKCglwcm9GaWxlID0gZGVmYXVsdHBybzsKCW1hcEZpbGUgPSBkZWZhdWx0bWFwOwoKCW9wdF9jb21wbGVtZW50YXJ5ID0gIm5uOmFhOmJiOnNzOmlpOnJyOnZ2IjsKCWdldG9wdDMyKGFyZ2MsIGFyZ3YsICJNOm06cDpuYWJzaXJ2IiwKCQkJJm11bHQsICZtYXBGaWxlLCAmcHJvRmlsZSwKCQkJJm9wdE5hdGl2ZSwgJm9wdEFsbCwgJm9wdEJpbnMsICZvcHRTdWIsCgkJCSZvcHRJbmZvLCAmb3B0UmVzZXQsICZvcHRWZXJib3NlKTsKCglpZiAob3B0UmVzZXQgfHwgbXVsdCkgewoJCWludCBtdWx0aXBsaWVyLCBmZCwgdG9fd3JpdGU7CgoJCS8qCgkJICogV2hlbiB3cml0aW5nIHRoZSBtdWx0aXBsaWVyLCBpZiB0aGUgbGVuZ3RoIG9mIHRoZSB3cml0ZSBpcwoJCSAqIG5vdCBzaXplb2YoaW50KSwgdGhlIG11bHRpcGxpZXIgaXMgbm90IGNoYW5nZWQKCQkgKi8KCQlpZiAobXVsdCkgewoJCQltdWx0aXBsaWVyID0geGF0b2lfdShtdWx0KTsKCQkJdG9fd3JpdGUgPSBzaXplb2YoaW50KTsKCQl9IGVsc2UgewoJCQltdWx0aXBsaWVyID0gMDsKCQkJdG9fd3JpdGUgPSAxOwkvKiBzdGggZGlmZmVyZW50IGZyb20gc2l6ZW9mKGludCkgKi8KCQl9CgoJCWZkID0geG9wZW4oZGVmYXVsdHBybywgT19XUk9OTFkpOwoKCQlpZiAoZnVsbF93cml0ZShmZCwgJm11bHRpcGxpZXIsIHRvX3dyaXRlKSAhPSB0b193cml0ZSkKCQkJYmJfcGVycm9yX21zZ19hbmRfZGllKCJlcnJvciB3cml0aW5nICVzIiwgZGVmYXVsdHBybyk7CgoJCWNsb3NlKGZkKTsKCQlyZXR1cm4gRVhJVF9TVUNDRVNTOwoJfQoKCS8qCgkgKiBVc2UgYW4gZmQgZm9yIHRoZSBwcm9maWxpbmcgYnVmZmVyLCB0byBza2lwIHN0ZGlvIG92ZXJoZWFkCgkgKi8KCWxlbiA9IElOVF9NQVg7CglidWYgPSB4bWFsbG9jX29wZW5fcmVhZF9jbG9zZShwcm9GaWxlLCAmbGVuKTsKCWlmICghb3B0TmF0aXZlKSB7CgkJaW50IGVudHJpZXMgPSBsZW4vc2l6ZW9mKCpidWYpOwoJCWludCBiaWcgPSAwLCBzbWFsbCA9IDAsIGk7CgkJdW5zaWduZWQgKnA7CgoJCWZvciAocCA9IGJ1ZisxOyBwIDwgYnVmK2VudHJpZXM7IHArKykgewoJCQlpZiAoKnAgJiB+MFUgPDwgKHNpemVvZigqYnVmKSo0KSkKCQkJCWJpZysrOwoJCQlpZiAoKnAgJiAoKDEgPDwgKHNpemVvZigqYnVmKSo0KSktMSkpCgkJCQlzbWFsbCsrOwoJCX0KCQlpZiAoYmlnID4gc21hbGwpIHsKCQkJYmJfZXJyb3JfbXNnKCJhc3N1bWluZyByZXZlcnNlZCBieXRlIG9yZGVyLCAiCgkJCQkidXNlIC1uIHRvIGZvcmNlIG5hdGl2ZSBieXRlIG9yZGVyIik7CgkJCWZvciAocCA9IGJ1ZjsgcCA8IGJ1ZitlbnRyaWVzOyBwKyspCgkJCQlmb3IgKGkgPSAwOyBpIDwgc2l6ZW9mKCpidWYpLzI7IGkrKykgewoJCQkJCXVuc2lnbmVkIGNoYXIgKmIgPSAodW5zaWduZWQgY2hhciAqKSBwOwoJCQkJCXVuc2lnbmVkIGNoYXIgdG1wOwoKCQkJCQl0bXAgPSBiW2ldOwoJCQkJCWJbaV0gPSBiW3NpemVvZigqYnVmKS1pLTFdOwoJCQkJCWJbc2l6ZW9mKCpidWYpLWktMV0gPSB0bXA7CgkJCQl9CgkJfQoJfQoKCXN0ZXAgPSBidWZbMF07CglpZiAob3B0SW5mbykgewoJCXByaW50ZigiU2FtcGxpbmdfc3RlcDogJWlcbiIsIHN0ZXApOwoJCXJldHVybiBFWElUX1NVQ0NFU1M7Cgl9CgoJdG90YWwgPSAwOwoKCW1hcCA9IHhmb3BlbihtYXBGaWxlLCAiciIpOwoKCXdoaWxlIChmZ2V0cyhtYXBsaW5lLCBTX0xFTiwgbWFwKSkgewoJCWlmIChzc2NhbmYobWFwbGluZSwgIiVsbHggJXMgJXMiLCAmZm5fYWRkLCBtb2RlLCBmbl9uYW1lKSAhPSAzKQoJCQliYl9lcnJvcl9tc2dfYW5kX2RpZSgiJXMoJWkpOiB3cm9uZyBtYXAgbGluZSIsCgkJCQkJICAgICBtYXBGaWxlLCBtYXBsaW5lbm8pOwoKCQlpZiAoIXN0cmNtcChmbl9uYW1lLCAiX3N0ZXh0IikpIC8qIG9ubHkgZWxmIHdvcmtzIGxpa2UgdGhpcyAqLyB7CgkJCWFkZDAgPSBmbl9hZGQ7CgkJCWJyZWFrOwoJCX0KCQltYXBsaW5lbm8rKzsKCX0KCglpZiAoIWFkZDApCgkJYmJfZXJyb3JfbXNnX2FuZF9kaWUoImNhbid0IGZpbmQgXCJfc3RleHRcIiBpbiAlcyIsIG1hcEZpbGUpOwoKCS8qCgkgKiBNYWluIGxvb3AuCgkgKi8KCXdoaWxlIChmZ2V0cyhtYXBsaW5lLCBTX0xFTiwgbWFwKSkgewoJCXVuc2lnbmVkIGludCB0aGlzID0gMDsKCgkJaWYgKHNzY2FuZihtYXBsaW5lLCAiJWxseCAlcyAlcyIsICZuZXh0X2FkZCwgbW9kZSwgbmV4dF9uYW1lKSAhPSAzKQoJCQliYl9lcnJvcl9tc2dfYW5kX2RpZSgiJXMoJWkpOiB3cm9uZyBtYXAgbGluZSIsCgkJCQkJbWFwRmlsZSwgbWFwbGluZW5vKTsKCgkJaGVhZGVyX3ByaW50ZWQgPSAwOwoKCQkvKiBpZ25vcmUgYW55IExFQURJTkcgKGJlZm9yZSBhICdbdFRdJyBzeW1ib2wgaXMgZm91bmQpCgkJICAgQWJzb2x1dGUgc3ltYm9scyAqLwoJCWlmICgoKm1vZGUgPT0gJ0EnIHx8ICptb2RlID09ICc/JykgJiYgdG90YWwgPT0gMCkgY29udGludWU7CgkJaWYgKCptb2RlICE9ICdUJyAmJiAqbW9kZSAhPSAndCcgJiYKCQkgICAgKm1vZGUgIT0gJ1cnICYmICptb2RlICE9ICd3JykKCQkJYnJlYWs7CS8qIG9ubHkgdGV4dCBpcyBwcm9maWxlZCAqLwoKCQlpZiAoaW5keCA+PSBsZW4gLyBzaXplb2YoKmJ1ZikpCgkJCWJiX2Vycm9yX21zZ19hbmRfZGllKCJwcm9maWxlIGFkZHJlc3Mgb3V0IG9mIHJhbmdlLiAiCgkJCQkJICAgICAiV3JvbmcgbWFwIGZpbGU/Iik7CgoJCXdoaWxlIChpbmR4IDwgKG5leHRfYWRkLWFkZDApL3N0ZXApIHsKCQkJaWYgKG9wdEJpbnMgJiYgKGJ1ZltpbmR4XSB8fCBvcHRBbGwpKSB7CgkJCQlpZiAoIWhlYWRlcl9wcmludGVkKSB7CgkJCQkJcHJpbnRmKCIlczpcbiIsIGZuX25hbWUpOwoJCQkJCWhlYWRlcl9wcmludGVkID0gMTsKCQkJCX0KCQkJCXByaW50ZigiXHQlIlBSSXg2NCJcdCV1XG4iLCAoaW5keCAtIDEpKnN0ZXAgKyBhZGQwLCBidWZbaW5keF0pOwoJCQl9CgkJCXRoaXMgKz0gYnVmW2luZHgrK107CgkJfQoJCXRvdGFsICs9IHRoaXM7CgoJCWlmIChvcHRCaW5zKSB7CgkJCWlmIChvcHRWZXJib3NlIHx8IHRoaXMgPiAwKQoJCQkJcHJpbnRmKCIgIHRvdGFsXHRcdFx0XHQldVxuIiwgdGhpcyk7CgkJfSBlbHNlIGlmICgodGhpcyB8fCBvcHRBbGwpICYmCgkJCSAgIChmbl9sZW4gPSBuZXh0X2FkZC1mbl9hZGQpICE9IDApIHsKCQkJaWYgKG9wdFZlcmJvc2UpCgkJCQlwcmludGYoIiUwMTZsbHggJS00MHMgJTZpICU4LjRmXG4iLCBmbl9hZGQsCgkJCQkgICAgICAgZm5fbmFtZSwgdGhpcywgdGhpcy8oZG91YmxlKWZuX2xlbik7CgkJCWVsc2UKCQkJCXByaW50ZigiJTZpICUtNDBzICU4LjRmXG4iLAoJCQkJICAgICAgIHRoaXMsIGZuX25hbWUsIHRoaXMvKGRvdWJsZSlmbl9sZW4pOwoJCQlpZiAob3B0U3ViKSB7CgkJCQl1bnNpZ25lZCBsb25nIGxvbmcgc2NhbjsKCgkJCQlmb3IgKHNjYW4gPSAoZm5fYWRkLWFkZDApL3N0ZXAgKyAxOwoJCQkJICAgICBzY2FuIDwgKG5leHRfYWRkLWFkZDApL3N0ZXA7IHNjYW4rKykgewoJCQkJCXVuc2lnbmVkIGxvbmcgbG9uZyBhZGRyOwoKCQkJCQlhZGRyID0gKHNjYW4gLSAxKSpzdGVwICsgYWRkMDsKCQkJCQlwcmludGYoIlx0JSNsbHhcdCVzKyUjbGx4XHQldVxuIiwKCQkJCQkgICAgICAgYWRkciwgZm5fbmFtZSwgYWRkciAtIGZuX2FkZCwKCQkJCQkgICAgICAgYnVmW3NjYW5dKTsKCQkJCX0KCQkJfQoJCX0KCgkJZm5fYWRkID0gbmV4dF9hZGQ7CgkJc3RyY3B5KGZuX25hbWUsIG5leHRfbmFtZSk7CgoJCW1hcGxpbmVubysrOwoJfQoKCS8qIGNsb2NrIHRpY2tzLCBvdXQgb2Yga2VybmVsIHRleHQgLSBwcm9iYWJseSBtb2R1bGVzICovCglwcmludGYoIiU2aSAlc1xuIiwgYnVmW2xlbi9zaXplb2YoKmJ1ZiktMV0sICIqdW5rbm93bioiKTsKCgkvKiB0cmFpbGVyICovCglpZiAob3B0VmVyYm9zZSkKCQlwcmludGYoIiUwMTZ4ICUtNDBzICU2aSAlOC40ZlxuIiwKCQkgICAgICAgMCwgInRvdGFsIiwgdG90YWwsIHRvdGFsLyhkb3VibGUpKGZuX2FkZC1hZGQwKSk7CgllbHNlCgkJcHJpbnRmKCIlNmkgJS00MHMgJTguNGZcbiIsCgkJICAgICAgIHRvdGFsLCAidG90YWwiLCB0b3RhbC8oZG91YmxlKShmbl9hZGQtYWRkMCkpOwoKCWZjbG9zZShtYXApOwoJZnJlZShidWYpOwoKCXJldHVybiBFWElUX1NVQ0NFU1M7Cn0K