LyogcmFuZGlzdC9sZXZ5LmMKICogCiAqIENvcHlyaWdodCAoQykgMTk5NiwgMTk5NywgMTk5OCwgMTk5OSwgMjAwMCBKYW1lcyBUaGVpbGVyLCBCcmlhbiBHb3VnaAogKiAKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0CiAqIHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICogCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQKICogV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqIAogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQS4KICovCgojaW5jbHVkZSA8Y29uZmlnLmg+CiNpbmNsdWRlIDxtYXRoLmg+CiNpbmNsdWRlIDxnc2wvZ3NsX21hdGguaD4KI2luY2x1ZGUgPGdzbC9nc2xfcm5nLmg+CiNpbmNsdWRlIDxnc2wvZ3NsX3JhbmRpc3QuaD4KCi8qIFRoZSBzdGFibGUgTGV2eSBwcm9iYWJpbGl0eSBkaXN0cmlidXRpb25zIGhhdmUgdGhlIGZvcm0KCiAgIHAoeCkgZHggPSAoMS8oMiBwaSkpIFxpbnQgZHQgZXhwKC0gaXQgeCAtIHxjIHR8XmFscGhhKQoKICAgd2l0aCAwIDwgYWxwaGEgPD0gMi4gCgogICBGb3IgYWxwaGEgPSAxLCB3ZSBnZXQgdGhlIENhdWNoeSBkaXN0cmlidXRpb24KICAgRm9yIGFscGhhID0gMiwgd2UgZ2V0IHRoZSBHYXVzc2lhbiBkaXN0cmlidXRpb24gd2l0aCBzaWdtYSA9IHNxcnQoMikgYy4KCiAgIEZyb21uIENoYXB0ZXIgNSBvZiBCcmF0bGV5LCBGb3ggYW5kIFNjaHJhZ2UgIkEgR3VpZGUgdG8KICAgU2ltdWxhdGlvbiIuIFRoZSBvcmlnaW5hbCByZWZlcmVuY2UgZ2l2ZW4gdGhlcmUgaXMsCgogICBKLk0uIENoYW1iZXJzLCBDLkwuIE1hbGxvd3MgYW5kIEIuIFcuIFN0dWNrLiAiQSBtZXRob2QgZm9yCiAgIHNpbXVsYXRpbmcgc3RhYmxlIHJhbmRvbSB2YXJpYXRlcyIuIEpvdXJuYWwgb2YgdGhlIEFtZXJpY2FuCiAgIFN0YXRpc3RpY2FsIEFzc29jaWF0aW9uLCBKQVNBIDcxIDM0MC0zNDQgKDE5NzYpLgoKICAgKi8KCmRvdWJsZQpnc2xfcmFuX2xldnkgKGNvbnN0IGdzbF9ybmcgKiByLCBjb25zdCBkb3VibGUgYywgY29uc3QgZG91YmxlIGFscGhhKQp7CiAgZG91YmxlIHUsIHYsIHQsIHM7CgogIHUgPSBNX1BJICogKGdzbF9ybmdfdW5pZm9ybV9wb3MgKHIpIC0gMC41KTsKCiAgaWYgKGFscGhhID09IDEpICAgICAgICAgICAgICAgLyogY2F1Y2h5IGNhc2UgKi8KICAgIHsKICAgICAgdCA9IHRhbiAodSk7CiAgICAgIHJldHVybiBjICogdDsKICAgIH0KCiAgZG8KICAgIHsKICAgICAgdiA9IGdzbF9yYW5fZXhwb25lbnRpYWwgKHIsIDEuMCk7CiAgICB9CiAgd2hpbGUgKHYgPT0gMCk7CgogIGlmIChhbHBoYSA9PSAyKSAgICAgICAgICAgICAvKiBnYXVzc2lhbiBjYXNlICovCiAgICB7CiAgICAgIHQgPSAyICogc2luICh1KSAqIHNxcnQodik7CiAgICAgIHJldHVybiBjICogdDsKICAgIH0KCiAgLyogZ2VuZXJhbCBjYXNlICovCgogIHQgPSBzaW4gKGFscGhhICogdSkgLyBwb3cgKGNvcyAodSksIDEgLyBhbHBoYSk7CiAgcyA9IHBvdyAoY29zICgoMSAtIGFscGhhKSAqIHUpIC8gdiwgKDEgLSBhbHBoYSkgLyBhbHBoYSk7CgogIHJldHVybiBjICogdCAqIHM7Cn0KCgovKiBUaGUgZm9sbG93aW5nIHJvdXRpbmUgZm9yIHRoZSBza2V3LXN5bW1ldHJpYyBjYXNlIHdhcyBwcm92aWRlZCBieQogICBLZWl0aCBCcmlnZ3MuCgogICBUaGUgc3RhYmxlIExldnkgcHJvYmFiaWxpdHkgZGlzdHJpYnV0aW9ucyBoYXZlIHRoZSBmb3JtCgogICAyKnBpKiBwKHgpIGR4CgogICAgID0gXGludCBkdCBleHAobXUqaSp0LXxzaWdtYSp0fF5hbHBoYSooMS1pKmJldGEqc2lnbih0KSp0YW4ocGkqYWxwaGEvMikpKSBmb3IgYWxwaGEhPTEKICAgICA9IFxpbnQgZHQgZXhwKG11KmkqdC18c2lnbWEqdHxeYWxwaGEqKDEraSpiZXRhKnNpZ24odCkqMi9waSpsb2cofHR8KSkpICAgZm9yIGFscGhhPT0xCgogICB3aXRoIDA8YWxwaGE8PTIsIC0xPD1iZXRhPD0xLCBzaWdtYT4wLgoKICAgRm9yIGJldGE9MCwgc2lnbWE9YywgbXU9MCwgd2UgZ2V0IGdzbF9yYW5fbGV2eSBhYm92ZS4KCiAgIEZvciBhbHBoYSA9IDEsIGJldGE9MCwgd2UgZ2V0IHRoZSBMb3JlbnR6IGRpc3RyaWJ1dGlvbgogICBGb3IgYWxwaGEgPSAyLCBiZXRhPTAsIHdlIGdldCB0aGUgR2F1c3NpYW4gZGlzdHJpYnV0aW9uCgogICBTZWUgQS4gV2Vyb24gYW5kIFIuIFdlcm9uOiBDb21wdXRlciBzaW11bGF0aW9uIG9mIEzpdnkgYWxwaGEtc3RhYmxlIAogICB2YXJpYWJsZXMgYW5kIHByb2Nlc3NlcywgcHJlcHJpbnQgVGVjaG5pY2FsIFVuaXZlcnNpdHkgb2YgV3JvY2xhdy4KICAgaHR0cDovL3d3dy5pbS5wd3Iud3JvYy5wbC9+aHVnby9QdWJsaWNhdGlvbnMuaHRtbAoKKi8KCmRvdWJsZQpnc2xfcmFuX2xldnlfc2tldyAoY29uc3QgZ3NsX3JuZyAqIHIsIGNvbnN0IGRvdWJsZSBjLCAKICAgICAgICAgICAgICAgICAgIGNvbnN0IGRvdWJsZSBhbHBoYSwgY29uc3QgZG91YmxlIGJldGEpCnsKICBkb3VibGUgViwgVywgWDsKCiAgaWYgKGJldGEgPT0gMCkgIC8qIHN5bW1ldHJpYyBjYXNlICovCiAgICB7CiAgICAgIHJldHVybiBnc2xfcmFuX2xldnkgKHIsIGMsIGFscGhhKTsKICAgIH0KCiAgViA9IE1fUEkgKiAoZ3NsX3JuZ191bmlmb3JtX3BvcyAocikgLSAwLjUpOwoKICBkbwogICAgewogICAgICBXID0gZ3NsX3Jhbl9leHBvbmVudGlhbCAociwgMS4wKTsKICAgIH0KICB3aGlsZSAoVyA9PSAwKTsKCiAgaWYgKGFscGhhID09IDEpCiAgICB7CiAgICAgIFggPSAoKE1fUElfMiArIGJldGEgKiBWKSAqIHRhbiAoVikgLQogICAgICAgICAgIGJldGEgKiBsb2cgKE1fUElfMiAqIFcgKiBjb3MgKFYpIC8gKE1fUElfMiArIGJldGEgKiBWKSkpIC8gTV9QSV8yOwogICAgICByZXR1cm4gYyAqIChYICsgYmV0YSAqIGxvZyAoYykgLyBNX1BJXzIpOwogICAgfQogIGVsc2UKICAgIHsKICAgICAgZG91YmxlIHQgPSBiZXRhICogdGFuIChNX1BJXzIgKiBhbHBoYSk7CiAgICAgIGRvdWJsZSBCID0gYXRhbiAodCkgLyBhbHBoYTsKICAgICAgZG91YmxlIFMgPSBwb3cgKDEgKyB0ICogdCwgMS8oMiAqIGFscGhhKSk7CgogICAgICBYID0gUyAqIHNpbiAoYWxwaGEgKiAoViArIEIpKSAvIHBvdyAoY29zIChWKSwgMSAvIGFscGhhKQogICAgICAgICogcG93IChjb3MgKFYgLSBhbHBoYSAqIChWICsgQikpIC8gVywgKDEgLSBhbHBoYSkgLyBhbHBoYSk7CiAgICAgIHJldHVybiBjICogWDsKICAgIH0KfQo=