LyoKICogQ29weXJpZ2h0IDE5OTkgTWFyY3VzIE1laXNzbmVyCiAqIENvcHlyaWdodCAyMDAyIE1pY2hhZWwgR/xubmV3aWcKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqLwoKI2RlZmluZSBDT01fTk9fV0lORE9XU19ICiNpbmNsdWRlIDxhc3NlcnQuaD4KCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5ubHMuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmRvd3N4LmgiCgojaW5jbHVkZSAib2xlMi5oIgojaW5jbHVkZSAic2hlbGxhcGkuaCIKI2luY2x1ZGUgInZmdy5oIgojaW5jbHVkZSAibXNhY20uaCIKCiNpbmNsdWRlICJhdmlmaWxlX3ByaXZhdGUuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJ3aW5lL3VuaWNvZGUuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGF2aWZpbGUpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIGNvcGllZCBmcm9tIGRsbHMvc2hlbGwzMi91bmRvY3NoZWxsLmgKICovCkhSRVNVTFQgV0lOQVBJIFNIQ29DcmVhdGVJbnN0YW5jZShMUENTVFIgbHBzekNsc2lkLFJFRkNMU0lEIHJDbHNpZCwKCQkJCSAgTFBVTktOT1dOIHBVbmtPdXRlcixSRUZJSUQgcmlpZCxMUFZPSUQgKnBwdik7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogZm9yIEFWSUJ1aWxkRmlsdGVyVyAtLSB1c2VzIGZpeGVkIHNpemUgdGFibGUKICovCiNkZWZpbmUgTUFYX0ZJTFRFUlMgMzAgLyogMzAgPT4gN2tCICovCgp0eXBlZGVmIHN0cnVjdCBfQVZJRmlsdGVyIHsKICBXQ0hBUiBzekNsc2lkWzQwXTsKICBXQ0hBUiBzekV4dGVuc2lvbnNbTUFYX0ZJTFRFUlMgKiA3XTsKfSBBVklGaWx0ZXI7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogZm9yIEFWSVNhdmVPcHRpb25zCiAqLwpzdGF0aWMgc3RydWN0IHsKICBVSU5UICAgICAgICAgICAgICAgICAgdUZsYWdzOwogIElOVCAgICAgICAgICAgICAgICAgICBuU3RyZWFtczsKICBQQVZJU1RSRUFNICAgICAgICAgICAqcHBhdmlzOwogIExQQVZJQ09NUFJFU1NPUFRJT05TICpwcE9wdGlvbnM7CiAgSU5UICAgICAgICAgICAgICAgICAgIG5DdXJyZW50Owp9IFNhdmVPcHRzOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIGNvcGllZCBmcm9tIGRsbHMvb2xlMzIvY29tcG9iai5jCiAqLwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0NMU0lERnJvbVN0cmluZyhMUENTVFIgaWRzdHIsIExQQ0xTSUQgaWQpCnsKICBCWVRFICpzID0gKEJZVEUqKWlkc3RyOwogIEJZVEUgKnA7CiAgSU5UICAgaTsKICBCWVRFIHRhYmxlWzI1Nl07CgogIGlmICghcykgewogICAgbWVtc2V0KHMsIDAsIHNpemVvZihDTFNJRCkpOwogICAgcmV0dXJuIFNfT0s7CiAgfSBlbHNlIHsgIC8qIHZhbGlkYXRlIHRoZSBDTFNJRCBzdHJpbmcgKi8KICAgIGlmIChsc3RybGVuQShzKSAhPSAzOCkKICAgICAgcmV0dXJuIENPX0VfQ0xBU1NTVFJJTkc7CgogICAgaWYgKChzWzBdIT0neycpIHx8IChzWzldIT0nLScpIHx8IChzWzE0XSE9Jy0nKSB8fCAoc1sxOV0hPSctJykgfHwKCShzWzI0XSE9Jy0nKSB8fCAoc1szN10hPSd9JykpCiAgICAgIHJldHVybiBDT19FX0NMQVNTU1RSSU5HOwoKICAgIGZvciAoaSA9IDE7IGkgPCAzNzsgaSsrKSB7CiAgICAgIGlmICgoaSA9PSA5KSB8fCAoaSA9PSAxNCkgfHwgKGkgPT0gMTkpIHx8IChpID09IDI0KSkKCWNvbnRpbnVlOwogICAgICBpZiAoISgoKHNbaV0gPj0gJzAnKSAmJiAoc1tpXSA8PSAnOScpKSAgfHwKCSAgICAoKHNbaV0gPj0gJ2EnKSAmJiAoc1tpXSA8PSAnZicpKSAgfHwKCSAgICAoKHNbaV0gPj0gJ0EnKSAmJiAoc1tpXSA8PSAnRicpKSkKCSAgKQoJcmV0dXJuIENPX0VfQ0xBU1NTVFJJTkc7CiAgICB9CiAgfQoKICBUUkFDRSgiJXMgLT4gJXBcbiIsIHMsIGlkKTsKCiAgLyogcXVpY2sgbG9va3VwIHRhYmxlICovCiAgbWVtc2V0KHRhYmxlLCAwLCAyNTYpOwoKICBmb3IgKGkgPSAwOyBpIDwgMTA7IGkrKykKICAgIHRhYmxlWycwJyArIGldID0gaTsKCiAgZm9yIChpID0gMDsgaSA8IDY7IGkrKykgewogICAgdGFibGVbJ0EnICsgaV0gPSBpKzEwOwogICAgdGFibGVbJ2EnICsgaV0gPSBpKzEwOwogIH0KCiAgLyogaW4gZm9ybSB7WFhYWFhYWFgtWFhYWC1YWFhYLVhYWFgtWFhYWFhYWFhYWFhYfSAqLwogIHAgPSAoQllURSAqKSBpZDsKCiAgcysrOwkvKiBza2lwIGxlYWRpbmcgYnJhY2UgICovCiAgZm9yIChpID0gMDsgaSA8IDQ7IGkrKykgewogICAgcFszIC0gaV0gPSB0YWJsZVsqc108PDQgfCB0YWJsZVsqKHMrMSldOwogICAgcyArPSAyOwogIH0KICBwICs9IDQ7CiAgcysrOwkvKiBza2lwIC0gKi8KCiAgZm9yIChpID0gMDsgaSA8IDI7IGkrKykgewogICAgcFsxLWldID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKICAgIHMgKz0gMjsKICB9CiAgcCArPSAyOwogIHMrKzsJLyogc2tpcCAtICovCgogIGZvciAoaSA9IDA7IGkgPCAyOyBpKyspIHsKICAgIHBbMS1pXSA9IHRhYmxlWypzXTw8NCB8IHRhYmxlWyoocysxKV07CiAgICBzICs9IDI7CiAgfQogIHAgKz0gMjsKICBzKys7CS8qIHNraXAgLSAqLwoKICAvKiB0aGVzZSBhcmUganVzdCBzZXF1ZW50aWFsIGJ5dGVzICovCiAgZm9yIChpID0gMDsgaSA8IDI7IGkrKykgewogICAgKnArKyA9IHRhYmxlWypzXTw8NCB8IHRhYmxlWyoocysxKV07CiAgICBzICs9IDI7CiAgfQogIHMrKzsJLyogc2tpcCAtICovCgogIGZvciAoaSA9IDA7IGkgPCA2OyBpKyspIHsKICAgICpwKysgPSB0YWJsZVsqc108PDQgfCB0YWJsZVsqKHMrMSldOwogICAgcyArPSAyOwogIH0KCiAgcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyBCT09MIEFWSUZJTEVfR2V0RmlsZUhhbmRsZXJCeUV4dGVuc2lvbihMUENXU1RSIHN6RmlsZSwgTFBDTFNJRCBscGNsc2lkKQp7CiAgQ0hBUiAgIHN6UmVnS2V5WzI1XTsKICBDSEFSICAgc3pWYWx1ZVsxMDBdOwogIExQV1NUUiBzekV4dCA9IHN0cnJjaHJXKHN6RmlsZSwgJy4nKTsKICBMT05HICAgbGVuID0gc2l6ZW9mKHN6VmFsdWUpIC8gc2l6ZW9mKHN6VmFsdWVbMF0pOwoKICBpZiAoc3pFeHQgPT0gTlVMTCkKICAgIHJldHVybiBGQUxTRTsKCiAgc3pFeHQrKzsKCiAgd3NwcmludGZBKHN6UmVnS2V5LCAiQVZJRmlsZVxcRXh0ZW5zaW9uc1xcJS4zbHMiLCBzekV4dCk7CiAgaWYgKFJlZ1F1ZXJ5VmFsdWVBKEhLRVlfQ0xBU1NFU19ST09ULCBzelJlZ0tleSwgc3pWYWx1ZSwgJmxlbikgIT0gRVJST1JfU1VDQ0VTUykKICAgIHJldHVybiBGQUxTRTsKCiAgcmV0dXJuIChBVklGSUxFX0NMU0lERnJvbVN0cmluZyhzelZhbHVlLCBscGNsc2lkKSA9PSBTX09LKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlSW5pdAkJKEFWSUZJTDMyLkApCiAqCQlBVklGaWxlSW5pdAkJKEFWSUZJTEUuMTAwKQogKi8Kdm9pZCBXSU5BUEkgQVZJRmlsZUluaXQodm9pZCkgewogIC8qIG5lZWQgdG8gbG9hZCBvbGUzMi5kbGwgaWYgbm90IGFscmVhZHkgZG9uZSBhbmQgZ2V0IHNvbWUgZnVuY3Rpb25zICovCiAgRklYTUUoIigpOiBzdHViIVxuIik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUV4aXQJCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZUV4aXQJCShBVklGSUxFLjEwMSkKICovCnZvaWQgV0lOQVBJIEFWSUZpbGVFeGl0KHZvaWQpIHsKICAvKiBuZWVkIHRvIGZyZWUgb2xlMzIuZGxsIGlmIHdlIGFyZSB0aGUgbGFzdCBleGl0IGNhbGwgKi8KICBGSVhNRSgiKCk6IHN0dWIhXG4iKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlT3BlbkEJCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZU9wZW4JCShBVklGSUxFLjEwMikKICovCkhSRVNVTFQgV0lOQVBJIEFWSUZpbGVPcGVuQShQQVZJRklMRSAqcHBmaWxlLCBMUENTVFIgc3pGaWxlLCBVSU5UIHVNb2RlLAoJCQkgICAgTFBDTFNJRCBscEhhbmRsZXIpCnsKICBMUFdTVFIgIHdzekZpbGUgPSBOVUxMOwogIEhSRVNVTFQgaHI7CiAgaW50ICAgICBsZW47CgogIFRSQUNFKCIoJXAsJXMsMHglMDhYLCVzKVxuIiwgcHBmaWxlLCBkZWJ1Z3N0cl9hKHN6RmlsZSksIHVNb2RlLAoJZGVidWdzdHJfZ3VpZChscEhhbmRsZXIpKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChwcGZpbGUgPT0gTlVMTCB8fCBzekZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIGNvbnZlcnQgQVNDSUkgc3RyaW5nIHRvIFVuaWNvZGUgYW5kIGNhbGwgdW5pY29kZSBmdW5jdGlvbiAqLwogIGxlbiA9IGxzdHJsZW5BKHN6RmlsZSk7CiAgaWYgKGxlbiA8PSAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgd3N6RmlsZSA9IChMUFdTVFIpTG9jYWxBbGxvYyhMUFRSLCAobGVuICsgMSkgKiBzaXplb2YoV0NIQVIpKTsKICBpZiAod3N6RmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzekZpbGUsIC0xLCB3c3pGaWxlLCBsZW4gKyAxKTsKICB3c3pGaWxlW2xlbiArIDFdID0gMDsKCiAgaHIgPSBBVklGaWxlT3BlblcocHBmaWxlLCB3c3pGaWxlLCB1TW9kZSwgbHBIYW5kbGVyKTsKCiAgTG9jYWxGcmVlKChITE9DQUwpd3N6RmlsZSk7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlT3BlblcJCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZU9wZW5XKFBBVklGSUxFICpwcGZpbGUsIExQQ1dTVFIgc3pGaWxlLCBVSU5UIHVNb2RlLAoJCQkgICAgTFBDTFNJRCBscEhhbmRsZXIpCnsKICBJUGVyc2lzdEZpbGUgKnBwZXJzaXN0ID0gTlVMTDsKICBDTFNJRCAgICAgICAgIGNsc2lkSGFuZGxlcjsKICBIUkVTVUxUICAgICAgIGhyOwoKICBUUkFDRSgiKCVwLCVzLDB4JVgsJXMpXG4iLCBwcGZpbGUsIGRlYnVnc3RyX3coc3pGaWxlKSwgdU1vZGUsCglkZWJ1Z3N0cl9ndWlkKGxwSGFuZGxlcikpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKHBwZmlsZSA9PSBOVUxMIHx8IHN6RmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKnBwZmlsZSA9IE5VTEw7CgogIC8qIGlmIG5vIGhhbmRsZXIgdGhlbiB0cnkgZ3Vlc3NpbmcgaXQgYnkgZXh0ZW5zaW9uICovCiAgaWYgKGxwSGFuZGxlciA9PSBOVUxMKSB7CiAgICBpZiAoISBBVklGSUxFX0dldEZpbGVIYW5kbGVyQnlFeHRlbnNpb24oc3pGaWxlLCAmY2xzaWRIYW5kbGVyKSkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9IGVsc2UKICAgIG1lbWNweSgmY2xzaWRIYW5kbGVyLCBscEhhbmRsZXIsIHNpemVvZihjbHNpZEhhbmRsZXIpKTsKCiAgLyogY3JldGUgaW5zdGFuY2Ugb2YgaGFuZGxlciAqLwogIGhyID0gU0hDb0NyZWF0ZUluc3RhbmNlKE5VTEwsICZjbHNpZEhhbmRsZXIsIE5VTEwsCgkJCSAgJklJRF9JQVZJRmlsZSwgKExQVk9JRCopcHBmaWxlKTsKICBpZiAoRkFJTEVEKGhyKSB8fCAqcHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gaHI7CgogIC8qIGFzayBmb3IgSVBlcnNpc3RGaWxlIGludGVyZmFjZSBmb3IgbG9hZGluZy9jcmVhdGluZyB0aGUgZmlsZSAqLwogIGhyID0gSUFWSUZpbGVfUXVlcnlJbnRlcmZhY2UoKnBwZmlsZSwgJklJRF9JUGVyc2lzdEZpbGUsIChMUFZPSUQqKSZwcGVyc2lzdCk7CiAgaWYgKEZBSUxFRChocikgfHwgcHBlcnNpc3QgPT0gTlVMTCkgewogICAgSUFWSUZpbGVfUmVsZWFzZSgqcHBmaWxlKTsKICAgICpwcGZpbGUgPSBOVUxMOwogICAgcmV0dXJuIGhyOwogIH0KCiAgaHIgPSBJUGVyc2lzdEZpbGVfTG9hZChwcGVyc2lzdCwgc3pGaWxlLCB1TW9kZSk7CiAgSVBlcnNpc3RGaWxlX1JlbGVhc2UocHBlcnNpc3QpOwogIGlmIChGQUlMRUQoaHIpKSB7CiAgICBJQVZJRmlsZV9SZWxlYXNlKCpwcGZpbGUpOwogICAgKnBwZmlsZSA9IE5VTEw7CiAgfQoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUFkZFJlZgkJKEFWSUZJTDMyLkApCiAqCQlBVklGaWxlQWRkUmVmCQkoQVZJRklMRS4xNDApCiAqLwpVTE9ORyBXSU5BUEkgQVZJRmlsZUFkZFJlZihQQVZJRklMRSBwZmlsZSkKewogIFRSQUNFKCIoJXApXG4iLCBwZmlsZSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKSB7CiAgICBFUlIoIjogYmFkIGhhbmRsZSBwYXNzZWQhXG4iKTsKICAgIHJldHVybiAwOwogIH0KCiAgcmV0dXJuIElBVklGaWxlX0FkZFJlZihwZmlsZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZVJlbGVhc2UJCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZVJlbGVhc2UJCShBVklGSUxFLjE0MSkKICovClVMT05HIFdJTkFQSSBBVklGaWxlUmVsZWFzZShQQVZJRklMRSBwZmlsZSkKewogIFRSQUNFKCIoJXApXG4iLCBwZmlsZSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKSB7CiAgICBFUlIoIjogYmFkIGhhbmRsZSBwYXNzZWQhXG4iKTsKICAgIHJldHVybiAwOwogIH0KCiAgcmV0dXJuIElBVklGaWxlX1JlbGVhc2UocGZpbGUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVJbmZvCQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVJbmZvQQkJKEFWSUZJTDMyLkApCiAqCQlBVklGaWxlSW5mbwkJKEFWSUZJTEUuMTQyKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZUluZm9BKFBBVklGSUxFIHBmaWxlLCBMUEFWSUZJTEVJTkZPQSBhZmksIExPTkcgc2l6ZSkKewogIEFWSUZJTEVJTkZPVyBhZml3OwogIEhSRVNVTFQgICAgICBocmVzOwoKICBUUkFDRSgiKCVwLCVwLCVsZClcbiIsIHBmaWxlLCBhZmksIHNpemUpOwoKICBpZiAocGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmIChzaXplIDwgc2l6ZW9mKEFWSUZJTEVJTkZPQSkpCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIGhyZXMgPSBJQVZJRmlsZV9JbmZvKHBmaWxlLCAmYWZpdywgc2l6ZW9mKGFmaXcpKTsKCiAgbWVtY3B5KGFmaSwgJmFmaXcsIHNpemVvZigqYWZpKSAtIHNpemVvZihhZmktPnN6RmlsZVR5cGUpKTsKICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgYWZpdy5zekZpbGVUeXBlLCAtMSwgYWZpLT5zekZpbGVUeXBlLAoJCSAgICAgIHNpemVvZihhZmktPnN6RmlsZVR5cGUpLCBOVUxMLCBOVUxMKTsKICBhZmktPnN6RmlsZVR5cGVbc2l6ZW9mKGFmaS0+c3pGaWxlVHlwZSkgLSAxXSA9IDA7CgogIHJldHVybiBocmVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVJbmZvVwkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlSW5mb1coUEFWSUZJTEUgcGZpbGUsIExQQVZJRklMRUlORk9XIGFmaXcsIExPTkcgc2l6ZSkKewogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIiwgcGZpbGUsIGFmaXcsIHNpemUpOwoKICBpZiAocGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSUZpbGVfSW5mbyhwZmlsZSwgYWZpdywgc2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUdldFN0cmVhbQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVHZXRTdHJlYW0JKEFWSUZJTEUuMTQzKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZUdldFN0cmVhbShQQVZJRklMRSBwZmlsZSwgUEFWSVNUUkVBTSAqYXZpcywKCQkJCURXT1JEIGZjY1R5cGUsIExPTkcgbFBhcmFtKQp7CiAgVFJBQ0UoIiglcCwlcCwnJTQuNHMnLCVsZClcbiIsIHBmaWxlLCBhdmlzLCAoY2hhciopJmZjY1R5cGUsIGxQYXJhbSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJRmlsZV9HZXRTdHJlYW0ocGZpbGUsIGF2aXMsIGZjY1R5cGUsIGxQYXJhbSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUNyZWF0ZVN0cmVhbUEJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlQ3JlYXRlU3RyZWFtQShQQVZJRklMRSBwZmlsZSwgUEFWSVNUUkVBTSAqcHBhdmksCgkJCQkgICAgTFBBVklTVFJFQU1JTkZPQSBwc2kpCnsKICBBVklTVFJFQU1JTkZPVwlwc2l3OwoKICBUUkFDRSgiKCVwLCVwLCVwKVxuIiwgcGZpbGUsIHBwYXZpLCBwc2kpOwoKICBpZiAocGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICAvKiBPbmx5IHRoZSBzek5hbWUgYXQgdGhlIGVuZCBpcyBkaWZmZXJlbnQgKi8KICBtZW1jcHkoJnBzaXcsIHBzaSwgc2l6ZW9mKCpwc2kpIC0gc2l6ZW9mKHBzaS0+c3pOYW1lKSk7CiAgTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHBzaS0+c3pOYW1lLCAtMSwgcHNpdy5zek5hbWUsCgkJICAgICAgc2l6ZW9mKHBzaXcuc3pOYW1lKSAvIHNpemVvZihwc2l3LnN6TmFtZVswXSkpOwoKICByZXR1cm4gSUFWSUZpbGVfQ3JlYXRlU3RyZWFtKHBmaWxlLCBwcGF2aSwgJnBzaXcpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVDcmVhdGVTdHJlYW1XCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZUNyZWF0ZVN0cmVhbVcoUEFWSUZJTEUgcGZpbGUsIFBBVklTVFJFQU0gKmF2aXMsCgkJCQkgICAgTFBBVklTVFJFQU1JTkZPVyBhc2kpCnsKICBUUkFDRSgiKCVwLCVwLCVwKVxuIiwgcGZpbGUsIGF2aXMsIGFzaSk7CgogIHJldHVybiBJQVZJRmlsZV9DcmVhdGVTdHJlYW0ocGZpbGUsIGF2aXMsIGFzaSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZVdyaXRlRGF0YQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSUZpbGVXcml0ZURhdGEoUEFWSUZJTEUgcGZpbGUsRFdPUkQgZmNjLExQVk9JRCBscCxMT05HIHNpemUpCnsKICBUUkFDRSgiKCVwLCclNC40cycsJXAsJWxkKVxuIiwgcGZpbGUsIChjaGFyKikmZmNjLCBscCwgc2l6ZSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJRmlsZV9Xcml0ZURhdGEocGZpbGUsIGZjYywgbHAsIHNpemUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVSZWFkRGF0YQkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlUmVhZERhdGEoUEFWSUZJTEUgcGZpbGUsRFdPUkQgZmNjLExQVk9JRCBscCxMUExPTkcgc2l6ZSkKewogIFRSQUNFKCIoJXAsJyU0LjRzJywlcCwlcClcbiIsIHBmaWxlLCAoY2hhciopJmZjYywgbHAsIHNpemUpOwoKICBpZiAocGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSUZpbGVfUmVhZERhdGEocGZpbGUsIGZjYywgbHAsIHNpemUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVFbmRSZWNvcmQJKEFWSUZJTDMyLkApCiAqCQlBVklGaWxlRW5kUmVjb3JkCShBVklGSUxFLjE0OCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSUZpbGVFbmRSZWNvcmQoUEFWSUZJTEUgcGZpbGUpCnsKICBUUkFDRSgiKCVwKVxuIiwgcGZpbGUpOwoKICBpZiAocGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSUZpbGVfRW5kUmVjb3JkKHBmaWxlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1BZGRSZWYJCShBVklGSUwzMi5AKQogKgkJQVZJU3RyZWFtQWRkUmVmCQkoQVZJRklMRS4xNjApCiAqLwpVTE9ORyBXSU5BUEkgQVZJU3RyZWFtQWRkUmVmKFBBVklTVFJFQU0gcHN0cmVhbSkKewogIFRSQUNFKCIoJXApXG4iLCBwc3RyZWFtKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkgewogICAgRVJSKCI6IGJhZCBoYW5kbGUgcGFzc2VkIVxuIik7CiAgICByZXR1cm4gMDsKICB9CgogIHJldHVybiBJQVZJU3RyZWFtX0FkZFJlZihwc3RyZWFtKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1SZWxlYXNlCShBVklGSUwzMi5AKQogKgkJQVZJU3RyZWFtUmVsZWFzZQkoQVZJRklMRS4xNjEpCiAqLwpVTE9ORyBXSU5BUEkgQVZJU3RyZWFtUmVsZWFzZShQQVZJU1RSRUFNIHBzdHJlYW0pCnsKICBUUkFDRSgiKCVwKVxuIiwgcHN0cmVhbSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpIHsKICAgIEVSUigiOiBiYWQgaGFuZGxlIHBhc3NlZCFcbiIpOwogICAgcmV0dXJuIDA7CiAgfQoKICByZXR1cm4gSUFWSVN0cmVhbV9SZWxlYXNlKHBzdHJlYW0pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUNyZWF0ZQkJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1DcmVhdGUJCShBVklGSUxFLjEwNCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbUNyZWF0ZShQQVZJU1RSRUFNICpwcGF2aSwgTE9ORyBsUGFyYW0xLCBMT05HIGxQYXJhbTIsCgkJCSAgICAgICBMUENMU0lEIHBjbHNpZEhhbmRsZXIpCnsKICBIUkVTVUxUIGhyOwoKICBUUkFDRSgiKCVwLDB4JTA4bFgsMHglMDhsWCwlcylcbiIsIHBwYXZpLCBsUGFyYW0xLCBsUGFyYW0yLAoJZGVidWdzdHJfZ3VpZChwY2xzaWRIYW5kbGVyKSk7CgogIGlmIChwcGF2aSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKnBwYXZpID0gTlVMTDsKICBpZiAocGNsc2lkSGFuZGxlciA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgaHIgPSBTSENvQ3JlYXRlSW5zdGFuY2UoTlVMTCwgcGNsc2lkSGFuZGxlciwgTlVMTCwKCQkJICAmSUlEX0lBVklTdHJlYW0sIChMUFZPSUQqKXBwYXZpKTsKICBpZiAoRkFJTEVEKGhyKSB8fCAqcHBhdmkgPT0gTlVMTCkKICAgIHJldHVybiBocjsKCiAgaHIgPSBJQVZJU3RyZWFtX0NyZWF0ZSgqcHBhdmksIGxQYXJhbTEsIGxQYXJhbTIpOwogIGlmIChGQUlMRUQoaHIpKSB7CiAgICBJQVZJU3RyZWFtX1JlbGVhc2UoKnBwYXZpKTsKICAgICpwcGF2aSA9IE5VTEw7CiAgfQoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtSW5mb0EJCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtSW5mb0EoUEFWSVNUUkVBTSBwc3RyZWFtLCBMUEFWSVNUUkVBTUlORk9BIGFzaSwKCQkJICAgICAgTE9ORyBzaXplKQp7CiAgQVZJU1RSRUFNSU5GT1cgYXNpdzsKICBIUkVTVUxUCSBocmVzOwoKICBUUkFDRSgiKCVwLCVwLCVsZClcbiIsIHBzdHJlYW0sIGFzaSwgc2l6ZSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKICBpZiAoc2l6ZSA8IHNpemVvZihBVklTVFJFQU1JTkZPQSkpCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIGhyZXMgPSBJQVZJU3RyZWFtX0luZm8ocHN0cmVhbSwgJmFzaXcsIHNpemVvZihhc2l3KSk7CgogIG1lbWNweShhc2ksICZhc2l3LCBzaXplb2YoYXNpdykgLSBzaXplb2YoYXNpdy5zek5hbWUpKTsKICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgYXNpdy5zek5hbWUsIC0xLCBhc2ktPnN6TmFtZSwKCQkgICAgICBzaXplb2YoYXNpLT5zek5hbWUpLCBOVUxMLCBOVUxMKTsKICBhc2ktPnN6TmFtZVtzaXplb2YoYXNpLT5zek5hbWUpIC0gMV0gPSAwOwoKICByZXR1cm4gaHJlczsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1JbmZvVwkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTdHJlYW1JbmZvVyhQQVZJU1RSRUFNIHBzdHJlYW0sIExQQVZJU1RSRUFNSU5GT1cgYXNpLAoJCQkgICAgICBMT05HIHNpemUpCnsKICBUUkFDRSgiKCVwLCVwLCVsZClcbiIsIHBzdHJlYW0sIGFzaSwgc2l6ZSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklTdHJlYW1fSW5mbyhwc3RyZWFtLCBhc2ksIHNpemUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUZpbmRTYW1wbGUJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTdHJlYW1GaW5kU2FtcGxlKFBBVklTVFJFQU0gcHN0cmVhbSwgTE9ORyBwb3MsIERXT1JEIGZsYWdzKQp7CiAgVFJBQ0UoIiglcCwlbGQsMHglbFgpXG4iLCBwc3RyZWFtLCBwb3MsIGZsYWdzKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiAtMTsKCiAgcmV0dXJuIElBVklTdHJlYW1fRmluZFNhbXBsZShwc3RyZWFtLCBwb3MsIGZsYWdzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1SZWFkRm9ybWF0CShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtUmVhZEZvcm1hdChQQVZJU1RSRUFNIHBzdHJlYW0sIExPTkcgcG9zLAoJCQkJICAgTFBWT0lEIGZvcm1hdCwgTFBMT05HIGZvcm1hdHNpemUpCnsKICBUUkFDRSgiKCVwLCVsZCwlcCwlcClcbiIsIHBzdHJlYW0sIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSVN0cmVhbV9SZWFkRm9ybWF0KHBzdHJlYW0sIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1TZXRGb3JtYXQJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTdHJlYW1TZXRGb3JtYXQoUEFWSVNUUkVBTSBwc3RyZWFtLCBMT05HIHBvcywKCQkJCSAgTFBWT0lEIGZvcm1hdCwgTE9ORyBmb3JtYXRzaXplKQp7CiAgVFJBQ0UoIiglcCwlbGQsJXAsJWxkKVxuIiwgcHN0cmVhbSwgcG9zLCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJU3RyZWFtX1NldEZvcm1hdChwc3RyZWFtLCBwb3MsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtUmVhZAkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTdHJlYW1SZWFkKFBBVklTVFJFQU0gcHN0cmVhbSwgTE9ORyBzdGFydCwgTE9ORyBzYW1wbGVzLAoJCQkgICAgIExQVk9JRCBidWZmZXIsIExPTkcgYnVmZmVyc2l6ZSwKCQkJICAgICBMUExPTkcgYnl0ZXNyZWFkLCBMUExPTkcgc2FtcGxlc3JlYWQpCnsKICBUUkFDRSgiKCVwLCVsZCwlbGQsJXAsJWxkLCVwLCVwKVxuIiwgcHN0cmVhbSwgc3RhcnQsIHNhbXBsZXMsIGJ1ZmZlciwKCWJ1ZmZlcnNpemUsIGJ5dGVzcmVhZCwgc2FtcGxlc3JlYWQpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJU3RyZWFtX1JlYWQocHN0cmVhbSwgc3RhcnQsIHNhbXBsZXMsIGJ1ZmZlciwgYnVmZmVyc2l6ZSwKCQkJIGJ5dGVzcmVhZCwgc2FtcGxlc3JlYWQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVdyaXRlCQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbVdyaXRlKFBBVklTVFJFQU0gcHN0cmVhbSwgTE9ORyBzdGFydCwgTE9ORyBzYW1wbGVzLAoJCQkgICAgICBMUFZPSUQgYnVmZmVyLCBMT05HIGJ1ZmZlcnNpemUsIERXT1JEIGZsYWdzLAoJCQkgICAgICBMUExPTkcgc2FtcHdyaXR0ZW4sIExQTE9ORyBieXRlc3dyaXR0ZW4pCnsKICBUUkFDRSgiKCVwLCVsZCwlbGQsJXAsJWxkLDB4JWxYLCVwLCVwKVxuIiwgcHN0cmVhbSwgc3RhcnQsIHNhbXBsZXMsIGJ1ZmZlciwKCWJ1ZmZlcnNpemUsIGZsYWdzLCBzYW1wd3JpdHRlbiwgYnl0ZXN3cml0dGVuKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSVN0cmVhbV9Xcml0ZShwc3RyZWFtLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLCBidWZmZXJzaXplLAoJCQkgIGZsYWdzLCBzYW1wd3JpdHRlbiwgYnl0ZXN3cml0dGVuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1SZWFkRGF0YQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbVJlYWREYXRhKFBBVklTVFJFQU0gcHN0cmVhbSwgRFdPUkQgZmNjLCBMUFZPSUQgbHAsCgkJCQkgTFBMT05HIGxwcmVhZCkKewogIFRSQUNFKCIoJXAsJyU0LjRzJywlcCwlcClcbiIsIHBzdHJlYW0sIChjaGFyKikmZmNjLCBscCwgbHByZWFkKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSVN0cmVhbV9SZWFkRGF0YShwc3RyZWFtLCBmY2MsIGxwLCBscHJlYWQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVdyaXRlRGF0YQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbVdyaXRlRGF0YShQQVZJU1RSRUFNIHBzdHJlYW0sIERXT1JEIGZjYywgTFBWT0lEIGxwLAoJCQkJICBMT05HIHNpemUpCnsKICBUUkFDRSgiKCVwLCclNC40cycsJXAsJWxkKVxuIiwgcHN0cmVhbSwgKGNoYXIqKSZmY2MsIGxwLCBzaXplKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSVN0cmVhbV9Xcml0ZURhdGEocHN0cmVhbSwgZmNjLCBscCwgc2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtR2V0RnJhbWVPcGVuCShBVklGSUwzMi5AKQogKi8KUEdFVEZSQU1FIFdJTkFQSSBBVklTdHJlYW1HZXRGcmFtZU9wZW4oUEFWSVNUUkVBTSBwc3RyZWFtLAoJCQkJICAgICAgIExQQklUTUFQSU5GT0hFQURFUiBscGJpV2FudGVkKQp7CiAgUEdFVEZSQU1FIHBnID0gTlVMTDsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIHBzdHJlYW0sIGxwYmlXYW50ZWQpOwoKICBpZiAoRkFJTEVEKElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UocHN0cmVhbSwgJklJRF9JR2V0RnJhbWUsIChMUFZPSUQqKSZwZykpIHx8CiAgICAgIHBnID09IE5VTEwpIHsKICAgIHBnID0gQVZJRklMRV9DcmVhdGVHZXRGcmFtZShwc3RyZWFtKTsKICAgIGlmIChwZyA9PSBOVUxMKQogICAgICByZXR1cm4gTlVMTDsKICB9CgogIGlmIChGQUlMRUQoSUdldEZyYW1lX1NldEZvcm1hdChwZywgbHBiaVdhbnRlZCwgTlVMTCwgMCwgMCwgLTEsIC0xKSkpIHsKICAgIElHZXRGcmFtZV9SZWxlYXNlKHBnKTsKICAgIHJldHVybiBOVUxMOwogIH0KCiAgcmV0dXJuIHBnOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUdldEZyYW1lCShBVklGSUwzMi5AKQogKi8KTFBWT0lEIFdJTkFQSSBBVklTdHJlYW1HZXRGcmFtZShQR0VURlJBTUUgcGcsIExPTkcgcG9zKQp7CiAgVFJBQ0UoIiglcCwlbGQpXG4iLCBwZywgcG9zKTsKCiAgaWYgKHBnID09IE5VTEwpCiAgICByZXR1cm4gTlVMTDsKCiAgcmV0dXJuIElHZXRGcmFtZV9HZXRGcmFtZShwZywgcG9zKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1HZXRGcmFtZUNsb3NlIChBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtR2V0RnJhbWVDbG9zZShQR0VURlJBTUUgcGcpCnsKICBUUkFDRSgiKCVwKVxuIiwgcGcpOwoKICBpZiAocGcgIT0gTlVMTCkKICAgIHJldHVybiBJR2V0RnJhbWVfUmVsZWFzZShwZyk7CiAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJTWFrZUNvbXByZXNzZWRTdHJlYW0JKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklNYWtlQ29tcHJlc3NlZFN0cmVhbShQQVZJU1RSRUFNICpwcHNDb21wcmVzc2VkLAoJCQkJICAgICAgIFBBVklTVFJFQU0gcHNTb3VyY2UsCgkJCQkgICAgICAgTFBBVklDT01QUkVTU09QVElPTlMgYWNvLAoJCQkJICAgICAgIExQQ0xTSUQgcGNsc2lkSGFuZGxlcikKewogIEFWSVNUUkVBTUlORk9XIGFzaXc7CiAgQ0hBUiAgICAgICAgICAgc3pSZWdLZXlbMjVdOwogIENIQVIgICAgICAgICAgIHN6VmFsdWVbMTAwXTsKICBDTFNJRCAgICAgICAgICBjbHNpZEhhbmRsZXI7CiAgSFJFU1VMVCAgICAgICAgaHI7CiAgTE9ORyAgICAgICAgICAgc2l6ZSA9IHNpemVvZihzelZhbHVlKTsKCiAgVFJBQ0UoIiglcCwlcCwlcCwlcylcbiIsIHBwc0NvbXByZXNzZWQsIHBzU291cmNlLCBhY28sCglkZWJ1Z3N0cl9ndWlkKHBjbHNpZEhhbmRsZXIpKTsKCiAgaWYgKHBwc0NvbXByZXNzZWQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHBzU291cmNlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgKnBwc0NvbXByZXNzZWQgPSBOVUxMOwoKICAvKiBpZiBubyBoYW5kbGVyIGdpdmVuIGdldCBkZWZhdWx0IG9uZXMgYmFzZWQgb24gc3RyZWFtdHlwZSAqLwogIGlmIChwY2xzaWRIYW5kbGVyID09IE5VTEwpIHsKICAgIGhyID0gSUFWSVN0cmVhbV9JbmZvKHBzU291cmNlLCAmYXNpdywgc2l6ZW9mKGFzaXcpKTsKICAgIGlmIChGQUlMRUQoaHIpKQogICAgICByZXR1cm4gaHI7CgogICAgd3NwcmludGZBKHN6UmVnS2V5LCAiQVZJRmlsZVxcQ29tcHJlc3NvcnNcXCU0LjRzIiwgKGNoYXIqKSZhc2l3LmZjY1R5cGUpOwogICAgaWYgKFJlZ1F1ZXJ5VmFsdWVBKEhLRVlfQ0xBU1NFU19ST09ULCBzelJlZ0tleSwgc3pWYWx1ZSwgJnNpemUpICE9IEVSUk9SX1NVQ0NFU1MpCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CiAgICBpZiAoQVZJRklMRV9DTFNJREZyb21TdHJpbmcoc3pWYWx1ZSwgJmNsc2lkSGFuZGxlcikgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9IGVsc2UKICAgIG1lbWNweSgmY2xzaWRIYW5kbGVyLCBwY2xzaWRIYW5kbGVyLCBzaXplb2YoY2xzaWRIYW5kbGVyKSk7CgogIGhyID0gU0hDb0NyZWF0ZUluc3RhbmNlKE5VTEwsICZjbHNpZEhhbmRsZXIsIE5VTEwsCgkJCSAgJklJRF9JQVZJU3RyZWFtLCAoTFBWT0lEKilwcHNDb21wcmVzc2VkKTsKICBpZiAoRkFJTEVEKGhyKSB8fCAqcHBzQ29tcHJlc3NlZCA9PSBOVUxMKQogICAgcmV0dXJuIGhyOwoKICBociA9IElBVklTdHJlYW1fQ3JlYXRlKCpwcHNDb21wcmVzc2VkLCAoTFBBUkFNKXBzU291cmNlLCAoTFBBUkFNKWFjbyk7CiAgaWYgKEZBSUxFRChocikpIHsKICAgIElBVklTdHJlYW1fUmVsZWFzZSgqcHBzQ29tcHJlc3NlZCk7CiAgICAqcHBzQ29tcHJlc3NlZCA9IE5VTEw7CiAgfQoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtT3BlbkZyb21GaWxlICAgKEFWSUZJTEUuMTAzKQogKgkJQVZJU3RyZWFtT3BlbkZyb21GaWxlQQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbU9wZW5Gcm9tRmlsZUEoUEFWSVNUUkVBTSAqcHBhdmksIExQQ1NUUiBzekZpbGUsCgkJCQkgICAgICBEV09SRCBmY2NUeXBlLCBMT05HIGxQYXJhbSwKCQkJCSAgICAgIFVJTlQgbW9kZSwgTFBDTFNJRCBwY2xzaWRIYW5kbGVyKQp7CiAgUEFWSUZJTEUgcGZpbGUgPSBOVUxMOwogIEhSRVNVTFQgIGhyOwoKICBUUkFDRSgiKCVwLCVzLCclNC40cycsJWxkLDB4JVgsJXMpXG4iLCBwcGF2aSwgZGVidWdzdHJfYShzekZpbGUpLAoJKGNoYXIqKSZmY2NUeXBlLCBsUGFyYW0sIG1vZGUsIGRlYnVnc3RyX2d1aWQocGNsc2lkSGFuZGxlcikpOwoKICBpZiAocHBhdmkgPT0gTlVMTCB8fCBzekZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICpwcGF2aSA9IE5VTEw7CgogIGhyID0gQVZJRmlsZU9wZW5BKCZwZmlsZSwgc3pGaWxlLCBtb2RlLCBwY2xzaWRIYW5kbGVyKTsKICBpZiAoRkFJTEVEKGhyKSB8fCBwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIGhyOwoKICBociA9IElBVklGaWxlX0dldFN0cmVhbShwZmlsZSwgcHBhdmksIGZjY1R5cGUsIGxQYXJhbSk7CiAgSUFWSUZpbGVfUmVsZWFzZShwZmlsZSk7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1PcGVuRnJvbUZpbGVXCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtT3BlbkZyb21GaWxlVyhQQVZJU1RSRUFNICpwcGF2aSwgTFBDV1NUUiBzekZpbGUsCgkJCQkgICAgICBEV09SRCBmY2NUeXBlLCBMT05HIGxQYXJhbSwKCQkJCSAgICAgIFVJTlQgbW9kZSwgTFBDTFNJRCBwY2xzaWRIYW5kbGVyKQp7CiAgUEFWSUZJTEUgcGZpbGUgPSBOVUxMOwogIEhSRVNVTFQgIGhyOwoKICBUUkFDRSgiKCVwLCVzLCclNC40cycsJWxkLDB4JVgsJXMpXG4iLCBwcGF2aSwgZGVidWdzdHJfdyhzekZpbGUpLAoJKGNoYXIqKSZmY2NUeXBlLCBsUGFyYW0sIG1vZGUsIGRlYnVnc3RyX2d1aWQocGNsc2lkSGFuZGxlcikpOwoKICBpZiAocHBhdmkgPT0gTlVMTCB8fCBzekZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICpwcGF2aSA9IE5VTEw7CgogIGhyID0gQVZJRmlsZU9wZW5XKCZwZmlsZSwgc3pGaWxlLCBtb2RlLCBwY2xzaWRIYW5kbGVyKTsKICBpZiAoRkFJTEVEKGhyKSB8fCBwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIGhyOwoKICBociA9IElBVklGaWxlX0dldFN0cmVhbShwZmlsZSwgcHBhdmksIGZjY1R5cGUsIGxQYXJhbSk7CiAgSUFWSUZpbGVfUmVsZWFzZShwZmlsZSk7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1TdGFydAkJKEFWSUZJTEUuMTMwKQogKgkJQVZJU3RyZWFtU3RhcnQJCShBVklGSUwzMi5AKQogKi8KTE9ORyBXSU5BUEkgQVZJU3RyZWFtU3RhcnQoUEFWSVNUUkVBTSBwc3RyZWFtKQp7CiAgQVZJU1RSRUFNSU5GT1cgYXNpdzsKCiAgVFJBQ0UoIiglcClcbiIsIHBzdHJlYW0pOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIDA7CgogIGlmIChGQUlMRUQoSUFWSVN0cmVhbV9JbmZvKHBzdHJlYW0sICZhc2l3LCBzaXplb2YoYXNpdykpKSkKICAgIHJldHVybiAwOwoKICByZXR1cm4gYXNpdy5kd1N0YXJ0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUxlbmd0aAkJKEFWSUZJTEUuMTMxKQogKgkJQVZJU3RyZWFtTGVuZ3RoCQkoQVZJRklMMzIuQCkKICovCkxPTkcgV0lOQVBJIEFWSVN0cmVhbUxlbmd0aChQQVZJU1RSRUFNIHBzdHJlYW0pCnsKICBBVklTVFJFQU1JTkZPVyBhc2l3OwoKICBUUkFDRSgiKCVwKVxuIiwgcHN0cmVhbSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gMDsKCiAgaWYgKEZBSUxFRChJQVZJU3RyZWFtX0luZm8ocHN0cmVhbSwgJmFzaXcsIHNpemVvZihhc2l3KSkpKQogICAgcmV0dXJuIDA7CgogIHJldHVybiBhc2l3LmR3TGVuZ3RoOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVNhbXBsZVRvVGltZQkoQVZJRklMRS4xMzMpCiAqCQlBVklTdHJlYW1TYW1wbGVUb1RpbWUJKEFWSUZJTDMyLkApCiAqLwpMT05HIFdJTkFQSSBBVklTdHJlYW1TYW1wbGVUb1RpbWUoUEFWSVNUUkVBTSBwc3RyZWFtLCBMT05HIGxTYW1wbGUpCnsKICBBVklTVFJFQU1JTkZPVyBhc2l3OwoKICBUUkFDRSgiKCVwLCVsZClcbiIsIHBzdHJlYW0sIGxTYW1wbGUpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIC0xOwoKICBpZiAoRkFJTEVEKElBVklTdHJlYW1fSW5mbyhwc3RyZWFtLCAmYXNpdywgc2l6ZW9mKGFzaXcpKSkpCiAgICByZXR1cm4gLTE7CiAgaWYgKGFzaXcuZHdSYXRlID09IDApCiAgICByZXR1cm4gLTE7CgogIHJldHVybiAoTE9ORykoKChmbG9hdClsU2FtcGxlICogYXNpdy5kd1NjYWxlICogMTAwMC4wKSAvIGFzaXcuZHdSYXRlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1UaW1lVG9TYW1wbGUJKEFWSUZJTEUuMTMyKQogKgkJQVZJU3RyZWFtVGltZVRvU2FtcGxlCShBVklGSUwzMi5AKQogKi8KTE9ORyBXSU5BUEkgQVZJU3RyZWFtVGltZVRvU2FtcGxlKFBBVklTVFJFQU0gcHN0cmVhbSwgTE9ORyBsVGltZSkKewogIEFWSVNUUkVBTUlORk9XIGFzaXc7CgogIFRSQUNFKCIoJXAsJWxkKVxuIiwgcHN0cmVhbSwgbFRpbWUpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIC0xOwoKICBpZiAoRkFJTEVEKElBVklTdHJlYW1fSW5mbyhwc3RyZWFtLCAmYXNpdywgc2l6ZW9mKGFzaXcpKSkpCiAgICByZXR1cm4gLTE7CiAgaWYgKGFzaXcuZHdTY2FsZSA9PSAwKQogICAgcmV0dXJuIC0xOwoKICByZXR1cm4gKExPTkcpKCgoZmxvYXQpbFRpbWUgKiBhc2l3LmR3UmF0ZSkgLyBhc2l3LmR3U2NhbGUgLyAxMDAwLjApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUJ1aWxkRmlsdGVyQQkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklCdWlsZEZpbHRlckEoTFBTVFIgc3pGaWx0ZXIsIExPTkcgY2JGaWx0ZXIsIEJPT0wgZlNhdmluZykKewogIExQV1NUUiAgd3N6RmlsdGVyOwogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsJWxkLCVkKVxuIiwgc3pGaWx0ZXIsIGNiRmlsdGVyLCBmU2F2aW5nKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChzekZpbHRlciA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoY2JGaWx0ZXIgPCAyKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICBzekZpbHRlclswXSA9IDA7CiAgc3pGaWx0ZXJbMV0gPSAwOwoKICB3c3pGaWx0ZXIgPSAoTFBXU1RSKUdsb2JhbEFsbG9jUHRyKEdITkQsIGNiRmlsdGVyKTsKICBpZiAod3N6RmlsdGVyID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgaHIgPSBBVklCdWlsZEZpbHRlclcod3N6RmlsdGVyLCBjYkZpbHRlciwgZlNhdmluZyk7CiAgaWYgKFNVQ0NFRURFRChocikpIHsKICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCB3c3pGaWx0ZXIsIGNiRmlsdGVyLAoJCQlzekZpbHRlciwgY2JGaWx0ZXIsIE5VTEwsIE5VTEwpOwogIH0KCiAgR2xvYmFsRnJlZVB0cih3c3pGaWx0ZXIpOwoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJQnVpbGRGaWx0ZXJXCQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSUJ1aWxkRmlsdGVyVyhMUFdTVFIgc3pGaWx0ZXIsIExPTkcgY2JGaWx0ZXIsIEJPT0wgZlNhdmluZykKewogIHN0YXRpYyBjb25zdCBXQ0hBUiBzekNsc2lkW10gPSB7J0MnLCdMJywnUycsJ0knLCdEJywwfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pFeHRlbnNpb25GbXRbXSA9IHsnOycsJyonLCcuJywnJScsJ3MnLDB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzekFWSUZpbGVFeHRlbnNpb25zW10gPQogICAgeydBJywnVicsJ0knLCdGJywnaScsJ2wnLCdlJywnXFwnLCdFJywneCcsJ3QnLCdlJywnbicsJ3MnLCdpJywnbycsJ24nLCdzJywwfTsKCiAgQVZJRmlsdGVyICpscDsKICBXQ0hBUiAgICAgIHN6QWxsRmlsZXNbNDBdOwogIFdDSEFSICAgICAgc3pGaWxlRXh0WzEwXTsKICBXQ0hBUiAgICAgIHN6VmFsdWVbMTI4XTsKICBIS0VZICAgICAgIGhLZXk7CiAgTE9ORyAgICAgICBuLCBpOwogIExPTkcgICAgICAgc2l6ZTsKICBMT05HICAgICAgIGNvdW50ID0gMDsKCiAgVFJBQ0UoIiglcCwlbGQsJWQpXG4iLCBzekZpbHRlciwgY2JGaWx0ZXIsIGZTYXZpbmcpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKHN6RmlsdGVyID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChjYkZpbHRlciA8IDIpCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIGxwID0gKEFWSUZpbHRlciopR2xvYmFsQWxsb2NQdHIoR0hORCwgTUFYX0ZJTFRFUlMgKiBzaXplb2YoQVZJRmlsdGVyKSk7CiAgaWYgKGxwID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgLyoKICAgKiAxLiBpdGVyYXRlIG92ZXIgSEtFWV9DTEFTU0VTX1JPT1RcXEFWSUZpbGVcXEV4dGVuc2lvbnMgYW5kIGNvbGxlY3QKICAgKiAgICBleHRlbnNpb25zIGFuZCBDTFNJRCdzCiAgICogMi4gaXRlcmF0ZSBvdmVyIGNvbGxlY3RlZCBDTFNJRCdzIGFuZCBjb3B5IGl0J3MgZGVzY3JpcHRpb24gYW5kIGl0J3MKICAgKiAgICBleHRlbnNpb25zIHRvIHN6RmlsdGVyIGlmIGl0IGZpdHMKICAgKgogICAqIEZpcnN0IGZpbHRlciBpcyBuYW1lZCAiQWxsIG11bHRpbWVkaWEgZmlsZXMiIGFuZCBpdCdzIGZpbHRlciBpcyBhCiAgICogY29sbGVjdGlvbiBvZiBhbGwgcG9zc2libGUgZXh0ZW5zaW9ucyBleGNlcHQgIiouKiIuCiAgICovCiAgaWYgKFJlZ09wZW5LZXlXKEhLRVlfQ0xBU1NFU19ST09ULCBzekFWSUZpbGVFeHRlbnNpb25zLCAmaEtleSkgIT0gU19PSykgewogICAgR2xvYmFsRnJlZVB0cihscCk7CiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOwogIH0KICBmb3IgKG4gPSAwO1JlZ0VudW1LZXlXKGhLZXksIG4sIHN6RmlsZUV4dCwgc2l6ZW9mKHN6RmlsZUV4dCkpID09IFNfT0s7bisrKSB7CiAgICAvKiBnZXQgQ0xTSUQgdG8gZXh0ZW5zaW9uICovCiAgICBzaXplID0gc2l6ZW9mKHN6VmFsdWUpL3NpemVvZihzelZhbHVlWzBdKTsKICAgIGlmIChSZWdRdWVyeVZhbHVlVyhoS2V5LCBzekZpbGVFeHQsIHN6VmFsdWUsICZzaXplKSAhPSBTX09LKQogICAgICBicmVhazsKCiAgICAvKiBzZWFyY2ggaWYgdGhlIENMU0lEIGlzIGFscmVhZHkga25vd24gKi8KICAgIGZvciAoaSA9IDE7IGkgPD0gY291bnQ7IGkrKykgewogICAgICBpZiAobHN0cmNtcFcobHBbaV0uc3pDbHNpZCwgc3pWYWx1ZSkgPT0gMCkKCWJyZWFrOyAvKiBhIG5ldyBvbmUgKi8KICAgIH0KCiAgICBpZiAoY291bnQgLSBpID09IC0xKSB7CiAgICAgIC8qIGl0J3MgYSBuZXcgQ0xTSUQgKi8KCiAgICAgIC8qIEZJWE1FOiBIb3cgZG8gd2UgZ2V0IGluZm8ncyBhYm91dCByZWFkL3dyaXRlIGNhcGFiaWxpdGllcz8gKi8KCiAgICAgIGlmIChjb3VudCA+PSBNQVhfRklMVEVSUykgewoJLyogdHJ5IHRvIGluZm9ybSB1c2VyIG9mIG91ciBmdWxsIGZpeGVkIHNpemUgdGFibGUgKi8KCUVSUigiOiBNb3JlIHRoYW4gJWQgZmlsdGVycyBmb3VuZCEgQWRqdXN0IE1BWF9GSUxURVJTIGluIGRsbHMvYXZpZmlsMzIvYXBpLmNcbiIsIE1BWF9GSUxURVJTKTsKCWJyZWFrOwogICAgICB9CgogICAgICBsc3RyY3B5VyhscFtpXS5zekNsc2lkLCBzelZhbHVlKTsKCiAgICAgIGNvdW50Kys7CiAgICB9CgogICAgLyogYXBwZW5kIGV4dGVuc2lvbiB0byB0aGUgZmlsdGVyICovCiAgICB3c3ByaW50Zlcoc3pWYWx1ZSwgc3pFeHRlbnNpb25GbXQsIHN6RmlsZUV4dCk7CiAgICBpZiAobHBbaV0uc3pFeHRlbnNpb25zWzBdID09IDApCiAgICAgIGxzdHJjYXRXKGxwW2ldLnN6RXh0ZW5zaW9ucywgc3pWYWx1ZSArIDEpOwogICAgZWxzZQogICAgICBsc3RyY2F0VyhscFtpXS5zekV4dGVuc2lvbnMsIHN6VmFsdWUpOwoKICAgIC8qIGFsc28gYXBwZW5kIHRvIHRoZSAiYWxsIG11bHRpbWVkaWEiLWZpbHRlciAqLwogICAgaWYgKGxwWzBdLnN6RXh0ZW5zaW9uc1swXSA9PSAwKQogICAgICBsc3RyY2F0VyhscFswXS5zekV4dGVuc2lvbnMsIHN6VmFsdWUgKyAxKTsKICAgIGVsc2UKICAgICAgbHN0cmNhdFcobHBbMF0uc3pFeHRlbnNpb25zLCBzelZhbHVlKTsKICB9CiAgUmVnQ2xvc2VLZXkoaEtleSk7CgogIC8qIDIuIGdldCBkZXNjcmlwdGlvbnMgZm9yIHRoZSBDTFNJRHMgYW5kIGZpbGwgb3V0IHN6RmlsdGVyICovCiAgaWYgKFJlZ09wZW5LZXlXKEhLRVlfQ0xBU1NFU19ST09ULCBzekNsc2lkLCAmaEtleSkgIT0gU19PSykgewogICAgR2xvYmFsRnJlZVB0cihscCk7CiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOwogIH0KICBmb3IgKG4gPSAwOyBuIDw9IGNvdW50OyBuKyspIHsKICAgIC8qIGZpcnN0IHRoZSBkZXNjcmlwdGlvbiAqLwogICAgaWYgKG4gIT0gMCkgewogICAgICBzaXplID0gc2l6ZW9mKHN6VmFsdWUpL3NpemVvZihzelZhbHVlWzBdKTsKICAgICAgaWYgKFJlZ1F1ZXJ5VmFsdWVXKGhLZXksIGxwW25dLnN6Q2xzaWQsIHN6VmFsdWUsICZzaXplKSA9PSBTX09LKSB7CglzaXplID0gbHN0cmxlblcoc3pWYWx1ZSk7Cglsc3RyY3B5blcoc3pGaWx0ZXIsIHN6VmFsdWUsIGNiRmlsdGVyKTsKICAgICAgfQogICAgfSBlbHNlCiAgICAgIHNpemUgPSBMb2FkU3RyaW5nVyhBVklGSUxFX2hNb2R1bGUsSURTX0FMTE1VTFRJTUVESUEsc3pGaWx0ZXIsY2JGaWx0ZXIpOwoKICAgIC8qIGNoZWNrIGZvciBlbm91Z2ggc3BhY2UgKi8KICAgIHNpemUrKzsKICAgIGlmIChjYkZpbHRlciA8IHNpemUgKyBsc3RybGVuVyhscFtuXS5zekV4dGVuc2lvbnMpICsgMikgewogICAgICBzekZpbHRlclswXSA9IDA7CiAgICAgIHN6RmlsdGVyWzFdID0gMDsKICAgICAgR2xvYmFsRnJlZVB0cihscCk7CiAgICAgIFJlZ0Nsb3NlS2V5KGhLZXkpOwogICAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogICAgfQogICAgY2JGaWx0ZXIgLT0gc2l6ZTsKICAgIHN6RmlsdGVyICs9IHNpemU7CgogICAgLyogYW5kIHRoZW4gdGhlIGZpbHRlciAqLwogICAgbHN0cmNweW5XKHN6RmlsdGVyLCBscFtuXS5zekV4dGVuc2lvbnMsIGNiRmlsdGVyKTsKICAgIHNpemUgPSBsc3RybGVuVyhscFtuXS5zekV4dGVuc2lvbnMpICsgMTsKICAgIGNiRmlsdGVyIC09IHNpemU7CiAgICBzekZpbHRlciArPSBzaXplOwogIH0KCiAgUmVnQ2xvc2VLZXkoaEtleSk7CiAgR2xvYmFsRnJlZVB0cihscCk7CgogIC8qIGFkZCAiQWxsIGZpbGVzIiAiKi4qIiBmaWx0ZXIgaWYgZW5vdWdoIHNwYWNlIGxlZnQgKi8KICBzaXplID0gTG9hZFN0cmluZ1coQVZJRklMRV9oTW9kdWxlLCBJRFNfQUxMRklMRVMsCgkJICAgICBzekFsbEZpbGVzLCBzaXplb2Yoc3pBbGxGaWxlcykpICsgMTsKICBpZiAoY2JGaWx0ZXIgPiBzaXplKSB7CiAgICBpbnQgaTsKCiAgICAvKiByZXBsYWNlICdAJyB3aXRoIFwwMDAgdG8gc2VwZXJhdGUgZGVzY3JpcHRpb24gb2YgZmlsdGVyICovCiAgICBmb3IgKGkgPSAwOyBpIDwgc2l6ZSAmJiBzekFsbEZpbGVzW2ldICE9IDA7IGkrKykgewogICAgICBpZiAoc3pBbGxGaWxlc1tpXSA9PSAnQCcpIHsKCXN6QWxsRmlsZXNbaV0gPSAwOwoJYnJlYWs7CiAgICAgIH0KICAgIH0KICAgICAgCiAgICBtZW1jcHkoc3pGaWx0ZXIsIHN6QWxsRmlsZXMsIHNpemUgKiBzaXplb2Yoc3pBbGxGaWxlc1swXSkpOwogICAgc3pGaWx0ZXIgKz0gc2l6ZTsKICAgIHN6RmlsdGVyWzBdID0gMDsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0gZWxzZSB7CiAgICBzekZpbHRlclswXSA9IDA7CiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIH0KfQoKc3RhdGljIEJPT0wgQVZJU2F2ZU9wdGlvbnNGbXRDaG9vc2UoSFdORCBoV25kKQp7CiAgTFBBVklDT01QUkVTU09QVElPTlMgcE9wdGlvbnMgPSBTYXZlT3B0cy5wcE9wdGlvbnNbU2F2ZU9wdHMubkN1cnJlbnRdOwogIEFWSVNUUkVBTUlORk9XICAgICAgIHNJbmZvOwoKICBUUkFDRSgiKCVwKVxuIiwgaFduZCk7CgogIGlmIChwT3B0aW9ucyA9PSBOVUxMIHx8IFNhdmVPcHRzLnBwYXZpc1tTYXZlT3B0cy5uQ3VycmVudF0gPT0gTlVMTCkgewogICAgRVJSKCI6IGJhZCBzdGF0ZSFcbiIpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KCiAgaWYgKEZBSUxFRChBVklTdHJlYW1JbmZvVyhTYXZlT3B0cy5wcGF2aXNbU2F2ZU9wdHMubkN1cnJlbnRdLAoJCQkgICAgJnNJbmZvLCBzaXplb2Yoc0luZm8pKSkpIHsKICAgIEVSUigiOiBBVklTdHJlYW1JbmZvVyBmYWlsZWQhXG4iKTsKICAgIHJldHVybiBGQUxTRTsKICB9CgogIGlmIChzSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTykgewogICAgQ09NUFZBUlMgY3Y7CiAgICBCT09MICAgICByZXQ7CgogICAgbWVtc2V0KCZjdiwgMCwgc2l6ZW9mKGN2KSk7CgogICAgaWYgKChwT3B0aW9ucy0+ZHdGbGFncyAmIEFWSUNPTVBSRVNTRl9WQUxJRCkgPT0gMCkgewogICAgICBtZW1zZXQocE9wdGlvbnMsIDAsIHNpemVvZihBVklDT01QUkVTU09QVElPTlMpKTsKICAgICAgcE9wdGlvbnMtPmZjY1R5cGUgICAgPSBzdHJlYW10eXBlVklERU87CiAgICAgIHBPcHRpb25zLT5mY2NIYW5kbGVyID0gY29tcHR5cGVESUI7CiAgICAgIHBPcHRpb25zLT5kd1F1YWxpdHkgID0gSUNRVUFMSVRZX0RFRkFVTFQ7CiAgICB9CgogICAgY3YuY2JTaXplICAgICA9IHNpemVvZihjdik7CiAgICBjdi5kd0ZsYWdzICAgID0gSUNNRl9DT01QVkFSU19WQUxJRDsKICAgIC8qY3YuZmNjVHlwZSAgICA9IHBPcHRpb25zLT5mY2NUeXBlOyAqLwogICAgY3YuZmNjSGFuZGxlciA9IHBPcHRpb25zLT5mY2NIYW5kbGVyOwogICAgY3YubFEgICAgICAgICA9IHBPcHRpb25zLT5kd1F1YWxpdHk7CiAgICBjdi5scFN0YXRlICAgID0gcE9wdGlvbnMtPmxwUGFybXM7CiAgICBjdi5jYlN0YXRlICAgID0gcE9wdGlvbnMtPmNiUGFybXM7CiAgICBpZiAocE9wdGlvbnMtPmR3RmxhZ3MgJiBBVklDT01QUkVTU0ZfS0VZRlJBTUVTKQogICAgICBjdi5sS2V5ID0gcE9wdGlvbnMtPmR3S2V5RnJhbWVFdmVyeTsKICAgIGVsc2UKICAgICAgY3YubEtleSA9IDA7CiAgICBpZiAocE9wdGlvbnMtPmR3RmxhZ3MgJiBBVklDT01QUkVTU0ZfREFUQVJBVEUpCiAgICAgIGN2LmxEYXRhUmF0ZSA9IHBPcHRpb25zLT5kd0J5dGVzUGVyU2Vjb25kIC8gMTAyNDsgLyogbmVlZCBrQnl0ZXMgKi8KICAgIGVsc2UKICAgICAgY3YubERhdGFSYXRlID0gMDsKCiAgICByZXQgPSBJQ0NvbXByZXNzb3JDaG9vc2UoaFduZCwgU2F2ZU9wdHMudUZsYWdzLCBOVUxMLAoJCQkgICAgIFNhdmVPcHRzLnBwYXZpc1tTYXZlT3B0cy5uQ3VycmVudF0sICZjdiwgTlVMTCk7CgogICAgaWYgKHJldCkgewogICAgICBwT3B0aW9ucy0+bHBQYXJtcyAgID0gY3YubHBTdGF0ZTsKICAgICAgcE9wdGlvbnMtPmNiUGFybXMgICA9IGN2LmNiU3RhdGU7CiAgICAgIHBPcHRpb25zLT5kd1F1YWxpdHkgPSBjdi5sUTsKICAgICAgaWYgKGN2LmxLZXkgIT0gMCkgewoJcE9wdGlvbnMtPmR3S2V5RnJhbWVFdmVyeSA9IGN2LmxLZXk7CglwT3B0aW9ucy0+ZHdGbGFncyB8PSBBVklDT01QUkVTU0ZfS0VZRlJBTUVTOwogICAgICB9IGVsc2UKCXBPcHRpb25zLT5kd0ZsYWdzICY9IH5BVklDT01QUkVTU0ZfS0VZRlJBTUVTOwogICAgICBpZiAoY3YubERhdGFSYXRlICE9IDApIHsKCXBPcHRpb25zLT5kd0J5dGVzUGVyU2Vjb25kID0gY3YubERhdGFSYXRlICogMTAyNDsgLyogbmVlZCBieXRlcyAqLwoJcE9wdGlvbnMtPmR3RmxhZ3MgfD0gQVZJQ09NUFJFU1NGX0RBVEFSQVRFOwogICAgICB9IGVsc2UKCXBPcHRpb25zLT5kd0ZsYWdzICY9IH5BVklDT01QUkVTU0ZfREFUQVJBVEU7CiAgICAgIHBPcHRpb25zLT5kd0ZsYWdzICB8PSBBVklDT01QUkVTU0ZfVkFMSUQ7CiAgICB9CiAgICBJQ0NvbXByZXNzb3JGcmVlKCZjdik7CgogICAgcmV0dXJuIHJldDsKICB9IGVsc2UgaWYgKHNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZUFVRElPKSB7CiAgICBBQ01GT1JNQVRDSE9PU0VXIGFmbXRjOwogICAgTU1SRVNVTFQgICAgICAgICByZXQ7CiAgICBMT05HICAgICAgICAgICAgIHNpemU7CgogICAgLyogRklYTUU6IGNoZWNrIEFDTSB2ZXJzaW9uIC0tIFdoaWNoIHZlcnNpb24gaXMgbmVlZGVkPyAqLwoKICAgIG1lbXNldCgmYWZtdGMsIDAsIHNpemVvZihhZm10YykpOwogICAgYWZtdGMuY2JTdHJ1Y3QgID0gc2l6ZW9mKGFmbXRjKTsKICAgIGFmbXRjLmZkd1N0eWxlICA9IDA7CiAgICBhZm10Yy5od25kT3duZXIgPSBoV25kOwoKICAgIGFjbU1ldHJpY3MoTlVMTCwgQUNNX01FVFJJQ19NQVhfU0laRV9GT1JNQVQsICZzaXplKTsKICAgIGlmICgocE9wdGlvbnMtPmNiRm9ybWF0ID09IDAgfHwgcE9wdGlvbnMtPmxwRm9ybWF0ID09IE5VTEwpICYmIHNpemUgIT0gMCkgewogICAgICBwT3B0aW9ucy0+bHBGb3JtYXQgPSBHbG9iYWxBbGxvY1B0cihHTUVNX01PVkVBQkxFLCBzaXplKTsKICAgICAgcE9wdGlvbnMtPmNiRm9ybWF0ID0gc2l6ZTsKICAgIH0gZWxzZSBpZiAocE9wdGlvbnMtPmNiRm9ybWF0IDwgc2l6ZSkgewogICAgICBwT3B0aW9ucy0+bHBGb3JtYXQgPSBHbG9iYWxSZUFsbG9jUHRyKHBPcHRpb25zLT5scEZvcm1hdCwgc2l6ZSwgR01FTV9NT1ZFQUJMRSk7CiAgICAgIHBPcHRpb25zLT5jYkZvcm1hdCA9IHNpemU7CiAgICB9CiAgICBpZiAocE9wdGlvbnMtPmxwRm9ybWF0ID09IE5VTEwpCiAgICAgIHJldHVybiBGQUxTRTsKICAgIGFmbXRjLnB3ZnggID0gcE9wdGlvbnMtPmxwRm9ybWF0OwogICAgYWZtdGMuY2J3ZnggPSBwT3B0aW9ucy0+Y2JGb3JtYXQ7CgogICAgc2l6ZSA9IDA7CiAgICBBVklTdHJlYW1Gb3JtYXRTaXplKFNhdmVPcHRzLnBwYXZpc1tTYXZlT3B0cy5uQ3VycmVudF0sCgkJCXNJbmZvLmR3U3RhcnQsICZzaXplKTsKICAgIGlmIChzaXplIDwgc2l6ZW9mKFBDTVdBVkVGT1JNQVQpKQogICAgICBzaXplID0gc2l6ZW9mKFBDTVdBVkVGT1JNQVQpOwogICAgYWZtdGMucHdmeEVudW0gPSBHbG9iYWxBbGxvY1B0cihHSE5ELCBzaXplKTsKICAgIGlmIChhZm10Yy5wd2Z4RW51bSAhPSBOVUxMKSB7CiAgICAgIEFWSVN0cmVhbVJlYWRGb3JtYXQoU2F2ZU9wdHMucHBhdmlzW1NhdmVPcHRzLm5DdXJyZW50XSwKCQkJICBzSW5mby5kd1N0YXJ0LCBhZm10Yy5wd2Z4RW51bSwgJnNpemUpOwogICAgICBhZm10Yy5mZHdFbnVtID0gQUNNX0ZPUk1BVEVOVU1GX0NPTlZFUlQ7CiAgICB9CgogICAgcmV0ID0gYWNtRm9ybWF0Q2hvb3NlVygmYWZtdGMpOwogICAgaWYgKHJldCA9PSBTX09LKQogICAgICBwT3B0aW9ucy0+ZHdGbGFncyB8PSBBVklDT01QUkVTU0ZfVkFMSUQ7CgogICAgaWYgKGFmbXRjLnB3ZnhFbnVtICE9IE5VTEwpCiAgICAgIEdsb2JhbEZyZWVQdHIoYWZtdGMucHdmeEVudW0pOwoKICAgIHJldHVybiAocmV0ID09IFNfT0sgPyBUUlVFIDogRkFMU0UpOwogIH0gZWxzZSB7CiAgICBFUlIoIjogdW5rbm93biBzdHJlYW10eXBlIDB4JTA4bFhcbiIsIHNJbmZvLmZjY1R5cGUpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KfQoKc3RhdGljIHZvaWQgQVZJU2F2ZU9wdGlvbnNVcGRhdGUoSFdORCBoV25kKQp7CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6VmlkZW9GbXRbXT17JyUnLCdsJywnZCcsJ3gnLCclJywnbCcsJ2QnLCd4JywnJScsJ2QnLDB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzekF1ZGlvRm10W109eyclJywncycsJyAnLCclJywncycsMH07CgogIFdDSEFSICAgICAgICAgIHN6Rm9ybWF0WzEyOF07CiAgQVZJU1RSRUFNSU5GT1cgc0luZm87CiAgTFBWT0lEICAgICAgICAgbHBGb3JtYXQ7CiAgTE9ORyAgICAgICAgICAgc2l6ZTsKCiAgVFJBQ0UoIiglcClcbiIsIGhXbmQpOwoKICBTYXZlT3B0cy5uQ3VycmVudCA9IFNlbmREbGdJdGVtTWVzc2FnZVcoaFduZCxJRENfU1RSRUFNLENCX0dFVENVUlNFTCwwLDApOwogIGlmIChTYXZlT3B0cy5uQ3VycmVudCA8IDApCiAgICByZXR1cm47CgogIGlmIChGQUlMRUQoQVZJU3RyZWFtSW5mb1coU2F2ZU9wdHMucHBhdmlzW1NhdmVPcHRzLm5DdXJyZW50XSwgJnNJbmZvLCBzaXplb2Yoc0luZm8pKSkpCiAgICByZXR1cm47CgogIEFWSVN0cmVhbUZvcm1hdFNpemUoU2F2ZU9wdHMucHBhdmlzW1NhdmVPcHRzLm5DdXJyZW50XSxzSW5mby5kd1N0YXJ0LCZzaXplKTsKICBpZiAoc2l6ZSA+IDApIHsKICAgIHN6Rm9ybWF0WzBdID0gMDsKCiAgICAvKiByZWFkIGZvcm1hdCB0byBidWlsZCBmb3JtYXQgZGVzY3Jpb3Rpb24gc3RyaW5nICovCiAgICBscEZvcm1hdCA9IEdsb2JhbEFsbG9jUHRyKEdITkQsIHNpemUpOwogICAgaWYgKGxwRm9ybWF0ICE9IE5VTEwpIHsKICAgICAgaWYgKFNVQ0NFRURFRChBVklTdHJlYW1SZWFkRm9ybWF0KFNhdmVPcHRzLnBwYXZpc1tTYXZlT3B0cy5uQ3VycmVudF0sc0luZm8uZHdTdGFydCxscEZvcm1hdCwgJnNpemUpKSkgewoJaWYgKHNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPKSB7CgkgIExQQklUTUFQSU5GT0hFQURFUiBscGJpID0gbHBGb3JtYXQ7CgkgIElDSU5GTyBpY2luZm87CgoJICB3c3ByaW50Zlcoc3pGb3JtYXQsIHN6VmlkZW9GbXQsIGxwYmktPmJpV2lkdGgsCgkJICAgIGxwYmktPmJpSGVpZ2h0LCBscGJpLT5iaUJpdENvdW50KTsKCgkgIGlmIChscGJpLT5iaUNvbXByZXNzaW9uICE9IEJJX1JHQikgewoJICAgIEhJQyAgICBoaWM7CgoJICAgIGhpYyA9IElDTG9jYXRlKElDVFlQRV9WSURFTywgc0luZm8uZmNjSGFuZGxlciwgbHBGb3JtYXQsCgkJCSAgIE5VTEwsIElDTU9ERV9ERUNPTVBSRVNTKTsKCSAgICBpZiAoaGljICE9IE5VTEwpIHsKCSAgICAgIGlmIChJQ0dldEluZm8oaGljLCAmaWNpbmZvLCBzaXplb2YoaWNpbmZvKSkgPT0gU19PSykKCQlsc3RyY2F0VyhzekZvcm1hdCwgaWNpbmZvLnN6RGVzY3JpcHRpb24pOwoJICAgICAgSUNDbG9zZShoaWMpOwoJICAgIH0KCSAgfSBlbHNlIHsKCSAgICBMb2FkU3RyaW5nVyhBVklGSUxFX2hNb2R1bGUsIElEU19VTkNPTVBSRVNTRUQsCgkJCWljaW5mby5zekRlc2NyaXB0aW9uLCBzaXplb2YoaWNpbmZvLnN6RGVzY3JpcHRpb24pKTsKCSAgICBsc3RyY2F0VyhzekZvcm1hdCwgaWNpbmZvLnN6RGVzY3JpcHRpb24pOwoJICB9Cgl9IGVsc2UgaWYgKHNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZUFVRElPKSB7CgkgIEFDTUZPUk1BVFRBR0RFVEFJTFNXIGFmdGQ7CgkgIEFDTUZPUk1BVERFVEFJTFNXICAgIGFmZDsKCgkgIG1lbXNldCgmYWZ0ZCwgMCwgc2l6ZW9mKGFmdGQpKTsKCSAgbWVtc2V0KCZhZmQsIDAsIHNpemVvZihhZmQpKTsKCgkgIGFmdGQuY2JTdHJ1Y3QgICAgID0gc2l6ZW9mKGFmdGQpOwoJICBhZnRkLmR3Rm9ybWF0VGFnICA9IGFmZC5kd0Zvcm1hdFRhZyA9CgkgICAgKChQV0FWRUZPUk1BVEVYKWxwRm9ybWF0KS0+d0Zvcm1hdFRhZzsKCSAgYWZ0ZC5jYkZvcm1hdFNpemUgPSBhZmQuY2J3ZnggPSBzaXplOwoKCSAgYWZkLmNiU3RydWN0ICAgICAgPSBzaXplb2YoYWZkKTsKCSAgYWZkLnB3ZnggICAgICAgICAgPSBscEZvcm1hdDsKCgkgIGlmIChhY21Gb3JtYXRUYWdEZXRhaWxzVyhOVUxMLCAmYWZ0ZCwKCQkJCSAgIEFDTV9GT1JNQVRUQUdERVRBSUxTRl9GT1JNQVRUQUcpID09IFNfT0spIHsKCSAgICBpZiAoYWNtRm9ybWF0RGV0YWlsc1coTlVMTCwmYWZkLEFDTV9GT1JNQVRERVRBSUxTRl9GT1JNQVQpID09IFNfT0spCgkgICAgICB3c3ByaW50Zlcoc3pGb3JtYXQsIHN6QXVkaW9GbXQsIGFmZC5zekZvcm1hdCwgYWZ0ZC5zekZvcm1hdFRhZyk7CgkgIH0KCX0KICAgICAgfQogICAgICBHbG9iYWxGcmVlUHRyKGxwRm9ybWF0KTsKICAgIH0KCiAgICAvKiBzZXQgdGV4dCBmb3IgZm9ybWF0IGRlc2NyaXB0aW9uICovCiAgICBTZXREbGdJdGVtVGV4dFcoaFduZCwgSURDX0ZPUk1BVFRFWFQsIHN6Rm9ybWF0KTsKCiAgICAvKiBEaXNhYmxlIG9wdGlvbiBidXR0b24gZm9yIHVuc3VwcG9ydGVkIHN0cmVhbXR5cGVzICovCiAgICBpZiAoc0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlVklERU8gfHwKCXNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZUFVRElPKQogICAgICBFbmFibGVXaW5kb3coR2V0RGxnSXRlbShoV25kLCBJRENfT1BUSU9OUyksIFRSVUUpOwogICAgZWxzZQogICAgICBFbmFibGVXaW5kb3coR2V0RGxnSXRlbShoV25kLCBJRENfT1BUSU9OUyksIEZBTFNFKTsKICB9Cgp9CgpJTlRfUFRSIENBTExCQUNLIEFWSVNhdmVPcHRpb25zRGxnUHJvYyhIV05EIGhXbmQsIFVJTlQgdU1zZywKCQkJCSAgICBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiAgRFdPUkQgZHdJbnRlcmxlYXZlOwogIEJPT0wgIGJJc0ludGVybGVhdmVkOwogIElOVCAgIG47CgogIC8qVFJBQ0UoIiglcCwldSwweCUwNFgsMHglMDhsWClcbiIsIGhXbmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsqLwoKICBzd2l0Y2ggKHVNc2cpIHsKICBjYXNlIFdNX0lOSVRESUFMT0c6CiAgICBTYXZlT3B0cy5uQ3VycmVudCA9IDA7CiAgICBpZiAoU2F2ZU9wdHMublN0cmVhbXMgPT0gMSkgewogICAgICBFbmREaWFsb2coaFduZCwgQVZJU2F2ZU9wdGlvbnNGbXRDaG9vc2UoaFduZCkpOwogICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgLyogYWRkIHN0cmVhbXMgKi8KICAgIGZvciAobiA9IDA7IG4gPCBTYXZlT3B0cy5uU3RyZWFtczsgbisrKSB7CiAgICAgIEFWSVNUUkVBTUlORk9XIHNJbmZvOwoKICAgICAgQVZJU3RyZWFtSW5mb1coU2F2ZU9wdHMucHBhdmlzW25dLCAmc0luZm8sIHNpemVvZihzSW5mbykpOwogICAgICBTZW5kRGxnSXRlbU1lc3NhZ2VXKGhXbmQsIElEQ19TVFJFQU0sIENCX0FERFNUUklORywKCQkJICAwTCwgKExQQVJBTSlzSW5mby5zek5hbWUpOwogICAgfQoKICAgIC8qIHNlbGVjdCBmaXJzdCBzdHJlYW0gKi8KICAgIFNlbmREbGdJdGVtTWVzc2FnZVcoaFduZCwgSURDX1NUUkVBTSwgQ0JfU0VUQ1VSU0VMLCAwLCAwKTsKICAgIFNlbmRNZXNzYWdlVyhoV25kLCBXTV9DT01NQU5ELAoJCSBHRVRfV01fQ09NTUFORF9NUFMoSURDX1NUUkVBTSwgaFduZCwgQ0JOX1NFTENIQU5HRSkpOwoKICAgIC8qIGluaXRpYWxpemUgaW50ZXJsZWF2ZSAqLwogICAgaWYgKFNhdmVPcHRzLnBwT3B0aW9uc1swXSAhPSBOVUxMICYmCgkoU2F2ZU9wdHMucHBPcHRpb25zWzBdLT5kd0ZsYWdzICYgQVZJQ09NUFJFU1NGX1ZBTElEKSkgewogICAgICBiSXNJbnRlcmxlYXZlZCA9IChTYXZlT3B0cy5wcE9wdGlvbnNbMF0tPmR3RmxhZ3MgJiBBVklDT01QUkVTU0ZfSU5URVJMRUFWRSk7CiAgICAgIGR3SW50ZXJsZWF2ZSA9IFNhdmVPcHRzLnBwT3B0aW9uc1swXS0+ZHdJbnRlcmxlYXZlRXZlcnk7CiAgICB9IGVsc2UgewogICAgICBiSXNJbnRlcmxlYXZlZCA9IFRSVUU7CiAgICAgIGR3SW50ZXJsZWF2ZSAgID0gMDsKICAgIH0KICAgIENoZWNrRGxnQnV0dG9uKGhXbmQsIElEQ19JTlRFUkxFQVZFLCBiSXNJbnRlcmxlYXZlZCk7CiAgICBTZXREbGdJdGVtSW50KGhXbmQsIElEQ19JTlRFUkxFQVZFRVZFUlksIGR3SW50ZXJsZWF2ZSwgRkFMU0UpOwogICAgRW5hYmxlV2luZG93KEdldERsZ0l0ZW0oaFduZCwgSURDX0lOVEVSTEVBVkVFVkVSWSksIGJJc0ludGVybGVhdmVkKTsKICAgIGJyZWFrOwogIGNhc2UgV01fQ09NTUFORDoKICAgIHN3aXRjaCAoR0VUX1dNX0NPTU1BTkRfQ01EKHdQYXJhbSwgbFBhcmFtKSkgewogICAgY2FzZSBJRE9LOgogICAgICAvKiBnZXQgZGF0YSBmcm9tIGNvbnRyb2xzIGFuZCBzYXZlIHRoZW0gKi8KICAgICAgZHdJbnRlcmxlYXZlICAgPSBHZXREbGdJdGVtSW50KGhXbmQsIElEQ19JTlRFUkxFQVZFRVZFUlksIE5VTEwsIDApOwogICAgICBiSXNJbnRlcmxlYXZlZCA9IElzRGxnQnV0dG9uQ2hlY2tlZChoV25kLCBJRENfSU5URVJMRUFWRSk7CiAgICAgIGZvciAobiA9IDA7IG4gPCBTYXZlT3B0cy5uU3RyZWFtczsgbisrKSB7CglpZiAoU2F2ZU9wdHMucHBPcHRpb25zW25dICE9IE5VTEwpIHsKCSAgaWYgKGJJc0ludGVybGVhdmVkKSB7CgkgICAgU2F2ZU9wdHMucHBPcHRpb25zW25dLT5kd0ZsYWdzIHw9IEFWSUNPTVBSRVNTRl9JTlRFUkxFQVZFOwoJICAgIFNhdmVPcHRzLnBwT3B0aW9uc1tuXS0+ZHdJbnRlcmxlYXZlRXZlcnkgPSBkd0ludGVybGVhdmU7CgkgIH0gZWxzZQoJICAgIFNhdmVPcHRzLnBwT3B0aW9uc1tuXS0+ZHdGbGFncyAmPSB+QVZJQ09NUFJFU1NGX0lOVEVSTEVBVkU7Cgl9CiAgICAgIH0KICAgICAgLyogZmFsbCB0aHJvdWdoICovCiAgICBjYXNlIElEQ0FOQ0VMOgogICAgICBFbmREaWFsb2coaFduZCwgR0VUX1dNX0NPTU1BTkRfQ01EKHdQYXJhbSwgbFBhcmFtKSA9PSBJRE9LKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIElEQ19JTlRFUkxFQVZFOgogICAgICBFbmFibGVXaW5kb3coR2V0RGxnSXRlbShoV25kLCBJRENfSU5URVJMRUFWRUVWRVJZKSwKCQkgICBJc0RsZ0J1dHRvbkNoZWNrZWQoaFduZCwgSURDX0lOVEVSTEVBVkUpKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIElEQ19TVFJFQU06CiAgICAgIGlmIChHRVRfV01fQ09NTUFORF9DTUQod1BhcmFtLCBsUGFyYW0pID09IENCTl9TRUxDSEFOR0UpIHsKCS8qIHVwZGF0ZSBjb250cm9sIGVsZW1lbnRzICovCglBVklTYXZlT3B0aW9uc1VwZGF0ZShoV25kKTsKICAgICAgfQogICAgICBicmVhazsKICAgIGNhc2UgSURDX09QVElPTlM6CiAgICAgIEFWSVNhdmVPcHRpb25zRm10Q2hvb3NlKGhXbmQpOwogICAgICBicmVhazsKICAgIH07CiAgICByZXR1cm4gRkFMU0U7CiAgfTsKCiAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU2F2ZU9wdGlvbnMJCShBVklGSUwzMi5AKQogKi8KQk9PTCBXSU5BUEkgQVZJU2F2ZU9wdGlvbnMoSFdORCBoV25kLCBVSU5UIHVGbGFncywgSU5UIG5TdHJlYW1zLAoJCQkgICBQQVZJU1RSRUFNICpwcGF2aSwgTFBBVklDT01QUkVTU09QVElPTlMgKnBwT3B0aW9ucykKewogIExQQVZJQ09NUFJFU1NPUFRJT05TIHBTYXZlZE9wdGlvbnMgPSBOVUxMOwogIElOVCByZXQsIG47CgogIFRSQUNFKCIoJXAsMHglWCwlZCwlcCwlcClcbiIsIGhXbmQsIHVGbGFncywgblN0cmVhbXMsCglwcGF2aSwgcHBPcHRpb25zKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChuU3RyZWFtcyA8PSAwIHx8IHBwYXZpID09IE5VTEwgfHwgcHBPcHRpb25zID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBzYXZlIG9wdGlvbnMgZm9yIGNhc2UgdXNlciBwcmVzcyBjYW5jZWwgKi8KICBpZiAocHBPcHRpb25zICE9IE5VTEwgJiYgblN0cmVhbXMgPiAxKSB7CiAgICBwU2F2ZWRPcHRpb25zID0gR2xvYmFsQWxsb2NQdHIoR0hORCxuU3RyZWFtcyAqIHNpemVvZihBVklDT01QUkVTU09QVElPTlMpKTsKICAgIGlmIChwU2F2ZWRPcHRpb25zID09IE5VTEwpCiAgICAgIHJldHVybiBGQUxTRTsKCiAgICBmb3IgKG4gPSAwOyBuIDwgblN0cmVhbXM7IG4rKykgewogICAgICBpZiAocHBPcHRpb25zW25dICE9IE5VTEwpCgltZW1jcHkocFNhdmVkT3B0aW9ucyArIG4sIHBwT3B0aW9uc1tuXSwgc2l6ZW9mKEFWSUNPTVBSRVNTT1BUSU9OUykpOwogICAgfQogIH0KCiAgU2F2ZU9wdHMudUZsYWdzICAgID0gdUZsYWdzOwogIFNhdmVPcHRzLm5TdHJlYW1zICA9IG5TdHJlYW1zOwogIFNhdmVPcHRzLnBwYXZpcyAgICA9IHBwYXZpOwogIFNhdmVPcHRzLnBwT3B0aW9ucyA9IHBwT3B0aW9uczsKCiAgcmV0ID0gRGlhbG9nQm94VyhBVklGSUxFX2hNb2R1bGUsIE1BS0VJTlRSRVNPVVJDRVcoSUREX1NBVkVPUFRJT05TKSwKCQkgICBoV25kLCBBVklTYXZlT3B0aW9uc0RsZ1Byb2MpOwoKICBpZiAocmV0ID09IC0xKQogICAgcmV0ID0gRkFMU0U7CgogIC8qIHJlc3RvcmUgb3B0aW9ucyB3aGVuIHVzZXIgcHJlc3NlZCBjYW5jZWwgKi8KICBpZiAocFNhdmVkT3B0aW9ucyAhPSBOVUxMICYmIHJldCA9PSBGQUxTRSkgewogICAgZm9yIChuID0gMDsgbiA8IG5TdHJlYW1zOyBuKyspIHsKICAgICAgaWYgKHBwT3B0aW9uc1tuXSAhPSBOVUxMKQoJbWVtY3B5KHBwT3B0aW9uc1tuXSwgcFNhdmVkT3B0aW9ucyArIG4sIHNpemVvZihBVklDT01QUkVTU09QVElPTlMpKTsKICAgIH0KICAgIEdsb2JhbEZyZWVQdHIocFNhdmVkT3B0aW9ucyk7CiAgfQoKICByZXR1cm4gKEJPT0wpcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVNhdmVPcHRpb25zRnJlZQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVNhdmVPcHRpb25zRnJlZShJTlQgblN0cmVhbXMsTFBBVklDT01QUkVTU09QVElPTlMqcHBPcHRpb25zKQp7CiAgVFJBQ0UoIiglZCwlcClcbiIsIG5TdHJlYW1zLCBwcE9wdGlvbnMpOwoKICBpZiAoblN0cmVhbXMgPCAwIHx8IHBwT3B0aW9ucyA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgZm9yICg7IG5TdHJlYW1zID4gMDsgblN0cmVhbXMtLSkgewogICAgaWYgKHBwT3B0aW9uc1tuU3RyZWFtc10gIT0gTlVMTCkgewogICAgICBwcE9wdGlvbnNbblN0cmVhbXNdLT5kd0ZsYWdzICY9IH5BVklDT01QUkVTU0ZfVkFMSUQ7CgogICAgICBpZiAocHBPcHRpb25zW25TdHJlYW1zXS0+bHBQYXJtcyAhPSBOVUxMKSB7CglHbG9iYWxGcmVlUHRyKHBwT3B0aW9uc1tuU3RyZWFtc10tPmxwUGFybXMpOwoJcHBPcHRpb25zW25TdHJlYW1zXS0+bHBQYXJtcyA9IE5VTEw7CglwcE9wdGlvbnNbblN0cmVhbXNdLT5jYlBhcm1zID0gMDsKICAgICAgfQogICAgICBpZiAocHBPcHRpb25zW25TdHJlYW1zXS0+bHBGb3JtYXQgIT0gTlVMTCkgewoJR2xvYmFsRnJlZVB0cihwcE9wdGlvbnNbblN0cmVhbXNdLT5scEZvcm1hdCk7CglwcE9wdGlvbnNbblN0cmVhbXNdLT5scEZvcm1hdCA9IE5VTEw7CglwcE9wdGlvbnNbblN0cmVhbXNdLT5jYkZvcm1hdCA9IDA7CiAgICAgIH0KICAgIH0KICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0K