LyoKICogYSBHVUkgYXBwbGljYXRpb24gZm9yIGRpc3BsYXlpbmcgYSBjb25zb2xlCiAqCVVTRVIzMiBiYWNrIGVuZAogKiBDb3B5cmlnaHQgMjAwMSBFcmljIFBvdWVjaAogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSAid2luZWNvbl91c2VyLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwod2luZWNvbnNvbGUpOwpXSU5FX0RFQ0xBUkVfREVCVUdfQ0hBTk5FTCh3Y19mb250KTsKCi8qIG1hcHBpbmcgY29uc29sZSBjb2xvcnMgdG8gUkdCIHZhbHVlcyAqLwpDT0xPUlJFRglXQ1VTRVJfQ29sb3JNYXBbMTZdID0KewogICAgUkdCKDB4MDAsIDB4MDAsIDB4MDApLCBSR0IoMHgwMCwgMHgwMCwgMHg4MCksIFJHQigweDAwLCAweDgwLCAweDAwKSwgUkdCKDB4MDAsIDB4ODAsIDB4ODApLAogICAgUkdCKDB4ODAsIDB4MDAsIDB4MDApLCBSR0IoMHg4MCwgMHgwMCwgMHg4MCksIFJHQigweDgwLCAweDgwLCAweDAwKSwgUkdCKDB4ODAsIDB4ODAsIDB4ODApLAogICAgUkdCKDB4QzAsIDB4QzAsIDB4QzApLCBSR0IoMHgwMCwgMHgwMCwgMHhGRiksIFJHQigweDAwLCAweEZGLCAweDAwKSwgUkdCKDB4MDAsIDB4RkYsIDB4RkYpLAogICAgUkdCKDB4RkYsIDB4MDAsIDB4MDApLCBSR0IoMHhGRiwgMHgwMCwgMHhGRiksIFJHQigweEZGLCAweEZGLCAweDAwKSwgUkdCKDB4RkYsIDB4RkYsIDB4RkYpLAp9OwoKc3RhdGljIEJPT0wgV0NVU0VSX1NldEZvbnQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIGNvbnN0IExPR0ZPTlQqIGZvbnQpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0ZpbGxNZW1EQwogKgogKiBGaWxscyB0aGUgTWVtIERDIHdpdGggY3VycmVudCBjZWxscyB2YWx1ZXMKICovCnN0YXRpYyB2b2lkIFdDVVNFUl9GaWxsTWVtREMoY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIGludCB1cGRfdHAsIGludCB1cGRfYm0pCnsKICAgIHVuc2lnbmVkCQlpLCBqLCBrOwogICAgQ0hBUl9JTkZPKgkJY2VsbDsKICAgIEhGT05UCQloT2xkRm9udDsKICAgIFdPUkQJCWF0dHI7CiAgICBXQ0hBUioJCWxpbmU7CiAgICBSRUNUICAgICAgICAgICAgICAgIHI7CiAgICBIQlJVU0ggICAgICAgICAgICAgIGhicjsKCiAgICAvKiBubyBmb250IGhhcyBiZWVuIHNldCB1cCB5ZXQsIGRvbid0IHdvcnJ5IGFib3V0IGZpbGxpbmcgdGhlIGJpdG1hcCwKICAgICAqIHdlJ2xsIGRvIGl0IG9uY2UgYSBmb250IGlzIGNob3NlbgogICAgICovCiAgICBpZiAoIVBSSVZBVEUoZGF0YSktPmhGb250KSByZXR1cm47CgogICAgLyogRklYTUU6IGNvdWxkIHNldCB1cCBhIG1lY2hhbmlzbSB0byByZXVzZSB0aGUgbGluZSBiZXR3ZWVuIGRpZmZlcmVudAogICAgICogY2FsbHMgdG8gdGhpcyBmdW5jdGlvbgogICAgICovCiAgICBpZiAoIShsaW5lID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGRhdGEtPmN1cmNmZy5zYl93aWR0aCAqIHNpemVvZihXQ0hBUikpKSkKICAgICAgICBXSU5FQ09OX0ZhdGFsKCJPT01cbiIpOwoKICAgIGhPbGRGb250ID0gU2VsZWN0T2JqZWN0KFBSSVZBVEUoZGF0YSktPmhNZW1EQywgUFJJVkFURShkYXRhKS0+aEZvbnQpOwogICAgZm9yIChqID0gdXBkX3RwOyBqIDw9IHVwZF9ibTsgaisrKQogICAgewoJY2VsbCA9ICZkYXRhLT5jZWxsc1tqICogZGF0YS0+Y3VyY2ZnLnNiX3dpZHRoXTsKCWZvciAoaSA9IDA7IGkgPCBkYXRhLT5jdXJjZmcuc2Jfd2lkdGg7IGkrKykKCXsKCSAgICBhdHRyID0gY2VsbFtpXS5BdHRyaWJ1dGVzOwoJICAgIFNldEJrQ29sb3IoUFJJVkFURShkYXRhKS0+aE1lbURDLCBXQ1VTRVJfQ29sb3JNYXBbKGF0dHI+PjQpJjB4MEZdKTsKCSAgICBTZXRUZXh0Q29sb3IoUFJJVkFURShkYXRhKS0+aE1lbURDLCBXQ1VTRVJfQ29sb3JNYXBbYXR0ciYweDBGXSk7CgkgICAgZm9yIChrID0gaTsgayA8IGRhdGEtPmN1cmNmZy5zYl93aWR0aCAmJiBjZWxsW2tdLkF0dHJpYnV0ZXMgPT0gYXR0cjsgaysrKQoJICAgIHsKCQlsaW5lW2sgLSBpXSA9IGNlbGxba10uQ2hhci5Vbmljb2RlQ2hhcjsKCSAgICB9CgkgICAgVGV4dE91dChQUklWQVRFKGRhdGEpLT5oTWVtREMsIGkgKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwgaiAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCwKCQkgICAgbGluZSwgayAtIGkpOwogICAgICAgICAgICBpZiAoUFJJVkFURShkYXRhKS0+ZXh0X2xlYWRpbmcgJiYgCiAgICAgICAgICAgICAgICAoaGJyID0gQ3JlYXRlU29saWRCcnVzaChXQ1VTRVJfQ29sb3JNYXBbKGF0dHI+PjQpJjB4MEZdKSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHIubGVmdCAgID0gaSAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoOwogICAgICAgICAgICAgICAgci50b3AgICAgPSAoaiArIDEpICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0IC0gUFJJVkFURShkYXRhKS0+ZXh0X2xlYWRpbmc7CiAgICAgICAgICAgICAgICByLnJpZ2h0ICA9IGsgKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgICAgICAgICAgICAgIHIuYm90dG9tID0gKGogKyAxKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKICAgICAgICAgICAgICAgIEZpbGxSZWN0KFBSSVZBVEUoZGF0YSktPmhNZW1EQywgJnIsIGhicik7CiAgICAgICAgICAgICAgICBEZWxldGVPYmplY3QoaGJyKTsKICAgICAgICAgICAgfQoJICAgIGkgPSBrIC0gMTsKCX0KICAgIH0KICAgIFNlbGVjdE9iamVjdChQUklWQVRFKGRhdGEpLT5oTWVtREMsIGhPbGRGb250KTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGxpbmUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfTmV3Qml0bWFwCiAqCiAqIEVpdGhlciB0aGUgZm9udCBnZW9tZXRyeSBvciB0aGUgc2IgZ2VvbWV0cnkgaGFzIGNoYW5nZWQuIHdlIG5lZWQKICogdG8gcmVjcmVhdGUgdGhlIGJpdG1hcCBnZW9tZXRyeS4KICovCnN0YXRpYyB2b2lkIFdDVVNFUl9OZXdCaXRtYXAoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIEhEQyAgICAgICAgIGhEQzsKICAgIEhCSVRNQVAJaG5ldywgaG9sZDsKCiAgICBpZiAoIWRhdGEtPmN1cmNmZy5zYl93aWR0aCB8fCAhZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCB8fAogICAgICAgICFQUklWQVRFKGRhdGEpLT5oRm9udCB8fCAhKGhEQyA9IEdldERDKFBSSVZBVEUoZGF0YSktPmhXbmQpKSkKICAgICAgICByZXR1cm47CiAgICBobmV3ID0gQ3JlYXRlQ29tcGF0aWJsZUJpdG1hcChoREMsCgkJCQkgIGRhdGEtPmN1cmNmZy5zYl93aWR0aCAgKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwKCQkJCSAgZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCk7CiAgICBSZWxlYXNlREMoUFJJVkFURShkYXRhKS0+aFduZCwgaERDKTsKICAgIGhvbGQgPSBTZWxlY3RPYmplY3QoUFJJVkFURShkYXRhKS0+aE1lbURDLCBobmV3KTsKCiAgICBpZiAoUFJJVkFURShkYXRhKS0+aEJpdG1hcCkKICAgIHsKCWlmIChob2xkID09IFBSSVZBVEUoZGF0YSktPmhCaXRtYXApCgkgICAgRGVsZXRlT2JqZWN0KFBSSVZBVEUoZGF0YSktPmhCaXRtYXApOwoJZWxzZQoJICAgIFdJTkVfRklYTUUoImxlYWtcbiIpOwogICAgfQogICAgUFJJVkFURShkYXRhKS0+aEJpdG1hcCA9IGhuZXc7CiAgICBXQ1VTRVJfRmlsbE1lbURDKGRhdGEsIDAsIGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgLSAxKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1Jlc2l6ZVNjcmVlbkJ1ZmZlcgogKgogKgogKi8Kc3RhdGljIHZvaWQgV0NVU0VSX1Jlc2l6ZVNjcmVlbkJ1ZmZlcihzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgV0NVU0VSX05ld0JpdG1hcChkYXRhKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1Bvc0N1cnNvcgogKgogKiBTZXQgYSBuZXcgcG9zaXRpb24gZm9yIHRoZSBjdXJzb3IKICovCnN0YXRpYyB2b2lkCVdDVVNFUl9Qb3NDdXJzb3IoY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIGlmIChQUklWQVRFKGRhdGEpLT5oV25kICE9IEdldEZvY3VzKCkgfHwgIWRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkgcmV0dXJuOwoKICAgIFNldENhcmV0UG9zKChkYXRhLT5jdXJzb3IuWCAtIGRhdGEtPmN1cmNmZy53aW5fcG9zLlgpICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGgsCgkJKGRhdGEtPmN1cnNvci5ZIC0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSkgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQpOwogICAgU2hvd0NhcmV0KFBSSVZBVEUoZGF0YSktPmhXbmQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfU2hhcGVDdXJzb3IKICoKICogU2V0cyBhIG5ldyBzaGFwZSBmb3IgdGhlIGN1cnNvcgogKi8Kc3RhdGljIHZvaWQJV0NVU0VSX1NoYXBlQ3Vyc29yKHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBpbnQgc2l6ZSwgaW50IHZpcywgQk9PTCBmb3JjZSkKewogICAgaWYgKGZvcmNlIHx8IHNpemUgIT0gZGF0YS0+Y3VyY2ZnLmN1cnNvcl9zaXplKQogICAgewoJaWYgKGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSAmJiBQUklWQVRFKGRhdGEpLT5oV25kID09IEdldEZvY3VzKCkpIERlc3Ryb3lDYXJldCgpOwoJaWYgKFBSSVZBVEUoZGF0YSktPmN1cnNvcl9iaXRtYXApIERlbGV0ZU9iamVjdChQUklWQVRFKGRhdGEpLT5jdXJzb3JfYml0bWFwKTsKCVBSSVZBVEUoZGF0YSktPmN1cnNvcl9iaXRtYXAgPSBOVUxMOwoJaWYgKHNpemUgIT0gMTAwKQoJewoJICAgIGludAkJdzE2YjsgLyogbnVtYmVyIG9mIGJ5dGVzIHBlciByb3csIGFsaWduZWQgb24gd29yZCBzaXplICovCgkgICAgQllURSoJcHRyOwoJICAgIGludAkJaSwgaiwgbmJsOwoKCSAgICB3MTZiID0gKChkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCArIDE1KSAmIH4xNSkgLyA4OwoJICAgIHB0ciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCB3MTZiICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0KTsKCSAgICBpZiAoIXB0cikgV0lORUNPTl9GYXRhbCgiT09NIik7CgkgICAgbmJsID0gbWF4KChkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQgKiBzaXplKSAvIDEwMCwgMSk7CgkgICAgZm9yIChqID0gZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0IC0gbmJsOyBqIDwgZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0OyBqKyspCgkgICAgewoJCWZvciAoaSA9IDA7IGkgPCBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsgaSsrKQoJCXsKCQkgICAgcHRyW3cxNmIgKiBqICsgKGkgLyA4KV0gfD0gMHg4MCA+PiAoaSAmIDcpOwoJCX0KCSAgICB9CgkgICAgUFJJVkFURShkYXRhKS0+Y3Vyc29yX2JpdG1hcCA9IENyZWF0ZUJpdG1hcChkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQsIDEsIDEsIHB0cik7CgkgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcHRyKTsKCX0KCWRhdGEtPmN1cmNmZy5jdXJzb3Jfc2l6ZSA9IHNpemU7CglkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUgPSAtMTsKICAgIH0KCiAgICB2aXMgPSAodmlzKSA/IFRSVUUgOiBGQUxTRTsKICAgIGlmIChmb3JjZSB8fCB2aXMgIT0gZGF0YS0+Y3VyY2ZnLmN1cnNvcl92aXNpYmxlKQogICAgewoJZGF0YS0+Y3VyY2ZnLmN1cnNvcl92aXNpYmxlID0gdmlzOwoJaWYgKFBSSVZBVEUoZGF0YSktPmhXbmQgPT0gR2V0Rm9jdXMoKSkKCXsKCSAgICBpZiAodmlzKQoJICAgIHsKCQlDcmVhdGVDYXJldChQUklWQVRFKGRhdGEpLT5oV25kLCBQUklWQVRFKGRhdGEpLT5jdXJzb3JfYml0bWFwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGgsIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCk7CgkJV0NVU0VSX1Bvc0N1cnNvcihkYXRhKTsKCSAgICB9CgkgICAgZWxzZQoJICAgIHsKCQlEZXN0cm95Q2FyZXQoKTsKCSAgICB9Cgl9CiAgICB9CiAgICBXSU5FQ09OX0R1bXBDb25maWcoImNyc3IiLCAmZGF0YS0+Y3VyY2ZnKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0NvbXB1dGVQb3NpdGlvbnMKICoKICogUmVjb21wdXRlcyBhbGwgdGhlIGNvbXBvbmVudHMgKG1haW5seSBzY3JvbGwgYmFycykgcG9zaXRpb25zCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfQ29tcHV0ZVBvc2l0aW9ucyhzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgUkVDVAkJcjsKICAgIGludAkJCWR4LCBkeTsKCiAgICAvKiBjb21wdXRlIHdpbmRvdyBzaXplIGZyb20gZGVzaXJlZCBjbGllbnQgc2l6ZSAqLwogICAgci5sZWZ0ID0gci50b3AgPSAwOwogICAgci5yaWdodCA9IGRhdGEtPmN1cmNmZy53aW5fd2lkdGggKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgIHIuYm90dG9tID0gZGF0YS0+Y3VyY2ZnLndpbl9oZWlnaHQgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQ7CgogICAgaWYgKElzUmVjdEVtcHR5KCZyKSkgcmV0dXJuOwoKICAgIEFkanVzdFdpbmRvd1JlY3QoJnIsIEdldFdpbmRvd0xvbmcoUFJJVkFURShkYXRhKS0+aFduZCwgR1dMX1NUWUxFKSwgRkFMU0UpOwoKICAgIGR4ID0gZHkgPSAwOwogICAgaWYgKGRhdGEtPmN1cmNmZy5zYl93aWR0aCA+IGRhdGEtPmN1cmNmZy53aW5fd2lkdGgpCiAgICB7CglkeSA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lIU0NST0xMKTsKCVNldFNjcm9sbFJhbmdlKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX0hPUlosIDAsCiAgICAgICAgICAgICAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLnNiX3dpZHRoIC0gZGF0YS0+Y3VyY2ZnLndpbl93aWR0aCwgRkFMU0UpOwoJU2V0U2Nyb2xsUG9zKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX0hPUlosIDAsIEZBTFNFKTsgLyogRklYTUUgKi8KCVNob3dTY3JvbGxCYXIoUFJJVkFURShkYXRhKS0+aFduZCwgU0JfSE9SWiwgVFJVRSk7CiAgICB9CiAgICBlbHNlCiAgICB7CglTaG93U2Nyb2xsQmFyKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX0hPUlosIEZBTFNFKTsKICAgIH0KCiAgICBpZiAoZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCA+IGRhdGEtPmN1cmNmZy53aW5faGVpZ2h0KQogICAgewoJZHggPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCk7CglTZXRTY3JvbGxSYW5nZShQUklWQVRFKGRhdGEpLT5oV25kLCBTQl9WRVJULCAwLAogICAgICAgICAgICAgICAgICAgICAgIGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgLSBkYXRhLT5jdXJjZmcud2luX2hlaWdodCwgRkFMU0UpOwoJU2V0U2Nyb2xsUG9zKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX1ZFUlQsIDAsIEZBTFNFKTsgLyogRklYTUUgKi8KCVNob3dTY3JvbGxCYXIoUFJJVkFURShkYXRhKS0+aFduZCwgU0JfVkVSVCwgVFJVRSk7CiAgICB9CiAgICBlbHNlCiAgICB7CglTaG93U2Nyb2xsQmFyKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX1ZFUlQsIEZBTFNFKTsKICAgIH0KCiAgICBTZXRXaW5kb3dQb3MoUFJJVkFURShkYXRhKS0+aFduZCwgMCwgMCwgMCwgci5yaWdodCAtIHIubGVmdCArIGR4LCByLmJvdHRvbSAtIHIudG9wICsgZHksCgkJIFNXUF9OT01PVkV8U1dQX05PWk9SREVSKTsKICAgIFdDVVNFUl9TaGFwZUN1cnNvcihkYXRhLCBkYXRhLT5jdXJjZmcuY3Vyc29yX3NpemUsIGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSwgVFJVRSk7CiAgICBXQ1VTRVJfUG9zQ3Vyc29yKGRhdGEpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfU2V0VGl0bGUKICoKICogU2V0cyB0aGUgdGl0bGUgdG8gdGhlIHdpbmUgY29uc29sZQogKi8Kc3RhdGljIHZvaWQJV0NVU0VSX1NldFRpdGxlKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBXQ0hBUglidWZmZXJbMjU2XTsKCiAgICBpZiAoV0lORUNPTl9HZXRDb25zb2xlVGl0bGUoZGF0YS0+aENvbkluLCBidWZmZXIsIHNpemVvZihidWZmZXIpKSkKCVNldFdpbmRvd1RleHQoUFJJVkFURShkYXRhKS0+aFduZCwgYnVmZmVyKTsKfQoKdm9pZCBXQ1VTRVJfRHVtcExvZ0ZvbnQoY29uc3QgY2hhciogcGZ4LCBjb25zdCBMT0dGT05UKiBsZiwgRFdPUkQgZnQpCnsKICAgIFdJTkVfVFJBQ0VfKHdjX2ZvbnQpKCIlcyAlcyVzJXMlc1xuIgogICAgICAgICAgICAgICAgICAgICAgICAgIlx0bGYubGZIZWlnaHQ9JWQgbGYubGZXaWR0aD0lZCBsZi5sZkVzY2FwZW1lbnQ9JWQgbGYubGZPcmllbnRhdGlvbj0lZFxuIgogICAgICAgICAgICAgICAgICAgICAgICAgIlx0bGYubGZXZWlnaHQ9JWQgbGYubGZJdGFsaWM9JXUgbGYubGZVbmRlcmxpbmU9JXUgbGYubGZTdHJpa2VPdXQ9JXVcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdGxmLmxmQ2hhclNldD0ldSBsZi5sZk91dFByZWNpc2lvbj0ldSBsZi5sZkNsaXBQcmVjaXNpb249JXUgbGYubGZRdWFsaXR5PSV1XG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAiXHRsZi0+bGZQaXRjaEFuZEZhbWlseT0ldSBsZi5sZkZhY2VOYW1lPSVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgcGZ4LAogICAgICAgICAgICAgICAgICAgICAgICAgKGZ0ICYgUkFTVEVSX0ZPTlRUWVBFKSA/ICJyYXN0ZXIiIDogIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAoZnQgJiBUUlVFVFlQRV9GT05UVFlQRSkgPyAidHJ1ZXR5cGUiIDogIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAoKGZ0ICYgKFJBU1RFUl9GT05UVFlQRXxUUlVFVFlQRV9GT05UVFlQRSkpID09IDApID8gInZlY3RvciIgOiAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgIChmdCAmIERFVklDRV9GT05UVFlQRSkgPyAifGRldmljZSIgOiAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgIGxmLT5sZkhlaWdodCwgbGYtPmxmV2lkdGgsIGxmLT5sZkVzY2FwZW1lbnQsIGxmLT5sZk9yaWVudGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgbGYtPmxmV2VpZ2h0LCBsZi0+bGZJdGFsaWMsIGxmLT5sZlVuZGVybGluZSwgbGYtPmxmU3RyaWtlT3V0LCBsZi0+bGZDaGFyU2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgbGYtPmxmT3V0UHJlY2lzaW9uLCBsZi0+bGZDbGlwUHJlY2lzaW9uLCBsZi0+bGZRdWFsaXR5LCBsZi0+bGZQaXRjaEFuZEZhbWlseSwKICAgICAgICAgICAgICAgICAgICAgICAgIHdpbmVfZGJnc3RyX3cobGYtPmxmRmFjZU5hbWUpKTsKfQoKdm9pZCBXQ1VTRVJfRHVtcFRleHRNZXRyaWMoY29uc3QgVEVYVE1FVFJJQyogdG0sIERXT1JEIGZ0KQp7CiAgICBXSU5FX1RSQUNFXyh3Y19mb250KSgiJXMlcyVzJXNcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdHRtSGVpZ2h0PSVkIHRtQXNjZW50PSVkIHRtRGVzY2VudD0lZCB0bUludGVybmFsTGVhZGluZz0lZCB0bUV4dGVybmFsTGVhZGluZz0lZFxuIgogICAgICAgICAgICAgICAgICAgICAgICAgIlx0dG1BdmVDaGFyV2lkdGg9JWQgdG1NYXhDaGFyV2lkdGg9JWQgdG1XZWlnaHQ9JWQgdG1PdmVyaGFuZz0lZFxuIgogICAgICAgICAgICAgICAgICAgICAgICAgIlx0dG1EaWdpdGl6ZWRBc3BlY3RYPSVkIHRtRGlnaXRpemVkQXNwZWN0WT0lZFxuIgogICAgICAgICAgICAgICAgICAgICAgICAgIlx0dG1GaXJzdENoYXI9JWQgdG1MYXN0Q2hhcj0lZCB0bURlZmF1bHRDaGFyPSVkIHRtQnJlYWtDaGFyPSVkXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAiXHR0bUl0YWxpYz0ldSB0bVVuZGVybGluZWQ9JXUgdG1TdHJ1Y2tPdXQ9JXUgdG1QaXRjaEFuZEZhbWlseT0ldSB0bUNoYXJTZXQ9JXVcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAoZnQgJiBSQVNURVJfRk9OVFRZUEUpID8gInJhc3RlciIgOiAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgIChmdCAmIFRSVUVUWVBFX0ZPTlRUWVBFKSA/ICJ0cnVldHlwZSIgOiAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgICgoZnQgJiAoUkFTVEVSX0ZPTlRUWVBFfFRSVUVUWVBFX0ZPTlRUWVBFKSkgPT0gMCkgPyAidmVjdG9yIiA6ICIiLAogICAgICAgICAgICAgICAgICAgICAgICAgKGZ0ICYgREVWSUNFX0ZPTlRUWVBFKSA/ICJ8ZGV2aWNlIiA6ICIiLAogICAgICAgICAgICAgICAgICAgICAgICAgdG0tPnRtSGVpZ2h0LCB0bS0+dG1Bc2NlbnQsIHRtLT50bURlc2NlbnQsIHRtLT50bUludGVybmFsTGVhZGluZywgdG0tPnRtRXh0ZXJuYWxMZWFkaW5nLCB0bS0+dG1BdmVDaGFyV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICB0bS0+dG1NYXhDaGFyV2lkdGgsIHRtLT50bVdlaWdodCwgdG0tPnRtT3ZlcmhhbmcsIHRtLT50bURpZ2l0aXplZEFzcGVjdFgsIHRtLT50bURpZ2l0aXplZEFzcGVjdFksCiAgICAgICAgICAgICAgICAgICAgICAgICB0bS0+dG1GaXJzdENoYXIsIHRtLT50bUxhc3RDaGFyLCB0bS0+dG1EZWZhdWx0Q2hhciwgdG0tPnRtQnJlYWtDaGFyLCB0bS0+dG1JdGFsaWMsIHRtLT50bVVuZGVybGluZWQsIHRtLT50bVN0cnVja091dCwKICAgICAgICAgICAgICAgICAgICAgICAgIHRtLT50bVBpdGNoQW5kRmFtaWx5LCB0bS0+dG1DaGFyU2V0KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0FyZUZvbnRzRXF1YWwKICoKICoKICovCkJPT0wgV0NVU0VSX0FyZUZvbnRzRXF1YWwoY29uc3Qgc3RydWN0IGNvbmZpZ19kYXRhKiBjb25maWcsIGNvbnN0IExPR0ZPTlQqIGxmKQp7CiAgICByZXR1cm4gbGYtPmxmSGVpZ2h0ID09IGNvbmZpZy0+Y2VsbF9oZWlnaHQgJiYKICAgICAgICBsZi0+bGZXZWlnaHQgPT0gY29uZmlnLT5mb250X3dlaWdodCAmJgogICAgICAgICFsZi0+bGZJdGFsaWMgJiYgIWxmLT5sZlVuZGVybGluZSAmJiAhbGYtPmxmU3RyaWtlT3V0ICYmCiAgICAgICAgIWxzdHJjbXAobGYtPmxmRmFjZU5hbWUsIGNvbmZpZy0+ZmFjZV9uYW1lKTsKfQoKc3RydWN0IGZvbnRfY2hvb3Nlcgp7CiAgICBzdHJ1Y3QgaW5uZXJfZGF0YSoJZGF0YTsKICAgIGludAkJCWRvbmU7Cn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfVmFsaWRhdGVGb250TWV0cmljCiAqCiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZm9udCBkZXNjcmliZWQgaW4gdG0gaXMgdXNhYmxlIGFzIGEgZm9udCBmb3IgdGhlIHJlbmRlcmVyCiAqLwpCT09MCVdDVVNFUl9WYWxpZGF0ZUZvbnRNZXRyaWMoY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIGNvbnN0IFRFWFRNRVRSSUMqIHRtLCBEV09SRCBmb250VHlwZSkKewogICAgQk9PTCAgICAgICAgcmV0ID0gVFJVRTsKCiAgICBpZiAoZm9udFR5cGUgJiBSQVNURVJfRk9OVFRZUEUpCiAgICAgICAgcmV0ID0gKHRtLT50bU1heENoYXJXaWR0aCAqIGRhdGEtPmN1cmNmZy53aW5fd2lkdGggPCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0NSRUVOKSAmJgogICAgICAgICAgICAgICB0bS0+dG1IZWlnaHQgKiBkYXRhLT5jdXJjZmcud2luX2hlaWdodCA8IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTQ1JFRU4pKTsKICAgIHJldHVybiByZXQgJiYgIXRtLT50bUl0YWxpYyAmJiAhdG0tPnRtVW5kZXJsaW5lZCAmJiAhdG0tPnRtU3RydWNrT3V0ICYmCiAgICAgICAgKHRtLT50bUNoYXJTZXQgPT0gREVGQVVMVF9DSEFSU0VUIHx8IHRtLT50bUNoYXJTZXQgPT0gQU5TSV9DSEFSU0VUKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1ZhbGlkYXRlRm9udAogKgogKiBSZXR1cm5zIHRydWUgaWYgdGhlIGZvbnQgZmFtaWx5IGRlc2NyaWJlZCBpbiBsZiBpcyB1c2FibGUgYXMgYSBmb250IGZvciB0aGUgcmVuZGVyZXIKICovCkJPT0wJV0NVU0VSX1ZhbGlkYXRlRm9udChjb25zdCBzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgY29uc3QgTE9HRk9OVCogbGYpCnsKICAgIHJldHVybiAobGYtPmxmUGl0Y2hBbmRGYW1pbHkgJiAzKSA9PSBGSVhFRF9QSVRDSCAmJgogICAgICAgIC8qIChsZi0+bGZQaXRjaEFuZEZhbWlseSAmIDB4RjApID09IEZGX01PREVSTiAmJiAqLwogICAgICAgIChsZi0+bGZDaGFyU2V0ID09IERFRkFVTFRfQ0hBUlNFVCB8fCBsZi0+bGZDaGFyU2V0ID09IEFOU0lfQ0hBUlNFVCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCWdldF9maXJzdF9mb250X2VudW1fMgogKgkJZ2V0X2ZpcnN0X2ZvbnRfZW51bQogKgogKiBIZWxwZXIgZnVuY3Rpb25zIHRvIGdldCBhIGRlY2VudCBmb250IGZvciB0aGUgcmVuZGVyZXIKICovCnN0YXRpYyBpbnQgQ0FMTEJBQ0sgZ2V0X2ZpcnN0X2ZvbnRfZW51bV8yKGNvbnN0IExPR0ZPTlQqIGxmLCBjb25zdCBURVhUTUVUUklDKiB0bSwKCQkJCQkgIERXT1JEIEZvbnRUeXBlLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBzdHJ1Y3QgZm9udF9jaG9vc2VyKglmYyA9IChzdHJ1Y3QgZm9udF9jaG9vc2VyKilsUGFyYW07CgogICAgV0NVU0VSX0R1bXBUZXh0TWV0cmljKHRtLCBGb250VHlwZSk7CiAgICBpZiAoV0NVU0VSX1ZhbGlkYXRlRm9udE1ldHJpYyhmYy0+ZGF0YSwgdG0sIEZvbnRUeXBlKSkKICAgIHsKICAgICAgICBMT0dGT05UIG1sZiA9ICpsZjsKCiAgICAgICAgLyogVXNlIHRoZSBkZWZhdWx0IHNpemVzIGZvciB0aGUgZm9udCAodGhpcyBpcyBuZWVkZWQsIGVzcGVjaWFsbHkgZm9yCiAgICAgICAgICogVHJ1ZVR5cGUgZm9udHMsIHNvIHRoYXQgd2UgZ2V0IGEgZGVjZW50IHNpemUsIG5vdCB0aGUgbWF4IHNpemUpCiAgICAgICAgICovCiAgICAgICAgbWxmLmxmV2lkdGggID0gZmMtPmRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoOwogICAgICAgIG1sZi5sZkhlaWdodCA9IGZjLT5kYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQ7CiAgICAgICAgaWYgKFdDVVNFUl9TZXRGb250KGZjLT5kYXRhLCAmbWxmKSkKICAgICAgICB7CiAgICAgICAgICAgIHN0cnVjdCAgICAgIGNvbmZpZ19kYXRhICAgICBkZWZjZmc7CgogICAgICAgICAgICBXQ1VTRVJfRHVtcExvZ0ZvbnQoIkluaXRDaG9vc2luZzogIiwgJm1sZiwgRm9udFR5cGUpOwogICAgICAgICAgICBmYy0+ZG9uZSA9IDE7CiAgICAgICAgICAgIC8qIHNpbmNlIHdlJ3ZlIG1vZGlmaWVkIHRoZSBjdXJyZW50IGNvbmZpZyB3aXRoIG5ldyBmb250IGluZm9ybWF0aW9uLAogICAgICAgICAgICAgKiBzZXQgdGhpcyBpbmZvcm1hdGlvbiBhcyB0aGUgbmV3IGRlZmF1bHQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBXSU5FQ09OX1JlZ0xvYWQoTlVMTCwgJmRlZmNmZyk7CiAgICAgICAgICAgIGRlZmNmZy5jZWxsX3dpZHRoID0gZmMtPmRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoOwogICAgICAgICAgICBkZWZjZmcuY2VsbF9oZWlnaHQgPSBmYy0+ZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0OwogICAgICAgICAgICBsc3RyY3B5VyhkZWZjZmcuZmFjZV9uYW1lLCBmYy0+ZGF0YS0+Y3VyY2ZnLmZhY2VfbmFtZSk7CiAgICAgICAgICAgIC8qIEZvcmNlIGFsc28gaXRzIHdyaXRpbmcgYmFjayB0byB0aGUgcmVnaXN0cnkgc28gdGhhdCB3ZSBjYW4gZ2V0IGl0CiAgICAgICAgICAgICAqIHRoZSBuZXh0IHRpbWUuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBXSU5FQ09OX1JlZ1NhdmUoJmRlZmNmZyk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAxOwp9CgpzdGF0aWMgaW50IENBTExCQUNLIGdldF9maXJzdF9mb250X2VudW0oY29uc3QgTE9HRk9OVCogbGYsIGNvbnN0IFRFWFRNRVRSSUMqIHRtLAoJCQkJCURXT1JEIEZvbnRUeXBlLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBzdHJ1Y3QgZm9udF9jaG9vc2VyKglmYyA9IChzdHJ1Y3QgZm9udF9jaG9vc2VyKilsUGFyYW07CgogICAgV0NVU0VSX0R1bXBMb2dGb250KCJJbml0RmFtaWx5OiAiLCBsZiwgRm9udFR5cGUpOwogICAgaWYgKFdDVVNFUl9WYWxpZGF0ZUZvbnQoZmMtPmRhdGEsIGxmKSkKICAgIHsKCUVudW1Gb250RmFtaWxpZXMoUFJJVkFURShmYy0+ZGF0YSktPmhNZW1EQywgbGYtPmxmRmFjZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICBnZXRfZmlyc3RfZm9udF9lbnVtXzIsIGxQYXJhbSk7CglyZXR1cm4gIWZjLT5kb25lOyAvKiB3ZSBqdXN0IG5lZWQgdGhlIGZpcnN0IG1hdGNoaW5nIG9uZS4uLiAqLwogICAgfQogICAgcmV0dXJuIDE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9Db3B5Rm9udAogKgogKiBnZXQgdGhlIHJlbGV2YW50IGluZm9ybWF0aW9uIGZyb20gdGhlIGZvbnQgZGVzY3JpYmVkIGluIGxmIGFuZCBzdG9yZSB0aGVtCiAqIGluIGNvbmZpZwogKi8KSEZPTlQgV0NVU0VSX0NvcHlGb250KHN0cnVjdCBjb25maWdfZGF0YSogY29uZmlnLCBIV05EIGhXbmQsIGNvbnN0IExPR0ZPTlQqIGxmLCBMT05HKiBlbCkKewogICAgVEVYVE1FVFJJQyAgdG07CiAgICBIREMgICAgICAgICBoREM7CiAgICBIRk9OVCAgICAgICBoRm9udCwgaE9sZEZvbnQ7CiAgICBpbnQgICAgICAgICB3LCBpLCBidWZbMjU2XTsKCiAgICBpZiAoIShoREMgPSBHZXREQyhoV25kKSkpIHJldHVybiBOVUxMOwogICAgaWYgKCEoaEZvbnQgPSBDcmVhdGVGb250SW5kaXJlY3QobGYpKSkgZ290byBlcnIxOwoKICAgIGhPbGRGb250ID0gU2VsZWN0T2JqZWN0KGhEQywgaEZvbnQpOwogICAgR2V0VGV4dE1ldHJpY3MoaERDLCAmdG0pOwoKICAgIC8qIEZJWE1FOgogICAgICogdGhlIGN1cnJlbnQgZnJlZXR5cGUgZW5naW5lIChhdCBsZWFzdCAyLjAueCB3aXRoIHggPD0gOCkgYW5kIGl0cyBpbXBsZW1lbnRhdGlvbgogICAgICogaW4gV2luZSBkb24ndCByZXR1cm4gYWRlcXVhdGUgdmFsdWVzIGZvciBmaXhlZCBmb250cwogICAgICogSW4gV2luZG93cywgdGhvc2UgZm9udHMgYXJlIGV4cGVjdGVkIHRvIHJldHVybiB0aGUgc2FtZSB2YWx1ZSBmb3IKICAgICAqICAtIHRoZSBhdmVyYWdlIHdpZHRoCiAgICAgKiAgLSB0aGUgbGFyZ2VzdCB3aWR0aAogICAgICogIC0gdGhlIHdpZHRoIG9mIGFsbCBjaGFyYWN0ZXJzIGluIHRoZSBmb250CiAgICAgKiBUaGlzIGlzbid0IHRydWUgaW4gV2luZS4gQXMgYSB0ZW1wb3Jhcnkgd29ya2Fyb3VuZCwgd2UgZ2V0IGFzIHRoZSB3aWR0aCBvZiB0aGUKICAgICAqIGNlbGwsIHRoZSB3aWR0aCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSBmb250LCBhZnRlciBjaGVja2luZyB0aGF0IGFsbAogICAgICogY2hhcmFjdGVycyBpbiB0aGUgZm9udCBoYXZlIHRoZSBzYW1lIHdpZHRoIChJIGhlYXIgcGFyYW5v72EgY29taW5nKQogICAgICogd2hlbiB0aGlzIGdldHMgZml4ZWQsIHRoZSBjb2RlIHNob3VsZCBiZSB1c2luZyB0bS50bUF2ZUNoYXJXaWR0aAogICAgICogb3IgdG0udG1NYXhDaGFyV2lkdGggYXMgdGhlIGNlbGwgd2lkdGguCiAgICAgKi8KICAgIEdldENoYXJXaWR0aDMyKGhEQywgdG0udG1GaXJzdENoYXIsIHRtLnRtRmlyc3RDaGFyLCAmdyk7CiAgICBmb3IgKGkgPSB0bS50bUZpcnN0Q2hhciArIDE7IGkgPD0gdG0udG1MYXN0Q2hhcjsgaSArPSBzaXplb2YoYnVmKSAvIHNpemVvZihidWZbMF0pKQogICAgewogICAgICAgIGludCBqLCBrOwoKICAgICAgICBrID0gbWluKHRtLnRtTGFzdENoYXIgLSBpLCBzaXplb2YoYnVmKSAvIHNpemVvZihidWZbMF0pIC0gMSk7CiAgICAgICAgR2V0Q2hhcldpZHRoMzIoaERDLCBpLCBpICsgaywgYnVmKTsKICAgICAgICBmb3IgKGogPSAwOyBqIDw9IGs7IGorKykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChidWZbal0gIT0gdykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0lORV9XQVJOKCJOb24gdW5pZm9ybSBjZWxsIHdpZHRoOiBbJWRdPSVkIFslZF09JWRcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICAiVGhpcyBtYXkgYmUgY2F1c2VkIGJ5IG9sZCBmcmVldHlwZSBsaWJyYXJpZXMsID49IDIuMC44IGlzIHJlY29tbWVuZGVkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgIGkgKyBqLCBidWZbal0sIHRtLnRtRmlyc3RDaGFyLCB3KTsKICAgICAgICAgICAgICAgIGdvdG8gZXJyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgU2VsZWN0T2JqZWN0KGhEQywgaE9sZEZvbnQpOwogICAgUmVsZWFzZURDKGhXbmQsIGhEQyk7CgogICAgY29uZmlnLT5jZWxsX3dpZHRoICA9IHc7CiAgICBjb25maWctPmNlbGxfaGVpZ2h0ID0gdG0udG1IZWlnaHQgKyB0bS50bUV4dGVybmFsTGVhZGluZzsKICAgIGNvbmZpZy0+Zm9udF93ZWlnaHQgPSB0bS50bVdlaWdodDsKICAgIGxzdHJjcHkoY29uZmlnLT5mYWNlX25hbWUsIGxmLT5sZkZhY2VOYW1lKTsKICAgIGlmIChlbCkgKmVsID0gdG0udG1FeHRlcm5hbExlYWRpbmc7CgogICAgcmV0dXJuIGhGb250OwogZXJyOgogICAgaWYgKGhEQyAmJiBoT2xkRm9udCkgU2VsZWN0T2JqZWN0KGhEQywgaE9sZEZvbnQpOwogICAgaWYgKGhGb250KSBEZWxldGVPYmplY3QoaEZvbnQpOwogZXJyMToKICAgIGlmIChoREMpIFJlbGVhc2VEQyhoV25kLCBoREMpOwoKICAgIHJldHVybiBOVUxMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfRmlsbExvZ0ZvbnQKICoKICoKICovCnZvaWQgICAgV0NVU0VSX0ZpbGxMb2dGb250KExPR0ZPTlQqIGxmLCBjb25zdCBXQ0hBUiogbmFtZSwgVUlOVCBoZWlnaHQsIFVJTlQgd2VpZ2h0KQp7CiAgICBsZi0+bGZIZWlnaHQgICAgICAgID0gaGVpZ2h0OwogICAgbGYtPmxmV2lkdGggICAgICAgICA9IDA7CiAgICBsZi0+bGZFc2NhcGVtZW50ICAgID0gMDsKICAgIGxmLT5sZk9yaWVudGF0aW9uICAgPSAwOwogICAgbGYtPmxmV2VpZ2h0ICAgICAgICA9IHdlaWdodDsKICAgIGxmLT5sZkl0YWxpYyAgICAgICAgPSBGQUxTRTsKICAgIGxmLT5sZlVuZGVybGluZSAgICAgPSBGQUxTRTsKICAgIGxmLT5sZlN0cmlrZU91dCAgICAgPSBGQUxTRTsKICAgIGxmLT5sZkNoYXJTZXQgICAgICAgPSBERUZBVUxUX0NIQVJTRVQ7CiAgICBsZi0+bGZPdXRQcmVjaXNpb24gID0gT1VUX0RFRkFVTFRfUFJFQ0lTOwogICAgbGYtPmxmQ2xpcFByZWNpc2lvbiA9IENMSVBfREVGQVVMVF9QUkVDSVM7CiAgICBsZi0+bGZRdWFsaXR5ICAgICAgID0gREVGQVVMVF9RVUFMSVRZOwogICAgbGYtPmxmUGl0Y2hBbmRGYW1pbHkgPSBGSVhFRF9QSVRDSCB8IEZGX0RPTlRDQVJFOwogICAgbHN0cmNweShsZi0+bGZGYWNlTmFtZSwgbmFtZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9TZXRGb250CiAqCiAqIHNldHMgbG9nZm9udCBhcyB0aGUgbmV3IGZvbnQgZm9yIHRoZSBjb25zb2xlCiAqLwpCT09MCVdDVVNFUl9TZXRGb250KHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBjb25zdCBMT0dGT05UKiBsb2dmb250KQp7CiAgICBIRk9OVCAgICAgICBoRm9udDsKICAgIExPTkcgICAgICAgIGVsOwoKICAgIGlmIChQUklWQVRFKGRhdGEpLT5oRm9udCAhPSAwICYmIFdDVVNFUl9BcmVGb250c0VxdWFsKCZkYXRhLT5jdXJjZmcsIGxvZ2ZvbnQpKQogICAgICAgIHJldHVybiBUUlVFOwoKICAgIGhGb250ID0gV0NVU0VSX0NvcHlGb250KCZkYXRhLT5jdXJjZmcsIFBSSVZBVEUoZGF0YSktPmhXbmQsIGxvZ2ZvbnQsICZlbCk7CiAgICBpZiAoIWhGb250KSB7V0lORV9FUlIoIndyb25nIGZvbnRcbiIpOyByZXR1cm4gRkFMU0U7fQoKICAgIGlmIChQUklWQVRFKGRhdGEpLT5oRm9udCkgRGVsZXRlT2JqZWN0KFBSSVZBVEUoZGF0YSktPmhGb250KTsKICAgIFBSSVZBVEUoZGF0YSktPmhGb250ID0gaEZvbnQ7CiAgICBQUklWQVRFKGRhdGEpLT5leHRfbGVhZGluZyA9IGVsOwoKICAgIFdDVVNFUl9Db21wdXRlUG9zaXRpb25zKGRhdGEpOwogICAgV0NVU0VSX05ld0JpdG1hcChkYXRhKTsKICAgIEludmFsaWRhdGVSZWN0KFBSSVZBVEUoZGF0YSktPmhXbmQsIE5VTEwsIEZBTFNFKTsKICAgIFVwZGF0ZVdpbmRvdyhQUklWQVRFKGRhdGEpLT5oV25kKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1NldEZvbnRQbXQKICoKICogU2V0cyBhIG5ldyBmb250IGZvciB0aGUgY29uc29sZS4KICogSW4gZmFjdCBhIHdyYXBwZXIgZm9yIFdDVVNFUl9TZXRGb250CiAqLwpzdGF0aWMgdm9pZCAgICAgV0NVU0VSX1NldEZvbnRQbXQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIGNvbnN0IFdDSEFSKiBmb250LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgaGVpZ2h0LCB1bnNpZ25lZCB3ZWlnaHQpCnsKICAgIExPR0ZPTlQgICAgICAgICAgICAgbGY7CiAgICBzdHJ1Y3QgZm9udF9jaG9vc2VyIGZjOwoKICAgIFdJTkVfVFJBQ0VfKHdjX2ZvbnQpKCI9PiAlcyBoPSV1IHc9JXVcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICB3aW5lX2RiZ3N0cl93bihmb250LCAtMSksIGhlaWdodCwgd2VpZ2h0KTsKCiAgICBpZiAoZm9udFswXSAhPSAnXDAnICYmIGhlaWdodCAhPSAwICYmIHdlaWdodCAhPSAwKQogICAgewogICAgICAgIFdDVVNFUl9GaWxsTG9nRm9udCgmbGYsIGZvbnQsIGhlaWdodCwgd2VpZ2h0KTsKICAgICAgICBpZiAoV0NVU0VSX1NldEZvbnQoZGF0YSwgJmxmKSkKICAgICAgICB7CiAgICAgICAgICAgIFdDVVNFUl9EdW1wTG9nRm9udCgiSW5pdFJldXNlczogIiwgJmxmLCAwKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAvKiB0cnkgdG8gZmluZCBhbiBhY2NlcHRhYmxlIGZvbnQgKi8KICAgIFdJTkVfV0FSTigiQ291bGRuJ3QgbWF0Y2ggdGhlIGZvbnQgZnJvbSByZWdpc3RyeS4uLiB0cnlpbmcgdG8gZmluZCBvbmVcbiIpOwogICAgZmMuZGF0YSA9IGRhdGE7CiAgICBmYy5kb25lID0gMDsKICAgIEVudW1Gb250RmFtaWxpZXMoUFJJVkFURShkYXRhKS0+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+aFduZCwgTlVMTCwgRkFMU0UpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfRmlsbE1lbnUKICoKICoKICovCnN0YXRpYyBCT09MIFdDVVNFUl9GaWxsTWVudShITUVOVSBoTWVudSwgQk9PTCBzZXApCnsKICAgIEhNRU5VCQloU3ViTWVudTsKICAgIEhJTlNUQU5DRQkJaEluc3RhbmNlID0gR2V0TW9kdWxlSGFuZGxlKE5VTEwpOwogICAgV0NIQVIJCWJ1ZmZbMjU2XTsKCiAgICBpZiAoIWhNZW51KSByZXR1cm4gRkFMU0U7CgogICAgLyogRklYTUU6IGVycm9yIGhhbmRsaW5nICYgbWVtb3J5IGNsZWFudXAgKi8KICAgIGhTdWJNZW51ID0gQ3JlYXRlTWVudSgpOwogICAgaWYgKCFoU3ViTWVudSkgcmV0dXJuIEZBTFNFOwoKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfTUFSSywgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhTdWJNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkcsIElEU19NQVJLLCBidWZmKTsKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfQ09QWSwgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhTdWJNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkcsIElEU19DT1BZLCBidWZmKTsKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfUEFTVEUsIGJ1ZmYsIHNpemVvZihidWZmKSAvIHNpemVvZihXQ0hBUikpOwogICAgSW5zZXJ0TWVudShoU3ViTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU1RSSU5HLCBJRFNfUEFTVEUsIGJ1ZmYpOwogICAgTG9hZFN0cmluZyhoSW5zdGFuY2UsIElEU19TRUxFQ1RBTEwsIGJ1ZmYsIHNpemVvZihidWZmKSAvIHNpemVvZihXQ0hBUikpOwogICAgSW5zZXJ0TWVudShoU3ViTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU1RSSU5HLCBJRFNfU0VMRUNUQUxMLCBidWZmKTsKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfU0NST0xMLCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaFN1Yk1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklORywgSURTX1NDUk9MTCwgYnVmZik7CiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX1NFQVJDSCwgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhTdWJNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkcsIElEU19TRUFSQ0gsIGJ1ZmYpOwoKICAgIGlmIChzZXApIEluc2VydE1lbnUoaE1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NFUEFSQVRPUiwgMCwgTlVMTCk7CiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX0VESVQsIGJ1ZmYsIHNpemVvZihidWZmKSAvIHNpemVvZihXQ0hBUikpOwogICAgSW5zZXJ0TWVudShoTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU1RSSU5HfE1GX1BPUFVQLCAoVUlOVF9QVFIpaFN1Yk1lbnUsIGJ1ZmYpOwogICAgTG9hZFN0cmluZyhoSW5zdGFuY2UsIElEU19ERUZBVUxULCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaE1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklORywgSURTX0RFRkFVTFQsIGJ1ZmYpOwogICAgTG9hZFN0cmluZyhoSW5zdGFuY2UsIElEU19QUk9QRVJUSUVTLCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaE1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklORywgSURTX1BST1BFUlRJRVMsIGJ1ZmYpOwoKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfU2V0TWVudURldGFpbHMKICoKICogR3JheXMgLyB1bmdyYXlzIHRoZSBtZW51IGl0ZW1zIGFjY29yZGluZyB0byB0aGVpciBzdGF0ZQogKi8Kc3RhdGljIHZvaWQJV0NVU0VSX1NldE1lbnVEZXRhaWxzKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBITUVOVSBoTWVudSkKewogICAgaWYgKCFoTWVudSkge1dJTkVfRVJSKCJJc3N1ZSBpbiBnZXR0aW5nIG1lbnUgYml0c1xuIik7cmV0dXJuO30KCiAgICBFbmFibGVNZW51SXRlbShoTWVudSwgSURTX0NPUFksCiAgICAgICAgICAgICAgICAgICBNRl9CWUNPTU1BTkR8KFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24gPyBNRl9FTkFCTEVEIDogTUZfR1JBWUVEKSk7CiAgICBFbmFibGVNZW51SXRlbShoTWVudSwgSURTX1BBU1RFLAoJCSAgIE1GX0JZQ09NTUFORHwoSXNDbGlwYm9hcmRGb3JtYXRBdmFpbGFibGUoQ0ZfVU5JQ09ERVRFWFQpCgkJCQkgPyBNRl9FTkFCTEVEIDogTUZfR1JBWUVEKSk7CiAgICBFbmFibGVNZW51SXRlbShoTWVudSwgSURTX1NDUk9MTCwgTUZfQllDT01NQU5EfE1GX0dSQVlFRCk7CiAgICBFbmFibGVNZW51SXRlbShoTWVudSwgSURTX1NFQVJDSCwgTUZfQllDT01NQU5EfE1GX0dSQVlFRCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9DcmVhdGUKICoKICogQ3JlYXRlcyB0aGUgd2luZG93IGZvciB0aGUgcmVuZGVyaW5nCiAqLwpzdGF0aWMgTFJFU1VMVCBXQ1VTRVJfQ3JlYXRlKEhXTkQgaFduZCwgTFBDUkVBVEVTVFJVQ1QgbHBjcykKewogICAgc3RydWN0IGlubmVyX2RhdGEqCWRhdGE7CiAgICBITUVOVQkJaFN5c01lbnU7CgogICAgZGF0YSA9IGxwY3MtPmxwQ3JlYXRlUGFyYW1zOwogICAgU2V0V2luZG93TG9uZ1B0cihoV25kLCAwTCwgKERXT1JEX1BUUilkYXRhKTsKICAgIFBSSVZBVEUoZGF0YSktPmhXbmQgPSBoV25kOwoKICAgIGhTeXNNZW51ID0gR2V0U3lzdGVtTWVudShoV25kLCBGQUxTRSk7CiAgICBpZiAoIWhTeXNNZW51KSByZXR1cm4gMDsKICAgIFBSSVZBVEUoZGF0YSktPmhQb3BNZW51ID0gQ3JlYXRlUG9wdXBNZW51KCk7CiAgICBpZiAoIVBSSVZBVEUoZGF0YSktPmhQb3BNZW51KSByZXR1cm4gMDsKCiAgICBXQ1VTRVJfRmlsbE1lbnUoaFN5c01lbnUsIFRSVUUpOwogICAgV0NVU0VSX0ZpbGxNZW51KFBSSVZBVEUoZGF0YSktPmhQb3BNZW51LCBGQUxTRSk7CgogICAgUFJJVkFURShkYXRhKS0+aE1lbURDID0gQ3JlYXRlQ29tcGF0aWJsZURDKDApOwogICAgaWYgKCFQUklWQVRFKGRhdGEpLT5oTWVtREMpIHtXSU5FX0VSUigibm8gbWVtIGRjXG4iKTtyZXR1cm4gMDt9CgogICAgZGF0YS0+Y3VyY2ZnLnF1aWNrX2VkaXQgPSBGQUxTRTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfR2V0Q3RybEtleVN0YXRlCiAqCiAqIEdldCB0aGUgY29uc29sZSBiaXQgbWFzayBlcXVpdmFsZW50IHRvIHRoZSBWS18gc3RhdHVzIGluIGtleVN0YXRlCiAqLwpzdGF0aWMgRFdPUkQgICAgV0NVU0VSX0dldEN0cmxLZXlTdGF0ZShCWVRFKiBrZXlTdGF0ZSkKewogICAgRFdPUkQgICAgICAgICAgICAgICByZXQgPSAwOwoKICAgIEdldEtleWJvYXJkU3RhdGUoa2V5U3RhdGUpOwogICAgaWYgKGtleVN0YXRlW1ZLX1NISUZUXSAgICAmIDB4ODApCXJldCB8PSBTSElGVF9QUkVTU0VEOwogICAgaWYgKGtleVN0YXRlW1ZLX0xDT05UUk9MXSAmIDB4ODApCXJldCB8PSBMRUZUX0NUUkxfUFJFU1NFRDsKICAgIGlmIChrZXlTdGF0ZVtWS19SQ09OVFJPTF0gJiAweDgwKQlyZXQgfD0gUklHSFRfQ1RSTF9QUkVTU0VEOwogICAgaWYgKGtleVN0YXRlW1ZLX0xNRU5VXSAgICAmIDB4ODApCXJldCB8PSBMRUZUX0FMVF9QUkVTU0VEOwogICAgaWYgKGtleVN0YXRlW1ZLX1JNRU5VXSAgICAmIDB4ODApCXJldCB8PSBSSUdIVF9BTFRfUFJFU1NFRDsKICAgIGlmIChrZXlTdGF0ZVtWS19DQVBJVEFMXSAgJiAweDAxKQlyZXQgfD0gQ0FQU0xPQ0tfT047CiAgICBpZiAoa2V5U3RhdGVbVktfTlVNTE9DS10gICYgMHgwMSkJcmV0IHw9IE5VTUxPQ0tfT047CiAgICBpZiAoa2V5U3RhdGVbVktfU0NST0xMXSAgICYgMHgwMSkJcmV0IHw9IFNDUk9MTExPQ0tfT047CgogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0hhbmRsZVNlbGVjdGlvbktleQogKgogKiBIYW5kbGVzIGtleXMgd2hpbGUgc2VsZWN0aW5nIGFuIGFyZWEKICovCnN0YXRpYyB2b2lkIFdDVVNFUl9IYW5kbGVTZWxlY3Rpb25LZXkoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIEJPT0wgZG93biwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBCWVRFCWtleVN0YXRlWzI1Nl07CiAgICBEV09SRCAgICAgICBzdGF0ZSA9IFdDVVNFUl9HZXRDdHJsS2V5U3RhdGUoa2V5U3RhdGUpICYgfihDQVBTTE9DS19PTnxOVU1MT0NLX09OfFNDUk9MTExPQ0tfT04pOwogICAgQ09PUkQgICAgICAgYzEsIGMyOwoKICAgIGlmIChkb3duKSByZXR1cm47CgogICAgc3dpdGNoIChzdGF0ZSkKICAgIHsKICAgIGNhc2UgMDoKICAgICAgICBzd2l0Y2ggKHdQYXJhbSkKICAgICAgICB7CiAgICAgICAgY2FzZSBWS19SRVRVUk46CiAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24gPSBGQUxTRTsKICAgICAgICAgICAgV0NVU0VSX1NldFNlbGVjdGlvbihkYXRhLCAwKTsKICAgICAgICAgICAgV0NVU0VSX0NvcHlTZWxlY3Rpb25Ub0NsaXBib2FyZChkYXRhKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBWS19SSUdIVDoKICAgICAgICAgICAgYzEgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDE7CiAgICAgICAgICAgIGMyID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyOwogICAgICAgICAgICBjMS5YKys7IGMyLlgrKzsKICAgICAgICAgICAgV0NVU0VSX01vdmVTZWxlY3Rpb24oZGF0YSwgYzEsIGMyKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBWS19MRUZUOgogICAgICAgICAgICBjMSA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MTsKICAgICAgICAgICAgYzIgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDI7CiAgICAgICAgICAgIGMxLlgtLTsgYzIuWC0tOwogICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFZLX1VQOgogICAgICAgICAgICBjMSA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MTsKICAgICAgICAgICAgYzIgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDI7CiAgICAgICAgICAgIGMxLlktLTsgYzIuWS0tOwogICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFZLX0RPV046CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzEuWSsrOyBjMi5ZKys7CiAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgU0hJRlRfUFJFU1NFRDoKICAgICAgICBzd2l0Y2ggKHdQYXJhbSkKICAgICAgICB7CiAgICAgICAgY2FzZSBWS19SSUdIVDoKICAgICAgICAgICAgYzEgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDE7CiAgICAgICAgICAgIGMyID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyOwogICAgICAgICAgICBjMi5YKys7CiAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVktfTEVGVDoKICAgICAgICAgICAgYzEgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDE7CiAgICAgICAgICAgIGMyID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyOwogICAgICAgICAgICBjMi5YLS07CiAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVktfVVA6CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzIuWS0tOwogICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFZLX0RPV046CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzIuWSsrOwogICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9HZW5lcmF0ZUtleUlucHV0UmVjb3JkCiAqCiAqIGdlbmVyYXRlcyBpbnB1dF9yZWNvcmQgZnJvbSB3aW5kb3dzIFdNX0tFWVVQL1dNX0tFWURPV04gbWVzc2FnZXMKICovCnN0YXRpYyB2b2lkICAgIFdDVVNFUl9HZW5lcmF0ZUtleUlucHV0UmVjb3JkKHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBCT09MIGRvd24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0sIEJPT0wgc3lzKQp7CiAgICBJTlBVVF9SRUNPUkQJaXI7CiAgICBEV09SRAkJbjsKICAgIFdDSEFSCQlidWZbMl07CiAgICBzdGF0aWMJV0NIQVIJbGFzdDsgLyoga2VlcCBsYXN0IGNoYXIgc2VlbiBhcyBmZWVkIGZvciBrZXkgdXAgbWVzc2FnZSAqLwogICAgQllURQkJa2V5U3RhdGVbMjU2XTsKCiAgICBpci5FdmVudFR5cGUgPSBLRVlfRVZFTlQ7CiAgICBpci5FdmVudC5LZXlFdmVudC5iS2V5RG93biA9IGRvd247CiAgICBpci5FdmVudC5LZXlFdmVudC53UmVwZWF0Q291bnQgPSBMT1dPUkQobFBhcmFtKTsKICAgIGlyLkV2ZW50LktleUV2ZW50LndWaXJ0dWFsS2V5Q29kZSA9IHdQYXJhbTsKCiAgICBpci5FdmVudC5LZXlFdmVudC53VmlydHVhbFNjYW5Db2RlID0gSElXT1JEKGxQYXJhbSkgJiAweEZGOwoKICAgIGlyLkV2ZW50LktleUV2ZW50LnVDaGFyLlVuaWNvZGVDaGFyID0gMDsKICAgIGlyLkV2ZW50LktleUV2ZW50LmR3Q29udHJvbEtleVN0YXRlID0gV0NVU0VSX0dldEN0cmxLZXlTdGF0ZShrZXlTdGF0ZSk7CiAgICBpZiAobFBhcmFtICYgKDFMIDw8IDI0KSkJCWlyLkV2ZW50LktleUV2ZW50LmR3Q29udHJvbEtleVN0YXRlIHw9IEVOSEFOQ0VEX0tFWTsKICAgIGlmIChzeXMpCQkJCWlyLkV2ZW50LktleUV2ZW50LmR3Q29udHJvbEtleVN0YXRlIHw9IExFRlRfQUxUX1BSRVNTRUQ7IC8qIEZJWE1FOiBnb3R0YSBjaG9vc2Ugb25lICovCgogICAgaWYgKCEoaXIuRXZlbnQuS2V5RXZlbnQuZHdDb250cm9sS2V5U3RhdGUgJiBFTkhBTkNFRF9LRVkpKQogICAgewoJaWYgKGRvd24pCgl7CgkgICAgc3dpdGNoIChUb1VuaWNvZGUod1BhcmFtLCBISVdPUkQobFBhcmFtKSwga2V5U3RhdGUsIGJ1ZiwgMiwgMCkpCgkgICAgewoJICAgIGNhc2UgMjoKCQkvKiBGSVhNRS4uLiBzaG91bGQgZ2VuZXJhdGUgdHdvIGV2ZW50cy4uLiAqLwoJCS8qIGZhbGwgdGhydSAqLwoJICAgIGNhc2UgMToKCQlsYXN0ID0gYnVmWzBdOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJbGFzdCA9IDA7CgkJYnJlYWs7CgkgICAgfQoJfQoJaXIuRXZlbnQuS2V5RXZlbnQudUNoYXIuVW5pY29kZUNoYXIgPSBsYXN0OyAvKiBGSVhNRSBIQUNLWS4uLiBhbmQgYnVnZ3kgJ2NveiBpdCBzaG91bGQgYmUgYSBzdGFjaywgbm90IGEgc2luZ2xlIHZhbHVlICovCglpZiAoIWRvd24pIGxhc3QgPSAwOwogICAgfQoKICAgIFdyaXRlQ29uc29sZUlucHV0KGRhdGEtPmhDb25JbiwgJmlyLCAxLCAmbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQKICoKICoKICovCnN0YXRpYyB2b2lkICAgIFdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIENPT1JEIGMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1BBUkFNIHdQYXJhbSwgRFdPUkQgZXZlbnQpCnsKICAgIElOUFVUX1JFQ09SRAlpcjsKICAgIEJZVEUJCWtleVN0YXRlWzI1Nl07CiAgICBEV09SRCAgICAgICAgICAgICAgIG1vZGUsIG47CgogICAgLyogTU9VU0VfRVZFTlRzIHNob3VsZG4ndCBiZSBzZW50IHVubGVzcyBFTkFCTEVfTU9VU0VfSU5QVVQgaXMgYWN0aXZlICovCiAgICBpZiAoIUdldENvbnNvbGVNb2RlKGRhdGEtPmhDb25JbiwgJm1vZGUpIHx8ICEobW9kZSAmIEVOQUJMRV9NT1VTRV9JTlBVVCkpCiAgICAgICAgcmV0dXJuOwoKICAgIGlyLkV2ZW50VHlwZSA9IE1PVVNFX0VWRU5UOwogICAgaXIuRXZlbnQuTW91c2VFdmVudC5kd01vdXNlUG9zaXRpb24gPSBjOwogICAgaXIuRXZlbnQuTW91c2VFdmVudC5kd0J1dHRvblN0YXRlID0gMDsKICAgIGlmICh3UGFyYW0gJiBNS19MQlVUVE9OKSBpci5FdmVudC5Nb3VzZUV2ZW50LmR3QnV0dG9uU3RhdGUgfD0gRlJPTV9MRUZUXzFTVF9CVVRUT05fUFJFU1NFRDsKICAgIGlmICh3UGFyYW0gJiBNS19NQlVUVE9OKSBpci5FdmVudC5Nb3VzZUV2ZW50LmR3QnV0dG9uU3RhdGUgfD0gRlJPTV9MRUZUXzJORF9CVVRUT05fUFJFU1NFRDsKICAgIGlmICh3UGFyYW0gJiBNS19SQlVUVE9OKSBpci5FdmVudC5Nb3VzZUV2ZW50LmR3QnV0dG9uU3RhdGUgfD0gUklHSFRNT1NUX0JVVFRPTl9QUkVTU0VEOwogICAgaWYgKHdQYXJhbSAmIE1LX0NPTlRST0wpIGlyLkV2ZW50Lk1vdXNlRXZlbnQuZHdCdXR0b25TdGF0ZSB8PSBMRUZUX0NUUkxfUFJFU1NFRDsKICAgIGlmICh3UGFyYW0gJiBNS19TSElGVCkgICBpci5FdmVudC5Nb3VzZUV2ZW50LmR3QnV0dG9uU3RhdGUgfD0gU0hJRlRfUFJFU1NFRDsKICAgIGlmIChldmVudCA9PSBNT1VTRV9XSEVFTEVEKSBpci5FdmVudC5Nb3VzZUV2ZW50LmR3QnV0dG9uU3RhdGUgfD0gd1BhcmFtICYgMHhGRkZGMDAwMDsKICAgIGlyLkV2ZW50Lk1vdXNlRXZlbnQuZHdDb250cm9sS2V5U3RhdGUgPSBXQ1VTRVJfR2V0Q3RybEtleVN0YXRlKGtleVN0YXRlKTsKICAgIGlyLkV2ZW50Lk1vdXNlRXZlbnQuZHdFdmVudEZsYWdzID0gZXZlbnQ7CgogICAgV3JpdGVDb25zb2xlSW5wdXQoZGF0YS0+aENvbkluLCAmaXIsIDEsICZuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1Byb2MKICoKICoKICovCnN0YXRpYyBMUkVTVUxUIENBTExCQUNLIFdDVVNFUl9Qcm9jKEhXTkQgaFduZCwgVUlOVCB1TXNnLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBzdHJ1Y3QgaW5uZXJfZGF0YSoJZGF0YSA9IChzdHJ1Y3QgaW5uZXJfZGF0YSopR2V0V2luZG93TG9uZ1B0cihoV25kLCAwKTsKCiAgICBzd2l0Y2ggKHVNc2cpCiAgICB7CiAgICBjYXNlIFdNX0NSRUFURToKICAgICAgICByZXR1cm4gV0NVU0VSX0NyZWF0ZShoV25kLCAoTFBDUkVBVEVTVFJVQ1QpbFBhcmFtKTsKICAgIGNhc2UgV01fREVTVFJPWToKCVBSSVZBVEUoZGF0YSktPmhXbmQgPSAwOwoJUG9zdFF1aXRNZXNzYWdlKDApOwoJYnJlYWs7CiAgICBjYXNlIFdNX1BBSU5UOgoJV0NVU0VSX1BhaW50KGRhdGEpOwoJYnJlYWs7CiAgICBjYXNlIFdNX0tFWURPV046CiAgICBjYXNlIFdNX0tFWVVQOgogICAgICAgIGlmIChQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uKQogICAgICAgICAgICBXQ1VTRVJfSGFuZGxlU2VsZWN0aW9uS2V5KGRhdGEsIHVNc2cgPT0gV01fS0VZRE9XTiwgd1BhcmFtLCBsUGFyYW0pOwogICAgICAgIGVsc2UKICAgICAgICAgICAgV0NVU0VSX0dlbmVyYXRlS2V5SW5wdXRSZWNvcmQoZGF0YSwgdU1zZyA9PSBXTV9LRVlET1dOLCB3UGFyYW0sIGxQYXJhbSwgRkFMU0UpOwoJYnJlYWs7CiAgICBjYXNlIFdNX1NZU0tFWURPV046CiAgICBjYXNlIFdNX1NZU0tFWVVQOgoJV0NVU0VSX0dlbmVyYXRlS2V5SW5wdXRSZWNvcmQoZGF0YSwgdU1zZyA9PSBXTV9TWVNLRVlET1dOLCB3UGFyYW0sIGxQYXJhbSwgVFJVRSk7CglicmVhazsKICAgIGNhc2UgV01fTEJVVFRPTkRPV046CiAgICAgICAgaWYgKGRhdGEtPmN1cmNmZy5xdWlja19lZGl0KQogICAgICAgIHsKICAgICAgICAgICAgaWYgKFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24gPSBGQUxTRTsKICAgICAgICAgICAgICAgIFdDVVNFUl9TZXRTZWxlY3Rpb24oZGF0YSwgMCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIgPSBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pOwogICAgICAgICAgICAgICAgU2V0Q2FwdHVyZShQUklWQVRFKGRhdGEpLT5oV25kKTsKICAgICAgICAgICAgICAgIFdDVVNFUl9TZXRTZWxlY3Rpb24oZGF0YSwgMCk7CiAgICAgICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID0gVFJVRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBXQ1VTRVJfR2VuZXJhdGVNb3VzZUlucHV0UmVjb3JkKGRhdGEsIFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSksIHdQYXJhbSwgMCk7CiAgICAgICAgfQoJYnJlYWs7CiAgICBjYXNlIFdNX01PVVNFTU9WRToKICAgICAgICBpZiAoZGF0YS0+Y3VyY2ZnLnF1aWNrX2VkaXQpCiAgICAgICAgewogICAgICAgICAgICBpZiAoR2V0Q2FwdHVyZSgpID09IFBSSVZBVEUoZGF0YSktPmhXbmQgJiYgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiAmJgogICAgICAgICAgICAgICAgKHdQYXJhbSAmIE1LX0xCVVRUT04pKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEsIFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQoZGF0YSwgV0NVU0VSX0dldENlbGwoZGF0YSwgbFBhcmFtKSwgd1BhcmFtLCBNT1VTRV9NT1ZFRCk7CiAgICAgICAgfQoJYnJlYWs7CiAgICBjYXNlIFdNX0xCVVRUT05VUDoKICAgICAgICBpZiAoZGF0YS0+Y3VyY2ZnLnF1aWNrX2VkaXQpCiAgICAgICAgewogICAgICAgICAgICBpZiAoR2V0Q2FwdHVyZSgpID09IFBSSVZBVEUoZGF0YSktPmhXbmQgJiYgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiAmJgogICAgICAgICAgICAgICAgKHdQYXJhbSYgTUtfTEJVVFRPTikpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MSwgV0NVU0VSX0dldENlbGwoZGF0YSwgbFBhcmFtKSk7CiAgICAgICAgICAgICAgICBSZWxlYXNlQ2FwdHVyZSgpOwogICAgICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiA9IEZBTFNFOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQoZGF0YSwgV0NVU0VSX0dldENlbGwoZGF0YSwgbFBhcmFtKSwgd1BhcmFtLCAwKTsKICAgICAgICB9CglicmVhazsKICAgIGNhc2UgV01fUkJVVFRPTkRPV046CiAgICAgICAgaWYgKCh3UGFyYW0gJiAoTUtfQ09OVFJPTHxNS19TSElGVCkpID09IGRhdGEtPmN1cmNmZy5tZW51X21hc2spCiAgICAgICAgewogICAgICAgICAgICBSRUNUICAgICAgICByOwoKICAgICAgICAgICAgR2V0V2luZG93UmVjdChoV25kLCAmcik7CiAgICAgICAgICAgIFdDVVNFUl9TZXRNZW51RGV0YWlscyhkYXRhLCBQUklWQVRFKGRhdGEpLT5oUG9wTWVudSk7CiAgICAgICAgICAgIFRyYWNrUG9wdXBNZW51KFBSSVZBVEUoZGF0YSktPmhQb3BNZW51LCBUUE1fTEVGVEFMSUdOfFRQTV9UT1BBTElHTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgci5sZWZ0ICsgTE9XT1JEKGxQYXJhbSksIHIudG9wICsgSElXT1JEKGxQYXJhbSksIDAsIGhXbmQsIE5VTEwpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBXQ1VTRVJfR2VuZXJhdGVNb3VzZUlucHV0UmVjb3JkKGRhdGEsIFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSksIHdQYXJhbSwgMCk7CiAgICAgICAgfQoJYnJlYWs7CiAgICBjYXNlIFdNX1JCVVRUT05VUDoKICAgICAgICAvKiBubyBuZWVkIHRvIHRyYWNrIGZvciByYnV0dG9uIHVwIHdoZW4gb3BlbmluZyB0aGUgcG9wdXAuLi4gdGhlIGV2ZW50IHdpbGwgYmUKICAgICAgICAgKiBzd2FsbG93ZWQgYnkgVHJhY2tQb3B1cE1lbnUgKi8KICAgIGNhc2UgV01fTUJVVFRPTkRPV046CiAgICBjYXNlIFdNX01CVVRUT05VUDoKICAgICAgICBXQ1VTRVJfR2VuZXJhdGVNb3VzZUlucHV0UmVjb3JkKGRhdGEsIFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSksIHdQYXJhbSwgMCk7CglicmVhazsKICAgIGNhc2UgV01fTEJVVFRPTkRCTENMSzoKICAgIGNhc2UgV01fTUJVVFRPTkRCTENMSzoKICAgIGNhc2UgV01fUkJVVFRPTkRCTENMSzoKICAgICAgICBXQ1VTRVJfR2VuZXJhdGVNb3VzZUlucHV0UmVjb3JkKGRhdGEsIFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSksIHdQYXJhbSwgRE9VQkxFX0NMSUNLKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgV01fTU9VU0VXSEVFTDoKICAgICAgICBXQ1VTRVJfR2VuZXJhdGVNb3VzZUlucHV0UmVjb3JkKGRhdGEsICBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCB3UGFyYW0sIE1PVVNFX1dIRUVMRUQpOwoJYnJlYWs7CiAgICBjYXNlIFdNX1NFVEZPQ1VTOgoJaWYgKGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKCXsKCSAgICBDcmVhdGVDYXJldChQUklWQVRFKGRhdGEpLT5oV25kLCBQUklWQVRFKGRhdGEpLT5jdXJzb3JfYml0bWFwLAogICAgICAgICAgICAgICAgICAgICAgICBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwgZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0KTsKCSAgICBXQ1VTRVJfUG9zQ3Vyc29yKGRhdGEpOwoJfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBXTV9LSUxMRk9DVVM6CglpZiAoZGF0YS0+Y3VyY2ZnLmN1cnNvcl92aXNpYmxlKQoJICAgIERlc3Ryb3lDYXJldCgpOwoJYnJlYWs7CiAgICBjYXNlIFdNX0hTQ1JPTEw6CiAgICAgICAgewogICAgICAgICAgICBpbnQJcG9zID0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWDsKCiAgICAgICAgICAgIHN3aXRjaCAoTE9XT1JEKHdQYXJhbSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgY2FzZSBTQl9QQUdFVVA6IAlwb3MgLT0gODsgCQlicmVhazsKICAgICAgICAgICAgY2FzZSBTQl9QQUdFRE9XTjogCXBvcyArPSA4OyAJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX0xJTkVVUDogCXBvcy0tOwkJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX0xJTkVET1dOOiAJcG9zKys7CSAJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX1RIVU1CVFJBQ0s6IHBvcyA9IEhJV09SRCh3UGFyYW0pOwlicmVhazsKICAgICAgICAgICAgZGVmYXVsdDogCQkJCQlicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAocG9zIDwgMCkgcG9zID0gMDsKICAgICAgICAgICAgaWYgKHBvcyA+IGRhdGEtPmN1cmNmZy5zYl93aWR0aCAtIGRhdGEtPmN1cmNmZy53aW5fd2lkdGgpCiAgICAgICAgICAgICAgICBwb3MgPSBkYXRhLT5jdXJjZmcuc2Jfd2lkdGggLSBkYXRhLT5jdXJjZmcud2luX3dpZHRoOwogICAgICAgICAgICBpZiAocG9zICE9IGRhdGEtPmN1cmNmZy53aW5fcG9zLlgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFNjcm9sbFdpbmRvdyhoV25kLCAoZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWCAtIHBvcykgKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMKTsKICAgICAgICAgICAgICAgIGRhdGEtPmN1cmNmZy53aW5fcG9zLlggPSBwb3M7CiAgICAgICAgICAgICAgICBTZXRTY3JvbGxQb3MoaFduZCwgU0JfSE9SWiwgcG9zLCBUUlVFKTsKICAgICAgICAgICAgICAgIFVwZGF0ZVdpbmRvdyhoV25kKTsKICAgICAgICAgICAgICAgIFdDVVNFUl9Qb3NDdXJzb3IoZGF0YSk7CiAgICAgICAgICAgICAgICBXSU5FQ09OX05vdGlmeVdpbmRvd0NoYW5nZShkYXRhKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCWJyZWFrOwogICAgY2FzZSBXTV9WU0NST0xMOgogICAgICAgIHsKCSAgICBpbnQJcG9zID0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWTsKCgkgICAgc3dpdGNoIChMT1dPUkQod1BhcmFtKSkKCSAgICB7CiAgICAgICAgICAgIGNhc2UgU0JfUEFHRVVQOiAJcG9zIC09IDg7IAkJYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU0JfUEFHRURPV046IAlwb3MgKz0gODsgCQlicmVhazsKICAgICAgICAgICAgY2FzZSBTQl9MSU5FVVA6IAlwb3MtLTsJCQlicmVhazsKCSAgICBjYXNlIFNCX0xJTkVET1dOOiAJcG9zKys7CSAJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX1RIVU1CVFJBQ0s6IHBvcyA9IEhJV09SRCh3UGFyYW0pOwlicmVhazsKICAgICAgICAgICAgZGVmYXVsdDogCQkJCQlicmVhazsKCSAgICB9CgkgICAgaWYgKHBvcyA8IDApIHBvcyA9IDA7CgkgICAgaWYgKHBvcyA+IGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgLSBkYXRhLT5jdXJjZmcud2luX2hlaWdodCkKICAgICAgICAgICAgICAgIHBvcyA9IGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgLSBkYXRhLT5jdXJjZmcud2luX2hlaWdodDsKCSAgICBpZiAocG9zICE9IGRhdGEtPmN1cmNmZy53aW5fcG9zLlkpCgkgICAgewoJCVNjcm9sbFdpbmRvdyhoV25kLCAwLCAoZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSAtIHBvcykgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCk7CgkJZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSA9IHBvczsKCQlTZXRTY3JvbGxQb3MoaFduZCwgU0JfVkVSVCwgcG9zLCBUUlVFKTsKCQlVcGRhdGVXaW5kb3coaFduZCk7CgkJV0NVU0VSX1Bvc0N1cnNvcihkYXRhKTsKCQlXSU5FQ09OX05vdGlmeVdpbmRvd0NoYW5nZShkYXRhKTsKCSAgICB9CgogICAgICAgIH0KICAgIGNhc2UgV01fU1lTQ09NTUFORDoKCXN3aXRjaCAod1BhcmFtKQoJewoJY2FzZSBJRFNfREVGQVVMVDoKCSAgICBXQ1VTRVJfR2V0UHJvcGVydGllcyhkYXRhLCBGQUxTRSk7CgkgICAgYnJlYWs7CgljYXNlIElEU19QUk9QRVJUSUVTOgoJICAgIFdDVVNFUl9HZXRQcm9wZXJ0aWVzKGRhdGEsIFRSVUUpOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICByZXR1cm4gRGVmV2luZG93UHJvYyhoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7Cgl9CglicmVhazsKICAgIGNhc2UgV01fQ09NTUFORDoKCXN3aXRjaCAod1BhcmFtKQoJewoJY2FzZSBJRFNfREVGQVVMVDoKCSAgICBXQ1VTRVJfR2V0UHJvcGVydGllcyhkYXRhLCBGQUxTRSk7CgkgICAgYnJlYWs7CgljYXNlIElEU19QUk9QRVJUSUVTOgoJICAgIFdDVVNFUl9HZXRQcm9wZXJ0aWVzKGRhdGEsIFRSVUUpOwoJICAgIGJyZWFrOwoJY2FzZSBJRFNfTUFSSzoKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlggPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWSA9IDA7CiAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5YID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlkgPSAwOwogICAgICAgICAgICBXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIDApOwogICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID0gVFJVRTsKCSAgICBicmVhazsKCWNhc2UgSURTX0NPUFk6CiAgICAgICAgICAgIGlmIChQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID0gRkFMU0U7CiAgICAgICAgICAgICAgICBXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIDApOwogICAgICAgICAgICAgICAgV0NVU0VSX0NvcHlTZWxlY3Rpb25Ub0NsaXBib2FyZChkYXRhKTsKICAgICAgICAgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBJRFNfUEFTVEU6CgkgICAgV0NVU0VSX1Bhc3RlRnJvbUNsaXBib2FyZChkYXRhKTsKCSAgICBicmVhazsKCWNhc2UgSURTX1NFTEVDVEFMTDoKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlggPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWSA9IDA7CiAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5YID0gKGRhdGEtPmN1cmNmZy5zYl93aWR0aCAtIDEpICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGg7CiAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5ZID0gKGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgLSAxKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKICAgICAgICAgICAgV0NVU0VSX1NldFNlbGVjdGlvbihkYXRhLCAwKTsKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiA9IFRSVUU7CgkgICAgYnJlYWs7CgljYXNlIElEU19TQ1JPTEw6CgljYXNlIElEU19TRUFSQ0g6CgkgICAgV0lORV9GSVhNRSgiVW5oYW5kbGVkIHlldCBjb21tYW5kOiAleFxuIiwgd1BhcmFtKTsKCSAgICBicmVhazsKCWRlZmF1bHQ6CgkgICAgcmV0dXJuIERlZldpbmRvd1Byb2MoaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwoJfQoJYnJlYWs7CiAgICBjYXNlIFdNX0lOSVRNRU5VUE9QVVA6CglpZiAoIUhJV09SRChsUGFyYW0pKQlyZXR1cm4gRGVmV2luZG93UHJvYyhoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7CglXQ1VTRVJfU2V0TWVudURldGFpbHMoZGF0YSwgR2V0U3lzdGVtTWVudShQUklWQVRFKGRhdGEpLT5oV25kLCBGQUxTRSkpOwoJYnJlYWs7CiAgICBkZWZhdWx0OgoJcmV0dXJuIERlZldpbmRvd1Byb2MoaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9EZWxldGVCYWNrZW5kCiAqCiAqCiAqLwpzdGF0aWMgdm9pZCBXQ1VTRVJfRGVsZXRlQmFja2VuZChzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgaWYgKCFQUklWQVRFKGRhdGEpKSByZXR1cm47CiAgICBpZiAoUFJJVkFURShkYXRhKS0+aE1lbURDKQkJRGVsZXRlREMoUFJJVkFURShkYXRhKS0+aE1lbURDKTsKICAgIGlmIChQUklWQVRFKGRhdGEpLT5oV25kKQkJRGVzdHJveVdpbmRvdyhQUklWQVRFKGRhdGEpLT5oV25kKTsKICAgIGlmIChQUklWQVRFKGRhdGEpLT5oRm9udCkJCURlbGV0ZU9iamVjdChQUklWQVRFKGRhdGEpLT5oRm9udCk7CiAgICBpZiAoUFJJVkFURShkYXRhKS0+Y3Vyc29yX2JpdG1hcCkJRGVsZXRlT2JqZWN0KFBSSVZBVEUoZGF0YSktPmN1cnNvcl9iaXRtYXApOwogICAgaWYgKFBSSVZBVEUoZGF0YSktPmhCaXRtYXApCQlEZWxldGVPYmplY3QoUFJJVkFURShkYXRhKS0+aEJpdG1hcCk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBQUklWQVRFKGRhdGEpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX01haW5Mb29wCiAqCiAqCiAqLwpzdGF0aWMgaW50IFdDVVNFUl9NYWluTG9vcChzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgTVNHCQltc2c7CgogICAgU2hvd1dpbmRvdyhQUklWQVRFKGRhdGEpLT5oV25kLCBkYXRhLT5uQ21kU2hvdyk7CiAgICBmb3IgKDs7KQogICAgewoJc3dpdGNoIChNc2dXYWl0Rm9yTXVsdGlwbGVPYmplY3RzKDEsICZkYXRhLT5oU3luY2hybywgRkFMU0UsIElORklOSVRFLCBRU19BTExJTlBVVCkpCgl7CgljYXNlIFdBSVRfT0JKRUNUXzA6CgkgICAgaWYgKCFXSU5FQ09OX0dyYWJDaGFuZ2VzKGRhdGEpICYmIGRhdGEtPmN1cmNmZy5leGl0X29uX2RpZSkKICAgICAgICAgICAgICAgIFBvc3RRdWl0TWVzc2FnZSgwKTsKCSAgICBicmVhazsKCWNhc2UgV0FJVF9PQkpFQ1RfMCsxOgoJICAgIC8qIG5lZWQgdG8gdXNlIFBlZWtNZXNzYWdlIGxvb3AgaW5zdGVhZCBvZiBzaW1wbGUgR2V0TWVzc2FnZToKCSAgICAgKiBtdWx0aXBsZSBtZXNzYWdlcyBtaWdodCBoYXZlIGFycml2ZWQgaW4gYmV0d2VlbiwKCSAgICAgKiBzbyBHZXRNZXNzYWdlIHdvdWxkIGxlYWQgdG8gZGVsYXllZCBwcm9jZXNzaW5nICovCgkgICAgd2hpbGUgKFBlZWtNZXNzYWdlKCZtc2csIDAsIDAsIDAsIFBNX1JFTU9WRSkpCgkgICAgewogICAgICAgICAgICAgICAgaWYgKG1zZy5tZXNzYWdlID09IFdNX1FVSVQpIHJldHVybiAwOwogICAgICAgICAgICAgICAgV0lORV9UUkFDRSgiZGlzcGF0Y2hpbmcgbXNnICUwNHhcbiIsIG1zZy5tZXNzYWdlKTsKICAgICAgICAgICAgICAgIERpc3BhdGNoTWVzc2FnZSgmbXNnKTsKCSAgICB9CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIFdJTkVfRVJSKCJnb3QgcGJcbiIpOwoJICAgIC8qIGVyciAqLwoJICAgIGJyZWFrOwoJfQogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfSW5pdEJhY2tlbmQKICoKICogSW5pdGlhbGlzYXRpb24gcGFydCBJSTogY3JlYXRpb24gb2Ygd2luZG93LgogKgogKi8KZW51bSBpbml0X3JldHVybiBXQ1VTRVJfSW5pdEJhY2tlbmQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiB3Q2xhc3NOYW1lW10gPSB7J1cnLCdpJywnbicsJ2UnLCdDJywnbycsJ24nLCdzJywnbycsJ2wnLCdlJywnQycsJ2wnLCdhJywncycsJ3MnLDB9OwoKICAgIFdORENMQVNTCQl3bmRjbGFzczsKCiAgICBkYXRhLT5wcml2YXRlID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihzdHJ1Y3QgaW5uZXJfZGF0YV91c2VyKSk7CiAgICBpZiAoIWRhdGEtPnByaXZhdGUpIHJldHVybiBpbml0X2ZhaWxlZDsKCiAgICBkYXRhLT5mbk1haW5Mb29wID0gV0NVU0VSX01haW5Mb29wOwogICAgZGF0YS0+Zm5Qb3NDdXJzb3IgPSBXQ1VTRVJfUG9zQ3Vyc29yOwogICAgZGF0YS0+Zm5TaGFwZUN1cnNvciA9IFdDVVNFUl9TaGFwZUN1cnNvcjsKICAgIGRhdGEtPmZuQ29tcHV0ZVBvc2l0aW9ucyA9IFdDVVNFUl9Db21wdXRlUG9zaXRpb25zOwogICAgZGF0YS0+Zm5SZWZyZXNoID0gV0NVU0VSX1JlZnJlc2g7CiAgICBkYXRhLT5mblJlc2l6ZVNjcmVlbkJ1ZmZlciA9IFdDVVNFUl9SZXNpemVTY3JlZW5CdWZmZXI7CiAgICBkYXRhLT5mblNldFRpdGxlID0gV0NVU0VSX1NldFRpdGxlOwogICAgZGF0YS0+Zm5TZXRGb250ID0gV0NVU0VSX1NldEZvbnRQbXQ7CiAgICBkYXRhLT5mblNjcm9sbCA9IFdDVVNFUl9TY3JvbGw7CiAgICBkYXRhLT5mbkRlbGV0ZUJhY2tlbmQgPSBXQ1VTRVJfRGVsZXRlQmFja2VuZDsKCiAgICB3bmRjbGFzcy5zdHlsZSAgICAgICAgID0gQ1NfREJMQ0xLUzsKICAgIHduZGNsYXNzLmxwZm5XbmRQcm9jICAgPSBXQ1VTRVJfUHJvYzsKICAgIHduZGNsYXNzLmNiQ2xzRXh0cmEgICAgPSAwOwogICAgd25kY2xhc3MuY2JXbmRFeHRyYSAgICA9IHNpemVvZihEV09SRF9QVFIpOwogICAgd25kY2xhc3MuaEluc3RhbmNlICAgICA9IEdldE1vZHVsZUhhbmRsZShOVUxMKTsKICAgIHduZGNsYXNzLmhJY29uICAgICAgICAgPSBMb2FkSWNvbigwLCBJRElfV0lOTE9HTyk7CiAgICB3bmRjbGFzcy5oQ3Vyc29yICAgICAgID0gTG9hZEN1cnNvcigwLCBJRENfQVJST1cpOwogICAgd25kY2xhc3MuaGJyQmFja2dyb3VuZCA9IEdldFN0b2NrT2JqZWN0KEJMQUNLX0JSVVNIKTsKICAgIHduZGNsYXNzLmxwc3pNZW51TmFtZSAgPSBOVUxMOwogICAgd25kY2xhc3MubHBzekNsYXNzTmFtZSA9IHdDbGFzc05hbWU7CgogICAgUmVnaXN0ZXJDbGFzcygmd25kY2xhc3MpOwoKICAgIENyZWF0ZVdpbmRvdyh3bmRjbGFzcy5scHN6Q2xhc3NOYW1lLCBOVUxMLAoJCSBXU19PVkVSTEFQUEVEfFdTX0NBUFRJT058V1NfU1lTTUVOVXxXU19USElDS0ZSQU1FfFdTX01JTklNSVpFQk9YfFdTX0hTQ1JPTEx8V1NfVlNDUk9MTCwKCQkgQ1dfVVNFREVGQVVMVCwgQ1dfVVNFREVGQVVMVCwgMCwgMCwgMCwgMCwgd25kY2xhc3MuaEluc3RhbmNlLCBkYXRhKTsKICAgIGlmICghUFJJVkFURShkYXRhKS0+aFduZCkgcmV0dXJuIGluaXRfZmFpbGVkOwoKICAgIHJldHVybiBpbml0X3N1Y2Nlc3M7Cn0K