IiIiR2V0IHVzZWZ1bCBpbmZvcm1hdGlvbiBmcm9tIGxpdmUgUHl0aG9uIG9iamVjdHMuCgpUaGlzIG1vZHVsZSBlbmNhcHN1bGF0ZXMgdGhlIGludGVyZmFjZSBwcm92aWRlZCBieSB0aGUgaW50ZXJuYWwgc3BlY2lhbAphdHRyaWJ1dGVzIChmdW5jXyosIGNvXyosIGltXyosIHRiXyosIGV0Yy4pIGluIGEgZnJpZW5kbGllciBmYXNoaW9uLgpJdCBhbHNvIHByb3ZpZGVzIHNvbWUgaGVscCBmb3IgZXhhbWluaW5nIHNvdXJjZSBjb2RlIGFuZCBjbGFzcyBsYXlvdXQuCgpIZXJlIGFyZSBzb21lIG9mIHRoZSB1c2VmdWwgZnVuY3Rpb25zIHByb3ZpZGVkIGJ5IHRoaXMgbW9kdWxlOgoKICAgIGlzbW9kdWxlKCksIGlzY2xhc3MoKSwgaXNtZXRob2QoKSwgaXNmdW5jdGlvbigpLCBpc3RyYWNlYmFjaygpLAogICAgICAgIGlzZnJhbWUoKSwgaXNjb2RlKCksIGlzYnVpbHRpbigpLCBpc3JvdXRpbmUoKSAtIGNoZWNrIG9iamVjdCB0eXBlcwogICAgZ2V0bWVtYmVycygpIC0gZ2V0IG1lbWJlcnMgb2YgYW4gb2JqZWN0IHRoYXQgc2F0aXNmeSBhIGdpdmVuIGNvbmRpdGlvbgoKICAgIGdldGZpbGUoKSwgZ2V0c291cmNlZmlsZSgpLCBnZXRzb3VyY2UoKSAtIGZpbmQgYW4gb2JqZWN0J3Mgc291cmNlIGNvZGUKICAgIGdldGRvYygpLCBnZXRjb21tZW50cygpIC0gZ2V0IGRvY3VtZW50YXRpb24gb24gYW4gb2JqZWN0CiAgICBnZXRtb2R1bGUoKSAtIGRldGVybWluZSB0aGUgbW9kdWxlIHRoYXQgYW4gb2JqZWN0IGNhbWUgZnJvbQogICAgZ2V0Y2xhc3N0cmVlKCkgLSBhcnJhbmdlIGNsYXNzZXMgc28gYXMgdG8gcmVwcmVzZW50IHRoZWlyIGhpZXJhcmNoeQoKICAgIGdldGFyZ3NwZWMoKSwgZ2V0YXJndmFsdWVzKCkgLSBnZXQgaW5mbyBhYm91dCBmdW5jdGlvbiBhcmd1bWVudHMKICAgIGZvcm1hdGFyZ3NwZWMoKSwgZm9ybWF0YXJndmFsdWVzKCkgLSBmb3JtYXQgYW4gYXJndW1lbnQgc3BlYwogICAgZ2V0b3V0ZXJmcmFtZXMoKSwgZ2V0aW5uZXJmcmFtZXMoKSAtIGdldCBpbmZvIGFib3V0IGZyYW1lcwogICAgY3VycmVudGZyYW1lKCkgLSBnZXQgdGhlIGN1cnJlbnQgc3RhY2sgZnJhbWUKICAgIHN0YWNrKCksIHRyYWNlKCkgLSBnZXQgaW5mbyBhYm91dCBmcmFtZXMgb24gdGhlIHN0YWNrIG9yIGluIGEgdHJhY2ViYWNrCiIiIgoKIyBUaGlzIG1vZHVsZSBpcyBpbiB0aGUgcHVibGljIGRvbWFpbi4gIE5vIHdhcnJhbnRpZXMuCgpfX2F1dGhvcl9fID0gJ0thLVBpbmcgWWVlIDxwaW5nQGxmdy5vcmc+JwpfX2RhdGVfXyA9ICcxIEphbiAyMDAxJwoKaW1wb3J0IHN5cywgb3MsIHR5cGVzLCBzdHJpbmcsIHJlLCBkaXMsIGltcCwgdG9rZW5pemUKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gdHlwZS1jaGVja2luZwpkZWYgaXNtb2R1bGUob2JqZWN0KToKICAgICIiIlJldHVybiB0cnVlIGlmIHRoZSBvYmplY3QgaXMgYSBtb2R1bGUuCgogICAgTW9kdWxlIG9iamVjdHMgcHJvdmlkZSB0aGVzZSBhdHRyaWJ1dGVzOgogICAgICAgIF9fZG9jX18gICAgICAgICBkb2N1bWVudGF0aW9uIHN0cmluZwogICAgICAgIF9fZmlsZV9fICAgICAgICBmaWxlbmFtZSAobWlzc2luZyBmb3IgYnVpbHQtaW4gbW9kdWxlcykiIiIKICAgIHJldHVybiBpc2luc3RhbmNlKG9iamVjdCwgdHlwZXMuTW9kdWxlVHlwZSkKCmRlZiBpc2NsYXNzKG9iamVjdCk6CiAgICAiIiJSZXR1cm4gdHJ1ZSBpZiB0aGUgb2JqZWN0IGlzIGEgY2xhc3MuCgogICAgQ2xhc3Mgb2JqZWN0cyBwcm92aWRlIHRoZXNlIGF0dHJpYnV0ZXM6CiAgICAgICAgX19kb2NfXyAgICAgICAgIGRvY3VtZW50YXRpb24gc3RyaW5nCiAgICAgICAgX19tb2R1bGVfXyAgICAgIG5hbWUgb2YgbW9kdWxlIGluIHdoaWNoIHRoaXMgY2xhc3Mgd2FzIGRlZmluZWQiIiIKICAgIHJldHVybiBpc2luc3RhbmNlKG9iamVjdCwgdHlwZXMuQ2xhc3NUeXBlKSBvciBoYXNhdHRyKG9iamVjdCwgJ19fYmFzZXNfXycpCgpkZWYgaXNtZXRob2Qob2JqZWN0KToKICAgICIiIlJldHVybiB0cnVlIGlmIHRoZSBvYmplY3QgaXMgYW4gaW5zdGFuY2UgbWV0aG9kLgoKICAgIEluc3RhbmNlIG1ldGhvZCBvYmplY3RzIHByb3ZpZGUgdGhlc2UgYXR0cmlidXRlczoKICAgICAgICBfX2RvY19fICAgICAgICAgZG9jdW1lbnRhdGlvbiBzdHJpbmcKICAgICAgICBfX25hbWVfXyAgICAgICAgbmFtZSB3aXRoIHdoaWNoIHRoaXMgbWV0aG9kIHdhcyBkZWZpbmVkCiAgICAgICAgaW1fY2xhc3MgICAgICAgIGNsYXNzIG9iamVjdCBpbiB3aGljaCB0aGlzIG1ldGhvZCBiZWxvbmdzCiAgICAgICAgaW1fZnVuYyAgICAgICAgIGZ1bmN0aW9uIG9iamVjdCBjb250YWluaW5nIGltcGxlbWVudGF0aW9uIG9mIG1ldGhvZAogICAgICAgIGltX3NlbGYgICAgICAgICBpbnN0YW5jZSB0byB3aGljaCB0aGlzIG1ldGhvZCBpcyBib3VuZCwgb3IgTm9uZSIiIgogICAgcmV0dXJuIGlzaW5zdGFuY2Uob2JqZWN0LCB0eXBlcy5NZXRob2RUeXBlKQoKZGVmIGlzbWV0aG9kZGVzY3JpcHRvcihvYmplY3QpOgogICAgIiIiUmV0dXJuIHRydWUgaWYgdGhlIG9iamVjdCBpcyBhIG1ldGhvZCBkZXNjcmlwdG9yLgoKICAgIEJ1dCBub3QgaWYgaXNtZXRob2QoKSBvciBpc2NsYXNzKCkgb3IgaXNmdW5jdGlvbigpIGFyZSB0cnVlLgoKICAgIFRoaXMgaXMgbmV3IGluIFB5dGhvbiAyLjIsIGFuZCwgZm9yIGV4YW1wbGUsIGlzIHRydWUgb2YgaW50Ll9fYWRkX18uCiAgICBBbiBvYmplY3QgcGFzc2luZyB0aGlzIHRlc3QgaGFzIGEgX19nZXRfXyBhdHRyaWJ1dGUgYnV0IG5vdCBhIF9fc2V0X18KICAgIGF0dHJpYnV0ZSwgYnV0IGJleW9uZCB0aGF0IHRoZSBzZXQgb2YgYXR0cmlidXRlcyB2YXJpZXMuICBfX25hbWVfXyBpcwogICAgdXN1YWxseSBzZW5zaWJsZSwgYW5kIF9fZG9jX18gb2Z0ZW4gaXMuCgogICAgTWV0aG9kcyBpbXBsZW1lbnRlZCB2aWEgZGVzY3JpcHRvcnMgdGhhdCBhbHNvIHBhc3Mgb25lIG9mIHRoZSBvdGhlcgogICAgdGVzdHMgcmV0dXJuIGZhbHNlIGZyb20gdGhlIGlzbWV0aG9kZGVzY3JpcHRvcigpIHRlc3QsIHNpbXBseSBiZWNhdXNlCiAgICB0aGUgb3RoZXIgdGVzdHMgcHJvbWlzZSBtb3JlIC0tIHlvdSBjYW4sIGUuZy4sIGNvdW50IG9uIGhhdmluZyB0aGUKICAgIGltX2Z1bmMgYXR0cmlidXRlIChldGMpIHdoZW4gYW4gb2JqZWN0IHBhc3NlcyBpc21ldGhvZCgpLiIiIgogICAgcmV0dXJuIChoYXNhdHRyKG9iamVjdCwgIl9fZ2V0X18iKQogICAgICAgICAgICBhbmQgbm90IGhhc2F0dHIob2JqZWN0LCAiX19zZXRfXyIpICMgZWxzZSBpdCdzIGEgZGF0YSBkZXNjcmlwdG9yCiAgICAgICAgICAgIGFuZCBub3QgaXNtZXRob2Qob2JqZWN0KSAgICAgICAgICAgIyBtdXR1YWwgZXhjbHVzaW9uCiAgICAgICAgICAgIGFuZCBub3QgaXNmdW5jdGlvbihvYmplY3QpCiAgICAgICAgICAgIGFuZCBub3QgaXNjbGFzcyhvYmplY3QpKQoKZGVmIGlzZnVuY3Rpb24ob2JqZWN0KToKICAgICIiIlJldHVybiB0cnVlIGlmIHRoZSBvYmplY3QgaXMgYSB1c2VyLWRlZmluZWQgZnVuY3Rpb24uCgogICAgRnVuY3Rpb24gb2JqZWN0cyBwcm92aWRlIHRoZXNlIGF0dHJpYnV0ZXM6CiAgICAgICAgX19kb2NfXyAgICAgICAgIGRvY3VtZW50YXRpb24gc3RyaW5nCiAgICAgICAgX19uYW1lX18gICAgICAgIG5hbWUgd2l0aCB3aGljaCB0aGlzIGZ1bmN0aW9uIHdhcyBkZWZpbmVkCiAgICAgICAgZnVuY19jb2RlICAgICAgIGNvZGUgb2JqZWN0IGNvbnRhaW5pbmcgY29tcGlsZWQgZnVuY3Rpb24gYnl0ZWNvZGUKICAgICAgICBmdW5jX2RlZmF1bHRzICAgdHVwbGUgb2YgYW55IGRlZmF1bHQgdmFsdWVzIGZvciBhcmd1bWVudHMKICAgICAgICBmdW5jX2RvYyAgICAgICAgKHNhbWUgYXMgX19kb2NfXykKICAgICAgICBmdW5jX2dsb2JhbHMgICAgZ2xvYmFsIG5hbWVzcGFjZSBpbiB3aGljaCB0aGlzIGZ1bmN0aW9uIHdhcyBkZWZpbmVkCiAgICAgICAgZnVuY19uYW1lICAgICAgIChzYW1lIGFzIF9fbmFtZV9fKSIiIgogICAgcmV0dXJuIGlzaW5zdGFuY2Uob2JqZWN0LCB0eXBlcy5GdW5jdGlvblR5cGUpCgpkZWYgaXN0cmFjZWJhY2sob2JqZWN0KToKICAgICIiIlJldHVybiB0cnVlIGlmIHRoZSBvYmplY3QgaXMgYSB0cmFjZWJhY2suCgogICAgVHJhY2ViYWNrIG9iamVjdHMgcHJvdmlkZSB0aGVzZSBhdHRyaWJ1dGVzOgogICAgICAgIHRiX2ZyYW1lICAgICAgICBmcmFtZSBvYmplY3QgYXQgdGhpcyBsZXZlbAogICAgICAgIHRiX2xhc3RpICAgICAgICBpbmRleCBvZiBsYXN0IGF0dGVtcHRlZCBpbnN0cnVjdGlvbiBpbiBieXRlY29kZQogICAgICAgIHRiX2xpbmVubyAgICAgICBjdXJyZW50IGxpbmUgbnVtYmVyIGluIFB5dGhvbiBzb3VyY2UgY29kZQogICAgICAgIHRiX25leHQgICAgICAgICBuZXh0IGlubmVyIHRyYWNlYmFjayBvYmplY3QgKGNhbGxlZCBieSB0aGlzIGxldmVsKSIiIgogICAgcmV0dXJuIGlzaW5zdGFuY2Uob2JqZWN0LCB0eXBlcy5UcmFjZWJhY2tUeXBlKQoKZGVmIGlzZnJhbWUob2JqZWN0KToKICAgICIiIlJldHVybiB0cnVlIGlmIHRoZSBvYmplY3QgaXMgYSBmcmFtZSBvYmplY3QuCgogICAgRnJhbWUgb2JqZWN0cyBwcm92aWRlIHRoZXNlIGF0dHJpYnV0ZXM6CiAgICAgICAgZl9iYWNrICAgICAgICAgIG5leHQgb3V0ZXIgZnJhbWUgb2JqZWN0ICh0aGlzIGZyYW1lJ3MgY2FsbGVyKQogICAgICAgIGZfYnVpbHRpbnMgICAgICBidWlsdC1pbiBuYW1lc3BhY2Ugc2VlbiBieSB0aGlzIGZyYW1lCiAgICAgICAgZl9jb2RlICAgICAgICAgIGNvZGUgb2JqZWN0IGJlaW5nIGV4ZWN1dGVkIGluIHRoaXMgZnJhbWUKICAgICAgICBmX2V4Y190cmFjZWJhY2sgdHJhY2ViYWNrIGlmIHJhaXNlZCBpbiB0aGlzIGZyYW1lLCBvciBOb25lCiAgICAgICAgZl9leGNfdHlwZSAgICAgIGV4Y2VwdGlvbiB0eXBlIGlmIHJhaXNlZCBpbiB0aGlzIGZyYW1lLCBvciBOb25lCiAgICAgICAgZl9leGNfdmFsdWUgICAgIGV4Y2VwdGlvbiB2YWx1ZSBpZiByYWlzZWQgaW4gdGhpcyBmcmFtZSwgb3IgTm9uZQogICAgICAgIGZfZ2xvYmFscyAgICAgICBnbG9iYWwgbmFtZXNwYWNlIHNlZW4gYnkgdGhpcyBmcmFtZQogICAgICAgIGZfbGFzdGkgICAgICAgICBpbmRleCBvZiBsYXN0IGF0dGVtcHRlZCBpbnN0cnVjdGlvbiBpbiBieXRlY29kZQogICAgICAgIGZfbGluZW5vICAgICAgICBjdXJyZW50IGxpbmUgbnVtYmVyIGluIFB5dGhvbiBzb3VyY2UgY29kZQogICAgICAgIGZfbG9jYWxzICAgICAgICBsb2NhbCBuYW1lc3BhY2Ugc2VlbiBieSB0aGlzIGZyYW1lCiAgICAgICAgZl9yZXN0cmljdGVkICAgIDAgb3IgMSBpZiBmcmFtZSBpcyBpbiByZXN0cmljdGVkIGV4ZWN1dGlvbiBtb2RlCiAgICAgICAgZl90cmFjZSAgICAgICAgIHRyYWNpbmcgZnVuY3Rpb24gZm9yIHRoaXMgZnJhbWUsIG9yIE5vbmUiIiIKICAgIHJldHVybiBpc2luc3RhbmNlKG9iamVjdCwgdHlwZXMuRnJhbWVUeXBlKQoKZGVmIGlzY29kZShvYmplY3QpOgogICAgIiIiUmV0dXJuIHRydWUgaWYgdGhlIG9iamVjdCBpcyBhIGNvZGUgb2JqZWN0LgoKICAgIENvZGUgb2JqZWN0cyBwcm92aWRlIHRoZXNlIGF0dHJpYnV0ZXM6CiAgICAgICAgY29fYXJnY291bnQgICAgIG51bWJlciBvZiBhcmd1bWVudHMgKG5vdCBpbmNsdWRpbmcgKiBvciAqKiBhcmdzKQogICAgICAgIGNvX2NvZGUgICAgICAgICBzdHJpbmcgb2YgcmF3IGNvbXBpbGVkIGJ5dGVjb2RlCiAgICAgICAgY29fY29uc3RzICAgICAgIHR1cGxlIG9mIGNvbnN0YW50cyB1c2VkIGluIHRoZSBieXRlY29kZQogICAgICAgIGNvX2ZpbGVuYW1lICAgICBuYW1lIG9mIGZpbGUgaW4gd2hpY2ggdGhpcyBjb2RlIG9iamVjdCB3YXMgY3JlYXRlZAogICAgICAgIGNvX2ZpcnN0bGluZW5vICBudW1iZXIgb2YgZmlyc3QgbGluZSBpbiBQeXRob24gc291cmNlIGNvZGUKICAgICAgICBjb19mbGFncyAgICAgICAgYml0bWFwOiAxPW9wdGltaXplZCB8IDI9bmV3bG9jYWxzIHwgND0qYXJnIHwgOD0qKmFyZwogICAgICAgIGNvX2xub3RhYiAgICAgICBlbmNvZGVkIG1hcHBpbmcgb2YgbGluZSBudW1iZXJzIHRvIGJ5dGVjb2RlIGluZGljZXMKICAgICAgICBjb19uYW1lICAgICAgICAgbmFtZSB3aXRoIHdoaWNoIHRoaXMgY29kZSBvYmplY3Qgd2FzIGRlZmluZWQKICAgICAgICBjb19uYW1lcyAgICAgICAgdHVwbGUgb2YgbmFtZXMgb2YgbG9jYWwgdmFyaWFibGVzCiAgICAgICAgY29fbmxvY2FscyAgICAgIG51bWJlciBvZiBsb2NhbCB2YXJpYWJsZXMKICAgICAgICBjb19zdGFja3NpemUgICAgdmlydHVhbCBtYWNoaW5lIHN0YWNrIHNwYWNlIHJlcXVpcmVkCiAgICAgICAgY29fdmFybmFtZXMgICAgIHR1cGxlIG9mIG5hbWVzIG9mIGFyZ3VtZW50cyBhbmQgbG9jYWwgdmFyaWFibGVzIiIiCiAgICByZXR1cm4gaXNpbnN0YW5jZShvYmplY3QsIHR5cGVzLkNvZGVUeXBlKQoKZGVmIGlzYnVpbHRpbihvYmplY3QpOgogICAgIiIiUmV0dXJuIHRydWUgaWYgdGhlIG9iamVjdCBpcyBhIGJ1aWx0LWluIGZ1bmN0aW9uIG9yIG1ldGhvZC4KCiAgICBCdWlsdC1pbiBmdW5jdGlvbnMgYW5kIG1ldGhvZHMgcHJvdmlkZSB0aGVzZSBhdHRyaWJ1dGVzOgogICAgICAgIF9fZG9jX18gICAgICAgICBkb2N1bWVudGF0aW9uIHN0cmluZwogICAgICAgIF9fbmFtZV9fICAgICAgICBvcmlnaW5hbCBuYW1lIG9mIHRoaXMgZnVuY3Rpb24gb3IgbWV0aG9kCiAgICAgICAgX19zZWxmX18gICAgICAgIGluc3RhbmNlIHRvIHdoaWNoIGEgbWV0aG9kIGlzIGJvdW5kLCBvciBOb25lIiIiCiAgICByZXR1cm4gaXNpbnN0YW5jZShvYmplY3QsIHR5cGVzLkJ1aWx0aW5GdW5jdGlvblR5cGUpCgpkZWYgaXNyb3V0aW5lKG9iamVjdCk6CiAgICAiIiJSZXR1cm4gdHJ1ZSBpZiB0aGUgb2JqZWN0IGlzIGFueSBraW5kIG9mIGZ1bmN0aW9uIG9yIG1ldGhvZC4iIiIKICAgIHJldHVybiAoaXNidWlsdGluKG9iamVjdCkKICAgICAgICAgICAgb3IgaXNmdW5jdGlvbihvYmplY3QpCiAgICAgICAgICAgIG9yIGlzbWV0aG9kKG9iamVjdCkKICAgICAgICAgICAgb3IgaXNtZXRob2RkZXNjcmlwdG9yKG9iamVjdCkpCgpkZWYgZ2V0bWVtYmVycyhvYmplY3QsIHByZWRpY2F0ZT1Ob25lKToKICAgICIiIlJldHVybiBhbGwgbWVtYmVycyBvZiBhbiBvYmplY3QgYXMgKG5hbWUsIHZhbHVlKSBwYWlycyBzb3J0ZWQgYnkgbmFtZS4KICAgIE9wdGlvbmFsbHksIG9ubHkgcmV0dXJuIG1lbWJlcnMgdGhhdCBzYXRpc2Z5IGEgZ2l2ZW4gcHJlZGljYXRlLiIiIgogICAgcmVzdWx0cyA9IFtdCiAgICBmb3Iga2V5IGluIGRpcihvYmplY3QpOgogICAgICAgIHZhbHVlID0gZ2V0YXR0cihvYmplY3QsIGtleSkKICAgICAgICBpZiBub3QgcHJlZGljYXRlIG9yIHByZWRpY2F0ZSh2YWx1ZSk6CiAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKChrZXksIHZhbHVlKSkKICAgIHJlc3VsdHMuc29ydCgpCiAgICByZXR1cm4gcmVzdWx0cwoKZGVmIGNsYXNzaWZ5X2NsYXNzX2F0dHJzKGNscyk6CiAgICAiIiJSZXR1cm4gbGlzdCBvZiBhdHRyaWJ1dGUtZGVzY3JpcHRvciB0dXBsZXMuCgogICAgRm9yIGVhY2ggbmFtZSBpbiBkaXIoY2xzKSwgdGhlIHJldHVybiBsaXN0IGNvbnRhaW5zIGEgNC10dXBsZQogICAgd2l0aCB0aGVzZSBlbGVtZW50czoKCiAgICAgICAgMC4gVGhlIG5hbWUgKGEgc3RyaW5nKS4KCiAgICAgICAgMS4gVGhlIGtpbmQgb2YgYXR0cmlidXRlIHRoaXMgaXMsIG9uZSBvZiB0aGVzZSBzdHJpbmdzOgogICAgICAgICAgICAgICAnY2xhc3MgbWV0aG9kJyAgICBjcmVhdGVkIHZpYSBjbGFzc21ldGhvZCgpCiAgICAgICAgICAgICAgICdzdGF0aWMgbWV0aG9kJyAgIGNyZWF0ZWQgdmlhIHN0YXRpY21ldGhvZCgpCiAgICAgICAgICAgICAgICdwcm9wZXJ0eScgICAgICAgIGNyZWF0ZWQgdmlhIHByb3BlcnR5KCkKICAgICAgICAgICAgICAgJ21ldGhvZCcgICAgICAgICAgYW55IG90aGVyIGZsYXZvciBvZiBtZXRob2QKICAgICAgICAgICAgICAgJ2RhdGEnICAgICAgICAgICAgbm90IGEgbWV0aG9kCgogICAgICAgIDIuIFRoZSBjbGFzcyB3aGljaCBkZWZpbmVkIHRoaXMgYXR0cmlidXRlIChhIGNsYXNzKS4KCiAgICAgICAgMy4gVGhlIG9iamVjdCBhcyBvYnRhaW5lZCBkaXJlY3RseSBmcm9tIHRoZSBkZWZpbmluZyBjbGFzcydzCiAgICAgICAgICAgX19kaWN0X18sIG5vdCB2aWEgZ2V0YXR0ci4gIFRoaXMgaXMgZXNwZWNpYWxseSBpbXBvcnRhbnQgZm9yCiAgICAgICAgICAgZGF0YSBhdHRyaWJ1dGVzOiAgQy5kYXRhIGlzIGp1c3QgYSBkYXRhIG9iamVjdCwgYnV0CiAgICAgICAgICAgQy5fX2RpY3RfX1snZGF0YSddIG1heSBiZSBhIGRhdGEgZGVzY3JpcHRvciB3aXRoIGFkZGl0aW9uYWwKICAgICAgICAgICBpbmZvLCBsaWtlIGEgX19kb2NfXyBzdHJpbmcuCiAgICAiIiIKCiAgICBtcm8gPSBnZXRtcm8oY2xzKQogICAgbmFtZXMgPSBkaXIoY2xzKQogICAgcmVzdWx0ID0gW10KICAgIGZvciBuYW1lIGluIG5hbWVzOgogICAgICAgICMgR2V0IHRoZSBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBuYW1lLgogICAgICAgICMgR2V0dGluZyBhbiBvYmogZnJvbSB0aGUgX19kaWN0X18gc29tZXRpbWVzIHJldmVhbHMgbW9yZSB0aGFuCiAgICAgICAgIyB1c2luZyBnZXRhdHRyLiAgU3RhdGljIGFuZCBjbGFzcyBtZXRob2RzIGFyZSBkcmFtYXRpYyBleGFtcGxlcy4KICAgICAgICBpZiBuYW1lIGluIGNscy5fX2RpY3RfXzoKICAgICAgICAgICAgb2JqID0gY2xzLl9fZGljdF9fW25hbWVdCiAgICAgICAgZWxzZToKICAgICAgICAgICAgb2JqID0gZ2V0YXR0cihjbHMsIG5hbWUpCgogICAgICAgICMgRmlndXJlIG91dCB3aGVyZSBpdCB3YXMgZGVmaW5lZC4KICAgICAgICBob21lY2xzID0gZ2V0YXR0cihvYmosICJfX29iamNsYXNzX18iLCBOb25lKQogICAgICAgIGlmIGhvbWVjbHMgaXMgTm9uZToKICAgICAgICAgICAgIyBzZWFyY2ggdGhlIGRpY3RzLgogICAgICAgICAgICBmb3IgYmFzZSBpbiBtcm86CiAgICAgICAgICAgICAgICBpZiBuYW1lIGluIGJhc2UuX19kaWN0X186CiAgICAgICAgICAgICAgICAgICAgaG9tZWNscyA9IGJhc2UKICAgICAgICAgICAgICAgICAgICBicmVhawoKICAgICAgICAjIEdldCB0aGUgb2JqZWN0IGFnYWluLCBpbiBvcmRlciB0byBnZXQgaXQgZnJvbSB0aGUgZGVmaW5pbmcKICAgICAgICAjIF9fZGljdF9fIGluc3RlYWQgb2YgdmlhIGdldGF0dHIgKGlmIHBvc3NpYmxlKS4KICAgICAgICBpZiBob21lY2xzIGlzIG5vdCBOb25lIGFuZCBuYW1lIGluIGhvbWVjbHMuX19kaWN0X186CiAgICAgICAgICAgIG9iaiA9IGhvbWVjbHMuX19kaWN0X19bbmFtZV0KCiAgICAgICAgIyBBbHNvIGdldCB0aGUgb2JqZWN0IHZpYSBnZXRhdHRyLgogICAgICAgIG9ial92aWFfZ2V0YXR0ciA9IGdldGF0dHIoY2xzLCBuYW1lKQoKICAgICAgICAjIENsYXNzaWZ5IHRoZSBvYmplY3QuCiAgICAgICAgaWYgaXNpbnN0YW5jZShvYmosIHN0YXRpY21ldGhvZCk6CiAgICAgICAgICAgIGtpbmQgPSAic3RhdGljIG1ldGhvZCIKICAgICAgICBlbGlmIGlzaW5zdGFuY2Uob2JqLCBjbGFzc21ldGhvZCk6CiAgICAgICAgICAgIGtpbmQgPSAiY2xhc3MgbWV0aG9kIgogICAgICAgIGVsaWYgaXNpbnN0YW5jZShvYmosIHByb3BlcnR5KToKICAgICAgICAgICAga2luZCA9ICJwcm9wZXJ0eSIKICAgICAgICBlbGlmIChpc21ldGhvZChvYmpfdmlhX2dldGF0dHIpIG9yCiAgICAgICAgICAgICAgaXNtZXRob2RkZXNjcmlwdG9yKG9ial92aWFfZ2V0YXR0cikpOgogICAgICAgICAgICBraW5kID0gIm1ldGhvZCIKICAgICAgICBlbHNlOgogICAgICAgICAgICBraW5kID0gImRhdGEiCgogICAgICAgIHJlc3VsdC5hcHBlbmQoKG5hbWUsIGtpbmQsIGhvbWVjbHMsIG9iaikpCgogICAgcmV0dXJuIHJlc3VsdAoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBjbGFzcyBoZWxwZXJzCmRlZiBfc2VhcmNoYmFzZXMoY2xzLCBhY2N1bSk6CiAgICAjIFNpbXVsYXRlIHRoZSAiY2xhc3NpYyBjbGFzcyIgc2VhcmNoIG9yZGVyLgogICAgaWYgY2xzIGluIGFjY3VtOgogICAgICAgIHJldHVybgogICAgYWNjdW0uYXBwZW5kKGNscykKICAgIGZvciBiYXNlIGluIGNscy5fX2Jhc2VzX186CiAgICAgICAgX3NlYXJjaGJhc2VzKGJhc2UsIGFjY3VtKQoKZGVmIGdldG1ybyhjbHMpOgogICAgIlJldHVybiB0dXBsZSBvZiBiYXNlIGNsYXNzZXMgKGluY2x1ZGluZyBjbHMpIGluIG1ldGhvZCByZXNvbHV0aW9uIG9yZGVyLiIKICAgIGlmIGhhc2F0dHIoY2xzLCAiX19tcm9fXyIpOgogICAgICAgIHJldHVybiBjbHMuX19tcm9fXwogICAgZWxzZToKICAgICAgICByZXN1bHQgPSBbXQogICAgICAgIF9zZWFyY2hiYXNlcyhjbHMsIHJlc3VsdCkKICAgICAgICByZXR1cm4gdHVwbGUocmVzdWx0KQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBzb3VyY2UgY29kZSBleHRyYWN0aW9uCmRlZiBpbmRlbnRzaXplKGxpbmUpOgogICAgIiIiUmV0dXJuIHRoZSBpbmRlbnQgc2l6ZSwgaW4gc3BhY2VzLCBhdCB0aGUgc3RhcnQgb2YgYSBsaW5lIG9mIHRleHQuIiIiCiAgICBleHBsaW5lID0gc3RyaW5nLmV4cGFuZHRhYnMobGluZSkKICAgIHJldHVybiBsZW4oZXhwbGluZSkgLSBsZW4oc3RyaW5nLmxzdHJpcChleHBsaW5lKSkKCmRlZiBnZXRkb2Mob2JqZWN0KToKICAgICIiIkdldCB0aGUgZG9jdW1lbnRhdGlvbiBzdHJpbmcgZm9yIGFuIG9iamVjdC4KCiAgICBBbGwgdGFicyBhcmUgZXhwYW5kZWQgdG8gc3BhY2VzLiAgVG8gY2xlYW4gdXAgZG9jc3RyaW5ncyB0aGF0IGFyZQogICAgaW5kZW50ZWQgdG8gbGluZSB1cCB3aXRoIGJsb2NrcyBvZiBjb2RlLCBhbnkgd2hpdGVzcGFjZSB0aGFuIGNhbiBiZQogICAgdW5pZm9ybWx5IHJlbW92ZWQgZnJvbSB0aGUgc2Vjb25kIGxpbmUgb253YXJkcyBpcyByZW1vdmVkLiIiIgogICAgaWYgaGFzYXR0cihvYmplY3QsICdfX2RvY19fJykgYW5kIG9iamVjdC5fX2RvY19fOgogICAgICAgIGxpbmVzID0gc3RyaW5nLnNwbGl0KHN0cmluZy5leHBhbmR0YWJzKG9iamVjdC5fX2RvY19fKSwgJ1xuJykKICAgICAgICBtYXJnaW4gPSBOb25lCiAgICAgICAgZm9yIGxpbmUgaW4gbGluZXNbMTpdOgogICAgICAgICAgICBjb250ZW50ID0gbGVuKHN0cmluZy5sc3RyaXAobGluZSkpCiAgICAgICAgICAgIGlmIG5vdCBjb250ZW50OiBjb250aW51ZQogICAgICAgICAgICBpbmRlbnQgPSBsZW4obGluZSkgLSBjb250ZW50CiAgICAgICAgICAgIGlmIG1hcmdpbiBpcyBOb25lOiBtYXJnaW4gPSBpbmRlbnQKICAgICAgICAgICAgZWxzZTogbWFyZ2luID0gbWluKG1hcmdpbiwgaW5kZW50KQogICAgICAgIGlmIG1hcmdpbiBpcyBub3QgTm9uZToKICAgICAgICAgICAgZm9yIGkgaW4gcmFuZ2UoMSwgbGVuKGxpbmVzKSk6IGxpbmVzW2ldID0gbGluZXNbaV1bbWFyZ2luOl0KICAgICAgICByZXR1cm4gc3RyaW5nLmpvaW4obGluZXMsICdcbicpCgpkZWYgZ2V0ZmlsZShvYmplY3QpOgogICAgIiIiV29yayBvdXQgd2hpY2ggc291cmNlIG9yIGNvbXBpbGVkIGZpbGUgYW4gb2JqZWN0IHdhcyBkZWZpbmVkIGluLiIiIgogICAgaWYgaXNtb2R1bGUob2JqZWN0KToKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fZmlsZV9fJyk6CiAgICAgICAgICAgIHJldHVybiBvYmplY3QuX19maWxlX18KICAgICAgICByYWlzZSBUeXBlRXJyb3IsICdhcmcgaXMgYSBidWlsdC1pbiBtb2R1bGUnCiAgICBpZiBpc2NsYXNzKG9iamVjdCk6CiAgICAgICAgb2JqZWN0ID0gc3lzLm1vZHVsZXMuZ2V0KG9iamVjdC5fX21vZHVsZV9fKQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19maWxlX18nKToKICAgICAgICAgICAgcmV0dXJuIG9iamVjdC5fX2ZpbGVfXwogICAgICAgIHJhaXNlIFR5cGVFcnJvciwgJ2FyZyBpcyBhIGJ1aWx0LWluIGNsYXNzJwogICAgaWYgaXNtZXRob2Qob2JqZWN0KToKICAgICAgICBvYmplY3QgPSBvYmplY3QuaW1fZnVuYwogICAgaWYgaXNmdW5jdGlvbihvYmplY3QpOgogICAgICAgIG9iamVjdCA9IG9iamVjdC5mdW5jX2NvZGUKICAgIGlmIGlzdHJhY2ViYWNrKG9iamVjdCk6CiAgICAgICAgb2JqZWN0ID0gb2JqZWN0LnRiX2ZyYW1lCiAgICBpZiBpc2ZyYW1lKG9iamVjdCk6CiAgICAgICAgb2JqZWN0ID0gb2JqZWN0LmZfY29kZQogICAgaWYgaXNjb2RlKG9iamVjdCk6CiAgICAgICAgcmV0dXJuIG9iamVjdC5jb19maWxlbmFtZQogICAgcmFpc2UgVHlwZUVycm9yLCAnYXJnIGlzIG5vdCBhIG1vZHVsZSwgY2xhc3MsIG1ldGhvZCwgJyBcCiAgICAgICAgICAgICAgICAgICAgICdmdW5jdGlvbiwgdHJhY2ViYWNrLCBmcmFtZSwgb3IgY29kZSBvYmplY3QnCgpkZWYgZ2V0bW9kdWxlaW5mbyhwYXRoKToKICAgICIiIkdldCB0aGUgbW9kdWxlIG5hbWUsIHN1ZmZpeCwgbW9kZSwgYW5kIG1vZHVsZSB0eXBlIGZvciBhIGdpdmVuIGZpbGUuIiIiCiAgICBmaWxlbmFtZSA9IG9zLnBhdGguYmFzZW5hbWUocGF0aCkKICAgIHN1ZmZpeGVzID0gbWFwKGxhbWJkYSAoc3VmZml4LCBtb2RlLCBtdHlwZSk6CiAgICAgICAgICAgICAgICAgICAoLWxlbihzdWZmaXgpLCBzdWZmaXgsIG1vZGUsIG10eXBlKSwgaW1wLmdldF9zdWZmaXhlcygpKQogICAgc3VmZml4ZXMuc29ydCgpICMgdHJ5IGxvbmdlc3Qgc3VmZml4ZXMgZmlyc3QsIGluIGNhc2UgdGhleSBvdmVybGFwCiAgICBmb3IgbmVnbGVuLCBzdWZmaXgsIG1vZGUsIG10eXBlIGluIHN1ZmZpeGVzOgogICAgICAgIGlmIGZpbGVuYW1lW25lZ2xlbjpdID09IHN1ZmZpeDoKICAgICAgICAgICAgcmV0dXJuIGZpbGVuYW1lWzpuZWdsZW5dLCBzdWZmaXgsIG1vZGUsIG10eXBlCgpkZWYgZ2V0bW9kdWxlbmFtZShwYXRoKToKICAgICIiIlJldHVybiB0aGUgbW9kdWxlIG5hbWUgZm9yIGEgZ2l2ZW4gZmlsZSwgb3IgTm9uZS4iIiIKICAgIGluZm8gPSBnZXRtb2R1bGVpbmZvKHBhdGgpCiAgICBpZiBpbmZvOiByZXR1cm4gaW5mb1swXQoKZGVmIGdldHNvdXJjZWZpbGUob2JqZWN0KToKICAgICIiIlJldHVybiB0aGUgUHl0aG9uIHNvdXJjZSBmaWxlIGFuIG9iamVjdCB3YXMgZGVmaW5lZCBpbiwgaWYgaXQgZXhpc3RzLiIiIgogICAgZmlsZW5hbWUgPSBnZXRmaWxlKG9iamVjdCkKICAgIGlmIHN0cmluZy5sb3dlcihmaWxlbmFtZVstNDpdKSBpbiBbJy5weWMnLCAnLnB5byddOgogICAgICAgIGZpbGVuYW1lID0gZmlsZW5hbWVbOi00XSArICcucHknCiAgICBmb3Igc3VmZml4LCBtb2RlLCBraW5kIGluIGltcC5nZXRfc3VmZml4ZXMoKToKICAgICAgICBpZiAnYicgaW4gbW9kZSBhbmQgc3RyaW5nLmxvd2VyKGZpbGVuYW1lWy1sZW4oc3VmZml4KTpdKSA9PSBzdWZmaXg6CiAgICAgICAgICAgICMgTG9va3MgbGlrZSBhIGJpbmFyeSBmaWxlLiAgV2Ugd2FudCB0byBvbmx5IHJldHVybiBhIHRleHQgZmlsZS4KICAgICAgICAgICAgcmV0dXJuIE5vbmUKICAgIGlmIG9zLnBhdGguZXhpc3RzKGZpbGVuYW1lKToKICAgICAgICByZXR1cm4gZmlsZW5hbWUKCmRlZiBnZXRhYnNmaWxlKG9iamVjdCk6CiAgICAiIiJSZXR1cm4gYW4gYWJzb2x1dGUgcGF0aCB0byB0aGUgc291cmNlIG9yIGNvbXBpbGVkIGZpbGUgZm9yIGFuIG9iamVjdC4KCiAgICBUaGUgaWRlYSBpcyBmb3IgZWFjaCBvYmplY3QgdG8gaGF2ZSBhIHVuaXF1ZSBvcmlnaW4sIHNvIHRoaXMgcm91dGluZQogICAgbm9ybWFsaXplcyB0aGUgcmVzdWx0IGFzIG11Y2ggYXMgcG9zc2libGUuIiIiCiAgICByZXR1cm4gb3MucGF0aC5ub3JtY2FzZSgKICAgICAgICBvcy5wYXRoLmFic3BhdGgoZ2V0c291cmNlZmlsZShvYmplY3QpIG9yIGdldGZpbGUob2JqZWN0KSkpCgptb2R1bGVzYnlmaWxlID0ge30KCmRlZiBnZXRtb2R1bGUob2JqZWN0KToKICAgICIiIlJldHVybiB0aGUgbW9kdWxlIGFuIG9iamVjdCB3YXMgZGVmaW5lZCBpbiwgb3IgTm9uZSBpZiBub3QgZm91bmQuIiIiCiAgICBpZiBpc21vZHVsZShvYmplY3QpOgogICAgICAgIHJldHVybiBvYmplY3QKICAgIGlmIGlzY2xhc3Mob2JqZWN0KToKICAgICAgICByZXR1cm4gc3lzLm1vZHVsZXMuZ2V0KG9iamVjdC5fX21vZHVsZV9fKQogICAgdHJ5OgogICAgICAgIGZpbGUgPSBnZXRhYnNmaWxlKG9iamVjdCkKICAgIGV4Y2VwdCBUeXBlRXJyb3I6CiAgICAgICAgcmV0dXJuIE5vbmUKICAgIGlmIG1vZHVsZXNieWZpbGUuaGFzX2tleShmaWxlKToKICAgICAgICByZXR1cm4gc3lzLm1vZHVsZXNbbW9kdWxlc2J5ZmlsZVtmaWxlXV0KICAgIGZvciBtb2R1bGUgaW4gc3lzLm1vZHVsZXMudmFsdWVzKCk6CiAgICAgICAgaWYgaGFzYXR0cihtb2R1bGUsICdfX2ZpbGVfXycpOgogICAgICAgICAgICBtb2R1bGVzYnlmaWxlW2dldGFic2ZpbGUobW9kdWxlKV0gPSBtb2R1bGUuX19uYW1lX18KICAgIGlmIG1vZHVsZXNieWZpbGUuaGFzX2tleShmaWxlKToKICAgICAgICByZXR1cm4gc3lzLm1vZHVsZXNbbW9kdWxlc2J5ZmlsZVtmaWxlXV0KICAgIG1haW4gPSBzeXMubW9kdWxlc1snX19tYWluX18nXQogICAgaWYgaGFzYXR0cihtYWluLCBvYmplY3QuX19uYW1lX18pOgogICAgICAgIG1haW5vYmplY3QgPSBnZXRhdHRyKG1haW4sIG9iamVjdC5fX25hbWVfXykKICAgICAgICBpZiBtYWlub2JqZWN0IGlzIG9iamVjdDoKICAgICAgICAgICAgcmV0dXJuIG1haW4KICAgIGJ1aWx0aW4gPSBzeXMubW9kdWxlc1snX19idWlsdGluX18nXQogICAgaWYgaGFzYXR0cihidWlsdGluLCBvYmplY3QuX19uYW1lX18pOgogICAgICAgIGJ1aWx0aW5vYmplY3QgPSBnZXRhdHRyKGJ1aWx0aW4sIG9iamVjdC5fX25hbWVfXykKICAgICAgICBpZiBidWlsdGlub2JqZWN0IGlzIG9iamVjdDoKICAgICAgICAgICAgcmV0dXJuIGJ1aWx0aW4KCmRlZiBmaW5kc291cmNlKG9iamVjdCk6CiAgICAiIiJSZXR1cm4gdGhlIGVudGlyZSBzb3VyY2UgZmlsZSBhbmQgc3RhcnRpbmcgbGluZSBudW1iZXIgZm9yIGFuIG9iamVjdC4KCiAgICBUaGUgYXJndW1lbnQgbWF5IGJlIGEgbW9kdWxlLCBjbGFzcywgbWV0aG9kLCBmdW5jdGlvbiwgdHJhY2ViYWNrLCBmcmFtZSwKICAgIG9yIGNvZGUgb2JqZWN0LiAgVGhlIHNvdXJjZSBjb2RlIGlzIHJldHVybmVkIGFzIGEgbGlzdCBvZiBhbGwgdGhlIGxpbmVzCiAgICBpbiB0aGUgZmlsZSBhbmQgdGhlIGxpbmUgbnVtYmVyIGluZGV4ZXMgYSBsaW5lIGluIHRoYXQgbGlzdC4gIEFuIElPRXJyb3IKICAgIGlzIHJhaXNlZCBpZiB0aGUgc291cmNlIGNvZGUgY2Fubm90IGJlIHJldHJpZXZlZC4iIiIKICAgIHRyeToKICAgICAgICBmaWxlID0gb3BlbihnZXRzb3VyY2VmaWxlKG9iamVjdCkpCiAgICBleGNlcHQgKFR5cGVFcnJvciwgSU9FcnJvcik6CiAgICAgICAgcmFpc2UgSU9FcnJvciwgJ2NvdWxkIG5vdCBnZXQgc291cmNlIGNvZGUnCiAgICBsaW5lcyA9IGZpbGUucmVhZGxpbmVzKCkKICAgIGZpbGUuY2xvc2UoKQoKICAgIGlmIGlzbW9kdWxlKG9iamVjdCk6CiAgICAgICAgcmV0dXJuIGxpbmVzLCAwCgogICAgaWYgaXNjbGFzcyhvYmplY3QpOgogICAgICAgIG5hbWUgPSBvYmplY3QuX19uYW1lX18KICAgICAgICBwYXQgPSByZS5jb21waWxlKHInXlxzKmNsYXNzXHMqJyArIG5hbWUgKyByJ1xiJykKICAgICAgICBmb3IgaSBpbiByYW5nZShsZW4obGluZXMpKToKICAgICAgICAgICAgaWYgcGF0Lm1hdGNoKGxpbmVzW2ldKTogcmV0dXJuIGxpbmVzLCBpCiAgICAgICAgZWxzZTogcmFpc2UgSU9FcnJvciwgJ2NvdWxkIG5vdCBmaW5kIGNsYXNzIGRlZmluaXRpb24nCgogICAgaWYgaXNtZXRob2Qob2JqZWN0KToKICAgICAgICBvYmplY3QgPSBvYmplY3QuaW1fZnVuYwogICAgaWYgaXNmdW5jdGlvbihvYmplY3QpOgogICAgICAgIG9iamVjdCA9IG9iamVjdC5mdW5jX2NvZGUKICAgIGlmIGlzdHJhY2ViYWNrKG9iamVjdCk6CiAgICAgICAgb2JqZWN0ID0gb2JqZWN0LnRiX2ZyYW1lCiAgICBpZiBpc2ZyYW1lKG9iamVjdCk6CiAgICAgICAgb2JqZWN0ID0gb2JqZWN0LmZfY29kZQogICAgaWYgaXNjb2RlKG9iamVjdCk6CiAgICAgICAgaWYgbm90IGhhc2F0dHIob2JqZWN0LCAnY29fZmlyc3RsaW5lbm8nKToKICAgICAgICAgICAgcmFpc2UgSU9FcnJvciwgJ2NvdWxkIG5vdCBmaW5kIGZ1bmN0aW9uIGRlZmluaXRpb24nCiAgICAgICAgbG51bSA9IG9iamVjdC5jb19maXJzdGxpbmVubyAtIDEKICAgICAgICBwYXQgPSByZS5jb21waWxlKHInXlxzKmRlZlxzJykKICAgICAgICB3aGlsZSBsbnVtID4gMDoKICAgICAgICAgICAgaWYgcGF0Lm1hdGNoKGxpbmVzW2xudW1dKTogYnJlYWsKICAgICAgICAgICAgbG51bSA9IGxudW0gLSAxCiAgICAgICAgcmV0dXJuIGxpbmVzLCBsbnVtCgpkZWYgZ2V0Y29tbWVudHMob2JqZWN0KToKICAgICIiIkdldCBsaW5lcyBvZiBjb21tZW50cyBpbW1lZGlhdGVseSBwcmVjZWRpbmcgYW4gb2JqZWN0J3Mgc291cmNlIGNvZGUuIiIiCiAgICB0cnk6IGxpbmVzLCBsbnVtID0gZmluZHNvdXJjZShvYmplY3QpCiAgICBleGNlcHQgSU9FcnJvcjogcmV0dXJuIE5vbmUKCiAgICBpZiBpc21vZHVsZShvYmplY3QpOgogICAgICAgICMgTG9vayBmb3IgYSBjb21tZW50IGJsb2NrIGF0IHRoZSB0b3Agb2YgdGhlIGZpbGUuCiAgICAgICAgc3RhcnQgPSAwCiAgICAgICAgaWYgbGluZXMgYW5kIGxpbmVzWzBdWzoyXSA9PSAnIyEnOiBzdGFydCA9IDEKICAgICAgICB3aGlsZSBzdGFydCA8IGxlbihsaW5lcykgYW5kIHN0cmluZy5zdHJpcChsaW5lc1tzdGFydF0pIGluIFsnJywgJyMnXToKICAgICAgICAgICAgc3RhcnQgPSBzdGFydCArIDEKICAgICAgICBpZiBzdGFydCA8IGxlbihsaW5lcykgYW5kIGxpbmVzW3N0YXJ0XVs6MV0gPT0gJyMnOgogICAgICAgICAgICBjb21tZW50cyA9IFtdCiAgICAgICAgICAgIGVuZCA9IHN0YXJ0CiAgICAgICAgICAgIHdoaWxlIGVuZCA8IGxlbihsaW5lcykgYW5kIGxpbmVzW2VuZF1bOjFdID09ICcjJzoKICAgICAgICAgICAgICAgIGNvbW1lbnRzLmFwcGVuZChzdHJpbmcuZXhwYW5kdGFicyhsaW5lc1tlbmRdKSkKICAgICAgICAgICAgICAgIGVuZCA9IGVuZCArIDEKICAgICAgICAgICAgcmV0dXJuIHN0cmluZy5qb2luKGNvbW1lbnRzLCAnJykKCiAgICAjIExvb2sgZm9yIGEgcHJlY2VkaW5nIGJsb2NrIG9mIGNvbW1lbnRzIGF0IHRoZSBzYW1lIGluZGVudGF0aW9uLgogICAgZWxpZiBsbnVtID4gMDoKICAgICAgICBpbmRlbnQgPSBpbmRlbnRzaXplKGxpbmVzW2xudW1dKQogICAgICAgIGVuZCA9IGxudW0gLSAxCiAgICAgICAgaWYgZW5kID49IDAgYW5kIHN0cmluZy5sc3RyaXAobGluZXNbZW5kXSlbOjFdID09ICcjJyBhbmQgXAogICAgICAgICAgICBpbmRlbnRzaXplKGxpbmVzW2VuZF0pID09IGluZGVudDoKICAgICAgICAgICAgY29tbWVudHMgPSBbc3RyaW5nLmxzdHJpcChzdHJpbmcuZXhwYW5kdGFicyhsaW5lc1tlbmRdKSldCiAgICAgICAgICAgIGlmIGVuZCA+IDA6CiAgICAgICAgICAgICAgICBlbmQgPSBlbmQgLSAxCiAgICAgICAgICAgICAgICBjb21tZW50ID0gc3RyaW5nLmxzdHJpcChzdHJpbmcuZXhwYW5kdGFicyhsaW5lc1tlbmRdKSkKICAgICAgICAgICAgICAgIHdoaWxlIGNvbW1lbnRbOjFdID09ICcjJyBhbmQgaW5kZW50c2l6ZShsaW5lc1tlbmRdKSA9PSBpbmRlbnQ6CiAgICAgICAgICAgICAgICAgICAgY29tbWVudHNbOjBdID0gW2NvbW1lbnRdCiAgICAgICAgICAgICAgICAgICAgZW5kID0gZW5kIC0gMQogICAgICAgICAgICAgICAgICAgIGlmIGVuZCA8IDA6IGJyZWFrCiAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IHN0cmluZy5sc3RyaXAoc3RyaW5nLmV4cGFuZHRhYnMobGluZXNbZW5kXSkpCiAgICAgICAgICAgIHdoaWxlIGNvbW1lbnRzIGFuZCBzdHJpbmcuc3RyaXAoY29tbWVudHNbMF0pID09ICcjJzoKICAgICAgICAgICAgICAgIGNvbW1lbnRzWzoxXSA9IFtdCiAgICAgICAgICAgIHdoaWxlIGNvbW1lbnRzIGFuZCBzdHJpbmcuc3RyaXAoY29tbWVudHNbLTFdKSA9PSAnIyc6CiAgICAgICAgICAgICAgICBjb21tZW50c1stMTpdID0gW10KICAgICAgICAgICAgcmV0dXJuIHN0cmluZy5qb2luKGNvbW1lbnRzLCAnJykKCmNsYXNzIExpc3RSZWFkZXI6CiAgICAiIiJQcm92aWRlIGEgcmVhZGxpbmUoKSBtZXRob2QgdG8gcmV0dXJuIGxpbmVzIGZyb20gYSBsaXN0IG9mIHN0cmluZ3MuIiIiCiAgICBkZWYgX19pbml0X18oc2VsZiwgbGluZXMpOgogICAgICAgIHNlbGYubGluZXMgPSBsaW5lcwogICAgICAgIHNlbGYuaW5kZXggPSAwCgogICAgZGVmIHJlYWRsaW5lKHNlbGYpOgogICAgICAgIGkgPSBzZWxmLmluZGV4CiAgICAgICAgaWYgaSA8IGxlbihzZWxmLmxpbmVzKToKICAgICAgICAgICAgc2VsZi5pbmRleCA9IGkgKyAxCiAgICAgICAgICAgIHJldHVybiBzZWxmLmxpbmVzW2ldCiAgICAgICAgZWxzZTogcmV0dXJuICcnCgpjbGFzcyBFbmRPZkJsb2NrKEV4Y2VwdGlvbik6IHBhc3MKCmNsYXNzIEJsb2NrRmluZGVyOgogICAgIiIiUHJvdmlkZSBhIHRva2VuZWF0ZXIoKSBtZXRob2QgdG8gZGV0ZWN0IHRoZSBlbmQgb2YgYSBjb2RlIGJsb2NrLiIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgIHNlbGYuaW5kZW50ID0gMAogICAgICAgIHNlbGYuc3RhcnRlZCA9IDAKICAgICAgICBzZWxmLmxhc3QgPSAwCgogICAgZGVmIHRva2VuZWF0ZXIoc2VsZiwgdHlwZSwgdG9rZW4sIChzcm93LCBzY29sKSwgKGVyb3csIGVjb2wpLCBsaW5lKToKICAgICAgICBpZiBub3Qgc2VsZi5zdGFydGVkOgogICAgICAgICAgICBpZiB0eXBlID09IHRva2VuaXplLk5BTUU6IHNlbGYuc3RhcnRlZCA9IDEKICAgICAgICBlbGlmIHR5cGUgPT0gdG9rZW5pemUuTkVXTElORToKICAgICAgICAgICAgc2VsZi5sYXN0ID0gc3JvdwogICAgICAgIGVsaWYgdHlwZSA9PSB0b2tlbml6ZS5JTkRFTlQ6CiAgICAgICAgICAgIHNlbGYuaW5kZW50ID0gc2VsZi5pbmRlbnQgKyAxCiAgICAgICAgZWxpZiB0eXBlID09IHRva2VuaXplLkRFREVOVDoKICAgICAgICAgICAgc2VsZi5pbmRlbnQgPSBzZWxmLmluZGVudCAtIDEKICAgICAgICAgICAgaWYgc2VsZi5pbmRlbnQgPT0gMDogcmFpc2UgRW5kT2ZCbG9jaywgc2VsZi5sYXN0CgpkZWYgZ2V0YmxvY2sobGluZXMpOgogICAgIiIiRXh0cmFjdCB0aGUgYmxvY2sgb2YgY29kZSBhdCB0aGUgdG9wIG9mIHRoZSBnaXZlbiBsaXN0IG9mIGxpbmVzLiIiIgogICAgdHJ5OgogICAgICAgIHRva2VuaXplLnRva2VuaXplKExpc3RSZWFkZXIobGluZXMpLnJlYWRsaW5lLCBCbG9ja0ZpbmRlcigpLnRva2VuZWF0ZXIpCiAgICBleGNlcHQgRW5kT2ZCbG9jaywgZW9iOgogICAgICAgIHJldHVybiBsaW5lc1s6ZW9iLmFyZ3NbMF1dCgpkZWYgZ2V0c291cmNlbGluZXMob2JqZWN0KToKICAgICIiIlJldHVybiBhIGxpc3Qgb2Ygc291cmNlIGxpbmVzIGFuZCBzdGFydGluZyBsaW5lIG51bWJlciBmb3IgYW4gb2JqZWN0LgoKICAgIFRoZSBhcmd1bWVudCBtYXkgYmUgYSBtb2R1bGUsIGNsYXNzLCBtZXRob2QsIGZ1bmN0aW9uLCB0cmFjZWJhY2ssIGZyYW1lLAogICAgb3IgY29kZSBvYmplY3QuICBUaGUgc291cmNlIGNvZGUgaXMgcmV0dXJuZWQgYXMgYSBsaXN0IG9mIHRoZSBsaW5lcwogICAgY29ycmVzcG9uZGluZyB0byB0aGUgb2JqZWN0IGFuZCB0aGUgbGluZSBudW1iZXIgaW5kaWNhdGVzIHdoZXJlIGluIHRoZQogICAgb3JpZ2luYWwgc291cmNlIGZpbGUgdGhlIGZpcnN0IGxpbmUgb2YgY29kZSB3YXMgZm91bmQuICBBbiBJT0Vycm9yIGlzCiAgICByYWlzZWQgaWYgdGhlIHNvdXJjZSBjb2RlIGNhbm5vdCBiZSByZXRyaWV2ZWQuIiIiCiAgICBsaW5lcywgbG51bSA9IGZpbmRzb3VyY2Uob2JqZWN0KQoKICAgIGlmIGlzbW9kdWxlKG9iamVjdCk6IHJldHVybiBsaW5lcywgMAogICAgZWxzZTogcmV0dXJuIGdldGJsb2NrKGxpbmVzW2xudW06XSksIGxudW0gKyAxCgpkZWYgZ2V0c291cmNlKG9iamVjdCk6CiAgICAiIiJSZXR1cm4gdGhlIHRleHQgb2YgdGhlIHNvdXJjZSBjb2RlIGZvciBhbiBvYmplY3QuCgogICAgVGhlIGFyZ3VtZW50IG1heSBiZSBhIG1vZHVsZSwgY2xhc3MsIG1ldGhvZCwgZnVuY3Rpb24sIHRyYWNlYmFjaywgZnJhbWUsCiAgICBvciBjb2RlIG9iamVjdC4gIFRoZSBzb3VyY2UgY29kZSBpcyByZXR1cm5lZCBhcyBhIHNpbmdsZSBzdHJpbmcuICBBbgogICAgSU9FcnJvciBpcyByYWlzZWQgaWYgdGhlIHNvdXJjZSBjb2RlIGNhbm5vdCBiZSByZXRyaWV2ZWQuIiIiCiAgICBsaW5lcywgbG51bSA9IGdldHNvdXJjZWxpbmVzKG9iamVjdCkKICAgIHJldHVybiBzdHJpbmcuam9pbihsaW5lcywgJycpCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBjbGFzcyB0cmVlIGV4dHJhY3Rpb24KZGVmIHdhbGt0cmVlKGNsYXNzZXMsIGNoaWxkcmVuLCBwYXJlbnQpOgogICAgIiIiUmVjdXJzaXZlIGhlbHBlciBmdW5jdGlvbiBmb3IgZ2V0Y2xhc3N0cmVlKCkuIiIiCiAgICByZXN1bHRzID0gW10KICAgIGNsYXNzZXMuc29ydChsYW1iZGEgYSwgYjogY21wKGEuX19uYW1lX18sIGIuX19uYW1lX18pKQogICAgZm9yIGMgaW4gY2xhc3NlczoKICAgICAgICByZXN1bHRzLmFwcGVuZCgoYywgYy5fX2Jhc2VzX18pKQogICAgICAgIGlmIGNoaWxkcmVuLmhhc19rZXkoYyk6CiAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKHdhbGt0cmVlKGNoaWxkcmVuW2NdLCBjaGlsZHJlbiwgYykpCiAgICByZXR1cm4gcmVzdWx0cwoKZGVmIGdldGNsYXNzdHJlZShjbGFzc2VzLCB1bmlxdWU9MCk6CiAgICAiIiJBcnJhbmdlIHRoZSBnaXZlbiBsaXN0IG9mIGNsYXNzZXMgaW50byBhIGhpZXJhcmNoeSBvZiBuZXN0ZWQgbGlzdHMuCgogICAgV2hlcmUgYSBuZXN0ZWQgbGlzdCBhcHBlYXJzLCBpdCBjb250YWlucyBjbGFzc2VzIGRlcml2ZWQgZnJvbSB0aGUgY2xhc3MKICAgIHdob3NlIGVudHJ5IGltbWVkaWF0ZWx5IHByZWNlZGVzIHRoZSBsaXN0LiAgRWFjaCBlbnRyeSBpcyBhIDItdHVwbGUKICAgIGNvbnRhaW5pbmcgYSBjbGFzcyBhbmQgYSB0dXBsZSBvZiBpdHMgYmFzZSBjbGFzc2VzLiAgSWYgdGhlICd1bmlxdWUnCiAgICBhcmd1bWVudCBpcyB0cnVlLCBleGFjdGx5IG9uZSBlbnRyeSBhcHBlYXJzIGluIHRoZSByZXR1cm5lZCBzdHJ1Y3R1cmUKICAgIGZvciBlYWNoIGNsYXNzIGluIHRoZSBnaXZlbiBsaXN0LiAgT3RoZXJ3aXNlLCBjbGFzc2VzIHVzaW5nIG11bHRpcGxlCiAgICBpbmhlcml0YW5jZSBhbmQgdGhlaXIgZGVzY2VuZGFudHMgd2lsbCBhcHBlYXIgbXVsdGlwbGUgdGltZXMuIiIiCiAgICBjaGlsZHJlbiA9IHt9CiAgICByb290cyA9IFtdCiAgICBmb3IgYyBpbiBjbGFzc2VzOgogICAgICAgIGlmIGMuX19iYXNlc19fOgogICAgICAgICAgICBmb3IgcGFyZW50IGluIGMuX19iYXNlc19fOgogICAgICAgICAgICAgICAgaWYgbm90IGNoaWxkcmVuLmhhc19rZXkocGFyZW50KToKICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbltwYXJlbnRdID0gW10KICAgICAgICAgICAgICAgIGNoaWxkcmVuW3BhcmVudF0uYXBwZW5kKGMpCiAgICAgICAgICAgICAgICBpZiB1bmlxdWUgYW5kIHBhcmVudCBpbiBjbGFzc2VzOiBicmVhawogICAgICAgIGVsaWYgYyBub3QgaW4gcm9vdHM6CiAgICAgICAgICAgIHJvb3RzLmFwcGVuZChjKQogICAgZm9yIHBhcmVudCBpbiBjaGlsZHJlbi5rZXlzKCk6CiAgICAgICAgaWYgcGFyZW50IG5vdCBpbiBjbGFzc2VzOgogICAgICAgICAgICByb290cy5hcHBlbmQocGFyZW50KQogICAgcmV0dXJuIHdhbGt0cmVlKHJvb3RzLCBjaGlsZHJlbiwgTm9uZSkKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGFyZ3VtZW50IGxpc3QgZXh0cmFjdGlvbgojIFRoZXNlIGNvbnN0YW50cyBhcmUgZnJvbSBQeXRob24ncyBjb21waWxlLmguCkNPX09QVElNSVpFRCwgQ09fTkVXTE9DQUxTLCBDT19WQVJBUkdTLCBDT19WQVJLRVlXT1JEUyA9IDEsIDIsIDQsIDgKCmRlZiBnZXRhcmdzKGNvKToKICAgICIiIkdldCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgYXJndW1lbnRzIGFjY2VwdGVkIGJ5IGEgY29kZSBvYmplY3QuCgogICAgVGhyZWUgdGhpbmdzIGFyZSByZXR1cm5lZDogKGFyZ3MsIHZhcmFyZ3MsIHZhcmt3KSwgd2hlcmUgJ2FyZ3MnIGlzCiAgICBhIGxpc3Qgb2YgYXJndW1lbnQgbmFtZXMgKHBvc3NpYmx5IGNvbnRhaW5pbmcgbmVzdGVkIGxpc3RzKSwgYW5kCiAgICAndmFyYXJncycgYW5kICd2YXJrdycgYXJlIHRoZSBuYW1lcyBvZiB0aGUgKiBhbmQgKiogYXJndW1lbnRzIG9yIE5vbmUuIiIiCiAgICBpZiBub3QgaXNjb2RlKGNvKTogcmFpc2UgVHlwZUVycm9yLCAnYXJnIGlzIG5vdCBhIGNvZGUgb2JqZWN0JwoKICAgIGNvZGUgPSBjby5jb19jb2RlCiAgICBuYXJncyA9IGNvLmNvX2FyZ2NvdW50CiAgICBuYW1lcyA9IGNvLmNvX3Zhcm5hbWVzCiAgICBhcmdzID0gbGlzdChuYW1lc1s6bmFyZ3NdKQogICAgc3RlcCA9IDAKCiAgICAjIFRoZSBmb2xsb3dpbmcgYWNyb2JhdGljcyBhcmUgZm9yIGFub255bW91cyAodHVwbGUpIGFyZ3VtZW50cy4KICAgIGZvciBpIGluIHJhbmdlKG5hcmdzKToKICAgICAgICBpZiBhcmdzW2ldWzoxXSBpbiBbJycsICcuJ106CiAgICAgICAgICAgIHN0YWNrLCByZW1haW4sIGNvdW50ID0gW10sIFtdLCBbXQogICAgICAgICAgICB3aGlsZSBzdGVwIDwgbGVuKGNvZGUpOgogICAgICAgICAgICAgICAgb3AgPSBvcmQoY29kZVtzdGVwXSkKICAgICAgICAgICAgICAgIHN0ZXAgPSBzdGVwICsgMQogICAgICAgICAgICAgICAgaWYgb3AgPj0gZGlzLkhBVkVfQVJHVU1FTlQ6CiAgICAgICAgICAgICAgICAgICAgb3BuYW1lID0gZGlzLm9wbmFtZVtvcF0KICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IG9yZChjb2RlW3N0ZXBdKSArIG9yZChjb2RlW3N0ZXArMV0pKjI1NgogICAgICAgICAgICAgICAgICAgIHN0ZXAgPSBzdGVwICsgMgogICAgICAgICAgICAgICAgICAgIGlmIG9wbmFtZSBpbiBbJ1VOUEFDS19UVVBMRScsICdVTlBBQ0tfU0VRVUVOQ0UnXToKICAgICAgICAgICAgICAgICAgICAgICAgcmVtYWluLmFwcGVuZCh2YWx1ZSkKICAgICAgICAgICAgICAgICAgICAgICAgY291bnQuYXBwZW5kKHZhbHVlKQogICAgICAgICAgICAgICAgICAgIGVsaWYgb3BuYW1lID09ICdTVE9SRV9GQVNUJzoKICAgICAgICAgICAgICAgICAgICAgICAgc3RhY2suYXBwZW5kKG5hbWVzW3ZhbHVlXSkKICAgICAgICAgICAgICAgICAgICAgICAgcmVtYWluWy0xXSA9IHJlbWFpblstMV0gLSAxCiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIHJlbWFpblstMV0gPT0gMDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbWFpbi5wb3AoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IGNvdW50LnBvcCgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFja1stc2l6ZTpdID0gW3N0YWNrWy1zaXplOl1dCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBub3QgcmVtYWluOiBicmVhawogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtYWluWy0xXSA9IHJlbWFpblstMV0gLSAxCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIG5vdCByZW1haW46IGJyZWFrCiAgICAgICAgICAgIGFyZ3NbaV0gPSBzdGFja1swXQoKICAgIHZhcmFyZ3MgPSBOb25lCiAgICBpZiBjby5jb19mbGFncyAmIENPX1ZBUkFSR1M6CiAgICAgICAgdmFyYXJncyA9IGNvLmNvX3Zhcm5hbWVzW25hcmdzXQogICAgICAgIG5hcmdzID0gbmFyZ3MgKyAxCiAgICB2YXJrdyA9IE5vbmUKICAgIGlmIGNvLmNvX2ZsYWdzICYgQ09fVkFSS0VZV09SRFM6CiAgICAgICAgdmFya3cgPSBjby5jb192YXJuYW1lc1tuYXJnc10KICAgIHJldHVybiBhcmdzLCB2YXJhcmdzLCB2YXJrdwoKZGVmIGdldGFyZ3NwZWMoZnVuYyk6CiAgICAiIiJHZXQgdGhlIG5hbWVzIGFuZCBkZWZhdWx0IHZhbHVlcyBvZiBhIGZ1bmN0aW9uJ3MgYXJndW1lbnRzLgoKICAgIEEgdHVwbGUgb2YgZm91ciB0aGluZ3MgaXMgcmV0dXJuZWQ6IChhcmdzLCB2YXJhcmdzLCB2YXJrdywgZGVmYXVsdHMpLgogICAgJ2FyZ3MnIGlzIGEgbGlzdCBvZiB0aGUgYXJndW1lbnQgbmFtZXMgKGl0IG1heSBjb250YWluIG5lc3RlZCBsaXN0cykuCiAgICAndmFyYXJncycgYW5kICd2YXJrdycgYXJlIHRoZSBuYW1lcyBvZiB0aGUgKiBhbmQgKiogYXJndW1lbnRzIG9yIE5vbmUuCiAgICAnZGVmYXVsdHMnIGlzIGFuIG4tdHVwbGUgb2YgdGhlIGRlZmF1bHQgdmFsdWVzIG9mIHRoZSBsYXN0IG4gYXJndW1lbnRzLiIiIgogICAgaWYgbm90IGlzZnVuY3Rpb24oZnVuYyk6IHJhaXNlIFR5cGVFcnJvciwgJ2FyZyBpcyBub3QgYSBQeXRob24gZnVuY3Rpb24nCiAgICBhcmdzLCB2YXJhcmdzLCB2YXJrdyA9IGdldGFyZ3MoZnVuYy5mdW5jX2NvZGUpCiAgICByZXR1cm4gYXJncywgdmFyYXJncywgdmFya3csIGZ1bmMuZnVuY19kZWZhdWx0cwoKZGVmIGdldGFyZ3ZhbHVlcyhmcmFtZSk6CiAgICAiIiJHZXQgaW5mb3JtYXRpb24gYWJvdXQgYXJndW1lbnRzIHBhc3NlZCBpbnRvIGEgcGFydGljdWxhciBmcmFtZS4KCiAgICBBIHR1cGxlIG9mIGZvdXIgdGhpbmdzIGlzIHJldHVybmVkOiAoYXJncywgdmFyYXJncywgdmFya3csIGxvY2FscykuCiAgICAnYXJncycgaXMgYSBsaXN0IG9mIHRoZSBhcmd1bWVudCBuYW1lcyAoaXQgbWF5IGNvbnRhaW4gbmVzdGVkIGxpc3RzKS4KICAgICd2YXJhcmdzJyBhbmQgJ3Zhcmt3JyBhcmUgdGhlIG5hbWVzIG9mIHRoZSAqIGFuZCAqKiBhcmd1bWVudHMgb3IgTm9uZS4KICAgICdsb2NhbHMnIGlzIHRoZSBsb2NhbHMgZGljdGlvbmFyeSBvZiB0aGUgZ2l2ZW4gZnJhbWUuIiIiCiAgICBhcmdzLCB2YXJhcmdzLCB2YXJrdyA9IGdldGFyZ3MoZnJhbWUuZl9jb2RlKQogICAgcmV0dXJuIGFyZ3MsIHZhcmFyZ3MsIHZhcmt3LCBmcmFtZS5mX2xvY2FscwoKZGVmIGpvaW5zZXEoc2VxKToKICAgIGlmIGxlbihzZXEpID09IDE6CiAgICAgICAgcmV0dXJuICcoJyArIHNlcVswXSArICcsKScKICAgIGVsc2U6CiAgICAgICAgcmV0dXJuICcoJyArIHN0cmluZy5qb2luKHNlcSwgJywgJykgKyAnKScKCmRlZiBzdHJzZXEob2JqZWN0LCBjb252ZXJ0LCBqb2luPWpvaW5zZXEpOgogICAgIiIiUmVjdXJzaXZlbHkgd2FsayBhIHNlcXVlbmNlLCBzdHJpbmdpZnlpbmcgZWFjaCBlbGVtZW50LiIiIgogICAgaWYgdHlwZShvYmplY3QpIGluIFt0eXBlcy5MaXN0VHlwZSwgdHlwZXMuVHVwbGVUeXBlXToKICAgICAgICByZXR1cm4gam9pbihtYXAobGFtYmRhIG8sIGM9Y29udmVydCwgaj1qb2luOiBzdHJzZXEobywgYywgaiksIG9iamVjdCkpCiAgICBlbHNlOgogICAgICAgIHJldHVybiBjb252ZXJ0KG9iamVjdCkKCmRlZiBmb3JtYXRhcmdzcGVjKGFyZ3MsIHZhcmFyZ3M9Tm9uZSwgdmFya3c9Tm9uZSwgZGVmYXVsdHM9Tm9uZSwKICAgICAgICAgICAgICAgICAgZm9ybWF0YXJnPXN0ciwKICAgICAgICAgICAgICAgICAgZm9ybWF0dmFyYXJncz1sYW1iZGEgbmFtZTogJyonICsgbmFtZSwKICAgICAgICAgICAgICAgICAgZm9ybWF0dmFya3c9bGFtYmRhIG5hbWU6ICcqKicgKyBuYW1lLAogICAgICAgICAgICAgICAgICBmb3JtYXR2YWx1ZT1sYW1iZGEgdmFsdWU6ICc9JyArIHJlcHIodmFsdWUpLAogICAgICAgICAgICAgICAgICBqb2luPWpvaW5zZXEpOgogICAgIiIiRm9ybWF0IGFuIGFyZ3VtZW50IHNwZWMgZnJvbSB0aGUgNCB2YWx1ZXMgcmV0dXJuZWQgYnkgZ2V0YXJnc3BlYy4KCiAgICBUaGUgZmlyc3QgZm91ciBhcmd1bWVudHMgYXJlIChhcmdzLCB2YXJhcmdzLCB2YXJrdywgZGVmYXVsdHMpLiAgVGhlCiAgICBvdGhlciBmb3VyIGFyZ3VtZW50cyBhcmUgdGhlIGNvcnJlc3BvbmRpbmcgb3B0aW9uYWwgZm9ybWF0dGluZyBmdW5jdGlvbnMKICAgIHRoYXQgYXJlIGNhbGxlZCB0byB0dXJuIG5hbWVzIGFuZCB2YWx1ZXMgaW50byBzdHJpbmdzLiAgVGhlIG5pbnRoCiAgICBhcmd1bWVudCBpcyBhbiBvcHRpb25hbCBmdW5jdGlvbiB0byBmb3JtYXQgdGhlIHNlcXVlbmNlIG9mIGFyZ3VtZW50cy4iIiIKICAgIHNwZWNzID0gW10KICAgIGlmIGRlZmF1bHRzOgogICAgICAgIGZpcnN0ZGVmYXVsdCA9IGxlbihhcmdzKSAtIGxlbihkZWZhdWx0cykKICAgIGZvciBpIGluIHJhbmdlKGxlbihhcmdzKSk6CiAgICAgICAgc3BlYyA9IHN0cnNlcShhcmdzW2ldLCBmb3JtYXRhcmcsIGpvaW4pCiAgICAgICAgaWYgZGVmYXVsdHMgYW5kIGkgPj0gZmlyc3RkZWZhdWx0OgogICAgICAgICAgICBzcGVjID0gc3BlYyArIGZvcm1hdHZhbHVlKGRlZmF1bHRzW2kgLSBmaXJzdGRlZmF1bHRdKQogICAgICAgIHNwZWNzLmFwcGVuZChzcGVjKQogICAgaWYgdmFyYXJnczoKICAgICAgICBzcGVjcy5hcHBlbmQoZm9ybWF0dmFyYXJncyh2YXJhcmdzKSkKICAgIGlmIHZhcmt3OgogICAgICAgIHNwZWNzLmFwcGVuZChmb3JtYXR2YXJrdyh2YXJrdykpCiAgICByZXR1cm4gJygnICsgc3RyaW5nLmpvaW4oc3BlY3MsICcsICcpICsgJyknCgpkZWYgZm9ybWF0YXJndmFsdWVzKGFyZ3MsIHZhcmFyZ3MsIHZhcmt3LCBsb2NhbHMsCiAgICAgICAgICAgICAgICAgICAgZm9ybWF0YXJnPXN0ciwKICAgICAgICAgICAgICAgICAgICBmb3JtYXR2YXJhcmdzPWxhbWJkYSBuYW1lOiAnKicgKyBuYW1lLAogICAgICAgICAgICAgICAgICAgIGZvcm1hdHZhcmt3PWxhbWJkYSBuYW1lOiAnKionICsgbmFtZSwKICAgICAgICAgICAgICAgICAgICBmb3JtYXR2YWx1ZT1sYW1iZGEgdmFsdWU6ICc9JyArIHJlcHIodmFsdWUpLAogICAgICAgICAgICAgICAgICAgIGpvaW49am9pbnNlcSk6CiAgICAiIiJGb3JtYXQgYW4gYXJndW1lbnQgc3BlYyBmcm9tIHRoZSA0IHZhbHVlcyByZXR1cm5lZCBieSBnZXRhcmd2YWx1ZXMuCgogICAgVGhlIGZpcnN0IGZvdXIgYXJndW1lbnRzIGFyZSAoYXJncywgdmFyYXJncywgdmFya3csIGxvY2FscykuICBUaGUKICAgIG5leHQgZm91ciBhcmd1bWVudHMgYXJlIHRoZSBjb3JyZXNwb25kaW5nIG9wdGlvbmFsIGZvcm1hdHRpbmcgZnVuY3Rpb25zCiAgICB0aGF0IGFyZSBjYWxsZWQgdG8gdHVybiBuYW1lcyBhbmQgdmFsdWVzIGludG8gc3RyaW5ncy4gIFRoZSBuaW50aAogICAgYXJndW1lbnQgaXMgYW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gZm9ybWF0IHRoZSBzZXF1ZW5jZSBvZiBhcmd1bWVudHMuIiIiCiAgICBkZWYgY29udmVydChuYW1lLCBsb2NhbHM9bG9jYWxzLAogICAgICAgICAgICAgICAgZm9ybWF0YXJnPWZvcm1hdGFyZywgZm9ybWF0dmFsdWU9Zm9ybWF0dmFsdWUpOgogICAgICAgIHJldHVybiBmb3JtYXRhcmcobmFtZSkgKyBmb3JtYXR2YWx1ZShsb2NhbHNbbmFtZV0pCiAgICBzcGVjcyA9IFtdCiAgICBmb3IgaSBpbiByYW5nZShsZW4oYXJncykpOgogICAgICAgIHNwZWNzLmFwcGVuZChzdHJzZXEoYXJnc1tpXSwgY29udmVydCwgam9pbikpCiAgICBpZiB2YXJhcmdzOgogICAgICAgIHNwZWNzLmFwcGVuZChmb3JtYXR2YXJhcmdzKHZhcmFyZ3MpICsgZm9ybWF0dmFsdWUobG9jYWxzW3ZhcmFyZ3NdKSkKICAgIGlmIHZhcmt3OgogICAgICAgIHNwZWNzLmFwcGVuZChmb3JtYXR2YXJrdyh2YXJrdykgKyBmb3JtYXR2YWx1ZShsb2NhbHNbdmFya3ddKSkKICAgIHJldHVybiAnKCcgKyBzdHJpbmcuam9pbihzcGVjcywgJywgJykgKyAnKScKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gc3RhY2sgZnJhbWUgZXh0cmFjdGlvbgpkZWYgZ2V0ZnJhbWVpbmZvKGZyYW1lLCBjb250ZXh0PTEpOgogICAgIiIiR2V0IGluZm9ybWF0aW9uIGFib3V0IGEgZnJhbWUgb3IgdHJhY2ViYWNrIG9iamVjdC4KCiAgICBBIHR1cGxlIG9mIGZpdmUgdGhpbmdzIGlzIHJldHVybmVkOiB0aGUgZmlsZW5hbWUsIHRoZSBsaW5lIG51bWJlciBvZgogICAgdGhlIGN1cnJlbnQgbGluZSwgdGhlIGZ1bmN0aW9uIG5hbWUsIGEgbGlzdCBvZiBsaW5lcyBvZiBjb250ZXh0IGZyb20KICAgIHRoZSBzb3VyY2UgY29kZSwgYW5kIHRoZSBpbmRleCBvZiB0aGUgY3VycmVudCBsaW5lIHdpdGhpbiB0aGF0IGxpc3QuCiAgICBUaGUgb3B0aW9uYWwgc2Vjb25kIGFyZ3VtZW50IHNwZWNpZmllcyB0aGUgbnVtYmVyIG9mIGxpbmVzIG9mIGNvbnRleHQKICAgIHRvIHJldHVybiwgd2hpY2ggYXJlIGNlbnRlcmVkIGFyb3VuZCB0aGUgY3VycmVudCBsaW5lLiIiIgogICAgaWYgaXN0cmFjZWJhY2soZnJhbWUpOgogICAgICAgIGZyYW1lID0gZnJhbWUudGJfZnJhbWUKICAgIGlmIG5vdCBpc2ZyYW1lKGZyYW1lKToKICAgICAgICByYWlzZSBUeXBlRXJyb3IsICdhcmcgaXMgbm90IGEgZnJhbWUgb3IgdHJhY2ViYWNrIG9iamVjdCcKCiAgICBmaWxlbmFtZSA9IGdldHNvdXJjZWZpbGUoZnJhbWUpCiAgICBsaW5lbm8gPSBnZXRsaW5lbm8oZnJhbWUpCiAgICBpZiBjb250ZXh0ID4gMDoKICAgICAgICBzdGFydCA9IGxpbmVubyAtIDEgLSBjb250ZXh0Ly8yCiAgICAgICAgdHJ5OgogICAgICAgICAgICBsaW5lcywgbG51bSA9IGZpbmRzb3VyY2UoZnJhbWUpCiAgICAgICAgZXhjZXB0IElPRXJyb3I6CiAgICAgICAgICAgIGxpbmVzID0gaW5kZXggPSBOb25lCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc3RhcnQgPSBtYXgoc3RhcnQsIDEpCiAgICAgICAgICAgIHN0YXJ0ID0gbWluKHN0YXJ0LCBsZW4obGluZXMpIC0gY29udGV4dCkKICAgICAgICAgICAgbGluZXMgPSBsaW5lc1tzdGFydDpzdGFydCtjb250ZXh0XQogICAgICAgICAgICBpbmRleCA9IGxpbmVubyAtIDEgLSBzdGFydAogICAgZWxzZToKICAgICAgICBsaW5lcyA9IGluZGV4ID0gTm9uZQoKICAgIHJldHVybiAoZmlsZW5hbWUsIGxpbmVubywgZnJhbWUuZl9jb2RlLmNvX25hbWUsIGxpbmVzLCBpbmRleCkKCmRlZiBnZXRsaW5lbm8oZnJhbWUpOgogICAgIiIiR2V0IHRoZSBsaW5lIG51bWJlciBmcm9tIGEgZnJhbWUgb2JqZWN0LCBhbGxvd2luZyBmb3Igb3B0aW1pemF0aW9uLiIiIgogICAgIyBXcml0dGVuIGJ5IE1hcmMtQW5kcukgTGVtYnVyZzsgcmV2aXNlZCBieSBKaW0gSHVndW5pbiBhbmQgRnJlZHJpayBMdW5kaC4KICAgIGxpbmVubyA9IGZyYW1lLmZfbGluZW5vCiAgICBjb2RlID0gZnJhbWUuZl9jb2RlCiAgICBpZiBoYXNhdHRyKGNvZGUsICdjb19sbm90YWInKToKICAgICAgICB0YWJsZSA9IGNvZGUuY29fbG5vdGFiCiAgICAgICAgbGluZW5vID0gY29kZS5jb19maXJzdGxpbmVubwogICAgICAgIGFkZHIgPSAwCiAgICAgICAgZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHRhYmxlKSwgMik6CiAgICAgICAgICAgIGFkZHIgPSBhZGRyICsgb3JkKHRhYmxlW2ldKQogICAgICAgICAgICBpZiBhZGRyID4gZnJhbWUuZl9sYXN0aTogYnJlYWsKICAgICAgICAgICAgbGluZW5vID0gbGluZW5vICsgb3JkKHRhYmxlW2krMV0pCiAgICByZXR1cm4gbGluZW5vCgpkZWYgZ2V0b3V0ZXJmcmFtZXMoZnJhbWUsIGNvbnRleHQ9MSk6CiAgICAiIiJHZXQgYSBsaXN0IG9mIHJlY29yZHMgZm9yIGEgZnJhbWUgYW5kIGFsbCBoaWdoZXIgKGNhbGxpbmcpIGZyYW1lcy4KCiAgICBFYWNoIHJlY29yZCBjb250YWlucyBhIGZyYW1lIG9iamVjdCwgZmlsZW5hbWUsIGxpbmUgbnVtYmVyLCBmdW5jdGlvbgogICAgbmFtZSwgYSBsaXN0IG9mIGxpbmVzIG9mIGNvbnRleHQsIGFuZCBpbmRleCB3aXRoaW4gdGhlIGNvbnRleHQuIiIiCiAgICBmcmFtZWxpc3QgPSBbXQogICAgd2hpbGUgZnJhbWU6CiAgICAgICAgZnJhbWVsaXN0LmFwcGVuZCgoZnJhbWUsKSArIGdldGZyYW1laW5mbyhmcmFtZSwgY29udGV4dCkpCiAgICAgICAgZnJhbWUgPSBmcmFtZS5mX2JhY2sKICAgIHJldHVybiBmcmFtZWxpc3QKCmRlZiBnZXRpbm5lcmZyYW1lcyh0YiwgY29udGV4dD0xKToKICAgICIiIkdldCBhIGxpc3Qgb2YgcmVjb3JkcyBmb3IgYSB0cmFjZWJhY2sncyBmcmFtZSBhbmQgYWxsIGxvd2VyIGZyYW1lcy4KCiAgICBFYWNoIHJlY29yZCBjb250YWlucyBhIGZyYW1lIG9iamVjdCwgZmlsZW5hbWUsIGxpbmUgbnVtYmVyLCBmdW5jdGlvbgogICAgbmFtZSwgYSBsaXN0IG9mIGxpbmVzIG9mIGNvbnRleHQsIGFuZCBpbmRleCB3aXRoaW4gdGhlIGNvbnRleHQuIiIiCiAgICBmcmFtZWxpc3QgPSBbXQogICAgd2hpbGUgdGI6CiAgICAgICAgZnJhbWVsaXN0LmFwcGVuZCgodGIudGJfZnJhbWUsKSArIGdldGZyYW1laW5mbyh0YiwgY29udGV4dCkpCiAgICAgICAgdGIgPSB0Yi50Yl9uZXh0CiAgICByZXR1cm4gZnJhbWVsaXN0CgpkZWYgY3VycmVudGZyYW1lKCk6CiAgICAiIiJSZXR1cm4gdGhlIGZyYW1lIG9iamVjdCBmb3IgdGhlIGNhbGxlcidzIHN0YWNrIGZyYW1lLiIiIgogICAgdHJ5OgogICAgICAgIHJhaXNlICdjYXRjaCBtZScKICAgIGV4Y2VwdDoKICAgICAgICByZXR1cm4gc3lzLmV4Y190cmFjZWJhY2sudGJfZnJhbWUuZl9iYWNrCgppZiBoYXNhdHRyKHN5cywgJ19nZXRmcmFtZScpOiBjdXJyZW50ZnJhbWUgPSBzeXMuX2dldGZyYW1lCgpkZWYgc3RhY2soY29udGV4dD0xKToKICAgICIiIlJldHVybiBhIGxpc3Qgb2YgcmVjb3JkcyBmb3IgdGhlIHN0YWNrIGFib3ZlIHRoZSBjYWxsZXIncyBmcmFtZS4iIiIKICAgIHJldHVybiBnZXRvdXRlcmZyYW1lcyhjdXJyZW50ZnJhbWUoKS5mX2JhY2ssIGNvbnRleHQpCgpkZWYgdHJhY2UoY29udGV4dD0xKToKICAgICIiIlJldHVybiBhIGxpc3Qgb2YgcmVjb3JkcyBmb3IgdGhlIHN0YWNrIGJlbG93IHRoZSBjdXJyZW50IGV4Y2VwdGlvbi4iIiIKICAgIHJldHVybiBnZXRpbm5lcmZyYW1lcyhzeXMuZXhjX3RyYWNlYmFjaywgY29udGV4dCkK