LyoKICoJaGFuZGxpbmcgb2YgU0hFTEwzMi5ETEwgT0xFLU9iamVjdHMKICoKICoJQ29weXJpZ2h0IDE5OTcJTWFyY3VzIE1laXNzbmVyCiAqCUNvcHlyaWdodCAxOTk4CUp1ZXJnZW4gU2NobWllZCAgPGp1ZXJnZW4uc2NobWllZEBtZXRyb25ldC5kZT4KICoKICovCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCiNpbmNsdWRlICJzaGxvYmouaCIKI2luY2x1ZGUgInNoZWxsYXBpLmgiCiNpbmNsdWRlICJzaGxndWlkLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgImRlYnVndG9vbHMuaCIKCiNpbmNsdWRlICJzaGVsbDMyX21haW4uaCIKCkRFRkFVTFRfREVCVUdfQ0hBTk5FTChzaGVsbCk7CgpEV09SRCBXSU5BUEkgU0hDTFNJREZyb21TdHJpbmdBIChMUFNUUiBjbHNpZCwgQ0xTSUQgKmlkKTsKZXh0ZXJuIElTaGVsbEZvbGRlciAqIElTaGVsbEZvbGRlcl9Db25zdHJ1Y3RvcigKCUlTaGVsbEZvbGRlciAqIHBzZiwKCUxQSVRFTUlETElTVCBwaWRsKTsKZXh0ZXJuIEhSRVNVTFQgSUZTRm9sZGVyX0NvbnN0cnVjdG9yKAoJSVVua25vd24gKiBwVW5rT3V0ZXIsCglSRUZJSUQgcmlpZCwKCUxQVk9JRCAqIHBwdik7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSENvQ3JlYXRlSW5zdGFuY2UgW1NIRUxMMzIuMTAyXQogKiAKICogTk9URVMKICogICAgIGV4cG9ydGVkIGJ5IG9yZGluYWwKICovCkxSRVNVTFQgV0lOQVBJIFNIQ29DcmVhdGVJbnN0YW5jZSgKCUxQU1RSIGFjbHNpZCwKCVJFRkNMU0lEIGNsc2lkLAoJSVVua25vd24gKiB1bmtub3dub3V0ZXIsCglSRUZJSUQgcmVmaWlkLAoJTFBWT0lEICpwcHYpCnsKCURXT1JECWhyZXM7CglJSUQJaWlkOwoJQ0xTSUQgKiBteWNsc2lkID0gKENMU0lEKiljbHNpZDsKCQoJaWYgKCFjbHNpZCkKCXsKCSAgaWYgKCFhY2xzaWQpIHJldHVybiBSRUdEQl9FX0NMQVNTTk9UUkVHOwoJICBTSENMU0lERnJvbVN0cmluZ0EoYWNsc2lkLCAmaWlkKTsKCSAgbXljbHNpZCA9ICZpaWQ7Cgl9CgoJVFJBQ0UoIiglcCxcblx0Q0xTSUQ6XHQlcywgdW5rOiVwXG5cdElJRDpcdCVzLCVwKVxuIiwKCQlhY2xzaWQsZGVidWdzdHJfZ3VpZChteWNsc2lkKSx1bmtub3dub3V0ZXIsZGVidWdzdHJfZ3VpZChyZWZpaWQpLHBwdik7CgoJaWYgSXNFcXVhbENMU0lEKG15Y2xzaWQsICZDTFNJRF9TaGVsbEZTRm9sZGVyKQoJewoJICBocmVzID0gSUZTRm9sZGVyX0NvbnN0cnVjdG9yKHVua25vd25vdXRlciwgcmVmaWlkLCBwcHYpOwoJfQoJZWxzZQoJewoJICBocmVzID0gQ29DcmVhdGVJbnN0YW5jZShteWNsc2lkLCB1bmtub3dub3V0ZXIsIENMU0NUWF9JTlBST0NfU0VSVkVSLCByZWZpaWQsIHBwdik7Cgl9CgkKCWlmKGhyZXMhPVNfT0spCgl7CgkgIEVSUigiZmFpbGVkICgweCUwOGx4KSB0byBjcmVhdGUgXG5cdENMU0lEOlx0JXNcblx0SUlEOlx0JXNcbiIsCiAgICAgICAgICAgICAgaHJlcywgZGVidWdzdHJfZ3VpZChteWNsc2lkKSwgZGVidWdzdHJfZ3VpZChyZWZpaWQpKTsKCSAgRVJSKCJjbGFzcyBub3QgZm91bmQgaW4gcmVnaXN0cnlcbiIpOwoJfQoKCVRSQUNFKCItLSBpbnN0YW5jZTogJXBcbiIsKnBwdik7CglyZXR1cm4gaHJlczsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hFTEwzMl9EbGxHZXRDbGFzc09iamVjdCAgIFtTSEVMTDMyLjEyOF0KICovCkhSRVNVTFQgV0lOQVBJIFNIRUxMMzJfRGxsR2V0Q2xhc3NPYmplY3QoUkVGQ0xTSUQgcmNsc2lkLCBSRUZJSUQgaWlkLExQVk9JRCAqcHB2KQp7CUhSRVNVTFQJaHJlcyA9IEVfT1VUT0ZNRU1PUlk7CglMUENMQVNTRkFDVE9SWSBscGNsZjsKCglUUkFDRSgiXG5cdENMU0lEOlx0JXMsXG5cdElJRDpcdCVzXG4iLGRlYnVnc3RyX2d1aWQocmNsc2lkKSxkZWJ1Z3N0cl9ndWlkKGlpZCkpOwoJCgkqcHB2ID0gTlVMTDsKCglpZihJc0VxdWFsQ0xTSUQocmNsc2lkLCAmQ0xTSURfU2hlbGxEZXNrdG9wKXx8IAoJICAgSXNFcXVhbENMU0lEKHJjbHNpZCwgJkNMU0lEX1NoZWxsTGluaykpCgl7CgkgIGxwY2xmID0gSUNsYXNzRmFjdG9yeV9Db25zdHJ1Y3RvciggcmNsc2lkICk7CgoJICBpZihscGNsZikgCgkgIHsKCSAgICBocmVzID0gSUNsYXNzRmFjdG9yeV9RdWVyeUludGVyZmFjZShscGNsZixpaWQsIHBwdik7CgkgICAgSUNsYXNzRmFjdG9yeV9SZWxlYXNlKGxwY2xmKTsKCSAgfQoJfQoJZWxzZQoJewoJICBXQVJOKCItLSBDTFNJRCBub3QgZm91bmRcbiIpOwoJICBocmVzID0gQ0xBU1NfRV9DTEFTU05PVEFWQUlMQUJMRTsKCX0KCVRSQUNFKCItLSBwb2ludGVyIHRvIGNsYXNzIGZhY3Rvcnk6ICVwXG4iLCpwcHYpOwoJcmV0dXJuIGhyZXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQ0xTSURGcm9tU3RyaW5nCQkJCVtTSEVMTDMyLjE0N10KICoKICogTk9URVMKICogICAgIGV4cG9ydGVkIGJ5IG9yZGluYWwKICovCkRXT1JEIFdJTkFQSSBTSENMU0lERnJvbVN0cmluZ0EgKExQU1RSIGNsc2lkLCBDTFNJRCAqaWQpCnsKICAgIFdDSEFSIGJ1ZmZlcls0MF07CiAgICBUUkFDRSgiKCVwKCVzKSAlcClcbiIsIGNsc2lkLCBjbHNpZCwgaWQpOwogICAgaWYgKCFNdWx0aUJ5dGVUb1dpZGVDaGFyKCBDUF9BQ1AsIDAsIGNsc2lkLCAtMSwgYnVmZmVyLCBzaXplb2YoYnVmZmVyKS9zaXplb2YoV0NIQVIpICkpCiAgICAgICAgcmV0dXJuIENPX0VfQ0xBU1NTVFJJTkc7CiAgICByZXR1cm4gQ0xTSURGcm9tU3RyaW5nKCBidWZmZXIsIGlkICk7Cn0KRFdPUkQgV0lOQVBJIFNIQ0xTSURGcm9tU3RyaW5nVyAoTFBXU1RSIGNsc2lkLCBDTFNJRCAqaWQpCnsKCVRSQUNFKCIoJXAoJXMpICVwKVxuIiwgY2xzaWQsIGRlYnVnc3RyX3coY2xzaWQpLCBpZCk7CglyZXR1cm4gQ0xTSURGcm9tU3RyaW5nKGNsc2lkLCBpZCk7IAp9CkRXT1JEIFdJTkFQSSBTSENMU0lERnJvbVN0cmluZ0FXIChMUFZPSUQgY2xzaWQsIENMU0lEICppZCkKewoJaWYgKFNIRUxMX09zSXNVbmljb2RlKCkpCgkgIHJldHVybiBTSENMU0lERnJvbVN0cmluZ1cgKGNsc2lkLCBpZCk7CglyZXR1cm4gU0hDTFNJREZyb21TdHJpbmdBIChjbHNpZCwgaWQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJCSBTSEdldE1hbGxvYwkJCVtTSEVMTDMyLjIyMF0KICogcmV0dXJucyB0aGUgaW50ZXJmYWNlIHRvIHNoZWxsIG1hbGxvYy4KICoKICogW1NESyBoZWFkZXIgd2luOTUvc2hsb2JqLmg6CiAqIGVxdWl2YWxlbnQgdG86ICAjZGVmaW5lIFNIR2V0TWFsbG9jKHBwbWVtKSAgIENvR2V0TWFsbG9jKE1FTUNUWF9UQVNLLCBwcG1lbSkKICogXQogKiBXaGF0IHdlIGFyZSBjdXJyZW50bHkgZG9pbmcgaXMgbm90IHZlcnkgd3JvbmcsIHNpbmNlIHdlIGFsd2F5cyB1c2UgdGhlIHNhbWUKICogaGVhcCAoUHJvY2Vzc0hlYXApLgogKi8KRFdPUkQgV0lOQVBJIFNIR2V0TWFsbG9jKExQTUFMTE9DICpscG1hbCkgCnsKCVRSQUNFKCIoJXApXG4iLCBscG1hbCk7CglyZXR1cm4gQ29HZXRNYWxsb2MoTUVNQ1RYX1RBU0ssIGxwbWFsKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hHZXREZXNrdG9wRm9sZGVyCQkJW1NIRUxMMzIuMjE2XQogKi8KTFBTSEVMTEZPTERFUiBwZGVza3RvcGZvbGRlcj1OVUxMOwoKRFdPUkQgV0lOQVBJIFNIR2V0RGVza3RvcEZvbGRlcihJU2hlbGxGb2xkZXIgKipwc2YpCnsKCUhSRVNVTFQJaHJlcyA9IFNfT0s7CglMUENMQVNTRkFDVE9SWSBscGNsZjsKCVRSQUNFKCIlcC0+KCVwKVxuIixwc2YsKnBzZik7CgoJKnBzZj1OVUxMOwoKCWlmICghcGRlc2t0b3Bmb2xkZXIpIAoJewoJICBscGNsZiA9IElDbGFzc0ZhY3RvcnlfQ29uc3RydWN0b3IoJkNMU0lEX1NoZWxsRGVza3RvcCk7CgkgIGlmKGxwY2xmKSAKCSAgewoJICAgIGhyZXMgPSBJQ2xhc3NGYWN0b3J5X0NyZWF0ZUluc3RhbmNlKGxwY2xmLE5VTEwsKFJFRklJRCkmSUlEX0lTaGVsbEZvbGRlciwgKHZvaWQqKSZwZGVza3RvcGZvbGRlcik7CgkgICAgSUNsYXNzRmFjdG9yeV9SZWxlYXNlKGxwY2xmKTsKCSAgfSAgCgl9CgkKCWlmIChwZGVza3RvcGZvbGRlcikgCgl7CgkgIC8qIGV2ZW4gaWYgd2UgY3JlYXRlIHRoZSBmb2xkZXIsIGFkZCBhIHJlZiBzbyB0aGUgYXBwbGljYXRpb24gY2FutHQgZGVzdHJveSB0aGUgZm9sZGVyKi8KCSAgSVNoZWxsRm9sZGVyX0FkZFJlZihwZGVza3RvcGZvbGRlcik7CgkgICpwc2YgPSBwZGVza3RvcGZvbGRlcjsKCX0KCglUUkFDRSgiLS0gJXAtPiglcClcbiIscHNmLCAqcHNmKTsKCXJldHVybiBocmVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiAgSUNsYXNzRmFjdG9yeSBJbXBsZW1lbnRhdGlvbgoqLwoKdHlwZWRlZiBzdHJ1Y3QKewogICAgLyogSVVua25vd24gZmllbGRzICovCiAgICBJQ09NX1ZGSUVMRChJQ2xhc3NGYWN0b3J5KTsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICByZWY7CiAgICBDTFNJRAkJCSpyY2xzaWQ7Cn0gSUNsYXNzRmFjdG9yeUltcGw7CgpzdGF0aWMgSUNPTV9WVEFCTEUoSUNsYXNzRmFjdG9yeSkgY2xmdnQ7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIElDbGFzc0ZhY3RvcnlfQ29uc3RydWN0b3IKICovCgpMUENMQVNTRkFDVE9SWSBJQ2xhc3NGYWN0b3J5X0NvbnN0cnVjdG9yKFJFRkNMU0lEIHJjbHNpZCkKewoJSUNsYXNzRmFjdG9yeUltcGwqIGxwY2xmOwoKCWxwY2xmPSAoSUNsYXNzRmFjdG9yeUltcGwqKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsc2l6ZW9mKElDbGFzc0ZhY3RvcnlJbXBsKSk7CglscGNsZi0+cmVmID0gMTsKCUlDT01fVlRCTChscGNsZikgPSAmY2xmdnQ7CglscGNsZi0+cmNsc2lkID0gKENMU0lEKilyY2xzaWQ7CgoJVFJBQ0UoIiglcCktPigpXG4iLGxwY2xmKTsKCUludGVybG9ja2VkSW5jcmVtZW50KCZzaGVsbDMyX09iakNvdW50KTsKCXJldHVybiAoTFBDTEFTU0ZBQ1RPUlkpbHBjbGY7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBJQ2xhc3NGYWN0b3J5X1F1ZXJ5SW50ZXJmYWNlCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNsYXNzRmFjdG9yeV9mblF1ZXJ5SW50ZXJmYWNlKAogIExQQ0xBU1NGQUNUT1JZIGlmYWNlLCBSRUZJSUQgcmlpZCwgTFBWT0lEICpwcHZPYmopCnsKCUlDT01fVEhJUyhJQ2xhc3NGYWN0b3J5SW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwKS0+KFxuXHRJSUQ6XHQlcylcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKCgkqcHB2T2JqID0gTlVMTDsKCglpZihJc0VxdWFsSUlEKHJpaWQsICZJSURfSVVua25vd24pKSAgICAgICAgICAvKklVbmtub3duKi8KCXsgKnBwdk9iaiA9IFRoaXM7IAoJfQoJZWxzZSBpZihJc0VxdWFsSUlEKHJpaWQsICZJSURfSUNsYXNzRmFjdG9yeSkpICAvKklDbGFzc0ZhY3RvcnkqLwoJeyAqcHB2T2JqID0gKElDbGFzc0ZhY3RvcnkqKVRoaXM7Cgl9ICAgCgoJaWYoKnBwdk9iaikKCXsgSVVua25vd25fQWRkUmVmKChMUFVOS05PV04pKnBwdk9iaik7ICAJCgkgIFRSQUNFKCItLSBJbnRlcmZhY2U6ICglcCktPiglcClcbiIscHB2T2JqLCpwcHZPYmopOwoJICByZXR1cm4gU19PSzsKCX0KCVRSQUNFKCItLSBJbnRlcmZhY2U6ICVzIEVfTk9JTlRFUkZBQ0VcbiIsIGRlYnVnc3RyX2d1aWQocmlpZCkpOwoJcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0gIAovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElDbGFzc0ZhY3RvcnlfQWRkUmVmCiAqLwpzdGF0aWMgVUxPTkcgV0lOQVBJIElDbGFzc0ZhY3RvcnlfZm5BZGRSZWYoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UpCnsKCUlDT01fVEhJUyhJQ2xhc3NGYWN0b3J5SW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwKS0+KGNvdW50PSVsdSlcbiIsVGhpcyxUaGlzLT5yZWYpOwoKCUludGVybG9ja2VkSW5jcmVtZW50KCZzaGVsbDMyX09iakNvdW50KTsKCXJldHVybiBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElDbGFzc0ZhY3RvcnlfUmVsZWFzZQogKi8Kc3RhdGljIFVMT05HIFdJTkFQSSBJQ2xhc3NGYWN0b3J5X2ZuUmVsZWFzZShMUENMQVNTRkFDVE9SWSBpZmFjZSkKewoJSUNPTV9USElTKElDbGFzc0ZhY3RvcnlJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXApLT4oY291bnQ9JWx1KVxuIixUaGlzLFRoaXMtPnJlZik7CgoJSW50ZXJsb2NrZWREZWNyZW1lbnQoJnNoZWxsMzJfT2JqQ291bnQpOwoJaWYgKCFJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKSkgCgl7CgkgIFRSQUNFKCItLSBkZXN0cm95aW5nIElDbGFzc0ZhY3RvcnkoJXApXG4iLFRoaXMpOwoJICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7CgkgIHJldHVybiAwOwoJfQoJcmV0dXJuIFRoaXMtPnJlZjsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElDbGFzc0ZhY3RvcnlfQ3JlYXRlSW5zdGFuY2UKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ2xhc3NGYWN0b3J5X2ZuQ3JlYXRlSW5zdGFuY2UoCiAgTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsIExQVU5LTk9XTiBwVW5rbm93biwgUkVGSUlEIHJpaWQsIExQVk9JRCAqcHBPYmplY3QpCnsKCUlDT01fVEhJUyhJQ2xhc3NGYWN0b3J5SW1wbCxpZmFjZSk7CglJVW5rbm93biAqcE9iaiA9IE5VTEw7CglIUkVTVUxUIGhyZXM7CgoJVFJBQ0UoIiVwLT4oJXAsXG5cdElJRDpcdCVzLCVwKVxuIixUaGlzLHBVbmtub3duLGRlYnVnc3RyX2d1aWQocmlpZCkscHBPYmplY3QpOwoKCSpwcE9iamVjdCA9IE5VTEw7CgkJCglpZihwVW5rbm93bikKCXsKCSAgcmV0dXJuKENMQVNTX0VfTk9BR0dSRUdBVElPTik7Cgl9CgoJaWYgKElzRXF1YWxDTFNJRChUaGlzLT5yY2xzaWQsICZDTFNJRF9TaGVsbERlc2t0b3ApKQoJewoJICBwT2JqID0gKElVbmtub3duICopSVNGX0Rlc2t0b3BfQ29uc3RydWN0b3IoKTsKCX0KCWVsc2UgaWYgKElzRXF1YWxDTFNJRChUaGlzLT5yY2xzaWQsICZDTFNJRF9TaGVsbExpbmspKQoJewoJICBwT2JqID0gKElVbmtub3duICopSVNoZWxsTGlua19Db25zdHJ1Y3RvcihGQUxTRSk7Cgl9IAoJZWxzZQoJewoJICBFUlIoInVua25vd24gSUlEIHJlcXVlc3RlZFxuXHRJSUQ6XHQlc1xuIixkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKCSAgcmV0dXJuKEVfTk9JTlRFUkZBQ0UpOwoJfQoJCglpZiAoIXBPYmopCgl7CgkgIHJldHVybihFX09VVE9GTUVNT1JZKTsKCX0KCSAKCWhyZXMgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShwT2JqLHJpaWQsIHBwT2JqZWN0KTsKCUlVbmtub3duX1JlbGVhc2UocE9iaik7CgoJVFJBQ0UoIi0tIE9iamVjdCBjcmVhdGVkOiAoJXApLT4lcFxuIixUaGlzLCpwcE9iamVjdCk7CgoJcmV0dXJuIGhyZXM7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJQ2xhc3NGYWN0b3J5X0xvY2tTZXJ2ZXIKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ2xhc3NGYWN0b3J5X2ZuTG9ja1NlcnZlcihMUENMQVNTRkFDVE9SWSBpZmFjZSwgQk9PTCBmTG9jaykKewoJSUNPTV9USElTKElDbGFzc0ZhY3RvcnlJbXBsLGlmYWNlKTsKCVRSQUNFKCIlcC0+KDB4JXgpLCBub3QgaW1wbGVtZW50ZWRcbiIsVGhpcywgZkxvY2spOwoJcmV0dXJuIEVfTk9USU1QTDsKfQoKc3RhdGljIElDT01fVlRBQkxFKElDbGFzc0ZhY3RvcnkpIGNsZnZ0ID0gCnsKICAgIElDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCiAgICBJQ2xhc3NGYWN0b3J5X2ZuUXVlcnlJbnRlcmZhY2UsCiAgICBJQ2xhc3NGYWN0b3J5X2ZuQWRkUmVmLAogIElDbGFzc0ZhY3RvcnlfZm5SZWxlYXNlLAogIElDbGFzc0ZhY3RvcnlfZm5DcmVhdGVJbnN0YW5jZSwKICBJQ2xhc3NGYWN0b3J5X2ZuTG9ja1NlcnZlcgp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERlZmF1bHQgQ2xhc3NGYWN0b3J5IEltcGxlbWVudGF0aW9uCiAqCiAqIFNIQ3JlYXRlRGVmQ2xhc3NPYmplY3QKICoKICogTk9URVMKICogIGhlbHBlciBmdW5jdGlvbiBmb3IgZGxsJ3Mgd2l0aG91dCBhIG93biBjbGFzc2ZhY3RvcnkKICogIGEgZ2VuZXJpYyBjbGFzc2ZhY3RvcnkgaXMgcmV0dXJuZWQKICogIHdoZW4gdGhlIENyZWF0ZUluc3RhbmNlIG9mIHRoZSBjZiBpcyBjYWxsZWQgdGhlIGNhbGxiYWNrIGlzIGV4ZWN1dGVkCiAqLwp0eXBlZGVmIEhSRVNVTFQgQ0FMTEJBQ0sgKCpMUEZOQ1JFQVRFSU5TVEFOQ0UpKElVbmtub3duKiBwVW5rT3V0ZXIsIFJFRklJRCByaWlkLCBMUFZPSUQqIHBwdk9iamVjdCk7Cgp0eXBlZGVmIHN0cnVjdAp7CiAgICBJQ09NX1ZGSUVMRChJQ2xhc3NGYWN0b3J5KTsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICByZWY7CiAgICBDTFNJRAkJCSpyY2xzaWQ7CiAgICBMUEZOQ1JFQVRFSU5TVEFOQ0UJCWxwZm5DSTsKICAgIGNvbnN0IElJRCAqCQkJcmlpZEluc3Q7CiAgICBVTE9ORyAqCQkJcGNSZWZEbGw7IC8qIHBvaW50ZXIgdG8gcmVmY291bnRlciBpbiBleHRlcm5hbCBkbGwgKHVncnJyLi4uKSAqLwp9IElEZWZDbEZJbXBsOwoKc3RhdGljIElDT01fVlRBQkxFKElDbGFzc0ZhY3RvcnkpIGRjbGZ2dDsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgSURlZkNsRl9mbkNvbnN0cnVjdG9yCiAqLwoKSUNsYXNzRmFjdG9yeSAqIElEZWZDbEZfZm5Db25zdHJ1Y3RvcihMUEZOQ1JFQVRFSU5TVEFOQ0UgbHBmbkNJLCBQTE9ORyBwY1JlZkRsbCwgUkVGSUlEIHJpaWRJbnN0KQp7CglJRGVmQ2xGSW1wbCogbHBjbGY7CgoJbHBjbGYgPSAoSURlZkNsRkltcGwqKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsc2l6ZW9mKElEZWZDbEZJbXBsKSk7CglscGNsZi0+cmVmID0gMTsKCUlDT01fVlRCTChscGNsZikgPSAmZGNsZnZ0OwoJbHBjbGYtPmxwZm5DSSA9IGxwZm5DSTsKCWxwY2xmLT5wY1JlZkRsbCA9IHBjUmVmRGxsOwoKCWlmIChwY1JlZkRsbCkgSW50ZXJsb2NrZWRJbmNyZW1lbnQocGNSZWZEbGwpOwoJbHBjbGYtPnJpaWRJbnN0ID0gcmlpZEluc3Q7CgoJVFJBQ0UoIiglcClcblx0SUlEOlx0JXNcbiIsbHBjbGYsIGRlYnVnc3RyX2d1aWQocmlpZEluc3QpKTsKCUludGVybG9ja2VkSW5jcmVtZW50KCZzaGVsbDMyX09iakNvdW50KTsKCXJldHVybiAoTFBDTEFTU0ZBQ1RPUlkpbHBjbGY7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBJRGVmQ2xGX2ZuUXVlcnlJbnRlcmZhY2UKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGVmQ2xGX2ZuUXVlcnlJbnRlcmZhY2UoCiAgTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsIFJFRklJRCByaWlkLCBMUFZPSUQgKnBwdk9iaikKewoJSUNPTV9USElTKElEZWZDbEZJbXBsLGlmYWNlKTsKCglUUkFDRSgiKCVwKS0+KFxuXHRJSUQ6XHQlcylcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKCgkqcHB2T2JqID0gTlVMTDsKCglpZihJc0VxdWFsSUlEKHJpaWQsICZJSURfSVVua25vd24pKSAgICAgICAgICAvKklVbmtub3duKi8KCXsgKnBwdk9iaiA9IFRoaXM7IAoJfQoJZWxzZSBpZihJc0VxdWFsSUlEKHJpaWQsICZJSURfSUNsYXNzRmFjdG9yeSkpICAvKklDbGFzc0ZhY3RvcnkqLwoJeyAqcHB2T2JqID0gKElDbGFzc0ZhY3RvcnkqKVRoaXM7Cgl9ICAgCgoJaWYoKnBwdk9iaikKCXsgSVVua25vd25fQWRkUmVmKChMUFVOS05PV04pKnBwdk9iaik7ICAJCgkgIFRSQUNFKCItLSBJbnRlcmZhY2U6ICglcCktPiglcClcbiIscHB2T2JqLCpwcHZPYmopOwoJICByZXR1cm4gU19PSzsKCX0KCVRSQUNFKCItLSBJbnRlcmZhY2U6ICVzIEVfTk9JTlRFUkZBQ0VcbiIsIGRlYnVnc3RyX2d1aWQocmlpZCkpOwoJcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0gIAovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEZWZDbEZfZm5BZGRSZWYKICovCnN0YXRpYyBVTE9ORyBXSU5BUEkgSURlZkNsRl9mbkFkZFJlZihMUENMQVNTRkFDVE9SWSBpZmFjZSkKewoJSUNPTV9USElTKElEZWZDbEZJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXApLT4oY291bnQ9JWx1KVxuIixUaGlzLFRoaXMtPnJlZik7CgoJSW50ZXJsb2NrZWRJbmNyZW1lbnQoJnNoZWxsMzJfT2JqQ291bnQpOwoJcmV0dXJuIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWYpOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURlZkNsRl9mblJlbGVhc2UKICovCnN0YXRpYyBVTE9ORyBXSU5BUEkgSURlZkNsRl9mblJlbGVhc2UoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UpCnsKCUlDT01fVEhJUyhJRGVmQ2xGSW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwKS0+KGNvdW50PSVsdSlcbiIsVGhpcyxUaGlzLT5yZWYpOwoKCUludGVybG9ja2VkRGVjcmVtZW50KCZzaGVsbDMyX09iakNvdW50KTsKCglpZiAoIUludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpKSAKCXsgCgkgIGlmIChUaGlzLT5wY1JlZkRsbCkgSW50ZXJsb2NrZWREZWNyZW1lbnQoVGhpcy0+cGNSZWZEbGwpOwoKCSAgVFJBQ0UoIi0tIGRlc3Ryb3lpbmcgSUNsYXNzRmFjdG9yeSglcClcbiIsVGhpcyk7CgkgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKCSAgcmV0dXJuIDA7Cgl9CglyZXR1cm4gVGhpcy0+cmVmOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURlZkNsRl9mbkNyZWF0ZUluc3RhbmNlCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURlZkNsRl9mbkNyZWF0ZUluc3RhbmNlKAogIExQQ0xBU1NGQUNUT1JZIGlmYWNlLCBMUFVOS05PV04gcFVua091dGVyLCBSRUZJSUQgcmlpZCwgTFBWT0lEICpwcHZPYmplY3QpCnsKCUlDT01fVEhJUyhJRGVmQ2xGSW1wbCxpZmFjZSk7CgoJVFJBQ0UoIiVwLT4oJXAsXG5cdElJRDpcdCVzLCVwKVxuIixUaGlzLHBVbmtPdXRlcixkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwdk9iamVjdCk7CgoJKnBwdk9iamVjdCA9IE5VTEw7CgkJCglpZihwVW5rT3V0ZXIpCgkgIHJldHVybihDTEFTU19FX05PQUdHUkVHQVRJT04pOwoKCWlmICggVGhpcy0+cmlpZEluc3Q9PU5VTEwgfHwKCSAgICAgSXNFcXVhbENMU0lEKHJpaWQsIFRoaXMtPnJpaWRJbnN0KSB8fAoJICAgICBJc0VxdWFsQ0xTSUQocmlpZCwgJklJRF9JVW5rbm93bikgKQoJewoJICByZXR1cm4gVGhpcy0+bHBmbkNJKHBVbmtPdXRlciwgcmlpZCwgcHB2T2JqZWN0KTsKCX0KCglFUlIoInVua25vd24gSUlEIHJlcXVlc3RlZFxuXHRJSUQ6XHQlc1xuIixkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKCXJldHVybiBFX05PSU5URVJGQUNFOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURlZkNsRl9mbkxvY2tTZXJ2ZXIKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGVmQ2xGX2ZuTG9ja1NlcnZlcihMUENMQVNTRkFDVE9SWSBpZmFjZSwgQk9PTCBmTG9jaykKewoJSUNPTV9USElTKElEZWZDbEZJbXBsLGlmYWNlKTsKCVRSQUNFKCIlcC0+KDB4JXgpLCBub3QgaW1wbGVtZW50ZWRcbiIsVGhpcywgZkxvY2spOwoJcmV0dXJuIEVfTk9USU1QTDsKfQoKc3RhdGljIElDT01fVlRBQkxFKElDbGFzc0ZhY3RvcnkpIGRjbGZ2dCA9IAp7CiAgICBJQ09NX01TVlRBQkxFX0NPTVBBVF9EdW1teVJUVElWQUxVRQogICAgSURlZkNsRl9mblF1ZXJ5SW50ZXJmYWNlLAogICAgSURlZkNsRl9mbkFkZFJlZiwKICBJRGVmQ2xGX2ZuUmVsZWFzZSwKICBJRGVmQ2xGX2ZuQ3JlYXRlSW5zdGFuY2UsCiAgSURlZkNsRl9mbkxvY2tTZXJ2ZXIKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hDcmVhdGVEZWZDbGFzc09iamVjdAkJCVtTSEVMTDMyLjcwXQogKi8KSFJFU1VMVCBXSU5BUEkgU0hDcmVhdGVEZWZDbGFzc09iamVjdCgKCVJFRklJRAlyaWlkLAkJCQkKCUxQVk9JRCoJcHB2LAkKCUxQRk5DUkVBVEVJTlNUQU5DRSBscGZuQ0ksCS8qIFtpbl0gY3JlYXRlIGluc3RhbmNlIGNhbGxiYWNrIGVudHJ5ICovCglQTE9ORwlwY1JlZkRsbCwJCS8qIFtpbi9vdXRdIHJlZiBjb3VudCBvZiB0aGUgZGxsICovCglSRUZJSUQJcmlpZEluc3QpCQkvKiBbaW5dIG9wdGlvbmFsIGludGVyZmFjZSB0byB0aGUgaW5zdGFuY2UgKi8KewoJVFJBQ0UoIlxuXHRJSUQ6XHQlcyAlcCAlcCAlcCBcblx0SUlESW5zOlx0JXNcbiIsCiAgICAgICAgICAgICAgZGVidWdzdHJfZ3VpZChyaWlkKSwgcHB2LCBscGZuQ0ksIHBjUmVmRGxsLCBkZWJ1Z3N0cl9ndWlkKHJpaWRJbnN0KSk7CgoJaWYgKCBJc0VxdWFsQ0xTSUQocmlpZCwgJklJRF9JQ2xhc3NGYWN0b3J5KSApCgl7CgkgIElDbGFzc0ZhY3RvcnkgKiBwY2YgPSBJRGVmQ2xGX2ZuQ29uc3RydWN0b3IobHBmbkNJLCBwY1JlZkRsbCwgcmlpZEluc3QpOwoJICBpZiAocGNmKQoJICB7CgkgICAgKnBwdiA9IHBjZjsKCSAgICByZXR1cm4gTk9FUlJPUjsKCSAgfQoJICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCX0KCXJldHVybiBFX05PSU5URVJGQUNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgRHJhZ0FjY2VwdEZpbGVzCQlbU0hFTEwzMi41NF0KICovCnZvaWQgV0lOQVBJIERyYWdBY2NlcHRGaWxlcyhIV05EIGhXbmQsIEJPT0wgYikKewoJTE9ORyBleHN0eWxlOwogIAoJaWYoICFJc1dpbmRvdyhoV25kKSApIHJldHVybjsKCWV4c3R5bGUgPSBHZXRXaW5kb3dMb25nQShoV25kLEdXTF9FWFNUWUxFKTsKCWlmIChiKQoJICBleHN0eWxlIHw9IFdTX0VYX0FDQ0VQVEZJTEVTOwoJZWxzZQoJICBleHN0eWxlICY9IH5XU19FWF9BQ0NFUFRGSUxFUzsKCVNldFdpbmRvd0xvbmdBKGhXbmQsR1dMX0VYU1RZTEUsZXhzdHlsZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERyYWdGaW5pc2gJCVtTSEVMTDMyLjgwXQogKi8Kdm9pZCBXSU5BUEkgRHJhZ0ZpbmlzaChIRFJPUCBoKQp7CglUUkFDRSgiXG4iKTsKCUdsb2JhbEZyZWUoKEhHTE9CQUwpaCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERyYWdRdWVyeVBvaW50CQlbU0hFTEwzMi4xMzVdCiAqLwpCT09MIFdJTkFQSSBEcmFnUXVlcnlQb2ludChIRFJPUCBoRHJvcCwgUE9JTlQgKnApCnsKICAgICAgICBEUk9QRklMRVMgKmxwRHJvcEZpbGVTdHJ1Y3Q7CglCT09MIGJSZXQ7CgoJVFJBQ0UoIlxuIik7CgoJbHBEcm9wRmlsZVN0cnVjdCA9IChEUk9QRklMRVMgKikgR2xvYmFsTG9jayhoRHJvcCk7CgogICAgICAgICpwID0gbHBEcm9wRmlsZVN0cnVjdC0+cHQ7CgliUmV0ID0gbHBEcm9wRmlsZVN0cnVjdC0+Zk5DOwogIAoJR2xvYmFsVW5sb2NrKGhEcm9wKTsKCXJldHVybiBiUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgRHJhZ1F1ZXJ5RmlsZUEJCVtTSEVMTDMyLjgxXSBbc2hlbGwzMi44Ml0KICovClVJTlQgV0lOQVBJIERyYWdRdWVyeUZpbGVBKAoJSERST1AgaERyb3AsCglVSU5UIGxGaWxlLAoJTFBTVFIgbHBzekZpbGUsCglVSU5UIGxMZW5ndGgpCnsKCUxQU1RSIGxwRHJvcDsKCVVJTlQgaSA9IDA7CglEUk9QRklMRVMgKmxwRHJvcEZpbGVTdHJ1Y3QgPSAoRFJPUEZJTEVTICopIEdsb2JhbExvY2soaERyb3ApOwogICAgCglUUkFDRSgiKCUwOHgsICV4LCAlcCwgJXUpXG4iLAloRHJvcCxsRmlsZSxscHN6RmlsZSxsTGVuZ3RoKTsKICAgIAoJaWYoIWxwRHJvcEZpbGVTdHJ1Y3QpIGdvdG8gZW5kOwoKCWxwRHJvcCA9IChMUFNUUikgbHBEcm9wRmlsZVN0cnVjdCArIGxwRHJvcEZpbGVTdHJ1Y3QtPnBGaWxlczsKCgl3aGlsZSAoaSsrIDwgbEZpbGUpCgl7CgkgIHdoaWxlICgqbHBEcm9wKyspOyAvKiBza2lwIGZpbGVuYW1lICovCgkgIGlmICghKmxwRHJvcCkgCgkgIHsKCSAgICBpID0gKGxGaWxlID09IDB4RkZGRkZGRkYpID8gaSA6IDA7IAoJICAgIGdvdG8gZW5kOwoJICB9Cgl9CiAgICAKCWkgPSBzdHJsZW4obHBEcm9wKTsKCWkrKzsKCWlmICghbHBzekZpbGUgKSBnb3RvIGVuZDsgICAvKiBuZWVkZWQgYnVmZmVyIHNpemUgKi8KCWkgPSAobExlbmd0aCA+IGkpID8gaSA6IGxMZW5ndGg7Cglsc3RyY3B5bkEgKGxwc3pGaWxlLCAgbHBEcm9wLCAgaSk7CmVuZDoKCUdsb2JhbFVubG9jayhoRHJvcCk7CglyZXR1cm4gaTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIERyYWdRdWVyeUZpbGVXCQlbc2hlbGwzMi4xMzNdCiAqLwpVSU5UIFdJTkFQSSBEcmFnUXVlcnlGaWxlVygKCUhEUk9QIGhEcm9wLAoJVUlOVCBsRmlsZSwKCUxQV1NUUiBscHN6d0ZpbGUsCglVSU5UIGxMZW5ndGgpCnsKCUxQV1NUUiBscHdEcm9wOwoJVUlOVCBpID0gMDsKCURST1BGSUxFUyAqbHBEcm9wRmlsZVN0cnVjdCA9IChEUk9QRklMRVMgKikgR2xvYmFsTG9jayhoRHJvcCk7CiAgICAKCVRSQUNFKCIoJTA4eCwgJXgsICVwLCAldSlcbiIsIGhEcm9wLGxGaWxlLGxwc3p3RmlsZSxsTGVuZ3RoKTsKICAgIAoJaWYoIWxwRHJvcEZpbGVTdHJ1Y3QpIGdvdG8gZW5kOwoKCWxwd0Ryb3AgPSAoTFBXU1RSKSBscERyb3BGaWxlU3RydWN0ICsgbHBEcm9wRmlsZVN0cnVjdC0+cEZpbGVzOwoKCWkgPSAwOwoJd2hpbGUgKGkrKyA8IGxGaWxlKQoJewoJICB3aGlsZSAoKmxwd0Ryb3ArKyk7IC8qIHNraXAgZmlsZW5hbWUgKi8KCSAgaWYgKCEqbHB3RHJvcCkgCgkgIHsKCSAgICBpID0gKGxGaWxlID09IDB4RkZGRkZGRkYpID8gaSA6IDA7IAoJICAgIGdvdG8gZW5kOwoJICB9Cgl9CiAgICAKCWkgPSBzdHJsZW5XKGxwd0Ryb3ApOwoJaSsrOwoJaWYgKCAhbHBzendGaWxlKSBnb3RvIGVuZDsgICAvKiBuZWVkZWQgYnVmZmVyIHNpemUgKi8KCglpID0gKGxMZW5ndGggPiBpKSA/IGkgOiBsTGVuZ3RoOwoJbHN0cmNweW5XIChscHN6d0ZpbGUsIGxwd0Ryb3AsIGkpOwplbmQ6CglHbG9iYWxVbmxvY2soaERyb3ApOwoJcmV0dXJuIGk7Cn0K