LyoKICogYSBHVUkgYXBwbGljYXRpb24gZm9yIGRpc3BsYXlpbmcgYSBjb25zb2xlCiAqCVVTRVIzMiBiYWNrIGVuZAogKiBDb3B5cmlnaHQgMjAwMSBFcmljIFBvdWVjaAogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSAid2luZWNvbl91c2VyLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwod2luZWNvbnNvbGUpOwpXSU5FX0RFQ0xBUkVfREVCVUdfQ0hBTk5FTCh3Y19mb250KTsKCi8qIG1hcHBpbmcgY29uc29sZSBjb2xvcnMgdG8gUkdCIHZhbHVlcyAqLwpDT0xPUlJFRglXQ1VTRVJfQ29sb3JNYXBbMTZdID0KewogICAgUkdCKDB4MDAsIDB4MDAsIDB4MDApLCBSR0IoMHgwMCwgMHgwMCwgMHg4MCksIFJHQigweDAwLCAweDgwLCAweDAwKSwgUkdCKDB4MDAsIDB4ODAsIDB4ODApLAogICAgUkdCKDB4ODAsIDB4MDAsIDB4MDApLCBSR0IoMHg4MCwgMHgwMCwgMHg4MCksIFJHQigweDgwLCAweDgwLCAweDAwKSwgUkdCKDB4ODAsIDB4ODAsIDB4ODApLAogICAgUkdCKDB4QzAsIDB4QzAsIDB4QzApLCBSR0IoMHgwMCwgMHgwMCwgMHhGRiksIFJHQigweDAwLCAweEZGLCAweDAwKSwgUkdCKDB4MDAsIDB4RkYsIDB4RkYpLAogICAgUkdCKDB4RkYsIDB4MDAsIDB4MDApLCBSR0IoMHhGRiwgMHgwMCwgMHhGRiksIFJHQigweEZGLCAweEZGLCAweDAwKSwgUkdCKDB4RkYsIDB4RkYsIDB4RkYpLAp9OwoKc3RhdGljIEJPT0wgV0NVU0VSX1NldEZvbnQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIGNvbnN0IExPR0ZPTlQqIGZvbnQpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0ZpbGxNZW1EQwogKgogKiBGaWxscyB0aGUgTWVtIERDIHdpdGggY3VycmVudCBjZWxscyB2YWx1ZXMKICovCnN0YXRpYyB2b2lkIFdDVVNFUl9GaWxsTWVtREMoY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIGludCB1cGRfdHAsIGludCB1cGRfYm0pCnsKICAgIHVuc2lnbmVkCQlpLCBqLCBrOwogICAgQ0hBUl9JTkZPKgkJY2VsbDsKICAgIEhGT05UCQloT2xkRm9udDsKICAgIFdPUkQJCWF0dHI7CiAgICBXQ0hBUioJCWxpbmU7CgogICAgLyogbm8gZm9udCBoYXMgYmVlbiBzZXQgdXAgeWV0LCBkb24ndCB3b3JyeSBhYm91dCBmaWxsaW5nIHRoZSBiaXRtYXAsCiAgICAgKiB3ZSdsbCBkbyBpdCBvbmNlIGEgZm9udCBpcyBjaG9zZW4KICAgICAqLwogICAgaWYgKCFQUklWQVRFKGRhdGEpLT5oRm9udCkgcmV0dXJuOwoKICAgIC8qIEZJWE1FOiBjb3VsZCBzZXQgdXAgYSBtZWNoYW5pc20gdG8gcmV1c2UgdGhlIGxpbmUgYmV0d2VlbiBkaWZmZXJlbnQKICAgICAqIGNhbGxzIHRvIHRoaXMgZnVuY3Rpb24KICAgICAqLwogICAgaWYgKCEobGluZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBkYXRhLT5jdXJjZmcuc2Jfd2lkdGggKiBzaXplb2YoV0NIQVIpKSkpCiAgICAgICAgV0lORUNPTl9GYXRhbCgiT09NXG4iKTsKCiAgICBoT2xkRm9udCA9IFNlbGVjdE9iamVjdChQUklWQVRFKGRhdGEpLT5oTWVtREMsIFBSSVZBVEUoZGF0YSktPmhGb250KTsKICAgIGZvciAoaiA9IHVwZF90cDsgaiA8PSB1cGRfYm07IGorKykKICAgIHsKCWNlbGwgPSAmZGF0YS0+Y2VsbHNbaiAqIGRhdGEtPmN1cmNmZy5zYl93aWR0aF07Cglmb3IgKGkgPSAwOyBpIDwgZGF0YS0+Y3VyY2ZnLnNiX3dpZHRoOyBpKyspCgl7CgkgICAgYXR0ciA9IGNlbGxbaV0uQXR0cmlidXRlczsKCSAgICBTZXRCa0NvbG9yKFBSSVZBVEUoZGF0YSktPmhNZW1EQywgV0NVU0VSX0NvbG9yTWFwWyhhdHRyPj40KSYweDBGXSk7CgkgICAgU2V0VGV4dENvbG9yKFBSSVZBVEUoZGF0YSktPmhNZW1EQywgV0NVU0VSX0NvbG9yTWFwW2F0dHImMHgwRl0pOwoJICAgIGZvciAoayA9IGk7IGsgPCBkYXRhLT5jdXJjZmcuc2Jfd2lkdGggJiYgY2VsbFtrXS5BdHRyaWJ1dGVzID09IGF0dHI7IGsrKykKCSAgICB7CgkJbGluZVtrIC0gaV0gPSBjZWxsW2tdLkNoYXIuVW5pY29kZUNoYXI7CgkgICAgfQoJICAgIFRleHRPdXQoUFJJVkFURShkYXRhKS0+aE1lbURDLCBpICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGgsIGogKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQsCgkJICAgIGxpbmUsIGsgLSBpKTsKCSAgICBpID0gayAtIDE7Cgl9CiAgICB9CiAgICBTZWxlY3RPYmplY3QoUFJJVkFURShkYXRhKS0+aE1lbURDLCBoT2xkRm9udCk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBsaW5lKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX05ld0JpdG1hcAogKgogKiBFaXRoZXIgdGhlIGZvbnQgZ2VvbWV0cnkgb3IgdGhlIHNiIGdlb21ldHJ5IGhhcyBjaGFuZ2VkLiB3ZSBuZWVkCiAqIHRvIHJlY3JlYXRlIHRoZSBiaXRtYXAgZ2VvbWV0cnkuCiAqLwpzdGF0aWMgdm9pZCBXQ1VTRVJfTmV3Qml0bWFwKHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBIREMgICAgICAgICBoREM7CiAgICBIQklUTUFQCWhuZXcsIGhvbGQ7CgogICAgaWYgKCFkYXRhLT5jdXJjZmcuc2Jfd2lkdGggfHwgIWRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgfHwKICAgICAgICAhUFJJVkFURShkYXRhKS0+aEZvbnQgfHwgIShoREMgPSBHZXREQyhQUklWQVRFKGRhdGEpLT5oV25kKSkpCiAgICAgICAgcmV0dXJuOwogICAgaG5ldyA9IENyZWF0ZUNvbXBhdGlibGVCaXRtYXAoaERDLAoJCQkJICBkYXRhLT5jdXJjZmcuc2Jfd2lkdGggICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGgsCgkJCQkgIGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQpOwogICAgUmVsZWFzZURDKFBSSVZBVEUoZGF0YSktPmhXbmQsIGhEQyk7CiAgICBob2xkID0gU2VsZWN0T2JqZWN0KFBSSVZBVEUoZGF0YSktPmhNZW1EQywgaG5ldyk7CgogICAgaWYgKFBSSVZBVEUoZGF0YSktPmhCaXRtYXApCiAgICB7CglpZiAoaG9sZCA9PSBQUklWQVRFKGRhdGEpLT5oQml0bWFwKQoJICAgIERlbGV0ZU9iamVjdChQUklWQVRFKGRhdGEpLT5oQml0bWFwKTsKCWVsc2UKCSAgICBXSU5FX0ZJWE1FKCJsZWFrXG4iKTsKICAgIH0KICAgIFBSSVZBVEUoZGF0YSktPmhCaXRtYXAgPSBobmV3OwogICAgV0NVU0VSX0ZpbGxNZW1EQyhkYXRhLCAwLCBkYXRhLT5jdXJjZmcuc2JfaGVpZ2h0IC0gMSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9SZXNpemVTY3JlZW5CdWZmZXIKICoKICoKICovCnN0YXRpYyB2b2lkIFdDVVNFUl9SZXNpemVTY3JlZW5CdWZmZXIoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIFdDVVNFUl9OZXdCaXRtYXAoZGF0YSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9Qb3NDdXJzb3IKICoKICogU2V0IGEgbmV3IHBvc2l0aW9uIGZvciB0aGUgY3Vyc29yCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfUG9zQ3Vyc29yKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBpZiAoUFJJVkFURShkYXRhKS0+aFduZCAhPSBHZXRGb2N1cygpIHx8ICFkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUpIHJldHVybjsKCiAgICBTZXRDYXJldFBvcygoZGF0YS0+Y3Vyc29yLlggLSBkYXRhLT5jdXJjZmcud2luX3Bvcy5YKSAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoLAoJCShkYXRhLT5jdXJzb3IuWSAtIGRhdGEtPmN1cmNmZy53aW5fcG9zLlkpICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0KTsKICAgIFNob3dDYXJldChQUklWQVRFKGRhdGEpLT5oV25kKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1NoYXBlQ3Vyc29yCiAqCiAqIFNldHMgYSBuZXcgc2hhcGUgZm9yIHRoZSBjdXJzb3IKICovCnN0YXRpYyB2b2lkCVdDVVNFUl9TaGFwZUN1cnNvcihzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgaW50IHNpemUsIGludCB2aXMsIEJPT0wgZm9yY2UpCnsKICAgIGlmIChmb3JjZSB8fCBzaXplICE9IGRhdGEtPmN1cmNmZy5jdXJzb3Jfc2l6ZSkKICAgIHsKCWlmIChkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUgJiYgUFJJVkFURShkYXRhKS0+aFduZCA9PSBHZXRGb2N1cygpKSBEZXN0cm95Q2FyZXQoKTsKCWlmIChQUklWQVRFKGRhdGEpLT5jdXJzb3JfYml0bWFwKSBEZWxldGVPYmplY3QoUFJJVkFURShkYXRhKS0+Y3Vyc29yX2JpdG1hcCk7CglQUklWQVRFKGRhdGEpLT5jdXJzb3JfYml0bWFwID0gTlVMTDsKCWlmIChzaXplICE9IDEwMCkKCXsKCSAgICBpbnQJCXcxNmI7IC8qIG51bWJlciBvZiBieXRlcyBwZXIgcm93LCBhbGlnbmVkIG9uIHdvcmQgc2l6ZSAqLwoJICAgIEJZVEUqCXB0cjsKCSAgICBpbnQJCWksIGosIG5ibDsKCgkgICAgdzE2YiA9ICgoZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGggKyAxNSkgJiB+MTUpIC8gODsKCSAgICBwdHIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgdzE2YiAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCk7CgkgICAgaWYgKCFwdHIpIFdJTkVDT05fRmF0YWwoIk9PTSIpOwoJICAgIG5ibCA9IG1heCgoZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0ICogc2l6ZSkgLyAxMDAsIDEpOwoJICAgIGZvciAoaiA9IGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCAtIG5ibDsgaiA8IGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsgaisrKQoJICAgIHsKCQlmb3IgKGkgPSAwOyBpIDwgZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGg7IGkrKykKCQl7CgkJICAgIHB0clt3MTZiICogaiArIChpIC8gOCldIHw9IDB4ODAgPj4gKGkgJiA3KTsKCQl9CgkgICAgfQoJICAgIFBSSVZBVEUoZGF0YSktPmN1cnNvcl9iaXRtYXAgPSBDcmVhdGVCaXRtYXAoZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0LCAxLCAxLCBwdHIpOwoJICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHB0cik7Cgl9CglkYXRhLT5jdXJjZmcuY3Vyc29yX3NpemUgPSBzaXplOwoJZGF0YS0+Y3VyY2ZnLmN1cnNvcl92aXNpYmxlID0gLTE7CiAgICB9CgogICAgdmlzID0gKHZpcykgPyBUUlVFIDogRkFMU0U7CiAgICBpZiAoZm9yY2UgfHwgdmlzICE9IGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKICAgIHsKCWRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSA9IHZpczsKCWlmIChQUklWQVRFKGRhdGEpLT5oV25kID09IEdldEZvY3VzKCkpCgl7CgkgICAgaWYgKHZpcykKCSAgICB7CgkJQ3JlYXRlQ2FyZXQoUFJJVkFURShkYXRhKS0+aFduZCwgUFJJVkFURShkYXRhKS0+Y3Vyc29yX2JpdG1hcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoLCBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQpOwoJCVdDVVNFUl9Qb3NDdXJzb3IoZGF0YSk7CgkgICAgfQoJICAgIGVsc2UKCSAgICB7CgkJRGVzdHJveUNhcmV0KCk7CgkgICAgfQoJfQogICAgfQogICAgV0lORUNPTl9EdW1wQ29uZmlnKCJjcnNyIiwgJmRhdGEtPmN1cmNmZyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9Db21wdXRlUG9zaXRpb25zCiAqCiAqIFJlY29tcHV0ZXMgYWxsIHRoZSBjb21wb25lbnRzIChtYWlubHkgc2Nyb2xsIGJhcnMpIHBvc2l0aW9ucwogKi8Kdm9pZAlXQ1VTRVJfQ29tcHV0ZVBvc2l0aW9ucyhzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgUkVDVAkJcjsKICAgIGludAkJCWR4LCBkeTsKCiAgICAvKiBjb21wdXRlIHdpbmRvdyBzaXplIGZyb20gZGVzaXJlZCBjbGllbnQgc2l6ZSAqLwogICAgci5sZWZ0ID0gci50b3AgPSAwOwogICAgci5yaWdodCA9IGRhdGEtPmN1cmNmZy53aW5fd2lkdGggKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgIHIuYm90dG9tID0gZGF0YS0+Y3VyY2ZnLndpbl9oZWlnaHQgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQ7CgogICAgaWYgKElzUmVjdEVtcHR5KCZyKSkgcmV0dXJuOwoKICAgIEFkanVzdFdpbmRvd1JlY3QoJnIsIEdldFdpbmRvd0xvbmcoUFJJVkFURShkYXRhKS0+aFduZCwgR1dMX1NUWUxFKSwgRkFMU0UpOwoKICAgIGR4ID0gZHkgPSAwOwogICAgaWYgKGRhdGEtPmN1cmNmZy5zYl93aWR0aCA+IGRhdGEtPmN1cmNmZy53aW5fd2lkdGgpCiAgICB7CglkeSA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lIU0NST0xMKTsKCVNldFNjcm9sbFJhbmdlKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX0hPUlosIDAsCiAgICAgICAgICAgICAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLnNiX3dpZHRoIC0gZGF0YS0+Y3VyY2ZnLndpbl93aWR0aCwgRkFMU0UpOwoJU2V0U2Nyb2xsUG9zKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX0hPUlosIDAsIEZBTFNFKTsgLyogRklYTUUgKi8KCVNob3dTY3JvbGxCYXIoUFJJVkFURShkYXRhKS0+aFduZCwgU0JfSE9SWiwgVFJVRSk7CiAgICB9CiAgICBlbHNlCiAgICB7CglTaG93U2Nyb2xsQmFyKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX0hPUlosIEZBTFNFKTsKICAgIH0KCiAgICBpZiAoZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCA+IGRhdGEtPmN1cmNmZy53aW5faGVpZ2h0KQogICAgewoJZHggPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCk7CglTZXRTY3JvbGxSYW5nZShQUklWQVRFKGRhdGEpLT5oV25kLCBTQl9WRVJULCAwLAogICAgICAgICAgICAgICAgICAgICAgIGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgLSBkYXRhLT5jdXJjZmcud2luX2hlaWdodCwgRkFMU0UpOwoJU2V0U2Nyb2xsUG9zKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX1ZFUlQsIDAsIEZBTFNFKTsgLyogRklYTUUgKi8KCVNob3dTY3JvbGxCYXIoUFJJVkFURShkYXRhKS0+aFduZCwgU0JfVkVSVCwgVFJVRSk7CiAgICB9CiAgICBlbHNlCiAgICB7CglTaG93U2Nyb2xsQmFyKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX1ZFUlQsIEZBTFNFKTsKICAgIH0KCiAgICBTZXRXaW5kb3dQb3MoUFJJVkFURShkYXRhKS0+aFduZCwgMCwgMCwgMCwgci5yaWdodCAtIHIubGVmdCArIGR4LCByLmJvdHRvbSAtIHIudG9wICsgZHksCgkJIFNXUF9OT01PVkV8U1dQX05PWk9SREVSKTsKICAgIFdDVVNFUl9TaGFwZUN1cnNvcihkYXRhLCBkYXRhLT5jdXJjZmcuY3Vyc29yX3NpemUsIGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSwgVFJVRSk7CiAgICBXQ1VTRVJfUG9zQ3Vyc29yKGRhdGEpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfU2V0VGl0bGUKICoKICogU2V0cyB0aGUgdGl0bGUgdG8gdGhlIHdpbmUgY29uc29sZQogKi8Kc3RhdGljIHZvaWQJV0NVU0VSX1NldFRpdGxlKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBXQ0hBUglidWZmZXJbMjU2XTsKCiAgICBpZiAoV0lORUNPTl9HZXRDb25zb2xlVGl0bGUoZGF0YS0+aENvbkluLCBidWZmZXIsIHNpemVvZihidWZmZXIpKSkKCVNldFdpbmRvd1RleHQoUFJJVkFURShkYXRhKS0+aFduZCwgYnVmZmVyKTsKfQoKdm9pZCBXQ1VTRVJfRHVtcExvZ0ZvbnQoY29uc3QgY2hhciogcGZ4LCBjb25zdCBMT0dGT05UKiBsZiwgRFdPUkQgZnQpCnsKICAgIFdJTkVfVFJBQ0VfKHdjX2ZvbnQpKCIlcyAlcyVzJXMlc1xuIgogICAgICAgICAgICAgICAgICAgICAgICAgIlx0bGYubGZIZWlnaHQ9JWxkIGxmLmxmV2lkdGg9JWxkIGxmLmxmRXNjYXBlbWVudD0lbGQgbGYubGZPcmllbnRhdGlvbj0lbGRcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdGxmLmxmV2VpZ2h0PSVsZCBsZi5sZkl0YWxpYz0ldSBsZi5sZlVuZGVybGluZT0ldSBsZi5sZlN0cmlrZU91dD0ldVxuIgogICAgICAgICAgICAgICAgICAgICAgICAgIlx0bGYubGZDaGFyU2V0PSV1IGxmLmxmT3V0UHJlY2lzaW9uPSV1IGxmLmxmQ2xpcFByZWNpc2lvbj0ldSBsZi5sZlF1YWxpdHk9JXVcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdGxmLT5sZlBpdGNoQW5kRmFtaWx5PSV1IGxmLmxmRmFjZU5hbWU9JXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICBwZngsCiAgICAgICAgICAgICAgICAgICAgICAgICAoZnQgJiBSQVNURVJfRk9OVFRZUEUpID8gInJhc3RlciIgOiAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgIChmdCAmIFRSVUVUWVBFX0ZPTlRUWVBFKSA/ICJ0cnVldHlwZSIgOiAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgICgoZnQgJiAoUkFTVEVSX0ZPTlRUWVBFfFRSVUVUWVBFX0ZPTlRUWVBFKSkgPT0gMCkgPyAidmVjdG9yIiA6ICIiLAogICAgICAgICAgICAgICAgICAgICAgICAgKGZ0ICYgREVWSUNFX0ZPTlRUWVBFKSA/ICJ8ZGV2aWNlIiA6ICIiLAogICAgICAgICAgICAgICAgICAgICAgICAgbGYtPmxmSGVpZ2h0LCBsZi0+bGZXaWR0aCwgbGYtPmxmRXNjYXBlbWVudCwgbGYtPmxmT3JpZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICBsZi0+bGZXZWlnaHQsIGxmLT5sZkl0YWxpYywgbGYtPmxmVW5kZXJsaW5lLCBsZi0+bGZTdHJpa2VPdXQsIGxmLT5sZkNoYXJTZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICBsZi0+bGZPdXRQcmVjaXNpb24sIGxmLT5sZkNsaXBQcmVjaXNpb24sIGxmLT5sZlF1YWxpdHksIGxmLT5sZlBpdGNoQW5kRmFtaWx5LAogICAgICAgICAgICAgICAgICAgICAgICAgd2luZV9kYmdzdHJfdyhsZi0+bGZGYWNlTmFtZSkpOwp9Cgp2b2lkIFdDVVNFUl9EdW1wVGV4dE1ldHJpYyhjb25zdCBURVhUTUVUUklDKiB0bSwgRFdPUkQgZnQpCnsKICAgIFdJTkVfVFJBQ0VfKHdjX2ZvbnQpKCIlcyVzJXMlc1xuIgogICAgICAgICAgICAgICAgICAgICAgICAgIlx0dG1IZWlnaHQ9JWxkIHRtQXNjZW50PSVsZCB0bURlc2NlbnQ9JWxkIHRtSW50ZXJuYWxMZWFkaW5nPSVsZCB0bUV4dGVybmFsTGVhZGluZz0lbGRcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdHRtQXZlQ2hhcldpZHRoPSVsZCB0bU1heENoYXJXaWR0aD0lbGQgdG1XZWlnaHQ9JWxkIHRtT3Zlcmhhbmc9JWxkXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAiXHR0bURpZ2l0aXplZEFzcGVjdFg9JWxkIHRtRGlnaXRpemVkQXNwZWN0WT0lbGRcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdHRtRmlyc3RDaGFyPSVkIHRtTGFzdENoYXI9JWQgdG1EZWZhdWx0Q2hhcj0lZCB0bUJyZWFrQ2hhcj0lZFxuIgogICAgICAgICAgICAgICAgICAgICAgICAgIlx0dG1JdGFsaWM9JXUgdG1VbmRlcmxpbmVkPSV1IHRtU3RydWNrT3V0PSV1IHRtUGl0Y2hBbmRGYW1pbHk9JXUgdG1DaGFyU2V0PSV1XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgKGZ0ICYgUkFTVEVSX0ZPTlRUWVBFKSA/ICJyYXN0ZXIiIDogIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAoZnQgJiBUUlVFVFlQRV9GT05UVFlQRSkgPyAidHJ1ZXR5cGUiIDogIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAoKGZ0ICYgKFJBU1RFUl9GT05UVFlQRXxUUlVFVFlQRV9GT05UVFlQRSkpID09IDApID8gInZlY3RvciIgOiAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgIChmdCAmIERFVklDRV9GT05UVFlQRSkgPyAifGRldmljZSIgOiAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgIHRtLT50bUhlaWdodCwgdG0tPnRtQXNjZW50LCB0bS0+dG1EZXNjZW50LCB0bS0+dG1JbnRlcm5hbExlYWRpbmcsIHRtLT50bUV4dGVybmFsTGVhZGluZywgdG0tPnRtQXZlQ2hhcldpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgdG0tPnRtTWF4Q2hhcldpZHRoLCB0bS0+dG1XZWlnaHQsIHRtLT50bU92ZXJoYW5nLCB0bS0+dG1EaWdpdGl6ZWRBc3BlY3RYLCB0bS0+dG1EaWdpdGl6ZWRBc3BlY3RZLAogICAgICAgICAgICAgICAgICAgICAgICAgdG0tPnRtRmlyc3RDaGFyLCB0bS0+dG1MYXN0Q2hhciwgdG0tPnRtRGVmYXVsdENoYXIsIHRtLT50bUJyZWFrQ2hhciwgdG0tPnRtSXRhbGljLCB0bS0+dG1VbmRlcmxpbmVkLCB0bS0+dG1TdHJ1Y2tPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICB0bS0+dG1QaXRjaEFuZEZhbWlseSwgdG0tPnRtQ2hhclNldCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9BcmVGb250c0VxdWFsCiAqCiAqCiAqLwpCT09MIFdDVVNFUl9BcmVGb250c0VxdWFsKGNvbnN0IHN0cnVjdCBjb25maWdfZGF0YSogY29uZmlnLCBjb25zdCBMT0dGT05UKiBsZikKewogICAgcmV0dXJuIGxmLT5sZkhlaWdodCA9PSBjb25maWctPmNlbGxfaGVpZ2h0ICYmCiAgICAgICAgbGYtPmxmV2VpZ2h0ID09IGNvbmZpZy0+Zm9udF93ZWlnaHQgJiYKICAgICAgICAhbGYtPmxmSXRhbGljICYmICFsZi0+bGZVbmRlcmxpbmUgJiYgIWxmLT5sZlN0cmlrZU91dCAmJgogICAgICAgICFsc3RyY21wKGxmLT5sZkZhY2VOYW1lLCBjb25maWctPmZhY2VfbmFtZSk7Cn0KCnN0cnVjdCBmb250X2Nob29zZXIKewogICAgc3RydWN0IGlubmVyX2RhdGEqCWRhdGE7CiAgICBpbnQJCQlkb25lOwp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1ZhbGlkYXRlRm9udE1ldHJpYwogKgogKiBSZXR1cm5zIHRydWUgaWYgdGhlIGZvbnQgZGVzY3JpYmVkIGluIHRtIGlzIHVzYWJsZSBhcyBhIGZvbnQgZm9yIHRoZSByZW5kZXJlcgogKi8KQk9PTAlXQ1VTRVJfVmFsaWRhdGVGb250TWV0cmljKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBjb25zdCBURVhUTUVUUklDKiB0bSwgRFdPUkQgZm9udFR5cGUpCnsKICAgIEJPT0wgICAgICAgIHJldCA9IFRSVUU7CgogICAgaWYgKGZvbnRUeXBlICYgUkFTVEVSX0ZPTlRUWVBFKQogICAgICAgIHJldCA9ICh0bS0+dG1NYXhDaGFyV2lkdGggKiBkYXRhLT5jdXJjZmcud2luX3dpZHRoIDwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNDUkVFTikgJiYKICAgICAgICAgICAgICAgdG0tPnRtSGVpZ2h0ICogZGF0YS0+Y3VyY2ZnLndpbl9oZWlnaHQgPCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0NSRUVOKSk7CiAgICByZXR1cm4gcmV0ICYmICF0bS0+dG1JdGFsaWMgJiYgIXRtLT50bVVuZGVybGluZWQgJiYgIXRtLT50bVN0cnVja091dCAmJgogICAgICAgICh0bS0+dG1DaGFyU2V0ID09IERFRkFVTFRfQ0hBUlNFVCB8fCB0bS0+dG1DaGFyU2V0ID09IEFOU0lfQ0hBUlNFVCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9WYWxpZGF0ZUZvbnQKICoKICogUmV0dXJucyB0cnVlIGlmIHRoZSBmb250IGZhbWlseSBkZXNjcmliZWQgaW4gbGYgaXMgdXNhYmxlIGFzIGEgZm9udCBmb3IgdGhlIHJlbmRlcmVyCiAqLwpCT09MCVdDVVNFUl9WYWxpZGF0ZUZvbnQoY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIGNvbnN0IExPR0ZPTlQqIGxmKQp7CiAgICByZXR1cm4gKGxmLT5sZlBpdGNoQW5kRmFtaWx5ICYgMykgPT0gRklYRURfUElUQ0ggJiYKICAgICAgICAvKiAobGYtPmxmUGl0Y2hBbmRGYW1pbHkgJiAweEYwKSA9PSBGRl9NT0RFUk4gJiYgKi8KICAgICAgICAobGYtPmxmQ2hhclNldCA9PSBERUZBVUxUX0NIQVJTRVQgfHwgbGYtPmxmQ2hhclNldCA9PSBBTlNJX0NIQVJTRVQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlnZXRfZmlyc3RfZm9udF9lbnVtXzIKICoJCWdldF9maXJzdF9mb250X2VudW0KICoKICogSGVscGVyIGZ1bmN0aW9ucyB0byBnZXQgYSBkZWNlbnQgZm9udCBmb3IgdGhlIHJlbmRlcmVyCiAqLwpzdGF0aWMgaW50IENBTExCQUNLIGdldF9maXJzdF9mb250X2VudW1fMihjb25zdCBMT0dGT05UKiBsZiwgY29uc3QgVEVYVE1FVFJJQyogdG0sCgkJCQkJICBEV09SRCBGb250VHlwZSwgTFBBUkFNIGxQYXJhbSkKewogICAgc3RydWN0IGZvbnRfY2hvb3NlcioJZmMgPSAoc3RydWN0IGZvbnRfY2hvb3NlciopbFBhcmFtOwoKICAgIFdDVVNFUl9EdW1wVGV4dE1ldHJpYyh0bSwgRm9udFR5cGUpOwogICAgaWYgKFdDVVNFUl9WYWxpZGF0ZUZvbnRNZXRyaWMoZmMtPmRhdGEsIHRtLCBGb250VHlwZSkpCiAgICB7CiAgICAgICAgTE9HRk9OVCBtbGYgPSAqbGY7CgogICAgICAgIC8qIFVzZSB0aGUgZGVmYXVsdCBzaXplcyBmb3IgdGhlIGZvbnQgKHRoaXMgaXMgbmVlZGVkLCBlc3BlY2lhbGx5IGZvcgogICAgICAgICAqIFRydWVUeXBlIGZvbnRzLCBzbyB0aGF0IHdlIGdldCBhIGRlY2VudCBzaXplLCBub3QgdGhlIG1heCBzaXplKQogICAgICAgICAqLwogICAgICAgIG1sZi5sZldpZHRoICA9IGZjLT5kYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgICAgICBtbGYubGZIZWlnaHQgPSBmYy0+ZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0OwogICAgICAgIGlmIChXQ1VTRVJfU2V0Rm9udChmYy0+ZGF0YSwgJm1sZikpCiAgICAgICAgewogICAgICAgICAgICBzdHJ1Y3QgICAgICBjb25maWdfZGF0YSAgICAgZGVmY2ZnOwoKICAgICAgICAgICAgV0NVU0VSX0R1bXBMb2dGb250KCJJbml0Q2hvb3Npbmc6ICIsICZtbGYsIEZvbnRUeXBlKTsKICAgICAgICAgICAgZmMtPmRvbmUgPSAxOwogICAgICAgICAgICAvKiBzaW5jZSB3ZSd2ZSBtb2RpZmllZCB0aGUgY3VycmVudCBjb25maWcgd2l0aCBuZXcgZm9udCBpbmZvcm1hdGlvbiwKICAgICAgICAgICAgICogc2V0IHRoaXMgaW5mb3JtYXRpb24gYXMgdGhlIG5ldyBkZWZhdWx0LgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgV0lORUNPTl9SZWdMb2FkKE5VTEwsICZkZWZjZmcpOwogICAgICAgICAgICBkZWZjZmcuY2VsbF93aWR0aCA9IGZjLT5kYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgICAgICAgICAgZGVmY2ZnLmNlbGxfaGVpZ2h0ID0gZmMtPmRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKICAgICAgICAgICAgbHN0cmNweVcoZGVmY2ZnLmZhY2VfbmFtZSwgZmMtPmRhdGEtPmN1cmNmZy5mYWNlX25hbWUpOwogICAgICAgICAgICAvKiBGb3JjZSBhbHNvIGl0cyB3cml0aW5nIGJhY2sgdG8gdGhlIHJlZ2lzdHJ5IHNvIHRoYXQgd2UgY2FuIGdldCBpdAogICAgICAgICAgICAgKiB0aGUgbmV4dCB0aW1lLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgV0lORUNPTl9SZWdTYXZlKCZkZWZjZmcpOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gMTsKfQoKc3RhdGljIGludCBDQUxMQkFDSyBnZXRfZmlyc3RfZm9udF9lbnVtKGNvbnN0IExPR0ZPTlQqIGxmLCBjb25zdCBURVhUTUVUUklDKiB0bSwKCQkJCQlEV09SRCBGb250VHlwZSwgTFBBUkFNIGxQYXJhbSkKewogICAgc3RydWN0IGZvbnRfY2hvb3NlcioJZmMgPSAoc3RydWN0IGZvbnRfY2hvb3NlciopbFBhcmFtOwoKICAgIFdDVVNFUl9EdW1wTG9nRm9udCgiSW5pdEZhbWlseTogIiwgbGYsIEZvbnRUeXBlKTsKICAgIGlmIChXQ1VTRVJfVmFsaWRhdGVGb250KGZjLT5kYXRhLCBsZikpCiAgICB7CglFbnVtRm9udEZhbWlsaWVzKFBSSVZBVEUoZmMtPmRhdGEpLT5oTWVtREMsIGxmLT5sZkZhY2VOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgZ2V0X2ZpcnN0X2ZvbnRfZW51bV8yLCBsUGFyYW0pOwoJcmV0dXJuICFmYy0+ZG9uZTsgLyogd2UganVzdCBuZWVkIHRoZSBmaXJzdCBtYXRjaGluZyBvbmUuLi4gKi8KICAgIH0KICAgIHJldHVybiAxOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfQ29weUZvbnQKICoKICogZ2V0IHRoZSByZWxldmFudCBpbmZvcm1hdGlvbiBmcm9tIHRoZSBmb250IGRlc2NyaWJlZCBpbiBsZiBhbmQgc3RvcmUgdGhlbQogKiBpbiBjb25maWcKICovCkhGT05UIFdDVVNFUl9Db3B5Rm9udChzdHJ1Y3QgY29uZmlnX2RhdGEqIGNvbmZpZywgSFdORCBoV25kLCBjb25zdCBMT0dGT05UKiBsZikKewogICAgVEVYVE1FVFJJQyAgdG07CiAgICBIREMgICAgICAgICBoREM7CiAgICBIRk9OVCAgICAgICBoRm9udCwgaE9sZEZvbnQ7CiAgICBpbnQgICAgICAgICB3LCBpLCBidWZbMjU2XTsKCiAgICBpZiAoIShoREMgPSBHZXREQyhoV25kKSkpIHJldHVybiBOVUxMOwogICAgaWYgKCEoaEZvbnQgPSBDcmVhdGVGb250SW5kaXJlY3QobGYpKSkgZ290byBlcnIxOwoKICAgIGhPbGRGb250ID0gU2VsZWN0T2JqZWN0KGhEQywgaEZvbnQpOwogICAgR2V0VGV4dE1ldHJpY3MoaERDLCAmdG0pOwoKICAgIC8qIEZJWE1FOgogICAgICogdGhlIGN1cnJlbnQgZnJlZXR5cGUgZW5naW5lIChhdCBsZWFzdCAyLjAueCB3aXRoIHggPD0gOCkgYW5kIGl0cyBpbXBsZW1lbnRhdGlvbgogICAgICogaW4gV2luZSBkb24ndCByZXR1cm4gYWRlcXVhdGUgdmFsdWVzIGZvciBmaXhlZCBmb250cwogICAgICogSW4gV2luZG93cywgdGhvc2UgZm9udHMgYXJlIGV4cGVjdGVkIHRvIHJldHVybiB0aGUgc2FtZSB2YWx1ZSBmb3IKICAgICAqICAtIHRoZSBhdmVyYWdlIHdpZHRoCiAgICAgKiAgLSB0aGUgbGFyZ2VzdCB3aWR0aAogICAgICogIC0gdGhlIHdpZHRoIG9mIGFsbCBjaGFyYWN0ZXJzIGluIHRoZSBmb250CiAgICAgKiBUaGlzIGlzbid0IHRydWUgaW4gV2luZS4gQXMgYSB0ZW1wb3Jhcnkgd29ya2Fyb3VuZCwgd2UgZ2V0IGFzIHRoZSB3aWR0aCBvZiB0aGUKICAgICAqIGNlbGwsIHRoZSB3aWR0aCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSBmb250LCBhZnRlciBjaGVja2luZyB0aGF0IGFsbAogICAgICogY2hhcmFjdGVycyBpbiB0aGUgZm9udCBoYXZlIHRoZSBzYW1lIHdpZHRoIChJIGhlYXIgcGFyYW5v72EgY29taW5nKQogICAgICogd2hlbiB0aGlzIGdldHMgZml4ZWQsIHRoZSBjb2RlIHNob3VsZCBiZSB1c2luZyB0bS50bUF2ZUNoYXJXaWR0aAogICAgICogb3IgdG0udG1NYXhDaGFyV2lkdGggYXMgdGhlIGNlbGwgd2lkdGguCiAgICAgKi8KICAgIEdldENoYXJXaWR0aDMyKGhEQywgdG0udG1GaXJzdENoYXIsIHRtLnRtRmlyc3RDaGFyLCAmdyk7CiAgICBmb3IgKGkgPSB0bS50bUZpcnN0Q2hhciArIDE7IGkgPD0gdG0udG1MYXN0Q2hhcjsgaSArPSBzaXplb2YoYnVmKSAvIHNpemVvZihidWZbMF0pKQogICAgewogICAgICAgIGludCBqLCBsOwoKICAgICAgICBsID0gbWluKHRtLnRtTGFzdENoYXIgLSBpLCBzaXplb2YoYnVmKSAvIHNpemVvZihidWZbMF0pIC0gMSk7CiAgICAgICAgR2V0Q2hhcldpZHRoMzIoaERDLCBpLCBpICsgbCwgYnVmKTsKICAgICAgICBmb3IgKGogPSAwOyBqIDw9IGw7IGorKykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChidWZbal0gIT0gdykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0lORV9XQVJOKCJOb24gdW5pZm9ybSBjZWxsIHdpZHRoOiBbJWRdPSVkIFslZF09JWRcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICAiVGhpcyBtYXkgYmUgY2F1c2VkIGJ5IG9sZCBmcmVldHlwZSBsaWJyYXJpZXMsID49IDIuMC44IGlzIHJlY29tbWVuZGVkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgIGkgKyBqLCBidWZbal0sIHRtLnRtRmlyc3RDaGFyLCB3KTsKICAgICAgICAgICAgICAgIGdvdG8gZXJyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgU2VsZWN0T2JqZWN0KGhEQywgaE9sZEZvbnQpOwogICAgUmVsZWFzZURDKGhXbmQsIGhEQyk7CgogICAgY29uZmlnLT5jZWxsX3dpZHRoICA9IHc7CiAgICBjb25maWctPmNlbGxfaGVpZ2h0ID0gdG0udG1IZWlnaHQgKyB0bS50bUV4dGVybmFsTGVhZGluZzsKICAgIGNvbmZpZy0+Zm9udF93ZWlnaHQgPSB0bS50bVdlaWdodDsKICAgIGxzdHJjcHkoY29uZmlnLT5mYWNlX25hbWUsIGxmLT5sZkZhY2VOYW1lKTsKCiAgICByZXR1cm4gaEZvbnQ7CiBlcnI6CiAgICBpZiAoaERDICYmIGhPbGRGb250KSBTZWxlY3RPYmplY3QoaERDLCBoT2xkRm9udCk7CiAgICBpZiAoaEZvbnQpIERlbGV0ZU9iamVjdChoRm9udCk7CiBlcnIxOgogICAgaWYgKGhEQykgUmVsZWFzZURDKGhXbmQsIGhEQyk7CgogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9GaWxsTG9nRm9udAogKgogKgogKi8Kdm9pZCAgICBXQ1VTRVJfRmlsbExvZ0ZvbnQoTE9HRk9OVCogbGYsIGNvbnN0IFdDSEFSKiBuYW1lLCBVSU5UIGhlaWdodCwgVUlOVCB3ZWlnaHQpCnsKICAgIGxmLT5sZkhlaWdodCAgICAgICAgPSBoZWlnaHQ7CiAgICBsZi0+bGZXaWR0aCAgICAgICAgID0gMDsKICAgIGxmLT5sZkVzY2FwZW1lbnQgICAgPSAwOwogICAgbGYtPmxmT3JpZW50YXRpb24gICA9IDA7CiAgICBsZi0+bGZXZWlnaHQgICAgICAgID0gd2VpZ2h0OwogICAgbGYtPmxmSXRhbGljICAgICAgICA9IEZBTFNFOwogICAgbGYtPmxmVW5kZXJsaW5lICAgICA9IEZBTFNFOwogICAgbGYtPmxmU3RyaWtlT3V0ICAgICA9IEZBTFNFOwogICAgbGYtPmxmQ2hhclNldCAgICAgICA9IERFRkFVTFRfQ0hBUlNFVDsKICAgIGxmLT5sZk91dFByZWNpc2lvbiAgPSBPVVRfREVGQVVMVF9QUkVDSVM7CiAgICBsZi0+bGZDbGlwUHJlY2lzaW9uID0gQ0xJUF9ERUZBVUxUX1BSRUNJUzsKICAgIGxmLT5sZlF1YWxpdHkgICAgICAgPSBERUZBVUxUX1FVQUxJVFk7CiAgICBsZi0+bGZQaXRjaEFuZEZhbWlseSA9IEZJWEVEX1BJVENIIHwgRkZfRE9OVENBUkU7CiAgICBsc3RyY3B5KGxmLT5sZkZhY2VOYW1lLCBuYW1lKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1NldEZvbnQKICoKICogc2V0cyBsb2dmb250IGFzIHRoZSBuZXcgZm9udCBmb3IgdGhlIGNvbnNvbGUKICovCkJPT0wJV0NVU0VSX1NldEZvbnQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIGNvbnN0IExPR0ZPTlQqIGxvZ2ZvbnQpCnsKICAgIEhGT05UICAgICAgIGhGb250OwoKICAgIGlmIChQUklWQVRFKGRhdGEpLT5oRm9udCAhPSAwICYmIFdDVVNFUl9BcmVGb250c0VxdWFsKCZkYXRhLT5jdXJjZmcsIGxvZ2ZvbnQpKQogICAgICAgIHJldHVybiBUUlVFOwoKICAgIGhGb250ID0gV0NVU0VSX0NvcHlGb250KCZkYXRhLT5jdXJjZmcsIFBSSVZBVEUoZGF0YSktPmhXbmQsIGxvZ2ZvbnQpOwogICAgaWYgKCFoRm9udCkge1dJTkVfRVJSKCJ3cm9uZyBmb250XG4iKTsgcmV0dXJuIEZBTFNFO30KCiAgICBpZiAoUFJJVkFURShkYXRhKS0+aEZvbnQpIERlbGV0ZU9iamVjdChQUklWQVRFKGRhdGEpLT5oRm9udCk7CiAgICBQUklWQVRFKGRhdGEpLT5oRm9udCA9IGhGb250OwoKICAgIFdDVVNFUl9Db21wdXRlUG9zaXRpb25zKGRhdGEpOwogICAgV0NVU0VSX05ld0JpdG1hcChkYXRhKTsKICAgIEludmFsaWRhdGVSZWN0KFBSSVZBVEUoZGF0YSktPmhXbmQsIE5VTEwsIEZBTFNFKTsKICAgIFVwZGF0ZVdpbmRvdyhQUklWQVRFKGRhdGEpLT5oV25kKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1NldEZvbnRQbXQKICoKICogU2V0cyBhIG5ldyBmb250IGZvciB0aGUgY29uc29sZS4KICogSW4gZmFjdCBhIHdyYXBwZXIgZm9yIFdDVVNFUl9TZXRGb250CiAqLwpzdGF0aWMgdm9pZCAgICAgV0NVU0VSX1NldEZvbnRQbXQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIGNvbnN0IFdDSEFSKiBmb250LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgaGVpZ2h0LCB1bnNpZ25lZCB3ZWlnaHQpCnsKICAgIExPR0ZPTlQgICAgICAgICAgICAgbGY7CiAgICBzdHJ1Y3QgZm9udF9jaG9vc2VyIGZjOwoKICAgIFdJTkVfVFJBQ0VfKHdjX2ZvbnQpKCI9PiAlcyBoPSV1IHc9JXVcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICB3aW5lX2RiZ3N0cl93bihmb250LCAtMSksIGhlaWdodCwgd2VpZ2h0KTsKCiAgICBpZiAoZm9udFswXSAhPSAnXDAnICYmIGhlaWdodCAhPSAwICYmIHdlaWdodCAhPSAwKQogICAgewogICAgICAgIFdDVVNFUl9GaWxsTG9nRm9udCgmbGYsIGZvbnQsIGhlaWdodCwgd2VpZ2h0KTsKICAgICAgICBpZiAoV0NVU0VSX1NldEZvbnQoZGF0YSwgJmxmKSkKICAgICAgICB7CiAgICAgICAgICAgIFdDVVNFUl9EdW1wTG9nRm9udCgiSW5pdFJldXNlczogIiwgJmxmLCAwKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAvKiB0cnkgdG8gZmluZCBhbiBhY2NlcHRhYmxlIGZvbnQgKi8KICAgIFdJTkVfV0FSTigiQ291bGRuJ3QgbWF0Y2ggdGhlIGZvbnQgZnJvbSByZWdpc3RyeS4uLiB0cnlpbmcgdG8gZmluZCBvbmVcbiIpOwogICAgZmMuZGF0YSA9IGRhdGE7CiAgICBmYy5kb25lID0gMDsKICAgIEVudW1Gb250RmFtaWxpZXMoUFJJVkFURShkYXRhKS0+aE1lbURDLCBOVUxMLCBnZXRfZmlyc3RfZm9udF9lbnVtLCAoTFBBUkFNKSZmYyk7CiAgICBpZiAoIWZjLmRvbmUpIFdJTkVDT05fRmF0YWwoIkNvdWxkbid0IGZpbmQgYSBkZWNlbnQgZm9udCwgYWJvcnRpbmdcbiIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfR2V0Q2VsbAogKgogKiBHZXQgYSBjZWxsIGZyb20gYSByZWxhdGl2ZSBjb29yZGluYXRlIGluIHdpbmRvdyAodGFrZXMgaW50bwogKiBhY2NvdW50IHRoZSBzY3JvbGxpbmcpCiAqLwpzdGF0aWMgQ09PUkQJV0NVU0VSX0dldENlbGwoY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIExQQVJBTSBsUGFyYW0pCnsKICAgIENPT1JECWM7CgogICAgYy5YID0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWCArIChzaG9ydClMT1dPUkQobFBhcmFtKSAvIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoOwogICAgYy5ZID0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSArIChzaG9ydClISVdPUkQobFBhcmFtKSAvIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKCiAgICByZXR1cm4gYzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0dldFNlbGVjdGlvblJlY3QKICoKICogR2V0IHRoZSBzZWxlY3Rpb24gcmVjdGFuZ2xlCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfR2V0U2VsZWN0aW9uUmVjdChjb25zdCBzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgTFBSRUNUIHIpCnsKICAgIHItPmxlZnQgICA9IChtaW4oUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlgsIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5YKSAgICAgLSBkYXRhLT5jdXJjZmcud2luX3Bvcy5YKSAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoOwogICAgci0+dG9wICAgID0gKG1pbihQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWSwgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlkpICAgICAtIGRhdGEtPmN1cmNmZy53aW5fcG9zLlkpICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0OwogICAgci0+cmlnaHQgID0gKG1heChQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWCwgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlgpICsgMSAtIGRhdGEtPmN1cmNmZy53aW5fcG9zLlgpICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGg7CiAgICByLT5ib3R0b20gPSAobWF4KFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MS5ZLCBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIuWSkgKyAxIC0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSkgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9TZXRTZWxlY3Rpb24KICoKICoKICovCnN0YXRpYyB2b2lkCVdDVVNFUl9TZXRTZWxlY3Rpb24oY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIEhEQyBoUmVmREMpCnsKICAgIEhEQwkJaERDOwogICAgUkVDVAlyOwoKICAgIFdDVVNFUl9HZXRTZWxlY3Rpb25SZWN0KGRhdGEsICZyKTsKICAgIGhEQyA9IGhSZWZEQyA/IGhSZWZEQyA6IEdldERDKFBSSVZBVEUoZGF0YSktPmhXbmQpOwogICAgaWYgKGhEQykKICAgIHsKCWlmIChQUklWQVRFKGRhdGEpLT5oV25kID09IEdldEZvY3VzKCkgJiYgZGF0YS0+Y3VyY2ZnLmN1cnNvcl92aXNpYmxlKQoJICAgIEhpZGVDYXJldChQUklWQVRFKGRhdGEpLT5oV25kKTsKCUludmVydFJlY3QoaERDLCAmcik7CglpZiAoaERDICE9IGhSZWZEQykKCSAgICBSZWxlYXNlREMoUFJJVkFURShkYXRhKS0+aFduZCwgaERDKTsKCWlmIChQUklWQVRFKGRhdGEpLT5oV25kID09IEdldEZvY3VzKCkgJiYgZGF0YS0+Y3VyY2ZnLmN1cnNvcl92aXNpYmxlKQoJICAgIFNob3dDYXJldChQUklWQVRFKGRhdGEpLT5oV25kKTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX01vdmVTZWxlY3Rpb24KICoKICoKICovCnN0YXRpYyB2b2lkCVdDVVNFUl9Nb3ZlU2VsZWN0aW9uKHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBDT09SRCBjMSwgQ09PUkQgYzIpCnsKICAgIFJFQ1QJcjsKICAgIEhEQwkJaERDOwoKICAgIGlmIChjMS5YIDwgMCB8fCBjMS5YID49IGRhdGEtPmN1cmNmZy5zYl93aWR0aCB8fAogICAgICAgIGMyLlggPCAwIHx8IGMyLlggPj0gZGF0YS0+Y3VyY2ZnLnNiX3dpZHRoIHx8CiAgICAgICAgYzEuWSA8IDAgfHwgYzEuWSA+PSBkYXRhLT5jdXJjZmcuc2JfaGVpZ2h0IHx8CiAgICAgICAgYzIuWSA8IDAgfHwgYzIuWSA+PSBkYXRhLT5jdXJjZmcuc2JfaGVpZ2h0KQogICAgICAgIHJldHVybjsKCiAgICBXQ1VTRVJfR2V0U2VsZWN0aW9uUmVjdChkYXRhLCAmcik7CiAgICBoREMgPSBHZXREQyhQUklWQVRFKGRhdGEpLT5oV25kKTsKICAgIGlmIChoREMpCiAgICB7CglpZiAoUFJJVkFURShkYXRhKS0+aFduZCA9PSBHZXRGb2N1cygpICYmIGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKCSAgICBIaWRlQ2FyZXQoUFJJVkFURShkYXRhKS0+aFduZCk7CglJbnZlcnRSZWN0KGhEQywgJnIpOwogICAgfQogICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxID0gYzE7CiAgICBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIgPSBjMjsKICAgIGlmIChoREMpCiAgICB7CglXQ1VTRVJfR2V0U2VsZWN0aW9uUmVjdChkYXRhLCAmcik7CglJbnZlcnRSZWN0KGhEQywgJnIpOwoJUmVsZWFzZURDKFBSSVZBVEUoZGF0YSktPmhXbmQsIGhEQyk7CglpZiAoUFJJVkFURShkYXRhKS0+aFduZCA9PSBHZXRGb2N1cygpICYmIGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKCSAgICBTaG93Q2FyZXQoUFJJVkFURShkYXRhKS0+aFduZCk7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9Db3B5U2VsZWN0aW9uVG9DbGlwYm9hcmQKICoKICogQ29waWVzIHRoZSBjdXJyZW50IHNlbGVjdGlvbiBpbnRvIHRoZSBjbGlwYm9hcmQKICovCnN0YXRpYyB2b2lkCVdDVVNFUl9Db3B5U2VsZWN0aW9uVG9DbGlwYm9hcmQoY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIEhBTkRMRQloTWVtOwogICAgTFBXU1RSCXA7CiAgICB1bnNpZ25lZAl3LCBoOwoKICAgIHcgPSBhYnMoUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlggLSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIuWCkgKyAyOwogICAgaCA9IGFicyhQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWSAtIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5ZKSArIDE7CgogICAgaWYgKCFPcGVuQ2xpcGJvYXJkKFBSSVZBVEUoZGF0YSktPmhXbmQpKSByZXR1cm47CiAgICBFbXB0eUNsaXBib2FyZCgpOwoKICAgIGhNZW0gPSBHbG9iYWxBbGxvYyhHTUVNX01PVkVBQkxFLCAodyAqIGgpICogc2l6ZW9mKFdDSEFSKSk7CiAgICBpZiAoaE1lbSAmJiAocCA9IEdsb2JhbExvY2soaE1lbSkpKQogICAgewoJQ09PUkQJYzsKCWludAl5OwoKCWMuWCA9IG1pbihQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWCwgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlgpOwoJYy5ZID0gbWluKFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MS5ZLCBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIuWSk7CgoJZm9yICh5ID0gMDsgeSA8IGg7IHkrKywgYy5ZKyspCgl7CgkgICAgUmVhZENvbnNvbGVPdXRwdXRDaGFyYWN0ZXIoZGF0YS0+aENvbk91dCwgJnBbeSAqIHddLCB3IC0gMSwgYywgTlVMTCk7CgkgICAgcFt5ICogdyArIHcgLSAxXSA9ICh5IDwgaCAtIDEpID8gJ1xuJyA6ICdcMCc7Cgl9CglHbG9iYWxVbmxvY2soaE1lbSk7CglTZXRDbGlwYm9hcmREYXRhKENGX1VOSUNPREVURVhULCBoTWVtKTsKICAgIH0KICAgIENsb3NlQ2xpcGJvYXJkKCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9QYXN0ZUZyb21DbGlwYm9hcmQKICoKICoKICovCnN0YXRpYyB2b2lkCVdDVVNFUl9QYXN0ZUZyb21DbGlwYm9hcmQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIEhBTkRMRQloOwogICAgV0NIQVIqCXB0cjsKCiAgICBpZiAoIU9wZW5DbGlwYm9hcmQoUFJJVkFURShkYXRhKS0+aFduZCkpIHJldHVybjsKICAgIGggPSBHZXRDbGlwYm9hcmREYXRhKENGX1VOSUNPREVURVhUKTsKICAgIGlmIChoICYmIChwdHIgPSBHbG9iYWxMb2NrKGgpKSkKICAgIHsKCWludAkJaSwgbGVuID0gR2xvYmFsU2l6ZShoKSAvIHNpemVvZihXQ0hBUik7CglJTlBVVF9SRUNPUkQJaXJbMl07CglEV09SRAkJbjsKCVNIT1JUCQlzaDsKCglpclswXS5FdmVudFR5cGUgPSBLRVlfRVZFTlQ7CglpclswXS5FdmVudC5LZXlFdmVudC53UmVwZWF0Q291bnQgPSAwOwoJaXJbMF0uRXZlbnQuS2V5RXZlbnQuZHdDb250cm9sS2V5U3RhdGUgPSAwOwoJaXJbMF0uRXZlbnQuS2V5RXZlbnQuYktleURvd24gPSBUUlVFOwoKCS8qIGdlbmVyYXRlIHRoZSBjb3JyZXNwb25kaW5nIGlucHV0IHJlY29yZHMgKi8KCWZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykKCXsKCSAgICAvKiBGSVhNRTogdGhlIG1vZGlmeWluZyBrZXlzIGFyZSBub3QgZ2VuZXJhdGVkIChzaGlmdCwgY3RybC4uLikgKi8KCSAgICBzaCA9IFZrS2V5U2NhbihwdHJbaV0pOwoJICAgIGlyWzBdLkV2ZW50LktleUV2ZW50LndWaXJ0dWFsS2V5Q29kZSA9IExPQllURShzaCk7CgkgICAgaXJbMF0uRXZlbnQuS2V5RXZlbnQud1ZpcnR1YWxTY2FuQ29kZSA9IE1hcFZpcnR1YWxLZXkoTE9CWVRFKHNoKSwgMCk7CgkgICAgaXJbMF0uRXZlbnQuS2V5RXZlbnQudUNoYXIuVW5pY29kZUNoYXIgPSBwdHJbaV07CgoJICAgIGlyWzFdID0gaXJbMF07CgkgICAgaXJbMV0uRXZlbnQuS2V5RXZlbnQuYktleURvd24gPSBGQUxTRTsKCgkgICAgV3JpdGVDb25zb2xlSW5wdXQoZGF0YS0+aENvbkluLCBpciwgMiwgJm4pOwoJfQoJR2xvYmFsVW5sb2NrKGgpOwogICAgfQogICAgQ2xvc2VDbGlwYm9hcmQoKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1JlZnJlc2gKICoKICoKICovCnN0YXRpYyB2b2lkIFdDVVNFUl9SZWZyZXNoKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBpbnQgdHAsIGludCBibSkKewogICAgV0NVU0VSX0ZpbGxNZW1EQyhkYXRhLCB0cCwgYm0pOwogICAgaWYgKGRhdGEtPmN1cmNmZy53aW5fcG9zLlkgPD0gYm0gJiYgZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSArIGRhdGEtPmN1cmNmZy53aW5faGVpZ2h0ID49IHRwKQogICAgewoJUkVDVAlyOwoKCXIubGVmdCAgID0gMDsKCXIucmlnaHQgID0gZGF0YS0+Y3VyY2ZnLndpbl93aWR0aCAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoOwoJci50b3AgICAgPSAodHAgLSBkYXRhLT5jdXJjZmcud2luX3Bvcy5ZKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKCXIuYm90dG9tID0gKGJtIC0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSArIDEpICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0OwoJSW52YWxpZGF0ZVJlY3QoUFJJVkFURShkYXRhKS0+aFduZCwgJnIsIEZBTFNFKTsKCVVwZGF0ZVdpbmRvdyhQUklWQVRFKGRhdGEpLT5oV25kKTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1BhaW50CiAqCiAqCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfUGFpbnQoY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIFBBSU5UU1RSVUNUCQlwczsKCiAgICBCZWdpblBhaW50KFBSSVZBVEUoZGF0YSktPmhXbmQsICZwcyk7CiAgICBCaXRCbHQocHMuaGRjLCAwLCAwLAogICAgICAgICAgIGRhdGEtPmN1cmNmZy53aW5fd2lkdGggKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwKICAgICAgICAgICBkYXRhLT5jdXJjZmcud2luX2hlaWdodCAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCwKCSAgIFBSSVZBVEUoZGF0YSktPmhNZW1EQywKICAgICAgICAgICBkYXRhLT5jdXJjZmcud2luX3Bvcy5YICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGgsCiAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCwKCSAgIFNSQ0NPUFkpOwogICAgaWYgKFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24pCglXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIHBzLmhkYyk7CiAgICBFbmRQYWludChQUklWQVRFKGRhdGEpLT5oV25kLCAmcHMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfU2Nyb2xsCiAqCiAqCiAqLwpzdGF0aWMgdm9pZCBXQ1VTRVJfU2Nyb2xsKHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBpbnQgcG9zLCBCT09MIGhvcnopCnsKICAgIGlmIChob3J6KQogICAgewoJU2V0U2Nyb2xsUG9zKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX0hPUlosIHBvcywgVFJVRSk7CglkYXRhLT5jdXJjZmcud2luX3Bvcy5YID0gcG9zOwogICAgfQogICAgZWxzZQogICAgewoJU2V0U2Nyb2xsUG9zKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX1ZFUlQsIHBvcywgVFJVRSk7CglkYXRhLT5jdXJjZmcud2luX3Bvcy5ZID0gcG9zOwogICAgfQogICAgSW52YWxpZGF0ZVJlY3QoUFJJVkFURShkYXRhKS0+aFduZCwgTlVMTCwgRkFMU0UpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfRmlsbE1lbnUKICoKICoKICovCnN0YXRpYyBCT09MIFdDVVNFUl9GaWxsTWVudShITUVOVSBoTWVudSwgQk9PTCBzZXApCnsKICAgIEhNRU5VCQloU3ViTWVudTsKICAgIEhJTlNUQU5DRQkJaEluc3RhbmNlID0gR2V0TW9kdWxlSGFuZGxlKE5VTEwpOwogICAgV0NIQVIJCWJ1ZmZbMjU2XTsKCiAgICBpZiAoIWhNZW51KSByZXR1cm4gRkFMU0U7CgogICAgLyogRklYTUU6IGVycm9yIGhhbmRsaW5nICYgbWVtb3J5IGNsZWFudXAgKi8KICAgIGhTdWJNZW51ID0gQ3JlYXRlTWVudSgpOwogICAgaWYgKCFoU3ViTWVudSkgcmV0dXJuIEZBTFNFOwoKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfTUFSSywgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhTdWJNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkcsIElEU19NQVJLLCBidWZmKTsKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfQ09QWSwgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhTdWJNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkcsIElEU19DT1BZLCBidWZmKTsKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfUEFTVEUsIGJ1ZmYsIHNpemVvZihidWZmKSAvIHNpemVvZihXQ0hBUikpOwogICAgSW5zZXJ0TWVudShoU3ViTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU1RSSU5HLCBJRFNfUEFTVEUsIGJ1ZmYpOwogICAgTG9hZFN0cmluZyhoSW5zdGFuY2UsIElEU19TRUxFQ1RBTEwsIGJ1ZmYsIHNpemVvZihidWZmKSAvIHNpemVvZihXQ0hBUikpOwogICAgSW5zZXJ0TWVudShoU3ViTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU1RSSU5HLCBJRFNfU0VMRUNUQUxMLCBidWZmKTsKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfU0NST0xMLCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaFN1Yk1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklORywgSURTX1NDUk9MTCwgYnVmZik7CiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX1NFQVJDSCwgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhTdWJNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkcsIElEU19TRUFSQ0gsIGJ1ZmYpOwoKICAgIGlmIChzZXApIEluc2VydE1lbnUoaE1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NFUEFSQVRPUiwgMCwgTlVMTCk7CiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX0VESVQsIGJ1ZmYsIHNpemVvZihidWZmKSAvIHNpemVvZihXQ0hBUikpOwogICAgSW5zZXJ0TWVudShoTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU1RSSU5HfE1GX1BPUFVQLCAoVUlOVF9QVFIpaFN1Yk1lbnUsIGJ1ZmYpOwogICAgTG9hZFN0cmluZyhoSW5zdGFuY2UsIElEU19ERUZBVUxULCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaE1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklORywgSURTX0RFRkFVTFQsIGJ1ZmYpOwogICAgTG9hZFN0cmluZyhoSW5zdGFuY2UsIElEU19QUk9QRVJUSUVTLCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaE1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklORywgSURTX1BST1BFUlRJRVMsIGJ1ZmYpOwoKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfU2V0TWVudURldGFpbHMKICoKICogR3JheXMgLyB1bmdyYXlzIHRoZSBtZW51IGl0ZW1zIGFjY29yZGluZyB0byB0aGVpciBzdGF0ZQogKi8Kc3RhdGljIHZvaWQJV0NVU0VSX1NldE1lbnVEZXRhaWxzKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBITUVOVSBoTWVudSkKewogICAgaWYgKCFoTWVudSkge1dJTkVfRVJSKCJJc3N1ZSBpbiBnZXR0aW5nIG1lbnUgYml0c1xuIik7cmV0dXJuO30KCiAgICBFbmFibGVNZW51SXRlbShoTWVudSwgSURTX0NPUFksCiAgICAgICAgICAgICAgICAgICBNRl9CWUNPTU1BTkR8KFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24gPyBNRl9FTkFCTEVEIDogTUZfR1JBWUVEKSk7CiAgICBFbmFibGVNZW51SXRlbShoTWVudSwgSURTX1BBU1RFLAoJCSAgIE1GX0JZQ09NTUFORHwoSXNDbGlwYm9hcmRGb3JtYXRBdmFpbGFibGUoQ0ZfVU5JQ09ERVRFWFQpCgkJCQkgPyBNRl9FTkFCTEVEIDogTUZfR1JBWUVEKSk7CiAgICBFbmFibGVNZW51SXRlbShoTWVudSwgSURTX1NDUk9MTCwgTUZfQllDT01NQU5EfE1GX0dSQVlFRCk7CiAgICBFbmFibGVNZW51SXRlbShoTWVudSwgSURTX1NFQVJDSCwgTUZfQllDT01NQU5EfE1GX0dSQVlFRCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9DcmVhdGUKICoKICogQ3JlYXRlcyB0aGUgd2luZG93IGZvciB0aGUgcmVuZGVyaW5nCiAqLwpzdGF0aWMgTFJFU1VMVCBXQ1VTRVJfQ3JlYXRlKEhXTkQgaFduZCwgTFBDUkVBVEVTVFJVQ1QgbHBjcykKewogICAgc3RydWN0IGlubmVyX2RhdGEqCWRhdGE7CiAgICBITUVOVQkJaFN5c01lbnU7CgogICAgZGF0YSA9IGxwY3MtPmxwQ3JlYXRlUGFyYW1zOwogICAgU2V0V2luZG93TG9uZyhoV25kLCAwTCwgKERXT1JEKWRhdGEpOwogICAgUFJJVkFURShkYXRhKS0+aFduZCA9IGhXbmQ7CgogICAgaFN5c01lbnUgPSBHZXRTeXN0ZW1NZW51KGhXbmQsIEZBTFNFKTsKICAgIGlmICghaFN5c01lbnUpIHJldHVybiAwOwogICAgUFJJVkFURShkYXRhKS0+aFBvcE1lbnUgPSBDcmVhdGVQb3B1cE1lbnUoKTsKICAgIGlmICghUFJJVkFURShkYXRhKS0+aFBvcE1lbnUpIHJldHVybiAwOwoKICAgIFdDVVNFUl9GaWxsTWVudShoU3lzTWVudSwgVFJVRSk7CiAgICBXQ1VTRVJfRmlsbE1lbnUoUFJJVkFURShkYXRhKS0+aFBvcE1lbnUsIEZBTFNFKTsKCiAgICBQUklWQVRFKGRhdGEpLT5oTWVtREMgPSBDcmVhdGVDb21wYXRpYmxlREMoMCk7CiAgICBpZiAoIVBSSVZBVEUoZGF0YSktPmhNZW1EQykge1dJTkVfRVJSKCJubyBtZW0gZGNcbiIpO3JldHVybiAwO30KCiAgICBkYXRhLT5jdXJjZmcucXVpY2tfZWRpdCA9IEZBTFNFOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9HZXRDdHJsS2V5U3RhdGUKICoKICogR2V0IHRoZSBjb25zb2xlIGJpdCBtYXNrIGVxdWl2YWxlbnQgdG8gdGhlIFZLXyBzdGF0dXMgaW4ga2V5U3RhdGUKICovCnN0YXRpYyBEV09SRCAgICBXQ1VTRVJfR2V0Q3RybEtleVN0YXRlKEJZVEUqIGtleVN0YXRlKQp7CiAgICBEV09SRCAgICAgICAgICAgICAgIHJldCA9IDA7CgogICAgR2V0S2V5Ym9hcmRTdGF0ZShrZXlTdGF0ZSk7CiAgICBpZiAoa2V5U3RhdGVbVktfU0hJRlRdICAgICYgMHg4MCkJcmV0IHw9IFNISUZUX1BSRVNTRUQ7CiAgICBpZiAoa2V5U3RhdGVbVktfTENPTlRST0xdICYgMHg4MCkJcmV0IHw9IExFRlRfQ1RSTF9QUkVTU0VEOwogICAgaWYgKGtleVN0YXRlW1ZLX1JDT05UUk9MXSAmIDB4ODApCXJldCB8PSBSSUdIVF9DVFJMX1BSRVNTRUQ7CiAgICBpZiAoa2V5U3RhdGVbVktfTE1FTlVdICAgICYgMHg4MCkJcmV0IHw9IExFRlRfQUxUX1BSRVNTRUQ7CiAgICBpZiAoa2V5U3RhdGVbVktfUk1FTlVdICAgICYgMHg4MCkJcmV0IHw9IFJJR0hUX0FMVF9QUkVTU0VEOwogICAgaWYgKGtleVN0YXRlW1ZLX0NBUElUQUxdICAmIDB4MDEpCXJldCB8PSBDQVBTTE9DS19PTjsKICAgIGlmIChrZXlTdGF0ZVtWS19OVU1MT0NLXSAgJiAweDAxKQlyZXQgfD0gTlVNTE9DS19PTjsKICAgIGlmIChrZXlTdGF0ZVtWS19TQ1JPTExdICAgJiAweDAxKQlyZXQgfD0gU0NST0xMTE9DS19PTjsKCiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfSGFuZGxlU2VsZWN0aW9uS2V5CiAqCiAqIEhhbmRsZXMga2V5cyB3aGlsZSBzZWxlY3RpbmcgYW4gYXJlYQogKi8Kc3RhdGljIHZvaWQgV0NVU0VSX0hhbmRsZVNlbGVjdGlvbktleShzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgQk9PTCBkb3duLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pCnsKICAgIEJZVEUJa2V5U3RhdGVbMjU2XTsKICAgIERXT1JEICAgICAgIHN0YXRlID0gV0NVU0VSX0dldEN0cmxLZXlTdGF0ZShrZXlTdGF0ZSkgJiB+KENBUFNMT0NLX09OfE5VTUxPQ0tfT058U0NST0xMTE9DS19PTik7CiAgICBDT09SRCAgICAgICBjMSwgYzI7CgogICAgaWYgKGRvd24pIHJldHVybjsKCiAgICBzd2l0Y2ggKHN0YXRlKQogICAgewogICAgY2FzZSAwOgogICAgICAgIHN3aXRjaCAod1BhcmFtKQogICAgICAgIHsKICAgICAgICBjYXNlIFZLX1JFVFVSTjoKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiA9IEZBTFNFOwogICAgICAgICAgICBXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIDApOwogICAgICAgICAgICBXQ1VTRVJfQ29weVNlbGVjdGlvblRvQ2xpcGJvYXJkKGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFZLX1JJR0hUOgogICAgICAgICAgICBjMSA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MTsKICAgICAgICAgICAgYzIgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDI7CiAgICAgICAgICAgIGMxLlgrKzsgYzIuWCsrOwogICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFZLX0xFRlQ6CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzEuWC0tOyBjMi5YLS07CiAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVktfVVA6CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzEuWS0tOyBjMi5ZLS07CiAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVktfRE9XTjoKICAgICAgICAgICAgYzEgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDE7CiAgICAgICAgICAgIGMyID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyOwogICAgICAgICAgICBjMS5ZKys7IGMyLlkrKzsKICAgICAgICAgICAgV0NVU0VSX01vdmVTZWxlY3Rpb24oZGF0YSwgYzEsIGMyKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBTSElGVF9QUkVTU0VEOgogICAgICAgIHN3aXRjaCAod1BhcmFtKQogICAgICAgIHsKICAgICAgICBjYXNlIFZLX1JJR0hUOgogICAgICAgICAgICBjMSA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MTsKICAgICAgICAgICAgYzIgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDI7CiAgICAgICAgICAgIGMyLlgrKzsKICAgICAgICAgICAgV0NVU0VSX01vdmVTZWxlY3Rpb24oZGF0YSwgYzEsIGMyKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBWS19MRUZUOgogICAgICAgICAgICBjMSA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MTsKICAgICAgICAgICAgYzIgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDI7CiAgICAgICAgICAgIGMyLlgtLTsKICAgICAgICAgICAgV0NVU0VSX01vdmVTZWxlY3Rpb24oZGF0YSwgYzEsIGMyKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBWS19VUDoKICAgICAgICAgICAgYzEgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDE7CiAgICAgICAgICAgIGMyID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyOwogICAgICAgICAgICBjMi5ZLS07CiAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVktfRE9XTjoKICAgICAgICAgICAgYzEgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDE7CiAgICAgICAgICAgIGMyID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyOwogICAgICAgICAgICBjMi5ZKys7CiAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0dlbmVyYXRlS2V5SW5wdXRSZWNvcmQKICoKICogZ2VuZXJhdGVzIGlucHV0X3JlY29yZCBmcm9tIHdpbmRvd3MgV01fS0VZVVAvV01fS0VZRE9XTiBtZXNzYWdlcwogKi8Kc3RhdGljIHZvaWQgICAgV0NVU0VSX0dlbmVyYXRlS2V5SW5wdXRSZWNvcmQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIEJPT0wgZG93biwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSwgQk9PTCBzeXMpCnsKICAgIElOUFVUX1JFQ09SRAlpcjsKICAgIERXT1JECQluOwogICAgV0NIQVIJCWJ1ZlsyXTsKICAgIHN0YXRpYwlXQ0hBUglsYXN0OyAvKiBrZWVwIGxhc3QgY2hhciBzZWVuIGFzIGZlZWQgZm9yIGtleSB1cCBtZXNzYWdlICovCiAgICBCWVRFCQlrZXlTdGF0ZVsyNTZdOwoKICAgIGlyLkV2ZW50VHlwZSA9IEtFWV9FVkVOVDsKICAgIGlyLkV2ZW50LktleUV2ZW50LmJLZXlEb3duID0gZG93bjsKICAgIGlyLkV2ZW50LktleUV2ZW50LndSZXBlYXRDb3VudCA9IExPV09SRChsUGFyYW0pOwogICAgaXIuRXZlbnQuS2V5RXZlbnQud1ZpcnR1YWxLZXlDb2RlID0gd1BhcmFtOwoKICAgIGlyLkV2ZW50LktleUV2ZW50LndWaXJ0dWFsU2NhbkNvZGUgPSBISVdPUkQobFBhcmFtKSAmIDB4RkY7CgogICAgaXIuRXZlbnQuS2V5RXZlbnQudUNoYXIuVW5pY29kZUNoYXIgPSAwOwogICAgaXIuRXZlbnQuS2V5RXZlbnQuZHdDb250cm9sS2V5U3RhdGUgPSBXQ1VTRVJfR2V0Q3RybEtleVN0YXRlKGtleVN0YXRlKTsKICAgIGlmIChsUGFyYW0gJiAoMUwgPDwgMjQpKQkJaXIuRXZlbnQuS2V5RXZlbnQuZHdDb250cm9sS2V5U3RhdGUgfD0gRU5IQU5DRURfS0VZOwogICAgaWYgKHN5cykJCQkJaXIuRXZlbnQuS2V5RXZlbnQuZHdDb250cm9sS2V5U3RhdGUgfD0gTEVGVF9BTFRfUFJFU1NFRDsgLyogRklYTUU6IGdvdHRhIGNob29zZSBvbmUgKi8KCiAgICBpZiAoIShpci5FdmVudC5LZXlFdmVudC5kd0NvbnRyb2xLZXlTdGF0ZSAmIEVOSEFOQ0VEX0tFWSkpCiAgICB7CglpZiAoZG93bikKCXsKCSAgICBzd2l0Y2ggKFRvVW5pY29kZSh3UGFyYW0sIEhJV09SRChsUGFyYW0pLCBrZXlTdGF0ZSwgYnVmLCAyLCAwKSkKCSAgICB7CgkgICAgY2FzZSAyOgoJCS8qIEZJWE1FLi4uIHNob3VsZCBnZW5lcmF0ZSB0d28gZXZlbnRzLi4uICovCgkJLyogZmFsbCB0aHJ1ICovCgkgICAgY2FzZSAxOgoJCWxhc3QgPSBidWZbMF07CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlsYXN0ID0gMDsKCQlicmVhazsKCSAgICB9Cgl9Cglpci5FdmVudC5LZXlFdmVudC51Q2hhci5Vbmljb2RlQ2hhciA9IGxhc3Q7IC8qIEZJWE1FIEhBQ0tZLi4uIGFuZCBidWdneSAnY296IGl0IHNob3VsZCBiZSBhIHN0YWNrLCBub3QgYSBzaW5nbGUgdmFsdWUgKi8KCWlmICghZG93bikgbGFzdCA9IDA7CiAgICB9CgogICAgV3JpdGVDb25zb2xlSW5wdXQoZGF0YS0+aENvbkluLCAmaXIsIDEsICZuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0dlbmVyYXRlTW91c2VJbnB1dFJlY29yZAogKgogKgogKi8Kc3RhdGljIHZvaWQgICAgV0NVU0VSX0dlbmVyYXRlTW91c2VJbnB1dFJlY29yZChzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgQ09PUkQgYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXUEFSQU0gd1BhcmFtLCBEV09SRCBldmVudCkKewogICAgSU5QVVRfUkVDT1JECWlyOwogICAgQllURQkJa2V5U3RhdGVbMjU2XTsKICAgIERXT1JEICAgICAgICAgICAgICAgbW9kZSwgbjsKCiAgICAvKiBNT1VTRV9FVkVOVHMgc2hvdWxkbid0IGJlIHNlbnQgdW5sZXNzIEVOQUJMRV9NT1VTRV9JTlBVVCBpcyBhY3RpdmUgKi8KICAgIGlmICghR2V0Q29uc29sZU1vZGUoZGF0YS0+aENvbkluLCAmbW9kZSkgfHwgIShtb2RlICYgRU5BQkxFX01PVVNFX0lOUFVUKSkKICAgICAgICByZXR1cm47CgogICAgaXIuRXZlbnRUeXBlID0gTU9VU0VfRVZFTlQ7CiAgICBpci5FdmVudC5Nb3VzZUV2ZW50LmR3TW91c2VQb3NpdGlvbiA9IGM7CiAgICBpci5FdmVudC5Nb3VzZUV2ZW50LmR3QnV0dG9uU3RhdGUgPSAwOwogICAgaWYgKHdQYXJhbSAmIE1LX0xCVVRUT04pIGlyLkV2ZW50Lk1vdXNlRXZlbnQuZHdCdXR0b25TdGF0ZSB8PSBGUk9NX0xFRlRfMVNUX0JVVFRPTl9QUkVTU0VEOwogICAgaWYgKHdQYXJhbSAmIE1LX01CVVRUT04pIGlyLkV2ZW50Lk1vdXNlRXZlbnQuZHdCdXR0b25TdGF0ZSB8PSBGUk9NX0xFRlRfMk5EX0JVVFRPTl9QUkVTU0VEOwogICAgaWYgKHdQYXJhbSAmIE1LX1JCVVRUT04pIGlyLkV2ZW50Lk1vdXNlRXZlbnQuZHdCdXR0b25TdGF0ZSB8PSBSSUdIVE1PU1RfQlVUVE9OX1BSRVNTRUQ7CiAgICBpci5FdmVudC5Nb3VzZUV2ZW50LmR3Q29udHJvbEtleVN0YXRlID0gV0NVU0VSX0dldEN0cmxLZXlTdGF0ZShrZXlTdGF0ZSk7CiAgICBpci5FdmVudC5Nb3VzZUV2ZW50LmR3RXZlbnRGbGFncyA9IGV2ZW50OwoKICAgIFdyaXRlQ29uc29sZUlucHV0KGRhdGEtPmhDb25JbiwgJmlyLCAxLCAmbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9Qcm9jCiAqCiAqCiAqLwpzdGF0aWMgTFJFU1VMVCBDQUxMQkFDSyBXQ1VTRVJfUHJvYyhIV05EIGhXbmQsIFVJTlQgdU1zZywgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogICAgc3RydWN0IGlubmVyX2RhdGEqCWRhdGEgPSAoc3RydWN0IGlubmVyX2RhdGEqKUdldFdpbmRvd0xvbmcoaFduZCwgMCk7CgogICAgc3dpdGNoICh1TXNnKQogICAgewogICAgY2FzZSBXTV9DUkVBVEU6CiAgICAgICAgcmV0dXJuIFdDVVNFUl9DcmVhdGUoaFduZCwgKExQQ1JFQVRFU1RSVUNUKWxQYXJhbSk7CiAgICBjYXNlIFdNX0RFU1RST1k6CglQUklWQVRFKGRhdGEpLT5oV25kID0gMDsKCVBvc3RRdWl0TWVzc2FnZSgwKTsKCWJyZWFrOwogICAgY2FzZSBXTV9QQUlOVDoKCVdDVVNFUl9QYWludChkYXRhKTsKCWJyZWFrOwogICAgY2FzZSBXTV9LRVlET1dOOgogICAgY2FzZSBXTV9LRVlVUDoKICAgICAgICBpZiAoUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbikKICAgICAgICAgICAgV0NVU0VSX0hhbmRsZVNlbGVjdGlvbktleShkYXRhLCB1TXNnID09IFdNX0tFWURPV04sIHdQYXJhbSwgbFBhcmFtKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIFdDVVNFUl9HZW5lcmF0ZUtleUlucHV0UmVjb3JkKGRhdGEsIHVNc2cgPT0gV01fS0VZRE9XTiwgd1BhcmFtLCBsUGFyYW0sIEZBTFNFKTsKCWJyZWFrOwogICAgY2FzZSBXTV9TWVNLRVlET1dOOgogICAgY2FzZSBXTV9TWVNLRVlVUDoKCVdDVVNFUl9HZW5lcmF0ZUtleUlucHV0UmVjb3JkKGRhdGEsIHVNc2cgPT0gV01fU1lTS0VZRE9XTiwgd1BhcmFtLCBsUGFyYW0sIFRSVUUpOwoJYnJlYWs7CiAgICBjYXNlIFdNX0xCVVRUT05ET1dOOgogICAgICAgIGlmIChkYXRhLT5jdXJjZmcucXVpY2tfZWRpdCkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID0gRkFMU0U7CiAgICAgICAgICAgICAgICBXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIDApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyID0gV0NVU0VSX0dldENlbGwoZGF0YSwgbFBhcmFtKTsKICAgICAgICAgICAgICAgIFNldENhcHR1cmUoUFJJVkFURShkYXRhKS0+aFduZCk7CiAgICAgICAgICAgICAgICBXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIDApOwogICAgICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiA9IFRSVUU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgV0NVU0VSX0dlbmVyYXRlTW91c2VJbnB1dFJlY29yZChkYXRhLCBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCB3UGFyYW0sIDApOwogICAgICAgIH0KCWJyZWFrOwogICAgY2FzZSBXTV9NT1VTRU1PVkU6CiAgICAgICAgaWYgKGRhdGEtPmN1cmNmZy5xdWlja19lZGl0KQogICAgICAgIHsKICAgICAgICAgICAgaWYgKEdldENhcHR1cmUoKSA9PSBQUklWQVRFKGRhdGEpLT5oV25kICYmIFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24gJiYKICAgICAgICAgICAgICAgICh3UGFyYW0gJiBNS19MQlVUVE9OKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0NVU0VSX01vdmVTZWxlY3Rpb24oZGF0YSwgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLCBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBXQ1VTRVJfR2VuZXJhdGVNb3VzZUlucHV0UmVjb3JkKGRhdGEsIFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSksIHdQYXJhbSwgTU9VU0VfTU9WRUQpOwogICAgICAgIH0KCWJyZWFrOwogICAgY2FzZSBXTV9MQlVUVE9OVVA6CiAgICAgICAgaWYgKGRhdGEtPmN1cmNmZy5xdWlja19lZGl0KQogICAgICAgIHsKICAgICAgICAgICAgaWYgKEdldENhcHR1cmUoKSA9PSBQUklWQVRFKGRhdGEpLT5oV25kICYmIFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24gJiYKICAgICAgICAgICAgICAgICh3UGFyYW0mIE1LX0xCVVRUT04pKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEsIFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSkpOwogICAgICAgICAgICAgICAgUmVsZWFzZUNhcHR1cmUoKTsKICAgICAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24gPSBGQUxTRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBXQ1VTRVJfR2VuZXJhdGVNb3VzZUlucHV0UmVjb3JkKGRhdGEsIFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSksIHdQYXJhbSwgMCk7CiAgICAgICAgfQoJYnJlYWs7CiAgICBjYXNlIFdNX1JCVVRUT05ET1dOOgogICAgICAgIGlmICgod1BhcmFtICYgKE1LX0NPTlRST0x8TUtfU0hJRlQpKSA9PSBkYXRhLT5jdXJjZmcubWVudV9tYXNrKQogICAgICAgIHsKICAgICAgICAgICAgUkVDVCAgICAgICAgcjsKCiAgICAgICAgICAgIEdldFdpbmRvd1JlY3QoaFduZCwgJnIpOwogICAgICAgICAgICBXQ1VTRVJfU2V0TWVudURldGFpbHMoZGF0YSwgUFJJVkFURShkYXRhKS0+aFBvcE1lbnUpOwogICAgICAgICAgICBUcmFja1BvcHVwTWVudShQUklWQVRFKGRhdGEpLT5oUG9wTWVudSwgVFBNX0xFRlRBTElHTnxUUE1fVE9QQUxJR04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHIubGVmdCArIExPV09SRChsUGFyYW0pLCByLnRvcCArIEhJV09SRChsUGFyYW0pLCAwLCBoV25kLCBOVUxMKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgV0NVU0VSX0dlbmVyYXRlTW91c2VJbnB1dFJlY29yZChkYXRhLCBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCB3UGFyYW0sIDApOwogICAgICAgIH0KCWJyZWFrOwogICAgY2FzZSBXTV9SQlVUVE9OVVA6CiAgICAgICAgLyogbm8gbmVlZCB0byB0cmFjayBmb3IgcmJ1dHRvbiB1cCB3aGVuIG9wZW5pbmcgdGhlIHBvcHVwLi4uIHRoZSBldmVudCB3aWxsIGJlCiAgICAgICAgICogc3dhbGxvd2VkIGJ5IFRyYWNrUG9wdXBNZW51ICovCiAgICAgICAgV0NVU0VSX0dlbmVyYXRlTW91c2VJbnB1dFJlY29yZChkYXRhLCBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCB3UGFyYW0sIDApOwoJYnJlYWs7CiAgICBjYXNlIFdNX01PVVNFV0hFRUw6CiAgICAgICAgLyogRklYTUU6IHNob3VsZCB3ZSBzY3JvbGwgdG9vID8gKi8KICAgICAgICBXQ1VTRVJfR2VuZXJhdGVNb3VzZUlucHV0UmVjb3JkKGRhdGEsIFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSksIHdQYXJhbSwgTU9VU0VfV0hFRUxFRCk7CglicmVhazsKICAgIGNhc2UgV01fU0VURk9DVVM6CglpZiAoZGF0YS0+Y3VyY2ZnLmN1cnNvcl92aXNpYmxlKQoJewoJICAgIENyZWF0ZUNhcmV0KFBSSVZBVEUoZGF0YSktPmhXbmQsIFBSSVZBVEUoZGF0YSktPmN1cnNvcl9iaXRtYXAsCiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoLCBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQpOwoJICAgIFdDVVNFUl9Qb3NDdXJzb3IoZGF0YSk7Cgl9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFdNX0tJTExGT0NVUzoKCWlmIChkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUpCgkgICAgRGVzdHJveUNhcmV0KCk7CglicmVhazsKICAgIGNhc2UgV01fSFNDUk9MTDoKICAgICAgICB7CiAgICAgICAgICAgIGludAlwb3MgPSBkYXRhLT5jdXJjZmcud2luX3Bvcy5YOwoKICAgICAgICAgICAgc3dpdGNoIChMT1dPUkQod1BhcmFtKSkKICAgICAgICAgICAgewogICAgICAgICAgICBjYXNlIFNCX1BBR0VVUDogCXBvcyAtPSA4OyAJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX1BBR0VET1dOOiAJcG9zICs9IDg7IAkJYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU0JfTElORVVQOiAJcG9zLS07CQkJYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU0JfTElORURPV046IAlwb3MrKzsJIAkJYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU0JfVEhVTUJUUkFDSzogcG9zID0gSElXT1JEKHdQYXJhbSk7CWJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OiAJCQkJCWJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChwb3MgPCAwKSBwb3MgPSAwOwogICAgICAgICAgICBpZiAocG9zID4gZGF0YS0+Y3VyY2ZnLnNiX3dpZHRoIC0gZGF0YS0+Y3VyY2ZnLndpbl93aWR0aCkKICAgICAgICAgICAgICAgIHBvcyA9IGRhdGEtPmN1cmNmZy5zYl93aWR0aCAtIGRhdGEtPmN1cmNmZy53aW5fd2lkdGg7CiAgICAgICAgICAgIGlmIChwb3MgIT0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgU2Nyb2xsV2luZG93KGhXbmQsIChkYXRhLT5jdXJjZmcud2luX3Bvcy5YIC0gcG9zKSAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE5VTEwpOwogICAgICAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWCA9IHBvczsKICAgICAgICAgICAgICAgIFNldFNjcm9sbFBvcyhoV25kLCBTQl9IT1JaLCBwb3MsIFRSVUUpOwogICAgICAgICAgICAgICAgVXBkYXRlV2luZG93KGhXbmQpOwogICAgICAgICAgICAgICAgV0NVU0VSX1Bvc0N1cnNvcihkYXRhKTsKICAgICAgICAgICAgICAgIFdJTkVDT05fTm90aWZ5V2luZG93Q2hhbmdlKGRhdGEpOwogICAgICAgICAgICB9CiAgICAgICAgfQoJYnJlYWs7CiAgICBjYXNlIFdNX1ZTQ1JPTEw6CiAgICAgICAgewoJICAgIGludAlwb3MgPSBkYXRhLT5jdXJjZmcud2luX3Bvcy5ZOwoKCSAgICBzd2l0Y2ggKExPV09SRCh3UGFyYW0pKQoJICAgIHsKICAgICAgICAgICAgY2FzZSBTQl9QQUdFVVA6IAlwb3MgLT0gODsgCQlicmVhazsKICAgICAgICAgICAgY2FzZSBTQl9QQUdFRE9XTjogCXBvcyArPSA4OyAJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX0xJTkVVUDogCXBvcy0tOwkJCWJyZWFrOwoJICAgIGNhc2UgU0JfTElORURPV046IAlwb3MrKzsJIAkJYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU0JfVEhVTUJUUkFDSzogcG9zID0gSElXT1JEKHdQYXJhbSk7CWJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OiAJCQkJCWJyZWFrOwoJICAgIH0KCSAgICBpZiAocG9zIDwgMCkgcG9zID0gMDsKCSAgICBpZiAocG9zID4gZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCAtIGRhdGEtPmN1cmNmZy53aW5faGVpZ2h0KQogICAgICAgICAgICAgICAgcG9zID0gZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCAtIGRhdGEtPmN1cmNmZy53aW5faGVpZ2h0OwoJICAgIGlmIChwb3MgIT0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSkKCSAgICB7CgkJU2Nyb2xsV2luZG93KGhXbmQsIDAsIChkYXRhLT5jdXJjZmcud2luX3Bvcy5ZIC0gcG9zKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMKTsKCQlkYXRhLT5jdXJjZmcud2luX3Bvcy5ZID0gcG9zOwoJCVNldFNjcm9sbFBvcyhoV25kLCBTQl9WRVJULCBwb3MsIFRSVUUpOwoJCVVwZGF0ZVdpbmRvdyhoV25kKTsKCQlXQ1VTRVJfUG9zQ3Vyc29yKGRhdGEpOwoJCVdJTkVDT05fTm90aWZ5V2luZG93Q2hhbmdlKGRhdGEpOwoJICAgIH0KCiAgICAgICAgfQogICAgY2FzZSBXTV9TWVNDT01NQU5EOgoJc3dpdGNoICh3UGFyYW0pCgl7CgljYXNlIElEU19ERUZBVUxUOgoJICAgIFdDVVNFUl9HZXRQcm9wZXJ0aWVzKGRhdGEsIEZBTFNFKTsKCSAgICBicmVhazsKCWNhc2UgSURTX1BST1BFUlRJRVM6CgkgICAgV0NVU0VSX0dldFByb3BlcnRpZXMoZGF0YSwgVFJVRSk7CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIHJldHVybiBEZWZXaW5kb3dQcm9jKGhXbmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKCX0KCWJyZWFrOwogICAgY2FzZSBXTV9DT01NQU5EOgoJc3dpdGNoICh3UGFyYW0pCgl7CgljYXNlIElEU19ERUZBVUxUOgoJICAgIFdDVVNFUl9HZXRQcm9wZXJ0aWVzKGRhdGEsIEZBTFNFKTsKCSAgICBicmVhazsKCWNhc2UgSURTX1BST1BFUlRJRVM6CgkgICAgV0NVU0VSX0dldFByb3BlcnRpZXMoZGF0YSwgVFJVRSk7CgkgICAgYnJlYWs7CgljYXNlIElEU19NQVJLOgogICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWCA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MS5ZID0gMDsKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlggPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIuWSA9IDA7CiAgICAgICAgICAgIFdDVVNFUl9TZXRTZWxlY3Rpb24oZGF0YSwgMCk7CiAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24gPSBUUlVFOwoJICAgIGJyZWFrOwoJY2FzZSBJRFNfQ09QWToKICAgICAgICAgICAgaWYgKFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24gPSBGQUxTRTsKICAgICAgICAgICAgICAgIFdDVVNFUl9TZXRTZWxlY3Rpb24oZGF0YSwgMCk7CiAgICAgICAgICAgICAgICBXQ1VTRVJfQ29weVNlbGVjdGlvblRvQ2xpcGJvYXJkKGRhdGEpOwogICAgICAgICAgICB9CgkgICAgYnJlYWs7CgljYXNlIElEU19QQVNURToKCSAgICBXQ1VTRVJfUGFzdGVGcm9tQ2xpcGJvYXJkKGRhdGEpOwoJICAgIGJyZWFrOwoJY2FzZSBJRFNfU0VMRUNUQUxMOgogICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWCA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MS5ZID0gMDsKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlggPSAoZGF0YS0+Y3VyY2ZnLnNiX3dpZHRoIC0gMSkgKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlkgPSAoZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCAtIDEpICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0OwogICAgICAgICAgICBXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIDApOwogICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID0gVFJVRTsKCSAgICBicmVhazsKCWNhc2UgSURTX1NDUk9MTDoKCWNhc2UgSURTX1NFQVJDSDoKCSAgICBXSU5FX0ZJWE1FKCJVbmhhbmRsZWQgeWV0IGNvbW1hbmQ6ICV4XG4iLCB3UGFyYW0pOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICByZXR1cm4gRGVmV2luZG93UHJvYyhoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7Cgl9CglicmVhazsKICAgIGNhc2UgV01fSU5JVE1FTlVQT1BVUDoKCWlmICghSElXT1JEKGxQYXJhbSkpCXJldHVybiBEZWZXaW5kb3dQcm9jKGhXbmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKCVdDVVNFUl9TZXRNZW51RGV0YWlscyhkYXRhLCBHZXRTeXN0ZW1NZW51KFBSSVZBVEUoZGF0YSktPmhXbmQsIEZBTFNFKSk7CglicmVhazsKICAgIGRlZmF1bHQ6CglyZXR1cm4gRGVmV2luZG93UHJvYyhoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7CiAgICB9CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0RlbGV0ZUJhY2tlbmQKICoKICoKICovCnZvaWQgV0NVU0VSX0RlbGV0ZUJhY2tlbmQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIGlmICghUFJJVkFURShkYXRhKSkgcmV0dXJuOwogICAgaWYgKFBSSVZBVEUoZGF0YSktPmhNZW1EQykJCURlbGV0ZURDKFBSSVZBVEUoZGF0YSktPmhNZW1EQyk7CiAgICBpZiAoUFJJVkFURShkYXRhKS0+aFduZCkJCURlc3Ryb3lXaW5kb3coUFJJVkFURShkYXRhKS0+aFduZCk7CiAgICBpZiAoUFJJVkFURShkYXRhKS0+aEZvbnQpCQlEZWxldGVPYmplY3QoUFJJVkFURShkYXRhKS0+aEZvbnQpOwogICAgaWYgKFBSSVZBVEUoZGF0YSktPmN1cnNvcl9iaXRtYXApCURlbGV0ZU9iamVjdChQUklWQVRFKGRhdGEpLT5jdXJzb3JfYml0bWFwKTsKICAgIGlmIChQUklWQVRFKGRhdGEpLT5oQml0bWFwKQkJRGVsZXRlT2JqZWN0KFBSSVZBVEUoZGF0YSktPmhCaXRtYXApOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgUFJJVkFURShkYXRhKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9NYWluTG9vcAogKgogKgogKi8Kc3RhdGljIGludCBXQ1VTRVJfTWFpbkxvb3Aoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIE1TRwkJbXNnOwoKICAgIFNob3dXaW5kb3coUFJJVkFURShkYXRhKS0+aFduZCwgU1dfU0hPVyk7CiAgICBmb3IgKDs7KQogICAgewoJc3dpdGNoIChNc2dXYWl0Rm9yTXVsdGlwbGVPYmplY3RzKDEsICZkYXRhLT5oU3luY2hybywgRkFMU0UsIElORklOSVRFLCBRU19BTExJTlBVVCkpCgl7CgljYXNlIFdBSVRfT0JKRUNUXzA6CgkgICAgaWYgKCFXSU5FQ09OX0dyYWJDaGFuZ2VzKGRhdGEpICYmIGRhdGEtPmN1cmNmZy5leGl0X29uX2RpZSkKICAgICAgICAgICAgICAgIFBvc3RRdWl0TWVzc2FnZSgwKTsKCSAgICBicmVhazsKCWNhc2UgV0FJVF9PQkpFQ1RfMCsxOgoJICAgIC8qIG5lZWQgdG8gdXNlIFBlZWtNZXNzYWdlIGxvb3AgaW5zdGVhZCBvZiBzaW1wbGUgR2V0TWVzc2FnZToKCSAgICAgKiBtdWx0aXBsZSBtZXNzYWdlcyBtaWdodCBoYXZlIGFycml2ZWQgaW4gYmV0d2VlbiwKCSAgICAgKiBzbyBHZXRNZXNzYWdlIHdvdWxkIGxlYWQgdG8gZGVsYXllZCBwcm9jZXNzaW5nICovCgkgICAgd2hpbGUgKFBlZWtNZXNzYWdlKCZtc2csIDAsIDAsIDAsIFBNX1JFTU9WRSkpCgkgICAgewogICAgICAgICAgICAgICAgaWYgKG1zZy5tZXNzYWdlID09IFdNX1FVSVQpIHJldHVybiAwOwogICAgICAgICAgICAgICAgV0lORV9UUkFDRSgiZGlzcGF0Y2hpbmcgbXNnICUwNHhcbiIsIG1zZy5tZXNzYWdlKTsKICAgICAgICAgICAgICAgIERpc3BhdGNoTWVzc2FnZSgmbXNnKTsKCSAgICB9CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIFdJTkVfRVJSKCJnb3QgcGJcbiIpOwoJICAgIC8qIGVyciAqLwoJICAgIGJyZWFrOwoJfQogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfSW5pdEJhY2tlbmQKICoKICogSW5pdGlhbGlzYXRpb24gcGFydCBJSTogY3JlYXRpb24gb2Ygd2luZG93LgogKgogKi8KZW51bSBpbml0X3JldHVybiBXQ1VTRVJfSW5pdEJhY2tlbmQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiB3Q2xhc3NOYW1lW10gPSB7J1cnLCdpJywnbicsJ2UnLCdDJywnbycsJ24nLCdzJywnbycsJ2wnLCdlJywnQycsJ2wnLCdhJywncycsJ3MnLDB9OwoKICAgIFdORENMQVNTCQl3bmRjbGFzczsKCiAgICBkYXRhLT5wcml2YXRlID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihzdHJ1Y3QgaW5uZXJfZGF0YV91c2VyKSk7CiAgICBpZiAoIWRhdGEtPnByaXZhdGUpIHJldHVybiBpbml0X2ZhaWxlZDsKCiAgICBkYXRhLT5mbk1haW5Mb29wID0gV0NVU0VSX01haW5Mb29wOwogICAgZGF0YS0+Zm5Qb3NDdXJzb3IgPSBXQ1VTRVJfUG9zQ3Vyc29yOwogICAgZGF0YS0+Zm5TaGFwZUN1cnNvciA9IFdDVVNFUl9TaGFwZUN1cnNvcjsKICAgIGRhdGEtPmZuQ29tcHV0ZVBvc2l0aW9ucyA9IFdDVVNFUl9Db21wdXRlUG9zaXRpb25zOwogICAgZGF0YS0+Zm5SZWZyZXNoID0gV0NVU0VSX1JlZnJlc2g7CiAgICBkYXRhLT5mblJlc2l6ZVNjcmVlbkJ1ZmZlciA9IFdDVVNFUl9SZXNpemVTY3JlZW5CdWZmZXI7CiAgICBkYXRhLT5mblNldFRpdGxlID0gV0NVU0VSX1NldFRpdGxlOwogICAgZGF0YS0+Zm5TZXRGb250ID0gV0NVU0VSX1NldEZvbnRQbXQ7CiAgICBkYXRhLT5mblNjcm9sbCA9IFdDVVNFUl9TY3JvbGw7CiAgICBkYXRhLT5mbkRlbGV0ZUJhY2tlbmQgPSBXQ1VTRVJfRGVsZXRlQmFja2VuZDsKCiAgICB3bmRjbGFzcy5zdHlsZSAgICAgICAgID0gMDsKICAgIHduZGNsYXNzLmxwZm5XbmRQcm9jICAgPSBXQ1VTRVJfUHJvYzsKICAgIHduZGNsYXNzLmNiQ2xzRXh0cmEgICAgPSAwOwogICAgd25kY2xhc3MuY2JXbmRFeHRyYSAgICA9IHNpemVvZihEV09SRCk7CiAgICB3bmRjbGFzcy5oSW5zdGFuY2UgICAgID0gR2V0TW9kdWxlSGFuZGxlKE5VTEwpOwogICAgd25kY2xhc3MuaEljb24gICAgICAgICA9IExvYWRJY29uKDAsIElESV9XSU5MT0dPKTsKICAgIHduZGNsYXNzLmhDdXJzb3IgICAgICAgPSBMb2FkQ3Vyc29yKDAsIElEQ19BUlJPVyk7CiAgICB3bmRjbGFzcy5oYnJCYWNrZ3JvdW5kID0gR2V0U3RvY2tPYmplY3QoQkxBQ0tfQlJVU0gpOwogICAgd25kY2xhc3MubHBzek1lbnVOYW1lICA9IE5VTEw7CiAgICB3bmRjbGFzcy5scHN6Q2xhc3NOYW1lID0gd0NsYXNzTmFtZTsKCiAgICBSZWdpc3RlckNsYXNzKCZ3bmRjbGFzcyk7CgogICAgQ3JlYXRlV2luZG93KHduZGNsYXNzLmxwc3pDbGFzc05hbWUsIE5VTEwsCgkJIFdTX09WRVJMQVBQRUR8V1NfQ0FQVElPTnxXU19TWVNNRU5VfFdTX1RISUNLRlJBTUV8V1NfTUlOSU1JWkVCT1h8V1NfSFNDUk9MTHxXU19WU0NST0xMLAoJCSBDV19VU0VERUZBVUxULCBDV19VU0VERUZBVUxULCAwLCAwLCAwLCAwLCB3bmRjbGFzcy5oSW5zdGFuY2UsIGRhdGEpOwogICAgaWYgKCFQUklWQVRFKGRhdGEpLT5oV25kKSByZXR1cm4gaW5pdF9mYWlsZWQ7CgogICAgcmV0dXJuIGluaXRfc3VjY2VzczsKfQo=