LyoKICogJFJDU0lkOiB4Yy9saWIvZm9udGNvbmZpZy9zcmMvZmNjZmcuYyx2IDEuMjMgMjAwMi8wOC8zMSAyMjoxNzozMiBrZWl0aHAgRXhwICQKICoKICogQ29weXJpZ2h0IKkgMjAwMCBLZWl0aCBQYWNrYXJkCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUsIGFuZCBzZWxsIHRoaXMgc29mdHdhcmUgYW5kIGl0cwogKiBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBpcyBoZXJlYnkgZ3JhbnRlZCB3aXRob3V0IGZlZSwgcHJvdmlkZWQgdGhhdAogKiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoYXQKICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZwogKiBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBLZWl0aCBQYWNrYXJkIG5vdCBiZSB1c2VkIGluCiAqIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dAogKiBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgS2VpdGggUGFja2FyZCBtYWtlcyBubwogKiByZXByZXNlbnRhdGlvbnMgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiAgSXQKICogaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KICoKICogS0VJVEggUEFDS0FSRCBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwKICogSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTwogKiBFVkVOVCBTSEFMTCBLRUlUSCBQQUNLQVJEIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SCiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLAogKiBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgojaW5jbHVkZSAiZmNpbnQuaCIKCiNpZiBkZWZpbmVkIChfV0lOMzIpICYmIChkZWZpbmVkIChQSUMpIHx8IGRlZmluZWQgKERMTF9FWFBPUlQpKQojZGVmaW5lIFNUUklDVAojaW5jbHVkZSA8d2luZG93cy5oPgojdW5kZWYgU1RSSUNUCiNlbmRpZgoKI2lmIGRlZmluZWQgKF9XSU4zMikgJiYgIWRlZmluZWQgKFJfT0spCiNkZWZpbmUgUl9PSyA0CiNlbmRpZgoKRmNDb25maWcgICAgKl9mY0NvbmZpZzsKCkZjQ29uZmlnICoKRmNDb25maWdDcmVhdGUgKHZvaWQpCnsKICAgIEZjU2V0TmFtZQlzZXQ7CiAgICBGY0NvbmZpZwkqY29uZmlnOwoKICAgIGNvbmZpZyA9IG1hbGxvYyAoc2l6ZW9mIChGY0NvbmZpZykpOwogICAgaWYgKCFjb25maWcpCglnb3RvIGJhaWwwOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX0NPTkZJRywgc2l6ZW9mIChGY0NvbmZpZykpOwogICAgCiAgICBjb25maWctPmNvbmZpZ0RpcnMgPSBGY1N0clNldENyZWF0ZSAoKTsKICAgIGlmICghY29uZmlnLT5jb25maWdEaXJzKQoJZ290byBiYWlsMTsKICAgIAogICAgY29uZmlnLT5jb25maWdGaWxlcyA9IEZjU3RyU2V0Q3JlYXRlICgpOwogICAgaWYgKCFjb25maWctPmNvbmZpZ0ZpbGVzKQoJZ290byBiYWlsMjsKICAgIAogICAgY29uZmlnLT5mb250RGlycyA9IEZjU3RyU2V0Q3JlYXRlICgpOwogICAgaWYgKCFjb25maWctPmZvbnREaXJzKQoJZ290byBiYWlsMzsKICAgIAogICAgY29uZmlnLT5hY2NlcHRHbG9icyA9IEZjU3RyU2V0Q3JlYXRlICgpOwogICAgaWYgKCFjb25maWctPmFjY2VwdEdsb2JzKQoJZ290byBiYWlsNDsKCiAgICBjb25maWctPnJlamVjdEdsb2JzID0gRmNTdHJTZXRDcmVhdGUgKCk7CiAgICBpZiAoIWNvbmZpZy0+cmVqZWN0R2xvYnMpCglnb3RvIGJhaWw1OwoKICAgIGNvbmZpZy0+Y2FjaGUgPSAwOwogICAgaWYgKEZjQ29uZmlnSG9tZSgpKQoJaWYgKCFGY0NvbmZpZ1NldENhY2hlIChjb25maWcsIChGY0NoYXI4ICopICgifi8iIEZDX1VTRVJfQ0FDSEVfRklMRSkpKQoJICAgIGdvdG8gYmFpbDY7CgojaWZkZWYgX1dJTjMyCiAgICBpZiAoY29uZmlnLT5jYWNoZSA9PSAwKQogICAgewoJLyogSWYgbm8gaG9tZSwgdXNlIHRoZSB0ZW1wIGZvbGRlci4gKi8KCUZjQ2hhcjgJICAgIGR1bW15WzFdOwoJaW50CSAgICB0ZW1wbGVuID0gR2V0VGVtcFBhdGggKDEsIGR1bW15KTsKCUZjQ2hhcjggICAgICp0ZW1wID0gbWFsbG9jICh0ZW1wbGVuICsgMSk7CgoJaWYgKHRlbXApCgl7CgkgICAgRmNDaGFyOCAqY2FjaGVfZGlyOwoKCSAgICBHZXRUZW1wUGF0aCAodGVtcGxlbiArIDEsIHRlbXApOwoJICAgIGNhY2hlX2RpciA9IEZjU3RyUGx1cyAodGVtcCwgRkNfVVNFUl9DQUNIRV9GSUxFKTsKCSAgICBmcmVlICh0ZW1wKTsKCSAgICBpZiAoIUZjQ29uZmlnU2V0Q2FjaGUgKGNvbmZpZywgY2FjaGVfZGlyKSkKCSAgICB7CgkJRmNTdHJGcmVlIChjYWNoZV9kaXIpOwoJCWdvdG8gYmFpbDY7CgkgICAgfQoJICAgIEZjU3RyRnJlZSAoY2FjaGVfZGlyKTsKCX0KICAgIH0KI2VuZGlmCgogICAgY29uZmlnLT5ibGFua3MgPSAwOwoKICAgIGNvbmZpZy0+c3Vic3RQYXR0ZXJuID0gMDsKICAgIGNvbmZpZy0+c3Vic3RGb250ID0gMDsKICAgIGNvbmZpZy0+bWF4T2JqZWN0cyA9IDA7CiAgICBmb3IgKHNldCA9IEZjU2V0U3lzdGVtOyBzZXQgPD0gRmNTZXRBcHBsaWNhdGlvbjsgc2V0KyspCgljb25maWctPmZvbnRzW3NldF0gPSAwOwoKICAgIGNvbmZpZy0+cmVzY2FuVGltZSA9IHRpbWUoMCk7CiAgICBjb25maWctPnJlc2NhbkludGVydmFsID0gMzA7ICAgIAogICAgCiAgICByZXR1cm4gY29uZmlnOwoKYmFpbDY6CiAgICBGY1N0clNldERlc3Ryb3kgKGNvbmZpZy0+cmVqZWN0R2xvYnMpOwpiYWlsNToKICAgIEZjU3RyU2V0RGVzdHJveSAoY29uZmlnLT5hY2NlcHRHbG9icyk7CmJhaWw0OgogICAgRmNTdHJTZXREZXN0cm95IChjb25maWctPmZvbnREaXJzKTsKYmFpbDM6CiAgICBGY1N0clNldERlc3Ryb3kgKGNvbmZpZy0+Y29uZmlnRmlsZXMpOwpiYWlsMjoKICAgIEZjU3RyU2V0RGVzdHJveSAoY29uZmlnLT5jb25maWdEaXJzKTsKYmFpbDE6CiAgICBmcmVlIChjb25maWcpOwogICAgRmNNZW1GcmVlIChGQ19NRU1fQ09ORklHLCBzaXplb2YgKEZjQ29uZmlnKSk7CmJhaWwwOgogICAgcmV0dXJuIDA7Cn0KCnR5cGVkZWYgc3RydWN0IF9GY0ZpbGVUaW1lIHsKICAgIHRpbWVfdCAgdGltZTsKICAgIEZjQm9vbCAgc2V0Owp9IEZjRmlsZVRpbWU7CgpzdGF0aWMgRmNGaWxlVGltZQpGY0NvbmZpZ05ld2VzdEZpbGUgKEZjU3RyU2V0ICpmaWxlcykKewogICAgRmNTdHJMaXN0CSAgICAqbGlzdCA9IEZjU3RyTGlzdENyZWF0ZSAoZmlsZXMpOwogICAgRmNGaWxlVGltZQkgICAgbmV3ZXN0ID0geyAwLCBGY0ZhbHNlIH07CiAgICBGY0NoYXI4CSAgICAqZmlsZTsKICAgIHN0cnVjdCAgc3RhdCAgICBzdGF0YjsKCiAgICBpZiAobGlzdCkKICAgIHsKCXdoaWxlICgoZmlsZSA9IEZjU3RyTGlzdE5leHQgKGxpc3QpKSkKCSAgICBpZiAoc3RhdCAoKGNoYXIgKikgZmlsZSwgJnN0YXRiKSA9PSAwKQoJCWlmICghbmV3ZXN0LnNldCB8fCBzdGF0Yi5zdF9tdGltZSAtIG5ld2VzdC50aW1lID4gMCkKCQl7CgkJICAgIG5ld2VzdC5zZXQgPSBGY1RydWU7CgkJICAgIG5ld2VzdC50aW1lID0gc3RhdGIuc3RfbXRpbWU7CgkJfQoJRmNTdHJMaXN0RG9uZSAobGlzdCk7CiAgICB9CiAgICByZXR1cm4gbmV3ZXN0Owp9CgpGY0Jvb2wKRmNDb25maWdVcHRvRGF0ZSAoRmNDb25maWcgKmNvbmZpZykKewogICAgRmNGaWxlVGltZQljb25maWdfdGltZSwgZm9udF90aW1lOwogICAgdGltZV90CW5vdyA9IHRpbWUoMCk7CiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgfQogICAgY29uZmlnX3RpbWUgPSBGY0NvbmZpZ05ld2VzdEZpbGUgKGNvbmZpZy0+Y29uZmlnRmlsZXMpOwogICAgZm9udF90aW1lID0gRmNDb25maWdOZXdlc3RGaWxlIChjb25maWctPmNvbmZpZ0RpcnMpOwogICAgaWYgKChjb25maWdfdGltZS5zZXQgJiYgY29uZmlnX3RpbWUudGltZSAtIGNvbmZpZy0+cmVzY2FuVGltZSA+IDApIHx8CgkoZm9udF90aW1lLnNldCAmJiBmb250X3RpbWUudGltZSAtIGNvbmZpZy0+cmVzY2FuVGltZSkgPiAwKQogICAgewoJcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBjb25maWctPnJlc2NhblRpbWUgPSBub3c7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgdm9pZApGY1N1YnN0RGVzdHJveSAoRmNTdWJzdCAqcykKewogICAgRmNTdWJzdCAqbjsKICAgIAogICAgd2hpbGUgKHMpCiAgICB7CgluID0gcy0+bmV4dDsKCWlmIChzLT50ZXN0KQoJICAgIEZjVGVzdERlc3Ryb3kgKHMtPnRlc3QpOwoJaWYgKHMtPmVkaXQpCgkgICAgRmNFZGl0RGVzdHJveSAocy0+ZWRpdCk7CglmcmVlIChzKTsKCUZjTWVtRnJlZSAoRkNfTUVNX1NVQlNULCBzaXplb2YgKEZjU3Vic3QpKTsKCXMgPSBuOwogICAgfQp9Cgp2b2lkCkZjQ29uZmlnRGVzdHJveSAoRmNDb25maWcgKmNvbmZpZykKewogICAgRmNTZXROYW1lCXNldDsKCiAgICBpZiAoY29uZmlnID09IF9mY0NvbmZpZykKCV9mY0NvbmZpZyA9IDA7CgogICAgRmNTdHJTZXREZXN0cm95IChjb25maWctPmNvbmZpZ0RpcnMpOwogICAgRmNTdHJTZXREZXN0cm95IChjb25maWctPmZvbnREaXJzKTsKICAgIEZjU3RyU2V0RGVzdHJveSAoY29uZmlnLT5jb25maWdGaWxlcyk7CiAgICBGY1N0clNldERlc3Ryb3kgKGNvbmZpZy0+YWNjZXB0R2xvYnMpOwogICAgRmNTdHJTZXREZXN0cm95IChjb25maWctPnJlamVjdEdsb2JzKTsKCiAgICBpZiAoY29uZmlnLT5ibGFua3MpCglGY0JsYW5rc0Rlc3Ryb3kgKGNvbmZpZy0+YmxhbmtzKTsKCiAgICBpZiAoY29uZmlnLT5jYWNoZSkKCUZjU3RyRnJlZSAoY29uZmlnLT5jYWNoZSk7CgogICAgRmNTdWJzdERlc3Ryb3kgKGNvbmZpZy0+c3Vic3RQYXR0ZXJuKTsKICAgIEZjU3Vic3REZXN0cm95IChjb25maWctPnN1YnN0Rm9udCk7CiAgICBmb3IgKHNldCA9IEZjU2V0U3lzdGVtOyBzZXQgPD0gRmNTZXRBcHBsaWNhdGlvbjsgc2V0KyspCglpZiAoY29uZmlnLT5mb250c1tzZXRdKQoJICAgIEZjRm9udFNldERlc3Ryb3kgKGNvbmZpZy0+Zm9udHNbc2V0XSk7CgogICAgZnJlZSAoY29uZmlnKTsKICAgIEZjTWVtRnJlZSAoRkNfTUVNX0NPTkZJRywgc2l6ZW9mIChGY0NvbmZpZykpOwp9CgovKgogKiBTY2FuIHRoZSBjdXJyZW50IGxpc3Qgb2YgZGlyZWN0b3JpZXMgaW4gdGhlIGNvbmZpZ3VyYXRpb24KICogYW5kIGJ1aWxkIHRoZSBzZXQgb2YgYXZhaWxhYmxlIGZvbnRzLiBVcGRhdGUgdGhlCiAqIHBlci11c2VyIGNhY2hlIGZpbGUgdG8gcmVmbGVjdCB0aGUgbmV3IGNvbmZpZ3VyYXRpb24KICovCgpGY0Jvb2wKRmNDb25maWdCdWlsZEZvbnRzIChGY0NvbmZpZyAqY29uZmlnKQp7CiAgICBGY0ZvbnRTZXQJICAgICpmb250czsKICAgIEZjR2xvYmFsQ2FjaGUgICAqY2FjaGU7CiAgICBGY1N0ckxpc3QJICAgICpsaXN0OwogICAgRmNDaGFyOAkgICAgKmRpcjsKCiAgICBmb250cyA9IEZjRm9udFNldENyZWF0ZSAoKTsKICAgIGlmICghZm9udHMpCglnb3RvIGJhaWwwOwogICAgCiAgICBjYWNoZSA9IEZjR2xvYmFsQ2FjaGVDcmVhdGUgKCk7CiAgICBpZiAoIWNhY2hlKQoJZ290byBiYWlsMTsKCiAgICBpZiAoY29uZmlnLT5jYWNoZSkKCUZjR2xvYmFsQ2FjaGVMb2FkIChjYWNoZSwgY29uZmlnLT5jYWNoZSk7CgogICAgbGlzdCA9IEZjQ29uZmlnR2V0Rm9udERpcnMgKGNvbmZpZyk7CiAgICBpZiAoIWxpc3QpCglnb3RvIGJhaWwxOwoKICAgIHdoaWxlICgoZGlyID0gRmNTdHJMaXN0TmV4dCAobGlzdCkpKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRk9OVFNFVCkKCSAgICBwcmludGYgKCJzY2FuIGRpciAlc1xuIiwgZGlyKTsKCUZjRGlyU2NhbkNvbmZpZyAoZm9udHMsIGNvbmZpZy0+Zm9udERpcnMsIGNhY2hlLCAKCQkJIGNvbmZpZy0+YmxhbmtzLCBkaXIsIEZjRmFsc2UsIGNvbmZpZyk7CiAgICB9CiAgICAKICAgIEZjU3RyTGlzdERvbmUgKGxpc3QpOwogICAgCiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19GT05UU0VUKQoJRmNGb250U2V0UHJpbnQgKGZvbnRzKTsKCiAgICBpZiAoY29uZmlnLT5jYWNoZSkKCUZjR2xvYmFsQ2FjaGVTYXZlIChjYWNoZSwgY29uZmlnLT5jYWNoZSk7CiAgICBGY0dsb2JhbENhY2hlRGVzdHJveSAoY2FjaGUpOwoKICAgIEZjQ29uZmlnU2V0Rm9udHMgKGNvbmZpZywgZm9udHMsIEZjU2V0U3lzdGVtKTsKICAgIAogICAgcmV0dXJuIEZjVHJ1ZTsKYmFpbDE6CiAgICBGY0ZvbnRTZXREZXN0cm95IChmb250cyk7CmJhaWwwOgogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCkZjQm9vbApGY0NvbmZpZ1NldEN1cnJlbnQgKEZjQ29uZmlnICpjb25maWcpCnsKICAgIGlmICghY29uZmlnLT5mb250cykKCWlmICghRmNDb25maWdCdWlsZEZvbnRzIChjb25maWcpKQoJICAgIHJldHVybiBGY0ZhbHNlOwoKICAgIGlmIChfZmNDb25maWcpCglGY0NvbmZpZ0Rlc3Ryb3kgKF9mY0NvbmZpZyk7CiAgICBfZmNDb25maWcgPSBjb25maWc7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0NvbmZpZyAqCkZjQ29uZmlnR2V0Q3VycmVudCAodm9pZCkKewogICAgaWYgKCFfZmNDb25maWcpCglpZiAoIUZjSW5pdCAoKSkKCSAgICByZXR1cm4gMDsKICAgIHJldHVybiBfZmNDb25maWc7Cn0KCkZjQm9vbApGY0NvbmZpZ0FkZENvbmZpZ0RpciAoRmNDb25maWcJICAgICpjb25maWcsCgkJICAgICAgY29uc3QgRmNDaGFyOCAqZCkKewogICAgcmV0dXJuIEZjU3RyU2V0QWRkRmlsZW5hbWUgKGNvbmZpZy0+Y29uZmlnRGlycywgZCk7Cn0KCkZjU3RyTGlzdCAqCkZjQ29uZmlnR2V0Q29uZmlnRGlycyAoRmNDb25maWcgICAqY29uZmlnKQp7CiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiAwOwogICAgfQogICAgcmV0dXJuIEZjU3RyTGlzdENyZWF0ZSAoY29uZmlnLT5jb25maWdEaXJzKTsKfQoKRmNCb29sCkZjQ29uZmlnQWRkRm9udERpciAoRmNDb25maWcJICAgICpjb25maWcsCgkJICAgIGNvbnN0IEZjQ2hhcjggICAqZCkKewogICAgcmV0dXJuIEZjU3RyU2V0QWRkRmlsZW5hbWUgKGNvbmZpZy0+Zm9udERpcnMsIGQpOwp9CgpGY0Jvb2wKRmNDb25maWdBZGREaXIgKEZjQ29uZmlnCSAgICAqY29uZmlnLAoJCWNvbnN0IEZjQ2hhcjgJICAgICpkKQp7CiAgICByZXR1cm4gKEZjQ29uZmlnQWRkQ29uZmlnRGlyIChjb25maWcsIGQpICYmIAoJICAgIEZjQ29uZmlnQWRkRm9udERpciAoY29uZmlnLCBkKSk7Cn0KCkZjU3RyTGlzdCAqCkZjQ29uZmlnR2V0Rm9udERpcnMgKEZjQ29uZmlnCSpjb25maWcpCnsKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIDA7CiAgICB9CiAgICByZXR1cm4gRmNTdHJMaXN0Q3JlYXRlIChjb25maWctPmZvbnREaXJzKTsKfQoKRmNCb29sCkZjQ29uZmlnQWRkQ29uZmlnRmlsZSAoRmNDb25maWcJICAgICpjb25maWcsCgkJICAgICAgIGNvbnN0IEZjQ2hhcjggICAqZikKewogICAgRmNCb29sCXJldDsKICAgIEZjQ2hhcjgJKmZpbGUgPSBGY0NvbmZpZ0ZpbGVuYW1lIChmKTsKICAgIAogICAgaWYgKCFmaWxlKQoJcmV0dXJuIEZjRmFsc2U7CiAgICAKICAgIHJldCA9IEZjU3RyU2V0QWRkIChjb25maWctPmNvbmZpZ0ZpbGVzLCBmaWxlKTsKICAgIEZjU3RyRnJlZSAoZmlsZSk7CiAgICByZXR1cm4gcmV0Owp9CgpGY1N0ckxpc3QgKgpGY0NvbmZpZ0dldENvbmZpZ0ZpbGVzIChGY0NvbmZpZyAgICAqY29uZmlnKQp7CiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiAwOwogICAgfQogICAgcmV0dXJuIEZjU3RyTGlzdENyZWF0ZSAoY29uZmlnLT5jb25maWdGaWxlcyk7Cn0KCkZjQm9vbApGY0NvbmZpZ1NldENhY2hlIChGY0NvbmZpZwkqY29uZmlnLAoJCSAgY29uc3QgRmNDaGFyOAkqYykKewogICAgRmNDaGFyOCAgICAqbmV3ID0gRmNTdHJDb3B5RmlsZW5hbWUgKGMpOwogICAgCiAgICBpZiAoIW5ldykKCXJldHVybiBGY0ZhbHNlOwogICAgaWYgKGNvbmZpZy0+Y2FjaGUpCglGY1N0ckZyZWUgKGNvbmZpZy0+Y2FjaGUpOwogICAgY29uZmlnLT5jYWNoZSA9IG5ldzsKICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQ2hhcjggKgpGY0NvbmZpZ0dldENhY2hlIChGY0NvbmZpZyAgKmNvbmZpZykKewogICAgaWYgKCFjb25maWcpCiAgICB7Cgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICByZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiBjb25maWctPmNhY2hlOwp9CgpGY0ZvbnRTZXQgKgpGY0NvbmZpZ0dldEZvbnRzIChGY0NvbmZpZwkqY29uZmlnLAoJCSAgRmNTZXROYW1lCXNldCkKewogICAgaWYgKCFjb25maWcpCiAgICB7Cgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICByZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiBjb25maWctPmZvbnRzW3NldF07Cn0KCnZvaWQKRmNDb25maWdTZXRGb250cyAoRmNDb25maWcJKmNvbmZpZywKCQkgIEZjRm9udFNldAkqZm9udHMsCgkJICBGY1NldE5hbWUJc2V0KQp7CiAgICBpZiAoY29uZmlnLT5mb250c1tzZXRdKQoJRmNGb250U2V0RGVzdHJveSAoY29uZmlnLT5mb250c1tzZXRdKTsKICAgIGNvbmZpZy0+Zm9udHNbc2V0XSA9IGZvbnRzOwp9CgoKCkZjQmxhbmtzICoKRmNDb25maWdHZXRCbGFua3MgKEZjQ29uZmlnCSpjb25maWcpCnsKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIDA7CiAgICB9CiAgICByZXR1cm4gY29uZmlnLT5ibGFua3M7Cn0KCkZjQm9vbApGY0NvbmZpZ0FkZEJsYW5rIChGY0NvbmZpZwkqY29uZmlnLAoJCSAgRmNDaGFyMzIgICAgCWJsYW5rKQp7CiAgICBGY0JsYW5rcwkqYjsKICAgIAogICAgYiA9IGNvbmZpZy0+YmxhbmtzOwogICAgaWYgKCFiKQogICAgewoJYiA9IEZjQmxhbmtzQ3JlYXRlICgpOwoJaWYgKCFiKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgfQogICAgaWYgKCFGY0JsYW5rc0FkZCAoYiwgYmxhbmspKQoJcmV0dXJuIEZjRmFsc2U7CiAgICBjb25maWctPmJsYW5rcyA9IGI7CiAgICByZXR1cm4gRmNUcnVlOwp9CgppbnQKRmNDb25maWdHZXRSZXNjYW5JbnZlcnZhbCAoRmNDb25maWcgKmNvbmZpZykKewogICAgaWYgKCFjb25maWcpCiAgICB7Cgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICByZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiBjb25maWctPnJlc2NhbkludGVydmFsOwp9CgpGY0Jvb2wKRmNDb25maWdTZXRSZXNjYW5JbnZlcnZhbCAoRmNDb25maWcgKmNvbmZpZywgaW50IHJlc2NhbkludGVydmFsKQp7CiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgfQogICAgY29uZmlnLT5yZXNjYW5JbnRlcnZhbCA9IHJlc2NhbkludGVydmFsOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNCb29sCkZjQ29uZmlnQWRkRWRpdCAoRmNDb25maWcJKmNvbmZpZywKCQkgRmNUZXN0CQkqdGVzdCwKCQkgRmNFZGl0CQkqZWRpdCwKCQkgRmNNYXRjaEtpbmQJa2luZCkKewogICAgRmNTdWJzdAkqc3Vic3QsICoqcHJldjsKICAgIEZjVGVzdAkqdDsKICAgIGludAkJbnVtOwoKICAgIHN1YnN0ID0gKEZjU3Vic3QgKikgbWFsbG9jIChzaXplb2YgKEZjU3Vic3QpKTsKICAgIGlmICghc3Vic3QpCglyZXR1cm4gRmNGYWxzZTsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9TVUJTVCwgc2l6ZW9mIChGY1N1YnN0KSk7CiAgICBpZiAoa2luZCA9PSBGY01hdGNoUGF0dGVybikKCXByZXYgPSAmY29uZmlnLT5zdWJzdFBhdHRlcm47CiAgICBlbHNlCglwcmV2ID0gJmNvbmZpZy0+c3Vic3RGb250OwogICAgZm9yICg7ICpwcmV2OyBwcmV2ID0gJigqcHJldiktPm5leHQpOwogICAgKnByZXYgPSBzdWJzdDsKICAgIHN1YnN0LT5uZXh0ID0gMDsKICAgIHN1YnN0LT50ZXN0ID0gdGVzdDsKICAgIHN1YnN0LT5lZGl0ID0gZWRpdDsKICAgIG51bSA9IDA7CiAgICBmb3IgKHQgPSB0ZXN0OyB0OyB0ID0gdC0+bmV4dCkKICAgIHsKCWlmICh0LT5raW5kID09IEZjTWF0Y2hEZWZhdWx0KQoJICAgIHQtPmtpbmQgPSBraW5kOwoJbnVtKys7CiAgICB9CiAgICBpZiAoY29uZmlnLT5tYXhPYmplY3RzIDwgbnVtKQoJY29uZmlnLT5tYXhPYmplY3RzID0gbnVtOwogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRURJVCkKICAgIHsKCXByaW50ZiAoIkFkZCBTdWJzdCAiKTsKCUZjU3Vic3RQcmludCAoc3Vic3QpOwogICAgfQogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKdHlwZWRlZiBzdHJ1Y3QgX0ZjU3ViU3RhdGUgewogICAgRmNQYXR0ZXJuRWx0ICAgKmVsdDsKICAgIEZjVmFsdWVMaXN0ICAgICp2YWx1ZTsKfSBGY1N1YlN0YXRlOwoKc3RhdGljIEZjVmFsdWUKRmNDb25maWdQcm9tb3RlIChGY1ZhbHVlIHYsIEZjVmFsdWUgdSkKewogICAgaWYgKHYudHlwZSA9PSBGY1R5cGVJbnRlZ2VyKQogICAgewoJdi50eXBlID0gRmNUeXBlRG91YmxlOwoJdi51LmQgPSAoZG91YmxlKSB2LnUuaTsKICAgIH0KICAgIGVsc2UgaWYgKHYudHlwZSA9PSBGY1R5cGVWb2lkICYmIHUudHlwZSA9PSBGY1R5cGVNYXRyaXgpCiAgICB7Cgl2LnUubSA9ICZGY0lkZW50aXR5TWF0cml4OwoJdi50eXBlID0gRmNUeXBlTWF0cml4OwogICAgfQogICAgZWxzZSBpZiAodi50eXBlID09IEZjVHlwZVN0cmluZyAmJiB1LnR5cGUgPT0gRmNUeXBlTGFuZ1NldCkKICAgIHsKCXYudS5sID0gRmNMYW5nU2V0UHJvbW90ZSAodi51LnMpOwoJdi50eXBlID0gRmNUeXBlTGFuZ1NldDsKICAgIH0KICAgIHJldHVybiB2Owp9CgpGY0Jvb2wKRmNDb25maWdDb21wYXJlVmFsdWUgKGNvbnN0IEZjVmFsdWUJbGVmdF9vLAoJCSAgICAgIEZjT3AJCW9wLAoJCSAgICAgIGNvbnN0IEZjVmFsdWUJcmlnaHRfbykKewogICAgRmNWYWx1ZQlsZWZ0ID0gbGVmdF9vOwogICAgRmNWYWx1ZQlyaWdodCA9IHJpZ2h0X287CiAgICBGY0Jvb2wJcmV0ID0gRmNGYWxzZTsKICAgIAogICAgbGVmdCA9IEZjQ29uZmlnUHJvbW90ZSAobGVmdCwgcmlnaHQpOwogICAgcmlnaHQgPSBGY0NvbmZpZ1Byb21vdGUgKHJpZ2h0LCBsZWZ0KTsKICAgIGlmIChsZWZ0LnR5cGUgPT0gcmlnaHQudHlwZSkgCiAgICB7Cglzd2l0Y2ggKGxlZnQudHlwZSkgewoJY2FzZSBGY1R5cGVJbnRlZ2VyOgoJICAgIGJyZWFrOwkvKiBGY0NvbmZpZ1Byb21vdGUgcHJldmVudHMgdGhpcyBmcm9tIGhhcHBlbmluZyAqLwoJY2FzZSBGY1R5cGVEb3VibGU6CgkgICAgc3dpdGNoIChvcCkgewoJICAgIGNhc2UgRmNPcEVxdWFsOgoJICAgIGNhc2UgRmNPcENvbnRhaW5zOgoJICAgIGNhc2UgRmNPcExpc3Rpbmc6CgkJcmV0ID0gbGVmdC51LmQgPT0gcmlnaHQudS5kOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcE5vdEVxdWFsOgoJICAgIGNhc2UgRmNPcE5vdENvbnRhaW5zOgoJCXJldCA9IGxlZnQudS5kICE9IHJpZ2h0LnUuZDsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BMZXNzOiAgICAKCQlyZXQgPSBsZWZ0LnUuZCA8IHJpZ2h0LnUuZDsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BMZXNzRXF1YWw6ICAgIAoJCXJldCA9IGxlZnQudS5kIDw9IHJpZ2h0LnUuZDsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BNb3JlOiAgICAKCQlyZXQgPSBsZWZ0LnUuZCA+IHJpZ2h0LnUuZDsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BNb3JlRXF1YWw6ICAgIAoJCXJldCA9IGxlZnQudS5kID49IHJpZ2h0LnUuZDsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgRmNUeXBlQm9vbDoKCSAgICBzd2l0Y2ggKG9wKSB7CgkgICAgY2FzZSBGY09wRXF1YWw6ICAgIAoJICAgIGNhc2UgRmNPcENvbnRhaW5zOgoJICAgIGNhc2UgRmNPcExpc3Rpbmc6CgkJcmV0ID0gbGVmdC51LmIgPT0gcmlnaHQudS5iOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcE5vdEVxdWFsOgoJICAgIGNhc2UgRmNPcE5vdENvbnRhaW5zOgoJCXJldCA9IGxlZnQudS5iICE9IHJpZ2h0LnUuYjsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgRmNUeXBlU3RyaW5nOgoJICAgIHN3aXRjaCAob3ApIHsKCSAgICBjYXNlIEZjT3BFcXVhbDogICAgCgkgICAgY2FzZSBGY09wTGlzdGluZzoKCQlyZXQgPSBGY1N0ckNtcElnbm9yZUNhc2UgKGxlZnQudS5zLCByaWdodC51LnMpID09IDA7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wQ29udGFpbnM6CgkJcmV0ID0gRmNTdHJTdHJJZ25vcmVDYXNlIChsZWZ0LnUucywgcmlnaHQudS5zKSAhPSAwOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcE5vdEVxdWFsOgoJICAgIGNhc2UgRmNPcE5vdENvbnRhaW5zOgoJCXJldCA9IEZjU3RyQ21wSWdub3JlQ2FzZSAobGVmdC51LnMsIHJpZ2h0LnUucykgIT0gMDsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgRmNUeXBlTWF0cml4OgoJICAgIHN3aXRjaCAob3ApIHsKCSAgICBjYXNlIEZjT3BFcXVhbDoKCSAgICBjYXNlIEZjT3BDb250YWluczoKCSAgICBjYXNlIEZjT3BMaXN0aW5nOgoJCXJldCA9IEZjTWF0cml4RXF1YWwgKGxlZnQudS5tLCByaWdodC51Lm0pOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcE5vdEVxdWFsOgoJICAgIGNhc2UgRmNPcE5vdENvbnRhaW5zOgoJCXJldCA9ICFGY01hdHJpeEVxdWFsIChsZWZ0LnUubSwgcmlnaHQudS5tKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgRmNUeXBlQ2hhclNldDoKCSAgICBzd2l0Y2ggKG9wKSB7CgkgICAgY2FzZSBGY09wQ29udGFpbnM6CgkgICAgY2FzZSBGY09wTGlzdGluZzoKCQkvKiBsZWZ0IGNvbnRhaW5zIHJpZ2h0IGlmIHJpZ2h0IGlzIGEgc3Vic2V0IG9mIGxlZnQgKi8KCQlyZXQgPSBGY0NoYXJTZXRJc1N1YnNldCAocmlnaHQudS5jLCBsZWZ0LnUuYyk7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTm90Q29udGFpbnM6CgkJLyogbGVmdCBjb250YWlucyByaWdodCBpZiByaWdodCBpcyBhIHN1YnNldCBvZiBsZWZ0ICovCgkJcmV0ID0gIUZjQ2hhclNldElzU3Vic2V0IChyaWdodC51LmMsIGxlZnQudS5jKTsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BFcXVhbDoKCQlyZXQgPSBGY0NoYXJTZXRFcXVhbCAobGVmdC51LmMsIHJpZ2h0LnUuYyk7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTm90RXF1YWw6CgkJcmV0ID0gIUZjQ2hhclNldEVxdWFsIChsZWZ0LnUuYywgcmlnaHQudS5jKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgRmNUeXBlTGFuZ1NldDoKCSAgICBzd2l0Y2ggKG9wKSB7CgkgICAgY2FzZSBGY09wQ29udGFpbnM6CgkgICAgY2FzZSBGY09wTGlzdGluZzoKCQlyZXQgPSBGY0xhbmdTZXRDb250YWlucyAobGVmdC51LmwsIHJpZ2h0LnUubCk7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTm90Q29udGFpbnM6CgkJcmV0ID0gRmNMYW5nU2V0Q29udGFpbnMgKGxlZnQudS5sLCByaWdodC51LmwpOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcEVxdWFsOgoJCXJldCA9IEZjTGFuZ1NldEVxdWFsIChsZWZ0LnUubCwgcmlnaHQudS5sKTsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BOb3RFcXVhbDoKCQlyZXQgPSAhRmNMYW5nU2V0RXF1YWwgKGxlZnQudS5sLCByaWdodC51LmwpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBGY1R5cGVWb2lkOgoJICAgIHN3aXRjaCAob3ApIHsKCSAgICBjYXNlIEZjT3BFcXVhbDoKCSAgICBjYXNlIEZjT3BDb250YWluczoKCSAgICBjYXNlIEZjT3BMaXN0aW5nOgoJCXJldCA9IEZjVHJ1ZTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgRmNUeXBlRlRGYWNlOgoJICAgIHN3aXRjaCAob3ApIHsKCSAgICBjYXNlIEZjT3BFcXVhbDoKCSAgICBjYXNlIEZjT3BDb250YWluczoKCSAgICBjYXNlIEZjT3BMaXN0aW5nOgoJCXJldCA9IGxlZnQudS5mID09IHJpZ2h0LnUuZjsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BOb3RFcXVhbDoKCSAgICBjYXNlIEZjT3BOb3RDb250YWluczoKCQlyZXQgPSBsZWZ0LnUuZiAhPSByaWdodC51LmY7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCSAgICB9CgkgICAgYnJlYWs7Cgl9CiAgICB9CiAgICBlbHNlCiAgICB7CglpZiAob3AgPT0gRmNPcE5vdEVxdWFsIHx8IG9wID09IEZjT3BOb3RDb250YWlucykKCSAgICByZXQgPSBGY1RydWU7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgoKI2RlZmluZSBfRmNEb3VibGVGbG9vcihkKQkoKGludCkgKGQpKQojZGVmaW5lIF9GY0RvdWJsZUNlaWwoZCkJKChkb3VibGUpIChpbnQpIChkKSA9PSAoZCkgPyAoaW50KSAoZCkgOiAoaW50KSAoKGQpICsgMSkpCiNkZWZpbmUgRmNEb3VibGVGbG9vcihkKQkoKGQpID49IDAgPyBfRmNEb3VibGVGbG9vcihkKSA6IC1fRmNEb3VibGVDZWlsKC0oZCkpKQojZGVmaW5lIEZjRG91YmxlQ2VpbChkKQkJKChkKSA+PSAwID8gX0ZjRG91YmxlQ2VpbChkKSA6IC1fRmNEb3VibGVGbG9vcigtKGQpKSkKI2RlZmluZSBGY0RvdWJsZVJvdW5kKGQpCUZjRG91YmxlRmxvb3IgKChkKSArIDAuNSkKI2RlZmluZSBGY0RvdWJsZVRydW5jKGQpCSgoZCkgPj0gMCA/IF9GY0RvdWJsZUZsb29yIChkKSA6IC1fRmNEb3VibGVGbG9vciAoLShkKSkpCgpzdGF0aWMgRmNWYWx1ZQpGY0NvbmZpZ0V2YWx1YXRlIChGY1BhdHRlcm4gKnAsIEZjRXhwciAqZSkKewogICAgRmNWYWx1ZQl2LCB2bCwgdnI7CiAgICBGY1Jlc3VsdAlyOwogICAgRmNNYXRyaXgJKm07CiAgICAKICAgIHN3aXRjaCAoZS0+b3ApIHsKICAgIGNhc2UgRmNPcEludGVnZXI6Cgl2LnR5cGUgPSBGY1R5cGVJbnRlZ2VyOwoJdi51LmkgPSBlLT51Lml2YWw7CglicmVhazsKICAgIGNhc2UgRmNPcERvdWJsZToKCXYudHlwZSA9IEZjVHlwZURvdWJsZTsKCXYudS5kID0gZS0+dS5kdmFsOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BTdHJpbmc6Cgl2LnR5cGUgPSBGY1R5cGVTdHJpbmc7Cgl2LnUucyA9IGUtPnUuc3ZhbDsKCXYgPSBGY1ZhbHVlU2F2ZSAodik7CglicmVhazsKICAgIGNhc2UgRmNPcE1hdHJpeDoKCXYudHlwZSA9IEZjVHlwZU1hdHJpeDsKCXYudS5tID0gZS0+dS5tdmFsOwoJdiA9IEZjVmFsdWVTYXZlICh2KTsKCWJyZWFrOwogICAgY2FzZSBGY09wQ2hhclNldDoKCXYudHlwZSA9IEZjVHlwZUNoYXJTZXQ7Cgl2LnUuYyA9IGUtPnUuY3ZhbDsKCXYgPSBGY1ZhbHVlU2F2ZSAodik7CglicmVhazsKICAgIGNhc2UgRmNPcEJvb2w6Cgl2LnR5cGUgPSBGY1R5cGVCb29sOwoJdi51LmIgPSBlLT51LmJ2YWw7CglicmVhazsKICAgIGNhc2UgRmNPcEZpZWxkOgoJciA9IEZjUGF0dGVybkdldCAocCwgZS0+dS5maWVsZCwgMCwgJnYpOwoJaWYgKHIgIT0gRmNSZXN1bHRNYXRjaCkKCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BDb25zdDoKCWlmIChGY05hbWVDb25zdGFudCAoZS0+dS5jb25zdGFudCwgJnYudS5pKSkKCSAgICB2LnR5cGUgPSBGY1R5cGVJbnRlZ2VyOwoJZWxzZQoJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CglicmVhazsKICAgIGNhc2UgRmNPcFF1ZXN0OgoJdmwgPSBGY0NvbmZpZ0V2YWx1YXRlIChwLCBlLT51LnRyZWUubGVmdCk7CglpZiAodmwudHlwZSA9PSBGY1R5cGVCb29sKQoJewoJICAgIGlmICh2bC51LmIpCgkJdiA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUtPnUudHJlZS5yaWdodC0+dS50cmVlLmxlZnQpOwoJICAgIGVsc2UKCQl2ID0gRmNDb25maWdFdmFsdWF0ZSAocCwgZS0+dS50cmVlLnJpZ2h0LT51LnRyZWUucmlnaHQpOwoJfQoJZWxzZQoJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CglGY1ZhbHVlRGVzdHJveSAodmwpOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BFcXVhbDoKICAgIGNhc2UgRmNPcE5vdEVxdWFsOgogICAgY2FzZSBGY09wTGVzczoKICAgIGNhc2UgRmNPcExlc3NFcXVhbDoKICAgIGNhc2UgRmNPcE1vcmU6CiAgICBjYXNlIEZjT3BNb3JlRXF1YWw6CiAgICBjYXNlIEZjT3BDb250YWluczoKICAgIGNhc2UgRmNPcE5vdENvbnRhaW5zOgogICAgY2FzZSBGY09wTGlzdGluZzoKCXZsID0gRmNDb25maWdFdmFsdWF0ZSAocCwgZS0+dS50cmVlLmxlZnQpOwoJdnIgPSBGY0NvbmZpZ0V2YWx1YXRlIChwLCBlLT51LnRyZWUucmlnaHQpOwoJdi50eXBlID0gRmNUeXBlQm9vbDsKCXYudS5iID0gRmNDb25maWdDb21wYXJlVmFsdWUgKHZsLCBlLT5vcCwgdnIpOwoJRmNWYWx1ZURlc3Ryb3kgKHZsKTsKCUZjVmFsdWVEZXN0cm95ICh2cik7CglicmVhazsJCiAgICBjYXNlIEZjT3BPcjoKICAgIGNhc2UgRmNPcEFuZDoKICAgIGNhc2UgRmNPcFBsdXM6CiAgICBjYXNlIEZjT3BNaW51czoKICAgIGNhc2UgRmNPcFRpbWVzOgogICAgY2FzZSBGY09wRGl2aWRlOgoJdmwgPSBGY0NvbmZpZ0V2YWx1YXRlIChwLCBlLT51LnRyZWUubGVmdCk7Cgl2ciA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUtPnUudHJlZS5yaWdodCk7Cgl2bCA9IEZjQ29uZmlnUHJvbW90ZSAodmwsIHZyKTsKCXZyID0gRmNDb25maWdQcm9tb3RlICh2ciwgdmwpOwoJaWYgKHZsLnR5cGUgPT0gdnIudHlwZSkKCXsKCSAgICBzd2l0Y2ggKHZsLnR5cGUpIHsKCSAgICBjYXNlIEZjVHlwZURvdWJsZToKCQlzd2l0Y2ggKGUtPm9wKSB7CgkJY2FzZSBGY09wUGx1czoJICAgCgkJICAgIHYudHlwZSA9IEZjVHlwZURvdWJsZTsKCQkgICAgdi51LmQgPSB2bC51LmQgKyB2ci51LmQ7IAoJCSAgICBicmVhazsKCQljYXNlIEZjT3BNaW51czoKCQkgICAgdi50eXBlID0gRmNUeXBlRG91YmxlOwoJCSAgICB2LnUuZCA9IHZsLnUuZCAtIHZyLnUuZDsgCgkJICAgIGJyZWFrOwoJCWNhc2UgRmNPcFRpbWVzOgoJCSAgICB2LnR5cGUgPSBGY1R5cGVEb3VibGU7CgkJICAgIHYudS5kID0gdmwudS5kICogdnIudS5kOyAKCQkgICAgYnJlYWs7CgkJY2FzZSBGY09wRGl2aWRlOgoJCSAgICB2LnR5cGUgPSBGY1R5cGVEb3VibGU7CgkJICAgIHYudS5kID0gdmwudS5kIC8gdnIudS5kOyAKCQkgICAgYnJlYWs7CgkJZGVmYXVsdDoKCQkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsgCgkJICAgIGJyZWFrOwoJCX0KCQlpZiAodi50eXBlID09IEZjVHlwZURvdWJsZSAmJgoJCSAgICB2LnUuZCA9PSAoZG91YmxlKSAoaW50KSB2LnUuZCkKCQl7CgkJICAgIHYudHlwZSA9IEZjVHlwZUludGVnZXI7CgkJICAgIHYudS5pID0gKGludCkgdi51LmQ7CgkJfQoJCWJyZWFrOwoJICAgIGNhc2UgRmNUeXBlQm9vbDoKCQlzd2l0Y2ggKGUtPm9wKSB7CgkJY2FzZSBGY09wT3I6CgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CgkJICAgIHYudS5iID0gdmwudS5iIHx8IHZyLnUuYjsKCQkgICAgYnJlYWs7CgkJY2FzZSBGY09wQW5kOgoJCSAgICB2LnR5cGUgPSBGY1R5cGVCb29sOwoJCSAgICB2LnUuYiA9IHZsLnUuYiAmJiB2ci51LmI7CgkJICAgIGJyZWFrOwoJCWRlZmF1bHQ6CgkJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7IAoJCSAgICBicmVhazsKCQl9CgkJYnJlYWs7CgkgICAgY2FzZSBGY1R5cGVTdHJpbmc6CgkJc3dpdGNoIChlLT5vcCkgewoJCWNhc2UgRmNPcFBsdXM6CgkJICAgIHYudHlwZSA9IEZjVHlwZVN0cmluZzsKCQkgICAgdi51LnMgPSBGY1N0clBsdXMgKHZsLnUucywgdnIudS5zKTsKCQkgICAgaWYgKCF2LnUucykKCQkJdi50eXBlID0gRmNUeXBlVm9pZDsKCQkgICAgYnJlYWs7CgkJZGVmYXVsdDoKCQkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsKCQkgICAgYnJlYWs7CgkJfQoJCWJyZWFrOwoJICAgIGNhc2UgRmNUeXBlTWF0cml4OgoJCXN3aXRjaCAoZS0+b3ApIHsKCQljYXNlIEZjT3BUaW1lczoKCQkgICAgdi50eXBlID0gRmNUeXBlTWF0cml4OwoJCSAgICBtID0gbWFsbG9jIChzaXplb2YgKEZjTWF0cml4KSk7CgkJICAgIGlmIChtKQoJCSAgICB7CgkJCUZjTWVtQWxsb2MgKEZDX01FTV9NQVRSSVgsIHNpemVvZiAoRmNNYXRyaXgpKTsKCQkJRmNNYXRyaXhNdWx0aXBseSAobSwgdmwudS5tLCB2ci51Lm0pOwoJCQl2LnUubSA9IG07CgkJICAgIH0KCQkgICAgZWxzZQoJCSAgICB7CgkJCXYudHlwZSA9IEZjVHlwZVZvaWQ7CgkJICAgIH0KCQkgICAgYnJlYWs7CgkJZGVmYXVsdDoKCQkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsKCQkgICAgYnJlYWs7CgkJfQoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJdi50eXBlID0gRmNUeXBlVm9pZDsKCQlicmVhazsKCSAgICB9Cgl9CgllbHNlCgkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsKCUZjVmFsdWVEZXN0cm95ICh2bCk7CglGY1ZhbHVlRGVzdHJveSAodnIpOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BOb3Q6Cgl2bCA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUtPnUudHJlZS5sZWZ0KTsKCXN3aXRjaCAodmwudHlwZSkgewoJY2FzZSBGY1R5cGVCb29sOgoJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CgkgICAgdi51LmIgPSAhdmwudS5iOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOwoJICAgIGJyZWFrOwoJfQoJRmNWYWx1ZURlc3Ryb3kgKHZsKTsKCWJyZWFrOwogICAgY2FzZSBGY09wRmxvb3I6Cgl2bCA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUtPnUudHJlZS5sZWZ0KTsKCXN3aXRjaCAodmwudHlwZSkgewoJY2FzZSBGY1R5cGVJbnRlZ2VyOgoJICAgIHYgPSB2bDsKCSAgICBicmVhazsKCWNhc2UgRmNUeXBlRG91YmxlOgoJICAgIHYudHlwZSA9IEZjVHlwZUludGVnZXI7CgkgICAgdi51LmkgPSBGY0RvdWJsZUZsb29yICh2bC51LmQpOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOwoJICAgIGJyZWFrOwoJfQoJRmNWYWx1ZURlc3Ryb3kgKHZsKTsKCWJyZWFrOwogICAgY2FzZSBGY09wQ2VpbDoKCXZsID0gRmNDb25maWdFdmFsdWF0ZSAocCwgZS0+dS50cmVlLmxlZnQpOwoJc3dpdGNoICh2bC50eXBlKSB7CgljYXNlIEZjVHlwZUludGVnZXI6CgkgICAgdiA9IHZsOwoJICAgIGJyZWFrOwoJY2FzZSBGY1R5cGVEb3VibGU6CgkgICAgdi50eXBlID0gRmNUeXBlSW50ZWdlcjsKCSAgICB2LnUuaSA9IEZjRG91YmxlQ2VpbCAodmwudS5kKTsKCSAgICBicmVhazsKCWRlZmF1bHQ6CgkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsKCSAgICBicmVhazsKCX0KCUZjVmFsdWVEZXN0cm95ICh2bCk7CglicmVhazsKICAgIGNhc2UgRmNPcFJvdW5kOgoJdmwgPSBGY0NvbmZpZ0V2YWx1YXRlIChwLCBlLT51LnRyZWUubGVmdCk7Cglzd2l0Y2ggKHZsLnR5cGUpIHsKCWNhc2UgRmNUeXBlSW50ZWdlcjoKCSAgICB2ID0gdmw7CgkgICAgYnJlYWs7CgljYXNlIEZjVHlwZURvdWJsZToKCSAgICB2LnR5cGUgPSBGY1R5cGVJbnRlZ2VyOwoJICAgIHYudS5pID0gRmNEb3VibGVSb3VuZCAodmwudS5kKTsKCSAgICBicmVhazsKCWRlZmF1bHQ6CgkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsKCSAgICBicmVhazsKCX0KCUZjVmFsdWVEZXN0cm95ICh2bCk7CglicmVhazsKICAgIGNhc2UgRmNPcFRydW5jOgoJdmwgPSBGY0NvbmZpZ0V2YWx1YXRlIChwLCBlLT51LnRyZWUubGVmdCk7Cglzd2l0Y2ggKHZsLnR5cGUpIHsKCWNhc2UgRmNUeXBlSW50ZWdlcjoKCSAgICB2ID0gdmw7CgkgICAgYnJlYWs7CgljYXNlIEZjVHlwZURvdWJsZToKCSAgICB2LnR5cGUgPSBGY1R5cGVJbnRlZ2VyOwoJICAgIHYudS5pID0gRmNEb3VibGVUcnVuYyAodmwudS5kKTsKCSAgICBicmVhazsKCWRlZmF1bHQ6CgkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsKCSAgICBicmVhazsKCX0KCUZjVmFsdWVEZXN0cm95ICh2bCk7CglicmVhazsKICAgIGRlZmF1bHQ6Cgl2LnR5cGUgPSBGY1R5cGVWb2lkOwoJYnJlYWs7CiAgICB9CiAgICByZXR1cm4gdjsKfQoKc3RhdGljIEZjVmFsdWVMaXN0ICoKRmNDb25maWdNYXRjaFZhbHVlTGlzdCAoRmNQYXR0ZXJuCSpwLAoJCQlGY1Rlc3QJCSp0LAoJCQlGY1ZhbHVlTGlzdAkqdmFsdWVzKQp7CiAgICBGY1ZhbHVlTGlzdAkgICAgKnJldCA9IDA7CiAgICBGY0V4cHIJICAgICplID0gdC0+ZXhwcjsKICAgIEZjVmFsdWUJICAgIHZhbHVlOwogICAgRmNWYWx1ZUxpc3QJICAgICp2OwogICAgCiAgICB3aGlsZSAoZSkKICAgIHsKCS8qIENvbXB1dGUgdGhlIHZhbHVlIG9mIHRoZSBtYXRjaCBleHByZXNzaW9uICovCglpZiAoZS0+b3AgPT0gRmNPcENvbW1hKQoJewoJICAgIHZhbHVlID0gRmNDb25maWdFdmFsdWF0ZSAocCwgZS0+dS50cmVlLmxlZnQpOwoJICAgIGUgPSBlLT51LnRyZWUucmlnaHQ7Cgl9CgllbHNlCgl7CgkgICAgdmFsdWUgPSBGY0NvbmZpZ0V2YWx1YXRlIChwLCBlKTsKCSAgICBlID0gMDsKCX0KCglmb3IgKHYgPSB2YWx1ZXM7IHY7IHYgPSB2LT5uZXh0KQoJewoJICAgIC8qIENvbXBhcmUgdGhlIHBhdHRlcm4gdmFsdWUgdG8gdGhlIG1hdGNoIGV4cHJlc3Npb24gdmFsdWUgKi8KCSAgICBpZiAoRmNDb25maWdDb21wYXJlVmFsdWUgKHYtPnZhbHVlLCB0LT5vcCwgdmFsdWUpKQoJICAgIHsKCQlpZiAoIXJldCkKCQkgICAgcmV0ID0gdjsKCSAgICB9CgkgICAgZWxzZQoJICAgIHsKCQlpZiAodC0+cXVhbCA9PSBGY1F1YWxBbGwpCgkJewoJCSAgICByZXQgPSAwOwoJCSAgICBicmVhazsKCQl9CgkgICAgfQoJfQoJRmNWYWx1ZURlc3Ryb3kgKHZhbHVlKTsKICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCnN0YXRpYyBGY1ZhbHVlTGlzdCAqCkZjQ29uZmlnVmFsdWVzIChGY1BhdHRlcm4gKnAsIEZjRXhwciAqZSwgRmNWYWx1ZUJpbmRpbmcgYmluZGluZykKewogICAgRmNWYWx1ZUxpc3QJKmw7CiAgICAKICAgIGlmICghZSkKCXJldHVybiAwOwogICAgbCA9IChGY1ZhbHVlTGlzdCAqKSBtYWxsb2MgKHNpemVvZiAoRmNWYWx1ZUxpc3QpKTsKICAgIGlmICghbCkKCXJldHVybiAwOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX1ZBTExJU1QsIHNpemVvZiAoRmNWYWx1ZUxpc3QpKTsKICAgIGlmIChlLT5vcCA9PSBGY09wQ29tbWEpCiAgICB7CglsLT52YWx1ZSA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUtPnUudHJlZS5sZWZ0KTsKCWwtPm5leHQgID0gRmNDb25maWdWYWx1ZXMgKHAsIGUtPnUudHJlZS5yaWdodCwgYmluZGluZyk7CiAgICB9CiAgICBlbHNlCiAgICB7CglsLT52YWx1ZSA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUpOwoJbC0+bmV4dCAgPSAwOwogICAgfQogICAgbC0+YmluZGluZyA9IGJpbmRpbmc7CiAgICB3aGlsZSAobCAmJiBsLT52YWx1ZS50eXBlID09IEZjVHlwZVZvaWQpCiAgICB7CglGY1ZhbHVlTGlzdAkqbmV4dCA9IGwtPm5leHQ7CgkKCUZjTWVtRnJlZSAoRkNfTUVNX1ZBTExJU1QsIHNpemVvZiAoRmNWYWx1ZUxpc3QpKTsKCWZyZWUgKGwpOwoJbCA9IG5leHQ7CiAgICB9CiAgICByZXR1cm4gbDsKfQoKc3RhdGljIEZjQm9vbApGY0NvbmZpZ0FkZCAoRmNWYWx1ZUxpc3QgICAgKipoZWFkLAoJICAgICBGY1ZhbHVlTGlzdCAgICAqcG9zaXRpb24sCgkgICAgIEZjQm9vbAkgICAgYXBwZW5kLAoJICAgICBGY1ZhbHVlTGlzdCAgICAqbmV3KQp7CiAgICBGY1ZhbHVlTGlzdAkgICAgKipwcmV2LCAqbGFzdCwgKnY7CiAgICBGY1ZhbHVlQmluZGluZyAgc2FtZUJpbmRpbmc7CiAgICAKICAgIGlmIChwb3NpdGlvbikKCXNhbWVCaW5kaW5nID0gcG9zaXRpb24tPmJpbmRpbmc7CiAgICBlbHNlCglzYW1lQmluZGluZyA9IEZjVmFsdWVCaW5kaW5nV2VhazsKICAgIGZvciAodiA9IG5ldzsgdjsgdiA9IHYtPm5leHQpCglpZiAodi0+YmluZGluZyA9PSBGY1ZhbHVlQmluZGluZ1NhbWUpCgkgICAgdi0+YmluZGluZyA9IHNhbWVCaW5kaW5nOwogICAgaWYgKGFwcGVuZCkKICAgIHsKCWlmIChwb3NpdGlvbikKCSAgICBwcmV2ID0gJnBvc2l0aW9uLT5uZXh0OwoJZWxzZQoJICAgIGZvciAocHJldiA9IGhlYWQ7ICpwcmV2OyBwcmV2ID0gJigqcHJldiktPm5leHQpCgkJOwogICAgfQogICAgZWxzZQogICAgewoJaWYgKHBvc2l0aW9uKQoJewoJICAgIGZvciAocHJldiA9IGhlYWQ7ICpwcmV2OyBwcmV2ID0gJigqcHJldiktPm5leHQpCgkgICAgewoJCWlmICgqcHJldiA9PSBwb3NpdGlvbikKCQkgICAgYnJlYWs7CgkgICAgfQoJfQoJZWxzZQoJICAgIHByZXYgPSBoZWFkOwoKCWlmIChGY0RlYnVnICgpICYgRkNfREJHX0VESVQpCgl7CgkgICAgaWYgKCEqcHJldikKCQlwcmludGYgKCJwb3NpdGlvbiBub3Qgb24gbGlzdFxuIik7Cgl9CiAgICB9CgogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRURJVCkKICAgIHsKCXByaW50ZiAoIiVzIGxpc3QgYmVmb3JlICIsIGFwcGVuZCA/ICJBcHBlbmQiIDogIlByZXBlbmQiKTsKCUZjVmFsdWVMaXN0UHJpbnQgKCpoZWFkKTsKCXByaW50ZiAoIlxuIik7CiAgICB9CiAgICAKICAgIGlmIChuZXcpCiAgICB7CglsYXN0ID0gbmV3OwoJd2hpbGUgKGxhc3QtPm5leHQpCgkgICAgbGFzdCA9IGxhc3QtPm5leHQ7CiAgICAKCWxhc3QtPm5leHQgPSAqcHJldjsKCSpwcmV2ID0gbmV3OwogICAgfQogICAgCiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19FRElUKQogICAgewoJcHJpbnRmICgiJXMgbGlzdCBhZnRlciAiLCBhcHBlbmQgPyAiQXBwZW5kIiA6ICJQcmVwZW5kIik7CglGY1ZhbHVlTGlzdFByaW50ICgqaGVhZCk7CglwcmludGYgKCJcbiIpOwogICAgfQogICAgCiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgdm9pZApGY0NvbmZpZ0RlbCAoRmNWYWx1ZUxpc3QgICAgKipoZWFkLAoJICAgICBGY1ZhbHVlTGlzdCAgICAqcG9zaXRpb24pCnsKICAgIEZjVmFsdWVMaXN0ICAgICoqcHJldjsKCiAgICBmb3IgKHByZXYgPSBoZWFkOyAqcHJldjsgcHJldiA9ICYoKnByZXYpLT5uZXh0KQogICAgewoJaWYgKCpwcmV2ID09IHBvc2l0aW9uKQoJewoJICAgICpwcmV2ID0gcG9zaXRpb24tPm5leHQ7CgkgICAgcG9zaXRpb24tPm5leHQgPSAwOwoJICAgIEZjVmFsdWVMaXN0RGVzdHJveSAocG9zaXRpb24pOwoJICAgIGJyZWFrOwoJfQogICAgfQp9CgpzdGF0aWMgdm9pZApGY0NvbmZpZ1BhdHRlcm5BZGQgKEZjUGF0dGVybgkqcCwKCQkgICAgY29uc3QgY2hhcgkqb2JqZWN0LAoJCSAgICBGY1ZhbHVlTGlzdAkqbGlzdCwKCQkgICAgRmNCb29sCWFwcGVuZCkKewogICAgaWYgKGxpc3QpCiAgICB7CglGY1BhdHRlcm5FbHQgICAgKmUgPSBGY1BhdHRlcm5JbnNlcnRFbHQgKHAsIG9iamVjdCk7CiAgICAKCWlmICghZSkKCSAgICByZXR1cm47CglGY0NvbmZpZ0FkZCAoJmUtPnZhbHVlcywgMCwgYXBwZW5kLCBsaXN0KTsKICAgIH0KfQoKLyoKICogRGVsZXRlIGFsbCB2YWx1ZXMgYXNzb2NpYXRlZCB3aXRoIGEgZmllbGQKICovCnN0YXRpYyB2b2lkCkZjQ29uZmlnUGF0dGVybkRlbCAoRmNQYXR0ZXJuCSpwLAoJCSAgICBjb25zdCBjaGFyCSpvYmplY3QpCnsKICAgIEZjUGF0dGVybkVsdCAgICAqZSA9IEZjUGF0dGVybkZpbmRFbHQgKHAsIG9iamVjdCk7CiAgICBpZiAoIWUpCglyZXR1cm47CiAgICB3aGlsZSAoZS0+dmFsdWVzKQoJRmNDb25maWdEZWwgKCZlLT52YWx1ZXMsIGUtPnZhbHVlcyk7Cn0KCnN0YXRpYyB2b2lkCkZjQ29uZmlnUGF0dGVybkNhbm9uIChGY1BhdHRlcm4JICAgICpwLAoJCSAgICAgIGNvbnN0IGNoYXIgICAgKm9iamVjdCkKewogICAgRmNQYXR0ZXJuRWx0ICAgICplID0gRmNQYXR0ZXJuRmluZEVsdCAocCwgb2JqZWN0KTsKICAgIGlmICghZSkKCXJldHVybjsKICAgIGlmICghZS0+dmFsdWVzKQoJRmNQYXR0ZXJuRGVsIChwLCBvYmplY3QpOwp9CgpGY0Jvb2wKRmNDb25maWdTdWJzdGl0dXRlV2l0aFBhdCAoRmNDb25maWcgICAgKmNvbmZpZywKCQkJICAgRmNQYXR0ZXJuICAgKnAsCgkJCSAgIEZjUGF0dGVybiAgICpwX3BhdCwKCQkJICAgRmNNYXRjaEtpbmQga2luZCkKewogICAgRmNTdWJzdAkgICAgKnM7CiAgICBGY1N1YlN0YXRlCSAgICAqc3Q7CiAgICBpbnQJCSAgICBpOwogICAgRmNUZXN0CSAgICAqdDsKICAgIEZjRWRpdAkgICAgKmU7CiAgICBGY1ZhbHVlTGlzdAkgICAgKmw7CiAgICBGY1BhdHRlcm4JICAgICptOwoKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CgogICAgc3QgPSAoRmNTdWJTdGF0ZSAqKSBtYWxsb2MgKGNvbmZpZy0+bWF4T2JqZWN0cyAqIHNpemVvZiAoRmNTdWJTdGF0ZSkpOwogICAgaWYgKCFzdCAmJiBjb25maWctPm1heE9iamVjdHMpCglyZXR1cm4gRmNGYWxzZTsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9TVUJTVEFURSwgY29uZmlnLT5tYXhPYmplY3RzICogc2l6ZW9mIChGY1N1YlN0YXRlKSk7CgogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRURJVCkKICAgIHsKCXByaW50ZiAoIkZjQ29uZmlnU3Vic3RpdHV0ZSAiKTsKCUZjUGF0dGVyblByaW50IChwKTsKICAgIH0KICAgIGlmIChraW5kID09IEZjTWF0Y2hQYXR0ZXJuKQoJcyA9IGNvbmZpZy0+c3Vic3RQYXR0ZXJuOwogICAgZWxzZQoJcyA9IGNvbmZpZy0+c3Vic3RGb250OwogICAgZm9yICg7IHM7IHMgPSBzLT5uZXh0KQogICAgewoJLyoKCSAqIENoZWNrIHRoZSB0ZXN0cyB0byBzZWUgaWYKCSAqIHRoZXkgYWxsIG1hdGNoIHRoZSBwYXR0ZXJuCgkgKi8KCWZvciAodCA9IHMtPnRlc3QsIGkgPSAwOyB0OyB0ID0gdC0+bmV4dCwgaSsrKQoJewoJICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0VESVQpCgkgICAgewoJCXByaW50ZiAoIkZjQ29uZmlnU3Vic3RpdHV0ZSB0ZXN0ICIpOwoJCUZjVGVzdFByaW50ICh0KTsKCSAgICB9CgkgICAgc3RbaV0uZWx0ID0gMDsKCSAgICBpZiAoa2luZCA9PSBGY01hdGNoRm9udCAmJiB0LT5raW5kID09IEZjTWF0Y2hQYXR0ZXJuKQoJCW0gPSBwX3BhdDsKCSAgICBlbHNlCgkJbSA9IHA7CgkgICAgaWYgKG0pCgkJc3RbaV0uZWx0ID0gRmNQYXR0ZXJuRmluZEVsdCAobSwgdC0+ZmllbGQpOwoJICAgIGVsc2UKCQlzdFtpXS5lbHQgPSAwOwoJICAgIC8qCgkgICAgICogSWYgdGhlcmUncyBubyBzdWNoIGZpZWxkIGluIHRoZSBmb250LAoJICAgICAqIHRoZW4gRmNRdWFsQWxsIG1hdGNoZXMgd2hpbGUgRmNRdWFsQW55IGRvZXMgbm90CgkgICAgICovCgkgICAgaWYgKCFzdFtpXS5lbHQpCgkgICAgewoJCWlmICh0LT5xdWFsID09IEZjUXVhbEFsbCkKCQl7CgkJICAgIHN0W2ldLnZhbHVlID0gMDsKCQkgICAgY29udGludWU7CgkJfQoJCWVsc2UKCQkgICAgYnJlYWs7CgkgICAgfQoJICAgIC8qCgkgICAgICogQ2hlY2sgdG8gc2VlIGlmIHRoZXJlIGlzIGEgbWF0Y2gsIG1hcmsgdGhlIGxvY2F0aW9uCgkgICAgICogdG8gYXBwbHkgbWF0Y2gtcmVsYXRpdmUgZWRpdHMKCSAgICAgKi8KCSAgICBzdFtpXS52YWx1ZSA9IEZjQ29uZmlnTWF0Y2hWYWx1ZUxpc3QgKG0sIHQsIHN0W2ldLmVsdC0+dmFsdWVzKTsKCSAgICBpZiAoIXN0W2ldLnZhbHVlKQoJCWJyZWFrOwoJICAgIGlmICh0LT5xdWFsID09IEZjUXVhbEZpcnN0ICYmIHN0W2ldLnZhbHVlICE9IHN0W2ldLmVsdC0+dmFsdWVzKQoJCWJyZWFrOwoJICAgIGlmICh0LT5xdWFsID09IEZjUXVhbE5vdEZpcnN0ICYmIHN0W2ldLnZhbHVlID09IHN0W2ldLmVsdC0+dmFsdWVzKQoJCWJyZWFrOwoJfQoJaWYgKHQpCgl7CgkgICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRURJVCkKCQlwcmludGYgKCJObyBtYXRjaFxuIik7CgkgICAgY29udGludWU7Cgl9CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19FRElUKQoJewoJICAgIHByaW50ZiAoIlN1YnN0aXR1dGUgIik7CgkgICAgRmNTdWJzdFByaW50IChzKTsKCX0KCWZvciAoZSA9IHMtPmVkaXQ7IGU7IGUgPSBlLT5uZXh0KQoJewoJICAgIC8qCgkgICAgICogRXZhbHVhdGUgdGhlIGxpc3Qgb2YgZXhwcmVzc2lvbnMKCSAgICAgKi8KCSAgICBsID0gRmNDb25maWdWYWx1ZXMgKHAsIGUtPmV4cHIsIGUtPmJpbmRpbmcpOwoJICAgIC8qCgkgICAgICogTG9jYXRlIGFueSB0ZXN0IGFzc29jaWF0ZWQgd2l0aCB0aGlzIGZpZWxkLCBza2lwcGluZwoJICAgICAqIHRlc3RzIGFzc29jaWF0ZWQgd2l0aCB0aGUgcGF0dGVybiB3aGVuIHN1YnN0aXR1dGluZyBpbgoJICAgICAqIHRoZSBmb250CgkgICAgICovCgkgICAgZm9yICh0ID0gcy0+dGVzdCwgaSA9IDA7IHQ7IHQgPSB0LT5uZXh0LCBpKyspCgkgICAgewoJCWlmICgodC0+a2luZCA9PSBGY01hdGNoRm9udCB8fCBraW5kID09IEZjTWF0Y2hQYXR0ZXJuKSAmJgoJCSAgICAhRmNTdHJDbXBJZ25vcmVDYXNlICgoRmNDaGFyOCAqKSB0LT5maWVsZCwgCgkJCQkJIChGY0NoYXI4ICopIGUtPmZpZWxkKSkKCQl7CgkJICAgIC8qIAoJCSAgICAgKiBLTFVER0UgLSB0aGUgcGF0dGVybiBtYXkgaGF2ZSBiZWVuIHJlYWxsb2NhdGVkIG9yCgkJICAgICAqIHRoaW5ncyBtYXkgaGF2ZSBiZWVuIGluc2VydGVkIG9yIGRlbGV0ZWQgYWJvdmUKCQkgICAgICogdGhpcyBlbGVtZW50IGJ5IG90aGVyIGVkaXRzLiAgR28gYmFjayBhbmQgZmluZAoJCSAgICAgKiB0aGUgZWxlbWVudCBhZ2FpbgoJCSAgICAgKi8KCQkgICAgaWYgKGUgIT0gcy0+ZWRpdCAmJiBzdFtpXS5lbHQpCgkJCXN0W2ldLmVsdCA9IEZjUGF0dGVybkZpbmRFbHQgKHAsIHQtPmZpZWxkKTsKCQkgICAgaWYgKCFzdFtpXS5lbHQpCgkJCXQgPSAwOwoJCSAgICBicmVhazsKCQl9CgkgICAgfQoJICAgIHN3aXRjaCAoZS0+b3ApIHsKCSAgICBjYXNlIEZjT3BBc3NpZ246CgkJLyoKCQkgKiBJZiB0aGVyZSB3YXMgYSB0ZXN0LCB0aGVuIHJlcGxhY2UgdGhlIG1hdGNoZWQKCQkgKiB2YWx1ZSB3aXRoIHRoZSBuZXcgbGlzdCBvZiB2YWx1ZXMKCQkgKi8KCQlpZiAodCkKCQl7CgkJICAgIEZjVmFsdWVMaXN0CSp0aGlzVmFsdWUgPSBzdFtpXS52YWx1ZTsKCQkgICAgRmNWYWx1ZUxpc3QJKm5leHRWYWx1ZSA9IHRoaXNWYWx1ZSA/IHRoaXNWYWx1ZS0+bmV4dCA6IDA7CgkJICAgIAoJCSAgICAvKgoJCSAgICAgKiBBcHBlbmQgdGhlIG5ldyBsaXN0IG9mIHZhbHVlcyBhZnRlciB0aGUgY3VycmVudCB2YWx1ZQoJCSAgICAgKi8KCQkgICAgRmNDb25maWdBZGQgKCZzdFtpXS5lbHQtPnZhbHVlcywgdGhpc1ZhbHVlLCBGY1RydWUsIGwpOwoJCSAgICAvKgoJCSAgICAgKiBEZWxldGUgdGhlIG1hcmtlZCB2YWx1ZQoJCSAgICAgKi8KCQkgICAgRmNDb25maWdEZWwgKCZzdFtpXS5lbHQtPnZhbHVlcywgdGhpc1ZhbHVlKTsKCQkgICAgLyoKCQkgICAgICogQWRqdXN0IGFueSBwb2ludGVycyBpbnRvIHRoZSB2YWx1ZSBsaXN0IHRvIGVuc3VyZQoJCSAgICAgKiBmdXR1cmUgZWRpdHMgb2NjdXIgYXQgdGhlIHNhbWUgcGxhY2UKCQkgICAgICovCgkJICAgIGZvciAodCA9IHMtPnRlc3QsIGkgPSAwOyB0OyB0ID0gdC0+bmV4dCwgaSsrKQoJCSAgICB7CgkJCWlmIChzdFtpXS52YWx1ZSA9PSB0aGlzVmFsdWUpCgkJCSAgICBzdFtpXS52YWx1ZSA9IG5leHRWYWx1ZTsKCQkgICAgfQoJCSAgICBicmVhazsKCQl9CgkJLyogZmFsbCB0aHJvdWdoIC4uLiAqLwoJICAgIGNhc2UgRmNPcEFzc2lnblJlcGxhY2U6CgkJLyoKCQkgKiBEZWxldGUgYWxsIG9mIHRoZSB2YWx1ZXMgYW5kIGluc2VydAoJCSAqIHRoZSBuZXcgc2V0CgkJICovCgkJRmNDb25maWdQYXR0ZXJuRGVsIChwLCBlLT5maWVsZCk7CgkJRmNDb25maWdQYXR0ZXJuQWRkIChwLCBlLT5maWVsZCwgbCwgRmNUcnVlKTsKCQkvKgoJCSAqIEFkanVzdCBhbnkgcG9pbnRlcnMgaW50byB0aGUgdmFsdWUgbGlzdCBhcyB0aGV5IG5vCgkJICogbG9uZ2VyIHBvaW50IHRvIGFueXRoaW5nIHZhbGlkCgkJICovCgkJaWYgKHQpCgkJewoJCSAgICBGY1BhdHRlcm5FbHQgICAgKnRoaXNFbHQgPSBzdFtpXS5lbHQ7CgkJICAgIGZvciAodCA9IHMtPnRlc3QsIGkgPSAwOyB0OyB0ID0gdC0+bmV4dCwgaSsrKQoJCSAgICB7CgkJCWlmIChzdFtpXS5lbHQgPT0gdGhpc0VsdCkKCQkJICAgIHN0W2ldLnZhbHVlID0gMDsKCQkgICAgfQoJCX0KCQlicmVhazsKCSAgICBjYXNlIEZjT3BQcmVwZW5kOgoJCWlmICh0KQoJCXsKCQkgICAgRmNDb25maWdBZGQgKCZzdFtpXS5lbHQtPnZhbHVlcywgc3RbaV0udmFsdWUsIEZjRmFsc2UsIGwpOwoJCSAgICBicmVhazsKCQl9CgkJLyogZmFsbCB0aHJvdWdoIC4uLiAqLwoJICAgIGNhc2UgRmNPcFByZXBlbmRGaXJzdDoKCQlGY0NvbmZpZ1BhdHRlcm5BZGQgKHAsIGUtPmZpZWxkLCBsLCBGY0ZhbHNlKTsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BBcHBlbmQ6CgkJaWYgKHQpCgkJewoJCSAgICBGY0NvbmZpZ0FkZCAoJnN0W2ldLmVsdC0+dmFsdWVzLCBzdFtpXS52YWx1ZSwgRmNUcnVlLCBsKTsKCQkgICAgYnJlYWs7CgkJfQoJCS8qIGZhbGwgdGhyb3VnaCAuLi4gKi8KCSAgICBjYXNlIEZjT3BBcHBlbmRMYXN0OgoJCUZjQ29uZmlnUGF0dGVybkFkZCAocCwgZS0+ZmllbGQsIGwsIEZjVHJ1ZSk7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCSAgICB9Cgl9CgkvKgoJICogTm93IGdvIHRocm91Z2ggdGhlIHBhdHRlcm4gYW5kIGVsaW1pbmF0ZQoJICogYW55IHByb3BlcnRpZXMgd2l0aG91dCBkYXRhCgkgKi8KCWZvciAoZSA9IHMtPmVkaXQ7IGU7IGUgPSBlLT5uZXh0KQoJICAgIEZjQ29uZmlnUGF0dGVybkNhbm9uIChwLCBlLT5maWVsZCk7CgoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRURJVCkKCXsKCSAgICBwcmludGYgKCJGY0NvbmZpZ1N1YnN0aXR1dGUgZWRpdCIpOwoJICAgIEZjUGF0dGVyblByaW50IChwKTsKCX0KICAgIH0KICAgIEZjTWVtRnJlZSAoRkNfTUVNX1NVQlNUQVRFLCBjb25maWctPm1heE9iamVjdHMgKiBzaXplb2YgKEZjU3ViU3RhdGUpKTsKICAgIGZyZWUgKHN0KTsKICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0VESVQpCiAgICB7CglwcmludGYgKCJGY0NvbmZpZ1N1YnN0aXR1dGUgZG9uZSIpOwoJRmNQYXR0ZXJuUHJpbnQgKHApOwogICAgfQogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNCb29sCkZjQ29uZmlnU3Vic3RpdHV0ZSAoRmNDb25maWcJKmNvbmZpZywKCQkgICAgRmNQYXR0ZXJuCSpwLAoJCSAgICBGY01hdGNoS2luZAlraW5kKQp7CiAgICByZXR1cm4gRmNDb25maWdTdWJzdGl0dXRlV2l0aFBhdCAoY29uZmlnLCBwLCAwLCBraW5kKTsKfQoKI2lmIGRlZmluZWQgKF9XSU4zMikgJiYgKGRlZmluZWQgKFBJQykgfHwgZGVmaW5lZCAoRExMX0VYUE9SVCkpCgpzdGF0aWMgRmNDaGFyOCBmb250Y29uZmlnX3BhdGhbMTAwMF0gPSAiIjsKCkJPT0wgV0lOQVBJCkRsbE1haW4gKEhJTlNUQU5DRSBoaW5zdERMTCwKCSBEV09SRCAgICAgZmR3UmVhc29uLAoJIExQVk9JRCAgICBscHZSZXNlcnZlZCkKewogIEZjQ2hhcjggKnA7CgogIHN3aXRjaCAoZmR3UmVhc29uKSB7CiAgY2FzZSBETExfUFJPQ0VTU19BVFRBQ0g6CiAgICAgIGlmICghR2V0TW9kdWxlRmlsZU5hbWUgKChITU9EVUxFKSBoaW5zdERMTCwgZm9udGNvbmZpZ19wYXRoLAoJCQkgICAgICBzaXplb2YgKGZvbnRjb25maWdfcGF0aCkpKQoJICBicmVhazsKCiAgICAgIC8qIElmIHRoZSBmb250Y29uZmlnIERMTCBpcyBpbiBhICJiaW4iIG9yICJsaWIiIHN1YmZvbGRlciwKICAgICAgICogYXNzdW1lIGl0J3MgYSBVbml4LXN0eWxlIGluc3RhbGxhdGlvbiB0cmVlLCBhbmQgdXNlCiAgICAgICAqICJldGMvZm9udHMiIGluIHRoZXJlIGFzIEZPTlRDT05GSUdfUEFUSC4gT3RoZXJ3aXNlIHVzZSB0aGUKICAgICAgICogZm9sZGVyIHdoZXJlIHRoZSBETEwgaXMgYXMgRk9OVENPTkZJR19QQVRILgogICAgICAgKi8KICAgICAgcCA9IHN0cnJjaHIgKGZvbnRjb25maWdfcGF0aCwgJ1xcJyk7CiAgICAgIGlmIChwKQogICAgICB7CgkgICpwID0gJ1wwJzsKCSAgcCA9IHN0cnJjaHIgKGZvbnRjb25maWdfcGF0aCwgJ1xcJyk7CgkgIGlmIChwICYmIChGY1N0ckNtcElnbm9yZUNhc2UgKHAgKyAxLCAiYmluIikgPT0gMCB8fAoJCSAgICBGY1N0ckNtcElnbm9yZUNhc2UgKHAgKyAxLCAibGliIikgPT0gMCkpCgkgICAgICAqcCA9ICdcMCc7CgkgIHN0cmNhdCAoZm9udGNvbmZpZ19wYXRoLCAiXFxldGNcXGZvbnRzIik7CiAgICAgIH0KICAgICAgZWxzZQogICAgICAgICAgZm9udGNvbmZpZ19wYXRoWzBdID0gJ1wwJzsKICAgICAgCiAgICAgIGJyZWFrOwogIH0KCiAgcmV0dXJuIFRSVUU7Cn0KCiN1bmRlZiBGT05UQ09ORklHX1BBVEgKI2RlZmluZSBGT05UQ09ORklHX1BBVEggZm9udGNvbmZpZ19wYXRoCgojZWxzZSAvKiAhKF9XSU4zMiAmJiBQSUMpICovCgojZW5kaWYgLyogIShfV0lOMzIgJiYgUElDKSAqLwoKI2lmbmRlZiBGT05UQ09ORklHX0ZJTEUKI2RlZmluZSBGT05UQ09ORklHX0ZJTEUJImZvbnRzLmNvbmYiCiNlbmRpZgoKc3RhdGljIEZjQ2hhcjggKgpGY0NvbmZpZ0ZpbGVFeGlzdHMgKGNvbnN0IEZjQ2hhcjggKmRpciwgY29uc3QgRmNDaGFyOCAqZmlsZSkKewogICAgRmNDaGFyOCAgICAqcGF0aDsKCiAgICBpZiAoIWRpcikKCWRpciA9IChGY0NoYXI4ICopICIiOwogICAgcGF0aCA9IG1hbGxvYyAoc3RybGVuICgoY2hhciAqKSBkaXIpICsgMSArIHN0cmxlbiAoKGNoYXIgKikgZmlsZSkgKyAxKTsKICAgIGlmICghcGF0aCkKCXJldHVybiAwOwoKICAgIHN0cmNweSAoKGNoYXIgKikgcGF0aCwgKGNvbnN0IGNoYXIgKikgZGlyKTsKICAgIC8qIG1ha2Ugc3VyZSB0aGVyZSdzIGEgc2luZ2xlIHNlcGFyYXRvciAqLwojaWZkZWYgX1dJTjMyCiAgICBpZiAoKCFwYXRoWzBdIHx8IChwYXRoW3N0cmxlbigoY2hhciAqKSBwYXRoKS0xXSAhPSAnLycgJiYKCQkgICAgICBwYXRoW3N0cmxlbigoY2hhciAqKSBwYXRoKS0xXSAhPSAnXFwnKSkgJiYKCSAoZmlsZVswXSAhPSAnLycgJiYgZmlsZVswXSAhPSAnXFwnKSkKCXN0cmNhdCAoKGNoYXIgKikgcGF0aCwgIlxcIik7CiNlbHNlCiAgICBpZiAoKCFwYXRoWzBdIHx8IHBhdGhbc3RybGVuKChjaGFyICopIHBhdGgpLTFdICE9ICcvJykgJiYgZmlsZVswXSAhPSAnLycpCglzdHJjYXQgKChjaGFyICopIHBhdGgsICIvIik7CiNlbmRpZgogICAgc3RyY2F0ICgoY2hhciAqKSBwYXRoLCAoY2hhciAqKSBmaWxlKTsKCiAgICBGY01lbUFsbG9jIChGQ19NRU1fU1RSSU5HLCBzdHJsZW4gKChjaGFyICopIHBhdGgpICsgMSk7CiAgICBpZiAoYWNjZXNzICgoY2hhciAqKSBwYXRoLCBSX09LKSA9PSAwKQoJcmV0dXJuIHBhdGg7CiAgICAKICAgIEZjU3RyRnJlZSAocGF0aCk7CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIEZjQ2hhcjggKioKRmNDb25maWdHZXRQYXRoICh2b2lkKQp7CiAgICBGY0NoYXI4ICAgICoqcGF0aDsKICAgIEZjQ2hhcjggICAgKmVudiwgKmUsICpjb2xvbjsKICAgIEZjQ2hhcjggICAgKmRpcjsKICAgIGludAkgICAgbnBhdGg7CiAgICBpbnQJICAgIGk7CgogICAgbnBhdGggPSAyOwkvKiBkZWZhdWx0IGRpciArIG51bGwgKi8KICAgIGVudiA9IChGY0NoYXI4ICopIGdldGVudiAoIkZPTlRDT05GSUdfUEFUSCIpOwogICAgaWYgKGVudikKICAgIHsKCWUgPSBlbnY7CglucGF0aCsrOwoJd2hpbGUgKCplKQoJICAgIGlmICgqZSsrID09IEZDX1NFQVJDSF9QQVRIX1NFUEFSQVRPUikKCQlucGF0aCsrOwogICAgfQogICAgcGF0aCA9IGNhbGxvYyAobnBhdGgsIHNpemVvZiAoRmNDaGFyOCAqKSk7CiAgICBpZiAoIXBhdGgpCglnb3RvIGJhaWwwOwogICAgaSA9IDA7CgogICAgaWYgKGVudikKICAgIHsKCWUgPSBlbnY7Cgl3aGlsZSAoKmUpIAoJewoJICAgIGNvbG9uID0gKEZjQ2hhcjggKikgc3RyY2hyICgoY2hhciAqKSBlLCBGQ19TRUFSQ0hfUEFUSF9TRVBBUkFUT1IpOwoJICAgIGlmICghY29sb24pCgkJY29sb24gPSBlICsgc3RybGVuICgoY2hhciAqKSBlKTsKCSAgICBwYXRoW2ldID0gbWFsbG9jIChjb2xvbiAtIGUgKyAxKTsKCSAgICBpZiAoIXBhdGhbaV0pCgkJZ290byBiYWlsMTsKCSAgICBzdHJuY3B5ICgoY2hhciAqKSBwYXRoW2ldLCAoY29uc3QgY2hhciAqKSBlLCBjb2xvbiAtIGUpOwoJICAgIHBhdGhbaV1bY29sb24gLSBlXSA9ICdcMCc7CgkgICAgaWYgKCpjb2xvbikKCQllID0gY29sb24gKyAxOwoJICAgIGVsc2UKCQllID0gY29sb247CgkgICAgaSsrOwoJfQogICAgfQogICAgCiAgICBkaXIgPSAoRmNDaGFyOCAqKSBGT05UQ09ORklHX1BBVEg7CiAgICBwYXRoW2ldID0gbWFsbG9jIChzdHJsZW4gKChjaGFyICopIGRpcikgKyAxKTsKICAgIGlmICghcGF0aFtpXSkKCWdvdG8gYmFpbDE7CiAgICBzdHJjcHkgKChjaGFyICopIHBhdGhbaV0sIChjb25zdCBjaGFyICopIGRpcik7CiAgICByZXR1cm4gcGF0aDsKCmJhaWwxOgogICAgZm9yIChpID0gMDsgcGF0aFtpXTsgaSsrKQoJZnJlZSAocGF0aFtpXSk7CiAgICBmcmVlIChwYXRoKTsKYmFpbDA6CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQKRmNDb25maWdGcmVlUGF0aCAoRmNDaGFyOCAqKnBhdGgpCnsKICAgIEZjQ2hhcjggICAgKipwOwoKICAgIGZvciAocCA9IHBhdGg7ICpwOyBwKyspCglmcmVlICgqcCk7CiAgICBmcmVlIChwYXRoKTsKfQoKc3RhdGljIEZjQm9vbAlfRmNDb25maWdIb21lRW5hYmxlZCA9IEZjVHJ1ZTsKCkZjQ2hhcjggKgpGY0NvbmZpZ0hvbWUgKHZvaWQpCnsKICAgIGlmIChfRmNDb25maWdIb21lRW5hYmxlZCkKICAgIHsKICAgICAgICBjaGFyICpob21lID0gZ2V0ZW52ICgiSE9NRSIpOwoKI2lmZGVmIF9XSU4zMgoJaWYgKGhvbWUgPT0gTlVMTCkKCSAgICBob21lID0gZ2V0ZW52ICgiVVNFUlBST0ZJTEUiKTsKI2VuZGlmCgoJcmV0dXJuIGhvbWU7CiAgICB9CiAgICByZXR1cm4gMDsKfQoKRmNCb29sCkZjQ29uZmlnRW5hYmxlSG9tZSAoRmNCb29sIGVuYWJsZSkKewogICAgRmNCb29sICBwcmV2ID0gX0ZjQ29uZmlnSG9tZUVuYWJsZWQ7CiAgICBfRmNDb25maWdIb21lRW5hYmxlZCA9IGVuYWJsZTsKICAgIHJldHVybiBwcmV2Owp9CgpGY0NoYXI4ICoKRmNDb25maWdGaWxlbmFtZSAoY29uc3QgRmNDaGFyOCAqdXJsKQp7CiAgICBGY0NoYXI4ICAgICpmaWxlLCAqZGlyLCAqKnBhdGgsICoqcDsKICAgIAogICAgaWYgKCF1cmwgfHwgISp1cmwpCiAgICB7Cgl1cmwgPSAoRmNDaGFyOCAqKSBnZXRlbnYgKCJGT05UQ09ORklHX0ZJTEUiKTsKCWlmICghdXJsKQoJICAgIHVybCA9IChGY0NoYXI4ICopIEZPTlRDT05GSUdfRklMRTsKICAgIH0KICAgIGZpbGUgPSAwOwoKI2lmZGVmIF9XSU4zMgogICAgaWYgKGlzYWxwaGEgKCp1cmwpICYmCgl1cmxbMV0gPT0gJzonICYmCgkodXJsWzJdID09ICcvJyB8fCB1cmxbMl0gPT0gJ1xcJykpCglnb3RvIGFic29sdXRlX3BhdGg7CiNlbmRpZgoKICAgIHN3aXRjaCAoKnVybCkgewogICAgY2FzZSAnfic6CglkaXIgPSBGY0NvbmZpZ0hvbWUgKCk7CglpZiAoZGlyKQoJICAgIGZpbGUgPSBGY0NvbmZpZ0ZpbGVFeGlzdHMgKGRpciwgdXJsICsgMSk7CgllbHNlCgkgICAgZmlsZSA9IDA7CglicmVhazsKI2lmZGVmIF9XSU4zMgogICAgY2FzZSAnXFwnOgogICAgYWJzb2x1dGVfcGF0aDoKI2VuZGlmCiAgICBjYXNlICcvJzoKCWZpbGUgPSBGY0NvbmZpZ0ZpbGVFeGlzdHMgKDAsIHVybCk7CglicmVhazsKICAgIGRlZmF1bHQ6CglwYXRoID0gRmNDb25maWdHZXRQYXRoICgpOwoJaWYgKCFwYXRoKQoJICAgIHJldHVybiAwOwoJZm9yIChwID0gcGF0aDsgKnA7IHArKykKCXsKCSAgICBmaWxlID0gRmNDb25maWdGaWxlRXhpc3RzICgqcCwgdXJsKTsKCSAgICBpZiAoZmlsZSkKCQlicmVhazsKCX0KCUZjQ29uZmlnRnJlZVBhdGggKHBhdGgpOwoJYnJlYWs7CiAgICB9CiAgICByZXR1cm4gZmlsZTsKfQoKLyoKICogTWFuYWdlIHRoZSBhcHBsaWNhdGlvbi1zcGVjaWZpYyBmb250cwogKi8KCkZjQm9vbApGY0NvbmZpZ0FwcEZvbnRBZGRGaWxlIChGY0NvbmZpZyAgICAqY29uZmlnLAoJCQljb25zdCBGY0NoYXI4ICAqZmlsZSkKewogICAgRmNGb250U2V0CSpzZXQ7CiAgICBGY1N0clNldAkqc3ViZGlyczsKICAgIEZjU3RyTGlzdAkqc3VibGlzdDsKICAgIEZjQ2hhcjgJKnN1YmRpcjsKCiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgfQoKICAgIHN1YmRpcnMgPSBGY1N0clNldENyZWF0ZSAoKTsKICAgIGlmICghc3ViZGlycykKCXJldHVybiBGY0ZhbHNlOwogICAgCiAgICBzZXQgPSBGY0NvbmZpZ0dldEZvbnRzIChjb25maWcsIEZjU2V0QXBwbGljYXRpb24pOwogICAgaWYgKCFzZXQpCiAgICB7CglzZXQgPSBGY0ZvbnRTZXRDcmVhdGUgKCk7CglpZiAoIXNldCkKCXsKCSAgICBGY1N0clNldERlc3Ryb3kgKHN1YmRpcnMpOwoJICAgIHJldHVybiBGY0ZhbHNlOwoJfQoJRmNDb25maWdTZXRGb250cyAoY29uZmlnLCBzZXQsIEZjU2V0QXBwbGljYXRpb24pOwogICAgfQoJCiAgICBpZiAoIUZjRmlsZVNjYW5Db25maWcgKHNldCwgc3ViZGlycywgMCwgY29uZmlnLT5ibGFua3MsIGZpbGUsIEZjRmFsc2UsIGNvbmZpZykpCiAgICB7CglGY1N0clNldERlc3Ryb3kgKHN1YmRpcnMpOwoJcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBpZiAoKHN1Ymxpc3QgPSBGY1N0ckxpc3RDcmVhdGUgKHN1YmRpcnMpKSkKICAgIHsKCXdoaWxlICgoc3ViZGlyID0gRmNTdHJMaXN0TmV4dCAoc3VibGlzdCkpKQoJewoJICAgIEZjQ29uZmlnQXBwRm9udEFkZERpciAoY29uZmlnLCBzdWJkaXIpOwoJfQoJRmNTdHJMaXN0RG9uZSAoc3VibGlzdCk7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNDb25maWdBcHBGb250QWRkRGlyIChGY0NvbmZpZwkgICAgKmNvbmZpZywKCQkgICAgICAgY29uc3QgRmNDaGFyOCAgICpkaXIpCnsKICAgIEZjRm9udFNldAkqc2V0OwogICAgRmNTdHJTZXQJKnN1YmRpcnM7CiAgICBGY1N0ckxpc3QJKnN1Ymxpc3Q7CiAgICBGY0NoYXI4CSpzdWJkaXI7CiAgICAKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBzdWJkaXJzID0gRmNTdHJTZXRDcmVhdGUgKCk7CiAgICBpZiAoIXN1YmRpcnMpCglyZXR1cm4gRmNGYWxzZTsKICAgIAogICAgc2V0ID0gRmNDb25maWdHZXRGb250cyAoY29uZmlnLCBGY1NldEFwcGxpY2F0aW9uKTsKICAgIGlmICghc2V0KQogICAgewoJc2V0ID0gRmNGb250U2V0Q3JlYXRlICgpOwoJaWYgKCFzZXQpCgl7CgkgICAgRmNTdHJTZXREZXN0cm95IChzdWJkaXJzKTsKCSAgICByZXR1cm4gRmNGYWxzZTsKCX0KCUZjQ29uZmlnU2V0Rm9udHMgKGNvbmZpZywgc2V0LCBGY1NldEFwcGxpY2F0aW9uKTsKICAgIH0KICAgIAogICAgaWYgKCFGY0RpclNjYW5Db25maWcgKHNldCwgc3ViZGlycywgMCwgY29uZmlnLT5ibGFua3MsIGRpciwgRmNGYWxzZSwgY29uZmlnKSkKICAgIHsKCUZjU3RyU2V0RGVzdHJveSAoc3ViZGlycyk7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIGlmICgoc3VibGlzdCA9IEZjU3RyTGlzdENyZWF0ZSAoc3ViZGlycykpKQogICAgewoJd2hpbGUgKChzdWJkaXIgPSBGY1N0ckxpc3ROZXh0IChzdWJsaXN0KSkpCgl7CgkgICAgRmNDb25maWdBcHBGb250QWRkRGlyIChjb25maWcsIHN1YmRpcik7Cgl9CglGY1N0ckxpc3REb25lIChzdWJsaXN0KTsKICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCnZvaWQKRmNDb25maWdBcHBGb250Q2xlYXIgKEZjQ29uZmlnCSAgICAqY29uZmlnKQp7CiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybjsKICAgIH0KCiAgICBGY0NvbmZpZ1NldEZvbnRzIChjb25maWcsIDAsIEZjU2V0QXBwbGljYXRpb24pOwp9CgovKgogKiBNYW5hZ2UgZmlsZW5hbWUtYmFzZWQgZm9udCBzb3VyY2Ugc2VsZWN0b3JzCiAqLwoKRmNCb29sCkZjQ29uZmlnR2xvYkFkZCAoRmNDb25maWcJKmNvbmZpZywKCQkgY29uc3QgRmNDaGFyOCAgKmdsb2IsCgkJIEZjQm9vbAkJYWNjZXB0KQp7CiAgICBGY1N0clNldAkqc2V0ID0gYWNjZXB0ID8gY29uZmlnLT5hY2NlcHRHbG9icyA6IGNvbmZpZy0+cmVqZWN0R2xvYnM7CgogICAgcmV0dXJuIEZjU3RyU2V0QWRkIChzZXQsIGdsb2IpOwp9CgpzdGF0aWMgRmNCb29sCkZjQ29uZmlnR2xvYk1hdGNoIChjb25zdCBGY0NoYXI4ICAgICpnbG9iLAoJCSAgIGNvbnN0IEZjQ2hhcjggICAgKnN0cmluZykKewogICAgRmNDaGFyOAljOwoKICAgIHdoaWxlICgoYyA9ICpnbG9iKyspKSAKICAgIHsKCXN3aXRjaCAoYykgewoJY2FzZSAnKic6CgkgICAgLyogc2hvcnQgY2lyY3VpdCBjb21tb24gY2FzZSAqLwoJICAgIGlmICghKmdsb2IpCgkJcmV0dXJuIEZjVHJ1ZTsKCSAgICAvKiBzaG9ydCBjaXJjdWl0IGFub3RoZXIgY29tbW9uIGNhc2UgKi8KCSAgICBpZiAoc3RyY2hyICgoY2hhciAqKSBnbG9iLCAnKicpID09IDApCgkJc3RyaW5nICs9IHN0cmxlbiAoKGNoYXIgKikgc3RyaW5nKSAtIHN0cmxlbiAoKGNoYXIgKikgZ2xvYik7CgkgICAgd2hpbGUgKCpzdHJpbmcpCgkgICAgewoJCWlmIChGY0NvbmZpZ0dsb2JNYXRjaCAoZ2xvYiwgc3RyaW5nKSkKCQkgICAgcmV0dXJuIEZjVHJ1ZTsKCQlzdHJpbmcrKzsKCSAgICB9CgkgICAgcmV0dXJuIEZjRmFsc2U7CgljYXNlICc/JzoKCSAgICBpZiAoKnN0cmluZysrID09ICdcMCcpCgkJcmV0dXJuIEZjRmFsc2U7CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIGlmICgqc3RyaW5nKysgIT0gYykKCQlyZXR1cm4gRmNGYWxzZTsKCSAgICBicmVhazsKCX0KICAgIH0KICAgIHJldHVybiAqc3RyaW5nID09ICdcMCc7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNDb25maWdHbG9ic01hdGNoIChjb25zdCBGY1N0clNldAkqZ2xvYnMsCgkJICAgIGNvbnN0IEZjQ2hhcjgJKnN0cmluZykKewogICAgaW50CWk7CgogICAgZm9yIChpID0gMDsgaSA8IGdsb2JzLT5udW07IGkrKykKCWlmIChGY0NvbmZpZ0dsb2JNYXRjaCAoZ2xvYnMtPnN0cnNbaV0sIHN0cmluZykpCgkgICAgcmV0dXJuIEZjVHJ1ZTsKICAgIHJldHVybiBGY0ZhbHNlOwp9CgpGY0Jvb2wKRmNDb25maWdBY2NlcHRGaWxlbmFtZSAoRmNDb25maWcJKmNvbmZpZywKCQkJY29uc3QgRmNDaGFyOAkqZmlsZW5hbWUpCnsKICAgIGlmIChGY0NvbmZpZ0dsb2JzTWF0Y2ggKGNvbmZpZy0+YWNjZXB0R2xvYnMsIGZpbGVuYW1lKSkKCXJldHVybiBGY1RydWU7CiAgICBpZiAoRmNDb25maWdHbG9ic01hdGNoIChjb25maWctPnJlamVjdEdsb2JzLCBmaWxlbmFtZSkpCglyZXR1cm4gRmNGYWxzZTsKICAgIHJldHVybiBGY1RydWU7Cn0K