LyoKICogYSBHVUkgYXBwbGljYXRpb24gZm9yIGRpc3BsYXlpbmcgYSBjb25zb2xlCiAqCVVTRVIzMiBiYWNrIGVuZAogKiBDb3B5cmlnaHQgMjAwMSBFcmljIFBvdWVjaAogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSAid2luZWNvbl91c2VyLmgiCiNpbmNsdWRlICJ3aW5ubHMuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTCh3aW5lY29uc29sZSk7CldJTkVfREVDTEFSRV9ERUJVR19DSEFOTkVMKHdjX2ZvbnQpOwoKVUlOVCBnX3VpRGVmYXVsdENoYXJzZXQ7CgovKiBtYXBwaW5nIGNvbnNvbGUgY29sb3JzIHRvIFJHQiB2YWx1ZXMgKi8KY29uc3QgQ09MT1JSRUYgV0NVU0VSX0NvbG9yTWFwWzE2XSA9CnsKICAgIFJHQigweDAwLCAweDAwLCAweDAwKSwgUkdCKDB4MDAsIDB4MDAsIDB4ODApLCBSR0IoMHgwMCwgMHg4MCwgMHgwMCksIFJHQigweDAwLCAweDgwLCAweDgwKSwKICAgIFJHQigweDgwLCAweDAwLCAweDAwKSwgUkdCKDB4ODAsIDB4MDAsIDB4ODApLCBSR0IoMHg4MCwgMHg4MCwgMHgwMCksIFJHQigweDgwLCAweDgwLCAweDgwKSwKICAgIFJHQigweEMwLCAweEMwLCAweEMwKSwgUkdCKDB4MDAsIDB4MDAsIDB4RkYpLCBSR0IoMHgwMCwgMHhGRiwgMHgwMCksIFJHQigweDAwLCAweEZGLCAweEZGKSwKICAgIFJHQigweEZGLCAweDAwLCAweDAwKSwgUkdCKDB4RkYsIDB4MDAsIDB4RkYpLCBSR0IoMHhGRiwgMHhGRiwgMHgwMCksIFJHQigweEZGLCAweEZGLCAweEZGKSwKfTsKCnN0YXRpYyBCT09MIFdDVVNFUl9TZXRGb250KHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBjb25zdCBMT0dGT05UKiBmb250KTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9GaWxsTWVtREMKICoKICogRmlsbHMgdGhlIE1lbSBEQyB3aXRoIGN1cnJlbnQgY2VsbHMgdmFsdWVzCiAqLwpzdGF0aWMgdm9pZCBXQ1VTRVJfRmlsbE1lbURDKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBpbnQgdXBkX3RwLCBpbnQgdXBkX2JtKQp7CiAgICB1bnNpZ25lZAkJaSwgaiwgazsKICAgIENIQVJfSU5GTyoJCWNlbGw7CiAgICBIRk9OVAkJaE9sZEZvbnQ7CiAgICBXT1JECQlhdHRyOwogICAgV0NIQVIqCQlsaW5lOwogICAgUkVDVCAgICAgICAgICAgICAgICByOwogICAgSEJSVVNIICAgICAgICAgICAgICBoYnI7CgogICAgLyogbm8gZm9udCBoYXMgYmVlbiBzZXQgdXAgeWV0LCBkb24ndCB3b3JyeSBhYm91dCBmaWxsaW5nIHRoZSBiaXRtYXAsCiAgICAgKiB3ZSdsbCBkbyBpdCBvbmNlIGEgZm9udCBpcyBjaG9zZW4KICAgICAqLwogICAgaWYgKCFQUklWQVRFKGRhdGEpLT5oRm9udCkgcmV0dXJuOwoKICAgIC8qIEZJWE1FOiBjb3VsZCBzZXQgdXAgYSBtZWNoYW5pc20gdG8gcmV1c2UgdGhlIGxpbmUgYmV0d2VlbiBkaWZmZXJlbnQKICAgICAqIGNhbGxzIHRvIHRoaXMgZnVuY3Rpb24KICAgICAqLwogICAgaWYgKCEobGluZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBkYXRhLT5jdXJjZmcuc2Jfd2lkdGggKiBzaXplb2YoV0NIQVIpKSkpCiAgICAgICAgV0lORUNPTl9GYXRhbCgiT09NXG4iKTsKCiAgICBoT2xkRm9udCA9IFNlbGVjdE9iamVjdChQUklWQVRFKGRhdGEpLT5oTWVtREMsIFBSSVZBVEUoZGF0YSktPmhGb250KTsKICAgIGZvciAoaiA9IHVwZF90cDsgaiA8PSB1cGRfYm07IGorKykKICAgIHsKCWNlbGwgPSAmZGF0YS0+Y2VsbHNbaiAqIGRhdGEtPmN1cmNmZy5zYl93aWR0aF07Cglmb3IgKGkgPSAwOyBpIDwgZGF0YS0+Y3VyY2ZnLnNiX3dpZHRoOyBpKyspCgl7CgkgICAgYXR0ciA9IGNlbGxbaV0uQXR0cmlidXRlczsKCSAgICBTZXRCa0NvbG9yKFBSSVZBVEUoZGF0YSktPmhNZW1EQywgV0NVU0VSX0NvbG9yTWFwWyhhdHRyPj40KSYweDBGXSk7CgkgICAgU2V0VGV4dENvbG9yKFBSSVZBVEUoZGF0YSktPmhNZW1EQywgV0NVU0VSX0NvbG9yTWFwW2F0dHImMHgwRl0pOwoJICAgIGZvciAoayA9IGk7IGsgPCBkYXRhLT5jdXJjZmcuc2Jfd2lkdGggJiYgY2VsbFtrXS5BdHRyaWJ1dGVzID09IGF0dHI7IGsrKykKCSAgICB7CgkJbGluZVtrIC0gaV0gPSBjZWxsW2tdLkNoYXIuVW5pY29kZUNoYXI7CgkgICAgfQoJICAgIFRleHRPdXQoUFJJVkFURShkYXRhKS0+aE1lbURDLCBpICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGgsIGogKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQsCgkJICAgIGxpbmUsIGsgLSBpKTsKICAgICAgICAgICAgaWYgKFBSSVZBVEUoZGF0YSktPmV4dF9sZWFkaW5nICYmIAogICAgICAgICAgICAgICAgKGhiciA9IENyZWF0ZVNvbGlkQnJ1c2goV0NVU0VSX0NvbG9yTWFwWyhhdHRyPj40KSYweDBGXSkpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByLmxlZnQgICA9IGkgKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgICAgICAgICAgICAgIHIudG9wICAgID0gKGogKyAxKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCAtIFBSSVZBVEUoZGF0YSktPmV4dF9sZWFkaW5nOwogICAgICAgICAgICAgICAgci5yaWdodCAgPSBrICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGg7CiAgICAgICAgICAgICAgICByLmJvdHRvbSA9IChqICsgMSkgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQ7CiAgICAgICAgICAgICAgICBGaWxsUmVjdChQUklWQVRFKGRhdGEpLT5oTWVtREMsICZyLCBoYnIpOwogICAgICAgICAgICAgICAgRGVsZXRlT2JqZWN0KGhicik7CiAgICAgICAgICAgIH0KCSAgICBpID0gayAtIDE7Cgl9CiAgICB9CiAgICBTZWxlY3RPYmplY3QoUFJJVkFURShkYXRhKS0+aE1lbURDLCBoT2xkRm9udCk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBsaW5lKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX05ld0JpdG1hcAogKgogKiBFaXRoZXIgdGhlIGZvbnQgZ2VvbWV0cnkgb3IgdGhlIHNiIGdlb21ldHJ5IGhhcyBjaGFuZ2VkLiB3ZSBuZWVkCiAqIHRvIHJlY3JlYXRlIHRoZSBiaXRtYXAgZ2VvbWV0cnkuCiAqLwpzdGF0aWMgdm9pZCBXQ1VTRVJfTmV3Qml0bWFwKHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBIREMgICAgICAgICBoREM7CiAgICBIQklUTUFQCWhuZXcsIGhvbGQ7CgogICAgaWYgKCFkYXRhLT5jdXJjZmcuc2Jfd2lkdGggfHwgIWRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgfHwKICAgICAgICAhUFJJVkFURShkYXRhKS0+aEZvbnQgfHwgIShoREMgPSBHZXREQyhkYXRhLT5oV25kKSkpCiAgICAgICAgcmV0dXJuOwogICAgaG5ldyA9IENyZWF0ZUNvbXBhdGlibGVCaXRtYXAoaERDLAoJCQkJICBkYXRhLT5jdXJjZmcuc2Jfd2lkdGggICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGgsCgkJCQkgIGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQpOwogICAgUmVsZWFzZURDKGRhdGEtPmhXbmQsIGhEQyk7CiAgICBob2xkID0gU2VsZWN0T2JqZWN0KFBSSVZBVEUoZGF0YSktPmhNZW1EQywgaG5ldyk7CgogICAgaWYgKFBSSVZBVEUoZGF0YSktPmhCaXRtYXApCiAgICB7CglpZiAoaG9sZCA9PSBQUklWQVRFKGRhdGEpLT5oQml0bWFwKQoJICAgIERlbGV0ZU9iamVjdChQUklWQVRFKGRhdGEpLT5oQml0bWFwKTsKCWVsc2UKCSAgICBXSU5FX0ZJWE1FKCJsZWFrXG4iKTsKICAgIH0KICAgIFBSSVZBVEUoZGF0YSktPmhCaXRtYXAgPSBobmV3OwogICAgV0NVU0VSX0ZpbGxNZW1EQyhkYXRhLCAwLCBkYXRhLT5jdXJjZmcuc2JfaGVpZ2h0IC0gMSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9SZXNpemVTY3JlZW5CdWZmZXIKICoKICoKICovCnN0YXRpYyB2b2lkIFdDVVNFUl9SZXNpemVTY3JlZW5CdWZmZXIoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIFdDVVNFUl9OZXdCaXRtYXAoZGF0YSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9Qb3NDdXJzb3IKICoKICogU2V0IGEgbmV3IHBvc2l0aW9uIGZvciB0aGUgY3Vyc29yCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfUG9zQ3Vyc29yKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBpZiAoZGF0YS0+aFduZCAhPSBHZXRGb2N1cygpIHx8ICFkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUpIHJldHVybjsKCiAgICBTZXRDYXJldFBvcygoZGF0YS0+Y3Vyc29yLlggLSBkYXRhLT5jdXJjZmcud2luX3Bvcy5YKSAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoLAoJCShkYXRhLT5jdXJzb3IuWSAtIGRhdGEtPmN1cmNmZy53aW5fcG9zLlkpICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0KTsKICAgIFNob3dDYXJldChkYXRhLT5oV25kKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1NoYXBlQ3Vyc29yCiAqCiAqIFNldHMgYSBuZXcgc2hhcGUgZm9yIHRoZSBjdXJzb3IKICovCnN0YXRpYyB2b2lkCVdDVVNFUl9TaGFwZUN1cnNvcihzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgaW50IHNpemUsIGludCB2aXMsIEJPT0wgZm9yY2UpCnsKICAgIGlmIChmb3JjZSB8fCBzaXplICE9IGRhdGEtPmN1cmNmZy5jdXJzb3Jfc2l6ZSkKICAgIHsKCWlmIChkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUgJiYgZGF0YS0+aFduZCA9PSBHZXRGb2N1cygpKSBEZXN0cm95Q2FyZXQoKTsKCWlmIChQUklWQVRFKGRhdGEpLT5jdXJzb3JfYml0bWFwKSBEZWxldGVPYmplY3QoUFJJVkFURShkYXRhKS0+Y3Vyc29yX2JpdG1hcCk7CglQUklWQVRFKGRhdGEpLT5jdXJzb3JfYml0bWFwID0gTlVMTDsKCWlmIChzaXplICE9IDEwMCkKCXsKCSAgICBpbnQJCXcxNmI7IC8qIG51bWJlciBvZiBieXRlcyBwZXIgcm93LCBhbGlnbmVkIG9uIHdvcmQgc2l6ZSAqLwoJICAgIEJZVEUqCXB0cjsKCSAgICBpbnQJCWksIGosIG5ibDsKCgkgICAgdzE2YiA9ICgoZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGggKyAxNSkgJiB+MTUpIC8gODsKCSAgICBwdHIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgdzE2YiAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCk7CgkgICAgaWYgKCFwdHIpIFdJTkVDT05fRmF0YWwoIk9PTSIpOwoJICAgIG5ibCA9IG1heCgoZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0ICogc2l6ZSkgLyAxMDAsIDEpOwoJICAgIGZvciAoaiA9IGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCAtIG5ibDsgaiA8IGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsgaisrKQoJICAgIHsKCQlmb3IgKGkgPSAwOyBpIDwgZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGg7IGkrKykKCQl7CgkJICAgIHB0clt3MTZiICogaiArIChpIC8gOCldIHw9IDB4ODAgPj4gKGkgJiA3KTsKCQl9CgkgICAgfQoJICAgIFBSSVZBVEUoZGF0YSktPmN1cnNvcl9iaXRtYXAgPSBDcmVhdGVCaXRtYXAoZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0LCAxLCAxLCBwdHIpOwoJICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHB0cik7Cgl9CglkYXRhLT5jdXJjZmcuY3Vyc29yX3NpemUgPSBzaXplOwoJZGF0YS0+Y3VyY2ZnLmN1cnNvcl92aXNpYmxlID0gLTE7CiAgICB9CgogICAgdmlzID0gKHZpcykgPyBUUlVFIDogRkFMU0U7CiAgICBpZiAoZm9yY2UgfHwgdmlzICE9IGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKICAgIHsKCWRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSA9IHZpczsKCWlmIChkYXRhLT5oV25kID09IEdldEZvY3VzKCkpCgl7CgkgICAgaWYgKHZpcykKCSAgICB7CgkJQ3JlYXRlQ2FyZXQoZGF0YS0+aFduZCwgUFJJVkFURShkYXRhKS0+Y3Vyc29yX2JpdG1hcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoLCBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQpOwoJCVdDVVNFUl9Qb3NDdXJzb3IoZGF0YSk7CgkgICAgfQoJICAgIGVsc2UKCSAgICB7CgkJRGVzdHJveUNhcmV0KCk7CgkgICAgfQoJfQogICAgfQogICAgV0lORUNPTl9EdW1wQ29uZmlnKCJjcnNyIiwgJmRhdGEtPmN1cmNmZyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9Db21wdXRlUG9zaXRpb25zCiAqCiAqIFJlY29tcHV0ZXMgYWxsIHRoZSBjb21wb25lbnRzIChtYWlubHkgc2Nyb2xsIGJhcnMpIHBvc2l0aW9ucwogKi8Kc3RhdGljIHZvaWQJV0NVU0VSX0NvbXB1dGVQb3NpdGlvbnMoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIFJFQ1QJCXI7CiAgICBpbnQJCQlkeCwgZHk7CgogICAgLyogY29tcHV0ZSB3aW5kb3cgc2l6ZSBmcm9tIGRlc2lyZWQgY2xpZW50IHNpemUgKi8KICAgIHIubGVmdCA9IHIudG9wID0gMDsKICAgIHIucmlnaHQgPSBkYXRhLT5jdXJjZmcud2luX3dpZHRoICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGg7CiAgICByLmJvdHRvbSA9IGRhdGEtPmN1cmNmZy53aW5faGVpZ2h0ICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0OwoKICAgIGlmIChJc1JlY3RFbXB0eSgmcikpIHJldHVybjsKCiAgICBBZGp1c3RXaW5kb3dSZWN0KCZyLCBHZXRXaW5kb3dMb25nKGRhdGEtPmhXbmQsIEdXTF9TVFlMRSksIEZBTFNFKTsKCiAgICBkeCA9IGR5ID0gMDsKICAgIGlmIChkYXRhLT5jdXJjZmcuc2Jfd2lkdGggPiBkYXRhLT5jdXJjZmcud2luX3dpZHRoKQogICAgewoJZHkgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZSFNDUk9MTCk7CglTZXRTY3JvbGxSYW5nZShkYXRhLT5oV25kLCBTQl9IT1JaLCAwLAogICAgICAgICAgICAgICAgICAgICAgIGRhdGEtPmN1cmNmZy5zYl93aWR0aCAtIGRhdGEtPmN1cmNmZy53aW5fd2lkdGgsIEZBTFNFKTsKCVNldFNjcm9sbFBvcyhkYXRhLT5oV25kLCBTQl9IT1JaLCAwLCBGQUxTRSk7IC8qIEZJWE1FICovCglTaG93U2Nyb2xsQmFyKGRhdGEtPmhXbmQsIFNCX0hPUlosIFRSVUUpOwogICAgfQogICAgZWxzZQogICAgewoJU2hvd1Njcm9sbEJhcihkYXRhLT5oV25kLCBTQl9IT1JaLCBGQUxTRSk7CiAgICB9CgogICAgaWYgKGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgPiBkYXRhLT5jdXJjZmcud2luX2hlaWdodCkKICAgIHsKCWR4ID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFZTQ1JPTEwpOwoJU2V0U2Nyb2xsUmFuZ2UoZGF0YS0+aFduZCwgU0JfVkVSVCwgMCwKICAgICAgICAgICAgICAgICAgICAgICBkYXRhLT5jdXJjZmcuc2JfaGVpZ2h0IC0gZGF0YS0+Y3VyY2ZnLndpbl9oZWlnaHQsIEZBTFNFKTsKCVNldFNjcm9sbFBvcyhkYXRhLT5oV25kLCBTQl9WRVJULCAwLCBGQUxTRSk7IC8qIEZJWE1FICovCglTaG93U2Nyb2xsQmFyKGRhdGEtPmhXbmQsIFNCX1ZFUlQsIFRSVUUpOwogICAgfQogICAgZWxzZQogICAgewoJU2hvd1Njcm9sbEJhcihkYXRhLT5oV25kLCBTQl9WRVJULCBGQUxTRSk7CiAgICB9CgogICAgU2V0V2luZG93UG9zKGRhdGEtPmhXbmQsIDAsIDAsIDAsIHIucmlnaHQgLSByLmxlZnQgKyBkeCwgci5ib3R0b20gLSByLnRvcCArIGR5LAoJCSBTV1BfTk9NT1ZFfFNXUF9OT1pPUkRFUik7CiAgICBXQ1VTRVJfU2hhcGVDdXJzb3IoZGF0YSwgZGF0YS0+Y3VyY2ZnLmN1cnNvcl9zaXplLCBkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUsIFRSVUUpOwogICAgV0NVU0VSX1Bvc0N1cnNvcihkYXRhKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1NldFRpdGxlCiAqCiAqIFNldHMgdGhlIHRpdGxlIHRvIHRoZSB3aW5lIGNvbnNvbGUKICovCnN0YXRpYyB2b2lkCVdDVVNFUl9TZXRUaXRsZShjb25zdCBzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgV0NIQVIJYnVmZmVyWzI1Nl07CgogICAgaWYgKFdJTkVDT05fR2V0Q29uc29sZVRpdGxlKGRhdGEtPmhDb25JbiwgYnVmZmVyLCBzaXplb2YoYnVmZmVyKSkpCglTZXRXaW5kb3dUZXh0KGRhdGEtPmhXbmQsIGJ1ZmZlcik7Cn0KCnZvaWQgV0NVU0VSX0R1bXBMb2dGb250KGNvbnN0IGNoYXIqIHBmeCwgY29uc3QgTE9HRk9OVCogbGYsIERXT1JEIGZ0KQp7CiAgICBXSU5FX1RSQUNFXyh3Y19mb250KSgiJXMgJXMlcyVzJXNcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdGxmLmxmSGVpZ2h0PSVkIGxmLmxmV2lkdGg9JWQgbGYubGZFc2NhcGVtZW50PSVkIGxmLmxmT3JpZW50YXRpb249JWRcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdGxmLmxmV2VpZ2h0PSVkIGxmLmxmSXRhbGljPSV1IGxmLmxmVW5kZXJsaW5lPSV1IGxmLmxmU3RyaWtlT3V0PSV1XG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAiXHRsZi5sZkNoYXJTZXQ9JXUgbGYubGZPdXRQcmVjaXNpb249JXUgbGYubGZDbGlwUHJlY2lzaW9uPSV1IGxmLmxmUXVhbGl0eT0ldVxuIgogICAgICAgICAgICAgICAgICAgICAgICAgIlx0bGYtPmxmUGl0Y2hBbmRGYW1pbHk9JXUgbGYubGZGYWNlTmFtZT0lc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgIHBmeCwKICAgICAgICAgICAgICAgICAgICAgICAgIChmdCAmIFJBU1RFUl9GT05UVFlQRSkgPyAicmFzdGVyIiA6ICIiLAogICAgICAgICAgICAgICAgICAgICAgICAgKGZ0ICYgVFJVRVRZUEVfRk9OVFRZUEUpID8gInRydWV0eXBlIiA6ICIiLAogICAgICAgICAgICAgICAgICAgICAgICAgKChmdCAmIChSQVNURVJfRk9OVFRZUEV8VFJVRVRZUEVfRk9OVFRZUEUpKSA9PSAwKSA/ICJ2ZWN0b3IiIDogIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAoZnQgJiBERVZJQ0VfRk9OVFRZUEUpID8gInxkZXZpY2UiIDogIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICBsZi0+bGZIZWlnaHQsIGxmLT5sZldpZHRoLCBsZi0+bGZFc2NhcGVtZW50LCBsZi0+bGZPcmllbnRhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgIGxmLT5sZldlaWdodCwgbGYtPmxmSXRhbGljLCBsZi0+bGZVbmRlcmxpbmUsIGxmLT5sZlN0cmlrZU91dCwgbGYtPmxmQ2hhclNldCwKICAgICAgICAgICAgICAgICAgICAgICAgIGxmLT5sZk91dFByZWNpc2lvbiwgbGYtPmxmQ2xpcFByZWNpc2lvbiwgbGYtPmxmUXVhbGl0eSwgbGYtPmxmUGl0Y2hBbmRGYW1pbHksCiAgICAgICAgICAgICAgICAgICAgICAgICB3aW5lX2RiZ3N0cl93KGxmLT5sZkZhY2VOYW1lKSk7Cn0KCnZvaWQgV0NVU0VSX0R1bXBUZXh0TWV0cmljKGNvbnN0IFRFWFRNRVRSSUMqIHRtLCBEV09SRCBmdCkKewogICAgV0lORV9UUkFDRV8od2NfZm9udCkoIiVzJXMlcyVzXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAiXHR0bUhlaWdodD0lZCB0bUFzY2VudD0lZCB0bURlc2NlbnQ9JWQgdG1JbnRlcm5hbExlYWRpbmc9JWQgdG1FeHRlcm5hbExlYWRpbmc9JWRcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdHRtQXZlQ2hhcldpZHRoPSVkIHRtTWF4Q2hhcldpZHRoPSVkIHRtV2VpZ2h0PSVkIHRtT3Zlcmhhbmc9JWRcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdHRtRGlnaXRpemVkQXNwZWN0WD0lZCB0bURpZ2l0aXplZEFzcGVjdFk9JWRcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdHRtRmlyc3RDaGFyPSVkIHRtTGFzdENoYXI9JWQgdG1EZWZhdWx0Q2hhcj0lZCB0bUJyZWFrQ2hhcj0lZFxuIgogICAgICAgICAgICAgICAgICAgICAgICAgIlx0dG1JdGFsaWM9JXUgdG1VbmRlcmxpbmVkPSV1IHRtU3RydWNrT3V0PSV1IHRtUGl0Y2hBbmRGYW1pbHk9JXUgdG1DaGFyU2V0PSV1XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgKGZ0ICYgUkFTVEVSX0ZPTlRUWVBFKSA/ICJyYXN0ZXIiIDogIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAoZnQgJiBUUlVFVFlQRV9GT05UVFlQRSkgPyAidHJ1ZXR5cGUiIDogIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAoKGZ0ICYgKFJBU1RFUl9GT05UVFlQRXxUUlVFVFlQRV9GT05UVFlQRSkpID09IDApID8gInZlY3RvciIgOiAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgIChmdCAmIERFVklDRV9GT05UVFlQRSkgPyAifGRldmljZSIgOiAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgIHRtLT50bUhlaWdodCwgdG0tPnRtQXNjZW50LCB0bS0+dG1EZXNjZW50LCB0bS0+dG1JbnRlcm5hbExlYWRpbmcsIHRtLT50bUV4dGVybmFsTGVhZGluZywgdG0tPnRtQXZlQ2hhcldpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgdG0tPnRtTWF4Q2hhcldpZHRoLCB0bS0+dG1XZWlnaHQsIHRtLT50bU92ZXJoYW5nLCB0bS0+dG1EaWdpdGl6ZWRBc3BlY3RYLCB0bS0+dG1EaWdpdGl6ZWRBc3BlY3RZLAogICAgICAgICAgICAgICAgICAgICAgICAgdG0tPnRtRmlyc3RDaGFyLCB0bS0+dG1MYXN0Q2hhciwgdG0tPnRtRGVmYXVsdENoYXIsIHRtLT50bUJyZWFrQ2hhciwgdG0tPnRtSXRhbGljLCB0bS0+dG1VbmRlcmxpbmVkLCB0bS0+dG1TdHJ1Y2tPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICB0bS0+dG1QaXRjaEFuZEZhbWlseSwgdG0tPnRtQ2hhclNldCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9BcmVGb250c0VxdWFsCiAqCiAqCiAqLwpCT09MIFdDVVNFUl9BcmVGb250c0VxdWFsKGNvbnN0IHN0cnVjdCBjb25maWdfZGF0YSogY29uZmlnLCBjb25zdCBMT0dGT05UKiBsZikKewogICAgcmV0dXJuIGxmLT5sZkhlaWdodCA9PSBjb25maWctPmNlbGxfaGVpZ2h0ICYmCiAgICAgICAgbGYtPmxmV2VpZ2h0ID09IGNvbmZpZy0+Zm9udF93ZWlnaHQgJiYKICAgICAgICAhbGYtPmxmSXRhbGljICYmICFsZi0+bGZVbmRlcmxpbmUgJiYgIWxmLT5sZlN0cmlrZU91dCAmJgogICAgICAgICFsc3RyY21wKGxmLT5sZkZhY2VOYW1lLCBjb25maWctPmZhY2VfbmFtZSk7Cn0KCnN0cnVjdCBmb250X2Nob29zZXIKewogICAgc3RydWN0IGlubmVyX2RhdGEqCWRhdGE7CiAgICBpbnQJCQlkb25lOwp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1ZhbGlkYXRlRm9udE1ldHJpYwogKgogKiBSZXR1cm5zIHRydWUgaWYgdGhlIGZvbnQgZGVzY3JpYmVkIGluIHRtIGlzIHVzYWJsZSBhcyBhIGZvbnQgZm9yIHRoZSByZW5kZXJlcgogKi8KQk9PTAlXQ1VTRVJfVmFsaWRhdGVGb250TWV0cmljKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBjb25zdCBURVhUTUVUUklDKiB0bSwgRFdPUkQgZm9udFR5cGUpCnsKICAgIEJPT0wgICAgICAgIHJldCA9IFRSVUU7CgogICAgaWYgKGZvbnRUeXBlICYgUkFTVEVSX0ZPTlRUWVBFKQogICAgICAgIHJldCA9ICh0bS0+dG1NYXhDaGFyV2lkdGggKiBkYXRhLT5jdXJjZmcud2luX3dpZHRoIDwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNDUkVFTikgJiYKICAgICAgICAgICAgICAgdG0tPnRtSGVpZ2h0ICogZGF0YS0+Y3VyY2ZnLndpbl9oZWlnaHQgPCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0NSRUVOKSk7CiAgICByZXR1cm4gcmV0ICYmICF0bS0+dG1JdGFsaWMgJiYgIXRtLT50bVVuZGVybGluZWQgJiYgIXRtLT50bVN0cnVja091dCAmJgogICAgICAgICh0bS0+dG1DaGFyU2V0ID09IERFRkFVTFRfQ0hBUlNFVCB8fCB0bS0+dG1DaGFyU2V0ID09IGdfdWlEZWZhdWx0Q2hhcnNldCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9WYWxpZGF0ZUZvbnQKICoKICogUmV0dXJucyB0cnVlIGlmIHRoZSBmb250IGZhbWlseSBkZXNjcmliZWQgaW4gbGYgaXMgdXNhYmxlIGFzIGEgZm9udCBmb3IgdGhlIHJlbmRlcmVyCiAqLwpCT09MCVdDVVNFUl9WYWxpZGF0ZUZvbnQoY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIGNvbnN0IExPR0ZPTlQqIGxmKQp7CiAgICByZXR1cm4gKGxmLT5sZlBpdGNoQW5kRmFtaWx5ICYgMykgPT0gRklYRURfUElUQ0ggJiYKICAgICAgICAvKiAobGYtPmxmUGl0Y2hBbmRGYW1pbHkgJiAweEYwKSA9PSBGRl9NT0RFUk4gJiYgKi8KICAgICAgICAobGYtPmxmQ2hhclNldCA9PSBERUZBVUxUX0NIQVJTRVQgfHwgbGYtPmxmQ2hhclNldCA9PSBnX3VpRGVmYXVsdENoYXJzZXQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlnZXRfZmlyc3RfZm9udF9lbnVtXzIKICoJCWdldF9maXJzdF9mb250X2VudW0KICoKICogSGVscGVyIGZ1bmN0aW9ucyB0byBnZXQgYSBkZWNlbnQgZm9udCBmb3IgdGhlIHJlbmRlcmVyCiAqLwpzdGF0aWMgaW50IENBTExCQUNLIGdldF9maXJzdF9mb250X2VudW1fMihjb25zdCBMT0dGT05UKiBsZiwgY29uc3QgVEVYVE1FVFJJQyogdG0sCgkJCQkJICBEV09SRCBGb250VHlwZSwgTFBBUkFNIGxQYXJhbSkKewogICAgc3RydWN0IGZvbnRfY2hvb3NlcioJZmMgPSAoc3RydWN0IGZvbnRfY2hvb3NlciopbFBhcmFtOwoKICAgIFdDVVNFUl9EdW1wVGV4dE1ldHJpYyh0bSwgRm9udFR5cGUpOwogICAgaWYgKFdDVVNFUl9WYWxpZGF0ZUZvbnRNZXRyaWMoZmMtPmRhdGEsIHRtLCBGb250VHlwZSkpCiAgICB7CiAgICAgICAgTE9HRk9OVCBtbGYgPSAqbGY7CgogICAgICAgIC8qIFVzZSB0aGUgZGVmYXVsdCBzaXplcyBmb3IgdGhlIGZvbnQgKHRoaXMgaXMgbmVlZGVkLCBlc3BlY2lhbGx5IGZvcgogICAgICAgICAqIFRydWVUeXBlIGZvbnRzLCBzbyB0aGF0IHdlIGdldCBhIGRlY2VudCBzaXplLCBub3QgdGhlIG1heCBzaXplKQogICAgICAgICAqLwogICAgICAgIG1sZi5sZldpZHRoICA9IGZjLT5kYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgICAgICBtbGYubGZIZWlnaHQgPSBmYy0+ZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0OwogICAgICAgIGlmIChXQ1VTRVJfU2V0Rm9udChmYy0+ZGF0YSwgJm1sZikpCiAgICAgICAgewogICAgICAgICAgICBzdHJ1Y3QgICAgICBjb25maWdfZGF0YSAgICAgZGVmY2ZnOwoKICAgICAgICAgICAgV0NVU0VSX0R1bXBMb2dGb250KCJJbml0Q2hvb3Npbmc6ICIsICZtbGYsIEZvbnRUeXBlKTsKICAgICAgICAgICAgZmMtPmRvbmUgPSAxOwogICAgICAgICAgICAvKiBzaW5jZSB3ZSd2ZSBtb2RpZmllZCB0aGUgY3VycmVudCBjb25maWcgd2l0aCBuZXcgZm9udCBpbmZvcm1hdGlvbiwKICAgICAgICAgICAgICogc2V0IHRoaXMgaW5mb3JtYXRpb24gYXMgdGhlIG5ldyBkZWZhdWx0LgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgV0lORUNPTl9SZWdMb2FkKE5VTEwsICZkZWZjZmcpOwogICAgICAgICAgICBkZWZjZmcuY2VsbF93aWR0aCA9IGZjLT5kYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgICAgICAgICAgZGVmY2ZnLmNlbGxfaGVpZ2h0ID0gZmMtPmRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKICAgICAgICAgICAgbHN0cmNweVcoZGVmY2ZnLmZhY2VfbmFtZSwgZmMtPmRhdGEtPmN1cmNmZy5mYWNlX25hbWUpOwogICAgICAgICAgICAvKiBGb3JjZSBhbHNvIGl0cyB3cml0aW5nIGJhY2sgdG8gdGhlIHJlZ2lzdHJ5IHNvIHRoYXQgd2UgY2FuIGdldCBpdAogICAgICAgICAgICAgKiB0aGUgbmV4dCB0aW1lLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgV0lORUNPTl9SZWdTYXZlKCZkZWZjZmcpOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gMTsKfQoKc3RhdGljIGludCBDQUxMQkFDSyBnZXRfZmlyc3RfZm9udF9lbnVtKGNvbnN0IExPR0ZPTlQqIGxmLCBjb25zdCBURVhUTUVUUklDKiB0bSwKCQkJCQlEV09SRCBGb250VHlwZSwgTFBBUkFNIGxQYXJhbSkKewogICAgc3RydWN0IGZvbnRfY2hvb3NlcioJZmMgPSAoc3RydWN0IGZvbnRfY2hvb3NlciopbFBhcmFtOwoKICAgIFdDVVNFUl9EdW1wTG9nRm9udCgiSW5pdEZhbWlseTogIiwgbGYsIEZvbnRUeXBlKTsKICAgIGlmIChXQ1VTRVJfVmFsaWRhdGVGb250KGZjLT5kYXRhLCBsZikpCiAgICB7CglFbnVtRm9udEZhbWlsaWVzKFBSSVZBVEUoZmMtPmRhdGEpLT5oTWVtREMsIGxmLT5sZkZhY2VOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgZ2V0X2ZpcnN0X2ZvbnRfZW51bV8yLCBsUGFyYW0pOwoJcmV0dXJuICFmYy0+ZG9uZTsgLyogd2UganVzdCBuZWVkIHRoZSBmaXJzdCBtYXRjaGluZyBvbmUuLi4gKi8KICAgIH0KICAgIHJldHVybiAxOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfQ29weUZvbnQKICoKICogZ2V0IHRoZSByZWxldmFudCBpbmZvcm1hdGlvbiBmcm9tIHRoZSBmb250IGRlc2NyaWJlZCBpbiBsZiBhbmQgc3RvcmUgdGhlbQogKiBpbiBjb25maWcKICovCkhGT05UIFdDVVNFUl9Db3B5Rm9udChzdHJ1Y3QgY29uZmlnX2RhdGEqIGNvbmZpZywgSFdORCBoV25kLCBjb25zdCBMT0dGT05UKiBsZiwgTE9ORyogZWwpCnsKICAgIFRFWFRNRVRSSUMgIHRtOwogICAgSERDICAgICAgICAgaERDOwogICAgSEZPTlQgICAgICAgaEZvbnQsIGhPbGRGb250OwogICAgaW50ICAgICAgICAgdywgaSwgYnVmWzI1Nl07CgogICAgaWYgKCEoaERDID0gR2V0REMoaFduZCkpKSByZXR1cm4gTlVMTDsKICAgIGlmICghKGhGb250ID0gQ3JlYXRlRm9udEluZGlyZWN0KGxmKSkpIGdvdG8gZXJyMTsKCiAgICBoT2xkRm9udCA9IFNlbGVjdE9iamVjdChoREMsIGhGb250KTsKICAgIEdldFRleHRNZXRyaWNzKGhEQywgJnRtKTsKCiAgICAvKiBGSVhNRToKICAgICAqIHRoZSBjdXJyZW50IGZyZWV0eXBlIGVuZ2luZSAoYXQgbGVhc3QgMi4wLnggd2l0aCB4IDw9IDgpIGFuZCBpdHMgaW1wbGVtZW50YXRpb24KICAgICAqIGluIFdpbmUgZG9uJ3QgcmV0dXJuIGFkZXF1YXRlIHZhbHVlcyBmb3IgZml4ZWQgZm9udHMKICAgICAqIEluIFdpbmRvd3MsIHRob3NlIGZvbnRzIGFyZSBleHBlY3RlZCB0byByZXR1cm4gdGhlIHNhbWUgdmFsdWUgZm9yCiAgICAgKiAgLSB0aGUgYXZlcmFnZSB3aWR0aAogICAgICogIC0gdGhlIGxhcmdlc3Qgd2lkdGgKICAgICAqICAtIHRoZSB3aWR0aCBvZiBhbGwgY2hhcmFjdGVycyBpbiB0aGUgZm9udAogICAgICogVGhpcyBpc24ndCB0cnVlIGluIFdpbmUuIEFzIGEgdGVtcG9yYXJ5IHdvcmthcm91bmQsIHdlIGdldCBhcyB0aGUgd2lkdGggb2YgdGhlCiAgICAgKiBjZWxsLCB0aGUgd2lkdGggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBpbiB0aGUgZm9udCwgYWZ0ZXIgY2hlY2tpbmcgdGhhdCBhbGwKICAgICAqIGNoYXJhY3RlcnMgaW4gdGhlIGZvbnQgaGF2ZSB0aGUgc2FtZSB3aWR0aCAoSSBoZWFyIHBhcmFub+9hIGNvbWluZykKICAgICAqIHdoZW4gdGhpcyBnZXRzIGZpeGVkLCB0aGUgY29kZSBzaG91bGQgYmUgdXNpbmcgdG0udG1BdmVDaGFyV2lkdGgKICAgICAqIG9yIHRtLnRtTWF4Q2hhcldpZHRoIGFzIHRoZSBjZWxsIHdpZHRoLgogICAgICovCiAgICBHZXRDaGFyV2lkdGgzMihoREMsIHRtLnRtRmlyc3RDaGFyLCB0bS50bUZpcnN0Q2hhciwgJncpOwogICAgZm9yIChpID0gdG0udG1GaXJzdENoYXIgKyAxOyBpIDw9IHRtLnRtTGFzdENoYXI7IGkgKz0gc2l6ZW9mKGJ1ZikgLyBzaXplb2YoYnVmWzBdKSkKICAgIHsKICAgICAgICBpbnQgaiwgazsKCiAgICAgICAgayA9IG1pbih0bS50bUxhc3RDaGFyIC0gaSwgc2l6ZW9mKGJ1ZikgLyBzaXplb2YoYnVmWzBdKSAtIDEpOwogICAgICAgIEdldENoYXJXaWR0aDMyKGhEQywgaSwgaSArIGssIGJ1Zik7CiAgICAgICAgZm9yIChqID0gMDsgaiA8PSBrOyBqKyspCiAgICAgICAgewogICAgICAgICAgICBpZiAoYnVmW2pdICE9IHcpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdJTkVfV0FSTigiTm9uIHVuaWZvcm0gY2VsbCB3aWR0aDogWyVkXT0lZCBbJWRdPSVkXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlRoaXMgbWF5IGJlIGNhdXNlZCBieSBvbGQgZnJlZXR5cGUgbGlicmFyaWVzLCA+PSAyLjAuOCBpcyByZWNvbW1lbmRlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBpICsgaiwgYnVmW2pdLCB0bS50bUZpcnN0Q2hhciwgdyk7CiAgICAgICAgICAgICAgICBnb3RvIGVycjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIFNlbGVjdE9iamVjdChoREMsIGhPbGRGb250KTsKICAgIFJlbGVhc2VEQyhoV25kLCBoREMpOwoKICAgIGNvbmZpZy0+Y2VsbF93aWR0aCAgPSB3OwogICAgY29uZmlnLT5jZWxsX2hlaWdodCA9IHRtLnRtSGVpZ2h0ICsgdG0udG1FeHRlcm5hbExlYWRpbmc7CiAgICBjb25maWctPmZvbnRfd2VpZ2h0ID0gdG0udG1XZWlnaHQ7CiAgICBsc3RyY3B5KGNvbmZpZy0+ZmFjZV9uYW1lLCBsZi0+bGZGYWNlTmFtZSk7CiAgICBpZiAoZWwpICplbCA9IHRtLnRtRXh0ZXJuYWxMZWFkaW5nOwoKICAgIHJldHVybiBoRm9udDsKIGVycjoKICAgIGlmIChoREMgJiYgaE9sZEZvbnQpIFNlbGVjdE9iamVjdChoREMsIGhPbGRGb250KTsKICAgIGlmIChoRm9udCkgRGVsZXRlT2JqZWN0KGhGb250KTsKIGVycjE6CiAgICBpZiAoaERDKSBSZWxlYXNlREMoaFduZCwgaERDKTsKCiAgICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0ZpbGxMb2dGb250CiAqCiAqCiAqLwp2b2lkICAgIFdDVVNFUl9GaWxsTG9nRm9udChMT0dGT05UKiBsZiwgY29uc3QgV0NIQVIqIG5hbWUsIFVJTlQgaGVpZ2h0LCBVSU5UIHdlaWdodCkKewogICAgbGYtPmxmSGVpZ2h0ICAgICAgICA9IGhlaWdodDsKICAgIGxmLT5sZldpZHRoICAgICAgICAgPSAwOwogICAgbGYtPmxmRXNjYXBlbWVudCAgICA9IDA7CiAgICBsZi0+bGZPcmllbnRhdGlvbiAgID0gMDsKICAgIGxmLT5sZldlaWdodCAgICAgICAgPSB3ZWlnaHQ7CiAgICBsZi0+bGZJdGFsaWMgICAgICAgID0gRkFMU0U7CiAgICBsZi0+bGZVbmRlcmxpbmUgICAgID0gRkFMU0U7CiAgICBsZi0+bGZTdHJpa2VPdXQgICAgID0gRkFMU0U7CiAgICBsZi0+bGZDaGFyU2V0ICAgICAgID0gREVGQVVMVF9DSEFSU0VUOwogICAgbGYtPmxmT3V0UHJlY2lzaW9uICA9IE9VVF9ERUZBVUxUX1BSRUNJUzsKICAgIGxmLT5sZkNsaXBQcmVjaXNpb24gPSBDTElQX0RFRkFVTFRfUFJFQ0lTOwogICAgbGYtPmxmUXVhbGl0eSAgICAgICA9IERFRkFVTFRfUVVBTElUWTsKICAgIGxmLT5sZlBpdGNoQW5kRmFtaWx5ID0gRklYRURfUElUQ0ggfCBGRl9ET05UQ0FSRTsKICAgIGxzdHJjcHkobGYtPmxmRmFjZU5hbWUsIG5hbWUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfU2V0Rm9udAogKgogKiBzZXRzIGxvZ2ZvbnQgYXMgdGhlIG5ldyBmb250IGZvciB0aGUgY29uc29sZQogKi8KQk9PTAlXQ1VTRVJfU2V0Rm9udChzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgY29uc3QgTE9HRk9OVCogbG9nZm9udCkKewogICAgSEZPTlQgICAgICAgaEZvbnQ7CiAgICBMT05HICAgICAgICBlbDsKCiAgICBpZiAoUFJJVkFURShkYXRhKS0+aEZvbnQgIT0gMCAmJiBXQ1VTRVJfQXJlRm9udHNFcXVhbCgmZGF0YS0+Y3VyY2ZnLCBsb2dmb250KSkKICAgICAgICByZXR1cm4gVFJVRTsKCiAgICBoRm9udCA9IFdDVVNFUl9Db3B5Rm9udCgmZGF0YS0+Y3VyY2ZnLCBkYXRhLT5oV25kLCBsb2dmb250LCAmZWwpOwogICAgaWYgKCFoRm9udCkge1dJTkVfRVJSKCJ3cm9uZyBmb250XG4iKTsgcmV0dXJuIEZBTFNFO30KCiAgICBpZiAoUFJJVkFURShkYXRhKS0+aEZvbnQpIERlbGV0ZU9iamVjdChQUklWQVRFKGRhdGEpLT5oRm9udCk7CiAgICBQUklWQVRFKGRhdGEpLT5oRm9udCA9IGhGb250OwogICAgUFJJVkFURShkYXRhKS0+ZXh0X2xlYWRpbmcgPSBlbDsKCiAgICBXQ1VTRVJfQ29tcHV0ZVBvc2l0aW9ucyhkYXRhKTsKICAgIFdDVVNFUl9OZXdCaXRtYXAoZGF0YSk7CiAgICBJbnZhbGlkYXRlUmVjdChkYXRhLT5oV25kLCBOVUxMLCBGQUxTRSk7CiAgICBVcGRhdGVXaW5kb3coZGF0YS0+aFduZCk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9TZXRGb250UG10CiAqCiAqIFNldHMgYSBuZXcgZm9udCBmb3IgdGhlIGNvbnNvbGUuCiAqIEluIGZhY3QgYSB3cmFwcGVyIGZvciBXQ1VTRVJfU2V0Rm9udAogKi8Kc3RhdGljIHZvaWQgICAgIFdDVVNFUl9TZXRGb250UG10KHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBjb25zdCBXQ0hBUiogZm9udCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGhlaWdodCwgdW5zaWduZWQgd2VpZ2h0KQp7CiAgICBMT0dGT05UICAgICAgICAgICAgIGxmOwogICAgc3RydWN0IGZvbnRfY2hvb3NlciBmYzsKCiAgICBXSU5FX1RSQUNFXyh3Y19mb250KSgiPT4gJXMgaD0ldSB3PSV1XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgd2luZV9kYmdzdHJfd24oZm9udCwgLTEpLCBoZWlnaHQsIHdlaWdodCk7CgogICAgaWYgKGZvbnRbMF0gIT0gJ1wwJyAmJiBoZWlnaHQgIT0gMCAmJiB3ZWlnaHQgIT0gMCkKICAgIHsKICAgICAgICBXQ1VTRVJfRmlsbExvZ0ZvbnQoJmxmLCBmb250LCBoZWlnaHQsIHdlaWdodCk7CiAgICAgICAgaWYgKFdDVVNFUl9TZXRGb250KGRhdGEsICZsZikpCiAgICAgICAgewogICAgICAgICAgICBXQ1VTRVJfRHVtcExvZ0ZvbnQoIkluaXRSZXVzZXM6ICIsICZsZiwgMCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgLyogdHJ5IHRvIGZpbmQgYW4gYWNjZXB0YWJsZSBmb250ICovCiAgICBXSU5FX1dBUk4oIkNvdWxkbid0IG1hdGNoIHRoZSBmb250IGZyb20gcmVnaXN0cnkuLi4gdHJ5aW5nIHRvIGZpbmQgb25lXG4iKTsKICAgIGZjLmRhdGEgPSBkYXRhOwogICAgZmMuZG9uZSA9IDA7CiAgICBFbnVtRm9udEZhbWlsaWVzKFBSSVZBVEUoZGF0YSktPmhNZW1EQywgTlVMTCwgZ2V0X2ZpcnN0X2ZvbnRfZW51bSwgKExQQVJBTSkmZmMpOwogICAgaWYgKCFmYy5kb25lKSBXSU5FQ09OX0ZhdGFsKCJDb3VsZG4ndCBmaW5kIGEgZGVjZW50IGZvbnQsIGFib3J0aW5nXG4iKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0dldENlbGwKICoKICogR2V0IGEgY2VsbCBmcm9tIGEgcmVsYXRpdmUgY29vcmRpbmF0ZSBpbiB3aW5kb3cgKHRha2VzIGludG8KICogYWNjb3VudCB0aGUgc2Nyb2xsaW5nKQogKi8Kc3RhdGljIENPT1JECVdDVVNFUl9HZXRDZWxsKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBDT09SRAljOwoKICAgIGMuWCA9IGRhdGEtPmN1cmNmZy53aW5fcG9zLlggKyAoc2hvcnQpTE9XT1JEKGxQYXJhbSkgLyBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgIGMuWSA9IGRhdGEtPmN1cmNmZy53aW5fcG9zLlkgKyAoc2hvcnQpSElXT1JEKGxQYXJhbSkgLyBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQ7CgogICAgcmV0dXJuIGM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9HZXRTZWxlY3Rpb25SZWN0CiAqCiAqIEdldCB0aGUgc2VsZWN0aW9uIHJlY3RhbmdsZQogKi8Kc3RhdGljIHZvaWQJV0NVU0VSX0dldFNlbGVjdGlvblJlY3QoY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIExQUkVDVCByKQp7CiAgICByLT5sZWZ0ICAgPSAobWluKFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MS5YLCBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIuWCkgICAgIC0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWCkgKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgIHItPnRvcCAgICA9IChtaW4oUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlksIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5ZKSAgICAgLSBkYXRhLT5jdXJjZmcud2luX3Bvcy5ZKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKICAgIHItPnJpZ2h0ICA9IChtYXgoUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlgsIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5YKSArIDEgLSBkYXRhLT5jdXJjZmcud2luX3Bvcy5YKSAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoOwogICAgci0+Ym90dG9tID0gKG1heChQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWSwgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlkpICsgMSAtIGRhdGEtPmN1cmNmZy53aW5fcG9zLlkpICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfU2V0U2VsZWN0aW9uCiAqCiAqCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfU2V0U2VsZWN0aW9uKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBIREMgaFJlZkRDKQp7CiAgICBIREMJCWhEQzsKICAgIFJFQ1QJcjsKCiAgICBXQ1VTRVJfR2V0U2VsZWN0aW9uUmVjdChkYXRhLCAmcik7CiAgICBoREMgPSBoUmVmREMgPyBoUmVmREMgOiBHZXREQyhkYXRhLT5oV25kKTsKICAgIGlmIChoREMpCiAgICB7CglpZiAoZGF0YS0+aFduZCA9PSBHZXRGb2N1cygpICYmIGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKCSAgICBIaWRlQ2FyZXQoZGF0YS0+aFduZCk7CglJbnZlcnRSZWN0KGhEQywgJnIpOwoJaWYgKGhEQyAhPSBoUmVmREMpCgkgICAgUmVsZWFzZURDKGRhdGEtPmhXbmQsIGhEQyk7CglpZiAoZGF0YS0+aFduZCA9PSBHZXRGb2N1cygpICYmIGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKCSAgICBTaG93Q2FyZXQoZGF0YS0+aFduZCk7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9Nb3ZlU2VsZWN0aW9uCiAqCiAqCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfTW92ZVNlbGVjdGlvbihzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgQ09PUkQgYzEsIENPT1JEIGMyKQp7CiAgICBSRUNUCXI7CiAgICBIREMJCWhEQzsKCiAgICBpZiAoYzEuWCA8IDAgfHwgYzEuWCA+PSBkYXRhLT5jdXJjZmcuc2Jfd2lkdGggfHwKICAgICAgICBjMi5YIDwgMCB8fCBjMi5YID49IGRhdGEtPmN1cmNmZy5zYl93aWR0aCB8fAogICAgICAgIGMxLlkgPCAwIHx8IGMxLlkgPj0gZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCB8fAogICAgICAgIGMyLlkgPCAwIHx8IGMyLlkgPj0gZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCkKICAgICAgICByZXR1cm47CgogICAgV0NVU0VSX0dldFNlbGVjdGlvblJlY3QoZGF0YSwgJnIpOwogICAgaERDID0gR2V0REMoZGF0YS0+aFduZCk7CiAgICBpZiAoaERDKQogICAgewoJaWYgKGRhdGEtPmhXbmQgPT0gR2V0Rm9jdXMoKSAmJiBkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUpCgkgICAgSGlkZUNhcmV0KGRhdGEtPmhXbmQpOwoJSW52ZXJ0UmVjdChoREMsICZyKTsKICAgIH0KICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MSA9IGMxOwogICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyID0gYzI7CiAgICBpZiAoaERDKQogICAgewoJV0NVU0VSX0dldFNlbGVjdGlvblJlY3QoZGF0YSwgJnIpOwoJSW52ZXJ0UmVjdChoREMsICZyKTsKCVJlbGVhc2VEQyhkYXRhLT5oV25kLCBoREMpOwoJaWYgKGRhdGEtPmhXbmQgPT0gR2V0Rm9jdXMoKSAmJiBkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUpCgkgICAgU2hvd0NhcmV0KGRhdGEtPmhXbmQpOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfQ29weVNlbGVjdGlvblRvQ2xpcGJvYXJkCiAqCiAqIENvcGllcyB0aGUgY3VycmVudCBzZWxlY3Rpb24gaW50byB0aGUgY2xpcGJvYXJkCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfQ29weVNlbGVjdGlvblRvQ2xpcGJvYXJkKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBIQU5ETEUJaE1lbTsKICAgIExQV1NUUglwOwogICAgdW5zaWduZWQJdywgaDsKCiAgICB3ID0gYWJzKFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MS5YIC0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlgpICsgMjsKICAgIGggPSBhYnMoUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlkgLSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIuWSkgKyAxOwoKICAgIGlmICghT3BlbkNsaXBib2FyZChkYXRhLT5oV25kKSkgcmV0dXJuOwogICAgRW1wdHlDbGlwYm9hcmQoKTsKCiAgICBoTWVtID0gR2xvYmFsQWxsb2MoR01FTV9NT1ZFQUJMRSwgKHcgKiBoKSAqIHNpemVvZihXQ0hBUikpOwogICAgaWYgKGhNZW0gJiYgKHAgPSBHbG9iYWxMb2NrKGhNZW0pKSkKICAgIHsKCUNPT1JECWM7CglpbnQJeTsKCgljLlggPSBtaW4oUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlgsIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5YKTsKCWMuWSA9IG1pbihQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWSwgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlkpOwoKCWZvciAoeSA9IDA7IHkgPCBoOyB5KyssIGMuWSsrKQoJewoJICAgIExQV1NUUiBlbmQ7CgkgICAgUmVhZENvbnNvbGVPdXRwdXRDaGFyYWN0ZXIoZGF0YS0+aENvbk91dCwgcCwgdyAtIDEsIGMsIE5VTEwpOwoJICAgIAoJICAgIC8qIHN0cmlwIHNwYWNlcyBmcm9tIHRoZSBlbmQgb2YgdGhlIGxpbmUgKi8KCSAgICBlbmQgPSBwICsgdyAtIDE7CgkgICAgd2hpbGUgKGVuZCA+IHAgJiYgKihlbmQgLSAxKSA9PSAnICcpCgkgICAgICAgIGVuZC0tOwoJICAgICplbmQgPSAoeSA8IGggLSAxKSA/ICdcbicgOiAnXDAnOwoJICAgIHAgPSBlbmQgKyAxOwoJfQoJR2xvYmFsVW5sb2NrKGhNZW0pOwoJU2V0Q2xpcGJvYXJkRGF0YShDRl9VTklDT0RFVEVYVCwgaE1lbSk7CiAgICB9CiAgICBDbG9zZUNsaXBib2FyZCgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfUGFzdGVGcm9tQ2xpcGJvYXJkCiAqCiAqCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfUGFzdGVGcm9tQ2xpcGJvYXJkKHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBIQU5ETEUJaDsKICAgIFdDSEFSKglwdHI7CgogICAgaWYgKCFPcGVuQ2xpcGJvYXJkKGRhdGEtPmhXbmQpKSByZXR1cm47CiAgICBoID0gR2V0Q2xpcGJvYXJkRGF0YShDRl9VTklDT0RFVEVYVCk7CiAgICBpZiAoaCAmJiAocHRyID0gR2xvYmFsTG9jayhoKSkpCiAgICB7CglpbnQJCWksIGxlbiA9IEdsb2JhbFNpemUoaCkgLyBzaXplb2YoV0NIQVIpOwoJSU5QVVRfUkVDT1JECWlyWzJdOwoJRFdPUkQJCW47CglTSE9SVAkJc2g7CgoJaXJbMF0uRXZlbnRUeXBlID0gS0VZX0VWRU5UOwoJaXJbMF0uRXZlbnQuS2V5RXZlbnQud1JlcGVhdENvdW50ID0gMDsKCWlyWzBdLkV2ZW50LktleUV2ZW50LmR3Q29udHJvbEtleVN0YXRlID0gMDsKCWlyWzBdLkV2ZW50LktleUV2ZW50LmJLZXlEb3duID0gVFJVRTsKCgkvKiBnZW5lcmF0ZSB0aGUgY29ycmVzcG9uZGluZyBpbnB1dCByZWNvcmRzICovCglmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspCgl7CgkgICAgLyogRklYTUU6IHRoZSBtb2RpZnlpbmcga2V5cyBhcmUgbm90IGdlbmVyYXRlZCAoc2hpZnQsIGN0cmwuLi4pICovCgkgICAgc2ggPSBWa0tleVNjYW4ocHRyW2ldKTsKCSAgICBpclswXS5FdmVudC5LZXlFdmVudC53VmlydHVhbEtleUNvZGUgPSBMT0JZVEUoc2gpOwoJICAgIGlyWzBdLkV2ZW50LktleUV2ZW50LndWaXJ0dWFsU2NhbkNvZGUgPSBNYXBWaXJ0dWFsS2V5KExPQllURShzaCksIDApOwoJICAgIGlyWzBdLkV2ZW50LktleUV2ZW50LnVDaGFyLlVuaWNvZGVDaGFyID0gcHRyW2ldOwoKCSAgICBpclsxXSA9IGlyWzBdOwoJICAgIGlyWzFdLkV2ZW50LktleUV2ZW50LmJLZXlEb3duID0gRkFMU0U7CgoJICAgIFdyaXRlQ29uc29sZUlucHV0KGRhdGEtPmhDb25JbiwgaXIsIDIsICZuKTsKCX0KCUdsb2JhbFVubG9jayhoKTsKICAgIH0KICAgIENsb3NlQ2xpcGJvYXJkKCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9SZWZyZXNoCiAqCiAqCiAqLwpzdGF0aWMgdm9pZCBXQ1VTRVJfUmVmcmVzaChjb25zdCBzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgaW50IHRwLCBpbnQgYm0pCnsKICAgIFdDVVNFUl9GaWxsTWVtREMoZGF0YSwgdHAsIGJtKTsKICAgIGlmIChkYXRhLT5jdXJjZmcud2luX3Bvcy5ZIDw9IGJtICYmIGRhdGEtPmN1cmNmZy53aW5fcG9zLlkgKyBkYXRhLT5jdXJjZmcud2luX2hlaWdodCA+PSB0cCkKICAgIHsKCVJFQ1QJcjsKCglyLmxlZnQgICA9IDA7CglyLnJpZ2h0ICA9IGRhdGEtPmN1cmNmZy53aW5fd2lkdGggKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKCXIudG9wICAgID0gKHRwIC0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSkgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQ7CglyLmJvdHRvbSA9IChibSAtIGRhdGEtPmN1cmNmZy53aW5fcG9zLlkgKyAxKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKCUludmFsaWRhdGVSZWN0KGRhdGEtPmhXbmQsICZyLCBGQUxTRSk7CglVcGRhdGVXaW5kb3coZGF0YS0+aFduZCk7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9QYWludAogKgogKgogKi8Kc3RhdGljIHZvaWQJV0NVU0VSX1BhaW50KGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBQQUlOVFNUUlVDVAkJcHM7CgogICAgQmVnaW5QYWludChkYXRhLT5oV25kLCAmcHMpOwogICAgQml0Qmx0KHBzLmhkYywgMCwgMCwKICAgICAgICAgICBkYXRhLT5jdXJjZmcud2luX3dpZHRoICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGgsCiAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLndpbl9oZWlnaHQgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQsCgkgICBQUklWQVRFKGRhdGEpLT5oTWVtREMsCiAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWCAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoLAogICAgICAgICAgIGRhdGEtPmN1cmNmZy53aW5fcG9zLlkgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQsCgkgICBTUkNDT1BZKTsKICAgIGlmIChQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uKQoJV0NVU0VSX1NldFNlbGVjdGlvbihkYXRhLCBwcy5oZGMpOwogICAgRW5kUGFpbnQoZGF0YS0+aFduZCwgJnBzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1Njcm9sbAogKgogKgogKi8Kc3RhdGljIHZvaWQgV0NVU0VSX1Njcm9sbChzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgaW50IHBvcywgQk9PTCBob3J6KQp7CiAgICBpZiAoaG9yeikKICAgIHsKCVNldFNjcm9sbFBvcyhkYXRhLT5oV25kLCBTQl9IT1JaLCBwb3MsIFRSVUUpOwoJZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWCA9IHBvczsKICAgIH0KICAgIGVsc2UKICAgIHsKCVNldFNjcm9sbFBvcyhkYXRhLT5oV25kLCBTQl9WRVJULCBwb3MsIFRSVUUpOwoJZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSA9IHBvczsKICAgIH0KICAgIEludmFsaWRhdGVSZWN0KGRhdGEtPmhXbmQsIE5VTEwsIEZBTFNFKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0ZpbGxNZW51CiAqCiAqCiAqLwpzdGF0aWMgQk9PTCBXQ1VTRVJfRmlsbE1lbnUoSE1FTlUgaE1lbnUsIEJPT0wgc2VwKQp7CiAgICBITUVOVQkJaFN1Yk1lbnU7CiAgICBISU5TVEFOQ0UJCWhJbnN0YW5jZSA9IEdldE1vZHVsZUhhbmRsZShOVUxMKTsKICAgIFdDSEFSCQlidWZmWzI1Nl07CgogICAgaWYgKCFoTWVudSkgcmV0dXJuIEZBTFNFOwoKICAgIC8qIEZJWE1FOiBlcnJvciBoYW5kbGluZyAmIG1lbW9yeSBjbGVhbnVwICovCiAgICBoU3ViTWVudSA9IENyZWF0ZU1lbnUoKTsKICAgIGlmICghaFN1Yk1lbnUpIHJldHVybiBGQUxTRTsKCiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX01BUkssIGJ1ZmYsIHNpemVvZihidWZmKSAvIHNpemVvZihXQ0hBUikpOwogICAgSW5zZXJ0TWVudShoU3ViTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU1RSSU5HLCBJRFNfTUFSSywgYnVmZik7CiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX0NPUFksIGJ1ZmYsIHNpemVvZihidWZmKSAvIHNpemVvZihXQ0hBUikpOwogICAgSW5zZXJ0TWVudShoU3ViTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU1RSSU5HLCBJRFNfQ09QWSwgYnVmZik7CiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX1BBU1RFLCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaFN1Yk1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklORywgSURTX1BBU1RFLCBidWZmKTsKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfU0VMRUNUQUxMLCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaFN1Yk1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklORywgSURTX1NFTEVDVEFMTCwgYnVmZik7CiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX1NDUk9MTCwgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhTdWJNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkcsIElEU19TQ1JPTEwsIGJ1ZmYpOwogICAgTG9hZFN0cmluZyhoSW5zdGFuY2UsIElEU19TRUFSQ0gsIGJ1ZmYsIHNpemVvZihidWZmKSAvIHNpemVvZihXQ0hBUikpOwogICAgSW5zZXJ0TWVudShoU3ViTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU1RSSU5HLCBJRFNfU0VBUkNILCBidWZmKTsKCiAgICBpZiAoc2VwKSBJbnNlcnRNZW51KGhNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TRVBBUkFUT1IsIDAsIE5VTEwpOwogICAgTG9hZFN0cmluZyhoSW5zdGFuY2UsIElEU19FRElULCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaE1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklOR3xNRl9QT1BVUCwgKFVJTlRfUFRSKWhTdWJNZW51LCBidWZmKTsKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfREVGQVVMVCwgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkcsIElEU19ERUZBVUxULCBidWZmKTsKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfUFJPUEVSVElFUywgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkcsIElEU19QUk9QRVJUSUVTLCBidWZmKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1NldE1lbnVEZXRhaWxzCiAqCiAqIEdyYXlzIC8gdW5ncmF5cyB0aGUgbWVudSBpdGVtcyBhY2NvcmRpbmcgdG8gdGhlaXIgc3RhdGUKICovCnN0YXRpYyB2b2lkCVdDVVNFUl9TZXRNZW51RGV0YWlscyhjb25zdCBzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgSE1FTlUgaE1lbnUpCnsKICAgIGlmICghaE1lbnUpIHtXSU5FX0VSUigiSXNzdWUgaW4gZ2V0dGluZyBtZW51IGJpdHNcbiIpO3JldHVybjt9CgogICAgRW5hYmxlTWVudUl0ZW0oaE1lbnUsIElEU19DT1BZLAogICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EfChQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID8gTUZfRU5BQkxFRCA6IE1GX0dSQVlFRCkpOwogICAgRW5hYmxlTWVudUl0ZW0oaE1lbnUsIElEU19QQVNURSwKCQkgICBNRl9CWUNPTU1BTkR8KElzQ2xpcGJvYXJkRm9ybWF0QXZhaWxhYmxlKENGX1VOSUNPREVURVhUKQoJCQkJID8gTUZfRU5BQkxFRCA6IE1GX0dSQVlFRCkpOwogICAgRW5hYmxlTWVudUl0ZW0oaE1lbnUsIElEU19TQ1JPTEwsIE1GX0JZQ09NTUFORHxNRl9HUkFZRUQpOwogICAgRW5hYmxlTWVudUl0ZW0oaE1lbnUsIElEU19TRUFSQ0gsIE1GX0JZQ09NTUFORHxNRl9HUkFZRUQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfQ3JlYXRlCiAqCiAqIENyZWF0ZXMgdGhlIHdpbmRvdyBmb3IgdGhlIHJlbmRlcmluZwogKi8Kc3RhdGljIExSRVNVTFQgV0NVU0VSX0NyZWF0ZShIV05EIGhXbmQsIExQQ1JFQVRFU1RSVUNUIGxwY3MpCnsKICAgIHN0cnVjdCBpbm5lcl9kYXRhKglkYXRhOwogICAgSE1FTlUJCWhTeXNNZW51OwoKICAgIGRhdGEgPSBscGNzLT5scENyZWF0ZVBhcmFtczsKICAgIFNldFdpbmRvd0xvbmdQdHIoaFduZCwgMEwsIChEV09SRF9QVFIpZGF0YSk7CiAgICBkYXRhLT5oV25kID0gaFduZDsKCiAgICBoU3lzTWVudSA9IEdldFN5c3RlbU1lbnUoaFduZCwgRkFMU0UpOwogICAgaWYgKCFoU3lzTWVudSkgcmV0dXJuIDA7CiAgICBQUklWQVRFKGRhdGEpLT5oUG9wTWVudSA9IENyZWF0ZVBvcHVwTWVudSgpOwogICAgaWYgKCFQUklWQVRFKGRhdGEpLT5oUG9wTWVudSkgcmV0dXJuIDA7CgogICAgV0NVU0VSX0ZpbGxNZW51KGhTeXNNZW51LCBUUlVFKTsKICAgIFdDVVNFUl9GaWxsTWVudShQUklWQVRFKGRhdGEpLT5oUG9wTWVudSwgRkFMU0UpOwoKICAgIFBSSVZBVEUoZGF0YSktPmhNZW1EQyA9IENyZWF0ZUNvbXBhdGlibGVEQygwKTsKICAgIGlmICghUFJJVkFURShkYXRhKS0+aE1lbURDKSB7V0lORV9FUlIoIm5vIG1lbSBkY1xuIik7cmV0dXJuIDA7fQoKICAgIGRhdGEtPmN1cmNmZy5xdWlja19lZGl0ID0gRkFMU0U7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0dldEN0cmxLZXlTdGF0ZQogKgogKiBHZXQgdGhlIGNvbnNvbGUgYml0IG1hc2sgZXF1aXZhbGVudCB0byB0aGUgVktfIHN0YXR1cyBpbiBrZXlTdGF0ZQogKi8Kc3RhdGljIERXT1JEICAgIFdDVVNFUl9HZXRDdHJsS2V5U3RhdGUoQllURSoga2V5U3RhdGUpCnsKICAgIERXT1JEICAgICAgICAgICAgICAgcmV0ID0gMDsKCiAgICBHZXRLZXlib2FyZFN0YXRlKGtleVN0YXRlKTsKICAgIGlmIChrZXlTdGF0ZVtWS19TSElGVF0gICAgJiAweDgwKQlyZXQgfD0gU0hJRlRfUFJFU1NFRDsKICAgIGlmIChrZXlTdGF0ZVtWS19MQ09OVFJPTF0gJiAweDgwKQlyZXQgfD0gTEVGVF9DVFJMX1BSRVNTRUQ7CiAgICBpZiAoa2V5U3RhdGVbVktfUkNPTlRST0xdICYgMHg4MCkJcmV0IHw9IFJJR0hUX0NUUkxfUFJFU1NFRDsKICAgIGlmIChrZXlTdGF0ZVtWS19MTUVOVV0gICAgJiAweDgwKQlyZXQgfD0gTEVGVF9BTFRfUFJFU1NFRDsKICAgIGlmIChrZXlTdGF0ZVtWS19STUVOVV0gICAgJiAweDgwKQlyZXQgfD0gUklHSFRfQUxUX1BSRVNTRUQ7CiAgICBpZiAoa2V5U3RhdGVbVktfQ0FQSVRBTF0gICYgMHgwMSkJcmV0IHw9IENBUFNMT0NLX09OOwogICAgaWYgKGtleVN0YXRlW1ZLX05VTUxPQ0tdICAmIDB4MDEpCXJldCB8PSBOVU1MT0NLX09OOwogICAgaWYgKGtleVN0YXRlW1ZLX1NDUk9MTF0gICAmIDB4MDEpCXJldCB8PSBTQ1JPTExMT0NLX09OOwoKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9IYW5kbGVTZWxlY3Rpb25LZXkKICoKICogSGFuZGxlcyBrZXlzIHdoaWxlIHNlbGVjdGluZyBhbiBhcmVhCiAqLwpzdGF0aWMgdm9pZCBXQ1VTRVJfSGFuZGxlU2VsZWN0aW9uS2V5KHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBCT09MIGRvd24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogICAgQllURQlrZXlTdGF0ZVsyNTZdOwogICAgRFdPUkQgICAgICAgc3RhdGUgPSBXQ1VTRVJfR2V0Q3RybEtleVN0YXRlKGtleVN0YXRlKSAmIH4oQ0FQU0xPQ0tfT058TlVNTE9DS19PTnxTQ1JPTExMT0NLX09OKTsKICAgIENPT1JEICAgICAgIGMxLCBjMjsKCiAgICBpZiAoIWRvd24pIHJldHVybjsKCiAgICBzd2l0Y2ggKHN0YXRlKQogICAgewogICAgY2FzZSAwOgogICAgICAgIHN3aXRjaCAod1BhcmFtKQogICAgICAgIHsKICAgICAgICBjYXNlIFZLX1JFVFVSTjoKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiA9IEZBTFNFOwogICAgICAgICAgICBXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIDApOwogICAgICAgICAgICBXQ1VTRVJfQ29weVNlbGVjdGlvblRvQ2xpcGJvYXJkKGRhdGEpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgY2FzZSBWS19SSUdIVDoKICAgICAgICAgICAgYzEgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDE7CiAgICAgICAgICAgIGMyID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyOwogICAgICAgICAgICBjMS5YKys7IGMyLlgrKzsKICAgICAgICAgICAgV0NVU0VSX01vdmVTZWxlY3Rpb24oZGF0YSwgYzEsIGMyKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIGNhc2UgVktfTEVGVDoKICAgICAgICAgICAgYzEgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDE7CiAgICAgICAgICAgIGMyID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyOwogICAgICAgICAgICBjMS5YLS07IGMyLlgtLTsKICAgICAgICAgICAgV0NVU0VSX01vdmVTZWxlY3Rpb24oZGF0YSwgYzEsIGMyKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIGNhc2UgVktfVVA6CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzEuWS0tOyBjMi5ZLS07CiAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMik7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICBjYXNlIFZLX0RPV046CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzEuWSsrOyBjMi5ZKys7CiAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMik7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFNISUZUX1BSRVNTRUQ6CiAgICAgICAgc3dpdGNoICh3UGFyYW0pCiAgICAgICAgewogICAgICAgIGNhc2UgVktfUklHSFQ6CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzIuWCsrOwogICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgY2FzZSBWS19MRUZUOgogICAgICAgICAgICBjMSA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MTsKICAgICAgICAgICAgYzIgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDI7CiAgICAgICAgICAgIGMyLlgtLTsKICAgICAgICAgICAgV0NVU0VSX01vdmVTZWxlY3Rpb24oZGF0YSwgYzEsIGMyKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIGNhc2UgVktfVVA6CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzIuWS0tOwogICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgY2FzZSBWS19ET1dOOgogICAgICAgICAgICBjMSA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MTsKICAgICAgICAgICAgYzIgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDI7CiAgICAgICAgICAgIGMyLlkrKzsKICAgICAgICAgICAgV0NVU0VSX01vdmVTZWxlY3Rpb24oZGF0YSwgYzEsIGMyKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KCiAgICBpZiAod1BhcmFtIDwgVktfU1BBQ0UpICAvKiBTaGlmdCwgQWx0LCBDdHJsLCBOdW0gTG9jayBldGMuICovCiAgICAgICAgcmV0dXJuOwogICAgCiAgICBXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIDApOyAgICAKICAgIFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24gPSBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0dlbmVyYXRlS2V5SW5wdXRSZWNvcmQKICoKICogZ2VuZXJhdGVzIGlucHV0X3JlY29yZCBmcm9tIHdpbmRvd3MgV01fS0VZVVAvV01fS0VZRE9XTiBtZXNzYWdlcwogKi8Kc3RhdGljIHZvaWQgICAgV0NVU0VSX0dlbmVyYXRlS2V5SW5wdXRSZWNvcmQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIEJPT0wgZG93biwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSwgQk9PTCBzeXMpCnsKICAgIElOUFVUX1JFQ09SRAlpcjsKICAgIERXT1JECQluOwogICAgV0NIQVIJCWJ1ZlsyXTsKICAgIHN0YXRpYwlXQ0hBUglsYXN0OyAvKiBrZWVwIGxhc3QgY2hhciBzZWVuIGFzIGZlZWQgZm9yIGtleSB1cCBtZXNzYWdlICovCiAgICBCWVRFCQlrZXlTdGF0ZVsyNTZdOwoKICAgIGlyLkV2ZW50VHlwZSA9IEtFWV9FVkVOVDsKICAgIGlyLkV2ZW50LktleUV2ZW50LmJLZXlEb3duID0gZG93bjsKICAgIGlyLkV2ZW50LktleUV2ZW50LndSZXBlYXRDb3VudCA9IExPV09SRChsUGFyYW0pOwogICAgaXIuRXZlbnQuS2V5RXZlbnQud1ZpcnR1YWxLZXlDb2RlID0gd1BhcmFtOwoKICAgIGlyLkV2ZW50LktleUV2ZW50LndWaXJ0dWFsU2NhbkNvZGUgPSBISVdPUkQobFBhcmFtKSAmIDB4RkY7CgogICAgaXIuRXZlbnQuS2V5RXZlbnQudUNoYXIuVW5pY29kZUNoYXIgPSAwOwogICAgaXIuRXZlbnQuS2V5RXZlbnQuZHdDb250cm9sS2V5U3RhdGUgPSBXQ1VTRVJfR2V0Q3RybEtleVN0YXRlKGtleVN0YXRlKTsKICAgIGlmIChsUGFyYW0gJiAoMUwgPDwgMjQpKQkJaXIuRXZlbnQuS2V5RXZlbnQuZHdDb250cm9sS2V5U3RhdGUgfD0gRU5IQU5DRURfS0VZOwogICAgaWYgKHN5cykJCQkJaXIuRXZlbnQuS2V5RXZlbnQuZHdDb250cm9sS2V5U3RhdGUgfD0gTEVGVF9BTFRfUFJFU1NFRDsgLyogRklYTUU6IGdvdHRhIGNob29zZSBvbmUgKi8KCiAgICBpZiAoIShpci5FdmVudC5LZXlFdmVudC5kd0NvbnRyb2xLZXlTdGF0ZSAmIEVOSEFOQ0VEX0tFWSkpCiAgICB7CglpZiAoZG93bikKCXsKCSAgICBzd2l0Y2ggKFRvVW5pY29kZSh3UGFyYW0sIEhJV09SRChsUGFyYW0pLCBrZXlTdGF0ZSwgYnVmLCAyLCAwKSkKCSAgICB7CgkgICAgY2FzZSAyOgoJCS8qIEZJWE1FLi4uIHNob3VsZCBnZW5lcmF0ZSB0d28gZXZlbnRzLi4uICovCgkJLyogZmFsbCB0aHJ1ICovCgkgICAgY2FzZSAxOgoJCWxhc3QgPSBidWZbMF07CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlsYXN0ID0gMDsKCQlicmVhazsKCSAgICB9Cgl9Cglpci5FdmVudC5LZXlFdmVudC51Q2hhci5Vbmljb2RlQ2hhciA9IGxhc3Q7IC8qIEZJWE1FOiBIQUNLWS4uLiBhbmQgYnVnZ3kgYmVjYXVzZSBpdCBzaG91bGQgYmUgYSBzdGFjaywgbm90IGEgc2luZ2xlIHZhbHVlICovCglpZiAoIWRvd24pIGxhc3QgPSAwOwogICAgfQoKICAgIFdyaXRlQ29uc29sZUlucHV0KGRhdGEtPmhDb25JbiwgJmlyLCAxLCAmbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQKICoKICoKICovCnN0YXRpYyB2b2lkICAgIFdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIENPT1JEIGMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1BBUkFNIHdQYXJhbSwgRFdPUkQgZXZlbnQpCnsKICAgIElOUFVUX1JFQ09SRAlpcjsKICAgIEJZVEUJCWtleVN0YXRlWzI1Nl07CiAgICBEV09SRCAgICAgICAgICAgICAgIG1vZGUsIG47CgogICAgLyogTU9VU0VfRVZFTlRzIHNob3VsZG4ndCBiZSBzZW50IHVubGVzcyBFTkFCTEVfTU9VU0VfSU5QVVQgaXMgYWN0aXZlICovCiAgICBpZiAoIUdldENvbnNvbGVNb2RlKGRhdGEtPmhDb25JbiwgJm1vZGUpIHx8ICEobW9kZSAmIEVOQUJMRV9NT1VTRV9JTlBVVCkpCiAgICAgICAgcmV0dXJuOwoKICAgIGlyLkV2ZW50VHlwZSA9IE1PVVNFX0VWRU5UOwogICAgaXIuRXZlbnQuTW91c2VFdmVudC5kd01vdXNlUG9zaXRpb24gPSBjOwogICAgaXIuRXZlbnQuTW91c2VFdmVudC5kd0J1dHRvblN0YXRlID0gMDsKICAgIGlmICh3UGFyYW0gJiBNS19MQlVUVE9OKSBpci5FdmVudC5Nb3VzZUV2ZW50LmR3QnV0dG9uU3RhdGUgfD0gRlJPTV9MRUZUXzFTVF9CVVRUT05fUFJFU1NFRDsKICAgIGlmICh3UGFyYW0gJiBNS19NQlVUVE9OKSBpci5FdmVudC5Nb3VzZUV2ZW50LmR3QnV0dG9uU3RhdGUgfD0gRlJPTV9MRUZUXzJORF9CVVRUT05fUFJFU1NFRDsKICAgIGlmICh3UGFyYW0gJiBNS19SQlVUVE9OKSBpci5FdmVudC5Nb3VzZUV2ZW50LmR3QnV0dG9uU3RhdGUgfD0gUklHSFRNT1NUX0JVVFRPTl9QUkVTU0VEOwogICAgaWYgKHdQYXJhbSAmIE1LX0NPTlRST0wpIGlyLkV2ZW50Lk1vdXNlRXZlbnQuZHdCdXR0b25TdGF0ZSB8PSBMRUZUX0NUUkxfUFJFU1NFRDsKICAgIGlmICh3UGFyYW0gJiBNS19TSElGVCkgICBpci5FdmVudC5Nb3VzZUV2ZW50LmR3QnV0dG9uU3RhdGUgfD0gU0hJRlRfUFJFU1NFRDsKICAgIGlmIChldmVudCA9PSBNT1VTRV9XSEVFTEVEKSBpci5FdmVudC5Nb3VzZUV2ZW50LmR3QnV0dG9uU3RhdGUgfD0gd1BhcmFtICYgMHhGRkZGMDAwMDsKICAgIGlyLkV2ZW50Lk1vdXNlRXZlbnQuZHdDb250cm9sS2V5U3RhdGUgPSBXQ1VTRVJfR2V0Q3RybEtleVN0YXRlKGtleVN0YXRlKTsKICAgIGlyLkV2ZW50Lk1vdXNlRXZlbnQuZHdFdmVudEZsYWdzID0gZXZlbnQ7CgogICAgV3JpdGVDb25zb2xlSW5wdXQoZGF0YS0+aENvbkluLCAmaXIsIDEsICZuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1Byb2MKICoKICoKICovCnN0YXRpYyBMUkVTVUxUIENBTExCQUNLIFdDVVNFUl9Qcm9jKEhXTkQgaFduZCwgVUlOVCB1TXNnLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBzdHJ1Y3QgaW5uZXJfZGF0YSoJZGF0YSA9IChzdHJ1Y3QgaW5uZXJfZGF0YSopR2V0V2luZG93TG9uZ1B0cihoV25kLCAwKTsKCiAgICBzd2l0Y2ggKHVNc2cpCiAgICB7CiAgICBjYXNlIFdNX0NSRUFURToKICAgICAgICByZXR1cm4gV0NVU0VSX0NyZWF0ZShoV25kLCAoTFBDUkVBVEVTVFJVQ1QpbFBhcmFtKTsKICAgIGNhc2UgV01fREVTVFJPWToKCWRhdGEtPmhXbmQgPSAwOwoJUG9zdFF1aXRNZXNzYWdlKDApOwoJYnJlYWs7CiAgICBjYXNlIFdNX1BBSU5UOgoJV0NVU0VSX1BhaW50KGRhdGEpOwoJYnJlYWs7CiAgICBjYXNlIFdNX0tFWURPV046CiAgICBjYXNlIFdNX0tFWVVQOgogICAgICAgIGlmIChQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uKQogICAgICAgICAgICBXQ1VTRVJfSGFuZGxlU2VsZWN0aW9uS2V5KGRhdGEsIHVNc2cgPT0gV01fS0VZRE9XTiwgd1BhcmFtLCBsUGFyYW0pOwogICAgICAgIGVsc2UKICAgICAgICAgICAgV0NVU0VSX0dlbmVyYXRlS2V5SW5wdXRSZWNvcmQoZGF0YSwgdU1zZyA9PSBXTV9LRVlET1dOLCB3UGFyYW0sIGxQYXJhbSwgRkFMU0UpOwoJYnJlYWs7CiAgICBjYXNlIFdNX1NZU0tFWURPV046CiAgICBjYXNlIFdNX1NZU0tFWVVQOgoJV0NVU0VSX0dlbmVyYXRlS2V5SW5wdXRSZWNvcmQoZGF0YSwgdU1zZyA9PSBXTV9TWVNLRVlET1dOLCB3UGFyYW0sIGxQYXJhbSwgVFJVRSk7CglicmVhazsKICAgIGNhc2UgV01fTEJVVFRPTkRPV046CiAgICAgICAgaWYgKGRhdGEtPmN1cmNmZy5xdWlja19lZGl0IHx8IFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24pCiAgICAgICAgewogICAgICAgICAgICBpZiAoUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbikKICAgICAgICAgICAgICAgIFdDVVNFUl9TZXRTZWxlY3Rpb24oZGF0YSwgMCk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoZGF0YS0+Y3VyY2ZnLnF1aWNrX2VkaXQgJiYgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiA9IEZBTFNFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyID0gV0NVU0VSX0dldENlbGwoZGF0YSwgbFBhcmFtKTsKICAgICAgICAgICAgICAgIFNldENhcHR1cmUoZGF0YS0+aFduZCk7CiAgICAgICAgICAgICAgICBXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIDApOwogICAgICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiA9IFRSVUU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgV0NVU0VSX0dlbmVyYXRlTW91c2VJbnB1dFJlY29yZChkYXRhLCBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCB3UGFyYW0sIDApOwogICAgICAgIH0KCWJyZWFrOwogICAgY2FzZSBXTV9NT1VTRU1PVkU6CiAgICAgICAgaWYgKGRhdGEtPmN1cmNmZy5xdWlja19lZGl0IHx8IFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24pCiAgICAgICAgewogICAgICAgICAgICBpZiAoR2V0Q2FwdHVyZSgpID09IGRhdGEtPmhXbmQgJiYgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiAmJgogICAgICAgICAgICAgICAgKHdQYXJhbSAmIE1LX0xCVVRUT04pKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEsIFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQoZGF0YSwgV0NVU0VSX0dldENlbGwoZGF0YSwgbFBhcmFtKSwgd1BhcmFtLCBNT1VTRV9NT1ZFRCk7CiAgICAgICAgfQoJYnJlYWs7CiAgICBjYXNlIFdNX0xCVVRUT05VUDoKICAgICAgICBpZiAoZGF0YS0+Y3VyY2ZnLnF1aWNrX2VkaXQgfHwgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIGlmIChHZXRDYXB0dXJlKCkgPT0gZGF0YS0+aFduZCAmJiBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEsIFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSkpOwogICAgICAgICAgICAgICAgUmVsZWFzZUNhcHR1cmUoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBXQ1VTRVJfR2VuZXJhdGVNb3VzZUlucHV0UmVjb3JkKGRhdGEsIFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSksIHdQYXJhbSwgMCk7CiAgICAgICAgfQoJYnJlYWs7CiAgICBjYXNlIFdNX1JCVVRUT05ET1dOOgogICAgICAgIGlmICgod1BhcmFtICYgKE1LX0NPTlRST0x8TUtfU0hJRlQpKSA9PSBkYXRhLT5jdXJjZmcubWVudV9tYXNrKQogICAgICAgIHsKICAgICAgICAgICAgUE9JTlQgICAgICAgcHQ7CgogICAgICAgICAgICBwdC54ID0gKHNob3J0KUxPV09SRChsUGFyYW0pOwogICAgICAgICAgICBwdC55ID0gKHNob3J0KUhJV09SRChsUGFyYW0pOwogICAgICAgICAgICBDbGllbnRUb1NjcmVlbihoV25kLCAmcHQpOwogICAgICAgICAgICBXQ1VTRVJfU2V0TWVudURldGFpbHMoZGF0YSwgUFJJVkFURShkYXRhKS0+aFBvcE1lbnUpOwogICAgICAgICAgICBUcmFja1BvcHVwTWVudShQUklWQVRFKGRhdGEpLT5oUG9wTWVudSwgVFBNX0xFRlRBTElHTnxUUE1fVE9QQUxJR04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHB0LngsIHB0LnksIDAsIGhXbmQsIE5VTEwpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBXQ1VTRVJfR2VuZXJhdGVNb3VzZUlucHV0UmVjb3JkKGRhdGEsIFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSksIHdQYXJhbSwgMCk7CiAgICAgICAgfQoJYnJlYWs7CiAgICBjYXNlIFdNX1JCVVRUT05VUDoKICAgICAgICAvKiBubyBuZWVkIHRvIHRyYWNrIGZvciByYnV0dG9uIHVwIHdoZW4gb3BlbmluZyB0aGUgcG9wdXAuLi4gdGhlIGV2ZW50IHdpbGwgYmUKICAgICAgICAgKiBzd2FsbG93ZWQgYnkgVHJhY2tQb3B1cE1lbnUgKi8KICAgIGNhc2UgV01fTUJVVFRPTkRPV046CiAgICBjYXNlIFdNX01CVVRUT05VUDoKICAgICAgICBXQ1VTRVJfR2VuZXJhdGVNb3VzZUlucHV0UmVjb3JkKGRhdGEsIFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSksIHdQYXJhbSwgMCk7CglicmVhazsKICAgIGNhc2UgV01fTEJVVFRPTkRCTENMSzoKICAgIGNhc2UgV01fTUJVVFRPTkRCTENMSzoKICAgIGNhc2UgV01fUkJVVFRPTkRCTENMSzoKICAgICAgICBXQ1VTRVJfR2VuZXJhdGVNb3VzZUlucHV0UmVjb3JkKGRhdGEsIFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSksIHdQYXJhbSwgRE9VQkxFX0NMSUNLKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgV01fTU9VU0VXSEVFTDoKICAgICAgICBXQ1VTRVJfR2VuZXJhdGVNb3VzZUlucHV0UmVjb3JkKGRhdGEsICBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCB3UGFyYW0sIE1PVVNFX1dIRUVMRUQpOwoJYnJlYWs7CiAgICBjYXNlIFdNX1NFVEZPQ1VTOgoJaWYgKGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKCXsKCSAgICBDcmVhdGVDYXJldChkYXRhLT5oV25kLCBQUklWQVRFKGRhdGEpLT5jdXJzb3JfYml0bWFwLAogICAgICAgICAgICAgICAgICAgICAgICBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwgZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0KTsKCSAgICBXQ1VTRVJfUG9zQ3Vyc29yKGRhdGEpOwoJfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBXTV9LSUxMRk9DVVM6CglpZiAoZGF0YS0+Y3VyY2ZnLmN1cnNvcl92aXNpYmxlKQoJICAgIERlc3Ryb3lDYXJldCgpOwoJYnJlYWs7CiAgICBjYXNlIFdNX0hTQ1JPTEw6CiAgICAgICAgewogICAgICAgICAgICBpbnQJcG9zID0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWDsKCiAgICAgICAgICAgIHN3aXRjaCAoTE9XT1JEKHdQYXJhbSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgY2FzZSBTQl9QQUdFVVA6IAlwb3MgLT0gODsgCQlicmVhazsKICAgICAgICAgICAgY2FzZSBTQl9QQUdFRE9XTjogCXBvcyArPSA4OyAJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX0xJTkVVUDogCXBvcy0tOwkJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX0xJTkVET1dOOiAJcG9zKys7CSAJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX1RIVU1CVFJBQ0s6IHBvcyA9IEhJV09SRCh3UGFyYW0pOwlicmVhazsKICAgICAgICAgICAgZGVmYXVsdDogCQkJCQlicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAocG9zIDwgMCkgcG9zID0gMDsKICAgICAgICAgICAgaWYgKHBvcyA+IGRhdGEtPmN1cmNmZy5zYl93aWR0aCAtIGRhdGEtPmN1cmNmZy53aW5fd2lkdGgpCiAgICAgICAgICAgICAgICBwb3MgPSBkYXRhLT5jdXJjZmcuc2Jfd2lkdGggLSBkYXRhLT5jdXJjZmcud2luX3dpZHRoOwogICAgICAgICAgICBpZiAocG9zICE9IGRhdGEtPmN1cmNmZy53aW5fcG9zLlgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFNjcm9sbFdpbmRvdyhoV25kLCAoZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWCAtIHBvcykgKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMKTsKICAgICAgICAgICAgICAgIGRhdGEtPmN1cmNmZy53aW5fcG9zLlggPSBwb3M7CiAgICAgICAgICAgICAgICBTZXRTY3JvbGxQb3MoaFduZCwgU0JfSE9SWiwgcG9zLCBUUlVFKTsKICAgICAgICAgICAgICAgIFVwZGF0ZVdpbmRvdyhoV25kKTsKICAgICAgICAgICAgICAgIFdDVVNFUl9Qb3NDdXJzb3IoZGF0YSk7CiAgICAgICAgICAgICAgICBXSU5FQ09OX05vdGlmeVdpbmRvd0NoYW5nZShkYXRhKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCWJyZWFrOwogICAgY2FzZSBXTV9WU0NST0xMOgogICAgICAgIHsKCSAgICBpbnQJcG9zID0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWTsKCgkgICAgc3dpdGNoIChMT1dPUkQod1BhcmFtKSkKCSAgICB7CiAgICAgICAgICAgIGNhc2UgU0JfUEFHRVVQOiAJcG9zIC09IDg7IAkJYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU0JfUEFHRURPV046IAlwb3MgKz0gODsgCQlicmVhazsKICAgICAgICAgICAgY2FzZSBTQl9MSU5FVVA6IAlwb3MtLTsJCQlicmVhazsKCSAgICBjYXNlIFNCX0xJTkVET1dOOiAJcG9zKys7CSAJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX1RIVU1CVFJBQ0s6IHBvcyA9IEhJV09SRCh3UGFyYW0pOwlicmVhazsKICAgICAgICAgICAgZGVmYXVsdDogCQkJCQlicmVhazsKCSAgICB9CgkgICAgaWYgKHBvcyA8IDApIHBvcyA9IDA7CgkgICAgaWYgKHBvcyA+IGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgLSBkYXRhLT5jdXJjZmcud2luX2hlaWdodCkKICAgICAgICAgICAgICAgIHBvcyA9IGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgLSBkYXRhLT5jdXJjZmcud2luX2hlaWdodDsKCSAgICBpZiAocG9zICE9IGRhdGEtPmN1cmNmZy53aW5fcG9zLlkpCgkgICAgewoJCVNjcm9sbFdpbmRvdyhoV25kLCAwLCAoZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSAtIHBvcykgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCk7CgkJZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSA9IHBvczsKCQlTZXRTY3JvbGxQb3MoaFduZCwgU0JfVkVSVCwgcG9zLCBUUlVFKTsKCQlVcGRhdGVXaW5kb3coaFduZCk7CgkJV0NVU0VSX1Bvc0N1cnNvcihkYXRhKTsKCQlXSU5FQ09OX05vdGlmeVdpbmRvd0NoYW5nZShkYXRhKTsKCSAgICB9CgogICAgICAgIH0KICAgIGNhc2UgV01fU1lTQ09NTUFORDoKCXN3aXRjaCAod1BhcmFtKQoJewoJY2FzZSBJRFNfREVGQVVMVDoKCSAgICBXQ1VTRVJfR2V0UHJvcGVydGllcyhkYXRhLCBGQUxTRSk7CgkgICAgYnJlYWs7CgljYXNlIElEU19QUk9QRVJUSUVTOgoJICAgIFdDVVNFUl9HZXRQcm9wZXJ0aWVzKGRhdGEsIFRSVUUpOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICByZXR1cm4gRGVmV2luZG93UHJvYyhoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7Cgl9CglicmVhazsKICAgIGNhc2UgV01fQ09NTUFORDoKCXN3aXRjaCAod1BhcmFtKQoJewoJY2FzZSBJRFNfREVGQVVMVDoKCSAgICBXQ1VTRVJfR2V0UHJvcGVydGllcyhkYXRhLCBGQUxTRSk7CgkgICAgYnJlYWs7CgljYXNlIElEU19QUk9QRVJUSUVTOgoJICAgIFdDVVNFUl9HZXRQcm9wZXJ0aWVzKGRhdGEsIFRSVUUpOwoJICAgIGJyZWFrOwoJY2FzZSBJRFNfTUFSSzoKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlggPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWSA9IDA7CiAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5YID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlkgPSAwOwogICAgICAgICAgICBXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIDApOwogICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID0gVFJVRTsKCSAgICBicmVhazsKCWNhc2UgSURTX0NPUFk6CiAgICAgICAgICAgIGlmIChQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID0gRkFMU0U7CiAgICAgICAgICAgICAgICBXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIDApOwogICAgICAgICAgICAgICAgV0NVU0VSX0NvcHlTZWxlY3Rpb25Ub0NsaXBib2FyZChkYXRhKTsKICAgICAgICAgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBJRFNfUEFTVEU6CgkgICAgV0NVU0VSX1Bhc3RlRnJvbUNsaXBib2FyZChkYXRhKTsKCSAgICBicmVhazsKCWNhc2UgSURTX1NFTEVDVEFMTDoKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlggPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWSA9IDA7CiAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5YID0gKGRhdGEtPmN1cmNmZy5zYl93aWR0aCAtIDEpICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGg7CiAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5ZID0gKGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgLSAxKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKICAgICAgICAgICAgV0NVU0VSX1NldFNlbGVjdGlvbihkYXRhLCAwKTsKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiA9IFRSVUU7CgkgICAgYnJlYWs7CgljYXNlIElEU19TQ1JPTEw6CgljYXNlIElEU19TRUFSQ0g6CgkgICAgV0lORV9GSVhNRSgiVW5oYW5kbGVkIHlldCBjb21tYW5kOiAlbHhcbiIsIHdQYXJhbSk7CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIHJldHVybiBEZWZXaW5kb3dQcm9jKGhXbmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKCX0KCWJyZWFrOwogICAgY2FzZSBXTV9JTklUTUVOVVBPUFVQOgoJaWYgKCFISVdPUkQobFBhcmFtKSkJcmV0dXJuIERlZldpbmRvd1Byb2MoaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwoJV0NVU0VSX1NldE1lbnVEZXRhaWxzKGRhdGEsIEdldFN5c3RlbU1lbnUoZGF0YS0+aFduZCwgRkFMU0UpKTsKCWJyZWFrOwogICAgZGVmYXVsdDoKCXJldHVybiBEZWZXaW5kb3dQcm9jKGhXbmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKICAgIH0KICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfRGVsZXRlQmFja2VuZAogKgogKgogKi8Kc3RhdGljIHZvaWQgV0NVU0VSX0RlbGV0ZUJhY2tlbmQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIGlmICghUFJJVkFURShkYXRhKSkgcmV0dXJuOwogICAgaWYgKFBSSVZBVEUoZGF0YSktPmhNZW1EQykJCURlbGV0ZURDKFBSSVZBVEUoZGF0YSktPmhNZW1EQyk7CiAgICBpZiAoZGF0YS0+aFduZCkJCSAgICAgICAgRGVzdHJveVdpbmRvdyhkYXRhLT5oV25kKTsKICAgIGlmIChQUklWQVRFKGRhdGEpLT5oRm9udCkJCURlbGV0ZU9iamVjdChQUklWQVRFKGRhdGEpLT5oRm9udCk7CiAgICBpZiAoUFJJVkFURShkYXRhKS0+Y3Vyc29yX2JpdG1hcCkJRGVsZXRlT2JqZWN0KFBSSVZBVEUoZGF0YSktPmN1cnNvcl9iaXRtYXApOwogICAgaWYgKFBSSVZBVEUoZGF0YSktPmhCaXRtYXApCQlEZWxldGVPYmplY3QoUFJJVkFURShkYXRhKS0+aEJpdG1hcCk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBQUklWQVRFKGRhdGEpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX01haW5Mb29wCiAqCiAqCiAqLwpzdGF0aWMgaW50IFdDVVNFUl9NYWluTG9vcChzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgTVNHCQltc2c7CgogICAgU2hvd1dpbmRvdyhkYXRhLT5oV25kLCBkYXRhLT5uQ21kU2hvdyk7CiAgICBmb3IgKDs7KQogICAgewoJc3dpdGNoIChNc2dXYWl0Rm9yTXVsdGlwbGVPYmplY3RzKDEsICZkYXRhLT5oU3luY2hybywgRkFMU0UsIElORklOSVRFLCBRU19BTExJTlBVVCkpCgl7CgljYXNlIFdBSVRfT0JKRUNUXzA6CgkgICAgaWYgKCFXSU5FQ09OX0dyYWJDaGFuZ2VzKGRhdGEpICYmIGRhdGEtPmN1cmNmZy5leGl0X29uX2RpZSkKICAgICAgICAgICAgICAgIFBvc3RRdWl0TWVzc2FnZSgwKTsKCSAgICBicmVhazsKCWNhc2UgV0FJVF9PQkpFQ1RfMCsxOgoJICAgIC8qIG5lZWQgdG8gdXNlIFBlZWtNZXNzYWdlIGxvb3AgaW5zdGVhZCBvZiBzaW1wbGUgR2V0TWVzc2FnZToKCSAgICAgKiBtdWx0aXBsZSBtZXNzYWdlcyBtaWdodCBoYXZlIGFycml2ZWQgaW4gYmV0d2VlbiwKCSAgICAgKiBzbyBHZXRNZXNzYWdlIHdvdWxkIGxlYWQgdG8gZGVsYXllZCBwcm9jZXNzaW5nICovCgkgICAgd2hpbGUgKFBlZWtNZXNzYWdlKCZtc2csIDAsIDAsIDAsIFBNX1JFTU9WRSkpCgkgICAgewogICAgICAgICAgICAgICAgaWYgKG1zZy5tZXNzYWdlID09IFdNX1FVSVQpIHJldHVybiAwOwogICAgICAgICAgICAgICAgV0lORV9UUkFDRSgiZGlzcGF0Y2hpbmcgbXNnICUwNHhcbiIsIG1zZy5tZXNzYWdlKTsKICAgICAgICAgICAgICAgIERpc3BhdGNoTWVzc2FnZSgmbXNnKTsKCSAgICB9CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIFdJTkVfRVJSKCJnb3QgcGJcbiIpOwoJICAgIC8qIGVyciAqLwoJICAgIGJyZWFrOwoJfQogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfSW5pdEJhY2tlbmQKICoKICogSW5pdGlhbGlzYXRpb24gcGFydCBJSTogY3JlYXRpb24gb2Ygd2luZG93LgogKgogKi8KZW51bSBpbml0X3JldHVybiBXQ1VTRVJfSW5pdEJhY2tlbmQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiB3Q2xhc3NOYW1lW10gPSB7J1cnLCdpJywnbicsJ2UnLCdDJywnbycsJ24nLCdzJywnbycsJ2wnLCdlJywnQycsJ2wnLCdhJywncycsJ3MnLDB9OwoKICAgIFdORENMQVNTCQl3bmRjbGFzczsKICAgIENIQVJTRVRJTkZPICAgICAgICAgY2k7CiAgICAKICAgIGlmICghVHJhbnNsYXRlQ2hhcnNldEluZm8oKERXT1JEICopKElOVF9QVFIpR2V0QUNQKCksICZjaSwgVENJX1NSQ0NPREVQQUdFKSkKICAgICAgICByZXR1cm4gaW5pdF9mYWlsZWQ7CiAgICBnX3VpRGVmYXVsdENoYXJzZXQgPSBjaS5jaUNoYXJzZXQ7CiAgICBXSU5FX1RSQUNFXyh3Y19mb250KSgiQ29kZSBwYWdlICVkID0+IERlZmF1bHQgY2hhcnNldDogJWRcbiIsIEdldEFDUCgpLCBnX3VpRGVmYXVsdENoYXJzZXQpOwoKICAgIGRhdGEtPnByaXZhdGUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKHN0cnVjdCBpbm5lcl9kYXRhX3VzZXIpKTsKICAgIGlmICghZGF0YS0+cHJpdmF0ZSkgcmV0dXJuIGluaXRfZmFpbGVkOwoKICAgIGRhdGEtPmZuTWFpbkxvb3AgPSBXQ1VTRVJfTWFpbkxvb3A7CiAgICBkYXRhLT5mblBvc0N1cnNvciA9IFdDVVNFUl9Qb3NDdXJzb3I7CiAgICBkYXRhLT5mblNoYXBlQ3Vyc29yID0gV0NVU0VSX1NoYXBlQ3Vyc29yOwogICAgZGF0YS0+Zm5Db21wdXRlUG9zaXRpb25zID0gV0NVU0VSX0NvbXB1dGVQb3NpdGlvbnM7CiAgICBkYXRhLT5mblJlZnJlc2ggPSBXQ1VTRVJfUmVmcmVzaDsKICAgIGRhdGEtPmZuUmVzaXplU2NyZWVuQnVmZmVyID0gV0NVU0VSX1Jlc2l6ZVNjcmVlbkJ1ZmZlcjsKICAgIGRhdGEtPmZuU2V0VGl0bGUgPSBXQ1VTRVJfU2V0VGl0bGU7CiAgICBkYXRhLT5mblNldEZvbnQgPSBXQ1VTRVJfU2V0Rm9udFBtdDsKICAgIGRhdGEtPmZuU2Nyb2xsID0gV0NVU0VSX1Njcm9sbDsKICAgIGRhdGEtPmZuRGVsZXRlQmFja2VuZCA9IFdDVVNFUl9EZWxldGVCYWNrZW5kOwoKICAgIHduZGNsYXNzLnN0eWxlICAgICAgICAgPSBDU19EQkxDTEtTOwogICAgd25kY2xhc3MubHBmblduZFByb2MgICA9IFdDVVNFUl9Qcm9jOwogICAgd25kY2xhc3MuY2JDbHNFeHRyYSAgICA9IDA7CiAgICB3bmRjbGFzcy5jYlduZEV4dHJhICAgID0gc2l6ZW9mKERXT1JEX1BUUik7CiAgICB3bmRjbGFzcy5oSW5zdGFuY2UgICAgID0gR2V0TW9kdWxlSGFuZGxlKE5VTEwpOwogICAgd25kY2xhc3MuaEljb24gICAgICAgICA9IExvYWRJY29uKDAsIElESV9XSU5MT0dPKTsKICAgIHduZGNsYXNzLmhDdXJzb3IgICAgICAgPSBMb2FkQ3Vyc29yKDAsIElEQ19BUlJPVyk7CiAgICB3bmRjbGFzcy5oYnJCYWNrZ3JvdW5kID0gR2V0U3RvY2tPYmplY3QoQkxBQ0tfQlJVU0gpOwogICAgd25kY2xhc3MubHBzek1lbnVOYW1lICA9IE5VTEw7CiAgICB3bmRjbGFzcy5scHN6Q2xhc3NOYW1lID0gd0NsYXNzTmFtZTsKCiAgICBSZWdpc3RlckNsYXNzKCZ3bmRjbGFzcyk7CgogICAgQ3JlYXRlV2luZG93KHduZGNsYXNzLmxwc3pDbGFzc05hbWUsIE5VTEwsCgkJIFdTX09WRVJMQVBQRUR8V1NfQ0FQVElPTnxXU19TWVNNRU5VfFdTX1RISUNLRlJBTUV8V1NfTUlOSU1JWkVCT1h8V1NfSFNDUk9MTHxXU19WU0NST0xMLAoJCSBDV19VU0VERUZBVUxULCBDV19VU0VERUZBVUxULCAwLCAwLCAwLCAwLCB3bmRjbGFzcy5oSW5zdGFuY2UsIGRhdGEpOwogICAgaWYgKCFkYXRhLT5oV25kKSByZXR1cm4gaW5pdF9ub3Rfc3VwcG9ydGVkOwoKICAgIHJldHVybiBpbml0X3N1Y2Nlc3M7Cn0K