LyoKICogQ29weXJpZ2h0IDE5OTkgTWFyY3VzIE1laXNzbmVyCiAqIENvcHlyaWdodCAyMDAyLTIwMDMgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSA8c3RkYXJnLmg+CgojZGVmaW5lIENPQkpNQUNST1MKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCgojaW5jbHVkZSAib2xlMi5oIgojaW5jbHVkZSAic2hlbGxhcGkuaCIKI2luY2x1ZGUgInNobG9iai5oIgojaW5jbHVkZSAidmZ3LmgiCiNpbmNsdWRlICJtc2FjbS5oIgoKI2luY2x1ZGUgImF2aWZpbGVfcHJpdmF0ZS5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoYXZpZmlsZSk7CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIGZvciBBVklCdWlsZEZpbHRlclcgLS0gdXNlcyBmaXhlZCBzaXplIHRhYmxlCiAqLwojZGVmaW5lIE1BWF9GSUxURVJTIDMwIC8qIDMwID0+IDdrQiAqLwoKdHlwZWRlZiBzdHJ1Y3QgX0FWSUZpbHRlciB7CiAgV0NIQVIgc3pDbHNpZFs0MF07CiAgV0NIQVIgc3pFeHRlbnNpb25zW01BWF9GSUxURVJTICogN107Cn0gQVZJRmlsdGVyOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIGZvciBBVklTYXZlT3B0aW9ucwogKi8Kc3RhdGljIHN0cnVjdCB7CiAgVUlOVCAgICAgICAgICAgICAgICAgIHVGbGFnczsKICBJTlQgICAgICAgICAgICAgICAgICAgblN0cmVhbXM7CiAgUEFWSVNUUkVBTSAgICAgICAgICAgKnBwYXZpczsKICBMUEFWSUNPTVBSRVNTT1BUSU9OUyAqcHBPcHRpb25zOwogIElOVCAgICAgICAgICAgICAgICAgICBuQ3VycmVudDsKfSBTYXZlT3B0czsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBjb3BpZWQgZnJvbSBkbGxzL29sZTMyL2NvbXBvYmouYwogKi8Kc3RhdGljIEhSRVNVTFQgQVZJRklMRV9DTFNJREZyb21TdHJpbmcoTFBDU1RSIGlkc3RyLCBMUENMU0lEIGlkKQp7CiAgQllURSBjb25zdCAqczsKICBCWVRFICpwOwogIElOVCAgIGk7CiAgQllURSB0YWJsZVsyNTZdOwoKICBpZiAoIWlkc3RyKSB7CiAgICBtZW1zZXQoaWQsIDAsIHNpemVvZihDTFNJRCkpOwogICAgcmV0dXJuIFNfT0s7CiAgfQoKICAvKiB2YWxpZGF0ZSB0aGUgQ0xTSUQgc3RyaW5nICovCiAgaWYgKGxzdHJsZW5BKGlkc3RyKSAhPSAzOCkKICAgIHJldHVybiBDT19FX0NMQVNTU1RSSU5HOwoKICBzID0gKEJZVEUgY29uc3QqKWlkc3RyOwogIGlmICgoc1swXSE9J3snKSB8fCAoc1s5XSE9Jy0nKSB8fCAoc1sxNF0hPSctJykgfHwgKHNbMTldIT0nLScpIHx8CiAgICAgIChzWzI0XSE9Jy0nKSB8fCAoc1szN10hPSd9JykpCiAgICByZXR1cm4gQ09fRV9DTEFTU1NUUklORzsKCiAgZm9yIChpID0gMTsgaSA8IDM3OyBpKyspIHsKICAgIGlmICgoaSA9PSA5KSB8fCAoaSA9PSAxNCkgfHwgKGkgPT0gMTkpIHx8IChpID09IDI0KSkKICAgICAgY29udGludWU7CiAgICBpZiAoISgoKHNbaV0gPj0gJzAnKSAmJiAoc1tpXSA8PSAnOScpKSAgfHwKICAgICAgICAoKHNbaV0gPj0gJ2EnKSAmJiAoc1tpXSA8PSAnZicpKSAgfHwKICAgICAgICAoKHNbaV0gPj0gJ0EnKSAmJiAoc1tpXSA8PSAnRicpKSkKICAgICAgICkKICAgICAgcmV0dXJuIENPX0VfQ0xBU1NTVFJJTkc7CiAgfQoKICBUUkFDRSgiJXMgLT4gJXBcbiIsIHMsIGlkKTsKCiAgLyogcXVpY2sgbG9va3VwIHRhYmxlICovCiAgbWVtc2V0KHRhYmxlLCAwLCAyNTYpOwoKICBmb3IgKGkgPSAwOyBpIDwgMTA7IGkrKykKICAgIHRhYmxlWycwJyArIGldID0gaTsKCiAgZm9yIChpID0gMDsgaSA8IDY7IGkrKykgewogICAgdGFibGVbJ0EnICsgaV0gPSBpKzEwOwogICAgdGFibGVbJ2EnICsgaV0gPSBpKzEwOwogIH0KCiAgLyogaW4gZm9ybSB7WFhYWFhYWFgtWFhYWC1YWFhYLVhYWFgtWFhYWFhYWFhYWFhYfSAqLwogIHAgPSAoQllURSAqKSBpZDsKCiAgcysrOwkvKiBza2lwIGxlYWRpbmcgYnJhY2UgICovCiAgZm9yIChpID0gMDsgaSA8IDQ7IGkrKykgewogICAgcFszIC0gaV0gPSB0YWJsZVsqc108PDQgfCB0YWJsZVsqKHMrMSldOwogICAgcyArPSAyOwogIH0KICBwICs9IDQ7CiAgcysrOwkvKiBza2lwIC0gKi8KCiAgZm9yIChpID0gMDsgaSA8IDI7IGkrKykgewogICAgcFsxLWldID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKICAgIHMgKz0gMjsKICB9CiAgcCArPSAyOwogIHMrKzsJLyogc2tpcCAtICovCgogIGZvciAoaSA9IDA7IGkgPCAyOyBpKyspIHsKICAgIHBbMS1pXSA9IHRhYmxlWypzXTw8NCB8IHRhYmxlWyoocysxKV07CiAgICBzICs9IDI7CiAgfQogIHAgKz0gMjsKICBzKys7CS8qIHNraXAgLSAqLwoKICAvKiB0aGVzZSBhcmUganVzdCBzZXF1ZW50aWFsIGJ5dGVzICovCiAgZm9yIChpID0gMDsgaSA8IDI7IGkrKykgewogICAgKnArKyA9IHRhYmxlWypzXTw8NCB8IHRhYmxlWyoocysxKV07CiAgICBzICs9IDI7CiAgfQogIHMrKzsJLyogc2tpcCAtICovCgogIGZvciAoaSA9IDA7IGkgPCA2OyBpKyspIHsKICAgICpwKysgPSB0YWJsZVsqc108PDQgfCB0YWJsZVsqKHMrMSldOwogICAgcyArPSAyOwogIH0KCiAgcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyBCT09MIEFWSUZJTEVfR2V0RmlsZUhhbmRsZXJCeUV4dGVuc2lvbihMUENXU1RSIHN6RmlsZSwgTFBDTFNJRCBscGNsc2lkKQp7CiAgQ0hBUiAgIHN6UmVnS2V5WzI1XTsKICBDSEFSICAgc3pWYWx1ZVsxMDBdOwogIExQV1NUUiBzekV4dCA9IHN0cnJjaHJXKHN6RmlsZSwgJy4nKTsKICBMT05HICAgbGVuID0gc2l6ZW9mKHN6VmFsdWUpIC8gc2l6ZW9mKHN6VmFsdWVbMF0pOwoKICBpZiAoc3pFeHQgPT0gTlVMTCkKICAgIHJldHVybiBGQUxTRTsKCiAgc3pFeHQrKzsKCiAgd3NwcmludGZBKHN6UmVnS2V5LCAiQVZJRmlsZVxcRXh0ZW5zaW9uc1xcJS4zbHMiLCBzekV4dCk7CiAgaWYgKFJlZ1F1ZXJ5VmFsdWVBKEhLRVlfQ0xBU1NFU19ST09ULCBzelJlZ0tleSwgc3pWYWx1ZSwgJmxlbikgIT0gRVJST1JfU1VDQ0VTUykKICAgIHJldHVybiBGQUxTRTsKCiAgcmV0dXJuIChBVklGSUxFX0NMU0lERnJvbVN0cmluZyhzelZhbHVlLCBscGNsc2lkKSA9PSBTX09LKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlSW5pdAkJKEFWSUZJTDMyLkApCiAqCQlBVklGaWxlSW5pdAkJKEFWSUZJTEUuMTAwKQogKi8Kdm9pZCBXSU5BUEkgQVZJRmlsZUluaXQodm9pZCkgewogIE9sZUluaXRpYWxpemUoTlVMTCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUV4aXQJCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZUV4aXQJCShBVklGSUxFLjEwMSkKICovCnZvaWQgV0lOQVBJIEFWSUZpbGVFeGl0KHZvaWQpIHsKICAvKiBuZWVkIHRvIGZyZWUgb2xlMzIuZGxsIGlmIHdlIGFyZSB0aGUgbGFzdCBleGl0IGNhbGwgKi8KICAvKiBPbGVVbmluaXRpYWxpemUoKSAqLwogIEZJWE1FKCIoKTogc3R1YiFcbiIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVPcGVuCQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVPcGVuQQkJKEFWSUZJTDMyLkApCiAqCQlBVklGaWxlT3BlbgkJKEFWSUZJTEUuMTAyKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZU9wZW5BKFBBVklGSUxFICpwcGZpbGUsIExQQ1NUUiBzekZpbGUsIFVJTlQgdU1vZGUsCgkJCSAgICBMUENMU0lEIGxwSGFuZGxlcikKewogIExQV1NUUiAgd3N6RmlsZSA9IE5VTEw7CiAgSFJFU1VMVCBocjsKICBpbnQgICAgIGxlbjsKCiAgVFJBQ0UoIiglcCwlcywweCUwOFgsJXMpXG4iLCBwcGZpbGUsIGRlYnVnc3RyX2Eoc3pGaWxlKSwgdU1vZGUsCglkZWJ1Z3N0cl9ndWlkKGxwSGFuZGxlcikpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKHBwZmlsZSA9PSBOVUxMIHx8IHN6RmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogY29udmVydCBBU0NJSSBzdHJpbmcgdG8gVW5pY29kZSBhbmQgY2FsbCB1bmljb2RlIGZ1bmN0aW9uICovCiAgbGVuID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHN6RmlsZSwgLTEsIE5VTEwsIDApOwogIGlmIChsZW4gPD0gMCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIHdzekZpbGUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuICogc2l6ZW9mKFdDSEFSKSk7CiAgaWYgKHdzekZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgc3pGaWxlLCAtMSwgd3N6RmlsZSwgbGVuKTsKCiAgaHIgPSBBVklGaWxlT3BlblcocHBmaWxlLCB3c3pGaWxlLCB1TW9kZSwgbHBIYW5kbGVyKTsKCiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgd3N6RmlsZSk7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlT3BlblcJCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZU9wZW5XKFBBVklGSUxFICpwcGZpbGUsIExQQ1dTVFIgc3pGaWxlLCBVSU5UIHVNb2RlLAoJCQkgICAgTFBDTFNJRCBscEhhbmRsZXIpCnsKICBJUGVyc2lzdEZpbGUgKnBwZXJzaXN0ID0gTlVMTDsKICBDTFNJRCAgICAgICAgIGNsc2lkSGFuZGxlcjsKICBIUkVTVUxUICAgICAgIGhyOwoKICBUUkFDRSgiKCVwLCVzLDB4JVgsJXMpXG4iLCBwcGZpbGUsIGRlYnVnc3RyX3coc3pGaWxlKSwgdU1vZGUsCglkZWJ1Z3N0cl9ndWlkKGxwSGFuZGxlcikpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKHBwZmlsZSA9PSBOVUxMIHx8IHN6RmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKnBwZmlsZSA9IE5VTEw7CgogIC8qIGlmIG5vIGhhbmRsZXIgdGhlbiB0cnkgZ3Vlc3NpbmcgaXQgYnkgZXh0ZW5zaW9uICovCiAgaWYgKGxwSGFuZGxlciA9PSBOVUxMKSB7CiAgICBpZiAoISBBVklGSUxFX0dldEZpbGVIYW5kbGVyQnlFeHRlbnNpb24oc3pGaWxlLCAmY2xzaWRIYW5kbGVyKSkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9IGVsc2UKICAgIGNsc2lkSGFuZGxlciA9ICpscEhhbmRsZXI7CgogIC8qIGNyZWF0ZSBpbnN0YW5jZSBvZiBoYW5kbGVyICovCiAgaHIgPSBDb0NyZWF0ZUluc3RhbmNlKCZjbHNpZEhhbmRsZXIsIE5VTEwsIENMU0NUWF9JTlBST0MsICZJSURfSUFWSUZpbGUsIChMUFZPSUQqKXBwZmlsZSk7CiAgaWYgKEZBSUxFRChocikgfHwgKnBwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIGhyOwoKICAvKiBhc2sgZm9yIElQZXJzaXN0RmlsZSBpbnRlcmZhY2UgZm9yIGxvYWRpbmcvY3JlYXRpbmcgdGhlIGZpbGUgKi8KICBociA9IElBVklGaWxlX1F1ZXJ5SW50ZXJmYWNlKCpwcGZpbGUsICZJSURfSVBlcnNpc3RGaWxlLCAoTFBWT0lEKikmcHBlcnNpc3QpOwogIGlmIChGQUlMRUQoaHIpIHx8IHBwZXJzaXN0ID09IE5VTEwpIHsKICAgIElBVklGaWxlX1JlbGVhc2UoKnBwZmlsZSk7CiAgICAqcHBmaWxlID0gTlVMTDsKICAgIHJldHVybiBocjsKICB9CgogIGhyID0gSVBlcnNpc3RGaWxlX0xvYWQocHBlcnNpc3QsIHN6RmlsZSwgdU1vZGUpOwogIElQZXJzaXN0RmlsZV9SZWxlYXNlKHBwZXJzaXN0KTsKICBpZiAoRkFJTEVEKGhyKSkgewogICAgSUFWSUZpbGVfUmVsZWFzZSgqcHBmaWxlKTsKICAgICpwcGZpbGUgPSBOVUxMOwogIH0KCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVBZGRSZWYJCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZUFkZFJlZgkJKEFWSUZJTEUuMTQwKQogKi8KVUxPTkcgV0lOQVBJIEFWSUZpbGVBZGRSZWYoUEFWSUZJTEUgcGZpbGUpCnsKICBUUkFDRSgiKCVwKVxuIiwgcGZpbGUpOwoKICBpZiAocGZpbGUgPT0gTlVMTCkgewogICAgRVJSKCI6IGJhZCBoYW5kbGUgcGFzc2VkIVxuIik7CiAgICByZXR1cm4gMDsKICB9CgogIHJldHVybiBJQVZJRmlsZV9BZGRSZWYocGZpbGUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVSZWxlYXNlCQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVSZWxlYXNlCQkoQVZJRklMRS4xNDEpCiAqLwpVTE9ORyBXSU5BUEkgQVZJRmlsZVJlbGVhc2UoUEFWSUZJTEUgcGZpbGUpCnsKICBUUkFDRSgiKCVwKVxuIiwgcGZpbGUpOwoKICBpZiAocGZpbGUgPT0gTlVMTCkgewogICAgRVJSKCI6IGJhZCBoYW5kbGUgcGFzc2VkIVxuIik7CiAgICByZXR1cm4gMDsKICB9CgogIHJldHVybiBJQVZJRmlsZV9SZWxlYXNlKHBmaWxlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlSW5mbwkJKEFWSUZJTDMyLkApCiAqCQlBVklGaWxlSW5mb0EJCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZUluZm8JCShBVklGSUxFLjE0MikKICovCkhSRVNVTFQgV0lOQVBJIEFWSUZpbGVJbmZvQShQQVZJRklMRSBwZmlsZSwgTFBBVklGSUxFSU5GT0EgYWZpLCBMT05HIHNpemUpCnsKICBBVklGSUxFSU5GT1cgYWZpdzsKICBIUkVTVUxUICAgICAgaHJlczsKCiAgVFJBQ0UoIiglcCwlcCwlZClcbiIsIHBmaWxlLCBhZmksIHNpemUpOwoKICBpZiAocGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmICgoRFdPUkQpc2l6ZSA8IHNpemVvZihBVklGSUxFSU5GT0EpKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICBocmVzID0gSUFWSUZpbGVfSW5mbyhwZmlsZSwgJmFmaXcsIHNpemVvZihhZml3KSk7CgogIG1lbWNweShhZmksICZhZml3LCBzaXplb2YoKmFmaSkgLSBzaXplb2YoYWZpLT5zekZpbGVUeXBlKSk7CiAgV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIGFmaXcuc3pGaWxlVHlwZSwgLTEsIGFmaS0+c3pGaWxlVHlwZSwKCQkgICAgICBzaXplb2YoYWZpLT5zekZpbGVUeXBlKSwgTlVMTCwgTlVMTCk7CiAgYWZpLT5zekZpbGVUeXBlW3NpemVvZihhZmktPnN6RmlsZVR5cGUpIC0gMV0gPSAwOwoKICByZXR1cm4gaHJlczsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlSW5mb1cJCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZUluZm9XKFBBVklGSUxFIHBmaWxlLCBMUEFWSUZJTEVJTkZPVyBhZml3LCBMT05HIHNpemUpCnsKICBUUkFDRSgiKCVwLCVwLCVkKVxuIiwgcGZpbGUsIGFmaXcsIHNpemUpOwoKICBpZiAocGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSUZpbGVfSW5mbyhwZmlsZSwgYWZpdywgc2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUdldFN0cmVhbQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVHZXRTdHJlYW0JKEFWSUZJTEUuMTQzKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZUdldFN0cmVhbShQQVZJRklMRSBwZmlsZSwgUEFWSVNUUkVBTSAqYXZpcywKCQkJCURXT1JEIGZjY1R5cGUsIExPTkcgbFBhcmFtKQp7CiAgVFJBQ0UoIiglcCwlcCwnJTQuNHMnLCVkKVxuIiwgcGZpbGUsIGF2aXMsIChjaGFyKikmZmNjVHlwZSwgbFBhcmFtKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklGaWxlX0dldFN0cmVhbShwZmlsZSwgYXZpcywgZmNjVHlwZSwgbFBhcmFtKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlQ3JlYXRlU3RyZWFtCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZUNyZWF0ZVN0cmVhbUEJKEFWSUZJTDMyLkApCiAqICAgICAgICAgICAgICBBVklGaWxlQ3JlYXRlU3RyZWFtCShBVklGSUxFLjE0NCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSUZpbGVDcmVhdGVTdHJlYW1BKFBBVklGSUxFIHBmaWxlLCBQQVZJU1RSRUFNICpwcGF2aSwKCQkJCSAgICBMUEFWSVNUUkVBTUlORk9BIHBzaSkKewogIEFWSVNUUkVBTUlORk9XCXBzaXc7CgogIFRSQUNFKCIoJXAsJXAsJXApXG4iLCBwZmlsZSwgcHBhdmksIHBzaSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIC8qIE9ubHkgdGhlIHN6TmFtZSBhdCB0aGUgZW5kIGlzIGRpZmZlcmVudCAqLwogIG1lbWNweSgmcHNpdywgcHNpLCBzaXplb2YoKnBzaSkgLSBzaXplb2YocHNpLT5zek5hbWUpKTsKICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgcHNpLT5zek5hbWUsIC0xLCBwc2l3LnN6TmFtZSwKCQkgICAgICBzaXplb2YocHNpdy5zek5hbWUpIC8gc2l6ZW9mKHBzaXcuc3pOYW1lWzBdKSk7CgogIHJldHVybiBJQVZJRmlsZV9DcmVhdGVTdHJlYW0ocGZpbGUsIHBwYXZpLCAmcHNpdyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUNyZWF0ZVN0cmVhbVcJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlQ3JlYXRlU3RyZWFtVyhQQVZJRklMRSBwZmlsZSwgUEFWSVNUUkVBTSAqYXZpcywKCQkJCSAgICBMUEFWSVNUUkVBTUlORk9XIGFzaSkKewogIFRSQUNFKCIoJXAsJXAsJXApXG4iLCBwZmlsZSwgYXZpcywgYXNpKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklGaWxlX0NyZWF0ZVN0cmVhbShwZmlsZSwgYXZpcywgYXNpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlV3JpdGVEYXRhCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZVdyaXRlRGF0YQkoQVZJRklMRS4xNDYpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlV3JpdGVEYXRhKFBBVklGSUxFIHBmaWxlLERXT1JEIGZjYyxMUFZPSUQgbHAsTE9ORyBzaXplKQp7CiAgVFJBQ0UoIiglcCwnJTQuNHMnLCVwLCVkKVxuIiwgcGZpbGUsIChjaGFyKikmZmNjLCBscCwgc2l6ZSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJRmlsZV9Xcml0ZURhdGEocGZpbGUsIGZjYywgbHAsIHNpemUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVSZWFkRGF0YQkJKEFWSUZJTDMyLkApCiAqCQlBVklGaWxlUmVhZERhdGEJCShBVklGSUxFLjE0NykKICovCkhSRVNVTFQgV0lOQVBJIEFWSUZpbGVSZWFkRGF0YShQQVZJRklMRSBwZmlsZSxEV09SRCBmY2MsTFBWT0lEIGxwLExQTE9ORyBzaXplKQp7CiAgVFJBQ0UoIiglcCwnJTQuNHMnLCVwLCVwKVxuIiwgcGZpbGUsIChjaGFyKikmZmNjLCBscCwgc2l6ZSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJRmlsZV9SZWFkRGF0YShwZmlsZSwgZmNjLCBscCwgc2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUVuZFJlY29yZAkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVFbmRSZWNvcmQJKEFWSUZJTEUuMTQ4KQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZUVuZFJlY29yZChQQVZJRklMRSBwZmlsZSkKewogIFRSQUNFKCIoJXApXG4iLCBwZmlsZSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJRmlsZV9FbmRSZWNvcmQocGZpbGUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUFkZFJlZgkJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1BZGRSZWYJCShBVklGSUxFLjE2MCkKICovClVMT05HIFdJTkFQSSBBVklTdHJlYW1BZGRSZWYoUEFWSVNUUkVBTSBwc3RyZWFtKQp7CiAgVFJBQ0UoIiglcClcbiIsIHBzdHJlYW0pOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKSB7CiAgICBFUlIoIjogYmFkIGhhbmRsZSBwYXNzZWQhXG4iKTsKICAgIHJldHVybiAwOwogIH0KCiAgcmV0dXJuIElBVklTdHJlYW1fQWRkUmVmKHBzdHJlYW0pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVJlbGVhc2UJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1SZWxlYXNlCShBVklGSUxFLjE2MSkKICovClVMT05HIFdJTkFQSSBBVklTdHJlYW1SZWxlYXNlKFBBVklTVFJFQU0gcHN0cmVhbSkKewogIFRSQUNFKCIoJXApXG4iLCBwc3RyZWFtKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkgewogICAgRVJSKCI6IGJhZCBoYW5kbGUgcGFzc2VkIVxuIik7CiAgICByZXR1cm4gMDsKICB9CgogIHJldHVybiBJQVZJU3RyZWFtX1JlbGVhc2UocHN0cmVhbSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtQ3JlYXRlCQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbUNyZWF0ZQkJKEFWSUZJTEUuMTA0KQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtQ3JlYXRlKFBBVklTVFJFQU0gKnBwYXZpLCBMT05HIGxQYXJhbTEsIExPTkcgbFBhcmFtMiwKCQkJICAgICAgIExQQ0xTSUQgcGNsc2lkSGFuZGxlcikKewogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsMHglMDhYLDB4JTA4WCwlcylcbiIsIHBwYXZpLCBsUGFyYW0xLCBsUGFyYW0yLAoJZGVidWdzdHJfZ3VpZChwY2xzaWRIYW5kbGVyKSk7CgogIGlmIChwcGF2aSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKnBwYXZpID0gTlVMTDsKICBpZiAocGNsc2lkSGFuZGxlciA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgaHIgPSBDb0NyZWF0ZUluc3RhbmNlKHBjbHNpZEhhbmRsZXIsIE5VTEwsIENMU0NUWF9JTlBST0MsICZJSURfSUFWSVN0cmVhbSwgKExQVk9JRCopcHBhdmkpOwogIGlmIChGQUlMRUQoaHIpIHx8ICpwcGF2aSA9PSBOVUxMKQogICAgcmV0dXJuIGhyOwoKICBociA9IElBVklTdHJlYW1fQ3JlYXRlKCpwcGF2aSwgbFBhcmFtMSwgbFBhcmFtMik7CiAgaWYgKEZBSUxFRChocikpIHsKICAgIElBVklTdHJlYW1fUmVsZWFzZSgqcHBhdmkpOwogICAgKnBwYXZpID0gTlVMTDsKICB9CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1JbmZvCQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbUluZm9BCQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbUluZm8JCShBVklGSUxFLjE2MikKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbUluZm9BKFBBVklTVFJFQU0gcHN0cmVhbSwgTFBBVklTVFJFQU1JTkZPQSBhc2ksCgkJCSAgICAgIExPTkcgc2l6ZSkKewogIEFWSVNUUkVBTUlORk9XIGFzaXc7CiAgSFJFU1VMVAkgaHJlczsKCiAgVFJBQ0UoIiglcCwlcCwlZClcbiIsIHBzdHJlYW0sIGFzaSwgc2l6ZSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKICBpZiAoKERXT1JEKXNpemUgPCBzaXplb2YoQVZJU1RSRUFNSU5GT0EpKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICBocmVzID0gSUFWSVN0cmVhbV9JbmZvKHBzdHJlYW0sICZhc2l3LCBzaXplb2YoYXNpdykpOwoKICBtZW1jcHkoYXNpLCAmYXNpdywgc2l6ZW9mKGFzaXcpIC0gc2l6ZW9mKGFzaXcuc3pOYW1lKSk7CiAgV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIGFzaXcuc3pOYW1lLCAtMSwgYXNpLT5zek5hbWUsCgkJICAgICAgc2l6ZW9mKGFzaS0+c3pOYW1lKSwgTlVMTCwgTlVMTCk7CiAgYXNpLT5zek5hbWVbc2l6ZW9mKGFzaS0+c3pOYW1lKSAtIDFdID0gMDsKCiAgcmV0dXJuIGhyZXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtSW5mb1cJCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtSW5mb1coUEFWSVNUUkVBTSBwc3RyZWFtLCBMUEFWSVNUUkVBTUlORk9XIGFzaSwKCQkJICAgICAgTE9ORyBzaXplKQp7CiAgVFJBQ0UoIiglcCwlcCwlZClcbiIsIHBzdHJlYW0sIGFzaSwgc2l6ZSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklTdHJlYW1fSW5mbyhwc3RyZWFtLCBhc2ksIHNpemUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUZpbmRTYW1wbGUJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1GaW5kU2FtcGxlCShBVklGSUxFLjE2MykKICovCkxPTkcgV0lOQVBJIEFWSVN0cmVhbUZpbmRTYW1wbGUoUEFWSVNUUkVBTSBwc3RyZWFtLCBMT05HIHBvcywgTE9ORyBmbGFncykKewogIFRSQUNFKCIoJXAsJWQsMHglWClcbiIsIHBzdHJlYW0sIHBvcywgZmxhZ3MpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIC0xOwoKICByZXR1cm4gSUFWSVN0cmVhbV9GaW5kU2FtcGxlKHBzdHJlYW0sIHBvcywgZmxhZ3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVJlYWRGb3JtYXQJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1SZWFkRm9ybWF0CShBVklGSUxFLjE2NCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbVJlYWRGb3JtYXQoUEFWSVNUUkVBTSBwc3RyZWFtLCBMT05HIHBvcywKCQkJCSAgIExQVk9JRCBmb3JtYXQsIExQTE9ORyBmb3JtYXRzaXplKQp7CiAgVFJBQ0UoIiglcCwlZCwlcCwlcClcbiIsIHBzdHJlYW0sIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSVN0cmVhbV9SZWFkRm9ybWF0KHBzdHJlYW0sIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1TZXRGb3JtYXQJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1TZXRGb3JtYXQJKEFWSUZJTEUuMTY5KQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtU2V0Rm9ybWF0KFBBVklTVFJFQU0gcHN0cmVhbSwgTE9ORyBwb3MsCgkJCQkgIExQVk9JRCBmb3JtYXQsIExPTkcgZm9ybWF0c2l6ZSkKewogIFRSQUNFKCIoJXAsJWQsJXAsJWQpXG4iLCBwc3RyZWFtLCBwb3MsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklTdHJlYW1fU2V0Rm9ybWF0KHBzdHJlYW0sIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1SZWFkCQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbVJlYWQJCShBVklGSUxFLjE2NykKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbVJlYWQoUEFWSVNUUkVBTSBwc3RyZWFtLCBMT05HIHN0YXJ0LCBMT05HIHNhbXBsZXMsCgkJCSAgICAgTFBWT0lEIGJ1ZmZlciwgTE9ORyBidWZmZXJzaXplLAoJCQkgICAgIExQTE9ORyBieXRlc3JlYWQsIExQTE9ORyBzYW1wbGVzcmVhZCkKewogIFRSQUNFKCIoJXAsJWQsJWQsJXAsJWQsJXAsJXApXG4iLCBwc3RyZWFtLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLAoJYnVmZmVyc2l6ZSwgYnl0ZXNyZWFkLCBzYW1wbGVzcmVhZCk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklTdHJlYW1fUmVhZChwc3RyZWFtLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLCBidWZmZXJzaXplLAoJCQkgYnl0ZXNyZWFkLCBzYW1wbGVzcmVhZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtV3JpdGUJCShBVklGSUwzMi5AKQogKgkJQVZJU3RyZWFtV3JpdGUJCShBVklGSUxFLjE2OCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbVdyaXRlKFBBVklTVFJFQU0gcHN0cmVhbSwgTE9ORyBzdGFydCwgTE9ORyBzYW1wbGVzLAoJCQkgICAgICBMUFZPSUQgYnVmZmVyLCBMT05HIGJ1ZmZlcnNpemUsIERXT1JEIGZsYWdzLAoJCQkgICAgICBMUExPTkcgc2FtcHdyaXR0ZW4sIExQTE9ORyBieXRlc3dyaXR0ZW4pCnsKICBUUkFDRSgiKCVwLCVkLCVkLCVwLCVkLDB4JVgsJXAsJXApXG4iLCBwc3RyZWFtLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLAoJYnVmZmVyc2l6ZSwgZmxhZ3MsIHNhbXB3cml0dGVuLCBieXRlc3dyaXR0ZW4pOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJU3RyZWFtX1dyaXRlKHBzdHJlYW0sIHN0YXJ0LCBzYW1wbGVzLCBidWZmZXIsIGJ1ZmZlcnNpemUsCgkJCSAgZmxhZ3MsIHNhbXB3cml0dGVuLCBieXRlc3dyaXR0ZW4pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVJlYWREYXRhCShBVklGSUwzMi5AKQogKgkJQVZJU3RyZWFtUmVhZERhdGEJKEFWSUZJTEUuMTY1KQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtUmVhZERhdGEoUEFWSVNUUkVBTSBwc3RyZWFtLCBEV09SRCBmY2MsIExQVk9JRCBscCwKCQkJCSBMUExPTkcgbHByZWFkKQp7CiAgVFJBQ0UoIiglcCwnJTQuNHMnLCVwLCVwKVxuIiwgcHN0cmVhbSwgKGNoYXIqKSZmY2MsIGxwLCBscHJlYWQpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJU3RyZWFtX1JlYWREYXRhKHBzdHJlYW0sIGZjYywgbHAsIGxwcmVhZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtV3JpdGVEYXRhCShBVklGSUwzMi5AKQogKgkJQVZJU3RyZWFtV3JpdGVEYXRhCShBVklGSUxFLjE2NikKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbVdyaXRlRGF0YShQQVZJU1RSRUFNIHBzdHJlYW0sIERXT1JEIGZjYywgTFBWT0lEIGxwLAoJCQkJICBMT05HIHNpemUpCnsKICBUUkFDRSgiKCVwLCclNC40cycsJXAsJWQpXG4iLCBwc3RyZWFtLCAoY2hhciopJmZjYywgbHAsIHNpemUpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJU3RyZWFtX1dyaXRlRGF0YShwc3RyZWFtLCBmY2MsIGxwLCBzaXplKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1HZXRGcmFtZU9wZW4JKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1HZXRGcmFtZU9wZW4JKEFWSUZJTEUuMTEyKQogKi8KUEdFVEZSQU1FIFdJTkFQSSBBVklTdHJlYW1HZXRGcmFtZU9wZW4oUEFWSVNUUkVBTSBwc3RyZWFtLAoJCQkJICAgICAgIExQQklUTUFQSU5GT0hFQURFUiBscGJpV2FudGVkKQp7CiAgUEdFVEZSQU1FIHBnID0gTlVMTDsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIHBzdHJlYW0sIGxwYmlXYW50ZWQpOwoKICBpZiAoRkFJTEVEKElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UocHN0cmVhbSwgJklJRF9JR2V0RnJhbWUsIChMUFZPSUQqKSZwZykpIHx8CiAgICAgIHBnID09IE5VTEwpIHsKICAgIHBnID0gQVZJRklMRV9DcmVhdGVHZXRGcmFtZShwc3RyZWFtKTsKICAgIGlmIChwZyA9PSBOVUxMKQogICAgICByZXR1cm4gTlVMTDsKICB9CgogIGlmIChGQUlMRUQoSUdldEZyYW1lX1NldEZvcm1hdChwZywgbHBiaVdhbnRlZCwgTlVMTCwgMCwgMCwgLTEsIC0xKSkpIHsKICAgIElHZXRGcmFtZV9SZWxlYXNlKHBnKTsKICAgIHJldHVybiBOVUxMOwogIH0KCiAgcmV0dXJuIHBnOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUdldEZyYW1lCShBVklGSUwzMi5AKQogKgkJQVZJU3RyZWFtR2V0RnJhbWUJKEFWSUZJTEUuMTEwKQogKi8KTFBWT0lEIFdJTkFQSSBBVklTdHJlYW1HZXRGcmFtZShQR0VURlJBTUUgcGcsIExPTkcgcG9zKQp7CiAgVFJBQ0UoIiglcCwlZClcbiIsIHBnLCBwb3MpOwoKICBpZiAocGcgPT0gTlVMTCkKICAgIHJldHVybiBOVUxMOwoKICByZXR1cm4gSUdldEZyYW1lX0dldEZyYW1lKHBnLCBwb3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUdldEZyYW1lQ2xvc2UJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1HZXRGcmFtZUNsb3NlCShBVklGSUxFLjExMSkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbUdldEZyYW1lQ2xvc2UoUEdFVEZSQU1FIHBnKQp7CiAgVFJBQ0UoIiglcClcbiIsIHBnKTsKCiAgaWYgKHBnICE9IE5VTEwpCiAgICByZXR1cm4gSUdldEZyYW1lX1JlbGVhc2UocGcpOwogIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSU1ha2VDb21wcmVzc2VkU3RyZWFtCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJTWFrZUNvbXByZXNzZWRTdHJlYW0oUEFWSVNUUkVBTSAqcHBzQ29tcHJlc3NlZCwKCQkJCSAgICAgICBQQVZJU1RSRUFNIHBzU291cmNlLAoJCQkJICAgICAgIExQQVZJQ09NUFJFU1NPUFRJT05TIGFjbywKCQkJCSAgICAgICBMUENMU0lEIHBjbHNpZEhhbmRsZXIpCnsKICBBVklTVFJFQU1JTkZPVyBhc2l3OwogIENIQVIgICAgICAgICAgIHN6UmVnS2V5WzI1XTsKICBDSEFSICAgICAgICAgICBzelZhbHVlWzEwMF07CiAgQ0xTSUQgICAgICAgICAgY2xzaWRIYW5kbGVyOwogIEhSRVNVTFQgICAgICAgIGhyOwogIExPTkcgICAgICAgICAgIHNpemUgPSBzaXplb2Yoc3pWYWx1ZSk7CgogIFRSQUNFKCIoJXAsJXAsJXAsJXMpXG4iLCBwcHNDb21wcmVzc2VkLCBwc1NvdXJjZSwgYWNvLAoJZGVidWdzdHJfZ3VpZChwY2xzaWRIYW5kbGVyKSk7CgogIGlmIChwcHNDb21wcmVzc2VkID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChwc1NvdXJjZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogICpwcHNDb21wcmVzc2VkID0gTlVMTDsKCiAgLyogaWYgbm8gaGFuZGxlciBnaXZlbiBnZXQgZGVmYXVsdCBvbmVzIGJhc2VkIG9uIHN0cmVhbXR5cGUgKi8KICBpZiAocGNsc2lkSGFuZGxlciA9PSBOVUxMKSB7CiAgICBociA9IElBVklTdHJlYW1fSW5mbyhwc1NvdXJjZSwgJmFzaXcsIHNpemVvZihhc2l3KSk7CiAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwoKICAgIHdzcHJpbnRmQShzelJlZ0tleSwgIkFWSUZpbGVcXENvbXByZXNzb3JzXFwlNC40cyIsIChjaGFyKikmYXNpdy5mY2NUeXBlKTsKICAgIGlmIChSZWdRdWVyeVZhbHVlQShIS0VZX0NMQVNTRVNfUk9PVCwgc3pSZWdLZXksIHN6VmFsdWUsICZzaXplKSAhPSBFUlJPUl9TVUNDRVNTKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogICAgaWYgKEFWSUZJTEVfQ0xTSURGcm9tU3RyaW5nKHN6VmFsdWUsICZjbHNpZEhhbmRsZXIpICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CiAgfSBlbHNlCiAgICBjbHNpZEhhbmRsZXIgPSAqcGNsc2lkSGFuZGxlcjsKCiAgaHIgPSBDb0NyZWF0ZUluc3RhbmNlKCZjbHNpZEhhbmRsZXIsIE5VTEwsIENMU0NUWF9JTlBST0MsICZJSURfSUFWSVN0cmVhbSwgKExQVk9JRCopcHBzQ29tcHJlc3NlZCk7CiAgaWYgKEZBSUxFRChocikgfHwgKnBwc0NvbXByZXNzZWQgPT0gTlVMTCkKICAgIHJldHVybiBocjsKCiAgaHIgPSBJQVZJU3RyZWFtX0NyZWF0ZSgqcHBzQ29tcHJlc3NlZCwgKExQQVJBTSlwc1NvdXJjZSwgKExQQVJBTSlhY28pOwogIGlmIChGQUlMRUQoaHIpKSB7CiAgICBJQVZJU3RyZWFtX1JlbGVhc2UoKnBwc0NvbXByZXNzZWQpOwogICAgKnBwc0NvbXByZXNzZWQgPSBOVUxMOwogIH0KCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSU1ha2VGaWxlRnJvbVN0cmVhbXMJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklNYWtlRmlsZUZyb21TdHJlYW1zKFBBVklGSUxFICpwcGZpbGUsIGludCBuU3RyZWFtcywKCQkJCSAgICAgIFBBVklTVFJFQU0gKnBwU3RyZWFtcykKewogIFRSQUNFKCIoJXAsJWQsJXApXG4iLCBwcGZpbGUsIG5TdHJlYW1zLCBwcFN0cmVhbXMpOwoKICBpZiAoblN0cmVhbXMgPCAwIHx8IHBwZmlsZSA9PSBOVUxMIHx8IHBwU3RyZWFtcyA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKnBwZmlsZSA9IEFWSUZJTEVfQ3JlYXRlQVZJVGVtcEZpbGUoblN0cmVhbXMsIHBwU3RyZWFtcyk7CiAgaWYgKCpwcGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbU9wZW5Gcm9tRmlsZQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbU9wZW5Gcm9tRmlsZUEJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1PcGVuRnJvbUZpbGUgICAoQVZJRklMRS4xMDMpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTdHJlYW1PcGVuRnJvbUZpbGVBKFBBVklTVFJFQU0gKnBwYXZpLCBMUENTVFIgc3pGaWxlLAoJCQkJICAgICAgRFdPUkQgZmNjVHlwZSwgTE9ORyBsUGFyYW0sCgkJCQkgICAgICBVSU5UIG1vZGUsIExQQ0xTSUQgcGNsc2lkSGFuZGxlcikKewogIFBBVklGSUxFIHBmaWxlID0gTlVMTDsKICBIUkVTVUxUICBocjsKCiAgVFJBQ0UoIiglcCwlcywnJTQuNHMnLCVkLDB4JVgsJXMpXG4iLCBwcGF2aSwgZGVidWdzdHJfYShzekZpbGUpLAoJKGNoYXIqKSZmY2NUeXBlLCBsUGFyYW0sIG1vZGUsIGRlYnVnc3RyX2d1aWQocGNsc2lkSGFuZGxlcikpOwoKICBpZiAocHBhdmkgPT0gTlVMTCB8fCBzekZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICpwcGF2aSA9IE5VTEw7CgogIGhyID0gQVZJRmlsZU9wZW5BKCZwZmlsZSwgc3pGaWxlLCBtb2RlLCBwY2xzaWRIYW5kbGVyKTsKICBpZiAoRkFJTEVEKGhyKSB8fCBwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIGhyOwoKICBociA9IElBVklGaWxlX0dldFN0cmVhbShwZmlsZSwgcHBhdmksIGZjY1R5cGUsIGxQYXJhbSk7CiAgSUFWSUZpbGVfUmVsZWFzZShwZmlsZSk7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1PcGVuRnJvbUZpbGVXCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtT3BlbkZyb21GaWxlVyhQQVZJU1RSRUFNICpwcGF2aSwgTFBDV1NUUiBzekZpbGUsCgkJCQkgICAgICBEV09SRCBmY2NUeXBlLCBMT05HIGxQYXJhbSwKCQkJCSAgICAgIFVJTlQgbW9kZSwgTFBDTFNJRCBwY2xzaWRIYW5kbGVyKQp7CiAgUEFWSUZJTEUgcGZpbGUgPSBOVUxMOwogIEhSRVNVTFQgIGhyOwoKICBUUkFDRSgiKCVwLCVzLCclNC40cycsJWQsMHglWCwlcylcbiIsIHBwYXZpLCBkZWJ1Z3N0cl93KHN6RmlsZSksCgkoY2hhciopJmZjY1R5cGUsIGxQYXJhbSwgbW9kZSwgZGVidWdzdHJfZ3VpZChwY2xzaWRIYW5kbGVyKSk7CgogIGlmIChwcGF2aSA9PSBOVUxMIHx8IHN6RmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKnBwYXZpID0gTlVMTDsKCiAgaHIgPSBBVklGaWxlT3BlblcoJnBmaWxlLCBzekZpbGUsIG1vZGUsIHBjbHNpZEhhbmRsZXIpOwogIGlmIChGQUlMRUQoaHIpIHx8IHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gaHI7CgogIGhyID0gSUFWSUZpbGVfR2V0U3RyZWFtKHBmaWxlLCBwcGF2aSwgZmNjVHlwZSwgbFBhcmFtKTsKICBJQVZJRmlsZV9SZWxlYXNlKHBmaWxlKTsKCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUJlZ2luU3RyZWFtaW5nCShBVklGSUwzMi5AKQogKi8KTE9ORyBXSU5BUEkgQVZJU3RyZWFtQmVnaW5TdHJlYW1pbmcoUEFWSVNUUkVBTSBwYXZpLCBMT05HIGxTdGFydCwgTE9ORyBsRW5kLCBMT05HIGxSYXRlKQp7CiAgSUFWSVN0cmVhbWluZyogcHN0cmVhbSA9IE5VTEw7CiAgSFJFU1VMVCBocjsKCiAgVFJBQ0UoIiglcCwlZCwlZCwlZClcbiIsIHBhdmksIGxTdGFydCwgbEVuZCwgbFJhdGUpOwoKICBpZiAocGF2aSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIGhyID0gSUFWSVN0cmVhbV9RdWVyeUludGVyZmFjZShwYXZpLCAmSUlEX0lBVklTdHJlYW1pbmcsIChMUFZPSUQqKSZwc3RyZWFtKTsKICBpZiAoU1VDQ0VFREVEKGhyKSAmJiBwc3RyZWFtICE9IE5VTEwpIHsKICAgIGhyID0gSUFWSVN0cmVhbWluZ19CZWdpbihwc3RyZWFtLCBsU3RhcnQsIGxFbmQsIGxSYXRlKTsKICAgIElBVklTdHJlYW1pbmdfUmVsZWFzZShwc3RyZWFtKTsKICB9IGVsc2UKICAgIGhyID0gQVZJRVJSX09LOwoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtRW5kU3RyZWFtaW5nCShBVklGSUwzMi5AKQogKi8KTE9ORyBXSU5BUEkgQVZJU3RyZWFtRW5kU3RyZWFtaW5nKFBBVklTVFJFQU0gcGF2aSkKewogIElBVklTdHJlYW1pbmcqIHBzdHJlYW0gPSBOVUxMOwogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXApXG4iLCBwYXZpKTsKCiAgaHIgPSBJQVZJU3RyZWFtX1F1ZXJ5SW50ZXJmYWNlKHBhdmksICZJSURfSUFWSVN0cmVhbWluZywgKExQVk9JRCopJnBzdHJlYW0pOwogIGlmIChTVUNDRUVERUQoaHIpICYmIHBzdHJlYW0gIT0gTlVMTCkgewogICAgSUFWSVN0cmVhbWluZ19FbmQocHN0cmVhbSk7CiAgICBJQVZJU3RyZWFtaW5nX1JlbGVhc2UocHN0cmVhbSk7CiAgfQoKIHJldHVybiBBVklFUlJfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtU3RhcnQJCShBVklGSUxFLjEzMCkKICoJCUFWSVN0cmVhbVN0YXJ0CQkoQVZJRklMMzIuQCkKICovCkxPTkcgV0lOQVBJIEFWSVN0cmVhbVN0YXJ0KFBBVklTVFJFQU0gcHN0cmVhbSkKewogIEFWSVNUUkVBTUlORk9XIGFzaXc7CgogIFRSQUNFKCIoJXApXG4iLCBwc3RyZWFtKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiAwOwoKICBpZiAoRkFJTEVEKElBVklTdHJlYW1fSW5mbyhwc3RyZWFtLCAmYXNpdywgc2l6ZW9mKGFzaXcpKSkpCiAgICByZXR1cm4gMDsKCiAgcmV0dXJuIGFzaXcuZHdTdGFydDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1MZW5ndGgJCShBVklGSUxFLjEzMSkKICoJCUFWSVN0cmVhbUxlbmd0aAkJKEFWSUZJTDMyLkApCiAqLwpMT05HIFdJTkFQSSBBVklTdHJlYW1MZW5ndGgoUEFWSVNUUkVBTSBwc3RyZWFtKQp7CiAgQVZJU1RSRUFNSU5GT1cgYXNpdzsKCiAgVFJBQ0UoIiglcClcbiIsIHBzdHJlYW0pOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIDA7CgogIGlmIChGQUlMRUQoSUFWSVN0cmVhbV9JbmZvKHBzdHJlYW0sICZhc2l3LCBzaXplb2YoYXNpdykpKSkKICAgIHJldHVybiAwOwoKICByZXR1cm4gYXNpdy5kd0xlbmd0aDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1TYW1wbGVUb1RpbWUJKEFWSUZJTEUuMTMzKQogKgkJQVZJU3RyZWFtU2FtcGxlVG9UaW1lCShBVklGSUwzMi5AKQogKi8KTE9ORyBXSU5BUEkgQVZJU3RyZWFtU2FtcGxlVG9UaW1lKFBBVklTVFJFQU0gcHN0cmVhbSwgTE9ORyBsU2FtcGxlKQp7CiAgQVZJU1RSRUFNSU5GT1cgYXNpdzsKICBMT05HIHRpbWU7CgogIFRSQUNFKCIoJXAsJWQpXG4iLCBwc3RyZWFtLCBsU2FtcGxlKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiAtMTsKCiAgaWYgKEZBSUxFRChJQVZJU3RyZWFtX0luZm8ocHN0cmVhbSwgJmFzaXcsIHNpemVvZihhc2l3KSkpKQogICAgcmV0dXJuIC0xOwogIGlmIChhc2l3LmR3UmF0ZSA9PSAwKQogICAgcmV0dXJuIC0xOwoKICAvKiBsaW1pdCB0byBzdHJlYW0gYm91bmRzICovCiAgaWYgKGxTYW1wbGUgPCBhc2l3LmR3U3RhcnQpCiAgICBsU2FtcGxlID0gYXNpdy5kd1N0YXJ0OwogIGlmIChsU2FtcGxlID4gYXNpdy5kd1N0YXJ0ICsgYXNpdy5kd0xlbmd0aCkKICAgIGxTYW1wbGUgPSBhc2l3LmR3U3RhcnQgKyBhc2l3LmR3TGVuZ3RoOwoKICBpZiAoYXNpdy5kd1JhdGUgLyBhc2l3LmR3U2NhbGUgPCAxMDAwKQogICAgdGltZSA9IChMT05HKSgoKGZsb2F0KWxTYW1wbGUgKiBhc2l3LmR3U2NhbGUgKiAxMDAwKSAvIGFzaXcuZHdSYXRlKTsKICBlbHNlCiAgICB0aW1lID0gKExPTkcpKCgoZmxvYXQpbFNhbXBsZSAqIGFzaXcuZHdTY2FsZSAqIDEwMDAgKyAoYXNpdy5kd1JhdGUgLSAxKSkgLyBhc2l3LmR3UmF0ZSk7CgogIFRSQUNFKCIgLT4gJWRcbiIsdGltZSk7CiAgcmV0dXJuIHRpbWU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtVGltZVRvU2FtcGxlCShBVklGSUxFLjEzMikKICoJCUFWSVN0cmVhbVRpbWVUb1NhbXBsZQkoQVZJRklMMzIuQCkKICovCkxPTkcgV0lOQVBJIEFWSVN0cmVhbVRpbWVUb1NhbXBsZShQQVZJU1RSRUFNIHBzdHJlYW0sIExPTkcgbFRpbWUpCnsKICBBVklTVFJFQU1JTkZPVyBhc2l3OwogIFVMT05HIHNhbXBsZTsKCiAgVFJBQ0UoIiglcCwlZClcbiIsIHBzdHJlYW0sIGxUaW1lKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCB8fCBsVGltZSA8IDApCiAgICByZXR1cm4gLTE7CgogIGlmIChGQUlMRUQoSUFWSVN0cmVhbV9JbmZvKHBzdHJlYW0sICZhc2l3LCBzaXplb2YoYXNpdykpKSkKICAgIHJldHVybiAtMTsKICBpZiAoYXNpdy5kd1NjYWxlID09IDApCiAgICByZXR1cm4gLTE7CgogIGlmIChhc2l3LmR3UmF0ZSAvIGFzaXcuZHdTY2FsZSA8IDEwMDApCiAgICBzYW1wbGUgPSAoTE9ORykoKCgoZmxvYXQpYXNpdy5kd1JhdGUgKiBsVGltZSkgLyAoYXNpdy5kd1NjYWxlICogMTAwMCkpKTsKICBlbHNlCiAgICBzYW1wbGUgPSAoTE9ORykoKChmbG9hdClhc2l3LmR3UmF0ZSAqIGxUaW1lICsgKGFzaXcuZHdTY2FsZSAqIDEwMDAgLSAxKSkgLyAoYXNpdy5kd1NjYWxlICogMTAwMCkpOwoKICAvKiBsaW1pdCB0byBzdHJlYW0gYm91bmRzICovCiAgaWYgKHNhbXBsZSA8IGFzaXcuZHdTdGFydCkKICAgIHNhbXBsZSA9IGFzaXcuZHdTdGFydDsKICBpZiAoc2FtcGxlID4gYXNpdy5kd1N0YXJ0ICsgYXNpdy5kd0xlbmd0aCkKICAgIHNhbXBsZSA9IGFzaXcuZHdTdGFydCArIGFzaXcuZHdMZW5ndGg7CgogIFRSQUNFKCIgLT4gJWRcbiIsIHNhbXBsZSk7CiAgcmV0dXJuIHNhbXBsZTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklCdWlsZEZpbHRlcgkJKEFWSUZJTDMyLkApCiAqCQlBVklCdWlsZEZpbHRlckEJCShBVklGSUwzMi5AKQogKgkJQVZJQnVpbGRGaWx0ZXIJCShBVklGSUxFLjEyMykKICovCkhSRVNVTFQgV0lOQVBJIEFWSUJ1aWxkRmlsdGVyQShMUFNUUiBzekZpbHRlciwgTE9ORyBjYkZpbHRlciwgQk9PTCBmU2F2aW5nKQp7CiAgTFBXU1RSICB3c3pGaWx0ZXI7CiAgSFJFU1VMVCBocjsKCiAgVFJBQ0UoIiglcCwlZCwlZClcbiIsIHN6RmlsdGVyLCBjYkZpbHRlciwgZlNhdmluZyk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoc3pGaWx0ZXIgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKGNiRmlsdGVyIDwgMikKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgc3pGaWx0ZXJbMF0gPSAwOwogIHN6RmlsdGVyWzFdID0gMDsKCiAgd3N6RmlsdGVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGNiRmlsdGVyICogc2l6ZW9mKFdDSEFSKSk7CiAgaWYgKHdzekZpbHRlciA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIGhyID0gQVZJQnVpbGRGaWx0ZXJXKHdzekZpbHRlciwgY2JGaWx0ZXIsIGZTYXZpbmcpOwogIGlmIChTVUNDRUVERUQoaHIpKSB7CiAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgd3N6RmlsdGVyLCBjYkZpbHRlciwKCQkJc3pGaWx0ZXIsIGNiRmlsdGVyLCBOVUxMLCBOVUxMKTsKICB9CgogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHdzekZpbHRlcik7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklCdWlsZEZpbHRlclcJCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJQnVpbGRGaWx0ZXJXKExQV1NUUiBzekZpbHRlciwgTE9ORyBjYkZpbHRlciwgQk9PTCBmU2F2aW5nKQp7CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6Q2xzaWRbXSA9IHsnQycsJ0wnLCdTJywnSScsJ0QnLDB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzekV4dGVuc2lvbkZtdFtdID0geyc7JywnKicsJy4nLCclJywncycsMH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6QVZJRmlsZUV4dGVuc2lvbnNbXSA9CiAgICB7J0EnLCdWJywnSScsJ0YnLCdpJywnbCcsJ2UnLCdcXCcsJ0UnLCd4JywndCcsJ2UnLCduJywncycsJ2knLCdvJywnbicsJ3MnLDB9OwoKICBBVklGaWx0ZXIgKmxwOwogIFdDSEFSICAgICAgc3pBbGxGaWxlc1s0MF07CiAgV0NIQVIgICAgICBzekZpbGVFeHRbMTBdOwogIFdDSEFSICAgICAgc3pWYWx1ZVsxMjhdOwogIEhLRVkgICAgICAgaEtleTsKICBEV09SRCAgICAgIG4sIGk7CiAgTE9ORyAgICAgICBzaXplOwogIERXT1JEICAgICAgY291bnQgPSAwOwoKICBUUkFDRSgiKCVwLCVkLCVkKVxuIiwgc3pGaWx0ZXIsIGNiRmlsdGVyLCBmU2F2aW5nKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChzekZpbHRlciA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoY2JGaWx0ZXIgPCAyKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICBscCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBNQVhfRklMVEVSUyAqIHNpemVvZihBVklGaWx0ZXIpKTsKICBpZiAobHAgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAvKgogICAqIDEuIGl0ZXJhdGUgb3ZlciBIS0VZX0NMQVNTRVNfUk9PVFxcQVZJRmlsZVxcRXh0ZW5zaW9ucyBhbmQgY29sbGVjdAogICAqICAgIGV4dGVuc2lvbnMgYW5kIENMU0lEJ3MKICAgKiAyLiBpdGVyYXRlIG92ZXIgY29sbGVjdGVkIENMU0lEJ3MgYW5kIGNvcHkgaXRzIGRlc2NyaXB0aW9uIGFuZCBpdHMKICAgKiAgICBleHRlbnNpb25zIHRvIHN6RmlsdGVyIGlmIGl0IGZpdHMKICAgKgogICAqIEZpcnN0IGZpbHRlciBpcyBuYW1lZCAiQWxsIG11bHRpbWVkaWEgZmlsZXMiIGFuZCBpdHMgZmlsdGVyIGlzIGEKICAgKiBjb2xsZWN0aW9uIG9mIGFsbCBwb3NzaWJsZSBleHRlbnNpb25zIGV4Y2VwdCAiKi4qIi4KICAgKi8KICBpZiAoUmVnT3BlbktleVcoSEtFWV9DTEFTU0VTX1JPT1QsIHN6QVZJRmlsZUV4dGVuc2lvbnMsICZoS2V5KSAhPSBTX09LKSB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBscCk7CiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOwogIH0KICBmb3IgKG4gPSAwO1JlZ0VudW1LZXlXKGhLZXksIG4sIHN6RmlsZUV4dCwgc2l6ZW9mKHN6RmlsZUV4dCkvc2l6ZW9mKHN6RmlsZUV4dFswXSkpID09IFNfT0s7bisrKSB7CiAgICAvKiBnZXQgQ0xTSUQgdG8gZXh0ZW5zaW9uICovCiAgICBzaXplID0gc2l6ZW9mKHN6VmFsdWUpOwogICAgaWYgKFJlZ1F1ZXJ5VmFsdWVXKGhLZXksIHN6RmlsZUV4dCwgc3pWYWx1ZSwgJnNpemUpICE9IFNfT0spCiAgICAgIGJyZWFrOwoKICAgIC8qIHNlYXJjaCBpZiB0aGUgQ0xTSUQgaXMgYWxyZWFkeSBrbm93biAqLwogICAgZm9yIChpID0gMTsgaSA8PSBjb3VudDsgaSsrKSB7CiAgICAgIGlmIChsc3RyY21wVyhscFtpXS5zekNsc2lkLCBzelZhbHVlKSA9PSAwKQoJYnJlYWs7IC8qIGEgbmV3IG9uZSAqLwogICAgfQoKICAgIGlmIChpID09IGNvdW50ICsgMSkgewogICAgICAvKiBpdCdzIGEgbmV3IENMU0lEICovCgogICAgICAvKiBGSVhNRTogSG93IGRvIHdlIGdldCBpbmZvJ3MgYWJvdXQgcmVhZC93cml0ZSBjYXBhYmlsaXRpZXM/ICovCgogICAgICBpZiAoY291bnQgPj0gTUFYX0ZJTFRFUlMpIHsKCS8qIHRyeSB0byBpbmZvcm0gdXNlciBvZiBvdXIgZnVsbCBmaXhlZCBzaXplIHRhYmxlICovCglFUlIoIjogTW9yZSB0aGFuICVkIGZpbHRlcnMgZm91bmQhIEFkanVzdCBNQVhfRklMVEVSUyBpbiBkbGxzL2F2aWZpbDMyL2FwaS5jXG4iLCBNQVhfRklMVEVSUyk7CglicmVhazsKICAgICAgfQoKICAgICAgbHN0cmNweVcobHBbaV0uc3pDbHNpZCwgc3pWYWx1ZSk7CgogICAgICBjb3VudCsrOwogICAgfQoKICAgIC8qIGFwcGVuZCBleHRlbnNpb24gdG8gdGhlIGZpbHRlciAqLwogICAgd3NwcmludGZXKHN6VmFsdWUsIHN6RXh0ZW5zaW9uRm10LCBzekZpbGVFeHQpOwogICAgaWYgKGxwW2ldLnN6RXh0ZW5zaW9uc1swXSA9PSAwKQogICAgICBsc3RyY2F0VyhscFtpXS5zekV4dGVuc2lvbnMsIHN6VmFsdWUgKyAxKTsKICAgIGVsc2UKICAgICAgbHN0cmNhdFcobHBbaV0uc3pFeHRlbnNpb25zLCBzelZhbHVlKTsKCiAgICAvKiBhbHNvIGFwcGVuZCB0byB0aGUgImFsbCBtdWx0aW1lZGlhIi1maWx0ZXIgKi8KICAgIGlmIChscFswXS5zekV4dGVuc2lvbnNbMF0gPT0gMCkKICAgICAgbHN0cmNhdFcobHBbMF0uc3pFeHRlbnNpb25zLCBzelZhbHVlICsgMSk7CiAgICBlbHNlCiAgICAgIGxzdHJjYXRXKGxwWzBdLnN6RXh0ZW5zaW9ucywgc3pWYWx1ZSk7CiAgfQogIFJlZ0Nsb3NlS2V5KGhLZXkpOwoKICAvKiAyLiBnZXQgZGVzY3JpcHRpb25zIGZvciB0aGUgQ0xTSURzIGFuZCBmaWxsIG91dCBzekZpbHRlciAqLwogIGlmIChSZWdPcGVuS2V5VyhIS0VZX0NMQVNTRVNfUk9PVCwgc3pDbHNpZCwgJmhLZXkpICE9IFNfT0spIHsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGxwKTsKICAgIHJldHVybiBBVklFUlJfRVJST1I7CiAgfQogIGZvciAobiA9IDA7IG4gPD0gY291bnQ7IG4rKykgewogICAgLyogZmlyc3QgdGhlIGRlc2NyaXB0aW9uICovCiAgICBpZiAobiAhPSAwKSB7CiAgICAgIHNpemUgPSBzaXplb2Yoc3pWYWx1ZSk7CiAgICAgIGlmIChSZWdRdWVyeVZhbHVlVyhoS2V5LCBscFtuXS5zekNsc2lkLCBzelZhbHVlLCAmc2l6ZSkgPT0gU19PSykgewoJc2l6ZSA9IGxzdHJsZW5XKHN6VmFsdWUpOwoJbHN0cmNweW5XKHN6RmlsdGVyLCBzelZhbHVlLCBjYkZpbHRlcik7CiAgICAgIH0KICAgIH0gZWxzZQogICAgICBzaXplID0gTG9hZFN0cmluZ1coQVZJRklMRV9oTW9kdWxlLElEU19BTExNVUxUSU1FRElBLHN6RmlsdGVyLGNiRmlsdGVyKTsKCiAgICAvKiBjaGVjayBmb3IgZW5vdWdoIHNwYWNlICovCiAgICBzaXplKys7CiAgICBpZiAoY2JGaWx0ZXIgPCBzaXplICsgbHN0cmxlblcobHBbbl0uc3pFeHRlbnNpb25zKSArIDIpIHsKICAgICAgc3pGaWx0ZXJbMF0gPSAwOwogICAgICBzekZpbHRlclsxXSA9IDA7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGxwKTsKICAgICAgUmVnQ2xvc2VLZXkoaEtleSk7CiAgICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgICB9CiAgICBjYkZpbHRlciAtPSBzaXplOwogICAgc3pGaWx0ZXIgKz0gc2l6ZTsKCiAgICAvKiBhbmQgdGhlbiB0aGUgZmlsdGVyICovCiAgICBsc3RyY3B5blcoc3pGaWx0ZXIsIGxwW25dLnN6RXh0ZW5zaW9ucywgY2JGaWx0ZXIpOwogICAgc2l6ZSA9IGxzdHJsZW5XKGxwW25dLnN6RXh0ZW5zaW9ucykgKyAxOwogICAgY2JGaWx0ZXIgLT0gc2l6ZTsKICAgIHN6RmlsdGVyICs9IHNpemU7CiAgfQoKICBSZWdDbG9zZUtleShoS2V5KTsKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBscCk7CgogIC8qIGFkZCAiQWxsIGZpbGVzIiAiKi4qIiBmaWx0ZXIgaWYgZW5vdWdoIHNwYWNlIGxlZnQgKi8KICBzaXplID0gTG9hZFN0cmluZ1coQVZJRklMRV9oTW9kdWxlLCBJRFNfQUxMRklMRVMsCgkJICAgICBzekFsbEZpbGVzLCBzaXplb2Yoc3pBbGxGaWxlcykvc2l6ZW9mKHN6QWxsRmlsZXNbMF0pKSArIDE7CiAgaWYgKGNiRmlsdGVyID4gc2l6ZSkgewogICAgaW50IGk7CgogICAgLyogcmVwbGFjZSAnQCcgd2l0aCBcMDAwIHRvIHNlcGFyYXRlIGRlc2NyaXB0aW9uIG9mIGZpbHRlciAqLwogICAgZm9yIChpID0gMDsgaSA8IHNpemUgJiYgc3pBbGxGaWxlc1tpXSAhPSAwOyBpKyspIHsKICAgICAgaWYgKHN6QWxsRmlsZXNbaV0gPT0gJ0AnKSB7CglzekFsbEZpbGVzW2ldID0gMDsKCWJyZWFrOwogICAgICB9CiAgICB9CiAgICAgIAogICAgbWVtY3B5KHN6RmlsdGVyLCBzekFsbEZpbGVzLCBzaXplICogc2l6ZW9mKHN6QWxsRmlsZXNbMF0pKTsKICAgIHN6RmlsdGVyICs9IHNpemU7CiAgICBzekZpbHRlclswXSA9IDA7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9IGVsc2UgewogICAgc3pGaWx0ZXJbMF0gPSAwOwogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICB9Cn0KCnN0YXRpYyBCT09MIEFWSVNhdmVPcHRpb25zRm10Q2hvb3NlKEhXTkQgaFduZCkKewogIExQQVZJQ09NUFJFU1NPUFRJT05TIHBPcHRpb25zID0gU2F2ZU9wdHMucHBPcHRpb25zW1NhdmVPcHRzLm5DdXJyZW50XTsKICBBVklTVFJFQU1JTkZPVyAgICAgICBzSW5mbzsKCiAgVFJBQ0UoIiglcClcbiIsIGhXbmQpOwoKICBpZiAocE9wdGlvbnMgPT0gTlVMTCB8fCBTYXZlT3B0cy5wcGF2aXNbU2F2ZU9wdHMubkN1cnJlbnRdID09IE5VTEwpIHsKICAgIEVSUigiOiBiYWQgc3RhdGUhXG4iKTsKICAgIHJldHVybiBGQUxTRTsKICB9CgogIGlmIChGQUlMRUQoQVZJU3RyZWFtSW5mb1coU2F2ZU9wdHMucHBhdmlzW1NhdmVPcHRzLm5DdXJyZW50XSwKCQkJICAgICZzSW5mbywgc2l6ZW9mKHNJbmZvKSkpKSB7CiAgICBFUlIoIjogQVZJU3RyZWFtSW5mb1cgZmFpbGVkIVxuIik7CiAgICByZXR1cm4gRkFMU0U7CiAgfQoKICBpZiAoc0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlVklERU8pIHsKICAgIENPTVBWQVJTIGN2OwogICAgQk9PTCAgICAgcmV0OwoKICAgIG1lbXNldCgmY3YsIDAsIHNpemVvZihjdikpOwoKICAgIGlmICgocE9wdGlvbnMtPmR3RmxhZ3MgJiBBVklDT01QUkVTU0ZfVkFMSUQpID09IDApIHsKICAgICAgbWVtc2V0KHBPcHRpb25zLCAwLCBzaXplb2YoQVZJQ09NUFJFU1NPUFRJT05TKSk7CiAgICAgIHBPcHRpb25zLT5mY2NUeXBlICAgID0gc3RyZWFtdHlwZVZJREVPOwogICAgICBwT3B0aW9ucy0+ZmNjSGFuZGxlciA9IGNvbXB0eXBlRElCOwogICAgICBwT3B0aW9ucy0+ZHdRdWFsaXR5ICA9IChEV09SRClJQ1FVQUxJVFlfREVGQVVMVDsKICAgIH0KCiAgICBjdi5jYlNpemUgICAgID0gc2l6ZW9mKGN2KTsKICAgIGN2LmR3RmxhZ3MgICAgPSBJQ01GX0NPTVBWQVJTX1ZBTElEOwogICAgLypjdi5mY2NUeXBlICAgID0gcE9wdGlvbnMtPmZjY1R5cGU7ICovCiAgICBjdi5mY2NIYW5kbGVyID0gcE9wdGlvbnMtPmZjY0hhbmRsZXI7CiAgICBjdi5sUSAgICAgICAgID0gcE9wdGlvbnMtPmR3UXVhbGl0eTsKICAgIGN2LmxwU3RhdGUgICAgPSBwT3B0aW9ucy0+bHBQYXJtczsKICAgIGN2LmNiU3RhdGUgICAgPSBwT3B0aW9ucy0+Y2JQYXJtczsKICAgIGlmIChwT3B0aW9ucy0+ZHdGbGFncyAmIEFWSUNPTVBSRVNTRl9LRVlGUkFNRVMpCiAgICAgIGN2LmxLZXkgPSBwT3B0aW9ucy0+ZHdLZXlGcmFtZUV2ZXJ5OwogICAgZWxzZQogICAgICBjdi5sS2V5ID0gMDsKICAgIGlmIChwT3B0aW9ucy0+ZHdGbGFncyAmIEFWSUNPTVBSRVNTRl9EQVRBUkFURSkKICAgICAgY3YubERhdGFSYXRlID0gcE9wdGlvbnMtPmR3Qnl0ZXNQZXJTZWNvbmQgLyAxMDI0OyAvKiBuZWVkIGtCeXRlcyAqLwogICAgZWxzZQogICAgICBjdi5sRGF0YVJhdGUgPSAwOwoKICAgIHJldCA9IElDQ29tcHJlc3NvckNob29zZShoV25kLCBTYXZlT3B0cy51RmxhZ3MsIE5VTEwsCgkJCSAgICAgU2F2ZU9wdHMucHBhdmlzW1NhdmVPcHRzLm5DdXJyZW50XSwgJmN2LCBOVUxMKTsKCiAgICBpZiAocmV0KSB7CiAgICAgIHBPcHRpb25zLT5mY2NIYW5kbGVyID0gY3YuZmNjSGFuZGxlcjsKICAgICAgcE9wdGlvbnMtPmxwUGFybXMgICA9IGN2LmxwU3RhdGU7CiAgICAgIHBPcHRpb25zLT5jYlBhcm1zICAgPSBjdi5jYlN0YXRlOwogICAgICBwT3B0aW9ucy0+ZHdRdWFsaXR5ID0gY3YubFE7CiAgICAgIGlmIChjdi5sS2V5ICE9IDApIHsKCXBPcHRpb25zLT5kd0tleUZyYW1lRXZlcnkgPSBjdi5sS2V5OwoJcE9wdGlvbnMtPmR3RmxhZ3MgfD0gQVZJQ09NUFJFU1NGX0tFWUZSQU1FUzsKICAgICAgfSBlbHNlCglwT3B0aW9ucy0+ZHdGbGFncyAmPSB+QVZJQ09NUFJFU1NGX0tFWUZSQU1FUzsKICAgICAgaWYgKGN2LmxEYXRhUmF0ZSAhPSAwKSB7CglwT3B0aW9ucy0+ZHdCeXRlc1BlclNlY29uZCA9IGN2LmxEYXRhUmF0ZSAqIDEwMjQ7IC8qIG5lZWQgYnl0ZXMgKi8KCXBPcHRpb25zLT5kd0ZsYWdzIHw9IEFWSUNPTVBSRVNTRl9EQVRBUkFURTsKICAgICAgfSBlbHNlCglwT3B0aW9ucy0+ZHdGbGFncyAmPSB+QVZJQ09NUFJFU1NGX0RBVEFSQVRFOwogICAgICBwT3B0aW9ucy0+ZHdGbGFncyAgfD0gQVZJQ09NUFJFU1NGX1ZBTElEOwogICAgfQogICAgSUNDb21wcmVzc29yRnJlZSgmY3YpOwoKICAgIHJldHVybiByZXQ7CiAgfSBlbHNlIGlmIChzSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVBVURJTykgewogICAgQUNNRk9STUFUQ0hPT1NFVyBhZm10YzsKICAgIE1NUkVTVUxUICAgICAgICAgcmV0OwogICAgTE9ORyAgICAgICAgICAgICBzaXplOwoKICAgIC8qIEZJWE1FOiBjaGVjayBBQ00gdmVyc2lvbiAtLSBXaGljaCB2ZXJzaW9uIGlzIG5lZWRlZD8gKi8KCiAgICBtZW1zZXQoJmFmbXRjLCAwLCBzaXplb2YoYWZtdGMpKTsKICAgIGFmbXRjLmNiU3RydWN0ICA9IHNpemVvZihhZm10Yyk7CiAgICBhZm10Yy5mZHdTdHlsZSAgPSAwOwogICAgYWZtdGMuaHduZE93bmVyID0gaFduZDsKCiAgICBhY21NZXRyaWNzKE5VTEwsIEFDTV9NRVRSSUNfTUFYX1NJWkVfRk9STUFULCAmc2l6ZSk7CiAgICBpZiAoKHBPcHRpb25zLT5jYkZvcm1hdCA9PSAwIHx8IHBPcHRpb25zLT5scEZvcm1hdCA9PSBOVUxMKSAmJiBzaXplICE9IDApIHsKICAgICAgcE9wdGlvbnMtPmxwRm9ybWF0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUpOwogICAgICBwT3B0aW9ucy0+Y2JGb3JtYXQgPSBzaXplOwogICAgfSBlbHNlIGlmIChwT3B0aW9ucy0+Y2JGb3JtYXQgPCAoRFdPUkQpc2l6ZSkgewogICAgICBwT3B0aW9ucy0+bHBGb3JtYXQgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBwT3B0aW9ucy0+bHBGb3JtYXQsIHNpemUpOwogICAgICBwT3B0aW9ucy0+Y2JGb3JtYXQgPSBzaXplOwogICAgfQogICAgaWYgKHBPcHRpb25zLT5scEZvcm1hdCA9PSBOVUxMKQogICAgICByZXR1cm4gRkFMU0U7CiAgICBhZm10Yy5wd2Z4ICA9IHBPcHRpb25zLT5scEZvcm1hdDsKICAgIGFmbXRjLmNid2Z4ID0gcE9wdGlvbnMtPmNiRm9ybWF0OwoKICAgIHNpemUgPSAwOwogICAgQVZJU3RyZWFtRm9ybWF0U2l6ZShTYXZlT3B0cy5wcGF2aXNbU2F2ZU9wdHMubkN1cnJlbnRdLAoJCQlzSW5mby5kd1N0YXJ0LCAmc2l6ZSk7CiAgICBpZiAoc2l6ZSA8IChMT05HKXNpemVvZihQQ01XQVZFRk9STUFUKSkKICAgICAgc2l6ZSA9IHNpemVvZihQQ01XQVZFRk9STUFUKTsKICAgIGFmbXRjLnB3ZnhFbnVtID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUpOwogICAgaWYgKGFmbXRjLnB3ZnhFbnVtICE9IE5VTEwpIHsKICAgICAgQVZJU3RyZWFtUmVhZEZvcm1hdChTYXZlT3B0cy5wcGF2aXNbU2F2ZU9wdHMubkN1cnJlbnRdLAoJCQkgIHNJbmZvLmR3U3RhcnQsIGFmbXRjLnB3ZnhFbnVtLCAmc2l6ZSk7CiAgICAgIGFmbXRjLmZkd0VudW0gPSBBQ01fRk9STUFURU5VTUZfQ09OVkVSVDsKICAgIH0KCiAgICByZXQgPSBhY21Gb3JtYXRDaG9vc2VXKCZhZm10Yyk7CiAgICBpZiAocmV0ID09IFNfT0spCiAgICAgIHBPcHRpb25zLT5kd0ZsYWdzIHw9IEFWSUNPTVBSRVNTRl9WQUxJRDsKCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBhZm10Yy5wd2Z4RW51bSk7CiAgICByZXR1cm4gKHJldCA9PSBTX09LID8gVFJVRSA6IEZBTFNFKTsKICB9IGVsc2UgewogICAgRVJSKCI6IHVua25vd24gc3RyZWFtdHlwZSAweCUwOFhcbiIsIHNJbmZvLmZjY1R5cGUpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KfQoKc3RhdGljIHZvaWQgQVZJU2F2ZU9wdGlvbnNVcGRhdGUoSFdORCBoV25kKQp7CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6VmlkZW9GbXRbXT17JyUnLCdsJywnZCcsJ3gnLCclJywnbCcsJ2QnLCd4JywnJScsJ2QnLDB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzekF1ZGlvRm10W109eyclJywncycsJyAnLCclJywncycsMH07CgogIFdDSEFSICAgICAgICAgIHN6Rm9ybWF0WzEyOF07CiAgQVZJU1RSRUFNSU5GT1cgc0luZm87CiAgTFBWT0lEICAgICAgICAgbHBGb3JtYXQ7CiAgTE9ORyAgICAgICAgICAgc2l6ZTsKCiAgVFJBQ0UoIiglcClcbiIsIGhXbmQpOwoKICBTYXZlT3B0cy5uQ3VycmVudCA9IFNlbmREbGdJdGVtTWVzc2FnZVcoaFduZCxJRENfU1RSRUFNLENCX0dFVENVUlNFTCwwLDApOwogIGlmIChTYXZlT3B0cy5uQ3VycmVudCA8IDApCiAgICByZXR1cm47CgogIGlmIChGQUlMRUQoQVZJU3RyZWFtSW5mb1coU2F2ZU9wdHMucHBhdmlzW1NhdmVPcHRzLm5DdXJyZW50XSwgJnNJbmZvLCBzaXplb2Yoc0luZm8pKSkpCiAgICByZXR1cm47CgogIEFWSVN0cmVhbUZvcm1hdFNpemUoU2F2ZU9wdHMucHBhdmlzW1NhdmVPcHRzLm5DdXJyZW50XSxzSW5mby5kd1N0YXJ0LCZzaXplKTsKICBpZiAoc2l6ZSA+IDApIHsKICAgIHN6Rm9ybWF0WzBdID0gMDsKCiAgICAvKiByZWFkIGZvcm1hdCB0byBidWlsZCBmb3JtYXQgZGVzY3JpcHRpb24gc3RyaW5nICovCiAgICBscEZvcm1hdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplKTsKICAgIGlmIChscEZvcm1hdCAhPSBOVUxMKSB7CiAgICAgIGlmIChTVUNDRUVERUQoQVZJU3RyZWFtUmVhZEZvcm1hdChTYXZlT3B0cy5wcGF2aXNbU2F2ZU9wdHMubkN1cnJlbnRdLHNJbmZvLmR3U3RhcnQsbHBGb3JtYXQsICZzaXplKSkpIHsKCWlmIChzSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTykgewoJICBMUEJJVE1BUElORk9IRUFERVIgbHBiaSA9IGxwRm9ybWF0OwoJICBJQ0lORk8gaWNpbmZvOwoKCSAgd3NwcmludGZXKHN6Rm9ybWF0LCBzelZpZGVvRm10LCBscGJpLT5iaVdpZHRoLAoJCSAgICBscGJpLT5iaUhlaWdodCwgbHBiaS0+YmlCaXRDb3VudCk7CgoJICBpZiAobHBiaS0+YmlDb21wcmVzc2lvbiAhPSBCSV9SR0IpIHsKCSAgICBISUMgICAgaGljOwoKCSAgICBoaWMgPSBJQ0xvY2F0ZShJQ1RZUEVfVklERU8sIHNJbmZvLmZjY0hhbmRsZXIsIGxwRm9ybWF0LAoJCQkgICBOVUxMLCBJQ01PREVfREVDT01QUkVTUyk7CgkgICAgaWYgKGhpYyAhPSBOVUxMKSB7CgkgICAgICBpZiAoSUNHZXRJbmZvKGhpYywgJmljaW5mbywgc2l6ZW9mKGljaW5mbykpID09IFNfT0spCgkJbHN0cmNhdFcoc3pGb3JtYXQsIGljaW5mby5zekRlc2NyaXB0aW9uKTsKCSAgICAgIElDQ2xvc2UoaGljKTsKCSAgICB9CgkgIH0gZWxzZSB7CgkgICAgTG9hZFN0cmluZ1coQVZJRklMRV9oTW9kdWxlLCBJRFNfVU5DT01QUkVTU0VELAoJCQlpY2luZm8uc3pEZXNjcmlwdGlvbiwKCQkJc2l6ZW9mKGljaW5mby5zekRlc2NyaXB0aW9uKS9zaXplb2YoaWNpbmZvLnN6RGVzY3JpcHRpb25bMF0pKTsKCSAgICBsc3RyY2F0VyhzekZvcm1hdCwgaWNpbmZvLnN6RGVzY3JpcHRpb24pOwoJICB9Cgl9IGVsc2UgaWYgKHNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZUFVRElPKSB7CgkgIEFDTUZPUk1BVFRBR0RFVEFJTFNXIGFmdGQ7CgkgIEFDTUZPUk1BVERFVEFJTFNXICAgIGFmZDsKCgkgIG1lbXNldCgmYWZ0ZCwgMCwgc2l6ZW9mKGFmdGQpKTsKCSAgbWVtc2V0KCZhZmQsIDAsIHNpemVvZihhZmQpKTsKCgkgIGFmdGQuY2JTdHJ1Y3QgICAgID0gc2l6ZW9mKGFmdGQpOwoJICBhZnRkLmR3Rm9ybWF0VGFnICA9IGFmZC5kd0Zvcm1hdFRhZyA9CgkgICAgKChQV0FWRUZPUk1BVEVYKWxwRm9ybWF0KS0+d0Zvcm1hdFRhZzsKCSAgYWZ0ZC5jYkZvcm1hdFNpemUgPSBhZmQuY2J3ZnggPSBzaXplOwoKCSAgYWZkLmNiU3RydWN0ICAgICAgPSBzaXplb2YoYWZkKTsKCSAgYWZkLnB3ZnggICAgICAgICAgPSBscEZvcm1hdDsKCgkgIGlmIChhY21Gb3JtYXRUYWdEZXRhaWxzVyhOVUxMLCAmYWZ0ZCwKCQkJCSAgIEFDTV9GT1JNQVRUQUdERVRBSUxTRl9GT1JNQVRUQUcpID09IFNfT0spIHsKCSAgICBpZiAoYWNtRm9ybWF0RGV0YWlsc1coTlVMTCwmYWZkLEFDTV9GT1JNQVRERVRBSUxTRl9GT1JNQVQpID09IFNfT0spCgkgICAgICB3c3ByaW50Zlcoc3pGb3JtYXQsIHN6QXVkaW9GbXQsIGFmZC5zekZvcm1hdCwgYWZ0ZC5zekZvcm1hdFRhZyk7CgkgIH0KCX0KICAgICAgfQogICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBscEZvcm1hdCk7CiAgICB9CgogICAgLyogc2V0IHRleHQgZm9yIGZvcm1hdCBkZXNjcmlwdGlvbiAqLwogICAgU2V0RGxnSXRlbVRleHRXKGhXbmQsIElEQ19GT1JNQVRURVhULCBzekZvcm1hdCk7CgogICAgLyogRGlzYWJsZSBvcHRpb24gYnV0dG9uIGZvciB1bnN1cHBvcnRlZCBzdHJlYW10eXBlcyAqLwogICAgaWYgKHNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPIHx8CglzSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVBVURJTykKICAgICAgRW5hYmxlV2luZG93KEdldERsZ0l0ZW0oaFduZCwgSURDX09QVElPTlMpLCBUUlVFKTsKICAgIGVsc2UKICAgICAgRW5hYmxlV2luZG93KEdldERsZ0l0ZW0oaFduZCwgSURDX09QVElPTlMpLCBGQUxTRSk7CiAgfQoKfQoKc3RhdGljIElOVF9QVFIgQ0FMTEJBQ0sgQVZJU2F2ZU9wdGlvbnNEbGdQcm9jKEhXTkQgaFduZCwgVUlOVCB1TXNnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogIERXT1JEIGR3SW50ZXJsZWF2ZTsKICBCT09MICBiSXNJbnRlcmxlYXZlZDsKICBJTlQgICBuOwoKICAvKlRSQUNFKCIoJXAsJXUsMHglMDRYLDB4JTA4bFgpXG4iLCBoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7Ki8KCiAgc3dpdGNoICh1TXNnKSB7CiAgY2FzZSBXTV9JTklURElBTE9HOgogICAgU2F2ZU9wdHMubkN1cnJlbnQgPSAwOwogICAgaWYgKFNhdmVPcHRzLm5TdHJlYW1zID09IDEpIHsKICAgICAgRW5kRGlhbG9nKGhXbmQsIEFWSVNhdmVPcHRpb25zRm10Q2hvb3NlKGhXbmQpKTsKICAgICAgcmV0dXJuIFRSVUU7CiAgICB9CgogICAgLyogYWRkIHN0cmVhbXMgKi8KICAgIGZvciAobiA9IDA7IG4gPCBTYXZlT3B0cy5uU3RyZWFtczsgbisrKSB7CiAgICAgIEFWSVNUUkVBTUlORk9XIHNJbmZvOwoKICAgICAgQVZJU3RyZWFtSW5mb1coU2F2ZU9wdHMucHBhdmlzW25dLCAmc0luZm8sIHNpemVvZihzSW5mbykpOwogICAgICBTZW5kRGxnSXRlbU1lc3NhZ2VXKGhXbmQsIElEQ19TVFJFQU0sIENCX0FERFNUUklORywKCQkJICAwTCwgKExQQVJBTSlzSW5mby5zek5hbWUpOwogICAgfQoKICAgIC8qIHNlbGVjdCBmaXJzdCBzdHJlYW0gKi8KICAgIFNlbmREbGdJdGVtTWVzc2FnZVcoaFduZCwgSURDX1NUUkVBTSwgQ0JfU0VUQ1VSU0VMLCAwLCAwKTsKICAgIFNlbmRNZXNzYWdlVyhoV25kLCBXTV9DT01NQU5ELCBNQUtFTE9ORyhJRENfU1RSRUFNLCBDQk5fU0VMQ0hBTkdFKSwgKExQQVJBTSloV25kKTsKCiAgICAvKiBpbml0aWFsaXplIGludGVybGVhdmUgKi8KICAgIGlmIChTYXZlT3B0cy5wcE9wdGlvbnNbMF0gIT0gTlVMTCAmJgoJKFNhdmVPcHRzLnBwT3B0aW9uc1swXS0+ZHdGbGFncyAmIEFWSUNPTVBSRVNTRl9WQUxJRCkpIHsKICAgICAgYklzSW50ZXJsZWF2ZWQgPSAoU2F2ZU9wdHMucHBPcHRpb25zWzBdLT5kd0ZsYWdzICYgQVZJQ09NUFJFU1NGX0lOVEVSTEVBVkUpOwogICAgICBkd0ludGVybGVhdmUgPSBTYXZlT3B0cy5wcE9wdGlvbnNbMF0tPmR3SW50ZXJsZWF2ZUV2ZXJ5OwogICAgfSBlbHNlIHsKICAgICAgYklzSW50ZXJsZWF2ZWQgPSBUUlVFOwogICAgICBkd0ludGVybGVhdmUgICA9IDA7CiAgICB9CiAgICBDaGVja0RsZ0J1dHRvbihoV25kLCBJRENfSU5URVJMRUFWRSwgYklzSW50ZXJsZWF2ZWQpOwogICAgU2V0RGxnSXRlbUludChoV25kLCBJRENfSU5URVJMRUFWRUVWRVJZLCBkd0ludGVybGVhdmUsIEZBTFNFKTsKICAgIEVuYWJsZVdpbmRvdyhHZXREbGdJdGVtKGhXbmQsIElEQ19JTlRFUkxFQVZFRVZFUlkpLCBiSXNJbnRlcmxlYXZlZCk7CiAgICBicmVhazsKICBjYXNlIFdNX0NPTU1BTkQ6CiAgICBzd2l0Y2ggKExPV09SRCh3UGFyYW0pKSB7CiAgICBjYXNlIElET0s6CiAgICAgIC8qIGdldCBkYXRhIGZyb20gY29udHJvbHMgYW5kIHNhdmUgdGhlbSAqLwogICAgICBkd0ludGVybGVhdmUgICA9IEdldERsZ0l0ZW1JbnQoaFduZCwgSURDX0lOVEVSTEVBVkVFVkVSWSwgTlVMTCwgMCk7CiAgICAgIGJJc0ludGVybGVhdmVkID0gSXNEbGdCdXR0b25DaGVja2VkKGhXbmQsIElEQ19JTlRFUkxFQVZFKTsKICAgICAgZm9yIChuID0gMDsgbiA8IFNhdmVPcHRzLm5TdHJlYW1zOyBuKyspIHsKCWlmIChTYXZlT3B0cy5wcE9wdGlvbnNbbl0gIT0gTlVMTCkgewoJICBpZiAoYklzSW50ZXJsZWF2ZWQpIHsKCSAgICBTYXZlT3B0cy5wcE9wdGlvbnNbbl0tPmR3RmxhZ3MgfD0gQVZJQ09NUFJFU1NGX0lOVEVSTEVBVkU7CgkgICAgU2F2ZU9wdHMucHBPcHRpb25zW25dLT5kd0ludGVybGVhdmVFdmVyeSA9IGR3SW50ZXJsZWF2ZTsKCSAgfSBlbHNlCgkgICAgU2F2ZU9wdHMucHBPcHRpb25zW25dLT5kd0ZsYWdzICY9IH5BVklDT01QUkVTU0ZfSU5URVJMRUFWRTsKCX0KICAgICAgfQogICAgICAvKiBmYWxsIHRocm91Z2ggKi8KICAgIGNhc2UgSURDQU5DRUw6CiAgICAgIEVuZERpYWxvZyhoV25kLCBMT1dPUkQod1BhcmFtKSA9PSBJRE9LKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIElEQ19JTlRFUkxFQVZFOgogICAgICBFbmFibGVXaW5kb3coR2V0RGxnSXRlbShoV25kLCBJRENfSU5URVJMRUFWRUVWRVJZKSwKCQkgICBJc0RsZ0J1dHRvbkNoZWNrZWQoaFduZCwgSURDX0lOVEVSTEVBVkUpKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIElEQ19TVFJFQU06CiAgICAgIGlmIChISVdPUkQod1BhcmFtKSA9PSBDQk5fU0VMQ0hBTkdFKSB7CgkvKiB1cGRhdGUgY29udHJvbCBlbGVtZW50cyAqLwoJQVZJU2F2ZU9wdGlvbnNVcGRhdGUoaFduZCk7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICBjYXNlIElEQ19PUFRJT05TOgogICAgICBBVklTYXZlT3B0aW9uc0ZtdENob29zZShoV25kKTsKICAgICAgYnJlYWs7CiAgICB9OwogICAgcmV0dXJuIFRSVUU7CiAgfTsKCiAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVNhdmVPcHRpb25zCQkoQVZJRklMMzIuQCkKICovCkJPT0wgV0lOQVBJIEFWSVNhdmVPcHRpb25zKEhXTkQgaFduZCwgVUlOVCB1RmxhZ3MsIElOVCBuU3RyZWFtcywKCQkJICAgUEFWSVNUUkVBTSAqcHBhdmksIExQQVZJQ09NUFJFU1NPUFRJT05TICpwcE9wdGlvbnMpCnsKICBMUEFWSUNPTVBSRVNTT1BUSU9OUyBwU2F2ZWRPcHRpb25zID0gTlVMTDsKICBJTlQgcmV0LCBuOwoKICBUUkFDRSgiKCVwLDB4JVgsJWQsJXAsJXApXG4iLCBoV25kLCB1RmxhZ3MsIG5TdHJlYW1zLAoJcHBhdmksIHBwT3B0aW9ucyk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoblN0cmVhbXMgPD0gMCB8fCBwcGF2aSA9PSBOVUxMIHx8IHBwT3B0aW9ucyA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogc2F2ZSBvcHRpb25zIGluIGNhc2UgdGhlIHVzZXIgcHJlc3NlcyBjYW5jZWwgKi8KICBpZiAocHBPcHRpb25zICE9IE5VTEwgJiYgblN0cmVhbXMgPiAxKSB7CiAgICBwU2F2ZWRPcHRpb25zID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIG5TdHJlYW1zICogc2l6ZW9mKEFWSUNPTVBSRVNTT1BUSU9OUykpOwogICAgaWYgKHBTYXZlZE9wdGlvbnMgPT0gTlVMTCkKICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGZvciAobiA9IDA7IG4gPCBuU3RyZWFtczsgbisrKSB7CiAgICAgIGlmIChwcE9wdGlvbnNbbl0gIT0gTlVMTCkKCW1lbWNweShwU2F2ZWRPcHRpb25zICsgbiwgcHBPcHRpb25zW25dLCBzaXplb2YoQVZJQ09NUFJFU1NPUFRJT05TKSk7CiAgICB9CiAgfQoKICBTYXZlT3B0cy51RmxhZ3MgICAgPSB1RmxhZ3M7CiAgU2F2ZU9wdHMublN0cmVhbXMgID0gblN0cmVhbXM7CiAgU2F2ZU9wdHMucHBhdmlzICAgID0gcHBhdmk7CiAgU2F2ZU9wdHMucHBPcHRpb25zID0gcHBPcHRpb25zOwoKICByZXQgPSBEaWFsb2dCb3hXKEFWSUZJTEVfaE1vZHVsZSwgTUFLRUlOVFJFU09VUkNFVyhJRERfU0FWRU9QVElPTlMpLAoJCSAgIGhXbmQsIEFWSVNhdmVPcHRpb25zRGxnUHJvYyk7CgogIGlmIChyZXQgPT0gLTEpCiAgICByZXQgPSBGQUxTRTsKCiAgLyogcmVzdG9yZSBvcHRpb25zIHdoZW4gdXNlciBwcmVzc2VkIGNhbmNlbCAqLwogIGlmIChwU2F2ZWRPcHRpb25zICE9IE5VTEwpIHsKICAgIGlmIChyZXQgPT0gRkFMU0UpIHsKICAgICAgZm9yIChuID0gMDsgbiA8IG5TdHJlYW1zOyBuKyspIHsKCWlmIChwcE9wdGlvbnNbbl0gIT0gTlVMTCkKCSAgbWVtY3B5KHBwT3B0aW9uc1tuXSwgcFNhdmVkT3B0aW9ucyArIG4sIHNpemVvZihBVklDT01QUkVTU09QVElPTlMpKTsKICAgICAgfQogICAgfQogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcFNhdmVkT3B0aW9ucyk7CiAgfQoKICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVNhdmVPcHRpb25zRnJlZQkoQVZJRklMMzIuQCkKICoJCUFWSVNhdmVPcHRpb25zRnJlZQkoQVZJRklMRS4xMjQpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTYXZlT3B0aW9uc0ZyZWUoSU5UIG5TdHJlYW1zLExQQVZJQ09NUFJFU1NPUFRJT05TKnBwT3B0aW9ucykKewogIFRSQUNFKCIoJWQsJXApXG4iLCBuU3RyZWFtcywgcHBPcHRpb25zKTsKCiAgaWYgKG5TdHJlYW1zIDwgMCB8fCBwcE9wdGlvbnMgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIGZvciAoblN0cmVhbXMtLTsgblN0cmVhbXMgPj0gMDsgblN0cmVhbXMtLSkgewogICAgaWYgKHBwT3B0aW9uc1tuU3RyZWFtc10gIT0gTlVMTCkgewogICAgICBwcE9wdGlvbnNbblN0cmVhbXNdLT5kd0ZsYWdzICY9IH5BVklDT01QUkVTU0ZfVkFMSUQ7CgogICAgICBpZiAocHBPcHRpb25zW25TdHJlYW1zXS0+bHBQYXJtcyAhPSBOVUxMKSB7CglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwcE9wdGlvbnNbblN0cmVhbXNdLT5scFBhcm1zKTsKCXBwT3B0aW9uc1tuU3RyZWFtc10tPmxwUGFybXMgPSBOVUxMOwoJcHBPcHRpb25zW25TdHJlYW1zXS0+Y2JQYXJtcyA9IDA7CiAgICAgIH0KICAgICAgaWYgKHBwT3B0aW9uc1tuU3RyZWFtc10tPmxwRm9ybWF0ICE9IE5VTEwpIHsKCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBwT3B0aW9uc1tuU3RyZWFtc10tPmxwRm9ybWF0KTsKCXBwT3B0aW9uc1tuU3RyZWFtc10tPmxwRm9ybWF0ID0gTlVMTDsKCXBwT3B0aW9uc1tuU3RyZWFtc10tPmNiRm9ybWF0ID0gMDsKICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTYXZlVkEJCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU2F2ZVZBKExQQ1NUUiBzekZpbGUsIENMU0lEICpwY2xzaWRIYW5kbGVyLAoJCQkgQVZJU0FWRUNBTExCQUNLIGxwZm5DYWxsYmFjaywgaW50IG5TdHJlYW0sCgkJCSBQQVZJU1RSRUFNICpwcGF2aSwgTFBBVklDT01QUkVTU09QVElPTlMgKnBscE9wdGlvbnMpCnsKICBMUFdTVFIgIHdzekZpbGUgPSBOVUxMOwogIEhSRVNVTFQgaHI7CiAgaW50ICAgICBsZW47CgogIFRSQUNFKCIlcywlcCwlcCwlZCwlcCwlcClcbiIsIGRlYnVnc3RyX2Eoc3pGaWxlKSwgcGNsc2lkSGFuZGxlciwKCWxwZm5DYWxsYmFjaywgblN0cmVhbSwgcHBhdmksIHBscE9wdGlvbnMpOwoKICBpZiAoc3pGaWxlID09IE5VTEwgfHwgcHBhdmkgPT0gTlVMTCB8fCBwbHBPcHRpb25zID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBjb252ZXJ0IEFTQ0lJIHN0cmluZyB0byBVbmljb2RlIGFuZCBjYWxsIFVuaWNvZGUgZnVuY3Rpb24gKi8KICBsZW4gPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgc3pGaWxlLCAtMSwgTlVMTCwgMCk7CiAgaWYgKGxlbiA8PSAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgd3N6RmlsZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4gKiBzaXplb2YoV0NIQVIpKTsKICBpZiAod3N6RmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzekZpbGUsIC0xLCB3c3pGaWxlLCBsZW4pOwoKICBociA9IEFWSVNhdmVWVyh3c3pGaWxlLCBwY2xzaWRIYW5kbGVyLCBscGZuQ2FsbGJhY2ssCgkJIG5TdHJlYW0sIHBwYXZpLCBwbHBPcHRpb25zKTsKCiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgd3N6RmlsZSk7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGSUxFX0FWSVNhdmVEZWZhdWx0Q2FsbGJhY2sJKGludGVybmFsKQogKi8Kc3RhdGljIEJPT0wgV0lOQVBJIEFWSUZJTEVfQVZJU2F2ZURlZmF1bHRDYWxsYmFjayhJTlQgcHJvZ3Jlc3MpCnsKICBUUkFDRSgiKCVkKVxuIiwgcHJvZ3Jlc3MpOwoKICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU2F2ZVZXCQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVNhdmVWVyhMUENXU1RSIHN6RmlsZSwgQ0xTSUQgKnBjbHNpZEhhbmRsZXIsCgkJCSBBVklTQVZFQ0FMTEJBQ0sgbHBmbkNhbGxiYWNrLCBpbnQgblN0cmVhbXMsCgkJCSBQQVZJU1RSRUFNICpwcGF2aSwgTFBBVklDT01QUkVTU09QVElPTlMgKnBscE9wdGlvbnMpCnsKICBMT05HICAgICAgICAgICBsU3RhcnRbTUFYX0FWSVNUUkVBTVNdOwogIFBBVklTVFJFQU0gICAgIHBPdXRTdHJlYW1zW01BWF9BVklTVFJFQU1TXTsKICBQQVZJU1RSRUFNICAgICBwSW5TdHJlYW1zW01BWF9BVklTVFJFQU1TXTsKICBBVklGSUxFSU5GT1cgICBmSW5mbzsKICBBVklTVFJFQU1JTkZPVyBzSW5mbzsKCiAgUEFWSUZJTEUgICAgICAgcGZpbGUgPSBOVUxMOyAvKiB0aGUgb3V0cHV0IEFWSSBmaWxlICovCiAgTE9ORyAgICAgICAgICAgbEZpcnN0VmlkZW8gPSAtMTsKICBpbnQgICAgICAgICAgICBjdXJTdHJlYW07CgogIC8qIGZvciBpbnRlcmxlYXZpbmcgLi4uICovCiAgRFdPUkQgICAgICAgICAgZHdJbnRlcmxlYXZlID0gMDsgLyogaW50ZXJsZWF2ZSByYXRlICovCiAgRFdPUkQgICAgICAgICAgZHdGaWxlSW5pdGlhbEZyYW1lczsKICBMT05HICAgICAgICAgICBsRmlsZUxlbmd0aDsKICBMT05HICAgICAgICAgICBsU2FtcGxlSW5jOwoKICAvKiBmb3IgcmVhZGluZy93cml0aW5nIHRoZSBkYXRhIC4uLiAqLwogIExQVk9JRCAgICAgICAgIGxwQnVmZmVyID0gTlVMTDsKICBMT05HICAgICAgICAgICBjYkJ1ZmZlcjsgICAgICAgIC8qIHJlYWwgc2l6ZSBvZiBscEJ1ZmZlciAqLwogIExPTkcgICAgICAgICAgIGxCdWZmZXJTaXplOyAgICAgLyogbmVlZGVkIGJ5dGVzIGZvciBmb3JtYXQocyksIGV0Yy4gKi8KICBMT05HICAgICAgICAgICBsUmVhZEJ5dGVzOwogIExPTkcgICAgICAgICAgIGxSZWFkU2FtcGxlczsKICBIUkVTVUxUICAgICAgICBocmVzOwoKICBUUkFDRSgiKCVzLCVwLCVwLCVkLCVwLCVwKVxuIiwgZGVidWdzdHJfdyhzekZpbGUpLCBwY2xzaWRIYW5kbGVyLAoJbHBmbkNhbGxiYWNrLCBuU3RyZWFtcywgcHBhdmksIHBscE9wdGlvbnMpOwoKICBpZiAoc3pGaWxlID09IE5VTEwgfHwgcHBhdmkgPT0gTlVMTCB8fCBwbHBPcHRpb25zID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChuU3RyZWFtcyA+PSBNQVhfQVZJU1RSRUFNUykgewogICAgV0FSTigiQ2FuJ3Qgd3JpdGUgQVZJIHdpdGggJWQgc3RyZWFtcyBvbmx5IHN1cHBvcnRzICVkIC0tIGNoYW5nZSBNQVhfQVZJU1RSRUFNUyFcbiIsIG5TdHJlYW1zLCBNQVhfQVZJU1RSRUFNUyk7CiAgICByZXR1cm4gQVZJRVJSX0lOVEVSTkFMOwogIH0KCiAgaWYgKGxwZm5DYWxsYmFjayA9PSBOVUxMKQogICAgbHBmbkNhbGxiYWNrID0gQVZJRklMRV9BVklTYXZlRGVmYXVsdENhbGxiYWNrOwoKICAvKiBjbGVhciBsb2NhbCB2YXJpYWJsZShzKSAqLwogIGZvciAoY3VyU3RyZWFtID0gMDsgY3VyU3RyZWFtIDwgblN0cmVhbXM7IGN1clN0cmVhbSsrKSB7CiAgICBwSW5TdHJlYW1zW2N1clN0cmVhbV0gID0gTlVMTDsKICAgIHBPdXRTdHJlYW1zW2N1clN0cmVhbV0gPSBOVUxMOwogIH0KCiAgLyogb3BlbiBvdXRwdXQgQVZJIGZpbGUgKGNyZWF0ZSBpdCBpZiBpdCBkb2Vzbid0IGV4aXN0KSAqLwogIGhyZXMgPSBBVklGaWxlT3BlblcoJnBmaWxlLCBzekZpbGUsIE9GX0NSRUFURXxPRl9TSEFSRV9FWENMVVNJVkV8T0ZfV1JJVEUsCgkJICAgICAgcGNsc2lkSGFuZGxlcik7CiAgaWYgKEZBSUxFRChocmVzKSkKICAgIHJldHVybiBocmVzOwogIEFWSUZpbGVJbmZvVyhwZmlsZSwgJmZJbmZvLCBzaXplb2YoZkluZm8pKTsgLyogZm9yIGR3Q2FwcyAqLwoKICAvKiBpbml0aWFsaXplIG91ciBkYXRhIHN0cnVjdHVyZXMgcGFydCAxICovCiAgZm9yIChjdXJTdHJlYW0gPSAwOyBjdXJTdHJlYW0gPCBuU3RyZWFtczsgY3VyU3RyZWFtKyspIHsKICAgIFBBVklTVFJFQU0gcEN1clN0cmVhbSA9IHBwYXZpW2N1clN0cmVhbV07CgogICAgaHJlcyA9IEFWSVN0cmVhbUluZm9XKHBDdXJTdHJlYW0sICZzSW5mbywgc2l6ZW9mKHNJbmZvKSk7CiAgICBpZiAoRkFJTEVEKGhyZXMpKQogICAgICBnb3RvIGVycm9yOwoKICAgIC8qIHNlYXJjaCBmaXJzdCB2aWRlbyBzdHJlYW0gYW5kIGNoZWNrIGZvciBpbnRlcmxlYXZpbmcgKi8KICAgIGlmIChzSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTykgewogICAgICAvKiByZW1lbWJlciBmaXJzdCB2aWRlbyBzdHJlYW0gLS0gbmVlZGVkIGZvciBpbnRlcmxlYXZpbmcgKi8KICAgICAgaWYgKGxGaXJzdFZpZGVvIDwgMCkKCWxGaXJzdFZpZGVvID0gY3VyU3RyZWFtOwogICAgfSBlbHNlIGlmICghZHdJbnRlcmxlYXZlICYmIHBscE9wdGlvbnMgIT0gTlVMTCkgewogICAgICAvKiBjaGVjayBpZiBhbnkgbm9uLXZpZGVvIHN0cmVhbSB3YW50cyB0byBiZSBpbnRlcmxlYXZlZCAqLwogICAgICBXQVJOKCJvcHRpb25zLmZsYWdzPTB4JVggb3B0aW9ucy5kd0ludGVybGVhdmU9JXVcbiIscGxwT3B0aW9uc1tjdXJTdHJlYW1dLT5kd0ZsYWdzLHBscE9wdGlvbnNbY3VyU3RyZWFtXS0+ZHdJbnRlcmxlYXZlRXZlcnkpOwogICAgICBpZiAocGxwT3B0aW9uc1tjdXJTdHJlYW1dICE9IE5VTEwgJiYKCSAgcGxwT3B0aW9uc1tjdXJTdHJlYW1dLT5kd0ZsYWdzICYgQVZJQ09NUFJFU1NGX0lOVEVSTEVBVkUpCglkd0ludGVybGVhdmUgPSBwbHBPcHRpb25zW2N1clN0cmVhbV0tPmR3SW50ZXJsZWF2ZUV2ZXJ5OwogICAgfQoKICAgIC8qIGNyZWF0ZSBkZS0vY29tcHJlc3NlZCBzdHJlYW0gaW50ZXJmYWNlIGlmIG5lZWRlZCAqLwogICAgcEluU3RyZWFtc1tjdXJTdHJlYW1dID0gTlVMTDsKICAgIGlmIChwbHBPcHRpb25zICE9IE5VTEwgJiYgcGxwT3B0aW9uc1tjdXJTdHJlYW1dICE9IE5VTEwpIHsKICAgICAgaWYgKHBscE9wdGlvbnNbY3VyU3RyZWFtXS0+ZmNjSGFuZGxlciB8fAoJICBwbHBPcHRpb25zW2N1clN0cmVhbV0tPmxwRm9ybWF0ICE9IE5VTEwpIHsKCURXT1JEIGR3S2V5U2F2ZSA9IHBscE9wdGlvbnNbY3VyU3RyZWFtXS0+ZHdLZXlGcmFtZUV2ZXJ5OwoKCWlmIChmSW5mby5kd0NhcHMgJiBBVklGSUxFQ0FQU19BTExLRVlGUkFNRVMpCgkgIHBscE9wdGlvbnNbY3VyU3RyZWFtXS0+ZHdLZXlGcmFtZUV2ZXJ5ID0gMTsKCglocmVzID0gQVZJTWFrZUNvbXByZXNzZWRTdHJlYW0oJnBJblN0cmVhbXNbY3VyU3RyZWFtXSwgcEN1clN0cmVhbSwKCQkJCSAgICAgICBwbHBPcHRpb25zW2N1clN0cmVhbV0sIE5VTEwpOwoJcGxwT3B0aW9uc1tjdXJTdHJlYW1dLT5kd0tleUZyYW1lRXZlcnkgPSBkd0tleVNhdmU7CglpZiAoRkFJTEVEKGhyZXMpIHx8IHBJblN0cmVhbXNbY3VyU3RyZWFtXSA9PSBOVUxMKSB7CgkgIHBJblN0cmVhbXNbY3VyU3RyZWFtXSA9IE5VTEw7CgkgIGdvdG8gZXJyb3I7Cgl9CgoJLyogdGVzdCBzdHJlYW0gaW50ZXJmYWNlIGFuZCB1cGRhdGUgc3RyZWFtLWluZm8gKi8KCWhyZXMgPSBBVklTdHJlYW1JbmZvVyhwSW5TdHJlYW1zW2N1clN0cmVhbV0sICZzSW5mbywgc2l6ZW9mKHNJbmZvKSk7CglpZiAoRkFJTEVEKGhyZXMpKQoJICBnb3RvIGVycm9yOwogICAgICB9CiAgICB9CgogICAgLyogbm93IGhhbmRsZSBzdHJlYW1zIHdoaWNoIHdpbGwgb25seSBiZSBjb3BpZWQgKi8KICAgIGlmIChwSW5TdHJlYW1zW2N1clN0cmVhbV0gPT0gTlVMTCkgewogICAgICBwQ3VyU3RyZWFtID0gcEluU3RyZWFtc1tjdXJTdHJlYW1dID0gcHBhdmlbY3VyU3RyZWFtXTsKICAgICAgQVZJU3RyZWFtQWRkUmVmKHBDdXJTdHJlYW0pOwogICAgfSBlbHNlCiAgICAgIHBDdXJTdHJlYW0gPSBwSW5TdHJlYW1zW2N1clN0cmVhbV07CgogICAgbFN0YXJ0W2N1clN0cmVhbV0gPSBzSW5mby5kd1N0YXJ0OwogIH0gLyogZm9yIGFsbCBzdHJlYW1zICovCgogIC8qIGNoZWNrIHRoYXQgZmlyc3QgdmlkZW8gc3RyZWFtIGlzIHRoZSBmaXJzdCBzdHJlYW0gKi8KICBpZiAobEZpcnN0VmlkZW8gPiAwKSB7CiAgICBQQVZJU1RSRUFNIHBUbXAgPSBwSW5TdHJlYW1zW2xGaXJzdFZpZGVvXTsKICAgIExPTkcgbFRtcCA9IGxTdGFydFtsRmlyc3RWaWRlb107CgogICAgcEluU3RyZWFtc1tsRmlyc3RWaWRlb10gPSBwSW5TdHJlYW1zWzBdOwogICAgcEluU3RyZWFtc1swXSA9IHBUbXA7CiAgICBsU3RhcnRbbEZpcnN0VmlkZW9dID0gbFN0YXJ0WzBdOwogICAgbFN0YXJ0WzBdID0gbFRtcDsKICAgIGxGaXJzdFZpZGVvID0gMDsKICB9CgogIC8qIGFsbG9jYXRlIGJ1ZmZlciBmb3IgZm9ybWF0cywgZGF0YSwgZXRjLiBvZiBhbiBpbml0aWFsIHNpemUgb2YgNjQga0J5dGVzKi8KICBjYkJ1ZmZlciA9IDB4MDAwMTAwMDA7CiAgbHBCdWZmZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2JCdWZmZXIpOwogIGlmIChscEJ1ZmZlciA9PSBOVUxMKSB7CiAgICBocmVzID0gQVZJRVJSX01FTU9SWTsKICAgIGdvdG8gZXJyb3I7CiAgfQoKICBBVklTdHJlYW1JbmZvVyhwSW5TdHJlYW1zWzBdLCAmc0luZm8sIHNpemVvZihzSW5mbykpOwogIGxGaWxlTGVuZ3RoID0gc0luZm8uZHdMZW5ndGg7CiAgZHdGaWxlSW5pdGlhbEZyYW1lcyA9IDA7CiAgaWYgKGxGaXJzdFZpZGVvID49IDApIHsKICAgIC8qIGNoZWNrIGZvciBjb3JyZWN0IHZlcnNpb24gb2YgdGhlIGZvcm1hdAogICAgICogIC0tIG5lZWQgYXQgbGVhc3QgQklUTUFQSU5GT0hFQURFUiBvciBuZXdlcgogICAgICovCiAgICBsU2FtcGxlSW5jID0gMTsKICAgIGxCdWZmZXJTaXplID0gY2JCdWZmZXI7CiAgICBocmVzID0gQVZJU3RyZWFtUmVhZEZvcm1hdChwSW5TdHJlYW1zW2xGaXJzdFZpZGVvXSwgQVZJU3RyZWFtU3RhcnQocEluU3RyZWFtc1tsRmlyc3RWaWRlb10pLCBscEJ1ZmZlciwgJmxCdWZmZXJTaXplKTsKICAgIGlmIChsQnVmZmVyU2l6ZSA8IChMT05HKXNpemVvZihCSVRNQVBJTkZPSEVBREVSKSkKICAgICAgaHJlcyA9IEFWSUVSUl9JTlRFUk5BTDsKICAgIGlmIChGQUlMRUQoaHJlcykpCiAgICAgIGdvdG8gZXJyb3I7CiAgfSBlbHNlIC8qIHVzZSBvbmUgc2Vjb25kIGJsb2NrcyBmb3IgaW50ZXJsZWF2aW5nIGlmIG5vIHZpZGVvIHByZXNlbnQgKi8KICAgIGxTYW1wbGVJbmMgPSBBVklTdHJlYW1UaW1lVG9TYW1wbGUocEluU3RyZWFtc1swXSwgMTAwMDAwMCk7CgogIC8qIGNyZWF0ZSBvdXRwdXQgc3RyZWFtcyAqLwogIGZvciAoY3VyU3RyZWFtID0gMDsgY3VyU3RyZWFtIDwgblN0cmVhbXM7IGN1clN0cmVhbSsrKSB7CiAgICBBVklTdHJlYW1JbmZvVyhwSW5TdHJlYW1zW2N1clN0cmVhbV0sICZzSW5mbywgc2l6ZW9mKHNJbmZvKSk7CgogICAgc0luZm8uZHdJbml0aWFsRnJhbWVzID0gMDsKICAgIGlmIChkd0ludGVybGVhdmUgIT0gMCAmJiBjdXJTdHJlYW0gPiAwICYmIHNJbmZvLmZjY1R5cGUgIT0gc3RyZWFtdHlwZVZJREVPKSB7CiAgICAgIC8qIDc1MCBtcyBpbml0aWFsIGZyYW1lcyBmb3Igbm9uLXZpZGVvIHN0cmVhbXMgKi8KICAgICAgc0luZm8uZHdJbml0aWFsRnJhbWVzID0gQVZJU3RyZWFtVGltZVRvU2FtcGxlKHBJblN0cmVhbXNbMF0sIDc1MCk7CiAgICB9CgogICAgaHJlcyA9IEFWSUZpbGVDcmVhdGVTdHJlYW1XKHBmaWxlLCAmcE91dFN0cmVhbXNbY3VyU3RyZWFtXSwgJnNJbmZvKTsKICAgIGlmIChwT3V0U3RyZWFtc1tjdXJTdHJlYW1dICE9IE5VTEwgJiYgU1VDQ0VFREVEKGhyZXMpKSB7CiAgICAgIC8qIGNvcHkgaW5pdGlhbCBmb3JtYXQgZm9yIHRoaXMgc3RyZWFtICovCiAgICAgIGxCdWZmZXJTaXplID0gY2JCdWZmZXI7CiAgICAgIGhyZXMgPSBBVklTdHJlYW1SZWFkRm9ybWF0KHBJblN0cmVhbXNbY3VyU3RyZWFtXSwgc0luZm8uZHdTdGFydCwKCQkJCSBscEJ1ZmZlciwgJmxCdWZmZXJTaXplKTsKICAgICAgaWYgKEZBSUxFRChocmVzKSkKCWdvdG8gZXJyb3I7CiAgICAgIGhyZXMgPSBBVklTdHJlYW1TZXRGb3JtYXQocE91dFN0cmVhbXNbY3VyU3RyZWFtXSwgMCwgbHBCdWZmZXIsIGxCdWZmZXJTaXplKTsKICAgICAgaWYgKEZBSUxFRChocmVzKSkKCWdvdG8gZXJyb3I7CgogICAgICAvKiB0cnkgdG8gY29weSBzdHJlYW0gaGFuZGxlciBkYXRhICovCiAgICAgIGxCdWZmZXJTaXplID0gY2JCdWZmZXI7CiAgICAgIGhyZXMgPSBBVklTdHJlYW1SZWFkRGF0YShwSW5TdHJlYW1zW2N1clN0cmVhbV0sIGNraWRTVFJFQU1IQU5ETEVSREFUQSwKCQkJICAgICAgIGxwQnVmZmVyLCAmbEJ1ZmZlclNpemUpOwogICAgICBpZiAoU1VDQ0VFREVEKGhyZXMpICYmIGxCdWZmZXJTaXplID4gMCkgewoJaHJlcyA9IEFWSVN0cmVhbVdyaXRlRGF0YShwT3V0U3RyZWFtc1tjdXJTdHJlYW1dLGNraWRTVFJFQU1IQU5ETEVSREFUQSwKCQkJCSAgbHBCdWZmZXIsIGxCdWZmZXJTaXplKTsKCWlmIChGQUlMRUQoaHJlcykpCgkgIGdvdG8gZXJyb3I7CiAgICAgIH0KCiAgICAgIGlmIChkd0ZpbGVJbml0aWFsRnJhbWVzIDwgc0luZm8uZHdJbml0aWFsRnJhbWVzKQoJZHdGaWxlSW5pdGlhbEZyYW1lcyA9IHNJbmZvLmR3SW5pdGlhbEZyYW1lczsKICAgICAgbFJlYWRCeXRlcyA9CglBVklTdHJlYW1TYW1wbGVUb1NhbXBsZShwT3V0U3RyZWFtc1swXSwgcEluU3RyZWFtc1tjdXJTdHJlYW1dLAoJCQkJc0luZm8uZHdMZW5ndGgpOwogICAgICBpZiAobEZpbGVMZW5ndGggPCBsUmVhZEJ5dGVzKQoJbEZpbGVMZW5ndGggPSBsUmVhZEJ5dGVzOwogICAgfSBlbHNlIHsKICAgICAgLyogY3JlYXRpb24gb2YgZGUtL2NvbXByZXNzaW9uIHN0cmVhbSBpbnRlcmZhY2UgZmFpbGVkICovCiAgICAgIFdBUk4oImNyZWF0aW9uIG9mIChkZS0pY29tcHJlc3Npb24gc3RyZWFtIGZhaWxlZCBmb3Igc3RyZWFtICVkXG4iLGN1clN0cmVhbSk7CiAgICAgIEFWSVN0cmVhbVJlbGVhc2UocEluU3RyZWFtc1tjdXJTdHJlYW1dKTsKICAgICAgaWYgKGN1clN0cmVhbSArIDEgPj0gblN0cmVhbXMpIHsKCS8qIG1vdmUgdGhlIG90aGVycyBvbmUgdXAgKi8KCVBBVklTVFJFQU0gKnBwYXMgPSAmcEluU3RyZWFtc1tjdXJTdHJlYW1dOwoJaW50ICAgICAgICAgICAgbiA9IG5TdHJlYW1zIC0gKGN1clN0cmVhbSArIDEpOwoKCWRvIHsKCSAgKnBwYXMgPSBwSW5TdHJlYW1zW2N1clN0cmVhbSArIDFdOwoJfSB3aGlsZSAoLS1uKTsKICAgICAgfQogICAgICBuU3RyZWFtcy0tOwogICAgICBjdXJTdHJlYW0tLTsKICAgIH0KICB9IC8qIGNyZWF0ZSBvdXRwdXQgc3RyZWFtcyBmb3IgYWxsIGlucHV0IHN0cmVhbXMgKi8KCiAgLyogaGF2ZSB3ZSBzdGlsbCBzb21ldGhpbmcgdG8gd3JpdGUsIG9yIGxvc3QgZXZlcnl0aGluZz8gKi8KICBpZiAoblN0cmVhbXMgPD0gMCkKICAgIGdvdG8gZXJyb3I7CgogIGlmIChkd0ludGVybGVhdmUpIHsKICAgIExPTkcgbEN1ckZyYW1lID0gLWR3RmlsZUluaXRpYWxGcmFtZXM7CgogICAgLyogaW50ZXJsZWF2ZWQgZmlsZSAqLwogICAgaWYgKGR3SW50ZXJsZWF2ZSA9PSAxKQogICAgICBBVklGaWxlRW5kUmVjb3JkKHBmaWxlKTsKCiAgICBmb3IgKDsgbEN1ckZyYW1lIDwgbEZpbGVMZW5ndGg7IGxDdXJGcmFtZSArPSBsU2FtcGxlSW5jKSB7CiAgICAgIGZvciAoY3VyU3RyZWFtID0gMDsgY3VyU3RyZWFtIDwgblN0cmVhbXM7IGN1clN0cmVhbSsrKSB7CglMT05HIGxMYXN0U2FtcGxlOwoKCWhyZXMgPSBBVklTdHJlYW1JbmZvVyhwT3V0U3RyZWFtc1tjdXJTdHJlYW1dLCAmc0luZm8sIHNpemVvZihzSW5mbykpOwoJaWYgKEZBSUxFRChocmVzKSkKCSAgZ290byBlcnJvcjsKCgkvKiBpbml0aWFsIGZyYW1lcyBwaGFzZSBhdCB0aGUgZW5kIGZvciB0aGlzIHN0cmVhbT8gKi8KCWlmICgtKExPTkcpc0luZm8uZHdJbml0aWFsRnJhbWVzID4gbEN1ckZyYW1lKQoJICBjb250aW51ZTsKCglpZiAoKGxGaWxlTGVuZ3RoIC0gbFNhbXBsZUluYykgPD0gbEN1ckZyYW1lKSB7CgkgIGxMYXN0U2FtcGxlID0gQVZJU3RyZWFtTGVuZ3RoKHBJblN0cmVhbXNbY3VyU3RyZWFtXSk7CgkgIGxGaXJzdFZpZGVvID0gbExhc3RTYW1wbGUgKyBBVklTdHJlYW1TdGFydChwSW5TdHJlYW1zW2N1clN0cmVhbV0pOwoJfSBlbHNlIHsKCSAgaWYgKGN1clN0cmVhbSAhPSAwKSB7CgkgICAgbEZpcnN0VmlkZW8gPQoJICAgICAgQVZJU3RyZWFtU2FtcGxlVG9TYW1wbGUocEluU3RyZWFtc1tjdXJTdHJlYW1dLCBwSW5TdHJlYW1zWzBdLAoJCQkJICAgICAgKHNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPID8gCgkJCQkgICAgICAgKExPTkcpZHdJbnRlcmxlYXZlIDogbFNhbXBsZUluYykgKwoJCQkJICAgICAgc0luZm8uZHdJbml0aWFsRnJhbWVzICsgbEN1ckZyYW1lKTsKCSAgfSBlbHNlCgkgICAgbEZpcnN0VmlkZW8gPSBsU2FtcGxlSW5jICsgKHNJbmZvLmR3SW5pdGlhbEZyYW1lcyArIGxDdXJGcmFtZSk7CgoJICBsTGFzdFNhbXBsZSA9IEFWSVN0cmVhbUVuZChwSW5TdHJlYW1zW2N1clN0cmVhbV0pOwoJICBpZiAobExhc3RTYW1wbGUgPD0gbEZpcnN0VmlkZW8pCgkgICAgbEZpcnN0VmlkZW8gPSBsTGFzdFNhbXBsZTsKCX0KCgkvKiBjb3B5IG5lZWRlZCBzYW1wbGVzIG5vdyAqLwoJV0FSTigiY29weSBmcm9tIHN0cmVhbSAlZCBzYW1wbGVzICVkIHRvICVkLi4uXG4iLGN1clN0cmVhbSwKCSAgICAgIGxTdGFydFtjdXJTdHJlYW1dLGxGaXJzdFZpZGVvKTsKCXdoaWxlIChsRmlyc3RWaWRlbyA+IGxTdGFydFtjdXJTdHJlYW1dKSB7CgkgIERXT1JEIGZsYWdzID0gMDsKCgkgIC8qIGNvcHkgZm9ybWF0IGluIGNhc2UgaXQgY2FuIGNoYW5nZSAqLwoJICBsQnVmZmVyU2l6ZSA9IGNiQnVmZmVyOwoJICBocmVzID0gQVZJU3RyZWFtUmVhZEZvcm1hdChwSW5TdHJlYW1zW2N1clN0cmVhbV0sIGxTdGFydFtjdXJTdHJlYW1dLAoJCQkJICAgICBscEJ1ZmZlciwgJmxCdWZmZXJTaXplKTsKCSAgaWYgKEZBSUxFRChocmVzKSkKCSAgICBnb3RvIGVycm9yOwoJICBBVklTdHJlYW1TZXRGb3JtYXQocE91dFN0cmVhbXNbY3VyU3RyZWFtXSwgbFN0YXJ0W2N1clN0cmVhbV0sCgkJCSAgICAgbHBCdWZmZXIsIGxCdWZmZXJTaXplKTsKCgkgIC8qIHRyeSB0byByZWFkIGRhdGEgdW50aWwgd2UgZ290IGl0LCBvciBlcnJvciAqLwoJICBkbyB7CgkgICAgaHJlcyA9IEFWSVN0cmVhbVJlYWQocEluU3RyZWFtc1tjdXJTdHJlYW1dLCBsU3RhcnRbY3VyU3RyZWFtXSwKCQkJCSBsRmlyc3RWaWRlbyAtIGxTdGFydFtjdXJTdHJlYW1dLCBscEJ1ZmZlciwKCQkJCSBjYkJ1ZmZlciwgJmxSZWFkQnl0ZXMsICZsUmVhZFNhbXBsZXMpOwoJICB9IHdoaWxlICgoaHJlcyA9PSBBVklFUlJfQlVGRkVSVE9PU01BTEwpICYmCgkJICAgKGxwQnVmZmVyID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbHBCdWZmZXIsIGNiQnVmZmVyICo9IDIpKSAhPSBOVUxMKTsKCSAgaWYgKGxwQnVmZmVyID09IE5VTEwpCgkgICAgaHJlcyA9IEFWSUVSUl9NRU1PUlk7CgkgIGlmIChGQUlMRUQoaHJlcykpCgkgICAgZ290byBlcnJvcjsKCgkgIGlmIChBVklTdHJlYW1Jc0tleUZyYW1lKHBJblN0cmVhbXNbY3VyU3RyZWFtXSwgKExPTkcpc0luZm8uZHdTdGFydCkpCgkgICAgZmxhZ3MgPSBBVklJRl9LRVlGUkFNRTsKCSAgaHJlcyA9IEFWSVN0cmVhbVdyaXRlKHBPdXRTdHJlYW1zW2N1clN0cmVhbV0sIC0xLCBsUmVhZFNhbXBsZXMsCgkJCQlscEJ1ZmZlciwgbFJlYWRCeXRlcywgZmxhZ3MsIE5VTEwsIE5VTEwpOwoJICBpZiAoRkFJTEVEKGhyZXMpKQoJICAgIGdvdG8gZXJyb3I7CgoJICBsU3RhcnRbY3VyU3RyZWFtXSArPSBsUmVhZFNhbXBsZXM7Cgl9CglsU3RhcnRbY3VyU3RyZWFtXSA9IGxGaXJzdFZpZGVvOwogICAgICB9IC8qIHN0cmVhbSBieSBzdHJlYW0gKi8KCiAgICAgIC8qIG5lZWQgdG8gY2xvc2UgdGhpcyBibG9jaz8gKi8KICAgICAgaWYgKGR3SW50ZXJsZWF2ZSA9PSAxKSB7CglocmVzID0gQVZJRmlsZUVuZFJlY29yZChwZmlsZSk7CglpZiAoRkFJTEVEKGhyZXMpKQoJICBicmVhazsKICAgICAgfQoKICAgICAgLyogc2hvdyBwcm9ncmVzcyAqLwogICAgICBpZiAobHBmbkNhbGxiYWNrKE11bERpdihkd0ZpbGVJbml0aWFsRnJhbWVzICsgbEN1ckZyYW1lLCAxMDAsCgkJCSAgICAgIGR3RmlsZUluaXRpYWxGcmFtZXMgKyBsRmlsZUxlbmd0aCkpKSB7CglocmVzID0gQVZJRVJSX1VTRVJBQk9SVDsKCWJyZWFrOwogICAgICB9CiAgICB9IC8qIGNvcHkgZnJhbWUgYnkgZnJhbWUgKi8KICB9IGVsc2UgewogICAgLyogbm9uLWludGVybGVhdmVkIGZpbGUgKi8KCiAgICBmb3IgKGN1clN0cmVhbSA9IDA7IGN1clN0cmVhbSA8IG5TdHJlYW1zOyBjdXJTdHJlYW0rKykgewogICAgICAvKiBzaG93IHByb2dyZXNzICovCiAgICAgIGlmIChscGZuQ2FsbGJhY2soTXVsRGl2KGN1clN0cmVhbSwgMTAwLCBuU3RyZWFtcykpKSB7CglocmVzID0gQVZJRVJSX1VTRVJBQk9SVDsKCWdvdG8gZXJyb3I7CiAgICAgIH0KCiAgICAgIEFWSVN0cmVhbUluZm9XKHBJblN0cmVhbXNbY3VyU3RyZWFtXSwgJnNJbmZvLCBzaXplb2Yoc0luZm8pKTsKCiAgICAgIGlmIChzSW5mby5kd1NhbXBsZVNpemUgIT0gMCkgewoJLyogc2FtcGxlLWJhc2VkIGRhdGEgbGlrZSBhdWRpbyAqLwoJd2hpbGUgKHNJbmZvLmR3U3RhcnQgPCBzSW5mby5kd0xlbmd0aCkgewoJICBMT05HIGxTYW1wbGVzID0gY2JCdWZmZXIgLyBzSW5mby5kd1NhbXBsZVNpemU7CgoJICAvKiBjb3B5IGZvcm1hdCBpbiBjYXNlIGl0IGNhbiBjaGFuZ2UgKi8KCSAgbEJ1ZmZlclNpemUgPSBjYkJ1ZmZlcjsKCSAgaHJlcyA9IEFWSVN0cmVhbVJlYWRGb3JtYXQocEluU3RyZWFtc1tjdXJTdHJlYW1dLCBzSW5mby5kd1N0YXJ0LAoJCQkJICAgICBscEJ1ZmZlciwgJmxCdWZmZXJTaXplKTsKCSAgaWYgKEZBSUxFRChocmVzKSkKCSAgICBnb3RvIGVycm9yOwoJICBBVklTdHJlYW1TZXRGb3JtYXQocE91dFN0cmVhbXNbY3VyU3RyZWFtXSwgc0luZm8uZHdTdGFydCwKCQkJICAgICBscEJ1ZmZlciwgbEJ1ZmZlclNpemUpOwoKCSAgLyogbGltaXQgdG8gc3RyZWFtIGJvdW5kYXJpZXMgKi8KCSAgaWYgKGxTYW1wbGVzICE9IChMT05HKShzSW5mby5kd0xlbmd0aCAtIHNJbmZvLmR3U3RhcnQpKQoJICAgIGxTYW1wbGVzID0gc0luZm8uZHdMZW5ndGggLSBzSW5mby5kd1N0YXJ0OwoKCSAgLyogbm93IHRyeSB0byByZWFkIHVudGlsIHdlIGdldCBpdCwgb3IgYW4gZXJyb3Igb2NjdXJzICovCgkgIGRvIHsKCSAgICBsUmVhZEJ5dGVzICAgPSBjYkJ1ZmZlcjsKCSAgICBsUmVhZFNhbXBsZXMgPSAwOwoJICAgIGhyZXMgPSBBVklTdHJlYW1SZWFkKHBJblN0cmVhbXNbY3VyU3RyZWFtXSxzSW5mby5kd1N0YXJ0LGxTYW1wbGVzLAoJCQkJIGxwQnVmZmVyLGNiQnVmZmVyLCZsUmVhZEJ5dGVzLCZsUmVhZFNhbXBsZXMpOwoJICB9IHdoaWxlICgoaHJlcyA9PSBBVklFUlJfQlVGRkVSVE9PU01BTEwpICYmCgkJICAgKGxwQnVmZmVyID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbHBCdWZmZXIsIGNiQnVmZmVyICo9IDIpKSAhPSBOVUxMKTsKCSAgaWYgKGxwQnVmZmVyID09IE5VTEwpCgkgICAgaHJlcyA9IEFWSUVSUl9NRU1PUlk7CgkgIGlmIChGQUlMRUQoaHJlcykpCgkgICAgZ290byBlcnJvcjsKCSAgaWYgKGxSZWFkU2FtcGxlcyAhPSAwKSB7CgkgICAgc0luZm8uZHdTdGFydCArPSBsUmVhZFNhbXBsZXM7CgkgICAgaHJlcyA9IEFWSVN0cmVhbVdyaXRlKHBPdXRTdHJlYW1zW2N1clN0cmVhbV0sIC0xLCBsUmVhZFNhbXBsZXMsCgkJCQkgIGxwQnVmZmVyLCBsUmVhZEJ5dGVzLCAwLCBOVUxMICwgTlVMTCk7CgkgICAgaWYgKEZBSUxFRChocmVzKSkKCSAgICAgIGdvdG8gZXJyb3I7CgoJICAgIC8qIHNob3cgcHJvZ3Jlc3MgKi8KCSAgICBpZiAobHBmbkNhbGxiYWNrKE11bERpdihzSW5mby5kd1N0YXJ0LDEwMCxuU3RyZWFtcypzSW5mby5kd0xlbmd0aCkrCgkJCSAgICAgTXVsRGl2KGN1clN0cmVhbSwgMTAwLCBuU3RyZWFtcykpKSB7CgkgICAgICBocmVzID0gQVZJRVJSX1VTRVJBQk9SVDsKCSAgICAgIGdvdG8gZXJyb3I7CgkgICAgfQoJICB9IGVsc2UgewoJICAgIGlmICgoc0luZm8uZHdMZW5ndGggLSBzSW5mby5kd1N0YXJ0KSAhPSAxKSB7CgkgICAgICBocmVzID0gQVZJRVJSX0ZJTEVSRUFEOwoJICAgICAgZ290byBlcnJvcjsKCSAgICB9CgkgIH0KCX0KICAgICAgfSBlbHNlIHsKCS8qIGJsb2NrLWJhc2VkIGRhdGEgbGlrZSB2aWRlbyAqLwoJZm9yICg7IHNJbmZvLmR3U3RhcnQgPCBzSW5mby5kd0xlbmd0aDsgc0luZm8uZHdTdGFydCsrKSB7CgkgIERXT1JEIGZsYWdzID0gMDsKCgkgIC8qIGNvcHkgZm9ybWF0IGluIGNhc2UgaXQgY2FuIGNoYW5nZSAqLwoJICBsQnVmZmVyU2l6ZSA9IGNiQnVmZmVyOwoJICBocmVzID0gQVZJU3RyZWFtUmVhZEZvcm1hdChwSW5TdHJlYW1zW2N1clN0cmVhbV0sIHNJbmZvLmR3U3RhcnQsCgkJCQkgICAgIGxwQnVmZmVyLCAmbEJ1ZmZlclNpemUpOwoJICBpZiAoRkFJTEVEKGhyZXMpKQoJICAgIGdvdG8gZXJyb3I7CgkgIEFWSVN0cmVhbVNldEZvcm1hdChwT3V0U3RyZWFtc1tjdXJTdHJlYW1dLCBzSW5mby5kd1N0YXJ0LAoJCQkgICAgIGxwQnVmZmVyLCBsQnVmZmVyU2l6ZSk7CgoJICAvKiB0cnkgdG8gcmVhZCBibG9jayBhbmQgcmVzaXplIGJ1ZmZlciBpZiBuZWNlc3NhcnkgKi8KCSAgZG8gewoJICAgIGxSZWFkU2FtcGxlcyA9IDA7CgkgICAgbFJlYWRCeXRlcyAgID0gY2JCdWZmZXI7CgkgICAgaHJlcyA9IEFWSVN0cmVhbVJlYWQocEluU3RyZWFtc1tjdXJTdHJlYW1dLCBzSW5mby5kd1N0YXJ0LCAxLAoJCQkJIGxwQnVmZmVyLCBjYkJ1ZmZlciwmbFJlYWRCeXRlcywmbFJlYWRTYW1wbGVzKTsKCSAgfSB3aGlsZSAoKGhyZXMgPT0gQVZJRVJSX0JVRkZFUlRPT1NNQUxMKSAmJgoJCSAgIChscEJ1ZmZlciA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxwQnVmZmVyLCBjYkJ1ZmZlciAqPSAyKSkgIT0gTlVMTCk7CgkgIGlmIChscEJ1ZmZlciA9PSBOVUxMKQoJICAgIGhyZXMgPSBBVklFUlJfTUVNT1JZOwoJICBpZiAoRkFJTEVEKGhyZXMpKQoJICAgIGdvdG8gZXJyb3I7CgkgIGlmIChsUmVhZFNhbXBsZXMgIT0gMSkgewoJICAgIGhyZXMgPSBBVklFUlJfRklMRVJFQUQ7CgkgICAgZ290byBlcnJvcjsKCSAgfQoKCSAgaWYgKEFWSVN0cmVhbUlzS2V5RnJhbWUocEluU3RyZWFtc1tjdXJTdHJlYW1dLCAoTE9ORylzSW5mby5kd1N0YXJ0KSkKCSAgICBmbGFncyA9IEFWSUlGX0tFWUZSQU1FOwoJICBocmVzID0gQVZJU3RyZWFtV3JpdGUocE91dFN0cmVhbXNbY3VyU3RyZWFtXSwgLTEsIGxSZWFkU2FtcGxlcywKCQkJCWxwQnVmZmVyLCBsUmVhZEJ5dGVzLCBmbGFncywgTlVMTCwgTlVMTCk7CgkgIGlmIChGQUlMRUQoaHJlcykpCgkgICAgZ290byBlcnJvcjsKCgkgIC8qIHNob3cgcHJvZ3Jlc3MgKi8KCSAgaWYgKGxwZm5DYWxsYmFjayhNdWxEaXYoc0luZm8uZHdTdGFydCwxMDAsblN0cmVhbXMqc0luZm8uZHdMZW5ndGgpKwoJCQkgICBNdWxEaXYoY3VyU3RyZWFtLCAxMDAsIG5TdHJlYW1zKSkpIHsKCSAgICBocmVzID0gQVZJRVJSX1VTRVJBQk9SVDsKCSAgICBnb3RvIGVycm9yOwoJICB9Cgl9IC8qIGNvcHkgYWxsIGJsb2NrcyAqLwogICAgICB9CiAgICB9IC8qIGNvcHkgZGF0YSBzdHJlYW0gYnkgc3RyZWFtICovCiAgfQoKIGVycm9yOgogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGxwQnVmZmVyKTsKICBpZiAocGZpbGUgIT0gTlVMTCkgewogICAgZm9yIChjdXJTdHJlYW0gPSAwOyBjdXJTdHJlYW0gPCBuU3RyZWFtczsgY3VyU3RyZWFtKyspIHsKICAgICAgaWYgKHBPdXRTdHJlYW1zW2N1clN0cmVhbV0gIT0gTlVMTCkKCUFWSVN0cmVhbVJlbGVhc2UocE91dFN0cmVhbXNbY3VyU3RyZWFtXSk7CiAgICAgIGlmIChwSW5TdHJlYW1zW2N1clN0cmVhbV0gIT0gTlVMTCkKCUFWSVN0cmVhbVJlbGVhc2UocEluU3RyZWFtc1tjdXJTdHJlYW1dKTsKICAgIH0KCiAgICBBVklGaWxlUmVsZWFzZShwZmlsZSk7CiAgfQoKICByZXR1cm4gaHJlczsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlDcmVhdGVFZGl0YWJsZVN0cmVhbQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIENyZWF0ZUVkaXRhYmxlU3RyZWFtKFBBVklTVFJFQU0gKnBwRWRpdGFibGUsIFBBVklTVFJFQU0gcFNvdXJjZSkKewogIElBVklFZGl0U3RyZWFtICpwRWRpdCA9IE5VTEw7CiAgSFJFU1VMVAkgIGhyOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgcHBFZGl0YWJsZSwgcFNvdXJjZSk7CgogIGlmIChwcEVkaXRhYmxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqcHBFZGl0YWJsZSA9IE5VTEw7CgogIGlmIChwU291cmNlICE9IE5VTEwpIHsKICAgIGhyID0gSUFWSVN0cmVhbV9RdWVyeUludGVyZmFjZShwU291cmNlLCAmSUlEX0lBVklFZGl0U3RyZWFtLAoJCQkJICAgKExQVk9JRCopJnBFZGl0KTsKICAgIGlmIChTVUNDRUVERUQoaHIpICYmIHBFZGl0ICE9IE5VTEwpIHsKICAgICAgaHIgPSBJQVZJRWRpdFN0cmVhbV9DbG9uZShwRWRpdCwgcHBFZGl0YWJsZSk7CiAgICAgIElBVklFZGl0U3RyZWFtX1JlbGVhc2UocEVkaXQpOwoKICAgICAgcmV0dXJuIGhyOwogICAgfQogIH0KCiAgLyogbmVlZCBvd24gaW1wbGVtZW50YXRpb24gb2YgSUFWSUVkaXRTdHJlYW0gKi8KICBwRWRpdCA9IEFWSUZJTEVfQ3JlYXRlRWRpdFN0cmVhbShwU291cmNlKTsKICBpZiAocEVkaXQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBociA9IElBVklFZGl0U3RyZWFtX1F1ZXJ5SW50ZXJmYWNlKHBFZGl0LCAmSUlEX0lBVklTdHJlYW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBWT0lEKilwcEVkaXRhYmxlKTsKICBJQVZJRWRpdFN0cmVhbV9SZWxlYXNlKHBFZGl0KTsKCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUVkaXRTdHJlYW1DbG9uZQkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBFZGl0U3RyZWFtQ2xvbmUoUEFWSVNUUkVBTSBwU3RyZWFtLCBQQVZJU1RSRUFNICpwcFJlc3VsdCkKewogIFBBVklFRElUU1RSRUFNIHBFZGl0ID0gTlVMTDsKICBIUkVTVUxUICAgICAgICBocjsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIHBTdHJlYW0sIHBwUmVzdWx0KTsKCiAgaWYgKHBTdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmIChwcFJlc3VsdCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKnBwUmVzdWx0ID0gTlVMTDsKCiAgaHIgPSBJQVZJU3RyZWFtX1F1ZXJ5SW50ZXJmYWNlKHBTdHJlYW0sICZJSURfSUFWSUVkaXRTdHJlYW0sKExQVk9JRCopJnBFZGl0KTsKICBpZiAoU1VDQ0VFREVEKGhyKSAmJiBwRWRpdCAhPSBOVUxMKSB7CiAgICBociA9IElBVklFZGl0U3RyZWFtX0Nsb25lKHBFZGl0LCBwcFJlc3VsdCk7CgogICAgSUFWSUVkaXRTdHJlYW1fUmVsZWFzZShwRWRpdCk7CiAgfSBlbHNlCiAgICBociA9IEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUVkaXRTdHJlYW1Db3B5CQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEVkaXRTdHJlYW1Db3B5KFBBVklTVFJFQU0gcFN0cmVhbSwgTE9ORyAqcGxTdGFydCwKCQkJICAgICAgTE9ORyAqcGxMZW5ndGgsIFBBVklTVFJFQU0gKnBwUmVzdWx0KQp7CiAgUEFWSUVESVRTVFJFQU0gcEVkaXQgPSBOVUxMOwogIEhSRVNVTFQgICAgICAgIGhyOwoKICBUUkFDRSgiKCVwLCVwLCVwLCVwKVxuIiwgcFN0cmVhbSwgcGxTdGFydCwgcGxMZW5ndGgsIHBwUmVzdWx0KTsKCiAgaWYgKHBTdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmIChwbFN0YXJ0ID09IE5VTEwgfHwgcGxMZW5ndGggPT0gTlVMTCB8fCBwcFJlc3VsdCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKnBwUmVzdWx0ID0gTlVMTDsKCiAgaHIgPSBJQVZJU3RyZWFtX1F1ZXJ5SW50ZXJmYWNlKHBTdHJlYW0sICZJSURfSUFWSUVkaXRTdHJlYW0sKExQVk9JRCopJnBFZGl0KTsKICBpZiAoU1VDQ0VFREVEKGhyKSAmJiBwRWRpdCAhPSBOVUxMKSB7CiAgICBociA9IElBVklFZGl0U3RyZWFtX0NvcHkocEVkaXQsIHBsU3RhcnQsIHBsTGVuZ3RoLCBwcFJlc3VsdCk7CgogICAgSUFWSUVkaXRTdHJlYW1fUmVsZWFzZShwRWRpdCk7CiAgfSBlbHNlCiAgICBociA9IEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUVkaXRTdHJlYW1DdXQJCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgRWRpdFN0cmVhbUN1dChQQVZJU1RSRUFNIHBTdHJlYW0sIExPTkcgKnBsU3RhcnQsCgkJCSAgICAgTE9ORyAqcGxMZW5ndGgsIFBBVklTVFJFQU0gKnBwUmVzdWx0KQp7CiAgUEFWSUVESVRTVFJFQU0gcEVkaXQgPSBOVUxMOwogIEhSRVNVTFQgICAgICAgIGhyOwoKICBUUkFDRSgiKCVwLCVwLCVwLCVwKVxuIiwgcFN0cmVhbSwgcGxTdGFydCwgcGxMZW5ndGgsIHBwUmVzdWx0KTsKCiAgaWYgKHBwUmVzdWx0ICE9IE5VTEwpCiAgICAqcHBSZXN1bHQgPSBOVUxMOwogIGlmIChwU3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKICBpZiAocGxTdGFydCA9PSBOVUxMIHx8IHBsTGVuZ3RoID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBociA9IElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UocFN0cmVhbSwgJklJRF9JQVZJRWRpdFN0cmVhbSwoTFBWT0lEKikmcEVkaXQpOwogIGlmIChTVUNDRUVERUQoaHIpICYmIHBFZGl0ICE9IE5VTEwpIHsKICAgIGhyID0gSUFWSUVkaXRTdHJlYW1fQ3V0KHBFZGl0LCBwbFN0YXJ0LCBwbExlbmd0aCwgcHBSZXN1bHQpOwoKICAgIElBVklFZGl0U3RyZWFtX1JlbGVhc2UocEVkaXQpOwogIH0gZWxzZQogICAgaHIgPSBBVklFUlJfVU5TVVBQT1JURUQ7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlFZGl0U3RyZWFtUGFzdGUJCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgRWRpdFN0cmVhbVBhc3RlKFBBVklTVFJFQU0gcERlc3QsIExPTkcgKnBsU3RhcnQsIExPTkcgKnBsTGVuZ3RoLAoJCQkgICAgICAgUEFWSVNUUkVBTSBwU291cmNlLCBMT05HIGxTdGFydCwgTE9ORyBsRW5kKQp7CiAgUEFWSUVESVRTVFJFQU0gcEVkaXQgPSBOVUxMOwogIEhSRVNVTFQgICAgICAgIGhyOwoKICBUUkFDRSgiKCVwLCVwLCVwLCVwLCVkLCVkKVxuIiwgcERlc3QsIHBsU3RhcnQsIHBsTGVuZ3RoLAoJcFNvdXJjZSwgbFN0YXJ0LCBsRW5kKTsKCiAgaWYgKHBEZXN0ID09IE5VTEwgfHwgcFNvdXJjZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CiAgaWYgKHBsU3RhcnQgPT0gTlVMTCB8fCBwbExlbmd0aCA9PSBOVUxMIHx8IGxTdGFydCA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBociA9IElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UocERlc3QsICZJSURfSUFWSUVkaXRTdHJlYW0sKExQVk9JRCopJnBFZGl0KTsKICBpZiAoU1VDQ0VFREVEKGhyKSAmJiBwRWRpdCAhPSBOVUxMKSB7CiAgICBociA9IElBVklFZGl0U3RyZWFtX1Bhc3RlKHBFZGl0LCBwbFN0YXJ0LCBwbExlbmd0aCwgcFNvdXJjZSwgbFN0YXJ0LCBsRW5kKTsKCiAgICBJQVZJRWRpdFN0cmVhbV9SZWxlYXNlKHBFZGl0KTsKICB9IGVsc2UKICAgIGhyID0gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRWRpdFN0cmVhbVNldEluZm9BCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgRWRpdFN0cmVhbVNldEluZm9BKFBBVklTVFJFQU0gcHN0cmVhbSwgTFBBVklTVFJFQU1JTkZPQSBhc2ksCgkJCQkgIExPTkcgc2l6ZSkKewogIEFWSVNUUkVBTUlORk9XIGFzaXc7CgogIFRSQUNFKCIoJXAsJXAsJWQpXG4iLCBwc3RyZWFtLCBhc2ksIHNpemUpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CiAgaWYgKChEV09SRClzaXplIDwgc2l6ZW9mKEFWSVNUUkVBTUlORk9BKSkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgbWVtY3B5KCZhc2l3LCBhc2ksIHNpemVvZihhc2l3KSAtIHNpemVvZihhc2l3LnN6TmFtZSkpOwogIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBhc2ktPnN6TmFtZSwgLTEsCgkJICAgICAgYXNpdy5zek5hbWUsIHNpemVvZihhc2l3LnN6TmFtZSkvc2l6ZW9mKFdDSEFSKSk7CgogIHJldHVybiBFZGl0U3RyZWFtU2V0SW5mb1cocHN0cmVhbSwgJmFzaXcsIHNpemVvZihhc2l3KSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRWRpdFN0cmVhbVNldEluZm9XCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgRWRpdFN0cmVhbVNldEluZm9XKFBBVklTVFJFQU0gcHN0cmVhbSwgTFBBVklTVFJFQU1JTkZPVyBhc2ksCgkJCQkgIExPTkcgc2l6ZSkKewogIFBBVklFRElUU1RSRUFNIHBFZGl0ID0gTlVMTDsKICBIUkVTVUxUICAgICAgICBocjsKCiAgVFJBQ0UoIiglcCwlcCwlZClcbiIsIHBzdHJlYW0sIGFzaSwgc2l6ZSk7CgogIGhyID0gSUFWSVN0cmVhbV9RdWVyeUludGVyZmFjZShwc3RyZWFtLCAmSUlEX0lBVklFZGl0U3RyZWFtLChMUFZPSUQqKSZwRWRpdCk7CiAgaWYgKFNVQ0NFRURFRChocikgJiYgcEVkaXQgIT0gTlVMTCkgewogICAgaHIgPSBJQVZJRWRpdFN0cmVhbV9TZXRJbmZvKHBFZGl0LCBhc2ksIHNpemUpOwoKICAgIElBVklFZGl0U3RyZWFtX1JlbGVhc2UocEVkaXQpOwogIH0gZWxzZQogICAgaHIgPSBBVklFUlJfVU5TVVBQT1JURUQ7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlFZGl0U3RyZWFtU2V0TmFtZUEJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBFZGl0U3RyZWFtU2V0TmFtZUEoUEFWSVNUUkVBTSBwc3RyZWFtLCBMUENTVFIgc3pOYW1lKQp7CiAgQVZJU1RSRUFNSU5GT0EgYXNpYTsKICBIUkVTVUxUICAgICAgICBocmVzOwoKICBUUkFDRSgiKCVwLCVzKVxuIiwgcHN0cmVhbSwgZGVidWdzdHJfYShzek5hbWUpKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmIChzek5hbWUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIGhyZXMgPSBBVklTdHJlYW1JbmZvQShwc3RyZWFtLCAmYXNpYSwgc2l6ZW9mKGFzaWEpKTsKICBpZiAoRkFJTEVEKGhyZXMpKQogICAgcmV0dXJuIGhyZXM7CgogIG1lbXNldChhc2lhLnN6TmFtZSwgMCwgc2l6ZW9mKGFzaWEuc3pOYW1lKSk7CiAgbHN0cmNweW5BKGFzaWEuc3pOYW1lLCBzek5hbWUsIHNpemVvZihhc2lhLnN6TmFtZSkvc2l6ZW9mKGFzaWEuc3pOYW1lWzBdKSk7CgogIHJldHVybiBFZGl0U3RyZWFtU2V0SW5mb0EocHN0cmVhbSwgJmFzaWEsIHNpemVvZihhc2lhKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRWRpdFN0cmVhbVNldE5hbWVXCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgRWRpdFN0cmVhbVNldE5hbWVXKFBBVklTVFJFQU0gcHN0cmVhbSwgTFBDV1NUUiBzek5hbWUpCnsKICBBVklTVFJFQU1JTkZPVyBhc2l3OwogIEhSRVNVTFQgICAgICAgIGhyZXM7CgogIFRSQUNFKCIoJXAsJXMpXG4iLCBwc3RyZWFtLCBkZWJ1Z3N0cl93KHN6TmFtZSkpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CiAgaWYgKHN6TmFtZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgaHJlcyA9IElBVklTdHJlYW1fSW5mbyhwc3RyZWFtLCAmYXNpdywgc2l6ZW9mKGFzaXcpKTsKICBpZiAoRkFJTEVEKGhyZXMpKQogICAgcmV0dXJuIGhyZXM7CgogIG1lbXNldChhc2l3LnN6TmFtZSwgMCwgc2l6ZW9mKGFzaXcuc3pOYW1lKSk7CiAgbHN0cmNweW5XKGFzaXcuc3pOYW1lLCBzek5hbWUsIHNpemVvZihhc2l3LnN6TmFtZSkvc2l6ZW9mKGFzaXcuc3pOYW1lWzBdKSk7CgogIHJldHVybiBFZGl0U3RyZWFtU2V0SW5mb1cocHN0cmVhbSwgJmFzaXcsIHNpemVvZihhc2l3KSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJQ2xlYXJDbGlwYm9hcmQJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklDbGVhckNsaXBib2FyZCh2b2lkKQp7CiAgVFJBQ0UoIigpXG4iKTsKCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsgLyogT2xlU2V0Q2xpcGJvYXJkKE5VTEwpOyAqLwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUdldEZyb21DbGlwYm9hcmQJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklHZXRGcm9tQ2xpcGJvYXJkKFBBVklGSUxFICpwcGZpbGUpCnsKICBGSVhNRSgiKCVwKSwgc3R1YiFcbiIsIHBwZmlsZSk7CgogICpwcGZpbGUgPSBOVUxMOwoKICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBBVklNYWtlU3RyZWFtRnJvbUNsaXBib2FyZCAoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSU1ha2VTdHJlYW1Gcm9tQ2xpcGJvYXJkKFVJTlQgY2ZGb3JtYXQsIEhBTkRMRSBoR2xvYmFsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQQVZJU1RSRUFNICogcHBzdHJlYW0pCnsKICBGSVhNRSgiKDB4JTA4eCwlcCwlcCksIHN0dWIhXG4iLCBjZkZvcm1hdCwgaEdsb2JhbCwgcHBzdHJlYW0pOwoKICBpZiAocHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVB1dEZpbGVPbkNsaXBib2FyZAkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVB1dEZpbGVPbkNsaXBib2FyZChQQVZJRklMRSBwZmlsZSkKewogIEZJWE1FKCIoJXApLCBzdHViIVxuIiwgcGZpbGUpOwoKICBpZiAocGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwp9CgpIUkVTVUxUIFdJTkFQSVYgQVZJU2F2ZUEoTFBDU1RSIHN6RmlsZSwgQ0xTSUQgKiBwY2xzaWRIYW5kbGVyLCBBVklTQVZFQ0FMTEJBQ0sgbHBmbkNhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICBpbnQgblN0cmVhbXMsIFBBVklTVFJFQU0gcGF2aSwgTFBBVklDT01QUkVTU09QVElPTlMgbHBPcHRpb25zLCAuLi4pCnsKICAgIEZJWE1FKCIoJXMsJXAsJXAsMHglMDh4LCVwLCVwKSwgc3R1YiFcbiIsIGRlYnVnc3RyX2Eoc3pGaWxlKSwgcGNsc2lkSGFuZGxlciwgbHBmbkNhbGxiYWNrLAogICAgICAgICAgblN0cmVhbXMsIHBhdmksIGxwT3B0aW9ucyk7CgogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKSFJFU1VMVCBXSU5BUElWIEFWSVNhdmVXKExQQ1dTVFIgc3pGaWxlLCBDTFNJRCAqIHBjbHNpZEhhbmRsZXIsIEFWSVNBVkVDQUxMQkFDSyBscGZuQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgIGludCBuU3RyZWFtcywgUEFWSVNUUkVBTSBwYXZpLCBMUEFWSUNPTVBSRVNTT1BUSU9OUyBscE9wdGlvbnMsIC4uLikKewogICAgRklYTUUoIiglcywlcCwlcCwweCUwOHgsJXAsJXApLCBzdHViIVxuIiwgZGVidWdzdHJfdyhzekZpbGUpLCBwY2xzaWRIYW5kbGVyLCBscGZuQ2FsbGJhY2ssCiAgICAgICAgICBuU3RyZWFtcywgcGF2aSwgbHBPcHRpb25zKTsKCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwp9Cg==