@sentry/node 7.106.0 → 7.106.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- /*! @sentry/node 7.106.0 (6b3f70d) | https://github.com/getsentry/sentry-javascript */
1
+ /*! @sentry/node 7.106.1 (887f0e7) | https://github.com/getsentry/sentry-javascript */
2
2
  exports.base64WorkerScript="aW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJ2luc3BlY3Rvcic7CmltcG9ydCB7IHdvcmtlckRhdGEsIHBhcmVudFBvcnQgfSBmcm9tICd3b3JrZXJfdGhyZWFkcyc7CmltcG9ydCB7IHBvc2l4LCBzZXAgfSBmcm9tICdwYXRoJzsKaW1wb3J0ICogYXMgaHR0cCBmcm9tICdodHRwJzsKaW1wb3J0ICogYXMgaHR0cHMgZnJvbSAnaHR0cHMnOwppbXBvcnQgeyBSZWFkYWJsZSB9IGZyb20gJ3N0cmVhbSc7CmltcG9ydCB7IFVSTCB9IGZyb20gJ3VybCc7CmltcG9ydCB7IGNyZWF0ZUd6aXAgfSBmcm9tICd6bGliJzsKaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnOwppbXBvcnQgKiBhcyBuZXQgZnJvbSAnbmV0JzsKaW1wb3J0ICogYXMgdGxzIGZyb20gJ3Rscyc7CgovLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L3VuYm91bmQtbWV0aG9kCmNvbnN0IG9iamVjdFRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZzsKCi8qKgogKiBDaGVja3Mgd2hldGhlciBnaXZlbiB2YWx1ZSdzIHR5cGUgaXMgb25lIG9mIGEgZmV3IEVycm9yIG9yIEVycm9yLWxpa2UKICoge0BsaW5rIGlzRXJyb3J9LgogKgogKiBAcGFyYW0gd2F0IEEgdmFsdWUgdG8gYmUgY2hlY2tlZC4KICogQHJldHVybnMgQSBib29sZWFuIHJlcHJlc2VudGluZyB0aGUgcmVzdWx0LgogKi8KZnVuY3Rpb24gaXNFcnJvcih3YXQpIHsKICBzd2l0Y2ggKG9iamVjdFRvU3RyaW5nLmNhbGwod2F0KSkgewogICAgY2FzZSAnW29iamVjdCBFcnJvcl0nOgogICAgY2FzZSAnW29iamVjdCBFeGNlcHRpb25dJzoKICAgIGNhc2UgJ1tvYmplY3QgRE9NRXhjZXB0aW9uXSc6CiAgICAgIHJldHVybiB0cnVlOwogICAgZGVmYXVsdDoKICAgICAgcmV0dXJuIGlzSW5zdGFuY2VPZih3YXQsIEVycm9yKTsKICB9Cn0KLyoqCiAqIENoZWNrcyB3aGV0aGVyIGdpdmVuIHZhbHVlIGlzIGFuIGluc3RhbmNlIG9mIHRoZSBnaXZlbiBidWlsdC1pbiBjbGFzcy4KICoKICogQHBhcmFtIHdhdCBUaGUgdmFsdWUgdG8gYmUgY2hlY2tlZAogKiBAcGFyYW0gY2xhc3NOYW1lCiAqIEByZXR1cm5zIEEgYm9vbGVhbiByZXByZXNlbnRpbmcgdGhlIHJlc3VsdC4KICovCmZ1bmN0aW9uIGlzQnVpbHRpbih3YXQsIGNsYXNzTmFtZSkgewogIHJldHVybiBvYmplY3RUb1N0cmluZy5jYWxsKHdhdCkgPT09IGBbb2JqZWN0ICR7Y2xhc3NOYW1lfV1gOwp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUncyB0eXBlIGlzIGEgc3RyaW5nCiAqIHtAbGluayBpc1N0cmluZ30uCiAqCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc1N0cmluZyh3YXQpIHsKICByZXR1cm4gaXNCdWlsdGluKHdhdCwgJ1N0cmluZycpOwp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUncyB0eXBlIGlzIGFuIG9iamVjdCBsaXRlcmFsLCBvciBhIGNsYXNzIGluc3RhbmNlLgogKiB7QGxpbmsgaXNQbGFpbk9iamVjdH0uCiAqCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc1BsYWluT2JqZWN0KHdhdCkgewogIHJldHVybiBpc0J1aWx0aW4od2F0LCAnT2JqZWN0Jyk7Cn0KCi8qKgogKiBDaGVja3Mgd2hldGhlciBnaXZlbiB2YWx1ZSdzIHR5cGUgaXMgYW4gRXZlbnQgaW5zdGFuY2UKICoge0BsaW5rIGlzRXZlbnR9LgogKgogKiBAcGFyYW0gd2F0IEEgdmFsdWUgdG8gYmUgY2hlY2tlZC4KICogQHJldHVybnMgQSBib29sZWFuIHJlcHJlc2VudGluZyB0aGUgcmVzdWx0LgogKi8KZnVuY3Rpb24gaXNFdmVudCh3YXQpIHsKICByZXR1cm4gdHlwZW9mIEV2ZW50ICE9PSAndW5kZWZpbmVkJyAmJiBpc0luc3RhbmNlT2Yod2F0LCBFdmVudCk7Cn0KCi8qKgogKiBDaGVja3Mgd2hldGhlciBnaXZlbiB2YWx1ZSdzIHR5cGUgaXMgYW4gRWxlbWVudCBpbnN0YW5jZQogKiB7QGxpbmsgaXNFbGVtZW50fS4KICoKICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqIEByZXR1cm5zIEEgYm9vbGVhbiByZXByZXNlbnRpbmcgdGhlIHJlc3VsdC4KICovCmZ1bmN0aW9uIGlzRWxlbWVudCh3YXQpIHsKICByZXR1cm4gdHlwZW9mIEVsZW1lbnQgIT09ICd1bmRlZmluZWQnICYmIGlzSW5zdGFuY2VPZih3YXQsIEVsZW1lbnQpOwp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUgaGFzIGEgdGhlbiBmdW5jdGlvbi4KICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqLwpmdW5jdGlvbiBpc1RoZW5hYmxlKHdhdCkgewogIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLW1lbWJlci1hY2Nlc3MKICByZXR1cm4gQm9vbGVhbih3YXQgJiYgd2F0LnRoZW4gJiYgdHlwZW9mIHdhdC50aGVuID09PSAnZnVuY3Rpb24nKTsKfQoKLyoqCiAqIENoZWNrcyB3aGV0aGVyIGdpdmVuIHZhbHVlJ3MgdHlwZSBpcyBhIFN5bnRoZXRpY0V2ZW50CiAqIHtAbGluayBpc1N5bnRoZXRpY0V2ZW50fS4KICoKICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqIEByZXR1cm5zIEEgYm9vbGVhbiByZXByZXNlbnRpbmcgdGhlIHJlc3VsdC4KICovCmZ1bmN0aW9uIGlzU3ludGhldGljRXZlbnQod2F0KSB7CiAgcmV0dXJuIGlzUGxhaW5PYmplY3Qod2F0KSAmJiAnbmF0aXZlRXZlbnQnIGluIHdhdCAmJiAncHJldmVudERlZmF1bHQnIGluIHdhdCAmJiAnc3RvcFByb3BhZ2F0aW9uJyBpbiB3YXQ7Cn0KCi8qKgogKiBDaGVja3Mgd2hldGhlciBnaXZlbiB2YWx1ZSBpcyBOYU4KICoge0BsaW5rIGlzTmFOfS4KICoKICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqIEByZXR1cm5zIEEgYm9vbGVhbiByZXByZXNlbnRpbmcgdGhlIHJlc3VsdC4KICovCmZ1bmN0aW9uIGlzTmFOJDEod2F0KSB7CiAgcmV0dXJuIHR5cGVvZiB3YXQgPT09ICdudW1iZXInICYmIHdhdCAhPT0gd2F0Owp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUncyB0eXBlIGlzIGFuIGluc3RhbmNlIG9mIHByb3ZpZGVkIGNvbnN0cnVjdG9yLgogKiB7QGxpbmsgaXNJbnN0YW5jZU9mfS4KICoKICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqIEBwYXJhbSBiYXNlIEEgY29uc3RydWN0b3IgdG8gYmUgdXNlZCBpbiBhIGNoZWNrLgogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc0luc3RhbmNlT2Yod2F0LCBiYXNlKSB7CiAgdHJ5IHsKICAgIHJldHVybiB3YXQgaW5zdGFuY2VvZiBiYXNlOwogIH0gY2F0Y2ggKF9lKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUncyB0eXBlIGlzIGEgVnVlIFZpZXdNb2RlbC4KICoKICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqIEByZXR1cm5zIEEgYm9vbGVhbiByZXByZXNlbnRpbmcgdGhlIHJlc3VsdC4KICovCmZ1bmN0aW9uIGlzVnVlVmlld01vZGVsKHdhdCkgewogIC8vIE5vdCB1c2luZyBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nIGJlY2F1c2UgaW4gVnVlIDMgaXQgd291bGQgcmVhZCB0aGUgaW5zdGFuY2UncyBTeW1ib2woU3ltYm9sLnRvU3RyaW5nVGFnKSBwcm9wZXJ0eS4KICByZXR1cm4gISEodHlwZW9mIHdhdCA9PT0gJ29iamVjdCcgJiYgd2F0ICE9PSBudWxsICYmICgod2F0ICkuX19pc1Z1ZSB8fCAod2F0ICkuX2lzVnVlKSk7Cn0KCi8qKiBJbnRlcm5hbCBnbG9iYWwgd2l0aCBjb21tb24gcHJvcGVydGllcyBhbmQgU2VudHJ5IGV4dGVuc2lvbnMgICovCgovLyBUaGUgY29kZSBiZWxvdyBmb3IgJ2lzR2xvYmFsT2JqJyBhbmQgJ0dMT0JBTF9PQkonIHdhcyBjb3BpZWQgZnJvbSBjb3JlLWpzIGJlZm9yZSBtb2RpZmljYXRpb24KLy8gaHR0cHM6Ly9naXRodWIuY29tL3psb2lyb2NrL2NvcmUtanMvYmxvYi8xYjk0NGRmNTUyODJjZGM5OWM5MGRiNWY0OWViMGI2ZWRhMmNjMGEzL3BhY2thZ2VzL2NvcmUtanMvaW50ZXJuYWxzL2dsb2JhbC5qcwovLyBjb3JlLWpzIGhhcyB0aGUgZm9sbG93aW5nIGxpY2VuY2U6Ci8vCi8vIENvcHlyaWdodCAoYykgMjAxNC0yMDIyIERlbmlzIFB1c2hrYXJldgovLwovLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5Ci8vIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLCB0byBkZWFsCi8vIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMKLy8gdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbAovLyBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMKLy8gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKLy8KLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4KLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCi8vCi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLAovLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKLy8gQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUgovLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLAovLyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOCi8vIFRIRSBTT0ZUV0FSRS4KCi8qKiBSZXR1cm5zICdvYmonIGlmIGl0J3MgdGhlIGdsb2JhbCBvYmplY3QsIG90aGVyd2lzZSByZXR1cm5zIHVuZGVmaW5lZCAqLwpmdW5jdGlvbiBpc0dsb2JhbE9iaihvYmopIHsKICByZXR1cm4gb2JqICYmIG9iai5NYXRoID09IE1hdGggPyBvYmogOiB1bmRlZmluZWQ7Cn0KCi8qKiBHZXQncyB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgdGhlIGN1cnJlbnQgSmF2YVNjcmlwdCBydW50aW1lICovCmNvbnN0IEdMT0JBTF9PQkogPQogICh0eXBlb2YgZ2xvYmFsVGhpcyA9PSAnb2JqZWN0JyAmJiBpc0dsb2JhbE9iaihnbG9iYWxUaGlzKSkgfHwKICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1nbG9iYWxzCiAgKHR5cGVvZiB3aW5kb3cgPT0gJ29iamVjdCcgJiYgaXNHbG9iYWxPYmood2luZG93KSkgfHwKICAodHlwZW9mIHNlbGYgPT0gJ29iamVjdCcgJiYgaXNHbG9iYWxPYmooc2VsZikpIHx8CiAgKHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgaXNHbG9iYWxPYmooZ2xvYmFsKSkgfHwKICAoZnVuY3Rpb24gKCkgewogICAgcmV0dXJuIHRoaXM7CiAgfSkoKSB8fAogIHt9OwoKLyoqCiAqIEBkZXByZWNhdGVkIFVzZSBHTE9CQUxfT0JKIGluc3RlYWQgb3IgV0lORE9XIGZyb20gQHNlbnRyeS9icm93c2VyLiBUaGlzIHdpbGwgYmUgcmVtb3ZlZCBpbiB2OAogKi8KZnVuY3Rpb24gZ2V0R2xvYmFsT2JqZWN0KCkgewogIHJldHVybiBHTE9CQUxfT0JKIDsKfQoKLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCmNvbnN0IFdJTkRPVyA9IGdldEdsb2JhbE9iamVjdCgpOwoKY29uc3QgREVGQVVMVF9NQVhfU1RSSU5HX0xFTkdUSCA9IDgwOwoKLyoqCiAqIEdpdmVuIGEgY2hpbGQgRE9NIGVsZW1lbnQsIHJldHVybnMgYSBxdWVyeS1zZWxlY3RvciBzdGF0ZW1lbnQgZGVzY3JpYmluZyB0aGF0CiAqIGFuZCBpdHMgYW5jZXN0b3JzCiAqIGUuZy4gW0hUTUxFbGVtZW50XSA9PiBib2R5ID4gZGl2ID4gaW5wdXQjZm9vLmJ0bltuYW1lPWJhel0KICogQHJldHVybnMgZ2VuZXJhdGVkIERPTSBwYXRoCiAqLwpmdW5jdGlvbiBodG1sVHJlZUFzU3RyaW5nKAogIGVsZW0sCiAgb3B0aW9ucyA9IHt9LAopIHsKICBpZiAoIWVsZW0pIHsKICAgIHJldHVybiAnPHVua25vd24+JzsKICB9CgogIC8vIHRyeS9jYXRjaCBib3RoOgogIC8vIC0gYWNjZXNzaW5nIGV2ZW50LnRhcmdldCAoc2VlIGdldHNlbnRyeS9yYXZlbi1qcyM4MzgsICM3NjgpCiAgLy8gLSBgaHRtbFRyZWVBc1N0cmluZ2AgYmVjYXVzZSBpdCdzIGNvbXBsZXgsIGFuZCBqdXN0IGFjY2Vzc2luZyB0aGUgRE9NIGluY29ycmVjdGx5CiAgLy8gLSBjYW4gdGhyb3cgYW4gZXhjZXB0aW9uIGluIHNvbWUgY2lyY3Vtc3RhbmNlcy4KICB0cnkgewogICAgbGV0IGN1cnJlbnRFbGVtID0gZWxlbSA7CiAgICBjb25zdCBNQVhfVFJBVkVSU0VfSEVJR0hUID0gNTsKICAgIGNvbnN0IG91dCA9IFtdOwogICAgbGV0IGhlaWdodCA9IDA7CiAgICBsZXQgbGVuID0gMDsKICAgIGNvbnN0IHNlcGFyYXRvciA9ICcgPiAnOwogICAgY29uc3Qgc2VwTGVuZ3RoID0gc2VwYXJhdG9yLmxlbmd0aDsKICAgIGxldCBuZXh0U3RyOwogICAgY29uc3Qga2V5QXR0cnMgPSBBcnJheS5pc0FycmF5KG9wdGlvbnMpID8gb3B0aW9ucyA6IG9wdGlvbnMua2V5QXR0cnM7CiAgICBjb25zdCBtYXhTdHJpbmdMZW5ndGggPSAoIUFycmF5LmlzQXJyYXkob3B0aW9ucykgJiYgb3B0aW9ucy5tYXhTdHJpbmdMZW5ndGgpIHx8IERFRkFVTFRfTUFYX1NUUklOR19MRU5HVEg7CgogICAgd2hpbGUgKGN1cnJlbnRFbGVtICYmIGhlaWdodCsrIDwgTUFYX1RSQVZFUlNFX0hFSUdIVCkgewogICAgICBuZXh0U3RyID0gX2h0bWxFbGVtZW50QXNTdHJpbmcoY3VycmVudEVsZW0sIGtleUF0dHJzKTsKICAgICAgLy8gYmFpbCBvdXQgaWYKICAgICAgLy8gLSBuZXh0U3RyIGlzIHRoZSAnaHRtbCcgZWxlbWVudAogICAgICAvLyAtIHRoZSBsZW5ndGggb2YgdGhlIHN0cmluZyB0aGF0IHdvdWxkIGJlIGNyZWF0ZWQgZXhjZWVkcyBtYXhTdHJpbmdMZW5ndGgKICAgICAgLy8gICAoaWdub3JlIHRoaXMgbGltaXQgaWYgd2UgYXJlIG9uIHRoZSBmaXJzdCBpdGVyYXRpb24pCiAgICAgIGlmIChuZXh0U3RyID09PSAnaHRtbCcgfHwgKGhlaWdodCA+IDEgJiYgbGVuICsgb3V0Lmxlbmd0aCAqIHNlcExlbmd0aCArIG5leHRTdHIubGVuZ3RoID49IG1heFN0cmluZ0xlbmd0aCkpIHsKICAgICAgICBicmVhazsKICAgICAgfQoKICAgICAgb3V0LnB1c2gobmV4dFN0cik7CgogICAgICBsZW4gKz0gbmV4dFN0ci5sZW5ndGg7CiAgICAgIGN1cnJlbnRFbGVtID0gY3VycmVudEVsZW0ucGFyZW50Tm9kZTsKICAgIH0KCiAgICByZXR1cm4gb3V0LnJldmVyc2UoKS5qb2luKHNlcGFyYXRvcik7CiAgfSBjYXRjaCAoX29PKSB7CiAgICByZXR1cm4gJzx1bmtub3duPic7CiAgfQp9CgovKioKICogUmV0dXJucyBhIHNpbXBsZSwgcXVlcnktc2VsZWN0b3IgcmVwcmVzZW50YXRpb24gb2YgYSBET00gZWxlbWVudAogKiBlLmcuIFtIVE1MRWxlbWVudF0gPT4gaW5wdXQjZm9vLmJ0bltuYW1lPWJhel0KICogQHJldHVybnMgZ2VuZXJhdGVkIERPTSBwYXRoCiAqLwpmdW5jdGlvbiBfaHRtbEVsZW1lbnRBc1N0cmluZyhlbCwga2V5QXR0cnMpIHsKICBjb25zdCBlbGVtID0gZWwKCjsKCiAgY29uc3Qgb3V0ID0gW107CiAgbGV0IGNsYXNzTmFtZTsKICBsZXQgY2xhc3NlczsKICBsZXQga2V5OwogIGxldCBhdHRyOwogIGxldCBpOwoKICBpZiAoIWVsZW0gfHwgIWVsZW0udGFnTmFtZSkgewogICAgcmV0dXJuICcnOwogIH0KCiAgLy8gQHRzLWV4cGVjdC1lcnJvciBXSU5ET1cgaGFzIEhUTUxFbGVtZW50CiAgaWYgKFdJTkRPVy5IVE1MRWxlbWVudCkgewogICAgLy8gSWYgdXNpbmcgdGhlIGNvbXBvbmVudCBuYW1lIGFubm90YXRpb24gcGx1Z2luLCB0aGlzIHZhbHVlIG1heSBiZSBhdmFpbGFibGUgb24gdGhlIERPTSBub2RlCiAgICBpZiAoZWxlbSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50ICYmIGVsZW0uZGF0YXNldCAmJiBlbGVtLmRhdGFzZXRbJ3NlbnRyeUNvbXBvbmVudCddKSB7CiAgICAgIHJldHVybiBlbGVtLmRhdGFzZXRbJ3NlbnRyeUNvbXBvbmVudCddOwogICAgfQogIH0KCiAgb3V0LnB1c2goZWxlbS50YWdOYW1lLnRvTG93ZXJDYXNlKCkpOwoKICAvLyBQYWlycyBvZiBhdHRyaWJ1dGUga2V5cyBkZWZpbmVkIGluIGBzZXJpYWxpemVBdHRyaWJ1dGVgIGFuZCB0aGVpciB2YWx1ZXMgb24gZWxlbWVudC4KICBjb25zdCBrZXlBdHRyUGFpcnMgPQogICAga2V5QXR0cnMgJiYga2V5QXR0cnMubGVuZ3RoCiAgICAgID8ga2V5QXR0cnMuZmlsdGVyKGtleUF0dHIgPT4gZWxlbS5nZXRBdHRyaWJ1dGUoa2V5QXR0cikpLm1hcChrZXlBdHRyID0+IFtrZXlBdHRyLCBlbGVtLmdldEF0dHJpYnV0ZShrZXlBdHRyKV0pCiAgICAgIDogbnVsbDsKCiAgaWYgKGtleUF0dHJQYWlycyAmJiBrZXlBdHRyUGFpcnMubGVuZ3RoKSB7CiAgICBrZXlBdHRyUGFpcnMuZm9yRWFjaChrZXlBdHRyUGFpciA9PiB7CiAgICAgIG91dC5wdXNoKGBbJHtrZXlBdHRyUGFpclswXX09IiR7a2V5QXR0clBhaXJbMV19Il1gKTsKICAgIH0pOwogIH0gZWxzZSB7CiAgICBpZiAoZWxlbS5pZCkgewogICAgICBvdXQucHVzaChgIyR7ZWxlbS5pZH1gKTsKICAgIH0KCiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLWNvbnN0CiAgICBjbGFzc05hbWUgPSBlbGVtLmNsYXNzTmFtZTsKICAgIGlmIChjbGFzc05hbWUgJiYgaXNTdHJpbmcoY2xhc3NOYW1lKSkgewogICAgICBjbGFzc2VzID0gY2xhc3NOYW1lLnNwbGl0KC9ccysvKTsKICAgICAgZm9yIChpID0gMDsgaSA8IGNsYXNzZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICBvdXQucHVzaChgLiR7Y2xhc3Nlc1tpXX1gKTsKICAgICAgfQogICAgfQogIH0KICBjb25zdCBhbGxvd2VkQXR0cnMgPSBbJ2FyaWEtbGFiZWwnLCAndHlwZScsICduYW1lJywgJ3RpdGxlJywgJ2FsdCddOwogIGZvciAoaSA9IDA7IGkgPCBhbGxvd2VkQXR0cnMubGVuZ3RoOyBpKyspIHsKICAgIGtleSA9IGFsbG93ZWRBdHRyc1tpXTsKICAgIGF0dHIgPSBlbGVtLmdldEF0dHJpYnV0ZShrZXkpOwogICAgaWYgKGF0dHIpIHsKICAgICAgb3V0LnB1c2goYFske2tleX09IiR7YXR0cn0iXWApOwogICAgfQogIH0KICByZXR1cm4gb3V0LmpvaW4oJycpOwp9CgovKioKICogVGhpcyBzZXJ2ZXMgYXMgYSBidWlsZCB0aW1lIGZsYWcgdGhhdCB3aWxsIGJlIHRydWUgYnkgZGVmYXVsdCwgYnV0IGZhbHNlIGluIG5vbi1kZWJ1ZyBidWlsZHMgb3IgaWYgdXNlcnMgcmVwbGFjZSBgX19TRU5UUllfREVCVUdfX2AgaW4gdGhlaXIgZ2VuZXJhdGVkIGNvZGUuCiAqCiAqIEFUVEVOVElPTjogVGhpcyBjb25zdGFudCBtdXN0IG5ldmVyIGNyb3NzIHBhY2thZ2UgYm91bmRhcmllcyAoaS5lLiBiZSBleHBvcnRlZCkgdG8gZ3VhcmFudGVlIHRoYXQgaXQgY2FuIGJlIHVzZWQgZm9yIHRyZWUgc2hha2luZy4KICovCmNvbnN0IERFQlVHX0JVSUxEJDEgPSAodHlwZW9mIF9fU0VOVFJZX0RFQlVHX18gPT09ICd1bmRlZmluZWQnIHx8IF9fU0VOVFJZX0RFQlVHX18pOwoKLyoqIFByZWZpeCBmb3IgbG9nZ2luZyBzdHJpbmdzICovCmNvbnN0IFBSRUZJWCA9ICdTZW50cnkgTG9nZ2VyICc7Cgpjb25zdCBDT05TT0xFX0xFVkVMUyA9IFsKICAnZGVidWcnLAogICdpbmZvJywKICAnd2FybicsCiAgJ2Vycm9yJywKICAnbG9nJywKICAnYXNzZXJ0JywKICAndHJhY2UnLApdIDsKCi8qKiBUaGlzIG1heSBiZSBtdXRhdGVkIGJ5IHRoZSBjb25zb2xlIGluc3RydW1lbnRhdGlvbi4gKi8KY29uc3Qgb3JpZ2luYWxDb25zb2xlTWV0aG9kcwoKID0ge307CgovKiogSlNEb2MgKi8KCi8qKgogKiBUZW1wb3JhcmlseSBkaXNhYmxlIHNlbnRyeSBjb25zb2xlIGluc3RydW1lbnRhdGlvbnMuCiAqCiAqIEBwYXJhbSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gdG8gcnVuIGFnYWluc3QgdGhlIG9yaWdpbmFsIGBjb25zb2xlYCBtZXNzYWdlcwogKiBAcmV0dXJucyBUaGUgcmVzdWx0cyBvZiB0aGUgY2FsbGJhY2sKICovCmZ1bmN0aW9uIGNvbnNvbGVTYW5kYm94KGNhbGxiYWNrKSB7CiAgaWYgKCEoJ2NvbnNvbGUnIGluIEdMT0JBTF9PQkopKSB7CiAgICByZXR1cm4gY2FsbGJhY2soKTsKICB9CgogIGNvbnN0IGNvbnNvbGUgPSBHTE9CQUxfT0JKLmNvbnNvbGUgOwogIGNvbnN0IHdyYXBwZWRGdW5jcyA9IHt9OwoKICBjb25zdCB3cmFwcGVkTGV2ZWxzID0gT2JqZWN0LmtleXMob3JpZ2luYWxDb25zb2xlTWV0aG9kcykgOwoKICAvLyBSZXN0b3JlIGFsbCB3cmFwcGVkIGNvbnNvbGUgbWV0aG9kcwogIHdyYXBwZWRMZXZlbHMuZm9yRWFjaChsZXZlbCA9PiB7CiAgICBjb25zdCBvcmlnaW5hbENvbnNvbGVNZXRob2QgPSBvcmlnaW5hbENvbnNvbGVNZXRob2RzW2xldmVsXSA7CiAgICB3cmFwcGVkRnVuY3NbbGV2ZWxdID0gY29uc29sZVtsZXZlbF0gOwogICAgY29uc29sZVtsZXZlbF0gPSBvcmlnaW5hbENvbnNvbGVNZXRob2Q7CiAgfSk7CgogIHRyeSB7CiAgICByZXR1cm4gY2FsbGJhY2soKTsKICB9IGZpbmFsbHkgewogICAgLy8gUmV2ZXJ0IHJlc3RvcmF0aW9uIHRvIHdyYXBwZWQgc3RhdGUKICAgIHdyYXBwZWRMZXZlbHMuZm9yRWFjaChsZXZlbCA9PiB7CiAgICAgIGNvbnNvbGVbbGV2ZWxdID0gd3JhcHBlZEZ1bmNzW2xldmVsXSA7CiAgICB9KTsKICB9Cn0KCmZ1bmN0aW9uIG1ha2VMb2dnZXIoKSB7CiAgbGV0IGVuYWJsZWQgPSBmYWxzZTsKICBjb25zdCBsb2dnZXIgPSB7CiAgICBlbmFibGU6ICgpID0+IHsKICAgICAgZW5hYmxlZCA9IHRydWU7CiAgICB9LAogICAgZGlzYWJsZTogKCkgPT4gewogICAgICBlbmFibGVkID0gZmFsc2U7CiAgICB9LAogICAgaXNFbmFibGVkOiAoKSA9PiBlbmFibGVkLAogIH07CgogIGlmIChERUJVR19CVUlMRCQxKSB7CiAgICBDT05TT0xFX0xFVkVMUy5mb3JFYWNoKG5hbWUgPT4gewogICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueQogICAgICBsb2dnZXJbbmFtZV0gPSAoLi4uYXJncykgPT4gewogICAgICAgIGlmIChlbmFibGVkKSB7CiAgICAgICAgICBjb25zb2xlU2FuZGJveCgoKSA9PiB7CiAgICAgICAgICAgIEdMT0JBTF9PQkouY29uc29sZVtuYW1lXShgJHtQUkVGSVh9WyR7bmFtZX1dOmAsIC4uLmFyZ3MpOwogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICB9OwogICAgfSk7CiAgfSBlbHNlIHsKICAgIENPTlNPTEVfTEVWRUxTLmZvckVhY2gobmFtZSA9PiB7CiAgICAgIGxvZ2dlcltuYW1lXSA9ICgpID0+IHVuZGVmaW5lZDsKICAgIH0pOwogIH0KCiAgcmV0dXJuIGxvZ2dlciA7Cn0KCmNvbnN0IGxvZ2dlciA9IG1ha2VMb2dnZXIoKTsKCi8qKgogKiBSZW5kZXJzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBEc24uCiAqCiAqIEJ5IGRlZmF1bHQsIHRoaXMgd2lsbCByZW5kZXIgdGhlIHB1YmxpYyByZXByZXNlbnRhdGlvbiB3aXRob3V0IHRoZSBwYXNzd29yZAogKiBjb21wb25lbnQuIFRvIGdldCB0aGUgZGVwcmVjYXRlZCBwcml2YXRlIHJlcHJlc2VudGF0aW9uLCBzZXQgYHdpdGhQYXNzd29yZGAKICogdG8gdHJ1ZS4KICoKICogQHBhcmFtIHdpdGhQYXNzd29yZCBXaGVuIHNldCB0byB0cnVlLCB0aGUgcGFzc3dvcmQgd2lsbCBiZSBpbmNsdWRlZC4KICovCmZ1bmN0aW9uIGRzblRvU3RyaW5nKGRzbiwgd2l0aFBhc3N3b3JkID0gZmFsc2UpIHsKICBjb25zdCB7IGhvc3QsIHBhdGgsIHBhc3MsIHBvcnQsIHByb2plY3RJZCwgcHJvdG9jb2wsIHB1YmxpY0tleSB9ID0gZHNuOwogIHJldHVybiAoCiAgICBgJHtwcm90b2NvbH06Ly8ke3B1YmxpY0tleX0ke3dpdGhQYXNzd29yZCAmJiBwYXNzID8gYDoke3Bhc3N9YCA6ICcnfWAgKwogICAgYEAke2hvc3R9JHtwb3J0ID8gYDoke3BvcnR9YCA6ICcnfS8ke3BhdGggPyBgJHtwYXRofS9gIDogcGF0aH0ke3Byb2plY3RJZH1gCiAgKTsKfQoKLyoqIEFuIGVycm9yIGVtaXR0ZWQgYnkgU2VudHJ5IFNES3MgYW5kIHJlbGF0ZWQgdXRpbGl0aWVzLiAqLwpjbGFzcyBTZW50cnlFcnJvciBleHRlbmRzIEVycm9yIHsKICAvKiogRGlzcGxheSBuYW1lIG9mIHRoaXMgZXJyb3IgaW5zdGFuY2UuICovCgogICBjb25zdHJ1Y3RvciggbWVzc2FnZSwgbG9nTGV2ZWwgPSAnd2FybicpIHsKICAgIHN1cGVyKG1lc3NhZ2UpO3RoaXMubWVzc2FnZSA9IG1lc3NhZ2U7CiAgICB0aGlzLm5hbWUgPSBuZXcudGFyZ2V0LnByb3RvdHlwZS5jb25zdHJ1Y3Rvci5uYW1lOwogICAgLy8gVGhpcyBzZXRzIHRoZSBwcm90b3R5cGUgdG8gYmUgYEVycm9yYCwgbm90IGBTZW50cnlFcnJvcmAuIEl0J3MgdW5jbGVhciB3aHkgd2UgZG8gdGhpcywgYnV0IGNvbW1lbnRpbmcgdGhpcyBsaW5lCiAgICAvLyBvdXQgY2F1c2VzIHZhcmlvdXMgKHNlZW1pbmdseSB0b3RhbGx5IHVucmVsYXRlZCkgcGxheXdyaWdodCB0ZXN0cyBjb25zaXN0ZW50bHkgdGltZSBvdXQuIEZZSSwgdGhpcyBtYWtlcwogICAgLy8gaW5zdGFuY2VzIG9mIGBTZW50cnlFcnJvcmAgZmFpbCBgb2JqIGluc3RhbmNlb2YgU2VudHJ5RXJyb3JgIGNoZWNrcy4KICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBuZXcudGFyZ2V0LnByb3RvdHlwZSk7CiAgICB0aGlzLmxvZ0xldmVsID0gbG9nTGV2ZWw7CiAgfQp9CgovKioKICogRW5jb2RlcyBnaXZlbiBvYmplY3QgaW50byB1cmwtZnJpZW5kbHkgZm9ybWF0CiAqCiAqIEBwYXJhbSBvYmplY3QgQW4gb2JqZWN0IHRoYXQgY29udGFpbnMgc2VyaWFsaXphYmxlIHZhbHVlcwogKiBAcmV0dXJucyBzdHJpbmcgRW5jb2RlZAogKi8KZnVuY3Rpb24gdXJsRW5jb2RlKG9iamVjdCkgewogIHJldHVybiBPYmplY3Qua2V5cyhvYmplY3QpCiAgICAubWFwKGtleSA9PiBgJHtlbmNvZGVVUklDb21wb25lbnQoa2V5KX09JHtlbmNvZGVVUklDb21wb25lbnQob2JqZWN0W2tleV0pfWApCiAgICAuam9pbignJicpOwp9CgovKioKICogVHJhbnNmb3JtcyBhbnkgYEVycm9yYCBvciBgRXZlbnRgIGludG8gYSBwbGFpbiBvYmplY3Qgd2l0aCBhbGwgb2YgdGhlaXIgZW51bWVyYWJsZSBwcm9wZXJ0aWVzLCBhbmQgc29tZSBvZiB0aGVpcgogKiBub24tZW51bWVyYWJsZSBwcm9wZXJ0aWVzIGF0dGFjaGVkLgogKgogKiBAcGFyYW0gdmFsdWUgSW5pdGlhbCBzb3VyY2UgdGhhdCB3ZSBoYXZlIHRvIHRyYW5zZm9ybSBpbiBvcmRlciBmb3IgaXQgdG8gYmUgdXNhYmxlIGJ5IHRoZSBzZXJpYWxpemVyCiAqIEByZXR1cm5zIEFuIEV2ZW50IG9yIEVycm9yIHR1cm5lZCBpbnRvIGFuIG9iamVjdCAtIG9yIHRoZSB2YWx1ZSBhcmd1cm1lbnQgaXRzZWxmLCB3aGVuIHZhbHVlIGlzIG5laXRoZXIgYW4gRXZlbnQgbm9yCiAqICBhbiBFcnJvci4KICovCmZ1bmN0aW9uIGNvbnZlcnRUb1BsYWluT2JqZWN0KAogIHZhbHVlLAopCgogewogIGlmIChpc0Vycm9yKHZhbHVlKSkgewogICAgcmV0dXJuIHsKICAgICAgbWVzc2FnZTogdmFsdWUubWVzc2FnZSwKICAgICAgbmFtZTogdmFsdWUubmFtZSwKICAgICAgc3RhY2s6IHZhbHVlLnN0YWNrLAogICAgICAuLi5nZXRPd25Qcm9wZXJ0aWVzKHZhbHVlKSwKICAgIH07CiAgfSBlbHNlIGlmIChpc0V2ZW50KHZhbHVlKSkgewogICAgY29uc3QgbmV3T2JqCgogPSB7CiAgICAgIHR5cGU6IHZhbHVlLnR5cGUsCiAgICAgIHRhcmdldDogc2VyaWFsaXplRXZlbnRUYXJnZXQodmFsdWUudGFyZ2V0KSwKICAgICAgY3VycmVudFRhcmdldDogc2VyaWFsaXplRXZlbnRUYXJnZXQodmFsdWUuY3VycmVudFRhcmdldCksCiAgICAgIC4uLmdldE93blByb3BlcnRpZXModmFsdWUpLAogICAgfTsKCiAgICBpZiAodHlwZW9mIEN1c3RvbUV2ZW50ICE9PSAndW5kZWZpbmVkJyAmJiBpc0luc3RhbmNlT2YodmFsdWUsIEN1c3RvbUV2ZW50KSkgewogICAgICBuZXdPYmouZGV0YWlsID0gdmFsdWUuZGV0YWlsOwogICAgfQoKICAgIHJldHVybiBuZXdPYmo7CiAgfSBlbHNlIHsKICAgIHJldHVybiB2YWx1ZTsKICB9Cn0KCi8qKiBDcmVhdGVzIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB0YXJnZXQgb2YgYW4gYEV2ZW50YCBvYmplY3QgKi8KZnVuY3Rpb24gc2VyaWFsaXplRXZlbnRUYXJnZXQodGFyZ2V0KSB7CiAgdHJ5IHsKICAgIHJldHVybiBpc0VsZW1lbnQodGFyZ2V0KSA/IGh0bWxUcmVlQXNTdHJpbmcodGFyZ2V0KSA6IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0YXJnZXQpOwogIH0gY2F0Y2ggKF9vTykgewogICAgcmV0dXJuICc8dW5rbm93bj4nOwogIH0KfQoKLyoqIEZpbHRlcnMgb3V0IGFsbCBidXQgYW4gb2JqZWN0J3Mgb3duIHByb3BlcnRpZXMgKi8KZnVuY3Rpb24gZ2V0T3duUHJvcGVydGllcyhvYmopIHsKICBpZiAodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgb2JqICE9PSBudWxsKSB7CiAgICBjb25zdCBleHRyYWN0ZWRQcm9wcyA9IHt9OwogICAgZm9yIChjb25zdCBwcm9wZXJ0eSBpbiBvYmopIHsKICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3BlcnR5KSkgewogICAgICAgIGV4dHJhY3RlZFByb3BzW3Byb3BlcnR5XSA9IChvYmogKVtwcm9wZXJ0eV07CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBleHRyYWN0ZWRQcm9wczsKICB9IGVsc2UgewogICAgcmV0dXJuIHt9OwogIH0KfQoKLyoqCiAqIEdpdmVuIGFueSBvYmplY3QsIHJldHVybiBhIG5ldyBvYmplY3QgaGF2aW5nIHJlbW92ZWQgYWxsIGZpZWxkcyB3aG9zZSB2YWx1ZSB3YXMgYHVuZGVmaW5lZGAuCiAqIFdvcmtzIHJlY3Vyc2l2ZWx5IG9uIG9iamVjdHMgYW5kIGFycmF5cy4KICoKICogQXR0ZW50aW9uOiBUaGlzIGZ1bmN0aW9uIGtlZXBzIGNpcmN1bGFyIHJlZmVyZW5jZXMgaW4gdGhlIHJldHVybmVkIG9iamVjdC4KICovCmZ1bmN0aW9uIGRyb3BVbmRlZmluZWRLZXlzKGlucHV0VmFsdWUpIHsKICAvLyBUaGlzIG1hcCBrZWVwcyB0cmFjayBvZiB3aGF0IGFscmVhZHkgdmlzaXRlZCBub2RlcyBtYXAgdG8uCiAgLy8gT3VyIFNldCAtIGJhc2VkIG1lbW9CdWlsZGVyIGRvZXNuJ3Qgd29yayBoZXJlIGJlY2F1c2Ugd2Ugd2FudCB0byB0aGUgb3V0cHV0IG9iamVjdCB0byBoYXZlIHRoZSBzYW1lIGNpcmN1bGFyCiAgLy8gcmVmZXJlbmNlcyBhcyB0aGUgaW5wdXQgb2JqZWN0LgogIGNvbnN0IG1lbW9pemF0aW9uTWFwID0gbmV3IE1hcCgpOwoKICAvLyBUaGlzIGZ1bmN0aW9uIGp1c3QgcHJveGllcyBgX2Ryb3BVbmRlZmluZWRLZXlzYCB0byBrZWVwIHRoZSBgbWVtb0J1aWxkZXJgIG91dCBvZiB0aGlzIGZ1bmN0aW9uJ3MgQVBJCiAgcmV0dXJuIF9kcm9wVW5kZWZpbmVkS2V5cyhpbnB1dFZhbHVlLCBtZW1vaXphdGlvbk1hcCk7Cn0KCmZ1bmN0aW9uIF9kcm9wVW5kZWZpbmVkS2V5cyhpbnB1dFZhbHVlLCBtZW1vaXphdGlvbk1hcCkgewogIGlmIChpc1Bvam8oaW5wdXRWYWx1ZSkpIHsKICAgIC8vIElmIHRoaXMgbm9kZSBoYXMgYWxyZWFkeSBiZWVuIHZpc2l0ZWQgZHVlIHRvIGEgY2lyY3VsYXIgcmVmZXJlbmNlLCByZXR1cm4gdGhlIG9iamVjdCBpdCB3YXMgbWFwcGVkIHRvIGluIHRoZSBuZXcgb2JqZWN0CiAgICBjb25zdCBtZW1vVmFsID0gbWVtb2l6YXRpb25NYXAuZ2V0KGlucHV0VmFsdWUpOwogICAgaWYgKG1lbW9WYWwgIT09IHVuZGVmaW5lZCkgewogICAgICByZXR1cm4gbWVtb1ZhbCA7CiAgICB9CgogICAgY29uc3QgcmV0dXJuVmFsdWUgPSB7fTsKICAgIC8vIFN0b3JlIHRoZSBtYXBwaW5nIG9mIHRoaXMgdmFsdWUgaW4gY2FzZSB3ZSB2aXNpdCBpdCBhZ2FpbiwgaW4gY2FzZSBvZiBjaXJjdWxhciBkYXRhCiAgICBtZW1vaXphdGlvbk1hcC5zZXQoaW5wdXRWYWx1ZSwgcmV0dXJuVmFsdWUpOwoKICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGlucHV0VmFsdWUpKSB7CiAgICAgIGlmICh0eXBlb2YgaW5wdXRWYWx1ZVtrZXldICE9PSAndW5kZWZpbmVkJykgewogICAgICAgIHJldHVyblZhbHVlW2tleV0gPSBfZHJvcFVuZGVmaW5lZEtleXMoaW5wdXRWYWx1ZVtrZXldLCBtZW1vaXphdGlvbk1hcCk7CiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcmV0dXJuVmFsdWUgOwogIH0KCiAgaWYgKEFycmF5LmlzQXJyYXkoaW5wdXRWYWx1ZSkpIHsKICAgIC8vIElmIHRoaXMgbm9kZSBoYXMgYWxyZWFkeSBiZWVuIHZpc2l0ZWQgZHVlIHRvIGEgY2lyY3VsYXIgcmVmZXJlbmNlLCByZXR1cm4gdGhlIGFycmF5IGl0IHdhcyBtYXBwZWQgdG8gaW4gdGhlIG5ldyBvYmplY3QKICAgIGNvbnN0IG1lbW9WYWwgPSBtZW1vaXphdGlvbk1hcC5nZXQoaW5wdXRWYWx1ZSk7CiAgICBpZiAobWVtb1ZhbCAhPT0gdW5kZWZpbmVkKSB7CiAgICAgIHJldHVybiBtZW1vVmFsIDsKICAgIH0KCiAgICBjb25zdCByZXR1cm5WYWx1ZSA9IFtdOwogICAgLy8gU3RvcmUgdGhlIG1hcHBpbmcgb2YgdGhpcyB2YWx1ZSBpbiBjYXNlIHdlIHZpc2l0IGl0IGFnYWluLCBpbiBjYXNlIG9mIGNpcmN1bGFyIGRhdGEKICAgIG1lbW9pemF0aW9uTWFwLnNldChpbnB1dFZhbHVlLCByZXR1cm5WYWx1ZSk7CgogICAgaW5wdXRWYWx1ZS5mb3JFYWNoKChpdGVtKSA9PiB7CiAgICAgIHJldHVyblZhbHVlLnB1c2goX2Ryb3BVbmRlZmluZWRLZXlzKGl0ZW0sIG1lbW9pemF0aW9uTWFwKSk7CiAgICB9KTsKCiAgICByZXR1cm4gcmV0dXJuVmFsdWUgOwogIH0KCiAgcmV0dXJuIGlucHV0VmFsdWU7Cn0KCmZ1bmN0aW9uIGlzUG9qbyhpbnB1dCkgewogIGlmICghaXNQbGFpbk9iamVjdChpbnB1dCkpIHsKICAgIHJldHVybiBmYWxzZTsKICB9CgogIHRyeSB7CiAgICBjb25zdCBuYW1lID0gKE9iamVjdC5nZXRQcm90b3R5cGVPZihpbnB1dCkgKS5jb25zdHJ1Y3Rvci5uYW1lOwogICAgcmV0dXJuICFuYW1lIHx8IG5hbWUgPT09ICdPYmplY3QnOwogIH0gY2F0Y2ggKGUpIHsKICAgIHJldHVybiB0cnVlOwogIH0KfQoKLyoqCiAqIERvZXMgdGhpcyBmaWxlbmFtZSBsb29rIGxpa2UgaXQncyBwYXJ0IG9mIHRoZSBhcHAgY29kZT8KICovCmZ1bmN0aW9uIGZpbGVuYW1lSXNJbkFwcChmaWxlbmFtZSwgaXNOYXRpdmUgPSBmYWxzZSkgewogIGNvbnN0IGlzSW50ZXJuYWwgPQogICAgaXNOYXRpdmUgfHwKICAgIChmaWxlbmFtZSAmJgogICAgICAvLyBJdCdzIG5vdCBpbnRlcm5hbCBpZiBpdCdzIGFuIGFic29sdXRlIGxpbnV4IHBhdGgKICAgICAgIWZpbGVuYW1lLnN0YXJ0c1dpdGgoJy8nKSAmJgogICAgICAvLyBJdCdzIG5vdCBpbnRlcm5hbCBpZiBpdCdzIGFuIGFic29sdXRlIHdpbmRvd3MgcGF0aAogICAgICAhZmlsZW5hbWUubWF0Y2goL15bQS1aXTovKSAmJgogICAgICAvLyBJdCdzIG5vdCBpbnRlcm5hbCBpZiB0aGUgcGF0aCBpcyBzdGFydGluZyB3aXRoIGEgZG90CiAgICAgICFmaWxlbmFtZS5zdGFydHNXaXRoKCcuJykgJiYKICAgICAgLy8gSXQncyBub3QgaW50ZXJuYWwgaWYgdGhlIGZyYW1lIGhhcyBhIHByb3RvY29sLiBJbiBub2RlLCB0aGlzIGlzIHVzdWFsbHkgdGhlIGNhc2UgaWYgdGhlIGZpbGUgZ290IHByZS1wcm9jZXNzZWQgd2l0aCBhIGJ1bmRsZXIgbGlrZSB3ZWJwYWNrCiAgICAgICFmaWxlbmFtZS5tYXRjaCgvXlthLXpBLVpdKFthLXpBLVowLTkuXC0rXSkqOlwvXC8vKSk7IC8vIFNjaGVtYSBmcm9tOiBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMzY0MTc4MgoKICAvLyBpbl9hcHAgaXMgYWxsIHRoYXQncyBub3QgYW4gaW50ZXJuYWwgTm9kZSBmdW5jdGlvbiBvciBhIG1vZHVsZSB3aXRoaW4gbm9kZV9tb2R1bGVzCiAgLy8gbm90ZSB0aGF0IGlzTmF0aXZlIGFwcGVhcnMgdG8gcmV0dXJuIHRydWUgZXZlbiBmb3Igbm9kZSBjb3JlIGxpYnJhcmllcwogIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vZ2V0c2VudHJ5L3JhdmVuLW5vZGUvaXNzdWVzLzE3NgoKICByZXR1cm4gIWlzSW50ZXJuYWwgJiYgZmlsZW5hbWUgIT09IHVuZGVmaW5lZCAmJiAhZmlsZW5hbWUuaW5jbHVkZXMoJ25vZGVfbW9kdWxlcy8nKTsKfQoKY29uc3QgU1RBQ0tUUkFDRV9GUkFNRV9MSU1JVCA9IDUwOwpjb25zdCBTVFJJUF9GUkFNRV9SRUdFWFAgPSAvY2FwdHVyZU1lc3NhZ2V8Y2FwdHVyZUV4Y2VwdGlvbi87CgovKioKICogUmVtb3ZlcyBTZW50cnkgZnJhbWVzIGZyb20gdGhlIHRvcCBhbmQgYm90dG9tIG9mIHRoZSBzdGFjayBpZiBwcmVzZW50IGFuZCBlbmZvcmNlcyBhIGxpbWl0IG9mIG1heCBudW1iZXIgb2YgZnJhbWVzLgogKiBBc3N1bWVzIHN0YWNrIGlucHV0IGlzIG9yZGVyZWQgZnJvbSB0b3AgdG8gYm90dG9tIGFuZCByZXR1cm5zIHRoZSByZXZlcnNlIHJlcHJlc2VudGF0aW9uIHNvIGNhbGwgc2l0ZSBvZiB0aGUKICogZnVuY3Rpb24gdGhhdCBjYXVzZWQgdGhlIGNyYXNoIGlzIHRoZSBsYXN0IGZyYW1lIGluIHRoZSBhcnJheS4KICogQGhpZGRlbgogKi8KZnVuY3Rpb24gc3RyaXBTZW50cnlGcmFtZXNBbmRSZXZlcnNlKHN0YWNrKSB7CiAgaWYgKCFzdGFjay5sZW5ndGgpIHsKICAgIHJldHVybiBbXTsKICB9CgogIGNvbnN0IGxvY2FsU3RhY2sgPSBBcnJheS5mcm9tKHN0YWNrKTsKCiAgLy8gSWYgc3RhY2sgc3RhcnRzIHdpdGggb25lIG9mIG91ciBBUEkgY2FsbHMsIHJlbW92ZSBpdCAoc3RhcnRzLCBtZWFuaW5nIGl0J3MgdGhlIHRvcCBvZiB0aGUgc3RhY2sgLSBha2EgbGFzdCBjYWxsKQogIGlmICgvc2VudHJ5V3JhcHBlZC8udGVzdChsb2NhbFN0YWNrW2xvY2FsU3RhY2subGVuZ3RoIC0gMV0uZnVuY3Rpb24gfHwgJycpKSB7CiAgICBsb2NhbFN0YWNrLnBvcCgpOwogIH0KCiAgLy8gUmV2ZXJzaW5nIGluIHRoZSBtaWRkbGUgb2YgdGhlIHByb2NlZHVyZSBhbGxvd3MgdXMgdG8ganVzdCBwb3AgdGhlIHZhbHVlcyBvZmYgdGhlIHN0YWNrCiAgbG9jYWxTdGFjay5yZXZlcnNlKCk7CgogIC8vIElmIHN0YWNrIGVuZHMgd2l0aCBvbmUgb2Ygb3VyIGludGVybmFsIEFQSSBjYWxscywgcmVtb3ZlIGl0IChlbmRzLCBtZWFuaW5nIGl0J3MgdGhlIGJvdHRvbSBvZiB0aGUgc3RhY2sgLSBha2EgdG9wLW1vc3QgY2FsbCkKICBpZiAoU1RSSVBfRlJBTUVfUkVHRVhQLnRlc3QobG9jYWxTdGFja1tsb2NhbFN0YWNrLmxlbmd0aCAtIDFdLmZ1bmN0aW9uIHx8ICcnKSkgewogICAgbG9jYWxTdGFjay5wb3AoKTsKCiAgICAvLyBXaGVuIHVzaW5nIHN5bnRoZXRpYyBldmVudHMsIHdlIHdpbGwgaGF2ZSBhIDIgbGV2ZWxzIGRlZXAgc3RhY2ssIGFzIGBuZXcgRXJyb3IoJ1NlbnRyeSBzeW50aGV0aWNFeGNlcHRpb24nKWAKICAgIC8vIGlzIHByb2R1Y2VkIHdpdGhpbiB0aGUgaHViIGl0c2VsZiwgbWFraW5nIGl0OgogICAgLy8KICAgIC8vICAgU2VudHJ5LmNhcHR1cmVFeGNlcHRpb24oKQogICAgLy8gICBnZXRDdXJyZW50SHViKCkuY2FwdHVyZUV4Y2VwdGlvbigpCiAgICAvLwogICAgLy8gaW5zdGVhZCBvZiBqdXN0IHRoZSB0b3AgYFNlbnRyeWAgY2FsbCBpdHNlbGYuCiAgICAvLyBUaGlzIGZvcmNlcyB1cyB0byBwb3NzaWJseSBzdHJpcCBhbiBhZGRpdGlvbmFsIGZyYW1lIGluIHRoZSBleGFjdCBzYW1lIHdhcyBhcyBhYm92ZS4KICAgIGlmIChTVFJJUF9GUkFNRV9SRUdFWFAudGVzdChsb2NhbFN0YWNrW2xvY2FsU3RhY2subGVuZ3RoIC0gMV0uZnVuY3Rpb24gfHwgJycpKSB7CiAgICAgIGxvY2FsU3RhY2sucG9wKCk7CiAgICB9CiAgfQoKICByZXR1cm4gbG9jYWxTdGFjay5zbGljZSgwLCBTVEFDS1RSQUNFX0ZSQU1FX0xJTUlUKS5tYXAoZnJhbWUgPT4gKHsKICAgIC4uLmZyYW1lLAogICAgZmlsZW5hbWU6IGZyYW1lLmZpbGVuYW1lIHx8IGxvY2FsU3RhY2tbbG9jYWxTdGFjay5sZW5ndGggLSAxXS5maWxlbmFtZSwKICAgIGZ1bmN0aW9uOiBmcmFtZS5mdW5jdGlvbiB8fCAnPycsCiAgfSkpOwp9Cgpjb25zdCBkZWZhdWx0RnVuY3Rpb25OYW1lID0gJzxhbm9ueW1vdXM+JzsKCi8qKgogKiBTYWZlbHkgZXh0cmFjdCBmdW5jdGlvbiBuYW1lIGZyb20gaXRzZWxmCiAqLwpmdW5jdGlvbiBnZXRGdW5jdGlvbk5hbWUoZm4pIHsKICB0cnkgewogICAgaWYgKCFmbiB8fCB0eXBlb2YgZm4gIT09ICdmdW5jdGlvbicpIHsKICAgICAgcmV0dXJuIGRlZmF1bHRGdW5jdGlvbk5hbWU7CiAgICB9CiAgICByZXR1cm4gZm4ubmFtZSB8fCBkZWZhdWx0RnVuY3Rpb25OYW1lOwogIH0gY2F0Y2ggKGUpIHsKICAgIC8vIEp1c3QgYWNjZXNzaW5nIGN1c3RvbSBwcm9wcyBpbiBzb21lIFNlbGVuaXVtIGVudmlyb25tZW50cwogICAgLy8gY2FuIGNhdXNlIGEgIlBlcm1pc3Npb24gZGVuaWVkIiBleGNlcHRpb24gKHNlZSByYXZlbi1qcyM0OTUpLgogICAgcmV0dXJuIGRlZmF1bHRGdW5jdGlvbk5hbWU7CiAgfQp9CgovKioKICogVVVJRDQgZ2VuZXJhdG9yCiAqCiAqIEByZXR1cm5zIHN0cmluZyBHZW5lcmF0ZWQgVVVJRDQuCiAqLwpmdW5jdGlvbiB1dWlkNCgpIHsKICBjb25zdCBnYmwgPSBHTE9CQUxfT0JKIDsKICBjb25zdCBjcnlwdG8gPSBnYmwuY3J5cHRvIHx8IGdibC5tc0NyeXB0bzsKCiAgbGV0IGdldFJhbmRvbUJ5dGUgPSAoKSA9PiBNYXRoLnJhbmRvbSgpICogMTY7CiAgdHJ5IHsKICAgIGlmIChjcnlwdG8gJiYgY3J5cHRvLnJhbmRvbVVVSUQpIHsKICAgICAgcmV0dXJuIGNyeXB0by5yYW5kb21VVUlEKCkucmVwbGFjZSgvLS9nLCAnJyk7CiAgICB9CiAgICBpZiAoY3J5cHRvICYmIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMpIHsKICAgICAgZ2V0UmFuZG9tQnl0ZSA9ICgpID0+IHsKICAgICAgICAvLyBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzIG1pZ2h0IHJldHVybiB1bmRlZmluZWQgaW5zdGVhZCBvZiB0aGUgdHlwZWQgYXJyYXkKICAgICAgICAvLyBpbiBvbGQgQ2hyb21pdW0gdmVyc2lvbnMgKGUuZy4gMjMuMC4xMjM1LjAgKDE1MTQyMikpCiAgICAgICAgLy8gSG93ZXZlciwgYHR5cGVkQXJyYXlgIGlzIHN0aWxsIGZpbGxlZCBpbi1wbGFjZS4KICAgICAgICAvLyBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9DcnlwdG8vZ2V0UmFuZG9tVmFsdWVzI3R5cGVkYXJyYXkKICAgICAgICBjb25zdCB0eXBlZEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoMSk7CiAgICAgICAgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyh0eXBlZEFycmF5KTsKICAgICAgICByZXR1cm4gdHlwZWRBcnJheVswXTsKICAgICAgfTsKICAgIH0KICB9IGNhdGNoIChfKSB7CiAgICAvLyBzb21lIHJ1bnRpbWVzIGNhbiBjcmFzaCBpbnZva2luZyBjcnlwdG8KICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9nZXRzZW50cnkvc2VudHJ5LWphdmFzY3JpcHQvaXNzdWVzLzg5MzUKICB9CgogIC8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTA1MDM0L2hvdy10by1jcmVhdGUtYS1ndWlkLXV1aWQtaW4tamF2YXNjcmlwdC8yMTE3NTIzIzIxMTc1MjMKICAvLyBDb25jYXRlbmF0aW5nIHRoZSBmb2xsb3dpbmcgbnVtYmVycyBhcyBzdHJpbmdzIHJlc3VsdHMgaW4gJzEwMDAwMDAwMTAwMDQwMDA4MDAwMTAwMDAwMDAwMDAwJwogIHJldHVybiAoKFsxZTddICkgKyAxZTMgKyA0ZTMgKyA4ZTMgKyAxZTExKS5yZXBsYWNlKC9bMDE4XS9nLCBjID0+CiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYml0d2lzZQogICAgKChjICkgXiAoKGdldFJhbmRvbUJ5dGUoKSAmIDE1KSA+PiAoKGMgKSAvIDQpKSkudG9TdHJpbmcoMTYpLAogICk7Cn0KCi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtbWVtYmVyLWFjY2VzcyAqLwovKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55ICovCgovKioKICogSGVscGVyIHRvIGRlY3ljbGUganNvbiBvYmplY3RzCiAqLwpmdW5jdGlvbiBtZW1vQnVpbGRlcigpIHsKICBjb25zdCBoYXNXZWFrU2V0ID0gdHlwZW9mIFdlYWtTZXQgPT09ICdmdW5jdGlvbic7CiAgY29uc3QgaW5uZXIgPSBoYXNXZWFrU2V0ID8gbmV3IFdlYWtTZXQoKSA6IFtdOwogIGZ1bmN0aW9uIG1lbW9pemUob2JqKSB7CiAgICBpZiAoaGFzV2Vha1NldCkgewogICAgICBpZiAoaW5uZXIuaGFzKG9iaikpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpbm5lci5hZGQob2JqKTsKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9wcmVmZXItZm9yLW9mCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGlubmVyLmxlbmd0aDsgaSsrKSB7CiAgICAgIGNvbnN0IHZhbHVlID0gaW5uZXJbaV07CiAgICAgIGlmICh2YWx1ZSA9PT0gb2JqKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgIH0KICAgIGlubmVyLnB1c2gob2JqKTsKICAgIHJldHVybiBmYWxzZTsKICB9CgogIGZ1bmN0aW9uIHVubWVtb2l6ZShvYmopIHsKICAgIGlmIChoYXNXZWFrU2V0KSB7CiAgICAgIGlubmVyLmRlbGV0ZShvYmopOwogICAgfSBlbHNlIHsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbm5lci5sZW5ndGg7IGkrKykgewogICAgICAgIGlmIChpbm5lcltpXSA9PT0gb2JqKSB7CiAgICAgICAgICBpbm5lci5zcGxpY2UoaSwgMSk7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIFttZW1vaXplLCB1bm1lbW9pemVdOwp9CgovKioKICogUmVjdXJzaXZlbHkgbm9ybWFsaXplcyB0aGUgZ2l2ZW4gb2JqZWN0LgogKgogKiAtIENyZWF0ZXMgYSBjb3B5IHRvIHByZXZlbnQgb3JpZ2luYWwgaW5wdXQgbXV0YXRpb24KICogLSBTa2lwcyBub24tZW51bWVyYWJsZSBwcm9wZXJ0aWVzCiAqIC0gV2hlbiBzdHJpbmdpZnlpbmcsIGNhbGxzIGB0b0pTT05gIGlmIGltcGxlbWVudGVkCiAqIC0gUmVtb3ZlcyBjaXJjdWxhciByZWZlcmVuY2VzCiAqIC0gVHJhbnNsYXRlcyBub24tc2VyaWFsaXphYmxlIHZhbHVlcyAoYHVuZGVmaW5lZGAvYE5hTmAvZnVuY3Rpb25zKSB0byBzZXJpYWxpemFibGUgZm9ybWF0CiAqIC0gVHJhbnNsYXRlcyBrbm93biBnbG9iYWwgb2JqZWN0cy9jbGFzc2VzIHRvIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9ucwogKiAtIFRha2VzIGNhcmUgb2YgYEVycm9yYCBvYmplY3Qgc2VyaWFsaXphdGlvbgogKiAtIE9wdGlvbmFsbHkgbGltaXRzIGRlcHRoIG9mIGZpbmFsIG91dHB1dAogKiAtIE9wdGlvbmFsbHkgbGltaXRzIG51bWJlciBvZiBwcm9wZXJ0aWVzL2VsZW1lbnRzIGluY2x1ZGVkIGluIGFueSBzaW5nbGUgb2JqZWN0L2FycmF5CiAqCiAqIEBwYXJhbSBpbnB1dCBUaGUgb2JqZWN0IHRvIGJlIG5vcm1hbGl6ZWQuCiAqIEBwYXJhbSBkZXB0aCBUaGUgbWF4IGRlcHRoIHRvIHdoaWNoIHRvIG5vcm1hbGl6ZSB0aGUgb2JqZWN0LiAoQW55dGhpbmcgZGVlcGVyIHN0cmluZ2lmaWVkIHdob2xlLikKICogQHBhcmFtIG1heFByb3BlcnRpZXMgVGhlIG1heCBudW1iZXIgb2YgZWxlbWVudHMgb3IgcHJvcGVydGllcyB0byBiZSBpbmNsdWRlZCBpbiBhbnkgc2luZ2xlIGFycmF5IG9yCiAqIG9iamVjdCBpbiB0aGUgbm9ybWFsbGl6ZWQgb3V0cHV0LgogKiBAcmV0dXJucyBBIG5vcm1hbGl6ZWQgdmVyc2lvbiBvZiB0aGUgb2JqZWN0LCBvciBgIioqbm9uLXNlcmlhbGl6YWJsZSoqImAgaWYgYW55IGVycm9ycyBhcmUgdGhyb3duIGR1cmluZyBub3JtYWxpemF0aW9uLgogKi8KLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkKZnVuY3Rpb24gbm9ybWFsaXplKGlucHV0LCBkZXB0aCA9IDEwMCwgbWF4UHJvcGVydGllcyA9ICtJbmZpbml0eSkgewogIHRyeSB7CiAgICAvLyBzaW5jZSB3ZSdyZSBhdCB0aGUgb3V0ZXJtb3N0IGxldmVsLCB3ZSBkb24ndCBwcm92aWRlIGEga2V5CiAgICByZXR1cm4gdmlzaXQoJycsIGlucHV0LCBkZXB0aCwgbWF4UHJvcGVydGllcyk7CiAgfSBjYXRjaCAoZXJyKSB7CiAgICByZXR1cm4geyBFUlJPUjogYCoqbm9uLXNlcmlhbGl6YWJsZSoqICgke2Vycn0pYCB9OwogIH0KfQoKLyoqCiAqIFZpc2l0cyBhIG5vZGUgdG8gcGVyZm9ybSBub3JtYWxpemF0aW9uIG9uIGl0CiAqCiAqIEBwYXJhbSBrZXkgVGhlIGtleSBjb3JyZXNwb25kaW5nIHRvIHRoZSBnaXZlbiBub2RlCiAqIEBwYXJhbSB2YWx1ZSBUaGUgbm9kZSB0byBiZSB2aXNpdGVkCiAqIEBwYXJhbSBkZXB0aCBPcHRpb25hbCBudW1iZXIgaW5kaWNhdGluZyB0aGUgbWF4aW11bSByZWN1cnNpb24gZGVwdGgKICogQHBhcmFtIG1heFByb3BlcnRpZXMgT3B0aW9uYWwgbWF4aW11bSBudW1iZXIgb2YgcHJvcGVydGllcy9lbGVtZW50cyBpbmNsdWRlZCBpbiBhbnkgc2luZ2xlIG9iamVjdC9hcnJheQogKiBAcGFyYW0gbWVtbyBPcHRpb25hbCBNZW1vIGNsYXNzIGhhbmRsaW5nIGRlY3ljbGluZwogKi8KZnVuY3Rpb24gdmlzaXQoCiAga2V5LAogIHZhbHVlLAogIGRlcHRoID0gK0luZmluaXR5LAogIG1heFByb3BlcnRpZXMgPSArSW5maW5pdHksCiAgbWVtbyA9IG1lbW9CdWlsZGVyKCksCikgewogIGNvbnN0IFttZW1vaXplLCB1bm1lbW9pemVdID0gbWVtbzsKCiAgLy8gR2V0IHRoZSBzaW1wbGUgY2FzZXMgb3V0IG9mIHRoZSB3YXkgZmlyc3QKICBpZiAoCiAgICB2YWx1ZSA9PSBudWxsIHx8IC8vIHRoaXMgbWF0Y2hlcyBudWxsIGFuZCB1bmRlZmluZWQgLT4gZXFlcSBub3QgZXFlcWVxCiAgICAoWydudW1iZXInLCAnYm9vbGVhbicsICdzdHJpbmcnXS5pbmNsdWRlcyh0eXBlb2YgdmFsdWUpICYmICFpc05hTiQxKHZhbHVlKSkKICApIHsKICAgIHJldHVybiB2YWx1ZSA7CiAgfQoKICBjb25zdCBzdHJpbmdpZmllZCA9IHN0cmluZ2lmeVZhbHVlKGtleSwgdmFsdWUpOwoKICAvLyBBbnl0aGluZyB3ZSBjb3VsZCBwb3RlbnRpYWxseSBkaWcgaW50byBtb3JlIChvYmplY3RzIG9yIGFycmF5cykgd2lsbCBoYXZlIGNvbWUgYmFjayBhcyBgIltvYmplY3QgWFhYWF0iYC4KICAvLyBFdmVyeXRoaW5nIGVsc2Ugd2lsbCBoYXZlIGFscmVhZHkgYmVlbiBzZXJpYWxpemVkLCBzbyBpZiB3ZSBkb24ndCBzZWUgdGhhdCBwYXR0ZXJuLCB3ZSdyZSBkb25lLgogIGlmICghc3RyaW5naWZpZWQuc3RhcnRzV2l0aCgnW29iamVjdCAnKSkgewogICAgcmV0dXJuIHN0cmluZ2lmaWVkOwogIH0KCiAgLy8gRnJvbSBoZXJlIG9uLCB3ZSBjYW4gYXNzZXJ0IHRoYXQgYHZhbHVlYCBpcyBlaXRoZXIgYW4gb2JqZWN0IG9yIGFuIGFycmF5LgoKICAvLyBEbyBub3Qgbm9ybWFsaXplIG9iamVjdHMgdGhhdCB3ZSBrbm93IGhhdmUgYWxyZWFkeSBiZWVuIG5vcm1hbGl6ZWQuIEFzIGEgZ2VuZXJhbCBydWxlLCB0aGUKICAvLyAiX19zZW50cnlfc2tpcF9ub3JtYWxpemF0aW9uX18iIHByb3BlcnR5IHNob3VsZCBvbmx5IGJlIHVzZWQgc3BhcmluZ2x5IGFuZCBvbmx5IHNob3VsZCBvbmx5IGJlIHNldCBvbiBvYmplY3RzIHRoYXQKICAvLyBoYXZlIGFscmVhZHkgYmVlbiBub3JtYWxpemVkLgogIGlmICgodmFsdWUgKVsnX19zZW50cnlfc2tpcF9ub3JtYWxpemF0aW9uX18nXSkgewogICAgcmV0dXJuIHZhbHVlIDsKICB9CgogIC8vIFdlIGNhbiBzZXQgYF9fc2VudHJ5X292ZXJyaWRlX25vcm1hbGl6YXRpb25fZGVwdGhfX2Agb24gYW4gb2JqZWN0IHRvIGVuc3VyZSB0aGF0IGZyb20gdGhlcmUKICAvLyBXZSBrZWVwIGEgY2VydGFpbiBhbW91bnQgb2YgZGVwdGguCiAgLy8gVGhpcyBzaG91bGQgYmUgdXNlZCBzcGFyaW5nbHksIGUuZy4gd2UgdXNlIGl0IGZvciB0aGUgcmVkdXggaW50ZWdyYXRpb24gdG8gZW5zdXJlIHdlIGdldCBhIGNlcnRhaW4gYW1vdW50IG9mIHN0YXRlLgogIGNvbnN0IHJlbWFpbmluZ0RlcHRoID0KICAgIHR5cGVvZiAodmFsdWUgKVsnX19zZW50cnlfb3ZlcnJpZGVfbm9ybWFsaXphdGlvbl9kZXB0aF9fJ10gPT09ICdudW1iZXInCiAgICAgID8gKCh2YWx1ZSApWydfX3NlbnRyeV9vdmVycmlkZV9ub3JtYWxpemF0aW9uX2RlcHRoX18nXSApCiAgICAgIDogZGVwdGg7CgogIC8vIFdlJ3JlIGFsc28gZG9uZSBpZiB3ZSd2ZSByZWFjaGVkIHRoZSBtYXggZGVwdGgKICBpZiAocmVtYWluaW5nRGVwdGggPT09IDApIHsKICAgIC8vIEF0IHRoaXMgcG9pbnQgd2Uga25vdyBgc2VyaWFsaXplZGAgaXMgYSBzdHJpbmcgb2YgdGhlIGZvcm0gYCJbb2JqZWN0IFhYWFhdImAuIENsZWFuIGl0IHVwIHNvIGl0J3MganVzdCBgIltYWFhYXSJgLgogICAgcmV0dXJuIHN0cmluZ2lmaWVkLnJlcGxhY2UoJ29iamVjdCAnLCAnJyk7CiAgfQoKICAvLyBJZiB3ZSd2ZSBhbHJlYWR5IHZpc2l0ZWQgdGhpcyBicmFuY2gsIGJhaWwgb3V0LCBhcyBpdCdzIGNpcmN1bGFyIHJlZmVyZW5jZS4gSWYgbm90LCBub3RlIHRoYXQgd2UncmUgc2VlaW5nIGl0IG5vdy4KICBpZiAobWVtb2l6ZSh2YWx1ZSkpIHsKICAgIHJldHVybiAnW0NpcmN1bGFyIH5dJzsKICB9CgogIC8vIElmIHRoZSB2YWx1ZSBoYXMgYSBgdG9KU09OYCBtZXRob2QsIHdlIGNhbGwgaXQgdG8gZXh0cmFjdCBtb3JlIGluZm9ybWF0aW9uCiAgY29uc3QgdmFsdWVXaXRoVG9KU09OID0gdmFsdWUgOwogIGlmICh2YWx1ZVdpdGhUb0pTT04gJiYgdHlwZW9mIHZhbHVlV2l0aFRvSlNPTi50b0pTT04gPT09ICdmdW5jdGlvbicpIHsKICAgIHRyeSB7CiAgICAgIGNvbnN0IGpzb25WYWx1ZSA9IHZhbHVlV2l0aFRvSlNPTi50b0pTT04oKTsKICAgICAgLy8gV2UgbmVlZCB0byBub3JtYWxpemUgdGhlIHJldHVybiB2YWx1ZSBvZiBgLnRvSlNPTigpYCBpbiBjYXNlIGl0IGhhcyBjaXJjdWxhciByZWZlcmVuY2VzCiAgICAgIHJldHVybiB2aXNpdCgnJywganNvblZhbHVlLCByZW1haW5pbmdEZXB0aCAtIDEsIG1heFByb3BlcnRpZXMsIG1lbW8pOwogICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgIC8vIHBhc3MgKFRoZSBidWlsdC1pbiBgdG9KU09OYCBmYWlsZWQsIGJ1dCB3ZSBjYW4gc3RpbGwgdHJ5IHRvIGRvIGl0IG91cnNlbHZlcykKICAgIH0KICB9CgogIC8vIEF0IHRoaXMgcG9pbnQgd2Uga25vdyB3ZSBlaXRoZXIgaGF2ZSBhbiBvYmplY3Qgb3IgYW4gYXJyYXksIHdlIGhhdmVuJ3Qgc2VlbiBpdCBiZWZvcmUsIGFuZCB3ZSdyZSBnb2luZyB0byByZWN1cnNlCiAgLy8gYmVjYXVzZSB3ZSBoYXZlbid0IHlldCByZWFjaGVkIHRoZSBtYXggZGVwdGguIENyZWF0ZSBhbiBhY2N1bXVsYXRvciB0byBob2xkIHRoZSByZXN1bHRzIG9mIHZpc2l0aW5nIGVhY2gKICAvLyBwcm9wZXJ0eS9lbnRyeSwgYW5kIGtlZXAgdHJhY2sgb2YgdGhlIG51bWJlciBvZiBpdGVtcyB3ZSBhZGQgdG8gaXQuCiAgY29uc3Qgbm9ybWFsaXplZCA9IChBcnJheS5pc0FycmF5KHZhbHVlKSA/IFtdIDoge30pIDsKICBsZXQgbnVtQWRkZWQgPSAwOwoKICAvLyBCZWZvcmUgd2UgYmVnaW4sIGNvbnZlcnRgRXJyb3JgIGFuZGBFdmVudGAgaW5zdGFuY2VzIGludG8gcGxhaW4gb2JqZWN0cywgc2luY2Ugc29tZSBvZiBlYWNoIG9mIHRoZWlyIHJlbGV2YW50CiAgLy8gcHJvcGVydGllcyBhcmUgbm9uLWVudW1lcmFibGUgYW5kIG90aGVyd2lzZSB3b3VsZCBnZXQgbWlzc2VkLgogIGNvbnN0IHZpc2l0YWJsZSA9IGNvbnZlcnRUb1BsYWluT2JqZWN0KHZhbHVlICk7CgogIGZvciAoY29uc3QgdmlzaXRLZXkgaW4gdmlzaXRhYmxlKSB7CiAgICAvLyBBdm9pZCBpdGVyYXRpbmcgb3ZlciBmaWVsZHMgaW4gdGhlIHByb3RvdHlwZSBpZiB0aGV5J3ZlIHNvbWVob3cgYmVlbiBleHBvc2VkIHRvIGVudW1lcmF0aW9uLgogICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodmlzaXRhYmxlLCB2aXNpdEtleSkpIHsKICAgICAgY29udGludWU7CiAgICB9CgogICAgaWYgKG51bUFkZGVkID49IG1heFByb3BlcnRpZXMpIHsKICAgICAgbm9ybWFsaXplZFt2aXNpdEtleV0gPSAnW01heFByb3BlcnRpZXMgfl0nOwogICAgICBicmVhazsKICAgIH0KCiAgICAvLyBSZWN1cnNpdmVseSB2aXNpdCBhbGwgdGhlIGNoaWxkIG5vZGVzCiAgICBjb25zdCB2aXNpdFZhbHVlID0gdmlzaXRhYmxlW3Zpc2l0S2V5XTsKICAgIG5vcm1hbGl6ZWRbdmlzaXRLZXldID0gdmlzaXQodmlzaXRLZXksIHZpc2l0VmFsdWUsIHJlbWFpbmluZ0RlcHRoIC0gMSwgbWF4UHJvcGVydGllcywgbWVtbyk7CgogICAgbnVtQWRkZWQrKzsKICB9CgogIC8vIE9uY2Ugd2UndmUgdmlzaXRlZCBhbGwgdGhlIGJyYW5jaGVzLCByZW1vdmUgdGhlIHBhcmVudCBmcm9tIG1lbW8gc3RvcmFnZQogIHVubWVtb2l6ZSh2YWx1ZSk7CgogIC8vIFJldHVybiBhY2N1bXVsYXRlZCB2YWx1ZXMKICByZXR1cm4gbm9ybWFsaXplZDsKfQoKLyogZXNsaW50LWRpc2FibGUgY29tcGxleGl0eSAqLwovKioKICogU3RyaW5naWZ5IHRoZSBnaXZlbiB2YWx1ZS4gSGFuZGxlcyB2YXJpb3VzIGtub3duIHNwZWNpYWwgdmFsdWVzIGFuZCB0eXBlcy4KICoKICogTm90IG1lYW50IHRvIGJlIHVzZWQgb24gc2ltcGxlIHByaW1pdGl2ZXMgd2hpY2ggYWxyZWFkeSBoYXZlIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uLCBhcyBpdCB3aWxsLCBmb3IgZXhhbXBsZSwgdHVybgogKiB0aGUgbnVtYmVyIDEyMzEgaW50byAiW09iamVjdCBOdW1iZXJdIiwgbm9yIG9uIGBudWxsYCwgYXMgaXQgd2lsbCB0aHJvdy4KICoKICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSB0byBzdHJpbmdpZnkKICogQHJldHVybnMgQSBzdHJpbmdpZmllZCByZXByZXNlbnRhdGlvbiBvZiB0aGUgZ2l2ZW4gdmFsdWUKICovCmZ1bmN0aW9uIHN0cmluZ2lmeVZhbHVlKAogIGtleSwKICAvLyB0aGlzIHR5cGUgaXMgYSB0aW55IGJpdCBvZiBhIGNoZWF0LCBzaW5jZSB0aGlzIGZ1bmN0aW9uIGRvZXMgaGFuZGxlIE5hTiAod2hpY2ggaXMgdGVjaG5pY2FsbHkgYSBudW1iZXIpLCBidXQgZm9yCiAgLy8gb3VyIGludGVybmFsIHVzZSwgaXQnbGwgZG8KICB2YWx1ZSwKKSB7CiAgdHJ5IHsKICAgIGlmIChrZXkgPT09ICdkb21haW4nICYmIHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgKHZhbHVlICkuX2V2ZW50cykgewogICAgICByZXR1cm4gJ1tEb21haW5dJzsKICAgIH0KCiAgICBpZiAoa2V5ID09PSAnZG9tYWluRW1pdHRlcicpIHsKICAgICAgcmV0dXJuICdbRG9tYWluRW1pdHRlcl0nOwogICAgfQoKICAgIC8vIEl0J3Mgc2FmZSB0byB1c2UgYGdsb2JhbGAsIGB3aW5kb3dgLCBhbmQgYGRvY3VtZW50YCBoZXJlIGluIHRoaXMgbWFubmVyLCBhcyB3ZSBhcmUgYXNzZXJ0aW5nIHVzaW5nIGB0eXBlb2ZgIGZpcnN0CiAgICAvLyB3aGljaCB3b24ndCB0aHJvdyBpZiB0aGV5IGFyZSBub3QgcHJlc2VudC4KCiAgICBpZiAodHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcgJiYgdmFsdWUgPT09IGdsb2JhbCkgewogICAgICByZXR1cm4gJ1tHbG9iYWxdJzsKICAgIH0KCiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1nbG9iYWxzCiAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgdmFsdWUgPT09IHdpbmRvdykgewogICAgICByZXR1cm4gJ1tXaW5kb3ddJzsKICAgIH0KCiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1nbG9iYWxzCiAgICBpZiAodHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyAmJiB2YWx1ZSA9PT0gZG9jdW1lbnQpIHsKICAgICAgcmV0dXJuICdbRG9jdW1lbnRdJzsKICAgIH0KCiAgICBpZiAoaXNWdWVWaWV3TW9kZWwodmFsdWUpKSB7CiAgICAgIHJldHVybiAnW1Z1ZVZpZXdNb2RlbF0nOwogICAgfQoKICAgIC8vIFJlYWN0J3MgU3ludGhldGljRXZlbnQgdGhpbmd5CiAgICBpZiAoaXNTeW50aGV0aWNFdmVudCh2YWx1ZSkpIHsKICAgICAgcmV0dXJuICdbU3ludGhldGljRXZlbnRdJzsKICAgIH0KCiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyAmJiB2YWx1ZSAhPT0gdmFsdWUpIHsKICAgICAgcmV0dXJuICdbTmFOXSc7CiAgICB9CgogICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykgewogICAgICByZXR1cm4gYFtGdW5jdGlvbjogJHtnZXRGdW5jdGlvbk5hbWUodmFsdWUpfV1gOwogICAgfQoKICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzeW1ib2wnKSB7CiAgICAgIHJldHVybiBgWyR7U3RyaW5nKHZhbHVlKX1dYDsKICAgIH0KCiAgICAvLyBzdHJpbmdpZmllZCBCaWdJbnRzIGFyZSBpbmRpc3Rpbmd1aXNoYWJsZSBmcm9tIHJlZ3VsYXIgbnVtYmVycywgc28gd2UgbmVlZCB0byBsYWJlbCB0aGVtIHRvIGF2b2lkIGNvbmZ1c2lvbgogICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2JpZ2ludCcpIHsKICAgICAgcmV0dXJuIGBbQmlnSW50OiAke1N0cmluZyh2YWx1ZSl9XWA7CiAgICB9CgogICAgLy8gTm93IHRoYXQgd2UndmUga25vY2tlZCBvdXQgYWxsIHRoZSBzcGVjaWFsIGNhc2VzIGFuZCB0aGUgcHJpbWl0aXZlcywgYWxsIHdlIGhhdmUgbGVmdCBhcmUgb2JqZWN0cy4gU2ltcGx5IGNhc3RpbmcKICAgIC8vIHRoZW0gdG8gc3RyaW5ncyBtZWFucyB0aGF0IGluc3RhbmNlcyBvZiBjbGFzc2VzIHdoaWNoIGhhdmVuJ3QgZGVmaW5lZCB0aGVpciBgdG9TdHJpbmdUYWdgIHdpbGwganVzdCBjb21lIG91dCBhcwogICAgLy8gYCJbb2JqZWN0IE9iamVjdF0iYC4gSWYgd2UgaW5zdGVhZCBsb29rIGF0IHRoZSBjb25zdHJ1Y3RvcidzIG5hbWUgKHdoaWNoIGlzIHRoZSBzYW1lIGFzIHRoZSBuYW1lIG9mIHRoZSBjbGFzcyksCiAgICAvLyB3ZSBjYW4gbWFrZSBzdXJlIHRoYXQgb25seSBwbGFpbiBvYmplY3RzIGNvbWUgb3V0IHRoYXQgd2F5LgogICAgY29uc3Qgb2JqTmFtZSA9IGdldENvbnN0cnVjdG9yTmFtZSh2YWx1ZSk7CgogICAgLy8gSGFuZGxlIEhUTUwgRWxlbWVudHMKICAgIGlmICgvXkhUTUwoXHcqKUVsZW1lbnQkLy50ZXN0KG9iak5hbWUpKSB7CiAgICAgIHJldHVybiBgW0hUTUxFbGVtZW50OiAke29iak5hbWV9XWA7CiAgICB9CgogICAgcmV0dXJuIGBbb2JqZWN0ICR7b2JqTmFtZX1dYDsKICB9IGNhdGNoIChlcnIpIHsKICAgIHJldHVybiBgKipub24tc2VyaWFsaXphYmxlKiogKCR7ZXJyfSlgOwogIH0KfQovKiBlc2xpbnQtZW5hYmxlIGNvbXBsZXhpdHkgKi8KCmZ1bmN0aW9uIGdldENvbnN0cnVjdG9yTmFtZSh2YWx1ZSkgewogIGNvbnN0IHByb3RvdHlwZSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZih2YWx1ZSk7CgogIHJldHVybiBwcm90b3R5cGUgPyBwcm90b3R5cGUuY29uc3RydWN0b3IubmFtZSA6ICdudWxsIHByb3RvdHlwZSc7Cn0KCi8qKgogKiBOb3JtYWxpemVzIFVSTHMgaW4gZXhjZXB0aW9ucyBhbmQgc3RhY2t0cmFjZXMgdG8gYSBiYXNlIHBhdGggc28gU2VudHJ5IGNhbiBmaW5nZXJwcmludAogKiBhY3Jvc3MgcGxhdGZvcm1zIGFuZCB3b3JraW5nIGRpcmVjdG9yeS4KICoKICogQHBhcmFtIHVybCBUaGUgVVJMIHRvIGJlIG5vcm1hbGl6ZWQuCiAqIEBwYXJhbSBiYXNlUGF0aCBUaGUgYXBwbGljYXRpb24gYmFzZSBwYXRoLgogKiBAcmV0dXJucyBUaGUgbm9ybWFsaXplZCBVUkwuCiAqLwpmdW5jdGlvbiBub3JtYWxpemVVcmxUb0Jhc2UodXJsLCBiYXNlUGF0aCkgewogIGNvbnN0IGVzY2FwZWRCYXNlID0gYmFzZVBhdGgKICAgIC8vIEJhY2tzbGFzaCB0byBmb3J3YXJkCiAgICAucmVwbGFjZSgvXFwvZywgJy8nKQogICAgLy8gRXNjYXBlIFJlZ0V4cCBzcGVjaWFsIGNoYXJhY3RlcnMKICAgIC5yZXBsYWNlKC9bfFxce30oKVtcXV4kKyo/Ll0vZywgJ1xcJCYnKTsKCiAgbGV0IG5ld1VybCA9IHVybDsKICB0cnkgewogICAgbmV3VXJsID0gZGVjb2RlVVJJKHVybCk7CiAgfSBjYXRjaCAoX09vKSB7CiAgICAvLyBTb21ldGltZSB0aGlzIGJyZWFrcwogIH0KICByZXR1cm4gKAogICAgbmV3VXJsCiAgICAgIC5yZXBsYWNlKC9cXC9nLCAnLycpCiAgICAgIC5yZXBsYWNlKC93ZWJwYWNrOlwvPy9nLCAnJykgLy8gUmVtb3ZlIGludGVybWVkaWF0ZSBiYXNlIHBhdGgKICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBzZW50cnktaW50ZXJuYWwvc2RrL25vLXJlZ2V4cC1jb25zdHJ1Y3RvcgogICAgICAucmVwbGFjZShuZXcgUmVnRXhwKGAoZmlsZTovLyk/Lyoke2VzY2FwZWRCYXNlfS8qYCwgJ2lnJyksICdhcHA6Ly8vJykKICApOwp9CgovLyBTbGlnaHRseSBtb2RpZmllZCAobm8gSUU4IHN1cHBvcnQsIEVTNikgYW5kIHRyYW5zY3JpYmVkIHRvIFR5cGVTY3JpcHQKCi8vIFNwbGl0IGEgZmlsZW5hbWUgaW50byBbcm9vdCwgZGlyLCBiYXNlbmFtZSwgZXh0XSwgdW5peCB2ZXJzaW9uCi8vICdyb290JyBpcyBqdXN0IGEgc2xhc2gsIG9yIG5vdGhpbmcuCmNvbnN0IHNwbGl0UGF0aFJlID0gL14oXFMrOlxcfFwvPykoW1xzXFNdKj8pKCg/OlwuezEsMn18W14vXFxdKz98KShcLlteLi9cXF0qfCkpKD86Wy9cXF0qKSQvOwovKiogSlNEb2MgKi8KZnVuY3Rpb24gc3BsaXRQYXRoKGZpbGVuYW1lKSB7CiAgLy8gVHJ1bmNhdGUgZmlsZXMgbmFtZXMgZ3JlYXRlciB0aGFuIDEwMjQgY2hhcmFjdGVycyB0byBhdm9pZCByZWdleCBkb3MKICAvLyBodHRwczovL2dpdGh1Yi5jb20vZ2V0c2VudHJ5L3NlbnRyeS1qYXZhc2NyaXB0L3B1bGwvODczNyNkaXNjdXNzaW9uX3IxMjg1NzE5MTcyCiAgY29uc3QgdHJ1bmNhdGVkID0gZmlsZW5hbWUubGVuZ3RoID4gMTAyNCA/IGA8dHJ1bmNhdGVkPiR7ZmlsZW5hbWUuc2xpY2UoLTEwMjQpfWAgOiBmaWxlbmFtZTsKICBjb25zdCBwYXJ0cyA9IHNwbGl0UGF0aFJlLmV4ZWModHJ1bmNhdGVkKTsKICByZXR1cm4gcGFydHMgPyBwYXJ0cy5zbGljZSgxKSA6IFtdOwp9CgovKiogSlNEb2MgKi8KZnVuY3Rpb24gZGlybmFtZShwYXRoKSB7CiAgY29uc3QgcmVzdWx0ID0gc3BsaXRQYXRoKHBhdGgpOwogIGNvbnN0IHJvb3QgPSByZXN1bHRbMF07CiAgbGV0IGRpciA9IHJlc3VsdFsxXTsKCiAgaWYgKCFyb290ICYmICFkaXIpIHsKICAgIC8vIE5vIGRpcm5hbWUgd2hhdHNvZXZlcgogICAgcmV0dXJuICcuJzsKICB9CgogIGlmIChkaXIpIHsKICAgIC8vIEl0IGhhcyBhIGRpcm5hbWUsIHN0cmlwIHRyYWlsaW5nIHNsYXNoCiAgICBkaXIgPSBkaXIuc2xpY2UoMCwgZGlyLmxlbmd0aCAtIDEpOwogIH0KCiAgcmV0dXJuIHJvb3QgKyBkaXI7Cn0KCi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9leHBsaWNpdC1mdW5jdGlvbi1yZXR1cm4tdHlwZSAqLwoKLyoqIFN5bmNQcm9taXNlIGludGVybmFsIHN0YXRlcyAqLwp2YXIgU3RhdGVzOyAoZnVuY3Rpb24gKFN0YXRlcykgewogIC8qKiBQZW5kaW5nICovCiAgY29uc3QgUEVORElORyA9IDA7IFN0YXRlc1tTdGF0ZXNbIlBFTkRJTkciXSA9IFBFTkRJTkddID0gIlBFTkRJTkciOwogIC8qKiBSZXNvbHZlZCAvIE9LICovCiAgY29uc3QgUkVTT0xWRUQgPSAxOyBTdGF0ZXNbU3RhdGVzWyJSRVNPTFZFRCJdID0gUkVTT0xWRURdID0gIlJFU09MVkVEIjsKICAvKiogUmVqZWN0ZWQgLyBFcnJvciAqLwogIGNvbnN0IFJFSkVDVEVEID0gMjsgU3RhdGVzW1N0YXRlc1siUkVKRUNURUQiXSA9IFJFSkVDVEVEXSA9ICJSRUpFQ1RFRCI7Cn0pKFN0YXRlcyB8fCAoU3RhdGVzID0ge30pKTsKCi8vIE92ZXJsb2FkcyBzbyB3ZSBjYW4gY2FsbCByZXNvbHZlZFN5bmNQcm9taXNlIHdpdGhvdXQgYXJndW1lbnRzIGFuZCBnZW5lcmljIGFyZ3VtZW50CgovKioKICogQ3JlYXRlcyBhIHJlc29sdmVkIHN5bmMgcHJvbWlzZS4KICoKICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSB0byByZXNvbHZlIHRoZSBwcm9taXNlIHdpdGgKICogQHJldHVybnMgdGhlIHJlc29sdmVkIHN5bmMgcHJvbWlzZQogKi8KZnVuY3Rpb24gcmVzb2x2ZWRTeW5jUHJvbWlzZSh2YWx1ZSkgewogIHJldHVybiBuZXcgU3luY1Byb21pc2UocmVzb2x2ZSA9PiB7CiAgICByZXNvbHZlKHZhbHVlKTsKICB9KTsKfQoKLyoqCiAqIENyZWF0ZXMgYSByZWplY3RlZCBzeW5jIHByb21pc2UuCiAqCiAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgdG8gcmVqZWN0IHRoZSBwcm9taXNlIHdpdGgKICogQHJldHVybnMgdGhlIHJlamVjdGVkIHN5bmMgcHJvbWlzZQogKi8KZnVuY3Rpb24gcmVqZWN0ZWRTeW5jUHJvbWlzZShyZWFzb24pIHsKICByZXR1cm4gbmV3IFN5bmNQcm9taXNlKChfLCByZWplY3QpID0+IHsKICAgIHJlamVjdChyZWFzb24pOwogIH0pOwp9CgovKioKICogVGhlbmFibGUgY2xhc3MgdGhhdCBiZWhhdmVzIGxpa2UgYSBQcm9taXNlIGFuZCBmb2xsb3dzIGl0J3MgaW50ZXJmYWNlCiAqIGJ1dCBpcyBub3QgYXN5bmMgaW50ZXJuYWxseQogKi8KY2xhc3MgU3luY1Byb21pc2UgewoKICAgY29uc3RydWN0b3IoCiAgICBleGVjdXRvciwKICApIHtTeW5jUHJvbWlzZS5wcm90b3R5cGUuX19pbml0LmNhbGwodGhpcyk7U3luY1Byb21pc2UucHJvdG90eXBlLl9faW5pdDIuY2FsbCh0aGlzKTtTeW5jUHJvbWlzZS5wcm90b3R5cGUuX19pbml0My5jYWxsKHRoaXMpO1N5bmNQcm9taXNlLnByb3RvdHlwZS5fX2luaXQ0LmNhbGwodGhpcyk7CiAgICB0aGlzLl9zdGF0ZSA9IFN0YXRlcy5QRU5ESU5HOwogICAgdGhpcy5faGFuZGxlcnMgPSBbXTsKCiAgICB0cnkgewogICAgICBleGVjdXRvcih0aGlzLl9yZXNvbHZlLCB0aGlzLl9yZWplY3QpOwogICAgfSBjYXRjaCAoZSkgewogICAgICB0aGlzLl9yZWplY3QoZSk7CiAgICB9CiAgfQoKICAvKiogSlNEb2MgKi8KICAgdGhlbigKICAgIG9uZnVsZmlsbGVkLAogICAgb25yZWplY3RlZCwKICApIHsKICAgIHJldHVybiBuZXcgU3luY1Byb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4gewogICAgICB0aGlzLl9oYW5kbGVycy5wdXNoKFsKICAgICAgICBmYWxzZSwKICAgICAgICByZXN1bHQgPT4gewogICAgICAgICAgaWYgKCFvbmZ1bGZpbGxlZCkgewogICAgICAgICAgICAvLyBUT0RPOiDCr1xfKOODhClfL8KvCiAgICAgICAgICAgIC8vIFRPRE86IEZJWE1FCiAgICAgICAgICAgIHJlc29sdmUocmVzdWx0ICk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgIHJlc29sdmUob25mdWxmaWxsZWQocmVzdWx0KSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICByZWplY3QoZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHJlYXNvbiA9PiB7CiAgICAgICAgICBpZiAoIW9ucmVqZWN0ZWQpIHsKICAgICAgICAgICAgcmVqZWN0KHJlYXNvbik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgIHJlc29sdmUob25yZWplY3RlZChyZWFzb24pKTsKICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgIHJlamVjdChlKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgIF0pOwogICAgICB0aGlzLl9leGVjdXRlSGFuZGxlcnMoKTsKICAgIH0pOwogIH0KCiAgLyoqIEpTRG9jICovCiAgIGNhdGNoKAogICAgb25yZWplY3RlZCwKICApIHsKICAgIHJldHVybiB0aGlzLnRoZW4odmFsID0+IHZhbCwgb25yZWplY3RlZCk7CiAgfQoKICAvKiogSlNEb2MgKi8KICAgZmluYWxseShvbmZpbmFsbHkpIHsKICAgIHJldHVybiBuZXcgU3luY1Byb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4gewogICAgICBsZXQgdmFsOwogICAgICBsZXQgaXNSZWplY3RlZDsKCiAgICAgIHJldHVybiB0aGlzLnRoZW4oCiAgICAgICAgdmFsdWUgPT4gewogICAgICAgICAgaXNSZWplY3RlZCA9IGZhbHNlOwogICAgICAgICAgdmFsID0gdmFsdWU7CiAgICAgICAgICBpZiAob25maW5hbGx5KSB7CiAgICAgICAgICAgIG9uZmluYWxseSgpOwogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcmVhc29uID0+IHsKICAgICAgICAgIGlzUmVqZWN0ZWQgPSB0cnVlOwogICAgICAgICAgdmFsID0gcmVhc29uOwogICAgICAgICAgaWYgKG9uZmluYWxseSkgewogICAgICAgICAgICBvbmZpbmFsbHkoKTsKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICApLnRoZW4oKCkgPT4gewogICAgICAgIGlmIChpc1JlamVjdGVkKSB7CiAgICAgICAgICByZWplY3QodmFsKTsKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHJlc29sdmUodmFsICk7CiAgICAgIH0pOwogICAgfSk7CiAgfQoKICAvKiogSlNEb2MgKi8KICAgIF9faW5pdCgpIHt0aGlzLl9yZXNvbHZlID0gKHZhbHVlKSA9PiB7CiAgICB0aGlzLl9zZXRSZXN1bHQoU3RhdGVzLlJFU09MVkVELCB2YWx1ZSk7CiAgfTt9CgogIC8qKiBKU0RvYyAqLwogICAgX19pbml0MigpIHt0aGlzLl9yZWplY3QgPSAocmVhc29uKSA9PiB7CiAgICB0aGlzLl9zZXRSZXN1bHQoU3RhdGVzLlJFSkVDVEVELCByZWFzb24pOwogIH07fQoKICAvKiogSlNEb2MgKi8KICAgIF9faW5pdDMoKSB7dGhpcy5fc2V0UmVzdWx0ID0gKHN0YXRlLCB2YWx1ZSkgPT4gewogICAgaWYgKHRoaXMuX3N0YXRlICE9PSBTdGF0ZXMuUEVORElORykgewogICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKGlzVGhlbmFibGUodmFsdWUpKSB7CiAgICAgIHZvaWQgKHZhbHVlICkudGhlbih0aGlzLl9yZXNvbHZlLCB0aGlzLl9yZWplY3QpOwogICAgICByZXR1cm47CiAgICB9CgogICAgdGhpcy5fc3RhdGUgPSBzdGF0ZTsKICAgIHRoaXMuX3ZhbHVlID0gdmFsdWU7CgogICAgdGhpcy5fZXhlY3V0ZUhhbmRsZXJzKCk7CiAgfTt9CgogIC8qKiBKU0RvYyAqLwogICAgX19pbml0NCgpIHt0aGlzLl9leGVjdXRlSGFuZGxlcnMgPSAoKSA9PiB7CiAgICBpZiAodGhpcy5fc3RhdGUgPT09IFN0YXRlcy5QRU5ESU5HKSB7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICBjb25zdCBjYWNoZWRIYW5kbGVycyA9IHRoaXMuX2hhbmRsZXJzLnNsaWNlKCk7CiAgICB0aGlzLl9oYW5kbGVycyA9IFtdOwoKICAgIGNhY2hlZEhhbmRsZXJzLmZvckVhY2goaGFuZGxlciA9PiB7CiAgICAgIGlmIChoYW5kbGVyWzBdKSB7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFN0YXRlcy5SRVNPTFZFRCkgewogICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZmxvYXRpbmctcHJvbWlzZXMKICAgICAgICBoYW5kbGVyWzFdKHRoaXMuX3ZhbHVlICk7CiAgICAgIH0KCiAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gU3RhdGVzLlJFSkVDVEVEKSB7CiAgICAgICAgaGFuZGxlclsyXSh0aGlzLl92YWx1ZSk7CiAgICAgIH0KCiAgICAgIGhhbmRsZXJbMF0gPSB0cnVlOwogICAgfSk7CiAgfTt9Cn0KCi8qKgogKiBDcmVhdGVzIGFuIG5ldyBQcm9taXNlQnVmZmVyIG9iamVjdCB3aXRoIHRoZSBzcGVjaWZpZWQgbGltaXQKICogQHBhcmFtIGxpbWl0IG1heCBudW1iZXIgb2YgcHJvbWlzZXMgdGhhdCBjYW4gYmUgc3RvcmVkIGluIHRoZSBidWZmZXIKICovCmZ1bmN0aW9uIG1ha2VQcm9taXNlQnVmZmVyKGxpbWl0KSB7CiAgY29uc3QgYnVmZmVyID0gW107CgogIGZ1bmN0aW9uIGlzUmVhZHkoKSB7CiAgICByZXR1cm4gbGltaXQgPT09IHVuZGVmaW5lZCB8fCBidWZmZXIubGVuZ3RoIDwgbGltaXQ7CiAgfQoKICAvKioKICAgKiBSZW1vdmUgYSBwcm9taXNlIGZyb20gdGhlIHF1ZXVlLgogICAqCiAgICogQHBhcmFtIHRhc2sgQ2FuIGJlIGFueSBQcm9taXNlTGlrZTxUPgogICAqIEByZXR1cm5zIFJlbW92ZWQgcHJvbWlzZS4KICAgKi8KICBmdW5jdGlvbiByZW1vdmUodGFzaykgewogICAgcmV0dXJuIGJ1ZmZlci5zcGxpY2UoYnVmZmVyLmluZGV4T2YodGFzayksIDEpWzBdOwogIH0KCiAgLyoqCiAgICogQWRkIGEgcHJvbWlzZSAocmVwcmVzZW50aW5nIGFuIGluLWZsaWdodCBhY3Rpb24pIHRvIHRoZSBxdWV1ZSwgYW5kIHNldCBpdCB0byByZW1vdmUgaXRzZWxmIG9uIGZ1bGZpbGxtZW50LgogICAqCiAgICogQHBhcmFtIHRhc2tQcm9kdWNlciBBIGZ1bmN0aW9uIHByb2R1Y2luZyBhbnkgUHJvbWlzZUxpa2U8VD47IEluIHByZXZpb3VzIHZlcnNpb25zIHRoaXMgdXNlZCB0byBiZSBgdGFzazoKICAgKiAgICAgICAgUHJvbWlzZUxpa2U8VD5gLCBidXQgdW5kZXIgdGhhdCBtb2RlbCwgUHJvbWlzZXMgd2VyZSBpbnN0YW50bHkgY3JlYXRlZCBvbiB0aGUgY2FsbC1zaXRlIGFuZCB0aGVpciBleGVjdXRvcgogICAqICAgICAgICBmdW5jdGlvbnMgdGhlcmVmb3JlIHJhbiBpbW1lZGlhdGVseS4gVGh1cywgZXZlbiBpZiB0aGUgYnVmZmVyIHdhcyBmdWxsLCB0aGUgYWN0aW9uIHN0aWxsIGhhcHBlbmVkLiBCeQogICAqICAgICAgICByZXF1aXJpbmcgdGhlIHByb21pc2UgdG8gYmUgd3JhcHBlZCBpbiBhIGZ1bmN0aW9uLCB3ZSBjYW4gZGVmZXIgcHJvbWlzZSBjcmVhdGlvbiB1bnRpbCBhZnRlciB0aGUgYnVmZmVyCiAgICogICAgICAgIGxpbWl0IGNoZWNrLgogICAqIEByZXR1cm5zIFRoZSBvcmlnaW5hbCBwcm9taXNlLgogICAqLwogIGZ1bmN0aW9uIGFkZCh0YXNrUHJvZHVjZXIpIHsKICAgIGlmICghaXNSZWFkeSgpKSB7CiAgICAgIHJldHVybiByZWplY3RlZFN5bmNQcm9taXNlKG5ldyBTZW50cnlFcnJvcignTm90IGFkZGluZyBQcm9taXNlIGJlY2F1c2UgYnVmZmVyIGxpbWl0IHdhcyByZWFjaGVkLicpKTsKICAgIH0KCiAgICAvLyBzdGFydCB0aGUgdGFzayBhbmQgYWRkIGl0cyBwcm9taXNlIHRvIHRoZSBxdWV1ZQogICAgY29uc3QgdGFzayA9IHRhc2tQcm9kdWNlcigpOwogICAgaWYgKGJ1ZmZlci5pbmRleE9mKHRhc2spID09PSAtMSkgewogICAgICBidWZmZXIucHVzaCh0YXNrKTsKICAgIH0KICAgIHZvaWQgdGFzawogICAgICAudGhlbigoKSA9PiByZW1vdmUodGFzaykpCiAgICAgIC8vIFVzZSBgdGhlbihudWxsLCByZWplY3Rpb25IYW5kbGVyKWAgcmF0aGVyIHRoYW4gYGNhdGNoKHJlamVjdGlvbkhhbmRsZXIpYCBzbyB0aGF0IHdlIGNhbiB1c2UgYFByb21pc2VMaWtlYAogICAgICAvLyByYXRoZXIgdGhhbiBgUHJvbWlzZWAuIGBQcm9taXNlTGlrZWAgZG9lc24ndCBoYXZlIGEgYC5jYXRjaGAgbWV0aG9kLCBtYWtpbmcgaXRzIHBvbHlmaWxsIHNtYWxsZXIuIChFUzUgZGlkbid0CiAgICAgIC8vIGhhdmUgcHJvbWlzZXMsIHNvIFRTIGhhcyB0byBwb2x5ZmlsbCB3aGVuIGRvd24tY29tcGlsaW5nLikKICAgICAgLnRoZW4obnVsbCwgKCkgPT4KICAgICAgICByZW1vdmUodGFzaykudGhlbihudWxsLCAoKSA9PiB7CiAgICAgICAgICAvLyBXZSBoYXZlIHRvIGFkZCBhbm90aGVyIGNhdGNoIGhlcmUgYmVjYXVzZSBgcmVtb3ZlKClgIHN0YXJ0cyBhIG5ldyBwcm9taXNlIGNoYWluLgogICAgICAgIH0pLAogICAgICApOwogICAgcmV0dXJuIHRhc2s7CiAgfQoKICAvKioKICAgKiBXYWl0IGZvciBhbGwgcHJvbWlzZXMgaW4gdGhlIHF1ZXVlIHRvIHJlc29sdmUgb3IgZm9yIHRpbWVvdXQgdG8gZXhwaXJlLCB3aGljaGV2ZXIgY29tZXMgZmlyc3QuCiAgICoKICAgKiBAcGFyYW0gdGltZW91dCBUaGUgdGltZSwgaW4gbXMsIGFmdGVyIHdoaWNoIHRvIHJlc29sdmUgdG8gYGZhbHNlYCBpZiB0aGUgcXVldWUgaXMgc3RpbGwgbm9uLWVtcHR5LiBQYXNzaW5nIGAwYCAob3IKICAgKiBub3QgcGFzc2luZyBhbnl0aGluZykgd2lsbCBtYWtlIHRoZSBwcm9taXNlIHdhaXQgYXMgbG9uZyBhcyBpdCB0YWtlcyBmb3IgdGhlIHF1ZXVlIHRvIGRyYWluIGJlZm9yZSByZXNvbHZpbmcgdG8KICAgKiBgdHJ1ZWAuCiAgICogQHJldHVybnMgQSBwcm9taXNlIHdoaWNoIHdpbGwgcmVzb2x2ZSB0byBgdHJ1ZWAgaWYgdGhlIHF1ZXVlIGlzIGFscmVhZHkgZW1wdHkgb3IgZHJhaW5zIGJlZm9yZSB0aGUgdGltZW91dCwgYW5kCiAgICogYGZhbHNlYCBvdGhlcndpc2UKICAgKi8KICBmdW5jdGlvbiBkcmFpbih0aW1lb3V0KSB7CiAgICByZXR1cm4gbmV3IFN5bmNQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHsKICAgICAgbGV0IGNvdW50ZXIgPSBidWZmZXIubGVuZ3RoOwoKICAgICAgaWYgKCFjb3VudGVyKSB7CiAgICAgICAgcmV0dXJuIHJlc29sdmUodHJ1ZSk7CiAgICAgIH0KCiAgICAgIC8vIHdhaXQgZm9yIGB0aW1lb3V0YCBtcyBhbmQgdGhlbiByZXNvbHZlIHRvIGBmYWxzZWAgKGlmIG5vdCBjYW5jZWxsZWQgZmlyc3QpCiAgICAgIGNvbnN0IGNhcHR1cmVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4gewogICAgICAgIGlmICh0aW1lb3V0ICYmIHRpbWVvdXQgPiAwKSB7CiAgICAgICAgICByZXNvbHZlKGZhbHNlKTsKICAgICAgICB9CiAgICAgIH0sIHRpbWVvdXQpOwoKICAgICAgLy8gaWYgYWxsIHByb21pc2VzIHJlc29sdmUgaW4gdGltZSwgY2FuY2VsIHRoZSB0aW1lciBhbmQgcmVzb2x2ZSB0byBgdHJ1ZWAKICAgICAgYnVmZmVyLmZvckVhY2goaXRlbSA9PiB7CiAgICAgICAgdm9pZCByZXNvbHZlZFN5bmNQcm9taXNlKGl0ZW0pLnRoZW4oKCkgPT4gewogICAgICAgICAgaWYgKCEtLWNvdW50ZXIpIHsKICAgICAgICAgICAgY2xlYXJUaW1lb3V0KGNhcHR1cmVkU2V0VGltZW91dCk7CiAgICAgICAgICAgIHJlc29sdmUodHJ1ZSk7CiAgICAgICAgICB9CiAgICAgICAgfSwgcmVqZWN0KTsKICAgICAgfSk7CiAgICB9KTsKICB9CgogIHJldHVybiB7CiAgICAkOiBidWZmZXIsCiAgICBhZGQsCiAgICBkcmFpbiwKICB9Owp9Cgpjb25zdCBPTkVfU0VDT05EX0lOX01TID0gMTAwMDsKCi8qKgogKiBBIHBhcnRpYWwgZGVmaW5pdGlvbiBvZiB0aGUgW1BlcmZvcm1hbmNlIFdlYiBBUElde0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9QZXJmb3JtYW5jZX0KICogZm9yIGFjY2Vzc2luZyBhIGhpZ2gtcmVzb2x1dGlvbiBtb25vdG9uaWMgY2xvY2suCiAqLwoKLyoqCiAqIFJldHVybnMgYSB0aW1lc3RhbXAgaW4gc2Vjb25kcyBzaW5jZSB0aGUgVU5JWCBlcG9jaCB1c2luZyB0aGUgRGF0ZSBBUEkuCiAqCiAqIFRPRE8odjgpOiBSZXR1cm4gdHlwZSBzaG91bGQgYmUgcm91bmRlZC4KICovCmZ1bmN0aW9uIGRhdGVUaW1lc3RhbXBJblNlY29uZHMoKSB7CiAgcmV0dXJuIERhdGUubm93KCkgLyBPTkVfU0VDT05EX0lOX01TOwp9CgovKioKICogUmV0dXJucyBhIHdyYXBwZXIgYXJvdW5kIHRoZSBuYXRpdmUgUGVyZm9ybWFuY2UgQVBJIGJyb3dzZXIgaW1wbGVtZW50YXRpb24sIG9yIHVuZGVmaW5lZCBmb3IgYnJvd3NlcnMgdGhhdCBkbyBub3QKICogc3VwcG9ydCB0aGUgQVBJLgogKgogKiBXcmFwcGluZyB0aGUgbmF0aXZlIEFQSSB3b3JrcyBhcm91bmQgZGlmZmVyZW5jZXMgaW4gYmVoYXZpb3IgZnJvbSBkaWZmZXJlbnQgYnJvd3NlcnMuCiAqLwpmdW5jdGlvbiBjcmVhdGVVbml4VGltZXN0YW1wSW5TZWNvbmRzRnVuYygpIHsKICBjb25zdCB7IHBlcmZvcm1hbmNlIH0gPSBHTE9CQUxfT0JKIDsKICBpZiAoIXBlcmZvcm1hbmNlIHx8ICFwZXJmb3JtYW5jZS5ub3cpIHsKICAgIHJldHVybiBkYXRlVGltZXN0YW1wSW5TZWNvbmRzOwogIH0KCiAgLy8gU29tZSBicm93c2VyIGFuZCBlbnZpcm9ubWVudHMgZG9uJ3QgaGF2ZSBhIHRpbWVPcmlnaW4sIHNvIHdlIGZhbGxiYWNrIHRvCiAgLy8gdXNpbmcgRGF0ZS5ub3coKSB0byBjb21wdXRlIHRoZSBzdGFydGluZyB0aW1lLgogIGNvbnN0IGFwcHJveFN0YXJ0aW5nVGltZU9yaWdpbiA9IERhdGUubm93KCkgLSBwZXJmb3JtYW5jZS5ub3coKTsKICBjb25zdCB0aW1lT3JpZ2luID0gcGVyZm9ybWFuY2UudGltZU9yaWdpbiA9PSB1bmRlZmluZWQgPyBhcHByb3hTdGFydGluZ1RpbWVPcmlnaW4gOiBwZXJmb3JtYW5jZS50aW1lT3JpZ2luOwoKICAvLyBwZXJmb3JtYW5jZS5ub3coKSBpcyBhIG1vbm90b25pYyBjbG9jaywgd2hpY2ggbWVhbnMgaXQgc3RhcnRzIGF0IDAgd2hlbiB0aGUgcHJvY2VzcyBiZWdpbnMuIFRvIGdldCB0aGUgY3VycmVudAogIC8vIHdhbGwgY2xvY2sgdGltZSAoYWN0dWFsIFVOSVggdGltZXN0YW1wKSwgd2UgbmVlZCB0byBhZGQgdGhlIHN0YXJ0aW5nIHRpbWUgb3JpZ2luIGFuZCB0aGUgY3VycmVudCB0aW1lIGVsYXBzZWQuCiAgLy8KICAvLyBUT0RPOiBUaGlzIGRvZXMgbm90IGFjY291bnQgZm9yIHRoZSBjYXNlIHdoZXJlIHRoZSBtb25vdG9uaWMgY2xvY2sgdGhhdCBwb3dlcnMgcGVyZm9ybWFuY2Uubm93KCkgZHJpZnRzIGZyb20gdGhlCiAgLy8gd2FsbCBjbG9jayB0aW1lLCB3aGljaCBjYXVzZXMgdGhlIHJldHVybmVkIHRpbWVzdGFtcCB0byBiZSBpbmFjY3VyYXRlLiBXZSBzaG91bGQgaW52ZXN0aWdhdGUgaG93IHRvIGRldGVjdCBhbmQKICAvLyBjb3JyZWN0IGZvciB0aGlzLgogIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdC9pc3N1ZXMvMjU5MAogIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL21kbi9jb250ZW50L2lzc3Vlcy80NzEzCiAgLy8gU2VlOiBodHRwczovL2Rldi50by9ub2Ftci93aGVuLWEtbWlsbGlzZWNvbmQtaXMtbm90LWEtbWlsbGlzZWNvbmQtM2g2CiAgcmV0dXJuICgpID0+IHsKICAgIHJldHVybiAodGltZU9yaWdpbiArIHBlcmZvcm1hbmNlLm5vdygpKSAvIE9ORV9TRUNPTkRfSU5fTVM7CiAgfTsKfQoKLyoqCiAqIFJldHVybnMgYSB0aW1lc3RhbXAgaW4gc2Vjb25kcyBzaW5jZSB0aGUgVU5JWCBlcG9jaCB1c2luZyBlaXRoZXIgdGhlIFBlcmZvcm1hbmNlIG9yIERhdGUgQVBJcywgZGVwZW5kaW5nIG9uIHRoZQogKiBhdmFpbGFiaWxpdHkgb2YgdGhlIFBlcmZvcm1hbmNlIEFQSS4KICoKICogQlVHOiBOb3RlIHRoYXQgYmVjYXVzZSBvZiBob3cgYnJvd3NlcnMgaW1wbGVtZW50IHRoZSBQZXJmb3JtYW5jZSBBUEksIHRoZSBjbG9jayBtaWdodCBzdG9wIHdoZW4gdGhlIGNvbXB1dGVyIGlzCiAqIGFzbGVlcC4gVGhpcyBjcmVhdGVzIGEgc2tldyBiZXR3ZWVuIGBkYXRlVGltZXN0YW1wSW5TZWNvbmRzYCBhbmQgYHRpbWVzdGFtcEluU2Vjb25kc2AuIFRoZQogKiBza2V3IGNhbiBncm93IHRvIGFyYml0cmFyeSBhbW91bnRzIGxpa2UgZGF5cywgd2Vla3Mgb3IgbW9udGhzLgogKiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdC9pc3N1ZXMvMjU5MC4KICovCmNvbnN0IHRpbWVzdGFtcEluU2Vjb25kcyA9IGNyZWF0ZVVuaXhUaW1lc3RhbXBJblNlY29uZHNGdW5jKCk7CgovKioKICogVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgc2luY2UgdGhlIFVOSVggZXBvY2guIFRoaXMgdmFsdWUgaXMgb25seSB1c2FibGUgaW4gYSBicm93c2VyLCBhbmQgb25seSB3aGVuIHRoZQogKiBwZXJmb3JtYW5jZSBBUEkgaXMgYXZhaWxhYmxlLgogKi8KKCgpID0+IHsKICAvLyBVbmZvcnR1bmF0ZWx5IGJyb3dzZXJzIG1heSByZXBvcnQgYW4gaW5hY2N1cmF0ZSB0aW1lIG9yaWdpbiBkYXRhLCB0aHJvdWdoIGVpdGhlciBwZXJmb3JtYW5jZS50aW1lT3JpZ2luIG9yCiAgLy8gcGVyZm9ybWFuY2UudGltaW5nLm5hdmlnYXRpb25TdGFydCwgd2hpY2ggcmVzdWx0cyBpbiBwb29yIHJlc3VsdHMgaW4gcGVyZm9ybWFuY2UgZGF0YS4gV2Ugb25seSB0cmVhdCB0aW1lIG9yaWdpbgogIC8vIGRhdGEgYXMgcmVsaWFibGUgaWYgdGhleSBhcmUgd2l0aGluIGEgcmVhc29uYWJsZSB0aHJlc2hvbGQgb2YgdGhlIGN1cnJlbnQgdGltZS4KCiAgY29uc3QgeyBwZXJmb3JtYW5jZSB9ID0gR0xPQkFMX09CSiA7CiAgaWYgKCFwZXJmb3JtYW5jZSB8fCAhcGVyZm9ybWFuY2Uubm93KSB7CiAgICByZXR1cm4gdW5kZWZpbmVkOwogIH0KCiAgY29uc3QgdGhyZXNob2xkID0gMzYwMCAqIDEwMDA7CiAgY29uc3QgcGVyZm9ybWFuY2VOb3cgPSBwZXJmb3JtYW5jZS5ub3coKTsKICBjb25zdCBkYXRlTm93ID0gRGF0ZS5ub3coKTsKCiAgLy8gaWYgdGltZU9yaWdpbiBpc24ndCBhdmFpbGFibGUgc2V0IGRlbHRhIHRvIHRocmVzaG9sZCBzbyBpdCBpc24ndCB1c2VkCiAgY29uc3QgdGltZU9yaWdpbkRlbHRhID0gcGVyZm9ybWFuY2UudGltZU9yaWdpbgogICAgPyBNYXRoLmFicyhwZXJmb3JtYW5jZS50aW1lT3JpZ2luICsgcGVyZm9ybWFuY2VOb3cgLSBkYXRlTm93KQogICAgOiB0aHJlc2hvbGQ7CiAgY29uc3QgdGltZU9yaWdpbklzUmVsaWFibGUgPSB0aW1lT3JpZ2luRGVsdGEgPCB0aHJlc2hvbGQ7CgogIC8vIFdoaWxlIHBlcmZvcm1hbmNlLnRpbWluZy5uYXZpZ2F0aW9uU3RhcnQgaXMgZGVwcmVjYXRlZCBpbiBmYXZvciBvZiBwZXJmb3JtYW5jZS50aW1lT3JpZ2luLCBwZXJmb3JtYW5jZS50aW1lT3JpZ2luCiAgLy8gaXMgbm90IGFzIHdpZGVseSBzdXBwb3J0ZWQuIE5hbWVseSwgcGVyZm9ybWFuY2UudGltZU9yaWdpbiBpcyB1bmRlZmluZWQgaW4gU2FmYXJpIGFzIG9mIHdyaXRpbmcuCiAgLy8gQWxzbyBhcyBvZiB3cml0aW5nLCBwZXJmb3JtYW5jZS50aW1pbmcgaXMgbm90IGF2YWlsYWJsZSBpbiBXZWIgV29ya2VycyBpbiBtYWluc3RyZWFtIGJyb3dzZXJzLCBzbyBpdCBpcyBub3QgYWx3YXlzCiAgLy8gYSB2YWxpZCBmYWxsYmFjay4gSW4gdGhlIGFic2VuY2Ugb2YgYW4gaW5pdGlhbCB0aW1lIHByb3ZpZGVkIGJ5IHRoZSBicm93c2VyLCBmYWxsYmFjayB0byB0aGUgY3VycmVudCB0aW1lIGZyb20gdGhlCiAgLy8gRGF0ZSBBUEkuCiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCiAgY29uc3QgbmF2aWdhdGlvblN0YXJ0ID0gcGVyZm9ybWFuY2UudGltaW5nICYmIHBlcmZvcm1hbmNlLnRpbWluZy5uYXZpZ2F0aW9uU3RhcnQ7CiAgY29uc3QgaGFzTmF2aWdhdGlvblN0YXJ0ID0gdHlwZW9mIG5hdmlnYXRpb25TdGFydCA9PT0gJ251bWJlcic7CiAgLy8gaWYgbmF2aWdhdGlvblN0YXJ0IGlzbid0IGF2YWlsYWJsZSBzZXQgZGVsdGEgdG8gdGhyZXNob2xkIHNvIGl0IGlzbid0IHVzZWQKICBjb25zdCBuYXZpZ2F0aW9uU3RhcnREZWx0YSA9IGhhc05hdmlnYXRpb25TdGFydCA/IE1hdGguYWJzKG5hdmlnYXRpb25TdGFydCArIHBlcmZvcm1hbmNlTm93IC0gZGF0ZU5vdykgOiB0aHJlc2hvbGQ7CiAgY29uc3QgbmF2aWdhdGlvblN0YXJ0SXNSZWxpYWJsZSA9IG5hdmlnYXRpb25TdGFydERlbHRhIDwgdGhyZXNob2xkOwoKICBpZiAodGltZU9yaWdpbklzUmVsaWFibGUgfHwgbmF2aWdhdGlvblN0YXJ0SXNSZWxpYWJsZSkgewogICAgLy8gVXNlIHRoZSBtb3JlIHJlbGlhYmxlIHRpbWUgb3JpZ2luCiAgICBpZiAodGltZU9yaWdpbkRlbHRhIDw9IG5hdmlnYXRpb25TdGFydERlbHRhKSB7CiAgICAgIHJldHVybiBwZXJmb3JtYW5jZS50aW1lT3JpZ2luOwogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIG5hdmlnYXRpb25TdGFydDsKICAgIH0KICB9CiAgcmV0dXJuIGRhdGVOb3c7Cn0pKCk7CgovKioKICogQ3JlYXRlcyBhbiBlbnZlbG9wZS4KICogTWFrZSBzdXJlIHRvIGFsd2F5cyBleHBsaWNpdGx5IHByb3ZpZGUgdGhlIGdlbmVyaWMgdG8gdGhpcyBmdW5jdGlvbgogKiBzbyB0aGF0IHRoZSBlbnZlbG9wZSB0eXBlcyByZXNvbHZlIGNvcnJlY3RseS4KICovCmZ1bmN0aW9uIGNyZWF0ZUVudmVsb3BlKGhlYWRlcnMsIGl0ZW1zID0gW10pIHsKICByZXR1cm4gW2hlYWRlcnMsIGl0ZW1zXSA7Cn0KCi8qKgogKiBDb252ZW5pZW5jZSBmdW5jdGlvbiB0byBsb29wIHRocm91Z2ggdGhlIGl0ZW1zIGFuZCBpdGVtIHR5cGVzIG9mIGFuIGVudmVsb3BlLgogKiAoVGhpcyBmdW5jdGlvbiB3YXMgbW9zdGx5IGNyZWF0ZWQgYmVjYXVzZSB3b3JraW5nIHdpdGggZW52ZWxvcGUgdHlwZXMgaXMgcGFpbmZ1bCBhdCB0aGUgbW9tZW50KQogKgogKiBJZiB0aGUgY2FsbGJhY2sgcmV0dXJucyB0cnVlLCB0aGUgcmVzdCBvZiB0aGUgaXRlbXMgd2lsbCBiZSBza2lwcGVkLgogKi8KZnVuY3Rpb24gZm9yRWFjaEVudmVsb3BlSXRlbSgKICBlbnZlbG9wZSwKICBjYWxsYmFjaywKKSB7CiAgY29uc3QgZW52ZWxvcGVJdGVtcyA9IGVudmVsb3BlWzFdOwoKICBmb3IgKGNvbnN0IGVudmVsb3BlSXRlbSBvZiBlbnZlbG9wZUl0ZW1zKSB7CiAgICBjb25zdCBlbnZlbG9wZUl0ZW1UeXBlID0gZW52ZWxvcGVJdGVtWzBdLnR5cGU7CiAgICBjb25zdCByZXN1bHQgPSBjYWxsYmFjayhlbnZlbG9wZUl0ZW0sIGVudmVsb3BlSXRlbVR5cGUpOwoKICAgIGlmIChyZXN1bHQpIHsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgfQoKICByZXR1cm4gZmFsc2U7Cn0KCi8qKgogKiBFbmNvZGUgYSBzdHJpbmcgdG8gVVRGOC4KICovCmZ1bmN0aW9uIGVuY29kZVVURjgoaW5wdXQsIHRleHRFbmNvZGVyKSB7CiAgY29uc3QgdXRmOCA9IHRleHRFbmNvZGVyIHx8IG5ldyBUZXh0RW5jb2RlcigpOwogIHJldHVybiB1dGY4LmVuY29kZShpbnB1dCk7Cn0KCi8qKgogKiBTZXJpYWxpemVzIGFuIGVudmVsb3BlLgogKi8KZnVuY3Rpb24gc2VyaWFsaXplRW52ZWxvcGUoZW52ZWxvcGUsIHRleHRFbmNvZGVyKSB7CiAgY29uc3QgW2VudkhlYWRlcnMsIGl0ZW1zXSA9IGVudmVsb3BlOwoKICAvLyBJbml0aWFsbHkgd2UgY29uc3RydWN0IG91ciBlbnZlbG9wZSBhcyBhIHN0cmluZyBhbmQgb25seSBjb252ZXJ0IHRvIGJpbmFyeSBjaHVua3MgaWYgd2UgZW5jb3VudGVyIGJpbmFyeSBkYXRhCiAgbGV0IHBhcnRzID0gSlNPTi5zdHJpbmdpZnkoZW52SGVhZGVycyk7CgogIGZ1bmN0aW9uIGFwcGVuZChuZXh0KSB7CiAgICBpZiAodHlwZW9mIHBhcnRzID09PSAnc3RyaW5nJykgewogICAgICBwYXJ0cyA9IHR5cGVvZiBuZXh0ID09PSAnc3RyaW5nJyA/IHBhcnRzICsgbmV4dCA6IFtlbmNvZGVVVEY4KHBhcnRzLCB0ZXh0RW5jb2RlciksIG5leHRdOwogICAgfSBlbHNlIHsKICAgICAgcGFydHMucHVzaCh0eXBlb2YgbmV4dCA9PT0gJ3N0cmluZycgPyBlbmNvZGVVVEY4KG5leHQsIHRleHRFbmNvZGVyKSA6IG5leHQpOwogICAgfQogIH0KCiAgZm9yIChjb25zdCBpdGVtIG9mIGl0ZW1zKSB7CiAgICBjb25zdCBbaXRlbUhlYWRlcnMsIHBheWxvYWRdID0gaXRlbTsKCiAgICBhcHBlbmQoYFxuJHtKU09OLnN0cmluZ2lmeShpdGVtSGVhZGVycyl9XG5gKTsKCiAgICBpZiAodHlwZW9mIHBheWxvYWQgPT09ICdzdHJpbmcnIHx8IHBheWxvYWQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7CiAgICAgIGFwcGVuZChwYXlsb2FkKTsKICAgIH0gZWxzZSB7CiAgICAgIGxldCBzdHJpbmdpZmllZFBheWxvYWQ7CiAgICAgIHRyeSB7CiAgICAgICAgc3RyaW5naWZpZWRQYXlsb2FkID0gSlNPTi5zdHJpbmdpZnkocGF5bG9hZCk7CiAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAvLyBJbiBjYXNlLCBkZXNwaXRlIGFsbCBvdXIgZWZmb3J0cyB0byBrZWVwIGBwYXlsb2FkYCBjaXJjdWxhci1kZXBlbmRlbmN5LWZyZWUsIGBKU09OLnN0cmluaWZ5KClgIHN0aWxsCiAgICAgICAgLy8gZmFpbHMsIHdlIHRyeSBhZ2FpbiBhZnRlciBub3JtYWxpemluZyBpdCBhZ2FpbiB3aXRoIGluZmluaXRlIG5vcm1hbGl6YXRpb24gZGVwdGguIFRoaXMgb2YgY291cnNlIGhhcyBhCiAgICAgICAgLy8gcGVyZm9ybWFuY2UgaW1wYWN0IGJ1dCBpbiB0aGlzIGNhc2UgYSBwZXJmb3JtYW5jZSBoaXQgaXMgYmV0dGVyIHRoYW4gdGhyb3dpbmcuCiAgICAgICAgc3RyaW5naWZpZWRQYXlsb2FkID0gSlNPTi5zdHJpbmdpZnkobm9ybWFsaXplKHBheWxvYWQpKTsKICAgICAgfQogICAgICBhcHBlbmQoc3RyaW5naWZpZWRQYXlsb2FkKTsKICAgIH0KICB9CgogIHJldHVybiB0eXBlb2YgcGFydHMgPT09ICdzdHJpbmcnID8gcGFydHMgOiBjb25jYXRCdWZmZXJzKHBhcnRzKTsKfQoKZnVuY3Rpb24gY29uY2F0QnVmZmVycyhidWZmZXJzKSB7CiAgY29uc3QgdG90YWxMZW5ndGggPSBidWZmZXJzLnJlZHVjZSgoYWNjLCBidWYpID0+IGFjYyArIGJ1Zi5sZW5ndGgsIDApOwoKICBjb25zdCBtZXJnZWQgPSBuZXcgVWludDhBcnJheSh0b3RhbExlbmd0aCk7CiAgbGV0IG9mZnNldCA9IDA7CiAgZm9yIChjb25zdCBidWZmZXIgb2YgYnVmZmVycykgewogICAgbWVyZ2VkLnNldChidWZmZXIsIG9mZnNldCk7CiAgICBvZmZzZXQgKz0gYnVmZmVyLmxlbmd0aDsKICB9CgogIHJldHVybiBtZXJnZWQ7Cn0KCmNvbnN0IElURU1fVFlQRV9UT19EQVRBX0NBVEVHT1JZX01BUCA9IHsKICBzZXNzaW9uOiAnc2Vzc2lvbicsCiAgc2Vzc2lvbnM6ICdzZXNzaW9uJywKICBhdHRhY2htZW50OiAnYXR0YWNobWVudCcsCiAgdHJhbnNhY3Rpb246ICd0cmFuc2FjdGlvbicsCiAgZXZlbnQ6ICdlcnJvcicsCiAgY2xpZW50X3JlcG9ydDogJ2ludGVybmFsJywKICB1c2VyX3JlcG9ydDogJ2RlZmF1bHQnLAogIHByb2ZpbGU6ICdwcm9maWxlJywKICByZXBsYXlfZXZlbnQ6ICdyZXBsYXknLAogIHJlcGxheV9yZWNvcmRpbmc6ICdyZXBsYXknLAogIGNoZWNrX2luOiAnbW9uaXRvcicsCiAgZmVlZGJhY2s6ICdmZWVkYmFjaycsCiAgc3BhbjogJ3NwYW4nLAogIC8vIFRPRE86IFRoaXMgaXMgYSB0ZW1wb3Jhcnkgd29ya2Fyb3VuZCB1bnRpbCB3ZSBoYXZlIGEgcHJvcGVyIGRhdGEgY2F0ZWdvcnkgZm9yIG1ldHJpY3MKICBzdGF0c2Q6ICd1bmtub3duJywKfTsKCi8qKgogKiBNYXBzIHRoZSB0eXBlIG9mIGFuIGVudmVsb3BlIGl0ZW0gdG8gYSBkYXRhIGNhdGVnb3J5LgogKi8KZnVuY3Rpb24gZW52ZWxvcGVJdGVtVHlwZVRvRGF0YUNhdGVnb3J5KHR5cGUpIHsKICByZXR1cm4gSVRFTV9UWVBFX1RPX0RBVEFfQ0FURUdPUllfTUFQW3R5cGVdOwp9CgovKiogRXh0cmFjdHMgdGhlIG1pbmltYWwgU0RLIGluZm8gZnJvbSBmcm9tIHRoZSBtZXRhZGF0YSBvciBhbiBldmVudHMgKi8KZnVuY3Rpb24gZ2V0U2RrTWV0YWRhdGFGb3JFbnZlbG9wZUhlYWRlcihtZXRhZGF0YU9yRXZlbnQpIHsKICBpZiAoIW1ldGFkYXRhT3JFdmVudCB8fCAhbWV0YWRhdGFPckV2ZW50LnNkaykgewogICAgcmV0dXJuOwogIH0KICBjb25zdCB7IG5hbWUsIHZlcnNpb24gfSA9IG1ldGFkYXRhT3JFdmVudC5zZGs7CiAgcmV0dXJuIHsgbmFtZSwgdmVyc2lvbiB9Owp9CgovKioKICogQ3JlYXRlcyBldmVudCBlbnZlbG9wZSBoZWFkZXJzLCBiYXNlZCBvbiBldmVudCwgc2RrIGluZm8gYW5kIHR1bm5lbAogKiBOb3RlOiBUaGlzIGZ1bmN0aW9uIHdhcyBleHRyYWN0ZWQgZnJvbSB0aGUgY29yZSBwYWNrYWdlIHRvIG1ha2UgaXQgYXZhaWxhYmxlIGluIFJlcGxheQogKi8KZnVuY3Rpb24gY3JlYXRlRXZlbnRFbnZlbG9wZUhlYWRlcnMoCiAgZXZlbnQsCiAgc2RrSW5mbywKICB0dW5uZWwsCiAgZHNuLAopIHsKICBjb25zdCBkeW5hbWljU2FtcGxpbmdDb250ZXh0ID0gZXZlbnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhICYmIGV2ZW50LnNka1Byb2Nlc3NpbmdNZXRhZGF0YS5keW5hbWljU2FtcGxpbmdDb250ZXh0OwogIHJldHVybiB7CiAgICBldmVudF9pZDogZXZlbnQuZXZlbnRfaWQgLAogICAgc2VudF9hdDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLAogICAgLi4uKHNka0luZm8gJiYgeyBzZGs6IHNka0luZm8gfSksCiAgICAuLi4oISF0dW5uZWwgJiYgZHNuICYmIHsgZHNuOiBkc25Ub1N0cmluZyhkc24pIH0pLAogICAgLi4uKGR5bmFtaWNTYW1wbGluZ0NvbnRleHQgJiYgewogICAgICB0cmFjZTogZHJvcFVuZGVmaW5lZEtleXMoeyAuLi5keW5hbWljU2FtcGxpbmdDb250ZXh0IH0pLAogICAgfSksCiAgfTsKfQoKLy8gSW50ZW50aW9uYWxseSBrZWVwaW5nIHRoZSBrZXkgYnJvYWQsIGFzIHdlIGRvbid0IGtub3cgZm9yIHN1cmUgd2hhdCByYXRlIGxpbWl0IGhlYWRlcnMgZ2V0IHJldHVybmVkIGZyb20gYmFja2VuZAoKY29uc3QgREVGQVVMVF9SRVRSWV9BRlRFUiA9IDYwICogMTAwMDsgLy8gNjAgc2Vjb25kcwoKLyoqCiAqIEV4dHJhY3RzIFJldHJ5LUFmdGVyIHZhbHVlIGZyb20gdGhlIHJlcXVlc3QgaGVhZGVyIG9yIHJldHVybnMgZGVmYXVsdCB2YWx1ZQogKiBAcGFyYW0gaGVhZGVyIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiAnUmV0cnktQWZ0ZXInIGhlYWRlcgogKiBAcGFyYW0gbm93IGN1cnJlbnQgdW5peCB0aW1lc3RhbXAKICoKICovCmZ1bmN0aW9uIHBhcnNlUmV0cnlBZnRlckhlYWRlcihoZWFkZXIsIG5vdyA9IERhdGUubm93KCkpIHsKICBjb25zdCBoZWFkZXJEZWxheSA9IHBhcnNlSW50KGAke2hlYWRlcn1gLCAxMCk7CiAgaWYgKCFpc05hTihoZWFkZXJEZWxheSkpIHsKICAgIHJldHVybiBoZWFkZXJEZWxheSAqIDEwMDA7CiAgfQoKICBjb25zdCBoZWFkZXJEYXRlID0gRGF0ZS5wYXJzZShgJHtoZWFkZXJ9YCk7CiAgaWYgKCFpc05hTihoZWFkZXJEYXRlKSkgewogICAgcmV0dXJuIGhlYWRlckRhdGUgLSBub3c7CiAgfQoKICByZXR1cm4gREVGQVVMVF9SRVRSWV9BRlRFUjsKfQoKLyoqCiAqIEdldHMgdGhlIHRpbWUgdGhhdCB0aGUgZ2l2ZW4gY2F0ZWdvcnkgaXMgZGlzYWJsZWQgdW50aWwgZm9yIHJhdGUgbGltaXRpbmcuCiAqIEluIGNhc2Ugbm8gY2F0ZWdvcnktc3BlY2lmaWMgbGltaXQgaXMgc2V0IGJ1dCBhIGdlbmVyYWwgcmF0ZSBsaW1pdCBhY3Jvc3MgYWxsIGNhdGVnb3JpZXMgaXMgYWN0aXZlLAogKiB0aGF0IHRpbWUgaXMgcmV0dXJuZWQuCiAqCiAqIEByZXR1cm4gdGhlIHRpbWUgaW4gbXMgdGhhdCB0aGUgY2F0ZWdvcnkgaXMgZGlzYWJsZWQgdW50aWwgb3IgMCBpZiB0aGVyZSdzIG5vIGFjdGl2ZSByYXRlIGxpbWl0LgogKi8KZnVuY3Rpb24gZGlzYWJsZWRVbnRpbChsaW1pdHMsIGNhdGVnb3J5KSB7CiAgcmV0dXJuIGxpbWl0c1tjYXRlZ29yeV0gfHwgbGltaXRzLmFsbCB8fCAwOwp9CgovKioKICogQ2hlY2tzIGlmIGEgY2F0ZWdvcnkgaXMgcmF0ZSBsaW1pdGVkCiAqLwpmdW5jdGlvbiBpc1JhdGVMaW1pdGVkKGxpbWl0cywgY2F0ZWdvcnksIG5vdyA9IERhdGUubm93KCkpIHsKICByZXR1cm4gZGlzYWJsZWRVbnRpbChsaW1pdHMsIGNhdGVnb3J5KSA+IG5vdzsKfQoKLyoqCiAqIFVwZGF0ZSByYXRlbGltaXRzIGZyb20gaW5jb21pbmcgaGVhZGVycy4KICoKICogQHJldHVybiB0aGUgdXBkYXRlZCBSYXRlTGltaXRzIG9iamVjdC4KICovCmZ1bmN0aW9uIHVwZGF0ZVJhdGVMaW1pdHMoCiAgbGltaXRzLAogIHsgc3RhdHVzQ29kZSwgaGVhZGVycyB9LAogIG5vdyA9IERhdGUubm93KCksCikgewogIGNvbnN0IHVwZGF0ZWRSYXRlTGltaXRzID0gewogICAgLi4ubGltaXRzLAogIH07CgogIC8vICJUaGUgbmFtZSBpcyBjYXNlLWluc2Vuc2l0aXZlLiIKICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvSGVhZGVycy9nZXQKICBjb25zdCByYXRlTGltaXRIZWFkZXIgPSBoZWFkZXJzICYmIGhlYWRlcnNbJ3gtc2VudHJ5LXJhdGUtbGltaXRzJ107CiAgY29uc3QgcmV0cnlBZnRlckhlYWRlciA9IGhlYWRlcnMgJiYgaGVhZGVyc1sncmV0cnktYWZ0ZXInXTsKCiAgaWYgKHJhdGVMaW1pdEhlYWRlcikgewogICAgLyoqCiAgICAgKiByYXRlIGxpbWl0IGhlYWRlcnMgYXJlIG9mIHRoZSBmb3JtCiAgICAgKiAgICAgPGhlYWRlcj4sPGhlYWRlcj4sLi4KICAgICAqIHdoZXJlIGVhY2ggPGhlYWRlcj4gaXMgb2YgdGhlIGZvcm0KICAgICAqICAgICA8cmV0cnlfYWZ0ZXI+OiA8Y2F0ZWdvcmllcz46IDxzY29wZT46IDxyZWFzb25fY29kZT4KICAgICAqIHdoZXJlCiAgICAgKiAgICAgPHJldHJ5X2FmdGVyPiBpcyBhIGRlbGF5IGluIHNlY29uZHMKICAgICAqICAgICA8Y2F0ZWdvcmllcz4gaXMgdGhlIGV2ZW50IHR5cGUocykgKGVycm9yLCB0cmFuc2FjdGlvbiwgZXRjKSBiZWluZyByYXRlIGxpbWl0ZWQgYW5kIGlzIG9mIHRoZSBmb3JtCiAgICAgKiAgICAgICAgIDxjYXRlZ29yeT47PGNhdGVnb3J5PjsuLi4KICAgICAqICAgICA8c2NvcGU+IGlzIHdoYXQncyBiZWluZyBsaW1pdGVkIChvcmcsIHByb2plY3QsIG9yIGtleSkgLSBpZ25vcmVkIGJ5IFNESwogICAgICogICAgIDxyZWFzb25fY29kZT4gaXMgYW4gYXJiaXRyYXJ5IHN0cmluZyBsaWtlICJvcmdfcXVvdGEiIC0gaWdub3JlZCBieSBTREsKICAgICAqLwogICAgZm9yIChjb25zdCBsaW1pdCBvZiByYXRlTGltaXRIZWFkZXIudHJpbSgpLnNwbGl0KCcsJykpIHsKICAgICAgY29uc3QgW3JldHJ5QWZ0ZXIsIGNhdGVnb3JpZXNdID0gbGltaXQuc3BsaXQoJzonLCAyKTsKICAgICAgY29uc3QgaGVhZGVyRGVsYXkgPSBwYXJzZUludChyZXRyeUFmdGVyLCAxMCk7CiAgICAgIGNvbnN0IGRlbGF5ID0gKCFpc05hTihoZWFkZXJEZWxheSkgPyBoZWFkZXJEZWxheSA6IDYwKSAqIDEwMDA7IC8vIDYwc2VjIGRlZmF1bHQKICAgICAgaWYgKCFjYXRlZ29yaWVzKSB7CiAgICAgICAgdXBkYXRlZFJhdGVMaW1pdHMuYWxsID0gbm93ICsgZGVsYXk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZm9yIChjb25zdCBjYXRlZ29yeSBvZiBjYXRlZ29yaWVzLnNwbGl0KCc7JykpIHsKICAgICAgICAgIHVwZGF0ZWRSYXRlTGltaXRzW2NhdGVnb3J5XSA9IG5vdyArIGRlbGF5OwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0gZWxzZSBpZiAocmV0cnlBZnRlckhlYWRlcikgewogICAgdXBkYXRlZFJhdGVMaW1pdHMuYWxsID0gbm93ICsgcGFyc2VSZXRyeUFmdGVySGVhZGVyKHJldHJ5QWZ0ZXJIZWFkZXIsIG5vdyk7CiAgfSBlbHNlIGlmIChzdGF0dXNDb2RlID09PSA0MjkpIHsKICAgIHVwZGF0ZWRSYXRlTGltaXRzLmFsbCA9IG5vdyArIDYwICogMTAwMDsKICB9CgogIHJldHVybiB1cGRhdGVkUmF0ZUxpbWl0czsKfQoKLyoqCiAqIEEgbm9kZS5qcyB3YXRjaGRvZyB0aW1lcgogKiBAcGFyYW0gcG9sbEludGVydmFsIFRoZSBpbnRlcnZhbCB0aGF0IHdlIGV4cGVjdCB0byBnZXQgcG9sbGVkIGF0CiAqIEBwYXJhbSBhbnJUaHJlc2hvbGQgVGhlIHRocmVzaG9sZCBmb3Igd2hlbiB3ZSBjb25zaWRlciBBTlIKICogQHBhcmFtIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBjYWxsIGZvciBBTlIKICogQHJldHVybnMgQW4gb2JqZWN0IHdpdGggYHBvbGxgIGFuZCBgZW5hYmxlZGAgZnVuY3Rpb25zIHtAbGluayBXYXRjaGRvZ1JldHVybn0KICovCmZ1bmN0aW9uIHdhdGNoZG9nVGltZXIoCiAgY3JlYXRlVGltZXIsCiAgcG9sbEludGVydmFsLAogIGFuclRocmVzaG9sZCwKICBjYWxsYmFjaywKKSB7CiAgY29uc3QgdGltZXIgPSBjcmVhdGVUaW1lcigpOwogIGxldCB0cmlnZ2VyZWQgPSBmYWxzZTsKICBsZXQgZW5hYmxlZCA9IHRydWU7CgogIHNldEludGVydmFsKCgpID0+IHsKICAgIGNvbnN0IGRpZmZNcyA9IHRpbWVyLmdldFRpbWVNcygpOwoKICAgIGlmICh0cmlnZ2VyZWQgPT09IGZhbHNlICYmIGRpZmZNcyA+IHBvbGxJbnRlcnZhbCArIGFuclRocmVzaG9sZCkgewogICAgICB0cmlnZ2VyZWQgPSB0cnVlOwogICAgICBpZiAoZW5hYmxlZCkgewogICAgICAgIGNhbGxiYWNrKCk7CiAgICAgIH0KICAgIH0KCiAgICBpZiAoZGlmZk1zIDwgcG9sbEludGVydmFsICsgYW5yVGhyZXNob2xkKSB7CiAgICAgIHRyaWdnZXJlZCA9IGZhbHNlOwogICAgfQogIH0sIDIwKTsKCiAgcmV0dXJuIHsKICAgIHBvbGw6ICgpID0+IHsKICAgICAgdGltZXIucmVzZXQoKTsKICAgIH0sCiAgICBlbmFibGVkOiAoc3RhdGUpID0+IHsKICAgICAgZW5hYmxlZCA9IHN0YXRlOwogICAgfSwKICB9Owp9CgovLyB0eXBlcyBjb3BpZWQgZnJvbSBpbnNwZWN0b3IuZC50cwoKLyoqCiAqIENvbnZlcnRzIERlYnVnZ2VyLkNhbGxGcmFtZSB0byBTZW50cnkgU3RhY2tGcmFtZQogKi8KZnVuY3Rpb24gY2FsbEZyYW1lVG9TdGFja0ZyYW1lKAogIGZyYW1lLAogIHVybCwKICBnZXRNb2R1bGVGcm9tRmlsZW5hbWUsCikgewogIGNvbnN0IGZpbGVuYW1lID0gdXJsID8gdXJsLnJlcGxhY2UoL15maWxlOlwvXC8vLCAnJykgOiB1bmRlZmluZWQ7CgogIC8vIENhbGxGcmFtZSByb3cvY29sIGFyZSAwIGJhc2VkLCB3aGVyZWFzIFN0YWNrRnJhbWUgYXJlIDEgYmFzZWQKICBjb25zdCBjb2xubyA9IGZyYW1lLmxvY2F0aW9uLmNvbHVtbk51bWJlciA/IGZyYW1lLmxvY2F0aW9uLmNvbHVtbk51bWJlciArIDEgOiB1bmRlZmluZWQ7CiAgY29uc3QgbGluZW5vID0gZnJhbWUubG9jYXRpb24ubGluZU51bWJlciA/IGZyYW1lLmxvY2F0aW9uLmxpbmVOdW1iZXIgKyAxIDogdW5kZWZpbmVkOwoKICByZXR1cm4gZHJvcFVuZGVmaW5lZEtleXMoewogICAgZmlsZW5hbWUsCiAgICBtb2R1bGU6IGdldE1vZHVsZUZyb21GaWxlbmFtZShmaWxlbmFtZSksCiAgICBmdW5jdGlvbjogZnJhbWUuZnVuY3Rpb25OYW1lIHx8ICc/JywKICAgIGNvbG5vLAogICAgbGluZW5vLAogICAgaW5fYXBwOiBmaWxlbmFtZSA/IGZpbGVuYW1lSXNJbkFwcChmaWxlbmFtZSkgOiB1bmRlZmluZWQsCiAgfSk7Cn0KCi8qKgogKiBUaGlzIHNlcnZlcyBhcyBhIGJ1aWxkIHRpbWUgZmxhZyB0aGF0IHdpbGwgYmUgdHJ1ZSBieSBkZWZhdWx0LCBidXQgZmFsc2UgaW4gbm9uLWRlYnVnIGJ1aWxkcyBvciBpZiB1c2VycyByZXBsYWNlIGBfX1NFTlRSWV9ERUJVR19fYCBpbiB0aGVpciBnZW5lcmF0ZWQgY29kZS4KICoKICogQVRURU5USU9OOiBUaGlzIGNvbnN0YW50IG11c3QgbmV2ZXIgY3Jvc3MgcGFja2FnZSBib3VuZGFyaWVzIChpLmUuIGJlIGV4cG9ydGVkKSB0byBndWFyYW50ZWUgdGhhdCBpdCBjYW4gYmUgdXNlZCBmb3IgdHJlZSBzaGFraW5nLgogKi8KY29uc3QgREVCVUdfQlVJTEQgPSAodHlwZW9mIF9fU0VOVFJZX0RFQlVHX18gPT09ICd1bmRlZmluZWQnIHx8IF9fU0VOVFJZX0RFQlVHX18pOwoKLyoqCiAqIENyZWF0ZXMgYSBuZXcgYFNlc3Npb25gIG9iamVjdCBieSBzZXR0aW5nIGNlcnRhaW4gZGVmYXVsdCBwYXJhbWV0ZXJzLiBJZiBvcHRpb25hbCBAcGFyYW0gY29udGV4dAogKiBpcyBwYXNzZWQsIHRoZSBwYXNzZWQgcHJvcGVydGllcyBhcmUgYXBwbGllZCB0byB0aGUgc2Vzc2lvbiBvYmplY3QuCiAqCiAqIEBwYXJhbSBjb250ZXh0IChvcHRpb25hbCkgYWRkaXRpb25hbCBwcm9wZXJ0aWVzIHRvIGJlIGFwcGxpZWQgdG8gdGhlIHJldHVybmVkIHNlc3Npb24gb2JqZWN0CiAqCiAqIEByZXR1cm5zIGEgbmV3IGBTZXNzaW9uYCBvYmplY3QKICovCmZ1bmN0aW9uIG1ha2VTZXNzaW9uKGNvbnRleHQpIHsKICAvLyBCb3RoIHRpbWVzdGFtcCBhbmQgc3RhcnRlZCBhcmUgaW4gc2Vjb25kcyBzaW5jZSB0aGUgVU5JWCBlcG9jaC4KICBjb25zdCBzdGFydGluZ1RpbWUgPSB0aW1lc3RhbXBJblNlY29uZHMoKTsKCiAgY29uc3Qgc2Vzc2lvbiA9IHsKICAgIHNpZDogdXVpZDQoKSwKICAgIGluaXQ6IHRydWUsCiAgICB0aW1lc3RhbXA6IHN0YXJ0aW5nVGltZSwKICAgIHN0YXJ0ZWQ6IHN0YXJ0aW5nVGltZSwKICAgIGR1cmF0aW9uOiAwLAogICAgc3RhdHVzOiAnb2snLAogICAgZXJyb3JzOiAwLAogICAgaWdub3JlRHVyYXRpb246IGZhbHNlLAogICAgdG9KU09OOiAoKSA9PiBzZXNzaW9uVG9KU09OKHNlc3Npb24pLAogIH07CgogIGlmIChjb250ZXh0KSB7CiAgICB1cGRhdGVTZXNzaW9uKHNlc3Npb24sIGNvbnRleHQpOwogIH0KCiAgcmV0dXJuIHNlc3Npb247Cn0KCi8qKgogKiBVcGRhdGVzIGEgc2Vzc2lvbiBvYmplY3Qgd2l0aCB0aGUgcHJvcGVydGllcyBwYXNzZWQgaW4gdGhlIGNvbnRleHQuCiAqCiAqIE5vdGUgdGhhdCB0aGlzIGZ1bmN0aW9uIG11dGF0ZXMgdGhlIHBhc3NlZCBvYmplY3QgYW5kIHJldHVybnMgdm9pZC4KICogKEhhZCB0byBkbyB0aGlzIGluc3RlYWQgb2YgcmV0dXJuaW5nIGEgbmV3IGFuZCB1cGRhdGVkIHNlc3Npb24gYmVjYXVzZSBjbG9zaW5nIGFuZCBzZW5kaW5nIGEgc2Vzc2lvbgogKiBtYWtlcyBhbiB1cGRhdGUgdG8gdGhlIHNlc3Npb24gYWZ0ZXIgaXQgd2FzIHBhc3NlZCB0byB0aGUgc2VuZGluZyBsb2dpYy4KICogQHNlZSBCYXNlQ2xpZW50LmNhcHR1cmVTZXNzaW9uICkKICoKICogQHBhcmFtIHNlc3Npb24gdGhlIGBTZXNzaW9uYCB0byB1cGRhdGUKICogQHBhcmFtIGNvbnRleHQgdGhlIGBTZXNzaW9uQ29udGV4dGAgaG9sZGluZyB0aGUgcHJvcGVydGllcyB0aGF0IHNob3VsZCBiZSB1cGRhdGVkIGluIEBwYXJhbSBzZXNzaW9uCiAqLwovLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29tcGxleGl0eQpmdW5jdGlvbiB1cGRhdGVTZXNzaW9uKHNlc3Npb24sIGNvbnRleHQgPSB7fSkgewogIGlmIChjb250ZXh0LnVzZXIpIHsKICAgIGlmICghc2Vzc2lvbi5pcEFkZHJlc3MgJiYgY29udGV4dC51c2VyLmlwX2FkZHJlc3MpIHsKICAgICAgc2Vzc2lvbi5pcEFkZHJlc3MgPSBjb250ZXh0LnVzZXIuaXBfYWRkcmVzczsKICAgIH0KCiAgICBpZiAoIXNlc3Npb24uZGlkICYmICFjb250ZXh0LmRpZCkgewogICAgICBzZXNzaW9uLmRpZCA9IGNvbnRleHQudXNlci5pZCB8fCBjb250ZXh0LnVzZXIuZW1haWwgfHwgY29udGV4dC51c2VyLnVzZXJuYW1lOwogICAgfQogIH0KCiAgc2Vzc2lvbi50aW1lc3RhbXAgPSBjb250ZXh0LnRpbWVzdGFtcCB8fCB0aW1lc3RhbXBJblNlY29uZHMoKTsKCiAgaWYgKGNvbnRleHQuYWJub3JtYWxfbWVjaGFuaXNtKSB7CiAgICBzZXNzaW9uLmFibm9ybWFsX21lY2hhbmlzbSA9IGNvbnRleHQuYWJub3JtYWxfbWVjaGFuaXNtOwogIH0KCiAgaWYgKGNvbnRleHQuaWdub3JlRHVyYXRpb24pIHsKICAgIHNlc3Npb24uaWdub3JlRHVyYXRpb24gPSBjb250ZXh0Lmlnbm9yZUR1cmF0aW9uOwogIH0KICBpZiAoY29udGV4dC5zaWQpIHsKICAgIC8vIEdvb2QgZW5vdWdoIHV1aWQgdmFsaWRhdGlvbi4g4oCUIEthbWlsCiAgICBzZXNzaW9uLnNpZCA9IGNvbnRleHQuc2lkLmxlbmd0aCA9PT0gMzIgPyBjb250ZXh0LnNpZCA6IHV1aWQ0KCk7CiAgfQogIGlmIChjb250ZXh0LmluaXQgIT09IHVuZGVmaW5lZCkgewogICAgc2Vzc2lvbi5pbml0ID0gY29udGV4dC5pbml0OwogIH0KICBpZiAoIXNlc3Npb24uZGlkICYmIGNvbnRleHQuZGlkKSB7CiAgICBzZXNzaW9uLmRpZCA9IGAke2NvbnRleHQuZGlkfWA7CiAgfQogIGlmICh0eXBlb2YgY29udGV4dC5zdGFydGVkID09PSAnbnVtYmVyJykgewogICAgc2Vzc2lvbi5zdGFydGVkID0gY29udGV4dC5zdGFydGVkOwogIH0KICBpZiAoc2Vzc2lvbi5pZ25vcmVEdXJhdGlvbikgewogICAgc2Vzc2lvbi5kdXJhdGlvbiA9IHVuZGVmaW5lZDsKICB9IGVsc2UgaWYgKHR5cGVvZiBjb250ZXh0LmR1cmF0aW9uID09PSAnbnVtYmVyJykgewogICAgc2Vzc2lvbi5kdXJhdGlvbiA9IGNvbnRleHQuZHVyYXRpb247CiAgfSBlbHNlIHsKICAgIGNvbnN0IGR1cmF0aW9uID0gc2Vzc2lvbi50aW1lc3RhbXAgLSBzZXNzaW9uLnN0YXJ0ZWQ7CiAgICBzZXNzaW9uLmR1cmF0aW9uID0gZHVyYXRpb24gPj0gMCA/IGR1cmF0aW9uIDogMDsKICB9CiAgaWYgKGNvbnRleHQucmVsZWFzZSkgewogICAgc2Vzc2lvbi5yZWxlYXNlID0gY29udGV4dC5yZWxlYXNlOwogIH0KICBpZiAoY29udGV4dC5lbnZpcm9ubWVudCkgewogICAgc2Vzc2lvbi5lbnZpcm9ubWVudCA9IGNvbnRleHQuZW52aXJvbm1lbnQ7CiAgfQogIGlmICghc2Vzc2lvbi5pcEFkZHJlc3MgJiYgY29udGV4dC5pcEFkZHJlc3MpIHsKICAgIHNlc3Npb24uaXBBZGRyZXNzID0gY29udGV4dC5pcEFkZHJlc3M7CiAgfQogIGlmICghc2Vzc2lvbi51c2VyQWdlbnQgJiYgY29udGV4dC51c2VyQWdlbnQpIHsKICAgIHNlc3Npb24udXNlckFnZW50ID0gY29udGV4dC51c2VyQWdlbnQ7CiAgfQogIGlmICh0eXBlb2YgY29udGV4dC5lcnJvcnMgPT09ICdudW1iZXInKSB7CiAgICBzZXNzaW9uLmVycm9ycyA9IGNvbnRleHQuZXJyb3JzOwogIH0KICBpZiAoY29udGV4dC5zdGF0dXMpIHsKICAgIHNlc3Npb24uc3RhdHVzID0gY29udGV4dC5zdGF0dXM7CiAgfQp9CgovKioKICogU2VyaWFsaXplcyBhIHBhc3NlZCBzZXNzaW9uIG9iamVjdCB0byBhIEpTT04gb2JqZWN0IHdpdGggYSBzbGlnaHRseSBkaWZmZXJlbnQgc3RydWN0dXJlLgogKiBUaGlzIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIHRoZSBTZW50cnkgYmFja2VuZCByZXF1aXJlcyBhIHNsaWdodGx5IGRpZmZlcmVudCBzY2hlbWEgb2YgYSBzZXNzaW9uCiAqIHRoYW4gdGhlIG9uZSB0aGUgSlMgU0RLcyB1c2UgaW50ZXJuYWxseS4KICoKICogQHBhcmFtIHNlc3Npb24gdGhlIHNlc3Npb24gdG8gYmUgY29udmVydGVkCiAqCiAqIEByZXR1cm5zIGEgSlNPTiBvYmplY3Qgb2YgdGhlIHBhc3NlZCBzZXNzaW9uCiAqLwpmdW5jdGlvbiBzZXNzaW9uVG9KU09OKHNlc3Npb24pIHsKICByZXR1cm4gZHJvcFVuZGVmaW5lZEtleXMoewogICAgc2lkOiBgJHtzZXNzaW9uLnNpZH1gLAogICAgaW5pdDogc2Vzc2lvbi5pbml0LAogICAgLy8gTWFrZSBzdXJlIHRoYXQgc2VjIGlzIGNvbnZlcnRlZCB0byBtcyBmb3IgZGF0ZSBjb25zdHJ1Y3RvcgogICAgc3RhcnRlZDogbmV3IERhdGUoc2Vzc2lvbi5zdGFydGVkICogMTAwMCkudG9JU09TdHJpbmcoKSwKICAgIHRpbWVzdGFtcDogbmV3IERhdGUoc2Vzc2lvbi50aW1lc3RhbXAgKiAxMDAwKS50b0lTT1N0cmluZygpLAogICAgc3RhdHVzOiBzZXNzaW9uLnN0YXR1cywKICAgIGVycm9yczogc2Vzc2lvbi5lcnJvcnMsCiAgICBkaWQ6IHR5cGVvZiBzZXNzaW9uLmRpZCA9PT0gJ251bWJlcicgfHwgdHlwZW9mIHNlc3Npb24uZGlkID09PSAnc3RyaW5nJyA/IGAke3Nlc3Npb24uZGlkfWAgOiB1bmRlZmluZWQsCiAgICBkdXJhdGlvbjogc2Vzc2lvbi5kdXJhdGlvbiwKICAgIGFibm9ybWFsX21lY2hhbmlzbTogc2Vzc2lvbi5hYm5vcm1hbF9tZWNoYW5pc20sCiAgICBhdHRyczogewogICAgICByZWxlYXNlOiBzZXNzaW9uLnJlbGVhc2UsCiAgICAgIGVudmlyb25tZW50OiBzZXNzaW9uLmVudmlyb25tZW50LAogICAgICBpcF9hZGRyZXNzOiBzZXNzaW9uLmlwQWRkcmVzcywKICAgICAgdXNlcl9hZ2VudDogc2Vzc2lvbi51c2VyQWdlbnQsCiAgICB9LAogIH0pOwp9CgovKioKICogQXBwbHkgU2RrSW5mbyAobmFtZSwgdmVyc2lvbiwgcGFja2FnZXMsIGludGVncmF0aW9ucykgdG8gdGhlIGNvcnJlc3BvbmRpbmcgZXZlbnQga2V5LgogKiBNZXJnZSB3aXRoIGV4aXN0aW5nIGRhdGEgaWYgYW55LgogKiovCmZ1bmN0aW9uIGVuaGFuY2VFdmVudFdpdGhTZGtJbmZvKGV2ZW50LCBzZGtJbmZvKSB7CiAgaWYgKCFzZGtJbmZvKSB7CiAgICByZXR1cm4gZXZlbnQ7CiAgfQogIGV2ZW50LnNkayA9IGV2ZW50LnNkayB8fCB7fTsKICBldmVudC5zZGsubmFtZSA9IGV2ZW50LnNkay5uYW1lIHx8IHNka0luZm8ubmFtZTsKICBldmVudC5zZGsudmVyc2lvbiA9IGV2ZW50LnNkay52ZXJzaW9uIHx8IHNka0luZm8udmVyc2lvbjsKICBldmVudC5zZGsuaW50ZWdyYXRpb25zID0gWy4uLihldmVudC5zZGsuaW50ZWdyYXRpb25zIHx8IFtdKSwgLi4uKHNka0luZm8uaW50ZWdyYXRpb25zIHx8IFtdKV07CiAgZXZlbnQuc2RrLnBhY2thZ2VzID0gWy4uLihldmVudC5zZGsucGFja2FnZXMgfHwgW10pLCAuLi4oc2RrSW5mby5wYWNrYWdlcyB8fCBbXSldOwogIHJldHVybiBldmVudDsKfQoKLyoqIENyZWF0ZXMgYW4gZW52ZWxvcGUgZnJvbSBhIFNlc3Npb24gKi8KZnVuY3Rpb24gY3JlYXRlU2Vzc2lvbkVudmVsb3BlKAogIHNlc3Npb24sCiAgZHNuLAogIG1ldGFkYXRhLAogIHR1bm5lbCwKKSB7CiAgY29uc3Qgc2RrSW5mbyA9IGdldFNka01ldGFkYXRhRm9yRW52ZWxvcGVIZWFkZXIobWV0YWRhdGEpOwogIGNvbnN0IGVudmVsb3BlSGVhZGVycyA9IHsKICAgIHNlbnRfYXQ6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSwKICAgIC4uLihzZGtJbmZvICYmIHsgc2RrOiBzZGtJbmZvIH0pLAogICAgLi4uKCEhdHVubmVsICYmIGRzbiAmJiB7IGRzbjogZHNuVG9TdHJpbmcoZHNuKSB9KSwKICB9OwoKICBjb25zdCBlbnZlbG9wZUl0ZW0gPQogICAgJ2FnZ3JlZ2F0ZXMnIGluIHNlc3Npb24gPyBbeyB0eXBlOiAnc2Vzc2lvbnMnIH0sIHNlc3Npb25dIDogW3sgdHlwZTogJ3Nlc3Npb24nIH0sIHNlc3Npb24udG9KU09OKCldOwoKICByZXR1cm4gY3JlYXRlRW52ZWxvcGUoZW52ZWxvcGVIZWFkZXJzLCBbZW52ZWxvcGVJdGVtXSk7Cn0KCi8qKgogKiBDcmVhdGUgYW4gRW52ZWxvcGUgZnJvbSBhbiBldmVudC4KICovCmZ1bmN0aW9uIGNyZWF0ZUV2ZW50RW52ZWxvcGUoCiAgZXZlbnQsCiAgZHNuLAogIG1ldGFkYXRhLAogIHR1bm5lbCwKKSB7CiAgY29uc3Qgc2RrSW5mbyA9IGdldFNka01ldGFkYXRhRm9yRW52ZWxvcGVIZWFkZXIobWV0YWRhdGEpOwoKICAvKgogICAgTm90ZTogRHVlIHRvIFRTLCBldmVudC50eXBlIG1heSBiZSBgcmVwbGF5X2V2ZW50YCwgdGhlb3JldGljYWxseS4KICAgIEluIHByYWN0aWNlLCB3ZSBuZXZlciBjYWxsIGBjcmVhdGVFdmVudEVudmVsb3BlYCB3aXRoIGByZXBsYXlfZXZlbnRgIHR5cGUsCiAgICBhbmQgd2UnZCBoYXZlIHRvIGFkanV0IGEgbG9vb3Qgb2YgdHlwZXMgdG8gbWFrZSB0aGlzIHdvcmsgcHJvcGVybHkuCiAgICBXZSB3YW50IHRvIGF2b2lkIGNhc3RpbmcgdGhpcyBhcm91bmQsIGFzIHRoYXQgY291bGQgbGVhZCB0byBidWdzIChlLmcuIHdoZW4gd2UgYWRkIGFub3RoZXIgdHlwZSkKICAgIFNvIHRoZSBzYWZlIGNob2ljZSBpcyB0byByZWFsbHkgZ3VhcmQgYWdhaW5zdCB0aGUgcmVwbGF5X2V2ZW50IHR5cGUgaGVyZS4KICAqLwogIGNvbnN0IGV2ZW50VHlwZSA9IGV2ZW50LnR5cGUgJiYgZXZlbnQudHlwZSAhPT0gJ3JlcGxheV9ldmVudCcgPyBldmVudC50eXBlIDogJ2V2ZW50JzsKCiAgZW5oYW5jZUV2ZW50V2l0aFNka0luZm8oZXZlbnQsIG1ldGFkYXRhICYmIG1ldGFkYXRhLnNkayk7CgogIGNvbnN0IGVudmVsb3BlSGVhZGVycyA9IGNyZWF0ZUV2ZW50RW52ZWxvcGVIZWFkZXJzKGV2ZW50LCBzZGtJbmZvLCB0dW5uZWwsIGRzbik7CgogIC8vIFByZXZlbnQgdGhpcyBkYXRhICh3aGljaCwgaWYgaXQgZXhpc3RzLCB3YXMgdXNlZCBpbiBlYXJsaWVyIHN0ZXBzIGluIHRoZSBwcm9jZXNzaW5nIHBpcGVsaW5lKSBmcm9tIGJlaW5nIHNlbnQgdG8KICAvLyBzZW50cnkuIChOb3RlOiBPdXIgdXNlIG9mIHRoaXMgcHJvcGVydHkgY29tZXMgYW5kIGdvZXMgd2l0aCB3aGF0ZXZlciB3ZSBtaWdodCBiZSBkZWJ1Z2dpbmcsIHdoYXRldmVyIGhhY2tzIHdlIG1heQogIC8vIGhhdmUgdGVtcG9yYXJpbHkgYWRkZWQsIGV0Yy4gRXZlbiBpZiB3ZSBkb24ndCBoYXBwZW4gdG8gYmUgdXNpbmcgaXQgYXQgc29tZSBwb2ludCBpbiB0aGUgZnV0dXJlLCBsZXQncyBub3QgZ2V0IHJpZAogIC8vIG9mIHRoaXMgYGRlbGV0ZWAsIGxlc3Qgd2UgbWlzcyBwdXR0aW5nIGl0IGJhY2sgaW4gdGhlIG5leHQgdGltZSB0aGUgcHJvcGVydHkgaXMgaW4gdXNlLikKICBkZWxldGUgZXZlbnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhOwoKICBjb25zdCBldmVudEl0ZW0gPSBbeyB0eXBlOiBldmVudFR5cGUgfSwgZXZlbnRdOwogIHJldHVybiBjcmVhdGVFbnZlbG9wZShlbnZlbG9wZUhlYWRlcnMsIFtldmVudEl0ZW1dKTsKfQoKY29uc3QgU0VOVFJZX0FQSV9WRVJTSU9OID0gJzcnOwoKLyoqIFJldHVybnMgdGhlIHByZWZpeCB0byBjb25zdHJ1Y3QgU2VudHJ5IGluZ2VzdGlvbiBBUEkgZW5kcG9pbnRzLiAqLwpmdW5jdGlvbiBnZXRCYXNlQXBpRW5kcG9pbnQoZHNuKSB7CiAgY29uc3QgcHJvdG9jb2wgPSBkc24ucHJvdG9jb2wgPyBgJHtkc24ucHJvdG9jb2x9OmAgOiAnJzsKICBjb25zdCBwb3J0ID0gZHNuLnBvcnQgPyBgOiR7ZHNuLnBvcnR9YCA6ICcnOwogIHJldHVybiBgJHtwcm90b2NvbH0vLyR7ZHNuLmhvc3R9JHtwb3J0fSR7ZHNuLnBhdGggPyBgLyR7ZHNuLnBhdGh9YCA6ICcnfS9hcGkvYDsKfQoKLyoqIFJldHVybnMgdGhlIGluZ2VzdCBBUEkgZW5kcG9pbnQgZm9yIHRhcmdldC4gKi8KZnVuY3Rpb24gX2dldEluZ2VzdEVuZHBvaW50KGRzbikgewogIHJldHVybiBgJHtnZXRCYXNlQXBpRW5kcG9pbnQoZHNuKX0ke2Rzbi5wcm9qZWN0SWR9L2VudmVsb3BlL2A7Cn0KCi8qKiBSZXR1cm5zIGEgVVJMLWVuY29kZWQgc3RyaW5nIHdpdGggYXV0aCBjb25maWcgc3VpdGFibGUgZm9yIGEgcXVlcnkgc3RyaW5nLiAqLwpmdW5jdGlvbiBfZW5jb2RlZEF1dGgoZHNuLCBzZGtJbmZvKSB7CiAgcmV0dXJuIHVybEVuY29kZSh7CiAgICAvLyBXZSBzZW5kIG9ubHkgdGhlIG1pbmltdW0gc2V0IG9mIHJlcXVpcmVkIGluZm9ybWF0aW9uLiBTZWUKICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9nZXRzZW50cnkvc2VudHJ5LWphdmFzY3JpcHQvaXNzdWVzLzI1NzIuCiAgICBzZW50cnlfa2V5OiBkc24ucHVibGljS2V5LAogICAgc2VudHJ5X3ZlcnNpb246IFNFTlRSWV9BUElfVkVSU0lPTiwKICAgIC4uLihzZGtJbmZvICYmIHsgc2VudHJ5X2NsaWVudDogYCR7c2RrSW5mby5uYW1lfS8ke3Nka0luZm8udmVyc2lvbn1gIH0pLAogIH0pOwp9CgovKioKICogUmV0dXJucyB0aGUgZW52ZWxvcGUgZW5kcG9pbnQgVVJMIHdpdGggYXV0aCBpbiB0aGUgcXVlcnkgc3RyaW5nLgogKgogKiBTZW5kaW5nIGF1dGggYXMgcGFydCBvZiB0aGUgcXVlcnkgc3RyaW5nIGFuZCBub3QgYXMgY3VzdG9tIEhUVFAgaGVhZGVycyBhdm9pZHMgQ09SUyBwcmVmbGlnaHQgcmVxdWVzdHMuCiAqLwpmdW5jdGlvbiBnZXRFbnZlbG9wZUVuZHBvaW50V2l0aFVybEVuY29kZWRBdXRoKAogIGRzbiwKICAvLyBUT0RPICh2OCk6IFJlbW92ZSBgdHVubmVsT3JPcHRpb25zYCBpbiBmYXZvciBvZiBgb3B0aW9uc2AsIGFuZCB1c2UgdGhlIHN1YnN0aXR1dGUgY29kZSBiZWxvdwogIC8vIG9wdGlvbnM6IENsaWVudE9wdGlvbnMgPSB7fSBhcyBDbGllbnRPcHRpb25zLAogIHR1bm5lbE9yT3B0aW9ucyA9IHt9ICwKKSB7CiAgLy8gVE9ETyAodjgpOiBVc2UgdGhpcyBjb2RlIGluc3RlYWQKICAvLyBjb25zdCB7IHR1bm5lbCwgX21ldGFkYXRhID0ge30gfSA9IG9wdGlvbnM7CiAgLy8gcmV0dXJuIHR1bm5lbCA/IHR1bm5lbCA6IGAke19nZXRJbmdlc3RFbmRwb2ludChkc24pfT8ke19lbmNvZGVkQXV0aChkc24sIF9tZXRhZGF0YS5zZGspfWA7CgogIGNvbnN0IHR1bm5lbCA9IHR5cGVvZiB0dW5uZWxPck9wdGlvbnMgPT09ICdzdHJpbmcnID8gdHVubmVsT3JPcHRpb25zIDogdHVubmVsT3JPcHRpb25zLnR1bm5lbDsKICBjb25zdCBzZGtJbmZvID0KICAgIHR5cGVvZiB0dW5uZWxPck9wdGlvbnMgPT09ICdzdHJpbmcnIHx8ICF0dW5uZWxPck9wdGlvbnMuX21ldGFkYXRhID8gdW5kZWZpbmVkIDogdHVubmVsT3JPcHRpb25zLl9tZXRhZGF0YS5zZGs7CgogIHJldHVybiB0dW5uZWwgPyB0dW5uZWwgOiBgJHtfZ2V0SW5nZXN0RW5kcG9pbnQoZHNuKX0/JHtfZW5jb2RlZEF1dGgoZHNuLCBzZGtJbmZvKX1gOwp9Cgpjb25zdCBERUZBVUxUX1RSQU5TUE9SVF9CVUZGRVJfU0laRSA9IDMwOwoKLyoqCiAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgYSBTZW50cnkgYFRyYW5zcG9ydGAKICoKICogQHBhcmFtIG9wdGlvbnMKICogQHBhcmFtIG1ha2VSZXF1ZXN0CiAqLwpmdW5jdGlvbiBjcmVhdGVUcmFuc3BvcnQoCiAgb3B0aW9ucywKICBtYWtlUmVxdWVzdCwKICBidWZmZXIgPSBtYWtlUHJvbWlzZUJ1ZmZlcigKICAgIG9wdGlvbnMuYnVmZmVyU2l6ZSB8fCBERUZBVUxUX1RSQU5TUE9SVF9CVUZGRVJfU0laRSwKICApLAopIHsKICBsZXQgcmF0ZUxpbWl0cyA9IHt9OwogIGNvbnN0IGZsdXNoID0gKHRpbWVvdXQpID0+IGJ1ZmZlci5kcmFpbih0aW1lb3V0KTsKCiAgZnVuY3Rpb24gc2VuZChlbnZlbG9wZSkgewogICAgY29uc3QgZmlsdGVyZWRFbnZlbG9wZUl0ZW1zID0gW107CgogICAgLy8gRHJvcCByYXRlIGxpbWl0ZWQgaXRlbXMgZnJvbSBlbnZlbG9wZQogICAgZm9yRWFjaEVudmVsb3BlSXRlbShlbnZlbG9wZSwgKGl0ZW0sIHR5cGUpID0+IHsKICAgICAgY29uc3QgZW52ZWxvcGVJdGVtRGF0YUNhdGVnb3J5ID0gZW52ZWxvcGVJdGVtVHlwZVRvRGF0YUNhdGVnb3J5KHR5cGUpOwogICAgICBpZiAoaXNSYXRlTGltaXRlZChyYXRlTGltaXRzLCBlbnZlbG9wZUl0ZW1EYXRhQ2F0ZWdvcnkpKSB7CiAgICAgICAgY29uc3QgZXZlbnQgPSBnZXRFdmVudEZvckVudmVsb3BlSXRlbShpdGVtLCB0eXBlKTsKICAgICAgICBvcHRpb25zLnJlY29yZERyb3BwZWRFdmVudCgncmF0ZWxpbWl0X2JhY2tvZmYnLCBlbnZlbG9wZUl0ZW1EYXRhQ2F0ZWdvcnksIGV2ZW50KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBmaWx0ZXJlZEVudmVsb3BlSXRlbXMucHVzaChpdGVtKTsKICAgICAgfQogICAgfSk7CgogICAgLy8gU2tpcCBzZW5kaW5nIGlmIGVudmVsb3BlIGlzIGVtcHR5IGFmdGVyIGZpbHRlcmluZyBvdXQgcmF0ZSBsaW1pdGVkIGV2ZW50cwogICAgaWYgKGZpbHRlcmVkRW52ZWxvcGVJdGVtcy5sZW5ndGggPT09IDApIHsKICAgICAgcmV0dXJuIHJlc29sdmVkU3luY1Byb21pc2UoKTsKICAgIH0KCiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueQogICAgY29uc3QgZmlsdGVyZWRFbnZlbG9wZSA9IGNyZWF0ZUVudmVsb3BlKGVudmVsb3BlWzBdLCBmaWx0ZXJlZEVudmVsb3BlSXRlbXMgKTsKCiAgICAvLyBDcmVhdGVzIGNsaWVudCByZXBvcnQgZm9yIGVhY2ggaXRlbSBpbiBhbiBlbnZlbG9wZQogICAgY29uc3QgcmVjb3JkRW52ZWxvcGVMb3NzID0gKHJlYXNvbikgPT4gewogICAgICBmb3JFYWNoRW52ZWxvcGVJdGVtKGZpbHRlcmVkRW52ZWxvcGUsIChpdGVtLCB0eXBlKSA9PiB7CiAgICAgICAgY29uc3QgZXZlbnQgPSBnZXRFdmVudEZvckVudmVsb3BlSXRlbShpdGVtLCB0eXBlKTsKICAgICAgICBvcHRpb25zLnJlY29yZERyb3BwZWRFdmVudChyZWFzb24sIGVudmVsb3BlSXRlbVR5cGVUb0RhdGFDYXRlZ29yeSh0eXBlKSwgZXZlbnQpOwogICAgICB9KTsKICAgIH07CgogICAgY29uc3QgcmVxdWVzdFRhc2sgPSAoKSA9PgogICAgICBtYWtlUmVxdWVzdCh7IGJvZHk6IHNlcmlhbGl6ZUVudmVsb3BlKGZpbHRlcmVkRW52ZWxvcGUsIG9wdGlvbnMudGV4dEVuY29kZXIpIH0pLnRoZW4oCiAgICAgICAgcmVzcG9uc2UgPT4gewogICAgICAgICAgLy8gV2UgZG9uJ3Qgd2FudCB0byB0aHJvdyBvbiBOT0sgcmVzcG9uc2VzLCBidXQgd2Ugd2FudCB0byBhdCBsZWFzdCBsb2cgdGhlbQogICAgICAgICAgaWYgKHJlc3BvbnNlLnN0YXR1c0NvZGUgIT09IHVuZGVmaW5lZCAmJiAocmVzcG9uc2Uuc3RhdHVzQ29kZSA8IDIwMCB8fCByZXNwb25zZS5zdGF0dXNDb2RlID49IDMwMCkpIHsKICAgICAgICAgICAgREVCVUdfQlVJTEQgJiYgbG9nZ2VyLndhcm4oYFNlbnRyeSByZXNwb25kZWQgd2l0aCBzdGF0dXMgY29kZSAke3Jlc3BvbnNlLnN0YXR1c0NvZGV9IHRvIHNlbnQgZXZlbnQuYCk7CiAgICAgICAgICB9CgogICAgICAgICAgcmF0ZUxpbWl0cyA9IHVwZGF0ZVJhdGVMaW1pdHMocmF0ZUxpbWl0cywgcmVzcG9uc2UpOwogICAgICAgICAgcmV0dXJuIHJlc3BvbnNlOwogICAgICAgIH0sCiAgICAgICAgZXJyb3IgPT4gewogICAgICAgICAgcmVjb3JkRW52ZWxvcGVMb3NzKCduZXR3b3JrX2Vycm9yJyk7CiAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9LAogICAgICApOwoKICAgIHJldHVybiBidWZmZXIuYWRkKHJlcXVlc3RUYXNrKS50aGVuKAogICAgICByZXN1bHQgPT4gcmVzdWx0LAogICAgICBlcnJvciA9PiB7CiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgU2VudHJ5RXJyb3IpIHsKICAgICAgICAgIERFQlVHX0JVSUxEICYmIGxvZ2dlci5lcnJvcignU2tpcHBlZCBzZW5kaW5nIGV2ZW50IGJlY2F1c2UgYnVmZmVyIGlzIGZ1bGwuJyk7CiAgICAgICAgICByZWNvcmRFbnZlbG9wZUxvc3MoJ3F1ZXVlX292ZXJmbG93Jyk7CiAgICAgICAgICByZXR1cm4gcmVzb2x2ZWRTeW5jUHJvbWlzZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9CiAgICAgIH0sCiAgICApOwogIH0KCiAgLy8gV2UgdXNlIHRoaXMgdG8gaWRlbnRpZmlmeSBpZiB0aGUgdHJhbnNwb3J0IGlzIHRoZSBiYXNlIHRyYW5zcG9ydAogIC8vIFRPRE8gKHY4KTogUmVtb3ZlIHRoaXMgYWdhaW4gYXMgd2UnbGwgbm8gbG9uZ2VyIG5lZWQgaXQKICBzZW5kLl9fc2VudHJ5X19iYXNlVHJhbnNwb3J0X18gPSB0cnVlOwoKICByZXR1cm4gewogICAgc2VuZCwKICAgIGZsdXNoLAogIH07Cn0KCmZ1bmN0aW9uIGdldEV2ZW50Rm9yRW52ZWxvcGVJdGVtKGl0ZW0sIHR5cGUpIHsKICBpZiAodHlwZSAhPT0gJ2V2ZW50JyAmJiB0eXBlICE9PSAndHJhbnNhY3Rpb24nKSB7CiAgICByZXR1cm4gdW5kZWZpbmVkOwogIH0KCiAgcmV0dXJuIEFycmF5LmlzQXJyYXkoaXRlbSkgPyAoaXRlbSApWzFdIDogdW5kZWZpbmVkOwp9CgovKiogbm9ybWFsaXplcyBXaW5kb3dzIHBhdGhzICovCmZ1bmN0aW9uIG5vcm1hbGl6ZVdpbmRvd3NQYXRoKHBhdGgpIHsKICByZXR1cm4gcGF0aAogICAgLnJlcGxhY2UoL15bQS1aXTovLCAnJykgLy8gcmVtb3ZlIFdpbmRvd3Mtc3R5bGUgcHJlZml4CiAgICAucmVwbGFjZSgvXFwvZywgJy8nKTsgLy8gcmVwbGFjZSBhbGwgYFxgIGluc3RhbmNlcyB3aXRoIGAvYAp9CgovKiogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgZ2V0cyB0aGUgbW9kdWxlIG5hbWUgZnJvbSBhIGZpbGVuYW1lICovCmZ1bmN0aW9uIGNyZWF0ZUdldE1vZHVsZUZyb21GaWxlbmFtZSgKICBiYXNlUGF0aCA9IHByb2Nlc3MuYXJndlsxXSA/IGRpcm5hbWUocHJvY2Vzcy5hcmd2WzFdKSA6IHByb2Nlc3MuY3dkKCksCiAgaXNXaW5kb3dzID0gc2VwID09PSAnXFwnLAopIHsKICBjb25zdCBub3JtYWxpemVkQmFzZSA9IGlzV2luZG93cyA/IG5vcm1hbGl6ZVdpbmRvd3NQYXRoKGJhc2VQYXRoKSA6IGJhc2VQYXRoOwoKICByZXR1cm4gKGZpbGVuYW1lKSA9PiB7CiAgICBpZiAoIWZpbGVuYW1lKSB7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICBjb25zdCBub3JtYWxpemVkRmlsZW5hbWUgPSBpc1dpbmRvd3MgPyBub3JtYWxpemVXaW5kb3dzUGF0aChmaWxlbmFtZSkgOiBmaWxlbmFtZTsKCiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLWNvbnN0CiAgICBsZXQgeyBkaXIsIGJhc2U6IGZpbGUsIGV4dCB9ID0gcG9zaXgucGFyc2Uobm9ybWFsaXplZEZpbGVuYW1lKTsKCiAgICBpZiAoZXh0ID09PSAnLmpzJyB8fCBleHQgPT09ICcubWpzJyB8fCBleHQgPT09ICcuY2pzJykgewogICAgICBmaWxlID0gZmlsZS5zbGljZSgwLCBleHQubGVuZ3RoICogLTEpOwogICAgfQoKICAgIGlmICghZGlyKSB7CiAgICAgIC8vIE5vIGRpcm5hbWUgd2hhdHNvZXZlcgogICAgICBkaXIgPSAnLic7CiAgICB9CgogICAgY29uc3QgbiA9IGRpci5sYXN0SW5kZXhPZignL25vZGVfbW9kdWxlcycpOwogICAgaWYgKG4gPiAtMSkgewogICAgICByZXR1cm4gYCR7ZGlyLnNsaWNlKG4gKyAxNCkucmVwbGFjZSgvXC8vZywgJy4nKX06JHtmaWxlfWA7CiAgICB9CgogICAgLy8gTGV0J3Mgc2VlIGlmIGl0J3MgYSBwYXJ0IG9mIHRoZSBtYWluIG1vZHVsZQogICAgLy8gVG8gYmUgYSBwYXJ0IG9mIG1haW4gbW9kdWxlLCBpdCBoYXMgdG8gc2hhcmUgdGhlIHNhbWUgYmFzZQogICAgaWYgKGRpci5zdGFydHNXaXRoKG5vcm1hbGl6ZWRCYXNlKSkgewogICAgICBsZXQgbW9kdWxlTmFtZSA9IGRpci5zbGljZShub3JtYWxpemVkQmFzZS5sZW5ndGggKyAxKS5yZXBsYWNlKC9cLy9nLCAnLicpOwoKICAgICAgaWYgKG1vZHVsZU5hbWUpIHsKICAgICAgICBtb2R1bGVOYW1lICs9ICc6JzsKICAgICAgfQogICAgICBtb2R1bGVOYW1lICs9IGZpbGU7CgogICAgICByZXR1cm4gbW9kdWxlTmFtZTsKICAgIH0KCiAgICByZXR1cm4gZmlsZTsKICB9Owp9CgpmdW5jdGlvbiBfbnVsbGlzaENvYWxlc2NlJDIobGhzLCByaHNGbikgeyBpZiAobGhzICE9IG51bGwpIHsgcmV0dXJuIGxoczsgfSBlbHNlIHsgcmV0dXJuIHJoc0ZuKCk7IH0gfS8qKgogKiBUaGlzIGNvZGUgd2FzIG9yaWdpbmFsbHkgZm9ya2VkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL1Rvb1RhbGxOYXRlL3Byb3h5LWFnZW50cy90cmVlL2IxMzMyOTVmZDE2ZjY0NzU1NzhiNmIxNWJkOWI0ZTMzZWNiMGQwYjcKICogV2l0aCB0aGUgZm9sbG93aW5nIGxpY2VuY2U6CiAqCiAqIChUaGUgTUlUIExpY2Vuc2UpCiAqCiAqIENvcHlyaWdodCAoYykgMjAxMyBOYXRoYW4gUmFqbGljaCA8bmF0aGFuQHRvb3RhbGxuYXRlLm5ldD4qCiAqCiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZwogKiBhIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUKICogJ1NvZnR3YXJlJyksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZwogKiB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsCiAqIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0bwogKiBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8KICogdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOioKICoKICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUKICogaW5jbHVkZWQgaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuKgogKgogKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgJ0FTIElTJywgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwKICogRVhQUkVTUyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GCiAqIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4KICogSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkKICogQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwKICogVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUKICogU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCiAqLwoKY29uc3QgSU5URVJOQUwgPSBTeW1ib2woJ0FnZW50QmFzZUludGVybmFsU3RhdGUnKTsKCmNsYXNzIEFnZW50IGV4dGVuZHMgaHR0cC5BZ2VudCB7CgogIC8vIFNldCBieSBgaHR0cC5BZ2VudGAgLSBtaXNzaW5nIGZyb20gYEB0eXBlcy9ub2RlYAoKICBjb25zdHJ1Y3RvcihvcHRzKSB7CiAgICBzdXBlcihvcHRzKTsKICAgIHRoaXNbSU5URVJOQUxdID0ge307CiAgfQoKICAvKioKICAgKiBEZXRlcm1pbmUgd2hldGhlciB0aGlzIGlzIGFuIGBodHRwYCBvciBgaHR0cHNgIHJlcXVlc3QuCiAgICovCiAgaXNTZWN1cmVFbmRwb2ludChvcHRpb25zKSB7CiAgICBpZiAob3B0aW9ucykgewogICAgICAvLyBGaXJzdCBjaGVjayB0aGUgYHNlY3VyZUVuZHBvaW50YCBwcm9wZXJ0eSBleHBsaWNpdGx5LCBzaW5jZSB0aGlzCiAgICAgIC8vIG1lYW5zIHRoYXQgYSBwYXJlbnQgYEFnZW50YCBpcyAicGFzc2luZyB0aHJvdWdoIiB0byB0aGlzIGluc3RhbmNlLgogICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1tZW1iZXItYWNjZXNzCiAgICAgIGlmICh0eXBlb2YgKG9wdGlvbnMgKS5zZWN1cmVFbmRwb2ludCA9PT0gJ2Jvb2xlYW4nKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbnMuc2VjdXJlRW5kcG9pbnQ7CiAgICAgIH0KCiAgICAgIC8vIElmIG5vIGV4cGxpY2l0IGBzZWN1cmVgIGVuZHBvaW50LCBjaGVjayBpZiBgcHJvdG9jb2xgIHByb3BlcnR5IGlzCiAgICAgIC8vIHNldC4gVGhpcyB3aWxsIHVzdWFsbHkgYmUgdGhlIGNhc2Ugc2luY2UgdXNpbmcgYSBmdWxsIHN0cmluZyBVUkwKICAgICAgLy8gb3IgYFVSTGAgaW5zdGFuY2Ugc2hvdWxkIGJlIHRoZSBtb3N0IGNvbW1vbiB1c2FnZS4KICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLnByb3RvY29sID09PSAnc3RyaW5nJykgewogICAgICAgIHJldHVybiBvcHRpb25zLnByb3RvY29sID09PSAnaHR0cHM6JzsKICAgICAgfQogICAgfQoKICAgIC8vIEZpbmFsbHksIGlmIG5vIGBwcm90b2NvbGAgcHJvcGVydHkgd2FzIHNldCwgdGhlbiBmYWxsIGJhY2sgdG8KICAgIC8vIGNoZWNraW5nIHRoZSBzdGFjayB0cmFjZSBvZiB0aGUgY3VycmVudCBjYWxsIHN0YWNrLCBhbmQgdHJ5IHRvCiAgICAvLyBkZXRlY3QgdGhlICJodHRwcyIgbW9kdWxlLgogICAgY29uc3QgeyBzdGFjayB9ID0gbmV3IEVycm9yKCk7CiAgICBpZiAodHlwZW9mIHN0YWNrICE9PSAnc3RyaW5nJykgcmV0dXJuIGZhbHNlOwogICAgcmV0dXJuIHN0YWNrLnNwbGl0KCdcbicpLnNvbWUobCA9PiBsLmluZGV4T2YoJyhodHRwcy5qczonKSAhPT0gLTEgfHwgbC5pbmRleE9mKCdub2RlOmh0dHBzOicpICE9PSAtMSk7CiAgfQoKICBjcmVhdGVTb2NrZXQocmVxLCBvcHRpb25zLCBjYikgewogICAgY29uc3QgY29ubmVjdE9wdHMgPSB7CiAgICAgIC4uLm9wdGlvbnMsCiAgICAgIHNlY3VyZUVuZHBvaW50OiB0aGlzLmlzU2VjdXJlRW5kcG9pbnQob3B0aW9ucyksCiAgICB9OwogICAgUHJvbWlzZS5yZXNvbHZlKCkKICAgICAgLnRoZW4oKCkgPT4gdGhpcy5jb25uZWN0KHJlcSwgY29ubmVjdE9wdHMpKQogICAgICAudGhlbihzb2NrZXQgPT4gewogICAgICAgIGlmIChzb2NrZXQgaW5zdGFuY2VvZiBodHRwLkFnZW50KSB7CiAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGBhZGRSZXF1ZXN0KClgIGlzbid0IGRlZmluZWQgaW4gYEB0eXBlcy9ub2RlYAogICAgICAgICAgcmV0dXJuIHNvY2tldC5hZGRSZXF1ZXN0KHJlcSwgY29ubmVjdE9wdHMpOwogICAgICAgIH0KICAgICAgICB0aGlzW0lOVEVSTkFMXS5jdXJyZW50U29ja2V0ID0gc29ja2V0OwogICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgYGNyZWF0ZVNvY2tldCgpYCBpc24ndCBkZWZpbmVkIGluIGBAdHlwZXMvbm9kZWAKICAgICAgICBzdXBlci5jcmVhdGVTb2NrZXQocmVxLCBvcHRpb25zLCBjYik7CiAgICAgIH0sIGNiKTsKICB9CgogIGNyZWF0ZUNvbm5lY3Rpb24oKSB7CiAgICBjb25zdCBzb2NrZXQgPSB0aGlzW0lOVEVSTkFMXS5jdXJyZW50U29ja2V0OwogICAgdGhpc1tJTlRFUk5BTF0uY3VycmVudFNvY2tldCA9IHVuZGVmaW5lZDsKICAgIGlmICghc29ja2V0KSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gc29ja2V0IHdhcyByZXR1cm5lZCBpbiB0aGUgYGNvbm5lY3QoKWAgZnVuY3Rpb24nKTsKICAgIH0KICAgIHJldHVybiBzb2NrZXQ7CiAgfQoKICBnZXQgZGVmYXVsdFBvcnQoKSB7CiAgICByZXR1cm4gX251bGxpc2hDb2FsZXNjZSQyKHRoaXNbSU5URVJOQUxdLmRlZmF1bHRQb3J0LCAoKSA9PiAoICh0aGlzLnByb3RvY29sID09PSAnaHR0cHM6JyA/IDQ0MyA6IDgwKSkpOwogIH0KCiAgc2V0IGRlZmF1bHRQb3J0KHYpIHsKICAgIGlmICh0aGlzW0lOVEVSTkFMXSkgewogICAgICB0aGlzW0lOVEVSTkFMXS5kZWZhdWx0UG9ydCA9IHY7CiAgICB9CiAgfQoKICBnZXQgcHJvdG9jb2woKSB7CiAgICByZXR1cm4gX251bGxpc2hDb2FsZXNjZSQyKHRoaXNbSU5URVJOQUxdLnByb3RvY29sLCAoKSA9PiAoICh0aGlzLmlzU2VjdXJlRW5kcG9pbnQoKSA/ICdodHRwczonIDogJ2h0dHA6JykpKTsKICB9CgogIHNldCBwcm90b2NvbCh2KSB7CiAgICBpZiAodGhpc1tJTlRFUk5BTF0pIHsKICAgICAgdGhpc1tJTlRFUk5BTF0ucHJvdG9jb2wgPSB2OwogICAgfQogIH0KfQoKZnVuY3Rpb24gZGVidWckMSguLi5hcmdzKSB7CiAgbG9nZ2VyLmxvZygnW2h0dHBzLXByb3h5LWFnZW50OnBhcnNlLXByb3h5LXJlc3BvbnNlXScsIC4uLmFyZ3MpOwp9CgpmdW5jdGlvbiBwYXJzZVByb3h5UmVzcG9uc2Uoc29ja2V0KSB7CiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHsKICAgIC8vIHdlIG5lZWQgdG8gYnVmZmVyIGFueSBIVFRQIHRyYWZmaWMgdGhhdCBoYXBwZW5zIHdpdGggdGhlIHByb3h5IGJlZm9yZSB3ZSBnZXQKICAgIC8vIHRoZSBDT05ORUNUIHJlc3BvbnNlLCBzbyB0aGF0IGlmIHRoZSByZXNwb25zZSBpcyBhbnl0aGluZyBvdGhlciB0aGFuIGFuICIyMDAiCiAgICAvLyByZXNwb25zZSBjb2RlLCB0aGVuIHdlIGNhbiByZS1wbGF5IHRoZSAiZGF0YSIgZXZlbnRzIG9uIHRoZSBzb2NrZXQgb25jZSB0aGUKICAgIC8vIEhUVFAgcGFyc2VyIGlzIGhvb2tlZCB1cC4uLgogICAgbGV0IGJ1ZmZlcnNMZW5ndGggPSAwOwogICAgY29uc3QgYnVmZmVycyA9IFtdOwoKICAgIGZ1bmN0aW9uIHJlYWQoKSB7CiAgICAgIGNvbnN0IGIgPSBzb2NrZXQucmVhZCgpOwogICAgICBpZiAoYikgb25kYXRhKGIpOwogICAgICBlbHNlIHNvY2tldC5vbmNlKCdyZWFkYWJsZScsIHJlYWQpOwogICAgfQoKICAgIGZ1bmN0aW9uIGNsZWFudXAoKSB7CiAgICAgIHNvY2tldC5yZW1vdmVMaXN0ZW5lcignZW5kJywgb25lbmQpOwogICAgICBzb2NrZXQucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7CiAgICAgIHNvY2tldC5yZW1vdmVMaXN0ZW5lcigncmVhZGFibGUnLCByZWFkKTsKICAgIH0KCiAgICBmdW5jdGlvbiBvbmVuZCgpIHsKICAgICAgY2xlYW51cCgpOwogICAgICBkZWJ1ZyQxKCdvbmVuZCcpOwogICAgICByZWplY3QobmV3IEVycm9yKCdQcm94eSBjb25uZWN0aW9uIGVuZGVkIGJlZm9yZSByZWNlaXZpbmcgQ09OTkVDVCByZXNwb25zZScpKTsKICAgIH0KCiAgICBmdW5jdGlvbiBvbmVycm9yKGVycikgewogICAgICBjbGVhbnVwKCk7CiAgICAgIGRlYnVnJDEoJ29uZXJyb3IgJW8nLCBlcnIpOwogICAgICByZWplY3QoZXJyKTsKICAgIH0KCiAgICBmdW5jdGlvbiBvbmRhdGEoYikgewogICAgICBidWZmZXJzLnB1c2goYik7CiAgICAgIGJ1ZmZlcnNMZW5ndGggKz0gYi5sZW5ndGg7CgogICAgICBjb25zdCBidWZmZXJlZCA9IEJ1ZmZlci5jb25jYXQoYnVmZmVycywgYnVmZmVyc0xlbmd0aCk7CiAgICAgIGNvbnN0IGVuZE9mSGVhZGVycyA9IGJ1ZmZlcmVkLmluZGV4T2YoJ1xyXG5cclxuJyk7CgogICAgICBpZiAoZW5kT2ZIZWFkZXJzID09PSAtMSkgewogICAgICAgIC8vIGtlZXAgYnVmZmVyaW5nCiAgICAgICAgZGVidWckMSgnaGF2ZSBub3QgcmVjZWl2ZWQgZW5kIG9mIEhUVFAgaGVhZGVycyB5ZXQuLi4nKTsKICAgICAgICByZWFkKCk7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogICAgICBjb25zdCBoZWFkZXJQYXJ0cyA9IGJ1ZmZlcmVkLnNsaWNlKDAsIGVuZE9mSGVhZGVycykudG9TdHJpbmcoJ2FzY2lpJykuc3BsaXQoJ1xyXG4nKTsKICAgICAgY29uc3QgZmlyc3RMaW5lID0gaGVhZGVyUGFydHMuc2hpZnQoKTsKICAgICAgaWYgKCFmaXJzdExpbmUpIHsKICAgICAgICBzb2NrZXQuZGVzdHJveSgpOwogICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKCdObyBoZWFkZXIgcmVjZWl2ZWQgZnJvbSBwcm94eSBDT05ORUNUIHJlc3BvbnNlJykpOwogICAgICB9CiAgICAgIGNvbnN0IGZpcnN0TGluZVBhcnRzID0gZmlyc3RMaW5lLnNwbGl0KCcgJyk7CiAgICAgIGNvbnN0IHN0YXR1c0NvZGUgPSArZmlyc3RMaW5lUGFydHNbMV07CiAgICAgIGNvbnN0IHN0YXR1c1RleHQgPSBmaXJzdExpbmVQYXJ0cy5zbGljZSgyKS5qb2luKCcgJyk7CiAgICAgIGNvbnN0IGhlYWRlcnMgPSB7fTsKICAgICAgZm9yIChjb25zdCBoZWFkZXIgb2YgaGVhZGVyUGFydHMpIHsKICAgICAgICBpZiAoIWhlYWRlcikgY29udGludWU7CiAgICAgICAgY29uc3QgZmlyc3RDb2xvbiA9IGhlYWRlci5pbmRleE9mKCc6Jyk7CiAgICAgICAgaWYgKGZpcnN0Q29sb24gPT09IC0xKSB7CiAgICAgICAgICBzb2NrZXQuZGVzdHJveSgpOwogICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoYEludmFsaWQgaGVhZGVyIGZyb20gcHJveHkgQ09OTkVDVCByZXNwb25zZTogIiR7aGVhZGVyfSJgKSk7CiAgICAgICAgfQogICAgICAgIGNvbnN0IGtleSA9IGhlYWRlci5zbGljZSgwLCBmaXJzdENvbG9uKS50b0xvd2VyQ2FzZSgpOwogICAgICAgIGNvbnN0IHZhbHVlID0gaGVhZGVyLnNsaWNlKGZpcnN0Q29sb24gKyAxKS50cmltU3RhcnQoKTsKICAgICAgICBjb25zdCBjdXJyZW50ID0gaGVhZGVyc1trZXldOwogICAgICAgIGlmICh0eXBlb2YgY3VycmVudCA9PT0gJ3N0cmluZycpIHsKICAgICAgICAgIGhlYWRlcnNba2V5XSA9IFtjdXJyZW50LCB2YWx1ZV07CiAgICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KGN1cnJlbnQpKSB7CiAgICAgICAgICBjdXJyZW50LnB1c2godmFsdWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBoZWFkZXJzW2tleV0gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgZGVidWckMSgnZ290IHByb3h5IHNlcnZlciByZXNwb25zZTogJW8gJW8nLCBmaXJzdExpbmUsIGhlYWRlcnMpOwogICAgICBjbGVhbnVwKCk7CiAgICAgIHJlc29sdmUoewogICAgICAgIGNvbm5lY3Q6IHsKICAgICAgICAgIHN0YXR1c0NvZGUsCiAgICAgICAgICBzdGF0dXNUZXh0LAogICAgICAgICAgaGVhZGVycywKICAgICAgICB9LAogICAgICAgIGJ1ZmZlcmVkLAogICAgICB9KTsKICAgIH0KCiAgICBzb2NrZXQub24oJ2Vycm9yJywgb25lcnJvcik7CiAgICBzb2NrZXQub24oJ2VuZCcsIG9uZW5kKTsKCiAgICByZWFkKCk7CiAgfSk7Cn0KCmZ1bmN0aW9uIF9udWxsaXNoQ29hbGVzY2UkMShsaHMsIHJoc0ZuKSB7IGlmIChsaHMgIT0gbnVsbCkgeyByZXR1cm4gbGhzOyB9IGVsc2UgeyByZXR1cm4gcmhzRm4oKTsgfSB9IGZ1bmN0aW9uIF9vcHRpb25hbENoYWluJDEob3BzKSB7IGxldCBsYXN0QWNjZXNzTEhTID0gdW5kZWZpbmVkOyBsZXQgdmFsdWUgPSBvcHNbMF07IGxldCBpID0gMTsgd2hpbGUgKGkgPCBvcHMubGVuZ3RoKSB7IGNvbnN0IG9wID0gb3BzW2ldOyBjb25zdCBmbiA9IG9wc1tpICsgMV07IGkgKz0gMjsgaWYgKChvcCA9PT0gJ29wdGlvbmFsQWNjZXNzJyB8fCBvcCA9PT0gJ29wdGlvbmFsQ2FsbCcpICYmIHZhbHVlID09IG51bGwpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSBpZiAob3AgPT09ICdhY2Nlc3MnIHx8IG9wID09PSAnb3B0aW9uYWxBY2Nlc3MnKSB7IGxhc3RBY2Nlc3NMSFMgPSB2YWx1ZTsgdmFsdWUgPSBmbih2YWx1ZSk7IH0gZWxzZSBpZiAob3AgPT09ICdjYWxsJyB8fCBvcCA9PT0gJ29wdGlvbmFsQ2FsbCcpIHsgdmFsdWUgPSBmbigoLi4uYXJncykgPT4gdmFsdWUuY2FsbChsYXN0QWNjZXNzTEhTLCAuLi5hcmdzKSk7IGxhc3RBY2Nlc3NMSFMgPSB1bmRlZmluZWQ7IH0gfSByZXR1cm4gdmFsdWU7IH0vKioKICogVGhpcyBjb2RlIHdhcyBvcmlnaW5hbGx5IGZvcmtlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9Ub29UYWxsTmF0ZS9wcm94eS1hZ2VudHMvdHJlZS9iMTMzMjk1ZmQxNmY2NDc1NTc4YjZiMTViZDliNGUzM2VjYjBkMGI3CiAqIFdpdGggdGhlIGZvbGxvd2luZyBsaWNlbmNlOgogKgogKiAoVGhlIE1JVCBMaWNlbnNlKQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTMgTmF0aGFuIFJhamxpY2ggPG5hdGhhbkB0b290YWxsbmF0ZS5uZXQ+KgogKgogKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcKICogYSBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlCiAqICdTb2Z0d2FyZScpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcKICogd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLAogKiBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8KICogcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvCiAqIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoqCiAqCiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlCiAqIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLioKICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICdBUyBJUycsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsCiAqIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRgogKiBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuCiAqIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZCiAqIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsCiAqIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFCiAqIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLgogKi8KCmZ1bmN0aW9uIGRlYnVnKC4uLmFyZ3MpIHsKICBsb2dnZXIubG9nKCdbaHR0cHMtcHJveHktYWdlbnRdJywgLi4uYXJncyk7Cn0KCi8qKgogKiBUaGUgYEh0dHBzUHJveHlBZ2VudGAgaW1wbGVtZW50cyBhbiBIVFRQIEFnZW50IHN1YmNsYXNzIHRoYXQgY29ubmVjdHMgdG8KICogdGhlIHNwZWNpZmllZCAiSFRUUChzKSBwcm94eSBzZXJ2ZXIiIGluIG9yZGVyIHRvIHByb3h5IEhUVFBTIHJlcXVlc3RzLgogKgogKiBPdXRnb2luZyBIVFRQIHJlcXVlc3RzIGFyZSBmaXJzdCB0dW5uZWxlZCB0aHJvdWdoIHRoZSBwcm94eSBzZXJ2ZXIgdXNpbmcgdGhlCiAqIGBDT05ORUNUYCBIVFRQIHJlcXVlc3QgbWV0aG9kIHRvIGVzdGFibGlzaCBhIGNvbm5lY3Rpb24gdG8gdGhlIHByb3h5IHNlcnZlciwKICogYW5kIHRoZW4gdGhlIHByb3h5IHNlcnZlciBjb25uZWN0cyB0byB0aGUgZGVzdGluYXRpb24gdGFyZ2V0IGFuZCBpc3N1ZXMgdGhlCiAqIEhUVFAgcmVxdWVzdCBmcm9tIHRoZSBwcm94eSBzZXJ2ZXIuCiAqCiAqIGBodHRwczpgIHJlcXVlc3RzIGhhdmUgdGhlaXIgc29ja2V0IGNvbm5lY3Rpb24gdXBncmFkZWQgdG8gVExTIG9uY2UKICogdGhlIGNvbm5lY3Rpb24gdG8gdGhlIHByb3h5IHNlcnZlciBoYXMgYmVlbiBlc3RhYmxpc2hlZC4KICovCmNsYXNzIEh0dHBzUHJveHlBZ2VudCBleHRlbmRzIEFnZW50IHsKICBzdGF0aWMgX19pbml0U3RhdGljKCkge3RoaXMucHJvdG9jb2xzID0gWydodHRwJywgJ2h0dHBzJ107IH0KCiAgY29uc3RydWN0b3IocHJveHksIG9wdHMpIHsKICAgIHN1cGVyKG9wdHMpOwogICAgdGhpcy5vcHRpb25zID0ge307CiAgICB0aGlzLnByb3h5ID0gdHlwZW9mIHByb3h5ID09PSAnc3RyaW5nJyA/IG5ldyBVUkwocHJveHkpIDogcHJveHk7CiAgICB0aGlzLnByb3h5SGVhZGVycyA9IF9udWxsaXNoQ29hbGVzY2UkMShfb3B0aW9uYWxDaGFpbiQxKFtvcHRzLCAnb3B0aW9uYWxBY2Nlc3MnLCBfMiA9PiBfMi5oZWFkZXJzXSksICgpID0+ICgge30pKTsKICAgIGRlYnVnKCdDcmVhdGluZyBuZXcgSHR0cHNQcm94eUFnZW50IGluc3RhbmNlOiAlbycsIHRoaXMucHJveHkuaHJlZik7CgogICAgLy8gVHJpbSBvZmYgdGhlIGJyYWNrZXRzIGZyb20gSVB2NiBhZGRyZXNzZXMKICAgIGNvbnN0IGhvc3QgPSAodGhpcy5wcm94eS5ob3N0bmFtZSB8fCB0aGlzLnByb3h5Lmhvc3QpLnJlcGxhY2UoL15cW3xcXSQvZywgJycpOwogICAgY29uc3QgcG9ydCA9IHRoaXMucHJveHkucG9ydCA/IHBhcnNlSW50KHRoaXMucHJveHkucG9ydCwgMTApIDogdGhpcy5wcm94eS5wcm90b2NvbCA9PT0gJ2h0dHBzOicgPyA0NDMgOiA4MDsKICAgIHRoaXMuY29ubmVjdE9wdHMgPSB7CiAgICAgIC8vIEF0dGVtcHQgdG8gbmVnb3RpYXRlIGh0dHAvMS4xIGZvciBwcm94eSBzZXJ2ZXJzIHRoYXQgc3VwcG9ydCBodHRwLzIKICAgICAgQUxQTlByb3RvY29sczogWydodHRwLzEuMSddLAogICAgICAuLi4ob3B0cyA/IG9taXQob3B0cywgJ2hlYWRlcnMnKSA6IG51bGwpLAogICAgICBob3N0LAogICAgICBwb3J0LAogICAgfTsKICB9CgogIC8qKgogICAqIENhbGxlZCB3aGVuIHRoZSBub2RlLWNvcmUgSFRUUCBjbGllbnQgbGlicmFyeSBpcyBjcmVhdGluZyBhCiAgICogbmV3IEhUVFAgcmVxdWVzdC4KICAgKi8KICBhc3luYyBjb25uZWN0KHJlcSwgb3B0cykgewogICAgY29uc3QgeyBwcm94eSB9ID0gdGhpczsKCiAgICBpZiAoIW9wdHMuaG9zdCkgewogICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdObyAiaG9zdCIgcHJvdmlkZWQnKTsKICAgIH0KCiAgICAvLyBDcmVhdGUgYSBzb2NrZXQgY29ubmVjdGlvbiB0byB0aGUgcHJveHkgc2VydmVyLgogICAgbGV0IHNvY2tldDsKICAgIGlmIChwcm94eS5wcm90b2NvbCA9PT0gJ2h0dHBzOicpIHsKICAgICAgZGVidWcoJ0NyZWF0aW5nIGB0bHMuU29ja2V0YDogJW8nLCB0aGlzLmNvbm5lY3RPcHRzKTsKICAgICAgY29uc3Qgc2VydmVybmFtZSA9IHRoaXMuY29ubmVjdE9wdHMuc2VydmVybmFtZSB8fCB0aGlzLmNvbm5lY3RPcHRzLmhvc3Q7CiAgICAgIHNvY2tldCA9IHRscy5jb25uZWN0KHsKICAgICAgICAuLi50aGlzLmNvbm5lY3RPcHRzLAogICAgICAgIHNlcnZlcm5hbWU6IHNlcnZlcm5hbWUgJiYgbmV0LmlzSVAoc2VydmVybmFtZSkgPyB1bmRlZmluZWQgOiBzZXJ2ZXJuYW1lLAogICAgICB9KTsKICAgIH0gZWxzZSB7CiAgICAgIGRlYnVnKCdDcmVhdGluZyBgbmV0LlNvY2tldGA6ICVvJywgdGhpcy5jb25uZWN0T3B0cyk7CiAgICAgIHNvY2tldCA9IG5ldC5jb25uZWN0KHRoaXMuY29ubmVjdE9wdHMpOwogICAgfQoKICAgIGNvbnN0IGhlYWRlcnMgPQogICAgICB0eXBlb2YgdGhpcy5wcm94eUhlYWRlcnMgPT09ICdmdW5jdGlvbicgPyB0aGlzLnByb3h5SGVhZGVycygpIDogeyAuLi50aGlzLnByb3h5SGVhZGVycyB9OwogICAgY29uc3QgaG9zdCA9IG5ldC5pc0lQdjYob3B0cy5ob3N0KSA/IGBbJHtvcHRzLmhvc3R9XWAgOiBvcHRzLmhvc3Q7CiAgICBsZXQgcGF5bG9hZCA9IGBDT05ORUNUICR7aG9zdH06JHtvcHRzLnBvcnR9IEhUVFAvMS4xXHJcbmA7CgogICAgLy8gSW5qZWN0IHRoZSBgUHJveHktQXV0aG9yaXphdGlvbmAgaGVhZGVyIGlmIG5lY2Vzc2FyeS4KICAgIGlmIChwcm94eS51c2VybmFtZSB8fCBwcm94eS5wYXNzd29yZCkgewogICAgICBjb25zdCBhdXRoID0gYCR7ZGVjb2RlVVJJQ29tcG9uZW50KHByb3h5LnVzZXJuYW1lKX06JHtkZWNvZGVVUklDb21wb25lbnQocHJveHkucGFzc3dvcmQpfWA7CiAgICAgIGhlYWRlcnNbJ1Byb3h5LUF1dGhvcml6YXRpb24nXSA9IGBCYXNpYyAke0J1ZmZlci5mcm9tKGF1dGgpLnRvU3RyaW5nKCdiYXNlNjQnKX1gOwogICAgfQoKICAgIGhlYWRlcnMuSG9zdCA9IGAke2hvc3R9OiR7b3B0cy5wb3J0fWA7CgogICAgaWYgKCFoZWFkZXJzWydQcm94eS1Db25uZWN0aW9uJ10pIHsKICAgICAgaGVhZGVyc1snUHJveHktQ29ubmVjdGlvbiddID0gdGhpcy5rZWVwQWxpdmUgPyAnS2VlcC1BbGl2ZScgOiAnY2xvc2UnOwogICAgfQogICAgZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKGhlYWRlcnMpKSB7CiAgICAgIHBheWxvYWQgKz0gYCR7bmFtZX06ICR7aGVhZGVyc1tuYW1lXX1cclxuYDsKICAgIH0KCiAgICBjb25zdCBwcm94eVJlc3BvbnNlUHJvbWlzZSA9IHBhcnNlUHJveHlSZXNwb25zZShzb2NrZXQpOwoKICAgIHNvY2tldC53cml0ZShgJHtwYXlsb2FkfVxyXG5gKTsKCiAgICBjb25zdCB7IGNvbm5lY3QsIGJ1ZmZlcmVkIH0gPSBhd2FpdCBwcm94eVJlc3BvbnNlUHJvbWlzZTsKICAgIHJlcS5lbWl0KCdwcm94eUNvbm5lY3QnLCBjb25uZWN0KTsKICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvYmFuLXRzLWNvbW1lbnQKICAgIC8vIEB0cy1pZ25vcmUgTm90IEV2ZW50RW1pdHRlciBpbiBOb2RlIHR5cGVzCiAgICB0aGlzLmVtaXQoJ3Byb3h5Q29ubmVjdCcsIGNvbm5lY3QsIHJlcSk7CgogICAgaWYgKGNvbm5lY3Quc3RhdHVzQ29kZSA9PT0gMjAwKSB7CiAgICAgIHJlcS5vbmNlKCdzb2NrZXQnLCByZXN1bWUpOwoKICAgICAgaWYgKG9wdHMuc2VjdXJlRW5kcG9pbnQpIHsKICAgICAgICAvLyBUaGUgcHJveHkgaXMgY29ubmVjdGluZyB0byBhIFRMUyBzZXJ2ZXIsIHNvIHVwZ3JhZGUKICAgICAgICAvLyB0aGlzIHNvY2tldCBjb25uZWN0aW9uIHRvIGEgVExTIGNvbm5lY3Rpb24uCiAgICAgICAgZGVidWcoJ1VwZ3JhZGluZyBzb2NrZXQgY29ubmVjdGlvbiB0byBUTFMnKTsKICAgICAgICBjb25zdCBzZXJ2ZXJuYW1lID0gb3B0cy5zZXJ2ZXJuYW1lIHx8IG9wdHMuaG9zdDsKICAgICAgICByZXR1cm4gdGxzLmNvbm5lY3QoewogICAgICAgICAgLi4ub21pdChvcHRzLCAnaG9zdCcsICdwYXRoJywgJ3BvcnQnKSwKICAgICAgICAgIHNvY2tldCwKICAgICAgICAgIHNlcnZlcm5hbWU6IG5ldC5pc0lQKHNlcnZlcm5hbWUpID8gdW5kZWZpbmVkIDogc2VydmVybmFtZSwKICAgICAgICB9KTsKICAgICAgfQoKICAgICAgcmV0dXJuIHNvY2tldDsKICAgIH0KCiAgICAvLyBTb21lIG90aGVyIHN0YXR1cyBjb2RlIHRoYXQncyBub3QgMjAwLi4uIG5lZWQgdG8gcmUtcGxheSB0aGUgSFRUUAogICAgLy8gaGVhZGVyICJkYXRhIiBldmVudHMgb250byB0aGUgc29ja2V0IG9uY2UgdGhlIEhUVFAgbWFjaGluZXJ5IGlzCiAgICAvLyBhdHRhY2hlZCBzbyB0aGF0IHRoZSBub2RlIGNvcmUgYGh0dHBgIGNhbiBwYXJzZSBhbmQgaGFuZGxlIHRoZQogICAgLy8gZXJyb3Igc3RhdHVzIGNvZGUuCgogICAgLy8gQ2xvc2UgdGhlIG9yaWdpbmFsIHNvY2tldCwgYW5kIGEgbmV3ICJmYWtlIiBzb2NrZXQgaXMgcmV0dXJuZWQKICAgIC8vIGluc3RlYWQsIHNvIHRoYXQgdGhlIHByb3h5IGRvZXNuJ3QgZ2V0IHRoZSBIVFRQIHJlcXVlc3QKICAgIC8vIHdyaXR0ZW4gdG8gaXQgKHdoaWNoIG1heSBjb250YWluIGBBdXRob3JpemF0aW9uYCBoZWFkZXJzIG9yIG90aGVyCiAgICAvLyBzZW5zaXRpdmUgZGF0YSkuCiAgICAvLwogICAgLy8gU2VlOiBodHRwczovL2hhY2tlcm9uZS5jb20vcmVwb3J0cy81NDE1MDIKICAgIHNvY2tldC5kZXN0cm95KCk7CgogICAgY29uc3QgZmFrZVNvY2tldCA9IG5ldyBuZXQuU29ja2V0KHsgd3JpdGFibGU6IGZhbHNlIH0pOwogICAgZmFrZVNvY2tldC5yZWFkYWJsZSA9IHRydWU7CgogICAgLy8gTmVlZCB0byB3YWl0IGZvciB0aGUgInNvY2tldCIgZXZlbnQgdG8gcmUtcGxheSB0aGUgImRhdGEiIGV2ZW50cy4KICAgIHJlcS5vbmNlKCdzb2NrZXQnLCAocykgPT4gewogICAgICBkZWJ1ZygnUmVwbGF5aW5nIHByb3h5IGJ1ZmZlciBmb3IgZmFpbGVkIHJlcXVlc3QnKTsKICAgICAgYXNzZXJ0KHMubGlzdGVuZXJDb3VudCgnZGF0YScpID4gMCk7CgogICAgICAvLyBSZXBsYXkgdGhlICJidWZmZXJlZCIgQnVmZmVyIG9udG8gdGhlIGZha2UgYHNvY2tldGAsIHNpbmNlIGF0CiAgICAgIC8vIHRoaXMgcG9pbnQgdGhlIEhUVFAgbW9kdWxlIG1hY2hpbmVyeSBoYXMgYmVlbiBob29rZWQgdXAgZm9yCiAgICAgIC8vIHRoZSB1c2VyLgogICAgICBzLnB1c2goYnVmZmVyZWQpOwogICAgICBzLnB1c2gobnVsbCk7CiAgICB9KTsKCiAgICByZXR1cm4gZmFrZVNvY2tldDsKICB9Cn0gSHR0cHNQcm94eUFnZW50Ll9faW5pdFN0YXRpYygpOwoKZnVuY3Rpb24gcmVzdW1lKHNvY2tldCkgewogIHNvY2tldC5yZXN1bWUoKTsKfQoKZnVuY3Rpb24gb21pdCgKICBvYmosCiAgLi4ua2V5cwopCgogewogIGNvbnN0IHJldCA9IHt9Cgo7CiAgbGV0IGtleTsKICBmb3IgKGtleSBpbiBvYmopIHsKICAgIGlmICgha2V5cy5pbmNsdWRlcyhrZXkpKSB7CiAgICAgIHJldFtrZXldID0gb2JqW2tleV07CiAgICB9CiAgfQogIHJldHVybiByZXQ7Cn0KCmZ1bmN0aW9uIF9udWxsaXNoQ29hbGVzY2UobGhzLCByaHNGbikgeyBpZiAobGhzICE9IG51bGwpIHsgcmV0dXJuIGxoczsgfSBlbHNlIHsgcmV0dXJuIHJoc0ZuKCk7IH0gfQovLyBFc3RpbWF0ZWQgbWF4aW11bSBzaXplIGZvciByZWFzb25hYmxlIHN0YW5kYWxvbmUgZXZlbnQKY29uc3QgR1pJUF9USFJFU0hPTEQgPSAxMDI0ICogMzI7CgovKioKICogR2V0cyBhIHN0cmVhbSBmcm9tIGEgVWludDhBcnJheSBvciBzdHJpbmcKICogUmVhZGFibGUuZnJvbSBpcyBpZGVhbCBidXQgd2FzIGFkZGVkIGluIG5vZGUuanMgdjEyLjMuMCBhbmQgdjEwLjE3LjAKICovCmZ1bmN0aW9uIHN0cmVhbUZyb21Cb2R5KGJvZHkpIHsKICByZXR1cm4gbmV3IFJlYWRhYmxlKHsKICAgIHJlYWQoKSB7CiAgICAgIHRoaXMucHVzaChib2R5KTsKICAgICAgdGhpcy5wdXNoKG51bGwpOwogICAgfSwKICB9KTsKfQoKLyoqCiAqIENyZWF0ZXMgYSBUcmFuc3BvcnQgdGhhdCB1c2VzIG5hdGl2ZSB0aGUgbmF0aXZlICdodHRwJyBhbmQgJ2h0dHBzJyBtb2R1bGVzIHRvIHNlbmQgZXZlbnRzIHRvIFNlbnRyeS4KICovCmZ1bmN0aW9uIG1ha2VOb2RlVHJhbnNwb3J0KG9wdGlvbnMpIHsKICBsZXQgdXJsU2VnbWVudHM7CgogIHRyeSB7CiAgICB1cmxTZWdtZW50cyA9IG5ldyBVUkwob3B0aW9ucy51cmwpOwogIH0gY2F0Y2ggKGUpIHsKICAgIGNvbnNvbGVTYW5kYm94KCgpID0+IHsKICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGUKICAgICAgY29uc29sZS53YXJuKAogICAgICAgICdbQHNlbnRyeS9ub2RlXTogSW52YWxpZCBkc24gb3IgdHVubmVsIG9wdGlvbiwgd2lsbCBub3Qgc2VuZCBhbnkgZXZlbnRzLiBUaGUgdHVubmVsIG9wdGlvbiBtdXN0IGJlIGEgZnVsbCBVUkwgd2hlbiB1c2VkLicsCiAgICAgICk7CiAgICB9KTsKICAgIHJldHVybiBjcmVhdGVUcmFuc3BvcnQob3B0aW9ucywgKCkgPT4gUHJvbWlzZS5yZXNvbHZlKHt9KSk7CiAgfQoKICBjb25zdCBpc0h0dHBzID0gdXJsU2VnbWVudHMucHJvdG9jb2wgPT09ICdodHRwczonOwoKICAvLyBQcm94eSBwcmlvcml0aXphdGlvbjogaHR0cCA9PiBgb3B0aW9ucy5wcm94eWAgfCBgcHJvY2Vzcy5lbnYuaHR0cF9wcm94eWAKICAvLyBQcm94eSBwcmlvcml0aXphdGlvbjogaHR0cHMgPT4gYG9wdGlvbnMucHJveHlgIHwgYHByb2Nlc3MuZW52Lmh0dHBzX3Byb3h5YCB8IGBwcm9jZXNzLmVudi5odHRwX3Byb3h5YAogIGNvbnN0IHByb3h5ID0gYXBwbHlOb1Byb3h5T3B0aW9uKAogICAgdXJsU2VnbWVudHMsCiAgICBvcHRpb25zLnByb3h5IHx8IChpc0h0dHBzID8gcHJvY2Vzcy5lbnYuaHR0cHNfcHJveHkgOiB1bmRlZmluZWQpIHx8IHByb2Nlc3MuZW52Lmh0dHBfcHJveHksCiAgKTsKCiAgY29uc3QgbmF0aXZlSHR0cE1vZHVsZSA9IGlzSHR0cHMgPyBodHRwcyA6IGh0dHA7CiAgY29uc3Qga2VlcEFsaXZlID0gb3B0aW9ucy5rZWVwQWxpdmUgPT09IHVuZGVmaW5lZCA/IGZhbHNlIDogb3B0aW9ucy5rZWVwQWxpdmU7CgogIC8vIFRPRE8odjcpOiBFdmFsdWF0ZSBpZiB3ZSBjYW4gc2V0IGtlZXBBbGl2ZSB0byB0cnVlLiBUaGlzIHdvdWxkIGludm9sdmUgdGVzdGluZyBmb3IgbWVtb3J5IGxlYWtzIGluIG9sZGVyIG5vZGUKICAvLyB2ZXJzaW9ucyg+PSA4KSBhcyB0aGV5IGhhZCBtZW1vcnkgbGVha3Mgd2hlbiB1c2luZyBpdDogIzI1NTUKICBjb25zdCBhZ2VudCA9IHByb3h5CiAgICA/IChuZXcgSHR0cHNQcm94eUFnZW50KHByb3h5KSApCiAgICA6IG5ldyBuYXRpdmVIdHRwTW9kdWxlLkFnZW50KHsga2VlcEFsaXZlLCBtYXhTb2NrZXRzOiAzMCwgdGltZW91dDogMjAwMCB9KTsKCiAgY29uc3QgcmVxdWVzdEV4ZWN1dG9yID0gY3JlYXRlUmVxdWVzdEV4ZWN1dG9yKG9wdGlvbnMsIF9udWxsaXNoQ29hbGVzY2Uob3B0aW9ucy5odHRwTW9kdWxlLCAoKSA9PiAoIG5hdGl2ZUh0dHBNb2R1bGUpKSwgYWdlbnQpOwogIHJldHVybiBjcmVhdGVUcmFuc3BvcnQob3B0aW9ucywgcmVxdWVzdEV4ZWN1dG9yKTsKfQoKLyoqCiAqIEhvbm9ycyB0aGUgYG5vX3Byb3h5YCBlbnYgdmFyaWFibGUgd2l0aCB0aGUgaGlnaGVzdCBwcmlvcml0eSB0byBhbGxvdyBmb3IgaG9zdHMgZXhjbHVzaW9uLgogKgogKiBAcGFyYW0gdHJhbnNwb3J0VXJsIFRoZSBVUkwgdGhlIHRyYW5zcG9ydCBpbnRlbmRzIHRvIHNlbmQgZXZlbnRzIHRvLgogKiBAcGFyYW0gcHJveHkgVGhlIGNsaWVudCBjb25maWd1cmVkIHByb3h5LgogKiBAcmV0dXJucyBBIHByb3h5IHRoZSB0cmFuc3BvcnQgc2hvdWxkIHVzZS4KICovCmZ1bmN0aW9uIGFwcGx5Tm9Qcm94eU9wdGlvbih0cmFuc3BvcnRVcmxTZWdtZW50cywgcHJveHkpIHsKICBjb25zdCB7IG5vX3Byb3h5IH0gPSBwcm9jZXNzLmVudjsKCiAgY29uc3QgdXJsSXNFeGVtcHRGcm9tUHJveHkgPQogICAgbm9fcHJveHkgJiYKICAgIG5vX3Byb3h5CiAgICAgIC5zcGxpdCgnLCcpCiAgICAgIC5zb21lKAogICAgICAgIGV4ZW1wdGlvbiA9PiB0cmFuc3BvcnRVcmxTZWdtZW50cy5ob3N0LmVuZHNXaXRoKGV4ZW1wdGlvbikgfHwgdHJhbnNwb3J0VXJsU2VnbWVudHMuaG9zdG5hbWUuZW5kc1dpdGgoZXhlbXB0aW9uKSwKICAgICAgKTsKCiAgaWYgKHVybElzRXhlbXB0RnJvbVByb3h5KSB7CiAgICByZXR1cm4gdW5kZWZpbmVkOwogIH0gZWxzZSB7CiAgICByZXR1cm4gcHJveHk7CiAgfQp9CgovKioKICogQ3JlYXRlcyBhIFJlcXVlc3RFeGVjdXRvciB0byBiZSB1c2VkIHdpdGggYGNyZWF0ZVRyYW5zcG9ydGAuCiAqLwpmdW5jdGlvbiBjcmVhdGVSZXF1ZXN0RXhlY3V0b3IoCiAgb3B0aW9ucywKICBodHRwTW9kdWxlLAogIGFnZW50LAopIHsKICBjb25zdCB7IGhvc3RuYW1lLCBwYXRobmFtZSwgcG9ydCwgcHJvdG9jb2wsIHNlYXJjaCB9ID0gbmV3IFVSTChvcHRpb25zLnVybCk7CiAgcmV0dXJuIGZ1bmN0aW9uIG1ha2VSZXF1ZXN0KHJlcXVlc3QpIHsKICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7CiAgICAgIGxldCBib2R5ID0gc3RyZWFtRnJvbUJvZHkocmVxdWVzdC5ib2R5KTsKCiAgICAgIGNvbnN0IGhlYWRlcnMgPSB7IC4uLm9wdGlvbnMuaGVhZGVycyB9OwoKICAgICAgaWYgKHJlcXVlc3QuYm9keS5sZW5ndGggPiBHWklQX1RIUkVTSE9MRCkgewogICAgICAgIGhlYWRlcnNbJ2NvbnRlbnQtZW5jb2RpbmcnXSA9ICdnemlwJzsKICAgICAgICBib2R5ID0gYm9keS5waXBlKGNyZWF0ZUd6aXAoKSk7CiAgICAgIH0KCiAgICAgIGNvbnN0IHJlcSA9IGh0dHBNb2R1bGUucmVxdWVzdCgKICAgICAgICB7CiAgICAgICAgICBtZXRob2Q6ICdQT1NUJywKICAgICAgICAgIGFnZW50LAogICAgICAgICAgaGVhZGVycywKICAgICAgICAgIGhvc3RuYW1lLAogICAgICAgICAgcGF0aDogYCR7cGF0aG5hbWV9JHtzZWFyY2h9YCwKICAgICAgICAgIHBvcnQsCiAgICAgICAgICBwcm90b2NvbCwKICAgICAgICAgIGNhOiBvcHRpb25zLmNhQ2VydHMsCiAgICAgICAgfSwKICAgICAgICByZXMgPT4gewogICAgICAgICAgcmVzLm9uKCdkYXRhJywgKCkgPT4gewogICAgICAgICAgICAvLyBEcmFpbiBzb2NrZXQKICAgICAgICAgIH0pOwoKICAgICAgICAgIHJlcy5vbignZW5kJywgKCkgPT4gewogICAgICAgICAgICAvLyBEcmFpbiBzb2NrZXQKICAgICAgICAgIH0pOwoKICAgICAgICAgIHJlcy5zZXRFbmNvZGluZygndXRmOCcpOwoKICAgICAgICAgIC8vICJLZXktdmFsdWUgcGFpcnMgb2YgaGVhZGVyIG5hbWVzIGFuZCB2YWx1ZXMuIEhlYWRlciBuYW1lcyBhcmUgbG93ZXItY2FzZWQuIgogICAgICAgICAgLy8gaHR0cHM6Ly9ub2RlanMub3JnL2FwaS9odHRwLmh0bWwjaHR0cF9tZXNzYWdlX2hlYWRlcnMKICAgICAgICAgIGNvbnN0IHJldHJ5QWZ0ZXJIZWFkZXIgPSBfbnVsbGlzaENvYWxlc2NlKHJlcy5oZWFkZXJzWydyZXRyeS1hZnRlciddLCAoKSA9PiAoIG51bGwpKTsKICAgICAgICAgIGNvbnN0IHJhdGVMaW1pdHNIZWFkZXIgPSBfbnVsbGlzaENvYWxlc2NlKHJlcy5oZWFkZXJzWyd4LXNlbnRyeS1yYXRlLWxpbWl0cyddLCAoKSA9PiAoIG51bGwpKTsKCiAgICAgICAgICByZXNvbHZlKHsKICAgICAgICAgICAgc3RhdHVzQ29kZTogcmVzLnN0YXR1c0NvZGUsCiAgICAgICAgICAgIGhlYWRlcnM6IHsKICAgICAgICAgICAgICAncmV0cnktYWZ0ZXInOiByZXRyeUFmdGVySGVhZGVyLAogICAgICAgICAgICAgICd4LXNlbnRyeS1yYXRlLWxpbWl0cyc6IEFycmF5LmlzQXJyYXkocmF0ZUxpbWl0c0hlYWRlcikgPyByYXRlTGltaXRzSGVhZGVyWzBdIDogcmF0ZUxpbWl0c0hlYWRlciwKICAgICAgICAgICAgfSwKICAgICAgICAgIH0pOwogICAgICAgIH0sCiAgICAgICk7CgogICAgICByZXEub24oJ2Vycm9yJywgcmVqZWN0KTsKICAgICAgYm9keS5waXBlKHJlcSk7CiAgICB9KTsKICB9Owp9CgpmdW5jdGlvbiBfb3B0aW9uYWxDaGFpbihvcHMpIHsgbGV0IGxhc3RBY2Nlc3NMSFMgPSB1bmRlZmluZWQ7IGxldCB2YWx1ZSA9IG9wc1swXTsgbGV0IGkgPSAxOyB3aGlsZSAoaSA8IG9wcy5sZW5ndGgpIHsgY29uc3Qgb3AgPSBvcHNbaV07IGNvbnN0IGZuID0gb3BzW2kgKyAxXTsgaSArPSAyOyBpZiAoKG9wID09PSAnb3B0aW9uYWxBY2Nlc3MnIHx8IG9wID09PSAnb3B0aW9uYWxDYWxsJykgJiYgdmFsdWUgPT0gbnVsbCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IGlmIChvcCA9PT0gJ2FjY2VzcycgfHwgb3AgPT09ICdvcHRpb25hbEFjY2VzcycpIHsgbGFzdEFjY2Vzc0xIUyA9IHZhbHVlOyB2YWx1ZSA9IGZuKHZhbHVlKTsgfSBlbHNlIGlmIChvcCA9PT0gJ2NhbGwnIHx8IG9wID09PSAnb3B0aW9uYWxDYWxsJykgeyB2YWx1ZSA9IGZuKCguLi5hcmdzKSA9PiB2YWx1ZS5jYWxsKGxhc3RBY2Nlc3NMSFMsIC4uLmFyZ3MpKTsgbGFzdEFjY2Vzc0xIUyA9IHVuZGVmaW5lZDsgfSB9IHJldHVybiB2YWx1ZTsgfQpjb25zdCBvcHRpb25zID0gd29ya2VyRGF0YTsKbGV0IHNlc3Npb247CmxldCBoYXNTZW50QW5yRXZlbnQgPSBmYWxzZTsKCmZ1bmN0aW9uIGxvZyhtc2cpIHsKICBpZiAob3B0aW9ucy5kZWJ1ZykgewogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGUKICAgIGNvbnNvbGUubG9nKGBbQU5SIFdvcmtlcl0gJHttc2d9YCk7CiAgfQp9Cgpjb25zdCB1cmwgPSBnZXRFbnZlbG9wZUVuZHBvaW50V2l0aFVybEVuY29kZWRBdXRoKG9wdGlvbnMuZHNuKTsKY29uc3QgdHJhbnNwb3J0ID0gbWFrZU5vZGVUcmFuc3BvcnQoewogIHVybCwKICByZWNvcmREcm9wcGVkRXZlbnQ6ICgpID0+IHsKICAgIC8vCiAgfSwKfSk7Cgphc3luYyBmdW5jdGlvbiBzZW5kQWJub3JtYWxTZXNzaW9uKCkgewogIC8vIG9mIHdlIGhhdmUgYW4gZXhpc3Rpbmcgc2Vzc2lvbiBwYXNzZWQgZnJvbSB0aGUgbWFpbiB0aHJlYWQsIHNlbmQgaXQgYXMgYWJub3JtYWwKICBpZiAoc2Vzc2lvbikgewogICAgbG9nKCdTZW5kaW5nIGFibm9ybWFsIHNlc3Npb24nKTsKICAgIHVwZGF0ZVNlc3Npb24oc2Vzc2lvbiwgeyBzdGF0dXM6ICdhYm5vcm1hbCcsIGFibm9ybWFsX21lY2hhbmlzbTogJ2Fucl9mb3JlZ3JvdW5kJyB9KTsKCiAgICBjb25zdCBlbnZlbG9wZSA9IGNyZWF0ZVNlc3Npb25FbnZlbG9wZShzZXNzaW9uLCBvcHRpb25zLmRzbiwgb3B0aW9ucy5zZGtNZXRhZGF0YSk7CiAgICAvLyBMb2cgdGhlIGVudmVsb3BlIHNvIHRvIGFpZCBpbiB0ZXN0aW5nCiAgICBsb2coSlNPTi5zdHJpbmdpZnkoZW52ZWxvcGUpKTsKCiAgICBhd2FpdCB0cmFuc3BvcnQuc2VuZChlbnZlbG9wZSk7CgogICAgdHJ5IHsKICAgICAgLy8gTm90aWZ5IHRoZSBtYWluIHByb2Nlc3MgdGhhdCB0aGUgc2Vzc2lvbiBoYXMgZW5kZWQgc28gdGhlIHNlc3Npb24gY2FuIGJlIGNsZWFyZWQgZnJvbSB0aGUgc2NvcGUKICAgICAgX29wdGlvbmFsQ2hhaW4oW3BhcmVudFBvcnQsICdvcHRpb25hbEFjY2VzcycsIF8yID0+IF8yLnBvc3RNZXNzYWdlLCAnY2FsbCcsIF8zID0+IF8zKCdzZXNzaW9uLWVuZGVkJyldKTsKICAgIH0gY2F0Y2ggKF8pIHsKICAgICAgLy8gaWdub3JlCiAgICB9CiAgfQp9Cgpsb2coJ1N0YXJ0ZWQnKTsKCmZ1bmN0aW9uIHByZXBhcmVTdGFja0ZyYW1lcyhzdGFja0ZyYW1lcykgewogIGlmICghc3RhY2tGcmFtZXMpIHsKICAgIHJldHVybiB1bmRlZmluZWQ7CiAgfQoKICAvLyBTdHJpcCBTZW50cnkgZnJhbWVzIGFuZCByZXZlcnNlIHRoZSBzdGFjayBmcmFtZXMgc28gdGhleSBhcmUgaW4gdGhlIGNvcnJlY3Qgb3JkZXIKICBjb25zdCBzdHJpcHBlZEZyYW1lcyA9IHN0cmlwU2VudHJ5RnJhbWVzQW5kUmV2ZXJzZShzdGFja0ZyYW1lcyk7CgogIC8vIElmIHdlIGhhdmUgYW4gYXBwIHJvb3QgcGF0aCwgcmV3cml0ZSB0aGUgZmlsZW5hbWVzIHRvIGJlIHJlbGF0aXZlIHRvIHRoZSBhcHAgcm9vdAogIGlmIChvcHRpb25zLmFwcFJvb3RQYXRoKSB7CiAgICBmb3IgKGNvbnN0IGZyYW1lIG9mIHN0cmlwcGVkRnJhbWVzKSB7CiAgICAgIGlmICghZnJhbWUuZmlsZW5hbWUpIHsKICAgICAgICBjb250aW51ZTsKICAgICAgfQoKICAgICAgZnJhbWUuZmlsZW5hbWUgPSBub3JtYWxpemVVcmxUb0Jhc2UoZnJhbWUuZmlsZW5hbWUsIG9wdGlvbnMuYXBwUm9vdFBhdGgpOwogICAgfQogIH0KCiAgcmV0dXJuIHN0cmlwcGVkRnJhbWVzOwp9Cgphc3luYyBmdW5jdGlvbiBzZW5kQW5yRXZlbnQoZnJhbWVzLCB0cmFjZUNvbnRleHQpIHsKICBpZiAoaGFzU2VudEFuckV2ZW50KSB7CiAgICByZXR1cm47CiAgfQoKICBoYXNTZW50QW5yRXZlbnQgPSB0cnVlOwoKICBhd2FpdCBzZW5kQWJub3JtYWxTZXNzaW9uKCk7CgogIGxvZygnU2VuZGluZyBldmVudCcpOwoKICBjb25zdCBldmVudCA9IHsKICAgIGV2ZW50X2lkOiB1dWlkNCgpLAogICAgY29udGV4dHM6IHsgLi4ub3B0aW9ucy5jb250ZXh0cywgdHJhY2U6IHRyYWNlQ29udGV4dCB9LAogICAgcmVsZWFzZTogb3B0aW9ucy5yZWxlYXNlLAogICAgZW52aXJvbm1lbnQ6IG9wdGlvbnMuZW52aXJvbm1lbnQsCiAgICBkaXN0OiBvcHRpb25zLmRpc3QsCiAgICBwbGF0Zm9ybTogJ25vZGUnLAogICAgbGV2ZWw6ICdlcnJvcicsCiAgICBleGNlcHRpb246IHsKICAgICAgdmFsdWVzOiBbCiAgICAgICAgewogICAgICAgICAgdHlwZTogJ0FwcGxpY2F0aW9uTm90UmVzcG9uZGluZycsCiAgICAgICAgICB2YWx1ZTogYEFwcGxpY2F0aW9uIE5vdCBSZXNwb25kaW5nIGZvciBhdCBsZWFzdCAke29wdGlvbnMuYW5yVGhyZXNob2xkfSBtc2AsCiAgICAgICAgICBzdGFja3RyYWNlOiB7IGZyYW1lczogcHJlcGFyZVN0YWNrRnJhbWVzKGZyYW1lcykgfSwKICAgICAgICAgIC8vIFRoaXMgZW5zdXJlcyB0aGUgVUkgZG9lc24ndCBzYXkgJ0NyYXNoZWQgaW4nIGZvciB0aGUgc3RhY2sgdHJhY2UKICAgICAgICAgIG1lY2hhbmlzbTogeyB0eXBlOiAnQU5SJyB9LAogICAgICAgIH0sCiAgICAgIF0sCiAgICB9LAogICAgdGFnczogb3B0aW9ucy5zdGF0aWNUYWdzLAogIH07CgogIGNvbnN0IGVudmVsb3BlID0gY3JlYXRlRXZlbnRFbnZlbG9wZShldmVudCwgb3B0aW9ucy5kc24sIG9wdGlvbnMuc2RrTWV0YWRhdGEpOwogIC8vIExvZyB0aGUgZW52ZWxvcGUgc28gdG8gYWlkIGluIHRlc3RpbmcKICBsb2coSlNPTi5zdHJpbmdpZnkoZW52ZWxvcGUpKTsKCiAgYXdhaXQgdHJhbnNwb3J0LnNlbmQoZW52ZWxvcGUpOwogIGF3YWl0IHRyYW5zcG9ydC5mbHVzaCgyMDAwKTsKCiAgLy8gRGVsYXkgZm9yIDUgc2Vjb25kcyBzbyB0aGF0IHN0ZGlvIGNhbiBmbHVzaCBpbiB0aGUgbWFpbiBldmVudCBsb29wIGV2ZXIgcmVzdGFydHMuCiAgLy8gVGhpcyBpcyBtYWlubHkgZm9yIHRoZSBiZW5lZml0IG9mIGxvZ2dpbmcvZGVidWdnaW5nIGlzc3Vlcy4KICBzZXRUaW1lb3V0KCgpID0+IHsKICAgIHByb2Nlc3MuZXhpdCgwKTsKICB9LCA1MDAwKTsKfQoKbGV0IGRlYnVnZ2VyUGF1c2U7CgppZiAob3B0aW9ucy5jYXB0dXJlU3RhY2tUcmFjZSkgewogIGxvZygnQ29ubmVjdGluZyB0byBkZWJ1Z2dlcicpOwoKICBjb25zdCBzZXNzaW9uID0gbmV3IFNlc3Npb24oKSA7CiAgc2Vzc2lvbi5jb25uZWN0VG9NYWluVGhyZWFkKCk7CgogIGxvZygnQ29ubmVjdGVkIHRvIGRlYnVnZ2VyJyk7CgogIC8vIENvbGxlY3Qgc2NyaXB0SWQgLT4gdXJsIG1hcCBzbyB3ZSBjYW4gbG9vayB1cCB0aGUgZmlsZW5hbWVzIGxhdGVyCiAgY29uc3Qgc2NyaXB0cyA9IG5ldyBNYXAoKTsKCiAgc2Vzc2lvbi5vbignRGVidWdnZXIuc2NyaXB0UGFyc2VkJywgZXZlbnQgPT4gewogICAgc2NyaXB0cy5zZXQoZXZlbnQucGFyYW1zLnNjcmlwdElkLCBldmVudC5wYXJhbXMudXJsKTsKICB9KTsKCiAgc2Vzc2lvbi5vbignRGVidWdnZXIucGF1c2VkJywgZXZlbnQgPT4gewogICAgaWYgKGV2ZW50LnBhcmFtcy5yZWFzb24gIT09ICdvdGhlcicpIHsKICAgICAgcmV0dXJuOwogICAgfQoKICAgIHRyeSB7CiAgICAgIGxvZygnRGVidWdnZXIgcGF1c2VkJyk7CgogICAgICAvLyBjb3B5IHRoZSBmcmFtZXMKICAgICAgY29uc3QgY2FsbEZyYW1lcyA9IFsuLi5ldmVudC5wYXJhbXMuY2FsbEZyYW1lc107CgogICAgICBjb25zdCBnZXRNb2R1bGVOYW1lID0gb3B0aW9ucy5hcHBSb290UGF0aCA/IGNyZWF0ZUdldE1vZHVsZUZyb21GaWxlbmFtZShvcHRpb25zLmFwcFJvb3RQYXRoKSA6ICgpID0+IHVuZGVmaW5lZDsKICAgICAgY29uc3Qgc3RhY2tGcmFtZXMgPSBjYWxsRnJhbWVzLm1hcChmcmFtZSA9PgogICAgICAgIGNhbGxGcmFtZVRvU3RhY2tGcmFtZShmcmFtZSwgc2NyaXB0cy5nZXQoZnJhbWUubG9jYXRpb24uc2NyaXB0SWQpLCBnZXRNb2R1bGVOYW1lKSwKICAgICAgKTsKCiAgICAgIC8vIEV2YWx1YXRlIGEgc2NyaXB0IGluIHRoZSBjdXJyZW50bHkgcGF1c2VkIGNvbnRleHQKICAgICAgc2Vzc2lvbi5wb3N0KAogICAgICAgICdSdW50aW1lLmV2YWx1YXRlJywKICAgICAgICB7CiAgICAgICAgICAvLyBHcmFiIHRoZSB0cmFjZSBjb250ZXh0IGZyb20gdGhlIGN1cnJlbnQgc2NvcGUKICAgICAgICAgIGV4cHJlc3Npb246CiAgICAgICAgICAgICdjb25zdCBjdHggPSBfX1NFTlRSWV9fLmh1Yi5nZXRTY29wZSgpLmdldFByb3BhZ2F0aW9uQ29udGV4dCgpOyBjdHgudHJhY2VJZCArICItIiArIGN0eC5zcGFuSWQgKyAiLSIgKyBjdHgucGFyZW50U3BhbklkJywKICAgICAgICAgIC8vIERvbid0IHJlLXRyaWdnZXIgdGhlIGRlYnVnZ2VyIGlmIHRoaXMgY2F1c2VzIGFuIGVycm9yCiAgICAgICAgICBzaWxlbnQ6IHRydWUsCiAgICAgICAgfSwKICAgICAgICAoXywgcGFyYW0pID0+IHsKICAgICAgICAgIGNvbnN0IHRyYWNlSWQgPSBwYXJhbSAmJiBwYXJhbS5yZXN1bHQgPyAocGFyYW0ucmVzdWx0LnZhbHVlICkgOiAnLS0nOwogICAgICAgICAgY29uc3QgW3RyYWNlX2lkLCBzcGFuX2lkLCBwYXJlbnRfc3Bhbl9pZF0gPSB0cmFjZUlkLnNwbGl0KCctJykgOwoKICAgICAgICAgIHNlc3Npb24ucG9zdCgnRGVidWdnZXIucmVzdW1lJyk7CiAgICAgICAgICBzZXNzaW9uLnBvc3QoJ0RlYnVnZ2VyLmRpc2FibGUnKTsKCiAgICAgICAgICBjb25zdCBjb250ZXh0ID0gX29wdGlvbmFsQ2hhaW4oW3RyYWNlX2lkLCAnb3B0aW9uYWxBY2Nlc3MnLCBfNCA9PiBfNC5sZW5ndGhdKSAmJiBfb3B0aW9uYWxDaGFpbihbc3Bhbl9pZCwgJ29wdGlvbmFsQWNjZXNzJywgXzUgPT4gXzUubGVuZ3RoXSkgPyB7IHRyYWNlX2lkLCBzcGFuX2lkLCBwYXJlbnRfc3Bhbl9pZCB9IDogdW5kZWZpbmVkOwogICAgICAgICAgc2VuZEFuckV2ZW50KHN0YWNrRnJhbWVzLCBjb250ZXh0KS50aGVuKG51bGwsICgpID0+IHsKICAgICAgICAgICAgbG9nKCdTZW5kaW5nIEFOUiBldmVudCBmYWlsZWQuJyk7CiAgICAgICAgICB9KTsKICAgICAgICB9LAogICAgICApOwogICAgfSBjYXRjaCAoZSkgewogICAgICBzZXNzaW9uLnBvc3QoJ0RlYnVnZ2VyLnJlc3VtZScpOwogICAgICBzZXNzaW9uLnBvc3QoJ0RlYnVnZ2VyLmRpc2FibGUnKTsKICAgICAgdGhyb3cgZTsKICAgIH0KICB9KTsKCiAgZGVidWdnZXJQYXVzZSA9ICgpID0+IHsKICAgIHRyeSB7CiAgICAgIHNlc3Npb24ucG9zdCgnRGVidWdnZXIuZW5hYmxlJywgKCkgPT4gewogICAgICAgIHNlc3Npb24ucG9zdCgnRGVidWdnZXIucGF1c2UnKTsKICAgICAgfSk7CiAgICB9IGNhdGNoIChfKSB7CiAgICAgIC8vCiAgICB9CiAgfTsKfQoKZnVuY3Rpb24gY3JlYXRlSHJUaW1lcigpIHsKICAvLyBUT0RPICh2OCk6IFdlIGNhbiB1c2UgcHJvY2Vzcy5ocnRpbWUuYmlnaW50KCkgYWZ0ZXIgd2UgZHJvcCBub2RlIHY4CiAgbGV0IGxhc3RQb2xsID0gcHJvY2Vzcy5ocnRpbWUoKTsKCiAgcmV0dXJuIHsKICAgIGdldFRpbWVNczogKCkgPT4gewogICAgICBjb25zdCBbc2Vjb25kcywgbmFub1NlY29uZHNdID0gcHJvY2Vzcy5ocnRpbWUobGFzdFBvbGwpOwogICAgICByZXR1cm4gTWF0aC5mbG9vcihzZWNvbmRzICogMWUzICsgbmFub1NlY29uZHMgLyAxZTYpOwogICAgfSwKICAgIHJlc2V0OiAoKSA9PiB7CiAgICAgIGxhc3RQb2xsID0gcHJvY2Vzcy5ocnRpbWUoKTsKICAgIH0sCiAgfTsKfQoKZnVuY3Rpb24gd2F0Y2hkb2dUaW1lb3V0KCkgewogIGxvZygnV2F0Y2hkb2cgdGltZW91dCcpOwoKICBpZiAoZGVidWdnZXJQYXVzZSkgewogICAgbG9nKCdQYXVzaW5nIGRlYnVnZ2VyIHRvIGNhcHR1cmUgc3RhY2sgdHJhY2UnKTsKICAgIGRlYnVnZ2VyUGF1c2UoKTsKICB9IGVsc2UgewogICAgbG9nKCdDYXB0dXJpbmcgZXZlbnQgd2l0aG91dCBhIHN0YWNrIHRyYWNlJyk7CiAgICBzZW5kQW5yRXZlbnQoKS50aGVuKG51bGwsICgpID0+IHsKICAgICAgbG9nKCdTZW5kaW5nIEFOUiBldmVudCBmYWlsZWQgb24gd2F0Y2hkb2cgdGltZW91dC4nKTsKICAgIH0pOwogIH0KfQoKY29uc3QgeyBwb2xsIH0gPSB3YXRjaGRvZ1RpbWVyKGNyZWF0ZUhyVGltZXIsIG9wdGlvbnMucG9sbEludGVydmFsLCBvcHRpb25zLmFuclRocmVzaG9sZCwgd2F0Y2hkb2dUaW1lb3V0KTsKCl9vcHRpb25hbENoYWluKFtwYXJlbnRQb3J0LCAnb3B0aW9uYWxBY2Nlc3MnLCBfNiA9PiBfNi5vbiwgJ2NhbGwnLCBfNyA9PiBfNygnbWVzc2FnZScsIChtc2cpID0+IHsKICBpZiAobXNnLnNlc3Npb24pIHsKICAgIHNlc3Npb24gPSBtYWtlU2Vzc2lvbihtc2cuc2Vzc2lvbik7CiAgfQoKICBwb2xsKCk7Cn0pXSk7";
@@ -1,2 +1,2 @@
1
- /*! @sentry/node 7.106.0 (6b3f70d) | https://github.com/getsentry/sentry-javascript */
1
+ /*! @sentry/node 7.106.1 (887f0e7) | https://github.com/getsentry/sentry-javascript */
2
2
  export const base64WorkerScript="aW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJ2luc3BlY3Rvcic7CmltcG9ydCB7IHdvcmtlckRhdGEsIHBhcmVudFBvcnQgfSBmcm9tICd3b3JrZXJfdGhyZWFkcyc7CmltcG9ydCB7IHBvc2l4LCBzZXAgfSBmcm9tICdwYXRoJzsKaW1wb3J0ICogYXMgaHR0cCBmcm9tICdodHRwJzsKaW1wb3J0ICogYXMgaHR0cHMgZnJvbSAnaHR0cHMnOwppbXBvcnQgeyBSZWFkYWJsZSB9IGZyb20gJ3N0cmVhbSc7CmltcG9ydCB7IFVSTCB9IGZyb20gJ3VybCc7CmltcG9ydCB7IGNyZWF0ZUd6aXAgfSBmcm9tICd6bGliJzsKaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnOwppbXBvcnQgKiBhcyBuZXQgZnJvbSAnbmV0JzsKaW1wb3J0ICogYXMgdGxzIGZyb20gJ3Rscyc7CgovLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L3VuYm91bmQtbWV0aG9kCmNvbnN0IG9iamVjdFRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZzsKCi8qKgogKiBDaGVja3Mgd2hldGhlciBnaXZlbiB2YWx1ZSdzIHR5cGUgaXMgb25lIG9mIGEgZmV3IEVycm9yIG9yIEVycm9yLWxpa2UKICoge0BsaW5rIGlzRXJyb3J9LgogKgogKiBAcGFyYW0gd2F0IEEgdmFsdWUgdG8gYmUgY2hlY2tlZC4KICogQHJldHVybnMgQSBib29sZWFuIHJlcHJlc2VudGluZyB0aGUgcmVzdWx0LgogKi8KZnVuY3Rpb24gaXNFcnJvcih3YXQpIHsKICBzd2l0Y2ggKG9iamVjdFRvU3RyaW5nLmNhbGwod2F0KSkgewogICAgY2FzZSAnW29iamVjdCBFcnJvcl0nOgogICAgY2FzZSAnW29iamVjdCBFeGNlcHRpb25dJzoKICAgIGNhc2UgJ1tvYmplY3QgRE9NRXhjZXB0aW9uXSc6CiAgICAgIHJldHVybiB0cnVlOwogICAgZGVmYXVsdDoKICAgICAgcmV0dXJuIGlzSW5zdGFuY2VPZih3YXQsIEVycm9yKTsKICB9Cn0KLyoqCiAqIENoZWNrcyB3aGV0aGVyIGdpdmVuIHZhbHVlIGlzIGFuIGluc3RhbmNlIG9mIHRoZSBnaXZlbiBidWlsdC1pbiBjbGFzcy4KICoKICogQHBhcmFtIHdhdCBUaGUgdmFsdWUgdG8gYmUgY2hlY2tlZAogKiBAcGFyYW0gY2xhc3NOYW1lCiAqIEByZXR1cm5zIEEgYm9vbGVhbiByZXByZXNlbnRpbmcgdGhlIHJlc3VsdC4KICovCmZ1bmN0aW9uIGlzQnVpbHRpbih3YXQsIGNsYXNzTmFtZSkgewogIHJldHVybiBvYmplY3RUb1N0cmluZy5jYWxsKHdhdCkgPT09IGBbb2JqZWN0ICR7Y2xhc3NOYW1lfV1gOwp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUncyB0eXBlIGlzIGEgc3RyaW5nCiAqIHtAbGluayBpc1N0cmluZ30uCiAqCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc1N0cmluZyh3YXQpIHsKICByZXR1cm4gaXNCdWlsdGluKHdhdCwgJ1N0cmluZycpOwp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUncyB0eXBlIGlzIGFuIG9iamVjdCBsaXRlcmFsLCBvciBhIGNsYXNzIGluc3RhbmNlLgogKiB7QGxpbmsgaXNQbGFpbk9iamVjdH0uCiAqCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc1BsYWluT2JqZWN0KHdhdCkgewogIHJldHVybiBpc0J1aWx0aW4od2F0LCAnT2JqZWN0Jyk7Cn0KCi8qKgogKiBDaGVja3Mgd2hldGhlciBnaXZlbiB2YWx1ZSdzIHR5cGUgaXMgYW4gRXZlbnQgaW5zdGFuY2UKICoge0BsaW5rIGlzRXZlbnR9LgogKgogKiBAcGFyYW0gd2F0IEEgdmFsdWUgdG8gYmUgY2hlY2tlZC4KICogQHJldHVybnMgQSBib29sZWFuIHJlcHJlc2VudGluZyB0aGUgcmVzdWx0LgogKi8KZnVuY3Rpb24gaXNFdmVudCh3YXQpIHsKICByZXR1cm4gdHlwZW9mIEV2ZW50ICE9PSAndW5kZWZpbmVkJyAmJiBpc0luc3RhbmNlT2Yod2F0LCBFdmVudCk7Cn0KCi8qKgogKiBDaGVja3Mgd2hldGhlciBnaXZlbiB2YWx1ZSdzIHR5cGUgaXMgYW4gRWxlbWVudCBpbnN0YW5jZQogKiB7QGxpbmsgaXNFbGVtZW50fS4KICoKICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqIEByZXR1cm5zIEEgYm9vbGVhbiByZXByZXNlbnRpbmcgdGhlIHJlc3VsdC4KICovCmZ1bmN0aW9uIGlzRWxlbWVudCh3YXQpIHsKICByZXR1cm4gdHlwZW9mIEVsZW1lbnQgIT09ICd1bmRlZmluZWQnICYmIGlzSW5zdGFuY2VPZih3YXQsIEVsZW1lbnQpOwp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUgaGFzIGEgdGhlbiBmdW5jdGlvbi4KICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqLwpmdW5jdGlvbiBpc1RoZW5hYmxlKHdhdCkgewogIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLW1lbWJlci1hY2Nlc3MKICByZXR1cm4gQm9vbGVhbih3YXQgJiYgd2F0LnRoZW4gJiYgdHlwZW9mIHdhdC50aGVuID09PSAnZnVuY3Rpb24nKTsKfQoKLyoqCiAqIENoZWNrcyB3aGV0aGVyIGdpdmVuIHZhbHVlJ3MgdHlwZSBpcyBhIFN5bnRoZXRpY0V2ZW50CiAqIHtAbGluayBpc1N5bnRoZXRpY0V2ZW50fS4KICoKICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqIEByZXR1cm5zIEEgYm9vbGVhbiByZXByZXNlbnRpbmcgdGhlIHJlc3VsdC4KICovCmZ1bmN0aW9uIGlzU3ludGhldGljRXZlbnQod2F0KSB7CiAgcmV0dXJuIGlzUGxhaW5PYmplY3Qod2F0KSAmJiAnbmF0aXZlRXZlbnQnIGluIHdhdCAmJiAncHJldmVudERlZmF1bHQnIGluIHdhdCAmJiAnc3RvcFByb3BhZ2F0aW9uJyBpbiB3YXQ7Cn0KCi8qKgogKiBDaGVja3Mgd2hldGhlciBnaXZlbiB2YWx1ZSBpcyBOYU4KICoge0BsaW5rIGlzTmFOfS4KICoKICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqIEByZXR1cm5zIEEgYm9vbGVhbiByZXByZXNlbnRpbmcgdGhlIHJlc3VsdC4KICovCmZ1bmN0aW9uIGlzTmFOJDEod2F0KSB7CiAgcmV0dXJuIHR5cGVvZiB3YXQgPT09ICdudW1iZXInICYmIHdhdCAhPT0gd2F0Owp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUncyB0eXBlIGlzIGFuIGluc3RhbmNlIG9mIHByb3ZpZGVkIGNvbnN0cnVjdG9yLgogKiB7QGxpbmsgaXNJbnN0YW5jZU9mfS4KICoKICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqIEBwYXJhbSBiYXNlIEEgY29uc3RydWN0b3IgdG8gYmUgdXNlZCBpbiBhIGNoZWNrLgogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc0luc3RhbmNlT2Yod2F0LCBiYXNlKSB7CiAgdHJ5IHsKICAgIHJldHVybiB3YXQgaW5zdGFuY2VvZiBiYXNlOwogIH0gY2F0Y2ggKF9lKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUncyB0eXBlIGlzIGEgVnVlIFZpZXdNb2RlbC4KICoKICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqIEByZXR1cm5zIEEgYm9vbGVhbiByZXByZXNlbnRpbmcgdGhlIHJlc3VsdC4KICovCmZ1bmN0aW9uIGlzVnVlVmlld01vZGVsKHdhdCkgewogIC8vIE5vdCB1c2luZyBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nIGJlY2F1c2UgaW4gVnVlIDMgaXQgd291bGQgcmVhZCB0aGUgaW5zdGFuY2UncyBTeW1ib2woU3ltYm9sLnRvU3RyaW5nVGFnKSBwcm9wZXJ0eS4KICByZXR1cm4gISEodHlwZW9mIHdhdCA9PT0gJ29iamVjdCcgJiYgd2F0ICE9PSBudWxsICYmICgod2F0ICkuX19pc1Z1ZSB8fCAod2F0ICkuX2lzVnVlKSk7Cn0KCi8qKiBJbnRlcm5hbCBnbG9iYWwgd2l0aCBjb21tb24gcHJvcGVydGllcyBhbmQgU2VudHJ5IGV4dGVuc2lvbnMgICovCgovLyBUaGUgY29kZSBiZWxvdyBmb3IgJ2lzR2xvYmFsT2JqJyBhbmQgJ0dMT0JBTF9PQkonIHdhcyBjb3BpZWQgZnJvbSBjb3JlLWpzIGJlZm9yZSBtb2RpZmljYXRpb24KLy8gaHR0cHM6Ly9naXRodWIuY29tL3psb2lyb2NrL2NvcmUtanMvYmxvYi8xYjk0NGRmNTUyODJjZGM5OWM5MGRiNWY0OWViMGI2ZWRhMmNjMGEzL3BhY2thZ2VzL2NvcmUtanMvaW50ZXJuYWxzL2dsb2JhbC5qcwovLyBjb3JlLWpzIGhhcyB0aGUgZm9sbG93aW5nIGxpY2VuY2U6Ci8vCi8vIENvcHlyaWdodCAoYykgMjAxNC0yMDIyIERlbmlzIFB1c2hrYXJldgovLwovLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5Ci8vIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLCB0byBkZWFsCi8vIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMKLy8gdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbAovLyBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMKLy8gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKLy8KLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4KLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCi8vCi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLAovLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKLy8gQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUgovLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLAovLyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOCi8vIFRIRSBTT0ZUV0FSRS4KCi8qKiBSZXR1cm5zICdvYmonIGlmIGl0J3MgdGhlIGdsb2JhbCBvYmplY3QsIG90aGVyd2lzZSByZXR1cm5zIHVuZGVmaW5lZCAqLwpmdW5jdGlvbiBpc0dsb2JhbE9iaihvYmopIHsKICByZXR1cm4gb2JqICYmIG9iai5NYXRoID09IE1hdGggPyBvYmogOiB1bmRlZmluZWQ7Cn0KCi8qKiBHZXQncyB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgdGhlIGN1cnJlbnQgSmF2YVNjcmlwdCBydW50aW1lICovCmNvbnN0IEdMT0JBTF9PQkogPQogICh0eXBlb2YgZ2xvYmFsVGhpcyA9PSAnb2JqZWN0JyAmJiBpc0dsb2JhbE9iaihnbG9iYWxUaGlzKSkgfHwKICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1nbG9iYWxzCiAgKHR5cGVvZiB3aW5kb3cgPT0gJ29iamVjdCcgJiYgaXNHbG9iYWxPYmood2luZG93KSkgfHwKICAodHlwZW9mIHNlbGYgPT0gJ29iamVjdCcgJiYgaXNHbG9iYWxPYmooc2VsZikpIHx8CiAgKHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgaXNHbG9iYWxPYmooZ2xvYmFsKSkgfHwKICAoZnVuY3Rpb24gKCkgewogICAgcmV0dXJuIHRoaXM7CiAgfSkoKSB8fAogIHt9OwoKLyoqCiAqIEBkZXByZWNhdGVkIFVzZSBHTE9CQUxfT0JKIGluc3RlYWQgb3IgV0lORE9XIGZyb20gQHNlbnRyeS9icm93c2VyLiBUaGlzIHdpbGwgYmUgcmVtb3ZlZCBpbiB2OAogKi8KZnVuY3Rpb24gZ2V0R2xvYmFsT2JqZWN0KCkgewogIHJldHVybiBHTE9CQUxfT0JKIDsKfQoKLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCmNvbnN0IFdJTkRPVyA9IGdldEdsb2JhbE9iamVjdCgpOwoKY29uc3QgREVGQVVMVF9NQVhfU1RSSU5HX0xFTkdUSCA9IDgwOwoKLyoqCiAqIEdpdmVuIGEgY2hpbGQgRE9NIGVsZW1lbnQsIHJldHVybnMgYSBxdWVyeS1zZWxlY3RvciBzdGF0ZW1lbnQgZGVzY3JpYmluZyB0aGF0CiAqIGFuZCBpdHMgYW5jZXN0b3JzCiAqIGUuZy4gW0hUTUxFbGVtZW50XSA9PiBib2R5ID4gZGl2ID4gaW5wdXQjZm9vLmJ0bltuYW1lPWJhel0KICogQHJldHVybnMgZ2VuZXJhdGVkIERPTSBwYXRoCiAqLwpmdW5jdGlvbiBodG1sVHJlZUFzU3RyaW5nKAogIGVsZW0sCiAgb3B0aW9ucyA9IHt9LAopIHsKICBpZiAoIWVsZW0pIHsKICAgIHJldHVybiAnPHVua25vd24+JzsKICB9CgogIC8vIHRyeS9jYXRjaCBib3RoOgogIC8vIC0gYWNjZXNzaW5nIGV2ZW50LnRhcmdldCAoc2VlIGdldHNlbnRyeS9yYXZlbi1qcyM4MzgsICM3NjgpCiAgLy8gLSBgaHRtbFRyZWVBc1N0cmluZ2AgYmVjYXVzZSBpdCdzIGNvbXBsZXgsIGFuZCBqdXN0IGFjY2Vzc2luZyB0aGUgRE9NIGluY29ycmVjdGx5CiAgLy8gLSBjYW4gdGhyb3cgYW4gZXhjZXB0aW9uIGluIHNvbWUgY2lyY3Vtc3RhbmNlcy4KICB0cnkgewogICAgbGV0IGN1cnJlbnRFbGVtID0gZWxlbSA7CiAgICBjb25zdCBNQVhfVFJBVkVSU0VfSEVJR0hUID0gNTsKICAgIGNvbnN0IG91dCA9IFtdOwogICAgbGV0IGhlaWdodCA9IDA7CiAgICBsZXQgbGVuID0gMDsKICAgIGNvbnN0IHNlcGFyYXRvciA9ICcgPiAnOwogICAgY29uc3Qgc2VwTGVuZ3RoID0gc2VwYXJhdG9yLmxlbmd0aDsKICAgIGxldCBuZXh0U3RyOwogICAgY29uc3Qga2V5QXR0cnMgPSBBcnJheS5pc0FycmF5KG9wdGlvbnMpID8gb3B0aW9ucyA6IG9wdGlvbnMua2V5QXR0cnM7CiAgICBjb25zdCBtYXhTdHJpbmdMZW5ndGggPSAoIUFycmF5LmlzQXJyYXkob3B0aW9ucykgJiYgb3B0aW9ucy5tYXhTdHJpbmdMZW5ndGgpIHx8IERFRkFVTFRfTUFYX1NUUklOR19MRU5HVEg7CgogICAgd2hpbGUgKGN1cnJlbnRFbGVtICYmIGhlaWdodCsrIDwgTUFYX1RSQVZFUlNFX0hFSUdIVCkgewogICAgICBuZXh0U3RyID0gX2h0bWxFbGVtZW50QXNTdHJpbmcoY3VycmVudEVsZW0sIGtleUF0dHJzKTsKICAgICAgLy8gYmFpbCBvdXQgaWYKICAgICAgLy8gLSBuZXh0U3RyIGlzIHRoZSAnaHRtbCcgZWxlbWVudAogICAgICAvLyAtIHRoZSBsZW5ndGggb2YgdGhlIHN0cmluZyB0aGF0IHdvdWxkIGJlIGNyZWF0ZWQgZXhjZWVkcyBtYXhTdHJpbmdMZW5ndGgKICAgICAgLy8gICAoaWdub3JlIHRoaXMgbGltaXQgaWYgd2UgYXJlIG9uIHRoZSBmaXJzdCBpdGVyYXRpb24pCiAgICAgIGlmIChuZXh0U3RyID09PSAnaHRtbCcgfHwgKGhlaWdodCA+IDEgJiYgbGVuICsgb3V0Lmxlbmd0aCAqIHNlcExlbmd0aCArIG5leHRTdHIubGVuZ3RoID49IG1heFN0cmluZ0xlbmd0aCkpIHsKICAgICAgICBicmVhazsKICAgICAgfQoKICAgICAgb3V0LnB1c2gobmV4dFN0cik7CgogICAgICBsZW4gKz0gbmV4dFN0ci5sZW5ndGg7CiAgICAgIGN1cnJlbnRFbGVtID0gY3VycmVudEVsZW0ucGFyZW50Tm9kZTsKICAgIH0KCiAgICByZXR1cm4gb3V0LnJldmVyc2UoKS5qb2luKHNlcGFyYXRvcik7CiAgfSBjYXRjaCAoX29PKSB7CiAgICByZXR1cm4gJzx1bmtub3duPic7CiAgfQp9CgovKioKICogUmV0dXJucyBhIHNpbXBsZSwgcXVlcnktc2VsZWN0b3IgcmVwcmVzZW50YXRpb24gb2YgYSBET00gZWxlbWVudAogKiBlLmcuIFtIVE1MRWxlbWVudF0gPT4gaW5wdXQjZm9vLmJ0bltuYW1lPWJhel0KICogQHJldHVybnMgZ2VuZXJhdGVkIERPTSBwYXRoCiAqLwpmdW5jdGlvbiBfaHRtbEVsZW1lbnRBc1N0cmluZyhlbCwga2V5QXR0cnMpIHsKICBjb25zdCBlbGVtID0gZWwKCjsKCiAgY29uc3Qgb3V0ID0gW107CiAgbGV0IGNsYXNzTmFtZTsKICBsZXQgY2xhc3NlczsKICBsZXQga2V5OwogIGxldCBhdHRyOwogIGxldCBpOwoKICBpZiAoIWVsZW0gfHwgIWVsZW0udGFnTmFtZSkgewogICAgcmV0dXJuICcnOwogIH0KCiAgLy8gQHRzLWV4cGVjdC1lcnJvciBXSU5ET1cgaGFzIEhUTUxFbGVtZW50CiAgaWYgKFdJTkRPVy5IVE1MRWxlbWVudCkgewogICAgLy8gSWYgdXNpbmcgdGhlIGNvbXBvbmVudCBuYW1lIGFubm90YXRpb24gcGx1Z2luLCB0aGlzIHZhbHVlIG1heSBiZSBhdmFpbGFibGUgb24gdGhlIERPTSBub2RlCiAgICBpZiAoZWxlbSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50ICYmIGVsZW0uZGF0YXNldCAmJiBlbGVtLmRhdGFzZXRbJ3NlbnRyeUNvbXBvbmVudCddKSB7CiAgICAgIHJldHVybiBlbGVtLmRhdGFzZXRbJ3NlbnRyeUNvbXBvbmVudCddOwogICAgfQogIH0KCiAgb3V0LnB1c2goZWxlbS50YWdOYW1lLnRvTG93ZXJDYXNlKCkpOwoKICAvLyBQYWlycyBvZiBhdHRyaWJ1dGUga2V5cyBkZWZpbmVkIGluIGBzZXJpYWxpemVBdHRyaWJ1dGVgIGFuZCB0aGVpciB2YWx1ZXMgb24gZWxlbWVudC4KICBjb25zdCBrZXlBdHRyUGFpcnMgPQogICAga2V5QXR0cnMgJiYga2V5QXR0cnMubGVuZ3RoCiAgICAgID8ga2V5QXR0cnMuZmlsdGVyKGtleUF0dHIgPT4gZWxlbS5nZXRBdHRyaWJ1dGUoa2V5QXR0cikpLm1hcChrZXlBdHRyID0+IFtrZXlBdHRyLCBlbGVtLmdldEF0dHJpYnV0ZShrZXlBdHRyKV0pCiAgICAgIDogbnVsbDsKCiAgaWYgKGtleUF0dHJQYWlycyAmJiBrZXlBdHRyUGFpcnMubGVuZ3RoKSB7CiAgICBrZXlBdHRyUGFpcnMuZm9yRWFjaChrZXlBdHRyUGFpciA9PiB7CiAgICAgIG91dC5wdXNoKGBbJHtrZXlBdHRyUGFpclswXX09IiR7a2V5QXR0clBhaXJbMV19Il1gKTsKICAgIH0pOwogIH0gZWxzZSB7CiAgICBpZiAoZWxlbS5pZCkgewogICAgICBvdXQucHVzaChgIyR7ZWxlbS5pZH1gKTsKICAgIH0KCiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLWNvbnN0CiAgICBjbGFzc05hbWUgPSBlbGVtLmNsYXNzTmFtZTsKICAgIGlmIChjbGFzc05hbWUgJiYgaXNTdHJpbmcoY2xhc3NOYW1lKSkgewogICAgICBjbGFzc2VzID0gY2xhc3NOYW1lLnNwbGl0KC9ccysvKTsKICAgICAgZm9yIChpID0gMDsgaSA8IGNsYXNzZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICBvdXQucHVzaChgLiR7Y2xhc3Nlc1tpXX1gKTsKICAgICAgfQogICAgfQogIH0KICBjb25zdCBhbGxvd2VkQXR0cnMgPSBbJ2FyaWEtbGFiZWwnLCAndHlwZScsICduYW1lJywgJ3RpdGxlJywgJ2FsdCddOwogIGZvciAoaSA9IDA7IGkgPCBhbGxvd2VkQXR0cnMubGVuZ3RoOyBpKyspIHsKICAgIGtleSA9IGFsbG93ZWRBdHRyc1tpXTsKICAgIGF0dHIgPSBlbGVtLmdldEF0dHJpYnV0ZShrZXkpOwogICAgaWYgKGF0dHIpIHsKICAgICAgb3V0LnB1c2goYFske2tleX09IiR7YXR0cn0iXWApOwogICAgfQogIH0KICByZXR1cm4gb3V0LmpvaW4oJycpOwp9CgovKioKICogVGhpcyBzZXJ2ZXMgYXMgYSBidWlsZCB0aW1lIGZsYWcgdGhhdCB3aWxsIGJlIHRydWUgYnkgZGVmYXVsdCwgYnV0IGZhbHNlIGluIG5vbi1kZWJ1ZyBidWlsZHMgb3IgaWYgdXNlcnMgcmVwbGFjZSBgX19TRU5UUllfREVCVUdfX2AgaW4gdGhlaXIgZ2VuZXJhdGVkIGNvZGUuCiAqCiAqIEFUVEVOVElPTjogVGhpcyBjb25zdGFudCBtdXN0IG5ldmVyIGNyb3NzIHBhY2thZ2UgYm91bmRhcmllcyAoaS5lLiBiZSBleHBvcnRlZCkgdG8gZ3VhcmFudGVlIHRoYXQgaXQgY2FuIGJlIHVzZWQgZm9yIHRyZWUgc2hha2luZy4KICovCmNvbnN0IERFQlVHX0JVSUxEJDEgPSAodHlwZW9mIF9fU0VOVFJZX0RFQlVHX18gPT09ICd1bmRlZmluZWQnIHx8IF9fU0VOVFJZX0RFQlVHX18pOwoKLyoqIFByZWZpeCBmb3IgbG9nZ2luZyBzdHJpbmdzICovCmNvbnN0IFBSRUZJWCA9ICdTZW50cnkgTG9nZ2VyICc7Cgpjb25zdCBDT05TT0xFX0xFVkVMUyA9IFsKICAnZGVidWcnLAogICdpbmZvJywKICAnd2FybicsCiAgJ2Vycm9yJywKICAnbG9nJywKICAnYXNzZXJ0JywKICAndHJhY2UnLApdIDsKCi8qKiBUaGlzIG1heSBiZSBtdXRhdGVkIGJ5IHRoZSBjb25zb2xlIGluc3RydW1lbnRhdGlvbi4gKi8KY29uc3Qgb3JpZ2luYWxDb25zb2xlTWV0aG9kcwoKID0ge307CgovKiogSlNEb2MgKi8KCi8qKgogKiBUZW1wb3JhcmlseSBkaXNhYmxlIHNlbnRyeSBjb25zb2xlIGluc3RydW1lbnRhdGlvbnMuCiAqCiAqIEBwYXJhbSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gdG8gcnVuIGFnYWluc3QgdGhlIG9yaWdpbmFsIGBjb25zb2xlYCBtZXNzYWdlcwogKiBAcmV0dXJucyBUaGUgcmVzdWx0cyBvZiB0aGUgY2FsbGJhY2sKICovCmZ1bmN0aW9uIGNvbnNvbGVTYW5kYm94KGNhbGxiYWNrKSB7CiAgaWYgKCEoJ2NvbnNvbGUnIGluIEdMT0JBTF9PQkopKSB7CiAgICByZXR1cm4gY2FsbGJhY2soKTsKICB9CgogIGNvbnN0IGNvbnNvbGUgPSBHTE9CQUxfT0JKLmNvbnNvbGUgOwogIGNvbnN0IHdyYXBwZWRGdW5jcyA9IHt9OwoKICBjb25zdCB3cmFwcGVkTGV2ZWxzID0gT2JqZWN0LmtleXMob3JpZ2luYWxDb25zb2xlTWV0aG9kcykgOwoKICAvLyBSZXN0b3JlIGFsbCB3cmFwcGVkIGNvbnNvbGUgbWV0aG9kcwogIHdyYXBwZWRMZXZlbHMuZm9yRWFjaChsZXZlbCA9PiB7CiAgICBjb25zdCBvcmlnaW5hbENvbnNvbGVNZXRob2QgPSBvcmlnaW5hbENvbnNvbGVNZXRob2RzW2xldmVsXSA7CiAgICB3cmFwcGVkRnVuY3NbbGV2ZWxdID0gY29uc29sZVtsZXZlbF0gOwogICAgY29uc29sZVtsZXZlbF0gPSBvcmlnaW5hbENvbnNvbGVNZXRob2Q7CiAgfSk7CgogIHRyeSB7CiAgICByZXR1cm4gY2FsbGJhY2soKTsKICB9IGZpbmFsbHkgewogICAgLy8gUmV2ZXJ0IHJlc3RvcmF0aW9uIHRvIHdyYXBwZWQgc3RhdGUKICAgIHdyYXBwZWRMZXZlbHMuZm9yRWFjaChsZXZlbCA9PiB7CiAgICAgIGNvbnNvbGVbbGV2ZWxdID0gd3JhcHBlZEZ1bmNzW2xldmVsXSA7CiAgICB9KTsKICB9Cn0KCmZ1bmN0aW9uIG1ha2VMb2dnZXIoKSB7CiAgbGV0IGVuYWJsZWQgPSBmYWxzZTsKICBjb25zdCBsb2dnZXIgPSB7CiAgICBlbmFibGU6ICgpID0+IHsKICAgICAgZW5hYmxlZCA9IHRydWU7CiAgICB9LAogICAgZGlzYWJsZTogKCkgPT4gewogICAgICBlbmFibGVkID0gZmFsc2U7CiAgICB9LAogICAgaXNFbmFibGVkOiAoKSA9PiBlbmFibGVkLAogIH07CgogIGlmIChERUJVR19CVUlMRCQxKSB7CiAgICBDT05TT0xFX0xFVkVMUy5mb3JFYWNoKG5hbWUgPT4gewogICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueQogICAgICBsb2dnZXJbbmFtZV0gPSAoLi4uYXJncykgPT4gewogICAgICAgIGlmIChlbmFibGVkKSB7CiAgICAgICAgICBjb25zb2xlU2FuZGJveCgoKSA9PiB7CiAgICAgICAgICAgIEdMT0JBTF9PQkouY29uc29sZVtuYW1lXShgJHtQUkVGSVh9WyR7bmFtZX1dOmAsIC4uLmFyZ3MpOwogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICB9OwogICAgfSk7CiAgfSBlbHNlIHsKICAgIENPTlNPTEVfTEVWRUxTLmZvckVhY2gobmFtZSA9PiB7CiAgICAgIGxvZ2dlcltuYW1lXSA9ICgpID0+IHVuZGVmaW5lZDsKICAgIH0pOwogIH0KCiAgcmV0dXJuIGxvZ2dlciA7Cn0KCmNvbnN0IGxvZ2dlciA9IG1ha2VMb2dnZXIoKTsKCi8qKgogKiBSZW5kZXJzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBEc24uCiAqCiAqIEJ5IGRlZmF1bHQsIHRoaXMgd2lsbCByZW5kZXIgdGhlIHB1YmxpYyByZXByZXNlbnRhdGlvbiB3aXRob3V0IHRoZSBwYXNzd29yZAogKiBjb21wb25lbnQuIFRvIGdldCB0aGUgZGVwcmVjYXRlZCBwcml2YXRlIHJlcHJlc2VudGF0aW9uLCBzZXQgYHdpdGhQYXNzd29yZGAKICogdG8gdHJ1ZS4KICoKICogQHBhcmFtIHdpdGhQYXNzd29yZCBXaGVuIHNldCB0byB0cnVlLCB0aGUgcGFzc3dvcmQgd2lsbCBiZSBpbmNsdWRlZC4KICovCmZ1bmN0aW9uIGRzblRvU3RyaW5nKGRzbiwgd2l0aFBhc3N3b3JkID0gZmFsc2UpIHsKICBjb25zdCB7IGhvc3QsIHBhdGgsIHBhc3MsIHBvcnQsIHByb2plY3RJZCwgcHJvdG9jb2wsIHB1YmxpY0tleSB9ID0gZHNuOwogIHJldHVybiAoCiAgICBgJHtwcm90b2NvbH06Ly8ke3B1YmxpY0tleX0ke3dpdGhQYXNzd29yZCAmJiBwYXNzID8gYDoke3Bhc3N9YCA6ICcnfWAgKwogICAgYEAke2hvc3R9JHtwb3J0ID8gYDoke3BvcnR9YCA6ICcnfS8ke3BhdGggPyBgJHtwYXRofS9gIDogcGF0aH0ke3Byb2plY3RJZH1gCiAgKTsKfQoKLyoqIEFuIGVycm9yIGVtaXR0ZWQgYnkgU2VudHJ5IFNES3MgYW5kIHJlbGF0ZWQgdXRpbGl0aWVzLiAqLwpjbGFzcyBTZW50cnlFcnJvciBleHRlbmRzIEVycm9yIHsKICAvKiogRGlzcGxheSBuYW1lIG9mIHRoaXMgZXJyb3IgaW5zdGFuY2UuICovCgogICBjb25zdHJ1Y3RvciggbWVzc2FnZSwgbG9nTGV2ZWwgPSAnd2FybicpIHsKICAgIHN1cGVyKG1lc3NhZ2UpO3RoaXMubWVzc2FnZSA9IG1lc3NhZ2U7CiAgICB0aGlzLm5hbWUgPSBuZXcudGFyZ2V0LnByb3RvdHlwZS5jb25zdHJ1Y3Rvci5uYW1lOwogICAgLy8gVGhpcyBzZXRzIHRoZSBwcm90b3R5cGUgdG8gYmUgYEVycm9yYCwgbm90IGBTZW50cnlFcnJvcmAuIEl0J3MgdW5jbGVhciB3aHkgd2UgZG8gdGhpcywgYnV0IGNvbW1lbnRpbmcgdGhpcyBsaW5lCiAgICAvLyBvdXQgY2F1c2VzIHZhcmlvdXMgKHNlZW1pbmdseSB0b3RhbGx5IHVucmVsYXRlZCkgcGxheXdyaWdodCB0ZXN0cyBjb25zaXN0ZW50bHkgdGltZSBvdXQuIEZZSSwgdGhpcyBtYWtlcwogICAgLy8gaW5zdGFuY2VzIG9mIGBTZW50cnlFcnJvcmAgZmFpbCBgb2JqIGluc3RhbmNlb2YgU2VudHJ5RXJyb3JgIGNoZWNrcy4KICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBuZXcudGFyZ2V0LnByb3RvdHlwZSk7CiAgICB0aGlzLmxvZ0xldmVsID0gbG9nTGV2ZWw7CiAgfQp9CgovKioKICogRW5jb2RlcyBnaXZlbiBvYmplY3QgaW50byB1cmwtZnJpZW5kbHkgZm9ybWF0CiAqCiAqIEBwYXJhbSBvYmplY3QgQW4gb2JqZWN0IHRoYXQgY29udGFpbnMgc2VyaWFsaXphYmxlIHZhbHVlcwogKiBAcmV0dXJucyBzdHJpbmcgRW5jb2RlZAogKi8KZnVuY3Rpb24gdXJsRW5jb2RlKG9iamVjdCkgewogIHJldHVybiBPYmplY3Qua2V5cyhvYmplY3QpCiAgICAubWFwKGtleSA9PiBgJHtlbmNvZGVVUklDb21wb25lbnQoa2V5KX09JHtlbmNvZGVVUklDb21wb25lbnQob2JqZWN0W2tleV0pfWApCiAgICAuam9pbignJicpOwp9CgovKioKICogVHJhbnNmb3JtcyBhbnkgYEVycm9yYCBvciBgRXZlbnRgIGludG8gYSBwbGFpbiBvYmplY3Qgd2l0aCBhbGwgb2YgdGhlaXIgZW51bWVyYWJsZSBwcm9wZXJ0aWVzLCBhbmQgc29tZSBvZiB0aGVpcgogKiBub24tZW51bWVyYWJsZSBwcm9wZXJ0aWVzIGF0dGFjaGVkLgogKgogKiBAcGFyYW0gdmFsdWUgSW5pdGlhbCBzb3VyY2UgdGhhdCB3ZSBoYXZlIHRvIHRyYW5zZm9ybSBpbiBvcmRlciBmb3IgaXQgdG8gYmUgdXNhYmxlIGJ5IHRoZSBzZXJpYWxpemVyCiAqIEByZXR1cm5zIEFuIEV2ZW50IG9yIEVycm9yIHR1cm5lZCBpbnRvIGFuIG9iamVjdCAtIG9yIHRoZSB2YWx1ZSBhcmd1cm1lbnQgaXRzZWxmLCB3aGVuIHZhbHVlIGlzIG5laXRoZXIgYW4gRXZlbnQgbm9yCiAqICBhbiBFcnJvci4KICovCmZ1bmN0aW9uIGNvbnZlcnRUb1BsYWluT2JqZWN0KAogIHZhbHVlLAopCgogewogIGlmIChpc0Vycm9yKHZhbHVlKSkgewogICAgcmV0dXJuIHsKICAgICAgbWVzc2FnZTogdmFsdWUubWVzc2FnZSwKICAgICAgbmFtZTogdmFsdWUubmFtZSwKICAgICAgc3RhY2s6IHZhbHVlLnN0YWNrLAogICAgICAuLi5nZXRPd25Qcm9wZXJ0aWVzKHZhbHVlKSwKICAgIH07CiAgfSBlbHNlIGlmIChpc0V2ZW50KHZhbHVlKSkgewogICAgY29uc3QgbmV3T2JqCgogPSB7CiAgICAgIHR5cGU6IHZhbHVlLnR5cGUsCiAgICAgIHRhcmdldDogc2VyaWFsaXplRXZlbnRUYXJnZXQodmFsdWUudGFyZ2V0KSwKICAgICAgY3VycmVudFRhcmdldDogc2VyaWFsaXplRXZlbnRUYXJnZXQodmFsdWUuY3VycmVudFRhcmdldCksCiAgICAgIC4uLmdldE93blByb3BlcnRpZXModmFsdWUpLAogICAgfTsKCiAgICBpZiAodHlwZW9mIEN1c3RvbUV2ZW50ICE9PSAndW5kZWZpbmVkJyAmJiBpc0luc3RhbmNlT2YodmFsdWUsIEN1c3RvbUV2ZW50KSkgewogICAgICBuZXdPYmouZGV0YWlsID0gdmFsdWUuZGV0YWlsOwogICAgfQoKICAgIHJldHVybiBuZXdPYmo7CiAgfSBlbHNlIHsKICAgIHJldHVybiB2YWx1ZTsKICB9Cn0KCi8qKiBDcmVhdGVzIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB0YXJnZXQgb2YgYW4gYEV2ZW50YCBvYmplY3QgKi8KZnVuY3Rpb24gc2VyaWFsaXplRXZlbnRUYXJnZXQodGFyZ2V0KSB7CiAgdHJ5IHsKICAgIHJldHVybiBpc0VsZW1lbnQodGFyZ2V0KSA/IGh0bWxUcmVlQXNTdHJpbmcodGFyZ2V0KSA6IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0YXJnZXQpOwogIH0gY2F0Y2ggKF9vTykgewogICAgcmV0dXJuICc8dW5rbm93bj4nOwogIH0KfQoKLyoqIEZpbHRlcnMgb3V0IGFsbCBidXQgYW4gb2JqZWN0J3Mgb3duIHByb3BlcnRpZXMgKi8KZnVuY3Rpb24gZ2V0T3duUHJvcGVydGllcyhvYmopIHsKICBpZiAodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgb2JqICE9PSBudWxsKSB7CiAgICBjb25zdCBleHRyYWN0ZWRQcm9wcyA9IHt9OwogICAgZm9yIChjb25zdCBwcm9wZXJ0eSBpbiBvYmopIHsKICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3BlcnR5KSkgewogICAgICAgIGV4dHJhY3RlZFByb3BzW3Byb3BlcnR5XSA9IChvYmogKVtwcm9wZXJ0eV07CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBleHRyYWN0ZWRQcm9wczsKICB9IGVsc2UgewogICAgcmV0dXJuIHt9OwogIH0KfQoKLyoqCiAqIEdpdmVuIGFueSBvYmplY3QsIHJldHVybiBhIG5ldyBvYmplY3QgaGF2aW5nIHJlbW92ZWQgYWxsIGZpZWxkcyB3aG9zZSB2YWx1ZSB3YXMgYHVuZGVmaW5lZGAuCiAqIFdvcmtzIHJlY3Vyc2l2ZWx5IG9uIG9iamVjdHMgYW5kIGFycmF5cy4KICoKICogQXR0ZW50aW9uOiBUaGlzIGZ1bmN0aW9uIGtlZXBzIGNpcmN1bGFyIHJlZmVyZW5jZXMgaW4gdGhlIHJldHVybmVkIG9iamVjdC4KICovCmZ1bmN0aW9uIGRyb3BVbmRlZmluZWRLZXlzKGlucHV0VmFsdWUpIHsKICAvLyBUaGlzIG1hcCBrZWVwcyB0cmFjayBvZiB3aGF0IGFscmVhZHkgdmlzaXRlZCBub2RlcyBtYXAgdG8uCiAgLy8gT3VyIFNldCAtIGJhc2VkIG1lbW9CdWlsZGVyIGRvZXNuJ3Qgd29yayBoZXJlIGJlY2F1c2Ugd2Ugd2FudCB0byB0aGUgb3V0cHV0IG9iamVjdCB0byBoYXZlIHRoZSBzYW1lIGNpcmN1bGFyCiAgLy8gcmVmZXJlbmNlcyBhcyB0aGUgaW5wdXQgb2JqZWN0LgogIGNvbnN0IG1lbW9pemF0aW9uTWFwID0gbmV3IE1hcCgpOwoKICAvLyBUaGlzIGZ1bmN0aW9uIGp1c3QgcHJveGllcyBgX2Ryb3BVbmRlZmluZWRLZXlzYCB0byBrZWVwIHRoZSBgbWVtb0J1aWxkZXJgIG91dCBvZiB0aGlzIGZ1bmN0aW9uJ3MgQVBJCiAgcmV0dXJuIF9kcm9wVW5kZWZpbmVkS2V5cyhpbnB1dFZhbHVlLCBtZW1vaXphdGlvbk1hcCk7Cn0KCmZ1bmN0aW9uIF9kcm9wVW5kZWZpbmVkS2V5cyhpbnB1dFZhbHVlLCBtZW1vaXphdGlvbk1hcCkgewogIGlmIChpc1Bvam8oaW5wdXRWYWx1ZSkpIHsKICAgIC8vIElmIHRoaXMgbm9kZSBoYXMgYWxyZWFkeSBiZWVuIHZpc2l0ZWQgZHVlIHRvIGEgY2lyY3VsYXIgcmVmZXJlbmNlLCByZXR1cm4gdGhlIG9iamVjdCBpdCB3YXMgbWFwcGVkIHRvIGluIHRoZSBuZXcgb2JqZWN0CiAgICBjb25zdCBtZW1vVmFsID0gbWVtb2l6YXRpb25NYXAuZ2V0KGlucHV0VmFsdWUpOwogICAgaWYgKG1lbW9WYWwgIT09IHVuZGVmaW5lZCkgewogICAgICByZXR1cm4gbWVtb1ZhbCA7CiAgICB9CgogICAgY29uc3QgcmV0dXJuVmFsdWUgPSB7fTsKICAgIC8vIFN0b3JlIHRoZSBtYXBwaW5nIG9mIHRoaXMgdmFsdWUgaW4gY2FzZSB3ZSB2aXNpdCBpdCBhZ2FpbiwgaW4gY2FzZSBvZiBjaXJjdWxhciBkYXRhCiAgICBtZW1vaXphdGlvbk1hcC5zZXQoaW5wdXRWYWx1ZSwgcmV0dXJuVmFsdWUpOwoKICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGlucHV0VmFsdWUpKSB7CiAgICAgIGlmICh0eXBlb2YgaW5wdXRWYWx1ZVtrZXldICE9PSAndW5kZWZpbmVkJykgewogICAgICAgIHJldHVyblZhbHVlW2tleV0gPSBfZHJvcFVuZGVmaW5lZEtleXMoaW5wdXRWYWx1ZVtrZXldLCBtZW1vaXphdGlvbk1hcCk7CiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcmV0dXJuVmFsdWUgOwogIH0KCiAgaWYgKEFycmF5LmlzQXJyYXkoaW5wdXRWYWx1ZSkpIHsKICAgIC8vIElmIHRoaXMgbm9kZSBoYXMgYWxyZWFkeSBiZWVuIHZpc2l0ZWQgZHVlIHRvIGEgY2lyY3VsYXIgcmVmZXJlbmNlLCByZXR1cm4gdGhlIGFycmF5IGl0IHdhcyBtYXBwZWQgdG8gaW4gdGhlIG5ldyBvYmplY3QKICAgIGNvbnN0IG1lbW9WYWwgPSBtZW1vaXphdGlvbk1hcC5nZXQoaW5wdXRWYWx1ZSk7CiAgICBpZiAobWVtb1ZhbCAhPT0gdW5kZWZpbmVkKSB7CiAgICAgIHJldHVybiBtZW1vVmFsIDsKICAgIH0KCiAgICBjb25zdCByZXR1cm5WYWx1ZSA9IFtdOwogICAgLy8gU3RvcmUgdGhlIG1hcHBpbmcgb2YgdGhpcyB2YWx1ZSBpbiBjYXNlIHdlIHZpc2l0IGl0IGFnYWluLCBpbiBjYXNlIG9mIGNpcmN1bGFyIGRhdGEKICAgIG1lbW9pemF0aW9uTWFwLnNldChpbnB1dFZhbHVlLCByZXR1cm5WYWx1ZSk7CgogICAgaW5wdXRWYWx1ZS5mb3JFYWNoKChpdGVtKSA9PiB7CiAgICAgIHJldHVyblZhbHVlLnB1c2goX2Ryb3BVbmRlZmluZWRLZXlzKGl0ZW0sIG1lbW9pemF0aW9uTWFwKSk7CiAgICB9KTsKCiAgICByZXR1cm4gcmV0dXJuVmFsdWUgOwogIH0KCiAgcmV0dXJuIGlucHV0VmFsdWU7Cn0KCmZ1bmN0aW9uIGlzUG9qbyhpbnB1dCkgewogIGlmICghaXNQbGFpbk9iamVjdChpbnB1dCkpIHsKICAgIHJldHVybiBmYWxzZTsKICB9CgogIHRyeSB7CiAgICBjb25zdCBuYW1lID0gKE9iamVjdC5nZXRQcm90b3R5cGVPZihpbnB1dCkgKS5jb25zdHJ1Y3Rvci5uYW1lOwogICAgcmV0dXJuICFuYW1lIHx8IG5hbWUgPT09ICdPYmplY3QnOwogIH0gY2F0Y2ggKGUpIHsKICAgIHJldHVybiB0cnVlOwogIH0KfQoKLyoqCiAqIERvZXMgdGhpcyBmaWxlbmFtZSBsb29rIGxpa2UgaXQncyBwYXJ0IG9mIHRoZSBhcHAgY29kZT8KICovCmZ1bmN0aW9uIGZpbGVuYW1lSXNJbkFwcChmaWxlbmFtZSwgaXNOYXRpdmUgPSBmYWxzZSkgewogIGNvbnN0IGlzSW50ZXJuYWwgPQogICAgaXNOYXRpdmUgfHwKICAgIChmaWxlbmFtZSAmJgogICAgICAvLyBJdCdzIG5vdCBpbnRlcm5hbCBpZiBpdCdzIGFuIGFic29sdXRlIGxpbnV4IHBhdGgKICAgICAgIWZpbGVuYW1lLnN0YXJ0c1dpdGgoJy8nKSAmJgogICAgICAvLyBJdCdzIG5vdCBpbnRlcm5hbCBpZiBpdCdzIGFuIGFic29sdXRlIHdpbmRvd3MgcGF0aAogICAgICAhZmlsZW5hbWUubWF0Y2goL15bQS1aXTovKSAmJgogICAgICAvLyBJdCdzIG5vdCBpbnRlcm5hbCBpZiB0aGUgcGF0aCBpcyBzdGFydGluZyB3aXRoIGEgZG90CiAgICAgICFmaWxlbmFtZS5zdGFydHNXaXRoKCcuJykgJiYKICAgICAgLy8gSXQncyBub3QgaW50ZXJuYWwgaWYgdGhlIGZyYW1lIGhhcyBhIHByb3RvY29sLiBJbiBub2RlLCB0aGlzIGlzIHVzdWFsbHkgdGhlIGNhc2UgaWYgdGhlIGZpbGUgZ290IHByZS1wcm9jZXNzZWQgd2l0aCBhIGJ1bmRsZXIgbGlrZSB3ZWJwYWNrCiAgICAgICFmaWxlbmFtZS5tYXRjaCgvXlthLXpBLVpdKFthLXpBLVowLTkuXC0rXSkqOlwvXC8vKSk7IC8vIFNjaGVtYSBmcm9tOiBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMzY0MTc4MgoKICAvLyBpbl9hcHAgaXMgYWxsIHRoYXQncyBub3QgYW4gaW50ZXJuYWwgTm9kZSBmdW5jdGlvbiBvciBhIG1vZHVsZSB3aXRoaW4gbm9kZV9tb2R1bGVzCiAgLy8gbm90ZSB0aGF0IGlzTmF0aXZlIGFwcGVhcnMgdG8gcmV0dXJuIHRydWUgZXZlbiBmb3Igbm9kZSBjb3JlIGxpYnJhcmllcwogIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vZ2V0c2VudHJ5L3JhdmVuLW5vZGUvaXNzdWVzLzE3NgoKICByZXR1cm4gIWlzSW50ZXJuYWwgJiYgZmlsZW5hbWUgIT09IHVuZGVmaW5lZCAmJiAhZmlsZW5hbWUuaW5jbHVkZXMoJ25vZGVfbW9kdWxlcy8nKTsKfQoKY29uc3QgU1RBQ0tUUkFDRV9GUkFNRV9MSU1JVCA9IDUwOwpjb25zdCBTVFJJUF9GUkFNRV9SRUdFWFAgPSAvY2FwdHVyZU1lc3NhZ2V8Y2FwdHVyZUV4Y2VwdGlvbi87CgovKioKICogUmVtb3ZlcyBTZW50cnkgZnJhbWVzIGZyb20gdGhlIHRvcCBhbmQgYm90dG9tIG9mIHRoZSBzdGFjayBpZiBwcmVzZW50IGFuZCBlbmZvcmNlcyBhIGxpbWl0IG9mIG1heCBudW1iZXIgb2YgZnJhbWVzLgogKiBBc3N1bWVzIHN0YWNrIGlucHV0IGlzIG9yZGVyZWQgZnJvbSB0b3AgdG8gYm90dG9tIGFuZCByZXR1cm5zIHRoZSByZXZlcnNlIHJlcHJlc2VudGF0aW9uIHNvIGNhbGwgc2l0ZSBvZiB0aGUKICogZnVuY3Rpb24gdGhhdCBjYXVzZWQgdGhlIGNyYXNoIGlzIHRoZSBsYXN0IGZyYW1lIGluIHRoZSBhcnJheS4KICogQGhpZGRlbgogKi8KZnVuY3Rpb24gc3RyaXBTZW50cnlGcmFtZXNBbmRSZXZlcnNlKHN0YWNrKSB7CiAgaWYgKCFzdGFjay5sZW5ndGgpIHsKICAgIHJldHVybiBbXTsKICB9CgogIGNvbnN0IGxvY2FsU3RhY2sgPSBBcnJheS5mcm9tKHN0YWNrKTsKCiAgLy8gSWYgc3RhY2sgc3RhcnRzIHdpdGggb25lIG9mIG91ciBBUEkgY2FsbHMsIHJlbW92ZSBpdCAoc3RhcnRzLCBtZWFuaW5nIGl0J3MgdGhlIHRvcCBvZiB0aGUgc3RhY2sgLSBha2EgbGFzdCBjYWxsKQogIGlmICgvc2VudHJ5V3JhcHBlZC8udGVzdChsb2NhbFN0YWNrW2xvY2FsU3RhY2subGVuZ3RoIC0gMV0uZnVuY3Rpb24gfHwgJycpKSB7CiAgICBsb2NhbFN0YWNrLnBvcCgpOwogIH0KCiAgLy8gUmV2ZXJzaW5nIGluIHRoZSBtaWRkbGUgb2YgdGhlIHByb2NlZHVyZSBhbGxvd3MgdXMgdG8ganVzdCBwb3AgdGhlIHZhbHVlcyBvZmYgdGhlIHN0YWNrCiAgbG9jYWxTdGFjay5yZXZlcnNlKCk7CgogIC8vIElmIHN0YWNrIGVuZHMgd2l0aCBvbmUgb2Ygb3VyIGludGVybmFsIEFQSSBjYWxscywgcmVtb3ZlIGl0IChlbmRzLCBtZWFuaW5nIGl0J3MgdGhlIGJvdHRvbSBvZiB0aGUgc3RhY2sgLSBha2EgdG9wLW1vc3QgY2FsbCkKICBpZiAoU1RSSVBfRlJBTUVfUkVHRVhQLnRlc3QobG9jYWxTdGFja1tsb2NhbFN0YWNrLmxlbmd0aCAtIDFdLmZ1bmN0aW9uIHx8ICcnKSkgewogICAgbG9jYWxTdGFjay5wb3AoKTsKCiAgICAvLyBXaGVuIHVzaW5nIHN5bnRoZXRpYyBldmVudHMsIHdlIHdpbGwgaGF2ZSBhIDIgbGV2ZWxzIGRlZXAgc3RhY2ssIGFzIGBuZXcgRXJyb3IoJ1NlbnRyeSBzeW50aGV0aWNFeGNlcHRpb24nKWAKICAgIC8vIGlzIHByb2R1Y2VkIHdpdGhpbiB0aGUgaHViIGl0c2VsZiwgbWFraW5nIGl0OgogICAgLy8KICAgIC8vICAgU2VudHJ5LmNhcHR1cmVFeGNlcHRpb24oKQogICAgLy8gICBnZXRDdXJyZW50SHViKCkuY2FwdHVyZUV4Y2VwdGlvbigpCiAgICAvLwogICAgLy8gaW5zdGVhZCBvZiBqdXN0IHRoZSB0b3AgYFNlbnRyeWAgY2FsbCBpdHNlbGYuCiAgICAvLyBUaGlzIGZvcmNlcyB1cyB0byBwb3NzaWJseSBzdHJpcCBhbiBhZGRpdGlvbmFsIGZyYW1lIGluIHRoZSBleGFjdCBzYW1lIHdhcyBhcyBhYm92ZS4KICAgIGlmIChTVFJJUF9GUkFNRV9SRUdFWFAudGVzdChsb2NhbFN0YWNrW2xvY2FsU3RhY2subGVuZ3RoIC0gMV0uZnVuY3Rpb24gfHwgJycpKSB7CiAgICAgIGxvY2FsU3RhY2sucG9wKCk7CiAgICB9CiAgfQoKICByZXR1cm4gbG9jYWxTdGFjay5zbGljZSgwLCBTVEFDS1RSQUNFX0ZSQU1FX0xJTUlUKS5tYXAoZnJhbWUgPT4gKHsKICAgIC4uLmZyYW1lLAogICAgZmlsZW5hbWU6IGZyYW1lLmZpbGVuYW1lIHx8IGxvY2FsU3RhY2tbbG9jYWxTdGFjay5sZW5ndGggLSAxXS5maWxlbmFtZSwKICAgIGZ1bmN0aW9uOiBmcmFtZS5mdW5jdGlvbiB8fCAnPycsCiAgfSkpOwp9Cgpjb25zdCBkZWZhdWx0RnVuY3Rpb25OYW1lID0gJzxhbm9ueW1vdXM+JzsKCi8qKgogKiBTYWZlbHkgZXh0cmFjdCBmdW5jdGlvbiBuYW1lIGZyb20gaXRzZWxmCiAqLwpmdW5jdGlvbiBnZXRGdW5jdGlvbk5hbWUoZm4pIHsKICB0cnkgewogICAgaWYgKCFmbiB8fCB0eXBlb2YgZm4gIT09ICdmdW5jdGlvbicpIHsKICAgICAgcmV0dXJuIGRlZmF1bHRGdW5jdGlvbk5hbWU7CiAgICB9CiAgICByZXR1cm4gZm4ubmFtZSB8fCBkZWZhdWx0RnVuY3Rpb25OYW1lOwogIH0gY2F0Y2ggKGUpIHsKICAgIC8vIEp1c3QgYWNjZXNzaW5nIGN1c3RvbSBwcm9wcyBpbiBzb21lIFNlbGVuaXVtIGVudmlyb25tZW50cwogICAgLy8gY2FuIGNhdXNlIGEgIlBlcm1pc3Npb24gZGVuaWVkIiBleGNlcHRpb24gKHNlZSByYXZlbi1qcyM0OTUpLgogICAgcmV0dXJuIGRlZmF1bHRGdW5jdGlvbk5hbWU7CiAgfQp9CgovKioKICogVVVJRDQgZ2VuZXJhdG9yCiAqCiAqIEByZXR1cm5zIHN0cmluZyBHZW5lcmF0ZWQgVVVJRDQuCiAqLwpmdW5jdGlvbiB1dWlkNCgpIHsKICBjb25zdCBnYmwgPSBHTE9CQUxfT0JKIDsKICBjb25zdCBjcnlwdG8gPSBnYmwuY3J5cHRvIHx8IGdibC5tc0NyeXB0bzsKCiAgbGV0IGdldFJhbmRvbUJ5dGUgPSAoKSA9PiBNYXRoLnJhbmRvbSgpICogMTY7CiAgdHJ5IHsKICAgIGlmIChjcnlwdG8gJiYgY3J5cHRvLnJhbmRvbVVVSUQpIHsKICAgICAgcmV0dXJuIGNyeXB0by5yYW5kb21VVUlEKCkucmVwbGFjZSgvLS9nLCAnJyk7CiAgICB9CiAgICBpZiAoY3J5cHRvICYmIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMpIHsKICAgICAgZ2V0UmFuZG9tQnl0ZSA9ICgpID0+IHsKICAgICAgICAvLyBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzIG1pZ2h0IHJldHVybiB1bmRlZmluZWQgaW5zdGVhZCBvZiB0aGUgdHlwZWQgYXJyYXkKICAgICAgICAvLyBpbiBvbGQgQ2hyb21pdW0gdmVyc2lvbnMgKGUuZy4gMjMuMC4xMjM1LjAgKDE1MTQyMikpCiAgICAgICAgLy8gSG93ZXZlciwgYHR5cGVkQXJyYXlgIGlzIHN0aWxsIGZpbGxlZCBpbi1wbGFjZS4KICAgICAgICAvLyBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9DcnlwdG8vZ2V0UmFuZG9tVmFsdWVzI3R5cGVkYXJyYXkKICAgICAgICBjb25zdCB0eXBlZEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoMSk7CiAgICAgICAgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyh0eXBlZEFycmF5KTsKICAgICAgICByZXR1cm4gdHlwZWRBcnJheVswXTsKICAgICAgfTsKICAgIH0KICB9IGNhdGNoIChfKSB7CiAgICAvLyBzb21lIHJ1bnRpbWVzIGNhbiBjcmFzaCBpbnZva2luZyBjcnlwdG8KICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9nZXRzZW50cnkvc2VudHJ5LWphdmFzY3JpcHQvaXNzdWVzLzg5MzUKICB9CgogIC8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTA1MDM0L2hvdy10by1jcmVhdGUtYS1ndWlkLXV1aWQtaW4tamF2YXNjcmlwdC8yMTE3NTIzIzIxMTc1MjMKICAvLyBDb25jYXRlbmF0aW5nIHRoZSBmb2xsb3dpbmcgbnVtYmVycyBhcyBzdHJpbmdzIHJlc3VsdHMgaW4gJzEwMDAwMDAwMTAwMDQwMDA4MDAwMTAwMDAwMDAwMDAwJwogIHJldHVybiAoKFsxZTddICkgKyAxZTMgKyA0ZTMgKyA4ZTMgKyAxZTExKS5yZXBsYWNlKC9bMDE4XS9nLCBjID0+CiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYml0d2lzZQogICAgKChjICkgXiAoKGdldFJhbmRvbUJ5dGUoKSAmIDE1KSA+PiAoKGMgKSAvIDQpKSkudG9TdHJpbmcoMTYpLAogICk7Cn0KCi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtbWVtYmVyLWFjY2VzcyAqLwovKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55ICovCgovKioKICogSGVscGVyIHRvIGRlY3ljbGUganNvbiBvYmplY3RzCiAqLwpmdW5jdGlvbiBtZW1vQnVpbGRlcigpIHsKICBjb25zdCBoYXNXZWFrU2V0ID0gdHlwZW9mIFdlYWtTZXQgPT09ICdmdW5jdGlvbic7CiAgY29uc3QgaW5uZXIgPSBoYXNXZWFrU2V0ID8gbmV3IFdlYWtTZXQoKSA6IFtdOwogIGZ1bmN0aW9uIG1lbW9pemUob2JqKSB7CiAgICBpZiAoaGFzV2Vha1NldCkgewogICAgICBpZiAoaW5uZXIuaGFzKG9iaikpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpbm5lci5hZGQob2JqKTsKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9wcmVmZXItZm9yLW9mCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGlubmVyLmxlbmd0aDsgaSsrKSB7CiAgICAgIGNvbnN0IHZhbHVlID0gaW5uZXJbaV07CiAgICAgIGlmICh2YWx1ZSA9PT0gb2JqKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgIH0KICAgIGlubmVyLnB1c2gob2JqKTsKICAgIHJldHVybiBmYWxzZTsKICB9CgogIGZ1bmN0aW9uIHVubWVtb2l6ZShvYmopIHsKICAgIGlmIChoYXNXZWFrU2V0KSB7CiAgICAgIGlubmVyLmRlbGV0ZShvYmopOwogICAgfSBlbHNlIHsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbm5lci5sZW5ndGg7IGkrKykgewogICAgICAgIGlmIChpbm5lcltpXSA9PT0gb2JqKSB7CiAgICAgICAgICBpbm5lci5zcGxpY2UoaSwgMSk7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIFttZW1vaXplLCB1bm1lbW9pemVdOwp9CgovKioKICogUmVjdXJzaXZlbHkgbm9ybWFsaXplcyB0aGUgZ2l2ZW4gb2JqZWN0LgogKgogKiAtIENyZWF0ZXMgYSBjb3B5IHRvIHByZXZlbnQgb3JpZ2luYWwgaW5wdXQgbXV0YXRpb24KICogLSBTa2lwcyBub24tZW51bWVyYWJsZSBwcm9wZXJ0aWVzCiAqIC0gV2hlbiBzdHJpbmdpZnlpbmcsIGNhbGxzIGB0b0pTT05gIGlmIGltcGxlbWVudGVkCiAqIC0gUmVtb3ZlcyBjaXJjdWxhciByZWZlcmVuY2VzCiAqIC0gVHJhbnNsYXRlcyBub24tc2VyaWFsaXphYmxlIHZhbHVlcyAoYHVuZGVmaW5lZGAvYE5hTmAvZnVuY3Rpb25zKSB0byBzZXJpYWxpemFibGUgZm9ybWF0CiAqIC0gVHJhbnNsYXRlcyBrbm93biBnbG9iYWwgb2JqZWN0cy9jbGFzc2VzIHRvIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9ucwogKiAtIFRha2VzIGNhcmUgb2YgYEVycm9yYCBvYmplY3Qgc2VyaWFsaXphdGlvbgogKiAtIE9wdGlvbmFsbHkgbGltaXRzIGRlcHRoIG9mIGZpbmFsIG91dHB1dAogKiAtIE9wdGlvbmFsbHkgbGltaXRzIG51bWJlciBvZiBwcm9wZXJ0aWVzL2VsZW1lbnRzIGluY2x1ZGVkIGluIGFueSBzaW5nbGUgb2JqZWN0L2FycmF5CiAqCiAqIEBwYXJhbSBpbnB1dCBUaGUgb2JqZWN0IHRvIGJlIG5vcm1hbGl6ZWQuCiAqIEBwYXJhbSBkZXB0aCBUaGUgbWF4IGRlcHRoIHRvIHdoaWNoIHRvIG5vcm1hbGl6ZSB0aGUgb2JqZWN0LiAoQW55dGhpbmcgZGVlcGVyIHN0cmluZ2lmaWVkIHdob2xlLikKICogQHBhcmFtIG1heFByb3BlcnRpZXMgVGhlIG1heCBudW1iZXIgb2YgZWxlbWVudHMgb3IgcHJvcGVydGllcyB0byBiZSBpbmNsdWRlZCBpbiBhbnkgc2luZ2xlIGFycmF5IG9yCiAqIG9iamVjdCBpbiB0aGUgbm9ybWFsbGl6ZWQgb3V0cHV0LgogKiBAcmV0dXJucyBBIG5vcm1hbGl6ZWQgdmVyc2lvbiBvZiB0aGUgb2JqZWN0LCBvciBgIioqbm9uLXNlcmlhbGl6YWJsZSoqImAgaWYgYW55IGVycm9ycyBhcmUgdGhyb3duIGR1cmluZyBub3JtYWxpemF0aW9uLgogKi8KLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkKZnVuY3Rpb24gbm9ybWFsaXplKGlucHV0LCBkZXB0aCA9IDEwMCwgbWF4UHJvcGVydGllcyA9ICtJbmZpbml0eSkgewogIHRyeSB7CiAgICAvLyBzaW5jZSB3ZSdyZSBhdCB0aGUgb3V0ZXJtb3N0IGxldmVsLCB3ZSBkb24ndCBwcm92aWRlIGEga2V5CiAgICByZXR1cm4gdmlzaXQoJycsIGlucHV0LCBkZXB0aCwgbWF4UHJvcGVydGllcyk7CiAgfSBjYXRjaCAoZXJyKSB7CiAgICByZXR1cm4geyBFUlJPUjogYCoqbm9uLXNlcmlhbGl6YWJsZSoqICgke2Vycn0pYCB9OwogIH0KfQoKLyoqCiAqIFZpc2l0cyBhIG5vZGUgdG8gcGVyZm9ybSBub3JtYWxpemF0aW9uIG9uIGl0CiAqCiAqIEBwYXJhbSBrZXkgVGhlIGtleSBjb3JyZXNwb25kaW5nIHRvIHRoZSBnaXZlbiBub2RlCiAqIEBwYXJhbSB2YWx1ZSBUaGUgbm9kZSB0byBiZSB2aXNpdGVkCiAqIEBwYXJhbSBkZXB0aCBPcHRpb25hbCBudW1iZXIgaW5kaWNhdGluZyB0aGUgbWF4aW11bSByZWN1cnNpb24gZGVwdGgKICogQHBhcmFtIG1heFByb3BlcnRpZXMgT3B0aW9uYWwgbWF4aW11bSBudW1iZXIgb2YgcHJvcGVydGllcy9lbGVtZW50cyBpbmNsdWRlZCBpbiBhbnkgc2luZ2xlIG9iamVjdC9hcnJheQogKiBAcGFyYW0gbWVtbyBPcHRpb25hbCBNZW1vIGNsYXNzIGhhbmRsaW5nIGRlY3ljbGluZwogKi8KZnVuY3Rpb24gdmlzaXQoCiAga2V5LAogIHZhbHVlLAogIGRlcHRoID0gK0luZmluaXR5LAogIG1heFByb3BlcnRpZXMgPSArSW5maW5pdHksCiAgbWVtbyA9IG1lbW9CdWlsZGVyKCksCikgewogIGNvbnN0IFttZW1vaXplLCB1bm1lbW9pemVdID0gbWVtbzsKCiAgLy8gR2V0IHRoZSBzaW1wbGUgY2FzZXMgb3V0IG9mIHRoZSB3YXkgZmlyc3QKICBpZiAoCiAgICB2YWx1ZSA9PSBudWxsIHx8IC8vIHRoaXMgbWF0Y2hlcyBudWxsIGFuZCB1bmRlZmluZWQgLT4gZXFlcSBub3QgZXFlcWVxCiAgICAoWydudW1iZXInLCAnYm9vbGVhbicsICdzdHJpbmcnXS5pbmNsdWRlcyh0eXBlb2YgdmFsdWUpICYmICFpc05hTiQxKHZhbHVlKSkKICApIHsKICAgIHJldHVybiB2YWx1ZSA7CiAgfQoKICBjb25zdCBzdHJpbmdpZmllZCA9IHN0cmluZ2lmeVZhbHVlKGtleSwgdmFsdWUpOwoKICAvLyBBbnl0aGluZyB3ZSBjb3VsZCBwb3RlbnRpYWxseSBkaWcgaW50byBtb3JlIChvYmplY3RzIG9yIGFycmF5cykgd2lsbCBoYXZlIGNvbWUgYmFjayBhcyBgIltvYmplY3QgWFhYWF0iYC4KICAvLyBFdmVyeXRoaW5nIGVsc2Ugd2lsbCBoYXZlIGFscmVhZHkgYmVlbiBzZXJpYWxpemVkLCBzbyBpZiB3ZSBkb24ndCBzZWUgdGhhdCBwYXR0ZXJuLCB3ZSdyZSBkb25lLgogIGlmICghc3RyaW5naWZpZWQuc3RhcnRzV2l0aCgnW29iamVjdCAnKSkgewogICAgcmV0dXJuIHN0cmluZ2lmaWVkOwogIH0KCiAgLy8gRnJvbSBoZXJlIG9uLCB3ZSBjYW4gYXNzZXJ0IHRoYXQgYHZhbHVlYCBpcyBlaXRoZXIgYW4gb2JqZWN0IG9yIGFuIGFycmF5LgoKICAvLyBEbyBub3Qgbm9ybWFsaXplIG9iamVjdHMgdGhhdCB3ZSBrbm93IGhhdmUgYWxyZWFkeSBiZWVuIG5vcm1hbGl6ZWQuIEFzIGEgZ2VuZXJhbCBydWxlLCB0aGUKICAvLyAiX19zZW50cnlfc2tpcF9ub3JtYWxpemF0aW9uX18iIHByb3BlcnR5IHNob3VsZCBvbmx5IGJlIHVzZWQgc3BhcmluZ2x5IGFuZCBvbmx5IHNob3VsZCBvbmx5IGJlIHNldCBvbiBvYmplY3RzIHRoYXQKICAvLyBoYXZlIGFscmVhZHkgYmVlbiBub3JtYWxpemVkLgogIGlmICgodmFsdWUgKVsnX19zZW50cnlfc2tpcF9ub3JtYWxpemF0aW9uX18nXSkgewogICAgcmV0dXJuIHZhbHVlIDsKICB9CgogIC8vIFdlIGNhbiBzZXQgYF9fc2VudHJ5X292ZXJyaWRlX25vcm1hbGl6YXRpb25fZGVwdGhfX2Agb24gYW4gb2JqZWN0IHRvIGVuc3VyZSB0aGF0IGZyb20gdGhlcmUKICAvLyBXZSBrZWVwIGEgY2VydGFpbiBhbW91bnQgb2YgZGVwdGguCiAgLy8gVGhpcyBzaG91bGQgYmUgdXNlZCBzcGFyaW5nbHksIGUuZy4gd2UgdXNlIGl0IGZvciB0aGUgcmVkdXggaW50ZWdyYXRpb24gdG8gZW5zdXJlIHdlIGdldCBhIGNlcnRhaW4gYW1vdW50IG9mIHN0YXRlLgogIGNvbnN0IHJlbWFpbmluZ0RlcHRoID0KICAgIHR5cGVvZiAodmFsdWUgKVsnX19zZW50cnlfb3ZlcnJpZGVfbm9ybWFsaXphdGlvbl9kZXB0aF9fJ10gPT09ICdudW1iZXInCiAgICAgID8gKCh2YWx1ZSApWydfX3NlbnRyeV9vdmVycmlkZV9ub3JtYWxpemF0aW9uX2RlcHRoX18nXSApCiAgICAgIDogZGVwdGg7CgogIC8vIFdlJ3JlIGFsc28gZG9uZSBpZiB3ZSd2ZSByZWFjaGVkIHRoZSBtYXggZGVwdGgKICBpZiAocmVtYWluaW5nRGVwdGggPT09IDApIHsKICAgIC8vIEF0IHRoaXMgcG9pbnQgd2Uga25vdyBgc2VyaWFsaXplZGAgaXMgYSBzdHJpbmcgb2YgdGhlIGZvcm0gYCJbb2JqZWN0IFhYWFhdImAuIENsZWFuIGl0IHVwIHNvIGl0J3MganVzdCBgIltYWFhYXSJgLgogICAgcmV0dXJuIHN0cmluZ2lmaWVkLnJlcGxhY2UoJ29iamVjdCAnLCAnJyk7CiAgfQoKICAvLyBJZiB3ZSd2ZSBhbHJlYWR5IHZpc2l0ZWQgdGhpcyBicmFuY2gsIGJhaWwgb3V0LCBhcyBpdCdzIGNpcmN1bGFyIHJlZmVyZW5jZS4gSWYgbm90LCBub3RlIHRoYXQgd2UncmUgc2VlaW5nIGl0IG5vdy4KICBpZiAobWVtb2l6ZSh2YWx1ZSkpIHsKICAgIHJldHVybiAnW0NpcmN1bGFyIH5dJzsKICB9CgogIC8vIElmIHRoZSB2YWx1ZSBoYXMgYSBgdG9KU09OYCBtZXRob2QsIHdlIGNhbGwgaXQgdG8gZXh0cmFjdCBtb3JlIGluZm9ybWF0aW9uCiAgY29uc3QgdmFsdWVXaXRoVG9KU09OID0gdmFsdWUgOwogIGlmICh2YWx1ZVdpdGhUb0pTT04gJiYgdHlwZW9mIHZhbHVlV2l0aFRvSlNPTi50b0pTT04gPT09ICdmdW5jdGlvbicpIHsKICAgIHRyeSB7CiAgICAgIGNvbnN0IGpzb25WYWx1ZSA9IHZhbHVlV2l0aFRvSlNPTi50b0pTT04oKTsKICAgICAgLy8gV2UgbmVlZCB0byBub3JtYWxpemUgdGhlIHJldHVybiB2YWx1ZSBvZiBgLnRvSlNPTigpYCBpbiBjYXNlIGl0IGhhcyBjaXJjdWxhciByZWZlcmVuY2VzCiAgICAgIHJldHVybiB2aXNpdCgnJywganNvblZhbHVlLCByZW1haW5pbmdEZXB0aCAtIDEsIG1heFByb3BlcnRpZXMsIG1lbW8pOwogICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgIC8vIHBhc3MgKFRoZSBidWlsdC1pbiBgdG9KU09OYCBmYWlsZWQsIGJ1dCB3ZSBjYW4gc3RpbGwgdHJ5IHRvIGRvIGl0IG91cnNlbHZlcykKICAgIH0KICB9CgogIC8vIEF0IHRoaXMgcG9pbnQgd2Uga25vdyB3ZSBlaXRoZXIgaGF2ZSBhbiBvYmplY3Qgb3IgYW4gYXJyYXksIHdlIGhhdmVuJ3Qgc2VlbiBpdCBiZWZvcmUsIGFuZCB3ZSdyZSBnb2luZyB0byByZWN1cnNlCiAgLy8gYmVjYXVzZSB3ZSBoYXZlbid0IHlldCByZWFjaGVkIHRoZSBtYXggZGVwdGguIENyZWF0ZSBhbiBhY2N1bXVsYXRvciB0byBob2xkIHRoZSByZXN1bHRzIG9mIHZpc2l0aW5nIGVhY2gKICAvLyBwcm9wZXJ0eS9lbnRyeSwgYW5kIGtlZXAgdHJhY2sgb2YgdGhlIG51bWJlciBvZiBpdGVtcyB3ZSBhZGQgdG8gaXQuCiAgY29uc3Qgbm9ybWFsaXplZCA9IChBcnJheS5pc0FycmF5KHZhbHVlKSA/IFtdIDoge30pIDsKICBsZXQgbnVtQWRkZWQgPSAwOwoKICAvLyBCZWZvcmUgd2UgYmVnaW4sIGNvbnZlcnRgRXJyb3JgIGFuZGBFdmVudGAgaW5zdGFuY2VzIGludG8gcGxhaW4gb2JqZWN0cywgc2luY2Ugc29tZSBvZiBlYWNoIG9mIHRoZWlyIHJlbGV2YW50CiAgLy8gcHJvcGVydGllcyBhcmUgbm9uLWVudW1lcmFibGUgYW5kIG90aGVyd2lzZSB3b3VsZCBnZXQgbWlzc2VkLgogIGNvbnN0IHZpc2l0YWJsZSA9IGNvbnZlcnRUb1BsYWluT2JqZWN0KHZhbHVlICk7CgogIGZvciAoY29uc3QgdmlzaXRLZXkgaW4gdmlzaXRhYmxlKSB7CiAgICAvLyBBdm9pZCBpdGVyYXRpbmcgb3ZlciBmaWVsZHMgaW4gdGhlIHByb3RvdHlwZSBpZiB0aGV5J3ZlIHNvbWVob3cgYmVlbiBleHBvc2VkIHRvIGVudW1lcmF0aW9uLgogICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodmlzaXRhYmxlLCB2aXNpdEtleSkpIHsKICAgICAgY29udGludWU7CiAgICB9CgogICAgaWYgKG51bUFkZGVkID49IG1heFByb3BlcnRpZXMpIHsKICAgICAgbm9ybWFsaXplZFt2aXNpdEtleV0gPSAnW01heFByb3BlcnRpZXMgfl0nOwogICAgICBicmVhazsKICAgIH0KCiAgICAvLyBSZWN1cnNpdmVseSB2aXNpdCBhbGwgdGhlIGNoaWxkIG5vZGVzCiAgICBjb25zdCB2aXNpdFZhbHVlID0gdmlzaXRhYmxlW3Zpc2l0S2V5XTsKICAgIG5vcm1hbGl6ZWRbdmlzaXRLZXldID0gdmlzaXQodmlzaXRLZXksIHZpc2l0VmFsdWUsIHJlbWFpbmluZ0RlcHRoIC0gMSwgbWF4UHJvcGVydGllcywgbWVtbyk7CgogICAgbnVtQWRkZWQrKzsKICB9CgogIC8vIE9uY2Ugd2UndmUgdmlzaXRlZCBhbGwgdGhlIGJyYW5jaGVzLCByZW1vdmUgdGhlIHBhcmVudCBmcm9tIG1lbW8gc3RvcmFnZQogIHVubWVtb2l6ZSh2YWx1ZSk7CgogIC8vIFJldHVybiBhY2N1bXVsYXRlZCB2YWx1ZXMKICByZXR1cm4gbm9ybWFsaXplZDsKfQoKLyogZXNsaW50LWRpc2FibGUgY29tcGxleGl0eSAqLwovKioKICogU3RyaW5naWZ5IHRoZSBnaXZlbiB2YWx1ZS4gSGFuZGxlcyB2YXJpb3VzIGtub3duIHNwZWNpYWwgdmFsdWVzIGFuZCB0eXBlcy4KICoKICogTm90IG1lYW50IHRvIGJlIHVzZWQgb24gc2ltcGxlIHByaW1pdGl2ZXMgd2hpY2ggYWxyZWFkeSBoYXZlIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uLCBhcyBpdCB3aWxsLCBmb3IgZXhhbXBsZSwgdHVybgogKiB0aGUgbnVtYmVyIDEyMzEgaW50byAiW09iamVjdCBOdW1iZXJdIiwgbm9yIG9uIGBudWxsYCwgYXMgaXQgd2lsbCB0aHJvdy4KICoKICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSB0byBzdHJpbmdpZnkKICogQHJldHVybnMgQSBzdHJpbmdpZmllZCByZXByZXNlbnRhdGlvbiBvZiB0aGUgZ2l2ZW4gdmFsdWUKICovCmZ1bmN0aW9uIHN0cmluZ2lmeVZhbHVlKAogIGtleSwKICAvLyB0aGlzIHR5cGUgaXMgYSB0aW55IGJpdCBvZiBhIGNoZWF0LCBzaW5jZSB0aGlzIGZ1bmN0aW9uIGRvZXMgaGFuZGxlIE5hTiAod2hpY2ggaXMgdGVjaG5pY2FsbHkgYSBudW1iZXIpLCBidXQgZm9yCiAgLy8gb3VyIGludGVybmFsIHVzZSwgaXQnbGwgZG8KICB2YWx1ZSwKKSB7CiAgdHJ5IHsKICAgIGlmIChrZXkgPT09ICdkb21haW4nICYmIHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgKHZhbHVlICkuX2V2ZW50cykgewogICAgICByZXR1cm4gJ1tEb21haW5dJzsKICAgIH0KCiAgICBpZiAoa2V5ID09PSAnZG9tYWluRW1pdHRlcicpIHsKICAgICAgcmV0dXJuICdbRG9tYWluRW1pdHRlcl0nOwogICAgfQoKICAgIC8vIEl0J3Mgc2FmZSB0byB1c2UgYGdsb2JhbGAsIGB3aW5kb3dgLCBhbmQgYGRvY3VtZW50YCBoZXJlIGluIHRoaXMgbWFubmVyLCBhcyB3ZSBhcmUgYXNzZXJ0aW5nIHVzaW5nIGB0eXBlb2ZgIGZpcnN0CiAgICAvLyB3aGljaCB3b24ndCB0aHJvdyBpZiB0aGV5IGFyZSBub3QgcHJlc2VudC4KCiAgICBpZiAodHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcgJiYgdmFsdWUgPT09IGdsb2JhbCkgewogICAgICByZXR1cm4gJ1tHbG9iYWxdJzsKICAgIH0KCiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1nbG9iYWxzCiAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgdmFsdWUgPT09IHdpbmRvdykgewogICAgICByZXR1cm4gJ1tXaW5kb3ddJzsKICAgIH0KCiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1nbG9iYWxzCiAgICBpZiAodHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyAmJiB2YWx1ZSA9PT0gZG9jdW1lbnQpIHsKICAgICAgcmV0dXJuICdbRG9jdW1lbnRdJzsKICAgIH0KCiAgICBpZiAoaXNWdWVWaWV3TW9kZWwodmFsdWUpKSB7CiAgICAgIHJldHVybiAnW1Z1ZVZpZXdNb2RlbF0nOwogICAgfQoKICAgIC8vIFJlYWN0J3MgU3ludGhldGljRXZlbnQgdGhpbmd5CiAgICBpZiAoaXNTeW50aGV0aWNFdmVudCh2YWx1ZSkpIHsKICAgICAgcmV0dXJuICdbU3ludGhldGljRXZlbnRdJzsKICAgIH0KCiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyAmJiB2YWx1ZSAhPT0gdmFsdWUpIHsKICAgICAgcmV0dXJuICdbTmFOXSc7CiAgICB9CgogICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykgewogICAgICByZXR1cm4gYFtGdW5jdGlvbjogJHtnZXRGdW5jdGlvbk5hbWUodmFsdWUpfV1gOwogICAgfQoKICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzeW1ib2wnKSB7CiAgICAgIHJldHVybiBgWyR7U3RyaW5nKHZhbHVlKX1dYDsKICAgIH0KCiAgICAvLyBzdHJpbmdpZmllZCBCaWdJbnRzIGFyZSBpbmRpc3Rpbmd1aXNoYWJsZSBmcm9tIHJlZ3VsYXIgbnVtYmVycywgc28gd2UgbmVlZCB0byBsYWJlbCB0aGVtIHRvIGF2b2lkIGNvbmZ1c2lvbgogICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2JpZ2ludCcpIHsKICAgICAgcmV0dXJuIGBbQmlnSW50OiAke1N0cmluZyh2YWx1ZSl9XWA7CiAgICB9CgogICAgLy8gTm93IHRoYXQgd2UndmUga25vY2tlZCBvdXQgYWxsIHRoZSBzcGVjaWFsIGNhc2VzIGFuZCB0aGUgcHJpbWl0aXZlcywgYWxsIHdlIGhhdmUgbGVmdCBhcmUgb2JqZWN0cy4gU2ltcGx5IGNhc3RpbmcKICAgIC8vIHRoZW0gdG8gc3RyaW5ncyBtZWFucyB0aGF0IGluc3RhbmNlcyBvZiBjbGFzc2VzIHdoaWNoIGhhdmVuJ3QgZGVmaW5lZCB0aGVpciBgdG9TdHJpbmdUYWdgIHdpbGwganVzdCBjb21lIG91dCBhcwogICAgLy8gYCJbb2JqZWN0IE9iamVjdF0iYC4gSWYgd2UgaW5zdGVhZCBsb29rIGF0IHRoZSBjb25zdHJ1Y3RvcidzIG5hbWUgKHdoaWNoIGlzIHRoZSBzYW1lIGFzIHRoZSBuYW1lIG9mIHRoZSBjbGFzcyksCiAgICAvLyB3ZSBjYW4gbWFrZSBzdXJlIHRoYXQgb25seSBwbGFpbiBvYmplY3RzIGNvbWUgb3V0IHRoYXQgd2F5LgogICAgY29uc3Qgb2JqTmFtZSA9IGdldENvbnN0cnVjdG9yTmFtZSh2YWx1ZSk7CgogICAgLy8gSGFuZGxlIEhUTUwgRWxlbWVudHMKICAgIGlmICgvXkhUTUwoXHcqKUVsZW1lbnQkLy50ZXN0KG9iak5hbWUpKSB7CiAgICAgIHJldHVybiBgW0hUTUxFbGVtZW50OiAke29iak5hbWV9XWA7CiAgICB9CgogICAgcmV0dXJuIGBbb2JqZWN0ICR7b2JqTmFtZX1dYDsKICB9IGNhdGNoIChlcnIpIHsKICAgIHJldHVybiBgKipub24tc2VyaWFsaXphYmxlKiogKCR7ZXJyfSlgOwogIH0KfQovKiBlc2xpbnQtZW5hYmxlIGNvbXBsZXhpdHkgKi8KCmZ1bmN0aW9uIGdldENvbnN0cnVjdG9yTmFtZSh2YWx1ZSkgewogIGNvbnN0IHByb3RvdHlwZSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZih2YWx1ZSk7CgogIHJldHVybiBwcm90b3R5cGUgPyBwcm90b3R5cGUuY29uc3RydWN0b3IubmFtZSA6ICdudWxsIHByb3RvdHlwZSc7Cn0KCi8qKgogKiBOb3JtYWxpemVzIFVSTHMgaW4gZXhjZXB0aW9ucyBhbmQgc3RhY2t0cmFjZXMgdG8gYSBiYXNlIHBhdGggc28gU2VudHJ5IGNhbiBmaW5nZXJwcmludAogKiBhY3Jvc3MgcGxhdGZvcm1zIGFuZCB3b3JraW5nIGRpcmVjdG9yeS4KICoKICogQHBhcmFtIHVybCBUaGUgVVJMIHRvIGJlIG5vcm1hbGl6ZWQuCiAqIEBwYXJhbSBiYXNlUGF0aCBUaGUgYXBwbGljYXRpb24gYmFzZSBwYXRoLgogKiBAcmV0dXJucyBUaGUgbm9ybWFsaXplZCBVUkwuCiAqLwpmdW5jdGlvbiBub3JtYWxpemVVcmxUb0Jhc2UodXJsLCBiYXNlUGF0aCkgewogIGNvbnN0IGVzY2FwZWRCYXNlID0gYmFzZVBhdGgKICAgIC8vIEJhY2tzbGFzaCB0byBmb3J3YXJkCiAgICAucmVwbGFjZSgvXFwvZywgJy8nKQogICAgLy8gRXNjYXBlIFJlZ0V4cCBzcGVjaWFsIGNoYXJhY3RlcnMKICAgIC5yZXBsYWNlKC9bfFxce30oKVtcXV4kKyo/Ll0vZywgJ1xcJCYnKTsKCiAgbGV0IG5ld1VybCA9IHVybDsKICB0cnkgewogICAgbmV3VXJsID0gZGVjb2RlVVJJKHVybCk7CiAgfSBjYXRjaCAoX09vKSB7CiAgICAvLyBTb21ldGltZSB0aGlzIGJyZWFrcwogIH0KICByZXR1cm4gKAogICAgbmV3VXJsCiAgICAgIC5yZXBsYWNlKC9cXC9nLCAnLycpCiAgICAgIC5yZXBsYWNlKC93ZWJwYWNrOlwvPy9nLCAnJykgLy8gUmVtb3ZlIGludGVybWVkaWF0ZSBiYXNlIHBhdGgKICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBzZW50cnktaW50ZXJuYWwvc2RrL25vLXJlZ2V4cC1jb25zdHJ1Y3RvcgogICAgICAucmVwbGFjZShuZXcgUmVnRXhwKGAoZmlsZTovLyk/Lyoke2VzY2FwZWRCYXNlfS8qYCwgJ2lnJyksICdhcHA6Ly8vJykKICApOwp9CgovLyBTbGlnaHRseSBtb2RpZmllZCAobm8gSUU4IHN1cHBvcnQsIEVTNikgYW5kIHRyYW5zY3JpYmVkIHRvIFR5cGVTY3JpcHQKCi8vIFNwbGl0IGEgZmlsZW5hbWUgaW50byBbcm9vdCwgZGlyLCBiYXNlbmFtZSwgZXh0XSwgdW5peCB2ZXJzaW9uCi8vICdyb290JyBpcyBqdXN0IGEgc2xhc2gsIG9yIG5vdGhpbmcuCmNvbnN0IHNwbGl0UGF0aFJlID0gL14oXFMrOlxcfFwvPykoW1xzXFNdKj8pKCg/OlwuezEsMn18W14vXFxdKz98KShcLlteLi9cXF0qfCkpKD86Wy9cXF0qKSQvOwovKiogSlNEb2MgKi8KZnVuY3Rpb24gc3BsaXRQYXRoKGZpbGVuYW1lKSB7CiAgLy8gVHJ1bmNhdGUgZmlsZXMgbmFtZXMgZ3JlYXRlciB0aGFuIDEwMjQgY2hhcmFjdGVycyB0byBhdm9pZCByZWdleCBkb3MKICAvLyBodHRwczovL2dpdGh1Yi5jb20vZ2V0c2VudHJ5L3NlbnRyeS1qYXZhc2NyaXB0L3B1bGwvODczNyNkaXNjdXNzaW9uX3IxMjg1NzE5MTcyCiAgY29uc3QgdHJ1bmNhdGVkID0gZmlsZW5hbWUubGVuZ3RoID4gMTAyNCA/IGA8dHJ1bmNhdGVkPiR7ZmlsZW5hbWUuc2xpY2UoLTEwMjQpfWAgOiBmaWxlbmFtZTsKICBjb25zdCBwYXJ0cyA9IHNwbGl0UGF0aFJlLmV4ZWModHJ1bmNhdGVkKTsKICByZXR1cm4gcGFydHMgPyBwYXJ0cy5zbGljZSgxKSA6IFtdOwp9CgovKiogSlNEb2MgKi8KZnVuY3Rpb24gZGlybmFtZShwYXRoKSB7CiAgY29uc3QgcmVzdWx0ID0gc3BsaXRQYXRoKHBhdGgpOwogIGNvbnN0IHJvb3QgPSByZXN1bHRbMF07CiAgbGV0IGRpciA9IHJlc3VsdFsxXTsKCiAgaWYgKCFyb290ICYmICFkaXIpIHsKICAgIC8vIE5vIGRpcm5hbWUgd2hhdHNvZXZlcgogICAgcmV0dXJuICcuJzsKICB9CgogIGlmIChkaXIpIHsKICAgIC8vIEl0IGhhcyBhIGRpcm5hbWUsIHN0cmlwIHRyYWlsaW5nIHNsYXNoCiAgICBkaXIgPSBkaXIuc2xpY2UoMCwgZGlyLmxlbmd0aCAtIDEpOwogIH0KCiAgcmV0dXJuIHJvb3QgKyBkaXI7Cn0KCi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9leHBsaWNpdC1mdW5jdGlvbi1yZXR1cm4tdHlwZSAqLwoKLyoqIFN5bmNQcm9taXNlIGludGVybmFsIHN0YXRlcyAqLwp2YXIgU3RhdGVzOyAoZnVuY3Rpb24gKFN0YXRlcykgewogIC8qKiBQZW5kaW5nICovCiAgY29uc3QgUEVORElORyA9IDA7IFN0YXRlc1tTdGF0ZXNbIlBFTkRJTkciXSA9IFBFTkRJTkddID0gIlBFTkRJTkciOwogIC8qKiBSZXNvbHZlZCAvIE9LICovCiAgY29uc3QgUkVTT0xWRUQgPSAxOyBTdGF0ZXNbU3RhdGVzWyJSRVNPTFZFRCJdID0gUkVTT0xWRURdID0gIlJFU09MVkVEIjsKICAvKiogUmVqZWN0ZWQgLyBFcnJvciAqLwogIGNvbnN0IFJFSkVDVEVEID0gMjsgU3RhdGVzW1N0YXRlc1siUkVKRUNURUQiXSA9IFJFSkVDVEVEXSA9ICJSRUpFQ1RFRCI7Cn0pKFN0YXRlcyB8fCAoU3RhdGVzID0ge30pKTsKCi8vIE92ZXJsb2FkcyBzbyB3ZSBjYW4gY2FsbCByZXNvbHZlZFN5bmNQcm9taXNlIHdpdGhvdXQgYXJndW1lbnRzIGFuZCBnZW5lcmljIGFyZ3VtZW50CgovKioKICogQ3JlYXRlcyBhIHJlc29sdmVkIHN5bmMgcHJvbWlzZS4KICoKICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSB0byByZXNvbHZlIHRoZSBwcm9taXNlIHdpdGgKICogQHJldHVybnMgdGhlIHJlc29sdmVkIHN5bmMgcHJvbWlzZQogKi8KZnVuY3Rpb24gcmVzb2x2ZWRTeW5jUHJvbWlzZSh2YWx1ZSkgewogIHJldHVybiBuZXcgU3luY1Byb21pc2UocmVzb2x2ZSA9PiB7CiAgICByZXNvbHZlKHZhbHVlKTsKICB9KTsKfQoKLyoqCiAqIENyZWF0ZXMgYSByZWplY3RlZCBzeW5jIHByb21pc2UuCiAqCiAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgdG8gcmVqZWN0IHRoZSBwcm9taXNlIHdpdGgKICogQHJldHVybnMgdGhlIHJlamVjdGVkIHN5bmMgcHJvbWlzZQogKi8KZnVuY3Rpb24gcmVqZWN0ZWRTeW5jUHJvbWlzZShyZWFzb24pIHsKICByZXR1cm4gbmV3IFN5bmNQcm9taXNlKChfLCByZWplY3QpID0+IHsKICAgIHJlamVjdChyZWFzb24pOwogIH0pOwp9CgovKioKICogVGhlbmFibGUgY2xhc3MgdGhhdCBiZWhhdmVzIGxpa2UgYSBQcm9taXNlIGFuZCBmb2xsb3dzIGl0J3MgaW50ZXJmYWNlCiAqIGJ1dCBpcyBub3QgYXN5bmMgaW50ZXJuYWxseQogKi8KY2xhc3MgU3luY1Byb21pc2UgewoKICAgY29uc3RydWN0b3IoCiAgICBleGVjdXRvciwKICApIHtTeW5jUHJvbWlzZS5wcm90b3R5cGUuX19pbml0LmNhbGwodGhpcyk7U3luY1Byb21pc2UucHJvdG90eXBlLl9faW5pdDIuY2FsbCh0aGlzKTtTeW5jUHJvbWlzZS5wcm90b3R5cGUuX19pbml0My5jYWxsKHRoaXMpO1N5bmNQcm9taXNlLnByb3RvdHlwZS5fX2luaXQ0LmNhbGwodGhpcyk7CiAgICB0aGlzLl9zdGF0ZSA9IFN0YXRlcy5QRU5ESU5HOwogICAgdGhpcy5faGFuZGxlcnMgPSBbXTsKCiAgICB0cnkgewogICAgICBleGVjdXRvcih0aGlzLl9yZXNvbHZlLCB0aGlzLl9yZWplY3QpOwogICAgfSBjYXRjaCAoZSkgewogICAgICB0aGlzLl9yZWplY3QoZSk7CiAgICB9CiAgfQoKICAvKiogSlNEb2MgKi8KICAgdGhlbigKICAgIG9uZnVsZmlsbGVkLAogICAgb25yZWplY3RlZCwKICApIHsKICAgIHJldHVybiBuZXcgU3luY1Byb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4gewogICAgICB0aGlzLl9oYW5kbGVycy5wdXNoKFsKICAgICAgICBmYWxzZSwKICAgICAgICByZXN1bHQgPT4gewogICAgICAgICAgaWYgKCFvbmZ1bGZpbGxlZCkgewogICAgICAgICAgICAvLyBUT0RPOiDCr1xfKOODhClfL8KvCiAgICAgICAgICAgIC8vIFRPRE86IEZJWE1FCiAgICAgICAgICAgIHJlc29sdmUocmVzdWx0ICk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgIHJlc29sdmUob25mdWxmaWxsZWQocmVzdWx0KSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICByZWplY3QoZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHJlYXNvbiA9PiB7CiAgICAgICAgICBpZiAoIW9ucmVqZWN0ZWQpIHsKICAgICAgICAgICAgcmVqZWN0KHJlYXNvbik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgIHJlc29sdmUob25yZWplY3RlZChyZWFzb24pKTsKICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgIHJlamVjdChlKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgIF0pOwogICAgICB0aGlzLl9leGVjdXRlSGFuZGxlcnMoKTsKICAgIH0pOwogIH0KCiAgLyoqIEpTRG9jICovCiAgIGNhdGNoKAogICAgb25yZWplY3RlZCwKICApIHsKICAgIHJldHVybiB0aGlzLnRoZW4odmFsID0+IHZhbCwgb25yZWplY3RlZCk7CiAgfQoKICAvKiogSlNEb2MgKi8KICAgZmluYWxseShvbmZpbmFsbHkpIHsKICAgIHJldHVybiBuZXcgU3luY1Byb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4gewogICAgICBsZXQgdmFsOwogICAgICBsZXQgaXNSZWplY3RlZDsKCiAgICAgIHJldHVybiB0aGlzLnRoZW4oCiAgICAgICAgdmFsdWUgPT4gewogICAgICAgICAgaXNSZWplY3RlZCA9IGZhbHNlOwogICAgICAgICAgdmFsID0gdmFsdWU7CiAgICAgICAgICBpZiAob25maW5hbGx5KSB7CiAgICAgICAgICAgIG9uZmluYWxseSgpOwogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcmVhc29uID0+IHsKICAgICAgICAgIGlzUmVqZWN0ZWQgPSB0cnVlOwogICAgICAgICAgdmFsID0gcmVhc29uOwogICAgICAgICAgaWYgKG9uZmluYWxseSkgewogICAgICAgICAgICBvbmZpbmFsbHkoKTsKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICApLnRoZW4oKCkgPT4gewogICAgICAgIGlmIChpc1JlamVjdGVkKSB7CiAgICAgICAgICByZWplY3QodmFsKTsKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHJlc29sdmUodmFsICk7CiAgICAgIH0pOwogICAgfSk7CiAgfQoKICAvKiogSlNEb2MgKi8KICAgIF9faW5pdCgpIHt0aGlzLl9yZXNvbHZlID0gKHZhbHVlKSA9PiB7CiAgICB0aGlzLl9zZXRSZXN1bHQoU3RhdGVzLlJFU09MVkVELCB2YWx1ZSk7CiAgfTt9CgogIC8qKiBKU0RvYyAqLwogICAgX19pbml0MigpIHt0aGlzLl9yZWplY3QgPSAocmVhc29uKSA9PiB7CiAgICB0aGlzLl9zZXRSZXN1bHQoU3RhdGVzLlJFSkVDVEVELCByZWFzb24pOwogIH07fQoKICAvKiogSlNEb2MgKi8KICAgIF9faW5pdDMoKSB7dGhpcy5fc2V0UmVzdWx0ID0gKHN0YXRlLCB2YWx1ZSkgPT4gewogICAgaWYgKHRoaXMuX3N0YXRlICE9PSBTdGF0ZXMuUEVORElORykgewogICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKGlzVGhlbmFibGUodmFsdWUpKSB7CiAgICAgIHZvaWQgKHZhbHVlICkudGhlbih0aGlzLl9yZXNvbHZlLCB0aGlzLl9yZWplY3QpOwogICAgICByZXR1cm47CiAgICB9CgogICAgdGhpcy5fc3RhdGUgPSBzdGF0ZTsKICAgIHRoaXMuX3ZhbHVlID0gdmFsdWU7CgogICAgdGhpcy5fZXhlY3V0ZUhhbmRsZXJzKCk7CiAgfTt9CgogIC8qKiBKU0RvYyAqLwogICAgX19pbml0NCgpIHt0aGlzLl9leGVjdXRlSGFuZGxlcnMgPSAoKSA9PiB7CiAgICBpZiAodGhpcy5fc3RhdGUgPT09IFN0YXRlcy5QRU5ESU5HKSB7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICBjb25zdCBjYWNoZWRIYW5kbGVycyA9IHRoaXMuX2hhbmRsZXJzLnNsaWNlKCk7CiAgICB0aGlzLl9oYW5kbGVycyA9IFtdOwoKICAgIGNhY2hlZEhhbmRsZXJzLmZvckVhY2goaGFuZGxlciA9PiB7CiAgICAgIGlmIChoYW5kbGVyWzBdKSB7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFN0YXRlcy5SRVNPTFZFRCkgewogICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZmxvYXRpbmctcHJvbWlzZXMKICAgICAgICBoYW5kbGVyWzFdKHRoaXMuX3ZhbHVlICk7CiAgICAgIH0KCiAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gU3RhdGVzLlJFSkVDVEVEKSB7CiAgICAgICAgaGFuZGxlclsyXSh0aGlzLl92YWx1ZSk7CiAgICAgIH0KCiAgICAgIGhhbmRsZXJbMF0gPSB0cnVlOwogICAgfSk7CiAgfTt9Cn0KCi8qKgogKiBDcmVhdGVzIGFuIG5ldyBQcm9taXNlQnVmZmVyIG9iamVjdCB3aXRoIHRoZSBzcGVjaWZpZWQgbGltaXQKICogQHBhcmFtIGxpbWl0IG1heCBudW1iZXIgb2YgcHJvbWlzZXMgdGhhdCBjYW4gYmUgc3RvcmVkIGluIHRoZSBidWZmZXIKICovCmZ1bmN0aW9uIG1ha2VQcm9taXNlQnVmZmVyKGxpbWl0KSB7CiAgY29uc3QgYnVmZmVyID0gW107CgogIGZ1bmN0aW9uIGlzUmVhZHkoKSB7CiAgICByZXR1cm4gbGltaXQgPT09IHVuZGVmaW5lZCB8fCBidWZmZXIubGVuZ3RoIDwgbGltaXQ7CiAgfQoKICAvKioKICAgKiBSZW1vdmUgYSBwcm9taXNlIGZyb20gdGhlIHF1ZXVlLgogICAqCiAgICogQHBhcmFtIHRhc2sgQ2FuIGJlIGFueSBQcm9taXNlTGlrZTxUPgogICAqIEByZXR1cm5zIFJlbW92ZWQgcHJvbWlzZS4KICAgKi8KICBmdW5jdGlvbiByZW1vdmUodGFzaykgewogICAgcmV0dXJuIGJ1ZmZlci5zcGxpY2UoYnVmZmVyLmluZGV4T2YodGFzayksIDEpWzBdOwogIH0KCiAgLyoqCiAgICogQWRkIGEgcHJvbWlzZSAocmVwcmVzZW50aW5nIGFuIGluLWZsaWdodCBhY3Rpb24pIHRvIHRoZSBxdWV1ZSwgYW5kIHNldCBpdCB0byByZW1vdmUgaXRzZWxmIG9uIGZ1bGZpbGxtZW50LgogICAqCiAgICogQHBhcmFtIHRhc2tQcm9kdWNlciBBIGZ1bmN0aW9uIHByb2R1Y2luZyBhbnkgUHJvbWlzZUxpa2U8VD47IEluIHByZXZpb3VzIHZlcnNpb25zIHRoaXMgdXNlZCB0byBiZSBgdGFzazoKICAgKiAgICAgICAgUHJvbWlzZUxpa2U8VD5gLCBidXQgdW5kZXIgdGhhdCBtb2RlbCwgUHJvbWlzZXMgd2VyZSBpbnN0YW50bHkgY3JlYXRlZCBvbiB0aGUgY2FsbC1zaXRlIGFuZCB0aGVpciBleGVjdXRvcgogICAqICAgICAgICBmdW5jdGlvbnMgdGhlcmVmb3JlIHJhbiBpbW1lZGlhdGVseS4gVGh1cywgZXZlbiBpZiB0aGUgYnVmZmVyIHdhcyBmdWxsLCB0aGUgYWN0aW9uIHN0aWxsIGhhcHBlbmVkLiBCeQogICAqICAgICAgICByZXF1aXJpbmcgdGhlIHByb21pc2UgdG8gYmUgd3JhcHBlZCBpbiBhIGZ1bmN0aW9uLCB3ZSBjYW4gZGVmZXIgcHJvbWlzZSBjcmVhdGlvbiB1bnRpbCBhZnRlciB0aGUgYnVmZmVyCiAgICogICAgICAgIGxpbWl0IGNoZWNrLgogICAqIEByZXR1cm5zIFRoZSBvcmlnaW5hbCBwcm9taXNlLgogICAqLwogIGZ1bmN0aW9uIGFkZCh0YXNrUHJvZHVjZXIpIHsKICAgIGlmICghaXNSZWFkeSgpKSB7CiAgICAgIHJldHVybiByZWplY3RlZFN5bmNQcm9taXNlKG5ldyBTZW50cnlFcnJvcignTm90IGFkZGluZyBQcm9taXNlIGJlY2F1c2UgYnVmZmVyIGxpbWl0IHdhcyByZWFjaGVkLicpKTsKICAgIH0KCiAgICAvLyBzdGFydCB0aGUgdGFzayBhbmQgYWRkIGl0cyBwcm9taXNlIHRvIHRoZSBxdWV1ZQogICAgY29uc3QgdGFzayA9IHRhc2tQcm9kdWNlcigpOwogICAgaWYgKGJ1ZmZlci5pbmRleE9mKHRhc2spID09PSAtMSkgewogICAgICBidWZmZXIucHVzaCh0YXNrKTsKICAgIH0KICAgIHZvaWQgdGFzawogICAgICAudGhlbigoKSA9PiByZW1vdmUodGFzaykpCiAgICAgIC8vIFVzZSBgdGhlbihudWxsLCByZWplY3Rpb25IYW5kbGVyKWAgcmF0aGVyIHRoYW4gYGNhdGNoKHJlamVjdGlvbkhhbmRsZXIpYCBzbyB0aGF0IHdlIGNhbiB1c2UgYFByb21pc2VMaWtlYAogICAgICAvLyByYXRoZXIgdGhhbiBgUHJvbWlzZWAuIGBQcm9taXNlTGlrZWAgZG9lc24ndCBoYXZlIGEgYC5jYXRjaGAgbWV0aG9kLCBtYWtpbmcgaXRzIHBvbHlmaWxsIHNtYWxsZXIuIChFUzUgZGlkbid0CiAgICAgIC8vIGhhdmUgcHJvbWlzZXMsIHNvIFRTIGhhcyB0byBwb2x5ZmlsbCB3aGVuIGRvd24tY29tcGlsaW5nLikKICAgICAgLnRoZW4obnVsbCwgKCkgPT4KICAgICAgICByZW1vdmUodGFzaykudGhlbihudWxsLCAoKSA9PiB7CiAgICAgICAgICAvLyBXZSBoYXZlIHRvIGFkZCBhbm90aGVyIGNhdGNoIGhlcmUgYmVjYXVzZSBgcmVtb3ZlKClgIHN0YXJ0cyBhIG5ldyBwcm9taXNlIGNoYWluLgogICAgICAgIH0pLAogICAgICApOwogICAgcmV0dXJuIHRhc2s7CiAgfQoKICAvKioKICAgKiBXYWl0IGZvciBhbGwgcHJvbWlzZXMgaW4gdGhlIHF1ZXVlIHRvIHJlc29sdmUgb3IgZm9yIHRpbWVvdXQgdG8gZXhwaXJlLCB3aGljaGV2ZXIgY29tZXMgZmlyc3QuCiAgICoKICAgKiBAcGFyYW0gdGltZW91dCBUaGUgdGltZSwgaW4gbXMsIGFmdGVyIHdoaWNoIHRvIHJlc29sdmUgdG8gYGZhbHNlYCBpZiB0aGUgcXVldWUgaXMgc3RpbGwgbm9uLWVtcHR5LiBQYXNzaW5nIGAwYCAob3IKICAgKiBub3QgcGFzc2luZyBhbnl0aGluZykgd2lsbCBtYWtlIHRoZSBwcm9taXNlIHdhaXQgYXMgbG9uZyBhcyBpdCB0YWtlcyBmb3IgdGhlIHF1ZXVlIHRvIGRyYWluIGJlZm9yZSByZXNvbHZpbmcgdG8KICAgKiBgdHJ1ZWAuCiAgICogQHJldHVybnMgQSBwcm9taXNlIHdoaWNoIHdpbGwgcmVzb2x2ZSB0byBgdHJ1ZWAgaWYgdGhlIHF1ZXVlIGlzIGFscmVhZHkgZW1wdHkgb3IgZHJhaW5zIGJlZm9yZSB0aGUgdGltZW91dCwgYW5kCiAgICogYGZhbHNlYCBvdGhlcndpc2UKICAgKi8KICBmdW5jdGlvbiBkcmFpbih0aW1lb3V0KSB7CiAgICByZXR1cm4gbmV3IFN5bmNQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHsKICAgICAgbGV0IGNvdW50ZXIgPSBidWZmZXIubGVuZ3RoOwoKICAgICAgaWYgKCFjb3VudGVyKSB7CiAgICAgICAgcmV0dXJuIHJlc29sdmUodHJ1ZSk7CiAgICAgIH0KCiAgICAgIC8vIHdhaXQgZm9yIGB0aW1lb3V0YCBtcyBhbmQgdGhlbiByZXNvbHZlIHRvIGBmYWxzZWAgKGlmIG5vdCBjYW5jZWxsZWQgZmlyc3QpCiAgICAgIGNvbnN0IGNhcHR1cmVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4gewogICAgICAgIGlmICh0aW1lb3V0ICYmIHRpbWVvdXQgPiAwKSB7CiAgICAgICAgICByZXNvbHZlKGZhbHNlKTsKICAgICAgICB9CiAgICAgIH0sIHRpbWVvdXQpOwoKICAgICAgLy8gaWYgYWxsIHByb21pc2VzIHJlc29sdmUgaW4gdGltZSwgY2FuY2VsIHRoZSB0aW1lciBhbmQgcmVzb2x2ZSB0byBgdHJ1ZWAKICAgICAgYnVmZmVyLmZvckVhY2goaXRlbSA9PiB7CiAgICAgICAgdm9pZCByZXNvbHZlZFN5bmNQcm9taXNlKGl0ZW0pLnRoZW4oKCkgPT4gewogICAgICAgICAgaWYgKCEtLWNvdW50ZXIpIHsKICAgICAgICAgICAgY2xlYXJUaW1lb3V0KGNhcHR1cmVkU2V0VGltZW91dCk7CiAgICAgICAgICAgIHJlc29sdmUodHJ1ZSk7CiAgICAgICAgICB9CiAgICAgICAgfSwgcmVqZWN0KTsKICAgICAgfSk7CiAgICB9KTsKICB9CgogIHJldHVybiB7CiAgICAkOiBidWZmZXIsCiAgICBhZGQsCiAgICBkcmFpbiwKICB9Owp9Cgpjb25zdCBPTkVfU0VDT05EX0lOX01TID0gMTAwMDsKCi8qKgogKiBBIHBhcnRpYWwgZGVmaW5pdGlvbiBvZiB0aGUgW1BlcmZvcm1hbmNlIFdlYiBBUElde0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9QZXJmb3JtYW5jZX0KICogZm9yIGFjY2Vzc2luZyBhIGhpZ2gtcmVzb2x1dGlvbiBtb25vdG9uaWMgY2xvY2suCiAqLwoKLyoqCiAqIFJldHVybnMgYSB0aW1lc3RhbXAgaW4gc2Vjb25kcyBzaW5jZSB0aGUgVU5JWCBlcG9jaCB1c2luZyB0aGUgRGF0ZSBBUEkuCiAqCiAqIFRPRE8odjgpOiBSZXR1cm4gdHlwZSBzaG91bGQgYmUgcm91bmRlZC4KICovCmZ1bmN0aW9uIGRhdGVUaW1lc3RhbXBJblNlY29uZHMoKSB7CiAgcmV0dXJuIERhdGUubm93KCkgLyBPTkVfU0VDT05EX0lOX01TOwp9CgovKioKICogUmV0dXJucyBhIHdyYXBwZXIgYXJvdW5kIHRoZSBuYXRpdmUgUGVyZm9ybWFuY2UgQVBJIGJyb3dzZXIgaW1wbGVtZW50YXRpb24sIG9yIHVuZGVmaW5lZCBmb3IgYnJvd3NlcnMgdGhhdCBkbyBub3QKICogc3VwcG9ydCB0aGUgQVBJLgogKgogKiBXcmFwcGluZyB0aGUgbmF0aXZlIEFQSSB3b3JrcyBhcm91bmQgZGlmZmVyZW5jZXMgaW4gYmVoYXZpb3IgZnJvbSBkaWZmZXJlbnQgYnJvd3NlcnMuCiAqLwpmdW5jdGlvbiBjcmVhdGVVbml4VGltZXN0YW1wSW5TZWNvbmRzRnVuYygpIHsKICBjb25zdCB7IHBlcmZvcm1hbmNlIH0gPSBHTE9CQUxfT0JKIDsKICBpZiAoIXBlcmZvcm1hbmNlIHx8ICFwZXJmb3JtYW5jZS5ub3cpIHsKICAgIHJldHVybiBkYXRlVGltZXN0YW1wSW5TZWNvbmRzOwogIH0KCiAgLy8gU29tZSBicm93c2VyIGFuZCBlbnZpcm9ubWVudHMgZG9uJ3QgaGF2ZSBhIHRpbWVPcmlnaW4sIHNvIHdlIGZhbGxiYWNrIHRvCiAgLy8gdXNpbmcgRGF0ZS5ub3coKSB0byBjb21wdXRlIHRoZSBzdGFydGluZyB0aW1lLgogIGNvbnN0IGFwcHJveFN0YXJ0aW5nVGltZU9yaWdpbiA9IERhdGUubm93KCkgLSBwZXJmb3JtYW5jZS5ub3coKTsKICBjb25zdCB0aW1lT3JpZ2luID0gcGVyZm9ybWFuY2UudGltZU9yaWdpbiA9PSB1bmRlZmluZWQgPyBhcHByb3hTdGFydGluZ1RpbWVPcmlnaW4gOiBwZXJmb3JtYW5jZS50aW1lT3JpZ2luOwoKICAvLyBwZXJmb3JtYW5jZS5ub3coKSBpcyBhIG1vbm90b25pYyBjbG9jaywgd2hpY2ggbWVhbnMgaXQgc3RhcnRzIGF0IDAgd2hlbiB0aGUgcHJvY2VzcyBiZWdpbnMuIFRvIGdldCB0aGUgY3VycmVudAogIC8vIHdhbGwgY2xvY2sgdGltZSAoYWN0dWFsIFVOSVggdGltZXN0YW1wKSwgd2UgbmVlZCB0byBhZGQgdGhlIHN0YXJ0aW5nIHRpbWUgb3JpZ2luIGFuZCB0aGUgY3VycmVudCB0aW1lIGVsYXBzZWQuCiAgLy8KICAvLyBUT0RPOiBUaGlzIGRvZXMgbm90IGFjY291bnQgZm9yIHRoZSBjYXNlIHdoZXJlIHRoZSBtb25vdG9uaWMgY2xvY2sgdGhhdCBwb3dlcnMgcGVyZm9ybWFuY2Uubm93KCkgZHJpZnRzIGZyb20gdGhlCiAgLy8gd2FsbCBjbG9jayB0aW1lLCB3aGljaCBjYXVzZXMgdGhlIHJldHVybmVkIHRpbWVzdGFtcCB0byBiZSBpbmFjY3VyYXRlLiBXZSBzaG91bGQgaW52ZXN0aWdhdGUgaG93IHRvIGRldGVjdCBhbmQKICAvLyBjb3JyZWN0IGZvciB0aGlzLgogIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdC9pc3N1ZXMvMjU5MAogIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL21kbi9jb250ZW50L2lzc3Vlcy80NzEzCiAgLy8gU2VlOiBodHRwczovL2Rldi50by9ub2Ftci93aGVuLWEtbWlsbGlzZWNvbmQtaXMtbm90LWEtbWlsbGlzZWNvbmQtM2g2CiAgcmV0dXJuICgpID0+IHsKICAgIHJldHVybiAodGltZU9yaWdpbiArIHBlcmZvcm1hbmNlLm5vdygpKSAvIE9ORV9TRUNPTkRfSU5fTVM7CiAgfTsKfQoKLyoqCiAqIFJldHVybnMgYSB0aW1lc3RhbXAgaW4gc2Vjb25kcyBzaW5jZSB0aGUgVU5JWCBlcG9jaCB1c2luZyBlaXRoZXIgdGhlIFBlcmZvcm1hbmNlIG9yIERhdGUgQVBJcywgZGVwZW5kaW5nIG9uIHRoZQogKiBhdmFpbGFiaWxpdHkgb2YgdGhlIFBlcmZvcm1hbmNlIEFQSS4KICoKICogQlVHOiBOb3RlIHRoYXQgYmVjYXVzZSBvZiBob3cgYnJvd3NlcnMgaW1wbGVtZW50IHRoZSBQZXJmb3JtYW5jZSBBUEksIHRoZSBjbG9jayBtaWdodCBzdG9wIHdoZW4gdGhlIGNvbXB1dGVyIGlzCiAqIGFzbGVlcC4gVGhpcyBjcmVhdGVzIGEgc2tldyBiZXR3ZWVuIGBkYXRlVGltZXN0YW1wSW5TZWNvbmRzYCBhbmQgYHRpbWVzdGFtcEluU2Vjb25kc2AuIFRoZQogKiBza2V3IGNhbiBncm93IHRvIGFyYml0cmFyeSBhbW91bnRzIGxpa2UgZGF5cywgd2Vla3Mgb3IgbW9udGhzLgogKiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdC9pc3N1ZXMvMjU5MC4KICovCmNvbnN0IHRpbWVzdGFtcEluU2Vjb25kcyA9IGNyZWF0ZVVuaXhUaW1lc3RhbXBJblNlY29uZHNGdW5jKCk7CgovKioKICogVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgc2luY2UgdGhlIFVOSVggZXBvY2guIFRoaXMgdmFsdWUgaXMgb25seSB1c2FibGUgaW4gYSBicm93c2VyLCBhbmQgb25seSB3aGVuIHRoZQogKiBwZXJmb3JtYW5jZSBBUEkgaXMgYXZhaWxhYmxlLgogKi8KKCgpID0+IHsKICAvLyBVbmZvcnR1bmF0ZWx5IGJyb3dzZXJzIG1heSByZXBvcnQgYW4gaW5hY2N1cmF0ZSB0aW1lIG9yaWdpbiBkYXRhLCB0aHJvdWdoIGVpdGhlciBwZXJmb3JtYW5jZS50aW1lT3JpZ2luIG9yCiAgLy8gcGVyZm9ybWFuY2UudGltaW5nLm5hdmlnYXRpb25TdGFydCwgd2hpY2ggcmVzdWx0cyBpbiBwb29yIHJlc3VsdHMgaW4gcGVyZm9ybWFuY2UgZGF0YS4gV2Ugb25seSB0cmVhdCB0aW1lIG9yaWdpbgogIC8vIGRhdGEgYXMgcmVsaWFibGUgaWYgdGhleSBhcmUgd2l0aGluIGEgcmVhc29uYWJsZSB0aHJlc2hvbGQgb2YgdGhlIGN1cnJlbnQgdGltZS4KCiAgY29uc3QgeyBwZXJmb3JtYW5jZSB9ID0gR0xPQkFMX09CSiA7CiAgaWYgKCFwZXJmb3JtYW5jZSB8fCAhcGVyZm9ybWFuY2Uubm93KSB7CiAgICByZXR1cm4gdW5kZWZpbmVkOwogIH0KCiAgY29uc3QgdGhyZXNob2xkID0gMzYwMCAqIDEwMDA7CiAgY29uc3QgcGVyZm9ybWFuY2VOb3cgPSBwZXJmb3JtYW5jZS5ub3coKTsKICBjb25zdCBkYXRlTm93ID0gRGF0ZS5ub3coKTsKCiAgLy8gaWYgdGltZU9yaWdpbiBpc24ndCBhdmFpbGFibGUgc2V0IGRlbHRhIHRvIHRocmVzaG9sZCBzbyBpdCBpc24ndCB1c2VkCiAgY29uc3QgdGltZU9yaWdpbkRlbHRhID0gcGVyZm9ybWFuY2UudGltZU9yaWdpbgogICAgPyBNYXRoLmFicyhwZXJmb3JtYW5jZS50aW1lT3JpZ2luICsgcGVyZm9ybWFuY2VOb3cgLSBkYXRlTm93KQogICAgOiB0aHJlc2hvbGQ7CiAgY29uc3QgdGltZU9yaWdpbklzUmVsaWFibGUgPSB0aW1lT3JpZ2luRGVsdGEgPCB0aHJlc2hvbGQ7CgogIC8vIFdoaWxlIHBlcmZvcm1hbmNlLnRpbWluZy5uYXZpZ2F0aW9uU3RhcnQgaXMgZGVwcmVjYXRlZCBpbiBmYXZvciBvZiBwZXJmb3JtYW5jZS50aW1lT3JpZ2luLCBwZXJmb3JtYW5jZS50aW1lT3JpZ2luCiAgLy8gaXMgbm90IGFzIHdpZGVseSBzdXBwb3J0ZWQuIE5hbWVseSwgcGVyZm9ybWFuY2UudGltZU9yaWdpbiBpcyB1bmRlZmluZWQgaW4gU2FmYXJpIGFzIG9mIHdyaXRpbmcuCiAgLy8gQWxzbyBhcyBvZiB3cml0aW5nLCBwZXJmb3JtYW5jZS50aW1pbmcgaXMgbm90IGF2YWlsYWJsZSBpbiBXZWIgV29ya2VycyBpbiBtYWluc3RyZWFtIGJyb3dzZXJzLCBzbyBpdCBpcyBub3QgYWx3YXlzCiAgLy8gYSB2YWxpZCBmYWxsYmFjay4gSW4gdGhlIGFic2VuY2Ugb2YgYW4gaW5pdGlhbCB0aW1lIHByb3ZpZGVkIGJ5IHRoZSBicm93c2VyLCBmYWxsYmFjayB0byB0aGUgY3VycmVudCB0aW1lIGZyb20gdGhlCiAgLy8gRGF0ZSBBUEkuCiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCiAgY29uc3QgbmF2aWdhdGlvblN0YXJ0ID0gcGVyZm9ybWFuY2UudGltaW5nICYmIHBlcmZvcm1hbmNlLnRpbWluZy5uYXZpZ2F0aW9uU3RhcnQ7CiAgY29uc3QgaGFzTmF2aWdhdGlvblN0YXJ0ID0gdHlwZW9mIG5hdmlnYXRpb25TdGFydCA9PT0gJ251bWJlcic7CiAgLy8gaWYgbmF2aWdhdGlvblN0YXJ0IGlzbid0IGF2YWlsYWJsZSBzZXQgZGVsdGEgdG8gdGhyZXNob2xkIHNvIGl0IGlzbid0IHVzZWQKICBjb25zdCBuYXZpZ2F0aW9uU3RhcnREZWx0YSA9IGhhc05hdmlnYXRpb25TdGFydCA/IE1hdGguYWJzKG5hdmlnYXRpb25TdGFydCArIHBlcmZvcm1hbmNlTm93IC0gZGF0ZU5vdykgOiB0aHJlc2hvbGQ7CiAgY29uc3QgbmF2aWdhdGlvblN0YXJ0SXNSZWxpYWJsZSA9IG5hdmlnYXRpb25TdGFydERlbHRhIDwgdGhyZXNob2xkOwoKICBpZiAodGltZU9yaWdpbklzUmVsaWFibGUgfHwgbmF2aWdhdGlvblN0YXJ0SXNSZWxpYWJsZSkgewogICAgLy8gVXNlIHRoZSBtb3JlIHJlbGlhYmxlIHRpbWUgb3JpZ2luCiAgICBpZiAodGltZU9yaWdpbkRlbHRhIDw9IG5hdmlnYXRpb25TdGFydERlbHRhKSB7CiAgICAgIHJldHVybiBwZXJmb3JtYW5jZS50aW1lT3JpZ2luOwogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIG5hdmlnYXRpb25TdGFydDsKICAgIH0KICB9CiAgcmV0dXJuIGRhdGVOb3c7Cn0pKCk7CgovKioKICogQ3JlYXRlcyBhbiBlbnZlbG9wZS4KICogTWFrZSBzdXJlIHRvIGFsd2F5cyBleHBsaWNpdGx5IHByb3ZpZGUgdGhlIGdlbmVyaWMgdG8gdGhpcyBmdW5jdGlvbgogKiBzbyB0aGF0IHRoZSBlbnZlbG9wZSB0eXBlcyByZXNvbHZlIGNvcnJlY3RseS4KICovCmZ1bmN0aW9uIGNyZWF0ZUVudmVsb3BlKGhlYWRlcnMsIGl0ZW1zID0gW10pIHsKICByZXR1cm4gW2hlYWRlcnMsIGl0ZW1zXSA7Cn0KCi8qKgogKiBDb252ZW5pZW5jZSBmdW5jdGlvbiB0byBsb29wIHRocm91Z2ggdGhlIGl0ZW1zIGFuZCBpdGVtIHR5cGVzIG9mIGFuIGVudmVsb3BlLgogKiAoVGhpcyBmdW5jdGlvbiB3YXMgbW9zdGx5IGNyZWF0ZWQgYmVjYXVzZSB3b3JraW5nIHdpdGggZW52ZWxvcGUgdHlwZXMgaXMgcGFpbmZ1bCBhdCB0aGUgbW9tZW50KQogKgogKiBJZiB0aGUgY2FsbGJhY2sgcmV0dXJucyB0cnVlLCB0aGUgcmVzdCBvZiB0aGUgaXRlbXMgd2lsbCBiZSBza2lwcGVkLgogKi8KZnVuY3Rpb24gZm9yRWFjaEVudmVsb3BlSXRlbSgKICBlbnZlbG9wZSwKICBjYWxsYmFjaywKKSB7CiAgY29uc3QgZW52ZWxvcGVJdGVtcyA9IGVudmVsb3BlWzFdOwoKICBmb3IgKGNvbnN0IGVudmVsb3BlSXRlbSBvZiBlbnZlbG9wZUl0ZW1zKSB7CiAgICBjb25zdCBlbnZlbG9wZUl0ZW1UeXBlID0gZW52ZWxvcGVJdGVtWzBdLnR5cGU7CiAgICBjb25zdCByZXN1bHQgPSBjYWxsYmFjayhlbnZlbG9wZUl0ZW0sIGVudmVsb3BlSXRlbVR5cGUpOwoKICAgIGlmIChyZXN1bHQpIHsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgfQoKICByZXR1cm4gZmFsc2U7Cn0KCi8qKgogKiBFbmNvZGUgYSBzdHJpbmcgdG8gVVRGOC4KICovCmZ1bmN0aW9uIGVuY29kZVVURjgoaW5wdXQsIHRleHRFbmNvZGVyKSB7CiAgY29uc3QgdXRmOCA9IHRleHRFbmNvZGVyIHx8IG5ldyBUZXh0RW5jb2RlcigpOwogIHJldHVybiB1dGY4LmVuY29kZShpbnB1dCk7Cn0KCi8qKgogKiBTZXJpYWxpemVzIGFuIGVudmVsb3BlLgogKi8KZnVuY3Rpb24gc2VyaWFsaXplRW52ZWxvcGUoZW52ZWxvcGUsIHRleHRFbmNvZGVyKSB7CiAgY29uc3QgW2VudkhlYWRlcnMsIGl0ZW1zXSA9IGVudmVsb3BlOwoKICAvLyBJbml0aWFsbHkgd2UgY29uc3RydWN0IG91ciBlbnZlbG9wZSBhcyBhIHN0cmluZyBhbmQgb25seSBjb252ZXJ0IHRvIGJpbmFyeSBjaHVua3MgaWYgd2UgZW5jb3VudGVyIGJpbmFyeSBkYXRhCiAgbGV0IHBhcnRzID0gSlNPTi5zdHJpbmdpZnkoZW52SGVhZGVycyk7CgogIGZ1bmN0aW9uIGFwcGVuZChuZXh0KSB7CiAgICBpZiAodHlwZW9mIHBhcnRzID09PSAnc3RyaW5nJykgewogICAgICBwYXJ0cyA9IHR5cGVvZiBuZXh0ID09PSAnc3RyaW5nJyA/IHBhcnRzICsgbmV4dCA6IFtlbmNvZGVVVEY4KHBhcnRzLCB0ZXh0RW5jb2RlciksIG5leHRdOwogICAgfSBlbHNlIHsKICAgICAgcGFydHMucHVzaCh0eXBlb2YgbmV4dCA9PT0gJ3N0cmluZycgPyBlbmNvZGVVVEY4KG5leHQsIHRleHRFbmNvZGVyKSA6IG5leHQpOwogICAgfQogIH0KCiAgZm9yIChjb25zdCBpdGVtIG9mIGl0ZW1zKSB7CiAgICBjb25zdCBbaXRlbUhlYWRlcnMsIHBheWxvYWRdID0gaXRlbTsKCiAgICBhcHBlbmQoYFxuJHtKU09OLnN0cmluZ2lmeShpdGVtSGVhZGVycyl9XG5gKTsKCiAgICBpZiAodHlwZW9mIHBheWxvYWQgPT09ICdzdHJpbmcnIHx8IHBheWxvYWQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7CiAgICAgIGFwcGVuZChwYXlsb2FkKTsKICAgIH0gZWxzZSB7CiAgICAgIGxldCBzdHJpbmdpZmllZFBheWxvYWQ7CiAgICAgIHRyeSB7CiAgICAgICAgc3RyaW5naWZpZWRQYXlsb2FkID0gSlNPTi5zdHJpbmdpZnkocGF5bG9hZCk7CiAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAvLyBJbiBjYXNlLCBkZXNwaXRlIGFsbCBvdXIgZWZmb3J0cyB0byBrZWVwIGBwYXlsb2FkYCBjaXJjdWxhci1kZXBlbmRlbmN5LWZyZWUsIGBKU09OLnN0cmluaWZ5KClgIHN0aWxsCiAgICAgICAgLy8gZmFpbHMsIHdlIHRyeSBhZ2FpbiBhZnRlciBub3JtYWxpemluZyBpdCBhZ2FpbiB3aXRoIGluZmluaXRlIG5vcm1hbGl6YXRpb24gZGVwdGguIFRoaXMgb2YgY291cnNlIGhhcyBhCiAgICAgICAgLy8gcGVyZm9ybWFuY2UgaW1wYWN0IGJ1dCBpbiB0aGlzIGNhc2UgYSBwZXJmb3JtYW5jZSBoaXQgaXMgYmV0dGVyIHRoYW4gdGhyb3dpbmcuCiAgICAgICAgc3RyaW5naWZpZWRQYXlsb2FkID0gSlNPTi5zdHJpbmdpZnkobm9ybWFsaXplKHBheWxvYWQpKTsKICAgICAgfQogICAgICBhcHBlbmQoc3RyaW5naWZpZWRQYXlsb2FkKTsKICAgIH0KICB9CgogIHJldHVybiB0eXBlb2YgcGFydHMgPT09ICdzdHJpbmcnID8gcGFydHMgOiBjb25jYXRCdWZmZXJzKHBhcnRzKTsKfQoKZnVuY3Rpb24gY29uY2F0QnVmZmVycyhidWZmZXJzKSB7CiAgY29uc3QgdG90YWxMZW5ndGggPSBidWZmZXJzLnJlZHVjZSgoYWNjLCBidWYpID0+IGFjYyArIGJ1Zi5sZW5ndGgsIDApOwoKICBjb25zdCBtZXJnZWQgPSBuZXcgVWludDhBcnJheSh0b3RhbExlbmd0aCk7CiAgbGV0IG9mZnNldCA9IDA7CiAgZm9yIChjb25zdCBidWZmZXIgb2YgYnVmZmVycykgewogICAgbWVyZ2VkLnNldChidWZmZXIsIG9mZnNldCk7CiAgICBvZmZzZXQgKz0gYnVmZmVyLmxlbmd0aDsKICB9CgogIHJldHVybiBtZXJnZWQ7Cn0KCmNvbnN0IElURU1fVFlQRV9UT19EQVRBX0NBVEVHT1JZX01BUCA9IHsKICBzZXNzaW9uOiAnc2Vzc2lvbicsCiAgc2Vzc2lvbnM6ICdzZXNzaW9uJywKICBhdHRhY2htZW50OiAnYXR0YWNobWVudCcsCiAgdHJhbnNhY3Rpb246ICd0cmFuc2FjdGlvbicsCiAgZXZlbnQ6ICdlcnJvcicsCiAgY2xpZW50X3JlcG9ydDogJ2ludGVybmFsJywKICB1c2VyX3JlcG9ydDogJ2RlZmF1bHQnLAogIHByb2ZpbGU6ICdwcm9maWxlJywKICByZXBsYXlfZXZlbnQ6ICdyZXBsYXknLAogIHJlcGxheV9yZWNvcmRpbmc6ICdyZXBsYXknLAogIGNoZWNrX2luOiAnbW9uaXRvcicsCiAgZmVlZGJhY2s6ICdmZWVkYmFjaycsCiAgc3BhbjogJ3NwYW4nLAogIC8vIFRPRE86IFRoaXMgaXMgYSB0ZW1wb3Jhcnkgd29ya2Fyb3VuZCB1bnRpbCB3ZSBoYXZlIGEgcHJvcGVyIGRhdGEgY2F0ZWdvcnkgZm9yIG1ldHJpY3MKICBzdGF0c2Q6ICd1bmtub3duJywKfTsKCi8qKgogKiBNYXBzIHRoZSB0eXBlIG9mIGFuIGVudmVsb3BlIGl0ZW0gdG8gYSBkYXRhIGNhdGVnb3J5LgogKi8KZnVuY3Rpb24gZW52ZWxvcGVJdGVtVHlwZVRvRGF0YUNhdGVnb3J5KHR5cGUpIHsKICByZXR1cm4gSVRFTV9UWVBFX1RPX0RBVEFfQ0FURUdPUllfTUFQW3R5cGVdOwp9CgovKiogRXh0cmFjdHMgdGhlIG1pbmltYWwgU0RLIGluZm8gZnJvbSBmcm9tIHRoZSBtZXRhZGF0YSBvciBhbiBldmVudHMgKi8KZnVuY3Rpb24gZ2V0U2RrTWV0YWRhdGFGb3JFbnZlbG9wZUhlYWRlcihtZXRhZGF0YU9yRXZlbnQpIHsKICBpZiAoIW1ldGFkYXRhT3JFdmVudCB8fCAhbWV0YWRhdGFPckV2ZW50LnNkaykgewogICAgcmV0dXJuOwogIH0KICBjb25zdCB7IG5hbWUsIHZlcnNpb24gfSA9IG1ldGFkYXRhT3JFdmVudC5zZGs7CiAgcmV0dXJuIHsgbmFtZSwgdmVyc2lvbiB9Owp9CgovKioKICogQ3JlYXRlcyBldmVudCBlbnZlbG9wZSBoZWFkZXJzLCBiYXNlZCBvbiBldmVudCwgc2RrIGluZm8gYW5kIHR1bm5lbAogKiBOb3RlOiBUaGlzIGZ1bmN0aW9uIHdhcyBleHRyYWN0ZWQgZnJvbSB0aGUgY29yZSBwYWNrYWdlIHRvIG1ha2UgaXQgYXZhaWxhYmxlIGluIFJlcGxheQogKi8KZnVuY3Rpb24gY3JlYXRlRXZlbnRFbnZlbG9wZUhlYWRlcnMoCiAgZXZlbnQsCiAgc2RrSW5mbywKICB0dW5uZWwsCiAgZHNuLAopIHsKICBjb25zdCBkeW5hbWljU2FtcGxpbmdDb250ZXh0ID0gZXZlbnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhICYmIGV2ZW50LnNka1Byb2Nlc3NpbmdNZXRhZGF0YS5keW5hbWljU2FtcGxpbmdDb250ZXh0OwogIHJldHVybiB7CiAgICBldmVudF9pZDogZXZlbnQuZXZlbnRfaWQgLAogICAgc2VudF9hdDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLAogICAgLi4uKHNka0luZm8gJiYgeyBzZGs6IHNka0luZm8gfSksCiAgICAuLi4oISF0dW5uZWwgJiYgZHNuICYmIHsgZHNuOiBkc25Ub1N0cmluZyhkc24pIH0pLAogICAgLi4uKGR5bmFtaWNTYW1wbGluZ0NvbnRleHQgJiYgewogICAgICB0cmFjZTogZHJvcFVuZGVmaW5lZEtleXMoeyAuLi5keW5hbWljU2FtcGxpbmdDb250ZXh0IH0pLAogICAgfSksCiAgfTsKfQoKLy8gSW50ZW50aW9uYWxseSBrZWVwaW5nIHRoZSBrZXkgYnJvYWQsIGFzIHdlIGRvbid0IGtub3cgZm9yIHN1cmUgd2hhdCByYXRlIGxpbWl0IGhlYWRlcnMgZ2V0IHJldHVybmVkIGZyb20gYmFja2VuZAoKY29uc3QgREVGQVVMVF9SRVRSWV9BRlRFUiA9IDYwICogMTAwMDsgLy8gNjAgc2Vjb25kcwoKLyoqCiAqIEV4dHJhY3RzIFJldHJ5LUFmdGVyIHZhbHVlIGZyb20gdGhlIHJlcXVlc3QgaGVhZGVyIG9yIHJldHVybnMgZGVmYXVsdCB2YWx1ZQogKiBAcGFyYW0gaGVhZGVyIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiAnUmV0cnktQWZ0ZXInIGhlYWRlcgogKiBAcGFyYW0gbm93IGN1cnJlbnQgdW5peCB0aW1lc3RhbXAKICoKICovCmZ1bmN0aW9uIHBhcnNlUmV0cnlBZnRlckhlYWRlcihoZWFkZXIsIG5vdyA9IERhdGUubm93KCkpIHsKICBjb25zdCBoZWFkZXJEZWxheSA9IHBhcnNlSW50KGAke2hlYWRlcn1gLCAxMCk7CiAgaWYgKCFpc05hTihoZWFkZXJEZWxheSkpIHsKICAgIHJldHVybiBoZWFkZXJEZWxheSAqIDEwMDA7CiAgfQoKICBjb25zdCBoZWFkZXJEYXRlID0gRGF0ZS5wYXJzZShgJHtoZWFkZXJ9YCk7CiAgaWYgKCFpc05hTihoZWFkZXJEYXRlKSkgewogICAgcmV0dXJuIGhlYWRlckRhdGUgLSBub3c7CiAgfQoKICByZXR1cm4gREVGQVVMVF9SRVRSWV9BRlRFUjsKfQoKLyoqCiAqIEdldHMgdGhlIHRpbWUgdGhhdCB0aGUgZ2l2ZW4gY2F0ZWdvcnkgaXMgZGlzYWJsZWQgdW50aWwgZm9yIHJhdGUgbGltaXRpbmcuCiAqIEluIGNhc2Ugbm8gY2F0ZWdvcnktc3BlY2lmaWMgbGltaXQgaXMgc2V0IGJ1dCBhIGdlbmVyYWwgcmF0ZSBsaW1pdCBhY3Jvc3MgYWxsIGNhdGVnb3JpZXMgaXMgYWN0aXZlLAogKiB0aGF0IHRpbWUgaXMgcmV0dXJuZWQuCiAqCiAqIEByZXR1cm4gdGhlIHRpbWUgaW4gbXMgdGhhdCB0aGUgY2F0ZWdvcnkgaXMgZGlzYWJsZWQgdW50aWwgb3IgMCBpZiB0aGVyZSdzIG5vIGFjdGl2ZSByYXRlIGxpbWl0LgogKi8KZnVuY3Rpb24gZGlzYWJsZWRVbnRpbChsaW1pdHMsIGNhdGVnb3J5KSB7CiAgcmV0dXJuIGxpbWl0c1tjYXRlZ29yeV0gfHwgbGltaXRzLmFsbCB8fCAwOwp9CgovKioKICogQ2hlY2tzIGlmIGEgY2F0ZWdvcnkgaXMgcmF0ZSBsaW1pdGVkCiAqLwpmdW5jdGlvbiBpc1JhdGVMaW1pdGVkKGxpbWl0cywgY2F0ZWdvcnksIG5vdyA9IERhdGUubm93KCkpIHsKICByZXR1cm4gZGlzYWJsZWRVbnRpbChsaW1pdHMsIGNhdGVnb3J5KSA+IG5vdzsKfQoKLyoqCiAqIFVwZGF0ZSByYXRlbGltaXRzIGZyb20gaW5jb21pbmcgaGVhZGVycy4KICoKICogQHJldHVybiB0aGUgdXBkYXRlZCBSYXRlTGltaXRzIG9iamVjdC4KICovCmZ1bmN0aW9uIHVwZGF0ZVJhdGVMaW1pdHMoCiAgbGltaXRzLAogIHsgc3RhdHVzQ29kZSwgaGVhZGVycyB9LAogIG5vdyA9IERhdGUubm93KCksCikgewogIGNvbnN0IHVwZGF0ZWRSYXRlTGltaXRzID0gewogICAgLi4ubGltaXRzLAogIH07CgogIC8vICJUaGUgbmFtZSBpcyBjYXNlLWluc2Vuc2l0aXZlLiIKICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvSGVhZGVycy9nZXQKICBjb25zdCByYXRlTGltaXRIZWFkZXIgPSBoZWFkZXJzICYmIGhlYWRlcnNbJ3gtc2VudHJ5LXJhdGUtbGltaXRzJ107CiAgY29uc3QgcmV0cnlBZnRlckhlYWRlciA9IGhlYWRlcnMgJiYgaGVhZGVyc1sncmV0cnktYWZ0ZXInXTsKCiAgaWYgKHJhdGVMaW1pdEhlYWRlcikgewogICAgLyoqCiAgICAgKiByYXRlIGxpbWl0IGhlYWRlcnMgYXJlIG9mIHRoZSBmb3JtCiAgICAgKiAgICAgPGhlYWRlcj4sPGhlYWRlcj4sLi4KICAgICAqIHdoZXJlIGVhY2ggPGhlYWRlcj4gaXMgb2YgdGhlIGZvcm0KICAgICAqICAgICA8cmV0cnlfYWZ0ZXI+OiA8Y2F0ZWdvcmllcz46IDxzY29wZT46IDxyZWFzb25fY29kZT4KICAgICAqIHdoZXJlCiAgICAgKiAgICAgPHJldHJ5X2FmdGVyPiBpcyBhIGRlbGF5IGluIHNlY29uZHMKICAgICAqICAgICA8Y2F0ZWdvcmllcz4gaXMgdGhlIGV2ZW50IHR5cGUocykgKGVycm9yLCB0cmFuc2FjdGlvbiwgZXRjKSBiZWluZyByYXRlIGxpbWl0ZWQgYW5kIGlzIG9mIHRoZSBmb3JtCiAgICAgKiAgICAgICAgIDxjYXRlZ29yeT47PGNhdGVnb3J5PjsuLi4KICAgICAqICAgICA8c2NvcGU+IGlzIHdoYXQncyBiZWluZyBsaW1pdGVkIChvcmcsIHByb2plY3QsIG9yIGtleSkgLSBpZ25vcmVkIGJ5IFNESwogICAgICogICAgIDxyZWFzb25fY29kZT4gaXMgYW4gYXJiaXRyYXJ5IHN0cmluZyBsaWtlICJvcmdfcXVvdGEiIC0gaWdub3JlZCBieSBTREsKICAgICAqLwogICAgZm9yIChjb25zdCBsaW1pdCBvZiByYXRlTGltaXRIZWFkZXIudHJpbSgpLnNwbGl0KCcsJykpIHsKICAgICAgY29uc3QgW3JldHJ5QWZ0ZXIsIGNhdGVnb3JpZXNdID0gbGltaXQuc3BsaXQoJzonLCAyKTsKICAgICAgY29uc3QgaGVhZGVyRGVsYXkgPSBwYXJzZUludChyZXRyeUFmdGVyLCAxMCk7CiAgICAgIGNvbnN0IGRlbGF5ID0gKCFpc05hTihoZWFkZXJEZWxheSkgPyBoZWFkZXJEZWxheSA6IDYwKSAqIDEwMDA7IC8vIDYwc2VjIGRlZmF1bHQKICAgICAgaWYgKCFjYXRlZ29yaWVzKSB7CiAgICAgICAgdXBkYXRlZFJhdGVMaW1pdHMuYWxsID0gbm93ICsgZGVsYXk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZm9yIChjb25zdCBjYXRlZ29yeSBvZiBjYXRlZ29yaWVzLnNwbGl0KCc7JykpIHsKICAgICAgICAgIHVwZGF0ZWRSYXRlTGltaXRzW2NhdGVnb3J5XSA9IG5vdyArIGRlbGF5OwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0gZWxzZSBpZiAocmV0cnlBZnRlckhlYWRlcikgewogICAgdXBkYXRlZFJhdGVMaW1pdHMuYWxsID0gbm93ICsgcGFyc2VSZXRyeUFmdGVySGVhZGVyKHJldHJ5QWZ0ZXJIZWFkZXIsIG5vdyk7CiAgfSBlbHNlIGlmIChzdGF0dXNDb2RlID09PSA0MjkpIHsKICAgIHVwZGF0ZWRSYXRlTGltaXRzLmFsbCA9IG5vdyArIDYwICogMTAwMDsKICB9CgogIHJldHVybiB1cGRhdGVkUmF0ZUxpbWl0czsKfQoKLyoqCiAqIEEgbm9kZS5qcyB3YXRjaGRvZyB0aW1lcgogKiBAcGFyYW0gcG9sbEludGVydmFsIFRoZSBpbnRlcnZhbCB0aGF0IHdlIGV4cGVjdCB0byBnZXQgcG9sbGVkIGF0CiAqIEBwYXJhbSBhbnJUaHJlc2hvbGQgVGhlIHRocmVzaG9sZCBmb3Igd2hlbiB3ZSBjb25zaWRlciBBTlIKICogQHBhcmFtIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBjYWxsIGZvciBBTlIKICogQHJldHVybnMgQW4gb2JqZWN0IHdpdGggYHBvbGxgIGFuZCBgZW5hYmxlZGAgZnVuY3Rpb25zIHtAbGluayBXYXRjaGRvZ1JldHVybn0KICovCmZ1bmN0aW9uIHdhdGNoZG9nVGltZXIoCiAgY3JlYXRlVGltZXIsCiAgcG9sbEludGVydmFsLAogIGFuclRocmVzaG9sZCwKICBjYWxsYmFjaywKKSB7CiAgY29uc3QgdGltZXIgPSBjcmVhdGVUaW1lcigpOwogIGxldCB0cmlnZ2VyZWQgPSBmYWxzZTsKICBsZXQgZW5hYmxlZCA9IHRydWU7CgogIHNldEludGVydmFsKCgpID0+IHsKICAgIGNvbnN0IGRpZmZNcyA9IHRpbWVyLmdldFRpbWVNcygpOwoKICAgIGlmICh0cmlnZ2VyZWQgPT09IGZhbHNlICYmIGRpZmZNcyA+IHBvbGxJbnRlcnZhbCArIGFuclRocmVzaG9sZCkgewogICAgICB0cmlnZ2VyZWQgPSB0cnVlOwogICAgICBpZiAoZW5hYmxlZCkgewogICAgICAgIGNhbGxiYWNrKCk7CiAgICAgIH0KICAgIH0KCiAgICBpZiAoZGlmZk1zIDwgcG9sbEludGVydmFsICsgYW5yVGhyZXNob2xkKSB7CiAgICAgIHRyaWdnZXJlZCA9IGZhbHNlOwogICAgfQogIH0sIDIwKTsKCiAgcmV0dXJuIHsKICAgIHBvbGw6ICgpID0+IHsKICAgICAgdGltZXIucmVzZXQoKTsKICAgIH0sCiAgICBlbmFibGVkOiAoc3RhdGUpID0+IHsKICAgICAgZW5hYmxlZCA9IHN0YXRlOwogICAgfSwKICB9Owp9CgovLyB0eXBlcyBjb3BpZWQgZnJvbSBpbnNwZWN0b3IuZC50cwoKLyoqCiAqIENvbnZlcnRzIERlYnVnZ2VyLkNhbGxGcmFtZSB0byBTZW50cnkgU3RhY2tGcmFtZQogKi8KZnVuY3Rpb24gY2FsbEZyYW1lVG9TdGFja0ZyYW1lKAogIGZyYW1lLAogIHVybCwKICBnZXRNb2R1bGVGcm9tRmlsZW5hbWUsCikgewogIGNvbnN0IGZpbGVuYW1lID0gdXJsID8gdXJsLnJlcGxhY2UoL15maWxlOlwvXC8vLCAnJykgOiB1bmRlZmluZWQ7CgogIC8vIENhbGxGcmFtZSByb3cvY29sIGFyZSAwIGJhc2VkLCB3aGVyZWFzIFN0YWNrRnJhbWUgYXJlIDEgYmFzZWQKICBjb25zdCBjb2xubyA9IGZyYW1lLmxvY2F0aW9uLmNvbHVtbk51bWJlciA/IGZyYW1lLmxvY2F0aW9uLmNvbHVtbk51bWJlciArIDEgOiB1bmRlZmluZWQ7CiAgY29uc3QgbGluZW5vID0gZnJhbWUubG9jYXRpb24ubGluZU51bWJlciA/IGZyYW1lLmxvY2F0aW9uLmxpbmVOdW1iZXIgKyAxIDogdW5kZWZpbmVkOwoKICByZXR1cm4gZHJvcFVuZGVmaW5lZEtleXMoewogICAgZmlsZW5hbWUsCiAgICBtb2R1bGU6IGdldE1vZHVsZUZyb21GaWxlbmFtZShmaWxlbmFtZSksCiAgICBmdW5jdGlvbjogZnJhbWUuZnVuY3Rpb25OYW1lIHx8ICc/JywKICAgIGNvbG5vLAogICAgbGluZW5vLAogICAgaW5fYXBwOiBmaWxlbmFtZSA/IGZpbGVuYW1lSXNJbkFwcChmaWxlbmFtZSkgOiB1bmRlZmluZWQsCiAgfSk7Cn0KCi8qKgogKiBUaGlzIHNlcnZlcyBhcyBhIGJ1aWxkIHRpbWUgZmxhZyB0aGF0IHdpbGwgYmUgdHJ1ZSBieSBkZWZhdWx0LCBidXQgZmFsc2UgaW4gbm9uLWRlYnVnIGJ1aWxkcyBvciBpZiB1c2VycyByZXBsYWNlIGBfX1NFTlRSWV9ERUJVR19fYCBpbiB0aGVpciBnZW5lcmF0ZWQgY29kZS4KICoKICogQVRURU5USU9OOiBUaGlzIGNvbnN0YW50IG11c3QgbmV2ZXIgY3Jvc3MgcGFja2FnZSBib3VuZGFyaWVzIChpLmUuIGJlIGV4cG9ydGVkKSB0byBndWFyYW50ZWUgdGhhdCBpdCBjYW4gYmUgdXNlZCBmb3IgdHJlZSBzaGFraW5nLgogKi8KY29uc3QgREVCVUdfQlVJTEQgPSAodHlwZW9mIF9fU0VOVFJZX0RFQlVHX18gPT09ICd1bmRlZmluZWQnIHx8IF9fU0VOVFJZX0RFQlVHX18pOwoKLyoqCiAqIENyZWF0ZXMgYSBuZXcgYFNlc3Npb25gIG9iamVjdCBieSBzZXR0aW5nIGNlcnRhaW4gZGVmYXVsdCBwYXJhbWV0ZXJzLiBJZiBvcHRpb25hbCBAcGFyYW0gY29udGV4dAogKiBpcyBwYXNzZWQsIHRoZSBwYXNzZWQgcHJvcGVydGllcyBhcmUgYXBwbGllZCB0byB0aGUgc2Vzc2lvbiBvYmplY3QuCiAqCiAqIEBwYXJhbSBjb250ZXh0IChvcHRpb25hbCkgYWRkaXRpb25hbCBwcm9wZXJ0aWVzIHRvIGJlIGFwcGxpZWQgdG8gdGhlIHJldHVybmVkIHNlc3Npb24gb2JqZWN0CiAqCiAqIEByZXR1cm5zIGEgbmV3IGBTZXNzaW9uYCBvYmplY3QKICovCmZ1bmN0aW9uIG1ha2VTZXNzaW9uKGNvbnRleHQpIHsKICAvLyBCb3RoIHRpbWVzdGFtcCBhbmQgc3RhcnRlZCBhcmUgaW4gc2Vjb25kcyBzaW5jZSB0aGUgVU5JWCBlcG9jaC4KICBjb25zdCBzdGFydGluZ1RpbWUgPSB0aW1lc3RhbXBJblNlY29uZHMoKTsKCiAgY29uc3Qgc2Vzc2lvbiA9IHsKICAgIHNpZDogdXVpZDQoKSwKICAgIGluaXQ6IHRydWUsCiAgICB0aW1lc3RhbXA6IHN0YXJ0aW5nVGltZSwKICAgIHN0YXJ0ZWQ6IHN0YXJ0aW5nVGltZSwKICAgIGR1cmF0aW9uOiAwLAogICAgc3RhdHVzOiAnb2snLAogICAgZXJyb3JzOiAwLAogICAgaWdub3JlRHVyYXRpb246IGZhbHNlLAogICAgdG9KU09OOiAoKSA9PiBzZXNzaW9uVG9KU09OKHNlc3Npb24pLAogIH07CgogIGlmIChjb250ZXh0KSB7CiAgICB1cGRhdGVTZXNzaW9uKHNlc3Npb24sIGNvbnRleHQpOwogIH0KCiAgcmV0dXJuIHNlc3Npb247Cn0KCi8qKgogKiBVcGRhdGVzIGEgc2Vzc2lvbiBvYmplY3Qgd2l0aCB0aGUgcHJvcGVydGllcyBwYXNzZWQgaW4gdGhlIGNvbnRleHQuCiAqCiAqIE5vdGUgdGhhdCB0aGlzIGZ1bmN0aW9uIG11dGF0ZXMgdGhlIHBhc3NlZCBvYmplY3QgYW5kIHJldHVybnMgdm9pZC4KICogKEhhZCB0byBkbyB0aGlzIGluc3RlYWQgb2YgcmV0dXJuaW5nIGEgbmV3IGFuZCB1cGRhdGVkIHNlc3Npb24gYmVjYXVzZSBjbG9zaW5nIGFuZCBzZW5kaW5nIGEgc2Vzc2lvbgogKiBtYWtlcyBhbiB1cGRhdGUgdG8gdGhlIHNlc3Npb24gYWZ0ZXIgaXQgd2FzIHBhc3NlZCB0byB0aGUgc2VuZGluZyBsb2dpYy4KICogQHNlZSBCYXNlQ2xpZW50LmNhcHR1cmVTZXNzaW9uICkKICoKICogQHBhcmFtIHNlc3Npb24gdGhlIGBTZXNzaW9uYCB0byB1cGRhdGUKICogQHBhcmFtIGNvbnRleHQgdGhlIGBTZXNzaW9uQ29udGV4dGAgaG9sZGluZyB0aGUgcHJvcGVydGllcyB0aGF0IHNob3VsZCBiZSB1cGRhdGVkIGluIEBwYXJhbSBzZXNzaW9uCiAqLwovLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29tcGxleGl0eQpmdW5jdGlvbiB1cGRhdGVTZXNzaW9uKHNlc3Npb24sIGNvbnRleHQgPSB7fSkgewogIGlmIChjb250ZXh0LnVzZXIpIHsKICAgIGlmICghc2Vzc2lvbi5pcEFkZHJlc3MgJiYgY29udGV4dC51c2VyLmlwX2FkZHJlc3MpIHsKICAgICAgc2Vzc2lvbi5pcEFkZHJlc3MgPSBjb250ZXh0LnVzZXIuaXBfYWRkcmVzczsKICAgIH0KCiAgICBpZiAoIXNlc3Npb24uZGlkICYmICFjb250ZXh0LmRpZCkgewogICAgICBzZXNzaW9uLmRpZCA9IGNvbnRleHQudXNlci5pZCB8fCBjb250ZXh0LnVzZXIuZW1haWwgfHwgY29udGV4dC51c2VyLnVzZXJuYW1lOwogICAgfQogIH0KCiAgc2Vzc2lvbi50aW1lc3RhbXAgPSBjb250ZXh0LnRpbWVzdGFtcCB8fCB0aW1lc3RhbXBJblNlY29uZHMoKTsKCiAgaWYgKGNvbnRleHQuYWJub3JtYWxfbWVjaGFuaXNtKSB7CiAgICBzZXNzaW9uLmFibm9ybWFsX21lY2hhbmlzbSA9IGNvbnRleHQuYWJub3JtYWxfbWVjaGFuaXNtOwogIH0KCiAgaWYgKGNvbnRleHQuaWdub3JlRHVyYXRpb24pIHsKICAgIHNlc3Npb24uaWdub3JlRHVyYXRpb24gPSBjb250ZXh0Lmlnbm9yZUR1cmF0aW9uOwogIH0KICBpZiAoY29udGV4dC5zaWQpIHsKICAgIC8vIEdvb2QgZW5vdWdoIHV1aWQgdmFsaWRhdGlvbi4g4oCUIEthbWlsCiAgICBzZXNzaW9uLnNpZCA9IGNvbnRleHQuc2lkLmxlbmd0aCA9PT0gMzIgPyBjb250ZXh0LnNpZCA6IHV1aWQ0KCk7CiAgfQogIGlmIChjb250ZXh0LmluaXQgIT09IHVuZGVmaW5lZCkgewogICAgc2Vzc2lvbi5pbml0ID0gY29udGV4dC5pbml0OwogIH0KICBpZiAoIXNlc3Npb24uZGlkICYmIGNvbnRleHQuZGlkKSB7CiAgICBzZXNzaW9uLmRpZCA9IGAke2NvbnRleHQuZGlkfWA7CiAgfQogIGlmICh0eXBlb2YgY29udGV4dC5zdGFydGVkID09PSAnbnVtYmVyJykgewogICAgc2Vzc2lvbi5zdGFydGVkID0gY29udGV4dC5zdGFydGVkOwogIH0KICBpZiAoc2Vzc2lvbi5pZ25vcmVEdXJhdGlvbikgewogICAgc2Vzc2lvbi5kdXJhdGlvbiA9IHVuZGVmaW5lZDsKICB9IGVsc2UgaWYgKHR5cGVvZiBjb250ZXh0LmR1cmF0aW9uID09PSAnbnVtYmVyJykgewogICAgc2Vzc2lvbi5kdXJhdGlvbiA9IGNvbnRleHQuZHVyYXRpb247CiAgfSBlbHNlIHsKICAgIGNvbnN0IGR1cmF0aW9uID0gc2Vzc2lvbi50aW1lc3RhbXAgLSBzZXNzaW9uLnN0YXJ0ZWQ7CiAgICBzZXNzaW9uLmR1cmF0aW9uID0gZHVyYXRpb24gPj0gMCA/IGR1cmF0aW9uIDogMDsKICB9CiAgaWYgKGNvbnRleHQucmVsZWFzZSkgewogICAgc2Vzc2lvbi5yZWxlYXNlID0gY29udGV4dC5yZWxlYXNlOwogIH0KICBpZiAoY29udGV4dC5lbnZpcm9ubWVudCkgewogICAgc2Vzc2lvbi5lbnZpcm9ubWVudCA9IGNvbnRleHQuZW52aXJvbm1lbnQ7CiAgfQogIGlmICghc2Vzc2lvbi5pcEFkZHJlc3MgJiYgY29udGV4dC5pcEFkZHJlc3MpIHsKICAgIHNlc3Npb24uaXBBZGRyZXNzID0gY29udGV4dC5pcEFkZHJlc3M7CiAgfQogIGlmICghc2Vzc2lvbi51c2VyQWdlbnQgJiYgY29udGV4dC51c2VyQWdlbnQpIHsKICAgIHNlc3Npb24udXNlckFnZW50ID0gY29udGV4dC51c2VyQWdlbnQ7CiAgfQogIGlmICh0eXBlb2YgY29udGV4dC5lcnJvcnMgPT09ICdudW1iZXInKSB7CiAgICBzZXNzaW9uLmVycm9ycyA9IGNvbnRleHQuZXJyb3JzOwogIH0KICBpZiAoY29udGV4dC5zdGF0dXMpIHsKICAgIHNlc3Npb24uc3RhdHVzID0gY29udGV4dC5zdGF0dXM7CiAgfQp9CgovKioKICogU2VyaWFsaXplcyBhIHBhc3NlZCBzZXNzaW9uIG9iamVjdCB0byBhIEpTT04gb2JqZWN0IHdpdGggYSBzbGlnaHRseSBkaWZmZXJlbnQgc3RydWN0dXJlLgogKiBUaGlzIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIHRoZSBTZW50cnkgYmFja2VuZCByZXF1aXJlcyBhIHNsaWdodGx5IGRpZmZlcmVudCBzY2hlbWEgb2YgYSBzZXNzaW9uCiAqIHRoYW4gdGhlIG9uZSB0aGUgSlMgU0RLcyB1c2UgaW50ZXJuYWxseS4KICoKICogQHBhcmFtIHNlc3Npb24gdGhlIHNlc3Npb24gdG8gYmUgY29udmVydGVkCiAqCiAqIEByZXR1cm5zIGEgSlNPTiBvYmplY3Qgb2YgdGhlIHBhc3NlZCBzZXNzaW9uCiAqLwpmdW5jdGlvbiBzZXNzaW9uVG9KU09OKHNlc3Npb24pIHsKICByZXR1cm4gZHJvcFVuZGVmaW5lZEtleXMoewogICAgc2lkOiBgJHtzZXNzaW9uLnNpZH1gLAogICAgaW5pdDogc2Vzc2lvbi5pbml0LAogICAgLy8gTWFrZSBzdXJlIHRoYXQgc2VjIGlzIGNvbnZlcnRlZCB0byBtcyBmb3IgZGF0ZSBjb25zdHJ1Y3RvcgogICAgc3RhcnRlZDogbmV3IERhdGUoc2Vzc2lvbi5zdGFydGVkICogMTAwMCkudG9JU09TdHJpbmcoKSwKICAgIHRpbWVzdGFtcDogbmV3IERhdGUoc2Vzc2lvbi50aW1lc3RhbXAgKiAxMDAwKS50b0lTT1N0cmluZygpLAogICAgc3RhdHVzOiBzZXNzaW9uLnN0YXR1cywKICAgIGVycm9yczogc2Vzc2lvbi5lcnJvcnMsCiAgICBkaWQ6IHR5cGVvZiBzZXNzaW9uLmRpZCA9PT0gJ251bWJlcicgfHwgdHlwZW9mIHNlc3Npb24uZGlkID09PSAnc3RyaW5nJyA/IGAke3Nlc3Npb24uZGlkfWAgOiB1bmRlZmluZWQsCiAgICBkdXJhdGlvbjogc2Vzc2lvbi5kdXJhdGlvbiwKICAgIGFibm9ybWFsX21lY2hhbmlzbTogc2Vzc2lvbi5hYm5vcm1hbF9tZWNoYW5pc20sCiAgICBhdHRyczogewogICAgICByZWxlYXNlOiBzZXNzaW9uLnJlbGVhc2UsCiAgICAgIGVudmlyb25tZW50OiBzZXNzaW9uLmVudmlyb25tZW50LAogICAgICBpcF9hZGRyZXNzOiBzZXNzaW9uLmlwQWRkcmVzcywKICAgICAgdXNlcl9hZ2VudDogc2Vzc2lvbi51c2VyQWdlbnQsCiAgICB9LAogIH0pOwp9CgovKioKICogQXBwbHkgU2RrSW5mbyAobmFtZSwgdmVyc2lvbiwgcGFja2FnZXMsIGludGVncmF0aW9ucykgdG8gdGhlIGNvcnJlc3BvbmRpbmcgZXZlbnQga2V5LgogKiBNZXJnZSB3aXRoIGV4aXN0aW5nIGRhdGEgaWYgYW55LgogKiovCmZ1bmN0aW9uIGVuaGFuY2VFdmVudFdpdGhTZGtJbmZvKGV2ZW50LCBzZGtJbmZvKSB7CiAgaWYgKCFzZGtJbmZvKSB7CiAgICByZXR1cm4gZXZlbnQ7CiAgfQogIGV2ZW50LnNkayA9IGV2ZW50LnNkayB8fCB7fTsKICBldmVudC5zZGsubmFtZSA9IGV2ZW50LnNkay5uYW1lIHx8IHNka0luZm8ubmFtZTsKICBldmVudC5zZGsudmVyc2lvbiA9IGV2ZW50LnNkay52ZXJzaW9uIHx8IHNka0luZm8udmVyc2lvbjsKICBldmVudC5zZGsuaW50ZWdyYXRpb25zID0gWy4uLihldmVudC5zZGsuaW50ZWdyYXRpb25zIHx8IFtdKSwgLi4uKHNka0luZm8uaW50ZWdyYXRpb25zIHx8IFtdKV07CiAgZXZlbnQuc2RrLnBhY2thZ2VzID0gWy4uLihldmVudC5zZGsucGFja2FnZXMgfHwgW10pLCAuLi4oc2RrSW5mby5wYWNrYWdlcyB8fCBbXSldOwogIHJldHVybiBldmVudDsKfQoKLyoqIENyZWF0ZXMgYW4gZW52ZWxvcGUgZnJvbSBhIFNlc3Npb24gKi8KZnVuY3Rpb24gY3JlYXRlU2Vzc2lvbkVudmVsb3BlKAogIHNlc3Npb24sCiAgZHNuLAogIG1ldGFkYXRhLAogIHR1bm5lbCwKKSB7CiAgY29uc3Qgc2RrSW5mbyA9IGdldFNka01ldGFkYXRhRm9yRW52ZWxvcGVIZWFkZXIobWV0YWRhdGEpOwogIGNvbnN0IGVudmVsb3BlSGVhZGVycyA9IHsKICAgIHNlbnRfYXQ6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSwKICAgIC4uLihzZGtJbmZvICYmIHsgc2RrOiBzZGtJbmZvIH0pLAogICAgLi4uKCEhdHVubmVsICYmIGRzbiAmJiB7IGRzbjogZHNuVG9TdHJpbmcoZHNuKSB9KSwKICB9OwoKICBjb25zdCBlbnZlbG9wZUl0ZW0gPQogICAgJ2FnZ3JlZ2F0ZXMnIGluIHNlc3Npb24gPyBbeyB0eXBlOiAnc2Vzc2lvbnMnIH0sIHNlc3Npb25dIDogW3sgdHlwZTogJ3Nlc3Npb24nIH0sIHNlc3Npb24udG9KU09OKCldOwoKICByZXR1cm4gY3JlYXRlRW52ZWxvcGUoZW52ZWxvcGVIZWFkZXJzLCBbZW52ZWxvcGVJdGVtXSk7Cn0KCi8qKgogKiBDcmVhdGUgYW4gRW52ZWxvcGUgZnJvbSBhbiBldmVudC4KICovCmZ1bmN0aW9uIGNyZWF0ZUV2ZW50RW52ZWxvcGUoCiAgZXZlbnQsCiAgZHNuLAogIG1ldGFkYXRhLAogIHR1bm5lbCwKKSB7CiAgY29uc3Qgc2RrSW5mbyA9IGdldFNka01ldGFkYXRhRm9yRW52ZWxvcGVIZWFkZXIobWV0YWRhdGEpOwoKICAvKgogICAgTm90ZTogRHVlIHRvIFRTLCBldmVudC50eXBlIG1heSBiZSBgcmVwbGF5X2V2ZW50YCwgdGhlb3JldGljYWxseS4KICAgIEluIHByYWN0aWNlLCB3ZSBuZXZlciBjYWxsIGBjcmVhdGVFdmVudEVudmVsb3BlYCB3aXRoIGByZXBsYXlfZXZlbnRgIHR5cGUsCiAgICBhbmQgd2UnZCBoYXZlIHRvIGFkanV0IGEgbG9vb3Qgb2YgdHlwZXMgdG8gbWFrZSB0aGlzIHdvcmsgcHJvcGVybHkuCiAgICBXZSB3YW50IHRvIGF2b2lkIGNhc3RpbmcgdGhpcyBhcm91bmQsIGFzIHRoYXQgY291bGQgbGVhZCB0byBidWdzIChlLmcuIHdoZW4gd2UgYWRkIGFub3RoZXIgdHlwZSkKICAgIFNvIHRoZSBzYWZlIGNob2ljZSBpcyB0byByZWFsbHkgZ3VhcmQgYWdhaW5zdCB0aGUgcmVwbGF5X2V2ZW50IHR5cGUgaGVyZS4KICAqLwogIGNvbnN0IGV2ZW50VHlwZSA9IGV2ZW50LnR5cGUgJiYgZXZlbnQudHlwZSAhPT0gJ3JlcGxheV9ldmVudCcgPyBldmVudC50eXBlIDogJ2V2ZW50JzsKCiAgZW5oYW5jZUV2ZW50V2l0aFNka0luZm8oZXZlbnQsIG1ldGFkYXRhICYmIG1ldGFkYXRhLnNkayk7CgogIGNvbnN0IGVudmVsb3BlSGVhZGVycyA9IGNyZWF0ZUV2ZW50RW52ZWxvcGVIZWFkZXJzKGV2ZW50LCBzZGtJbmZvLCB0dW5uZWwsIGRzbik7CgogIC8vIFByZXZlbnQgdGhpcyBkYXRhICh3aGljaCwgaWYgaXQgZXhpc3RzLCB3YXMgdXNlZCBpbiBlYXJsaWVyIHN0ZXBzIGluIHRoZSBwcm9jZXNzaW5nIHBpcGVsaW5lKSBmcm9tIGJlaW5nIHNlbnQgdG8KICAvLyBzZW50cnkuIChOb3RlOiBPdXIgdXNlIG9mIHRoaXMgcHJvcGVydHkgY29tZXMgYW5kIGdvZXMgd2l0aCB3aGF0ZXZlciB3ZSBtaWdodCBiZSBkZWJ1Z2dpbmcsIHdoYXRldmVyIGhhY2tzIHdlIG1heQogIC8vIGhhdmUgdGVtcG9yYXJpbHkgYWRkZWQsIGV0Yy4gRXZlbiBpZiB3ZSBkb24ndCBoYXBwZW4gdG8gYmUgdXNpbmcgaXQgYXQgc29tZSBwb2ludCBpbiB0aGUgZnV0dXJlLCBsZXQncyBub3QgZ2V0IHJpZAogIC8vIG9mIHRoaXMgYGRlbGV0ZWAsIGxlc3Qgd2UgbWlzcyBwdXR0aW5nIGl0IGJhY2sgaW4gdGhlIG5leHQgdGltZSB0aGUgcHJvcGVydHkgaXMgaW4gdXNlLikKICBkZWxldGUgZXZlbnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhOwoKICBjb25zdCBldmVudEl0ZW0gPSBbeyB0eXBlOiBldmVudFR5cGUgfSwgZXZlbnRdOwogIHJldHVybiBjcmVhdGVFbnZlbG9wZShlbnZlbG9wZUhlYWRlcnMsIFtldmVudEl0ZW1dKTsKfQoKY29uc3QgU0VOVFJZX0FQSV9WRVJTSU9OID0gJzcnOwoKLyoqIFJldHVybnMgdGhlIHByZWZpeCB0byBjb25zdHJ1Y3QgU2VudHJ5IGluZ2VzdGlvbiBBUEkgZW5kcG9pbnRzLiAqLwpmdW5jdGlvbiBnZXRCYXNlQXBpRW5kcG9pbnQoZHNuKSB7CiAgY29uc3QgcHJvdG9jb2wgPSBkc24ucHJvdG9jb2wgPyBgJHtkc24ucHJvdG9jb2x9OmAgOiAnJzsKICBjb25zdCBwb3J0ID0gZHNuLnBvcnQgPyBgOiR7ZHNuLnBvcnR9YCA6ICcnOwogIHJldHVybiBgJHtwcm90b2NvbH0vLyR7ZHNuLmhvc3R9JHtwb3J0fSR7ZHNuLnBhdGggPyBgLyR7ZHNuLnBhdGh9YCA6ICcnfS9hcGkvYDsKfQoKLyoqIFJldHVybnMgdGhlIGluZ2VzdCBBUEkgZW5kcG9pbnQgZm9yIHRhcmdldC4gKi8KZnVuY3Rpb24gX2dldEluZ2VzdEVuZHBvaW50KGRzbikgewogIHJldHVybiBgJHtnZXRCYXNlQXBpRW5kcG9pbnQoZHNuKX0ke2Rzbi5wcm9qZWN0SWR9L2VudmVsb3BlL2A7Cn0KCi8qKiBSZXR1cm5zIGEgVVJMLWVuY29kZWQgc3RyaW5nIHdpdGggYXV0aCBjb25maWcgc3VpdGFibGUgZm9yIGEgcXVlcnkgc3RyaW5nLiAqLwpmdW5jdGlvbiBfZW5jb2RlZEF1dGgoZHNuLCBzZGtJbmZvKSB7CiAgcmV0dXJuIHVybEVuY29kZSh7CiAgICAvLyBXZSBzZW5kIG9ubHkgdGhlIG1pbmltdW0gc2V0IG9mIHJlcXVpcmVkIGluZm9ybWF0aW9uLiBTZWUKICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9nZXRzZW50cnkvc2VudHJ5LWphdmFzY3JpcHQvaXNzdWVzLzI1NzIuCiAgICBzZW50cnlfa2V5OiBkc24ucHVibGljS2V5LAogICAgc2VudHJ5X3ZlcnNpb246IFNFTlRSWV9BUElfVkVSU0lPTiwKICAgIC4uLihzZGtJbmZvICYmIHsgc2VudHJ5X2NsaWVudDogYCR7c2RrSW5mby5uYW1lfS8ke3Nka0luZm8udmVyc2lvbn1gIH0pLAogIH0pOwp9CgovKioKICogUmV0dXJucyB0aGUgZW52ZWxvcGUgZW5kcG9pbnQgVVJMIHdpdGggYXV0aCBpbiB0aGUgcXVlcnkgc3RyaW5nLgogKgogKiBTZW5kaW5nIGF1dGggYXMgcGFydCBvZiB0aGUgcXVlcnkgc3RyaW5nIGFuZCBub3QgYXMgY3VzdG9tIEhUVFAgaGVhZGVycyBhdm9pZHMgQ09SUyBwcmVmbGlnaHQgcmVxdWVzdHMuCiAqLwpmdW5jdGlvbiBnZXRFbnZlbG9wZUVuZHBvaW50V2l0aFVybEVuY29kZWRBdXRoKAogIGRzbiwKICAvLyBUT0RPICh2OCk6IFJlbW92ZSBgdHVubmVsT3JPcHRpb25zYCBpbiBmYXZvciBvZiBgb3B0aW9uc2AsIGFuZCB1c2UgdGhlIHN1YnN0aXR1dGUgY29kZSBiZWxvdwogIC8vIG9wdGlvbnM6IENsaWVudE9wdGlvbnMgPSB7fSBhcyBDbGllbnRPcHRpb25zLAogIHR1bm5lbE9yT3B0aW9ucyA9IHt9ICwKKSB7CiAgLy8gVE9ETyAodjgpOiBVc2UgdGhpcyBjb2RlIGluc3RlYWQKICAvLyBjb25zdCB7IHR1bm5lbCwgX21ldGFkYXRhID0ge30gfSA9IG9wdGlvbnM7CiAgLy8gcmV0dXJuIHR1bm5lbCA/IHR1bm5lbCA6IGAke19nZXRJbmdlc3RFbmRwb2ludChkc24pfT8ke19lbmNvZGVkQXV0aChkc24sIF9tZXRhZGF0YS5zZGspfWA7CgogIGNvbnN0IHR1bm5lbCA9IHR5cGVvZiB0dW5uZWxPck9wdGlvbnMgPT09ICdzdHJpbmcnID8gdHVubmVsT3JPcHRpb25zIDogdHVubmVsT3JPcHRpb25zLnR1bm5lbDsKICBjb25zdCBzZGtJbmZvID0KICAgIHR5cGVvZiB0dW5uZWxPck9wdGlvbnMgPT09ICdzdHJpbmcnIHx8ICF0dW5uZWxPck9wdGlvbnMuX21ldGFkYXRhID8gdW5kZWZpbmVkIDogdHVubmVsT3JPcHRpb25zLl9tZXRhZGF0YS5zZGs7CgogIHJldHVybiB0dW5uZWwgPyB0dW5uZWwgOiBgJHtfZ2V0SW5nZXN0RW5kcG9pbnQoZHNuKX0/JHtfZW5jb2RlZEF1dGgoZHNuLCBzZGtJbmZvKX1gOwp9Cgpjb25zdCBERUZBVUxUX1RSQU5TUE9SVF9CVUZGRVJfU0laRSA9IDMwOwoKLyoqCiAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgYSBTZW50cnkgYFRyYW5zcG9ydGAKICoKICogQHBhcmFtIG9wdGlvbnMKICogQHBhcmFtIG1ha2VSZXF1ZXN0CiAqLwpmdW5jdGlvbiBjcmVhdGVUcmFuc3BvcnQoCiAgb3B0aW9ucywKICBtYWtlUmVxdWVzdCwKICBidWZmZXIgPSBtYWtlUHJvbWlzZUJ1ZmZlcigKICAgIG9wdGlvbnMuYnVmZmVyU2l6ZSB8fCBERUZBVUxUX1RSQU5TUE9SVF9CVUZGRVJfU0laRSwKICApLAopIHsKICBsZXQgcmF0ZUxpbWl0cyA9IHt9OwogIGNvbnN0IGZsdXNoID0gKHRpbWVvdXQpID0+IGJ1ZmZlci5kcmFpbih0aW1lb3V0KTsKCiAgZnVuY3Rpb24gc2VuZChlbnZlbG9wZSkgewogICAgY29uc3QgZmlsdGVyZWRFbnZlbG9wZUl0ZW1zID0gW107CgogICAgLy8gRHJvcCByYXRlIGxpbWl0ZWQgaXRlbXMgZnJvbSBlbnZlbG9wZQogICAgZm9yRWFjaEVudmVsb3BlSXRlbShlbnZlbG9wZSwgKGl0ZW0sIHR5cGUpID0+IHsKICAgICAgY29uc3QgZW52ZWxvcGVJdGVtRGF0YUNhdGVnb3J5ID0gZW52ZWxvcGVJdGVtVHlwZVRvRGF0YUNhdGVnb3J5KHR5cGUpOwogICAgICBpZiAoaXNSYXRlTGltaXRlZChyYXRlTGltaXRzLCBlbnZlbG9wZUl0ZW1EYXRhQ2F0ZWdvcnkpKSB7CiAgICAgICAgY29uc3QgZXZlbnQgPSBnZXRFdmVudEZvckVudmVsb3BlSXRlbShpdGVtLCB0eXBlKTsKICAgICAgICBvcHRpb25zLnJlY29yZERyb3BwZWRFdmVudCgncmF0ZWxpbWl0X2JhY2tvZmYnLCBlbnZlbG9wZUl0ZW1EYXRhQ2F0ZWdvcnksIGV2ZW50KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBmaWx0ZXJlZEVudmVsb3BlSXRlbXMucHVzaChpdGVtKTsKICAgICAgfQogICAgfSk7CgogICAgLy8gU2tpcCBzZW5kaW5nIGlmIGVudmVsb3BlIGlzIGVtcHR5IGFmdGVyIGZpbHRlcmluZyBvdXQgcmF0ZSBsaW1pdGVkIGV2ZW50cwogICAgaWYgKGZpbHRlcmVkRW52ZWxvcGVJdGVtcy5sZW5ndGggPT09IDApIHsKICAgICAgcmV0dXJuIHJlc29sdmVkU3luY1Byb21pc2UoKTsKICAgIH0KCiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueQogICAgY29uc3QgZmlsdGVyZWRFbnZlbG9wZSA9IGNyZWF0ZUVudmVsb3BlKGVudmVsb3BlWzBdLCBmaWx0ZXJlZEVudmVsb3BlSXRlbXMgKTsKCiAgICAvLyBDcmVhdGVzIGNsaWVudCByZXBvcnQgZm9yIGVhY2ggaXRlbSBpbiBhbiBlbnZlbG9wZQogICAgY29uc3QgcmVjb3JkRW52ZWxvcGVMb3NzID0gKHJlYXNvbikgPT4gewogICAgICBmb3JFYWNoRW52ZWxvcGVJdGVtKGZpbHRlcmVkRW52ZWxvcGUsIChpdGVtLCB0eXBlKSA9PiB7CiAgICAgICAgY29uc3QgZXZlbnQgPSBnZXRFdmVudEZvckVudmVsb3BlSXRlbShpdGVtLCB0eXBlKTsKICAgICAgICBvcHRpb25zLnJlY29yZERyb3BwZWRFdmVudChyZWFzb24sIGVudmVsb3BlSXRlbVR5cGVUb0RhdGFDYXRlZ29yeSh0eXBlKSwgZXZlbnQpOwogICAgICB9KTsKICAgIH07CgogICAgY29uc3QgcmVxdWVzdFRhc2sgPSAoKSA9PgogICAgICBtYWtlUmVxdWVzdCh7IGJvZHk6IHNlcmlhbGl6ZUVudmVsb3BlKGZpbHRlcmVkRW52ZWxvcGUsIG9wdGlvbnMudGV4dEVuY29kZXIpIH0pLnRoZW4oCiAgICAgICAgcmVzcG9uc2UgPT4gewogICAgICAgICAgLy8gV2UgZG9uJ3Qgd2FudCB0byB0aHJvdyBvbiBOT0sgcmVzcG9uc2VzLCBidXQgd2Ugd2FudCB0byBhdCBsZWFzdCBsb2cgdGhlbQogICAgICAgICAgaWYgKHJlc3BvbnNlLnN0YXR1c0NvZGUgIT09IHVuZGVmaW5lZCAmJiAocmVzcG9uc2Uuc3RhdHVzQ29kZSA8IDIwMCB8fCByZXNwb25zZS5zdGF0dXNDb2RlID49IDMwMCkpIHsKICAgICAgICAgICAgREVCVUdfQlVJTEQgJiYgbG9nZ2VyLndhcm4oYFNlbnRyeSByZXNwb25kZWQgd2l0aCBzdGF0dXMgY29kZSAke3Jlc3BvbnNlLnN0YXR1c0NvZGV9IHRvIHNlbnQgZXZlbnQuYCk7CiAgICAgICAgICB9CgogICAgICAgICAgcmF0ZUxpbWl0cyA9IHVwZGF0ZVJhdGVMaW1pdHMocmF0ZUxpbWl0cywgcmVzcG9uc2UpOwogICAgICAgICAgcmV0dXJuIHJlc3BvbnNlOwogICAgICAgIH0sCiAgICAgICAgZXJyb3IgPT4gewogICAgICAgICAgcmVjb3JkRW52ZWxvcGVMb3NzKCduZXR3b3JrX2Vycm9yJyk7CiAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9LAogICAgICApOwoKICAgIHJldHVybiBidWZmZXIuYWRkKHJlcXVlc3RUYXNrKS50aGVuKAogICAgICByZXN1bHQgPT4gcmVzdWx0LAogICAgICBlcnJvciA9PiB7CiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgU2VudHJ5RXJyb3IpIHsKICAgICAgICAgIERFQlVHX0JVSUxEICYmIGxvZ2dlci5lcnJvcignU2tpcHBlZCBzZW5kaW5nIGV2ZW50IGJlY2F1c2UgYnVmZmVyIGlzIGZ1bGwuJyk7CiAgICAgICAgICByZWNvcmRFbnZlbG9wZUxvc3MoJ3F1ZXVlX292ZXJmbG93Jyk7CiAgICAgICAgICByZXR1cm4gcmVzb2x2ZWRTeW5jUHJvbWlzZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9CiAgICAgIH0sCiAgICApOwogIH0KCiAgLy8gV2UgdXNlIHRoaXMgdG8gaWRlbnRpZmlmeSBpZiB0aGUgdHJhbnNwb3J0IGlzIHRoZSBiYXNlIHRyYW5zcG9ydAogIC8vIFRPRE8gKHY4KTogUmVtb3ZlIHRoaXMgYWdhaW4gYXMgd2UnbGwgbm8gbG9uZ2VyIG5lZWQgaXQKICBzZW5kLl9fc2VudHJ5X19iYXNlVHJhbnNwb3J0X18gPSB0cnVlOwoKICByZXR1cm4gewogICAgc2VuZCwKICAgIGZsdXNoLAogIH07Cn0KCmZ1bmN0aW9uIGdldEV2ZW50Rm9yRW52ZWxvcGVJdGVtKGl0ZW0sIHR5cGUpIHsKICBpZiAodHlwZSAhPT0gJ2V2ZW50JyAmJiB0eXBlICE9PSAndHJhbnNhY3Rpb24nKSB7CiAgICByZXR1cm4gdW5kZWZpbmVkOwogIH0KCiAgcmV0dXJuIEFycmF5LmlzQXJyYXkoaXRlbSkgPyAoaXRlbSApWzFdIDogdW5kZWZpbmVkOwp9CgovKiogbm9ybWFsaXplcyBXaW5kb3dzIHBhdGhzICovCmZ1bmN0aW9uIG5vcm1hbGl6ZVdpbmRvd3NQYXRoKHBhdGgpIHsKICByZXR1cm4gcGF0aAogICAgLnJlcGxhY2UoL15bQS1aXTovLCAnJykgLy8gcmVtb3ZlIFdpbmRvd3Mtc3R5bGUgcHJlZml4CiAgICAucmVwbGFjZSgvXFwvZywgJy8nKTsgLy8gcmVwbGFjZSBhbGwgYFxgIGluc3RhbmNlcyB3aXRoIGAvYAp9CgovKiogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgZ2V0cyB0aGUgbW9kdWxlIG5hbWUgZnJvbSBhIGZpbGVuYW1lICovCmZ1bmN0aW9uIGNyZWF0ZUdldE1vZHVsZUZyb21GaWxlbmFtZSgKICBiYXNlUGF0aCA9IHByb2Nlc3MuYXJndlsxXSA/IGRpcm5hbWUocHJvY2Vzcy5hcmd2WzFdKSA6IHByb2Nlc3MuY3dkKCksCiAgaXNXaW5kb3dzID0gc2VwID09PSAnXFwnLAopIHsKICBjb25zdCBub3JtYWxpemVkQmFzZSA9IGlzV2luZG93cyA/IG5vcm1hbGl6ZVdpbmRvd3NQYXRoKGJhc2VQYXRoKSA6IGJhc2VQYXRoOwoKICByZXR1cm4gKGZpbGVuYW1lKSA9PiB7CiAgICBpZiAoIWZpbGVuYW1lKSB7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICBjb25zdCBub3JtYWxpemVkRmlsZW5hbWUgPSBpc1dpbmRvd3MgPyBub3JtYWxpemVXaW5kb3dzUGF0aChmaWxlbmFtZSkgOiBmaWxlbmFtZTsKCiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLWNvbnN0CiAgICBsZXQgeyBkaXIsIGJhc2U6IGZpbGUsIGV4dCB9ID0gcG9zaXgucGFyc2Uobm9ybWFsaXplZEZpbGVuYW1lKTsKCiAgICBpZiAoZXh0ID09PSAnLmpzJyB8fCBleHQgPT09ICcubWpzJyB8fCBleHQgPT09ICcuY2pzJykgewogICAgICBmaWxlID0gZmlsZS5zbGljZSgwLCBleHQubGVuZ3RoICogLTEpOwogICAgfQoKICAgIGlmICghZGlyKSB7CiAgICAgIC8vIE5vIGRpcm5hbWUgd2hhdHNvZXZlcgogICAgICBkaXIgPSAnLic7CiAgICB9CgogICAgY29uc3QgbiA9IGRpci5sYXN0SW5kZXhPZignL25vZGVfbW9kdWxlcycpOwogICAgaWYgKG4gPiAtMSkgewogICAgICByZXR1cm4gYCR7ZGlyLnNsaWNlKG4gKyAxNCkucmVwbGFjZSgvXC8vZywgJy4nKX06JHtmaWxlfWA7CiAgICB9CgogICAgLy8gTGV0J3Mgc2VlIGlmIGl0J3MgYSBwYXJ0IG9mIHRoZSBtYWluIG1vZHVsZQogICAgLy8gVG8gYmUgYSBwYXJ0IG9mIG1haW4gbW9kdWxlLCBpdCBoYXMgdG8gc2hhcmUgdGhlIHNhbWUgYmFzZQogICAgaWYgKGRpci5zdGFydHNXaXRoKG5vcm1hbGl6ZWRCYXNlKSkgewogICAgICBsZXQgbW9kdWxlTmFtZSA9IGRpci5zbGljZShub3JtYWxpemVkQmFzZS5sZW5ndGggKyAxKS5yZXBsYWNlKC9cLy9nLCAnLicpOwoKICAgICAgaWYgKG1vZHVsZU5hbWUpIHsKICAgICAgICBtb2R1bGVOYW1lICs9ICc6JzsKICAgICAgfQogICAgICBtb2R1bGVOYW1lICs9IGZpbGU7CgogICAgICByZXR1cm4gbW9kdWxlTmFtZTsKICAgIH0KCiAgICByZXR1cm4gZmlsZTsKICB9Owp9CgpmdW5jdGlvbiBfbnVsbGlzaENvYWxlc2NlJDIobGhzLCByaHNGbikgeyBpZiAobGhzICE9IG51bGwpIHsgcmV0dXJuIGxoczsgfSBlbHNlIHsgcmV0dXJuIHJoc0ZuKCk7IH0gfS8qKgogKiBUaGlzIGNvZGUgd2FzIG9yaWdpbmFsbHkgZm9ya2VkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL1Rvb1RhbGxOYXRlL3Byb3h5LWFnZW50cy90cmVlL2IxMzMyOTVmZDE2ZjY0NzU1NzhiNmIxNWJkOWI0ZTMzZWNiMGQwYjcKICogV2l0aCB0aGUgZm9sbG93aW5nIGxpY2VuY2U6CiAqCiAqIChUaGUgTUlUIExpY2Vuc2UpCiAqCiAqIENvcHlyaWdodCAoYykgMjAxMyBOYXRoYW4gUmFqbGljaCA8bmF0aGFuQHRvb3RhbGxuYXRlLm5ldD4qCiAqCiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZwogKiBhIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUKICogJ1NvZnR3YXJlJyksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZwogKiB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsCiAqIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0bwogKiBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8KICogdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOioKICoKICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUKICogaW5jbHVkZWQgaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuKgogKgogKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgJ0FTIElTJywgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwKICogRVhQUkVTUyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GCiAqIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4KICogSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkKICogQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwKICogVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUKICogU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCiAqLwoKY29uc3QgSU5URVJOQUwgPSBTeW1ib2woJ0FnZW50QmFzZUludGVybmFsU3RhdGUnKTsKCmNsYXNzIEFnZW50IGV4dGVuZHMgaHR0cC5BZ2VudCB7CgogIC8vIFNldCBieSBgaHR0cC5BZ2VudGAgLSBtaXNzaW5nIGZyb20gYEB0eXBlcy9ub2RlYAoKICBjb25zdHJ1Y3RvcihvcHRzKSB7CiAgICBzdXBlcihvcHRzKTsKICAgIHRoaXNbSU5URVJOQUxdID0ge307CiAgfQoKICAvKioKICAgKiBEZXRlcm1pbmUgd2hldGhlciB0aGlzIGlzIGFuIGBodHRwYCBvciBgaHR0cHNgIHJlcXVlc3QuCiAgICovCiAgaXNTZWN1cmVFbmRwb2ludChvcHRpb25zKSB7CiAgICBpZiAob3B0aW9ucykgewogICAgICAvLyBGaXJzdCBjaGVjayB0aGUgYHNlY3VyZUVuZHBvaW50YCBwcm9wZXJ0eSBleHBsaWNpdGx5LCBzaW5jZSB0aGlzCiAgICAgIC8vIG1lYW5zIHRoYXQgYSBwYXJlbnQgYEFnZW50YCBpcyAicGFzc2luZyB0aHJvdWdoIiB0byB0aGlzIGluc3RhbmNlLgogICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1tZW1iZXItYWNjZXNzCiAgICAgIGlmICh0eXBlb2YgKG9wdGlvbnMgKS5zZWN1cmVFbmRwb2ludCA9PT0gJ2Jvb2xlYW4nKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbnMuc2VjdXJlRW5kcG9pbnQ7CiAgICAgIH0KCiAgICAgIC8vIElmIG5vIGV4cGxpY2l0IGBzZWN1cmVgIGVuZHBvaW50LCBjaGVjayBpZiBgcHJvdG9jb2xgIHByb3BlcnR5IGlzCiAgICAgIC8vIHNldC4gVGhpcyB3aWxsIHVzdWFsbHkgYmUgdGhlIGNhc2Ugc2luY2UgdXNpbmcgYSBmdWxsIHN0cmluZyBVUkwKICAgICAgLy8gb3IgYFVSTGAgaW5zdGFuY2Ugc2hvdWxkIGJlIHRoZSBtb3N0IGNvbW1vbiB1c2FnZS4KICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLnByb3RvY29sID09PSAnc3RyaW5nJykgewogICAgICAgIHJldHVybiBvcHRpb25zLnByb3RvY29sID09PSAnaHR0cHM6JzsKICAgICAgfQogICAgfQoKICAgIC8vIEZpbmFsbHksIGlmIG5vIGBwcm90b2NvbGAgcHJvcGVydHkgd2FzIHNldCwgdGhlbiBmYWxsIGJhY2sgdG8KICAgIC8vIGNoZWNraW5nIHRoZSBzdGFjayB0cmFjZSBvZiB0aGUgY3VycmVudCBjYWxsIHN0YWNrLCBhbmQgdHJ5IHRvCiAgICAvLyBkZXRlY3QgdGhlICJodHRwcyIgbW9kdWxlLgogICAgY29uc3QgeyBzdGFjayB9ID0gbmV3IEVycm9yKCk7CiAgICBpZiAodHlwZW9mIHN0YWNrICE9PSAnc3RyaW5nJykgcmV0dXJuIGZhbHNlOwogICAgcmV0dXJuIHN0YWNrLnNwbGl0KCdcbicpLnNvbWUobCA9PiBsLmluZGV4T2YoJyhodHRwcy5qczonKSAhPT0gLTEgfHwgbC5pbmRleE9mKCdub2RlOmh0dHBzOicpICE9PSAtMSk7CiAgfQoKICBjcmVhdGVTb2NrZXQocmVxLCBvcHRpb25zLCBjYikgewogICAgY29uc3QgY29ubmVjdE9wdHMgPSB7CiAgICAgIC4uLm9wdGlvbnMsCiAgICAgIHNlY3VyZUVuZHBvaW50OiB0aGlzLmlzU2VjdXJlRW5kcG9pbnQob3B0aW9ucyksCiAgICB9OwogICAgUHJvbWlzZS5yZXNvbHZlKCkKICAgICAgLnRoZW4oKCkgPT4gdGhpcy5jb25uZWN0KHJlcSwgY29ubmVjdE9wdHMpKQogICAgICAudGhlbihzb2NrZXQgPT4gewogICAgICAgIGlmIChzb2NrZXQgaW5zdGFuY2VvZiBodHRwLkFnZW50KSB7CiAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGBhZGRSZXF1ZXN0KClgIGlzbid0IGRlZmluZWQgaW4gYEB0eXBlcy9ub2RlYAogICAgICAgICAgcmV0dXJuIHNvY2tldC5hZGRSZXF1ZXN0KHJlcSwgY29ubmVjdE9wdHMpOwogICAgICAgIH0KICAgICAgICB0aGlzW0lOVEVSTkFMXS5jdXJyZW50U29ja2V0ID0gc29ja2V0OwogICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgYGNyZWF0ZVNvY2tldCgpYCBpc24ndCBkZWZpbmVkIGluIGBAdHlwZXMvbm9kZWAKICAgICAgICBzdXBlci5jcmVhdGVTb2NrZXQocmVxLCBvcHRpb25zLCBjYik7CiAgICAgIH0sIGNiKTsKICB9CgogIGNyZWF0ZUNvbm5lY3Rpb24oKSB7CiAgICBjb25zdCBzb2NrZXQgPSB0aGlzW0lOVEVSTkFMXS5jdXJyZW50U29ja2V0OwogICAgdGhpc1tJTlRFUk5BTF0uY3VycmVudFNvY2tldCA9IHVuZGVmaW5lZDsKICAgIGlmICghc29ja2V0KSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gc29ja2V0IHdhcyByZXR1cm5lZCBpbiB0aGUgYGNvbm5lY3QoKWAgZnVuY3Rpb24nKTsKICAgIH0KICAgIHJldHVybiBzb2NrZXQ7CiAgfQoKICBnZXQgZGVmYXVsdFBvcnQoKSB7CiAgICByZXR1cm4gX251bGxpc2hDb2FsZXNjZSQyKHRoaXNbSU5URVJOQUxdLmRlZmF1bHRQb3J0LCAoKSA9PiAoICh0aGlzLnByb3RvY29sID09PSAnaHR0cHM6JyA/IDQ0MyA6IDgwKSkpOwogIH0KCiAgc2V0IGRlZmF1bHRQb3J0KHYpIHsKICAgIGlmICh0aGlzW0lOVEVSTkFMXSkgewogICAgICB0aGlzW0lOVEVSTkFMXS5kZWZhdWx0UG9ydCA9IHY7CiAgICB9CiAgfQoKICBnZXQgcHJvdG9jb2woKSB7CiAgICByZXR1cm4gX251bGxpc2hDb2FsZXNjZSQyKHRoaXNbSU5URVJOQUxdLnByb3RvY29sLCAoKSA9PiAoICh0aGlzLmlzU2VjdXJlRW5kcG9pbnQoKSA/ICdodHRwczonIDogJ2h0dHA6JykpKTsKICB9CgogIHNldCBwcm90b2NvbCh2KSB7CiAgICBpZiAodGhpc1tJTlRFUk5BTF0pIHsKICAgICAgdGhpc1tJTlRFUk5BTF0ucHJvdG9jb2wgPSB2OwogICAgfQogIH0KfQoKZnVuY3Rpb24gZGVidWckMSguLi5hcmdzKSB7CiAgbG9nZ2VyLmxvZygnW2h0dHBzLXByb3h5LWFnZW50OnBhcnNlLXByb3h5LXJlc3BvbnNlXScsIC4uLmFyZ3MpOwp9CgpmdW5jdGlvbiBwYXJzZVByb3h5UmVzcG9uc2Uoc29ja2V0KSB7CiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHsKICAgIC8vIHdlIG5lZWQgdG8gYnVmZmVyIGFueSBIVFRQIHRyYWZmaWMgdGhhdCBoYXBwZW5zIHdpdGggdGhlIHByb3h5IGJlZm9yZSB3ZSBnZXQKICAgIC8vIHRoZSBDT05ORUNUIHJlc3BvbnNlLCBzbyB0aGF0IGlmIHRoZSByZXNwb25zZSBpcyBhbnl0aGluZyBvdGhlciB0aGFuIGFuICIyMDAiCiAgICAvLyByZXNwb25zZSBjb2RlLCB0aGVuIHdlIGNhbiByZS1wbGF5IHRoZSAiZGF0YSIgZXZlbnRzIG9uIHRoZSBzb2NrZXQgb25jZSB0aGUKICAgIC8vIEhUVFAgcGFyc2VyIGlzIGhvb2tlZCB1cC4uLgogICAgbGV0IGJ1ZmZlcnNMZW5ndGggPSAwOwogICAgY29uc3QgYnVmZmVycyA9IFtdOwoKICAgIGZ1bmN0aW9uIHJlYWQoKSB7CiAgICAgIGNvbnN0IGIgPSBzb2NrZXQucmVhZCgpOwogICAgICBpZiAoYikgb25kYXRhKGIpOwogICAgICBlbHNlIHNvY2tldC5vbmNlKCdyZWFkYWJsZScsIHJlYWQpOwogICAgfQoKICAgIGZ1bmN0aW9uIGNsZWFudXAoKSB7CiAgICAgIHNvY2tldC5yZW1vdmVMaXN0ZW5lcignZW5kJywgb25lbmQpOwogICAgICBzb2NrZXQucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7CiAgICAgIHNvY2tldC5yZW1vdmVMaXN0ZW5lcigncmVhZGFibGUnLCByZWFkKTsKICAgIH0KCiAgICBmdW5jdGlvbiBvbmVuZCgpIHsKICAgICAgY2xlYW51cCgpOwogICAgICBkZWJ1ZyQxKCdvbmVuZCcpOwogICAgICByZWplY3QobmV3IEVycm9yKCdQcm94eSBjb25uZWN0aW9uIGVuZGVkIGJlZm9yZSByZWNlaXZpbmcgQ09OTkVDVCByZXNwb25zZScpKTsKICAgIH0KCiAgICBmdW5jdGlvbiBvbmVycm9yKGVycikgewogICAgICBjbGVhbnVwKCk7CiAgICAgIGRlYnVnJDEoJ29uZXJyb3IgJW8nLCBlcnIpOwogICAgICByZWplY3QoZXJyKTsKICAgIH0KCiAgICBmdW5jdGlvbiBvbmRhdGEoYikgewogICAgICBidWZmZXJzLnB1c2goYik7CiAgICAgIGJ1ZmZlcnNMZW5ndGggKz0gYi5sZW5ndGg7CgogICAgICBjb25zdCBidWZmZXJlZCA9IEJ1ZmZlci5jb25jYXQoYnVmZmVycywgYnVmZmVyc0xlbmd0aCk7CiAgICAgIGNvbnN0IGVuZE9mSGVhZGVycyA9IGJ1ZmZlcmVkLmluZGV4T2YoJ1xyXG5cclxuJyk7CgogICAgICBpZiAoZW5kT2ZIZWFkZXJzID09PSAtMSkgewogICAgICAgIC8vIGtlZXAgYnVmZmVyaW5nCiAgICAgICAgZGVidWckMSgnaGF2ZSBub3QgcmVjZWl2ZWQgZW5kIG9mIEhUVFAgaGVhZGVycyB5ZXQuLi4nKTsKICAgICAgICByZWFkKCk7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogICAgICBjb25zdCBoZWFkZXJQYXJ0cyA9IGJ1ZmZlcmVkLnNsaWNlKDAsIGVuZE9mSGVhZGVycykudG9TdHJpbmcoJ2FzY2lpJykuc3BsaXQoJ1xyXG4nKTsKICAgICAgY29uc3QgZmlyc3RMaW5lID0gaGVhZGVyUGFydHMuc2hpZnQoKTsKICAgICAgaWYgKCFmaXJzdExpbmUpIHsKICAgICAgICBzb2NrZXQuZGVzdHJveSgpOwogICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKCdObyBoZWFkZXIgcmVjZWl2ZWQgZnJvbSBwcm94eSBDT05ORUNUIHJlc3BvbnNlJykpOwogICAgICB9CiAgICAgIGNvbnN0IGZpcnN0TGluZVBhcnRzID0gZmlyc3RMaW5lLnNwbGl0KCcgJyk7CiAgICAgIGNvbnN0IHN0YXR1c0NvZGUgPSArZmlyc3RMaW5lUGFydHNbMV07CiAgICAgIGNvbnN0IHN0YXR1c1RleHQgPSBmaXJzdExpbmVQYXJ0cy5zbGljZSgyKS5qb2luKCcgJyk7CiAgICAgIGNvbnN0IGhlYWRlcnMgPSB7fTsKICAgICAgZm9yIChjb25zdCBoZWFkZXIgb2YgaGVhZGVyUGFydHMpIHsKICAgICAgICBpZiAoIWhlYWRlcikgY29udGludWU7CiAgICAgICAgY29uc3QgZmlyc3RDb2xvbiA9IGhlYWRlci5pbmRleE9mKCc6Jyk7CiAgICAgICAgaWYgKGZpcnN0Q29sb24gPT09IC0xKSB7CiAgICAgICAgICBzb2NrZXQuZGVzdHJveSgpOwogICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoYEludmFsaWQgaGVhZGVyIGZyb20gcHJveHkgQ09OTkVDVCByZXNwb25zZTogIiR7aGVhZGVyfSJgKSk7CiAgICAgICAgfQogICAgICAgIGNvbnN0IGtleSA9IGhlYWRlci5zbGljZSgwLCBmaXJzdENvbG9uKS50b0xvd2VyQ2FzZSgpOwogICAgICAgIGNvbnN0IHZhbHVlID0gaGVhZGVyLnNsaWNlKGZpcnN0Q29sb24gKyAxKS50cmltU3RhcnQoKTsKICAgICAgICBjb25zdCBjdXJyZW50ID0gaGVhZGVyc1trZXldOwogICAgICAgIGlmICh0eXBlb2YgY3VycmVudCA9PT0gJ3N0cmluZycpIHsKICAgICAgICAgIGhlYWRlcnNba2V5XSA9IFtjdXJyZW50LCB2YWx1ZV07CiAgICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KGN1cnJlbnQpKSB7CiAgICAgICAgICBjdXJyZW50LnB1c2godmFsdWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBoZWFkZXJzW2tleV0gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgZGVidWckMSgnZ290IHByb3h5IHNlcnZlciByZXNwb25zZTogJW8gJW8nLCBmaXJzdExpbmUsIGhlYWRlcnMpOwogICAgICBjbGVhbnVwKCk7CiAgICAgIHJlc29sdmUoewogICAgICAgIGNvbm5lY3Q6IHsKICAgICAgICAgIHN0YXR1c0NvZGUsCiAgICAgICAgICBzdGF0dXNUZXh0LAogICAgICAgICAgaGVhZGVycywKICAgICAgICB9LAogICAgICAgIGJ1ZmZlcmVkLAogICAgICB9KTsKICAgIH0KCiAgICBzb2NrZXQub24oJ2Vycm9yJywgb25lcnJvcik7CiAgICBzb2NrZXQub24oJ2VuZCcsIG9uZW5kKTsKCiAgICByZWFkKCk7CiAgfSk7Cn0KCmZ1bmN0aW9uIF9udWxsaXNoQ29hbGVzY2UkMShsaHMsIHJoc0ZuKSB7IGlmIChsaHMgIT0gbnVsbCkgeyByZXR1cm4gbGhzOyB9IGVsc2UgeyByZXR1cm4gcmhzRm4oKTsgfSB9IGZ1bmN0aW9uIF9vcHRpb25hbENoYWluJDEob3BzKSB7IGxldCBsYXN0QWNjZXNzTEhTID0gdW5kZWZpbmVkOyBsZXQgdmFsdWUgPSBvcHNbMF07IGxldCBpID0gMTsgd2hpbGUgKGkgPCBvcHMubGVuZ3RoKSB7IGNvbnN0IG9wID0gb3BzW2ldOyBjb25zdCBmbiA9IG9wc1tpICsgMV07IGkgKz0gMjsgaWYgKChvcCA9PT0gJ29wdGlvbmFsQWNjZXNzJyB8fCBvcCA9PT0gJ29wdGlvbmFsQ2FsbCcpICYmIHZhbHVlID09IG51bGwpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSBpZiAob3AgPT09ICdhY2Nlc3MnIHx8IG9wID09PSAnb3B0aW9uYWxBY2Nlc3MnKSB7IGxhc3RBY2Nlc3NMSFMgPSB2YWx1ZTsgdmFsdWUgPSBmbih2YWx1ZSk7IH0gZWxzZSBpZiAob3AgPT09ICdjYWxsJyB8fCBvcCA9PT0gJ29wdGlvbmFsQ2FsbCcpIHsgdmFsdWUgPSBmbigoLi4uYXJncykgPT4gdmFsdWUuY2FsbChsYXN0QWNjZXNzTEhTLCAuLi5hcmdzKSk7IGxhc3RBY2Nlc3NMSFMgPSB1bmRlZmluZWQ7IH0gfSByZXR1cm4gdmFsdWU7IH0vKioKICogVGhpcyBjb2RlIHdhcyBvcmlnaW5hbGx5IGZvcmtlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9Ub29UYWxsTmF0ZS9wcm94eS1hZ2VudHMvdHJlZS9iMTMzMjk1ZmQxNmY2NDc1NTc4YjZiMTViZDliNGUzM2VjYjBkMGI3CiAqIFdpdGggdGhlIGZvbGxvd2luZyBsaWNlbmNlOgogKgogKiAoVGhlIE1JVCBMaWNlbnNlKQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTMgTmF0aGFuIFJhamxpY2ggPG5hdGhhbkB0b290YWxsbmF0ZS5uZXQ+KgogKgogKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcKICogYSBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlCiAqICdTb2Z0d2FyZScpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcKICogd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLAogKiBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8KICogcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvCiAqIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoqCiAqCiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlCiAqIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLioKICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICdBUyBJUycsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsCiAqIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRgogKiBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuCiAqIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZCiAqIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsCiAqIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFCiAqIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLgogKi8KCmZ1bmN0aW9uIGRlYnVnKC4uLmFyZ3MpIHsKICBsb2dnZXIubG9nKCdbaHR0cHMtcHJveHktYWdlbnRdJywgLi4uYXJncyk7Cn0KCi8qKgogKiBUaGUgYEh0dHBzUHJveHlBZ2VudGAgaW1wbGVtZW50cyBhbiBIVFRQIEFnZW50IHN1YmNsYXNzIHRoYXQgY29ubmVjdHMgdG8KICogdGhlIHNwZWNpZmllZCAiSFRUUChzKSBwcm94eSBzZXJ2ZXIiIGluIG9yZGVyIHRvIHByb3h5IEhUVFBTIHJlcXVlc3RzLgogKgogKiBPdXRnb2luZyBIVFRQIHJlcXVlc3RzIGFyZSBmaXJzdCB0dW5uZWxlZCB0aHJvdWdoIHRoZSBwcm94eSBzZXJ2ZXIgdXNpbmcgdGhlCiAqIGBDT05ORUNUYCBIVFRQIHJlcXVlc3QgbWV0aG9kIHRvIGVzdGFibGlzaCBhIGNvbm5lY3Rpb24gdG8gdGhlIHByb3h5IHNlcnZlciwKICogYW5kIHRoZW4gdGhlIHByb3h5IHNlcnZlciBjb25uZWN0cyB0byB0aGUgZGVzdGluYXRpb24gdGFyZ2V0IGFuZCBpc3N1ZXMgdGhlCiAqIEhUVFAgcmVxdWVzdCBmcm9tIHRoZSBwcm94eSBzZXJ2ZXIuCiAqCiAqIGBodHRwczpgIHJlcXVlc3RzIGhhdmUgdGhlaXIgc29ja2V0IGNvbm5lY3Rpb24gdXBncmFkZWQgdG8gVExTIG9uY2UKICogdGhlIGNvbm5lY3Rpb24gdG8gdGhlIHByb3h5IHNlcnZlciBoYXMgYmVlbiBlc3RhYmxpc2hlZC4KICovCmNsYXNzIEh0dHBzUHJveHlBZ2VudCBleHRlbmRzIEFnZW50IHsKICBzdGF0aWMgX19pbml0U3RhdGljKCkge3RoaXMucHJvdG9jb2xzID0gWydodHRwJywgJ2h0dHBzJ107IH0KCiAgY29uc3RydWN0b3IocHJveHksIG9wdHMpIHsKICAgIHN1cGVyKG9wdHMpOwogICAgdGhpcy5vcHRpb25zID0ge307CiAgICB0aGlzLnByb3h5ID0gdHlwZW9mIHByb3h5ID09PSAnc3RyaW5nJyA/IG5ldyBVUkwocHJveHkpIDogcHJveHk7CiAgICB0aGlzLnByb3h5SGVhZGVycyA9IF9udWxsaXNoQ29hbGVzY2UkMShfb3B0aW9uYWxDaGFpbiQxKFtvcHRzLCAnb3B0aW9uYWxBY2Nlc3MnLCBfMiA9PiBfMi5oZWFkZXJzXSksICgpID0+ICgge30pKTsKICAgIGRlYnVnKCdDcmVhdGluZyBuZXcgSHR0cHNQcm94eUFnZW50IGluc3RhbmNlOiAlbycsIHRoaXMucHJveHkuaHJlZik7CgogICAgLy8gVHJpbSBvZmYgdGhlIGJyYWNrZXRzIGZyb20gSVB2NiBhZGRyZXNzZXMKICAgIGNvbnN0IGhvc3QgPSAodGhpcy5wcm94eS5ob3N0bmFtZSB8fCB0aGlzLnByb3h5Lmhvc3QpLnJlcGxhY2UoL15cW3xcXSQvZywgJycpOwogICAgY29uc3QgcG9ydCA9IHRoaXMucHJveHkucG9ydCA/IHBhcnNlSW50KHRoaXMucHJveHkucG9ydCwgMTApIDogdGhpcy5wcm94eS5wcm90b2NvbCA9PT0gJ2h0dHBzOicgPyA0NDMgOiA4MDsKICAgIHRoaXMuY29ubmVjdE9wdHMgPSB7CiAgICAgIC8vIEF0dGVtcHQgdG8gbmVnb3RpYXRlIGh0dHAvMS4xIGZvciBwcm94eSBzZXJ2ZXJzIHRoYXQgc3VwcG9ydCBodHRwLzIKICAgICAgQUxQTlByb3RvY29sczogWydodHRwLzEuMSddLAogICAgICAuLi4ob3B0cyA/IG9taXQob3B0cywgJ2hlYWRlcnMnKSA6IG51bGwpLAogICAgICBob3N0LAogICAgICBwb3J0LAogICAgfTsKICB9CgogIC8qKgogICAqIENhbGxlZCB3aGVuIHRoZSBub2RlLWNvcmUgSFRUUCBjbGllbnQgbGlicmFyeSBpcyBjcmVhdGluZyBhCiAgICogbmV3IEhUVFAgcmVxdWVzdC4KICAgKi8KICBhc3luYyBjb25uZWN0KHJlcSwgb3B0cykgewogICAgY29uc3QgeyBwcm94eSB9ID0gdGhpczsKCiAgICBpZiAoIW9wdHMuaG9zdCkgewogICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdObyAiaG9zdCIgcHJvdmlkZWQnKTsKICAgIH0KCiAgICAvLyBDcmVhdGUgYSBzb2NrZXQgY29ubmVjdGlvbiB0byB0aGUgcHJveHkgc2VydmVyLgogICAgbGV0IHNvY2tldDsKICAgIGlmIChwcm94eS5wcm90b2NvbCA9PT0gJ2h0dHBzOicpIHsKICAgICAgZGVidWcoJ0NyZWF0aW5nIGB0bHMuU29ja2V0YDogJW8nLCB0aGlzLmNvbm5lY3RPcHRzKTsKICAgICAgY29uc3Qgc2VydmVybmFtZSA9IHRoaXMuY29ubmVjdE9wdHMuc2VydmVybmFtZSB8fCB0aGlzLmNvbm5lY3RPcHRzLmhvc3Q7CiAgICAgIHNvY2tldCA9IHRscy5jb25uZWN0KHsKICAgICAgICAuLi50aGlzLmNvbm5lY3RPcHRzLAogICAgICAgIHNlcnZlcm5hbWU6IHNlcnZlcm5hbWUgJiYgbmV0LmlzSVAoc2VydmVybmFtZSkgPyB1bmRlZmluZWQgOiBzZXJ2ZXJuYW1lLAogICAgICB9KTsKICAgIH0gZWxzZSB7CiAgICAgIGRlYnVnKCdDcmVhdGluZyBgbmV0LlNvY2tldGA6ICVvJywgdGhpcy5jb25uZWN0T3B0cyk7CiAgICAgIHNvY2tldCA9IG5ldC5jb25uZWN0KHRoaXMuY29ubmVjdE9wdHMpOwogICAgfQoKICAgIGNvbnN0IGhlYWRlcnMgPQogICAgICB0eXBlb2YgdGhpcy5wcm94eUhlYWRlcnMgPT09ICdmdW5jdGlvbicgPyB0aGlzLnByb3h5SGVhZGVycygpIDogeyAuLi50aGlzLnByb3h5SGVhZGVycyB9OwogICAgY29uc3QgaG9zdCA9IG5ldC5pc0lQdjYob3B0cy5ob3N0KSA/IGBbJHtvcHRzLmhvc3R9XWAgOiBvcHRzLmhvc3Q7CiAgICBsZXQgcGF5bG9hZCA9IGBDT05ORUNUICR7aG9zdH06JHtvcHRzLnBvcnR9IEhUVFAvMS4xXHJcbmA7CgogICAgLy8gSW5qZWN0IHRoZSBgUHJveHktQXV0aG9yaXphdGlvbmAgaGVhZGVyIGlmIG5lY2Vzc2FyeS4KICAgIGlmIChwcm94eS51c2VybmFtZSB8fCBwcm94eS5wYXNzd29yZCkgewogICAgICBjb25zdCBhdXRoID0gYCR7ZGVjb2RlVVJJQ29tcG9uZW50KHByb3h5LnVzZXJuYW1lKX06JHtkZWNvZGVVUklDb21wb25lbnQocHJveHkucGFzc3dvcmQpfWA7CiAgICAgIGhlYWRlcnNbJ1Byb3h5LUF1dGhvcml6YXRpb24nXSA9IGBCYXNpYyAke0J1ZmZlci5mcm9tKGF1dGgpLnRvU3RyaW5nKCdiYXNlNjQnKX1gOwogICAgfQoKICAgIGhlYWRlcnMuSG9zdCA9IGAke2hvc3R9OiR7b3B0cy5wb3J0fWA7CgogICAgaWYgKCFoZWFkZXJzWydQcm94eS1Db25uZWN0aW9uJ10pIHsKICAgICAgaGVhZGVyc1snUHJveHktQ29ubmVjdGlvbiddID0gdGhpcy5rZWVwQWxpdmUgPyAnS2VlcC1BbGl2ZScgOiAnY2xvc2UnOwogICAgfQogICAgZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKGhlYWRlcnMpKSB7CiAgICAgIHBheWxvYWQgKz0gYCR7bmFtZX06ICR7aGVhZGVyc1tuYW1lXX1cclxuYDsKICAgIH0KCiAgICBjb25zdCBwcm94eVJlc3BvbnNlUHJvbWlzZSA9IHBhcnNlUHJveHlSZXNwb25zZShzb2NrZXQpOwoKICAgIHNvY2tldC53cml0ZShgJHtwYXlsb2FkfVxyXG5gKTsKCiAgICBjb25zdCB7IGNvbm5lY3QsIGJ1ZmZlcmVkIH0gPSBhd2FpdCBwcm94eVJlc3BvbnNlUHJvbWlzZTsKICAgIHJlcS5lbWl0KCdwcm94eUNvbm5lY3QnLCBjb25uZWN0KTsKICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvYmFuLXRzLWNvbW1lbnQKICAgIC8vIEB0cy1pZ25vcmUgTm90IEV2ZW50RW1pdHRlciBpbiBOb2RlIHR5cGVzCiAgICB0aGlzLmVtaXQoJ3Byb3h5Q29ubmVjdCcsIGNvbm5lY3QsIHJlcSk7CgogICAgaWYgKGNvbm5lY3Quc3RhdHVzQ29kZSA9PT0gMjAwKSB7CiAgICAgIHJlcS5vbmNlKCdzb2NrZXQnLCByZXN1bWUpOwoKICAgICAgaWYgKG9wdHMuc2VjdXJlRW5kcG9pbnQpIHsKICAgICAgICAvLyBUaGUgcHJveHkgaXMgY29ubmVjdGluZyB0byBhIFRMUyBzZXJ2ZXIsIHNvIHVwZ3JhZGUKICAgICAgICAvLyB0aGlzIHNvY2tldCBjb25uZWN0aW9uIHRvIGEgVExTIGNvbm5lY3Rpb24uCiAgICAgICAgZGVidWcoJ1VwZ3JhZGluZyBzb2NrZXQgY29ubmVjdGlvbiB0byBUTFMnKTsKICAgICAgICBjb25zdCBzZXJ2ZXJuYW1lID0gb3B0cy5zZXJ2ZXJuYW1lIHx8IG9wdHMuaG9zdDsKICAgICAgICByZXR1cm4gdGxzLmNvbm5lY3QoewogICAgICAgICAgLi4ub21pdChvcHRzLCAnaG9zdCcsICdwYXRoJywgJ3BvcnQnKSwKICAgICAgICAgIHNvY2tldCwKICAgICAgICAgIHNlcnZlcm5hbWU6IG5ldC5pc0lQKHNlcnZlcm5hbWUpID8gdW5kZWZpbmVkIDogc2VydmVybmFtZSwKICAgICAgICB9KTsKICAgICAgfQoKICAgICAgcmV0dXJuIHNvY2tldDsKICAgIH0KCiAgICAvLyBTb21lIG90aGVyIHN0YXR1cyBjb2RlIHRoYXQncyBub3QgMjAwLi4uIG5lZWQgdG8gcmUtcGxheSB0aGUgSFRUUAogICAgLy8gaGVhZGVyICJkYXRhIiBldmVudHMgb250byB0aGUgc29ja2V0IG9uY2UgdGhlIEhUVFAgbWFjaGluZXJ5IGlzCiAgICAvLyBhdHRhY2hlZCBzbyB0aGF0IHRoZSBub2RlIGNvcmUgYGh0dHBgIGNhbiBwYXJzZSBhbmQgaGFuZGxlIHRoZQogICAgLy8gZXJyb3Igc3RhdHVzIGNvZGUuCgogICAgLy8gQ2xvc2UgdGhlIG9yaWdpbmFsIHNvY2tldCwgYW5kIGEgbmV3ICJmYWtlIiBzb2NrZXQgaXMgcmV0dXJuZWQKICAgIC8vIGluc3RlYWQsIHNvIHRoYXQgdGhlIHByb3h5IGRvZXNuJ3QgZ2V0IHRoZSBIVFRQIHJlcXVlc3QKICAgIC8vIHdyaXR0ZW4gdG8gaXQgKHdoaWNoIG1heSBjb250YWluIGBBdXRob3JpemF0aW9uYCBoZWFkZXJzIG9yIG90aGVyCiAgICAvLyBzZW5zaXRpdmUgZGF0YSkuCiAgICAvLwogICAgLy8gU2VlOiBodHRwczovL2hhY2tlcm9uZS5jb20vcmVwb3J0cy81NDE1MDIKICAgIHNvY2tldC5kZXN0cm95KCk7CgogICAgY29uc3QgZmFrZVNvY2tldCA9IG5ldyBuZXQuU29ja2V0KHsgd3JpdGFibGU6IGZhbHNlIH0pOwogICAgZmFrZVNvY2tldC5yZWFkYWJsZSA9IHRydWU7CgogICAgLy8gTmVlZCB0byB3YWl0IGZvciB0aGUgInNvY2tldCIgZXZlbnQgdG8gcmUtcGxheSB0aGUgImRhdGEiIGV2ZW50cy4KICAgIHJlcS5vbmNlKCdzb2NrZXQnLCAocykgPT4gewogICAgICBkZWJ1ZygnUmVwbGF5aW5nIHByb3h5IGJ1ZmZlciBmb3IgZmFpbGVkIHJlcXVlc3QnKTsKICAgICAgYXNzZXJ0KHMubGlzdGVuZXJDb3VudCgnZGF0YScpID4gMCk7CgogICAgICAvLyBSZXBsYXkgdGhlICJidWZmZXJlZCIgQnVmZmVyIG9udG8gdGhlIGZha2UgYHNvY2tldGAsIHNpbmNlIGF0CiAgICAgIC8vIHRoaXMgcG9pbnQgdGhlIEhUVFAgbW9kdWxlIG1hY2hpbmVyeSBoYXMgYmVlbiBob29rZWQgdXAgZm9yCiAgICAgIC8vIHRoZSB1c2VyLgogICAgICBzLnB1c2goYnVmZmVyZWQpOwogICAgICBzLnB1c2gobnVsbCk7CiAgICB9KTsKCiAgICByZXR1cm4gZmFrZVNvY2tldDsKICB9Cn0gSHR0cHNQcm94eUFnZW50Ll9faW5pdFN0YXRpYygpOwoKZnVuY3Rpb24gcmVzdW1lKHNvY2tldCkgewogIHNvY2tldC5yZXN1bWUoKTsKfQoKZnVuY3Rpb24gb21pdCgKICBvYmosCiAgLi4ua2V5cwopCgogewogIGNvbnN0IHJldCA9IHt9Cgo7CiAgbGV0IGtleTsKICBmb3IgKGtleSBpbiBvYmopIHsKICAgIGlmICgha2V5cy5pbmNsdWRlcyhrZXkpKSB7CiAgICAgIHJldFtrZXldID0gb2JqW2tleV07CiAgICB9CiAgfQogIHJldHVybiByZXQ7Cn0KCmZ1bmN0aW9uIF9udWxsaXNoQ29hbGVzY2UobGhzLCByaHNGbikgeyBpZiAobGhzICE9IG51bGwpIHsgcmV0dXJuIGxoczsgfSBlbHNlIHsgcmV0dXJuIHJoc0ZuKCk7IH0gfQovLyBFc3RpbWF0ZWQgbWF4aW11bSBzaXplIGZvciByZWFzb25hYmxlIHN0YW5kYWxvbmUgZXZlbnQKY29uc3QgR1pJUF9USFJFU0hPTEQgPSAxMDI0ICogMzI7CgovKioKICogR2V0cyBhIHN0cmVhbSBmcm9tIGEgVWludDhBcnJheSBvciBzdHJpbmcKICogUmVhZGFibGUuZnJvbSBpcyBpZGVhbCBidXQgd2FzIGFkZGVkIGluIG5vZGUuanMgdjEyLjMuMCBhbmQgdjEwLjE3LjAKICovCmZ1bmN0aW9uIHN0cmVhbUZyb21Cb2R5KGJvZHkpIHsKICByZXR1cm4gbmV3IFJlYWRhYmxlKHsKICAgIHJlYWQoKSB7CiAgICAgIHRoaXMucHVzaChib2R5KTsKICAgICAgdGhpcy5wdXNoKG51bGwpOwogICAgfSwKICB9KTsKfQoKLyoqCiAqIENyZWF0ZXMgYSBUcmFuc3BvcnQgdGhhdCB1c2VzIG5hdGl2ZSB0aGUgbmF0aXZlICdodHRwJyBhbmQgJ2h0dHBzJyBtb2R1bGVzIHRvIHNlbmQgZXZlbnRzIHRvIFNlbnRyeS4KICovCmZ1bmN0aW9uIG1ha2VOb2RlVHJhbnNwb3J0KG9wdGlvbnMpIHsKICBsZXQgdXJsU2VnbWVudHM7CgogIHRyeSB7CiAgICB1cmxTZWdtZW50cyA9IG5ldyBVUkwob3B0aW9ucy51cmwpOwogIH0gY2F0Y2ggKGUpIHsKICAgIGNvbnNvbGVTYW5kYm94KCgpID0+IHsKICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGUKICAgICAgY29uc29sZS53YXJuKAogICAgICAgICdbQHNlbnRyeS9ub2RlXTogSW52YWxpZCBkc24gb3IgdHVubmVsIG9wdGlvbiwgd2lsbCBub3Qgc2VuZCBhbnkgZXZlbnRzLiBUaGUgdHVubmVsIG9wdGlvbiBtdXN0IGJlIGEgZnVsbCBVUkwgd2hlbiB1c2VkLicsCiAgICAgICk7CiAgICB9KTsKICAgIHJldHVybiBjcmVhdGVUcmFuc3BvcnQob3B0aW9ucywgKCkgPT4gUHJvbWlzZS5yZXNvbHZlKHt9KSk7CiAgfQoKICBjb25zdCBpc0h0dHBzID0gdXJsU2VnbWVudHMucHJvdG9jb2wgPT09ICdodHRwczonOwoKICAvLyBQcm94eSBwcmlvcml0aXphdGlvbjogaHR0cCA9PiBgb3B0aW9ucy5wcm94eWAgfCBgcHJvY2Vzcy5lbnYuaHR0cF9wcm94eWAKICAvLyBQcm94eSBwcmlvcml0aXphdGlvbjogaHR0cHMgPT4gYG9wdGlvbnMucHJveHlgIHwgYHByb2Nlc3MuZW52Lmh0dHBzX3Byb3h5YCB8IGBwcm9jZXNzLmVudi5odHRwX3Byb3h5YAogIGNvbnN0IHByb3h5ID0gYXBwbHlOb1Byb3h5T3B0aW9uKAogICAgdXJsU2VnbWVudHMsCiAgICBvcHRpb25zLnByb3h5IHx8IChpc0h0dHBzID8gcHJvY2Vzcy5lbnYuaHR0cHNfcHJveHkgOiB1bmRlZmluZWQpIHx8IHByb2Nlc3MuZW52Lmh0dHBfcHJveHksCiAgKTsKCiAgY29uc3QgbmF0aXZlSHR0cE1vZHVsZSA9IGlzSHR0cHMgPyBodHRwcyA6IGh0dHA7CiAgY29uc3Qga2VlcEFsaXZlID0gb3B0aW9ucy5rZWVwQWxpdmUgPT09IHVuZGVmaW5lZCA/IGZhbHNlIDogb3B0aW9ucy5rZWVwQWxpdmU7CgogIC8vIFRPRE8odjcpOiBFdmFsdWF0ZSBpZiB3ZSBjYW4gc2V0IGtlZXBBbGl2ZSB0byB0cnVlLiBUaGlzIHdvdWxkIGludm9sdmUgdGVzdGluZyBmb3IgbWVtb3J5IGxlYWtzIGluIG9sZGVyIG5vZGUKICAvLyB2ZXJzaW9ucyg+PSA4KSBhcyB0aGV5IGhhZCBtZW1vcnkgbGVha3Mgd2hlbiB1c2luZyBpdDogIzI1NTUKICBjb25zdCBhZ2VudCA9IHByb3h5CiAgICA/IChuZXcgSHR0cHNQcm94eUFnZW50KHByb3h5KSApCiAgICA6IG5ldyBuYXRpdmVIdHRwTW9kdWxlLkFnZW50KHsga2VlcEFsaXZlLCBtYXhTb2NrZXRzOiAzMCwgdGltZW91dDogMjAwMCB9KTsKCiAgY29uc3QgcmVxdWVzdEV4ZWN1dG9yID0gY3JlYXRlUmVxdWVzdEV4ZWN1dG9yKG9wdGlvbnMsIF9udWxsaXNoQ29hbGVzY2Uob3B0aW9ucy5odHRwTW9kdWxlLCAoKSA9PiAoIG5hdGl2ZUh0dHBNb2R1bGUpKSwgYWdlbnQpOwogIHJldHVybiBjcmVhdGVUcmFuc3BvcnQob3B0aW9ucywgcmVxdWVzdEV4ZWN1dG9yKTsKfQoKLyoqCiAqIEhvbm9ycyB0aGUgYG5vX3Byb3h5YCBlbnYgdmFyaWFibGUgd2l0aCB0aGUgaGlnaGVzdCBwcmlvcml0eSB0byBhbGxvdyBmb3IgaG9zdHMgZXhjbHVzaW9uLgogKgogKiBAcGFyYW0gdHJhbnNwb3J0VXJsIFRoZSBVUkwgdGhlIHRyYW5zcG9ydCBpbnRlbmRzIHRvIHNlbmQgZXZlbnRzIHRvLgogKiBAcGFyYW0gcHJveHkgVGhlIGNsaWVudCBjb25maWd1cmVkIHByb3h5LgogKiBAcmV0dXJucyBBIHByb3h5IHRoZSB0cmFuc3BvcnQgc2hvdWxkIHVzZS4KICovCmZ1bmN0aW9uIGFwcGx5Tm9Qcm94eU9wdGlvbih0cmFuc3BvcnRVcmxTZWdtZW50cywgcHJveHkpIHsKICBjb25zdCB7IG5vX3Byb3h5IH0gPSBwcm9jZXNzLmVudjsKCiAgY29uc3QgdXJsSXNFeGVtcHRGcm9tUHJveHkgPQogICAgbm9fcHJveHkgJiYKICAgIG5vX3Byb3h5CiAgICAgIC5zcGxpdCgnLCcpCiAgICAgIC5zb21lKAogICAgICAgIGV4ZW1wdGlvbiA9PiB0cmFuc3BvcnRVcmxTZWdtZW50cy5ob3N0LmVuZHNXaXRoKGV4ZW1wdGlvbikgfHwgdHJhbnNwb3J0VXJsU2VnbWVudHMuaG9zdG5hbWUuZW5kc1dpdGgoZXhlbXB0aW9uKSwKICAgICAgKTsKCiAgaWYgKHVybElzRXhlbXB0RnJvbVByb3h5KSB7CiAgICByZXR1cm4gdW5kZWZpbmVkOwogIH0gZWxzZSB7CiAgICByZXR1cm4gcHJveHk7CiAgfQp9CgovKioKICogQ3JlYXRlcyBhIFJlcXVlc3RFeGVjdXRvciB0byBiZSB1c2VkIHdpdGggYGNyZWF0ZVRyYW5zcG9ydGAuCiAqLwpmdW5jdGlvbiBjcmVhdGVSZXF1ZXN0RXhlY3V0b3IoCiAgb3B0aW9ucywKICBodHRwTW9kdWxlLAogIGFnZW50LAopIHsKICBjb25zdCB7IGhvc3RuYW1lLCBwYXRobmFtZSwgcG9ydCwgcHJvdG9jb2wsIHNlYXJjaCB9ID0gbmV3IFVSTChvcHRpb25zLnVybCk7CiAgcmV0dXJuIGZ1bmN0aW9uIG1ha2VSZXF1ZXN0KHJlcXVlc3QpIHsKICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7CiAgICAgIGxldCBib2R5ID0gc3RyZWFtRnJvbUJvZHkocmVxdWVzdC5ib2R5KTsKCiAgICAgIGNvbnN0IGhlYWRlcnMgPSB7IC4uLm9wdGlvbnMuaGVhZGVycyB9OwoKICAgICAgaWYgKHJlcXVlc3QuYm9keS5sZW5ndGggPiBHWklQX1RIUkVTSE9MRCkgewogICAgICAgIGhlYWRlcnNbJ2NvbnRlbnQtZW5jb2RpbmcnXSA9ICdnemlwJzsKICAgICAgICBib2R5ID0gYm9keS5waXBlKGNyZWF0ZUd6aXAoKSk7CiAgICAgIH0KCiAgICAgIGNvbnN0IHJlcSA9IGh0dHBNb2R1bGUucmVxdWVzdCgKICAgICAgICB7CiAgICAgICAgICBtZXRob2Q6ICdQT1NUJywKICAgICAgICAgIGFnZW50LAogICAgICAgICAgaGVhZGVycywKICAgICAgICAgIGhvc3RuYW1lLAogICAgICAgICAgcGF0aDogYCR7cGF0aG5hbWV9JHtzZWFyY2h9YCwKICAgICAgICAgIHBvcnQsCiAgICAgICAgICBwcm90b2NvbCwKICAgICAgICAgIGNhOiBvcHRpb25zLmNhQ2VydHMsCiAgICAgICAgfSwKICAgICAgICByZXMgPT4gewogICAgICAgICAgcmVzLm9uKCdkYXRhJywgKCkgPT4gewogICAgICAgICAgICAvLyBEcmFpbiBzb2NrZXQKICAgICAgICAgIH0pOwoKICAgICAgICAgIHJlcy5vbignZW5kJywgKCkgPT4gewogICAgICAgICAgICAvLyBEcmFpbiBzb2NrZXQKICAgICAgICAgIH0pOwoKICAgICAgICAgIHJlcy5zZXRFbmNvZGluZygndXRmOCcpOwoKICAgICAgICAgIC8vICJLZXktdmFsdWUgcGFpcnMgb2YgaGVhZGVyIG5hbWVzIGFuZCB2YWx1ZXMuIEhlYWRlciBuYW1lcyBhcmUgbG93ZXItY2FzZWQuIgogICAgICAgICAgLy8gaHR0cHM6Ly9ub2RlanMub3JnL2FwaS9odHRwLmh0bWwjaHR0cF9tZXNzYWdlX2hlYWRlcnMKICAgICAgICAgIGNvbnN0IHJldHJ5QWZ0ZXJIZWFkZXIgPSBfbnVsbGlzaENvYWxlc2NlKHJlcy5oZWFkZXJzWydyZXRyeS1hZnRlciddLCAoKSA9PiAoIG51bGwpKTsKICAgICAgICAgIGNvbnN0IHJhdGVMaW1pdHNIZWFkZXIgPSBfbnVsbGlzaENvYWxlc2NlKHJlcy5oZWFkZXJzWyd4LXNlbnRyeS1yYXRlLWxpbWl0cyddLCAoKSA9PiAoIG51bGwpKTsKCiAgICAgICAgICByZXNvbHZlKHsKICAgICAgICAgICAgc3RhdHVzQ29kZTogcmVzLnN0YXR1c0NvZGUsCiAgICAgICAgICAgIGhlYWRlcnM6IHsKICAgICAgICAgICAgICAncmV0cnktYWZ0ZXInOiByZXRyeUFmdGVySGVhZGVyLAogICAgICAgICAgICAgICd4LXNlbnRyeS1yYXRlLWxpbWl0cyc6IEFycmF5LmlzQXJyYXkocmF0ZUxpbWl0c0hlYWRlcikgPyByYXRlTGltaXRzSGVhZGVyWzBdIDogcmF0ZUxpbWl0c0hlYWRlciwKICAgICAgICAgICAgfSwKICAgICAgICAgIH0pOwogICAgICAgIH0sCiAgICAgICk7CgogICAgICByZXEub24oJ2Vycm9yJywgcmVqZWN0KTsKICAgICAgYm9keS5waXBlKHJlcSk7CiAgICB9KTsKICB9Owp9CgpmdW5jdGlvbiBfb3B0aW9uYWxDaGFpbihvcHMpIHsgbGV0IGxhc3RBY2Nlc3NMSFMgPSB1bmRlZmluZWQ7IGxldCB2YWx1ZSA9IG9wc1swXTsgbGV0IGkgPSAxOyB3aGlsZSAoaSA8IG9wcy5sZW5ndGgpIHsgY29uc3Qgb3AgPSBvcHNbaV07IGNvbnN0IGZuID0gb3BzW2kgKyAxXTsgaSArPSAyOyBpZiAoKG9wID09PSAnb3B0aW9uYWxBY2Nlc3MnIHx8IG9wID09PSAnb3B0aW9uYWxDYWxsJykgJiYgdmFsdWUgPT0gbnVsbCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IGlmIChvcCA9PT0gJ2FjY2VzcycgfHwgb3AgPT09ICdvcHRpb25hbEFjY2VzcycpIHsgbGFzdEFjY2Vzc0xIUyA9IHZhbHVlOyB2YWx1ZSA9IGZuKHZhbHVlKTsgfSBlbHNlIGlmIChvcCA9PT0gJ2NhbGwnIHx8IG9wID09PSAnb3B0aW9uYWxDYWxsJykgeyB2YWx1ZSA9IGZuKCguLi5hcmdzKSA9PiB2YWx1ZS5jYWxsKGxhc3RBY2Nlc3NMSFMsIC4uLmFyZ3MpKTsgbGFzdEFjY2Vzc0xIUyA9IHVuZGVmaW5lZDsgfSB9IHJldHVybiB2YWx1ZTsgfQpjb25zdCBvcHRpb25zID0gd29ya2VyRGF0YTsKbGV0IHNlc3Npb247CmxldCBoYXNTZW50QW5yRXZlbnQgPSBmYWxzZTsKCmZ1bmN0aW9uIGxvZyhtc2cpIHsKICBpZiAob3B0aW9ucy5kZWJ1ZykgewogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGUKICAgIGNvbnNvbGUubG9nKGBbQU5SIFdvcmtlcl0gJHttc2d9YCk7CiAgfQp9Cgpjb25zdCB1cmwgPSBnZXRFbnZlbG9wZUVuZHBvaW50V2l0aFVybEVuY29kZWRBdXRoKG9wdGlvbnMuZHNuKTsKY29uc3QgdHJhbnNwb3J0ID0gbWFrZU5vZGVUcmFuc3BvcnQoewogIHVybCwKICByZWNvcmREcm9wcGVkRXZlbnQ6ICgpID0+IHsKICAgIC8vCiAgfSwKfSk7Cgphc3luYyBmdW5jdGlvbiBzZW5kQWJub3JtYWxTZXNzaW9uKCkgewogIC8vIG9mIHdlIGhhdmUgYW4gZXhpc3Rpbmcgc2Vzc2lvbiBwYXNzZWQgZnJvbSB0aGUgbWFpbiB0aHJlYWQsIHNlbmQgaXQgYXMgYWJub3JtYWwKICBpZiAoc2Vzc2lvbikgewogICAgbG9nKCdTZW5kaW5nIGFibm9ybWFsIHNlc3Npb24nKTsKICAgIHVwZGF0ZVNlc3Npb24oc2Vzc2lvbiwgeyBzdGF0dXM6ICdhYm5vcm1hbCcsIGFibm9ybWFsX21lY2hhbmlzbTogJ2Fucl9mb3JlZ3JvdW5kJyB9KTsKCiAgICBjb25zdCBlbnZlbG9wZSA9IGNyZWF0ZVNlc3Npb25FbnZlbG9wZShzZXNzaW9uLCBvcHRpb25zLmRzbiwgb3B0aW9ucy5zZGtNZXRhZGF0YSk7CiAgICAvLyBMb2cgdGhlIGVudmVsb3BlIHNvIHRvIGFpZCBpbiB0ZXN0aW5nCiAgICBsb2coSlNPTi5zdHJpbmdpZnkoZW52ZWxvcGUpKTsKCiAgICBhd2FpdCB0cmFuc3BvcnQuc2VuZChlbnZlbG9wZSk7CgogICAgdHJ5IHsKICAgICAgLy8gTm90aWZ5IHRoZSBtYWluIHByb2Nlc3MgdGhhdCB0aGUgc2Vzc2lvbiBoYXMgZW5kZWQgc28gdGhlIHNlc3Npb24gY2FuIGJlIGNsZWFyZWQgZnJvbSB0aGUgc2NvcGUKICAgICAgX29wdGlvbmFsQ2hhaW4oW3BhcmVudFBvcnQsICdvcHRpb25hbEFjY2VzcycsIF8yID0+IF8yLnBvc3RNZXNzYWdlLCAnY2FsbCcsIF8zID0+IF8zKCdzZXNzaW9uLWVuZGVkJyldKTsKICAgIH0gY2F0Y2ggKF8pIHsKICAgICAgLy8gaWdub3JlCiAgICB9CiAgfQp9Cgpsb2coJ1N0YXJ0ZWQnKTsKCmZ1bmN0aW9uIHByZXBhcmVTdGFja0ZyYW1lcyhzdGFja0ZyYW1lcykgewogIGlmICghc3RhY2tGcmFtZXMpIHsKICAgIHJldHVybiB1bmRlZmluZWQ7CiAgfQoKICAvLyBTdHJpcCBTZW50cnkgZnJhbWVzIGFuZCByZXZlcnNlIHRoZSBzdGFjayBmcmFtZXMgc28gdGhleSBhcmUgaW4gdGhlIGNvcnJlY3Qgb3JkZXIKICBjb25zdCBzdHJpcHBlZEZyYW1lcyA9IHN0cmlwU2VudHJ5RnJhbWVzQW5kUmV2ZXJzZShzdGFja0ZyYW1lcyk7CgogIC8vIElmIHdlIGhhdmUgYW4gYXBwIHJvb3QgcGF0aCwgcmV3cml0ZSB0aGUgZmlsZW5hbWVzIHRvIGJlIHJlbGF0aXZlIHRvIHRoZSBhcHAgcm9vdAogIGlmIChvcHRpb25zLmFwcFJvb3RQYXRoKSB7CiAgICBmb3IgKGNvbnN0IGZyYW1lIG9mIHN0cmlwcGVkRnJhbWVzKSB7CiAgICAgIGlmICghZnJhbWUuZmlsZW5hbWUpIHsKICAgICAgICBjb250aW51ZTsKICAgICAgfQoKICAgICAgZnJhbWUuZmlsZW5hbWUgPSBub3JtYWxpemVVcmxUb0Jhc2UoZnJhbWUuZmlsZW5hbWUsIG9wdGlvbnMuYXBwUm9vdFBhdGgpOwogICAgfQogIH0KCiAgcmV0dXJuIHN0cmlwcGVkRnJhbWVzOwp9Cgphc3luYyBmdW5jdGlvbiBzZW5kQW5yRXZlbnQoZnJhbWVzLCB0cmFjZUNvbnRleHQpIHsKICBpZiAoaGFzU2VudEFuckV2ZW50KSB7CiAgICByZXR1cm47CiAgfQoKICBoYXNTZW50QW5yRXZlbnQgPSB0cnVlOwoKICBhd2FpdCBzZW5kQWJub3JtYWxTZXNzaW9uKCk7CgogIGxvZygnU2VuZGluZyBldmVudCcpOwoKICBjb25zdCBldmVudCA9IHsKICAgIGV2ZW50X2lkOiB1dWlkNCgpLAogICAgY29udGV4dHM6IHsgLi4ub3B0aW9ucy5jb250ZXh0cywgdHJhY2U6IHRyYWNlQ29udGV4dCB9LAogICAgcmVsZWFzZTogb3B0aW9ucy5yZWxlYXNlLAogICAgZW52aXJvbm1lbnQ6IG9wdGlvbnMuZW52aXJvbm1lbnQsCiAgICBkaXN0OiBvcHRpb25zLmRpc3QsCiAgICBwbGF0Zm9ybTogJ25vZGUnLAogICAgbGV2ZWw6ICdlcnJvcicsCiAgICBleGNlcHRpb246IHsKICAgICAgdmFsdWVzOiBbCiAgICAgICAgewogICAgICAgICAgdHlwZTogJ0FwcGxpY2F0aW9uTm90UmVzcG9uZGluZycsCiAgICAgICAgICB2YWx1ZTogYEFwcGxpY2F0aW9uIE5vdCBSZXNwb25kaW5nIGZvciBhdCBsZWFzdCAke29wdGlvbnMuYW5yVGhyZXNob2xkfSBtc2AsCiAgICAgICAgICBzdGFja3RyYWNlOiB7IGZyYW1lczogcHJlcGFyZVN0YWNrRnJhbWVzKGZyYW1lcykgfSwKICAgICAgICAgIC8vIFRoaXMgZW5zdXJlcyB0aGUgVUkgZG9lc24ndCBzYXkgJ0NyYXNoZWQgaW4nIGZvciB0aGUgc3RhY2sgdHJhY2UKICAgICAgICAgIG1lY2hhbmlzbTogeyB0eXBlOiAnQU5SJyB9LAogICAgICAgIH0sCiAgICAgIF0sCiAgICB9LAogICAgdGFnczogb3B0aW9ucy5zdGF0aWNUYWdzLAogIH07CgogIGNvbnN0IGVudmVsb3BlID0gY3JlYXRlRXZlbnRFbnZlbG9wZShldmVudCwgb3B0aW9ucy5kc24sIG9wdGlvbnMuc2RrTWV0YWRhdGEpOwogIC8vIExvZyB0aGUgZW52ZWxvcGUgc28gdG8gYWlkIGluIHRlc3RpbmcKICBsb2coSlNPTi5zdHJpbmdpZnkoZW52ZWxvcGUpKTsKCiAgYXdhaXQgdHJhbnNwb3J0LnNlbmQoZW52ZWxvcGUpOwogIGF3YWl0IHRyYW5zcG9ydC5mbHVzaCgyMDAwKTsKCiAgLy8gRGVsYXkgZm9yIDUgc2Vjb25kcyBzbyB0aGF0IHN0ZGlvIGNhbiBmbHVzaCBpbiB0aGUgbWFpbiBldmVudCBsb29wIGV2ZXIgcmVzdGFydHMuCiAgLy8gVGhpcyBpcyBtYWlubHkgZm9yIHRoZSBiZW5lZml0IG9mIGxvZ2dpbmcvZGVidWdnaW5nIGlzc3Vlcy4KICBzZXRUaW1lb3V0KCgpID0+IHsKICAgIHByb2Nlc3MuZXhpdCgwKTsKICB9LCA1MDAwKTsKfQoKbGV0IGRlYnVnZ2VyUGF1c2U7CgppZiAob3B0aW9ucy5jYXB0dXJlU3RhY2tUcmFjZSkgewogIGxvZygnQ29ubmVjdGluZyB0byBkZWJ1Z2dlcicpOwoKICBjb25zdCBzZXNzaW9uID0gbmV3IFNlc3Npb24oKSA7CiAgc2Vzc2lvbi5jb25uZWN0VG9NYWluVGhyZWFkKCk7CgogIGxvZygnQ29ubmVjdGVkIHRvIGRlYnVnZ2VyJyk7CgogIC8vIENvbGxlY3Qgc2NyaXB0SWQgLT4gdXJsIG1hcCBzbyB3ZSBjYW4gbG9vayB1cCB0aGUgZmlsZW5hbWVzIGxhdGVyCiAgY29uc3Qgc2NyaXB0cyA9IG5ldyBNYXAoKTsKCiAgc2Vzc2lvbi5vbignRGVidWdnZXIuc2NyaXB0UGFyc2VkJywgZXZlbnQgPT4gewogICAgc2NyaXB0cy5zZXQoZXZlbnQucGFyYW1zLnNjcmlwdElkLCBldmVudC5wYXJhbXMudXJsKTsKICB9KTsKCiAgc2Vzc2lvbi5vbignRGVidWdnZXIucGF1c2VkJywgZXZlbnQgPT4gewogICAgaWYgKGV2ZW50LnBhcmFtcy5yZWFzb24gIT09ICdvdGhlcicpIHsKICAgICAgcmV0dXJuOwogICAgfQoKICAgIHRyeSB7CiAgICAgIGxvZygnRGVidWdnZXIgcGF1c2VkJyk7CgogICAgICAvLyBjb3B5IHRoZSBmcmFtZXMKICAgICAgY29uc3QgY2FsbEZyYW1lcyA9IFsuLi5ldmVudC5wYXJhbXMuY2FsbEZyYW1lc107CgogICAgICBjb25zdCBnZXRNb2R1bGVOYW1lID0gb3B0aW9ucy5hcHBSb290UGF0aCA/IGNyZWF0ZUdldE1vZHVsZUZyb21GaWxlbmFtZShvcHRpb25zLmFwcFJvb3RQYXRoKSA6ICgpID0+IHVuZGVmaW5lZDsKICAgICAgY29uc3Qgc3RhY2tGcmFtZXMgPSBjYWxsRnJhbWVzLm1hcChmcmFtZSA9PgogICAgICAgIGNhbGxGcmFtZVRvU3RhY2tGcmFtZShmcmFtZSwgc2NyaXB0cy5nZXQoZnJhbWUubG9jYXRpb24uc2NyaXB0SWQpLCBnZXRNb2R1bGVOYW1lKSwKICAgICAgKTsKCiAgICAgIC8vIEV2YWx1YXRlIGEgc2NyaXB0IGluIHRoZSBjdXJyZW50bHkgcGF1c2VkIGNvbnRleHQKICAgICAgc2Vzc2lvbi5wb3N0KAogICAgICAgICdSdW50aW1lLmV2YWx1YXRlJywKICAgICAgICB7CiAgICAgICAgICAvLyBHcmFiIHRoZSB0cmFjZSBjb250ZXh0IGZyb20gdGhlIGN1cnJlbnQgc2NvcGUKICAgICAgICAgIGV4cHJlc3Npb246CiAgICAgICAgICAgICdjb25zdCBjdHggPSBfX1NFTlRSWV9fLmh1Yi5nZXRTY29wZSgpLmdldFByb3BhZ2F0aW9uQ29udGV4dCgpOyBjdHgudHJhY2VJZCArICItIiArIGN0eC5zcGFuSWQgKyAiLSIgKyBjdHgucGFyZW50U3BhbklkJywKICAgICAgICAgIC8vIERvbid0IHJlLXRyaWdnZXIgdGhlIGRlYnVnZ2VyIGlmIHRoaXMgY2F1c2VzIGFuIGVycm9yCiAgICAgICAgICBzaWxlbnQ6IHRydWUsCiAgICAgICAgfSwKICAgICAgICAoXywgcGFyYW0pID0+IHsKICAgICAgICAgIGNvbnN0IHRyYWNlSWQgPSBwYXJhbSAmJiBwYXJhbS5yZXN1bHQgPyAocGFyYW0ucmVzdWx0LnZhbHVlICkgOiAnLS0nOwogICAgICAgICAgY29uc3QgW3RyYWNlX2lkLCBzcGFuX2lkLCBwYXJlbnRfc3Bhbl9pZF0gPSB0cmFjZUlkLnNwbGl0KCctJykgOwoKICAgICAgICAgIHNlc3Npb24ucG9zdCgnRGVidWdnZXIucmVzdW1lJyk7CiAgICAgICAgICBzZXNzaW9uLnBvc3QoJ0RlYnVnZ2VyLmRpc2FibGUnKTsKCiAgICAgICAgICBjb25zdCBjb250ZXh0ID0gX29wdGlvbmFsQ2hhaW4oW3RyYWNlX2lkLCAnb3B0aW9uYWxBY2Nlc3MnLCBfNCA9PiBfNC5sZW5ndGhdKSAmJiBfb3B0aW9uYWxDaGFpbihbc3Bhbl9pZCwgJ29wdGlvbmFsQWNjZXNzJywgXzUgPT4gXzUubGVuZ3RoXSkgPyB7IHRyYWNlX2lkLCBzcGFuX2lkLCBwYXJlbnRfc3Bhbl9pZCB9IDogdW5kZWZpbmVkOwogICAgICAgICAgc2VuZEFuckV2ZW50KHN0YWNrRnJhbWVzLCBjb250ZXh0KS50aGVuKG51bGwsICgpID0+IHsKICAgICAgICAgICAgbG9nKCdTZW5kaW5nIEFOUiBldmVudCBmYWlsZWQuJyk7CiAgICAgICAgICB9KTsKICAgICAgICB9LAogICAgICApOwogICAgfSBjYXRjaCAoZSkgewogICAgICBzZXNzaW9uLnBvc3QoJ0RlYnVnZ2VyLnJlc3VtZScpOwogICAgICBzZXNzaW9uLnBvc3QoJ0RlYnVnZ2VyLmRpc2FibGUnKTsKICAgICAgdGhyb3cgZTsKICAgIH0KICB9KTsKCiAgZGVidWdnZXJQYXVzZSA9ICgpID0+IHsKICAgIHRyeSB7CiAgICAgIHNlc3Npb24ucG9zdCgnRGVidWdnZXIuZW5hYmxlJywgKCkgPT4gewogICAgICAgIHNlc3Npb24ucG9zdCgnRGVidWdnZXIucGF1c2UnKTsKICAgICAgfSk7CiAgICB9IGNhdGNoIChfKSB7CiAgICAgIC8vCiAgICB9CiAgfTsKfQoKZnVuY3Rpb24gY3JlYXRlSHJUaW1lcigpIHsKICAvLyBUT0RPICh2OCk6IFdlIGNhbiB1c2UgcHJvY2Vzcy5ocnRpbWUuYmlnaW50KCkgYWZ0ZXIgd2UgZHJvcCBub2RlIHY4CiAgbGV0IGxhc3RQb2xsID0gcHJvY2Vzcy5ocnRpbWUoKTsKCiAgcmV0dXJuIHsKICAgIGdldFRpbWVNczogKCkgPT4gewogICAgICBjb25zdCBbc2Vjb25kcywgbmFub1NlY29uZHNdID0gcHJvY2Vzcy5ocnRpbWUobGFzdFBvbGwpOwogICAgICByZXR1cm4gTWF0aC5mbG9vcihzZWNvbmRzICogMWUzICsgbmFub1NlY29uZHMgLyAxZTYpOwogICAgfSwKICAgIHJlc2V0OiAoKSA9PiB7CiAgICAgIGxhc3RQb2xsID0gcHJvY2Vzcy5ocnRpbWUoKTsKICAgIH0sCiAgfTsKfQoKZnVuY3Rpb24gd2F0Y2hkb2dUaW1lb3V0KCkgewogIGxvZygnV2F0Y2hkb2cgdGltZW91dCcpOwoKICBpZiAoZGVidWdnZXJQYXVzZSkgewogICAgbG9nKCdQYXVzaW5nIGRlYnVnZ2VyIHRvIGNhcHR1cmUgc3RhY2sgdHJhY2UnKTsKICAgIGRlYnVnZ2VyUGF1c2UoKTsKICB9IGVsc2UgewogICAgbG9nKCdDYXB0dXJpbmcgZXZlbnQgd2l0aG91dCBhIHN0YWNrIHRyYWNlJyk7CiAgICBzZW5kQW5yRXZlbnQoKS50aGVuKG51bGwsICgpID0+IHsKICAgICAgbG9nKCdTZW5kaW5nIEFOUiBldmVudCBmYWlsZWQgb24gd2F0Y2hkb2cgdGltZW91dC4nKTsKICAgIH0pOwogIH0KfQoKY29uc3QgeyBwb2xsIH0gPSB3YXRjaGRvZ1RpbWVyKGNyZWF0ZUhyVGltZXIsIG9wdGlvbnMucG9sbEludGVydmFsLCBvcHRpb25zLmFuclRocmVzaG9sZCwgd2F0Y2hkb2dUaW1lb3V0KTsKCl9vcHRpb25hbENoYWluKFtwYXJlbnRQb3J0LCAnb3B0aW9uYWxBY2Nlc3MnLCBfNiA9PiBfNi5vbiwgJ2NhbGwnLCBfNyA9PiBfNygnbWVzc2FnZScsIChtc2cpID0+IHsKICBpZiAobXNnLnNlc3Npb24pIHsKICAgIHNlc3Npb24gPSBtYWtlU2Vzc2lvbihtc2cuc2Vzc2lvbik7CiAgfQoKICBwb2xsKCk7Cn0pXSk7";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/node",
3
- "version": "7.106.0",
3
+ "version": "7.106.1",
4
4
  "description": "Official Sentry SDK for Node.js",
5
5
  "repository": "git://github.com/getsentry/sentry-javascript.git",
6
6
  "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/node",
@@ -29,10 +29,10 @@
29
29
  "access": "public"
30
30
  },
31
31
  "dependencies": {
32
- "@sentry-internal/tracing": "7.106.0",
33
- "@sentry/core": "7.106.0",
34
- "@sentry/types": "7.106.0",
35
- "@sentry/utils": "7.106.0"
32
+ "@sentry-internal/tracing": "7.106.1",
33
+ "@sentry/core": "7.106.1",
34
+ "@sentry/types": "7.106.1",
35
+ "@sentry/utils": "7.106.1"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/cookie": "0.5.2",