LyoKICogQ29weXJpZ2h0IChDKSAyMDAzIE1pY2hhZWwgR/xubmV3aWcKICogQ29weXJpZ2h0IChDKSAyMDAzIENvZGVXZWF2ZXJzIEluYy4gKFVscmljaCBDemVrYWxsYSkKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqLwoKI2RlZmluZSBDT01fTk9fV0lORE9XU19ICiNpbmNsdWRlIDxzdGRhcmcuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgIm9iamJhc2UuaCIKI2luY2x1ZGUgImRtby5oIgoKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwobXNkbW8pOwoKCnN0YXRpYyBjb25zdCBXQ0hBUiBzekRNT1Jvb3RLZXlbXSA9IAp7CiAgICAnRCcsJ2knLCdyJywnZScsJ2MnLCd0JywnUycsJ2gnLCdvJywndycsJ1xcJywKICAgICdNJywnZScsJ2QnLCdpJywnYScsJ08nLCdiJywnaicsJ2UnLCdjJywndCcsJ3MnLDAKfTsgCgpzdGF0aWMgY29uc3QgV0NIQVIgc3pETU9JbnB1dFR5cGVbXSA9CnsKICAgICdJJywnbicsJ3AnLCd1JywndCcsJ1QnLCd5JywncCcsJ2UnLCdzJywwCn07CgpzdGF0aWMgY29uc3QgV0NIQVIgc3pETU9PdXRwdXRUeXBlW10gPQp7CiAgICAnTycsJ3UnLCd0JywncCcsJ3UnLCd0JywnVCcsJ3knLCdwJywnZScsJ3MnLDAKfTsKCnN0YXRpYyBjb25zdCBXQ0hBUiBzekRNT0tleWVkW10gPQp7CiAgICAnSycsJ2UnLCd5JywnZScsJ2QnLDAKfTsKCnN0YXRpYyBjb25zdCBXQ0hBUiBzekRNT0NhdGVnb3JpZXNbXSA9CnsKICAgICdDJywnYScsJ3QnLCdlJywnZycsJ28nLCdyJywnaScsJ2UnLCdzJywwCn07CgpzdGF0aWMgY29uc3QgV0NIQVIgc3pHVUlERm10W10gPQp7CiAgICAnJScsJzAnLCc4JywnWCcsJy0nLCclJywnMCcsJzQnLCdYJywnLScsJyUnLCcwJywnNCcsJ1gnLCctJywnJScsJzAnLAogICAgJzInLCdYJywnJScsJzAnLCcyJywnWCcsJy0nLCclJywnMCcsJzInLCdYJywnJScsJzAnLCcyJywnWCcsJyUnLCcwJywnMicsCiAgICAnWCcsJyUnLCcwJywnMicsJ1gnLCclJywnMCcsJzInLCdYJywnJScsJzAnLCcyJywnWCcsMAp9OwoKc3RhdGljIGNvbnN0IFdDSEFSIHN6Q2F0M0ZtdFtdID0KewogICAgJyUnLCdzJywnXFwnLCclJywncycsJ1xcJywnJScsJ3MnLDAKfTsKCnN0YXRpYyBjb25zdCBXQ0hBUiBzekNhdDJGbXRbXSA9CnsKICAgICclJywncycsJ1xcJywnJScsJ3MnLDAKfTsKCnR5cGVkZWYgc3RydWN0CnsKICAgIElDT01fVkZJRUxEKElFbnVtRE1PKTsKICAgIERXT1JECQkJcmVmOwogICAgRFdPUkQJCQlpbmRleDsKICAgIGNvbnN0IEdVSUQqICAgICAgICAgICAgICAgICBndWlkQ2F0ZWdvcnk7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgZHdGbGFnczsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICBjSW5UeXBlczsKICAgIERNT19QQVJUSUFMX01FRElBVFlQRSAgICAgICAqcEluVHlwZXM7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgY091dFR5cGVzOwogICAgRE1PX1BBUlRJQUxfTUVESUFUWVBFICAgICAgICpwT3V0VHlwZXM7CiAgICBIS0VZICAgICAgICAgICAgICAgICAgICAgICAgaGtleTsKfSBJRW51bURNT0ltcGw7Cgpjb25zdCBHVUlEIElJRF9JRW51bURNTyA9IHsgMHgyYzNjZDk4YSwgMHgyYmZhLCAweDRhNTMsCiAgICB7IDB4OWMsIDB4MjcsIDB4NTIsIDB4NDksIDB4YmEsIDB4NjQsIDB4YmEsIDB4MGZ9fTsKCnN0YXRpYyBzdHJ1Y3QgSUNPTV9WVEFCTEUoSUVudW1ETU8pIGVkbW92dDsKCnN0YXRpYyBMUFdTVFIgR1VJRFRvU3RyaW5nKExQV1NUUiBscHdzdHIsIFJFRkdVSUQgbHBjZ3VpZCkKewogICAgd3NwcmludGZXKGxwd3N0ciwgc3pHVUlERm10LCBscGNndWlkLT5EYXRhMSwgbHBjZ3VpZC0+RGF0YTIsCiAgICAgICAgbHBjZ3VpZC0+RGF0YTMsIGxwY2d1aWQtPkRhdGE0WzBdLCBscGNndWlkLT5EYXRhNFsxXSwKICAgICAgICBscGNndWlkLT5EYXRhNFsyXSwgbHBjZ3VpZC0+RGF0YTRbM10sIGxwY2d1aWQtPkRhdGE0WzRdLAogICAgICAgIGxwY2d1aWQtPkRhdGE0WzVdLCBscGNndWlkLT5EYXRhNFs2XSwgbHBjZ3VpZC0+RGF0YTRbN10pOwoKICAgIHJldHVybiBscHdzdHI7Cn0KCnN0YXRpYyBCT09MIElzTWVkaWFUeXBlRXF1YWwoRE1PX1BBUlRJQUxfTUVESUFUWVBFKiBtdDEsIERNT19QQVJUSUFMX01FRElBVFlQRSogbXQyKQp7CgogICAgcmV0dXJuIChJc0VxdWFsQ0xTSUQoJm10MS0+dHlwZSwgJm10Mi0+dHlwZSkgfHwKICAgICAgICAgICAgSXNFcXVhbENMU0lEKCZtdDItPnR5cGUsICZHVUlEX05VTEwpIHx8CiAgICAgICAgICAgIElzRXF1YWxDTFNJRCgmbXQxLT50eXBlLCAmR1VJRF9OVUxMKSkgJiYKICAgICAgICAgICAgKElzRXF1YWxDTFNJRCgmbXQxLT5zdWJ0eXBlLCAmbXQyLT5zdWJ0eXBlKSB8fAogICAgICAgICAgICBJc0VxdWFsQ0xTSUQoJm10Mi0+c3VidHlwZSwgJkdVSURfTlVMTCkgfHwKICAgICAgICAgICAgSXNFcXVhbENMU0lEKCZtdDEtPnN1YnR5cGUsICZHVUlEX05VTEwpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBETU9SZWdpc3RlcgogKgogKiBSZWdpc3RlciBhIERpcmVjdFggTWVkaWEgT2JqZWN0LgogKi8KSFJFU1VMVCBXSU5BUEkgRE1PUmVnaXN0ZXIoCiAgIExQQ1dTVFIgc3pOYW1lLAogICBSRUZDTFNJRCBjbHNpZERNTywKICAgUkVGR1VJRCBndWlkQ2F0ZWdvcnksCiAgIERXT1JEIGR3RmxhZ3MsCiAgIERXT1JEIGNJblR5cGVzLAogICBjb25zdCBETU9fUEFSVElBTF9NRURJQVRZUEUgKnBJblR5cGVzLAogICBEV09SRCBjT3V0VHlwZXMsCiAgIGNvbnN0IERNT19QQVJUSUFMX01FRElBVFlQRSAqcE91dFR5cGVzCikKewogICAgV0NIQVIgc3pndWlkWzY0XTsKICAgIEhSRVNVTFQgaHJlczsKICAgIEhLRVkgaHJrZXkgPSAwOwogICAgSEtFWSBoa2V5ID0gMDsKICAgIEhLRVkgaGNrZXkgPSAwOwogICAgSEtFWSBoY2xza2V5ID0gMDsKCiAgICBUUkFDRSgiJXNcbiIsIGRlYnVnc3RyX3coc3pOYW1lKSk7CgogICAgaHJlcyA9IFJlZ09wZW5LZXlFeFcoSEtFWV9DTEFTU0VTX1JPT1QsIHN6RE1PUm9vdEtleSwgMCwgS0VZX1dSSVRFLCAmaHJrZXkpOwogICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICBnb3RvIGxlbmQ7CgogICAgLyogQ3JlYXRlIGNsc2lkRE1PIGtleSB1bmRlciBNZWRpYU9iamVjdHMgKi8gCiAgICBocmVzID0gUmVnQ3JlYXRlS2V5RXhXKGhya2V5LCBHVUlEVG9TdHJpbmcoc3pndWlkLCBjbHNpZERNTyksIDAsIE5VTEwsCiAgICAgICAgUkVHX09QVElPTl9OT05fVk9MQVRJTEUsIEtFWV9XUklURSwgTlVMTCwgJmhrZXksIE5VTEwpOwogICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICBnb3RvIGxlbmQ7CgogICAgLyogU2V0IGRlZmF1bHQgTmFtZSB2YWx1ZSAqLwogICAgaHJlcyA9IFJlZ1NldFZhbHVlRXhXKGhrZXksIE5VTEwsIDAsIFJFR19TWiwgKExQQllURSkgc3pOYW1lLCAKICAgICAgICAoc3RybGVuVyhzek5hbWUpICsgMSkpICogc2l6ZW9mKFdDSEFSKTsKICAgIC8qIFNldCBJbnB1dFR5cGVzICovCiAgICBocmVzID0gUmVnU2V0VmFsdWVFeFcoaGtleSwgc3pETU9JbnB1dFR5cGUsIDAsIFJFR19CSU5BUlksIAogICAgICAgIChMUEJZVEUpIHBJblR5cGVzLCBjSW5UeXBlcyAqIHNpemVvZihETU9fUEFSVElBTF9NRURJQVRZUEUpKTsKICAgIC8qIFNldCBPdXRwdXRUeXBlcyAqLwogICAgaHJlcyA9IFJlZ1NldFZhbHVlRXhXKGhrZXksIHN6RE1PT3V0cHV0VHlwZSwgMCwgUkVHX0JJTkFSWSwgCiAgICAgICAgKExQQllURSkgcE91dFR5cGVzLCBjT3V0VHlwZXMgKiBzaXplb2YoRE1PX1BBUlRJQUxfTUVESUFUWVBFKSk7CgogICAgaWYgKGR3RmxhZ3MgJiBETU9fUkVHSVNURVJGX0lTX0tFWUVEKQogICAgewogICAgICAgIC8qIENyZWF0ZSBLZXllZCBrZXkgKi8gCiAgICAgICAgaHJlcyA9IFJlZ0NyZWF0ZUtleUV4Vyhoa2V5LCBzekRNT0tleWVkLCAwLCBOVUxMLAogICAgICAgICAgICBSRUdfT1BUSU9OX05PTl9WT0xBVElMRSwgS0VZX1dSSVRFLCBOVUxMLCAmaGNrZXksIE5VTEwpOwogICAgICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgICAgIGdvdG8gbGVuZDsKICAgICAgICBSZWdDbG9zZUtleShoY2tleSk7CiAgICB9CgogICAgLyogUmVnaXN0ZXIgdGhlIGNhdGVnb3J5ICovCiAgICBocmVzID0gUmVnT3BlbktleUV4VyhocmtleSwgc3pETU9DYXRlZ29yaWVzLCAwLCBLRVlfV1JJVEUsICZoY2tleSk7CiAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgIGdvdG8gbGVuZDsKCiAgICBSZWdDbG9zZUtleShoa2V5KTsKCiAgICBocmVzID0gUmVnT3BlbktleUV4VyhoY2tleSwgR1VJRFRvU3RyaW5nKHN6Z3VpZCwgZ3VpZENhdGVnb3J5KSwgMCwgS0VZX1dSSVRFLCAmaGtleSk7CiAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgIGdvdG8gbGVuZDsKICAgIGhyZXMgPSBSZWdDcmVhdGVLZXlFeFcoaGtleSwgR1VJRFRvU3RyaW5nKHN6Z3VpZCwgY2xzaWRETU8pLCAwLCBOVUxMLAogICAgICAgIFJFR19PUFRJT05fTk9OX1ZPTEFUSUxFLCBLRVlfV1JJVEUsIE5VTEwsICZoY2xza2V5LCBOVUxMKTsKICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgZ290byBsZW5kOwoKbGVuZDoKICAgIGlmIChoa2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgaWYgKGhja2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhja2V5KTsKICAgIGlmIChoY2xza2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhjbHNrZXkpOwogICAgaWYgKGhya2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhya2V5KTsKCiAgICBUUkFDRSgiIGhyZXN1bHQ9MHglMDhseFxuIiwgaHJlcyk7CiAgICByZXR1cm4gaHJlczsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRE1PVW5yZWdpc3RlcgogKgogKiBVbnJlZ2lzdGVyIGEgRGlyZWN0WCBNZWRpYSBPYmplY3QuCiAqLwpIUkVTVUxUIFdJTkFQSSBETU9VbnJlZ2lzdGVyKFJFRkNMU0lEIGNsc2lkRE1PLCBSRUZHVUlEIGd1aWRDYXRlZ29yeSkKewogICAgSFJFU1VMVCBocmVzOwogICAgV0NIQVIgc3pndWlkWzY0XTsKICAgIEhLRVkgaHJrZXkgPSAwOwogICAgSEtFWSBoY2tleSA9IDA7CgogICAgR1VJRFRvU3RyaW5nKHN6Z3VpZCwgY2xzaWRETU8pOwoKICAgIFRSQUNFKCIlcyAlcFxuIiwgZGVidWdzdHJfdyhzemd1aWQpLCBndWlkQ2F0ZWdvcnkpOwoKICAgIGhyZXMgPSBSZWdPcGVuS2V5RXhXKEhLRVlfQ0xBU1NFU19ST09ULCBzekRNT1Jvb3RLZXksIDAsIEtFWV9XUklURSwgJmhya2V5KTsKICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgZ290byBsZW5kOwoKICAgIGhyZXMgPSBSZWdEZWxldGVLZXlXKGhya2V5LCBzemd1aWQpOwogICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICBnb3RvIGxlbmQ7CgogICAgaHJlcyA9IFJlZ09wZW5LZXlFeFcoaHJrZXksIHN6RE1PQ2F0ZWdvcmllcywgMCwgS0VZX1dSSVRFLCAmaGNrZXkpOwogICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICBnb3RvIGxlbmQ7CgogICAgaHJlcyA9IFJlZ0RlbGV0ZUtleVcoaGNrZXksIHN6Z3VpZCk7CiAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgIGdvdG8gbGVuZDsKCmxlbmQ6CiAgICBpZiAoaGNrZXkpCiAgICAgICAgUmVnQ2xvc2VLZXkoaGNrZXkpOwogICAgaWYgKGhya2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhya2V5KTsKCiAgICByZXR1cm4gaHJlczsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRE1PR2V0TmFtZQogKgogKiBHZXQgRE1QIE5hbWUgZnJvbSB0aGUgcmVnaXN0cnkKICovCkhSRVNVTFQgV0lOQVBJIERNT0dldE5hbWUoUkVGQ0xTSUQgY2xzaWRETU8sIFdDSEFSKiBzek5hbWUpCnsKICAgIFdDSEFSIHN6Z3VpZFs2NF07CiAgICBIUkVTVUxUIGhyZXM7CiAgICBIS0VZIGhya2V5ID0gMDsKICAgIEhLRVkgaGtleSA9IDA7CiAgICBEV09SRCBjb3VudDsKCiAgICBUUkFDRSgiJXNcbiIsIGRlYnVnc3RyX2d1aWQoY2xzaWRETU8pKTsKCiAgICBocmVzID0gUmVnT3BlbktleUV4VyhIS0VZX0NMQVNTRVNfUk9PVCwgc3pETU9Sb290S2V5LCAKICAgICAgICAwLCBLRVlfUkVBRCwgJmhya2V5KTsKICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgZ290byBsZW5kOwoKICAgIGhyZXMgPSBSZWdPcGVuS2V5RXhXKGhya2V5LCBHVUlEVG9TdHJpbmcoc3pndWlkLCBjbHNpZERNTyksCiAgICAgICAgMCwgS0VZX1JFQUQsICZoa2V5KTsKICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgZ290byBsZW5kOwoKICAgIGNvdW50ID0gODAgKiBzaXplb2YoV0NIQVIpOyAvKiA4MCBieSBBUEkgZGVmaW5pdGlvbiAqLwogICAgaHJlcyA9IFJlZ1F1ZXJ5VmFsdWVFeFcoaGtleSwgTlVMTCwgTlVMTCwgTlVMTCwgCiAgICAgICAgKExQQllURSkgc3pOYW1lLCAmY291bnQpOyAKCiAgICBUUkFDRSgiIHN6TmFtZT0lc1xuIiwgZGVidWdzdHJfdyhzek5hbWUpKTsKbGVuZDoKICAgIGlmIChoa2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhya2V5KTsKICAgIGlmIChoa2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwoKICAgIHJldHVybiBocmVzOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogICBJRW51bURNT19EZXN0cnVjdG9yCiovCnN0YXRpYyBCT09MIElFbnVtRE1PX0Rlc3RydWN0b3IoSUVudW1ETU8qIGlmYWNlKQp7CiAgICBJQ09NX1RISVMoSUVudW1ETU9JbXBsLGlmYWNlKTsKCiAgICBUUkFDRSgiJXBcbiIsIFRoaXMpOwoKICAgIGlmIChUaGlzLT5oa2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KFRoaXMtPmhrZXkpOwoKICAgIGlmIChUaGlzLT5wSW5UeXBlcykKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5wSW5UeXBlcyk7CgogICAgaWYgKFRoaXMtPnBPdXRUeXBlcykKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5wT3V0VHlwZXMpOwoKICAgIHJldHVybiBUUlVFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBJRW51bURNT19Db25zdHJ1Y3RvcgogKi8KSUVudW1ETU8gKiBJRW51bURNT19Db25zdHJ1Y3RvcigKICAgIFJFRkdVSUQgZ3VpZENhdGVnb3J5LAogICAgRFdPUkQgZHdGbGFncywKICAgIERXT1JEIGNJblR5cGVzLAogICAgY29uc3QgRE1PX1BBUlRJQUxfTUVESUFUWVBFICpwSW5UeXBlcywKICAgIERXT1JEIGNPdXRUeXBlcywKICAgIGNvbnN0IERNT19QQVJUSUFMX01FRElBVFlQRSAqcE91dFR5cGVzKQp7CiAgICBVSU5UIHNpemU7CiAgICBJRW51bURNT0ltcGwqIGxwZWRtbzsKICAgIEJPT0wgcmV0ID0gRkFMU0U7CgogICAgbHBlZG1vID0gKElFbnVtRE1PSW1wbCopSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIAogICAgICAgIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJRW51bURNT0ltcGwpKTsKCiAgICBpZiAobHBlZG1vKQogICAgewogICAgICAgIGxwZWRtby0+cmVmID0gMTsKICAgICAgICBscGVkbW8tPmxwVnRibCA9ICZlZG1vdnQ7CiAgICAgICAgbHBlZG1vLT5pbmRleCA9IC0xOwoJbHBlZG1vLT5ndWlkQ2F0ZWdvcnkgPSBndWlkQ2F0ZWdvcnk7CglscGVkbW8tPmR3RmxhZ3MgPSBkd0ZsYWdzOwoKCXNpemUgPSBjSW5UeXBlcyAqIHNpemVvZihETU9fUEFSVElBTF9NRURJQVRZUEUpOwogICAgICAgIGxwZWRtby0+cEluVHlwZXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZSk7CiAgICAgICAgaWYgKCFscGVkbW8tPnBJblR5cGVzKQogICAgICAgICAgICBnb3RvIGxlcnI7CgltZW1jcHkobHBlZG1vLT5wSW5UeXBlcywgcEluVHlwZXMsIHNpemUpOwogICAgICAgIGxwZWRtby0+Y0luVHlwZXMgPSBjSW5UeXBlczsKCglzaXplID0gY091dFR5cGVzICogc2l6ZW9mKERNT19QQVJUSUFMX01FRElBVFlQRSk7CiAgICAgICAgbHBlZG1vLT5wT3V0VHlwZXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZSk7CiAgICAgICAgaWYgKCFscGVkbW8tPnBPdXRUeXBlcykKICAgICAgICAgICAgZ290byBsZXJyOwoJbWVtY3B5KGxwZWRtby0+cE91dFR5cGVzLCBwT3V0VHlwZXMsIHNpemUpOwogICAgICAgIGxwZWRtby0+Y091dFR5cGVzID0gY091dFR5cGVzOwoKICAgICAgICAvKiBJZiBub3QgZmlsdGVyaW5nIGJ5IGNhdGVnb3J5IGVudW0gZnJvbSBtZWRpYSBvYmplY3RzIHJvb3QgKi8KICAgICAgICBpZiAoSXNFcXVhbEdVSUQoZ3VpZENhdGVnb3J5LCAmR1VJRF9OVUxMKSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChFUlJPUl9TVUNDRVNTID09IFJlZ09wZW5LZXlFeFcoSEtFWV9DTEFTU0VTX1JPT1QsIHN6RE1PUm9vdEtleSwgCiAgICAgICAgICAgICAgICAwLCBLRVlfUkVBRCwgJmxwZWRtby0+aGtleSkpCiAgICAgICAgICAgICAgICByZXQgPSBUUlVFOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBXQ0hBUiBzemd1aWRbNjRdOwogICAgICAgICAgICBXQ0hBUiBzektleVtNQVhfUEFUSF07CgogICAgICAgICAgICB3c3ByaW50Zlcoc3pLZXksIHN6Q2F0M0ZtdCwgc3pETU9Sb290S2V5LCBzekRNT0NhdGVnb3JpZXMsIAogICAgICAgICAgICAgICAgR1VJRFRvU3RyaW5nKHN6Z3VpZCwgZ3VpZENhdGVnb3J5KSk7CiAgICAgICAgICAgIGlmIChFUlJPUl9TVUNDRVNTID09IFJlZ09wZW5LZXlFeFcoSEtFWV9DTEFTU0VTX1JPT1QsIHN6S2V5LCAKICAgICAgICAgICAgICAgIDAsIEtFWV9SRUFELCAmbHBlZG1vLT5oa2V5KSkKICAgICAgICAgICAgICAgIHJldCA9IFRSVUU7CiAgICAgICAgfQoKbGVycjoKICAgICAgICBpZighcmV0KQogICAgICAgIHsKICAgICAgICAgICAgSUVudW1ETU9fRGVzdHJ1Y3RvcigoSUVudW1ETU8qKWxwZWRtbyk7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxscGVkbW8pOwogICAgICAgICAgICBscGVkbW8gPSBOVUxMOwogICAgICAgIH0KICAgIH0KCiAgICBUUkFDRSgicmV0dXJuaW5nICVwXG4iLCBscGVkbW8pOwoKICAgIHJldHVybiAoSUVudW1ETU8qKWxwZWRtbzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUVudW1ETU9fZm5BZGRSZWYKICovCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUVudW1ETU9fZm5BZGRSZWYoSUVudW1ETU8gKiBpZmFjZSkKewogICAgSUNPTV9USElTKElFbnVtRE1PSW1wbCxpZmFjZSk7CiAgICByZXR1cm4gKysoVGhpcy0+cmVmKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgRW51bURNT19RdWVyeUludGVyZmFjZQogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFbnVtRE1PX2ZuUXVlcnlJbnRlcmZhY2UoCiAgICBJRW51bURNTyogaWZhY2UsCiAgICBSRUZJSUQgcmlpZCwKICAgIExQVk9JRCAqcHB2T2JqKQp7CiAgICBJQ09NX1RISVMoSUVudW1ETU9JbXBsLGlmYWNlKTsKCiAgICAqcHB2T2JqID0gTlVMTDsKCiAgICBpZihJc0VxdWFsSUlEKHJpaWQsICZJSURfSVVua25vd24pKQogICAgICAgICpwcHZPYmogPSBUaGlzOwogICAgZWxzZSBpZihJc0VxdWFsSUlEKHJpaWQsICZJSURfSUVudW1ETU8pKQogICAgICAgICpwcHZPYmogPSAoSUVudW1ETU8qKVRoaXM7CgogICAgaWYoKnBwdk9iaikKICAgIHsKICAgICAgICBJRW51bURNT19mbkFkZFJlZigoSUVudW1ETU8qKSpwcHZPYmopOwogICAgICAgIHJldHVybiBTX09LOwogICAgfQoKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRW51bURNT19mblJlbGVhc2UKICovCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUVudW1ETU9fZm5SZWxlYXNlKElFbnVtRE1PICogaWZhY2UpCnsKICAgIElDT01fVEhJUyhJRW51bURNT0ltcGwsaWZhY2UpOwoKICAgIGlmICghLS0oVGhpcy0+cmVmKSkKICAgIHsKICAgICAgICBJRW51bURNT19EZXN0cnVjdG9yKChJRW51bURNTyopVGhpcyk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHJldHVybiBUaGlzLT5yZWY7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElFbnVtRE1PX2ZuTmV4dAogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFbnVtRE1PX2ZuTmV4dCgKICAgIElFbnVtRE1PICogaWZhY2UsIAogICAgRFdPUkQgY0l0ZW1zVG9GZXRjaCwKICAgIENMU0lEICogcENMU0lELAogICAgV0NIQVIgKiogTmFtZXMsCiAgICBEV09SRCAqIHBjSXRlbXNGZXRjaGVkKQp7CiAgICBGSUxFVElNRSBmdDsKICAgIEhLRVkgaGtleTsKICAgIFdDSEFSIHN6TmV4dEtleVtNQVhfUEFUSF07CiAgICBXQ0hBUiBzektleVtNQVhfUEFUSF07CiAgICBXQ0hBUiBzelZhbHVlW01BWF9QQVRIXTsKICAgIERXT1JEIGxlbjsKICAgIFVJTlQgY291bnQgPSAwOwogICAgSFJFU1VMVCBocmVzID0gU19PSzsKCiAgICBJQ09NX1RISVMoSUVudW1ETU9JbXBsLGlmYWNlKTsKCiAgICBUUkFDRSgiJWxkXG4iLCBjSXRlbXNUb0ZldGNoKTsKCiAgICBpZiAoIXBDTFNJRCB8fCAhTmFtZXMgfHwgIXBjSXRlbXNGZXRjaGVkKQogICAgICAgIHJldHVybiBFX1BPSU5URVI7CgogICAgd2hpbGUgKGNvdW50IDwgKElOVCljSXRlbXNUb0ZldGNoKQogICAgewogICAgICAgIFRoaXMtPmluZGV4Kys7CgogICAgICAgIGhyZXMgPSBSZWdFbnVtS2V5RXhXKFRoaXMtPmhrZXksIFRoaXMtPmluZGV4LCBzek5leHRLZXksICZsZW4sIE5VTEwsIE5VTEwsIE5VTEwsICZmdCk7CiAgICAgICAgaWYgKGhyZXMgIT0gRVJST1JfU1VDQ0VTUykKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIFRSQUNFKCJmb3VuZCAlc1xuIiwgZGVidWdzdHJfdyhzek5leHRLZXkpKTsKCglpZiAoVGhpcy0+ZHdGbGFncyAmIERNT19SRUdJU1RFUkZfSVNfS0VZRUQpCiAgICAgICAgewogICAgICAgICAgICB3c3ByaW50Zlcoc3pLZXksIHN6Q2F0M0ZtdCwgc3pETU9Sb290S2V5LCBzek5leHRLZXksIHN6RE1PS2V5ZWQpOwogICAgICAgICAgICBocmVzID0gUmVnT3BlbktleUV4VyhIS0VZX0NMQVNTRVNfUk9PVCwgc3pLZXksIDAsIEtFWV9SRUFELCAmaGtleSk7CiAgICAgICAgICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICAgICAgfQoKICAgICAgICB3c3ByaW50Zlcoc3pLZXksIHN6Q2F0MkZtdCwgc3pETU9Sb290S2V5LCBzek5leHRLZXkpOwogICAgICAgIGhyZXMgPSBSZWdPcGVuS2V5RXhXKEhLRVlfQ0xBU1NFU19ST09ULCBzektleSwgMCwgS0VZX1JFQUQsICZoa2V5KTsKCiAgICAgICAgaWYgKFRoaXMtPnBJblR5cGVzKQogICAgICAgIHsKICAgICAgICAgICAgSU5UIGksIGo7CiAgICAgICAgICAgIERXT1JEIGNJblR5cGVzOwogICAgICAgICAgICBETU9fUEFSVElBTF9NRURJQVRZUEUqIHBJblR5cGVzOwoKCSAgICBsZW4gPSBNQVhfUEFUSCAqIHNpemVvZihXQ0hBUik7CiAgICAgICAgICAgIGhyZXMgPSBSZWdRdWVyeVZhbHVlRXhXKGhrZXksIHN6RE1PSW5wdXRUeXBlLCBOVUxMLCBOVUxMLCAoTFBCWVRFKSBzelZhbHVlLCAmbGVuKTsKCSAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgoJICAgIGNJblR5cGVzID0gbGVuIC8gc2l6ZW9mKERNT19QQVJUSUFMX01FRElBVFlQRSk7CgkgICAgcEluVHlwZXMgPSAoRE1PX1BBUlRJQUxfTUVESUFUWVBFKikgc3pWYWx1ZTsKCiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5jSW5UeXBlczsgaSsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgY0luVHlwZXM7IGorKykgCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKElzTWVkaWFUeXBlRXF1YWwoJnBJblR5cGVzW2pdLCAmVGhpcy0+cEluVHlwZXNbaV0pKQoJCSAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CgoJCWlmIChqID49IGNJblR5cGVzKQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaSA8IFRoaXMtPmNJblR5cGVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoVGhpcy0+cE91dFR5cGVzKQogICAgICAgIHsKICAgICAgICAgICAgSU5UIGksIGo7CiAgICAgICAgICAgIERXT1JEIGNPdXRUeXBlczsKICAgICAgICAgICAgRE1PX1BBUlRJQUxfTUVESUFUWVBFKiBwT3V0VHlwZXM7CgoJICAgIGxlbiA9IE1BWF9QQVRIICogc2l6ZW9mKFdDSEFSKTsKICAgICAgICAgICAgaHJlcyA9IFJlZ1F1ZXJ5VmFsdWVFeFcoaGtleSwgc3pETU9PdXRwdXRUeXBlLCBOVUxMLCBOVUxMLCAoTFBCWVRFKSBzelZhbHVlLCAmbGVuKTsKCSAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgoJICAgIGNPdXRUeXBlcyA9IGxlbiAvIHNpemVvZihETU9fUEFSVElBTF9NRURJQVRZUEUpOwoJICAgIHBPdXRUeXBlcyA9IChETU9fUEFSVElBTF9NRURJQVRZUEUqKSBzelZhbHVlOwoKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IFRoaXMtPmNPdXRUeXBlczsgaSsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgY091dFR5cGVzOyBqKyspIAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChJc01lZGlhVHlwZUVxdWFsKCZwT3V0VHlwZXNbal0sICZUaGlzLT5wT3V0VHlwZXNbaV0pKQoJCSAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CgoJCWlmIChqID49IGNPdXRUeXBlcykKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGkgPCBUaGlzLT5jT3V0VHlwZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgoJLyogTWVkaWEgb2JqZWN0IHdhc24ndCBmaWx0ZXJlZCBzbyBhZGQgaXQgdG8gcmV0dXJuIGxpc3QgKi8KICAgICAgICBOYW1lc1tjb3VudF0gPSBOVUxMOwoJbGVuID0gTUFYX1BBVEggKiBzaXplb2YoV0NIQVIpOwogICAgICAgIGhyZXMgPSBSZWdRdWVyeVZhbHVlRXhXKGhrZXksIE5VTEwsIE5VTEwsIE5VTEwsIChMUEJZVEUpIHN6VmFsdWUsICZsZW4pOyAKICAgICAgICBpZiAoRVJST1JfU1VDQ0VTUyA9PSBocmVzKQoJewogICAgICAgICAgICBOYW1lc1tjb3VudF0gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RybGVuVyhzelZhbHVlKSArIDEpOwoJICAgIGlmIChOYW1lc1tjb3VudF0pCiAgICAgICAgICAgICAgICBzdHJjbXBXKE5hbWVzW2NvdW50XSwgc3pWYWx1ZSk7Cgl9CiAgICAgICAgQ0xTSURGcm9tU3RyaW5nKHN6TmV4dEtleSwgJnBDTFNJRFtjb3VudF0pOwoKICAgICAgICBUUkFDRSgiZm91bmQgbWF0Y2ggJXMgJXNcbiIsIGRlYnVnc3RyX3coc3pWYWx1ZSksIGRlYnVnc3RyX3coc3pOZXh0S2V5KSk7CiAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7Cgljb3VudCsrOwogICAgfQoKICAgICpwY0l0ZW1zRmV0Y2hlZCA9IGNvdW50OwogICAgaWYgKCpwY0l0ZW1zRmV0Y2hlZCA8IGNJdGVtc1RvRmV0Y2gpCiAgICAgICAgaHJlcyA9IFNfRkFMU0U7CgogICAgcmV0dXJuIGhyZXM7Cn0KIAoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRW51bURNT19mblNraXAKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRW51bURNT19mblNraXAoSUVudW1ETU8gKiBpZmFjZSwgRFdPUkQgY0l0ZW1zVG9Ta2lwKQp7CiAgICBJQ09NX1RISVMoSUVudW1ETU9JbXBsLGlmYWNlKTsKCiAgICBUaGlzLT5pbmRleCArPSBjSXRlbXNUb1NraXA7CgogICAgcmV0dXJuIFNfT0s7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElFbnVtRE1PX2ZuUmVzZXQKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRW51bURNT19mblJlc2V0KElFbnVtRE1PICogaWZhY2UpCnsKICAgIElDT01fVEhJUyhJRW51bURNT0ltcGwsaWZhY2UpOwoKICAgIFRoaXMtPmluZGV4ID0gLTE7CgogICAgcmV0dXJuIFNfT0s7Cn0KIAoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRW51bURNT19mbkNsb25lCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVudW1ETU9fZm5DbG9uZShJRW51bURNTyAqIGlmYWNlLCBJRW51bURNTyAqKnBwRW51bSkKewogICAgSUNPTV9USElTKElFbnVtRE1PSW1wbCxpZmFjZSk7CgogICAgRklYTUUoIiglcCktPigpIHRvICglcCktPigpIEVfTk9USU1QTFxuIiwgVGhpcywgcHBFbnVtKTsKCiAgcmV0dXJuIEVfTk9USU1QTDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRE1PRW51bQogKgogKiBFbnVtZXJhdGUgRGlyZWN0WCBNZWRpYSBPYmplY3RzIGluIHRoZSByZWdpc3RyeS4KICovCkhSRVNVTFQgV0lOQVBJIERNT0VudW0oCiAgICBSRUZHVUlEIGd1aWRDYXRlZ29yeSwKICAgIERXT1JEIGR3RmxhZ3MsCiAgICBEV09SRCBjSW5UeXBlcywKICAgIGNvbnN0IERNT19QQVJUSUFMX01FRElBVFlQRSAqcEluVHlwZXMsCiAgICBEV09SRCBjT3V0VHlwZXMsCiAgICBjb25zdCBETU9fUEFSVElBTF9NRURJQVRZUEUgKnBPdXRUeXBlcywKICAgIElFbnVtRE1PICoqcHBFbnVtKQp7CiAgICBIUkVTVUxUIGhyZXMgPSBFX0ZBSUw7CgogICAgVFJBQ0UoImd1aWRDYXRlZ29yeT0lcCBkd0ZsYWdzPTB4JTA4bHggY0luVHlwZXM9JWxkIGNPdXRUeXBlcz0lbGRcbiIsCiAgICAgICAgZ3VpZENhdGVnb3J5LCBkd0ZsYWdzLCBjSW5UeXBlcywgY091dFR5cGVzKTsKCiAgICAqcHBFbnVtID0gSUVudW1ETU9fQ29uc3RydWN0b3IoZ3VpZENhdGVnb3J5LCBkd0ZsYWdzLCBjSW5UeXBlcywKICAgICAgICBwSW5UeXBlcywgY091dFR5cGVzLCBwT3V0VHlwZXMpOwogICAgaWYgKCpwcEVudW0pCiAgICAgICAgaHJlcyA9IFNfT0s7CgogICAgcmV0dXJuIGhyZXM7Cn0KCgpzdGF0aWMgSUNPTV9WVEFCTEUgKElFbnVtRE1PKSBlZG1vdnQgPQp7CglJQ09NX01TVlRBQkxFX0NPTVBBVF9EdW1teVJUVElWQUxVRQoJSUVudW1ETU9fZm5RdWVyeUludGVyZmFjZSwKCUlFbnVtRE1PX2ZuQWRkUmVmLAoJSUVudW1ETU9fZm5SZWxlYXNlLAoJSUVudW1ETU9fZm5OZXh0LAoJSUVudW1ETU9fZm5Ta2lwLAoJSUVudW1ETU9fZm5SZXNldCwKCUlFbnVtRE1PX2ZuQ2xvbmUsCn07CgoKSFJFU1VMVCBXSU5BUEkgRE1PR2V0VHlwZXMoUkVGQ0xTSUQgYSwgdW5zaWduZWQgbG9uZyBiLCB1bnNpZ25lZCBsb25nKiBjLAoJCQkgICBETU9fUEFSVElBTF9NRURJQVRZUEUqIGQsIHVuc2lnbmVkIGxvbmcgZSwKCQkJICAgdW5zaWduZWQgbG9uZyogZiwgRE1PX1BBUlRJQUxfTUVESUFUWVBFKiBnKQp7CiAgRklYTUUoIiglcCwlbHUsJXAsJXAsJWx1LCVwLCVwKSxzdHViIVxuIixhLGIsYyxkLGUsZixnKTsKCiAgcmV0dXJuIEVfTk9USU1QTDsKfQo=