LyoKICogQ29weXJpZ2h0IChDKSAyMDAzIE1pY2hhZWwgR/xubmV3aWcKICogQ29weXJpZ2h0IChDKSAyMDAzIENvZGVXZWF2ZXJzIEluYy4gKFVscmljaCBDemVrYWxsYSkKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqLwoKI2RlZmluZSBDT01fTk9fV0lORE9XU19ICiNpbmNsdWRlIDxzdGRhcmcuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgIm9iamJhc2UuaCIKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAiaW5pdGd1aWQuaCIKI2luY2x1ZGUgImRtby5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwobXNkbW8pOwoKCnN0YXRpYyBjb25zdCBXQ0hBUiBzekRNT1Jvb3RLZXlbXSA9IAp7CiAgICAnRCcsJ2knLCdyJywnZScsJ2MnLCd0JywnUycsJ2gnLCdvJywndycsJ1xcJywKICAgICdNJywnZScsJ2QnLCdpJywnYScsJ08nLCdiJywnaicsJ2UnLCdjJywndCcsJ3MnLDAKfTsgCgpzdGF0aWMgY29uc3QgV0NIQVIgc3pETU9JbnB1dFR5cGVbXSA9CnsKICAgICdJJywnbicsJ3AnLCd1JywndCcsJ1QnLCd5JywncCcsJ2UnLCdzJywwCn07CgpzdGF0aWMgY29uc3QgV0NIQVIgc3pETU9PdXRwdXRUeXBlW10gPQp7CiAgICAnTycsJ3UnLCd0JywncCcsJ3UnLCd0JywnVCcsJ3knLCdwJywnZScsJ3MnLDAKfTsKCnN0YXRpYyBjb25zdCBXQ0hBUiBzekRNT0tleWVkW10gPQp7CiAgICAnSycsJ2UnLCd5JywnZScsJ2QnLDAKfTsKCnN0YXRpYyBjb25zdCBXQ0hBUiBzekRNT0NhdGVnb3JpZXNbXSA9CnsKICAgICdDJywnYScsJ3QnLCdlJywnZycsJ28nLCdyJywnaScsJ2UnLCdzJywwCn07CgpzdGF0aWMgY29uc3QgV0NIQVIgc3pHVUlERm10W10gPQp7CiAgICAnJScsJzAnLCc4JywnWCcsJy0nLCclJywnMCcsJzQnLCdYJywnLScsJyUnLCcwJywnNCcsJ1gnLCctJywnJScsJzAnLAogICAgJzInLCdYJywnJScsJzAnLCcyJywnWCcsJy0nLCclJywnMCcsJzInLCdYJywnJScsJzAnLCcyJywnWCcsJyUnLCcwJywnMicsCiAgICAnWCcsJyUnLCcwJywnMicsJ1gnLCclJywnMCcsJzInLCdYJywnJScsJzAnLCcyJywnWCcsMAp9OwoKc3RhdGljIGNvbnN0IFdDSEFSIHN6Q2F0M0ZtdFtdID0KewogICAgJyUnLCdzJywnXFwnLCclJywncycsJ1xcJywnJScsJ3MnLDAKfTsKCnN0YXRpYyBjb25zdCBXQ0hBUiBzekNhdDJGbXRbXSA9CnsKICAgICclJywncycsJ1xcJywnJScsJ3MnLDAKfTsKCnR5cGVkZWYgc3RydWN0CnsKICAgIGNvbnN0IElFbnVtRE1PVnRibCAgICAgICAgICpscFZ0Ymw7CiAgICBMT05HCQkJcmVmOwogICAgRFdPUkQJCQlpbmRleDsKICAgIGNvbnN0IEdVSUQqICAgICAgICAgICAgICAgICBndWlkQ2F0ZWdvcnk7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgZHdGbGFnczsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICBjSW5UeXBlczsKICAgIERNT19QQVJUSUFMX01FRElBVFlQRSAgICAgICAqcEluVHlwZXM7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgY091dFR5cGVzOwogICAgRE1PX1BBUlRJQUxfTUVESUFUWVBFICAgICAgICpwT3V0VHlwZXM7CiAgICBIS0VZICAgICAgICAgICAgICAgICAgICAgICAgaGtleTsKfSBJRW51bURNT0ltcGw7CgpzdGF0aWMgY29uc3QgSUVudW1ETU9WdGJsIGVkbW92dDsKCnN0YXRpYyBMUFdTVFIgR1VJRFRvU3RyaW5nKExQV1NUUiBscHdzdHIsIFJFRkdVSUQgbHBjZ3VpZCkKewogICAgd3NwcmludGZXKGxwd3N0ciwgc3pHVUlERm10LCBscGNndWlkLT5EYXRhMSwgbHBjZ3VpZC0+RGF0YTIsCiAgICAgICAgbHBjZ3VpZC0+RGF0YTMsIGxwY2d1aWQtPkRhdGE0WzBdLCBscGNndWlkLT5EYXRhNFsxXSwKICAgICAgICBscGNndWlkLT5EYXRhNFsyXSwgbHBjZ3VpZC0+RGF0YTRbM10sIGxwY2d1aWQtPkRhdGE0WzRdLAogICAgICAgIGxwY2d1aWQtPkRhdGE0WzVdLCBscGNndWlkLT5EYXRhNFs2XSwgbHBjZ3VpZC0+RGF0YTRbN10pOwoKICAgIHJldHVybiBscHdzdHI7Cn0KCnN0YXRpYyBCT09MIElzTWVkaWFUeXBlRXF1YWwoRE1PX1BBUlRJQUxfTUVESUFUWVBFKiBtdDEsIERNT19QQVJUSUFMX01FRElBVFlQRSogbXQyKQp7CgogICAgcmV0dXJuIChJc0VxdWFsQ0xTSUQoJm10MS0+dHlwZSwgJm10Mi0+dHlwZSkgfHwKICAgICAgICAgICAgSXNFcXVhbENMU0lEKCZtdDItPnR5cGUsICZHVUlEX05VTEwpIHx8CiAgICAgICAgICAgIElzRXF1YWxDTFNJRCgmbXQxLT50eXBlLCAmR1VJRF9OVUxMKSkgJiYKICAgICAgICAgICAgKElzRXF1YWxDTFNJRCgmbXQxLT5zdWJ0eXBlLCAmbXQyLT5zdWJ0eXBlKSB8fAogICAgICAgICAgICBJc0VxdWFsQ0xTSUQoJm10Mi0+c3VidHlwZSwgJkdVSURfTlVMTCkgfHwKICAgICAgICAgICAgSXNFcXVhbENMU0lEKCZtdDEtPnN1YnR5cGUsICZHVUlEX05VTEwpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBETU9SZWdpc3RlcgogKgogKiBSZWdpc3RlciBhIERpcmVjdFggTWVkaWEgT2JqZWN0LgogKi8KSFJFU1VMVCBXSU5BUEkgRE1PUmVnaXN0ZXIoCiAgIExQQ1dTVFIgc3pOYW1lLAogICBSRUZDTFNJRCBjbHNpZERNTywKICAgUkVGR1VJRCBndWlkQ2F0ZWdvcnksCiAgIERXT1JEIGR3RmxhZ3MsCiAgIERXT1JEIGNJblR5cGVzLAogICBjb25zdCBETU9fUEFSVElBTF9NRURJQVRZUEUgKnBJblR5cGVzLAogICBEV09SRCBjT3V0VHlwZXMsCiAgIGNvbnN0IERNT19QQVJUSUFMX01FRElBVFlQRSAqcE91dFR5cGVzCikKewogICAgV0NIQVIgc3pndWlkWzY0XTsKICAgIEhSRVNVTFQgaHJlczsKICAgIEhLRVkgaHJrZXkgPSAwOwogICAgSEtFWSBoa2V5ID0gMDsKICAgIEhLRVkgaGNrZXkgPSAwOwogICAgSEtFWSBoY2xza2V5ID0gMDsKCiAgICBUUkFDRSgiJXNcbiIsIGRlYnVnc3RyX3coc3pOYW1lKSk7CgogICAgaHJlcyA9IFJlZ09wZW5LZXlFeFcoSEtFWV9DTEFTU0VTX1JPT1QsIHN6RE1PUm9vdEtleSwgMCwgS0VZX1dSSVRFLCAmaHJrZXkpOwogICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICBnb3RvIGxlbmQ7CgogICAgLyogQ3JlYXRlIGNsc2lkRE1PIGtleSB1bmRlciBNZWRpYU9iamVjdHMgKi8gCiAgICBocmVzID0gUmVnQ3JlYXRlS2V5RXhXKGhya2V5LCBHVUlEVG9TdHJpbmcoc3pndWlkLCBjbHNpZERNTyksIDAsIE5VTEwsCiAgICAgICAgUkVHX09QVElPTl9OT05fVk9MQVRJTEUsIEtFWV9XUklURSwgTlVMTCwgJmhrZXksIE5VTEwpOwogICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICBnb3RvIGxlbmQ7CgogICAgLyogU2V0IGRlZmF1bHQgTmFtZSB2YWx1ZSAqLwogICAgaHJlcyA9IFJlZ1NldFZhbHVlRXhXKGhrZXksIE5VTEwsIDAsIFJFR19TWiwgKGNvbnN0IEJZVEUqKSBzek5hbWUsIAogICAgICAgIChzdHJsZW5XKHN6TmFtZSkgKyAxKSkgKiBzaXplb2YoV0NIQVIpOwogICAgLyogU2V0IElucHV0VHlwZXMgKi8KICAgIGhyZXMgPSBSZWdTZXRWYWx1ZUV4Vyhoa2V5LCBzekRNT0lucHV0VHlwZSwgMCwgUkVHX0JJTkFSWSwgCiAgICAgICAgKGNvbnN0IEJZVEUqKSBwSW5UeXBlcywgY0luVHlwZXMgKiBzaXplb2YoRE1PX1BBUlRJQUxfTUVESUFUWVBFKSk7CiAgICAvKiBTZXQgT3V0cHV0VHlwZXMgKi8KICAgIGhyZXMgPSBSZWdTZXRWYWx1ZUV4Vyhoa2V5LCBzekRNT091dHB1dFR5cGUsIDAsIFJFR19CSU5BUlksIAogICAgICAgIChjb25zdCBCWVRFKikgcE91dFR5cGVzLCBjT3V0VHlwZXMgKiBzaXplb2YoRE1PX1BBUlRJQUxfTUVESUFUWVBFKSk7CgogICAgaWYgKGR3RmxhZ3MgJiBETU9fUkVHSVNURVJGX0lTX0tFWUVEKQogICAgewogICAgICAgIC8qIENyZWF0ZSBLZXllZCBrZXkgKi8gCiAgICAgICAgaHJlcyA9IFJlZ0NyZWF0ZUtleUV4Vyhoa2V5LCBzekRNT0tleWVkLCAwLCBOVUxMLAogICAgICAgICAgICBSRUdfT1BUSU9OX05PTl9WT0xBVElMRSwgS0VZX1dSSVRFLCBOVUxMLCAmaGNrZXksIE5VTEwpOwogICAgICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgICAgIGdvdG8gbGVuZDsKICAgICAgICBSZWdDbG9zZUtleShoY2tleSk7CiAgICB9CgogICAgLyogUmVnaXN0ZXIgdGhlIGNhdGVnb3J5ICovCiAgICBocmVzID0gUmVnT3BlbktleUV4VyhocmtleSwgc3pETU9DYXRlZ29yaWVzLCAwLCBLRVlfV1JJVEUsICZoY2tleSk7CiAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgIGdvdG8gbGVuZDsKCiAgICBSZWdDbG9zZUtleShoa2V5KTsKCiAgICBocmVzID0gUmVnT3BlbktleUV4VyhoY2tleSwgR1VJRFRvU3RyaW5nKHN6Z3VpZCwgZ3VpZENhdGVnb3J5KSwgMCwgS0VZX1dSSVRFLCAmaGtleSk7CiAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgIGdvdG8gbGVuZDsKICAgIGhyZXMgPSBSZWdDcmVhdGVLZXlFeFcoaGtleSwgR1VJRFRvU3RyaW5nKHN6Z3VpZCwgY2xzaWRETU8pLCAwLCBOVUxMLAogICAgICAgIFJFR19PUFRJT05fTk9OX1ZPTEFUSUxFLCBLRVlfV1JJVEUsIE5VTEwsICZoY2xza2V5LCBOVUxMKTsKICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgZ290byBsZW5kOwoKbGVuZDoKICAgIGlmIChoa2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgaWYgKGhja2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhja2V5KTsKICAgIGlmIChoY2xza2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhjbHNrZXkpOwogICAgaWYgKGhya2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhya2V5KTsKCiAgICBUUkFDRSgiIGhyZXN1bHQ9MHglMDhseFxuIiwgaHJlcyk7CiAgICByZXR1cm4gaHJlczsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRE1PVW5yZWdpc3RlcgogKgogKiBVbnJlZ2lzdGVyIGEgRGlyZWN0WCBNZWRpYSBPYmplY3QuCiAqLwpIUkVTVUxUIFdJTkFQSSBETU9VbnJlZ2lzdGVyKFJFRkNMU0lEIGNsc2lkRE1PLCBSRUZHVUlEIGd1aWRDYXRlZ29yeSkKewogICAgSFJFU1VMVCBocmVzOwogICAgV0NIQVIgc3pndWlkWzY0XTsKICAgIEhLRVkgaHJrZXkgPSAwOwogICAgSEtFWSBoY2tleSA9IDA7CgogICAgR1VJRFRvU3RyaW5nKHN6Z3VpZCwgY2xzaWRETU8pOwoKICAgIFRSQUNFKCIlcyAlcFxuIiwgZGVidWdzdHJfdyhzemd1aWQpLCBndWlkQ2F0ZWdvcnkpOwoKICAgIGhyZXMgPSBSZWdPcGVuS2V5RXhXKEhLRVlfQ0xBU1NFU19ST09ULCBzekRNT1Jvb3RLZXksIDAsIEtFWV9XUklURSwgJmhya2V5KTsKICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgZ290byBsZW5kOwoKICAgIGhyZXMgPSBSZWdEZWxldGVLZXlXKGhya2V5LCBzemd1aWQpOwogICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICBnb3RvIGxlbmQ7CgogICAgaHJlcyA9IFJlZ09wZW5LZXlFeFcoaHJrZXksIHN6RE1PQ2F0ZWdvcmllcywgMCwgS0VZX1dSSVRFLCAmaGNrZXkpOwogICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICBnb3RvIGxlbmQ7CgogICAgaHJlcyA9IFJlZ0RlbGV0ZUtleVcoaGNrZXksIHN6Z3VpZCk7CiAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgIGdvdG8gbGVuZDsKCmxlbmQ6CiAgICBpZiAoaGNrZXkpCiAgICAgICAgUmVnQ2xvc2VLZXkoaGNrZXkpOwogICAgaWYgKGhya2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhya2V5KTsKCiAgICByZXR1cm4gaHJlczsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRE1PR2V0TmFtZQogKgogKiBHZXQgRE1QIE5hbWUgZnJvbSB0aGUgcmVnaXN0cnkKICovCkhSRVNVTFQgV0lOQVBJIERNT0dldE5hbWUoUkVGQ0xTSUQgY2xzaWRETU8sIFdDSEFSKiBzek5hbWUpCnsKICAgIFdDSEFSIHN6Z3VpZFs2NF07CiAgICBIUkVTVUxUIGhyZXM7CiAgICBIS0VZIGhya2V5ID0gMDsKICAgIEhLRVkgaGtleSA9IDA7CiAgICBEV09SRCBjb3VudDsKCiAgICBUUkFDRSgiJXNcbiIsIGRlYnVnc3RyX2d1aWQoY2xzaWRETU8pKTsKCiAgICBocmVzID0gUmVnT3BlbktleUV4VyhIS0VZX0NMQVNTRVNfUk9PVCwgc3pETU9Sb290S2V5LCAKICAgICAgICAwLCBLRVlfUkVBRCwgJmhya2V5KTsKICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgZ290byBsZW5kOwoKICAgIGhyZXMgPSBSZWdPcGVuS2V5RXhXKGhya2V5LCBHVUlEVG9TdHJpbmcoc3pndWlkLCBjbHNpZERNTyksCiAgICAgICAgMCwgS0VZX1JFQUQsICZoa2V5KTsKICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgZ290byBsZW5kOwoKICAgIGNvdW50ID0gODAgKiBzaXplb2YoV0NIQVIpOyAvKiA4MCBieSBBUEkgZGVmaW5pdGlvbiAqLwogICAgaHJlcyA9IFJlZ1F1ZXJ5VmFsdWVFeFcoaGtleSwgTlVMTCwgTlVMTCwgTlVMTCwgCiAgICAgICAgKExQQllURSkgc3pOYW1lLCAmY291bnQpOyAKCiAgICBUUkFDRSgiIHN6TmFtZT0lc1xuIiwgZGVidWdzdHJfdyhzek5hbWUpKTsKbGVuZDoKICAgIGlmIChoa2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhya2V5KTsKICAgIGlmIChoa2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwoKICAgIHJldHVybiBocmVzOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogICBJRW51bURNT19EZXN0cnVjdG9yCiovCnN0YXRpYyBCT09MIElFbnVtRE1PX0Rlc3RydWN0b3IoSUVudW1ETU8qIGlmYWNlKQp7CiAgICBJRW51bURNT0ltcGwgKlRoaXMgPSAoSUVudW1ETU9JbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiVwXG4iLCBUaGlzKTsKCiAgICBpZiAoVGhpcy0+aGtleSkKICAgICAgICBSZWdDbG9zZUtleShUaGlzLT5oa2V5KTsKCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5wSW5UeXBlcyk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5wT3V0VHlwZXMpOwoKICAgIHJldHVybiBUUlVFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBJRW51bURNT19Db25zdHJ1Y3RvcgogKi8KSUVudW1ETU8gKiBJRW51bURNT19Db25zdHJ1Y3RvcigKICAgIFJFRkdVSUQgZ3VpZENhdGVnb3J5LAogICAgRFdPUkQgZHdGbGFncywKICAgIERXT1JEIGNJblR5cGVzLAogICAgY29uc3QgRE1PX1BBUlRJQUxfTUVESUFUWVBFICpwSW5UeXBlcywKICAgIERXT1JEIGNPdXRUeXBlcywKICAgIGNvbnN0IERNT19QQVJUSUFMX01FRElBVFlQRSAqcE91dFR5cGVzKQp7CiAgICBVSU5UIHNpemU7CiAgICBJRW51bURNT0ltcGwqIGxwZWRtbzsKICAgIEJPT0wgcmV0ID0gRkFMU0U7CgogICAgbHBlZG1vID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJRW51bURNT0ltcGwpKTsKCiAgICBpZiAobHBlZG1vKQogICAgewogICAgICAgIGxwZWRtby0+cmVmID0gMTsKICAgICAgICBscGVkbW8tPmxwVnRibCA9ICZlZG1vdnQ7CiAgICAgICAgbHBlZG1vLT5pbmRleCA9IC0xOwoJbHBlZG1vLT5ndWlkQ2F0ZWdvcnkgPSBndWlkQ2F0ZWdvcnk7CglscGVkbW8tPmR3RmxhZ3MgPSBkd0ZsYWdzOwoKCXNpemUgPSBjSW5UeXBlcyAqIHNpemVvZihETU9fUEFSVElBTF9NRURJQVRZUEUpOwogICAgICAgIGxwZWRtby0+cEluVHlwZXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZSk7CiAgICAgICAgaWYgKCFscGVkbW8tPnBJblR5cGVzKQogICAgICAgICAgICBnb3RvIGxlcnI7CgltZW1jcHkobHBlZG1vLT5wSW5UeXBlcywgcEluVHlwZXMsIHNpemUpOwogICAgICAgIGxwZWRtby0+Y0luVHlwZXMgPSBjSW5UeXBlczsKCglzaXplID0gY091dFR5cGVzICogc2l6ZW9mKERNT19QQVJUSUFMX01FRElBVFlQRSk7CiAgICAgICAgbHBlZG1vLT5wT3V0VHlwZXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZSk7CiAgICAgICAgaWYgKCFscGVkbW8tPnBPdXRUeXBlcykKICAgICAgICAgICAgZ290byBsZXJyOwoJbWVtY3B5KGxwZWRtby0+cE91dFR5cGVzLCBwT3V0VHlwZXMsIHNpemUpOwogICAgICAgIGxwZWRtby0+Y091dFR5cGVzID0gY091dFR5cGVzOwoKICAgICAgICAvKiBJZiBub3QgZmlsdGVyaW5nIGJ5IGNhdGVnb3J5IGVudW0gZnJvbSBtZWRpYSBvYmplY3RzIHJvb3QgKi8KICAgICAgICBpZiAoSXNFcXVhbEdVSUQoZ3VpZENhdGVnb3J5LCAmR1VJRF9OVUxMKSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChFUlJPUl9TVUNDRVNTID09IFJlZ09wZW5LZXlFeFcoSEtFWV9DTEFTU0VTX1JPT1QsIHN6RE1PUm9vdEtleSwgCiAgICAgICAgICAgICAgICAwLCBLRVlfUkVBRCwgJmxwZWRtby0+aGtleSkpCiAgICAgICAgICAgICAgICByZXQgPSBUUlVFOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBXQ0hBUiBzemd1aWRbNjRdOwogICAgICAgICAgICBXQ0hBUiBzektleVtNQVhfUEFUSF07CgogICAgICAgICAgICB3c3ByaW50Zlcoc3pLZXksIHN6Q2F0M0ZtdCwgc3pETU9Sb290S2V5LCBzekRNT0NhdGVnb3JpZXMsIAogICAgICAgICAgICAgICAgR1VJRFRvU3RyaW5nKHN6Z3VpZCwgZ3VpZENhdGVnb3J5KSk7CiAgICAgICAgICAgIGlmIChFUlJPUl9TVUNDRVNTID09IFJlZ09wZW5LZXlFeFcoSEtFWV9DTEFTU0VTX1JPT1QsIHN6S2V5LCAKICAgICAgICAgICAgICAgIDAsIEtFWV9SRUFELCAmbHBlZG1vLT5oa2V5KSkKICAgICAgICAgICAgICAgIHJldCA9IFRSVUU7CiAgICAgICAgfQoKbGVycjoKICAgICAgICBpZighcmV0KQogICAgICAgIHsKICAgICAgICAgICAgSUVudW1ETU9fRGVzdHJ1Y3RvcigoSUVudW1ETU8qKWxwZWRtbyk7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxscGVkbW8pOwogICAgICAgICAgICBscGVkbW8gPSBOVUxMOwogICAgICAgIH0KICAgIH0KCiAgICBUUkFDRSgicmV0dXJuaW5nICVwXG4iLCBscGVkbW8pOwoKICAgIHJldHVybiAoSUVudW1ETU8qKWxwZWRtbzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUVudW1ETU9fZm5BZGRSZWYKICovCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUVudW1ETU9fZm5BZGRSZWYoSUVudW1ETU8gKiBpZmFjZSkKewogICAgSUVudW1ETU9JbXBsICpUaGlzID0gKElFbnVtRE1PSW1wbCAqKWlmYWNlOwogICAgcmV0dXJuIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWYpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBFbnVtRE1PX1F1ZXJ5SW50ZXJmYWNlCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVudW1ETU9fZm5RdWVyeUludGVyZmFjZSgKICAgIElFbnVtRE1PKiBpZmFjZSwKICAgIFJFRklJRCByaWlkLAogICAgTFBWT0lEICpwcHZPYmopCnsKICAgIElFbnVtRE1PSW1wbCAqVGhpcyA9IChJRW51bURNT0ltcGwgKilpZmFjZTsKCiAgICAqcHB2T2JqID0gTlVMTDsKCiAgICBpZihJc0VxdWFsSUlEKHJpaWQsICZJSURfSVVua25vd24pKQogICAgICAgICpwcHZPYmogPSBUaGlzOwogICAgZWxzZSBpZihJc0VxdWFsSUlEKHJpaWQsICZJSURfSUVudW1ETU8pKQogICAgICAgICpwcHZPYmogPSAoSUVudW1ETU8qKVRoaXM7CgogICAgaWYoKnBwdk9iaikKICAgIHsKICAgICAgICBJRW51bURNT19mbkFkZFJlZigoSUVudW1ETU8qKSpwcHZPYmopOwogICAgICAgIHJldHVybiBTX09LOwogICAgfQoKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRW51bURNT19mblJlbGVhc2UKICovCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUVudW1ETU9fZm5SZWxlYXNlKElFbnVtRE1PICogaWZhY2UpCnsKICAgIElFbnVtRE1PSW1wbCAqVGhpcyA9IChJRW51bURNT0ltcGwgKilpZmFjZTsKICAgIFVMT05HIHJlZkNvdW50ID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZik7CgogICAgaWYgKCFyZWZDb3VudCkKICAgIHsKICAgICAgICBJRW51bURNT19EZXN0cnVjdG9yKChJRW51bURNTyopVGhpcyk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMpOwogICAgfQogICAgcmV0dXJuIHJlZkNvdW50Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRW51bURNT19mbk5leHQKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRW51bURNT19mbk5leHQoCiAgICBJRW51bURNTyAqIGlmYWNlLCAKICAgIERXT1JEIGNJdGVtc1RvRmV0Y2gsCiAgICBDTFNJRCAqIHBDTFNJRCwKICAgIFdDSEFSICoqIE5hbWVzLAogICAgRFdPUkQgKiBwY0l0ZW1zRmV0Y2hlZCkKewogICAgRklMRVRJTUUgZnQ7CiAgICBIS0VZIGhrZXk7CiAgICBXQ0hBUiBzek5leHRLZXlbTUFYX1BBVEhdOwogICAgV0NIQVIgc3pLZXlbTUFYX1BBVEhdOwogICAgV0NIQVIgc3pWYWx1ZVtNQVhfUEFUSF07CiAgICBEV09SRCBsZW47CiAgICBVSU5UIGNvdW50ID0gMDsKICAgIEhSRVNVTFQgaHJlcyA9IFNfT0s7CgogICAgSUVudW1ETU9JbXBsICpUaGlzID0gKElFbnVtRE1PSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIlbGRcbiIsIGNJdGVtc1RvRmV0Y2gpOwoKICAgIGlmICghcENMU0lEIHx8ICFOYW1lcyB8fCAhcGNJdGVtc0ZldGNoZWQpCiAgICAgICAgcmV0dXJuIEVfUE9JTlRFUjsKCiAgICB3aGlsZSAoY291bnQgPCBjSXRlbXNUb0ZldGNoKQogICAgewogICAgICAgIFRoaXMtPmluZGV4Kys7CgogICAgICAgIGhyZXMgPSBSZWdFbnVtS2V5RXhXKFRoaXMtPmhrZXksIFRoaXMtPmluZGV4LCBzek5leHRLZXksICZsZW4sIE5VTEwsIE5VTEwsIE5VTEwsICZmdCk7CiAgICAgICAgaWYgKGhyZXMgIT0gRVJST1JfU1VDQ0VTUykKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIFRSQUNFKCJmb3VuZCAlc1xuIiwgZGVidWdzdHJfdyhzek5leHRLZXkpKTsKCglpZiAoVGhpcy0+ZHdGbGFncyAmIERNT19SRUdJU1RFUkZfSVNfS0VZRUQpCiAgICAgICAgewogICAgICAgICAgICB3c3ByaW50Zlcoc3pLZXksIHN6Q2F0M0ZtdCwgc3pETU9Sb290S2V5LCBzek5leHRLZXksIHN6RE1PS2V5ZWQpOwogICAgICAgICAgICBocmVzID0gUmVnT3BlbktleUV4VyhIS0VZX0NMQVNTRVNfUk9PVCwgc3pLZXksIDAsIEtFWV9SRUFELCAmaGtleSk7CiAgICAgICAgICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICAgICAgfQoKICAgICAgICB3c3ByaW50Zlcoc3pLZXksIHN6Q2F0MkZtdCwgc3pETU9Sb290S2V5LCBzek5leHRLZXkpOwogICAgICAgIGhyZXMgPSBSZWdPcGVuS2V5RXhXKEhLRVlfQ0xBU1NFU19ST09ULCBzektleSwgMCwgS0VZX1JFQUQsICZoa2V5KTsKCiAgICAgICAgaWYgKFRoaXMtPnBJblR5cGVzKQogICAgICAgIHsKICAgICAgICAgICAgVUlOVCBpLCBqOwogICAgICAgICAgICBEV09SRCBjSW5UeXBlczsKICAgICAgICAgICAgRE1PX1BBUlRJQUxfTUVESUFUWVBFKiBwSW5UeXBlczsKCgkgICAgbGVuID0gTUFYX1BBVEggKiBzaXplb2YoV0NIQVIpOwogICAgICAgICAgICBocmVzID0gUmVnUXVlcnlWYWx1ZUV4Vyhoa2V5LCBzekRNT0lucHV0VHlwZSwgTlVMTCwgTlVMTCwgKExQQllURSkgc3pWYWx1ZSwgJmxlbik7CgkgICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKCSAgICBjSW5UeXBlcyA9IGxlbiAvIHNpemVvZihETU9fUEFSVElBTF9NRURJQVRZUEUpOwoJICAgIHBJblR5cGVzID0gKERNT19QQVJUSUFMX01FRElBVFlQRSopIHN6VmFsdWU7CgogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgVGhpcy0+Y0luVHlwZXM7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IGNJblR5cGVzOyBqKyspIAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChJc01lZGlhVHlwZUVxdWFsKCZwSW5UeXBlc1tqXSwgJlRoaXMtPnBJblR5cGVzW2ldKSkKCQkgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQoKCQlpZiAoaiA+PSBjSW5UeXBlcykKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGkgPCBUaGlzLT5jSW5UeXBlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKFRoaXMtPnBPdXRUeXBlcykKICAgICAgICB7CiAgICAgICAgICAgIFVJTlQgaSwgajsKICAgICAgICAgICAgRFdPUkQgY091dFR5cGVzOwogICAgICAgICAgICBETU9fUEFSVElBTF9NRURJQVRZUEUqIHBPdXRUeXBlczsKCgkgICAgbGVuID0gTUFYX1BBVEggKiBzaXplb2YoV0NIQVIpOwogICAgICAgICAgICBocmVzID0gUmVnUXVlcnlWYWx1ZUV4Vyhoa2V5LCBzekRNT091dHB1dFR5cGUsIE5VTEwsIE5VTEwsIChMUEJZVEUpIHN6VmFsdWUsICZsZW4pOwoJICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCgkgICAgY091dFR5cGVzID0gbGVuIC8gc2l6ZW9mKERNT19QQVJUSUFMX01FRElBVFlQRSk7CgkgICAgcE91dFR5cGVzID0gKERNT19QQVJUSUFMX01FRElBVFlQRSopIHN6VmFsdWU7CgogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgVGhpcy0+Y091dFR5cGVzOyBpKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCBjT3V0VHlwZXM7IGorKykgCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKElzTWVkaWFUeXBlRXF1YWwoJnBPdXRUeXBlc1tqXSwgJlRoaXMtPnBPdXRUeXBlc1tpXSkpCgkJICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KCgkJaWYgKGogPj0gY091dFR5cGVzKQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaSA8IFRoaXMtPmNPdXRUeXBlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCgkvKiBNZWRpYSBvYmplY3Qgd2Fzbid0IGZpbHRlcmVkIHNvIGFkZCBpdCB0byByZXR1cm4gbGlzdCAqLwogICAgICAgIE5hbWVzW2NvdW50XSA9IE5VTEw7CglsZW4gPSBNQVhfUEFUSCAqIHNpemVvZihXQ0hBUik7CiAgICAgICAgaHJlcyA9IFJlZ1F1ZXJ5VmFsdWVFeFcoaGtleSwgTlVMTCwgTlVMTCwgTlVMTCwgKExQQllURSkgc3pWYWx1ZSwgJmxlbik7IAogICAgICAgIGlmIChFUlJPUl9TVUNDRVNTID09IGhyZXMpCgl7CiAgICAgICAgICAgIE5hbWVzW2NvdW50XSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHJsZW5XKHN6VmFsdWUpICsgMSk7CgkgICAgaWYgKE5hbWVzW2NvdW50XSkKICAgICAgICAgICAgICAgIHN0cmNtcFcoTmFtZXNbY291bnRdLCBzelZhbHVlKTsKCX0KICAgICAgICBDTFNJREZyb21TdHJpbmcoc3pOZXh0S2V5LCAmcENMU0lEW2NvdW50XSk7CgogICAgICAgIFRSQUNFKCJmb3VuZCBtYXRjaCAlcyAlc1xuIiwgZGVidWdzdHJfdyhzelZhbHVlKSwgZGVidWdzdHJfdyhzek5leHRLZXkpKTsKICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKCWNvdW50Kys7CiAgICB9CgogICAgKnBjSXRlbXNGZXRjaGVkID0gY291bnQ7CiAgICBpZiAoKnBjSXRlbXNGZXRjaGVkIDwgY0l0ZW1zVG9GZXRjaCkKICAgICAgICBocmVzID0gU19GQUxTRTsKCiAgICByZXR1cm4gaHJlczsKfQogCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElFbnVtRE1PX2ZuU2tpcAogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFbnVtRE1PX2ZuU2tpcChJRW51bURNTyAqIGlmYWNlLCBEV09SRCBjSXRlbXNUb1NraXApCnsKICAgIElFbnVtRE1PSW1wbCAqVGhpcyA9IChJRW51bURNT0ltcGwgKilpZmFjZTsKCiAgICBUaGlzLT5pbmRleCArPSBjSXRlbXNUb1NraXA7CgogICAgcmV0dXJuIFNfT0s7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElFbnVtRE1PX2ZuUmVzZXQKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRW51bURNT19mblJlc2V0KElFbnVtRE1PICogaWZhY2UpCnsKICAgIElFbnVtRE1PSW1wbCAqVGhpcyA9IChJRW51bURNT0ltcGwgKilpZmFjZTsKCiAgICBUaGlzLT5pbmRleCA9IC0xOwoKICAgIHJldHVybiBTX09LOwp9CiAKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUVudW1ETU9fZm5DbG9uZQogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFbnVtRE1PX2ZuQ2xvbmUoSUVudW1ETU8gKiBpZmFjZSwgSUVudW1ETU8gKipwcEVudW0pCnsKICAgIElFbnVtRE1PSW1wbCAqVGhpcyA9IChJRW51bURNT0ltcGwgKilpZmFjZTsKCiAgICBGSVhNRSgiKCVwKS0+KCkgdG8gKCVwKS0+KCkgRV9OT1RJTVBMXG4iLCBUaGlzLCBwcEVudW0pOwoKICByZXR1cm4gRV9OT1RJTVBMOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBETU9FbnVtCiAqCiAqIEVudW1lcmF0ZSBEaXJlY3RYIE1lZGlhIE9iamVjdHMgaW4gdGhlIHJlZ2lzdHJ5LgogKi8KSFJFU1VMVCBXSU5BUEkgRE1PRW51bSgKICAgIFJFRkdVSUQgZ3VpZENhdGVnb3J5LAogICAgRFdPUkQgZHdGbGFncywKICAgIERXT1JEIGNJblR5cGVzLAogICAgY29uc3QgRE1PX1BBUlRJQUxfTUVESUFUWVBFICpwSW5UeXBlcywKICAgIERXT1JEIGNPdXRUeXBlcywKICAgIGNvbnN0IERNT19QQVJUSUFMX01FRElBVFlQRSAqcE91dFR5cGVzLAogICAgSUVudW1ETU8gKipwcEVudW0pCnsKICAgIEhSRVNVTFQgaHJlcyA9IEVfRkFJTDsKCiAgICBUUkFDRSgiZ3VpZENhdGVnb3J5PSVwIGR3RmxhZ3M9MHglMDhseCBjSW5UeXBlcz0lbGQgY091dFR5cGVzPSVsZFxuIiwKICAgICAgICBndWlkQ2F0ZWdvcnksIGR3RmxhZ3MsIGNJblR5cGVzLCBjT3V0VHlwZXMpOwoKICAgICpwcEVudW0gPSBJRW51bURNT19Db25zdHJ1Y3RvcihndWlkQ2F0ZWdvcnksIGR3RmxhZ3MsIGNJblR5cGVzLAogICAgICAgIHBJblR5cGVzLCBjT3V0VHlwZXMsIHBPdXRUeXBlcyk7CiAgICBpZiAoKnBwRW51bSkKICAgICAgICBocmVzID0gU19PSzsKCiAgICByZXR1cm4gaHJlczsKfQoKCnN0YXRpYyBjb25zdCBJRW51bURNT1Z0YmwgZWRtb3Z0ID0KewoJSUVudW1ETU9fZm5RdWVyeUludGVyZmFjZSwKCUlFbnVtRE1PX2ZuQWRkUmVmLAoJSUVudW1ETU9fZm5SZWxlYXNlLAoJSUVudW1ETU9fZm5OZXh0LAoJSUVudW1ETU9fZm5Ta2lwLAoJSUVudW1ETU9fZm5SZXNldCwKCUlFbnVtRE1PX2ZuQ2xvbmUsCn07CgoKSFJFU1VMVCBXSU5BUEkgRE1PR2V0VHlwZXMoUkVGQ0xTSUQgYSwgdW5zaWduZWQgbG9uZyBiLCB1bnNpZ25lZCBsb25nKiBjLAoJCQkgICBETU9fUEFSVElBTF9NRURJQVRZUEUqIGQsIHVuc2lnbmVkIGxvbmcgZSwKCQkJICAgdW5zaWduZWQgbG9uZyogZiwgRE1PX1BBUlRJQUxfTUVESUFUWVBFKiBnKQp7CiAgRklYTUUoIiglcCwlbHUsJXAsJXAsJWx1LCVwLCVwKSxzdHViIVxuIixhLGIsYyxkLGUsZixnKTsKCiAgcmV0dXJuIEVfTk9USU1QTDsKfQo=