PD9waHAKLyoqCiAqIFBsdWdpbiBOYW1lOiBGRlAgU2FsZXMgQ29tbWlzc2lvbiBUcmFja2VyCiAqIERlc2NyaXB0aW9uOiBVbHRpbWF0ZSBzYWxlcyB0cmFja2luZyB3aXRoIGdhbWlmaWNhdGlvbiwgYWNoaWV2ZW1lbnRzLCBUViBtb2RlLCBhbmQgbW9yZQogKiBWZXJzaW9uOiAyLjAuMAogKiBBdXRob3I6IEZ1bmN0aW9uIEZhY3RvcnkgUGVyZm9ybWFuY2UKICovCmlmICghZGVmaW5lZCgnQUJTUEFUSCcpKSBleGl0OwoKY2xhc3MgRkZQX1NhbGVzX0NvbW1pc3Npb25fVHJhY2tlciB7CiAgICAKICAgIHByaXZhdGUgJGFzc29jaWF0ZXMgPSBbCiAgICAgICAgJ2NoYXJsZXMnID0+IFsnbmFtZScgPT4gJ0NoYXJsZXMnLCAnY29tbWlzc2lvbicgPT4gZmFsc2UsICdyb2xlJyA9PiAnT3duZXInLCAncmF0ZScgPT4gMF0sCiAgICAgICAgJ2V2YW4nID0+IFsnbmFtZScgPT4gJ0V2YW4nLCAnY29tbWlzc2lvbicgPT4gdHJ1ZSwgJ3JvbGUnID0+ICdDdXN0b21lciBTZXJ2aWNlJywgJ3JhdGUnID0+IDAuMDVdLAogICAgICAgICdyZWdnaWUnID0+IFsnbmFtZScgPT4gJ1JlZ2dpZScsICdjb21taXNzaW9uJyA9PiB0cnVlLCAncm9sZScgPT4gJ1NhbGVzJywgJ3JhdGUnID0+IDAuMDddLAogICAgICAgICd3aWxsJyA9PiBbJ25hbWUnID0+ICdXaWxsJywgJ2NvbW1pc3Npb24nID0+IGZhbHNlLCAncm9sZScgPT4gJ093bmVyJywgJ3JhdGUnID0+IDBdLAogICAgICAgICdldGhhbicgPT4gWyduYW1lJyA9PiAnRXRoYW4nLCAnY29tbWlzc2lvbicgPT4gdHJ1ZSwgJ3JvbGUnID0+ICdQcm9kdWN0IENhdGFsb2cgQ29vcmRpbmF0b3InLCAncmF0ZScgPT4gMC4wN10sCiAgICAgICAgJ2lzYWlhaCcgPT4gWyduYW1lJyA9PiAnSXNhaWFoJywgJ2NvbW1pc3Npb24nID0+IHRydWUsICdyb2xlJyA9PiAnU2FsZXMnLCAncmF0ZScgPT4gMC4wN10sCiAgICBdOwogICAgCiAgICBwcml2YXRlICRjb21taXNzaW9uX3JhdGUgPSAwLjA3OwogICAgCiAgICBwcml2YXRlICRhY2hpZXZlbWVudHMgPSBbCiAgICAgICAgJ2ZpcnN0X2Jsb29kJyA9PiBbJ25hbWUnID0+ICdGaXJzdCBCbG9vZCcsICdpY29uJyA9PiAn8J+puCcsICdkZXNjJyA9PiAnRmlyc3Qgc2FsZSBvZiB0aGUgbW9udGgnXSwKICAgICAgICAndGVuX2tfY2x1YicgPT4gWyduYW1lJyA9PiAnMTBLIENsdWInLCAnaWNvbicgPT4gJ/Cfko4nLCAnZGVzYycgPT4gJ0hpdCAkMTBrIGluIGEgbW9udGgnXSwKICAgICAgICAndHdlbnR5X2ZpdmVfaycgPT4gWyduYW1lJyA9PiAnMjVLIExlZ2VuZCcsICdpY29uJyA9PiAn8J+RkScsICdkZXNjJyA9PiAnSGl0ICQyNWsgaW4gYSBtb250aCddLAogICAgICAgICdoYXRfdHJpY2snID0+IFsnbmFtZScgPT4gJ0hhdCBUcmljaycsICdpY29uJyA9PiAn8J+OqScsICdkZXNjJyA9PiAnMyBzYWxlcyBpbiBvbmUgZGF5J10sCiAgICAgICAgJ2Nsb3NlcicgPT4gWyduYW1lJyA9PiAnVGhlIENsb3NlcicsICdpY29uJyA9PiAn8J+OrycsICdkZXNjJyA9PiAnSGlnaGVzdCBzaW5nbGUgb3JkZXIgb2YgbW9udGgnXSwKICAgICAgICAnc3RyZWFrXzMnID0+IFsnbmFtZScgPT4gJ09uIEEgUm9sbCcsICdpY29uJyA9PiAn8J+UpScsICdkZXNjJyA9PiAnU2FsZXMgMyBkYXlzIGluIGEgcm93J10sCiAgICAgICAgJ3N0cmVha181JyA9PiBbJ25hbWUnID0+ICdTdHJlYWsgTWFzdGVyJywgJ2ljb24nID0+ICfimqEnLCAnZGVzYycgPT4gJ1NhbGVzIDUgZGF5cyBpbiBhIHJvdyddLAogICAgICAgICdjZW50dXJ5JyA9PiBbJ25hbWUnID0+ICdDZW50dXJ5IENsdWInLCAnaWNvbicgPT4gJ/Cfkq8nLCAnZGVzYycgPT4gJzEwMCBvcmRlcnMgbGlmZXRpbWUnXSwKICAgICAgICAnZWFybHlfYmlyZCcgPT4gWyduYW1lJyA9PiAnRWFybHkgQmlyZCcsICdpY29uJyA9PiAn8J+MhScsICdkZXNjJyA9PiAnU2FsZSBiZWZvcmUgOWFtJ10sCiAgICAgICAgJ25pZ2h0X293bCcgPT4gWyduYW1lJyA9PiAnTmlnaHQgT3dsJywgJ2ljb24nID0+ICfwn6aJJywgJ2Rlc2MnID0+ICdTYWxlIGFmdGVyIDhwbSddLAogICAgICAgICd3ZWVrZW5kX3dhcnJpb3InID0+IFsnbmFtZScgPT4gJ1dlZWtlbmQgV2FycmlvcicsICdpY29uJyA9PiAn4pqU77iPJywgJ2Rlc2MnID0+ICdTYWxlIG9uIHdlZWtlbmQnXSwKICAgICAgICAnYmlnX3RpY2tldCcgPT4gWyduYW1lJyA9PiAnQmlnIFRpY2tldCcsICdpY29uJyA9PiAn8J+On++4jycsICdkZXNjJyA9PiAnU2luZ2xlIG9yZGVyIG92ZXIgJDIsMDAwJ10sCiAgICAgICAgJ3doYWxlJyA9PiBbJ25hbWUnID0+ICdXaGFsZSBIdW50ZXInLCAnaWNvbicgPT4gJ/CfkIsnLCAnZGVzYycgPT4gJ1NpbmdsZSBvcmRlciBvdmVyICQ1LDAwMCddLAogICAgXTsKICAgIAogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkgewogICAgICAgIHJlZ2lzdGVyX2FjdGl2YXRpb25faG9vayhfX0ZJTEVfXywgWyR0aGlzLCAnYWN0aXZhdGUnXSk7CiAgICAgICAgYWRkX2FjdGlvbignd29vY29tbWVyY2VfYWZ0ZXJfY2hlY2tvdXRfYmlsbGluZ19mb3JtJywgWyR0aGlzLCAnYWRkX3NhbGVzX2Fzc29jaWF0ZV9maWVsZCddKTsKICAgICAgICBhZGRfYWN0aW9uKCd3b29jb21tZXJjZV9jaGVja291dF91cGRhdGVfb3JkZXJfbWV0YScsIFskdGhpcywgJ3NhdmVfc2FsZXNfYXNzb2NpYXRlX2ZpZWxkJ10pOwogICAgICAgIGFkZF9hY3Rpb24oJ3dvb2NvbW1lcmNlX2FkbWluX29yZGVyX2RhdGFfYWZ0ZXJfYmlsbGluZ19hZGRyZXNzJywgWyR0aGlzLCAnZGlzcGxheV9zYWxlc19hc3NvY2lhdGVfYWRtaW4nXSk7CiAgICAgICAgYWRkX2FjdGlvbignd2ZhY3BfYWZ0ZXJfcGhvbmVfZmllbGQnLCBbJHRoaXMsICdhZGRfc2FsZXNfYXNzb2NpYXRlX2ZpZWxkJ10pOwogICAgICAgIGFkZF9maWx0ZXIoJ3dmYWNwX2NoZWNrb3V0X2ZpZWxkcycsIFskdGhpcywgJ2FkZF9mdW5uZWxraXRfZmllbGQnXSwgMTAsIDIpOwogICAgICAgIGFkZF9hY3Rpb24oJ2FkbWluX21lbnUnLCBbJHRoaXMsICdhZGRfYWRtaW5fbWVudSddKTsKICAgICAgICBhZGRfYWN0aW9uKCd3cF9hamF4X2ZmcF9nZXRfY29tbWlzc2lvbl9kYXRhJywgWyR0aGlzLCAnYWpheF9nZXRfY29tbWlzc2lvbl9kYXRhJ10pOwogICAgICAgIGFkZF9hY3Rpb24oJ3dwX2FqYXhfZmZwX2dldF9saXZlX2ZlZWQnLCBbJHRoaXMsICdhamF4X2dldF9saXZlX2ZlZWQnXSk7CiAgICAgICAgYWRkX2FjdGlvbignd3BfYWpheF9mZnBfZXhwb3J0X2NvbW1pc3Npb24nLCBbJHRoaXMsICdhamF4X2V4cG9ydF9jb21taXNzaW9uJ10pOwogICAgICAgIGFkZF9hY3Rpb24oJ3dwX2FqYXhfZmZwX2dldF9hbmFseXRpY3MnLCBbJHRoaXMsICdhamF4X2dldF9hbmFseXRpY3MnXSk7CiAgICAgICAgYWRkX2FjdGlvbignd3BfYWpheF9mZnBfZ2V0X2hlYWRfdG9faGVhZCcsIFskdGhpcywgJ2FqYXhfZ2V0X2hlYWRfdG9faGVhZCddKTsKICAgICAgICBhZGRfZmlsdGVyKCdtYW5hZ2VfZWRpdC1zaG9wX29yZGVyX2NvbHVtbnMnLCBbJHRoaXMsICdhZGRfb3JkZXJfY29sdW1uJ10pOwogICAgICAgIGFkZF9hY3Rpb24oJ21hbmFnZV9zaG9wX29yZGVyX3Bvc3RzX2N1c3RvbV9jb2x1bW4nLCBbJHRoaXMsICdyZW5kZXJfb3JkZXJfY29sdW1uJ10sIDEwLCAyKTsKICAgICAgICBhZGRfZmlsdGVyKCdtYW5hZ2Vfd29vY29tbWVyY2VfcGFnZV93Yy1vcmRlcnNfY29sdW1ucycsIFskdGhpcywgJ2FkZF9vcmRlcl9jb2x1bW4nXSk7CiAgICAgICAgYWRkX2FjdGlvbignbWFuYWdlX3dvb2NvbW1lcmNlX3BhZ2Vfd2Mtb3JkZXJzX2N1c3RvbV9jb2x1bW4nLCBbJHRoaXMsICdyZW5kZXJfb3JkZXJfY29sdW1uX2hwb3MnXSwgMTAsIDIpOwogICAgICAgIGFkZF9hY3Rpb24oJ3dvb2NvbW1lcmNlX29yZGVyX3N0YXR1c19jb21wbGV0ZWQnLCBbJHRoaXMsICdwcm9jZXNzX2FjaGlldmVtZW50cyddKTsKICAgICAgICBhZGRfYWN0aW9uKCd3b29jb21tZXJjZV9vcmRlcl9zdGF0dXNfcHJvY2Vzc2luZycsIFskdGhpcywgJ3Byb2Nlc3NfYWNoaWV2ZW1lbnRzJ10pOwogICAgfQogICAgCiAgICBwdWJsaWMgZnVuY3Rpb24gYWN0aXZhdGUoKSB7CiAgICAgICAgZ2xvYmFsICR3cGRiOwogICAgICAgICRjaGFyc2V0X2NvbGxhdGUgPSAkd3BkYi0+Z2V0X2NoYXJzZXRfY29sbGF0ZSgpOwogICAgICAgICR0YWJsZV9uYW1lID0gJHdwZGItPnByZWZpeCAuICdmZnBfYWNoaWV2ZW1lbnRzJzsKICAgICAgICAkc3FsID0gIkNSRUFURSBUQUJMRSBJRiBOT1QgRVhJU1RTICR0YWJsZV9uYW1lICgKICAgICAgICAgICAgaWQgYmlnaW50KDIwKSBOT1QgTlVMTCBBVVRPX0lOQ1JFTUVOVCwKICAgICAgICAgICAgYXNzb2NpYXRlX2tleSB2YXJjaGFyKDUwKSBOT1QgTlVMTCwKICAgICAgICAgICAgYWNoaWV2ZW1lbnRfa2V5IHZhcmNoYXIoNTApIE5PVCBOVUxMLAogICAgICAgICAgICBlYXJuZWRfYXQgZGF0ZXRpbWUgREVGQVVMVCBDVVJSRU5UX1RJTUVTVEFNUCwKICAgICAgICAgICAgb3JkZXJfaWQgYmlnaW50KDIwKSBERUZBVUxUIE5VTEwsCiAgICAgICAgICAgIFBSSU1BUlkgS0VZIChpZCkKICAgICAgICApICRjaGFyc2V0X2NvbGxhdGU7IjsKICAgICAgICByZXF1aXJlX29uY2UoQUJTUEFUSCAuICd3cC1hZG1pbi9pbmNsdWRlcy91cGdyYWRlLnBocCcpOwogICAgICAgIGRiRGVsdGEoJHNxbCk7CiAgICB9CiAgICAKICAgIHB1YmxpYyBmdW5jdGlvbiBwcm9jZXNzX2FjaGlldmVtZW50cygkb3JkZXJfaWQpIHsKICAgICAgICBnbG9iYWwgJHdwZGI7CiAgICAgICAgJG9yZGVyID0gd2NfZ2V0X29yZGVyKCRvcmRlcl9pZCk7CiAgICAgICAgaWYgKCEkb3JkZXIpIHJldHVybjsKICAgICAgICAkYXNzb2NpYXRlX2tleSA9ICRvcmRlci0+Z2V0X21ldGEoJ19zYWxlc19hc3NvY2lhdGUnKTsKICAgICAgICBpZiAoISRhc3NvY2lhdGVfa2V5IHx8ICFpc3NldCgkdGhpcy0+YXNzb2NpYXRlc1skYXNzb2NpYXRlX2tleV0pKSByZXR1cm47CiAgICAgICAgJHN1YnRvdGFsID0gJG9yZGVyLT5nZXRfc3VidG90YWwoKTsKICAgICAgICAkb3JkZXJfZGF0ZSA9ICRvcmRlci0+Z2V0X2RhdGVfY3JlYXRlZCgpOwogICAgICAgICRtb250aF95ZWFyID0gJG9yZGVyX2RhdGUtPmZvcm1hdCgnWS1tJyk7CiAgICAgICAgCiAgICAgICAgaWYgKCRzdWJ0b3RhbCA+PSAyMDAwKSAkdGhpcy0+YXdhcmRfYWNoaWV2ZW1lbnQoJGFzc29jaWF0ZV9rZXksICdiaWdfdGlja2V0JywgJG9yZGVyX2lkKTsKICAgICAgICBpZiAoJHN1YnRvdGFsID49IDUwMDApICR0aGlzLT5hd2FyZF9hY2hpZXZlbWVudCgkYXNzb2NpYXRlX2tleSwgJ3doYWxlJywgJG9yZGVyX2lkKTsKICAgICAgICBpZiAoKGludCkkb3JkZXJfZGF0ZS0+Zm9ybWF0KCdIJykgPCA5KSAkdGhpcy0+YXdhcmRfYWNoaWV2ZW1lbnQoJGFzc29jaWF0ZV9rZXksICdlYXJseV9iaXJkJywgJG9yZGVyX2lkKTsKICAgICAgICBpZiAoKGludCkkb3JkZXJfZGF0ZS0+Zm9ybWF0KCdIJykgPj0gMjApICR0aGlzLT5hd2FyZF9hY2hpZXZlbWVudCgkYXNzb2NpYXRlX2tleSwgJ25pZ2h0X293bCcsICRvcmRlcl9pZCk7CiAgICAgICAgaWYgKCRvcmRlcl9kYXRlLT5mb3JtYXQoJ04nKSA+PSA2KSAkdGhpcy0+YXdhcmRfYWNoaWV2ZW1lbnQoJGFzc29jaWF0ZV9rZXksICd3ZWVrZW5kX3dhcnJpb3InLCAkb3JkZXJfaWQpOwogICAgICAgIGlmICgkdGhpcy0+aXNfZmlyc3Rfc2FsZV9vZl9tb250aCgkYXNzb2NpYXRlX2tleSwgJG1vbnRoX3llYXIpKSAkdGhpcy0+YXdhcmRfYWNoaWV2ZW1lbnQoJGFzc29jaWF0ZV9rZXksICdmaXJzdF9ibG9vZCcsICRvcmRlcl9pZCk7CiAgICAgICAgCiAgICAgICAgJG1vbnRobHlfdG90YWwgPSAkdGhpcy0+Z2V0X21vbnRobHlfdG90YWwoJGFzc29jaWF0ZV9rZXksICRtb250aF95ZWFyKTsKICAgICAgICBpZiAoJG1vbnRobHlfdG90YWwgPj0gMTAwMDApICR0aGlzLT5hd2FyZF9hY2hpZXZlbWVudCgkYXNzb2NpYXRlX2tleSwgJ3Rlbl9rX2NsdWInLCAkb3JkZXJfaWQpOwogICAgICAgIGlmICgkbW9udGhseV90b3RhbCA+PSAyNTAwMCkgJHRoaXMtPmF3YXJkX2FjaGlldmVtZW50KCRhc3NvY2lhdGVfa2V5LCAndHdlbnR5X2ZpdmVfaycsICRvcmRlcl9pZCk7CiAgICAgICAgCiAgICAgICAgJHN0cmVhayA9ICR0aGlzLT5nZXRfc2FsZXNfc3RyZWFrKCRhc3NvY2lhdGVfa2V5KTsKICAgICAgICBpZiAoJHN0cmVhayA+PSAzKSAkdGhpcy0+YXdhcmRfYWNoaWV2ZW1lbnQoJGFzc29jaWF0ZV9rZXksICdzdHJlYWtfMycsICRvcmRlcl9pZCk7CiAgICAgICAgaWYgKCRzdHJlYWsgPj0gNSkgJHRoaXMtPmF3YXJkX2FjaGlldmVtZW50KCRhc3NvY2lhdGVfa2V5LCAnc3RyZWFrXzUnLCAkb3JkZXJfaWQpOwogICAgICAgIGlmICgkdGhpcy0+Z2V0X2RhaWx5X3NhbGVzX2NvdW50KCRhc3NvY2lhdGVfa2V5LCAkb3JkZXJfZGF0ZS0+Zm9ybWF0KCdZLW0tZCcpKSA+PSAzKSAkdGhpcy0+YXdhcmRfYWNoaWV2ZW1lbnQoJGFzc29jaWF0ZV9rZXksICdoYXRfdHJpY2snLCAkb3JkZXJfaWQpOwogICAgICAgIGlmICgkdGhpcy0+Z2V0X2xpZmV0aW1lX29yZGVyX2NvdW50KCRhc3NvY2lhdGVfa2V5KSA+PSAxMDApICR0aGlzLT5hd2FyZF9hY2hpZXZlbWVudCgkYXNzb2NpYXRlX2tleSwgJ2NlbnR1cnknLCAkb3JkZXJfaWQpOwogICAgfQogICAgCiAgICBwcml2YXRlIGZ1bmN0aW9uIGF3YXJkX2FjaGlldmVtZW50KCRhc3NvY2lhdGVfa2V5LCAkYWNoaWV2ZW1lbnRfa2V5LCAkb3JkZXJfaWQpIHsKICAgICAgICBnbG9iYWwgJHdwZGI7CiAgICAgICAgJHRhYmxlX25hbWUgPSAkd3BkYi0+cHJlZml4IC4gJ2ZmcF9hY2hpZXZlbWVudHMnOwogICAgICAgICRtb250aGx5ID0gWydmaXJzdF9ibG9vZCcsICd0ZW5fa19jbHViJywgJ3R3ZW50eV9maXZlX2snLCAnY2xvc2VyJ107CiAgICAgICAgaWYgKGluX2FycmF5KCRhY2hpZXZlbWVudF9rZXksICRtb250aGx5KSkgewogICAgICAgICAgICAkZXhpc3RpbmcgPSAkd3BkYi0+Z2V0X3Zhcigkd3BkYi0+cHJlcGFyZSgiU0VMRUNUIGlkIEZST00gJHRhYmxlX25hbWUgV0hFUkUgYXNzb2NpYXRlX2tleSA9ICVzIEFORCBhY2hpZXZlbWVudF9rZXkgPSAlcyBBTkQgZWFybmVkX2F0ID49ICVzIiwgJGFzc29jaWF0ZV9rZXksICRhY2hpZXZlbWVudF9rZXksIGRhdGUoJ1ktbS0wMSAwMDowMDowMCcpKSk7CiAgICAgICAgICAgIGlmICgkZXhpc3RpbmcpIHJldHVybjsKICAgICAgICB9CiAgICAgICAgJHdwZGItPmluc2VydCgkdGFibGVfbmFtZSwgWydhc3NvY2lhdGVfa2V5JyA9PiAkYXNzb2NpYXRlX2tleSwgJ2FjaGlldmVtZW50X2tleScgPT4gJGFjaGlldmVtZW50X2tleSwgJ29yZGVyX2lkJyA9PiAkb3JkZXJfaWQsICdlYXJuZWRfYXQnID0+IGN1cnJlbnRfdGltZSgnbXlzcWwnKV0pOwogICAgfQogICAgCiAgICBwcml2YXRlIGZ1bmN0aW9uIGlzX2ZpcnN0X3NhbGVfb2ZfbW9udGgoJGFzc29jaWF0ZV9rZXksICRtb250aF95ZWFyKSB7CiAgICAgICAgJG9yZGVycyA9IHdjX2dldF9vcmRlcnMoWydsaW1pdCcgPT4gMiwgJ3N0YXR1cycgPT4gWydjb21wbGV0ZWQnLCAncHJvY2Vzc2luZyddLCAnZGF0ZV9jcmVhdGVkJyA9PiAkbW9udGhfeWVhciAuICctMDEuLi4nIC4gJG1vbnRoX3llYXIgLiAnLTMxJywgJ21ldGFfa2V5JyA9PiAnX3NhbGVzX2Fzc29jaWF0ZScsICdtZXRhX3ZhbHVlJyA9PiAkYXNzb2NpYXRlX2tleV0pOwogICAgICAgIHJldHVybiBjb3VudCgkb3JkZXJzKSA9PT0gMTsKICAgIH0KICAgIAogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRfbW9udGhseV90b3RhbCgkYXNzb2NpYXRlX2tleSwgJG1vbnRoX3llYXIpIHsKICAgICAgICAkb3JkZXJzID0gd2NfZ2V0X29yZGVycyhbJ2xpbWl0JyA9PiAtMSwgJ3N0YXR1cycgPT4gWydjb21wbGV0ZWQnLCAncHJvY2Vzc2luZyddLCAnZGF0ZV9jcmVhdGVkJyA9PiAkbW9udGhfeWVhciAuICctMDEuLi4nIC4gJG1vbnRoX3llYXIgLiAnLTMxJywgJ21ldGFfa2V5JyA9PiAnX3NhbGVzX2Fzc29jaWF0ZScsICdtZXRhX3ZhbHVlJyA9PiAkYXNzb2NpYXRlX2tleV0pOwogICAgICAgICR0b3RhbCA9IDA7CiAgICAgICAgZm9yZWFjaCAoJG9yZGVycyBhcyAkb3JkZXIpICR0b3RhbCArPSAkb3JkZXItPmdldF9zdWJ0b3RhbCgpOwogICAgICAgIHJldHVybiAkdG90YWw7CiAgICB9CiAgICAKICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0X3NhbGVzX3N0cmVhaygkYXNzb2NpYXRlX2tleSkgewogICAgICAgICRzdHJlYWsgPSAwOwogICAgICAgICRjaGVja19kYXRlID0gbmV3IERhdGVUaW1lKCk7CiAgICAgICAgZm9yICgkaSA9IDA7ICRpIDwgMzA7ICRpKyspIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5nZXRfZGFpbHlfc2FsZXNfY291bnQoJGFzc29jaWF0ZV9rZXksICRjaGVja19kYXRlLT5mb3JtYXQoJ1ktbS1kJykpID4gMCkgJHN0cmVhaysrOwogICAgICAgICAgICBlbHNlIGJyZWFrOwogICAgICAgICAgICAkY2hlY2tfZGF0ZS0+bW9kaWZ5KCctMSBkYXknKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRzdHJlYWs7CiAgICB9CiAgICAKICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0X2RhaWx5X3NhbGVzX2NvdW50KCRhc3NvY2lhdGVfa2V5LCAkZGF0ZSkgewogICAgICAgIHJldHVybiBjb3VudCh3Y19nZXRfb3JkZXJzKFsnbGltaXQnID0+IC0xLCAnc3RhdHVzJyA9PiBbJ2NvbXBsZXRlZCcsICdwcm9jZXNzaW5nJ10sICdkYXRlX2NyZWF0ZWQnID0+ICIkZGF0ZS4uLiRkYXRlIiwgJ21ldGFfa2V5JyA9PiAnX3NhbGVzX2Fzc29jaWF0ZScsICdtZXRhX3ZhbHVlJyA9PiAkYXNzb2NpYXRlX2tleV0pKTsKICAgIH0KICAgIAogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRfbGlmZXRpbWVfb3JkZXJfY291bnQoJGFzc29jaWF0ZV9rZXkpIHsKICAgICAgICByZXR1cm4gY291bnQod2NfZ2V0X29yZGVycyhbJ2xpbWl0JyA9PiAtMSwgJ3N0YXR1cycgPT4gWydjb21wbGV0ZWQnLCAncHJvY2Vzc2luZyddLCAnbWV0YV9rZXknID0+ICdfc2FsZXNfYXNzb2NpYXRlJywgJ21ldGFfdmFsdWUnID0+ICRhc3NvY2lhdGVfa2V5XSkpOwogICAgfQogICAgCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkX3NhbGVzX2Fzc29jaWF0ZV9maWVsZCgkY2hlY2tvdXQgPSBudWxsKSB7CiAgICAgICAgZWNobyAnPGRpdiBpZD0iZmZwLXNhbGVzLWFzc29jaWF0ZS1maWVsZCIgY2xhc3M9ImZmcC1zYWxlcy1maWVsZCI+JzsKICAgICAgICB3b29jb21tZXJjZV9mb3JtX2ZpZWxkKCdzYWxlc19hc3NvY2lhdGUnLCBbJ3R5cGUnID0+ICdzZWxlY3QnLCAnY2xhc3MnID0+IFsnZmZwLXNhbGVzLWFzc29jaWF0ZS1zZWxlY3QgZm9ybS1yb3ctd2lkZSddLCAnbGFiZWwnID0+ICdTYWxlcyBSZXByZXNlbnRhdGl2ZScsICdyZXF1aXJlZCcgPT4gZmFsc2UsICdvcHRpb25zJyA9PiAkdGhpcy0+Z2V0X2Fzc29jaWF0ZV9vcHRpb25zKCldLCBXQygpLT5jaGVja291dC0+Z2V0X3ZhbHVlKCdzYWxlc19hc3NvY2lhdGUnKSk7CiAgICAgICAgZWNobyAnPHAgY2xhc3M9ImZmcC1zYWxlcy1ub3RlIj5Xb3JraW5nIHdpdGggb25lIG9mIG91ciB0ZWFtPyBTZWxlY3QgdGhlbSBzbyB0aGV5IGdldCBjcmVkaXQhPC9wPjwvZGl2Pic7CiAgICAgICAgZWNobyAnPHN0eWxlPiNmZnAtc2FsZXMtYXNzb2NpYXRlLWZpZWxke21hcmdpbi10b3A6MjBweDtwYWRkaW5nOjE1cHg7YmFja2dyb3VuZDpsaW5lYXItZ3JhZGllbnQoMTM1ZGVnLHJnYmEoMCwyMDAsODMsMC4wNSkgMCUscmdiYSgwLDE4MCwyMTYsMC4wNSkgMTAwJSk7Ym9yZGVyOjFweCBzb2xpZCByZ2JhKDAsMjAwLDgzLDAuMik7Ym9yZGVyLXJhZGl1czo4cHh9I2ZmcC1zYWxlcy1hc3NvY2lhdGUtZmllbGQgbGFiZWx7Y29sb3I6IzAwYTg0NCFpbXBvcnRhbnQ7Zm9udC13ZWlnaHQ6NjAwIWltcG9ydGFudH0uZmZwLXNhbGVzLW5vdGV7Zm9udC1zaXplOjEycHg7Y29sb3I6Izg4ODttYXJnaW4tdG9wOjVweDtmb250LXN0eWxlOml0YWxpY308L3N0eWxlPic7CiAgICB9CiAgICAKICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRfZnVubmVsa2l0X2ZpZWxkKCRmaWVsZHMsICRrZXkpIHsKICAgICAgICBpZiAoJGtleSA9PT0gJ2JpbGxpbmcnKSAkZmllbGRzWydzYWxlc19hc3NvY2lhdGUnXSA9IFsndHlwZScgPT4gJ3NlbGVjdCcsICdsYWJlbCcgPT4gJ1NhbGVzIFJlcHJlc2VudGF0aXZlJywgJ3JlcXVpcmVkJyA9PiBmYWxzZSwgJ29wdGlvbnMnID0+ICR0aGlzLT5nZXRfYXNzb2NpYXRlX29wdGlvbnMoKSwgJ3ByaW9yaXR5JyA9PiAxMjBdOwogICAgICAgIHJldHVybiAkZmllbGRzOwogICAgfQogICAgCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldF9hc3NvY2lhdGVfb3B0aW9ucygpIHsKICAgICAgICAkb3B0aW9ucyA9IFsnJyA9PiAnTm9uZSAvIE9ubGluZSBPcmRlciddOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5hc3NvY2lhdGVzIGFzICRrZXkgPT4gJGRhdGEpICRvcHRpb25zWyRrZXldID0gJGRhdGFbJ25hbWUnXTsKICAgICAgICByZXR1cm4gJG9wdGlvbnM7CiAgICB9CiAgICAKICAgIHB1YmxpYyBmdW5jdGlvbiBzYXZlX3NhbGVzX2Fzc29jaWF0ZV9maWVsZCgkb3JkZXJfaWQpIHsKICAgICAgICBpZiAoIWVtcHR5KCRfUE9TVFsnc2FsZXNfYXNzb2NpYXRlJ10pKSB7CiAgICAgICAgICAgICRhc3NvY2lhdGUgPSBzYW5pdGl6ZV90ZXh0X2ZpZWxkKCRfUE9TVFsnc2FsZXNfYXNzb2NpYXRlJ10pOwogICAgICAgICAgICAkb3JkZXIgPSB3Y19nZXRfb3JkZXIoJG9yZGVyX2lkKTsKICAgICAgICAgICAgJG9yZGVyLT51cGRhdGVfbWV0YV9kYXRhKCdfc2FsZXNfYXNzb2NpYXRlJywgJGFzc29jaWF0ZSk7CiAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+YXNzb2NpYXRlc1skYXNzb2NpYXRlXSkgJiYgJHRoaXMtPmFzc29jaWF0ZXNbJGFzc29jaWF0ZV1bJ2NvbW1pc3Npb24nXSkgewogICAgICAgICAgICAgICAgJHJhdGUgPSAkdGhpcy0+YXNzb2NpYXRlc1skYXNzb2NpYXRlXVsncmF0ZSddID8/ICR0aGlzLT5jb21taXNzaW9uX3JhdGU7CiAgICAgICAgICAgICAgICAkb3JkZXItPnVwZGF0ZV9tZXRhX2RhdGEoJ19zYWxlc19jb21taXNzaW9uJywgJG9yZGVyLT5nZXRfc3VidG90YWwoKSAqICRyYXRlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkb3JkZXItPnNhdmUoKTsKICAgICAgICB9CiAgICB9CiAgICAKICAgIHB1YmxpYyBmdW5jdGlvbiBkaXNwbGF5X3NhbGVzX2Fzc29jaWF0ZV9hZG1pbigkb3JkZXIpIHsKICAgICAgICAka2V5ID0gJG9yZGVyLT5nZXRfbWV0YSgnX3NhbGVzX2Fzc29jaWF0ZScpOwogICAgICAgICRjb21tID0gJG9yZGVyLT5nZXRfbWV0YSgnX3NhbGVzX2NvbW1pc3Npb24nKTsKICAgICAgICBpZiAoJGtleSAmJiBpc3NldCgkdGhpcy0+YXNzb2NpYXRlc1ska2V5XSkpIHsKICAgICAgICAgICAgZWNobyAnPHA+PHN0cm9uZz5TYWxlcyBSZXA6PC9zdHJvbmc+ICcgLiBlc2NfaHRtbCgkdGhpcy0+YXNzb2NpYXRlc1ska2V5XVsnbmFtZSddKTsKICAgICAgICAgICAgaWYgKCRjb21tKSBlY2hvICcgPHNwYW4gc3R5bGU9ImNvbG9yOiMwMGM4NTM7Zm9udC13ZWlnaHQ6Ym9sZDsiPigkJyAuIG51bWJlcl9mb3JtYXQoJGNvbW0sIDIpIC4gJyBjb21taXNzaW9uKTwvc3Bhbj4nOwogICAgICAgICAgICBlY2hvICc8L3A+JzsKICAgICAgICB9CiAgICB9CiAgICAKICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRfb3JkZXJfY29sdW1uKCRjb2x1bW5zKSB7CiAgICAgICAgJG5ldyA9IFtdOwogICAgICAgIGZvcmVhY2ggKCRjb2x1bW5zIGFzICRrID0+ICR2KSB7ICRuZXdbJGtdID0gJHY7IGlmICgkayA9PT0gJ29yZGVyX3N0YXR1cycpICRuZXdbJ3NhbGVzX3JlcCddID0gJ1NhbGVzIFJlcCc7IH0KICAgICAgICByZXR1cm4gJG5ldzsKICAgIH0KICAgIAogICAgcHVibGljIGZ1bmN0aW9uIHJlbmRlcl9vcmRlcl9jb2x1bW4oJGNvbHVtbiwgJHBvc3RfaWQpIHsgaWYgKCRjb2x1bW4gPT09ICdzYWxlc19yZXAnKSAkdGhpcy0+cmVuZGVyX3JlcF9iYWRnZSh3Y19nZXRfb3JkZXIoJHBvc3RfaWQpKTsgfQogICAgcHVibGljIGZ1bmN0aW9uIHJlbmRlcl9vcmRlcl9jb2x1bW5faHBvcygkY29sdW1uLCAkb3JkZXIpIHsgaWYgKCRjb2x1bW4gPT09ICdzYWxlc19yZXAnKSAkdGhpcy0+cmVuZGVyX3JlcF9iYWRnZSgkb3JkZXIpOyB9CiAgICAKICAgIHByaXZhdGUgZnVuY3Rpb24gcmVuZGVyX3JlcF9iYWRnZSgkb3JkZXIpIHsKICAgICAgICBpZiAoISRvcmRlcikgcmV0dXJuOwogICAgICAgICRrZXkgPSAkb3JkZXItPmdldF9tZXRhKCdfc2FsZXNfYXNzb2NpYXRlJyk7CiAgICAgICAgaWYgKCRrZXkgJiYgaXNzZXQoJHRoaXMtPmFzc29jaWF0ZXNbJGtleV0pKSB7CiAgICAgICAgICAgICRjb2xvciA9ICR0aGlzLT5hc3NvY2lhdGVzWyRrZXldWydjb21taXNzaW9uJ10gPyAnIzAwYzg1MycgOiAnIzAwYjRkOCc7CiAgICAgICAgICAgIGVjaG8gJzxzcGFuIHN0eWxlPSJiYWNrZ3JvdW5kOicgLiAkY29sb3IgLiAnMjI7Y29sb3I6JyAuICRjb2xvciAuICc7cGFkZGluZzozcHggOHB4O2JvcmRlci1yYWRpdXM6NHB4O2ZvbnQtc2l6ZToxMXB4O2ZvbnQtd2VpZ2h0OjYwMDsiPicgLiBlc2NfaHRtbCgkdGhpcy0+YXNzb2NpYXRlc1ska2V5XVsnbmFtZSddKSAuICc8L3NwYW4+JzsKICAgICAgICB9IGVsc2UgZWNobyAnPHNwYW4gc3R5bGU9ImNvbG9yOiM2NjY7Ij7igJQ8L3NwYW4+JzsKICAgIH0KICAgIAogICAgcHVibGljIGZ1bmN0aW9uIGFkZF9hZG1pbl9tZW51KCkgewogICAgICAgIGFkZF9tZW51X3BhZ2UoJ1NhbGVzIENvbW1pc3Npb24nLCAnU2FsZXMgQ29tbWlzc2lvbicsICdyZWFkJywgJ2ZmcC1jb21taXNzaW9uJywgWyR0aGlzLCAncmVuZGVyX2Rhc2hib2FyZCddLCAnZGFzaGljb25zLWNoYXJ0LWFyZWEnLCA1Nik7CiAgICAgICAgYWRkX3N1Ym1lbnVfcGFnZSgnZmZwLWNvbW1pc3Npb24nLCAnVFYgRGlzcGxheScsICfwn5O6IFRWIERpc3BsYXknLCAncmVhZCcsICdmZnAtY29tbWlzc2lvbi10dicsIFskdGhpcywgJ3JlbmRlcl90dl9tb2RlJ10pOwogICAgICAgIGFkZF9zdWJtZW51X3BhZ2UoJ2ZmcC1jb21taXNzaW9uJywgJ0hlYWQgdG8gSGVhZCcsICfimpTvuI8gSGVhZCB0byBIZWFkJywgJ3JlYWQnLCAnZmZwLWNvbW1pc3Npb24taDJoJywgWyR0aGlzLCAncmVuZGVyX2hlYWRfdG9faGVhZCddKTsKICAgICAgICBhZGRfc3VibWVudV9wYWdlKCdmZnAtY29tbWlzc2lvbicsICdFeHBvcnQnLCAn8J+ThCBFeHBvcnQnLCAnbWFuYWdlX29wdGlvbnMnLCAnZmZwLWNvbW1pc3Npb24tZXhwb3J0JywgWyR0aGlzLCAncmVuZGVyX2V4cG9ydF9wYWdlJ10pOwogICAgfQogICAgCiAgICBwdWJsaWMgZnVuY3Rpb24gYWpheF9nZXRfY29tbWlzc2lvbl9kYXRhKCkgewogICAgICAgIGNoZWNrX2FqYXhfcmVmZXJlcignZmZwX2NvbW1pc3Npb25fbm9uY2UnLCAnbm9uY2UnKTsKICAgICAgICAkc3RhcnQgPSBpc3NldCgkX1BPU1RbJ3N0YXJ0X2RhdGUnXSkgPyBzYW5pdGl6ZV90ZXh0X2ZpZWxkKCRfUE9TVFsnc3RhcnRfZGF0ZSddKSA6IGRhdGUoJ1ktbS0wMScpOwogICAgICAgICRlbmQgPSBpc3NldCgkX1BPU1RbJ2VuZF9kYXRlJ10pID8gc2FuaXRpemVfdGV4dF9maWVsZCgkX1BPU1RbJ2VuZF9kYXRlJ10pIDogZGF0ZSgnWS1tLWQnKTsKICAgICAgICAkZGF0YSA9ICR0aGlzLT5nZXRfY29tbWlzc2lvbl9zdGF0cygkc3RhcnQsICRlbmQpOwogICAgICAgICRkYXRhWydhY2hpZXZlbWVudHMnXSA9ICR0aGlzLT5nZXRfcmVjZW50X2FjaGlldmVtZW50cygpOwogICAgICAgICRkYXRhWydvbl9maXJlJ10gPSAkdGhpcy0+Z2V0X29uX2ZpcmVfcmVwcygpOwogICAgICAgICRkYXRhWydtb250aGx5X2NoYW1waW9uJ10gPSAkdGhpcy0+Z2V0X21vbnRobHlfY2hhbXBpb24oKTsKICAgICAgICB3cF9zZW5kX2pzb25fc3VjY2VzcygkZGF0YSk7CiAgICB9CiAgICAKICAgIHB1YmxpYyBmdW5jdGlvbiBhamF4X2dldF9saXZlX2ZlZWQoKSB7CiAgICAgICAgY2hlY2tfYWpheF9yZWZlcmVyKCdmZnBfY29tbWlzc2lvbl9ub25jZScsICdub25jZScpOwogICAgICAgICRvcmRlcnMgPSB3Y19nZXRfb3JkZXJzKFsnbGltaXQnID0+IDEwLCAnc3RhdHVzJyA9PiBbJ2NvbXBsZXRlZCcsICdwcm9jZXNzaW5nJ10sICdvcmRlcmJ5JyA9PiAnZGF0ZScsICdvcmRlcicgPT4gJ0RFU0MnXSk7CiAgICAgICAgJGZlZWQgPSBbXTsKICAgICAgICBmb3JlYWNoICgkb3JkZXJzIGFzICRvcmRlcikgewogICAgICAgICAgICAka2V5ID0gJG9yZGVyLT5nZXRfbWV0YSgnX3NhbGVzX2Fzc29jaWF0ZScpOwogICAgICAgICAgICAkbmFtZSA9ICgka2V5ICYmIGlzc2V0KCR0aGlzLT5hc3NvY2lhdGVzWyRrZXldKSkgPyAkdGhpcy0+YXNzb2NpYXRlc1ska2V5XVsnbmFtZSddIDogJ09ubGluZSc7CiAgICAgICAgICAgICRpdGVtcyA9ICRvcmRlci0+Z2V0X2l0ZW1zKCk7CiAgICAgICAgICAgICRmaXJzdCA9IHJlc2V0KCRpdGVtcyk7CiAgICAgICAgICAgICRwcm9kdWN0ID0gJGZpcnN0ID8gc3Vic3RyKCRmaXJzdC0+Z2V0X25hbWUoKSwgMCwgNDApIDogJ09yZGVyJzsKICAgICAgICAgICAgJGZlZWRbXSA9IFsnaWQnID0+ICRvcmRlci0+Z2V0X2lkKCksICdyZXAnID0+ICRuYW1lLCAnYW1vdW50JyA9PiAkb3JkZXItPmdldF9zdWJ0b3RhbCgpLCAncHJvZHVjdCcgPT4gJHByb2R1Y3QsICd0aW1lJyA9PiBodW1hbl90aW1lX2RpZmYoJG9yZGVyLT5nZXRfZGF0ZV9jcmVhdGVkKCktPmdldFRpbWVzdGFtcCgpKSAuICcgYWdvJ107CiAgICAgICAgfQogICAgICAgIHdwX3NlbmRfanNvbl9zdWNjZXNzKCRmZWVkKTsKICAgIH0KICAgIAogICAgcHVibGljIGZ1bmN0aW9uIGFqYXhfZ2V0X2FuYWx5dGljcygpIHsKICAgICAgICBjaGVja19hamF4X3JlZmVyZXIoJ2ZmcF9jb21taXNzaW9uX25vbmNlJywgJ25vbmNlJyk7CiAgICAgICAgJHN0YXJ0ID0gaXNzZXQoJF9QT1NUWydzdGFydF9kYXRlJ10pID8gc2FuaXRpemVfdGV4dF9maWVsZCgkX1BPU1RbJ3N0YXJ0X2RhdGUnXSkgOiBkYXRlKCdZLW0tMDEnKTsKICAgICAgICAkZW5kID0gaXNzZXQoJF9QT1NUWydlbmRfZGF0ZSddKSA/IHNhbml0aXplX3RleHRfZmllbGQoJF9QT1NUWydlbmRfZGF0ZSddKSA6IGRhdGUoJ1ktbS1kJyk7CiAgICAgICAgJHNwYXJrbGluZXMgPSBbXTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+YXNzb2NpYXRlcyBhcyAka2V5ID0+ICRhKSAkc3BhcmtsaW5lc1ska2V5XSA9ICR0aGlzLT5nZXRfc3BhcmtsaW5lX2RhdGEoJGtleSk7CiAgICAgICAgd3Bfc2VuZF9qc29uX3N1Y2Nlc3MoWydzcGFya2xpbmVzJyA9PiAkc3BhcmtsaW5lcywgJ2Jlc3Rfc2VsbGVycycgPT4gJHRoaXMtPmdldF9iZXN0X3NlbGxlcnMoJHN0YXJ0LCAkZW5kKSwgJ2hlYXRtYXAnID0+ICR0aGlzLT5nZXRfaGVhdG1hcCgkc3RhcnQsICRlbmQpXSk7CiAgICB9CiAgICAKICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0X3NwYXJrbGluZV9kYXRhKCRrZXkpIHsKICAgICAgICAkZGF0YSA9IFtdOwogICAgICAgIGZvciAoJGkgPSAyOTsgJGkgPj0gMDsgJGktLSkgewogICAgICAgICAgICAkZGF0ZSA9IGRhdGUoJ1ktbS1kJywgc3RydG90aW1lKCItJGkgZGF5cyIpKTsKICAgICAgICAgICAgJG9yZGVycyA9IHdjX2dldF9vcmRlcnMoWydsaW1pdCcgPT4gLTEsICdzdGF0dXMnID0+IFsnY29tcGxldGVkJywgJ3Byb2Nlc3NpbmcnXSwgJ2RhdGVfY3JlYXRlZCcgPT4gIiRkYXRlLi4uJGRhdGUiLCAnbWV0YV9rZXknID0+ICdfc2FsZXNfYXNzb2NpYXRlJywgJ21ldGFfdmFsdWUnID0+ICRrZXldKTsKICAgICAgICAgICAgJHRvdGFsID0gMDsKICAgICAgICAgICAgZm9yZWFjaCAoJG9yZGVycyBhcyAkbykgJHRvdGFsICs9ICRvLT5nZXRfc3VidG90YWwoKTsKICAgICAgICAgICAgJGRhdGFbXSA9ICR0b3RhbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRkYXRhOwogICAgfQogICAgCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldF9iZXN0X3NlbGxlcnMoJHN0YXJ0LCAkZW5kKSB7CiAgICAgICAgJHJlc3VsdHMgPSBbXTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+YXNzb2NpYXRlcyBhcyAka2V5ID0+ICRhKSB7CiAgICAgICAgICAgICRvcmRlcnMgPSB3Y19nZXRfb3JkZXJzKFsnbGltaXQnID0+IC0xLCAnc3RhdHVzJyA9PiBbJ2NvbXBsZXRlZCcsICdwcm9jZXNzaW5nJ10sICdkYXRlX2NyZWF0ZWQnID0+ICIkc3RhcnQuLi4kZW5kIiwgJ21ldGFfa2V5JyA9PiAnX3NhbGVzX2Fzc29jaWF0ZScsICdtZXRhX3ZhbHVlJyA9PiAka2V5XSk7CiAgICAgICAgICAgICRwcm9kdWN0cyA9IFtdOwogICAgICAgICAgICBmb3JlYWNoICgkb3JkZXJzIGFzICRvcmRlcikgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJG9yZGVyLT5nZXRfaXRlbXMoKSBhcyAkaXRlbSkgewogICAgICAgICAgICAgICAgICAgICRwaWQgPSAkaXRlbS0+Z2V0X3Byb2R1Y3RfaWQoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRwcm9kdWN0c1skcGlkXSkpICRwcm9kdWN0c1skcGlkXSA9IFsnbmFtZScgPT4gJGl0ZW0tPmdldF9uYW1lKCksICd0b3RhbCcgPT4gMF07CiAgICAgICAgICAgICAgICAgICAgJHByb2R1Y3RzWyRwaWRdWyd0b3RhbCddICs9ICRpdGVtLT5nZXRfdG90YWwoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB1YXNvcnQoJHByb2R1Y3RzLCBmbigkYSwgJGIpID0+ICRiWyd0b3RhbCddIDw9PiAkYVsndG90YWwnXSk7CiAgICAgICAgICAgICRyZXN1bHRzWyRrZXldID0gYXJyYXlfc2xpY2UoJHByb2R1Y3RzLCAwLCAzLCB0cnVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRyZXN1bHRzOwogICAgfQogICAgCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldF9oZWF0bWFwKCRzdGFydCwgJGVuZCkgewogICAgICAgICRoZWF0bWFwID0gYXJyYXlfZmlsbCgwLCA3LCBhcnJheV9maWxsKDAsIDI0LCAwKSk7CiAgICAgICAgJG9yZGVycyA9IHdjX2dldF9vcmRlcnMoWydsaW1pdCcgPT4gLTEsICdzdGF0dXMnID0+IFsnY29tcGxldGVkJywgJ3Byb2Nlc3NpbmcnXSwgJ2RhdGVfY3JlYXRlZCcgPT4gIiRzdGFydC4uLiRlbmQiXSk7CiAgICAgICAgZm9yZWFjaCAoJG9yZGVycyBhcyAkb3JkZXIpIHsKICAgICAgICAgICAgJGQgPSAkb3JkZXItPmdldF9kYXRlX2NyZWF0ZWQoKTsKICAgICAgICAgICAgJGhlYXRtYXBbKGludCkkZC0+Zm9ybWF0KCdOJykgLSAxXVsoaW50KSRkLT5mb3JtYXQoJ0cnKV0gKz0gJG9yZGVyLT5nZXRfc3VidG90YWwoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRoZWF0bWFwOwogICAgfQogICAgCiAgICBwdWJsaWMgZnVuY3Rpb24gYWpheF9nZXRfaGVhZF90b19oZWFkKCkgewogICAgICAgIGNoZWNrX2FqYXhfcmVmZXJlcignZmZwX2NvbW1pc3Npb25fbm9uY2UnLCAnbm9uY2UnKTsKICAgICAgICAkcmVwMSA9IHNhbml0aXplX3RleHRfZmllbGQoJF9QT1NUWydyZXAxJ10pOwogICAgICAgICRyZXAyID0gc2FuaXRpemVfdGV4dF9maWVsZCgkX1BPU1RbJ3JlcDInXSk7CiAgICAgICAgJHN0YXJ0ID0gaXNzZXQoJF9QT1NUWydzdGFydF9kYXRlJ10pID8gc2FuaXRpemVfdGV4dF9maWVsZCgkX1BPU1RbJ3N0YXJ0X2RhdGUnXSkgOiBkYXRlKCdZLW0tMDEnKTsKICAgICAgICAkZW5kID0gaXNzZXQoJF9QT1NUWydlbmRfZGF0ZSddKSA/IHNhbml0aXplX3RleHRfZmllbGQoJF9QT1NUWydlbmRfZGF0ZSddKSA6IGRhdGUoJ1ktbS1kJyk7CiAgICAgICAgd3Bfc2VuZF9qc29uX3N1Y2Nlc3MoWydyZXAxJyA9PiAkdGhpcy0+Z2V0X3JlcF9zdGF0cygkcmVwMSwgJHN0YXJ0LCAkZW5kKSwgJ3JlcDInID0+ICR0aGlzLT5nZXRfcmVwX3N0YXRzKCRyZXAyLCAkc3RhcnQsICRlbmQpXSk7CiAgICB9CiAgICAKICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0X3JlcF9zdGF0cygka2V5LCAkc3RhcnQsICRlbmQpIHsKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5hc3NvY2lhdGVzWyRrZXldKSkgcmV0dXJuIG51bGw7CiAgICAgICAgJG9yZGVycyA9IHdjX2dldF9vcmRlcnMoWydsaW1pdCcgPT4gLTEsICdzdGF0dXMnID0+IFsnY29tcGxldGVkJywgJ3Byb2Nlc3NpbmcnXSwgJ2RhdGVfY3JlYXRlZCcgPT4gIiRzdGFydC4uLiRlbmQiLCAnbWV0YV9rZXknID0+ICdfc2FsZXNfYXNzb2NpYXRlJywgJ21ldGFfdmFsdWUnID0+ICRrZXldKTsKICAgICAgICAkdG90YWwgPSAwOyAkaGlnaGVzdCA9IDA7CiAgICAgICAgZm9yZWFjaCAoJG9yZGVycyBhcyAkbykgeyAkcyA9ICRvLT5nZXRfc3VidG90YWwoKTsgJHRvdGFsICs9ICRzOyBpZiAoJHMgPiAkaGlnaGVzdCkgJGhpZ2hlc3QgPSAkczsgfQogICAgICAgICRjb3VudCA9IGNvdW50KCRvcmRlcnMpOwogICAgICAgIHJldHVybiBbJ25hbWUnID0+ICR0aGlzLT5hc3NvY2lhdGVzWyRrZXldWyduYW1lJ10sICdyb2xlJyA9PiAkdGhpcy0+YXNzb2NpYXRlc1ska2V5XVsncm9sZSddLCAndG90YWwnID0+ICR0b3RhbCwgJ29yZGVycycgPT4gJGNvdW50LCAnYW92JyA9PiAkY291bnQgPiAwID8gJHRvdGFsIC8gJGNvdW50IDogMCwgJ2hpZ2hlc3QnID0+ICRoaWdoZXN0LCAnc3RyZWFrJyA9PiAkdGhpcy0+Z2V0X3NhbGVzX3N0cmVhaygka2V5KV07CiAgICB9CiAgICAKICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0X3JlY2VudF9hY2hpZXZlbWVudHMoKSB7CiAgICAgICAgZ2xvYmFsICR3cGRiOwogICAgICAgICR0YWJsZSA9ICR3cGRiLT5wcmVmaXggLiAnZmZwX2FjaGlldmVtZW50cyc7CiAgICAgICAgJHJvd3MgPSAkd3BkYi0+Z2V0X3Jlc3VsdHMoIlNFTEVDVCAqIEZST00gJHRhYmxlIE9SREVSIEJZIGVhcm5lZF9hdCBERVNDIExJTUlUIDEwIik7CiAgICAgICAgJGFjaGlldmVtZW50cyA9IFtdOwogICAgICAgIGZvcmVhY2ggKCRyb3dzIGFzICRyKSB7CiAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+YWNoaWV2ZW1lbnRzWyRyLT5hY2hpZXZlbWVudF9rZXldKSAmJiBpc3NldCgkdGhpcy0+YXNzb2NpYXRlc1skci0+YXNzb2NpYXRlX2tleV0pKSB7CiAgICAgICAgICAgICAgICAkYWNoaWV2ZW1lbnRzW10gPSBbJ3JlcCcgPT4gJHRoaXMtPmFzc29jaWF0ZXNbJHItPmFzc29jaWF0ZV9rZXldWyduYW1lJ10sICdhY2hpZXZlbWVudCcgPT4gJHRoaXMtPmFjaGlldmVtZW50c1skci0+YWNoaWV2ZW1lbnRfa2V5XSwgJ3RpbWUnID0+IGh1bWFuX3RpbWVfZGlmZihzdHJ0b3RpbWUoJHItPmVhcm5lZF9hdCkpIC4gJyBhZ28nXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gJGFjaGlldmVtZW50czsKICAgIH0KICAgIAogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRfb25fZmlyZV9yZXBzKCkgewogICAgICAgICRmaXJlID0gW107CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmFzc29jaWF0ZXMgYXMgJGtleSA9PiAkYSkgeyAkc3RyZWFrID0gJHRoaXMtPmdldF9zYWxlc19zdHJlYWsoJGtleSk7IGlmICgkc3RyZWFrID49IDMpICRmaXJlWyRrZXldID0gJHN0cmVhazsgfQogICAgICAgIHJldHVybiAkZmlyZTsKICAgIH0KICAgIAogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRfbW9udGhseV9jaGFtcGlvbigpIHsKICAgICAgICAkbGFzdCA9IGRhdGUoJ1ktbScsIHN0cnRvdGltZSgnLTEgbW9udGgnKSk7CiAgICAgICAgJGNoYW1wID0gbnVsbDsgJGhpZ2ggPSAwOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5hc3NvY2lhdGVzIGFzICRrZXkgPT4gJGEpIHsgJHQgPSAkdGhpcy0+Z2V0X21vbnRobHlfdG90YWwoJGtleSwgJGxhc3QpOyBpZiAoJHQgPiAkaGlnaCkgeyAkaGlnaCA9ICR0OyAkY2hhbXAgPSAka2V5OyB9IH0KICAgICAgICByZXR1cm4gJGNoYW1wOwogICAgfQogICAgCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldF9jb21taXNzaW9uX3N0YXRzKCRzdGFydCwgJGVuZCkgewogICAgICAgICRzdGF0cyA9IFtdOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5hc3NvY2lhdGVzIGFzICRrZXkgPT4gJGEpICRzdGF0c1ska2V5XSA9IFsnbmFtZScgPT4gJGFbJ25hbWUnXSwgJ3JvbGUnID0+ICRhWydyb2xlJ10sICdlYXJuc19jb21taXNzaW9uJyA9PiAkYVsnY29tbWlzc2lvbiddLCAncmF0ZScgPT4gJGFbJ3JhdGUnXSwgJ29yZGVyX2NvdW50JyA9PiAwLCAndG90YWxfc2FsZXMnID0+IDAsICdjb21taXNzaW9uX2Vhcm5lZCcgPT4gMF07CiAgICAgICAgJHN0YXRzWydvbmxpbmUnXSA9IFsnbmFtZScgPT4gJ09ubGluZSAoTm8gUmVwKScsICdyb2xlJyA9PiAnRGlyZWN0JywgJ2Vhcm5zX2NvbW1pc3Npb24nID0+IGZhbHNlLCAncmF0ZScgPT4gMCwgJ29yZGVyX2NvdW50JyA9PiAwLCAndG90YWxfc2FsZXMnID0+IDAsICdjb21taXNzaW9uX2Vhcm5lZCcgPT4gMF07CiAgICAgICAgCiAgICAgICAgJG9yZGVycyA9IHdjX2dldF9vcmRlcnMoWydsaW1pdCcgPT4gLTEsICdzdGF0dXMnID0+IFsnY29tcGxldGVkJywgJ3Byb2Nlc3NpbmcnXSwgJ2RhdGVfY3JlYXRlZCcgPT4gIiRzdGFydC4uLiRlbmQiXSk7CiAgICAgICAgJHRvdGFsX3NhbGVzID0gMDsgJHRvdGFsX2NvbW1pc3Npb24gPSAwOwogICAgICAgIAogICAgICAgIGZvcmVhY2ggKCRvcmRlcnMgYXMgJG9yZGVyKSB7CiAgICAgICAgICAgICRrZXkgPSAkb3JkZXItPmdldF9tZXRhKCdfc2FsZXNfYXNzb2NpYXRlJyk7CiAgICAgICAgICAgICRzdWJ0b3RhbCA9ICRvcmRlci0+Z2V0X3N1YnRvdGFsKCk7CiAgICAgICAgICAgIGlmIChlbXB0eSgka2V5KSB8fCAhaXNzZXQoJHN0YXRzWyRrZXldKSkgJGtleSA9ICdvbmxpbmUnOwogICAgICAgICAgICAkc3RhdHNbJGtleV1bJ29yZGVyX2NvdW50J10rKzsKICAgICAgICAgICAgJHN0YXRzWyRrZXldWyd0b3RhbF9zYWxlcyddICs9ICRzdWJ0b3RhbDsKICAgICAgICAgICAgJHRvdGFsX3NhbGVzICs9ICRzdWJ0b3RhbDsKICAgICAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5hc3NvY2lhdGVzWyRrZXldKSAmJiAkdGhpcy0+YXNzb2NpYXRlc1ska2V5XVsnY29tbWlzc2lvbiddKSB7CiAgICAgICAgICAgICAgICAkY29tbSA9ICRzdWJ0b3RhbCAqICgkdGhpcy0+YXNzb2NpYXRlc1ska2V5XVsncmF0ZSddID8/ICR0aGlzLT5jb21taXNzaW9uX3JhdGUpOwogICAgICAgICAgICAgICAgJHN0YXRzWyRrZXldWydjb21taXNzaW9uX2Vhcm5lZCddICs9ICRjb21tOwogICAgICAgICAgICAgICAgJHRvdGFsX2NvbW1pc3Npb24gKz0gJGNvbW07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWFzb3J0KCRzdGF0cywgZm4oJGEsICRiKSA9PiAkYlsndG90YWxfc2FsZXMnXSA8PT4gJGFbJ3RvdGFsX3NhbGVzJ10pOwogICAgICAgIHJldHVybiBbJ2Fzc29jaWF0ZXMnID0+ICRzdGF0cywgJ3RvdGFsX3NhbGVzJyA9PiAkdG90YWxfc2FsZXMsICd0b3RhbF9jb21taXNzaW9uJyA9PiAkdG90YWxfY29tbWlzc2lvbiwgJ29yZGVyX2NvdW50JyA9PiBjb3VudCgkb3JkZXJzKV07CiAgICB9CiAgICAKICAgIHB1YmxpYyBmdW5jdGlvbiBhamF4X2V4cG9ydF9jb21taXNzaW9uKCkgewogICAgICAgIGNoZWNrX2FqYXhfcmVmZXJlcignZmZwX2NvbW1pc3Npb25fbm9uY2UnLCAnbm9uY2UnKTsKICAgICAgICBpZiAoIWN1cnJlbnRfdXNlcl9jYW4oJ21hbmFnZV9vcHRpb25zJykpIHdwX2RpZSgnVW5hdXRob3JpemVkJyk7CiAgICAgICAgJGRhdGEgPSAkdGhpcy0+Z2V0X2NvbW1pc3Npb25fc3RhdHMoc2FuaXRpemVfdGV4dF9maWVsZCgkX0dFVFsnc3RhcnRfZGF0ZSddKSwgc2FuaXRpemVfdGV4dF9maWVsZCgkX0dFVFsnZW5kX2RhdGUnXSkpOwogICAgICAgIGhlYWRlcignQ29udGVudC1UeXBlOiB0ZXh0L2NzdicpOwogICAgICAgIGhlYWRlcignQ29udGVudC1EaXNwb3NpdGlvbjogYXR0YWNobWVudDsgZmlsZW5hbWU9ImZmcC1jb21taXNzaW9uLScgLiAkX0dFVFsnc3RhcnRfZGF0ZSddIC4gJy10by0nIC4gJF9HRVRbJ2VuZF9kYXRlJ10gLiAnLmNzdiInKTsKICAgICAgICAkb3V0ID0gZm9wZW4oJ3BocDovL291dHB1dCcsICd3Jyk7CiAgICAgICAgZnB1dGNzdigkb3V0LCBbJ05hbWUnLCAnUm9sZScsICdPcmRlcnMnLCAnVG90YWwgU2FsZXMnLCAnQ29tbWlzc2lvbiBSYXRlJywgJ0NvbW1pc3Npb24gRWFybmVkJ10pOwogICAgICAgIGZvcmVhY2ggKCRkYXRhWydhc3NvY2lhdGVzJ10gYXMgJGEpIGZwdXRjc3YoJG91dCwgWyRhWyduYW1lJ10sICRhWydyb2xlJ10sICRhWydvcmRlcl9jb3VudCddLCAnJCcgLiBudW1iZXJfZm9ybWF0KCRhWyd0b3RhbF9zYWxlcyddLCAyKSwgJGFbJ2Vhcm5zX2NvbW1pc3Npb24nXSA/ICgkYVsncmF0ZSddICogMTAwKSAuICclJyA6ICdOL0EnLCAkYVsnZWFybnNfY29tbWlzc2lvbiddID8gJyQnIC4gbnVtYmVyX2Zvcm1hdCgkYVsnY29tbWlzc2lvbl9lYXJuZWQnXSwgMikgOiAnTi9BJ10pOwogICAgICAgIGZwdXRjc3YoJG91dCwgW10pOwogICAgICAgIGZwdXRjc3YoJG91dCwgWydUT1RBTFMnLCAnJywgJGRhdGFbJ29yZGVyX2NvdW50J10sICckJyAuIG51bWJlcl9mb3JtYXQoJGRhdGFbJ3RvdGFsX3NhbGVzJ10sIDIpLCAnJywgJyQnIC4gbnVtYmVyX2Zvcm1hdCgkZGF0YVsndG90YWxfY29tbWlzc2lvbiddLCAyKV0pOwogICAgICAgIGZjbG9zZSgkb3V0KTsKICAgICAgICBleGl0OwogICAgfQogICAgCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVuZGVyX2V4cG9ydF9wYWdlKCkgewogICAgICAgIGVjaG8gJzxkaXYgY2xhc3M9IndyYXAiPjxoMT7wn5OEIEV4cG9ydCBDb21taXNzaW9uIERhdGE8L2gxPjxkaXYgc3R5bGU9ImJhY2tncm91bmQ6I2ZmZjtwYWRkaW5nOjMwcHg7Ym9yZGVyLXJhZGl1czoxMnB4O2JveC1zaGFkb3c6MCAycHggMTBweCByZ2JhKDAsMCwwLDAuMSk7bWF4LXdpZHRoOjUwMHB4O21hcmdpbi10b3A6MjBweDsiPjxmb3JtIG1ldGhvZD0iZ2V0IiBhY3Rpb249IicgLiBhZG1pbl91cmwoJ2FkbWluLWFqYXgucGhwJykgLiAnIj48aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJhY3Rpb24iIHZhbHVlPSJmZnBfZXhwb3J0X2NvbW1pc3Npb24iPjxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9Im5vbmNlIiB2YWx1ZT0iJyAuIHdwX2NyZWF0ZV9ub25jZSgnZmZwX2NvbW1pc3Npb25fbm9uY2UnKSAuICciPjxwPjxsYWJlbD48c3Ryb25nPlN0YXJ0IERhdGU8L3N0cm9uZz48L2xhYmVsPjxicj48aW5wdXQgdHlwZT0iZGF0ZSIgbmFtZT0ic3RhcnRfZGF0ZSIgdmFsdWU9IicgLiBkYXRlKCdZLW0tMDEnKSAuICciIHN0eWxlPSJ3aWR0aDoxMDAlO3BhZGRpbmc6MTBweDtib3JkZXItcmFkaXVzOjhweDtib3JkZXI6MXB4IHNvbGlkICNkZGQ7Ij48L3A+PHA+PGxhYmVsPjxzdHJvbmc+RW5kIERhdGU8L3N0cm9uZz48L2xhYmVsPjxicj48aW5wdXQgdHlwZT0iZGF0ZSIgbmFtZT0iZW5kX2RhdGUiIHZhbHVlPSInIC4gZGF0ZSgnWS1tLWQnKSAuICciIHN0eWxlPSJ3aWR0aDoxMDAlO3BhZGRpbmc6MTBweDtib3JkZXItcmFkaXVzOjhweDtib3JkZXI6MXB4IHNvbGlkICNkZGQ7Ij48L3A+PHA+PGJ1dHRvbiB0eXBlPSJzdWJtaXQiIHN0eWxlPSJiYWNrZ3JvdW5kOmxpbmVhci1ncmFkaWVudCgxMzVkZWcsIzAwYzg1MywjMDBiNGQ4KTtjb2xvcjojZmZmO2JvcmRlcjpub25lO3BhZGRpbmc6MTVweCAzMHB4O2JvcmRlci1yYWRpdXM6MTBweDtmb250LXdlaWdodDo3MDA7Y3Vyc29yOnBvaW50ZXI7d2lkdGg6MTAwJTsiPuKsh++4jyBEb3dubG9hZCBDU1Y8L2J1dHRvbj48L3A+PC9mb3JtPjwvZGl2PjwvZGl2Pic7CiAgICB9CiAgICAKICAgIHB1YmxpYyBmdW5jdGlvbiByZW5kZXJfaGVhZF90b19oZWFkKCkgewogICAgICAgICRub25jZSA9IHdwX2NyZWF0ZV9ub25jZSgnZmZwX2NvbW1pc3Npb25fbm9uY2UnKTsKICAgICAgICBlY2hvICc8ZGl2IGNsYXNzPSJ3cmFwIj48aDE+4pqU77iPIEhlYWQgdG8gSGVhZDwvaDE+PGRpdiBzdHlsZT0iYmFja2dyb3VuZDojZmZmO3BhZGRpbmc6MzBweDtib3JkZXItcmFkaXVzOjE2cHg7Ym94LXNoYWRvdzowIDRweCAyMHB4IHJnYmEoMCwwLDAsMC4xKTttYXJnaW4tdG9wOjIwcHg7Ij48ZGl2IHN0eWxlPSJkaXNwbGF5OmZsZXg7Z2FwOjIwcHg7bWFyZ2luLWJvdHRvbTozMHB4O2ZsZXgtd3JhcDp3cmFwO2FsaWduLWl0ZW1zOmNlbnRlcjsiPjxzZWxlY3QgaWQ9ImgyaC1yZXAxIiBzdHlsZT0icGFkZGluZzoxMnB4O2JvcmRlci1yYWRpdXM6OHB4O2JvcmRlcjoycHggc29saWQgI2UwZTBlMDtmb250LXNpemU6MTZweDsiPic7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmFzc29jaWF0ZXMgYXMgJGsgPT4gJGEpIGVjaG8gJzxvcHRpb24gdmFsdWU9IicgLiAkayAuICciPicgLiAkYVsnbmFtZSddIC4gJzwvb3B0aW9uPic7CiAgICAgICAgZWNobyAnPC9zZWxlY3Q+PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZTozMnB4O2ZvbnQtd2VpZ2h0OjgwMDtjb2xvcjojOGI1Y2Y2OyI+VlM8L3NwYW4+PHNlbGVjdCBpZD0iaDJoLXJlcDIiIHN0eWxlPSJwYWRkaW5nOjEycHg7Ym9yZGVyLXJhZGl1czo4cHg7Ym9yZGVyOjJweCBzb2xpZCAjZTBlMGUwO2ZvbnQtc2l6ZToxNnB4OyI+JzsKICAgICAgICAkaSA9IDA7IGZvcmVhY2ggKCR0aGlzLT5hc3NvY2lhdGVzIGFzICRrID0+ICRhKSB7IGVjaG8gJzxvcHRpb24gdmFsdWU9IicgLiAkayAuICciJyAuICgkaSA9PT0gMSA/ICcgc2VsZWN0ZWQnIDogJycpIC4gJz4nIC4gJGFbJ25hbWUnXSAuICc8L29wdGlvbj4nOyAkaSsrOyB9CiAgICAgICAgZWNobyAnPC9zZWxlY3Q+PGJ1dHRvbiBpZD0iaDJoLWNvbXBhcmUiIHN0eWxlPSJiYWNrZ3JvdW5kOmxpbmVhci1ncmFkaWVudCgxMzVkZWcsIzAwYzg1MywjMDBiNGQ4KTtjb2xvcjojZmZmO2JvcmRlcjpub25lO3BhZGRpbmc6MTJweCAzMHB4O2JvcmRlci1yYWRpdXM6MTBweDtmb250LXdlaWdodDo3MDA7Y3Vyc29yOnBvaW50ZXI7Ij5Db21wYXJlPC9idXR0b24+PC9kaXY+PGRpdiBpZD0iaDJoLXJlc3VsdHMiIHN0eWxlPSJkaXNwbGF5OmdyaWQ7Z3JpZC10ZW1wbGF0ZS1jb2x1bW5zOjFmciAxZnI7Z2FwOjMwcHg7Ij48ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOmNlbnRlcjtwYWRkaW5nOjQwcHg7YmFja2dyb3VuZDojZjhmOWZhO2JvcmRlci1yYWRpdXM6MTJweDsiPlNlbGVjdCByZXBzIGFuZCBjbGljayBDb21wYXJlPC9kaXY+PGRpdj48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj4nOwogICAgICAgIGVjaG8gJzxzY3JpcHQ+alF1ZXJ5KGZ1bmN0aW9uKCQpeyQoIiNoMmgtY29tcGFyZSIpLm9uKCJjbGljayIsZnVuY3Rpb24oKXskLnBvc3QoYWpheHVybCx7YWN0aW9uOiJmZnBfZ2V0X2hlYWRfdG9faGVhZCIsbm9uY2U6IicgLiAkbm9uY2UgLiAnIixyZXAxOiQoIiNoMmgtcmVwMSIpLnZhbCgpLHJlcDI6JCgiI2gyaC1yZXAyIikudmFsKCl9LGZ1bmN0aW9uKHIpe2lmKHIuc3VjY2Vzcyl7Y29uc3QgZD1yLmRhdGE7bGV0IGh0bWw9IiI7W2QucmVwMSxkLnJlcDJdLmZvckVhY2goKHJlcCxpKT0+e2NvbnN0IHdpbnM9W107aWYoaT09PTApe2lmKGQucmVwMS50b3RhbD5kLnJlcDIudG90YWwpd2lucy5wdXNoKCJ0b3RhbCIpO2lmKGQucmVwMS5vcmRlcnM+ZC5yZXAyLm9yZGVycyl3aW5zLnB1c2goIm9yZGVycyIpO2lmKGQucmVwMS5hb3Y+ZC5yZXAyLmFvdil3aW5zLnB1c2goImFvdiIpO2lmKGQucmVwMS5oaWdoZXN0PmQucmVwMi5oaWdoZXN0KXdpbnMucHVzaCgiaGlnaGVzdCIpO2lmKGQucmVwMS5zdHJlYWs+ZC5yZXAyLnN0cmVhayl3aW5zLnB1c2goInN0cmVhayIpO31lbHNle2lmKGQucmVwMi50b3RhbD5kLnJlcDEudG90YWwpd2lucy5wdXNoKCJ0b3RhbCIpO2lmKGQucmVwMi5vcmRlcnM+ZC5yZXAxLm9yZGVycyl3aW5zLnB1c2goIm9yZGVycyIpO2lmKGQucmVwMi5hb3Y+ZC5yZXAxLmFvdil3aW5zLnB1c2goImFvdiIpO2lmKGQucmVwMi5oaWdoZXN0PmQucmVwMS5oaWdoZXN0KXdpbnMucHVzaCgiaGlnaGVzdCIpO2lmKGQucmVwMi5zdHJlYWs+ZC5yZXAxLnN0cmVhayl3aW5zLnB1c2goInN0cmVhayIpO31odG1sKz1gPGRpdiBzdHlsZT0iYmFja2dyb3VuZDpsaW5lYXItZ3JhZGllbnQoMTM1ZGVnLCR7d2lucy5sZW5ndGg+Mj8icmdiYSgwLDIwMCw4MywwLjEpIjoiI2Y4ZjlmYSJ9LCNmZmYpO3BhZGRpbmc6MzBweDtib3JkZXItcmFkaXVzOjE2cHg7Ym9yZGVyOjJweCBzb2xpZCAke3dpbnMubGVuZ3RoPjI/IiMwMGM4NTMiOiIjZTBlMGUwIn07Ij48aDIgc3R5bGU9Im1hcmdpbjowIDAgNXB4IDA7Zm9udC1zaXplOjI4cHg7Ij4ke3JlcC5uYW1lfTwvaDI+PHAgc3R5bGU9ImNvbG9yOiM4ODg7bWFyZ2luOjAgMCAyMHB4IDA7Ij4ke3JlcC5yb2xlfTwvcD48ZGl2IHN0eWxlPSJmb250LXNpemU6MzZweDtmb250LXdlaWdodDo4MDA7Y29sb3I6IzAwYzg1MzttYXJnaW4tYm90dG9tOjIwcHg7Ij4kJHtyZXAudG90YWwudG9Mb2NhbGVTdHJpbmcoImVuLVVTIix7bWluaW11bUZyYWN0aW9uRGlnaXRzOjJ9KX08L2Rpdj48ZGl2IHN0eWxlPSJkaXNwbGF5OmdyaWQ7Z2FwOjEwcHg7Ij48ZGl2IHN0eWxlPSJkaXNwbGF5OmZsZXg7anVzdGlmeS1jb250ZW50OnNwYWNlLWJldHdlZW47cGFkZGluZzoxMHB4O2JhY2tncm91bmQ6JHt3aW5zLmluY2x1ZGVzKCJvcmRlcnMiKT8icmdiYSgwLDIwMCw4MywwLjEpIjoiI2Y4ZjlmYSJ9O2JvcmRlci1yYWRpdXM6OHB4OyI+PHNwYW4+T3JkZXJzPC9zcGFuPjxzdHJvbmc+JHtyZXAub3JkZXJzfTwvc3Ryb25nPjwvZGl2PjxkaXYgc3R5bGU9ImRpc3BsYXk6ZmxleDtqdXN0aWZ5LWNvbnRlbnQ6c3BhY2UtYmV0d2VlbjtwYWRkaW5nOjEwcHg7YmFja2dyb3VuZDoke3dpbnMuaW5jbHVkZXMoImFvdiIpPyJyZ2JhKDAsMjAwLDgzLDAuMSkiOiIjZjhmOWZhIn07Ym9yZGVyLXJhZGl1czo4cHg7Ij48c3Bhbj5BdmcgT3JkZXI8L3NwYW4+PHN0cm9uZz4kJHtyZXAuYW92LnRvTG9jYWxlU3RyaW5nKCJlbi1VUyIse21pbmltdW1GcmFjdGlvbkRpZ2l0czoyfSl9PC9zdHJvbmc+PC9kaXY+PGRpdiBzdHlsZT0iZGlzcGxheTpmbGV4O2p1c3RpZnktY29udGVudDpzcGFjZS1iZXR3ZWVuO3BhZGRpbmc6MTBweDtiYWNrZ3JvdW5kOiR7d2lucy5pbmNsdWRlcygiaGlnaGVzdCIpPyJyZ2JhKDAsMjAwLDgzLDAuMSkiOiIjZjhmOWZhIn07Ym9yZGVyLXJhZGl1czo4cHg7Ij48c3Bhbj5IaWdoZXN0PC9zcGFuPjxzdHJvbmc+JCR7cmVwLmhpZ2hlc3QudG9Mb2NhbGVTdHJpbmcoImVuLVVTIix7bWluaW11bUZyYWN0aW9uRGlnaXRzOjJ9KX08L3N0cm9uZz48L2Rpdj48ZGl2IHN0eWxlPSJkaXNwbGF5OmZsZXg7anVzdGlmeS1jb250ZW50OnNwYWNlLWJldHdlZW47cGFkZGluZzoxMHB4O2JhY2tncm91bmQ6JHt3aW5zLmluY2x1ZGVzKCJzdHJlYWsiKT8icmdiYSgwLDIwMCw4MywwLjEpIjoiI2Y4ZjlmYSJ9O2JvcmRlci1yYWRpdXM6OHB4OyI+PHNwYW4+U3RyZWFrPC9zcGFuPjxzdHJvbmc+JHtyZXAuc3RyZWFrfSBkYXlzPC9zdHJvbmc+PC9kaXY+PC9kaXY+PC9kaXY+YDt9KTskKCIjaDJoLXJlc3VsdHMiKS5odG1sKGh0bWwpO319KTt9KTt9KTs8L3NjcmlwdD4nOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiByZW5kZXJfZGFzaGJvYXJkKCkgewogICAgICAgICRkZWZhdWx0X3N0YXJ0ID0gZGF0ZSgnWS1tLTAxJyk7CiAgICAgICAgJGRlZmF1bHRfZW5kID0gZGF0ZSgnWS1tLWQnKTsKICAgICAgICAkaW5pdGlhbF9kYXRhID0gJHRoaXMtPmdldF9jb21taXNzaW9uX3N0YXRzKCRkZWZhdWx0X3N0YXJ0LCAkZGVmYXVsdF9lbmQpOwogICAgICAgICRpbml0aWFsX2RhdGFbJ29uX2ZpcmUnXSA9ICR0aGlzLT5nZXRfb25fZmlyZV9yZXBzKCk7CiAgICAgICAgJGluaXRpYWxfZGF0YVsnbW9udGhseV9jaGFtcGlvbiddID0gJHRoaXMtPmdldF9tb250aGx5X2NoYW1waW9uKCk7CiAgICAgICAgJGluaXRpYWxfZGF0YVsnYWNoaWV2ZW1lbnRzJ10gPSAkdGhpcy0+Z2V0X3JlY2VudF9hY2hpZXZlbWVudHMoKTsKICAgICAgICBpbmNsdWRlKHBsdWdpbl9kaXJfcGF0aChfX0ZJTEVfXykgLiAndGVtcGxhdGVzL2Rhc2hib2FyZC5waHAnKTsKICAgIH0KICAgIAogICAgcHVibGljIGZ1bmN0aW9uIHJlbmRlcl90dl9tb2RlKCkgewogICAgICAgICRkYXRhID0gJHRoaXMtPmdldF9jb21taXNzaW9uX3N0YXRzKGRhdGUoJ1ktbS0wMScpLCBkYXRlKCdZLW0tZCcpKTsKICAgICAgICAkZGF0YVsnb25fZmlyZSddID0gJHRoaXMtPmdldF9vbl9maXJlX3JlcHMoKTsKICAgICAgICBpbmNsdWRlKHBsdWdpbl9kaXJfcGF0aChfX0ZJTEVfXykgLiAndGVtcGxhdGVzL3R2LW1vZGUucGhwJyk7CiAgICAgICAgZXhpdDsKICAgIH0KfQoKbmV3IEZGUF9TYWxlc19Db21taXNzaW9uX1RyYWNrZXIoKTsK RTR 2024-2025 Ford Mustang Chin Splitter | 11011.0004.12.A - Function Factory Performance
Our favorite time of the year. USE CODE: FULLSEND25 |  Call 805-267-9762 to connect with an expert.
🎉 New Year Sale Start 2026 with Free Shipping + Exclusive Deals FULLSEND25 📞 805-267-9762

RTR 2024-2025 Ford Mustang Chin Splitter

  • Fits 2024+ Mustang EcoBoost & GT
  • Modern aggressive design
  • Satin black finish
  • Made from durable, injection-molded ASA plastic
  • RTR Undertray Extension is not required but recommended
  • Straight forward installation – no cutting required
  • Due to package dimensions – this item has a $100 Handling Fee
$399.99

Available

Category: SKU: 11011.0004.12.A

The RTR Chin Splitter is now available for the 2024+ Mustang EcoBoost and GT models! Our modern, aggressive design will give your S650 Mustang an all-new look. It’s made from durable, injection-molded ASA plastic for durability and finished in an automotive-grade Satin Black paint for added resistance to the elements. Plus, you can choose to install the RTR Undertray Extension for further customization.

The optional RTR Undertray Extension smooths airflow between the RTR Chin Splitter and OEM Belly Pan to further enhance lift reduction and added stiffness.

Installation is easy with no cutting required—all you need are basic hand tools to get the job done quickly. Upgrade your Mustang with the RTR Chin Splitter today.

FITMENT GUIDE

Year Model
2024+ Ford® Mustang EcoBoost, GT

First Class Customer Service & Satisfaction.

At Function Factory Performance, customer service is our top priority. We know that finding the right parts can be overwhelming, so we’re here to make the process smooth and enjoyable. We’re always ahead of the curve with our commitment to education and awareness. Let’s make this experience simple and awesome together! Don’t hesitate to call us at (480) 576-8606 or click here to reach us via email.

Make sure to follow us on Instagram: @FFPerformanceAZ and Youtube.

EMAIL A FACTORY SPECIALIST FOR HELP CALL A FACTORY SPECIALIST NOW

Reviews

There are no reviews yet

Be the first to review “RTR 2024-2025 Ford Mustang Chin Splitter”

Your email address will not be published. Required fields are marked *

💡 Quick Answers

FREQUENTLY ASKED QUESTIONS

📦 How long does it take for my parts to ship? +

If it's in stock and ready to roll, your order usually hits the road within 1–3 business days.

For made-to-order or specialty items (like carbon fiber parts or custom builds), the turnaround can take up to 8 weeks — perfection takes time.

Either way, we'll keep you updated so you know exactly when your parts are leaving the pit lane.

🚚 Do you send tracking with my order? +

Absolutely! Once your order ships, you'll receive an email with a tracking link so you can follow its journey from our shop to your doorstep.

If your order ships via freight, you'll get a separate email with a direct link to the carrier's tracking page — easy and stress-free.

🛡️ What if my parts get lost or damaged? +

Things happen on the road — even to boxes. If your order arrives damaged, snap a few clear photos of the box and product and send them our way right away.

If your shipment is lost, just email or call us — we'll help track it down and guide you through the next steps to make it right.

❤️ What can I do to help FFP? +

Simple — spread the horsepower! Follow us on Instagram, YouTube, and Facebook, and most importantly, drop us a review on Google or Yelp to let others know about your experience.

Your feedback helps us grow, create more content, and keep bringing performance-driven parts to the community. 🏁

🏎️
Ready to Order?

1ST CLASS SERVICE

805-267-9762

or email Support@FFPerformance.co

Car parts can be a maze — good thing we brought the map. Our team's here to keep things smooth, simple, and maybe even a little fun.

📞 Click To Call Now

Follow us for builds, tips & giveaways

@FFPerformanceAZ
👤
Customer Support Specialist
Product Guaranteed
🏁
Race Proven Knowledge
🔒
Payments Verified