LyoKICogYSBHVUkgYXBwbGljYXRpb24gZm9yIGRpc3BsYXlpbmcgYSBjb25zb2xlCiAqCVVTRVIzMiBiYWNrIGVuZAogKiBDb3B5cmlnaHQgMjAwMSBFcmljIFBvdWVjaAogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSAid2luZWNvbl91c2VyLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwod2luZWNvbnNvbGUpOwpXSU5FX0RFQ0xBUkVfREVCVUdfQ0hBTk5FTCh3Y19mb250KTsKCi8qIG1hcHBpbmcgY29uc29sZSBjb2xvcnMgdG8gUkdCIHZhbHVlcyAqLwpDT0xPUlJFRglXQ1VTRVJfQ29sb3JNYXBbMTZdID0KewogICAgUkdCKDB4MDAsIDB4MDAsIDB4MDApLCBSR0IoMHgwMCwgMHgwMCwgMHg4MCksIFJHQigweDAwLCAweDgwLCAweDAwKSwgUkdCKDB4MDAsIDB4ODAsIDB4ODApLAogICAgUkdCKDB4ODAsIDB4MDAsIDB4MDApLCBSR0IoMHg4MCwgMHgwMCwgMHg4MCksIFJHQigweDgwLCAweDgwLCAweDAwKSwgUkdCKDB4ODAsIDB4ODAsIDB4ODApLAogICAgUkdCKDB4QzAsIDB4QzAsIDB4QzApLCBSR0IoMHgwMCwgMHgwMCwgMHhGRiksIFJHQigweDAwLCAweEZGLCAweDAwKSwgUkdCKDB4MDAsIDB4RkYsIDB4RkYpLAogICAgUkdCKDB4RkYsIDB4MDAsIDB4MDApLCBSR0IoMHhGRiwgMHgwMCwgMHhGRiksIFJHQigweEZGLCAweEZGLCAweDAwKSwgUkdCKDB4RkYsIDB4RkYsIDB4RkYpLAp9OwoKc3RhdGljIEJPT0wgV0NVU0VSX1NldEZvbnQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIGNvbnN0IExPR0ZPTlQqIGZvbnQpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0ZpbGxNZW1EQwogKgogKiBGaWxscyB0aGUgTWVtIERDIHdpdGggY3VycmVudCBjZWxscyB2YWx1ZXMKICovCnN0YXRpYyB2b2lkIFdDVVNFUl9GaWxsTWVtREMoY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIGludCB1cGRfdHAsIGludCB1cGRfYm0pCnsKICAgIHVuc2lnbmVkCQlpLCBqLCBrOwogICAgQ0hBUl9JTkZPKgkJY2VsbDsKICAgIEhGT05UCQloT2xkRm9udDsKICAgIFdPUkQJCWF0dHI7CiAgICBXQ0hBUioJCWxpbmU7CgogICAgLyogbm8gZm9udCBoYXMgYmVlbiBzZXQgdXAgeWV0LCBkb24ndCB3b3JyeSBhYm91dCBmaWxsaW5nIHRoZSBiaXRtYXAsCiAgICAgKiB3ZSdsbCBkbyBpdCBvbmNlIGEgZm9udCBpcyBjaG9zZW4KICAgICAqLwogICAgaWYgKCFQUklWQVRFKGRhdGEpLT5oRm9udCkgcmV0dXJuOwoKICAgIC8qIEZJWE1FOiBjb3VsZCBzZXQgdXAgYSBtZWNoYW5pc20gdG8gcmV1c2UgdGhlIGxpbmUgYmV0d2VlbiBkaWZmZXJlbnQKICAgICAqIGNhbGxzIHRvIHRoaXMgZnVuY3Rpb24KICAgICAqLwogICAgaWYgKCEobGluZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBkYXRhLT5jdXJjZmcuc2Jfd2lkdGggKiBzaXplb2YoV0NIQVIpKSkpCiAgICAgICAgV0lORUNPTl9GYXRhbCgiT09NXG4iKTsKCiAgICBoT2xkRm9udCA9IFNlbGVjdE9iamVjdChQUklWQVRFKGRhdGEpLT5oTWVtREMsIFBSSVZBVEUoZGF0YSktPmhGb250KTsKICAgIGZvciAoaiA9IHVwZF90cDsgaiA8PSB1cGRfYm07IGorKykKICAgIHsKCWNlbGwgPSAmZGF0YS0+Y2VsbHNbaiAqIGRhdGEtPmN1cmNmZy5zYl93aWR0aF07Cglmb3IgKGkgPSAwOyBpIDwgZGF0YS0+Y3VyY2ZnLnNiX3dpZHRoOyBpKyspCgl7CgkgICAgYXR0ciA9IGNlbGxbaV0uQXR0cmlidXRlczsKCSAgICBTZXRCa0NvbG9yKFBSSVZBVEUoZGF0YSktPmhNZW1EQywgV0NVU0VSX0NvbG9yTWFwWyhhdHRyPj40KSYweDBGXSk7CgkgICAgU2V0VGV4dENvbG9yKFBSSVZBVEUoZGF0YSktPmhNZW1EQywgV0NVU0VSX0NvbG9yTWFwW2F0dHImMHgwRl0pOwoJICAgIGZvciAoayA9IGk7IGsgPCBkYXRhLT5jdXJjZmcuc2Jfd2lkdGggJiYgY2VsbFtrXS5BdHRyaWJ1dGVzID09IGF0dHI7IGsrKykKCSAgICB7CgkJbGluZVtrIC0gaV0gPSBjZWxsW2tdLkNoYXIuVW5pY29kZUNoYXI7CgkgICAgfQoJICAgIFRleHRPdXQoUFJJVkFURShkYXRhKS0+aE1lbURDLCBpICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGgsIGogKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQsCgkJICAgIGxpbmUsIGsgLSBpKTsKCSAgICBpID0gayAtIDE7Cgl9CiAgICB9CiAgICBTZWxlY3RPYmplY3QoUFJJVkFURShkYXRhKS0+aE1lbURDLCBoT2xkRm9udCk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBsaW5lKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX05ld0JpdG1hcAogKgogKiBFaXRoZXIgdGhlIGZvbnQgZ2VvbWV0cnkgb3IgdGhlIHNiIGdlb21ldHJ5IGhhcyBjaGFuZ2VkLiB3ZSBuZWVkCiAqIHRvIHJlY3JlYXRlIHRoZSBiaXRtYXAgZ2VvbWV0cnkuCiAqLwpzdGF0aWMgdm9pZCBXQ1VTRVJfTmV3Qml0bWFwKHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBIREMgICAgICAgICBoREM7CiAgICBIQklUTUFQCWhuZXcsIGhvbGQ7CgogICAgaWYgKCFkYXRhLT5jdXJjZmcuc2Jfd2lkdGggfHwgIWRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgfHwKICAgICAgICAhUFJJVkFURShkYXRhKS0+aEZvbnQgfHwgIShoREMgPSBHZXREQyhQUklWQVRFKGRhdGEpLT5oV25kKSkpCiAgICAgICAgcmV0dXJuOwogICAgaG5ldyA9IENyZWF0ZUNvbXBhdGlibGVCaXRtYXAoaERDLAoJCQkJICBkYXRhLT5jdXJjZmcuc2Jfd2lkdGggICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGgsCgkJCQkgIGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQpOwogICAgUmVsZWFzZURDKFBSSVZBVEUoZGF0YSktPmhXbmQsIGhEQyk7CiAgICBob2xkID0gU2VsZWN0T2JqZWN0KFBSSVZBVEUoZGF0YSktPmhNZW1EQywgaG5ldyk7CgogICAgaWYgKFBSSVZBVEUoZGF0YSktPmhCaXRtYXApCiAgICB7CglpZiAoaG9sZCA9PSBQUklWQVRFKGRhdGEpLT5oQml0bWFwKQoJICAgIERlbGV0ZU9iamVjdChQUklWQVRFKGRhdGEpLT5oQml0bWFwKTsKCWVsc2UKCSAgICBXSU5FX0ZJWE1FKCJsZWFrXG4iKTsKICAgIH0KICAgIFBSSVZBVEUoZGF0YSktPmhCaXRtYXAgPSBobmV3OwogICAgV0NVU0VSX0ZpbGxNZW1EQyhkYXRhLCAwLCBkYXRhLT5jdXJjZmcuc2JfaGVpZ2h0IC0gMSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9SZXNpemVTY3JlZW5CdWZmZXIKICoKICoKICovCnN0YXRpYyB2b2lkIFdDVVNFUl9SZXNpemVTY3JlZW5CdWZmZXIoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIFdDVVNFUl9OZXdCaXRtYXAoZGF0YSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9Qb3NDdXJzb3IKICoKICogU2V0IGEgbmV3IHBvc2l0aW9uIGZvciB0aGUgY3Vyc29yCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfUG9zQ3Vyc29yKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBpZiAoUFJJVkFURShkYXRhKS0+aFduZCAhPSBHZXRGb2N1cygpIHx8ICFkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUpIHJldHVybjsKCiAgICBTZXRDYXJldFBvcygoZGF0YS0+Y3Vyc29yLlggLSBkYXRhLT5jdXJjZmcud2luX3Bvcy5YKSAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoLAoJCShkYXRhLT5jdXJzb3IuWSAtIGRhdGEtPmN1cmNmZy53aW5fcG9zLlkpICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0KTsKICAgIFNob3dDYXJldChQUklWQVRFKGRhdGEpLT5oV25kKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1NoYXBlQ3Vyc29yCiAqCiAqIFNldHMgYSBuZXcgc2hhcGUgZm9yIHRoZSBjdXJzb3IKICovCnN0YXRpYyB2b2lkCVdDVVNFUl9TaGFwZUN1cnNvcihzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgaW50IHNpemUsIGludCB2aXMsIEJPT0wgZm9yY2UpCnsKICAgIGlmIChmb3JjZSB8fCBzaXplICE9IGRhdGEtPmN1cmNmZy5jdXJzb3Jfc2l6ZSkKICAgIHsKCWlmIChkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUgJiYgUFJJVkFURShkYXRhKS0+aFduZCA9PSBHZXRGb2N1cygpKSBEZXN0cm95Q2FyZXQoKTsKCWlmIChQUklWQVRFKGRhdGEpLT5jdXJzb3JfYml0bWFwKSBEZWxldGVPYmplY3QoUFJJVkFURShkYXRhKS0+Y3Vyc29yX2JpdG1hcCk7CglQUklWQVRFKGRhdGEpLT5jdXJzb3JfYml0bWFwID0gTlVMTDsKCWlmIChzaXplICE9IDEwMCkKCXsKCSAgICBpbnQJCXcxNmI7IC8qIG51bWJlciBvZiBieXRlcyBwZXIgcm93LCBhbGlnbmVkIG9uIHdvcmQgc2l6ZSAqLwoJICAgIEJZVEUqCXB0cjsKCSAgICBpbnQJCWksIGosIG5ibDsKCgkgICAgdzE2YiA9ICgoZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGggKyAxNSkgJiB+MTUpIC8gODsKCSAgICBwdHIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgdzE2YiAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCk7CgkgICAgaWYgKCFwdHIpIFdJTkVDT05fRmF0YWwoIk9PTSIpOwoJICAgIG5ibCA9IG1heCgoZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0ICogc2l6ZSkgLyAxMDAsIDEpOwoJICAgIGZvciAoaiA9IGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCAtIG5ibDsgaiA8IGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsgaisrKQoJICAgIHsKCQlmb3IgKGkgPSAwOyBpIDwgZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGg7IGkrKykKCQl7CgkJICAgIHB0clt3MTZiICogaiArIChpIC8gOCldIHw9IDB4ODAgPj4gKGkgJiA3KTsKCQl9CgkgICAgfQoJICAgIFBSSVZBVEUoZGF0YSktPmN1cnNvcl9iaXRtYXAgPSBDcmVhdGVCaXRtYXAoZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0LCAxLCAxLCBwdHIpOwoJICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHB0cik7Cgl9CglkYXRhLT5jdXJjZmcuY3Vyc29yX3NpemUgPSBzaXplOwoJZGF0YS0+Y3VyY2ZnLmN1cnNvcl92aXNpYmxlID0gLTE7CiAgICB9CgogICAgdmlzID0gKHZpcykgPyBUUlVFIDogRkFMU0U7CiAgICBpZiAoZm9yY2UgfHwgdmlzICE9IGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKICAgIHsKCWRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSA9IHZpczsKCWlmIChQUklWQVRFKGRhdGEpLT5oV25kID09IEdldEZvY3VzKCkpCgl7CgkgICAgaWYgKHZpcykKCSAgICB7CgkJQ3JlYXRlQ2FyZXQoUFJJVkFURShkYXRhKS0+aFduZCwgUFJJVkFURShkYXRhKS0+Y3Vyc29yX2JpdG1hcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoLCBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQpOwoJCVdDVVNFUl9Qb3NDdXJzb3IoZGF0YSk7CgkgICAgfQoJICAgIGVsc2UKCSAgICB7CgkJRGVzdHJveUNhcmV0KCk7CgkgICAgfQoJfQogICAgfQogICAgV0lORUNPTl9EdW1wQ29uZmlnKCJjcnNyIiwgJmRhdGEtPmN1cmNmZyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9Db21wdXRlUG9zaXRpb25zCiAqCiAqIFJlY29tcHV0ZXMgYWxsIHRoZSBjb21wb25lbnRzIChtYWlubHkgc2Nyb2xsIGJhcnMpIHBvc2l0aW9ucwogKi8Kc3RhdGljIHZvaWQJV0NVU0VSX0NvbXB1dGVQb3NpdGlvbnMoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIFJFQ1QJCXI7CiAgICBpbnQJCQlkeCwgZHk7CgogICAgLyogY29tcHV0ZSB3aW5kb3cgc2l6ZSBmcm9tIGRlc2lyZWQgY2xpZW50IHNpemUgKi8KICAgIHIubGVmdCA9IHIudG9wID0gMDsKICAgIHIucmlnaHQgPSBkYXRhLT5jdXJjZmcud2luX3dpZHRoICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGg7CiAgICByLmJvdHRvbSA9IGRhdGEtPmN1cmNmZy53aW5faGVpZ2h0ICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0OwoKICAgIGlmIChJc1JlY3RFbXB0eSgmcikpIHJldHVybjsKCiAgICBBZGp1c3RXaW5kb3dSZWN0KCZyLCBHZXRXaW5kb3dMb25nKFBSSVZBVEUoZGF0YSktPmhXbmQsIEdXTF9TVFlMRSksIEZBTFNFKTsKCiAgICBkeCA9IGR5ID0gMDsKICAgIGlmIChkYXRhLT5jdXJjZmcuc2Jfd2lkdGggPiBkYXRhLT5jdXJjZmcud2luX3dpZHRoKQogICAgewoJZHkgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZSFNDUk9MTCk7CglTZXRTY3JvbGxSYW5nZShQUklWQVRFKGRhdGEpLT5oV25kLCBTQl9IT1JaLCAwLAogICAgICAgICAgICAgICAgICAgICAgIGRhdGEtPmN1cmNmZy5zYl93aWR0aCAtIGRhdGEtPmN1cmNmZy53aW5fd2lkdGgsIEZBTFNFKTsKCVNldFNjcm9sbFBvcyhQUklWQVRFKGRhdGEpLT5oV25kLCBTQl9IT1JaLCAwLCBGQUxTRSk7IC8qIEZJWE1FICovCglTaG93U2Nyb2xsQmFyKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX0hPUlosIFRSVUUpOwogICAgfQogICAgZWxzZQogICAgewoJU2hvd1Njcm9sbEJhcihQUklWQVRFKGRhdGEpLT5oV25kLCBTQl9IT1JaLCBGQUxTRSk7CiAgICB9CgogICAgaWYgKGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgPiBkYXRhLT5jdXJjZmcud2luX2hlaWdodCkKICAgIHsKCWR4ID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFZTQ1JPTEwpOwoJU2V0U2Nyb2xsUmFuZ2UoUFJJVkFURShkYXRhKS0+aFduZCwgU0JfVkVSVCwgMCwKICAgICAgICAgICAgICAgICAgICAgICBkYXRhLT5jdXJjZmcuc2JfaGVpZ2h0IC0gZGF0YS0+Y3VyY2ZnLndpbl9oZWlnaHQsIEZBTFNFKTsKCVNldFNjcm9sbFBvcyhQUklWQVRFKGRhdGEpLT5oV25kLCBTQl9WRVJULCAwLCBGQUxTRSk7IC8qIEZJWE1FICovCglTaG93U2Nyb2xsQmFyKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX1ZFUlQsIFRSVUUpOwogICAgfQogICAgZWxzZQogICAgewoJU2hvd1Njcm9sbEJhcihQUklWQVRFKGRhdGEpLT5oV25kLCBTQl9WRVJULCBGQUxTRSk7CiAgICB9CgogICAgU2V0V2luZG93UG9zKFBSSVZBVEUoZGF0YSktPmhXbmQsIDAsIDAsIDAsIHIucmlnaHQgLSByLmxlZnQgKyBkeCwgci5ib3R0b20gLSByLnRvcCArIGR5LAoJCSBTV1BfTk9NT1ZFfFNXUF9OT1pPUkRFUik7CiAgICBXQ1VTRVJfU2hhcGVDdXJzb3IoZGF0YSwgZGF0YS0+Y3VyY2ZnLmN1cnNvcl9zaXplLCBkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUsIFRSVUUpOwogICAgV0NVU0VSX1Bvc0N1cnNvcihkYXRhKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1NldFRpdGxlCiAqCiAqIFNldHMgdGhlIHRpdGxlIHRvIHRoZSB3aW5lIGNvbnNvbGUKICovCnN0YXRpYyB2b2lkCVdDVVNFUl9TZXRUaXRsZShjb25zdCBzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgV0NIQVIJYnVmZmVyWzI1Nl07CgogICAgaWYgKFdJTkVDT05fR2V0Q29uc29sZVRpdGxlKGRhdGEtPmhDb25JbiwgYnVmZmVyLCBzaXplb2YoYnVmZmVyKSkpCglTZXRXaW5kb3dUZXh0KFBSSVZBVEUoZGF0YSktPmhXbmQsIGJ1ZmZlcik7Cn0KCnZvaWQgV0NVU0VSX0R1bXBMb2dGb250KGNvbnN0IGNoYXIqIHBmeCwgY29uc3QgTE9HRk9OVCogbGYsIERXT1JEIGZ0KQp7CiAgICBXSU5FX1RSQUNFXyh3Y19mb250KSgiJXMgJXMlcyVzJXNcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdGxmLmxmSGVpZ2h0PSVsZCBsZi5sZldpZHRoPSVsZCBsZi5sZkVzY2FwZW1lbnQ9JWxkIGxmLmxmT3JpZW50YXRpb249JWxkXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAiXHRsZi5sZldlaWdodD0lbGQgbGYubGZJdGFsaWM9JXUgbGYubGZVbmRlcmxpbmU9JXUgbGYubGZTdHJpa2VPdXQ9JXVcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdGxmLmxmQ2hhclNldD0ldSBsZi5sZk91dFByZWNpc2lvbj0ldSBsZi5sZkNsaXBQcmVjaXNpb249JXUgbGYubGZRdWFsaXR5PSV1XG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAiXHRsZi0+bGZQaXRjaEFuZEZhbWlseT0ldSBsZi5sZkZhY2VOYW1lPSVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgcGZ4LAogICAgICAgICAgICAgICAgICAgICAgICAgKGZ0ICYgUkFTVEVSX0ZPTlRUWVBFKSA/ICJyYXN0ZXIiIDogIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAoZnQgJiBUUlVFVFlQRV9GT05UVFlQRSkgPyAidHJ1ZXR5cGUiIDogIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAoKGZ0ICYgKFJBU1RFUl9GT05UVFlQRXxUUlVFVFlQRV9GT05UVFlQRSkpID09IDApID8gInZlY3RvciIgOiAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgIChmdCAmIERFVklDRV9GT05UVFlQRSkgPyAifGRldmljZSIgOiAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgIGxmLT5sZkhlaWdodCwgbGYtPmxmV2lkdGgsIGxmLT5sZkVzY2FwZW1lbnQsIGxmLT5sZk9yaWVudGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgbGYtPmxmV2VpZ2h0LCBsZi0+bGZJdGFsaWMsIGxmLT5sZlVuZGVybGluZSwgbGYtPmxmU3RyaWtlT3V0LCBsZi0+bGZDaGFyU2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgbGYtPmxmT3V0UHJlY2lzaW9uLCBsZi0+bGZDbGlwUHJlY2lzaW9uLCBsZi0+bGZRdWFsaXR5LCBsZi0+bGZQaXRjaEFuZEZhbWlseSwKICAgICAgICAgICAgICAgICAgICAgICAgIHdpbmVfZGJnc3RyX3cobGYtPmxmRmFjZU5hbWUpKTsKfQoKdm9pZCBXQ1VTRVJfRHVtcFRleHRNZXRyaWMoY29uc3QgVEVYVE1FVFJJQyogdG0sIERXT1JEIGZ0KQp7CiAgICBXSU5FX1RSQUNFXyh3Y19mb250KSgiJXMlcyVzJXNcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdHRtSGVpZ2h0PSVsZCB0bUFzY2VudD0lbGQgdG1EZXNjZW50PSVsZCB0bUludGVybmFsTGVhZGluZz0lbGQgdG1FeHRlcm5hbExlYWRpbmc9JWxkXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAiXHR0bUF2ZUNoYXJXaWR0aD0lbGQgdG1NYXhDaGFyV2lkdGg9JWxkIHRtV2VpZ2h0PSVsZCB0bU92ZXJoYW5nPSVsZFxuIgogICAgICAgICAgICAgICAgICAgICAgICAgIlx0dG1EaWdpdGl6ZWRBc3BlY3RYPSVsZCB0bURpZ2l0aXplZEFzcGVjdFk9JWxkXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAiXHR0bUZpcnN0Q2hhcj0lZCB0bUxhc3RDaGFyPSVkIHRtRGVmYXVsdENoYXI9JWQgdG1CcmVha0NoYXI9JWRcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdHRtSXRhbGljPSV1IHRtVW5kZXJsaW5lZD0ldSB0bVN0cnVja091dD0ldSB0bVBpdGNoQW5kRmFtaWx5PSV1IHRtQ2hhclNldD0ldVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgIChmdCAmIFJBU1RFUl9GT05UVFlQRSkgPyAicmFzdGVyIiA6ICIiLAogICAgICAgICAgICAgICAgICAgICAgICAgKGZ0ICYgVFJVRVRZUEVfRk9OVFRZUEUpID8gInRydWV0eXBlIiA6ICIiLAogICAgICAgICAgICAgICAgICAgICAgICAgKChmdCAmIChSQVNURVJfRk9OVFRZUEV8VFJVRVRZUEVfRk9OVFRZUEUpKSA9PSAwKSA/ICJ2ZWN0b3IiIDogIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAoZnQgJiBERVZJQ0VfRk9OVFRZUEUpID8gInxkZXZpY2UiIDogIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICB0bS0+dG1IZWlnaHQsIHRtLT50bUFzY2VudCwgdG0tPnRtRGVzY2VudCwgdG0tPnRtSW50ZXJuYWxMZWFkaW5nLCB0bS0+dG1FeHRlcm5hbExlYWRpbmcsIHRtLT50bUF2ZUNoYXJXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgIHRtLT50bU1heENoYXJXaWR0aCwgdG0tPnRtV2VpZ2h0LCB0bS0+dG1PdmVyaGFuZywgdG0tPnRtRGlnaXRpemVkQXNwZWN0WCwgdG0tPnRtRGlnaXRpemVkQXNwZWN0WSwKICAgICAgICAgICAgICAgICAgICAgICAgIHRtLT50bUZpcnN0Q2hhciwgdG0tPnRtTGFzdENoYXIsIHRtLT50bURlZmF1bHRDaGFyLCB0bS0+dG1CcmVha0NoYXIsIHRtLT50bUl0YWxpYywgdG0tPnRtVW5kZXJsaW5lZCwgdG0tPnRtU3RydWNrT3V0LAogICAgICAgICAgICAgICAgICAgICAgICAgdG0tPnRtUGl0Y2hBbmRGYW1pbHksIHRtLT50bUNoYXJTZXQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfQXJlRm9udHNFcXVhbAogKgogKgogKi8KQk9PTCBXQ1VTRVJfQXJlRm9udHNFcXVhbChjb25zdCBzdHJ1Y3QgY29uZmlnX2RhdGEqIGNvbmZpZywgY29uc3QgTE9HRk9OVCogbGYpCnsKICAgIHJldHVybiBsZi0+bGZIZWlnaHQgPT0gY29uZmlnLT5jZWxsX2hlaWdodCAmJgogICAgICAgIGxmLT5sZldlaWdodCA9PSBjb25maWctPmZvbnRfd2VpZ2h0ICYmCiAgICAgICAgIWxmLT5sZkl0YWxpYyAmJiAhbGYtPmxmVW5kZXJsaW5lICYmICFsZi0+bGZTdHJpa2VPdXQgJiYKICAgICAgICAhbHN0cmNtcChsZi0+bGZGYWNlTmFtZSwgY29uZmlnLT5mYWNlX25hbWUpOwp9CgpzdHJ1Y3QgZm9udF9jaG9vc2VyCnsKICAgIHN0cnVjdCBpbm5lcl9kYXRhKglkYXRhOwogICAgaW50CQkJZG9uZTsKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9WYWxpZGF0ZUZvbnRNZXRyaWMKICoKICogUmV0dXJucyB0cnVlIGlmIHRoZSBmb250IGRlc2NyaWJlZCBpbiB0bSBpcyB1c2FibGUgYXMgYSBmb250IGZvciB0aGUgcmVuZGVyZXIKICovCkJPT0wJV0NVU0VSX1ZhbGlkYXRlRm9udE1ldHJpYyhjb25zdCBzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgY29uc3QgVEVYVE1FVFJJQyogdG0sIERXT1JEIGZvbnRUeXBlKQp7CiAgICBCT09MICAgICAgICByZXQgPSBUUlVFOwoKICAgIGlmIChmb250VHlwZSAmIFJBU1RFUl9GT05UVFlQRSkKICAgICAgICByZXQgPSAodG0tPnRtTWF4Q2hhcldpZHRoICogZGF0YS0+Y3VyY2ZnLndpbl93aWR0aCA8IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTQ1JFRU4pICYmCiAgICAgICAgICAgICAgIHRtLT50bUhlaWdodCAqIGRhdGEtPmN1cmNmZy53aW5faGVpZ2h0IDwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNDUkVFTikpOwogICAgcmV0dXJuIHJldCAmJiAhdG0tPnRtSXRhbGljICYmICF0bS0+dG1VbmRlcmxpbmVkICYmICF0bS0+dG1TdHJ1Y2tPdXQgJiYKICAgICAgICAodG0tPnRtQ2hhclNldCA9PSBERUZBVUxUX0NIQVJTRVQgfHwgdG0tPnRtQ2hhclNldCA9PSBBTlNJX0NIQVJTRVQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfVmFsaWRhdGVGb250CiAqCiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZm9udCBmYW1pbHkgZGVzY3JpYmVkIGluIGxmIGlzIHVzYWJsZSBhcyBhIGZvbnQgZm9yIHRoZSByZW5kZXJlcgogKi8KQk9PTAlXQ1VTRVJfVmFsaWRhdGVGb250KGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBjb25zdCBMT0dGT05UKiBsZikKewogICAgcmV0dXJuIChsZi0+bGZQaXRjaEFuZEZhbWlseSAmIDMpID09IEZJWEVEX1BJVENIICYmCiAgICAgICAgLyogKGxmLT5sZlBpdGNoQW5kRmFtaWx5ICYgMHhGMCkgPT0gRkZfTU9ERVJOICYmICovCiAgICAgICAgKGxmLT5sZkNoYXJTZXQgPT0gREVGQVVMVF9DSEFSU0VUIHx8IGxmLT5sZkNoYXJTZXQgPT0gQU5TSV9DSEFSU0VUKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJZ2V0X2ZpcnN0X2ZvbnRfZW51bV8yCiAqCQlnZXRfZmlyc3RfZm9udF9lbnVtCiAqCiAqIEhlbHBlciBmdW5jdGlvbnMgdG8gZ2V0IGEgZGVjZW50IGZvbnQgZm9yIHRoZSByZW5kZXJlcgogKi8Kc3RhdGljIGludCBDQUxMQkFDSyBnZXRfZmlyc3RfZm9udF9lbnVtXzIoY29uc3QgTE9HRk9OVCogbGYsIGNvbnN0IFRFWFRNRVRSSUMqIHRtLAoJCQkJCSAgRFdPUkQgRm9udFR5cGUsIExQQVJBTSBsUGFyYW0pCnsKICAgIHN0cnVjdCBmb250X2Nob29zZXIqCWZjID0gKHN0cnVjdCBmb250X2Nob29zZXIqKWxQYXJhbTsKCiAgICBXQ1VTRVJfRHVtcFRleHRNZXRyaWModG0sIEZvbnRUeXBlKTsKICAgIGlmIChXQ1VTRVJfVmFsaWRhdGVGb250TWV0cmljKGZjLT5kYXRhLCB0bSwgRm9udFR5cGUpKQogICAgewogICAgICAgIExPR0ZPTlQgbWxmID0gKmxmOwoKICAgICAgICAvKiBVc2UgdGhlIGRlZmF1bHQgc2l6ZXMgZm9yIHRoZSBmb250ICh0aGlzIGlzIG5lZWRlZCwgZXNwZWNpYWxseSBmb3IKICAgICAgICAgKiBUcnVlVHlwZSBmb250cywgc28gdGhhdCB3ZSBnZXQgYSBkZWNlbnQgc2l6ZSwgbm90IHRoZSBtYXggc2l6ZSkKICAgICAgICAgKi8KICAgICAgICBtbGYubGZXaWR0aCAgPSBmYy0+ZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGg7CiAgICAgICAgbWxmLmxmSGVpZ2h0ID0gZmMtPmRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKICAgICAgICBpZiAoV0NVU0VSX1NldEZvbnQoZmMtPmRhdGEsICZtbGYpKQogICAgICAgIHsKICAgICAgICAgICAgc3RydWN0ICAgICAgY29uZmlnX2RhdGEgICAgIGRlZmNmZzsKCiAgICAgICAgICAgIFdDVVNFUl9EdW1wTG9nRm9udCgiSW5pdENob29zaW5nOiAiLCAmbWxmLCBGb250VHlwZSk7CiAgICAgICAgICAgIGZjLT5kb25lID0gMTsKICAgICAgICAgICAgLyogc2luY2Ugd2UndmUgbW9kaWZpZWQgdGhlIGN1cnJlbnQgY29uZmlnIHdpdGggbmV3IGZvbnQgaW5mb3JtYXRpb24sCiAgICAgICAgICAgICAqIHNldCB0aGlzIGluZm9ybWF0aW9uIGFzIHRoZSBuZXcgZGVmYXVsdC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIFdJTkVDT05fUmVnTG9hZChOVUxMLCAmZGVmY2ZnKTsKICAgICAgICAgICAgZGVmY2ZnLmNlbGxfd2lkdGggPSBmYy0+ZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGg7CiAgICAgICAgICAgIGRlZmNmZy5jZWxsX2hlaWdodCA9IGZjLT5kYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQ7CiAgICAgICAgICAgIGxzdHJjcHlXKGRlZmNmZy5mYWNlX25hbWUsIGZjLT5kYXRhLT5jdXJjZmcuZmFjZV9uYW1lKTsKICAgICAgICAgICAgLyogRm9yY2UgYWxzbyBpdHMgd3JpdGluZyBiYWNrIHRvIHRoZSByZWdpc3RyeSBzbyB0aGF0IHdlIGNhbiBnZXQgaXQKICAgICAgICAgICAgICogdGhlIG5leHQgdGltZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIFdJTkVDT05fUmVnU2F2ZSgmZGVmY2ZnKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIDE7Cn0KCnN0YXRpYyBpbnQgQ0FMTEJBQ0sgZ2V0X2ZpcnN0X2ZvbnRfZW51bShjb25zdCBMT0dGT05UKiBsZiwgY29uc3QgVEVYVE1FVFJJQyogdG0sCgkJCQkJRFdPUkQgRm9udFR5cGUsIExQQVJBTSBsUGFyYW0pCnsKICAgIHN0cnVjdCBmb250X2Nob29zZXIqCWZjID0gKHN0cnVjdCBmb250X2Nob29zZXIqKWxQYXJhbTsKCiAgICBXQ1VTRVJfRHVtcExvZ0ZvbnQoIkluaXRGYW1pbHk6ICIsIGxmLCBGb250VHlwZSk7CiAgICBpZiAoV0NVU0VSX1ZhbGlkYXRlRm9udChmYy0+ZGF0YSwgbGYpKQogICAgewoJRW51bUZvbnRGYW1pbGllcyhQUklWQVRFKGZjLT5kYXRhKS0+aE1lbURDLCBsZi0+bGZGYWNlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgIGdldF9maXJzdF9mb250X2VudW1fMiwgbFBhcmFtKTsKCXJldHVybiAhZmMtPmRvbmU7IC8qIHdlIGp1c3QgbmVlZCB0aGUgZmlyc3QgbWF0Y2hpbmcgb25lLi4uICovCiAgICB9CiAgICByZXR1cm4gMTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0NvcHlGb250CiAqCiAqIGdldCB0aGUgcmVsZXZhbnQgaW5mb3JtYXRpb24gZnJvbSB0aGUgZm9udCBkZXNjcmliZWQgaW4gbGYgYW5kIHN0b3JlIHRoZW0KICogaW4gY29uZmlnCiAqLwpIRk9OVCBXQ1VTRVJfQ29weUZvbnQoc3RydWN0IGNvbmZpZ19kYXRhKiBjb25maWcsIEhXTkQgaFduZCwgY29uc3QgTE9HRk9OVCogbGYpCnsKICAgIFRFWFRNRVRSSUMgIHRtOwogICAgSERDICAgICAgICAgaERDOwogICAgSEZPTlQgICAgICAgaEZvbnQsIGhPbGRGb250OwogICAgaW50ICAgICAgICAgdywgaSwgYnVmWzI1Nl07CgogICAgaWYgKCEoaERDID0gR2V0REMoaFduZCkpKSByZXR1cm4gTlVMTDsKICAgIGlmICghKGhGb250ID0gQ3JlYXRlRm9udEluZGlyZWN0KGxmKSkpIGdvdG8gZXJyMTsKCiAgICBoT2xkRm9udCA9IFNlbGVjdE9iamVjdChoREMsIGhGb250KTsKICAgIEdldFRleHRNZXRyaWNzKGhEQywgJnRtKTsKCiAgICAvKiBGSVhNRToKICAgICAqIHRoZSBjdXJyZW50IGZyZWV0eXBlIGVuZ2luZSAoYXQgbGVhc3QgMi4wLnggd2l0aCB4IDw9IDgpIGFuZCBpdHMgaW1wbGVtZW50YXRpb24KICAgICAqIGluIFdpbmUgZG9uJ3QgcmV0dXJuIGFkZXF1YXRlIHZhbHVlcyBmb3IgZml4ZWQgZm9udHMKICAgICAqIEluIFdpbmRvd3MsIHRob3NlIGZvbnRzIGFyZSBleHBlY3RlZCB0byByZXR1cm4gdGhlIHNhbWUgdmFsdWUgZm9yCiAgICAgKiAgLSB0aGUgYXZlcmFnZSB3aWR0aAogICAgICogIC0gdGhlIGxhcmdlc3Qgd2lkdGgKICAgICAqICAtIHRoZSB3aWR0aCBvZiBhbGwgY2hhcmFjdGVycyBpbiB0aGUgZm9udAogICAgICogVGhpcyBpc24ndCB0cnVlIGluIFdpbmUuIEFzIGEgdGVtcG9yYXJ5IHdvcmthcm91bmQsIHdlIGdldCBhcyB0aGUgd2lkdGggb2YgdGhlCiAgICAgKiBjZWxsLCB0aGUgd2lkdGggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBpbiB0aGUgZm9udCwgYWZ0ZXIgY2hlY2tpbmcgdGhhdCBhbGwKICAgICAqIGNoYXJhY3RlcnMgaW4gdGhlIGZvbnQgaGF2ZSB0aGUgc2FtZSB3aWR0aCAoSSBoZWFyIHBhcmFub+9hIGNvbWluZykKICAgICAqIHdoZW4gdGhpcyBnZXRzIGZpeGVkLCB0aGUgY29kZSBzaG91bGQgYmUgdXNpbmcgdG0udG1BdmVDaGFyV2lkdGgKICAgICAqIG9yIHRtLnRtTWF4Q2hhcldpZHRoIGFzIHRoZSBjZWxsIHdpZHRoLgogICAgICovCiAgICBHZXRDaGFyV2lkdGgzMihoREMsIHRtLnRtRmlyc3RDaGFyLCB0bS50bUZpcnN0Q2hhciwgJncpOwogICAgZm9yIChpID0gdG0udG1GaXJzdENoYXIgKyAxOyBpIDw9IHRtLnRtTGFzdENoYXI7IGkgKz0gc2l6ZW9mKGJ1ZikgLyBzaXplb2YoYnVmWzBdKSkKICAgIHsKICAgICAgICBpbnQgaiwgazsKCiAgICAgICAgayA9IG1pbih0bS50bUxhc3RDaGFyIC0gaSwgc2l6ZW9mKGJ1ZikgLyBzaXplb2YoYnVmWzBdKSAtIDEpOwogICAgICAgIEdldENoYXJXaWR0aDMyKGhEQywgaSwgaSArIGssIGJ1Zik7CiAgICAgICAgZm9yIChqID0gMDsgaiA8PSBrOyBqKyspCiAgICAgICAgewogICAgICAgICAgICBpZiAoYnVmW2pdICE9IHcpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdJTkVfV0FSTigiTm9uIHVuaWZvcm0gY2VsbCB3aWR0aDogWyVkXT0lZCBbJWRdPSVkXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlRoaXMgbWF5IGJlIGNhdXNlZCBieSBvbGQgZnJlZXR5cGUgbGlicmFyaWVzLCA+PSAyLjAuOCBpcyByZWNvbW1lbmRlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBpICsgaiwgYnVmW2pdLCB0bS50bUZpcnN0Q2hhciwgdyk7CiAgICAgICAgICAgICAgICBnb3RvIGVycjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIFNlbGVjdE9iamVjdChoREMsIGhPbGRGb250KTsKICAgIFJlbGVhc2VEQyhoV25kLCBoREMpOwoKICAgIGNvbmZpZy0+Y2VsbF93aWR0aCAgPSB3OwogICAgY29uZmlnLT5jZWxsX2hlaWdodCA9IHRtLnRtSGVpZ2h0ICsgdG0udG1FeHRlcm5hbExlYWRpbmc7CiAgICBjb25maWctPmZvbnRfd2VpZ2h0ID0gdG0udG1XZWlnaHQ7CiAgICBsc3RyY3B5KGNvbmZpZy0+ZmFjZV9uYW1lLCBsZi0+bGZGYWNlTmFtZSk7CgogICAgcmV0dXJuIGhGb250OwogZXJyOgogICAgaWYgKGhEQyAmJiBoT2xkRm9udCkgU2VsZWN0T2JqZWN0KGhEQywgaE9sZEZvbnQpOwogICAgaWYgKGhGb250KSBEZWxldGVPYmplY3QoaEZvbnQpOwogZXJyMToKICAgIGlmIChoREMpIFJlbGVhc2VEQyhoV25kLCBoREMpOwoKICAgIHJldHVybiBOVUxMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfRmlsbExvZ0ZvbnQKICoKICoKICovCnZvaWQgICAgV0NVU0VSX0ZpbGxMb2dGb250KExPR0ZPTlQqIGxmLCBjb25zdCBXQ0hBUiogbmFtZSwgVUlOVCBoZWlnaHQsIFVJTlQgd2VpZ2h0KQp7CiAgICBsZi0+bGZIZWlnaHQgICAgICAgID0gaGVpZ2h0OwogICAgbGYtPmxmV2lkdGggICAgICAgICA9IDA7CiAgICBsZi0+bGZFc2NhcGVtZW50ICAgID0gMDsKICAgIGxmLT5sZk9yaWVudGF0aW9uICAgPSAwOwogICAgbGYtPmxmV2VpZ2h0ICAgICAgICA9IHdlaWdodDsKICAgIGxmLT5sZkl0YWxpYyAgICAgICAgPSBGQUxTRTsKICAgIGxmLT5sZlVuZGVybGluZSAgICAgPSBGQUxTRTsKICAgIGxmLT5sZlN0cmlrZU91dCAgICAgPSBGQUxTRTsKICAgIGxmLT5sZkNoYXJTZXQgICAgICAgPSBERUZBVUxUX0NIQVJTRVQ7CiAgICBsZi0+bGZPdXRQcmVjaXNpb24gID0gT1VUX0RFRkFVTFRfUFJFQ0lTOwogICAgbGYtPmxmQ2xpcFByZWNpc2lvbiA9IENMSVBfREVGQVVMVF9QUkVDSVM7CiAgICBsZi0+bGZRdWFsaXR5ICAgICAgID0gREVGQVVMVF9RVUFMSVRZOwogICAgbGYtPmxmUGl0Y2hBbmRGYW1pbHkgPSBGSVhFRF9QSVRDSCB8IEZGX0RPTlRDQVJFOwogICAgbHN0cmNweShsZi0+bGZGYWNlTmFtZSwgbmFtZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9TZXRGb250CiAqCiAqIHNldHMgbG9nZm9udCBhcyB0aGUgbmV3IGZvbnQgZm9yIHRoZSBjb25zb2xlCiAqLwpCT09MCVdDVVNFUl9TZXRGb250KHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBjb25zdCBMT0dGT05UKiBsb2dmb250KQp7CiAgICBIRk9OVCAgICAgICBoRm9udDsKCiAgICBpZiAoUFJJVkFURShkYXRhKS0+aEZvbnQgIT0gMCAmJiBXQ1VTRVJfQXJlRm9udHNFcXVhbCgmZGF0YS0+Y3VyY2ZnLCBsb2dmb250KSkKICAgICAgICByZXR1cm4gVFJVRTsKCiAgICBoRm9udCA9IFdDVVNFUl9Db3B5Rm9udCgmZGF0YS0+Y3VyY2ZnLCBQUklWQVRFKGRhdGEpLT5oV25kLCBsb2dmb250KTsKICAgIGlmICghaEZvbnQpIHtXSU5FX0VSUigid3JvbmcgZm9udFxuIik7IHJldHVybiBGQUxTRTt9CgogICAgaWYgKFBSSVZBVEUoZGF0YSktPmhGb250KSBEZWxldGVPYmplY3QoUFJJVkFURShkYXRhKS0+aEZvbnQpOwogICAgUFJJVkFURShkYXRhKS0+aEZvbnQgPSBoRm9udDsKCiAgICBXQ1VTRVJfQ29tcHV0ZVBvc2l0aW9ucyhkYXRhKTsKICAgIFdDVVNFUl9OZXdCaXRtYXAoZGF0YSk7CiAgICBJbnZhbGlkYXRlUmVjdChQUklWQVRFKGRhdGEpLT5oV25kLCBOVUxMLCBGQUxTRSk7CiAgICBVcGRhdGVXaW5kb3coUFJJVkFURShkYXRhKS0+aFduZCk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9TZXRGb250UG10CiAqCiAqIFNldHMgYSBuZXcgZm9udCBmb3IgdGhlIGNvbnNvbGUuCiAqIEluIGZhY3QgYSB3cmFwcGVyIGZvciBXQ1VTRVJfU2V0Rm9udAogKi8Kc3RhdGljIHZvaWQgICAgIFdDVVNFUl9TZXRGb250UG10KHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBjb25zdCBXQ0hBUiogZm9udCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGhlaWdodCwgdW5zaWduZWQgd2VpZ2h0KQp7CiAgICBMT0dGT05UICAgICAgICAgICAgIGxmOwogICAgc3RydWN0IGZvbnRfY2hvb3NlciBmYzsKCiAgICBXSU5FX1RSQUNFXyh3Y19mb250KSgiPT4gJXMgaD0ldSB3PSV1XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgd2luZV9kYmdzdHJfd24oZm9udCwgLTEpLCBoZWlnaHQsIHdlaWdodCk7CgogICAgaWYgKGZvbnRbMF0gIT0gJ1wwJyAmJiBoZWlnaHQgIT0gMCAmJiB3ZWlnaHQgIT0gMCkKICAgIHsKICAgICAgICBXQ1VTRVJfRmlsbExvZ0ZvbnQoJmxmLCBmb250LCBoZWlnaHQsIHdlaWdodCk7CiAgICAgICAgaWYgKFdDVVNFUl9TZXRGb250KGRhdGEsICZsZikpCiAgICAgICAgewogICAgICAgICAgICBXQ1VTRVJfRHVtcExvZ0ZvbnQoIkluaXRSZXVzZXM6ICIsICZsZiwgMCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgLyogdHJ5IHRvIGZpbmQgYW4gYWNjZXB0YWJsZSBmb250ICovCiAgICBXSU5FX1dBUk4oIkNvdWxkbid0IG1hdGNoIHRoZSBmb250IGZyb20gcmVnaXN0cnkuLi4gdHJ5aW5nIHRvIGZpbmQgb25lXG4iKTsKICAgIGZjLmRhdGEgPSBkYXRhOwogICAgZmMuZG9uZSA9IDA7CiAgICBFbnVtRm9udEZhbWlsaWVzKFBSSVZBVEUoZGF0YSktPmhNZW1EQywgTlVMTCwgZ2V0X2ZpcnN0X2ZvbnRfZW51bSwgKExQQVJBTSkmZmMpOwogICAgaWYgKCFmYy5kb25lKSBXSU5FQ09OX0ZhdGFsKCJDb3VsZG4ndCBmaW5kIGEgZGVjZW50IGZvbnQsIGFib3J0aW5nXG4iKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0dldENlbGwKICoKICogR2V0IGEgY2VsbCBmcm9tIGEgcmVsYXRpdmUgY29vcmRpbmF0ZSBpbiB3aW5kb3cgKHRha2VzIGludG8KICogYWNjb3VudCB0aGUgc2Nyb2xsaW5nKQogKi8Kc3RhdGljIENPT1JECVdDVVNFUl9HZXRDZWxsKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBDT09SRAljOwoKICAgIGMuWCA9IGRhdGEtPmN1cmNmZy53aW5fcG9zLlggKyAoc2hvcnQpTE9XT1JEKGxQYXJhbSkgLyBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgIGMuWSA9IGRhdGEtPmN1cmNmZy53aW5fcG9zLlkgKyAoc2hvcnQpSElXT1JEKGxQYXJhbSkgLyBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQ7CgogICAgcmV0dXJuIGM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9HZXRTZWxlY3Rpb25SZWN0CiAqCiAqIEdldCB0aGUgc2VsZWN0aW9uIHJlY3RhbmdsZQogKi8Kc3RhdGljIHZvaWQJV0NVU0VSX0dldFNlbGVjdGlvblJlY3QoY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIExQUkVDVCByKQp7CiAgICByLT5sZWZ0ICAgPSAobWluKFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MS5YLCBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIuWCkgICAgIC0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWCkgKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgIHItPnRvcCAgICA9IChtaW4oUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlksIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5ZKSAgICAgLSBkYXRhLT5jdXJjZmcud2luX3Bvcy5ZKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKICAgIHItPnJpZ2h0ICA9IChtYXgoUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlgsIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5YKSArIDEgLSBkYXRhLT5jdXJjZmcud2luX3Bvcy5YKSAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoOwogICAgci0+Ym90dG9tID0gKG1heChQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWSwgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlkpICsgMSAtIGRhdGEtPmN1cmNmZy53aW5fcG9zLlkpICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfU2V0U2VsZWN0aW9uCiAqCiAqCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfU2V0U2VsZWN0aW9uKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBIREMgaFJlZkRDKQp7CiAgICBIREMJCWhEQzsKICAgIFJFQ1QJcjsKCiAgICBXQ1VTRVJfR2V0U2VsZWN0aW9uUmVjdChkYXRhLCAmcik7CiAgICBoREMgPSBoUmVmREMgPyBoUmVmREMgOiBHZXREQyhQUklWQVRFKGRhdGEpLT5oV25kKTsKICAgIGlmIChoREMpCiAgICB7CglpZiAoUFJJVkFURShkYXRhKS0+aFduZCA9PSBHZXRGb2N1cygpICYmIGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKCSAgICBIaWRlQ2FyZXQoUFJJVkFURShkYXRhKS0+aFduZCk7CglJbnZlcnRSZWN0KGhEQywgJnIpOwoJaWYgKGhEQyAhPSBoUmVmREMpCgkgICAgUmVsZWFzZURDKFBSSVZBVEUoZGF0YSktPmhXbmQsIGhEQyk7CglpZiAoUFJJVkFURShkYXRhKS0+aFduZCA9PSBHZXRGb2N1cygpICYmIGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKCSAgICBTaG93Q2FyZXQoUFJJVkFURShkYXRhKS0+aFduZCk7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9Nb3ZlU2VsZWN0aW9uCiAqCiAqCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfTW92ZVNlbGVjdGlvbihzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgQ09PUkQgYzEsIENPT1JEIGMyKQp7CiAgICBSRUNUCXI7CiAgICBIREMJCWhEQzsKCiAgICBpZiAoYzEuWCA8IDAgfHwgYzEuWCA+PSBkYXRhLT5jdXJjZmcuc2Jfd2lkdGggfHwKICAgICAgICBjMi5YIDwgMCB8fCBjMi5YID49IGRhdGEtPmN1cmNmZy5zYl93aWR0aCB8fAogICAgICAgIGMxLlkgPCAwIHx8IGMxLlkgPj0gZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCB8fAogICAgICAgIGMyLlkgPCAwIHx8IGMyLlkgPj0gZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCkKICAgICAgICByZXR1cm47CgogICAgV0NVU0VSX0dldFNlbGVjdGlvblJlY3QoZGF0YSwgJnIpOwogICAgaERDID0gR2V0REMoUFJJVkFURShkYXRhKS0+aFduZCk7CiAgICBpZiAoaERDKQogICAgewoJaWYgKFBSSVZBVEUoZGF0YSktPmhXbmQgPT0gR2V0Rm9jdXMoKSAmJiBkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUpCgkgICAgSGlkZUNhcmV0KFBSSVZBVEUoZGF0YSktPmhXbmQpOwoJSW52ZXJ0UmVjdChoREMsICZyKTsKICAgIH0KICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MSA9IGMxOwogICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyID0gYzI7CiAgICBpZiAoaERDKQogICAgewoJV0NVU0VSX0dldFNlbGVjdGlvblJlY3QoZGF0YSwgJnIpOwoJSW52ZXJ0UmVjdChoREMsICZyKTsKCVJlbGVhc2VEQyhQUklWQVRFKGRhdGEpLT5oV25kLCBoREMpOwoJaWYgKFBSSVZBVEUoZGF0YSktPmhXbmQgPT0gR2V0Rm9jdXMoKSAmJiBkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUpCgkgICAgU2hvd0NhcmV0KFBSSVZBVEUoZGF0YSktPmhXbmQpOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfQ29weVNlbGVjdGlvblRvQ2xpcGJvYXJkCiAqCiAqIENvcGllcyB0aGUgY3VycmVudCBzZWxlY3Rpb24gaW50byB0aGUgY2xpcGJvYXJkCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfQ29weVNlbGVjdGlvblRvQ2xpcGJvYXJkKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBIQU5ETEUJaE1lbTsKICAgIExQV1NUUglwOwogICAgdW5zaWduZWQJdywgaDsKCiAgICB3ID0gYWJzKFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MS5YIC0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlgpICsgMjsKICAgIGggPSBhYnMoUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlkgLSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIuWSkgKyAxOwoKICAgIGlmICghT3BlbkNsaXBib2FyZChQUklWQVRFKGRhdGEpLT5oV25kKSkgcmV0dXJuOwogICAgRW1wdHlDbGlwYm9hcmQoKTsKCiAgICBoTWVtID0gR2xvYmFsQWxsb2MoR01FTV9NT1ZFQUJMRSwgKHcgKiBoKSAqIHNpemVvZihXQ0hBUikpOwogICAgaWYgKGhNZW0gJiYgKHAgPSBHbG9iYWxMb2NrKGhNZW0pKSkKICAgIHsKCUNPT1JECWM7CglpbnQJeTsKCgljLlggPSBtaW4oUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlgsIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5YKTsKCWMuWSA9IG1pbihQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWSwgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlkpOwoKCWZvciAoeSA9IDA7IHkgPCBoOyB5KyssIGMuWSsrKQoJewoJICAgIFJlYWRDb25zb2xlT3V0cHV0Q2hhcmFjdGVyKGRhdGEtPmhDb25PdXQsICZwW3kgKiB3XSwgdyAtIDEsIGMsIE5VTEwpOwoJICAgIHBbeSAqIHcgKyB3IC0gMV0gPSAoeSA8IGggLSAxKSA/ICdcbicgOiAnXDAnOwoJfQoJR2xvYmFsVW5sb2NrKGhNZW0pOwoJU2V0Q2xpcGJvYXJkRGF0YShDRl9VTklDT0RFVEVYVCwgaE1lbSk7CiAgICB9CiAgICBDbG9zZUNsaXBib2FyZCgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfUGFzdGVGcm9tQ2xpcGJvYXJkCiAqCiAqCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfUGFzdGVGcm9tQ2xpcGJvYXJkKHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBIQU5ETEUJaDsKICAgIFdDSEFSKglwdHI7CgogICAgaWYgKCFPcGVuQ2xpcGJvYXJkKFBSSVZBVEUoZGF0YSktPmhXbmQpKSByZXR1cm47CiAgICBoID0gR2V0Q2xpcGJvYXJkRGF0YShDRl9VTklDT0RFVEVYVCk7CiAgICBpZiAoaCAmJiAocHRyID0gR2xvYmFsTG9jayhoKSkpCiAgICB7CglpbnQJCWksIGxlbiA9IEdsb2JhbFNpemUoaCkgLyBzaXplb2YoV0NIQVIpOwoJSU5QVVRfUkVDT1JECWlyWzJdOwoJRFdPUkQJCW47CglTSE9SVAkJc2g7CgoJaXJbMF0uRXZlbnRUeXBlID0gS0VZX0VWRU5UOwoJaXJbMF0uRXZlbnQuS2V5RXZlbnQud1JlcGVhdENvdW50ID0gMDsKCWlyWzBdLkV2ZW50LktleUV2ZW50LmR3Q29udHJvbEtleVN0YXRlID0gMDsKCWlyWzBdLkV2ZW50LktleUV2ZW50LmJLZXlEb3duID0gVFJVRTsKCgkvKiBnZW5lcmF0ZSB0aGUgY29ycmVzcG9uZGluZyBpbnB1dCByZWNvcmRzICovCglmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspCgl7CgkgICAgLyogRklYTUU6IHRoZSBtb2RpZnlpbmcga2V5cyBhcmUgbm90IGdlbmVyYXRlZCAoc2hpZnQsIGN0cmwuLi4pICovCgkgICAgc2ggPSBWa0tleVNjYW4ocHRyW2ldKTsKCSAgICBpclswXS5FdmVudC5LZXlFdmVudC53VmlydHVhbEtleUNvZGUgPSBMT0JZVEUoc2gpOwoJICAgIGlyWzBdLkV2ZW50LktleUV2ZW50LndWaXJ0dWFsU2NhbkNvZGUgPSBNYXBWaXJ0dWFsS2V5KExPQllURShzaCksIDApOwoJICAgIGlyWzBdLkV2ZW50LktleUV2ZW50LnVDaGFyLlVuaWNvZGVDaGFyID0gcHRyW2ldOwoKCSAgICBpclsxXSA9IGlyWzBdOwoJICAgIGlyWzFdLkV2ZW50LktleUV2ZW50LmJLZXlEb3duID0gRkFMU0U7CgoJICAgIFdyaXRlQ29uc29sZUlucHV0KGRhdGEtPmhDb25JbiwgaXIsIDIsICZuKTsKCX0KCUdsb2JhbFVubG9jayhoKTsKICAgIH0KICAgIENsb3NlQ2xpcGJvYXJkKCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9SZWZyZXNoCiAqCiAqCiAqLwpzdGF0aWMgdm9pZCBXQ1VTRVJfUmVmcmVzaChjb25zdCBzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgaW50IHRwLCBpbnQgYm0pCnsKICAgIFdDVVNFUl9GaWxsTWVtREMoZGF0YSwgdHAsIGJtKTsKICAgIGlmIChkYXRhLT5jdXJjZmcud2luX3Bvcy5ZIDw9IGJtICYmIGRhdGEtPmN1cmNmZy53aW5fcG9zLlkgKyBkYXRhLT5jdXJjZmcud2luX2hlaWdodCA+PSB0cCkKICAgIHsKCVJFQ1QJcjsKCglyLmxlZnQgICA9IDA7CglyLnJpZ2h0ICA9IGRhdGEtPmN1cmNmZy53aW5fd2lkdGggKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKCXIudG9wICAgID0gKHRwIC0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSkgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQ7CglyLmJvdHRvbSA9IChibSAtIGRhdGEtPmN1cmNmZy53aW5fcG9zLlkgKyAxKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKCUludmFsaWRhdGVSZWN0KFBSSVZBVEUoZGF0YSktPmhXbmQsICZyLCBGQUxTRSk7CglVcGRhdGVXaW5kb3coUFJJVkFURShkYXRhKS0+aFduZCk7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9QYWludAogKgogKgogKi8Kc3RhdGljIHZvaWQJV0NVU0VSX1BhaW50KGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBQQUlOVFNUUlVDVAkJcHM7CgogICAgQmVnaW5QYWludChQUklWQVRFKGRhdGEpLT5oV25kLCAmcHMpOwogICAgQml0Qmx0KHBzLmhkYywgMCwgMCwKICAgICAgICAgICBkYXRhLT5jdXJjZmcud2luX3dpZHRoICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGgsCiAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLndpbl9oZWlnaHQgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQsCgkgICBQUklWQVRFKGRhdGEpLT5oTWVtREMsCiAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWCAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoLAogICAgICAgICAgIGRhdGEtPmN1cmNmZy53aW5fcG9zLlkgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQsCgkgICBTUkNDT1BZKTsKICAgIGlmIChQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uKQoJV0NVU0VSX1NldFNlbGVjdGlvbihkYXRhLCBwcy5oZGMpOwogICAgRW5kUGFpbnQoUFJJVkFURShkYXRhKS0+aFduZCwgJnBzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1Njcm9sbAogKgogKgogKi8Kc3RhdGljIHZvaWQgV0NVU0VSX1Njcm9sbChzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgaW50IHBvcywgQk9PTCBob3J6KQp7CiAgICBpZiAoaG9yeikKICAgIHsKCVNldFNjcm9sbFBvcyhQUklWQVRFKGRhdGEpLT5oV25kLCBTQl9IT1JaLCBwb3MsIFRSVUUpOwoJZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWCA9IHBvczsKICAgIH0KICAgIGVsc2UKICAgIHsKCVNldFNjcm9sbFBvcyhQUklWQVRFKGRhdGEpLT5oV25kLCBTQl9WRVJULCBwb3MsIFRSVUUpOwoJZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSA9IHBvczsKICAgIH0KICAgIEludmFsaWRhdGVSZWN0KFBSSVZBVEUoZGF0YSktPmhXbmQsIE5VTEwsIEZBTFNFKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0ZpbGxNZW51CiAqCiAqCiAqLwpzdGF0aWMgQk9PTCBXQ1VTRVJfRmlsbE1lbnUoSE1FTlUgaE1lbnUsIEJPT0wgc2VwKQp7CiAgICBITUVOVQkJaFN1Yk1lbnU7CiAgICBISU5TVEFOQ0UJCWhJbnN0YW5jZSA9IEdldE1vZHVsZUhhbmRsZShOVUxMKTsKICAgIFdDSEFSCQlidWZmWzI1Nl07CgogICAgaWYgKCFoTWVudSkgcmV0dXJuIEZBTFNFOwoKICAgIC8qIEZJWE1FOiBlcnJvciBoYW5kbGluZyAmIG1lbW9yeSBjbGVhbnVwICovCiAgICBoU3ViTWVudSA9IENyZWF0ZU1lbnUoKTsKICAgIGlmICghaFN1Yk1lbnUpIHJldHVybiBGQUxTRTsKCiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX01BUkssIGJ1ZmYsIHNpemVvZihidWZmKSAvIHNpemVvZihXQ0hBUikpOwogICAgSW5zZXJ0TWVudShoU3ViTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU1RSSU5HLCBJRFNfTUFSSywgYnVmZik7CiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX0NPUFksIGJ1ZmYsIHNpemVvZihidWZmKSAvIHNpemVvZihXQ0hBUikpOwogICAgSW5zZXJ0TWVudShoU3ViTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU1RSSU5HLCBJRFNfQ09QWSwgYnVmZik7CiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX1BBU1RFLCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaFN1Yk1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklORywgSURTX1BBU1RFLCBidWZmKTsKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfU0VMRUNUQUxMLCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaFN1Yk1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklORywgSURTX1NFTEVDVEFMTCwgYnVmZik7CiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX1NDUk9MTCwgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhTdWJNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkcsIElEU19TQ1JPTEwsIGJ1ZmYpOwogICAgTG9hZFN0cmluZyhoSW5zdGFuY2UsIElEU19TRUFSQ0gsIGJ1ZmYsIHNpemVvZihidWZmKSAvIHNpemVvZihXQ0hBUikpOwogICAgSW5zZXJ0TWVudShoU3ViTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU1RSSU5HLCBJRFNfU0VBUkNILCBidWZmKTsKCiAgICBpZiAoc2VwKSBJbnNlcnRNZW51KGhNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TRVBBUkFUT1IsIDAsIE5VTEwpOwogICAgTG9hZFN0cmluZyhoSW5zdGFuY2UsIElEU19FRElULCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaE1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklOR3xNRl9QT1BVUCwgKFVJTlRfUFRSKWhTdWJNZW51LCBidWZmKTsKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfREVGQVVMVCwgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkcsIElEU19ERUZBVUxULCBidWZmKTsKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfUFJPUEVSVElFUywgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkcsIElEU19QUk9QRVJUSUVTLCBidWZmKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1NldE1lbnVEZXRhaWxzCiAqCiAqIEdyYXlzIC8gdW5ncmF5cyB0aGUgbWVudSBpdGVtcyBhY2NvcmRpbmcgdG8gdGhlaXIgc3RhdGUKICovCnN0YXRpYyB2b2lkCVdDVVNFUl9TZXRNZW51RGV0YWlscyhjb25zdCBzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgSE1FTlUgaE1lbnUpCnsKICAgIGlmICghaE1lbnUpIHtXSU5FX0VSUigiSXNzdWUgaW4gZ2V0dGluZyBtZW51IGJpdHNcbiIpO3JldHVybjt9CgogICAgRW5hYmxlTWVudUl0ZW0oaE1lbnUsIElEU19DT1BZLAogICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EfChQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID8gTUZfRU5BQkxFRCA6IE1GX0dSQVlFRCkpOwogICAgRW5hYmxlTWVudUl0ZW0oaE1lbnUsIElEU19QQVNURSwKCQkgICBNRl9CWUNPTU1BTkR8KElzQ2xpcGJvYXJkRm9ybWF0QXZhaWxhYmxlKENGX1VOSUNPREVURVhUKQoJCQkJID8gTUZfRU5BQkxFRCA6IE1GX0dSQVlFRCkpOwogICAgRW5hYmxlTWVudUl0ZW0oaE1lbnUsIElEU19TQ1JPTEwsIE1GX0JZQ09NTUFORHxNRl9HUkFZRUQpOwogICAgRW5hYmxlTWVudUl0ZW0oaE1lbnUsIElEU19TRUFSQ0gsIE1GX0JZQ09NTUFORHxNRl9HUkFZRUQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfQ3JlYXRlCiAqCiAqIENyZWF0ZXMgdGhlIHdpbmRvdyBmb3IgdGhlIHJlbmRlcmluZwogKi8Kc3RhdGljIExSRVNVTFQgV0NVU0VSX0NyZWF0ZShIV05EIGhXbmQsIExQQ1JFQVRFU1RSVUNUIGxwY3MpCnsKICAgIHN0cnVjdCBpbm5lcl9kYXRhKglkYXRhOwogICAgSE1FTlUJCWhTeXNNZW51OwoKICAgIGRhdGEgPSBscGNzLT5scENyZWF0ZVBhcmFtczsKICAgIFNldFdpbmRvd0xvbmcoaFduZCwgMEwsIChEV09SRClkYXRhKTsKICAgIFBSSVZBVEUoZGF0YSktPmhXbmQgPSBoV25kOwoKICAgIGhTeXNNZW51ID0gR2V0U3lzdGVtTWVudShoV25kLCBGQUxTRSk7CiAgICBpZiAoIWhTeXNNZW51KSByZXR1cm4gMDsKICAgIFBSSVZBVEUoZGF0YSktPmhQb3BNZW51ID0gQ3JlYXRlUG9wdXBNZW51KCk7CiAgICBpZiAoIVBSSVZBVEUoZGF0YSktPmhQb3BNZW51KSByZXR1cm4gMDsKCiAgICBXQ1VTRVJfRmlsbE1lbnUoaFN5c01lbnUsIFRSVUUpOwogICAgV0NVU0VSX0ZpbGxNZW51KFBSSVZBVEUoZGF0YSktPmhQb3BNZW51LCBGQUxTRSk7CgogICAgUFJJVkFURShkYXRhKS0+aE1lbURDID0gQ3JlYXRlQ29tcGF0aWJsZURDKDApOwogICAgaWYgKCFQUklWQVRFKGRhdGEpLT5oTWVtREMpIHtXSU5FX0VSUigibm8gbWVtIGRjXG4iKTtyZXR1cm4gMDt9CgogICAgZGF0YS0+Y3VyY2ZnLnF1aWNrX2VkaXQgPSBGQUxTRTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfR2V0Q3RybEtleVN0YXRlCiAqCiAqIEdldCB0aGUgY29uc29sZSBiaXQgbWFzayBlcXVpdmFsZW50IHRvIHRoZSBWS18gc3RhdHVzIGluIGtleVN0YXRlCiAqLwpzdGF0aWMgRFdPUkQgICAgV0NVU0VSX0dldEN0cmxLZXlTdGF0ZShCWVRFKiBrZXlTdGF0ZSkKewogICAgRFdPUkQgICAgICAgICAgICAgICByZXQgPSAwOwoKICAgIEdldEtleWJvYXJkU3RhdGUoa2V5U3RhdGUpOwogICAgaWYgKGtleVN0YXRlW1ZLX1NISUZUXSAgICAmIDB4ODApCXJldCB8PSBTSElGVF9QUkVTU0VEOwogICAgaWYgKGtleVN0YXRlW1ZLX0xDT05UUk9MXSAmIDB4ODApCXJldCB8PSBMRUZUX0NUUkxfUFJFU1NFRDsKICAgIGlmIChrZXlTdGF0ZVtWS19SQ09OVFJPTF0gJiAweDgwKQlyZXQgfD0gUklHSFRfQ1RSTF9QUkVTU0VEOwogICAgaWYgKGtleVN0YXRlW1ZLX0xNRU5VXSAgICAmIDB4ODApCXJldCB8PSBMRUZUX0FMVF9QUkVTU0VEOwogICAgaWYgKGtleVN0YXRlW1ZLX1JNRU5VXSAgICAmIDB4ODApCXJldCB8PSBSSUdIVF9BTFRfUFJFU1NFRDsKICAgIGlmIChrZXlTdGF0ZVtWS19DQVBJVEFMXSAgJiAweDAxKQlyZXQgfD0gQ0FQU0xPQ0tfT047CiAgICBpZiAoa2V5U3RhdGVbVktfTlVNTE9DS10gICYgMHgwMSkJcmV0IHw9IE5VTUxPQ0tfT047CiAgICBpZiAoa2V5U3RhdGVbVktfU0NST0xMXSAgICYgMHgwMSkJcmV0IHw9IFNDUk9MTExPQ0tfT047CgogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0hhbmRsZVNlbGVjdGlvbktleQogKgogKiBIYW5kbGVzIGtleXMgd2hpbGUgc2VsZWN0aW5nIGFuIGFyZWEKICovCnN0YXRpYyB2b2lkIFdDVVNFUl9IYW5kbGVTZWxlY3Rpb25LZXkoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIEJPT0wgZG93biwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBCWVRFCWtleVN0YXRlWzI1Nl07CiAgICBEV09SRCAgICAgICBzdGF0ZSA9IFdDVVNFUl9HZXRDdHJsS2V5U3RhdGUoa2V5U3RhdGUpICYgfihDQVBTTE9DS19PTnxOVU1MT0NLX09OfFNDUk9MTExPQ0tfT04pOwogICAgQ09PUkQgICAgICAgYzEsIGMyOwoKICAgIGlmIChkb3duKSByZXR1cm47CgogICAgc3dpdGNoIChzdGF0ZSkKICAgIHsKICAgIGNhc2UgMDoKICAgICAgICBzd2l0Y2ggKHdQYXJhbSkKICAgICAgICB7CiAgICAgICAgY2FzZSBWS19SRVRVUk46CiAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24gPSBGQUxTRTsKICAgICAgICAgICAgV0NVU0VSX1NldFNlbGVjdGlvbihkYXRhLCAwKTsKICAgICAgICAgICAgV0NVU0VSX0NvcHlTZWxlY3Rpb25Ub0NsaXBib2FyZChkYXRhKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBWS19SSUdIVDoKICAgICAgICAgICAgYzEgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDE7CiAgICAgICAgICAgIGMyID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyOwogICAgICAgICAgICBjMS5YKys7IGMyLlgrKzsKICAgICAgICAgICAgV0NVU0VSX01vdmVTZWxlY3Rpb24oZGF0YSwgYzEsIGMyKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBWS19MRUZUOgogICAgICAgICAgICBjMSA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MTsKICAgICAgICAgICAgYzIgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDI7CiAgICAgICAgICAgIGMxLlgtLTsgYzIuWC0tOwogICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFZLX1VQOgogICAgICAgICAgICBjMSA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MTsKICAgICAgICAgICAgYzIgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDI7CiAgICAgICAgICAgIGMxLlktLTsgYzIuWS0tOwogICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFZLX0RPV046CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzEuWSsrOyBjMi5ZKys7CiAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgU0hJRlRfUFJFU1NFRDoKICAgICAgICBzd2l0Y2ggKHdQYXJhbSkKICAgICAgICB7CiAgICAgICAgY2FzZSBWS19SSUdIVDoKICAgICAgICAgICAgYzEgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDE7CiAgICAgICAgICAgIGMyID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyOwogICAgICAgICAgICBjMi5YKys7CiAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVktfTEVGVDoKICAgICAgICAgICAgYzEgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDE7CiAgICAgICAgICAgIGMyID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyOwogICAgICAgICAgICBjMi5YLS07CiAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVktfVVA6CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzIuWS0tOwogICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFZLX0RPV046CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzIuWSsrOwogICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9HZW5lcmF0ZUtleUlucHV0UmVjb3JkCiAqCiAqIGdlbmVyYXRlcyBpbnB1dF9yZWNvcmQgZnJvbSB3aW5kb3dzIFdNX0tFWVVQL1dNX0tFWURPV04gbWVzc2FnZXMKICovCnN0YXRpYyB2b2lkICAgIFdDVVNFUl9HZW5lcmF0ZUtleUlucHV0UmVjb3JkKHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBCT09MIGRvd24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0sIEJPT0wgc3lzKQp7CiAgICBJTlBVVF9SRUNPUkQJaXI7CiAgICBEV09SRAkJbjsKICAgIFdDSEFSCQlidWZbMl07CiAgICBzdGF0aWMJV0NIQVIJbGFzdDsgLyoga2VlcCBsYXN0IGNoYXIgc2VlbiBhcyBmZWVkIGZvciBrZXkgdXAgbWVzc2FnZSAqLwogICAgQllURQkJa2V5U3RhdGVbMjU2XTsKCiAgICBpci5FdmVudFR5cGUgPSBLRVlfRVZFTlQ7CiAgICBpci5FdmVudC5LZXlFdmVudC5iS2V5RG93biA9IGRvd247CiAgICBpci5FdmVudC5LZXlFdmVudC53UmVwZWF0Q291bnQgPSBMT1dPUkQobFBhcmFtKTsKICAgIGlyLkV2ZW50LktleUV2ZW50LndWaXJ0dWFsS2V5Q29kZSA9IHdQYXJhbTsKCiAgICBpci5FdmVudC5LZXlFdmVudC53VmlydHVhbFNjYW5Db2RlID0gSElXT1JEKGxQYXJhbSkgJiAweEZGOwoKICAgIGlyLkV2ZW50LktleUV2ZW50LnVDaGFyLlVuaWNvZGVDaGFyID0gMDsKICAgIGlyLkV2ZW50LktleUV2ZW50LmR3Q29udHJvbEtleVN0YXRlID0gV0NVU0VSX0dldEN0cmxLZXlTdGF0ZShrZXlTdGF0ZSk7CiAgICBpZiAobFBhcmFtICYgKDFMIDw8IDI0KSkJCWlyLkV2ZW50LktleUV2ZW50LmR3Q29udHJvbEtleVN0YXRlIHw9IEVOSEFOQ0VEX0tFWTsKICAgIGlmIChzeXMpCQkJCWlyLkV2ZW50LktleUV2ZW50LmR3Q29udHJvbEtleVN0YXRlIHw9IExFRlRfQUxUX1BSRVNTRUQ7IC8qIEZJWE1FOiBnb3R0YSBjaG9vc2Ugb25lICovCgogICAgaWYgKCEoaXIuRXZlbnQuS2V5RXZlbnQuZHdDb250cm9sS2V5U3RhdGUgJiBFTkhBTkNFRF9LRVkpKQogICAgewoJaWYgKGRvd24pCgl7CgkgICAgc3dpdGNoIChUb1VuaWNvZGUod1BhcmFtLCBISVdPUkQobFBhcmFtKSwga2V5U3RhdGUsIGJ1ZiwgMiwgMCkpCgkgICAgewoJICAgIGNhc2UgMjoKCQkvKiBGSVhNRS4uLiBzaG91bGQgZ2VuZXJhdGUgdHdvIGV2ZW50cy4uLiAqLwoJCS8qIGZhbGwgdGhydSAqLwoJICAgIGNhc2UgMToKCQlsYXN0ID0gYnVmWzBdOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJbGFzdCA9IDA7CgkJYnJlYWs7CgkgICAgfQoJfQoJaXIuRXZlbnQuS2V5RXZlbnQudUNoYXIuVW5pY29kZUNoYXIgPSBsYXN0OyAvKiBGSVhNRSBIQUNLWS4uLiBhbmQgYnVnZ3kgJ2NveiBpdCBzaG91bGQgYmUgYSBzdGFjaywgbm90IGEgc2luZ2xlIHZhbHVlICovCglpZiAoIWRvd24pIGxhc3QgPSAwOwogICAgfQoKICAgIFdyaXRlQ29uc29sZUlucHV0KGRhdGEtPmhDb25JbiwgJmlyLCAxLCAmbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQKICoKICoKICovCnN0YXRpYyB2b2lkICAgIFdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIENPT1JEIGMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1BBUkFNIHdQYXJhbSwgRFdPUkQgZXZlbnQpCnsKICAgIElOUFVUX1JFQ09SRAlpcjsKICAgIEJZVEUJCWtleVN0YXRlWzI1Nl07CiAgICBEV09SRCAgICAgICAgICAgICAgIG1vZGUsIG47CgogICAgLyogTU9VU0VfRVZFTlRzIHNob3VsZG4ndCBiZSBzZW50IHVubGVzcyBFTkFCTEVfTU9VU0VfSU5QVVQgaXMgYWN0aXZlICovCiAgICBpZiAoIUdldENvbnNvbGVNb2RlKGRhdGEtPmhDb25JbiwgJm1vZGUpIHx8ICEobW9kZSAmIEVOQUJMRV9NT1VTRV9JTlBVVCkpCiAgICAgICAgcmV0dXJuOwoKICAgIGlyLkV2ZW50VHlwZSA9IE1PVVNFX0VWRU5UOwogICAgaXIuRXZlbnQuTW91c2VFdmVudC5kd01vdXNlUG9zaXRpb24gPSBjOwogICAgaXIuRXZlbnQuTW91c2VFdmVudC5kd0J1dHRvblN0YXRlID0gMDsKICAgIGlmICh3UGFyYW0gJiBNS19MQlVUVE9OKSBpci5FdmVudC5Nb3VzZUV2ZW50LmR3QnV0dG9uU3RhdGUgfD0gRlJPTV9MRUZUXzFTVF9CVVRUT05fUFJFU1NFRDsKICAgIGlmICh3UGFyYW0gJiBNS19NQlVUVE9OKSBpci5FdmVudC5Nb3VzZUV2ZW50LmR3QnV0dG9uU3RhdGUgfD0gRlJPTV9MRUZUXzJORF9CVVRUT05fUFJFU1NFRDsKICAgIGlmICh3UGFyYW0gJiBNS19SQlVUVE9OKSBpci5FdmVudC5Nb3VzZUV2ZW50LmR3QnV0dG9uU3RhdGUgfD0gUklHSFRNT1NUX0JVVFRPTl9QUkVTU0VEOwogICAgaXIuRXZlbnQuTW91c2VFdmVudC5kd0NvbnRyb2xLZXlTdGF0ZSA9IFdDVVNFUl9HZXRDdHJsS2V5U3RhdGUoa2V5U3RhdGUpOwogICAgaXIuRXZlbnQuTW91c2VFdmVudC5kd0V2ZW50RmxhZ3MgPSBldmVudDsKCiAgICBXcml0ZUNvbnNvbGVJbnB1dChkYXRhLT5oQ29uSW4sICZpciwgMSwgJm4pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfUHJvYwogKgogKgogKi8Kc3RhdGljIExSRVNVTFQgQ0FMTEJBQ0sgV0NVU0VSX1Byb2MoSFdORCBoV25kLCBVSU5UIHVNc2csIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pCnsKICAgIHN0cnVjdCBpbm5lcl9kYXRhKglkYXRhID0gKHN0cnVjdCBpbm5lcl9kYXRhKilHZXRXaW5kb3dMb25nKGhXbmQsIDApOwoKICAgIHN3aXRjaCAodU1zZykKICAgIHsKICAgIGNhc2UgV01fQ1JFQVRFOgogICAgICAgIHJldHVybiBXQ1VTRVJfQ3JlYXRlKGhXbmQsIChMUENSRUFURVNUUlVDVClsUGFyYW0pOwogICAgY2FzZSBXTV9ERVNUUk9ZOgoJUFJJVkFURShkYXRhKS0+aFduZCA9IDA7CglQb3N0UXVpdE1lc3NhZ2UoMCk7CglicmVhazsKICAgIGNhc2UgV01fUEFJTlQ6CglXQ1VTRVJfUGFpbnQoZGF0YSk7CglicmVhazsKICAgIGNhc2UgV01fS0VZRE9XTjoKICAgIGNhc2UgV01fS0VZVVA6CiAgICAgICAgaWYgKFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24pCiAgICAgICAgICAgIFdDVVNFUl9IYW5kbGVTZWxlY3Rpb25LZXkoZGF0YSwgdU1zZyA9PSBXTV9LRVlET1dOLCB3UGFyYW0sIGxQYXJhbSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBXQ1VTRVJfR2VuZXJhdGVLZXlJbnB1dFJlY29yZChkYXRhLCB1TXNnID09IFdNX0tFWURPV04sIHdQYXJhbSwgbFBhcmFtLCBGQUxTRSk7CglicmVhazsKICAgIGNhc2UgV01fU1lTS0VZRE9XTjoKICAgIGNhc2UgV01fU1lTS0VZVVA6CglXQ1VTRVJfR2VuZXJhdGVLZXlJbnB1dFJlY29yZChkYXRhLCB1TXNnID09IFdNX1NZU0tFWURPV04sIHdQYXJhbSwgbFBhcmFtLCBUUlVFKTsKCWJyZWFrOwogICAgY2FzZSBXTV9MQlVUVE9ORE9XTjoKICAgICAgICBpZiAoZGF0YS0+Y3VyY2ZnLnF1aWNrX2VkaXQpCiAgICAgICAgewogICAgICAgICAgICBpZiAoUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiA9IEZBTFNFOwogICAgICAgICAgICAgICAgV0NVU0VSX1NldFNlbGVjdGlvbihkYXRhLCAwKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MSA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MiA9IFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSk7CiAgICAgICAgICAgICAgICBTZXRDYXB0dXJlKFBSSVZBVEUoZGF0YSktPmhXbmQpOwogICAgICAgICAgICAgICAgV0NVU0VSX1NldFNlbGVjdGlvbihkYXRhLCAwKTsKICAgICAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24gPSBUUlVFOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQoZGF0YSwgV0NVU0VSX0dldENlbGwoZGF0YSwgbFBhcmFtKSwgd1BhcmFtLCAwKTsKICAgICAgICB9CglicmVhazsKICAgIGNhc2UgV01fTU9VU0VNT1ZFOgogICAgICAgIGlmIChkYXRhLT5jdXJjZmcucXVpY2tfZWRpdCkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChHZXRDYXB0dXJlKCkgPT0gUFJJVkFURShkYXRhKS0+aFduZCAmJiBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uICYmCiAgICAgICAgICAgICAgICAod1BhcmFtICYgTUtfTEJVVFRPTikpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MSwgV0NVU0VSX0dldENlbGwoZGF0YSwgbFBhcmFtKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgV0NVU0VSX0dlbmVyYXRlTW91c2VJbnB1dFJlY29yZChkYXRhLCBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCB3UGFyYW0sIE1PVVNFX01PVkVEKTsKICAgICAgICB9CglicmVhazsKICAgIGNhc2UgV01fTEJVVFRPTlVQOgogICAgICAgIGlmIChkYXRhLT5jdXJjZmcucXVpY2tfZWRpdCkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChHZXRDYXB0dXJlKCkgPT0gUFJJVkFURShkYXRhKS0+aFduZCAmJiBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uICYmCiAgICAgICAgICAgICAgICAod1BhcmFtJiBNS19MQlVUVE9OKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0NVU0VSX01vdmVTZWxlY3Rpb24oZGF0YSwgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLCBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pKTsKICAgICAgICAgICAgICAgIFJlbGVhc2VDYXB0dXJlKCk7CiAgICAgICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID0gRkFMU0U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgV0NVU0VSX0dlbmVyYXRlTW91c2VJbnB1dFJlY29yZChkYXRhLCBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCB3UGFyYW0sIDApOwogICAgICAgIH0KCWJyZWFrOwogICAgY2FzZSBXTV9SQlVUVE9ORE9XTjoKICAgICAgICBpZiAoKHdQYXJhbSAmIChNS19DT05UUk9MfE1LX1NISUZUKSkgPT0gZGF0YS0+Y3VyY2ZnLm1lbnVfbWFzaykKICAgICAgICB7CiAgICAgICAgICAgIFJFQ1QgICAgICAgIHI7CgogICAgICAgICAgICBHZXRXaW5kb3dSZWN0KGhXbmQsICZyKTsKICAgICAgICAgICAgV0NVU0VSX1NldE1lbnVEZXRhaWxzKGRhdGEsIFBSSVZBVEUoZGF0YSktPmhQb3BNZW51KTsKICAgICAgICAgICAgVHJhY2tQb3B1cE1lbnUoUFJJVkFURShkYXRhKS0+aFBvcE1lbnUsIFRQTV9MRUZUQUxJR058VFBNX1RPUEFMSUdOLAogICAgICAgICAgICAgICAgICAgICAgICAgICByLmxlZnQgKyBMT1dPUkQobFBhcmFtKSwgci50b3AgKyBISVdPUkQobFBhcmFtKSwgMCwgaFduZCwgTlVMTCk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQoZGF0YSwgV0NVU0VSX0dldENlbGwoZGF0YSwgbFBhcmFtKSwgd1BhcmFtLCAwKTsKICAgICAgICB9CglicmVhazsKICAgIGNhc2UgV01fUkJVVFRPTlVQOgogICAgICAgIC8qIG5vIG5lZWQgdG8gdHJhY2sgZm9yIHJidXR0b24gdXAgd2hlbiBvcGVuaW5nIHRoZSBwb3B1cC4uLiB0aGUgZXZlbnQgd2lsbCBiZQogICAgICAgICAqIHN3YWxsb3dlZCBieSBUcmFja1BvcHVwTWVudSAqLwogICAgICAgIFdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQoZGF0YSwgV0NVU0VSX0dldENlbGwoZGF0YSwgbFBhcmFtKSwgd1BhcmFtLCAwKTsKCWJyZWFrOwogICAgY2FzZSBXTV9NT1VTRVdIRUVMOgogICAgICAgIC8qIEZJWE1FOiBzaG91bGQgd2Ugc2Nyb2xsIHRvbyA/ICovCiAgICAgICAgV0NVU0VSX0dlbmVyYXRlTW91c2VJbnB1dFJlY29yZChkYXRhLCBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCB3UGFyYW0sIE1PVVNFX1dIRUVMRUQpOwoJYnJlYWs7CiAgICBjYXNlIFdNX1NFVEZPQ1VTOgoJaWYgKGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKCXsKCSAgICBDcmVhdGVDYXJldChQUklWQVRFKGRhdGEpLT5oV25kLCBQUklWQVRFKGRhdGEpLT5jdXJzb3JfYml0bWFwLAogICAgICAgICAgICAgICAgICAgICAgICBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwgZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0KTsKCSAgICBXQ1VTRVJfUG9zQ3Vyc29yKGRhdGEpOwoJfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBXTV9LSUxMRk9DVVM6CglpZiAoZGF0YS0+Y3VyY2ZnLmN1cnNvcl92aXNpYmxlKQoJICAgIERlc3Ryb3lDYXJldCgpOwoJYnJlYWs7CiAgICBjYXNlIFdNX0hTQ1JPTEw6CiAgICAgICAgewogICAgICAgICAgICBpbnQJcG9zID0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWDsKCiAgICAgICAgICAgIHN3aXRjaCAoTE9XT1JEKHdQYXJhbSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgY2FzZSBTQl9QQUdFVVA6IAlwb3MgLT0gODsgCQlicmVhazsKICAgICAgICAgICAgY2FzZSBTQl9QQUdFRE9XTjogCXBvcyArPSA4OyAJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX0xJTkVVUDogCXBvcy0tOwkJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX0xJTkVET1dOOiAJcG9zKys7CSAJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX1RIVU1CVFJBQ0s6IHBvcyA9IEhJV09SRCh3UGFyYW0pOwlicmVhazsKICAgICAgICAgICAgZGVmYXVsdDogCQkJCQlicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAocG9zIDwgMCkgcG9zID0gMDsKICAgICAgICAgICAgaWYgKHBvcyA+IGRhdGEtPmN1cmNmZy5zYl93aWR0aCAtIGRhdGEtPmN1cmNmZy53aW5fd2lkdGgpCiAgICAgICAgICAgICAgICBwb3MgPSBkYXRhLT5jdXJjZmcuc2Jfd2lkdGggLSBkYXRhLT5jdXJjZmcud2luX3dpZHRoOwogICAgICAgICAgICBpZiAocG9zICE9IGRhdGEtPmN1cmNmZy53aW5fcG9zLlgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFNjcm9sbFdpbmRvdyhoV25kLCAoZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWCAtIHBvcykgKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMKTsKICAgICAgICAgICAgICAgIGRhdGEtPmN1cmNmZy53aW5fcG9zLlggPSBwb3M7CiAgICAgICAgICAgICAgICBTZXRTY3JvbGxQb3MoaFduZCwgU0JfSE9SWiwgcG9zLCBUUlVFKTsKICAgICAgICAgICAgICAgIFVwZGF0ZVdpbmRvdyhoV25kKTsKICAgICAgICAgICAgICAgIFdDVVNFUl9Qb3NDdXJzb3IoZGF0YSk7CiAgICAgICAgICAgICAgICBXSU5FQ09OX05vdGlmeVdpbmRvd0NoYW5nZShkYXRhKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCWJyZWFrOwogICAgY2FzZSBXTV9WU0NST0xMOgogICAgICAgIHsKCSAgICBpbnQJcG9zID0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWTsKCgkgICAgc3dpdGNoIChMT1dPUkQod1BhcmFtKSkKCSAgICB7CiAgICAgICAgICAgIGNhc2UgU0JfUEFHRVVQOiAJcG9zIC09IDg7IAkJYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU0JfUEFHRURPV046IAlwb3MgKz0gODsgCQlicmVhazsKICAgICAgICAgICAgY2FzZSBTQl9MSU5FVVA6IAlwb3MtLTsJCQlicmVhazsKCSAgICBjYXNlIFNCX0xJTkVET1dOOiAJcG9zKys7CSAJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX1RIVU1CVFJBQ0s6IHBvcyA9IEhJV09SRCh3UGFyYW0pOwlicmVhazsKICAgICAgICAgICAgZGVmYXVsdDogCQkJCQlicmVhazsKCSAgICB9CgkgICAgaWYgKHBvcyA8IDApIHBvcyA9IDA7CgkgICAgaWYgKHBvcyA+IGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgLSBkYXRhLT5jdXJjZmcud2luX2hlaWdodCkKICAgICAgICAgICAgICAgIHBvcyA9IGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgLSBkYXRhLT5jdXJjZmcud2luX2hlaWdodDsKCSAgICBpZiAocG9zICE9IGRhdGEtPmN1cmNmZy53aW5fcG9zLlkpCgkgICAgewoJCVNjcm9sbFdpbmRvdyhoV25kLCAwLCAoZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSAtIHBvcykgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCk7CgkJZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSA9IHBvczsKCQlTZXRTY3JvbGxQb3MoaFduZCwgU0JfVkVSVCwgcG9zLCBUUlVFKTsKCQlVcGRhdGVXaW5kb3coaFduZCk7CgkJV0NVU0VSX1Bvc0N1cnNvcihkYXRhKTsKCQlXSU5FQ09OX05vdGlmeVdpbmRvd0NoYW5nZShkYXRhKTsKCSAgICB9CgogICAgICAgIH0KICAgIGNhc2UgV01fU1lTQ09NTUFORDoKCXN3aXRjaCAod1BhcmFtKQoJewoJY2FzZSBJRFNfREVGQVVMVDoKCSAgICBXQ1VTRVJfR2V0UHJvcGVydGllcyhkYXRhLCBGQUxTRSk7CgkgICAgYnJlYWs7CgljYXNlIElEU19QUk9QRVJUSUVTOgoJICAgIFdDVVNFUl9HZXRQcm9wZXJ0aWVzKGRhdGEsIFRSVUUpOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICByZXR1cm4gRGVmV2luZG93UHJvYyhoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7Cgl9CglicmVhazsKICAgIGNhc2UgV01fQ09NTUFORDoKCXN3aXRjaCAod1BhcmFtKQoJewoJY2FzZSBJRFNfREVGQVVMVDoKCSAgICBXQ1VTRVJfR2V0UHJvcGVydGllcyhkYXRhLCBGQUxTRSk7CgkgICAgYnJlYWs7CgljYXNlIElEU19QUk9QRVJUSUVTOgoJICAgIFdDVVNFUl9HZXRQcm9wZXJ0aWVzKGRhdGEsIFRSVUUpOwoJICAgIGJyZWFrOwoJY2FzZSBJRFNfTUFSSzoKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlggPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWSA9IDA7CiAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5YID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlkgPSAwOwogICAgICAgICAgICBXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIDApOwogICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID0gVFJVRTsKCSAgICBicmVhazsKCWNhc2UgSURTX0NPUFk6CiAgICAgICAgICAgIGlmIChQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID0gRkFMU0U7CiAgICAgICAgICAgICAgICBXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIDApOwogICAgICAgICAgICAgICAgV0NVU0VSX0NvcHlTZWxlY3Rpb25Ub0NsaXBib2FyZChkYXRhKTsKICAgICAgICAgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBJRFNfUEFTVEU6CgkgICAgV0NVU0VSX1Bhc3RlRnJvbUNsaXBib2FyZChkYXRhKTsKCSAgICBicmVhazsKCWNhc2UgSURTX1NFTEVDVEFMTDoKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlggPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWSA9IDA7CiAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5YID0gKGRhdGEtPmN1cmNmZy5zYl93aWR0aCAtIDEpICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGg7CiAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5ZID0gKGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgLSAxKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKICAgICAgICAgICAgV0NVU0VSX1NldFNlbGVjdGlvbihkYXRhLCAwKTsKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiA9IFRSVUU7CgkgICAgYnJlYWs7CgljYXNlIElEU19TQ1JPTEw6CgljYXNlIElEU19TRUFSQ0g6CgkgICAgV0lORV9GSVhNRSgiVW5oYW5kbGVkIHlldCBjb21tYW5kOiAleFxuIiwgd1BhcmFtKTsKCSAgICBicmVhazsKCWRlZmF1bHQ6CgkgICAgcmV0dXJuIERlZldpbmRvd1Byb2MoaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwoJfQoJYnJlYWs7CiAgICBjYXNlIFdNX0lOSVRNRU5VUE9QVVA6CglpZiAoIUhJV09SRChsUGFyYW0pKQlyZXR1cm4gRGVmV2luZG93UHJvYyhoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7CglXQ1VTRVJfU2V0TWVudURldGFpbHMoZGF0YSwgR2V0U3lzdGVtTWVudShQUklWQVRFKGRhdGEpLT5oV25kLCBGQUxTRSkpOwoJYnJlYWs7CiAgICBkZWZhdWx0OgoJcmV0dXJuIERlZldpbmRvd1Byb2MoaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9EZWxldGVCYWNrZW5kCiAqCiAqCiAqLwpzdGF0aWMgdm9pZCBXQ1VTRVJfRGVsZXRlQmFja2VuZChzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgaWYgKCFQUklWQVRFKGRhdGEpKSByZXR1cm47CiAgICBpZiAoUFJJVkFURShkYXRhKS0+aE1lbURDKQkJRGVsZXRlREMoUFJJVkFURShkYXRhKS0+aE1lbURDKTsKICAgIGlmIChQUklWQVRFKGRhdGEpLT5oV25kKQkJRGVzdHJveVdpbmRvdyhQUklWQVRFKGRhdGEpLT5oV25kKTsKICAgIGlmIChQUklWQVRFKGRhdGEpLT5oRm9udCkJCURlbGV0ZU9iamVjdChQUklWQVRFKGRhdGEpLT5oRm9udCk7CiAgICBpZiAoUFJJVkFURShkYXRhKS0+Y3Vyc29yX2JpdG1hcCkJRGVsZXRlT2JqZWN0KFBSSVZBVEUoZGF0YSktPmN1cnNvcl9iaXRtYXApOwogICAgaWYgKFBSSVZBVEUoZGF0YSktPmhCaXRtYXApCQlEZWxldGVPYmplY3QoUFJJVkFURShkYXRhKS0+aEJpdG1hcCk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBQUklWQVRFKGRhdGEpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX01haW5Mb29wCiAqCiAqCiAqLwpzdGF0aWMgaW50IFdDVVNFUl9NYWluTG9vcChzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgTVNHCQltc2c7CgogICAgU2hvd1dpbmRvdyhQUklWQVRFKGRhdGEpLT5oV25kLCBTV19TSE9XKTsKICAgIGZvciAoOzspCiAgICB7Cglzd2l0Y2ggKE1zZ1dhaXRGb3JNdWx0aXBsZU9iamVjdHMoMSwgJmRhdGEtPmhTeW5jaHJvLCBGQUxTRSwgSU5GSU5JVEUsIFFTX0FMTElOUFVUKSkKCXsKCWNhc2UgV0FJVF9PQkpFQ1RfMDoKCSAgICBpZiAoIVdJTkVDT05fR3JhYkNoYW5nZXMoZGF0YSkgJiYgZGF0YS0+Y3VyY2ZnLmV4aXRfb25fZGllKQogICAgICAgICAgICAgICAgUG9zdFF1aXRNZXNzYWdlKDApOwoJICAgIGJyZWFrOwoJY2FzZSBXQUlUX09CSkVDVF8wKzE6CgkgICAgLyogbmVlZCB0byB1c2UgUGVla01lc3NhZ2UgbG9vcCBpbnN0ZWFkIG9mIHNpbXBsZSBHZXRNZXNzYWdlOgoJICAgICAqIG11bHRpcGxlIG1lc3NhZ2VzIG1pZ2h0IGhhdmUgYXJyaXZlZCBpbiBiZXR3ZWVuLAoJICAgICAqIHNvIEdldE1lc3NhZ2Ugd291bGQgbGVhZCB0byBkZWxheWVkIHByb2Nlc3NpbmcgKi8KCSAgICB3aGlsZSAoUGVla01lc3NhZ2UoJm1zZywgMCwgMCwgMCwgUE1fUkVNT1ZFKSkKCSAgICB7CiAgICAgICAgICAgICAgICBpZiAobXNnLm1lc3NhZ2UgPT0gV01fUVVJVCkgcmV0dXJuIDA7CiAgICAgICAgICAgICAgICBXSU5FX1RSQUNFKCJkaXNwYXRjaGluZyBtc2cgJTA0eFxuIiwgbXNnLm1lc3NhZ2UpOwogICAgICAgICAgICAgICAgRGlzcGF0Y2hNZXNzYWdlKCZtc2cpOwoJICAgIH0KCSAgICBicmVhazsKCWRlZmF1bHQ6CgkgICAgV0lORV9FUlIoImdvdCBwYlxuIik7CgkgICAgLyogZXJyICovCgkgICAgYnJlYWs7Cgl9CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9Jbml0QmFja2VuZAogKgogKiBJbml0aWFsaXNhdGlvbiBwYXJ0IElJOiBjcmVhdGlvbiBvZiB3aW5kb3cuCiAqCiAqLwplbnVtIGluaXRfcmV0dXJuIFdDVVNFUl9Jbml0QmFja2VuZChzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIHdDbGFzc05hbWVbXSA9IHsnVycsJ2knLCduJywnZScsJ0MnLCdvJywnbicsJ3MnLCdvJywnbCcsJ2UnLCdDJywnbCcsJ2EnLCdzJywncycsMH07CgogICAgV05EQ0xBU1MJCXduZGNsYXNzOwoKICAgIGRhdGEtPnByaXZhdGUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKHN0cnVjdCBpbm5lcl9kYXRhX3VzZXIpKTsKICAgIGlmICghZGF0YS0+cHJpdmF0ZSkgcmV0dXJuIGluaXRfZmFpbGVkOwoKICAgIGRhdGEtPmZuTWFpbkxvb3AgPSBXQ1VTRVJfTWFpbkxvb3A7CiAgICBkYXRhLT5mblBvc0N1cnNvciA9IFdDVVNFUl9Qb3NDdXJzb3I7CiAgICBkYXRhLT5mblNoYXBlQ3Vyc29yID0gV0NVU0VSX1NoYXBlQ3Vyc29yOwogICAgZGF0YS0+Zm5Db21wdXRlUG9zaXRpb25zID0gV0NVU0VSX0NvbXB1dGVQb3NpdGlvbnM7CiAgICBkYXRhLT5mblJlZnJlc2ggPSBXQ1VTRVJfUmVmcmVzaDsKICAgIGRhdGEtPmZuUmVzaXplU2NyZWVuQnVmZmVyID0gV0NVU0VSX1Jlc2l6ZVNjcmVlbkJ1ZmZlcjsKICAgIGRhdGEtPmZuU2V0VGl0bGUgPSBXQ1VTRVJfU2V0VGl0bGU7CiAgICBkYXRhLT5mblNldEZvbnQgPSBXQ1VTRVJfU2V0Rm9udFBtdDsKICAgIGRhdGEtPmZuU2Nyb2xsID0gV0NVU0VSX1Njcm9sbDsKICAgIGRhdGEtPmZuRGVsZXRlQmFja2VuZCA9IFdDVVNFUl9EZWxldGVCYWNrZW5kOwoKICAgIHduZGNsYXNzLnN0eWxlICAgICAgICAgPSAwOwogICAgd25kY2xhc3MubHBmblduZFByb2MgICA9IFdDVVNFUl9Qcm9jOwogICAgd25kY2xhc3MuY2JDbHNFeHRyYSAgICA9IDA7CiAgICB3bmRjbGFzcy5jYlduZEV4dHJhICAgID0gc2l6ZW9mKERXT1JEKTsKICAgIHduZGNsYXNzLmhJbnN0YW5jZSAgICAgPSBHZXRNb2R1bGVIYW5kbGUoTlVMTCk7CiAgICB3bmRjbGFzcy5oSWNvbiAgICAgICAgID0gTG9hZEljb24oMCwgSURJX1dJTkxPR08pOwogICAgd25kY2xhc3MuaEN1cnNvciAgICAgICA9IExvYWRDdXJzb3IoMCwgSURDX0FSUk9XKTsKICAgIHduZGNsYXNzLmhickJhY2tncm91bmQgPSBHZXRTdG9ja09iamVjdChCTEFDS19CUlVTSCk7CiAgICB3bmRjbGFzcy5scHN6TWVudU5hbWUgID0gTlVMTDsKICAgIHduZGNsYXNzLmxwc3pDbGFzc05hbWUgPSB3Q2xhc3NOYW1lOwoKICAgIFJlZ2lzdGVyQ2xhc3MoJnduZGNsYXNzKTsKCiAgICBDcmVhdGVXaW5kb3cod25kY2xhc3MubHBzekNsYXNzTmFtZSwgTlVMTCwKCQkgV1NfT1ZFUkxBUFBFRHxXU19DQVBUSU9OfFdTX1NZU01FTlV8V1NfVEhJQ0tGUkFNRXxXU19NSU5JTUlaRUJPWHxXU19IU0NST0xMfFdTX1ZTQ1JPTEwsCgkJIENXX1VTRURFRkFVTFQsIENXX1VTRURFRkFVTFQsIDAsIDAsIDAsIDAsIHduZGNsYXNzLmhJbnN0YW5jZSwgZGF0YSk7CiAgICBpZiAoIVBSSVZBVEUoZGF0YSktPmhXbmQpIHJldHVybiBpbml0X2ZhaWxlZDsKCiAgICByZXR1cm4gaW5pdF9zdWNjZXNzOwp9Cg==