LyoKICogJFJDU0lkOiB4Yy9saWIvZm9udGNvbmZpZy9zcmMvZmN4bWwuYyx2IDEuMjEgMjAwMi8wOC8yMiAxODo1MzoyMiBrZWl0aHAgRXhwICQKICoKICogQ29weXJpZ2h0IKkgMjAwMiBLZWl0aCBQYWNrYXJkCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUsIGFuZCBzZWxsIHRoaXMgc29mdHdhcmUgYW5kIGl0cwogKiBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBpcyBoZXJlYnkgZ3JhbnRlZCB3aXRob3V0IGZlZSwgcHJvdmlkZWQgdGhhdAogKiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoYXQKICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZwogKiBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBLZWl0aCBQYWNrYXJkIG5vdCBiZSB1c2VkIGluCiAqIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dAogKiBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgS2VpdGggUGFja2FyZCBtYWtlcyBubwogKiByZXByZXNlbnRhdGlvbnMgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiAgSXQKICogaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KICoKICogS0VJVEggUEFDS0FSRCBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwKICogSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTwogKiBFVkVOVCBTSEFMTCBLRUlUSCBQQUNLQVJEIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SCiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLAogKiBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlICJmY2ludC5oIgoKI2lmbmRlZiBIQVZFX1hNTFBBUlNFX0gKI2RlZmluZSBIQVZFX1hNTFBBUlNFX0ggMAojZW5kaWYKCiNpZiBIQVZFX1hNTFBBUlNFX0gKI2luY2x1ZGUgPHhtbHBhcnNlLmg+CiNlbHNlCiNpbmNsdWRlIDxleHBhdC5oPgojZW5kaWYKCiNpZmRlZiBfV0lOMzIKI2RlZmluZSBTVFJJQ1QKI2luY2x1ZGUgPHdpbmRvd3MuaD4KI3VuZGVmIFNUUklDVAojZW5kaWYKCkZjVGVzdCAqCkZjVGVzdENyZWF0ZSAoRmNNYXRjaEtpbmQgICBraW5kLCAKCSAgICAgIEZjUXVhbAkgICAgcXVhbCwKCSAgICAgIGNvbnN0IEZjQ2hhcjggKmZpZWxkLAoJICAgICAgRmNPcAkgICAgY29tcGFyZSwKCSAgICAgIEZjRXhwcgkgICAgKmV4cHIpCnsKICAgIEZjVGVzdAkqdGVzdCA9IChGY1Rlc3QgKikgbWFsbG9jIChzaXplb2YgKEZjVGVzdCkpOwoKICAgIGlmICh0ZXN0KQogICAgewoJRmNNZW1BbGxvYyAoRkNfTUVNX1RFU1QsIHNpemVvZiAoRmNUZXN0KSk7Cgl0ZXN0LT5uZXh0ID0gMDsKCXRlc3QtPmtpbmQgPSBraW5kOwoJdGVzdC0+cXVhbCA9IHF1YWw7Cgl0ZXN0LT5maWVsZCA9IChjaGFyICopIEZjU3RyQ29weSAoZmllbGQpOwoJdGVzdC0+b3AgPSBjb21wYXJlOwoJdGVzdC0+ZXhwciA9IGV4cHI7CiAgICB9CiAgICByZXR1cm4gdGVzdDsKfQoKdm9pZApGY1Rlc3REZXN0cm95IChGY1Rlc3QgKnRlc3QpCnsKICAgIGlmICh0ZXN0LT5uZXh0KQoJRmNUZXN0RGVzdHJveSAodGVzdC0+bmV4dCk7CiAgICBGY0V4cHJEZXN0cm95ICh0ZXN0LT5leHByKTsKICAgIEZjU3RyRnJlZSAoKEZjQ2hhcjggKikgdGVzdC0+ZmllbGQpOwogICAgRmNNZW1GcmVlIChGQ19NRU1fVEVTVCwgc2l6ZW9mIChGY1Rlc3QpKTsKICAgIGZyZWUgKHRlc3QpOwp9CgpGY0V4cHIgKgpGY0V4cHJDcmVhdGVJbnRlZ2VyIChpbnQgaSkKewogICAgRmNFeHByICplID0gKEZjRXhwciAqKSBtYWxsb2MgKHNpemVvZiAoRmNFeHByKSk7CgogICAgaWYgKGUpCiAgICB7CglGY01lbUFsbG9jIChGQ19NRU1fRVhQUiwgc2l6ZW9mIChGY0V4cHIpKTsKCWUtPm9wID0gRmNPcEludGVnZXI7CgllLT51Lml2YWwgPSBpOwogICAgfQogICAgcmV0dXJuIGU7Cn0KCkZjRXhwciAqCkZjRXhwckNyZWF0ZURvdWJsZSAoZG91YmxlIGQpCnsKICAgIEZjRXhwciAqZSA9IChGY0V4cHIgKikgbWFsbG9jIChzaXplb2YgKEZjRXhwcikpOwoKICAgIGlmIChlKQogICAgewoJRmNNZW1BbGxvYyAoRkNfTUVNX0VYUFIsIHNpemVvZiAoRmNFeHByKSk7CgllLT5vcCA9IEZjT3BEb3VibGU7CgllLT51LmR2YWwgPSBkOwogICAgfQogICAgcmV0dXJuIGU7Cn0KCkZjRXhwciAqCkZjRXhwckNyZWF0ZVN0cmluZyAoY29uc3QgRmNDaGFyOCAqcykKewogICAgRmNFeHByICplID0gKEZjRXhwciAqKSBtYWxsb2MgKHNpemVvZiAoRmNFeHByKSk7CgogICAgaWYgKGUpCiAgICB7CglGY01lbUFsbG9jIChGQ19NRU1fRVhQUiwgc2l6ZW9mIChGY0V4cHIpKTsKCWUtPm9wID0gRmNPcFN0cmluZzsKCWUtPnUuc3ZhbCA9IEZjU3RyQ29weSAocyk7CiAgICB9CiAgICByZXR1cm4gZTsKfQoKRmNFeHByICoKRmNFeHByQ3JlYXRlTWF0cml4IChjb25zdCBGY01hdHJpeCAqbSkKewogICAgRmNFeHByICplID0gKEZjRXhwciAqKSBtYWxsb2MgKHNpemVvZiAoRmNFeHByKSk7CgogICAgaWYgKGUpCiAgICB7CglGY01lbUFsbG9jIChGQ19NRU1fRVhQUiwgc2l6ZW9mIChGY0V4cHIpKTsKCWUtPm9wID0gRmNPcE1hdHJpeDsKCWUtPnUubXZhbCA9IEZjTWF0cml4Q29weSAobSk7CiAgICB9CiAgICByZXR1cm4gZTsKfQoKRmNFeHByICoKRmNFeHByQ3JlYXRlQm9vbCAoRmNCb29sIGIpCnsKICAgIEZjRXhwciAqZSA9IChGY0V4cHIgKikgbWFsbG9jIChzaXplb2YgKEZjRXhwcikpOwoKICAgIGlmIChlKQogICAgewoJRmNNZW1BbGxvYyAoRkNfTUVNX0VYUFIsIHNpemVvZiAoRmNFeHByKSk7CgllLT5vcCA9IEZjT3BCb29sOwoJZS0+dS5idmFsID0gYjsKICAgIH0KICAgIHJldHVybiBlOwp9CgpGY0V4cHIgKgpGY0V4cHJDcmVhdGVOaWwgKHZvaWQpCnsKICAgIEZjRXhwciAqZSA9IChGY0V4cHIgKikgbWFsbG9jIChzaXplb2YgKEZjRXhwcikpOwoKICAgIGlmIChlKQogICAgewoJRmNNZW1BbGxvYyAoRkNfTUVNX0VYUFIsIHNpemVvZiAoRmNFeHByKSk7CgllLT5vcCA9IEZjT3BOaWw7CiAgICB9CiAgICByZXR1cm4gZTsKfQoKRmNFeHByICoKRmNFeHByQ3JlYXRlRmllbGQgKGNvbnN0IGNoYXIgKmZpZWxkKQp7CiAgICBGY0V4cHIgKmUgPSAoRmNFeHByICopIG1hbGxvYyAoc2l6ZW9mIChGY0V4cHIpKTsKCiAgICBpZiAoZSkKICAgIHsKCUZjTWVtQWxsb2MgKEZDX01FTV9FWFBSLCBzaXplb2YgKEZjRXhwcikpOwoJZS0+b3AgPSBGY09wRmllbGQ7CgllLT51LmZpZWxkID0gKGNoYXIgKikgRmNTdHJDb3B5ICgoRmNDaGFyOCAqKSBmaWVsZCk7CiAgICB9CiAgICByZXR1cm4gZTsKfQoKRmNFeHByICoKRmNFeHByQ3JlYXRlQ29uc3QgKGNvbnN0IEZjQ2hhcjggKmNvbnN0YW50KQp7CiAgICBGY0V4cHIgKmUgPSAoRmNFeHByICopIG1hbGxvYyAoc2l6ZW9mIChGY0V4cHIpKTsKCiAgICBpZiAoZSkKICAgIHsKCUZjTWVtQWxsb2MgKEZDX01FTV9FWFBSLCBzaXplb2YgKEZjRXhwcikpOwoJZS0+b3AgPSBGY09wQ29uc3Q7CgllLT51LmNvbnN0YW50ID0gRmNTdHJDb3B5IChjb25zdGFudCk7CiAgICB9CiAgICByZXR1cm4gZTsKfQoKRmNFeHByICoKRmNFeHByQ3JlYXRlT3AgKEZjRXhwciAqbGVmdCwgRmNPcCBvcCwgRmNFeHByICpyaWdodCkKewogICAgRmNFeHByICplID0gKEZjRXhwciAqKSBtYWxsb2MgKHNpemVvZiAoRmNFeHByKSk7CgogICAgaWYgKGUpCiAgICB7CglGY01lbUFsbG9jIChGQ19NRU1fRVhQUiwgc2l6ZW9mIChGY0V4cHIpKTsKCWUtPm9wID0gb3A7CgllLT51LnRyZWUubGVmdCA9IGxlZnQ7CgllLT51LnRyZWUucmlnaHQgPSByaWdodDsKICAgIH0KICAgIHJldHVybiBlOwp9Cgp2b2lkCkZjRXhwckRlc3Ryb3kgKEZjRXhwciAqZSkKewogICAgaWYgKCFlKQoJcmV0dXJuOwogICAgc3dpdGNoIChlLT5vcCkgewogICAgY2FzZSBGY09wSW50ZWdlcjoKCWJyZWFrOwogICAgY2FzZSBGY09wRG91YmxlOgoJYnJlYWs7CiAgICBjYXNlIEZjT3BTdHJpbmc6CglGY1N0ckZyZWUgKGUtPnUuc3ZhbCk7CglicmVhazsKICAgIGNhc2UgRmNPcE1hdHJpeDoKCUZjTWF0cml4RnJlZSAoZS0+dS5tdmFsKTsKCWJyZWFrOwogICAgY2FzZSBGY09wQ2hhclNldDoKCUZjQ2hhclNldERlc3Ryb3kgKGUtPnUuY3ZhbCk7CglicmVhazsKICAgIGNhc2UgRmNPcEJvb2w6CglicmVhazsKICAgIGNhc2UgRmNPcEZpZWxkOgoJRmNTdHJGcmVlICgoRmNDaGFyOCAqKSBlLT51LmZpZWxkKTsKCWJyZWFrOwogICAgY2FzZSBGY09wQ29uc3Q6CglGY1N0ckZyZWUgKGUtPnUuY29uc3RhbnQpOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BBc3NpZ246CiAgICBjYXNlIEZjT3BBc3NpZ25SZXBsYWNlOgogICAgY2FzZSBGY09wUHJlcGVuZDoKICAgIGNhc2UgRmNPcFByZXBlbmRGaXJzdDoKICAgIGNhc2UgRmNPcEFwcGVuZDoKICAgIGNhc2UgRmNPcEFwcGVuZExhc3Q6CglicmVhazsKICAgIGNhc2UgRmNPcE9yOgogICAgY2FzZSBGY09wQW5kOgogICAgY2FzZSBGY09wRXF1YWw6CiAgICBjYXNlIEZjT3BOb3RFcXVhbDoKICAgIGNhc2UgRmNPcExlc3M6CiAgICBjYXNlIEZjT3BMZXNzRXF1YWw6CiAgICBjYXNlIEZjT3BNb3JlOgogICAgY2FzZSBGY09wTW9yZUVxdWFsOgogICAgY2FzZSBGY09wQ29udGFpbnM6CiAgICBjYXNlIEZjT3BMaXN0aW5nOgogICAgY2FzZSBGY09wTm90Q29udGFpbnM6CiAgICBjYXNlIEZjT3BQbHVzOgogICAgY2FzZSBGY09wTWludXM6CiAgICBjYXNlIEZjT3BUaW1lczoKICAgIGNhc2UgRmNPcERpdmlkZToKICAgIGNhc2UgRmNPcFF1ZXN0OgogICAgY2FzZSBGY09wQ29tbWE6CglGY0V4cHJEZXN0cm95IChlLT51LnRyZWUucmlnaHQpOwoJLyogZmFsbCB0aHJvdWdoICovCiAgICBjYXNlIEZjT3BOb3Q6CiAgICBjYXNlIEZjT3BGbG9vcjoKICAgIGNhc2UgRmNPcENlaWw6CiAgICBjYXNlIEZjT3BSb3VuZDoKICAgIGNhc2UgRmNPcFRydW5jOgoJRmNFeHByRGVzdHJveSAoZS0+dS50cmVlLmxlZnQpOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BOaWw6CiAgICBjYXNlIEZjT3BJbnZhbGlkOgoJYnJlYWs7CiAgICB9CiAgICBGY01lbUZyZWUgKEZDX01FTV9FWFBSLCBzaXplb2YgKEZjRXhwcikpOwogICAgZnJlZSAoZSk7Cn0KCkZjRWRpdCAqCkZjRWRpdENyZWF0ZSAoY29uc3QgY2hhciAqZmllbGQsIEZjT3Agb3AsIEZjRXhwciAqZXhwciwgRmNWYWx1ZUJpbmRpbmcgYmluZGluZykKewogICAgRmNFZGl0ICplID0gKEZjRWRpdCAqKSBtYWxsb2MgKHNpemVvZiAoRmNFZGl0KSk7CgogICAgaWYgKGUpCiAgICB7CgllLT5uZXh0ID0gMDsKCWUtPmZpZWxkID0gZmllbGQ7ICAgLyogYWxyZWFkeSBzYXZlZCBpbiBncmFtbWFyICovCgllLT5vcCA9IG9wOwoJZS0+ZXhwciA9IGV4cHI7CgllLT5iaW5kaW5nID0gYmluZGluZzsKICAgIH0KICAgIHJldHVybiBlOwp9Cgp2b2lkCkZjRWRpdERlc3Ryb3kgKEZjRWRpdCAqZSkKewogICAgaWYgKGUtPm5leHQpCglGY0VkaXREZXN0cm95IChlLT5uZXh0KTsKICAgIEZjU3RyRnJlZSAoKEZjQ2hhcjggKikgZS0+ZmllbGQpOwogICAgaWYgKGUtPmV4cHIpCglGY0V4cHJEZXN0cm95IChlLT5leHByKTsKICAgIGZyZWUgKGUpOwp9CgpjaGFyICoKRmNDb25maWdTYXZlRmllbGQgKGNvbnN0IGNoYXIgKmZpZWxkKQp7CiAgICByZXR1cm4gKGNoYXIgKikgRmNTdHJDb3B5ICgoRmNDaGFyOCAqKSBmaWVsZCk7Cn0KCnR5cGVkZWYgZW51bSBfRmNFbGVtZW50IHsKICAgIEZjRWxlbWVudE5vbmUsCiAgICBGY0VsZW1lbnRGb250Y29uZmlnLAogICAgRmNFbGVtZW50RGlyLAogICAgRmNFbGVtZW50Q2FjaGUsCiAgICBGY0VsZW1lbnRJbmNsdWRlLAogICAgRmNFbGVtZW50Q29uZmlnLAogICAgRmNFbGVtZW50TWF0Y2gsCiAgICBGY0VsZW1lbnRBbGlhcywKCQogICAgRmNFbGVtZW50QmxhbmssCiAgICBGY0VsZW1lbnRSZXNjYW4sCgogICAgRmNFbGVtZW50UHJlZmVyLAogICAgRmNFbGVtZW50QWNjZXB0LAogICAgRmNFbGVtZW50RGVmYXVsdCwKICAgIEZjRWxlbWVudEZhbWlseSwKCiAgICBGY0VsZW1lbnRTZWxlY3Rmb250LAogICAgRmNFbGVtZW50QWNjZXB0Zm9udCwKICAgIEZjRWxlbWVudFJlamVjdGZvbnQsCiAgICBGY0VsZW1lbnRHbG9iLAoKICAgIEZjRWxlbWVudFRlc3QsCiAgICBGY0VsZW1lbnRFZGl0LAogICAgRmNFbGVtZW50SW50LAogICAgRmNFbGVtZW50RG91YmxlLAogICAgRmNFbGVtZW50U3RyaW5nLAogICAgRmNFbGVtZW50TWF0cml4LAogICAgRmNFbGVtZW50Qm9vbCwKICAgIEZjRWxlbWVudENoYXJzZXQsCiAgICBGY0VsZW1lbnROYW1lLAogICAgRmNFbGVtZW50Q29uc3QsCiAgICBGY0VsZW1lbnRPciwKICAgIEZjRWxlbWVudEFuZCwKICAgIEZjRWxlbWVudEVxLAogICAgRmNFbGVtZW50Tm90RXEsCiAgICBGY0VsZW1lbnRMZXNzLAogICAgRmNFbGVtZW50TGVzc0VxLAogICAgRmNFbGVtZW50TW9yZSwKICAgIEZjRWxlbWVudE1vcmVFcSwKICAgIEZjRWxlbWVudENvbnRhaW5zLAogICAgRmNFbGVtZW50Tm90Q29udGFpbnMsCiAgICBGY0VsZW1lbnRQbHVzLAogICAgRmNFbGVtZW50TWludXMsCiAgICBGY0VsZW1lbnRUaW1lcywKICAgIEZjRWxlbWVudERpdmlkZSwKICAgIEZjRWxlbWVudE5vdCwKICAgIEZjRWxlbWVudElmLAogICAgRmNFbGVtZW50Rmxvb3IsCiAgICBGY0VsZW1lbnRDZWlsLAogICAgRmNFbGVtZW50Um91bmQsCiAgICBGY0VsZW1lbnRUcnVuYywKICAgIEZjRWxlbWVudFVua25vd24KfSBGY0VsZW1lbnQ7CgpzdGF0aWMgRmNFbGVtZW50CkZjRWxlbWVudE1hcCAoY29uc3QgWE1MX0NoYXIgKm5hbWUpCnsKICAgIHN0YXRpYyBzdHJ1Y3QgewoJY2hhcgkgICAgKm5hbWU7CglGY0VsZW1lbnQgICBlbGVtZW50OwogICAgfSBmY0VsZW1lbnRNYXBbXSA9IHsKCXsgImZvbnRjb25maWciLAlGY0VsZW1lbnRGb250Y29uZmlnIH0sCgl7ICJkaXIiLAlGY0VsZW1lbnREaXIgfSwKCXsgImNhY2hlIiwJRmNFbGVtZW50Q2FjaGUgfSwKCXsgImluY2x1ZGUiLAlGY0VsZW1lbnRJbmNsdWRlIH0sCgl7ICJjb25maWciLAlGY0VsZW1lbnRDb25maWcgfSwKCXsgIm1hdGNoIiwJRmNFbGVtZW50TWF0Y2ggfSwKCXsgImFsaWFzIiwJRmNFbGVtZW50QWxpYXMgfSwKCQoJeyAiYmxhbmsiLAlGY0VsZW1lbnRCbGFuayB9LAoJeyAicmVzY2FuIiwJRmNFbGVtZW50UmVzY2FuIH0sCgoJeyAicHJlZmVyIiwJRmNFbGVtZW50UHJlZmVyIH0sCgl7ICJhY2NlcHQiLAlGY0VsZW1lbnRBY2NlcHQgfSwKCXsgImRlZmF1bHQiLAlGY0VsZW1lbnREZWZhdWx0IH0sCgl7ICJmYW1pbHkiLAlGY0VsZW1lbnRGYW1pbHkgfSwKCgl7ICJzZWxlY3Rmb250IiwJRmNFbGVtZW50U2VsZWN0Zm9udCB9LAoJeyAiYWNjZXB0Zm9udCIsCUZjRWxlbWVudEFjY2VwdGZvbnQgfSwKCXsgInJlamVjdGZvbnQiLAlGY0VsZW1lbnRSZWplY3Rmb250IH0sCgl7ICJnbG9iIiwJRmNFbGVtZW50R2xvYiB9LAoKCXsgInRlc3QiLAlGY0VsZW1lbnRUZXN0IH0sCgl7ICJlZGl0IiwJRmNFbGVtZW50RWRpdCB9LAoJeyAiaW50IiwJRmNFbGVtZW50SW50IH0sCgl7ICJkb3VibGUiLAlGY0VsZW1lbnREb3VibGUgfSwKCXsgInN0cmluZyIsCUZjRWxlbWVudFN0cmluZyB9LAoJeyAibWF0cml4IiwJRmNFbGVtZW50TWF0cml4IH0sCgl7ICJib29sIiwJRmNFbGVtZW50Qm9vbCB9LAoJeyAiY2hhcnNldCIsCUZjRWxlbWVudENoYXJzZXQgfSwKCXsgIm5hbWUiLAlGY0VsZW1lbnROYW1lIH0sCgl7ICJjb25zdCIsCUZjRWxlbWVudENvbnN0IH0sCgl7ICJvciIsCQlGY0VsZW1lbnRPciB9LAoJeyAiYW5kIiwJRmNFbGVtZW50QW5kIH0sCgl7ICJlcSIsCQlGY0VsZW1lbnRFcSB9LAoJeyAibm90X2VxIiwJRmNFbGVtZW50Tm90RXEgfSwKCXsgImxlc3MiLAlGY0VsZW1lbnRMZXNzIH0sCgl7ICJsZXNzX2VxIiwJRmNFbGVtZW50TGVzc0VxIH0sCgl7ICJtb3JlIiwJRmNFbGVtZW50TW9yZSB9LAoJeyAibW9yZV9lcSIsCUZjRWxlbWVudE1vcmVFcSB9LAoJeyAiY29udGFpbnMiLAlGY0VsZW1lbnRDb250YWlucyB9LAoJeyAibm90X2NvbnRhaW5zIixGY0VsZW1lbnROb3RDb250YWlucyB9LAoJeyAicGx1cyIsCUZjRWxlbWVudFBsdXMgfSwKCXsgIm1pbnVzIiwJRmNFbGVtZW50TWludXMgfSwKCXsgInRpbWVzIiwJRmNFbGVtZW50VGltZXMgfSwKCXsgImRpdmlkZSIsCUZjRWxlbWVudERpdmlkZSB9LAoJeyAibm90IiwJRmNFbGVtZW50Tm90IH0sCgl7ICJpZiIsCQlGY0VsZW1lbnRJZiB9LAoJeyAiZmxvb3IiLAlGY0VsZW1lbnRGbG9vciB9LAoJeyAiY2VpbCIsCUZjRWxlbWVudENlaWwgfSwKCXsgInJvdW5kIiwJRmNFbGVtZW50Um91bmQgfSwKCXsgInRydW5jIiwJRmNFbGVtZW50VHJ1bmMgfSwKCQoJeyAwLAkJMCB9CiAgICB9OwoKICAgIGludAkgICAgaTsKICAgIGZvciAoaSA9IDA7IGZjRWxlbWVudE1hcFtpXS5uYW1lOyBpKyspCglpZiAoIXN0cmNtcCAoKGNoYXIgKikgbmFtZSwgZmNFbGVtZW50TWFwW2ldLm5hbWUpKQoJICAgIHJldHVybiBmY0VsZW1lbnRNYXBbaV0uZWxlbWVudDsKICAgIHJldHVybiBGY0VsZW1lbnRVbmtub3duOwp9Cgp0eXBlZGVmIHN0cnVjdCBfRmNQU3RhY2sgewogICAgc3RydWN0IF9GY1BTdGFjayAgICpwcmV2OwogICAgRmNFbGVtZW50CQllbGVtZW50OwogICAgRmNDaGFyOAkJKiphdHRyOwogICAgRmNTdHJCdWYJCXN0cjsKfSBGY1BTdGFjazsKICAgIAp0eXBlZGVmIGVudW0gX0ZjVlN0YWNrVGFnIHsKICAgIEZjVlN0YWNrTm9uZSwKCiAgICBGY1ZTdGFja1N0cmluZywKICAgIEZjVlN0YWNrRmFtaWx5LAogICAgRmNWU3RhY2tGaWVsZCwKICAgIEZjVlN0YWNrQ29uc3RhbnQsCiAgICBGY1ZTdGFja0dsb2IsCiAgICAKICAgIEZjVlN0YWNrUHJlZmVyLAogICAgRmNWU3RhY2tBY2NlcHQsCiAgICBGY1ZTdGFja0RlZmF1bHQsCiAgICAKICAgIEZjVlN0YWNrSW50ZWdlciwKICAgIEZjVlN0YWNrRG91YmxlLAogICAgRmNWU3RhY2tNYXRyaXgsCiAgICBGY1ZTdGFja0Jvb2wsCiAgICAKICAgIEZjVlN0YWNrVGVzdCwKICAgIEZjVlN0YWNrRXhwciwKICAgIEZjVlN0YWNrRWRpdAp9IEZjVlN0YWNrVGFnOwoKdHlwZWRlZiBzdHJ1Y3QgX0ZjVlN0YWNrIHsKICAgIHN0cnVjdCBfRmNWU3RhY2sJKnByZXY7CiAgICBGY1BTdGFjawkJKnBzdGFjazsJLyogcmVsYXRlZCBwYXJzZSBlbGVtZW50ICovCiAgICBGY1ZTdGFja1RhZwkJdGFnOwogICAgdW5pb24gewoJRmNDaGFyOAkJKnN0cmluZzsKCglpbnQJCWludGVnZXI7Cglkb3VibGUJCV9kb3VibGU7CglGY01hdHJpeAkqbWF0cml4OwoJRmNCb29sCQlib29sOwoKCUZjVGVzdAkJKnRlc3Q7CglGY1F1YWwJCXF1YWw7CglGY09wCQlvcDsKCUZjRXhwcgkJKmV4cHI7CglGY0VkaXQJCSplZGl0OwogICAgfSB1Owp9IEZjVlN0YWNrOwoKdHlwZWRlZiBzdHJ1Y3QgX0ZjQ29uZmlnUGFyc2UgewogICAgRmNQU3RhY2sJICAgICpwc3RhY2s7CiAgICBGY1ZTdGFjawkgICAgKnZzdGFjazsKICAgIEZjQm9vbAkgICAgZXJyb3I7CiAgICBjb25zdCBGY0NoYXI4ICAgKm5hbWU7CiAgICBGY0NvbmZpZwkgICAgKmNvbmZpZzsKICAgIFhNTF9QYXJzZXIJICAgIHBhcnNlcjsKfSBGY0NvbmZpZ1BhcnNlOwoKdHlwZWRlZiBlbnVtIF9GY0NvbmZpZ1NldmVyaXR5IHsKICAgIEZjU2V2ZXJlSW5mbywgRmNTZXZlcmVXYXJuaW5nLCBGY1NldmVyZUVycm9yCn0gRmNDb25maWdTZXZlcml0eTsKCnN0YXRpYyB2b2lkCkZjQ29uZmlnTWVzc2FnZSAoRmNDb25maWdQYXJzZSAqcGFyc2UsIEZjQ29uZmlnU2V2ZXJpdHkgc2V2ZXJlLCBjaGFyICpmbXQsIC4uLikKewogICAgY2hhcgkqcyA9ICJ1bmtub3duIjsKICAgIHZhX2xpc3QJYXJnczsKCiAgICB2YV9zdGFydCAoYXJncywgZm10KTsKCiAgICBzd2l0Y2ggKHNldmVyZSkgewogICAgY2FzZSBGY1NldmVyZUluZm86IHMgPSAiaW5mbyI7IGJyZWFrOwogICAgY2FzZSBGY1NldmVyZVdhcm5pbmc6IHMgPSAid2FybmluZyI7IGJyZWFrOwogICAgY2FzZSBGY1NldmVyZUVycm9yOiBzID0gImVycm9yIjsgYnJlYWs7CiAgICB9CiAgICBpZiAocGFyc2UpCiAgICB7CglpZiAocGFyc2UtPm5hbWUpCgkgICAgZnByaW50ZiAoc3RkZXJyLCAiRm9udGNvbmZpZyAlczogXCIlc1wiLCBsaW5lICVkOiAiLCBzLAoJCSAgICAgcGFyc2UtPm5hbWUsIFhNTF9HZXRDdXJyZW50TGluZU51bWJlciAocGFyc2UtPnBhcnNlcikpOwoJZWxzZQoJICAgIGZwcmludGYgKHN0ZGVyciwgIkZvbnRjb25maWcgJXM6IGxpbmUgJWQ6ICIsIHMsCgkJICAgICBYTUxfR2V0Q3VycmVudExpbmVOdW1iZXIgKHBhcnNlLT5wYXJzZXIpKTsKCWlmIChzZXZlcmUgPj0gRmNTZXZlcmVFcnJvcikKCSAgICBwYXJzZS0+ZXJyb3IgPSBGY1RydWU7CiAgICB9CiAgICBlbHNlCglmcHJpbnRmIChzdGRlcnIsICJGb250Y29uZmlnICVzOiAiLCBzKTsKICAgIHZmcHJpbnRmIChzdGRlcnIsIGZtdCwgYXJncyk7CiAgICBmcHJpbnRmIChzdGRlcnIsICJcbiIpOwogICAgdmFfZW5kIChhcmdzKTsKfQoKc3RhdGljIHZvaWQKRmNWU3RhY2tQdXNoIChGY0NvbmZpZ1BhcnNlICpwYXJzZSwgRmNWU3RhY2sgKnZzdGFjaykKewogICAgdnN0YWNrLT5wcmV2ID0gcGFyc2UtPnZzdGFjazsKICAgIHZzdGFjay0+cHN0YWNrID0gcGFyc2UtPnBzdGFjayA/IHBhcnNlLT5wc3RhY2stPnByZXYgOiAwOwogICAgcGFyc2UtPnZzdGFjayA9IHZzdGFjazsKfQoKc3RhdGljIEZjVlN0YWNrICoKRmNWU3RhY2tDcmVhdGUgKHZvaWQpCnsKICAgIEZjVlN0YWNrICAgICpuZXc7CgogICAgbmV3ID0gbWFsbG9jIChzaXplb2YgKEZjVlN0YWNrKSk7CiAgICBpZiAoIW5ldykKCXJldHVybiAwOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX1ZTVEFDSywgc2l6ZW9mIChGY1ZTdGFjaykpOwogICAgbmV3LT50YWcgPSBGY1ZTdGFja05vbmU7CiAgICBuZXctPnByZXYgPSAwOwogICAgcmV0dXJuIG5ldzsKfQoKc3RhdGljIHZvaWQKRmNWU3RhY2tEZXN0cm95IChGY1ZTdGFjayAqdnN0YWNrKQp7CiAgICBGY1ZTdGFjayAgICAqcHJldjsKCiAgICBmb3IgKDsgdnN0YWNrOyB2c3RhY2sgPSBwcmV2KQogICAgewoJcHJldiA9IHZzdGFjay0+cHJldjsKCXN3aXRjaCAodnN0YWNrLT50YWcpIHsKCWNhc2UgRmNWU3RhY2tOb25lOgoJICAgIGJyZWFrOwoJY2FzZSBGY1ZTdGFja1N0cmluZzoKCWNhc2UgRmNWU3RhY2tGYW1pbHk6CgljYXNlIEZjVlN0YWNrRmllbGQ6CgljYXNlIEZjVlN0YWNrQ29uc3RhbnQ6CgljYXNlIEZjVlN0YWNrR2xvYjoKCSAgICBGY1N0ckZyZWUgKHZzdGFjay0+dS5zdHJpbmcpOwoJICAgIGJyZWFrOwoJY2FzZSBGY1ZTdGFja0ludGVnZXI6CgljYXNlIEZjVlN0YWNrRG91YmxlOgoJICAgIGJyZWFrOwoJY2FzZSBGY1ZTdGFja01hdHJpeDoKCSAgICBGY01hdHJpeEZyZWUgKHZzdGFjay0+dS5tYXRyaXgpOwoJICAgIGJyZWFrOwoJY2FzZSBGY1ZTdGFja0Jvb2w6CgkgICAgYnJlYWs7CgljYXNlIEZjVlN0YWNrVGVzdDoKCSAgICBGY1Rlc3REZXN0cm95ICh2c3RhY2stPnUudGVzdCk7CgkgICAgYnJlYWs7CgljYXNlIEZjVlN0YWNrRXhwcjoKCWNhc2UgRmNWU3RhY2tQcmVmZXI6CgljYXNlIEZjVlN0YWNrQWNjZXB0OgoJY2FzZSBGY1ZTdGFja0RlZmF1bHQ6CgkgICAgRmNFeHByRGVzdHJveSAodnN0YWNrLT51LmV4cHIpOwoJICAgIGJyZWFrOwoJY2FzZSBGY1ZTdGFja0VkaXQ6CgkgICAgRmNFZGl0RGVzdHJveSAodnN0YWNrLT51LmVkaXQpOwoJICAgIGJyZWFrOwoJfQoJRmNNZW1GcmVlIChGQ19NRU1fVlNUQUNLLCBzaXplb2YgKEZjVlN0YWNrKSk7CglmcmVlICh2c3RhY2spOwogICAgfQp9CgpzdGF0aWMgRmNCb29sCkZjVlN0YWNrUHVzaFN0cmluZyAoRmNDb25maWdQYXJzZSAqcGFyc2UsIEZjVlN0YWNrVGFnIHRhZywgRmNDaGFyOCAqc3RyaW5nKQp7CiAgICBGY1ZTdGFjayAgICAqdnN0YWNrID0gRmNWU3RhY2tDcmVhdGUgKCk7CiAgICBpZiAoIXZzdGFjaykKCXJldHVybiBGY0ZhbHNlOwogICAgdnN0YWNrLT51LnN0cmluZyA9IHN0cmluZzsKICAgIHZzdGFjay0+dGFnID0gdGFnOwogICAgRmNWU3RhY2tQdXNoIChwYXJzZSwgdnN0YWNrKTsKICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNWU3RhY2tQdXNoSW50ZWdlciAoRmNDb25maWdQYXJzZSAqcGFyc2UsIGludCBpbnRlZ2VyKQp7CiAgICBGY1ZTdGFjayAgICAqdnN0YWNrID0gRmNWU3RhY2tDcmVhdGUgKCk7CiAgICBpZiAoIXZzdGFjaykKCXJldHVybiBGY0ZhbHNlOwogICAgdnN0YWNrLT51LmludGVnZXIgPSBpbnRlZ2VyOwogICAgdnN0YWNrLT50YWcgPSBGY1ZTdGFja0ludGVnZXI7CiAgICBGY1ZTdGFja1B1c2ggKHBhcnNlLCB2c3RhY2spOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY1ZTdGFja1B1c2hEb3VibGUgKEZjQ29uZmlnUGFyc2UgKnBhcnNlLCBkb3VibGUgX2RvdWJsZSkKewogICAgRmNWU3RhY2sgICAgKnZzdGFjayA9IEZjVlN0YWNrQ3JlYXRlICgpOwogICAgaWYgKCF2c3RhY2spCglyZXR1cm4gRmNGYWxzZTsKICAgIHZzdGFjay0+dS5fZG91YmxlID0gX2RvdWJsZTsKICAgIHZzdGFjay0+dGFnID0gRmNWU3RhY2tEb3VibGU7CiAgICBGY1ZTdGFja1B1c2ggKHBhcnNlLCB2c3RhY2spOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY1ZTdGFja1B1c2hNYXRyaXggKEZjQ29uZmlnUGFyc2UgKnBhcnNlLCBGY01hdHJpeCAqbWF0cml4KQp7CiAgICBGY1ZTdGFjayAgICAqdnN0YWNrID0gRmNWU3RhY2tDcmVhdGUgKCk7CiAgICBpZiAoIXZzdGFjaykKCXJldHVybiBGY0ZhbHNlOwogICAgbWF0cml4ID0gRmNNYXRyaXhDb3B5IChtYXRyaXgpOwogICAgaWYgKCFtYXRyaXgpCiAgICB7CglGY1ZTdGFja0Rlc3Ryb3kgKHZzdGFjayk7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHZzdGFjay0+dS5tYXRyaXggPSBtYXRyaXg7CiAgICB2c3RhY2stPnRhZyA9IEZjVlN0YWNrTWF0cml4OwogICAgRmNWU3RhY2tQdXNoIChwYXJzZSwgdnN0YWNrKTsKICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNWU3RhY2tQdXNoQm9vbCAoRmNDb25maWdQYXJzZSAqcGFyc2UsIEZjQm9vbCBib29sKQp7CiAgICBGY1ZTdGFjayAgICAqdnN0YWNrID0gRmNWU3RhY2tDcmVhdGUgKCk7CiAgICBpZiAoIXZzdGFjaykKCXJldHVybiBGY0ZhbHNlOwogICAgdnN0YWNrLT51LmJvb2wgPSBib29sOwogICAgdnN0YWNrLT50YWcgPSBGY1ZTdGFja0Jvb2w7CiAgICBGY1ZTdGFja1B1c2ggKHBhcnNlLCB2c3RhY2spOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY1ZTdGFja1B1c2hUZXN0IChGY0NvbmZpZ1BhcnNlICpwYXJzZSwgRmNUZXN0ICp0ZXN0KQp7CiAgICBGY1ZTdGFjayAgICAqdnN0YWNrID0gRmNWU3RhY2tDcmVhdGUgKCk7CiAgICBpZiAoIXZzdGFjaykKCXJldHVybiBGY0ZhbHNlOwogICAgdnN0YWNrLT51LnRlc3QgPSB0ZXN0OwogICAgdnN0YWNrLT50YWcgPSBGY1ZTdGFja1Rlc3Q7CiAgICBGY1ZTdGFja1B1c2ggKHBhcnNlLCB2c3RhY2spOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY1ZTdGFja1B1c2hFeHByIChGY0NvbmZpZ1BhcnNlICpwYXJzZSwgRmNWU3RhY2tUYWcgdGFnLCBGY0V4cHIgKmV4cHIpCnsKICAgIEZjVlN0YWNrICAgICp2c3RhY2sgPSBGY1ZTdGFja0NyZWF0ZSAoKTsKICAgIGlmICghdnN0YWNrKQoJcmV0dXJuIEZjRmFsc2U7CiAgICB2c3RhY2stPnUuZXhwciA9IGV4cHI7CiAgICB2c3RhY2stPnRhZyA9IHRhZzsKICAgIEZjVlN0YWNrUHVzaCAocGFyc2UsIHZzdGFjayk7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgRmNCb29sCkZjVlN0YWNrUHVzaEVkaXQgKEZjQ29uZmlnUGFyc2UgKnBhcnNlLCBGY0VkaXQgKmVkaXQpCnsKICAgIEZjVlN0YWNrICAgICp2c3RhY2sgPSBGY1ZTdGFja0NyZWF0ZSAoKTsKICAgIGlmICghdnN0YWNrKQoJcmV0dXJuIEZjRmFsc2U7CiAgICB2c3RhY2stPnUuZWRpdCA9IGVkaXQ7CiAgICB2c3RhY2stPnRhZyA9IEZjVlN0YWNrRWRpdDsKICAgIEZjVlN0YWNrUHVzaCAocGFyc2UsIHZzdGFjayk7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgRmNWU3RhY2sgKgpGY1ZTdGFja0ZldGNoIChGY0NvbmZpZ1BhcnNlICpwYXJzZSwgaW50IG9mZikKewogICAgRmNWU3RhY2sgICAgKnZzdGFjazsKCiAgICBmb3IgKHZzdGFjayA9IHBhcnNlLT52c3RhY2s7IHZzdGFjayAmJiBvZmYtLSA+IDA7IHZzdGFjayA9IHZzdGFjay0+cHJldik7CiAgICByZXR1cm4gdnN0YWNrOwp9CgpzdGF0aWMgdm9pZApGY1ZTdGFja0NsZWFyIChGY0NvbmZpZ1BhcnNlICpwYXJzZSkKewogICAgd2hpbGUgKHBhcnNlLT52c3RhY2sgJiYgcGFyc2UtPnZzdGFjay0+cHN0YWNrID09IHBhcnNlLT5wc3RhY2spCiAgICB7CglGY1ZTdGFjayAgICAqdnN0YWNrID0gcGFyc2UtPnZzdGFjazsKCXBhcnNlLT52c3RhY2sgPSB2c3RhY2stPnByZXY7Cgl2c3RhY2stPnByZXYgPSAwOwoJRmNWU3RhY2tEZXN0cm95ICh2c3RhY2spOwogICAgfQp9CgpzdGF0aWMgRmNWU3RhY2sgKgpGY1ZTdGFja1BvcCAoRmNDb25maWdQYXJzZSAqcGFyc2UpCnsKICAgIEZjVlN0YWNrCSp2c3RhY2sgPSBwYXJzZS0+dnN0YWNrOwogICAgCiAgICBpZiAoIXZzdGFjayB8fCB2c3RhY2stPnBzdGFjayAhPSBwYXJzZS0+cHN0YWNrKQoJcmV0dXJuIDA7CiAgICBwYXJzZS0+dnN0YWNrID0gdnN0YWNrLT5wcmV2OwogICAgdnN0YWNrLT5wcmV2ID0gMDsKICAgIHJldHVybiB2c3RhY2s7Cn0KCnN0YXRpYyBpbnQKRmNWU3RhY2tFbGVtZW50cyAoRmNDb25maWdQYXJzZSAqcGFyc2UpCnsKICAgIGludAkJaCA9IDA7CiAgICBGY1ZTdGFjawkqdnN0YWNrID0gcGFyc2UtPnZzdGFjazsKICAgIHdoaWxlICh2c3RhY2sgJiYgdnN0YWNrLT5wc3RhY2sgPT0gcGFyc2UtPnBzdGFjaykKICAgIHsKCWgrKzsKCXZzdGFjayA9IHZzdGFjay0+cHJldjsKICAgIH0KICAgIHJldHVybiBoOwp9CgpzdGF0aWMgRmNDaGFyOCAqKgpGY0NvbmZpZ1NhdmVBdHRyIChjb25zdCBYTUxfQ2hhciAqKmF0dHIpCnsKICAgIGludAkJbjsKICAgIGludAkJc2xlbjsKICAgIGludAkJaTsKICAgIEZjQ2hhcjgJKipuZXc7CiAgICBGY0NoYXI4CSpzOwoKICAgIGlmICghYXR0cikKCXJldHVybiAwOwogICAgc2xlbiA9IDA7CiAgICBmb3IgKGkgPSAwOyBhdHRyW2ldOyBpKyspCglzbGVuICs9IHN0cmxlbiAoYXR0cltpXSkgKyAxOwogICAgbiA9IGk7CiAgICBuZXcgPSBtYWxsb2MgKChpICsgMSkgKiBzaXplb2YgKEZjQ2hhcjggKikgKyBzbGVuKTsKICAgIGlmICghbmV3KQoJcmV0dXJuIDA7CiAgICBGY01lbUFsbG9jIChGQ19NRU1fQVRUUiwgMSk7ICAgIC8qIHNpemUgaXMgdG9vIGV4cGVuc2l2ZSAqLwogICAgcyA9IChGY0NoYXI4ICopIChuZXcgKyAoaSArIDEpKTsKICAgIGZvciAoaSA9IDA7IGF0dHJbaV07IGkrKykKICAgIHsKCW5ld1tpXSA9IHM7CglzdHJjcHkgKChjaGFyICopIHMsIChjaGFyICopIGF0dHJbaV0pOwoJcyArPSBzdHJsZW4gKChjaGFyICopIHMpICsgMTsKICAgIH0KICAgIG5ld1tpXSA9IDA7CiAgICByZXR1cm4gbmV3Owp9CgpzdGF0aWMgRmNCb29sCkZjUFN0YWNrUHVzaCAoRmNDb25maWdQYXJzZSAqcGFyc2UsIEZjRWxlbWVudCBlbGVtZW50LCBjb25zdCBYTUxfQ2hhciAqKmF0dHIpCnsKICAgIEZjUFN0YWNrICAgKm5ldyA9IG1hbGxvYyAoc2l6ZW9mIChGY1BTdGFjaykpOwoKICAgIGlmICghbmV3KQoJcmV0dXJuIEZjRmFsc2U7CiAgICBGY01lbUFsbG9jIChGQ19NRU1fUFNUQUNLLCBzaXplb2YgKEZjUFN0YWNrKSk7CiAgICBuZXctPnByZXYgPSBwYXJzZS0+cHN0YWNrOwogICAgbmV3LT5lbGVtZW50ID0gZWxlbWVudDsKICAgIGlmIChhdHRyKQogICAgewoJbmV3LT5hdHRyID0gRmNDb25maWdTYXZlQXR0ciAoYXR0cik7CglpZiAoIW5ldy0+YXR0cikKCSAgICBGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZUVycm9yLCAib3V0IG9mIG1lbW9yeSIpOwogICAgfQogICAgZWxzZQoJbmV3LT5hdHRyID0gMDsKICAgIEZjU3RyQnVmSW5pdCAoJm5ldy0+c3RyLCAwLCAwKTsKICAgIHBhcnNlLT5wc3RhY2sgPSBuZXc7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgRmNCb29sCkZjUFN0YWNrUG9wIChGY0NvbmZpZ1BhcnNlICpwYXJzZSkKewogICAgRmNQU3RhY2sgICAqb2xkOwogICAgCiAgICBpZiAoIXBhcnNlLT5wc3RhY2spIAogICAgewoJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVFcnJvciwgIm1pc21hdGNoaW5nIGVsZW1lbnQiKTsKCXJldHVybiBGY0ZhbHNlOwogICAgfQogICAgRmNWU3RhY2tDbGVhciAocGFyc2UpOwogICAgb2xkID0gcGFyc2UtPnBzdGFjazsKICAgIHBhcnNlLT5wc3RhY2sgPSBvbGQtPnByZXY7CiAgICBGY1N0ckJ1ZkRlc3Ryb3kgKCZvbGQtPnN0cik7CiAgICBpZiAob2xkLT5hdHRyKQogICAgewoJRmNNZW1GcmVlIChGQ19NRU1fQVRUUiwgMSk7IC8qIHNpemUgaXMgdG8gZXhwZW5zaXZlICovCglmcmVlIChvbGQtPmF0dHIpOwogICAgfQogICAgRmNNZW1GcmVlIChGQ19NRU1fUFNUQUNLLCBzaXplb2YgKEZjUFN0YWNrKSk7CiAgICBmcmVlIChvbGQpOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY0NvbmZpZ0luaXQgKEZjQ29uZmlnUGFyc2UgKnBhcnNlLCBjb25zdCBGY0NoYXI4ICpuYW1lLCBGY0NvbmZpZyAqY29uZmlnLCBYTUxfUGFyc2VyIHBhcnNlcikKewogICAgcGFyc2UtPnBzdGFjayA9IDA7CiAgICBwYXJzZS0+dnN0YWNrID0gMDsKICAgIHBhcnNlLT5lcnJvciA9IEZjRmFsc2U7CiAgICBwYXJzZS0+bmFtZSA9IG5hbWU7CiAgICBwYXJzZS0+Y29uZmlnID0gY29uZmlnOwogICAgcGFyc2UtPnBhcnNlciA9IHBhcnNlcjsKICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyB2b2lkCkZjQ29uZmlnQ2xlYW51cCAoRmNDb25maWdQYXJzZQkqcGFyc2UpCnsKICAgIHdoaWxlIChwYXJzZS0+cHN0YWNrKQoJRmNQU3RhY2tQb3AgKHBhcnNlKTsKfQoKc3RhdGljIGNvbnN0IEZjQ2hhcjggKgpGY0NvbmZpZ0dldEF0dHJpYnV0ZSAoRmNDb25maWdQYXJzZSAqcGFyc2UsIGNoYXIgKmF0dHIpCnsKICAgIEZjQ2hhcjggKiphdHRyczsKICAgIGlmICghcGFyc2UtPnBzdGFjaykKCXJldHVybiAwOwoKICAgIGF0dHJzID0gcGFyc2UtPnBzdGFjay0+YXR0cjsKICAgIHdoaWxlICgqYXR0cnMpCiAgICB7CglpZiAoIXN0cmNtcCAoKGNoYXIgKikgKmF0dHJzLCBhdHRyKSkKCSAgICByZXR1cm4gYXR0cnNbMV07CglhdHRycyArPSAyOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkCkZjU3RhcnRFbGVtZW50KHZvaWQgKnVzZXJEYXRhLCBjb25zdCBYTUxfQ2hhciAqbmFtZSwgY29uc3QgWE1MX0NoYXIgKiphdHRyKQp7CiAgICBGY0NvbmZpZ1BhcnNlICAgKnBhcnNlID0gdXNlckRhdGE7CiAgICBGY0VsZW1lbnQJICAgIGVsZW1lbnQ7CiAgICAKICAgIGVsZW1lbnQgPSBGY0VsZW1lbnRNYXAgKG5hbWUpOwogICAgaWYgKGVsZW1lbnQgPT0gRmNFbGVtZW50VW5rbm93bikKCUZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlV2FybmluZywgInVua25vd24gZWxlbWVudCBcIiVzXCIiLCBuYW1lKTsKICAgIAogICAgaWYgKCFGY1BTdGFja1B1c2ggKHBhcnNlLCBlbGVtZW50LCBhdHRyKSkKICAgIHsKCUZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlRXJyb3IsICJvdXQgb2YgbWVtb3J5Iik7CglyZXR1cm47CiAgICB9CiAgICByZXR1cm47Cn0KCnN0YXRpYyB2b2lkCkZjUGFyc2VCbGFuayAoRmNDb25maWdQYXJzZSAqcGFyc2UpCnsKICAgIGludAkgICAgbiA9IEZjVlN0YWNrRWxlbWVudHMgKHBhcnNlKTsKICAgIHdoaWxlIChuLS0gPiAwKQogICAgewoJRmNWU3RhY2sgICAgKnYgPSBGY1ZTdGFja0ZldGNoIChwYXJzZSwgbik7CglpZiAodi0+dGFnICE9IEZjVlN0YWNrSW50ZWdlcikKCSAgICBGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZUVycm9yLCAibm9uLWludGVnZXIgYmxhbmsiKTsKCWVsc2UKCXsKCSAgICBpZiAoIXBhcnNlLT5jb25maWctPmJsYW5rcykKCSAgICB7CgkJcGFyc2UtPmNvbmZpZy0+YmxhbmtzID0gRmNCbGFua3NDcmVhdGUgKCk7CgkJaWYgKCFwYXJzZS0+Y29uZmlnLT5ibGFua3MpCgkJewoJCSAgICBGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZUVycm9yLCAib3V0IG9mIG1lbW9yeSIpOwoJCSAgICBicmVhazsKCQl9CgkgICAgfQoJICAgIGlmICghRmNCbGFua3NBZGQgKHBhcnNlLT5jb25maWctPmJsYW5rcywgdi0+dS5pbnRlZ2VyKSkKCSAgICB7CgkJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVFcnJvciwgIm91dCBvZiBtZW1vcnkiKTsKCQlicmVhazsKCSAgICB9Cgl9CiAgICB9Cn0KCnN0YXRpYyB2b2lkCkZjUGFyc2VSZXNjYW4gKEZjQ29uZmlnUGFyc2UgKnBhcnNlKQp7CiAgICBpbnQJICAgIG4gPSBGY1ZTdGFja0VsZW1lbnRzIChwYXJzZSk7CiAgICB3aGlsZSAobi0tID4gMCkKICAgIHsKCUZjVlN0YWNrICAgICp2ID0gRmNWU3RhY2tGZXRjaCAocGFyc2UsIG4pOwoJaWYgKHYtPnRhZyAhPSBGY1ZTdGFja0ludGVnZXIpCgkgICAgRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVXYXJuaW5nLCAibm9uLWludGVnZXIgcmVzY2FuIik7CgllbHNlCgkgICAgcGFyc2UtPmNvbmZpZy0+cmVzY2FuSW50ZXJ2YWwgPSB2LT51LmludGVnZXI7CiAgICB9Cn0KCnN0YXRpYyB2b2lkCkZjUGFyc2VJbnQgKEZjQ29uZmlnUGFyc2UgKnBhcnNlKQp7CiAgICBGY0NoYXI4ICpzLCAqZW5kOwogICAgaW50CSAgICBsOwogICAgCiAgICBpZiAoIXBhcnNlLT5wc3RhY2spCglyZXR1cm47CiAgICBzID0gRmNTdHJCdWZEb25lICgmcGFyc2UtPnBzdGFjay0+c3RyKTsKICAgIGlmICghcykKICAgIHsKCUZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlRXJyb3IsICJvdXQgb2YgbWVtb3J5Iik7CglyZXR1cm47CiAgICB9CiAgICBlbmQgPSAwOwogICAgbCA9IChpbnQpIHN0cnRvbCAoKGNoYXIgKikgcywgKGNoYXIgKiopJmVuZCwgMCk7CiAgICBpZiAoZW5kICE9IHMgKyBzdHJsZW4gKChjaGFyICopIHMpKQoJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVFcnJvciwgIlwiJXNcIjogbm90IGEgdmFsaWQgaW50ZWdlciIsIHMpOwogICAgZWxzZQoJRmNWU3RhY2tQdXNoSW50ZWdlciAocGFyc2UsIGwpOwogICAgRmNTdHJGcmVlIChzKTsKfQoKLyoKICogaWRlYSBjb3BpZWQgZnJvbSBnbGliIGdfYXNjaWlfc3RydG9kIHdpdGggCiAqIHBlcm1pc3Npb24gb2YgdGhlIGF1dGhvciAoQWxleGFuZGVyIExhcnNzb24pIAogKi8KCiNpbmNsdWRlIDxsb2NhbGUuaD4KCnN0YXRpYyBkb3VibGUgCkZjU3RydG9kIChjaGFyICpzLCBjaGFyICoqZW5kKQp7CiAgICBzdHJ1Y3QgbGNvbnYgICAgKmxvY2FsZV9kYXRhOwogICAgY2hhcgkgICAgKmRvdDsKICAgIGRvdWJsZQkgICAgdjsKCiAgICAvKgogICAgICogSGF2ZSB0byBzd2FwIHRoZSBkZWNpbWFsIHBvaW50IHRvIG1hdGNoIHRoZSBjdXJyZW50IGxvY2FsZQogICAgICogaWYgdGhhdCBsb2NhbGUgZG9lc24ndCB1c2UgMHgyZQogICAgICovCiAgICBpZiAoKGRvdCA9IHN0cmNociAocywgMHgyZSkpICYmCgkobG9jYWxlX2RhdGEgPSBsb2NhbGVjb252ICgpKSAmJgoJKGxvY2FsZV9kYXRhLT5kZWNpbWFsX3BvaW50WzBdICE9IDB4MmUgfHwKCSBsb2NhbGVfZGF0YS0+ZGVjaW1hbF9wb2ludFsxXSAhPSAwKSkKICAgIHsKCWNoYXIJYnVmWzEyOF07CglpbnQJc2xlbiA9IHN0cmxlbiAocyk7CglpbnQJZGxlbiA9IHN0cmxlbiAobG9jYWxlX2RhdGEtPmRlY2ltYWxfcG9pbnQpOwoJCglpZiAoc2xlbiArIGRsZW4gPiBzaXplb2YgKGJ1ZikpCgl7CgkgICAgaWYgKGVuZCkKCQkqZW5kID0gczsKCSAgICB2ID0gMDsKCX0KCWVsc2UKCXsKCSAgICBjaGFyCSpidWZfZW5kOwoJICAgIC8qIG1hbnRpc3NhICovCgkgICAgc3RybmNweSAoYnVmLCBzLCBkb3QgLSBzKTsKCSAgICAvKiBkZWNpbWFsIHBvaW50ICovCgkgICAgc3RyY3B5IChidWYgKyAoZG90IC0gcyksIGxvY2FsZV9kYXRhLT5kZWNpbWFsX3BvaW50KTsKCSAgICAvKiByZXN0IG9mIG51bWJlciAqLwoJICAgIHN0cmNweSAoYnVmICsgKGRvdCAtIHMpICsgZGxlbiwgZG90ICsgMSk7CgkgICAgYnVmX2VuZCA9IDA7CgkgICAgdiA9IHN0cnRvZCAoYnVmLCAmYnVmX2VuZCk7CgkgICAgaWYgKGJ1Zl9lbmQpCgkJYnVmX2VuZCA9IHMgKyAoYnVmX2VuZCAtIGJ1ZikgKyAxIC0gZGxlbjsKCSAgICBpZiAoZW5kKQoJCSplbmQgPSBidWZfZW5kOwoJfQogICAgfQogICAgZWxzZQoJdiA9IHN0cnRvZCAocywgZW5kKTsKICAgIHJldHVybiB2Owp9CgpzdGF0aWMgdm9pZApGY1BhcnNlRG91YmxlIChGY0NvbmZpZ1BhcnNlICpwYXJzZSkKewogICAgRmNDaGFyOCAqcywgKmVuZDsKICAgIGRvdWJsZSAgZDsKICAgIAogICAgaWYgKCFwYXJzZS0+cHN0YWNrKQoJcmV0dXJuOwogICAgcyA9IEZjU3RyQnVmRG9uZSAoJnBhcnNlLT5wc3RhY2stPnN0cik7CiAgICBpZiAoIXMpCiAgICB7CglGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZUVycm9yLCAib3V0IG9mIG1lbW9yeSIpOwoJcmV0dXJuOwogICAgfQogICAgZW5kID0gMDsKICAgIGQgPSBGY1N0cnRvZCAoKGNoYXIgKikgcywgKGNoYXIgKiopJmVuZCk7CiAgICBpZiAoZW5kICE9IHMgKyBzdHJsZW4gKChjaGFyICopIHMpKQoJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVFcnJvciwgIlwiJXNcIjogbm90IGEgdmFsaWQgZG91YmxlIiwgcyk7CiAgICBlbHNlCglGY1ZTdGFja1B1c2hEb3VibGUgKHBhcnNlLCBkKTsKICAgIEZjU3RyRnJlZSAocyk7Cn0KCnN0YXRpYyB2b2lkCkZjUGFyc2VTdHJpbmcgKEZjQ29uZmlnUGFyc2UgKnBhcnNlLCBGY1ZTdGFja1RhZyB0YWcpCnsKICAgIEZjQ2hhcjggKnM7CiAgICAKICAgIGlmICghcGFyc2UtPnBzdGFjaykKCXJldHVybjsKICAgIHMgPSBGY1N0ckJ1ZkRvbmUgKCZwYXJzZS0+cHN0YWNrLT5zdHIpOwogICAgaWYgKCFzKQogICAgewoJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVFcnJvciwgIm91dCBvZiBtZW1vcnkiKTsKCXJldHVybjsKICAgIH0KICAgIGlmICghRmNWU3RhY2tQdXNoU3RyaW5nIChwYXJzZSwgdGFnLCBzKSkKCUZjU3RyRnJlZSAocyk7Cn0KCnN0YXRpYyB2b2lkCkZjUGFyc2VNYXRyaXggKEZjQ29uZmlnUGFyc2UgKnBhcnNlKQp7CiAgICBGY1ZTdGFjawkqdnN0YWNrOwogICAgZW51bSB7IG1fZG9uZSwgbV94eCwgbV94eSwgbV95eCwgbV95eSB9IG1hdHJpeF9zdGF0ZSA9IG1feXk7CiAgICBGY01hdHJpeAltOwogICAgCiAgICB3aGlsZSAoKHZzdGFjayA9IEZjVlN0YWNrUG9wIChwYXJzZSkpKQogICAgewoJZG91YmxlCXY7Cglzd2l0Y2ggKHZzdGFjay0+dGFnKSB7CgljYXNlIEZjVlN0YWNrSW50ZWdlcjoKCSAgICB2ID0gdnN0YWNrLT51LmludGVnZXI7CgkgICAgYnJlYWs7CgljYXNlIEZjVlN0YWNrRG91YmxlOgoJICAgIHYgPSB2c3RhY2stPnUuX2RvdWJsZTsKCSAgICBicmVhazsKCWRlZmF1bHQ6CgkgICAgRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVFcnJvciwgIm5vbi1kb3VibGUgbWF0cml4IGVsZW1lbnQiKTsKCSAgICB2ID0gMS4wOwoJICAgIGJyZWFrOwoJfQoJc3dpdGNoIChtYXRyaXhfc3RhdGUpIHsKCWNhc2UgbV94eDogbS54eCA9IHY7IGJyZWFrOwoJY2FzZSBtX3h5OiBtLnh5ID0gdjsgYnJlYWs7CgljYXNlIG1feXg6IG0ueXggPSB2OyBicmVhazsKCWNhc2UgbV95eTogbS55eSA9IHY7IGJyZWFrOwoJZGVmYXVsdDogYnJlYWs7Cgl9CglGY1ZTdGFja0Rlc3Ryb3kgKHZzdGFjayk7CgltYXRyaXhfc3RhdGUtLTsKICAgIH0KICAgIGlmIChtYXRyaXhfc3RhdGUgIT0gbV9kb25lKQoJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVFcnJvciwgIndyb25nIG51bWJlciBvZiBtYXRyaXggZWxlbWVudHMiKTsKICAgIGVsc2UKCUZjVlN0YWNrUHVzaE1hdHJpeCAocGFyc2UsICZtKTsKfQoKc3RhdGljIEZjQm9vbApGY0NvbmZpZ0xleEJvb2wgKGNvbnN0IEZjQ2hhcjggKmJvb2wpCnsKICAgIGlmICgqYm9vbCA9PSAndCcgfHwgKmJvb2wgPT0gJ1QnKQoJcmV0dXJuIEZjVHJ1ZTsKICAgIGlmICgqYm9vbCA9PSAneScgfHwgKmJvb2wgPT0gJ1knKQoJcmV0dXJuIEZjVHJ1ZTsKICAgIGlmICgqYm9vbCA9PSAnMScpCglyZXR1cm4gRmNUcnVlOwogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCnN0YXRpYyB2b2lkCkZjUGFyc2VCb29sIChGY0NvbmZpZ1BhcnNlICpwYXJzZSkKewogICAgRmNDaGFyOCAqczsKCiAgICBpZiAoIXBhcnNlLT5wc3RhY2spCglyZXR1cm47CiAgICBzID0gRmNTdHJCdWZEb25lICgmcGFyc2UtPnBzdGFjay0+c3RyKTsKICAgIGlmICghcykKICAgIHsKCUZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlRXJyb3IsICJvdXQgb2YgbWVtb3J5Iik7CglyZXR1cm47CiAgICB9CiAgICBGY1ZTdGFja1B1c2hCb29sIChwYXJzZSwgRmNDb25maWdMZXhCb29sIChzKSk7CiAgICBGY1N0ckZyZWUgKHMpOwp9CgpzdGF0aWMgdm9pZApGY1BhcnNlRmFtaWxpZXMgKEZjQ29uZmlnUGFyc2UgKnBhcnNlLCBGY1ZTdGFja1RhZyB0YWcpCnsKICAgIEZjVlN0YWNrCSp2c3RhY2s7CiAgICBGY0V4cHIJKmxlZnQsICpleHByID0gMCwgKm5ldzsKCiAgICB3aGlsZSAoKHZzdGFjayA9IEZjVlN0YWNrUG9wIChwYXJzZSkpKQogICAgewoJaWYgKHZzdGFjay0+dGFnICE9IEZjVlN0YWNrRmFtaWx5KQoJewoJICAgIEZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlV2FybmluZywgIm5vbi1mYW1pbHkiKTsKCSAgICBGY1ZTdGFja0Rlc3Ryb3kgKHZzdGFjayk7CgkgICAgY29udGludWU7Cgl9CglsZWZ0ID0gdnN0YWNrLT51LmV4cHI7Cgl2c3RhY2stPnRhZyA9IEZjVlN0YWNrTm9uZTsKCUZjVlN0YWNrRGVzdHJveSAodnN0YWNrKTsKCWlmIChleHByKQoJewoJICAgIG5ldyA9IEZjRXhwckNyZWF0ZU9wIChsZWZ0LCBGY09wQ29tbWEsIGV4cHIpOwoJICAgIGlmICghbmV3KQoJICAgIHsKCQlGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZUVycm9yLCAib3V0IG9mIG1lbW9yeSIpOwoJCUZjRXhwckRlc3Ryb3kgKGxlZnQpOwoJCUZjRXhwckRlc3Ryb3kgKGV4cHIpOwoJCWJyZWFrOwoJICAgIH0KCSAgICBleHByID0gbmV3OwoJfQoJZWxzZQoJICAgIGV4cHIgPSBsZWZ0OwogICAgfQogICAgaWYgKGV4cHIpCiAgICB7CglpZiAoIUZjVlN0YWNrUHVzaEV4cHIgKHBhcnNlLCB0YWcsIGV4cHIpKQoJewoJICAgIEZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlRXJyb3IsICJvdXQgb2YgbWVtb3J5Iik7CgkgICAgaWYgKGV4cHIpCgkJRmNFeHByRGVzdHJveSAoZXhwcik7Cgl9CiAgICB9Cn0KCnN0YXRpYyB2b2lkCkZjUGFyc2VGYW1pbHkgKEZjQ29uZmlnUGFyc2UgKnBhcnNlKQp7CiAgICBGY0NoYXI4ICpzOwogICAgRmNFeHByICAqZXhwcjsKCiAgICBpZiAoIXBhcnNlLT5wc3RhY2spCglyZXR1cm47CiAgICBzID0gRmNTdHJCdWZEb25lICgmcGFyc2UtPnBzdGFjay0+c3RyKTsKICAgIGlmICghcykKICAgIHsKCUZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlRXJyb3IsICJvdXQgb2YgbWVtb3J5Iik7CglyZXR1cm47CiAgICB9CiAgICBleHByID0gRmNFeHByQ3JlYXRlU3RyaW5nIChzKTsKICAgIEZjU3RyRnJlZSAocyk7CiAgICBpZiAoZXhwcikKCUZjVlN0YWNrUHVzaEV4cHIgKHBhcnNlLCBGY1ZTdGFja0ZhbWlseSwgZXhwcik7Cn0KCnN0YXRpYyB2b2lkCkZjUGFyc2VBbGlhcyAoRmNDb25maWdQYXJzZSAqcGFyc2UpCnsKICAgIEZjRXhwcgkqZmFtaWx5ID0gMCwgKmFjY2VwdCA9IDAsICpwcmVmZXIgPSAwLCAqZGVmID0gMCwgKm5ldyA9IDA7CiAgICBGY0VkaXQJKmVkaXQgPSAwLCAqbmV4dDsKICAgIEZjVlN0YWNrCSp2c3RhY2s7CiAgICBGY1Rlc3QJKnRlc3Q7CgogICAgd2hpbGUgKCh2c3RhY2sgPSBGY1ZTdGFja1BvcCAocGFyc2UpKSkgCiAgICB7Cglzd2l0Y2ggKHZzdGFjay0+dGFnKSB7CgljYXNlIEZjVlN0YWNrRmFtaWx5OgoJICAgIGlmIChmYW1pbHkpCgkgICAgewoJCW5ldyA9IEZjRXhwckNyZWF0ZU9wICh2c3RhY2stPnUuZXhwciwgRmNPcENvbW1hLCBmYW1pbHkpOwoJCWlmICghbmV3KQoJCSAgICBGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZUVycm9yLCAib3V0IG9mIG1lbW9yeSIpOwoJCWVsc2UKCQkgICAgZmFtaWx5ID0gbmV3OwoJICAgIH0KCSAgICBlbHNlCgkJbmV3ID0gdnN0YWNrLT51LmV4cHI7CgkgICAgaWYgKG5ldykKCSAgICB7CgkJZmFtaWx5ID0gbmV3OwoJCXZzdGFjay0+dGFnID0gRmNWU3RhY2tOb25lOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgRmNWU3RhY2tQcmVmZXI6CgkgICAgaWYgKHByZWZlcikKCQlGY0V4cHJEZXN0cm95IChwcmVmZXIpOwoJICAgIHByZWZlciA9IHZzdGFjay0+dS5leHByOwoJICAgIHZzdGFjay0+dGFnID0gRmNWU3RhY2tOb25lOwoJICAgIGJyZWFrOwoJY2FzZSBGY1ZTdGFja0FjY2VwdDoKCSAgICBpZiAoYWNjZXB0KQoJCUZjRXhwckRlc3Ryb3kgKGFjY2VwdCk7CgkgICAgYWNjZXB0ID0gdnN0YWNrLT51LmV4cHI7CgkgICAgdnN0YWNrLT50YWcgPSBGY1ZTdGFja05vbmU7CgkgICAgYnJlYWs7CgljYXNlIEZjVlN0YWNrRGVmYXVsdDoKCSAgICBpZiAoZGVmKQoJCUZjRXhwckRlc3Ryb3kgKGRlZik7CgkgICAgZGVmID0gdnN0YWNrLT51LmV4cHI7CgkgICAgdnN0YWNrLT50YWcgPSBGY1ZTdGFja05vbmU7CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIEZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlV2FybmluZywgImJhZCBhbGlhcyIpOwoJICAgIGJyZWFrOwoJfQoJRmNWU3RhY2tEZXN0cm95ICh2c3RhY2spOwogICAgfQogICAgaWYgKCFmYW1pbHkpCiAgICB7CglGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZUVycm9yLCAibWlzc2luZyBmYW1pbHkgaW4gYWxpYXMiKTsKCWlmIChwcmVmZXIpCgkgICAgRmNFeHByRGVzdHJveSAocHJlZmVyKTsKCWlmIChhY2NlcHQpCgkgICAgRmNFeHByRGVzdHJveSAoYWNjZXB0KTsKCWlmIChkZWYpCgkgICAgRmNFeHByRGVzdHJveSAoZGVmKTsKCXJldHVybjsKICAgIH0KICAgIGlmIChwcmVmZXIpCiAgICB7CgllZGl0ID0gRmNFZGl0Q3JlYXRlIChGY0NvbmZpZ1NhdmVGaWVsZCAoImZhbWlseSIpLAoJCQkgICAgIEZjT3BQcmVwZW5kLAoJCQkgICAgIHByZWZlciwKCQkJICAgICBGY1ZhbHVlQmluZGluZ1dlYWspOwoJaWYgKGVkaXQpCgkgICAgZWRpdC0+bmV4dCA9IDA7CgllbHNlCgkgICAgRmNFeHByRGVzdHJveSAocHJlZmVyKTsKICAgIH0KICAgIGlmIChhY2NlcHQpCiAgICB7CgluZXh0ID0gZWRpdDsKCWVkaXQgPSBGY0VkaXRDcmVhdGUgKEZjQ29uZmlnU2F2ZUZpZWxkICgiZmFtaWx5IiksCgkJCSAgICAgRmNPcEFwcGVuZCwKCQkJICAgICBhY2NlcHQsCgkJCSAgICAgRmNWYWx1ZUJpbmRpbmdXZWFrKTsKCWlmIChlZGl0KQoJICAgIGVkaXQtPm5leHQgPSBuZXh0OwoJZWxzZQoJICAgIEZjRXhwckRlc3Ryb3kgKGFjY2VwdCk7CiAgICB9CiAgICBpZiAoZGVmKQogICAgewoJbmV4dCA9IGVkaXQ7CgllZGl0ID0gRmNFZGl0Q3JlYXRlIChGY0NvbmZpZ1NhdmVGaWVsZCAoImZhbWlseSIpLAoJCQkgICAgIEZjT3BBcHBlbmRMYXN0LAoJCQkgICAgIGRlZiwKCQkJICAgICBGY1ZhbHVlQmluZGluZ1dlYWspOwoJaWYgKGVkaXQpCgkgICAgZWRpdC0+bmV4dCA9IG5leHQ7CgllbHNlCgkgICAgRmNFeHByRGVzdHJveSAoZGVmKTsKICAgIH0KICAgIGlmIChlZGl0KQogICAgewoJdGVzdCA9IEZjVGVzdENyZWF0ZSAoRmNNYXRjaFBhdHRlcm4sCgkJCSAgICAgRmNRdWFsQW55LAoJCQkgICAgIChGY0NoYXI4ICopIEZDX0ZBTUlMWSwKCQkJICAgICBGY09wRXF1YWwsCgkJCSAgICAgZmFtaWx5KTsKCWlmICh0ZXN0KQoJICAgIGlmICghRmNDb25maWdBZGRFZGl0IChwYXJzZS0+Y29uZmlnLCB0ZXN0LCBlZGl0LCBGY01hdGNoUGF0dGVybikpCgkJRmNUZXN0RGVzdHJveSAodGVzdCk7CiAgICB9CiAgICBlbHNlCglGY0V4cHJEZXN0cm95IChmYW1pbHkpOwp9CgpzdGF0aWMgRmNFeHByICoKRmNQb3BFeHByIChGY0NvbmZpZ1BhcnNlICpwYXJzZSkKewogICAgRmNWU3RhY2sJKnZzdGFjayA9IEZjVlN0YWNrUG9wIChwYXJzZSk7CiAgICBGY0V4cHIJKmV4cHIgPSAwOwogICAgaWYgKCF2c3RhY2spCglyZXR1cm4gMDsKICAgIHN3aXRjaCAodnN0YWNrLT50YWcpIHsKICAgIGNhc2UgRmNWU3RhY2tOb25lOgoJYnJlYWs7CiAgICBjYXNlIEZjVlN0YWNrU3RyaW5nOgogICAgY2FzZSBGY1ZTdGFja0ZhbWlseToKCWV4cHIgPSBGY0V4cHJDcmVhdGVTdHJpbmcgKHZzdGFjay0+dS5zdHJpbmcpOwoJYnJlYWs7CiAgICBjYXNlIEZjVlN0YWNrRmllbGQ6CglleHByID0gRmNFeHByQ3JlYXRlRmllbGQgKChjaGFyICopIHZzdGFjay0+dS5zdHJpbmcpOwoJYnJlYWs7CiAgICBjYXNlIEZjVlN0YWNrQ29uc3RhbnQ6CglleHByID0gRmNFeHByQ3JlYXRlQ29uc3QgKHZzdGFjay0+dS5zdHJpbmcpOwoJYnJlYWs7CiAgICBjYXNlIEZjVlN0YWNrR2xvYjoKCS8qIFhYWDogV2hhdCdzIHRoZSBjb3JyZWN0IGFjdGlvbiBoZXJlPyAoQ0RXKSAqLwoJYnJlYWs7CiAgICBjYXNlIEZjVlN0YWNrUHJlZmVyOgogICAgY2FzZSBGY1ZTdGFja0FjY2VwdDoKICAgIGNhc2UgRmNWU3RhY2tEZWZhdWx0OgoJZXhwciA9IHZzdGFjay0+dS5leHByOwoJdnN0YWNrLT50YWcgPSBGY1ZTdGFja05vbmU7CglicmVhazsKICAgIGNhc2UgRmNWU3RhY2tJbnRlZ2VyOgoJZXhwciA9IEZjRXhwckNyZWF0ZUludGVnZXIgKHZzdGFjay0+dS5pbnRlZ2VyKTsKCWJyZWFrOwogICAgY2FzZSBGY1ZTdGFja0RvdWJsZToKCWV4cHIgPSBGY0V4cHJDcmVhdGVEb3VibGUgKHZzdGFjay0+dS5fZG91YmxlKTsKCWJyZWFrOwogICAgY2FzZSBGY1ZTdGFja01hdHJpeDoKCWV4cHIgPSBGY0V4cHJDcmVhdGVNYXRyaXggKHZzdGFjay0+dS5tYXRyaXgpOwoJYnJlYWs7CiAgICBjYXNlIEZjVlN0YWNrQm9vbDoKCWV4cHIgPSBGY0V4cHJDcmVhdGVCb29sICh2c3RhY2stPnUuYm9vbCk7CglicmVhazsKICAgIGNhc2UgRmNWU3RhY2tUZXN0OgoJYnJlYWs7CiAgICBjYXNlIEZjVlN0YWNrRXhwcjoKCWV4cHIgPSB2c3RhY2stPnUuZXhwcjsKCXZzdGFjay0+dGFnID0gRmNWU3RhY2tOb25lOwoJYnJlYWs7CiAgICBjYXNlIEZjVlN0YWNrRWRpdDoKCWJyZWFrOwogICAgfQogICAgRmNWU3RhY2tEZXN0cm95ICh2c3RhY2spOwogICAgcmV0dXJuIGV4cHI7Cn0KCi8qCiAqIFRoaXMgYnVpbGRzIGEgdHJlZSBvZiBiaW5hcnkgb3BlcmF0aW9ucy4gIE5vdGUKICogdGhhdCBldmVyeSBvcGVyYXRvciBpcyBkZWZpbmVkIHNvIHRoYXQgaWYgb25seQogKiBhIHNpbmdsZSBvcGVyYW5kIGlzIGNvbnRhaW5lZCwgdGhlIHZhbHVlIG9mIHRoZQogKiB3aG9sZSBleHByZXNzaW9uIGlzIHRoZSB2YWx1ZSBvZiB0aGUgb3BlcmFuZC4KICoKICogVGhpcyBjb2RlIHJlZHVjZXMgaW4gdGhhdCBjYXNlIHRvIHJldHVybmluZyB0aGF0CiAqIG9wZXJhbmQuCiAqLwpzdGF0aWMgRmNFeHByICoKRmNQb3BCaW5hcnkgKEZjQ29uZmlnUGFyc2UgKnBhcnNlLCBGY09wIG9wKQp7CiAgICBGY0V4cHIgICpsZWZ0LCAqZXhwciA9IDAsICpuZXc7CgogICAgd2hpbGUgKChsZWZ0ID0gRmNQb3BFeHByIChwYXJzZSkpKQogICAgewoJaWYgKGV4cHIpCgl7CgkgICAgbmV3ID0gRmNFeHByQ3JlYXRlT3AgKGxlZnQsIG9wLCBleHByKTsKCSAgICBpZiAoIW5ldykKCSAgICB7CgkJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVFcnJvciwgIm91dCBvZiBtZW1vcnkiKTsKCQlGY0V4cHJEZXN0cm95IChsZWZ0KTsKCQlGY0V4cHJEZXN0cm95IChleHByKTsKCQlicmVhazsKCSAgICB9CgkgICAgZXhwciA9IG5ldzsKCX0KCWVsc2UKCSAgICBleHByID0gbGVmdDsKICAgIH0KICAgIHJldHVybiBleHByOwp9CgpzdGF0aWMgdm9pZApGY1BhcnNlQmluYXJ5IChGY0NvbmZpZ1BhcnNlICpwYXJzZSwgRmNPcCBvcCkKewogICAgRmNFeHByICAqZXhwciA9IEZjUG9wQmluYXJ5IChwYXJzZSwgb3ApOwogICAgaWYgKGV4cHIpCglGY1ZTdGFja1B1c2hFeHByIChwYXJzZSwgRmNWU3RhY2tFeHByLCBleHByKTsKfQoKLyoKICogVGhpcyBidWlsZHMgYSBhIHVuYXJ5IG9wZXJhdG9yLCBpdCBjb25zdW1lcyBvbmx5CiAqIGEgc2luZ2xlIG9wZXJhbmQKICovCgpzdGF0aWMgRmNFeHByICoKRmNQb3BVbmFyeSAoRmNDb25maWdQYXJzZSAqcGFyc2UsIEZjT3Agb3ApCnsKICAgIEZjRXhwciAgKm9wZXJhbmQsICpuZXcgPSAwOwoKICAgIGlmICgob3BlcmFuZCA9IEZjUG9wRXhwciAocGFyc2UpKSkKICAgIHsKCW5ldyA9IEZjRXhwckNyZWF0ZU9wIChvcGVyYW5kLCBvcCwgMCk7CglpZiAoIW5ldykKCXsKCSAgICBGY0V4cHJEZXN0cm95IChvcGVyYW5kKTsKCSAgICBGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZUVycm9yLCAib3V0IG9mIG1lbW9yeSIpOwoJfQogICAgfQogICAgcmV0dXJuIG5ldzsKfQoKc3RhdGljIHZvaWQKRmNQYXJzZVVuYXJ5IChGY0NvbmZpZ1BhcnNlICpwYXJzZSwgRmNPcCBvcCkKewogICAgRmNFeHByICAqZXhwciA9IEZjUG9wVW5hcnkgKHBhcnNlLCBvcCk7CiAgICBpZiAoZXhwcikKCUZjVlN0YWNrUHVzaEV4cHIgKHBhcnNlLCBGY1ZTdGFja0V4cHIsIGV4cHIpOwp9CgpzdGF0aWMgdm9pZApGY1BhcnNlSW5jbHVkZSAoRmNDb25maWdQYXJzZSAqcGFyc2UpCnsKICAgIEZjQ2hhcjgJICAgICpzOwogICAgY29uc3QgRmNDaGFyOCAgICppOwogICAgRmNCb29sCSAgICBpZ25vcmVfbWlzc2luZyA9IEZjRmFsc2U7CiAgICAKICAgIHMgPSBGY1N0ckJ1ZkRvbmUgKCZwYXJzZS0+cHN0YWNrLT5zdHIpOwogICAgaWYgKCFzKQogICAgewoJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVFcnJvciwgIm91dCBvZiBtZW1vcnkiKTsKCXJldHVybjsKICAgIH0KICAgIGkgPSBGY0NvbmZpZ0dldEF0dHJpYnV0ZSAocGFyc2UsICJpZ25vcmVfbWlzc2luZyIpOwogICAgaWYgKGkgJiYgRmNDb25maWdMZXhCb29sICgoRmNDaGFyOCAqKSBpKSA9PSBGY1RydWUpCglpZ25vcmVfbWlzc2luZyA9IEZjVHJ1ZTsKICAgIGlmICghRmNDb25maWdQYXJzZUFuZExvYWQgKHBhcnNlLT5jb25maWcsIHMsICFpZ25vcmVfbWlzc2luZykpCglwYXJzZS0+ZXJyb3IgPSBGY1RydWU7CiAgICBGY1N0ckZyZWUgKHMpOwp9Cgp0eXBlZGVmIHN0cnVjdCBfRmNPcE1hcCB7CiAgICBjaGFyICAgICpuYW1lOwogICAgRmNPcCAgICBvcDsKfSBGY09wTWFwOwoKc3RhdGljIEZjT3AKRmNDb25maWdMZXhPcCAoY29uc3QgRmNDaGFyOCAqb3AsIGNvbnN0IEZjT3BNYXAJKm1hcCwgaW50IG5tYXApCnsKICAgIGludAlpOwoKICAgIGZvciAoaSA9IDA7IGkgPCBubWFwOyBpKyspCglpZiAoIXN0cmNtcCAoKGNoYXIgKikgb3AsIG1hcFtpXS5uYW1lKSkgCgkgICAgcmV0dXJuIG1hcFtpXS5vcDsKICAgIHJldHVybiBGY09wSW52YWxpZDsKfQoKc3RhdGljIGNvbnN0IEZjT3BNYXAgZmNDb21wYXJlT3BzW10gPSB7CiAgICB7ICJlcSIsCQlGY09wRXF1YWwJICAgIH0sCiAgICB7ICJub3RfZXEiLAkJRmNPcE5vdEVxdWFsCSAgICB9LAogICAgeyAibGVzcyIsCQlGY09wTGVzcwkgICAgfSwKICAgIHsgImxlc3NfZXEiLAlGY09wTGVzc0VxdWFsCSAgICB9LAogICAgeyAibW9yZSIsCQlGY09wTW9yZQkgICAgfSwKICAgIHsgIm1vcmVfZXEiLAlGY09wTW9yZUVxdWFsCSAgICB9LAogICAgeyAiY29udGFpbnMiLAlGY09wQ29udGFpbnMJICAgIH0sCiAgICB7ICJub3RfY29udGFpbnMiLAlGY09wTm90Q29udGFpbnMJICAgIH0KfTsKCiNkZWZpbmUgTlVNX0NPTVBBUkVfT1BTIChzaXplb2YgZmNDb21wYXJlT3BzIC8gc2l6ZW9mIGZjQ29tcGFyZU9wc1swXSkKCnN0YXRpYyBGY09wCkZjQ29uZmlnTGV4Q29tcGFyZSAoY29uc3QgRmNDaGFyOCAqY29tcGFyZSkKewogICAgcmV0dXJuIEZjQ29uZmlnTGV4T3AgKGNvbXBhcmUsIGZjQ29tcGFyZU9wcywgTlVNX0NPTVBBUkVfT1BTKTsKfQoKCnN0YXRpYyB2b2lkCkZjUGFyc2VUZXN0IChGY0NvbmZpZ1BhcnNlICpwYXJzZSkKewogICAgY29uc3QgRmNDaGFyOCAgICpraW5kX3N0cmluZzsKICAgIEZjTWF0Y2hLaW5kCSAgICBraW5kOwogICAgY29uc3QgRmNDaGFyOCAgICpxdWFsX3N0cmluZzsKICAgIEZjUXVhbAkgICAgcXVhbDsKICAgIGNvbnN0IEZjQ2hhcjggICAqbmFtZTsKICAgIGNvbnN0IEZjQ2hhcjggICAqY29tcGFyZV9zdHJpbmc7CiAgICBGY09wCSAgICBjb21wYXJlOwogICAgRmNFeHByCSAgICAqZXhwcjsKICAgIEZjVGVzdAkgICAgKnRlc3Q7CgogICAga2luZF9zdHJpbmcgPSBGY0NvbmZpZ0dldEF0dHJpYnV0ZSAocGFyc2UsICJ0YXJnZXQiKTsKICAgIGlmICgha2luZF9zdHJpbmcpCglraW5kID0gRmNNYXRjaERlZmF1bHQ7CiAgICBlbHNlCiAgICB7CglpZiAoIXN0cmNtcCAoKGNoYXIgKikga2luZF9zdHJpbmcsICJwYXR0ZXJuIikpCgkgICAga2luZCA9IEZjTWF0Y2hQYXR0ZXJuOwoJZWxzZSBpZiAoIXN0cmNtcCAoKGNoYXIgKikga2luZF9zdHJpbmcsICJmb250IikpCgkgICAga2luZCA9IEZjTWF0Y2hGb250OwoJZWxzZSBpZiAoIXN0cmNtcCAoKGNoYXIgKikga2luZF9zdHJpbmcsICJkZWZhdWx0IikpCgkgICAga2luZCA9IEZjTWF0Y2hEZWZhdWx0OwoJZWxzZQoJewoJICAgIEZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlV2FybmluZywgImludmFsaWQgdGVzdCB0YXJnZXQgXCIlc1wiIiwga2luZF9zdHJpbmcpOwoJICAgIHJldHVybjsKCX0KICAgIH0KICAgIHF1YWxfc3RyaW5nID0gRmNDb25maWdHZXRBdHRyaWJ1dGUgKHBhcnNlLCAicXVhbCIpOwogICAgaWYgKCFxdWFsX3N0cmluZykKCXF1YWwgPSBGY1F1YWxBbnk7CiAgICBlbHNlCiAgICB7CglpZiAoIXN0cmNtcCAoKGNoYXIgKikgcXVhbF9zdHJpbmcsICJhbnkiKSkKCSAgICBxdWFsID0gRmNRdWFsQW55OwoJZWxzZSBpZiAoIXN0cmNtcCAoKGNoYXIgKikgcXVhbF9zdHJpbmcsICJhbGwiKSkKCSAgICBxdWFsID0gRmNRdWFsQWxsOwoJZWxzZSBpZiAoIXN0cmNtcCAoKGNoYXIgKikgcXVhbF9zdHJpbmcsICJmaXJzdCIpKQoJICAgIHF1YWwgPSBGY1F1YWxGaXJzdDsKCWVsc2UgaWYgKCFzdHJjbXAgKChjaGFyICopIHF1YWxfc3RyaW5nLCAibm90X2ZpcnN0IikpCgkgICAgcXVhbCA9IEZjUXVhbE5vdEZpcnN0OwoJZWxzZQoJewoJICAgIEZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlV2FybmluZywgImludmFsaWQgdGVzdCBxdWFsIFwiJXNcIiIsIHF1YWxfc3RyaW5nKTsKCSAgICByZXR1cm47Cgl9CiAgICB9CiAgICBuYW1lID0gRmNDb25maWdHZXRBdHRyaWJ1dGUgKHBhcnNlLCAibmFtZSIpOwogICAgaWYgKCFuYW1lKQogICAgewoJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVXYXJuaW5nLCAibWlzc2luZyB0ZXN0IG5hbWUiKTsKCXJldHVybjsKICAgIH0KICAgIGNvbXBhcmVfc3RyaW5nID0gRmNDb25maWdHZXRBdHRyaWJ1dGUgKHBhcnNlLCAiY29tcGFyZSIpOwogICAgaWYgKCFjb21wYXJlX3N0cmluZykKCWNvbXBhcmUgPSBGY09wRXF1YWw7CiAgICBlbHNlCiAgICB7Cgljb21wYXJlID0gRmNDb25maWdMZXhDb21wYXJlIChjb21wYXJlX3N0cmluZyk7CglpZiAoY29tcGFyZSA9PSBGY09wSW52YWxpZCkKCXsKCSAgICBGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZVdhcm5pbmcsICJpbnZhbGlkIHRlc3QgY29tcGFyZSBcIiVzXCIiLCBjb21wYXJlX3N0cmluZyk7CgkgICAgcmV0dXJuOwoJfQogICAgfQogICAgZXhwciA9IEZjUG9wQmluYXJ5IChwYXJzZSwgRmNPcENvbW1hKTsKICAgIGlmICghZXhwcikKICAgIHsKCUZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlV2FybmluZywgIm1pc3NpbmcgdGVzdCBleHByZXNzaW9uIik7CglyZXR1cm47CiAgICB9CiAgICB0ZXN0ID0gRmNUZXN0Q3JlYXRlIChraW5kLCBxdWFsLCBuYW1lLCBjb21wYXJlLCBleHByKTsKICAgIGlmICghdGVzdCkKICAgIHsKCUZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlRXJyb3IsICJvdXQgb2YgbWVtb3J5Iik7CglyZXR1cm47CiAgICB9CiAgICBGY1ZTdGFja1B1c2hUZXN0IChwYXJzZSwgdGVzdCk7Cn0KCnN0YXRpYyBjb25zdCBGY09wTWFwIGZjTW9kZU9wc1tdID0gewogICAgeyAiYXNzaWduIiwJCUZjT3BBc3NpZ24JICAgIH0sCiAgICB7ICJhc3NpZ25fcmVwbGFjZSIsCUZjT3BBc3NpZ25SZXBsYWNlICAgfSwKICAgIHsgInByZXBlbmQiLAlGY09wUHJlcGVuZAkgICAgfSwKICAgIHsgInByZXBlbmRfZmlyc3QiLAlGY09wUHJlcGVuZEZpcnN0ICAgIH0sCiAgICB7ICJhcHBlbmQiLAkJRmNPcEFwcGVuZAkgICAgfSwKICAgIHsgImFwcGVuZF9sYXN0IiwJRmNPcEFwcGVuZExhc3QJICAgIH0sCn07CgojZGVmaW5lIE5VTV9NT0RFX09QUyAoc2l6ZW9mIGZjTW9kZU9wcyAvIHNpemVvZiBmY01vZGVPcHNbMF0pCgpzdGF0aWMgRmNPcApGY0NvbmZpZ0xleE1vZGUgKGNvbnN0IEZjQ2hhcjggKm1vZGUpCnsKICAgIHJldHVybiBGY0NvbmZpZ0xleE9wIChtb2RlLCBmY01vZGVPcHMsIE5VTV9NT0RFX09QUyk7Cn0KCnN0YXRpYyB2b2lkCkZjUGFyc2VFZGl0IChGY0NvbmZpZ1BhcnNlICpwYXJzZSkKewogICAgY29uc3QgRmNDaGFyOCAgICpuYW1lOwogICAgY29uc3QgRmNDaGFyOCAgICptb2RlX3N0cmluZzsKICAgIGNvbnN0IEZjQ2hhcjggICAqYmluZGluZ19zdHJpbmc7CiAgICBGY09wCSAgICBtb2RlOwogICAgRmNWYWx1ZUJpbmRpbmcgIGJpbmRpbmc7CiAgICBGY0V4cHIJICAgICpleHByOwogICAgRmNFZGl0CSAgICAqZWRpdDsKCiAgICBuYW1lID0gRmNDb25maWdHZXRBdHRyaWJ1dGUgKHBhcnNlLCAibmFtZSIpOwogICAgaWYgKCFuYW1lKQogICAgewoJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVXYXJuaW5nLCAibWlzc2luZyBlZGl0IG5hbWUiKTsKCXJldHVybjsKICAgIH0KICAgIG1vZGVfc3RyaW5nID0gRmNDb25maWdHZXRBdHRyaWJ1dGUgKHBhcnNlLCAibW9kZSIpOwogICAgaWYgKCFtb2RlX3N0cmluZykKCW1vZGUgPSBGY09wQXNzaWduOwogICAgZWxzZQogICAgewoJbW9kZSA9IEZjQ29uZmlnTGV4TW9kZSAobW9kZV9zdHJpbmcpOwoJaWYgKG1vZGUgPT0gRmNPcEludmFsaWQpCgl7CgkgICAgRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVXYXJuaW5nLCAiaW52YWxpZCBlZGl0IG1vZGUgXCIlc1wiIiwgbW9kZV9zdHJpbmcpOwoJICAgIHJldHVybjsKCX0KICAgIH0KICAgIGJpbmRpbmdfc3RyaW5nID0gRmNDb25maWdHZXRBdHRyaWJ1dGUgKHBhcnNlLCAiYmluZGluZyIpOwogICAgaWYgKCFiaW5kaW5nX3N0cmluZykKCWJpbmRpbmcgPSBGY1ZhbHVlQmluZGluZ1dlYWs7CiAgICBlbHNlCiAgICB7CglpZiAoIXN0cmNtcCAoKGNoYXIgKikgYmluZGluZ19zdHJpbmcsICJ3ZWFrIikpCgkgICAgYmluZGluZyA9IEZjVmFsdWVCaW5kaW5nV2VhazsKCWVsc2UgaWYgKCFzdHJjbXAgKChjaGFyICopIGJpbmRpbmdfc3RyaW5nLCAic3Ryb25nIikpCgkgICAgYmluZGluZyA9IEZjVmFsdWVCaW5kaW5nU3Ryb25nOwoJZWxzZSBpZiAoIXN0cmNtcCAoKGNoYXIgKikgYmluZGluZ19zdHJpbmcsICJzYW1lIikpCgkgICAgYmluZGluZyA9IEZjVmFsdWVCaW5kaW5nU2FtZTsKCWVsc2UKCXsKCSAgICBGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZVdhcm5pbmcsICJpbnZhbGlkIGVkaXQgYmluZGluZyBcIiVzXCIiLCBiaW5kaW5nX3N0cmluZyk7CgkgICAgcmV0dXJuOwoJfQogICAgfQogICAgZXhwciA9IEZjUG9wQmluYXJ5IChwYXJzZSwgRmNPcENvbW1hKTsKICAgIGVkaXQgPSBGY0VkaXRDcmVhdGUgKChjaGFyICopIEZjU3RyQ29weSAobmFtZSksIG1vZGUsIGV4cHIsIGJpbmRpbmcpOwogICAgaWYgKCFlZGl0KQogICAgewoJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVFcnJvciwgIm91dCBvZiBtZW1vcnkiKTsKCUZjRXhwckRlc3Ryb3kgKGV4cHIpOwoJcmV0dXJuOwogICAgfQogICAgaWYgKCFGY1ZTdGFja1B1c2hFZGl0IChwYXJzZSwgZWRpdCkpCglGY0VkaXREZXN0cm95IChlZGl0KTsKfQoKc3RhdGljIHZvaWQKRmNQYXJzZU1hdGNoIChGY0NvbmZpZ1BhcnNlICpwYXJzZSkKewogICAgY29uc3QgRmNDaGFyOCAgICpraW5kX25hbWU7CiAgICBGY01hdGNoS2luZAkgICAga2luZDsKICAgIEZjVGVzdAkgICAgKnRlc3QgPSAwOwogICAgRmNFZGl0CSAgICAqZWRpdCA9IDA7CiAgICBGY1ZTdGFjawkgICAgKnZzdGFjazsKCiAgICBraW5kX25hbWUgPSBGY0NvbmZpZ0dldEF0dHJpYnV0ZSAocGFyc2UsICJ0YXJnZXQiKTsKICAgIGlmICgha2luZF9uYW1lKQoJa2luZCA9IEZjTWF0Y2hQYXR0ZXJuOwogICAgZWxzZQogICAgewoJaWYgKCFzdHJjbXAgKChjaGFyICopIGtpbmRfbmFtZSwgInBhdHRlcm4iKSkKCSAgICBraW5kID0gRmNNYXRjaFBhdHRlcm47CgllbHNlIGlmICghc3RyY21wICgoY2hhciAqKSBraW5kX25hbWUsICJmb250IikpCgkgICAga2luZCA9IEZjTWF0Y2hGb250OwoJZWxzZQoJewoJICAgIEZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlV2FybmluZywgImludmFsaWQgbWF0Y2ggdGFyZ2V0IFwiJXNcIiIsIGtpbmRfbmFtZSk7CgkgICAgcmV0dXJuOwoJfQogICAgfQogICAgd2hpbGUgKCh2c3RhY2sgPSBGY1ZTdGFja1BvcCAocGFyc2UpKSkKICAgIHsKCXN3aXRjaCAodnN0YWNrLT50YWcpIHsKCWNhc2UgRmNWU3RhY2tUZXN0OgoJICAgIHZzdGFjay0+dS50ZXN0LT5uZXh0ID0gdGVzdDsKCSAgICB0ZXN0ID0gdnN0YWNrLT51LnRlc3Q7CgkgICAgdnN0YWNrLT50YWcgPSBGY1ZTdGFja05vbmU7CgkgICAgYnJlYWs7CgljYXNlIEZjVlN0YWNrRWRpdDoKCSAgICB2c3RhY2stPnUuZWRpdC0+bmV4dCA9IGVkaXQ7CgkgICAgZWRpdCA9IHZzdGFjay0+dS5lZGl0OwoJICAgIHZzdGFjay0+dGFnID0gRmNWU3RhY2tOb25lOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICBGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZVdhcm5pbmcsICJpbnZhbGlkIG1hdGNoIGVsZW1lbnQiKTsKCSAgICBicmVhazsKCX0KCUZjVlN0YWNrRGVzdHJveSAodnN0YWNrKTsKICAgIH0KICAgIGlmICghRmNDb25maWdBZGRFZGl0IChwYXJzZS0+Y29uZmlnLCB0ZXN0LCBlZGl0LCBraW5kKSkKCUZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlRXJyb3IsICJvdXQgb2YgbWVtb3J5Iik7Cn0KCnN0YXRpYyB2b2lkCkZjUGFyc2VBY2NlcHRSZWplY3RGb250IChGY0NvbmZpZ1BhcnNlICpwYXJzZSwgRmNFbGVtZW50IGVsZW1lbnQpCnsKICAgIEZjVlN0YWNrCSp2c3RhY2s7CgogICAgd2hpbGUgKCh2c3RhY2sgPSBGY1ZTdGFja1BvcCAocGFyc2UpKSkKICAgIHsKCXN3aXRjaCAodnN0YWNrLT50YWcpIHsKCWNhc2UgRmNWU3RhY2tHbG9iOgoJICAgIGlmICghRmNDb25maWdHbG9iQWRkIChwYXJzZS0+Y29uZmlnLCAKCQkJCSAgdnN0YWNrLT51LnN0cmluZywKCQkJCSAgZWxlbWVudCA9PSBGY0VsZW1lbnRBY2NlcHRmb250KSkKCSAgICB7CgkJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVFcnJvciwgIm91dCBvZiBtZW1vcnkiKTsKCSAgICB9CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIEZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlV2FybmluZywgImJhZCBmb250IHNlbGVjdG9yIik7CgkgICAgYnJlYWs7Cgl9CglGY1ZTdGFja0Rlc3Ryb3kgKHZzdGFjayk7CiAgICB9Cn0KCnN0YXRpYyB2b2lkCkZjRW5kRWxlbWVudCh2b2lkICp1c2VyRGF0YSwgY29uc3QgWE1MX0NoYXIgKm5hbWUpCnsKICAgIEZjQ29uZmlnUGFyc2UgICAqcGFyc2UgPSB1c2VyRGF0YTsKICAgIEZjQ2hhcjgJICAgICpkYXRhOwogICAgCiAgICBpZiAoIXBhcnNlLT5wc3RhY2spCglyZXR1cm47CiAgICBzd2l0Y2ggKHBhcnNlLT5wc3RhY2stPmVsZW1lbnQpIHsKICAgIGNhc2UgRmNFbGVtZW50Tm9uZToKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnRGb250Y29uZmlnOgoJYnJlYWs7CiAgICBjYXNlIEZjRWxlbWVudERpcjoKCWRhdGEgPSBGY1N0ckJ1ZkRvbmUgKCZwYXJzZS0+cHN0YWNrLT5zdHIpOwoJaWYgKCFkYXRhKQoJewoJICAgIEZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlRXJyb3IsICJvdXQgb2YgbWVtb3J5Iik7CgkgICAgYnJlYWs7Cgl9CiNpZmRlZiBfV0lOMzIKCWlmIChzdHJjbXAgKGRhdGEsICJXSU5ET1dTRk9OVERJUiIpID09IDApCgl7CgkgICAgaW50IHJjOwoJICAgIEZjU3RyRnJlZSAoZGF0YSk7CgkgICAgZGF0YSA9IG1hbGxvYyAoMTAwMCk7CgkgICAgaWYgKCFkYXRhKQoJICAgIHsKCQlGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZUVycm9yLCAib3V0IG9mIG1lbW9yeSIpOwoJCWJyZWFrOwoJICAgIH0KCSAgICBGY01lbUFsbG9jIChGQ19NRU1fU1RSSU5HLCAxMDAwKTsKCSAgICByYyA9IEdldFdpbmRvd3NEaXJlY3RvcnkgKGRhdGEsIDgwMCk7CgkgICAgaWYgKHJjID09IDAgfHwgcmMgPiA4MDApCgkgICAgewoJCUZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlRXJyb3IsICJHZXRXaW5kb3dzRGlyZWN0b3J5IGZhaWxlZCIpOwoJCUZjU3RyRnJlZSAoZGF0YSk7CgkJYnJlYWs7CgkgICAgfQoJICAgIGlmIChkYXRhIFtzdHJsZW4gKGRhdGEpIC0gMV0gIT0gJ1xcJykKCQlzdHJjYXQgKGRhdGEsICJcXCIpOwoJICAgIHN0cmNhdCAoZGF0YSwgImZvbnRzIik7Cgl9CiNlbmRpZgoJaWYgKCFGY1N0clVzZXNIb21lIChkYXRhKSB8fCBGY0NvbmZpZ0hvbWUgKCkpCgl7CgkgICAgaWYgKCFGY0NvbmZpZ0FkZERpciAocGFyc2UtPmNvbmZpZywgZGF0YSkpCgkJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVFcnJvciwgIm91dCBvZiBtZW1vcnkiKTsKCX0KCUZjU3RyRnJlZSAoZGF0YSk7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50Q2FjaGU6CglkYXRhID0gRmNTdHJCdWZEb25lICgmcGFyc2UtPnBzdGFjay0+c3RyKTsKCWlmICghZGF0YSkKCXsKCSAgICBGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZUVycm9yLCAib3V0IG9mIG1lbW9yeSIpOwoJICAgIGJyZWFrOwoJfQoJaWYgKCFGY1N0clVzZXNIb21lIChkYXRhKSB8fCBGY0NvbmZpZ0hvbWUgKCkpCgl7CgkgICAgaWYgKCFGY0NvbmZpZ1NldENhY2hlIChwYXJzZS0+Y29uZmlnLCBkYXRhKSkKCQlGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZUVycm9yLCAib3V0IG9mIG1lbW9yeSIpOwoJfQoJRmNTdHJGcmVlIChkYXRhKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnRJbmNsdWRlOgoJRmNQYXJzZUluY2x1ZGUgKHBhcnNlKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnRDb25maWc6CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50TWF0Y2g6CglGY1BhcnNlTWF0Y2ggKHBhcnNlKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnRBbGlhczoKCUZjUGFyc2VBbGlhcyAocGFyc2UpOwoJYnJlYWs7CgogICAgY2FzZSBGY0VsZW1lbnRCbGFuazoKCUZjUGFyc2VCbGFuayAocGFyc2UpOwoJYnJlYWs7CiAgICBjYXNlIEZjRWxlbWVudFJlc2NhbjoKCUZjUGFyc2VSZXNjYW4gKHBhcnNlKTsKCWJyZWFrOwoJCiAgICBjYXNlIEZjRWxlbWVudFByZWZlcjoKCUZjUGFyc2VGYW1pbGllcyAocGFyc2UsIEZjVlN0YWNrUHJlZmVyKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnRBY2NlcHQ6CglGY1BhcnNlRmFtaWxpZXMgKHBhcnNlLCBGY1ZTdGFja0FjY2VwdCk7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50RGVmYXVsdDoKCUZjUGFyc2VGYW1pbGllcyAocGFyc2UsIEZjVlN0YWNrRGVmYXVsdCk7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50RmFtaWx5OgoJRmNQYXJzZUZhbWlseSAocGFyc2UpOwoJYnJlYWs7CgogICAgY2FzZSBGY0VsZW1lbnRUZXN0OgoJRmNQYXJzZVRlc3QgKHBhcnNlKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnRFZGl0OgoJRmNQYXJzZUVkaXQgKHBhcnNlKTsKCWJyZWFrOwoKICAgIGNhc2UgRmNFbGVtZW50SW50OgoJRmNQYXJzZUludCAocGFyc2UpOwoJYnJlYWs7CiAgICBjYXNlIEZjRWxlbWVudERvdWJsZToKCUZjUGFyc2VEb3VibGUgKHBhcnNlKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnRTdHJpbmc6CglGY1BhcnNlU3RyaW5nIChwYXJzZSwgRmNWU3RhY2tTdHJpbmcpOwoJYnJlYWs7CiAgICBjYXNlIEZjRWxlbWVudE1hdHJpeDoKCUZjUGFyc2VNYXRyaXggKHBhcnNlKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnRCb29sOgoJRmNQYXJzZUJvb2wgKHBhcnNlKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnRDaGFyc2V0OgovKglGY1BhcnNlQ2hhcnNldCAocGFyc2UpOyAqLwoJYnJlYWs7CiAgICBjYXNlIEZjRWxlbWVudFNlbGVjdGZvbnQ6CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50QWNjZXB0Zm9udDoKICAgIGNhc2UgRmNFbGVtZW50UmVqZWN0Zm9udDoKCUZjUGFyc2VBY2NlcHRSZWplY3RGb250IChwYXJzZSwgcGFyc2UtPnBzdGFjay0+ZWxlbWVudCk7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50R2xvYjoKCUZjUGFyc2VTdHJpbmcgKHBhcnNlLCBGY1ZTdGFja0dsb2IpOwoJYnJlYWs7CiAgICBjYXNlIEZjRWxlbWVudE5hbWU6CglGY1BhcnNlU3RyaW5nIChwYXJzZSwgRmNWU3RhY2tGaWVsZCk7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50Q29uc3Q6CglGY1BhcnNlU3RyaW5nIChwYXJzZSwgRmNWU3RhY2tDb25zdGFudCk7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50T3I6CglGY1BhcnNlQmluYXJ5IChwYXJzZSwgRmNPcE9yKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnRBbmQ6CglGY1BhcnNlQmluYXJ5IChwYXJzZSwgRmNPcEFuZCk7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50RXE6CglGY1BhcnNlQmluYXJ5IChwYXJzZSwgRmNPcEVxdWFsKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnROb3RFcToKCUZjUGFyc2VCaW5hcnkgKHBhcnNlLCBGY09wTm90RXF1YWwpOwoJYnJlYWs7CiAgICBjYXNlIEZjRWxlbWVudExlc3M6CglGY1BhcnNlQmluYXJ5IChwYXJzZSwgRmNPcExlc3MpOwoJYnJlYWs7CiAgICBjYXNlIEZjRWxlbWVudExlc3NFcToKCUZjUGFyc2VCaW5hcnkgKHBhcnNlLCBGY09wTGVzc0VxdWFsKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnRNb3JlOgoJRmNQYXJzZUJpbmFyeSAocGFyc2UsIEZjT3BNb3JlKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnRNb3JlRXE6CglGY1BhcnNlQmluYXJ5IChwYXJzZSwgRmNPcE1vcmVFcXVhbCk7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50Q29udGFpbnM6CglGY1BhcnNlQmluYXJ5IChwYXJzZSwgRmNPcENvbnRhaW5zKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnROb3RDb250YWluczoKCUZjUGFyc2VCaW5hcnkgKHBhcnNlLCBGY09wTm90Q29udGFpbnMpOwoJYnJlYWs7CiAgICBjYXNlIEZjRWxlbWVudFBsdXM6CglGY1BhcnNlQmluYXJ5IChwYXJzZSwgRmNPcFBsdXMpOwoJYnJlYWs7CiAgICBjYXNlIEZjRWxlbWVudE1pbnVzOgoJRmNQYXJzZUJpbmFyeSAocGFyc2UsIEZjT3BNaW51cyk7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50VGltZXM6CglGY1BhcnNlQmluYXJ5IChwYXJzZSwgRmNPcFRpbWVzKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnREaXZpZGU6CglGY1BhcnNlQmluYXJ5IChwYXJzZSwgRmNPcERpdmlkZSk7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50Tm90OgoJRmNQYXJzZVVuYXJ5IChwYXJzZSwgRmNPcE5vdCk7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50SWY6CglGY1BhcnNlQmluYXJ5IChwYXJzZSwgRmNPcFF1ZXN0KTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnRGbG9vcjoKCUZjUGFyc2VVbmFyeSAocGFyc2UsIEZjT3BGbG9vcik7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50Q2VpbDoKCUZjUGFyc2VVbmFyeSAocGFyc2UsIEZjT3BDZWlsKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnRSb3VuZDoKCUZjUGFyc2VVbmFyeSAocGFyc2UsIEZjT3BSb3VuZCk7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50VHJ1bmM6CglGY1BhcnNlVW5hcnkgKHBhcnNlLCBGY09wVHJ1bmMpOwoJYnJlYWs7CiAgICBjYXNlIEZjRWxlbWVudFVua25vd246CglicmVhazsKICAgIH0KICAgICh2b2lkKSBGY1BTdGFja1BvcCAocGFyc2UpOwp9CgpzdGF0aWMgdm9pZApGY0NoYXJhY3RlckRhdGEgKHZvaWQgKnVzZXJEYXRhLCBjb25zdCBYTUxfQ2hhciAqcywgaW50IGxlbikKewogICAgRmNDb25maWdQYXJzZSAgICpwYXJzZSA9IHVzZXJEYXRhOwogICAgCiAgICBpZiAoIXBhcnNlLT5wc3RhY2spCglyZXR1cm47CiAgICBpZiAoIUZjU3RyQnVmRGF0YSAoJnBhcnNlLT5wc3RhY2stPnN0ciwgKEZjQ2hhcjggKikgcywgbGVuKSkKCUZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlRXJyb3IsICJvdXQgb2YgbWVtb3J5Iik7Cn0KCnN0YXRpYyB2b2lkCkZjU3RhcnREb2N0eXBlRGVjbCAodm9pZAkgICAgKnVzZXJEYXRhLAoJCSAgICBjb25zdCBYTUxfQ2hhciAgKmRvY3R5cGVOYW1lLAoJCSAgICBjb25zdCBYTUxfQ2hhciAgKnN5c2lkLAoJCSAgICBjb25zdCBYTUxfQ2hhciAgKnB1YmlkLAoJCSAgICBpbnQJCSAgICBoYXNfaW50ZXJuYWxfc3Vic2V0KQp7CiAgICBGY0NvbmZpZ1BhcnNlICAgKnBhcnNlID0gdXNlckRhdGE7CgogICAgaWYgKHN0cmNtcCAoKGNoYXIgKikgZG9jdHlwZU5hbWUsICJmb250Y29uZmlnIikgIT0gMCkKCUZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlRXJyb3IsICJpbnZhbGlkIGRvY3R5cGUgXCIlc1wiIiwgZG9jdHlwZU5hbWUpOwp9CgpzdGF0aWMgdm9pZApGY0VuZERvY3R5cGVEZWNsICh2b2lkICp1c2VyRGF0YSkKewp9CgpGY0Jvb2wKRmNDb25maWdQYXJzZUFuZExvYWQgKEZjQ29uZmlnCSAgICAqY29uZmlnLAoJCSAgICAgIGNvbnN0IEZjQ2hhcjggKm5hbWUsCgkJICAgICAgRmNCb29sCSAgICBjb21wbGFpbikKewoKICAgIFhNTF9QYXJzZXIJICAgIHA7CiAgICBGY0NoYXI4CSAgICAqZmlsZW5hbWU7CiAgICBGSUxFCSAgICAqZjsKICAgIGludAkJICAgIGxlbjsKICAgIHZvaWQJICAgICpidWY7CiAgICBGY0NvbmZpZ1BhcnNlICAgcGFyc2U7CiAgICBGY0Jvb2wJICAgIGVycm9yID0gRmNUcnVlOwogICAgCiAgICBmaWxlbmFtZSA9IEZjQ29uZmlnRmlsZW5hbWUgKG5hbWUpOwogICAgaWYgKCFmaWxlbmFtZSkKCWdvdG8gYmFpbDA7CiAgICAKICAgIGlmICghRmNTdHJTZXRBZGQgKGNvbmZpZy0+Y29uZmlnRmlsZXMsIGZpbGVuYW1lKSkKICAgIHsKCUZjU3RyRnJlZSAoZmlsZW5hbWUpOwoJZ290byBiYWlsMDsKICAgIH0KCiAgICBmID0gZm9wZW4gKChjaGFyICopIGZpbGVuYW1lLCAiciIpOwogICAgRmNTdHJGcmVlIChmaWxlbmFtZSk7CiAgICBpZiAoIWYpCglnb3RvIGJhaWwwOwogICAgCiAgICBwID0gWE1MX1BhcnNlckNyZWF0ZSAoIlVURi04Iik7CiAgICBpZiAoIXApCglnb3RvIGJhaWwxOwoKICAgIGlmICghRmNDb25maWdJbml0ICgmcGFyc2UsIG5hbWUsIGNvbmZpZywgcCkpCglnb3RvIGJhaWwyOwoKICAgIFhNTF9TZXRVc2VyRGF0YSAocCwgJnBhcnNlKTsKICAgIAogICAgWE1MX1NldERvY3R5cGVEZWNsSGFuZGxlciAocCwgRmNTdGFydERvY3R5cGVEZWNsLCBGY0VuZERvY3R5cGVEZWNsKTsKICAgIFhNTF9TZXRFbGVtZW50SGFuZGxlciAocCwgRmNTdGFydEVsZW1lbnQsIEZjRW5kRWxlbWVudCk7CiAgICBYTUxfU2V0Q2hhcmFjdGVyRGF0YUhhbmRsZXIgKHAsIEZjQ2hhcmFjdGVyRGF0YSk7CgkKICAgIGRvIHsKCWJ1ZiA9IFhNTF9HZXRCdWZmZXIgKHAsIEJVRlNJWik7CglpZiAoIWJ1ZikKCXsKCSAgICBGY0NvbmZpZ01lc3NhZ2UgKCZwYXJzZSwgRmNTZXZlcmVFcnJvciwgImNhbm5vdCBnZXQgcGFyc2UgYnVmZmVyIik7CgkgICAgZ290byBiYWlsMzsKCX0KCWxlbiA9IGZyZWFkIChidWYsIDEsIEJVRlNJWiwgZik7CglpZiAobGVuIDwgMCkKCXsKCSAgICBGY0NvbmZpZ01lc3NhZ2UgKCZwYXJzZSwgRmNTZXZlcmVFcnJvciwgImZhaWxlZCByZWFkaW5nIGNvbmZpZyBmaWxlIik7CgkgICAgZ290byBiYWlsMzsKCX0KCWlmICghWE1MX1BhcnNlQnVmZmVyIChwLCBsZW4sIGxlbiA9PSAwKSkKCXsKCSAgICBGY0NvbmZpZ01lc3NhZ2UgKCZwYXJzZSwgRmNTZXZlcmVFcnJvciwgIiVzIiwgCgkJCSAgIFhNTF9FcnJvclN0cmluZyAoWE1MX0dldEVycm9yQ29kZSAocCkpKTsKCSAgICBnb3RvIGJhaWwzOwoJfQogICAgfSB3aGlsZSAobGVuICE9IDApOwogICAgZXJyb3IgPSBwYXJzZS5lcnJvcjsKYmFpbDM6CiAgICBGY0NvbmZpZ0NsZWFudXAgKCZwYXJzZSk7CmJhaWwyOgogICAgWE1MX1BhcnNlckZyZWUgKHApOwpiYWlsMToKICAgIGZjbG9zZSAoZik7CmJhaWwwOgogICAgaWYgKGVycm9yICYmIGNvbXBsYWluKQogICAgewoJaWYgKG5hbWUpCgkgICAgRmNDb25maWdNZXNzYWdlICgwLCBGY1NldmVyZUVycm9yLCAiQ2Fubm90IGxvYWQgY29uZmlnIGZpbGUgXCIlc1wiIiwgbmFtZSk7CgllbHNlCgkgICAgRmNDb25maWdNZXNzYWdlICgwLCBGY1NldmVyZUVycm9yLCAiQ2Fubm90IGxvYWQgZGVmYXVsdCBjb25maWcgZmlsZSIpOwoJcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9Cg==