LyoKICogQ29weXJpZ2h0IChDKSAyMDAzIE1pY2hhZWwgR/xubmV3aWcKICogQ29weXJpZ2h0IChDKSAyMDAzIENvZGVXZWF2ZXJzIEluYy4gKFVscmljaCBDemVrYWxsYSkKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqLwoKI2RlZmluZSBDT01fTk9fV0lORE9XU19ICiNpbmNsdWRlIDxzdGRhcmcuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgIm9iamJhc2UuaCIKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAiaW5pdGd1aWQuaCIKI2luY2x1ZGUgImRtby5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwobXNkbW8pOwoKCnN0YXRpYyBjb25zdCBXQ0hBUiBzekRNT1Jvb3RLZXlbXSA9IAp7CiAgICAnRCcsJ2knLCdyJywnZScsJ2MnLCd0JywnUycsJ2gnLCdvJywndycsJ1xcJywKICAgICdNJywnZScsJ2QnLCdpJywnYScsJ08nLCdiJywnaicsJ2UnLCdjJywndCcsJ3MnLDAKfTsgCgpzdGF0aWMgY29uc3QgV0NIQVIgc3pETU9JbnB1dFR5cGVbXSA9CnsKICAgICdJJywnbicsJ3AnLCd1JywndCcsJ1QnLCd5JywncCcsJ2UnLCdzJywwCn07CgpzdGF0aWMgY29uc3QgV0NIQVIgc3pETU9PdXRwdXRUeXBlW10gPQp7CiAgICAnTycsJ3UnLCd0JywncCcsJ3UnLCd0JywnVCcsJ3knLCdwJywnZScsJ3MnLDAKfTsKCnN0YXRpYyBjb25zdCBXQ0hBUiBzekRNT0tleWVkW10gPQp7CiAgICAnSycsJ2UnLCd5JywnZScsJ2QnLDAKfTsKCnN0YXRpYyBjb25zdCBXQ0hBUiBzekRNT0NhdGVnb3JpZXNbXSA9CnsKICAgICdDJywnYScsJ3QnLCdlJywnZycsJ28nLCdyJywnaScsJ2UnLCdzJywwCn07CgpzdGF0aWMgY29uc3QgV0NIQVIgc3pHVUlERm10W10gPQp7CiAgICAnJScsJzAnLCc4JywnWCcsJy0nLCclJywnMCcsJzQnLCdYJywnLScsJyUnLCcwJywnNCcsJ1gnLCctJywnJScsJzAnLAogICAgJzInLCdYJywnJScsJzAnLCcyJywnWCcsJy0nLCclJywnMCcsJzInLCdYJywnJScsJzAnLCcyJywnWCcsJyUnLCcwJywnMicsCiAgICAnWCcsJyUnLCcwJywnMicsJ1gnLCclJywnMCcsJzInLCdYJywnJScsJzAnLCcyJywnWCcsMAp9OwoKc3RhdGljIGNvbnN0IFdDSEFSIHN6Q2F0M0ZtdFtdID0KewogICAgJyUnLCdzJywnXFwnLCclJywncycsJ1xcJywnJScsJ3MnLDAKfTsKCnN0YXRpYyBjb25zdCBXQ0hBUiBzekNhdDJGbXRbXSA9CnsKICAgICclJywncycsJ1xcJywnJScsJ3MnLDAKfTsKCnR5cGVkZWYgc3RydWN0CnsKICAgIGNvbnN0IElFbnVtRE1PVnRibCAgICAgICAgICpscFZ0Ymw7CiAgICBEV09SRAkJCXJlZjsKICAgIERXT1JECQkJaW5kZXg7CiAgICBjb25zdCBHVUlEKiAgICAgICAgICAgICAgICAgZ3VpZENhdGVnb3J5OwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgIGR3RmxhZ3M7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgY0luVHlwZXM7CiAgICBETU9fUEFSVElBTF9NRURJQVRZUEUgICAgICAgKnBJblR5cGVzOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgIGNPdXRUeXBlczsKICAgIERNT19QQVJUSUFMX01FRElBVFlQRSAgICAgICAqcE91dFR5cGVzOwogICAgSEtFWSAgICAgICAgICAgICAgICAgICAgICAgIGhrZXk7Cn0gSUVudW1ETU9JbXBsOwoKc3RhdGljIGNvbnN0IElFbnVtRE1PVnRibCBlZG1vdnQ7CgpzdGF0aWMgTFBXU1RSIEdVSURUb1N0cmluZyhMUFdTVFIgbHB3c3RyLCBSRUZHVUlEIGxwY2d1aWQpCnsKICAgIHdzcHJpbnRmVyhscHdzdHIsIHN6R1VJREZtdCwgbHBjZ3VpZC0+RGF0YTEsIGxwY2d1aWQtPkRhdGEyLAogICAgICAgIGxwY2d1aWQtPkRhdGEzLCBscGNndWlkLT5EYXRhNFswXSwgbHBjZ3VpZC0+RGF0YTRbMV0sCiAgICAgICAgbHBjZ3VpZC0+RGF0YTRbMl0sIGxwY2d1aWQtPkRhdGE0WzNdLCBscGNndWlkLT5EYXRhNFs0XSwKICAgICAgICBscGNndWlkLT5EYXRhNFs1XSwgbHBjZ3VpZC0+RGF0YTRbNl0sIGxwY2d1aWQtPkRhdGE0WzddKTsKCiAgICByZXR1cm4gbHB3c3RyOwp9CgpzdGF0aWMgQk9PTCBJc01lZGlhVHlwZUVxdWFsKERNT19QQVJUSUFMX01FRElBVFlQRSogbXQxLCBETU9fUEFSVElBTF9NRURJQVRZUEUqIG10MikKewoKICAgIHJldHVybiAoSXNFcXVhbENMU0lEKCZtdDEtPnR5cGUsICZtdDItPnR5cGUpIHx8CiAgICAgICAgICAgIElzRXF1YWxDTFNJRCgmbXQyLT50eXBlLCAmR1VJRF9OVUxMKSB8fAogICAgICAgICAgICBJc0VxdWFsQ0xTSUQoJm10MS0+dHlwZSwgJkdVSURfTlVMTCkpICYmCiAgICAgICAgICAgIChJc0VxdWFsQ0xTSUQoJm10MS0+c3VidHlwZSwgJm10Mi0+c3VidHlwZSkgfHwKICAgICAgICAgICAgSXNFcXVhbENMU0lEKCZtdDItPnN1YnR5cGUsICZHVUlEX05VTEwpIHx8CiAgICAgICAgICAgIElzRXF1YWxDTFNJRCgmbXQxLT5zdWJ0eXBlLCAmR1VJRF9OVUxMKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRE1PUmVnaXN0ZXIKICoKICogUmVnaXN0ZXIgYSBEaXJlY3RYIE1lZGlhIE9iamVjdC4KICovCkhSRVNVTFQgV0lOQVBJIERNT1JlZ2lzdGVyKAogICBMUENXU1RSIHN6TmFtZSwKICAgUkVGQ0xTSUQgY2xzaWRETU8sCiAgIFJFRkdVSUQgZ3VpZENhdGVnb3J5LAogICBEV09SRCBkd0ZsYWdzLAogICBEV09SRCBjSW5UeXBlcywKICAgY29uc3QgRE1PX1BBUlRJQUxfTUVESUFUWVBFICpwSW5UeXBlcywKICAgRFdPUkQgY091dFR5cGVzLAogICBjb25zdCBETU9fUEFSVElBTF9NRURJQVRZUEUgKnBPdXRUeXBlcwopCnsKICAgIFdDSEFSIHN6Z3VpZFs2NF07CiAgICBIUkVTVUxUIGhyZXM7CiAgICBIS0VZIGhya2V5ID0gMDsKICAgIEhLRVkgaGtleSA9IDA7CiAgICBIS0VZIGhja2V5ID0gMDsKICAgIEhLRVkgaGNsc2tleSA9IDA7CgogICAgVFJBQ0UoIiVzXG4iLCBkZWJ1Z3N0cl93KHN6TmFtZSkpOwoKICAgIGhyZXMgPSBSZWdPcGVuS2V5RXhXKEhLRVlfQ0xBU1NFU19ST09ULCBzekRNT1Jvb3RLZXksIDAsIEtFWV9XUklURSwgJmhya2V5KTsKICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgZ290byBsZW5kOwoKICAgIC8qIENyZWF0ZSBjbHNpZERNTyBrZXkgdW5kZXIgTWVkaWFPYmplY3RzICovIAogICAgaHJlcyA9IFJlZ0NyZWF0ZUtleUV4VyhocmtleSwgR1VJRFRvU3RyaW5nKHN6Z3VpZCwgY2xzaWRETU8pLCAwLCBOVUxMLAogICAgICAgIFJFR19PUFRJT05fTk9OX1ZPTEFUSUxFLCBLRVlfV1JJVEUsIE5VTEwsICZoa2V5LCBOVUxMKTsKICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgZ290byBsZW5kOwoKICAgIC8qIFNldCBkZWZhdWx0IE5hbWUgdmFsdWUgKi8KICAgIGhyZXMgPSBSZWdTZXRWYWx1ZUV4Vyhoa2V5LCBOVUxMLCAwLCBSRUdfU1osIChjb25zdCBCWVRFKikgc3pOYW1lLCAKICAgICAgICAoc3RybGVuVyhzek5hbWUpICsgMSkpICogc2l6ZW9mKFdDSEFSKTsKICAgIC8qIFNldCBJbnB1dFR5cGVzICovCiAgICBocmVzID0gUmVnU2V0VmFsdWVFeFcoaGtleSwgc3pETU9JbnB1dFR5cGUsIDAsIFJFR19CSU5BUlksIAogICAgICAgIChjb25zdCBCWVRFKikgcEluVHlwZXMsIGNJblR5cGVzICogc2l6ZW9mKERNT19QQVJUSUFMX01FRElBVFlQRSkpOwogICAgLyogU2V0IE91dHB1dFR5cGVzICovCiAgICBocmVzID0gUmVnU2V0VmFsdWVFeFcoaGtleSwgc3pETU9PdXRwdXRUeXBlLCAwLCBSRUdfQklOQVJZLCAKICAgICAgICAoY29uc3QgQllURSopIHBPdXRUeXBlcywgY091dFR5cGVzICogc2l6ZW9mKERNT19QQVJUSUFMX01FRElBVFlQRSkpOwoKICAgIGlmIChkd0ZsYWdzICYgRE1PX1JFR0lTVEVSRl9JU19LRVlFRCkKICAgIHsKICAgICAgICAvKiBDcmVhdGUgS2V5ZWQga2V5ICovIAogICAgICAgIGhyZXMgPSBSZWdDcmVhdGVLZXlFeFcoaGtleSwgc3pETU9LZXllZCwgMCwgTlVMTCwKICAgICAgICAgICAgUkVHX09QVElPTl9OT05fVk9MQVRJTEUsIEtFWV9XUklURSwgTlVMTCwgJmhja2V5LCBOVUxMKTsKICAgICAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgICAgICBnb3RvIGxlbmQ7CiAgICAgICAgUmVnQ2xvc2VLZXkoaGNrZXkpOwogICAgfQoKICAgIC8qIFJlZ2lzdGVyIHRoZSBjYXRlZ29yeSAqLwogICAgaHJlcyA9IFJlZ09wZW5LZXlFeFcoaHJrZXksIHN6RE1PQ2F0ZWdvcmllcywgMCwgS0VZX1dSSVRFLCAmaGNrZXkpOwogICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICBnb3RvIGxlbmQ7CgogICAgUmVnQ2xvc2VLZXkoaGtleSk7CgogICAgaHJlcyA9IFJlZ09wZW5LZXlFeFcoaGNrZXksIEdVSURUb1N0cmluZyhzemd1aWQsIGd1aWRDYXRlZ29yeSksIDAsIEtFWV9XUklURSwgJmhrZXkpOwogICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICBnb3RvIGxlbmQ7CiAgICBocmVzID0gUmVnQ3JlYXRlS2V5RXhXKGhrZXksIEdVSURUb1N0cmluZyhzemd1aWQsIGNsc2lkRE1PKSwgMCwgTlVMTCwKICAgICAgICBSRUdfT1BUSU9OX05PTl9WT0xBVElMRSwgS0VZX1dSSVRFLCBOVUxMLCAmaGNsc2tleSwgTlVMTCk7CiAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgIGdvdG8gbGVuZDsKCmxlbmQ6CiAgICBpZiAoaGtleSkKICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKICAgIGlmIChoY2tleSkKICAgICAgICBSZWdDbG9zZUtleShoY2tleSk7CiAgICBpZiAoaGNsc2tleSkKICAgICAgICBSZWdDbG9zZUtleShoY2xza2V5KTsKICAgIGlmIChocmtleSkKICAgICAgICBSZWdDbG9zZUtleShocmtleSk7CgogICAgVFJBQ0UoIiBocmVzdWx0PTB4JTA4bHhcbiIsIGhyZXMpOwogICAgcmV0dXJuIGhyZXM7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERNT1VucmVnaXN0ZXIKICoKICogVW5yZWdpc3RlciBhIERpcmVjdFggTWVkaWEgT2JqZWN0LgogKi8KSFJFU1VMVCBXSU5BUEkgRE1PVW5yZWdpc3RlcihSRUZDTFNJRCBjbHNpZERNTywgUkVGR1VJRCBndWlkQ2F0ZWdvcnkpCnsKICAgIEhSRVNVTFQgaHJlczsKICAgIFdDSEFSIHN6Z3VpZFs2NF07CiAgICBIS0VZIGhya2V5ID0gMDsKICAgIEhLRVkgaGNrZXkgPSAwOwoKICAgIEdVSURUb1N0cmluZyhzemd1aWQsIGNsc2lkRE1PKTsKCiAgICBUUkFDRSgiJXMgJXBcbiIsIGRlYnVnc3RyX3coc3pndWlkKSwgZ3VpZENhdGVnb3J5KTsKCiAgICBocmVzID0gUmVnT3BlbktleUV4VyhIS0VZX0NMQVNTRVNfUk9PVCwgc3pETU9Sb290S2V5LCAwLCBLRVlfV1JJVEUsICZocmtleSk7CiAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgIGdvdG8gbGVuZDsKCiAgICBocmVzID0gUmVnRGVsZXRlS2V5VyhocmtleSwgc3pndWlkKTsKICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgZ290byBsZW5kOwoKICAgIGhyZXMgPSBSZWdPcGVuS2V5RXhXKGhya2V5LCBzekRNT0NhdGVnb3JpZXMsIDAsIEtFWV9XUklURSwgJmhja2V5KTsKICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgZ290byBsZW5kOwoKICAgIGhyZXMgPSBSZWdEZWxldGVLZXlXKGhja2V5LCBzemd1aWQpOwogICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICBnb3RvIGxlbmQ7CgpsZW5kOgogICAgaWYgKGhja2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhja2V5KTsKICAgIGlmIChocmtleSkKICAgICAgICBSZWdDbG9zZUtleShocmtleSk7CgogICAgcmV0dXJuIGhyZXM7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERNT0dldE5hbWUKICoKICogR2V0IERNUCBOYW1lIGZyb20gdGhlIHJlZ2lzdHJ5CiAqLwpIUkVTVUxUIFdJTkFQSSBETU9HZXROYW1lKFJFRkNMU0lEIGNsc2lkRE1PLCBXQ0hBUiogc3pOYW1lKQp7CiAgICBXQ0hBUiBzemd1aWRbNjRdOwogICAgSFJFU1VMVCBocmVzOwogICAgSEtFWSBocmtleSA9IDA7CiAgICBIS0VZIGhrZXkgPSAwOwogICAgRFdPUkQgY291bnQ7CgogICAgVFJBQ0UoIiVzXG4iLCBkZWJ1Z3N0cl9ndWlkKGNsc2lkRE1PKSk7CgogICAgaHJlcyA9IFJlZ09wZW5LZXlFeFcoSEtFWV9DTEFTU0VTX1JPT1QsIHN6RE1PUm9vdEtleSwgCiAgICAgICAgMCwgS0VZX1JFQUQsICZocmtleSk7CiAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgIGdvdG8gbGVuZDsKCiAgICBocmVzID0gUmVnT3BlbktleUV4VyhocmtleSwgR1VJRFRvU3RyaW5nKHN6Z3VpZCwgY2xzaWRETU8pLAogICAgICAgIDAsIEtFWV9SRUFELCAmaGtleSk7CiAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgIGdvdG8gbGVuZDsKCiAgICBjb3VudCA9IDgwICogc2l6ZW9mKFdDSEFSKTsgLyogODAgYnkgQVBJIGRlZmluaXRpb24gKi8KICAgIGhyZXMgPSBSZWdRdWVyeVZhbHVlRXhXKGhrZXksIE5VTEwsIE5VTEwsIE5VTEwsIAogICAgICAgIChMUEJZVEUpIHN6TmFtZSwgJmNvdW50KTsgCgogICAgVFJBQ0UoIiBzek5hbWU9JXNcbiIsIGRlYnVnc3RyX3coc3pOYW1lKSk7CmxlbmQ6CiAgICBpZiAoaGtleSkKICAgICAgICBSZWdDbG9zZUtleShocmtleSk7CiAgICBpZiAoaGtleSkKICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKCiAgICByZXR1cm4gaHJlczsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgSUVudW1ETU9fRGVzdHJ1Y3RvcgoqLwpzdGF0aWMgQk9PTCBJRW51bURNT19EZXN0cnVjdG9yKElFbnVtRE1PKiBpZmFjZSkKewogICAgSUVudW1ETU9JbXBsICpUaGlzID0gKElFbnVtRE1PSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIlcFxuIiwgVGhpcyk7CgogICAgaWYgKFRoaXMtPmhrZXkpCiAgICAgICAgUmVnQ2xvc2VLZXkoVGhpcy0+aGtleSk7CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cEluVHlwZXMpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cE91dFR5cGVzKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgSUVudW1ETU9fQ29uc3RydWN0b3IKICovCklFbnVtRE1PICogSUVudW1ETU9fQ29uc3RydWN0b3IoCiAgICBSRUZHVUlEIGd1aWRDYXRlZ29yeSwKICAgIERXT1JEIGR3RmxhZ3MsCiAgICBEV09SRCBjSW5UeXBlcywKICAgIGNvbnN0IERNT19QQVJUSUFMX01FRElBVFlQRSAqcEluVHlwZXMsCiAgICBEV09SRCBjT3V0VHlwZXMsCiAgICBjb25zdCBETU9fUEFSVElBTF9NRURJQVRZUEUgKnBPdXRUeXBlcykKewogICAgVUlOVCBzaXplOwogICAgSUVudW1ETU9JbXBsKiBscGVkbW87CiAgICBCT09MIHJldCA9IEZBTFNFOwoKICAgIGxwZWRtbyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSUVudW1ETU9JbXBsKSk7CgogICAgaWYgKGxwZWRtbykKICAgIHsKICAgICAgICBscGVkbW8tPnJlZiA9IDE7CiAgICAgICAgbHBlZG1vLT5scFZ0YmwgPSAmZWRtb3Z0OwogICAgICAgIGxwZWRtby0+aW5kZXggPSAtMTsKCWxwZWRtby0+Z3VpZENhdGVnb3J5ID0gZ3VpZENhdGVnb3J5OwoJbHBlZG1vLT5kd0ZsYWdzID0gZHdGbGFnczsKCglzaXplID0gY0luVHlwZXMgKiBzaXplb2YoRE1PX1BBUlRJQUxfTUVESUFUWVBFKTsKICAgICAgICBscGVkbW8tPnBJblR5cGVzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUpOwogICAgICAgIGlmICghbHBlZG1vLT5wSW5UeXBlcykKICAgICAgICAgICAgZ290byBsZXJyOwoJbWVtY3B5KGxwZWRtby0+cEluVHlwZXMsIHBJblR5cGVzLCBzaXplKTsKICAgICAgICBscGVkbW8tPmNJblR5cGVzID0gY0luVHlwZXM7CgoJc2l6ZSA9IGNPdXRUeXBlcyAqIHNpemVvZihETU9fUEFSVElBTF9NRURJQVRZUEUpOwogICAgICAgIGxwZWRtby0+cE91dFR5cGVzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUpOwogICAgICAgIGlmICghbHBlZG1vLT5wT3V0VHlwZXMpCiAgICAgICAgICAgIGdvdG8gbGVycjsKCW1lbWNweShscGVkbW8tPnBPdXRUeXBlcywgcE91dFR5cGVzLCBzaXplKTsKICAgICAgICBscGVkbW8tPmNPdXRUeXBlcyA9IGNPdXRUeXBlczsKCiAgICAgICAgLyogSWYgbm90IGZpbHRlcmluZyBieSBjYXRlZ29yeSBlbnVtIGZyb20gbWVkaWEgb2JqZWN0cyByb290ICovCiAgICAgICAgaWYgKElzRXF1YWxHVUlEKGd1aWRDYXRlZ29yeSwgJkdVSURfTlVMTCkpCiAgICAgICAgewogICAgICAgICAgICBpZiAoRVJST1JfU1VDQ0VTUyA9PSBSZWdPcGVuS2V5RXhXKEhLRVlfQ0xBU1NFU19ST09ULCBzekRNT1Jvb3RLZXksIAogICAgICAgICAgICAgICAgMCwgS0VZX1JFQUQsICZscGVkbW8tPmhrZXkpKQogICAgICAgICAgICAgICAgcmV0ID0gVFJVRTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgV0NIQVIgc3pndWlkWzY0XTsKICAgICAgICAgICAgV0NIQVIgc3pLZXlbTUFYX1BBVEhdOwoKICAgICAgICAgICAgd3NwcmludGZXKHN6S2V5LCBzekNhdDNGbXQsIHN6RE1PUm9vdEtleSwgc3pETU9DYXRlZ29yaWVzLCAKICAgICAgICAgICAgICAgIEdVSURUb1N0cmluZyhzemd1aWQsIGd1aWRDYXRlZ29yeSkpOwogICAgICAgICAgICBpZiAoRVJST1JfU1VDQ0VTUyA9PSBSZWdPcGVuS2V5RXhXKEhLRVlfQ0xBU1NFU19ST09ULCBzektleSwgCiAgICAgICAgICAgICAgICAwLCBLRVlfUkVBRCwgJmxwZWRtby0+aGtleSkpCiAgICAgICAgICAgICAgICByZXQgPSBUUlVFOwogICAgICAgIH0KCmxlcnI6CiAgICAgICAgaWYoIXJldCkKICAgICAgICB7CiAgICAgICAgICAgIElFbnVtRE1PX0Rlc3RydWN0b3IoKElFbnVtRE1PKilscGVkbW8pOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsbHBlZG1vKTsKICAgICAgICAgICAgbHBlZG1vID0gTlVMTDsKICAgICAgICB9CiAgICB9CgogICAgVFJBQ0UoInJldHVybmluZyAlcFxuIiwgbHBlZG1vKTsKCiAgICByZXR1cm4gKElFbnVtRE1PKilscGVkbW87Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElFbnVtRE1PX2ZuQWRkUmVmCiAqLwpzdGF0aWMgVUxPTkcgV0lOQVBJIElFbnVtRE1PX2ZuQWRkUmVmKElFbnVtRE1PICogaWZhY2UpCnsKICAgIElFbnVtRE1PSW1wbCAqVGhpcyA9IChJRW51bURNT0ltcGwgKilpZmFjZTsKICAgIHJldHVybiBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgRW51bURNT19RdWVyeUludGVyZmFjZQogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFbnVtRE1PX2ZuUXVlcnlJbnRlcmZhY2UoCiAgICBJRW51bURNTyogaWZhY2UsCiAgICBSRUZJSUQgcmlpZCwKICAgIExQVk9JRCAqcHB2T2JqKQp7CiAgICBJRW51bURNT0ltcGwgKlRoaXMgPSAoSUVudW1ETU9JbXBsICopaWZhY2U7CgogICAgKnBwdk9iaiA9IE5VTEw7CgogICAgaWYoSXNFcXVhbElJRChyaWlkLCAmSUlEX0lVbmtub3duKSkKICAgICAgICAqcHB2T2JqID0gVGhpczsKICAgIGVsc2UgaWYoSXNFcXVhbElJRChyaWlkLCAmSUlEX0lFbnVtRE1PKSkKICAgICAgICAqcHB2T2JqID0gKElFbnVtRE1PKilUaGlzOwoKICAgIGlmKCpwcHZPYmopCiAgICB7CiAgICAgICAgSUVudW1ETU9fZm5BZGRSZWYoKElFbnVtRE1PKikqcHB2T2JqKTsKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KCiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUVudW1ETU9fZm5SZWxlYXNlCiAqLwpzdGF0aWMgVUxPTkcgV0lOQVBJIElFbnVtRE1PX2ZuUmVsZWFzZShJRW51bURNTyAqIGlmYWNlKQp7CiAgICBJRW51bURNT0ltcGwgKlRoaXMgPSAoSUVudW1ETU9JbXBsICopaWZhY2U7CiAgICBVTE9ORyByZWZDb3VudCA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwoKICAgIGlmICghcmVmQ291bnQpCiAgICB7CiAgICAgICAgSUVudW1ETU9fRGVzdHJ1Y3RvcigoSUVudW1ETU8qKVRoaXMpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKICAgIH0KICAgIHJldHVybiByZWZDb3VudDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUVudW1ETU9fZm5OZXh0CiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVudW1ETU9fZm5OZXh0KAogICAgSUVudW1ETU8gKiBpZmFjZSwgCiAgICBEV09SRCBjSXRlbXNUb0ZldGNoLAogICAgQ0xTSUQgKiBwQ0xTSUQsCiAgICBXQ0hBUiAqKiBOYW1lcywKICAgIERXT1JEICogcGNJdGVtc0ZldGNoZWQpCnsKICAgIEZJTEVUSU1FIGZ0OwogICAgSEtFWSBoa2V5OwogICAgV0NIQVIgc3pOZXh0S2V5W01BWF9QQVRIXTsKICAgIFdDSEFSIHN6S2V5W01BWF9QQVRIXTsKICAgIFdDSEFSIHN6VmFsdWVbTUFYX1BBVEhdOwogICAgRFdPUkQgbGVuOwogICAgVUlOVCBjb3VudCA9IDA7CiAgICBIUkVTVUxUIGhyZXMgPSBTX09LOwoKICAgIElFbnVtRE1PSW1wbCAqVGhpcyA9IChJRW51bURNT0ltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiJWxkXG4iLCBjSXRlbXNUb0ZldGNoKTsKCiAgICBpZiAoIXBDTFNJRCB8fCAhTmFtZXMgfHwgIXBjSXRlbXNGZXRjaGVkKQogICAgICAgIHJldHVybiBFX1BPSU5URVI7CgogICAgd2hpbGUgKGNvdW50IDwgY0l0ZW1zVG9GZXRjaCkKICAgIHsKICAgICAgICBUaGlzLT5pbmRleCsrOwoKICAgICAgICBocmVzID0gUmVnRW51bUtleUV4VyhUaGlzLT5oa2V5LCBUaGlzLT5pbmRleCwgc3pOZXh0S2V5LCAmbGVuLCBOVUxMLCBOVUxMLCBOVUxMLCAmZnQpOwogICAgICAgIGlmIChocmVzICE9IEVSUk9SX1NVQ0NFU1MpCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBUUkFDRSgiZm91bmQgJXNcbiIsIGRlYnVnc3RyX3coc3pOZXh0S2V5KSk7CgoJaWYgKFRoaXMtPmR3RmxhZ3MgJiBETU9fUkVHSVNURVJGX0lTX0tFWUVEKQogICAgICAgIHsKICAgICAgICAgICAgd3NwcmludGZXKHN6S2V5LCBzekNhdDNGbXQsIHN6RE1PUm9vdEtleSwgc3pOZXh0S2V5LCBzekRNT0tleWVkKTsKICAgICAgICAgICAgaHJlcyA9IFJlZ09wZW5LZXlFeFcoSEtFWV9DTEFTU0VTX1JPT1QsIHN6S2V5LCAwLCBLRVlfUkVBRCwgJmhrZXkpOwogICAgICAgICAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICAgIH0KCiAgICAgICAgd3NwcmludGZXKHN6S2V5LCBzekNhdDJGbXQsIHN6RE1PUm9vdEtleSwgc3pOZXh0S2V5KTsKICAgICAgICBocmVzID0gUmVnT3BlbktleUV4VyhIS0VZX0NMQVNTRVNfUk9PVCwgc3pLZXksIDAsIEtFWV9SRUFELCAmaGtleSk7CgogICAgICAgIGlmIChUaGlzLT5wSW5UeXBlcykKICAgICAgICB7CiAgICAgICAgICAgIFVJTlQgaSwgajsKICAgICAgICAgICAgRFdPUkQgY0luVHlwZXM7CiAgICAgICAgICAgIERNT19QQVJUSUFMX01FRElBVFlQRSogcEluVHlwZXM7CgoJICAgIGxlbiA9IE1BWF9QQVRIICogc2l6ZW9mKFdDSEFSKTsKICAgICAgICAgICAgaHJlcyA9IFJlZ1F1ZXJ5VmFsdWVFeFcoaGtleSwgc3pETU9JbnB1dFR5cGUsIE5VTEwsIE5VTEwsIChMUEJZVEUpIHN6VmFsdWUsICZsZW4pOwoJICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCgkgICAgY0luVHlwZXMgPSBsZW4gLyBzaXplb2YoRE1PX1BBUlRJQUxfTUVESUFUWVBFKTsKCSAgICBwSW5UeXBlcyA9IChETU9fUEFSVElBTF9NRURJQVRZUEUqKSBzelZhbHVlOwoKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IFRoaXMtPmNJblR5cGVzOyBpKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCBjSW5UeXBlczsgaisrKSAKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoSXNNZWRpYVR5cGVFcXVhbCgmcEluVHlwZXNbal0sICZUaGlzLT5wSW5UeXBlc1tpXSkpCgkJICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KCgkJaWYgKGogPj0gY0luVHlwZXMpCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChpIDwgVGhpcy0+Y0luVHlwZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChUaGlzLT5wT3V0VHlwZXMpCiAgICAgICAgewogICAgICAgICAgICBVSU5UIGksIGo7CiAgICAgICAgICAgIERXT1JEIGNPdXRUeXBlczsKICAgICAgICAgICAgRE1PX1BBUlRJQUxfTUVESUFUWVBFKiBwT3V0VHlwZXM7CgoJICAgIGxlbiA9IE1BWF9QQVRIICogc2l6ZW9mKFdDSEFSKTsKICAgICAgICAgICAgaHJlcyA9IFJlZ1F1ZXJ5VmFsdWVFeFcoaGtleSwgc3pETU9PdXRwdXRUeXBlLCBOVUxMLCBOVUxMLCAoTFBCWVRFKSBzelZhbHVlLCAmbGVuKTsKCSAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgoJICAgIGNPdXRUeXBlcyA9IGxlbiAvIHNpemVvZihETU9fUEFSVElBTF9NRURJQVRZUEUpOwoJICAgIHBPdXRUeXBlcyA9IChETU9fUEFSVElBTF9NRURJQVRZUEUqKSBzelZhbHVlOwoKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IFRoaXMtPmNPdXRUeXBlczsgaSsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgY091dFR5cGVzOyBqKyspIAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChJc01lZGlhVHlwZUVxdWFsKCZwT3V0VHlwZXNbal0sICZUaGlzLT5wT3V0VHlwZXNbaV0pKQoJCSAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CgoJCWlmIChqID49IGNPdXRUeXBlcykKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGkgPCBUaGlzLT5jT3V0VHlwZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgoJLyogTWVkaWEgb2JqZWN0IHdhc24ndCBmaWx0ZXJlZCBzbyBhZGQgaXQgdG8gcmV0dXJuIGxpc3QgKi8KICAgICAgICBOYW1lc1tjb3VudF0gPSBOVUxMOwoJbGVuID0gTUFYX1BBVEggKiBzaXplb2YoV0NIQVIpOwogICAgICAgIGhyZXMgPSBSZWdRdWVyeVZhbHVlRXhXKGhrZXksIE5VTEwsIE5VTEwsIE5VTEwsIChMUEJZVEUpIHN6VmFsdWUsICZsZW4pOyAKICAgICAgICBpZiAoRVJST1JfU1VDQ0VTUyA9PSBocmVzKQoJewogICAgICAgICAgICBOYW1lc1tjb3VudF0gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RybGVuVyhzelZhbHVlKSArIDEpOwoJICAgIGlmIChOYW1lc1tjb3VudF0pCiAgICAgICAgICAgICAgICBzdHJjbXBXKE5hbWVzW2NvdW50XSwgc3pWYWx1ZSk7Cgl9CiAgICAgICAgQ0xTSURGcm9tU3RyaW5nKHN6TmV4dEtleSwgJnBDTFNJRFtjb3VudF0pOwoKICAgICAgICBUUkFDRSgiZm91bmQgbWF0Y2ggJXMgJXNcbiIsIGRlYnVnc3RyX3coc3pWYWx1ZSksIGRlYnVnc3RyX3coc3pOZXh0S2V5KSk7CiAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7Cgljb3VudCsrOwogICAgfQoKICAgICpwY0l0ZW1zRmV0Y2hlZCA9IGNvdW50OwogICAgaWYgKCpwY0l0ZW1zRmV0Y2hlZCA8IGNJdGVtc1RvRmV0Y2gpCiAgICAgICAgaHJlcyA9IFNfRkFMU0U7CgogICAgcmV0dXJuIGhyZXM7Cn0KIAoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRW51bURNT19mblNraXAKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRW51bURNT19mblNraXAoSUVudW1ETU8gKiBpZmFjZSwgRFdPUkQgY0l0ZW1zVG9Ta2lwKQp7CiAgICBJRW51bURNT0ltcGwgKlRoaXMgPSAoSUVudW1ETU9JbXBsICopaWZhY2U7CgogICAgVGhpcy0+aW5kZXggKz0gY0l0ZW1zVG9Ta2lwOwoKICAgIHJldHVybiBTX09LOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRW51bURNT19mblJlc2V0CiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVudW1ETU9fZm5SZXNldChJRW51bURNTyAqIGlmYWNlKQp7CiAgICBJRW51bURNT0ltcGwgKlRoaXMgPSAoSUVudW1ETU9JbXBsICopaWZhY2U7CgogICAgVGhpcy0+aW5kZXggPSAtMTsKCiAgICByZXR1cm4gU19PSzsKfQogCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElFbnVtRE1PX2ZuQ2xvbmUKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRW51bURNT19mbkNsb25lKElFbnVtRE1PICogaWZhY2UsIElFbnVtRE1PICoqcHBFbnVtKQp7CiAgICBJRW51bURNT0ltcGwgKlRoaXMgPSAoSUVudW1ETU9JbXBsICopaWZhY2U7CgogICAgRklYTUUoIiglcCktPigpIHRvICglcCktPigpIEVfTk9USU1QTFxuIiwgVGhpcywgcHBFbnVtKTsKCiAgcmV0dXJuIEVfTk9USU1QTDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRE1PRW51bQogKgogKiBFbnVtZXJhdGUgRGlyZWN0WCBNZWRpYSBPYmplY3RzIGluIHRoZSByZWdpc3RyeS4KICovCkhSRVNVTFQgV0lOQVBJIERNT0VudW0oCiAgICBSRUZHVUlEIGd1aWRDYXRlZ29yeSwKICAgIERXT1JEIGR3RmxhZ3MsCiAgICBEV09SRCBjSW5UeXBlcywKICAgIGNvbnN0IERNT19QQVJUSUFMX01FRElBVFlQRSAqcEluVHlwZXMsCiAgICBEV09SRCBjT3V0VHlwZXMsCiAgICBjb25zdCBETU9fUEFSVElBTF9NRURJQVRZUEUgKnBPdXRUeXBlcywKICAgIElFbnVtRE1PICoqcHBFbnVtKQp7CiAgICBIUkVTVUxUIGhyZXMgPSBFX0ZBSUw7CgogICAgVFJBQ0UoImd1aWRDYXRlZ29yeT0lcCBkd0ZsYWdzPTB4JTA4bHggY0luVHlwZXM9JWxkIGNPdXRUeXBlcz0lbGRcbiIsCiAgICAgICAgZ3VpZENhdGVnb3J5LCBkd0ZsYWdzLCBjSW5UeXBlcywgY091dFR5cGVzKTsKCiAgICAqcHBFbnVtID0gSUVudW1ETU9fQ29uc3RydWN0b3IoZ3VpZENhdGVnb3J5LCBkd0ZsYWdzLCBjSW5UeXBlcywKICAgICAgICBwSW5UeXBlcywgY091dFR5cGVzLCBwT3V0VHlwZXMpOwogICAgaWYgKCpwcEVudW0pCiAgICAgICAgaHJlcyA9IFNfT0s7CgogICAgcmV0dXJuIGhyZXM7Cn0KCgpzdGF0aWMgY29uc3QgSUVudW1ETU9WdGJsIGVkbW92dCA9CnsKCUlFbnVtRE1PX2ZuUXVlcnlJbnRlcmZhY2UsCglJRW51bURNT19mbkFkZFJlZiwKCUlFbnVtRE1PX2ZuUmVsZWFzZSwKCUlFbnVtRE1PX2ZuTmV4dCwKCUlFbnVtRE1PX2ZuU2tpcCwKCUlFbnVtRE1PX2ZuUmVzZXQsCglJRW51bURNT19mbkNsb25lLAp9OwoKCkhSRVNVTFQgV0lOQVBJIERNT0dldFR5cGVzKFJFRkNMU0lEIGEsIHVuc2lnbmVkIGxvbmcgYiwgdW5zaWduZWQgbG9uZyogYywKCQkJICAgRE1PX1BBUlRJQUxfTUVESUFUWVBFKiBkLCB1bnNpZ25lZCBsb25nIGUsCgkJCSAgIHVuc2lnbmVkIGxvbmcqIGYsIERNT19QQVJUSUFMX01FRElBVFlQRSogZykKewogIEZJWE1FKCIoJXAsJWx1LCVwLCVwLCVsdSwlcCwlcCksc3R1YiFcbiIsYSxiLGMsZCxlLGYsZyk7CgogIHJldHVybiBFX05PVElNUEw7Cn0K