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+Y3VyY2ZnLmN1cnNvcl92aXNpYmxlKQoJICAgIFNob3dDYXJldChQUklWQVRFKGRhdGEpLT5oV25kKTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX01vdmVTZWxlY3Rpb24KICoKICoKICovCnN0YXRpYyB2b2lkCVdDVVNFUl9Nb3ZlU2VsZWN0aW9uKHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBDT09SRCBjMSwgQ09PUkQgYzIsIEJPT0wgZmluYWwpCnsKICAgIFJFQ1QJcjsKICAgIEhEQwkJaERDOwoKICAgIFdDVVNFUl9HZXRTZWxlY3Rpb25SZWN0KGRhdGEsICZyKTsKICAgIGhEQyA9IEdldERDKFBSSVZBVEUoZGF0YSktPmhXbmQpOwogICAgaWYgKGhEQykKICAgIHsKCWlmIChQUklWQVRFKGRhdGEpLT5oV25kID09IEdldEZvY3VzKCkgJiYgZGF0YS0+Y3VyY2ZnLmN1cnNvcl92aXNpYmxlKQoJICAgIEhpZGVDYXJldChQUklWQVRFKGRhdGEpLT5oV25kKTsKCUludmVydFJlY3QoaERDLCAmcik7CiAgICB9CiAgICBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEgPSBjMTsKICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MiA9IGMyOwogICAgaWYgKGhEQykKICAgIHsKCVdDVVNFUl9HZXRTZWxlY3Rpb25SZWN0KGRhdGEsICZyKTsKCUludmVydFJlY3QoaERDLCAmcik7CglSZWxlYXNlREMoUFJJVkFURShkYXRhKS0+aFduZCwgaERDKTsKCWlmIChQUklWQVRFKGRhdGEpLT5oV25kID09IEdldEZvY3VzKCkgJiYgZGF0YS0+Y3VyY2ZnLmN1cnNvcl92aXNpYmxlKQoJICAgIFNob3dDYXJldChQUklWQVRFKGRhdGEpLT5oV25kKTsKICAgIH0KICAgIGlmIChmaW5hbCkKICAgIHsKCVJlbGVhc2VDYXB0dXJlKCk7CglQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID0gVFJVRTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0NvcHlTZWxlY3Rpb25Ub0NsaXBib2FyZAogKgogKiBDb3BpZXMgdGhlIGN1cnJlbnQgc2VsZWN0aW9uIGludG8gdGhlIGNsaXBib2FyZAogKi8Kc3RhdGljIHZvaWQJV0NVU0VSX0NvcHlTZWxlY3Rpb25Ub0NsaXBib2FyZChjb25zdCBzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgSEFORExFCWhNZW07CiAgICBMUFdTVFIJcDsKICAgIHVuc2lnbmVkCXcsIGg7CgogICAgdyA9IGFicyhQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWCAtIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5YKSArIDI7CiAgICBoID0gYWJzKFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MS5ZIC0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlkpICsgMTsKCiAgICBpZiAoIU9wZW5DbGlwYm9hcmQoUFJJVkFURShkYXRhKS0+aFduZCkpIHJldHVybjsKICAgIEVtcHR5Q2xpcGJvYXJkKCk7CgogICAgaE1lbSA9IEdsb2JhbEFsbG9jKEdNRU1fTU9WRUFCTEUsICh3ICogaCkgKiBzaXplb2YoV0NIQVIpKTsKICAgIGlmIChoTWVtICYmIChwID0gR2xvYmFsTG9jayhoTWVtKSkpCiAgICB7CglDT09SRAljOwoJaW50CXk7CgoJYy5YID0gbWluKFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MS5YLCBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIuWCk7CgljLlkgPSBtaW4oUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlksIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5ZKTsKCglmb3IgKHkgPSAwOyB5IDwgaDsgeSsrLCBjLlkrKykKCXsKCSAgICBSZWFkQ29uc29sZU91dHB1dENoYXJhY3RlcihkYXRhLT5oQ29uT3V0LCAmcFt5ICogd10sIHcgLSAxLCBjLCBOVUxMKTsKCSAgICBwW3kgKiB3ICsgdyAtIDFdID0gKHkgPCBoIC0gMSkgPyAnXG4nIDogJ1wwJzsKCX0KCUdsb2JhbFVubG9jayhoTWVtKTsKCVNldENsaXBib2FyZERhdGEoQ0ZfVU5JQ09ERVRFWFQsIGhNZW0pOwogICAgfQogICAgQ2xvc2VDbGlwYm9hcmQoKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1Bhc3RlRnJvbUNsaXBib2FyZAogKgogKgogKi8Kc3RhdGljIHZvaWQJV0NVU0VSX1Bhc3RlRnJvbUNsaXBib2FyZChzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgSEFORExFCWg7CiAgICBXQ0hBUioJcHRyOwoKICAgIGlmICghT3BlbkNsaXBib2FyZChQUklWQVRFKGRhdGEpLT5oV25kKSkgcmV0dXJuOwogICAgaCA9IEdldENsaXBib2FyZERhdGEoQ0ZfVU5JQ09ERVRFWFQpOwogICAgaWYgKGggJiYgKHB0ciA9IEdsb2JhbExvY2soaCkpKQogICAgewoJaW50CQlpLCBsZW4gPSBHbG9iYWxTaXplKGgpIC8gc2l6ZW9mKFdDSEFSKTsKCUlOUFVUX1JFQ09SRAlpclsyXTsKCURXT1JECQluOwoJU0hPUlQJCXNoOwoKCWlyWzBdLkV2ZW50VHlwZSA9IEtFWV9FVkVOVDsKCWlyWzBdLkV2ZW50LktleUV2ZW50LndSZXBlYXRDb3VudCA9IDA7CglpclswXS5FdmVudC5LZXlFdmVudC5kd0NvbnRyb2xLZXlTdGF0ZSA9IDA7CglpclswXS5FdmVudC5LZXlFdmVudC5iS2V5RG93biA9IFRSVUU7CgoJLyogZ2VuZXJhdGUgdGhlIGNvcnJlc3BvbmRpbmcgaW5wdXQgcmVjb3JkcyAqLwoJZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKQoJewoJICAgIC8qIEZJWE1FOiB0aGUgbW9kaWZ5aW5nIGtleXMgYXJlIG5vdCBnZW5lcmF0ZWQgKHNoaWZ0LCBjdHJsLi4uKSAqLwoJICAgIHNoID0gVmtLZXlTY2FuKHB0cltpXSk7CgkgICAgaXJbMF0uRXZlbnQuS2V5RXZlbnQud1ZpcnR1YWxLZXlDb2RlID0gTE9CWVRFKHNoKTsKCSAgICBpclswXS5FdmVudC5LZXlFdmVudC53VmlydHVhbFNjYW5Db2RlID0gTWFwVmlydHVhbEtleShMT0JZVEUoc2gpLCAwKTsKCSAgICBpclswXS5FdmVudC5LZXlFdmVudC51Q2hhci5Vbmljb2RlQ2hhciA9IHB0cltpXTsKCgkgICAgaXJbMV0gPSBpclswXTsKCSAgICBpclsxXS5FdmVudC5LZXlFdmVudC5iS2V5RG93biA9IEZBTFNFOwoKCSAgICBXcml0ZUNvbnNvbGVJbnB1dChkYXRhLT5oQ29uSW4sIGlyLCAyLCAmbik7Cgl9CglHbG9iYWxVbmxvY2soaCk7CiAgICB9CiAgICBDbG9zZUNsaXBib2FyZCgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfUmVmcmVzaAogKgogKgogKi8Kc3RhdGljIHZvaWQgV0NVU0VSX1JlZnJlc2goY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIGludCB0cCwgaW50IGJtKQp7CiAgICBXQ1VTRVJfRmlsbE1lbURDKGRhdGEsIHRwLCBibSk7CiAgICBpZiAoZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSA8PSBibSAmJiBkYXRhLT5jdXJjZmcud2luX3Bvcy5ZICsgZGF0YS0+Y3VyY2ZnLndpbl9oZWlnaHQgPj0gdHApCiAgICB7CglSRUNUCXI7CgoJci5sZWZ0ICAgPSAwOwoJci5yaWdodCAgPSBkYXRhLT5jdXJjZmcud2luX3dpZHRoICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGg7CglyLnRvcCAgICA9ICh0cCAtIGRhdGEtPmN1cmNmZy53aW5fcG9zLlkpICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0OwoJci5ib3R0b20gPSAoYm0gLSBkYXRhLT5jdXJjZmcud2luX3Bvcy5ZICsgMSkgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQ7CglJbnZhbGlkYXRlUmVjdChQUklWQVRFKGRhdGEpLT5oV25kLCAmciwgRkFMU0UpOwoJVXBkYXRlV2luZG93KFBSSVZBVEUoZGF0YSktPmhXbmQpOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfUGFpbnQKICoKICoKICovCnN0YXRpYyB2b2lkCVdDVVNFUl9QYWludChjb25zdCBzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgUEFJTlRTVFJVQ1QJCXBzOwoKICAgIEJlZ2luUGFpbnQoUFJJVkFURShkYXRhKS0+aFduZCwgJnBzKTsKICAgIEJpdEJsdChwcy5oZGMsIDAsIDAsCiAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLndpbl93aWR0aCAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoLAogICAgICAgICAgIGRhdGEtPmN1cmNmZy53aW5faGVpZ2h0ICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0LAoJICAgUFJJVkFURShkYXRhKS0+aE1lbURDLAogICAgICAgICAgIGRhdGEtPmN1cmNmZy53aW5fcG9zLlggKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwKICAgICAgICAgICBkYXRhLT5jdXJjZmcud2luX3Bvcy5ZICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0LAoJICAgU1JDQ09QWSk7CiAgICBpZiAoUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbikKCVdDVVNFUl9TZXRTZWxlY3Rpb24oZGF0YSwgcHMuaGRjKTsKICAgIEVuZFBhaW50KFBSSVZBVEUoZGF0YSktPmhXbmQsICZwcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9TY3JvbGwKICoKICoKICovCnN0YXRpYyB2b2lkIFdDVVNFUl9TY3JvbGwoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIGludCBwb3MsIEJPT0wgaG9yeikKewogICAgaWYgKGhvcnopCiAgICB7CglTZXRTY3JvbGxQb3MoUFJJVkFURShkYXRhKS0+aFduZCwgU0JfSE9SWiwgcG9zLCBUUlVFKTsKCWRhdGEtPmN1cmNmZy53aW5fcG9zLlggPSBwb3M7CiAgICB9CiAgICBlbHNlCiAgICB7CglTZXRTY3JvbGxQb3MoUFJJVkFURShkYXRhKS0+aFduZCwgU0JfVkVSVCwgcG9zLCBUUlVFKTsKCWRhdGEtPmN1cmNmZy53aW5fcG9zLlkgPSBwb3M7CiAgICB9CiAgICBJbnZhbGlkYXRlUmVjdChQUklWQVRFKGRhdGEpLT5oV25kLCBOVUxMLCBGQUxTRSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9GaWxsTWVudQogKgogKgogKi8Kc3RhdGljIEJPT0wgV0NVU0VSX0ZpbGxNZW51KEhNRU5VIGhNZW51LCBCT09MIHNlcCkKewogICAgSE1FTlUJCWhTdWJNZW51OwogICAgSElOU1RBTkNFCQloSW5zdGFuY2UgPSBHZXRNb2R1bGVIYW5kbGUoTlVMTCk7CiAgICBXQ0hBUgkJYnVmZlsyNTZdOwoKICAgIGlmICghaE1lbnUpIHJldHVybiBGQUxTRTsKCiAgICAvKiBGSVhNRTogZXJyb3IgaGFuZGxpbmcgJiBtZW1vcnkgY2xlYW51cCAqLwogICAgaFN1Yk1lbnUgPSBDcmVhdGVNZW51KCk7CiAgICBpZiAoIWhTdWJNZW51KSByZXR1cm4gRkFMU0U7CgogICAgTG9hZFN0cmluZyhoSW5zdGFuY2UsIElEU19NQVJLLCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaFN1Yk1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklORywgSURTX01BUkssIGJ1ZmYpOwogICAgTG9hZFN0cmluZyhoSW5zdGFuY2UsIElEU19DT1BZLCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaFN1Yk1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklORywgSURTX0NPUFksIGJ1ZmYpOwogICAgTG9hZFN0cmluZyhoSW5zdGFuY2UsIElEU19QQVNURSwgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhTdWJNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkcsIElEU19QQVNURSwgYnVmZik7CiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX1NFTEVDVEFMTCwgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhTdWJNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkcsIElEU19TRUxFQ1RBTEwsIGJ1ZmYpOwogICAgTG9hZFN0cmluZyhoSW5zdGFuY2UsIElEU19TQ1JPTEwsIGJ1ZmYsIHNpemVvZihidWZmKSAvIHNpemVvZihXQ0hBUikpOwogICAgSW5zZXJ0TWVudShoU3ViTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU1RSSU5HLCBJRFNfU0NST0xMLCBidWZmKTsKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfU0VBUkNILCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaFN1Yk1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklORywgSURTX1NFQVJDSCwgYnVmZik7CgogICAgaWYgKHNlcCkgSW5zZXJ0TWVudShoTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU0VQQVJBVE9SLCAwLCBOVUxMKTsKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfRURJVCwgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkd8TUZfUE9QVVAsIChVSU5UX1BUUiloU3ViTWVudSwgYnVmZik7CiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX0RFRkFVTFQsIGJ1ZmYsIHNpemVvZihidWZmKSAvIHNpemVvZihXQ0hBUikpOwogICAgSW5zZXJ0TWVudShoTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU1RSSU5HLCBJRFNfREVGQVVMVCwgYnVmZik7CiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX1BST1BFUlRJRVMsIGJ1ZmYsIHNpemVvZihidWZmKSAvIHNpemVvZihXQ0hBUikpOwogICAgSW5zZXJ0TWVudShoTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU1RSSU5HLCBJRFNfUFJPUEVSVElFUywgYnVmZik7CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9TZXRNZW51RGV0YWlscwogKgogKiBHcmF5cyAvIHVuZ3JheXMgdGhlIG1lbnUgaXRlbXMgYWNjb3JkaW5nIHRvIHRoZWlyIHN0YXRlCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfU2V0TWVudURldGFpbHMoY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIEhNRU5VIGhNZW51KQp7CiAgICBpZiAoIWhNZW51KSB7V0lORV9FUlIoIklzc3VlIGluIGdldHRpbmcgbWVudSBiaXRzXG4iKTtyZXR1cm47fQoKICAgIEVuYWJsZU1lbnVJdGVtKGhNZW51LCBJRFNfQ09QWSwKICAgICAgICAgICAgICAgICAgIE1GX0JZQ09NTUFORHwoUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiA/IE1GX0VOQUJMRUQgOiBNRl9HUkFZRUQpKTsKICAgIEVuYWJsZU1lbnVJdGVtKGhNZW51LCBJRFNfUEFTVEUsCgkJICAgTUZfQllDT01NQU5EfChJc0NsaXBib2FyZEZvcm1hdEF2YWlsYWJsZShDRl9VTklDT0RFVEVYVCkKCQkJCSA/IE1GX0VOQUJMRUQgOiBNRl9HUkFZRUQpKTsKICAgIEVuYWJsZU1lbnVJdGVtKGhNZW51LCBJRFNfU0NST0xMLCBNRl9CWUNPTU1BTkR8TUZfR1JBWUVEKTsKICAgIEVuYWJsZU1lbnVJdGVtKGhNZW51LCBJRFNfU0VBUkNILCBNRl9CWUNPTU1BTkR8TUZfR1JBWUVEKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0NyZWF0ZQogKgogKiBDcmVhdGVzIHRoZSB3aW5kb3cgZm9yIHRoZSByZW5kZXJpbmcKICovCnN0YXRpYyBMUkVTVUxUIFdDVVNFUl9DcmVhdGUoSFdORCBoV25kLCBMUENSRUFURVNUUlVDVCBscGNzKQp7CiAgICBzdHJ1Y3QgaW5uZXJfZGF0YSoJZGF0YTsKICAgIEhNRU5VCQloU3lzTWVudTsKCiAgICBkYXRhID0gbHBjcy0+bHBDcmVhdGVQYXJhbXM7CiAgICBTZXRXaW5kb3dMb25nKGhXbmQsIDBMLCAoRFdPUkQpZGF0YSk7CiAgICBQUklWQVRFKGRhdGEpLT5oV25kID0gaFduZDsKCiAgICBoU3lzTWVudSA9IEdldFN5c3RlbU1lbnUoaFduZCwgRkFMU0UpOwogICAgaWYgKCFoU3lzTWVudSkgcmV0dXJuIDA7CiAgICBQUklWQVRFKGRhdGEpLT5oUG9wTWVudSA9IENyZWF0ZVBvcHVwTWVudSgpOwogICAgaWYgKCFQUklWQVRFKGRhdGEpLT5oUG9wTWVudSkgcmV0dXJuIDA7CgogICAgV0NVU0VSX0ZpbGxNZW51KGhTeXNNZW51LCBUUlVFKTsKICAgIFdDVVNFUl9GaWxsTWVudShQUklWQVRFKGRhdGEpLT5oUG9wTWVudSwgRkFMU0UpOwoKICAgIFBSSVZBVEUoZGF0YSktPmhNZW1EQyA9IENyZWF0ZUNvbXBhdGlibGVEQygwKTsKICAgIGlmICghUFJJVkFURShkYXRhKS0+aE1lbURDKSB7V0lORV9FUlIoIm5vIG1lbSBkY1xuIik7cmV0dXJuIDA7fQoKICAgIGRhdGEtPmN1cmNmZy5xdWlja19lZGl0ID0gRkFMU0U7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0dldEN0cmxLZXlTdGF0ZQogKgogKiBHZXQgdGhlIGNvbnNvbGUgYml0IG1hc2sgZXF1aXZhbGVudCB0byB0aGUgVktfIHN0YXR1cyBpbiBrZXlTdGF0ZQogKi8Kc3RhdGljIERXT1JEICAgIFdDVVNFUl9HZXRDdHJsS2V5U3RhdGUoQllURSoga2V5U3RhdGUpCnsKICAgIERXT1JEICAgICAgICAgICAgICAgcmV0ID0gMDsKCiAgICBHZXRLZXlib2FyZFN0YXRlKGtleVN0YXRlKTsKICAgIGlmIChrZXlTdGF0ZVtWS19TSElGVF0gICAgJiAweDgwKQlyZXQgfD0gU0hJRlRfUFJFU1NFRDsKICAgIGlmIChrZXlTdGF0ZVtWS19MQ09OVFJPTF0gJiAweDgwKQlyZXQgfD0gTEVGVF9DVFJMX1BSRVNTRUQ7CiAgICBpZiAoa2V5U3RhdGVbVktfUkNPTlRST0xdICYgMHg4MCkJcmV0IHw9IFJJR0hUX0NUUkxfUFJFU1NFRDsKICAgIGlmIChrZXlTdGF0ZVtWS19MTUVOVV0gICAgJiAweDgwKQlyZXQgfD0gTEVGVF9BTFRfUFJFU1NFRDsKICAgIGlmIChrZXlTdGF0ZVtWS19STUVOVV0gICAgJiAweDgwKQlyZXQgfD0gUklHSFRfQUxUX1BSRVNTRUQ7CiAgICBpZiAoa2V5U3RhdGVbVktfQ0FQSVRBTF0gICYgMHgwMSkJcmV0IHw9IENBUFNMT0NLX09OOwogICAgaWYgKGtleVN0YXRlW1ZLX05VTUxPQ0tdICAmIDB4MDEpCXJldCB8PSBOVU1MT0NLX09OOwogICAgaWYgKGtleVN0YXRlW1ZLX1NDUk9MTF0gICAmIDB4MDEpCXJldCB8PSBTQ1JPTExMT0NLX09OOwoKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9IYW5kbGVTZWxlY3Rpb25LZXkKICoKICogSGFuZGxlcyBrZXlzIHdoaWxlIHNlbGVjdGluZyBhbiBhcmVhCiAqLwpzdGF0aWMgdm9pZCBXQ1VTRVJfSGFuZGxlU2VsZWN0aW9uS2V5KHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBCT09MIGRvd24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogICAgQllURQlrZXlTdGF0ZVsyNTZdOwogICAgRFdPUkQgICAgICAgc3RhdGUgPSBXQ1VTRVJfR2V0Q3RybEtleVN0YXRlKGtleVN0YXRlKSAmIH4oQ0FQU0xPQ0tfT058TlVNTE9DS19PTnxTQ1JPTExMT0NLX09OKTsKICAgIENPT1JEICAgICAgIGMxLCBjMjsKCiAgICBpZiAoZG93bikgcmV0dXJuOwoKICAgIHN3aXRjaCAoc3RhdGUpCiAgICB7CiAgICBjYXNlIDA6CiAgICAgICAgc3dpdGNoICh3UGFyYW0pCiAgICAgICAgewogICAgICAgIGNhc2UgVktfUkVUVVJOOgogICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID0gRkFMU0U7CiAgICAgICAgICAgIFdDVVNFUl9TZXRTZWxlY3Rpb24oZGF0YSwgMCk7CiAgICAgICAgICAgIFdDVVNFUl9Db3B5U2VsZWN0aW9uVG9DbGlwYm9hcmQoZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVktfUklHSFQ6CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzEuWCsrOyBjMi5YKys7CiAgICAgICAgICAgIGlmIChjMS5YIDwgZGF0YS0+Y3VyY2ZnLnNiX3dpZHRoICYmIGMyLlggPCBkYXRhLT5jdXJjZmcuc2Jfd2lkdGgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMiwgRkFMU0UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVktfTEVGVDoKICAgICAgICAgICAgYzEgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDE7CiAgICAgICAgICAgIGMyID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyOwogICAgICAgICAgICBjMS5YLS07IGMyLlgtLTsKICAgICAgICAgICAgaWYgKGMxLlggPj0gMCAmJiBjMi5YID49IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMiwgRkFMU0UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVktfVVA6CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzEuWS0tOyBjMi5ZLS07CiAgICAgICAgICAgIGlmIChjMS5ZID49IDAgJiYgYzIuWSA+PSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIsIEZBTFNFKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFZLX0RPV046CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzEuWSsrOyBjMi5ZKys7CiAgICAgICAgICAgIGlmIChjMS5YIDwgZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCAmJiBjMi5YIDwgZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0NVU0VSX01vdmVTZWxlY3Rpb24oZGF0YSwgYzEsIGMyLCBGQUxTRSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBTSElGVF9QUkVTU0VEOgogICAgICAgIHN3aXRjaCAod1BhcmFtKQogICAgICAgIHsKICAgICAgICBjYXNlIFZLX1JJR0hUOgogICAgICAgICAgICBjMSA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MTsKICAgICAgICAgICAgYzIgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDI7CiAgICAgICAgICAgIGMyLlgrKzsKICAgICAgICAgICAgaWYgKGMyLlggPCBkYXRhLT5jdXJjZmcuc2Jfd2lkdGgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMiwgRkFMU0UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVktfTEVGVDoKICAgICAgICAgICAgYzEgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDE7CiAgICAgICAgICAgIGMyID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyOwogICAgICAgICAgICBjMi5YLS07CiAgICAgICAgICAgIGlmIChjMi5YID49IGMxLlgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMiwgRkFMU0UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVktfVVA6CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzIuWS0tOwogICAgICAgICAgICBpZiAoYzIuWSA+PSBjMS5ZKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIsIEZBTFNFKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFZLX0RPV046CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzIuWSsrOwogICAgICAgICAgICBpZiAoYzIuWCA8IGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMiwgRkFMU0UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0dlbmVyYXRlS2V5SW5wdXRSZWNvcmQKICoKICogZ2VuZXJhdGVzIGlucHV0X3JlY29yZCBmcm9tIHdpbmRvd3MgV01fS0VZVVAvV01fS0VZRE9XTiBtZXNzYWdlcwogKi8Kc3RhdGljIHZvaWQgICAgV0NVU0VSX0dlbmVyYXRlS2V5SW5wdXRSZWNvcmQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIEJPT0wgZG93biwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSwgQk9PTCBzeXMpCnsKICAgIElOUFVUX1JFQ09SRAlpcjsKICAgIERXT1JECQluOwogICAgV0NIQVIJCWJ1ZlsyXTsKICAgIHN0YXRpYwlXQ0hBUglsYXN0OyAvKiBrZWVwIGxhc3QgY2hhciBzZWVuIGFzIGZlZWQgZm9yIGtleSB1cCBtZXNzYWdlICovCiAgICBCWVRFCQlrZXlTdGF0ZVsyNTZdOwoKICAgIGlyLkV2ZW50VHlwZSA9IEtFWV9FVkVOVDsKICAgIGlyLkV2ZW50LktleUV2ZW50LmJLZXlEb3duID0gZG93bjsKICAgIGlyLkV2ZW50LktleUV2ZW50LndSZXBlYXRDb3VudCA9IExPV09SRChsUGFyYW0pOwogICAgaXIuRXZlbnQuS2V5RXZlbnQud1ZpcnR1YWxLZXlDb2RlID0gd1BhcmFtOwoKICAgIGlyLkV2ZW50LktleUV2ZW50LndWaXJ0dWFsU2NhbkNvZGUgPSBISVdPUkQobFBhcmFtKSAmIDB4RkY7CgogICAgaXIuRXZlbnQuS2V5RXZlbnQudUNoYXIuVW5pY29kZUNoYXIgPSAwOwogICAgaXIuRXZlbnQuS2V5RXZlbnQuZHdDb250cm9sS2V5U3RhdGUgPSBXQ1VTRVJfR2V0Q3RybEtleVN0YXRlKGtleVN0YXRlKTsKICAgIGlmIChsUGFyYW0gJiAoMUwgPDwgMjQpKQkJaXIuRXZlbnQuS2V5RXZlbnQuZHdDb250cm9sS2V5U3RhdGUgfD0gRU5IQU5DRURfS0VZOwogICAgaWYgKHN5cykJCQkJaXIuRXZlbnQuS2V5RXZlbnQuZHdDb250cm9sS2V5U3RhdGUgfD0gTEVGVF9BTFRfUFJFU1NFRDsgLyogRklYTUU6IGdvdHRhIGNob29zZSBvbmUgKi8KCiAgICBpZiAoIShpci5FdmVudC5LZXlFdmVudC5kd0NvbnRyb2xLZXlTdGF0ZSAmIEVOSEFOQ0VEX0tFWSkpCiAgICB7CglpZiAoZG93bikKCXsKCSAgICBzd2l0Y2ggKFRvVW5pY29kZSh3UGFyYW0sIEhJV09SRChsUGFyYW0pLCBrZXlTdGF0ZSwgYnVmLCAyLCAwKSkKCSAgICB7CgkgICAgY2FzZSAyOgoJCS8qIEZJWE1FLi4uIHNob3VsZCBnZW5lcmF0ZSB0d28gZXZlbnRzLi4uICovCgkJLyogZmFsbCB0aHJ1ICovCgkgICAgY2FzZSAxOgoJCWxhc3QgPSBidWZbMF07CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlsYXN0ID0gMDsKCQlicmVhazsKCSAgICB9Cgl9Cglpci5FdmVudC5LZXlFdmVudC51Q2hhci5Vbmljb2RlQ2hhciA9IGxhc3Q7IC8qIEZJWE1FIEhBQ0tZLi4uIGFuZCBidWdneSAnY296IGl0IHNob3VsZCBiZSBhIHN0YWNrLCBub3QgYSBzaW5nbGUgdmFsdWUgKi8KCWlmICghZG93bikgbGFzdCA9IDA7CiAgICB9CgogICAgV3JpdGVDb25zb2xlSW5wdXQoZGF0YS0+aENvbkluLCAmaXIsIDEsICZuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0dlbmVyYXRlTW91c2VJbnB1dFJlY29yZAogKgogKgogKi8Kc3RhdGljIHZvaWQgICAgV0NVU0VSX0dlbmVyYXRlTW91c2VJbnB1dFJlY29yZChzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgQ09PUkQgYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXUEFSQU0gd1BhcmFtLCBEV09SRCBldmVudCkKewogICAgSU5QVVRfUkVDT1JECWlyOwogICAgQllURQkJa2V5U3RhdGVbMjU2XTsKICAgIERXT1JEICAgICAgICAgICAgICAgbW9kZSwgbjsKCiAgICAvKiBNT1VTRV9FVkVOVHMgc2hvdWxkbid0IGJlIHNlbnQgdW5sZXNzIEVOQUJMRV9NT1VTRV9JTlBVVCBpcyBhY3RpdmUgKi8KICAgIGlmICghR2V0Q29uc29sZU1vZGUoZGF0YS0+aENvbkluLCAmbW9kZSkgfHwgIShtb2RlICYgRU5BQkxFX01PVVNFX0lOUFVUKSkKICAgICAgICByZXR1cm47CgogICAgaXIuRXZlbnRUeXBlID0gTU9VU0VfRVZFTlQ7CiAgICBpci5FdmVudC5Nb3VzZUV2ZW50LmR3TW91c2VQb3NpdGlvbiA9IGM7CiAgICBpci5FdmVudC5Nb3VzZUV2ZW50LmR3QnV0dG9uU3RhdGUgPSAwOwogICAgaWYgKHdQYXJhbSAmIE1LX0xCVVRUT04pIGlyLkV2ZW50Lk1vdXNlRXZlbnQuZHdCdXR0b25TdGF0ZSB8PSBGUk9NX0xFRlRfMVNUX0JVVFRPTl9QUkVTU0VEOwogICAgaWYgKHdQYXJhbSAmIE1LX01CVVRUT04pIGlyLkV2ZW50Lk1vdXNlRXZlbnQuZHdCdXR0b25TdGF0ZSB8PSBGUk9NX0xFRlRfMk5EX0JVVFRPTl9QUkVTU0VEOwogICAgaWYgKHdQYXJhbSAmIE1LX1JCVVRUT04pIGlyLkV2ZW50Lk1vdXNlRXZlbnQuZHdCdXR0b25TdGF0ZSB8PSBSSUdIVE1PU1RfQlVUVE9OX1BSRVNTRUQ7CiAgICBpci5FdmVudC5Nb3VzZUV2ZW50LmR3Q29udHJvbEtleVN0YXRlID0gV0NVU0VSX0dldEN0cmxLZXlTdGF0ZShrZXlTdGF0ZSk7CiAgICBpci5FdmVudC5Nb3VzZUV2ZW50LmR3RXZlbnRGbGFncyA9IGV2ZW50OwoKICAgIFdyaXRlQ29uc29sZUlucHV0KGRhdGEtPmhDb25JbiwgJmlyLCAxLCAmbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9Qcm9jCiAqCiAqCiAqLwpzdGF0aWMgTFJFU1VMVCBDQUxMQkFDSyBXQ1VTRVJfUHJvYyhIV05EIGhXbmQsIFVJTlQgdU1zZywgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogICAgc3RydWN0IGlubmVyX2RhdGEqCWRhdGEgPSAoc3RydWN0IGlubmVyX2RhdGEqKUdldFdpbmRvd0xvbmcoaFduZCwgMCk7CgogICAgc3dpdGNoICh1TXNnKQogICAgewogICAgY2FzZSBXTV9DUkVBVEU6CiAgICAgICAgcmV0dXJuIFdDVVNFUl9DcmVhdGUoaFduZCwgKExQQ1JFQVRFU1RSVUNUKWxQYXJhbSk7CiAgICBjYXNlIFdNX0RFU1RST1k6CglQUklWQVRFKGRhdGEpLT5oV25kID0gMDsKCVBvc3RRdWl0TWVzc2FnZSgwKTsKCWJyZWFrOwogICAgY2FzZSBXTV9QQUlOVDoKCVdDVVNFUl9QYWludChkYXRhKTsKCWJyZWFrOwogICAgY2FzZSBXTV9LRVlET1dOOgogICAgY2FzZSBXTV9LRVlVUDoKICAgICAgICBpZiAoUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbikKICAgICAgICAgICAgV0NVU0VSX0hhbmRsZVNlbGVjdGlvbktleShkYXRhLCB1TXNnID09IFdNX0tFWURPV04sIHdQYXJhbSwgbFBhcmFtKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIFdDVVNFUl9HZW5lcmF0ZUtleUlucHV0UmVjb3JkKGRhdGEsIHVNc2cgPT0gV01fS0VZRE9XTiwgd1BhcmFtLCBsUGFyYW0sIEZBTFNFKTsKCWJyZWFrOwogICAgY2FzZSBXTV9TWVNLRVlET1dOOgogICAgY2FzZSBXTV9TWVNLRVlVUDoKCVdDVVNFUl9HZW5lcmF0ZUtleUlucHV0UmVjb3JkKGRhdGEsIHVNc2cgPT0gV01fU1lTS0VZRE9XTiwgd1BhcmFtLCBsUGFyYW0sIFRSVUUpOwoJYnJlYWs7CiAgICBjYXNlIFdNX0xCVVRUT05ET1dOOgogICAgICAgIGlmIChkYXRhLT5jdXJjZmcucXVpY2tfZWRpdCkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID0gRkFMU0U7CiAgICAgICAgICAgICAgICBXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIDApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyID0gV0NVU0VSX0dldENlbGwoZGF0YSwgbFBhcmFtKTsKICAgICAgICAgICAgICAgIFNldENhcHR1cmUoUFJJVkFURShkYXRhKS0+aFduZCk7CiAgICAgICAgICAgICAgICBXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIDApOwogICAgICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiA9IFRSVUU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgV0NVU0VSX0dlbmVyYXRlTW91c2VJbnB1dFJlY29yZChkYXRhLCBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCB3UGFyYW0sIDApOwogICAgICAgIH0KCWJyZWFrOwogICAgY2FzZSBXTV9NT1VTRU1PVkU6CiAgICAgICAgaWYgKGRhdGEtPmN1cmNmZy5xdWlja19lZGl0KQogICAgICAgIHsKICAgICAgICAgICAgaWYgKEdldENhcHR1cmUoKSA9PSBQUklWQVRFKGRhdGEpLT5oV25kICYmIFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24gJiYKICAgICAgICAgICAgICAgICh3UGFyYW0gJiBNS19MQlVUVE9OKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0NVU0VSX01vdmVTZWxlY3Rpb24oZGF0YSwgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLCBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCBGQUxTRSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgV0NVU0VSX0dlbmVyYXRlTW91c2VJbnB1dFJlY29yZChkYXRhLCBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCB3UGFyYW0sIE1PVVNFX01PVkVEKTsKICAgICAgICB9CglicmVhazsKICAgIGNhc2UgV01fTEJVVFRPTlVQOgogICAgICAgIGlmIChkYXRhLT5jdXJjZmcucXVpY2tfZWRpdCkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChHZXRDYXB0dXJlKCkgPT0gUFJJVkFURShkYXRhKS0+aFduZCAmJiBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uICYmCiAgICAgICAgICAgICAgICAod1BhcmFtJiBNS19MQlVUVE9OKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0NVU0VSX01vdmVTZWxlY3Rpb24oZGF0YSwgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLCBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCBUUlVFKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBXQ1VTRVJfR2VuZXJhdGVNb3VzZUlucHV0UmVjb3JkKGRhdGEsIFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSksIHdQYXJhbSwgMCk7CiAgICAgICAgfQoJYnJlYWs7CiAgICBjYXNlIFdNX1JCVVRUT05ET1dOOgogICAgICAgIGlmICgod1BhcmFtICYgKE1LX0NPTlRST0x8TUtfU0hJRlQpKSA9PSBkYXRhLT5jdXJjZmcubWVudV9tYXNrKQogICAgICAgIHsKICAgICAgICAgICAgUkVDVCAgICAgICAgcjsKCiAgICAgICAgICAgIEdldFdpbmRvd1JlY3QoaFduZCwgJnIpOwogICAgICAgICAgICBXQ1VTRVJfU2V0TWVudURldGFpbHMoZGF0YSwgUFJJVkFURShkYXRhKS0+aFBvcE1lbnUpOwogICAgICAgICAgICBUcmFja1BvcHVwTWVudShQUklWQVRFKGRhdGEpLT5oUG9wTWVudSwgVFBNX0xFRlRBTElHTnxUUE1fVE9QQUxJR04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHIubGVmdCArIExPV09SRChsUGFyYW0pLCByLnRvcCArIEhJV09SRChsUGFyYW0pLCAwLCBoV25kLCBOVUxMKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgV0NVU0VSX0dlbmVyYXRlTW91c2VJbnB1dFJlY29yZChkYXRhLCBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCB3UGFyYW0sIDApOwogICAgICAgIH0KCWJyZWFrOwogICAgY2FzZSBXTV9SQlVUVE9OVVA6CiAgICAgICAgLyogbm8gbmVlZCB0byB0cmFjayBmb3IgcmJ1dHRvbiB1cCB3aGVuIG9wZW5pbmcgdGhlIHBvcHVwLi4uIHRoZSBldmVudCB3aWxsIGJlCiAgICAgICAgICogc3dhbGxvd2VkIGJ5IFRyYWNrUG9wdXBNZW51ICovCiAgICAgICAgV0NVU0VSX0dlbmVyYXRlTW91c2VJbnB1dFJlY29yZChkYXRhLCBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCB3UGFyYW0sIDApOwoJYnJlYWs7CiAgICBjYXNlIFdNX01PVVNFV0hFRUw6CiAgICAgICAgLyogRklYTUU6IHNob3VsZCB3ZSBzY3JvbGwgdG9vID8gKi8KICAgICAgICBXQ1VTRVJfR2VuZXJhdGVNb3VzZUlucHV0UmVjb3JkKGRhdGEsIFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSksIHdQYXJhbSwgTU9VU0VfV0hFRUxFRCk7CglicmVhazsKICAgIGNhc2UgV01fU0VURk9DVVM6CglpZiAoZGF0YS0+Y3VyY2ZnLmN1cnNvcl92aXNpYmxlKQoJewoJICAgIENyZWF0ZUNhcmV0KFBSSVZBVEUoZGF0YSktPmhXbmQsIFBSSVZBVEUoZGF0YSktPmN1cnNvcl9iaXRtYXAsCiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoLCBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQpOwoJICAgIFdDVVNFUl9Qb3NDdXJzb3IoZGF0YSk7Cgl9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFdNX0tJTExGT0NVUzoKCWlmIChkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUpCgkgICAgRGVzdHJveUNhcmV0KCk7CglicmVhazsKICAgIGNhc2UgV01fSFNDUk9MTDoKICAgICAgICB7CiAgICAgICAgICAgIGludAlwb3MgPSBkYXRhLT5jdXJjZmcud2luX3Bvcy5YOwoKICAgICAgICAgICAgc3dpdGNoIChMT1dPUkQod1BhcmFtKSkKICAgICAgICAgICAgewogICAgICAgICAgICBjYXNlIFNCX1BBR0VVUDogCXBvcyAtPSA4OyAJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX1BBR0VET1dOOiAJcG9zICs9IDg7IAkJYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU0JfTElORVVQOiAJcG9zLS07CQkJYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU0JfTElORURPV046IAlwb3MrKzsJIAkJYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU0JfVEhVTUJUUkFDSzogcG9zID0gSElXT1JEKHdQYXJhbSk7CWJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OiAJCQkJCWJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChwb3MgPCAwKSBwb3MgPSAwOwogICAgICAgICAgICBpZiAocG9zID4gZGF0YS0+Y3VyY2ZnLnNiX3dpZHRoIC0gZGF0YS0+Y3VyY2ZnLndpbl93aWR0aCkKICAgICAgICAgICAgICAgIHBvcyA9IGRhdGEtPmN1cmNmZy5zYl93aWR0aCAtIGRhdGEtPmN1cmNmZy53aW5fd2lkdGg7CiAgICAgICAgICAgIGlmIChwb3MgIT0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgU2Nyb2xsV2luZG93KGhXbmQsIChkYXRhLT5jdXJjZmcud2luX3Bvcy5YIC0gcG9zKSAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE5VTEwpOwogICAgICAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWCA9IHBvczsKICAgICAgICAgICAgICAgIFNldFNjcm9sbFBvcyhoV25kLCBTQl9IT1JaLCBwb3MsIFRSVUUpOwogICAgICAgICAgICAgICAgVXBkYXRlV2luZG93KGhXbmQpOwogICAgICAgICAgICAgICAgV0NVU0VSX1Bvc0N1cnNvcihkYXRhKTsKICAgICAgICAgICAgICAgIFdJTkVDT05fTm90aWZ5V2luZG93Q2hhbmdlKGRhdGEpOwogICAgICAgICAgICB9CiAgICAgICAgfQoJYnJlYWs7CiAgICBjYXNlIFdNX1ZTQ1JPTEw6CiAgICAgICAgewoJICAgIGludAlwb3MgPSBkYXRhLT5jdXJjZmcud2luX3Bvcy5ZOwoKCSAgICBzd2l0Y2ggKExPV09SRCh3UGFyYW0pKQoJICAgIHsKICAgICAgICAgICAgY2FzZSBTQl9QQUdFVVA6IAlwb3MgLT0gODsgCQlicmVhazsKICAgICAgICAgICAgY2FzZSBTQl9QQUdFRE9XTjogCXBvcyArPSA4OyAJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX0xJTkVVUDogCXBvcy0tOwkJCWJyZWFrOwoJICAgIGNhc2UgU0JfTElORURPV046IAlwb3MrKzsJIAkJYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU0JfVEhVTUJUUkFDSzogcG9zID0gSElXT1JEKHdQYXJhbSk7CWJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OiAJCQkJCWJyZWFrOwoJICAgIH0KCSAgICBpZiAocG9zIDwgMCkgcG9zID0gMDsKCSAgICBpZiAocG9zID4gZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCAtIGRhdGEtPmN1cmNmZy53aW5faGVpZ2h0KQogICAgICAgICAgICAgICAgcG9zID0gZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCAtIGRhdGEtPmN1cmNmZy53aW5faGVpZ2h0OwoJICAgIGlmIChwb3MgIT0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSkKCSAgICB7CgkJU2Nyb2xsV2luZG93KGhXbmQsIDAsIChkYXRhLT5jdXJjZmcud2luX3Bvcy5ZIC0gcG9zKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMKTsKCQlkYXRhLT5jdXJjZmcud2luX3Bvcy5ZID0gcG9zOwoJCVNldFNjcm9sbFBvcyhoV25kLCBTQl9WRVJULCBwb3MsIFRSVUUpOwoJCVVwZGF0ZVdpbmRvdyhoV25kKTsKCQlXQ1VTRVJfUG9zQ3Vyc29yKGRhdGEpOwoJCVdJTkVDT05fTm90aWZ5V2luZG93Q2hhbmdlKGRhdGEpOwoJICAgIH0KCiAgICAgICAgfQogICAgY2FzZSBXTV9TWVNDT01NQU5EOgoJc3dpdGNoICh3UGFyYW0pCgl7CgljYXNlIElEU19ERUZBVUxUOgoJICAgIFdDVVNFUl9HZXRQcm9wZXJ0aWVzKGRhdGEsIEZBTFNFKTsKCSAgICBicmVhazsKCWNhc2UgSURTX1BST1BFUlRJRVM6CgkgICAgV0NVU0VSX0dldFByb3BlcnRpZXMoZGF0YSwgVFJVRSk7CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIHJldHVybiBEZWZXaW5kb3dQcm9jKGhXbmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKCX0KCWJyZWFrOwogICAgY2FzZSBXTV9DT01NQU5EOgoJc3dpdGNoICh3UGFyYW0pCgl7CgljYXNlIElEU19ERUZBVUxUOgoJICAgIFdDVVNFUl9HZXRQcm9wZXJ0aWVzKGRhdGEsIEZBTFNFKTsKCSAgICBicmVhazsKCWNhc2UgSURTX1BST1BFUlRJRVM6CgkgICAgV0NVU0VSX0dldFByb3BlcnRpZXMoZGF0YSwgVFJVRSk7CgkgICAgYnJlYWs7CgljYXNlIElEU19NQVJLOgogICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWCA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MS5ZID0gMDsKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlggPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIuWSA9IDA7CiAgICAgICAgICAgIFdDVVNFUl9TZXRTZWxlY3Rpb24oZGF0YSwgMCk7CiAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24gPSBUUlVFOwoJICAgIGJyZWFrOwoJY2FzZSBJRFNfQ09QWToKICAgICAgICAgICAgaWYgKFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24gPSBGQUxTRTsKICAgICAgICAgICAgICAgIFdDVVNFUl9TZXRTZWxlY3Rpb24oZGF0YSwgMCk7CiAgICAgICAgICAgICAgICBXQ1VTRVJfQ29weVNlbGVjdGlvblRvQ2xpcGJvYXJkKGRhdGEpOwogICAgICAgICAgICB9CgkgICAgYnJlYWs7CgljYXNlIElEU19QQVNURToKCSAgICBXQ1VTRVJfUGFzdGVGcm9tQ2xpcGJvYXJkKGRhdGEpOwoJICAgIGJyZWFrOwoJY2FzZSBJRFNfU0VMRUNUQUxMOgogICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWCA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MS5ZID0gMDsKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlggPSAoZGF0YS0+Y3VyY2ZnLnNiX3dpZHRoIC0gMSkgKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlkgPSAoZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCAtIDEpICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0OwogICAgICAgICAgICBXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIDApOwogICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID0gVFJVRTsKCSAgICBicmVhazsKCWNhc2UgSURTX1NDUk9MTDoKCWNhc2UgSURTX1NFQVJDSDoKCSAgICBXSU5FX0ZJWE1FKCJVbmhhbmRsZWQgeWV0IGNvbW1hbmQ6ICV4XG4iLCB3UGFyYW0pOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICByZXR1cm4gRGVmV2luZG93UHJvYyhoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7Cgl9CglicmVhazsKICAgIGNhc2UgV01fSU5JVE1FTlVQT1BVUDoKCWlmICghSElXT1JEKGxQYXJhbSkpCXJldHVybiBEZWZXaW5kb3dQcm9jKGhXbmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKCVdDVVNFUl9TZXRNZW51RGV0YWlscyhkYXRhLCBHZXRTeXN0ZW1NZW51KFBSSVZBVEUoZGF0YSktPmhXbmQsIEZBTFNFKSk7CglicmVhazsKICAgIGRlZmF1bHQ6CglyZXR1cm4gRGVmV2luZG93UHJvYyhoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7CiAgICB9CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0RlbGV0ZUJhY2tlbmQKICoKICoKICovCnZvaWQgV0NVU0VSX0RlbGV0ZUJhY2tlbmQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIGlmICghUFJJVkFURShkYXRhKSkgcmV0dXJuOwogICAgaWYgKFBSSVZBVEUoZGF0YSktPmhNZW1EQykJCURlbGV0ZURDKFBSSVZBVEUoZGF0YSktPmhNZW1EQyk7CiAgICBpZiAoUFJJVkFURShkYXRhKS0+aFduZCkJCURlc3Ryb3lXaW5kb3coUFJJVkFURShkYXRhKS0+aFduZCk7CiAgICBpZiAoUFJJVkFURShkYXRhKS0+aEZvbnQpCQlEZWxldGVPYmplY3QoUFJJVkFURShkYXRhKS0+aEZvbnQpOwogICAgaWYgKFBSSVZBVEUoZGF0YSktPmN1cnNvcl9iaXRtYXApCURlbGV0ZU9iamVjdChQUklWQVRFKGRhdGEpLT5jdXJzb3JfYml0bWFwKTsKICAgIGlmIChQUklWQVRFKGRhdGEpLT5oQml0bWFwKQkJRGVsZXRlT2JqZWN0KFBSSVZBVEUoZGF0YSktPmhCaXRtYXApOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgUFJJVkFURShkYXRhKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9NYWluTG9vcAogKgogKgogKi8Kc3RhdGljIGludCBXQ1VTRVJfTWFpbkxvb3Aoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIE1TRwkJbXNnOwoKICAgIFNob3dXaW5kb3coUFJJVkFURShkYXRhKS0+aFduZCwgU1dfU0hPVyk7CiAgICBmb3IgKDs7KQogICAgewoJc3dpdGNoIChNc2dXYWl0Rm9yTXVsdGlwbGVPYmplY3RzKDEsICZkYXRhLT5oU3luY2hybywgRkFMU0UsIElORklOSVRFLCBRU19BTExJTlBVVCkpCgl7CgljYXNlIFdBSVRfT0JKRUNUXzA6CgkgICAgaWYgKCFXSU5FQ09OX0dyYWJDaGFuZ2VzKGRhdGEpICYmIGRhdGEtPmN1cmNmZy5leGl0X29uX2RpZSkKICAgICAgICAgICAgICAgIFBvc3RRdWl0TWVzc2FnZSgwKTsKCSAgICBicmVhazsKCWNhc2UgV0FJVF9PQkpFQ1RfMCsxOgoJICAgIC8qIG5lZWQgdG8gdXNlIFBlZWtNZXNzYWdlIGxvb3AgaW5zdGVhZCBvZiBzaW1wbGUgR2V0TWVzc2FnZToKCSAgICAgKiBtdWx0aXBsZSBtZXNzYWdlcyBtaWdodCBoYXZlIGFycml2ZWQgaW4gYmV0d2VlbiwKCSAgICAgKiBzbyBHZXRNZXNzYWdlIHdvdWxkIGxlYWQgdG8gZGVsYXllZCBwcm9jZXNzaW5nICovCgkgICAgd2hpbGUgKFBlZWtNZXNzYWdlKCZtc2csIDAsIDAsIDAsIFBNX1JFTU9WRSkpCgkgICAgewogICAgICAgICAgICAgICAgaWYgKG1zZy5tZXNzYWdlID09IFdNX1FVSVQpIHJldHVybiAwOwogICAgICAgICAgICAgICAgV0lORV9UUkFDRSgiZGlzcGF0Y2hpbmcgbXNnICUwNHhcbiIsIG1zZy5tZXNzYWdlKTsKICAgICAgICAgICAgICAgIERpc3BhdGNoTWVzc2FnZSgmbXNnKTsKCSAgICB9CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIFdJTkVfRVJSKCJnb3QgcGJcbiIpOwoJICAgIC8qIGVyciAqLwoJICAgIGJyZWFrOwoJfQogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfSW5pdEJhY2tlbmQKICoKICogSW5pdGlhbGlzYXRpb24gcGFydCBJSTogY3JlYXRpb24gb2Ygd2luZG93LgogKgogKi8KQk9PTCBXQ1VTRVJfSW5pdEJhY2tlbmQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIHN0YXRpYyBXQ0hBUiB3Q2xhc3NOYW1lW10gPSB7J1cnLCdpJywnbicsJ2UnLCdDJywnbycsJ24nLCdzJywnbycsJ2wnLCdlJywnQycsJ2wnLCdhJywncycsJ3MnLDB9OwoKICAgIFdORENMQVNTCQl3bmRjbGFzczsKCiAgICBkYXRhLT5wcml2YXRlID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihzdHJ1Y3QgaW5uZXJfZGF0YV91c2VyKSk7CiAgICBpZiAoIWRhdGEtPnByaXZhdGUpIHJldHVybiBGQUxTRTsKCiAgICBkYXRhLT5mbk1haW5Mb29wID0gV0NVU0VSX01haW5Mb29wOwogICAgZGF0YS0+Zm5Qb3NDdXJzb3IgPSBXQ1VTRVJfUG9zQ3Vyc29yOwogICAgZGF0YS0+Zm5TaGFwZUN1cnNvciA9IFdDVVNFUl9TaGFwZUN1cnNvcjsKICAgIGRhdGEtPmZuQ29tcHV0ZVBvc2l0aW9ucyA9IFdDVVNFUl9Db21wdXRlUG9zaXRpb25zOwogICAgZGF0YS0+Zm5SZWZyZXNoID0gV0NVU0VSX1JlZnJlc2g7CiAgICBkYXRhLT5mblJlc2l6ZVNjcmVlbkJ1ZmZlciA9IFdDVVNFUl9SZXNpemVTY3JlZW5CdWZmZXI7CiAgICBkYXRhLT5mblNldFRpdGxlID0gV0NVU0VSX1NldFRpdGxlOwogICAgZGF0YS0+Zm5TZXRGb250ID0gV0NVU0VSX1NldEZvbnRQbXQ7CiAgICBkYXRhLT5mblNjcm9sbCA9IFdDVVNFUl9TY3JvbGw7CiAgICBkYXRhLT5mbkRlbGV0ZUJhY2tlbmQgPSBXQ1VTRVJfRGVsZXRlQmFja2VuZDsKCiAgICB3bmRjbGFzcy5zdHlsZSAgICAgICAgID0gMDsKICAgIHduZGNsYXNzLmxwZm5XbmRQcm9jICAgPSBXQ1VTRVJfUHJvYzsKICAgIHduZGNsYXNzLmNiQ2xzRXh0cmEgICAgPSAwOwogICAgd25kY2xhc3MuY2JXbmRFeHRyYSAgICA9IHNpemVvZihEV09SRCk7CiAgICB3bmRjbGFzcy5oSW5zdGFuY2UgICAgID0gR2V0TW9kdWxlSGFuZGxlKE5VTEwpOwogICAgd25kY2xhc3MuaEljb24gICAgICAgICA9IExvYWRJY29uKDAsIElESV9XSU5MT0dPKTsKICAgIHduZGNsYXNzLmhDdXJzb3IgICAgICAgPSBMb2FkQ3Vyc29yKDAsIElEQ19BUlJPVyk7CiAgICB3bmRjbGFzcy5oYnJCYWNrZ3JvdW5kID0gR2V0U3RvY2tPYmplY3QoQkxBQ0tfQlJVU0gpOwogICAgd25kY2xhc3MubHBzek1lbnVOYW1lICA9IE5VTEw7CiAgICB3bmRjbGFzcy5scHN6Q2xhc3NOYW1lID0gd0NsYXNzTmFtZTsKCiAgICBSZWdpc3RlckNsYXNzKCZ3bmRjbGFzcyk7CgogICAgQ3JlYXRlV2luZG93KHduZGNsYXNzLmxwc3pDbGFzc05hbWUsIE5VTEwsCgkJIFdTX09WRVJMQVBQRUR8V1NfQ0FQVElPTnxXU19TWVNNRU5VfFdTX1RISUNLRlJBTUV8V1NfTUlOSU1JWkVCT1h8V1NfSFNDUk9MTHxXU19WU0NST0xMLAoJCSBDV19VU0VERUZBVUxULCBDV19VU0VERUZBVUxULCAwLCAwLCAwLCAwLCB3bmRjbGFzcy5oSW5zdGFuY2UsIGRhdGEpOwogICAgaWYgKCFQUklWQVRFKGRhdGEpLT5oV25kKSByZXR1cm4gRkFMU0U7CgogICAgcmV0dXJuIFRSVUU7Cn0K