IyEgL3Vzci9iaW4vZW52IHB5dGhvbgojIC0qLSBjb2Rpbmc6IGlzby04ODU5LTEgLSotCiMgT3JpZ2luYWxseSB3cml0dGVuIGJ5IEJhcnJ5IFdhcnNhdyA8YmFycnlAcHl0aG9uLm9yZz4KIwojIE1pbmltYWxseSBwYXRjaGVkIHRvIG1ha2UgaXQgZXZlbiBtb3JlIHhnZXR0ZXh0IGNvbXBhdGlibGUKIyBieSBQZXRlciBGdW5rIDxwZkBhcnRjb20tZ21iaC5kZT4KIwojIDIwMDItMTEtMjIgSvxyZ2VuIEhlcm1hbm4gPGpoQHdlYi5kZT4KIyBBZGRlZCBjaGVja3MgdGhhdCBfKCkgb25seSBjb250YWlucyBzdHJpbmcgbGl0ZXJhbHMsIGFuZAojIGNvbW1hbmQgbGluZSBhcmdzIGFyZSByZXNvbHZlZCB0byBtb2R1bGUgbGlzdHMsIGkuZS4geW91CiMgY2FuIG5vdyBwYXNzIGEgZmlsZW5hbWUsIGEgbW9kdWxlIG9yIHBhY2thZ2UgbmFtZSwgb3IgYQojIGRpcmVjdG9yeSAoaW5jbHVkaW5nIGdsb2JiaW5nIGNoYXJzLCBpbXBvcnRhbnQgZm9yIFdpbjMyKS4KIyBNYWRlIGRvY3N0cmluZyBmaXQgaW4gODAgY2hhcnMgd2lkZSBkaXNwbGF5cyB1c2luZyBweWRvYy4KIwoKIyBmb3Igc2VsZnRlc3RpbmcKdHJ5OgogICAgaW1wb3J0IGZpbnRsCiAgICBfID0gZmludGwuZ2V0dGV4dApleGNlcHQgSW1wb3J0RXJyb3I6CiAgICBfID0gbGFtYmRhIHM6IHMKCl9fZG9jX18gPSBfKCIiInB5Z2V0dGV4dCAtLSBQeXRob24gZXF1aXZhbGVudCBvZiB4Z2V0dGV4dCgxKQoKTWFueSBzeXN0ZW1zIChTb2xhcmlzLCBMaW51eCwgR251KSBwcm92aWRlIGV4dGVuc2l2ZSB0b29scyB0aGF0IGVhc2UgdGhlCmludGVybmF0aW9uYWxpemF0aW9uIG9mIEMgcHJvZ3JhbXMuIE1vc3Qgb2YgdGhlc2UgdG9vbHMgYXJlIGluZGVwZW5kZW50IG9mCnRoZSBwcm9ncmFtbWluZyBsYW5ndWFnZSBhbmQgY2FuIGJlIHVzZWQgZnJvbSB3aXRoaW4gUHl0aG9uIHByb2dyYW1zLgpNYXJ0aW4gdm9uIExvZXdpcycgd29ya1sxXSBoZWxwcyBjb25zaWRlcmFibHkgaW4gdGhpcyByZWdhcmQuCgpUaGVyZSdzIG9uZSBwcm9ibGVtIHRob3VnaDsgeGdldHRleHQgaXMgdGhlIHByb2dyYW0gdGhhdCBzY2FucyBzb3VyY2UgY29kZQpsb29raW5nIGZvciBtZXNzYWdlIHN0cmluZ3MsIGJ1dCBpdCBncm9rcyBvbmx5IEMgKG9yIEMrKykuIFB5dGhvbgppbnRyb2R1Y2VzIGEgZmV3IHdyaW5rbGVzLCBzdWNoIGFzIGR1YWwgcXVvdGluZyBjaGFyYWN0ZXJzLCB0cmlwbGUgcXVvdGVkCnN0cmluZ3MsIGFuZCByYXcgc3RyaW5ncy4geGdldHRleHQgdW5kZXJzdGFuZHMgbm9uZSBvZiB0aGlzLgoKRW50ZXIgcHlnZXR0ZXh0LCB3aGljaCB1c2VzIFB5dGhvbidzIHN0YW5kYXJkIHRva2VuaXplIG1vZHVsZSB0byBzY2FuClB5dGhvbiBzb3VyY2UgY29kZSwgZ2VuZXJhdGluZyAucG90IGZpbGVzIGlkZW50aWNhbCB0byB3aGF0IEdOVSB4Z2V0dGV4dFsyXQpnZW5lcmF0ZXMgZm9yIEMgYW5kIEMrKyBjb2RlLiBGcm9tIHRoZXJlLCB0aGUgc3RhbmRhcmQgR05VIHRvb2xzIGNhbiBiZQp1c2VkLgoKQSB3b3JkIGFib3V0IG1hcmtpbmcgUHl0aG9uIHN0cmluZ3MgYXMgY2FuZGlkYXRlcyBmb3IgdHJhbnNsYXRpb24uIEdOVQp4Z2V0dGV4dCByZWNvZ25pemVzIHRoZSBmb2xsb3dpbmcga2V5d29yZHM6IGdldHRleHQsIGRnZXR0ZXh0LCBkY2dldHRleHQsCmFuZCBnZXR0ZXh0X25vb3AuIEJ1dCB0aG9zZSBjYW4gYmUgYSBsb3Qgb2YgdGV4dCB0byBpbmNsdWRlIGFsbCBvdmVyIHlvdXIKY29kZS4gQyBhbmQgQysrIGhhdmUgYSB0cmljazogdGhleSB1c2UgdGhlIEMgcHJlcHJvY2Vzc29yLiBNb3N0CmludGVybmF0aW9uYWxpemVkIEMgc291cmNlIGluY2x1ZGVzIGEgI2RlZmluZSBmb3IgZ2V0dGV4dCgpIHRvIF8oKSBzbyB0aGF0CndoYXQgaGFzIHRvIGJlIHdyaXR0ZW4gaW4gdGhlIHNvdXJjZSBpcyBtdWNoIGxlc3MuIFRodXMgdGhlc2UgYXJlIGJvdGgKdHJhbnNsYXRhYmxlIHN0cmluZ3M6CgogICAgZ2V0dGV4dCgiVHJhbnNsYXRhYmxlIFN0cmluZyIpCiAgICBfKCJUcmFuc2xhdGFibGUgU3RyaW5nIikKClB5dGhvbiBvZiBjb3Vyc2UgaGFzIG5vIHByZXByb2Nlc3NvciBzbyB0aGlzIGRvZXNuJ3Qgd29yayBzbyB3ZWxsLiAgVGh1cywKcHlnZXR0ZXh0IHNlYXJjaGVzIG9ubHkgZm9yIF8oKSBieSBkZWZhdWx0LCBidXQgc2VlIHRoZSAtay8tLWtleXdvcmQgZmxhZwpiZWxvdyBmb3IgaG93IHRvIGF1Z21lbnQgdGhpcy4KCiBbMV0gaHR0cDovL3d3dy5weXRob24ub3JnL3dvcmtzaG9wcy8xOTk3LTEwL3Byb2NlZWRpbmdzL2xvZXdpcy5odG1sCiBbMl0gaHR0cDovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2dldHRleHQvZ2V0dGV4dC5odG1sCgpOT1RFOiBweWdldHRleHQgYXR0ZW1wdHMgdG8gYmUgb3B0aW9uIGFuZCBmZWF0dXJlIGNvbXBhdGlibGUgd2l0aCBHTlUKeGdldHRleHQgd2hlcmUgZXZlciBwb3NzaWJsZS4gSG93ZXZlciBzb21lIG9wdGlvbnMgYXJlIHN0aWxsIG1pc3Npbmcgb3IgYXJlCm5vdCBmdWxseSBpbXBsZW1lbnRlZC4gQWxzbywgeGdldHRleHQncyB1c2Ugb2YgY29tbWFuZCBsaW5lIHN3aXRjaGVzIHdpdGgKb3B0aW9uIGFyZ3VtZW50cyBpcyBicm9rZW4sIGFuZCBpbiB0aGVzZSBjYXNlcywgcHlnZXR0ZXh0IGp1c3QgZGVmaW5lcwphZGRpdGlvbmFsIHN3aXRjaGVzLgoKVXNhZ2U6IHB5Z2V0dGV4dCBbb3B0aW9uc10gaW5wdXRmaWxlIC4uLgoKT3B0aW9uczoKCiAgICAtYQogICAgLS1leHRyYWN0LWFsbAogICAgICAgIEV4dHJhY3QgYWxsIHN0cmluZ3MuCgogICAgLWQgbmFtZQogICAgLS1kZWZhdWx0LWRvbWFpbj1uYW1lCiAgICAgICAgUmVuYW1lIHRoZSBkZWZhdWx0IG91dHB1dCBmaWxlIGZyb20gbWVzc2FnZXMucG90IHRvIG5hbWUucG90LgoKICAgIC1FCiAgICAtLWVzY2FwZQogICAgICAgIFJlcGxhY2Ugbm9uLUFTQ0lJIGNoYXJhY3RlcnMgd2l0aCBvY3RhbCBlc2NhcGUgc2VxdWVuY2VzLgoKICAgIC1ECiAgICAtLWRvY3N0cmluZ3MKICAgICAgICBFeHRyYWN0IG1vZHVsZSwgY2xhc3MsIG1ldGhvZCwgYW5kIGZ1bmN0aW9uIGRvY3N0cmluZ3MuICBUaGVzZSBkbwogICAgICAgIG5vdCBuZWVkIHRvIGJlIHdyYXBwZWQgaW4gXygpIG1hcmtlcnMsIGFuZCBpbiBmYWN0IGNhbm5vdCBiZSBmb3IKICAgICAgICBQeXRob24gdG8gY29uc2lkZXIgdGhlbSBkb2NzdHJpbmdzLiAoU2VlIGFsc28gdGhlIC1YIG9wdGlvbikuCgogICAgLWgKICAgIC0taGVscAogICAgICAgIFByaW50IHRoaXMgaGVscCBtZXNzYWdlIGFuZCBleGl0LgoKICAgIC1rIHdvcmQKICAgIC0ta2V5d29yZD13b3JkCiAgICAgICAgS2V5d29yZHMgdG8gbG9vayBmb3IgaW4gYWRkaXRpb24gdG8gdGhlIGRlZmF1bHQgc2V0LCB3aGljaCBhcmU6CiAgICAgICAgJShERUZBVUxUS0VZV09SRFMpcwoKICAgICAgICBZb3UgY2FuIGhhdmUgbXVsdGlwbGUgLWsgZmxhZ3Mgb24gdGhlIGNvbW1hbmQgbGluZS4KCiAgICAtSwogICAgLS1uby1kZWZhdWx0LWtleXdvcmRzCiAgICAgICAgRGlzYWJsZSB0aGUgZGVmYXVsdCBzZXQgb2Yga2V5d29yZHMgKHNlZSBhYm92ZSkuICBBbnkga2V5d29yZHMKICAgICAgICBleHBsaWNpdGx5IGFkZGVkIHdpdGggdGhlIC1rLy0ta2V5d29yZCBvcHRpb24gYXJlIHN0aWxsIHJlY29nbml6ZWQuCgogICAgLS1uby1sb2NhdGlvbgogICAgICAgIERvIG5vdCB3cml0ZSBmaWxlbmFtZS9saW5lbm8gbG9jYXRpb24gY29tbWVudHMuCgogICAgLW4KICAgIC0tYWRkLWxvY2F0aW9uCiAgICAgICAgV3JpdGUgZmlsZW5hbWUvbGluZW5vIGxvY2F0aW9uIGNvbW1lbnRzIGluZGljYXRpbmcgd2hlcmUgZWFjaAogICAgICAgIGV4dHJhY3RlZCBzdHJpbmcgaXMgZm91bmQgaW4gdGhlIHNvdXJjZS4gIFRoZXNlIGxpbmVzIGFwcGVhciBiZWZvcmUKICAgICAgICBlYWNoIG1zZ2lkLiAgVGhlIHN0eWxlIG9mIGNvbW1lbnRzIGlzIGNvbnRyb2xsZWQgYnkgdGhlIC1TLy0tc3R5bGUKICAgICAgICBvcHRpb24uICBUaGlzIGlzIHRoZSBkZWZhdWx0LgoKICAgIC1vIGZpbGVuYW1lCiAgICAtLW91dHB1dD1maWxlbmFtZQogICAgICAgIFJlbmFtZSB0aGUgZGVmYXVsdCBvdXRwdXQgZmlsZSBmcm9tIG1lc3NhZ2VzLnBvdCB0byBmaWxlbmFtZS4gIElmCiAgICAgICAgZmlsZW5hbWUgaXMgYC0nIHRoZW4gdGhlIG91dHB1dCBpcyBzZW50IHRvIHN0YW5kYXJkIG91dC4KCiAgICAtcCBkaXIKICAgIC0tb3V0cHV0LWRpcj1kaXIKICAgICAgICBPdXRwdXQgZmlsZXMgd2lsbCBiZSBwbGFjZWQgaW4gZGlyZWN0b3J5IGRpci4KCiAgICAtUyBzdHlsZW5hbWUKICAgIC0tc3R5bGUgc3R5bGVuYW1lCiAgICAgICAgU3BlY2lmeSB3aGljaCBzdHlsZSB0byB1c2UgZm9yIGxvY2F0aW9uIGNvbW1lbnRzLiAgVHdvIHN0eWxlcyBhcmUKICAgICAgICBzdXBwb3J0ZWQ6CgogICAgICAgIFNvbGFyaXMgICMgRmlsZTogZmlsZW5hbWUsIGxpbmU6IGxpbmUtbnVtYmVyCiAgICAgICAgR05VICAgICAgIzogZmlsZW5hbWU6bGluZQoKICAgICAgICBUaGUgc3R5bGUgbmFtZSBpcyBjYXNlIGluc2Vuc2l0aXZlLiAgR05VIHN0eWxlIGlzIHRoZSBkZWZhdWx0LgoKICAgIC12CiAgICAtLXZlcmJvc2UKICAgICAgICBQcmludCB0aGUgbmFtZXMgb2YgdGhlIGZpbGVzIGJlaW5nIHByb2Nlc3NlZC4KCiAgICAtVgogICAgLS12ZXJzaW9uCiAgICAgICAgUHJpbnQgdGhlIHZlcnNpb24gb2YgcHlnZXR0ZXh0IGFuZCBleGl0LgoKICAgIC13IGNvbHVtbnMKICAgIC0td2lkdGg9Y29sdW1ucwogICAgICAgIFNldCB3aWR0aCBvZiBvdXRwdXQgdG8gY29sdW1ucy4KCiAgICAteCBmaWxlbmFtZQogICAgLS1leGNsdWRlLWZpbGU9ZmlsZW5hbWUKICAgICAgICBTcGVjaWZ5IGEgZmlsZSB0aGF0IGNvbnRhaW5zIGEgbGlzdCBvZiBzdHJpbmdzIHRoYXQgYXJlIG5vdCBiZQogICAgICAgIGV4dHJhY3RlZCBmcm9tIHRoZSBpbnB1dCBmaWxlcy4gIEVhY2ggc3RyaW5nIHRvIGJlIGV4Y2x1ZGVkIG11c3QKICAgICAgICBhcHBlYXIgb24gYSBsaW5lIGJ5IGl0c2VsZiBpbiB0aGUgZmlsZS4KCiAgICAtWCBmaWxlbmFtZQogICAgLS1uby1kb2NzdHJpbmdzPWZpbGVuYW1lCiAgICAgICAgU3BlY2lmeSBhIGZpbGUgdGhhdCBjb250YWlucyBhIGxpc3Qgb2YgZmlsZXMgKG9uZSBwZXIgbGluZSkgdGhhdAogICAgICAgIHNob3VsZCBub3QgaGF2ZSB0aGVpciBkb2NzdHJpbmdzIGV4dHJhY3RlZC4gIFRoaXMgaXMgb25seSB1c2VmdWwgaW4KICAgICAgICBjb25qdW5jdGlvbiB3aXRoIHRoZSAtRCBvcHRpb24gYWJvdmUuCgpJZiBgaW5wdXRmaWxlJyBpcyAtLCBzdGFuZGFyZCBpbnB1dCBpcyByZWFkLgoiIiIpCgppbXBvcnQgb3MKaW1wb3J0IGltcAppbXBvcnQgc3lzCmltcG9ydCBnbG9iCmltcG9ydCB0aW1lCmltcG9ydCBnZXRvcHQKaW1wb3J0IHRva2VuCmltcG9ydCB0b2tlbml6ZQppbXBvcnQgb3BlcmF0b3IKCl9fdmVyc2lvbl9fID0gJzEuNScKCmRlZmF1bHRfa2V5d29yZHMgPSBbJ18nXQpERUZBVUxUS0VZV09SRFMgPSAnLCAnLmpvaW4oZGVmYXVsdF9rZXl3b3JkcykKCkVNUFRZU1RSSU5HID0gJycKCgoMCiMgVGhlIG5vcm1hbCBwb3QtZmlsZSBoZWFkZXIuIG1zZ21lcmdlIGFuZCBFbWFjcydzIHBvLW1vZGUgd29yayBiZXR0ZXIgaWYgaXQncwojIHRoZXJlLgpwb3RfaGVhZGVyID0gXygnJydcCiMgU09NRSBERVNDUklQVElWRSBUSVRMRS4KIyBDb3B5cmlnaHQgKEMpIFlFQVIgT1JHQU5JWkFUSU9OCiMgRklSU1QgQVVUSE9SIDxFTUFJTEBBRERSRVNTPiwgWUVBUi4KIwptc2dpZCAiIgptc2dzdHIgIiIKIlByb2plY3QtSWQtVmVyc2lvbjogUEFDS0FHRSBWRVJTSU9OXFxuIgoiUE9ULUNyZWF0aW9uLURhdGU6ICUodGltZSlzXFxuIgoiUE8tUmV2aXNpb24tRGF0ZTogWUVBUi1NTy1EQSBITzpNSStaT05FXFxuIgoiTGFzdC1UcmFuc2xhdG9yOiBGVUxMIE5BTUUgPEVNQUlMQEFERFJFU1M+XFxuIgoiTGFuZ3VhZ2UtVGVhbTogTEFOR1VBR0UgPExMQGxpLm9yZz5cXG4iCiJNSU1FLVZlcnNpb246IDEuMFxcbiIKIkNvbnRlbnQtVHlwZTogdGV4dC9wbGFpbjsgY2hhcnNldD1DSEFSU0VUXFxuIgoiQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogRU5DT0RJTkdcXG4iCiJHZW5lcmF0ZWQtQnk6IHB5Z2V0dGV4dC5weSAlKHZlcnNpb24pc1xcbiIKCicnJykKCgwKZGVmIHVzYWdlKGNvZGUsIG1zZz0nJyk6CiAgICBwcmludCA+PiBzeXMuc3RkZXJyLCBfX2RvY19fICUgZ2xvYmFscygpCiAgICBpZiBtc2c6CiAgICAgICAgcHJpbnQgPj4gc3lzLnN0ZGVyciwgbXNnCiAgICBzeXMuZXhpdChjb2RlKQoKCgwKZXNjYXBlcyA9IFtdCgpkZWYgbWFrZV9lc2NhcGVzKHBhc3NfaXNvODg1OSk6CiAgICBnbG9iYWwgZXNjYXBlcwogICAgZXNjYXBlcyA9IFtjaHIoaSkgZm9yIGkgaW4gcmFuZ2UoMjU2KV0KICAgIGlmIHBhc3NfaXNvODg1OToKICAgICAgICAjIEFsbG93IGlzby04ODU5IGNoYXJhY3RlcnMgdG8gcGFzcyB0aHJvdWdoIHNvIHRoYXQgZS5nLiAnbXNnaWQKICAgICAgICAjICJI9mhlIicgd291bGQgcmVzdWx0IG5vdCByZXN1bHQgaW4gJ21zZ2lkICJIXDM2NmhlIicuICBPdGhlcndpc2Ugd2UKICAgICAgICAjIGVzY2FwZSBhbnkgY2hhcmFjdGVyIG91dHNpZGUgdGhlIDMyLi4xMjYgcmFuZ2UuCiAgICAgICAgbW9kID0gMTI4CiAgICBlbHNlOgogICAgICAgIG1vZCA9IDI1NgogICAgZm9yIGkgaW4gcmFuZ2UobW9kKToKICAgICAgICBpZiBub3QoMzIgPD0gaSA8PSAxMjYpOgogICAgICAgICAgICBlc2NhcGVzW2ldID0gIlxcJTAzbyIgJSBpCiAgICBlc2NhcGVzW29yZCgnXFwnKV0gPSAnXFxcXCcKICAgIGVzY2FwZXNbb3JkKCdcdCcpXSA9ICdcXHQnCiAgICBlc2NhcGVzW29yZCgnXHInKV0gPSAnXFxyJwogICAgZXNjYXBlc1tvcmQoJ1xuJyldID0gJ1xcbicKICAgIGVzY2FwZXNbb3JkKCdcIicpXSA9ICdcXCInCgoKZGVmIGVzY2FwZShzKToKICAgIGdsb2JhbCBlc2NhcGVzCiAgICBzID0gbGlzdChzKQogICAgZm9yIGkgaW4gcmFuZ2UobGVuKHMpKToKICAgICAgICBzW2ldID0gZXNjYXBlc1tvcmQoc1tpXSldCiAgICByZXR1cm4gRU1QVFlTVFJJTkcuam9pbihzKQoKCmRlZiBzYWZlX2V2YWwocyk6CiAgICAjIHVud3JhcCBxdW90ZXMsIHNhZmVseQogICAgcmV0dXJuIGV2YWwocywgeydfX2J1aWx0aW5zX18nOnt9fSwge30pCgoKZGVmIG5vcm1hbGl6ZShzKToKICAgICMgVGhpcyBjb252ZXJ0cyB0aGUgdmFyaW91cyBQeXRob24gc3RyaW5nIHR5cGVzIGludG8gYSBmb3JtYXQgdGhhdCBpcwogICAgIyBhcHByb3ByaWF0ZSBmb3IgLnBvIGZpbGVzLCBuYW1lbHkgbXVjaCBjbG9zZXIgdG8gQyBzdHlsZS4KICAgIGxpbmVzID0gcy5zcGxpdCgnXG4nKQogICAgaWYgbGVuKGxpbmVzKSA9PSAxOgogICAgICAgIHMgPSAnIicgKyBlc2NhcGUocykgKyAnIicKICAgIGVsc2U6CiAgICAgICAgaWYgbm90IGxpbmVzWy0xXToKICAgICAgICAgICAgZGVsIGxpbmVzWy0xXQogICAgICAgICAgICBsaW5lc1stMV0gPSBsaW5lc1stMV0gKyAnXG4nCiAgICAgICAgZm9yIGkgaW4gcmFuZ2UobGVuKGxpbmVzKSk6CiAgICAgICAgICAgIGxpbmVzW2ldID0gZXNjYXBlKGxpbmVzW2ldKQogICAgICAgIGxpbmV0ZXJtID0gJ1xcbiJcbiInCiAgICAgICAgcyA9ICciIlxuIicgKyBsaW5ldGVybS5qb2luKGxpbmVzKSArICciJwogICAgcmV0dXJuIHMKCgwKZGVmIGNvbnRhaW5zQW55KHN0ciwgc2V0KToKICAgICIiIkNoZWNrIHdoZXRoZXIgJ3N0cicgY29udGFpbnMgQU5ZIG9mIHRoZSBjaGFycyBpbiAnc2V0JyIiIgogICAgcmV0dXJuIDEgaW4gW2MgaW4gc3RyIGZvciBjIGluIHNldF0KCgpkZWYgX3Zpc2l0X3B5ZmlsZXMobGlzdCwgZGlybmFtZSwgbmFtZXMpOgogICAgIiIiSGVscGVyIGZvciBnZXRGaWxlc0Zvck5hbWUoKS4iIiIKICAgICMgZ2V0IGV4dGVuc2lvbiBmb3IgcHl0aG9uIHNvdXJjZSBmaWxlcwogICAgaWYgbm90IGdsb2JhbHMoKS5oYXNfa2V5KCdfcHlfZXh0Jyk6CiAgICAgICAgZ2xvYmFsIF9weV9leHQKICAgICAgICBfcHlfZXh0ID0gW3RyaXBsZVswXSBmb3IgdHJpcGxlIGluIGltcC5nZXRfc3VmZml4ZXMoKQogICAgICAgICAgICAgICAgICAgaWYgdHJpcGxlWzJdID09IGltcC5QWV9TT1VSQ0VdWzBdCgogICAgIyBkb24ndCByZWN1cnNlIGludG8gQ1ZTIGRpcmVjdG9yaWVzCiAgICBpZiAnQ1ZTJyBpbiBuYW1lczoKICAgICAgICBuYW1lcy5yZW1vdmUoJ0NWUycpCgogICAgIyBhZGQgYWxsICoucHkgZmlsZXMgdG8gbGlzdAogICAgbGlzdC5leHRlbmQoCiAgICAgICAgW29zLnBhdGguam9pbihkaXJuYW1lLCBmaWxlKSBmb3IgZmlsZSBpbiBuYW1lcwogICAgICAgICBpZiBvcy5wYXRoLnNwbGl0ZXh0KGZpbGUpWzFdID09IF9weV9leHRdCiAgICAgICAgKQoKCmRlZiBfZ2V0X21vZHBrZ19wYXRoKGRvdHRlZF9uYW1lLCBwYXRobGlzdD1Ob25lKToKICAgICIiIkdldCB0aGUgZmlsZXN5c3RlbSBwYXRoIGZvciBhIG1vZHVsZSBvciBhIHBhY2thZ2UuCgogICAgUmV0dXJuIHRoZSBmaWxlIHN5c3RlbSBwYXRoIHRvIGEgZmlsZSBmb3IgYSBtb2R1bGUsIGFuZCB0byBhIGRpcmVjdG9yeSBmb3IKICAgIGEgcGFja2FnZS4gUmV0dXJuIE5vbmUgaWYgdGhlIG5hbWUgaXMgbm90IGZvdW5kLCBvciBpcyBhIGJ1aWx0aW4gb3IKICAgIGV4dGVuc2lvbiBtb2R1bGUuCiAgICAiIiIKICAgICMgc3BsaXQgb2ZmIHRvcC1tb3N0IG5hbWUKICAgIHBhcnRzID0gZG90dGVkX25hbWUuc3BsaXQoJy4nLCAxKQoKICAgIGlmIGxlbihwYXJ0cykgPiAxOgogICAgICAgICMgd2UgaGF2ZSBhIGRvdHRlZCBwYXRoLCBpbXBvcnQgdG9wLWxldmVsIHBhY2thZ2UKICAgICAgICB0cnk6CiAgICAgICAgICAgIGZpbGUsIHBhdGhuYW1lLCBkZXNjcmlwdGlvbiA9IGltcC5maW5kX21vZHVsZShwYXJ0c1swXSwgcGF0aGxpc3QpCiAgICAgICAgICAgIGlmIGZpbGU6IGZpbGUuY2xvc2UoKQogICAgICAgIGV4Y2VwdCBJbXBvcnRFcnJvcjoKICAgICAgICAgICAgcmV0dXJuIE5vbmUKCiAgICAgICAgIyBjaGVjayBpZiBpdCdzIGluZGVlZCBhIHBhY2thZ2UKICAgICAgICBpZiBkZXNjcmlwdGlvblsyXSA9PSBpbXAuUEtHX0RJUkVDVE9SWToKICAgICAgICAgICAgIyByZWN1cnNpdmVseSBoYW5kbGUgdGhlIHJlbWFpbmluZyBuYW1lIHBhcnRzCiAgICAgICAgICAgIHBhdGhuYW1lID0gX2dldF9tb2Rwa2dfcGF0aChwYXJ0c1sxXSwgW3BhdGhuYW1lXSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBwYXRobmFtZSA9IE5vbmUKICAgIGVsc2U6CiAgICAgICAgIyBwbGFpbiBuYW1lCiAgICAgICAgdHJ5OgogICAgICAgICAgICBmaWxlLCBwYXRobmFtZSwgZGVzY3JpcHRpb24gPSBpbXAuZmluZF9tb2R1bGUoCiAgICAgICAgICAgICAgICBkb3R0ZWRfbmFtZSwgcGF0aGxpc3QpCiAgICAgICAgICAgIGlmIGZpbGU6CiAgICAgICAgICAgICAgICBmaWxlLmNsb3NlKCkKICAgICAgICAgICAgaWYgZGVzY3JpcHRpb25bMl0gbm90IGluIFtpbXAuUFlfU09VUkNFLCBpbXAuUEtHX0RJUkVDVE9SWV06CiAgICAgICAgICAgICAgICBwYXRobmFtZSA9IE5vbmUKICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgIHBhdGhuYW1lID0gTm9uZQoKICAgIHJldHVybiBwYXRobmFtZQoKCmRlZiBnZXRGaWxlc0Zvck5hbWUobmFtZSk6CiAgICAiIiJHZXQgYSBsaXN0IG9mIG1vZHVsZSBmaWxlcyBmb3IgYSBmaWxlbmFtZSwgYSBtb2R1bGUgb3IgcGFja2FnZSBuYW1lLAogICAgb3IgYSBkaXJlY3RvcnkuCiAgICAiIiIKICAgIGlmIG5vdCBvcy5wYXRoLmV4aXN0cyhuYW1lKToKICAgICAgICAjIGNoZWNrIGZvciBnbG9iIGNoYXJzCiAgICAgICAgaWYgY29udGFpbnNBbnkobmFtZSwgIio/W10iKToKICAgICAgICAgICAgZmlsZXMgPSBnbG9iLmdsb2IobmFtZSkKICAgICAgICAgICAgbGlzdCA9IFtdCiAgICAgICAgICAgIGZvciBmaWxlIGluIGZpbGVzOgogICAgICAgICAgICAgICAgbGlzdC5leHRlbmQoZ2V0RmlsZXNGb3JOYW1lKGZpbGUpKQogICAgICAgICAgICByZXR1cm4gbGlzdAoKICAgICAgICAjIHRyeSB0byBmaW5kIG1vZHVsZSBvciBwYWNrYWdlCiAgICAgICAgbmFtZSA9IF9nZXRfbW9kcGtnX3BhdGgobmFtZSkKICAgICAgICBpZiBub3QgbmFtZToKICAgICAgICAgICAgcmV0dXJuIFtdCgogICAgaWYgb3MucGF0aC5pc2RpcihuYW1lKToKICAgICAgICAjIGZpbmQgYWxsIHB5dGhvbiBmaWxlcyBpbiBkaXJlY3RvcnkKICAgICAgICBsaXN0ID0gW10KICAgICAgICBvcy5wYXRoLndhbGsobmFtZSwgX3Zpc2l0X3B5ZmlsZXMsIGxpc3QpCiAgICAgICAgcmV0dXJuIGxpc3QKICAgIGVsaWYgb3MucGF0aC5leGlzdHMobmFtZSk6CiAgICAgICAgIyBhIHNpbmdsZSBmaWxlCiAgICAgICAgcmV0dXJuIFtuYW1lXQoKICAgIHJldHVybiBbXQoKDApjbGFzcyBUb2tlbkVhdGVyOgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG9wdGlvbnMpOgogICAgICAgIHNlbGYuX19vcHRpb25zID0gb3B0aW9ucwogICAgICAgIHNlbGYuX19tZXNzYWdlcyA9IHt9CiAgICAgICAgc2VsZi5fX3N0YXRlID0gc2VsZi5fX3dhaXRpbmcKICAgICAgICBzZWxmLl9fZGF0YSA9IFtdCiAgICAgICAgc2VsZi5fX2xpbmVubyA9IC0xCiAgICAgICAgc2VsZi5fX2ZyZXNobW9kdWxlID0gMQogICAgICAgIHNlbGYuX19jdXJmaWxlID0gTm9uZQoKICAgIGRlZiBfX2NhbGxfXyhzZWxmLCB0dHlwZSwgdHN0cmluZywgc3R1cCwgZXR1cCwgbGluZSk6CiAgICAgICAgIyBkaXNwYXRjaAojIyAgICAgICAgaW1wb3J0IHRva2VuCiMjICAgICAgICBwcmludCA+PiBzeXMuc3RkZXJyLCAndHR5cGU6JywgdG9rZW4udG9rX25hbWVbdHR5cGVdLCBcCiMjICAgICAgICAgICAgICAndHN0cmluZzonLCB0c3RyaW5nCiAgICAgICAgc2VsZi5fX3N0YXRlKHR0eXBlLCB0c3RyaW5nLCBzdHVwWzBdKQoKICAgIGRlZiBfX3dhaXRpbmcoc2VsZiwgdHR5cGUsIHRzdHJpbmcsIGxpbmVubyk6CiAgICAgICAgb3B0cyA9IHNlbGYuX19vcHRpb25zCiAgICAgICAgIyBEbyBkb2NzdHJpbmcgZXh0cmFjdGlvbnMsIGlmIGVuYWJsZWQKICAgICAgICBpZiBvcHRzLmRvY3N0cmluZ3MgYW5kIG5vdCBvcHRzLm5vZG9jc3RyaW5ncy5nZXQoc2VsZi5fX2N1cmZpbGUpOgogICAgICAgICAgICAjIG1vZHVsZSBkb2NzdHJpbmc/CiAgICAgICAgICAgIGlmIHNlbGYuX19mcmVzaG1vZHVsZToKICAgICAgICAgICAgICAgIGlmIHR0eXBlID09IHRva2VuaXplLlNUUklORzoKICAgICAgICAgICAgICAgICAgICBzZWxmLl9fYWRkZW50cnkoc2FmZV9ldmFsKHRzdHJpbmcpLCBsaW5lbm8sIGlzZG9jc3RyaW5nPTEpCiAgICAgICAgICAgICAgICAgICAgc2VsZi5fX2ZyZXNobW9kdWxlID0gMAogICAgICAgICAgICAgICAgZWxpZiB0dHlwZSBub3QgaW4gKHRva2VuaXplLkNPTU1FTlQsIHRva2VuaXplLk5MKToKICAgICAgICAgICAgICAgICAgICBzZWxmLl9fZnJlc2htb2R1bGUgPSAwCiAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgIyBjbGFzcyBkb2NzdHJpbmc/CiAgICAgICAgICAgIGlmIHR0eXBlID09IHRva2VuaXplLk5BTUUgYW5kIHRzdHJpbmcgaW4gKCdjbGFzcycsICdkZWYnKToKICAgICAgICAgICAgICAgIHNlbGYuX19zdGF0ZSA9IHNlbGYuX19zdWl0ZXNlZW4KICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgIGlmIHR0eXBlID09IHRva2VuaXplLk5BTUUgYW5kIHRzdHJpbmcgaW4gb3B0cy5rZXl3b3JkczoKICAgICAgICAgICAgc2VsZi5fX3N0YXRlID0gc2VsZi5fX2tleXdvcmRzZWVuCgogICAgZGVmIF9fc3VpdGVzZWVuKHNlbGYsIHR0eXBlLCB0c3RyaW5nLCBsaW5lbm8pOgogICAgICAgICMgaWdub3JlIGFueXRoaW5nIHVudGlsIHdlIHNlZSB0aGUgY29sb24KICAgICAgICBpZiB0dHlwZSA9PSB0b2tlbml6ZS5PUCBhbmQgdHN0cmluZyA9PSAnOic6CiAgICAgICAgICAgIHNlbGYuX19zdGF0ZSA9IHNlbGYuX19zdWl0ZWRvY3N0cmluZwoKICAgIGRlZiBfX3N1aXRlZG9jc3RyaW5nKHNlbGYsIHR0eXBlLCB0c3RyaW5nLCBsaW5lbm8pOgogICAgICAgICMgaWdub3JlIGFueSBpbnRlcnZlbmluZyBub2lzZQogICAgICAgIGlmIHR0eXBlID09IHRva2VuaXplLlNUUklORzoKICAgICAgICAgICAgc2VsZi5fX2FkZGVudHJ5KHNhZmVfZXZhbCh0c3RyaW5nKSwgbGluZW5vLCBpc2RvY3N0cmluZz0xKQogICAgICAgICAgICBzZWxmLl9fc3RhdGUgPSBzZWxmLl9fd2FpdGluZwogICAgICAgIGVsaWYgdHR5cGUgbm90IGluICh0b2tlbml6ZS5ORVdMSU5FLCB0b2tlbml6ZS5JTkRFTlQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRva2VuaXplLkNPTU1FTlQpOgogICAgICAgICAgICAjIHRoZXJlIHdhcyBubyBjbGFzcyBkb2NzdHJpbmcKICAgICAgICAgICAgc2VsZi5fX3N0YXRlID0gc2VsZi5fX3dhaXRpbmcKCiAgICBkZWYgX19rZXl3b3Jkc2VlbihzZWxmLCB0dHlwZSwgdHN0cmluZywgbGluZW5vKToKICAgICAgICBpZiB0dHlwZSA9PSB0b2tlbml6ZS5PUCBhbmQgdHN0cmluZyA9PSAnKCc6CiAgICAgICAgICAgIHNlbGYuX19kYXRhID0gW10KICAgICAgICAgICAgc2VsZi5fX2xpbmVubyA9IGxpbmVubwogICAgICAgICAgICBzZWxmLl9fc3RhdGUgPSBzZWxmLl9fb3BlbnNlZW4KICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLl9fc3RhdGUgPSBzZWxmLl9fd2FpdGluZwoKICAgIGRlZiBfX29wZW5zZWVuKHNlbGYsIHR0eXBlLCB0c3RyaW5nLCBsaW5lbm8pOgogICAgICAgIGlmIHR0eXBlID09IHRva2VuaXplLk9QIGFuZCB0c3RyaW5nID09ICcpJzoKICAgICAgICAgICAgIyBXZSd2ZSBzZWVuIHRoZSBsYXN0IG9mIHRoZSB0cmFuc2xhdGFibGUgc3RyaW5ncy4gIFJlY29yZCB0aGUKICAgICAgICAgICAgIyBsaW5lIG51bWJlciBvZiB0aGUgZmlyc3QgbGluZSBvZiB0aGUgc3RyaW5ncyBhbmQgdXBkYXRlIHRoZSBsaXN0CiAgICAgICAgICAgICMgb2YgbWVzc2FnZXMgc2Vlbi4gIFJlc2V0IHN0YXRlIGZvciB0aGUgbmV4dCBiYXRjaC4gIElmIHRoZXJlCiAgICAgICAgICAgICMgd2VyZSBubyBzdHJpbmdzIGluc2lkZSBfKCksIHRoZW4ganVzdCBpZ25vcmUgdGhpcyBlbnRyeS4KICAgICAgICAgICAgaWYgc2VsZi5fX2RhdGE6CiAgICAgICAgICAgICAgICBzZWxmLl9fYWRkZW50cnkoRU1QVFlTVFJJTkcuam9pbihzZWxmLl9fZGF0YSkpCiAgICAgICAgICAgIHNlbGYuX19zdGF0ZSA9IHNlbGYuX193YWl0aW5nCiAgICAgICAgZWxpZiB0dHlwZSA9PSB0b2tlbml6ZS5TVFJJTkc6CiAgICAgICAgICAgIHNlbGYuX19kYXRhLmFwcGVuZChzYWZlX2V2YWwodHN0cmluZykpCiAgICAgICAgZWxpZiB0dHlwZSBub3QgaW4gW3Rva2VuaXplLkNPTU1FTlQsIHRva2VuLklOREVOVCwgdG9rZW4uREVERU5ULAogICAgICAgICAgICAgICAgICAgICAgICAgICB0b2tlbi5ORVdMSU5FLCB0b2tlbml6ZS5OTF06CiAgICAgICAgICAgICMgd2FybiBpZiB3ZSBzZWUgYW55dGhpbmcgZWxzZSB0aGFuIFNUUklORyBvciB3aGl0ZXNwYWNlCiAgICAgICAgICAgIHByaW50ID4+IHN5cy5zdGRlcnIsIF8oCiAgICAgICAgICAgICAgICAnKioqICUoZmlsZSlzOiUobGluZW5vKXM6IFNlZW4gdW5leHBlY3RlZCB0b2tlbiAiJSh0b2tlbilzIicKICAgICAgICAgICAgICAgICkgJSB7CiAgICAgICAgICAgICAgICAndG9rZW4nOiB0c3RyaW5nLAogICAgICAgICAgICAgICAgJ2ZpbGUnOiBzZWxmLl9fY3VyZmlsZSwKICAgICAgICAgICAgICAgICdsaW5lbm8nOiBzZWxmLl9fbGluZW5vCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIHNlbGYuX19zdGF0ZSA9IHNlbGYuX193YWl0aW5nCgogICAgZGVmIF9fYWRkZW50cnkoc2VsZiwgbXNnLCBsaW5lbm89Tm9uZSwgaXNkb2NzdHJpbmc9MCk6CiAgICAgICAgaWYgbGluZW5vIGlzIE5vbmU6CiAgICAgICAgICAgIGxpbmVubyA9IHNlbGYuX19saW5lbm8KICAgICAgICBpZiBub3QgbXNnIGluIHNlbGYuX19vcHRpb25zLnRvZXhjbHVkZToKICAgICAgICAgICAgZW50cnkgPSAoc2VsZi5fX2N1cmZpbGUsIGxpbmVubykKICAgICAgICAgICAgc2VsZi5fX21lc3NhZ2VzLnNldGRlZmF1bHQobXNnLCB7fSlbZW50cnldID0gaXNkb2NzdHJpbmcKCiAgICBkZWYgc2V0X2ZpbGVuYW1lKHNlbGYsIGZpbGVuYW1lKToKICAgICAgICBzZWxmLl9fY3VyZmlsZSA9IGZpbGVuYW1lCiAgICAgICAgc2VsZi5fX2ZyZXNobW9kdWxlID0gMQoKICAgIGRlZiB3cml0ZShzZWxmLCBmcCk6CiAgICAgICAgb3B0aW9ucyA9IHNlbGYuX19vcHRpb25zCiAgICAgICAgdGltZXN0YW1wID0gdGltZS5zdHJmdGltZSgnJVktJW0tJWQgJUg6JU0rJVonKQogICAgICAgICMgVGhlIHRpbWUgc3RhbXAgaW4gdGhlIGhlYWRlciBkb2Vzbid0IGhhdmUgdGhlIHNhbWUgZm9ybWF0IGFzIHRoYXQKICAgICAgICAjIGdlbmVyYXRlZCBieSB4Z2V0dGV4dC4uLgogICAgICAgIHByaW50ID4+IGZwLCBwb3RfaGVhZGVyICUgeyd0aW1lJzogdGltZXN0YW1wLCAndmVyc2lvbic6IF9fdmVyc2lvbl9ffQogICAgICAgICMgU29ydCB0aGUgZW50cmllcy4gIEZpcnN0IHNvcnQgZWFjaCBwYXJ0aWN1bGFyIGVudHJ5J3Mga2V5cywgdGhlbgogICAgICAgICMgc29ydCBhbGwgdGhlIGVudHJpZXMgYnkgdGhlaXIgZmlyc3QgaXRlbS4KICAgICAgICByZXZlcnNlID0ge30KICAgICAgICBmb3IgaywgdiBpbiBzZWxmLl9fbWVzc2FnZXMuaXRlbXMoKToKICAgICAgICAgICAga2V5cyA9IHYua2V5cygpCiAgICAgICAgICAgIGtleXMuc29ydCgpCiAgICAgICAgICAgIHJldmVyc2Uuc2V0ZGVmYXVsdCh0dXBsZShrZXlzKSwgW10pLmFwcGVuZCgoaywgdikpCiAgICAgICAgcmtleXMgPSByZXZlcnNlLmtleXMoKQogICAgICAgIHJrZXlzLnNvcnQoKQogICAgICAgIGZvciBya2V5IGluIHJrZXlzOgogICAgICAgICAgICByZW50cmllcyA9IHJldmVyc2VbcmtleV0KICAgICAgICAgICAgcmVudHJpZXMuc29ydCgpCiAgICAgICAgICAgIGZvciBrLCB2IGluIHJlbnRyaWVzOgogICAgICAgICAgICAgICAgaXNkb2NzdHJpbmcgPSAwCiAgICAgICAgICAgICAgICAjIElmIHRoZSBlbnRyeSB3YXMgZ2xlYW5lZCBvdXQgb2YgYSBkb2NzdHJpbmcsIHRoZW4gYWRkIGEKICAgICAgICAgICAgICAgICMgY29tbWVudCBzdGF0aW5nIHNvLiAgVGhpcyBpcyB0byBhaWQgdHJhbnNsYXRvcnMgd2hvIG1heSB3aXNoCiAgICAgICAgICAgICAgICAjIHRvIHNraXAgdHJhbnNsYXRpbmcgc29tZSB1bmltcG9ydGFudCBkb2NzdHJpbmdzLgogICAgICAgICAgICAgICAgaWYgcmVkdWNlKG9wZXJhdG9yLl9fYWRkX18sIHYudmFsdWVzKCkpOgogICAgICAgICAgICAgICAgICAgIGlzZG9jc3RyaW5nID0gMQogICAgICAgICAgICAgICAgIyBrIGlzIHRoZSBtZXNzYWdlIHN0cmluZywgdiBpcyBhIGRpY3Rpb25hcnktc2V0IG9mIChmaWxlbmFtZSwKICAgICAgICAgICAgICAgICMgbGluZW5vKSB0dXBsZXMuICBXZSB3YW50IHRvIHNvcnQgdGhlIGVudHJpZXMgaW4gdiBmaXJzdCBieQogICAgICAgICAgICAgICAgIyBmaWxlIG5hbWUgYW5kIHRoZW4gYnkgbGluZSBudW1iZXIuCiAgICAgICAgICAgICAgICB2ID0gdi5rZXlzKCkKICAgICAgICAgICAgICAgIHYuc29ydCgpCiAgICAgICAgICAgICAgICBpZiBub3Qgb3B0aW9ucy53cml0ZWxvY2F0aW9uczoKICAgICAgICAgICAgICAgICAgICBwYXNzCiAgICAgICAgICAgICAgICAjIGxvY2F0aW9uIGNvbW1lbnRzIGFyZSBkaWZmZXJlbnQgYi93IFNvbGFyaXMgYW5kIEdOVToKICAgICAgICAgICAgICAgIGVsaWYgb3B0aW9ucy5sb2NhdGlvbnN0eWxlID09IG9wdGlvbnMuU09MQVJJUzoKICAgICAgICAgICAgICAgICAgICBmb3IgZmlsZW5hbWUsIGxpbmVubyBpbiB2OgogICAgICAgICAgICAgICAgICAgICAgICBkID0geydmaWxlbmFtZSc6IGZpbGVuYW1lLCAnbGluZW5vJzogbGluZW5vfQogICAgICAgICAgICAgICAgICAgICAgICBwcmludCA+PmZwLCBfKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJyMgRmlsZTogJShmaWxlbmFtZSlzLCBsaW5lOiAlKGxpbmVubylkJykgJSBkCiAgICAgICAgICAgICAgICBlbGlmIG9wdGlvbnMubG9jYXRpb25zdHlsZSA9PSBvcHRpb25zLkdOVToKICAgICAgICAgICAgICAgICAgICAjIGZpdCBhcyBtYW55IGxvY2F0aW9ucyBvbiBvbmUgbGluZSwgYXMgbG9uZyBhcyB0aGUKICAgICAgICAgICAgICAgICAgICAjIHJlc3VsdGluZyBsaW5lIGxlbmd0aCBkb2Vzbid0IGV4Y2VlZHMgJ29wdGlvbnMud2lkdGgnCiAgICAgICAgICAgICAgICAgICAgbG9jbGluZSA9ICcjOicKICAgICAgICAgICAgICAgICAgICBmb3IgZmlsZW5hbWUsIGxpbmVubyBpbiB2OgogICAgICAgICAgICAgICAgICAgICAgICBkID0geydmaWxlbmFtZSc6IGZpbGVuYW1lLCAnbGluZW5vJzogbGluZW5vfQogICAgICAgICAgICAgICAgICAgICAgICBzID0gXygnICUoZmlsZW5hbWUpczolKGxpbmVubylkJykgJSBkCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIGxlbihsb2NsaW5lKSArIGxlbihzKSA8PSBvcHRpb25zLndpZHRoOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jbGluZSA9IGxvY2xpbmUgKyBzCiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmludCA+PiBmcCwgbG9jbGluZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jbGluZSA9ICIjOiIgKyBzCiAgICAgICAgICAgICAgICAgICAgaWYgbGVuKGxvY2xpbmUpID4gMjoKICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQgPj4gZnAsIGxvY2xpbmUKICAgICAgICAgICAgICAgIGlmIGlzZG9jc3RyaW5nOgogICAgICAgICAgICAgICAgICAgIHByaW50ID4+IGZwLCAnIywgZG9jc3RyaW5nJwogICAgICAgICAgICAgICAgcHJpbnQgPj4gZnAsICdtc2dpZCcsIG5vcm1hbGl6ZShrKQogICAgICAgICAgICAgICAgcHJpbnQgPj4gZnAsICdtc2dzdHIgIiJcbicKCgoMCmRlZiBtYWluKCk6CiAgICBnbG9iYWwgZGVmYXVsdF9rZXl3b3JkcwogICAgdHJ5OgogICAgICAgIG9wdHMsIGFyZ3MgPSBnZXRvcHQuZ2V0b3B0KAogICAgICAgICAgICBzeXMuYXJndlsxOl0sCiAgICAgICAgICAgICdhZDpERWhrOktubzpwOlM6VnZ3Ong6WDonLAogICAgICAgICAgICBbJ2V4dHJhY3QtYWxsJywgJ2RlZmF1bHQtZG9tYWluPScsICdlc2NhcGUnLCAnaGVscCcsCiAgICAgICAgICAgICAna2V5d29yZD0nLCAnbm8tZGVmYXVsdC1rZXl3b3JkcycsCiAgICAgICAgICAgICAnYWRkLWxvY2F0aW9uJywgJ25vLWxvY2F0aW9uJywgJ291dHB1dD0nLCAnb3V0cHV0LWRpcj0nLAogICAgICAgICAgICAgJ3N0eWxlPScsICd2ZXJib3NlJywgJ3ZlcnNpb24nLCAnd2lkdGg9JywgJ2V4Y2x1ZGUtZmlsZT0nLAogICAgICAgICAgICAgJ2RvY3N0cmluZ3MnLCAnbm8tZG9jc3RyaW5ncycsCiAgICAgICAgICAgICBdKQogICAgZXhjZXB0IGdldG9wdC5lcnJvciwgbXNnOgogICAgICAgIHVzYWdlKDEsIG1zZykKCiAgICAjIGZvciBob2xkaW5nIG9wdGlvbiB2YWx1ZXMKICAgIGNsYXNzIE9wdGlvbnM6CiAgICAgICAgIyBjb25zdGFudHMKICAgICAgICBHTlUgPSAxCiAgICAgICAgU09MQVJJUyA9IDIKICAgICAgICAjIGRlZmF1bHRzCiAgICAgICAgZXh0cmFjdGFsbCA9IDAgIyBGSVhNRTogY3VycmVudGx5IHRoaXMgb3B0aW9uIGhhcyBubyBlZmZlY3QgYXQgYWxsLgogICAgICAgIGVzY2FwZSA9IDAKICAgICAgICBrZXl3b3JkcyA9IFtdCiAgICAgICAgb3V0cGF0aCA9ICcnCiAgICAgICAgb3V0ZmlsZSA9ICdtZXNzYWdlcy5wb3QnCiAgICAgICAgd3JpdGVsb2NhdGlvbnMgPSAxCiAgICAgICAgbG9jYXRpb25zdHlsZSA9IEdOVQogICAgICAgIHZlcmJvc2UgPSAwCiAgICAgICAgd2lkdGggPSA3OAogICAgICAgIGV4Y2x1ZGVmaWxlbmFtZSA9ICcnCiAgICAgICAgZG9jc3RyaW5ncyA9IDAKICAgICAgICBub2RvY3N0cmluZ3MgPSB7fQoKICAgIG9wdGlvbnMgPSBPcHRpb25zKCkKICAgIGxvY2F0aW9ucyA9IHsnZ251JyA6IG9wdGlvbnMuR05VLAogICAgICAgICAgICAgICAgICdzb2xhcmlzJyA6IG9wdGlvbnMuU09MQVJJUywKICAgICAgICAgICAgICAgICB9CgogICAgIyBwYXJzZSBvcHRpb25zCiAgICBmb3Igb3B0LCBhcmcgaW4gb3B0czoKICAgICAgICBpZiBvcHQgaW4gKCctaCcsICctLWhlbHAnKToKICAgICAgICAgICAgdXNhZ2UoMCkKICAgICAgICBlbGlmIG9wdCBpbiAoJy1hJywgJy0tZXh0cmFjdC1hbGwnKToKICAgICAgICAgICAgb3B0aW9ucy5leHRyYWN0YWxsID0gMQogICAgICAgIGVsaWYgb3B0IGluICgnLWQnLCAnLS1kZWZhdWx0LWRvbWFpbicpOgogICAgICAgICAgICBvcHRpb25zLm91dGZpbGUgPSBhcmcgKyAnLnBvdCcKICAgICAgICBlbGlmIG9wdCBpbiAoJy1FJywgJy0tZXNjYXBlJyk6CiAgICAgICAgICAgIG9wdGlvbnMuZXNjYXBlID0gMQogICAgICAgIGVsaWYgb3B0IGluICgnLUQnLCAnLS1kb2NzdHJpbmdzJyk6CiAgICAgICAgICAgIG9wdGlvbnMuZG9jc3RyaW5ncyA9IDEKICAgICAgICBlbGlmIG9wdCBpbiAoJy1rJywgJy0ta2V5d29yZCcpOgogICAgICAgICAgICBvcHRpb25zLmtleXdvcmRzLmFwcGVuZChhcmcpCiAgICAgICAgZWxpZiBvcHQgaW4gKCctSycsICctLW5vLWRlZmF1bHQta2V5d29yZHMnKToKICAgICAgICAgICAgZGVmYXVsdF9rZXl3b3JkcyA9IFtdCiAgICAgICAgZWxpZiBvcHQgaW4gKCctbicsICctLWFkZC1sb2NhdGlvbicpOgogICAgICAgICAgICBvcHRpb25zLndyaXRlbG9jYXRpb25zID0gMQogICAgICAgIGVsaWYgb3B0IGluICgnLS1uby1sb2NhdGlvbicsKToKICAgICAgICAgICAgb3B0aW9ucy53cml0ZWxvY2F0aW9ucyA9IDAKICAgICAgICBlbGlmIG9wdCBpbiAoJy1TJywgJy0tc3R5bGUnKToKICAgICAgICAgICAgb3B0aW9ucy5sb2NhdGlvbnN0eWxlID0gbG9jYXRpb25zLmdldChhcmcubG93ZXIoKSkKICAgICAgICAgICAgaWYgb3B0aW9ucy5sb2NhdGlvbnN0eWxlIGlzIE5vbmU6CiAgICAgICAgICAgICAgICB1c2FnZSgxLCBfKCdJbnZhbGlkIHZhbHVlIGZvciAtLXN0eWxlOiAlcycpICUgYXJnKQogICAgICAgIGVsaWYgb3B0IGluICgnLW8nLCAnLS1vdXRwdXQnKToKICAgICAgICAgICAgb3B0aW9ucy5vdXRmaWxlID0gYXJnCiAgICAgICAgZWxpZiBvcHQgaW4gKCctcCcsICctLW91dHB1dC1kaXInKToKICAgICAgICAgICAgb3B0aW9ucy5vdXRwYXRoID0gYXJnCiAgICAgICAgZWxpZiBvcHQgaW4gKCctdicsICctLXZlcmJvc2UnKToKICAgICAgICAgICAgb3B0aW9ucy52ZXJib3NlID0gMQogICAgICAgIGVsaWYgb3B0IGluICgnLVYnLCAnLS12ZXJzaW9uJyk6CiAgICAgICAgICAgIHByaW50IF8oJ3B5Z2V0dGV4dC5weSAoeGdldHRleHQgZm9yIFB5dGhvbikgJXMnKSAlIF9fdmVyc2lvbl9fCiAgICAgICAgICAgIHN5cy5leGl0KDApCiAgICAgICAgZWxpZiBvcHQgaW4gKCctdycsICctLXdpZHRoJyk6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIG9wdGlvbnMud2lkdGggPSBpbnQoYXJnKQogICAgICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICAgICAgICAgIHVzYWdlKDEsIF8oJy0td2lkdGggYXJndW1lbnQgbXVzdCBiZSBhbiBpbnRlZ2VyOiAlcycpICUgYXJnKQogICAgICAgIGVsaWYgb3B0IGluICgnLXgnLCAnLS1leGNsdWRlLWZpbGUnKToKICAgICAgICAgICAgb3B0aW9ucy5leGNsdWRlZmlsZW5hbWUgPSBhcmcKICAgICAgICBlbGlmIG9wdCBpbiAoJy1YJywgJy0tbm8tZG9jc3RyaW5ncycpOgogICAgICAgICAgICBmcCA9IG9wZW4oYXJnKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB3aGlsZSAxOgogICAgICAgICAgICAgICAgICAgIGxpbmUgPSBmcC5yZWFkbGluZSgpCiAgICAgICAgICAgICAgICAgICAgaWYgbm90IGxpbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5ub2RvY3N0cmluZ3NbbGluZVs6LTFdXSA9IDEKICAgICAgICAgICAgZmluYWxseToKICAgICAgICAgICAgICAgIGZwLmNsb3NlKCkKCiAgICAjIGNhbGN1bGF0ZSBlc2NhcGVzCiAgICBtYWtlX2VzY2FwZXMobm90IG9wdGlvbnMuZXNjYXBlKQoKICAgICMgY2FsY3VsYXRlIGFsbCBrZXl3b3JkcwogICAgb3B0aW9ucy5rZXl3b3Jkcy5leHRlbmQoZGVmYXVsdF9rZXl3b3JkcykKCiAgICAjIGluaXRpYWxpemUgbGlzdCBvZiBzdHJpbmdzIHRvIGV4Y2x1ZGUKICAgIGlmIG9wdGlvbnMuZXhjbHVkZWZpbGVuYW1lOgogICAgICAgIHRyeToKICAgICAgICAgICAgZnAgPSBvcGVuKG9wdGlvbnMuZXhjbHVkZWZpbGVuYW1lKQogICAgICAgICAgICBvcHRpb25zLnRvZXhjbHVkZSA9IGZwLnJlYWRsaW5lcygpCiAgICAgICAgICAgIGZwLmNsb3NlKCkKICAgICAgICBleGNlcHQgSU9FcnJvcjoKICAgICAgICAgICAgcHJpbnQgPj4gc3lzLnN0ZGVyciwgXygKICAgICAgICAgICAgICAgICJDYW4ndCByZWFkIC0tZXhjbHVkZS1maWxlOiAlcyIpICUgb3B0aW9ucy5leGNsdWRlZmlsZW5hbWUKICAgICAgICAgICAgc3lzLmV4aXQoMSkKICAgIGVsc2U6CiAgICAgICAgb3B0aW9ucy50b2V4Y2x1ZGUgPSBbXQoKICAgICMgcmVzb2x2ZSBhcmdzIHRvIG1vZHVsZSBsaXN0cwogICAgZXhwYW5kZWQgPSBbXQogICAgZm9yIGFyZyBpbiBhcmdzOgogICAgICAgIGlmIGFyZyA9PSAnLSc6CiAgICAgICAgICAgIGV4cGFuZGVkLmFwcGVuZChhcmcpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgZXhwYW5kZWQuZXh0ZW5kKGdldEZpbGVzRm9yTmFtZShhcmcpKQogICAgYXJncyA9IGV4cGFuZGVkCgogICAgIyBzbHVycCB0aHJvdWdoIGFsbCB0aGUgZmlsZXMKICAgIGVhdGVyID0gVG9rZW5FYXRlcihvcHRpb25zKQogICAgZm9yIGZpbGVuYW1lIGluIGFyZ3M6CiAgICAgICAgaWYgZmlsZW5hbWUgPT0gJy0nOgogICAgICAgICAgICBpZiBvcHRpb25zLnZlcmJvc2U6CiAgICAgICAgICAgICAgICBwcmludCBfKCdSZWFkaW5nIHN0YW5kYXJkIGlucHV0JykKICAgICAgICAgICAgZnAgPSBzeXMuc3RkaW4KICAgICAgICAgICAgY2xvc2VwID0gMAogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGlmIG9wdGlvbnMudmVyYm9zZToKICAgICAgICAgICAgICAgIHByaW50IF8oJ1dvcmtpbmcgb24gJXMnKSAlIGZpbGVuYW1lCiAgICAgICAgICAgIGZwID0gb3BlbihmaWxlbmFtZSkKICAgICAgICAgICAgY2xvc2VwID0gMQogICAgICAgIHRyeToKICAgICAgICAgICAgZWF0ZXIuc2V0X2ZpbGVuYW1lKGZpbGVuYW1lKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB0b2tlbml6ZS50b2tlbml6ZShmcC5yZWFkbGluZSwgZWF0ZXIpCiAgICAgICAgICAgIGV4Y2VwdCB0b2tlbml6ZS5Ub2tlbkVycm9yLCBlOgogICAgICAgICAgICAgICAgcHJpbnQgPj4gc3lzLnN0ZGVyciwgJyVzOiAlcywgbGluZSAlZCwgY29sdW1uICVkJyAlICgKICAgICAgICAgICAgICAgICAgICBlWzBdLCBmaWxlbmFtZSwgZVsxXVswXSwgZVsxXVsxXSkKICAgICAgICBmaW5hbGx5OgogICAgICAgICAgICBpZiBjbG9zZXA6CiAgICAgICAgICAgICAgICBmcC5jbG9zZSgpCgogICAgIyB3cml0ZSB0aGUgb3V0cHV0CiAgICBpZiBvcHRpb25zLm91dGZpbGUgPT0gJy0nOgogICAgICAgIGZwID0gc3lzLnN0ZG91dAogICAgICAgIGNsb3NlcCA9IDAKICAgIGVsc2U6CiAgICAgICAgaWYgb3B0aW9ucy5vdXRwYXRoOgogICAgICAgICAgICBvcHRpb25zLm91dGZpbGUgPSBvcy5wYXRoLmpvaW4ob3B0aW9ucy5vdXRwYXRoLCBvcHRpb25zLm91dGZpbGUpCiAgICAgICAgZnAgPSBvcGVuKG9wdGlvbnMub3V0ZmlsZSwgJ3cnKQogICAgICAgIGNsb3NlcCA9IDEKICAgIHRyeToKICAgICAgICBlYXRlci53cml0ZShmcCkKICAgIGZpbmFsbHk6CiAgICAgICAgaWYgY2xvc2VwOgogICAgICAgICAgICBmcC5jbG9zZSgpCgoMCmlmIF9fbmFtZV9fID09ICdfX21haW5fXyc6CiAgICBtYWluKCkKICAgICMgc29tZSBtb3JlIHRlc3Qgc3RyaW5ncwogICAgXyh1J2EgdW5pY29kZSBzdHJpbmcnKQogICAgIyB0aGlzIG9uZSBjcmVhdGVzIGEgd2FybmluZwogICAgXygnKioqIFNlZW4gdW5leHBlY3RlZCB0b2tlbiAiJSh0b2tlbilzIicpICUgeyd0b2tlbic6ICd0ZXN0J30KICAgIF8oJ21vcmUnICd0aGFuJyAnb25lJyAnc3RyaW5nJykK