IiIiUGFyc2VyIGZvciBjb21tYW5kIGxpbmUgb3B0aW9ucy4KClRoaXMgbW9kdWxlIGhlbHBzIHNjcmlwdHMgdG8gcGFyc2UgdGhlIGNvbW1hbmQgbGluZSBhcmd1bWVudHMgaW4Kc3lzLmFyZ3YuICBJdCBzdXBwb3J0cyB0aGUgc2FtZSBjb252ZW50aW9ucyBhcyB0aGUgVW5peCBnZXRvcHQoKQpmdW5jdGlvbiAoaW5jbHVkaW5nIHRoZSBzcGVjaWFsIG1lYW5pbmdzIG9mIGFyZ3VtZW50cyBvZiB0aGUgZm9ybSBgLScKYW5kIGAtLScpLiAgTG9uZyBvcHRpb25zIHNpbWlsYXIgdG8gdGhvc2Ugc3VwcG9ydGVkIGJ5IEdOVSBzb2Z0d2FyZQptYXkgYmUgdXNlZCBhcyB3ZWxsIHZpYSBhbiBvcHRpb25hbCB0aGlyZCBhcmd1bWVudC4gIFRoaXMgbW9kdWxlCnByb3ZpZGVzIHR3byBmdW5jdGlvbnMgYW5kIGFuIGV4Y2VwdGlvbjoKCmdldG9wdCgpIC0tIFBhcnNlIGNvbW1hbmQgbGluZSBvcHRpb25zCmdudV9nZXRvcHQoKSAtLSBMaWtlIGdldG9wdCgpLCBidXQgYWxsb3cgb3B0aW9uIGFuZCBub24tb3B0aW9uIGFyZ3VtZW50cwp0byBiZSBpbnRlcm1peGVkLiAKR2V0b3B0RXJyb3IgLS0gZXhjZXB0aW9uIChjbGFzcykgcmFpc2VkIHdpdGggJ29wdCcgYXR0cmlidXRlLCB3aGljaCBpcyB0aGUKb3B0aW9uIGludm9sdmVkIHdpdGggdGhlIGV4Y2VwdGlvbi4KIiIiCgojIExvbmcgb3B0aW9uIHN1cHBvcnQgYWRkZWQgYnkgTGFycyBXaXJ6ZW5pdXMgPGxpd0Bpa2kuZmk+LgojCiMgR2Vycml0IEhvbGwgPGdlcnJpdEBubC5saW51eC5vcmc+IG1vdmVkIHRoZSBzdHJpbmctYmFzZWQgZXhjZXB0aW9ucwojIHRvIGNsYXNzLWJhc2VkIGV4Y2VwdGlvbnMuCiMKIyBQZXRlciDFc3RyYW5kIDxhc3RyYW5kQGx5c2F0b3IubGl1LnNlPiBhZGRlZCBnbnVfZ2V0b3B0KCkuCiMKIyBUT0RPIGZvciBnbnVfZ2V0b3B0KCk6CiMKIyAtIEdOVSBnZXRvcHRfbG9uZ19vbmx5IG1lY2hhbmlzbQojIC0gYWxsb3cgdGhlIGNhbGxlciB0byBzcGVjaWZ5IG9yZGVyaW5nCiMgLSBSRVRVUk5fSU5fT1JERVIgb3B0aW9uCiMgLSBHTlUgZXh0ZW5zaW9uIHdpdGggJy0nIGFzIGZpcnN0IGNoYXJhY3RlciBvZiBvcHRpb24gc3RyaW5nCiMgLSBvcHRpb25hbCBhcmd1bWVudHMsIHNwZWNpZmllZCBieSBkb3VibGUgY29sb25zCiMgLSBhIG9wdGlvbiBzdHJpbmcgd2l0aCBhIFcgZm9sbG93ZWQgYnkgc2VtaWNvbG9uIHNob3VsZAojICAgdHJlYXQgIi1XIGZvbyIgYXMgIi0tZm9vIgoKX19hbGxfXyA9IFsiR2V0b3B0RXJyb3IiLCJlcnJvciIsImdldG9wdCJdCgppbXBvcnQgb3MKCmNsYXNzIEdldG9wdEVycm9yKEV4Y2VwdGlvbik6CiAgICBvcHQgPSAnJwogICAgbXNnID0gJycKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBtc2csIG9wdCk6CiAgICAgICAgc2VsZi5tc2cgPSBtc2cKICAgICAgICBzZWxmLm9wdCA9IG9wdAogICAgICAgIEV4Y2VwdGlvbi5fX2luaXRfXyhzZWxmLCBtc2csIG9wdCkKCiAgICBkZWYgX19zdHJfXyhzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5tc2cKCmVycm9yID0gR2V0b3B0RXJyb3IgIyBiYWNrd2FyZCBjb21wYXRpYmlsaXR5CgpkZWYgZ2V0b3B0KGFyZ3MsIHNob3J0b3B0cywgbG9uZ29wdHMgPSBbXSk6CiAgICAiIiJnZXRvcHQoYXJncywgb3B0aW9uc1ssIGxvbmdfb3B0aW9uc10pIC0+IG9wdHMsIGFyZ3MKCiAgICBQYXJzZXMgY29tbWFuZCBsaW5lIG9wdGlvbnMgYW5kIHBhcmFtZXRlciBsaXN0LiAgYXJncyBpcyB0aGUKICAgIGFyZ3VtZW50IGxpc3QgdG8gYmUgcGFyc2VkLCB3aXRob3V0IHRoZSBsZWFkaW5nIHJlZmVyZW5jZSB0byB0aGUKICAgIHJ1bm5pbmcgcHJvZ3JhbS4gIFR5cGljYWxseSwgdGhpcyBtZWFucyAic3lzLmFyZ3ZbMTpdIi4gIHNob3J0b3B0cwogICAgaXMgdGhlIHN0cmluZyBvZiBvcHRpb24gbGV0dGVycyB0aGF0IHRoZSBzY3JpcHQgd2FudHMgdG8KICAgIHJlY29nbml6ZSwgd2l0aCBvcHRpb25zIHRoYXQgcmVxdWlyZSBhbiBhcmd1bWVudCBmb2xsb3dlZCBieSBhCiAgICBjb2xvbiAoaS5lLiwgdGhlIHNhbWUgZm9ybWF0IHRoYXQgVW5peCBnZXRvcHQoKSB1c2VzKS4gIElmCiAgICBzcGVjaWZpZWQsIGxvbmdvcHRzIGlzIGEgbGlzdCBvZiBzdHJpbmdzIHdpdGggdGhlIG5hbWVzIG9mIHRoZQogICAgbG9uZyBvcHRpb25zIHdoaWNoIHNob3VsZCBiZSBzdXBwb3J0ZWQuICBUaGUgbGVhZGluZyAnLS0nCiAgICBjaGFyYWN0ZXJzIHNob3VsZCBub3QgYmUgaW5jbHVkZWQgaW4gdGhlIG9wdGlvbiBuYW1lLiAgT3B0aW9ucwogICAgd2hpY2ggcmVxdWlyZSBhbiBhcmd1bWVudCBzaG91bGQgYmUgZm9sbG93ZWQgYnkgYW4gZXF1YWwgc2lnbgogICAgKCc9JykuCgogICAgVGhlIHJldHVybiB2YWx1ZSBjb25zaXN0cyBvZiB0d28gZWxlbWVudHM6IHRoZSBmaXJzdCBpcyBhIGxpc3Qgb2YKICAgIChvcHRpb24sIHZhbHVlKSBwYWlyczsgdGhlIHNlY29uZCBpcyB0aGUgbGlzdCBvZiBwcm9ncmFtIGFyZ3VtZW50cwogICAgbGVmdCBhZnRlciB0aGUgb3B0aW9uIGxpc3Qgd2FzIHN0cmlwcGVkICh0aGlzIGlzIGEgdHJhaWxpbmcgc2xpY2UKICAgIG9mIHRoZSBmaXJzdCBhcmd1bWVudCkuICBFYWNoIG9wdGlvbi1hbmQtdmFsdWUgcGFpciByZXR1cm5lZCBoYXMKICAgIHRoZSBvcHRpb24gYXMgaXRzIGZpcnN0IGVsZW1lbnQsIHByZWZpeGVkIHdpdGggYSBoeXBoZW4gKGUuZy4sCiAgICAnLXgnKSwgYW5kIHRoZSBvcHRpb24gYXJndW1lbnQgYXMgaXRzIHNlY29uZCBlbGVtZW50LCBvciBhbiBlbXB0eQogICAgc3RyaW5nIGlmIHRoZSBvcHRpb24gaGFzIG5vIGFyZ3VtZW50LiAgVGhlIG9wdGlvbnMgb2NjdXIgaW4gdGhlCiAgICBsaXN0IGluIHRoZSBzYW1lIG9yZGVyIGluIHdoaWNoIHRoZXkgd2VyZSBmb3VuZCwgdGh1cyBhbGxvd2luZwogICAgbXVsdGlwbGUgb2NjdXJyZW5jZXMuICBMb25nIGFuZCBzaG9ydCBvcHRpb25zIG1heSBiZSBtaXhlZC4KCiAgICAiIiIKCiAgICBvcHRzID0gW10KICAgIGlmIHR5cGUobG9uZ29wdHMpID09IHR5cGUoIiIpOgogICAgICAgIGxvbmdvcHRzID0gW2xvbmdvcHRzXQogICAgZWxzZToKICAgICAgICBsb25nb3B0cyA9IGxpc3QobG9uZ29wdHMpCiAgICB3aGlsZSBhcmdzIGFuZCBhcmdzWzBdLnN0YXJ0c3dpdGgoJy0nKSBhbmQgYXJnc1swXSAhPSAnLSc6CiAgICAgICAgaWYgYXJnc1swXSA9PSAnLS0nOgogICAgICAgICAgICBhcmdzID0gYXJnc1sxOl0KICAgICAgICAgICAgYnJlYWsKICAgICAgICBpZiBhcmdzWzBdLnN0YXJ0c3dpdGgoJy0tJyk6CiAgICAgICAgICAgIG9wdHMsIGFyZ3MgPSBkb19sb25ncyhvcHRzLCBhcmdzWzBdWzI6XSwgbG9uZ29wdHMsIGFyZ3NbMTpdKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIG9wdHMsIGFyZ3MgPSBkb19zaG9ydHMob3B0cywgYXJnc1swXVsxOl0sIHNob3J0b3B0cywgYXJnc1sxOl0pCgogICAgcmV0dXJuIG9wdHMsIGFyZ3MKCmRlZiBnbnVfZ2V0b3B0KGFyZ3MsIHNob3J0b3B0cywgbG9uZ29wdHMgPSBbXSk6CiAgICAiIiJnZXRvcHQoYXJncywgb3B0aW9uc1ssIGxvbmdfb3B0aW9uc10pIC0+IG9wdHMsIGFyZ3MKCiAgICBUaGlzIGZ1bmN0aW9uIHdvcmtzIGxpa2UgZ2V0b3B0KCksIGV4Y2VwdCB0aGF0IEdOVSBzdHlsZSBzY2FubmluZwogICAgbW9kZSBpcyB1c2VkIGJ5IGRlZmF1bHQuIFRoaXMgbWVhbnMgdGhhdCBvcHRpb24gYW5kIG5vbi1vcHRpb24KICAgIGFyZ3VtZW50cyBtYXkgYmUgaW50ZXJtaXhlZC4gVGhlIGdldG9wdCgpIGZ1bmN0aW9uIHN0b3BzCiAgICBwcm9jZXNzaW5nIG9wdGlvbnMgYXMgc29vbiBhcyBhIG5vbi1vcHRpb24gYXJndW1lbnQgaXMKICAgIGVuY291bnRlcmVkLgoKICAgIElmIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIG9wdGlvbiBzdHJpbmcgaXMgYCsnLCBvciBpZiB0aGUKICAgIGVudmlyb25tZW50IHZhcmlhYmxlIFBPU0lYTFlfQ09SUkVDVCBpcyBzZXQsIHRoZW4gb3B0aW9uCiAgICBwcm9jZXNzaW5nIHN0b3BzIGFzIHNvb24gYXMgYSBub24tb3B0aW9uIGFyZ3VtZW50IGlzIGVuY291bnRlcmVkLgogICAgCiAgICAiIiIKCiAgICBvcHRzID0gW10KICAgIHByb2dfYXJncyA9IFtdCiAgICBpZiBpc2luc3RhbmNlKGxvbmdvcHRzLCBzdHIpOgogICAgICAgIGxvbmdvcHRzID0gW2xvbmdvcHRzXQogICAgZWxzZToKICAgICAgICBsb25nb3B0cyA9IGxpc3QobG9uZ29wdHMpCgogICAgIyBBbGxvdyBvcHRpb25zIGFmdGVyIG5vbi1vcHRpb24gYXJndW1lbnRzPwogICAgaWYgc2hvcnRvcHRzLnN0YXJ0c3dpdGgoJysnKToKICAgICAgICBzaG9ydG9wdHMgPSBzaG9ydG9wdHNbMTpdCiAgICAgICAgYWxsX29wdGlvbnNfZmlyc3QgPSBUcnVlCiAgICBlbGlmIG9zLmdldGVudigiUE9TSVhMWV9DT1JSRUNUIik6CiAgICAgICAgYWxsX29wdGlvbnNfZmlyc3QgPSBUcnVlCiAgICBlbHNlOgogICAgICAgIGFsbF9vcHRpb25zX2ZpcnN0ID0gRmFsc2UKCiAgICB3aGlsZSBhcmdzOgogICAgICAgIGlmIGFyZ3NbMF0gPT0gJy0tJzoKICAgICAgICAgICAgcHJvZ19hcmdzICs9IGFyZ3NbMTpdCiAgICAgICAgICAgIGJyZWFrCgogICAgICAgIGlmIGFyZ3NbMF1bOjJdID09ICctLSc6CiAgICAgICAgICAgIG9wdHMsIGFyZ3MgPSBkb19sb25ncyhvcHRzLCBhcmdzWzBdWzI6XSwgbG9uZ29wdHMsIGFyZ3NbMTpdKQogICAgICAgIGVsaWYgYXJnc1swXVs6MV0gPT0gJy0nOgogICAgICAgICAgICBvcHRzLCBhcmdzID0gZG9fc2hvcnRzKG9wdHMsIGFyZ3NbMF1bMTpdLCBzaG9ydG9wdHMsIGFyZ3NbMTpdKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGlmIGFsbF9vcHRpb25zX2ZpcnN0OgogICAgICAgICAgICAgICAgcHJvZ19hcmdzICs9IGFyZ3MKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBwcm9nX2FyZ3MuYXBwZW5kKGFyZ3NbMF0pCiAgICAgICAgICAgICAgICBhcmdzID0gYXJnc1sxOl0KCiAgICByZXR1cm4gb3B0cywgcHJvZ19hcmdzCgpkZWYgZG9fbG9uZ3Mob3B0cywgb3B0LCBsb25nb3B0cywgYXJncyk6CiAgICB0cnk6CiAgICAgICAgaSA9IG9wdC5pbmRleCgnPScpCiAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICBvcHRhcmcgPSBOb25lCiAgICBlbHNlOgogICAgICAgIG9wdCwgb3B0YXJnID0gb3B0WzppXSwgb3B0W2krMTpdCgogICAgaGFzX2FyZywgb3B0ID0gbG9uZ19oYXNfYXJncyhvcHQsIGxvbmdvcHRzKQogICAgaWYgaGFzX2FyZzoKICAgICAgICBpZiBvcHRhcmcgaXMgTm9uZToKICAgICAgICAgICAgaWYgbm90IGFyZ3M6CiAgICAgICAgICAgICAgICByYWlzZSBHZXRvcHRFcnJvcignb3B0aW9uIC0tJXMgcmVxdWlyZXMgYXJndW1lbnQnICUgb3B0LCBvcHQpCiAgICAgICAgICAgIG9wdGFyZywgYXJncyA9IGFyZ3NbMF0sIGFyZ3NbMTpdCiAgICBlbGlmIG9wdGFyZzoKICAgICAgICByYWlzZSBHZXRvcHRFcnJvcignb3B0aW9uIC0tJXMgbXVzdCBub3QgaGF2ZSBhbiBhcmd1bWVudCcgJSBvcHQsIG9wdCkKICAgIG9wdHMuYXBwZW5kKCgnLS0nICsgb3B0LCBvcHRhcmcgb3IgJycpKQogICAgcmV0dXJuIG9wdHMsIGFyZ3MKCiMgUmV0dXJuOgojICAgaGFzX2FyZz8KIyAgIGZ1bGwgb3B0aW9uIG5hbWUKZGVmIGxvbmdfaGFzX2FyZ3Mob3B0LCBsb25nb3B0cyk6CiAgICBwb3NzaWJpbGl0aWVzID0gW28gZm9yIG8gaW4gbG9uZ29wdHMgaWYgby5zdGFydHN3aXRoKG9wdCldCiAgICBpZiBub3QgcG9zc2liaWxpdGllczoKICAgICAgICByYWlzZSBHZXRvcHRFcnJvcignb3B0aW9uIC0tJXMgbm90IHJlY29nbml6ZWQnICUgb3B0LCBvcHQpCiAgICAjIElzIHRoZXJlIGFuIGV4YWN0IG1hdGNoPwogICAgaWYgb3B0IGluIHBvc3NpYmlsaXRpZXM6CiAgICAgICAgcmV0dXJuIEZhbHNlLCBvcHQKICAgIGVsaWYgb3B0ICsgJz0nIGluIHBvc3NpYmlsaXRpZXM6CiAgICAgICAgcmV0dXJuIFRydWUsIG9wdAogICAgIyBObyBleGFjdCBtYXRjaCwgc28gYmV0dGVyIGJlIHVuaXF1ZS4KICAgIGlmIGxlbihwb3NzaWJpbGl0aWVzKSA+IDE6CiAgICAgICAgIyBYWFggc2luY2UgcG9zc2liaWxpdGllcyBjb250YWlucyBhbGwgdmFsaWQgY29udGludWF0aW9ucywgbWlnaHQgYmUKICAgICAgICAjIG5pY2UgdG8gd29yayB0aGVtIGludG8gdGhlIGVycm9yIG1zZwogICAgICAgIHJhaXNlIEdldG9wdEVycm9yKCdvcHRpb24gLS0lcyBub3QgYSB1bmlxdWUgcHJlZml4JyAlIG9wdCwgb3B0KQogICAgYXNzZXJ0IGxlbihwb3NzaWJpbGl0aWVzKSA9PSAxCiAgICB1bmlxdWVfbWF0Y2ggPSBwb3NzaWJpbGl0aWVzWzBdCiAgICBoYXNfYXJnID0gdW5pcXVlX21hdGNoLmVuZHN3aXRoKCc9JykKICAgIGlmIGhhc19hcmc6CiAgICAgICAgdW5pcXVlX21hdGNoID0gdW5pcXVlX21hdGNoWzotMV0KICAgIHJldHVybiBoYXNfYXJnLCB1bmlxdWVfbWF0Y2gKCmRlZiBkb19zaG9ydHMob3B0cywgb3B0c3RyaW5nLCBzaG9ydG9wdHMsIGFyZ3MpOgogICAgd2hpbGUgb3B0c3RyaW5nICE9ICcnOgogICAgICAgIG9wdCwgb3B0c3RyaW5nID0gb3B0c3RyaW5nWzBdLCBvcHRzdHJpbmdbMTpdCiAgICAgICAgaWYgc2hvcnRfaGFzX2FyZyhvcHQsIHNob3J0b3B0cyk6CiAgICAgICAgICAgIGlmIG9wdHN0cmluZyA9PSAnJzoKICAgICAgICAgICAgICAgIGlmIG5vdCBhcmdzOgogICAgICAgICAgICAgICAgICAgIHJhaXNlIEdldG9wdEVycm9yKCdvcHRpb24gLSVzIHJlcXVpcmVzIGFyZ3VtZW50JyAlIG9wdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHQpCiAgICAgICAgICAgICAgICBvcHRzdHJpbmcsIGFyZ3MgPSBhcmdzWzBdLCBhcmdzWzE6XQogICAgICAgICAgICBvcHRhcmcsIG9wdHN0cmluZyA9IG9wdHN0cmluZywgJycKICAgICAgICBlbHNlOgogICAgICAgICAgICBvcHRhcmcgPSAnJwogICAgICAgIG9wdHMuYXBwZW5kKCgnLScgKyBvcHQsIG9wdGFyZykpCiAgICByZXR1cm4gb3B0cywgYXJncwoKZGVmIHNob3J0X2hhc19hcmcob3B0LCBzaG9ydG9wdHMpOgogICAgZm9yIGkgaW4gcmFuZ2UobGVuKHNob3J0b3B0cykpOgogICAgICAgIGlmIG9wdCA9PSBzaG9ydG9wdHNbaV0gIT0gJzonOgogICAgICAgICAgICByZXR1cm4gc2hvcnRvcHRzLnN0YXJ0c3dpdGgoJzonLCBpKzEpCiAgICByYWlzZSBHZXRvcHRFcnJvcignb3B0aW9uIC0lcyBub3QgcmVjb2duaXplZCcgJSBvcHQsIG9wdCkKCmlmIF9fbmFtZV9fID09ICdfX21haW5fXyc6CiAgICBpbXBvcnQgc3lzCiAgICBwcmludCBnZXRvcHQoc3lzLmFyZ3ZbMTpdLCAiYTpiIiwgWyJhbHBoYT0iLCAiYmV0YSJdKQo=