LyoKICogJFJDU0lkOiB4Yy9saWIvZm9udGNvbmZpZy9zcmMvZmNjZmcuYyx2IDEuMjMgMjAwMi8wOC8zMSAyMjoxNzozMiBrZWl0aHAgRXhwICQKICoKICogQ29weXJpZ2h0IKkgMjAwMCBLZWl0aCBQYWNrYXJkCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUsIGFuZCBzZWxsIHRoaXMgc29mdHdhcmUgYW5kIGl0cwogKiBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBpcyBoZXJlYnkgZ3JhbnRlZCB3aXRob3V0IGZlZSwgcHJvdmlkZWQgdGhhdAogKiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoYXQKICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZwogKiBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBLZWl0aCBQYWNrYXJkIG5vdCBiZSB1c2VkIGluCiAqIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dAogKiBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgS2VpdGggUGFja2FyZCBtYWtlcyBubwogKiByZXByZXNlbnRhdGlvbnMgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiAgSXQKICogaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KICoKICogS0VJVEggUEFDS0FSRCBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwKICogSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTwogKiBFVkVOVCBTSEFMTCBLRUlUSCBQQUNLQVJEIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SCiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLAogKiBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgojaW5jbHVkZSAiZmNpbnQuaCIKCiNpZiBkZWZpbmVkIChfV0lOMzIpICYmIChkZWZpbmVkIChQSUMpIHx8IGRlZmluZWQgKERMTF9FWFBPUlQpKQojZGVmaW5lIFNUUklDVAojaW5jbHVkZSA8d2luZG93cy5oPgojdW5kZWYgU1RSSUNUCiNlbmRpZgoKI2lmIGRlZmluZWQgKF9XSU4zMikgJiYgIWRlZmluZWQgKFJfT0spCiNkZWZpbmUgUl9PSyA0CiNlbmRpZgoKRmNDb25maWcgICAgKl9mY0NvbmZpZzsKCkZjQ29uZmlnICoKRmNDb25maWdDcmVhdGUgKHZvaWQpCnsKICAgIEZjU2V0TmFtZQlzZXQ7CiAgICBGY0NvbmZpZwkqY29uZmlnOwoKICAgIGNvbmZpZyA9IG1hbGxvYyAoc2l6ZW9mIChGY0NvbmZpZykpOwogICAgaWYgKCFjb25maWcpCglnb3RvIGJhaWwwOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX0NPTkZJRywgc2l6ZW9mIChGY0NvbmZpZykpOwogICAgCiAgICBjb25maWctPmNvbmZpZ0RpcnMgPSBGY1N0clNldENyZWF0ZSAoKTsKICAgIGlmICghY29uZmlnLT5jb25maWdEaXJzKQoJZ290byBiYWlsMTsKICAgIAogICAgY29uZmlnLT5jb25maWdGaWxlcyA9IEZjU3RyU2V0Q3JlYXRlICgpOwogICAgaWYgKCFjb25maWctPmNvbmZpZ0ZpbGVzKQoJZ290byBiYWlsMjsKICAgIAogICAgY29uZmlnLT5mb250RGlycyA9IEZjU3RyU2V0Q3JlYXRlICgpOwogICAgaWYgKCFjb25maWctPmZvbnREaXJzKQoJZ290byBiYWlsMzsKICAgIAogICAgY29uZmlnLT5hY2NlcHRHbG9icyA9IEZjU3RyU2V0Q3JlYXRlICgpOwogICAgaWYgKCFjb25maWctPmFjY2VwdEdsb2JzKQoJZ290byBiYWlsNDsKCiAgICBjb25maWctPnJlamVjdEdsb2JzID0gRmNTdHJTZXRDcmVhdGUgKCk7CiAgICBpZiAoIWNvbmZpZy0+cmVqZWN0R2xvYnMpCglnb3RvIGJhaWw1OwoKICAgIGNvbmZpZy0+YWNjZXB0UGF0dGVybnMgPSBGY0ZvbnRTZXRDcmVhdGUgKCk7CiAgICBpZiAoIWNvbmZpZy0+YWNjZXB0UGF0dGVybnMpCglnb3RvIGJhaWw2OwogICAgCiAgICBjb25maWctPnJlamVjdFBhdHRlcm5zID0gRmNGb250U2V0Q3JlYXRlICgpOwogICAgaWYgKCFjb25maWctPnJlamVjdFBhdHRlcm5zKQoJZ290byBiYWlsNzsKCiAgICBjb25maWctPmNhY2hlID0gMDsKICAgIGlmIChGY0NvbmZpZ0hvbWUoKSkKCWlmICghRmNDb25maWdTZXRDYWNoZSAoY29uZmlnLCAoRmNDaGFyOCAqKSAoIn4vIiBGQ19VU0VSX0NBQ0hFX0ZJTEUpKSkKCSAgICBnb3RvIGJhaWw4OwoKI2lmZGVmIF9XSU4zMgogICAgaWYgKGNvbmZpZy0+Y2FjaGUgPT0gMCkKICAgIHsKCS8qIElmIG5vIGhvbWUsIHVzZSB0aGUgdGVtcCBmb2xkZXIuICovCglGY0NoYXI4CSAgICBkdW1teVsxXTsKCWludAkgICAgdGVtcGxlbiA9IEdldFRlbXBQYXRoICgxLCBkdW1teSk7CglGY0NoYXI4ICAgICAqdGVtcCA9IG1hbGxvYyAodGVtcGxlbiArIDEpOwoKCWlmICh0ZW1wKQoJewoJICAgIEZjQ2hhcjggKmNhY2hlX2RpcjsKCgkgICAgR2V0VGVtcFBhdGggKHRlbXBsZW4gKyAxLCB0ZW1wKTsKCSAgICBjYWNoZV9kaXIgPSBGY1N0clBsdXMgKHRlbXAsIEZDX1VTRVJfQ0FDSEVfRklMRSk7CgkgICAgZnJlZSAodGVtcCk7CgkgICAgaWYgKCFGY0NvbmZpZ1NldENhY2hlIChjb25maWcsIGNhY2hlX2RpcikpCgkgICAgewoJCUZjU3RyRnJlZSAoY2FjaGVfZGlyKTsKCQlnb3RvIGJhaWw2OwoJICAgIH0KCSAgICBGY1N0ckZyZWUgKGNhY2hlX2Rpcik7Cgl9CiAgICB9CiNlbmRpZgoKICAgIGNvbmZpZy0+YmxhbmtzID0gMDsKCiAgICBjb25maWctPnN1YnN0UGF0dGVybiA9IDA7CiAgICBjb25maWctPnN1YnN0Rm9udCA9IDA7CiAgICBjb25maWctPm1heE9iamVjdHMgPSAwOwogICAgZm9yIChzZXQgPSBGY1NldFN5c3RlbTsgc2V0IDw9IEZjU2V0QXBwbGljYXRpb247IHNldCsrKQoJY29uZmlnLT5mb250c1tzZXRdID0gMDsKCiAgICBjb25maWctPnJlc2NhblRpbWUgPSB0aW1lKDApOwogICAgY29uZmlnLT5yZXNjYW5JbnRlcnZhbCA9IDMwOyAgICAKICAgIAogICAgcmV0dXJuIGNvbmZpZzsKCmJhaWw4OgogICAgRmNGb250U2V0RGVzdHJveSAoY29uZmlnLT5yZWplY3RQYXR0ZXJucyk7CmJhaWw3OgogICAgRmNGb250U2V0RGVzdHJveSAoY29uZmlnLT5hY2NlcHRQYXR0ZXJucyk7CmJhaWw2OgogICAgRmNTdHJTZXREZXN0cm95IChjb25maWctPnJlamVjdEdsb2JzKTsKYmFpbDU6CiAgICBGY1N0clNldERlc3Ryb3kgKGNvbmZpZy0+YWNjZXB0R2xvYnMpOwpiYWlsNDoKICAgIEZjU3RyU2V0RGVzdHJveSAoY29uZmlnLT5mb250RGlycyk7CmJhaWwzOgogICAgRmNTdHJTZXREZXN0cm95IChjb25maWctPmNvbmZpZ0ZpbGVzKTsKYmFpbDI6CiAgICBGY1N0clNldERlc3Ryb3kgKGNvbmZpZy0+Y29uZmlnRGlycyk7CmJhaWwxOgogICAgZnJlZSAoY29uZmlnKTsKICAgIEZjTWVtRnJlZSAoRkNfTUVNX0NPTkZJRywgc2l6ZW9mIChGY0NvbmZpZykpOwpiYWlsMDoKICAgIHJldHVybiAwOwp9Cgp0eXBlZGVmIHN0cnVjdCBfRmNGaWxlVGltZSB7CiAgICB0aW1lX3QgIHRpbWU7CiAgICBGY0Jvb2wgIHNldDsKfSBGY0ZpbGVUaW1lOwoKc3RhdGljIEZjRmlsZVRpbWUKRmNDb25maWdOZXdlc3RGaWxlIChGY1N0clNldCAqZmlsZXMpCnsKICAgIEZjU3RyTGlzdAkgICAgKmxpc3QgPSBGY1N0ckxpc3RDcmVhdGUgKGZpbGVzKTsKICAgIEZjRmlsZVRpbWUJICAgIG5ld2VzdCA9IHsgMCwgRmNGYWxzZSB9OwogICAgRmNDaGFyOAkgICAgKmZpbGU7CiAgICBzdHJ1Y3QgIHN0YXQgICAgc3RhdGI7CgogICAgaWYgKGxpc3QpCiAgICB7Cgl3aGlsZSAoKGZpbGUgPSBGY1N0ckxpc3ROZXh0IChsaXN0KSkpCgkgICAgaWYgKHN0YXQgKChjaGFyICopIGZpbGUsICZzdGF0YikgPT0gMCkKCQlpZiAoIW5ld2VzdC5zZXQgfHwgc3RhdGIuc3RfbXRpbWUgLSBuZXdlc3QudGltZSA+IDApCgkJewoJCSAgICBuZXdlc3Quc2V0ID0gRmNUcnVlOwoJCSAgICBuZXdlc3QudGltZSA9IHN0YXRiLnN0X210aW1lOwoJCX0KCUZjU3RyTGlzdERvbmUgKGxpc3QpOwogICAgfQogICAgcmV0dXJuIG5ld2VzdDsKfQoKRmNCb29sCkZjQ29uZmlnVXB0b0RhdGUgKEZjQ29uZmlnICpjb25maWcpCnsKICAgIEZjRmlsZVRpbWUJY29uZmlnX3RpbWUsIGZvbnRfdGltZTsKICAgIHRpbWVfdAlub3cgPSB0aW1lKDApOwogICAgaWYgKCFjb25maWcpCiAgICB7Cgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICByZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIGNvbmZpZ190aW1lID0gRmNDb25maWdOZXdlc3RGaWxlIChjb25maWctPmNvbmZpZ0ZpbGVzKTsKICAgIGZvbnRfdGltZSA9IEZjQ29uZmlnTmV3ZXN0RmlsZSAoY29uZmlnLT5mb250RGlycyk7CiAgICBpZiAoKGNvbmZpZ190aW1lLnNldCAmJiBjb25maWdfdGltZS50aW1lIC0gY29uZmlnLT5yZXNjYW5UaW1lID4gMCkgfHwKCShmb250X3RpbWUuc2V0ICYmIChmb250X3RpbWUudGltZSAtIGNvbmZpZy0+cmVzY2FuVGltZSkgPiAwKSkKICAgIHsKCXJldHVybiBGY0ZhbHNlOwogICAgfQogICAgY29uZmlnLT5yZXNjYW5UaW1lID0gbm93OwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIHZvaWQKRmNTdWJzdERlc3Ryb3kgKEZjU3Vic3QgKnMpCnsKICAgIEZjU3Vic3QgKm47CiAgICAKICAgIHdoaWxlIChzKQogICAgewoJbiA9IHMtPm5leHQ7CglpZiAocy0+dGVzdCkKCSAgICBGY1Rlc3REZXN0cm95IChzLT50ZXN0KTsKCWlmIChzLT5lZGl0KQoJICAgIEZjRWRpdERlc3Ryb3kgKHMtPmVkaXQpOwoJZnJlZSAocyk7CglGY01lbUZyZWUgKEZDX01FTV9TVUJTVCwgc2l6ZW9mIChGY1N1YnN0KSk7CglzID0gbjsKICAgIH0KfQoKdm9pZApGY0NvbmZpZ0Rlc3Ryb3kgKEZjQ29uZmlnICpjb25maWcpCnsKICAgIEZjU2V0TmFtZQlzZXQ7CgogICAgaWYgKGNvbmZpZyA9PSBfZmNDb25maWcpCglfZmNDb25maWcgPSAwOwoKICAgIEZjU3RyU2V0RGVzdHJveSAoY29uZmlnLT5jb25maWdEaXJzKTsKICAgIEZjU3RyU2V0RGVzdHJveSAoY29uZmlnLT5mb250RGlycyk7CiAgICBGY1N0clNldERlc3Ryb3kgKGNvbmZpZy0+Y29uZmlnRmlsZXMpOwogICAgRmNTdHJTZXREZXN0cm95IChjb25maWctPmFjY2VwdEdsb2JzKTsKICAgIEZjU3RyU2V0RGVzdHJveSAoY29uZmlnLT5yZWplY3RHbG9icyk7CiAgICBGY0ZvbnRTZXREZXN0cm95IChjb25maWctPmFjY2VwdFBhdHRlcm5zKTsKICAgIEZjRm9udFNldERlc3Ryb3kgKGNvbmZpZy0+cmVqZWN0UGF0dGVybnMpOwoKICAgIGlmIChjb25maWctPmJsYW5rcykKCUZjQmxhbmtzRGVzdHJveSAoY29uZmlnLT5ibGFua3MpOwoKICAgIGlmIChjb25maWctPmNhY2hlKQoJRmNTdHJGcmVlIChjb25maWctPmNhY2hlKTsKCiAgICBGY1N1YnN0RGVzdHJveSAoY29uZmlnLT5zdWJzdFBhdHRlcm4pOwogICAgRmNTdWJzdERlc3Ryb3kgKGNvbmZpZy0+c3Vic3RGb250KTsKICAgIGZvciAoc2V0ID0gRmNTZXRTeXN0ZW07IHNldCA8PSBGY1NldEFwcGxpY2F0aW9uOyBzZXQrKykKCWlmIChjb25maWctPmZvbnRzW3NldF0pCgkgICAgRmNGb250U2V0RGVzdHJveSAoY29uZmlnLT5mb250c1tzZXRdKTsKCiAgICBmcmVlIChjb25maWcpOwogICAgRmNNZW1GcmVlIChGQ19NRU1fQ09ORklHLCBzaXplb2YgKEZjQ29uZmlnKSk7Cn0KCi8qCiAqIFNjYW4gdGhlIGN1cnJlbnQgbGlzdCBvZiBkaXJlY3RvcmllcyBpbiB0aGUgY29uZmlndXJhdGlvbgogKiBhbmQgYnVpbGQgdGhlIHNldCBvZiBhdmFpbGFibGUgZm9udHMuIFVwZGF0ZSB0aGUKICogcGVyLXVzZXIgY2FjaGUgZmlsZSB0byByZWZsZWN0IHRoZSBuZXcgY29uZmlndXJhdGlvbgogKi8KCkZjQm9vbApGY0NvbmZpZ0J1aWxkRm9udHMgKEZjQ29uZmlnICpjb25maWcpCnsKICAgIEZjRm9udFNldAkgICAgKmZvbnRzOwogICAgRmNHbG9iYWxDYWNoZSAgICpjYWNoZTsKICAgIEZjU3RyTGlzdAkgICAgKmxpc3Q7CiAgICBGY0NoYXI4CSAgICAqZGlyOwoKICAgIGZvbnRzID0gRmNGb250U2V0Q3JlYXRlICgpOwogICAgaWYgKCFmb250cykKCWdvdG8gYmFpbDA7CiAgICAKICAgIGNhY2hlID0gRmNHbG9iYWxDYWNoZUNyZWF0ZSAoKTsKICAgIGlmICghY2FjaGUpCglnb3RvIGJhaWwxOwoKICAgIGlmIChjb25maWctPmNhY2hlKQoJRmNHbG9iYWxDYWNoZUxvYWQgKGNhY2hlLCBjb25maWctPmNhY2hlKTsKCiAgICBsaXN0ID0gRmNDb25maWdHZXRGb250RGlycyAoY29uZmlnKTsKICAgIGlmICghbGlzdCkKCWdvdG8gYmFpbDE7CgogICAgd2hpbGUgKChkaXIgPSBGY1N0ckxpc3ROZXh0IChsaXN0KSkpCiAgICB7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19GT05UU0VUKQoJICAgIHByaW50ZiAoInNjYW4gZGlyICVzXG4iLCBkaXIpOwoJRmNEaXJTY2FuQ29uZmlnIChmb250cywgY29uZmlnLT5mb250RGlycywgY2FjaGUsIAoJCQkgY29uZmlnLT5ibGFua3MsIGRpciwgRmNGYWxzZSwgY29uZmlnKTsKICAgIH0KICAgIAogICAgRmNTdHJMaXN0RG9uZSAobGlzdCk7CiAgICAKICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0ZPTlRTRVQpCglGY0ZvbnRTZXRQcmludCAoZm9udHMpOwoKICAgIGlmIChjb25maWctPmNhY2hlKQoJRmNHbG9iYWxDYWNoZVNhdmUgKGNhY2hlLCBjb25maWctPmNhY2hlKTsKICAgIEZjR2xvYmFsQ2FjaGVEZXN0cm95IChjYWNoZSk7CgogICAgRmNDb25maWdTZXRGb250cyAoY29uZmlnLCBmb250cywgRmNTZXRTeXN0ZW0pOwogICAgCiAgICByZXR1cm4gRmNUcnVlOwpiYWlsMToKICAgIEZjRm9udFNldERlc3Ryb3kgKGZvbnRzKTsKYmFpbDA6CiAgICByZXR1cm4gRmNGYWxzZTsKfQoKRmNCb29sCkZjQ29uZmlnU2V0Q3VycmVudCAoRmNDb25maWcgKmNvbmZpZykKewogICAgaWYgKCFjb25maWctPmZvbnRzKQoJaWYgKCFGY0NvbmZpZ0J1aWxkRm9udHMgKGNvbmZpZykpCgkgICAgcmV0dXJuIEZjRmFsc2U7CgogICAgaWYgKF9mY0NvbmZpZykKCUZjQ29uZmlnRGVzdHJveSAoX2ZjQ29uZmlnKTsKICAgIF9mY0NvbmZpZyA9IGNvbmZpZzsKICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQ29uZmlnICoKRmNDb25maWdHZXRDdXJyZW50ICh2b2lkKQp7CiAgICBpZiAoIV9mY0NvbmZpZykKCWlmICghRmNJbml0ICgpKQoJICAgIHJldHVybiAwOwogICAgcmV0dXJuIF9mY0NvbmZpZzsKfQoKRmNCb29sCkZjQ29uZmlnQWRkQ29uZmlnRGlyIChGY0NvbmZpZwkgICAgKmNvbmZpZywKCQkgICAgICBjb25zdCBGY0NoYXI4ICpkKQp7CiAgICByZXR1cm4gRmNTdHJTZXRBZGRGaWxlbmFtZSAoY29uZmlnLT5jb25maWdEaXJzLCBkKTsKfQoKRmNTdHJMaXN0ICoKRmNDb25maWdHZXRDb25maWdEaXJzIChGY0NvbmZpZyAgICpjb25maWcpCnsKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIDA7CiAgICB9CiAgICByZXR1cm4gRmNTdHJMaXN0Q3JlYXRlIChjb25maWctPmNvbmZpZ0RpcnMpOwp9CgpGY0Jvb2wKRmNDb25maWdBZGRGb250RGlyIChGY0NvbmZpZwkgICAgKmNvbmZpZywKCQkgICAgY29uc3QgRmNDaGFyOCAgICpkKQp7CiAgICByZXR1cm4gRmNTdHJTZXRBZGRGaWxlbmFtZSAoY29uZmlnLT5mb250RGlycywgZCk7Cn0KCkZjQm9vbApGY0NvbmZpZ0FkZERpciAoRmNDb25maWcJICAgICpjb25maWcsCgkJY29uc3QgRmNDaGFyOAkgICAgKmQpCnsKICAgIHJldHVybiAoRmNDb25maWdBZGRDb25maWdEaXIgKGNvbmZpZywgZCkgJiYgCgkgICAgRmNDb25maWdBZGRGb250RGlyIChjb25maWcsIGQpKTsKfQoKRmNTdHJMaXN0ICoKRmNDb25maWdHZXRGb250RGlycyAoRmNDb25maWcJKmNvbmZpZykKewogICAgaWYgKCFjb25maWcpCiAgICB7Cgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICByZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiBGY1N0ckxpc3RDcmVhdGUgKGNvbmZpZy0+Zm9udERpcnMpOwp9CgpGY0Jvb2wKRmNDb25maWdBZGRDb25maWdGaWxlIChGY0NvbmZpZwkgICAgKmNvbmZpZywKCQkgICAgICAgY29uc3QgRmNDaGFyOCAgICpmKQp7CiAgICBGY0Jvb2wJcmV0OwogICAgRmNDaGFyOAkqZmlsZSA9IEZjQ29uZmlnRmlsZW5hbWUgKGYpOwogICAgCiAgICBpZiAoIWZpbGUpCglyZXR1cm4gRmNGYWxzZTsKICAgIAogICAgcmV0ID0gRmNTdHJTZXRBZGQgKGNvbmZpZy0+Y29uZmlnRmlsZXMsIGZpbGUpOwogICAgRmNTdHJGcmVlIChmaWxlKTsKICAgIHJldHVybiByZXQ7Cn0KCkZjU3RyTGlzdCAqCkZjQ29uZmlnR2V0Q29uZmlnRmlsZXMgKEZjQ29uZmlnICAgICpjb25maWcpCnsKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIDA7CiAgICB9CiAgICByZXR1cm4gRmNTdHJMaXN0Q3JlYXRlIChjb25maWctPmNvbmZpZ0ZpbGVzKTsKfQoKRmNCb29sCkZjQ29uZmlnU2V0Q2FjaGUgKEZjQ29uZmlnCSpjb25maWcsCgkJICBjb25zdCBGY0NoYXI4CSpjKQp7CiAgICBGY0NoYXI4ICAgICpuZXcgPSBGY1N0ckNvcHlGaWxlbmFtZSAoYyk7CiAgICAKICAgIGlmICghbmV3KQoJcmV0dXJuIEZjRmFsc2U7CiAgICBpZiAoY29uZmlnLT5jYWNoZSkKCUZjU3RyRnJlZSAoY29uZmlnLT5jYWNoZSk7CiAgICBjb25maWctPmNhY2hlID0gbmV3OwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNDaGFyOCAqCkZjQ29uZmlnR2V0Q2FjaGUgKEZjQ29uZmlnICAqY29uZmlnKQp7CiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiAwOwogICAgfQogICAgcmV0dXJuIGNvbmZpZy0+Y2FjaGU7Cn0KCkZjRm9udFNldCAqCkZjQ29uZmlnR2V0Rm9udHMgKEZjQ29uZmlnCSpjb25maWcsCgkJICBGY1NldE5hbWUJc2V0KQp7CiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiAwOwogICAgfQogICAgcmV0dXJuIGNvbmZpZy0+Zm9udHNbc2V0XTsKfQoKdm9pZApGY0NvbmZpZ1NldEZvbnRzIChGY0NvbmZpZwkqY29uZmlnLAoJCSAgRmNGb250U2V0CSpmb250cywKCQkgIEZjU2V0TmFtZQlzZXQpCnsKICAgIGlmIChjb25maWctPmZvbnRzW3NldF0pCglGY0ZvbnRTZXREZXN0cm95IChjb25maWctPmZvbnRzW3NldF0pOwogICAgY29uZmlnLT5mb250c1tzZXRdID0gZm9udHM7Cn0KCgoKRmNCbGFua3MgKgpGY0NvbmZpZ0dldEJsYW5rcyAoRmNDb25maWcJKmNvbmZpZykKewogICAgaWYgKCFjb25maWcpCiAgICB7Cgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICByZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiBjb25maWctPmJsYW5rczsKfQoKRmNCb29sCkZjQ29uZmlnQWRkQmxhbmsgKEZjQ29uZmlnCSpjb25maWcsCgkJICBGY0NoYXIzMiAgICAJYmxhbmspCnsKICAgIEZjQmxhbmtzCSpiOwogICAgCiAgICBiID0gY29uZmlnLT5ibGFua3M7CiAgICBpZiAoIWIpCiAgICB7CgliID0gRmNCbGFua3NDcmVhdGUgKCk7CglpZiAoIWIpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBpZiAoIUZjQmxhbmtzQWRkIChiLCBibGFuaykpCglyZXR1cm4gRmNGYWxzZTsKICAgIGNvbmZpZy0+YmxhbmtzID0gYjsKICAgIHJldHVybiBGY1RydWU7Cn0KCmludApGY0NvbmZpZ0dldFJlc2NhbkludmVydmFsIChGY0NvbmZpZyAqY29uZmlnKQp7CiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiAwOwogICAgfQogICAgcmV0dXJuIGNvbmZpZy0+cmVzY2FuSW50ZXJ2YWw7Cn0KCkZjQm9vbApGY0NvbmZpZ1NldFJlc2NhbkludmVydmFsIChGY0NvbmZpZyAqY29uZmlnLCBpbnQgcmVzY2FuSW50ZXJ2YWwpCnsKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBjb25maWctPnJlc2NhbkludGVydmFsID0gcmVzY2FuSW50ZXJ2YWw7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNDb25maWdBZGRFZGl0IChGY0NvbmZpZwkqY29uZmlnLAoJCSBGY1Rlc3QJCSp0ZXN0LAoJCSBGY0VkaXQJCSplZGl0LAoJCSBGY01hdGNoS2luZAlraW5kKQp7CiAgICBGY1N1YnN0CSpzdWJzdCwgKipwcmV2OwogICAgRmNUZXN0CSp0OwogICAgaW50CQludW07CgogICAgc3Vic3QgPSAoRmNTdWJzdCAqKSBtYWxsb2MgKHNpemVvZiAoRmNTdWJzdCkpOwogICAgaWYgKCFzdWJzdCkKCXJldHVybiBGY0ZhbHNlOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX1NVQlNULCBzaXplb2YgKEZjU3Vic3QpKTsKICAgIGlmIChraW5kID09IEZjTWF0Y2hQYXR0ZXJuKQoJcHJldiA9ICZjb25maWctPnN1YnN0UGF0dGVybjsKICAgIGVsc2UKCXByZXYgPSAmY29uZmlnLT5zdWJzdEZvbnQ7CiAgICBmb3IgKDsgKnByZXY7IHByZXYgPSAmKCpwcmV2KS0+bmV4dCk7CiAgICAqcHJldiA9IHN1YnN0OwogICAgc3Vic3QtPm5leHQgPSAwOwogICAgc3Vic3QtPnRlc3QgPSB0ZXN0OwogICAgc3Vic3QtPmVkaXQgPSBlZGl0OwogICAgbnVtID0gMDsKICAgIGZvciAodCA9IHRlc3Q7IHQ7IHQgPSB0LT5uZXh0KQogICAgewoJaWYgKHQtPmtpbmQgPT0gRmNNYXRjaERlZmF1bHQpCgkgICAgdC0+a2luZCA9IGtpbmQ7CgludW0rKzsKICAgIH0KICAgIGlmIChjb25maWctPm1heE9iamVjdHMgPCBudW0pCgljb25maWctPm1heE9iamVjdHMgPSBudW07CiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19FRElUKQogICAgewoJcHJpbnRmICgiQWRkIFN1YnN0ICIpOwoJRmNTdWJzdFByaW50IChzdWJzdCk7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9Cgp0eXBlZGVmIHN0cnVjdCBfRmNTdWJTdGF0ZSB7CiAgICBGY1BhdHRlcm5FbHQgICAqZWx0OwogICAgRmNWYWx1ZUxpc3QgICAgKnZhbHVlOwp9IEZjU3ViU3RhdGU7CgpzdGF0aWMgRmNWYWx1ZQpGY0NvbmZpZ1Byb21vdGUgKEZjVmFsdWUgdiwgRmNWYWx1ZSB1KQp7CiAgICBpZiAodi50eXBlID09IEZjVHlwZUludGVnZXIpCiAgICB7Cgl2LnR5cGUgPSBGY1R5cGVEb3VibGU7Cgl2LnUuZCA9IChkb3VibGUpIHYudS5pOwogICAgfQogICAgZWxzZSBpZiAodi50eXBlID09IEZjVHlwZVZvaWQgJiYgdS50eXBlID09IEZjVHlwZU1hdHJpeCkKICAgIHsKCXYudS5tID0gJkZjSWRlbnRpdHlNYXRyaXg7Cgl2LnR5cGUgPSBGY1R5cGVNYXRyaXg7CiAgICB9CiAgICBlbHNlIGlmICh2LnR5cGUgPT0gRmNUeXBlU3RyaW5nICYmIHUudHlwZSA9PSBGY1R5cGVMYW5nU2V0KQogICAgewoJdi51LmwgPSBGY0xhbmdTZXRQcm9tb3RlICh2LnUucyk7Cgl2LnR5cGUgPSBGY1R5cGVMYW5nU2V0OwogICAgfQogICAgcmV0dXJuIHY7Cn0KCkZjQm9vbApGY0NvbmZpZ0NvbXBhcmVWYWx1ZSAoY29uc3QgRmNWYWx1ZQlsZWZ0X28sCgkJICAgICAgRmNPcAkJb3AsCgkJICAgICAgY29uc3QgRmNWYWx1ZQlyaWdodF9vKQp7CiAgICBGY1ZhbHVlCWxlZnQgPSBsZWZ0X287CiAgICBGY1ZhbHVlCXJpZ2h0ID0gcmlnaHRfbzsKICAgIEZjQm9vbAlyZXQgPSBGY0ZhbHNlOwogICAgCiAgICBsZWZ0ID0gRmNDb25maWdQcm9tb3RlIChsZWZ0LCByaWdodCk7CiAgICByaWdodCA9IEZjQ29uZmlnUHJvbW90ZSAocmlnaHQsIGxlZnQpOwogICAgaWYgKGxlZnQudHlwZSA9PSByaWdodC50eXBlKSAKICAgIHsKCXN3aXRjaCAobGVmdC50eXBlKSB7CgljYXNlIEZjVHlwZUludGVnZXI6CgkgICAgYnJlYWs7CS8qIEZjQ29uZmlnUHJvbW90ZSBwcmV2ZW50cyB0aGlzIGZyb20gaGFwcGVuaW5nICovCgljYXNlIEZjVHlwZURvdWJsZToKCSAgICBzd2l0Y2ggKG9wKSB7CgkgICAgY2FzZSBGY09wRXF1YWw6CgkgICAgY2FzZSBGY09wQ29udGFpbnM6CgkgICAgY2FzZSBGY09wTGlzdGluZzoKCQlyZXQgPSBsZWZ0LnUuZCA9PSByaWdodC51LmQ7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTm90RXF1YWw6CgkgICAgY2FzZSBGY09wTm90Q29udGFpbnM6CgkJcmV0ID0gbGVmdC51LmQgIT0gcmlnaHQudS5kOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcExlc3M6ICAgIAoJCXJldCA9IGxlZnQudS5kIDwgcmlnaHQudS5kOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcExlc3NFcXVhbDogICAgCgkJcmV0ID0gbGVmdC51LmQgPD0gcmlnaHQudS5kOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcE1vcmU6ICAgIAoJCXJldCA9IGxlZnQudS5kID4gcmlnaHQudS5kOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcE1vcmVFcXVhbDogICAgCgkJcmV0ID0gbGVmdC51LmQgPj0gcmlnaHQudS5kOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBGY1R5cGVCb29sOgoJICAgIHN3aXRjaCAob3ApIHsKCSAgICBjYXNlIEZjT3BFcXVhbDogICAgCgkgICAgY2FzZSBGY09wQ29udGFpbnM6CgkgICAgY2FzZSBGY09wTGlzdGluZzoKCQlyZXQgPSBsZWZ0LnUuYiA9PSByaWdodC51LmI7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTm90RXF1YWw6CgkgICAgY2FzZSBGY09wTm90Q29udGFpbnM6CgkJcmV0ID0gbGVmdC51LmIgIT0gcmlnaHQudS5iOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBGY1R5cGVTdHJpbmc6CgkgICAgc3dpdGNoIChvcCkgewoJICAgIGNhc2UgRmNPcEVxdWFsOiAgICAKCSAgICBjYXNlIEZjT3BMaXN0aW5nOgoJCXJldCA9IEZjU3RyQ21wSWdub3JlQ2FzZSAobGVmdC51LnMsIHJpZ2h0LnUucykgPT0gMDsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BDb250YWluczoKCQlyZXQgPSBGY1N0clN0cklnbm9yZUNhc2UgKGxlZnQudS5zLCByaWdodC51LnMpICE9IDA7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTm90RXF1YWw6CgkgICAgY2FzZSBGY09wTm90Q29udGFpbnM6CgkJcmV0ID0gRmNTdHJDbXBJZ25vcmVDYXNlIChsZWZ0LnUucywgcmlnaHQudS5zKSAhPSAwOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBGY1R5cGVNYXRyaXg6CgkgICAgc3dpdGNoIChvcCkgewoJICAgIGNhc2UgRmNPcEVxdWFsOgoJICAgIGNhc2UgRmNPcENvbnRhaW5zOgoJICAgIGNhc2UgRmNPcExpc3Rpbmc6CgkJcmV0ID0gRmNNYXRyaXhFcXVhbCAobGVmdC51Lm0sIHJpZ2h0LnUubSk7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTm90RXF1YWw6CgkgICAgY2FzZSBGY09wTm90Q29udGFpbnM6CgkJcmV0ID0gIUZjTWF0cml4RXF1YWwgKGxlZnQudS5tLCByaWdodC51Lm0pOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBGY1R5cGVDaGFyU2V0OgoJICAgIHN3aXRjaCAob3ApIHsKCSAgICBjYXNlIEZjT3BDb250YWluczoKCSAgICBjYXNlIEZjT3BMaXN0aW5nOgoJCS8qIGxlZnQgY29udGFpbnMgcmlnaHQgaWYgcmlnaHQgaXMgYSBzdWJzZXQgb2YgbGVmdCAqLwoJCXJldCA9IEZjQ2hhclNldElzU3Vic2V0IChyaWdodC51LmMsIGxlZnQudS5jKTsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BOb3RDb250YWluczoKCQkvKiBsZWZ0IGNvbnRhaW5zIHJpZ2h0IGlmIHJpZ2h0IGlzIGEgc3Vic2V0IG9mIGxlZnQgKi8KCQlyZXQgPSAhRmNDaGFyU2V0SXNTdWJzZXQgKHJpZ2h0LnUuYywgbGVmdC51LmMpOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcEVxdWFsOgoJCXJldCA9IEZjQ2hhclNldEVxdWFsIChsZWZ0LnUuYywgcmlnaHQudS5jKTsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BOb3RFcXVhbDoKCQlyZXQgPSAhRmNDaGFyU2V0RXF1YWwgKGxlZnQudS5jLCByaWdodC51LmMpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBGY1R5cGVMYW5nU2V0OgoJICAgIHN3aXRjaCAob3ApIHsKCSAgICBjYXNlIEZjT3BDb250YWluczoKCSAgICBjYXNlIEZjT3BMaXN0aW5nOgoJCXJldCA9IEZjTGFuZ1NldENvbnRhaW5zIChsZWZ0LnUubCwgcmlnaHQudS5sKTsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BOb3RDb250YWluczoKCQlyZXQgPSAhRmNMYW5nU2V0Q29udGFpbnMgKGxlZnQudS5sLCByaWdodC51LmwpOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcEVxdWFsOgoJCXJldCA9IEZjTGFuZ1NldEVxdWFsIChsZWZ0LnUubCwgcmlnaHQudS5sKTsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BOb3RFcXVhbDoKCQlyZXQgPSAhRmNMYW5nU2V0RXF1YWwgKGxlZnQudS5sLCByaWdodC51LmwpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBGY1R5cGVWb2lkOgoJICAgIHN3aXRjaCAob3ApIHsKCSAgICBjYXNlIEZjT3BFcXVhbDoKCSAgICBjYXNlIEZjT3BDb250YWluczoKCSAgICBjYXNlIEZjT3BMaXN0aW5nOgoJCXJldCA9IEZjVHJ1ZTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgRmNUeXBlRlRGYWNlOgoJICAgIHN3aXRjaCAob3ApIHsKCSAgICBjYXNlIEZjT3BFcXVhbDoKCSAgICBjYXNlIEZjT3BDb250YWluczoKCSAgICBjYXNlIEZjT3BMaXN0aW5nOgoJCXJldCA9IGxlZnQudS5mID09IHJpZ2h0LnUuZjsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BOb3RFcXVhbDoKCSAgICBjYXNlIEZjT3BOb3RDb250YWluczoKCQlyZXQgPSBsZWZ0LnUuZiAhPSByaWdodC51LmY7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCSAgICB9CgkgICAgYnJlYWs7Cgl9CiAgICB9CiAgICBlbHNlCiAgICB7CglpZiAob3AgPT0gRmNPcE5vdEVxdWFsIHx8IG9wID09IEZjT3BOb3RDb250YWlucykKCSAgICByZXQgPSBGY1RydWU7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgoKI2RlZmluZSBfRmNEb3VibGVGbG9vcihkKQkoKGludCkgKGQpKQojZGVmaW5lIF9GY0RvdWJsZUNlaWwoZCkJKChkb3VibGUpIChpbnQpIChkKSA9PSAoZCkgPyAoaW50KSAoZCkgOiAoaW50KSAoKGQpICsgMSkpCiNkZWZpbmUgRmNEb3VibGVGbG9vcihkKQkoKGQpID49IDAgPyBfRmNEb3VibGVGbG9vcihkKSA6IC1fRmNEb3VibGVDZWlsKC0oZCkpKQojZGVmaW5lIEZjRG91YmxlQ2VpbChkKQkJKChkKSA+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+YWNjZXB0R2xvYnMsIGZpbGVuYW1lKSkKCXJldHVybiBGY1RydWU7CiAgICBpZiAoRmNDb25maWdHbG9ic01hdGNoIChjb25maWctPnJlamVjdEdsb2JzLCBmaWxlbmFtZSkpCglyZXR1cm4gRmNGYWxzZTsKICAgIHJldHVybiBGY1RydWU7Cn0KCi8qCiAqIE1hbmFnZSBmb250LXBhdHRlcm4gYmFzZWQgZm9udCBzb3VyY2Ugc2VsZWN0b3JzCiAqLwoKRmNCb29sCkZjQ29uZmlnUGF0dGVybnNBZGQgKEZjQ29uZmlnCSpjb25maWcsCgkJICAgICBGY1BhdHRlcm4JKnBhdHRlcm4sCgkJICAgICBGY0Jvb2wJYWNjZXB0KQp7CiAgICBGY0ZvbnRTZXQJKnNldCA9IGFjY2VwdCA/IGNvbmZpZy0+YWNjZXB0UGF0dGVybnMgOiBjb25maWctPnJlamVjdFBhdHRlcm5zOwoKICAgIHJldHVybiBGY0ZvbnRTZXRBZGQgKHNldCwgcGF0dGVybik7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNDb25maWdQYXR0ZXJuc01hdGNoIChjb25zdCBGY0ZvbnRTZXQJKnBhdHRlcm5zLAoJCSAgICAgICBjb25zdCBGY1BhdHRlcm4JKmZvbnQpCnsKICAgIGludCBpOwogICAgCiAgICBmb3IgKGkgPSAwOyBpIDwgcGF0dGVybnMtPm5mb250OyBpKyspCglpZiAoRmNMaXN0UGF0dGVybk1hdGNoQW55IChwYXR0ZXJucy0+Zm9udHNbaV0sIGZvbnQpKQoJICAgIHJldHVybiBGY1RydWU7CiAgICByZXR1cm4gRmNGYWxzZTsKfQoKRmNCb29sCkZjQ29uZmlnQWNjZXB0Rm9udCAoRmNDb25maWcJICAgICpjb25maWcsCgkJICAgIGNvbnN0IEZjUGF0dGVybiAqZm9udCkKewogICAgaWYgKEZjQ29uZmlnUGF0dGVybnNNYXRjaCAoY29uZmlnLT5hY2NlcHRQYXR0ZXJucywgZm9udCkpCglyZXR1cm4gRmNUcnVlOwogICAgaWYgKEZjQ29uZmlnUGF0dGVybnNNYXRjaCAoY29uZmlnLT5yZWplY3RQYXR0ZXJucywgZm9udCkpCglyZXR1cm4gRmNGYWxzZTsKICAgIHJldHVybiBGY1RydWU7Cn0K