@shjjs/visual-ui 3.0.18 → 3.0.19
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.
- package/es/components/Commons/components/CustomComponentRender/index.vue.mjs +2 -2
- package/es/components/Commons/components/CustomComponentRender/index.vue2.mjs +13 -11
- package/es/packages/components/Commons/components/CustomComponentRender/index.vue.d.ts +2 -0
- package/es/widgets.css +1 -1
- package/package.json +1 -1
- package/umd/index.js +2 -2
- package/umd/widgets.css +1 -1
package/umd/index.js
CHANGED
|
@@ -5205,7 +5205,7 @@ Tip: edit the "Import Map" tab to specify import paths for dependencies.`:u.valu
|
|
|
5205
5205
|
window.__ssr_promise__.then(_mount)
|
|
5206
5206
|
} else {
|
|
5207
5207
|
_mount()
|
|
5208
|
-
}`),await h.eval(B)}catch(T){u.value=T.message}}function C(){d.contentWindow?.location.reload()}return e({reload:C,container:l}),(I,S)=>(Vt(),kr(ta,null,[vv(Xi("div",{ref:"container",class:Ba(["iframe-container",Nr(n)])},null,2),[[S8,t.show]]),$a(aqt,{err:(Nr(a)?.showRuntimeError??!0)&&u.value},null,8,["err"]),!u.value&&(Nr(a)?.showRuntimeWarning??!0)?(Vt(),Pi(aqt,{key:0,warn:c.value},null,8,["warn"])):Hi("",!0)],64))}}),[["__scopeId","data-v-da180541"]]),Ann=(i,e,t)=>{bi(()=>i.sources,()=>{e()},{deep:!0}),bi(()=>i.option.value.option,(r,n)=>{Ht.isEqual(r,n)||t()},{deep:!0})},dqt="2.0.0",bnn=i=>{const e=Ht.cloneDeep(i);return e.version!==dqt?{hash:e.hash,option:e.option,version:dqt}:i},hqt="data:text/javascript;base64,LyoqDQoqIEB2dWUvcnVudGltZS1kb20gdjMuNS4xNw0KKiAoYykgMjAxOC1wcmVzZW50IFl1eGkgKEV2YW4pIFlvdSBhbmQgVnVlIGNvbnRyaWJ1dG9ycw0KKiBAbGljZW5zZSBNSVQNCioqLw0KLyohICNfX05PX1NJREVfRUZGRUNUU19fICovDQovLyBAX19OT19TSURFX0VGRkVDVFNfXw0KZnVuY3Rpb24gbWFrZU1hcChzdHIpIHsNCiAgY29uc3QgbWFwID0gLyogQF9fUFVSRV9fICovIE9iamVjdC5jcmVhdGUobnVsbCk7DQogIGZvciAoY29uc3Qga2V5IG9mIHN0ci5zcGxpdCgiLCIpKSBtYXBba2V5XSA9IDE7DQogIHJldHVybiAodmFsKSA9PiB2YWwgaW4gbWFwOw0KfQ0KDQpjb25zdCBFTVBUWV9PQkogPSBPYmplY3QuZnJlZXplKHt9KSA7DQpjb25zdCBFTVBUWV9BUlIgPSBPYmplY3QuZnJlZXplKFtdKSA7DQpjb25zdCBOT09QID0gKCkgPT4gew0KfTsNCmNvbnN0IE5PID0gKCkgPT4gZmFsc2U7DQpjb25zdCBpc09uID0gKGtleSkgPT4ga2V5LmNoYXJDb2RlQXQoMCkgPT09IDExMSAmJiBrZXkuY2hhckNvZGVBdCgxKSA9PT0gMTEwICYmIC8vIHVwcGVyY2FzZSBsZXR0ZXINCihrZXkuY2hhckNvZGVBdCgyKSA+IDEyMiB8fCBrZXkuY2hhckNvZGVBdCgyKSA8IDk3KTsNCmNvbnN0IGlzTW9kZWxMaXN0ZW5lciA9IChrZXkpID0+IGtleS5zdGFydHNXaXRoKCJvblVwZGF0ZToiKTsNCmNvbnN0IGV4dGVuZCA9IE9iamVjdC5hc3NpZ247DQpjb25zdCByZW1vdmUgPSAoYXJyLCBlbCkgPT4gew0KICBjb25zdCBpID0gYXJyLmluZGV4T2YoZWwpOw0KICBpZiAoaSA+IC0xKSB7DQogICAgYXJyLnNwbGljZShpLCAxKTsNCiAgfQ0KfTsNCmNvbnN0IGhhc093blByb3BlcnR5JDEgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5Ow0KY29uc3QgaGFzT3duID0gKHZhbCwga2V5KSA9PiBoYXNPd25Qcm9wZXJ0eSQxLmNhbGwodmFsLCBrZXkpOw0KY29uc3QgaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7DQpjb25zdCBpc01hcCA9ICh2YWwpID0+IHRvVHlwZVN0cmluZyh2YWwpID09PSAiW29iamVjdCBNYXBdIjsNCmNvbnN0IGlzU2V0ID0gKHZhbCkgPT4gdG9UeXBlU3RyaW5nKHZhbCkgPT09ICJbb2JqZWN0IFNldF0iOw0KY29uc3QgaXNEYXRlID0gKHZhbCkgPT4gdG9UeXBlU3RyaW5nKHZhbCkgPT09ICJbb2JqZWN0IERhdGVdIjsNCmNvbnN0IGlzUmVnRXhwID0gKHZhbCkgPT4gdG9UeXBlU3RyaW5nKHZhbCkgPT09ICJbb2JqZWN0IFJlZ0V4cF0iOw0KY29uc3QgaXNGdW5jdGlvbiA9ICh2YWwpID0+IHR5cGVvZiB2YWwgPT09ICJmdW5jdGlvbiI7DQpjb25zdCBpc1N0cmluZyA9ICh2YWwpID0+IHR5cGVvZiB2YWwgPT09ICJzdHJpbmciOw0KY29uc3QgaXNTeW1ib2wgPSAodmFsKSA9PiB0eXBlb2YgdmFsID09PSAic3ltYm9sIjsNCmNvbnN0IGlzT2JqZWN0ID0gKHZhbCkgPT4gdmFsICE9PSBudWxsICYmIHR5cGVvZiB2YWwgPT09ICJvYmplY3QiOw0KY29uc3QgaXNQcm9taXNlID0gKHZhbCkgPT4gew0KICByZXR1cm4gKGlzT2JqZWN0KHZhbCkgfHwgaXNGdW5jdGlvbih2YWwpKSAmJiBpc0Z1bmN0aW9uKHZhbC50aGVuKSAmJiBpc0Z1bmN0aW9uKHZhbC5jYXRjaCk7DQp9Ow0KY29uc3Qgb2JqZWN0VG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nOw0KY29uc3QgdG9UeXBlU3RyaW5nID0gKHZhbHVlKSA9PiBvYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKTsNCmNvbnN0IHRvUmF3VHlwZSA9ICh2YWx1ZSkgPT4gew0KICByZXR1cm4gdG9UeXBlU3RyaW5nKHZhbHVlKS5zbGljZSg4LCAtMSk7DQp9Ow0KY29uc3QgaXNQbGFpbk9iamVjdCA9ICh2YWwpID0+IHRvVHlwZVN0cmluZyh2YWwpID09PSAiW29iamVjdCBPYmplY3RdIjsNCmNvbnN0IGlzSW50ZWdlcktleSA9IChrZXkpID0+IGlzU3RyaW5nKGtleSkgJiYga2V5ICE9PSAiTmFOIiAmJiBrZXlbMF0gIT09ICItIiAmJiAiIiArIHBhcnNlSW50KGtleSwgMTApID09PSBrZXk7DQpjb25zdCBpc1Jlc2VydmVkUHJvcCA9IC8qIEBfX1BVUkVfXyAqLyBtYWtlTWFwKA0KICAvLyB0aGUgbGVhZGluZyBjb21tYSBpcyBpbnRlbnRpb25hbCBzbyBlbXB0eSBzdHJpbmcgIiIgaXMgYWxzbyBpbmNsdWRlZA0KICAiLGtleSxyZWYscmVmX2ZvcixyZWZfa2V5LG9uVm5vZGVCZWZvcmVNb3VudCxvblZub2RlTW91bnRlZCxvblZub2RlQmVmb3JlVXBkYXRlLG9uVm5vZGVVcGRhdGVkLG9uVm5vZGVCZWZvcmVVbm1vdW50LG9uVm5vZGVVbm1vdW50ZWQiDQopOw0KY29uc3QgaXNCdWlsdEluRGlyZWN0aXZlID0gLyogQF9fUFVSRV9fICovIG1ha2VNYXAoDQogICJiaW5kLGNsb2FrLGVsc2UtaWYsZWxzZSxmb3IsaHRtbCxpZixtb2RlbCxvbixvbmNlLHByZSxzaG93LHNsb3QsdGV4dCxtZW1vIg0KKTsNCmNvbnN0IGNhY2hlU3RyaW5nRnVuY3Rpb24gPSAoZm4pID0+IHsNCiAgY29uc3QgY2FjaGUgPSAvKiBAX19QVVJFX18gKi8gT2JqZWN0LmNyZWF0ZShudWxsKTsNCiAgcmV0dXJuIChzdHIpID0+IHsNCiAgICBjb25zdCBoaXQgPSBjYWNoZVtzdHJdOw0KICAgIHJldHVybiBoaXQgfHwgKGNhY2hlW3N0cl0gPSBmbihzdHIpKTsNCiAgfTsNCn07DQpjb25zdCBjYW1lbGl6ZVJFID0gLy0oXHcpL2c7DQpjb25zdCBjYW1lbGl6ZSA9IGNhY2hlU3RyaW5nRnVuY3Rpb24oDQogIChzdHIpID0+IHsNCiAgICByZXR1cm4gc3RyLnJlcGxhY2UoY2FtZWxpemVSRSwgKF8sIGMpID0+IGMgPyBjLnRvVXBwZXJDYXNlKCkgOiAiIik7DQogIH0NCik7DQpjb25zdCBoeXBoZW5hdGVSRSA9IC9cQihbQS1aXSkvZzsNCmNvbnN0IGh5cGhlbmF0ZSA9IGNhY2hlU3RyaW5nRnVuY3Rpb24oDQogIChzdHIpID0+IHN0ci5yZXBsYWNlKGh5cGhlbmF0ZVJFLCAiLSQxIikudG9Mb3dlckNhc2UoKQ0KKTsNCmNvbnN0IGNhcGl0YWxpemUgPSBjYWNoZVN0cmluZ0Z1bmN0aW9uKChzdHIpID0+IHsNCiAgcmV0dXJuIHN0ci5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHN0ci5zbGljZSgxKTsNCn0pOw0KY29uc3QgdG9IYW5kbGVyS2V5ID0gY2FjaGVTdHJpbmdGdW5jdGlvbigNCiAgKHN0cikgPT4gew0KICAgIGNvbnN0IHMgPSBzdHIgPyBgb24ke2NhcGl0YWxpemUoc3RyKX1gIDogYGA7DQogICAgcmV0dXJuIHM7DQogIH0NCik7DQpjb25zdCBoYXNDaGFuZ2VkID0gKHZhbHVlLCBvbGRWYWx1ZSkgPT4gIU9iamVjdC5pcyh2YWx1ZSwgb2xkVmFsdWUpOw0KY29uc3QgaW52b2tlQXJyYXlGbnMgPSAoZm5zLCAuLi5hcmcpID0+IHsNCiAgZm9yIChsZXQgaSA9IDA7IGkgPCBmbnMubGVuZ3RoOyBpKyspIHsNCiAgICBmbnNbaV0oLi4uYXJnKTsNCiAgfQ0KfTsNCmNvbnN0IGRlZiA9IChvYmosIGtleSwgdmFsdWUsIHdyaXRhYmxlID0gZmFsc2UpID0+IHsNCiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwga2V5LCB7DQogICAgY29uZmlndXJhYmxlOiB0cnVlLA0KICAgIGVudW1lcmFibGU6IGZhbHNlLA0KICAgIHdyaXRhYmxlLA0KICAgIHZhbHVlDQogIH0pOw0KfTsNCmNvbnN0IGxvb3NlVG9OdW1iZXIgPSAodmFsKSA9PiB7DQogIGNvbnN0IG4gPSBwYXJzZUZsb2F0KHZhbCk7DQogIHJldHVybiBpc05hTihuKSA/IHZhbCA6IG47DQp9Ow0KY29uc3QgdG9OdW1iZXIgPSAodmFsKSA9PiB7DQogIGNvbnN0IG4gPSBpc1N0cmluZyh2YWwpID8gTnVtYmVyKHZhbCkgOiBOYU47DQogIHJldHVybiBpc05hTihuKSA/IHZhbCA6IG47DQp9Ow0KbGV0IF9nbG9iYWxUaGlzOw0KY29uc3QgZ2V0R2xvYmFsVGhpcyA9ICgpID0+IHsNCiAgcmV0dXJuIF9nbG9iYWxUaGlzIHx8IChfZ2xvYmFsVGhpcyA9IHR5cGVvZiBnbG9iYWxUaGlzICE9PSAidW5kZWZpbmVkIiA/IGdsb2JhbFRoaXMgOiB0eXBlb2Ygc2VsZiAhPT0gInVuZGVmaW5lZCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gInVuZGVmaW5lZCIgPyB3aW5kb3cgOiB0eXBlb2YgZ2xvYmFsICE9PSAidW5kZWZpbmVkIiA/IGdsb2JhbCA6IHt9KTsNCn07DQoNCmNvbnN0IEdMT0JBTFNfQUxMT1dFRCA9ICJJbmZpbml0eSx1bmRlZmluZWQsTmFOLGlzRmluaXRlLGlzTmFOLHBhcnNlRmxvYXQscGFyc2VJbnQsZGVjb2RlVVJJLGRlY29kZVVSSUNvbXBvbmVudCxlbmNvZGVVUkksZW5jb2RlVVJJQ29tcG9uZW50LE1hdGgsTnVtYmVyLERhdGUsQXJyYXksT2JqZWN0LEJvb2xlYW4sU3RyaW5nLFJlZ0V4cCxNYXAsU2V0LEpTT04sSW50bCxCaWdJbnQsY29uc29sZSxFcnJvcixTeW1ib2wiOw0KY29uc3QgaXNHbG9iYWxseUFsbG93ZWQgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcChHTE9CQUxTX0FMTE9XRUQpOw0KDQpmdW5jdGlvbiBub3JtYWxpemVTdHlsZSh2YWx1ZSkgew0KICBpZiAoaXNBcnJheSh2YWx1ZSkpIHsNCiAgICBjb25zdCByZXMgPSB7fTsNCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKSB7DQogICAgICBjb25zdCBpdGVtID0gdmFsdWVbaV07DQogICAgICBjb25zdCBub3JtYWxpemVkID0gaXNTdHJpbmcoaXRlbSkgPyBwYXJzZVN0cmluZ1N0eWxlKGl0ZW0pIDogbm9ybWFsaXplU3R5bGUoaXRlbSk7DQogICAgICBpZiAobm9ybWFsaXplZCkgew0KICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBub3JtYWxpemVkKSB7DQogICAgICAgICAgcmVzW2tleV0gPSBub3JtYWxpemVkW2tleV07DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogICAgcmV0dXJuIHJlczsNCiAgfSBlbHNlIGlmIChpc1N0cmluZyh2YWx1ZSkgfHwgaXNPYmplY3QodmFsdWUpKSB7DQogICAgcmV0dXJuIHZhbHVlOw0KICB9DQp9DQpjb25zdCBsaXN0RGVsaW1pdGVyUkUgPSAvOyg/IVteKF0qXCkpL2c7DQpjb25zdCBwcm9wZXJ0eURlbGltaXRlclJFID0gLzooW15dKykvOw0KY29uc3Qgc3R5bGVDb21tZW50UkUgPSAvXC9cKlteXSo/XCpcLy9nOw0KZnVuY3Rpb24gcGFyc2VTdHJpbmdTdHlsZShjc3NUZXh0KSB7DQogIGNvbnN0IHJldCA9IHt9Ow0KICBjc3NUZXh0LnJlcGxhY2Uoc3R5bGVDb21tZW50UkUsICIiKS5zcGxpdChsaXN0RGVsaW1pdGVyUkUpLmZvckVhY2goKGl0ZW0pID0+IHsNCiAgICBpZiAoaXRlbSkgew0KICAgICAgY29uc3QgdG1wID0gaXRlbS5zcGxpdChwcm9wZXJ0eURlbGltaXRlclJFKTsNCiAgICAgIHRtcC5sZW5ndGggPiAxICYmIChyZXRbdG1wWzBdLnRyaW0oKV0gPSB0bXBbMV0udHJpbSgpKTsNCiAgICB9DQogIH0pOw0KICByZXR1cm4gcmV0Ow0KfQ0KZnVuY3Rpb24gc3RyaW5naWZ5U3R5bGUoc3R5bGVzKSB7DQogIGlmICghc3R5bGVzKSByZXR1cm4gIiI7DQogIGlmIChpc1N0cmluZyhzdHlsZXMpKSByZXR1cm4gc3R5bGVzOw0KICBsZXQgcmV0ID0gIiI7DQogIGZvciAoY29uc3Qga2V5IGluIHN0eWxlcykgew0KICAgIGNvbnN0IHZhbHVlID0gc3R5bGVzW2tleV07DQogICAgaWYgKGlzU3RyaW5nKHZhbHVlKSB8fCB0eXBlb2YgdmFsdWUgPT09ICJudW1iZXIiKSB7DQogICAgICBjb25zdCBub3JtYWxpemVkS2V5ID0ga2V5LnN0YXJ0c1dpdGgoYC0tYCkgPyBrZXkgOiBoeXBoZW5hdGUoa2V5KTsNCiAgICAgIHJldCArPSBgJHtub3JtYWxpemVkS2V5fToke3ZhbHVlfTtgOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gcmV0Ow0KfQ0KZnVuY3Rpb24gbm9ybWFsaXplQ2xhc3ModmFsdWUpIHsNCiAgbGV0IHJlcyA9ICIiOw0KICBpZiAoaXNTdHJpbmcodmFsdWUpKSB7DQogICAgcmVzID0gdmFsdWU7DQogIH0gZWxzZSBpZiAoaXNBcnJheSh2YWx1ZSkpIHsNCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKSB7DQogICAgICBjb25zdCBub3JtYWxpemVkID0gbm9ybWFsaXplQ2xhc3ModmFsdWVbaV0pOw0KICAgICAgaWYgKG5vcm1hbGl6ZWQpIHsNCiAgICAgICAgcmVzICs9IG5vcm1hbGl6ZWQgKyAiICI7DQogICAgICB9DQogICAgfQ0KICB9IGVsc2UgaWYgKGlzT2JqZWN0KHZhbHVlKSkgew0KICAgIGZvciAoY29uc3QgbmFtZSBpbiB2YWx1ZSkgew0KICAgICAgaWYgKHZhbHVlW25hbWVdKSB7DQogICAgICAgIHJlcyArPSBuYW1lICsgIiAiOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICByZXR1cm4gcmVzLnRyaW0oKTsNCn0NCmZ1bmN0aW9uIG5vcm1hbGl6ZVByb3BzKHByb3BzKSB7DQogIGlmICghcHJvcHMpIHJldHVybiBudWxsOw0KICBsZXQgeyBjbGFzczoga2xhc3MsIHN0eWxlIH0gPSBwcm9wczsNCiAgaWYgKGtsYXNzICYmICFpc1N0cmluZyhrbGFzcykpIHsNCiAgICBwcm9wcy5jbGFzcyA9IG5vcm1hbGl6ZUNsYXNzKGtsYXNzKTsNCiAgfQ0KICBpZiAoc3R5bGUpIHsNCiAgICBwcm9wcy5zdHlsZSA9IG5vcm1hbGl6ZVN0eWxlKHN0eWxlKTsNCiAgfQ0KICByZXR1cm4gcHJvcHM7DQp9DQoNCmNvbnN0IEhUTUxfVEFHUyA9ICJodG1sLGJvZHksYmFzZSxoZWFkLGxpbmssbWV0YSxzdHlsZSx0aXRsZSxhZGRyZXNzLGFydGljbGUsYXNpZGUsZm9vdGVyLGhlYWRlcixoZ3JvdXAsaDEsaDIsaDMsaDQsaDUsaDYsbmF2LHNlY3Rpb24sZGl2LGRkLGRsLGR0LGZpZ2NhcHRpb24sZmlndXJlLHBpY3R1cmUsaHIsaW1nLGxpLG1haW4sb2wscCxwcmUsdWwsYSxiLGFiYnIsYmRpLGJkbyxicixjaXRlLGNvZGUsZGF0YSxkZm4sZW0saSxrYmQsbWFyayxxLHJwLHJ0LHJ1YnkscyxzYW1wLHNtYWxsLHNwYW4sc3Ryb25nLHN1YixzdXAsdGltZSx1LHZhcix3YnIsYXJlYSxhdWRpbyxtYXAsdHJhY2ssdmlkZW8sZW1iZWQsb2JqZWN0LHBhcmFtLHNvdXJjZSxjYW52YXMsc2NyaXB0LG5vc2NyaXB0LGRlbCxpbnMsY2FwdGlvbixjb2wsY29sZ3JvdXAsdGFibGUsdGhlYWQsdGJvZHksdGQsdGgsdHIsYnV0dG9uLGRhdGFsaXN0LGZpZWxkc2V0LGZvcm0saW5wdXQsbGFiZWwsbGVnZW5kLG1ldGVyLG9wdGdyb3VwLG9wdGlvbixvdXRwdXQscHJvZ3Jlc3Msc2VsZWN0LHRleHRhcmVhLGRldGFpbHMsZGlhbG9nLG1lbnUsc3VtbWFyeSx0ZW1wbGF0ZSxibG9ja3F1b3RlLGlmcmFtZSx0Zm9vdCI7DQpjb25zdCBTVkdfVEFHUyA9ICJzdmcsYW5pbWF0ZSxhbmltYXRlTW90aW9uLGFuaW1hdGVUcmFuc2Zvcm0sY2lyY2xlLGNsaXBQYXRoLGNvbG9yLXByb2ZpbGUsZGVmcyxkZXNjLGRpc2NhcmQsZWxsaXBzZSxmZUJsZW5kLGZlQ29sb3JNYXRyaXgsZmVDb21wb25lbnRUcmFuc2ZlcixmZUNvbXBvc2l0ZSxmZUNvbnZvbHZlTWF0cml4LGZlRGlmZnVzZUxpZ2h0aW5nLGZlRGlzcGxhY2VtZW50TWFwLGZlRGlzdGFudExpZ2h0LGZlRHJvcFNoYWRvdyxmZUZsb29kLGZlRnVuY0EsZmVGdW5jQixmZUZ1bmNHLGZlRnVuY1IsZmVHYXVzc2lhbkJsdXIsZmVJbWFnZSxmZU1lcmdlLGZlTWVyZ2VOb2RlLGZlTW9ycGhvbG9neSxmZU9mZnNldCxmZVBvaW50TGlnaHQsZmVTcGVjdWxhckxpZ2h0aW5nLGZlU3BvdExpZ2h0LGZlVGlsZSxmZVR1cmJ1bGVuY2UsZmlsdGVyLGZvcmVpZ25PYmplY3QsZyxoYXRjaCxoYXRjaHBhdGgsaW1hZ2UsbGluZSxsaW5lYXJHcmFkaWVudCxtYXJrZXIsbWFzayxtZXNoLG1lc2hncmFkaWVudCxtZXNocGF0Y2gsbWVzaHJvdyxtZXRhZGF0YSxtcGF0aCxwYXRoLHBhdHRlcm4scG9seWdvbixwb2x5bGluZSxyYWRpYWxHcmFkaWVudCxyZWN0LHNldCxzb2xpZGNvbG9yLHN0b3Asc3dpdGNoLHN5bWJvbCx0ZXh0LHRleHRQYXRoLHRpdGxlLHRzcGFuLHVua25vd24sdXNlLHZpZXciOw0KY29uc3QgTUFUSF9UQUdTID0gImFubm90YXRpb24sYW5ub3RhdGlvbi14bWwsbWFjdGlvbixtYWxpZ25ncm91cCxtYWxpZ25tYXJrLG1hdGgsbWVuY2xvc2UsbWVycm9yLG1mZW5jZWQsbWZyYWMsbWZyYWN0aW9uLG1nbHlwaCxtaSxtbGFiZWxlZHRyLG1sb25nZGl2LG1tdWx0aXNjcmlwdHMsbW4sbW8sbW92ZXIsbXBhZGRlZCxtcGhhbnRvbSxtcHJlc2NyaXB0cyxtcm9vdCxtcm93LG1zLG1zY2Fycmllcyxtc2NhcnJ5LG1zZ3JvdXAsbXNsaW5lLG1zcGFjZSxtc3FydCxtc3Jvdyxtc3RhY2ssbXN0eWxlLG1zdWIsbXN1YnN1cCxtc3VwLG10YWJsZSxtdGQsbXRleHQsbXRyLG11bmRlcixtdW5kZXJvdmVyLG5vbmUsc2VtYW50aWNzIjsNCmNvbnN0IGlzSFRNTFRhZyA9IC8qIEBfX1BVUkVfXyAqLyBtYWtlTWFwKEhUTUxfVEFHUyk7DQpjb25zdCBpc1NWR1RhZyA9IC8qIEBfX1BVUkVfXyAqLyBtYWtlTWFwKFNWR19UQUdTKTsNCmNvbnN0IGlzTWF0aE1MVGFnID0gLyogQF9fUFVSRV9fICovIG1ha2VNYXAoTUFUSF9UQUdTKTsNCg0KY29uc3Qgc3BlY2lhbEJvb2xlYW5BdHRycyA9IGBpdGVtc2NvcGUsYWxsb3dmdWxsc2NyZWVuLGZvcm1ub3ZhbGlkYXRlLGlzbWFwLG5vbW9kdWxlLG5vdmFsaWRhdGUscmVhZG9ubHlgOw0KY29uc3QgaXNTcGVjaWFsQm9vbGVhbkF0dHIgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcChzcGVjaWFsQm9vbGVhbkF0dHJzKTsNCmNvbnN0IGlzQm9vbGVhbkF0dHIgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcCgNCiAgc3BlY2lhbEJvb2xlYW5BdHRycyArIGAsYXN5bmMsYXV0b2ZvY3VzLGF1dG9wbGF5LGNvbnRyb2xzLGRlZmF1bHQsZGVmZXIsZGlzYWJsZWQsaGlkZGVuLGluZXJ0LGxvb3Asb3BlbixyZXF1aXJlZCxyZXZlcnNlZCxzY29wZWQsc2VhbWxlc3MsY2hlY2tlZCxtdXRlZCxtdWx0aXBsZSxzZWxlY3RlZGANCik7DQpmdW5jdGlvbiBpbmNsdWRlQm9vbGVhbkF0dHIodmFsdWUpIHsNCiAgcmV0dXJuICEhdmFsdWUgfHwgdmFsdWUgPT09ICIiOw0KfQ0KY29uc3QgaXNLbm93bkh0bWxBdHRyID0gLyogQF9fUFVSRV9fICovIG1ha2VNYXAoDQogIGBhY2NlcHQsYWNjZXB0LWNoYXJzZXQsYWNjZXNza2V5LGFjdGlvbixhbGlnbixhbGxvdyxhbHQsYXN5bmMsYXV0b2NhcGl0YWxpemUsYXV0b2NvbXBsZXRlLGF1dG9mb2N1cyxhdXRvcGxheSxiYWNrZ3JvdW5kLGJnY29sb3IsYm9yZGVyLGJ1ZmZlcmVkLGNhcHR1cmUsY2hhbGxlbmdlLGNoYXJzZXQsY2hlY2tlZCxjaXRlLGNsYXNzLGNvZGUsY29kZWJhc2UsY29sb3IsY29scyxjb2xzcGFuLGNvbnRlbnQsY29udGVudGVkaXRhYmxlLGNvbnRleHRtZW51LGNvbnRyb2xzLGNvb3Jkcyxjcm9zc29yaWdpbixjc3AsZGF0YSxkYXRldGltZSxkZWNvZGluZyxkZWZhdWx0LGRlZmVyLGRpcixkaXJuYW1lLGRpc2FibGVkLGRvd25sb2FkLGRyYWdnYWJsZSxkcm9wem9uZSxlbmN0eXBlLGVudGVya2V5aGludCxmb3IsZm9ybSxmb3JtYWN0aW9uLGZvcm1lbmN0eXBlLGZvcm1tZXRob2QsZm9ybW5vdmFsaWRhdGUsZm9ybXRhcmdldCxoZWFkZXJzLGhlaWdodCxoaWRkZW4saGlnaCxocmVmLGhyZWZsYW5nLGh0dHAtZXF1aXYsaWNvbixpZCxpbXBvcnRhbmNlLGluZXJ0LGludGVncml0eSxpc21hcCxpdGVtcHJvcCxrZXl0eXBlLGtpbmQsbGFiZWwsbGFuZyxsYW5ndWFnZSxsb2FkaW5nLGxpc3QsbG9vcCxsb3csbWFuaWZlc3QsbWF4LG1heGxlbmd0aCxtaW5sZW5ndGgsbWVkaWEsbWluLG11bHRpcGxlLG11dGVkLG5hbWUsbm92YWxpZGF0ZSxvcGVuLG9wdGltdW0scGF0dGVybixwaW5nLHBsYWNlaG9sZGVyLHBvc3RlcixwcmVsb2FkLHJhZGlvZ3JvdXAscmVhZG9ubHkscmVmZXJyZXJwb2xpY3kscmVsLHJlcXVpcmVkLHJldmVyc2VkLHJvd3Mscm93c3BhbixzYW5kYm94LHNjb3BlLHNjb3BlZCxzZWxlY3RlZCxzaGFwZSxzaXplLHNpemVzLHNsb3Qsc3BhbixzcGVsbGNoZWNrLHNyYyxzcmNkb2Msc3JjbGFuZyxzcmNzZXQsc3RhcnQsc3RlcCxzdHlsZSxzdW1tYXJ5LHRhYmluZGV4LHRhcmdldCx0aXRsZSx0cmFuc2xhdGUsdHlwZSx1c2VtYXAsdmFsdWUsd2lkdGgsd3JhcGANCik7DQpjb25zdCBpc0tub3duU3ZnQXR0ciA9IC8qIEBfX1BVUkVfXyAqLyBtYWtlTWFwKA0KICBgeG1sbnMsYWNjZW50LWhlaWdodCxhY2N1bXVsYXRlLGFkZGl0aXZlLGFsaWdubWVudC1iYXNlbGluZSxhbHBoYWJldGljLGFtcGxpdHVkZSxhcmFiaWMtZm9ybSxhc2NlbnQsYXR0cmlidXRlTmFtZSxhdHRyaWJ1dGVUeXBlLGF6aW11dGgsYmFzZUZyZXF1ZW5jeSxiYXNlbGluZS1zaGlmdCxiYXNlUHJvZmlsZSxiYm94LGJlZ2luLGJpYXMsYnksY2FsY01vZGUsY2FwLWhlaWdodCxjbGFzcyxjbGlwLGNsaXBQYXRoVW5pdHMsY2xpcC1wYXRoLGNsaXAtcnVsZSxjb2xvcixjb2xvci1pbnRlcnBvbGF0aW9uLGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycyxjb2xvci1wcm9maWxlLGNvbG9yLXJlbmRlcmluZyxjb250ZW50U2NyaXB0VHlwZSxjb250ZW50U3R5bGVUeXBlLGNyb3Nzb3JpZ2luLGN1cnNvcixjeCxjeSxkLGRlY2VsZXJhdGUsZGVzY2VudCxkaWZmdXNlQ29uc3RhbnQsZGlyZWN0aW9uLGRpc3BsYXksZGl2aXNvcixkb21pbmFudC1iYXNlbGluZSxkdXIsZHgsZHksZWRnZU1vZGUsZWxldmF0aW9uLGVuYWJsZS1iYWNrZ3JvdW5kLGVuZCxleHBvbmVudCxmaWxsLGZpbGwtb3BhY2l0eSxmaWxsLXJ1bGUsZmlsdGVyLGZpbHRlclJlcyxmaWx0ZXJVbml0cyxmbG9vZC1jb2xvcixmbG9vZC1vcGFjaXR5LGZvbnQtZmFtaWx5LGZvbnQtc2l6ZSxmb250LXNpemUtYWRqdXN0LGZvbnQtc3RyZXRjaCxmb250LXN0eWxlLGZvbnQtdmFyaWFudCxmb250LXdlaWdodCxmb3JtYXQsZnJvbSxmcixmeCxmeSxnMSxnMixnbHlwaC1uYW1lLGdseXBoLW9yaWVudGF0aW9uLWhvcml6b250YWwsZ2x5cGgtb3JpZW50YXRpb24tdmVydGljYWwsZ2x5cGhSZWYsZ3JhZGllbnRUcmFuc2Zvcm0sZ3JhZGllbnRVbml0cyxoYW5naW5nLGhlaWdodCxocmVmLGhyZWZsYW5nLGhvcml6LWFkdi14LGhvcml6LW9yaWdpbi14LGlkLGlkZW9ncmFwaGljLGltYWdlLXJlbmRlcmluZyxpbixpbjIsaW50ZXJjZXB0LGssazEsazIsazMsazQsa2VybmVsTWF0cml4LGtlcm5lbFVuaXRMZW5ndGgsa2VybmluZyxrZXlQb2ludHMsa2V5U3BsaW5lcyxrZXlUaW1lcyxsYW5nLGxlbmd0aEFkanVzdCxsZXR0ZXItc3BhY2luZyxsaWdodGluZy1jb2xvcixsaW1pdGluZ0NvbmVBbmdsZSxsb2NhbCxtYXJrZXItZW5kLG1hcmtlci1taWQsbWFya2VyLXN0YXJ0LG1hcmtlckhlaWdodCxtYXJrZXJVbml0cyxtYXJrZXJXaWR0aCxtYXNrLG1hc2tDb250ZW50VW5pdHMsbWFza1VuaXRzLG1hdGhlbWF0aWNhbCxtYXgsbWVkaWEsbWV0aG9kLG1pbixtb2RlLG5hbWUsbnVtT2N0YXZlcyxvZmZzZXQsb3BhY2l0eSxvcGVyYXRvcixvcmRlcixvcmllbnQsb3JpZW50YXRpb24sb3JpZ2luLG92ZXJmbG93LG92ZXJsaW5lLXBvc2l0aW9uLG92ZXJsaW5lLXRoaWNrbmVzcyxwYW5vc2UtMSxwYWludC1vcmRlcixwYXRoLHBhdGhMZW5ndGgscGF0dGVybkNvbnRlbnRVbml0cyxwYXR0ZXJuVHJhbnNmb3JtLHBhdHRlcm5Vbml0cyxwaW5nLHBvaW50ZXItZXZlbnRzLHBvaW50cyxwb2ludHNBdFgscG9pbnRzQXRZLHBvaW50c0F0WixwcmVzZXJ2ZUFscGhhLHByZXNlcnZlQXNwZWN0UmF0aW8scHJpbWl0aXZlVW5pdHMscixyYWRpdXMscmVmZXJyZXJQb2xpY3kscmVmWCxyZWZZLHJlbCxyZW5kZXJpbmctaW50ZW50LHJlcGVhdENvdW50LHJlcGVhdER1cixyZXF1aXJlZEV4dGVuc2lvbnMscmVxdWlyZWRGZWF0dXJlcyxyZXN0YXJ0LHJlc3VsdCxyb3RhdGUscngscnksc2NhbGUsc2VlZCxzaGFwZS1yZW5kZXJpbmcsc2xvcGUsc3BhY2luZyxzcGVjdWxhckNvbnN0YW50LHNwZWN1bGFyRXhwb25lbnQsc3BlZWQsc3ByZWFkTWV0aG9kLHN0YXJ0T2Zmc2V0LHN0ZERldmlhdGlvbixzdGVtaCxzdGVtdixzdGl0Y2hUaWxlcyxzdG9wLWNvbG9yLHN0b3Atb3BhY2l0eSxzdHJpa2V0aHJvdWdoLXBvc2l0aW9uLHN0cmlrZXRocm91Z2gtdGhpY2tuZXNzLHN0cmluZyxzdHJva2Usc3Ryb2tlLWRhc2hhcnJheSxzdHJva2UtZGFzaG9mZnNldCxzdHJva2UtbGluZWNhcCxzdHJva2UtbGluZWpvaW4sc3Ryb2tlLW1pdGVybGltaXQsc3Ryb2tlLW9wYWNpdHksc3Ryb2tlLXdpZHRoLHN0eWxlLHN1cmZhY2VTY2FsZSxzeXN0ZW1MYW5ndWFnZSx0YWJpbmRleCx0YWJsZVZhbHVlcyx0YXJnZXQsdGFyZ2V0WCx0YXJnZXRZLHRleHQtYW5jaG9yLHRleHQtZGVjb3JhdGlvbix0ZXh0LXJlbmRlcmluZyx0ZXh0TGVuZ3RoLHRvLHRyYW5zZm9ybSx0cmFuc2Zvcm0tb3JpZ2luLHR5cGUsdTEsdTIsdW5kZXJsaW5lLXBvc2l0aW9uLHVuZGVybGluZS10aGlja25lc3MsdW5pY29kZSx1bmljb2RlLWJpZGksdW5pY29kZS1yYW5nZSx1bml0cy1wZXItZW0sdi1hbHBoYWJldGljLHYtaGFuZ2luZyx2LWlkZW9ncmFwaGljLHYtbWF0aGVtYXRpY2FsLHZhbHVlcyx2ZWN0b3ItZWZmZWN0LHZlcnNpb24sdmVydC1hZHYteSx2ZXJ0LW9yaWdpbi14LHZlcnQtb3JpZ2luLXksdmlld0JveCx2aWV3VGFyZ2V0LHZpc2liaWxpdHksd2lkdGgsd2lkdGhzLHdvcmQtc3BhY2luZyx3cml0aW5nLW1vZGUseCx4LWhlaWdodCx4MSx4Mix4Q2hhbm5lbFNlbGVjdG9yLHhsaW5rOmFjdHVhdGUseGxpbms6YXJjcm9sZSx4bGluazpocmVmLHhsaW5rOnJvbGUseGxpbms6c2hvdyx4bGluazp0aXRsZSx4bGluazp0eXBlLHhtbG5zOnhsaW5rLHhtbDpiYXNlLHhtbDpsYW5nLHhtbDpzcGFjZSx5LHkxLHkyLHlDaGFubmVsU2VsZWN0b3Iseix6b29tQW5kUGFuYA0KKTsNCmZ1bmN0aW9uIGlzUmVuZGVyYWJsZUF0dHJWYWx1ZSh2YWx1ZSkgew0KICBpZiAodmFsdWUgPT0gbnVsbCkgew0KICAgIHJldHVybiBmYWxzZTsNCiAgfQ0KICBjb25zdCB0eXBlID0gdHlwZW9mIHZhbHVlOw0KICByZXR1cm4gdHlwZSA9PT0gInN0cmluZyIgfHwgdHlwZSA9PT0gIm51bWJlciIgfHwgdHlwZSA9PT0gImJvb2xlYW4iOw0KfQ0KDQpjb25zdCBjc3NWYXJOYW1lRXNjYXBlU3ltYm9sc1JFID0gL1sgISIjJCUmJygpKissLi86Ozw9Pj9AW1xcXF1eYHt8fX5dL2c7DQpmdW5jdGlvbiBnZXRFc2NhcGVkQ3NzVmFyTmFtZShrZXksIGRvdWJsZUVzY2FwZSkgew0KICByZXR1cm4ga2V5LnJlcGxhY2UoDQogICAgY3NzVmFyTmFtZUVzY2FwZVN5bWJvbHNSRSwNCiAgICAocykgPT4gYFxcJHtzfWANCiAgKTsNCn0NCg0KZnVuY3Rpb24gbG9vc2VDb21wYXJlQXJyYXlzKGEsIGIpIHsNCiAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkgcmV0dXJuIGZhbHNlOw0KICBsZXQgZXF1YWwgPSB0cnVlOw0KICBmb3IgKGxldCBpID0gMDsgZXF1YWwgJiYgaSA8IGEubGVuZ3RoOyBpKyspIHsNCiAgICBlcXVhbCA9IGxvb3NlRXF1YWwoYVtpXSwgYltpXSk7DQogIH0NCiAgcmV0dXJuIGVxdWFsOw0KfQ0KZnVuY3Rpb24gbG9vc2VFcXVhbChhLCBiKSB7DQogIGlmIChhID09PSBiKSByZXR1cm4gdHJ1ZTsNCiAgbGV0IGFWYWxpZFR5cGUgPSBpc0RhdGUoYSk7DQogIGxldCBiVmFsaWRUeXBlID0gaXNEYXRlKGIpOw0KICBpZiAoYVZhbGlkVHlwZSB8fCBiVmFsaWRUeXBlKSB7DQogICAgcmV0dXJuIGFWYWxpZFR5cGUgJiYgYlZhbGlkVHlwZSA/IGEuZ2V0VGltZSgpID09PSBiLmdldFRpbWUoKSA6IGZhbHNlOw0KICB9DQogIGFWYWxpZFR5cGUgPSBpc1N5bWJvbChhKTsNCiAgYlZhbGlkVHlwZSA9IGlzU3ltYm9sKGIpOw0KICBpZiAoYVZhbGlkVHlwZSB8fCBiVmFsaWRUeXBlKSB7DQogICAgcmV0dXJuIGEgPT09IGI7DQogIH0NCiAgYVZhbGlkVHlwZSA9IGlzQXJyYXkoYSk7DQogIGJWYWxpZFR5cGUgPSBpc0FycmF5KGIpOw0KICBpZiAoYVZhbGlkVHlwZSB8fCBiVmFsaWRUeXBlKSB7DQogICAgcmV0dXJuIGFWYWxpZFR5cGUgJiYgYlZhbGlkVHlwZSA/IGxvb3NlQ29tcGFyZUFycmF5cyhhLCBiKSA6IGZhbHNlOw0KICB9DQogIGFWYWxpZFR5cGUgPSBpc09iamVjdChhKTsNCiAgYlZhbGlkVHlwZSA9IGlzT2JqZWN0KGIpOw0KICBpZiAoYVZhbGlkVHlwZSB8fCBiVmFsaWRUeXBlKSB7DQogICAgaWYgKCFhVmFsaWRUeXBlIHx8ICFiVmFsaWRUeXBlKSB7DQogICAgICByZXR1cm4gZmFsc2U7DQogICAgfQ0KICAgIGNvbnN0IGFLZXlzQ291bnQgPSBPYmplY3Qua2V5cyhhKS5sZW5ndGg7DQogICAgY29uc3QgYktleXNDb3VudCA9IE9iamVjdC5rZXlzKGIpLmxlbmd0aDsNCiAgICBpZiAoYUtleXNDb3VudCAhPT0gYktleXNDb3VudCkgew0KICAgICAgcmV0dXJuIGZhbHNlOw0KICAgIH0NCiAgICBmb3IgKGNvbnN0IGtleSBpbiBhKSB7DQogICAgICBjb25zdCBhSGFzS2V5ID0gYS5oYXNPd25Qcm9wZXJ0eShrZXkpOw0KICAgICAgY29uc3QgYkhhc0tleSA9IGIuaGFzT3duUHJvcGVydHkoa2V5KTsNCiAgICAgIGlmIChhSGFzS2V5ICYmICFiSGFzS2V5IHx8ICFhSGFzS2V5ICYmIGJIYXNLZXkgfHwgIWxvb3NlRXF1YWwoYVtrZXldLCBiW2tleV0pKSB7DQogICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgcmV0dXJuIFN0cmluZyhhKSA9PT0gU3RyaW5nKGIpOw0KfQ0KZnVuY3Rpb24gbG9vc2VJbmRleE9mKGFyciwgdmFsKSB7DQogIHJldHVybiBhcnIuZmluZEluZGV4KChpdGVtKSA9PiBsb29zZUVxdWFsKGl0ZW0sIHZhbCkpOw0KfQ0KDQpjb25zdCBpc1JlZiQxID0gKHZhbCkgPT4gew0KICByZXR1cm4gISEodmFsICYmIHZhbFsiX192X2lzUmVmIl0gPT09IHRydWUpOw0KfTsNCmNvbnN0IHRvRGlzcGxheVN0cmluZyA9ICh2YWwpID0+IHsNCiAgcmV0dXJuIGlzU3RyaW5nKHZhbCkgPyB2YWwgOiB2YWwgPT0gbnVsbCA/ICIiIDogaXNBcnJheSh2YWwpIHx8IGlzT2JqZWN0KHZhbCkgJiYgKHZhbC50b1N0cmluZyA9PT0gb2JqZWN0VG9TdHJpbmcgfHwgIWlzRnVuY3Rpb24odmFsLnRvU3RyaW5nKSkgPyBpc1JlZiQxKHZhbCkgPyB0b0Rpc3BsYXlTdHJpbmcodmFsLnZhbHVlKSA6IEpTT04uc3RyaW5naWZ5KHZhbCwgcmVwbGFjZXIsIDIpIDogU3RyaW5nKHZhbCk7DQp9Ow0KY29uc3QgcmVwbGFjZXIgPSAoX2tleSwgdmFsKSA9PiB7DQogIGlmIChpc1JlZiQxKHZhbCkpIHsNCiAgICByZXR1cm4gcmVwbGFjZXIoX2tleSwgdmFsLnZhbHVlKTsNCiAgfSBlbHNlIGlmIChpc01hcCh2YWwpKSB7DQogICAgcmV0dXJuIHsNCiAgICAgIFtgTWFwKCR7dmFsLnNpemV9KWBdOiBbLi4udmFsLmVudHJpZXMoKV0ucmVkdWNlKA0KICAgICAgICAoZW50cmllcywgW2tleSwgdmFsMl0sIGkpID0+IHsNCiAgICAgICAgICBlbnRyaWVzW3N0cmluZ2lmeVN5bWJvbChrZXksIGkpICsgIiA9PiJdID0gdmFsMjsNCiAgICAgICAgICByZXR1cm4gZW50cmllczsNCiAgICAgICAgfSwNCiAgICAgICAge30NCiAgICAgICkNCiAgICB9Ow0KICB9IGVsc2UgaWYgKGlzU2V0KHZhbCkpIHsNCiAgICByZXR1cm4gew0KICAgICAgW2BTZXQoJHt2YWwuc2l6ZX0pYF06IFsuLi52YWwudmFsdWVzKCldLm1hcCgodikgPT4gc3RyaW5naWZ5U3ltYm9sKHYpKQ0KICAgIH07DQogIH0gZWxzZSBpZiAoaXNTeW1ib2wodmFsKSkgew0KICAgIHJldHVybiBzdHJpbmdpZnlTeW1ib2wodmFsKTsNCiAgfSBlbHNlIGlmIChpc09iamVjdCh2YWwpICYmICFpc0FycmF5KHZhbCkgJiYgIWlzUGxhaW5PYmplY3QodmFsKSkgew0KICAgIHJldHVybiBTdHJpbmcodmFsKTsNCiAgfQ0KICByZXR1cm4gdmFsOw0KfTsNCmNvbnN0IHN0cmluZ2lmeVN5bWJvbCA9ICh2LCBpID0gIiIpID0+IHsNCiAgdmFyIF9hOw0KICByZXR1cm4gKA0KICAgIC8vIFN5bWJvbC5kZXNjcmlwdGlvbiBpbiBlczIwMTkrIHNvIHdlIG5lZWQgdG8gY2FzdCBoZXJlIHRvIHBhc3MNCiAgICAvLyB0aGUgbGliOiBlczIwMTYgY2hlY2sNCiAgICBpc1N5bWJvbCh2KSA/IGBTeW1ib2woJHsoX2EgPSB2LmRlc2NyaXB0aW9uKSAhPSBudWxsID8gX2EgOiBpfSlgIDogdg0KICApOw0KfTsNCg0KZnVuY3Rpb24gd2FybiQyKG1zZywgLi4uYXJncykgew0KICBjb25zb2xlLndhcm4oYFtWdWUgd2Fybl0gJHttc2d9YCwgLi4uYXJncyk7DQp9DQoNCmxldCBhY3RpdmVFZmZlY3RTY29wZTsNCmNsYXNzIEVmZmVjdFNjb3BlIHsNCiAgY29uc3RydWN0b3IoZGV0YWNoZWQgPSBmYWxzZSkgew0KICAgIHRoaXMuZGV0YWNoZWQgPSBkZXRhY2hlZDsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLl9hY3RpdmUgPSB0cnVlOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbCB0cmFjayBgb25gIGNhbGxzLCBhbGxvdyBgb25gIGNhbGwgbXVsdGlwbGUgdGltZXMNCiAgICAgKi8NCiAgICB0aGlzLl9vbiA9IDA7DQogICAgLyoqDQogICAgICogQGludGVybmFsDQogICAgICovDQogICAgdGhpcy5lZmZlY3RzID0gW107DQogICAgLyoqDQogICAgICogQGludGVybmFsDQogICAgICovDQogICAgdGhpcy5jbGVhbnVwcyA9IFtdOw0KICAgIHRoaXMuX2lzUGF1c2VkID0gZmFsc2U7DQogICAgdGhpcy5wYXJlbnQgPSBhY3RpdmVFZmZlY3RTY29wZTsNCiAgICBpZiAoIWRldGFjaGVkICYmIGFjdGl2ZUVmZmVjdFNjb3BlKSB7DQogICAgICB0aGlzLmluZGV4ID0gKGFjdGl2ZUVmZmVjdFNjb3BlLnNjb3BlcyB8fCAoYWN0aXZlRWZmZWN0U2NvcGUuc2NvcGVzID0gW10pKS5wdXNoKA0KICAgICAgICB0aGlzDQogICAgICApIC0gMTsNCiAgICB9DQogIH0NCiAgZ2V0IGFjdGl2ZSgpIHsNCiAgICByZXR1cm4gdGhpcy5fYWN0aXZlOw0KICB9DQogIHBhdXNlKCkgew0KICAgIGlmICh0aGlzLl9hY3RpdmUpIHsNCiAgICAgIHRoaXMuX2lzUGF1c2VkID0gdHJ1ZTsNCiAgICAgIGxldCBpLCBsOw0KICAgICAgaWYgKHRoaXMuc2NvcGVzKSB7DQogICAgICAgIGZvciAoaSA9IDAsIGwgPSB0aGlzLnNjb3Blcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsNCiAgICAgICAgICB0aGlzLnNjb3Blc1tpXS5wYXVzZSgpOw0KICAgICAgICB9DQogICAgICB9DQogICAgICBmb3IgKGkgPSAwLCBsID0gdGhpcy5lZmZlY3RzLmxlbmd0aDsgaSA8IGw7IGkrKykgew0KICAgICAgICB0aGlzLmVmZmVjdHNbaV0ucGF1c2UoKTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgLyoqDQogICAqIFJlc3VtZXMgdGhlIGVmZmVjdCBzY29wZSwgaW5jbHVkaW5nIGFsbCBjaGlsZCBzY29wZXMgYW5kIGVmZmVjdHMuDQogICAqLw0KICByZXN1bWUoKSB7DQogICAgaWYgKHRoaXMuX2FjdGl2ZSkgew0KICAgICAgaWYgKHRoaXMuX2lzUGF1c2VkKSB7DQogICAgICAgIHRoaXMuX2lzUGF1c2VkID0gZmFsc2U7DQogICAgICAgIGxldCBpLCBsOw0KICAgICAgICBpZiAodGhpcy5zY29wZXMpIHsNCiAgICAgICAgICBmb3IgKGkgPSAwLCBsID0gdGhpcy5zY29wZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7DQogICAgICAgICAgICB0aGlzLnNjb3Blc1tpXS5yZXN1bWUoKTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgZm9yIChpID0gMCwgbCA9IHRoaXMuZWZmZWN0cy5sZW5ndGg7IGkgPCBsOyBpKyspIHsNCiAgICAgICAgICB0aGlzLmVmZmVjdHNbaV0ucmVzdW1lKCk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH0NCiAgcnVuKGZuKSB7DQogICAgaWYgKHRoaXMuX2FjdGl2ZSkgew0KICAgICAgY29uc3QgY3VycmVudEVmZmVjdFNjb3BlID0gYWN0aXZlRWZmZWN0U2NvcGU7DQogICAgICB0cnkgew0KICAgICAgICBhY3RpdmVFZmZlY3RTY29wZSA9IHRoaXM7DQogICAgICAgIHJldHVybiBmbigpOw0KICAgICAgfSBmaW5hbGx5IHsNCiAgICAgICAgYWN0aXZlRWZmZWN0U2NvcGUgPSBjdXJyZW50RWZmZWN0U2NvcGU7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIHdhcm4kMihgY2Fubm90IHJ1biBhbiBpbmFjdGl2ZSBlZmZlY3Qgc2NvcGUuYCk7DQogICAgfQ0KICB9DQogIC8qKg0KICAgKiBUaGlzIHNob3VsZCBvbmx5IGJlIGNhbGxlZCBvbiBub24tZGV0YWNoZWQgc2NvcGVzDQogICAqIEBpbnRlcm5hbA0KICAgKi8NCiAgb24oKSB7DQogICAgaWYgKCsrdGhpcy5fb24gPT09IDEpIHsNCiAgICAgIHRoaXMucHJldlNjb3BlID0gYWN0aXZlRWZmZWN0U2NvcGU7DQogICAgICBhY3RpdmVFZmZlY3RTY29wZSA9IHRoaXM7DQogICAgfQ0KICB9DQogIC8qKg0KICAgKiBUaGlzIHNob3VsZCBvbmx5IGJlIGNhbGxlZCBvbiBub24tZGV0YWNoZWQgc2NvcGVzDQogICAqIEBpbnRlcm5hbA0KICAgKi8NCiAgb2ZmKCkgew0KICAgIGlmICh0aGlzLl9vbiA+IDAgJiYgLS10aGlzLl9vbiA9PT0gMCkgew0KICAgICAgYWN0aXZlRWZmZWN0U2NvcGUgPSB0aGlzLnByZXZTY29wZTsNCiAgICAgIHRoaXMucHJldlNjb3BlID0gdm9pZCAwOw0KICAgIH0NCiAgfQ0KICBzdG9wKGZyb21QYXJlbnQpIHsNCiAgICBpZiAodGhpcy5fYWN0aXZlKSB7DQogICAgICB0aGlzLl9hY3RpdmUgPSBmYWxzZTsNCiAgICAgIGxldCBpLCBsOw0KICAgICAgZm9yIChpID0gMCwgbCA9IHRoaXMuZWZmZWN0cy5sZW5ndGg7IGkgPCBsOyBpKyspIHsNCiAgICAgICAgdGhpcy5lZmZlY3RzW2ldLnN0b3AoKTsNCiAgICAgIH0NCiAgICAgIHRoaXMuZWZmZWN0cy5sZW5ndGggPSAwOw0KICAgICAgZm9yIChpID0gMCwgbCA9IHRoaXMuY2xlYW51cHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7DQogICAgICAgIHRoaXMuY2xlYW51cHNbaV0oKTsNCiAgICAgIH0NCiAgICAgIHRoaXMuY2xlYW51cHMubGVuZ3RoID0gMDsNCiAgICAgIGlmICh0aGlzLnNjb3Blcykgew0KICAgICAgICBmb3IgKGkgPSAwLCBsID0gdGhpcy5zY29wZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7DQogICAgICAgICAgdGhpcy5zY29wZXNbaV0uc3RvcCh0cnVlKTsNCiAgICAgICAgfQ0KICAgICAgICB0aGlzLnNjb3Blcy5sZW5ndGggPSAwOw0KICAgICAgfQ0KICAgICAgaWYgKCF0aGlzLmRldGFjaGVkICYmIHRoaXMucGFyZW50ICYmICFmcm9tUGFyZW50KSB7DQogICAgICAgIGNvbnN0IGxhc3QgPSB0aGlzLnBhcmVudC5zY29wZXMucG9wKCk7DQogICAgICAgIGlmIChsYXN0ICYmIGxhc3QgIT09IHRoaXMpIHsNCiAgICAgICAgICB0aGlzLnBhcmVudC5zY29wZXNbdGhpcy5pbmRleF0gPSBsYXN0Ow0KICAgICAgICAgIGxhc3QuaW5kZXggPSB0aGlzLmluZGV4Ow0KICAgICAgICB9DQogICAgICB9DQogICAgICB0aGlzLnBhcmVudCA9IHZvaWQgMDsNCiAgICB9DQogIH0NCn0NCmZ1bmN0aW9uIGVmZmVjdFNjb3BlKGRldGFjaGVkKSB7DQogIHJldHVybiBuZXcgRWZmZWN0U2NvcGUoZGV0YWNoZWQpOw0KfQ0KZnVuY3Rpb24gZ2V0Q3VycmVudFNjb3BlKCkgew0KICByZXR1cm4gYWN0aXZlRWZmZWN0U2NvcGU7DQp9DQpmdW5jdGlvbiBvblNjb3BlRGlzcG9zZShmbiwgZmFpbFNpbGVudGx5ID0gZmFsc2UpIHsNCiAgaWYgKGFjdGl2ZUVmZmVjdFNjb3BlKSB7DQogICAgYWN0aXZlRWZmZWN0U2NvcGUuY2xlYW51cHMucHVzaChmbik7DQogIH0gZWxzZSBpZiAoIWZhaWxTaWxlbnRseSkgew0KICAgIHdhcm4kMigNCiAgICAgIGBvblNjb3BlRGlzcG9zZSgpIGlzIGNhbGxlZCB3aGVuIHRoZXJlIGlzIG5vIGFjdGl2ZSBlZmZlY3Qgc2NvcGUgdG8gYmUgYXNzb2NpYXRlZCB3aXRoLmANCiAgICApOw0KICB9DQp9DQoNCmxldCBhY3RpdmVTdWI7DQpjb25zdCBwYXVzZWRRdWV1ZUVmZmVjdHMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtTZXQoKTsNCmNsYXNzIFJlYWN0aXZlRWZmZWN0IHsNCiAgY29uc3RydWN0b3IoZm4pIHsNCiAgICB0aGlzLmZuID0gZm47DQogICAgLyoqDQogICAgICogQGludGVybmFsDQogICAgICovDQogICAgdGhpcy5kZXBzID0gdm9pZCAwOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuZGVwc1RhaWwgPSB2b2lkIDA7DQogICAgLyoqDQogICAgICogQGludGVybmFsDQogICAgICovDQogICAgdGhpcy5mbGFncyA9IDEgfCA0Ow0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMubmV4dCA9IHZvaWQgMDsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLmNsZWFudXAgPSB2b2lkIDA7DQogICAgdGhpcy5zY2hlZHVsZXIgPSB2b2lkIDA7DQogICAgaWYgKGFjdGl2ZUVmZmVjdFNjb3BlICYmIGFjdGl2ZUVmZmVjdFNjb3BlLmFjdGl2ZSkgew0KICAgICAgYWN0aXZlRWZmZWN0U2NvcGUuZWZmZWN0cy5wdXNoKHRoaXMpOw0KICAgIH0NCiAgfQ0KICBwYXVzZSgpIHsNCiAgICB0aGlzLmZsYWdzIHw9IDY0Ow0KICB9DQogIHJlc3VtZSgpIHsNCiAgICBpZiAodGhpcy5mbGFncyAmIDY0KSB7DQogICAgICB0aGlzLmZsYWdzICY9IC02NTsNCiAgICAgIGlmIChwYXVzZWRRdWV1ZUVmZmVjdHMuaGFzKHRoaXMpKSB7DQogICAgICAgIHBhdXNlZFF1ZXVlRWZmZWN0cy5kZWxldGUodGhpcyk7DQogICAgICAgIHRoaXMudHJpZ2dlcigpOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICAvKioNCiAgICogQGludGVybmFsDQogICAqLw0KICBub3RpZnkoKSB7DQogICAgaWYgKHRoaXMuZmxhZ3MgJiAyICYmICEodGhpcy5mbGFncyAmIDMyKSkgew0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBpZiAoISh0aGlzLmZsYWdzICYgOCkpIHsNCiAgICAgIGJhdGNoKHRoaXMpOw0KICAgIH0NCiAgfQ0KICBydW4oKSB7DQogICAgaWYgKCEodGhpcy5mbGFncyAmIDEpKSB7DQogICAgICByZXR1cm4gdGhpcy5mbigpOw0KICAgIH0NCiAgICB0aGlzLmZsYWdzIHw9IDI7DQogICAgY2xlYW51cEVmZmVjdCh0aGlzKTsNCiAgICBwcmVwYXJlRGVwcyh0aGlzKTsNCiAgICBjb25zdCBwcmV2RWZmZWN0ID0gYWN0aXZlU3ViOw0KICAgIGNvbnN0IHByZXZTaG91bGRUcmFjayA9IHNob3VsZFRyYWNrOw0KICAgIGFjdGl2ZVN1YiA9IHRoaXM7DQogICAgc2hvdWxkVHJhY2sgPSB0cnVlOw0KICAgIHRyeSB7DQogICAgICByZXR1cm4gdGhpcy5mbigpOw0KICAgIH0gZmluYWxseSB7DQogICAgICBpZiAoYWN0aXZlU3ViICE9PSB0aGlzKSB7DQogICAgICAgIHdhcm4kMigNCiAgICAgICAgICAiQWN0aXZlIGVmZmVjdCB3YXMgbm90IHJlc3RvcmVkIGNvcnJlY3RseSAtIHRoaXMgaXMgbGlrZWx5IGEgVnVlIGludGVybmFsIGJ1Zy4iDQogICAgICAgICk7DQogICAgICB9DQogICAgICBjbGVhbnVwRGVwcyh0aGlzKTsNCiAgICAgIGFjdGl2ZVN1YiA9IHByZXZFZmZlY3Q7DQogICAgICBzaG91bGRUcmFjayA9IHByZXZTaG91bGRUcmFjazsNCiAgICAgIHRoaXMuZmxhZ3MgJj0gLTM7DQogICAgfQ0KICB9DQogIHN0b3AoKSB7DQogICAgaWYgKHRoaXMuZmxhZ3MgJiAxKSB7DQogICAgICBmb3IgKGxldCBsaW5rID0gdGhpcy5kZXBzOyBsaW5rOyBsaW5rID0gbGluay5uZXh0RGVwKSB7DQogICAgICAgIHJlbW92ZVN1YihsaW5rKTsNCiAgICAgIH0NCiAgICAgIHRoaXMuZGVwcyA9IHRoaXMuZGVwc1RhaWwgPSB2b2lkIDA7DQogICAgICBjbGVhbnVwRWZmZWN0KHRoaXMpOw0KICAgICAgdGhpcy5vblN0b3AgJiYgdGhpcy5vblN0b3AoKTsNCiAgICAgIHRoaXMuZmxhZ3MgJj0gLTI7DQogICAgfQ0KICB9DQogIHRyaWdnZXIoKSB7DQogICAgaWYgKHRoaXMuZmxhZ3MgJiA2NCkgew0KICAgICAgcGF1c2VkUXVldWVFZmZlY3RzLmFkZCh0aGlzKTsNCiAgICB9IGVsc2UgaWYgKHRoaXMuc2NoZWR1bGVyKSB7DQogICAgICB0aGlzLnNjaGVkdWxlcigpOw0KICAgIH0gZWxzZSB7DQogICAgICB0aGlzLnJ1bklmRGlydHkoKTsNCiAgICB9DQogIH0NCiAgLyoqDQogICAqIEBpbnRlcm5hbA0KICAgKi8NCiAgcnVuSWZEaXJ0eSgpIHsNCiAgICBpZiAoaXNEaXJ0eSh0aGlzKSkgew0KICAgICAgdGhpcy5ydW4oKTsNCiAgICB9DQogIH0NCiAgZ2V0IGRpcnR5KCkgew0KICAgIHJldHVybiBpc0RpcnR5KHRoaXMpOw0KICB9DQp9DQpsZXQgYmF0Y2hEZXB0aCA9IDA7DQpsZXQgYmF0Y2hlZFN1YjsNCmxldCBiYXRjaGVkQ29tcHV0ZWQ7DQpmdW5jdGlvbiBiYXRjaChzdWIsIGlzQ29tcHV0ZWQgPSBmYWxzZSkgew0KICBzdWIuZmxhZ3MgfD0gODsNCiAgaWYgKGlzQ29tcHV0ZWQpIHsNCiAgICBzdWIubmV4dCA9IGJhdGNoZWRDb21wdXRlZDsNCiAgICBiYXRjaGVkQ29tcHV0ZWQgPSBzdWI7DQogICAgcmV0dXJuOw0KICB9DQogIHN1Yi5uZXh0ID0gYmF0Y2hlZFN1YjsNCiAgYmF0Y2hlZFN1YiA9IHN1YjsNCn0NCmZ1bmN0aW9uIHN0YXJ0QmF0Y2goKSB7DQogIGJhdGNoRGVwdGgrKzsNCn0NCmZ1bmN0aW9uIGVuZEJhdGNoKCkgew0KICBpZiAoLS1iYXRjaERlcHRoID4gMCkgew0KICAgIHJldHVybjsNCiAgfQ0KICBpZiAoYmF0Y2hlZENvbXB1dGVkKSB7DQogICAgbGV0IGUgPSBiYXRjaGVkQ29tcHV0ZWQ7DQogICAgYmF0Y2hlZENvbXB1dGVkID0gdm9pZCAwOw0KICAgIHdoaWxlIChlKSB7DQogICAgICBjb25zdCBuZXh0ID0gZS5uZXh0Ow0KICAgICAgZS5uZXh0ID0gdm9pZCAwOw0KICAgICAgZS5mbGFncyAmPSAtOTsNCiAgICAgIGUgPSBuZXh0Ow0KICAgIH0NCiAgfQ0KICBsZXQgZXJyb3I7DQogIHdoaWxlIChiYXRjaGVkU3ViKSB7DQogICAgbGV0IGUgPSBiYXRjaGVkU3ViOw0KICAgIGJhdGNoZWRTdWIgPSB2b2lkIDA7DQogICAgd2hpbGUgKGUpIHsNCiAgICAgIGNvbnN0IG5leHQgPSBlLm5leHQ7DQogICAgICBlLm5leHQgPSB2b2lkIDA7DQogICAgICBlLmZsYWdzICY9IC05Ow0KICAgICAgaWYgKGUuZmxhZ3MgJiAxKSB7DQogICAgICAgIHRyeSB7DQogICAgICAgICAgOw0KICAgICAgICAgIGUudHJpZ2dlcigpOw0KICAgICAgICB9IGNhdGNoIChlcnIpIHsNCiAgICAgICAgICBpZiAoIWVycm9yKSBlcnJvciA9IGVycjsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgZSA9IG5leHQ7DQogICAgfQ0KICB9DQogIGlmIChlcnJvcikgdGhyb3cgZXJyb3I7DQp9DQpmdW5jdGlvbiBwcmVwYXJlRGVwcyhzdWIpIHsNCiAgZm9yIChsZXQgbGluayA9IHN1Yi5kZXBzOyBsaW5rOyBsaW5rID0gbGluay5uZXh0RGVwKSB7DQogICAgbGluay52ZXJzaW9uID0gLTE7DQogICAgbGluay5wcmV2QWN0aXZlTGluayA9IGxpbmsuZGVwLmFjdGl2ZUxpbms7DQogICAgbGluay5kZXAuYWN0aXZlTGluayA9IGxpbms7DQogIH0NCn0NCmZ1bmN0aW9uIGNsZWFudXBEZXBzKHN1Yikgew0KICBsZXQgaGVhZDsNCiAgbGV0IHRhaWwgPSBzdWIuZGVwc1RhaWw7DQogIGxldCBsaW5rID0gdGFpbDsNCiAgd2hpbGUgKGxpbmspIHsNCiAgICBjb25zdCBwcmV2ID0gbGluay5wcmV2RGVwOw0KICAgIGlmIChsaW5rLnZlcnNpb24gPT09IC0xKSB7DQogICAgICBpZiAobGluayA9PT0gdGFpbCkgdGFpbCA9IHByZXY7DQogICAgICByZW1vdmVTdWIobGluayk7DQogICAgICByZW1vdmVEZXAobGluayk7DQogICAgfSBlbHNlIHsNCiAgICAgIGhlYWQgPSBsaW5rOw0KICAgIH0NCiAgICBsaW5rLmRlcC5hY3RpdmVMaW5rID0gbGluay5wcmV2QWN0aXZlTGluazsNCiAgICBsaW5rLnByZXZBY3RpdmVMaW5rID0gdm9pZCAwOw0KICAgIGxpbmsgPSBwcmV2Ow0KICB9DQogIHN1Yi5kZXBzID0gaGVhZDsNCiAgc3ViLmRlcHNUYWlsID0gdGFpbDsNCn0NCmZ1bmN0aW9uIGlzRGlydHkoc3ViKSB7DQogIGZvciAobGV0IGxpbmsgPSBzdWIuZGVwczsgbGluazsgbGluayA9IGxpbmsubmV4dERlcCkgew0KICAgIGlmIChsaW5rLmRlcC52ZXJzaW9uICE9PSBsaW5rLnZlcnNpb24gfHwgbGluay5kZXAuY29tcHV0ZWQgJiYgKHJlZnJlc2hDb21wdXRlZChsaW5rLmRlcC5jb21wdXRlZCkgfHwgbGluay5kZXAudmVyc2lvbiAhPT0gbGluay52ZXJzaW9uKSkgew0KICAgICAgcmV0dXJuIHRydWU7DQogICAgfQ0KICB9DQogIGlmIChzdWIuX2RpcnR5KSB7DQogICAgcmV0dXJuIHRydWU7DQogIH0NCiAgcmV0dXJuIGZhbHNlOw0KfQ0KZnVuY3Rpb24gcmVmcmVzaENvbXB1dGVkKGNvbXB1dGVkKSB7DQogIGlmIChjb21wdXRlZC5mbGFncyAmIDQgJiYgIShjb21wdXRlZC5mbGFncyAmIDE2KSkgew0KICAgIHJldHVybjsNCiAgfQ0KICBjb21wdXRlZC5mbGFncyAmPSAtMTc7DQogIGlmIChjb21wdXRlZC5nbG9iYWxWZXJzaW9uID09PSBnbG9iYWxWZXJzaW9uKSB7DQogICAgcmV0dXJuOw0KICB9DQogIGNvbXB1dGVkLmdsb2JhbFZlcnNpb24gPSBnbG9iYWxWZXJzaW9uOw0KICBpZiAoIWNvbXB1dGVkLmlzU1NSICYmIGNvbXB1dGVkLmZsYWdzICYgMTI4ICYmICghY29tcHV0ZWQuZGVwcyAmJiAhY29tcHV0ZWQuX2RpcnR5IHx8ICFpc0RpcnR5KGNvbXB1dGVkKSkpIHsNCiAgICByZXR1cm47DQogIH0NCiAgY29tcHV0ZWQuZmxhZ3MgfD0gMjsNCiAgY29uc3QgZGVwID0gY29tcHV0ZWQuZGVwOw0KICBjb25zdCBwcmV2U3ViID0gYWN0aXZlU3ViOw0KICBjb25zdCBwcmV2U2hvdWxkVHJhY2sgPSBzaG91bGRUcmFjazsNCiAgYWN0aXZlU3ViID0gY29tcHV0ZWQ7DQogIHNob3VsZFRyYWNrID0gdHJ1ZTsNCiAgdHJ5IHsNCiAgICBwcmVwYXJlRGVwcyhjb21wdXRlZCk7DQogICAgY29uc3QgdmFsdWUgPSBjb21wdXRlZC5mbihjb21wdXRlZC5fdmFsdWUpOw0KICAgIGlmIChkZXAudmVyc2lvbiA9PT0gMCB8fCBoYXNDaGFuZ2VkKHZhbHVlLCBjb21wdXRlZC5fdmFsdWUpKSB7DQogICAgICBjb21wdXRlZC5mbGFncyB8PSAxMjg7DQogICAgICBjb21wdXRlZC5fdmFsdWUgPSB2YWx1ZTsNCiAgICAgIGRlcC52ZXJzaW9uKys7DQogICAgfQ0KICB9IGNhdGNoIChlcnIpIHsNCiAgICBkZXAudmVyc2lvbisrOw0KICAgIHRocm93IGVycjsNCiAgfSBmaW5hbGx5IHsNCiAgICBhY3RpdmVTdWIgPSBwcmV2U3ViOw0KICAgIHNob3VsZFRyYWNrID0gcHJldlNob3VsZFRyYWNrOw0KICAgIGNsZWFudXBEZXBzKGNvbXB1dGVkKTsNCiAgICBjb21wdXRlZC5mbGFncyAmPSAtMzsNCiAgfQ0KfQ0KZnVuY3Rpb24gcmVtb3ZlU3ViKGxpbmssIHNvZnQgPSBmYWxzZSkgew0KICBjb25zdCB7IGRlcCwgcHJldlN1YiwgbmV4dFN1YiB9ID0gbGluazsNCiAgaWYgKHByZXZTdWIpIHsNCiAgICBwcmV2U3ViLm5leHRTdWIgPSBuZXh0U3ViOw0KICAgIGxpbmsucHJldlN1YiA9IHZvaWQgMDsNCiAgfQ0KICBpZiAobmV4dFN1Yikgew0KICAgIG5leHRTdWIucHJldlN1YiA9IHByZXZTdWI7DQogICAgbGluay5uZXh0U3ViID0gdm9pZCAwOw0KICB9DQogIGlmIChkZXAuc3Vic0hlYWQgPT09IGxpbmspIHsNCiAgICBkZXAuc3Vic0hlYWQgPSBuZXh0U3ViOw0KICB9DQogIGlmIChkZXAuc3VicyA9PT0gbGluaykgew0KICAgIGRlcC5zdWJzID0gcHJldlN1YjsNCiAgICBpZiAoIXByZXZTdWIgJiYgZGVwLmNvbXB1dGVkKSB7DQogICAgICBkZXAuY29tcHV0ZWQuZmxhZ3MgJj0gLTU7DQogICAgICBmb3IgKGxldCBsID0gZGVwLmNvbXB1dGVkLmRlcHM7IGw7IGwgPSBsLm5leHREZXApIHsNCiAgICAgICAgcmVtb3ZlU3ViKGwsIHRydWUpOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICBpZiAoIXNvZnQgJiYgIS0tZGVwLnNjICYmIGRlcC5tYXApIHsNCiAgICBkZXAubWFwLmRlbGV0ZShkZXAua2V5KTsNCiAgfQ0KfQ0KZnVuY3Rpb24gcmVtb3ZlRGVwKGxpbmspIHsNCiAgY29uc3QgeyBwcmV2RGVwLCBuZXh0RGVwIH0gPSBsaW5rOw0KICBpZiAocHJldkRlcCkgew0KICAgIHByZXZEZXAubmV4dERlcCA9IG5leHREZXA7DQogICAgbGluay5wcmV2RGVwID0gdm9pZCAwOw0KICB9DQogIGlmIChuZXh0RGVwKSB7DQogICAgbmV4dERlcC5wcmV2RGVwID0gcHJldkRlcDsNCiAgICBsaW5rLm5leHREZXAgPSB2b2lkIDA7DQogIH0NCn0NCmZ1bmN0aW9uIGVmZmVjdChmbiwgb3B0aW9ucykgew0KICBpZiAoZm4uZWZmZWN0IGluc3RhbmNlb2YgUmVhY3RpdmVFZmZlY3QpIHsNCiAgICBmbiA9IGZuLmVmZmVjdC5mbjsNCiAgfQ0KICBjb25zdCBlID0gbmV3IFJlYWN0aXZlRWZmZWN0KGZuKTsNCiAgaWYgKG9wdGlvbnMpIHsNCiAgICBleHRlbmQoZSwgb3B0aW9ucyk7DQogIH0NCiAgdHJ5IHsNCiAgICBlLnJ1bigpOw0KICB9IGNhdGNoIChlcnIpIHsNCiAgICBlLnN0b3AoKTsNCiAgICB0aHJvdyBlcnI7DQogIH0NCiAgY29uc3QgcnVubmVyID0gZS5ydW4uYmluZChlKTsNCiAgcnVubmVyLmVmZmVjdCA9IGU7DQogIHJldHVybiBydW5uZXI7DQp9DQpmdW5jdGlvbiBzdG9wKHJ1bm5lcikgew0KICBydW5uZXIuZWZmZWN0LnN0b3AoKTsNCn0NCmxldCBzaG91bGRUcmFjayA9IHRydWU7DQpjb25zdCB0cmFja1N0YWNrID0gW107DQpmdW5jdGlvbiBwYXVzZVRyYWNraW5nKCkgew0KICB0cmFja1N0YWNrLnB1c2goc2hvdWxkVHJhY2spOw0KICBzaG91bGRUcmFjayA9IGZhbHNlOw0KfQ0KZnVuY3Rpb24gcmVzZXRUcmFja2luZygpIHsNCiAgY29uc3QgbGFzdCA9IHRyYWNrU3RhY2sucG9wKCk7DQogIHNob3VsZFRyYWNrID0gbGFzdCA9PT0gdm9pZCAwID8gdHJ1ZSA6IGxhc3Q7DQp9DQpmdW5jdGlvbiBjbGVhbnVwRWZmZWN0KGUpIHsNCiAgY29uc3QgeyBjbGVhbnVwIH0gPSBlOw0KICBlLmNsZWFudXAgPSB2b2lkIDA7DQogIGlmIChjbGVhbnVwKSB7DQogICAgY29uc3QgcHJldlN1YiA9IGFjdGl2ZVN1YjsNCiAgICBhY3RpdmVTdWIgPSB2b2lkIDA7DQogICAgdHJ5IHsNCiAgICAgIGNsZWFudXAoKTsNCiAgICB9IGZpbmFsbHkgew0KICAgICAgYWN0aXZlU3ViID0gcHJldlN1YjsNCiAgICB9DQogIH0NCn0NCg0KbGV0IGdsb2JhbFZlcnNpb24gPSAwOw0KY2xhc3MgTGluayB7DQogIGNvbnN0cnVjdG9yKHN1YiwgZGVwKSB7DQogICAgdGhpcy5zdWIgPSBzdWI7DQogICAgdGhpcy5kZXAgPSBkZXA7DQogICAgdGhpcy52ZXJzaW9uID0gZGVwLnZlcnNpb247DQogICAgdGhpcy5uZXh0RGVwID0gdGhpcy5wcmV2RGVwID0gdGhpcy5uZXh0U3ViID0gdGhpcy5wcmV2U3ViID0gdGhpcy5wcmV2QWN0aXZlTGluayA9IHZvaWQgMDsNCiAgfQ0KfQ0KY2xhc3MgRGVwIHsNCiAgLy8gVE9ETyBpc29sYXRlZERlY2xhcmF0aW9ucyAiX192X3NraXAiDQogIGNvbnN0cnVjdG9yKGNvbXB1dGVkKSB7DQogICAgdGhpcy5jb21wdXRlZCA9IGNvbXB1dGVkOw0KICAgIHRoaXMudmVyc2lvbiA9IDA7DQogICAgLyoqDQogICAgICogTGluayBiZXR3ZWVuIHRoaXMgZGVwIGFuZCB0aGUgY3VycmVudCBhY3RpdmUgZWZmZWN0DQogICAgICovDQogICAgdGhpcy5hY3RpdmVMaW5rID0gdm9pZCAwOw0KICAgIC8qKg0KICAgICAqIERvdWJseSBsaW5rZWQgbGlzdCByZXByZXNlbnRpbmcgdGhlIHN1YnNjcmliaW5nIGVmZmVjdHMgKHRhaWwpDQogICAgICovDQogICAgdGhpcy5zdWJzID0gdm9pZCAwOw0KICAgIC8qKg0KICAgICAqIEZvciBvYmplY3QgcHJvcGVydHkgZGVwcyBjbGVhbnVwDQogICAgICovDQogICAgdGhpcy5tYXAgPSB2b2lkIDA7DQogICAgdGhpcy5rZXkgPSB2b2lkIDA7DQogICAgLyoqDQogICAgICogU3Vic2NyaWJlciBjb3VudGVyDQogICAgICovDQogICAgdGhpcy5zYyA9IDA7DQogICAgLyoqDQogICAgICogQGludGVybmFsDQogICAgICovDQogICAgdGhpcy5fX3Zfc2tpcCA9IHRydWU7DQogICAgew0KICAgICAgdGhpcy5zdWJzSGVhZCA9IHZvaWQgMDsNCiAgICB9DQogIH0NCiAgdHJhY2soZGVidWdJbmZvKSB7DQogICAgaWYgKCFhY3RpdmVTdWIgfHwgIXNob3VsZFRyYWNrIHx8IGFjdGl2ZVN1YiA9PT0gdGhpcy5jb21wdXRlZCkgew0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBsZXQgbGluayA9IHRoaXMuYWN0aXZlTGluazsNCiAgICBpZiAobGluayA9PT0gdm9pZCAwIHx8IGxpbmsuc3ViICE9PSBhY3RpdmVTdWIpIHsNCiAgICAgIGxpbmsgPSB0aGlzLmFjdGl2ZUxpbmsgPSBuZXcgTGluayhhY3RpdmVTdWIsIHRoaXMpOw0KICAgICAgaWYgKCFhY3RpdmVTdWIuZGVwcykgew0KICAgICAgICBhY3RpdmVTdWIuZGVwcyA9IGFjdGl2ZVN1Yi5kZXBzVGFpbCA9IGxpbms7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBsaW5rLnByZXZEZXAgPSBhY3RpdmVTdWIuZGVwc1RhaWw7DQogICAgICAgIGFjdGl2ZVN1Yi5kZXBzVGFpbC5uZXh0RGVwID0gbGluazsNCiAgICAgICAgYWN0aXZlU3ViLmRlcHNUYWlsID0gbGluazsNCiAgICAgIH0NCiAgICAgIGFkZFN1YihsaW5rKTsNCiAgICB9IGVsc2UgaWYgKGxpbmsudmVyc2lvbiA9PT0gLTEpIHsNCiAgICAgIGxpbmsudmVyc2lvbiA9IHRoaXMudmVyc2lvbjsNCiAgICAgIGlmIChsaW5rLm5leHREZXApIHsNCiAgICAgICAgY29uc3QgbmV4dCA9IGxpbmsubmV4dERlcDsNCiAgICAgICAgbmV4dC5wcmV2RGVwID0gbGluay5wcmV2RGVwOw0KICAgICAgICBpZiAobGluay5wcmV2RGVwKSB7DQogICAgICAgICAgbGluay5wcmV2RGVwLm5leHREZXAgPSBuZXh0Ow0KICAgICAgICB9DQogICAgICAgIGxpbmsucHJldkRlcCA9IGFjdGl2ZVN1Yi5kZXBzVGFpbDsNCiAgICAgICAgbGluay5uZXh0RGVwID0gdm9pZCAwOw0KICAgICAgICBhY3RpdmVTdWIuZGVwc1RhaWwubmV4dERlcCA9IGxpbms7DQogICAgICAgIGFjdGl2ZVN1Yi5kZXBzVGFpbCA9IGxpbms7DQogICAgICAgIGlmIChhY3RpdmVTdWIuZGVwcyA9PT0gbGluaykgew0KICAgICAgICAgIGFjdGl2ZVN1Yi5kZXBzID0gbmV4dDsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgICBpZiAoYWN0aXZlU3ViLm9uVHJhY2spIHsNCiAgICAgIGFjdGl2ZVN1Yi5vblRyYWNrKA0KICAgICAgICBleHRlbmQoDQogICAgICAgICAgew0KICAgICAgICAgICAgZWZmZWN0OiBhY3RpdmVTdWINCiAgICAgICAgICB9LA0KICAgICAgICAgIGRlYnVnSW5mbw0KICAgICAgICApDQogICAgICApOw0KICAgIH0NCiAgICByZXR1cm4gbGluazsNCiAgfQ0KICB0cmlnZ2VyKGRlYnVnSW5mbykgew0KICAgIHRoaXMudmVyc2lvbisrOw0KICAgIGdsb2JhbFZlcnNpb24rKzsNCiAgICB0aGlzLm5vdGlmeShkZWJ1Z0luZm8pOw0KICB9DQogIG5vdGlmeShkZWJ1Z0luZm8pIHsNCiAgICBzdGFydEJhdGNoKCk7DQogICAgdHJ5IHsNCiAgICAgIGlmICh0cnVlKSB7DQogICAgICAgIGZvciAobGV0IGhlYWQgPSB0aGlzLnN1YnNIZWFkOyBoZWFkOyBoZWFkID0gaGVhZC5uZXh0U3ViKSB7DQogICAgICAgICAgaWYgKGhlYWQuc3ViLm9uVHJpZ2dlciAmJiAhKGhlYWQuc3ViLmZsYWdzICYgOCkpIHsNCiAgICAgICAgICAgIGhlYWQuc3ViLm9uVHJpZ2dlcigNCiAgICAgICAgICAgICAgZXh0ZW5kKA0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgIGVmZmVjdDogaGVhZC5zdWINCiAgICAgICAgICAgICAgICB9LA0KICAgICAgICAgICAgICAgIGRlYnVnSW5mbw0KICAgICAgICAgICAgICApDQogICAgICAgICAgICApOw0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgZm9yIChsZXQgbGluayA9IHRoaXMuc3ViczsgbGluazsgbGluayA9IGxpbmsucHJldlN1Yikgew0KICAgICAgICBpZiAobGluay5zdWIubm90aWZ5KCkpIHsNCiAgICAgICAgICA7DQogICAgICAgICAgbGluay5zdWIuZGVwLm5vdGlmeSgpOw0KICAgICAgICB9DQogICAgICB9DQogICAgfSBmaW5hbGx5IHsNCiAgICAgIGVuZEJhdGNoKCk7DQogICAgfQ0KICB9DQp9DQpmdW5jdGlvbiBhZGRTdWIobGluaykgew0KICBsaW5rLmRlcC5zYysrOw0KICBpZiAobGluay5zdWIuZmxhZ3MgJiA0KSB7DQogICAgY29uc3QgY29tcHV0ZWQgPSBsaW5rLmRlcC5jb21wdXRlZDsNCiAgICBpZiAoY29tcHV0ZWQgJiYgIWxpbmsuZGVwLnN1YnMpIHsNCiAgICAgIGNvbXB1dGVkLmZsYWdzIHw9IDQgfCAxNjsNCiAgICAgIGZvciAobGV0IGwgPSBjb21wdXRlZC5kZXBzOyBsOyBsID0gbC5uZXh0RGVwKSB7DQogICAgICAgIGFkZFN1YihsKTsNCiAgICAgIH0NCiAgICB9DQogICAgY29uc3QgY3VycmVudFRhaWwgPSBsaW5rLmRlcC5zdWJzOw0KICAgIGlmIChjdXJyZW50VGFpbCAhPT0gbGluaykgew0KICAgICAgbGluay5wcmV2U3ViID0gY3VycmVudFRhaWw7DQogICAgICBpZiAoY3VycmVudFRhaWwpIGN1cnJlbnRUYWlsLm5leHRTdWIgPSBsaW5rOw0KICAgIH0NCiAgICBpZiAobGluay5kZXAuc3Vic0hlYWQgPT09IHZvaWQgMCkgew0KICAgICAgbGluay5kZXAuc3Vic0hlYWQgPSBsaW5rOw0KICAgIH0NCiAgICBsaW5rLmRlcC5zdWJzID0gbGluazsNCiAgfQ0KfQ0KY29uc3QgdGFyZ2V0TWFwID0gLyogQF9fUFVSRV9fICovIG5ldyBXZWFrTWFwKCk7DQpjb25zdCBJVEVSQVRFX0tFWSA9IFN5bWJvbCgNCiAgIk9iamVjdCBpdGVyYXRlIiANCik7DQpjb25zdCBNQVBfS0VZX0lURVJBVEVfS0VZID0gU3ltYm9sKA0KICAiTWFwIGtleXMgaXRlcmF0ZSIgDQopOw0KY29uc3QgQVJSQVlfSVRFUkFURV9LRVkgPSBTeW1ib2woDQogICJBcnJheSBpdGVyYXRlIiANCik7DQpmdW5jdGlvbiB0cmFjayh0YXJnZXQsIHR5cGUsIGtleSkgew0KICBpZiAoc2hvdWxkVHJhY2sgJiYgYWN0aXZlU3ViKSB7DQogICAgbGV0IGRlcHNNYXAgPSB0YXJnZXRNYXAuZ2V0KHRhcmdldCk7DQogICAgaWYgKCFkZXBzTWFwKSB7DQogICAgICB0YXJnZXRNYXAuc2V0KHRhcmdldCwgZGVwc01hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCkpOw0KICAgIH0NCiAgICBsZXQgZGVwID0gZGVwc01hcC5nZXQoa2V5KTsNCiAgICBpZiAoIWRlcCkgew0KICAgICAgZGVwc01hcC5zZXQoa2V5LCBkZXAgPSBuZXcgRGVwKCkpOw0KICAgICAgZGVwLm1hcCA9IGRlcHNNYXA7DQogICAgICBkZXAua2V5ID0ga2V5Ow0KICAgIH0NCiAgICB7DQogICAgICBkZXAudHJhY2soew0KICAgICAgICB0YXJnZXQsDQogICAgICAgIHR5cGUsDQogICAgICAgIGtleQ0KICAgICAgfSk7DQogICAgfQ0KICB9DQp9DQpmdW5jdGlvbiB0cmlnZ2VyKHRhcmdldCwgdHlwZSwga2V5LCBuZXdWYWx1ZSwgb2xkVmFsdWUsIG9sZFRhcmdldCkgew0KICBjb25zdCBkZXBzTWFwID0gdGFyZ2V0TWFwLmdldCh0YXJnZXQpOw0KICBpZiAoIWRlcHNNYXApIHsNCiAgICBnbG9iYWxWZXJzaW9uKys7DQogICAgcmV0dXJuOw0KICB9DQogIGNvbnN0IHJ1biA9IChkZXApID0+IHsNCiAgICBpZiAoZGVwKSB7DQogICAgICB7DQogICAgICAgIGRlcC50cmlnZ2VyKHsNCiAgICAgICAgICB0YXJnZXQsDQogICAgICAgICAgdHlwZSwNCiAgICAgICAgICBrZXksDQogICAgICAgICAgbmV3VmFsdWUsDQogICAgICAgICAgb2xkVmFsdWUsDQogICAgICAgICAgb2xkVGFyZ2V0DQogICAgICAgIH0pOw0KICAgICAgfQ0KICAgIH0NCiAgfTsNCiAgc3RhcnRCYXRjaCgpOw0KICBpZiAodHlwZSA9PT0gImNsZWFyIikgew0KICAgIGRlcHNNYXAuZm9yRWFjaChydW4pOw0KICB9IGVsc2Ugew0KICAgIGNvbnN0IHRhcmdldElzQXJyYXkgPSBpc0FycmF5KHRhcmdldCk7DQogICAgY29uc3QgaXNBcnJheUluZGV4ID0gdGFyZ2V0SXNBcnJheSAmJiBpc0ludGVnZXJLZXkoa2V5KTsNCiAgICBpZiAodGFyZ2V0SXNBcnJheSAmJiBrZXkgPT09ICJsZW5ndGgiKSB7DQogICAgICBjb25zdCBuZXdMZW5ndGggPSBOdW1iZXIobmV3VmFsdWUpOw0KICAgICAgZGVwc01hcC5mb3JFYWNoKChkZXAsIGtleTIpID0+IHsNCiAgICAgICAgaWYgKGtleTIgPT09ICJsZW5ndGgiIHx8IGtleTIgPT09IEFSUkFZX0lURVJBVEVfS0VZIHx8ICFpc1N5bWJvbChrZXkyKSAmJiBrZXkyID49IG5ld0xlbmd0aCkgew0KICAgICAgICAgIHJ1bihkZXApOw0KICAgICAgICB9DQogICAgICB9KTsNCiAgICB9IGVsc2Ugew0KICAgICAgaWYgKGtleSAhPT0gdm9pZCAwIHx8IGRlcHNNYXAuaGFzKHZvaWQgMCkpIHsNCiAgICAgICAgcnVuKGRlcHNNYXAuZ2V0KGtleSkpOw0KICAgICAgfQ0KICAgICAgaWYgKGlzQXJyYXlJbmRleCkgew0KICAgICAgICBydW4oZGVwc01hcC5nZXQoQVJSQVlfSVRFUkFURV9LRVkpKTsNCiAgICAgIH0NCiAgICAgIHN3aXRjaCAodHlwZSkgew0KICAgICAgICBjYXNlICJhZGQiOg0KICAgICAgICAgIGlmICghdGFyZ2V0SXNBcnJheSkgew0KICAgICAgICAgICAgcnVuKGRlcHNNYXAuZ2V0KElURVJBVEVfS0VZKSk7DQogICAgICAgICAgICBpZiAoaXNNYXAodGFyZ2V0KSkgew0KICAgICAgICAgICAgICBydW4oZGVwc01hcC5nZXQoTUFQX0tFWV9JVEVSQVRFX0tFWSkpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgIH0gZWxzZSBpZiAoaXNBcnJheUluZGV4KSB7DQogICAgICAgICAgICBydW4oZGVwc01hcC5nZXQoImxlbmd0aCIpKTsNCiAgICAgICAgICB9DQogICAgICAgICAgYnJlYWs7DQogICAgICAgIGNhc2UgImRlbGV0ZSI6DQogICAgICAgICAgaWYgKCF0YXJnZXRJc0FycmF5KSB7DQogICAgICAgICAgICBydW4oZGVwc01hcC5nZXQoSVRFUkFURV9LRVkpKTsNCiAgICAgICAgICAgIGlmIChpc01hcCh0YXJnZXQpKSB7DQogICAgICAgICAgICAgIHJ1bihkZXBzTWFwLmdldChNQVBfS0VZX0lURVJBVEVfS0VZKSk7DQogICAgICAgICAgICB9DQogICAgICAgICAgfQ0KICAgICAgICAgIGJyZWFrOw0KICAgICAgICBjYXNlICJzZXQiOg0KICAgICAgICAgIGlmIChpc01hcCh0YXJnZXQpKSB7DQogICAgICAgICAgICBydW4oZGVwc01hcC5nZXQoSVRFUkFURV9LRVkpKTsNCiAgICAgICAgICB9DQogICAgICAgICAgYnJlYWs7DQogICAgICB9DQogICAgfQ0KICB9DQogIGVuZEJhdGNoKCk7DQp9DQpmdW5jdGlvbiBnZXREZXBGcm9tUmVhY3RpdmUob2JqZWN0LCBrZXkpIHsNCiAgY29uc3QgZGVwTWFwID0gdGFyZ2V0TWFwLmdldChvYmplY3QpOw0KICByZXR1cm4gZGVwTWFwICYmIGRlcE1hcC5nZXQoa2V5KTsNCn0NCg0KZnVuY3Rpb24gcmVhY3RpdmVSZWFkQXJyYXkoYXJyYXkpIHsNCiAgY29uc3QgcmF3ID0gdG9SYXcoYXJyYXkpOw0KICBpZiAocmF3ID09PSBhcnJheSkgcmV0dXJuIHJhdzsNCiAgdHJhY2socmF3LCAiaXRlcmF0ZSIsIEFSUkFZX0lURVJBVEVfS0VZKTsNCiAgcmV0dXJuIGlzU2hhbGxvdyhhcnJheSkgPyByYXcgOiByYXcubWFwKHRvUmVhY3RpdmUpOw0KfQ0KZnVuY3Rpb24gc2hhbGxvd1JlYWRBcnJheShhcnIpIHsNCiAgdHJhY2soYXJyID0gdG9SYXcoYXJyKSwgIml0ZXJhdGUiLCBBUlJBWV9JVEVSQVRFX0tFWSk7DQogIHJldHVybiBhcnI7DQp9DQpjb25zdCBhcnJheUluc3RydW1lbnRhdGlvbnMgPSB7DQogIF9fcHJvdG9fXzogbnVsbCwNCiAgW1N5bWJvbC5pdGVyYXRvcl0oKSB7DQogICAgcmV0dXJuIGl0ZXJhdG9yKHRoaXMsIFN5bWJvbC5pdGVyYXRvciwgdG9SZWFjdGl2ZSk7DQogIH0sDQogIGNvbmNhdCguLi5hcmdzKSB7DQogICAgcmV0dXJuIHJlYWN0aXZlUmVhZEFycmF5KHRoaXMpLmNvbmNhdCgNCiAgICAgIC4uLmFyZ3MubWFwKCh4KSA9PiBpc0FycmF5KHgpID8gcmVhY3RpdmVSZWFkQXJyYXkoeCkgOiB4KQ0KICAgICk7DQogIH0sDQogIGVudHJpZXMoKSB7DQogICAgcmV0dXJuIGl0ZXJhdG9yKHRoaXMsICJlbnRyaWVzIiwgKHZhbHVlKSA9PiB7DQogICAgICB2YWx1ZVsxXSA9IHRvUmVhY3RpdmUodmFsdWVbMV0pOw0KICAgICAgcmV0dXJuIHZhbHVlOw0KICAgIH0pOw0KICB9LA0KICBldmVyeShmbiwgdGhpc0FyZykgew0KICAgIHJldHVybiBhcHBseSh0aGlzLCAiZXZlcnkiLCBmbiwgdGhpc0FyZywgdm9pZCAwLCBhcmd1bWVudHMpOw0KICB9LA0KICBmaWx0ZXIoZm4sIHRoaXNBcmcpIHsNCiAgICByZXR1cm4gYXBwbHkodGhpcywgImZpbHRlciIsIGZuLCB0aGlzQXJnLCAodikgPT4gdi5tYXAodG9SZWFjdGl2ZSksIGFyZ3VtZW50cyk7DQogIH0sDQogIGZpbmQoZm4sIHRoaXNBcmcpIHsNCiAgICByZXR1cm4gYXBwbHkodGhpcywgImZpbmQiLCBmbiwgdGhpc0FyZywgdG9SZWFjdGl2ZSwgYXJndW1lbnRzKTsNCiAgfSwNCiAgZmluZEluZGV4KGZuLCB0aGlzQXJnKSB7DQogICAgcmV0dXJuIGFwcGx5KHRoaXMsICJmaW5kSW5kZXgiLCBmbiwgdGhpc0FyZywgdm9pZCAwLCBhcmd1bWVudHMpOw0KICB9LA0KICBmaW5kTGFzdChmbiwgdGhpc0FyZykgew0KICAgIHJldHVybiBhcHBseSh0aGlzLCAiZmluZExhc3QiLCBmbiwgdGhpc0FyZywgdG9SZWFjdGl2ZSwgYXJndW1lbnRzKTsNCiAgfSwNCiAgZmluZExhc3RJbmRleChmbiwgdGhpc0FyZykgew0KICAgIHJldHVybiBhcHBseSh0aGlzLCAiZmluZExhc3RJbmRleCIsIGZuLCB0aGlzQXJnLCB2b2lkIDAsIGFyZ3VtZW50cyk7DQogIH0sDQogIC8vIGZsYXQsIGZsYXRNYXAgY291bGQgYmVuZWZpdCBmcm9tIEFSUkFZX0lURVJBVEUgYnV0IGFyZSBub3Qgc3RyYWlnaHQtZm9yd2FyZCB0byBpbXBsZW1lbnQNCiAgZm9yRWFjaChmbiwgdGhpc0FyZykgew0KICAgIHJldHVybiBhcHBseSh0aGlzLCAiZm9yRWFjaCIsIGZuLCB0aGlzQXJnLCB2b2lkIDAsIGFyZ3VtZW50cyk7DQogIH0sDQogIGluY2x1ZGVzKC4uLmFyZ3MpIHsNCiAgICByZXR1cm4gc2VhcmNoUHJveHkodGhpcywgImluY2x1ZGVzIiwgYXJncyk7DQogIH0sDQogIGluZGV4T2YoLi4uYXJncykgew0KICAgIHJldHVybiBzZWFyY2hQcm94eSh0aGlzLCAiaW5kZXhPZiIsIGFyZ3MpOw0KICB9LA0KICBqb2luKHNlcGFyYXRvcikgew0KICAgIHJldHVybiByZWFjdGl2ZVJlYWRBcnJheSh0aGlzKS5qb2luKHNlcGFyYXRvcik7DQogIH0sDQogIC8vIGtleXMoKSBpdGVyYXRvciBvbmx5IHJlYWRzIGBsZW5ndGhgLCBubyBvcHRpbWlzYXRpb24gcmVxdWlyZWQNCiAgbGFzdEluZGV4T2YoLi4uYXJncykgew0KICAgIHJldHVybiBzZWFyY2hQcm94eSh0aGlzLCAibGFzdEluZGV4T2YiLCBhcmdzKTsNCiAgfSwNCiAgbWFwKGZuLCB0aGlzQXJnKSB7DQogICAgcmV0dXJuIGFwcGx5KHRoaXMsICJtYXAiLCBmbiwgdGhpc0FyZywgdm9pZCAwLCBhcmd1bWVudHMpOw0KICB9LA0KICBwb3AoKSB7DQogICAgcmV0dXJuIG5vVHJhY2tpbmcodGhpcywgInBvcCIpOw0KICB9LA0KICBwdXNoKC4uLmFyZ3MpIHsNCiAgICByZXR1cm4gbm9UcmFja2luZyh0aGlzLCAicHVzaCIsIGFyZ3MpOw0KICB9LA0KICByZWR1Y2UoZm4sIC4uLmFyZ3MpIHsNCiAgICByZXR1cm4gcmVkdWNlKHRoaXMsICJyZWR1Y2UiLCBmbiwgYXJncyk7DQogIH0sDQogIHJlZHVjZVJpZ2h0KGZuLCAuLi5hcmdzKSB7DQogICAgcmV0dXJuIHJlZHVjZSh0aGlzLCAicmVkdWNlUmlnaHQiLCBmbiwgYXJncyk7DQogIH0sDQogIHNoaWZ0KCkgew0KICAgIHJldHVybiBub1RyYWNraW5nKHRoaXMsICJzaGlmdCIpOw0KICB9LA0KICAvLyBzbGljZSBjb3VsZCB1c2UgQVJSQVlfSVRFUkFURSBidXQgYWxzbyBzZWVtcyB0byBiZWcgZm9yIHJhbmdlIHRyYWNraW5nDQogIHNvbWUoZm4sIHRoaXNBcmcpIHsNCiAgICByZXR1cm4gYXBwbHkodGhpcywgInNvbWUiLCBmbiwgdGhpc0FyZywgdm9pZCAwLCBhcmd1bWVudHMpOw0KICB9LA0KICBzcGxpY2UoLi4uYXJncykgew0KICAgIHJldHVybiBub1RyYWNraW5nKHRoaXMsICJzcGxpY2UiLCBhcmdzKTsNCiAgfSwNCiAgdG9SZXZlcnNlZCgpIHsNCiAgICByZXR1cm4gcmVhY3RpdmVSZWFkQXJyYXkodGhpcykudG9SZXZlcnNlZCgpOw0KICB9LA0KICB0b1NvcnRlZChjb21wYXJlcikgew0KICAgIHJldHVybiByZWFjdGl2ZVJlYWRBcnJheSh0aGlzKS50b1NvcnRlZChjb21wYXJlcik7DQogIH0sDQogIHRvU3BsaWNlZCguLi5hcmdzKSB7DQogICAgcmV0dXJuIHJlYWN0aXZlUmVhZEFycmF5KHRoaXMpLnRvU3BsaWNlZCguLi5hcmdzKTsNCiAgfSwNCiAgdW5zaGlmdCguLi5hcmdzKSB7DQogICAgcmV0dXJuIG5vVHJhY2tpbmcodGhpcywgInVuc2hpZnQiLCBhcmdzKTsNCiAgfSwNCiAgdmFsdWVzKCkgew0KICAgIHJldHVybiBpdGVyYXRvcih0aGlzLCAidmFsdWVzIiwgdG9SZWFjdGl2ZSk7DQogIH0NCn07DQpmdW5jdGlvbiBpdGVyYXRvcihzZWxmLCBtZXRob2QsIHdyYXBWYWx1ZSkgew0KICBjb25zdCBhcnIgPSBzaGFsbG93UmVhZEFycmF5KHNlbGYpOw0KICBjb25zdCBpdGVyID0gYXJyW21ldGhvZF0oKTsNCiAgaWYgKGFyciAhPT0gc2VsZiAmJiAhaXNTaGFsbG93KHNlbGYpKSB7DQogICAgaXRlci5fbmV4dCA9IGl0ZXIubmV4dDsNCiAgICBpdGVyLm5leHQgPSAoKSA9PiB7DQogICAgICBjb25zdCByZXN1bHQgPSBpdGVyLl9uZXh0KCk7DQogICAgICBpZiAocmVzdWx0LnZhbHVlKSB7DQogICAgICAgIHJlc3VsdC52YWx1ZSA9IHdyYXBWYWx1ZShyZXN1bHQudmFsdWUpOw0KICAgICAgfQ0KICAgICAgcmV0dXJuIHJlc3VsdDsNCiAgICB9Ow0KICB9DQogIHJldHVybiBpdGVyOw0KfQ0KY29uc3QgYXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZTsNCmZ1bmN0aW9uIGFwcGx5KHNlbGYsIG1ldGhvZCwgZm4sIHRoaXNBcmcsIHdyYXBwZWRSZXRGbiwgYXJncykgew0KICBjb25zdCBhcnIgPSBzaGFsbG93UmVhZEFycmF5KHNlbGYpOw0KICBjb25zdCBuZWVkc1dyYXAgPSBhcnIgIT09IHNlbGYgJiYgIWlzU2hhbGxvdyhzZWxmKTsNCiAgY29uc3QgbWV0aG9kRm4gPSBhcnJbbWV0aG9kXTsNCiAgaWYgKG1ldGhvZEZuICE9PSBhcnJheVByb3RvW21ldGhvZF0pIHsNCiAgICBjb25zdCByZXN1bHQyID0gbWV0aG9kRm4uYXBwbHkoc2VsZiwgYXJncyk7DQogICAgcmV0dXJuIG5lZWRzV3JhcCA/IHRvUmVhY3RpdmUocmVzdWx0MikgOiByZXN1bHQyOw0KICB9DQogIGxldCB3cmFwcGVkRm4gPSBmbjsNCiAgaWYgKGFyciAhPT0gc2VsZikgew0KICAgIGlmIChuZWVkc1dyYXApIHsNCiAgICAgIHdyYXBwZWRGbiA9IGZ1bmN0aW9uKGl0ZW0sIGluZGV4KSB7DQogICAgICAgIHJldHVybiBmbi5jYWxsKHRoaXMsIHRvUmVhY3RpdmUoaXRlbSksIGluZGV4LCBzZWxmKTsNCiAgICAgIH07DQogICAgfSBlbHNlIGlmIChmbi5sZW5ndGggPiAyKSB7DQogICAgICB3cmFwcGVkRm4gPSBmdW5jdGlvbihpdGVtLCBpbmRleCkgew0KICAgICAgICByZXR1cm4gZm4uY2FsbCh0aGlzLCBpdGVtLCBpbmRleCwgc2VsZik7DQogICAgICB9Ow0KICAgIH0NCiAgfQ0KICBjb25zdCByZXN1bHQgPSBtZXRob2RGbi5jYWxsKGFyciwgd3JhcHBlZEZuLCB0aGlzQXJnKTsNCiAgcmV0dXJuIG5lZWRzV3JhcCAmJiB3cmFwcGVkUmV0Rm4gPyB3cmFwcGVkUmV0Rm4ocmVzdWx0KSA6IHJlc3VsdDsNCn0NCmZ1bmN0aW9uIHJlZHVjZShzZWxmLCBtZXRob2QsIGZuLCBhcmdzKSB7DQogIGNvbnN0IGFyciA9IHNoYWxsb3dSZWFkQXJyYXkoc2VsZik7DQogIGxldCB3cmFwcGVkRm4gPSBmbjsNCiAgaWYgKGFyciAhPT0gc2VsZikgew0KICAgIGlmICghaXNTaGFsbG93KHNlbGYpKSB7DQogICAgICB3cmFwcGVkRm4gPSBmdW5jdGlvbihhY2MsIGl0ZW0sIGluZGV4KSB7DQogICAgICAgIHJldHVybiBmbi5jYWxsKHRoaXMsIGFjYywgdG9SZWFjdGl2ZShpdGVtKSwgaW5kZXgsIHNlbGYpOw0KICAgICAgfTsNCiAgICB9IGVsc2UgaWYgKGZuLmxlbmd0aCA+IDMpIHsNCiAgICAgIHdyYXBwZWRGbiA9IGZ1bmN0aW9uKGFjYywgaXRlbSwgaW5kZXgpIHsNCiAgICAgICAgcmV0dXJuIGZuLmNhbGwodGhpcywgYWNjLCBpdGVtLCBpbmRleCwgc2VsZik7DQogICAgICB9Ow0KICAgIH0NCiAgfQ0KICByZXR1cm4gYXJyW21ldGhvZF0od3JhcHBlZEZuLCAuLi5hcmdzKTsNCn0NCmZ1bmN0aW9uIHNlYXJjaFByb3h5KHNlbGYsIG1ldGhvZCwgYXJncykgew0KICBjb25zdCBhcnIgPSB0b1JhdyhzZWxmKTsNCiAgdHJhY2soYXJyLCAiaXRlcmF0ZSIsIEFSUkFZX0lURVJBVEVfS0VZKTsNCiAgY29uc3QgcmVzID0gYXJyW21ldGhvZF0oLi4uYXJncyk7DQogIGlmICgocmVzID09PSAtMSB8fCByZXMgPT09IGZhbHNlKSAmJiBpc1Byb3h5KGFyZ3NbMF0pKSB7DQogICAgYXJnc1swXSA9IHRvUmF3KGFyZ3NbMF0pOw0KICAgIHJldHVybiBhcnJbbWV0aG9kXSguLi5hcmdzKTsNCiAgfQ0KICByZXR1cm4gcmVzOw0KfQ0KZnVuY3Rpb24gbm9UcmFja2luZyhzZWxmLCBtZXRob2QsIGFyZ3MgPSBbXSkgew0KICBwYXVzZVRyYWNraW5nKCk7DQogIHN0YXJ0QmF0Y2goKTsNCiAgY29uc3QgcmVzID0gdG9SYXcoc2VsZilbbWV0aG9kXS5hcHBseShzZWxmLCBhcmdzKTsNCiAgZW5kQmF0Y2goKTsNCiAgcmVzZXRUcmFja2luZygpOw0KICByZXR1cm4gcmVzOw0KfQ0KDQpjb25zdCBpc05vblRyYWNrYWJsZUtleXMgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcChgX19wcm90b19fLF9fdl9pc1JlZixfX2lzVnVlYCk7DQpjb25zdCBidWlsdEluU3ltYm9scyA9IG5ldyBTZXQoDQogIC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhTeW1ib2wpLmZpbHRlcigoa2V5KSA9PiBrZXkgIT09ICJhcmd1bWVudHMiICYmIGtleSAhPT0gImNhbGxlciIpLm1hcCgoa2V5KSA9PiBTeW1ib2xba2V5XSkuZmlsdGVyKGlzU3ltYm9sKQ0KKTsNCmZ1bmN0aW9uIGhhc093blByb3BlcnR5KGtleSkgew0KICBpZiAoIWlzU3ltYm9sKGtleSkpIGtleSA9IFN0cmluZyhrZXkpOw0KICBjb25zdCBvYmogPSB0b1Jhdyh0aGlzKTsNCiAgdHJhY2sob2JqLCAiaGFzIiwga2V5KTsNCiAgcmV0dXJuIG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpOw0KfQ0KY2xhc3MgQmFzZVJlYWN0aXZlSGFuZGxlciB7DQogIGNvbnN0cnVjdG9yKF9pc1JlYWRvbmx5ID0gZmFsc2UsIF9pc1NoYWxsb3cgPSBmYWxzZSkgew0KICAgIHRoaXMuX2lzUmVhZG9ubHkgPSBfaXNSZWFkb25seTsNCiAgICB0aGlzLl9pc1NoYWxsb3cgPSBfaXNTaGFsbG93Ow0KICB9DQogIGdldCh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpIHsNCiAgICBpZiAoa2V5ID09PSAiX192X3NraXAiKSByZXR1cm4gdGFyZ2V0WyJfX3Zfc2tpcCJdOw0KICAgIGNvbnN0IGlzUmVhZG9ubHkyID0gdGhpcy5faXNSZWFkb25seSwgaXNTaGFsbG93MiA9IHRoaXMuX2lzU2hhbGxvdzsNCiAgICBpZiAoa2V5ID09PSAiX192X2lzUmVhY3RpdmUiKSB7DQogICAgICByZXR1cm4gIWlzUmVhZG9ubHkyOw0KICAgIH0gZWxzZSBpZiAoa2V5ID09PSAiX192X2lzUmVhZG9ubHkiKSB7DQogICAgICByZXR1cm4gaXNSZWFkb25seTI7DQogICAgfSBlbHNlIGlmIChrZXkgPT09ICJfX3ZfaXNTaGFsbG93Iikgew0KICAgICAgcmV0dXJuIGlzU2hhbGxvdzI7DQogICAgfSBlbHNlIGlmIChrZXkgPT09ICJfX3ZfcmF3Iikgew0KICAgICAgaWYgKHJlY2VpdmVyID09PSAoaXNSZWFkb25seTIgPyBpc1NoYWxsb3cyID8gc2hhbGxvd1JlYWRvbmx5TWFwIDogcmVhZG9ubHlNYXAgOiBpc1NoYWxsb3cyID8gc2hhbGxvd1JlYWN0aXZlTWFwIDogcmVhY3RpdmVNYXApLmdldCh0YXJnZXQpIHx8IC8vIHJlY2VpdmVyIGlzIG5vdCB0aGUgcmVhY3RpdmUgcHJveHksIGJ1dCBoYXMgdGhlIHNhbWUgcHJvdG90eXBlDQogICAgICAvLyB0aGlzIG1lYW5zIHRoZSByZWNlaXZlciBpcyBhIHVzZXIgcHJveHkgb2YgdGhlIHJlYWN0aXZlIHByb3h5DQogICAgICBPYmplY3QuZ2V0UHJvdG90eXBlT2YodGFyZ2V0KSA9PT0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHJlY2VpdmVyKSkgew0KICAgICAgICByZXR1cm4gdGFyZ2V0Ow0KICAgICAgfQ0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBjb25zdCB0YXJnZXRJc0FycmF5ID0gaXNBcnJheSh0YXJnZXQpOw0KICAgIGlmICghaXNSZWFkb25seTIpIHsNCiAgICAgIGxldCBmbjsNCiAgICAgIGlmICh0YXJnZXRJc0FycmF5ICYmIChmbiA9IGFycmF5SW5zdHJ1bWVudGF0aW9uc1trZXldKSkgew0KICAgICAgICByZXR1cm4gZm47DQogICAgICB9DQogICAgICBpZiAoa2V5ID09PSAiaGFzT3duUHJvcGVydHkiKSB7DQogICAgICAgIHJldHVybiBoYXNPd25Qcm9wZXJ0eTsNCiAgICAgIH0NCiAgICB9DQogICAgY29uc3QgcmVzID0gUmVmbGVjdC5nZXQoDQogICAgICB0YXJnZXQsDQogICAgICBrZXksDQogICAgICAvLyBpZiB0aGlzIGlzIGEgcHJveHkgd3JhcHBpbmcgYSByZWYsIHJldHVybiBtZXRob2RzIHVzaW5nIHRoZSByYXcgcmVmDQogICAgICAvLyBhcyByZWNlaXZlciBzbyB0aGF0IHdlIGRvbid0IGhhdmUgdG8gY2FsbCBgdG9SYXdgIG9uIHRoZSByZWYgaW4gYWxsDQogICAgICAvLyBpdHMgY2xhc3MgbWV0aG9kcw0KICAgICAgaXNSZWYodGFyZ2V0KSA/IHRhcmdldCA6IHJlY2VpdmVyDQogICAgKTsNCiAgICBpZiAoaXNTeW1ib2woa2V5KSA/IGJ1aWx0SW5TeW1ib2xzLmhhcyhrZXkpIDogaXNOb25UcmFja2FibGVLZXlzKGtleSkpIHsNCiAgICAgIHJldHVybiByZXM7DQogICAgfQ0KICAgIGlmICghaXNSZWFkb25seTIpIHsNCiAgICAgIHRyYWNrKHRhcmdldCwgImdldCIsIGtleSk7DQogICAgfQ0KICAgIGlmIChpc1NoYWxsb3cyKSB7DQogICAgICByZXR1cm4gcmVzOw0KICAgIH0NCiAgICBpZiAoaXNSZWYocmVzKSkgew0KICAgICAgcmV0dXJuIHRhcmdldElzQXJyYXkgJiYgaXNJbnRlZ2VyS2V5KGtleSkgPyByZXMgOiByZXMudmFsdWU7DQogICAgfQ0KICAgIGlmIChpc09iamVjdChyZXMpKSB7DQogICAgICByZXR1cm4gaXNSZWFkb25seTIgPyByZWFkb25seShyZXMpIDogcmVhY3RpdmUocmVzKTsNCiAgICB9DQogICAgcmV0dXJuIHJlczsNCiAgfQ0KfQ0KY2xhc3MgTXV0YWJsZVJlYWN0aXZlSGFuZGxlciBleHRlbmRzIEJhc2VSZWFjdGl2ZUhhbmRsZXIgew0KICBjb25zdHJ1Y3Rvcihpc1NoYWxsb3cyID0gZmFsc2UpIHsNCiAgICBzdXBlcihmYWxzZSwgaXNTaGFsbG93Mik7DQogIH0NCiAgc2V0KHRhcmdldCwga2V5LCB2YWx1ZSwgcmVjZWl2ZXIpIHsNCiAgICBsZXQgb2xkVmFsdWUgPSB0YXJnZXRba2V5XTsNCiAgICBpZiAoIXRoaXMuX2lzU2hhbGxvdykgew0KICAgICAgY29uc3QgaXNPbGRWYWx1ZVJlYWRvbmx5ID0gaXNSZWFkb25seShvbGRWYWx1ZSk7DQogICAgICBpZiAoIWlzU2hhbGxvdyh2YWx1ZSkgJiYgIWlzUmVhZG9ubHkodmFsdWUpKSB7DQogICAgICAgIG9sZFZhbHVlID0gdG9SYXcob2xkVmFsdWUpOw0KICAgICAgICB2YWx1ZSA9IHRvUmF3KHZhbHVlKTsNCiAgICAgIH0NCiAgICAgIGlmICghaXNBcnJheSh0YXJnZXQpICYmIGlzUmVmKG9sZFZhbHVlKSAmJiAhaXNSZWYodmFsdWUpKSB7DQogICAgICAgIGlmIChpc09sZFZhbHVlUmVhZG9ubHkpIHsNCiAgICAgICAgICByZXR1cm4gZmFsc2U7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgb2xkVmFsdWUudmFsdWUgPSB2YWx1ZTsNCiAgICAgICAgICByZXR1cm4gdHJ1ZTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgICBjb25zdCBoYWRLZXkgPSBpc0FycmF5KHRhcmdldCkgJiYgaXNJbnRlZ2VyS2V5KGtleSkgPyBOdW1iZXIoa2V5KSA8IHRhcmdldC5sZW5ndGggOiBoYXNPd24odGFyZ2V0LCBrZXkpOw0KICAgIGNvbnN0IHJlc3VsdCA9IFJlZmxlY3Quc2V0KA0KICAgICAgdGFyZ2V0LA0KICAgICAga2V5LA0KICAgICAgdmFsdWUsDQogICAgICBpc1JlZih0YXJnZXQpID8gdGFyZ2V0IDogcmVjZWl2ZXINCiAgICApOw0KICAgIGlmICh0YXJnZXQgPT09IHRvUmF3KHJlY2VpdmVyKSkgew0KICAgICAgaWYgKCFoYWRLZXkpIHsNCiAgICAgICAgdHJpZ2dlcih0YXJnZXQsICJhZGQiLCBrZXksIHZhbHVlKTsNCiAgICAgIH0gZWxzZSBpZiAoaGFzQ2hhbmdlZCh2YWx1ZSwgb2xkVmFsdWUpKSB7DQogICAgICAgIHRyaWdnZXIodGFyZ2V0LCAic2V0Iiwga2V5LCB2YWx1ZSwgb2xkVmFsdWUpOw0KICAgICAgfQ0KICAgIH0NCiAgICByZXR1cm4gcmVzdWx0Ow0KICB9DQogIGRlbGV0ZVByb3BlcnR5KHRhcmdldCwga2V5KSB7DQogICAgY29uc3QgaGFkS2V5ID0gaGFzT3duKHRhcmdldCwga2V5KTsNCiAgICBjb25zdCBvbGRWYWx1ZSA9IHRhcmdldFtrZXldOw0KICAgIGNvbnN0IHJlc3VsdCA9IFJlZmxlY3QuZGVsZXRlUHJvcGVydHkodGFyZ2V0LCBrZXkpOw0KICAgIGlmIChyZXN1bHQgJiYgaGFkS2V5KSB7DQogICAgICB0cmlnZ2VyKHRhcmdldCwgImRlbGV0ZSIsIGtleSwgdm9pZCAwLCBvbGRWYWx1ZSk7DQogICAgfQ0KICAgIHJldHVybiByZXN1bHQ7DQogIH0NCiAgaGFzKHRhcmdldCwga2V5KSB7DQogICAgY29uc3QgcmVzdWx0ID0gUmVmbGVjdC5oYXModGFyZ2V0LCBrZXkpOw0KICAgIGlmICghaXNTeW1ib2woa2V5KSB8fCAhYnVpbHRJblN5bWJvbHMuaGFzKGtleSkpIHsNCiAgICAgIHRyYWNrKHRhcmdldCwgImhhcyIsIGtleSk7DQogICAgfQ0KICAgIHJldHVybiByZXN1bHQ7DQogIH0NCiAgb3duS2V5cyh0YXJnZXQpIHsNCiAgICB0cmFjaygNCiAgICAgIHRhcmdldCwNCiAgICAgICJpdGVyYXRlIiwNCiAgICAgIGlzQXJyYXkodGFyZ2V0KSA/ICJsZW5ndGgiIDogSVRFUkFURV9LRVkNCiAgICApOw0KICAgIHJldHVybiBSZWZsZWN0Lm93bktleXModGFyZ2V0KTsNCiAgfQ0KfQ0KY2xhc3MgUmVhZG9ubHlSZWFjdGl2ZUhhbmRsZXIgZXh0ZW5kcyBCYXNlUmVhY3RpdmVIYW5kbGVyIHsNCiAgY29uc3RydWN0b3IoaXNTaGFsbG93MiA9IGZhbHNlKSB7DQogICAgc3VwZXIodHJ1ZSwgaXNTaGFsbG93Mik7DQogIH0NCiAgc2V0KHRhcmdldCwga2V5KSB7DQogICAgew0KICAgICAgd2FybiQyKA0KICAgICAgICBgU2V0IG9wZXJhdGlvbiBvbiBrZXkgIiR7U3RyaW5nKGtleSl9IiBmYWlsZWQ6IHRhcmdldCBpcyByZWFkb25seS5gLA0KICAgICAgICB0YXJnZXQNCiAgICAgICk7DQogICAgfQ0KICAgIHJldHVybiB0cnVlOw0KICB9DQogIGRlbGV0ZVByb3BlcnR5KHRhcmdldCwga2V5KSB7DQogICAgew0KICAgICAgd2FybiQyKA0KICAgICAgICBgRGVsZXRlIG9wZXJhdGlvbiBvbiBrZXkgIiR7U3RyaW5nKGtleSl9IiBmYWlsZWQ6IHRhcmdldCBpcyByZWFkb25seS5gLA0KICAgICAgICB0YXJnZXQNCiAgICAgICk7DQogICAgfQ0KICAgIHJldHVybiB0cnVlOw0KICB9DQp9DQpjb25zdCBtdXRhYmxlSGFuZGxlcnMgPSAvKiBAX19QVVJFX18gKi8gbmV3IE11dGFibGVSZWFjdGl2ZUhhbmRsZXIoKTsNCmNvbnN0IHJlYWRvbmx5SGFuZGxlcnMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFJlYWRvbmx5UmVhY3RpdmVIYW5kbGVyKCk7DQpjb25zdCBzaGFsbG93UmVhY3RpdmVIYW5kbGVycyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTXV0YWJsZVJlYWN0aXZlSGFuZGxlcih0cnVlKTsNCmNvbnN0IHNoYWxsb3dSZWFkb25seUhhbmRsZXJzID0gLyogQF9fUFVSRV9fICovIG5ldyBSZWFkb25seVJlYWN0aXZlSGFuZGxlcih0cnVlKTsNCg0KY29uc3QgdG9TaGFsbG93ID0gKHZhbHVlKSA9PiB2YWx1ZTsNCmNvbnN0IGdldFByb3RvID0gKHYpID0+IFJlZmxlY3QuZ2V0UHJvdG90eXBlT2Yodik7DQpmdW5jdGlvbiBjcmVhdGVJdGVyYWJsZU1ldGhvZChtZXRob2QsIGlzUmVhZG9ubHkyLCBpc1NoYWxsb3cyKSB7DQogIHJldHVybiBmdW5jdGlvbiguLi5hcmdzKSB7DQogICAgY29uc3QgdGFyZ2V0ID0gdGhpc1siX192X3JhdyJdOw0KICAgIGNvbnN0IHJhd1RhcmdldCA9IHRvUmF3KHRhcmdldCk7DQogICAgY29uc3QgdGFyZ2V0SXNNYXAgPSBpc01hcChyYXdUYXJnZXQpOw0KICAgIGNvbnN0IGlzUGFpciA9IG1ldGhvZCA9PT0gImVudHJpZXMiIHx8IG1ldGhvZCA9PT0gU3ltYm9sLml0ZXJhdG9yICYmIHRhcmdldElzTWFwOw0KICAgIGNvbnN0IGlzS2V5T25seSA9IG1ldGhvZCA9PT0gImtleXMiICYmIHRhcmdldElzTWFwOw0KICAgIGNvbnN0IGlubmVySXRlcmF0b3IgPSB0YXJnZXRbbWV0aG9kXSguLi5hcmdzKTsNCiAgICBjb25zdCB3cmFwID0gaXNTaGFsbG93MiA/IHRvU2hhbGxvdyA6IGlzUmVhZG9ubHkyID8gdG9SZWFkb25seSA6IHRvUmVhY3RpdmU7DQogICAgIWlzUmVhZG9ubHkyICYmIHRyYWNrKA0KICAgICAgcmF3VGFyZ2V0LA0KICAgICAgIml0ZXJhdGUiLA0KICAgICAgaXNLZXlPbmx5ID8gTUFQX0tFWV9JVEVSQVRFX0tFWSA6IElURVJBVEVfS0VZDQogICAgKTsNCiAgICByZXR1cm4gew0KICAgICAgLy8gaXRlcmF0b3IgcHJvdG9jb2wNCiAgICAgIG5leHQoKSB7DQogICAgICAgIGNvbnN0IHsgdmFsdWUsIGRvbmUgfSA9IGlubmVySXRlcmF0b3IubmV4dCgpOw0KICAgICAgICByZXR1cm4gZG9uZSA/IHsgdmFsdWUsIGRvbmUgfSA6IHsNCiAgICAgICAgICB2YWx1ZTogaXNQYWlyID8gW3dyYXAodmFsdWVbMF0pLCB3cmFwKHZhbHVlWzFdKV0gOiB3cmFwKHZhbHVlKSwNCiAgICAgICAgICBkb25lDQogICAgICAgIH07DQogICAgICB9LA0KICAgICAgLy8gaXRlcmFibGUgcHJvdG9jb2wNCiAgICAgIFtTeW1ib2wuaXRlcmF0b3JdKCkgew0KICAgICAgICByZXR1cm4gdGhpczsNCiAgICAgIH0NCiAgICB9Ow0KICB9Ow0KfQ0KZnVuY3Rpb24gY3JlYXRlUmVhZG9ubHlNZXRob2QodHlwZSkgew0KICByZXR1cm4gZnVuY3Rpb24oLi4uYXJncykgew0KICAgIHsNCiAgICAgIGNvbnN0IGtleSA9IGFyZ3NbMF0gPyBgb24ga2V5ICIke2FyZ3NbMF19IiBgIDogYGA7DQogICAgICB3YXJuJDIoDQogICAgICAgIGAke2NhcGl0YWxpemUodHlwZSl9IG9wZXJhdGlvbiAke2tleX1mYWlsZWQ6IHRhcmdldCBpcyByZWFkb25seS5gLA0KICAgICAgICB0b1Jhdyh0aGlzKQ0KICAgICAgKTsNCiAgICB9DQogICAgcmV0dXJuIHR5cGUgPT09ICJkZWxldGUiID8gZmFsc2UgOiB0eXBlID09PSAiY2xlYXIiID8gdm9pZCAwIDogdGhpczsNCiAgfTsNCn0NCmZ1bmN0aW9uIGNyZWF0ZUluc3RydW1lbnRhdGlvbnMocmVhZG9ubHksIHNoYWxsb3cpIHsNCiAgY29uc3QgaW5zdHJ1bWVudGF0aW9ucyA9IHsNCiAgICBnZXQoa2V5KSB7DQogICAgICBjb25zdCB0YXJnZXQgPSB0aGlzWyJfX3ZfcmF3Il07DQogICAgICBjb25zdCByYXdUYXJnZXQgPSB0b1Jhdyh0YXJnZXQpOw0KICAgICAgY29uc3QgcmF3S2V5ID0gdG9SYXcoa2V5KTsNCiAgICAgIGlmICghcmVhZG9ubHkpIHsNCiAgICAgICAgaWYgKGhhc0NoYW5nZWQoa2V5LCByYXdLZXkpKSB7DQogICAgICAgICAgdHJhY2socmF3VGFyZ2V0LCAiZ2V0Iiwga2V5KTsNCiAgICAgICAgfQ0KICAgICAgICB0cmFjayhyYXdUYXJnZXQsICJnZXQiLCByYXdLZXkpOw0KICAgICAgfQ0KICAgICAgY29uc3QgeyBoYXMgfSA9IGdldFByb3RvKHJhd1RhcmdldCk7DQogICAgICBjb25zdCB3cmFwID0gc2hhbGxvdyA/IHRvU2hhbGxvdyA6IHJlYWRvbmx5ID8gdG9SZWFkb25seSA6IHRvUmVhY3RpdmU7DQogICAgICBpZiAoaGFzLmNhbGwocmF3VGFyZ2V0LCBrZXkpKSB7DQogICAgICAgIHJldHVybiB3cmFwKHRhcmdldC5nZXQoa2V5KSk7DQogICAgICB9IGVsc2UgaWYgKGhhcy5jYWxsKHJhd1RhcmdldCwgcmF3S2V5KSkgew0KICAgICAgICByZXR1cm4gd3JhcCh0YXJnZXQuZ2V0KHJhd0tleSkpOw0KICAgICAgfSBlbHNlIGlmICh0YXJnZXQgIT09IHJhd1RhcmdldCkgew0KICAgICAgICB0YXJnZXQuZ2V0KGtleSk7DQogICAgICB9DQogICAgfSwNCiAgICBnZXQgc2l6ZSgpIHsNCiAgICAgIGNvbnN0IHRhcmdldCA9IHRoaXNbIl9fdl9yYXciXTsNCiAgICAgICFyZWFkb25seSAmJiB0cmFjayh0b1Jhdyh0YXJnZXQpLCAiaXRlcmF0ZSIsIElURVJBVEVfS0VZKTsNCiAgICAgIHJldHVybiBSZWZsZWN0LmdldCh0YXJnZXQsICJzaXplIiwgdGFyZ2V0KTsNCiAgICB9LA0KICAgIGhhcyhrZXkpIHsNCiAgICAgIGNvbnN0IHRhcmdldCA9IHRoaXNbIl9fdl9yYXciXTsNCiAgICAgIGNvbnN0IHJhd1RhcmdldCA9IHRvUmF3KHRhcmdldCk7DQogICAgICBjb25zdCByYXdLZXkgPSB0b1JhdyhrZXkpOw0KICAgICAgaWYgKCFyZWFkb25seSkgew0KICAgICAgICBpZiAoaGFzQ2hhbmdlZChrZXksIHJhd0tleSkpIHsNCiAgICAgICAgICB0cmFjayhyYXdUYXJnZXQsICJoYXMiLCBrZXkpOw0KICAgICAgICB9DQogICAgICAgIHRyYWNrKHJhd1RhcmdldCwgImhhcyIsIHJhd0tleSk7DQogICAgICB9DQogICAgICByZXR1cm4ga2V5ID09PSByYXdLZXkgPyB0YXJnZXQuaGFzKGtleSkgOiB0YXJnZXQuaGFzKGtleSkgfHwgdGFyZ2V0LmhhcyhyYXdLZXkpOw0KICAgIH0sDQogICAgZm9yRWFjaChjYWxsYmFjaywgdGhpc0FyZykgew0KICAgICAgY29uc3Qgb2JzZXJ2ZWQgPSB0aGlzOw0KICAgICAgY29uc3QgdGFyZ2V0ID0gb2JzZXJ2ZWRbIl9fdl9yYXciXTsNCiAgICAgIGNvbnN0IHJhd1RhcmdldCA9IHRvUmF3KHRhcmdldCk7DQogICAgICBjb25zdCB3cmFwID0gc2hhbGxvdyA/IHRvU2hhbGxvdyA6IHJlYWRvbmx5ID8gdG9SZWFkb25seSA6IHRvUmVhY3RpdmU7DQogICAgICAhcmVhZG9ubHkgJiYgdHJhY2socmF3VGFyZ2V0LCAiaXRlcmF0ZSIsIElURVJBVEVfS0VZKTsNCiAgICAgIHJldHVybiB0YXJnZXQuZm9yRWFjaCgodmFsdWUsIGtleSkgPT4gew0KICAgICAgICByZXR1cm4gY2FsbGJhY2suY2FsbCh0aGlzQXJnLCB3cmFwKHZhbHVlKSwgd3JhcChrZXkpLCBvYnNlcnZlZCk7DQogICAgICB9KTsNCiAgICB9DQogIH07DQogIGV4dGVuZCgNCiAgICBpbnN0cnVtZW50YXRpb25zLA0KICAgIHJlYWRvbmx5ID8gew0KICAgICAgYWRkOiBjcmVhdGVSZWFkb25seU1ldGhvZCgiYWRkIiksDQogICAgICBzZXQ6IGNyZWF0ZVJlYWRvbmx5TWV0aG9kKCJzZXQiKSwNCiAgICAgIGRlbGV0ZTogY3JlYXRlUmVhZG9ubHlNZXRob2QoImRlbGV0ZSIpLA0KICAgICAgY2xlYXI6IGNyZWF0ZVJlYWRvbmx5TWV0aG9kKCJjbGVhciIpDQogICAgfSA6IHsNCiAgICAgIGFkZCh2YWx1ZSkgew0KICAgICAgICBpZiAoIXNoYWxsb3cgJiYgIWlzU2hhbGxvdyh2YWx1ZSkgJiYgIWlzUmVhZG9ubHkodmFsdWUpKSB7DQogICAgICAgICAgdmFsdWUgPSB0b1Jhdyh2YWx1ZSk7DQogICAgICAgIH0NCiAgICAgICAgY29uc3QgdGFyZ2V0ID0gdG9SYXcodGhpcyk7DQogICAgICAgIGNvbnN0IHByb3RvID0gZ2V0UHJvdG8odGFyZ2V0KTsNCiAgICAgICAgY29uc3QgaGFkS2V5ID0gcHJvdG8uaGFzLmNhbGwodGFyZ2V0LCB2YWx1ZSk7DQogICAgICAgIGlmICghaGFkS2V5KSB7DQogICAgICAgICAgdGFyZ2V0LmFkZCh2YWx1ZSk7DQogICAgICAgICAgdHJpZ2dlcih0YXJnZXQsICJhZGQiLCB2YWx1ZSwgdmFsdWUpOw0KICAgICAgICB9DQogICAgICAgIHJldHVybiB0aGlzOw0KICAgICAgfSwNCiAgICAgIHNldChrZXksIHZhbHVlKSB7DQogICAgICAgIGlmICghc2hhbGxvdyAmJiAhaXNTaGFsbG93KHZhbHVlKSAmJiAhaXNSZWFkb25seSh2YWx1ZSkpIHsNCiAgICAgICAgICB2YWx1ZSA9IHRvUmF3KHZhbHVlKTsNCiAgICAgICAgfQ0KICAgICAgICBjb25zdCB0YXJnZXQgPSB0b1Jhdyh0aGlzKTsNCiAgICAgICAgY29uc3QgeyBoYXMsIGdldCB9ID0gZ2V0UHJvdG8odGFyZ2V0KTsNCiAgICAgICAgbGV0IGhhZEtleSA9IGhhcy5jYWxsKHRhcmdldCwga2V5KTsNCiAgICAgICAgaWYgKCFoYWRLZXkpIHsNCiAgICAgICAgICBrZXkgPSB0b1JhdyhrZXkpOw0KICAgICAgICAgIGhhZEtleSA9IGhhcy5jYWxsKHRhcmdldCwga2V5KTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBjaGVja0lkZW50aXR5S2V5cyh0YXJnZXQsIGhhcywga2V5KTsNCiAgICAgICAgfQ0KICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IGdldC5jYWxsKHRhcmdldCwga2V5KTsNCiAgICAgICAgdGFyZ2V0LnNldChrZXksIHZhbHVlKTsNCiAgICAgICAgaWYgKCFoYWRLZXkpIHsNCiAgICAgICAgICB0cmlnZ2VyKHRhcmdldCwgImFkZCIsIGtleSwgdmFsdWUpOw0KICAgICAgICB9IGVsc2UgaWYgKGhhc0NoYW5nZWQodmFsdWUsIG9sZFZhbHVlKSkgew0KICAgICAgICAgIHRyaWdnZXIodGFyZ2V0LCAic2V0Iiwga2V5LCB2YWx1ZSwgb2xkVmFsdWUpOw0KICAgICAgICB9DQogICAgICAgIHJldHVybiB0aGlzOw0KICAgICAgfSwNCiAgICAgIGRlbGV0ZShrZXkpIHsNCiAgICAgICAgY29uc3QgdGFyZ2V0ID0gdG9SYXcodGhpcyk7DQogICAgICAgIGNvbnN0IHsgaGFzLCBnZXQgfSA9IGdldFByb3RvKHRhcmdldCk7DQogICAgICAgIGxldCBoYWRLZXkgPSBoYXMuY2FsbCh0YXJnZXQsIGtleSk7DQogICAgICAgIGlmICghaGFkS2V5KSB7DQogICAgICAgICAga2V5ID0gdG9SYXcoa2V5KTsNCiAgICAgICAgICBoYWRLZXkgPSBoYXMuY2FsbCh0YXJnZXQsIGtleSk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgY2hlY2tJZGVudGl0eUtleXModGFyZ2V0LCBoYXMsIGtleSk7DQogICAgICAgIH0NCiAgICAgICAgY29uc3Qgb2xkVmFsdWUgPSBnZXQgPyBnZXQuY2FsbCh0YXJnZXQsIGtleSkgOiB2b2lkIDA7DQogICAgICAgIGNvbnN0IHJlc3VsdCA9IHRhcmdldC5kZWxldGUoa2V5KTsNCiAgICAgICAgaWYgKGhhZEtleSkgew0KICAgICAgICAgIHRyaWdnZXIodGFyZ2V0LCAiZGVsZXRlIiwga2V5LCB2b2lkIDAsIG9sZFZhbHVlKTsNCiAgICAgICAgfQ0KICAgICAgICByZXR1cm4gcmVzdWx0Ow0KICAgICAgfSwNCiAgICAgIGNsZWFyKCkgew0KICAgICAgICBjb25zdCB0YXJnZXQgPSB0b1Jhdyh0aGlzKTsNCiAgICAgICAgY29uc3QgaGFkSXRlbXMgPSB0YXJnZXQuc2l6ZSAhPT0gMDsNCiAgICAgICAgY29uc3Qgb2xkVGFyZ2V0ID0gaXNNYXAodGFyZ2V0KSA/IG5ldyBNYXAodGFyZ2V0KSA6IG5ldyBTZXQodGFyZ2V0KSA7DQogICAgICAgIGNvbnN0IHJlc3VsdCA9IHRhcmdldC5jbGVhcigpOw0KICAgICAgICBpZiAoaGFkSXRlbXMpIHsNCiAgICAgICAgICB0cmlnZ2VyKA0KICAgICAgICAgICAgdGFyZ2V0LA0KICAgICAgICAgICAgImNsZWFyIiwNCiAgICAgICAgICAgIHZvaWQgMCwNCiAgICAgICAgICAgIHZvaWQgMCwNCiAgICAgICAgICAgIG9sZFRhcmdldA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIHJlc3VsdDsNCiAgICAgIH0NCiAgICB9DQogICk7DQogIGNvbnN0IGl0ZXJhdG9yTWV0aG9kcyA9IFsNCiAgICAia2V5cyIsDQogICAgInZhbHVlcyIsDQogICAgImVudHJpZXMiLA0KICAgIFN5bWJvbC5pdGVyYXRvcg0KICBdOw0KICBpdGVyYXRvck1ldGhvZHMuZm9yRWFjaCgobWV0aG9kKSA9PiB7DQogICAgaW5zdHJ1bWVudGF0aW9uc1ttZXRob2RdID0gY3JlYXRlSXRlcmFibGVNZXRob2QobWV0aG9kLCByZWFkb25seSwgc2hhbGxvdyk7DQogIH0pOw0KICByZXR1cm4gaW5zdHJ1bWVudGF0aW9uczsNCn0NCmZ1bmN0aW9uIGNyZWF0ZUluc3RydW1lbnRhdGlvbkdldHRlcihpc1JlYWRvbmx5Miwgc2hhbGxvdykgew0KICBjb25zdCBpbnN0cnVtZW50YXRpb25zID0gY3JlYXRlSW5zdHJ1bWVudGF0aW9ucyhpc1JlYWRvbmx5Miwgc2hhbGxvdyk7DQogIHJldHVybiAodGFyZ2V0LCBrZXksIHJlY2VpdmVyKSA9PiB7DQogICAgaWYgKGtleSA9PT0gIl9fdl9pc1JlYWN0aXZlIikgew0KICAgICAgcmV0dXJuICFpc1JlYWRvbmx5MjsNCiAgICB9IGVsc2UgaWYgKGtleSA9PT0gIl9fdl9pc1JlYWRvbmx5Iikgew0KICAgICAgcmV0dXJuIGlzUmVhZG9ubHkyOw0KICAgIH0gZWxzZSBpZiAoa2V5ID09PSAiX192X3JhdyIpIHsNCiAgICAgIHJldHVybiB0YXJnZXQ7DQogICAgfQ0KICAgIHJldHVybiBSZWZsZWN0LmdldCgNCiAgICAgIGhhc093bihpbnN0cnVtZW50YXRpb25zLCBrZXkpICYmIGtleSBpbiB0YXJnZXQgPyBpbnN0cnVtZW50YXRpb25zIDogdGFyZ2V0LA0KICAgICAga2V5LA0KICAgICAgcmVjZWl2ZXINCiAgICApOw0KICB9Ow0KfQ0KY29uc3QgbXV0YWJsZUNvbGxlY3Rpb25IYW5kbGVycyA9IHsNCiAgZ2V0OiAvKiBAX19QVVJFX18gKi8gY3JlYXRlSW5zdHJ1bWVudGF0aW9uR2V0dGVyKGZhbHNlLCBmYWxzZSkNCn07DQpjb25zdCBzaGFsbG93Q29sbGVjdGlvbkhhbmRsZXJzID0gew0KICBnZXQ6IC8qIEBfX1BVUkVfXyAqLyBjcmVhdGVJbnN0cnVtZW50YXRpb25HZXR0ZXIoZmFsc2UsIHRydWUpDQp9Ow0KY29uc3QgcmVhZG9ubHlDb2xsZWN0aW9uSGFuZGxlcnMgPSB7DQogIGdldDogLyogQF9fUFVSRV9fICovIGNyZWF0ZUluc3RydW1lbnRhdGlvbkdldHRlcih0cnVlLCBmYWxzZSkNCn07DQpjb25zdCBzaGFsbG93UmVhZG9ubHlDb2xsZWN0aW9uSGFuZGxlcnMgPSB7DQogIGdldDogLyogQF9fUFVSRV9fICovIGNyZWF0ZUluc3RydW1lbnRhdGlvbkdldHRlcih0cnVlLCB0cnVlKQ0KfTsNCmZ1bmN0aW9uIGNoZWNrSWRlbnRpdHlLZXlzKHRhcmdldCwgaGFzLCBrZXkpIHsNCiAgY29uc3QgcmF3S2V5ID0gdG9SYXcoa2V5KTsNCiAgaWYgKHJhd0tleSAhPT0ga2V5ICYmIGhhcy5jYWxsKHRhcmdldCwgcmF3S2V5KSkgew0KICAgIGNvbnN0IHR5cGUgPSB0b1Jhd1R5cGUodGFyZ2V0KTsNCiAgICB3YXJuJDIoDQogICAgICBgUmVhY3RpdmUgJHt0eXBlfSBjb250YWlucyBib3RoIHRoZSByYXcgYW5kIHJlYWN0aXZlIHZlcnNpb25zIG9mIHRoZSBzYW1lIG9iamVjdCR7dHlwZSA9PT0gYE1hcGAgPyBgIGFzIGtleXNgIDogYGB9LCB3aGljaCBjYW4gbGVhZCB0byBpbmNvbnNpc3RlbmNpZXMuIEF2b2lkIGRpZmZlcmVudGlhdGluZyBiZXR3ZWVuIHRoZSByYXcgYW5kIHJlYWN0aXZlIHZlcnNpb25zIG9mIGFuIG9iamVjdCBhbmQgb25seSB1c2UgdGhlIHJlYWN0aXZlIHZlcnNpb24gaWYgcG9zc2libGUuYA0KICAgICk7DQogIH0NCn0NCg0KY29uc3QgcmVhY3RpdmVNYXAgPSAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtNYXAoKTsNCmNvbnN0IHNoYWxsb3dSZWFjdGl2ZU1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgV2Vha01hcCgpOw0KY29uc3QgcmVhZG9ubHlNYXAgPSAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtNYXAoKTsNCmNvbnN0IHNoYWxsb3dSZWFkb25seU1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgV2Vha01hcCgpOw0KZnVuY3Rpb24gdGFyZ2V0VHlwZU1hcChyYXdUeXBlKSB7DQogIHN3aXRjaCAocmF3VHlwZSkgew0KICAgIGNhc2UgIk9iamVjdCI6DQogICAgY2FzZSAiQXJyYXkiOg0KICAgICAgcmV0dXJuIDEgLyogQ09NTU9OICovOw0KICAgIGNhc2UgIk1hcCI6DQogICAgY2FzZSAiU2V0IjoNCiAgICBjYXNlICJXZWFrTWFwIjoNCiAgICBjYXNlICJXZWFrU2V0IjoNCiAgICAgIHJldHVybiAyIC8qIENPTExFQ1RJT04gKi87DQogICAgZGVmYXVsdDoNCiAgICAgIHJldHVybiAwIC8qIElOVkFMSUQgKi87DQogIH0NCn0NCmZ1bmN0aW9uIGdldFRhcmdldFR5cGUodmFsdWUpIHsNCiAgcmV0dXJuIHZhbHVlWyJfX3Zfc2tpcCJdIHx8ICFPYmplY3QuaXNFeHRlbnNpYmxlKHZhbHVlKSA/IDAgLyogSU5WQUxJRCAqLyA6IHRhcmdldFR5cGVNYXAodG9SYXdUeXBlKHZhbHVlKSk7DQp9DQpmdW5jdGlvbiByZWFjdGl2ZSh0YXJnZXQpIHsNCiAgaWYgKGlzUmVhZG9ubHkodGFyZ2V0KSkgew0KICAgIHJldHVybiB0YXJnZXQ7DQogIH0NCiAgcmV0dXJuIGNyZWF0ZVJlYWN0aXZlT2JqZWN0KA0KICAgIHRhcmdldCwNCiAgICBmYWxzZSwNCiAgICBtdXRhYmxlSGFuZGxlcnMsDQogICAgbXV0YWJsZUNvbGxlY3Rpb25IYW5kbGVycywNCiAgICByZWFjdGl2ZU1hcA0KICApOw0KfQ0KZnVuY3Rpb24gc2hhbGxvd1JlYWN0aXZlKHRhcmdldCkgew0KICByZXR1cm4gY3JlYXRlUmVhY3RpdmVPYmplY3QoDQogICAgdGFyZ2V0LA0KICAgIGZhbHNlLA0KICAgIHNoYWxsb3dSZWFjdGl2ZUhhbmRsZXJzLA0KICAgIHNoYWxsb3dDb2xsZWN0aW9uSGFuZGxlcnMsDQogICAgc2hhbGxvd1JlYWN0aXZlTWFwDQogICk7DQp9DQpmdW5jdGlvbiByZWFkb25seSh0YXJnZXQpIHsNCiAgcmV0dXJuIGNyZWF0ZVJlYWN0aXZlT2JqZWN0KA0KICAgIHRhcmdldCwNCiAgICB0cnVlLA0KICAgIHJlYWRvbmx5SGFuZGxlcnMsDQogICAgcmVhZG9ubHlDb2xsZWN0aW9uSGFuZGxlcnMsDQogICAgcmVhZG9ubHlNYXANCiAgKTsNCn0NCmZ1bmN0aW9uIHNoYWxsb3dSZWFkb25seSh0YXJnZXQpIHsNCiAgcmV0dXJuIGNyZWF0ZVJlYWN0aXZlT2JqZWN0KA0KICAgIHRhcmdldCwNCiAgICB0cnVlLA0KICAgIHNoYWxsb3dSZWFkb25seUhhbmRsZXJzLA0KICAgIHNoYWxsb3dSZWFkb25seUNvbGxlY3Rpb25IYW5kbGVycywNCiAgICBzaGFsbG93UmVhZG9ubHlNYXANCiAgKTsNCn0NCmZ1bmN0aW9uIGNyZWF0ZVJlYWN0aXZlT2JqZWN0KHRhcmdldCwgaXNSZWFkb25seTIsIGJhc2VIYW5kbGVycywgY29sbGVjdGlvbkhhbmRsZXJzLCBwcm94eU1hcCkgew0KICBpZiAoIWlzT2JqZWN0KHRhcmdldCkpIHsNCiAgICB7DQogICAgICB3YXJuJDIoDQogICAgICAgIGB2YWx1ZSBjYW5ub3QgYmUgbWFkZSAke2lzUmVhZG9ubHkyID8gInJlYWRvbmx5IiA6ICJyZWFjdGl2ZSJ9OiAke1N0cmluZygNCiAgICAgICAgICB0YXJnZXQNCiAgICAgICAgKX1gDQogICAgICApOw0KICAgIH0NCiAgICByZXR1cm4gdGFyZ2V0Ow0KICB9DQogIGlmICh0YXJnZXRbIl9fdl9yYXciXSAmJiAhKGlzUmVhZG9ubHkyICYmIHRhcmdldFsiX192X2lzUmVhY3RpdmUiXSkpIHsNCiAgICByZXR1cm4gdGFyZ2V0Ow0KICB9DQogIGNvbnN0IHRhcmdldFR5cGUgPSBnZXRUYXJnZXRUeXBlKHRhcmdldCk7DQogIGlmICh0YXJnZXRUeXBlID09PSAwIC8qIElOVkFMSUQgKi8pIHsNCiAgICByZXR1cm4gdGFyZ2V0Ow0KICB9DQogIGNvbnN0IGV4aXN0aW5nUHJveHkgPSBwcm94eU1hcC5nZXQodGFyZ2V0KTsNCiAgaWYgKGV4aXN0aW5nUHJveHkpIHsNCiAgICByZXR1cm4gZXhpc3RpbmdQcm94eTsNCiAgfQ0KICBjb25zdCBwcm94eSA9IG5ldyBQcm94eSgNCiAgICB0YXJnZXQsDQogICAgdGFyZ2V0VHlwZSA9PT0gMiAvKiBDT0xMRUNUSU9OICovID8gY29sbGVjdGlvbkhhbmRsZXJzIDogYmFzZUhhbmRsZXJzDQogICk7DQogIHByb3h5TWFwLnNldCh0YXJnZXQsIHByb3h5KTsNCiAgcmV0dXJuIHByb3h5Ow0KfQ0KZnVuY3Rpb24gaXNSZWFjdGl2ZSh2YWx1ZSkgew0KICBpZiAoaXNSZWFkb25seSh2YWx1ZSkpIHsNCiAgICByZXR1cm4gaXNSZWFjdGl2ZSh2YWx1ZVsiX192X3JhdyJdKTsNCiAgfQ0KICByZXR1cm4gISEodmFsdWUgJiYgdmFsdWVbIl9fdl9pc1JlYWN0aXZlIl0pOw0KfQ0KZnVuY3Rpb24gaXNSZWFkb25seSh2YWx1ZSkgew0KICByZXR1cm4gISEodmFsdWUgJiYgdmFsdWVbIl9fdl9pc1JlYWRvbmx5Il0pOw0KfQ0KZnVuY3Rpb24gaXNTaGFsbG93KHZhbHVlKSB7DQogIHJldHVybiAhISh2YWx1ZSAmJiB2YWx1ZVsiX192X2lzU2hhbGxvdyJdKTsNCn0NCmZ1bmN0aW9uIGlzUHJveHkodmFsdWUpIHsNCiAgcmV0dXJuIHZhbHVlID8gISF2YWx1ZVsiX192X3JhdyJdIDogZmFsc2U7DQp9DQpmdW5jdGlvbiB0b1JhdyhvYnNlcnZlZCkgew0KICBjb25zdCByYXcgPSBvYnNlcnZlZCAmJiBvYnNlcnZlZFsiX192X3JhdyJdOw0KICByZXR1cm4gcmF3ID8gdG9SYXcocmF3KSA6IG9ic2VydmVkOw0KfQ0KZnVuY3Rpb24gbWFya1Jhdyh2YWx1ZSkgew0KICBpZiAoIWhhc093bih2YWx1ZSwgIl9fdl9za2lwIikgJiYgT2JqZWN0LmlzRXh0ZW5zaWJsZSh2YWx1ZSkpIHsNCiAgICBkZWYodmFsdWUsICJfX3Zfc2tpcCIsIHRydWUpOw0KICB9DQogIHJldHVybiB2YWx1ZTsNCn0NCmNvbnN0IHRvUmVhY3RpdmUgPSAodmFsdWUpID0+IGlzT2JqZWN0KHZhbHVlKSA/IHJlYWN0aXZlKHZhbHVlKSA6IHZhbHVlOw0KY29uc3QgdG9SZWFkb25seSA9ICh2YWx1ZSkgPT4gaXNPYmplY3QodmFsdWUpID8gcmVhZG9ubHkodmFsdWUpIDogdmFsdWU7DQoNCmZ1bmN0aW9uIGlzUmVmKHIpIHsNCiAgcmV0dXJuIHIgPyByWyJfX3ZfaXNSZWYiXSA9PT0gdHJ1ZSA6IGZhbHNlOw0KfQ0KZnVuY3Rpb24gcmVmKHZhbHVlKSB7DQogIHJldHVybiBjcmVhdGVSZWYodmFsdWUsIGZhbHNlKTsNCn0NCmZ1bmN0aW9uIHNoYWxsb3dSZWYodmFsdWUpIHsNCiAgcmV0dXJuIGNyZWF0ZVJlZih2YWx1ZSwgdHJ1ZSk7DQp9DQpmdW5jdGlvbiBjcmVhdGVSZWYocmF3VmFsdWUsIHNoYWxsb3cpIHsNCiAgaWYgKGlzUmVmKHJhd1ZhbHVlKSkgew0KICAgIHJldHVybiByYXdWYWx1ZTsNCiAgfQ0KICByZXR1cm4gbmV3IFJlZkltcGwocmF3VmFsdWUsIHNoYWxsb3cpOw0KfQ0KY2xhc3MgUmVmSW1wbCB7DQogIGNvbnN0cnVjdG9yKHZhbHVlLCBpc1NoYWxsb3cyKSB7DQogICAgdGhpcy5kZXAgPSBuZXcgRGVwKCk7DQogICAgdGhpc1siX192X2lzUmVmIl0gPSB0cnVlOw0KICAgIHRoaXNbIl9fdl9pc1NoYWxsb3ciXSA9IGZhbHNlOw0KICAgIHRoaXMuX3Jhd1ZhbHVlID0gaXNTaGFsbG93MiA/IHZhbHVlIDogdG9SYXcodmFsdWUpOw0KICAgIHRoaXMuX3ZhbHVlID0gaXNTaGFsbG93MiA/IHZhbHVlIDogdG9SZWFjdGl2ZSh2YWx1ZSk7DQogICAgdGhpc1siX192X2lzU2hhbGxvdyJdID0gaXNTaGFsbG93MjsNCiAgfQ0KICBnZXQgdmFsdWUoKSB7DQogICAgew0KICAgICAgdGhpcy5kZXAudHJhY2soew0KICAgICAgICB0YXJnZXQ6IHRoaXMsDQogICAgICAgIHR5cGU6ICJnZXQiLA0KICAgICAgICBrZXk6ICJ2YWx1ZSINCiAgICAgIH0pOw0KICAgIH0NCiAgICByZXR1cm4gdGhpcy5fdmFsdWU7DQogIH0NCiAgc2V0IHZhbHVlKG5ld1ZhbHVlKSB7DQogICAgY29uc3Qgb2xkVmFsdWUgPSB0aGlzLl9yYXdWYWx1ZTsNCiAgICBjb25zdCB1c2VEaXJlY3RWYWx1ZSA9IHRoaXNbIl9fdl9pc1NoYWxsb3ciXSB8fCBpc1NoYWxsb3cobmV3VmFsdWUpIHx8IGlzUmVhZG9ubHkobmV3VmFsdWUpOw0KICAgIG5ld1ZhbHVlID0gdXNlRGlyZWN0VmFsdWUgPyBuZXdWYWx1ZSA6IHRvUmF3KG5ld1ZhbHVlKTsNCiAgICBpZiAoaGFzQ2hhbmdlZChuZXdWYWx1ZSwgb2xkVmFsdWUpKSB7DQogICAgICB0aGlzLl9yYXdWYWx1ZSA9IG5ld1ZhbHVlOw0KICAgICAgdGhpcy5fdmFsdWUgPSB1c2VEaXJlY3RWYWx1ZSA/IG5ld1ZhbHVlIDogdG9SZWFjdGl2ZShuZXdWYWx1ZSk7DQogICAgICB7DQogICAgICAgIHRoaXMuZGVwLnRyaWdnZXIoew0KICAgICAgICAgIHRhcmdldDogdGhpcywNCiAgICAgICAgICB0eXBlOiAic2V0IiwNCiAgICAgICAgICBrZXk6ICJ2YWx1ZSIsDQogICAgICAgICAgbmV3VmFsdWUsDQogICAgICAgICAgb2xkVmFsdWUNCiAgICAgICAgfSk7DQogICAgICB9DQogICAgfQ0KICB9DQp9DQpmdW5jdGlvbiB0cmlnZ2VyUmVmKHJlZjIpIHsNCiAgaWYgKHJlZjIuZGVwKSB7DQogICAgew0KICAgICAgcmVmMi5kZXAudHJpZ2dlcih7DQogICAgICAgIHRhcmdldDogcmVmMiwNCiAgICAgICAgdHlwZTogInNldCIsDQogICAgICAgIGtleTogInZhbHVlIiwNCiAgICAgICAgbmV3VmFsdWU6IHJlZjIuX3ZhbHVlDQogICAgICB9KTsNCiAgICB9DQogIH0NCn0NCmZ1bmN0aW9uIHVucmVmKHJlZjIpIHsNCiAgcmV0dXJuIGlzUmVmKHJlZjIpID8gcmVmMi52YWx1ZSA6IHJlZjI7DQp9DQpmdW5jdGlvbiB0b1ZhbHVlKHNvdXJjZSkgew0KICByZXR1cm4gaXNGdW5jdGlvbihzb3VyY2UpID8gc291cmNlKCkgOiB1bnJlZihzb3VyY2UpOw0KfQ0KY29uc3Qgc2hhbGxvd1Vud3JhcEhhbmRsZXJzID0gew0KICBnZXQ6ICh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpID0+IGtleSA9PT0gIl9fdl9yYXciID8gdGFyZ2V0IDogdW5yZWYoUmVmbGVjdC5nZXQodGFyZ2V0LCBrZXksIHJlY2VpdmVyKSksDQogIHNldDogKHRhcmdldCwga2V5LCB2YWx1ZSwgcmVjZWl2ZXIpID0+IHsNCiAgICBjb25zdCBvbGRWYWx1ZSA9IHRhcmdldFtrZXldOw0KICAgIGlmIChpc1JlZihvbGRWYWx1ZSkgJiYgIWlzUmVmKHZhbHVlKSkgew0KICAgICAgb2xkVmFsdWUudmFsdWUgPSB2YWx1ZTsNCiAgICAgIHJldHVybiB0cnVlOw0KICAgIH0gZWxzZSB7DQogICAgICByZXR1cm4gUmVmbGVjdC5zZXQodGFyZ2V0LCBrZXksIHZhbHVlLCByZWNlaXZlcik7DQogICAgfQ0KICB9DQp9Ow0KZnVuY3Rpb24gcHJveHlSZWZzKG9iamVjdFdpdGhSZWZzKSB7DQogIHJldHVybiBpc1JlYWN0aXZlKG9iamVjdFdpdGhSZWZzKSA/IG9iamVjdFdpdGhSZWZzIDogbmV3IFByb3h5KG9iamVjdFdpdGhSZWZzLCBzaGFsbG93VW53cmFwSGFuZGxlcnMpOw0KfQ0KY2xhc3MgQ3VzdG9tUmVmSW1wbCB7DQogIGNvbnN0cnVjdG9yKGZhY3RvcnkpIHsNCiAgICB0aGlzWyJfX3ZfaXNSZWYiXSA9IHRydWU7DQogICAgdGhpcy5fdmFsdWUgPSB2b2lkIDA7DQogICAgY29uc3QgZGVwID0gdGhpcy5kZXAgPSBuZXcgRGVwKCk7DQogICAgY29uc3QgeyBnZXQsIHNldCB9ID0gZmFjdG9yeShkZXAudHJhY2suYmluZChkZXApLCBkZXAudHJpZ2dlci5iaW5kKGRlcCkpOw0KICAgIHRoaXMuX2dldCA9IGdldDsNCiAgICB0aGlzLl9zZXQgPSBzZXQ7DQogIH0NCiAgZ2V0IHZhbHVlKCkgew0KICAgIHJldHVybiB0aGlzLl92YWx1ZSA9IHRoaXMuX2dldCgpOw0KICB9DQogIHNldCB2YWx1ZShuZXdWYWwpIHsNCiAgICB0aGlzLl9zZXQobmV3VmFsKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gY3VzdG9tUmVmKGZhY3RvcnkpIHsNCiAgcmV0dXJuIG5ldyBDdXN0b21SZWZJbXBsKGZhY3RvcnkpOw0KfQ0KZnVuY3Rpb24gdG9SZWZzKG9iamVjdCkgew0KICBpZiAoIWlzUHJveHkob2JqZWN0KSkgew0KICAgIHdhcm4kMihgdG9SZWZzKCkgZXhwZWN0cyBhIHJlYWN0aXZlIG9iamVjdCBidXQgcmVjZWl2ZWQgYSBwbGFpbiBvbmUuYCk7DQogIH0NCiAgY29uc3QgcmV0ID0gaXNBcnJheShvYmplY3QpID8gbmV3IEFycmF5KG9iamVjdC5sZW5ndGgpIDoge307DQogIGZvciAoY29uc3Qga2V5IGluIG9iamVjdCkgew0KICAgIHJldFtrZXldID0gcHJvcGVydHlUb1JlZihvYmplY3QsIGtleSk7DQogIH0NCiAgcmV0dXJuIHJldDsNCn0NCmNsYXNzIE9iamVjdFJlZkltcGwgew0KICBjb25zdHJ1Y3Rvcihfb2JqZWN0LCBfa2V5LCBfZGVmYXVsdFZhbHVlKSB7DQogICAgdGhpcy5fb2JqZWN0ID0gX29iamVjdDsNCiAgICB0aGlzLl9rZXkgPSBfa2V5Ow0KICAgIHRoaXMuX2RlZmF1bHRWYWx1ZSA9IF9kZWZhdWx0VmFsdWU7DQogICAgdGhpc1siX192X2lzUmVmIl0gPSB0cnVlOw0KICAgIHRoaXMuX3ZhbHVlID0gdm9pZCAwOw0KICB9DQogIGdldCB2YWx1ZSgpIHsNCiAgICBjb25zdCB2YWwgPSB0aGlzLl9vYmplY3RbdGhpcy5fa2V5XTsNCiAgICByZXR1cm4gdGhpcy5fdmFsdWUgPSB2YWwgPT09IHZvaWQgMCA/IHRoaXMuX2RlZmF1bHRWYWx1ZSA6IHZhbDsNCiAgfQ0KICBzZXQgdmFsdWUobmV3VmFsKSB7DQogICAgdGhpcy5fb2JqZWN0W3RoaXMuX2tleV0gPSBuZXdWYWw7DQogIH0NCiAgZ2V0IGRlcCgpIHsNCiAgICByZXR1cm4gZ2V0RGVwRnJvbVJlYWN0aXZlKHRvUmF3KHRoaXMuX29iamVjdCksIHRoaXMuX2tleSk7DQogIH0NCn0NCmNsYXNzIEdldHRlclJlZkltcGwgew0KICBjb25zdHJ1Y3RvcihfZ2V0dGVyKSB7DQogICAgdGhpcy5fZ2V0dGVyID0gX2dldHRlcjsNCiAgICB0aGlzWyJfX3ZfaXNSZWYiXSA9IHRydWU7DQogICAgdGhpc1siX192X2lzUmVhZG9ubHkiXSA9IHRydWU7DQogICAgdGhpcy5fdmFsdWUgPSB2b2lkIDA7DQogIH0NCiAgZ2V0IHZhbHVlKCkgew0KICAgIHJldHVybiB0aGlzLl92YWx1ZSA9IHRoaXMuX2dldHRlcigpOw0KICB9DQp9DQpmdW5jdGlvbiB0b1JlZihzb3VyY2UsIGtleSwgZGVmYXVsdFZhbHVlKSB7DQogIGlmIChpc1JlZihzb3VyY2UpKSB7DQogICAgcmV0dXJuIHNvdXJjZTsNCiAgfSBlbHNlIGlmIChpc0Z1bmN0aW9uKHNvdXJjZSkpIHsNCiAgICByZXR1cm4gbmV3IEdldHRlclJlZkltcGwoc291cmNlKTsNCiAgfSBlbHNlIGlmIChpc09iamVjdChzb3VyY2UpICYmIGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7DQogICAgcmV0dXJuIHByb3BlcnR5VG9SZWYoc291cmNlLCBrZXksIGRlZmF1bHRWYWx1ZSk7DQogIH0gZWxzZSB7DQogICAgcmV0dXJuIHJlZihzb3VyY2UpOw0KICB9DQp9DQpmdW5jdGlvbiBwcm9wZXJ0eVRvUmVmKHNvdXJjZSwga2V5LCBkZWZhdWx0VmFsdWUpIHsNCiAgY29uc3QgdmFsID0gc291cmNlW2tleV07DQogIHJldHVybiBpc1JlZih2YWwpID8gdmFsIDogbmV3IE9iamVjdFJlZkltcGwoc291cmNlLCBrZXksIGRlZmF1bHRWYWx1ZSk7DQp9DQoNCmNsYXNzIENvbXB1dGVkUmVmSW1wbCB7DQogIGNvbnN0cnVjdG9yKGZuLCBzZXR0ZXIsIGlzU1NSKSB7DQogICAgdGhpcy5mbiA9IGZuOw0KICAgIHRoaXMuc2V0dGVyID0gc2V0dGVyOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuX3ZhbHVlID0gdm9pZCAwOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuZGVwID0gbmV3IERlcCh0aGlzKTsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLl9fdl9pc1JlZiA9IHRydWU7DQogICAgLy8gVE9ETyBpc29sYXRlZERlY2xhcmF0aW9ucyAiX192X2lzUmVhZG9ubHkiDQogICAgLy8gQSBjb21wdXRlZCBpcyBhbHNvIGEgc3Vic2NyaWJlciB0aGF0IHRyYWNrcyBvdGhlciBkZXBzDQogICAgLyoqDQogICAgICogQGludGVybmFsDQogICAgICovDQogICAgdGhpcy5kZXBzID0gdm9pZCAwOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuZGVwc1RhaWwgPSB2b2lkIDA7DQogICAgLyoqDQogICAgICogQGludGVybmFsDQogICAgICovDQogICAgdGhpcy5mbGFncyA9IDE2Ow0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuZ2xvYmFsVmVyc2lvbiA9IGdsb2JhbFZlcnNpb24gLSAxOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMubmV4dCA9IHZvaWQgMDsNCiAgICAvLyBmb3IgYmFja3dhcmRzIGNvbXBhdA0KICAgIHRoaXMuZWZmZWN0ID0gdGhpczsNCiAgICB0aGlzWyJfX3ZfaXNSZWFkb25seSJdID0gIXNldHRlcjsNCiAgICB0aGlzLmlzU1NSID0gaXNTU1I7DQogIH0NCiAgLyoqDQogICAqIEBpbnRlcm5hbA0KICAgKi8NCiAgbm90aWZ5KCkgew0KICAgIHRoaXMuZmxhZ3MgfD0gMTY7DQogICAgaWYgKCEodGhpcy5mbGFncyAmIDgpICYmIC8vIGF2b2lkIGluZmluaXRlIHNlbGYgcmVjdXJzaW9uDQogICAgYWN0aXZlU3ViICE9PSB0aGlzKSB7DQogICAgICBiYXRjaCh0aGlzLCB0cnVlKTsNCiAgICAgIHJldHVybiB0cnVlOw0KICAgIH0NCiAgfQ0KICBnZXQgdmFsdWUoKSB7DQogICAgY29uc3QgbGluayA9IHRoaXMuZGVwLnRyYWNrKHsNCiAgICAgIHRhcmdldDogdGhpcywNCiAgICAgIHR5cGU6ICJnZXQiLA0KICAgICAga2V5OiAidmFsdWUiDQogICAgfSkgOw0KICAgIHJlZnJlc2hDb21wdXRlZCh0aGlzKTsNCiAgICBpZiAobGluaykgew0KICAgICAgbGluay52ZXJzaW9uID0gdGhpcy5kZXAudmVyc2lvbjsNCiAgICB9DQogICAgcmV0dXJuIHRoaXMuX3ZhbHVlOw0KICB9DQogIHNldCB2YWx1ZShuZXdWYWx1ZSkgew0KICAgIGlmICh0aGlzLnNldHRlcikgew0KICAgICAgdGhpcy5zZXR0ZXIobmV3VmFsdWUpOw0KICAgIH0gZWxzZSB7DQogICAgICB3YXJuJDIoIldyaXRlIG9wZXJhdGlvbiBmYWlsZWQ6IGNvbXB1dGVkIHZhbHVlIGlzIHJlYWRvbmx5Iik7DQogICAgfQ0KICB9DQp9DQpmdW5jdGlvbiBjb21wdXRlZCQxKGdldHRlck9yT3B0aW9ucywgZGVidWdPcHRpb25zLCBpc1NTUiA9IGZhbHNlKSB7DQogIGxldCBnZXR0ZXI7DQogIGxldCBzZXR0ZXI7DQogIGlmIChpc0Z1bmN0aW9uKGdldHRlck9yT3B0aW9ucykpIHsNCiAgICBnZXR0ZXIgPSBnZXR0ZXJPck9wdGlvbnM7DQogIH0gZWxzZSB7DQogICAgZ2V0dGVyID0gZ2V0dGVyT3JPcHRpb25zLmdldDsNCiAgICBzZXR0ZXIgPSBnZXR0ZXJPck9wdGlvbnMuc2V0Ow0KICB9DQogIGNvbnN0IGNSZWYgPSBuZXcgQ29tcHV0ZWRSZWZJbXBsKGdldHRlciwgc2V0dGVyLCBpc1NTUik7DQogIGlmIChkZWJ1Z09wdGlvbnMgJiYgIWlzU1NSKSB7DQogICAgY1JlZi5vblRyYWNrID0gZGVidWdPcHRpb25zLm9uVHJhY2s7DQogICAgY1JlZi5vblRyaWdnZXIgPSBkZWJ1Z09wdGlvbnMub25UcmlnZ2VyOw0KICB9DQogIHJldHVybiBjUmVmOw0KfQ0KDQpjb25zdCBUcmFja09wVHlwZXMgPSB7DQogICJHRVQiOiAiZ2V0IiwNCiAgIkhBUyI6ICJoYXMiLA0KICAiSVRFUkFURSI6ICJpdGVyYXRlIg0KfTsNCmNvbnN0IFRyaWdnZXJPcFR5cGVzID0gew0KICAiU0VUIjogInNldCIsDQogICJBREQiOiAiYWRkIiwNCiAgIkRFTEVURSI6ICJkZWxldGUiLA0KICAiQ0xFQVIiOiAiY2xlYXIiDQp9Ow0KDQpjb25zdCBJTklUSUFMX1dBVENIRVJfVkFMVUUgPSB7fTsNCmNvbnN0IGNsZWFudXBNYXAgPSAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtNYXAoKTsNCmxldCBhY3RpdmVXYXRjaGVyID0gdm9pZCAwOw0KZnVuY3Rpb24gZ2V0Q3VycmVudFdhdGNoZXIoKSB7DQogIHJldHVybiBhY3RpdmVXYXRjaGVyOw0KfQ0KZnVuY3Rpb24gb25XYXRjaGVyQ2xlYW51cChjbGVhbnVwRm4sIGZhaWxTaWxlbnRseSA9IGZhbHNlLCBvd25lciA9IGFjdGl2ZVdhdGNoZXIpIHsNCiAgaWYgKG93bmVyKSB7DQogICAgbGV0IGNsZWFudXBzID0gY2xlYW51cE1hcC5nZXQob3duZXIpOw0KICAgIGlmICghY2xlYW51cHMpIGNsZWFudXBNYXAuc2V0KG93bmVyLCBjbGVhbnVwcyA9IFtdKTsNCiAgICBjbGVhbnVwcy5wdXNoKGNsZWFudXBGbik7DQogIH0gZWxzZSBpZiAoIWZhaWxTaWxlbnRseSkgew0KICAgIHdhcm4kMigNCiAgICAgIGBvbldhdGNoZXJDbGVhbnVwKCkgd2FzIGNhbGxlZCB3aGVuIHRoZXJlIHdhcyBubyBhY3RpdmUgd2F0Y2hlciB0byBhc3NvY2lhdGUgd2l0aC5gDQogICAgKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gd2F0Y2gkMShzb3VyY2UsIGNiLCBvcHRpb25zID0gRU1QVFlfT0JKKSB7DQogIGNvbnN0IHsgaW1tZWRpYXRlLCBkZWVwLCBvbmNlLCBzY2hlZHVsZXIsIGF1Z21lbnRKb2IsIGNhbGwgfSA9IG9wdGlvbnM7DQogIGNvbnN0IHdhcm5JbnZhbGlkU291cmNlID0gKHMpID0+IHsNCiAgICAob3B0aW9ucy5vbldhcm4gfHwgd2FybiQyKSgNCiAgICAgIGBJbnZhbGlkIHdhdGNoIHNvdXJjZTogYCwNCiAgICAgIHMsDQogICAgICBgQSB3YXRjaCBzb3VyY2UgY2FuIG9ubHkgYmUgYSBnZXR0ZXIvZWZmZWN0IGZ1bmN0aW9uLCBhIHJlZiwgYSByZWFjdGl2ZSBvYmplY3QsIG9yIGFuIGFycmF5IG9mIHRoZXNlIHR5cGVzLmANCiAgICApOw0KICB9Ow0KICBjb25zdCByZWFjdGl2ZUdldHRlciA9IChzb3VyY2UyKSA9PiB7DQogICAgaWYgKGRlZXApIHJldHVybiBzb3VyY2UyOw0KICAgIGlmIChpc1NoYWxsb3coc291cmNlMikgfHwgZGVlcCA9PT0gZmFsc2UgfHwgZGVlcCA9PT0gMCkNCiAgICAgIHJldHVybiB0cmF2ZXJzZShzb3VyY2UyLCAxKTsNCiAgICByZXR1cm4gdHJhdmVyc2Uoc291cmNlMik7DQogIH07DQogIGxldCBlZmZlY3Q7DQogIGxldCBnZXR0ZXI7DQogIGxldCBjbGVhbnVwOw0KICBsZXQgYm91bmRDbGVhbnVwOw0KICBsZXQgZm9yY2VUcmlnZ2VyID0gZmFsc2U7DQogIGxldCBpc011bHRpU291cmNlID0gZmFsc2U7DQogIGlmIChpc1JlZihzb3VyY2UpKSB7DQogICAgZ2V0dGVyID0gKCkgPT4gc291cmNlLnZhbHVlOw0KICAgIGZvcmNlVHJpZ2dlciA9IGlzU2hhbGxvdyhzb3VyY2UpOw0KICB9IGVsc2UgaWYgKGlzUmVhY3RpdmUoc291cmNlKSkgew0KICAgIGdldHRlciA9ICgpID0+IHJlYWN0aXZlR2V0dGVyKHNvdXJjZSk7DQogICAgZm9yY2VUcmlnZ2VyID0gdHJ1ZTsNCiAgfSBlbHNlIGlmIChpc0FycmF5KHNvdXJjZSkpIHsNCiAgICBpc011bHRpU291cmNlID0gdHJ1ZTsNCiAgICBmb3JjZVRyaWdnZXIgPSBzb3VyY2Uuc29tZSgocykgPT4gaXNSZWFjdGl2ZShzKSB8fCBpc1NoYWxsb3cocykpOw0KICAgIGdldHRlciA9ICgpID0+IHNvdXJjZS5tYXAoKHMpID0+IHsNCiAgICAgIGlmIChpc1JlZihzKSkgew0KICAgICAgICByZXR1cm4gcy52YWx1ZTsNCiAgICAgIH0gZWxzZSBpZiAoaXNSZWFjdGl2ZShzKSkgew0KICAgICAgICByZXR1cm4gcmVhY3RpdmVHZXR0ZXIocyk7DQogICAgICB9IGVsc2UgaWYgKGlzRnVuY3Rpb24ocykpIHsNCiAgICAgICAgcmV0dXJuIGNhbGwgPyBjYWxsKHMsIDIpIDogcygpOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgd2FybkludmFsaWRTb3VyY2Uocyk7DQogICAgICB9DQogICAgfSk7DQogIH0gZWxzZSBpZiAoaXNGdW5jdGlvbihzb3VyY2UpKSB7DQogICAgaWYgKGNiKSB7DQogICAgICBnZXR0ZXIgPSBjYWxsID8gKCkgPT4gY2FsbChzb3VyY2UsIDIpIDogc291cmNlOw0KICAgIH0gZWxzZSB7DQogICAgICBnZXR0ZXIgPSAoKSA9PiB7DQogICAgICAgIGlmIChjbGVhbnVwKSB7DQogICAgICAgICAgcGF1c2VUcmFja2luZygpOw0KICAgICAgICAgIHRyeSB7DQogICAgICAgICAgICBjbGVhbnVwKCk7DQogICAgICAgICAgfSBmaW5hbGx5IHsNCiAgICAgICAgICAgIHJlc2V0VHJhY2tpbmcoKTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgY29uc3QgY3VycmVudEVmZmVjdCA9IGFjdGl2ZVdhdGNoZXI7DQogICAgICAgIGFjdGl2ZVdhdGNoZXIgPSBlZmZlY3Q7DQogICAgICAgIHRyeSB7DQogICAgICAgICAgcmV0dXJuIGNhbGwgPyBjYWxsKHNvdXJjZSwgMywgW2JvdW5kQ2xlYW51cF0pIDogc291cmNlKGJvdW5kQ2xlYW51cCk7DQogICAgICAgIH0gZmluYWxseSB7DQogICAgICAgICAgYWN0aXZlV2F0Y2hlciA9IGN1cnJlbnRFZmZlY3Q7DQogICAgICAgIH0NCiAgICAgIH07DQogICAgfQ0KICB9IGVsc2Ugew0KICAgIGdldHRlciA9IE5PT1A7DQogICAgd2FybkludmFsaWRTb3VyY2Uoc291cmNlKTsNCiAgfQ0KICBpZiAoY2IgJiYgZGVlcCkgew0KICAgIGNvbnN0IGJhc2VHZXR0ZXIgPSBnZXR0ZXI7DQogICAgY29uc3QgZGVwdGggPSBkZWVwID09PSB0cnVlID8gSW5maW5pdHkgOiBkZWVwOw0KICAgIGdldHRlciA9ICgpID0+IHRyYXZlcnNlKGJhc2VHZXR0ZXIoKSwgZGVwdGgpOw0KICB9DQogIGNvbnN0IHNjb3BlID0gZ2V0Q3VycmVudFNjb3BlKCk7DQogIGNvbnN0IHdhdGNoSGFuZGxlID0gKCkgPT4gew0KICAgIGVmZmVjdC5zdG9wKCk7DQogICAgaWYgKHNjb3BlICYmIHNjb3BlLmFjdGl2ZSkgew0KICAgICAgcmVtb3ZlKHNjb3BlLmVmZmVjdHMsIGVmZmVjdCk7DQogICAgfQ0KICB9Ow0KICBpZiAob25jZSAmJiBjYikgew0KICAgIGNvbnN0IF9jYiA9IGNiOw0KICAgIGNiID0gKC4uLmFyZ3MpID0+IHsNCiAgICAgIF9jYiguLi5hcmdzKTsNCiAgICAgIHdhdGNoSGFuZGxlKCk7DQogICAgfTsNCiAgfQ0KICBsZXQgb2xkVmFsdWUgPSBpc011bHRpU291cmNlID8gbmV3IEFycmF5KHNvdXJjZS5sZW5ndGgpLmZpbGwoSU5JVElBTF9XQVRDSEVSX1ZBTFVFKSA6IElOSVRJQUxfV0FUQ0hFUl9WQUxVRTsNCiAgY29uc3Qgam9iID0gKGltbWVkaWF0ZUZpcnN0UnVuKSA9PiB7DQogICAgaWYgKCEoZWZmZWN0LmZsYWdzICYgMSkgfHwgIWVmZmVjdC5kaXJ0eSAmJiAhaW1tZWRpYXRlRmlyc3RSdW4pIHsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgaWYgKGNiKSB7DQogICAgICBjb25zdCBuZXdWYWx1ZSA9IGVmZmVjdC5ydW4oKTsNCiAgICAgIGlmIChkZWVwIHx8IGZvcmNlVHJpZ2dlciB8fCAoaXNNdWx0aVNvdXJjZSA/IG5ld1ZhbHVlLnNvbWUoKHYsIGkpID0+IGhhc0NoYW5nZWQodiwgb2xkVmFsdWVbaV0pKSA6IGhhc0NoYW5nZWQobmV3VmFsdWUsIG9sZFZhbHVlKSkpIHsNCiAgICAgICAgaWYgKGNsZWFudXApIHsNCiAgICAgICAgICBjbGVhbnVwKCk7DQogICAgICAgIH0NCiAgICAgICAgY29uc3QgY3VycmVudFdhdGNoZXIgPSBhY3RpdmVXYXRjaGVyOw0KICAgICAgICBhY3RpdmVXYXRjaGVyID0gZWZmZWN0Ow0KICAgICAgICB0cnkgew0KICAgICAgICAgIGNvbnN0IGFyZ3MgPSBbDQogICAgICAgICAgICBuZXdWYWx1ZSwNCiAgICAgICAgICAgIC8vIHBhc3MgdW5kZWZpbmVkIGFzIHRoZSBvbGQgdmFsdWUgd2hlbiBpdCdzIGNoYW5nZWQgZm9yIHRoZSBmaXJzdCB0aW1lDQogICAgICAgICAgICBvbGRWYWx1ZSA9PT0gSU5JVElBTF9XQVRDSEVSX1ZBTFVFID8gdm9pZCAwIDogaXNNdWx0aVNvdXJjZSAmJiBvbGRWYWx1ZVswXSA9PT0gSU5JVElBTF9XQVRDSEVSX1ZBTFVFID8gW10gOiBvbGRWYWx1ZSwNCiAgICAgICAgICAgIGJvdW5kQ2xlYW51cA0KICAgICAgICAgIF07DQogICAgICAgICAgb2xkVmFsdWUgPSBuZXdWYWx1ZTsNCiAgICAgICAgICBjYWxsID8gY2FsbChjYiwgMywgYXJncykgOiAoDQogICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yDQogICAgICAgICAgICBjYiguLi5hcmdzKQ0KICAgICAgICAgICk7DQogICAgICAgIH0gZmluYWxseSB7DQogICAgICAgICAgYWN0aXZlV2F0Y2hlciA9IGN1cnJlbnRXYXRjaGVyOw0KICAgICAgICB9DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIGVmZmVjdC5ydW4oKTsNCiAgICB9DQogIH07DQogIGlmIChhdWdtZW50Sm9iKSB7DQogICAgYXVnbWVudEpvYihqb2IpOw0KICB9DQogIGVmZmVjdCA9IG5ldyBSZWFjdGl2ZUVmZmVjdChnZXR0ZXIpOw0KICBlZmZlY3Quc2NoZWR1bGVyID0gc2NoZWR1bGVyID8gKCkgPT4gc2NoZWR1bGVyKGpvYiwgZmFsc2UpIDogam9iOw0KICBib3VuZENsZWFudXAgPSAoZm4pID0+IG9uV2F0Y2hlckNsZWFudXAoZm4sIGZhbHNlLCBlZmZlY3QpOw0KICBjbGVhbnVwID0gZWZmZWN0Lm9uU3RvcCA9ICgpID0+IHsNCiAgICBjb25zdCBjbGVhbnVwcyA9IGNsZWFudXBNYXAuZ2V0KGVmZmVjdCk7DQogICAgaWYgKGNsZWFudXBzKSB7DQogICAgICBpZiAoY2FsbCkgew0KICAgICAgICBjYWxsKGNsZWFudXBzLCA0KTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGZvciAoY29uc3QgY2xlYW51cDIgb2YgY2xlYW51cHMpIGNsZWFudXAyKCk7DQogICAgICB9DQogICAgICBjbGVhbnVwTWFwLmRlbGV0ZShlZmZlY3QpOw0KICAgIH0NCiAgfTsNCiAgew0KICAgIGVmZmVjdC5vblRyYWNrID0gb3B0aW9ucy5vblRyYWNrOw0KICAgIGVmZmVjdC5vblRyaWdnZXIgPSBvcHRpb25zLm9uVHJpZ2dlcjsNCiAgfQ0KICBpZiAoY2IpIHsNCiAgICBpZiAoaW1tZWRpYXRlKSB7DQogICAgICBqb2IodHJ1ZSk7DQogICAgfSBlbHNlIHsNCiAgICAgIG9sZFZhbHVlID0gZWZmZWN0LnJ1bigpOw0KICAgIH0NCiAgfSBlbHNlIGlmIChzY2hlZHVsZXIpIHsNCiAgICBzY2hlZHVsZXIoam9iLmJpbmQobnVsbCwgdHJ1ZSksIHRydWUpOw0KICB9IGVsc2Ugew0KICAgIGVmZmVjdC5ydW4oKTsNCiAgfQ0KICB3YXRjaEhhbmRsZS5wYXVzZSA9IGVmZmVjdC5wYXVzZS5iaW5kKGVmZmVjdCk7DQogIHdhdGNoSGFuZGxlLnJlc3VtZSA9IGVmZmVjdC5yZXN1bWUuYmluZChlZmZlY3QpOw0KICB3YXRjaEhhbmRsZS5zdG9wID0gd2F0Y2hIYW5kbGU7DQogIHJldHVybiB3YXRjaEhhbmRsZTsNCn0NCmZ1bmN0aW9uIHRyYXZlcnNlKHZhbHVlLCBkZXB0aCA9IEluZmluaXR5LCBzZWVuKSB7DQogIGlmIChkZXB0aCA8PSAwIHx8ICFpc09iamVjdCh2YWx1ZSkgfHwgdmFsdWVbIl9fdl9za2lwIl0pIHsNCiAgICByZXR1cm4gdmFsdWU7DQogIH0NCiAgc2VlbiA9IHNlZW4gfHwgLyogQF9fUFVSRV9fICovIG5ldyBTZXQoKTsNCiAgaWYgKHNlZW4uaGFzKHZhbHVlKSkgew0KICAgIHJldHVybiB2YWx1ZTsNCiAgfQ0KICBzZWVuLmFkZCh2YWx1ZSk7DQogIGRlcHRoLS07DQogIGlmIChpc1JlZih2YWx1ZSkpIHsNCiAgICB0cmF2ZXJzZSh2YWx1ZS52YWx1ZSwgZGVwdGgsIHNlZW4pOw0KICB9IGVsc2UgaWYgKGlzQXJyYXkodmFsdWUpKSB7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykgew0KICAgICAgdHJhdmVyc2UodmFsdWVbaV0sIGRlcHRoLCBzZWVuKTsNCiAgICB9DQogIH0gZWxzZSBpZiAoaXNTZXQodmFsdWUpIHx8IGlzTWFwKHZhbHVlKSkgew0KICAgIHZhbHVlLmZvckVhY2goKHYpID0+IHsNCiAgICAgIHRyYXZlcnNlKHYsIGRlcHRoLCBzZWVuKTsNCiAgICB9KTsNCiAgfSBlbHNlIGlmIChpc1BsYWluT2JqZWN0KHZhbHVlKSkgew0KICAgIGZvciAoY29uc3Qga2V5IGluIHZhbHVlKSB7DQogICAgICB0cmF2ZXJzZSh2YWx1ZVtrZXldLCBkZXB0aCwgc2Vlbik7DQogICAgfQ0KICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHModmFsdWUpKSB7DQogICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHZhbHVlLCBrZXkpKSB7DQogICAgICAgIHRyYXZlcnNlKHZhbHVlW2tleV0sIGRlcHRoLCBzZWVuKTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgcmV0dXJuIHZhbHVlOw0KfQ0KDQpjb25zdCBzdGFjayA9IFtdOw0KZnVuY3Rpb24gcHVzaFdhcm5pbmdDb250ZXh0KHZub2RlKSB7DQogIHN0YWNrLnB1c2godm5vZGUpOw0KfQ0KZnVuY3Rpb24gcG9wV2FybmluZ0NvbnRleHQoKSB7DQogIHN0YWNrLnBvcCgpOw0KfQ0KbGV0IGlzV2FybmluZyA9IGZhbHNlOw0KZnVuY3Rpb24gd2FybiQxKG1zZywgLi4uYXJncykgew0KICBpZiAoaXNXYXJuaW5nKSByZXR1cm47DQogIGlzV2FybmluZyA9IHRydWU7DQogIHBhdXNlVHJhY2tpbmcoKTsNCiAgY29uc3QgaW5zdGFuY2UgPSBzdGFjay5sZW5ndGggPyBzdGFja1tzdGFjay5sZW5ndGggLSAxXS5jb21wb25lbnQgOiBudWxsOw0KICBjb25zdCBhcHBXYXJuSGFuZGxlciA9IGluc3RhbmNlICYmIGluc3RhbmNlLmFwcENvbnRleHQuY29uZmlnLndhcm5IYW5kbGVyOw0KICBjb25zdCB0cmFjZSA9IGdldENvbXBvbmVudFRyYWNlKCk7DQogIGlmIChhcHBXYXJuSGFuZGxlcikgew0KICAgIGNhbGxXaXRoRXJyb3JIYW5kbGluZygNCiAgICAgIGFwcFdhcm5IYW5kbGVyLA0KICAgICAgaW5zdGFuY2UsDQogICAgICAxMSwNCiAgICAgIFsNCiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4DQogICAgICAgIG1zZyArIGFyZ3MubWFwKChhKSA9PiB7DQogICAgICAgICAgdmFyIF9hLCBfYjsNCiAgICAgICAgICByZXR1cm4gKF9iID0gKF9hID0gYS50b1N0cmluZykgPT0gbnVsbCA/IHZvaWQgMCA6IF9hLmNhbGwoYSkpICE9IG51bGwgPyBfYiA6IEpTT04uc3RyaW5naWZ5KGEpOw0KICAgICAgICB9KS5qb2luKCIiKSwNCiAgICAgICAgaW5zdGFuY2UgJiYgaW5zdGFuY2UucHJveHksDQogICAgICAgIHRyYWNlLm1hcCgNCiAgICAgICAgICAoeyB2bm9kZSB9KSA9PiBgYXQgPCR7Zm9ybWF0Q29tcG9uZW50TmFtZShpbnN0YW5jZSwgdm5vZGUudHlwZSl9PmANCiAgICAgICAgKS5qb2luKCJcbiIpLA0KICAgICAgICB0cmFjZQ0KICAgICAgXQ0KICAgICk7DQogIH0gZWxzZSB7DQogICAgY29uc3Qgd2FybkFyZ3MgPSBbYFtWdWUgd2Fybl06ICR7bXNnfWAsIC4uLmFyZ3NdOw0KICAgIGlmICh0cmFjZS5sZW5ndGggJiYgLy8gYXZvaWQgc3BhbW1pbmcgY29uc29sZSBkdXJpbmcgdGVzdHMNCiAgICB0cnVlKSB7DQogICAgICB3YXJuQXJncy5wdXNoKGANCmAsIC4uLmZvcm1hdFRyYWNlKHRyYWNlKSk7DQogICAgfQ0KICAgIGNvbnNvbGUud2FybiguLi53YXJuQXJncyk7DQogIH0NCiAgcmVzZXRUcmFja2luZygpOw0KICBpc1dhcm5pbmcgPSBmYWxzZTsNCn0NCmZ1bmN0aW9uIGdldENvbXBvbmVudFRyYWNlKCkgew0KICBsZXQgY3VycmVudFZOb2RlID0gc3RhY2tbc3RhY2subGVuZ3RoIC0gMV07DQogIGlmICghY3VycmVudFZOb2RlKSB7DQogICAgcmV0dXJuIFtdOw0KICB9DQogIGNvbnN0IG5vcm1hbGl6ZWRTdGFjayA9IFtdOw0KICB3aGlsZSAoY3VycmVudFZOb2RlKSB7DQogICAgY29uc3QgbGFzdCA9IG5vcm1hbGl6ZWRTdGFja1swXTsNCiAgICBpZiAobGFzdCAmJiBsYXN0LnZub2RlID09PSBjdXJyZW50Vk5vZGUpIHsNCiAgICAgIGxhc3QucmVjdXJzZUNvdW50Kys7DQogICAgfSBlbHNlIHsNCiAgICAgIG5vcm1hbGl6ZWRTdGFjay5wdXNoKHsNCiAgICAgICAgdm5vZGU6IGN1cnJlbnRWTm9kZSwNCiAgICAgICAgcmVjdXJzZUNvdW50OiAwDQogICAgICB9KTsNCiAgICB9DQogICAgY29uc3QgcGFyZW50SW5zdGFuY2UgPSBjdXJyZW50Vk5vZGUuY29tcG9uZW50ICYmIGN1cnJlbnRWTm9kZS5jb21wb25lbnQucGFyZW50Ow0KICAgIGN1cnJlbnRWTm9kZSA9IHBhcmVudEluc3RhbmNlICYmIHBhcmVudEluc3RhbmNlLnZub2RlOw0KICB9DQogIHJldHVybiBub3JtYWxpemVkU3RhY2s7DQp9DQpmdW5jdGlvbiBmb3JtYXRUcmFjZSh0cmFjZSkgew0KICBjb25zdCBsb2dzID0gW107DQogIHRyYWNlLmZvckVhY2goKGVudHJ5LCBpKSA9PiB7DQogICAgbG9ncy5wdXNoKC4uLmkgPT09IDAgPyBbXSA6IFtgDQpgXSwgLi4uZm9ybWF0VHJhY2VFbnRyeShlbnRyeSkpOw0KICB9KTsNCiAgcmV0dXJuIGxvZ3M7DQp9DQpmdW5jdGlvbiBmb3JtYXRUcmFjZUVudHJ5KHsgdm5vZGUsIHJlY3Vyc2VDb3VudCB9KSB7DQogIGNvbnN0IHBvc3RmaXggPSByZWN1cnNlQ291bnQgPiAwID8gYC4uLiAoJHtyZWN1cnNlQ291bnR9IHJlY3Vyc2l2ZSBjYWxscylgIDogYGA7DQogIGNvbnN0IGlzUm9vdCA9IHZub2RlLmNvbXBvbmVudCA/IHZub2RlLmNvbXBvbmVudC5wYXJlbnQgPT0gbnVsbCA6IGZhbHNlOw0KICBjb25zdCBvcGVuID0gYCBhdCA8JHtmb3JtYXRDb21wb25lbnROYW1lKA0KICAgIHZub2RlLmNvbXBvbmVudCwNCiAgICB2bm9kZS50eXBlLA0KICAgIGlzUm9vdA0KICApfWA7DQogIGNvbnN0IGNsb3NlID0gYD5gICsgcG9zdGZpeDsNCiAgcmV0dXJuIHZub2RlLnByb3BzID8gW29wZW4sIC4uLmZvcm1hdFByb3BzKHZub2RlLnByb3BzKSwgY2xvc2VdIDogW29wZW4gKyBjbG9zZV07DQp9DQpmdW5jdGlvbiBmb3JtYXRQcm9wcyhwcm9wcykgew0KICBjb25zdCByZXMgPSBbXTsNCiAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHByb3BzKTsNCiAga2V5cy5zbGljZSgwLCAzKS5mb3JFYWNoKChrZXkpID0+IHsNCiAgICByZXMucHVzaCguLi5mb3JtYXRQcm9wKGtleSwgcHJvcHNba2V5XSkpOw0KICB9KTsNCiAgaWYgKGtleXMubGVuZ3RoID4gMykgew0KICAgIHJlcy5wdXNoKGAgLi4uYCk7DQogIH0NCiAgcmV0dXJuIHJlczsNCn0NCmZ1bmN0aW9uIGZvcm1hdFByb3Aoa2V5LCB2YWx1ZSwgcmF3KSB7DQogIGlmIChpc1N0cmluZyh2YWx1ZSkpIHsNCiAgICB2YWx1ZSA9IEpTT04uc3RyaW5naWZ5KHZhbHVlKTsNCiAgICByZXR1cm4gcmF3ID8gdmFsdWUgOiBbYCR7a2V5fT0ke3ZhbHVlfWBdOw0KICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gIm51bWJlciIgfHwgdHlwZW9mIHZhbHVlID09PSAiYm9vbGVhbiIgfHwgdmFsdWUgPT0gbnVsbCkgew0KICAgIHJldHVybiByYXcgPyB2YWx1ZSA6IFtgJHtrZXl9PSR7dmFsdWV9YF07DQogIH0gZWxzZSBpZiAoaXNSZWYodmFsdWUpKSB7DQogICAgdmFsdWUgPSBmb3JtYXRQcm9wKGtleSwgdG9SYXcodmFsdWUudmFsdWUpLCB0cnVlKTsNCiAgICByZXR1cm4gcmF3ID8gdmFsdWUgOiBbYCR7a2V5fT1SZWY8YCwgdmFsdWUsIGA+YF07DQogIH0gZWxzZSBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHsNCiAgICByZXR1cm4gW2Ake2tleX09Zm4ke3ZhbHVlLm5hbWUgPyBgPCR7dmFsdWUubmFtZX0+YCA6IGBgfWBdOw0KICB9IGVsc2Ugew0KICAgIHZhbHVlID0gdG9SYXcodmFsdWUpOw0KICAgIHJldHVybiByYXcgPyB2YWx1ZSA6IFtgJHtrZXl9PWAsIHZhbHVlXTsNCiAgfQ0KfQ0KZnVuY3Rpb24gYXNzZXJ0TnVtYmVyKHZhbCwgdHlwZSkgew0KICBpZiAodmFsID09PSB2b2lkIDApIHsNCiAgICByZXR1cm47DQogIH0gZWxzZSBpZiAodHlwZW9mIHZhbCAhPT0gIm51bWJlciIpIHsNCiAgICB3YXJuJDEoYCR7dHlwZX0gaXMgbm90IGEgdmFsaWQgbnVtYmVyIC0gZ290ICR7SlNPTi5zdHJpbmdpZnkodmFsKX0uYCk7DQogIH0gZWxzZSBpZiAoaXNOYU4odmFsKSkgew0KICAgIHdhcm4kMShgJHt0eXBlfSBpcyBOYU4gLSB0aGUgZHVyYXRpb24gZXhwcmVzc2lvbiBtaWdodCBiZSBpbmNvcnJlY3QuYCk7DQogIH0NCn0NCg0KY29uc3QgRXJyb3JDb2RlcyA9IHsNCiAgIlNFVFVQX0ZVTkNUSU9OIjogMCwNCiAgIjAiOiAiU0VUVVBfRlVOQ1RJT04iLA0KICAiUkVOREVSX0ZVTkNUSU9OIjogMSwNCiAgIjEiOiAiUkVOREVSX0ZVTkNUSU9OIiwNCiAgIk5BVElWRV9FVkVOVF9IQU5ETEVSIjogNSwNCiAgIjUiOiAiTkFUSVZFX0VWRU5UX0hBTkRMRVIiLA0KICAiQ09NUE9ORU5UX0VWRU5UX0hBTkRMRVIiOiA2LA0KICAiNiI6ICJDT01QT05FTlRfRVZFTlRfSEFORExFUiIsDQogICJWTk9ERV9IT09LIjogNywNCiAgIjciOiAiVk5PREVfSE9PSyIsDQogICJESVJFQ1RJVkVfSE9PSyI6IDgsDQogICI4IjogIkRJUkVDVElWRV9IT09LIiwNCiAgIlRSQU5TSVRJT05fSE9PSyI6IDksDQogICI5IjogIlRSQU5TSVRJT05fSE9PSyIsDQogICJBUFBfRVJST1JfSEFORExFUiI6IDEwLA0KICAiMTAiOiAiQVBQX0VSUk9SX0hBTkRMRVIiLA0KICAiQVBQX1dBUk5fSEFORExFUiI6IDExLA0KICAiMTEiOiAiQVBQX1dBUk5fSEFORExFUiIsDQogICJGVU5DVElPTl9SRUYiOiAxMiwNCiAgIjEyIjogIkZVTkNUSU9OX1JFRiIsDQogICJBU1lOQ19DT01QT05FTlRfTE9BREVSIjogMTMsDQogICIxMyI6ICJBU1lOQ19DT01QT05FTlRfTE9BREVSIiwNCiAgIlNDSEVEVUxFUiI6IDE0LA0KICAiMTQiOiAiU0NIRURVTEVSIiwNCiAgIkNPTVBPTkVOVF9VUERBVEUiOiAxNSwNCiAgIjE1IjogIkNPTVBPTkVOVF9VUERBVEUiLA0KICAiQVBQX1VOTU9VTlRfQ0xFQU5VUCI6IDE2LA0KICAiMTYiOiAiQVBQX1VOTU9VTlRfQ0xFQU5VUCINCn07DQpjb25zdCBFcnJvclR5cGVTdHJpbmdzJDEgPSB7DQogIFsic3AiXTogInNlcnZlclByZWZldGNoIGhvb2siLA0KICBbImJjIl06ICJiZWZvcmVDcmVhdGUgaG9vayIsDQogIFsiYyJdOiAiY3JlYXRlZCBob29rIiwNCiAgWyJibSJdOiAiYmVmb3JlTW91bnQgaG9vayIsDQogIFsibSJdOiAibW91bnRlZCBob29rIiwNCiAgWyJidSJdOiAiYmVmb3JlVXBkYXRlIGhvb2siLA0KICBbInUiXTogInVwZGF0ZWQiLA0KICBbImJ1bSJdOiAiYmVmb3JlVW5tb3VudCBob29rIiwNCiAgWyJ1bSJdOiAidW5tb3VudGVkIGhvb2siLA0KICBbImEiXTogImFjdGl2YXRlZCBob29rIiwNCiAgWyJkYSJdOiAiZGVhY3RpdmF0ZWQgaG9vayIsDQogIFsiZWMiXTogImVycm9yQ2FwdHVyZWQgaG9vayIsDQogIFsicnRjIl06ICJyZW5kZXJUcmFja2VkIGhvb2siLA0KICBbInJ0ZyJdOiAicmVuZGVyVHJpZ2dlcmVkIGhvb2siLA0KICBbMF06ICJzZXR1cCBmdW5jdGlvbiIsDQogIFsxXTogInJlbmRlciBmdW5jdGlvbiIsDQogIFsyXTogIndhdGNoZXIgZ2V0dGVyIiwNCiAgWzNdOiAid2F0Y2hlciBjYWxsYmFjayIsDQogIFs0XTogIndhdGNoZXIgY2xlYW51cCBmdW5jdGlvbiIsDQogIFs1XTogIm5hdGl2ZSBldmVudCBoYW5kbGVyIiwNCiAgWzZdOiAiY29tcG9uZW50IGV2ZW50IGhhbmRsZXIiLA0KICBbN106ICJ2bm9kZSBob29rIiwNCiAgWzhdOiAiZGlyZWN0aXZlIGhvb2siLA0KICBbOV06ICJ0cmFuc2l0aW9uIGhvb2siLA0KICBbMTBdOiAiYXBwIGVycm9ySGFuZGxlciIsDQogIFsxMV06ICJhcHAgd2FybkhhbmRsZXIiLA0KICBbMTJdOiAicmVmIGZ1bmN0aW9uIiwNCiAgWzEzXTogImFzeW5jIGNvbXBvbmVudCBsb2FkZXIiLA0KICBbMTRdOiAic2NoZWR1bGVyIGZsdXNoIiwNCiAgWzE1XTogImNvbXBvbmVudCB1cGRhdGUiLA0KICBbMTZdOiAiYXBwIHVubW91bnQgY2xlYW51cCBmdW5jdGlvbiINCn07DQpmdW5jdGlvbiBjYWxsV2l0aEVycm9ySGFuZGxpbmcoZm4sIGluc3RhbmNlLCB0eXBlLCBhcmdzKSB7DQogIHRyeSB7DQogICAgcmV0dXJuIGFyZ3MgPyBmbiguLi5hcmdzKSA6IGZuKCk7DQogIH0gY2F0Y2ggKGVycikgew0KICAgIGhhbmRsZUVycm9yKGVyciwgaW5zdGFuY2UsIHR5cGUpOw0KICB9DQp9DQpmdW5jdGlvbiBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZyhmbiwgaW5zdGFuY2UsIHR5cGUsIGFyZ3MpIHsNCiAgaWYgKGlzRnVuY3Rpb24oZm4pKSB7DQogICAgY29uc3QgcmVzID0gY2FsbFdpdGhFcnJvckhhbmRsaW5nKGZuLCBpbnN0YW5jZSwgdHlwZSwgYXJncyk7DQogICAgaWYgKHJlcyAmJiBpc1Byb21pc2UocmVzKSkgew0KICAgICAgcmVzLmNhdGNoKChlcnIpID0+IHsNCiAgICAgICAgaGFuZGxlRXJyb3IoZXJyLCBpbnN0YW5jZSwgdHlwZSk7DQogICAgICB9KTsNCiAgICB9DQogICAgcmV0dXJuIHJlczsNCiAgfQ0KICBpZiAoaXNBcnJheShmbikpIHsNCiAgICBjb25zdCB2YWx1ZXMgPSBbXTsNCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZuLmxlbmd0aDsgaSsrKSB7DQogICAgICB2YWx1ZXMucHVzaChjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZyhmbltpXSwgaW5zdGFuY2UsIHR5cGUsIGFyZ3MpKTsNCiAgICB9DQogICAgcmV0dXJuIHZhbHVlczsNCiAgfSBlbHNlIHsNCiAgICB3YXJuJDEoDQogICAgICBgSW52YWxpZCB2YWx1ZSB0eXBlIHBhc3NlZCB0byBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZygpOiAke3R5cGVvZiBmbn1gDQogICAgKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gaGFuZGxlRXJyb3IoZXJyLCBpbnN0YW5jZSwgdHlwZSwgdGhyb3dJbkRldiA9IHRydWUpIHsNCiAgY29uc3QgY29udGV4dFZOb2RlID0gaW5zdGFuY2UgPyBpbnN0YW5jZS52bm9kZSA6IG51bGw7DQogIGNvbnN0IHsgZXJyb3JIYW5kbGVyLCB0aHJvd1VuaGFuZGxlZEVycm9ySW5Qcm9kdWN0aW9uIH0gPSBpbnN0YW5jZSAmJiBpbnN0YW5jZS5hcHBDb250ZXh0LmNvbmZpZyB8fCBFTVBUWV9PQko7DQogIGlmIChpbnN0YW5jZSkgew0KICAgIGxldCBjdXIgPSBpbnN0YW5jZS5wYXJlbnQ7DQogICAgY29uc3QgZXhwb3NlZEluc3RhbmNlID0gaW5zdGFuY2UucHJveHk7DQogICAgY29uc3QgZXJyb3JJbmZvID0gRXJyb3JUeXBlU3RyaW5ncyQxW3R5cGVdIDsNCiAgICB3aGlsZSAoY3VyKSB7DQogICAgICBjb25zdCBlcnJvckNhcHR1cmVkSG9va3MgPSBjdXIuZWM7DQogICAgICBpZiAoZXJyb3JDYXB0dXJlZEhvb2tzKSB7DQogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXJyb3JDYXB0dXJlZEhvb2tzLmxlbmd0aDsgaSsrKSB7DQogICAgICAgICAgaWYgKGVycm9yQ2FwdHVyZWRIb29rc1tpXShlcnIsIGV4cG9zZWRJbnN0YW5jZSwgZXJyb3JJbmZvKSA9PT0gZmFsc2UpIHsNCiAgICAgICAgICAgIHJldHVybjsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGN1ciA9IGN1ci5wYXJlbnQ7DQogICAgfQ0KICAgIGlmIChlcnJvckhhbmRsZXIpIHsNCiAgICAgIHBhdXNlVHJhY2tpbmcoKTsNCiAgICAgIGNhbGxXaXRoRXJyb3JIYW5kbGluZyhlcnJvckhhbmRsZXIsIG51bGwsIDEwLCBbDQogICAgICAgIGVyciwNCiAgICAgICAgZXhwb3NlZEluc3RhbmNlLA0KICAgICAgICBlcnJvckluZm8NCiAgICAgIF0pOw0KICAgICAgcmVzZXRUcmFja2luZygpOw0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgfQ0KICBsb2dFcnJvcihlcnIsIHR5cGUsIGNvbnRleHRWTm9kZSwgdGhyb3dJbkRldiwgdGhyb3dVbmhhbmRsZWRFcnJvckluUHJvZHVjdGlvbik7DQp9DQpmdW5jdGlvbiBsb2dFcnJvcihlcnIsIHR5cGUsIGNvbnRleHRWTm9kZSwgdGhyb3dJbkRldiA9IHRydWUsIHRocm93SW5Qcm9kID0gZmFsc2UpIHsNCiAgew0KICAgIGNvbnN0IGluZm8gPSBFcnJvclR5cGVTdHJpbmdzJDFbdHlwZV07DQogICAgaWYgKGNvbnRleHRWTm9kZSkgew0KICAgICAgcHVzaFdhcm5pbmdDb250ZXh0KGNvbnRleHRWTm9kZSk7DQogICAgfQ0KICAgIHdhcm4kMShgVW5oYW5kbGVkIGVycm9yJHtpbmZvID8gYCBkdXJpbmcgZXhlY3V0aW9uIG9mICR7aW5mb31gIDogYGB9YCk7DQogICAgaWYgKGNvbnRleHRWTm9kZSkgew0KICAgICAgcG9wV2FybmluZ0NvbnRleHQoKTsNCiAgICB9DQogICAgaWYgKHRocm93SW5EZXYpIHsNCiAgICAgIHRocm93IGVycjsNCiAgICB9IGVsc2Ugew0KICAgICAgY29uc29sZS5lcnJvcihlcnIpOw0KICAgIH0NCiAgfQ0KfQ0KDQpjb25zdCBxdWV1ZSA9IFtdOw0KbGV0IGZsdXNoSW5kZXggPSAtMTsNCmNvbnN0IHBlbmRpbmdQb3N0Rmx1c2hDYnMgPSBbXTsNCmxldCBhY3RpdmVQb3N0Rmx1c2hDYnMgPSBudWxsOw0KbGV0IHBvc3RGbHVzaEluZGV4ID0gMDsNCmNvbnN0IHJlc29sdmVkUHJvbWlzZSA9IC8qIEBfX1BVUkVfXyAqLyBQcm9taXNlLnJlc29sdmUoKTsNCmxldCBjdXJyZW50Rmx1c2hQcm9taXNlID0gbnVsbDsNCmNvbnN0IFJFQ1VSU0lPTl9MSU1JVCA9IDEwMDsNCmZ1bmN0aW9uIG5leHRUaWNrKGZuKSB7DQogIGNvbnN0IHAgPSBjdXJyZW50Rmx1c2hQcm9taXNlIHx8IHJlc29sdmVkUHJvbWlzZTsNCiAgcmV0dXJuIGZuID8gcC50aGVuKHRoaXMgPyBmbi5iaW5kKHRoaXMpIDogZm4pIDogcDsNCn0NCmZ1bmN0aW9uIGZpbmRJbnNlcnRpb25JbmRleChpZCkgew0KICBsZXQgc3RhcnQgPSBmbHVzaEluZGV4ICsgMTsNCiAgbGV0IGVuZCA9IHF1ZXVlLmxlbmd0aDsNCiAgd2hpbGUgKHN0YXJ0IDwgZW5kKSB7DQogICAgY29uc3QgbWlkZGxlID0gc3RhcnQgKyBlbmQgPj4+IDE7DQogICAgY29uc3QgbWlkZGxlSm9iID0gcXVldWVbbWlkZGxlXTsNCiAgICBjb25zdCBtaWRkbGVKb2JJZCA9IGdldElkKG1pZGRsZUpvYik7DQogICAgaWYgKG1pZGRsZUpvYklkIDwgaWQgfHwgbWlkZGxlSm9iSWQgPT09IGlkICYmIG1pZGRsZUpvYi5mbGFncyAmIDIpIHsNCiAgICAgIHN0YXJ0ID0gbWlkZGxlICsgMTsNCiAgICB9IGVsc2Ugew0KICAgICAgZW5kID0gbWlkZGxlOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gc3RhcnQ7DQp9DQpmdW5jdGlvbiBxdWV1ZUpvYihqb2IpIHsNCiAgaWYgKCEoam9iLmZsYWdzICYgMSkpIHsNCiAgICBjb25zdCBqb2JJZCA9IGdldElkKGpvYik7DQogICAgY29uc3QgbGFzdEpvYiA9IHF1ZXVlW3F1ZXVlLmxlbmd0aCAtIDFdOw0KICAgIGlmICghbGFzdEpvYiB8fCAvLyBmYXN0IHBhdGggd2hlbiB0aGUgam9iIGlkIGlzIGxhcmdlciB0aGFuIHRoZSB0YWlsDQogICAgIShqb2IuZmxhZ3MgJiAyKSAmJiBqb2JJZCA+PSBnZXRJZChsYXN0Sm9iKSkgew0KICAgICAgcXVldWUucHVzaChqb2IpOw0KICAgIH0gZWxzZSB7DQogICAgICBxdWV1ZS5zcGxpY2UoZmluZEluc2VydGlvbkluZGV4KGpvYklkKSwgMCwgam9iKTsNCiAgICB9DQogICAgam9iLmZsYWdzIHw9IDE7DQogICAgcXVldWVGbHVzaCgpOw0KICB9DQp9DQpmdW5jdGlvbiBxdWV1ZUZsdXNoKCkgew0KICBpZiAoIWN1cnJlbnRGbHVzaFByb21pc2UpIHsNCiAgICBjdXJyZW50Rmx1c2hQcm9taXNlID0gcmVzb2x2ZWRQcm9taXNlLnRoZW4oZmx1c2hKb2JzKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gcXVldWVQb3N0Rmx1c2hDYihjYikgew0KICBpZiAoIWlzQXJyYXkoY2IpKSB7DQogICAgaWYgKGFjdGl2ZVBvc3RGbHVzaENicyAmJiBjYi5pZCA9PT0gLTEpIHsNCiAgICAgIGFjdGl2ZVBvc3RGbHVzaENicy5zcGxpY2UocG9zdEZsdXNoSW5kZXggKyAxLCAwLCBjYik7DQogICAgfSBlbHNlIGlmICghKGNiLmZsYWdzICYgMSkpIHsNCiAgICAgIHBlbmRpbmdQb3N0Rmx1c2hDYnMucHVzaChjYik7DQogICAgICBjYi5mbGFncyB8PSAxOw0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICBwZW5kaW5nUG9zdEZsdXNoQ2JzLnB1c2goLi4uY2IpOw0KICB9DQogIHF1ZXVlRmx1c2goKTsNCn0NCmZ1bmN0aW9uIGZsdXNoUHJlRmx1c2hDYnMoaW5zdGFuY2UsIHNlZW4sIGkgPSBmbHVzaEluZGV4ICsgMSkgew0KICB7DQogICAgc2VlbiA9IHNlZW4gfHwgLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTsNCiAgfQ0KICBmb3IgKDsgaSA8IHF1ZXVlLmxlbmd0aDsgaSsrKSB7DQogICAgY29uc3QgY2IgPSBxdWV1ZVtpXTsNCiAgICBpZiAoY2IgJiYgY2IuZmxhZ3MgJiAyKSB7DQogICAgICBpZiAoaW5zdGFuY2UgJiYgY2IuaWQgIT09IGluc3RhbmNlLnVpZCkgew0KICAgICAgICBjb250aW51ZTsNCiAgICAgIH0NCiAgICAgIGlmIChjaGVja1JlY3Vyc2l2ZVVwZGF0ZXMoc2VlbiwgY2IpKSB7DQogICAgICAgIGNvbnRpbnVlOw0KICAgICAgfQ0KICAgICAgcXVldWUuc3BsaWNlKGksIDEpOw0KICAgICAgaS0tOw0KICAgICAgaWYgKGNiLmZsYWdzICYgNCkgew0KICAgICAgICBjYi5mbGFncyAmPSAtMjsNCiAgICAgIH0NCiAgICAgIGNiKCk7DQogICAgICBpZiAoIShjYi5mbGFncyAmIDQpKSB7DQogICAgICAgIGNiLmZsYWdzICY9IC0yOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KfQ0KZnVuY3Rpb24gZmx1c2hQb3N0Rmx1c2hDYnMoc2Vlbikgew0KICBpZiAocGVuZGluZ1Bvc3RGbHVzaENicy5sZW5ndGgpIHsNCiAgICBjb25zdCBkZWR1cGVkID0gWy4uLm5ldyBTZXQocGVuZGluZ1Bvc3RGbHVzaENicyldLnNvcnQoDQogICAgICAoYSwgYikgPT4gZ2V0SWQoYSkgLSBnZXRJZChiKQ0KICAgICk7DQogICAgcGVuZGluZ1Bvc3RGbHVzaENicy5sZW5ndGggPSAwOw0KICAgIGlmIChhY3RpdmVQb3N0Rmx1c2hDYnMpIHsNCiAgICAgIGFjdGl2ZVBvc3RGbHVzaENicy5wdXNoKC4uLmRlZHVwZWQpOw0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBhY3RpdmVQb3N0Rmx1c2hDYnMgPSBkZWR1cGVkOw0KICAgIHsNCiAgICAgIHNlZW4gPSBzZWVuIHx8IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7DQogICAgfQ0KICAgIGZvciAocG9zdEZsdXNoSW5kZXggPSAwOyBwb3N0Rmx1c2hJbmRleCA8IGFjdGl2ZVBvc3RGbHVzaENicy5sZW5ndGg7IHBvc3RGbHVzaEluZGV4KyspIHsNCiAgICAgIGNvbnN0IGNiID0gYWN0aXZlUG9zdEZsdXNoQ2JzW3Bvc3RGbHVzaEluZGV4XTsNCiAgICAgIGlmIChjaGVja1JlY3Vyc2l2ZVVwZGF0ZXMoc2VlbiwgY2IpKSB7DQogICAgICAgIGNvbnRpbnVlOw0KICAgICAgfQ0KICAgICAgaWYgKGNiLmZsYWdzICYgNCkgew0KICAgICAgICBjYi5mbGFncyAmPSAtMjsNCiAgICAgIH0NCiAgICAgIGlmICghKGNiLmZsYWdzICYgOCkpIGNiKCk7DQogICAgICBjYi5mbGFncyAmPSAtMjsNCiAgICB9DQogICAgYWN0aXZlUG9zdEZsdXNoQ2JzID0gbnVsbDsNCiAgICBwb3N0Rmx1c2hJbmRleCA9IDA7DQogIH0NCn0NCmNvbnN0IGdldElkID0gKGpvYikgPT4gam9iLmlkID09IG51bGwgPyBqb2IuZmxhZ3MgJiAyID8gLTEgOiBJbmZpbml0eSA6IGpvYi5pZDsNCmZ1bmN0aW9uIGZsdXNoSm9icyhzZWVuKSB7DQogIHsNCiAgICBzZWVuID0gc2VlbiB8fCAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOw0KICB9DQogIGNvbnN0IGNoZWNrID0gKGpvYikgPT4gY2hlY2tSZWN1cnNpdmVVcGRhdGVzKHNlZW4sIGpvYikgOw0KICB0cnkgew0KICAgIGZvciAoZmx1c2hJbmRleCA9IDA7IGZsdXNoSW5kZXggPCBxdWV1ZS5sZW5ndGg7IGZsdXNoSW5kZXgrKykgew0KICAgICAgY29uc3Qgam9iID0gcXVldWVbZmx1c2hJbmRleF07DQogICAgICBpZiAoam9iICYmICEoam9iLmZsYWdzICYgOCkpIHsNCiAgICAgICAgaWYgKGNoZWNrKGpvYikpIHsNCiAgICAgICAgICBjb250aW51ZTsNCiAgICAgICAgfQ0KICAgICAgICBpZiAoam9iLmZsYWdzICYgNCkgew0KICAgICAgICAgIGpvYi5mbGFncyAmPSB+MTsNCiAgICAgICAgfQ0KICAgICAgICBjYWxsV2l0aEVycm9ySGFuZGxpbmcoDQogICAgICAgICAgam9iLA0KICAgICAgICAgIGpvYi5pLA0KICAgICAgICAgIGpvYi5pID8gMTUgOiAxNA0KICAgICAgICApOw0KICAgICAgICBpZiAoIShqb2IuZmxhZ3MgJiA0KSkgew0KICAgICAgICAgIGpvYi5mbGFncyAmPSB+MTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgfSBmaW5hbGx5IHsNCiAgICBmb3IgKDsgZmx1c2hJbmRleCA8IHF1ZXVlLmxlbmd0aDsgZmx1c2hJbmRleCsrKSB7DQogICAgICBjb25zdCBqb2IgPSBxdWV1ZVtmbHVzaEluZGV4XTsNCiAgICAgIGlmIChqb2IpIHsNCiAgICAgICAgam9iLmZsYWdzICY9IC0yOw0KICAgICAgfQ0KICAgIH0NCiAgICBmbHVzaEluZGV4ID0gLTE7DQogICAgcXVldWUubGVuZ3RoID0gMDsNCiAgICBmbHVzaFBvc3RGbHVzaENicyhzZWVuKTsNCiAgICBjdXJyZW50Rmx1c2hQcm9taXNlID0gbnVsbDsNCiAgICBpZiAocXVldWUubGVuZ3RoIHx8IHBlbmRpbmdQb3N0Rmx1c2hDYnMubGVuZ3RoKSB7DQogICAgICBmbHVzaEpvYnMoc2Vlbik7DQogICAgfQ0KICB9DQp9DQpmdW5jdGlvbiBjaGVja1JlY3Vyc2l2ZVVwZGF0ZXMoc2VlbiwgZm4pIHsNCiAgY29uc3QgY291bnQgPSBzZWVuLmdldChmbikgfHwgMDsNCiAgaWYgKGNvdW50ID4gUkVDVVJTSU9OX0xJTUlUKSB7DQogICAgY29uc3QgaW5zdGFuY2UgPSBmbi5pOw0KICAgIGNvbnN0IGNvbXBvbmVudE5hbWUgPSBpbnN0YW5jZSAmJiBnZXRDb21wb25lbnROYW1lKGluc3RhbmNlLnR5cGUpOw0KICAgIGhhbmRsZUVycm9yKA0KICAgICAgYE1heGltdW0gcmVjdXJzaXZlIHVwZGF0ZXMgZXhjZWVkZWQke2NvbXBvbmVudE5hbWUgPyBgIGluIGNvbXBvbmVudCA8JHtjb21wb25lbnROYW1lfT5gIDogYGB9LiBUaGlzIG1lYW5zIHlvdSBoYXZlIGEgcmVhY3RpdmUgZWZmZWN0IHRoYXQgaXMgbXV0YXRpbmcgaXRzIG93biBkZXBlbmRlbmNpZXMgYW5kIHRodXMgcmVjdXJzaXZlbHkgdHJpZ2dlcmluZyBpdHNlbGYuIFBvc3NpYmxlIHNvdXJjZXMgaW5jbHVkZSBjb21wb25lbnQgdGVtcGxhdGUsIHJlbmRlciBmdW5jdGlvbiwgdXBkYXRlZCBob29rIG9yIHdhdGNoZXIgc291cmNlIGZ1bmN0aW9uLmAsDQogICAgICBudWxsLA0KICAgICAgMTANCiAgICApOw0KICAgIHJldHVybiB0cnVlOw0KICB9DQogIHNlZW4uc2V0KGZuLCBjb3VudCArIDEpOw0KICByZXR1cm4gZmFsc2U7DQp9DQoNCmxldCBpc0htclVwZGF0aW5nID0gZmFsc2U7DQpjb25zdCBobXJEaXJ0eUNvbXBvbmVudHMgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOw0Kew0KICBnZXRHbG9iYWxUaGlzKCkuX19WVUVfSE1SX1JVTlRJTUVfXyA9IHsNCiAgICBjcmVhdGVSZWNvcmQ6IHRyeVdyYXAoY3JlYXRlUmVjb3JkKSwNCiAgICByZXJlbmRlcjogdHJ5V3JhcChyZXJlbmRlciksDQogICAgcmVsb2FkOiB0cnlXcmFwKHJlbG9hZCkNCiAgfTsNCn0NCmNvbnN0IG1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7DQpmdW5jdGlvbiByZWdpc3RlckhNUihpbnN0YW5jZSkgew0KICBjb25zdCBpZCA9IGluc3RhbmNlLnR5cGUuX19obXJJZDsNCiAgbGV0IHJlY29yZCA9IG1hcC5nZXQoaWQpOw0KICBpZiAoIXJlY29yZCkgew0KICAgIGNyZWF0ZVJlY29yZChpZCwgaW5zdGFuY2UudHlwZSk7DQogICAgcmVjb3JkID0gbWFwLmdldChpZCk7DQogIH0NCiAgcmVjb3JkLmluc3RhbmNlcy5hZGQoaW5zdGFuY2UpOw0KfQ0KZnVuY3Rpb24gdW5yZWdpc3RlckhNUihpbnN0YW5jZSkgew0KICBtYXAuZ2V0KGluc3RhbmNlLnR5cGUuX19obXJJZCkuaW5zdGFuY2VzLmRlbGV0ZShpbnN0YW5jZSk7DQp9DQpmdW5jdGlvbiBjcmVhdGVSZWNvcmQoaWQsIGluaXRpYWxEZWYpIHsNCiAgaWYgKG1hcC5oYXMoaWQpKSB7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9DQogIG1hcC5zZXQoaWQsIHsNCiAgICBpbml0aWFsRGVmOiBub3JtYWxpemVDbGFzc0NvbXBvbmVudChpbml0aWFsRGVmKSwNCiAgICBpbnN0YW5jZXM6IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KCkNCiAgfSk7DQogIHJldHVybiB0cnVlOw0KfQ0KZnVuY3Rpb24gbm9ybWFsaXplQ2xhc3NDb21wb25lbnQoY29tcG9uZW50KSB7DQogIHJldHVybiBpc0NsYXNzQ29tcG9uZW50KGNvbXBvbmVudCkgPyBjb21wb25lbnQuX192Y2NPcHRzIDogY29tcG9uZW50Ow0KfQ0KZnVuY3Rpb24gcmVyZW5kZXIoaWQsIG5ld1JlbmRlcikgew0KICBjb25zdCByZWNvcmQgPSBtYXAuZ2V0KGlkKTsNCiAgaWYgKCFyZWNvcmQpIHsNCiAgICByZXR1cm47DQogIH0NCiAgcmVjb3JkLmluaXRpYWxEZWYucmVuZGVyID0gbmV3UmVuZGVyOw0KICBbLi4ucmVjb3JkLmluc3RhbmNlc10uZm9yRWFjaCgoaW5zdGFuY2UpID0+IHsNCiAgICBpZiAobmV3UmVuZGVyKSB7DQogICAgICBpbnN0YW5jZS5yZW5kZXIgPSBuZXdSZW5kZXI7DQogICAgICBub3JtYWxpemVDbGFzc0NvbXBvbmVudChpbnN0YW5jZS50eXBlKS5yZW5kZXIgPSBuZXdSZW5kZXI7DQogICAgfQ0KICAgIGluc3RhbmNlLnJlbmRlckNhY2hlID0gW107DQogICAgaXNIbXJVcGRhdGluZyA9IHRydWU7DQogICAgaW5zdGFuY2UudXBkYXRlKCk7DQogICAgaXNIbXJVcGRhdGluZyA9IGZhbHNlOw0KICB9KTsNCn0NCmZ1bmN0aW9uIHJlbG9hZChpZCwgbmV3Q29tcCkgew0KICBjb25zdCByZWNvcmQgPSBtYXAuZ2V0KGlkKTsNCiAgaWYgKCFyZWNvcmQpIHJldHVybjsNCiAgbmV3Q29tcCA9IG5vcm1hbGl6ZUNsYXNzQ29tcG9uZW50KG5ld0NvbXApOw0KICB1cGRhdGVDb21wb25lbnREZWYocmVjb3JkLmluaXRpYWxEZWYsIG5ld0NvbXApOw0KICBjb25zdCBpbnN0YW5jZXMgPSBbLi4ucmVjb3JkLmluc3RhbmNlc107DQogIGZvciAobGV0IGkgPSAwOyBpIDwgaW5zdGFuY2VzLmxlbmd0aDsgaSsrKSB7DQogICAgY29uc3QgaW5zdGFuY2UgPSBpbnN0YW5jZXNbaV07DQogICAgY29uc3Qgb2xkQ29tcCA9IG5vcm1hbGl6ZUNsYXNzQ29tcG9uZW50KGluc3RhbmNlLnR5cGUpOw0KICAgIGxldCBkaXJ0eUluc3RhbmNlcyA9IGhtckRpcnR5Q29tcG9uZW50cy5nZXQob2xkQ29tcCk7DQogICAgaWYgKCFkaXJ0eUluc3RhbmNlcykgew0KICAgICAgaWYgKG9sZENvbXAgIT09IHJlY29yZC5pbml0aWFsRGVmKSB7DQogICAgICAgIHVwZGF0ZUNvbXBvbmVudERlZihvbGRDb21wLCBuZXdDb21wKTsNCiAgICAgIH0NCiAgICAgIGhtckRpcnR5Q29tcG9uZW50cy5zZXQob2xkQ29tcCwgZGlydHlJbnN0YW5jZXMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpKTsNCiAgICB9DQogICAgZGlydHlJbnN0YW5jZXMuYWRkKGluc3RhbmNlKTsNCiAgICBpbnN0YW5jZS5hcHBDb250ZXh0LnByb3BzQ2FjaGUuZGVsZXRlKGluc3RhbmNlLnR5cGUpOw0KICAgIGluc3RhbmNlLmFwcENvbnRleHQuZW1pdHNDYWNoZS5kZWxldGUoaW5zdGFuY2UudHlwZSk7DQogICAgaW5zdGFuY2UuYXBwQ29udGV4dC5vcHRpb25zQ2FjaGUuZGVsZXRlKGluc3RhbmNlLnR5cGUpOw0KICAgIGlmIChpbnN0YW5jZS5jZVJlbG9hZCkgew0KICAgICAgZGlydHlJbnN0YW5jZXMuYWRkKGluc3RhbmNlKTsNCiAgICAgIGluc3RhbmNlLmNlUmVsb2FkKG5ld0NvbXAuc3R5bGVzKTsNCiAgICAgIGRpcnR5SW5zdGFuY2VzLmRlbGV0ZShpbnN0YW5jZSk7DQogICAgfSBlbHNlIGlmIChpbnN0YW5jZS5wYXJlbnQpIHsNCiAgICAgIHF1ZXVlSm9iKCgpID0+IHsNCiAgICAgICAgaXNIbXJVcGRhdGluZyA9IHRydWU7DQogICAgICAgIGluc3RhbmNlLnBhcmVudC51cGRhdGUoKTsNCiAgICAgICAgaXNIbXJVcGRhdGluZyA9IGZhbHNlOw0KICAgICAgICBkaXJ0eUluc3RhbmNlcy5kZWxldGUoaW5zdGFuY2UpOw0KICAgICAgfSk7DQogICAgfSBlbHNlIGlmIChpbnN0YW5jZS5hcHBDb250ZXh0LnJlbG9hZCkgew0KICAgICAgaW5zdGFuY2UuYXBwQ29udGV4dC5yZWxvYWQoKTsNCiAgICB9IGVsc2UgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICJ1bmRlZmluZWQiKSB7DQogICAgICB3aW5kb3cubG9jYXRpb24ucmVsb2FkKCk7DQogICAgfSBlbHNlIHsNCiAgICAgIGNvbnNvbGUud2FybigNCiAgICAgICAgIltITVJdIFJvb3Qgb3IgbWFudWFsbHkgbW91bnRlZCBpbnN0YW5jZSBtb2RpZmllZC4gRnVsbCByZWxvYWQgcmVxdWlyZWQuIg0KICAgICAgKTsNCiAgICB9DQogICAgaWYgKGluc3RhbmNlLnJvb3QuY2UgJiYgaW5zdGFuY2UgIT09IGluc3RhbmNlLnJvb3QpIHsNCiAgICAgIGluc3RhbmNlLnJvb3QuY2UuX3JlbW92ZUNoaWxkU3R5bGUob2xkQ29tcCk7DQogICAgfQ0KICB9DQogIHF1ZXVlUG9zdEZsdXNoQ2IoKCkgPT4gew0KICAgIGhtckRpcnR5Q29tcG9uZW50cy5jbGVhcigpOw0KICB9KTsNCn0NCmZ1bmN0aW9uIHVwZGF0ZUNvbXBvbmVudERlZihvbGRDb21wLCBuZXdDb21wKSB7DQogIGV4dGVuZChvbGRDb21wLCBuZXdDb21wKTsNCiAgZm9yIChjb25zdCBrZXkgaW4gb2xkQ29tcCkgew0KICAgIGlmIChrZXkgIT09ICJfX2ZpbGUiICYmICEoa2V5IGluIG5ld0NvbXApKSB7DQogICAgICBkZWxldGUgb2xkQ29tcFtrZXldOw0KICAgIH0NCiAgfQ0KfQ0KZnVuY3Rpb24gdHJ5V3JhcChmbikgew0KICByZXR1cm4gKGlkLCBhcmcpID0+IHsNCiAgICB0cnkgew0KICAgICAgcmV0dXJuIGZuKGlkLCBhcmcpOw0KICAgIH0gY2F0Y2ggKGUpIHsNCiAgICAgIGNvbnNvbGUuZXJyb3IoZSk7DQogICAgICBjb25zb2xlLndhcm4oDQogICAgICAgIGBbSE1SXSBTb21ldGhpbmcgd2VudCB3cm9uZyBkdXJpbmcgVnVlIGNvbXBvbmVudCBob3QtcmVsb2FkLiBGdWxsIHJlbG9hZCByZXF1aXJlZC5gDQogICAgICApOw0KICAgIH0NCiAgfTsNCn0NCg0KbGV0IGRldnRvb2xzJDE7DQpsZXQgYnVmZmVyID0gW107DQpsZXQgZGV2dG9vbHNOb3RJbnN0YWxsZWQgPSBmYWxzZTsNCmZ1bmN0aW9uIGVtaXQkMShldmVudCwgLi4uYXJncykgew0KICBpZiAoZGV2dG9vbHMkMSkgew0KICAgIGRldnRvb2xzJDEuZW1pdChldmVudCwgLi4uYXJncyk7DQogIH0gZWxzZSBpZiAoIWRldnRvb2xzTm90SW5zdGFsbGVkKSB7DQogICAgYnVmZmVyLnB1c2goeyBldmVudCwgYXJncyB9KTsNCiAgfQ0KfQ0KZnVuY3Rpb24gc2V0RGV2dG9vbHNIb29rJDEoaG9vaywgdGFyZ2V0KSB7DQogIHZhciBfYSwgX2I7DQogIGRldnRvb2xzJDEgPSBob29rOw0KICBpZiAoZGV2dG9vbHMkMSkgew0KICAgIGRldnRvb2xzJDEuZW5hYmxlZCA9IHRydWU7DQogICAgYnVmZmVyLmZvckVhY2goKHsgZXZlbnQsIGFyZ3MgfSkgPT4gZGV2dG9vbHMkMS5lbWl0KGV2ZW50LCAuLi5hcmdzKSk7DQogICAgYnVmZmVyID0gW107DQogIH0gZWxzZSBpZiAoDQogICAgLy8gaGFuZGxlIGxhdGUgZGV2dG9vbHMgaW5qZWN0aW9uIC0gb25seSBkbyB0aGlzIGlmIHdlIGFyZSBpbiBhbiBhY3R1YWwNCiAgICAvLyBicm93c2VyIGVudmlyb25tZW50IHRvIGF2b2lkIHRoZSB0aW1lciBoYW5kbGUgc3RhbGxpbmcgdGVzdCBydW5uZXIgZXhpdA0KICAgIC8vICgjNDgxNSkNCiAgICB0eXBlb2Ygd2luZG93ICE9PSAidW5kZWZpbmVkIiAmJiAvLyBzb21lIGVudnMgbW9jayB3aW5kb3cgYnV0IG5vdCBmdWxseQ0KICAgIHdpbmRvdy5IVE1MRWxlbWVudCAmJiAvLyBhbHNvIGV4Y2x1ZGUganNkb20NCiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXgNCiAgICAhKChfYiA9IChfYSA9IHdpbmRvdy5uYXZpZ2F0b3IpID09IG51bGwgPyB2b2lkIDAgOiBfYS51c2VyQWdlbnQpID09IG51bGwgPyB2b2lkIDAgOiBfYi5pbmNsdWRlcygianNkb20iKSkNCiAgKSB7DQogICAgY29uc3QgcmVwbGF5ID0gdGFyZ2V0Ll9fVlVFX0RFVlRPT0xTX0hPT0tfUkVQTEFZX18gPSB0YXJnZXQuX19WVUVfREVWVE9PTFNfSE9PS19SRVBMQVlfXyB8fCBbXTsNCiAgICByZXBsYXkucHVzaCgobmV3SG9vaykgPT4gew0KICAgICAgc2V0RGV2dG9vbHNIb29rJDEobmV3SG9vaywgdGFyZ2V0KTsNCiAgICB9KTsNCiAgICBzZXRUaW1lb3V0KCgpID0+IHsNCiAgICAgIGlmICghZGV2dG9vbHMkMSkgew0KICAgICAgICB0YXJnZXQuX19WVUVfREVWVE9PTFNfSE9PS19SRVBMQVlfXyA9IG51bGw7DQogICAgICAgIGRldnRvb2xzTm90SW5zdGFsbGVkID0gdHJ1ZTsNCiAgICAgICAgYnVmZmVyID0gW107DQogICAgICB9DQogICAgfSwgM2UzKTsNCiAgfSBlbHNlIHsNCiAgICBkZXZ0b29sc05vdEluc3RhbGxlZCA9IHRydWU7DQogICAgYnVmZmVyID0gW107DQogIH0NCn0NCmZ1bmN0aW9uIGRldnRvb2xzSW5pdEFwcChhcHAsIHZlcnNpb24pIHsNCiAgZW1pdCQxKCJhcHA6aW5pdCIgLyogQVBQX0lOSVQgKi8sIGFwcCwgdmVyc2lvbiwgew0KICAgIEZyYWdtZW50LA0KICAgIFRleHQsDQogICAgQ29tbWVudCwNCiAgICBTdGF0aWMNCiAgfSk7DQp9DQpmdW5jdGlvbiBkZXZ0b29sc1VubW91bnRBcHAoYXBwKSB7DQogIGVtaXQkMSgiYXBwOnVubW91bnQiIC8qIEFQUF9VTk1PVU5UICovLCBhcHApOw0KfQ0KY29uc3QgZGV2dG9vbHNDb21wb25lbnRBZGRlZCA9IC8qIEBfX1BVUkVfXyAqLyBjcmVhdGVEZXZ0b29sc0NvbXBvbmVudEhvb2soImNvbXBvbmVudDphZGRlZCIgLyogQ09NUE9ORU5UX0FEREVEICovKTsNCmNvbnN0IGRldnRvb2xzQ29tcG9uZW50VXBkYXRlZCA9IC8qIEBfX1BVUkVfXyAqLyBjcmVhdGVEZXZ0b29sc0NvbXBvbmVudEhvb2soImNvbXBvbmVudDp1cGRhdGVkIiAvKiBDT01QT05FTlRfVVBEQVRFRCAqLyk7DQpjb25zdCBfZGV2dG9vbHNDb21wb25lbnRSZW1vdmVkID0gLyogQF9fUFVSRV9fICovIGNyZWF0ZURldnRvb2xzQ29tcG9uZW50SG9vaygNCiAgImNvbXBvbmVudDpyZW1vdmVkIiAvKiBDT01QT05FTlRfUkVNT1ZFRCAqLw0KKTsNCmNvbnN0IGRldnRvb2xzQ29tcG9uZW50UmVtb3ZlZCA9IChjb21wb25lbnQpID0+IHsNCiAgaWYgKGRldnRvb2xzJDEgJiYgdHlwZW9mIGRldnRvb2xzJDEuY2xlYW51cEJ1ZmZlciA9PT0gImZ1bmN0aW9uIiAmJiAvLyByZW1vdmUgdGhlIGNvbXBvbmVudCBpZiBpdCB3YXNuJ3QgYnVmZmVyZWQNCiAgIWRldnRvb2xzJDEuY2xlYW51cEJ1ZmZlcihjb21wb25lbnQpKSB7DQogICAgX2RldnRvb2xzQ29tcG9uZW50UmVtb3ZlZChjb21wb25lbnQpOw0KICB9DQp9Ow0KLyohICNfX05PX1NJREVfRUZGRUNUU19fICovDQovLyBAX19OT19TSURFX0VGRkVDVFNfXw0KZnVuY3Rpb24gY3JlYXRlRGV2dG9vbHNDb21wb25lbnRIb29rKGhvb2spIHsNCiAgcmV0dXJuIChjb21wb25lbnQpID0+IHsNCiAgICBlbWl0JDEoDQogICAgICBob29rLA0KICAgICAgY29tcG9uZW50LmFwcENvbnRleHQuYXBwLA0KICAgICAgY29tcG9uZW50LnVpZCwNCiAgICAgIGNvbXBvbmVudC5wYXJlbnQgPyBjb21wb25lbnQucGFyZW50LnVpZCA6IHZvaWQgMCwNCiAgICAgIGNvbXBvbmVudA0KICAgICk7DQogIH07DQp9DQpjb25zdCBkZXZ0b29sc1BlcmZTdGFydCA9IC8qIEBfX1BVUkVfXyAqLyBjcmVhdGVEZXZ0b29sc1BlcmZvcm1hbmNlSG9vaygicGVyZjpzdGFydCIgLyogUEVSRk9STUFOQ0VfU1RBUlQgKi8pOw0KY29uc3QgZGV2dG9vbHNQZXJmRW5kID0gLyogQF9fUFVSRV9fICovIGNyZWF0ZURldnRvb2xzUGVyZm9ybWFuY2VIb29rKCJwZXJmOmVuZCIgLyogUEVSRk9STUFOQ0VfRU5EICovKTsNCmZ1bmN0aW9uIGNyZWF0ZURldnRvb2xzUGVyZm9ybWFuY2VIb29rKGhvb2spIHsNCiAgcmV0dXJuIChjb21wb25lbnQsIHR5cGUsIHRpbWUpID0+IHsNCiAgICBlbWl0JDEoaG9vaywgY29tcG9uZW50LmFwcENvbnRleHQuYXBwLCBjb21wb25lbnQudWlkLCBjb21wb25lbnQsIHR5cGUsIHRpbWUpOw0KICB9Ow0KfQ0KZnVuY3Rpb24gZGV2dG9vbHNDb21wb25lbnRFbWl0KGNvbXBvbmVudCwgZXZlbnQsIHBhcmFtcykgew0KICBlbWl0JDEoDQogICAgImNvbXBvbmVudDplbWl0IiAvKiBDT01QT05FTlRfRU1JVCAqLywNCiAgICBjb21wb25lbnQuYXBwQ29udGV4dC5hcHAsDQogICAgY29tcG9uZW50LA0KICAgIGV2ZW50LA0KICAgIHBhcmFtcw0KICApOw0KfQ0KDQpsZXQgY3VycmVudFJlbmRlcmluZ0luc3RhbmNlID0gbnVsbDsNCmxldCBjdXJyZW50U2NvcGVJZCA9IG51bGw7DQpmdW5jdGlvbiBzZXRDdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UoaW5zdGFuY2UpIHsNCiAgY29uc3QgcHJldiA9IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZTsNCiAgY3VycmVudFJlbmRlcmluZ0luc3RhbmNlID0gaW5zdGFuY2U7DQogIGN1cnJlbnRTY29wZUlkID0gaW5zdGFuY2UgJiYgaW5zdGFuY2UudHlwZS5fX3Njb3BlSWQgfHwgbnVsbDsNCiAgcmV0dXJuIHByZXY7DQp9DQpmdW5jdGlvbiBwdXNoU2NvcGVJZChpZCkgew0KICBjdXJyZW50U2NvcGVJZCA9IGlkOw0KfQ0KZnVuY3Rpb24gcG9wU2NvcGVJZCgpIHsNCiAgY3VycmVudFNjb3BlSWQgPSBudWxsOw0KfQ0KY29uc3Qgd2l0aFNjb3BlSWQgPSAoX2lkKSA9PiB3aXRoQ3R4Ow0KZnVuY3Rpb24gd2l0aEN0eChmbiwgY3R4ID0gY3VycmVudFJlbmRlcmluZ0luc3RhbmNlLCBpc05vblNjb3BlZFNsb3QpIHsNCiAgaWYgKCFjdHgpIHJldHVybiBmbjsNCiAgaWYgKGZuLl9uKSB7DQogICAgcmV0dXJuIGZuOw0KICB9DQogIGNvbnN0IHJlbmRlckZuV2l0aENvbnRleHQgPSAoLi4uYXJncykgPT4gew0KICAgIGlmIChyZW5kZXJGbldpdGhDb250ZXh0Ll9kKSB7DQogICAgICBzZXRCbG9ja1RyYWNraW5nKC0xKTsNCiAgICB9DQogICAgY29uc3QgcHJldkluc3RhbmNlID0gc2V0Q3VycmVudFJlbmRlcmluZ0luc3RhbmNlKGN0eCk7DQogICAgbGV0IHJlczsNCiAgICB0cnkgew0KICAgICAgcmVzID0gZm4oLi4uYXJncyk7DQogICAgfSBmaW5hbGx5IHsNCiAgICAgIHNldEN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZShwcmV2SW5zdGFuY2UpOw0KICAgICAgaWYgKHJlbmRlckZuV2l0aENvbnRleHQuX2QpIHsNCiAgICAgICAgc2V0QmxvY2tUcmFja2luZygxKTsNCiAgICAgIH0NCiAgICB9DQogICAgew0KICAgICAgZGV2dG9vbHNDb21wb25lbnRVcGRhdGVkKGN0eCk7DQogICAgfQ0KICAgIHJldHVybiByZXM7DQogIH07DQogIHJlbmRlckZuV2l0aENvbnRleHQuX24gPSB0cnVlOw0KICByZW5kZXJGbldpdGhDb250ZXh0Ll9jID0gdHJ1ZTsNCiAgcmVuZGVyRm5XaXRoQ29udGV4dC5fZCA9IHRydWU7DQogIHJldHVybiByZW5kZXJGbldpdGhDb250ZXh0Ow0KfQ0KDQpmdW5jdGlvbiB2YWxpZGF0ZURpcmVjdGl2ZU5hbWUobmFtZSkgew0KICBpZiAoaXNCdWlsdEluRGlyZWN0aXZlKG5hbWUpKSB7DQogICAgd2FybiQxKCJEbyBub3QgdXNlIGJ1aWx0LWluIGRpcmVjdGl2ZSBpZHMgYXMgY3VzdG9tIGRpcmVjdGl2ZSBpZDogIiArIG5hbWUpOw0KICB9DQp9DQpmdW5jdGlvbiB3aXRoRGlyZWN0aXZlcyh2bm9kZSwgZGlyZWN0aXZlcykgew0KICBpZiAoY3VycmVudFJlbmRlcmluZ0luc3RhbmNlID09PSBudWxsKSB7DQogICAgd2FybiQxKGB3aXRoRGlyZWN0aXZlcyBjYW4gb25seSBiZSB1c2VkIGluc2lkZSByZW5kZXIgZnVuY3Rpb25zLmApOw0KICAgIHJldHVybiB2bm9kZTsNCiAgfQ0KICBjb25zdCBpbnN0YW5jZSA9IGdldENvbXBvbmVudFB1YmxpY0luc3RhbmNlKGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSk7DQogIGNvbnN0IGJpbmRpbmdzID0gdm5vZGUuZGlycyB8fCAodm5vZGUuZGlycyA9IFtdKTsNCiAgZm9yIChsZXQgaSA9IDA7IGkgPCBkaXJlY3RpdmVzLmxlbmd0aDsgaSsrKSB7DQogICAgbGV0IFtkaXIsIHZhbHVlLCBhcmcsIG1vZGlmaWVycyA9IEVNUFRZX09CSl0gPSBkaXJlY3RpdmVzW2ldOw0KICAgIGlmIChkaXIpIHsNCiAgICAgIGlmIChpc0Z1bmN0aW9uKGRpcikpIHsNCiAgICAgICAgZGlyID0gew0KICAgICAgICAgIG1vdW50ZWQ6IGRpciwNCiAgICAgICAgICB1cGRhdGVkOiBkaXINCiAgICAgICAgfTsNCiAgICAgIH0NCiAgICAgIGlmIChkaXIuZGVlcCkgew0KICAgICAgICB0cmF2ZXJzZSh2YWx1ZSk7DQogICAgICB9DQogICAgICBiaW5kaW5ncy5wdXNoKHsNCiAgICAgICAgZGlyLA0KICAgICAgICBpbnN0YW5jZSwNCiAgICAgICAgdmFsdWUsDQogICAgICAgIG9sZFZhbHVlOiB2b2lkIDAsDQogICAgICAgIGFyZywNCiAgICAgICAgbW9kaWZpZXJzDQogICAgICB9KTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIHZub2RlOw0KfQ0KZnVuY3Rpb24gaW52b2tlRGlyZWN0aXZlSG9vayh2bm9kZSwgcHJldlZOb2RlLCBpbnN0YW5jZSwgbmFtZSkgew0KICBjb25zdCBiaW5kaW5ncyA9IHZub2RlLmRpcnM7DQogIGNvbnN0IG9sZEJpbmRpbmdzID0gcHJldlZOb2RlICYmIHByZXZWTm9kZS5kaXJzOw0KICBmb3IgKGxldCBpID0gMDsgaSA8IGJpbmRpbmdzLmxlbmd0aDsgaSsrKSB7DQogICAgY29uc3QgYmluZGluZyA9IGJpbmRpbmdzW2ldOw0KICAgIGlmIChvbGRCaW5kaW5ncykgew0KICAgICAgYmluZGluZy5vbGRWYWx1ZSA9IG9sZEJpbmRpbmdzW2ldLnZhbHVlOw0KICAgIH0NCiAgICBsZXQgaG9vayA9IGJpbmRpbmcuZGlyW25hbWVdOw0KICAgIGlmIChob29rKSB7DQogICAgICBwYXVzZVRyYWNraW5nKCk7DQogICAgICBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZyhob29rLCBpbnN0YW5jZSwgOCwgWw0KICAgICAgICB2bm9kZS5lbCwNCiAgICAgICAgYmluZGluZywNCiAgICAgICAgdm5vZGUsDQogICAgICAgIHByZXZWTm9kZQ0KICAgICAgXSk7DQogICAgICByZXNldFRyYWNraW5nKCk7DQogICAgfQ0KICB9DQp9DQoNCmNvbnN0IFRlbGVwb3J0RW5kS2V5ID0gU3ltYm9sKCJfdnRlIik7DQpjb25zdCBpc1RlbGVwb3J0ID0gKHR5cGUpID0+IHR5cGUuX19pc1RlbGVwb3J0Ow0KY29uc3QgaXNUZWxlcG9ydERpc2FibGVkID0gKHByb3BzKSA9PiBwcm9wcyAmJiAocHJvcHMuZGlzYWJsZWQgfHwgcHJvcHMuZGlzYWJsZWQgPT09ICIiKTsNCmNvbnN0IGlzVGVsZXBvcnREZWZlcnJlZCA9IChwcm9wcykgPT4gcHJvcHMgJiYgKHByb3BzLmRlZmVyIHx8IHByb3BzLmRlZmVyID09PSAiIik7DQpjb25zdCBpc1RhcmdldFNWRyA9ICh0YXJnZXQpID0+IHR5cGVvZiBTVkdFbGVtZW50ICE9PSAidW5kZWZpbmVkIiAmJiB0YXJnZXQgaW5zdGFuY2VvZiBTVkdFbGVtZW50Ow0KY29uc3QgaXNUYXJnZXRNYXRoTUwgPSAodGFyZ2V0KSA9PiB0eXBlb2YgTWF0aE1MRWxlbWVudCA9PT0gImZ1bmN0aW9uIiAmJiB0YXJnZXQgaW5zdGFuY2VvZiBNYXRoTUxFbGVtZW50Ow0KY29uc3QgcmVzb2x2ZVRhcmdldCA9IChwcm9wcywgc2VsZWN0KSA9PiB7DQogIGNvbnN0IHRhcmdldFNlbGVjdG9yID0gcHJvcHMgJiYgcHJvcHMudG87DQogIGlmIChpc1N0cmluZyh0YXJnZXRTZWxlY3RvcikpIHsNCiAgICBpZiAoIXNlbGVjdCkgew0KICAgICAgd2FybiQxKA0KICAgICAgICBgQ3VycmVudCByZW5kZXJlciBkb2VzIG5vdCBzdXBwb3J0IHN0cmluZyB0YXJnZXQgZm9yIFRlbGVwb3J0cy4gKG1pc3NpbmcgcXVlcnlTZWxlY3RvciByZW5kZXJlciBvcHRpb24pYA0KICAgICAgKTsNCiAgICAgIHJldHVybiBudWxsOw0KICAgIH0gZWxzZSB7DQogICAgICBjb25zdCB0YXJnZXQgPSBzZWxlY3QodGFyZ2V0U2VsZWN0b3IpOw0KICAgICAgaWYgKCF0YXJnZXQgJiYgIWlzVGVsZXBvcnREaXNhYmxlZChwcm9wcykpIHsNCiAgICAgICAgd2FybiQxKA0KICAgICAgICAgIGBGYWlsZWQgdG8gbG9jYXRlIFRlbGVwb3J0IHRhcmdldCB3aXRoIHNlbGVjdG9yICIke3RhcmdldFNlbGVjdG9yfSIuIE5vdGUgdGhlIHRhcmdldCBlbGVtZW50IG11c3QgZXhpc3QgYmVmb3JlIHRoZSBjb21wb25lbnQgaXMgbW91bnRlZCAtIGkuZS4gdGhlIHRhcmdldCBjYW5ub3QgYmUgcmVuZGVyZWQgYnkgdGhlIGNvbXBvbmVudCBpdHNlbGYsIGFuZCBpZGVhbGx5IHNob3VsZCBiZSBvdXRzaWRlIG9mIHRoZSBlbnRpcmUgVnVlIGNvbXBvbmVudCB0cmVlLmANCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICAgIHJldHVybiB0YXJnZXQ7DQogICAgfQ0KICB9IGVsc2Ugew0KICAgIGlmICghdGFyZ2V0U2VsZWN0b3IgJiYgIWlzVGVsZXBvcnREaXNhYmxlZChwcm9wcykpIHsNCiAgICAgIHdhcm4kMShgSW52YWxpZCBUZWxlcG9ydCB0YXJnZXQ6ICR7dGFyZ2V0U2VsZWN0b3J9YCk7DQogICAgfQ0KICAgIHJldHVybiB0YXJnZXRTZWxlY3RvcjsNCiAgfQ0KfTsNCmNvbnN0IFRlbGVwb3J0SW1wbCA9IHsNCiAgbmFtZTogIlRlbGVwb3J0IiwNCiAgX19pc1RlbGVwb3J0OiB0cnVlLA0KICBwcm9jZXNzKG4xLCBuMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQsIGludGVybmFscykgew0KICAgIGNvbnN0IHsNCiAgICAgIG1jOiBtb3VudENoaWxkcmVuLA0KICAgICAgcGM6IHBhdGNoQ2hpbGRyZW4sDQogICAgICBwYmM6IHBhdGNoQmxvY2tDaGlsZHJlbiwNCiAgICAgIG86IHsgaW5zZXJ0LCBxdWVyeVNlbGVjdG9yLCBjcmVhdGVUZXh0LCBjcmVhdGVDb21tZW50IH0NCiAgICB9ID0gaW50ZXJuYWxzOw0KICAgIGNvbnN0IGRpc2FibGVkID0gaXNUZWxlcG9ydERpc2FibGVkKG4yLnByb3BzKTsNCiAgICBsZXQgeyBzaGFwZUZsYWcsIGNoaWxkcmVuLCBkeW5hbWljQ2hpbGRyZW4gfSA9IG4yOw0KICAgIGlmIChpc0htclVwZGF0aW5nKSB7DQogICAgICBvcHRpbWl6ZWQgPSBmYWxzZTsNCiAgICAgIGR5bmFtaWNDaGlsZHJlbiA9IG51bGw7DQogICAgfQ0KICAgIGlmIChuMSA9PSBudWxsKSB7DQogICAgICBjb25zdCBwbGFjZWhvbGRlciA9IG4yLmVsID0gY3JlYXRlQ29tbWVudCgidGVsZXBvcnQgc3RhcnQiKSA7DQogICAgICBjb25zdCBtYWluQW5jaG9yID0gbjIuYW5jaG9yID0gY3JlYXRlQ29tbWVudCgidGVsZXBvcnQgZW5kIikgOw0KICAgICAgaW5zZXJ0KHBsYWNlaG9sZGVyLCBjb250YWluZXIsIGFuY2hvcik7DQogICAgICBpbnNlcnQobWFpbkFuY2hvciwgY29udGFpbmVyLCBhbmNob3IpOw0KICAgICAgY29uc3QgbW91bnQgPSAoY29udGFpbmVyMiwgYW5jaG9yMikgPT4gew0KICAgICAgICBpZiAoc2hhcGVGbGFnICYgMTYpIHsNCiAgICAgICAgICBpZiAocGFyZW50Q29tcG9uZW50ICYmIHBhcmVudENvbXBvbmVudC5pc0NFKSB7DQogICAgICAgICAgICBwYXJlbnRDb21wb25lbnQuY2UuX3RlbGVwb3J0VGFyZ2V0ID0gY29udGFpbmVyMjsNCiAgICAgICAgICB9DQogICAgICAgICAgbW91bnRDaGlsZHJlbigNCiAgICAgICAgICAgIGNoaWxkcmVuLA0KICAgICAgICAgICAgY29udGFpbmVyMiwNCiAgICAgICAgICAgIGFuY2hvcjIsDQogICAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH07DQogICAgICBjb25zdCBtb3VudFRvVGFyZ2V0ID0gKCkgPT4gew0KICAgICAgICBjb25zdCB0YXJnZXQgPSBuMi50YXJnZXQgPSByZXNvbHZlVGFyZ2V0KG4yLnByb3BzLCBxdWVyeVNlbGVjdG9yKTsNCiAgICAgICAgY29uc3QgdGFyZ2V0QW5jaG9yID0gcHJlcGFyZUFuY2hvcih0YXJnZXQsIG4yLCBjcmVhdGVUZXh0LCBpbnNlcnQpOw0KICAgICAgICBpZiAodGFyZ2V0KSB7DQogICAgICAgICAgaWYgKG5hbWVzcGFjZSAhPT0gInN2ZyIgJiYgaXNUYXJnZXRTVkcodGFyZ2V0KSkgew0KICAgICAgICAgICAgbmFtZXNwYWNlID0gInN2ZyI7DQogICAgICAgICAgfSBlbHNlIGlmIChuYW1lc3BhY2UgIT09ICJtYXRobWwiICYmIGlzVGFyZ2V0TWF0aE1MKHRhcmdldCkpIHsNCiAgICAgICAgICAgIG5hbWVzcGFjZSA9ICJtYXRobWwiOw0KICAgICAgICAgIH0NCiAgICAgICAgICBpZiAoIWRpc2FibGVkKSB7DQogICAgICAgICAgICBtb3VudCh0YXJnZXQsIHRhcmdldEFuY2hvcik7DQogICAgICAgICAgICB1cGRhdGVDc3NWYXJzKG4yLCBmYWxzZSk7DQogICAgICAgICAgfQ0KICAgICAgICB9IGVsc2UgaWYgKCFkaXNhYmxlZCkgew0KICAgICAgICAgIHdhcm4kMSgNCiAgICAgICAgICAgICJJbnZhbGlkIFRlbGVwb3J0IHRhcmdldCBvbiBtb3VudDoiLA0KICAgICAgICAgICAgdGFyZ2V0LA0KICAgICAgICAgICAgYCgke3R5cGVvZiB0YXJnZXR9KWANCiAgICAgICAgICApOw0KICAgICAgICB9DQogICAgICB9Ow0KICAgICAgaWYgKGRpc2FibGVkKSB7DQogICAgICAgIG1vdW50KGNvbnRhaW5lciwgbWFpbkFuY2hvcik7DQogICAgICAgIHVwZGF0ZUNzc1ZhcnMobjIsIHRydWUpOw0KICAgICAgfQ0KICAgICAgaWYgKGlzVGVsZXBvcnREZWZlcnJlZChuMi5wcm9wcykpIHsNCiAgICAgICAgbjIuZWwuX19pc01vdW50ZWQgPSBmYWxzZTsNCiAgICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KCgpID0+IHsNCiAgICAgICAgICBtb3VudFRvVGFyZ2V0KCk7DQogICAgICAgICAgZGVsZXRlIG4yLmVsLl9faXNNb3VudGVkOw0KICAgICAgICB9LCBwYXJlbnRTdXNwZW5zZSk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBtb3VudFRvVGFyZ2V0KCk7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIGlmIChpc1RlbGVwb3J0RGVmZXJyZWQobjIucHJvcHMpICYmIG4xLmVsLl9faXNNb3VudGVkID09PSBmYWxzZSkgew0KICAgICAgICBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QoKCkgPT4gew0KICAgICAgICAgIFRlbGVwb3J0SW1wbC5wcm9jZXNzKA0KICAgICAgICAgICAgbjEsDQogICAgICAgICAgICBuMiwNCiAgICAgICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgICAgIGFuY2hvciwNCiAgICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgICAgb3B0aW1pemVkLA0KICAgICAgICAgICAgaW50ZXJuYWxzDQogICAgICAgICAgKTsNCiAgICAgICAgfSwgcGFyZW50U3VzcGVuc2UpOw0KICAgICAgICByZXR1cm47DQogICAgICB9DQogICAgICBuMi5lbCA9IG4xLmVsOw0KICAgICAgbjIudGFyZ2V0U3RhcnQgPSBuMS50YXJnZXRTdGFydDsNCiAgICAgIGNvbnN0IG1haW5BbmNob3IgPSBuMi5hbmNob3IgPSBuMS5hbmNob3I7DQogICAgICBjb25zdCB0YXJnZXQgPSBuMi50YXJnZXQgPSBuMS50YXJnZXQ7DQogICAgICBjb25zdCB0YXJnZXRBbmNob3IgPSBuMi50YXJnZXRBbmNob3IgPSBuMS50YXJnZXRBbmNob3I7DQogICAgICBjb25zdCB3YXNEaXNhYmxlZCA9IGlzVGVsZXBvcnREaXNhYmxlZChuMS5wcm9wcyk7DQogICAgICBjb25zdCBjdXJyZW50Q29udGFpbmVyID0gd2FzRGlzYWJsZWQgPyBjb250YWluZXIgOiB0YXJnZXQ7DQogICAgICBjb25zdCBjdXJyZW50QW5jaG9yID0gd2FzRGlzYWJsZWQgPyBtYWluQW5jaG9yIDogdGFyZ2V0QW5jaG9yOw0KICAgICAgaWYgKG5hbWVzcGFjZSA9PT0gInN2ZyIgfHwgaXNUYXJnZXRTVkcodGFyZ2V0KSkgew0KICAgICAgICBuYW1lc3BhY2UgPSAic3ZnIjsNCiAgICAgIH0gZWxzZSBpZiAobmFtZXNwYWNlID09PSAibWF0aG1sIiB8fCBpc1RhcmdldE1hdGhNTCh0YXJnZXQpKSB7DQogICAgICAgIG5hbWVzcGFjZSA9ICJtYXRobWwiOw0KICAgICAgfQ0KICAgICAgaWYgKGR5bmFtaWNDaGlsZHJlbikgew0KICAgICAgICBwYXRjaEJsb2NrQ2hpbGRyZW4oDQogICAgICAgICAgbjEuZHluYW1pY0NoaWxkcmVuLA0KICAgICAgICAgIGR5bmFtaWNDaGlsZHJlbiwNCiAgICAgICAgICBjdXJyZW50Q29udGFpbmVyLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzDQogICAgICAgICk7DQogICAgICAgIHRyYXZlcnNlU3RhdGljQ2hpbGRyZW4objEsIG4yLCBmYWxzZSk7DQogICAgICB9IGVsc2UgaWYgKCFvcHRpbWl6ZWQpIHsNCiAgICAgICAgcGF0Y2hDaGlsZHJlbigNCiAgICAgICAgICBuMSwNCiAgICAgICAgICBuMiwNCiAgICAgICAgICBjdXJyZW50Q29udGFpbmVyLA0KICAgICAgICAgIGN1cnJlbnRBbmNob3IsDQogICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgZmFsc2UNCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICAgIGlmIChkaXNhYmxlZCkgew0KICAgICAgICBpZiAoIXdhc0Rpc2FibGVkKSB7DQogICAgICAgICAgbW92ZVRlbGVwb3J0KA0KICAgICAgICAgICAgbjIsDQogICAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgICBtYWluQW5jaG9yLA0KICAgICAgICAgICAgaW50ZXJuYWxzLA0KICAgICAgICAgICAgMQ0KICAgICAgICAgICk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgaWYgKG4yLnByb3BzICYmIG4xLnByb3BzICYmIG4yLnByb3BzLnRvICE9PSBuMS5wcm9wcy50bykgew0KICAgICAgICAgICAgbjIucHJvcHMudG8gPSBuMS5wcm9wcy50bzsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGlmICgobjIucHJvcHMgJiYgbjIucHJvcHMudG8pICE9PSAobjEucHJvcHMgJiYgbjEucHJvcHMudG8pKSB7DQogICAgICAgICAgY29uc3QgbmV4dFRhcmdldCA9IG4yLnRhcmdldCA9IHJlc29sdmVUYXJnZXQoDQogICAgICAgICAgICBuMi5wcm9wcywNCiAgICAgICAgICAgIHF1ZXJ5U2VsZWN0b3INCiAgICAgICAgICApOw0KICAgICAgICAgIGlmIChuZXh0VGFyZ2V0KSB7DQogICAgICAgICAgICBtb3ZlVGVsZXBvcnQoDQogICAgICAgICAgICAgIG4yLA0KICAgICAgICAgICAgICBuZXh0VGFyZ2V0LA0KICAgICAgICAgICAgICBudWxsLA0KICAgICAgICAgICAgICBpbnRlcm5hbHMsDQogICAgICAgICAgICAgIDANCiAgICAgICAgICAgICk7DQogICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIHdhcm4kMSgNCiAgICAgICAgICAgICAgIkludmFsaWQgVGVsZXBvcnQgdGFyZ2V0IG9uIHVwZGF0ZToiLA0KICAgICAgICAgICAgICB0YXJnZXQsDQogICAgICAgICAgICAgIGAoJHt0eXBlb2YgdGFyZ2V0fSlgDQogICAgICAgICAgICApOw0KICAgICAgICAgIH0NCiAgICAgICAgfSBlbHNlIGlmICh3YXNEaXNhYmxlZCkgew0KICAgICAgICAgIG1vdmVUZWxlcG9ydCgNCiAgICAgICAgICAgIG4yLA0KICAgICAgICAgICAgdGFyZ2V0LA0KICAgICAgICAgICAgdGFyZ2V0QW5jaG9yLA0KICAgICAgICAgICAgaW50ZXJuYWxzLA0KICAgICAgICAgICAgMQ0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIHVwZGF0ZUNzc1ZhcnMobjIsIGRpc2FibGVkKTsNCiAgICB9DQogIH0sDQogIHJlbW92ZSh2bm9kZSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgeyB1bTogdW5tb3VudCwgbzogeyByZW1vdmU6IGhvc3RSZW1vdmUgfSB9LCBkb1JlbW92ZSkgew0KICAgIGNvbnN0IHsNCiAgICAgIHNoYXBlRmxhZywNCiAgICAgIGNoaWxkcmVuLA0KICAgICAgYW5jaG9yLA0KICAgICAgdGFyZ2V0U3RhcnQsDQogICAgICB0YXJnZXRBbmNob3IsDQogICAgICB0YXJnZXQsDQogICAgICBwcm9wcw0KICAgIH0gPSB2bm9kZTsNCiAgICBpZiAodGFyZ2V0KSB7DQogICAgICBob3N0UmVtb3ZlKHRhcmdldFN0YXJ0KTsNCiAgICAgIGhvc3RSZW1vdmUodGFyZ2V0QW5jaG9yKTsNCiAgICB9DQogICAgZG9SZW1vdmUgJiYgaG9zdFJlbW92ZShhbmNob3IpOw0KICAgIGlmIChzaGFwZUZsYWcgJiAxNikgew0KICAgICAgY29uc3Qgc2hvdWxkUmVtb3ZlID0gZG9SZW1vdmUgfHwgIWlzVGVsZXBvcnREaXNhYmxlZChwcm9wcyk7DQogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7DQogICAgICAgIGNvbnN0IGNoaWxkID0gY2hpbGRyZW5baV07DQogICAgICAgIHVubW91bnQoDQogICAgICAgICAgY2hpbGQsDQogICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgIHNob3VsZFJlbW92ZSwNCiAgICAgICAgICAhIWNoaWxkLmR5bmFtaWNDaGlsZHJlbg0KICAgICAgICApOw0KICAgICAgfQ0KICAgIH0NCiAgfSwNCiAgbW92ZTogbW92ZVRlbGVwb3J0LA0KICBoeWRyYXRlOiBoeWRyYXRlVGVsZXBvcnQNCn07DQpmdW5jdGlvbiBtb3ZlVGVsZXBvcnQodm5vZGUsIGNvbnRhaW5lciwgcGFyZW50QW5jaG9yLCB7IG86IHsgaW5zZXJ0IH0sIG06IG1vdmUgfSwgbW92ZVR5cGUgPSAyKSB7DQogIGlmIChtb3ZlVHlwZSA9PT0gMCkgew0KICAgIGluc2VydCh2bm9kZS50YXJnZXRBbmNob3IsIGNvbnRhaW5lciwgcGFyZW50QW5jaG9yKTsNCiAgfQ0KICBjb25zdCB7IGVsLCBhbmNob3IsIHNoYXBlRmxhZywgY2hpbGRyZW4sIHByb3BzIH0gPSB2bm9kZTsNCiAgY29uc3QgaXNSZW9yZGVyID0gbW92ZVR5cGUgPT09IDI7DQogIGlmIChpc1Jlb3JkZXIpIHsNCiAgICBpbnNlcnQoZWwsIGNvbnRhaW5lciwgcGFyZW50QW5jaG9yKTsNCiAgfQ0KICBpZiAoIWlzUmVvcmRlciB8fCBpc1RlbGVwb3J0RGlzYWJsZWQocHJvcHMpKSB7DQogICAgaWYgKHNoYXBlRmxhZyAmIDE2KSB7DQogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7DQogICAgICAgIG1vdmUoDQogICAgICAgICAgY2hpbGRyZW5baV0sDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIHBhcmVudEFuY2hvciwNCiAgICAgICAgICAyDQogICAgICAgICk7DQogICAgICB9DQogICAgfQ0KICB9DQogIGlmIChpc1Jlb3JkZXIpIHsNCiAgICBpbnNlcnQoYW5jaG9yLCBjb250YWluZXIsIHBhcmVudEFuY2hvcik7DQogIH0NCn0NCmZ1bmN0aW9uIGh5ZHJhdGVUZWxlcG9ydChub2RlLCB2bm9kZSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQsIHsNCiAgbzogeyBuZXh0U2libGluZywgcGFyZW50Tm9kZSwgcXVlcnlTZWxlY3RvciwgaW5zZXJ0LCBjcmVhdGVUZXh0IH0NCn0sIGh5ZHJhdGVDaGlsZHJlbikgew0KICBjb25zdCB0YXJnZXQgPSB2bm9kZS50YXJnZXQgPSByZXNvbHZlVGFyZ2V0KA0KICAgIHZub2RlLnByb3BzLA0KICAgIHF1ZXJ5U2VsZWN0b3INCiAgKTsNCiAgaWYgKHRhcmdldCkgew0KICAgIGNvbnN0IGRpc2FibGVkID0gaXNUZWxlcG9ydERpc2FibGVkKHZub2RlLnByb3BzKTsNCiAgICBjb25zdCB0YXJnZXROb2RlID0gdGFyZ2V0Ll9scGEgfHwgdGFyZ2V0LmZpcnN0Q2hpbGQ7DQogICAgaWYgKHZub2RlLnNoYXBlRmxhZyAmIDE2KSB7DQogICAgICBpZiAoZGlzYWJsZWQpIHsNCiAgICAgICAgdm5vZGUuYW5jaG9yID0gaHlkcmF0ZUNoaWxkcmVuKA0KICAgICAgICAgIG5leHRTaWJsaW5nKG5vZGUpLA0KICAgICAgICAgIHZub2RlLA0KICAgICAgICAgIHBhcmVudE5vZGUobm9kZSksDQogICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgKTsNCiAgICAgICAgdm5vZGUudGFyZ2V0U3RhcnQgPSB0YXJnZXROb2RlOw0KICAgICAgICB2bm9kZS50YXJnZXRBbmNob3IgPSB0YXJnZXROb2RlICYmIG5leHRTaWJsaW5nKHRhcmdldE5vZGUpOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgdm5vZGUuYW5jaG9yID0gbmV4dFNpYmxpbmcobm9kZSk7DQogICAgICAgIGxldCB0YXJnZXRBbmNob3IgPSB0YXJnZXROb2RlOw0KICAgICAgICB3aGlsZSAodGFyZ2V0QW5jaG9yKSB7DQogICAgICAgICAgaWYgKHRhcmdldEFuY2hvciAmJiB0YXJnZXRBbmNob3Iubm9kZVR5cGUgPT09IDgpIHsNCiAgICAgICAgICAgIGlmICh0YXJnZXRBbmNob3IuZGF0YSA9PT0gInRlbGVwb3J0IHN0YXJ0IGFuY2hvciIpIHsNCiAgICAgICAgICAgICAgdm5vZGUudGFyZ2V0U3RhcnQgPSB0YXJnZXRBbmNob3I7DQogICAgICAgICAgICB9IGVsc2UgaWYgKHRhcmdldEFuY2hvci5kYXRhID09PSAidGVsZXBvcnQgYW5jaG9yIikgew0KICAgICAgICAgICAgICB2bm9kZS50YXJnZXRBbmNob3IgPSB0YXJnZXRBbmNob3I7DQogICAgICAgICAgICAgIHRhcmdldC5fbHBhID0gdm5vZGUudGFyZ2V0QW5jaG9yICYmIG5leHRTaWJsaW5nKHZub2RlLnRhcmdldEFuY2hvcik7DQogICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgIH0NCiAgICAgICAgICB0YXJnZXRBbmNob3IgPSBuZXh0U2libGluZyh0YXJnZXRBbmNob3IpOw0KICAgICAgICB9DQogICAgICAgIGlmICghdm5vZGUudGFyZ2V0QW5jaG9yKSB7DQogICAgICAgICAgcHJlcGFyZUFuY2hvcih0YXJnZXQsIHZub2RlLCBjcmVhdGVUZXh0LCBpbnNlcnQpOw0KICAgICAgICB9DQogICAgICAgIGh5ZHJhdGVDaGlsZHJlbigNCiAgICAgICAgICB0YXJnZXROb2RlICYmIG5leHRTaWJsaW5nKHRhcmdldE5vZGUpLA0KICAgICAgICAgIHZub2RlLA0KICAgICAgICAgIHRhcmdldCwNCiAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICApOw0KICAgICAgfQ0KICAgIH0NCiAgICB1cGRhdGVDc3NWYXJzKHZub2RlLCBkaXNhYmxlZCk7DQogIH0NCiAgcmV0dXJuIHZub2RlLmFuY2hvciAmJiBuZXh0U2libGluZyh2bm9kZS5hbmNob3IpOw0KfQ0KY29uc3QgVGVsZXBvcnQgPSBUZWxlcG9ydEltcGw7DQpmdW5jdGlvbiB1cGRhdGVDc3NWYXJzKHZub2RlLCBpc0Rpc2FibGVkKSB7DQogIGNvbnN0IGN0eCA9IHZub2RlLmN0eDsNCiAgaWYgKGN0eCAmJiBjdHgudXQpIHsNCiAgICBsZXQgbm9kZSwgYW5jaG9yOw0KICAgIGlmIChpc0Rpc2FibGVkKSB7DQogICAgICBub2RlID0gdm5vZGUuZWw7DQogICAgICBhbmNob3IgPSB2bm9kZS5hbmNob3I7DQogICAgfSBlbHNlIHsNCiAgICAgIG5vZGUgPSB2bm9kZS50YXJnZXRTdGFydDsNCiAgICAgIGFuY2hvciA9IHZub2RlLnRhcmdldEFuY2hvcjsNCiAgICB9DQogICAgd2hpbGUgKG5vZGUgJiYgbm9kZSAhPT0gYW5jaG9yKSB7DQogICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PT0gMSkgbm9kZS5zZXRBdHRyaWJ1dGUoImRhdGEtdi1vd25lciIsIGN0eC51aWQpOw0KICAgICAgbm9kZSA9IG5vZGUubmV4dFNpYmxpbmc7DQogICAgfQ0KICAgIGN0eC51dCgpOw0KICB9DQp9DQpmdW5jdGlvbiBwcmVwYXJlQW5jaG9yKHRhcmdldCwgdm5vZGUsIGNyZWF0ZVRleHQsIGluc2VydCkgew0KICBjb25zdCB0YXJnZXRTdGFydCA9IHZub2RlLnRhcmdldFN0YXJ0ID0gY3JlYXRlVGV4dCgiIik7DQogIGNvbnN0IHRhcmdldEFuY2hvciA9IHZub2RlLnRhcmdldEFuY2hvciA9IGNyZWF0ZVRleHQoIiIpOw0KICB0YXJnZXRTdGFydFtUZWxlcG9ydEVuZEtleV0gPSB0YXJnZXRBbmNob3I7DQogIGlmICh0YXJnZXQpIHsNCiAgICBpbnNlcnQodGFyZ2V0U3RhcnQsIHRhcmdldCk7DQogICAgaW5zZXJ0KHRhcmdldEFuY2hvciwgdGFyZ2V0KTsNCiAgfQ0KICByZXR1cm4gdGFyZ2V0QW5jaG9yOw0KfQ0KDQpjb25zdCBsZWF2ZUNiS2V5ID0gU3ltYm9sKCJfbGVhdmVDYiIpOw0KY29uc3QgZW50ZXJDYktleSQxID0gU3ltYm9sKCJfZW50ZXJDYiIpOw0KZnVuY3Rpb24gdXNlVHJhbnNpdGlvblN0YXRlKCkgew0KICBjb25zdCBzdGF0ZSA9IHsNCiAgICBpc01vdW50ZWQ6IGZhbHNlLA0KICAgIGlzTGVhdmluZzogZmFsc2UsDQogICAgaXNVbm1vdW50aW5nOiBmYWxzZSwNCiAgICBsZWF2aW5nVk5vZGVzOiAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpDQogIH07DQogIG9uTW91bnRlZCgoKSA9PiB7DQogICAgc3RhdGUuaXNNb3VudGVkID0gdHJ1ZTsNCiAgfSk7DQogIG9uQmVmb3JlVW5tb3VudCgoKSA9PiB7DQogICAgc3RhdGUuaXNVbm1vdW50aW5nID0gdHJ1ZTsNCiAgfSk7DQogIHJldHVybiBzdGF0ZTsNCn0NCmNvbnN0IFRyYW5zaXRpb25Ib29rVmFsaWRhdG9yID0gW0Z1bmN0aW9uLCBBcnJheV07DQpjb25zdCBCYXNlVHJhbnNpdGlvblByb3BzVmFsaWRhdG9ycyA9IHsNCiAgbW9kZTogU3RyaW5nLA0KICBhcHBlYXI6IEJvb2xlYW4sDQogIHBlcnNpc3RlZDogQm9vbGVhbiwNCiAgLy8gZW50ZXINCiAgb25CZWZvcmVFbnRlcjogVHJhbnNpdGlvbkhvb2tWYWxpZGF0b3IsDQogIG9uRW50ZXI6IFRyYW5zaXRpb25Ib29rVmFsaWRhdG9yLA0KICBvbkFmdGVyRW50ZXI6IFRyYW5zaXRpb25Ib29rVmFsaWRhdG9yLA0KICBvbkVudGVyQ2FuY2VsbGVkOiBUcmFuc2l0aW9uSG9va1ZhbGlkYXRvciwNCiAgLy8gbGVhdmUNCiAgb25CZWZvcmVMZWF2ZTogVHJhbnNpdGlvbkhvb2tWYWxpZGF0b3IsDQogIG9uTGVhdmU6IFRyYW5zaXRpb25Ib29rVmFsaWRhdG9yLA0KICBvbkFmdGVyTGVhdmU6IFRyYW5zaXRpb25Ib29rVmFsaWRhdG9yLA0KICBvbkxlYXZlQ2FuY2VsbGVkOiBUcmFuc2l0aW9uSG9va1ZhbGlkYXRvciwNCiAgLy8gYXBwZWFyDQogIG9uQmVmb3JlQXBwZWFyOiBUcmFuc2l0aW9uSG9va1ZhbGlkYXRvciwNCiAgb25BcHBlYXI6IFRyYW5zaXRpb25Ib29rVmFsaWRhdG9yLA0KICBvbkFmdGVyQXBwZWFyOiBUcmFuc2l0aW9uSG9va1ZhbGlkYXRvciwNCiAgb25BcHBlYXJDYW5jZWxsZWQ6IFRyYW5zaXRpb25Ib29rVmFsaWRhdG9yDQp9Ow0KY29uc3QgcmVjdXJzaXZlR2V0U3VidHJlZSA9IChpbnN0YW5jZSkgPT4gew0KICBjb25zdCBzdWJUcmVlID0gaW5zdGFuY2Uuc3ViVHJlZTsNCiAgcmV0dXJuIHN1YlRyZWUuY29tcG9uZW50ID8gcmVjdXJzaXZlR2V0U3VidHJlZShzdWJUcmVlLmNvbXBvbmVudCkgOiBzdWJUcmVlOw0KfTsNCmNvbnN0IEJhc2VUcmFuc2l0aW9uSW1wbCA9IHsNCiAgbmFtZTogYEJhc2VUcmFuc2l0aW9uYCwNCiAgcHJvcHM6IEJhc2VUcmFuc2l0aW9uUHJvcHNWYWxpZGF0b3JzLA0KICBzZXR1cChwcm9wcywgeyBzbG90cyB9KSB7DQogICAgY29uc3QgaW5zdGFuY2UgPSBnZXRDdXJyZW50SW5zdGFuY2UoKTsNCiAgICBjb25zdCBzdGF0ZSA9IHVzZVRyYW5zaXRpb25TdGF0ZSgpOw0KICAgIHJldHVybiAoKSA9PiB7DQogICAgICBjb25zdCBjaGlsZHJlbiA9IHNsb3RzLmRlZmF1bHQgJiYgZ2V0VHJhbnNpdGlvblJhd0NoaWxkcmVuKHNsb3RzLmRlZmF1bHQoKSwgdHJ1ZSk7DQogICAgICBpZiAoIWNoaWxkcmVuIHx8ICFjaGlsZHJlbi5sZW5ndGgpIHsNCiAgICAgICAgcmV0dXJuOw0KICAgICAgfQ0KICAgICAgY29uc3QgY2hpbGQgPSBmaW5kTm9uQ29tbWVudENoaWxkKGNoaWxkcmVuKTsNCiAgICAgIGNvbnN0IHJhd1Byb3BzID0gdG9SYXcocHJvcHMpOw0KICAgICAgY29uc3QgeyBtb2RlIH0gPSByYXdQcm9wczsNCiAgICAgIGlmIChtb2RlICYmIG1vZGUgIT09ICJpbi1vdXQiICYmIG1vZGUgIT09ICJvdXQtaW4iICYmIG1vZGUgIT09ICJkZWZhdWx0Iikgew0KICAgICAgICB3YXJuJDEoYGludmFsaWQgPHRyYW5zaXRpb24+IG1vZGU6ICR7bW9kZX1gKTsNCiAgICAgIH0NCiAgICAgIGlmIChzdGF0ZS5pc0xlYXZpbmcpIHsNCiAgICAgICAgcmV0dXJuIGVtcHR5UGxhY2Vob2xkZXIoY2hpbGQpOw0KICAgICAgfQ0KICAgICAgY29uc3QgaW5uZXJDaGlsZCA9IGdldElubmVyQ2hpbGQkMShjaGlsZCk7DQogICAgICBpZiAoIWlubmVyQ2hpbGQpIHsNCiAgICAgICAgcmV0dXJuIGVtcHR5UGxhY2Vob2xkZXIoY2hpbGQpOw0KICAgICAgfQ0KICAgICAgbGV0IGVudGVySG9va3MgPSByZXNvbHZlVHJhbnNpdGlvbkhvb2tzKA0KICAgICAgICBpbm5lckNoaWxkLA0KICAgICAgICByYXdQcm9wcywNCiAgICAgICAgc3RhdGUsDQogICAgICAgIGluc3RhbmNlLA0KICAgICAgICAvLyAjMTEwNjEsIGVuc3VyZSBlbnRlckhvb2tzIGlzIGZyZXNoIGFmdGVyIGNsb25lDQogICAgICAgIChob29rcykgPT4gZW50ZXJIb29rcyA9IGhvb2tzDQogICAgICApOw0KICAgICAgaWYgKGlubmVyQ2hpbGQudHlwZSAhPT0gQ29tbWVudCkgew0KICAgICAgICBzZXRUcmFuc2l0aW9uSG9va3MoaW5uZXJDaGlsZCwgZW50ZXJIb29rcyk7DQogICAgICB9DQogICAgICBsZXQgb2xkSW5uZXJDaGlsZCA9IGluc3RhbmNlLnN1YlRyZWUgJiYgZ2V0SW5uZXJDaGlsZCQxKGluc3RhbmNlLnN1YlRyZWUpOw0KICAgICAgaWYgKG9sZElubmVyQ2hpbGQgJiYgb2xkSW5uZXJDaGlsZC50eXBlICE9PSBDb21tZW50ICYmICFpc1NhbWVWTm9kZVR5cGUoaW5uZXJDaGlsZCwgb2xkSW5uZXJDaGlsZCkgJiYgcmVjdXJzaXZlR2V0U3VidHJlZShpbnN0YW5jZSkudHlwZSAhPT0gQ29tbWVudCkgew0KICAgICAgICBsZXQgbGVhdmluZ0hvb2tzID0gcmVzb2x2ZVRyYW5zaXRpb25Ib29rcygNCiAgICAgICAgICBvbGRJbm5lckNoaWxkLA0KICAgICAgICAgIHJhd1Byb3BzLA0KICAgICAgICAgIHN0YXRlLA0KICAgICAgICAgIGluc3RhbmNlDQogICAgICAgICk7DQogICAgICAgIHNldFRyYW5zaXRpb25Ib29rcyhvbGRJbm5lckNoaWxkLCBsZWF2aW5nSG9va3MpOw0KICAgICAgICBpZiAobW9kZSA9PT0gIm91dC1pbiIgJiYgaW5uZXJDaGlsZC50eXBlICE9PSBDb21tZW50KSB7DQogICAgICAgICAgc3RhdGUuaXNMZWF2aW5nID0gdHJ1ZTsNCiAgICAgICAgICBsZWF2aW5nSG9va3MuYWZ0ZXJMZWF2ZSA9ICgpID0+IHsNCiAgICAgICAgICAgIHN0YXRlLmlzTGVhdmluZyA9IGZhbHNlOw0KICAgICAgICAgICAgaWYgKCEoaW5zdGFuY2Uuam9iLmZsYWdzICYgOCkpIHsNCiAgICAgICAgICAgICAgaW5zdGFuY2UudXBkYXRlKCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBkZWxldGUgbGVhdmluZ0hvb2tzLmFmdGVyTGVhdmU7DQogICAgICAgICAgICBvbGRJbm5lckNoaWxkID0gdm9pZCAwOw0KICAgICAgICAgIH07DQogICAgICAgICAgcmV0dXJuIGVtcHR5UGxhY2Vob2xkZXIoY2hpbGQpOw0KICAgICAgICB9IGVsc2UgaWYgKG1vZGUgPT09ICJpbi1vdXQiICYmIGlubmVyQ2hpbGQudHlwZSAhPT0gQ29tbWVudCkgew0KICAgICAgICAgIGxlYXZpbmdIb29rcy5kZWxheUxlYXZlID0gKGVsLCBlYXJseVJlbW92ZSwgZGVsYXllZExlYXZlKSA9PiB7DQogICAgICAgICAgICBjb25zdCBsZWF2aW5nVk5vZGVzQ2FjaGUgPSBnZXRMZWF2aW5nTm9kZXNGb3JUeXBlKA0KICAgICAgICAgICAgICBzdGF0ZSwNCiAgICAgICAgICAgICAgb2xkSW5uZXJDaGlsZA0KICAgICAgICAgICAgKTsNCiAgICAgICAgICAgIGxlYXZpbmdWTm9kZXNDYWNoZVtTdHJpbmcob2xkSW5uZXJDaGlsZC5rZXkpXSA9IG9sZElubmVyQ2hpbGQ7DQogICAgICAgICAgICBlbFtsZWF2ZUNiS2V5XSA9ICgpID0+IHsNCiAgICAgICAgICAgICAgZWFybHlSZW1vdmUoKTsNCiAgICAgICAgICAgICAgZWxbbGVhdmVDYktleV0gPSB2b2lkIDA7DQogICAgICAgICAgICAgIGRlbGV0ZSBlbnRlckhvb2tzLmRlbGF5ZWRMZWF2ZTsNCiAgICAgICAgICAgICAgb2xkSW5uZXJDaGlsZCA9IHZvaWQgMDsNCiAgICAgICAgICAgIH07DQogICAgICAgICAgICBlbnRlckhvb2tzLmRlbGF5ZWRMZWF2ZSA9ICgpID0+IHsNCiAgICAgICAgICAgICAgZGVsYXllZExlYXZlKCk7DQogICAgICAgICAgICAgIGRlbGV0ZSBlbnRlckhvb2tzLmRlbGF5ZWRMZWF2ZTsNCiAgICAgICAgICAgICAgb2xkSW5uZXJDaGlsZCA9IHZvaWQgMDsNCiAgICAgICAgICAgIH07DQogICAgICAgICAgfTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBvbGRJbm5lckNoaWxkID0gdm9pZCAwOw0KICAgICAgICB9DQogICAgICB9IGVsc2UgaWYgKG9sZElubmVyQ2hpbGQpIHsNCiAgICAgICAgb2xkSW5uZXJDaGlsZCA9IHZvaWQgMDsNCiAgICAgIH0NCiAgICAgIHJldHVybiBjaGlsZDsNCiAgICB9Ow0KICB9DQp9Ow0KZnVuY3Rpb24gZmluZE5vbkNvbW1lbnRDaGlsZChjaGlsZHJlbikgew0KICBsZXQgY2hpbGQgPSBjaGlsZHJlblswXTsNCiAgaWYgKGNoaWxkcmVuLmxlbmd0aCA+IDEpIHsNCiAgICBsZXQgaGFzRm91bmQgPSBmYWxzZTsNCiAgICBmb3IgKGNvbnN0IGMgb2YgY2hpbGRyZW4pIHsNCiAgICAgIGlmIChjLnR5cGUgIT09IENvbW1lbnQpIHsNCiAgICAgICAgaWYgKGhhc0ZvdW5kKSB7DQogICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgIjx0cmFuc2l0aW9uPiBjYW4gb25seSBiZSB1c2VkIG9uIGEgc2luZ2xlIGVsZW1lbnQgb3IgY29tcG9uZW50LiBVc2UgPHRyYW5zaXRpb24tZ3JvdXA+IGZvciBsaXN0cy4iDQogICAgICAgICAgKTsNCiAgICAgICAgICBicmVhazsNCiAgICAgICAgfQ0KICAgICAgICBjaGlsZCA9IGM7DQogICAgICAgIGhhc0ZvdW5kID0gdHJ1ZTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgcmV0dXJuIGNoaWxkOw0KfQ0KY29uc3QgQmFzZVRyYW5zaXRpb24gPSBCYXNlVHJhbnNpdGlvbkltcGw7DQpmdW5jdGlvbiBnZXRMZWF2aW5nTm9kZXNGb3JUeXBlKHN0YXRlLCB2bm9kZSkgew0KICBjb25zdCB7IGxlYXZpbmdWTm9kZXMgfSA9IHN0YXRlOw0KICBsZXQgbGVhdmluZ1ZOb2Rlc0NhY2hlID0gbGVhdmluZ1ZOb2Rlcy5nZXQodm5vZGUudHlwZSk7DQogIGlmICghbGVhdmluZ1ZOb2Rlc0NhY2hlKSB7DQogICAgbGVhdmluZ1ZOb2Rlc0NhY2hlID0gLyogQF9fUFVSRV9fICovIE9iamVjdC5jcmVhdGUobnVsbCk7DQogICAgbGVhdmluZ1ZOb2Rlcy5zZXQodm5vZGUudHlwZSwgbGVhdmluZ1ZOb2Rlc0NhY2hlKTsNCiAgfQ0KICByZXR1cm4gbGVhdmluZ1ZOb2Rlc0NhY2hlOw0KfQ0KZnVuY3Rpb24gcmVzb2x2ZVRyYW5zaXRpb25Ib29rcyh2bm9kZSwgcHJvcHMsIHN0YXRlLCBpbnN0YW5jZSwgcG9zdENsb25lKSB7DQogIGNvbnN0IHsNCiAgICBhcHBlYXIsDQogICAgbW9kZSwNCiAgICBwZXJzaXN0ZWQgPSBmYWxzZSwNCiAgICBvbkJlZm9yZUVudGVyLA0KICAgIG9uRW50ZXIsDQogICAgb25BZnRlckVudGVyLA0KICAgIG9uRW50ZXJDYW5jZWxsZWQsDQogICAgb25CZWZvcmVMZWF2ZSwNCiAgICBvbkxlYXZlLA0KICAgIG9uQWZ0ZXJMZWF2ZSwNCiAgICBvbkxlYXZlQ2FuY2VsbGVkLA0KICAgIG9uQmVmb3JlQXBwZWFyLA0KICAgIG9uQXBwZWFyLA0KICAgIG9uQWZ0ZXJBcHBlYXIsDQogICAgb25BcHBlYXJDYW5jZWxsZWQNCiAgfSA9IHByb3BzOw0KICBjb25zdCBrZXkgPSBTdHJpbmcodm5vZGUua2V5KTsNCiAgY29uc3QgbGVhdmluZ1ZOb2Rlc0NhY2hlID0gZ2V0TGVhdmluZ05vZGVzRm9yVHlwZShzdGF0ZSwgdm5vZGUpOw0KICBjb25zdCBjYWxsSG9vayA9IChob29rLCBhcmdzKSA9PiB7DQogICAgaG9vayAmJiBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZygNCiAgICAgIGhvb2ssDQogICAgICBpbnN0YW5jZSwNCiAgICAgIDksDQogICAgICBhcmdzDQogICAgKTsNCiAgfTsNCiAgY29uc3QgY2FsbEFzeW5jSG9vayA9IChob29rLCBhcmdzKSA9PiB7DQogICAgY29uc3QgZG9uZSA9IGFyZ3NbMV07DQogICAgY2FsbEhvb2soaG9vaywgYXJncyk7DQogICAgaWYgKGlzQXJyYXkoaG9vaykpIHsNCiAgICAgIGlmIChob29rLmV2ZXJ5KChob29rMikgPT4gaG9vazIubGVuZ3RoIDw9IDEpKSBkb25lKCk7DQogICAgfSBlbHNlIGlmIChob29rLmxlbmd0aCA8PSAxKSB7DQogICAgICBkb25lKCk7DQogICAgfQ0KICB9Ow0KICBjb25zdCBob29rcyA9IHsNCiAgICBtb2RlLA0KICAgIHBlcnNpc3RlZCwNCiAgICBiZWZvcmVFbnRlcihlbCkgew0KICAgICAgbGV0IGhvb2sgPSBvbkJlZm9yZUVudGVyOw0KICAgICAgaWYgKCFzdGF0ZS5pc01vdW50ZWQpIHsNCiAgICAgICAgaWYgKGFwcGVhcikgew0KICAgICAgICAgIGhvb2sgPSBvbkJlZm9yZUFwcGVhciB8fCBvbkJlZm9yZUVudGVyOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIHJldHVybjsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgaWYgKGVsW2xlYXZlQ2JLZXldKSB7DQogICAgICAgIGVsW2xlYXZlQ2JLZXldKA0KICAgICAgICAgIHRydWUNCiAgICAgICAgICAvKiBjYW5jZWxsZWQgKi8NCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICAgIGNvbnN0IGxlYXZpbmdWTm9kZSA9IGxlYXZpbmdWTm9kZXNDYWNoZVtrZXldOw0KICAgICAgaWYgKGxlYXZpbmdWTm9kZSAmJiBpc1NhbWVWTm9kZVR5cGUodm5vZGUsIGxlYXZpbmdWTm9kZSkgJiYgbGVhdmluZ1ZOb2RlLmVsW2xlYXZlQ2JLZXldKSB7DQogICAgICAgIGxlYXZpbmdWTm9kZS5lbFtsZWF2ZUNiS2V5XSgpOw0KICAgICAgfQ0KICAgICAgY2FsbEhvb2soaG9vaywgW2VsXSk7DQogICAgfSwNCiAgICBlbnRlcihlbCkgew0KICAgICAgbGV0IGhvb2sgPSBvbkVudGVyOw0KICAgICAgbGV0IGFmdGVySG9vayA9IG9uQWZ0ZXJFbnRlcjsNCiAgICAgIGxldCBjYW5jZWxIb29rID0gb25FbnRlckNhbmNlbGxlZDsNCiAgICAgIGlmICghc3RhdGUuaXNNb3VudGVkKSB7DQogICAgICAgIGlmIChhcHBlYXIpIHsNCiAgICAgICAgICBob29rID0gb25BcHBlYXIgfHwgb25FbnRlcjsNCiAgICAgICAgICBhZnRlckhvb2sgPSBvbkFmdGVyQXBwZWFyIHx8IG9uQWZ0ZXJFbnRlcjsNCiAgICAgICAgICBjYW5jZWxIb29rID0gb25BcHBlYXJDYW5jZWxsZWQgfHwgb25FbnRlckNhbmNlbGxlZDsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICByZXR1cm47DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGxldCBjYWxsZWQgPSBmYWxzZTsNCiAgICAgIGNvbnN0IGRvbmUgPSBlbFtlbnRlckNiS2V5JDFdID0gKGNhbmNlbGxlZCkgPT4gew0KICAgICAgICBpZiAoY2FsbGVkKSByZXR1cm47DQogICAgICAgIGNhbGxlZCA9IHRydWU7DQogICAgICAgIGlmIChjYW5jZWxsZWQpIHsNCiAgICAgICAgICBjYWxsSG9vayhjYW5jZWxIb29rLCBbZWxdKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBjYWxsSG9vayhhZnRlckhvb2ssIFtlbF0pOw0KICAgICAgICB9DQogICAgICAgIGlmIChob29rcy5kZWxheWVkTGVhdmUpIHsNCiAgICAgICAgICBob29rcy5kZWxheWVkTGVhdmUoKTsNCiAgICAgICAgfQ0KICAgICAgICBlbFtlbnRlckNiS2V5JDFdID0gdm9pZCAwOw0KICAgICAgfTsNCiAgICAgIGlmIChob29rKSB7DQogICAgICAgIGNhbGxBc3luY0hvb2soaG9vaywgW2VsLCBkb25lXSk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBkb25lKCk7DQogICAgICB9DQogICAgfSwNCiAgICBsZWF2ZShlbCwgcmVtb3ZlKSB7DQogICAgICBjb25zdCBrZXkyID0gU3RyaW5nKHZub2RlLmtleSk7DQogICAgICBpZiAoZWxbZW50ZXJDYktleSQxXSkgew0KICAgICAgICBlbFtlbnRlckNiS2V5JDFdKA0KICAgICAgICAgIHRydWUNCiAgICAgICAgICAvKiBjYW5jZWxsZWQgKi8NCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICAgIGlmIChzdGF0ZS5pc1VubW91bnRpbmcpIHsNCiAgICAgICAgcmV0dXJuIHJlbW92ZSgpOw0KICAgICAgfQ0KICAgICAgY2FsbEhvb2sob25CZWZvcmVMZWF2ZSwgW2VsXSk7DQogICAgICBsZXQgY2FsbGVkID0gZmFsc2U7DQogICAgICBjb25zdCBkb25lID0gZWxbbGVhdmVDYktleV0gPSAoY2FuY2VsbGVkKSA9PiB7DQogICAgICAgIGlmIChjYWxsZWQpIHJldHVybjsNCiAgICAgICAgY2FsbGVkID0gdHJ1ZTsNCiAgICAgICAgcmVtb3ZlKCk7DQogICAgICAgIGlmIChjYW5jZWxsZWQpIHsNCiAgICAgICAgICBjYWxsSG9vayhvbkxlYXZlQ2FuY2VsbGVkLCBbZWxdKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBjYWxsSG9vayhvbkFmdGVyTGVhdmUsIFtlbF0pOw0KICAgICAgICB9DQogICAgICAgIGVsW2xlYXZlQ2JLZXldID0gdm9pZCAwOw0KICAgICAgICBpZiAobGVhdmluZ1ZOb2Rlc0NhY2hlW2tleTJdID09PSB2bm9kZSkgew0KICAgICAgICAgIGRlbGV0ZSBsZWF2aW5nVk5vZGVzQ2FjaGVba2V5Ml07DQogICAgICAgIH0NCiAgICAgIH07DQogICAgICBsZWF2aW5nVk5vZGVzQ2FjaGVba2V5Ml0gPSB2bm9kZTsNCiAgICAgIGlmIChvbkxlYXZlKSB7DQogICAgICAgIGNhbGxBc3luY0hvb2sob25MZWF2ZSwgW2VsLCBkb25lXSk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBkb25lKCk7DQogICAgICB9DQogICAgfSwNCiAgICBjbG9uZSh2bm9kZTIpIHsNCiAgICAgIGNvbnN0IGhvb2tzMiA9IHJlc29sdmVUcmFuc2l0aW9uSG9va3MoDQogICAgICAgIHZub2RlMiwNCiAgICAgICAgcHJvcHMsDQogICAgICAgIHN0YXRlLA0KICAgICAgICBpbnN0YW5jZSwNCiAgICAgICAgcG9zdENsb25lDQogICAgICApOw0KICAgICAgaWYgKHBvc3RDbG9uZSkgcG9zdENsb25lKGhvb2tzMik7DQogICAgICByZXR1cm4gaG9va3MyOw0KICAgIH0NCiAgfTsNCiAgcmV0dXJuIGhvb2tzOw0KfQ0KZnVuY3Rpb24gZW1wdHlQbGFjZWhvbGRlcih2bm9kZSkgew0KICBpZiAoaXNLZWVwQWxpdmUodm5vZGUpKSB7DQogICAgdm5vZGUgPSBjbG9uZVZOb2RlKHZub2RlKTsNCiAgICB2bm9kZS5jaGlsZHJlbiA9IG51bGw7DQogICAgcmV0dXJuIHZub2RlOw0KICB9DQp9DQpmdW5jdGlvbiBnZXRJbm5lckNoaWxkJDEodm5vZGUpIHsNCiAgaWYgKCFpc0tlZXBBbGl2ZSh2bm9kZSkpIHsNCiAgICBpZiAoaXNUZWxlcG9ydCh2bm9kZS50eXBlKSAmJiB2bm9kZS5jaGlsZHJlbikgew0KICAgICAgcmV0dXJuIGZpbmROb25Db21tZW50Q2hpbGQodm5vZGUuY2hpbGRyZW4pOw0KICAgIH0NCiAgICByZXR1cm4gdm5vZGU7DQogIH0NCiAgaWYgKHZub2RlLmNvbXBvbmVudCkgew0KICAgIHJldHVybiB2bm9kZS5jb21wb25lbnQuc3ViVHJlZTsNCiAgfQ0KICBjb25zdCB7IHNoYXBlRmxhZywgY2hpbGRyZW4gfSA9IHZub2RlOw0KICBpZiAoY2hpbGRyZW4pIHsNCiAgICBpZiAoc2hhcGVGbGFnICYgMTYpIHsNCiAgICAgIHJldHVybiBjaGlsZHJlblswXTsNCiAgICB9DQogICAgaWYgKHNoYXBlRmxhZyAmIDMyICYmIGlzRnVuY3Rpb24oY2hpbGRyZW4uZGVmYXVsdCkpIHsNCiAgICAgIHJldHVybiBjaGlsZHJlbi5kZWZhdWx0KCk7DQogICAgfQ0KICB9DQp9DQpmdW5jdGlvbiBzZXRUcmFuc2l0aW9uSG9va3Modm5vZGUsIGhvb2tzKSB7DQogIGlmICh2bm9kZS5zaGFwZUZsYWcgJiA2ICYmIHZub2RlLmNvbXBvbmVudCkgew0KICAgIHZub2RlLnRyYW5zaXRpb24gPSBob29rczsNCiAgICBzZXRUcmFuc2l0aW9uSG9va3Modm5vZGUuY29tcG9uZW50LnN1YlRyZWUsIGhvb2tzKTsNCiAgfSBlbHNlIGlmICh2bm9kZS5zaGFwZUZsYWcgJiAxMjgpIHsNCiAgICB2bm9kZS5zc0NvbnRlbnQudHJhbnNpdGlvbiA9IGhvb2tzLmNsb25lKHZub2RlLnNzQ29udGVudCk7DQogICAgdm5vZGUuc3NGYWxsYmFjay50cmFuc2l0aW9uID0gaG9va3MuY2xvbmUodm5vZGUuc3NGYWxsYmFjayk7DQogIH0gZWxzZSB7DQogICAgdm5vZGUudHJhbnNpdGlvbiA9IGhvb2tzOw0KICB9DQp9DQpmdW5jdGlvbiBnZXRUcmFuc2l0aW9uUmF3Q2hpbGRyZW4oY2hpbGRyZW4sIGtlZXBDb21tZW50ID0gZmFsc2UsIHBhcmVudEtleSkgew0KICBsZXQgcmV0ID0gW107DQogIGxldCBrZXllZEZyYWdtZW50Q291bnQgPSAwOw0KICBmb3IgKGxldCBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7DQogICAgbGV0IGNoaWxkID0gY2hpbGRyZW5baV07DQogICAgY29uc3Qga2V5ID0gcGFyZW50S2V5ID09IG51bGwgPyBjaGlsZC5rZXkgOiBTdHJpbmcocGFyZW50S2V5KSArIFN0cmluZyhjaGlsZC5rZXkgIT0gbnVsbCA/IGNoaWxkLmtleSA6IGkpOw0KICAgIGlmIChjaGlsZC50eXBlID09PSBGcmFnbWVudCkgew0KICAgICAgaWYgKGNoaWxkLnBhdGNoRmxhZyAmIDEyOCkga2V5ZWRGcmFnbWVudENvdW50Kys7DQogICAgICByZXQgPSByZXQuY29uY2F0KA0KICAgICAgICBnZXRUcmFuc2l0aW9uUmF3Q2hpbGRyZW4oY2hpbGQuY2hpbGRyZW4sIGtlZXBDb21tZW50LCBrZXkpDQogICAgICApOw0KICAgIH0gZWxzZSBpZiAoa2VlcENvbW1lbnQgfHwgY2hpbGQudHlwZSAhPT0gQ29tbWVudCkgew0KICAgICAgcmV0LnB1c2goa2V5ICE9IG51bGwgPyBjbG9uZVZOb2RlKGNoaWxkLCB7IGtleSB9KSA6IGNoaWxkKTsNCiAgICB9DQogIH0NCiAgaWYgKGtleWVkRnJhZ21lbnRDb3VudCA+IDEpIHsNCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJldC5sZW5ndGg7IGkrKykgew0KICAgICAgcmV0W2ldLnBhdGNoRmxhZyA9IC0yOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gcmV0Ow0KfQ0KDQovKiEgI19fTk9fU0lERV9FRkZFQ1RTX18gKi8NCi8vIEBfX05PX1NJREVfRUZGRUNUU19fDQpmdW5jdGlvbiBkZWZpbmVDb21wb25lbnQob3B0aW9ucywgZXh0cmFPcHRpb25zKSB7DQogIHJldHVybiBpc0Z1bmN0aW9uKG9wdGlvbnMpID8gKA0KICAgIC8vICM4MjM2OiBleHRlbmQgY2FsbCBhbmQgb3B0aW9ucy5uYW1lIGFjY2VzcyBhcmUgY29uc2lkZXJlZCBzaWRlLWVmZmVjdHMNCiAgICAvLyBieSBSb2xsdXAsIHNvIHdlIGhhdmUgdG8gd3JhcCBpdCBpbiBhIHB1cmUtYW5ub3RhdGVkIElJRkUuDQogICAgLyogQF9fUFVSRV9fICovICgoKSA9PiBleHRlbmQoeyBuYW1lOiBvcHRpb25zLm5hbWUgfSwgZXh0cmFPcHRpb25zLCB7IHNldHVwOiBvcHRpb25zIH0pKSgpDQogICkgOiBvcHRpb25zOw0KfQ0KDQpmdW5jdGlvbiB1c2VJZCgpIHsNCiAgY29uc3QgaSA9IGdldEN1cnJlbnRJbnN0YW5jZSgpOw0KICBpZiAoaSkgew0KICAgIHJldHVybiAoaS5hcHBDb250ZXh0LmNvbmZpZy5pZFByZWZpeCB8fCAidiIpICsgIi0iICsgaS5pZHNbMF0gKyBpLmlkc1sxXSsrOw0KICB9IGVsc2Ugew0KICAgIHdhcm4kMSgNCiAgICAgIGB1c2VJZCgpIGlzIGNhbGxlZCB3aGVuIHRoZXJlIGlzIG5vIGFjdGl2ZSBjb21wb25lbnQgaW5zdGFuY2UgdG8gYmUgYXNzb2NpYXRlZCB3aXRoLmANCiAgICApOw0KICB9DQogIHJldHVybiAiIjsNCn0NCmZ1bmN0aW9uIG1hcmtBc3luY0JvdW5kYXJ5KGluc3RhbmNlKSB7DQogIGluc3RhbmNlLmlkcyA9IFtpbnN0YW5jZS5pZHNbMF0gKyBpbnN0YW5jZS5pZHNbMl0rKyArICItIiwgMCwgMF07DQp9DQoNCmNvbnN0IGtub3duVGVtcGxhdGVSZWZzID0gLyogQF9fUFVSRV9fICovIG5ldyBXZWFrU2V0KCk7DQpmdW5jdGlvbiB1c2VUZW1wbGF0ZVJlZihrZXkpIHsNCiAgY29uc3QgaSA9IGdldEN1cnJlbnRJbnN0YW5jZSgpOw0KICBjb25zdCByID0gc2hhbGxvd1JlZihudWxsKTsNCiAgaWYgKGkpIHsNCiAgICBjb25zdCByZWZzID0gaS5yZWZzID09PSBFTVBUWV9PQkogPyBpLnJlZnMgPSB7fSA6IGkucmVmczsNCiAgICBsZXQgZGVzYzsNCiAgICBpZiAoKGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHJlZnMsIGtleSkpICYmICFkZXNjLmNvbmZpZ3VyYWJsZSkgew0KICAgICAgd2FybiQxKGB1c2VUZW1wbGF0ZVJlZignJHtrZXl9JykgYWxyZWFkeSBleGlzdHMuYCk7DQogICAgfSBlbHNlIHsNCiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyZWZzLCBrZXksIHsNCiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSwNCiAgICAgICAgZ2V0OiAoKSA9PiByLnZhbHVlLA0KICAgICAgICBzZXQ6ICh2YWwpID0+IHIudmFsdWUgPSB2YWwNCiAgICAgIH0pOw0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICB3YXJuJDEoDQogICAgICBgdXNlVGVtcGxhdGVSZWYoKSBpcyBjYWxsZWQgd2hlbiB0aGVyZSBpcyBubyBhY3RpdmUgY29tcG9uZW50IGluc3RhbmNlIHRvIGJlIGFzc29jaWF0ZWQgd2l0aC5gDQogICAgKTsNCiAgfQ0KICBjb25zdCByZXQgPSByZWFkb25seShyKSA7DQogIHsNCiAgICBrbm93blRlbXBsYXRlUmVmcy5hZGQocmV0KTsNCiAgfQ0KICByZXR1cm4gcmV0Ow0KfQ0KDQpmdW5jdGlvbiBzZXRSZWYocmF3UmVmLCBvbGRSYXdSZWYsIHBhcmVudFN1c3BlbnNlLCB2bm9kZSwgaXNVbm1vdW50ID0gZmFsc2UpIHsNCiAgaWYgKGlzQXJyYXkocmF3UmVmKSkgew0KICAgIHJhd1JlZi5mb3JFYWNoKA0KICAgICAgKHIsIGkpID0+IHNldFJlZigNCiAgICAgICAgciwNCiAgICAgICAgb2xkUmF3UmVmICYmIChpc0FycmF5KG9sZFJhd1JlZikgPyBvbGRSYXdSZWZbaV0gOiBvbGRSYXdSZWYpLA0KICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgdm5vZGUsDQogICAgICAgIGlzVW5tb3VudA0KICAgICAgKQ0KICAgICk7DQogICAgcmV0dXJuOw0KICB9DQogIGlmIChpc0FzeW5jV3JhcHBlcih2bm9kZSkgJiYgIWlzVW5tb3VudCkgew0KICAgIGlmICh2bm9kZS5zaGFwZUZsYWcgJiA1MTIgJiYgdm5vZGUudHlwZS5fX2FzeW5jUmVzb2x2ZWQgJiYgdm5vZGUuY29tcG9uZW50LnN1YlRyZWUuY29tcG9uZW50KSB7DQogICAgICBzZXRSZWYocmF3UmVmLCBvbGRSYXdSZWYsIHBhcmVudFN1c3BlbnNlLCB2bm9kZS5jb21wb25lbnQuc3ViVHJlZSk7DQogICAgfQ0KICAgIHJldHVybjsNCiAgfQ0KICBjb25zdCByZWZWYWx1ZSA9IHZub2RlLnNoYXBlRmxhZyAmIDQgPyBnZXRDb21wb25lbnRQdWJsaWNJbnN0YW5jZSh2bm9kZS5jb21wb25lbnQpIDogdm5vZGUuZWw7DQogIGNvbnN0IHZhbHVlID0gaXNVbm1vdW50ID8gbnVsbCA6IHJlZlZhbHVlOw0KICBjb25zdCB7IGk6IG93bmVyLCByOiByZWYgfSA9IHJhd1JlZjsNCiAgaWYgKCFvd25lcikgew0KICAgIHdhcm4kMSgNCiAgICAgIGBNaXNzaW5nIHJlZiBvd25lciBjb250ZXh0LiByZWYgY2Fubm90IGJlIHVzZWQgb24gaG9pc3RlZCB2bm9kZXMuIEEgdm5vZGUgd2l0aCByZWYgbXVzdCBiZSBjcmVhdGVkIGluc2lkZSB0aGUgcmVuZGVyIGZ1bmN0aW9uLmANCiAgICApOw0KICAgIHJldHVybjsNCiAgfQ0KICBjb25zdCBvbGRSZWYgPSBvbGRSYXdSZWYgJiYgb2xkUmF3UmVmLnI7DQogIGNvbnN0IHJlZnMgPSBvd25lci5yZWZzID09PSBFTVBUWV9PQkogPyBvd25lci5yZWZzID0ge30gOiBvd25lci5yZWZzOw0KICBjb25zdCBzZXR1cFN0YXRlID0gb3duZXIuc2V0dXBTdGF0ZTsNCiAgY29uc3QgcmF3U2V0dXBTdGF0ZSA9IHRvUmF3KHNldHVwU3RhdGUpOw0KICBjb25zdCBjYW5TZXRTZXR1cFJlZiA9IHNldHVwU3RhdGUgPT09IEVNUFRZX09CSiA/ICgpID0+IGZhbHNlIDogKGtleSkgPT4gew0KICAgIHsNCiAgICAgIGlmIChoYXNPd24ocmF3U2V0dXBTdGF0ZSwga2V5KSAmJiAhaXNSZWYocmF3U2V0dXBTdGF0ZVtrZXldKSkgew0KICAgICAgICB3YXJuJDEoDQogICAgICAgICAgYFRlbXBsYXRlIHJlZiAiJHtrZXl9IiB1c2VkIG9uIGEgbm9uLXJlZiB2YWx1ZS4gSXQgd2lsbCBub3Qgd29yayBpbiB0aGUgcHJvZHVjdGlvbiBidWlsZC5gDQogICAgICAgICk7DQogICAgICB9DQogICAgICBpZiAoa25vd25UZW1wbGF0ZVJlZnMuaGFzKHJhd1NldHVwU3RhdGVba2V5XSkpIHsNCiAgICAgICAgcmV0dXJuIGZhbHNlOw0KICAgICAgfQ0KICAgIH0NCiAgICByZXR1cm4gaGFzT3duKHJhd1NldHVwU3RhdGUsIGtleSk7DQogIH07DQogIGlmIChvbGRSZWYgIT0gbnVsbCAmJiBvbGRSZWYgIT09IHJlZikgew0KICAgIGlmIChpc1N0cmluZyhvbGRSZWYpKSB7DQogICAgICByZWZzW29sZFJlZl0gPSBudWxsOw0KICAgICAgaWYgKGNhblNldFNldHVwUmVmKG9sZFJlZikpIHsNCiAgICAgICAgc2V0dXBTdGF0ZVtvbGRSZWZdID0gbnVsbDsNCiAgICAgIH0NCiAgICB9IGVsc2UgaWYgKGlzUmVmKG9sZFJlZikpIHsNCiAgICAgIG9sZFJlZi52YWx1ZSA9IG51bGw7DQogICAgfQ0KICB9DQogIGlmIChpc0Z1bmN0aW9uKHJlZikpIHsNCiAgICBjYWxsV2l0aEVycm9ySGFuZGxpbmcocmVmLCBvd25lciwgMTIsIFt2YWx1ZSwgcmVmc10pOw0KICB9IGVsc2Ugew0KICAgIGNvbnN0IF9pc1N0cmluZyA9IGlzU3RyaW5nKHJlZik7DQogICAgY29uc3QgX2lzUmVmID0gaXNSZWYocmVmKTsNCiAgICBpZiAoX2lzU3RyaW5nIHx8IF9pc1JlZikgew0KICAgICAgY29uc3QgZG9TZXQgPSAoKSA9PiB7DQogICAgICAgIGlmIChyYXdSZWYuZikgew0KICAgICAgICAgIGNvbnN0IGV4aXN0aW5nID0gX2lzU3RyaW5nID8gY2FuU2V0U2V0dXBSZWYocmVmKSA/IHNldHVwU3RhdGVbcmVmXSA6IHJlZnNbcmVmXSA6IHJlZi52YWx1ZTsNCiAgICAgICAgICBpZiAoaXNVbm1vdW50KSB7DQogICAgICAgICAgICBpc0FycmF5KGV4aXN0aW5nKSAmJiByZW1vdmUoZXhpc3RpbmcsIHJlZlZhbHVlKTsNCiAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgaWYgKCFpc0FycmF5KGV4aXN0aW5nKSkgew0KICAgICAgICAgICAgICBpZiAoX2lzU3RyaW5nKSB7DQogICAgICAgICAgICAgICAgcmVmc1tyZWZdID0gW3JlZlZhbHVlXTsNCiAgICAgICAgICAgICAgICBpZiAoY2FuU2V0U2V0dXBSZWYocmVmKSkgew0KICAgICAgICAgICAgICAgICAgc2V0dXBTdGF0ZVtyZWZdID0gcmVmc1tyZWZdOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICByZWYudmFsdWUgPSBbcmVmVmFsdWVdOw0KICAgICAgICAgICAgICAgIGlmIChyYXdSZWYuaykgcmVmc1tyYXdSZWYua10gPSByZWYudmFsdWU7DQogICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0gZWxzZSBpZiAoIWV4aXN0aW5nLmluY2x1ZGVzKHJlZlZhbHVlKSkgew0KICAgICAgICAgICAgICBleGlzdGluZy5wdXNoKHJlZlZhbHVlKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICB9DQogICAgICAgIH0gZWxzZSBpZiAoX2lzU3RyaW5nKSB7DQogICAgICAgICAgcmVmc1tyZWZdID0gdmFsdWU7DQogICAgICAgICAgaWYgKGNhblNldFNldHVwUmVmKHJlZikpIHsNCiAgICAgICAgICAgIHNldHVwU3RhdGVbcmVmXSA9IHZhbHVlOw0KICAgICAgICAgIH0NCiAgICAgICAgfSBlbHNlIGlmIChfaXNSZWYpIHsNCiAgICAgICAgICByZWYudmFsdWUgPSB2YWx1ZTsNCiAgICAgICAgICBpZiAocmF3UmVmLmspIHJlZnNbcmF3UmVmLmtdID0gdmFsdWU7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgd2FybiQxKCJJbnZhbGlkIHRlbXBsYXRlIHJlZiB0eXBlOiIsIHJlZiwgYCgke3R5cGVvZiByZWZ9KWApOw0KICAgICAgICB9DQogICAgICB9Ow0KICAgICAgaWYgKHZhbHVlKSB7DQogICAgICAgIGRvU2V0LmlkID0gLTE7DQogICAgICAgIHF1ZXVlUG9zdFJlbmRlckVmZmVjdChkb1NldCwgcGFyZW50U3VzcGVuc2UpOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgZG9TZXQoKTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgd2FybiQxKCJJbnZhbGlkIHRlbXBsYXRlIHJlZiB0eXBlOiIsIHJlZiwgYCgke3R5cGVvZiByZWZ9KWApOw0KICAgIH0NCiAgfQ0KfQ0KDQpsZXQgaGFzTG9nZ2VkTWlzbWF0Y2hFcnJvciA9IGZhbHNlOw0KY29uc3QgbG9nTWlzbWF0Y2hFcnJvciA9ICgpID0+IHsNCiAgaWYgKGhhc0xvZ2dlZE1pc21hdGNoRXJyb3IpIHsNCiAgICByZXR1cm47DQogIH0NCiAgY29uc29sZS5lcnJvcigiSHlkcmF0aW9uIGNvbXBsZXRlZCBidXQgY29udGFpbnMgbWlzbWF0Y2hlcy4iKTsNCiAgaGFzTG9nZ2VkTWlzbWF0Y2hFcnJvciA9IHRydWU7DQp9Ow0KY29uc3QgaXNTVkdDb250YWluZXIgPSAoY29udGFpbmVyKSA9PiBjb250YWluZXIubmFtZXNwYWNlVVJJLmluY2x1ZGVzKCJzdmciKSAmJiBjb250YWluZXIudGFnTmFtZSAhPT0gImZvcmVpZ25PYmplY3QiOw0KY29uc3QgaXNNYXRoTUxDb250YWluZXIgPSAoY29udGFpbmVyKSA9PiBjb250YWluZXIubmFtZXNwYWNlVVJJLmluY2x1ZGVzKCJNYXRoTUwiKTsNCmNvbnN0IGdldENvbnRhaW5lclR5cGUgPSAoY29udGFpbmVyKSA9PiB7DQogIGlmIChjb250YWluZXIubm9kZVR5cGUgIT09IDEpIHJldHVybiB2b2lkIDA7DQogIGlmIChpc1NWR0NvbnRhaW5lcihjb250YWluZXIpKSByZXR1cm4gInN2ZyI7DQogIGlmIChpc01hdGhNTENvbnRhaW5lcihjb250YWluZXIpKSByZXR1cm4gIm1hdGhtbCI7DQogIHJldHVybiB2b2lkIDA7DQp9Ow0KY29uc3QgaXNDb21tZW50ID0gKG5vZGUpID0+IG5vZGUubm9kZVR5cGUgPT09IDg7DQpmdW5jdGlvbiBjcmVhdGVIeWRyYXRpb25GdW5jdGlvbnMocmVuZGVyZXJJbnRlcm5hbHMpIHsNCiAgY29uc3Qgew0KICAgIG10OiBtb3VudENvbXBvbmVudCwNCiAgICBwOiBwYXRjaCwNCiAgICBvOiB7DQogICAgICBwYXRjaFByb3AsDQogICAgICBjcmVhdGVUZXh0LA0KICAgICAgbmV4dFNpYmxpbmcsDQogICAgICBwYXJlbnROb2RlLA0KICAgICAgcmVtb3ZlLA0KICAgICAgaW5zZXJ0LA0KICAgICAgY3JlYXRlQ29tbWVudA0KICAgIH0NCiAgfSA9IHJlbmRlcmVySW50ZXJuYWxzOw0KICBjb25zdCBoeWRyYXRlID0gKHZub2RlLCBjb250YWluZXIpID0+IHsNCiAgICBpZiAoIWNvbnRhaW5lci5oYXNDaGlsZE5vZGVzKCkpIHsNCiAgICAgIHdhcm4kMSgNCiAgICAgICAgYEF0dGVtcHRpbmcgdG8gaHlkcmF0ZSBleGlzdGluZyBtYXJrdXAgYnV0IGNvbnRhaW5lciBpcyBlbXB0eS4gUGVyZm9ybWluZyBmdWxsIG1vdW50IGluc3RlYWQuYA0KICAgICAgKTsNCiAgICAgIHBhdGNoKG51bGwsIHZub2RlLCBjb250YWluZXIpOw0KICAgICAgZmx1c2hQb3N0Rmx1c2hDYnMoKTsNCiAgICAgIGNvbnRhaW5lci5fdm5vZGUgPSB2bm9kZTsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgaHlkcmF0ZU5vZGUoY29udGFpbmVyLmZpcnN0Q2hpbGQsIHZub2RlLCBudWxsLCBudWxsLCBudWxsKTsNCiAgICBmbHVzaFBvc3RGbHVzaENicygpOw0KICAgIGNvbnRhaW5lci5fdm5vZGUgPSB2bm9kZTsNCiAgfTsNCiAgY29uc3QgaHlkcmF0ZU5vZGUgPSAobm9kZSwgdm5vZGUsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIHNsb3RTY29wZUlkcywgb3B0aW1pemVkID0gZmFsc2UpID0+IHsNCiAgICBvcHRpbWl6ZWQgPSBvcHRpbWl6ZWQgfHwgISF2bm9kZS5keW5hbWljQ2hpbGRyZW47DQogICAgY29uc3QgaXNGcmFnbWVudFN0YXJ0ID0gaXNDb21tZW50KG5vZGUpICYmIG5vZGUuZGF0YSA9PT0gIlsiOw0KICAgIGNvbnN0IG9uTWlzbWF0Y2ggPSAoKSA9PiBoYW5kbGVNaXNtYXRjaCgNCiAgICAgIG5vZGUsDQogICAgICB2bm9kZSwNCiAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgaXNGcmFnbWVudFN0YXJ0DQogICAgKTsNCiAgICBjb25zdCB7IHR5cGUsIHJlZiwgc2hhcGVGbGFnLCBwYXRjaEZsYWcgfSA9IHZub2RlOw0KICAgIGxldCBkb21UeXBlID0gbm9kZS5ub2RlVHlwZTsNCiAgICB2bm9kZS5lbCA9IG5vZGU7DQogICAgew0KICAgICAgZGVmKG5vZGUsICJfX3Zub2RlIiwgdm5vZGUsIHRydWUpOw0KICAgICAgZGVmKG5vZGUsICJfX3Z1ZVBhcmVudENvbXBvbmVudCIsIHBhcmVudENvbXBvbmVudCwgdHJ1ZSk7DQogICAgfQ0KICAgIGlmIChwYXRjaEZsYWcgPT09IC0yKSB7DQogICAgICBvcHRpbWl6ZWQgPSBmYWxzZTsNCiAgICAgIHZub2RlLmR5bmFtaWNDaGlsZHJlbiA9IG51bGw7DQogICAgfQ0KICAgIGxldCBuZXh0Tm9kZSA9IG51bGw7DQogICAgc3dpdGNoICh0eXBlKSB7DQogICAgICBjYXNlIFRleHQ6DQogICAgICAgIGlmIChkb21UeXBlICE9PSAzKSB7DQogICAgICAgICAgaWYgKHZub2RlLmNoaWxkcmVuID09PSAiIikgew0KICAgICAgICAgICAgaW5zZXJ0KHZub2RlLmVsID0gY3JlYXRlVGV4dCgiIiksIHBhcmVudE5vZGUobm9kZSksIG5vZGUpOw0KICAgICAgICAgICAgbmV4dE5vZGUgPSBub2RlOw0KICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBuZXh0Tm9kZSA9IG9uTWlzbWF0Y2goKTsNCiAgICAgICAgICB9DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgaWYgKG5vZGUuZGF0YSAhPT0gdm5vZGUuY2hpbGRyZW4pIHsNCiAgICAgICAgICAgIHdhcm4kMSgNCiAgICAgICAgICAgICAgYEh5ZHJhdGlvbiB0ZXh0IG1pc21hdGNoIGluYCwNCiAgICAgICAgICAgICAgbm9kZS5wYXJlbnROb2RlLA0KICAgICAgICAgICAgICBgDQogIC0gcmVuZGVyZWQgb24gc2VydmVyOiAke0pTT04uc3RyaW5naWZ5KA0KICAgICAgICAgICAgICAgIG5vZGUuZGF0YQ0KICAgICAgICAgICAgICApfQ0KICAtIGV4cGVjdGVkIG9uIGNsaWVudDogJHtKU09OLnN0cmluZ2lmeSh2bm9kZS5jaGlsZHJlbil9YA0KICAgICAgICAgICAgKTsNCiAgICAgICAgICAgIGxvZ01pc21hdGNoRXJyb3IoKTsNCiAgICAgICAgICAgIG5vZGUuZGF0YSA9IHZub2RlLmNoaWxkcmVuOw0KICAgICAgICAgIH0NCiAgICAgICAgICBuZXh0Tm9kZSA9IG5leHRTaWJsaW5nKG5vZGUpOw0KICAgICAgICB9DQogICAgICAgIGJyZWFrOw0KICAgICAgY2FzZSBDb21tZW50Og0KICAgICAgICBpZiAoaXNUZW1wbGF0ZU5vZGUobm9kZSkpIHsNCiAgICAgICAgICBuZXh0Tm9kZSA9IG5leHRTaWJsaW5nKG5vZGUpOw0KICAgICAgICAgIHJlcGxhY2VOb2RlKA0KICAgICAgICAgICAgdm5vZGUuZWwgPSBub2RlLmNvbnRlbnQuZmlyc3RDaGlsZCwNCiAgICAgICAgICAgIG5vZGUsDQogICAgICAgICAgICBwYXJlbnRDb21wb25lbnQNCiAgICAgICAgICApOw0KICAgICAgICB9IGVsc2UgaWYgKGRvbVR5cGUgIT09IDggfHwgaXNGcmFnbWVudFN0YXJ0KSB7DQogICAgICAgICAgbmV4dE5vZGUgPSBvbk1pc21hdGNoKCk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgbmV4dE5vZGUgPSBuZXh0U2libGluZyhub2RlKTsNCiAgICAgICAgfQ0KICAgICAgICBicmVhazsNCiAgICAgIGNhc2UgU3RhdGljOg0KICAgICAgICBpZiAoaXNGcmFnbWVudFN0YXJ0KSB7DQogICAgICAgICAgbm9kZSA9IG5leHRTaWJsaW5nKG5vZGUpOw0KICAgICAgICAgIGRvbVR5cGUgPSBub2RlLm5vZGVUeXBlOw0KICAgICAgICB9DQogICAgICAgIGlmIChkb21UeXBlID09PSAxIHx8IGRvbVR5cGUgPT09IDMpIHsNCiAgICAgICAgICBuZXh0Tm9kZSA9IG5vZGU7DQogICAgICAgICAgY29uc3QgbmVlZFRvQWRvcHRDb250ZW50ID0gIXZub2RlLmNoaWxkcmVuLmxlbmd0aDsNCiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZub2RlLnN0YXRpY0NvdW50OyBpKyspIHsNCiAgICAgICAgICAgIGlmIChuZWVkVG9BZG9wdENvbnRlbnQpDQogICAgICAgICAgICAgIHZub2RlLmNoaWxkcmVuICs9IG5leHROb2RlLm5vZGVUeXBlID09PSAxID8gbmV4dE5vZGUub3V0ZXJIVE1MIDogbmV4dE5vZGUuZGF0YTsNCiAgICAgICAgICAgIGlmIChpID09PSB2bm9kZS5zdGF0aWNDb3VudCAtIDEpIHsNCiAgICAgICAgICAgICAgdm5vZGUuYW5jaG9yID0gbmV4dE5vZGU7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBuZXh0Tm9kZSA9IG5leHRTaWJsaW5nKG5leHROb2RlKTsNCiAgICAgICAgICB9DQogICAgICAgICAgcmV0dXJuIGlzRnJhZ21lbnRTdGFydCA/IG5leHRTaWJsaW5nKG5leHROb2RlKSA6IG5leHROb2RlOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIG9uTWlzbWF0Y2goKTsNCiAgICAgICAgfQ0KICAgICAgICBicmVhazsNCiAgICAgIGNhc2UgRnJhZ21lbnQ6DQogICAgICAgIGlmICghaXNGcmFnbWVudFN0YXJ0KSB7DQogICAgICAgICAgbmV4dE5vZGUgPSBvbk1pc21hdGNoKCk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgbmV4dE5vZGUgPSBoeWRyYXRlRnJhZ21lbnQoDQogICAgICAgICAgICBub2RlLA0KICAgICAgICAgICAgdm5vZGUsDQogICAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgICAgYnJlYWs7DQogICAgICBkZWZhdWx0Og0KICAgICAgICBpZiAoc2hhcGVGbGFnICYgMSkgew0KICAgICAgICAgIGlmICgoZG9tVHlwZSAhPT0gMSB8fCB2bm9kZS50eXBlLnRvTG93ZXJDYXNlKCkgIT09IG5vZGUudGFnTmFtZS50b0xvd2VyQ2FzZSgpKSAmJiAhaXNUZW1wbGF0ZU5vZGUobm9kZSkpIHsNCiAgICAgICAgICAgIG5leHROb2RlID0gb25NaXNtYXRjaCgpOw0KICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBuZXh0Tm9kZSA9IGh5ZHJhdGVFbGVtZW50KA0KICAgICAgICAgICAgICBub2RlLA0KICAgICAgICAgICAgICB2bm9kZSwNCiAgICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgICAgICk7DQogICAgICAgICAgfQ0KICAgICAgICB9IGVsc2UgaWYgKHNoYXBlRmxhZyAmIDYpIHsNCiAgICAgICAgICB2bm9kZS5zbG90U2NvcGVJZHMgPSBzbG90U2NvcGVJZHM7DQogICAgICAgICAgY29uc3QgY29udGFpbmVyID0gcGFyZW50Tm9kZShub2RlKTsNCiAgICAgICAgICBpZiAoaXNGcmFnbWVudFN0YXJ0KSB7DQogICAgICAgICAgICBuZXh0Tm9kZSA9IGxvY2F0ZUNsb3NpbmdBbmNob3Iobm9kZSk7DQogICAgICAgICAgfSBlbHNlIGlmIChpc0NvbW1lbnQobm9kZSkgJiYgbm9kZS5kYXRhID09PSAidGVsZXBvcnQgc3RhcnQiKSB7DQogICAgICAgICAgICBuZXh0Tm9kZSA9IGxvY2F0ZUNsb3NpbmdBbmNob3Iobm9kZSwgbm9kZS5kYXRhLCAidGVsZXBvcnQgZW5kIik7DQogICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIG5leHROb2RlID0gbmV4dFNpYmxpbmcobm9kZSk7DQogICAgICAgICAgfQ0KICAgICAgICAgIG1vdW50Q29tcG9uZW50KA0KICAgICAgICAgICAgdm5vZGUsDQogICAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgICBudWxsLA0KICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgICBnZXRDb250YWluZXJUeXBlKGNvbnRhaW5lciksDQogICAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgICApOw0KICAgICAgICAgIGlmIChpc0FzeW5jV3JhcHBlcih2bm9kZSkgJiYgIXZub2RlLnR5cGUuX19hc3luY1Jlc29sdmVkKSB7DQogICAgICAgICAgICBsZXQgc3ViVHJlZTsNCiAgICAgICAgICAgIGlmIChpc0ZyYWdtZW50U3RhcnQpIHsNCiAgICAgICAgICAgICAgc3ViVHJlZSA9IGNyZWF0ZVZOb2RlKEZyYWdtZW50KTsNCiAgICAgICAgICAgICAgc3ViVHJlZS5hbmNob3IgPSBuZXh0Tm9kZSA/IG5leHROb2RlLnByZXZpb3VzU2libGluZyA6IGNvbnRhaW5lci5sYXN0Q2hpbGQ7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICBzdWJUcmVlID0gbm9kZS5ub2RlVHlwZSA9PT0gMyA/IGNyZWF0ZVRleHRWTm9kZSgiIikgOiBjcmVhdGVWTm9kZSgiZGl2Iik7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBzdWJUcmVlLmVsID0gbm9kZTsNCiAgICAgICAgICAgIHZub2RlLmNvbXBvbmVudC5zdWJUcmVlID0gc3ViVHJlZTsNCiAgICAgICAgICB9DQogICAgICAgIH0gZWxzZSBpZiAoc2hhcGVGbGFnICYgNjQpIHsNCiAgICAgICAgICBpZiAoZG9tVHlwZSAhPT0gOCkgew0KICAgICAgICAgICAgbmV4dE5vZGUgPSBvbk1pc21hdGNoKCk7DQogICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIG5leHROb2RlID0gdm5vZGUudHlwZS5oeWRyYXRlKA0KICAgICAgICAgICAgICBub2RlLA0KICAgICAgICAgICAgICB2bm9kZSwNCiAgICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgICAgICBvcHRpbWl6ZWQsDQogICAgICAgICAgICAgIHJlbmRlcmVySW50ZXJuYWxzLA0KICAgICAgICAgICAgICBoeWRyYXRlQ2hpbGRyZW4NCiAgICAgICAgICAgICk7DQogICAgICAgICAgfQ0KICAgICAgICB9IGVsc2UgaWYgKHNoYXBlRmxhZyAmIDEyOCkgew0KICAgICAgICAgIG5leHROb2RlID0gdm5vZGUudHlwZS5oeWRyYXRlKA0KICAgICAgICAgICAgbm9kZSwNCiAgICAgICAgICAgIHZub2RlLA0KICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgICBnZXRDb250YWluZXJUeXBlKHBhcmVudE5vZGUobm9kZSkpLA0KICAgICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgICAgb3B0aW1pemVkLA0KICAgICAgICAgICAgcmVuZGVyZXJJbnRlcm5hbHMsDQogICAgICAgICAgICBoeWRyYXRlTm9kZQ0KICAgICAgICAgICk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgd2FybiQxKCJJbnZhbGlkIEhvc3RWTm9kZSB0eXBlOiIsIHR5cGUsIGAoJHt0eXBlb2YgdHlwZX0pYCk7DQogICAgICAgIH0NCiAgICB9DQogICAgaWYgKHJlZiAhPSBudWxsKSB7DQogICAgICBzZXRSZWYocmVmLCBudWxsLCBwYXJlbnRTdXNwZW5zZSwgdm5vZGUpOw0KICAgIH0NCiAgICByZXR1cm4gbmV4dE5vZGU7DQogIH07DQogIGNvbnN0IGh5ZHJhdGVFbGVtZW50ID0gKGVsLCB2bm9kZSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQpID0+IHsNCiAgICBvcHRpbWl6ZWQgPSBvcHRpbWl6ZWQgfHwgISF2bm9kZS5keW5hbWljQ2hpbGRyZW47DQogICAgY29uc3QgeyB0eXBlLCBwcm9wcywgcGF0Y2hGbGFnLCBzaGFwZUZsYWcsIGRpcnMsIHRyYW5zaXRpb24gfSA9IHZub2RlOw0KICAgIGNvbnN0IGZvcmNlUGF0Y2ggPSB0eXBlID09PSAiaW5wdXQiIHx8IHR5cGUgPT09ICJvcHRpb24iOw0KICAgIHsNCiAgICAgIGlmIChkaXJzKSB7DQogICAgICAgIGludm9rZURpcmVjdGl2ZUhvb2sodm5vZGUsIG51bGwsIHBhcmVudENvbXBvbmVudCwgImNyZWF0ZWQiKTsNCiAgICAgIH0NCiAgICAgIGxldCBuZWVkQ2FsbFRyYW5zaXRpb25Ib29rcyA9IGZhbHNlOw0KICAgICAgaWYgKGlzVGVtcGxhdGVOb2RlKGVsKSkgew0KICAgICAgICBuZWVkQ2FsbFRyYW5zaXRpb25Ib29rcyA9IG5lZWRUcmFuc2l0aW9uKA0KICAgICAgICAgIG51bGwsDQogICAgICAgICAgLy8gbm8gbmVlZCBjaGVjayBwYXJlbnRTdXNwZW5zZSBpbiBoeWRyYXRpb24NCiAgICAgICAgICB0cmFuc2l0aW9uDQogICAgICAgICkgJiYgcGFyZW50Q29tcG9uZW50ICYmIHBhcmVudENvbXBvbmVudC52bm9kZS5wcm9wcyAmJiBwYXJlbnRDb21wb25lbnQudm5vZGUucHJvcHMuYXBwZWFyOw0KICAgICAgICBjb25zdCBjb250ZW50ID0gZWwuY29udGVudC5maXJzdENoaWxkOw0KICAgICAgICBpZiAobmVlZENhbGxUcmFuc2l0aW9uSG9va3MpIHsNCiAgICAgICAgICBjb25zdCBjbHMgPSBjb250ZW50LmdldEF0dHJpYnV0ZSgiY2xhc3MiKTsNCiAgICAgICAgICBpZiAoY2xzKSBjb250ZW50LiRjbHMgPSBjbHM7DQogICAgICAgICAgdHJhbnNpdGlvbi5iZWZvcmVFbnRlcihjb250ZW50KTsNCiAgICAgICAgfQ0KICAgICAgICByZXBsYWNlTm9kZShjb250ZW50LCBlbCwgcGFyZW50Q29tcG9uZW50KTsNCiAgICAgICAgdm5vZGUuZWwgPSBlbCA9IGNvbnRlbnQ7DQogICAgICB9DQogICAgICBpZiAoc2hhcGVGbGFnICYgMTYgJiYgLy8gc2tpcCBpZiBlbGVtZW50IGhhcyBpbm5lckhUTUwgLyB0ZXh0Q29udGVudA0KICAgICAgIShwcm9wcyAmJiAocHJvcHMuaW5uZXJIVE1MIHx8IHByb3BzLnRleHRDb250ZW50KSkpIHsNCiAgICAgICAgbGV0IG5leHQgPSBoeWRyYXRlQ2hpbGRyZW4oDQogICAgICAgICAgZWwuZmlyc3RDaGlsZCwNCiAgICAgICAgICB2bm9kZSwNCiAgICAgICAgICBlbCwNCiAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICApOw0KICAgICAgICBsZXQgaGFzV2FybmVkID0gZmFsc2U7DQogICAgICAgIHdoaWxlIChuZXh0KSB7DQogICAgICAgICAgaWYgKCFpc01pc21hdGNoQWxsb3dlZChlbCwgMSAvKiBDSElMRFJFTiAqLykpIHsNCiAgICAgICAgICAgIGlmICghaGFzV2FybmVkKSB7DQogICAgICAgICAgICAgIHdhcm4kMSgNCiAgICAgICAgICAgICAgICBgSHlkcmF0aW9uIGNoaWxkcmVuIG1pc21hdGNoIG9uYCwNCiAgICAgICAgICAgICAgICBlbCwNCiAgICAgICAgICAgICAgICBgDQpTZXJ2ZXIgcmVuZGVyZWQgZWxlbWVudCBjb250YWlucyBtb3JlIGNoaWxkIG5vZGVzIHRoYW4gY2xpZW50IHZkb20uYA0KICAgICAgICAgICAgICApOw0KICAgICAgICAgICAgICBoYXNXYXJuZWQgPSB0cnVlOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgbG9nTWlzbWF0Y2hFcnJvcigpOw0KICAgICAgICAgIH0NCiAgICAgICAgICBjb25zdCBjdXIgPSBuZXh0Ow0KICAgICAgICAgIG5leHQgPSBuZXh0Lm5leHRTaWJsaW5nOw0KICAgICAgICAgIHJlbW92ZShjdXIpOw0KICAgICAgICB9DQogICAgICB9IGVsc2UgaWYgKHNoYXBlRmxhZyAmIDgpIHsNCiAgICAgICAgbGV0IGNsaWVudFRleHQgPSB2bm9kZS5jaGlsZHJlbjsNCiAgICAgICAgaWYgKGNsaWVudFRleHRbMF0gPT09ICJcbiIgJiYgKGVsLnRhZ05hbWUgPT09ICJQUkUiIHx8IGVsLnRhZ05hbWUgPT09ICJURVhUQVJFQSIpKSB7DQogICAgICAgICAgY2xpZW50VGV4dCA9IGNsaWVudFRleHQuc2xpY2UoMSk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKGVsLnRleHRDb250ZW50ICE9PSBjbGllbnRUZXh0KSB7DQogICAgICAgICAgaWYgKCFpc01pc21hdGNoQWxsb3dlZChlbCwgMCAvKiBURVhUICovKSkgew0KICAgICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgICBgSHlkcmF0aW9uIHRleHQgY29udGVudCBtaXNtYXRjaCBvbmAsDQogICAgICAgICAgICAgIGVsLA0KICAgICAgICAgICAgICBgDQogIC0gcmVuZGVyZWQgb24gc2VydmVyOiAke2VsLnRleHRDb250ZW50fQ0KICAtIGV4cGVjdGVkIG9uIGNsaWVudDogJHt2bm9kZS5jaGlsZHJlbn1gDQogICAgICAgICAgICApOw0KICAgICAgICAgICAgbG9nTWlzbWF0Y2hFcnJvcigpOw0KICAgICAgICAgIH0NCiAgICAgICAgICBlbC50ZXh0Q29udGVudCA9IHZub2RlLmNoaWxkcmVuOw0KICAgICAgICB9DQogICAgICB9DQogICAgICBpZiAocHJvcHMpIHsNCiAgICAgICAgew0KICAgICAgICAgIGNvbnN0IGlzQ3VzdG9tRWxlbWVudCA9IGVsLnRhZ05hbWUuaW5jbHVkZXMoIi0iKTsNCiAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBwcm9wcykgew0KICAgICAgICAgICAgaWYgKC8vICMxMTE4OSBza2lwIGlmIHRoaXMgbm9kZSBoYXMgZGlyZWN0aXZlcyB0aGF0IGhhdmUgY3JlYXRlZCBob29rcw0KICAgICAgICAgICAgLy8gYXMgaXQgY291bGQgaGF2ZSBtdXRhdGVkIHRoZSBET00gaW4gYW55IHBvc3NpYmxlIHdheQ0KICAgICAgICAgICAgIShkaXJzICYmIGRpcnMuc29tZSgoZCkgPT4gZC5kaXIuY3JlYXRlZCkpICYmIHByb3BIYXNNaXNtYXRjaChlbCwga2V5LCBwcm9wc1trZXldLCB2bm9kZSwgcGFyZW50Q29tcG9uZW50KSkgew0KICAgICAgICAgICAgICBsb2dNaXNtYXRjaEVycm9yKCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZiAoZm9yY2VQYXRjaCAmJiAoa2V5LmVuZHNXaXRoKCJ2YWx1ZSIpIHx8IGtleSA9PT0gImluZGV0ZXJtaW5hdGUiKSB8fCBpc09uKGtleSkgJiYgIWlzUmVzZXJ2ZWRQcm9wKGtleSkgfHwgLy8gZm9yY2UgaHlkcmF0ZSB2LWJpbmQgd2l0aCAucHJvcCBtb2RpZmllcnMNCiAgICAgICAgICAgIGtleVswXSA9PT0gIi4iIHx8IGlzQ3VzdG9tRWxlbWVudCkgew0KICAgICAgICAgICAgICBwYXRjaFByb3AoZWwsIGtleSwgbnVsbCwgcHJvcHNba2V5XSwgdm9pZCAwLCBwYXJlbnRDb21wb25lbnQpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgbGV0IHZub2RlSG9va3M7DQogICAgICBpZiAodm5vZGVIb29rcyA9IHByb3BzICYmIHByb3BzLm9uVm5vZGVCZWZvcmVNb3VudCkgew0KICAgICAgICBpbnZva2VWTm9kZUhvb2sodm5vZGVIb29rcywgcGFyZW50Q29tcG9uZW50LCB2bm9kZSk7DQogICAgICB9DQogICAgICBpZiAoZGlycykgew0KICAgICAgICBpbnZva2VEaXJlY3RpdmVIb29rKHZub2RlLCBudWxsLCBwYXJlbnRDb21wb25lbnQsICJiZWZvcmVNb3VudCIpOw0KICAgICAgfQ0KICAgICAgaWYgKCh2bm9kZUhvb2tzID0gcHJvcHMgJiYgcHJvcHMub25Wbm9kZU1vdW50ZWQpIHx8IGRpcnMgfHwgbmVlZENhbGxUcmFuc2l0aW9uSG9va3MpIHsNCiAgICAgICAgcXVldWVFZmZlY3RXaXRoU3VzcGVuc2UoKCkgPT4gew0KICAgICAgICAgIHZub2RlSG9va3MgJiYgaW52b2tlVk5vZGVIb29rKHZub2RlSG9va3MsIHBhcmVudENvbXBvbmVudCwgdm5vZGUpOw0KICAgICAgICAgIG5lZWRDYWxsVHJhbnNpdGlvbkhvb2tzICYmIHRyYW5zaXRpb24uZW50ZXIoZWwpOw0KICAgICAgICAgIGRpcnMgJiYgaW52b2tlRGlyZWN0aXZlSG9vayh2bm9kZSwgbnVsbCwgcGFyZW50Q29tcG9uZW50LCAibW91bnRlZCIpOw0KICAgICAgICB9LCBwYXJlbnRTdXNwZW5zZSk7DQogICAgICB9DQogICAgfQ0KICAgIHJldHVybiBlbC5uZXh0U2libGluZzsNCiAgfTsNCiAgY29uc3QgaHlkcmF0ZUNoaWxkcmVuID0gKG5vZGUsIHBhcmVudFZOb2RlLCBjb250YWluZXIsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIHNsb3RTY29wZUlkcywgb3B0aW1pemVkKSA9PiB7DQogICAgb3B0aW1pemVkID0gb3B0aW1pemVkIHx8ICEhcGFyZW50Vk5vZGUuZHluYW1pY0NoaWxkcmVuOw0KICAgIGNvbnN0IGNoaWxkcmVuID0gcGFyZW50Vk5vZGUuY2hpbGRyZW47DQogICAgY29uc3QgbCA9IGNoaWxkcmVuLmxlbmd0aDsNCiAgICBsZXQgaGFzV2FybmVkID0gZmFsc2U7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsOyBpKyspIHsNCiAgICAgIGNvbnN0IHZub2RlID0gb3B0aW1pemVkID8gY2hpbGRyZW5baV0gOiBjaGlsZHJlbltpXSA9IG5vcm1hbGl6ZVZOb2RlKGNoaWxkcmVuW2ldKTsNCiAgICAgIGNvbnN0IGlzVGV4dCA9IHZub2RlLnR5cGUgPT09IFRleHQ7DQogICAgICBpZiAobm9kZSkgew0KICAgICAgICBpZiAoaXNUZXh0ICYmICFvcHRpbWl6ZWQpIHsNCiAgICAgICAgICBpZiAoaSArIDEgPCBsICYmIG5vcm1hbGl6ZVZOb2RlKGNoaWxkcmVuW2kgKyAxXSkudHlwZSA9PT0gVGV4dCkgew0KICAgICAgICAgICAgaW5zZXJ0KA0KICAgICAgICAgICAgICBjcmVhdGVUZXh0KA0KICAgICAgICAgICAgICAgIG5vZGUuZGF0YS5zbGljZSh2bm9kZS5jaGlsZHJlbi5sZW5ndGgpDQogICAgICAgICAgICAgICksDQogICAgICAgICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgICAgICAgbmV4dFNpYmxpbmcobm9kZSkNCiAgICAgICAgICAgICk7DQogICAgICAgICAgICBub2RlLmRhdGEgPSB2bm9kZS5jaGlsZHJlbjsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgbm9kZSA9IGh5ZHJhdGVOb2RlKA0KICAgICAgICAgIG5vZGUsDQogICAgICAgICAgdm5vZGUsDQogICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgKTsNCiAgICAgIH0gZWxzZSBpZiAoaXNUZXh0ICYmICF2bm9kZS5jaGlsZHJlbikgew0KICAgICAgICBpbnNlcnQodm5vZGUuZWwgPSBjcmVhdGVUZXh0KCIiKSwgY29udGFpbmVyKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGlmICghaXNNaXNtYXRjaEFsbG93ZWQoY29udGFpbmVyLCAxIC8qIENISUxEUkVOICovKSkgew0KICAgICAgICAgIGlmICghaGFzV2FybmVkKSB7DQogICAgICAgICAgICB3YXJuJDEoDQogICAgICAgICAgICAgIGBIeWRyYXRpb24gY2hpbGRyZW4gbWlzbWF0Y2ggb25gLA0KICAgICAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgICAgIGANClNlcnZlciByZW5kZXJlZCBlbGVtZW50IGNvbnRhaW5zIGZld2VyIGNoaWxkIG5vZGVzIHRoYW4gY2xpZW50IHZkb20uYA0KICAgICAgICAgICAgKTsNCiAgICAgICAgICAgIGhhc1dhcm5lZCA9IHRydWU7DQogICAgICAgICAgfQ0KICAgICAgICAgIGxvZ01pc21hdGNoRXJyb3IoKTsNCiAgICAgICAgfQ0KICAgICAgICBwYXRjaCgNCiAgICAgICAgICBudWxsLA0KICAgICAgICAgIHZub2RlLA0KICAgICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgICBudWxsLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBnZXRDb250YWluZXJUeXBlKGNvbnRhaW5lciksDQogICAgICAgICAgc2xvdFNjb3BlSWRzDQogICAgICAgICk7DQogICAgICB9DQogICAgfQ0KICAgIHJldHVybiBub2RlOw0KICB9Ow0KICBjb25zdCBoeWRyYXRlRnJhZ21lbnQgPSAobm9kZSwgdm5vZGUsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIHNsb3RTY29wZUlkcywgb3B0aW1pemVkKSA9PiB7DQogICAgY29uc3QgeyBzbG90U2NvcGVJZHM6IGZyYWdtZW50U2xvdFNjb3BlSWRzIH0gPSB2bm9kZTsNCiAgICBpZiAoZnJhZ21lbnRTbG90U2NvcGVJZHMpIHsNCiAgICAgIHNsb3RTY29wZUlkcyA9IHNsb3RTY29wZUlkcyA/IHNsb3RTY29wZUlkcy5jb25jYXQoZnJhZ21lbnRTbG90U2NvcGVJZHMpIDogZnJhZ21lbnRTbG90U2NvcGVJZHM7DQogICAgfQ0KICAgIGNvbnN0IGNvbnRhaW5lciA9IHBhcmVudE5vZGUobm9kZSk7DQogICAgY29uc3QgbmV4dCA9IGh5ZHJhdGVDaGlsZHJlbigNCiAgICAgIG5leHRTaWJsaW5nKG5vZGUpLA0KICAgICAgdm5vZGUsDQogICAgICBjb250YWluZXIsDQogICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgIG9wdGltaXplZA0KICAgICk7DQogICAgaWYgKG5leHQgJiYgaXNDb21tZW50KG5leHQpICYmIG5leHQuZGF0YSA9PT0gIl0iKSB7DQogICAgICByZXR1cm4gbmV4dFNpYmxpbmcodm5vZGUuYW5jaG9yID0gbmV4dCk7DQogICAgfSBlbHNlIHsNCiAgICAgIGxvZ01pc21hdGNoRXJyb3IoKTsNCiAgICAgIGluc2VydCh2bm9kZS5hbmNob3IgPSBjcmVhdGVDb21tZW50KGBdYCksIGNvbnRhaW5lciwgbmV4dCk7DQogICAgICByZXR1cm4gbmV4dDsNCiAgICB9DQogIH07DQogIGNvbnN0IGhhbmRsZU1pc21hdGNoID0gKG5vZGUsIHZub2RlLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBzbG90U2NvcGVJZHMsIGlzRnJhZ21lbnQpID0+IHsNCiAgICBpZiAoIWlzTWlzbWF0Y2hBbGxvd2VkKG5vZGUucGFyZW50RWxlbWVudCwgMSAvKiBDSElMRFJFTiAqLykpIHsNCiAgICAgIHdhcm4kMSgNCiAgICAgICAgYEh5ZHJhdGlvbiBub2RlIG1pc21hdGNoOg0KLSByZW5kZXJlZCBvbiBzZXJ2ZXI6YCwNCiAgICAgICAgbm9kZSwNCiAgICAgICAgbm9kZS5ub2RlVHlwZSA9PT0gMyA/IGAodGV4dClgIDogaXNDb21tZW50KG5vZGUpICYmIG5vZGUuZGF0YSA9PT0gIlsiID8gYChzdGFydCBvZiBmcmFnbWVudClgIDogYGAsDQogICAgICAgIGANCi0gZXhwZWN0ZWQgb24gY2xpZW50OmAsDQogICAgICAgIHZub2RlLnR5cGUNCiAgICAgICk7DQogICAgICBsb2dNaXNtYXRjaEVycm9yKCk7DQogICAgfQ0KICAgIHZub2RlLmVsID0gbnVsbDsNCiAgICBpZiAoaXNGcmFnbWVudCkgew0KICAgICAgY29uc3QgZW5kID0gbG9jYXRlQ2xvc2luZ0FuY2hvcihub2RlKTsNCiAgICAgIHdoaWxlICh0cnVlKSB7DQogICAgICAgIGNvbnN0IG5leHQyID0gbmV4dFNpYmxpbmcobm9kZSk7DQogICAgICAgIGlmIChuZXh0MiAmJiBuZXh0MiAhPT0gZW5kKSB7DQogICAgICAgICAgcmVtb3ZlKG5leHQyKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBicmVhazsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgICBjb25zdCBuZXh0ID0gbmV4dFNpYmxpbmcobm9kZSk7DQogICAgY29uc3QgY29udGFpbmVyID0gcGFyZW50Tm9kZShub2RlKTsNCiAgICByZW1vdmUobm9kZSk7DQogICAgcGF0Y2goDQogICAgICBudWxsLA0KICAgICAgdm5vZGUsDQogICAgICBjb250YWluZXIsDQogICAgICBuZXh0LA0KICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICBnZXRDb250YWluZXJUeXBlKGNvbnRhaW5lciksDQogICAgICBzbG90U2NvcGVJZHMNCiAgICApOw0KICAgIGlmIChwYXJlbnRDb21wb25lbnQpIHsNCiAgICAgIHBhcmVudENvbXBvbmVudC52bm9kZS5lbCA9IHZub2RlLmVsOw0KICAgICAgdXBkYXRlSE9DSG9zdEVsKHBhcmVudENvbXBvbmVudCwgdm5vZGUuZWwpOw0KICAgIH0NCiAgICByZXR1cm4gbmV4dDsNCiAgfTsNCiAgY29uc3QgbG9jYXRlQ2xvc2luZ0FuY2hvciA9IChub2RlLCBvcGVuID0gIlsiLCBjbG9zZSA9ICJdIikgPT4gew0KICAgIGxldCBtYXRjaCA9IDA7DQogICAgd2hpbGUgKG5vZGUpIHsNCiAgICAgIG5vZGUgPSBuZXh0U2libGluZyhub2RlKTsNCiAgICAgIGlmIChub2RlICYmIGlzQ29tbWVudChub2RlKSkgew0KICAgICAgICBpZiAobm9kZS5kYXRhID09PSBvcGVuKSBtYXRjaCsrOw0KICAgICAgICBpZiAobm9kZS5kYXRhID09PSBjbG9zZSkgew0KICAgICAgICAgIGlmIChtYXRjaCA9PT0gMCkgew0KICAgICAgICAgICAgcmV0dXJuIG5leHRTaWJsaW5nKG5vZGUpOw0KICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBtYXRjaC0tOw0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgICByZXR1cm4gbm9kZTsNCiAgfTsNCiAgY29uc3QgcmVwbGFjZU5vZGUgPSAobmV3Tm9kZSwgb2xkTm9kZSwgcGFyZW50Q29tcG9uZW50KSA9PiB7DQogICAgY29uc3QgcGFyZW50Tm9kZTIgPSBvbGROb2RlLnBhcmVudE5vZGU7DQogICAgaWYgKHBhcmVudE5vZGUyKSB7DQogICAgICBwYXJlbnROb2RlMi5yZXBsYWNlQ2hpbGQobmV3Tm9kZSwgb2xkTm9kZSk7DQogICAgfQ0KICAgIGxldCBwYXJlbnQgPSBwYXJlbnRDb21wb25lbnQ7DQogICAgd2hpbGUgKHBhcmVudCkgew0KICAgICAgaWYgKHBhcmVudC52bm9kZS5lbCA9PT0gb2xkTm9kZSkgew0KICAgICAgICBwYXJlbnQudm5vZGUuZWwgPSBwYXJlbnQuc3ViVHJlZS5lbCA9IG5ld05vZGU7DQogICAgICB9DQogICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50Ow0KICAgIH0NCiAgfTsNCiAgY29uc3QgaXNUZW1wbGF0ZU5vZGUgPSAobm9kZSkgPT4gew0KICAgIHJldHVybiBub2RlLm5vZGVUeXBlID09PSAxICYmIG5vZGUudGFnTmFtZSA9PT0gIlRFTVBMQVRFIjsNCiAgfTsNCiAgcmV0dXJuIFtoeWRyYXRlLCBoeWRyYXRlTm9kZV07DQp9DQpmdW5jdGlvbiBwcm9wSGFzTWlzbWF0Y2goZWwsIGtleSwgY2xpZW50VmFsdWUsIHZub2RlLCBpbnN0YW5jZSkgew0KICBsZXQgbWlzbWF0Y2hUeXBlOw0KICBsZXQgbWlzbWF0Y2hLZXk7DQogIGxldCBhY3R1YWw7DQogIGxldCBleHBlY3RlZDsNCiAgaWYgKGtleSA9PT0gImNsYXNzIikgew0KICAgIGlmIChlbC4kY2xzKSB7DQogICAgICBhY3R1YWwgPSBlbC4kY2xzOw0KICAgICAgZGVsZXRlIGVsLiRjbHM7DQogICAgfSBlbHNlIHsNCiAgICAgIGFjdHVhbCA9IGVsLmdldEF0dHJpYnV0ZSgiY2xhc3MiKTsNCiAgICB9DQogICAgZXhwZWN0ZWQgPSBub3JtYWxpemVDbGFzcyhjbGllbnRWYWx1ZSk7DQogICAgaWYgKCFpc1NldEVxdWFsKHRvQ2xhc3NTZXQoYWN0dWFsIHx8ICIiKSwgdG9DbGFzc1NldChleHBlY3RlZCkpKSB7DQogICAgICBtaXNtYXRjaFR5cGUgPSAyIC8qIENMQVNTICovOw0KICAgICAgbWlzbWF0Y2hLZXkgPSBgY2xhc3NgOw0KICAgIH0NCiAgfSBlbHNlIGlmIChrZXkgPT09ICJzdHlsZSIpIHsNCiAgICBhY3R1YWwgPSBlbC5nZXRBdHRyaWJ1dGUoInN0eWxlIikgfHwgIiI7DQogICAgZXhwZWN0ZWQgPSBpc1N0cmluZyhjbGllbnRWYWx1ZSkgPyBjbGllbnRWYWx1ZSA6IHN0cmluZ2lmeVN0eWxlKG5vcm1hbGl6ZVN0eWxlKGNsaWVudFZhbHVlKSk7DQogICAgY29uc3QgYWN0dWFsTWFwID0gdG9TdHlsZU1hcChhY3R1YWwpOw0KICAgIGNvbnN0IGV4cGVjdGVkTWFwID0gdG9TdHlsZU1hcChleHBlY3RlZCk7DQogICAgaWYgKHZub2RlLmRpcnMpIHsNCiAgICAgIGZvciAoY29uc3QgeyBkaXIsIHZhbHVlIH0gb2Ygdm5vZGUuZGlycykgew0KICAgICAgICBpZiAoZGlyLm5hbWUgPT09ICJzaG93IiAmJiAhdmFsdWUpIHsNCiAgICAgICAgICBleHBlY3RlZE1hcC5zZXQoImRpc3BsYXkiLCAibm9uZSIpOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICAgIGlmIChpbnN0YW5jZSkgew0KICAgICAgcmVzb2x2ZUNzc1ZhcnMoaW5zdGFuY2UsIHZub2RlLCBleHBlY3RlZE1hcCk7DQogICAgfQ0KICAgIGlmICghaXNNYXBFcXVhbChhY3R1YWxNYXAsIGV4cGVjdGVkTWFwKSkgew0KICAgICAgbWlzbWF0Y2hUeXBlID0gMyAvKiBTVFlMRSAqLzsNCiAgICAgIG1pc21hdGNoS2V5ID0gInN0eWxlIjsNCiAgICB9DQogIH0gZWxzZSBpZiAoZWwgaW5zdGFuY2VvZiBTVkdFbGVtZW50ICYmIGlzS25vd25TdmdBdHRyKGtleSkgfHwgZWwgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCAmJiAoaXNCb29sZWFuQXR0cihrZXkpIHx8IGlzS25vd25IdG1sQXR0cihrZXkpKSkgew0KICAgIGlmIChpc0Jvb2xlYW5BdHRyKGtleSkpIHsNCiAgICAgIGFjdHVhbCA9IGVsLmhhc0F0dHJpYnV0ZShrZXkpOw0KICAgICAgZXhwZWN0ZWQgPSBpbmNsdWRlQm9vbGVhbkF0dHIoY2xpZW50VmFsdWUpOw0KICAgIH0gZWxzZSBpZiAoY2xpZW50VmFsdWUgPT0gbnVsbCkgew0KICAgICAgYWN0dWFsID0gZWwuaGFzQXR0cmlidXRlKGtleSk7DQogICAgICBleHBlY3RlZCA9IGZhbHNlOw0KICAgIH0gZWxzZSB7DQogICAgICBpZiAoZWwuaGFzQXR0cmlidXRlKGtleSkpIHsNCiAgICAgICAgYWN0dWFsID0gZWwuZ2V0QXR0cmlidXRlKGtleSk7DQogICAgICB9IGVsc2UgaWYgKGtleSA9PT0gInZhbHVlIiAmJiBlbC50YWdOYW1lID09PSAiVEVYVEFSRUEiKSB7DQogICAgICAgIGFjdHVhbCA9IGVsLnZhbHVlOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgYWN0dWFsID0gZmFsc2U7DQogICAgICB9DQogICAgICBleHBlY3RlZCA9IGlzUmVuZGVyYWJsZUF0dHJWYWx1ZShjbGllbnRWYWx1ZSkgPyBTdHJpbmcoY2xpZW50VmFsdWUpIDogZmFsc2U7DQogICAgfQ0KICAgIGlmIChhY3R1YWwgIT09IGV4cGVjdGVkKSB7DQogICAgICBtaXNtYXRjaFR5cGUgPSA0IC8qIEFUVFJJQlVURSAqLzsNCiAgICAgIG1pc21hdGNoS2V5ID0ga2V5Ow0KICAgIH0NCiAgfQ0KICBpZiAobWlzbWF0Y2hUeXBlICE9IG51bGwgJiYgIWlzTWlzbWF0Y2hBbGxvd2VkKGVsLCBtaXNtYXRjaFR5cGUpKSB7DQogICAgY29uc3QgZm9ybWF0ID0gKHYpID0+IHYgPT09IGZhbHNlID8gYChub3QgcmVuZGVyZWQpYCA6IGAke21pc21hdGNoS2V5fT0iJHt2fSJgOw0KICAgIGNvbnN0IHByZVNlZ21lbnQgPSBgSHlkcmF0aW9uICR7TWlzbWF0Y2hUeXBlU3RyaW5nW21pc21hdGNoVHlwZV19IG1pc21hdGNoIG9uYDsNCiAgICBjb25zdCBwb3N0U2VnbWVudCA9IGANCiAgLSByZW5kZXJlZCBvbiBzZXJ2ZXI6ICR7Zm9ybWF0KGFjdHVhbCl9DQogIC0gZXhwZWN0ZWQgb24gY2xpZW50OiAke2Zvcm1hdChleHBlY3RlZCl9DQogIE5vdGU6IHRoaXMgbWlzbWF0Y2ggaXMgY2hlY2stb25seS4gVGhlIERPTSB3aWxsIG5vdCBiZSByZWN0aWZpZWQgaW4gcHJvZHVjdGlvbiBkdWUgdG8gcGVyZm9ybWFuY2Ugb3ZlcmhlYWQuDQogIFlvdSBzaG91bGQgZml4IHRoZSBzb3VyY2Ugb2YgdGhlIG1pc21hdGNoLmA7DQogICAgew0KICAgICAgd2FybiQxKHByZVNlZ21lbnQsIGVsLCBwb3N0U2VnbWVudCk7DQogICAgfQ0KICAgIHJldHVybiB0cnVlOw0KICB9DQogIHJldHVybiBmYWxzZTsNCn0NCmZ1bmN0aW9uIHRvQ2xhc3NTZXQoc3RyKSB7DQogIHJldHVybiBuZXcgU2V0KHN0ci50cmltKCkuc3BsaXQoL1xzKy8pKTsNCn0NCmZ1bmN0aW9uIGlzU2V0RXF1YWwoYSwgYikgew0KICBpZiAoYS5zaXplICE9PSBiLnNpemUpIHsNCiAgICByZXR1cm4gZmFsc2U7DQogIH0NCiAgZm9yIChjb25zdCBzIG9mIGEpIHsNCiAgICBpZiAoIWIuaGFzKHMpKSB7DQogICAgICByZXR1cm4gZmFsc2U7DQogICAgfQ0KICB9DQogIHJldHVybiB0cnVlOw0KfQ0KZnVuY3Rpb24gdG9TdHlsZU1hcChzdHIpIHsNCiAgY29uc3Qgc3R5bGVNYXAgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOw0KICBmb3IgKGNvbnN0IGl0ZW0gb2Ygc3RyLnNwbGl0KCI7IikpIHsNCiAgICBsZXQgW2tleSwgdmFsdWVdID0gaXRlbS5zcGxpdCgiOiIpOw0KICAgIGtleSA9IGtleS50cmltKCk7DQogICAgdmFsdWUgPSB2YWx1ZSAmJiB2YWx1ZS50cmltKCk7DQogICAgaWYgKGtleSAmJiB2YWx1ZSkgew0KICAgICAgc3R5bGVNYXAuc2V0KGtleSwgdmFsdWUpOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gc3R5bGVNYXA7DQp9DQpmdW5jdGlvbiBpc01hcEVxdWFsKGEsIGIpIHsNCiAgaWYgKGEuc2l6ZSAhPT0gYi5zaXplKSB7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9DQogIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIGEpIHsNCiAgICBpZiAodmFsdWUgIT09IGIuZ2V0KGtleSkpIHsNCiAgICAgIHJldHVybiBmYWxzZTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIHRydWU7DQp9DQpmdW5jdGlvbiByZXNvbHZlQ3NzVmFycyhpbnN0YW5jZSwgdm5vZGUsIGV4cGVjdGVkTWFwKSB7DQogIGNvbnN0IHJvb3QgPSBpbnN0YW5jZS5zdWJUcmVlOw0KICBpZiAoaW5zdGFuY2UuZ2V0Q3NzVmFycyAmJiAodm5vZGUgPT09IHJvb3QgfHwgcm9vdCAmJiByb290LnR5cGUgPT09IEZyYWdtZW50ICYmIHJvb3QuY2hpbGRyZW4uaW5jbHVkZXModm5vZGUpKSkgew0KICAgIGNvbnN0IGNzc1ZhcnMgPSBpbnN0YW5jZS5nZXRDc3NWYXJzKCk7DQogICAgZm9yIChjb25zdCBrZXkgaW4gY3NzVmFycykgew0KICAgICAgZXhwZWN0ZWRNYXAuc2V0KA0KICAgICAgICBgLS0ke2dldEVzY2FwZWRDc3NWYXJOYW1lKGtleSl9YCwNCiAgICAgICAgU3RyaW5nKGNzc1ZhcnNba2V5XSkNCiAgICAgICk7DQogICAgfQ0KICB9DQogIGlmICh2bm9kZSA9PT0gcm9vdCAmJiBpbnN0YW5jZS5wYXJlbnQpIHsNCiAgICByZXNvbHZlQ3NzVmFycyhpbnN0YW5jZS5wYXJlbnQsIGluc3RhbmNlLnZub2RlLCBleHBlY3RlZE1hcCk7DQogIH0NCn0NCmNvbnN0IGFsbG93TWlzbWF0Y2hBdHRyID0gImRhdGEtYWxsb3ctbWlzbWF0Y2giOw0KY29uc3QgTWlzbWF0Y2hUeXBlU3RyaW5nID0gew0KICBbMCAvKiBURVhUICovXTogInRleHQiLA0KICBbMSAvKiBDSElMRFJFTiAqL106ICJjaGlsZHJlbiIsDQogIFsyIC8qIENMQVNTICovXTogImNsYXNzIiwNCiAgWzMgLyogU1RZTEUgKi9dOiAic3R5bGUiLA0KICBbNCAvKiBBVFRSSUJVVEUgKi9dOiAiYXR0cmlidXRlIg0KfTsNCmZ1bmN0aW9uIGlzTWlzbWF0Y2hBbGxvd2VkKGVsLCBhbGxvd2VkVHlwZSkgew0KICBpZiAoYWxsb3dlZFR5cGUgPT09IDAgLyogVEVYVCAqLyB8fCBhbGxvd2VkVHlwZSA9PT0gMSAvKiBDSElMRFJFTiAqLykgew0KICAgIHdoaWxlIChlbCAmJiAhZWwuaGFzQXR0cmlidXRlKGFsbG93TWlzbWF0Y2hBdHRyKSkgew0KICAgICAgZWwgPSBlbC5wYXJlbnRFbGVtZW50Ow0KICAgIH0NCiAgfQ0KICBjb25zdCBhbGxvd2VkQXR0ciA9IGVsICYmIGVsLmdldEF0dHJpYnV0ZShhbGxvd01pc21hdGNoQXR0cik7DQogIGlmIChhbGxvd2VkQXR0ciA9PSBudWxsKSB7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9IGVsc2UgaWYgKGFsbG93ZWRBdHRyID09PSAiIikgew0KICAgIHJldHVybiB0cnVlOw0KICB9IGVsc2Ugew0KICAgIGNvbnN0IGxpc3QgPSBhbGxvd2VkQXR0ci5zcGxpdCgiLCIpOw0KICAgIGlmIChhbGxvd2VkVHlwZSA9PT0gMCAvKiBURVhUICovICYmIGxpc3QuaW5jbHVkZXMoImNoaWxkcmVuIikpIHsNCiAgICAgIHJldHVybiB0cnVlOw0KICAgIH0NCiAgICByZXR1cm4gbGlzdC5pbmNsdWRlcyhNaXNtYXRjaFR5cGVTdHJpbmdbYWxsb3dlZFR5cGVdKTsNCiAgfQ0KfQ0KDQpjb25zdCByZXF1ZXN0SWRsZUNhbGxiYWNrID0gZ2V0R2xvYmFsVGhpcygpLnJlcXVlc3RJZGxlQ2FsbGJhY2sgfHwgKChjYikgPT4gc2V0VGltZW91dChjYiwgMSkpOw0KY29uc3QgY2FuY2VsSWRsZUNhbGxiYWNrID0gZ2V0R2xvYmFsVGhpcygpLmNhbmNlbElkbGVDYWxsYmFjayB8fCAoKGlkKSA9PiBjbGVhclRpbWVvdXQoaWQpKTsNCmNvbnN0IGh5ZHJhdGVPbklkbGUgPSAodGltZW91dCA9IDFlNCkgPT4gKGh5ZHJhdGUpID0+IHsNCiAgY29uc3QgaWQgPSByZXF1ZXN0SWRsZUNhbGxiYWNrKGh5ZHJhdGUsIHsgdGltZW91dCB9KTsNCiAgcmV0dXJuICgpID0+IGNhbmNlbElkbGVDYWxsYmFjayhpZCk7DQp9Ow0KZnVuY3Rpb24gZWxlbWVudElzVmlzaWJsZUluVmlld3BvcnQoZWwpIHsNCiAgY29uc3QgeyB0b3AsIGxlZnQsIGJvdHRvbSwgcmlnaHQgfSA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOw0KICBjb25zdCB7IGlubmVySGVpZ2h0LCBpbm5lcldpZHRoIH0gPSB3aW5kb3c7DQogIHJldHVybiAodG9wID4gMCAmJiB0b3AgPCBpbm5lckhlaWdodCB8fCBib3R0b20gPiAwICYmIGJvdHRvbSA8IGlubmVySGVpZ2h0KSAmJiAobGVmdCA+IDAgJiYgbGVmdCA8IGlubmVyV2lkdGggfHwgcmlnaHQgPiAwICYmIHJpZ2h0IDwgaW5uZXJXaWR0aCk7DQp9DQpjb25zdCBoeWRyYXRlT25WaXNpYmxlID0gKG9wdHMpID0+IChoeWRyYXRlLCBmb3JFYWNoKSA9PiB7DQogIGNvbnN0IG9iID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKChlbnRyaWVzKSA9PiB7DQogICAgZm9yIChjb25zdCBlIG9mIGVudHJpZXMpIHsNCiAgICAgIGlmICghZS5pc0ludGVyc2VjdGluZykgY29udGludWU7DQogICAgICBvYi5kaXNjb25uZWN0KCk7DQogICAgICBoeWRyYXRlKCk7DQogICAgICBicmVhazsNCiAgICB9DQogIH0sIG9wdHMpOw0KICBmb3JFYWNoKChlbCkgPT4gew0KICAgIGlmICghKGVsIGluc3RhbmNlb2YgRWxlbWVudCkpIHJldHVybjsNCiAgICBpZiAoZWxlbWVudElzVmlzaWJsZUluVmlld3BvcnQoZWwpKSB7DQogICAgICBoeWRyYXRlKCk7DQogICAgICBvYi5kaXNjb25uZWN0KCk7DQogICAgICByZXR1cm4gZmFsc2U7DQogICAgfQ0KICAgIG9iLm9ic2VydmUoZWwpOw0KICB9KTsNCiAgcmV0dXJuICgpID0+IG9iLmRpc2Nvbm5lY3QoKTsNCn07DQpjb25zdCBoeWRyYXRlT25NZWRpYVF1ZXJ5ID0gKHF1ZXJ5KSA9PiAoaHlkcmF0ZSkgPT4gew0KICBpZiAocXVlcnkpIHsNCiAgICBjb25zdCBtcWwgPSBtYXRjaE1lZGlhKHF1ZXJ5KTsNCiAgICBpZiAobXFsLm1hdGNoZXMpIHsNCiAgICAgIGh5ZHJhdGUoKTsNCiAgICB9IGVsc2Ugew0KICAgICAgbXFsLmFkZEV2ZW50TGlzdGVuZXIoImNoYW5nZSIsIGh5ZHJhdGUsIHsgb25jZTogdHJ1ZSB9KTsNCiAgICAgIHJldHVybiAoKSA9PiBtcWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigiY2hhbmdlIiwgaHlkcmF0ZSk7DQogICAgfQ0KICB9DQp9Ow0KY29uc3QgaHlkcmF0ZU9uSW50ZXJhY3Rpb24gPSAoaW50ZXJhY3Rpb25zID0gW10pID0+IChoeWRyYXRlLCBmb3JFYWNoKSA9PiB7DQogIGlmIChpc1N0cmluZyhpbnRlcmFjdGlvbnMpKSBpbnRlcmFjdGlvbnMgPSBbaW50ZXJhY3Rpb25zXTsNCiAgbGV0IGhhc0h5ZHJhdGVkID0gZmFsc2U7DQogIGNvbnN0IGRvSHlkcmF0ZSA9IChlKSA9PiB7DQogICAgaWYgKCFoYXNIeWRyYXRlZCkgew0KICAgICAgaGFzSHlkcmF0ZWQgPSB0cnVlOw0KICAgICAgdGVhcmRvd24oKTsNCiAgICAgIGh5ZHJhdGUoKTsNCiAgICAgIGUudGFyZ2V0LmRpc3BhdGNoRXZlbnQobmV3IGUuY29uc3RydWN0b3IoZS50eXBlLCBlKSk7DQogICAgfQ0KICB9Ow0KICBjb25zdCB0ZWFyZG93biA9ICgpID0+IHsNCiAgICBmb3JFYWNoKChlbCkgPT4gew0KICAgICAgZm9yIChjb25zdCBpIG9mIGludGVyYWN0aW9ucykgew0KICAgICAgICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKGksIGRvSHlkcmF0ZSk7DQogICAgICB9DQogICAgfSk7DQogIH07DQogIGZvckVhY2goKGVsKSA9PiB7DQogICAgZm9yIChjb25zdCBpIG9mIGludGVyYWN0aW9ucykgew0KICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcihpLCBkb0h5ZHJhdGUsIHsgb25jZTogdHJ1ZSB9KTsNCiAgICB9DQogIH0pOw0KICByZXR1cm4gdGVhcmRvd247DQp9Ow0KZnVuY3Rpb24gZm9yRWFjaEVsZW1lbnQobm9kZSwgY2IpIHsNCiAgaWYgKGlzQ29tbWVudChub2RlKSAmJiBub2RlLmRhdGEgPT09ICJbIikgew0KICAgIGxldCBkZXB0aCA9IDE7DQogICAgbGV0IG5leHQgPSBub2RlLm5leHRTaWJsaW5nOw0KICAgIHdoaWxlIChuZXh0KSB7DQogICAgICBpZiAobmV4dC5ub2RlVHlwZSA9PT0gMSkgew0KICAgICAgICBjb25zdCByZXN1bHQgPSBjYihuZXh0KTsNCiAgICAgICAgaWYgKHJlc3VsdCA9PT0gZmFsc2UpIHsNCiAgICAgICAgICBicmVhazsNCiAgICAgICAgfQ0KICAgICAgfSBlbHNlIGlmIChpc0NvbW1lbnQobmV4dCkpIHsNCiAgICAgICAgaWYgKG5leHQuZGF0YSA9PT0gIl0iKSB7DQogICAgICAgICAgaWYgKC0tZGVwdGggPT09IDApIGJyZWFrOw0KICAgICAgICB9IGVsc2UgaWYgKG5leHQuZGF0YSA9PT0gIlsiKSB7DQogICAgICAgICAgZGVwdGgrKzsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgbmV4dCA9IG5leHQubmV4dFNpYmxpbmc7DQogICAgfQ0KICB9IGVsc2Ugew0KICAgIGNiKG5vZGUpOw0KICB9DQp9DQoNCmNvbnN0IGlzQXN5bmNXcmFwcGVyID0gKGkpID0+ICEhaS50eXBlLl9fYXN5bmNMb2FkZXI7DQovKiEgI19fTk9fU0lERV9FRkZFQ1RTX18gKi8NCi8vIEBfX05PX1NJREVfRUZGRUNUU19fDQpmdW5jdGlvbiBkZWZpbmVBc3luY0NvbXBvbmVudChzb3VyY2UpIHsNCiAgaWYgKGlzRnVuY3Rpb24oc291cmNlKSkgew0KICAgIHNvdXJjZSA9IHsgbG9hZGVyOiBzb3VyY2UgfTsNCiAgfQ0KICBjb25zdCB7DQogICAgbG9hZGVyLA0KICAgIGxvYWRpbmdDb21wb25lbnQsDQogICAgZXJyb3JDb21wb25lbnQsDQogICAgZGVsYXkgPSAyMDAsDQogICAgaHlkcmF0ZTogaHlkcmF0ZVN0cmF0ZWd5LA0KICAgIHRpbWVvdXQsDQogICAgLy8gdW5kZWZpbmVkID0gbmV2ZXIgdGltZXMgb3V0DQogICAgc3VzcGVuc2libGUgPSB0cnVlLA0KICAgIG9uRXJyb3I6IHVzZXJPbkVycm9yDQogIH0gPSBzb3VyY2U7DQogIGxldCBwZW5kaW5nUmVxdWVzdCA9IG51bGw7DQogIGxldCByZXNvbHZlZENvbXA7DQogIGxldCByZXRyaWVzID0gMDsNCiAgY29uc3QgcmV0cnkgPSAoKSA9PiB7DQogICAgcmV0cmllcysrOw0KICAgIHBlbmRpbmdSZXF1ZXN0ID0gbnVsbDsNCiAgICByZXR1cm4gbG9hZCgpOw0KICB9Ow0KICBjb25zdCBsb2FkID0gKCkgPT4gew0KICAgIGxldCB0aGlzUmVxdWVzdDsNCiAgICByZXR1cm4gcGVuZGluZ1JlcXVlc3QgfHwgKHRoaXNSZXF1ZXN0ID0gcGVuZGluZ1JlcXVlc3QgPSBsb2FkZXIoKS5jYXRjaCgoZXJyKSA9PiB7DQogICAgICBlcnIgPSBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyKSk7DQogICAgICBpZiAodXNlck9uRXJyb3IpIHsNCiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHsNCiAgICAgICAgICBjb25zdCB1c2VyUmV0cnkgPSAoKSA9PiByZXNvbHZlKHJldHJ5KCkpOw0KICAgICAgICAgIGNvbnN0IHVzZXJGYWlsID0gKCkgPT4gcmVqZWN0KGVycik7DQogICAgICAgICAgdXNlck9uRXJyb3IoZXJyLCB1c2VyUmV0cnksIHVzZXJGYWlsLCByZXRyaWVzICsgMSk7DQogICAgICAgIH0pOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgdGhyb3cgZXJyOw0KICAgICAgfQ0KICAgIH0pLnRoZW4oKGNvbXApID0+IHsNCiAgICAgIGlmICh0aGlzUmVxdWVzdCAhPT0gcGVuZGluZ1JlcXVlc3QgJiYgcGVuZGluZ1JlcXVlc3QpIHsNCiAgICAgICAgcmV0dXJuIHBlbmRpbmdSZXF1ZXN0Ow0KICAgICAgfQ0KICAgICAgaWYgKCFjb21wKSB7DQogICAgICAgIHdhcm4kMSgNCiAgICAgICAgICBgQXN5bmMgY29tcG9uZW50IGxvYWRlciByZXNvbHZlZCB0byB1bmRlZmluZWQuIElmIHlvdSBhcmUgdXNpbmcgcmV0cnkoKSwgbWFrZSBzdXJlIHRvIHJldHVybiBpdHMgcmV0dXJuIHZhbHVlLmANCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICAgIGlmIChjb21wICYmIChjb21wLl9fZXNNb2R1bGUgfHwgY29tcFtTeW1ib2wudG9TdHJpbmdUYWddID09PSAiTW9kdWxlIikpIHsNCiAgICAgICAgY29tcCA9IGNvbXAuZGVmYXVsdDsNCiAgICAgIH0NCiAgICAgIGlmIChjb21wICYmICFpc09iamVjdChjb21wKSAmJiAhaXNGdW5jdGlvbihjb21wKSkgew0KICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgYXN5bmMgY29tcG9uZW50IGxvYWQgcmVzdWx0OiAke2NvbXB9YCk7DQogICAgICB9DQogICAgICByZXNvbHZlZENvbXAgPSBjb21wOw0KICAgICAgcmV0dXJuIGNvbXA7DQogICAgfSkpOw0KICB9Ow0KICByZXR1cm4gZGVmaW5lQ29tcG9uZW50KHsNCiAgICBuYW1lOiAiQXN5bmNDb21wb25lbnRXcmFwcGVyIiwNCiAgICBfX2FzeW5jTG9hZGVyOiBsb2FkLA0KICAgIF9fYXN5bmNIeWRyYXRlKGVsLCBpbnN0YW5jZSwgaHlkcmF0ZSkgew0KICAgICAgbGV0IHBhdGNoZWQgPSBmYWxzZTsNCiAgICAgIGNvbnN0IGRvSHlkcmF0ZSA9IGh5ZHJhdGVTdHJhdGVneSA/ICgpID0+IHsNCiAgICAgICAgY29uc3QgcGVyZm9ybUh5ZHJhdGUgPSAoKSA9PiB7DQogICAgICAgICAgaWYgKHBhdGNoZWQpIHsNCiAgICAgICAgICAgIHdhcm4kMSgNCiAgICAgICAgICAgICAgYFNraXBwaW5nIGxhenkgaHlkcmF0aW9uIGZvciBjb21wb25lbnQgJyR7Z2V0Q29tcG9uZW50TmFtZShyZXNvbHZlZENvbXApfSc6IGl0IHdhcyB1cGRhdGVkIGJlZm9yZSBsYXp5IGh5ZHJhdGlvbiBwZXJmb3JtZWQuYA0KICAgICAgICAgICAgKTsNCiAgICAgICAgICAgIHJldHVybjsNCiAgICAgICAgICB9DQogICAgICAgICAgaHlkcmF0ZSgpOw0KICAgICAgICB9Ow0KICAgICAgICBjb25zdCB0ZWFyZG93biA9IGh5ZHJhdGVTdHJhdGVneSgNCiAgICAgICAgICBwZXJmb3JtSHlkcmF0ZSwNCiAgICAgICAgICAoY2IpID0+IGZvckVhY2hFbGVtZW50KGVsLCBjYikNCiAgICAgICAgKTsNCiAgICAgICAgaWYgKHRlYXJkb3duKSB7DQogICAgICAgICAgKGluc3RhbmNlLmJ1bSB8fCAoaW5zdGFuY2UuYnVtID0gW10pKS5wdXNoKHRlYXJkb3duKTsNCiAgICAgICAgfQ0KICAgICAgICAoaW5zdGFuY2UudSB8fCAoaW5zdGFuY2UudSA9IFtdKSkucHVzaCgoKSA9PiBwYXRjaGVkID0gdHJ1ZSk7DQogICAgICB9IDogaHlkcmF0ZTsNCiAgICAgIGlmIChyZXNvbHZlZENvbXApIHsNCiAgICAgICAgZG9IeWRyYXRlKCk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBsb2FkKCkudGhlbigoKSA9PiAhaW5zdGFuY2UuaXNVbm1vdW50ZWQgJiYgZG9IeWRyYXRlKCkpOw0KICAgICAgfQ0KICAgIH0sDQogICAgZ2V0IF9fYXN5bmNSZXNvbHZlZCgpIHsNCiAgICAgIHJldHVybiByZXNvbHZlZENvbXA7DQogICAgfSwNCiAgICBzZXR1cCgpIHsNCiAgICAgIGNvbnN0IGluc3RhbmNlID0gY3VycmVudEluc3RhbmNlOw0KICAgICAgbWFya0FzeW5jQm91bmRhcnkoaW5zdGFuY2UpOw0KICAgICAgaWYgKHJlc29sdmVkQ29tcCkgew0KICAgICAgICByZXR1cm4gKCkgPT4gY3JlYXRlSW5uZXJDb21wKHJlc29sdmVkQ29tcCwgaW5zdGFuY2UpOw0KICAgICAgfQ0KICAgICAgY29uc3Qgb25FcnJvciA9IChlcnIpID0+IHsNCiAgICAgICAgcGVuZGluZ1JlcXVlc3QgPSBudWxsOw0KICAgICAgICBoYW5kbGVFcnJvcigNCiAgICAgICAgICBlcnIsDQogICAgICAgICAgaW5zdGFuY2UsDQogICAgICAgICAgMTMsDQogICAgICAgICAgIWVycm9yQ29tcG9uZW50DQogICAgICAgICk7DQogICAgICB9Ow0KICAgICAgaWYgKHN1c3BlbnNpYmxlICYmIGluc3RhbmNlLnN1c3BlbnNlIHx8IGlzSW5TU1JDb21wb25lbnRTZXR1cCkgew0KICAgICAgICByZXR1cm4gbG9hZCgpLnRoZW4oKGNvbXApID0+IHsNCiAgICAgICAgICByZXR1cm4gKCkgPT4gY3JlYXRlSW5uZXJDb21wKGNvbXAsIGluc3RhbmNlKTsNCiAgICAgICAgfSkuY2F0Y2goKGVycikgPT4gew0KICAgICAgICAgIG9uRXJyb3IoZXJyKTsNCiAgICAgICAgICByZXR1cm4gKCkgPT4gZXJyb3JDb21wb25lbnQgPyBjcmVhdGVWTm9kZShlcnJvckNvbXBvbmVudCwgew0KICAgICAgICAgICAgZXJyb3I6IGVycg0KICAgICAgICAgIH0pIDogbnVsbDsNCiAgICAgICAgfSk7DQogICAgICB9DQogICAgICBjb25zdCBsb2FkZWQgPSByZWYoZmFsc2UpOw0KICAgICAgY29uc3QgZXJyb3IgPSByZWYoKTsNCiAgICAgIGNvbnN0IGRlbGF5ZWQgPSByZWYoISFkZWxheSk7DQogICAgICBpZiAoZGVsYXkpIHsNCiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7DQogICAgICAgICAgZGVsYXllZC52YWx1ZSA9IGZhbHNlOw0KICAgICAgICB9LCBkZWxheSk7DQogICAgICB9DQogICAgICBpZiAodGltZW91dCAhPSBudWxsKSB7DQogICAgICAgIHNldFRpbWVvdXQoKCkgPT4gew0KICAgICAgICAgIGlmICghbG9hZGVkLnZhbHVlICYmICFlcnJvci52YWx1ZSkgew0KICAgICAgICAgICAgY29uc3QgZXJyID0gbmV3IEVycm9yKA0KICAgICAgICAgICAgICBgQXN5bmMgY29tcG9uZW50IHRpbWVkIG91dCBhZnRlciAke3RpbWVvdXR9bXMuYA0KICAgICAgICAgICAgKTsNCiAgICAgICAgICAgIG9uRXJyb3IoZXJyKTsNCiAgICAgICAgICAgIGVycm9yLnZhbHVlID0gZXJyOw0KICAgICAgICAgIH0NCiAgICAgICAgfSwgdGltZW91dCk7DQogICAgICB9DQogICAgICBsb2FkKCkudGhlbigoKSA9PiB7DQogICAgICAgIGxvYWRlZC52YWx1ZSA9IHRydWU7DQogICAgICAgIGlmIChpbnN0YW5jZS5wYXJlbnQgJiYgaXNLZWVwQWxpdmUoaW5zdGFuY2UucGFyZW50LnZub2RlKSkgew0KICAgICAgICAgIGluc3RhbmNlLnBhcmVudC51cGRhdGUoKTsNCiAgICAgICAgfQ0KICAgICAgfSkuY2F0Y2goKGVycikgPT4gew0KICAgICAgICBvbkVycm9yKGVycik7DQogICAgICAgIGVycm9yLnZhbHVlID0gZXJyOw0KICAgICAgfSk7DQogICAgICByZXR1cm4gKCkgPT4gew0KICAgICAgICBpZiAobG9hZGVkLnZhbHVlICYmIHJlc29sdmVkQ29tcCkgew0KICAgICAgICAgIHJldHVybiBjcmVhdGVJbm5lckNvbXAocmVzb2x2ZWRDb21wLCBpbnN0YW5jZSk7DQogICAgICAgIH0gZWxzZSBpZiAoZXJyb3IudmFsdWUgJiYgZXJyb3JDb21wb25lbnQpIHsNCiAgICAgICAgICByZXR1cm4gY3JlYXRlVk5vZGUoZXJyb3JDb21wb25lbnQsIHsNCiAgICAgICAgICAgIGVycm9yOiBlcnJvci52YWx1ZQ0KICAgICAgICAgIH0pOw0KICAgICAgICB9IGVsc2UgaWYgKGxvYWRpbmdDb21wb25lbnQgJiYgIWRlbGF5ZWQudmFsdWUpIHsNCiAgICAgICAgICByZXR1cm4gY3JlYXRlVk5vZGUobG9hZGluZ0NvbXBvbmVudCk7DQogICAgICAgIH0NCiAgICAgIH07DQogICAgfQ0KICB9KTsNCn0NCmZ1bmN0aW9uIGNyZWF0ZUlubmVyQ29tcChjb21wLCBwYXJlbnQpIHsNCiAgY29uc3QgeyByZWY6IHJlZjIsIHByb3BzLCBjaGlsZHJlbiwgY2UgfSA9IHBhcmVudC52bm9kZTsNCiAgY29uc3Qgdm5vZGUgPSBjcmVhdGVWTm9kZShjb21wLCBwcm9wcywgY2hpbGRyZW4pOw0KICB2bm9kZS5yZWYgPSByZWYyOw0KICB2bm9kZS5jZSA9IGNlOw0KICBkZWxldGUgcGFyZW50LnZub2RlLmNlOw0KICByZXR1cm4gdm5vZGU7DQp9DQoNCmNvbnN0IGlzS2VlcEFsaXZlID0gKHZub2RlKSA9PiB2bm9kZS50eXBlLl9faXNLZWVwQWxpdmU7DQpjb25zdCBLZWVwQWxpdmVJbXBsID0gew0KICBuYW1lOiBgS2VlcEFsaXZlYCwNCiAgLy8gTWFya2VyIGZvciBzcGVjaWFsIGhhbmRsaW5nIGluc2lkZSB0aGUgcmVuZGVyZXIuIFdlIGFyZSBub3QgdXNpbmcgYSA9PT0NCiAgLy8gY2hlY2sgZGlyZWN0bHkgb24gS2VlcEFsaXZlIGluIHRoZSByZW5kZXJlciwgYmVjYXVzZSBpbXBvcnRpbmcgaXQgZGlyZWN0bHkNCiAgLy8gd291bGQgcHJldmVudCBpdCBmcm9tIGJlaW5nIHRyZWUtc2hha2VuLg0KICBfX2lzS2VlcEFsaXZlOiB0cnVlLA0KICBwcm9wczogew0KICAgIGluY2x1ZGU6IFtTdHJpbmcsIFJlZ0V4cCwgQXJyYXldLA0KICAgIGV4Y2x1ZGU6IFtTdHJpbmcsIFJlZ0V4cCwgQXJyYXldLA0KICAgIG1heDogW1N0cmluZywgTnVtYmVyXQ0KICB9LA0KICBzZXR1cChwcm9wcywgeyBzbG90cyB9KSB7DQogICAgY29uc3QgaW5zdGFuY2UgPSBnZXRDdXJyZW50SW5zdGFuY2UoKTsNCiAgICBjb25zdCBzaGFyZWRDb250ZXh0ID0gaW5zdGFuY2UuY3R4Ow0KICAgIGlmICghc2hhcmVkQ29udGV4dC5yZW5kZXJlcikgew0KICAgICAgcmV0dXJuICgpID0+IHsNCiAgICAgICAgY29uc3QgY2hpbGRyZW4gPSBzbG90cy5kZWZhdWx0ICYmIHNsb3RzLmRlZmF1bHQoKTsNCiAgICAgICAgcmV0dXJuIGNoaWxkcmVuICYmIGNoaWxkcmVuLmxlbmd0aCA9PT0gMSA/IGNoaWxkcmVuWzBdIDogY2hpbGRyZW47DQogICAgICB9Ow0KICAgIH0NCiAgICBjb25zdCBjYWNoZSA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7DQogICAgY29uc3Qga2V5cyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KCk7DQogICAgbGV0IGN1cnJlbnQgPSBudWxsOw0KICAgIHsNCiAgICAgIGluc3RhbmNlLl9fdl9jYWNoZSA9IGNhY2hlOw0KICAgIH0NCiAgICBjb25zdCBwYXJlbnRTdXNwZW5zZSA9IGluc3RhbmNlLnN1c3BlbnNlOw0KICAgIGNvbnN0IHsNCiAgICAgIHJlbmRlcmVyOiB7DQogICAgICAgIHA6IHBhdGNoLA0KICAgICAgICBtOiBtb3ZlLA0KICAgICAgICB1bTogX3VubW91bnQsDQogICAgICAgIG86IHsgY3JlYXRlRWxlbWVudCB9DQogICAgICB9DQogICAgfSA9IHNoYXJlZENvbnRleHQ7DQogICAgY29uc3Qgc3RvcmFnZUNvbnRhaW5lciA9IGNyZWF0ZUVsZW1lbnQoImRpdiIpOw0KICAgIHNoYXJlZENvbnRleHQuYWN0aXZhdGUgPSAodm5vZGUsIGNvbnRhaW5lciwgYW5jaG9yLCBuYW1lc3BhY2UsIG9wdGltaXplZCkgPT4gew0KICAgICAgY29uc3QgaW5zdGFuY2UyID0gdm5vZGUuY29tcG9uZW50Ow0KICAgICAgbW92ZSh2bm9kZSwgY29udGFpbmVyLCBhbmNob3IsIDAsIHBhcmVudFN1c3BlbnNlKTsNCiAgICAgIHBhdGNoKA0KICAgICAgICBpbnN0YW5jZTIudm5vZGUsDQogICAgICAgIHZub2RlLA0KICAgICAgICBjb250YWluZXIsDQogICAgICAgIGFuY2hvciwNCiAgICAgICAgaW5zdGFuY2UyLA0KICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICB2bm9kZS5zbG90U2NvcGVJZHMsDQogICAgICAgIG9wdGltaXplZA0KICAgICAgKTsNCiAgICAgIHF1ZXVlUG9zdFJlbmRlckVmZmVjdCgoKSA9PiB7DQogICAgICAgIGluc3RhbmNlMi5pc0RlYWN0aXZhdGVkID0gZmFsc2U7DQogICAgICAgIGlmIChpbnN0YW5jZTIuYSkgew0KICAgICAgICAgIGludm9rZUFycmF5Rm5zKGluc3RhbmNlMi5hKTsNCiAgICAgICAgfQ0KICAgICAgICBjb25zdCB2bm9kZUhvb2sgPSB2bm9kZS5wcm9wcyAmJiB2bm9kZS5wcm9wcy5vblZub2RlTW91bnRlZDsNCiAgICAgICAgaWYgKHZub2RlSG9vaykgew0KICAgICAgICAgIGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIGluc3RhbmNlMi5wYXJlbnQsIHZub2RlKTsNCiAgICAgICAgfQ0KICAgICAgfSwgcGFyZW50U3VzcGVuc2UpOw0KICAgICAgew0KICAgICAgICBkZXZ0b29sc0NvbXBvbmVudEFkZGVkKGluc3RhbmNlMik7DQogICAgICB9DQogICAgfTsNCiAgICBzaGFyZWRDb250ZXh0LmRlYWN0aXZhdGUgPSAodm5vZGUpID0+IHsNCiAgICAgIGNvbnN0IGluc3RhbmNlMiA9IHZub2RlLmNvbXBvbmVudDsNCiAgICAgIGludmFsaWRhdGVNb3VudChpbnN0YW5jZTIubSk7DQogICAgICBpbnZhbGlkYXRlTW91bnQoaW5zdGFuY2UyLmEpOw0KICAgICAgbW92ZSh2bm9kZSwgc3RvcmFnZUNvbnRhaW5lciwgbnVsbCwgMSwgcGFyZW50U3VzcGVuc2UpOw0KICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KCgpID0+IHsNCiAgICAgICAgaWYgKGluc3RhbmNlMi5kYSkgew0KICAgICAgICAgIGludm9rZUFycmF5Rm5zKGluc3RhbmNlMi5kYSk7DQogICAgICAgIH0NCiAgICAgICAgY29uc3Qgdm5vZGVIb29rID0gdm5vZGUucHJvcHMgJiYgdm5vZGUucHJvcHMub25Wbm9kZVVubW91bnRlZDsNCiAgICAgICAgaWYgKHZub2RlSG9vaykgew0KICAgICAgICAgIGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIGluc3RhbmNlMi5wYXJlbnQsIHZub2RlKTsNCiAgICAgICAgfQ0KICAgICAgICBpbnN0YW5jZTIuaXNEZWFjdGl2YXRlZCA9IHRydWU7DQogICAgICB9LCBwYXJlbnRTdXNwZW5zZSk7DQogICAgICB7DQogICAgICAgIGRldnRvb2xzQ29tcG9uZW50QWRkZWQoaW5zdGFuY2UyKTsNCiAgICAgIH0NCiAgICAgIHsNCiAgICAgICAgaW5zdGFuY2UyLl9fa2VlcEFsaXZlU3RvcmFnZUNvbnRhaW5lciA9IHN0b3JhZ2VDb250YWluZXI7DQogICAgICB9DQogICAgfTsNCiAgICBmdW5jdGlvbiB1bm1vdW50KHZub2RlKSB7DQogICAgICByZXNldFNoYXBlRmxhZyh2bm9kZSk7DQogICAgICBfdW5tb3VudCh2bm9kZSwgaW5zdGFuY2UsIHBhcmVudFN1c3BlbnNlLCB0cnVlKTsNCiAgICB9DQogICAgZnVuY3Rpb24gcHJ1bmVDYWNoZShmaWx0ZXIpIHsNCiAgICAgIGNhY2hlLmZvckVhY2goKHZub2RlLCBrZXkpID0+IHsNCiAgICAgICAgY29uc3QgbmFtZSA9IGdldENvbXBvbmVudE5hbWUodm5vZGUudHlwZSk7DQogICAgICAgIGlmIChuYW1lICYmICFmaWx0ZXIobmFtZSkpIHsNCiAgICAgICAgICBwcnVuZUNhY2hlRW50cnkoa2V5KTsNCiAgICAgICAgfQ0KICAgICAgfSk7DQogICAgfQ0KICAgIGZ1bmN0aW9uIHBydW5lQ2FjaGVFbnRyeShrZXkpIHsNCiAgICAgIGNvbnN0IGNhY2hlZCA9IGNhY2hlLmdldChrZXkpOw0KICAgICAgaWYgKGNhY2hlZCAmJiAoIWN1cnJlbnQgfHwgIWlzU2FtZVZOb2RlVHlwZShjYWNoZWQsIGN1cnJlbnQpKSkgew0KICAgICAgICB1bm1vdW50KGNhY2hlZCk7DQogICAgICB9IGVsc2UgaWYgKGN1cnJlbnQpIHsNCiAgICAgICAgcmVzZXRTaGFwZUZsYWcoY3VycmVudCk7DQogICAgICB9DQogICAgICBjYWNoZS5kZWxldGUoa2V5KTsNCiAgICAgIGtleXMuZGVsZXRlKGtleSk7DQogICAgfQ0KICAgIHdhdGNoKA0KICAgICAgKCkgPT4gW3Byb3BzLmluY2x1ZGUsIHByb3BzLmV4Y2x1ZGVdLA0KICAgICAgKFtpbmNsdWRlLCBleGNsdWRlXSkgPT4gew0KICAgICAgICBpbmNsdWRlICYmIHBydW5lQ2FjaGUoKG5hbWUpID0+IG1hdGNoZXMoaW5jbHVkZSwgbmFtZSkpOw0KICAgICAgICBleGNsdWRlICYmIHBydW5lQ2FjaGUoKG5hbWUpID0+ICFtYXRjaGVzKGV4Y2x1ZGUsIG5hbWUpKTsNCiAgICAgIH0sDQogICAgICAvLyBwcnVuZSBwb3N0LXJlbmRlciBhZnRlciBgY3VycmVudGAgaGFzIGJlZW4gdXBkYXRlZA0KICAgICAgeyBmbHVzaDogInBvc3QiLCBkZWVwOiB0cnVlIH0NCiAgICApOw0KICAgIGxldCBwZW5kaW5nQ2FjaGVLZXkgPSBudWxsOw0KICAgIGNvbnN0IGNhY2hlU3VidHJlZSA9ICgpID0+IHsNCiAgICAgIGlmIChwZW5kaW5nQ2FjaGVLZXkgIT0gbnVsbCkgew0KICAgICAgICBpZiAoaXNTdXNwZW5zZShpbnN0YW5jZS5zdWJUcmVlLnR5cGUpKSB7DQogICAgICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KCgpID0+IHsNCiAgICAgICAgICAgIGNhY2hlLnNldChwZW5kaW5nQ2FjaGVLZXksIGdldElubmVyQ2hpbGQoaW5zdGFuY2Uuc3ViVHJlZSkpOw0KICAgICAgICAgIH0sIGluc3RhbmNlLnN1YlRyZWUuc3VzcGVuc2UpOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIGNhY2hlLnNldChwZW5kaW5nQ2FjaGVLZXksIGdldElubmVyQ2hpbGQoaW5zdGFuY2Uuc3ViVHJlZSkpOw0KICAgICAgICB9DQogICAgICB9DQogICAgfTsNCiAgICBvbk1vdW50ZWQoY2FjaGVTdWJ0cmVlKTsNCiAgICBvblVwZGF0ZWQoY2FjaGVTdWJ0cmVlKTsNCiAgICBvbkJlZm9yZVVubW91bnQoKCkgPT4gew0KICAgICAgY2FjaGUuZm9yRWFjaCgoY2FjaGVkKSA9PiB7DQogICAgICAgIGNvbnN0IHsgc3ViVHJlZSwgc3VzcGVuc2UgfSA9IGluc3RhbmNlOw0KICAgICAgICBjb25zdCB2bm9kZSA9IGdldElubmVyQ2hpbGQoc3ViVHJlZSk7DQogICAgICAgIGlmIChjYWNoZWQudHlwZSA9PT0gdm5vZGUudHlwZSAmJiBjYWNoZWQua2V5ID09PSB2bm9kZS5rZXkpIHsNCiAgICAgICAgICByZXNldFNoYXBlRmxhZyh2bm9kZSk7DQogICAgICAgICAgY29uc3QgZGEgPSB2bm9kZS5jb21wb25lbnQuZGE7DQogICAgICAgICAgZGEgJiYgcXVldWVQb3N0UmVuZGVyRWZmZWN0KGRhLCBzdXNwZW5zZSk7DQogICAgICAgICAgcmV0dXJuOw0KICAgICAgICB9DQogICAgICAgIHVubW91bnQoY2FjaGVkKTsNCiAgICAgIH0pOw0KICAgIH0pOw0KICAgIHJldHVybiAoKSA9PiB7DQogICAgICBwZW5kaW5nQ2FjaGVLZXkgPSBudWxsOw0KICAgICAgaWYgKCFzbG90cy5kZWZhdWx0KSB7DQogICAgICAgIHJldHVybiBjdXJyZW50ID0gbnVsbDsNCiAgICAgIH0NCiAgICAgIGNvbnN0IGNoaWxkcmVuID0gc2xvdHMuZGVmYXVsdCgpOw0KICAgICAgY29uc3QgcmF3Vk5vZGUgPSBjaGlsZHJlblswXTsNCiAgICAgIGlmIChjaGlsZHJlbi5sZW5ndGggPiAxKSB7DQogICAgICAgIHsNCiAgICAgICAgICB3YXJuJDEoYEtlZXBBbGl2ZSBzaG91bGQgY29udGFpbiBleGFjdGx5IG9uZSBjb21wb25lbnQgY2hpbGQuYCk7DQogICAgICAgIH0NCiAgICAgICAgY3VycmVudCA9IG51bGw7DQogICAgICAgIHJldHVybiBjaGlsZHJlbjsNCiAgICAgIH0gZWxzZSBpZiAoIWlzVk5vZGUocmF3Vk5vZGUpIHx8ICEocmF3Vk5vZGUuc2hhcGVGbGFnICYgNCkgJiYgIShyYXdWTm9kZS5zaGFwZUZsYWcgJiAxMjgpKSB7DQogICAgICAgIGN1cnJlbnQgPSBudWxsOw0KICAgICAgICByZXR1cm4gcmF3Vk5vZGU7DQogICAgICB9DQogICAgICBsZXQgdm5vZGUgPSBnZXRJbm5lckNoaWxkKHJhd1ZOb2RlKTsNCiAgICAgIGlmICh2bm9kZS50eXBlID09PSBDb21tZW50KSB7DQogICAgICAgIGN1cnJlbnQgPSBudWxsOw0KICAgICAgICByZXR1cm4gdm5vZGU7DQogICAgICB9DQogICAgICBjb25zdCBjb21wID0gdm5vZGUudHlwZTsNCiAgICAgIGNvbnN0IG5hbWUgPSBnZXRDb21wb25lbnROYW1lKA0KICAgICAgICBpc0FzeW5jV3JhcHBlcih2bm9kZSkgPyB2bm9kZS50eXBlLl9fYXN5bmNSZXNvbHZlZCB8fCB7fSA6IGNvbXANCiAgICAgICk7DQogICAgICBjb25zdCB7IGluY2x1ZGUsIGV4Y2x1ZGUsIG1heCB9ID0gcHJvcHM7DQogICAgICBpZiAoaW5jbHVkZSAmJiAoIW5hbWUgfHwgIW1hdGNoZXMoaW5jbHVkZSwgbmFtZSkpIHx8IGV4Y2x1ZGUgJiYgbmFtZSAmJiBtYXRjaGVzKGV4Y2x1ZGUsIG5hbWUpKSB7DQogICAgICAgIHZub2RlLnNoYXBlRmxhZyAmPSAtMjU3Ow0KICAgICAgICBjdXJyZW50ID0gdm5vZGU7DQogICAgICAgIHJldHVybiByYXdWTm9kZTsNCiAgICAgIH0NCiAgICAgIGNvbnN0IGtleSA9IHZub2RlLmtleSA9PSBudWxsID8gY29tcCA6IHZub2RlLmtleTsNCiAgICAgIGNvbnN0IGNhY2hlZFZOb2RlID0gY2FjaGUuZ2V0KGtleSk7DQogICAgICBpZiAodm5vZGUuZWwpIHsNCiAgICAgICAgdm5vZGUgPSBjbG9uZVZOb2RlKHZub2RlKTsNCiAgICAgICAgaWYgKHJhd1ZOb2RlLnNoYXBlRmxhZyAmIDEyOCkgew0KICAgICAgICAgIHJhd1ZOb2RlLnNzQ29udGVudCA9IHZub2RlOw0KICAgICAgICB9DQogICAgICB9DQogICAgICBwZW5kaW5nQ2FjaGVLZXkgPSBrZXk7DQogICAgICBpZiAoY2FjaGVkVk5vZGUpIHsNCiAgICAgICAgdm5vZGUuZWwgPSBjYWNoZWRWTm9kZS5lbDsNCiAgICAgICAgdm5vZGUuY29tcG9uZW50ID0gY2FjaGVkVk5vZGUuY29tcG9uZW50Ow0KICAgICAgICBpZiAodm5vZGUudHJhbnNpdGlvbikgew0KICAgICAgICAgIHNldFRyYW5zaXRpb25Ib29rcyh2bm9kZSwgdm5vZGUudHJhbnNpdGlvbik7DQogICAgICAgIH0NCiAgICAgICAgdm5vZGUuc2hhcGVGbGFnIHw9IDUxMjsNCiAgICAgICAga2V5cy5kZWxldGUoa2V5KTsNCiAgICAgICAga2V5cy5hZGQoa2V5KTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGtleXMuYWRkKGtleSk7DQogICAgICAgIGlmIChtYXggJiYga2V5cy5zaXplID4gcGFyc2VJbnQobWF4LCAxMCkpIHsNCiAgICAgICAgICBwcnVuZUNhY2hlRW50cnkoa2V5cy52YWx1ZXMoKS5uZXh0KCkudmFsdWUpOw0KICAgICAgICB9DQogICAgICB9DQogICAgICB2bm9kZS5zaGFwZUZsYWcgfD0gMjU2Ow0KICAgICAgY3VycmVudCA9IHZub2RlOw0KICAgICAgcmV0dXJuIGlzU3VzcGVuc2UocmF3Vk5vZGUudHlwZSkgPyByYXdWTm9kZSA6IHZub2RlOw0KICAgIH07DQogIH0NCn07DQpjb25zdCBLZWVwQWxpdmUgPSBLZWVwQWxpdmVJbXBsOw0KZnVuY3Rpb24gbWF0Y2hlcyhwYXR0ZXJuLCBuYW1lKSB7DQogIGlmIChpc0FycmF5KHBhdHRlcm4pKSB7DQogICAgcmV0dXJuIHBhdHRlcm4uc29tZSgocCkgPT4gbWF0Y2hlcyhwLCBuYW1lKSk7DQogIH0gZWxzZSBpZiAoaXNTdHJpbmcocGF0dGVybikpIHsNCiAgICByZXR1cm4gcGF0dGVybi5zcGxpdCgiLCIpLmluY2x1ZGVzKG5hbWUpOw0KICB9IGVsc2UgaWYgKGlzUmVnRXhwKHBhdHRlcm4pKSB7DQogICAgcGF0dGVybi5sYXN0SW5kZXggPSAwOw0KICAgIHJldHVybiBwYXR0ZXJuLnRlc3QobmFtZSk7DQogIH0NCiAgcmV0dXJuIGZhbHNlOw0KfQ0KZnVuY3Rpb24gb25BY3RpdmF0ZWQoaG9vaywgdGFyZ2V0KSB7DQogIHJlZ2lzdGVyS2VlcEFsaXZlSG9vayhob29rLCAiYSIsIHRhcmdldCk7DQp9DQpmdW5jdGlvbiBvbkRlYWN0aXZhdGVkKGhvb2ssIHRhcmdldCkgew0KICByZWdpc3RlcktlZXBBbGl2ZUhvb2soaG9vaywgImRhIiwgdGFyZ2V0KTsNCn0NCmZ1bmN0aW9uIHJlZ2lzdGVyS2VlcEFsaXZlSG9vayhob29rLCB0eXBlLCB0YXJnZXQgPSBjdXJyZW50SW5zdGFuY2UpIHsNCiAgY29uc3Qgd3JhcHBlZEhvb2sgPSBob29rLl9fd2RjIHx8IChob29rLl9fd2RjID0gKCkgPT4gew0KICAgIGxldCBjdXJyZW50ID0gdGFyZ2V0Ow0KICAgIHdoaWxlIChjdXJyZW50KSB7DQogICAgICBpZiAoY3VycmVudC5pc0RlYWN0aXZhdGVkKSB7DQogICAgICAgIHJldHVybjsNCiAgICAgIH0NCiAgICAgIGN1cnJlbnQgPSBjdXJyZW50LnBhcmVudDsNCiAgICB9DQogICAgcmV0dXJuIGhvb2soKTsNCiAgfSk7DQogIGluamVjdEhvb2sodHlwZSwgd3JhcHBlZEhvb2ssIHRhcmdldCk7DQogIGlmICh0YXJnZXQpIHsNCiAgICBsZXQgY3VycmVudCA9IHRhcmdldC5wYXJlbnQ7DQogICAgd2hpbGUgKGN1cnJlbnQgJiYgY3VycmVudC5wYXJlbnQpIHsNCiAgICAgIGlmIChpc0tlZXBBbGl2ZShjdXJyZW50LnBhcmVudC52bm9kZSkpIHsNCiAgICAgICAgaW5qZWN0VG9LZWVwQWxpdmVSb290KHdyYXBwZWRIb29rLCB0eXBlLCB0YXJnZXQsIGN1cnJlbnQpOw0KICAgICAgfQ0KICAgICAgY3VycmVudCA9IGN1cnJlbnQucGFyZW50Ow0KICAgIH0NCiAgfQ0KfQ0KZnVuY3Rpb24gaW5qZWN0VG9LZWVwQWxpdmVSb290KGhvb2ssIHR5cGUsIHRhcmdldCwga2VlcEFsaXZlUm9vdCkgew0KICBjb25zdCBpbmplY3RlZCA9IGluamVjdEhvb2soDQogICAgdHlwZSwNCiAgICBob29rLA0KICAgIGtlZXBBbGl2ZVJvb3QsDQogICAgdHJ1ZQ0KICAgIC8qIHByZXBlbmQgKi8NCiAgKTsNCiAgb25Vbm1vdW50ZWQoKCkgPT4gew0KICAgIHJlbW92ZShrZWVwQWxpdmVSb290W3R5cGVdLCBpbmplY3RlZCk7DQogIH0sIHRhcmdldCk7DQp9DQpmdW5jdGlvbiByZXNldFNoYXBlRmxhZyh2bm9kZSkgew0KICB2bm9kZS5zaGFwZUZsYWcgJj0gLTI1NzsNCiAgdm5vZGUuc2hhcGVGbGFnICY9IC01MTM7DQp9DQpmdW5jdGlvbiBnZXRJbm5lckNoaWxkKHZub2RlKSB7DQogIHJldHVybiB2bm9kZS5zaGFwZUZsYWcgJiAxMjggPyB2bm9kZS5zc0NvbnRlbnQgOiB2bm9kZTsNCn0NCg0KZnVuY3Rpb24gaW5qZWN0SG9vayh0eXBlLCBob29rLCB0YXJnZXQgPSBjdXJyZW50SW5zdGFuY2UsIHByZXBlbmQgPSBmYWxzZSkgew0KICBpZiAodGFyZ2V0KSB7DQogICAgY29uc3QgaG9va3MgPSB0YXJnZXRbdHlwZV0gfHwgKHRhcmdldFt0eXBlXSA9IFtdKTsNCiAgICBjb25zdCB3cmFwcGVkSG9vayA9IGhvb2suX193ZWggfHwgKGhvb2suX193ZWggPSAoLi4uYXJncykgPT4gew0KICAgICAgcGF1c2VUcmFja2luZygpOw0KICAgICAgY29uc3QgcmVzZXQgPSBzZXRDdXJyZW50SW5zdGFuY2UodGFyZ2V0KTsNCiAgICAgIGNvbnN0IHJlcyA9IGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nKGhvb2ssIHRhcmdldCwgdHlwZSwgYXJncyk7DQogICAgICByZXNldCgpOw0KICAgICAgcmVzZXRUcmFja2luZygpOw0KICAgICAgcmV0dXJuIHJlczsNCiAgICB9KTsNCiAgICBpZiAocHJlcGVuZCkgew0KICAgICAgaG9va3MudW5zaGlmdCh3cmFwcGVkSG9vayk7DQogICAgfSBlbHNlIHsNCiAgICAgIGhvb2tzLnB1c2god3JhcHBlZEhvb2spOw0KICAgIH0NCiAgICByZXR1cm4gd3JhcHBlZEhvb2s7DQogIH0gZWxzZSB7DQogICAgY29uc3QgYXBpTmFtZSA9IHRvSGFuZGxlcktleShFcnJvclR5cGVTdHJpbmdzJDFbdHlwZV0ucmVwbGFjZSgvIGhvb2skLywgIiIpKTsNCiAgICB3YXJuJDEoDQogICAgICBgJHthcGlOYW1lfSBpcyBjYWxsZWQgd2hlbiB0aGVyZSBpcyBubyBhY3RpdmUgY29tcG9uZW50IGluc3RhbmNlIHRvIGJlIGFzc29jaWF0ZWQgd2l0aC4gTGlmZWN5Y2xlIGluamVjdGlvbiBBUElzIGNhbiBvbmx5IGJlIHVzZWQgZHVyaW5nIGV4ZWN1dGlvbiBvZiBzZXR1cCgpLmAgKyAoYCBJZiB5b3UgYXJlIHVzaW5nIGFzeW5jIHNldHVwKCksIG1ha2Ugc3VyZSB0byByZWdpc3RlciBsaWZlY3ljbGUgaG9va3MgYmVmb3JlIHRoZSBmaXJzdCBhd2FpdCBzdGF0ZW1lbnQuYCApDQogICAgKTsNCiAgfQ0KfQ0KY29uc3QgY3JlYXRlSG9vayA9IChsaWZlY3ljbGUpID0+IChob29rLCB0YXJnZXQgPSBjdXJyZW50SW5zdGFuY2UpID0+IHsNCiAgaWYgKCFpc0luU1NSQ29tcG9uZW50U2V0dXAgfHwgbGlmZWN5Y2xlID09PSAic3AiKSB7DQogICAgaW5qZWN0SG9vayhsaWZlY3ljbGUsICguLi5hcmdzKSA9PiBob29rKC4uLmFyZ3MpLCB0YXJnZXQpOw0KICB9DQp9Ow0KY29uc3Qgb25CZWZvcmVNb3VudCA9IGNyZWF0ZUhvb2soImJtIik7DQpjb25zdCBvbk1vdW50ZWQgPSBjcmVhdGVIb29rKCJtIik7DQpjb25zdCBvbkJlZm9yZVVwZGF0ZSA9IGNyZWF0ZUhvb2soDQogICJidSINCik7DQpjb25zdCBvblVwZGF0ZWQgPSBjcmVhdGVIb29rKCJ1Iik7DQpjb25zdCBvbkJlZm9yZVVubW91bnQgPSBjcmVhdGVIb29rKA0KICAiYnVtIg0KKTsNCmNvbnN0IG9uVW5tb3VudGVkID0gY3JlYXRlSG9vaygidW0iKTsNCmNvbnN0IG9uU2VydmVyUHJlZmV0Y2ggPSBjcmVhdGVIb29rKA0KICAic3AiDQopOw0KY29uc3Qgb25SZW5kZXJUcmlnZ2VyZWQgPSBjcmVhdGVIb29rKCJydGciKTsNCmNvbnN0IG9uUmVuZGVyVHJhY2tlZCA9IGNyZWF0ZUhvb2soInJ0YyIpOw0KZnVuY3Rpb24gb25FcnJvckNhcHR1cmVkKGhvb2ssIHRhcmdldCA9IGN1cnJlbnRJbnN0YW5jZSkgew0KICBpbmplY3RIb29rKCJlYyIsIGhvb2ssIHRhcmdldCk7DQp9DQoNCmNvbnN0IENPTVBPTkVOVFMgPSAiY29tcG9uZW50cyI7DQpjb25zdCBESVJFQ1RJVkVTID0gImRpcmVjdGl2ZXMiOw0KZnVuY3Rpb24gcmVzb2x2ZUNvbXBvbmVudChuYW1lLCBtYXliZVNlbGZSZWZlcmVuY2UpIHsNCiAgcmV0dXJuIHJlc29sdmVBc3NldChDT01QT05FTlRTLCBuYW1lLCB0cnVlLCBtYXliZVNlbGZSZWZlcmVuY2UpIHx8IG5hbWU7DQp9DQpjb25zdCBOVUxMX0RZTkFNSUNfQ09NUE9ORU5UID0gU3ltYm9sLmZvcigidi1uZGMiKTsNCmZ1bmN0aW9uIHJlc29sdmVEeW5hbWljQ29tcG9uZW50KGNvbXBvbmVudCkgew0KICBpZiAoaXNTdHJpbmcoY29tcG9uZW50KSkgew0KICAgIHJldHVybiByZXNvbHZlQXNzZXQoQ09NUE9ORU5UUywgY29tcG9uZW50LCBmYWxzZSkgfHwgY29tcG9uZW50Ow0KICB9IGVsc2Ugew0KICAgIHJldHVybiBjb21wb25lbnQgfHwgTlVMTF9EWU5BTUlDX0NPTVBPTkVOVDsNCiAgfQ0KfQ0KZnVuY3Rpb24gcmVzb2x2ZURpcmVjdGl2ZShuYW1lKSB7DQogIHJldHVybiByZXNvbHZlQXNzZXQoRElSRUNUSVZFUywgbmFtZSk7DQp9DQpmdW5jdGlvbiByZXNvbHZlQXNzZXQodHlwZSwgbmFtZSwgd2Fybk1pc3NpbmcgPSB0cnVlLCBtYXliZVNlbGZSZWZlcmVuY2UgPSBmYWxzZSkgew0KICBjb25zdCBpbnN0YW5jZSA9IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSB8fCBjdXJyZW50SW5zdGFuY2U7DQogIGlmIChpbnN0YW5jZSkgew0KICAgIGNvbnN0IENvbXBvbmVudCA9IGluc3RhbmNlLnR5cGU7DQogICAgaWYgKHR5cGUgPT09IENPTVBPTkVOVFMpIHsNCiAgICAgIGNvbnN0IHNlbGZOYW1lID0gZ2V0Q29tcG9uZW50TmFtZSgNCiAgICAgICAgQ29tcG9uZW50LA0KICAgICAgICBmYWxzZQ0KICAgICAgKTsNCiAgICAgIGlmIChzZWxmTmFtZSAmJiAoc2VsZk5hbWUgPT09IG5hbWUgfHwgc2VsZk5hbWUgPT09IGNhbWVsaXplKG5hbWUpIHx8IHNlbGZOYW1lID09PSBjYXBpdGFsaXplKGNhbWVsaXplKG5hbWUpKSkpIHsNCiAgICAgICAgcmV0dXJuIENvbXBvbmVudDsNCiAgICAgIH0NCiAgICB9DQogICAgY29uc3QgcmVzID0gKA0KICAgICAgLy8gbG9jYWwgcmVnaXN0cmF0aW9uDQogICAgICAvLyBjaGVjayBpbnN0YW5jZVt0eXBlXSBmaXJzdCB3aGljaCBpcyByZXNvbHZlZCBmb3Igb3B0aW9ucyBBUEkNCiAgICAgIHJlc29sdmUoaW5zdGFuY2VbdHlwZV0gfHwgQ29tcG9uZW50W3R5cGVdLCBuYW1lKSB8fCAvLyBnbG9iYWwgcmVnaXN0cmF0aW9uDQogICAgICByZXNvbHZlKGluc3RhbmNlLmFwcENvbnRleHRbdHlwZV0sIG5hbWUpDQogICAgKTsNCiAgICBpZiAoIXJlcyAmJiBtYXliZVNlbGZSZWZlcmVuY2UpIHsNCiAgICAgIHJldHVybiBDb21wb25lbnQ7DQogICAgfQ0KICAgIGlmICh3YXJuTWlzc2luZyAmJiAhcmVzKSB7DQogICAgICBjb25zdCBleHRyYSA9IHR5cGUgPT09IENPTVBPTkVOVFMgPyBgDQpJZiB0aGlzIGlzIGEgbmF0aXZlIGN1c3RvbSBlbGVtZW50LCBtYWtlIHN1cmUgdG8gZXhjbHVkZSBpdCBmcm9tIGNvbXBvbmVudCByZXNvbHV0aW9uIHZpYSBjb21waWxlck9wdGlvbnMuaXNDdXN0b21FbGVtZW50LmAgOiBgYDsNCiAgICAgIHdhcm4kMShgRmFpbGVkIHRvIHJlc29sdmUgJHt0eXBlLnNsaWNlKDAsIC0xKX06ICR7bmFtZX0ke2V4dHJhfWApOw0KICAgIH0NCiAgICByZXR1cm4gcmVzOw0KICB9IGVsc2Ugew0KICAgIHdhcm4kMSgNCiAgICAgIGByZXNvbHZlJHtjYXBpdGFsaXplKHR5cGUuc2xpY2UoMCwgLTEpKX0gY2FuIG9ubHkgYmUgdXNlZCBpbiByZW5kZXIoKSBvciBzZXR1cCgpLmANCiAgICApOw0KICB9DQp9DQpmdW5jdGlvbiByZXNvbHZlKHJlZ2lzdHJ5LCBuYW1lKSB7DQogIHJldHVybiByZWdpc3RyeSAmJiAocmVnaXN0cnlbbmFtZV0gfHwgcmVnaXN0cnlbY2FtZWxpemUobmFtZSldIHx8IHJlZ2lzdHJ5W2NhcGl0YWxpemUoY2FtZWxpemUobmFtZSkpXSk7DQp9DQoNCmZ1bmN0aW9uIHJlbmRlckxpc3Qoc291cmNlLCByZW5kZXJJdGVtLCBjYWNoZSwgaW5kZXgpIHsNCiAgbGV0IHJldDsNCiAgY29uc3QgY2FjaGVkID0gY2FjaGUgJiYgY2FjaGVbaW5kZXhdOw0KICBjb25zdCBzb3VyY2VJc0FycmF5ID0gaXNBcnJheShzb3VyY2UpOw0KICBpZiAoc291cmNlSXNBcnJheSB8fCBpc1N0cmluZyhzb3VyY2UpKSB7DQogICAgY29uc3Qgc291cmNlSXNSZWFjdGl2ZUFycmF5ID0gc291cmNlSXNBcnJheSAmJiBpc1JlYWN0aXZlKHNvdXJjZSk7DQogICAgbGV0IG5lZWRzV3JhcCA9IGZhbHNlOw0KICAgIGxldCBpc1JlYWRvbmx5U291cmNlID0gZmFsc2U7DQogICAgaWYgKHNvdXJjZUlzUmVhY3RpdmVBcnJheSkgew0KICAgICAgbmVlZHNXcmFwID0gIWlzU2hhbGxvdyhzb3VyY2UpOw0KICAgICAgaXNSZWFkb25seVNvdXJjZSA9IGlzUmVhZG9ubHkoc291cmNlKTsNCiAgICAgIHNvdXJjZSA9IHNoYWxsb3dSZWFkQXJyYXkoc291cmNlKTsNCiAgICB9DQogICAgcmV0ID0gbmV3IEFycmF5KHNvdXJjZS5sZW5ndGgpOw0KICAgIGZvciAobGV0IGkgPSAwLCBsID0gc291cmNlLmxlbmd0aDsgaSA8IGw7IGkrKykgew0KICAgICAgcmV0W2ldID0gcmVuZGVySXRlbSgNCiAgICAgICAgbmVlZHNXcmFwID8gaXNSZWFkb25seVNvdXJjZSA/IHRvUmVhZG9ubHkodG9SZWFjdGl2ZShzb3VyY2VbaV0pKSA6IHRvUmVhY3RpdmUoc291cmNlW2ldKSA6IHNvdXJjZVtpXSwNCiAgICAgICAgaSwNCiAgICAgICAgdm9pZCAwLA0KICAgICAgICBjYWNoZWQgJiYgY2FjaGVkW2ldDQogICAgICApOw0KICAgIH0NCiAgfSBlbHNlIGlmICh0eXBlb2Ygc291cmNlID09PSAibnVtYmVyIikgew0KICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihzb3VyY2UpKSB7DQogICAgICB3YXJuJDEoYFRoZSB2LWZvciByYW5nZSBleHBlY3QgYW4gaW50ZWdlciB2YWx1ZSBidXQgZ290ICR7c291cmNlfS5gKTsNCiAgICB9DQogICAgcmV0ID0gbmV3IEFycmF5KHNvdXJjZSk7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzb3VyY2U7IGkrKykgew0KICAgICAgcmV0W2ldID0gcmVuZGVySXRlbShpICsgMSwgaSwgdm9pZCAwLCBjYWNoZWQgJiYgY2FjaGVkW2ldKTsNCiAgICB9DQogIH0gZWxzZSBpZiAoaXNPYmplY3Qoc291cmNlKSkgew0KICAgIGlmIChzb3VyY2VbU3ltYm9sLml0ZXJhdG9yXSkgew0KICAgICAgcmV0ID0gQXJyYXkuZnJvbSgNCiAgICAgICAgc291cmNlLA0KICAgICAgICAoaXRlbSwgaSkgPT4gcmVuZGVySXRlbShpdGVtLCBpLCB2b2lkIDAsIGNhY2hlZCAmJiBjYWNoZWRbaV0pDQogICAgICApOw0KICAgIH0gZWxzZSB7DQogICAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoc291cmNlKTsNCiAgICAgIHJldCA9IG5ldyBBcnJheShrZXlzLmxlbmd0aCk7DQogICAgICBmb3IgKGxldCBpID0gMCwgbCA9IGtleXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7DQogICAgICAgIGNvbnN0IGtleSA9IGtleXNbaV07DQogICAgICAgIHJldFtpXSA9IHJlbmRlckl0ZW0oc291cmNlW2tleV0sIGtleSwgaSwgY2FjaGVkICYmIGNhY2hlZFtpXSk7DQogICAgICB9DQogICAgfQ0KICB9IGVsc2Ugew0KICAgIHJldCA9IFtdOw0KICB9DQogIGlmIChjYWNoZSkgew0KICAgIGNhY2hlW2luZGV4XSA9IHJldDsNCiAgfQ0KICByZXR1cm4gcmV0Ow0KfQ0KDQpmdW5jdGlvbiBjcmVhdGVTbG90cyhzbG90cywgZHluYW1pY1Nsb3RzKSB7DQogIGZvciAobGV0IGkgPSAwOyBpIDwgZHluYW1pY1Nsb3RzLmxlbmd0aDsgaSsrKSB7DQogICAgY29uc3Qgc2xvdCA9IGR5bmFtaWNTbG90c1tpXTsNCiAgICBpZiAoaXNBcnJheShzbG90KSkgew0KICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBzbG90Lmxlbmd0aDsgaisrKSB7DQogICAgICAgIHNsb3RzW3Nsb3Rbal0ubmFtZV0gPSBzbG90W2pdLmZuOw0KICAgICAgfQ0KICAgIH0gZWxzZSBpZiAoc2xvdCkgew0KICAgICAgc2xvdHNbc2xvdC5uYW1lXSA9IHNsb3Qua2V5ID8gKC4uLmFyZ3MpID0+IHsNCiAgICAgICAgY29uc3QgcmVzID0gc2xvdC5mbiguLi5hcmdzKTsNCiAgICAgICAgaWYgKHJlcykgcmVzLmtleSA9IHNsb3Qua2V5Ow0KICAgICAgICByZXR1cm4gcmVzOw0KICAgICAgfSA6IHNsb3QuZm47DQogICAgfQ0KICB9DQogIHJldHVybiBzbG90czsNCn0NCg0KZnVuY3Rpb24gcmVuZGVyU2xvdChzbG90cywgbmFtZSwgcHJvcHMgPSB7fSwgZmFsbGJhY2ssIG5vU2xvdHRlZCkgew0KICBpZiAoY3VycmVudFJlbmRlcmluZ0luc3RhbmNlLmNlIHx8IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZS5wYXJlbnQgJiYgaXNBc3luY1dyYXBwZXIoY3VycmVudFJlbmRlcmluZ0luc3RhbmNlLnBhcmVudCkgJiYgY3VycmVudFJlbmRlcmluZ0luc3RhbmNlLnBhcmVudC5jZSkgew0KICAgIGlmIChuYW1lICE9PSAiZGVmYXVsdCIpIHByb3BzLm5hbWUgPSBuYW1lOw0KICAgIHJldHVybiBvcGVuQmxvY2soKSwgY3JlYXRlQmxvY2soDQogICAgICBGcmFnbWVudCwNCiAgICAgIG51bGwsDQogICAgICBbY3JlYXRlVk5vZGUoInNsb3QiLCBwcm9wcywgZmFsbGJhY2sgJiYgZmFsbGJhY2soKSldLA0KICAgICAgNjQNCiAgICApOw0KICB9DQogIGxldCBzbG90ID0gc2xvdHNbbmFtZV07DQogIGlmIChzbG90ICYmIHNsb3QubGVuZ3RoID4gMSkgew0KICAgIHdhcm4kMSgNCiAgICAgIGBTU1Itb3B0aW1pemVkIHNsb3QgZnVuY3Rpb24gZGV0ZWN0ZWQgaW4gYSBub24tU1NSLW9wdGltaXplZCByZW5kZXIgZnVuY3Rpb24uIFlvdSBuZWVkIHRvIG1hcmsgdGhpcyBjb21wb25lbnQgd2l0aCAkZHluYW1pYy1zbG90cyBpbiB0aGUgcGFyZW50IHRlbXBsYXRlLmANCiAgICApOw0KICAgIHNsb3QgPSAoKSA9PiBbXTsNCiAgfQ0KICBpZiAoc2xvdCAmJiBzbG90Ll9jKSB7DQogICAgc2xvdC5fZCA9IGZhbHNlOw0KICB9DQogIG9wZW5CbG9jaygpOw0KICBjb25zdCB2YWxpZFNsb3RDb250ZW50ID0gc2xvdCAmJiBlbnN1cmVWYWxpZFZOb2RlKHNsb3QocHJvcHMpKTsNCiAgY29uc3Qgc2xvdEtleSA9IHByb3BzLmtleSB8fCAvLyBzbG90IGNvbnRlbnQgYXJyYXkgb2YgYSBkeW5hbWljIGNvbmRpdGlvbmFsIHNsb3QgbWF5IGhhdmUgYSBicmFuY2gNCiAgLy8ga2V5IGF0dGFjaGVkIGluIHRoZSBgY3JlYXRlU2xvdHNgIGhlbHBlciwgcmVzcGVjdCB0aGF0DQogIHZhbGlkU2xvdENvbnRlbnQgJiYgdmFsaWRTbG90Q29udGVudC5rZXk7DQogIGNvbnN0IHJlbmRlcmVkID0gY3JlYXRlQmxvY2soDQogICAgRnJhZ21lbnQsDQogICAgew0KICAgICAga2V5OiAoc2xvdEtleSAmJiAhaXNTeW1ib2woc2xvdEtleSkgPyBzbG90S2V5IDogYF8ke25hbWV9YCkgKyAvLyAjNzI1NiBmb3JjZSBkaWZmZXJlbnRpYXRlIGZhbGxiYWNrIGNvbnRlbnQgZnJvbSBhY3R1YWwgY29udGVudA0KICAgICAgKCF2YWxpZFNsb3RDb250ZW50ICYmIGZhbGxiYWNrID8gIl9mYiIgOiAiIikNCiAgICB9LA0KICAgIHZhbGlkU2xvdENvbnRlbnQgfHwgKGZhbGxiYWNrID8gZmFsbGJhY2soKSA6IFtdKSwNCiAgICB2YWxpZFNsb3RDb250ZW50ICYmIHNsb3RzLl8gPT09IDEgPyA2NCA6IC0yDQogICk7DQogIGlmICghbm9TbG90dGVkICYmIHJlbmRlcmVkLnNjb3BlSWQpIHsNCiAgICByZW5kZXJlZC5zbG90U2NvcGVJZHMgPSBbcmVuZGVyZWQuc2NvcGVJZCArICItcyJdOw0KICB9DQogIGlmIChzbG90ICYmIHNsb3QuX2MpIHsNCiAgICBzbG90Ll9kID0gdHJ1ZTsNCiAgfQ0KICByZXR1cm4gcmVuZGVyZWQ7DQp9DQpmdW5jdGlvbiBlbnN1cmVWYWxpZFZOb2RlKHZub2Rlcykgew0KICByZXR1cm4gdm5vZGVzLnNvbWUoKGNoaWxkKSA9PiB7DQogICAgaWYgKCFpc1ZOb2RlKGNoaWxkKSkgcmV0dXJuIHRydWU7DQogICAgaWYgKGNoaWxkLnR5cGUgPT09IENvbW1lbnQpIHJldHVybiBmYWxzZTsNCiAgICBpZiAoY2hpbGQudHlwZSA9PT0gRnJhZ21lbnQgJiYgIWVuc3VyZVZhbGlkVk5vZGUoY2hpbGQuY2hpbGRyZW4pKQ0KICAgICAgcmV0dXJuIGZhbHNlOw0KICAgIHJldHVybiB0cnVlOw0KICB9KSA/IHZub2RlcyA6IG51bGw7DQp9DQoNCmZ1bmN0aW9uIHRvSGFuZGxlcnMob2JqLCBwcmVzZXJ2ZUNhc2VJZk5lY2Vzc2FyeSkgew0KICBjb25zdCByZXQgPSB7fTsNCiAgaWYgKCFpc09iamVjdChvYmopKSB7DQogICAgd2FybiQxKGB2LW9uIHdpdGggbm8gYXJndW1lbnQgZXhwZWN0cyBhbiBvYmplY3QgdmFsdWUuYCk7DQogICAgcmV0dXJuIHJldDsNCiAgfQ0KICBmb3IgKGNvbnN0IGtleSBpbiBvYmopIHsNCiAgICByZXRbcHJlc2VydmVDYXNlSWZOZWNlc3NhcnkgJiYgL1tBLVpdLy50ZXN0KGtleSkgPyBgb246JHtrZXl9YCA6IHRvSGFuZGxlcktleShrZXkpXSA9IG9ialtrZXldOw0KICB9DQogIHJldHVybiByZXQ7DQp9DQoNCmNvbnN0IGdldFB1YmxpY0luc3RhbmNlID0gKGkpID0+IHsNCiAgaWYgKCFpKSByZXR1cm4gbnVsbDsNCiAgaWYgKGlzU3RhdGVmdWxDb21wb25lbnQoaSkpIHJldHVybiBnZXRDb21wb25lbnRQdWJsaWNJbnN0YW5jZShpKTsNCiAgcmV0dXJuIGdldFB1YmxpY0luc3RhbmNlKGkucGFyZW50KTsNCn07DQpjb25zdCBwdWJsaWNQcm9wZXJ0aWVzTWFwID0gKA0KICAvLyBNb3ZlIFBVUkUgbWFya2VyIHRvIG5ldyBsaW5lIHRvIHdvcmthcm91bmQgY29tcGlsZXIgZGlzY2FyZGluZyBpdA0KICAvLyBkdWUgdG8gdHlwZSBhbm5vdGF0aW9uDQogIC8qIEBfX1BVUkVfXyAqLyBleHRlbmQoLyogQF9fUFVSRV9fICovIE9iamVjdC5jcmVhdGUobnVsbCksIHsNCiAgICAkOiAoaSkgPT4gaSwNCiAgICAkZWw6IChpKSA9PiBpLnZub2RlLmVsLA0KICAgICRkYXRhOiAoaSkgPT4gaS5kYXRhLA0KICAgICRwcm9wczogKGkpID0+IHNoYWxsb3dSZWFkb25seShpLnByb3BzKSAsDQogICAgJGF0dHJzOiAoaSkgPT4gc2hhbGxvd1JlYWRvbmx5KGkuYXR0cnMpICwNCiAgICAkc2xvdHM6IChpKSA9PiBzaGFsbG93UmVhZG9ubHkoaS5zbG90cykgLA0KICAgICRyZWZzOiAoaSkgPT4gc2hhbGxvd1JlYWRvbmx5KGkucmVmcykgLA0KICAgICRwYXJlbnQ6IChpKSA9PiBnZXRQdWJsaWNJbnN0YW5jZShpLnBhcmVudCksDQogICAgJHJvb3Q6IChpKSA9PiBnZXRQdWJsaWNJbnN0YW5jZShpLnJvb3QpLA0KICAgICRob3N0OiAoaSkgPT4gaS5jZSwNCiAgICAkZW1pdDogKGkpID0+IGkuZW1pdCwNCiAgICAkb3B0aW9uczogKGkpID0+IHJlc29sdmVNZXJnZWRPcHRpb25zKGkpICwNCiAgICAkZm9yY2VVcGRhdGU6IChpKSA9PiBpLmYgfHwgKGkuZiA9ICgpID0+IHsNCiAgICAgIHF1ZXVlSm9iKGkudXBkYXRlKTsNCiAgICB9KSwNCiAgICAkbmV4dFRpY2s6IChpKSA9PiBpLm4gfHwgKGkubiA9IG5leHRUaWNrLmJpbmQoaS5wcm94eSkpLA0KICAgICR3YXRjaDogKGkpID0+IGluc3RhbmNlV2F0Y2guYmluZChpKSANCiAgfSkNCik7DQpjb25zdCBpc1Jlc2VydmVkUHJlZml4ID0gKGtleSkgPT4ga2V5ID09PSAiXyIgfHwga2V5ID09PSAiJCI7DQpjb25zdCBoYXNTZXR1cEJpbmRpbmcgPSAoc3RhdGUsIGtleSkgPT4gc3RhdGUgIT09IEVNUFRZX09CSiAmJiAhc3RhdGUuX19pc1NjcmlwdFNldHVwICYmIGhhc093bihzdGF0ZSwga2V5KTsNCmNvbnN0IFB1YmxpY0luc3RhbmNlUHJveHlIYW5kbGVycyA9IHsNCiAgZ2V0KHsgXzogaW5zdGFuY2UgfSwga2V5KSB7DQogICAgaWYgKGtleSA9PT0gIl9fdl9za2lwIikgew0KICAgICAgcmV0dXJuIHRydWU7DQogICAgfQ0KICAgIGNvbnN0IHsgY3R4LCBzZXR1cFN0YXRlLCBkYXRhLCBwcm9wcywgYWNjZXNzQ2FjaGUsIHR5cGUsIGFwcENvbnRleHQgfSA9IGluc3RhbmNlOw0KICAgIGlmIChrZXkgPT09ICJfX2lzVnVlIikgew0KICAgICAgcmV0dXJuIHRydWU7DQogICAgfQ0KICAgIGxldCBub3JtYWxpemVkUHJvcHM7DQogICAgaWYgKGtleVswXSAhPT0gIiQiKSB7DQogICAgICBjb25zdCBuID0gYWNjZXNzQ2FjaGVba2V5XTsNCiAgICAgIGlmIChuICE9PSB2b2lkIDApIHsNCiAgICAgICAgc3dpdGNoIChuKSB7DQogICAgICAgICAgY2FzZSAxIC8qIFNFVFVQICovOg0KICAgICAgICAgICAgcmV0dXJuIHNldHVwU3RhdGVba2V5XTsNCiAgICAgICAgICBjYXNlIDIgLyogREFUQSAqLzoNCiAgICAgICAgICAgIHJldHVybiBkYXRhW2tleV07DQogICAgICAgICAgY2FzZSA0IC8qIENPTlRFWFQgKi86DQogICAgICAgICAgICByZXR1cm4gY3R4W2tleV07DQogICAgICAgICAgY2FzZSAzIC8qIFBST1BTICovOg0KICAgICAgICAgICAgcmV0dXJuIHByb3BzW2tleV07DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSBpZiAoaGFzU2V0dXBCaW5kaW5nKHNldHVwU3RhdGUsIGtleSkpIHsNCiAgICAgICAgYWNjZXNzQ2FjaGVba2V5XSA9IDEgLyogU0VUVVAgKi87DQogICAgICAgIHJldHVybiBzZXR1cFN0YXRlW2tleV07DQogICAgICB9IGVsc2UgaWYgKGRhdGEgIT09IEVNUFRZX09CSiAmJiBoYXNPd24oZGF0YSwga2V5KSkgew0KICAgICAgICBhY2Nlc3NDYWNoZVtrZXldID0gMiAvKiBEQVRBICovOw0KICAgICAgICByZXR1cm4gZGF0YVtrZXldOw0KICAgICAgfSBlbHNlIGlmICgNCiAgICAgICAgLy8gb25seSBjYWNoZSBvdGhlciBwcm9wZXJ0aWVzIHdoZW4gaW5zdGFuY2UgaGFzIGRlY2xhcmVkICh0aHVzIHN0YWJsZSkNCiAgICAgICAgLy8gcHJvcHMNCiAgICAgICAgKG5vcm1hbGl6ZWRQcm9wcyA9IGluc3RhbmNlLnByb3BzT3B0aW9uc1swXSkgJiYgaGFzT3duKG5vcm1hbGl6ZWRQcm9wcywga2V5KQ0KICAgICAgKSB7DQogICAgICAgIGFjY2Vzc0NhY2hlW2tleV0gPSAzIC8qIFBST1BTICovOw0KICAgICAgICByZXR1cm4gcHJvcHNba2V5XTsNCiAgICAgIH0gZWxzZSBpZiAoY3R4ICE9PSBFTVBUWV9PQkogJiYgaGFzT3duKGN0eCwga2V5KSkgew0KICAgICAgICBhY2Nlc3NDYWNoZVtrZXldID0gNCAvKiBDT05URVhUICovOw0KICAgICAgICByZXR1cm4gY3R4W2tleV07DQogICAgICB9IGVsc2UgaWYgKHNob3VsZENhY2hlQWNjZXNzKSB7DQogICAgICAgIGFjY2Vzc0NhY2hlW2tleV0gPSAwIC8qIE9USEVSICovOw0KICAgICAgfQ0KICAgIH0NCiAgICBjb25zdCBwdWJsaWNHZXR0ZXIgPSBwdWJsaWNQcm9wZXJ0aWVzTWFwW2tleV07DQogICAgbGV0IGNzc01vZHVsZSwgZ2xvYmFsUHJvcGVydGllczsNCiAgICBpZiAocHVibGljR2V0dGVyKSB7DQogICAgICBpZiAoa2V5ID09PSAiJGF0dHJzIikgew0KICAgICAgICB0cmFjayhpbnN0YW5jZS5hdHRycywgImdldCIsICIiKTsNCiAgICAgICAgbWFya0F0dHJzQWNjZXNzZWQoKTsNCiAgICAgIH0gZWxzZSBpZiAoa2V5ID09PSAiJHNsb3RzIikgew0KICAgICAgICB0cmFjayhpbnN0YW5jZSwgImdldCIsIGtleSk7DQogICAgICB9DQogICAgICByZXR1cm4gcHVibGljR2V0dGVyKGluc3RhbmNlKTsNCiAgICB9IGVsc2UgaWYgKA0KICAgICAgLy8gY3NzIG1vZHVsZSAoaW5qZWN0ZWQgYnkgdnVlLWxvYWRlcikNCiAgICAgIChjc3NNb2R1bGUgPSB0eXBlLl9fY3NzTW9kdWxlcykgJiYgKGNzc01vZHVsZSA9IGNzc01vZHVsZVtrZXldKQ0KICAgICkgew0KICAgICAgcmV0dXJuIGNzc01vZHVsZTsNCiAgICB9IGVsc2UgaWYgKGN0eCAhPT0gRU1QVFlfT0JKICYmIGhhc093bihjdHgsIGtleSkpIHsNCiAgICAgIGFjY2Vzc0NhY2hlW2tleV0gPSA0IC8qIENPTlRFWFQgKi87DQogICAgICByZXR1cm4gY3R4W2tleV07DQogICAgfSBlbHNlIGlmICgNCiAgICAgIC8vIGdsb2JhbCBwcm9wZXJ0aWVzDQogICAgICBnbG9iYWxQcm9wZXJ0aWVzID0gYXBwQ29udGV4dC5jb25maWcuZ2xvYmFsUHJvcGVydGllcywgaGFzT3duKGdsb2JhbFByb3BlcnRpZXMsIGtleSkNCiAgICApIHsNCiAgICAgIHsNCiAgICAgICAgcmV0dXJuIGdsb2JhbFByb3BlcnRpZXNba2V5XTsNCiAgICAgIH0NCiAgICB9IGVsc2UgaWYgKGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSAmJiAoIWlzU3RyaW5nKGtleSkgfHwgLy8gIzEwOTEgYXZvaWQgaW50ZXJuYWwgaXNSZWYvaXNWTm9kZSBjaGVja3Mgb24gY29tcG9uZW50IGluc3RhbmNlIGxlYWRpbmcNCiAgICAvLyB0byBpbmZpbml0ZSB3YXJuaW5nIGxvb3ANCiAgICBrZXkuaW5kZXhPZigiX192IikgIT09IDApKSB7DQogICAgICBpZiAoZGF0YSAhPT0gRU1QVFlfT0JKICYmIGlzUmVzZXJ2ZWRQcmVmaXgoa2V5WzBdKSAmJiBoYXNPd24oZGF0YSwga2V5KSkgew0KICAgICAgICB3YXJuJDEoDQogICAgICAgICAgYFByb3BlcnR5ICR7SlNPTi5zdHJpbmdpZnkoDQogICAgICAgICAgICBrZXkNCiAgICAgICAgICApfSBtdXN0IGJlIGFjY2Vzc2VkIHZpYSAkZGF0YSBiZWNhdXNlIGl0IHN0YXJ0cyB3aXRoIGEgcmVzZXJ2ZWQgY2hhcmFjdGVyICgiJCIgb3IgIl8iKSBhbmQgaXMgbm90IHByb3hpZWQgb24gdGhlIHJlbmRlciBjb250ZXh0LmANCiAgICAgICAgKTsNCiAgICAgIH0gZWxzZSBpZiAoaW5zdGFuY2UgPT09IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSkgew0KICAgICAgICB3YXJuJDEoDQogICAgICAgICAgYFByb3BlcnR5ICR7SlNPTi5zdHJpbmdpZnkoa2V5KX0gd2FzIGFjY2Vzc2VkIGR1cmluZyByZW5kZXIgYnV0IGlzIG5vdCBkZWZpbmVkIG9uIGluc3RhbmNlLmANCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICB9DQogIH0sDQogIHNldCh7IF86IGluc3RhbmNlIH0sIGtleSwgdmFsdWUpIHsNCiAgICBjb25zdCB7IGRhdGEsIHNldHVwU3RhdGUsIGN0eCB9ID0gaW5zdGFuY2U7DQogICAgaWYgKGhhc1NldHVwQmluZGluZyhzZXR1cFN0YXRlLCBrZXkpKSB7DQogICAgICBzZXR1cFN0YXRlW2tleV0gPSB2YWx1ZTsNCiAgICAgIHJldHVybiB0cnVlOw0KICAgIH0gZWxzZSBpZiAoc2V0dXBTdGF0ZS5fX2lzU2NyaXB0U2V0dXAgJiYgaGFzT3duKHNldHVwU3RhdGUsIGtleSkpIHsNCiAgICAgIHdhcm4kMShgQ2Fubm90IG11dGF0ZSA8c2NyaXB0IHNldHVwPiBiaW5kaW5nICIke2tleX0iIGZyb20gT3B0aW9ucyBBUEkuYCk7DQogICAgICByZXR1cm4gZmFsc2U7DQogICAgfSBlbHNlIGlmIChkYXRhICE9PSBFTVBUWV9PQkogJiYgaGFzT3duKGRhdGEsIGtleSkpIHsNCiAgICAgIGRhdGFba2V5XSA9IHZhbHVlOw0KICAgICAgcmV0dXJuIHRydWU7DQogICAgfSBlbHNlIGlmIChoYXNPd24oaW5zdGFuY2UucHJvcHMsIGtleSkpIHsNCiAgICAgIHdhcm4kMShgQXR0ZW1wdGluZyB0byBtdXRhdGUgcHJvcCAiJHtrZXl9Ii4gUHJvcHMgYXJlIHJlYWRvbmx5LmApOw0KICAgICAgcmV0dXJuIGZhbHNlOw0KICAgIH0NCiAgICBpZiAoa2V5WzBdID09PSAiJCIgJiYga2V5LnNsaWNlKDEpIGluIGluc3RhbmNlKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGBBdHRlbXB0aW5nIHRvIG11dGF0ZSBwdWJsaWMgcHJvcGVydHkgIiR7a2V5fSIuIFByb3BlcnRpZXMgc3RhcnRpbmcgd2l0aCAkIGFyZSByZXNlcnZlZCBhbmQgcmVhZG9ubHkuYA0KICAgICAgKTsNCiAgICAgIHJldHVybiBmYWxzZTsNCiAgICB9IGVsc2Ugew0KICAgICAgaWYgKGtleSBpbiBpbnN0YW5jZS5hcHBDb250ZXh0LmNvbmZpZy5nbG9iYWxQcm9wZXJ0aWVzKSB7DQogICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIGtleSwgew0KICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsDQogICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLA0KICAgICAgICAgIHZhbHVlDQogICAgICAgIH0pOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgY3R4W2tleV0gPSB2YWx1ZTsNCiAgICAgIH0NCiAgICB9DQogICAgcmV0dXJuIHRydWU7DQogIH0sDQogIGhhcyh7DQogICAgXzogeyBkYXRhLCBzZXR1cFN0YXRlLCBhY2Nlc3NDYWNoZSwgY3R4LCBhcHBDb250ZXh0LCBwcm9wc09wdGlvbnMgfQ0KICB9LCBrZXkpIHsNCiAgICBsZXQgbm9ybWFsaXplZFByb3BzOw0KICAgIHJldHVybiAhIWFjY2Vzc0NhY2hlW2tleV0gfHwgZGF0YSAhPT0gRU1QVFlfT0JKICYmIGhhc093bihkYXRhLCBrZXkpIHx8IGhhc1NldHVwQmluZGluZyhzZXR1cFN0YXRlLCBrZXkpIHx8IChub3JtYWxpemVkUHJvcHMgPSBwcm9wc09wdGlvbnNbMF0pICYmIGhhc093bihub3JtYWxpemVkUHJvcHMsIGtleSkgfHwgaGFzT3duKGN0eCwga2V5KSB8fCBoYXNPd24ocHVibGljUHJvcGVydGllc01hcCwga2V5KSB8fCBoYXNPd24oYXBwQ29udGV4dC5jb25maWcuZ2xvYmFsUHJvcGVydGllcywga2V5KTsNCiAgfSwNCiAgZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIGRlc2NyaXB0b3IpIHsNCiAgICBpZiAoZGVzY3JpcHRvci5nZXQgIT0gbnVsbCkgew0KICAgICAgdGFyZ2V0Ll8uYWNjZXNzQ2FjaGVba2V5XSA9IDA7DQogICAgfSBlbHNlIGlmIChoYXNPd24oZGVzY3JpcHRvciwgInZhbHVlIikpIHsNCiAgICAgIHRoaXMuc2V0KHRhcmdldCwga2V5LCBkZXNjcmlwdG9yLnZhbHVlLCBudWxsKTsNCiAgICB9DQogICAgcmV0dXJuIFJlZmxlY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIGRlc2NyaXB0b3IpOw0KICB9DQp9Ow0Kew0KICBQdWJsaWNJbnN0YW5jZVByb3h5SGFuZGxlcnMub3duS2V5cyA9ICh0YXJnZXQpID0+IHsNCiAgICB3YXJuJDEoDQogICAgICBgQXZvaWQgYXBwIGxvZ2ljIHRoYXQgcmVsaWVzIG9uIGVudW1lcmF0aW5nIGtleXMgb24gYSBjb21wb25lbnQgaW5zdGFuY2UuIFRoZSBrZXlzIHdpbGwgYmUgZW1wdHkgaW4gcHJvZHVjdGlvbiBtb2RlIHRvIGF2b2lkIHBlcmZvcm1hbmNlIG92ZXJoZWFkLmANCiAgICApOw0KICAgIHJldHVybiBSZWZsZWN0Lm93bktleXModGFyZ2V0KTsNCiAgfTsNCn0NCmNvbnN0IFJ1bnRpbWVDb21waWxlZFB1YmxpY0luc3RhbmNlUHJveHlIYW5kbGVycyA9IC8qIEBfX1BVUkVfXyAqLyBleHRlbmQoe30sIFB1YmxpY0luc3RhbmNlUHJveHlIYW5kbGVycywgew0KICBnZXQodGFyZ2V0LCBrZXkpIHsNCiAgICBpZiAoa2V5ID09PSBTeW1ib2wudW5zY29wYWJsZXMpIHsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgcmV0dXJuIFB1YmxpY0luc3RhbmNlUHJveHlIYW5kbGVycy5nZXQodGFyZ2V0LCBrZXksIHRhcmdldCk7DQogIH0sDQogIGhhcyhfLCBrZXkpIHsNCiAgICBjb25zdCBoYXMgPSBrZXlbMF0gIT09ICJfIiAmJiAhaXNHbG9iYWxseUFsbG93ZWQoa2V5KTsNCiAgICBpZiAoIWhhcyAmJiBQdWJsaWNJbnN0YW5jZVByb3h5SGFuZGxlcnMuaGFzKF8sIGtleSkpIHsNCiAgICAgIHdhcm4kMSgNCiAgICAgICAgYFByb3BlcnR5ICR7SlNPTi5zdHJpbmdpZnkoDQogICAgICAgICAga2V5DQogICAgICAgICl9IHNob3VsZCBub3Qgc3RhcnQgd2l0aCBfIHdoaWNoIGlzIGEgcmVzZXJ2ZWQgcHJlZml4IGZvciBWdWUgaW50ZXJuYWxzLmANCiAgICAgICk7DQogICAgfQ0KICAgIHJldHVybiBoYXM7DQogIH0NCn0pOw0KZnVuY3Rpb24gY3JlYXRlRGV2UmVuZGVyQ29udGV4dChpbnN0YW5jZSkgew0KICBjb25zdCB0YXJnZXQgPSB7fTsNCiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgYF9gLCB7DQogICAgY29uZmlndXJhYmxlOiB0cnVlLA0KICAgIGVudW1lcmFibGU6IGZhbHNlLA0KICAgIGdldDogKCkgPT4gaW5zdGFuY2UNCiAgfSk7DQogIE9iamVjdC5rZXlzKHB1YmxpY1Byb3BlcnRpZXNNYXApLmZvckVhY2goKGtleSkgPT4gew0KICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgew0KICAgICAgY29uZmlndXJhYmxlOiB0cnVlLA0KICAgICAgZW51bWVyYWJsZTogZmFsc2UsDQogICAgICBnZXQ6ICgpID0+IHB1YmxpY1Byb3BlcnRpZXNNYXBba2V5XShpbnN0YW5jZSksDQogICAgICAvLyBpbnRlcmNlcHRlZCBieSB0aGUgcHJveHkgc28gbm8gbmVlZCBmb3IgaW1wbGVtZW50YXRpb24sDQogICAgICAvLyBidXQgbmVlZGVkIHRvIHByZXZlbnQgc2V0IGVycm9ycw0KICAgICAgc2V0OiBOT09QDQogICAgfSk7DQogIH0pOw0KICByZXR1cm4gdGFyZ2V0Ow0KfQ0KZnVuY3Rpb24gZXhwb3NlUHJvcHNPblJlbmRlckNvbnRleHQoaW5zdGFuY2UpIHsNCiAgY29uc3Qgew0KICAgIGN0eCwNCiAgICBwcm9wc09wdGlvbnM6IFtwcm9wc09wdGlvbnNdDQogIH0gPSBpbnN0YW5jZTsNCiAgaWYgKHByb3BzT3B0aW9ucykgew0KICAgIE9iamVjdC5rZXlzKHByb3BzT3B0aW9ucykuZm9yRWFjaCgoa2V5KSA9PiB7DQogICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY3R4LCBrZXksIHsNCiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSwNCiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLA0KICAgICAgICBnZXQ6ICgpID0+IGluc3RhbmNlLnByb3BzW2tleV0sDQogICAgICAgIHNldDogTk9PUA0KICAgICAgfSk7DQogICAgfSk7DQogIH0NCn0NCmZ1bmN0aW9uIGV4cG9zZVNldHVwU3RhdGVPblJlbmRlckNvbnRleHQoaW5zdGFuY2UpIHsNCiAgY29uc3QgeyBjdHgsIHNldHVwU3RhdGUgfSA9IGluc3RhbmNlOw0KICBPYmplY3Qua2V5cyh0b1JhdyhzZXR1cFN0YXRlKSkuZm9yRWFjaCgoa2V5KSA9PiB7DQogICAgaWYgKCFzZXR1cFN0YXRlLl9faXNTY3JpcHRTZXR1cCkgew0KICAgICAgaWYgKGlzUmVzZXJ2ZWRQcmVmaXgoa2V5WzBdKSkgew0KICAgICAgICB3YXJuJDEoDQogICAgICAgICAgYHNldHVwKCkgcmV0dXJuIHByb3BlcnR5ICR7SlNPTi5zdHJpbmdpZnkoDQogICAgICAgICAgICBrZXkNCiAgICAgICAgICApfSBzaG91bGQgbm90IHN0YXJ0IHdpdGggIiQiIG9yICJfIiB3aGljaCBhcmUgcmVzZXJ2ZWQgcHJlZml4ZXMgZm9yIFZ1ZSBpbnRlcm5hbHMuYA0KICAgICAgICApOw0KICAgICAgICByZXR1cm47DQogICAgICB9DQogICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY3R4LCBrZXksIHsNCiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSwNCiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLA0KICAgICAgICBnZXQ6ICgpID0+IHNldHVwU3RhdGVba2V5XSwNCiAgICAgICAgc2V0OiBOT09QDQogICAgICB9KTsNCiAgICB9DQogIH0pOw0KfQ0KDQpjb25zdCB3YXJuUnVudGltZVVzYWdlID0gKG1ldGhvZCkgPT4gd2FybiQxKA0KICBgJHttZXRob2R9KCkgaXMgYSBjb21waWxlci1oaW50IGhlbHBlciB0aGF0IGlzIG9ubHkgdXNhYmxlIGluc2lkZSA8c2NyaXB0IHNldHVwPiBvZiBhIHNpbmdsZSBmaWxlIGNvbXBvbmVudC4gSXRzIGFyZ3VtZW50cyBzaG91bGQgYmUgY29tcGlsZWQgYXdheSBhbmQgcGFzc2luZyBpdCBhdCBydW50aW1lIGhhcyBubyBlZmZlY3QuYA0KKTsNCmZ1bmN0aW9uIGRlZmluZVByb3BzKCkgew0KICB7DQogICAgd2FyblJ1bnRpbWVVc2FnZShgZGVmaW5lUHJvcHNgKTsNCiAgfQ0KICByZXR1cm4gbnVsbDsNCn0NCmZ1bmN0aW9uIGRlZmluZUVtaXRzKCkgew0KICB7DQogICAgd2FyblJ1bnRpbWVVc2FnZShgZGVmaW5lRW1pdHNgKTsNCiAgfQ0KICByZXR1cm4gbnVsbDsNCn0NCmZ1bmN0aW9uIGRlZmluZUV4cG9zZShleHBvc2VkKSB7DQogIHsNCiAgICB3YXJuUnVudGltZVVzYWdlKGBkZWZpbmVFeHBvc2VgKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gZGVmaW5lT3B0aW9ucyhvcHRpb25zKSB7DQogIHsNCiAgICB3YXJuUnVudGltZVVzYWdlKGBkZWZpbmVPcHRpb25zYCk7DQogIH0NCn0NCmZ1bmN0aW9uIGRlZmluZVNsb3RzKCkgew0KICB7DQogICAgd2FyblJ1bnRpbWVVc2FnZShgZGVmaW5lU2xvdHNgKTsNCiAgfQ0KICByZXR1cm4gbnVsbDsNCn0NCmZ1bmN0aW9uIGRlZmluZU1vZGVsKCkgew0KICB7DQogICAgd2FyblJ1bnRpbWVVc2FnZSgiZGVmaW5lTW9kZWwiKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gd2l0aERlZmF1bHRzKHByb3BzLCBkZWZhdWx0cykgew0KICB7DQogICAgd2FyblJ1bnRpbWVVc2FnZShgd2l0aERlZmF1bHRzYCk7DQogIH0NCiAgcmV0dXJuIG51bGw7DQp9DQpmdW5jdGlvbiB1c2VTbG90cygpIHsNCiAgcmV0dXJuIGdldENvbnRleHQoKS5zbG90czsNCn0NCmZ1bmN0aW9uIHVzZUF0dHJzKCkgew0KICByZXR1cm4gZ2V0Q29udGV4dCgpLmF0dHJzOw0KfQ0KZnVuY3Rpb24gZ2V0Q29udGV4dCgpIHsNCiAgY29uc3QgaSA9IGdldEN1cnJlbnRJbnN0YW5jZSgpOw0KICBpZiAoIWkpIHsNCiAgICB3YXJuJDEoYHVzZUNvbnRleHQoKSBjYWxsZWQgd2l0aG91dCBhY3RpdmUgaW5zdGFuY2UuYCk7DQogIH0NCiAgcmV0dXJuIGkuc2V0dXBDb250ZXh0IHx8IChpLnNldHVwQ29udGV4dCA9IGNyZWF0ZVNldHVwQ29udGV4dChpKSk7DQp9DQpmdW5jdGlvbiBub3JtYWxpemVQcm9wc09yRW1pdHMocHJvcHMpIHsNCiAgcmV0dXJuIGlzQXJyYXkocHJvcHMpID8gcHJvcHMucmVkdWNlKA0KICAgIChub3JtYWxpemVkLCBwKSA9PiAobm9ybWFsaXplZFtwXSA9IG51bGwsIG5vcm1hbGl6ZWQpLA0KICAgIHt9DQogICkgOiBwcm9wczsNCn0NCmZ1bmN0aW9uIG1lcmdlRGVmYXVsdHMocmF3LCBkZWZhdWx0cykgew0KICBjb25zdCBwcm9wcyA9IG5vcm1hbGl6ZVByb3BzT3JFbWl0cyhyYXcpOw0KICBmb3IgKGNvbnN0IGtleSBpbiBkZWZhdWx0cykgew0KICAgIGlmIChrZXkuc3RhcnRzV2l0aCgiX19za2lwIikpIGNvbnRpbnVlOw0KICAgIGxldCBvcHQgPSBwcm9wc1trZXldOw0KICAgIGlmIChvcHQpIHsNCiAgICAgIGlmIChpc0FycmF5KG9wdCkgfHwgaXNGdW5jdGlvbihvcHQpKSB7DQogICAgICAgIG9wdCA9IHByb3BzW2tleV0gPSB7IHR5cGU6IG9wdCwgZGVmYXVsdDogZGVmYXVsdHNba2V5XSB9Ow0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgb3B0LmRlZmF1bHQgPSBkZWZhdWx0c1trZXldOw0KICAgICAgfQ0KICAgIH0gZWxzZSBpZiAob3B0ID09PSBudWxsKSB7DQogICAgICBvcHQgPSBwcm9wc1trZXldID0geyBkZWZhdWx0OiBkZWZhdWx0c1trZXldIH07DQogICAgfSBlbHNlIHsNCiAgICAgIHdhcm4kMShgcHJvcHMgZGVmYXVsdCBrZXkgIiR7a2V5fSIgaGFzIG5vIGNvcnJlc3BvbmRpbmcgZGVjbGFyYXRpb24uYCk7DQogICAgfQ0KICAgIGlmIChvcHQgJiYgZGVmYXVsdHNbYF9fc2tpcF8ke2tleX1gXSkgew0KICAgICAgb3B0LnNraXBGYWN0b3J5ID0gdHJ1ZTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIHByb3BzOw0KfQ0KZnVuY3Rpb24gbWVyZ2VNb2RlbHMoYSwgYikgew0KICBpZiAoIWEgfHwgIWIpIHJldHVybiBhIHx8IGI7DQogIGlmIChpc0FycmF5KGEpICYmIGlzQXJyYXkoYikpIHJldHVybiBhLmNvbmNhdChiKTsNCiAgcmV0dXJuIGV4dGVuZCh7fSwgbm9ybWFsaXplUHJvcHNPckVtaXRzKGEpLCBub3JtYWxpemVQcm9wc09yRW1pdHMoYikpOw0KfQ0KZnVuY3Rpb24gY3JlYXRlUHJvcHNSZXN0UHJveHkocHJvcHMsIGV4Y2x1ZGVkS2V5cykgew0KICBjb25zdCByZXQgPSB7fTsNCiAgZm9yIChjb25zdCBrZXkgaW4gcHJvcHMpIHsNCiAgICBpZiAoIWV4Y2x1ZGVkS2V5cy5pbmNsdWRlcyhrZXkpKSB7DQogICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocmV0LCBrZXksIHsNCiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSwNCiAgICAgICAgZ2V0OiAoKSA9PiBwcm9wc1trZXldDQogICAgICB9KTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIHJldDsNCn0NCmZ1bmN0aW9uIHdpdGhBc3luY0NvbnRleHQoZ2V0QXdhaXRhYmxlKSB7DQogIGNvbnN0IGN0eCA9IGdldEN1cnJlbnRJbnN0YW5jZSgpOw0KICBpZiAoIWN0eCkgew0KICAgIHdhcm4kMSgNCiAgICAgIGB3aXRoQXN5bmNDb250ZXh0IGNhbGxlZCB3aXRob3V0IGFjdGl2ZSBjdXJyZW50IGluc3RhbmNlLiBUaGlzIGlzIGxpa2VseSBhIGJ1Zy5gDQogICAgKTsNCiAgfQ0KICBsZXQgYXdhaXRhYmxlID0gZ2V0QXdhaXRhYmxlKCk7DQogIHVuc2V0Q3VycmVudEluc3RhbmNlKCk7DQogIGlmIChpc1Byb21pc2UoYXdhaXRhYmxlKSkgew0KICAgIGF3YWl0YWJsZSA9IGF3YWl0YWJsZS5jYXRjaCgoZSkgPT4gew0KICAgICAgc2V0Q3VycmVudEluc3RhbmNlKGN0eCk7DQogICAgICB0aHJvdyBlOw0KICAgIH0pOw0KICB9DQogIHJldHVybiBbYXdhaXRhYmxlLCAoKSA9PiBzZXRDdXJyZW50SW5zdGFuY2UoY3R4KV07DQp9DQoNCmZ1bmN0aW9uIGNyZWF0ZUR1cGxpY2F0ZUNoZWNrZXIoKSB7DQogIGNvbnN0IGNhY2hlID0gLyogQF9fUFVSRV9fICovIE9iamVjdC5jcmVhdGUobnVsbCk7DQogIHJldHVybiAodHlwZSwga2V5KSA9PiB7DQogICAgaWYgKGNhY2hlW2tleV0pIHsNCiAgICAgIHdhcm4kMShgJHt0eXBlfSBwcm9wZXJ0eSAiJHtrZXl9IiBpcyBhbHJlYWR5IGRlZmluZWQgaW4gJHtjYWNoZVtrZXldfS5gKTsNCiAgICB9IGVsc2Ugew0KICAgICAgY2FjaGVba2V5XSA9IHR5cGU7DQogICAgfQ0KICB9Ow0KfQ0KbGV0IHNob3VsZENhY2hlQWNjZXNzID0gdHJ1ZTsNCmZ1bmN0aW9uIGFwcGx5T3B0aW9ucyhpbnN0YW5jZSkgew0KICBjb25zdCBvcHRpb25zID0gcmVzb2x2ZU1lcmdlZE9wdGlvbnMoaW5zdGFuY2UpOw0KICBjb25zdCBwdWJsaWNUaGlzID0gaW5zdGFuY2UucHJveHk7DQogIGNvbnN0IGN0eCA9IGluc3RhbmNlLmN0eDsNCiAgc2hvdWxkQ2FjaGVBY2Nlc3MgPSBmYWxzZTsNCiAgaWYgKG9wdGlvbnMuYmVmb3JlQ3JlYXRlKSB7DQogICAgY2FsbEhvb2skMShvcHRpb25zLmJlZm9yZUNyZWF0ZSwgaW5zdGFuY2UsICJiYyIpOw0KICB9DQogIGNvbnN0IHsNCiAgICAvLyBzdGF0ZQ0KICAgIGRhdGE6IGRhdGFPcHRpb25zLA0KICAgIGNvbXB1dGVkOiBjb21wdXRlZE9wdGlvbnMsDQogICAgbWV0aG9kcywNCiAgICB3YXRjaDogd2F0Y2hPcHRpb25zLA0KICAgIHByb3ZpZGU6IHByb3ZpZGVPcHRpb25zLA0KICAgIGluamVjdDogaW5qZWN0T3B0aW9ucywNCiAgICAvLyBsaWZlY3ljbGUNCiAgICBjcmVhdGVkLA0KICAgIGJlZm9yZU1vdW50LA0KICAgIG1vdW50ZWQsDQogICAgYmVmb3JlVXBkYXRlLA0KICAgIHVwZGF0ZWQsDQogICAgYWN0aXZhdGVkLA0KICAgIGRlYWN0aXZhdGVkLA0KICAgIGJlZm9yZURlc3Ryb3ksDQogICAgYmVmb3JlVW5tb3VudCwNCiAgICBkZXN0cm95ZWQsDQogICAgdW5tb3VudGVkLA0KICAgIHJlbmRlciwNCiAgICByZW5kZXJUcmFja2VkLA0KICAgIHJlbmRlclRyaWdnZXJlZCwNCiAgICBlcnJvckNhcHR1cmVkLA0KICAgIHNlcnZlclByZWZldGNoLA0KICAgIC8vIHB1YmxpYyBBUEkNCiAgICBleHBvc2UsDQogICAgaW5oZXJpdEF0dHJzLA0KICAgIC8vIGFzc2V0cw0KICAgIGNvbXBvbmVudHMsDQogICAgZGlyZWN0aXZlcywNCiAgICBmaWx0ZXJzDQogIH0gPSBvcHRpb25zOw0KICBjb25zdCBjaGVja0R1cGxpY2F0ZVByb3BlcnRpZXMgPSBjcmVhdGVEdXBsaWNhdGVDaGVja2VyKCkgOw0KICB7DQogICAgY29uc3QgW3Byb3BzT3B0aW9uc10gPSBpbnN0YW5jZS5wcm9wc09wdGlvbnM7DQogICAgaWYgKHByb3BzT3B0aW9ucykgew0KICAgICAgZm9yIChjb25zdCBrZXkgaW4gcHJvcHNPcHRpb25zKSB7DQogICAgICAgIGNoZWNrRHVwbGljYXRlUHJvcGVydGllcygiUHJvcHMiIC8qIFBST1BTICovLCBrZXkpOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICBpZiAoaW5qZWN0T3B0aW9ucykgew0KICAgIHJlc29sdmVJbmplY3Rpb25zKGluamVjdE9wdGlvbnMsIGN0eCwgY2hlY2tEdXBsaWNhdGVQcm9wZXJ0aWVzKTsNCiAgfQ0KICBpZiAobWV0aG9kcykgew0KICAgIGZvciAoY29uc3Qga2V5IGluIG1ldGhvZHMpIHsNCiAgICAgIGNvbnN0IG1ldGhvZEhhbmRsZXIgPSBtZXRob2RzW2tleV07DQogICAgICBpZiAoaXNGdW5jdGlvbihtZXRob2RIYW5kbGVyKSkgew0KICAgICAgICB7DQogICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGN0eCwga2V5LCB7DQogICAgICAgICAgICB2YWx1ZTogbWV0aG9kSGFuZGxlci5iaW5kKHB1YmxpY1RoaXMpLA0KICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLA0KICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSwNCiAgICAgICAgICAgIHdyaXRhYmxlOiB0cnVlDQogICAgICAgICAgfSk7DQogICAgICAgIH0NCiAgICAgICAgew0KICAgICAgICAgIGNoZWNrRHVwbGljYXRlUHJvcGVydGllcygiTWV0aG9kcyIgLyogTUVUSE9EUyAqLywga2V5KTsNCiAgICAgICAgfQ0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgd2FybiQxKA0KICAgICAgICAgIGBNZXRob2QgIiR7a2V5fSIgaGFzIHR5cGUgIiR7dHlwZW9mIG1ldGhvZEhhbmRsZXJ9IiBpbiB0aGUgY29tcG9uZW50IGRlZmluaXRpb24uIERpZCB5b3UgcmVmZXJlbmNlIHRoZSBmdW5jdGlvbiBjb3JyZWN0bHk/YA0KICAgICAgICApOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICBpZiAoZGF0YU9wdGlvbnMpIHsNCiAgICBpZiAoIWlzRnVuY3Rpb24oZGF0YU9wdGlvbnMpKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGBUaGUgZGF0YSBvcHRpb24gbXVzdCBiZSBhIGZ1bmN0aW9uLiBQbGFpbiBvYmplY3QgdXNhZ2UgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZC5gDQogICAgICApOw0KICAgIH0NCiAgICBjb25zdCBkYXRhID0gZGF0YU9wdGlvbnMuY2FsbChwdWJsaWNUaGlzLCBwdWJsaWNUaGlzKTsNCiAgICBpZiAoaXNQcm9taXNlKGRhdGEpKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGBkYXRhKCkgcmV0dXJuZWQgYSBQcm9taXNlIC0gbm90ZSBkYXRhKCkgY2Fubm90IGJlIGFzeW5jOyBJZiB5b3UgaW50ZW5kIHRvIHBlcmZvcm0gZGF0YSBmZXRjaGluZyBiZWZvcmUgY29tcG9uZW50IHJlbmRlcnMsIHVzZSBhc3luYyBzZXR1cCgpICsgPFN1c3BlbnNlPi5gDQogICAgICApOw0KICAgIH0NCiAgICBpZiAoIWlzT2JqZWN0KGRhdGEpKSB7DQogICAgICB3YXJuJDEoYGRhdGEoKSBzaG91bGQgcmV0dXJuIGFuIG9iamVjdC5gKTsNCiAgICB9IGVsc2Ugew0KICAgICAgaW5zdGFuY2UuZGF0YSA9IHJlYWN0aXZlKGRhdGEpOw0KICAgICAgew0KICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBkYXRhKSB7DQogICAgICAgICAgY2hlY2tEdXBsaWNhdGVQcm9wZXJ0aWVzKCJEYXRhIiAvKiBEQVRBICovLCBrZXkpOw0KICAgICAgICAgIGlmICghaXNSZXNlcnZlZFByZWZpeChrZXlbMF0pKSB7DQogICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY3R4LCBrZXksIHsNCiAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLA0KICAgICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLA0KICAgICAgICAgICAgICBnZXQ6ICgpID0+IGRhdGFba2V5XSwNCiAgICAgICAgICAgICAgc2V0OiBOT09QDQogICAgICAgICAgICB9KTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH0NCiAgc2hvdWxkQ2FjaGVBY2Nlc3MgPSB0cnVlOw0KICBpZiAoY29tcHV0ZWRPcHRpb25zKSB7DQogICAgZm9yIChjb25zdCBrZXkgaW4gY29tcHV0ZWRPcHRpb25zKSB7DQogICAgICBjb25zdCBvcHQgPSBjb21wdXRlZE9wdGlvbnNba2V5XTsNCiAgICAgIGNvbnN0IGdldCA9IGlzRnVuY3Rpb24ob3B0KSA/IG9wdC5iaW5kKHB1YmxpY1RoaXMsIHB1YmxpY1RoaXMpIDogaXNGdW5jdGlvbihvcHQuZ2V0KSA/IG9wdC5nZXQuYmluZChwdWJsaWNUaGlzLCBwdWJsaWNUaGlzKSA6IE5PT1A7DQogICAgICBpZiAoZ2V0ID09PSBOT09QKSB7DQogICAgICAgIHdhcm4kMShgQ29tcHV0ZWQgcHJvcGVydHkgIiR7a2V5fSIgaGFzIG5vIGdldHRlci5gKTsNCiAgICAgIH0NCiAgICAgIGNvbnN0IHNldCA9ICFpc0Z1bmN0aW9uKG9wdCkgJiYgaXNGdW5jdGlvbihvcHQuc2V0KSA/IG9wdC5zZXQuYmluZChwdWJsaWNUaGlzKSA6ICgpID0+IHsNCiAgICAgICAgd2FybiQxKA0KICAgICAgICAgIGBXcml0ZSBvcGVyYXRpb24gZmFpbGVkOiBjb21wdXRlZCBwcm9wZXJ0eSAiJHtrZXl9IiBpcyByZWFkb25seS5gDQogICAgICAgICk7DQogICAgICB9IDsNCiAgICAgIGNvbnN0IGMgPSBjb21wdXRlZCh7DQogICAgICAgIGdldCwNCiAgICAgICAgc2V0DQogICAgICB9KTsNCiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIGtleSwgew0KICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLA0KICAgICAgICBjb25maWd1cmFibGU6IHRydWUsDQogICAgICAgIGdldDogKCkgPT4gYy52YWx1ZSwNCiAgICAgICAgc2V0OiAodikgPT4gYy52YWx1ZSA9IHYNCiAgICAgIH0pOw0KICAgICAgew0KICAgICAgICBjaGVja0R1cGxpY2F0ZVByb3BlcnRpZXMoIkNvbXB1dGVkIiAvKiBDT01QVVRFRCAqLywga2V5KTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgaWYgKHdhdGNoT3B0aW9ucykgew0KICAgIGZvciAoY29uc3Qga2V5IGluIHdhdGNoT3B0aW9ucykgew0KICAgICAgY3JlYXRlV2F0Y2hlcih3YXRjaE9wdGlvbnNba2V5XSwgY3R4LCBwdWJsaWNUaGlzLCBrZXkpOw0KICAgIH0NCiAgfQ0KICBpZiAocHJvdmlkZU9wdGlvbnMpIHsNCiAgICBjb25zdCBwcm92aWRlcyA9IGlzRnVuY3Rpb24ocHJvdmlkZU9wdGlvbnMpID8gcHJvdmlkZU9wdGlvbnMuY2FsbChwdWJsaWNUaGlzKSA6IHByb3ZpZGVPcHRpb25zOw0KICAgIFJlZmxlY3Qub3duS2V5cyhwcm92aWRlcykuZm9yRWFjaCgoa2V5KSA9PiB7DQogICAgICBwcm92aWRlKGtleSwgcHJvdmlkZXNba2V5XSk7DQogICAgfSk7DQogIH0NCiAgaWYgKGNyZWF0ZWQpIHsNCiAgICBjYWxsSG9vayQxKGNyZWF0ZWQsIGluc3RhbmNlLCAiYyIpOw0KICB9DQogIGZ1bmN0aW9uIHJlZ2lzdGVyTGlmZWN5Y2xlSG9vayhyZWdpc3RlciwgaG9vaykgew0KICAgIGlmIChpc0FycmF5KGhvb2spKSB7DQogICAgICBob29rLmZvckVhY2goKF9ob29rKSA9PiByZWdpc3RlcihfaG9vay5iaW5kKHB1YmxpY1RoaXMpKSk7DQogICAgfSBlbHNlIGlmIChob29rKSB7DQogICAgICByZWdpc3Rlcihob29rLmJpbmQocHVibGljVGhpcykpOw0KICAgIH0NCiAgfQ0KICByZWdpc3RlckxpZmVjeWNsZUhvb2sob25CZWZvcmVNb3VudCwgYmVmb3JlTW91bnQpOw0KICByZWdpc3RlckxpZmVjeWNsZUhvb2sob25Nb3VudGVkLCBtb3VudGVkKTsNCiAgcmVnaXN0ZXJMaWZlY3ljbGVIb29rKG9uQmVmb3JlVXBkYXRlLCBiZWZvcmVVcGRhdGUpOw0KICByZWdpc3RlckxpZmVjeWNsZUhvb2sob25VcGRhdGVkLCB1cGRhdGVkKTsNCiAgcmVnaXN0ZXJMaWZlY3ljbGVIb29rKG9uQWN0aXZhdGVkLCBhY3RpdmF0ZWQpOw0KICByZWdpc3RlckxpZmVjeWNsZUhvb2sob25EZWFjdGl2YXRlZCwgZGVhY3RpdmF0ZWQpOw0KICByZWdpc3RlckxpZmVjeWNsZUhvb2sob25FcnJvckNhcHR1cmVkLCBlcnJvckNhcHR1cmVkKTsNCiAgcmVnaXN0ZXJMaWZlY3ljbGVIb29rKG9uUmVuZGVyVHJhY2tlZCwgcmVuZGVyVHJhY2tlZCk7DQogIHJlZ2lzdGVyTGlmZWN5Y2xlSG9vayhvblJlbmRlclRyaWdnZXJlZCwgcmVuZGVyVHJpZ2dlcmVkKTsNCiAgcmVnaXN0ZXJMaWZlY3ljbGVIb29rKG9uQmVmb3JlVW5tb3VudCwgYmVmb3JlVW5tb3VudCk7DQogIHJlZ2lzdGVyTGlmZWN5Y2xlSG9vayhvblVubW91bnRlZCwgdW5tb3VudGVkKTsNCiAgcmVnaXN0ZXJMaWZlY3ljbGVIb29rKG9uU2VydmVyUHJlZmV0Y2gsIHNlcnZlclByZWZldGNoKTsNCiAgaWYgKGlzQXJyYXkoZXhwb3NlKSkgew0KICAgIGlmIChleHBvc2UubGVuZ3RoKSB7DQogICAgICBjb25zdCBleHBvc2VkID0gaW5zdGFuY2UuZXhwb3NlZCB8fCAoaW5zdGFuY2UuZXhwb3NlZCA9IHt9KTsNCiAgICAgIGV4cG9zZS5mb3JFYWNoKChrZXkpID0+IHsNCiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9zZWQsIGtleSwgew0KICAgICAgICAgIGdldDogKCkgPT4gcHVibGljVGhpc1trZXldLA0KICAgICAgICAgIHNldDogKHZhbCkgPT4gcHVibGljVGhpc1trZXldID0gdmFsDQogICAgICAgIH0pOw0KICAgICAgfSk7DQogICAgfSBlbHNlIGlmICghaW5zdGFuY2UuZXhwb3NlZCkgew0KICAgICAgaW5zdGFuY2UuZXhwb3NlZCA9IHt9Ow0KICAgIH0NCiAgfQ0KICBpZiAocmVuZGVyICYmIGluc3RhbmNlLnJlbmRlciA9PT0gTk9PUCkgew0KICAgIGluc3RhbmNlLnJlbmRlciA9IHJlbmRlcjsNCiAgfQ0KICBpZiAoaW5oZXJpdEF0dHJzICE9IG51bGwpIHsNCiAgICBpbnN0YW5jZS5pbmhlcml0QXR0cnMgPSBpbmhlcml0QXR0cnM7DQogIH0NCiAgaWYgKGNvbXBvbmVudHMpIGluc3RhbmNlLmNvbXBvbmVudHMgPSBjb21wb25lbnRzOw0KICBpZiAoZGlyZWN0aXZlcykgaW5zdGFuY2UuZGlyZWN0aXZlcyA9IGRpcmVjdGl2ZXM7DQogIGlmIChzZXJ2ZXJQcmVmZXRjaCkgew0KICAgIG1hcmtBc3luY0JvdW5kYXJ5KGluc3RhbmNlKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gcmVzb2x2ZUluamVjdGlvbnMoaW5qZWN0T3B0aW9ucywgY3R4LCBjaGVja0R1cGxpY2F0ZVByb3BlcnRpZXMgPSBOT09QKSB7DQogIGlmIChpc0FycmF5KGluamVjdE9wdGlvbnMpKSB7DQogICAgaW5qZWN0T3B0aW9ucyA9IG5vcm1hbGl6ZUluamVjdChpbmplY3RPcHRpb25zKTsNCiAgfQ0KICBmb3IgKGNvbnN0IGtleSBpbiBpbmplY3RPcHRpb25zKSB7DQogICAgY29uc3Qgb3B0ID0gaW5qZWN0T3B0aW9uc1trZXldOw0KICAgIGxldCBpbmplY3RlZDsNCiAgICBpZiAoaXNPYmplY3Qob3B0KSkgew0KICAgICAgaWYgKCJkZWZhdWx0IiBpbiBvcHQpIHsNCiAgICAgICAgaW5qZWN0ZWQgPSBpbmplY3QoDQogICAgICAgICAgb3B0LmZyb20gfHwga2V5LA0KICAgICAgICAgIG9wdC5kZWZhdWx0LA0KICAgICAgICAgIHRydWUNCiAgICAgICAgKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGluamVjdGVkID0gaW5qZWN0KG9wdC5mcm9tIHx8IGtleSk7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIGluamVjdGVkID0gaW5qZWN0KG9wdCk7DQogICAgfQ0KICAgIGlmIChpc1JlZihpbmplY3RlZCkpIHsNCiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIGtleSwgew0KICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLA0KICAgICAgICBjb25maWd1cmFibGU6IHRydWUsDQogICAgICAgIGdldDogKCkgPT4gaW5qZWN0ZWQudmFsdWUsDQogICAgICAgIHNldDogKHYpID0+IGluamVjdGVkLnZhbHVlID0gdg0KICAgICAgfSk7DQogICAgfSBlbHNlIHsNCiAgICAgIGN0eFtrZXldID0gaW5qZWN0ZWQ7DQogICAgfQ0KICAgIHsNCiAgICAgIGNoZWNrRHVwbGljYXRlUHJvcGVydGllcygiSW5qZWN0IiAvKiBJTkpFQ1QgKi8sIGtleSk7DQogICAgfQ0KICB9DQp9DQpmdW5jdGlvbiBjYWxsSG9vayQxKGhvb2ssIGluc3RhbmNlLCB0eXBlKSB7DQogIGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nKA0KICAgIGlzQXJyYXkoaG9vaykgPyBob29rLm1hcCgoaCkgPT4gaC5iaW5kKGluc3RhbmNlLnByb3h5KSkgOiBob29rLmJpbmQoaW5zdGFuY2UucHJveHkpLA0KICAgIGluc3RhbmNlLA0KICAgIHR5cGUNCiAgKTsNCn0NCmZ1bmN0aW9uIGNyZWF0ZVdhdGNoZXIocmF3LCBjdHgsIHB1YmxpY1RoaXMsIGtleSkgew0KICBsZXQgZ2V0dGVyID0ga2V5LmluY2x1ZGVzKCIuIikgPyBjcmVhdGVQYXRoR2V0dGVyKHB1YmxpY1RoaXMsIGtleSkgOiAoKSA9PiBwdWJsaWNUaGlzW2tleV07DQogIGlmIChpc1N0cmluZyhyYXcpKSB7DQogICAgY29uc3QgaGFuZGxlciA9IGN0eFtyYXddOw0KICAgIGlmIChpc0Z1bmN0aW9uKGhhbmRsZXIpKSB7DQogICAgICB7DQogICAgICAgIHdhdGNoKGdldHRlciwgaGFuZGxlcik7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIHdhcm4kMShgSW52YWxpZCB3YXRjaCBoYW5kbGVyIHNwZWNpZmllZCBieSBrZXkgIiR7cmF3fSJgLCBoYW5kbGVyKTsNCiAgICB9DQogIH0gZWxzZSBpZiAoaXNGdW5jdGlvbihyYXcpKSB7DQogICAgew0KICAgICAgd2F0Y2goZ2V0dGVyLCByYXcuYmluZChwdWJsaWNUaGlzKSk7DQogICAgfQ0KICB9IGVsc2UgaWYgKGlzT2JqZWN0KHJhdykpIHsNCiAgICBpZiAoaXNBcnJheShyYXcpKSB7DQogICAgICByYXcuZm9yRWFjaCgocikgPT4gY3JlYXRlV2F0Y2hlcihyLCBjdHgsIHB1YmxpY1RoaXMsIGtleSkpOw0KICAgIH0gZWxzZSB7DQogICAgICBjb25zdCBoYW5kbGVyID0gaXNGdW5jdGlvbihyYXcuaGFuZGxlcikgPyByYXcuaGFuZGxlci5iaW5kKHB1YmxpY1RoaXMpIDogY3R4W3Jhdy5oYW5kbGVyXTsNCiAgICAgIGlmIChpc0Z1bmN0aW9uKGhhbmRsZXIpKSB7DQogICAgICAgIHdhdGNoKGdldHRlciwgaGFuZGxlciwgcmF3KTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHdhcm4kMShgSW52YWxpZCB3YXRjaCBoYW5kbGVyIHNwZWNpZmllZCBieSBrZXkgIiR7cmF3LmhhbmRsZXJ9ImAsIGhhbmRsZXIpOw0KICAgICAgfQ0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICB3YXJuJDEoYEludmFsaWQgd2F0Y2ggb3B0aW9uOiAiJHtrZXl9ImAsIHJhdyk7DQogIH0NCn0NCmZ1bmN0aW9uIHJlc29sdmVNZXJnZWRPcHRpb25zKGluc3RhbmNlKSB7DQogIGNvbnN0IGJhc2UgPSBpbnN0YW5jZS50eXBlOw0KICBjb25zdCB7IG1peGlucywgZXh0ZW5kczogZXh0ZW5kc09wdGlvbnMgfSA9IGJhc2U7DQogIGNvbnN0IHsNCiAgICBtaXhpbnM6IGdsb2JhbE1peGlucywNCiAgICBvcHRpb25zQ2FjaGU6IGNhY2hlLA0KICAgIGNvbmZpZzogeyBvcHRpb25NZXJnZVN0cmF0ZWdpZXMgfQ0KICB9ID0gaW5zdGFuY2UuYXBwQ29udGV4dDsNCiAgY29uc3QgY2FjaGVkID0gY2FjaGUuZ2V0KGJhc2UpOw0KICBsZXQgcmVzb2x2ZWQ7DQogIGlmIChjYWNoZWQpIHsNCiAgICByZXNvbHZlZCA9IGNhY2hlZDsNCiAgfSBlbHNlIGlmICghZ2xvYmFsTWl4aW5zLmxlbmd0aCAmJiAhbWl4aW5zICYmICFleHRlbmRzT3B0aW9ucykgew0KICAgIHsNCiAgICAgIHJlc29sdmVkID0gYmFzZTsNCiAgICB9DQogIH0gZWxzZSB7DQogICAgcmVzb2x2ZWQgPSB7fTsNCiAgICBpZiAoZ2xvYmFsTWl4aW5zLmxlbmd0aCkgew0KICAgICAgZ2xvYmFsTWl4aW5zLmZvckVhY2goDQogICAgICAgIChtKSA9PiBtZXJnZU9wdGlvbnMocmVzb2x2ZWQsIG0sIG9wdGlvbk1lcmdlU3RyYXRlZ2llcywgdHJ1ZSkNCiAgICAgICk7DQogICAgfQ0KICAgIG1lcmdlT3B0aW9ucyhyZXNvbHZlZCwgYmFzZSwgb3B0aW9uTWVyZ2VTdHJhdGVnaWVzKTsNCiAgfQ0KICBpZiAoaXNPYmplY3QoYmFzZSkpIHsNCiAgICBjYWNoZS5zZXQoYmFzZSwgcmVzb2x2ZWQpOw0KICB9DQogIHJldHVybiByZXNvbHZlZDsNCn0NCmZ1bmN0aW9uIG1lcmdlT3B0aW9ucyh0bywgZnJvbSwgc3RyYXRzLCBhc01peGluID0gZmFsc2UpIHsNCiAgY29uc3QgeyBtaXhpbnMsIGV4dGVuZHM6IGV4dGVuZHNPcHRpb25zIH0gPSBmcm9tOw0KICBpZiAoZXh0ZW5kc09wdGlvbnMpIHsNCiAgICBtZXJnZU9wdGlvbnModG8sIGV4dGVuZHNPcHRpb25zLCBzdHJhdHMsIHRydWUpOw0KICB9DQogIGlmIChtaXhpbnMpIHsNCiAgICBtaXhpbnMuZm9yRWFjaCgNCiAgICAgIChtKSA9PiBtZXJnZU9wdGlvbnModG8sIG0sIHN0cmF0cywgdHJ1ZSkNCiAgICApOw0KICB9DQogIGZvciAoY29uc3Qga2V5IGluIGZyb20pIHsNCiAgICBpZiAoYXNNaXhpbiAmJiBrZXkgPT09ICJleHBvc2UiKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGAiZXhwb3NlIiBvcHRpb24gaXMgaWdub3JlZCB3aGVuIGRlY2xhcmVkIGluIG1peGlucyBvciBleHRlbmRzLiBJdCBzaG91bGQgb25seSBiZSBkZWNsYXJlZCBpbiB0aGUgYmFzZSBjb21wb25lbnQgaXRzZWxmLmANCiAgICAgICk7DQogICAgfSBlbHNlIHsNCiAgICAgIGNvbnN0IHN0cmF0ID0gaW50ZXJuYWxPcHRpb25NZXJnZVN0cmF0c1trZXldIHx8IHN0cmF0cyAmJiBzdHJhdHNba2V5XTsNCiAgICAgIHRvW2tleV0gPSBzdHJhdCA/IHN0cmF0KHRvW2tleV0sIGZyb21ba2V5XSkgOiBmcm9tW2tleV07DQogICAgfQ0KICB9DQogIHJldHVybiB0bzsNCn0NCmNvbnN0IGludGVybmFsT3B0aW9uTWVyZ2VTdHJhdHMgPSB7DQogIGRhdGE6IG1lcmdlRGF0YUZuLA0KICBwcm9wczogbWVyZ2VFbWl0c09yUHJvcHNPcHRpb25zLA0KICBlbWl0czogbWVyZ2VFbWl0c09yUHJvcHNPcHRpb25zLA0KICAvLyBvYmplY3RzDQogIG1ldGhvZHM6IG1lcmdlT2JqZWN0T3B0aW9ucywNCiAgY29tcHV0ZWQ6IG1lcmdlT2JqZWN0T3B0aW9ucywNCiAgLy8gbGlmZWN5Y2xlDQogIGJlZm9yZUNyZWF0ZTogbWVyZ2VBc0FycmF5LA0KICBjcmVhdGVkOiBtZXJnZUFzQXJyYXksDQogIGJlZm9yZU1vdW50OiBtZXJnZUFzQXJyYXksDQogIG1vdW50ZWQ6IG1lcmdlQXNBcnJheSwNCiAgYmVmb3JlVXBkYXRlOiBtZXJnZUFzQXJyYXksDQogIHVwZGF0ZWQ6IG1lcmdlQXNBcnJheSwNCiAgYmVmb3JlRGVzdHJveTogbWVyZ2VBc0FycmF5LA0KICBiZWZvcmVVbm1vdW50OiBtZXJnZUFzQXJyYXksDQogIGRlc3Ryb3llZDogbWVyZ2VBc0FycmF5LA0KICB1bm1vdW50ZWQ6IG1lcmdlQXNBcnJheSwNCiAgYWN0aXZhdGVkOiBtZXJnZUFzQXJyYXksDQogIGRlYWN0aXZhdGVkOiBtZXJnZUFzQXJyYXksDQogIGVycm9yQ2FwdHVyZWQ6IG1lcmdlQXNBcnJheSwNCiAgc2VydmVyUHJlZmV0Y2g6IG1lcmdlQXNBcnJheSwNCiAgLy8gYXNzZXRzDQogIGNvbXBvbmVudHM6IG1lcmdlT2JqZWN0T3B0aW9ucywNCiAgZGlyZWN0aXZlczogbWVyZ2VPYmplY3RPcHRpb25zLA0KICAvLyB3YXRjaA0KICB3YXRjaDogbWVyZ2VXYXRjaE9wdGlvbnMsDQogIC8vIHByb3ZpZGUgLyBpbmplY3QNCiAgcHJvdmlkZTogbWVyZ2VEYXRhRm4sDQogIGluamVjdDogbWVyZ2VJbmplY3QNCn07DQpmdW5jdGlvbiBtZXJnZURhdGFGbih0bywgZnJvbSkgew0KICBpZiAoIWZyb20pIHsNCiAgICByZXR1cm4gdG87DQogIH0NCiAgaWYgKCF0bykgew0KICAgIHJldHVybiBmcm9tOw0KICB9DQogIHJldHVybiBmdW5jdGlvbiBtZXJnZWREYXRhRm4oKSB7DQogICAgcmV0dXJuIChleHRlbmQpKA0KICAgICAgaXNGdW5jdGlvbih0bykgPyB0by5jYWxsKHRoaXMsIHRoaXMpIDogdG8sDQogICAgICBpc0Z1bmN0aW9uKGZyb20pID8gZnJvbS5jYWxsKHRoaXMsIHRoaXMpIDogZnJvbQ0KICAgICk7DQogIH07DQp9DQpmdW5jdGlvbiBtZXJnZUluamVjdCh0bywgZnJvbSkgew0KICByZXR1cm4gbWVyZ2VPYmplY3RPcHRpb25zKG5vcm1hbGl6ZUluamVjdCh0byksIG5vcm1hbGl6ZUluamVjdChmcm9tKSk7DQp9DQpmdW5jdGlvbiBub3JtYWxpemVJbmplY3QocmF3KSB7DQogIGlmIChpc0FycmF5KHJhdykpIHsNCiAgICBjb25zdCByZXMgPSB7fTsNCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhdy5sZW5ndGg7IGkrKykgew0KICAgICAgcmVzW3Jhd1tpXV0gPSByYXdbaV07DQogICAgfQ0KICAgIHJldHVybiByZXM7DQogIH0NCiAgcmV0dXJuIHJhdzsNCn0NCmZ1bmN0aW9uIG1lcmdlQXNBcnJheSh0bywgZnJvbSkgew0KICByZXR1cm4gdG8gPyBbLi4ubmV3IFNldChbXS5jb25jYXQodG8sIGZyb20pKV0gOiBmcm9tOw0KfQ0KZnVuY3Rpb24gbWVyZ2VPYmplY3RPcHRpb25zKHRvLCBmcm9tKSB7DQogIHJldHVybiB0byA/IGV4dGVuZCgvKiBAX19QVVJFX18gKi8gT2JqZWN0LmNyZWF0ZShudWxsKSwgdG8sIGZyb20pIDogZnJvbTsNCn0NCmZ1bmN0aW9uIG1lcmdlRW1pdHNPclByb3BzT3B0aW9ucyh0bywgZnJvbSkgew0KICBpZiAodG8pIHsNCiAgICBpZiAoaXNBcnJheSh0bykgJiYgaXNBcnJheShmcm9tKSkgew0KICAgICAgcmV0dXJuIFsuLi4vKiBAX19QVVJFX18gKi8gbmV3IFNldChbLi4udG8sIC4uLmZyb21dKV07DQogICAgfQ0KICAgIHJldHVybiBleHRlbmQoDQogICAgICAvKiBAX19QVVJFX18gKi8gT2JqZWN0LmNyZWF0ZShudWxsKSwNCiAgICAgIG5vcm1hbGl6ZVByb3BzT3JFbWl0cyh0byksDQogICAgICBub3JtYWxpemVQcm9wc09yRW1pdHMoZnJvbSAhPSBudWxsID8gZnJvbSA6IHt9KQ0KICAgICk7DQogIH0gZWxzZSB7DQogICAgcmV0dXJuIGZyb207DQogIH0NCn0NCmZ1bmN0aW9uIG1lcmdlV2F0Y2hPcHRpb25zKHRvLCBmcm9tKSB7DQogIGlmICghdG8pIHJldHVybiBmcm9tOw0KICBpZiAoIWZyb20pIHJldHVybiB0bzsNCiAgY29uc3QgbWVyZ2VkID0gZXh0ZW5kKC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuY3JlYXRlKG51bGwpLCB0byk7DQogIGZvciAoY29uc3Qga2V5IGluIGZyb20pIHsNCiAgICBtZXJnZWRba2V5XSA9IG1lcmdlQXNBcnJheSh0b1trZXldLCBmcm9tW2tleV0pOw0KICB9DQogIHJldHVybiBtZXJnZWQ7DQp9DQoNCmZ1bmN0aW9uIGNyZWF0ZUFwcENvbnRleHQoKSB7DQogIHJldHVybiB7DQogICAgYXBwOiBudWxsLA0KICAgIGNvbmZpZzogew0KICAgICAgaXNOYXRpdmVUYWc6IE5PLA0KICAgICAgcGVyZm9ybWFuY2U6IGZhbHNlLA0KICAgICAgZ2xvYmFsUHJvcGVydGllczoge30sDQogICAgICBvcHRpb25NZXJnZVN0cmF0ZWdpZXM6IHt9LA0KICAgICAgZXJyb3JIYW5kbGVyOiB2b2lkIDAsDQogICAgICB3YXJuSGFuZGxlcjogdm9pZCAwLA0KICAgICAgY29tcGlsZXJPcHRpb25zOiB7fQ0KICAgIH0sDQogICAgbWl4aW5zOiBbXSwNCiAgICBjb21wb25lbnRzOiB7fSwNCiAgICBkaXJlY3RpdmVzOiB7fSwNCiAgICBwcm92aWRlczogLyogQF9fUFVSRV9fICovIE9iamVjdC5jcmVhdGUobnVsbCksDQogICAgb3B0aW9uc0NhY2hlOiAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtNYXAoKSwNCiAgICBwcm9wc0NhY2hlOiAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtNYXAoKSwNCiAgICBlbWl0c0NhY2hlOiAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtNYXAoKQ0KICB9Ow0KfQ0KbGV0IHVpZCQxID0gMDsNCmZ1bmN0aW9uIGNyZWF0ZUFwcEFQSShyZW5kZXIsIGh5ZHJhdGUpIHsNCiAgcmV0dXJuIGZ1bmN0aW9uIGNyZWF0ZUFwcChyb290Q29tcG9uZW50LCByb290UHJvcHMgPSBudWxsKSB7DQogICAgaWYgKCFpc0Z1bmN0aW9uKHJvb3RDb21wb25lbnQpKSB7DQogICAgICByb290Q29tcG9uZW50ID0gZXh0ZW5kKHt9LCByb290Q29tcG9uZW50KTsNCiAgICB9DQogICAgaWYgKHJvb3RQcm9wcyAhPSBudWxsICYmICFpc09iamVjdChyb290UHJvcHMpKSB7DQogICAgICB3YXJuJDEoYHJvb3QgcHJvcHMgcGFzc2VkIHRvIGFwcC5tb3VudCgpIG11c3QgYmUgYW4gb2JqZWN0LmApOw0KICAgICAgcm9vdFByb3BzID0gbnVsbDsNCiAgICB9DQogICAgY29uc3QgY29udGV4dCA9IGNyZWF0ZUFwcENvbnRleHQoKTsNCiAgICBjb25zdCBpbnN0YWxsZWRQbHVnaW5zID0gLyogQF9fUFVSRV9fICovIG5ldyBXZWFrU2V0KCk7DQogICAgY29uc3QgcGx1Z2luQ2xlYW51cEZucyA9IFtdOw0KICAgIGxldCBpc01vdW50ZWQgPSBmYWxzZTsNCiAgICBjb25zdCBhcHAgPSBjb250ZXh0LmFwcCA9IHsNCiAgICAgIF91aWQ6IHVpZCQxKyssDQogICAgICBfY29tcG9uZW50OiByb290Q29tcG9uZW50LA0KICAgICAgX3Byb3BzOiByb290UHJvcHMsDQogICAgICBfY29udGFpbmVyOiBudWxsLA0KICAgICAgX2NvbnRleHQ6IGNvbnRleHQsDQogICAgICBfaW5zdGFuY2U6IG51bGwsDQogICAgICB2ZXJzaW9uLA0KICAgICAgZ2V0IGNvbmZpZygpIHsNCiAgICAgICAgcmV0dXJuIGNvbnRleHQuY29uZmlnOw0KICAgICAgfSwNCiAgICAgIHNldCBjb25maWcodikgew0KICAgICAgICB7DQogICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgYGFwcC5jb25maWcgY2Fubm90IGJlIHJlcGxhY2VkLiBNb2RpZnkgaW5kaXZpZHVhbCBvcHRpb25zIGluc3RlYWQuYA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH0sDQogICAgICB1c2UocGx1Z2luLCAuLi5vcHRpb25zKSB7DQogICAgICAgIGlmIChpbnN0YWxsZWRQbHVnaW5zLmhhcyhwbHVnaW4pKSB7DQogICAgICAgICAgd2FybiQxKGBQbHVnaW4gaGFzIGFscmVhZHkgYmVlbiBhcHBsaWVkIHRvIHRhcmdldCBhcHAuYCk7DQogICAgICAgIH0gZWxzZSBpZiAocGx1Z2luICYmIGlzRnVuY3Rpb24ocGx1Z2luLmluc3RhbGwpKSB7DQogICAgICAgICAgaW5zdGFsbGVkUGx1Z2lucy5hZGQocGx1Z2luKTsNCiAgICAgICAgICBwbHVnaW4uaW5zdGFsbChhcHAsIC4uLm9wdGlvbnMpOw0KICAgICAgICB9IGVsc2UgaWYgKGlzRnVuY3Rpb24ocGx1Z2luKSkgew0KICAgICAgICAgIGluc3RhbGxlZFBsdWdpbnMuYWRkKHBsdWdpbik7DQogICAgICAgICAgcGx1Z2luKGFwcCwgLi4ub3B0aW9ucyk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgYEEgcGx1Z2luIG11c3QgZWl0aGVyIGJlIGEgZnVuY3Rpb24gb3IgYW4gb2JqZWN0IHdpdGggYW4gImluc3RhbGwiIGZ1bmN0aW9uLmANCiAgICAgICAgICApOw0KICAgICAgICB9DQogICAgICAgIHJldHVybiBhcHA7DQogICAgICB9LA0KICAgICAgbWl4aW4obWl4aW4pIHsNCiAgICAgICAgew0KICAgICAgICAgIGlmICghY29udGV4dC5taXhpbnMuaW5jbHVkZXMobWl4aW4pKSB7DQogICAgICAgICAgICBjb250ZXh0Lm1peGlucy5wdXNoKG1peGluKTsNCiAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgICAiTWl4aW4gaGFzIGFscmVhZHkgYmVlbiBhcHBsaWVkIHRvIHRhcmdldCBhcHAiICsgKG1peGluLm5hbWUgPyBgOiAke21peGluLm5hbWV9YCA6ICIiKQ0KICAgICAgICAgICAgKTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIGFwcDsNCiAgICAgIH0sDQogICAgICBjb21wb25lbnQobmFtZSwgY29tcG9uZW50KSB7DQogICAgICAgIHsNCiAgICAgICAgICB2YWxpZGF0ZUNvbXBvbmVudE5hbWUobmFtZSwgY29udGV4dC5jb25maWcpOw0KICAgICAgICB9DQogICAgICAgIGlmICghY29tcG9uZW50KSB7DQogICAgICAgICAgcmV0dXJuIGNvbnRleHQuY29tcG9uZW50c1tuYW1lXTsNCiAgICAgICAgfQ0KICAgICAgICBpZiAoY29udGV4dC5jb21wb25lbnRzW25hbWVdKSB7DQogICAgICAgICAgd2FybiQxKGBDb21wb25lbnQgIiR7bmFtZX0iIGhhcyBhbHJlYWR5IGJlZW4gcmVnaXN0ZXJlZCBpbiB0YXJnZXQgYXBwLmApOw0KICAgICAgICB9DQogICAgICAgIGNvbnRleHQuY29tcG9uZW50c1tuYW1lXSA9IGNvbXBvbmVudDsNCiAgICAgICAgcmV0dXJuIGFwcDsNCiAgICAgIH0sDQogICAgICBkaXJlY3RpdmUobmFtZSwgZGlyZWN0aXZlKSB7DQogICAgICAgIHsNCiAgICAgICAgICB2YWxpZGF0ZURpcmVjdGl2ZU5hbWUobmFtZSk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKCFkaXJlY3RpdmUpIHsNCiAgICAgICAgICByZXR1cm4gY29udGV4dC5kaXJlY3RpdmVzW25hbWVdOw0KICAgICAgICB9DQogICAgICAgIGlmIChjb250ZXh0LmRpcmVjdGl2ZXNbbmFtZV0pIHsNCiAgICAgICAgICB3YXJuJDEoYERpcmVjdGl2ZSAiJHtuYW1lfSIgaGFzIGFscmVhZHkgYmVlbiByZWdpc3RlcmVkIGluIHRhcmdldCBhcHAuYCk7DQogICAgICAgIH0NCiAgICAgICAgY29udGV4dC5kaXJlY3RpdmVzW25hbWVdID0gZGlyZWN0aXZlOw0KICAgICAgICByZXR1cm4gYXBwOw0KICAgICAgfSwNCiAgICAgIG1vdW50KHJvb3RDb250YWluZXIsIGlzSHlkcmF0ZSwgbmFtZXNwYWNlKSB7DQogICAgICAgIGlmICghaXNNb3VudGVkKSB7DQogICAgICAgICAgaWYgKHJvb3RDb250YWluZXIuX192dWVfYXBwX18pIHsNCiAgICAgICAgICAgIHdhcm4kMSgNCiAgICAgICAgICAgICAgYFRoZXJlIGlzIGFscmVhZHkgYW4gYXBwIGluc3RhbmNlIG1vdW50ZWQgb24gdGhlIGhvc3QgY29udGFpbmVyLg0KIElmIHlvdSB3YW50IHRvIG1vdW50IGFub3RoZXIgYXBwIG9uIHRoZSBzYW1lIGhvc3QgY29udGFpbmVyLCB5b3UgbmVlZCB0byB1bm1vdW50IHRoZSBwcmV2aW91cyBhcHAgYnkgY2FsbGluZyBcYGFwcC51bm1vdW50KClcYCBmaXJzdC5gDQogICAgICAgICAgICApOw0KICAgICAgICAgIH0NCiAgICAgICAgICBjb25zdCB2bm9kZSA9IGFwcC5fY2VWTm9kZSB8fCBjcmVhdGVWTm9kZShyb290Q29tcG9uZW50LCByb290UHJvcHMpOw0KICAgICAgICAgIHZub2RlLmFwcENvbnRleHQgPSBjb250ZXh0Ow0KICAgICAgICAgIGlmIChuYW1lc3BhY2UgPT09IHRydWUpIHsNCiAgICAgICAgICAgIG5hbWVzcGFjZSA9ICJzdmciOw0KICAgICAgICAgIH0gZWxzZSBpZiAobmFtZXNwYWNlID09PSBmYWxzZSkgew0KICAgICAgICAgICAgbmFtZXNwYWNlID0gdm9pZCAwOw0KICAgICAgICAgIH0NCiAgICAgICAgICB7DQogICAgICAgICAgICBjb250ZXh0LnJlbG9hZCA9ICgpID0+IHsNCiAgICAgICAgICAgICAgY29uc3QgY2xvbmVkID0gY2xvbmVWTm9kZSh2bm9kZSk7DQogICAgICAgICAgICAgIGNsb25lZC5lbCA9IG51bGw7DQogICAgICAgICAgICAgIHJlbmRlcihjbG9uZWQsIHJvb3RDb250YWluZXIsIG5hbWVzcGFjZSk7DQogICAgICAgICAgICB9Ow0KICAgICAgICAgIH0NCiAgICAgICAgICBpZiAoaXNIeWRyYXRlICYmIGh5ZHJhdGUpIHsNCiAgICAgICAgICAgIGh5ZHJhdGUodm5vZGUsIHJvb3RDb250YWluZXIpOw0KICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICByZW5kZXIodm5vZGUsIHJvb3RDb250YWluZXIsIG5hbWVzcGFjZSk7DQogICAgICAgICAgfQ0KICAgICAgICAgIGlzTW91bnRlZCA9IHRydWU7DQogICAgICAgICAgYXBwLl9jb250YWluZXIgPSByb290Q29udGFpbmVyOw0KICAgICAgICAgIHJvb3RDb250YWluZXIuX192dWVfYXBwX18gPSBhcHA7DQogICAgICAgICAgew0KICAgICAgICAgICAgYXBwLl9pbnN0YW5jZSA9IHZub2RlLmNvbXBvbmVudDsNCiAgICAgICAgICAgIGRldnRvb2xzSW5pdEFwcChhcHAsIHZlcnNpb24pOw0KICAgICAgICAgIH0NCiAgICAgICAgICByZXR1cm4gZ2V0Q29tcG9uZW50UHVibGljSW5zdGFuY2Uodm5vZGUuY29tcG9uZW50KTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICB3YXJuJDEoDQogICAgICAgICAgICBgQXBwIGhhcyBhbHJlYWR5IGJlZW4gbW91bnRlZC4NCklmIHlvdSB3YW50IHRvIHJlbW91bnQgdGhlIHNhbWUgYXBwLCBtb3ZlIHlvdXIgYXBwIGNyZWF0aW9uIGxvZ2ljIGludG8gYSBmYWN0b3J5IGZ1bmN0aW9uIGFuZCBjcmVhdGUgZnJlc2ggYXBwIGluc3RhbmNlcyBmb3IgZWFjaCBtb3VudCAtIGUuZy4gXGBjb25zdCBjcmVhdGVNeUFwcCA9ICgpID0+IGNyZWF0ZUFwcChBcHApXGBgDQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgfSwNCiAgICAgIG9uVW5tb3VudChjbGVhbnVwRm4pIHsNCiAgICAgICAgaWYgKHR5cGVvZiBjbGVhbnVwRm4gIT09ICJmdW5jdGlvbiIpIHsNCiAgICAgICAgICB3YXJuJDEoDQogICAgICAgICAgICBgRXhwZWN0ZWQgZnVuY3Rpb24gYXMgZmlyc3QgYXJndW1lbnQgdG8gYXBwLm9uVW5tb3VudCgpLCBidXQgZ290ICR7dHlwZW9mIGNsZWFudXBGbn1gDQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgICBwbHVnaW5DbGVhbnVwRm5zLnB1c2goY2xlYW51cEZuKTsNCiAgICAgIH0sDQogICAgICB1bm1vdW50KCkgew0KICAgICAgICBpZiAoaXNNb3VudGVkKSB7DQogICAgICAgICAgY2FsbFdpdGhBc3luY0Vycm9ySGFuZGxpbmcoDQogICAgICAgICAgICBwbHVnaW5DbGVhbnVwRm5zLA0KICAgICAgICAgICAgYXBwLl9pbnN0YW5jZSwNCiAgICAgICAgICAgIDE2DQogICAgICAgICAgKTsNCiAgICAgICAgICByZW5kZXIobnVsbCwgYXBwLl9jb250YWluZXIpOw0KICAgICAgICAgIHsNCiAgICAgICAgICAgIGFwcC5faW5zdGFuY2UgPSBudWxsOw0KICAgICAgICAgICAgZGV2dG9vbHNVbm1vdW50QXBwKGFwcCk7DQogICAgICAgICAgfQ0KICAgICAgICAgIGRlbGV0ZSBhcHAuX2NvbnRhaW5lci5fX3Z1ZV9hcHBfXzsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICB3YXJuJDEoYENhbm5vdCB1bm1vdW50IGFuIGFwcCB0aGF0IGlzIG5vdCBtb3VudGVkLmApOw0KICAgICAgICB9DQogICAgICB9LA0KICAgICAgcHJvdmlkZShrZXksIHZhbHVlKSB7DQogICAgICAgIGlmIChrZXkgaW4gY29udGV4dC5wcm92aWRlcykgew0KICAgICAgICAgIGlmIChoYXNPd24oY29udGV4dC5wcm92aWRlcywga2V5KSkgew0KICAgICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgICBgQXBwIGFscmVhZHkgcHJvdmlkZXMgcHJvcGVydHkgd2l0aCBrZXkgIiR7U3RyaW5nKGtleSl9Ii4gSXQgd2lsbCBiZSBvdmVyd3JpdHRlbiB3aXRoIHRoZSBuZXcgdmFsdWUuYA0KICAgICAgICAgICAgKTsNCiAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgICBgQXBwIGFscmVhZHkgcHJvdmlkZXMgcHJvcGVydHkgd2l0aCBrZXkgIiR7U3RyaW5nKGtleSl9IiBpbmhlcml0ZWQgZnJvbSBpdHMgcGFyZW50IGVsZW1lbnQuIEl0IHdpbGwgYmUgb3ZlcndyaXR0ZW4gd2l0aCB0aGUgbmV3IHZhbHVlLmANCiAgICAgICAgICAgICk7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGNvbnRleHQucHJvdmlkZXNba2V5XSA9IHZhbHVlOw0KICAgICAgICByZXR1cm4gYXBwOw0KICAgICAgfSwNCiAgICAgIHJ1bldpdGhDb250ZXh0KGZuKSB7DQogICAgICAgIGNvbnN0IGxhc3RBcHAgPSBjdXJyZW50QXBwOw0KICAgICAgICBjdXJyZW50QXBwID0gYXBwOw0KICAgICAgICB0cnkgew0KICAgICAgICAgIHJldHVybiBmbigpOw0KICAgICAgICB9IGZpbmFsbHkgew0KICAgICAgICAgIGN1cnJlbnRBcHAgPSBsYXN0QXBwOw0KICAgICAgICB9DQogICAgICB9DQogICAgfTsNCiAgICByZXR1cm4gYXBwOw0KICB9Ow0KfQ0KbGV0IGN1cnJlbnRBcHAgPSBudWxsOw0KDQpmdW5jdGlvbiBwcm92aWRlKGtleSwgdmFsdWUpIHsNCiAgaWYgKCFjdXJyZW50SW5zdGFuY2UpIHsNCiAgICB7DQogICAgICB3YXJuJDEoYHByb3ZpZGUoKSBjYW4gb25seSBiZSB1c2VkIGluc2lkZSBzZXR1cCgpLmApOw0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICBsZXQgcHJvdmlkZXMgPSBjdXJyZW50SW5zdGFuY2UucHJvdmlkZXM7DQogICAgY29uc3QgcGFyZW50UHJvdmlkZXMgPSBjdXJyZW50SW5zdGFuY2UucGFyZW50ICYmIGN1cnJlbnRJbnN0YW5jZS5wYXJlbnQucHJvdmlkZXM7DQogICAgaWYgKHBhcmVudFByb3ZpZGVzID09PSBwcm92aWRlcykgew0KICAgICAgcHJvdmlkZXMgPSBjdXJyZW50SW5zdGFuY2UucHJvdmlkZXMgPSBPYmplY3QuY3JlYXRlKHBhcmVudFByb3ZpZGVzKTsNCiAgICB9DQogICAgcHJvdmlkZXNba2V5XSA9IHZhbHVlOw0KICB9DQp9DQpmdW5jdGlvbiBpbmplY3Qoa2V5LCBkZWZhdWx0VmFsdWUsIHRyZWF0RGVmYXVsdEFzRmFjdG9yeSA9IGZhbHNlKSB7DQogIGNvbnN0IGluc3RhbmNlID0gY3VycmVudEluc3RhbmNlIHx8IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZTsNCiAgaWYgKGluc3RhbmNlIHx8IGN1cnJlbnRBcHApIHsNCiAgICBsZXQgcHJvdmlkZXMgPSBjdXJyZW50QXBwID8gY3VycmVudEFwcC5fY29udGV4dC5wcm92aWRlcyA6IGluc3RhbmNlID8gaW5zdGFuY2UucGFyZW50ID09IG51bGwgfHwgaW5zdGFuY2UuY2UgPyBpbnN0YW5jZS52bm9kZS5hcHBDb250ZXh0ICYmIGluc3RhbmNlLnZub2RlLmFwcENvbnRleHQucHJvdmlkZXMgOiBpbnN0YW5jZS5wYXJlbnQucHJvdmlkZXMgOiB2b2lkIDA7DQogICAgaWYgKHByb3ZpZGVzICYmIGtleSBpbiBwcm92aWRlcykgew0KICAgICAgcmV0dXJuIHByb3ZpZGVzW2tleV07DQogICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkgew0KICAgICAgcmV0dXJuIHRyZWF0RGVmYXVsdEFzRmFjdG9yeSAmJiBpc0Z1bmN0aW9uKGRlZmF1bHRWYWx1ZSkgPyBkZWZhdWx0VmFsdWUuY2FsbChpbnN0YW5jZSAmJiBpbnN0YW5jZS5wcm94eSkgOiBkZWZhdWx0VmFsdWU7DQogICAgfSBlbHNlIHsNCiAgICAgIHdhcm4kMShgaW5qZWN0aW9uICIke1N0cmluZyhrZXkpfSIgbm90IGZvdW5kLmApOw0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICB3YXJuJDEoYGluamVjdCgpIGNhbiBvbmx5IGJlIHVzZWQgaW5zaWRlIHNldHVwKCkgb3IgZnVuY3Rpb25hbCBjb21wb25lbnRzLmApOw0KICB9DQp9DQpmdW5jdGlvbiBoYXNJbmplY3Rpb25Db250ZXh0KCkgew0KICByZXR1cm4gISEoY3VycmVudEluc3RhbmNlIHx8IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSB8fCBjdXJyZW50QXBwKTsNCn0NCg0KY29uc3QgaW50ZXJuYWxPYmplY3RQcm90byA9IHt9Ow0KY29uc3QgY3JlYXRlSW50ZXJuYWxPYmplY3QgPSAoKSA9PiBPYmplY3QuY3JlYXRlKGludGVybmFsT2JqZWN0UHJvdG8pOw0KY29uc3QgaXNJbnRlcm5hbE9iamVjdCA9IChvYmopID0+IE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmopID09PSBpbnRlcm5hbE9iamVjdFByb3RvOw0KDQpmdW5jdGlvbiBpbml0UHJvcHMoaW5zdGFuY2UsIHJhd1Byb3BzLCBpc1N0YXRlZnVsLCBpc1NTUiA9IGZhbHNlKSB7DQogIGNvbnN0IHByb3BzID0ge307DQogIGNvbnN0IGF0dHJzID0gY3JlYXRlSW50ZXJuYWxPYmplY3QoKTsNCiAgaW5zdGFuY2UucHJvcHNEZWZhdWx0cyA9IC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuY3JlYXRlKG51bGwpOw0KICBzZXRGdWxsUHJvcHMoaW5zdGFuY2UsIHJhd1Byb3BzLCBwcm9wcywgYXR0cnMpOw0KICBmb3IgKGNvbnN0IGtleSBpbiBpbnN0YW5jZS5wcm9wc09wdGlvbnNbMF0pIHsNCiAgICBpZiAoIShrZXkgaW4gcHJvcHMpKSB7DQogICAgICBwcm9wc1trZXldID0gdm9pZCAwOw0KICAgIH0NCiAgfQ0KICB7DQogICAgdmFsaWRhdGVQcm9wcyhyYXdQcm9wcyB8fCB7fSwgcHJvcHMsIGluc3RhbmNlKTsNCiAgfQ0KICBpZiAoaXNTdGF0ZWZ1bCkgew0KICAgIGluc3RhbmNlLnByb3BzID0gaXNTU1IgPyBwcm9wcyA6IHNoYWxsb3dSZWFjdGl2ZShwcm9wcyk7DQogIH0gZWxzZSB7DQogICAgaWYgKCFpbnN0YW5jZS50eXBlLnByb3BzKSB7DQogICAgICBpbnN0YW5jZS5wcm9wcyA9IGF0dHJzOw0KICAgIH0gZWxzZSB7DQogICAgICBpbnN0YW5jZS5wcm9wcyA9IHByb3BzOw0KICAgIH0NCiAgfQ0KICBpbnN0YW5jZS5hdHRycyA9IGF0dHJzOw0KfQ0KZnVuY3Rpb24gaXNJbkhtckNvbnRleHQoaW5zdGFuY2UpIHsNCiAgd2hpbGUgKGluc3RhbmNlKSB7DQogICAgaWYgKGluc3RhbmNlLnR5cGUuX19obXJJZCkgcmV0dXJuIHRydWU7DQogICAgaW5zdGFuY2UgPSBpbnN0YW5jZS5wYXJlbnQ7DQogIH0NCn0NCmZ1bmN0aW9uIHVwZGF0ZVByb3BzKGluc3RhbmNlLCByYXdQcm9wcywgcmF3UHJldlByb3BzLCBvcHRpbWl6ZWQpIHsNCiAgY29uc3Qgew0KICAgIHByb3BzLA0KICAgIGF0dHJzLA0KICAgIHZub2RlOiB7IHBhdGNoRmxhZyB9DQogIH0gPSBpbnN0YW5jZTsNCiAgY29uc3QgcmF3Q3VycmVudFByb3BzID0gdG9SYXcocHJvcHMpOw0KICBjb25zdCBbb3B0aW9uc10gPSBpbnN0YW5jZS5wcm9wc09wdGlvbnM7DQogIGxldCBoYXNBdHRyc0NoYW5nZWQgPSBmYWxzZTsNCiAgaWYgKA0KICAgIC8vIGFsd2F5cyBmb3JjZSBmdWxsIGRpZmYgaW4gZGV2DQogICAgLy8gLSAjMTk0MiBpZiBobXIgaXMgZW5hYmxlZCB3aXRoIHNmYyBjb21wb25lbnQNCiAgICAvLyAtIHZpdGUjODcyIG5vbi1zZmMgY29tcG9uZW50IHVzZWQgYnkgc2ZjIGNvbXBvbmVudA0KICAgICFpc0luSG1yQ29udGV4dChpbnN0YW5jZSkgJiYgKG9wdGltaXplZCB8fCBwYXRjaEZsYWcgPiAwKSAmJiAhKHBhdGNoRmxhZyAmIDE2KQ0KICApIHsNCiAgICBpZiAocGF0Y2hGbGFnICYgOCkgew0KICAgICAgY29uc3QgcHJvcHNUb1VwZGF0ZSA9IGluc3RhbmNlLnZub2RlLmR5bmFtaWNQcm9wczsNCiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcHJvcHNUb1VwZGF0ZS5sZW5ndGg7IGkrKykgew0KICAgICAgICBsZXQga2V5ID0gcHJvcHNUb1VwZGF0ZVtpXTsNCiAgICAgICAgaWYgKGlzRW1pdExpc3RlbmVyKGluc3RhbmNlLmVtaXRzT3B0aW9ucywga2V5KSkgew0KICAgICAgICAgIGNvbnRpbnVlOw0KICAgICAgICB9DQogICAgICAgIGNvbnN0IHZhbHVlID0gcmF3UHJvcHNba2V5XTsNCiAgICAgICAgaWYgKG9wdGlvbnMpIHsNCiAgICAgICAgICBpZiAoaGFzT3duKGF0dHJzLCBrZXkpKSB7DQogICAgICAgICAgICBpZiAodmFsdWUgIT09IGF0dHJzW2tleV0pIHsNCiAgICAgICAgICAgICAgYXR0cnNba2V5XSA9IHZhbHVlOw0KICAgICAgICAgICAgICBoYXNBdHRyc0NoYW5nZWQgPSB0cnVlOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBjb25zdCBjYW1lbGl6ZWRLZXkgPSBjYW1lbGl6ZShrZXkpOw0KICAgICAgICAgICAgcHJvcHNbY2FtZWxpemVkS2V5XSA9IHJlc29sdmVQcm9wVmFsdWUoDQogICAgICAgICAgICAgIG9wdGlvbnMsDQogICAgICAgICAgICAgIHJhd0N1cnJlbnRQcm9wcywNCiAgICAgICAgICAgICAgY2FtZWxpemVkS2V5LA0KICAgICAgICAgICAgICB2YWx1ZSwNCiAgICAgICAgICAgICAgaW5zdGFuY2UsDQogICAgICAgICAgICAgIGZhbHNlDQogICAgICAgICAgICApOw0KICAgICAgICAgIH0NCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBpZiAodmFsdWUgIT09IGF0dHJzW2tleV0pIHsNCiAgICAgICAgICAgIGF0dHJzW2tleV0gPSB2YWx1ZTsNCiAgICAgICAgICAgIGhhc0F0dHJzQ2hhbmdlZCA9IHRydWU7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICB9IGVsc2Ugew0KICAgIGlmIChzZXRGdWxsUHJvcHMoaW5zdGFuY2UsIHJhd1Byb3BzLCBwcm9wcywgYXR0cnMpKSB7DQogICAgICBoYXNBdHRyc0NoYW5nZWQgPSB0cnVlOw0KICAgIH0NCiAgICBsZXQga2ViYWJLZXk7DQogICAgZm9yIChjb25zdCBrZXkgaW4gcmF3Q3VycmVudFByb3BzKSB7DQogICAgICBpZiAoIXJhd1Byb3BzIHx8IC8vIGZvciBjYW1lbENhc2UNCiAgICAgICFoYXNPd24ocmF3UHJvcHMsIGtleSkgJiYgLy8gaXQncyBwb3NzaWJsZSB0aGUgb3JpZ2luYWwgcHJvcHMgd2FzIHBhc3NlZCBpbiBhcyBrZWJhYi1jYXNlDQogICAgICAvLyBhbmQgY29udmVydGVkIHRvIGNhbWVsQ2FzZSAoIzk1NSkNCiAgICAgICgoa2ViYWJLZXkgPSBoeXBoZW5hdGUoa2V5KSkgPT09IGtleSB8fCAhaGFzT3duKHJhd1Byb3BzLCBrZWJhYktleSkpKSB7DQogICAgICAgIGlmIChvcHRpb25zKSB7DQogICAgICAgICAgaWYgKHJhd1ByZXZQcm9wcyAmJiAvLyBmb3IgY2FtZWxDYXNlDQogICAgICAgICAgKHJhd1ByZXZQcm9wc1trZXldICE9PSB2b2lkIDAgfHwgLy8gZm9yIGtlYmFiLWNhc2UNCiAgICAgICAgICByYXdQcmV2UHJvcHNba2ViYWJLZXldICE9PSB2b2lkIDApKSB7DQogICAgICAgICAgICBwcm9wc1trZXldID0gcmVzb2x2ZVByb3BWYWx1ZSgNCiAgICAgICAgICAgICAgb3B0aW9ucywNCiAgICAgICAgICAgICAgcmF3Q3VycmVudFByb3BzLA0KICAgICAgICAgICAgICBrZXksDQogICAgICAgICAgICAgIHZvaWQgMCwNCiAgICAgICAgICAgICAgaW5zdGFuY2UsDQogICAgICAgICAgICAgIHRydWUNCiAgICAgICAgICAgICk7DQogICAgICAgICAgfQ0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIGRlbGV0ZSBwcm9wc1trZXldOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICAgIGlmIChhdHRycyAhPT0gcmF3Q3VycmVudFByb3BzKSB7DQogICAgICBmb3IgKGNvbnN0IGtleSBpbiBhdHRycykgew0KICAgICAgICBpZiAoIXJhd1Byb3BzIHx8ICFoYXNPd24ocmF3UHJvcHMsIGtleSkgJiYgdHJ1ZSkgew0KICAgICAgICAgIGRlbGV0ZSBhdHRyc1trZXldOw0KICAgICAgICAgIGhhc0F0dHJzQ2hhbmdlZCA9IHRydWU7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH0NCiAgaWYgKGhhc0F0dHJzQ2hhbmdlZCkgew0KICAgIHRyaWdnZXIoaW5zdGFuY2UuYXR0cnMsICJzZXQiLCAiIik7DQogIH0NCiAgew0KICAgIHZhbGlkYXRlUHJvcHMocmF3UHJvcHMgfHwge30sIHByb3BzLCBpbnN0YW5jZSk7DQogIH0NCn0NCmZ1bmN0aW9uIHNldEZ1bGxQcm9wcyhpbnN0YW5jZSwgcmF3UHJvcHMsIHByb3BzLCBhdHRycykgew0KICBjb25zdCBbb3B0aW9ucywgbmVlZENhc3RLZXlzXSA9IGluc3RhbmNlLnByb3BzT3B0aW9uczsNCiAgbGV0IGhhc0F0dHJzQ2hhbmdlZCA9IGZhbHNlOw0KICBsZXQgcmF3Q2FzdFZhbHVlczsNCiAgaWYgKHJhd1Byb3BzKSB7DQogICAgZm9yIChsZXQga2V5IGluIHJhd1Byb3BzKSB7DQogICAgICBpZiAoaXNSZXNlcnZlZFByb3Aoa2V5KSkgew0KICAgICAgICBjb250aW51ZTsNCiAgICAgIH0NCiAgICAgIGNvbnN0IHZhbHVlID0gcmF3UHJvcHNba2V5XTsNCiAgICAgIGxldCBjYW1lbEtleTsNCiAgICAgIGlmIChvcHRpb25zICYmIGhhc093bihvcHRpb25zLCBjYW1lbEtleSA9IGNhbWVsaXplKGtleSkpKSB7DQogICAgICAgIGlmICghbmVlZENhc3RLZXlzIHx8ICFuZWVkQ2FzdEtleXMuaW5jbHVkZXMoY2FtZWxLZXkpKSB7DQogICAgICAgICAgcHJvcHNbY2FtZWxLZXldID0gdmFsdWU7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgKHJhd0Nhc3RWYWx1ZXMgfHwgKHJhd0Nhc3RWYWx1ZXMgPSB7fSkpW2NhbWVsS2V5XSA9IHZhbHVlOw0KICAgICAgICB9DQogICAgICB9IGVsc2UgaWYgKCFpc0VtaXRMaXN0ZW5lcihpbnN0YW5jZS5lbWl0c09wdGlvbnMsIGtleSkpIHsNCiAgICAgICAgaWYgKCEoa2V5IGluIGF0dHJzKSB8fCB2YWx1ZSAhPT0gYXR0cnNba2V5XSkgew0KICAgICAgICAgIGF0dHJzW2tleV0gPSB2YWx1ZTsNCiAgICAgICAgICBoYXNBdHRyc0NoYW5nZWQgPSB0cnVlOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICB9DQogIGlmIChuZWVkQ2FzdEtleXMpIHsNCiAgICBjb25zdCByYXdDdXJyZW50UHJvcHMgPSB0b1Jhdyhwcm9wcyk7DQogICAgY29uc3QgY2FzdFZhbHVlcyA9IHJhd0Nhc3RWYWx1ZXMgfHwgRU1QVFlfT0JKOw0KICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbmVlZENhc3RLZXlzLmxlbmd0aDsgaSsrKSB7DQogICAgICBjb25zdCBrZXkgPSBuZWVkQ2FzdEtleXNbaV07DQogICAgICBwcm9wc1trZXldID0gcmVzb2x2ZVByb3BWYWx1ZSgNCiAgICAgICAgb3B0aW9ucywNCiAgICAgICAgcmF3Q3VycmVudFByb3BzLA0KICAgICAgICBrZXksDQogICAgICAgIGNhc3RWYWx1ZXNba2V5XSwNCiAgICAgICAgaW5zdGFuY2UsDQogICAgICAgICFoYXNPd24oY2FzdFZhbHVlcywga2V5KQ0KICAgICAgKTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIGhhc0F0dHJzQ2hhbmdlZDsNCn0NCmZ1bmN0aW9uIHJlc29sdmVQcm9wVmFsdWUob3B0aW9ucywgcHJvcHMsIGtleSwgdmFsdWUsIGluc3RhbmNlLCBpc0Fic2VudCkgew0KICBjb25zdCBvcHQgPSBvcHRpb25zW2tleV07DQogIGlmIChvcHQgIT0gbnVsbCkgew0KICAgIGNvbnN0IGhhc0RlZmF1bHQgPSBoYXNPd24ob3B0LCAiZGVmYXVsdCIpOw0KICAgIGlmIChoYXNEZWZhdWx0ICYmIHZhbHVlID09PSB2b2lkIDApIHsNCiAgICAgIGNvbnN0IGRlZmF1bHRWYWx1ZSA9IG9wdC5kZWZhdWx0Ow0KICAgICAgaWYgKG9wdC50eXBlICE9PSBGdW5jdGlvbiAmJiAhb3B0LnNraXBGYWN0b3J5ICYmIGlzRnVuY3Rpb24oZGVmYXVsdFZhbHVlKSkgew0KICAgICAgICBjb25zdCB7IHByb3BzRGVmYXVsdHMgfSA9IGluc3RhbmNlOw0KICAgICAgICBpZiAoa2V5IGluIHByb3BzRGVmYXVsdHMpIHsNCiAgICAgICAgICB2YWx1ZSA9IHByb3BzRGVmYXVsdHNba2V5XTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBjb25zdCByZXNldCA9IHNldEN1cnJlbnRJbnN0YW5jZShpbnN0YW5jZSk7DQogICAgICAgICAgdmFsdWUgPSBwcm9wc0RlZmF1bHRzW2tleV0gPSBkZWZhdWx0VmFsdWUuY2FsbCgNCiAgICAgICAgICAgIG51bGwsDQogICAgICAgICAgICBwcm9wcw0KICAgICAgICAgICk7DQogICAgICAgICAgcmVzZXQoKTsNCiAgICAgICAgfQ0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgdmFsdWUgPSBkZWZhdWx0VmFsdWU7DQogICAgICB9DQogICAgICBpZiAoaW5zdGFuY2UuY2UpIHsNCiAgICAgICAgaW5zdGFuY2UuY2UuX3NldFByb3Aoa2V5LCB2YWx1ZSk7DQogICAgICB9DQogICAgfQ0KICAgIGlmIChvcHRbMCAvKiBzaG91bGRDYXN0ICovXSkgew0KICAgICAgaWYgKGlzQWJzZW50ICYmICFoYXNEZWZhdWx0KSB7DQogICAgICAgIHZhbHVlID0gZmFsc2U7DQogICAgICB9IGVsc2UgaWYgKG9wdFsxIC8qIHNob3VsZENhc3RUcnVlICovXSAmJiAodmFsdWUgPT09ICIiIHx8IHZhbHVlID09PSBoeXBoZW5hdGUoa2V5KSkpIHsNCiAgICAgICAgdmFsdWUgPSB0cnVlOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICByZXR1cm4gdmFsdWU7DQp9DQpjb25zdCBtaXhpblByb3BzQ2FjaGUgPSAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtNYXAoKTsNCmZ1bmN0aW9uIG5vcm1hbGl6ZVByb3BzT3B0aW9ucyhjb21wLCBhcHBDb250ZXh0LCBhc01peGluID0gZmFsc2UpIHsNCiAgY29uc3QgY2FjaGUgPSBhc01peGluID8gbWl4aW5Qcm9wc0NhY2hlIDogYXBwQ29udGV4dC5wcm9wc0NhY2hlOw0KICBjb25zdCBjYWNoZWQgPSBjYWNoZS5nZXQoY29tcCk7DQogIGlmIChjYWNoZWQpIHsNCiAgICByZXR1cm4gY2FjaGVkOw0KICB9DQogIGNvbnN0IHJhdyA9IGNvbXAucHJvcHM7DQogIGNvbnN0IG5vcm1hbGl6ZWQgPSB7fTsNCiAgY29uc3QgbmVlZENhc3RLZXlzID0gW107DQogIGxldCBoYXNFeHRlbmRzID0gZmFsc2U7DQogIGlmICghaXNGdW5jdGlvbihjb21wKSkgew0KICAgIGNvbnN0IGV4dGVuZFByb3BzID0gKHJhdzIpID0+IHsNCiAgICAgIGhhc0V4dGVuZHMgPSB0cnVlOw0KICAgICAgY29uc3QgW3Byb3BzLCBrZXlzXSA9IG5vcm1hbGl6ZVByb3BzT3B0aW9ucyhyYXcyLCBhcHBDb250ZXh0LCB0cnVlKTsNCiAgICAgIGV4dGVuZChub3JtYWxpemVkLCBwcm9wcyk7DQogICAgICBpZiAoa2V5cykgbmVlZENhc3RLZXlzLnB1c2goLi4ua2V5cyk7DQogICAgfTsNCiAgICBpZiAoIWFzTWl4aW4gJiYgYXBwQ29udGV4dC5taXhpbnMubGVuZ3RoKSB7DQogICAgICBhcHBDb250ZXh0Lm1peGlucy5mb3JFYWNoKGV4dGVuZFByb3BzKTsNCiAgICB9DQogICAgaWYgKGNvbXAuZXh0ZW5kcykgew0KICAgICAgZXh0ZW5kUHJvcHMoY29tcC5leHRlbmRzKTsNCiAgICB9DQogICAgaWYgKGNvbXAubWl4aW5zKSB7DQogICAgICBjb21wLm1peGlucy5mb3JFYWNoKGV4dGVuZFByb3BzKTsNCiAgICB9DQogIH0NCiAgaWYgKCFyYXcgJiYgIWhhc0V4dGVuZHMpIHsNCiAgICBpZiAoaXNPYmplY3QoY29tcCkpIHsNCiAgICAgIGNhY2hlLnNldChjb21wLCBFTVBUWV9BUlIpOw0KICAgIH0NCiAgICByZXR1cm4gRU1QVFlfQVJSOw0KICB9DQogIGlmIChpc0FycmF5KHJhdykpIHsNCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhdy5sZW5ndGg7IGkrKykgew0KICAgICAgaWYgKCFpc1N0cmluZyhyYXdbaV0pKSB7DQogICAgICAgIHdhcm4kMShgcHJvcHMgbXVzdCBiZSBzdHJpbmdzIHdoZW4gdXNpbmcgYXJyYXkgc3ludGF4LmAsIHJhd1tpXSk7DQogICAgICB9DQogICAgICBjb25zdCBub3JtYWxpemVkS2V5ID0gY2FtZWxpemUocmF3W2ldKTsNCiAgICAgIGlmICh2YWxpZGF0ZVByb3BOYW1lKG5vcm1hbGl6ZWRLZXkpKSB7DQogICAgICAgIG5vcm1hbGl6ZWRbbm9ybWFsaXplZEtleV0gPSBFTVBUWV9PQko7DQogICAgICB9DQogICAgfQ0KICB9IGVsc2UgaWYgKHJhdykgew0KICAgIGlmICghaXNPYmplY3QocmF3KSkgew0KICAgICAgd2FybiQxKGBpbnZhbGlkIHByb3BzIG9wdGlvbnNgLCByYXcpOw0KICAgIH0NCiAgICBmb3IgKGNvbnN0IGtleSBpbiByYXcpIHsNCiAgICAgIGNvbnN0IG5vcm1hbGl6ZWRLZXkgPSBjYW1lbGl6ZShrZXkpOw0KICAgICAgaWYgKHZhbGlkYXRlUHJvcE5hbWUobm9ybWFsaXplZEtleSkpIHsNCiAgICAgICAgY29uc3Qgb3B0ID0gcmF3W2tleV07DQogICAgICAgIGNvbnN0IHByb3AgPSBub3JtYWxpemVkW25vcm1hbGl6ZWRLZXldID0gaXNBcnJheShvcHQpIHx8IGlzRnVuY3Rpb24ob3B0KSA/IHsgdHlwZTogb3B0IH0gOiBleHRlbmQoe30sIG9wdCk7DQogICAgICAgIGNvbnN0IHByb3BUeXBlID0gcHJvcC50eXBlOw0KICAgICAgICBsZXQgc2hvdWxkQ2FzdCA9IGZhbHNlOw0KICAgICAgICBsZXQgc2hvdWxkQ2FzdFRydWUgPSB0cnVlOw0KICAgICAgICBpZiAoaXNBcnJheShwcm9wVHlwZSkpIHsNCiAgICAgICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgcHJvcFR5cGUubGVuZ3RoOyArK2luZGV4KSB7DQogICAgICAgICAgICBjb25zdCB0eXBlID0gcHJvcFR5cGVbaW5kZXhdOw0KICAgICAgICAgICAgY29uc3QgdHlwZU5hbWUgPSBpc0Z1bmN0aW9uKHR5cGUpICYmIHR5cGUubmFtZTsNCiAgICAgICAgICAgIGlmICh0eXBlTmFtZSA9PT0gIkJvb2xlYW4iKSB7DQogICAgICAgICAgICAgIHNob3VsZENhc3QgPSB0cnVlOw0KICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZU5hbWUgPT09ICJTdHJpbmciKSB7DQogICAgICAgICAgICAgIHNob3VsZENhc3RUcnVlID0gZmFsc2U7DQogICAgICAgICAgICB9DQogICAgICAgICAgfQ0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIHNob3VsZENhc3QgPSBpc0Z1bmN0aW9uKHByb3BUeXBlKSAmJiBwcm9wVHlwZS5uYW1lID09PSAiQm9vbGVhbiI7DQogICAgICAgIH0NCiAgICAgICAgcHJvcFswIC8qIHNob3VsZENhc3QgKi9dID0gc2hvdWxkQ2FzdDsNCiAgICAgICAgcHJvcFsxIC8qIHNob3VsZENhc3RUcnVlICovXSA9IHNob3VsZENhc3RUcnVlOw0KICAgICAgICBpZiAoc2hvdWxkQ2FzdCB8fCBoYXNPd24ocHJvcCwgImRlZmF1bHQiKSkgew0KICAgICAgICAgIG5lZWRDYXN0S2V5cy5wdXNoKG5vcm1hbGl6ZWRLZXkpOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICB9DQogIGNvbnN0IHJlcyA9IFtub3JtYWxpemVkLCBuZWVkQ2FzdEtleXNdOw0KICBpZiAoaXNPYmplY3QoY29tcCkpIHsNCiAgICBjYWNoZS5zZXQoY29tcCwgcmVzKTsNCiAgfQ0KICByZXR1cm4gcmVzOw0KfQ0KZnVuY3Rpb24gdmFsaWRhdGVQcm9wTmFtZShrZXkpIHsNCiAgaWYgKGtleVswXSAhPT0gIiQiICYmICFpc1Jlc2VydmVkUHJvcChrZXkpKSB7DQogICAgcmV0dXJuIHRydWU7DQogIH0gZWxzZSB7DQogICAgd2FybiQxKGBJbnZhbGlkIHByb3AgbmFtZTogIiR7a2V5fSIgaXMgYSByZXNlcnZlZCBwcm9wZXJ0eS5gKTsNCiAgfQ0KICByZXR1cm4gZmFsc2U7DQp9DQpmdW5jdGlvbiBnZXRUeXBlKGN0b3IpIHsNCiAgaWYgKGN0b3IgPT09IG51bGwpIHsNCiAgICByZXR1cm4gIm51bGwiOw0KICB9DQogIGlmICh0eXBlb2YgY3RvciA9PT0gImZ1bmN0aW9uIikgew0KICAgIHJldHVybiBjdG9yLm5hbWUgfHwgIiI7DQogIH0gZWxzZSBpZiAodHlwZW9mIGN0b3IgPT09ICJvYmplY3QiKSB7DQogICAgY29uc3QgbmFtZSA9IGN0b3IuY29uc3RydWN0b3IgJiYgY3Rvci5jb25zdHJ1Y3Rvci5uYW1lOw0KICAgIHJldHVybiBuYW1lIHx8ICIiOw0KICB9DQogIHJldHVybiAiIjsNCn0NCmZ1bmN0aW9uIHZhbGlkYXRlUHJvcHMocmF3UHJvcHMsIHByb3BzLCBpbnN0YW5jZSkgew0KICBjb25zdCByZXNvbHZlZFZhbHVlcyA9IHRvUmF3KHByb3BzKTsNCiAgY29uc3Qgb3B0aW9ucyA9IGluc3RhbmNlLnByb3BzT3B0aW9uc1swXTsNCiAgY29uc3QgY2FtZWxpemVQcm9wc0tleSA9IE9iamVjdC5rZXlzKHJhd1Byb3BzKS5tYXAoKGtleSkgPT4gY2FtZWxpemUoa2V5KSk7DQogIGZvciAoY29uc3Qga2V5IGluIG9wdGlvbnMpIHsNCiAgICBsZXQgb3B0ID0gb3B0aW9uc1trZXldOw0KICAgIGlmIChvcHQgPT0gbnVsbCkgY29udGludWU7DQogICAgdmFsaWRhdGVQcm9wKA0KICAgICAga2V5LA0KICAgICAgcmVzb2x2ZWRWYWx1ZXNba2V5XSwNCiAgICAgIG9wdCwNCiAgICAgIHNoYWxsb3dSZWFkb25seShyZXNvbHZlZFZhbHVlcykgLA0KICAgICAgIWNhbWVsaXplUHJvcHNLZXkuaW5jbHVkZXMoa2V5KQ0KICAgICk7DQogIH0NCn0NCmZ1bmN0aW9uIHZhbGlkYXRlUHJvcChuYW1lLCB2YWx1ZSwgcHJvcCwgcHJvcHMsIGlzQWJzZW50KSB7DQogIGNvbnN0IHsgdHlwZSwgcmVxdWlyZWQsIHZhbGlkYXRvciwgc2tpcENoZWNrIH0gPSBwcm9wOw0KICBpZiAocmVxdWlyZWQgJiYgaXNBYnNlbnQpIHsNCiAgICB3YXJuJDEoJ01pc3NpbmcgcmVxdWlyZWQgcHJvcDogIicgKyBuYW1lICsgJyInKTsNCiAgICByZXR1cm47DQogIH0NCiAgaWYgKHZhbHVlID09IG51bGwgJiYgIXJlcXVpcmVkKSB7DQogICAgcmV0dXJuOw0KICB9DQogIGlmICh0eXBlICE9IG51bGwgJiYgdHlwZSAhPT0gdHJ1ZSAmJiAhc2tpcENoZWNrKSB7DQogICAgbGV0IGlzVmFsaWQgPSBmYWxzZTsNCiAgICBjb25zdCB0eXBlcyA9IGlzQXJyYXkodHlwZSkgPyB0eXBlIDogW3R5cGVdOw0KICAgIGNvbnN0IGV4cGVjdGVkVHlwZXMgPSBbXTsNCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHR5cGVzLmxlbmd0aCAmJiAhaXNWYWxpZDsgaSsrKSB7DQogICAgICBjb25zdCB7IHZhbGlkLCBleHBlY3RlZFR5cGUgfSA9IGFzc2VydFR5cGUodmFsdWUsIHR5cGVzW2ldKTsNCiAgICAgIGV4cGVjdGVkVHlwZXMucHVzaChleHBlY3RlZFR5cGUgfHwgIiIpOw0KICAgICAgaXNWYWxpZCA9IHZhbGlkOw0KICAgIH0NCiAgICBpZiAoIWlzVmFsaWQpIHsNCiAgICAgIHdhcm4kMShnZXRJbnZhbGlkVHlwZU1lc3NhZ2UobmFtZSwgdmFsdWUsIGV4cGVjdGVkVHlwZXMpKTsNCiAgICAgIHJldHVybjsNCiAgICB9DQogIH0NCiAgaWYgKHZhbGlkYXRvciAmJiAhdmFsaWRhdG9yKHZhbHVlLCBwcm9wcykpIHsNCiAgICB3YXJuJDEoJ0ludmFsaWQgcHJvcDogY3VzdG9tIHZhbGlkYXRvciBjaGVjayBmYWlsZWQgZm9yIHByb3AgIicgKyBuYW1lICsgJyIuJyk7DQogIH0NCn0NCmNvbnN0IGlzU2ltcGxlVHlwZSA9IC8qIEBfX1BVUkVfXyAqLyBtYWtlTWFwKA0KICAiU3RyaW5nLE51bWJlcixCb29sZWFuLEZ1bmN0aW9uLFN5bWJvbCxCaWdJbnQiDQopOw0KZnVuY3Rpb24gYXNzZXJ0VHlwZSh2YWx1ZSwgdHlwZSkgew0KICBsZXQgdmFsaWQ7DQogIGNvbnN0IGV4cGVjdGVkVHlwZSA9IGdldFR5cGUodHlwZSk7DQogIGlmIChleHBlY3RlZFR5cGUgPT09ICJudWxsIikgew0KICAgIHZhbGlkID0gdmFsdWUgPT09IG51bGw7DQogIH0gZWxzZSBpZiAoaXNTaW1wbGVUeXBlKGV4cGVjdGVkVHlwZSkpIHsNCiAgICBjb25zdCB0ID0gdHlwZW9mIHZhbHVlOw0KICAgIHZhbGlkID0gdCA9PT0gZXhwZWN0ZWRUeXBlLnRvTG93ZXJDYXNlKCk7DQogICAgaWYgKCF2YWxpZCAmJiB0ID09PSAib2JqZWN0Iikgew0KICAgICAgdmFsaWQgPSB2YWx1ZSBpbnN0YW5jZW9mIHR5cGU7DQogICAgfQ0KICB9IGVsc2UgaWYgKGV4cGVjdGVkVHlwZSA9PT0gIk9iamVjdCIpIHsNCiAgICB2YWxpZCA9IGlzT2JqZWN0KHZhbHVlKTsNCiAgfSBlbHNlIGlmIChleHBlY3RlZFR5cGUgPT09ICJBcnJheSIpIHsNCiAgICB2YWxpZCA9IGlzQXJyYXkodmFsdWUpOw0KICB9IGVsc2Ugew0KICAgIHZhbGlkID0gdmFsdWUgaW5zdGFuY2VvZiB0eXBlOw0KICB9DQogIHJldHVybiB7DQogICAgdmFsaWQsDQogICAgZXhwZWN0ZWRUeXBlDQogIH07DQp9DQpmdW5jdGlvbiBnZXRJbnZhbGlkVHlwZU1lc3NhZ2UobmFtZSwgdmFsdWUsIGV4cGVjdGVkVHlwZXMpIHsNCiAgaWYgKGV4cGVjdGVkVHlwZXMubGVuZ3RoID09PSAwKSB7DQogICAgcmV0dXJuIGBQcm9wIHR5cGUgW10gZm9yIHByb3AgIiR7bmFtZX0iIHdvbid0IG1hdGNoIGFueXRoaW5nLiBEaWQgeW91IG1lYW4gdG8gdXNlIHR5cGUgQXJyYXkgaW5zdGVhZD9gOw0KICB9DQogIGxldCBtZXNzYWdlID0gYEludmFsaWQgcHJvcDogdHlwZSBjaGVjayBmYWlsZWQgZm9yIHByb3AgIiR7bmFtZX0iLiBFeHBlY3RlZCAke2V4cGVjdGVkVHlwZXMubWFwKGNhcGl0YWxpemUpLmpvaW4oIiB8ICIpfWA7DQogIGNvbnN0IGV4cGVjdGVkVHlwZSA9IGV4cGVjdGVkVHlwZXNbMF07DQogIGNvbnN0IHJlY2VpdmVkVHlwZSA9IHRvUmF3VHlwZSh2YWx1ZSk7DQogIGNvbnN0IGV4cGVjdGVkVmFsdWUgPSBzdHlsZVZhbHVlKHZhbHVlLCBleHBlY3RlZFR5cGUpOw0KICBjb25zdCByZWNlaXZlZFZhbHVlID0gc3R5bGVWYWx1ZSh2YWx1ZSwgcmVjZWl2ZWRUeXBlKTsNCiAgaWYgKGV4cGVjdGVkVHlwZXMubGVuZ3RoID09PSAxICYmIGlzRXhwbGljYWJsZShleHBlY3RlZFR5cGUpICYmICFpc0Jvb2xlYW4oZXhwZWN0ZWRUeXBlLCByZWNlaXZlZFR5cGUpKSB7DQogICAgbWVzc2FnZSArPSBgIHdpdGggdmFsdWUgJHtleHBlY3RlZFZhbHVlfWA7DQogIH0NCiAgbWVzc2FnZSArPSBgLCBnb3QgJHtyZWNlaXZlZFR5cGV9IGA7DQogIGlmIChpc0V4cGxpY2FibGUocmVjZWl2ZWRUeXBlKSkgew0KICAgIG1lc3NhZ2UgKz0gYHdpdGggdmFsdWUgJHtyZWNlaXZlZFZhbHVlfS5gOw0KICB9DQogIHJldHVybiBtZXNzYWdlOw0KfQ0KZnVuY3Rpb24gc3R5bGVWYWx1ZSh2YWx1ZSwgdHlwZSkgew0KICBpZiAodHlwZSA9PT0gIlN0cmluZyIpIHsNCiAgICByZXR1cm4gYCIke3ZhbHVlfSJgOw0KICB9IGVsc2UgaWYgKHR5cGUgPT09ICJOdW1iZXIiKSB7DQogICAgcmV0dXJuIGAke051bWJlcih2YWx1ZSl9YDsNCiAgfSBlbHNlIHsNCiAgICByZXR1cm4gYCR7dmFsdWV9YDsNCiAgfQ0KfQ0KZnVuY3Rpb24gaXNFeHBsaWNhYmxlKHR5cGUpIHsNCiAgY29uc3QgZXhwbGljaXRUeXBlcyA9IFsic3RyaW5nIiwgIm51bWJlciIsICJib29sZWFuIl07DQogIHJldHVybiBleHBsaWNpdFR5cGVzLnNvbWUoKGVsZW0pID0+IHR5cGUudG9Mb3dlckNhc2UoKSA9PT0gZWxlbSk7DQp9DQpmdW5jdGlvbiBpc0Jvb2xlYW4oLi4uYXJncykgew0KICByZXR1cm4gYXJncy5zb21lKChlbGVtKSA9PiBlbGVtLnRvTG93ZXJDYXNlKCkgPT09ICJib29sZWFuIik7DQp9DQoNCmNvbnN0IGlzSW50ZXJuYWxLZXkgPSAoa2V5KSA9PiBrZXlbMF0gPT09ICJfIiB8fCBrZXkgPT09ICIkc3RhYmxlIjsNCmNvbnN0IG5vcm1hbGl6ZVNsb3RWYWx1ZSA9ICh2YWx1ZSkgPT4gaXNBcnJheSh2YWx1ZSkgPyB2YWx1ZS5tYXAobm9ybWFsaXplVk5vZGUpIDogW25vcm1hbGl6ZVZOb2RlKHZhbHVlKV07DQpjb25zdCBub3JtYWxpemVTbG90ID0gKGtleSwgcmF3U2xvdCwgY3R4KSA9PiB7DQogIGlmIChyYXdTbG90Ll9uKSB7DQogICAgcmV0dXJuIHJhd1Nsb3Q7DQogIH0NCiAgY29uc3Qgbm9ybWFsaXplZCA9IHdpdGhDdHgoKC4uLmFyZ3MpID0+IHsNCiAgICBpZiAoY3VycmVudEluc3RhbmNlICYmICEoY3R4ID09PSBudWxsICYmIGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSkgJiYgIShjdHggJiYgY3R4LnJvb3QgIT09IGN1cnJlbnRJbnN0YW5jZS5yb290KSkgew0KICAgICAgd2FybiQxKA0KICAgICAgICBgU2xvdCAiJHtrZXl9IiBpbnZva2VkIG91dHNpZGUgb2YgdGhlIHJlbmRlciBmdW5jdGlvbjogdGhpcyB3aWxsIG5vdCB0cmFjayBkZXBlbmRlbmNpZXMgdXNlZCBpbiB0aGUgc2xvdC4gSW52b2tlIHRoZSBzbG90IGZ1bmN0aW9uIGluc2lkZSB0aGUgcmVuZGVyIGZ1bmN0aW9uIGluc3RlYWQuYA0KICAgICAgKTsNCiAgICB9DQogICAgcmV0dXJuIG5vcm1hbGl6ZVNsb3RWYWx1ZShyYXdTbG90KC4uLmFyZ3MpKTsNCiAgfSwgY3R4KTsNCiAgbm9ybWFsaXplZC5fYyA9IGZhbHNlOw0KICByZXR1cm4gbm9ybWFsaXplZDsNCn07DQpjb25zdCBub3JtYWxpemVPYmplY3RTbG90cyA9IChyYXdTbG90cywgc2xvdHMsIGluc3RhbmNlKSA9PiB7DQogIGNvbnN0IGN0eCA9IHJhd1Nsb3RzLl9jdHg7DQogIGZvciAoY29uc3Qga2V5IGluIHJhd1Nsb3RzKSB7DQogICAgaWYgKGlzSW50ZXJuYWxLZXkoa2V5KSkgY29udGludWU7DQogICAgY29uc3QgdmFsdWUgPSByYXdTbG90c1trZXldOw0KICAgIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkgew0KICAgICAgc2xvdHNba2V5XSA9IG5vcm1hbGl6ZVNsb3Qoa2V5LCB2YWx1ZSwgY3R4KTsNCiAgICB9IGVsc2UgaWYgKHZhbHVlICE9IG51bGwpIHsNCiAgICAgIHsNCiAgICAgICAgd2FybiQxKA0KICAgICAgICAgIGBOb24tZnVuY3Rpb24gdmFsdWUgZW5jb3VudGVyZWQgZm9yIHNsb3QgIiR7a2V5fSIuIFByZWZlciBmdW5jdGlvbiBzbG90cyBmb3IgYmV0dGVyIHBlcmZvcm1hbmNlLmANCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBub3JtYWxpemVTbG90VmFsdWUodmFsdWUpOw0KICAgICAgc2xvdHNba2V5XSA9ICgpID0+IG5vcm1hbGl6ZWQ7DQogICAgfQ0KICB9DQp9Ow0KY29uc3Qgbm9ybWFsaXplVk5vZGVTbG90cyA9IChpbnN0YW5jZSwgY2hpbGRyZW4pID0+IHsNCiAgaWYgKCFpc0tlZXBBbGl2ZShpbnN0YW5jZS52bm9kZSkgJiYgdHJ1ZSkgew0KICAgIHdhcm4kMSgNCiAgICAgIGBOb24tZnVuY3Rpb24gdmFsdWUgZW5jb3VudGVyZWQgZm9yIGRlZmF1bHQgc2xvdC4gUHJlZmVyIGZ1bmN0aW9uIHNsb3RzIGZvciBiZXR0ZXIgcGVyZm9ybWFuY2UuYA0KICAgICk7DQogIH0NCiAgY29uc3Qgbm9ybWFsaXplZCA9IG5vcm1hbGl6ZVNsb3RWYWx1ZShjaGlsZHJlbik7DQogIGluc3RhbmNlLnNsb3RzLmRlZmF1bHQgPSAoKSA9PiBub3JtYWxpemVkOw0KfTsNCmNvbnN0IGFzc2lnblNsb3RzID0gKHNsb3RzLCBjaGlsZHJlbiwgb3B0aW1pemVkKSA9PiB7DQogIGZvciAoY29uc3Qga2V5IGluIGNoaWxkcmVuKSB7DQogICAgaWYgKG9wdGltaXplZCB8fCAhaXNJbnRlcm5hbEtleShrZXkpKSB7DQogICAgICBzbG90c1trZXldID0gY2hpbGRyZW5ba2V5XTsNCiAgICB9DQogIH0NCn07DQpjb25zdCBpbml0U2xvdHMgPSAoaW5zdGFuY2UsIGNoaWxkcmVuLCBvcHRpbWl6ZWQpID0+IHsNCiAgY29uc3Qgc2xvdHMgPSBpbnN0YW5jZS5zbG90cyA9IGNyZWF0ZUludGVybmFsT2JqZWN0KCk7DQogIGlmIChpbnN0YW5jZS52bm9kZS5zaGFwZUZsYWcgJiAzMikgew0KICAgIGNvbnN0IGNhY2hlSW5kZXhlcyA9IGNoaWxkcmVuLl9fOw0KICAgIGlmIChjYWNoZUluZGV4ZXMpIGRlZihzbG90cywgIl9fIiwgY2FjaGVJbmRleGVzLCB0cnVlKTsNCiAgICBjb25zdCB0eXBlID0gY2hpbGRyZW4uXzsNCiAgICBpZiAodHlwZSkgew0KICAgICAgYXNzaWduU2xvdHMoc2xvdHMsIGNoaWxkcmVuLCBvcHRpbWl6ZWQpOw0KICAgICAgaWYgKG9wdGltaXplZCkgew0KICAgICAgICBkZWYoc2xvdHMsICJfIiwgdHlwZSwgdHJ1ZSk7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIG5vcm1hbGl6ZU9iamVjdFNsb3RzKGNoaWxkcmVuLCBzbG90cyk7DQogICAgfQ0KICB9IGVsc2UgaWYgKGNoaWxkcmVuKSB7DQogICAgbm9ybWFsaXplVk5vZGVTbG90cyhpbnN0YW5jZSwgY2hpbGRyZW4pOw0KICB9DQp9Ow0KY29uc3QgdXBkYXRlU2xvdHMgPSAoaW5zdGFuY2UsIGNoaWxkcmVuLCBvcHRpbWl6ZWQpID0+IHsNCiAgY29uc3QgeyB2bm9kZSwgc2xvdHMgfSA9IGluc3RhbmNlOw0KICBsZXQgbmVlZERlbGV0aW9uQ2hlY2sgPSB0cnVlOw0KICBsZXQgZGVsZXRpb25Db21wYXJpc29uVGFyZ2V0ID0gRU1QVFlfT0JKOw0KICBpZiAodm5vZGUuc2hhcGVGbGFnICYgMzIpIHsNCiAgICBjb25zdCB0eXBlID0gY2hpbGRyZW4uXzsNCiAgICBpZiAodHlwZSkgew0KICAgICAgaWYgKGlzSG1yVXBkYXRpbmcpIHsNCiAgICAgICAgYXNzaWduU2xvdHMoc2xvdHMsIGNoaWxkcmVuLCBvcHRpbWl6ZWQpOw0KICAgICAgICB0cmlnZ2VyKGluc3RhbmNlLCAic2V0IiwgIiRzbG90cyIpOw0KICAgICAgfSBlbHNlIGlmIChvcHRpbWl6ZWQgJiYgdHlwZSA9PT0gMSkgew0KICAgICAgICBuZWVkRGVsZXRpb25DaGVjayA9IGZhbHNlOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgYXNzaWduU2xvdHMoc2xvdHMsIGNoaWxkcmVuLCBvcHRpbWl6ZWQpOw0KICAgICAgfQ0KICAgIH0gZWxzZSB7DQogICAgICBuZWVkRGVsZXRpb25DaGVjayA9ICFjaGlsZHJlbi4kc3RhYmxlOw0KICAgICAgbm9ybWFsaXplT2JqZWN0U2xvdHMoY2hpbGRyZW4sIHNsb3RzKTsNCiAgICB9DQogICAgZGVsZXRpb25Db21wYXJpc29uVGFyZ2V0ID0gY2hpbGRyZW47DQogIH0gZWxzZSBpZiAoY2hpbGRyZW4pIHsNCiAgICBub3JtYWxpemVWTm9kZVNsb3RzKGluc3RhbmNlLCBjaGlsZHJlbik7DQogICAgZGVsZXRpb25Db21wYXJpc29uVGFyZ2V0ID0geyBkZWZhdWx0OiAxIH07DQogIH0NCiAgaWYgKG5lZWREZWxldGlvbkNoZWNrKSB7DQogICAgZm9yIChjb25zdCBrZXkgaW4gc2xvdHMpIHsNCiAgICAgIGlmICghaXNJbnRlcm5hbEtleShrZXkpICYmIGRlbGV0aW9uQ29tcGFyaXNvblRhcmdldFtrZXldID09IG51bGwpIHsNCiAgICAgICAgZGVsZXRlIHNsb3RzW2tleV07DQogICAgICB9DQogICAgfQ0KICB9DQp9Ow0KDQpsZXQgc3VwcG9ydGVkOw0KbGV0IHBlcmY7DQpmdW5jdGlvbiBzdGFydE1lYXN1cmUoaW5zdGFuY2UsIHR5cGUpIHsNCiAgaWYgKGluc3RhbmNlLmFwcENvbnRleHQuY29uZmlnLnBlcmZvcm1hbmNlICYmIGlzU3VwcG9ydGVkKCkpIHsNCiAgICBwZXJmLm1hcmsoYHZ1ZS0ke3R5cGV9LSR7aW5zdGFuY2UudWlkfWApOw0KICB9DQogIHsNCiAgICBkZXZ0b29sc1BlcmZTdGFydChpbnN0YW5jZSwgdHlwZSwgaXNTdXBwb3J0ZWQoKSA/IHBlcmYubm93KCkgOiBEYXRlLm5vdygpKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gZW5kTWVhc3VyZShpbnN0YW5jZSwgdHlwZSkgew0KICBpZiAoaW5zdGFuY2UuYXBwQ29udGV4dC5jb25maWcucGVyZm9ybWFuY2UgJiYgaXNTdXBwb3J0ZWQoKSkgew0KICAgIGNvbnN0IHN0YXJ0VGFnID0gYHZ1ZS0ke3R5cGV9LSR7aW5zdGFuY2UudWlkfWA7DQogICAgY29uc3QgZW5kVGFnID0gc3RhcnRUYWcgKyBgOmVuZGA7DQogICAgcGVyZi5tYXJrKGVuZFRhZyk7DQogICAgcGVyZi5tZWFzdXJlKA0KICAgICAgYDwke2Zvcm1hdENvbXBvbmVudE5hbWUoaW5zdGFuY2UsIGluc3RhbmNlLnR5cGUpfT4gJHt0eXBlfWAsDQogICAgICBzdGFydFRhZywNCiAgICAgIGVuZFRhZw0KICAgICk7DQogICAgcGVyZi5jbGVhck1hcmtzKHN0YXJ0VGFnKTsNCiAgICBwZXJmLmNsZWFyTWFya3MoZW5kVGFnKTsNCiAgfQ0KICB7DQogICAgZGV2dG9vbHNQZXJmRW5kKGluc3RhbmNlLCB0eXBlLCBpc1N1cHBvcnRlZCgpID8gcGVyZi5ub3coKSA6IERhdGUubm93KCkpOw0KICB9DQp9DQpmdW5jdGlvbiBpc1N1cHBvcnRlZCgpIHsNCiAgaWYgKHN1cHBvcnRlZCAhPT0gdm9pZCAwKSB7DQogICAgcmV0dXJuIHN1cHBvcnRlZDsNCiAgfQ0KICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gInVuZGVmaW5lZCIgJiYgd2luZG93LnBlcmZvcm1hbmNlKSB7DQogICAgc3VwcG9ydGVkID0gdHJ1ZTsNCiAgICBwZXJmID0gd2luZG93LnBlcmZvcm1hbmNlOw0KICB9IGVsc2Ugew0KICAgIHN1cHBvcnRlZCA9IGZhbHNlOw0KICB9DQogIHJldHVybiBzdXBwb3J0ZWQ7DQp9DQoNCmNvbnN0IHF1ZXVlUG9zdFJlbmRlckVmZmVjdCA9IHF1ZXVlRWZmZWN0V2l0aFN1c3BlbnNlIDsNCmZ1bmN0aW9uIGNyZWF0ZVJlbmRlcmVyKG9wdGlvbnMpIHsNCiAgcmV0dXJuIGJhc2VDcmVhdGVSZW5kZXJlcihvcHRpb25zKTsNCn0NCmZ1bmN0aW9uIGNyZWF0ZUh5ZHJhdGlvblJlbmRlcmVyKG9wdGlvbnMpIHsNCiAgcmV0dXJuIGJhc2VDcmVhdGVSZW5kZXJlcihvcHRpb25zLCBjcmVhdGVIeWRyYXRpb25GdW5jdGlvbnMpOw0KfQ0KZnVuY3Rpb24gYmFzZUNyZWF0ZVJlbmRlcmVyKG9wdGlvbnMsIGNyZWF0ZUh5ZHJhdGlvbkZucykgew0KICBjb25zdCB0YXJnZXQgPSBnZXRHbG9iYWxUaGlzKCk7DQogIHRhcmdldC5fX1ZVRV9fID0gdHJ1ZTsNCiAgew0KICAgIHNldERldnRvb2xzSG9vayQxKHRhcmdldC5fX1ZVRV9ERVZUT09MU19HTE9CQUxfSE9PS19fLCB0YXJnZXQpOw0KICB9DQogIGNvbnN0IHsNCiAgICBpbnNlcnQ6IGhvc3RJbnNlcnQsDQogICAgcmVtb3ZlOiBob3N0UmVtb3ZlLA0KICAgIHBhdGNoUHJvcDogaG9zdFBhdGNoUHJvcCwNCiAgICBjcmVhdGVFbGVtZW50OiBob3N0Q3JlYXRlRWxlbWVudCwNCiAgICBjcmVhdGVUZXh0OiBob3N0Q3JlYXRlVGV4dCwNCiAgICBjcmVhdGVDb21tZW50OiBob3N0Q3JlYXRlQ29tbWVudCwNCiAgICBzZXRUZXh0OiBob3N0U2V0VGV4dCwNCiAgICBzZXRFbGVtZW50VGV4dDogaG9zdFNldEVsZW1lbnRUZXh0LA0KICAgIHBhcmVudE5vZGU6IGhvc3RQYXJlbnROb2RlLA0KICAgIG5leHRTaWJsaW5nOiBob3N0TmV4dFNpYmxpbmcsDQogICAgc2V0U2NvcGVJZDogaG9zdFNldFNjb3BlSWQgPSBOT09QLA0KICAgIGluc2VydFN0YXRpY0NvbnRlbnQ6IGhvc3RJbnNlcnRTdGF0aWNDb250ZW50DQogIH0gPSBvcHRpb25zOw0KICBjb25zdCBwYXRjaCA9IChuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yID0gbnVsbCwgcGFyZW50Q29tcG9uZW50ID0gbnVsbCwgcGFyZW50U3VzcGVuc2UgPSBudWxsLCBuYW1lc3BhY2UgPSB2b2lkIDAsIHNsb3RTY29wZUlkcyA9IG51bGwsIG9wdGltaXplZCA9IGlzSG1yVXBkYXRpbmcgPyBmYWxzZSA6ICEhbjIuZHluYW1pY0NoaWxkcmVuKSA9PiB7DQogICAgaWYgKG4xID09PSBuMikgew0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBpZiAobjEgJiYgIWlzU2FtZVZOb2RlVHlwZShuMSwgbjIpKSB7DQogICAgICBhbmNob3IgPSBnZXROZXh0SG9zdE5vZGUobjEpOw0KICAgICAgdW5tb3VudChuMSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgdHJ1ZSk7DQogICAgICBuMSA9IG51bGw7DQogICAgfQ0KICAgIGlmIChuMi5wYXRjaEZsYWcgPT09IC0yKSB7DQogICAgICBvcHRpbWl6ZWQgPSBmYWxzZTsNCiAgICAgIG4yLmR5bmFtaWNDaGlsZHJlbiA9IG51bGw7DQogICAgfQ0KICAgIGNvbnN0IHsgdHlwZSwgcmVmLCBzaGFwZUZsYWcgfSA9IG4yOw0KICAgIHN3aXRjaCAodHlwZSkgew0KICAgICAgY2FzZSBUZXh0Og0KICAgICAgICBwcm9jZXNzVGV4dChuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yKTsNCiAgICAgICAgYnJlYWs7DQogICAgICBjYXNlIENvbW1lbnQ6DQogICAgICAgIHByb2Nlc3NDb21tZW50Tm9kZShuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yKTsNCiAgICAgICAgYnJlYWs7DQogICAgICBjYXNlIFN0YXRpYzoNCiAgICAgICAgaWYgKG4xID09IG51bGwpIHsNCiAgICAgICAgICBtb3VudFN0YXRpY05vZGUobjIsIGNvbnRhaW5lciwgYW5jaG9yLCBuYW1lc3BhY2UpOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIHBhdGNoU3RhdGljTm9kZShuMSwgbjIsIGNvbnRhaW5lciwgbmFtZXNwYWNlKTsNCiAgICAgICAgfQ0KICAgICAgICBicmVhazsNCiAgICAgIGNhc2UgRnJhZ21lbnQ6DQogICAgICAgIHByb2Nlc3NGcmFnbWVudCgNCiAgICAgICAgICBuMSwNCiAgICAgICAgICBuMiwNCiAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICApOw0KICAgICAgICBicmVhazsNCiAgICAgIGRlZmF1bHQ6DQogICAgICAgIGlmIChzaGFwZUZsYWcgJiAxKSB7DQogICAgICAgICAgcHJvY2Vzc0VsZW1lbnQoDQogICAgICAgICAgICBuMSwNCiAgICAgICAgICAgIG4yLA0KICAgICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgICApOw0KICAgICAgICB9IGVsc2UgaWYgKHNoYXBlRmxhZyAmIDYpIHsNCiAgICAgICAgICBwcm9jZXNzQ29tcG9uZW50KA0KICAgICAgICAgICAgbjEsDQogICAgICAgICAgICBuMiwNCiAgICAgICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgICAgIGFuY2hvciwNCiAgICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICAgKTsNCiAgICAgICAgfSBlbHNlIGlmIChzaGFwZUZsYWcgJiA2NCkgew0KICAgICAgICAgIHR5cGUucHJvY2VzcygNCiAgICAgICAgICAgIG4xLA0KICAgICAgICAgICAgbjIsDQogICAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgICBhbmNob3IsDQogICAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICAgIG9wdGltaXplZCwNCiAgICAgICAgICAgIGludGVybmFscw0KICAgICAgICAgICk7DQogICAgICAgIH0gZWxzZSBpZiAoc2hhcGVGbGFnICYgMTI4KSB7DQogICAgICAgICAgdHlwZS5wcm9jZXNzKA0KICAgICAgICAgICAgbjEsDQogICAgICAgICAgICBuMiwNCiAgICAgICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgICAgIGFuY2hvciwNCiAgICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgICAgb3B0aW1pemVkLA0KICAgICAgICAgICAgaW50ZXJuYWxzDQogICAgICAgICAgKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICB3YXJuJDEoIkludmFsaWQgVk5vZGUgdHlwZToiLCB0eXBlLCBgKCR7dHlwZW9mIHR5cGV9KWApOw0KICAgICAgICB9DQogICAgfQ0KICAgIGlmIChyZWYgIT0gbnVsbCAmJiBwYXJlbnRDb21wb25lbnQpIHsNCiAgICAgIHNldFJlZihyZWYsIG4xICYmIG4xLnJlZiwgcGFyZW50U3VzcGVuc2UsIG4yIHx8IG4xLCAhbjIpOw0KICAgIH0gZWxzZSBpZiAocmVmID09IG51bGwgJiYgbjEgJiYgbjEucmVmICE9IG51bGwpIHsNCiAgICAgIHNldFJlZihuMS5yZWYsIG51bGwsIHBhcmVudFN1c3BlbnNlLCBuMSwgdHJ1ZSk7DQogICAgfQ0KICB9Ow0KICBjb25zdCBwcm9jZXNzVGV4dCA9IChuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yKSA9PiB7DQogICAgaWYgKG4xID09IG51bGwpIHsNCiAgICAgIGhvc3RJbnNlcnQoDQogICAgICAgIG4yLmVsID0gaG9zdENyZWF0ZVRleHQobjIuY2hpbGRyZW4pLA0KICAgICAgICBjb250YWluZXIsDQogICAgICAgIGFuY2hvcg0KICAgICAgKTsNCiAgICB9IGVsc2Ugew0KICAgICAgY29uc3QgZWwgPSBuMi5lbCA9IG4xLmVsOw0KICAgICAgaWYgKG4yLmNoaWxkcmVuICE9PSBuMS5jaGlsZHJlbikgew0KICAgICAgICBob3N0U2V0VGV4dChlbCwgbjIuY2hpbGRyZW4pOw0KICAgICAgfQ0KICAgIH0NCiAgfTsNCiAgY29uc3QgcHJvY2Vzc0NvbW1lbnROb2RlID0gKG4xLCBuMiwgY29udGFpbmVyLCBhbmNob3IpID0+IHsNCiAgICBpZiAobjEgPT0gbnVsbCkgew0KICAgICAgaG9zdEluc2VydCgNCiAgICAgICAgbjIuZWwgPSBob3N0Q3JlYXRlQ29tbWVudChuMi5jaGlsZHJlbiB8fCAiIiksDQogICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgYW5jaG9yDQogICAgICApOw0KICAgIH0gZWxzZSB7DQogICAgICBuMi5lbCA9IG4xLmVsOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgbW91bnRTdGF0aWNOb2RlID0gKG4yLCBjb250YWluZXIsIGFuY2hvciwgbmFtZXNwYWNlKSA9PiB7DQogICAgW24yLmVsLCBuMi5hbmNob3JdID0gaG9zdEluc2VydFN0YXRpY0NvbnRlbnQoDQogICAgICBuMi5jaGlsZHJlbiwNCiAgICAgIGNvbnRhaW5lciwNCiAgICAgIGFuY2hvciwNCiAgICAgIG5hbWVzcGFjZSwNCiAgICAgIG4yLmVsLA0KICAgICAgbjIuYW5jaG9yDQogICAgKTsNCiAgfTsNCiAgY29uc3QgcGF0Y2hTdGF0aWNOb2RlID0gKG4xLCBuMiwgY29udGFpbmVyLCBuYW1lc3BhY2UpID0+IHsNCiAgICBpZiAobjIuY2hpbGRyZW4gIT09IG4xLmNoaWxkcmVuKSB7DQogICAgICBjb25zdCBhbmNob3IgPSBob3N0TmV4dFNpYmxpbmcobjEuYW5jaG9yKTsNCiAgICAgIHJlbW92ZVN0YXRpY05vZGUobjEpOw0KICAgICAgW24yLmVsLCBuMi5hbmNob3JdID0gaG9zdEluc2VydFN0YXRpY0NvbnRlbnQoDQogICAgICAgIG4yLmNoaWxkcmVuLA0KICAgICAgICBjb250YWluZXIsDQogICAgICAgIGFuY2hvciwNCiAgICAgICAgbmFtZXNwYWNlDQogICAgICApOw0KICAgIH0gZWxzZSB7DQogICAgICBuMi5lbCA9IG4xLmVsOw0KICAgICAgbjIuYW5jaG9yID0gbjEuYW5jaG9yOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgbW92ZVN0YXRpY05vZGUgPSAoeyBlbCwgYW5jaG9yIH0sIGNvbnRhaW5lciwgbmV4dFNpYmxpbmcpID0+IHsNCiAgICBsZXQgbmV4dDsNCiAgICB3aGlsZSAoZWwgJiYgZWwgIT09IGFuY2hvcikgew0KICAgICAgbmV4dCA9IGhvc3ROZXh0U2libGluZyhlbCk7DQogICAgICBob3N0SW5zZXJ0KGVsLCBjb250YWluZXIsIG5leHRTaWJsaW5nKTsNCiAgICAgIGVsID0gbmV4dDsNCiAgICB9DQogICAgaG9zdEluc2VydChhbmNob3IsIGNvbnRhaW5lciwgbmV4dFNpYmxpbmcpOw0KICB9Ow0KICBjb25zdCByZW1vdmVTdGF0aWNOb2RlID0gKHsgZWwsIGFuY2hvciB9KSA9PiB7DQogICAgbGV0IG5leHQ7DQogICAgd2hpbGUgKGVsICYmIGVsICE9PSBhbmNob3IpIHsNCiAgICAgIG5leHQgPSBob3N0TmV4dFNpYmxpbmcoZWwpOw0KICAgICAgaG9zdFJlbW92ZShlbCk7DQogICAgICBlbCA9IG5leHQ7DQogICAgfQ0KICAgIGhvc3RSZW1vdmUoYW5jaG9yKTsNCiAgfTsNCiAgY29uc3QgcHJvY2Vzc0VsZW1lbnQgPSAobjEsIG4yLCBjb250YWluZXIsIGFuY2hvciwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgbmFtZXNwYWNlLCBzbG90U2NvcGVJZHMsIG9wdGltaXplZCkgPT4gew0KICAgIGlmIChuMi50eXBlID09PSAic3ZnIikgew0KICAgICAgbmFtZXNwYWNlID0gInN2ZyI7DQogICAgfSBlbHNlIGlmIChuMi50eXBlID09PSAibWF0aCIpIHsNCiAgICAgIG5hbWVzcGFjZSA9ICJtYXRobWwiOw0KICAgIH0NCiAgICBpZiAobjEgPT0gbnVsbCkgew0KICAgICAgbW91bnRFbGVtZW50KA0KICAgICAgICBuMiwNCiAgICAgICAgY29udGFpbmVyLA0KICAgICAgICBhbmNob3IsDQogICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICk7DQogICAgfSBlbHNlIHsNCiAgICAgIHBhdGNoRWxlbWVudCgNCiAgICAgICAgbjEsDQogICAgICAgIG4yLA0KICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgb3B0aW1pemVkDQogICAgICApOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgbW91bnRFbGVtZW50ID0gKHZub2RlLCBjb250YWluZXIsIGFuY2hvciwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgbmFtZXNwYWNlLCBzbG90U2NvcGVJZHMsIG9wdGltaXplZCkgPT4gew0KICAgIGxldCBlbDsNCiAgICBsZXQgdm5vZGVIb29rOw0KICAgIGNvbnN0IHsgcHJvcHMsIHNoYXBlRmxhZywgdHJhbnNpdGlvbiwgZGlycyB9ID0gdm5vZGU7DQogICAgZWwgPSB2bm9kZS5lbCA9IGhvc3RDcmVhdGVFbGVtZW50KA0KICAgICAgdm5vZGUudHlwZSwNCiAgICAgIG5hbWVzcGFjZSwNCiAgICAgIHByb3BzICYmIHByb3BzLmlzLA0KICAgICAgcHJvcHMNCiAgICApOw0KICAgIGlmIChzaGFwZUZsYWcgJiA4KSB7DQogICAgICBob3N0U2V0RWxlbWVudFRleHQoZWwsIHZub2RlLmNoaWxkcmVuKTsNCiAgICB9IGVsc2UgaWYgKHNoYXBlRmxhZyAmIDE2KSB7DQogICAgICBtb3VudENoaWxkcmVuKA0KICAgICAgICB2bm9kZS5jaGlsZHJlbiwNCiAgICAgICAgZWwsDQogICAgICAgIG51bGwsDQogICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgIHJlc29sdmVDaGlsZHJlbk5hbWVzcGFjZSh2bm9kZSwgbmFtZXNwYWNlKSwNCiAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICk7DQogICAgfQ0KICAgIGlmIChkaXJzKSB7DQogICAgICBpbnZva2VEaXJlY3RpdmVIb29rKHZub2RlLCBudWxsLCBwYXJlbnRDb21wb25lbnQsICJjcmVhdGVkIik7DQogICAgfQ0KICAgIHNldFNjb3BlSWQoZWwsIHZub2RlLCB2bm9kZS5zY29wZUlkLCBzbG90U2NvcGVJZHMsIHBhcmVudENvbXBvbmVudCk7DQogICAgaWYgKHByb3BzKSB7DQogICAgICBmb3IgKGNvbnN0IGtleSBpbiBwcm9wcykgew0KICAgICAgICBpZiAoa2V5ICE9PSAidmFsdWUiICYmICFpc1Jlc2VydmVkUHJvcChrZXkpKSB7DQogICAgICAgICAgaG9zdFBhdGNoUHJvcChlbCwga2V5LCBudWxsLCBwcm9wc1trZXldLCBuYW1lc3BhY2UsIHBhcmVudENvbXBvbmVudCk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGlmICgidmFsdWUiIGluIHByb3BzKSB7DQogICAgICAgIGhvc3RQYXRjaFByb3AoZWwsICJ2YWx1ZSIsIG51bGwsIHByb3BzLnZhbHVlLCBuYW1lc3BhY2UpOw0KICAgICAgfQ0KICAgICAgaWYgKHZub2RlSG9vayA9IHByb3BzLm9uVm5vZGVCZWZvcmVNb3VudCkgew0KICAgICAgICBpbnZva2VWTm9kZUhvb2sodm5vZGVIb29rLCBwYXJlbnRDb21wb25lbnQsIHZub2RlKTsNCiAgICAgIH0NCiAgICB9DQogICAgew0KICAgICAgZGVmKGVsLCAiX192bm9kZSIsIHZub2RlLCB0cnVlKTsNCiAgICAgIGRlZihlbCwgIl9fdnVlUGFyZW50Q29tcG9uZW50IiwgcGFyZW50Q29tcG9uZW50LCB0cnVlKTsNCiAgICB9DQogICAgaWYgKGRpcnMpIHsNCiAgICAgIGludm9rZURpcmVjdGl2ZUhvb2sodm5vZGUsIG51bGwsIHBhcmVudENvbXBvbmVudCwgImJlZm9yZU1vdW50Iik7DQogICAgfQ0KICAgIGNvbnN0IG5lZWRDYWxsVHJhbnNpdGlvbkhvb2tzID0gbmVlZFRyYW5zaXRpb24ocGFyZW50U3VzcGVuc2UsIHRyYW5zaXRpb24pOw0KICAgIGlmIChuZWVkQ2FsbFRyYW5zaXRpb25Ib29rcykgew0KICAgICAgdHJhbnNpdGlvbi5iZWZvcmVFbnRlcihlbCk7DQogICAgfQ0KICAgIGhvc3RJbnNlcnQoZWwsIGNvbnRhaW5lciwgYW5jaG9yKTsNCiAgICBpZiAoKHZub2RlSG9vayA9IHByb3BzICYmIHByb3BzLm9uVm5vZGVNb3VudGVkKSB8fCBuZWVkQ2FsbFRyYW5zaXRpb25Ib29rcyB8fCBkaXJzKSB7DQogICAgICBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QoKCkgPT4gew0KICAgICAgICB2bm9kZUhvb2sgJiYgaW52b2tlVk5vZGVIb29rKHZub2RlSG9vaywgcGFyZW50Q29tcG9uZW50LCB2bm9kZSk7DQogICAgICAgIG5lZWRDYWxsVHJhbnNpdGlvbkhvb2tzICYmIHRyYW5zaXRpb24uZW50ZXIoZWwpOw0KICAgICAgICBkaXJzICYmIGludm9rZURpcmVjdGl2ZUhvb2sodm5vZGUsIG51bGwsIHBhcmVudENvbXBvbmVudCwgIm1vdW50ZWQiKTsNCiAgICAgIH0sIHBhcmVudFN1c3BlbnNlKTsNCiAgICB9DQogIH07DQogIGNvbnN0IHNldFNjb3BlSWQgPSAoZWwsIHZub2RlLCBzY29wZUlkLCBzbG90U2NvcGVJZHMsIHBhcmVudENvbXBvbmVudCkgPT4gew0KICAgIGlmIChzY29wZUlkKSB7DQogICAgICBob3N0U2V0U2NvcGVJZChlbCwgc2NvcGVJZCk7DQogICAgfQ0KICAgIGlmIChzbG90U2NvcGVJZHMpIHsNCiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2xvdFNjb3BlSWRzLmxlbmd0aDsgaSsrKSB7DQogICAgICAgIGhvc3RTZXRTY29wZUlkKGVsLCBzbG90U2NvcGVJZHNbaV0pOw0KICAgICAgfQ0KICAgIH0NCiAgICBpZiAocGFyZW50Q29tcG9uZW50KSB7DQogICAgICBsZXQgc3ViVHJlZSA9IHBhcmVudENvbXBvbmVudC5zdWJUcmVlOw0KICAgICAgaWYgKHN1YlRyZWUucGF0Y2hGbGFnID4gMCAmJiBzdWJUcmVlLnBhdGNoRmxhZyAmIDIwNDgpIHsNCiAgICAgICAgc3ViVHJlZSA9IGZpbHRlclNpbmdsZVJvb3Qoc3ViVHJlZS5jaGlsZHJlbikgfHwgc3ViVHJlZTsNCiAgICAgIH0NCiAgICAgIGlmICh2bm9kZSA9PT0gc3ViVHJlZSB8fCBpc1N1c3BlbnNlKHN1YlRyZWUudHlwZSkgJiYgKHN1YlRyZWUuc3NDb250ZW50ID09PSB2bm9kZSB8fCBzdWJUcmVlLnNzRmFsbGJhY2sgPT09IHZub2RlKSkgew0KICAgICAgICBjb25zdCBwYXJlbnRWTm9kZSA9IHBhcmVudENvbXBvbmVudC52bm9kZTsNCiAgICAgICAgc2V0U2NvcGVJZCgNCiAgICAgICAgICBlbCwNCiAgICAgICAgICBwYXJlbnRWTm9kZSwNCiAgICAgICAgICBwYXJlbnRWTm9kZS5zY29wZUlkLA0KICAgICAgICAgIHBhcmVudFZOb2RlLnNsb3RTY29wZUlkcywNCiAgICAgICAgICBwYXJlbnRDb21wb25lbnQucGFyZW50DQogICAgICAgICk7DQogICAgICB9DQogICAgfQ0KICB9Ow0KICBjb25zdCBtb3VudENoaWxkcmVuID0gKGNoaWxkcmVuLCBjb250YWluZXIsIGFuY2hvciwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgbmFtZXNwYWNlLCBzbG90U2NvcGVJZHMsIG9wdGltaXplZCwgc3RhcnQgPSAwKSA9PiB7DQogICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHsNCiAgICAgIGNvbnN0IGNoaWxkID0gY2hpbGRyZW5baV0gPSBvcHRpbWl6ZWQgPyBjbG9uZUlmTW91bnRlZChjaGlsZHJlbltpXSkgOiBub3JtYWxpemVWTm9kZShjaGlsZHJlbltpXSk7DQogICAgICBwYXRjaCgNCiAgICAgICAgbnVsbCwNCiAgICAgICAgY2hpbGQsDQogICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgYW5jaG9yLA0KICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgb3B0aW1pemVkDQogICAgICApOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgcGF0Y2hFbGVtZW50ID0gKG4xLCBuMiwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgbmFtZXNwYWNlLCBzbG90U2NvcGVJZHMsIG9wdGltaXplZCkgPT4gew0KICAgIGNvbnN0IGVsID0gbjIuZWwgPSBuMS5lbDsNCiAgICB7DQogICAgICBlbC5fX3Zub2RlID0gbjI7DQogICAgfQ0KICAgIGxldCB7IHBhdGNoRmxhZywgZHluYW1pY0NoaWxkcmVuLCBkaXJzIH0gPSBuMjsNCiAgICBwYXRjaEZsYWcgfD0gbjEucGF0Y2hGbGFnICYgMTY7DQogICAgY29uc3Qgb2xkUHJvcHMgPSBuMS5wcm9wcyB8fCBFTVBUWV9PQko7DQogICAgY29uc3QgbmV3UHJvcHMgPSBuMi5wcm9wcyB8fCBFTVBUWV9PQko7DQogICAgbGV0IHZub2RlSG9vazsNCiAgICBwYXJlbnRDb21wb25lbnQgJiYgdG9nZ2xlUmVjdXJzZShwYXJlbnRDb21wb25lbnQsIGZhbHNlKTsNCiAgICBpZiAodm5vZGVIb29rID0gbmV3UHJvcHMub25Wbm9kZUJlZm9yZVVwZGF0ZSkgew0KICAgICAgaW52b2tlVk5vZGVIb29rKHZub2RlSG9vaywgcGFyZW50Q29tcG9uZW50LCBuMiwgbjEpOw0KICAgIH0NCiAgICBpZiAoZGlycykgew0KICAgICAgaW52b2tlRGlyZWN0aXZlSG9vayhuMiwgbjEsIHBhcmVudENvbXBvbmVudCwgImJlZm9yZVVwZGF0ZSIpOw0KICAgIH0NCiAgICBwYXJlbnRDb21wb25lbnQgJiYgdG9nZ2xlUmVjdXJzZShwYXJlbnRDb21wb25lbnQsIHRydWUpOw0KICAgIGlmIChpc0htclVwZGF0aW5nKSB7DQogICAgICBwYXRjaEZsYWcgPSAwOw0KICAgICAgb3B0aW1pemVkID0gZmFsc2U7DQogICAgICBkeW5hbWljQ2hpbGRyZW4gPSBudWxsOw0KICAgIH0NCiAgICBpZiAob2xkUHJvcHMuaW5uZXJIVE1MICYmIG5ld1Byb3BzLmlubmVySFRNTCA9PSBudWxsIHx8IG9sZFByb3BzLnRleHRDb250ZW50ICYmIG5ld1Byb3BzLnRleHRDb250ZW50ID09IG51bGwpIHsNCiAgICAgIGhvc3RTZXRFbGVtZW50VGV4dChlbCwgIiIpOw0KICAgIH0NCiAgICBpZiAoZHluYW1pY0NoaWxkcmVuKSB7DQogICAgICBwYXRjaEJsb2NrQ2hpbGRyZW4oDQogICAgICAgIG4xLmR5bmFtaWNDaGlsZHJlbiwNCiAgICAgICAgZHluYW1pY0NoaWxkcmVuLA0KICAgICAgICBlbCwNCiAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgcmVzb2x2ZUNoaWxkcmVuTmFtZXNwYWNlKG4yLCBuYW1lc3BhY2UpLA0KICAgICAgICBzbG90U2NvcGVJZHMNCiAgICAgICk7DQogICAgICB7DQogICAgICAgIHRyYXZlcnNlU3RhdGljQ2hpbGRyZW4objEsIG4yKTsNCiAgICAgIH0NCiAgICB9IGVsc2UgaWYgKCFvcHRpbWl6ZWQpIHsNCiAgICAgIHBhdGNoQ2hpbGRyZW4oDQogICAgICAgIG4xLA0KICAgICAgICBuMiwNCiAgICAgICAgZWwsDQogICAgICAgIG51bGwsDQogICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgIHJlc29sdmVDaGlsZHJlbk5hbWVzcGFjZShuMiwgbmFtZXNwYWNlKSwNCiAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICBmYWxzZQ0KICAgICAgKTsNCiAgICB9DQogICAgaWYgKHBhdGNoRmxhZyA+IDApIHsNCiAgICAgIGlmIChwYXRjaEZsYWcgJiAxNikgew0KICAgICAgICBwYXRjaFByb3BzKGVsLCBvbGRQcm9wcywgbmV3UHJvcHMsIHBhcmVudENvbXBvbmVudCwgbmFtZXNwYWNlKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGlmIChwYXRjaEZsYWcgJiAyKSB7DQogICAgICAgICAgaWYgKG9sZFByb3BzLmNsYXNzICE9PSBuZXdQcm9wcy5jbGFzcykgew0KICAgICAgICAgICAgaG9zdFBhdGNoUHJvcChlbCwgImNsYXNzIiwgbnVsbCwgbmV3UHJvcHMuY2xhc3MsIG5hbWVzcGFjZSk7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGlmIChwYXRjaEZsYWcgJiA0KSB7DQogICAgICAgICAgaG9zdFBhdGNoUHJvcChlbCwgInN0eWxlIiwgb2xkUHJvcHMuc3R5bGUsIG5ld1Byb3BzLnN0eWxlLCBuYW1lc3BhY2UpOw0KICAgICAgICB9DQogICAgICAgIGlmIChwYXRjaEZsYWcgJiA4KSB7DQogICAgICAgICAgY29uc3QgcHJvcHNUb1VwZGF0ZSA9IG4yLmR5bmFtaWNQcm9wczsNCiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByb3BzVG9VcGRhdGUubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgICAgIGNvbnN0IGtleSA9IHByb3BzVG9VcGRhdGVbaV07DQogICAgICAgICAgICBjb25zdCBwcmV2ID0gb2xkUHJvcHNba2V5XTsNCiAgICAgICAgICAgIGNvbnN0IG5leHQgPSBuZXdQcm9wc1trZXldOw0KICAgICAgICAgICAgaWYgKG5leHQgIT09IHByZXYgfHwga2V5ID09PSAidmFsdWUiKSB7DQogICAgICAgICAgICAgIGhvc3RQYXRjaFByb3AoZWwsIGtleSwgcHJldiwgbmV4dCwgbmFtZXNwYWNlLCBwYXJlbnRDb21wb25lbnQpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgaWYgKHBhdGNoRmxhZyAmIDEpIHsNCiAgICAgICAgaWYgKG4xLmNoaWxkcmVuICE9PSBuMi5jaGlsZHJlbikgew0KICAgICAgICAgIGhvc3RTZXRFbGVtZW50VGV4dChlbCwgbjIuY2hpbGRyZW4pOw0KICAgICAgICB9DQogICAgICB9DQogICAgfSBlbHNlIGlmICghb3B0aW1pemVkICYmIGR5bmFtaWNDaGlsZHJlbiA9PSBudWxsKSB7DQogICAgICBwYXRjaFByb3BzKGVsLCBvbGRQcm9wcywgbmV3UHJvcHMsIHBhcmVudENvbXBvbmVudCwgbmFtZXNwYWNlKTsNCiAgICB9DQogICAgaWYgKCh2bm9kZUhvb2sgPSBuZXdQcm9wcy5vblZub2RlVXBkYXRlZCkgfHwgZGlycykgew0KICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KCgpID0+IHsNCiAgICAgICAgdm5vZGVIb29rICYmIGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIHBhcmVudENvbXBvbmVudCwgbjIsIG4xKTsNCiAgICAgICAgZGlycyAmJiBpbnZva2VEaXJlY3RpdmVIb29rKG4yLCBuMSwgcGFyZW50Q29tcG9uZW50LCAidXBkYXRlZCIpOw0KICAgICAgfSwgcGFyZW50U3VzcGVuc2UpOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgcGF0Y2hCbG9ja0NoaWxkcmVuID0gKG9sZENoaWxkcmVuLCBuZXdDaGlsZHJlbiwgZmFsbGJhY2tDb250YWluZXIsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzKSA9PiB7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuZXdDaGlsZHJlbi5sZW5ndGg7IGkrKykgew0KICAgICAgY29uc3Qgb2xkVk5vZGUgPSBvbGRDaGlsZHJlbltpXTsNCiAgICAgIGNvbnN0IG5ld1ZOb2RlID0gbmV3Q2hpbGRyZW5baV07DQogICAgICBjb25zdCBjb250YWluZXIgPSAoDQogICAgICAgIC8vIG9sZFZOb2RlIG1heSBiZSBhbiBlcnJvcmVkIGFzeW5jIHNldHVwKCkgY29tcG9uZW50IGluc2lkZSBTdXNwZW5zZQ0KICAgICAgICAvLyB3aGljaCB3aWxsIG5vdCBoYXZlIGEgbW91bnRlZCBlbGVtZW50DQogICAgICAgIG9sZFZOb2RlLmVsICYmIC8vIC0gSW4gdGhlIGNhc2Ugb2YgYSBGcmFnbWVudCwgd2UgbmVlZCB0byBwcm92aWRlIHRoZSBhY3R1YWwgcGFyZW50DQogICAgICAgIC8vIG9mIHRoZSBGcmFnbWVudCBpdHNlbGYgc28gaXQgY2FuIG1vdmUgaXRzIGNoaWxkcmVuLg0KICAgICAgICAob2xkVk5vZGUudHlwZSA9PT0gRnJhZ21lbnQgfHwgLy8gLSBJbiB0aGUgY2FzZSBvZiBkaWZmZXJlbnQgbm9kZXMsIHRoZXJlIGlzIGdvaW5nIHRvIGJlIGEgcmVwbGFjZW1lbnQNCiAgICAgICAgLy8gd2hpY2ggYWxzbyByZXF1aXJlcyB0aGUgY29ycmVjdCBwYXJlbnQgY29udGFpbmVyDQogICAgICAgICFpc1NhbWVWTm9kZVR5cGUob2xkVk5vZGUsIG5ld1ZOb2RlKSB8fCAvLyAtIEluIHRoZSBjYXNlIG9mIGEgY29tcG9uZW50LCBpdCBjb3VsZCBjb250YWluIGFueXRoaW5nLg0KICAgICAgICBvbGRWTm9kZS5zaGFwZUZsYWcgJiAoNiB8IDY0IHwgMTI4KSkgPyBob3N0UGFyZW50Tm9kZShvbGRWTm9kZS5lbCkgOiAoDQogICAgICAgICAgLy8gSW4gb3RoZXIgY2FzZXMsIHRoZSBwYXJlbnQgY29udGFpbmVyIGlzIG5vdCBhY3R1YWxseSB1c2VkIHNvIHdlDQogICAgICAgICAgLy8ganVzdCBwYXNzIHRoZSBibG9jayBlbGVtZW50IGhlcmUgdG8gYXZvaWQgYSBET00gcGFyZW50Tm9kZSBjYWxsLg0KICAgICAgICAgIGZhbGxiYWNrQ29udGFpbmVyDQogICAgICAgICkNCiAgICAgICk7DQogICAgICBwYXRjaCgNCiAgICAgICAgb2xkVk5vZGUsDQogICAgICAgIG5ld1ZOb2RlLA0KICAgICAgICBjb250YWluZXIsDQogICAgICAgIG51bGwsDQogICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICB0cnVlDQogICAgICApOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgcGF0Y2hQcm9wcyA9IChlbCwgb2xkUHJvcHMsIG5ld1Byb3BzLCBwYXJlbnRDb21wb25lbnQsIG5hbWVzcGFjZSkgPT4gew0KICAgIGlmIChvbGRQcm9wcyAhPT0gbmV3UHJvcHMpIHsNCiAgICAgIGlmIChvbGRQcm9wcyAhPT0gRU1QVFlfT0JKKSB7DQogICAgICAgIGZvciAoY29uc3Qga2V5IGluIG9sZFByb3BzKSB7DQogICAgICAgICAgaWYgKCFpc1Jlc2VydmVkUHJvcChrZXkpICYmICEoa2V5IGluIG5ld1Byb3BzKSkgew0KICAgICAgICAgICAgaG9zdFBhdGNoUHJvcCgNCiAgICAgICAgICAgICAgZWwsDQogICAgICAgICAgICAgIGtleSwNCiAgICAgICAgICAgICAgb2xkUHJvcHNba2V5XSwNCiAgICAgICAgICAgICAgbnVsbCwNCiAgICAgICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgICAgICBwYXJlbnRDb21wb25lbnQNCiAgICAgICAgICAgICk7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICB9DQogICAgICBmb3IgKGNvbnN0IGtleSBpbiBuZXdQcm9wcykgew0KICAgICAgICBpZiAoaXNSZXNlcnZlZFByb3Aoa2V5KSkgY29udGludWU7DQogICAgICAgIGNvbnN0IG5leHQgPSBuZXdQcm9wc1trZXldOw0KICAgICAgICBjb25zdCBwcmV2ID0gb2xkUHJvcHNba2V5XTsNCiAgICAgICAgaWYgKG5leHQgIT09IHByZXYgJiYga2V5ICE9PSAidmFsdWUiKSB7DQogICAgICAgICAgaG9zdFBhdGNoUHJvcChlbCwga2V5LCBwcmV2LCBuZXh0LCBuYW1lc3BhY2UsIHBhcmVudENvbXBvbmVudCk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGlmICgidmFsdWUiIGluIG5ld1Byb3BzKSB7DQogICAgICAgIGhvc3RQYXRjaFByb3AoZWwsICJ2YWx1ZSIsIG9sZFByb3BzLnZhbHVlLCBuZXdQcm9wcy52YWx1ZSwgbmFtZXNwYWNlKTsNCiAgICAgIH0NCiAgICB9DQogIH07DQogIGNvbnN0IHByb2Nlc3NGcmFnbWVudCA9IChuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBuYW1lc3BhY2UsIHNsb3RTY29wZUlkcywgb3B0aW1pemVkKSA9PiB7DQogICAgY29uc3QgZnJhZ21lbnRTdGFydEFuY2hvciA9IG4yLmVsID0gbjEgPyBuMS5lbCA6IGhvc3RDcmVhdGVUZXh0KCIiKTsNCiAgICBjb25zdCBmcmFnbWVudEVuZEFuY2hvciA9IG4yLmFuY2hvciA9IG4xID8gbjEuYW5jaG9yIDogaG9zdENyZWF0ZVRleHQoIiIpOw0KICAgIGxldCB7IHBhdGNoRmxhZywgZHluYW1pY0NoaWxkcmVuLCBzbG90U2NvcGVJZHM6IGZyYWdtZW50U2xvdFNjb3BlSWRzIH0gPSBuMjsNCiAgICBpZiAoDQogICAgICAvLyAjNTUyMyBkZXYgcm9vdCBmcmFnbWVudCBtYXkgaW5oZXJpdCBkaXJlY3RpdmVzDQogICAgICBpc0htclVwZGF0aW5nIHx8IHBhdGNoRmxhZyAmIDIwNDgNCiAgICApIHsNCiAgICAgIHBhdGNoRmxhZyA9IDA7DQogICAgICBvcHRpbWl6ZWQgPSBmYWxzZTsNCiAgICAgIGR5bmFtaWNDaGlsZHJlbiA9IG51bGw7DQogICAgfQ0KICAgIGlmIChmcmFnbWVudFNsb3RTY29wZUlkcykgew0KICAgICAgc2xvdFNjb3BlSWRzID0gc2xvdFNjb3BlSWRzID8gc2xvdFNjb3BlSWRzLmNvbmNhdChmcmFnbWVudFNsb3RTY29wZUlkcykgOiBmcmFnbWVudFNsb3RTY29wZUlkczsNCiAgICB9DQogICAgaWYgKG4xID09IG51bGwpIHsNCiAgICAgIGhvc3RJbnNlcnQoZnJhZ21lbnRTdGFydEFuY2hvciwgY29udGFpbmVyLCBhbmNob3IpOw0KICAgICAgaG9zdEluc2VydChmcmFnbWVudEVuZEFuY2hvciwgY29udGFpbmVyLCBhbmNob3IpOw0KICAgICAgbW91bnRDaGlsZHJlbigNCiAgICAgICAgLy8gIzEwMDA3DQogICAgICAgIC8vIHN1Y2ggZnJhZ21lbnQgbGlrZSBgPD48Lz5gIHdpbGwgYmUgY29tcGlsZWQgaW50bw0KICAgICAgICAvLyBhIGZyYWdtZW50IHdoaWNoIGRvZXNuJ3QgaGF2ZSBhIGNoaWxkcmVuLg0KICAgICAgICAvLyBJbiB0aGlzIGNhc2UgZmFsbGJhY2sgdG8gYW4gZW1wdHkgYXJyYXkNCiAgICAgICAgbjIuY2hpbGRyZW4gfHwgW10sDQogICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgZnJhZ21lbnRFbmRBbmNob3IsDQogICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICk7DQogICAgfSBlbHNlIHsNCiAgICAgIGlmIChwYXRjaEZsYWcgPiAwICYmIHBhdGNoRmxhZyAmIDY0ICYmIGR5bmFtaWNDaGlsZHJlbiAmJiAvLyAjMjcxNSB0aGUgcHJldmlvdXMgZnJhZ21lbnQgY291bGQndmUgYmVlbiBhIEJBSUxlZCBvbmUgYXMgYSByZXN1bHQNCiAgICAgIC8vIG9mIHJlbmRlclNsb3QoKSB3aXRoIG5vIHZhbGlkIGNoaWxkcmVuDQogICAgICBuMS5keW5hbWljQ2hpbGRyZW4pIHsNCiAgICAgICAgcGF0Y2hCbG9ja0NoaWxkcmVuKA0KICAgICAgICAgIG4xLmR5bmFtaWNDaGlsZHJlbiwNCiAgICAgICAgICBkeW5hbWljQ2hpbGRyZW4sDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzDQogICAgICAgICk7DQogICAgICAgIHsNCiAgICAgICAgICB0cmF2ZXJzZVN0YXRpY0NoaWxkcmVuKG4xLCBuMik7DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHBhdGNoQ2hpbGRyZW4oDQogICAgICAgICAgbjEsDQogICAgICAgICAgbjIsDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIGZyYWdtZW50RW5kQW5jaG9yLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICApOw0KICAgICAgfQ0KICAgIH0NCiAgfTsNCiAgY29uc3QgcHJvY2Vzc0NvbXBvbmVudCA9IChuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBuYW1lc3BhY2UsIHNsb3RTY29wZUlkcywgb3B0aW1pemVkKSA9PiB7DQogICAgbjIuc2xvdFNjb3BlSWRzID0gc2xvdFNjb3BlSWRzOw0KICAgIGlmIChuMSA9PSBudWxsKSB7DQogICAgICBpZiAobjIuc2hhcGVGbGFnICYgNTEyKSB7DQogICAgICAgIHBhcmVudENvbXBvbmVudC5jdHguYWN0aXZhdGUoDQogICAgICAgICAgbjIsDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIGFuY2hvciwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBtb3VudENvbXBvbmVudCgNCiAgICAgICAgICBuMiwNCiAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICk7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIHVwZGF0ZUNvbXBvbmVudChuMSwgbjIsIG9wdGltaXplZCk7DQogICAgfQ0KICB9Ow0KICBjb25zdCBtb3VudENvbXBvbmVudCA9IChpbml0aWFsVk5vZGUsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBuYW1lc3BhY2UsIG9wdGltaXplZCkgPT4gew0KICAgIGNvbnN0IGluc3RhbmNlID0gKGluaXRpYWxWTm9kZS5jb21wb25lbnQgPSBjcmVhdGVDb21wb25lbnRJbnN0YW5jZSgNCiAgICAgIGluaXRpYWxWTm9kZSwNCiAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgIHBhcmVudFN1c3BlbnNlDQogICAgKSk7DQogICAgaWYgKGluc3RhbmNlLnR5cGUuX19obXJJZCkgew0KICAgICAgcmVnaXN0ZXJITVIoaW5zdGFuY2UpOw0KICAgIH0NCiAgICB7DQogICAgICBwdXNoV2FybmluZ0NvbnRleHQoaW5pdGlhbFZOb2RlKTsNCiAgICAgIHN0YXJ0TWVhc3VyZShpbnN0YW5jZSwgYG1vdW50YCk7DQogICAgfQ0KICAgIGlmIChpc0tlZXBBbGl2ZShpbml0aWFsVk5vZGUpKSB7DQogICAgICBpbnN0YW5jZS5jdHgucmVuZGVyZXIgPSBpbnRlcm5hbHM7DQogICAgfQ0KICAgIHsNCiAgICAgIHsNCiAgICAgICAgc3RhcnRNZWFzdXJlKGluc3RhbmNlLCBgaW5pdGApOw0KICAgICAgfQ0KICAgICAgc2V0dXBDb21wb25lbnQoaW5zdGFuY2UsIGZhbHNlLCBvcHRpbWl6ZWQpOw0KICAgICAgew0KICAgICAgICBlbmRNZWFzdXJlKGluc3RhbmNlLCBgaW5pdGApOw0KICAgICAgfQ0KICAgIH0NCiAgICBpZiAoaXNIbXJVcGRhdGluZykgaW5pdGlhbFZOb2RlLmVsID0gbnVsbDsNCiAgICBpZiAoaW5zdGFuY2UuYXN5bmNEZXApIHsNCiAgICAgIHBhcmVudFN1c3BlbnNlICYmIHBhcmVudFN1c3BlbnNlLnJlZ2lzdGVyRGVwKGluc3RhbmNlLCBzZXR1cFJlbmRlckVmZmVjdCwgb3B0aW1pemVkKTsNCiAgICAgIGlmICghaW5pdGlhbFZOb2RlLmVsKSB7DQogICAgICAgIGNvbnN0IHBsYWNlaG9sZGVyID0gaW5zdGFuY2Uuc3ViVHJlZSA9IGNyZWF0ZVZOb2RlKENvbW1lbnQpOw0KICAgICAgICBwcm9jZXNzQ29tbWVudE5vZGUobnVsbCwgcGxhY2Vob2xkZXIsIGNvbnRhaW5lciwgYW5jaG9yKTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgc2V0dXBSZW5kZXJFZmZlY3QoDQogICAgICAgIGluc3RhbmNlLA0KICAgICAgICBpbml0aWFsVk5vZGUsDQogICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgYW5jaG9yLA0KICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICk7DQogICAgfQ0KICAgIHsNCiAgICAgIHBvcFdhcm5pbmdDb250ZXh0KCk7DQogICAgICBlbmRNZWFzdXJlKGluc3RhbmNlLCBgbW91bnRgKTsNCiAgICB9DQogIH07DQogIGNvbnN0IHVwZGF0ZUNvbXBvbmVudCA9IChuMSwgbjIsIG9wdGltaXplZCkgPT4gew0KICAgIGNvbnN0IGluc3RhbmNlID0gbjIuY29tcG9uZW50ID0gbjEuY29tcG9uZW50Ow0KICAgIGlmIChzaG91bGRVcGRhdGVDb21wb25lbnQobjEsIG4yLCBvcHRpbWl6ZWQpKSB7DQogICAgICBpZiAoaW5zdGFuY2UuYXN5bmNEZXAgJiYgIWluc3RhbmNlLmFzeW5jUmVzb2x2ZWQpIHsNCiAgICAgICAgew0KICAgICAgICAgIHB1c2hXYXJuaW5nQ29udGV4dChuMik7DQogICAgICAgIH0NCiAgICAgICAgdXBkYXRlQ29tcG9uZW50UHJlUmVuZGVyKGluc3RhbmNlLCBuMiwgb3B0aW1pemVkKTsNCiAgICAgICAgew0KICAgICAgICAgIHBvcFdhcm5pbmdDb250ZXh0KCk7DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgaW5zdGFuY2UubmV4dCA9IG4yOw0KICAgICAgICBpbnN0YW5jZS51cGRhdGUoKTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgbjIuZWwgPSBuMS5lbDsNCiAgICAgIGluc3RhbmNlLnZub2RlID0gbjI7DQogICAgfQ0KICB9Ow0KICBjb25zdCBzZXR1cFJlbmRlckVmZmVjdCA9IChpbnN0YW5jZSwgaW5pdGlhbFZOb2RlLCBjb250YWluZXIsIGFuY2hvciwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgb3B0aW1pemVkKSA9PiB7DQogICAgY29uc3QgY29tcG9uZW50VXBkYXRlRm4gPSAoKSA9PiB7DQogICAgICBpZiAoIWluc3RhbmNlLmlzTW91bnRlZCkgew0KICAgICAgICBsZXQgdm5vZGVIb29rOw0KICAgICAgICBjb25zdCB7IGVsLCBwcm9wcyB9ID0gaW5pdGlhbFZOb2RlOw0KICAgICAgICBjb25zdCB7IGJtLCBtLCBwYXJlbnQsIHJvb3QsIHR5cGUgfSA9IGluc3RhbmNlOw0KICAgICAgICBjb25zdCBpc0FzeW5jV3JhcHBlclZOb2RlID0gaXNBc3luY1dyYXBwZXIoaW5pdGlhbFZOb2RlKTsNCiAgICAgICAgdG9nZ2xlUmVjdXJzZShpbnN0YW5jZSwgZmFsc2UpOw0KICAgICAgICBpZiAoYm0pIHsNCiAgICAgICAgICBpbnZva2VBcnJheUZucyhibSk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKCFpc0FzeW5jV3JhcHBlclZOb2RlICYmICh2bm9kZUhvb2sgPSBwcm9wcyAmJiBwcm9wcy5vblZub2RlQmVmb3JlTW91bnQpKSB7DQogICAgICAgICAgaW52b2tlVk5vZGVIb29rKHZub2RlSG9vaywgcGFyZW50LCBpbml0aWFsVk5vZGUpOw0KICAgICAgICB9DQogICAgICAgIHRvZ2dsZVJlY3Vyc2UoaW5zdGFuY2UsIHRydWUpOw0KICAgICAgICBpZiAoZWwgJiYgaHlkcmF0ZU5vZGUpIHsNCiAgICAgICAgICBjb25zdCBoeWRyYXRlU3ViVHJlZSA9ICgpID0+IHsNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgc3RhcnRNZWFzdXJlKGluc3RhbmNlLCBgcmVuZGVyYCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBpbnN0YW5jZS5zdWJUcmVlID0gcmVuZGVyQ29tcG9uZW50Um9vdChpbnN0YW5jZSk7DQogICAgICAgICAgICB7DQogICAgICAgICAgICAgIGVuZE1lYXN1cmUoaW5zdGFuY2UsIGByZW5kZXJgKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgc3RhcnRNZWFzdXJlKGluc3RhbmNlLCBgaHlkcmF0ZWApOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgaHlkcmF0ZU5vZGUoDQogICAgICAgICAgICAgIGVsLA0KICAgICAgICAgICAgICBpbnN0YW5jZS5zdWJUcmVlLA0KICAgICAgICAgICAgICBpbnN0YW5jZSwNCiAgICAgICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgICAgIG51bGwNCiAgICAgICAgICAgICk7DQogICAgICAgICAgICB7DQogICAgICAgICAgICAgIGVuZE1lYXN1cmUoaW5zdGFuY2UsIGBoeWRyYXRlYCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgfTsNCiAgICAgICAgICBpZiAoaXNBc3luY1dyYXBwZXJWTm9kZSAmJiB0eXBlLl9fYXN5bmNIeWRyYXRlKSB7DQogICAgICAgICAgICB0eXBlLl9fYXN5bmNIeWRyYXRlKA0KICAgICAgICAgICAgICBlbCwNCiAgICAgICAgICAgICAgaW5zdGFuY2UsDQogICAgICAgICAgICAgIGh5ZHJhdGVTdWJUcmVlDQogICAgICAgICAgICApOw0KICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBoeWRyYXRlU3ViVHJlZSgpOw0KICAgICAgICAgIH0NCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBpZiAocm9vdC5jZSAmJiAvLyBAdHMtZXhwZWN0LWVycm9yIF9kZWYgaXMgcHJpdmF0ZQ0KICAgICAgICAgIHJvb3QuY2UuX2RlZi5zaGFkb3dSb290ICE9PSBmYWxzZSkgew0KICAgICAgICAgICAgcm9vdC5jZS5faW5qZWN0Q2hpbGRTdHlsZSh0eXBlKTsNCiAgICAgICAgICB9DQogICAgICAgICAgew0KICAgICAgICAgICAgc3RhcnRNZWFzdXJlKGluc3RhbmNlLCBgcmVuZGVyYCk7DQogICAgICAgICAgfQ0KICAgICAgICAgIGNvbnN0IHN1YlRyZWUgPSBpbnN0YW5jZS5zdWJUcmVlID0gcmVuZGVyQ29tcG9uZW50Um9vdChpbnN0YW5jZSk7DQogICAgICAgICAgew0KICAgICAgICAgICAgZW5kTWVhc3VyZShpbnN0YW5jZSwgYHJlbmRlcmApOw0KICAgICAgICAgIH0NCiAgICAgICAgICB7DQogICAgICAgICAgICBzdGFydE1lYXN1cmUoaW5zdGFuY2UsIGBwYXRjaGApOw0KICAgICAgICAgIH0NCiAgICAgICAgICBwYXRjaCgNCiAgICAgICAgICAgIG51bGwsDQogICAgICAgICAgICBzdWJUcmVlLA0KICAgICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgICAgaW5zdGFuY2UsDQogICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgIG5hbWVzcGFjZQ0KICAgICAgICAgICk7DQogICAgICAgICAgew0KICAgICAgICAgICAgZW5kTWVhc3VyZShpbnN0YW5jZSwgYHBhdGNoYCk7DQogICAgICAgICAgfQ0KICAgICAgICAgIGluaXRpYWxWTm9kZS5lbCA9IHN1YlRyZWUuZWw7DQogICAgICAgIH0NCiAgICAgICAgaWYgKG0pIHsNCiAgICAgICAgICBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QobSwgcGFyZW50U3VzcGVuc2UpOw0KICAgICAgICB9DQogICAgICAgIGlmICghaXNBc3luY1dyYXBwZXJWTm9kZSAmJiAodm5vZGVIb29rID0gcHJvcHMgJiYgcHJvcHMub25Wbm9kZU1vdW50ZWQpKSB7DQogICAgICAgICAgY29uc3Qgc2NvcGVkSW5pdGlhbFZOb2RlID0gaW5pdGlhbFZOb2RlOw0KICAgICAgICAgIHF1ZXVlUG9zdFJlbmRlckVmZmVjdCgNCiAgICAgICAgICAgICgpID0+IGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIHBhcmVudCwgc2NvcGVkSW5pdGlhbFZOb2RlKSwNCiAgICAgICAgICAgIHBhcmVudFN1c3BlbnNlDQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgICBpZiAoaW5pdGlhbFZOb2RlLnNoYXBlRmxhZyAmIDI1NiB8fCBwYXJlbnQgJiYgaXNBc3luY1dyYXBwZXIocGFyZW50LnZub2RlKSAmJiBwYXJlbnQudm5vZGUuc2hhcGVGbGFnICYgMjU2KSB7DQogICAgICAgICAgaW5zdGFuY2UuYSAmJiBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QoaW5zdGFuY2UuYSwgcGFyZW50U3VzcGVuc2UpOw0KICAgICAgICB9DQogICAgICAgIGluc3RhbmNlLmlzTW91bnRlZCA9IHRydWU7DQogICAgICAgIHsNCiAgICAgICAgICBkZXZ0b29sc0NvbXBvbmVudEFkZGVkKGluc3RhbmNlKTsNCiAgICAgICAgfQ0KICAgICAgICBpbml0aWFsVk5vZGUgPSBjb250YWluZXIgPSBhbmNob3IgPSBudWxsOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgbGV0IHsgbmV4dCwgYnUsIHUsIHBhcmVudCwgdm5vZGUgfSA9IGluc3RhbmNlOw0KICAgICAgICB7DQogICAgICAgICAgY29uc3Qgbm9uSHlkcmF0ZWRBc3luY1Jvb3QgPSBsb2NhdGVOb25IeWRyYXRlZEFzeW5jUm9vdChpbnN0YW5jZSk7DQogICAgICAgICAgaWYgKG5vbkh5ZHJhdGVkQXN5bmNSb290KSB7DQogICAgICAgICAgICBpZiAobmV4dCkgew0KICAgICAgICAgICAgICBuZXh0LmVsID0gdm5vZGUuZWw7DQogICAgICAgICAgICAgIHVwZGF0ZUNvbXBvbmVudFByZVJlbmRlcihpbnN0YW5jZSwgbmV4dCwgb3B0aW1pemVkKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIG5vbkh5ZHJhdGVkQXN5bmNSb290LmFzeW5jRGVwLnRoZW4oKCkgPT4gew0KICAgICAgICAgICAgICBpZiAoIWluc3RhbmNlLmlzVW5tb3VudGVkKSB7DQogICAgICAgICAgICAgICAgY29tcG9uZW50VXBkYXRlRm4oKTsNCiAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSk7DQogICAgICAgICAgICByZXR1cm47DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGxldCBvcmlnaW5OZXh0ID0gbmV4dDsNCiAgICAgICAgbGV0IHZub2RlSG9vazsNCiAgICAgICAgew0KICAgICAgICAgIHB1c2hXYXJuaW5nQ29udGV4dChuZXh0IHx8IGluc3RhbmNlLnZub2RlKTsNCiAgICAgICAgfQ0KICAgICAgICB0b2dnbGVSZWN1cnNlKGluc3RhbmNlLCBmYWxzZSk7DQogICAgICAgIGlmIChuZXh0KSB7DQogICAgICAgICAgbmV4dC5lbCA9IHZub2RlLmVsOw0KICAgICAgICAgIHVwZGF0ZUNvbXBvbmVudFByZVJlbmRlcihpbnN0YW5jZSwgbmV4dCwgb3B0aW1pemVkKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBuZXh0ID0gdm5vZGU7DQogICAgICAgIH0NCiAgICAgICAgaWYgKGJ1KSB7DQogICAgICAgICAgaW52b2tlQXJyYXlGbnMoYnUpOw0KICAgICAgICB9DQogICAgICAgIGlmICh2bm9kZUhvb2sgPSBuZXh0LnByb3BzICYmIG5leHQucHJvcHMub25Wbm9kZUJlZm9yZVVwZGF0ZSkgew0KICAgICAgICAgIGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIHBhcmVudCwgbmV4dCwgdm5vZGUpOw0KICAgICAgICB9DQogICAgICAgIHRvZ2dsZVJlY3Vyc2UoaW5zdGFuY2UsIHRydWUpOw0KICAgICAgICB7DQogICAgICAgICAgc3RhcnRNZWFzdXJlKGluc3RhbmNlLCBgcmVuZGVyYCk7DQogICAgICAgIH0NCiAgICAgICAgY29uc3QgbmV4dFRyZWUgPSByZW5kZXJDb21wb25lbnRSb290KGluc3RhbmNlKTsNCiAgICAgICAgew0KICAgICAgICAgIGVuZE1lYXN1cmUoaW5zdGFuY2UsIGByZW5kZXJgKTsNCiAgICAgICAgfQ0KICAgICAgICBjb25zdCBwcmV2VHJlZSA9IGluc3RhbmNlLnN1YlRyZWU7DQogICAgICAgIGluc3RhbmNlLnN1YlRyZWUgPSBuZXh0VHJlZTsNCiAgICAgICAgew0KICAgICAgICAgIHN0YXJ0TWVhc3VyZShpbnN0YW5jZSwgYHBhdGNoYCk7DQogICAgICAgIH0NCiAgICAgICAgcGF0Y2goDQogICAgICAgICAgcHJldlRyZWUsDQogICAgICAgICAgbmV4dFRyZWUsDQogICAgICAgICAgLy8gcGFyZW50IG1heSBoYXZlIGNoYW5nZWQgaWYgaXQncyBpbiBhIHRlbGVwb3J0DQogICAgICAgICAgaG9zdFBhcmVudE5vZGUocHJldlRyZWUuZWwpLA0KICAgICAgICAgIC8vIGFuY2hvciBtYXkgaGF2ZSBjaGFuZ2VkIGlmIGl0J3MgaW4gYSBmcmFnbWVudA0KICAgICAgICAgIGdldE5leHRIb3N0Tm9kZShwcmV2VHJlZSksDQogICAgICAgICAgaW5zdGFuY2UsDQogICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgbmFtZXNwYWNlDQogICAgICAgICk7DQogICAgICAgIHsNCiAgICAgICAgICBlbmRNZWFzdXJlKGluc3RhbmNlLCBgcGF0Y2hgKTsNCiAgICAgICAgfQ0KICAgICAgICBuZXh0LmVsID0gbmV4dFRyZWUuZWw7DQogICAgICAgIGlmIChvcmlnaW5OZXh0ID09PSBudWxsKSB7DQogICAgICAgICAgdXBkYXRlSE9DSG9zdEVsKGluc3RhbmNlLCBuZXh0VHJlZS5lbCk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKHUpIHsNCiAgICAgICAgICBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QodSwgcGFyZW50U3VzcGVuc2UpOw0KICAgICAgICB9DQogICAgICAgIGlmICh2bm9kZUhvb2sgPSBuZXh0LnByb3BzICYmIG5leHQucHJvcHMub25Wbm9kZVVwZGF0ZWQpIHsNCiAgICAgICAgICBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QoDQogICAgICAgICAgICAoKSA9PiBpbnZva2VWTm9kZUhvb2sodm5vZGVIb29rLCBwYXJlbnQsIG5leHQsIHZub2RlKSwNCiAgICAgICAgICAgIHBhcmVudFN1c3BlbnNlDQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgICB7DQogICAgICAgICAgZGV2dG9vbHNDb21wb25lbnRVcGRhdGVkKGluc3RhbmNlKTsNCiAgICAgICAgfQ0KICAgICAgICB7DQogICAgICAgICAgcG9wV2FybmluZ0NvbnRleHQoKTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH07DQogICAgaW5zdGFuY2Uuc2NvcGUub24oKTsNCiAgICBjb25zdCBlZmZlY3QgPSBpbnN0YW5jZS5lZmZlY3QgPSBuZXcgUmVhY3RpdmVFZmZlY3QoY29tcG9uZW50VXBkYXRlRm4pOw0KICAgIGluc3RhbmNlLnNjb3BlLm9mZigpOw0KICAgIGNvbnN0IHVwZGF0ZSA9IGluc3RhbmNlLnVwZGF0ZSA9IGVmZmVjdC5ydW4uYmluZChlZmZlY3QpOw0KICAgIGNvbnN0IGpvYiA9IGluc3RhbmNlLmpvYiA9IGVmZmVjdC5ydW5JZkRpcnR5LmJpbmQoZWZmZWN0KTsNCiAgICBqb2IuaSA9IGluc3RhbmNlOw0KICAgIGpvYi5pZCA9IGluc3RhbmNlLnVpZDsNCiAgICBlZmZlY3Quc2NoZWR1bGVyID0gKCkgPT4gcXVldWVKb2Ioam9iKTsNCiAgICB0b2dnbGVSZWN1cnNlKGluc3RhbmNlLCB0cnVlKTsNCiAgICB7DQogICAgICBlZmZlY3Qub25UcmFjayA9IGluc3RhbmNlLnJ0YyA/IChlKSA9PiBpbnZva2VBcnJheUZucyhpbnN0YW5jZS5ydGMsIGUpIDogdm9pZCAwOw0KICAgICAgZWZmZWN0Lm9uVHJpZ2dlciA9IGluc3RhbmNlLnJ0ZyA/IChlKSA9PiBpbnZva2VBcnJheUZucyhpbnN0YW5jZS5ydGcsIGUpIDogdm9pZCAwOw0KICAgIH0NCiAgICB1cGRhdGUoKTsNCiAgfTsNCiAgY29uc3QgdXBkYXRlQ29tcG9uZW50UHJlUmVuZGVyID0gKGluc3RhbmNlLCBuZXh0Vk5vZGUsIG9wdGltaXplZCkgPT4gew0KICAgIG5leHRWTm9kZS5jb21wb25lbnQgPSBpbnN0YW5jZTsNCiAgICBjb25zdCBwcmV2UHJvcHMgPSBpbnN0YW5jZS52bm9kZS5wcm9wczsNCiAgICBpbnN0YW5jZS52bm9kZSA9IG5leHRWTm9kZTsNCiAgICBpbnN0YW5jZS5uZXh0ID0gbnVsbDsNCiAgICB1cGRhdGVQcm9wcyhpbnN0YW5jZSwgbmV4dFZOb2RlLnByb3BzLCBwcmV2UHJvcHMsIG9wdGltaXplZCk7DQogICAgdXBkYXRlU2xvdHMoaW5zdGFuY2UsIG5leHRWTm9kZS5jaGlsZHJlbiwgb3B0aW1pemVkKTsNCiAgICBwYXVzZVRyYWNraW5nKCk7DQogICAgZmx1c2hQcmVGbHVzaENicyhpbnN0YW5jZSk7DQogICAgcmVzZXRUcmFja2luZygpOw0KICB9Ow0KICBjb25zdCBwYXRjaENoaWxkcmVuID0gKG4xLCBuMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQgPSBmYWxzZSkgPT4gew0KICAgIGNvbnN0IGMxID0gbjEgJiYgbjEuY2hpbGRyZW47DQogICAgY29uc3QgcHJldlNoYXBlRmxhZyA9IG4xID8gbjEuc2hhcGVGbGFnIDogMDsNCiAgICBjb25zdCBjMiA9IG4yLmNoaWxkcmVuOw0KICAgIGNvbnN0IHsgcGF0Y2hGbGFnLCBzaGFwZUZsYWcgfSA9IG4yOw0KICAgIGlmIChwYXRjaEZsYWcgPiAwKSB7DQogICAgICBpZiAocGF0Y2hGbGFnICYgMTI4KSB7DQogICAgICAgIHBhdGNoS2V5ZWRDaGlsZHJlbigNCiAgICAgICAgICBjMSwNCiAgICAgICAgICBjMiwNCiAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICApOw0KICAgICAgICByZXR1cm47DQogICAgICB9IGVsc2UgaWYgKHBhdGNoRmxhZyAmIDI1Nikgew0KICAgICAgICBwYXRjaFVua2V5ZWRDaGlsZHJlbigNCiAgICAgICAgICBjMSwNCiAgICAgICAgICBjMiwNCiAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICApOw0KICAgICAgICByZXR1cm47DQogICAgICB9DQogICAgfQ0KICAgIGlmIChzaGFwZUZsYWcgJiA4KSB7DQogICAgICBpZiAocHJldlNoYXBlRmxhZyAmIDE2KSB7DQogICAgICAgIHVubW91bnRDaGlsZHJlbihjMSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSk7DQogICAgICB9DQogICAgICBpZiAoYzIgIT09IGMxKSB7DQogICAgICAgIGhvc3RTZXRFbGVtZW50VGV4dChjb250YWluZXIsIGMyKTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgaWYgKHByZXZTaGFwZUZsYWcgJiAxNikgew0KICAgICAgICBpZiAoc2hhcGVGbGFnICYgMTYpIHsNCiAgICAgICAgICBwYXRjaEtleWVkQ2hpbGRyZW4oDQogICAgICAgICAgICBjMSwNCiAgICAgICAgICAgIGMyLA0KICAgICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgICApOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIHVubW91bnRDaGlsZHJlbihjMSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgdHJ1ZSk7DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGlmIChwcmV2U2hhcGVGbGFnICYgOCkgew0KICAgICAgICAgIGhvc3RTZXRFbGVtZW50VGV4dChjb250YWluZXIsICIiKTsNCiAgICAgICAgfQ0KICAgICAgICBpZiAoc2hhcGVGbGFnICYgMTYpIHsNCiAgICAgICAgICBtb3VudENoaWxkcmVuKA0KICAgICAgICAgICAgYzIsDQogICAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgICBhbmNob3IsDQogICAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH07DQogIGNvbnN0IHBhdGNoVW5rZXllZENoaWxkcmVuID0gKGMxLCBjMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQpID0+IHsNCiAgICBjMSA9IGMxIHx8IEVNUFRZX0FSUjsNCiAgICBjMiA9IGMyIHx8IEVNUFRZX0FSUjsNCiAgICBjb25zdCBvbGRMZW5ndGggPSBjMS5sZW5ndGg7DQogICAgY29uc3QgbmV3TGVuZ3RoID0gYzIubGVuZ3RoOw0KICAgIGNvbnN0IGNvbW1vbkxlbmd0aCA9IE1hdGgubWluKG9sZExlbmd0aCwgbmV3TGVuZ3RoKTsNCiAgICBsZXQgaTsNCiAgICBmb3IgKGkgPSAwOyBpIDwgY29tbW9uTGVuZ3RoOyBpKyspIHsNCiAgICAgIGNvbnN0IG5leHRDaGlsZCA9IGMyW2ldID0gb3B0aW1pemVkID8gY2xvbmVJZk1vdW50ZWQoYzJbaV0pIDogbm9ybWFsaXplVk5vZGUoYzJbaV0pOw0KICAgICAgcGF0Y2goDQogICAgICAgIGMxW2ldLA0KICAgICAgICBuZXh0Q2hpbGQsDQogICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgbnVsbCwNCiAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgIG9wdGltaXplZA0KICAgICAgKTsNCiAgICB9DQogICAgaWYgKG9sZExlbmd0aCA+IG5ld0xlbmd0aCkgew0KICAgICAgdW5tb3VudENoaWxkcmVuKA0KICAgICAgICBjMSwNCiAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgdHJ1ZSwNCiAgICAgICAgZmFsc2UsDQogICAgICAgIGNvbW1vbkxlbmd0aA0KICAgICAgKTsNCiAgICB9IGVsc2Ugew0KICAgICAgbW91bnRDaGlsZHJlbigNCiAgICAgICAgYzIsDQogICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgYW5jaG9yLA0KICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgb3B0aW1pemVkLA0KICAgICAgICBjb21tb25MZW5ndGgNCiAgICAgICk7DQogICAgfQ0KICB9Ow0KICBjb25zdCBwYXRjaEtleWVkQ2hpbGRyZW4gPSAoYzEsIGMyLCBjb250YWluZXIsIHBhcmVudEFuY2hvciwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgbmFtZXNwYWNlLCBzbG90U2NvcGVJZHMsIG9wdGltaXplZCkgPT4gew0KICAgIGxldCBpID0gMDsNCiAgICBjb25zdCBsMiA9IGMyLmxlbmd0aDsNCiAgICBsZXQgZTEgPSBjMS5sZW5ndGggLSAxOw0KICAgIGxldCBlMiA9IGwyIC0gMTsNCiAgICB3aGlsZSAoaSA8PSBlMSAmJiBpIDw9IGUyKSB7DQogICAgICBjb25zdCBuMSA9IGMxW2ldOw0KICAgICAgY29uc3QgbjIgPSBjMltpXSA9IG9wdGltaXplZCA/IGNsb25lSWZNb3VudGVkKGMyW2ldKSA6IG5vcm1hbGl6ZVZOb2RlKGMyW2ldKTsNCiAgICAgIGlmIChpc1NhbWVWTm9kZVR5cGUobjEsIG4yKSkgew0KICAgICAgICBwYXRjaCgNCiAgICAgICAgICBuMSwNCiAgICAgICAgICBuMiwNCiAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgbnVsbCwNCiAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGJyZWFrOw0KICAgICAgfQ0KICAgICAgaSsrOw0KICAgIH0NCiAgICB3aGlsZSAoaSA8PSBlMSAmJiBpIDw9IGUyKSB7DQogICAgICBjb25zdCBuMSA9IGMxW2UxXTsNCiAgICAgIGNvbnN0IG4yID0gYzJbZTJdID0gb3B0aW1pemVkID8gY2xvbmVJZk1vdW50ZWQoYzJbZTJdKSA6IG5vcm1hbGl6ZVZOb2RlKGMyW2UyXSk7DQogICAgICBpZiAoaXNTYW1lVk5vZGVUeXBlKG4xLCBuMikpIHsNCiAgICAgICAgcGF0Y2goDQogICAgICAgICAgbjEsDQogICAgICAgICAgbjIsDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIG51bGwsDQogICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBicmVhazsNCiAgICAgIH0NCiAgICAgIGUxLS07DQogICAgICBlMi0tOw0KICAgIH0NCiAgICBpZiAoaSA+IGUxKSB7DQogICAgICBpZiAoaSA8PSBlMikgew0KICAgICAgICBjb25zdCBuZXh0UG9zID0gZTIgKyAxOw0KICAgICAgICBjb25zdCBhbmNob3IgPSBuZXh0UG9zIDwgbDIgPyBjMltuZXh0UG9zXS5lbCA6IHBhcmVudEFuY2hvcjsNCiAgICAgICAgd2hpbGUgKGkgPD0gZTIpIHsNCiAgICAgICAgICBwYXRjaCgNCiAgICAgICAgICAgIG51bGwsDQogICAgICAgICAgICBjMltpXSA9IG9wdGltaXplZCA/IGNsb25lSWZNb3VudGVkKGMyW2ldKSA6IG5vcm1hbGl6ZVZOb2RlKGMyW2ldKSwNCiAgICAgICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgICAgIGFuY2hvciwNCiAgICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICAgKTsNCiAgICAgICAgICBpKys7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9IGVsc2UgaWYgKGkgPiBlMikgew0KICAgICAgd2hpbGUgKGkgPD0gZTEpIHsNCiAgICAgICAgdW5tb3VudChjMVtpXSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgdHJ1ZSk7DQogICAgICAgIGkrKzsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgY29uc3QgczEgPSBpOw0KICAgICAgY29uc3QgczIgPSBpOw0KICAgICAgY29uc3Qga2V5VG9OZXdJbmRleE1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7DQogICAgICBmb3IgKGkgPSBzMjsgaSA8PSBlMjsgaSsrKSB7DQogICAgICAgIGNvbnN0IG5leHRDaGlsZCA9IGMyW2ldID0gb3B0aW1pemVkID8gY2xvbmVJZk1vdW50ZWQoYzJbaV0pIDogbm9ybWFsaXplVk5vZGUoYzJbaV0pOw0KICAgICAgICBpZiAobmV4dENoaWxkLmtleSAhPSBudWxsKSB7DQogICAgICAgICAgaWYgKGtleVRvTmV3SW5kZXhNYXAuaGFzKG5leHRDaGlsZC5rZXkpKSB7DQogICAgICAgICAgICB3YXJuJDEoDQogICAgICAgICAgICAgIGBEdXBsaWNhdGUga2V5cyBmb3VuZCBkdXJpbmcgdXBkYXRlOmAsDQogICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KG5leHRDaGlsZC5rZXkpLA0KICAgICAgICAgICAgICBgTWFrZSBzdXJlIGtleXMgYXJlIHVuaXF1ZS5gDQogICAgICAgICAgICApOw0KICAgICAgICAgIH0NCiAgICAgICAgICBrZXlUb05ld0luZGV4TWFwLnNldChuZXh0Q2hpbGQua2V5LCBpKTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgbGV0IGo7DQogICAgICBsZXQgcGF0Y2hlZCA9IDA7DQogICAgICBjb25zdCB0b0JlUGF0Y2hlZCA9IGUyIC0gczIgKyAxOw0KICAgICAgbGV0IG1vdmVkID0gZmFsc2U7DQogICAgICBsZXQgbWF4TmV3SW5kZXhTb0ZhciA9IDA7DQogICAgICBjb25zdCBuZXdJbmRleFRvT2xkSW5kZXhNYXAgPSBuZXcgQXJyYXkodG9CZVBhdGNoZWQpOw0KICAgICAgZm9yIChpID0gMDsgaSA8IHRvQmVQYXRjaGVkOyBpKyspIG5ld0luZGV4VG9PbGRJbmRleE1hcFtpXSA9IDA7DQogICAgICBmb3IgKGkgPSBzMTsgaSA8PSBlMTsgaSsrKSB7DQogICAgICAgIGNvbnN0IHByZXZDaGlsZCA9IGMxW2ldOw0KICAgICAgICBpZiAocGF0Y2hlZCA+PSB0b0JlUGF0Y2hlZCkgew0KICAgICAgICAgIHVubW91bnQocHJldkNoaWxkLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCB0cnVlKTsNCiAgICAgICAgICBjb250aW51ZTsNCiAgICAgICAgfQ0KICAgICAgICBsZXQgbmV3SW5kZXg7DQogICAgICAgIGlmIChwcmV2Q2hpbGQua2V5ICE9IG51bGwpIHsNCiAgICAgICAgICBuZXdJbmRleCA9IGtleVRvTmV3SW5kZXhNYXAuZ2V0KHByZXZDaGlsZC5rZXkpOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIGZvciAoaiA9IHMyOyBqIDw9IGUyOyBqKyspIHsNCiAgICAgICAgICAgIGlmIChuZXdJbmRleFRvT2xkSW5kZXhNYXBbaiAtIHMyXSA9PT0gMCAmJiBpc1NhbWVWTm9kZVR5cGUocHJldkNoaWxkLCBjMltqXSkpIHsNCiAgICAgICAgICAgICAgbmV3SW5kZXggPSBqOw0KICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgaWYgKG5ld0luZGV4ID09PSB2b2lkIDApIHsNCiAgICAgICAgICB1bm1vdW50KHByZXZDaGlsZCwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgdHJ1ZSk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgbmV3SW5kZXhUb09sZEluZGV4TWFwW25ld0luZGV4IC0gczJdID0gaSArIDE7DQogICAgICAgICAgaWYgKG5ld0luZGV4ID49IG1heE5ld0luZGV4U29GYXIpIHsNCiAgICAgICAgICAgIG1heE5ld0luZGV4U29GYXIgPSBuZXdJbmRleDsNCiAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgbW92ZWQgPSB0cnVlOw0KICAgICAgICAgIH0NCiAgICAgICAgICBwYXRjaCgNCiAgICAgICAgICAgIHByZXZDaGlsZCwNCiAgICAgICAgICAgIGMyW25ld0luZGV4XSwNCiAgICAgICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgICAgIG51bGwsDQogICAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICAgICk7DQogICAgICAgICAgcGF0Y2hlZCsrOw0KICAgICAgICB9DQogICAgICB9DQogICAgICBjb25zdCBpbmNyZWFzaW5nTmV3SW5kZXhTZXF1ZW5jZSA9IG1vdmVkID8gZ2V0U2VxdWVuY2UobmV3SW5kZXhUb09sZEluZGV4TWFwKSA6IEVNUFRZX0FSUjsNCiAgICAgIGogPSBpbmNyZWFzaW5nTmV3SW5kZXhTZXF1ZW5jZS5sZW5ndGggLSAxOw0KICAgICAgZm9yIChpID0gdG9CZVBhdGNoZWQgLSAxOyBpID49IDA7IGktLSkgew0KICAgICAgICBjb25zdCBuZXh0SW5kZXggPSBzMiArIGk7DQogICAgICAgIGNvbnN0IG5leHRDaGlsZCA9IGMyW25leHRJbmRleF07DQogICAgICAgIGNvbnN0IGFuY2hvciA9IG5leHRJbmRleCArIDEgPCBsMiA/IGMyW25leHRJbmRleCArIDFdLmVsIDogcGFyZW50QW5jaG9yOw0KICAgICAgICBpZiAobmV3SW5kZXhUb09sZEluZGV4TWFwW2ldID09PSAwKSB7DQogICAgICAgICAgcGF0Y2goDQogICAgICAgICAgICBudWxsLA0KICAgICAgICAgICAgbmV4dENoaWxkLA0KICAgICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgICApOw0KICAgICAgICB9IGVsc2UgaWYgKG1vdmVkKSB7DQogICAgICAgICAgaWYgKGogPCAwIHx8IGkgIT09IGluY3JlYXNpbmdOZXdJbmRleFNlcXVlbmNlW2pdKSB7DQogICAgICAgICAgICBtb3ZlKG5leHRDaGlsZCwgY29udGFpbmVyLCBhbmNob3IsIDIpOw0KICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBqLS07DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICB9Ow0KICBjb25zdCBtb3ZlID0gKHZub2RlLCBjb250YWluZXIsIGFuY2hvciwgbW92ZVR5cGUsIHBhcmVudFN1c3BlbnNlID0gbnVsbCkgPT4gew0KICAgIGNvbnN0IHsgZWwsIHR5cGUsIHRyYW5zaXRpb24sIGNoaWxkcmVuLCBzaGFwZUZsYWcgfSA9IHZub2RlOw0KICAgIGlmIChzaGFwZUZsYWcgJiA2KSB7DQogICAgICBtb3ZlKHZub2RlLmNvbXBvbmVudC5zdWJUcmVlLCBjb250YWluZXIsIGFuY2hvciwgbW92ZVR5cGUpOw0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBpZiAoc2hhcGVGbGFnICYgMTI4KSB7DQogICAgICB2bm9kZS5zdXNwZW5zZS5tb3ZlKGNvbnRhaW5lciwgYW5jaG9yLCBtb3ZlVHlwZSk7DQogICAgICByZXR1cm47DQogICAgfQ0KICAgIGlmIChzaGFwZUZsYWcgJiA2NCkgew0KICAgICAgdHlwZS5tb3ZlKHZub2RlLCBjb250YWluZXIsIGFuY2hvciwgaW50ZXJuYWxzKTsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgaWYgKHR5cGUgPT09IEZyYWdtZW50KSB7DQogICAgICBob3N0SW5zZXJ0KGVsLCBjb250YWluZXIsIGFuY2hvcik7DQogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7DQogICAgICAgIG1vdmUoY2hpbGRyZW5baV0sIGNvbnRhaW5lciwgYW5jaG9yLCBtb3ZlVHlwZSk7DQogICAgICB9DQogICAgICBob3N0SW5zZXJ0KHZub2RlLmFuY2hvciwgY29udGFpbmVyLCBhbmNob3IpOw0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBpZiAodHlwZSA9PT0gU3RhdGljKSB7DQogICAgICBtb3ZlU3RhdGljTm9kZSh2bm9kZSwgY29udGFpbmVyLCBhbmNob3IpOw0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBjb25zdCBuZWVkVHJhbnNpdGlvbjIgPSBtb3ZlVHlwZSAhPT0gMiAmJiBzaGFwZUZsYWcgJiAxICYmIHRyYW5zaXRpb247DQogICAgaWYgKG5lZWRUcmFuc2l0aW9uMikgew0KICAgICAgaWYgKG1vdmVUeXBlID09PSAwKSB7DQogICAgICAgIHRyYW5zaXRpb24uYmVmb3JlRW50ZXIoZWwpOw0KICAgICAgICBob3N0SW5zZXJ0KGVsLCBjb250YWluZXIsIGFuY2hvcik7DQogICAgICAgIHF1ZXVlUG9zdFJlbmRlckVmZmVjdCgoKSA9PiB0cmFuc2l0aW9uLmVudGVyKGVsKSwgcGFyZW50U3VzcGVuc2UpOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgY29uc3QgeyBsZWF2ZSwgZGVsYXlMZWF2ZSwgYWZ0ZXJMZWF2ZSB9ID0gdHJhbnNpdGlvbjsNCiAgICAgICAgY29uc3QgcmVtb3ZlMiA9ICgpID0+IHsNCiAgICAgICAgICBpZiAodm5vZGUuY3R4LmlzVW5tb3VudGVkKSB7DQogICAgICAgICAgICBob3N0UmVtb3ZlKGVsKTsNCiAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgaG9zdEluc2VydChlbCwgY29udGFpbmVyLCBhbmNob3IpOw0KICAgICAgICAgIH0NCiAgICAgICAgfTsNCiAgICAgICAgY29uc3QgcGVyZm9ybUxlYXZlID0gKCkgPT4gew0KICAgICAgICAgIGxlYXZlKGVsLCAoKSA9PiB7DQogICAgICAgICAgICByZW1vdmUyKCk7DQogICAgICAgICAgICBhZnRlckxlYXZlICYmIGFmdGVyTGVhdmUoKTsNCiAgICAgICAgICB9KTsNCiAgICAgICAgfTsNCiAgICAgICAgaWYgKGRlbGF5TGVhdmUpIHsNCiAgICAgICAgICBkZWxheUxlYXZlKGVsLCByZW1vdmUyLCBwZXJmb3JtTGVhdmUpOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIHBlcmZvcm1MZWF2ZSgpOw0KICAgICAgICB9DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIGhvc3RJbnNlcnQoZWwsIGNvbnRhaW5lciwgYW5jaG9yKTsNCiAgICB9DQogIH07DQogIGNvbnN0IHVubW91bnQgPSAodm5vZGUsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGRvUmVtb3ZlID0gZmFsc2UsIG9wdGltaXplZCA9IGZhbHNlKSA9PiB7DQogICAgY29uc3Qgew0KICAgICAgdHlwZSwNCiAgICAgIHByb3BzLA0KICAgICAgcmVmLA0KICAgICAgY2hpbGRyZW4sDQogICAgICBkeW5hbWljQ2hpbGRyZW4sDQogICAgICBzaGFwZUZsYWcsDQogICAgICBwYXRjaEZsYWcsDQogICAgICBkaXJzLA0KICAgICAgY2FjaGVJbmRleA0KICAgIH0gPSB2bm9kZTsNCiAgICBpZiAocGF0Y2hGbGFnID09PSAtMikgew0KICAgICAgb3B0aW1pemVkID0gZmFsc2U7DQogICAgfQ0KICAgIGlmIChyZWYgIT0gbnVsbCkgew0KICAgICAgcGF1c2VUcmFja2luZygpOw0KICAgICAgc2V0UmVmKHJlZiwgbnVsbCwgcGFyZW50U3VzcGVuc2UsIHZub2RlLCB0cnVlKTsNCiAgICAgIHJlc2V0VHJhY2tpbmcoKTsNCiAgICB9DQogICAgaWYgKGNhY2hlSW5kZXggIT0gbnVsbCkgew0KICAgICAgcGFyZW50Q29tcG9uZW50LnJlbmRlckNhY2hlW2NhY2hlSW5kZXhdID0gdm9pZCAwOw0KICAgIH0NCiAgICBpZiAoc2hhcGVGbGFnICYgMjU2KSB7DQogICAgICBwYXJlbnRDb21wb25lbnQuY3R4LmRlYWN0aXZhdGUodm5vZGUpOw0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBjb25zdCBzaG91bGRJbnZva2VEaXJzID0gc2hhcGVGbGFnICYgMSAmJiBkaXJzOw0KICAgIGNvbnN0IHNob3VsZEludm9rZVZub2RlSG9vayA9ICFpc0FzeW5jV3JhcHBlcih2bm9kZSk7DQogICAgbGV0IHZub2RlSG9vazsNCiAgICBpZiAoc2hvdWxkSW52b2tlVm5vZGVIb29rICYmICh2bm9kZUhvb2sgPSBwcm9wcyAmJiBwcm9wcy5vblZub2RlQmVmb3JlVW5tb3VudCkpIHsNCiAgICAgIGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIHBhcmVudENvbXBvbmVudCwgdm5vZGUpOw0KICAgIH0NCiAgICBpZiAoc2hhcGVGbGFnICYgNikgew0KICAgICAgdW5tb3VudENvbXBvbmVudCh2bm9kZS5jb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBkb1JlbW92ZSk7DQogICAgfSBlbHNlIHsNCiAgICAgIGlmIChzaGFwZUZsYWcgJiAxMjgpIHsNCiAgICAgICAgdm5vZGUuc3VzcGVuc2UudW5tb3VudChwYXJlbnRTdXNwZW5zZSwgZG9SZW1vdmUpOw0KICAgICAgICByZXR1cm47DQogICAgICB9DQogICAgICBpZiAoc2hvdWxkSW52b2tlRGlycykgew0KICAgICAgICBpbnZva2VEaXJlY3RpdmVIb29rKHZub2RlLCBudWxsLCBwYXJlbnRDb21wb25lbnQsICJiZWZvcmVVbm1vdW50Iik7DQogICAgICB9DQogICAgICBpZiAoc2hhcGVGbGFnICYgNjQpIHsNCiAgICAgICAgdm5vZGUudHlwZS5yZW1vdmUoDQogICAgICAgICAgdm5vZGUsDQogICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgIGludGVybmFscywNCiAgICAgICAgICBkb1JlbW92ZQ0KICAgICAgICApOw0KICAgICAgfSBlbHNlIGlmIChkeW5hbWljQ2hpbGRyZW4gJiYgLy8gIzUxNTQNCiAgICAgIC8vIHdoZW4gdi1vbmNlIGlzIHVzZWQgaW5zaWRlIGEgYmxvY2ssIHNldEJsb2NrVHJhY2tpbmcoLTEpIG1hcmtzIHRoZQ0KICAgICAgLy8gcGFyZW50IGJsb2NrIHdpdGggaGFzT25jZTogdHJ1ZQ0KICAgICAgLy8gc28gdGhhdCBpdCBkb2Vzbid0IHRha2UgdGhlIGZhc3QgcGF0aCBkdXJpbmcgdW5tb3VudCAtIG90aGVyd2lzZQ0KICAgICAgLy8gY29tcG9uZW50cyBuZXN0ZWQgaW4gdi1vbmNlIGFyZSBuZXZlciB1bm1vdW50ZWQuDQogICAgICAhZHluYW1pY0NoaWxkcmVuLmhhc09uY2UgJiYgLy8gIzExNTM6IGZhc3QgcGF0aCBzaG91bGQgbm90IGJlIHRha2VuIGZvciBub24tc3RhYmxlICh2LWZvcikgZnJhZ21lbnRzDQogICAgICAodHlwZSAhPT0gRnJhZ21lbnQgfHwgcGF0Y2hGbGFnID4gMCAmJiBwYXRjaEZsYWcgJiA2NCkpIHsNCiAgICAgICAgdW5tb3VudENoaWxkcmVuKA0KICAgICAgICAgIGR5bmFtaWNDaGlsZHJlbiwNCiAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgZmFsc2UsDQogICAgICAgICAgdHJ1ZQ0KICAgICAgICApOw0KICAgICAgfSBlbHNlIGlmICh0eXBlID09PSBGcmFnbWVudCAmJiBwYXRjaEZsYWcgJiAoMTI4IHwgMjU2KSB8fCAhb3B0aW1pemVkICYmIHNoYXBlRmxhZyAmIDE2KSB7DQogICAgICAgIHVubW91bnRDaGlsZHJlbihjaGlsZHJlbiwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSk7DQogICAgICB9DQogICAgICBpZiAoZG9SZW1vdmUpIHsNCiAgICAgICAgcmVtb3ZlKHZub2RlKTsNCiAgICAgIH0NCiAgICB9DQogICAgaWYgKHNob3VsZEludm9rZVZub2RlSG9vayAmJiAodm5vZGVIb29rID0gcHJvcHMgJiYgcHJvcHMub25Wbm9kZVVubW91bnRlZCkgfHwgc2hvdWxkSW52b2tlRGlycykgew0KICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KCgpID0+IHsNCiAgICAgICAgdm5vZGVIb29rICYmIGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIHBhcmVudENvbXBvbmVudCwgdm5vZGUpOw0KICAgICAgICBzaG91bGRJbnZva2VEaXJzICYmIGludm9rZURpcmVjdGl2ZUhvb2sodm5vZGUsIG51bGwsIHBhcmVudENvbXBvbmVudCwgInVubW91bnRlZCIpOw0KICAgICAgfSwgcGFyZW50U3VzcGVuc2UpOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgcmVtb3ZlID0gKHZub2RlKSA9PiB7DQogICAgY29uc3QgeyB0eXBlLCBlbCwgYW5jaG9yLCB0cmFuc2l0aW9uIH0gPSB2bm9kZTsNCiAgICBpZiAodHlwZSA9PT0gRnJhZ21lbnQpIHsNCiAgICAgIGlmICh2bm9kZS5wYXRjaEZsYWcgPiAwICYmIHZub2RlLnBhdGNoRmxhZyAmIDIwNDggJiYgdHJhbnNpdGlvbiAmJiAhdHJhbnNpdGlvbi5wZXJzaXN0ZWQpIHsNCiAgICAgICAgdm5vZGUuY2hpbGRyZW4uZm9yRWFjaCgoY2hpbGQpID0+IHsNCiAgICAgICAgICBpZiAoY2hpbGQudHlwZSA9PT0gQ29tbWVudCkgew0KICAgICAgICAgICAgaG9zdFJlbW92ZShjaGlsZC5lbCk7DQogICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIHJlbW92ZShjaGlsZCk7DQogICAgICAgICAgfQ0KICAgICAgICB9KTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHJlbW92ZUZyYWdtZW50KGVsLCBhbmNob3IpOw0KICAgICAgfQ0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBpZiAodHlwZSA9PT0gU3RhdGljKSB7DQogICAgICByZW1vdmVTdGF0aWNOb2RlKHZub2RlKTsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgY29uc3QgcGVyZm9ybVJlbW92ZSA9ICgpID0+IHsNCiAgICAgIGhvc3RSZW1vdmUoZWwpOw0KICAgICAgaWYgKHRyYW5zaXRpb24gJiYgIXRyYW5zaXRpb24ucGVyc2lzdGVkICYmIHRyYW5zaXRpb24uYWZ0ZXJMZWF2ZSkgew0KICAgICAgICB0cmFuc2l0aW9uLmFmdGVyTGVhdmUoKTsNCiAgICAgIH0NCiAgICB9Ow0KICAgIGlmICh2bm9kZS5zaGFwZUZsYWcgJiAxICYmIHRyYW5zaXRpb24gJiYgIXRyYW5zaXRpb24ucGVyc2lzdGVkKSB7DQogICAgICBjb25zdCB7IGxlYXZlLCBkZWxheUxlYXZlIH0gPSB0cmFuc2l0aW9uOw0KICAgICAgY29uc3QgcGVyZm9ybUxlYXZlID0gKCkgPT4gbGVhdmUoZWwsIHBlcmZvcm1SZW1vdmUpOw0KICAgICAgaWYgKGRlbGF5TGVhdmUpIHsNCiAgICAgICAgZGVsYXlMZWF2ZSh2bm9kZS5lbCwgcGVyZm9ybVJlbW92ZSwgcGVyZm9ybUxlYXZlKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHBlcmZvcm1MZWF2ZSgpOw0KICAgICAgfQ0KICAgIH0gZWxzZSB7DQogICAgICBwZXJmb3JtUmVtb3ZlKCk7DQogICAgfQ0KICB9Ow0KICBjb25zdCByZW1vdmVGcmFnbWVudCA9IChjdXIsIGVuZCkgPT4gew0KICAgIGxldCBuZXh0Ow0KICAgIHdoaWxlIChjdXIgIT09IGVuZCkgew0KICAgICAgbmV4dCA9IGhvc3ROZXh0U2libGluZyhjdXIpOw0KICAgICAgaG9zdFJlbW92ZShjdXIpOw0KICAgICAgY3VyID0gbmV4dDsNCiAgICB9DQogICAgaG9zdFJlbW92ZShlbmQpOw0KICB9Ow0KICBjb25zdCB1bm1vdW50Q29tcG9uZW50ID0gKGluc3RhbmNlLCBwYXJlbnRTdXNwZW5zZSwgZG9SZW1vdmUpID0+IHsNCiAgICBpZiAoaW5zdGFuY2UudHlwZS5fX2htcklkKSB7DQogICAgICB1bnJlZ2lzdGVySE1SKGluc3RhbmNlKTsNCiAgICB9DQogICAgY29uc3Qgew0KICAgICAgYnVtLA0KICAgICAgc2NvcGUsDQogICAgICBqb2IsDQogICAgICBzdWJUcmVlLA0KICAgICAgdW0sDQogICAgICBtLA0KICAgICAgYSwNCiAgICAgIHBhcmVudCwNCiAgICAgIHNsb3RzOiB7IF9fOiBzbG90Q2FjaGVLZXlzIH0NCiAgICB9ID0gaW5zdGFuY2U7DQogICAgaW52YWxpZGF0ZU1vdW50KG0pOw0KICAgIGludmFsaWRhdGVNb3VudChhKTsNCiAgICBpZiAoYnVtKSB7DQogICAgICBpbnZva2VBcnJheUZucyhidW0pOw0KICAgIH0NCiAgICBpZiAocGFyZW50ICYmIGlzQXJyYXkoc2xvdENhY2hlS2V5cykpIHsNCiAgICAgIHNsb3RDYWNoZUtleXMuZm9yRWFjaCgodikgPT4gew0KICAgICAgICBwYXJlbnQucmVuZGVyQ2FjaGVbdl0gPSB2b2lkIDA7DQogICAgICB9KTsNCiAgICB9DQogICAgc2NvcGUuc3RvcCgpOw0KICAgIGlmIChqb2IpIHsNCiAgICAgIGpvYi5mbGFncyB8PSA4Ow0KICAgICAgdW5tb3VudChzdWJUcmVlLCBpbnN0YW5jZSwgcGFyZW50U3VzcGVuc2UsIGRvUmVtb3ZlKTsNCiAgICB9DQogICAgaWYgKHVtKSB7DQogICAgICBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QodW0sIHBhcmVudFN1c3BlbnNlKTsNCiAgICB9DQogICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KCgpID0+IHsNCiAgICAgIGluc3RhbmNlLmlzVW5tb3VudGVkID0gdHJ1ZTsNCiAgICB9LCBwYXJlbnRTdXNwZW5zZSk7DQogICAgaWYgKHBhcmVudFN1c3BlbnNlICYmIHBhcmVudFN1c3BlbnNlLnBlbmRpbmdCcmFuY2ggJiYgIXBhcmVudFN1c3BlbnNlLmlzVW5tb3VudGVkICYmIGluc3RhbmNlLmFzeW5jRGVwICYmICFpbnN0YW5jZS5hc3luY1Jlc29sdmVkICYmIGluc3RhbmNlLnN1c3BlbnNlSWQgPT09IHBhcmVudFN1c3BlbnNlLnBlbmRpbmdJZCkgew0KICAgICAgcGFyZW50U3VzcGVuc2UuZGVwcy0tOw0KICAgICAgaWYgKHBhcmVudFN1c3BlbnNlLmRlcHMgPT09IDApIHsNCiAgICAgICAgcGFyZW50U3VzcGVuc2UucmVzb2x2ZSgpOw0KICAgICAgfQ0KICAgIH0NCiAgICB7DQogICAgICBkZXZ0b29sc0NvbXBvbmVudFJlbW92ZWQoaW5zdGFuY2UpOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgdW5tb3VudENoaWxkcmVuID0gKGNoaWxkcmVuLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBkb1JlbW92ZSA9IGZhbHNlLCBvcHRpbWl6ZWQgPSBmYWxzZSwgc3RhcnQgPSAwKSA9PiB7DQogICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHsNCiAgICAgIHVubW91bnQoY2hpbGRyZW5baV0sIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGRvUmVtb3ZlLCBvcHRpbWl6ZWQpOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgZ2V0TmV4dEhvc3ROb2RlID0gKHZub2RlKSA9PiB7DQogICAgaWYgKHZub2RlLnNoYXBlRmxhZyAmIDYpIHsNCiAgICAgIHJldHVybiBnZXROZXh0SG9zdE5vZGUodm5vZGUuY29tcG9uZW50LnN1YlRyZWUpOw0KICAgIH0NCiAgICBpZiAodm5vZGUuc2hhcGVGbGFnICYgMTI4KSB7DQogICAgICByZXR1cm4gdm5vZGUuc3VzcGVuc2UubmV4dCgpOw0KICAgIH0NCiAgICBjb25zdCBlbCA9IGhvc3ROZXh0U2libGluZyh2bm9kZS5hbmNob3IgfHwgdm5vZGUuZWwpOw0KICAgIGNvbnN0IHRlbGVwb3J0RW5kID0gZWwgJiYgZWxbVGVsZXBvcnRFbmRLZXldOw0KICAgIHJldHVybiB0ZWxlcG9ydEVuZCA/IGhvc3ROZXh0U2libGluZyh0ZWxlcG9ydEVuZCkgOiBlbDsNCiAgfTsNCiAgbGV0IGlzRmx1c2hpbmcgPSBmYWxzZTsNCiAgY29uc3QgcmVuZGVyID0gKHZub2RlLCBjb250YWluZXIsIG5hbWVzcGFjZSkgPT4gew0KICAgIGlmICh2bm9kZSA9PSBudWxsKSB7DQogICAgICBpZiAoY29udGFpbmVyLl92bm9kZSkgew0KICAgICAgICB1bm1vdW50KGNvbnRhaW5lci5fdm5vZGUsIG51bGwsIG51bGwsIHRydWUpOw0KICAgICAgfQ0KICAgIH0gZWxzZSB7DQogICAgICBwYXRjaCgNCiAgICAgICAgY29udGFpbmVyLl92bm9kZSB8fCBudWxsLA0KICAgICAgICB2bm9kZSwNCiAgICAgICAgY29udGFpbmVyLA0KICAgICAgICBudWxsLA0KICAgICAgICBudWxsLA0KICAgICAgICBudWxsLA0KICAgICAgICBuYW1lc3BhY2UNCiAgICAgICk7DQogICAgfQ0KICAgIGNvbnRhaW5lci5fdm5vZGUgPSB2bm9kZTsNCiAgICBpZiAoIWlzRmx1c2hpbmcpIHsNCiAgICAgIGlzRmx1c2hpbmcgPSB0cnVlOw0KICAgICAgZmx1c2hQcmVGbHVzaENicygpOw0KICAgICAgZmx1c2hQb3N0Rmx1c2hDYnMoKTsNCiAgICAgIGlzRmx1c2hpbmcgPSBmYWxzZTsNCiAgICB9DQogIH07DQogIGNvbnN0IGludGVybmFscyA9IHsNCiAgICBwOiBwYXRjaCwNCiAgICB1bTogdW5tb3VudCwNCiAgICBtOiBtb3ZlLA0KICAgIHI6IHJlbW92ZSwNCiAgICBtdDogbW91bnRDb21wb25lbnQsDQogICAgbWM6IG1vdW50Q2hpbGRyZW4sDQogICAgcGM6IHBhdGNoQ2hpbGRyZW4sDQogICAgcGJjOiBwYXRjaEJsb2NrQ2hpbGRyZW4sDQogICAgbjogZ2V0TmV4dEhvc3ROb2RlLA0KICAgIG86IG9wdGlvbnMNCiAgfTsNCiAgbGV0IGh5ZHJhdGU7DQogIGxldCBoeWRyYXRlTm9kZTsNCiAgaWYgKGNyZWF0ZUh5ZHJhdGlvbkZucykgew0KICAgIFtoeWRyYXRlLCBoeWRyYXRlTm9kZV0gPSBjcmVhdGVIeWRyYXRpb25GbnMoDQogICAgICBpbnRlcm5hbHMNCiAgICApOw0KICB9DQogIHJldHVybiB7DQogICAgcmVuZGVyLA0KICAgIGh5ZHJhdGUsDQogICAgY3JlYXRlQXBwOiBjcmVhdGVBcHBBUEkocmVuZGVyLCBoeWRyYXRlKQ0KICB9Ow0KfQ0KZnVuY3Rpb24gcmVzb2x2ZUNoaWxkcmVuTmFtZXNwYWNlKHsgdHlwZSwgcHJvcHMgfSwgY3VycmVudE5hbWVzcGFjZSkgew0KICByZXR1cm4gY3VycmVudE5hbWVzcGFjZSA9PT0gInN2ZyIgJiYgdHlwZSA9PT0gImZvcmVpZ25PYmplY3QiIHx8IGN1cnJlbnROYW1lc3BhY2UgPT09ICJtYXRobWwiICYmIHR5cGUgPT09ICJhbm5vdGF0aW9uLXhtbCIgJiYgcHJvcHMgJiYgcHJvcHMuZW5jb2RpbmcgJiYgcHJvcHMuZW5jb2RpbmcuaW5jbHVkZXMoImh0bWwiKSA/IHZvaWQgMCA6IGN1cnJlbnROYW1lc3BhY2U7DQp9DQpmdW5jdGlvbiB0b2dnbGVSZWN1cnNlKHsgZWZmZWN0LCBqb2IgfSwgYWxsb3dlZCkgew0KICBpZiAoYWxsb3dlZCkgew0KICAgIGVmZmVjdC5mbGFncyB8PSAzMjsNCiAgICBqb2IuZmxhZ3MgfD0gNDsNCiAgfSBlbHNlIHsNCiAgICBlZmZlY3QuZmxhZ3MgJj0gLTMzOw0KICAgIGpvYi5mbGFncyAmPSAtNTsNCiAgfQ0KfQ0KZnVuY3Rpb24gbmVlZFRyYW5zaXRpb24ocGFyZW50U3VzcGVuc2UsIHRyYW5zaXRpb24pIHsNCiAgcmV0dXJuICghcGFyZW50U3VzcGVuc2UgfHwgcGFyZW50U3VzcGVuc2UgJiYgIXBhcmVudFN1c3BlbnNlLnBlbmRpbmdCcmFuY2gpICYmIHRyYW5zaXRpb24gJiYgIXRyYW5zaXRpb24ucGVyc2lzdGVkOw0KfQ0KZnVuY3Rpb24gdHJhdmVyc2VTdGF0aWNDaGlsZHJlbihuMSwgbjIsIHNoYWxsb3cgPSBmYWxzZSkgew0KICBjb25zdCBjaDEgPSBuMS5jaGlsZHJlbjsNCiAgY29uc3QgY2gyID0gbjIuY2hpbGRyZW47DQogIGlmIChpc0FycmF5KGNoMSkgJiYgaXNBcnJheShjaDIpKSB7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaDEubGVuZ3RoOyBpKyspIHsNCiAgICAgIGNvbnN0IGMxID0gY2gxW2ldOw0KICAgICAgbGV0IGMyID0gY2gyW2ldOw0KICAgICAgaWYgKGMyLnNoYXBlRmxhZyAmIDEgJiYgIWMyLmR5bmFtaWNDaGlsZHJlbikgew0KICAgICAgICBpZiAoYzIucGF0Y2hGbGFnIDw9IDAgfHwgYzIucGF0Y2hGbGFnID09PSAzMikgew0KICAgICAgICAgIGMyID0gY2gyW2ldID0gY2xvbmVJZk1vdW50ZWQoY2gyW2ldKTsNCiAgICAgICAgICBjMi5lbCA9IGMxLmVsOw0KICAgICAgICB9DQogICAgICAgIGlmICghc2hhbGxvdyAmJiBjMi5wYXRjaEZsYWcgIT09IC0yKQ0KICAgICAgICAgIHRyYXZlcnNlU3RhdGljQ2hpbGRyZW4oYzEsIGMyKTsNCiAgICAgIH0NCiAgICAgIGlmIChjMi50eXBlID09PSBUZXh0KSB7DQogICAgICAgIGMyLmVsID0gYzEuZWw7DQogICAgICB9DQogICAgICBpZiAoYzIudHlwZSA9PT0gQ29tbWVudCAmJiAhYzIuZWwpIHsNCiAgICAgICAgYzIuZWwgPSBjMS5lbDsNCiAgICAgIH0NCiAgICAgIHsNCiAgICAgICAgYzIuZWwgJiYgKGMyLmVsLl9fdm5vZGUgPSBjMik7DQogICAgICB9DQogICAgfQ0KICB9DQp9DQpmdW5jdGlvbiBnZXRTZXF1ZW5jZShhcnIpIHsNCiAgY29uc3QgcCA9IGFyci5zbGljZSgpOw0KICBjb25zdCByZXN1bHQgPSBbMF07DQogIGxldCBpLCBqLCB1LCB2LCBjOw0KICBjb25zdCBsZW4gPSBhcnIubGVuZ3RoOw0KICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHsNCiAgICBjb25zdCBhcnJJID0gYXJyW2ldOw0KICAgIGlmIChhcnJJICE9PSAwKSB7DQogICAgICBqID0gcmVzdWx0W3Jlc3VsdC5sZW5ndGggLSAxXTsNCiAgICAgIGlmIChhcnJbal0gPCBhcnJJKSB7DQogICAgICAgIHBbaV0gPSBqOw0KICAgICAgICByZXN1bHQucHVzaChpKTsNCiAgICAgICAgY29udGludWU7DQogICAgICB9DQogICAgICB1ID0gMDsNCiAgICAgIHYgPSByZXN1bHQubGVuZ3RoIC0gMTsNCiAgICAgIHdoaWxlICh1IDwgdikgew0KICAgICAgICBjID0gdSArIHYgPj4gMTsNCiAgICAgICAgaWYgKGFycltyZXN1bHRbY11dIDwgYXJySSkgew0KICAgICAgICAgIHUgPSBjICsgMTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICB2ID0gYzsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgaWYgKGFyckkgPCBhcnJbcmVzdWx0W3VdXSkgew0KICAgICAgICBpZiAodSA+IDApIHsNCiAgICAgICAgICBwW2ldID0gcmVzdWx0W3UgLSAxXTsNCiAgICAgICAgfQ0KICAgICAgICByZXN1bHRbdV0gPSBpOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICB1ID0gcmVzdWx0Lmxlbmd0aDsNCiAgdiA9IHJlc3VsdFt1IC0gMV07DQogIHdoaWxlICh1LS0gPiAwKSB7DQogICAgcmVzdWx0W3VdID0gdjsNCiAgICB2ID0gcFt2XTsNCiAgfQ0KICByZXR1cm4gcmVzdWx0Ow0KfQ0KZnVuY3Rpb24gbG9jYXRlTm9uSHlkcmF0ZWRBc3luY1Jvb3QoaW5zdGFuY2UpIHsNCiAgY29uc3Qgc3ViQ29tcG9uZW50ID0gaW5zdGFuY2Uuc3ViVHJlZS5jb21wb25lbnQ7DQogIGlmIChzdWJDb21wb25lbnQpIHsNCiAgICBpZiAoc3ViQ29tcG9uZW50LmFzeW5jRGVwICYmICFzdWJDb21wb25lbnQuYXN5bmNSZXNvbHZlZCkgew0KICAgICAgcmV0dXJuIHN1YkNvbXBvbmVudDsNCiAgICB9IGVsc2Ugew0KICAgICAgcmV0dXJuIGxvY2F0ZU5vbkh5ZHJhdGVkQXN5bmNSb290KHN1YkNvbXBvbmVudCk7DQogICAgfQ0KICB9DQp9DQpmdW5jdGlvbiBpbnZhbGlkYXRlTW91bnQoaG9va3MpIHsNCiAgaWYgKGhvb2tzKSB7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBob29rcy5sZW5ndGg7IGkrKykNCiAgICAgIGhvb2tzW2ldLmZsYWdzIHw9IDg7DQogIH0NCn0NCg0KY29uc3Qgc3NyQ29udGV4dEtleSA9IFN5bWJvbC5mb3IoInYtc2N4Iik7DQpjb25zdCB1c2VTU1JDb250ZXh0ID0gKCkgPT4gew0KICB7DQogICAgY29uc3QgY3R4ID0gaW5qZWN0KHNzckNvbnRleHRLZXkpOw0KICAgIGlmICghY3R4KSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGBTZXJ2ZXIgcmVuZGVyaW5nIGNvbnRleHQgbm90IHByb3ZpZGVkLiBNYWtlIHN1cmUgdG8gb25seSBjYWxsIHVzZVNTUkNvbnRleHQoKSBjb25kaXRpb25hbGx5IGluIHRoZSBzZXJ2ZXIgYnVpbGQuYA0KICAgICAgKTsNCiAgICB9DQogICAgcmV0dXJuIGN0eDsNCiAgfQ0KfTsNCg0KZnVuY3Rpb24gd2F0Y2hFZmZlY3QoZWZmZWN0LCBvcHRpb25zKSB7DQogIHJldHVybiBkb1dhdGNoKGVmZmVjdCwgbnVsbCwgb3B0aW9ucyk7DQp9DQpmdW5jdGlvbiB3YXRjaFBvc3RFZmZlY3QoZWZmZWN0LCBvcHRpb25zKSB7DQogIHJldHVybiBkb1dhdGNoKA0KICAgIGVmZmVjdCwNCiAgICBudWxsLA0KICAgIGV4dGVuZCh7fSwgb3B0aW9ucywgeyBmbHVzaDogInBvc3QiIH0pIA0KICApOw0KfQ0KZnVuY3Rpb24gd2F0Y2hTeW5jRWZmZWN0KGVmZmVjdCwgb3B0aW9ucykgew0KICByZXR1cm4gZG9XYXRjaCgNCiAgICBlZmZlY3QsDQogICAgbnVsbCwNCiAgICBleHRlbmQoe30sIG9wdGlvbnMsIHsgZmx1c2g6ICJzeW5jIiB9KSANCiAgKTsNCn0NCmZ1bmN0aW9uIHdhdGNoKHNvdXJjZSwgY2IsIG9wdGlvbnMpIHsNCiAgaWYgKCFpc0Z1bmN0aW9uKGNiKSkgew0KICAgIHdhcm4kMSgNCiAgICAgIGBcYHdhdGNoKGZuLCBvcHRpb25zPylcYCBzaWduYXR1cmUgaGFzIGJlZW4gbW92ZWQgdG8gYSBzZXBhcmF0ZSBBUEkuIFVzZSBcYHdhdGNoRWZmZWN0KGZuLCBvcHRpb25zPylcYCBpbnN0ZWFkLiBcYHdhdGNoXGAgbm93IG9ubHkgc3VwcG9ydHMgXGB3YXRjaChzb3VyY2UsIGNiLCBvcHRpb25zPykgc2lnbmF0dXJlLmANCiAgICApOw0KICB9DQogIHJldHVybiBkb1dhdGNoKHNvdXJjZSwgY2IsIG9wdGlvbnMpOw0KfQ0KZnVuY3Rpb24gZG9XYXRjaChzb3VyY2UsIGNiLCBvcHRpb25zID0gRU1QVFlfT0JKKSB7DQogIGNvbnN0IHsgaW1tZWRpYXRlLCBkZWVwLCBmbHVzaCwgb25jZSB9ID0gb3B0aW9uczsNCiAgaWYgKCFjYikgew0KICAgIGlmIChpbW1lZGlhdGUgIT09IHZvaWQgMCkgew0KICAgICAgd2FybiQxKA0KICAgICAgICBgd2F0Y2goKSAiaW1tZWRpYXRlIiBvcHRpb24gaXMgb25seSByZXNwZWN0ZWQgd2hlbiB1c2luZyB0aGUgd2F0Y2goc291cmNlLCBjYWxsYmFjaywgb3B0aW9ucz8pIHNpZ25hdHVyZS5gDQogICAgICApOw0KICAgIH0NCiAgICBpZiAoZGVlcCAhPT0gdm9pZCAwKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGB3YXRjaCgpICJkZWVwIiBvcHRpb24gaXMgb25seSByZXNwZWN0ZWQgd2hlbiB1c2luZyB0aGUgd2F0Y2goc291cmNlLCBjYWxsYmFjaywgb3B0aW9ucz8pIHNpZ25hdHVyZS5gDQogICAgICApOw0KICAgIH0NCiAgICBpZiAob25jZSAhPT0gdm9pZCAwKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGB3YXRjaCgpICJvbmNlIiBvcHRpb24gaXMgb25seSByZXNwZWN0ZWQgd2hlbiB1c2luZyB0aGUgd2F0Y2goc291cmNlLCBjYWxsYmFjaywgb3B0aW9ucz8pIHNpZ25hdHVyZS5gDQogICAgICApOw0KICAgIH0NCiAgfQ0KICBjb25zdCBiYXNlV2F0Y2hPcHRpb25zID0gZXh0ZW5kKHt9LCBvcHRpb25zKTsNCiAgYmFzZVdhdGNoT3B0aW9ucy5vbldhcm4gPSB3YXJuJDE7DQogIGNvbnN0IHJ1bnNJbW1lZGlhdGVseSA9IGNiICYmIGltbWVkaWF0ZSB8fCAhY2IgJiYgZmx1c2ggIT09ICJwb3N0IjsNCiAgbGV0IHNzckNsZWFudXA7DQogIGlmIChpc0luU1NSQ29tcG9uZW50U2V0dXApIHsNCiAgICBpZiAoZmx1c2ggPT09ICJzeW5jIikgew0KICAgICAgY29uc3QgY3R4ID0gdXNlU1NSQ29udGV4dCgpOw0KICAgICAgc3NyQ2xlYW51cCA9IGN0eC5fX3dhdGNoZXJIYW5kbGVzIHx8IChjdHguX193YXRjaGVySGFuZGxlcyA9IFtdKTsNCiAgICB9IGVsc2UgaWYgKCFydW5zSW1tZWRpYXRlbHkpIHsNCiAgICAgIGNvbnN0IHdhdGNoU3RvcEhhbmRsZSA9ICgpID0+IHsNCiAgICAgIH07DQogICAgICB3YXRjaFN0b3BIYW5kbGUuc3RvcCA9IE5PT1A7DQogICAgICB3YXRjaFN0b3BIYW5kbGUucmVzdW1lID0gTk9PUDsNCiAgICAgIHdhdGNoU3RvcEhhbmRsZS5wYXVzZSA9IE5PT1A7DQogICAgICByZXR1cm4gd2F0Y2hTdG9wSGFuZGxlOw0KICAgIH0NCiAgfQ0KICBjb25zdCBpbnN0YW5jZSA9IGN1cnJlbnRJbnN0YW5jZTsNCiAgYmFzZVdhdGNoT3B0aW9ucy5jYWxsID0gKGZuLCB0eXBlLCBhcmdzKSA9PiBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZyhmbiwgaW5zdGFuY2UsIHR5cGUsIGFyZ3MpOw0KICBsZXQgaXNQcmUgPSBmYWxzZTsNCiAgaWYgKGZsdXNoID09PSAicG9zdCIpIHsNCiAgICBiYXNlV2F0Y2hPcHRpb25zLnNjaGVkdWxlciA9IChqb2IpID0+IHsNCiAgICAgIHF1ZXVlUG9zdFJlbmRlckVmZmVjdChqb2IsIGluc3RhbmNlICYmIGluc3RhbmNlLnN1c3BlbnNlKTsNCiAgICB9Ow0KICB9IGVsc2UgaWYgKGZsdXNoICE9PSAic3luYyIpIHsNCiAgICBpc1ByZSA9IHRydWU7DQogICAgYmFzZVdhdGNoT3B0aW9ucy5zY2hlZHVsZXIgPSAoam9iLCBpc0ZpcnN0UnVuKSA9PiB7DQogICAgICBpZiAoaXNGaXJzdFJ1bikgew0KICAgICAgICBqb2IoKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHF1ZXVlSm9iKGpvYik7DQogICAgICB9DQogICAgfTsNCiAgfQ0KICBiYXNlV2F0Y2hPcHRpb25zLmF1Z21lbnRKb2IgPSAoam9iKSA9PiB7DQogICAgaWYgKGNiKSB7DQogICAgICBqb2IuZmxhZ3MgfD0gNDsNCiAgICB9DQogICAgaWYgKGlzUHJlKSB7DQogICAgICBqb2IuZmxhZ3MgfD0gMjsNCiAgICAgIGlmIChpbnN0YW5jZSkgew0KICAgICAgICBqb2IuaWQgPSBpbnN0YW5jZS51aWQ7DQogICAgICAgIGpvYi5pID0gaW5zdGFuY2U7DQogICAgICB9DQogICAgfQ0KICB9Ow0KICBjb25zdCB3YXRjaEhhbmRsZSA9IHdhdGNoJDEoc291cmNlLCBjYiwgYmFzZVdhdGNoT3B0aW9ucyk7DQogIGlmIChpc0luU1NSQ29tcG9uZW50U2V0dXApIHsNCiAgICBpZiAoc3NyQ2xlYW51cCkgew0KICAgICAgc3NyQ2xlYW51cC5wdXNoKHdhdGNoSGFuZGxlKTsNCiAgICB9IGVsc2UgaWYgKHJ1bnNJbW1lZGlhdGVseSkgew0KICAgICAgd2F0Y2hIYW5kbGUoKTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIHdhdGNoSGFuZGxlOw0KfQ0KZnVuY3Rpb24gaW5zdGFuY2VXYXRjaChzb3VyY2UsIHZhbHVlLCBvcHRpb25zKSB7DQogIGNvbnN0IHB1YmxpY1RoaXMgPSB0aGlzLnByb3h5Ow0KICBjb25zdCBnZXR0ZXIgPSBpc1N0cmluZyhzb3VyY2UpID8gc291cmNlLmluY2x1ZGVzKCIuIikgPyBjcmVhdGVQYXRoR2V0dGVyKHB1YmxpY1RoaXMsIHNvdXJjZSkgOiAoKSA9PiBwdWJsaWNUaGlzW3NvdXJjZV0gOiBzb3VyY2UuYmluZChwdWJsaWNUaGlzLCBwdWJsaWNUaGlzKTsNCiAgbGV0IGNiOw0KICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHsNCiAgICBjYiA9IHZhbHVlOw0KICB9IGVsc2Ugew0KICAgIGNiID0gdmFsdWUuaGFuZGxlcjsNCiAgICBvcHRpb25zID0gdmFsdWU7DQogIH0NCiAgY29uc3QgcmVzZXQgPSBzZXRDdXJyZW50SW5zdGFuY2UodGhpcyk7DQogIGNvbnN0IHJlcyA9IGRvV2F0Y2goZ2V0dGVyLCBjYi5iaW5kKHB1YmxpY1RoaXMpLCBvcHRpb25zKTsNCiAgcmVzZXQoKTsNCiAgcmV0dXJuIHJlczsNCn0NCmZ1bmN0aW9uIGNyZWF0ZVBhdGhHZXR0ZXIoY3R4LCBwYXRoKSB7DQogIGNvbnN0IHNlZ21lbnRzID0gcGF0aC5zcGxpdCgiLiIpOw0KICByZXR1cm4gKCkgPT4gew0KICAgIGxldCBjdXIgPSBjdHg7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWdtZW50cy5sZW5ndGggJiYgY3VyOyBpKyspIHsNCiAgICAgIGN1ciA9IGN1cltzZWdtZW50c1tpXV07DQogICAgfQ0KICAgIHJldHVybiBjdXI7DQogIH07DQp9DQoNCmZ1bmN0aW9uIHVzZU1vZGVsKHByb3BzLCBuYW1lLCBvcHRpb25zID0gRU1QVFlfT0JKKSB7DQogIGNvbnN0IGkgPSBnZXRDdXJyZW50SW5zdGFuY2UoKTsNCiAgaWYgKCFpKSB7DQogICAgd2FybiQxKGB1c2VNb2RlbCgpIGNhbGxlZCB3aXRob3V0IGFjdGl2ZSBpbnN0YW5jZS5gKTsNCiAgICByZXR1cm4gcmVmKCk7DQogIH0NCiAgY29uc3QgY2FtZWxpemVkTmFtZSA9IGNhbWVsaXplKG5hbWUpOw0KICBpZiAoIWkucHJvcHNPcHRpb25zWzBdW2NhbWVsaXplZE5hbWVdKSB7DQogICAgd2FybiQxKGB1c2VNb2RlbCgpIGNhbGxlZCB3aXRoIHByb3AgIiR7bmFtZX0iIHdoaWNoIGlzIG5vdCBkZWNsYXJlZC5gKTsNCiAgICByZXR1cm4gcmVmKCk7DQogIH0NCiAgY29uc3QgaHlwaGVuYXRlZE5hbWUgPSBoeXBoZW5hdGUobmFtZSk7DQogIGNvbnN0IG1vZGlmaWVycyA9IGdldE1vZGVsTW9kaWZpZXJzKHByb3BzLCBjYW1lbGl6ZWROYW1lKTsNCiAgY29uc3QgcmVzID0gY3VzdG9tUmVmKCh0cmFjaywgdHJpZ2dlcikgPT4gew0KICAgIGxldCBsb2NhbFZhbHVlOw0KICAgIGxldCBwcmV2U2V0VmFsdWUgPSBFTVBUWV9PQko7DQogICAgbGV0IHByZXZFbWl0dGVkVmFsdWU7DQogICAgd2F0Y2hTeW5jRWZmZWN0KCgpID0+IHsNCiAgICAgIGNvbnN0IHByb3BWYWx1ZSA9IHByb3BzW2NhbWVsaXplZE5hbWVdOw0KICAgICAgaWYgKGhhc0NoYW5nZWQobG9jYWxWYWx1ZSwgcHJvcFZhbHVlKSkgew0KICAgICAgICBsb2NhbFZhbHVlID0gcHJvcFZhbHVlOw0KICAgICAgICB0cmlnZ2VyKCk7DQogICAgICB9DQogICAgfSk7DQogICAgcmV0dXJuIHsNCiAgICAgIGdldCgpIHsNCiAgICAgICAgdHJhY2soKTsNCiAgICAgICAgcmV0dXJuIG9wdGlvbnMuZ2V0ID8gb3B0aW9ucy5nZXQobG9jYWxWYWx1ZSkgOiBsb2NhbFZhbHVlOw0KICAgICAgfSwNCiAgICAgIHNldCh2YWx1ZSkgew0KICAgICAgICBjb25zdCBlbWl0dGVkVmFsdWUgPSBvcHRpb25zLnNldCA/IG9wdGlvbnMuc2V0KHZhbHVlKSA6IHZhbHVlOw0KICAgICAgICBpZiAoIWhhc0NoYW5nZWQoZW1pdHRlZFZhbHVlLCBsb2NhbFZhbHVlKSAmJiAhKHByZXZTZXRWYWx1ZSAhPT0gRU1QVFlfT0JKICYmIGhhc0NoYW5nZWQodmFsdWUsIHByZXZTZXRWYWx1ZSkpKSB7DQogICAgICAgICAgcmV0dXJuOw0KICAgICAgICB9DQogICAgICAgIGNvbnN0IHJhd1Byb3BzID0gaS52bm9kZS5wcm9wczsNCiAgICAgICAgaWYgKCEocmF3UHJvcHMgJiYgLy8gY2hlY2sgaWYgcGFyZW50IGhhcyBwYXNzZWQgdi1tb2RlbA0KICAgICAgICAobmFtZSBpbiByYXdQcm9wcyB8fCBjYW1lbGl6ZWROYW1lIGluIHJhd1Byb3BzIHx8IGh5cGhlbmF0ZWROYW1lIGluIHJhd1Byb3BzKSAmJiAoYG9uVXBkYXRlOiR7bmFtZX1gIGluIHJhd1Byb3BzIHx8IGBvblVwZGF0ZToke2NhbWVsaXplZE5hbWV9YCBpbiByYXdQcm9wcyB8fCBgb25VcGRhdGU6JHtoeXBoZW5hdGVkTmFtZX1gIGluIHJhd1Byb3BzKSkpIHsNCiAgICAgICAgICBsb2NhbFZhbHVlID0gdmFsdWU7DQogICAgICAgICAgdHJpZ2dlcigpOw0KICAgICAgICB9DQogICAgICAgIGkuZW1pdChgdXBkYXRlOiR7bmFtZX1gLCBlbWl0dGVkVmFsdWUpOw0KICAgICAgICBpZiAoaGFzQ2hhbmdlZCh2YWx1ZSwgZW1pdHRlZFZhbHVlKSAmJiBoYXNDaGFuZ2VkKHZhbHVlLCBwcmV2U2V0VmFsdWUpICYmICFoYXNDaGFuZ2VkKGVtaXR0ZWRWYWx1ZSwgcHJldkVtaXR0ZWRWYWx1ZSkpIHsNCiAgICAgICAgICB0cmlnZ2VyKCk7DQogICAgICAgIH0NCiAgICAgICAgcHJldlNldFZhbHVlID0gdmFsdWU7DQogICAgICAgIHByZXZFbWl0dGVkVmFsdWUgPSBlbWl0dGVkVmFsdWU7DQogICAgICB9DQogICAgfTsNCiAgfSk7DQogIHJlc1tTeW1ib2wuaXRlcmF0b3JdID0gKCkgPT4gew0KICAgIGxldCBpMiA9IDA7DQogICAgcmV0dXJuIHsNCiAgICAgIG5leHQoKSB7DQogICAgICAgIGlmIChpMiA8IDIpIHsNCiAgICAgICAgICByZXR1cm4geyB2YWx1ZTogaTIrKyA/IG1vZGlmaWVycyB8fCBFTVBUWV9PQkogOiByZXMsIGRvbmU6IGZhbHNlIH07DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgcmV0dXJuIHsgZG9uZTogdHJ1ZSB9Ow0KICAgICAgICB9DQogICAgICB9DQogICAgfTsNCiAgfTsNCiAgcmV0dXJuIHJlczsNCn0NCmNvbnN0IGdldE1vZGVsTW9kaWZpZXJzID0gKHByb3BzLCBtb2RlbE5hbWUpID0+IHsNCiAgcmV0dXJuIG1vZGVsTmFtZSA9PT0gIm1vZGVsVmFsdWUiIHx8IG1vZGVsTmFtZSA9PT0gIm1vZGVsLXZhbHVlIiA/IHByb3BzLm1vZGVsTW9kaWZpZXJzIDogcHJvcHNbYCR7bW9kZWxOYW1lfU1vZGlmaWVyc2BdIHx8IHByb3BzW2Ake2NhbWVsaXplKG1vZGVsTmFtZSl9TW9kaWZpZXJzYF0gfHwgcHJvcHNbYCR7aHlwaGVuYXRlKG1vZGVsTmFtZSl9TW9kaWZpZXJzYF07DQp9Ow0KDQpmdW5jdGlvbiBlbWl0KGluc3RhbmNlLCBldmVudCwgLi4ucmF3QXJncykgew0KICBpZiAoaW5zdGFuY2UuaXNVbm1vdW50ZWQpIHJldHVybjsNCiAgY29uc3QgcHJvcHMgPSBpbnN0YW5jZS52bm9kZS5wcm9wcyB8fCBFTVBUWV9PQko7DQogIHsNCiAgICBjb25zdCB7DQogICAgICBlbWl0c09wdGlvbnMsDQogICAgICBwcm9wc09wdGlvbnM6IFtwcm9wc09wdGlvbnNdDQogICAgfSA9IGluc3RhbmNlOw0KICAgIGlmIChlbWl0c09wdGlvbnMpIHsNCiAgICAgIGlmICghKGV2ZW50IGluIGVtaXRzT3B0aW9ucykgJiYgdHJ1ZSkgew0KICAgICAgICBpZiAoIXByb3BzT3B0aW9ucyB8fCAhKHRvSGFuZGxlcktleShjYW1lbGl6ZShldmVudCkpIGluIHByb3BzT3B0aW9ucykpIHsNCiAgICAgICAgICB3YXJuJDEoDQogICAgICAgICAgICBgQ29tcG9uZW50IGVtaXR0ZWQgZXZlbnQgIiR7ZXZlbnR9IiBidXQgaXQgaXMgbmVpdGhlciBkZWNsYXJlZCBpbiB0aGUgZW1pdHMgb3B0aW9uIG5vciBhcyBhbiAiJHt0b0hhbmRsZXJLZXkoY2FtZWxpemUoZXZlbnQpKX0iIHByb3AuYA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGNvbnN0IHZhbGlkYXRvciA9IGVtaXRzT3B0aW9uc1tldmVudF07DQogICAgICAgIGlmIChpc0Z1bmN0aW9uKHZhbGlkYXRvcikpIHsNCiAgICAgICAgICBjb25zdCBpc1ZhbGlkID0gdmFsaWRhdG9yKC4uLnJhd0FyZ3MpOw0KICAgICAgICAgIGlmICghaXNWYWxpZCkgew0KICAgICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgICBgSW52YWxpZCBldmVudCBhcmd1bWVudHM6IGV2ZW50IHZhbGlkYXRpb24gZmFpbGVkIGZvciBldmVudCAiJHtldmVudH0iLmANCiAgICAgICAgICAgICk7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICB9DQogIGxldCBhcmdzID0gcmF3QXJnczsNCiAgY29uc3QgaXNNb2RlbExpc3RlbmVyID0gZXZlbnQuc3RhcnRzV2l0aCgidXBkYXRlOiIpOw0KICBjb25zdCBtb2RpZmllcnMgPSBpc01vZGVsTGlzdGVuZXIgJiYgZ2V0TW9kZWxNb2RpZmllcnMocHJvcHMsIGV2ZW50LnNsaWNlKDcpKTsNCiAgaWYgKG1vZGlmaWVycykgew0KICAgIGlmIChtb2RpZmllcnMudHJpbSkgew0KICAgICAgYXJncyA9IHJhd0FyZ3MubWFwKChhKSA9PiBpc1N0cmluZyhhKSA/IGEudHJpbSgpIDogYSk7DQogICAgfQ0KICAgIGlmIChtb2RpZmllcnMubnVtYmVyKSB7DQogICAgICBhcmdzID0gcmF3QXJncy5tYXAobG9vc2VUb051bWJlcik7DQogICAgfQ0KICB9DQogIHsNCiAgICBkZXZ0b29sc0NvbXBvbmVudEVtaXQoaW5zdGFuY2UsIGV2ZW50LCBhcmdzKTsNCiAgfQ0KICB7DQogICAgY29uc3QgbG93ZXJDYXNlRXZlbnQgPSBldmVudC50b0xvd2VyQ2FzZSgpOw0KICAgIGlmIChsb3dlckNhc2VFdmVudCAhPT0gZXZlbnQgJiYgcHJvcHNbdG9IYW5kbGVyS2V5KGxvd2VyQ2FzZUV2ZW50KV0pIHsNCiAgICAgIHdhcm4kMSgNCiAgICAgICAgYEV2ZW50ICIke2xvd2VyQ2FzZUV2ZW50fSIgaXMgZW1pdHRlZCBpbiBjb21wb25lbnQgJHtmb3JtYXRDb21wb25lbnROYW1lKA0KICAgICAgICAgIGluc3RhbmNlLA0KICAgICAgICAgIGluc3RhbmNlLnR5cGUNCiAgICAgICAgKX0gYnV0IHRoZSBoYW5kbGVyIGlzIHJlZ2lzdGVyZWQgZm9yICIke2V2ZW50fSIuIE5vdGUgdGhhdCBIVE1MIGF0dHJpYnV0ZXMgYXJlIGNhc2UtaW5zZW5zaXRpdmUgYW5kIHlvdSBjYW5ub3QgdXNlIHYtb24gdG8gbGlzdGVuIHRvIGNhbWVsQ2FzZSBldmVudHMgd2hlbiB1c2luZyBpbi1ET00gdGVtcGxhdGVzLiBZb3Ugc2hvdWxkIHByb2JhYmx5IHVzZSAiJHtoeXBoZW5hdGUoDQogICAgICAgICAgZXZlbnQNCiAgICAgICAgKX0iIGluc3RlYWQgb2YgIiR7ZXZlbnR9Ii5gDQogICAgICApOw0KICAgIH0NCiAgfQ0KICBsZXQgaGFuZGxlck5hbWU7DQogIGxldCBoYW5kbGVyID0gcHJvcHNbaGFuZGxlck5hbWUgPSB0b0hhbmRsZXJLZXkoZXZlbnQpXSB8fCAvLyBhbHNvIHRyeSBjYW1lbENhc2UgZXZlbnQgaGFuZGxlciAoIzIyNDkpDQogIHByb3BzW2hhbmRsZXJOYW1lID0gdG9IYW5kbGVyS2V5KGNhbWVsaXplKGV2ZW50KSldOw0KICBpZiAoIWhhbmRsZXIgJiYgaXNNb2RlbExpc3RlbmVyKSB7DQogICAgaGFuZGxlciA9IHByb3BzW2hhbmRsZXJOYW1lID0gdG9IYW5kbGVyS2V5KGh5cGhlbmF0ZShldmVudCkpXTsNCiAgfQ0KICBpZiAoaGFuZGxlcikgew0KICAgIGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nKA0KICAgICAgaGFuZGxlciwNCiAgICAgIGluc3RhbmNlLA0KICAgICAgNiwNCiAgICAgIGFyZ3MNCiAgICApOw0KICB9DQogIGNvbnN0IG9uY2VIYW5kbGVyID0gcHJvcHNbaGFuZGxlck5hbWUgKyBgT25jZWBdOw0KICBpZiAob25jZUhhbmRsZXIpIHsNCiAgICBpZiAoIWluc3RhbmNlLmVtaXR0ZWQpIHsNCiAgICAgIGluc3RhbmNlLmVtaXR0ZWQgPSB7fTsNCiAgICB9IGVsc2UgaWYgKGluc3RhbmNlLmVtaXR0ZWRbaGFuZGxlck5hbWVdKSB7DQogICAgICByZXR1cm47DQogICAgfQ0KICAgIGluc3RhbmNlLmVtaXR0ZWRbaGFuZGxlck5hbWVdID0gdHJ1ZTsNCiAgICBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZygNCiAgICAgIG9uY2VIYW5kbGVyLA0KICAgICAgaW5zdGFuY2UsDQogICAgICA2LA0KICAgICAgYXJncw0KICAgICk7DQogIH0NCn0NCmZ1bmN0aW9uIG5vcm1hbGl6ZUVtaXRzT3B0aW9ucyhjb21wLCBhcHBDb250ZXh0LCBhc01peGluID0gZmFsc2UpIHsNCiAgY29uc3QgY2FjaGUgPSBhcHBDb250ZXh0LmVtaXRzQ2FjaGU7DQogIGNvbnN0IGNhY2hlZCA9IGNhY2hlLmdldChjb21wKTsNCiAgaWYgKGNhY2hlZCAhPT0gdm9pZCAwKSB7DQogICAgcmV0dXJuIGNhY2hlZDsNCiAgfQ0KICBjb25zdCByYXcgPSBjb21wLmVtaXRzOw0KICBsZXQgbm9ybWFsaXplZCA9IHt9Ow0KICBsZXQgaGFzRXh0ZW5kcyA9IGZhbHNlOw0KICBpZiAoIWlzRnVuY3Rpb24oY29tcCkpIHsNCiAgICBjb25zdCBleHRlbmRFbWl0cyA9IChyYXcyKSA9PiB7DQogICAgICBjb25zdCBub3JtYWxpemVkRnJvbUV4dGVuZCA9IG5vcm1hbGl6ZUVtaXRzT3B0aW9ucyhyYXcyLCBhcHBDb250ZXh0LCB0cnVlKTsNCiAgICAgIGlmIChub3JtYWxpemVkRnJvbUV4dGVuZCkgew0KICAgICAgICBoYXNFeHRlbmRzID0gdHJ1ZTsNCiAgICAgICAgZXh0ZW5kKG5vcm1hbGl6ZWQsIG5vcm1hbGl6ZWRGcm9tRXh0ZW5kKTsNCiAgICAgIH0NCiAgICB9Ow0KICAgIGlmICghYXNNaXhpbiAmJiBhcHBDb250ZXh0Lm1peGlucy5sZW5ndGgpIHsNCiAgICAgIGFwcENvbnRleHQubWl4aW5zLmZvckVhY2goZXh0ZW5kRW1pdHMpOw0KICAgIH0NCiAgICBpZiAoY29tcC5leHRlbmRzKSB7DQogICAgICBleHRlbmRFbWl0cyhjb21wLmV4dGVuZHMpOw0KICAgIH0NCiAgICBpZiAoY29tcC5taXhpbnMpIHsNCiAgICAgIGNvbXAubWl4aW5zLmZvckVhY2goZXh0ZW5kRW1pdHMpOw0KICAgIH0NCiAgfQ0KICBpZiAoIXJhdyAmJiAhaGFzRXh0ZW5kcykgew0KICAgIGlmIChpc09iamVjdChjb21wKSkgew0KICAgICAgY2FjaGUuc2V0KGNvbXAsIG51bGwpOw0KICAgIH0NCiAgICByZXR1cm4gbnVsbDsNCiAgfQ0KICBpZiAoaXNBcnJheShyYXcpKSB7DQogICAgcmF3LmZvckVhY2goKGtleSkgPT4gbm9ybWFsaXplZFtrZXldID0gbnVsbCk7DQogIH0gZWxzZSB7DQogICAgZXh0ZW5kKG5vcm1hbGl6ZWQsIHJhdyk7DQogIH0NCiAgaWYgKGlzT2JqZWN0KGNvbXApKSB7DQogICAgY2FjaGUuc2V0KGNvbXAsIG5vcm1hbGl6ZWQpOw0KICB9DQogIHJldHVybiBub3JtYWxpemVkOw0KfQ0KZnVuY3Rpb24gaXNFbWl0TGlzdGVuZXIob3B0aW9ucywga2V5KSB7DQogIGlmICghb3B0aW9ucyB8fCAhaXNPbihrZXkpKSB7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9DQogIGtleSA9IGtleS5zbGljZSgyKS5yZXBsYWNlKC9PbmNlJC8sICIiKTsNCiAgcmV0dXJuIGhhc093bihvcHRpb25zLCBrZXlbMF0udG9Mb3dlckNhc2UoKSArIGtleS5zbGljZSgxKSkgfHwgaGFzT3duKG9wdGlvbnMsIGh5cGhlbmF0ZShrZXkpKSB8fCBoYXNPd24ob3B0aW9ucywga2V5KTsNCn0NCg0KbGV0IGFjY2Vzc2VkQXR0cnMgPSBmYWxzZTsNCmZ1bmN0aW9uIG1hcmtBdHRyc0FjY2Vzc2VkKCkgew0KICBhY2Nlc3NlZEF0dHJzID0gdHJ1ZTsNCn0NCmZ1bmN0aW9uIHJlbmRlckNvbXBvbmVudFJvb3QoaW5zdGFuY2UpIHsNCiAgY29uc3Qgew0KICAgIHR5cGU6IENvbXBvbmVudCwNCiAgICB2bm9kZSwNCiAgICBwcm94eSwNCiAgICB3aXRoUHJveHksDQogICAgcHJvcHNPcHRpb25zOiBbcHJvcHNPcHRpb25zXSwNCiAgICBzbG90cywNCiAgICBhdHRycywNCiAgICBlbWl0LA0KICAgIHJlbmRlciwNCiAgICByZW5kZXJDYWNoZSwNCiAgICBwcm9wcywNCiAgICBkYXRhLA0KICAgIHNldHVwU3RhdGUsDQogICAgY3R4LA0KICAgIGluaGVyaXRBdHRycw0KICB9ID0gaW5zdGFuY2U7DQogIGNvbnN0IHByZXYgPSBzZXRDdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UoaW5zdGFuY2UpOw0KICBsZXQgcmVzdWx0Ow0KICBsZXQgZmFsbHRocm91Z2hBdHRyczsNCiAgew0KICAgIGFjY2Vzc2VkQXR0cnMgPSBmYWxzZTsNCiAgfQ0KICB0cnkgew0KICAgIGlmICh2bm9kZS5zaGFwZUZsYWcgJiA0KSB7DQogICAgICBjb25zdCBwcm94eVRvVXNlID0gd2l0aFByb3h5IHx8IHByb3h5Ow0KICAgICAgY29uc3QgdGhpc1Byb3h5ID0gc2V0dXBTdGF0ZS5fX2lzU2NyaXB0U2V0dXAgPyBuZXcgUHJveHkocHJveHlUb1VzZSwgew0KICAgICAgICBnZXQodGFyZ2V0LCBrZXksIHJlY2VpdmVyKSB7DQogICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgYFByb3BlcnR5ICcke1N0cmluZygNCiAgICAgICAgICAgICAga2V5DQogICAgICAgICAgICApfScgd2FzIGFjY2Vzc2VkIHZpYSAndGhpcycuIEF2b2lkIHVzaW5nICd0aGlzJyBpbiB0ZW1wbGF0ZXMuYA0KICAgICAgICAgICk7DQogICAgICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0KHRhcmdldCwga2V5LCByZWNlaXZlcik7DQogICAgICAgIH0NCiAgICAgIH0pIDogcHJveHlUb1VzZTsNCiAgICAgIHJlc3VsdCA9IG5vcm1hbGl6ZVZOb2RlKA0KICAgICAgICByZW5kZXIuY2FsbCgNCiAgICAgICAgICB0aGlzUHJveHksDQogICAgICAgICAgcHJveHlUb1VzZSwNCiAgICAgICAgICByZW5kZXJDYWNoZSwNCiAgICAgICAgICB0cnVlID8gc2hhbGxvd1JlYWRvbmx5KHByb3BzKSA6IHByb3BzLA0KICAgICAgICAgIHNldHVwU3RhdGUsDQogICAgICAgICAgZGF0YSwNCiAgICAgICAgICBjdHgNCiAgICAgICAgKQ0KICAgICAgKTsNCiAgICAgIGZhbGx0aHJvdWdoQXR0cnMgPSBhdHRyczsNCiAgICB9IGVsc2Ugew0KICAgICAgY29uc3QgcmVuZGVyMiA9IENvbXBvbmVudDsNCiAgICAgIGlmIChhdHRycyA9PT0gcHJvcHMpIHsNCiAgICAgICAgbWFya0F0dHJzQWNjZXNzZWQoKTsNCiAgICAgIH0NCiAgICAgIHJlc3VsdCA9IG5vcm1hbGl6ZVZOb2RlKA0KICAgICAgICByZW5kZXIyLmxlbmd0aCA+IDEgPyByZW5kZXIyKA0KICAgICAgICAgIHRydWUgPyBzaGFsbG93UmVhZG9ubHkocHJvcHMpIDogcHJvcHMsDQogICAgICAgICAgdHJ1ZSA/IHsNCiAgICAgICAgICAgIGdldCBhdHRycygpIHsNCiAgICAgICAgICAgICAgbWFya0F0dHJzQWNjZXNzZWQoKTsNCiAgICAgICAgICAgICAgcmV0dXJuIHNoYWxsb3dSZWFkb25seShhdHRycyk7DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgc2xvdHMsDQogICAgICAgICAgICBlbWl0DQogICAgICAgICAgfSA6IHsgYXR0cnMsIHNsb3RzLCBlbWl0IH0NCiAgICAgICAgKSA6IHJlbmRlcjIoDQogICAgICAgICAgdHJ1ZSA/IHNoYWxsb3dSZWFkb25seShwcm9wcykgOiBwcm9wcywNCiAgICAgICAgICBudWxsDQogICAgICAgICkNCiAgICAgICk7DQogICAgICBmYWxsdGhyb3VnaEF0dHJzID0gQ29tcG9uZW50LnByb3BzID8gYXR0cnMgOiBnZXRGdW5jdGlvbmFsRmFsbHRocm91Z2goYXR0cnMpOw0KICAgIH0NCiAgfSBjYXRjaCAoZXJyKSB7DQogICAgYmxvY2tTdGFjay5sZW5ndGggPSAwOw0KICAgIGhhbmRsZUVycm9yKGVyciwgaW5zdGFuY2UsIDEpOw0KICAgIHJlc3VsdCA9IGNyZWF0ZVZOb2RlKENvbW1lbnQpOw0KICB9DQogIGxldCByb290ID0gcmVzdWx0Ow0KICBsZXQgc2V0Um9vdCA9IHZvaWQgMDsNCiAgaWYgKHJlc3VsdC5wYXRjaEZsYWcgPiAwICYmIHJlc3VsdC5wYXRjaEZsYWcgJiAyMDQ4KSB7DQogICAgW3Jvb3QsIHNldFJvb3RdID0gZ2V0Q2hpbGRSb290KHJlc3VsdCk7DQogIH0NCiAgaWYgKGZhbGx0aHJvdWdoQXR0cnMgJiYgaW5oZXJpdEF0dHJzICE9PSBmYWxzZSkgew0KICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhmYWxsdGhyb3VnaEF0dHJzKTsNCiAgICBjb25zdCB7IHNoYXBlRmxhZyB9ID0gcm9vdDsNCiAgICBpZiAoa2V5cy5sZW5ndGgpIHsNCiAgICAgIGlmIChzaGFwZUZsYWcgJiAoMSB8IDYpKSB7DQogICAgICAgIGlmIChwcm9wc09wdGlvbnMgJiYga2V5cy5zb21lKGlzTW9kZWxMaXN0ZW5lcikpIHsNCiAgICAgICAgICBmYWxsdGhyb3VnaEF0dHJzID0gZmlsdGVyTW9kZWxMaXN0ZW5lcnMoDQogICAgICAgICAgICBmYWxsdGhyb3VnaEF0dHJzLA0KICAgICAgICAgICAgcHJvcHNPcHRpb25zDQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgICByb290ID0gY2xvbmVWTm9kZShyb290LCBmYWxsdGhyb3VnaEF0dHJzLCBmYWxzZSwgdHJ1ZSk7DQogICAgICB9IGVsc2UgaWYgKCFhY2Nlc3NlZEF0dHJzICYmIHJvb3QudHlwZSAhPT0gQ29tbWVudCkgew0KICAgICAgICBjb25zdCBhbGxBdHRycyA9IE9iamVjdC5rZXlzKGF0dHJzKTsNCiAgICAgICAgY29uc3QgZXZlbnRBdHRycyA9IFtdOw0KICAgICAgICBjb25zdCBleHRyYUF0dHJzID0gW107DQogICAgICAgIGZvciAobGV0IGkgPSAwLCBsID0gYWxsQXR0cnMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7DQogICAgICAgICAgY29uc3Qga2V5ID0gYWxsQXR0cnNbaV07DQogICAgICAgICAgaWYgKGlzT24oa2V5KSkgew0KICAgICAgICAgICAgaWYgKCFpc01vZGVsTGlzdGVuZXIoa2V5KSkgew0KICAgICAgICAgICAgICBldmVudEF0dHJzLnB1c2goa2V5WzJdLnRvTG93ZXJDYXNlKCkgKyBrZXkuc2xpY2UoMykpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBleHRyYUF0dHJzLnB1c2goa2V5KTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgaWYgKGV4dHJhQXR0cnMubGVuZ3RoKSB7DQogICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgYEV4dHJhbmVvdXMgbm9uLXByb3BzIGF0dHJpYnV0ZXMgKCR7ZXh0cmFBdHRycy5qb2luKCIsICIpfSkgd2VyZSBwYXNzZWQgdG8gY29tcG9uZW50IGJ1dCBjb3VsZCBub3QgYmUgYXV0b21hdGljYWxseSBpbmhlcml0ZWQgYmVjYXVzZSBjb21wb25lbnQgcmVuZGVycyBmcmFnbWVudCBvciB0ZXh0IG9yIHRlbGVwb3J0IHJvb3Qgbm9kZXMuYA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKGV2ZW50QXR0cnMubGVuZ3RoKSB7DQogICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgYEV4dHJhbmVvdXMgbm9uLWVtaXRzIGV2ZW50IGxpc3RlbmVycyAoJHtldmVudEF0dHJzLmpvaW4oIiwgIil9KSB3ZXJlIHBhc3NlZCB0byBjb21wb25lbnQgYnV0IGNvdWxkIG5vdCBiZSBhdXRvbWF0aWNhbGx5IGluaGVyaXRlZCBiZWNhdXNlIGNvbXBvbmVudCByZW5kZXJzIGZyYWdtZW50IG9yIHRleHQgcm9vdCBub2Rlcy4gSWYgdGhlIGxpc3RlbmVyIGlzIGludGVuZGVkIHRvIGJlIGEgY29tcG9uZW50IGN1c3RvbSBldmVudCBsaXN0ZW5lciBvbmx5LCBkZWNsYXJlIGl0IHVzaW5nIHRoZSAiZW1pdHMiIG9wdGlvbi5gDQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICBpZiAodm5vZGUuZGlycykgew0KICAgIGlmICghaXNFbGVtZW50Um9vdChyb290KSkgew0KICAgICAgd2FybiQxKA0KICAgICAgICBgUnVudGltZSBkaXJlY3RpdmUgdXNlZCBvbiBjb21wb25lbnQgd2l0aCBub24tZWxlbWVudCByb290IG5vZGUuIFRoZSBkaXJlY3RpdmVzIHdpbGwgbm90IGZ1bmN0aW9uIGFzIGludGVuZGVkLmANCiAgICAgICk7DQogICAgfQ0KICAgIHJvb3QgPSBjbG9uZVZOb2RlKHJvb3QsIG51bGwsIGZhbHNlLCB0cnVlKTsNCiAgICByb290LmRpcnMgPSByb290LmRpcnMgPyByb290LmRpcnMuY29uY2F0KHZub2RlLmRpcnMpIDogdm5vZGUuZGlyczsNCiAgfQ0KICBpZiAodm5vZGUudHJhbnNpdGlvbikgew0KICAgIGlmICghaXNFbGVtZW50Um9vdChyb290KSkgew0KICAgICAgd2FybiQxKA0KICAgICAgICBgQ29tcG9uZW50IGluc2lkZSA8VHJhbnNpdGlvbj4gcmVuZGVycyBub24tZWxlbWVudCByb290IG5vZGUgdGhhdCBjYW5ub3QgYmUgYW5pbWF0ZWQuYA0KICAgICAgKTsNCiAgICB9DQogICAgc2V0VHJhbnNpdGlvbkhvb2tzKHJvb3QsIHZub2RlLnRyYW5zaXRpb24pOw0KICB9DQogIGlmIChzZXRSb290KSB7DQogICAgc2V0Um9vdChyb290KTsNCiAgfSBlbHNlIHsNCiAgICByZXN1bHQgPSByb290Ow0KICB9DQogIHNldEN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZShwcmV2KTsNCiAgcmV0dXJuIHJlc3VsdDsNCn0NCmNvbnN0IGdldENoaWxkUm9vdCA9ICh2bm9kZSkgPT4gew0KICBjb25zdCByYXdDaGlsZHJlbiA9IHZub2RlLmNoaWxkcmVuOw0KICBjb25zdCBkeW5hbWljQ2hpbGRyZW4gPSB2bm9kZS5keW5hbWljQ2hpbGRyZW47DQogIGNvbnN0IGNoaWxkUm9vdCA9IGZpbHRlclNpbmdsZVJvb3QocmF3Q2hpbGRyZW4sIGZhbHNlKTsNCiAgaWYgKCFjaGlsZFJvb3QpIHsNCiAgICByZXR1cm4gW3Zub2RlLCB2b2lkIDBdOw0KICB9IGVsc2UgaWYgKGNoaWxkUm9vdC5wYXRjaEZsYWcgPiAwICYmIGNoaWxkUm9vdC5wYXRjaEZsYWcgJiAyMDQ4KSB7DQogICAgcmV0dXJuIGdldENoaWxkUm9vdChjaGlsZFJvb3QpOw0KICB9DQogIGNvbnN0IGluZGV4ID0gcmF3Q2hpbGRyZW4uaW5kZXhPZihjaGlsZFJvb3QpOw0KICBjb25zdCBkeW5hbWljSW5kZXggPSBkeW5hbWljQ2hpbGRyZW4gPyBkeW5hbWljQ2hpbGRyZW4uaW5kZXhPZihjaGlsZFJvb3QpIDogLTE7DQogIGNvbnN0IHNldFJvb3QgPSAodXBkYXRlZFJvb3QpID0+IHsNCiAgICByYXdDaGlsZHJlbltpbmRleF0gPSB1cGRhdGVkUm9vdDsNCiAgICBpZiAoZHluYW1pY0NoaWxkcmVuKSB7DQogICAgICBpZiAoZHluYW1pY0luZGV4ID4gLTEpIHsNCiAgICAgICAgZHluYW1pY0NoaWxkcmVuW2R5bmFtaWNJbmRleF0gPSB1cGRhdGVkUm9vdDsNCiAgICAgIH0gZWxzZSBpZiAodXBkYXRlZFJvb3QucGF0Y2hGbGFnID4gMCkgew0KICAgICAgICB2bm9kZS5keW5hbWljQ2hpbGRyZW4gPSBbLi4uZHluYW1pY0NoaWxkcmVuLCB1cGRhdGVkUm9vdF07DQogICAgICB9DQogICAgfQ0KICB9Ow0KICByZXR1cm4gW25vcm1hbGl6ZVZOb2RlKGNoaWxkUm9vdCksIHNldFJvb3RdOw0KfTsNCmZ1bmN0aW9uIGZpbHRlclNpbmdsZVJvb3QoY2hpbGRyZW4sIHJlY3Vyc2UgPSB0cnVlKSB7DQogIGxldCBzaW5nbGVSb290Ow0KICBmb3IgKGxldCBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7DQogICAgY29uc3QgY2hpbGQgPSBjaGlsZHJlbltpXTsNCiAgICBpZiAoaXNWTm9kZShjaGlsZCkpIHsNCiAgICAgIGlmIChjaGlsZC50eXBlICE9PSBDb21tZW50IHx8IGNoaWxkLmNoaWxkcmVuID09PSAidi1pZiIpIHsNCiAgICAgICAgaWYgKHNpbmdsZVJvb3QpIHsNCiAgICAgICAgICByZXR1cm47DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgc2luZ2xlUm9vdCA9IGNoaWxkOw0KICAgICAgICAgIGlmIChyZWN1cnNlICYmIHNpbmdsZVJvb3QucGF0Y2hGbGFnID4gMCAmJiBzaW5nbGVSb290LnBhdGNoRmxhZyAmIDIwNDgpIHsNCiAgICAgICAgICAgIHJldHVybiBmaWx0ZXJTaW5nbGVSb290KHNpbmdsZVJvb3QuY2hpbGRyZW4pOw0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0gZWxzZSB7DQogICAgICByZXR1cm47DQogICAgfQ0KICB9DQogIHJldHVybiBzaW5nbGVSb290Ow0KfQ0KY29uc3QgZ2V0RnVuY3Rpb25hbEZhbGx0aHJvdWdoID0gKGF0dHJzKSA9PiB7DQogIGxldCByZXM7DQogIGZvciAoY29uc3Qga2V5IGluIGF0dHJzKSB7DQogICAgaWYgKGtleSA9PT0gImNsYXNzIiB8fCBrZXkgPT09ICJzdHlsZSIgfHwgaXNPbihrZXkpKSB7DQogICAgICAocmVzIHx8IChyZXMgPSB7fSkpW2tleV0gPSBhdHRyc1trZXldOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gcmVzOw0KfTsNCmNvbnN0IGZpbHRlck1vZGVsTGlzdGVuZXJzID0gKGF0dHJzLCBwcm9wcykgPT4gew0KICBjb25zdCByZXMgPSB7fTsNCiAgZm9yIChjb25zdCBrZXkgaW4gYXR0cnMpIHsNCiAgICBpZiAoIWlzTW9kZWxMaXN0ZW5lcihrZXkpIHx8ICEoa2V5LnNsaWNlKDkpIGluIHByb3BzKSkgew0KICAgICAgcmVzW2tleV0gPSBhdHRyc1trZXldOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gcmVzOw0KfTsNCmNvbnN0IGlzRWxlbWVudFJvb3QgPSAodm5vZGUpID0+IHsNCiAgcmV0dXJuIHZub2RlLnNoYXBlRmxhZyAmICg2IHwgMSkgfHwgdm5vZGUudHlwZSA9PT0gQ29tbWVudDsNCn07DQpmdW5jdGlvbiBzaG91bGRVcGRhdGVDb21wb25lbnQocHJldlZOb2RlLCBuZXh0Vk5vZGUsIG9wdGltaXplZCkgew0KICBjb25zdCB7IHByb3BzOiBwcmV2UHJvcHMsIGNoaWxkcmVuOiBwcmV2Q2hpbGRyZW4sIGNvbXBvbmVudCB9ID0gcHJldlZOb2RlOw0KICBjb25zdCB7IHByb3BzOiBuZXh0UHJvcHMsIGNoaWxkcmVuOiBuZXh0Q2hpbGRyZW4sIHBhdGNoRmxhZyB9ID0gbmV4dFZOb2RlOw0KICBjb25zdCBlbWl0cyA9IGNvbXBvbmVudC5lbWl0c09wdGlvbnM7DQogIGlmICgocHJldkNoaWxkcmVuIHx8IG5leHRDaGlsZHJlbikgJiYgaXNIbXJVcGRhdGluZykgew0KICAgIHJldHVybiB0cnVlOw0KICB9DQogIGlmIChuZXh0Vk5vZGUuZGlycyB8fCBuZXh0Vk5vZGUudHJhbnNpdGlvbikgew0KICAgIHJldHVybiB0cnVlOw0KICB9DQogIGlmIChvcHRpbWl6ZWQgJiYgcGF0Y2hGbGFnID49IDApIHsNCiAgICBpZiAocGF0Y2hGbGFnICYgMTAyNCkgew0KICAgICAgcmV0dXJuIHRydWU7DQogICAgfQ0KICAgIGlmIChwYXRjaEZsYWcgJiAxNikgew0KICAgICAgaWYgKCFwcmV2UHJvcHMpIHsNCiAgICAgICAgcmV0dXJuICEhbmV4dFByb3BzOw0KICAgICAgfQ0KICAgICAgcmV0dXJuIGhhc1Byb3BzQ2hhbmdlZChwcmV2UHJvcHMsIG5leHRQcm9wcywgZW1pdHMpOw0KICAgIH0gZWxzZSBpZiAocGF0Y2hGbGFnICYgOCkgew0KICAgICAgY29uc3QgZHluYW1pY1Byb3BzID0gbmV4dFZOb2RlLmR5bmFtaWNQcm9wczsNCiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZHluYW1pY1Byb3BzLmxlbmd0aDsgaSsrKSB7DQogICAgICAgIGNvbnN0IGtleSA9IGR5bmFtaWNQcm9wc1tpXTsNCiAgICAgICAgaWYgKG5leHRQcm9wc1trZXldICE9PSBwcmV2UHJvcHNba2V5XSAmJiAhaXNFbWl0TGlzdGVuZXIoZW1pdHMsIGtleSkpIHsNCiAgICAgICAgICByZXR1cm4gdHJ1ZTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICBpZiAocHJldkNoaWxkcmVuIHx8IG5leHRDaGlsZHJlbikgew0KICAgICAgaWYgKCFuZXh0Q2hpbGRyZW4gfHwgIW5leHRDaGlsZHJlbi4kc3RhYmxlKSB7DQogICAgICAgIHJldHVybiB0cnVlOw0KICAgICAgfQ0KICAgIH0NCiAgICBpZiAocHJldlByb3BzID09PSBuZXh0UHJvcHMpIHsNCiAgICAgIHJldHVybiBmYWxzZTsNCiAgICB9DQogICAgaWYgKCFwcmV2UHJvcHMpIHsNCiAgICAgIHJldHVybiAhIW5leHRQcm9wczsNCiAgICB9DQogICAgaWYgKCFuZXh0UHJvcHMpIHsNCiAgICAgIHJldHVybiB0cnVlOw0KICAgIH0NCiAgICByZXR1cm4gaGFzUHJvcHNDaGFuZ2VkKHByZXZQcm9wcywgbmV4dFByb3BzLCBlbWl0cyk7DQogIH0NCiAgcmV0dXJuIGZhbHNlOw0KfQ0KZnVuY3Rpb24gaGFzUHJvcHNDaGFuZ2VkKHByZXZQcm9wcywgbmV4dFByb3BzLCBlbWl0c09wdGlvbnMpIHsNCiAgY29uc3QgbmV4dEtleXMgPSBPYmplY3Qua2V5cyhuZXh0UHJvcHMpOw0KICBpZiAobmV4dEtleXMubGVuZ3RoICE9PSBPYmplY3Qua2V5cyhwcmV2UHJvcHMpLmxlbmd0aCkgew0KICAgIHJldHVybiB0cnVlOw0KICB9DQogIGZvciAobGV0IGkgPSAwOyBpIDwgbmV4dEtleXMubGVuZ3RoOyBpKyspIHsNCiAgICBjb25zdCBrZXkgPSBuZXh0S2V5c1tpXTsNCiAgICBpZiAobmV4dFByb3BzW2tleV0gIT09IHByZXZQcm9wc1trZXldICYmICFpc0VtaXRMaXN0ZW5lcihlbWl0c09wdGlvbnMsIGtleSkpIHsNCiAgICAgIHJldHVybiB0cnVlOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gZmFsc2U7DQp9DQpmdW5jdGlvbiB1cGRhdGVIT0NIb3N0RWwoeyB2bm9kZSwgcGFyZW50IH0sIGVsKSB7DQogIHdoaWxlIChwYXJlbnQpIHsNCiAgICBjb25zdCByb290ID0gcGFyZW50LnN1YlRyZWU7DQogICAgaWYgKHJvb3Quc3VzcGVuc2UgJiYgcm9vdC5zdXNwZW5zZS5hY3RpdmVCcmFuY2ggPT09IHZub2RlKSB7DQogICAgICByb290LmVsID0gdm5vZGUuZWw7DQogICAgfQ0KICAgIGlmIChyb290ID09PSB2bm9kZSkgew0KICAgICAgKHZub2RlID0gcGFyZW50LnZub2RlKS5lbCA9IGVsOw0KICAgICAgcGFyZW50ID0gcGFyZW50LnBhcmVudDsNCiAgICB9IGVsc2Ugew0KICAgICAgYnJlYWs7DQogICAgfQ0KICB9DQp9DQoNCmNvbnN0IGlzU3VzcGVuc2UgPSAodHlwZSkgPT4gdHlwZS5fX2lzU3VzcGVuc2U7DQpsZXQgc3VzcGVuc2VJZCA9IDA7DQpjb25zdCBTdXNwZW5zZUltcGwgPSB7DQogIG5hbWU6ICJTdXNwZW5zZSIsDQogIC8vIEluIG9yZGVyIHRvIG1ha2UgU3VzcGVuc2UgdHJlZS1zaGFrYWJsZSwgd2UgbmVlZCB0byBhdm9pZCBpbXBvcnRpbmcgaXQNCiAgLy8gZGlyZWN0bHkgaW4gdGhlIHJlbmRlcmVyLiBUaGUgcmVuZGVyZXIgY2hlY2tzIGZvciB0aGUgX19pc1N1c3BlbnNlIGZsYWcNCiAgLy8gb24gYSB2bm9kZSdzIHR5cGUgYW5kIGNhbGxzIHRoZSBgcHJvY2Vzc2AgbWV0aG9kLCBwYXNzaW5nIGluIHJlbmRlcmVyDQogIC8vIGludGVybmFscy4NCiAgX19pc1N1c3BlbnNlOiB0cnVlLA0KICBwcm9jZXNzKG4xLCBuMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQsIHJlbmRlcmVySW50ZXJuYWxzKSB7DQogICAgaWYgKG4xID09IG51bGwpIHsNCiAgICAgIG1vdW50U3VzcGVuc2UoDQogICAgICAgIG4yLA0KICAgICAgICBjb250YWluZXIsDQogICAgICAgIGFuY2hvciwNCiAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgIG9wdGltaXplZCwNCiAgICAgICAgcmVuZGVyZXJJbnRlcm5hbHMNCiAgICAgICk7DQogICAgfSBlbHNlIHsNCiAgICAgIGlmIChwYXJlbnRTdXNwZW5zZSAmJiBwYXJlbnRTdXNwZW5zZS5kZXBzID4gMCAmJiAhbjEuc3VzcGVuc2UuaXNJbkZhbGxiYWNrKSB7DQogICAgICAgIG4yLnN1c3BlbnNlID0gbjEuc3VzcGVuc2U7DQogICAgICAgIG4yLnN1c3BlbnNlLnZub2RlID0gbjI7DQogICAgICAgIG4yLmVsID0gbjEuZWw7DQogICAgICAgIHJldHVybjsNCiAgICAgIH0NCiAgICAgIHBhdGNoU3VzcGVuc2UoDQogICAgICAgIG4xLA0KICAgICAgICBuMiwNCiAgICAgICAgY29udGFpbmVyLA0KICAgICAgICBhbmNob3IsDQogICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgIG9wdGltaXplZCwNCiAgICAgICAgcmVuZGVyZXJJbnRlcm5hbHMNCiAgICAgICk7DQogICAgfQ0KICB9LA0KICBoeWRyYXRlOiBoeWRyYXRlU3VzcGVuc2UsDQogIG5vcm1hbGl6ZTogbm9ybWFsaXplU3VzcGVuc2VDaGlsZHJlbg0KfTsNCmNvbnN0IFN1c3BlbnNlID0gU3VzcGVuc2VJbXBsIDsNCmZ1bmN0aW9uIHRyaWdnZXJFdmVudCh2bm9kZSwgbmFtZSkgew0KICBjb25zdCBldmVudExpc3RlbmVyID0gdm5vZGUucHJvcHMgJiYgdm5vZGUucHJvcHNbbmFtZV07DQogIGlmIChpc0Z1bmN0aW9uKGV2ZW50TGlzdGVuZXIpKSB7DQogICAgZXZlbnRMaXN0ZW5lcigpOw0KICB9DQp9DQpmdW5jdGlvbiBtb3VudFN1c3BlbnNlKHZub2RlLCBjb250YWluZXIsIGFuY2hvciwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgbmFtZXNwYWNlLCBzbG90U2NvcGVJZHMsIG9wdGltaXplZCwgcmVuZGVyZXJJbnRlcm5hbHMpIHsNCiAgY29uc3Qgew0KICAgIHA6IHBhdGNoLA0KICAgIG86IHsgY3JlYXRlRWxlbWVudCB9DQogIH0gPSByZW5kZXJlckludGVybmFsczsNCiAgY29uc3QgaGlkZGVuQ29udGFpbmVyID0gY3JlYXRlRWxlbWVudCgiZGl2Iik7DQogIGNvbnN0IHN1c3BlbnNlID0gdm5vZGUuc3VzcGVuc2UgPSBjcmVhdGVTdXNwZW5zZUJvdW5kYXJ5KA0KICAgIHZub2RlLA0KICAgIHBhcmVudFN1c3BlbnNlLA0KICAgIHBhcmVudENvbXBvbmVudCwNCiAgICBjb250YWluZXIsDQogICAgaGlkZGVuQ29udGFpbmVyLA0KICAgIGFuY2hvciwNCiAgICBuYW1lc3BhY2UsDQogICAgc2xvdFNjb3BlSWRzLA0KICAgIG9wdGltaXplZCwNCiAgICByZW5kZXJlckludGVybmFscw0KICApOw0KICBwYXRjaCgNCiAgICBudWxsLA0KICAgIHN1c3BlbnNlLnBlbmRpbmdCcmFuY2ggPSB2bm9kZS5zc0NvbnRlbnQsDQogICAgaGlkZGVuQ29udGFpbmVyLA0KICAgIG51bGwsDQogICAgcGFyZW50Q29tcG9uZW50LA0KICAgIHN1c3BlbnNlLA0KICAgIG5hbWVzcGFjZSwNCiAgICBzbG90U2NvcGVJZHMNCiAgKTsNCiAgaWYgKHN1c3BlbnNlLmRlcHMgPiAwKSB7DQogICAgdHJpZ2dlckV2ZW50KHZub2RlLCAib25QZW5kaW5nIik7DQogICAgdHJpZ2dlckV2ZW50KHZub2RlLCAib25GYWxsYmFjayIpOw0KICAgIHBhdGNoKA0KICAgICAgbnVsbCwNCiAgICAgIHZub2RlLnNzRmFsbGJhY2ssDQogICAgICBjb250YWluZXIsDQogICAgICBhbmNob3IsDQogICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICBudWxsLA0KICAgICAgLy8gZmFsbGJhY2sgdHJlZSB3aWxsIG5vdCBoYXZlIHN1c3BlbnNlIGNvbnRleHQNCiAgICAgIG5hbWVzcGFjZSwNCiAgICAgIHNsb3RTY29wZUlkcw0KICAgICk7DQogICAgc2V0QWN0aXZlQnJhbmNoKHN1c3BlbnNlLCB2bm9kZS5zc0ZhbGxiYWNrKTsNCiAgfSBlbHNlIHsNCiAgICBzdXNwZW5zZS5yZXNvbHZlKGZhbHNlLCB0cnVlKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gcGF0Y2hTdXNwZW5zZShuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQsIHsgcDogcGF0Y2gsIHVtOiB1bm1vdW50LCBvOiB7IGNyZWF0ZUVsZW1lbnQgfSB9KSB7DQogIGNvbnN0IHN1c3BlbnNlID0gbjIuc3VzcGVuc2UgPSBuMS5zdXNwZW5zZTsNCiAgc3VzcGVuc2Uudm5vZGUgPSBuMjsNCiAgbjIuZWwgPSBuMS5lbDsNCiAgY29uc3QgbmV3QnJhbmNoID0gbjIuc3NDb250ZW50Ow0KICBjb25zdCBuZXdGYWxsYmFjayA9IG4yLnNzRmFsbGJhY2s7DQogIGNvbnN0IHsgYWN0aXZlQnJhbmNoLCBwZW5kaW5nQnJhbmNoLCBpc0luRmFsbGJhY2ssIGlzSHlkcmF0aW5nIH0gPSBzdXNwZW5zZTsNCiAgaWYgKHBlbmRpbmdCcmFuY2gpIHsNCiAgICBzdXNwZW5zZS5wZW5kaW5nQnJhbmNoID0gbmV3QnJhbmNoOw0KICAgIGlmIChpc1NhbWVWTm9kZVR5cGUobmV3QnJhbmNoLCBwZW5kaW5nQnJhbmNoKSkgew0KICAgICAgcGF0Y2goDQogICAgICAgIHBlbmRpbmdCcmFuY2gsDQogICAgICAgIG5ld0JyYW5jaCwNCiAgICAgICAgc3VzcGVuc2UuaGlkZGVuQ29udGFpbmVyLA0KICAgICAgICBudWxsLA0KICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgIHN1c3BlbnNlLA0KICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgb3B0aW1pemVkDQogICAgICApOw0KICAgICAgaWYgKHN1c3BlbnNlLmRlcHMgPD0gMCkgew0KICAgICAgICBzdXNwZW5zZS5yZXNvbHZlKCk7DQogICAgICB9IGVsc2UgaWYgKGlzSW5GYWxsYmFjaykgew0KICAgICAgICBpZiAoIWlzSHlkcmF0aW5nKSB7DQogICAgICAgICAgcGF0Y2goDQogICAgICAgICAgICBhY3RpdmVCcmFuY2gsDQogICAgICAgICAgICBuZXdGYWxsYmFjaywNCiAgICAgICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgICAgIGFuY2hvciwNCiAgICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICAgIG51bGwsDQogICAgICAgICAgICAvLyBmYWxsYmFjayB0cmVlIHdpbGwgbm90IGhhdmUgc3VzcGVuc2UgY29udGV4dA0KICAgICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICAgKTsNCiAgICAgICAgICBzZXRBY3RpdmVCcmFuY2goc3VzcGVuc2UsIG5ld0ZhbGxiYWNrKTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0gZWxzZSB7DQogICAgICBzdXNwZW5zZS5wZW5kaW5nSWQgPSBzdXNwZW5zZUlkKys7DQogICAgICBpZiAoaXNIeWRyYXRpbmcpIHsNCiAgICAgICAgc3VzcGVuc2UuaXNIeWRyYXRpbmcgPSBmYWxzZTsNCiAgICAgICAgc3VzcGVuc2UuYWN0aXZlQnJhbmNoID0gcGVuZGluZ0JyYW5jaDsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHVubW91bnQocGVuZGluZ0JyYW5jaCwgcGFyZW50Q29tcG9uZW50LCBzdXNwZW5zZSk7DQogICAgICB9DQogICAgICBzdXNwZW5zZS5kZXBzID0gMDsNCiAgICAgIHN1c3BlbnNlLmVmZmVjdHMubGVuZ3RoID0gMDsNCiAgICAgIHN1c3BlbnNlLmhpZGRlbkNvbnRhaW5lciA9IGNyZWF0ZUVsZW1lbnQoImRpdiIpOw0KICAgICAgaWYgKGlzSW5GYWxsYmFjaykgew0KICAgICAgICBwYXRjaCgNCiAgICAgICAgICBudWxsLA0KICAgICAgICAgIG5ld0JyYW5jaCwNCiAgICAgICAgICBzdXNwZW5zZS5oaWRkZW5Db250YWluZXIsDQogICAgICAgICAgbnVsbCwNCiAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgc3VzcGVuc2UsDQogICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgKTsNCiAgICAgICAgaWYgKHN1c3BlbnNlLmRlcHMgPD0gMCkgew0KICAgICAgICAgIHN1c3BlbnNlLnJlc29sdmUoKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBwYXRjaCgNCiAgICAgICAgICAgIGFjdGl2ZUJyYW5jaCwNCiAgICAgICAgICAgIG5ld0ZhbGxiYWNrLA0KICAgICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgbnVsbCwNCiAgICAgICAgICAgIC8vIGZhbGxiYWNrIHRyZWUgd2lsbCBub3QgaGF2ZSBzdXNwZW5zZSBjb250ZXh0DQogICAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgICApOw0KICAgICAgICAgIHNldEFjdGl2ZUJyYW5jaChzdXNwZW5zZSwgbmV3RmFsbGJhY2spOw0KICAgICAgICB9DQogICAgICB9IGVsc2UgaWYgKGFjdGl2ZUJyYW5jaCAmJiBpc1NhbWVWTm9kZVR5cGUobmV3QnJhbmNoLCBhY3RpdmVCcmFuY2gpKSB7DQogICAgICAgIHBhdGNoKA0KICAgICAgICAgIGFjdGl2ZUJyYW5jaCwNCiAgICAgICAgICBuZXdCcmFuY2gsDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIGFuY2hvciwNCiAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgc3VzcGVuc2UsDQogICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgKTsNCiAgICAgICAgc3VzcGVuc2UucmVzb2x2ZSh0cnVlKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHBhdGNoKA0KICAgICAgICAgIG51bGwsDQogICAgICAgICAgbmV3QnJhbmNoLA0KICAgICAgICAgIHN1c3BlbnNlLmhpZGRlbkNvbnRhaW5lciwNCiAgICAgICAgICBudWxsLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBzdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICApOw0KICAgICAgICBpZiAoc3VzcGVuc2UuZGVwcyA8PSAwKSB7DQogICAgICAgICAgc3VzcGVuc2UucmVzb2x2ZSgpOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICB9IGVsc2Ugew0KICAgIGlmIChhY3RpdmVCcmFuY2ggJiYgaXNTYW1lVk5vZGVUeXBlKG5ld0JyYW5jaCwgYWN0aXZlQnJhbmNoKSkgew0KICAgICAgcGF0Y2goDQogICAgICAgIGFjdGl2ZUJyYW5jaCwNCiAgICAgICAgbmV3QnJhbmNoLA0KICAgICAgICBjb250YWluZXIsDQogICAgICAgIGFuY2hvciwNCiAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICBzdXNwZW5zZSwNCiAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgIG9wdGltaXplZA0KICAgICAgKTsNCiAgICAgIHNldEFjdGl2ZUJyYW5jaChzdXNwZW5zZSwgbmV3QnJhbmNoKTsNCiAgICB9IGVsc2Ugew0KICAgICAgdHJpZ2dlckV2ZW50KG4yLCAib25QZW5kaW5nIik7DQogICAgICBzdXNwZW5zZS5wZW5kaW5nQnJhbmNoID0gbmV3QnJhbmNoOw0KICAgICAgaWYgKG5ld0JyYW5jaC5zaGFwZUZsYWcgJiA1MTIpIHsNCiAgICAgICAgc3VzcGVuc2UucGVuZGluZ0lkID0gbmV3QnJhbmNoLmNvbXBvbmVudC5zdXNwZW5zZUlkOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgc3VzcGVuc2UucGVuZGluZ0lkID0gc3VzcGVuc2VJZCsrOw0KICAgICAgfQ0KICAgICAgcGF0Y2goDQogICAgICAgIG51bGwsDQogICAgICAgIG5ld0JyYW5jaCwNCiAgICAgICAgc3VzcGVuc2UuaGlkZGVuQ29udGFpbmVyLA0KICAgICAgICBudWxsLA0KICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgIHN1c3BlbnNlLA0KICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgb3B0aW1pemVkDQogICAgICApOw0KICAgICAgaWYgKHN1c3BlbnNlLmRlcHMgPD0gMCkgew0KICAgICAgICBzdXNwZW5zZS5yZXNvbHZlKCk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBjb25zdCB7IHRpbWVvdXQsIHBlbmRpbmdJZCB9ID0gc3VzcGVuc2U7DQogICAgICAgIGlmICh0aW1lb3V0ID4gMCkgew0KICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gew0KICAgICAgICAgICAgaWYgKHN1c3BlbnNlLnBlbmRpbmdJZCA9PT0gcGVuZGluZ0lkKSB7DQogICAgICAgICAgICAgIHN1c3BlbnNlLmZhbGxiYWNrKG5ld0ZhbGxiYWNrKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICB9LCB0aW1lb3V0KTsNCiAgICAgICAgfSBlbHNlIGlmICh0aW1lb3V0ID09PSAwKSB7DQogICAgICAgICAgc3VzcGVuc2UuZmFsbGJhY2sobmV3RmFsbGJhY2spOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICB9DQp9DQpsZXQgaGFzV2FybmVkID0gZmFsc2U7DQpmdW5jdGlvbiBjcmVhdGVTdXNwZW5zZUJvdW5kYXJ5KHZub2RlLCBwYXJlbnRTdXNwZW5zZSwgcGFyZW50Q29tcG9uZW50LCBjb250YWluZXIsIGhpZGRlbkNvbnRhaW5lciwgYW5jaG9yLCBuYW1lc3BhY2UsIHNsb3RTY29wZUlkcywgb3B0aW1pemVkLCByZW5kZXJlckludGVybmFscywgaXNIeWRyYXRpbmcgPSBmYWxzZSkgew0KICBpZiAoIWhhc1dhcm5lZCkgew0KICAgIGhhc1dhcm5lZCA9IHRydWU7DQogICAgY29uc29sZVtjb25zb2xlLmluZm8gPyAiaW5mbyIgOiAibG9nIl0oDQogICAgICBgPFN1c3BlbnNlPiBpcyBhbiBleHBlcmltZW50YWwgZmVhdHVyZSBhbmQgaXRzIEFQSSB3aWxsIGxpa2VseSBjaGFuZ2UuYA0KICAgICk7DQogIH0NCiAgY29uc3Qgew0KICAgIHA6IHBhdGNoLA0KICAgIG06IG1vdmUsDQogICAgdW06IHVubW91bnQsDQogICAgbjogbmV4dCwNCiAgICBvOiB7IHBhcmVudE5vZGUsIHJlbW92ZSB9DQogIH0gPSByZW5kZXJlckludGVybmFsczsNCiAgbGV0IHBhcmVudFN1c3BlbnNlSWQ7DQogIGNvbnN0IGlzU3VzcGVuc2libGUgPSBpc1ZOb2RlU3VzcGVuc2libGUodm5vZGUpOw0KICBpZiAoaXNTdXNwZW5zaWJsZSkgew0KICAgIGlmIChwYXJlbnRTdXNwZW5zZSAmJiBwYXJlbnRTdXNwZW5zZS5wZW5kaW5nQnJhbmNoKSB7DQogICAgICBwYXJlbnRTdXNwZW5zZUlkID0gcGFyZW50U3VzcGVuc2UucGVuZGluZ0lkOw0KICAgICAgcGFyZW50U3VzcGVuc2UuZGVwcysrOw0KICAgIH0NCiAgfQ0KICBjb25zdCB0aW1lb3V0ID0gdm5vZGUucHJvcHMgPyB0b051bWJlcih2bm9kZS5wcm9wcy50aW1lb3V0KSA6IHZvaWQgMDsNCiAgew0KICAgIGFzc2VydE51bWJlcih0aW1lb3V0LCBgU3VzcGVuc2UgdGltZW91dGApOw0KICB9DQogIGNvbnN0IGluaXRpYWxBbmNob3IgPSBhbmNob3I7DQogIGNvbnN0IHN1c3BlbnNlID0gew0KICAgIHZub2RlLA0KICAgIHBhcmVudDogcGFyZW50U3VzcGVuc2UsDQogICAgcGFyZW50Q29tcG9uZW50LA0KICAgIG5hbWVzcGFjZSwNCiAgICBjb250YWluZXIsDQogICAgaGlkZGVuQ29udGFpbmVyLA0KICAgIGRlcHM6IDAsDQogICAgcGVuZGluZ0lkOiBzdXNwZW5zZUlkKyssDQogICAgdGltZW91dDogdHlwZW9mIHRpbWVvdXQgPT09ICJudW1iZXIiID8gdGltZW91dCA6IC0xLA0KICAgIGFjdGl2ZUJyYW5jaDogbnVsbCwNCiAgICBwZW5kaW5nQnJhbmNoOiBudWxsLA0KICAgIGlzSW5GYWxsYmFjazogIWlzSHlkcmF0aW5nLA0KICAgIGlzSHlkcmF0aW5nLA0KICAgIGlzVW5tb3VudGVkOiBmYWxzZSwNCiAgICBlZmZlY3RzOiBbXSwNCiAgICByZXNvbHZlKHJlc3VtZSA9IGZhbHNlLCBzeW5jID0gZmFsc2UpIHsNCiAgICAgIHsNCiAgICAgICAgaWYgKCFyZXN1bWUgJiYgIXN1c3BlbnNlLnBlbmRpbmdCcmFuY2gpIHsNCiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoDQogICAgICAgICAgICBgc3VzcGVuc2UucmVzb2x2ZSgpIGlzIGNhbGxlZCB3aXRob3V0IGEgcGVuZGluZyBicmFuY2guYA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKHN1c3BlbnNlLmlzVW5tb3VudGVkKSB7DQogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKA0KICAgICAgICAgICAgYHN1c3BlbnNlLnJlc29sdmUoKSBpcyBjYWxsZWQgb24gYW4gYWxyZWFkeSB1bm1vdW50ZWQgc3VzcGVuc2UgYm91bmRhcnkuYA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGNvbnN0IHsNCiAgICAgICAgdm5vZGU6IHZub2RlMiwNCiAgICAgICAgYWN0aXZlQnJhbmNoLA0KICAgICAgICBwZW5kaW5nQnJhbmNoLA0KICAgICAgICBwZW5kaW5nSWQsDQogICAgICAgIGVmZmVjdHMsDQogICAgICAgIHBhcmVudENvbXBvbmVudDogcGFyZW50Q29tcG9uZW50MiwNCiAgICAgICAgY29udGFpbmVyOiBjb250YWluZXIyDQogICAgICB9ID0gc3VzcGVuc2U7DQogICAgICBsZXQgZGVsYXlFbnRlciA9IGZhbHNlOw0KICAgICAgaWYgKHN1c3BlbnNlLmlzSHlkcmF0aW5nKSB7DQogICAgICAgIHN1c3BlbnNlLmlzSHlkcmF0aW5nID0gZmFsc2U7DQogICAgICB9IGVsc2UgaWYgKCFyZXN1bWUpIHsNCiAgICAgICAgZGVsYXlFbnRlciA9IGFjdGl2ZUJyYW5jaCAmJiBwZW5kaW5nQnJhbmNoLnRyYW5zaXRpb24gJiYgcGVuZGluZ0JyYW5jaC50cmFuc2l0aW9uLm1vZGUgPT09ICJvdXQtaW4iOw0KICAgICAgICBpZiAoZGVsYXlFbnRlcikgew0KICAgICAgICAgIGFjdGl2ZUJyYW5jaC50cmFuc2l0aW9uLmFmdGVyTGVhdmUgPSAoKSA9PiB7DQogICAgICAgICAgICBpZiAocGVuZGluZ0lkID09PSBzdXNwZW5zZS5wZW5kaW5nSWQpIHsNCiAgICAgICAgICAgICAgbW92ZSgNCiAgICAgICAgICAgICAgICBwZW5kaW5nQnJhbmNoLA0KICAgICAgICAgICAgICAgIGNvbnRhaW5lcjIsDQogICAgICAgICAgICAgICAgYW5jaG9yID09PSBpbml0aWFsQW5jaG9yID8gbmV4dChhY3RpdmVCcmFuY2gpIDogYW5jaG9yLA0KICAgICAgICAgICAgICAgIDANCiAgICAgICAgICAgICAgKTsNCiAgICAgICAgICAgICAgcXVldWVQb3N0Rmx1c2hDYihlZmZlY3RzKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICB9Ow0KICAgICAgICB9DQogICAgICAgIGlmIChhY3RpdmVCcmFuY2gpIHsNCiAgICAgICAgICBpZiAocGFyZW50Tm9kZShhY3RpdmVCcmFuY2guZWwpID09PSBjb250YWluZXIyKSB7DQogICAgICAgICAgICBhbmNob3IgPSBuZXh0KGFjdGl2ZUJyYW5jaCk7DQogICAgICAgICAgfQ0KICAgICAgICAgIHVubW91bnQoYWN0aXZlQnJhbmNoLCBwYXJlbnRDb21wb25lbnQyLCBzdXNwZW5zZSwgdHJ1ZSk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKCFkZWxheUVudGVyKSB7DQogICAgICAgICAgbW92ZShwZW5kaW5nQnJhbmNoLCBjb250YWluZXIyLCBhbmNob3IsIDApOw0KICAgICAgICB9DQogICAgICB9DQogICAgICBzZXRBY3RpdmVCcmFuY2goc3VzcGVuc2UsIHBlbmRpbmdCcmFuY2gpOw0KICAgICAgc3VzcGVuc2UucGVuZGluZ0JyYW5jaCA9IG51bGw7DQogICAgICBzdXNwZW5zZS5pc0luRmFsbGJhY2sgPSBmYWxzZTsNCiAgICAgIGxldCBwYXJlbnQgPSBzdXNwZW5zZS5wYXJlbnQ7DQogICAgICBsZXQgaGFzVW5yZXNvbHZlZEFuY2VzdG9yID0gZmFsc2U7DQogICAgICB3aGlsZSAocGFyZW50KSB7DQogICAgICAgIGlmIChwYXJlbnQucGVuZGluZ0JyYW5jaCkgew0KICAgICAgICAgIHBhcmVudC5lZmZlY3RzLnB1c2goLi4uZWZmZWN0cyk7DQogICAgICAgICAgaGFzVW5yZXNvbHZlZEFuY2VzdG9yID0gdHJ1ZTsNCiAgICAgICAgICBicmVhazsNCiAgICAgICAgfQ0KICAgICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50Ow0KICAgICAgfQ0KICAgICAgaWYgKCFoYXNVbnJlc29sdmVkQW5jZXN0b3IgJiYgIWRlbGF5RW50ZXIpIHsNCiAgICAgICAgcXVldWVQb3N0Rmx1c2hDYihlZmZlY3RzKTsNCiAgICAgIH0NCiAgICAgIHN1c3BlbnNlLmVmZmVjdHMgPSBbXTsNCiAgICAgIGlmIChpc1N1c3BlbnNpYmxlKSB7DQogICAgICAgIGlmIChwYXJlbnRTdXNwZW5zZSAmJiBwYXJlbnRTdXNwZW5zZS5wZW5kaW5nQnJhbmNoICYmIHBhcmVudFN1c3BlbnNlSWQgPT09IHBhcmVudFN1c3BlbnNlLnBlbmRpbmdJZCkgew0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlLmRlcHMtLTsNCiAgICAgICAgICBpZiAocGFyZW50U3VzcGVuc2UuZGVwcyA9PT0gMCAmJiAhc3luYykgew0KICAgICAgICAgICAgcGFyZW50U3VzcGVuc2UucmVzb2x2ZSgpOw0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgdHJpZ2dlckV2ZW50KHZub2RlMiwgIm9uUmVzb2x2ZSIpOw0KICAgIH0sDQogICAgZmFsbGJhY2soZmFsbGJhY2tWTm9kZSkgew0KICAgICAgaWYgKCFzdXNwZW5zZS5wZW5kaW5nQnJhbmNoKSB7DQogICAgICAgIHJldHVybjsNCiAgICAgIH0NCiAgICAgIGNvbnN0IHsgdm5vZGU6IHZub2RlMiwgYWN0aXZlQnJhbmNoLCBwYXJlbnRDb21wb25lbnQ6IHBhcmVudENvbXBvbmVudDIsIGNvbnRhaW5lcjogY29udGFpbmVyMiwgbmFtZXNwYWNlOiBuYW1lc3BhY2UyIH0gPSBzdXNwZW5zZTsNCiAgICAgIHRyaWdnZXJFdmVudCh2bm9kZTIsICJvbkZhbGxiYWNrIik7DQogICAgICBjb25zdCBhbmNob3IyID0gbmV4dChhY3RpdmVCcmFuY2gpOw0KICAgICAgY29uc3QgbW91bnRGYWxsYmFjayA9ICgpID0+IHsNCiAgICAgICAgaWYgKCFzdXNwZW5zZS5pc0luRmFsbGJhY2spIHsNCiAgICAgICAgICByZXR1cm47DQogICAgICAgIH0NCiAgICAgICAgcGF0Y2goDQogICAgICAgICAgbnVsbCwNCiAgICAgICAgICBmYWxsYmFja1ZOb2RlLA0KICAgICAgICAgIGNvbnRhaW5lcjIsDQogICAgICAgICAgYW5jaG9yMiwNCiAgICAgICAgICBwYXJlbnRDb21wb25lbnQyLA0KICAgICAgICAgIG51bGwsDQogICAgICAgICAgLy8gZmFsbGJhY2sgdHJlZSB3aWxsIG5vdCBoYXZlIHN1c3BlbnNlIGNvbnRleHQNCiAgICAgICAgICBuYW1lc3BhY2UyLA0KICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgKTsNCiAgICAgICAgc2V0QWN0aXZlQnJhbmNoKHN1c3BlbnNlLCBmYWxsYmFja1ZOb2RlKTsNCiAgICAgIH07DQogICAgICBjb25zdCBkZWxheUVudGVyID0gZmFsbGJhY2tWTm9kZS50cmFuc2l0aW9uICYmIGZhbGxiYWNrVk5vZGUudHJhbnNpdGlvbi5tb2RlID09PSAib3V0LWluIjsNCiAgICAgIGlmIChkZWxheUVudGVyKSB7DQogICAgICAgIGFjdGl2ZUJyYW5jaC50cmFuc2l0aW9uLmFmdGVyTGVhdmUgPSBtb3VudEZhbGxiYWNrOw0KICAgICAgfQ0KICAgICAgc3VzcGVuc2UuaXNJbkZhbGxiYWNrID0gdHJ1ZTsNCiAgICAgIHVubW91bnQoDQogICAgICAgIGFjdGl2ZUJyYW5jaCwNCiAgICAgICAgcGFyZW50Q29tcG9uZW50MiwNCiAgICAgICAgbnVsbCwNCiAgICAgICAgLy8gbm8gc3VzcGVuc2Ugc28gdW5tb3VudCBob29rcyBmaXJlIG5vdw0KICAgICAgICB0cnVlDQogICAgICAgIC8vIHNob3VsZFJlbW92ZQ0KICAgICAgKTsNCiAgICAgIGlmICghZGVsYXlFbnRlcikgew0KICAgICAgICBtb3VudEZhbGxiYWNrKCk7DQogICAgICB9DQogICAgfSwNCiAgICBtb3ZlKGNvbnRhaW5lcjIsIGFuY2hvcjIsIHR5cGUpIHsNCiAgICAgIHN1c3BlbnNlLmFjdGl2ZUJyYW5jaCAmJiBtb3ZlKHN1c3BlbnNlLmFjdGl2ZUJyYW5jaCwgY29udGFpbmVyMiwgYW5jaG9yMiwgdHlwZSk7DQogICAgICBzdXNwZW5zZS5jb250YWluZXIgPSBjb250YWluZXIyOw0KICAgIH0sDQogICAgbmV4dCgpIHsNCiAgICAgIHJldHVybiBzdXNwZW5zZS5hY3RpdmVCcmFuY2ggJiYgbmV4dChzdXNwZW5zZS5hY3RpdmVCcmFuY2gpOw0KICAgIH0sDQogICAgcmVnaXN0ZXJEZXAoaW5zdGFuY2UsIHNldHVwUmVuZGVyRWZmZWN0LCBvcHRpbWl6ZWQyKSB7DQogICAgICBjb25zdCBpc0luUGVuZGluZ1N1c3BlbnNlID0gISFzdXNwZW5zZS5wZW5kaW5nQnJhbmNoOw0KICAgICAgaWYgKGlzSW5QZW5kaW5nU3VzcGVuc2UpIHsNCiAgICAgICAgc3VzcGVuc2UuZGVwcysrOw0KICAgICAgfQ0KICAgICAgY29uc3QgaHlkcmF0ZWRFbCA9IGluc3RhbmNlLnZub2RlLmVsOw0KICAgICAgaW5zdGFuY2UuYXN5bmNEZXAuY2F0Y2goKGVycikgPT4gew0KICAgICAgICBoYW5kbGVFcnJvcihlcnIsIGluc3RhbmNlLCAwKTsNCiAgICAgIH0pLnRoZW4oKGFzeW5jU2V0dXBSZXN1bHQpID0+IHsNCiAgICAgICAgaWYgKGluc3RhbmNlLmlzVW5tb3VudGVkIHx8IHN1c3BlbnNlLmlzVW5tb3VudGVkIHx8IHN1c3BlbnNlLnBlbmRpbmdJZCAhPT0gaW5zdGFuY2Uuc3VzcGVuc2VJZCkgew0KICAgICAgICAgIHJldHVybjsNCiAgICAgICAgfQ0KICAgICAgICBpbnN0YW5jZS5hc3luY1Jlc29sdmVkID0gdHJ1ZTsNCiAgICAgICAgY29uc3QgeyB2bm9kZTogdm5vZGUyIH0gPSBpbnN0YW5jZTsNCiAgICAgICAgew0KICAgICAgICAgIHB1c2hXYXJuaW5nQ29udGV4dCh2bm9kZTIpOw0KICAgICAgICB9DQogICAgICAgIGhhbmRsZVNldHVwUmVzdWx0KGluc3RhbmNlLCBhc3luY1NldHVwUmVzdWx0LCBmYWxzZSk7DQogICAgICAgIGlmIChoeWRyYXRlZEVsKSB7DQogICAgICAgICAgdm5vZGUyLmVsID0gaHlkcmF0ZWRFbDsNCiAgICAgICAgfQ0KICAgICAgICBjb25zdCBwbGFjZWhvbGRlciA9ICFoeWRyYXRlZEVsICYmIGluc3RhbmNlLnN1YlRyZWUuZWw7DQogICAgICAgIHNldHVwUmVuZGVyRWZmZWN0KA0KICAgICAgICAgIGluc3RhbmNlLA0KICAgICAgICAgIHZub2RlMiwNCiAgICAgICAgICAvLyBjb21wb25lbnQgbWF5IGhhdmUgYmVlbiBtb3ZlZCBiZWZvcmUgcmVzb2x2ZS4NCiAgICAgICAgICAvLyBpZiB0aGlzIGlzIG5vdCBhIGh5ZHJhdGlvbiwgaW5zdGFuY2Uuc3ViVHJlZSB3aWxsIGJlIHRoZSBjb21tZW50DQogICAgICAgICAgLy8gcGxhY2Vob2xkZXIuDQogICAgICAgICAgcGFyZW50Tm9kZShoeWRyYXRlZEVsIHx8IGluc3RhbmNlLnN1YlRyZWUuZWwpLA0KICAgICAgICAgIC8vIGFuY2hvciB3aWxsIG5vdCBiZSB1c2VkIGlmIHRoaXMgaXMgaHlkcmF0aW9uLCBzbyBvbmx5IG5lZWQgdG8NCiAgICAgICAgICAvLyBjb25zaWRlciB0aGUgY29tbWVudCBwbGFjZWhvbGRlciBjYXNlLg0KICAgICAgICAgIGh5ZHJhdGVkRWwgPyBudWxsIDogbmV4dChpbnN0YW5jZS5zdWJUcmVlKSwNCiAgICAgICAgICBzdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgb3B0aW1pemVkMg0KICAgICAgICApOw0KICAgICAgICBpZiAocGxhY2Vob2xkZXIpIHsNCiAgICAgICAgICByZW1vdmUocGxhY2Vob2xkZXIpOw0KICAgICAgICB9DQogICAgICAgIHVwZGF0ZUhPQ0hvc3RFbChpbnN0YW5jZSwgdm5vZGUyLmVsKTsNCiAgICAgICAgew0KICAgICAgICAgIHBvcFdhcm5pbmdDb250ZXh0KCk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKGlzSW5QZW5kaW5nU3VzcGVuc2UgJiYgLS1zdXNwZW5zZS5kZXBzID09PSAwKSB7DQogICAgICAgICAgc3VzcGVuc2UucmVzb2x2ZSgpOw0KICAgICAgICB9DQogICAgICB9KTsNCiAgICB9LA0KICAgIHVubW91bnQocGFyZW50U3VzcGVuc2UyLCBkb1JlbW92ZSkgew0KICAgICAgc3VzcGVuc2UuaXNVbm1vdW50ZWQgPSB0cnVlOw0KICAgICAgaWYgKHN1c3BlbnNlLmFjdGl2ZUJyYW5jaCkgew0KICAgICAgICB1bm1vdW50KA0KICAgICAgICAgIHN1c3BlbnNlLmFjdGl2ZUJyYW5jaCwNCiAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgcGFyZW50U3VzcGVuc2UyLA0KICAgICAgICAgIGRvUmVtb3ZlDQogICAgICAgICk7DQogICAgICB9DQogICAgICBpZiAoc3VzcGVuc2UucGVuZGluZ0JyYW5jaCkgew0KICAgICAgICB1bm1vdW50KA0KICAgICAgICAgIHN1c3BlbnNlLnBlbmRpbmdCcmFuY2gsDQogICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlMiwNCiAgICAgICAgICBkb1JlbW92ZQ0KICAgICAgICApOw0KICAgICAgfQ0KICAgIH0NCiAgfTsNCiAgcmV0dXJuIHN1c3BlbnNlOw0KfQ0KZnVuY3Rpb24gaHlkcmF0ZVN1c3BlbnNlKG5vZGUsIHZub2RlLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBuYW1lc3BhY2UsIHNsb3RTY29wZUlkcywgb3B0aW1pemVkLCByZW5kZXJlckludGVybmFscywgaHlkcmF0ZU5vZGUpIHsNCiAgY29uc3Qgc3VzcGVuc2UgPSB2bm9kZS5zdXNwZW5zZSA9IGNyZWF0ZVN1c3BlbnNlQm91bmRhcnkoDQogICAgdm5vZGUsDQogICAgcGFyZW50U3VzcGVuc2UsDQogICAgcGFyZW50Q29tcG9uZW50LA0KICAgIG5vZGUucGFyZW50Tm9kZSwNCiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1nbG9iYWxzDQogICAgZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2IiksDQogICAgbnVsbCwNCiAgICBuYW1lc3BhY2UsDQogICAgc2xvdFNjb3BlSWRzLA0KICAgIG9wdGltaXplZCwNCiAgICByZW5kZXJlckludGVybmFscywNCiAgICB0cnVlDQogICk7DQogIGNvbnN0IHJlc3VsdCA9IGh5ZHJhdGVOb2RlKA0KICAgIG5vZGUsDQogICAgc3VzcGVuc2UucGVuZGluZ0JyYW5jaCA9IHZub2RlLnNzQ29udGVudCwNCiAgICBwYXJlbnRDb21wb25lbnQsDQogICAgc3VzcGVuc2UsDQogICAgc2xvdFNjb3BlSWRzLA0KICAgIG9wdGltaXplZA0KICApOw0KICBpZiAoc3VzcGVuc2UuZGVwcyA9PT0gMCkgew0KICAgIHN1c3BlbnNlLnJlc29sdmUoZmFsc2UsIHRydWUpOw0KICB9DQogIHJldHVybiByZXN1bHQ7DQp9DQpmdW5jdGlvbiBub3JtYWxpemVTdXNwZW5zZUNoaWxkcmVuKHZub2RlKSB7DQogIGNvbnN0IHsgc2hhcGVGbGFnLCBjaGlsZHJlbiB9ID0gdm5vZGU7DQogIGNvbnN0IGlzU2xvdENoaWxkcmVuID0gc2hhcGVGbGFnICYgMzI7DQogIHZub2RlLnNzQ29udGVudCA9IG5vcm1hbGl6ZVN1c3BlbnNlU2xvdCgNCiAgICBpc1Nsb3RDaGlsZHJlbiA/IGNoaWxkcmVuLmRlZmF1bHQgOiBjaGlsZHJlbg0KICApOw0KICB2bm9kZS5zc0ZhbGxiYWNrID0gaXNTbG90Q2hpbGRyZW4gPyBub3JtYWxpemVTdXNwZW5zZVNsb3QoY2hpbGRyZW4uZmFsbGJhY2spIDogY3JlYXRlVk5vZGUoQ29tbWVudCk7DQp9DQpmdW5jdGlvbiBub3JtYWxpemVTdXNwZW5zZVNsb3Qocykgew0KICBsZXQgYmxvY2s7DQogIGlmIChpc0Z1bmN0aW9uKHMpKSB7DQogICAgY29uc3QgdHJhY2tCbG9jayA9IGlzQmxvY2tUcmVlRW5hYmxlZCAmJiBzLl9jOw0KICAgIGlmICh0cmFja0Jsb2NrKSB7DQogICAgICBzLl9kID0gZmFsc2U7DQogICAgICBvcGVuQmxvY2soKTsNCiAgICB9DQogICAgcyA9IHMoKTsNCiAgICBpZiAodHJhY2tCbG9jaykgew0KICAgICAgcy5fZCA9IHRydWU7DQogICAgICBibG9jayA9IGN1cnJlbnRCbG9jazsNCiAgICAgIGNsb3NlQmxvY2soKTsNCiAgICB9DQogIH0NCiAgaWYgKGlzQXJyYXkocykpIHsNCiAgICBjb25zdCBzaW5nbGVDaGlsZCA9IGZpbHRlclNpbmdsZVJvb3Qocyk7DQogICAgaWYgKCFzaW5nbGVDaGlsZCAmJiBzLmZpbHRlcigoY2hpbGQpID0+IGNoaWxkICE9PSBOVUxMX0RZTkFNSUNfQ09NUE9ORU5UKS5sZW5ndGggPiAwKSB7DQogICAgICB3YXJuJDEoYDxTdXNwZW5zZT4gc2xvdHMgZXhwZWN0IGEgc2luZ2xlIHJvb3Qgbm9kZS5gKTsNCiAgICB9DQogICAgcyA9IHNpbmdsZUNoaWxkOw0KICB9DQogIHMgPSBub3JtYWxpemVWTm9kZShzKTsNCiAgaWYgKGJsb2NrICYmICFzLmR5bmFtaWNDaGlsZHJlbikgew0KICAgIHMuZHluYW1pY0NoaWxkcmVuID0gYmxvY2suZmlsdGVyKChjKSA9PiBjICE9PSBzKTsNCiAgfQ0KICByZXR1cm4gczsNCn0NCmZ1bmN0aW9uIHF1ZXVlRWZmZWN0V2l0aFN1c3BlbnNlKGZuLCBzdXNwZW5zZSkgew0KICBpZiAoc3VzcGVuc2UgJiYgc3VzcGVuc2UucGVuZGluZ0JyYW5jaCkgew0KICAgIGlmIChpc0FycmF5KGZuKSkgew0KICAgICAgc3VzcGVuc2UuZWZmZWN0cy5wdXNoKC4uLmZuKTsNCiAgICB9IGVsc2Ugew0KICAgICAgc3VzcGVuc2UuZWZmZWN0cy5wdXNoKGZuKTsNCiAgICB9DQogIH0gZWxzZSB7DQogICAgcXVldWVQb3N0Rmx1c2hDYihmbik7DQogIH0NCn0NCmZ1bmN0aW9uIHNldEFjdGl2ZUJyYW5jaChzdXNwZW5zZSwgYnJhbmNoKSB7DQogIHN1c3BlbnNlLmFjdGl2ZUJyYW5jaCA9IGJyYW5jaDsNCiAgY29uc3QgeyB2bm9kZSwgcGFyZW50Q29tcG9uZW50IH0gPSBzdXNwZW5zZTsNCiAgbGV0IGVsID0gYnJhbmNoLmVsOw0KICB3aGlsZSAoIWVsICYmIGJyYW5jaC5jb21wb25lbnQpIHsNCiAgICBicmFuY2ggPSBicmFuY2guY29tcG9uZW50LnN1YlRyZWU7DQogICAgZWwgPSBicmFuY2guZWw7DQogIH0NCiAgdm5vZGUuZWwgPSBlbDsNCiAgaWYgKHBhcmVudENvbXBvbmVudCAmJiBwYXJlbnRDb21wb25lbnQuc3ViVHJlZSA9PT0gdm5vZGUpIHsNCiAgICBwYXJlbnRDb21wb25lbnQudm5vZGUuZWwgPSBlbDsNCiAgICB1cGRhdGVIT0NIb3N0RWwocGFyZW50Q29tcG9uZW50LCBlbCk7DQogIH0NCn0NCmZ1bmN0aW9uIGlzVk5vZGVTdXNwZW5zaWJsZSh2bm9kZSkgew0KICBjb25zdCBzdXNwZW5zaWJsZSA9IHZub2RlLnByb3BzICYmIHZub2RlLnByb3BzLnN1c3BlbnNpYmxlOw0KICByZXR1cm4gc3VzcGVuc2libGUgIT0gbnVsbCAmJiBzdXNwZW5zaWJsZSAhPT0gZmFsc2U7DQp9DQoNCmNvbnN0IEZyYWdtZW50ID0gU3ltYm9sLmZvcigidi1mZ3QiKTsNCmNvbnN0IFRleHQgPSBTeW1ib2wuZm9yKCJ2LXR4dCIpOw0KY29uc3QgQ29tbWVudCA9IFN5bWJvbC5mb3IoInYtY210Iik7DQpjb25zdCBTdGF0aWMgPSBTeW1ib2wuZm9yKCJ2LXN0YyIpOw0KY29uc3QgYmxvY2tTdGFjayA9IFtdOw0KbGV0IGN1cnJlbnRCbG9jayA9IG51bGw7DQpmdW5jdGlvbiBvcGVuQmxvY2soZGlzYWJsZVRyYWNraW5nID0gZmFsc2UpIHsNCiAgYmxvY2tTdGFjay5wdXNoKGN1cnJlbnRCbG9jayA9IGRpc2FibGVUcmFja2luZyA/IG51bGwgOiBbXSk7DQp9DQpmdW5jdGlvbiBjbG9zZUJsb2NrKCkgew0KICBibG9ja1N0YWNrLnBvcCgpOw0KICBjdXJyZW50QmxvY2sgPSBibG9ja1N0YWNrW2Jsb2NrU3RhY2subGVuZ3RoIC0gMV0gfHwgbnVsbDsNCn0NCmxldCBpc0Jsb2NrVHJlZUVuYWJsZWQgPSAxOw0KZnVuY3Rpb24gc2V0QmxvY2tUcmFja2luZyh2YWx1ZSwgaW5WT25jZSA9IGZhbHNlKSB7DQogIGlzQmxvY2tUcmVlRW5hYmxlZCArPSB2YWx1ZTsNCiAgaWYgKHZhbHVlIDwgMCAmJiBjdXJyZW50QmxvY2sgJiYgaW5WT25jZSkgew0KICAgIGN1cnJlbnRCbG9jay5oYXNPbmNlID0gdHJ1ZTsNCiAgfQ0KfQ0KZnVuY3Rpb24gc2V0dXBCbG9jayh2bm9kZSkgew0KICB2bm9kZS5keW5hbWljQ2hpbGRyZW4gPSBpc0Jsb2NrVHJlZUVuYWJsZWQgPiAwID8gY3VycmVudEJsb2NrIHx8IEVNUFRZX0FSUiA6IG51bGw7DQogIGNsb3NlQmxvY2soKTsNCiAgaWYgKGlzQmxvY2tUcmVlRW5hYmxlZCA+IDAgJiYgY3VycmVudEJsb2NrKSB7DQogICAgY3VycmVudEJsb2NrLnB1c2godm5vZGUpOw0KICB9DQogIHJldHVybiB2bm9kZTsNCn0NCmZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnRCbG9jayh0eXBlLCBwcm9wcywgY2hpbGRyZW4sIHBhdGNoRmxhZywgZHluYW1pY1Byb3BzLCBzaGFwZUZsYWcpIHsNCiAgcmV0dXJuIHNldHVwQmxvY2soDQogICAgY3JlYXRlQmFzZVZOb2RlKA0KICAgICAgdHlwZSwNCiAgICAgIHByb3BzLA0KICAgICAgY2hpbGRyZW4sDQogICAgICBwYXRjaEZsYWcsDQogICAgICBkeW5hbWljUHJvcHMsDQogICAgICBzaGFwZUZsYWcsDQogICAgICB0cnVlDQogICAgKQ0KICApOw0KfQ0KZnVuY3Rpb24gY3JlYXRlQmxvY2sodHlwZSwgcHJvcHMsIGNoaWxkcmVuLCBwYXRjaEZsYWcsIGR5bmFtaWNQcm9wcykgew0KICByZXR1cm4gc2V0dXBCbG9jaygNCiAgICBjcmVhdGVWTm9kZSgNCiAgICAgIHR5cGUsDQogICAgICBwcm9wcywNCiAgICAgIGNoaWxkcmVuLA0KICAgICAgcGF0Y2hGbGFnLA0KICAgICAgZHluYW1pY1Byb3BzLA0KICAgICAgdHJ1ZQ0KICAgICkNCiAgKTsNCn0NCmZ1bmN0aW9uIGlzVk5vZGUodmFsdWUpIHsNCiAgcmV0dXJuIHZhbHVlID8gdmFsdWUuX192X2lzVk5vZGUgPT09IHRydWUgOiBmYWxzZTsNCn0NCmZ1bmN0aW9uIGlzU2FtZVZOb2RlVHlwZShuMSwgbjIpIHsNCiAgaWYgKG4yLnNoYXBlRmxhZyAmIDYgJiYgbjEuY29tcG9uZW50KSB7DQogICAgY29uc3QgZGlydHlJbnN0YW5jZXMgPSBobXJEaXJ0eUNvbXBvbmVudHMuZ2V0KG4yLnR5cGUpOw0KICAgIGlmIChkaXJ0eUluc3RhbmNlcyAmJiBkaXJ0eUluc3RhbmNlcy5oYXMobjEuY29tcG9uZW50KSkgew0KICAgICAgbjEuc2hhcGVGbGFnICY9IC0yNTc7DQogICAgICBuMi5zaGFwZUZsYWcgJj0gLTUxMzsNCiAgICAgIHJldHVybiBmYWxzZTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIG4xLnR5cGUgPT09IG4yLnR5cGUgJiYgbjEua2V5ID09PSBuMi5rZXk7DQp9DQpsZXQgdm5vZGVBcmdzVHJhbnNmb3JtZXI7DQpmdW5jdGlvbiB0cmFuc2Zvcm1WTm9kZUFyZ3ModHJhbnNmb3JtZXIpIHsNCiAgdm5vZGVBcmdzVHJhbnNmb3JtZXIgPSB0cmFuc2Zvcm1lcjsNCn0NCmNvbnN0IGNyZWF0ZVZOb2RlV2l0aEFyZ3NUcmFuc2Zvcm0gPSAoLi4uYXJncykgPT4gew0KICByZXR1cm4gX2NyZWF0ZVZOb2RlKA0KICAgIC4uLnZub2RlQXJnc1RyYW5zZm9ybWVyID8gdm5vZGVBcmdzVHJhbnNmb3JtZXIoYXJncywgY3VycmVudFJlbmRlcmluZ0luc3RhbmNlKSA6IGFyZ3MNCiAgKTsNCn07DQpjb25zdCBub3JtYWxpemVLZXkgPSAoeyBrZXkgfSkgPT4ga2V5ICE9IG51bGwgPyBrZXkgOiBudWxsOw0KY29uc3Qgbm9ybWFsaXplUmVmID0gKHsNCiAgcmVmLA0KICByZWZfa2V5LA0KICByZWZfZm9yDQp9KSA9PiB7DQogIGlmICh0eXBlb2YgcmVmID09PSAibnVtYmVyIikgew0KICAgIHJlZiA9ICIiICsgcmVmOw0KICB9DQogIHJldHVybiByZWYgIT0gbnVsbCA/IGlzU3RyaW5nKHJlZikgfHwgaXNSZWYocmVmKSB8fCBpc0Z1bmN0aW9uKHJlZikgPyB7IGk6IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSwgcjogcmVmLCBrOiByZWZfa2V5LCBmOiAhIXJlZl9mb3IgfSA6IHJlZiA6IG51bGw7DQp9Ow0KZnVuY3Rpb24gY3JlYXRlQmFzZVZOb2RlKHR5cGUsIHByb3BzID0gbnVsbCwgY2hpbGRyZW4gPSBudWxsLCBwYXRjaEZsYWcgPSAwLCBkeW5hbWljUHJvcHMgPSBudWxsLCBzaGFwZUZsYWcgPSB0eXBlID09PSBGcmFnbWVudCA/IDAgOiAxLCBpc0Jsb2NrTm9kZSA9IGZhbHNlLCBuZWVkRnVsbENoaWxkcmVuTm9ybWFsaXphdGlvbiA9IGZhbHNlKSB7DQogIGNvbnN0IHZub2RlID0gew0KICAgIF9fdl9pc1ZOb2RlOiB0cnVlLA0KICAgIF9fdl9za2lwOiB0cnVlLA0KICAgIHR5cGUsDQogICAgcHJvcHMsDQogICAga2V5OiBwcm9wcyAmJiBub3JtYWxpemVLZXkocHJvcHMpLA0KICAgIHJlZjogcHJvcHMgJiYgbm9ybWFsaXplUmVmKHByb3BzKSwNCiAgICBzY29wZUlkOiBjdXJyZW50U2NvcGVJZCwNCiAgICBzbG90U2NvcGVJZHM6IG51bGwsDQogICAgY2hpbGRyZW4sDQogICAgY29tcG9uZW50OiBudWxsLA0KICAgIHN1c3BlbnNlOiBudWxsLA0KICAgIHNzQ29udGVudDogbnVsbCwNCiAgICBzc0ZhbGxiYWNrOiBudWxsLA0KICAgIGRpcnM6IG51bGwsDQogICAgdHJhbnNpdGlvbjogbnVsbCwNCiAgICBlbDogbnVsbCwNCiAgICBhbmNob3I6IG51bGwsDQogICAgdGFyZ2V0OiBudWxsLA0KICAgIHRhcmdldFN0YXJ0OiBudWxsLA0KICAgIHRhcmdldEFuY2hvcjogbnVsbCwNCiAgICBzdGF0aWNDb3VudDogMCwNCiAgICBzaGFwZUZsYWcsDQogICAgcGF0Y2hGbGFnLA0KICAgIGR5bmFtaWNQcm9wcywNCiAgICBkeW5hbWljQ2hpbGRyZW46IG51bGwsDQogICAgYXBwQ29udGV4dDogbnVsbCwNCiAgICBjdHg6IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZQ0KICB9Ow0KICBpZiAobmVlZEZ1bGxDaGlsZHJlbk5vcm1hbGl6YXRpb24pIHsNCiAgICBub3JtYWxpemVDaGlsZHJlbih2bm9kZSwgY2hpbGRyZW4pOw0KICAgIGlmIChzaGFwZUZsYWcgJiAxMjgpIHsNCiAgICAgIHR5cGUubm9ybWFsaXplKHZub2RlKTsNCiAgICB9DQogIH0gZWxzZSBpZiAoY2hpbGRyZW4pIHsNCiAgICB2bm9kZS5zaGFwZUZsYWcgfD0gaXNTdHJpbmcoY2hpbGRyZW4pID8gOCA6IDE2Ow0KICB9DQogIGlmICh2bm9kZS5rZXkgIT09IHZub2RlLmtleSkgew0KICAgIHdhcm4kMShgVk5vZGUgY3JlYXRlZCB3aXRoIGludmFsaWQga2V5IChOYU4pLiBWTm9kZSB0eXBlOmAsIHZub2RlLnR5cGUpOw0KICB9DQogIGlmIChpc0Jsb2NrVHJlZUVuYWJsZWQgPiAwICYmIC8vIGF2b2lkIGEgYmxvY2sgbm9kZSBmcm9tIHRyYWNraW5nIGl0c2VsZg0KICAhaXNCbG9ja05vZGUgJiYgLy8gaGFzIGN1cnJlbnQgcGFyZW50IGJsb2NrDQogIGN1cnJlbnRCbG9jayAmJiAvLyBwcmVzZW5jZSBvZiBhIHBhdGNoIGZsYWcgaW5kaWNhdGVzIHRoaXMgbm9kZSBuZWVkcyBwYXRjaGluZyBvbiB1cGRhdGVzLg0KICAvLyBjb21wb25lbnQgbm9kZXMgYWxzbyBzaG91bGQgYWx3YXlzIGJlIHBhdGNoZWQsIGJlY2F1c2UgZXZlbiBpZiB0aGUNCiAgLy8gY29tcG9uZW50IGRvZXNuJ3QgbmVlZCB0byB1cGRhdGUsIGl0IG5lZWRzIHRvIHBlcnNpc3QgdGhlIGluc3RhbmNlIG9uIHRvDQogIC8vIHRoZSBuZXh0IHZub2RlIHNvIHRoYXQgaXQgY2FuIGJlIHByb3Blcmx5IHVubW91bnRlZCBsYXRlci4NCiAgKHZub2RlLnBhdGNoRmxhZyA+IDAgfHwgc2hhcGVGbGFnICYgNikgJiYgLy8gdGhlIEVWRU5UUyBmbGFnIGlzIG9ubHkgZm9yIGh5ZHJhdGlvbiBhbmQgaWYgaXQgaXMgdGhlIG9ubHkgZmxhZywgdGhlDQogIC8vIHZub2RlIHNob3VsZCBub3QgYmUgY29uc2lkZXJlZCBkeW5hbWljIGR1ZSB0byBoYW5kbGVyIGNhY2hpbmcuDQogIHZub2RlLnBhdGNoRmxhZyAhPT0gMzIpIHsNCiAgICBjdXJyZW50QmxvY2sucHVzaCh2bm9kZSk7DQogIH0NCiAgcmV0dXJuIHZub2RlOw0KfQ0KY29uc3QgY3JlYXRlVk5vZGUgPSBjcmVhdGVWTm9kZVdpdGhBcmdzVHJhbnNmb3JtIDsNCmZ1bmN0aW9uIF9jcmVhdGVWTm9kZSh0eXBlLCBwcm9wcyA9IG51bGwsIGNoaWxkcmVuID0gbnVsbCwgcGF0Y2hGbGFnID0gMCwgZHluYW1pY1Byb3BzID0gbnVsbCwgaXNCbG9ja05vZGUgPSBmYWxzZSkgew0KICBpZiAoIXR5cGUgfHwgdHlwZSA9PT0gTlVMTF9EWU5BTUlDX0NPTVBPTkVOVCkgew0KICAgIGlmICghdHlwZSkgew0KICAgICAgd2FybiQxKGBJbnZhbGlkIHZub2RlIHR5cGUgd2hlbiBjcmVhdGluZyB2bm9kZTogJHt0eXBlfS5gKTsNCiAgICB9DQogICAgdHlwZSA9IENvbW1lbnQ7DQogIH0NCiAgaWYgKGlzVk5vZGUodHlwZSkpIHsNCiAgICBjb25zdCBjbG9uZWQgPSBjbG9uZVZOb2RlKA0KICAgICAgdHlwZSwNCiAgICAgIHByb3BzLA0KICAgICAgdHJ1ZQ0KICAgICAgLyogbWVyZ2VSZWY6IHRydWUgKi8NCiAgICApOw0KICAgIGlmIChjaGlsZHJlbikgew0KICAgICAgbm9ybWFsaXplQ2hpbGRyZW4oY2xvbmVkLCBjaGlsZHJlbik7DQogICAgfQ0KICAgIGlmIChpc0Jsb2NrVHJlZUVuYWJsZWQgPiAwICYmICFpc0Jsb2NrTm9kZSAmJiBjdXJyZW50QmxvY2spIHsNCiAgICAgIGlmIChjbG9uZWQuc2hhcGVGbGFnICYgNikgew0KICAgICAgICBjdXJyZW50QmxvY2tbY3VycmVudEJsb2NrLmluZGV4T2YodHlwZSldID0gY2xvbmVkOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgY3VycmVudEJsb2NrLnB1c2goY2xvbmVkKTsNCiAgICAgIH0NCiAgICB9DQogICAgY2xvbmVkLnBhdGNoRmxhZyA9IC0yOw0KICAgIHJldHVybiBjbG9uZWQ7DQogIH0NCiAgaWYgKGlzQ2xhc3NDb21wb25lbnQodHlwZSkpIHsNCiAgICB0eXBlID0gdHlwZS5fX3ZjY09wdHM7DQogIH0NCiAgaWYgKHByb3BzKSB7DQogICAgcHJvcHMgPSBndWFyZFJlYWN0aXZlUHJvcHMocHJvcHMpOw0KICAgIGxldCB7IGNsYXNzOiBrbGFzcywgc3R5bGUgfSA9IHByb3BzOw0KICAgIGlmIChrbGFzcyAmJiAhaXNTdHJpbmcoa2xhc3MpKSB7DQogICAgICBwcm9wcy5jbGFzcyA9IG5vcm1hbGl6ZUNsYXNzKGtsYXNzKTsNCiAgICB9DQogICAgaWYgKGlzT2JqZWN0KHN0eWxlKSkgew0KICAgICAgaWYgKGlzUHJveHkoc3R5bGUpICYmICFpc0FycmF5KHN0eWxlKSkgew0KICAgICAgICBzdHlsZSA9IGV4dGVuZCh7fSwgc3R5bGUpOw0KICAgICAgfQ0KICAgICAgcHJvcHMuc3R5bGUgPSBub3JtYWxpemVTdHlsZShzdHlsZSk7DQogICAgfQ0KICB9DQogIGNvbnN0IHNoYXBlRmxhZyA9IGlzU3RyaW5nKHR5cGUpID8gMSA6IGlzU3VzcGVuc2UodHlwZSkgPyAxMjggOiBpc1RlbGVwb3J0KHR5cGUpID8gNjQgOiBpc09iamVjdCh0eXBlKSA/IDQgOiBpc0Z1bmN0aW9uKHR5cGUpID8gMiA6IDA7DQogIGlmIChzaGFwZUZsYWcgJiA0ICYmIGlzUHJveHkodHlwZSkpIHsNCiAgICB0eXBlID0gdG9SYXcodHlwZSk7DQogICAgd2FybiQxKA0KICAgICAgYFZ1ZSByZWNlaXZlZCBhIENvbXBvbmVudCB0aGF0IHdhcyBtYWRlIGEgcmVhY3RpdmUgb2JqZWN0LiBUaGlzIGNhbiBsZWFkIHRvIHVubmVjZXNzYXJ5IHBlcmZvcm1hbmNlIG92ZXJoZWFkIGFuZCBzaG91bGQgYmUgYXZvaWRlZCBieSBtYXJraW5nIHRoZSBjb21wb25lbnQgd2l0aCBcYG1hcmtSYXdcYCBvciB1c2luZyBcYHNoYWxsb3dSZWZcYCBpbnN0ZWFkIG9mIFxgcmVmXGAuYCwNCiAgICAgIGANCkNvbXBvbmVudCB0aGF0IHdhcyBtYWRlIHJlYWN0aXZlOiBgLA0KICAgICAgdHlwZQ0KICAgICk7DQogIH0NCiAgcmV0dXJuIGNyZWF0ZUJhc2VWTm9kZSgNCiAgICB0eXBlLA0KICAgIHByb3BzLA0KICAgIGNoaWxkcmVuLA0KICAgIHBhdGNoRmxhZywNCiAgICBkeW5hbWljUHJvcHMsDQogICAgc2hhcGVGbGFnLA0KICAgIGlzQmxvY2tOb2RlLA0KICAgIHRydWUNCiAgKTsNCn0NCmZ1bmN0aW9uIGd1YXJkUmVhY3RpdmVQcm9wcyhwcm9wcykgew0KICBpZiAoIXByb3BzKSByZXR1cm4gbnVsbDsNCiAgcmV0dXJuIGlzUHJveHkocHJvcHMpIHx8IGlzSW50ZXJuYWxPYmplY3QocHJvcHMpID8gZXh0ZW5kKHt9LCBwcm9wcykgOiBwcm9wczsNCn0NCmZ1bmN0aW9uIGNsb25lVk5vZGUodm5vZGUsIGV4dHJhUHJvcHMsIG1lcmdlUmVmID0gZmFsc2UsIGNsb25lVHJhbnNpdGlvbiA9IGZhbHNlKSB7DQogIGNvbnN0IHsgcHJvcHMsIHJlZiwgcGF0Y2hGbGFnLCBjaGlsZHJlbiwgdHJhbnNpdGlvbiB9ID0gdm5vZGU7DQogIGNvbnN0IG1lcmdlZFByb3BzID0gZXh0cmFQcm9wcyA/IG1lcmdlUHJvcHMocHJvcHMgfHwge30sIGV4dHJhUHJvcHMpIDogcHJvcHM7DQogIGNvbnN0IGNsb25lZCA9IHsNCiAgICBfX3ZfaXNWTm9kZTogdHJ1ZSwNCiAgICBfX3Zfc2tpcDogdHJ1ZSwNCiAgICB0eXBlOiB2bm9kZS50eXBlLA0KICAgIHByb3BzOiBtZXJnZWRQcm9wcywNCiAgICBrZXk6IG1lcmdlZFByb3BzICYmIG5vcm1hbGl6ZUtleShtZXJnZWRQcm9wcyksDQogICAgcmVmOiBleHRyYVByb3BzICYmIGV4dHJhUHJvcHMucmVmID8gKA0KICAgICAgLy8gIzIwNzggaW4gdGhlIGNhc2Ugb2YgPGNvbXBvbmVudCA6aXM9InZub2RlIiByZWY9ImV4dHJhIi8+DQogICAgICAvLyBpZiB0aGUgdm5vZGUgaXRzZWxmIGFscmVhZHkgaGFzIGEgcmVmLCBjbG9uZVZOb2RlIHdpbGwgbmVlZCB0byBtZXJnZQ0KICAgICAgLy8gdGhlIHJlZnMgc28gdGhlIHNpbmdsZSB2bm9kZSBjYW4gYmUgc2V0IG9uIG11bHRpcGxlIHJlZnMNCiAgICAgIG1lcmdlUmVmICYmIHJlZiA/IGlzQXJyYXkocmVmKSA/IHJlZi5jb25jYXQobm9ybWFsaXplUmVmKGV4dHJhUHJvcHMpKSA6IFtyZWYsIG5vcm1hbGl6ZVJlZihleHRyYVByb3BzKV0gOiBub3JtYWxpemVSZWYoZXh0cmFQcm9wcykNCiAgICApIDogcmVmLA0KICAgIHNjb3BlSWQ6IHZub2RlLnNjb3BlSWQsDQogICAgc2xvdFNjb3BlSWRzOiB2bm9kZS5zbG90U2NvcGVJZHMsDQogICAgY2hpbGRyZW46IHBhdGNoRmxhZyA9PT0gLTEgJiYgaXNBcnJheShjaGlsZHJlbikgPyBjaGlsZHJlbi5tYXAoZGVlcENsb25lVk5vZGUpIDogY2hpbGRyZW4sDQogICAgdGFyZ2V0OiB2bm9kZS50YXJnZXQsDQogICAgdGFyZ2V0U3RhcnQ6IHZub2RlLnRhcmdldFN0YXJ0LA0KICAgIHRhcmdldEFuY2hvcjogdm5vZGUudGFyZ2V0QW5jaG9yLA0KICAgIHN0YXRpY0NvdW50OiB2bm9kZS5zdGF0aWNDb3VudCwNCiAgICBzaGFwZUZsYWc6IHZub2RlLnNoYXBlRmxhZywNCiAgICAvLyBpZiB0aGUgdm5vZGUgaXMgY2xvbmVkIHdpdGggZXh0cmEgcHJvcHMsIHdlIGNhbiBubyBsb25nZXIgYXNzdW1lIGl0cw0KICAgIC8vIGV4aXN0aW5nIHBhdGNoIGZsYWcgdG8gYmUgcmVsaWFibGUgYW5kIG5lZWQgdG8gYWRkIHRoZSBGVUxMX1BST1BTIGZsYWcuDQogICAgLy8gbm90ZTogcHJlc2VydmUgZmxhZyBmb3IgZnJhZ21lbnRzIHNpbmNlIHRoZXkgdXNlIHRoZSBmbGFnIGZvciBjaGlsZHJlbg0KICAgIC8vIGZhc3QgcGF0aHMgb25seS4NCiAgICBwYXRjaEZsYWc6IGV4dHJhUHJvcHMgJiYgdm5vZGUudHlwZSAhPT0gRnJhZ21lbnQgPyBwYXRjaEZsYWcgPT09IC0xID8gMTYgOiBwYXRjaEZsYWcgfCAxNiA6IHBhdGNoRmxhZywNCiAgICBkeW5hbWljUHJvcHM6IHZub2RlLmR5bmFtaWNQcm9wcywNCiAgICBkeW5hbWljQ2hpbGRyZW46IHZub2RlLmR5bmFtaWNDaGlsZHJlbiwNCiAgICBhcHBDb250ZXh0OiB2bm9kZS5hcHBDb250ZXh0LA0KICAgIGRpcnM6IHZub2RlLmRpcnMsDQogICAgdHJhbnNpdGlvbiwNCiAgICAvLyBUaGVzZSBzaG91bGQgdGVjaG5pY2FsbHkgb25seSBiZSBub24tbnVsbCBvbiBtb3VudGVkIFZOb2Rlcy4gSG93ZXZlciwNCiAgICAvLyB0aGV5ICpzaG91bGQqIGJlIGNvcGllZCBmb3Iga2VwdC1hbGl2ZSB2bm9kZXMuIFNvIHdlIGp1c3QgYWx3YXlzIGNvcHkNCiAgICAvLyB0aGVtIHNpbmNlIHRoZW0gYmVpbmcgbm9uLW51bGwgZHVyaW5nIGEgbW91bnQgZG9lc24ndCBhZmZlY3QgdGhlIGxvZ2ljIGFzDQogICAgLy8gdGhleSB3aWxsIHNpbXBseSBiZSBvdmVyd3JpdHRlbi4NCiAgICBjb21wb25lbnQ6IHZub2RlLmNvbXBvbmVudCwNCiAgICBzdXNwZW5zZTogdm5vZGUuc3VzcGVuc2UsDQogICAgc3NDb250ZW50OiB2bm9kZS5zc0NvbnRlbnQgJiYgY2xvbmVWTm9kZSh2bm9kZS5zc0NvbnRlbnQpLA0KICAgIHNzRmFsbGJhY2s6IHZub2RlLnNzRmFsbGJhY2sgJiYgY2xvbmVWTm9kZSh2bm9kZS5zc0ZhbGxiYWNrKSwNCiAgICBlbDogdm5vZGUuZWwsDQogICAgYW5jaG9yOiB2bm9kZS5hbmNob3IsDQogICAgY3R4OiB2bm9kZS5jdHgsDQogICAgY2U6IHZub2RlLmNlDQogIH07DQogIGlmICh0cmFuc2l0aW9uICYmIGNsb25lVHJhbnNpdGlvbikgew0KICAgIHNldFRyYW5zaXRpb25Ib29rcygNCiAgICAgIGNsb25lZCwNCiAgICAgIHRyYW5zaXRpb24uY2xvbmUoY2xvbmVkKQ0KICAgICk7DQogIH0NCiAgcmV0dXJuIGNsb25lZDsNCn0NCmZ1bmN0aW9uIGRlZXBDbG9uZVZOb2RlKHZub2RlKSB7DQogIGNvbnN0IGNsb25lZCA9IGNsb25lVk5vZGUodm5vZGUpOw0KICBpZiAoaXNBcnJheSh2bm9kZS5jaGlsZHJlbikpIHsNCiAgICBjbG9uZWQuY2hpbGRyZW4gPSB2bm9kZS5jaGlsZHJlbi5tYXAoZGVlcENsb25lVk5vZGUpOw0KICB9DQogIHJldHVybiBjbG9uZWQ7DQp9DQpmdW5jdGlvbiBjcmVhdGVUZXh0Vk5vZGUodGV4dCA9ICIgIiwgZmxhZyA9IDApIHsNCiAgcmV0dXJuIGNyZWF0ZVZOb2RlKFRleHQsIG51bGwsIHRleHQsIGZsYWcpOw0KfQ0KZnVuY3Rpb24gY3JlYXRlU3RhdGljVk5vZGUoY29udGVudCwgbnVtYmVyT2ZOb2Rlcykgew0KICBjb25zdCB2bm9kZSA9IGNyZWF0ZVZOb2RlKFN0YXRpYywgbnVsbCwgY29udGVudCk7DQogIHZub2RlLnN0YXRpY0NvdW50ID0gbnVtYmVyT2ZOb2RlczsNCiAgcmV0dXJuIHZub2RlOw0KfQ0KZnVuY3Rpb24gY3JlYXRlQ29tbWVudFZOb2RlKHRleHQgPSAiIiwgYXNCbG9jayA9IGZhbHNlKSB7DQogIHJldHVybiBhc0Jsb2NrID8gKG9wZW5CbG9jaygpLCBjcmVhdGVCbG9jayhDb21tZW50LCBudWxsLCB0ZXh0KSkgOiBjcmVhdGVWTm9kZShDb21tZW50LCBudWxsLCB0ZXh0KTsNCn0NCmZ1bmN0aW9uIG5vcm1hbGl6ZVZOb2RlKGNoaWxkKSB7DQogIGlmIChjaGlsZCA9PSBudWxsIHx8IHR5cGVvZiBjaGlsZCA9PT0gImJvb2xlYW4iKSB7DQogICAgcmV0dXJuIGNyZWF0ZVZOb2RlKENvbW1lbnQpOw0KICB9IGVsc2UgaWYgKGlzQXJyYXkoY2hpbGQpKSB7DQogICAgcmV0dXJuIGNyZWF0ZVZOb2RlKA0KICAgICAgRnJhZ21lbnQsDQogICAgICBudWxsLA0KICAgICAgLy8gIzM2NjYsIGF2b2lkIHJlZmVyZW5jZSBwb2xsdXRpb24gd2hlbiByZXVzaW5nIHZub2RlDQogICAgICBjaGlsZC5zbGljZSgpDQogICAgKTsNCiAgfSBlbHNlIGlmIChpc1ZOb2RlKGNoaWxkKSkgew0KICAgIHJldHVybiBjbG9uZUlmTW91bnRlZChjaGlsZCk7DQogIH0gZWxzZSB7DQogICAgcmV0dXJuIGNyZWF0ZVZOb2RlKFRleHQsIG51bGwsIFN0cmluZyhjaGlsZCkpOw0KICB9DQp9DQpmdW5jdGlvbiBjbG9uZUlmTW91bnRlZChjaGlsZCkgew0KICByZXR1cm4gY2hpbGQuZWwgPT09IG51bGwgJiYgY2hpbGQucGF0Y2hGbGFnICE9PSAtMSB8fCBjaGlsZC5tZW1vID8gY2hpbGQgOiBjbG9uZVZOb2RlKGNoaWxkKTsNCn0NCmZ1bmN0aW9uIG5vcm1hbGl6ZUNoaWxkcmVuKHZub2RlLCBjaGlsZHJlbikgew0KICBsZXQgdHlwZSA9IDA7DQogIGNvbnN0IHsgc2hhcGVGbGFnIH0gPSB2bm9kZTsNCiAgaWYgKGNoaWxkcmVuID09IG51bGwpIHsNCiAgICBjaGlsZHJlbiA9IG51bGw7DQogIH0gZWxzZSBpZiAoaXNBcnJheShjaGlsZHJlbikpIHsNCiAgICB0eXBlID0gMTY7DQogIH0gZWxzZSBpZiAodHlwZW9mIGNoaWxkcmVuID09PSAib2JqZWN0Iikgew0KICAgIGlmIChzaGFwZUZsYWcgJiAoMSB8IDY0KSkgew0KICAgICAgY29uc3Qgc2xvdCA9IGNoaWxkcmVuLmRlZmF1bHQ7DQogICAgICBpZiAoc2xvdCkgew0KICAgICAgICBzbG90Ll9jICYmIChzbG90Ll9kID0gZmFsc2UpOw0KICAgICAgICBub3JtYWxpemVDaGlsZHJlbih2bm9kZSwgc2xvdCgpKTsNCiAgICAgICAgc2xvdC5fYyAmJiAoc2xvdC5fZCA9IHRydWUpOw0KICAgICAgfQ0KICAgICAgcmV0dXJuOw0KICAgIH0gZWxzZSB7DQogICAgICB0eXBlID0gMzI7DQogICAgICBjb25zdCBzbG90RmxhZyA9IGNoaWxkcmVuLl87DQogICAgICBpZiAoIXNsb3RGbGFnICYmICFpc0ludGVybmFsT2JqZWN0KGNoaWxkcmVuKSkgew0KICAgICAgICBjaGlsZHJlbi5fY3R4ID0gY3VycmVudFJlbmRlcmluZ0luc3RhbmNlOw0KICAgICAgfSBlbHNlIGlmIChzbG90RmxhZyA9PT0gMyAmJiBjdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UpIHsNCiAgICAgICAgaWYgKGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZS5zbG90cy5fID09PSAxKSB7DQogICAgICAgICAgY2hpbGRyZW4uXyA9IDE7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgY2hpbGRyZW4uXyA9IDI7DQogICAgICAgICAgdm5vZGUucGF0Y2hGbGFnIHw9IDEwMjQ7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH0gZWxzZSBpZiAoaXNGdW5jdGlvbihjaGlsZHJlbikpIHsNCiAgICBjaGlsZHJlbiA9IHsgZGVmYXVsdDogY2hpbGRyZW4sIF9jdHg6IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSB9Ow0KICAgIHR5cGUgPSAzMjsNCiAgfSBlbHNlIHsNCiAgICBjaGlsZHJlbiA9IFN0cmluZyhjaGlsZHJlbik7DQogICAgaWYgKHNoYXBlRmxhZyAmIDY0KSB7DQogICAgICB0eXBlID0gMTY7DQogICAgICBjaGlsZHJlbiA9IFtjcmVhdGVUZXh0Vk5vZGUoY2hpbGRyZW4pXTsNCiAgICB9IGVsc2Ugew0KICAgICAgdHlwZSA9IDg7DQogICAgfQ0KICB9DQogIHZub2RlLmNoaWxkcmVuID0gY2hpbGRyZW47DQogIHZub2RlLnNoYXBlRmxhZyB8PSB0eXBlOw0KfQ0KZnVuY3Rpb24gbWVyZ2VQcm9wcyguLi5hcmdzKSB7DQogIGNvbnN0IHJldCA9IHt9Ow0KICBmb3IgKGxldCBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHsNCiAgICBjb25zdCB0b01lcmdlID0gYXJnc1tpXTsNCiAgICBmb3IgKGNvbnN0IGtleSBpbiB0b01lcmdlKSB7DQogICAgICBpZiAoa2V5ID09PSAiY2xhc3MiKSB7DQogICAgICAgIGlmIChyZXQuY2xhc3MgIT09IHRvTWVyZ2UuY2xhc3MpIHsNCiAgICAgICAgICByZXQuY2xhc3MgPSBub3JtYWxpemVDbGFzcyhbcmV0LmNsYXNzLCB0b01lcmdlLmNsYXNzXSk7DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSBpZiAoa2V5ID09PSAic3R5bGUiKSB7DQogICAgICAgIHJldC5zdHlsZSA9IG5vcm1hbGl6ZVN0eWxlKFtyZXQuc3R5bGUsIHRvTWVyZ2Uuc3R5bGVdKTsNCiAgICAgIH0gZWxzZSBpZiAoaXNPbihrZXkpKSB7DQogICAgICAgIGNvbnN0IGV4aXN0aW5nID0gcmV0W2tleV07DQogICAgICAgIGNvbnN0IGluY29taW5nID0gdG9NZXJnZVtrZXldOw0KICAgICAgICBpZiAoaW5jb21pbmcgJiYgZXhpc3RpbmcgIT09IGluY29taW5nICYmICEoaXNBcnJheShleGlzdGluZykgJiYgZXhpc3RpbmcuaW5jbHVkZXMoaW5jb21pbmcpKSkgew0KICAgICAgICAgIHJldFtrZXldID0gZXhpc3RpbmcgPyBbXS5jb25jYXQoZXhpc3RpbmcsIGluY29taW5nKSA6IGluY29taW5nOw0KICAgICAgICB9DQogICAgICB9IGVsc2UgaWYgKGtleSAhPT0gIiIpIHsNCiAgICAgICAgcmV0W2tleV0gPSB0b01lcmdlW2tleV07DQogICAgICB9DQogICAgfQ0KICB9DQogIHJldHVybiByZXQ7DQp9DQpmdW5jdGlvbiBpbnZva2VWTm9kZUhvb2soaG9vaywgaW5zdGFuY2UsIHZub2RlLCBwcmV2Vk5vZGUgPSBudWxsKSB7DQogIGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nKGhvb2ssIGluc3RhbmNlLCA3LCBbDQogICAgdm5vZGUsDQogICAgcHJldlZOb2RlDQogIF0pOw0KfQ0KDQpjb25zdCBlbXB0eUFwcENvbnRleHQgPSBjcmVhdGVBcHBDb250ZXh0KCk7DQpsZXQgdWlkID0gMDsNCmZ1bmN0aW9uIGNyZWF0ZUNvbXBvbmVudEluc3RhbmNlKHZub2RlLCBwYXJlbnQsIHN1c3BlbnNlKSB7DQogIGNvbnN0IHR5cGUgPSB2bm9kZS50eXBlOw0KICBjb25zdCBhcHBDb250ZXh0ID0gKHBhcmVudCA/IHBhcmVudC5hcHBDb250ZXh0IDogdm5vZGUuYXBwQ29udGV4dCkgfHwgZW1wdHlBcHBDb250ZXh0Ow0KICBjb25zdCBpbnN0YW5jZSA9IHsNCiAgICB1aWQ6IHVpZCsrLA0KICAgIHZub2RlLA0KICAgIHR5cGUsDQogICAgcGFyZW50LA0KICAgIGFwcENvbnRleHQsDQogICAgcm9vdDogbnVsbCwNCiAgICAvLyB0byBiZSBpbW1lZGlhdGVseSBzZXQNCiAgICBuZXh0OiBudWxsLA0KICAgIHN1YlRyZWU6IG51bGwsDQogICAgLy8gd2lsbCBiZSBzZXQgc3luY2hyb25vdXNseSByaWdodCBhZnRlciBjcmVhdGlvbg0KICAgIGVmZmVjdDogbnVsbCwNCiAgICB1cGRhdGU6IG51bGwsDQogICAgLy8gd2lsbCBiZSBzZXQgc3luY2hyb25vdXNseSByaWdodCBhZnRlciBjcmVhdGlvbg0KICAgIGpvYjogbnVsbCwNCiAgICBzY29wZTogbmV3IEVmZmVjdFNjb3BlKA0KICAgICAgdHJ1ZQ0KICAgICAgLyogZGV0YWNoZWQgKi8NCiAgICApLA0KICAgIHJlbmRlcjogbnVsbCwNCiAgICBwcm94eTogbnVsbCwNCiAgICBleHBvc2VkOiBudWxsLA0KICAgIGV4cG9zZVByb3h5OiBudWxsLA0KICAgIHdpdGhQcm94eTogbnVsbCwNCiAgICBwcm92aWRlczogcGFyZW50ID8gcGFyZW50LnByb3ZpZGVzIDogT2JqZWN0LmNyZWF0ZShhcHBDb250ZXh0LnByb3ZpZGVzKSwNCiAgICBpZHM6IHBhcmVudCA/IHBhcmVudC5pZHMgOiBbIiIsIDAsIDBdLA0KICAgIGFjY2Vzc0NhY2hlOiBudWxsLA0KICAgIHJlbmRlckNhY2hlOiBbXSwNCiAgICAvLyBsb2NhbCByZXNvbHZlZCBhc3NldHMNCiAgICBjb21wb25lbnRzOiBudWxsLA0KICAgIGRpcmVjdGl2ZXM6IG51bGwsDQogICAgLy8gcmVzb2x2ZWQgcHJvcHMgYW5kIGVtaXRzIG9wdGlvbnMNCiAgICBwcm9wc09wdGlvbnM6IG5vcm1hbGl6ZVByb3BzT3B0aW9ucyh0eXBlLCBhcHBDb250ZXh0KSwNCiAgICBlbWl0c09wdGlvbnM6IG5vcm1hbGl6ZUVtaXRzT3B0aW9ucyh0eXBlLCBhcHBDb250ZXh0KSwNCiAgICAvLyBlbWl0DQogICAgZW1pdDogbnVsbCwNCiAgICAvLyB0byBiZSBzZXQgaW1tZWRpYXRlbHkNCiAgICBlbWl0dGVkOiBudWxsLA0KICAgIC8vIHByb3BzIGRlZmF1bHQgdmFsdWUNCiAgICBwcm9wc0RlZmF1bHRzOiBFTVBUWV9PQkosDQogICAgLy8gaW5oZXJpdEF0dHJzDQogICAgaW5oZXJpdEF0dHJzOiB0eXBlLmluaGVyaXRBdHRycywNCiAgICAvLyBzdGF0ZQ0KICAgIGN0eDogRU1QVFlfT0JKLA0KICAgIGRhdGE6IEVNUFRZX09CSiwNCiAgICBwcm9wczogRU1QVFlfT0JKLA0KICAgIGF0dHJzOiBFTVBUWV9PQkosDQogICAgc2xvdHM6IEVNUFRZX09CSiwNCiAgICByZWZzOiBFTVBUWV9PQkosDQogICAgc2V0dXBTdGF0ZTogRU1QVFlfT0JKLA0KICAgIHNldHVwQ29udGV4dDogbnVsbCwNCiAgICAvLyBzdXNwZW5zZSByZWxhdGVkDQogICAgc3VzcGVuc2UsDQogICAgc3VzcGVuc2VJZDogc3VzcGVuc2UgPyBzdXNwZW5zZS5wZW5kaW5nSWQgOiAwLA0KICAgIGFzeW5jRGVwOiBudWxsLA0KICAgIGFzeW5jUmVzb2x2ZWQ6IGZhbHNlLA0KICAgIC8vIGxpZmVjeWNsZSBob29rcw0KICAgIC8vIG5vdCB1c2luZyBlbnVtcyBoZXJlIGJlY2F1c2UgaXQgcmVzdWx0cyBpbiBjb21wdXRlZCBwcm9wZXJ0aWVzDQogICAgaXNNb3VudGVkOiBmYWxzZSwNCiAgICBpc1VubW91bnRlZDogZmFsc2UsDQogICAgaXNEZWFjdGl2YXRlZDogZmFsc2UsDQogICAgYmM6IG51bGwsDQogICAgYzogbnVsbCwNCiAgICBibTogbnVsbCwNCiAgICBtOiBudWxsLA0KICAgIGJ1OiBudWxsLA0KICAgIHU6IG51bGwsDQogICAgdW06IG51bGwsDQogICAgYnVtOiBudWxsLA0KICAgIGRhOiBudWxsLA0KICAgIGE6IG51bGwsDQogICAgcnRnOiBudWxsLA0KICAgIHJ0YzogbnVsbCwNCiAgICBlYzogbnVsbCwNCiAgICBzcDogbnVsbA0KICB9Ow0KICB7DQogICAgaW5zdGFuY2UuY3R4ID0gY3JlYXRlRGV2UmVuZGVyQ29udGV4dChpbnN0YW5jZSk7DQogIH0NCiAgaW5zdGFuY2Uucm9vdCA9IHBhcmVudCA/IHBhcmVudC5yb290IDogaW5zdGFuY2U7DQogIGluc3RhbmNlLmVtaXQgPSBlbWl0LmJpbmQobnVsbCwgaW5zdGFuY2UpOw0KICBpZiAodm5vZGUuY2UpIHsNCiAgICB2bm9kZS5jZShpbnN0YW5jZSk7DQogIH0NCiAgcmV0dXJuIGluc3RhbmNlOw0KfQ0KbGV0IGN1cnJlbnRJbnN0YW5jZSA9IG51bGw7DQpjb25zdCBnZXRDdXJyZW50SW5zdGFuY2UgPSAoKSA9PiBjdXJyZW50SW5zdGFuY2UgfHwgY3VycmVudFJlbmRlcmluZ0luc3RhbmNlOw0KbGV0IGludGVybmFsU2V0Q3VycmVudEluc3RhbmNlOw0KbGV0IHNldEluU1NSU2V0dXBTdGF0ZTsNCnsNCiAgY29uc3QgZyA9IGdldEdsb2JhbFRoaXMoKTsNCiAgY29uc3QgcmVnaXN0ZXJHbG9iYWxTZXR0ZXIgPSAoa2V5LCBzZXR0ZXIpID0+IHsNCiAgICBsZXQgc2V0dGVyczsNCiAgICBpZiAoIShzZXR0ZXJzID0gZ1trZXldKSkgc2V0dGVycyA9IGdba2V5XSA9IFtdOw0KICAgIHNldHRlcnMucHVzaChzZXR0ZXIpOw0KICAgIHJldHVybiAodikgPT4gew0KICAgICAgaWYgKHNldHRlcnMubGVuZ3RoID4gMSkgc2V0dGVycy5mb3JFYWNoKChzZXQpID0+IHNldCh2KSk7DQogICAgICBlbHNlIHNldHRlcnNbMF0odik7DQogICAgfTsNCiAgfTsNCiAgaW50ZXJuYWxTZXRDdXJyZW50SW5zdGFuY2UgPSByZWdpc3Rlckdsb2JhbFNldHRlcigNCiAgICBgX19WVUVfSU5TVEFOQ0VfU0VUVEVSU19fYCwNCiAgICAodikgPT4gY3VycmVudEluc3RhbmNlID0gdg0KICApOw0KICBzZXRJblNTUlNldHVwU3RhdGUgPSByZWdpc3Rlckdsb2JhbFNldHRlcigNCiAgICBgX19WVUVfU1NSX1NFVFRFUlNfX2AsDQogICAgKHYpID0+IGlzSW5TU1JDb21wb25lbnRTZXR1cCA9IHYNCiAgKTsNCn0NCmNvbnN0IHNldEN1cnJlbnRJbnN0YW5jZSA9IChpbnN0YW5jZSkgPT4gew0KICBjb25zdCBwcmV2ID0gY3VycmVudEluc3RhbmNlOw0KICBpbnRlcm5hbFNldEN1cnJlbnRJbnN0YW5jZShpbnN0YW5jZSk7DQogIGluc3RhbmNlLnNjb3BlLm9uKCk7DQogIHJldHVybiAoKSA9PiB7DQogICAgaW5zdGFuY2Uuc2NvcGUub2ZmKCk7DQogICAgaW50ZXJuYWxTZXRDdXJyZW50SW5zdGFuY2UocHJldik7DQogIH07DQp9Ow0KY29uc3QgdW5zZXRDdXJyZW50SW5zdGFuY2UgPSAoKSA9PiB7DQogIGN1cnJlbnRJbnN0YW5jZSAmJiBjdXJyZW50SW5zdGFuY2Uuc2NvcGUub2ZmKCk7DQogIGludGVybmFsU2V0Q3VycmVudEluc3RhbmNlKG51bGwpOw0KfTsNCmNvbnN0IGlzQnVpbHRJblRhZyA9IC8qIEBfX1BVUkVfXyAqLyBtYWtlTWFwKCJzbG90LGNvbXBvbmVudCIpOw0KZnVuY3Rpb24gdmFsaWRhdGVDb21wb25lbnROYW1lKG5hbWUsIHsgaXNOYXRpdmVUYWcgfSkgew0KICBpZiAoaXNCdWlsdEluVGFnKG5hbWUpIHx8IGlzTmF0aXZlVGFnKG5hbWUpKSB7DQogICAgd2FybiQxKA0KICAgICAgIkRvIG5vdCB1c2UgYnVpbHQtaW4gb3IgcmVzZXJ2ZWQgSFRNTCBlbGVtZW50cyBhcyBjb21wb25lbnQgaWQ6ICIgKyBuYW1lDQogICAgKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gaXNTdGF0ZWZ1bENvbXBvbmVudChpbnN0YW5jZSkgew0KICByZXR1cm4gaW5zdGFuY2Uudm5vZGUuc2hhcGVGbGFnICYgNDsNCn0NCmxldCBpc0luU1NSQ29tcG9uZW50U2V0dXAgPSBmYWxzZTsNCmZ1bmN0aW9uIHNldHVwQ29tcG9uZW50KGluc3RhbmNlLCBpc1NTUiA9IGZhbHNlLCBvcHRpbWl6ZWQgPSBmYWxzZSkgew0KICBpc1NTUiAmJiBzZXRJblNTUlNldHVwU3RhdGUoaXNTU1IpOw0KICBjb25zdCB7IHByb3BzLCBjaGlsZHJlbiB9ID0gaW5zdGFuY2Uudm5vZGU7DQogIGNvbnN0IGlzU3RhdGVmdWwgPSBpc1N0YXRlZnVsQ29tcG9uZW50KGluc3RhbmNlKTsNCiAgaW5pdFByb3BzKGluc3RhbmNlLCBwcm9wcywgaXNTdGF0ZWZ1bCwgaXNTU1IpOw0KICBpbml0U2xvdHMoaW5zdGFuY2UsIGNoaWxkcmVuLCBvcHRpbWl6ZWQgfHwgaXNTU1IpOw0KICBjb25zdCBzZXR1cFJlc3VsdCA9IGlzU3RhdGVmdWwgPyBzZXR1cFN0YXRlZnVsQ29tcG9uZW50KGluc3RhbmNlLCBpc1NTUikgOiB2b2lkIDA7DQogIGlzU1NSICYmIHNldEluU1NSU2V0dXBTdGF0ZShmYWxzZSk7DQogIHJldHVybiBzZXR1cFJlc3VsdDsNCn0NCmZ1bmN0aW9uIHNldHVwU3RhdGVmdWxDb21wb25lbnQoaW5zdGFuY2UsIGlzU1NSKSB7DQogIHZhciBfYTsNCiAgY29uc3QgQ29tcG9uZW50ID0gaW5zdGFuY2UudHlwZTsNCiAgew0KICAgIGlmIChDb21wb25lbnQubmFtZSkgew0KICAgICAgdmFsaWRhdGVDb21wb25lbnROYW1lKENvbXBvbmVudC5uYW1lLCBpbnN0YW5jZS5hcHBDb250ZXh0LmNvbmZpZyk7DQogICAgfQ0KICAgIGlmIChDb21wb25lbnQuY29tcG9uZW50cykgew0KICAgICAgY29uc3QgbmFtZXMgPSBPYmplY3Qua2V5cyhDb21wb25lbnQuY29tcG9uZW50cyk7DQogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5hbWVzLmxlbmd0aDsgaSsrKSB7DQogICAgICAgIHZhbGlkYXRlQ29tcG9uZW50TmFtZShuYW1lc1tpXSwgaW5zdGFuY2UuYXBwQ29udGV4dC5jb25maWcpOw0KICAgICAgfQ0KICAgIH0NCiAgICBpZiAoQ29tcG9uZW50LmRpcmVjdGl2ZXMpIHsNCiAgICAgIGNvbnN0IG5hbWVzID0gT2JqZWN0LmtleXMoQ29tcG9uZW50LmRpcmVjdGl2ZXMpOw0KICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuYW1lcy5sZW5ndGg7IGkrKykgew0KICAgICAgICB2YWxpZGF0ZURpcmVjdGl2ZU5hbWUobmFtZXNbaV0pOw0KICAgICAgfQ0KICAgIH0NCiAgICBpZiAoQ29tcG9uZW50LmNvbXBpbGVyT3B0aW9ucyAmJiBpc1J1bnRpbWVPbmx5KCkpIHsNCiAgICAgIHdhcm4kMSgNCiAgICAgICAgYCJjb21waWxlck9wdGlvbnMiIGlzIG9ubHkgc3VwcG9ydGVkIHdoZW4gdXNpbmcgYSBidWlsZCBvZiBWdWUgdGhhdCBpbmNsdWRlcyB0aGUgcnVudGltZSBjb21waWxlci4gU2luY2UgeW91IGFyZSB1c2luZyBhIHJ1bnRpbWUtb25seSBidWlsZCwgdGhlIG9wdGlvbnMgc2hvdWxkIGJlIHBhc3NlZCB2aWEgeW91ciBidWlsZCB0b29sIGNvbmZpZyBpbnN0ZWFkLmANCiAgICAgICk7DQogICAgfQ0KICB9DQogIGluc3RhbmNlLmFjY2Vzc0NhY2hlID0gLyogQF9fUFVSRV9fICovIE9iamVjdC5jcmVhdGUobnVsbCk7DQogIGluc3RhbmNlLnByb3h5ID0gbmV3IFByb3h5KGluc3RhbmNlLmN0eCwgUHVibGljSW5zdGFuY2VQcm94eUhhbmRsZXJzKTsNCiAgew0KICAgIGV4cG9zZVByb3BzT25SZW5kZXJDb250ZXh0KGluc3RhbmNlKTsNCiAgfQ0KICBjb25zdCB7IHNldHVwIH0gPSBDb21wb25lbnQ7DQogIGlmIChzZXR1cCkgew0KICAgIHBhdXNlVHJhY2tpbmcoKTsNCiAgICBjb25zdCBzZXR1cENvbnRleHQgPSBpbnN0YW5jZS5zZXR1cENvbnRleHQgPSBzZXR1cC5sZW5ndGggPiAxID8gY3JlYXRlU2V0dXBDb250ZXh0KGluc3RhbmNlKSA6IG51bGw7DQogICAgY29uc3QgcmVzZXQgPSBzZXRDdXJyZW50SW5zdGFuY2UoaW5zdGFuY2UpOw0KICAgIGNvbnN0IHNldHVwUmVzdWx0ID0gY2FsbFdpdGhFcnJvckhhbmRsaW5nKA0KICAgICAgc2V0dXAsDQogICAgICBpbnN0YW5jZSwNCiAgICAgIDAsDQogICAgICBbDQogICAgICAgIHNoYWxsb3dSZWFkb25seShpbnN0YW5jZS5wcm9wcykgLA0KICAgICAgICBzZXR1cENvbnRleHQNCiAgICAgIF0NCiAgICApOw0KICAgIGNvbnN0IGlzQXN5bmNTZXR1cCA9IGlzUHJvbWlzZShzZXR1cFJlc3VsdCk7DQogICAgcmVzZXRUcmFja2luZygpOw0KICAgIHJlc2V0KCk7DQogICAgaWYgKChpc0FzeW5jU2V0dXAgfHwgaW5zdGFuY2Uuc3ApICYmICFpc0FzeW5jV3JhcHBlcihpbnN0YW5jZSkpIHsNCiAgICAgIG1hcmtBc3luY0JvdW5kYXJ5KGluc3RhbmNlKTsNCiAgICB9DQogICAgaWYgKGlzQXN5bmNTZXR1cCkgew0KICAgICAgc2V0dXBSZXN1bHQudGhlbih1bnNldEN1cnJlbnRJbnN0YW5jZSwgdW5zZXRDdXJyZW50SW5zdGFuY2UpOw0KICAgICAgaWYgKGlzU1NSKSB7DQogICAgICAgIHJldHVybiBzZXR1cFJlc3VsdC50aGVuKChyZXNvbHZlZFJlc3VsdCkgPT4gew0KICAgICAgICAgIGhhbmRsZVNldHVwUmVzdWx0KGluc3RhbmNlLCByZXNvbHZlZFJlc3VsdCwgaXNTU1IpOw0KICAgICAgICB9KS5jYXRjaCgoZSkgPT4gew0KICAgICAgICAgIGhhbmRsZUVycm9yKGUsIGluc3RhbmNlLCAwKTsNCiAgICAgICAgfSk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBpbnN0YW5jZS5hc3luY0RlcCA9IHNldHVwUmVzdWx0Ow0KICAgICAgICBpZiAoIWluc3RhbmNlLnN1c3BlbnNlKSB7DQogICAgICAgICAgY29uc3QgbmFtZSA9IChfYSA9IENvbXBvbmVudC5uYW1lKSAhPSBudWxsID8gX2EgOiAiQW5vbnltb3VzIjsNCiAgICAgICAgICB3YXJuJDEoDQogICAgICAgICAgICBgQ29tcG9uZW50IDwke25hbWV9Pjogc2V0dXAgZnVuY3Rpb24gcmV0dXJuZWQgYSBwcm9taXNlLCBidXQgbm8gPFN1c3BlbnNlPiBib3VuZGFyeSB3YXMgZm91bmQgaW4gdGhlIHBhcmVudCBjb21wb25lbnQgdHJlZS4gQSBjb21wb25lbnQgd2l0aCBhc3luYyBzZXR1cCgpIG11c3QgYmUgbmVzdGVkIGluIGEgPFN1c3BlbnNlPiBpbiBvcmRlciB0byBiZSByZW5kZXJlZC5gDQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0gZWxzZSB7DQogICAgICBoYW5kbGVTZXR1cFJlc3VsdChpbnN0YW5jZSwgc2V0dXBSZXN1bHQsIGlzU1NSKTsNCiAgICB9DQogIH0gZWxzZSB7DQogICAgZmluaXNoQ29tcG9uZW50U2V0dXAoaW5zdGFuY2UsIGlzU1NSKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gaGFuZGxlU2V0dXBSZXN1bHQoaW5zdGFuY2UsIHNldHVwUmVzdWx0LCBpc1NTUikgew0KICBpZiAoaXNGdW5jdGlvbihzZXR1cFJlc3VsdCkpIHsNCiAgICBpZiAoaW5zdGFuY2UudHlwZS5fX3NzcklubGluZVJlbmRlcikgew0KICAgICAgaW5zdGFuY2Uuc3NyUmVuZGVyID0gc2V0dXBSZXN1bHQ7DQogICAgfSBlbHNlIHsNCiAgICAgIGluc3RhbmNlLnJlbmRlciA9IHNldHVwUmVzdWx0Ow0KICAgIH0NCiAgfSBlbHNlIGlmIChpc09iamVjdChzZXR1cFJlc3VsdCkpIHsNCiAgICBpZiAoaXNWTm9kZShzZXR1cFJlc3VsdCkpIHsNCiAgICAgIHdhcm4kMSgNCiAgICAgICAgYHNldHVwKCkgc2hvdWxkIG5vdCByZXR1cm4gVk5vZGVzIGRpcmVjdGx5IC0gcmV0dXJuIGEgcmVuZGVyIGZ1bmN0aW9uIGluc3RlYWQuYA0KICAgICAgKTsNCiAgICB9DQogICAgew0KICAgICAgaW5zdGFuY2UuZGV2dG9vbHNSYXdTZXR1cFN0YXRlID0gc2V0dXBSZXN1bHQ7DQogICAgfQ0KICAgIGluc3RhbmNlLnNldHVwU3RhdGUgPSBwcm94eVJlZnMoc2V0dXBSZXN1bHQpOw0KICAgIHsNCiAgICAgIGV4cG9zZVNldHVwU3RhdGVPblJlbmRlckNvbnRleHQoaW5zdGFuY2UpOw0KICAgIH0NCiAgfSBlbHNlIGlmIChzZXR1cFJlc3VsdCAhPT0gdm9pZCAwKSB7DQogICAgd2FybiQxKA0KICAgICAgYHNldHVwKCkgc2hvdWxkIHJldHVybiBhbiBvYmplY3QuIFJlY2VpdmVkOiAke3NldHVwUmVzdWx0ID09PSBudWxsID8gIm51bGwiIDogdHlwZW9mIHNldHVwUmVzdWx0fWANCiAgICApOw0KICB9DQogIGZpbmlzaENvbXBvbmVudFNldHVwKGluc3RhbmNlLCBpc1NTUik7DQp9DQpsZXQgY29tcGlsZTsNCmxldCBpbnN0YWxsV2l0aFByb3h5Ow0KZnVuY3Rpb24gcmVnaXN0ZXJSdW50aW1lQ29tcGlsZXIoX2NvbXBpbGUpIHsNCiAgY29tcGlsZSA9IF9jb21waWxlOw0KICBpbnN0YWxsV2l0aFByb3h5ID0gKGkpID0+IHsNCiAgICBpZiAoaS5yZW5kZXIuX3JjKSB7DQogICAgICBpLndpdGhQcm94eSA9IG5ldyBQcm94eShpLmN0eCwgUnVudGltZUNvbXBpbGVkUHVibGljSW5zdGFuY2VQcm94eUhhbmRsZXJzKTsNCiAgICB9DQogIH07DQp9DQpjb25zdCBpc1J1bnRpbWVPbmx5ID0gKCkgPT4gIWNvbXBpbGU7DQpmdW5jdGlvbiBmaW5pc2hDb21wb25lbnRTZXR1cChpbnN0YW5jZSwgaXNTU1IsIHNraXBPcHRpb25zKSB7DQogIGNvbnN0IENvbXBvbmVudCA9IGluc3RhbmNlLnR5cGU7DQogIGlmICghaW5zdGFuY2UucmVuZGVyKSB7DQogICAgaWYgKCFpc1NTUiAmJiBjb21waWxlICYmICFDb21wb25lbnQucmVuZGVyKSB7DQogICAgICBjb25zdCB0ZW1wbGF0ZSA9IENvbXBvbmVudC50ZW1wbGF0ZSB8fCByZXNvbHZlTWVyZ2VkT3B0aW9ucyhpbnN0YW5jZSkudGVtcGxhdGU7DQogICAgICBpZiAodGVtcGxhdGUpIHsNCiAgICAgICAgew0KICAgICAgICAgIHN0YXJ0TWVhc3VyZShpbnN0YW5jZSwgYGNvbXBpbGVgKTsNCiAgICAgICAgfQ0KICAgICAgICBjb25zdCB7IGlzQ3VzdG9tRWxlbWVudCwgY29tcGlsZXJPcHRpb25zIH0gPSBpbnN0YW5jZS5hcHBDb250ZXh0LmNvbmZpZzsNCiAgICAgICAgY29uc3QgeyBkZWxpbWl0ZXJzLCBjb21waWxlck9wdGlvbnM6IGNvbXBvbmVudENvbXBpbGVyT3B0aW9ucyB9ID0gQ29tcG9uZW50Ow0KICAgICAgICBjb25zdCBmaW5hbENvbXBpbGVyT3B0aW9ucyA9IGV4dGVuZCgNCiAgICAgICAgICBleHRlbmQoDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgIGlzQ3VzdG9tRWxlbWVudCwNCiAgICAgICAgICAgICAgZGVsaW1pdGVycw0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIGNvbXBpbGVyT3B0aW9ucw0KICAgICAgICAgICksDQogICAgICAgICAgY29tcG9uZW50Q29tcGlsZXJPcHRpb25zDQogICAgICAgICk7DQogICAgICAgIENvbXBvbmVudC5yZW5kZXIgPSBjb21waWxlKHRlbXBsYXRlLCBmaW5hbENvbXBpbGVyT3B0aW9ucyk7DQogICAgICAgIHsNCiAgICAgICAgICBlbmRNZWFzdXJlKGluc3RhbmNlLCBgY29tcGlsZWApOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICAgIGluc3RhbmNlLnJlbmRlciA9IENvbXBvbmVudC5yZW5kZXIgfHwgTk9PUDsNCiAgICBpZiAoaW5zdGFsbFdpdGhQcm94eSkgew0KICAgICAgaW5zdGFsbFdpdGhQcm94eShpbnN0YW5jZSk7DQogICAgfQ0KICB9DQogIHsNCiAgICBjb25zdCByZXNldCA9IHNldEN1cnJlbnRJbnN0YW5jZShpbnN0YW5jZSk7DQogICAgcGF1c2VUcmFja2luZygpOw0KICAgIHRyeSB7DQogICAgICBhcHBseU9wdGlvbnMoaW5zdGFuY2UpOw0KICAgIH0gZmluYWxseSB7DQogICAgICByZXNldFRyYWNraW5nKCk7DQogICAgICByZXNldCgpOw0KICAgIH0NCiAgfQ0KICBpZiAoIUNvbXBvbmVudC5yZW5kZXIgJiYgaW5zdGFuY2UucmVuZGVyID09PSBOT09QICYmICFpc1NTUikgew0KICAgIGlmICghY29tcGlsZSAmJiBDb21wb25lbnQudGVtcGxhdGUpIHsNCiAgICAgIHdhcm4kMSgNCiAgICAgICAgYENvbXBvbmVudCBwcm92aWRlZCB0ZW1wbGF0ZSBvcHRpb24gYnV0IHJ1bnRpbWUgY29tcGlsYXRpb24gaXMgbm90IHN1cHBvcnRlZCBpbiB0aGlzIGJ1aWxkIG9mIFZ1ZS5gICsgKGAgVXNlICJ2dWUuZXNtLWJyb3dzZXIuanMiIGluc3RlYWQuYCApDQogICAgICApOw0KICAgIH0gZWxzZSB7DQogICAgICB3YXJuJDEoYENvbXBvbmVudCBpcyBtaXNzaW5nIHRlbXBsYXRlIG9yIHJlbmRlciBmdW5jdGlvbjogYCwgQ29tcG9uZW50KTsNCiAgICB9DQogIH0NCn0NCmNvbnN0IGF0dHJzUHJveHlIYW5kbGVycyA9IHsNCiAgZ2V0KHRhcmdldCwga2V5KSB7DQogICAgbWFya0F0dHJzQWNjZXNzZWQoKTsNCiAgICB0cmFjayh0YXJnZXQsICJnZXQiLCAiIik7DQogICAgcmV0dXJuIHRhcmdldFtrZXldOw0KICB9LA0KICBzZXQoKSB7DQogICAgd2FybiQxKGBzZXR1cENvbnRleHQuYXR0cnMgaXMgcmVhZG9ubHkuYCk7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9LA0KICBkZWxldGVQcm9wZXJ0eSgpIHsNCiAgICB3YXJuJDEoYHNldHVwQ29udGV4dC5hdHRycyBpcyByZWFkb25seS5gKTsNCiAgICByZXR1cm4gZmFsc2U7DQogIH0NCn0gOw0KZnVuY3Rpb24gZ2V0U2xvdHNQcm94eShpbnN0YW5jZSkgew0KICByZXR1cm4gbmV3IFByb3h5KGluc3RhbmNlLnNsb3RzLCB7DQogICAgZ2V0KHRhcmdldCwga2V5KSB7DQogICAgICB0cmFjayhpbnN0YW5jZSwgImdldCIsICIkc2xvdHMiKTsNCiAgICAgIHJldHVybiB0YXJnZXRba2V5XTsNCiAgICB9DQogIH0pOw0KfQ0KZnVuY3Rpb24gY3JlYXRlU2V0dXBDb250ZXh0KGluc3RhbmNlKSB7DQogIGNvbnN0IGV4cG9zZSA9IChleHBvc2VkKSA9PiB7DQogICAgew0KICAgICAgaWYgKGluc3RhbmNlLmV4cG9zZWQpIHsNCiAgICAgICAgd2FybiQxKGBleHBvc2UoKSBzaG91bGQgYmUgY2FsbGVkIG9ubHkgb25jZSBwZXIgc2V0dXAoKS5gKTsNCiAgICAgIH0NCiAgICAgIGlmIChleHBvc2VkICE9IG51bGwpIHsNCiAgICAgICAgbGV0IGV4cG9zZWRUeXBlID0gdHlwZW9mIGV4cG9zZWQ7DQogICAgICAgIGlmIChleHBvc2VkVHlwZSA9PT0gIm9iamVjdCIpIHsNCiAgICAgICAgICBpZiAoaXNBcnJheShleHBvc2VkKSkgew0KICAgICAgICAgICAgZXhwb3NlZFR5cGUgPSAiYXJyYXkiOw0KICAgICAgICAgIH0gZWxzZSBpZiAoaXNSZWYoZXhwb3NlZCkpIHsNCiAgICAgICAgICAgIGV4cG9zZWRUeXBlID0gInJlZiI7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGlmIChleHBvc2VkVHlwZSAhPT0gIm9iamVjdCIpIHsNCiAgICAgICAgICB3YXJuJDEoDQogICAgICAgICAgICBgZXhwb3NlKCkgc2hvdWxkIGJlIHBhc3NlZCBhIHBsYWluIG9iamVjdCwgcmVjZWl2ZWQgJHtleHBvc2VkVHlwZX0uYA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogICAgaW5zdGFuY2UuZXhwb3NlZCA9IGV4cG9zZWQgfHwge307DQogIH07DQogIHsNCiAgICBsZXQgYXR0cnNQcm94eTsNCiAgICBsZXQgc2xvdHNQcm94eTsNCiAgICByZXR1cm4gT2JqZWN0LmZyZWV6ZSh7DQogICAgICBnZXQgYXR0cnMoKSB7DQogICAgICAgIHJldHVybiBhdHRyc1Byb3h5IHx8IChhdHRyc1Byb3h5ID0gbmV3IFByb3h5KGluc3RhbmNlLmF0dHJzLCBhdHRyc1Byb3h5SGFuZGxlcnMpKTsNCiAgICAgIH0sDQogICAgICBnZXQgc2xvdHMoKSB7DQogICAgICAgIHJldHVybiBzbG90c1Byb3h5IHx8IChzbG90c1Byb3h5ID0gZ2V0U2xvdHNQcm94eShpbnN0YW5jZSkpOw0KICAgICAgfSwNCiAgICAgIGdldCBlbWl0KCkgew0KICAgICAgICByZXR1cm4gKGV2ZW50LCAuLi5hcmdzKSA9PiBpbnN0YW5jZS5lbWl0KGV2ZW50LCAuLi5hcmdzKTsNCiAgICAgIH0sDQogICAgICBleHBvc2UNCiAgICB9KTsNCiAgfQ0KfQ0KZnVuY3Rpb24gZ2V0Q29tcG9uZW50UHVibGljSW5zdGFuY2UoaW5zdGFuY2UpIHsNCiAgaWYgKGluc3RhbmNlLmV4cG9zZWQpIHsNCiAgICByZXR1cm4gaW5zdGFuY2UuZXhwb3NlUHJveHkgfHwgKGluc3RhbmNlLmV4cG9zZVByb3h5ID0gbmV3IFByb3h5KHByb3h5UmVmcyhtYXJrUmF3KGluc3RhbmNlLmV4cG9zZWQpKSwgew0KICAgICAgZ2V0KHRhcmdldCwga2V5KSB7DQogICAgICAgIGlmIChrZXkgaW4gdGFyZ2V0KSB7DQogICAgICAgICAgcmV0dXJuIHRhcmdldFtrZXldOw0KICAgICAgICB9IGVsc2UgaWYgKGtleSBpbiBwdWJsaWNQcm9wZXJ0aWVzTWFwKSB7DQogICAgICAgICAgcmV0dXJuIHB1YmxpY1Byb3BlcnRpZXNNYXBba2V5XShpbnN0YW5jZSk7DQogICAgICAgIH0NCiAgICAgIH0sDQogICAgICBoYXModGFyZ2V0LCBrZXkpIHsNCiAgICAgICAgcmV0dXJuIGtleSBpbiB0YXJnZXQgfHwga2V5IGluIHB1YmxpY1Byb3BlcnRpZXNNYXA7DQogICAgICB9DQogICAgfSkpOw0KICB9IGVsc2Ugew0KICAgIHJldHVybiBpbnN0YW5jZS5wcm94eTsNCiAgfQ0KfQ0KY29uc3QgY2xhc3NpZnlSRSA9IC8oPzpefFstX10pKFx3KS9nOw0KY29uc3QgY2xhc3NpZnkgPSAoc3RyKSA9PiBzdHIucmVwbGFjZShjbGFzc2lmeVJFLCAoYykgPT4gYy50b1VwcGVyQ2FzZSgpKS5yZXBsYWNlKC9bLV9dL2csICIiKTsNCmZ1bmN0aW9uIGdldENvbXBvbmVudE5hbWUoQ29tcG9uZW50LCBpbmNsdWRlSW5mZXJyZWQgPSB0cnVlKSB7DQogIHJldHVybiBpc0Z1bmN0aW9uKENvbXBvbmVudCkgPyBDb21wb25lbnQuZGlzcGxheU5hbWUgfHwgQ29tcG9uZW50Lm5hbWUgOiBDb21wb25lbnQubmFtZSB8fCBpbmNsdWRlSW5mZXJyZWQgJiYgQ29tcG9uZW50Ll9fbmFtZTsNCn0NCmZ1bmN0aW9uIGZvcm1hdENvbXBvbmVudE5hbWUoaW5zdGFuY2UsIENvbXBvbmVudCwgaXNSb290ID0gZmFsc2UpIHsNCiAgbGV0IG5hbWUgPSBnZXRDb21wb25lbnROYW1lKENvbXBvbmVudCk7DQogIGlmICghbmFtZSAmJiBDb21wb25lbnQuX19maWxlKSB7DQogICAgY29uc3QgbWF0Y2ggPSBDb21wb25lbnQuX19maWxlLm1hdGNoKC8oW14vXFxdKylcLlx3KyQvKTsNCiAgICBpZiAobWF0Y2gpIHsNCiAgICAgIG5hbWUgPSBtYXRjaFsxXTsNCiAgICB9DQogIH0NCiAgaWYgKCFuYW1lICYmIGluc3RhbmNlICYmIGluc3RhbmNlLnBhcmVudCkgew0KICAgIGNvbnN0IGluZmVyRnJvbVJlZ2lzdHJ5ID0gKHJlZ2lzdHJ5KSA9PiB7DQogICAgICBmb3IgKGNvbnN0IGtleSBpbiByZWdpc3RyeSkgew0KICAgICAgICBpZiAocmVnaXN0cnlba2V5XSA9PT0gQ29tcG9uZW50KSB7DQogICAgICAgICAgcmV0dXJuIGtleTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH07DQogICAgbmFtZSA9IGluZmVyRnJvbVJlZ2lzdHJ5KA0KICAgICAgaW5zdGFuY2UuY29tcG9uZW50cyB8fCBpbnN0YW5jZS5wYXJlbnQudHlwZS5jb21wb25lbnRzDQogICAgKSB8fCBpbmZlckZyb21SZWdpc3RyeShpbnN0YW5jZS5hcHBDb250ZXh0LmNvbXBvbmVudHMpOw0KICB9DQogIHJldHVybiBuYW1lID8gY2xhc3NpZnkobmFtZSkgOiBpc1Jvb3QgPyBgQXBwYCA6IGBBbm9ueW1vdXNgOw0KfQ0KZnVuY3Rpb24gaXNDbGFzc0NvbXBvbmVudCh2YWx1ZSkgew0KICByZXR1cm4gaXNGdW5jdGlvbih2YWx1ZSkgJiYgIl9fdmNjT3B0cyIgaW4gdmFsdWU7DQp9DQoNCmNvbnN0IGNvbXB1dGVkID0gKGdldHRlck9yT3B0aW9ucywgZGVidWdPcHRpb25zKSA9PiB7DQogIGNvbnN0IGMgPSBjb21wdXRlZCQxKGdldHRlck9yT3B0aW9ucywgZGVidWdPcHRpb25zLCBpc0luU1NSQ29tcG9uZW50U2V0dXApOw0KICB7DQogICAgY29uc3QgaSA9IGdldEN1cnJlbnRJbnN0YW5jZSgpOw0KICAgIGlmIChpICYmIGkuYXBwQ29udGV4dC5jb25maWcud2FyblJlY3Vyc2l2ZUNvbXB1dGVkKSB7DQogICAgICBjLl93YXJuUmVjdXJzaXZlID0gdHJ1ZTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIGM7DQp9Ow0KDQpmdW5jdGlvbiBoKHR5cGUsIHByb3BzT3JDaGlsZHJlbiwgY2hpbGRyZW4pIHsNCiAgY29uc3QgbCA9IGFyZ3VtZW50cy5sZW5ndGg7DQogIGlmIChsID09PSAyKSB7DQogICAgaWYgKGlzT2JqZWN0KHByb3BzT3JDaGlsZHJlbikgJiYgIWlzQXJyYXkocHJvcHNPckNoaWxkcmVuKSkgew0KICAgICAgaWYgKGlzVk5vZGUocHJvcHNPckNoaWxkcmVuKSkgew0KICAgICAgICByZXR1cm4gY3JlYXRlVk5vZGUodHlwZSwgbnVsbCwgW3Byb3BzT3JDaGlsZHJlbl0pOw0KICAgICAgfQ0KICAgICAgcmV0dXJuIGNyZWF0ZVZOb2RlKHR5cGUsIHByb3BzT3JDaGlsZHJlbik7DQogICAgfSBlbHNlIHsNCiAgICAgIHJldHVybiBjcmVhdGVWTm9kZSh0eXBlLCBudWxsLCBwcm9wc09yQ2hpbGRyZW4pOw0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICBpZiAobCA+IDMpIHsNCiAgICAgIGNoaWxkcmVuID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKTsNCiAgICB9IGVsc2UgaWYgKGwgPT09IDMgJiYgaXNWTm9kZShjaGlsZHJlbikpIHsNCiAgICAgIGNoaWxkcmVuID0gW2NoaWxkcmVuXTsNCiAgICB9DQogICAgcmV0dXJuIGNyZWF0ZVZOb2RlKHR5cGUsIHByb3BzT3JDaGlsZHJlbiwgY2hpbGRyZW4pOw0KICB9DQp9DQoNCmZ1bmN0aW9uIGluaXRDdXN0b21Gb3JtYXR0ZXIoKSB7DQogIGlmICh0eXBlb2Ygd2luZG93ID09PSAidW5kZWZpbmVkIikgew0KICAgIHJldHVybjsNCiAgfQ0KICBjb25zdCB2dWVTdHlsZSA9IHsgc3R5bGU6ICJjb2xvcjojM2JhNzc2IiB9Ow0KICBjb25zdCBudW1iZXJTdHlsZSA9IHsgc3R5bGU6ICJjb2xvcjojMTY3N2ZmIiB9Ow0KICBjb25zdCBzdHJpbmdTdHlsZSA9IHsgc3R5bGU6ICJjb2xvcjojZjUyMjJkIiB9Ow0KICBjb25zdCBrZXl3b3JkU3R5bGUgPSB7IHN0eWxlOiAiY29sb3I6I2ViMmY5NiIgfTsNCiAgY29uc3QgZm9ybWF0dGVyID0gew0KICAgIF9fdnVlX2N1c3RvbV9mb3JtYXR0ZXI6IHRydWUsDQogICAgaGVhZGVyKG9iaikgew0KICAgICAgaWYgKCFpc09iamVjdChvYmopKSB7DQogICAgICAgIHJldHVybiBudWxsOw0KICAgICAgfQ0KICAgICAgaWYgKG9iai5fX2lzVnVlKSB7DQogICAgICAgIHJldHVybiBbImRpdiIsIHZ1ZVN0eWxlLCBgVnVlSW5zdGFuY2VgXTsNCiAgICAgIH0gZWxzZSBpZiAoaXNSZWYob2JqKSkgew0KICAgICAgICBwYXVzZVRyYWNraW5nKCk7DQogICAgICAgIGNvbnN0IHZhbHVlID0gb2JqLnZhbHVlOw0KICAgICAgICByZXNldFRyYWNraW5nKCk7DQogICAgICAgIHJldHVybiBbDQogICAgICAgICAgImRpdiIsDQogICAgICAgICAge30sDQogICAgICAgICAgWyJzcGFuIiwgdnVlU3R5bGUsIGdlblJlZkZsYWcob2JqKV0sDQogICAgICAgICAgIjwiLA0KICAgICAgICAgIGZvcm1hdFZhbHVlKHZhbHVlKSwNCiAgICAgICAgICBgPmANCiAgICAgICAgXTsNCiAgICAgIH0gZWxzZSBpZiAoaXNSZWFjdGl2ZShvYmopKSB7DQogICAgICAgIHJldHVybiBbDQogICAgICAgICAgImRpdiIsDQogICAgICAgICAge30sDQogICAgICAgICAgWyJzcGFuIiwgdnVlU3R5bGUsIGlzU2hhbGxvdyhvYmopID8gIlNoYWxsb3dSZWFjdGl2ZSIgOiAiUmVhY3RpdmUiXSwNCiAgICAgICAgICAiPCIsDQogICAgICAgICAgZm9ybWF0VmFsdWUob2JqKSwNCiAgICAgICAgICBgPiR7aXNSZWFkb25seShvYmopID8gYCAocmVhZG9ubHkpYCA6IGBgfWANCiAgICAgICAgXTsNCiAgICAgIH0gZWxzZSBpZiAoaXNSZWFkb25seShvYmopKSB7DQogICAgICAgIHJldHVybiBbDQogICAgICAgICAgImRpdiIsDQogICAgICAgICAge30sDQogICAgICAgICAgWyJzcGFuIiwgdnVlU3R5bGUsIGlzU2hhbGxvdyhvYmopID8gIlNoYWxsb3dSZWFkb25seSIgOiAiUmVhZG9ubHkiXSwNCiAgICAgICAgICAiPCIsDQogICAgICAgICAgZm9ybWF0VmFsdWUob2JqKSwNCiAgICAgICAgICAiPiINCiAgICAgICAgXTsNCiAgICAgIH0NCiAgICAgIHJldHVybiBudWxsOw0KICAgIH0sDQogICAgaGFzQm9keShvYmopIHsNCiAgICAgIHJldHVybiBvYmogJiYgb2JqLl9faXNWdWU7DQogICAgfSwNCiAgICBib2R5KG9iaikgew0KICAgICAgaWYgKG9iaiAmJiBvYmouX19pc1Z1ZSkgew0KICAgICAgICByZXR1cm4gWw0KICAgICAgICAgICJkaXYiLA0KICAgICAgICAgIHt9LA0KICAgICAgICAgIC4uLmZvcm1hdEluc3RhbmNlKG9iai4kKQ0KICAgICAgICBdOw0KICAgICAgfQ0KICAgIH0NCiAgfTsNCiAgZnVuY3Rpb24gZm9ybWF0SW5zdGFuY2UoaW5zdGFuY2UpIHsNCiAgICBjb25zdCBibG9ja3MgPSBbXTsNCiAgICBpZiAoaW5zdGFuY2UudHlwZS5wcm9wcyAmJiBpbnN0YW5jZS5wcm9wcykgew0KICAgICAgYmxvY2tzLnB1c2goY3JlYXRlSW5zdGFuY2VCbG9jaygicHJvcHMiLCB0b1JhdyhpbnN0YW5jZS5wcm9wcykpKTsNCiAgICB9DQogICAgaWYgKGluc3RhbmNlLnNldHVwU3RhdGUgIT09IEVNUFRZX09CSikgew0KICAgICAgYmxvY2tzLnB1c2goY3JlYXRlSW5zdGFuY2VCbG9jaygic2V0dXAiLCBpbnN0YW5jZS5zZXR1cFN0YXRlKSk7DQogICAgfQ0KICAgIGlmIChpbnN0YW5jZS5kYXRhICE9PSBFTVBUWV9PQkopIHsNCiAgICAgIGJsb2Nrcy5wdXNoKGNyZWF0ZUluc3RhbmNlQmxvY2soImRhdGEiLCB0b1JhdyhpbnN0YW5jZS5kYXRhKSkpOw0KICAgIH0NCiAgICBjb25zdCBjb21wdXRlZCA9IGV4dHJhY3RLZXlzKGluc3RhbmNlLCAiY29tcHV0ZWQiKTsNCiAgICBpZiAoY29tcHV0ZWQpIHsNCiAgICAgIGJsb2Nrcy5wdXNoKGNyZWF0ZUluc3RhbmNlQmxvY2soImNvbXB1dGVkIiwgY29tcHV0ZWQpKTsNCiAgICB9DQogICAgY29uc3QgaW5qZWN0ZWQgPSBleHRyYWN0S2V5cyhpbnN0YW5jZSwgImluamVjdCIpOw0KICAgIGlmIChpbmplY3RlZCkgew0KICAgICAgYmxvY2tzLnB1c2goY3JlYXRlSW5zdGFuY2VCbG9jaygiaW5qZWN0ZWQiLCBpbmplY3RlZCkpOw0KICAgIH0NCiAgICBibG9ja3MucHVzaChbDQogICAgICAiZGl2IiwNCiAgICAgIHt9LA0KICAgICAgWw0KICAgICAgICAic3BhbiIsDQogICAgICAgIHsNCiAgICAgICAgICBzdHlsZToga2V5d29yZFN0eWxlLnN0eWxlICsgIjtvcGFjaXR5OjAuNjYiDQogICAgICAgIH0sDQogICAgICAgICIkIChpbnRlcm5hbCk6ICINCiAgICAgIF0sDQogICAgICBbIm9iamVjdCIsIHsgb2JqZWN0OiBpbnN0YW5jZSB9XQ0KICAgIF0pOw0KICAgIHJldHVybiBibG9ja3M7DQogIH0NCiAgZnVuY3Rpb24gY3JlYXRlSW5zdGFuY2VCbG9jayh0eXBlLCB0YXJnZXQpIHsNCiAgICB0YXJnZXQgPSBleHRlbmQoe30sIHRhcmdldCk7DQogICAgaWYgKCFPYmplY3Qua2V5cyh0YXJnZXQpLmxlbmd0aCkgew0KICAgICAgcmV0dXJuIFsic3BhbiIsIHt9XTsNCiAgICB9DQogICAgcmV0dXJuIFsNCiAgICAgICJkaXYiLA0KICAgICAgeyBzdHlsZTogImxpbmUtaGVpZ2h0OjEuMjVlbTttYXJnaW4tYm90dG9tOjAuNmVtIiB9LA0KICAgICAgWw0KICAgICAgICAiZGl2IiwNCiAgICAgICAgew0KICAgICAgICAgIHN0eWxlOiAiY29sb3I6IzQ3NjU4MiINCiAgICAgICAgfSwNCiAgICAgICAgdHlwZQ0KICAgICAgXSwNCiAgICAgIFsNCiAgICAgICAgImRpdiIsDQogICAgICAgIHsNCiAgICAgICAgICBzdHlsZTogInBhZGRpbmctbGVmdDoxLjI1ZW0iDQogICAgICAgIH0sDQogICAgICAgIC4uLk9iamVjdC5rZXlzKHRhcmdldCkubWFwKChrZXkpID0+IHsNCiAgICAgICAgICByZXR1cm4gWw0KICAgICAgICAgICAgImRpdiIsDQogICAgICAgICAgICB7fSwNCiAgICAgICAgICAgIFsic3BhbiIsIGtleXdvcmRTdHlsZSwga2V5ICsgIjogIl0sDQogICAgICAgICAgICBmb3JtYXRWYWx1ZSh0YXJnZXRba2V5XSwgZmFsc2UpDQogICAgICAgICAgXTsNCiAgICAgICAgfSkNCiAgICAgIF0NCiAgICBdOw0KICB9DQogIGZ1bmN0aW9uIGZvcm1hdFZhbHVlKHYsIGFzUmF3ID0gdHJ1ZSkgew0KICAgIGlmICh0eXBlb2YgdiA9PT0gIm51bWJlciIpIHsNCiAgICAgIHJldHVybiBbInNwYW4iLCBudW1iZXJTdHlsZSwgdl07DQogICAgfSBlbHNlIGlmICh0eXBlb2YgdiA9PT0gInN0cmluZyIpIHsNCiAgICAgIHJldHVybiBbInNwYW4iLCBzdHJpbmdTdHlsZSwgSlNPTi5zdHJpbmdpZnkodildOw0KICAgIH0gZWxzZSBpZiAodHlwZW9mIHYgPT09ICJib29sZWFuIikgew0KICAgICAgcmV0dXJuIFsic3BhbiIsIGtleXdvcmRTdHlsZSwgdl07DQogICAgfSBlbHNlIGlmIChpc09iamVjdCh2KSkgew0KICAgICAgcmV0dXJuIFsib2JqZWN0IiwgeyBvYmplY3Q6IGFzUmF3ID8gdG9SYXcodikgOiB2IH1dOw0KICAgIH0gZWxzZSB7DQogICAgICByZXR1cm4gWyJzcGFuIiwgc3RyaW5nU3R5bGUsIFN0cmluZyh2KV07DQogICAgfQ0KICB9DQogIGZ1bmN0aW9uIGV4dHJhY3RLZXlzKGluc3RhbmNlLCB0eXBlKSB7DQogICAgY29uc3QgQ29tcCA9IGluc3RhbmNlLnR5cGU7DQogICAgaWYgKGlzRnVuY3Rpb24oQ29tcCkpIHsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgY29uc3QgZXh0cmFjdGVkID0ge307DQogICAgZm9yIChjb25zdCBrZXkgaW4gaW5zdGFuY2UuY3R4KSB7DQogICAgICBpZiAoaXNLZXlPZlR5cGUoQ29tcCwga2V5LCB0eXBlKSkgew0KICAgICAgICBleHRyYWN0ZWRba2V5XSA9IGluc3RhbmNlLmN0eFtrZXldOw0KICAgICAgfQ0KICAgIH0NCiAgICByZXR1cm4gZXh0cmFjdGVkOw0KICB9DQogIGZ1bmN0aW9uIGlzS2V5T2ZUeXBlKENvbXAsIGtleSwgdHlwZSkgew0KICAgIGNvbnN0IG9wdHMgPSBDb21wW3R5cGVdOw0KICAgIGlmIChpc0FycmF5KG9wdHMpICYmIG9wdHMuaW5jbHVkZXMoa2V5KSB8fCBpc09iamVjdChvcHRzKSAmJiBrZXkgaW4gb3B0cykgew0KICAgICAgcmV0dXJuIHRydWU7DQogICAgfQ0KICAgIGlmIChDb21wLmV4dGVuZHMgJiYgaXNLZXlPZlR5cGUoQ29tcC5leHRlbmRzLCBrZXksIHR5cGUpKSB7DQogICAgICByZXR1cm4gdHJ1ZTsNCiAgICB9DQogICAgaWYgKENvbXAubWl4aW5zICYmIENvbXAubWl4aW5zLnNvbWUoKG0pID0+IGlzS2V5T2ZUeXBlKG0sIGtleSwgdHlwZSkpKSB7DQogICAgICByZXR1cm4gdHJ1ZTsNCiAgICB9DQogIH0NCiAgZnVuY3Rpb24gZ2VuUmVmRmxhZyh2KSB7DQogICAgaWYgKGlzU2hhbGxvdyh2KSkgew0KICAgICAgcmV0dXJuIGBTaGFsbG93UmVmYDsNCiAgICB9DQogICAgaWYgKHYuZWZmZWN0KSB7DQogICAgICByZXR1cm4gYENvbXB1dGVkUmVmYDsNCiAgICB9DQogICAgcmV0dXJuIGBSZWZgOw0KICB9DQogIGlmICh3aW5kb3cuZGV2dG9vbHNGb3JtYXR0ZXJzKSB7DQogICAgd2luZG93LmRldnRvb2xzRm9ybWF0dGVycy5wdXNoKGZvcm1hdHRlcik7DQogIH0gZWxzZSB7DQogICAgd2luZG93LmRldnRvb2xzRm9ybWF0dGVycyA9IFtmb3JtYXR0ZXJdOw0KICB9DQp9DQoNCmZ1bmN0aW9uIHdpdGhNZW1vKG1lbW8sIHJlbmRlciwgY2FjaGUsIGluZGV4KSB7DQogIGNvbnN0IGNhY2hlZCA9IGNhY2hlW2luZGV4XTsNCiAgaWYgKGNhY2hlZCAmJiBpc01lbW9TYW1lKGNhY2hlZCwgbWVtbykpIHsNCiAgICByZXR1cm4gY2FjaGVkOw0KICB9DQogIGNvbnN0IHJldCA9IHJlbmRlcigpOw0KICByZXQubWVtbyA9IG1lbW8uc2xpY2UoKTsNCiAgcmV0LmNhY2hlSW5kZXggPSBpbmRleDsNCiAgcmV0dXJuIGNhY2hlW2luZGV4XSA9IHJldDsNCn0NCmZ1bmN0aW9uIGlzTWVtb1NhbWUoY2FjaGVkLCBtZW1vKSB7DQogIGNvbnN0IHByZXYgPSBjYWNoZWQubWVtbzsNCiAgaWYgKHByZXYubGVuZ3RoICE9IG1lbW8ubGVuZ3RoKSB7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9DQogIGZvciAobGV0IGkgPSAwOyBpIDwgcHJldi5sZW5ndGg7IGkrKykgew0KICAgIGlmIChoYXNDaGFuZ2VkKHByZXZbaV0sIG1lbW9baV0pKSB7DQogICAgICByZXR1cm4gZmFsc2U7DQogICAgfQ0KICB9DQogIGlmIChpc0Jsb2NrVHJlZUVuYWJsZWQgPiAwICYmIGN1cnJlbnRCbG9jaykgew0KICAgIGN1cnJlbnRCbG9jay5wdXNoKGNhY2hlZCk7DQogIH0NCiAgcmV0dXJuIHRydWU7DQp9DQoNCmNvbnN0IHZlcnNpb24gPSAiMy41LjE3IjsNCmNvbnN0IHdhcm4gPSB3YXJuJDEgOw0KY29uc3QgRXJyb3JUeXBlU3RyaW5ncyA9IEVycm9yVHlwZVN0cmluZ3MkMSA7DQpjb25zdCBkZXZ0b29scyA9IGRldnRvb2xzJDEgOw0KY29uc3Qgc2V0RGV2dG9vbHNIb29rID0gc2V0RGV2dG9vbHNIb29rJDEgOw0KY29uc3QgX3NzclV0aWxzID0gew0KICBjcmVhdGVDb21wb25lbnRJbnN0YW5jZSwNCiAgc2V0dXBDb21wb25lbnQsDQogIHJlbmRlckNvbXBvbmVudFJvb3QsDQogIHNldEN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSwNCiAgaXNWTm9kZTogaXNWTm9kZSwNCiAgbm9ybWFsaXplVk5vZGUsDQogIGdldENvbXBvbmVudFB1YmxpY0luc3RhbmNlLA0KICBlbnN1cmVWYWxpZFZOb2RlLA0KICBwdXNoV2FybmluZ0NvbnRleHQsDQogIHBvcFdhcm5pbmdDb250ZXh0DQp9Ow0KY29uc3Qgc3NyVXRpbHMgPSBfc3NyVXRpbHMgOw0KY29uc3QgcmVzb2x2ZUZpbHRlciA9IG51bGw7DQpjb25zdCBjb21wYXRVdGlscyA9IG51bGw7DQpjb25zdCBEZXByZWNhdGlvblR5cGVzID0gbnVsbDsNCg0KbGV0IHBvbGljeSA9IHZvaWQgMDsNCmNvbnN0IHR0ID0gdHlwZW9mIHdpbmRvdyAhPT0gInVuZGVmaW5lZCIgJiYgd2luZG93LnRydXN0ZWRUeXBlczsNCmlmICh0dCkgew0KICB0cnkgew0KICAgIHBvbGljeSA9IC8qIEBfX1BVUkVfXyAqLyB0dC5jcmVhdGVQb2xpY3koInZ1ZSIsIHsNCiAgICAgIGNyZWF0ZUhUTUw6ICh2YWwpID0+IHZhbA0KICAgIH0pOw0KICB9IGNhdGNoIChlKSB7DQogICAgd2FybihgRXJyb3IgY3JlYXRpbmcgdHJ1c3RlZCB0eXBlcyBwb2xpY3k6ICR7ZX1gKTsNCiAgfQ0KfQ0KY29uc3QgdW5zYWZlVG9UcnVzdGVkSFRNTCA9IHBvbGljeSA/ICh2YWwpID0+IHBvbGljeS5jcmVhdGVIVE1MKHZhbCkgOiAodmFsKSA9PiB2YWw7DQpjb25zdCBzdmdOUyA9ICJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI7DQpjb25zdCBtYXRobWxOUyA9ICJodHRwOi8vd3d3LnczLm9yZy8xOTk4L01hdGgvTWF0aE1MIjsNCmNvbnN0IGRvYyA9IHR5cGVvZiBkb2N1bWVudCAhPT0gInVuZGVmaW5lZCIgPyBkb2N1bWVudCA6IG51bGw7DQpjb25zdCB0ZW1wbGF0ZUNvbnRhaW5lciA9IGRvYyAmJiAvKiBAX19QVVJFX18gKi8gZG9jLmNyZWF0ZUVsZW1lbnQoInRlbXBsYXRlIik7DQpjb25zdCBub2RlT3BzID0gew0KICBpbnNlcnQ6IChjaGlsZCwgcGFyZW50LCBhbmNob3IpID0+IHsNCiAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKGNoaWxkLCBhbmNob3IgfHwgbnVsbCk7DQogIH0sDQogIHJlbW92ZTogKGNoaWxkKSA9PiB7DQogICAgY29uc3QgcGFyZW50ID0gY2hpbGQucGFyZW50Tm9kZTsNCiAgICBpZiAocGFyZW50KSB7DQogICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQoY2hpbGQpOw0KICAgIH0NCiAgfSwNCiAgY3JlYXRlRWxlbWVudDogKHRhZywgbmFtZXNwYWNlLCBpcywgcHJvcHMpID0+IHsNCiAgICBjb25zdCBlbCA9IG5hbWVzcGFjZSA9PT0gInN2ZyIgPyBkb2MuY3JlYXRlRWxlbWVudE5TKHN2Z05TLCB0YWcpIDogbmFtZXNwYWNlID09PSAibWF0aG1sIiA/IGRvYy5jcmVhdGVFbGVtZW50TlMobWF0aG1sTlMsIHRhZykgOiBpcyA/IGRvYy5jcmVhdGVFbGVtZW50KHRhZywgeyBpcyB9KSA6IGRvYy5jcmVhdGVFbGVtZW50KHRhZyk7DQogICAgaWYgKHRhZyA9PT0gInNlbGVjdCIgJiYgcHJvcHMgJiYgcHJvcHMubXVsdGlwbGUgIT0gbnVsbCkgew0KICAgICAgZWwuc2V0QXR0cmlidXRlKCJtdWx0aXBsZSIsIHByb3BzLm11bHRpcGxlKTsNCiAgICB9DQogICAgcmV0dXJuIGVsOw0KICB9LA0KICBjcmVhdGVUZXh0OiAodGV4dCkgPT4gZG9jLmNyZWF0ZVRleHROb2RlKHRleHQpLA0KICBjcmVhdGVDb21tZW50OiAodGV4dCkgPT4gZG9jLmNyZWF0ZUNvbW1lbnQodGV4dCksDQogIHNldFRleHQ6IChub2RlLCB0ZXh0KSA9PiB7DQogICAgbm9kZS5ub2RlVmFsdWUgPSB0ZXh0Ow0KICB9LA0KICBzZXRFbGVtZW50VGV4dDogKGVsLCB0ZXh0KSA9PiB7DQogICAgZWwudGV4dENvbnRlbnQgPSB0ZXh0Ow0KICB9LA0KICBwYXJlbnROb2RlOiAobm9kZSkgPT4gbm9kZS5wYXJlbnROb2RlLA0KICBuZXh0U2libGluZzogKG5vZGUpID0+IG5vZGUubmV4dFNpYmxpbmcsDQogIHF1ZXJ5U2VsZWN0b3I6IChzZWxlY3RvcikgPT4gZG9jLnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpLA0KICBzZXRTY29wZUlkKGVsLCBpZCkgew0KICAgIGVsLnNldEF0dHJpYnV0ZShpZCwgIiIpOw0KICB9LA0KICAvLyBfX1VOU0FGRV9fDQogIC8vIFJlYXNvbjogaW5uZXJIVE1MLg0KICAvLyBTdGF0aWMgY29udGVudCBoZXJlIGNhbiBvbmx5IGNvbWUgZnJvbSBjb21waWxlZCB0ZW1wbGF0ZXMuDQogIC8vIEFzIGxvbmcgYXMgdGhlIHVzZXIgb25seSB1c2VzIHRydXN0ZWQgdGVtcGxhdGVzLCB0aGlzIGlzIHNhZmUuDQogIGluc2VydFN0YXRpY0NvbnRlbnQoY29udGVudCwgcGFyZW50LCBhbmNob3IsIG5hbWVzcGFjZSwgc3RhcnQsIGVuZCkgew0KICAgIGNvbnN0IGJlZm9yZSA9IGFuY2hvciA/IGFuY2hvci5wcmV2aW91c1NpYmxpbmcgOiBwYXJlbnQubGFzdENoaWxkOw0KICAgIGlmIChzdGFydCAmJiAoc3RhcnQgPT09IGVuZCB8fCBzdGFydC5uZXh0U2libGluZykpIHsNCiAgICAgIHdoaWxlICh0cnVlKSB7DQogICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoc3RhcnQuY2xvbmVOb2RlKHRydWUpLCBhbmNob3IpOw0KICAgICAgICBpZiAoc3RhcnQgPT09IGVuZCB8fCAhKHN0YXJ0ID0gc3RhcnQubmV4dFNpYmxpbmcpKSBicmVhazsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgdGVtcGxhdGVDb250YWluZXIuaW5uZXJIVE1MID0gdW5zYWZlVG9UcnVzdGVkSFRNTCgNCiAgICAgICAgbmFtZXNwYWNlID09PSAic3ZnIiA/IGA8c3ZnPiR7Y29udGVudH08L3N2Zz5gIDogbmFtZXNwYWNlID09PSAibWF0aG1sIiA/IGA8bWF0aD4ke2NvbnRlbnR9PC9tYXRoPmAgOiBjb250ZW50DQogICAgICApOw0KICAgICAgY29uc3QgdGVtcGxhdGUgPSB0ZW1wbGF0ZUNvbnRhaW5lci5jb250ZW50Ow0KICAgICAgaWYgKG5hbWVzcGFjZSA9PT0gInN2ZyIgfHwgbmFtZXNwYWNlID09PSAibWF0aG1sIikgew0KICAgICAgICBjb25zdCB3cmFwcGVyID0gdGVtcGxhdGUuZmlyc3RDaGlsZDsNCiAgICAgICAgd2hpbGUgKHdyYXBwZXIuZmlyc3RDaGlsZCkgew0KICAgICAgICAgIHRlbXBsYXRlLmFwcGVuZENoaWxkKHdyYXBwZXIuZmlyc3RDaGlsZCk7DQogICAgICAgIH0NCiAgICAgICAgdGVtcGxhdGUucmVtb3ZlQ2hpbGQod3JhcHBlcik7DQogICAgICB9DQogICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKHRlbXBsYXRlLCBhbmNob3IpOw0KICAgIH0NCiAgICByZXR1cm4gWw0KICAgICAgLy8gZmlyc3QNCiAgICAgIGJlZm9yZSA/IGJlZm9yZS5uZXh0U2libGluZyA6IHBhcmVudC5maXJzdENoaWxkLA0KICAgICAgLy8gbGFzdA0KICAgICAgYW5jaG9yID8gYW5jaG9yLnByZXZpb3VzU2libGluZyA6IHBhcmVudC5sYXN0Q2hpbGQNCiAgICBdOw0KICB9DQp9Ow0KDQpjb25zdCBUUkFOU0lUSU9OID0gInRyYW5zaXRpb24iOw0KY29uc3QgQU5JTUFUSU9OID0gImFuaW1hdGlvbiI7DQpjb25zdCB2dGNLZXkgPSBTeW1ib2woIl92dGMiKTsNCmNvbnN0IERPTVRyYW5zaXRpb25Qcm9wc1ZhbGlkYXRvcnMgPSB7DQogIG5hbWU6IFN0cmluZywNCiAgdHlwZTogU3RyaW5nLA0KICBjc3M6IHsNCiAgICB0eXBlOiBCb29sZWFuLA0KICAgIGRlZmF1bHQ6IHRydWUNCiAgfSwNCiAgZHVyYXRpb246IFtTdHJpbmcsIE51bWJlciwgT2JqZWN0XSwNCiAgZW50ZXJGcm9tQ2xhc3M6IFN0cmluZywNCiAgZW50ZXJBY3RpdmVDbGFzczogU3RyaW5nLA0KICBlbnRlclRvQ2xhc3M6IFN0cmluZywNCiAgYXBwZWFyRnJvbUNsYXNzOiBTdHJpbmcsDQogIGFwcGVhckFjdGl2ZUNsYXNzOiBTdHJpbmcsDQogIGFwcGVhclRvQ2xhc3M6IFN0cmluZywNCiAgbGVhdmVGcm9tQ2xhc3M6IFN0cmluZywNCiAgbGVhdmVBY3RpdmVDbGFzczogU3RyaW5nLA0KICBsZWF2ZVRvQ2xhc3M6IFN0cmluZw0KfTsNCmNvbnN0IFRyYW5zaXRpb25Qcm9wc1ZhbGlkYXRvcnMgPSAvKiBAX19QVVJFX18gKi8gZXh0ZW5kKA0KICB7fSwNCiAgQmFzZVRyYW5zaXRpb25Qcm9wc1ZhbGlkYXRvcnMsDQogIERPTVRyYW5zaXRpb25Qcm9wc1ZhbGlkYXRvcnMNCik7DQpjb25zdCBkZWNvcmF0ZSQxID0gKHQpID0+IHsNCiAgdC5kaXNwbGF5TmFtZSA9ICJUcmFuc2l0aW9uIjsNCiAgdC5wcm9wcyA9IFRyYW5zaXRpb25Qcm9wc1ZhbGlkYXRvcnM7DQogIHJldHVybiB0Ow0KfTsNCmNvbnN0IFRyYW5zaXRpb24gPSAvKiBAX19QVVJFX18gKi8gZGVjb3JhdGUkMSgNCiAgKHByb3BzLCB7IHNsb3RzIH0pID0+IGgoQmFzZVRyYW5zaXRpb24sIHJlc29sdmVUcmFuc2l0aW9uUHJvcHMocHJvcHMpLCBzbG90cykNCik7DQpjb25zdCBjYWxsSG9vayA9IChob29rLCBhcmdzID0gW10pID0+IHsNCiAgaWYgKGlzQXJyYXkoaG9vaykpIHsNCiAgICBob29rLmZvckVhY2goKGgyKSA9PiBoMiguLi5hcmdzKSk7DQogIH0gZWxzZSBpZiAoaG9vaykgew0KICAgIGhvb2soLi4uYXJncyk7DQogIH0NCn07DQpjb25zdCBoYXNFeHBsaWNpdENhbGxiYWNrID0gKGhvb2spID0+IHsNCiAgcmV0dXJuIGhvb2sgPyBpc0FycmF5KGhvb2spID8gaG9vay5zb21lKChoMikgPT4gaDIubGVuZ3RoID4gMSkgOiBob29rLmxlbmd0aCA+IDEgOiBmYWxzZTsNCn07DQpmdW5jdGlvbiByZXNvbHZlVHJhbnNpdGlvblByb3BzKHJhd1Byb3BzKSB7DQogIGNvbnN0IGJhc2VQcm9wcyA9IHt9Ow0KICBmb3IgKGNvbnN0IGtleSBpbiByYXdQcm9wcykgew0KICAgIGlmICghKGtleSBpbiBET01UcmFuc2l0aW9uUHJvcHNWYWxpZGF0b3JzKSkgew0KICAgICAgYmFzZVByb3BzW2tleV0gPSByYXdQcm9wc1trZXldOw0KICAgIH0NCiAgfQ0KICBpZiAocmF3UHJvcHMuY3NzID09PSBmYWxzZSkgew0KICAgIHJldHVybiBiYXNlUHJvcHM7DQogIH0NCiAgY29uc3Qgew0KICAgIG5hbWUgPSAidiIsDQogICAgdHlwZSwNCiAgICBkdXJhdGlvbiwNCiAgICBlbnRlckZyb21DbGFzcyA9IGAke25hbWV9LWVudGVyLWZyb21gLA0KICAgIGVudGVyQWN0aXZlQ2xhc3MgPSBgJHtuYW1lfS1lbnRlci1hY3RpdmVgLA0KICAgIGVudGVyVG9DbGFzcyA9IGAke25hbWV9LWVudGVyLXRvYCwNCiAgICBhcHBlYXJGcm9tQ2xhc3MgPSBlbnRlckZyb21DbGFzcywNCiAgICBhcHBlYXJBY3RpdmVDbGFzcyA9IGVudGVyQWN0aXZlQ2xhc3MsDQogICAgYXBwZWFyVG9DbGFzcyA9IGVudGVyVG9DbGFzcywNCiAgICBsZWF2ZUZyb21DbGFzcyA9IGAke25hbWV9LWxlYXZlLWZyb21gLA0KICAgIGxlYXZlQWN0aXZlQ2xhc3MgPSBgJHtuYW1lfS1sZWF2ZS1hY3RpdmVgLA0KICAgIGxlYXZlVG9DbGFzcyA9IGAke25hbWV9LWxlYXZlLXRvYA0KICB9ID0gcmF3UHJvcHM7DQogIGNvbnN0IGR1cmF0aW9ucyA9IG5vcm1hbGl6ZUR1cmF0aW9uKGR1cmF0aW9uKTsNCiAgY29uc3QgZW50ZXJEdXJhdGlvbiA9IGR1cmF0aW9ucyAmJiBkdXJhdGlvbnNbMF07DQogIGNvbnN0IGxlYXZlRHVyYXRpb24gPSBkdXJhdGlvbnMgJiYgZHVyYXRpb25zWzFdOw0KICBjb25zdCB7DQogICAgb25CZWZvcmVFbnRlciwNCiAgICBvbkVudGVyLA0KICAgIG9uRW50ZXJDYW5jZWxsZWQsDQogICAgb25MZWF2ZSwNCiAgICBvbkxlYXZlQ2FuY2VsbGVkLA0KICAgIG9uQmVmb3JlQXBwZWFyID0gb25CZWZvcmVFbnRlciwNCiAgICBvbkFwcGVhciA9IG9uRW50ZXIsDQogICAgb25BcHBlYXJDYW5jZWxsZWQgPSBvbkVudGVyQ2FuY2VsbGVkDQogIH0gPSBiYXNlUHJvcHM7DQogIGNvbnN0IGZpbmlzaEVudGVyID0gKGVsLCBpc0FwcGVhciwgZG9uZSwgaXNDYW5jZWxsZWQpID0+IHsNCiAgICBlbC5fZW50ZXJDYW5jZWxsZWQgPSBpc0NhbmNlbGxlZDsNCiAgICByZW1vdmVUcmFuc2l0aW9uQ2xhc3MoZWwsIGlzQXBwZWFyID8gYXBwZWFyVG9DbGFzcyA6IGVudGVyVG9DbGFzcyk7DQogICAgcmVtb3ZlVHJhbnNpdGlvbkNsYXNzKGVsLCBpc0FwcGVhciA/IGFwcGVhckFjdGl2ZUNsYXNzIDogZW50ZXJBY3RpdmVDbGFzcyk7DQogICAgZG9uZSAmJiBkb25lKCk7DQogIH07DQogIGNvbnN0IGZpbmlzaExlYXZlID0gKGVsLCBkb25lKSA9PiB7DQogICAgZWwuX2lzTGVhdmluZyA9IGZhbHNlOw0KICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgbGVhdmVGcm9tQ2xhc3MpOw0KICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgbGVhdmVUb0NsYXNzKTsNCiAgICByZW1vdmVUcmFuc2l0aW9uQ2xhc3MoZWwsIGxlYXZlQWN0aXZlQ2xhc3MpOw0KICAgIGRvbmUgJiYgZG9uZSgpOw0KICB9Ow0KICBjb25zdCBtYWtlRW50ZXJIb29rID0gKGlzQXBwZWFyKSA9PiB7DQogICAgcmV0dXJuIChlbCwgZG9uZSkgPT4gew0KICAgICAgY29uc3QgaG9vayA9IGlzQXBwZWFyID8gb25BcHBlYXIgOiBvbkVudGVyOw0KICAgICAgY29uc3QgcmVzb2x2ZSA9ICgpID0+IGZpbmlzaEVudGVyKGVsLCBpc0FwcGVhciwgZG9uZSk7DQogICAgICBjYWxsSG9vayhob29rLCBbZWwsIHJlc29sdmVdKTsNCiAgICAgIG5leHRGcmFtZSgoKSA9PiB7DQogICAgICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgaXNBcHBlYXIgPyBhcHBlYXJGcm9tQ2xhc3MgOiBlbnRlckZyb21DbGFzcyk7DQogICAgICAgIGFkZFRyYW5zaXRpb25DbGFzcyhlbCwgaXNBcHBlYXIgPyBhcHBlYXJUb0NsYXNzIDogZW50ZXJUb0NsYXNzKTsNCiAgICAgICAgaWYgKCFoYXNFeHBsaWNpdENhbGxiYWNrKGhvb2spKSB7DQogICAgICAgICAgd2hlblRyYW5zaXRpb25FbmRzKGVsLCB0eXBlLCBlbnRlckR1cmF0aW9uLCByZXNvbHZlKTsNCiAgICAgICAgfQ0KICAgICAgfSk7DQogICAgfTsNCiAgfTsNCiAgcmV0dXJuIGV4dGVuZChiYXNlUHJvcHMsIHsNCiAgICBvbkJlZm9yZUVudGVyKGVsKSB7DQogICAgICBjYWxsSG9vayhvbkJlZm9yZUVudGVyLCBbZWxdKTsNCiAgICAgIGFkZFRyYW5zaXRpb25DbGFzcyhlbCwgZW50ZXJGcm9tQ2xhc3MpOw0KICAgICAgYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCBlbnRlckFjdGl2ZUNsYXNzKTsNCiAgICB9LA0KICAgIG9uQmVmb3JlQXBwZWFyKGVsKSB7DQogICAgICBjYWxsSG9vayhvbkJlZm9yZUFwcGVhciwgW2VsXSk7DQogICAgICBhZGRUcmFuc2l0aW9uQ2xhc3MoZWwsIGFwcGVhckZyb21DbGFzcyk7DQogICAgICBhZGRUcmFuc2l0aW9uQ2xhc3MoZWwsIGFwcGVhckFjdGl2ZUNsYXNzKTsNCiAgICB9LA0KICAgIG9uRW50ZXI6IG1ha2VFbnRlckhvb2soZmFsc2UpLA0KICAgIG9uQXBwZWFyOiBtYWtlRW50ZXJIb29rKHRydWUpLA0KICAgIG9uTGVhdmUoZWwsIGRvbmUpIHsNCiAgICAgIGVsLl9pc0xlYXZpbmcgPSB0cnVlOw0KICAgICAgY29uc3QgcmVzb2x2ZSA9ICgpID0+IGZpbmlzaExlYXZlKGVsLCBkb25lKTsNCiAgICAgIGFkZFRyYW5zaXRpb25DbGFzcyhlbCwgbGVhdmVGcm9tQ2xhc3MpOw0KICAgICAgaWYgKCFlbC5fZW50ZXJDYW5jZWxsZWQpIHsNCiAgICAgICAgZm9yY2VSZWZsb3coKTsNCiAgICAgICAgYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCBsZWF2ZUFjdGl2ZUNsYXNzKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGFkZFRyYW5zaXRpb25DbGFzcyhlbCwgbGVhdmVBY3RpdmVDbGFzcyk7DQogICAgICAgIGZvcmNlUmVmbG93KCk7DQogICAgICB9DQogICAgICBuZXh0RnJhbWUoKCkgPT4gew0KICAgICAgICBpZiAoIWVsLl9pc0xlYXZpbmcpIHsNCiAgICAgICAgICByZXR1cm47DQogICAgICAgIH0NCiAgICAgICAgcmVtb3ZlVHJhbnNpdGlvbkNsYXNzKGVsLCBsZWF2ZUZyb21DbGFzcyk7DQogICAgICAgIGFkZFRyYW5zaXRpb25DbGFzcyhlbCwgbGVhdmVUb0NsYXNzKTsNCiAgICAgICAgaWYgKCFoYXNFeHBsaWNpdENhbGxiYWNrKG9uTGVhdmUpKSB7DQogICAgICAgICAgd2hlblRyYW5zaXRpb25FbmRzKGVsLCB0eXBlLCBsZWF2ZUR1cmF0aW9uLCByZXNvbHZlKTsNCiAgICAgICAgfQ0KICAgICAgfSk7DQogICAgICBjYWxsSG9vayhvbkxlYXZlLCBbZWwsIHJlc29sdmVdKTsNCiAgICB9LA0KICAgIG9uRW50ZXJDYW5jZWxsZWQoZWwpIHsNCiAgICAgIGZpbmlzaEVudGVyKGVsLCBmYWxzZSwgdm9pZCAwLCB0cnVlKTsNCiAgICAgIGNhbGxIb29rKG9uRW50ZXJDYW5jZWxsZWQsIFtlbF0pOw0KICAgIH0sDQogICAgb25BcHBlYXJDYW5jZWxsZWQoZWwpIHsNCiAgICAgIGZpbmlzaEVudGVyKGVsLCB0cnVlLCB2b2lkIDAsIHRydWUpOw0KICAgICAgY2FsbEhvb2sob25BcHBlYXJDYW5jZWxsZWQsIFtlbF0pOw0KICAgIH0sDQogICAgb25MZWF2ZUNhbmNlbGxlZChlbCkgew0KICAgICAgZmluaXNoTGVhdmUoZWwpOw0KICAgICAgY2FsbEhvb2sob25MZWF2ZUNhbmNlbGxlZCwgW2VsXSk7DQogICAgfQ0KICB9KTsNCn0NCmZ1bmN0aW9uIG5vcm1hbGl6ZUR1cmF0aW9uKGR1cmF0aW9uKSB7DQogIGlmIChkdXJhdGlvbiA9PSBudWxsKSB7DQogICAgcmV0dXJuIG51bGw7DQogIH0gZWxzZSBpZiAoaXNPYmplY3QoZHVyYXRpb24pKSB7DQogICAgcmV0dXJuIFtOdW1iZXJPZihkdXJhdGlvbi5lbnRlciksIE51bWJlck9mKGR1cmF0aW9uLmxlYXZlKV07DQogIH0gZWxzZSB7DQogICAgY29uc3QgbiA9IE51bWJlck9mKGR1cmF0aW9uKTsNCiAgICByZXR1cm4gW24sIG5dOw0KICB9DQp9DQpmdW5jdGlvbiBOdW1iZXJPZih2YWwpIHsNCiAgY29uc3QgcmVzID0gdG9OdW1iZXIodmFsKTsNCiAgew0KICAgIGFzc2VydE51bWJlcihyZXMsICI8dHJhbnNpdGlvbj4gZXhwbGljaXQgZHVyYXRpb24iKTsNCiAgfQ0KICByZXR1cm4gcmVzOw0KfQ0KZnVuY3Rpb24gYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCBjbHMpIHsNCiAgY2xzLnNwbGl0KC9ccysvKS5mb3JFYWNoKChjKSA9PiBjICYmIGVsLmNsYXNzTGlzdC5hZGQoYykpOw0KICAoZWxbdnRjS2V5XSB8fCAoZWxbdnRjS2V5XSA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KCkpKS5hZGQoY2xzKTsNCn0NCmZ1bmN0aW9uIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgY2xzKSB7DQogIGNscy5zcGxpdCgvXHMrLykuZm9yRWFjaCgoYykgPT4gYyAmJiBlbC5jbGFzc0xpc3QucmVtb3ZlKGMpKTsNCiAgY29uc3QgX3Z0YyA9IGVsW3Z0Y0tleV07DQogIGlmIChfdnRjKSB7DQogICAgX3Z0Yy5kZWxldGUoY2xzKTsNCiAgICBpZiAoIV92dGMuc2l6ZSkgew0KICAgICAgZWxbdnRjS2V5XSA9IHZvaWQgMDsNCiAgICB9DQogIH0NCn0NCmZ1bmN0aW9uIG5leHRGcmFtZShjYikgew0KICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4gew0KICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZShjYik7DQogIH0pOw0KfQ0KbGV0IGVuZElkID0gMDsNCmZ1bmN0aW9uIHdoZW5UcmFuc2l0aW9uRW5kcyhlbCwgZXhwZWN0ZWRUeXBlLCBleHBsaWNpdFRpbWVvdXQsIHJlc29sdmUpIHsNCiAgY29uc3QgaWQgPSBlbC5fZW5kSWQgPSArK2VuZElkOw0KICBjb25zdCByZXNvbHZlSWZOb3RTdGFsZSA9ICgpID0+IHsNCiAgICBpZiAoaWQgPT09IGVsLl9lbmRJZCkgew0KICAgICAgcmVzb2x2ZSgpOw0KICAgIH0NCiAgfTsNCiAgaWYgKGV4cGxpY2l0VGltZW91dCAhPSBudWxsKSB7DQogICAgcmV0dXJuIHNldFRpbWVvdXQocmVzb2x2ZUlmTm90U3RhbGUsIGV4cGxpY2l0VGltZW91dCk7DQogIH0NCiAgY29uc3QgeyB0eXBlLCB0aW1lb3V0LCBwcm9wQ291bnQgfSA9IGdldFRyYW5zaXRpb25JbmZvKGVsLCBleHBlY3RlZFR5cGUpOw0KICBpZiAoIXR5cGUpIHsNCiAgICByZXR1cm4gcmVzb2x2ZSgpOw0KICB9DQogIGNvbnN0IGVuZEV2ZW50ID0gdHlwZSArICJlbmQiOw0KICBsZXQgZW5kZWQgPSAwOw0KICBjb25zdCBlbmQgPSAoKSA9PiB7DQogICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihlbmRFdmVudCwgb25FbmQpOw0KICAgIHJlc29sdmVJZk5vdFN0YWxlKCk7DQogIH07DQogIGNvbnN0IG9uRW5kID0gKGUpID0+IHsNCiAgICBpZiAoZS50YXJnZXQgPT09IGVsICYmICsrZW5kZWQgPj0gcHJvcENvdW50KSB7DQogICAgICBlbmQoKTsNCiAgICB9DQogIH07DQogIHNldFRpbWVvdXQoKCkgPT4gew0KICAgIGlmIChlbmRlZCA8IHByb3BDb3VudCkgew0KICAgICAgZW5kKCk7DQogICAgfQ0KICB9LCB0aW1lb3V0ICsgMSk7DQogIGVsLmFkZEV2ZW50TGlzdGVuZXIoZW5kRXZlbnQsIG9uRW5kKTsNCn0NCmZ1bmN0aW9uIGdldFRyYW5zaXRpb25JbmZvKGVsLCBleHBlY3RlZFR5cGUpIHsNCiAgY29uc3Qgc3R5bGVzID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWwpOw0KICBjb25zdCBnZXRTdHlsZVByb3BlcnRpZXMgPSAoa2V5KSA9PiAoc3R5bGVzW2tleV0gfHwgIiIpLnNwbGl0KCIsICIpOw0KICBjb25zdCB0cmFuc2l0aW9uRGVsYXlzID0gZ2V0U3R5bGVQcm9wZXJ0aWVzKGAke1RSQU5TSVRJT059RGVsYXlgKTsNCiAgY29uc3QgdHJhbnNpdGlvbkR1cmF0aW9ucyA9IGdldFN0eWxlUHJvcGVydGllcyhgJHtUUkFOU0lUSU9OfUR1cmF0aW9uYCk7DQogIGNvbnN0IHRyYW5zaXRpb25UaW1lb3V0ID0gZ2V0VGltZW91dCh0cmFuc2l0aW9uRGVsYXlzLCB0cmFuc2l0aW9uRHVyYXRpb25zKTsNCiAgY29uc3QgYW5pbWF0aW9uRGVsYXlzID0gZ2V0U3R5bGVQcm9wZXJ0aWVzKGAke0FOSU1BVElPTn1EZWxheWApOw0KICBjb25zdCBhbmltYXRpb25EdXJhdGlvbnMgPSBnZXRTdHlsZVByb3BlcnRpZXMoYCR7QU5JTUFUSU9OfUR1cmF0aW9uYCk7DQogIGNvbnN0IGFuaW1hdGlvblRpbWVvdXQgPSBnZXRUaW1lb3V0KGFuaW1hdGlvbkRlbGF5cywgYW5pbWF0aW9uRHVyYXRpb25zKTsNCiAgbGV0IHR5cGUgPSBudWxsOw0KICBsZXQgdGltZW91dCA9IDA7DQogIGxldCBwcm9wQ291bnQgPSAwOw0KICBpZiAoZXhwZWN0ZWRUeXBlID09PSBUUkFOU0lUSU9OKSB7DQogICAgaWYgKHRyYW5zaXRpb25UaW1lb3V0ID4gMCkgew0KICAgICAgdHlwZSA9IFRSQU5TSVRJT047DQogICAgICB0aW1lb3V0ID0gdHJhbnNpdGlvblRpbWVvdXQ7DQogICAgICBwcm9wQ291bnQgPSB0cmFuc2l0aW9uRHVyYXRpb25zLmxlbmd0aDsNCiAgICB9DQogIH0gZWxzZSBpZiAoZXhwZWN0ZWRUeXBlID09PSBBTklNQVRJT04pIHsNCiAgICBpZiAoYW5pbWF0aW9uVGltZW91dCA+IDApIHsNCiAgICAgIHR5cGUgPSBBTklNQVRJT047DQogICAgICB0aW1lb3V0ID0gYW5pbWF0aW9uVGltZW91dDsNCiAgICAgIHByb3BDb3VudCA9IGFuaW1hdGlvbkR1cmF0aW9ucy5sZW5ndGg7DQogICAgfQ0KICB9IGVsc2Ugew0KICAgIHRpbWVvdXQgPSBNYXRoLm1heCh0cmFuc2l0aW9uVGltZW91dCwgYW5pbWF0aW9uVGltZW91dCk7DQogICAgdHlwZSA9IHRpbWVvdXQgPiAwID8gdHJhbnNpdGlvblRpbWVvdXQgPiBhbmltYXRpb25UaW1lb3V0ID8gVFJBTlNJVElPTiA6IEFOSU1BVElPTiA6IG51bGw7DQogICAgcHJvcENvdW50ID0gdHlwZSA/IHR5cGUgPT09IFRSQU5TSVRJT04gPyB0cmFuc2l0aW9uRHVyYXRpb25zLmxlbmd0aCA6IGFuaW1hdGlvbkR1cmF0aW9ucy5sZW5ndGggOiAwOw0KICB9DQogIGNvbnN0IGhhc1RyYW5zZm9ybSA9IHR5cGUgPT09IFRSQU5TSVRJT04gJiYgL1xiKHRyYW5zZm9ybXxhbGwpKCx8JCkvLnRlc3QoDQogICAgZ2V0U3R5bGVQcm9wZXJ0aWVzKGAke1RSQU5TSVRJT059UHJvcGVydHlgKS50b1N0cmluZygpDQogICk7DQogIHJldHVybiB7DQogICAgdHlwZSwNCiAgICB0aW1lb3V0LA0KICAgIHByb3BDb3VudCwNCiAgICBoYXNUcmFuc2Zvcm0NCiAgfTsNCn0NCmZ1bmN0aW9uIGdldFRpbWVvdXQoZGVsYXlzLCBkdXJhdGlvbnMpIHsNCiAgd2hpbGUgKGRlbGF5cy5sZW5ndGggPCBkdXJhdGlvbnMubGVuZ3RoKSB7DQogICAgZGVsYXlzID0gZGVsYXlzLmNvbmNhdChkZWxheXMpOw0KICB9DQogIHJldHVybiBNYXRoLm1heCguLi5kdXJhdGlvbnMubWFwKChkLCBpKSA9PiB0b01zKGQpICsgdG9NcyhkZWxheXNbaV0pKSk7DQp9DQpmdW5jdGlvbiB0b01zKHMpIHsNCiAgaWYgKHMgPT09ICJhdXRvIikgcmV0dXJuIDA7DQogIHJldHVybiBOdW1iZXIocy5zbGljZSgwLCAtMSkucmVwbGFjZSgiLCIsICIuIikpICogMWUzOw0KfQ0KZnVuY3Rpb24gZm9yY2VSZWZsb3coKSB7DQogIHJldHVybiBkb2N1bWVudC5ib2R5Lm9mZnNldEhlaWdodDsNCn0NCg0KZnVuY3Rpb24gcGF0Y2hDbGFzcyhlbCwgdmFsdWUsIGlzU1ZHKSB7DQogIGNvbnN0IHRyYW5zaXRpb25DbGFzc2VzID0gZWxbdnRjS2V5XTsNCiAgaWYgKHRyYW5zaXRpb25DbGFzc2VzKSB7DQogICAgdmFsdWUgPSAodmFsdWUgPyBbdmFsdWUsIC4uLnRyYW5zaXRpb25DbGFzc2VzXSA6IFsuLi50cmFuc2l0aW9uQ2xhc3Nlc10pLmpvaW4oIiAiKTsNCiAgfQ0KICBpZiAodmFsdWUgPT0gbnVsbCkgew0KICAgIGVsLnJlbW92ZUF0dHJpYnV0ZSgiY2xhc3MiKTsNCiAgfSBlbHNlIGlmIChpc1NWRykgew0KICAgIGVsLnNldEF0dHJpYnV0ZSgiY2xhc3MiLCB2YWx1ZSk7DQogIH0gZWxzZSB7DQogICAgZWwuY2xhc3NOYW1lID0gdmFsdWU7DQogIH0NCn0NCg0KY29uc3QgdlNob3dPcmlnaW5hbERpc3BsYXkgPSBTeW1ib2woIl92b2QiKTsNCmNvbnN0IHZTaG93SGlkZGVuID0gU3ltYm9sKCJfdnNoIik7DQpjb25zdCB2U2hvdyA9IHsNCiAgYmVmb3JlTW91bnQoZWwsIHsgdmFsdWUgfSwgeyB0cmFuc2l0aW9uIH0pIHsNCiAgICBlbFt2U2hvd09yaWdpbmFsRGlzcGxheV0gPSBlbC5zdHlsZS5kaXNwbGF5ID09PSAibm9uZSIgPyAiIiA6IGVsLnN0eWxlLmRpc3BsYXk7DQogICAgaWYgKHRyYW5zaXRpb24gJiYgdmFsdWUpIHsNCiAgICAgIHRyYW5zaXRpb24uYmVmb3JlRW50ZXIoZWwpOw0KICAgIH0gZWxzZSB7DQogICAgICBzZXREaXNwbGF5KGVsLCB2YWx1ZSk7DQogICAgfQ0KICB9LA0KICBtb3VudGVkKGVsLCB7IHZhbHVlIH0sIHsgdHJhbnNpdGlvbiB9KSB7DQogICAgaWYgKHRyYW5zaXRpb24gJiYgdmFsdWUpIHsNCiAgICAgIHRyYW5zaXRpb24uZW50ZXIoZWwpOw0KICAgIH0NCiAgfSwNCiAgdXBkYXRlZChlbCwgeyB2YWx1ZSwgb2xkVmFsdWUgfSwgeyB0cmFuc2l0aW9uIH0pIHsNCiAgICBpZiAoIXZhbHVlID09PSAhb2xkVmFsdWUpIHJldHVybjsNCiAgICBpZiAodHJhbnNpdGlvbikgew0KICAgICAgaWYgKHZhbHVlKSB7DQogICAgICAgIHRyYW5zaXRpb24uYmVmb3JlRW50ZXIoZWwpOw0KICAgICAgICBzZXREaXNwbGF5KGVsLCB0cnVlKTsNCiAgICAgICAgdHJhbnNpdGlvbi5lbnRlcihlbCk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICB0cmFuc2l0aW9uLmxlYXZlKGVsLCAoKSA9PiB7DQogICAgICAgICAgc2V0RGlzcGxheShlbCwgZmFsc2UpOw0KICAgICAgICB9KTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgc2V0RGlzcGxheShlbCwgdmFsdWUpOw0KICAgIH0NCiAgfSwNCiAgYmVmb3JlVW5tb3VudChlbCwgeyB2YWx1ZSB9KSB7DQogICAgc2V0RGlzcGxheShlbCwgdmFsdWUpOw0KICB9DQp9Ow0Kew0KICB2U2hvdy5uYW1lID0gInNob3ciOw0KfQ0KZnVuY3Rpb24gc2V0RGlzcGxheShlbCwgdmFsdWUpIHsNCiAgZWwuc3R5bGUuZGlzcGxheSA9IHZhbHVlID8gZWxbdlNob3dPcmlnaW5hbERpc3BsYXldIDogIm5vbmUiOw0KICBlbFt2U2hvd0hpZGRlbl0gPSAhdmFsdWU7DQp9DQpmdW5jdGlvbiBpbml0VlNob3dGb3JTU1IoKSB7DQogIHZTaG93LmdldFNTUlByb3BzID0gKHsgdmFsdWUgfSkgPT4gew0KICAgIGlmICghdmFsdWUpIHsNCiAgICAgIHJldHVybiB7IHN0eWxlOiB7IGRpc3BsYXk6ICJub25lIiB9IH07DQogICAgfQ0KICB9Ow0KfQ0KDQpjb25zdCBDU1NfVkFSX1RFWFQgPSBTeW1ib2woIkNTU19WQVJfVEVYVCIgKTsNCmZ1bmN0aW9uIHVzZUNzc1ZhcnMoZ2V0dGVyKSB7DQogIGNvbnN0IGluc3RhbmNlID0gZ2V0Q3VycmVudEluc3RhbmNlKCk7DQogIGlmICghaW5zdGFuY2UpIHsNCiAgICB3YXJuKGB1c2VDc3NWYXJzIGlzIGNhbGxlZCB3aXRob3V0IGN1cnJlbnQgYWN0aXZlIGNvbXBvbmVudCBpbnN0YW5jZS5gKTsNCiAgICByZXR1cm47DQogIH0NCiAgY29uc3QgdXBkYXRlVGVsZXBvcnRzID0gaW5zdGFuY2UudXQgPSAodmFycyA9IGdldHRlcihpbnN0YW5jZS5wcm94eSkpID0+IHsNCiAgICBBcnJheS5mcm9tKA0KICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChgW2RhdGEtdi1vd25lcj0iJHtpbnN0YW5jZS51aWR9Il1gKQ0KICAgICkuZm9yRWFjaCgobm9kZSkgPT4gc2V0VmFyc09uTm9kZShub2RlLCB2YXJzKSk7DQogIH07DQogIHsNCiAgICBpbnN0YW5jZS5nZXRDc3NWYXJzID0gKCkgPT4gZ2V0dGVyKGluc3RhbmNlLnByb3h5KTsNCiAgfQ0KICBjb25zdCBzZXRWYXJzID0gKCkgPT4gew0KICAgIGNvbnN0IHZhcnMgPSBnZXR0ZXIoaW5zdGFuY2UucHJveHkpOw0KICAgIGlmIChpbnN0YW5jZS5jZSkgew0KICAgICAgc2V0VmFyc09uTm9kZShpbnN0YW5jZS5jZSwgdmFycyk7DQogICAgfSBlbHNlIHsNCiAgICAgIHNldFZhcnNPblZOb2RlKGluc3RhbmNlLnN1YlRyZWUsIHZhcnMpOw0KICAgIH0NCiAgICB1cGRhdGVUZWxlcG9ydHModmFycyk7DQogIH07DQogIG9uQmVmb3JlVXBkYXRlKCgpID0+IHsNCiAgICBxdWV1ZVBvc3RGbHVzaENiKHNldFZhcnMpOw0KICB9KTsNCiAgb25Nb3VudGVkKCgpID0+IHsNCiAgICB3YXRjaChzZXRWYXJzLCBOT09QLCB7IGZsdXNoOiAicG9zdCIgfSk7DQogICAgY29uc3Qgb2IgPSBuZXcgTXV0YXRpb25PYnNlcnZlcihzZXRWYXJzKTsNCiAgICBvYi5vYnNlcnZlKGluc3RhbmNlLnN1YlRyZWUuZWwucGFyZW50Tm9kZSwgeyBjaGlsZExpc3Q6IHRydWUgfSk7DQogICAgb25Vbm1vdW50ZWQoKCkgPT4gb2IuZGlzY29ubmVjdCgpKTsNCiAgfSk7DQp9DQpmdW5jdGlvbiBzZXRWYXJzT25WTm9kZSh2bm9kZSwgdmFycykgew0KICBpZiAodm5vZGUuc2hhcGVGbGFnICYgMTI4KSB7DQogICAgY29uc3Qgc3VzcGVuc2UgPSB2bm9kZS5zdXNwZW5zZTsNCiAgICB2bm9kZSA9IHN1c3BlbnNlLmFjdGl2ZUJyYW5jaDsNCiAgICBpZiAoc3VzcGVuc2UucGVuZGluZ0JyYW5jaCAmJiAhc3VzcGVuc2UuaXNIeWRyYXRpbmcpIHsNCiAgICAgIHN1c3BlbnNlLmVmZmVjdHMucHVzaCgoKSA9PiB7DQogICAgICAgIHNldFZhcnNPblZOb2RlKHN1c3BlbnNlLmFjdGl2ZUJyYW5jaCwgdmFycyk7DQogICAgICB9KTsNCiAgICB9DQogIH0NCiAgd2hpbGUgKHZub2RlLmNvbXBvbmVudCkgew0KICAgIHZub2RlID0gdm5vZGUuY29tcG9uZW50LnN1YlRyZWU7DQogIH0NCiAgaWYgKHZub2RlLnNoYXBlRmxhZyAmIDEgJiYgdm5vZGUuZWwpIHsNCiAgICBzZXRWYXJzT25Ob2RlKHZub2RlLmVsLCB2YXJzKTsNCiAgfSBlbHNlIGlmICh2bm9kZS50eXBlID09PSBGcmFnbWVudCkgew0KICAgIHZub2RlLmNoaWxkcmVuLmZvckVhY2goKGMpID0+IHNldFZhcnNPblZOb2RlKGMsIHZhcnMpKTsNCiAgfSBlbHNlIGlmICh2bm9kZS50eXBlID09PSBTdGF0aWMpIHsNCiAgICBsZXQgeyBlbCwgYW5jaG9yIH0gPSB2bm9kZTsNCiAgICB3aGlsZSAoZWwpIHsNCiAgICAgIHNldFZhcnNPbk5vZGUoZWwsIHZhcnMpOw0KICAgICAgaWYgKGVsID09PSBhbmNob3IpIGJyZWFrOw0KICAgICAgZWwgPSBlbC5uZXh0U2libGluZzsNCiAgICB9DQogIH0NCn0NCmZ1bmN0aW9uIHNldFZhcnNPbk5vZGUoZWwsIHZhcnMpIHsNCiAgaWYgKGVsLm5vZGVUeXBlID09PSAxKSB7DQogICAgY29uc3Qgc3R5bGUgPSBlbC5zdHlsZTsNCiAgICBsZXQgY3NzVGV4dCA9ICIiOw0KICAgIGZvciAoY29uc3Qga2V5IGluIHZhcnMpIHsNCiAgICAgIHN0eWxlLnNldFByb3BlcnR5KGAtLSR7a2V5fWAsIHZhcnNba2V5XSk7DQogICAgICBjc3NUZXh0ICs9IGAtLSR7a2V5fTogJHt2YXJzW2tleV19O2A7DQogICAgfQ0KICAgIHN0eWxlW0NTU19WQVJfVEVYVF0gPSBjc3NUZXh0Ow0KICB9DQp9DQoNCmNvbnN0IGRpc3BsYXlSRSA9IC8oXnw7KVxzKmRpc3BsYXlccyo6LzsNCmZ1bmN0aW9uIHBhdGNoU3R5bGUoZWwsIHByZXYsIG5leHQpIHsNCiAgY29uc3Qgc3R5bGUgPSBlbC5zdHlsZTsNCiAgY29uc3QgaXNDc3NTdHJpbmcgPSBpc1N0cmluZyhuZXh0KTsNCiAgbGV0IGhhc0NvbnRyb2xsZWREaXNwbGF5ID0gZmFsc2U7DQogIGlmIChuZXh0ICYmICFpc0Nzc1N0cmluZykgew0KICAgIGlmIChwcmV2KSB7DQogICAgICBpZiAoIWlzU3RyaW5nKHByZXYpKSB7DQogICAgICAgIGZvciAoY29uc3Qga2V5IGluIHByZXYpIHsNCiAgICAgICAgICBpZiAobmV4dFtrZXldID09IG51bGwpIHsNCiAgICAgICAgICAgIHNldFN0eWxlKHN0eWxlLCBrZXksICIiKTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGZvciAoY29uc3QgcHJldlN0eWxlIG9mIHByZXYuc3BsaXQoIjsiKSkgew0KICAgICAgICAgIGNvbnN0IGtleSA9IHByZXZTdHlsZS5zbGljZSgwLCBwcmV2U3R5bGUuaW5kZXhPZigiOiIpKS50cmltKCk7DQogICAgICAgICAgaWYgKG5leHRba2V5XSA9PSBudWxsKSB7DQogICAgICAgICAgICBzZXRTdHlsZShzdHlsZSwga2V5LCAiIik7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICAgIGZvciAoY29uc3Qga2V5IGluIG5leHQpIHsNCiAgICAgIGlmIChrZXkgPT09ICJkaXNwbGF5Iikgew0KICAgICAgICBoYXNDb250cm9sbGVkRGlzcGxheSA9IHRydWU7DQogICAgICB9DQogICAgICBzZXRTdHlsZShzdHlsZSwga2V5LCBuZXh0W2tleV0pOw0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICBpZiAoaXNDc3NTdHJpbmcpIHsNCiAgICAgIGlmIChwcmV2ICE9PSBuZXh0KSB7DQogICAgICAgIGNvbnN0IGNzc1ZhclRleHQgPSBzdHlsZVtDU1NfVkFSX1RFWFRdOw0KICAgICAgICBpZiAoY3NzVmFyVGV4dCkgew0KICAgICAgICAgIG5leHQgKz0gIjsiICsgY3NzVmFyVGV4dDsNCiAgICAgICAgfQ0KICAgICAgICBzdHlsZS5jc3NUZXh0ID0gbmV4dDsNCiAgICAgICAgaGFzQ29udHJvbGxlZERpc3BsYXkgPSBkaXNwbGF5UkUudGVzdChuZXh0KTsNCiAgICAgIH0NCiAgICB9IGVsc2UgaWYgKHByZXYpIHsNCiAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZSgic3R5bGUiKTsNCiAgICB9DQogIH0NCiAgaWYgKHZTaG93T3JpZ2luYWxEaXNwbGF5IGluIGVsKSB7DQogICAgZWxbdlNob3dPcmlnaW5hbERpc3BsYXldID0gaGFzQ29udHJvbGxlZERpc3BsYXkgPyBzdHlsZS5kaXNwbGF5IDogIiI7DQogICAgaWYgKGVsW3ZTaG93SGlkZGVuXSkgew0KICAgICAgc3R5bGUuZGlzcGxheSA9ICJub25lIjsNCiAgICB9DQogIH0NCn0NCmNvbnN0IHNlbWljb2xvblJFID0gL1teXFxdO1xzKiQvOw0KY29uc3QgaW1wb3J0YW50UkUgPSAvXHMqIWltcG9ydGFudCQvOw0KZnVuY3Rpb24gc2V0U3R5bGUoc3R5bGUsIG5hbWUsIHZhbCkgew0KICBpZiAoaXNBcnJheSh2YWwpKSB7DQogICAgdmFsLmZvckVhY2goKHYpID0+IHNldFN0eWxlKHN0eWxlLCBuYW1lLCB2KSk7DQogIH0gZWxzZSB7DQogICAgaWYgKHZhbCA9PSBudWxsKSB2YWwgPSAiIjsNCiAgICB7DQogICAgICBpZiAoc2VtaWNvbG9uUkUudGVzdCh2YWwpKSB7DQogICAgICAgIHdhcm4oDQogICAgICAgICAgYFVuZXhwZWN0ZWQgc2VtaWNvbG9uIGF0IHRoZSBlbmQgb2YgJyR7bmFtZX0nIHN0eWxlIHZhbHVlOiAnJHt2YWx9J2ANCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICB9DQogICAgaWYgKG5hbWUuc3RhcnRzV2l0aCgiLS0iKSkgew0KICAgICAgc3R5bGUuc2V0UHJvcGVydHkobmFtZSwgdmFsKTsNCiAgICB9IGVsc2Ugew0KICAgICAgY29uc3QgcHJlZml4ZWQgPSBhdXRvUHJlZml4KHN0eWxlLCBuYW1lKTsNCiAgICAgIGlmIChpbXBvcnRhbnRSRS50ZXN0KHZhbCkpIHsNCiAgICAgICAgc3R5bGUuc2V0UHJvcGVydHkoDQogICAgICAgICAgaHlwaGVuYXRlKHByZWZpeGVkKSwNCiAgICAgICAgICB2YWwucmVwbGFjZShpbXBvcnRhbnRSRSwgIiIpLA0KICAgICAgICAgICJpbXBvcnRhbnQiDQogICAgICAgICk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBzdHlsZVtwcmVmaXhlZF0gPSB2YWw7DQogICAgICB9DQogICAgfQ0KICB9DQp9DQpjb25zdCBwcmVmaXhlcyA9IFsiV2Via2l0IiwgIk1veiIsICJtcyJdOw0KY29uc3QgcHJlZml4Q2FjaGUgPSB7fTsNCmZ1bmN0aW9uIGF1dG9QcmVmaXgoc3R5bGUsIHJhd05hbWUpIHsNCiAgY29uc3QgY2FjaGVkID0gcHJlZml4Q2FjaGVbcmF3TmFtZV07DQogIGlmIChjYWNoZWQpIHsNCiAgICByZXR1cm4gY2FjaGVkOw0KICB9DQogIGxldCBuYW1lID0gY2FtZWxpemUocmF3TmFtZSk7DQogIGlmIChuYW1lICE9PSAiZmlsdGVyIiAmJiBuYW1lIGluIHN0eWxlKSB7DQogICAgcmV0dXJuIHByZWZpeENhY2hlW3Jhd05hbWVdID0gbmFtZTsNCiAgfQ0KICBuYW1lID0gY2FwaXRhbGl6ZShuYW1lKTsNCiAgZm9yIChsZXQgaSA9IDA7IGkgPCBwcmVmaXhlcy5sZW5ndGg7IGkrKykgew0KICAgIGNvbnN0IHByZWZpeGVkID0gcHJlZml4ZXNbaV0gKyBuYW1lOw0KICAgIGlmIChwcmVmaXhlZCBpbiBzdHlsZSkgew0KICAgICAgcmV0dXJuIHByZWZpeENhY2hlW3Jhd05hbWVdID0gcHJlZml4ZWQ7DQogICAgfQ0KICB9DQogIHJldHVybiByYXdOYW1lOw0KfQ0KDQpjb25zdCB4bGlua05TID0gImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiOw0KZnVuY3Rpb24gcGF0Y2hBdHRyKGVsLCBrZXksIHZhbHVlLCBpc1NWRywgaW5zdGFuY2UsIGlzQm9vbGVhbiA9IGlzU3BlY2lhbEJvb2xlYW5BdHRyKGtleSkpIHsNCiAgaWYgKGlzU1ZHICYmIGtleS5zdGFydHNXaXRoKCJ4bGluazoiKSkgew0KICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7DQogICAgICBlbC5yZW1vdmVBdHRyaWJ1dGVOUyh4bGlua05TLCBrZXkuc2xpY2UoNiwga2V5Lmxlbmd0aCkpOw0KICAgIH0gZWxzZSB7DQogICAgICBlbC5zZXRBdHRyaWJ1dGVOUyh4bGlua05TLCBrZXksIHZhbHVlKTsNCiAgICB9DQogIH0gZWxzZSB7DQogICAgaWYgKHZhbHVlID09IG51bGwgfHwgaXNCb29sZWFuICYmICFpbmNsdWRlQm9vbGVhbkF0dHIodmFsdWUpKSB7DQogICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoa2V5KTsNCiAgICB9IGVsc2Ugew0KICAgICAgZWwuc2V0QXR0cmlidXRlKA0KICAgICAgICBrZXksDQogICAgICAgIGlzQm9vbGVhbiA/ICIiIDogaXNTeW1ib2wodmFsdWUpID8gU3RyaW5nKHZhbHVlKSA6IHZhbHVlDQogICAgICApOw0KICAgIH0NCiAgfQ0KfQ0KDQpmdW5jdGlvbiBwYXRjaERPTVByb3AoZWwsIGtleSwgdmFsdWUsIHBhcmVudENvbXBvbmVudCwgYXR0ck5hbWUpIHsNCiAgaWYgKGtleSA9PT0gImlubmVySFRNTCIgfHwga2V5ID09PSAidGV4dENvbnRlbnQiKSB7DQogICAgaWYgKHZhbHVlICE9IG51bGwpIHsNCiAgICAgIGVsW2tleV0gPSBrZXkgPT09ICJpbm5lckhUTUwiID8gdW5zYWZlVG9UcnVzdGVkSFRNTCh2YWx1ZSkgOiB2YWx1ZTsNCiAgICB9DQogICAgcmV0dXJuOw0KICB9DQogIGNvbnN0IHRhZyA9IGVsLnRhZ05hbWU7DQogIGlmIChrZXkgPT09ICJ2YWx1ZSIgJiYgdGFnICE9PSAiUFJPR1JFU1MiICYmIC8vIGN1c3RvbSBlbGVtZW50cyBtYXkgdXNlIF92YWx1ZSBpbnRlcm5hbGx5DQogICF0YWcuaW5jbHVkZXMoIi0iKSkgew0KICAgIGNvbnN0IG9sZFZhbHVlID0gdGFnID09PSAiT1BUSU9OIiA/IGVsLmdldEF0dHJpYnV0ZSgidmFsdWUiKSB8fCAiIiA6IGVsLnZhbHVlOw0KICAgIGNvbnN0IG5ld1ZhbHVlID0gdmFsdWUgPT0gbnVsbCA/ICgNCiAgICAgIC8vICMxMTY0NzogdmFsdWUgc2hvdWxkIGJlIHNldCBhcyBlbXB0eSBzdHJpbmcgZm9yIG51bGwgYW5kIHVuZGVmaW5lZCwNCiAgICAgIC8vIGJ1dCA8aW5wdXQgdHlwZT0iY2hlY2tib3giPiBzaG91bGQgYmUgc2V0IGFzICdvbicuDQogICAgICBlbC50eXBlID09PSAiY2hlY2tib3giID8gIm9uIiA6ICIiDQogICAgKSA6IFN0cmluZyh2YWx1ZSk7DQogICAgaWYgKG9sZFZhbHVlICE9PSBuZXdWYWx1ZSB8fCAhKCJfdmFsdWUiIGluIGVsKSkgew0KICAgICAgZWwudmFsdWUgPSBuZXdWYWx1ZTsNCiAgICB9DQogICAgaWYgKHZhbHVlID09IG51bGwpIHsNCiAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZShrZXkpOw0KICAgIH0NCiAgICBlbC5fdmFsdWUgPSB2YWx1ZTsNCiAgICByZXR1cm47DQogIH0NCiAgbGV0IG5lZWRSZW1vdmUgPSBmYWxzZTsNCiAgaWYgKHZhbHVlID09PSAiIiB8fCB2YWx1ZSA9PSBudWxsKSB7DQogICAgY29uc3QgdHlwZSA9IHR5cGVvZiBlbFtrZXldOw0KICAgIGlmICh0eXBlID09PSAiYm9vbGVhbiIpIHsNCiAgICAgIHZhbHVlID0gaW5jbHVkZUJvb2xlYW5BdHRyKHZhbHVlKTsNCiAgICB9IGVsc2UgaWYgKHZhbHVlID09IG51bGwgJiYgdHlwZSA9PT0gInN0cmluZyIpIHsNCiAgICAgIHZhbHVlID0gIiI7DQogICAgICBuZWVkUmVtb3ZlID0gdHJ1ZTsNCiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICJudW1iZXIiKSB7DQogICAgICB2YWx1ZSA9IDA7DQogICAgICBuZWVkUmVtb3ZlID0gdHJ1ZTsNCiAgICB9DQogIH0NCiAgdHJ5IHsNCiAgICBlbFtrZXldID0gdmFsdWU7DQogIH0gY2F0Y2ggKGUpIHsNCiAgICBpZiAoIW5lZWRSZW1vdmUpIHsNCiAgICAgIHdhcm4oDQogICAgICAgIGBGYWlsZWQgc2V0dGluZyBwcm9wICIke2tleX0iIG9uIDwke3RhZy50b0xvd2VyQ2FzZSgpfT46IHZhbHVlICR7dmFsdWV9IGlzIGludmFsaWQuYCwNCiAgICAgICAgZQ0KICAgICAgKTsNCiAgICB9DQogIH0NCiAgbmVlZFJlbW92ZSAmJiBlbC5yZW1vdmVBdHRyaWJ1dGUoYXR0ck5hbWUgfHwga2V5KTsNCn0NCg0KZnVuY3Rpb24gYWRkRXZlbnRMaXN0ZW5lcihlbCwgZXZlbnQsIGhhbmRsZXIsIG9wdGlvbnMpIHsNCiAgZWwuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgaGFuZGxlciwgb3B0aW9ucyk7DQp9DQpmdW5jdGlvbiByZW1vdmVFdmVudExpc3RlbmVyKGVsLCBldmVudCwgaGFuZGxlciwgb3B0aW9ucykgew0KICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50LCBoYW5kbGVyLCBvcHRpb25zKTsNCn0NCmNvbnN0IHZlaUtleSA9IFN5bWJvbCgiX3ZlaSIpOw0KZnVuY3Rpb24gcGF0Y2hFdmVudChlbCwgcmF3TmFtZSwgcHJldlZhbHVlLCBuZXh0VmFsdWUsIGluc3RhbmNlID0gbnVsbCkgew0KICBjb25zdCBpbnZva2VycyA9IGVsW3ZlaUtleV0gfHwgKGVsW3ZlaUtleV0gPSB7fSk7DQogIGNvbnN0IGV4aXN0aW5nSW52b2tlciA9IGludm9rZXJzW3Jhd05hbWVdOw0KICBpZiAobmV4dFZhbHVlICYmIGV4aXN0aW5nSW52b2tlcikgew0KICAgIGV4aXN0aW5nSW52b2tlci52YWx1ZSA9IHNhbml0aXplRXZlbnRWYWx1ZShuZXh0VmFsdWUsIHJhd05hbWUpIDsNCiAgfSBlbHNlIHsNCiAgICBjb25zdCBbbmFtZSwgb3B0aW9uc10gPSBwYXJzZU5hbWUocmF3TmFtZSk7DQogICAgaWYgKG5leHRWYWx1ZSkgew0KICAgICAgY29uc3QgaW52b2tlciA9IGludm9rZXJzW3Jhd05hbWVdID0gY3JlYXRlSW52b2tlcigNCiAgICAgICAgc2FuaXRpemVFdmVudFZhbHVlKG5leHRWYWx1ZSwgcmF3TmFtZSkgLA0KICAgICAgICBpbnN0YW5jZQ0KICAgICAgKTsNCiAgICAgIGFkZEV2ZW50TGlzdGVuZXIoZWwsIG5hbWUsIGludm9rZXIsIG9wdGlvbnMpOw0KICAgIH0gZWxzZSBpZiAoZXhpc3RpbmdJbnZva2VyKSB7DQogICAgICByZW1vdmVFdmVudExpc3RlbmVyKGVsLCBuYW1lLCBleGlzdGluZ0ludm9rZXIsIG9wdGlvbnMpOw0KICAgICAgaW52b2tlcnNbcmF3TmFtZV0gPSB2b2lkIDA7DQogICAgfQ0KICB9DQp9DQpjb25zdCBvcHRpb25zTW9kaWZpZXJSRSA9IC8oPzpPbmNlfFBhc3NpdmV8Q2FwdHVyZSkkLzsNCmZ1bmN0aW9uIHBhcnNlTmFtZShuYW1lKSB7DQogIGxldCBvcHRpb25zOw0KICBpZiAob3B0aW9uc01vZGlmaWVyUkUudGVzdChuYW1lKSkgew0KICAgIG9wdGlvbnMgPSB7fTsNCiAgICBsZXQgbTsNCiAgICB3aGlsZSAobSA9IG5hbWUubWF0Y2gob3B0aW9uc01vZGlmaWVyUkUpKSB7DQogICAgICBuYW1lID0gbmFtZS5zbGljZSgwLCBuYW1lLmxlbmd0aCAtIG1bMF0ubGVuZ3RoKTsNCiAgICAgIG9wdGlvbnNbbVswXS50b0xvd2VyQ2FzZSgpXSA9IHRydWU7DQogICAgfQ0KICB9DQogIGNvbnN0IGV2ZW50ID0gbmFtZVsyXSA9PT0gIjoiID8gbmFtZS5zbGljZSgzKSA6IGh5cGhlbmF0ZShuYW1lLnNsaWNlKDIpKTsNCiAgcmV0dXJuIFtldmVudCwgb3B0aW9uc107DQp9DQpsZXQgY2FjaGVkTm93ID0gMDsNCmNvbnN0IHAgPSAvKiBAX19QVVJFX18gKi8gUHJvbWlzZS5yZXNvbHZlKCk7DQpjb25zdCBnZXROb3cgPSAoKSA9PiBjYWNoZWROb3cgfHwgKHAudGhlbigoKSA9PiBjYWNoZWROb3cgPSAwKSwgY2FjaGVkTm93ID0gRGF0ZS5ub3coKSk7DQpmdW5jdGlvbiBjcmVhdGVJbnZva2VyKGluaXRpYWxWYWx1ZSwgaW5zdGFuY2UpIHsNCiAgY29uc3QgaW52b2tlciA9IChlKSA9PiB7DQogICAgaWYgKCFlLl92dHMpIHsNCiAgICAgIGUuX3Z0cyA9IERhdGUubm93KCk7DQogICAgfSBlbHNlIGlmIChlLl92dHMgPD0gaW52b2tlci5hdHRhY2hlZCkgew0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZygNCiAgICAgIHBhdGNoU3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKGUsIGludm9rZXIudmFsdWUpLA0KICAgICAgaW5zdGFuY2UsDQogICAgICA1LA0KICAgICAgW2VdDQogICAgKTsNCiAgfTsNCiAgaW52b2tlci52YWx1ZSA9IGluaXRpYWxWYWx1ZTsNCiAgaW52b2tlci5hdHRhY2hlZCA9IGdldE5vdygpOw0KICByZXR1cm4gaW52b2tlcjsNCn0NCmZ1bmN0aW9uIHNhbml0aXplRXZlbnRWYWx1ZSh2YWx1ZSwgcHJvcE5hbWUpIHsNCiAgaWYgKGlzRnVuY3Rpb24odmFsdWUpIHx8IGlzQXJyYXkodmFsdWUpKSB7DQogICAgcmV0dXJuIHZhbHVlOw0KICB9DQogIHdhcm4oDQogICAgYFdyb25nIHR5cGUgcGFzc2VkIGFzIGV2ZW50IGhhbmRsZXIgdG8gJHtwcm9wTmFtZX0gLSBkaWQgeW91IGZvcmdldCBAIG9yIDogaW4gZnJvbnQgb2YgeW91ciBwcm9wPw0KRXhwZWN0ZWQgZnVuY3Rpb24gb3IgYXJyYXkgb2YgZnVuY3Rpb25zLCByZWNlaXZlZCB0eXBlICR7dHlwZW9mIHZhbHVlfS5gDQogICk7DQogIHJldHVybiBOT09QOw0KfQ0KZnVuY3Rpb24gcGF0Y2hTdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oZSwgdmFsdWUpIHsNCiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7DQogICAgY29uc3Qgb3JpZ2luYWxTdG9wID0gZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb247DQogICAgZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24gPSAoKSA9PiB7DQogICAgICBvcmlnaW5hbFN0b3AuY2FsbChlKTsNCiAgICAgIGUuX3N0b3BwZWQgPSB0cnVlOw0KICAgIH07DQogICAgcmV0dXJuIHZhbHVlLm1hcCgNCiAgICAgIChmbikgPT4gKGUyKSA9PiAhZTIuX3N0b3BwZWQgJiYgZm4gJiYgZm4oZTIpDQogICAgKTsNCiAgfSBlbHNlIHsNCiAgICByZXR1cm4gdmFsdWU7DQogIH0NCn0NCg0KY29uc3QgaXNOYXRpdmVPbiA9IChrZXkpID0+IGtleS5jaGFyQ29kZUF0KDApID09PSAxMTEgJiYga2V5LmNoYXJDb2RlQXQoMSkgPT09IDExMCAmJiAvLyBsb3dlcmNhc2UgbGV0dGVyDQprZXkuY2hhckNvZGVBdCgyKSA+IDk2ICYmIGtleS5jaGFyQ29kZUF0KDIpIDwgMTIzOw0KY29uc3QgcGF0Y2hQcm9wID0gKGVsLCBrZXksIHByZXZWYWx1ZSwgbmV4dFZhbHVlLCBuYW1lc3BhY2UsIHBhcmVudENvbXBvbmVudCkgPT4gew0KICBjb25zdCBpc1NWRyA9IG5hbWVzcGFjZSA9PT0gInN2ZyI7DQogIGlmIChrZXkgPT09ICJjbGFzcyIpIHsNCiAgICBwYXRjaENsYXNzKGVsLCBuZXh0VmFsdWUsIGlzU1ZHKTsNCiAgfSBlbHNlIGlmIChrZXkgPT09ICJzdHlsZSIpIHsNCiAgICBwYXRjaFN0eWxlKGVsLCBwcmV2VmFsdWUsIG5leHRWYWx1ZSk7DQogIH0gZWxzZSBpZiAoaXNPbihrZXkpKSB7DQogICAgaWYgKCFpc01vZGVsTGlzdGVuZXIoa2V5KSkgew0KICAgICAgcGF0Y2hFdmVudChlbCwga2V5LCBwcmV2VmFsdWUsIG5leHRWYWx1ZSwgcGFyZW50Q29tcG9uZW50KTsNCiAgICB9DQogIH0gZWxzZSBpZiAoa2V5WzBdID09PSAiLiIgPyAoa2V5ID0ga2V5LnNsaWNlKDEpLCB0cnVlKSA6IGtleVswXSA9PT0gIl4iID8gKGtleSA9IGtleS5zbGljZSgxKSwgZmFsc2UpIDogc2hvdWxkU2V0QXNQcm9wKGVsLCBrZXksIG5leHRWYWx1ZSwgaXNTVkcpKSB7DQogICAgcGF0Y2hET01Qcm9wKGVsLCBrZXksIG5leHRWYWx1ZSk7DQogICAgaWYgKCFlbC50YWdOYW1lLmluY2x1ZGVzKCItIikgJiYgKGtleSA9PT0gInZhbHVlIiB8fCBrZXkgPT09ICJjaGVja2VkIiB8fCBrZXkgPT09ICJzZWxlY3RlZCIpKSB7DQogICAgICBwYXRjaEF0dHIoZWwsIGtleSwgbmV4dFZhbHVlLCBpc1NWRywgcGFyZW50Q29tcG9uZW50LCBrZXkgIT09ICJ2YWx1ZSIpOw0KICAgIH0NCiAgfSBlbHNlIGlmICgNCiAgICAvLyAjMTEwODEgZm9yY2Ugc2V0IHByb3BzIGZvciBwb3NzaWJsZSBhc3luYyBjdXN0b20gZWxlbWVudA0KICAgIGVsLl9pc1Z1ZUNFICYmICgvW0EtWl0vLnRlc3Qoa2V5KSB8fCAhaXNTdHJpbmcobmV4dFZhbHVlKSkNCiAgKSB7DQogICAgcGF0Y2hET01Qcm9wKGVsLCBjYW1lbGl6ZShrZXkpLCBuZXh0VmFsdWUsIHBhcmVudENvbXBvbmVudCwga2V5KTsNCiAgfSBlbHNlIHsNCiAgICBpZiAoa2V5ID09PSAidHJ1ZS12YWx1ZSIpIHsNCiAgICAgIGVsLl90cnVlVmFsdWUgPSBuZXh0VmFsdWU7DQogICAgfSBlbHNlIGlmIChrZXkgPT09ICJmYWxzZS12YWx1ZSIpIHsNCiAgICAgIGVsLl9mYWxzZVZhbHVlID0gbmV4dFZhbHVlOw0KICAgIH0NCiAgICBwYXRjaEF0dHIoZWwsIGtleSwgbmV4dFZhbHVlLCBpc1NWRyk7DQogIH0NCn07DQpmdW5jdGlvbiBzaG91bGRTZXRBc1Byb3AoZWwsIGtleSwgdmFsdWUsIGlzU1ZHKSB7DQogIGlmIChpc1NWRykgew0KICAgIGlmIChrZXkgPT09ICJpbm5lckhUTUwiIHx8IGtleSA9PT0gInRleHRDb250ZW50Iikgew0KICAgICAgcmV0dXJuIHRydWU7DQogICAgfQ0KICAgIGlmIChrZXkgaW4gZWwgJiYgaXNOYXRpdmVPbihrZXkpICYmIGlzRnVuY3Rpb24odmFsdWUpKSB7DQogICAgICByZXR1cm4gdHJ1ZTsNCiAgICB9DQogICAgcmV0dXJuIGZhbHNlOw0KICB9DQogIGlmIChrZXkgPT09ICJzcGVsbGNoZWNrIiB8fCBrZXkgPT09ICJkcmFnZ2FibGUiIHx8IGtleSA9PT0gInRyYW5zbGF0ZSIgfHwga2V5ID09PSAiYXV0b2NvcnJlY3QiKSB7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9DQogIGlmIChrZXkgPT09ICJmb3JtIikgew0KICAgIHJldHVybiBmYWxzZTsNCiAgfQ0KICBpZiAoa2V5ID09PSAibGlzdCIgJiYgZWwudGFnTmFtZSA9PT0gIklOUFVUIikgew0KICAgIHJldHVybiBmYWxzZTsNCiAgfQ0KICBpZiAoa2V5ID09PSAidHlwZSIgJiYgZWwudGFnTmFtZSA9PT0gIlRFWFRBUkVBIikgew0KICAgIHJldHVybiBmYWxzZTsNCiAgfQ0KICBpZiAoa2V5ID09PSAid2lkdGgiIHx8IGtleSA9PT0gImhlaWdodCIpIHsNCiAgICBjb25zdCB0YWcgPSBlbC50YWdOYW1lOw0KICAgIGlmICh0YWcgPT09ICJJTUciIHx8IHRhZyA9PT0gIlZJREVPIiB8fCB0YWcgPT09ICJDQU5WQVMiIHx8IHRhZyA9PT0gIlNPVVJDRSIpIHsNCiAgICAgIHJldHVybiBmYWxzZTsNCiAgICB9DQogIH0NCiAgaWYgKGlzTmF0aXZlT24oa2V5KSAmJiBpc1N0cmluZyh2YWx1ZSkpIHsNCiAgICByZXR1cm4gZmFsc2U7DQogIH0NCiAgcmV0dXJuIGtleSBpbiBlbDsNCn0NCg0KY29uc3QgUkVNT1ZBTCA9IHt9Ow0KLyohICNfX05PX1NJREVfRUZGRUNUU19fICovDQovLyBAX19OT19TSURFX0VGRkVDVFNfXw0KZnVuY3Rpb24gZGVmaW5lQ3VzdG9tRWxlbWVudChvcHRpb25zLCBleHRyYU9wdGlvbnMsIF9jcmVhdGVBcHApIHsNCiAgY29uc3QgQ29tcCA9IGRlZmluZUNvbXBvbmVudChvcHRpb25zLCBleHRyYU9wdGlvbnMpOw0KICBpZiAoaXNQbGFpbk9iamVjdChDb21wKSkgZXh0ZW5kKENvbXAsIGV4dHJhT3B0aW9ucyk7DQogIGNsYXNzIFZ1ZUN1c3RvbUVsZW1lbnQgZXh0ZW5kcyBWdWVFbGVtZW50IHsNCiAgICBjb25zdHJ1Y3Rvcihpbml0aWFsUHJvcHMpIHsNCiAgICAgIHN1cGVyKENvbXAsIGluaXRpYWxQcm9wcywgX2NyZWF0ZUFwcCk7DQogICAgfQ0KICB9DQogIFZ1ZUN1c3RvbUVsZW1lbnQuZGVmID0gQ29tcDsNCiAgcmV0dXJuIFZ1ZUN1c3RvbUVsZW1lbnQ7DQp9DQovKiEgI19fTk9fU0lERV9FRkZFQ1RTX18gKi8NCmNvbnN0IGRlZmluZVNTUkN1c3RvbUVsZW1lbnQgPSAvKiBAX19OT19TSURFX0VGRkVDVFNfXyAqLyAob3B0aW9ucywgZXh0cmFPcHRpb25zKSA9PiB7DQogIHJldHVybiAvKiBAX19QVVJFX18gKi8gZGVmaW5lQ3VzdG9tRWxlbWVudChvcHRpb25zLCBleHRyYU9wdGlvbnMsIGNyZWF0ZVNTUkFwcCk7DQp9Ow0KY29uc3QgQmFzZUNsYXNzID0gdHlwZW9mIEhUTUxFbGVtZW50ICE9PSAidW5kZWZpbmVkIiA/IEhUTUxFbGVtZW50IDogY2xhc3Mgew0KfTsNCmNsYXNzIFZ1ZUVsZW1lbnQgZXh0ZW5kcyBCYXNlQ2xhc3Mgew0KICBjb25zdHJ1Y3RvcihfZGVmLCBfcHJvcHMgPSB7fSwgX2NyZWF0ZUFwcCA9IGNyZWF0ZUFwcCkgew0KICAgIHN1cGVyKCk7DQogICAgdGhpcy5fZGVmID0gX2RlZjsNCiAgICB0aGlzLl9wcm9wcyA9IF9wcm9wczsNCiAgICB0aGlzLl9jcmVhdGVBcHAgPSBfY3JlYXRlQXBwOw0KICAgIHRoaXMuX2lzVnVlQ0UgPSB0cnVlOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuX2luc3RhbmNlID0gbnVsbDsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLl9hcHAgPSBudWxsOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuX25vbmNlID0gdGhpcy5fZGVmLm5vbmNlOw0KICAgIHRoaXMuX2Nvbm5lY3RlZCA9IGZhbHNlOw0KICAgIHRoaXMuX3Jlc29sdmVkID0gZmFsc2U7DQogICAgdGhpcy5fbnVtYmVyUHJvcHMgPSBudWxsOw0KICAgIHRoaXMuX3N0eWxlQ2hpbGRyZW4gPSAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtTZXQoKTsNCiAgICB0aGlzLl9vYiA9IG51bGw7DQogICAgaWYgKHRoaXMuc2hhZG93Um9vdCAmJiBfY3JlYXRlQXBwICE9PSBjcmVhdGVBcHApIHsNCiAgICAgIHRoaXMuX3Jvb3QgPSB0aGlzLnNoYWRvd1Jvb3Q7DQogICAgfSBlbHNlIHsNCiAgICAgIGlmICh0aGlzLnNoYWRvd1Jvb3QpIHsNCiAgICAgICAgd2FybigNCiAgICAgICAgICBgQ3VzdG9tIGVsZW1lbnQgaGFzIHByZS1yZW5kZXJlZCBkZWNsYXJhdGl2ZSBzaGFkb3cgcm9vdCBidXQgaXMgbm90IGRlZmluZWQgYXMgaHlkcmF0YWJsZS4gVXNlIFxgZGVmaW5lU1NSQ3VzdG9tRWxlbWVudFxgLmANCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICAgIGlmIChfZGVmLnNoYWRvd1Jvb3QgIT09IGZhbHNlKSB7DQogICAgICAgIHRoaXMuYXR0YWNoU2hhZG93KHsgbW9kZTogIm9wZW4iIH0pOw0KICAgICAgICB0aGlzLl9yb290ID0gdGhpcy5zaGFkb3dSb290Ow0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgdGhpcy5fcm9vdCA9IHRoaXM7DQogICAgICB9DQogICAgfQ0KICB9DQogIGNvbm5lY3RlZENhbGxiYWNrKCkgew0KICAgIGlmICghdGhpcy5pc0Nvbm5lY3RlZCkgcmV0dXJuOw0KICAgIGlmICghdGhpcy5zaGFkb3dSb290ICYmICF0aGlzLl9yZXNvbHZlZCkgew0KICAgICAgdGhpcy5fcGFyc2VTbG90cygpOw0KICAgIH0NCiAgICB0aGlzLl9jb25uZWN0ZWQgPSB0cnVlOw0KICAgIGxldCBwYXJlbnQgPSB0aGlzOw0KICAgIHdoaWxlIChwYXJlbnQgPSBwYXJlbnQgJiYgKHBhcmVudC5wYXJlbnROb2RlIHx8IHBhcmVudC5ob3N0KSkgew0KICAgICAgaWYgKHBhcmVudCBpbnN0YW5jZW9mIFZ1ZUVsZW1lbnQpIHsNCiAgICAgICAgdGhpcy5fcGFyZW50ID0gcGFyZW50Ow0KICAgICAgICBicmVhazsNCiAgICAgIH0NCiAgICB9DQogICAgaWYgKCF0aGlzLl9pbnN0YW5jZSkgew0KICAgICAgaWYgKHRoaXMuX3Jlc29sdmVkKSB7DQogICAgICAgIHRoaXMuX21vdW50KHRoaXMuX2RlZik7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBpZiAocGFyZW50ICYmIHBhcmVudC5fcGVuZGluZ1Jlc29sdmUpIHsNCiAgICAgICAgICB0aGlzLl9wZW5kaW5nUmVzb2x2ZSA9IHBhcmVudC5fcGVuZGluZ1Jlc29sdmUudGhlbigoKSA9PiB7DQogICAgICAgICAgICB0aGlzLl9wZW5kaW5nUmVzb2x2ZSA9IHZvaWQgMDsNCiAgICAgICAgICAgIHRoaXMuX3Jlc29sdmVEZWYoKTsNCiAgICAgICAgICB9KTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICB0aGlzLl9yZXNvbHZlRGVmKCk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH0NCiAgX3NldFBhcmVudChwYXJlbnQgPSB0aGlzLl9wYXJlbnQpIHsNCiAgICBpZiAocGFyZW50KSB7DQogICAgICB0aGlzLl9pbnN0YW5jZS5wYXJlbnQgPSBwYXJlbnQuX2luc3RhbmNlOw0KICAgICAgdGhpcy5faW5oZXJpdFBhcmVudENvbnRleHQocGFyZW50KTsNCiAgICB9DQogIH0NCiAgX2luaGVyaXRQYXJlbnRDb250ZXh0KHBhcmVudCA9IHRoaXMuX3BhcmVudCkgew0KICAgIGlmIChwYXJlbnQgJiYgdGhpcy5fYXBwKSB7DQogICAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YoDQogICAgICAgIHRoaXMuX2FwcC5fY29udGV4dC5wcm92aWRlcywNCiAgICAgICAgcGFyZW50Ll9pbnN0YW5jZS5wcm92aWRlcw0KICAgICAgKTsNCiAgICB9DQogIH0NCiAgZGlzY29ubmVjdGVkQ2FsbGJhY2soKSB7DQogICAgdGhpcy5fY29ubmVjdGVkID0gZmFsc2U7DQogICAgbmV4dFRpY2soKCkgPT4gew0KICAgICAgaWYgKCF0aGlzLl9jb25uZWN0ZWQpIHsNCiAgICAgICAgaWYgKHRoaXMuX29iKSB7DQogICAgICAgICAgdGhpcy5fb2IuZGlzY29ubmVjdCgpOw0KICAgICAgICAgIHRoaXMuX29iID0gbnVsbDsNCiAgICAgICAgfQ0KICAgICAgICB0aGlzLl9hcHAgJiYgdGhpcy5fYXBwLnVubW91bnQoKTsNCiAgICAgICAgaWYgKHRoaXMuX2luc3RhbmNlKSB0aGlzLl9pbnN0YW5jZS5jZSA9IHZvaWQgMDsNCiAgICAgICAgdGhpcy5fYXBwID0gdGhpcy5faW5zdGFuY2UgPSBudWxsOw0KICAgICAgfQ0KICAgIH0pOw0KICB9DQogIC8qKg0KICAgKiByZXNvbHZlIGlubmVyIGNvbXBvbmVudCBkZWZpbml0aW9uIChoYW5kbGUgcG9zc2libGUgYXN5bmMgY29tcG9uZW50KQ0KICAgKi8NCiAgX3Jlc29sdmVEZWYoKSB7DQogICAgaWYgKHRoaXMuX3BlbmRpbmdSZXNvbHZlKSB7DQogICAgICByZXR1cm47DQogICAgfQ0KICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5hdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKSB7DQogICAgICB0aGlzLl9zZXRBdHRyKHRoaXMuYXR0cmlidXRlc1tpXS5uYW1lKTsNCiAgICB9DQogICAgdGhpcy5fb2IgPSBuZXcgTXV0YXRpb25PYnNlcnZlcigobXV0YXRpb25zKSA9PiB7DQogICAgICBmb3IgKGNvbnN0IG0gb2YgbXV0YXRpb25zKSB7DQogICAgICAgIHRoaXMuX3NldEF0dHIobS5hdHRyaWJ1dGVOYW1lKTsNCiAgICAgIH0NCiAgICB9KTsNCiAgICB0aGlzLl9vYi5vYnNlcnZlKHRoaXMsIHsgYXR0cmlidXRlczogdHJ1ZSB9KTsNCiAgICBjb25zdCByZXNvbHZlID0gKGRlZiwgaXNBc3luYyA9IGZhbHNlKSA9PiB7DQogICAgICB0aGlzLl9yZXNvbHZlZCA9IHRydWU7DQogICAgICB0aGlzLl9wZW5kaW5nUmVzb2x2ZSA9IHZvaWQgMDsNCiAgICAgIGNvbnN0IHsgcHJvcHMsIHN0eWxlcyB9ID0gZGVmOw0KICAgICAgbGV0IG51bWJlclByb3BzOw0KICAgICAgaWYgKHByb3BzICYmICFpc0FycmF5KHByb3BzKSkgew0KICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBwcm9wcykgew0KICAgICAgICAgIGNvbnN0IG9wdCA9IHByb3BzW2tleV07DQogICAgICAgICAgaWYgKG9wdCA9PT0gTnVtYmVyIHx8IG9wdCAmJiBvcHQudHlwZSA9PT0gTnVtYmVyKSB7DQogICAgICAgICAgICBpZiAoa2V5IGluIHRoaXMuX3Byb3BzKSB7DQogICAgICAgICAgICAgIHRoaXMuX3Byb3BzW2tleV0gPSB0b051bWJlcih0aGlzLl9wcm9wc1trZXldKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIChudW1iZXJQcm9wcyB8fCAobnVtYmVyUHJvcHMgPSAvKiBAX19QVVJFX18gKi8gT2JqZWN0LmNyZWF0ZShudWxsKSkpW2NhbWVsaXplKGtleSldID0gdHJ1ZTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIHRoaXMuX251bWJlclByb3BzID0gbnVtYmVyUHJvcHM7DQogICAgICB0aGlzLl9yZXNvbHZlUHJvcHMoZGVmKTsNCiAgICAgIGlmICh0aGlzLnNoYWRvd1Jvb3QpIHsNCiAgICAgICAgdGhpcy5fYXBwbHlTdHlsZXMoc3R5bGVzKTsNCiAgICAgIH0gZWxzZSBpZiAoc3R5bGVzKSB7DQogICAgICAgIHdhcm4oDQogICAgICAgICAgIkN1c3RvbSBlbGVtZW50IHN0eWxlIGluamVjdGlvbiBpcyBub3Qgc3VwcG9ydGVkIHdoZW4gdXNpbmcgc2hhZG93Um9vdDogZmFsc2UiDQogICAgICAgICk7DQogICAgICB9DQogICAgICB0aGlzLl9tb3VudChkZWYpOw0KICAgIH07DQogICAgY29uc3QgYXN5bmNEZWYgPSB0aGlzLl9kZWYuX19hc3luY0xvYWRlcjsNCiAgICBpZiAoYXN5bmNEZWYpIHsNCiAgICAgIHRoaXMuX3BlbmRpbmdSZXNvbHZlID0gYXN5bmNEZWYoKS50aGVuKChkZWYpID0+IHsNCiAgICAgICAgZGVmLmNvbmZpZ3VyZUFwcCA9IHRoaXMuX2RlZi5jb25maWd1cmVBcHA7DQogICAgICAgIHJlc29sdmUodGhpcy5fZGVmID0gZGVmLCB0cnVlKTsNCiAgICAgIH0pOw0KICAgIH0gZWxzZSB7DQogICAgICByZXNvbHZlKHRoaXMuX2RlZik7DQogICAgfQ0KICB9DQogIF9tb3VudChkZWYpIHsNCiAgICBpZiAoIWRlZi5uYW1lKSB7DQogICAgICBkZWYubmFtZSA9ICJWdWVFbGVtZW50IjsNCiAgICB9DQogICAgdGhpcy5fYXBwID0gdGhpcy5fY3JlYXRlQXBwKGRlZik7DQogICAgdGhpcy5faW5oZXJpdFBhcmVudENvbnRleHQoKTsNCiAgICBpZiAoZGVmLmNvbmZpZ3VyZUFwcCkgew0KICAgICAgZGVmLmNvbmZpZ3VyZUFwcCh0aGlzLl9hcHApOw0KICAgIH0NCiAgICB0aGlzLl9hcHAuX2NlVk5vZGUgPSB0aGlzLl9jcmVhdGVWTm9kZSgpOw0KICAgIHRoaXMuX2FwcC5tb3VudCh0aGlzLl9yb290KTsNCiAgICBjb25zdCBleHBvc2VkID0gdGhpcy5faW5zdGFuY2UgJiYgdGhpcy5faW5zdGFuY2UuZXhwb3NlZDsNCiAgICBpZiAoIWV4cG9zZWQpIHJldHVybjsNCiAgICBmb3IgKGNvbnN0IGtleSBpbiBleHBvc2VkKSB7DQogICAgICBpZiAoIWhhc093bih0aGlzLCBrZXkpKSB7DQogICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBrZXksIHsNCiAgICAgICAgICAvLyB1bndyYXAgcmVmIHRvIGJlIGNvbnNpc3RlbnQgd2l0aCBwdWJsaWMgaW5zdGFuY2UgYmVoYXZpb3INCiAgICAgICAgICBnZXQ6ICgpID0+IHVucmVmKGV4cG9zZWRba2V5XSkNCiAgICAgICAgfSk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICB3YXJuKGBFeHBvc2VkIHByb3BlcnR5ICIke2tleX0iIGFscmVhZHkgZXhpc3RzIG9uIGN1c3RvbSBlbGVtZW50LmApOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICBfcmVzb2x2ZVByb3BzKGRlZikgew0KICAgIGNvbnN0IHsgcHJvcHMgfSA9IGRlZjsNCiAgICBjb25zdCBkZWNsYXJlZFByb3BLZXlzID0gaXNBcnJheShwcm9wcykgPyBwcm9wcyA6IE9iamVjdC5rZXlzKHByb3BzIHx8IHt9KTsNCiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyh0aGlzKSkgew0KICAgICAgaWYgKGtleVswXSAhPT0gIl8iICYmIGRlY2xhcmVkUHJvcEtleXMuaW5jbHVkZXMoa2V5KSkgew0KICAgICAgICB0aGlzLl9zZXRQcm9wKGtleSwgdGhpc1trZXldKTsNCiAgICAgIH0NCiAgICB9DQogICAgZm9yIChjb25zdCBrZXkgb2YgZGVjbGFyZWRQcm9wS2V5cy5tYXAoY2FtZWxpemUpKSB7DQogICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywga2V5LCB7DQogICAgICAgIGdldCgpIHsNCiAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0UHJvcChrZXkpOw0KICAgICAgICB9LA0KICAgICAgICBzZXQodmFsKSB7DQogICAgICAgICAgdGhpcy5fc2V0UHJvcChrZXksIHZhbCwgdHJ1ZSwgdHJ1ZSk7DQogICAgICAgIH0NCiAgICAgIH0pOw0KICAgIH0NCiAgfQ0KICBfc2V0QXR0cihrZXkpIHsNCiAgICBpZiAoa2V5LnN0YXJ0c1dpdGgoImRhdGEtdi0iKSkgcmV0dXJuOw0KICAgIGNvbnN0IGhhcyA9IHRoaXMuaGFzQXR0cmlidXRlKGtleSk7DQogICAgbGV0IHZhbHVlID0gaGFzID8gdGhpcy5nZXRBdHRyaWJ1dGUoa2V5KSA6IFJFTU9WQUw7DQogICAgY29uc3QgY2FtZWxLZXkgPSBjYW1lbGl6ZShrZXkpOw0KICAgIGlmIChoYXMgJiYgdGhpcy5fbnVtYmVyUHJvcHMgJiYgdGhpcy5fbnVtYmVyUHJvcHNbY2FtZWxLZXldKSB7DQogICAgICB2YWx1ZSA9IHRvTnVtYmVyKHZhbHVlKTsNCiAgICB9DQogICAgdGhpcy5fc2V0UHJvcChjYW1lbEtleSwgdmFsdWUsIGZhbHNlLCB0cnVlKTsNCiAgfQ0KICAvKioNCiAgICogQGludGVybmFsDQogICAqLw0KICBfZ2V0UHJvcChrZXkpIHsNCiAgICByZXR1cm4gdGhpcy5fcHJvcHNba2V5XTsNCiAgfQ0KICAvKioNCiAgICogQGludGVybmFsDQogICAqLw0KICBfc2V0UHJvcChrZXksIHZhbCwgc2hvdWxkUmVmbGVjdCA9IHRydWUsIHNob3VsZFVwZGF0ZSA9IGZhbHNlKSB7DQogICAgaWYgKHZhbCAhPT0gdGhpcy5fcHJvcHNba2V5XSkgew0KICAgICAgaWYgKHZhbCA9PT0gUkVNT1ZBTCkgew0KICAgICAgICBkZWxldGUgdGhpcy5fcHJvcHNba2V5XTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHRoaXMuX3Byb3BzW2tleV0gPSB2YWw7DQogICAgICAgIGlmIChrZXkgPT09ICJrZXkiICYmIHRoaXMuX2FwcCkgew0KICAgICAgICAgIHRoaXMuX2FwcC5fY2VWTm9kZS5rZXkgPSB2YWw7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGlmIChzaG91bGRVcGRhdGUgJiYgdGhpcy5faW5zdGFuY2UpIHsNCiAgICAgICAgdGhpcy5fdXBkYXRlKCk7DQogICAgICB9DQogICAgICBpZiAoc2hvdWxkUmVmbGVjdCkgew0KICAgICAgICBjb25zdCBvYiA9IHRoaXMuX29iOw0KICAgICAgICBvYiAmJiBvYi5kaXNjb25uZWN0KCk7DQogICAgICAgIGlmICh2YWwgPT09IHRydWUpIHsNCiAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZShoeXBoZW5hdGUoa2V5KSwgIiIpOw0KICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICJzdHJpbmciIHx8IHR5cGVvZiB2YWwgPT09ICJudW1iZXIiKSB7DQogICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUoaHlwaGVuYXRlKGtleSksIHZhbCArICIiKTsNCiAgICAgICAgfSBlbHNlIGlmICghdmFsKSB7DQogICAgICAgICAgdGhpcy5yZW1vdmVBdHRyaWJ1dGUoaHlwaGVuYXRlKGtleSkpOw0KICAgICAgICB9DQogICAgICAgIG9iICYmIG9iLm9ic2VydmUodGhpcywgeyBhdHRyaWJ1dGVzOiB0cnVlIH0pOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICBfdXBkYXRlKCkgew0KICAgIGNvbnN0IHZub2RlID0gdGhpcy5fY3JlYXRlVk5vZGUoKTsNCiAgICBpZiAodGhpcy5fYXBwKSB2bm9kZS5hcHBDb250ZXh0ID0gdGhpcy5fYXBwLl9jb250ZXh0Ow0KICAgIHJlbmRlcih2bm9kZSwgdGhpcy5fcm9vdCk7DQogIH0NCiAgX2NyZWF0ZVZOb2RlKCkgew0KICAgIGNvbnN0IGJhc2VQcm9wcyA9IHt9Ow0KICAgIGlmICghdGhpcy5zaGFkb3dSb290KSB7DQogICAgICBiYXNlUHJvcHMub25Wbm9kZU1vdW50ZWQgPSBiYXNlUHJvcHMub25Wbm9kZVVwZGF0ZWQgPSB0aGlzLl9yZW5kZXJTbG90cy5iaW5kKHRoaXMpOw0KICAgIH0NCiAgICBjb25zdCB2bm9kZSA9IGNyZWF0ZVZOb2RlKHRoaXMuX2RlZiwgZXh0ZW5kKGJhc2VQcm9wcywgdGhpcy5fcHJvcHMpKTsNCiAgICBpZiAoIXRoaXMuX2luc3RhbmNlKSB7DQogICAgICB2bm9kZS5jZSA9IChpbnN0YW5jZSkgPT4gew0KICAgICAgICB0aGlzLl9pbnN0YW5jZSA9IGluc3RhbmNlOw0KICAgICAgICBpbnN0YW5jZS5jZSA9IHRoaXM7DQogICAgICAgIGluc3RhbmNlLmlzQ0UgPSB0cnVlOw0KICAgICAgICB7DQogICAgICAgICAgaW5zdGFuY2UuY2VSZWxvYWQgPSAobmV3U3R5bGVzKSA9PiB7DQogICAgICAgICAgICBpZiAodGhpcy5fc3R5bGVzKSB7DQogICAgICAgICAgICAgIHRoaXMuX3N0eWxlcy5mb3JFYWNoKChzKSA9PiB0aGlzLl9yb290LnJlbW92ZUNoaWxkKHMpKTsNCiAgICAgICAgICAgICAgdGhpcy5fc3R5bGVzLmxlbmd0aCA9IDA7DQogICAgICAgICAgICB9DQogICAgICAgICAgICB0aGlzLl9hcHBseVN0eWxlcyhuZXdTdHlsZXMpOw0KICAgICAgICAgICAgdGhpcy5faW5zdGFuY2UgPSBudWxsOw0KICAgICAgICAgICAgdGhpcy5fdXBkYXRlKCk7DQogICAgICAgICAgfTsNCiAgICAgICAgfQ0KICAgICAgICBjb25zdCBkaXNwYXRjaCA9IChldmVudCwgYXJncykgPT4gew0KICAgICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudCgNCiAgICAgICAgICAgIG5ldyBDdXN0b21FdmVudCgNCiAgICAgICAgICAgICAgZXZlbnQsDQogICAgICAgICAgICAgIGlzUGxhaW5PYmplY3QoYXJnc1swXSkgPyBleHRlbmQoeyBkZXRhaWw6IGFyZ3MgfSwgYXJnc1swXSkgOiB7IGRldGFpbDogYXJncyB9DQogICAgICAgICAgICApDQogICAgICAgICAgKTsNCiAgICAgICAgfTsNCiAgICAgICAgaW5zdGFuY2UuZW1pdCA9IChldmVudCwgLi4uYXJncykgPT4gew0KICAgICAgICAgIGRpc3BhdGNoKGV2ZW50LCBhcmdzKTsNCiAgICAgICAgICBpZiAoaHlwaGVuYXRlKGV2ZW50KSAhPT0gZXZlbnQpIHsNCiAgICAgICAgICAgIGRpc3BhdGNoKGh5cGhlbmF0ZShldmVudCksIGFyZ3MpOw0KICAgICAgICAgIH0NCiAgICAgICAgfTsNCiAgICAgICAgdGhpcy5fc2V0UGFyZW50KCk7DQogICAgICB9Ow0KICAgIH0NCiAgICByZXR1cm4gdm5vZGU7DQogIH0NCiAgX2FwcGx5U3R5bGVzKHN0eWxlcywgb3duZXIpIHsNCiAgICBpZiAoIXN0eWxlcykgcmV0dXJuOw0KICAgIGlmIChvd25lcikgew0KICAgICAgaWYgKG93bmVyID09PSB0aGlzLl9kZWYgfHwgdGhpcy5fc3R5bGVDaGlsZHJlbi5oYXMob3duZXIpKSB7DQogICAgICAgIHJldHVybjsNCiAgICAgIH0NCiAgICAgIHRoaXMuX3N0eWxlQ2hpbGRyZW4uYWRkKG93bmVyKTsNCiAgICB9DQogICAgY29uc3Qgbm9uY2UgPSB0aGlzLl9ub25jZTsNCiAgICBmb3IgKGxldCBpID0gc3R5bGVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7DQogICAgICBjb25zdCBzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3R5bGUiKTsNCiAgICAgIGlmIChub25jZSkgcy5zZXRBdHRyaWJ1dGUoIm5vbmNlIiwgbm9uY2UpOw0KICAgICAgcy50ZXh0Q29udGVudCA9IHN0eWxlc1tpXTsNCiAgICAgIHRoaXMuc2hhZG93Um9vdC5wcmVwZW5kKHMpOw0KICAgICAgew0KICAgICAgICBpZiAob3duZXIpIHsNCiAgICAgICAgICBpZiAob3duZXIuX19obXJJZCkgew0KICAgICAgICAgICAgaWYgKCF0aGlzLl9jaGlsZFN0eWxlcykgdGhpcy5fY2hpbGRTdHlsZXMgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOw0KICAgICAgICAgICAgbGV0IGVudHJ5ID0gdGhpcy5fY2hpbGRTdHlsZXMuZ2V0KG93bmVyLl9faG1ySWQpOw0KICAgICAgICAgICAgaWYgKCFlbnRyeSkgew0KICAgICAgICAgICAgICB0aGlzLl9jaGlsZFN0eWxlcy5zZXQob3duZXIuX19obXJJZCwgZW50cnkgPSBbXSk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBlbnRyeS5wdXNoKHMpOw0KICAgICAgICAgIH0NCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAodGhpcy5fc3R5bGVzIHx8ICh0aGlzLl9zdHlsZXMgPSBbXSkpLnB1c2gocyk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH0NCiAgLyoqDQogICAqIE9ubHkgY2FsbGVkIHdoZW4gc2hhZG93Um9vdCBpcyBmYWxzZQ0KICAgKi8NCiAgX3BhcnNlU2xvdHMoKSB7DQogICAgY29uc3Qgc2xvdHMgPSB0aGlzLl9zbG90cyA9IHt9Ow0KICAgIGxldCBuOw0KICAgIHdoaWxlIChuID0gdGhpcy5maXJzdENoaWxkKSB7DQogICAgICBjb25zdCBzbG90TmFtZSA9IG4ubm9kZVR5cGUgPT09IDEgJiYgbi5nZXRBdHRyaWJ1dGUoInNsb3QiKSB8fCAiZGVmYXVsdCI7DQogICAgICAoc2xvdHNbc2xvdE5hbWVdIHx8IChzbG90c1tzbG90TmFtZV0gPSBbXSkpLnB1c2gobik7DQogICAgICB0aGlzLnJlbW92ZUNoaWxkKG4pOw0KICAgIH0NCiAgfQ0KICAvKioNCiAgICogT25seSBjYWxsZWQgd2hlbiBzaGFkb3dSb290IGlzIGZhbHNlDQogICAqLw0KICBfcmVuZGVyU2xvdHMoKSB7DQogICAgY29uc3Qgb3V0bGV0cyA9ICh0aGlzLl90ZWxlcG9ydFRhcmdldCB8fCB0aGlzKS5xdWVyeVNlbGVjdG9yQWxsKCJzbG90Iik7DQogICAgY29uc3Qgc2NvcGVJZCA9IHRoaXMuX2luc3RhbmNlLnR5cGUuX19zY29wZUlkOw0KICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3V0bGV0cy5sZW5ndGg7IGkrKykgew0KICAgICAgY29uc3QgbyA9IG91dGxldHNbaV07DQogICAgICBjb25zdCBzbG90TmFtZSA9IG8uZ2V0QXR0cmlidXRlKCJuYW1lIikgfHwgImRlZmF1bHQiOw0KICAgICAgY29uc3QgY29udGVudCA9IHRoaXMuX3Nsb3RzW3Nsb3ROYW1lXTsNCiAgICAgIGNvbnN0IHBhcmVudCA9IG8ucGFyZW50Tm9kZTsNCiAgICAgIGlmIChjb250ZW50KSB7DQogICAgICAgIGZvciAoY29uc3QgbiBvZiBjb250ZW50KSB7DQogICAgICAgICAgaWYgKHNjb3BlSWQgJiYgbi5ub2RlVHlwZSA9PT0gMSkgew0KICAgICAgICAgICAgY29uc3QgaWQgPSBzY29wZUlkICsgIi1zIjsNCiAgICAgICAgICAgIGNvbnN0IHdhbGtlciA9IGRvY3VtZW50LmNyZWF0ZVRyZWVXYWxrZXIobiwgMSk7DQogICAgICAgICAgICBuLnNldEF0dHJpYnV0ZShpZCwgIiIpOw0KICAgICAgICAgICAgbGV0IGNoaWxkOw0KICAgICAgICAgICAgd2hpbGUgKGNoaWxkID0gd2Fsa2VyLm5leHROb2RlKCkpIHsNCiAgICAgICAgICAgICAgY2hpbGQuc2V0QXR0cmlidXRlKGlkLCAiIik7DQogICAgICAgICAgICB9DQogICAgICAgICAgfQ0KICAgICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUobiwgbyk7DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHdoaWxlIChvLmZpcnN0Q2hpbGQpIHBhcmVudC5pbnNlcnRCZWZvcmUoby5maXJzdENoaWxkLCBvKTsNCiAgICAgIH0NCiAgICAgIHBhcmVudC5yZW1vdmVDaGlsZChvKTsNCiAgICB9DQogIH0NCiAgLyoqDQogICAqIEBpbnRlcm5hbA0KICAgKi8NCiAgX2luamVjdENoaWxkU3R5bGUoY29tcCkgew0KICAgIHRoaXMuX2FwcGx5U3R5bGVzKGNvbXAuc3R5bGVzLCBjb21wKTsNCiAgfQ0KICAvKioNCiAgICogQGludGVybmFsDQogICAqLw0KICBfcmVtb3ZlQ2hpbGRTdHlsZShjb21wKSB7DQogICAgew0KICAgICAgdGhpcy5fc3R5bGVDaGlsZHJlbi5kZWxldGUoY29tcCk7DQogICAgICBpZiAodGhpcy5fY2hpbGRTdHlsZXMgJiYgY29tcC5fX2htcklkKSB7DQogICAgICAgIGNvbnN0IG9sZFN0eWxlcyA9IHRoaXMuX2NoaWxkU3R5bGVzLmdldChjb21wLl9faG1ySWQpOw0KICAgICAgICBpZiAob2xkU3R5bGVzKSB7DQogICAgICAgICAgb2xkU3R5bGVzLmZvckVhY2goKHMpID0+IHRoaXMuX3Jvb3QucmVtb3ZlQ2hpbGQocykpOw0KICAgICAgICAgIG9sZFN0eWxlcy5sZW5ndGggPSAwOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICB9DQp9DQpmdW5jdGlvbiB1c2VIb3N0KGNhbGxlcikgew0KICBjb25zdCBpbnN0YW5jZSA9IGdldEN1cnJlbnRJbnN0YW5jZSgpOw0KICBjb25zdCBlbCA9IGluc3RhbmNlICYmIGluc3RhbmNlLmNlOw0KICBpZiAoZWwpIHsNCiAgICByZXR1cm4gZWw7DQogIH0gZWxzZSB7DQogICAgaWYgKCFpbnN0YW5jZSkgew0KICAgICAgd2FybigNCiAgICAgICAgYCR7Y2FsbGVyIHx8ICJ1c2VIb3N0In0gY2FsbGVkIHdpdGhvdXQgYW4gYWN0aXZlIGNvbXBvbmVudCBpbnN0YW5jZS5gDQogICAgICApOw0KICAgIH0gZWxzZSB7DQogICAgICB3YXJuKA0KICAgICAgICBgJHtjYWxsZXIgfHwgInVzZUhvc3QifSBjYW4gb25seSBiZSB1c2VkIGluIGNvbXBvbmVudHMgZGVmaW5lZCB2aWEgZGVmaW5lQ3VzdG9tRWxlbWVudC5gDQogICAgICApOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gbnVsbDsNCn0NCmZ1bmN0aW9uIHVzZVNoYWRvd1Jvb3QoKSB7DQogIGNvbnN0IGVsID0gdXNlSG9zdCgidXNlU2hhZG93Um9vdCIpIDsNCiAgcmV0dXJuIGVsICYmIGVsLnNoYWRvd1Jvb3Q7DQp9DQoNCmZ1bmN0aW9uIHVzZUNzc01vZHVsZShuYW1lID0gIiRzdHlsZSIpIHsNCiAgew0KICAgIGNvbnN0IGluc3RhbmNlID0gZ2V0Q3VycmVudEluc3RhbmNlKCk7DQogICAgaWYgKCFpbnN0YW5jZSkgew0KICAgICAgd2FybihgdXNlQ3NzTW9kdWxlIG11c3QgYmUgY2FsbGVkIGluc2lkZSBzZXR1cCgpYCk7DQogICAgICByZXR1cm4gRU1QVFlfT0JKOw0KICAgIH0NCiAgICBjb25zdCBtb2R1bGVzID0gaW5zdGFuY2UudHlwZS5fX2Nzc01vZHVsZXM7DQogICAgaWYgKCFtb2R1bGVzKSB7DQogICAgICB3YXJuKGBDdXJyZW50IGluc3RhbmNlIGRvZXMgbm90IGhhdmUgQ1NTIG1vZHVsZXMgaW5qZWN0ZWQuYCk7DQogICAgICByZXR1cm4gRU1QVFlfT0JKOw0KICAgIH0NCiAgICBjb25zdCBtb2QgPSBtb2R1bGVzW25hbWVdOw0KICAgIGlmICghbW9kKSB7DQogICAgICB3YXJuKGBDdXJyZW50IGluc3RhbmNlIGRvZXMgbm90IGhhdmUgQ1NTIG1vZHVsZSBuYW1lZCAiJHtuYW1lfSIuYCk7DQogICAgICByZXR1cm4gRU1QVFlfT0JKOw0KICAgIH0NCiAgICByZXR1cm4gbW9kOw0KICB9DQp9DQoNCmNvbnN0IHBvc2l0aW9uTWFwID0gLyogQF9fUFVSRV9fICovIG5ldyBXZWFrTWFwKCk7DQpjb25zdCBuZXdQb3NpdGlvbk1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgV2Vha01hcCgpOw0KY29uc3QgbW92ZUNiS2V5ID0gU3ltYm9sKCJfbW92ZUNiIik7DQpjb25zdCBlbnRlckNiS2V5ID0gU3ltYm9sKCJfZW50ZXJDYiIpOw0KY29uc3QgZGVjb3JhdGUgPSAodCkgPT4gew0KICBkZWxldGUgdC5wcm9wcy5tb2RlOw0KICByZXR1cm4gdDsNCn07DQpjb25zdCBUcmFuc2l0aW9uR3JvdXBJbXBsID0gLyogQF9fUFVSRV9fICovIGRlY29yYXRlKHsNCiAgbmFtZTogIlRyYW5zaXRpb25Hcm91cCIsDQogIHByb3BzOiAvKiBAX19QVVJFX18gKi8gZXh0ZW5kKHt9LCBUcmFuc2l0aW9uUHJvcHNWYWxpZGF0b3JzLCB7DQogICAgdGFnOiBTdHJpbmcsDQogICAgbW92ZUNsYXNzOiBTdHJpbmcNCiAgfSksDQogIHNldHVwKHByb3BzLCB7IHNsb3RzIH0pIHsNCiAgICBjb25zdCBpbnN0YW5jZSA9IGdldEN1cnJlbnRJbnN0YW5jZSgpOw0KICAgIGNvbnN0IHN0YXRlID0gdXNlVHJhbnNpdGlvblN0YXRlKCk7DQogICAgbGV0IHByZXZDaGlsZHJlbjsNCiAgICBsZXQgY2hpbGRyZW47DQogICAgb25VcGRhdGVkKCgpID0+IHsNCiAgICAgIGlmICghcHJldkNoaWxkcmVuLmxlbmd0aCkgew0KICAgICAgICByZXR1cm47DQogICAgICB9DQogICAgICBjb25zdCBtb3ZlQ2xhc3MgPSBwcm9wcy5tb3ZlQ2xhc3MgfHwgYCR7cHJvcHMubmFtZSB8fCAidiJ9LW1vdmVgOw0KICAgICAgaWYgKCFoYXNDU1NUcmFuc2Zvcm0oDQogICAgICAgIHByZXZDaGlsZHJlblswXS5lbCwNCiAgICAgICAgaW5zdGFuY2Uudm5vZGUuZWwsDQogICAgICAgIG1vdmVDbGFzcw0KICAgICAgKSkgew0KICAgICAgICBwcmV2Q2hpbGRyZW4gPSBbXTsNCiAgICAgICAgcmV0dXJuOw0KICAgICAgfQ0KICAgICAgcHJldkNoaWxkcmVuLmZvckVhY2goY2FsbFBlbmRpbmdDYnMpOw0KICAgICAgcHJldkNoaWxkcmVuLmZvckVhY2gocmVjb3JkUG9zaXRpb24pOw0KICAgICAgY29uc3QgbW92ZWRDaGlsZHJlbiA9IHByZXZDaGlsZHJlbi5maWx0ZXIoYXBwbHlUcmFuc2xhdGlvbik7DQogICAgICBmb3JjZVJlZmxvdygpOw0KICAgICAgbW92ZWRDaGlsZHJlbi5mb3JFYWNoKChjKSA9PiB7DQogICAgICAgIGNvbnN0IGVsID0gYy5lbDsNCiAgICAgICAgY29uc3Qgc3R5bGUgPSBlbC5zdHlsZTsNCiAgICAgICAgYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCBtb3ZlQ2xhc3MpOw0KICAgICAgICBzdHlsZS50cmFuc2Zvcm0gPSBzdHlsZS53ZWJraXRUcmFuc2Zvcm0gPSBzdHlsZS50cmFuc2l0aW9uRHVyYXRpb24gPSAiIjsNCiAgICAgICAgY29uc3QgY2IgPSBlbFttb3ZlQ2JLZXldID0gKGUpID0+IHsNCiAgICAgICAgICBpZiAoZSAmJiBlLnRhcmdldCAhPT0gZWwpIHsNCiAgICAgICAgICAgIHJldHVybjsNCiAgICAgICAgICB9DQogICAgICAgICAgaWYgKCFlIHx8IC90cmFuc2Zvcm0kLy50ZXN0KGUucHJvcGVydHlOYW1lKSkgew0KICAgICAgICAgICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigidHJhbnNpdGlvbmVuZCIsIGNiKTsNCiAgICAgICAgICAgIGVsW21vdmVDYktleV0gPSBudWxsOw0KICAgICAgICAgICAgcmVtb3ZlVHJhbnNpdGlvbkNsYXNzKGVsLCBtb3ZlQ2xhc3MpOw0KICAgICAgICAgIH0NCiAgICAgICAgfTsNCiAgICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcigidHJhbnNpdGlvbmVuZCIsIGNiKTsNCiAgICAgIH0pOw0KICAgICAgcHJldkNoaWxkcmVuID0gW107DQogICAgfSk7DQogICAgcmV0dXJuICgpID0+IHsNCiAgICAgIGNvbnN0IHJhd1Byb3BzID0gdG9SYXcocHJvcHMpOw0KICAgICAgY29uc3QgY3NzVHJhbnNpdGlvblByb3BzID0gcmVzb2x2ZVRyYW5zaXRpb25Qcm9wcyhyYXdQcm9wcyk7DQogICAgICBsZXQgdGFnID0gcmF3UHJvcHMudGFnIHx8IEZyYWdtZW50Ow0KICAgICAgcHJldkNoaWxkcmVuID0gW107DQogICAgICBpZiAoY2hpbGRyZW4pIHsNCiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykgew0KICAgICAgICAgIGNvbnN0IGNoaWxkID0gY2hpbGRyZW5baV07DQogICAgICAgICAgaWYgKGNoaWxkLmVsICYmIGNoaWxkLmVsIGluc3RhbmNlb2YgRWxlbWVudCkgew0KICAgICAgICAgICAgcHJldkNoaWxkcmVuLnB1c2goY2hpbGQpOw0KICAgICAgICAgICAgc2V0VHJhbnNpdGlvbkhvb2tzKA0KICAgICAgICAgICAgICBjaGlsZCwNCiAgICAgICAgICAgICAgcmVzb2x2ZVRyYW5zaXRpb25Ib29rcygNCiAgICAgICAgICAgICAgICBjaGlsZCwNCiAgICAgICAgICAgICAgICBjc3NUcmFuc2l0aW9uUHJvcHMsDQogICAgICAgICAgICAgICAgc3RhdGUsDQogICAgICAgICAgICAgICAgaW5zdGFuY2UNCiAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgKTsNCiAgICAgICAgICAgIHBvc2l0aW9uTWFwLnNldCgNCiAgICAgICAgICAgICAgY2hpbGQsDQogICAgICAgICAgICAgIGNoaWxkLmVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpDQogICAgICAgICAgICApOw0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgY2hpbGRyZW4gPSBzbG90cy5kZWZhdWx0ID8gZ2V0VHJhbnNpdGlvblJhd0NoaWxkcmVuKHNsb3RzLmRlZmF1bHQoKSkgOiBbXTsNCiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgY29uc3QgY2hpbGQgPSBjaGlsZHJlbltpXTsNCiAgICAgICAgaWYgKGNoaWxkLmtleSAhPSBudWxsKSB7DQogICAgICAgICAgc2V0VHJhbnNpdGlvbkhvb2tzKA0KICAgICAgICAgICAgY2hpbGQsDQogICAgICAgICAgICByZXNvbHZlVHJhbnNpdGlvbkhvb2tzKGNoaWxkLCBjc3NUcmFuc2l0aW9uUHJvcHMsIHN0YXRlLCBpbnN0YW5jZSkNCiAgICAgICAgICApOw0KICAgICAgICB9IGVsc2UgaWYgKGNoaWxkLnR5cGUgIT09IFRleHQpIHsNCiAgICAgICAgICB3YXJuKGA8VHJhbnNpdGlvbkdyb3VwPiBjaGlsZHJlbiBtdXN0IGJlIGtleWVkLmApOw0KICAgICAgICB9DQogICAgICB9DQogICAgICByZXR1cm4gY3JlYXRlVk5vZGUodGFnLCBudWxsLCBjaGlsZHJlbik7DQogICAgfTsNCiAgfQ0KfSk7DQpjb25zdCBUcmFuc2l0aW9uR3JvdXAgPSBUcmFuc2l0aW9uR3JvdXBJbXBsOw0KZnVuY3Rpb24gY2FsbFBlbmRpbmdDYnMoYykgew0KICBjb25zdCBlbCA9IGMuZWw7DQogIGlmIChlbFttb3ZlQ2JLZXldKSB7DQogICAgZWxbbW92ZUNiS2V5XSgpOw0KICB9DQogIGlmIChlbFtlbnRlckNiS2V5XSkgew0KICAgIGVsW2VudGVyQ2JLZXldKCk7DQogIH0NCn0NCmZ1bmN0aW9uIHJlY29yZFBvc2l0aW9uKGMpIHsNCiAgbmV3UG9zaXRpb25NYXAuc2V0KGMsIGMuZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpOw0KfQ0KZnVuY3Rpb24gYXBwbHlUcmFuc2xhdGlvbihjKSB7DQogIGNvbnN0IG9sZFBvcyA9IHBvc2l0aW9uTWFwLmdldChjKTsNCiAgY29uc3QgbmV3UG9zID0gbmV3UG9zaXRpb25NYXAuZ2V0KGMpOw0KICBjb25zdCBkeCA9IG9sZFBvcy5sZWZ0IC0gbmV3UG9zLmxlZnQ7DQogIGNvbnN0IGR5ID0gb2xkUG9zLnRvcCAtIG5ld1Bvcy50b3A7DQogIGlmIChkeCB8fCBkeSkgew0KICAgIGNvbnN0IHMgPSBjLmVsLnN0eWxlOw0KICAgIHMudHJhbnNmb3JtID0gcy53ZWJraXRUcmFuc2Zvcm0gPSBgdHJhbnNsYXRlKCR7ZHh9cHgsJHtkeX1weClgOw0KICAgIHMudHJhbnNpdGlvbkR1cmF0aW9uID0gIjBzIjsNCiAgICByZXR1cm4gYzsNCiAgfQ0KfQ0KZnVuY3Rpb24gaGFzQ1NTVHJhbnNmb3JtKGVsLCByb290LCBtb3ZlQ2xhc3MpIHsNCiAgY29uc3QgY2xvbmUgPSBlbC5jbG9uZU5vZGUoKTsNCiAgY29uc3QgX3Z0YyA9IGVsW3Z0Y0tleV07DQogIGlmIChfdnRjKSB7DQogICAgX3Z0Yy5mb3JFYWNoKChjbHMpID0+IHsNCiAgICAgIGNscy5zcGxpdCgvXHMrLykuZm9yRWFjaCgoYykgPT4gYyAmJiBjbG9uZS5jbGFzc0xpc3QucmVtb3ZlKGMpKTsNCiAgICB9KTsNCiAgfQ0KICBtb3ZlQ2xhc3Muc3BsaXQoL1xzKy8pLmZvckVhY2goKGMpID0+IGMgJiYgY2xvbmUuY2xhc3NMaXN0LmFkZChjKSk7DQogIGNsb25lLnN0eWxlLmRpc3BsYXkgPSAibm9uZSI7DQogIGNvbnN0IGNvbnRhaW5lciA9IHJvb3Qubm9kZVR5cGUgPT09IDEgPyByb290IDogcm9vdC5wYXJlbnROb2RlOw0KICBjb250YWluZXIuYXBwZW5kQ2hpbGQoY2xvbmUpOw0KICBjb25zdCB7IGhhc1RyYW5zZm9ybSB9ID0gZ2V0VHJhbnNpdGlvbkluZm8oY2xvbmUpOw0KICBjb250YWluZXIucmVtb3ZlQ2hpbGQoY2xvbmUpOw0KICByZXR1cm4gaGFzVHJhbnNmb3JtOw0KfQ0KDQpjb25zdCBnZXRNb2RlbEFzc2lnbmVyID0gKHZub2RlKSA9PiB7DQogIGNvbnN0IGZuID0gdm5vZGUucHJvcHNbIm9uVXBkYXRlOm1vZGVsVmFsdWUiXSB8fCBmYWxzZTsNCiAgcmV0dXJuIGlzQXJyYXkoZm4pID8gKHZhbHVlKSA9PiBpbnZva2VBcnJheUZucyhmbiwgdmFsdWUpIDogZm47DQp9Ow0KZnVuY3Rpb24gb25Db21wb3NpdGlvblN0YXJ0KGUpIHsNCiAgZS50YXJnZXQuY29tcG9zaW5nID0gdHJ1ZTsNCn0NCmZ1bmN0aW9uIG9uQ29tcG9zaXRpb25FbmQoZSkgew0KICBjb25zdCB0YXJnZXQgPSBlLnRhcmdldDsNCiAgaWYgKHRhcmdldC5jb21wb3NpbmcpIHsNCiAgICB0YXJnZXQuY29tcG9zaW5nID0gZmFsc2U7DQogICAgdGFyZ2V0LmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KCJpbnB1dCIpKTsNCiAgfQ0KfQ0KY29uc3QgYXNzaWduS2V5ID0gU3ltYm9sKCJfYXNzaWduIik7DQpjb25zdCB2TW9kZWxUZXh0ID0gew0KICBjcmVhdGVkKGVsLCB7IG1vZGlmaWVyczogeyBsYXp5LCB0cmltLCBudW1iZXIgfSB9LCB2bm9kZSkgew0KICAgIGVsW2Fzc2lnbktleV0gPSBnZXRNb2RlbEFzc2lnbmVyKHZub2RlKTsNCiAgICBjb25zdCBjYXN0VG9OdW1iZXIgPSBudW1iZXIgfHwgdm5vZGUucHJvcHMgJiYgdm5vZGUucHJvcHMudHlwZSA9PT0gIm51bWJlciI7DQogICAgYWRkRXZlbnRMaXN0ZW5lcihlbCwgbGF6eSA/ICJjaGFuZ2UiIDogImlucHV0IiwgKGUpID0+IHsNCiAgICAgIGlmIChlLnRhcmdldC5jb21wb3NpbmcpIHJldHVybjsNCiAgICAgIGxldCBkb21WYWx1ZSA9IGVsLnZhbHVlOw0KICAgICAgaWYgKHRyaW0pIHsNCiAgICAgICAgZG9tVmFsdWUgPSBkb21WYWx1ZS50cmltKCk7DQogICAgICB9DQogICAgICBpZiAoY2FzdFRvTnVtYmVyKSB7DQogICAgICAgIGRvbVZhbHVlID0gbG9vc2VUb051bWJlcihkb21WYWx1ZSk7DQogICAgICB9DQogICAgICBlbFthc3NpZ25LZXldKGRvbVZhbHVlKTsNCiAgICB9KTsNCiAgICBpZiAodHJpbSkgew0KICAgICAgYWRkRXZlbnRMaXN0ZW5lcihlbCwgImNoYW5nZSIsICgpID0+IHsNCiAgICAgICAgZWwudmFsdWUgPSBlbC52YWx1ZS50cmltKCk7DQogICAgICB9KTsNCiAgICB9DQogICAgaWYgKCFsYXp5KSB7DQogICAgICBhZGRFdmVudExpc3RlbmVyKGVsLCAiY29tcG9zaXRpb25zdGFydCIsIG9uQ29tcG9zaXRpb25TdGFydCk7DQogICAgICBhZGRFdmVudExpc3RlbmVyKGVsLCAiY29tcG9zaXRpb25lbmQiLCBvbkNvbXBvc2l0aW9uRW5kKTsNCiAgICAgIGFkZEV2ZW50TGlzdGVuZXIoZWwsICJjaGFuZ2UiLCBvbkNvbXBvc2l0aW9uRW5kKTsNCiAgICB9DQogIH0sDQogIC8vIHNldCB2YWx1ZSBvbiBtb3VudGVkIHNvIGl0J3MgYWZ0ZXIgbWluL21heCBmb3IgdHlwZT0icmFuZ2UiDQogIG1vdW50ZWQoZWwsIHsgdmFsdWUgfSkgew0KICAgIGVsLnZhbHVlID0gdmFsdWUgPT0gbnVsbCA/ICIiIDogdmFsdWU7DQogIH0sDQogIGJlZm9yZVVwZGF0ZShlbCwgeyB2YWx1ZSwgb2xkVmFsdWUsIG1vZGlmaWVyczogeyBsYXp5LCB0cmltLCBudW1iZXIgfSB9LCB2bm9kZSkgew0KICAgIGVsW2Fzc2lnbktleV0gPSBnZXRNb2RlbEFzc2lnbmVyKHZub2RlKTsNCiAgICBpZiAoZWwuY29tcG9zaW5nKSByZXR1cm47DQogICAgY29uc3QgZWxWYWx1ZSA9IChudW1iZXIgfHwgZWwudHlwZSA9PT0gIm51bWJlciIpICYmICEvXjBcZC8udGVzdChlbC52YWx1ZSkgPyBsb29zZVRvTnVtYmVyKGVsLnZhbHVlKSA6IGVsLnZhbHVlOw0KICAgIGNvbnN0IG5ld1ZhbHVlID0gdmFsdWUgPT0gbnVsbCA/ICIiIDogdmFsdWU7DQogICAgaWYgKGVsVmFsdWUgPT09IG5ld1ZhbHVlKSB7DQogICAgICByZXR1cm47DQogICAgfQ0KICAgIGlmIChkb2N1bWVudC5hY3RpdmVFbGVtZW50ID09PSBlbCAmJiBlbC50eXBlICE9PSAicmFuZ2UiKSB7DQogICAgICBpZiAobGF6eSAmJiB2YWx1ZSA9PT0gb2xkVmFsdWUpIHsNCiAgICAgICAgcmV0dXJuOw0KICAgICAgfQ0KICAgICAgaWYgKHRyaW0gJiYgZWwudmFsdWUudHJpbSgpID09PSBuZXdWYWx1ZSkgew0KICAgICAgICByZXR1cm47DQogICAgICB9DQogICAgfQ0KICAgIGVsLnZhbHVlID0gbmV3VmFsdWU7DQogIH0NCn07DQpjb25zdCB2TW9kZWxDaGVja2JveCA9IHsNCiAgLy8gIzQwOTYgYXJyYXkgY2hlY2tib3hlcyBuZWVkIHRvIGJlIGRlZXAgdHJhdmVyc2VkDQogIGRlZXA6IHRydWUsDQogIGNyZWF0ZWQoZWwsIF8sIHZub2RlKSB7DQogICAgZWxbYXNzaWduS2V5XSA9IGdldE1vZGVsQXNzaWduZXIodm5vZGUpOw0KICAgIGFkZEV2ZW50TGlzdGVuZXIoZWwsICJjaGFuZ2UiLCAoKSA9PiB7DQogICAgICBjb25zdCBtb2RlbFZhbHVlID0gZWwuX21vZGVsVmFsdWU7DQogICAgICBjb25zdCBlbGVtZW50VmFsdWUgPSBnZXRWYWx1ZShlbCk7DQogICAgICBjb25zdCBjaGVja2VkID0gZWwuY2hlY2tlZDsNCiAgICAgIGNvbnN0IGFzc2lnbiA9IGVsW2Fzc2lnbktleV07DQogICAgICBpZiAoaXNBcnJheShtb2RlbFZhbHVlKSkgew0KICAgICAgICBjb25zdCBpbmRleCA9IGxvb3NlSW5kZXhPZihtb2RlbFZhbHVlLCBlbGVtZW50VmFsdWUpOw0KICAgICAgICBjb25zdCBmb3VuZCA9IGluZGV4ICE9PSAtMTsNCiAgICAgICAgaWYgKGNoZWNrZWQgJiYgIWZvdW5kKSB7DQogICAgICAgICAgYXNzaWduKG1vZGVsVmFsdWUuY29uY2F0KGVsZW1lbnRWYWx1ZSkpOw0KICAgICAgICB9IGVsc2UgaWYgKCFjaGVja2VkICYmIGZvdW5kKSB7DQogICAgICAgICAgY29uc3QgZmlsdGVyZWQgPSBbLi4ubW9kZWxWYWx1ZV07DQogICAgICAgICAgZmlsdGVyZWQuc3BsaWNlKGluZGV4LCAxKTsNCiAgICAgICAgICBhc3NpZ24oZmlsdGVyZWQpOw0KICAgICAgICB9DQogICAgICB9IGVsc2UgaWYgKGlzU2V0KG1vZGVsVmFsdWUpKSB7DQogICAgICAgIGNvbnN0IGNsb25lZCA9IG5ldyBTZXQobW9kZWxWYWx1ZSk7DQogICAgICAgIGlmIChjaGVja2VkKSB7DQogICAgICAgICAgY2xvbmVkLmFkZChlbGVtZW50VmFsdWUpOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIGNsb25lZC5kZWxldGUoZWxlbWVudFZhbHVlKTsNCiAgICAgICAgfQ0KICAgICAgICBhc3NpZ24oY2xvbmVkKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGFzc2lnbihnZXRDaGVja2JveFZhbHVlKGVsLCBjaGVja2VkKSk7DQogICAgICB9DQogICAgfSk7DQogIH0sDQogIC8vIHNldCBpbml0aWFsIGNoZWNrZWQgb24gbW91bnQgdG8gd2FpdCBmb3IgdHJ1ZS12YWx1ZS9mYWxzZS12YWx1ZQ0KICBtb3VudGVkOiBzZXRDaGVja2VkLA0KICBiZWZvcmVVcGRhdGUoZWwsIGJpbmRpbmcsIHZub2RlKSB7DQogICAgZWxbYXNzaWduS2V5XSA9IGdldE1vZGVsQXNzaWduZXIodm5vZGUpOw0KICAgIHNldENoZWNrZWQoZWwsIGJpbmRpbmcsIHZub2RlKTsNCiAgfQ0KfTsNCmZ1bmN0aW9uIHNldENoZWNrZWQoZWwsIHsgdmFsdWUsIG9sZFZhbHVlIH0sIHZub2RlKSB7DQogIGVsLl9tb2RlbFZhbHVlID0gdmFsdWU7DQogIGxldCBjaGVja2VkOw0KICBpZiAoaXNBcnJheSh2YWx1ZSkpIHsNCiAgICBjaGVja2VkID0gbG9vc2VJbmRleE9mKHZhbHVlLCB2bm9kZS5wcm9wcy52YWx1ZSkgPiAtMTsNCiAgfSBlbHNlIGlmIChpc1NldCh2YWx1ZSkpIHsNCiAgICBjaGVja2VkID0gdmFsdWUuaGFzKHZub2RlLnByb3BzLnZhbHVlKTsNCiAgfSBlbHNlIHsNCiAgICBpZiAodmFsdWUgPT09IG9sZFZhbHVlKSByZXR1cm47DQogICAgY2hlY2tlZCA9IGxvb3NlRXF1YWwodmFsdWUsIGdldENoZWNrYm94VmFsdWUoZWwsIHRydWUpKTsNCiAgfQ0KICBpZiAoZWwuY2hlY2tlZCAhPT0gY2hlY2tlZCkgew0KICAgIGVsLmNoZWNrZWQgPSBjaGVja2VkOw0KICB9DQp9DQpjb25zdCB2TW9kZWxSYWRpbyA9IHsNCiAgY3JlYXRlZChlbCwgeyB2YWx1ZSB9LCB2bm9kZSkgew0KICAgIGVsLmNoZWNrZWQgPSBsb29zZUVxdWFsKHZhbHVlLCB2bm9kZS5wcm9wcy52YWx1ZSk7DQogICAgZWxbYXNzaWduS2V5XSA9IGdldE1vZGVsQXNzaWduZXIodm5vZGUpOw0KICAgIGFkZEV2ZW50TGlzdGVuZXIoZWwsICJjaGFuZ2UiLCAoKSA9PiB7DQogICAgICBlbFthc3NpZ25LZXldKGdldFZhbHVlKGVsKSk7DQogICAgfSk7DQogIH0sDQogIGJlZm9yZVVwZGF0ZShlbCwgeyB2YWx1ZSwgb2xkVmFsdWUgfSwgdm5vZGUpIHsNCiAgICBlbFthc3NpZ25LZXldID0gZ2V0TW9kZWxBc3NpZ25lcih2bm9kZSk7DQogICAgaWYgKHZhbHVlICE9PSBvbGRWYWx1ZSkgew0KICAgICAgZWwuY2hlY2tlZCA9IGxvb3NlRXF1YWwodmFsdWUsIHZub2RlLnByb3BzLnZhbHVlKTsNCiAgICB9DQogIH0NCn07DQpjb25zdCB2TW9kZWxTZWxlY3QgPSB7DQogIC8vIDxzZWxlY3QgbXVsdGlwbGU+IHZhbHVlIG5lZWQgdG8gYmUgZGVlcCB0cmF2ZXJzZWQNCiAgZGVlcDogdHJ1ZSwNCiAgY3JlYXRlZChlbCwgeyB2YWx1ZSwgbW9kaWZpZXJzOiB7IG51bWJlciB9IH0sIHZub2RlKSB7DQogICAgY29uc3QgaXNTZXRNb2RlbCA9IGlzU2V0KHZhbHVlKTsNCiAgICBhZGRFdmVudExpc3RlbmVyKGVsLCAiY2hhbmdlIiwgKCkgPT4gew0KICAgICAgY29uc3Qgc2VsZWN0ZWRWYWwgPSBBcnJheS5wcm90b3R5cGUuZmlsdGVyLmNhbGwoZWwub3B0aW9ucywgKG8pID0+IG8uc2VsZWN0ZWQpLm1hcCgNCiAgICAgICAgKG8pID0+IG51bWJlciA/IGxvb3NlVG9OdW1iZXIoZ2V0VmFsdWUobykpIDogZ2V0VmFsdWUobykNCiAgICAgICk7DQogICAgICBlbFthc3NpZ25LZXldKA0KICAgICAgICBlbC5tdWx0aXBsZSA/IGlzU2V0TW9kZWwgPyBuZXcgU2V0KHNlbGVjdGVkVmFsKSA6IHNlbGVjdGVkVmFsIDogc2VsZWN0ZWRWYWxbMF0NCiAgICAgICk7DQogICAgICBlbC5fYXNzaWduaW5nID0gdHJ1ZTsNCiAgICAgIG5leHRUaWNrKCgpID0+IHsNCiAgICAgICAgZWwuX2Fzc2lnbmluZyA9IGZhbHNlOw0KICAgICAgfSk7DQogICAgfSk7DQogICAgZWxbYXNzaWduS2V5XSA9IGdldE1vZGVsQXNzaWduZXIodm5vZGUpOw0KICB9LA0KICAvLyBzZXQgdmFsdWUgaW4gbW91bnRlZCAmIHVwZGF0ZWQgYmVjYXVzZSA8c2VsZWN0PiByZWxpZXMgb24gaXRzIGNoaWxkcmVuDQogIC8vIDxvcHRpb24+cy4NCiAgbW91bnRlZChlbCwgeyB2YWx1ZSB9KSB7DQogICAgc2V0U2VsZWN0ZWQoZWwsIHZhbHVlKTsNCiAgfSwNCiAgYmVmb3JlVXBkYXRlKGVsLCBfYmluZGluZywgdm5vZGUpIHsNCiAgICBlbFthc3NpZ25LZXldID0gZ2V0TW9kZWxBc3NpZ25lcih2bm9kZSk7DQogIH0sDQogIHVwZGF0ZWQoZWwsIHsgdmFsdWUgfSkgew0KICAgIGlmICghZWwuX2Fzc2lnbmluZykgew0KICAgICAgc2V0U2VsZWN0ZWQoZWwsIHZhbHVlKTsNCiAgICB9DQogIH0NCn07DQpmdW5jdGlvbiBzZXRTZWxlY3RlZChlbCwgdmFsdWUpIHsNCiAgY29uc3QgaXNNdWx0aXBsZSA9IGVsLm11bHRpcGxlOw0KICBjb25zdCBpc0FycmF5VmFsdWUgPSBpc0FycmF5KHZhbHVlKTsNCiAgaWYgKGlzTXVsdGlwbGUgJiYgIWlzQXJyYXlWYWx1ZSAmJiAhaXNTZXQodmFsdWUpKSB7DQogICAgd2FybigNCiAgICAgIGA8c2VsZWN0IG11bHRpcGxlIHYtbW9kZWw+IGV4cGVjdHMgYW4gQXJyYXkgb3IgU2V0IHZhbHVlIGZvciBpdHMgYmluZGluZywgYnV0IGdvdCAke09iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSkuc2xpY2UoOCwgLTEpfS5gDQogICAgKTsNCiAgICByZXR1cm47DQogIH0NCiAgZm9yIChsZXQgaSA9IDAsIGwgPSBlbC5vcHRpb25zLmxlbmd0aDsgaSA8IGw7IGkrKykgew0KICAgIGNvbnN0IG9wdGlvbiA9IGVsLm9wdGlvbnNbaV07DQogICAgY29uc3Qgb3B0aW9uVmFsdWUgPSBnZXRWYWx1ZShvcHRpb24pOw0KICAgIGlmIChpc011bHRpcGxlKSB7DQogICAgICBpZiAoaXNBcnJheVZhbHVlKSB7DQogICAgICAgIGNvbnN0IG9wdGlvblR5cGUgPSB0eXBlb2Ygb3B0aW9uVmFsdWU7DQogICAgICAgIGlmIChvcHRpb25UeXBlID09PSAic3RyaW5nIiB8fCBvcHRpb25UeXBlID09PSAibnVtYmVyIikgew0KICAgICAgICAgIG9wdGlvbi5zZWxlY3RlZCA9IHZhbHVlLnNvbWUoKHYpID0+IFN0cmluZyh2KSA9PT0gU3RyaW5nKG9wdGlvblZhbHVlKSk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgb3B0aW9uLnNlbGVjdGVkID0gbG9vc2VJbmRleE9mKHZhbHVlLCBvcHRpb25WYWx1ZSkgPiAtMTsNCiAgICAgICAgfQ0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgb3B0aW9uLnNlbGVjdGVkID0gdmFsdWUuaGFzKG9wdGlvblZhbHVlKTsNCiAgICAgIH0NCiAgICB9IGVsc2UgaWYgKGxvb3NlRXF1YWwoZ2V0VmFsdWUob3B0aW9uKSwgdmFsdWUpKSB7DQogICAgICBpZiAoZWwuc2VsZWN0ZWRJbmRleCAhPT0gaSkgZWwuc2VsZWN0ZWRJbmRleCA9IGk7DQogICAgICByZXR1cm47DQogICAgfQ0KICB9DQogIGlmICghaXNNdWx0aXBsZSAmJiBlbC5zZWxlY3RlZEluZGV4ICE9PSAtMSkgew0KICAgIGVsLnNlbGVjdGVkSW5kZXggPSAtMTsNCiAgfQ0KfQ0KZnVuY3Rpb24gZ2V0VmFsdWUoZWwpIHsNCiAgcmV0dXJuICJfdmFsdWUiIGluIGVsID8gZWwuX3ZhbHVlIDogZWwudmFsdWU7DQp9DQpmdW5jdGlvbiBnZXRDaGVja2JveFZhbHVlKGVsLCBjaGVja2VkKSB7DQogIGNvbnN0IGtleSA9IGNoZWNrZWQgPyAiX3RydWVWYWx1ZSIgOiAiX2ZhbHNlVmFsdWUiOw0KICByZXR1cm4ga2V5IGluIGVsID8gZWxba2V5XSA6IGNoZWNrZWQ7DQp9DQpjb25zdCB2TW9kZWxEeW5hbWljID0gew0KICBjcmVhdGVkKGVsLCBiaW5kaW5nLCB2bm9kZSkgew0KICAgIGNhbGxNb2RlbEhvb2soZWwsIGJpbmRpbmcsIHZub2RlLCBudWxsLCAiY3JlYXRlZCIpOw0KICB9LA0KICBtb3VudGVkKGVsLCBiaW5kaW5nLCB2bm9kZSkgew0KICAgIGNhbGxNb2RlbEhvb2soZWwsIGJpbmRpbmcsIHZub2RlLCBudWxsLCAibW91bnRlZCIpOw0KICB9LA0KICBiZWZvcmVVcGRhdGUoZWwsIGJpbmRpbmcsIHZub2RlLCBwcmV2Vk5vZGUpIHsNCiAgICBjYWxsTW9kZWxIb29rKGVsLCBiaW5kaW5nLCB2bm9kZSwgcHJldlZOb2RlLCAiYmVmb3JlVXBkYXRlIik7DQogIH0sDQogIHVwZGF0ZWQoZWwsIGJpbmRpbmcsIHZub2RlLCBwcmV2Vk5vZGUpIHsNCiAgICBjYWxsTW9kZWxIb29rKGVsLCBiaW5kaW5nLCB2bm9kZSwgcHJldlZOb2RlLCAidXBkYXRlZCIpOw0KICB9DQp9Ow0KZnVuY3Rpb24gcmVzb2x2ZUR5bmFtaWNNb2RlbCh0YWdOYW1lLCB0eXBlKSB7DQogIHN3aXRjaCAodGFnTmFtZSkgew0KICAgIGNhc2UgIlNFTEVDVCI6DQogICAgICByZXR1cm4gdk1vZGVsU2VsZWN0Ow0KICAgIGNhc2UgIlRFWFRBUkVBIjoNCiAgICAgIHJldHVybiB2TW9kZWxUZXh0Ow0KICAgIGRlZmF1bHQ6DQogICAgICBzd2l0Y2ggKHR5cGUpIHsNCiAgICAgICAgY2FzZSAiY2hlY2tib3giOg0KICAgICAgICAgIHJldHVybiB2TW9kZWxDaGVja2JveDsNCiAgICAgICAgY2FzZSAicmFkaW8iOg0KICAgICAgICAgIHJldHVybiB2TW9kZWxSYWRpbzsNCiAgICAgICAgZGVmYXVsdDoNCiAgICAgICAgICByZXR1cm4gdk1vZGVsVGV4dDsNCiAgICAgIH0NCiAgfQ0KfQ0KZnVuY3Rpb24gY2FsbE1vZGVsSG9vayhlbCwgYmluZGluZywgdm5vZGUsIHByZXZWTm9kZSwgaG9vaykgew0KICBjb25zdCBtb2RlbFRvVXNlID0gcmVzb2x2ZUR5bmFtaWNNb2RlbCgNCiAgICBlbC50YWdOYW1lLA0KICAgIHZub2RlLnByb3BzICYmIHZub2RlLnByb3BzLnR5cGUNCiAgKTsNCiAgY29uc3QgZm4gPSBtb2RlbFRvVXNlW2hvb2tdOw0KICBmbiAmJiBmbihlbCwgYmluZGluZywgdm5vZGUsIHByZXZWTm9kZSk7DQp9DQpmdW5jdGlvbiBpbml0Vk1vZGVsRm9yU1NSKCkgew0KICB2TW9kZWxUZXh0LmdldFNTUlByb3BzID0gKHsgdmFsdWUgfSkgPT4gKHsgdmFsdWUgfSk7DQogIHZNb2RlbFJhZGlvLmdldFNTUlByb3BzID0gKHsgdmFsdWUgfSwgdm5vZGUpID0+IHsNCiAgICBpZiAodm5vZGUucHJvcHMgJiYgbG9vc2VFcXVhbCh2bm9kZS5wcm9wcy52YWx1ZSwgdmFsdWUpKSB7DQogICAgICByZXR1cm4geyBjaGVja2VkOiB0cnVlIH07DQogICAgfQ0KICB9Ow0KICB2TW9kZWxDaGVja2JveC5nZXRTU1JQcm9wcyA9ICh7IHZhbHVlIH0sIHZub2RlKSA9PiB7DQogICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7DQogICAgICBpZiAodm5vZGUucHJvcHMgJiYgbG9vc2VJbmRleE9mKHZhbHVlLCB2bm9kZS5wcm9wcy52YWx1ZSkgPiAtMSkgew0KICAgICAgICByZXR1cm4geyBjaGVja2VkOiB0cnVlIH07DQogICAgICB9DQogICAgfSBlbHNlIGlmIChpc1NldCh2YWx1ZSkpIHsNCiAgICAgIGlmICh2bm9kZS5wcm9wcyAmJiB2YWx1ZS5oYXModm5vZGUucHJvcHMudmFsdWUpKSB7DQogICAgICAgIHJldHVybiB7IGNoZWNrZWQ6IHRydWUgfTsNCiAgICAgIH0NCiAgICB9IGVsc2UgaWYgKHZhbHVlKSB7DQogICAgICByZXR1cm4geyBjaGVja2VkOiB0cnVlIH07DQogICAgfQ0KICB9Ow0KICB2TW9kZWxEeW5hbWljLmdldFNTUlByb3BzID0gKGJpbmRpbmcsIHZub2RlKSA9PiB7DQogICAgaWYgKHR5cGVvZiB2bm9kZS50eXBlICE9PSAic3RyaW5nIikgew0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBjb25zdCBtb2RlbFRvVXNlID0gcmVzb2x2ZUR5bmFtaWNNb2RlbCgNCiAgICAgIC8vIHJlc29sdmVEeW5hbWljTW9kZWwgZXhwZWN0cyBhbiB1cHBlcmNhc2UgdGFnIG5hbWUsIGJ1dCB2bm9kZS50eXBlIGlzIGxvd2VyY2FzZQ0KICAgICAgdm5vZGUudHlwZS50b1VwcGVyQ2FzZSgpLA0KICAgICAgdm5vZGUucHJvcHMgJiYgdm5vZGUucHJvcHMudHlwZQ0KICAgICk7DQogICAgaWYgKG1vZGVsVG9Vc2UuZ2V0U1NSUHJvcHMpIHsNCiAgICAgIHJldHVybiBtb2RlbFRvVXNlLmdldFNTUlByb3BzKGJpbmRpbmcsIHZub2RlKTsNCiAgICB9DQogIH07DQp9DQoNCmNvbnN0IHN5c3RlbU1vZGlmaWVycyA9IFsiY3RybCIsICJzaGlmdCIsICJhbHQiLCAibWV0YSJdOw0KY29uc3QgbW9kaWZpZXJHdWFyZHMgPSB7DQogIHN0b3A6IChlKSA9PiBlLnN0b3BQcm9wYWdhdGlvbigpLA0KICBwcmV2ZW50OiAoZSkgPT4gZS5wcmV2ZW50RGVmYXVsdCgpLA0KICBzZWxmOiAoZSkgPT4gZS50YXJnZXQgIT09IGUuY3VycmVudFRhcmdldCwNCiAgY3RybDogKGUpID0+ICFlLmN0cmxLZXksDQogIHNoaWZ0OiAoZSkgPT4gIWUuc2hpZnRLZXksDQogIGFsdDogKGUpID0+ICFlLmFsdEtleSwNCiAgbWV0YTogKGUpID0+ICFlLm1ldGFLZXksDQogIGxlZnQ6IChlKSA9PiAiYnV0dG9uIiBpbiBlICYmIGUuYnV0dG9uICE9PSAwLA0KICBtaWRkbGU6IChlKSA9PiAiYnV0dG9uIiBpbiBlICYmIGUuYnV0dG9uICE9PSAxLA0KICByaWdodDogKGUpID0+ICJidXR0b24iIGluIGUgJiYgZS5idXR0b24gIT09IDIsDQogIGV4YWN0OiAoZSwgbW9kaWZpZXJzKSA9PiBzeXN0ZW1Nb2RpZmllcnMuc29tZSgobSkgPT4gZVtgJHttfUtleWBdICYmICFtb2RpZmllcnMuaW5jbHVkZXMobSkpDQp9Ow0KY29uc3Qgd2l0aE1vZGlmaWVycyA9IChmbiwgbW9kaWZpZXJzKSA9PiB7DQogIGNvbnN0IGNhY2hlID0gZm4uX3dpdGhNb2RzIHx8IChmbi5fd2l0aE1vZHMgPSB7fSk7DQogIGNvbnN0IGNhY2hlS2V5ID0gbW9kaWZpZXJzLmpvaW4oIi4iKTsNCiAgcmV0dXJuIGNhY2hlW2NhY2hlS2V5XSB8fCAoY2FjaGVbY2FjaGVLZXldID0gKGV2ZW50LCAuLi5hcmdzKSA9PiB7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtb2RpZmllcnMubGVuZ3RoOyBpKyspIHsNCiAgICAgIGNvbnN0IGd1YXJkID0gbW9kaWZpZXJHdWFyZHNbbW9kaWZpZXJzW2ldXTsNCiAgICAgIGlmIChndWFyZCAmJiBndWFyZChldmVudCwgbW9kaWZpZXJzKSkgcmV0dXJuOw0KICAgIH0NCiAgICByZXR1cm4gZm4oZXZlbnQsIC4uLmFyZ3MpOw0KICB9KTsNCn07DQpjb25zdCBrZXlOYW1lcyA9IHsNCiAgZXNjOiAiZXNjYXBlIiwNCiAgc3BhY2U6ICIgIiwNCiAgdXA6ICJhcnJvdy11cCIsDQogIGxlZnQ6ICJhcnJvdy1sZWZ0IiwNCiAgcmlnaHQ6ICJhcnJvdy1yaWdodCIsDQogIGRvd246ICJhcnJvdy1kb3duIiwNCiAgZGVsZXRlOiAiYmFja3NwYWNlIg0KfTsNCmNvbnN0IHdpdGhLZXlzID0gKGZuLCBtb2RpZmllcnMpID0+IHsNCiAgY29uc3QgY2FjaGUgPSBmbi5fd2l0aEtleXMgfHwgKGZuLl93aXRoS2V5cyA9IHt9KTsNCiAgY29uc3QgY2FjaGVLZXkgPSBtb2RpZmllcnMuam9pbigiLiIpOw0KICByZXR1cm4gY2FjaGVbY2FjaGVLZXldIHx8IChjYWNoZVtjYWNoZUtleV0gPSAoZXZlbnQpID0+IHsNCiAgICBpZiAoISgia2V5IiBpbiBldmVudCkpIHsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgY29uc3QgZXZlbnRLZXkgPSBoeXBoZW5hdGUoZXZlbnQua2V5KTsNCiAgICBpZiAobW9kaWZpZXJzLnNvbWUoDQogICAgICAoaykgPT4gayA9PT0gZXZlbnRLZXkgfHwga2V5TmFtZXNba10gPT09IGV2ZW50S2V5DQogICAgKSkgew0KICAgICAgcmV0dXJuIGZuKGV2ZW50KTsNCiAgICB9DQogIH0pOw0KfTsNCg0KY29uc3QgcmVuZGVyZXJPcHRpb25zID0gLyogQF9fUFVSRV9fICovIGV4dGVuZCh7IHBhdGNoUHJvcCB9LCBub2RlT3BzKTsNCmxldCByZW5kZXJlcjsNCmxldCBlbmFibGVkSHlkcmF0aW9uID0gZmFsc2U7DQpmdW5jdGlvbiBlbnN1cmVSZW5kZXJlcigpIHsNCiAgcmV0dXJuIHJlbmRlcmVyIHx8IChyZW5kZXJlciA9IGNyZWF0ZVJlbmRlcmVyKHJlbmRlcmVyT3B0aW9ucykpOw0KfQ0KZnVuY3Rpb24gZW5zdXJlSHlkcmF0aW9uUmVuZGVyZXIoKSB7DQogIHJlbmRlcmVyID0gZW5hYmxlZEh5ZHJhdGlvbiA/IHJlbmRlcmVyIDogY3JlYXRlSHlkcmF0aW9uUmVuZGVyZXIocmVuZGVyZXJPcHRpb25zKTsNCiAgZW5hYmxlZEh5ZHJhdGlvbiA9IHRydWU7DQogIHJldHVybiByZW5kZXJlcjsNCn0NCmNvbnN0IHJlbmRlciA9ICguLi5hcmdzKSA9PiB7DQogIGVuc3VyZVJlbmRlcmVyKCkucmVuZGVyKC4uLmFyZ3MpOw0KfTsNCmNvbnN0IGh5ZHJhdGUgPSAoLi4uYXJncykgPT4gew0KICBlbnN1cmVIeWRyYXRpb25SZW5kZXJlcigpLmh5ZHJhdGUoLi4uYXJncyk7DQp9Ow0KY29uc3QgY3JlYXRlQXBwID0gKC4uLmFyZ3MpID0+IHsNCiAgY29uc3QgYXBwID0gZW5zdXJlUmVuZGVyZXIoKS5jcmVhdGVBcHAoLi4uYXJncyk7DQogIHsNCiAgICBpbmplY3ROYXRpdmVUYWdDaGVjayhhcHApOw0KICAgIGluamVjdENvbXBpbGVyT3B0aW9uc0NoZWNrKGFwcCk7DQogIH0NCiAgY29uc3QgeyBtb3VudCB9ID0gYXBwOw0KICBhcHAubW91bnQgPSAoY29udGFpbmVyT3JTZWxlY3RvcikgPT4gew0KICAgIGNvbnN0IGNvbnRhaW5lciA9IG5vcm1hbGl6ZUNvbnRhaW5lcihjb250YWluZXJPclNlbGVjdG9yKTsNCiAgICBpZiAoIWNvbnRhaW5lcikgcmV0dXJuOw0KICAgIGNvbnN0IGNvbXBvbmVudCA9IGFwcC5fY29tcG9uZW50Ow0KICAgIGlmICghaXNGdW5jdGlvbihjb21wb25lbnQpICYmICFjb21wb25lbnQucmVuZGVyICYmICFjb21wb25lbnQudGVtcGxhdGUpIHsNCiAgICAgIGNvbXBvbmVudC50ZW1wbGF0ZSA9IGNvbnRhaW5lci5pbm5lckhUTUw7DQogICAgfQ0KICAgIGlmIChjb250YWluZXIubm9kZVR5cGUgPT09IDEpIHsNCiAgICAgIGNvbnRhaW5lci50ZXh0Q29udGVudCA9ICIiOw0KICAgIH0NCiAgICBjb25zdCBwcm94eSA9IG1vdW50KGNvbnRhaW5lciwgZmFsc2UsIHJlc29sdmVSb290TmFtZXNwYWNlKGNvbnRhaW5lcikpOw0KICAgIGlmIChjb250YWluZXIgaW5zdGFuY2VvZiBFbGVtZW50KSB7DQogICAgICBjb250YWluZXIucmVtb3ZlQXR0cmlidXRlKCJ2LWNsb2FrIik7DQogICAgICBjb250YWluZXIuc2V0QXR0cmlidXRlKCJkYXRhLXYtYXBwIiwgIiIpOw0KICAgIH0NCiAgICByZXR1cm4gcHJveHk7DQogIH07DQogIHJldHVybiBhcHA7DQp9Ow0KY29uc3QgY3JlYXRlU1NSQXBwID0gKC4uLmFyZ3MpID0+IHsNCiAgY29uc3QgYXBwID0gZW5zdXJlSHlkcmF0aW9uUmVuZGVyZXIoKS5jcmVhdGVBcHAoLi4uYXJncyk7DQogIHsNCiAgICBpbmplY3ROYXRpdmVUYWdDaGVjayhhcHApOw0KICAgIGluamVjdENvbXBpbGVyT3B0aW9uc0NoZWNrKGFwcCk7DQogIH0NCiAgY29uc3QgeyBtb3VudCB9ID0gYXBwOw0KICBhcHAubW91bnQgPSAoY29udGFpbmVyT3JTZWxlY3RvcikgPT4gew0KICAgIGNvbnN0IGNvbnRhaW5lciA9IG5vcm1hbGl6ZUNvbnRhaW5lcihjb250YWluZXJPclNlbGVjdG9yKTsNCiAgICBpZiAoY29udGFpbmVyKSB7DQogICAgICByZXR1cm4gbW91bnQoY29udGFpbmVyLCB0cnVlLCByZXNvbHZlUm9vdE5hbWVzcGFjZShjb250YWluZXIpKTsNCiAgICB9DQogIH07DQogIHJldHVybiBhcHA7DQp9Ow0KZnVuY3Rpb24gcmVzb2x2ZVJvb3ROYW1lc3BhY2UoY29udGFpbmVyKSB7DQogIGlmIChjb250YWluZXIgaW5zdGFuY2VvZiBTVkdFbGVtZW50KSB7DQogICAgcmV0dXJuICJzdmciOw0KICB9DQogIGlmICh0eXBlb2YgTWF0aE1MRWxlbWVudCA9PT0gImZ1bmN0aW9uIiAmJiBjb250YWluZXIgaW5zdGFuY2VvZiBNYXRoTUxFbGVtZW50KSB7DQogICAgcmV0dXJuICJtYXRobWwiOw0KICB9DQp9DQpmdW5jdGlvbiBpbmplY3ROYXRpdmVUYWdDaGVjayhhcHApIHsNCiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGFwcC5jb25maWcsICJpc05hdGl2ZVRhZyIsIHsNCiAgICB2YWx1ZTogKHRhZykgPT4gaXNIVE1MVGFnKHRhZykgfHwgaXNTVkdUYWcodGFnKSB8fCBpc01hdGhNTFRhZyh0YWcpLA0KICAgIHdyaXRhYmxlOiBmYWxzZQ0KICB9KTsNCn0NCmZ1bmN0aW9uIGluamVjdENvbXBpbGVyT3B0aW9uc0NoZWNrKGFwcCkgew0KICBpZiAoaXNSdW50aW1lT25seSgpKSB7DQogICAgY29uc3QgaXNDdXN0b21FbGVtZW50ID0gYXBwLmNvbmZpZy5pc0N1c3RvbUVsZW1lbnQ7DQogICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGFwcC5jb25maWcsICJpc0N1c3RvbUVsZW1lbnQiLCB7DQogICAgICBnZXQoKSB7DQogICAgICAgIHJldHVybiBpc0N1c3RvbUVsZW1lbnQ7DQogICAgICB9LA0KICAgICAgc2V0KCkgew0KICAgICAgICB3YXJuKA0KICAgICAgICAgIGBUaGUgXGBpc0N1c3RvbUVsZW1lbnRcYCBjb25maWcgb3B0aW9uIGlzIGRlcHJlY2F0ZWQuIFVzZSBcYGNvbXBpbGVyT3B0aW9ucy5pc0N1c3RvbUVsZW1lbnRcYCBpbnN0ZWFkLmANCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICB9KTsNCiAgICBjb25zdCBjb21waWxlck9wdGlvbnMgPSBhcHAuY29uZmlnLmNvbXBpbGVyT3B0aW9uczsNCiAgICBjb25zdCBtc2cgPSBgVGhlIFxgY29tcGlsZXJPcHRpb25zXGAgY29uZmlnIG9wdGlvbiBpcyBvbmx5IHJlc3BlY3RlZCB3aGVuIHVzaW5nIGEgYnVpbGQgb2YgVnVlLmpzIHRoYXQgaW5jbHVkZXMgdGhlIHJ1bnRpbWUgY29tcGlsZXIgKGFrYSAiZnVsbCBidWlsZCIpLiBTaW5jZSB5b3UgYXJlIHVzaW5nIHRoZSBydW50aW1lLW9ubHkgYnVpbGQsIFxgY29tcGlsZXJPcHRpb25zXGAgbXVzdCBiZSBwYXNzZWQgdG8gXGBAdnVlL2NvbXBpbGVyLWRvbVxgIGluIHRoZSBidWlsZCBzZXR1cCBpbnN0ZWFkLg0KLSBGb3IgdnVlLWxvYWRlcjogcGFzcyBpdCB2aWEgdnVlLWxvYWRlcidzIFxgY29tcGlsZXJPcHRpb25zXGAgbG9hZGVyIG9wdGlvbi4NCi0gRm9yIHZ1ZS1jbGk6IHNlZSBodHRwczovL2NsaS52dWVqcy5vcmcvZ3VpZGUvd2VicGFjay5odG1sI21vZGlmeWluZy1vcHRpb25zLW9mLWEtbG9hZGVyDQotIEZvciB2aXRlOiBwYXNzIGl0IHZpYSBAdml0ZWpzL3BsdWdpbi12dWUgb3B0aW9ucy4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS92aXRlanMvdml0ZS1wbHVnaW4tdnVlL3RyZWUvbWFpbi9wYWNrYWdlcy9wbHVnaW4tdnVlI2V4YW1wbGUtZm9yLXBhc3Npbmctb3B0aW9ucy10by12dWVjb21waWxlci1zZmNgOw0KICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhcHAuY29uZmlnLCAiY29tcGlsZXJPcHRpb25zIiwgew0KICAgICAgZ2V0KCkgew0KICAgICAgICB3YXJuKG1zZyk7DQogICAgICAgIHJldHVybiBjb21waWxlck9wdGlvbnM7DQogICAgICB9LA0KICAgICAgc2V0KCkgew0KICAgICAgICB3YXJuKG1zZyk7DQogICAgICB9DQogICAgfSk7DQogIH0NCn0NCmZ1bmN0aW9uIG5vcm1hbGl6ZUNvbnRhaW5lcihjb250YWluZXIpIHsNCiAgaWYgKGlzU3RyaW5nKGNvbnRhaW5lcikpIHsNCiAgICBjb25zdCByZXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGNvbnRhaW5lcik7DQogICAgaWYgKCFyZXMpIHsNCiAgICAgIHdhcm4oDQogICAgICAgIGBGYWlsZWQgdG8gbW91bnQgYXBwOiBtb3VudCB0YXJnZXQgc2VsZWN0b3IgIiR7Y29udGFpbmVyfSIgcmV0dXJuZWQgbnVsbC5gDQogICAgICApOw0KICAgIH0NCiAgICByZXR1cm4gcmVzOw0KICB9DQogIGlmICh3aW5kb3cuU2hhZG93Um9vdCAmJiBjb250YWluZXIgaW5zdGFuY2VvZiB3aW5kb3cuU2hhZG93Um9vdCAmJiBjb250YWluZXIubW9kZSA9PT0gImNsb3NlZCIpIHsNCiAgICB3YXJuKA0KICAgICAgYG1vdW50aW5nIG9uIGEgU2hhZG93Um9vdCB3aXRoIFxge21vZGU6ICJjbG9zZWQifVxgIG1heSBsZWFkIHRvIHVucHJlZGljdGFibGUgYnVnc2ANCiAgICApOw0KICB9DQogIHJldHVybiBjb250YWluZXI7DQp9DQpsZXQgc3NyRGlyZWN0aXZlSW5pdGlhbGl6ZWQgPSBmYWxzZTsNCmNvbnN0IGluaXREaXJlY3RpdmVzRm9yU1NSID0gKCkgPT4gew0KICBpZiAoIXNzckRpcmVjdGl2ZUluaXRpYWxpemVkKSB7DQogICAgc3NyRGlyZWN0aXZlSW5pdGlhbGl6ZWQgPSB0cnVlOw0KICAgIGluaXRWTW9kZWxGb3JTU1IoKTsNCiAgICBpbml0VlNob3dGb3JTU1IoKTsNCiAgfQ0KfSA7DQoNCmV4cG9ydCB7IEJhc2VUcmFuc2l0aW9uLCBCYXNlVHJhbnNpdGlvblByb3BzVmFsaWRhdG9ycywgQ29tbWVudCwgRGVwcmVjYXRpb25UeXBlcywgRWZmZWN0U2NvcGUsIEVycm9yQ29kZXMsIEVycm9yVHlwZVN0cmluZ3MsIEZyYWdtZW50LCBLZWVwQWxpdmUsIFJlYWN0aXZlRWZmZWN0LCBTdGF0aWMsIFN1c3BlbnNlLCBUZWxlcG9ydCwgVGV4dCwgVHJhY2tPcFR5cGVzLCBUcmFuc2l0aW9uLCBUcmFuc2l0aW9uR3JvdXAsIFRyaWdnZXJPcFR5cGVzLCBWdWVFbGVtZW50LCBhc3NlcnROdW1iZXIsIGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nLCBjYWxsV2l0aEVycm9ySGFuZGxpbmcsIGNhbWVsaXplLCBjYXBpdGFsaXplLCBjbG9uZVZOb2RlLCBjb21wYXRVdGlscywgY29tcHV0ZWQsIGNyZWF0ZUFwcCwgY3JlYXRlQmxvY2ssIGNyZWF0ZUNvbW1lbnRWTm9kZSwgY3JlYXRlRWxlbWVudEJsb2NrLCBjcmVhdGVCYXNlVk5vZGUgYXMgY3JlYXRlRWxlbWVudFZOb2RlLCBjcmVhdGVIeWRyYXRpb25SZW5kZXJlciwgY3JlYXRlUHJvcHNSZXN0UHJveHksIGNyZWF0ZVJlbmRlcmVyLCBjcmVhdGVTU1JBcHAsIGNyZWF0ZVNsb3RzLCBjcmVhdGVTdGF0aWNWTm9kZSwgY3JlYXRlVGV4dFZOb2RlLCBjcmVhdGVWTm9kZSwgY3VzdG9tUmVmLCBkZWZpbmVBc3luY0NvbXBvbmVudCwgZGVmaW5lQ29tcG9uZW50LCBkZWZpbmVDdXN0b21FbGVtZW50LCBkZWZpbmVFbWl0cywgZGVmaW5lRXhwb3NlLCBkZWZpbmVNb2RlbCwgZGVmaW5lT3B0aW9ucywgZGVmaW5lUHJvcHMsIGRlZmluZVNTUkN1c3RvbUVsZW1lbnQsIGRlZmluZVNsb3RzLCBkZXZ0b29scywgZWZmZWN0LCBlZmZlY3RTY29wZSwgZ2V0Q3VycmVudEluc3RhbmNlLCBnZXRDdXJyZW50U2NvcGUsIGdldEN1cnJlbnRXYXRjaGVyLCBnZXRUcmFuc2l0aW9uUmF3Q2hpbGRyZW4sIGd1YXJkUmVhY3RpdmVQcm9wcywgaCwgaGFuZGxlRXJyb3IsIGhhc0luamVjdGlvbkNvbnRleHQsIGh5ZHJhdGUsIGh5ZHJhdGVPbklkbGUsIGh5ZHJhdGVPbkludGVyYWN0aW9uLCBoeWRyYXRlT25NZWRpYVF1ZXJ5LCBoeWRyYXRlT25WaXNpYmxlLCBpbml0Q3VzdG9tRm9ybWF0dGVyLCBpbml0RGlyZWN0aXZlc0ZvclNTUiwgaW5qZWN0LCBpc01lbW9TYW1lLCBpc1Byb3h5LCBpc1JlYWN0aXZlLCBpc1JlYWRvbmx5LCBpc1JlZiwgaXNSdW50aW1lT25seSwgaXNTaGFsbG93LCBpc1ZOb2RlLCBtYXJrUmF3LCBtZXJnZURlZmF1bHRzLCBtZXJnZU1vZGVscywgbWVyZ2VQcm9wcywgbmV4dFRpY2ssIG5vcm1hbGl6ZUNsYXNzLCBub3JtYWxpemVQcm9wcywgbm9ybWFsaXplU3R5bGUsIG9uQWN0aXZhdGVkLCBvbkJlZm9yZU1vdW50LCBvbkJlZm9yZVVubW91bnQsIG9uQmVmb3JlVXBkYXRlLCBvbkRlYWN0aXZhdGVkLCBvbkVycm9yQ2FwdHVyZWQsIG9uTW91bnRlZCwgb25SZW5kZXJUcmFja2VkLCBvblJlbmRlclRyaWdnZXJlZCwgb25TY29wZURpc3Bvc2UsIG9uU2VydmVyUHJlZmV0Y2gsIG9uVW5tb3VudGVkLCBvblVwZGF0ZWQsIG9uV2F0Y2hlckNsZWFudXAsIG9wZW5CbG9jaywgcG9wU2NvcGVJZCwgcHJvdmlkZSwgcHJveHlSZWZzLCBwdXNoU2NvcGVJZCwgcXVldWVQb3N0Rmx1c2hDYiwgcmVhY3RpdmUsIHJlYWRvbmx5LCByZWYsIHJlZ2lzdGVyUnVudGltZUNvbXBpbGVyLCByZW5kZXIsIHJlbmRlckxpc3QsIHJlbmRlclNsb3QsIHJlc29sdmVDb21wb25lbnQsIHJlc29sdmVEaXJlY3RpdmUsIHJlc29sdmVEeW5hbWljQ29tcG9uZW50LCByZXNvbHZlRmlsdGVyLCByZXNvbHZlVHJhbnNpdGlvbkhvb2tzLCBzZXRCbG9ja1RyYWNraW5nLCBzZXREZXZ0b29sc0hvb2ssIHNldFRyYW5zaXRpb25Ib29rcywgc2hhbGxvd1JlYWN0aXZlLCBzaGFsbG93UmVhZG9ubHksIHNoYWxsb3dSZWYsIHNzckNvbnRleHRLZXksIHNzclV0aWxzLCBzdG9wLCB0b0Rpc3BsYXlTdHJpbmcsIHRvSGFuZGxlcktleSwgdG9IYW5kbGVycywgdG9SYXcsIHRvUmVmLCB0b1JlZnMsIHRvVmFsdWUsIHRyYW5zZm9ybVZOb2RlQXJncywgdHJpZ2dlclJlZiwgdW5yZWYsIHVzZUF0dHJzLCB1c2VDc3NNb2R1bGUsIHVzZUNzc1ZhcnMsIHVzZUhvc3QsIHVzZUlkLCB1c2VNb2RlbCwgdXNlU1NSQ29udGV4dCwgdXNlU2hhZG93Um9vdCwgdXNlU2xvdHMsIHVzZVRlbXBsYXRlUmVmLCB1c2VUcmFuc2l0aW9uU3RhdGUsIHZNb2RlbENoZWNrYm94LCB2TW9kZWxEeW5hbWljLCB2TW9kZWxSYWRpbywgdk1vZGVsU2VsZWN0LCB2TW9kZWxUZXh0LCB2U2hvdywgdmVyc2lvbiwgd2Fybiwgd2F0Y2gsIHdhdGNoRWZmZWN0LCB3YXRjaFBvc3RFZmZlY3QsIHdhdGNoU3luY0VmZmVjdCwgd2l0aEFzeW5jQ29udGV4dCwgd2l0aEN0eCwgd2l0aERlZmF1bHRzLCB3aXRoRGlyZWN0aXZlcywgd2l0aEtleXMsIHdpdGhNZW1vLCB3aXRoTW9kaWZpZXJzLCB3aXRoU2NvcGVJZCB9Ow0K",Inn="data:text/javascript;base64,LyoqDQoqIEB2dWUvc2VydmVyLXJlbmRlcmVyIHYzLjUuMTcNCiogKGMpIDIwMTgtcHJlc2VudCBZdXhpIChFdmFuKSBZb3UgYW5kIFZ1ZSBjb250cmlidXRvcnMNCiogQGxpY2Vuc2UgTUlUDQoqKi8NCi8qISAjX19OT19TSURFX0VGRkVDVFNfXyAqLw0KLy8gQF9fTk9fU0lERV9FRkZFQ1RTX18NCmZ1bmN0aW9uIG1ha2VNYXAoc3RyKSB7DQogIGNvbnN0IG1hcCA9IC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuY3JlYXRlKG51bGwpOw0KICBmb3IgKGNvbnN0IGtleSBvZiBzdHIuc3BsaXQoIiwiKSkgbWFwW2tleV0gPSAxOw0KICByZXR1cm4gKHZhbCkgPT4gdmFsIGluIG1hcDsNCn0NCg0KY29uc3QgRU1QVFlfT0JKID0gT2JqZWN0LmZyZWV6ZSh7fSkgOw0KY29uc3QgRU1QVFlfQVJSID0gT2JqZWN0LmZyZWV6ZShbXSkgOw0KY29uc3QgTk9PUCA9ICgpID0+IHsNCn07DQpjb25zdCBOTyA9ICgpID0+IGZhbHNlOw0KY29uc3QgaXNPbiA9IChrZXkpID0+IGtleS5jaGFyQ29kZUF0KDApID09PSAxMTEgJiYga2V5LmNoYXJDb2RlQXQoMSkgPT09IDExMCAmJiAvLyB1cHBlcmNhc2UgbGV0dGVyDQooa2V5LmNoYXJDb2RlQXQoMikgPiAxMjIgfHwga2V5LmNoYXJDb2RlQXQoMikgPCA5Nyk7DQpjb25zdCBpc01vZGVsTGlzdGVuZXIgPSAoa2V5KSA9PiBrZXkuc3RhcnRzV2l0aCgib25VcGRhdGU6Iik7DQpjb25zdCBleHRlbmQgPSBPYmplY3QuYXNzaWduOw0KY29uc3QgcmVtb3ZlID0gKGFyciwgZWwpID0+IHsNCiAgY29uc3QgaSA9IGFyci5pbmRleE9mKGVsKTsNCiAgaWYgKGkgPiAtMSkgew0KICAgIGFyci5zcGxpY2UoaSwgMSk7DQogIH0NCn07DQpjb25zdCBoYXNPd25Qcm9wZXJ0eSQxID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTsNCmNvbnN0IGhhc093biA9ICh2YWwsIGtleSkgPT4gaGFzT3duUHJvcGVydHkkMS5jYWxsKHZhbCwga2V5KTsNCmNvbnN0IGlzQXJyYXkgPSBBcnJheS5pc0FycmF5Ow0KY29uc3QgaXNNYXAgPSAodmFsKSA9PiB0b1R5cGVTdHJpbmcodmFsKSA9PT0gIltvYmplY3QgTWFwXSI7DQpjb25zdCBpc1NldCA9ICh2YWwpID0+IHRvVHlwZVN0cmluZyh2YWwpID09PSAiW29iamVjdCBTZXRdIjsNCmNvbnN0IGlzRGF0ZSA9ICh2YWwpID0+IHRvVHlwZVN0cmluZyh2YWwpID09PSAiW29iamVjdCBEYXRlXSI7DQpjb25zdCBpc0Z1bmN0aW9uID0gKHZhbCkgPT4gdHlwZW9mIHZhbCA9PT0gImZ1bmN0aW9uIjsNCmNvbnN0IGlzU3RyaW5nID0gKHZhbCkgPT4gdHlwZW9mIHZhbCA9PT0gInN0cmluZyI7DQpjb25zdCBpc1N5bWJvbCA9ICh2YWwpID0+IHR5cGVvZiB2YWwgPT09ICJzeW1ib2wiOw0KY29uc3QgaXNPYmplY3QgPSAodmFsKSA9PiB2YWwgIT09IG51bGwgJiYgdHlwZW9mIHZhbCA9PT0gIm9iamVjdCI7DQpjb25zdCBpc1Byb21pc2UgPSAodmFsKSA9PiB7DQogIHJldHVybiAoaXNPYmplY3QodmFsKSB8fCBpc0Z1bmN0aW9uKHZhbCkpICYmIGlzRnVuY3Rpb24odmFsLnRoZW4pICYmIGlzRnVuY3Rpb24odmFsLmNhdGNoKTsNCn07DQpjb25zdCBvYmplY3RUb1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7DQpjb25zdCB0b1R5cGVTdHJpbmcgPSAodmFsdWUpID0+IG9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpOw0KY29uc3QgdG9SYXdUeXBlID0gKHZhbHVlKSA9PiB7DQogIHJldHVybiB0b1R5cGVTdHJpbmcodmFsdWUpLnNsaWNlKDgsIC0xKTsNCn07DQpjb25zdCBpc1BsYWluT2JqZWN0ID0gKHZhbCkgPT4gdG9UeXBlU3RyaW5nKHZhbCkgPT09ICJbb2JqZWN0IE9iamVjdF0iOw0KY29uc3QgaXNJbnRlZ2VyS2V5ID0gKGtleSkgPT4gaXNTdHJpbmcoa2V5KSAmJiBrZXkgIT09ICJOYU4iICYmIGtleVswXSAhPT0gIi0iICYmICIiICsgcGFyc2VJbnQoa2V5LCAxMCkgPT09IGtleTsNCmNvbnN0IGlzUmVzZXJ2ZWRQcm9wID0gLyogQF9fUFVSRV9fICovIG1ha2VNYXAoDQogIC8vIHRoZSBsZWFkaW5nIGNvbW1hIGlzIGludGVudGlvbmFsIHNvIGVtcHR5IHN0cmluZyAiIiBpcyBhbHNvIGluY2x1ZGVkDQogICIsa2V5LHJlZixyZWZfZm9yLHJlZl9rZXksb25Wbm9kZUJlZm9yZU1vdW50LG9uVm5vZGVNb3VudGVkLG9uVm5vZGVCZWZvcmVVcGRhdGUsb25Wbm9kZVVwZGF0ZWQsb25Wbm9kZUJlZm9yZVVubW91bnQsb25Wbm9kZVVubW91bnRlZCINCik7DQpjb25zdCBpc0J1aWx0SW5EaXJlY3RpdmUgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcCgNCiAgImJpbmQsY2xvYWssZWxzZS1pZixlbHNlLGZvcixodG1sLGlmLG1vZGVsLG9uLG9uY2UscHJlLHNob3csc2xvdCx0ZXh0LG1lbW8iDQopOw0KY29uc3QgY2FjaGVTdHJpbmdGdW5jdGlvbiA9IChmbikgPT4gew0KICBjb25zdCBjYWNoZSA9IC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuY3JlYXRlKG51bGwpOw0KICByZXR1cm4gKHN0cikgPT4gew0KICAgIGNvbnN0IGhpdCA9IGNhY2hlW3N0cl07DQogICAgcmV0dXJuIGhpdCB8fCAoY2FjaGVbc3RyXSA9IGZuKHN0cikpOw0KICB9Ow0KfTsNCmNvbnN0IGNhbWVsaXplUkUgPSAvLShcdykvZzsNCmNvbnN0IGNhbWVsaXplID0gY2FjaGVTdHJpbmdGdW5jdGlvbigNCiAgKHN0cikgPT4gew0KICAgIHJldHVybiBzdHIucmVwbGFjZShjYW1lbGl6ZVJFLCAoXywgYykgPT4gYyA/IGMudG9VcHBlckNhc2UoKSA6ICIiKTsNCiAgfQ0KKTsNCmNvbnN0IGh5cGhlbmF0ZVJFID0gL1xCKFtBLVpdKS9nOw0KY29uc3QgaHlwaGVuYXRlID0gY2FjaGVTdHJpbmdGdW5jdGlvbigNCiAgKHN0cikgPT4gc3RyLnJlcGxhY2UoaHlwaGVuYXRlUkUsICItJDEiKS50b0xvd2VyQ2FzZSgpDQopOw0KY29uc3QgY2FwaXRhbGl6ZSA9IGNhY2hlU3RyaW5nRnVuY3Rpb24oKHN0cikgPT4gew0KICByZXR1cm4gc3RyLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3RyLnNsaWNlKDEpOw0KfSk7DQpjb25zdCB0b0hhbmRsZXJLZXkgPSBjYWNoZVN0cmluZ0Z1bmN0aW9uKA0KICAoc3RyKSA9PiB7DQogICAgY29uc3QgcyA9IHN0ciA/IGBvbiR7Y2FwaXRhbGl6ZShzdHIpfWAgOiBgYDsNCiAgICByZXR1cm4gczsNCiAgfQ0KKTsNCmNvbnN0IGhhc0NoYW5nZWQgPSAodmFsdWUsIG9sZFZhbHVlKSA9PiAhT2JqZWN0LmlzKHZhbHVlLCBvbGRWYWx1ZSk7DQpjb25zdCBpbnZva2VBcnJheUZucyA9IChmbnMsIC4uLmFyZykgPT4gew0KICBmb3IgKGxldCBpID0gMDsgaSA8IGZucy5sZW5ndGg7IGkrKykgew0KICAgIGZuc1tpXSguLi5hcmcpOw0KICB9DQp9Ow0KY29uc3QgZGVmID0gKG9iaiwga2V5LCB2YWx1ZSwgd3JpdGFibGUgPSBmYWxzZSkgPT4gew0KICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBrZXksIHsNCiAgICBjb25maWd1cmFibGU6IHRydWUsDQogICAgZW51bWVyYWJsZTogZmFsc2UsDQogICAgd3JpdGFibGUsDQogICAgdmFsdWUNCiAgfSk7DQp9Ow0KY29uc3QgbG9vc2VUb051bWJlciA9ICh2YWwpID0+IHsNCiAgY29uc3QgbiA9IHBhcnNlRmxvYXQodmFsKTsNCiAgcmV0dXJuIGlzTmFOKG4pID8gdmFsIDogbjsNCn07DQpsZXQgX2dsb2JhbFRoaXM7DQpjb25zdCBnZXRHbG9iYWxUaGlzID0gKCkgPT4gew0KICByZXR1cm4gX2dsb2JhbFRoaXMgfHwgKF9nbG9iYWxUaGlzID0gdHlwZW9mIGdsb2JhbFRoaXMgIT09ICJ1bmRlZmluZWQiID8gZ2xvYmFsVGhpcyA6IHR5cGVvZiBzZWxmICE9PSAidW5kZWZpbmVkIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSAidW5kZWZpbmVkIiA/IHdpbmRvdyA6IHR5cGVvZiBnbG9iYWwgIT09ICJ1bmRlZmluZWQiID8gZ2xvYmFsIDoge30pOw0KfTsNCg0KZnVuY3Rpb24gbm9ybWFsaXplU3R5bGUodmFsdWUpIHsNCiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7DQogICAgY29uc3QgcmVzID0ge307DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykgew0KICAgICAgY29uc3QgaXRlbSA9IHZhbHVlW2ldOw0KICAgICAgY29uc3Qgbm9ybWFsaXplZCA9IGlzU3RyaW5nKGl0ZW0pID8gcGFyc2VTdHJpbmdTdHlsZShpdGVtKSA6IG5vcm1hbGl6ZVN0eWxlKGl0ZW0pOw0KICAgICAgaWYgKG5vcm1hbGl6ZWQpIHsNCiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gbm9ybWFsaXplZCkgew0KICAgICAgICAgIHJlc1trZXldID0gbm9ybWFsaXplZFtrZXldOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICAgIHJldHVybiByZXM7DQogIH0gZWxzZSBpZiAoaXNTdHJpbmcodmFsdWUpIHx8IGlzT2JqZWN0KHZhbHVlKSkgew0KICAgIHJldHVybiB2YWx1ZTsNCiAgfQ0KfQ0KY29uc3QgbGlzdERlbGltaXRlclJFID0gLzsoPyFbXihdKlwpKS9nOw0KY29uc3QgcHJvcGVydHlEZWxpbWl0ZXJSRSA9IC86KFteXSspLzsNCmNvbnN0IHN0eWxlQ29tbWVudFJFID0gL1wvXCpbXl0qP1wqXC8vZzsNCmZ1bmN0aW9uIHBhcnNlU3RyaW5nU3R5bGUoY3NzVGV4dCkgew0KICBjb25zdCByZXQgPSB7fTsNCiAgY3NzVGV4dC5yZXBsYWNlKHN0eWxlQ29tbWVudFJFLCAiIikuc3BsaXQobGlzdERlbGltaXRlclJFKS5mb3JFYWNoKChpdGVtKSA9PiB7DQogICAgaWYgKGl0ZW0pIHsNCiAgICAgIGNvbnN0IHRtcCA9IGl0ZW0uc3BsaXQocHJvcGVydHlEZWxpbWl0ZXJSRSk7DQogICAgICB0bXAubGVuZ3RoID4gMSAmJiAocmV0W3RtcFswXS50cmltKCldID0gdG1wWzFdLnRyaW0oKSk7DQogICAgfQ0KICB9KTsNCiAgcmV0dXJuIHJldDsNCn0NCmZ1bmN0aW9uIHN0cmluZ2lmeVN0eWxlKHN0eWxlcykgew0KICBpZiAoIXN0eWxlcykgcmV0dXJuICIiOw0KICBpZiAoaXNTdHJpbmcoc3R5bGVzKSkgcmV0dXJuIHN0eWxlczsNCiAgbGV0IHJldCA9ICIiOw0KICBmb3IgKGNvbnN0IGtleSBpbiBzdHlsZXMpIHsNCiAgICBjb25zdCB2YWx1ZSA9IHN0eWxlc1trZXldOw0KICAgIGlmIChpc1N0cmluZyh2YWx1ZSkgfHwgdHlwZW9mIHZhbHVlID09PSAibnVtYmVyIikgew0KICAgICAgY29uc3Qgbm9ybWFsaXplZEtleSA9IGtleS5zdGFydHNXaXRoKGAtLWApID8ga2V5IDogaHlwaGVuYXRlKGtleSk7DQogICAgICByZXQgKz0gYCR7bm9ybWFsaXplZEtleX06JHt2YWx1ZX07YDsNCiAgICB9DQogIH0NCiAgcmV0dXJuIHJldDsNCn0NCmZ1bmN0aW9uIG5vcm1hbGl6ZUNsYXNzKHZhbHVlKSB7DQogIGxldCByZXMgPSAiIjsNCiAgaWYgKGlzU3RyaW5nKHZhbHVlKSkgew0KICAgIHJlcyA9IHZhbHVlOw0KICB9IGVsc2UgaWYgKGlzQXJyYXkodmFsdWUpKSB7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykgew0KICAgICAgY29uc3Qgbm9ybWFsaXplZCA9IG5vcm1hbGl6ZUNsYXNzKHZhbHVlW2ldKTsNCiAgICAgIGlmIChub3JtYWxpemVkKSB7DQogICAgICAgIHJlcyArPSBub3JtYWxpemVkICsgIiAiOw0KICAgICAgfQ0KICAgIH0NCiAgfSBlbHNlIGlmIChpc09iamVjdCh2YWx1ZSkpIHsNCiAgICBmb3IgKGNvbnN0IG5hbWUgaW4gdmFsdWUpIHsNCiAgICAgIGlmICh2YWx1ZVtuYW1lXSkgew0KICAgICAgICByZXMgKz0gbmFtZSArICIgIjsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgcmV0dXJuIHJlcy50cmltKCk7DQp9DQoNCmNvbnN0IEhUTUxfVEFHUyA9ICJodG1sLGJvZHksYmFzZSxoZWFkLGxpbmssbWV0YSxzdHlsZSx0aXRsZSxhZGRyZXNzLGFydGljbGUsYXNpZGUsZm9vdGVyLGhlYWRlcixoZ3JvdXAsaDEsaDIsaDMsaDQsaDUsaDYsbmF2LHNlY3Rpb24sZGl2LGRkLGRsLGR0LGZpZ2NhcHRpb24sZmlndXJlLHBpY3R1cmUsaHIsaW1nLGxpLG1haW4sb2wscCxwcmUsdWwsYSxiLGFiYnIsYmRpLGJkbyxicixjaXRlLGNvZGUsZGF0YSxkZm4sZW0saSxrYmQsbWFyayxxLHJwLHJ0LHJ1YnkscyxzYW1wLHNtYWxsLHNwYW4sc3Ryb25nLHN1YixzdXAsdGltZSx1LHZhcix3YnIsYXJlYSxhdWRpbyxtYXAsdHJhY2ssdmlkZW8sZW1iZWQsb2JqZWN0LHBhcmFtLHNvdXJjZSxjYW52YXMsc2NyaXB0LG5vc2NyaXB0LGRlbCxpbnMsY2FwdGlvbixjb2wsY29sZ3JvdXAsdGFibGUsdGhlYWQsdGJvZHksdGQsdGgsdHIsYnV0dG9uLGRhdGFsaXN0LGZpZWxkc2V0LGZvcm0saW5wdXQsbGFiZWwsbGVnZW5kLG1ldGVyLG9wdGdyb3VwLG9wdGlvbixvdXRwdXQscHJvZ3Jlc3Msc2VsZWN0LHRleHRhcmVhLGRldGFpbHMsZGlhbG9nLG1lbnUsc3VtbWFyeSx0ZW1wbGF0ZSxibG9ja3F1b3RlLGlmcmFtZSx0Zm9vdCI7DQpjb25zdCBTVkdfVEFHUyA9ICJzdmcsYW5pbWF0ZSxhbmltYXRlTW90aW9uLGFuaW1hdGVUcmFuc2Zvcm0sY2lyY2xlLGNsaXBQYXRoLGNvbG9yLXByb2ZpbGUsZGVmcyxkZXNjLGRpc2NhcmQsZWxsaXBzZSxmZUJsZW5kLGZlQ29sb3JNYXRyaXgsZmVDb21wb25lbnRUcmFuc2ZlcixmZUNvbXBvc2l0ZSxmZUNvbnZvbHZlTWF0cml4LGZlRGlmZnVzZUxpZ2h0aW5nLGZlRGlzcGxhY2VtZW50TWFwLGZlRGlzdGFudExpZ2h0LGZlRHJvcFNoYWRvdyxmZUZsb29kLGZlRnVuY0EsZmVGdW5jQixmZUZ1bmNHLGZlRnVuY1IsZmVHYXVzc2lhbkJsdXIsZmVJbWFnZSxmZU1lcmdlLGZlTWVyZ2VOb2RlLGZlTW9ycGhvbG9neSxmZU9mZnNldCxmZVBvaW50TGlnaHQsZmVTcGVjdWxhckxpZ2h0aW5nLGZlU3BvdExpZ2h0LGZlVGlsZSxmZVR1cmJ1bGVuY2UsZmlsdGVyLGZvcmVpZ25PYmplY3QsZyxoYXRjaCxoYXRjaHBhdGgsaW1hZ2UsbGluZSxsaW5lYXJHcmFkaWVudCxtYXJrZXIsbWFzayxtZXNoLG1lc2hncmFkaWVudCxtZXNocGF0Y2gsbWVzaHJvdyxtZXRhZGF0YSxtcGF0aCxwYXRoLHBhdHRlcm4scG9seWdvbixwb2x5bGluZSxyYWRpYWxHcmFkaWVudCxyZWN0LHNldCxzb2xpZGNvbG9yLHN0b3Asc3dpdGNoLHN5bWJvbCx0ZXh0LHRleHRQYXRoLHRpdGxlLHRzcGFuLHVua25vd24sdXNlLHZpZXciOw0KY29uc3QgTUFUSF9UQUdTID0gImFubm90YXRpb24sYW5ub3RhdGlvbi14bWwsbWFjdGlvbixtYWxpZ25ncm91cCxtYWxpZ25tYXJrLG1hdGgsbWVuY2xvc2UsbWVycm9yLG1mZW5jZWQsbWZyYWMsbWZyYWN0aW9uLG1nbHlwaCxtaSxtbGFiZWxlZHRyLG1sb25nZGl2LG1tdWx0aXNjcmlwdHMsbW4sbW8sbW92ZXIsbXBhZGRlZCxtcGhhbnRvbSxtcHJlc2NyaXB0cyxtcm9vdCxtcm93LG1zLG1zY2Fycmllcyxtc2NhcnJ5LG1zZ3JvdXAsbXNsaW5lLG1zcGFjZSxtc3FydCxtc3Jvdyxtc3RhY2ssbXN0eWxlLG1zdWIsbXN1YnN1cCxtc3VwLG10YWJsZSxtdGQsbXRleHQsbXRyLG11bmRlcixtdW5kZXJvdmVyLG5vbmUsc2VtYW50aWNzIjsNCmNvbnN0IFZPSURfVEFHUyA9ICJhcmVhLGJhc2UsYnIsY29sLGVtYmVkLGhyLGltZyxpbnB1dCxsaW5rLG1ldGEscGFyYW0sc291cmNlLHRyYWNrLHdiciI7DQpjb25zdCBpc0hUTUxUYWcgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcChIVE1MX1RBR1MpOw0KY29uc3QgaXNTVkdUYWcgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcChTVkdfVEFHUyk7DQpjb25zdCBpc01hdGhNTFRhZyA9IC8qIEBfX1BVUkVfXyAqLyBtYWtlTWFwKE1BVEhfVEFHUyk7DQpjb25zdCBpc1ZvaWRUYWcgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcChWT0lEX1RBR1MpOw0KDQpjb25zdCBzcGVjaWFsQm9vbGVhbkF0dHJzID0gYGl0ZW1zY29wZSxhbGxvd2Z1bGxzY3JlZW4sZm9ybW5vdmFsaWRhdGUsaXNtYXAsbm9tb2R1bGUsbm92YWxpZGF0ZSxyZWFkb25seWA7DQpjb25zdCBpc1NwZWNpYWxCb29sZWFuQXR0ciA9IC8qIEBfX1BVUkVfXyAqLyBtYWtlTWFwKHNwZWNpYWxCb29sZWFuQXR0cnMpOw0KY29uc3QgaXNCb29sZWFuQXR0ciA9IC8qIEBfX1BVUkVfXyAqLyBtYWtlTWFwKA0KICBzcGVjaWFsQm9vbGVhbkF0dHJzICsgYCxhc3luYyxhdXRvZm9jdXMsYXV0b3BsYXksY29udHJvbHMsZGVmYXVsdCxkZWZlcixkaXNhYmxlZCxoaWRkZW4saW5lcnQsbG9vcCxvcGVuLHJlcXVpcmVkLHJldmVyc2VkLHNjb3BlZCxzZWFtbGVzcyxjaGVja2VkLG11dGVkLG11bHRpcGxlLHNlbGVjdGVkYA0KKTsNCmZ1bmN0aW9uIGluY2x1ZGVCb29sZWFuQXR0cih2YWx1ZSkgew0KICByZXR1cm4gISF2YWx1ZSB8fCB2YWx1ZSA9PT0gIiI7DQp9DQpjb25zdCB1bnNhZmVBdHRyQ2hhclJFID0gL1s+Lz0iJ1x1MDAwOVx1MDAwYVx1MDAwY1x1MDAyMF0vOw0KY29uc3QgYXR0clZhbGlkYXRpb25DYWNoZSA9IHt9Ow0KZnVuY3Rpb24gaXNTU1JTYWZlQXR0ck5hbWUobmFtZSkgew0KICBpZiAoYXR0clZhbGlkYXRpb25DYWNoZS5oYXNPd25Qcm9wZXJ0eShuYW1lKSkgew0KICAgIHJldHVybiBhdHRyVmFsaWRhdGlvbkNhY2hlW25hbWVdOw0KICB9DQogIGNvbnN0IGlzVW5zYWZlID0gdW5zYWZlQXR0ckNoYXJSRS50ZXN0KG5hbWUpOw0KICBpZiAoaXNVbnNhZmUpIHsNCiAgICBjb25zb2xlLmVycm9yKGB1bnNhZmUgYXR0cmlidXRlIG5hbWU6ICR7bmFtZX1gKTsNCiAgfQ0KICByZXR1cm4gYXR0clZhbGlkYXRpb25DYWNoZVtuYW1lXSA9ICFpc1Vuc2FmZTsNCn0NCmNvbnN0IHByb3BzVG9BdHRyTWFwID0gew0KICBhY2NlcHRDaGFyc2V0OiAiYWNjZXB0LWNoYXJzZXQiLA0KICBjbGFzc05hbWU6ICJjbGFzcyIsDQogIGh0bWxGb3I6ICJmb3IiLA0KICBodHRwRXF1aXY6ICJodHRwLWVxdWl2Ig0KfTsNCmZ1bmN0aW9uIGlzUmVuZGVyYWJsZUF0dHJWYWx1ZSh2YWx1ZSkgew0KICBpZiAodmFsdWUgPT0gbnVsbCkgew0KICAgIHJldHVybiBmYWxzZTsNCiAgfQ0KICBjb25zdCB0eXBlID0gdHlwZW9mIHZhbHVlOw0KICByZXR1cm4gdHlwZSA9PT0gInN0cmluZyIgfHwgdHlwZSA9PT0gIm51bWJlciIgfHwgdHlwZSA9PT0gImJvb2xlYW4iOw0KfQ0KDQpjb25zdCBlc2NhcGVSRSA9IC9bIicmPD5dLzsNCmZ1bmN0aW9uIGVzY2FwZUh0bWwoc3RyaW5nKSB7DQogIGNvbnN0IHN0ciA9ICIiICsgc3RyaW5nOw0KICBjb25zdCBtYXRjaCA9IGVzY2FwZVJFLmV4ZWMoc3RyKTsNCiAgaWYgKCFtYXRjaCkgew0KICAgIHJldHVybiBzdHI7DQogIH0NCiAgbGV0IGh0bWwgPSAiIjsNCiAgbGV0IGVzY2FwZWQ7DQogIGxldCBpbmRleDsNCiAgbGV0IGxhc3RJbmRleCA9IDA7DQogIGZvciAoaW5kZXggPSBtYXRjaC5pbmRleDsgaW5kZXggPCBzdHIubGVuZ3RoOyBpbmRleCsrKSB7DQogICAgc3dpdGNoIChzdHIuY2hhckNvZGVBdChpbmRleCkpIHsNCiAgICAgIGNhc2UgMzQ6DQogICAgICAgIGVzY2FwZWQgPSAiJnF1b3Q7IjsNCiAgICAgICAgYnJlYWs7DQogICAgICBjYXNlIDM4Og0KICAgICAgICBlc2NhcGVkID0gIiZhbXA7IjsNCiAgICAgICAgYnJlYWs7DQogICAgICBjYXNlIDM5Og0KICAgICAgICBlc2NhcGVkID0gIiYjMzk7IjsNCiAgICAgICAgYnJlYWs7DQogICAgICBjYXNlIDYwOg0KICAgICAgICBlc2NhcGVkID0gIiZsdDsiOw0KICAgICAgICBicmVhazsNCiAgICAgIGNhc2UgNjI6DQogICAgICAgIGVzY2FwZWQgPSAiJmd0OyI7DQogICAgICAgIGJyZWFrOw0KICAgICAgZGVmYXVsdDoNCiAgICAgICAgY29udGludWU7DQogICAgfQ0KICAgIGlmIChsYXN0SW5kZXggIT09IGluZGV4KSB7DQogICAgICBodG1sICs9IHN0ci5zbGljZShsYXN0SW5kZXgsIGluZGV4KTsNCiAgICB9DQogICAgbGFzdEluZGV4ID0gaW5kZXggKyAxOw0KICAgIGh0bWwgKz0gZXNjYXBlZDsNCiAgfQ0KICByZXR1cm4gbGFzdEluZGV4ICE9PSBpbmRleCA/IGh0bWwgKyBzdHIuc2xpY2UobGFzdEluZGV4LCBpbmRleCkgOiBodG1sOw0KfQ0KY29uc3QgY29tbWVudFN0cmlwUkUgPSAvXi0/Pnw8IS0tfC0tPnwtLSE+fDwhLSQvZzsNCmZ1bmN0aW9uIGVzY2FwZUh0bWxDb21tZW50KHNyYykgew0KICByZXR1cm4gc3JjLnJlcGxhY2UoY29tbWVudFN0cmlwUkUsICIiKTsNCn0NCg0KZnVuY3Rpb24gbG9vc2VDb21wYXJlQXJyYXlzKGEsIGIpIHsNCiAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkgcmV0dXJuIGZhbHNlOw0KICBsZXQgZXF1YWwgPSB0cnVlOw0KICBmb3IgKGxldCBpID0gMDsgZXF1YWwgJiYgaSA8IGEubGVuZ3RoOyBpKyspIHsNCiAgICBlcXVhbCA9IGxvb3NlRXF1YWwoYVtpXSwgYltpXSk7DQogIH0NCiAgcmV0dXJuIGVxdWFsOw0KfQ0KZnVuY3Rpb24gbG9vc2VFcXVhbChhLCBiKSB7DQogIGlmIChhID09PSBiKSByZXR1cm4gdHJ1ZTsNCiAgbGV0IGFWYWxpZFR5cGUgPSBpc0RhdGUoYSk7DQogIGxldCBiVmFsaWRUeXBlID0gaXNEYXRlKGIpOw0KICBpZiAoYVZhbGlkVHlwZSB8fCBiVmFsaWRUeXBlKSB7DQogICAgcmV0dXJuIGFWYWxpZFR5cGUgJiYgYlZhbGlkVHlwZSA/IGEuZ2V0VGltZSgpID09PSBiLmdldFRpbWUoKSA6IGZhbHNlOw0KICB9DQogIGFWYWxpZFR5cGUgPSBpc1N5bWJvbChhKTsNCiAgYlZhbGlkVHlwZSA9IGlzU3ltYm9sKGIpOw0KICBpZiAoYVZhbGlkVHlwZSB8fCBiVmFsaWRUeXBlKSB7DQogICAgcmV0dXJuIGEgPT09IGI7DQogIH0NCiAgYVZhbGlkVHlwZSA9IGlzQXJyYXkoYSk7DQogIGJWYWxpZFR5cGUgPSBpc0FycmF5KGIpOw0KICBpZiAoYVZhbGlkVHlwZSB8fCBiVmFsaWRUeXBlKSB7DQogICAgcmV0dXJuIGFWYWxpZFR5cGUgJiYgYlZhbGlkVHlwZSA/IGxvb3NlQ29tcGFyZUFycmF5cyhhLCBiKSA6IGZhbHNlOw0KICB9DQogIGFWYWxpZFR5cGUgPSBpc09iamVjdChhKTsNCiAgYlZhbGlkVHlwZSA9IGlzT2JqZWN0KGIpOw0KICBpZiAoYVZhbGlkVHlwZSB8fCBiVmFsaWRUeXBlKSB7DQogICAgaWYgKCFhVmFsaWRUeXBlIHx8ICFiVmFsaWRUeXBlKSB7DQogICAgICByZXR1cm4gZmFsc2U7DQogICAgfQ0KICAgIGNvbnN0IGFLZXlzQ291bnQgPSBPYmplY3Qua2V5cyhhKS5sZW5ndGg7DQogICAgY29uc3QgYktleXNDb3VudCA9IE9iamVjdC5rZXlzKGIpLmxlbmd0aDsNCiAgICBpZiAoYUtleXNDb3VudCAhPT0gYktleXNDb3VudCkgew0KICAgICAgcmV0dXJuIGZhbHNlOw0KICAgIH0NCiAgICBmb3IgKGNvbnN0IGtleSBpbiBhKSB7DQogICAgICBjb25zdCBhSGFzS2V5ID0gYS5oYXNPd25Qcm9wZXJ0eShrZXkpOw0KICAgICAgY29uc3QgYkhhc0tleSA9IGIuaGFzT3duUHJvcGVydHkoa2V5KTsNCiAgICAgIGlmIChhSGFzS2V5ICYmICFiSGFzS2V5IHx8ICFhSGFzS2V5ICYmIGJIYXNLZXkgfHwgIWxvb3NlRXF1YWwoYVtrZXldLCBiW2tleV0pKSB7DQogICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgcmV0dXJuIFN0cmluZyhhKSA9PT0gU3RyaW5nKGIpOw0KfQ0KZnVuY3Rpb24gbG9vc2VJbmRleE9mKGFyciwgdmFsKSB7DQogIHJldHVybiBhcnIuZmluZEluZGV4KChpdGVtKSA9PiBsb29zZUVxdWFsKGl0ZW0sIHZhbCkpOw0KfQ0KDQpjb25zdCBpc1JlZiQxID0gKHZhbCkgPT4gew0KICByZXR1cm4gISEodmFsICYmIHZhbFsiX192X2lzUmVmIl0gPT09IHRydWUpOw0KfTsNCmNvbnN0IHRvRGlzcGxheVN0cmluZyA9ICh2YWwpID0+IHsNCiAgcmV0dXJuIGlzU3RyaW5nKHZhbCkgPyB2YWwgOiB2YWwgPT0gbnVsbCA/ICIiIDogaXNBcnJheSh2YWwpIHx8IGlzT2JqZWN0KHZhbCkgJiYgKHZhbC50b1N0cmluZyA9PT0gb2JqZWN0VG9TdHJpbmcgfHwgIWlzRnVuY3Rpb24odmFsLnRvU3RyaW5nKSkgPyBpc1JlZiQxKHZhbCkgPyB0b0Rpc3BsYXlTdHJpbmcodmFsLnZhbHVlKSA6IEpTT04uc3RyaW5naWZ5KHZhbCwgcmVwbGFjZXIsIDIpIDogU3RyaW5nKHZhbCk7DQp9Ow0KY29uc3QgcmVwbGFjZXIgPSAoX2tleSwgdmFsKSA9PiB7DQogIGlmIChpc1JlZiQxKHZhbCkpIHsNCiAgICByZXR1cm4gcmVwbGFjZXIoX2tleSwgdmFsLnZhbHVlKTsNCiAgfSBlbHNlIGlmIChpc01hcCh2YWwpKSB7DQogICAgcmV0dXJuIHsNCiAgICAgIFtgTWFwKCR7dmFsLnNpemV9KWBdOiBbLi4udmFsLmVudHJpZXMoKV0ucmVkdWNlKA0KICAgICAgICAoZW50cmllcywgW2tleSwgdmFsMl0sIGkpID0+IHsNCiAgICAgICAgICBlbnRyaWVzW3N0cmluZ2lmeVN5bWJvbChrZXksIGkpICsgIiA9PiJdID0gdmFsMjsNCiAgICAgICAgICByZXR1cm4gZW50cmllczsNCiAgICAgICAgfSwNCiAgICAgICAge30NCiAgICAgICkNCiAgICB9Ow0KICB9IGVsc2UgaWYgKGlzU2V0KHZhbCkpIHsNCiAgICByZXR1cm4gew0KICAgICAgW2BTZXQoJHt2YWwuc2l6ZX0pYF06IFsuLi52YWwudmFsdWVzKCldLm1hcCgodikgPT4gc3RyaW5naWZ5U3ltYm9sKHYpKQ0KICAgIH07DQogIH0gZWxzZSBpZiAoaXNTeW1ib2wodmFsKSkgew0KICAgIHJldHVybiBzdHJpbmdpZnlTeW1ib2wodmFsKTsNCiAgfSBlbHNlIGlmIChpc09iamVjdCh2YWwpICYmICFpc0FycmF5KHZhbCkgJiYgIWlzUGxhaW5PYmplY3QodmFsKSkgew0KICAgIHJldHVybiBTdHJpbmcodmFsKTsNCiAgfQ0KICByZXR1cm4gdmFsOw0KfTsNCmNvbnN0IHN0cmluZ2lmeVN5bWJvbCA9ICh2LCBpID0gIiIpID0+IHsNCiAgdmFyIF9hOw0KICByZXR1cm4gKA0KICAgIC8vIFN5bWJvbC5kZXNjcmlwdGlvbiBpbiBlczIwMTkrIHNvIHdlIG5lZWQgdG8gY2FzdCBoZXJlIHRvIHBhc3MNCiAgICAvLyB0aGUgbGliOiBlczIwMTYgY2hlY2sNCiAgICBpc1N5bWJvbCh2KSA/IGBTeW1ib2woJHsoX2EgPSB2LmRlc2NyaXB0aW9uKSAhPSBudWxsID8gX2EgOiBpfSlgIDogdg0KICApOw0KfTsNCg0KZnVuY3Rpb24gd2FybiQyKG1zZywgLi4uYXJncykgew0KICBjb25zb2xlLndhcm4oYFtWdWUgd2Fybl0gJHttc2d9YCwgLi4uYXJncyk7DQp9DQoNCmxldCBhY3RpdmVFZmZlY3RTY29wZTsNCmNsYXNzIEVmZmVjdFNjb3BlIHsNCiAgY29uc3RydWN0b3IoZGV0YWNoZWQgPSBmYWxzZSkgew0KICAgIHRoaXMuZGV0YWNoZWQgPSBkZXRhY2hlZDsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLl9hY3RpdmUgPSB0cnVlOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbCB0cmFjayBgb25gIGNhbGxzLCBhbGxvdyBgb25gIGNhbGwgbXVsdGlwbGUgdGltZXMNCiAgICAgKi8NCiAgICB0aGlzLl9vbiA9IDA7DQogICAgLyoqDQogICAgICogQGludGVybmFsDQogICAgICovDQogICAgdGhpcy5lZmZlY3RzID0gW107DQogICAgLyoqDQogICAgICogQGludGVybmFsDQogICAgICovDQogICAgdGhpcy5jbGVhbnVwcyA9IFtdOw0KICAgIHRoaXMuX2lzUGF1c2VkID0gZmFsc2U7DQogICAgdGhpcy5wYXJlbnQgPSBhY3RpdmVFZmZlY3RTY29wZTsNCiAgICBpZiAoIWRldGFjaGVkICYmIGFjdGl2ZUVmZmVjdFNjb3BlKSB7DQogICAgICB0aGlzLmluZGV4ID0gKGFjdGl2ZUVmZmVjdFNjb3BlLnNjb3BlcyB8fCAoYWN0aXZlRWZmZWN0U2NvcGUuc2NvcGVzID0gW10pKS5wdXNoKA0KICAgICAgICB0aGlzDQogICAgICApIC0gMTsNCiAgICB9DQogIH0NCiAgZ2V0IGFjdGl2ZSgpIHsNCiAgICByZXR1cm4gdGhpcy5fYWN0aXZlOw0KICB9DQogIHBhdXNlKCkgew0KICAgIGlmICh0aGlzLl9hY3RpdmUpIHsNCiAgICAgIHRoaXMuX2lzUGF1c2VkID0gdHJ1ZTsNCiAgICAgIGxldCBpLCBsOw0KICAgICAgaWYgKHRoaXMuc2NvcGVzKSB7DQogICAgICAgIGZvciAoaSA9IDAsIGwgPSB0aGlzLnNjb3Blcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsNCiAgICAgICAgICB0aGlzLnNjb3Blc1tpXS5wYXVzZSgpOw0KICAgICAgICB9DQogICAgICB9DQogICAgICBmb3IgKGkgPSAwLCBsID0gdGhpcy5lZmZlY3RzLmxlbmd0aDsgaSA8IGw7IGkrKykgew0KICAgICAgICB0aGlzLmVmZmVjdHNbaV0ucGF1c2UoKTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgLyoqDQogICAqIFJlc3VtZXMgdGhlIGVmZmVjdCBzY29wZSwgaW5jbHVkaW5nIGFsbCBjaGlsZCBzY29wZXMgYW5kIGVmZmVjdHMuDQogICAqLw0KICByZXN1bWUoKSB7DQogICAgaWYgKHRoaXMuX2FjdGl2ZSkgew0KICAgICAgaWYgKHRoaXMuX2lzUGF1c2VkKSB7DQogICAgICAgIHRoaXMuX2lzUGF1c2VkID0gZmFsc2U7DQogICAgICAgIGxldCBpLCBsOw0KICAgICAgICBpZiAodGhpcy5zY29wZXMpIHsNCiAgICAgICAgICBmb3IgKGkgPSAwLCBsID0gdGhpcy5zY29wZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7DQogICAgICAgICAgICB0aGlzLnNjb3Blc1tpXS5yZXN1bWUoKTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgZm9yIChpID0gMCwgbCA9IHRoaXMuZWZmZWN0cy5sZW5ndGg7IGkgPCBsOyBpKyspIHsNCiAgICAgICAgICB0aGlzLmVmZmVjdHNbaV0ucmVzdW1lKCk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH0NCiAgcnVuKGZuKSB7DQogICAgaWYgKHRoaXMuX2FjdGl2ZSkgew0KICAgICAgY29uc3QgY3VycmVudEVmZmVjdFNjb3BlID0gYWN0aXZlRWZmZWN0U2NvcGU7DQogICAgICB0cnkgew0KICAgICAgICBhY3RpdmVFZmZlY3RTY29wZSA9IHRoaXM7DQogICAgICAgIHJldHVybiBmbigpOw0KICAgICAgfSBmaW5hbGx5IHsNCiAgICAgICAgYWN0aXZlRWZmZWN0U2NvcGUgPSBjdXJyZW50RWZmZWN0U2NvcGU7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIHdhcm4kMihgY2Fubm90IHJ1biBhbiBpbmFjdGl2ZSBlZmZlY3Qgc2NvcGUuYCk7DQogICAgfQ0KICB9DQogIC8qKg0KICAgKiBUaGlzIHNob3VsZCBvbmx5IGJlIGNhbGxlZCBvbiBub24tZGV0YWNoZWQgc2NvcGVzDQogICAqIEBpbnRlcm5hbA0KICAgKi8NCiAgb24oKSB7DQogICAgaWYgKCsrdGhpcy5fb24gPT09IDEpIHsNCiAgICAgIHRoaXMucHJldlNjb3BlID0gYWN0aXZlRWZmZWN0U2NvcGU7DQogICAgICBhY3RpdmVFZmZlY3RTY29wZSA9IHRoaXM7DQogICAgfQ0KICB9DQogIC8qKg0KICAgKiBUaGlzIHNob3VsZCBvbmx5IGJlIGNhbGxlZCBvbiBub24tZGV0YWNoZWQgc2NvcGVzDQogICAqIEBpbnRlcm5hbA0KICAgKi8NCiAgb2ZmKCkgew0KICAgIGlmICh0aGlzLl9vbiA+IDAgJiYgLS10aGlzLl9vbiA9PT0gMCkgew0KICAgICAgYWN0aXZlRWZmZWN0U2NvcGUgPSB0aGlzLnByZXZTY29wZTsNCiAgICAgIHRoaXMucHJldlNjb3BlID0gdm9pZCAwOw0KICAgIH0NCiAgfQ0KICBzdG9wKGZyb21QYXJlbnQpIHsNCiAgICBpZiAodGhpcy5fYWN0aXZlKSB7DQogICAgICB0aGlzLl9hY3RpdmUgPSBmYWxzZTsNCiAgICAgIGxldCBpLCBsOw0KICAgICAgZm9yIChpID0gMCwgbCA9IHRoaXMuZWZmZWN0cy5sZW5ndGg7IGkgPCBsOyBpKyspIHsNCiAgICAgICAgdGhpcy5lZmZlY3RzW2ldLnN0b3AoKTsNCiAgICAgIH0NCiAgICAgIHRoaXMuZWZmZWN0cy5sZW5ndGggPSAwOw0KICAgICAgZm9yIChpID0gMCwgbCA9IHRoaXMuY2xlYW51cHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7DQogICAgICAgIHRoaXMuY2xlYW51cHNbaV0oKTsNCiAgICAgIH0NCiAgICAgIHRoaXMuY2xlYW51cHMubGVuZ3RoID0gMDsNCiAgICAgIGlmICh0aGlzLnNjb3Blcykgew0KICAgICAgICBmb3IgKGkgPSAwLCBsID0gdGhpcy5zY29wZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7DQogICAgICAgICAgdGhpcy5zY29wZXNbaV0uc3RvcCh0cnVlKTsNCiAgICAgICAgfQ0KICAgICAgICB0aGlzLnNjb3Blcy5sZW5ndGggPSAwOw0KICAgICAgfQ0KICAgICAgaWYgKCF0aGlzLmRldGFjaGVkICYmIHRoaXMucGFyZW50ICYmICFmcm9tUGFyZW50KSB7DQogICAgICAgIGNvbnN0IGxhc3QgPSB0aGlzLnBhcmVudC5zY29wZXMucG9wKCk7DQogICAgICAgIGlmIChsYXN0ICYmIGxhc3QgIT09IHRoaXMpIHsNCiAgICAgICAgICB0aGlzLnBhcmVudC5zY29wZXNbdGhpcy5pbmRleF0gPSBsYXN0Ow0KICAgICAgICAgIGxhc3QuaW5kZXggPSB0aGlzLmluZGV4Ow0KICAgICAgICB9DQogICAgICB9DQogICAgICB0aGlzLnBhcmVudCA9IHZvaWQgMDsNCiAgICB9DQogIH0NCn0NCmZ1bmN0aW9uIGdldEN1cnJlbnRTY29wZSgpIHsNCiAgcmV0dXJuIGFjdGl2ZUVmZmVjdFNjb3BlOw0KfQ0KDQpsZXQgYWN0aXZlU3ViOw0KY29uc3QgcGF1c2VkUXVldWVFZmZlY3RzID0gLyogQF9fUFVSRV9fICovIG5ldyBXZWFrU2V0KCk7DQpjbGFzcyBSZWFjdGl2ZUVmZmVjdCB7DQogIGNvbnN0cnVjdG9yKGZuKSB7DQogICAgdGhpcy5mbiA9IGZuOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuZGVwcyA9IHZvaWQgMDsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLmRlcHNUYWlsID0gdm9pZCAwOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuZmxhZ3MgPSAxIHwgNDsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLm5leHQgPSB2b2lkIDA7DQogICAgLyoqDQogICAgICogQGludGVybmFsDQogICAgICovDQogICAgdGhpcy5jbGVhbnVwID0gdm9pZCAwOw0KICAgIHRoaXMuc2NoZWR1bGVyID0gdm9pZCAwOw0KICAgIGlmIChhY3RpdmVFZmZlY3RTY29wZSAmJiBhY3RpdmVFZmZlY3RTY29wZS5hY3RpdmUpIHsNCiAgICAgIGFjdGl2ZUVmZmVjdFNjb3BlLmVmZmVjdHMucHVzaCh0aGlzKTsNCiAgICB9DQogIH0NCiAgcGF1c2UoKSB7DQogICAgdGhpcy5mbGFncyB8PSA2NDsNCiAgfQ0KICByZXN1bWUoKSB7DQogICAgaWYgKHRoaXMuZmxhZ3MgJiA2NCkgew0KICAgICAgdGhpcy5mbGFncyAmPSAtNjU7DQogICAgICBpZiAocGF1c2VkUXVldWVFZmZlY3RzLmhhcyh0aGlzKSkgew0KICAgICAgICBwYXVzZWRRdWV1ZUVmZmVjdHMuZGVsZXRlKHRoaXMpOw0KICAgICAgICB0aGlzLnRyaWdnZXIoKTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgLyoqDQogICAqIEBpbnRlcm5hbA0KICAgKi8NCiAgbm90aWZ5KCkgew0KICAgIGlmICh0aGlzLmZsYWdzICYgMiAmJiAhKHRoaXMuZmxhZ3MgJiAzMikpIHsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgaWYgKCEodGhpcy5mbGFncyAmIDgpKSB7DQogICAgICBiYXRjaCh0aGlzKTsNCiAgICB9DQogIH0NCiAgcnVuKCkgew0KICAgIGlmICghKHRoaXMuZmxhZ3MgJiAxKSkgew0KICAgICAgcmV0dXJuIHRoaXMuZm4oKTsNCiAgICB9DQogICAgdGhpcy5mbGFncyB8PSAyOw0KICAgIGNsZWFudXBFZmZlY3QodGhpcyk7DQogICAgcHJlcGFyZURlcHModGhpcyk7DQogICAgY29uc3QgcHJldkVmZmVjdCA9IGFjdGl2ZVN1YjsNCiAgICBjb25zdCBwcmV2U2hvdWxkVHJhY2sgPSBzaG91bGRUcmFjazsNCiAgICBhY3RpdmVTdWIgPSB0aGlzOw0KICAgIHNob3VsZFRyYWNrID0gdHJ1ZTsNCiAgICB0cnkgew0KICAgICAgcmV0dXJuIHRoaXMuZm4oKTsNCiAgICB9IGZpbmFsbHkgew0KICAgICAgaWYgKGFjdGl2ZVN1YiAhPT0gdGhpcykgew0KICAgICAgICB3YXJuJDIoDQogICAgICAgICAgIkFjdGl2ZSBlZmZlY3Qgd2FzIG5vdCByZXN0b3JlZCBjb3JyZWN0bHkgLSB0aGlzIGlzIGxpa2VseSBhIFZ1ZSBpbnRlcm5hbCBidWcuIg0KICAgICAgICApOw0KICAgICAgfQ0KICAgICAgY2xlYW51cERlcHModGhpcyk7DQogICAgICBhY3RpdmVTdWIgPSBwcmV2RWZmZWN0Ow0KICAgICAgc2hvdWxkVHJhY2sgPSBwcmV2U2hvdWxkVHJhY2s7DQogICAgICB0aGlzLmZsYWdzICY9IC0zOw0KICAgIH0NCiAgfQ0KICBzdG9wKCkgew0KICAgIGlmICh0aGlzLmZsYWdzICYgMSkgew0KICAgICAgZm9yIChsZXQgbGluayA9IHRoaXMuZGVwczsgbGluazsgbGluayA9IGxpbmsubmV4dERlcCkgew0KICAgICAgICByZW1vdmVTdWIobGluayk7DQogICAgICB9DQogICAgICB0aGlzLmRlcHMgPSB0aGlzLmRlcHNUYWlsID0gdm9pZCAwOw0KICAgICAgY2xlYW51cEVmZmVjdCh0aGlzKTsNCiAgICAgIHRoaXMub25TdG9wICYmIHRoaXMub25TdG9wKCk7DQogICAgICB0aGlzLmZsYWdzICY9IC0yOw0KICAgIH0NCiAgfQ0KICB0cmlnZ2VyKCkgew0KICAgIGlmICh0aGlzLmZsYWdzICYgNjQpIHsNCiAgICAgIHBhdXNlZFF1ZXVlRWZmZWN0cy5hZGQodGhpcyk7DQogICAgfSBlbHNlIGlmICh0aGlzLnNjaGVkdWxlcikgew0KICAgICAgdGhpcy5zY2hlZHVsZXIoKTsNCiAgICB9IGVsc2Ugew0KICAgICAgdGhpcy5ydW5JZkRpcnR5KCk7DQogICAgfQ0KICB9DQogIC8qKg0KICAgKiBAaW50ZXJuYWwNCiAgICovDQogIHJ1bklmRGlydHkoKSB7DQogICAgaWYgKGlzRGlydHkodGhpcykpIHsNCiAgICAgIHRoaXMucnVuKCk7DQogICAgfQ0KICB9DQogIGdldCBkaXJ0eSgpIHsNCiAgICByZXR1cm4gaXNEaXJ0eSh0aGlzKTsNCiAgfQ0KfQ0KbGV0IGJhdGNoRGVwdGggPSAwOw0KbGV0IGJhdGNoZWRTdWI7DQpsZXQgYmF0Y2hlZENvbXB1dGVkOw0KZnVuY3Rpb24gYmF0Y2goc3ViLCBpc0NvbXB1dGVkID0gZmFsc2UpIHsNCiAgc3ViLmZsYWdzIHw9IDg7DQogIGlmIChpc0NvbXB1dGVkKSB7DQogICAgc3ViLm5leHQgPSBiYXRjaGVkQ29tcHV0ZWQ7DQogICAgYmF0Y2hlZENvbXB1dGVkID0gc3ViOw0KICAgIHJldHVybjsNCiAgfQ0KICBzdWIubmV4dCA9IGJhdGNoZWRTdWI7DQogIGJhdGNoZWRTdWIgPSBzdWI7DQp9DQpmdW5jdGlvbiBzdGFydEJhdGNoKCkgew0KICBiYXRjaERlcHRoKys7DQp9DQpmdW5jdGlvbiBlbmRCYXRjaCgpIHsNCiAgaWYgKC0tYmF0Y2hEZXB0aCA+IDApIHsNCiAgICByZXR1cm47DQogIH0NCiAgaWYgKGJhdGNoZWRDb21wdXRlZCkgew0KICAgIGxldCBlID0gYmF0Y2hlZENvbXB1dGVkOw0KICAgIGJhdGNoZWRDb21wdXRlZCA9IHZvaWQgMDsNCiAgICB3aGlsZSAoZSkgew0KICAgICAgY29uc3QgbmV4dCA9IGUubmV4dDsNCiAgICAgIGUubmV4dCA9IHZvaWQgMDsNCiAgICAgIGUuZmxhZ3MgJj0gLTk7DQogICAgICBlID0gbmV4dDsNCiAgICB9DQogIH0NCiAgbGV0IGVycm9yOw0KICB3aGlsZSAoYmF0Y2hlZFN1Yikgew0KICAgIGxldCBlID0gYmF0Y2hlZFN1YjsNCiAgICBiYXRjaGVkU3ViID0gdm9pZCAwOw0KICAgIHdoaWxlIChlKSB7DQogICAgICBjb25zdCBuZXh0ID0gZS5uZXh0Ow0KICAgICAgZS5uZXh0ID0gdm9pZCAwOw0KICAgICAgZS5mbGFncyAmPSAtOTsNCiAgICAgIGlmIChlLmZsYWdzICYgMSkgew0KICAgICAgICB0cnkgew0KICAgICAgICAgIDsNCiAgICAgICAgICBlLnRyaWdnZXIoKTsNCiAgICAgICAgfSBjYXRjaCAoZXJyKSB7DQogICAgICAgICAgaWYgKCFlcnJvcikgZXJyb3IgPSBlcnI7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGUgPSBuZXh0Ow0KICAgIH0NCiAgfQ0KICBpZiAoZXJyb3IpIHRocm93IGVycm9yOw0KfQ0KZnVuY3Rpb24gcHJlcGFyZURlcHMoc3ViKSB7DQogIGZvciAobGV0IGxpbmsgPSBzdWIuZGVwczsgbGluazsgbGluayA9IGxpbmsubmV4dERlcCkgew0KICAgIGxpbmsudmVyc2lvbiA9IC0xOw0KICAgIGxpbmsucHJldkFjdGl2ZUxpbmsgPSBsaW5rLmRlcC5hY3RpdmVMaW5rOw0KICAgIGxpbmsuZGVwLmFjdGl2ZUxpbmsgPSBsaW5rOw0KICB9DQp9DQpmdW5jdGlvbiBjbGVhbnVwRGVwcyhzdWIpIHsNCiAgbGV0IGhlYWQ7DQogIGxldCB0YWlsID0gc3ViLmRlcHNUYWlsOw0KICBsZXQgbGluayA9IHRhaWw7DQogIHdoaWxlIChsaW5rKSB7DQogICAgY29uc3QgcHJldiA9IGxpbmsucHJldkRlcDsNCiAgICBpZiAobGluay52ZXJzaW9uID09PSAtMSkgew0KICAgICAgaWYgKGxpbmsgPT09IHRhaWwpIHRhaWwgPSBwcmV2Ow0KICAgICAgcmVtb3ZlU3ViKGxpbmspOw0KICAgICAgcmVtb3ZlRGVwKGxpbmspOw0KICAgIH0gZWxzZSB7DQogICAgICBoZWFkID0gbGluazsNCiAgICB9DQogICAgbGluay5kZXAuYWN0aXZlTGluayA9IGxpbmsucHJldkFjdGl2ZUxpbms7DQogICAgbGluay5wcmV2QWN0aXZlTGluayA9IHZvaWQgMDsNCiAgICBsaW5rID0gcHJldjsNCiAgfQ0KICBzdWIuZGVwcyA9IGhlYWQ7DQogIHN1Yi5kZXBzVGFpbCA9IHRhaWw7DQp9DQpmdW5jdGlvbiBpc0RpcnR5KHN1Yikgew0KICBmb3IgKGxldCBsaW5rID0gc3ViLmRlcHM7IGxpbms7IGxpbmsgPSBsaW5rLm5leHREZXApIHsNCiAgICBpZiAobGluay5kZXAudmVyc2lvbiAhPT0gbGluay52ZXJzaW9uIHx8IGxpbmsuZGVwLmNvbXB1dGVkICYmIChyZWZyZXNoQ29tcHV0ZWQobGluay5kZXAuY29tcHV0ZWQpIHx8IGxpbmsuZGVwLnZlcnNpb24gIT09IGxpbmsudmVyc2lvbikpIHsNCiAgICAgIHJldHVybiB0cnVlOw0KICAgIH0NCiAgfQ0KICBpZiAoc3ViLl9kaXJ0eSkgew0KICAgIHJldHVybiB0cnVlOw0KICB9DQogIHJldHVybiBmYWxzZTsNCn0NCmZ1bmN0aW9uIHJlZnJlc2hDb21wdXRlZChjb21wdXRlZCkgew0KICBpZiAoY29tcHV0ZWQuZmxhZ3MgJiA0ICYmICEoY29tcHV0ZWQuZmxhZ3MgJiAxNikpIHsNCiAgICByZXR1cm47DQogIH0NCiAgY29tcHV0ZWQuZmxhZ3MgJj0gLTE3Ow0KICBpZiAoY29tcHV0ZWQuZ2xvYmFsVmVyc2lvbiA9PT0gZ2xvYmFsVmVyc2lvbikgew0KICAgIHJldHVybjsNCiAgfQ0KICBjb21wdXRlZC5nbG9iYWxWZXJzaW9uID0gZ2xvYmFsVmVyc2lvbjsNCiAgaWYgKCFjb21wdXRlZC5pc1NTUiAmJiBjb21wdXRlZC5mbGFncyAmIDEyOCAmJiAoIWNvbXB1dGVkLmRlcHMgJiYgIWNvbXB1dGVkLl9kaXJ0eSB8fCAhaXNEaXJ0eShjb21wdXRlZCkpKSB7DQogICAgcmV0dXJuOw0KICB9DQogIGNvbXB1dGVkLmZsYWdzIHw9IDI7DQogIGNvbnN0IGRlcCA9IGNvbXB1dGVkLmRlcDsNCiAgY29uc3QgcHJldlN1YiA9IGFjdGl2ZVN1YjsNCiAgY29uc3QgcHJldlNob3VsZFRyYWNrID0gc2hvdWxkVHJhY2s7DQogIGFjdGl2ZVN1YiA9IGNvbXB1dGVkOw0KICBzaG91bGRUcmFjayA9IHRydWU7DQogIHRyeSB7DQogICAgcHJlcGFyZURlcHMoY29tcHV0ZWQpOw0KICAgIGNvbnN0IHZhbHVlID0gY29tcHV0ZWQuZm4oY29tcHV0ZWQuX3ZhbHVlKTsNCiAgICBpZiAoZGVwLnZlcnNpb24gPT09IDAgfHwgaGFzQ2hhbmdlZCh2YWx1ZSwgY29tcHV0ZWQuX3ZhbHVlKSkgew0KICAgICAgY29tcHV0ZWQuZmxhZ3MgfD0gMTI4Ow0KICAgICAgY29tcHV0ZWQuX3ZhbHVlID0gdmFsdWU7DQogICAgICBkZXAudmVyc2lvbisrOw0KICAgIH0NCiAgfSBjYXRjaCAoZXJyKSB7DQogICAgZGVwLnZlcnNpb24rKzsNCiAgICB0aHJvdyBlcnI7DQogIH0gZmluYWxseSB7DQogICAgYWN0aXZlU3ViID0gcHJldlN1YjsNCiAgICBzaG91bGRUcmFjayA9IHByZXZTaG91bGRUcmFjazsNCiAgICBjbGVhbnVwRGVwcyhjb21wdXRlZCk7DQogICAgY29tcHV0ZWQuZmxhZ3MgJj0gLTM7DQogIH0NCn0NCmZ1bmN0aW9uIHJlbW92ZVN1YihsaW5rLCBzb2Z0ID0gZmFsc2UpIHsNCiAgY29uc3QgeyBkZXAsIHByZXZTdWIsIG5leHRTdWIgfSA9IGxpbms7DQogIGlmIChwcmV2U3ViKSB7DQogICAgcHJldlN1Yi5uZXh0U3ViID0gbmV4dFN1YjsNCiAgICBsaW5rLnByZXZTdWIgPSB2b2lkIDA7DQogIH0NCiAgaWYgKG5leHRTdWIpIHsNCiAgICBuZXh0U3ViLnByZXZTdWIgPSBwcmV2U3ViOw0KICAgIGxpbmsubmV4dFN1YiA9IHZvaWQgMDsNCiAgfQ0KICBpZiAoZGVwLnN1YnNIZWFkID09PSBsaW5rKSB7DQogICAgZGVwLnN1YnNIZWFkID0gbmV4dFN1YjsNCiAgfQ0KICBpZiAoZGVwLnN1YnMgPT09IGxpbmspIHsNCiAgICBkZXAuc3VicyA9IHByZXZTdWI7DQogICAgaWYgKCFwcmV2U3ViICYmIGRlcC5jb21wdXRlZCkgew0KICAgICAgZGVwLmNvbXB1dGVkLmZsYWdzICY9IC01Ow0KICAgICAgZm9yIChsZXQgbCA9IGRlcC5jb21wdXRlZC5kZXBzOyBsOyBsID0gbC5uZXh0RGVwKSB7DQogICAgICAgIHJlbW92ZVN1YihsLCB0cnVlKTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgaWYgKCFzb2Z0ICYmICEtLWRlcC5zYyAmJiBkZXAubWFwKSB7DQogICAgZGVwLm1hcC5kZWxldGUoZGVwLmtleSk7DQogIH0NCn0NCmZ1bmN0aW9uIHJlbW92ZURlcChsaW5rKSB7DQogIGNvbnN0IHsgcHJldkRlcCwgbmV4dERlcCB9ID0gbGluazsNCiAgaWYgKHByZXZEZXApIHsNCiAgICBwcmV2RGVwLm5leHREZXAgPSBuZXh0RGVwOw0KICAgIGxpbmsucHJldkRlcCA9IHZvaWQgMDsNCiAgfQ0KICBpZiAobmV4dERlcCkgew0KICAgIG5leHREZXAucHJldkRlcCA9IHByZXZEZXA7DQogICAgbGluay5uZXh0RGVwID0gdm9pZCAwOw0KICB9DQp9DQpsZXQgc2hvdWxkVHJhY2sgPSB0cnVlOw0KY29uc3QgdHJhY2tTdGFjayA9IFtdOw0KZnVuY3Rpb24gcGF1c2VUcmFja2luZygpIHsNCiAgdHJhY2tTdGFjay5wdXNoKHNob3VsZFRyYWNrKTsNCiAgc2hvdWxkVHJhY2sgPSBmYWxzZTsNCn0NCmZ1bmN0aW9uIHJlc2V0VHJhY2tpbmcoKSB7DQogIGNvbnN0IGxhc3QgPSB0cmFja1N0YWNrLnBvcCgpOw0KICBzaG91bGRUcmFjayA9IGxhc3QgPT09IHZvaWQgMCA/IHRydWUgOiBsYXN0Ow0KfQ0KZnVuY3Rpb24gY2xlYW51cEVmZmVjdChlKSB7DQogIGNvbnN0IHsgY2xlYW51cCB9ID0gZTsNCiAgZS5jbGVhbnVwID0gdm9pZCAwOw0KICBpZiAoY2xlYW51cCkgew0KICAgIGNvbnN0IHByZXZTdWIgPSBhY3RpdmVTdWI7DQogICAgYWN0aXZlU3ViID0gdm9pZCAwOw0KICAgIHRyeSB7DQogICAgICBjbGVhbnVwKCk7DQogICAgfSBmaW5hbGx5IHsNCiAgICAgIGFjdGl2ZVN1YiA9IHByZXZTdWI7DQogICAgfQ0KICB9DQp9DQoNCmxldCBnbG9iYWxWZXJzaW9uID0gMDsNCmNsYXNzIExpbmsgew0KICBjb25zdHJ1Y3RvcihzdWIsIGRlcCkgew0KICAgIHRoaXMuc3ViID0gc3ViOw0KICAgIHRoaXMuZGVwID0gZGVwOw0KICAgIHRoaXMudmVyc2lvbiA9IGRlcC52ZXJzaW9uOw0KICAgIHRoaXMubmV4dERlcCA9IHRoaXMucHJldkRlcCA9IHRoaXMubmV4dFN1YiA9IHRoaXMucHJldlN1YiA9IHRoaXMucHJldkFjdGl2ZUxpbmsgPSB2b2lkIDA7DQogIH0NCn0NCmNsYXNzIERlcCB7DQogIC8vIFRPRE8gaXNvbGF0ZWREZWNsYXJhdGlvbnMgIl9fdl9za2lwIg0KICBjb25zdHJ1Y3Rvcihjb21wdXRlZCkgew0KICAgIHRoaXMuY29tcHV0ZWQgPSBjb21wdXRlZDsNCiAgICB0aGlzLnZlcnNpb24gPSAwOw0KICAgIC8qKg0KICAgICAqIExpbmsgYmV0d2VlbiB0aGlzIGRlcCBhbmQgdGhlIGN1cnJlbnQgYWN0aXZlIGVmZmVjdA0KICAgICAqLw0KICAgIHRoaXMuYWN0aXZlTGluayA9IHZvaWQgMDsNCiAgICAvKioNCiAgICAgKiBEb3VibHkgbGlua2VkIGxpc3QgcmVwcmVzZW50aW5nIHRoZSBzdWJzY3JpYmluZyBlZmZlY3RzICh0YWlsKQ0KICAgICAqLw0KICAgIHRoaXMuc3VicyA9IHZvaWQgMDsNCiAgICAvKioNCiAgICAgKiBGb3Igb2JqZWN0IHByb3BlcnR5IGRlcHMgY2xlYW51cA0KICAgICAqLw0KICAgIHRoaXMubWFwID0gdm9pZCAwOw0KICAgIHRoaXMua2V5ID0gdm9pZCAwOw0KICAgIC8qKg0KICAgICAqIFN1YnNjcmliZXIgY291bnRlcg0KICAgICAqLw0KICAgIHRoaXMuc2MgPSAwOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuX192X3NraXAgPSB0cnVlOw0KICAgIHsNCiAgICAgIHRoaXMuc3Vic0hlYWQgPSB2b2lkIDA7DQogICAgfQ0KICB9DQogIHRyYWNrKGRlYnVnSW5mbykgew0KICAgIGlmICghYWN0aXZlU3ViIHx8ICFzaG91bGRUcmFjayB8fCBhY3RpdmVTdWIgPT09IHRoaXMuY29tcHV0ZWQpIHsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgbGV0IGxpbmsgPSB0aGlzLmFjdGl2ZUxpbms7DQogICAgaWYgKGxpbmsgPT09IHZvaWQgMCB8fCBsaW5rLnN1YiAhPT0gYWN0aXZlU3ViKSB7DQogICAgICBsaW5rID0gdGhpcy5hY3RpdmVMaW5rID0gbmV3IExpbmsoYWN0aXZlU3ViLCB0aGlzKTsNCiAgICAgIGlmICghYWN0aXZlU3ViLmRlcHMpIHsNCiAgICAgICAgYWN0aXZlU3ViLmRlcHMgPSBhY3RpdmVTdWIuZGVwc1RhaWwgPSBsaW5rOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgbGluay5wcmV2RGVwID0gYWN0aXZlU3ViLmRlcHNUYWlsOw0KICAgICAgICBhY3RpdmVTdWIuZGVwc1RhaWwubmV4dERlcCA9IGxpbms7DQogICAgICAgIGFjdGl2ZVN1Yi5kZXBzVGFpbCA9IGxpbms7DQogICAgICB9DQogICAgICBhZGRTdWIobGluayk7DQogICAgfSBlbHNlIGlmIChsaW5rLnZlcnNpb24gPT09IC0xKSB7DQogICAgICBsaW5rLnZlcnNpb24gPSB0aGlzLnZlcnNpb247DQogICAgICBpZiAobGluay5uZXh0RGVwKSB7DQogICAgICAgIGNvbnN0IG5leHQgPSBsaW5rLm5leHREZXA7DQogICAgICAgIG5leHQucHJldkRlcCA9IGxpbmsucHJldkRlcDsNCiAgICAgICAgaWYgKGxpbmsucHJldkRlcCkgew0KICAgICAgICAgIGxpbmsucHJldkRlcC5uZXh0RGVwID0gbmV4dDsNCiAgICAgICAgfQ0KICAgICAgICBsaW5rLnByZXZEZXAgPSBhY3RpdmVTdWIuZGVwc1RhaWw7DQogICAgICAgIGxpbmsubmV4dERlcCA9IHZvaWQgMDsNCiAgICAgICAgYWN0aXZlU3ViLmRlcHNUYWlsLm5leHREZXAgPSBsaW5rOw0KICAgICAgICBhY3RpdmVTdWIuZGVwc1RhaWwgPSBsaW5rOw0KICAgICAgICBpZiAoYWN0aXZlU3ViLmRlcHMgPT09IGxpbmspIHsNCiAgICAgICAgICBhY3RpdmVTdWIuZGVwcyA9IG5leHQ7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogICAgaWYgKGFjdGl2ZVN1Yi5vblRyYWNrKSB7DQogICAgICBhY3RpdmVTdWIub25UcmFjaygNCiAgICAgICAgZXh0ZW5kKA0KICAgICAgICAgIHsNCiAgICAgICAgICAgIGVmZmVjdDogYWN0aXZlU3ViDQogICAgICAgICAgfSwNCiAgICAgICAgICBkZWJ1Z0luZm8NCiAgICAgICAgKQ0KICAgICAgKTsNCiAgICB9DQogICAgcmV0dXJuIGxpbms7DQogIH0NCiAgdHJpZ2dlcihkZWJ1Z0luZm8pIHsNCiAgICB0aGlzLnZlcnNpb24rKzsNCiAgICBnbG9iYWxWZXJzaW9uKys7DQogICAgdGhpcy5ub3RpZnkoZGVidWdJbmZvKTsNCiAgfQ0KICBub3RpZnkoZGVidWdJbmZvKSB7DQogICAgc3RhcnRCYXRjaCgpOw0KICAgIHRyeSB7DQogICAgICBpZiAodHJ1ZSkgew0KICAgICAgICBmb3IgKGxldCBoZWFkID0gdGhpcy5zdWJzSGVhZDsgaGVhZDsgaGVhZCA9IGhlYWQubmV4dFN1Yikgew0KICAgICAgICAgIGlmIChoZWFkLnN1Yi5vblRyaWdnZXIgJiYgIShoZWFkLnN1Yi5mbGFncyAmIDgpKSB7DQogICAgICAgICAgICBoZWFkLnN1Yi5vblRyaWdnZXIoDQogICAgICAgICAgICAgIGV4dGVuZCgNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICBlZmZlY3Q6IGhlYWQuc3ViDQogICAgICAgICAgICAgICAgfSwNCiAgICAgICAgICAgICAgICBkZWJ1Z0luZm8NCiAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgKTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGZvciAobGV0IGxpbmsgPSB0aGlzLnN1YnM7IGxpbms7IGxpbmsgPSBsaW5rLnByZXZTdWIpIHsNCiAgICAgICAgaWYgKGxpbmsuc3ViLm5vdGlmeSgpKSB7DQogICAgICAgICAgOw0KICAgICAgICAgIGxpbmsuc3ViLmRlcC5ub3RpZnkoKTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0gZmluYWxseSB7DQogICAgICBlbmRCYXRjaCgpOw0KICAgIH0NCiAgfQ0KfQ0KZnVuY3Rpb24gYWRkU3ViKGxpbmspIHsNCiAgbGluay5kZXAuc2MrKzsNCiAgaWYgKGxpbmsuc3ViLmZsYWdzICYgNCkgew0KICAgIGNvbnN0IGNvbXB1dGVkID0gbGluay5kZXAuY29tcHV0ZWQ7DQogICAgaWYgKGNvbXB1dGVkICYmICFsaW5rLmRlcC5zdWJzKSB7DQogICAgICBjb21wdXRlZC5mbGFncyB8PSA0IHwgMTY7DQogICAgICBmb3IgKGxldCBsID0gY29tcHV0ZWQuZGVwczsgbDsgbCA9IGwubmV4dERlcCkgew0KICAgICAgICBhZGRTdWIobCk7DQogICAgICB9DQogICAgfQ0KICAgIGNvbnN0IGN1cnJlbnRUYWlsID0gbGluay5kZXAuc3ViczsNCiAgICBpZiAoY3VycmVudFRhaWwgIT09IGxpbmspIHsNCiAgICAgIGxpbmsucHJldlN1YiA9IGN1cnJlbnRUYWlsOw0KICAgICAgaWYgKGN1cnJlbnRUYWlsKSBjdXJyZW50VGFpbC5uZXh0U3ViID0gbGluazsNCiAgICB9DQogICAgaWYgKGxpbmsuZGVwLnN1YnNIZWFkID09PSB2b2lkIDApIHsNCiAgICAgIGxpbmsuZGVwLnN1YnNIZWFkID0gbGluazsNCiAgICB9DQogICAgbGluay5kZXAuc3VicyA9IGxpbms7DQogIH0NCn0NCmNvbnN0IHRhcmdldE1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgV2Vha01hcCgpOw0KY29uc3QgSVRFUkFURV9LRVkgPSBTeW1ib2woDQogICJPYmplY3QgaXRlcmF0ZSIgDQopOw0KY29uc3QgTUFQX0tFWV9JVEVSQVRFX0tFWSA9IFN5bWJvbCgNCiAgIk1hcCBrZXlzIGl0ZXJhdGUiIA0KKTsNCmNvbnN0IEFSUkFZX0lURVJBVEVfS0VZID0gU3ltYm9sKA0KICAiQXJyYXkgaXRlcmF0ZSIgDQopOw0KZnVuY3Rpb24gdHJhY2sodGFyZ2V0LCB0eXBlLCBrZXkpIHsNCiAgaWYgKHNob3VsZFRyYWNrICYmIGFjdGl2ZVN1Yikgew0KICAgIGxldCBkZXBzTWFwID0gdGFyZ2V0TWFwLmdldCh0YXJnZXQpOw0KICAgIGlmICghZGVwc01hcCkgew0KICAgICAgdGFyZ2V0TWFwLnNldCh0YXJnZXQsIGRlcHNNYXAgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpKTsNCiAgICB9DQogICAgbGV0IGRlcCA9IGRlcHNNYXAuZ2V0KGtleSk7DQogICAgaWYgKCFkZXApIHsNCiAgICAgIGRlcHNNYXAuc2V0KGtleSwgZGVwID0gbmV3IERlcCgpKTsNCiAgICAgIGRlcC5tYXAgPSBkZXBzTWFwOw0KICAgICAgZGVwLmtleSA9IGtleTsNCiAgICB9DQogICAgew0KICAgICAgZGVwLnRyYWNrKHsNCiAgICAgICAgdGFyZ2V0LA0KICAgICAgICB0eXBlLA0KICAgICAgICBrZXkNCiAgICAgIH0pOw0KICAgIH0NCiAgfQ0KfQ0KZnVuY3Rpb24gdHJpZ2dlcih0YXJnZXQsIHR5cGUsIGtleSwgbmV3VmFsdWUsIG9sZFZhbHVlLCBvbGRUYXJnZXQpIHsNCiAgY29uc3QgZGVwc01hcCA9IHRhcmdldE1hcC5nZXQodGFyZ2V0KTsNCiAgaWYgKCFkZXBzTWFwKSB7DQogICAgZ2xvYmFsVmVyc2lvbisrOw0KICAgIHJldHVybjsNCiAgfQ0KICBjb25zdCBydW4gPSAoZGVwKSA9PiB7DQogICAgaWYgKGRlcCkgew0KICAgICAgew0KICAgICAgICBkZXAudHJpZ2dlcih7DQogICAgICAgICAgdGFyZ2V0LA0KICAgICAgICAgIHR5cGUsDQogICAgICAgICAga2V5LA0KICAgICAgICAgIG5ld1ZhbHVlLA0KICAgICAgICAgIG9sZFZhbHVlLA0KICAgICAgICAgIG9sZFRhcmdldA0KICAgICAgICB9KTsNCiAgICAgIH0NCiAgICB9DQogIH07DQogIHN0YXJ0QmF0Y2goKTsNCiAgaWYgKHR5cGUgPT09ICJjbGVhciIpIHsNCiAgICBkZXBzTWFwLmZvckVhY2gocnVuKTsNCiAgfSBlbHNlIHsNCiAgICBjb25zdCB0YXJnZXRJc0FycmF5ID0gaXNBcnJheSh0YXJnZXQpOw0KICAgIGNvbnN0IGlzQXJyYXlJbmRleCA9IHRhcmdldElzQXJyYXkgJiYgaXNJbnRlZ2VyS2V5KGtleSk7DQogICAgaWYgKHRhcmdldElzQXJyYXkgJiYga2V5ID09PSAibGVuZ3RoIikgew0KICAgICAgY29uc3QgbmV3TGVuZ3RoID0gTnVtYmVyKG5ld1ZhbHVlKTsNCiAgICAgIGRlcHNNYXAuZm9yRWFjaCgoZGVwLCBrZXkyKSA9PiB7DQogICAgICAgIGlmIChrZXkyID09PSAibGVuZ3RoIiB8fCBrZXkyID09PSBBUlJBWV9JVEVSQVRFX0tFWSB8fCAhaXNTeW1ib2woa2V5MikgJiYga2V5MiA+PSBuZXdMZW5ndGgpIHsNCiAgICAgICAgICBydW4oZGVwKTsNCiAgICAgICAgfQ0KICAgICAgfSk7DQogICAgfSBlbHNlIHsNCiAgICAgIGlmIChrZXkgIT09IHZvaWQgMCB8fCBkZXBzTWFwLmhhcyh2b2lkIDApKSB7DQogICAgICAgIHJ1bihkZXBzTWFwLmdldChrZXkpKTsNCiAgICAgIH0NCiAgICAgIGlmIChpc0FycmF5SW5kZXgpIHsNCiAgICAgICAgcnVuKGRlcHNNYXAuZ2V0KEFSUkFZX0lURVJBVEVfS0VZKSk7DQogICAgICB9DQogICAgICBzd2l0Y2ggKHR5cGUpIHsNCiAgICAgICAgY2FzZSAiYWRkIjoNCiAgICAgICAgICBpZiAoIXRhcmdldElzQXJyYXkpIHsNCiAgICAgICAgICAgIHJ1bihkZXBzTWFwLmdldChJVEVSQVRFX0tFWSkpOw0KICAgICAgICAgICAgaWYgKGlzTWFwKHRhcmdldCkpIHsNCiAgICAgICAgICAgICAgcnVuKGRlcHNNYXAuZ2V0KE1BUF9LRVlfSVRFUkFURV9LRVkpKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICB9IGVsc2UgaWYgKGlzQXJyYXlJbmRleCkgew0KICAgICAgICAgICAgcnVuKGRlcHNNYXAuZ2V0KCJsZW5ndGgiKSk7DQogICAgICAgICAgfQ0KICAgICAgICAgIGJyZWFrOw0KICAgICAgICBjYXNlICJkZWxldGUiOg0KICAgICAgICAgIGlmICghdGFyZ2V0SXNBcnJheSkgew0KICAgICAgICAgICAgcnVuKGRlcHNNYXAuZ2V0KElURVJBVEVfS0VZKSk7DQogICAgICAgICAgICBpZiAoaXNNYXAodGFyZ2V0KSkgew0KICAgICAgICAgICAgICBydW4oZGVwc01hcC5nZXQoTUFQX0tFWV9JVEVSQVRFX0tFWSkpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgIH0NCiAgICAgICAgICBicmVhazsNCiAgICAgICAgY2FzZSAic2V0IjoNCiAgICAgICAgICBpZiAoaXNNYXAodGFyZ2V0KSkgew0KICAgICAgICAgICAgcnVuKGRlcHNNYXAuZ2V0KElURVJBVEVfS0VZKSk7DQogICAgICAgICAgfQ0KICAgICAgICAgIGJyZWFrOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICBlbmRCYXRjaCgpOw0KfQ0KDQpmdW5jdGlvbiByZWFjdGl2ZVJlYWRBcnJheShhcnJheSkgew0KICBjb25zdCByYXcgPSB0b1JhdyhhcnJheSk7DQogIGlmIChyYXcgPT09IGFycmF5KSByZXR1cm4gcmF3Ow0KICB0cmFjayhyYXcsICJpdGVyYXRlIiwgQVJSQVlfSVRFUkFURV9LRVkpOw0KICByZXR1cm4gaXNTaGFsbG93KGFycmF5KSA/IHJhdyA6IHJhdy5tYXAodG9SZWFjdGl2ZSk7DQp9DQpmdW5jdGlvbiBzaGFsbG93UmVhZEFycmF5KGFycikgew0KICB0cmFjayhhcnIgPSB0b1JhdyhhcnIpLCAiaXRlcmF0ZSIsIEFSUkFZX0lURVJBVEVfS0VZKTsNCiAgcmV0dXJuIGFycjsNCn0NCmNvbnN0IGFycmF5SW5zdHJ1bWVudGF0aW9ucyA9IHsNCiAgX19wcm90b19fOiBudWxsLA0KICBbU3ltYm9sLml0ZXJhdG9yXSgpIHsNCiAgICByZXR1cm4gaXRlcmF0b3IodGhpcywgU3ltYm9sLml0ZXJhdG9yLCB0b1JlYWN0aXZlKTsNCiAgfSwNCiAgY29uY2F0KC4uLmFyZ3MpIHsNCiAgICByZXR1cm4gcmVhY3RpdmVSZWFkQXJyYXkodGhpcykuY29uY2F0KA0KICAgICAgLi4uYXJncy5tYXAoKHgpID0+IGlzQXJyYXkoeCkgPyByZWFjdGl2ZVJlYWRBcnJheSh4KSA6IHgpDQogICAgKTsNCiAgfSwNCiAgZW50cmllcygpIHsNCiAgICByZXR1cm4gaXRlcmF0b3IodGhpcywgImVudHJpZXMiLCAodmFsdWUpID0+IHsNCiAgICAgIHZhbHVlWzFdID0gdG9SZWFjdGl2ZSh2YWx1ZVsxXSk7DQogICAgICByZXR1cm4gdmFsdWU7DQogICAgfSk7DQogIH0sDQogIGV2ZXJ5KGZuLCB0aGlzQXJnKSB7DQogICAgcmV0dXJuIGFwcGx5KHRoaXMsICJldmVyeSIsIGZuLCB0aGlzQXJnLCB2b2lkIDAsIGFyZ3VtZW50cyk7DQogIH0sDQogIGZpbHRlcihmbiwgdGhpc0FyZykgew0KICAgIHJldHVybiBhcHBseSh0aGlzLCAiZmlsdGVyIiwgZm4sIHRoaXNBcmcsICh2KSA9PiB2Lm1hcCh0b1JlYWN0aXZlKSwgYXJndW1lbnRzKTsNCiAgfSwNCiAgZmluZChmbiwgdGhpc0FyZykgew0KICAgIHJldHVybiBhcHBseSh0aGlzLCAiZmluZCIsIGZuLCB0aGlzQXJnLCB0b1JlYWN0aXZlLCBhcmd1bWVudHMpOw0KICB9LA0KICBmaW5kSW5kZXgoZm4sIHRoaXNBcmcpIHsNCiAgICByZXR1cm4gYXBwbHkodGhpcywgImZpbmRJbmRleCIsIGZuLCB0aGlzQXJnLCB2b2lkIDAsIGFyZ3VtZW50cyk7DQogIH0sDQogIGZpbmRMYXN0KGZuLCB0aGlzQXJnKSB7DQogICAgcmV0dXJuIGFwcGx5KHRoaXMsICJmaW5kTGFzdCIsIGZuLCB0aGlzQXJnLCB0b1JlYWN0aXZlLCBhcmd1bWVudHMpOw0KICB9LA0KICBmaW5kTGFzdEluZGV4KGZuLCB0aGlzQXJnKSB7DQogICAgcmV0dXJuIGFwcGx5KHRoaXMsICJmaW5kTGFzdEluZGV4IiwgZm4sIHRoaXNBcmcsIHZvaWQgMCwgYXJndW1lbnRzKTsNCiAgfSwNCiAgLy8gZmxhdCwgZmxhdE1hcCBjb3VsZCBiZW5lZml0IGZyb20gQVJSQVlfSVRFUkFURSBidXQgYXJlIG5vdCBzdHJhaWdodC1mb3J3YXJkIHRvIGltcGxlbWVudA0KICBmb3JFYWNoKGZuLCB0aGlzQXJnKSB7DQogICAgcmV0dXJuIGFwcGx5KHRoaXMsICJmb3JFYWNoIiwgZm4sIHRoaXNBcmcsIHZvaWQgMCwgYXJndW1lbnRzKTsNCiAgfSwNCiAgaW5jbHVkZXMoLi4uYXJncykgew0KICAgIHJldHVybiBzZWFyY2hQcm94eSh0aGlzLCAiaW5jbHVkZXMiLCBhcmdzKTsNCiAgfSwNCiAgaW5kZXhPZiguLi5hcmdzKSB7DQogICAgcmV0dXJuIHNlYXJjaFByb3h5KHRoaXMsICJpbmRleE9mIiwgYXJncyk7DQogIH0sDQogIGpvaW4oc2VwYXJhdG9yKSB7DQogICAgcmV0dXJuIHJlYWN0aXZlUmVhZEFycmF5KHRoaXMpLmpvaW4oc2VwYXJhdG9yKTsNCiAgfSwNCiAgLy8ga2V5cygpIGl0ZXJhdG9yIG9ubHkgcmVhZHMgYGxlbmd0aGAsIG5vIG9wdGltaXNhdGlvbiByZXF1aXJlZA0KICBsYXN0SW5kZXhPZiguLi5hcmdzKSB7DQogICAgcmV0dXJuIHNlYXJjaFByb3h5KHRoaXMsICJsYXN0SW5kZXhPZiIsIGFyZ3MpOw0KICB9LA0KICBtYXAoZm4sIHRoaXNBcmcpIHsNCiAgICByZXR1cm4gYXBwbHkodGhpcywgIm1hcCIsIGZuLCB0aGlzQXJnLCB2b2lkIDAsIGFyZ3VtZW50cyk7DQogIH0sDQogIHBvcCgpIHsNCiAgICByZXR1cm4gbm9UcmFja2luZyh0aGlzLCAicG9wIik7DQogIH0sDQogIHB1c2goLi4uYXJncykgew0KICAgIHJldHVybiBub1RyYWNraW5nKHRoaXMsICJwdXNoIiwgYXJncyk7DQogIH0sDQogIHJlZHVjZShmbiwgLi4uYXJncykgew0KICAgIHJldHVybiByZWR1Y2UodGhpcywgInJlZHVjZSIsIGZuLCBhcmdzKTsNCiAgfSwNCiAgcmVkdWNlUmlnaHQoZm4sIC4uLmFyZ3MpIHsNCiAgICByZXR1cm4gcmVkdWNlKHRoaXMsICJyZWR1Y2VSaWdodCIsIGZuLCBhcmdzKTsNCiAgfSwNCiAgc2hpZnQoKSB7DQogICAgcmV0dXJuIG5vVHJhY2tpbmcodGhpcywgInNoaWZ0Iik7DQogIH0sDQogIC8vIHNsaWNlIGNvdWxkIHVzZSBBUlJBWV9JVEVSQVRFIGJ1dCBhbHNvIHNlZW1zIHRvIGJlZyBmb3IgcmFuZ2UgdHJhY2tpbmcNCiAgc29tZShmbiwgdGhpc0FyZykgew0KICAgIHJldHVybiBhcHBseSh0aGlzLCAic29tZSIsIGZuLCB0aGlzQXJnLCB2b2lkIDAsIGFyZ3VtZW50cyk7DQogIH0sDQogIHNwbGljZSguLi5hcmdzKSB7DQogICAgcmV0dXJuIG5vVHJhY2tpbmcodGhpcywgInNwbGljZSIsIGFyZ3MpOw0KICB9LA0KICB0b1JldmVyc2VkKCkgew0KICAgIHJldHVybiByZWFjdGl2ZVJlYWRBcnJheSh0aGlzKS50b1JldmVyc2VkKCk7DQogIH0sDQogIHRvU29ydGVkKGNvbXBhcmVyKSB7DQogICAgcmV0dXJuIHJlYWN0aXZlUmVhZEFycmF5KHRoaXMpLnRvU29ydGVkKGNvbXBhcmVyKTsNCiAgfSwNCiAgdG9TcGxpY2VkKC4uLmFyZ3MpIHsNCiAgICByZXR1cm4gcmVhY3RpdmVSZWFkQXJyYXkodGhpcykudG9TcGxpY2VkKC4uLmFyZ3MpOw0KICB9LA0KICB1bnNoaWZ0KC4uLmFyZ3MpIHsNCiAgICByZXR1cm4gbm9UcmFja2luZyh0aGlzLCAidW5zaGlmdCIsIGFyZ3MpOw0KICB9LA0KICB2YWx1ZXMoKSB7DQogICAgcmV0dXJuIGl0ZXJhdG9yKHRoaXMsICJ2YWx1ZXMiLCB0b1JlYWN0aXZlKTsNCiAgfQ0KfTsNCmZ1bmN0aW9uIGl0ZXJhdG9yKHNlbGYsIG1ldGhvZCwgd3JhcFZhbHVlKSB7DQogIGNvbnN0IGFyciA9IHNoYWxsb3dSZWFkQXJyYXkoc2VsZik7DQogIGNvbnN0IGl0ZXIgPSBhcnJbbWV0aG9kXSgpOw0KICBpZiAoYXJyICE9PSBzZWxmICYmICFpc1NoYWxsb3coc2VsZikpIHsNCiAgICBpdGVyLl9uZXh0ID0gaXRlci5uZXh0Ow0KICAgIGl0ZXIubmV4dCA9ICgpID0+IHsNCiAgICAgIGNvbnN0IHJlc3VsdCA9IGl0ZXIuX25leHQoKTsNCiAgICAgIGlmIChyZXN1bHQudmFsdWUpIHsNCiAgICAgICAgcmVzdWx0LnZhbHVlID0gd3JhcFZhbHVlKHJlc3VsdC52YWx1ZSk7DQogICAgICB9DQogICAgICByZXR1cm4gcmVzdWx0Ow0KICAgIH07DQogIH0NCiAgcmV0dXJuIGl0ZXI7DQp9DQpjb25zdCBhcnJheVByb3RvID0gQXJyYXkucHJvdG90eXBlOw0KZnVuY3Rpb24gYXBwbHkoc2VsZiwgbWV0aG9kLCBmbiwgdGhpc0FyZywgd3JhcHBlZFJldEZuLCBhcmdzKSB7DQogIGNvbnN0IGFyciA9IHNoYWxsb3dSZWFkQXJyYXkoc2VsZik7DQogIGNvbnN0IG5lZWRzV3JhcCA9IGFyciAhPT0gc2VsZiAmJiAhaXNTaGFsbG93KHNlbGYpOw0KICBjb25zdCBtZXRob2RGbiA9IGFyclttZXRob2RdOw0KICBpZiAobWV0aG9kRm4gIT09IGFycmF5UHJvdG9bbWV0aG9kXSkgew0KICAgIGNvbnN0IHJlc3VsdDIgPSBtZXRob2RGbi5hcHBseShzZWxmLCBhcmdzKTsNCiAgICByZXR1cm4gbmVlZHNXcmFwID8gdG9SZWFjdGl2ZShyZXN1bHQyKSA6IHJlc3VsdDI7DQogIH0NCiAgbGV0IHdyYXBwZWRGbiA9IGZuOw0KICBpZiAoYXJyICE9PSBzZWxmKSB7DQogICAgaWYgKG5lZWRzV3JhcCkgew0KICAgICAgd3JhcHBlZEZuID0gZnVuY3Rpb24oaXRlbSwgaW5kZXgpIHsNCiAgICAgICAgcmV0dXJuIGZuLmNhbGwodGhpcywgdG9SZWFjdGl2ZShpdGVtKSwgaW5kZXgsIHNlbGYpOw0KICAgICAgfTsNCiAgICB9IGVsc2UgaWYgKGZuLmxlbmd0aCA+IDIpIHsNCiAgICAgIHdyYXBwZWRGbiA9IGZ1bmN0aW9uKGl0ZW0sIGluZGV4KSB7DQogICAgICAgIHJldHVybiBmbi5jYWxsKHRoaXMsIGl0ZW0sIGluZGV4LCBzZWxmKTsNCiAgICAgIH07DQogICAgfQ0KICB9DQogIGNvbnN0IHJlc3VsdCA9IG1ldGhvZEZuLmNhbGwoYXJyLCB3cmFwcGVkRm4sIHRoaXNBcmcpOw0KICByZXR1cm4gbmVlZHNXcmFwICYmIHdyYXBwZWRSZXRGbiA/IHdyYXBwZWRSZXRGbihyZXN1bHQpIDogcmVzdWx0Ow0KfQ0KZnVuY3Rpb24gcmVkdWNlKHNlbGYsIG1ldGhvZCwgZm4sIGFyZ3MpIHsNCiAgY29uc3QgYXJyID0gc2hhbGxvd1JlYWRBcnJheShzZWxmKTsNCiAgbGV0IHdyYXBwZWRGbiA9IGZuOw0KICBpZiAoYXJyICE9PSBzZWxmKSB7DQogICAgaWYgKCFpc1NoYWxsb3coc2VsZikpIHsNCiAgICAgIHdyYXBwZWRGbiA9IGZ1bmN0aW9uKGFjYywgaXRlbSwgaW5kZXgpIHsNCiAgICAgICAgcmV0dXJuIGZuLmNhbGwodGhpcywgYWNjLCB0b1JlYWN0aXZlKGl0ZW0pLCBpbmRleCwgc2VsZik7DQogICAgICB9Ow0KICAgIH0gZWxzZSBpZiAoZm4ubGVuZ3RoID4gMykgew0KICAgICAgd3JhcHBlZEZuID0gZnVuY3Rpb24oYWNjLCBpdGVtLCBpbmRleCkgew0KICAgICAgICByZXR1cm4gZm4uY2FsbCh0aGlzLCBhY2MsIGl0ZW0sIGluZGV4LCBzZWxmKTsNCiAgICAgIH07DQogICAgfQ0KICB9DQogIHJldHVybiBhcnJbbWV0aG9kXSh3cmFwcGVkRm4sIC4uLmFyZ3MpOw0KfQ0KZnVuY3Rpb24gc2VhcmNoUHJveHkoc2VsZiwgbWV0aG9kLCBhcmdzKSB7DQogIGNvbnN0IGFyciA9IHRvUmF3KHNlbGYpOw0KICB0cmFjayhhcnIsICJpdGVyYXRlIiwgQVJSQVlfSVRFUkFURV9LRVkpOw0KICBjb25zdCByZXMgPSBhcnJbbWV0aG9kXSguLi5hcmdzKTsNCiAgaWYgKChyZXMgPT09IC0xIHx8IHJlcyA9PT0gZmFsc2UpICYmIGlzUHJveHkoYXJnc1swXSkpIHsNCiAgICBhcmdzWzBdID0gdG9SYXcoYXJnc1swXSk7DQogICAgcmV0dXJuIGFyclttZXRob2RdKC4uLmFyZ3MpOw0KICB9DQogIHJldHVybiByZXM7DQp9DQpmdW5jdGlvbiBub1RyYWNraW5nKHNlbGYsIG1ldGhvZCwgYXJncyA9IFtdKSB7DQogIHBhdXNlVHJhY2tpbmcoKTsNCiAgc3RhcnRCYXRjaCgpOw0KICBjb25zdCByZXMgPSB0b1JhdyhzZWxmKVttZXRob2RdLmFwcGx5KHNlbGYsIGFyZ3MpOw0KICBlbmRCYXRjaCgpOw0KICByZXNldFRyYWNraW5nKCk7DQogIHJldHVybiByZXM7DQp9DQoNCmNvbnN0IGlzTm9uVHJhY2thYmxlS2V5cyA9IC8qIEBfX1BVUkVfXyAqLyBtYWtlTWFwKGBfX3Byb3RvX18sX192X2lzUmVmLF9faXNWdWVgKTsNCmNvbnN0IGJ1aWx0SW5TeW1ib2xzID0gbmV3IFNldCgNCiAgLyogQF9fUFVSRV9fICovIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKFN5bWJvbCkuZmlsdGVyKChrZXkpID0+IGtleSAhPT0gImFyZ3VtZW50cyIgJiYga2V5ICE9PSAiY2FsbGVyIikubWFwKChrZXkpID0+IFN5bWJvbFtrZXldKS5maWx0ZXIoaXNTeW1ib2wpDQopOw0KZnVuY3Rpb24gaGFzT3duUHJvcGVydHkoa2V5KSB7DQogIGlmICghaXNTeW1ib2woa2V5KSkga2V5ID0gU3RyaW5nKGtleSk7DQogIGNvbnN0IG9iaiA9IHRvUmF3KHRoaXMpOw0KICB0cmFjayhvYmosICJoYXMiLCBrZXkpOw0KICByZXR1cm4gb2JqLmhhc093blByb3BlcnR5KGtleSk7DQp9DQpjbGFzcyBCYXNlUmVhY3RpdmVIYW5kbGVyIHsNCiAgY29uc3RydWN0b3IoX2lzUmVhZG9ubHkgPSBmYWxzZSwgX2lzU2hhbGxvdyA9IGZhbHNlKSB7DQogICAgdGhpcy5faXNSZWFkb25seSA9IF9pc1JlYWRvbmx5Ow0KICAgIHRoaXMuX2lzU2hhbGxvdyA9IF9pc1NoYWxsb3c7DQogIH0NCiAgZ2V0KHRhcmdldCwga2V5LCByZWNlaXZlcikgew0KICAgIGlmIChrZXkgPT09ICJfX3Zfc2tpcCIpIHJldHVybiB0YXJnZXRbIl9fdl9za2lwIl07DQogICAgY29uc3QgaXNSZWFkb25seTIgPSB0aGlzLl9pc1JlYWRvbmx5LCBpc1NoYWxsb3cyID0gdGhpcy5faXNTaGFsbG93Ow0KICAgIGlmIChrZXkgPT09ICJfX3ZfaXNSZWFjdGl2ZSIpIHsNCiAgICAgIHJldHVybiAhaXNSZWFkb25seTI7DQogICAgfSBlbHNlIGlmIChrZXkgPT09ICJfX3ZfaXNSZWFkb25seSIpIHsNCiAgICAgIHJldHVybiBpc1JlYWRvbmx5MjsNCiAgICB9IGVsc2UgaWYgKGtleSA9PT0gIl9fdl9pc1NoYWxsb3ciKSB7DQogICAgICByZXR1cm4gaXNTaGFsbG93MjsNCiAgICB9IGVsc2UgaWYgKGtleSA9PT0gIl9fdl9yYXciKSB7DQogICAgICBpZiAocmVjZWl2ZXIgPT09IChpc1JlYWRvbmx5MiA/IGlzU2hhbGxvdzIgPyBzaGFsbG93UmVhZG9ubHlNYXAgOiByZWFkb25seU1hcCA6IGlzU2hhbGxvdzIgPyBzaGFsbG93UmVhY3RpdmVNYXAgOiByZWFjdGl2ZU1hcCkuZ2V0KHRhcmdldCkgfHwgLy8gcmVjZWl2ZXIgaXMgbm90IHRoZSByZWFjdGl2ZSBwcm94eSwgYnV0IGhhcyB0aGUgc2FtZSBwcm90b3R5cGUNCiAgICAgIC8vIHRoaXMgbWVhbnMgdGhlIHJlY2VpdmVyIGlzIGEgdXNlciBwcm94eSBvZiB0aGUgcmVhY3RpdmUgcHJveHkNCiAgICAgIE9iamVjdC5nZXRQcm90b3R5cGVPZih0YXJnZXQpID09PSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocmVjZWl2ZXIpKSB7DQogICAgICAgIHJldHVybiB0YXJnZXQ7DQogICAgICB9DQogICAgICByZXR1cm47DQogICAgfQ0KICAgIGNvbnN0IHRhcmdldElzQXJyYXkgPSBpc0FycmF5KHRhcmdldCk7DQogICAgaWYgKCFpc1JlYWRvbmx5Mikgew0KICAgICAgbGV0IGZuOw0KICAgICAgaWYgKHRhcmdldElzQXJyYXkgJiYgKGZuID0gYXJyYXlJbnN0cnVtZW50YXRpb25zW2tleV0pKSB7DQogICAgICAgIHJldHVybiBmbjsNCiAgICAgIH0NCiAgICAgIGlmIChrZXkgPT09ICJoYXNPd25Qcm9wZXJ0eSIpIHsNCiAgICAgICAgcmV0dXJuIGhhc093blByb3BlcnR5Ow0KICAgICAgfQ0KICAgIH0NCiAgICBjb25zdCByZXMgPSBSZWZsZWN0LmdldCgNCiAgICAgIHRhcmdldCwNCiAgICAgIGtleSwNCiAgICAgIC8vIGlmIHRoaXMgaXMgYSBwcm94eSB3cmFwcGluZyBhIHJlZiwgcmV0dXJuIG1ldGhvZHMgdXNpbmcgdGhlIHJhdyByZWYNCiAgICAgIC8vIGFzIHJlY2VpdmVyIHNvIHRoYXQgd2UgZG9uJ3QgaGF2ZSB0byBjYWxsIGB0b1Jhd2Agb24gdGhlIHJlZiBpbiBhbGwNCiAgICAgIC8vIGl0cyBjbGFzcyBtZXRob2RzDQogICAgICBpc1JlZih0YXJnZXQpID8gdGFyZ2V0IDogcmVjZWl2ZXINCiAgICApOw0KICAgIGlmIChpc1N5bWJvbChrZXkpID8gYnVpbHRJblN5bWJvbHMuaGFzKGtleSkgOiBpc05vblRyYWNrYWJsZUtleXMoa2V5KSkgew0KICAgICAgcmV0dXJuIHJlczsNCiAgICB9DQogICAgaWYgKCFpc1JlYWRvbmx5Mikgew0KICAgICAgdHJhY2sodGFyZ2V0LCAiZ2V0Iiwga2V5KTsNCiAgICB9DQogICAgaWYgKGlzU2hhbGxvdzIpIHsNCiAgICAgIHJldHVybiByZXM7DQogICAgfQ0KICAgIGlmIChpc1JlZihyZXMpKSB7DQogICAgICByZXR1cm4gdGFyZ2V0SXNBcnJheSAmJiBpc0ludGVnZXJLZXkoa2V5KSA/IHJlcyA6IHJlcy52YWx1ZTsNCiAgICB9DQogICAgaWYgKGlzT2JqZWN0KHJlcykpIHsNCiAgICAgIHJldHVybiBpc1JlYWRvbmx5MiA/IHJlYWRvbmx5KHJlcykgOiByZWFjdGl2ZShyZXMpOw0KICAgIH0NCiAgICByZXR1cm4gcmVzOw0KICB9DQp9DQpjbGFzcyBNdXRhYmxlUmVhY3RpdmVIYW5kbGVyIGV4dGVuZHMgQmFzZVJlYWN0aXZlSGFuZGxlciB7DQogIGNvbnN0cnVjdG9yKGlzU2hhbGxvdzIgPSBmYWxzZSkgew0KICAgIHN1cGVyKGZhbHNlLCBpc1NoYWxsb3cyKTsNCiAgfQ0KICBzZXQodGFyZ2V0LCBrZXksIHZhbHVlLCByZWNlaXZlcikgew0KICAgIGxldCBvbGRWYWx1ZSA9IHRhcmdldFtrZXldOw0KICAgIGlmICghdGhpcy5faXNTaGFsbG93KSB7DQogICAgICBjb25zdCBpc09sZFZhbHVlUmVhZG9ubHkgPSBpc1JlYWRvbmx5KG9sZFZhbHVlKTsNCiAgICAgIGlmICghaXNTaGFsbG93KHZhbHVlKSAmJiAhaXNSZWFkb25seSh2YWx1ZSkpIHsNCiAgICAgICAgb2xkVmFsdWUgPSB0b1JhdyhvbGRWYWx1ZSk7DQogICAgICAgIHZhbHVlID0gdG9SYXcodmFsdWUpOw0KICAgICAgfQ0KICAgICAgaWYgKCFpc0FycmF5KHRhcmdldCkgJiYgaXNSZWYob2xkVmFsdWUpICYmICFpc1JlZih2YWx1ZSkpIHsNCiAgICAgICAgaWYgKGlzT2xkVmFsdWVSZWFkb25seSkgew0KICAgICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBvbGRWYWx1ZS52YWx1ZSA9IHZhbHVlOw0KICAgICAgICAgIHJldHVybiB0cnVlOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICAgIGNvbnN0IGhhZEtleSA9IGlzQXJyYXkodGFyZ2V0KSAmJiBpc0ludGVnZXJLZXkoa2V5KSA/IE51bWJlcihrZXkpIDwgdGFyZ2V0Lmxlbmd0aCA6IGhhc093bih0YXJnZXQsIGtleSk7DQogICAgY29uc3QgcmVzdWx0ID0gUmVmbGVjdC5zZXQoDQogICAgICB0YXJnZXQsDQogICAgICBrZXksDQogICAgICB2YWx1ZSwNCiAgICAgIGlzUmVmKHRhcmdldCkgPyB0YXJnZXQgOiByZWNlaXZlcg0KICAgICk7DQogICAgaWYgKHRhcmdldCA9PT0gdG9SYXcocmVjZWl2ZXIpKSB7DQogICAgICBpZiAoIWhhZEtleSkgew0KICAgICAgICB0cmlnZ2VyKHRhcmdldCwgImFkZCIsIGtleSwgdmFsdWUpOw0KICAgICAgfSBlbHNlIGlmIChoYXNDaGFuZ2VkKHZhbHVlLCBvbGRWYWx1ZSkpIHsNCiAgICAgICAgdHJpZ2dlcih0YXJnZXQsICJzZXQiLCBrZXksIHZhbHVlLCBvbGRWYWx1ZSk7DQogICAgICB9DQogICAgfQ0KICAgIHJldHVybiByZXN1bHQ7DQogIH0NCiAgZGVsZXRlUHJvcGVydHkodGFyZ2V0LCBrZXkpIHsNCiAgICBjb25zdCBoYWRLZXkgPSBoYXNPd24odGFyZ2V0LCBrZXkpOw0KICAgIGNvbnN0IG9sZFZhbHVlID0gdGFyZ2V0W2tleV07DQogICAgY29uc3QgcmVzdWx0ID0gUmVmbGVjdC5kZWxldGVQcm9wZXJ0eSh0YXJnZXQsIGtleSk7DQogICAgaWYgKHJlc3VsdCAmJiBoYWRLZXkpIHsNCiAgICAgIHRyaWdnZXIodGFyZ2V0LCAiZGVsZXRlIiwga2V5LCB2b2lkIDAsIG9sZFZhbHVlKTsNCiAgICB9DQogICAgcmV0dXJuIHJlc3VsdDsNCiAgfQ0KICBoYXModGFyZ2V0LCBrZXkpIHsNCiAgICBjb25zdCByZXN1bHQgPSBSZWZsZWN0Lmhhcyh0YXJnZXQsIGtleSk7DQogICAgaWYgKCFpc1N5bWJvbChrZXkpIHx8ICFidWlsdEluU3ltYm9scy5oYXMoa2V5KSkgew0KICAgICAgdHJhY2sodGFyZ2V0LCAiaGFzIiwga2V5KTsNCiAgICB9DQogICAgcmV0dXJuIHJlc3VsdDsNCiAgfQ0KICBvd25LZXlzKHRhcmdldCkgew0KICAgIHRyYWNrKA0KICAgICAgdGFyZ2V0LA0KICAgICAgIml0ZXJhdGUiLA0KICAgICAgaXNBcnJheSh0YXJnZXQpID8gImxlbmd0aCIgOiBJVEVSQVRFX0tFWQ0KICAgICk7DQogICAgcmV0dXJuIFJlZmxlY3Qub3duS2V5cyh0YXJnZXQpOw0KICB9DQp9DQpjbGFzcyBSZWFkb25seVJlYWN0aXZlSGFuZGxlciBleHRlbmRzIEJhc2VSZWFjdGl2ZUhhbmRsZXIgew0KICBjb25zdHJ1Y3Rvcihpc1NoYWxsb3cyID0gZmFsc2UpIHsNCiAgICBzdXBlcih0cnVlLCBpc1NoYWxsb3cyKTsNCiAgfQ0KICBzZXQodGFyZ2V0LCBrZXkpIHsNCiAgICB7DQogICAgICB3YXJuJDIoDQogICAgICAgIGBTZXQgb3BlcmF0aW9uIG9uIGtleSAiJHtTdHJpbmcoa2V5KX0iIGZhaWxlZDogdGFyZ2V0IGlzIHJlYWRvbmx5LmAsDQogICAgICAgIHRhcmdldA0KICAgICAgKTsNCiAgICB9DQogICAgcmV0dXJuIHRydWU7DQogIH0NCiAgZGVsZXRlUHJvcGVydHkodGFyZ2V0LCBrZXkpIHsNCiAgICB7DQogICAgICB3YXJuJDIoDQogICAgICAgIGBEZWxldGUgb3BlcmF0aW9uIG9uIGtleSAiJHtTdHJpbmcoa2V5KX0iIGZhaWxlZDogdGFyZ2V0IGlzIHJlYWRvbmx5LmAsDQogICAgICAgIHRhcmdldA0KICAgICAgKTsNCiAgICB9DQogICAgcmV0dXJuIHRydWU7DQogIH0NCn0NCmNvbnN0IG11dGFibGVIYW5kbGVycyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTXV0YWJsZVJlYWN0aXZlSGFuZGxlcigpOw0KY29uc3QgcmVhZG9ubHlIYW5kbGVycyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgUmVhZG9ubHlSZWFjdGl2ZUhhbmRsZXIoKTsNCmNvbnN0IHNoYWxsb3dSZWFjdGl2ZUhhbmRsZXJzID0gLyogQF9fUFVSRV9fICovIG5ldyBNdXRhYmxlUmVhY3RpdmVIYW5kbGVyKHRydWUpOw0KY29uc3Qgc2hhbGxvd1JlYWRvbmx5SGFuZGxlcnMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFJlYWRvbmx5UmVhY3RpdmVIYW5kbGVyKHRydWUpOw0KDQpjb25zdCB0b1NoYWxsb3cgPSAodmFsdWUpID0+IHZhbHVlOw0KY29uc3QgZ2V0UHJvdG8gPSAodikgPT4gUmVmbGVjdC5nZXRQcm90b3R5cGVPZih2KTsNCmZ1bmN0aW9uIGNyZWF0ZUl0ZXJhYmxlTWV0aG9kKG1ldGhvZCwgaXNSZWFkb25seTIsIGlzU2hhbGxvdzIpIHsNCiAgcmV0dXJuIGZ1bmN0aW9uKC4uLmFyZ3MpIHsNCiAgICBjb25zdCB0YXJnZXQgPSB0aGlzWyJfX3ZfcmF3Il07DQogICAgY29uc3QgcmF3VGFyZ2V0ID0gdG9SYXcodGFyZ2V0KTsNCiAgICBjb25zdCB0YXJnZXRJc01hcCA9IGlzTWFwKHJhd1RhcmdldCk7DQogICAgY29uc3QgaXNQYWlyID0gbWV0aG9kID09PSAiZW50cmllcyIgfHwgbWV0aG9kID09PSBTeW1ib2wuaXRlcmF0b3IgJiYgdGFyZ2V0SXNNYXA7DQogICAgY29uc3QgaXNLZXlPbmx5ID0gbWV0aG9kID09PSAia2V5cyIgJiYgdGFyZ2V0SXNNYXA7DQogICAgY29uc3QgaW5uZXJJdGVyYXRvciA9IHRhcmdldFttZXRob2RdKC4uLmFyZ3MpOw0KICAgIGNvbnN0IHdyYXAgPSBpc1NoYWxsb3cyID8gdG9TaGFsbG93IDogaXNSZWFkb25seTIgPyB0b1JlYWRvbmx5IDogdG9SZWFjdGl2ZTsNCiAgICAhaXNSZWFkb25seTIgJiYgdHJhY2soDQogICAgICByYXdUYXJnZXQsDQogICAgICAiaXRlcmF0ZSIsDQogICAgICBpc0tleU9ubHkgPyBNQVBfS0VZX0lURVJBVEVfS0VZIDogSVRFUkFURV9LRVkNCiAgICApOw0KICAgIHJldHVybiB7DQogICAgICAvLyBpdGVyYXRvciBwcm90b2NvbA0KICAgICAgbmV4dCgpIHsNCiAgICAgICAgY29uc3QgeyB2YWx1ZSwgZG9uZSB9ID0gaW5uZXJJdGVyYXRvci5uZXh0KCk7DQogICAgICAgIHJldHVybiBkb25lID8geyB2YWx1ZSwgZG9uZSB9IDogew0KICAgICAgICAgIHZhbHVlOiBpc1BhaXIgPyBbd3JhcCh2YWx1ZVswXSksIHdyYXAodmFsdWVbMV0pXSA6IHdyYXAodmFsdWUpLA0KICAgICAgICAgIGRvbmUNCiAgICAgICAgfTsNCiAgICAgIH0sDQogICAgICAvLyBpdGVyYWJsZSBwcm90b2NvbA0KICAgICAgW1N5bWJvbC5pdGVyYXRvcl0oKSB7DQogICAgICAgIHJldHVybiB0aGlzOw0KICAgICAgfQ0KICAgIH07DQogIH07DQp9DQpmdW5jdGlvbiBjcmVhdGVSZWFkb25seU1ldGhvZCh0eXBlKSB7DQogIHJldHVybiBmdW5jdGlvbiguLi5hcmdzKSB7DQogICAgew0KICAgICAgY29uc3Qga2V5ID0gYXJnc1swXSA/IGBvbiBrZXkgIiR7YXJnc1swXX0iIGAgOiBgYDsNCiAgICAgIHdhcm4kMigNCiAgICAgICAgYCR7Y2FwaXRhbGl6ZSh0eXBlKX0gb3BlcmF0aW9uICR7a2V5fWZhaWxlZDogdGFyZ2V0IGlzIHJlYWRvbmx5LmAsDQogICAgICAgIHRvUmF3KHRoaXMpDQogICAgICApOw0KICAgIH0NCiAgICByZXR1cm4gdHlwZSA9PT0gImRlbGV0ZSIgPyBmYWxzZSA6IHR5cGUgPT09ICJjbGVhciIgPyB2b2lkIDAgOiB0aGlzOw0KICB9Ow0KfQ0KZnVuY3Rpb24gY3JlYXRlSW5zdHJ1bWVudGF0aW9ucyhyZWFkb25seSwgc2hhbGxvdykgew0KICBjb25zdCBpbnN0cnVtZW50YXRpb25zID0gew0KICAgIGdldChrZXkpIHsNCiAgICAgIGNvbnN0IHRhcmdldCA9IHRoaXNbIl9fdl9yYXciXTsNCiAgICAgIGNvbnN0IHJhd1RhcmdldCA9IHRvUmF3KHRhcmdldCk7DQogICAgICBjb25zdCByYXdLZXkgPSB0b1JhdyhrZXkpOw0KICAgICAgaWYgKCFyZWFkb25seSkgew0KICAgICAgICBpZiAoaGFzQ2hhbmdlZChrZXksIHJhd0tleSkpIHsNCiAgICAgICAgICB0cmFjayhyYXdUYXJnZXQsICJnZXQiLCBrZXkpOw0KICAgICAgICB9DQogICAgICAgIHRyYWNrKHJhd1RhcmdldCwgImdldCIsIHJhd0tleSk7DQogICAgICB9DQogICAgICBjb25zdCB7IGhhcyB9ID0gZ2V0UHJvdG8ocmF3VGFyZ2V0KTsNCiAgICAgIGNvbnN0IHdyYXAgPSBzaGFsbG93ID8gdG9TaGFsbG93IDogcmVhZG9ubHkgPyB0b1JlYWRvbmx5IDogdG9SZWFjdGl2ZTsNCiAgICAgIGlmIChoYXMuY2FsbChyYXdUYXJnZXQsIGtleSkpIHsNCiAgICAgICAgcmV0dXJuIHdyYXAodGFyZ2V0LmdldChrZXkpKTsNCiAgICAgIH0gZWxzZSBpZiAoaGFzLmNhbGwocmF3VGFyZ2V0LCByYXdLZXkpKSB7DQogICAgICAgIHJldHVybiB3cmFwKHRhcmdldC5nZXQocmF3S2V5KSk7DQogICAgICB9IGVsc2UgaWYgKHRhcmdldCAhPT0gcmF3VGFyZ2V0KSB7DQogICAgICAgIHRhcmdldC5nZXQoa2V5KTsNCiAgICAgIH0NCiAgICB9LA0KICAgIGdldCBzaXplKCkgew0KICAgICAgY29uc3QgdGFyZ2V0ID0gdGhpc1siX192X3JhdyJdOw0KICAgICAgIXJlYWRvbmx5ICYmIHRyYWNrKHRvUmF3KHRhcmdldCksICJpdGVyYXRlIiwgSVRFUkFURV9LRVkpOw0KICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0KHRhcmdldCwgInNpemUiLCB0YXJnZXQpOw0KICAgIH0sDQogICAgaGFzKGtleSkgew0KICAgICAgY29uc3QgdGFyZ2V0ID0gdGhpc1siX192X3JhdyJdOw0KICAgICAgY29uc3QgcmF3VGFyZ2V0ID0gdG9SYXcodGFyZ2V0KTsNCiAgICAgIGNvbnN0IHJhd0tleSA9IHRvUmF3KGtleSk7DQogICAgICBpZiAoIXJlYWRvbmx5KSB7DQogICAgICAgIGlmIChoYXNDaGFuZ2VkKGtleSwgcmF3S2V5KSkgew0KICAgICAgICAgIHRyYWNrKHJhd1RhcmdldCwgImhhcyIsIGtleSk7DQogICAgICAgIH0NCiAgICAgICAgdHJhY2socmF3VGFyZ2V0LCAiaGFzIiwgcmF3S2V5KTsNCiAgICAgIH0NCiAgICAgIHJldHVybiBrZXkgPT09IHJhd0tleSA/IHRhcmdldC5oYXMoa2V5KSA6IHRhcmdldC5oYXMoa2V5KSB8fCB0YXJnZXQuaGFzKHJhd0tleSk7DQogICAgfSwNCiAgICBmb3JFYWNoKGNhbGxiYWNrLCB0aGlzQXJnKSB7DQogICAgICBjb25zdCBvYnNlcnZlZCA9IHRoaXM7DQogICAgICBjb25zdCB0YXJnZXQgPSBvYnNlcnZlZFsiX192X3JhdyJdOw0KICAgICAgY29uc3QgcmF3VGFyZ2V0ID0gdG9SYXcodGFyZ2V0KTsNCiAgICAgIGNvbnN0IHdyYXAgPSBzaGFsbG93ID8gdG9TaGFsbG93IDogcmVhZG9ubHkgPyB0b1JlYWRvbmx5IDogdG9SZWFjdGl2ZTsNCiAgICAgICFyZWFkb25seSAmJiB0cmFjayhyYXdUYXJnZXQsICJpdGVyYXRlIiwgSVRFUkFURV9LRVkpOw0KICAgICAgcmV0dXJuIHRhcmdldC5mb3JFYWNoKCh2YWx1ZSwga2V5KSA9PiB7DQogICAgICAgIHJldHVybiBjYWxsYmFjay5jYWxsKHRoaXNBcmcsIHdyYXAodmFsdWUpLCB3cmFwKGtleSksIG9ic2VydmVkKTsNCiAgICAgIH0pOw0KICAgIH0NCiAgfTsNCiAgZXh0ZW5kKA0KICAgIGluc3RydW1lbnRhdGlvbnMsDQogICAgcmVhZG9ubHkgPyB7DQogICAgICBhZGQ6IGNyZWF0ZVJlYWRvbmx5TWV0aG9kKCJhZGQiKSwNCiAgICAgIHNldDogY3JlYXRlUmVhZG9ubHlNZXRob2QoInNldCIpLA0KICAgICAgZGVsZXRlOiBjcmVhdGVSZWFkb25seU1ldGhvZCgiZGVsZXRlIiksDQogICAgICBjbGVhcjogY3JlYXRlUmVhZG9ubHlNZXRob2QoImNsZWFyIikNCiAgICB9IDogew0KICAgICAgYWRkKHZhbHVlKSB7DQogICAgICAgIGlmICghc2hhbGxvdyAmJiAhaXNTaGFsbG93KHZhbHVlKSAmJiAhaXNSZWFkb25seSh2YWx1ZSkpIHsNCiAgICAgICAgICB2YWx1ZSA9IHRvUmF3KHZhbHVlKTsNCiAgICAgICAgfQ0KICAgICAgICBjb25zdCB0YXJnZXQgPSB0b1Jhdyh0aGlzKTsNCiAgICAgICAgY29uc3QgcHJvdG8gPSBnZXRQcm90byh0YXJnZXQpOw0KICAgICAgICBjb25zdCBoYWRLZXkgPSBwcm90by5oYXMuY2FsbCh0YXJnZXQsIHZhbHVlKTsNCiAgICAgICAgaWYgKCFoYWRLZXkpIHsNCiAgICAgICAgICB0YXJnZXQuYWRkKHZhbHVlKTsNCiAgICAgICAgICB0cmlnZ2VyKHRhcmdldCwgImFkZCIsIHZhbHVlLCB2YWx1ZSk7DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIHRoaXM7DQogICAgICB9LA0KICAgICAgc2V0KGtleSwgdmFsdWUpIHsNCiAgICAgICAgaWYgKCFzaGFsbG93ICYmICFpc1NoYWxsb3codmFsdWUpICYmICFpc1JlYWRvbmx5KHZhbHVlKSkgew0KICAgICAgICAgIHZhbHVlID0gdG9SYXcodmFsdWUpOw0KICAgICAgICB9DQogICAgICAgIGNvbnN0IHRhcmdldCA9IHRvUmF3KHRoaXMpOw0KICAgICAgICBjb25zdCB7IGhhcywgZ2V0IH0gPSBnZXRQcm90byh0YXJnZXQpOw0KICAgICAgICBsZXQgaGFkS2V5ID0gaGFzLmNhbGwodGFyZ2V0LCBrZXkpOw0KICAgICAgICBpZiAoIWhhZEtleSkgew0KICAgICAgICAgIGtleSA9IHRvUmF3KGtleSk7DQogICAgICAgICAgaGFkS2V5ID0gaGFzLmNhbGwodGFyZ2V0LCBrZXkpOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIGNoZWNrSWRlbnRpdHlLZXlzKHRhcmdldCwgaGFzLCBrZXkpOw0KICAgICAgICB9DQogICAgICAgIGNvbnN0IG9sZFZhbHVlID0gZ2V0LmNhbGwodGFyZ2V0LCBrZXkpOw0KICAgICAgICB0YXJnZXQuc2V0KGtleSwgdmFsdWUpOw0KICAgICAgICBpZiAoIWhhZEtleSkgew0KICAgICAgICAgIHRyaWdnZXIodGFyZ2V0LCAiYWRkIiwga2V5LCB2YWx1ZSk7DQogICAgICAgIH0gZWxzZSBpZiAoaGFzQ2hhbmdlZCh2YWx1ZSwgb2xkVmFsdWUpKSB7DQogICAgICAgICAgdHJpZ2dlcih0YXJnZXQsICJzZXQiLCBrZXksIHZhbHVlLCBvbGRWYWx1ZSk7DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIHRoaXM7DQogICAgICB9LA0KICAgICAgZGVsZXRlKGtleSkgew0KICAgICAgICBjb25zdCB0YXJnZXQgPSB0b1Jhdyh0aGlzKTsNCiAgICAgICAgY29uc3QgeyBoYXMsIGdldCB9ID0gZ2V0UHJvdG8odGFyZ2V0KTsNCiAgICAgICAgbGV0IGhhZEtleSA9IGhhcy5jYWxsKHRhcmdldCwga2V5KTsNCiAgICAgICAgaWYgKCFoYWRLZXkpIHsNCiAgICAgICAgICBrZXkgPSB0b1JhdyhrZXkpOw0KICAgICAgICAgIGhhZEtleSA9IGhhcy5jYWxsKHRhcmdldCwga2V5KTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBjaGVja0lkZW50aXR5S2V5cyh0YXJnZXQsIGhhcywga2V5KTsNCiAgICAgICAgfQ0KICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IGdldCA/IGdldC5jYWxsKHRhcmdldCwga2V5KSA6IHZvaWQgMDsNCiAgICAgICAgY29uc3QgcmVzdWx0ID0gdGFyZ2V0LmRlbGV0ZShrZXkpOw0KICAgICAgICBpZiAoaGFkS2V5KSB7DQogICAgICAgICAgdHJpZ2dlcih0YXJnZXQsICJkZWxldGUiLCBrZXksIHZvaWQgMCwgb2xkVmFsdWUpOw0KICAgICAgICB9DQogICAgICAgIHJldHVybiByZXN1bHQ7DQogICAgICB9LA0KICAgICAgY2xlYXIoKSB7DQogICAgICAgIGNvbnN0IHRhcmdldCA9IHRvUmF3KHRoaXMpOw0KICAgICAgICBjb25zdCBoYWRJdGVtcyA9IHRhcmdldC5zaXplICE9PSAwOw0KICAgICAgICBjb25zdCBvbGRUYXJnZXQgPSBpc01hcCh0YXJnZXQpID8gbmV3IE1hcCh0YXJnZXQpIDogbmV3IFNldCh0YXJnZXQpIDsNCiAgICAgICAgY29uc3QgcmVzdWx0ID0gdGFyZ2V0LmNsZWFyKCk7DQogICAgICAgIGlmIChoYWRJdGVtcykgew0KICAgICAgICAgIHRyaWdnZXIoDQogICAgICAgICAgICB0YXJnZXQsDQogICAgICAgICAgICAiY2xlYXIiLA0KICAgICAgICAgICAgdm9pZCAwLA0KICAgICAgICAgICAgdm9pZCAwLA0KICAgICAgICAgICAgb2xkVGFyZ2V0DQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgICByZXR1cm4gcmVzdWx0Ow0KICAgICAgfQ0KICAgIH0NCiAgKTsNCiAgY29uc3QgaXRlcmF0b3JNZXRob2RzID0gWw0KICAgICJrZXlzIiwNCiAgICAidmFsdWVzIiwNCiAgICAiZW50cmllcyIsDQogICAgU3ltYm9sLml0ZXJhdG9yDQogIF07DQogIGl0ZXJhdG9yTWV0aG9kcy5mb3JFYWNoKChtZXRob2QpID0+IHsNCiAgICBpbnN0cnVtZW50YXRpb25zW21ldGhvZF0gPSBjcmVhdGVJdGVyYWJsZU1ldGhvZChtZXRob2QsIHJlYWRvbmx5LCBzaGFsbG93KTsNCiAgfSk7DQogIHJldHVybiBpbnN0cnVtZW50YXRpb25zOw0KfQ0KZnVuY3Rpb24gY3JlYXRlSW5zdHJ1bWVudGF0aW9uR2V0dGVyKGlzUmVhZG9ubHkyLCBzaGFsbG93KSB7DQogIGNvbnN0IGluc3RydW1lbnRhdGlvbnMgPSBjcmVhdGVJbnN0cnVtZW50YXRpb25zKGlzUmVhZG9ubHkyLCBzaGFsbG93KTsNCiAgcmV0dXJuICh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpID0+IHsNCiAgICBpZiAoa2V5ID09PSAiX192X2lzUmVhY3RpdmUiKSB7DQogICAgICByZXR1cm4gIWlzUmVhZG9ubHkyOw0KICAgIH0gZWxzZSBpZiAoa2V5ID09PSAiX192X2lzUmVhZG9ubHkiKSB7DQogICAgICByZXR1cm4gaXNSZWFkb25seTI7DQogICAgfSBlbHNlIGlmIChrZXkgPT09ICJfX3ZfcmF3Iikgew0KICAgICAgcmV0dXJuIHRhcmdldDsNCiAgICB9DQogICAgcmV0dXJuIFJlZmxlY3QuZ2V0KA0KICAgICAgaGFzT3duKGluc3RydW1lbnRhdGlvbnMsIGtleSkgJiYga2V5IGluIHRhcmdldCA/IGluc3RydW1lbnRhdGlvbnMgOiB0YXJnZXQsDQogICAgICBrZXksDQogICAgICByZWNlaXZlcg0KICAgICk7DQogIH07DQp9DQpjb25zdCBtdXRhYmxlQ29sbGVjdGlvbkhhbmRsZXJzID0gew0KICBnZXQ6IC8qIEBfX1BVUkVfXyAqLyBjcmVhdGVJbnN0cnVtZW50YXRpb25HZXR0ZXIoZmFsc2UsIGZhbHNlKQ0KfTsNCmNvbnN0IHNoYWxsb3dDb2xsZWN0aW9uSGFuZGxlcnMgPSB7DQogIGdldDogLyogQF9fUFVSRV9fICovIGNyZWF0ZUluc3RydW1lbnRhdGlvbkdldHRlcihmYWxzZSwgdHJ1ZSkNCn07DQpjb25zdCByZWFkb25seUNvbGxlY3Rpb25IYW5kbGVycyA9IHsNCiAgZ2V0OiAvKiBAX19QVVJFX18gKi8gY3JlYXRlSW5zdHJ1bWVudGF0aW9uR2V0dGVyKHRydWUsIGZhbHNlKQ0KfTsNCmNvbnN0IHNoYWxsb3dSZWFkb25seUNvbGxlY3Rpb25IYW5kbGVycyA9IHsNCiAgZ2V0OiAvKiBAX19QVVJFX18gKi8gY3JlYXRlSW5zdHJ1bWVudGF0aW9uR2V0dGVyKHRydWUsIHRydWUpDQp9Ow0KZnVuY3Rpb24gY2hlY2tJZGVudGl0eUtleXModGFyZ2V0LCBoYXMsIGtleSkgew0KICBjb25zdCByYXdLZXkgPSB0b1JhdyhrZXkpOw0KICBpZiAocmF3S2V5ICE9PSBrZXkgJiYgaGFzLmNhbGwodGFyZ2V0LCByYXdLZXkpKSB7DQogICAgY29uc3QgdHlwZSA9IHRvUmF3VHlwZSh0YXJnZXQpOw0KICAgIHdhcm4kMigNCiAgICAgIGBSZWFjdGl2ZSAke3R5cGV9IGNvbnRhaW5zIGJvdGggdGhlIHJhdyBhbmQgcmVhY3RpdmUgdmVyc2lvbnMgb2YgdGhlIHNhbWUgb2JqZWN0JHt0eXBlID09PSBgTWFwYCA/IGAgYXMga2V5c2AgOiBgYH0sIHdoaWNoIGNhbiBsZWFkIHRvIGluY29uc2lzdGVuY2llcy4gQXZvaWQgZGlmZmVyZW50aWF0aW5nIGJldHdlZW4gdGhlIHJhdyBhbmQgcmVhY3RpdmUgdmVyc2lvbnMgb2YgYW4gb2JqZWN0IGFuZCBvbmx5IHVzZSB0aGUgcmVhY3RpdmUgdmVyc2lvbiBpZiBwb3NzaWJsZS5gDQogICAgKTsNCiAgfQ0KfQ0KDQpjb25zdCByZWFjdGl2ZU1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgV2Vha01hcCgpOw0KY29uc3Qgc2hhbGxvd1JlYWN0aXZlTWFwID0gLyogQF9fUFVSRV9fICovIG5ldyBXZWFrTWFwKCk7DQpjb25zdCByZWFkb25seU1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgV2Vha01hcCgpOw0KY29uc3Qgc2hhbGxvd1JlYWRvbmx5TWFwID0gLyogQF9fUFVSRV9fICovIG5ldyBXZWFrTWFwKCk7DQpmdW5jdGlvbiB0YXJnZXRUeXBlTWFwKHJhd1R5cGUpIHsNCiAgc3dpdGNoIChyYXdUeXBlKSB7DQogICAgY2FzZSAiT2JqZWN0IjoNCiAgICBjYXNlICJBcnJheSI6DQogICAgICByZXR1cm4gMSAvKiBDT01NT04gKi87DQogICAgY2FzZSAiTWFwIjoNCiAgICBjYXNlICJTZXQiOg0KICAgIGNhc2UgIldlYWtNYXAiOg0KICAgIGNhc2UgIldlYWtTZXQiOg0KICAgICAgcmV0dXJuIDIgLyogQ09MTEVDVElPTiAqLzsNCiAgICBkZWZhdWx0Og0KICAgICAgcmV0dXJuIDAgLyogSU5WQUxJRCAqLzsNCiAgfQ0KfQ0KZnVuY3Rpb24gZ2V0VGFyZ2V0VHlwZSh2YWx1ZSkgew0KICByZXR1cm4gdmFsdWVbIl9fdl9za2lwIl0gfHwgIU9iamVjdC5pc0V4dGVuc2libGUodmFsdWUpID8gMCAvKiBJTlZBTElEICovIDogdGFyZ2V0VHlwZU1hcCh0b1Jhd1R5cGUodmFsdWUpKTsNCn0NCmZ1bmN0aW9uIHJlYWN0aXZlKHRhcmdldCkgew0KICBpZiAoaXNSZWFkb25seSh0YXJnZXQpKSB7DQogICAgcmV0dXJuIHRhcmdldDsNCiAgfQ0KICByZXR1cm4gY3JlYXRlUmVhY3RpdmVPYmplY3QoDQogICAgdGFyZ2V0LA0KICAgIGZhbHNlLA0KICAgIG11dGFibGVIYW5kbGVycywNCiAgICBtdXRhYmxlQ29sbGVjdGlvbkhhbmRsZXJzLA0KICAgIHJlYWN0aXZlTWFwDQogICk7DQp9DQpmdW5jdGlvbiBzaGFsbG93UmVhY3RpdmUodGFyZ2V0KSB7DQogIHJldHVybiBjcmVhdGVSZWFjdGl2ZU9iamVjdCgNCiAgICB0YXJnZXQsDQogICAgZmFsc2UsDQogICAgc2hhbGxvd1JlYWN0aXZlSGFuZGxlcnMsDQogICAgc2hhbGxvd0NvbGxlY3Rpb25IYW5kbGVycywNCiAgICBzaGFsbG93UmVhY3RpdmVNYXANCiAgKTsNCn0NCmZ1bmN0aW9uIHJlYWRvbmx5KHRhcmdldCkgew0KICByZXR1cm4gY3JlYXRlUmVhY3RpdmVPYmplY3QoDQogICAgdGFyZ2V0LA0KICAgIHRydWUsDQogICAgcmVhZG9ubHlIYW5kbGVycywNCiAgICByZWFkb25seUNvbGxlY3Rpb25IYW5kbGVycywNCiAgICByZWFkb25seU1hcA0KICApOw0KfQ0KZnVuY3Rpb24gc2hhbGxvd1JlYWRvbmx5KHRhcmdldCkgew0KICByZXR1cm4gY3JlYXRlUmVhY3RpdmVPYmplY3QoDQogICAgdGFyZ2V0LA0KICAgIHRydWUsDQogICAgc2hhbGxvd1JlYWRvbmx5SGFuZGxlcnMsDQogICAgc2hhbGxvd1JlYWRvbmx5Q29sbGVjdGlvbkhhbmRsZXJzLA0KICAgIHNoYWxsb3dSZWFkb25seU1hcA0KICApOw0KfQ0KZnVuY3Rpb24gY3JlYXRlUmVhY3RpdmVPYmplY3QodGFyZ2V0LCBpc1JlYWRvbmx5MiwgYmFzZUhhbmRsZXJzLCBjb2xsZWN0aW9uSGFuZGxlcnMsIHByb3h5TWFwKSB7DQogIGlmICghaXNPYmplY3QodGFyZ2V0KSkgew0KICAgIHsNCiAgICAgIHdhcm4kMigNCiAgICAgICAgYHZhbHVlIGNhbm5vdCBiZSBtYWRlICR7aXNSZWFkb25seTIgPyAicmVhZG9ubHkiIDogInJlYWN0aXZlIn06ICR7U3RyaW5nKA0KICAgICAgICAgIHRhcmdldA0KICAgICAgICApfWANCiAgICAgICk7DQogICAgfQ0KICAgIHJldHVybiB0YXJnZXQ7DQogIH0NCiAgaWYgKHRhcmdldFsiX192X3JhdyJdICYmICEoaXNSZWFkb25seTIgJiYgdGFyZ2V0WyJfX3ZfaXNSZWFjdGl2ZSJdKSkgew0KICAgIHJldHVybiB0YXJnZXQ7DQogIH0NCiAgY29uc3QgdGFyZ2V0VHlwZSA9IGdldFRhcmdldFR5cGUodGFyZ2V0KTsNCiAgaWYgKHRhcmdldFR5cGUgPT09IDAgLyogSU5WQUxJRCAqLykgew0KICAgIHJldHVybiB0YXJnZXQ7DQogIH0NCiAgY29uc3QgZXhpc3RpbmdQcm94eSA9IHByb3h5TWFwLmdldCh0YXJnZXQpOw0KICBpZiAoZXhpc3RpbmdQcm94eSkgew0KICAgIHJldHVybiBleGlzdGluZ1Byb3h5Ow0KICB9DQogIGNvbnN0IHByb3h5ID0gbmV3IFByb3h5KA0KICAgIHRhcmdldCwNCiAgICB0YXJnZXRUeXBlID09PSAyIC8qIENPTExFQ1RJT04gKi8gPyBjb2xsZWN0aW9uSGFuZGxlcnMgOiBiYXNlSGFuZGxlcnMNCiAgKTsNCiAgcHJveHlNYXAuc2V0KHRhcmdldCwgcHJveHkpOw0KICByZXR1cm4gcHJveHk7DQp9DQpmdW5jdGlvbiBpc1JlYWN0aXZlKHZhbHVlKSB7DQogIGlmIChpc1JlYWRvbmx5KHZhbHVlKSkgew0KICAgIHJldHVybiBpc1JlYWN0aXZlKHZhbHVlWyJfX3ZfcmF3Il0pOw0KICB9DQogIHJldHVybiAhISh2YWx1ZSAmJiB2YWx1ZVsiX192X2lzUmVhY3RpdmUiXSk7DQp9DQpmdW5jdGlvbiBpc1JlYWRvbmx5KHZhbHVlKSB7DQogIHJldHVybiAhISh2YWx1ZSAmJiB2YWx1ZVsiX192X2lzUmVhZG9ubHkiXSk7DQp9DQpmdW5jdGlvbiBpc1NoYWxsb3codmFsdWUpIHsNCiAgcmV0dXJuICEhKHZhbHVlICYmIHZhbHVlWyJfX3ZfaXNTaGFsbG93Il0pOw0KfQ0KZnVuY3Rpb24gaXNQcm94eSh2YWx1ZSkgew0KICByZXR1cm4gdmFsdWUgPyAhIXZhbHVlWyJfX3ZfcmF3Il0gOiBmYWxzZTsNCn0NCmZ1bmN0aW9uIHRvUmF3KG9ic2VydmVkKSB7DQogIGNvbnN0IHJhdyA9IG9ic2VydmVkICYmIG9ic2VydmVkWyJfX3ZfcmF3Il07DQogIHJldHVybiByYXcgPyB0b1JhdyhyYXcpIDogb2JzZXJ2ZWQ7DQp9DQpmdW5jdGlvbiBtYXJrUmF3KHZhbHVlKSB7DQogIGlmICghaGFzT3duKHZhbHVlLCAiX192X3NraXAiKSAmJiBPYmplY3QuaXNFeHRlbnNpYmxlKHZhbHVlKSkgew0KICAgIGRlZih2YWx1ZSwgIl9fdl9za2lwIiwgdHJ1ZSk7DQogIH0NCiAgcmV0dXJuIHZhbHVlOw0KfQ0KY29uc3QgdG9SZWFjdGl2ZSA9ICh2YWx1ZSkgPT4gaXNPYmplY3QodmFsdWUpID8gcmVhY3RpdmUodmFsdWUpIDogdmFsdWU7DQpjb25zdCB0b1JlYWRvbmx5ID0gKHZhbHVlKSA9PiBpc09iamVjdCh2YWx1ZSkgPyByZWFkb25seSh2YWx1ZSkgOiB2YWx1ZTsNCg0KZnVuY3Rpb24gaXNSZWYocikgew0KICByZXR1cm4gciA/IHJbIl9fdl9pc1JlZiJdID09PSB0cnVlIDogZmFsc2U7DQp9DQpmdW5jdGlvbiB1bnJlZihyZWYyKSB7DQogIHJldHVybiBpc1JlZihyZWYyKSA/IHJlZjIudmFsdWUgOiByZWYyOw0KfQ0KY29uc3Qgc2hhbGxvd1Vud3JhcEhhbmRsZXJzID0gew0KICBnZXQ6ICh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpID0+IGtleSA9PT0gIl9fdl9yYXciID8gdGFyZ2V0IDogdW5yZWYoUmVmbGVjdC5nZXQodGFyZ2V0LCBrZXksIHJlY2VpdmVyKSksDQogIHNldDogKHRhcmdldCwga2V5LCB2YWx1ZSwgcmVjZWl2ZXIpID0+IHsNCiAgICBjb25zdCBvbGRWYWx1ZSA9IHRhcmdldFtrZXldOw0KICAgIGlmIChpc1JlZihvbGRWYWx1ZSkgJiYgIWlzUmVmKHZhbHVlKSkgew0KICAgICAgb2xkVmFsdWUudmFsdWUgPSB2YWx1ZTsNCiAgICAgIHJldHVybiB0cnVlOw0KICAgIH0gZWxzZSB7DQogICAgICByZXR1cm4gUmVmbGVjdC5zZXQodGFyZ2V0LCBrZXksIHZhbHVlLCByZWNlaXZlcik7DQogICAgfQ0KICB9DQp9Ow0KZnVuY3Rpb24gcHJveHlSZWZzKG9iamVjdFdpdGhSZWZzKSB7DQogIHJldHVybiBpc1JlYWN0aXZlKG9iamVjdFdpdGhSZWZzKSA/IG9iamVjdFdpdGhSZWZzIDogbmV3IFByb3h5KG9iamVjdFdpdGhSZWZzLCBzaGFsbG93VW53cmFwSGFuZGxlcnMpOw0KfQ0KDQpjbGFzcyBDb21wdXRlZFJlZkltcGwgew0KICBjb25zdHJ1Y3Rvcihmbiwgc2V0dGVyLCBpc1NTUikgew0KICAgIHRoaXMuZm4gPSBmbjsNCiAgICB0aGlzLnNldHRlciA9IHNldHRlcjsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLl92YWx1ZSA9IHZvaWQgMDsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLmRlcCA9IG5ldyBEZXAodGhpcyk7DQogICAgLyoqDQogICAgICogQGludGVybmFsDQogICAgICovDQogICAgdGhpcy5fX3ZfaXNSZWYgPSB0cnVlOw0KICAgIC8vIFRPRE8gaXNvbGF0ZWREZWNsYXJhdGlvbnMgIl9fdl9pc1JlYWRvbmx5Ig0KICAgIC8vIEEgY29tcHV0ZWQgaXMgYWxzbyBhIHN1YnNjcmliZXIgdGhhdCB0cmFja3Mgb3RoZXIgZGVwcw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuZGVwcyA9IHZvaWQgMDsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLmRlcHNUYWlsID0gdm9pZCAwOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuZmxhZ3MgPSAxNjsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLmdsb2JhbFZlcnNpb24gPSBnbG9iYWxWZXJzaW9uIC0gMTsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLm5leHQgPSB2b2lkIDA7DQogICAgLy8gZm9yIGJhY2t3YXJkcyBjb21wYXQNCiAgICB0aGlzLmVmZmVjdCA9IHRoaXM7DQogICAgdGhpc1siX192X2lzUmVhZG9ubHkiXSA9ICFzZXR0ZXI7DQogICAgdGhpcy5pc1NTUiA9IGlzU1NSOw0KICB9DQogIC8qKg0KICAgKiBAaW50ZXJuYWwNCiAgICovDQogIG5vdGlmeSgpIHsNCiAgICB0aGlzLmZsYWdzIHw9IDE2Ow0KICAgIGlmICghKHRoaXMuZmxhZ3MgJiA4KSAmJiAvLyBhdm9pZCBpbmZpbml0ZSBzZWxmIHJlY3Vyc2lvbg0KICAgIGFjdGl2ZVN1YiAhPT0gdGhpcykgew0KICAgICAgYmF0Y2godGhpcywgdHJ1ZSk7DQogICAgICByZXR1cm4gdHJ1ZTsNCiAgICB9DQogIH0NCiAgZ2V0IHZhbHVlKCkgew0KICAgIGNvbnN0IGxpbmsgPSB0aGlzLmRlcC50cmFjayh7DQogICAgICB0YXJnZXQ6IHRoaXMsDQogICAgICB0eXBlOiAiZ2V0IiwNCiAgICAgIGtleTogInZhbHVlIg0KICAgIH0pIDsNCiAgICByZWZyZXNoQ29tcHV0ZWQodGhpcyk7DQogICAgaWYgKGxpbmspIHsNCiAgICAgIGxpbmsudmVyc2lvbiA9IHRoaXMuZGVwLnZlcnNpb247DQogICAgfQ0KICAgIHJldHVybiB0aGlzLl92YWx1ZTsNCiAgfQ0KICBzZXQgdmFsdWUobmV3VmFsdWUpIHsNCiAgICBpZiAodGhpcy5zZXR0ZXIpIHsNCiAgICAgIHRoaXMuc2V0dGVyKG5ld1ZhbHVlKTsNCiAgICB9IGVsc2Ugew0KICAgICAgd2FybiQyKCJXcml0ZSBvcGVyYXRpb24gZmFpbGVkOiBjb21wdXRlZCB2YWx1ZSBpcyByZWFkb25seSIpOw0KICAgIH0NCiAgfQ0KfQ0KZnVuY3Rpb24gY29tcHV0ZWQkMShnZXR0ZXJPck9wdGlvbnMsIGRlYnVnT3B0aW9ucywgaXNTU1IgPSBmYWxzZSkgew0KICBsZXQgZ2V0dGVyOw0KICBsZXQgc2V0dGVyOw0KICBpZiAoaXNGdW5jdGlvbihnZXR0ZXJPck9wdGlvbnMpKSB7DQogICAgZ2V0dGVyID0gZ2V0dGVyT3JPcHRpb25zOw0KICB9IGVsc2Ugew0KICAgIGdldHRlciA9IGdldHRlck9yT3B0aW9ucy5nZXQ7DQogICAgc2V0dGVyID0gZ2V0dGVyT3JPcHRpb25zLnNldDsNCiAgfQ0KICBjb25zdCBjUmVmID0gbmV3IENvbXB1dGVkUmVmSW1wbChnZXR0ZXIsIHNldHRlciwgaXNTU1IpOw0KICByZXR1cm4gY1JlZjsNCn0NCg0KY29uc3QgSU5JVElBTF9XQVRDSEVSX1ZBTFVFID0ge307DQpjb25zdCBjbGVhbnVwTWFwID0gLyogQF9fUFVSRV9fICovIG5ldyBXZWFrTWFwKCk7DQpsZXQgYWN0aXZlV2F0Y2hlciA9IHZvaWQgMDsNCmZ1bmN0aW9uIG9uV2F0Y2hlckNsZWFudXAoY2xlYW51cEZuLCBmYWlsU2lsZW50bHkgPSBmYWxzZSwgb3duZXIgPSBhY3RpdmVXYXRjaGVyKSB7DQogIGlmIChvd25lcikgew0KICAgIGxldCBjbGVhbnVwcyA9IGNsZWFudXBNYXAuZ2V0KG93bmVyKTsNCiAgICBpZiAoIWNsZWFudXBzKSBjbGVhbnVwTWFwLnNldChvd25lciwgY2xlYW51cHMgPSBbXSk7DQogICAgY2xlYW51cHMucHVzaChjbGVhbnVwRm4pOw0KICB9IGVsc2UgaWYgKCFmYWlsU2lsZW50bHkpIHsNCiAgICB3YXJuJDIoDQogICAgICBgb25XYXRjaGVyQ2xlYW51cCgpIHdhcyBjYWxsZWQgd2hlbiB0aGVyZSB3YXMgbm8gYWN0aXZlIHdhdGNoZXIgdG8gYXNzb2NpYXRlIHdpdGguYA0KICAgICk7DQogIH0NCn0NCmZ1bmN0aW9uIHdhdGNoJDEoc291cmNlLCBjYiwgb3B0aW9ucyA9IEVNUFRZX09CSikgew0KICBjb25zdCB7IGltbWVkaWF0ZSwgZGVlcCwgb25jZSwgc2NoZWR1bGVyLCBhdWdtZW50Sm9iLCBjYWxsIH0gPSBvcHRpb25zOw0KICBjb25zdCB3YXJuSW52YWxpZFNvdXJjZSA9IChzKSA9PiB7DQogICAgKG9wdGlvbnMub25XYXJuIHx8IHdhcm4kMikoDQogICAgICBgSW52YWxpZCB3YXRjaCBzb3VyY2U6IGAsDQogICAgICBzLA0KICAgICAgYEEgd2F0Y2ggc291cmNlIGNhbiBvbmx5IGJlIGEgZ2V0dGVyL2VmZmVjdCBmdW5jdGlvbiwgYSByZWYsIGEgcmVhY3RpdmUgb2JqZWN0LCBvciBhbiBhcnJheSBvZiB0aGVzZSB0eXBlcy5gDQogICAgKTsNCiAgfTsNCiAgY29uc3QgcmVhY3RpdmVHZXR0ZXIgPSAoc291cmNlMikgPT4gew0KICAgIGlmIChkZWVwKSByZXR1cm4gc291cmNlMjsNCiAgICBpZiAoaXNTaGFsbG93KHNvdXJjZTIpIHx8IGRlZXAgPT09IGZhbHNlIHx8IGRlZXAgPT09IDApDQogICAgICByZXR1cm4gdHJhdmVyc2Uoc291cmNlMiwgMSk7DQogICAgcmV0dXJuIHRyYXZlcnNlKHNvdXJjZTIpOw0KICB9Ow0KICBsZXQgZWZmZWN0Ow0KICBsZXQgZ2V0dGVyOw0KICBsZXQgY2xlYW51cDsNCiAgbGV0IGJvdW5kQ2xlYW51cDsNCiAgbGV0IGZvcmNlVHJpZ2dlciA9IGZhbHNlOw0KICBsZXQgaXNNdWx0aVNvdXJjZSA9IGZhbHNlOw0KICBpZiAoaXNSZWYoc291cmNlKSkgew0KICAgIGdldHRlciA9ICgpID0+IHNvdXJjZS52YWx1ZTsNCiAgICBmb3JjZVRyaWdnZXIgPSBpc1NoYWxsb3coc291cmNlKTsNCiAgfSBlbHNlIGlmIChpc1JlYWN0aXZlKHNvdXJjZSkpIHsNCiAgICBnZXR0ZXIgPSAoKSA9PiByZWFjdGl2ZUdldHRlcihzb3VyY2UpOw0KICAgIGZvcmNlVHJpZ2dlciA9IHRydWU7DQogIH0gZWxzZSBpZiAoaXNBcnJheShzb3VyY2UpKSB7DQogICAgaXNNdWx0aVNvdXJjZSA9IHRydWU7DQogICAgZm9yY2VUcmlnZ2VyID0gc291cmNlLnNvbWUoKHMpID0+IGlzUmVhY3RpdmUocykgfHwgaXNTaGFsbG93KHMpKTsNCiAgICBnZXR0ZXIgPSAoKSA9PiBzb3VyY2UubWFwKChzKSA9PiB7DQogICAgICBpZiAoaXNSZWYocykpIHsNCiAgICAgICAgcmV0dXJuIHMudmFsdWU7DQogICAgICB9IGVsc2UgaWYgKGlzUmVhY3RpdmUocykpIHsNCiAgICAgICAgcmV0dXJuIHJlYWN0aXZlR2V0dGVyKHMpOw0KICAgICAgfSBlbHNlIGlmIChpc0Z1bmN0aW9uKHMpKSB7DQogICAgICAgIHJldHVybiBjYWxsID8gY2FsbChzLCAyKSA6IHMoKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHdhcm5JbnZhbGlkU291cmNlKHMpOw0KICAgICAgfQ0KICAgIH0pOw0KICB9IGVsc2UgaWYgKGlzRnVuY3Rpb24oc291cmNlKSkgew0KICAgIGlmIChjYikgew0KICAgICAgZ2V0dGVyID0gY2FsbCA/ICgpID0+IGNhbGwoc291cmNlLCAyKSA6IHNvdXJjZTsNCiAgICB9IGVsc2Ugew0KICAgICAgZ2V0dGVyID0gKCkgPT4gew0KICAgICAgICBpZiAoY2xlYW51cCkgew0KICAgICAgICAgIHBhdXNlVHJhY2tpbmcoKTsNCiAgICAgICAgICB0cnkgew0KICAgICAgICAgICAgY2xlYW51cCgpOw0KICAgICAgICAgIH0gZmluYWxseSB7DQogICAgICAgICAgICByZXNldFRyYWNraW5nKCk7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGNvbnN0IGN1cnJlbnRFZmZlY3QgPSBhY3RpdmVXYXRjaGVyOw0KICAgICAgICBhY3RpdmVXYXRjaGVyID0gZWZmZWN0Ow0KICAgICAgICB0cnkgew0KICAgICAgICAgIHJldHVybiBjYWxsID8gY2FsbChzb3VyY2UsIDMsIFtib3VuZENsZWFudXBdKSA6IHNvdXJjZShib3VuZENsZWFudXApOw0KICAgICAgICB9IGZpbmFsbHkgew0KICAgICAgICAgIGFjdGl2ZVdhdGNoZXIgPSBjdXJyZW50RWZmZWN0Ow0KICAgICAgICB9DQogICAgICB9Ow0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICBnZXR0ZXIgPSBOT09QOw0KICAgIHdhcm5JbnZhbGlkU291cmNlKHNvdXJjZSk7DQogIH0NCiAgaWYgKGNiICYmIGRlZXApIHsNCiAgICBjb25zdCBiYXNlR2V0dGVyID0gZ2V0dGVyOw0KICAgIGNvbnN0IGRlcHRoID0gZGVlcCA9PT0gdHJ1ZSA/IEluZmluaXR5IDogZGVlcDsNCiAgICBnZXR0ZXIgPSAoKSA9PiB0cmF2ZXJzZShiYXNlR2V0dGVyKCksIGRlcHRoKTsNCiAgfQ0KICBjb25zdCBzY29wZSA9IGdldEN1cnJlbnRTY29wZSgpOw0KICBjb25zdCB3YXRjaEhhbmRsZSA9ICgpID0+IHsNCiAgICBlZmZlY3Quc3RvcCgpOw0KICAgIGlmIChzY29wZSAmJiBzY29wZS5hY3RpdmUpIHsNCiAgICAgIHJlbW92ZShzY29wZS5lZmZlY3RzLCBlZmZlY3QpOw0KICAgIH0NCiAgfTsNCiAgaWYgKG9uY2UgJiYgY2IpIHsNCiAgICBjb25zdCBfY2IgPSBjYjsNCiAgICBjYiA9ICguLi5hcmdzKSA9PiB7DQogICAgICBfY2IoLi4uYXJncyk7DQogICAgICB3YXRjaEhhbmRsZSgpOw0KICAgIH07DQogIH0NCiAgbGV0IG9sZFZhbHVlID0gaXNNdWx0aVNvdXJjZSA/IG5ldyBBcnJheShzb3VyY2UubGVuZ3RoKS5maWxsKElOSVRJQUxfV0FUQ0hFUl9WQUxVRSkgOiBJTklUSUFMX1dBVENIRVJfVkFMVUU7DQogIGNvbnN0IGpvYiA9IChpbW1lZGlhdGVGaXJzdFJ1bikgPT4gew0KICAgIGlmICghKGVmZmVjdC5mbGFncyAmIDEpIHx8ICFlZmZlY3QuZGlydHkgJiYgIWltbWVkaWF0ZUZpcnN0UnVuKSB7DQogICAgICByZXR1cm47DQogICAgfQ0KICAgIGlmIChjYikgew0KICAgICAgY29uc3QgbmV3VmFsdWUgPSBlZmZlY3QucnVuKCk7DQogICAgICBpZiAoZGVlcCB8fCBmb3JjZVRyaWdnZXIgfHwgKGlzTXVsdGlTb3VyY2UgPyBuZXdWYWx1ZS5zb21lKCh2LCBpKSA9PiBoYXNDaGFuZ2VkKHYsIG9sZFZhbHVlW2ldKSkgOiBoYXNDaGFuZ2VkKG5ld1ZhbHVlLCBvbGRWYWx1ZSkpKSB7DQogICAgICAgIGlmIChjbGVhbnVwKSB7DQogICAgICAgICAgY2xlYW51cCgpOw0KICAgICAgICB9DQogICAgICAgIGNvbnN0IGN1cnJlbnRXYXRjaGVyID0gYWN0aXZlV2F0Y2hlcjsNCiAgICAgICAgYWN0aXZlV2F0Y2hlciA9IGVmZmVjdDsNCiAgICAgICAgdHJ5IHsNCiAgICAgICAgICBjb25zdCBhcmdzID0gWw0KICAgICAgICAgICAgbmV3VmFsdWUsDQogICAgICAgICAgICAvLyBwYXNzIHVuZGVmaW5lZCBhcyB0aGUgb2xkIHZhbHVlIHdoZW4gaXQncyBjaGFuZ2VkIGZvciB0aGUgZmlyc3QgdGltZQ0KICAgICAgICAgICAgb2xkVmFsdWUgPT09IElOSVRJQUxfV0FUQ0hFUl9WQUxVRSA/IHZvaWQgMCA6IGlzTXVsdGlTb3VyY2UgJiYgb2xkVmFsdWVbMF0gPT09IElOSVRJQUxfV0FUQ0hFUl9WQUxVRSA/IFtdIDogb2xkVmFsdWUsDQogICAgICAgICAgICBib3VuZENsZWFudXANCiAgICAgICAgICBdOw0KICAgICAgICAgIG9sZFZhbHVlID0gbmV3VmFsdWU7DQogICAgICAgICAgY2FsbCA/IGNhbGwoY2IsIDMsIGFyZ3MpIDogKA0KICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvcg0KICAgICAgICAgICAgY2IoLi4uYXJncykNCiAgICAgICAgICApOw0KICAgICAgICB9IGZpbmFsbHkgew0KICAgICAgICAgIGFjdGl2ZVdhdGNoZXIgPSBjdXJyZW50V2F0Y2hlcjsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0gZWxzZSB7DQogICAgICBlZmZlY3QucnVuKCk7DQogICAgfQ0KICB9Ow0KICBpZiAoYXVnbWVudEpvYikgew0KICAgIGF1Z21lbnRKb2Ioam9iKTsNCiAgfQ0KICBlZmZlY3QgPSBuZXcgUmVhY3RpdmVFZmZlY3QoZ2V0dGVyKTsNCiAgZWZmZWN0LnNjaGVkdWxlciA9IHNjaGVkdWxlciA/ICgpID0+IHNjaGVkdWxlcihqb2IsIGZhbHNlKSA6IGpvYjsNCiAgYm91bmRDbGVhbnVwID0gKGZuKSA9PiBvbldhdGNoZXJDbGVhbnVwKGZuLCBmYWxzZSwgZWZmZWN0KTsNCiAgY2xlYW51cCA9IGVmZmVjdC5vblN0b3AgPSAoKSA9PiB7DQogICAgY29uc3QgY2xlYW51cHMgPSBjbGVhbnVwTWFwLmdldChlZmZlY3QpOw0KICAgIGlmIChjbGVhbnVwcykgew0KICAgICAgaWYgKGNhbGwpIHsNCiAgICAgICAgY2FsbChjbGVhbnVwcywgNCk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBmb3IgKGNvbnN0IGNsZWFudXAyIG9mIGNsZWFudXBzKSBjbGVhbnVwMigpOw0KICAgICAgfQ0KICAgICAgY2xlYW51cE1hcC5kZWxldGUoZWZmZWN0KTsNCiAgICB9DQogIH07DQogIHsNCiAgICBlZmZlY3Qub25UcmFjayA9IG9wdGlvbnMub25UcmFjazsNCiAgICBlZmZlY3Qub25UcmlnZ2VyID0gb3B0aW9ucy5vblRyaWdnZXI7DQogIH0NCiAgaWYgKGNiKSB7DQogICAgaWYgKGltbWVkaWF0ZSkgew0KICAgICAgam9iKHRydWUpOw0KICAgIH0gZWxzZSB7DQogICAgICBvbGRWYWx1ZSA9IGVmZmVjdC5ydW4oKTsNCiAgICB9DQogIH0gZWxzZSBpZiAoc2NoZWR1bGVyKSB7DQogICAgc2NoZWR1bGVyKGpvYi5iaW5kKG51bGwsIHRydWUpLCB0cnVlKTsNCiAgfSBlbHNlIHsNCiAgICBlZmZlY3QucnVuKCk7DQogIH0NCiAgd2F0Y2hIYW5kbGUucGF1c2UgPSBlZmZlY3QucGF1c2UuYmluZChlZmZlY3QpOw0KICB3YXRjaEhhbmRsZS5yZXN1bWUgPSBlZmZlY3QucmVzdW1lLmJpbmQoZWZmZWN0KTsNCiAgd2F0Y2hIYW5kbGUuc3RvcCA9IHdhdGNoSGFuZGxlOw0KICByZXR1cm4gd2F0Y2hIYW5kbGU7DQp9DQpmdW5jdGlvbiB0cmF2ZXJzZSh2YWx1ZSwgZGVwdGggPSBJbmZpbml0eSwgc2Vlbikgew0KICBpZiAoZGVwdGggPD0gMCB8fCAhaXNPYmplY3QodmFsdWUpIHx8IHZhbHVlWyJfX3Zfc2tpcCJdKSB7DQogICAgcmV0dXJuIHZhbHVlOw0KICB9DQogIHNlZW4gPSBzZWVuIHx8IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KCk7DQogIGlmIChzZWVuLmhhcyh2YWx1ZSkpIHsNCiAgICByZXR1cm4gdmFsdWU7DQogIH0NCiAgc2Vlbi5hZGQodmFsdWUpOw0KICBkZXB0aC0tOw0KICBpZiAoaXNSZWYodmFsdWUpKSB7DQogICAgdHJhdmVyc2UodmFsdWUudmFsdWUsIGRlcHRoLCBzZWVuKTsNCiAgfSBlbHNlIGlmIChpc0FycmF5KHZhbHVlKSkgew0KICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspIHsNCiAgICAgIHRyYXZlcnNlKHZhbHVlW2ldLCBkZXB0aCwgc2Vlbik7DQogICAgfQ0KICB9IGVsc2UgaWYgKGlzU2V0KHZhbHVlKSB8fCBpc01hcCh2YWx1ZSkpIHsNCiAgICB2YWx1ZS5mb3JFYWNoKCh2KSA9PiB7DQogICAgICB0cmF2ZXJzZSh2LCBkZXB0aCwgc2Vlbik7DQogICAgfSk7DQogIH0gZWxzZSBpZiAoaXNQbGFpbk9iamVjdCh2YWx1ZSkpIHsNCiAgICBmb3IgKGNvbnN0IGtleSBpbiB2YWx1ZSkgew0KICAgICAgdHJhdmVyc2UodmFsdWVba2V5XSwgZGVwdGgsIHNlZW4pOw0KICAgIH0NCiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHZhbHVlKSkgew0KICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbCh2YWx1ZSwga2V5KSkgew0KICAgICAgICB0cmF2ZXJzZSh2YWx1ZVtrZXldLCBkZXB0aCwgc2Vlbik7DQogICAgICB9DQogICAgfQ0KICB9DQogIHJldHVybiB2YWx1ZTsNCn0NCg0KY29uc3Qgc3RhY2sgPSBbXTsNCmZ1bmN0aW9uIHB1c2hXYXJuaW5nQ29udGV4dCQxKHZub2RlKSB7DQogIHN0YWNrLnB1c2godm5vZGUpOw0KfQ0KZnVuY3Rpb24gcG9wV2FybmluZ0NvbnRleHQkMSgpIHsNCiAgc3RhY2sucG9wKCk7DQp9DQpsZXQgaXNXYXJuaW5nID0gZmFsc2U7DQpmdW5jdGlvbiB3YXJuJDEobXNnLCAuLi5hcmdzKSB7DQogIGlmIChpc1dhcm5pbmcpIHJldHVybjsNCiAgaXNXYXJuaW5nID0gdHJ1ZTsNCiAgcGF1c2VUcmFja2luZygpOw0KICBjb25zdCBpbnN0YW5jZSA9IHN0YWNrLmxlbmd0aCA/IHN0YWNrW3N0YWNrLmxlbmd0aCAtIDFdLmNvbXBvbmVudCA6IG51bGw7DQogIGNvbnN0IGFwcFdhcm5IYW5kbGVyID0gaW5zdGFuY2UgJiYgaW5zdGFuY2UuYXBwQ29udGV4dC5jb25maWcud2FybkhhbmRsZXI7DQogIGNvbnN0IHRyYWNlID0gZ2V0Q29tcG9uZW50VHJhY2UoKTsNCiAgaWYgKGFwcFdhcm5IYW5kbGVyKSB7DQogICAgY2FsbFdpdGhFcnJvckhhbmRsaW5nKA0KICAgICAgYXBwV2FybkhhbmRsZXIsDQogICAgICBpbnN0YW5jZSwNCiAgICAgIDExLA0KICAgICAgWw0KICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXgNCiAgICAgICAgbXNnICsgYXJncy5tYXAoKGEpID0+IHsNCiAgICAgICAgICB2YXIgX2EsIF9iOw0KICAgICAgICAgIHJldHVybiAoX2IgPSAoX2EgPSBhLnRvU3RyaW5nKSA9PSBudWxsID8gdm9pZCAwIDogX2EuY2FsbChhKSkgIT0gbnVsbCA/IF9iIDogSlNPTi5zdHJpbmdpZnkoYSk7DQogICAgICAgIH0pLmpvaW4oIiIpLA0KICAgICAgICBpbnN0YW5jZSAmJiBpbnN0YW5jZS5wcm94eSwNCiAgICAgICAgdHJhY2UubWFwKA0KICAgICAgICAgICh7IHZub2RlIH0pID0+IGBhdCA8JHtmb3JtYXRDb21wb25lbnROYW1lKGluc3RhbmNlLCB2bm9kZS50eXBlKX0+YA0KICAgICAgICApLmpvaW4oIlxuIiksDQogICAgICAgIHRyYWNlDQogICAgICBdDQogICAgKTsNCiAgfSBlbHNlIHsNCiAgICBjb25zdCB3YXJuQXJncyA9IFtgW1Z1ZSB3YXJuXTogJHttc2d9YCwgLi4uYXJnc107DQogICAgaWYgKHRyYWNlLmxlbmd0aCAmJiAvLyBhdm9pZCBzcGFtbWluZyBjb25zb2xlIGR1cmluZyB0ZXN0cw0KICAgIHRydWUpIHsNCiAgICAgIHdhcm5BcmdzLnB1c2goYA0KYCwgLi4uZm9ybWF0VHJhY2UodHJhY2UpKTsNCiAgICB9DQogICAgY29uc29sZS53YXJuKC4uLndhcm5BcmdzKTsNCiAgfQ0KICByZXNldFRyYWNraW5nKCk7DQogIGlzV2FybmluZyA9IGZhbHNlOw0KfQ0KZnVuY3Rpb24gZ2V0Q29tcG9uZW50VHJhY2UoKSB7DQogIGxldCBjdXJyZW50Vk5vZGUgPSBzdGFja1tzdGFjay5sZW5ndGggLSAxXTsNCiAgaWYgKCFjdXJyZW50Vk5vZGUpIHsNCiAgICByZXR1cm4gW107DQogIH0NCiAgY29uc3Qgbm9ybWFsaXplZFN0YWNrID0gW107DQogIHdoaWxlIChjdXJyZW50Vk5vZGUpIHsNCiAgICBjb25zdCBsYXN0ID0gbm9ybWFsaXplZFN0YWNrWzBdOw0KICAgIGlmIChsYXN0ICYmIGxhc3Qudm5vZGUgPT09IGN1cnJlbnRWTm9kZSkgew0KICAgICAgbGFzdC5yZWN1cnNlQ291bnQrKzsNCiAgICB9IGVsc2Ugew0KICAgICAgbm9ybWFsaXplZFN0YWNrLnB1c2goew0KICAgICAgICB2bm9kZTogY3VycmVudFZOb2RlLA0KICAgICAgICByZWN1cnNlQ291bnQ6IDANCiAgICAgIH0pOw0KICAgIH0NCiAgICBjb25zdCBwYXJlbnRJbnN0YW5jZSA9IGN1cnJlbnRWTm9kZS5jb21wb25lbnQgJiYgY3VycmVudFZOb2RlLmNvbXBvbmVudC5wYXJlbnQ7DQogICAgY3VycmVudFZOb2RlID0gcGFyZW50SW5zdGFuY2UgJiYgcGFyZW50SW5zdGFuY2Uudm5vZGU7DQogIH0NCiAgcmV0dXJuIG5vcm1hbGl6ZWRTdGFjazsNCn0NCmZ1bmN0aW9uIGZvcm1hdFRyYWNlKHRyYWNlKSB7DQogIGNvbnN0IGxvZ3MgPSBbXTsNCiAgdHJhY2UuZm9yRWFjaCgoZW50cnksIGkpID0+IHsNCiAgICBsb2dzLnB1c2goLi4uaSA9PT0gMCA/IFtdIDogW2ANCmBdLCAuLi5mb3JtYXRUcmFjZUVudHJ5KGVudHJ5KSk7DQogIH0pOw0KICByZXR1cm4gbG9nczsNCn0NCmZ1bmN0aW9uIGZvcm1hdFRyYWNlRW50cnkoeyB2bm9kZSwgcmVjdXJzZUNvdW50IH0pIHsNCiAgY29uc3QgcG9zdGZpeCA9IHJlY3Vyc2VDb3VudCA+IDAgPyBgLi4uICgke3JlY3Vyc2VDb3VudH0gcmVjdXJzaXZlIGNhbGxzKWAgOiBgYDsNCiAgY29uc3QgaXNSb290ID0gdm5vZGUuY29tcG9uZW50ID8gdm5vZGUuY29tcG9uZW50LnBhcmVudCA9PSBudWxsIDogZmFsc2U7DQogIGNvbnN0IG9wZW4gPSBgIGF0IDwke2Zvcm1hdENvbXBvbmVudE5hbWUoDQogICAgdm5vZGUuY29tcG9uZW50LA0KICAgIHZub2RlLnR5cGUsDQogICAgaXNSb290DQogICl9YDsNCiAgY29uc3QgY2xvc2UgPSBgPmAgKyBwb3N0Zml4Ow0KICByZXR1cm4gdm5vZGUucHJvcHMgPyBbb3BlbiwgLi4uZm9ybWF0UHJvcHModm5vZGUucHJvcHMpLCBjbG9zZV0gOiBbb3BlbiArIGNsb3NlXTsNCn0NCmZ1bmN0aW9uIGZvcm1hdFByb3BzKHByb3BzKSB7DQogIGNvbnN0IHJlcyA9IFtdOw0KICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMocHJvcHMpOw0KICBrZXlzLnNsaWNlKDAsIDMpLmZvckVhY2goKGtleSkgPT4gew0KICAgIHJlcy5wdXNoKC4uLmZvcm1hdFByb3Aoa2V5LCBwcm9wc1trZXldKSk7DQogIH0pOw0KICBpZiAoa2V5cy5sZW5ndGggPiAzKSB7DQogICAgcmVzLnB1c2goYCAuLi5gKTsNCiAgfQ0KICByZXR1cm4gcmVzOw0KfQ0KZnVuY3Rpb24gZm9ybWF0UHJvcChrZXksIHZhbHVlLCByYXcpIHsNCiAgaWYgKGlzU3RyaW5nKHZhbHVlKSkgew0KICAgIHZhbHVlID0gSlNPTi5zdHJpbmdpZnkodmFsdWUpOw0KICAgIHJldHVybiByYXcgPyB2YWx1ZSA6IFtgJHtrZXl9PSR7dmFsdWV9YF07DQogIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAibnVtYmVyIiB8fCB0eXBlb2YgdmFsdWUgPT09ICJib29sZWFuIiB8fCB2YWx1ZSA9PSBudWxsKSB7DQogICAgcmV0dXJuIHJhdyA/IHZhbHVlIDogW2Ake2tleX09JHt2YWx1ZX1gXTsNCiAgfSBlbHNlIGlmIChpc1JlZih2YWx1ZSkpIHsNCiAgICB2YWx1ZSA9IGZvcm1hdFByb3Aoa2V5LCB0b1Jhdyh2YWx1ZS52YWx1ZSksIHRydWUpOw0KICAgIHJldHVybiByYXcgPyB2YWx1ZSA6IFtgJHtrZXl9PVJlZjxgLCB2YWx1ZSwgYD5gXTsNCiAgfSBlbHNlIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkgew0KICAgIHJldHVybiBbYCR7a2V5fT1mbiR7dmFsdWUubmFtZSA/IGA8JHt2YWx1ZS5uYW1lfT5gIDogYGB9YF07DQogIH0gZWxzZSB7DQogICAgdmFsdWUgPSB0b1Jhdyh2YWx1ZSk7DQogICAgcmV0dXJuIHJhdyA/IHZhbHVlIDogW2Ake2tleX09YCwgdmFsdWVdOw0KICB9DQp9DQoNCmNvbnN0IEVycm9yVHlwZVN0cmluZ3MgPSB7DQogIFsic3AiXTogInNlcnZlclByZWZldGNoIGhvb2siLA0KICBbImJjIl06ICJiZWZvcmVDcmVhdGUgaG9vayIsDQogIFsiYyJdOiAiY3JlYXRlZCBob29rIiwNCiAgWyJibSJdOiAiYmVmb3JlTW91bnQgaG9vayIsDQogIFsibSJdOiAibW91bnRlZCBob29rIiwNCiAgWyJidSJdOiAiYmVmb3JlVXBkYXRlIGhvb2siLA0KICBbInUiXTogInVwZGF0ZWQiLA0KICBbImJ1bSJdOiAiYmVmb3JlVW5tb3VudCBob29rIiwNCiAgWyJ1bSJdOiAidW5tb3VudGVkIGhvb2siLA0KICBbImEiXTogImFjdGl2YXRlZCBob29rIiwNCiAgWyJkYSJdOiAiZGVhY3RpdmF0ZWQgaG9vayIsDQogIFsiZWMiXTogImVycm9yQ2FwdHVyZWQgaG9vayIsDQogIFsicnRjIl06ICJyZW5kZXJUcmFja2VkIGhvb2siLA0KICBbInJ0ZyJdOiAicmVuZGVyVHJpZ2dlcmVkIGhvb2siLA0KICBbMF06ICJzZXR1cCBmdW5jdGlvbiIsDQogIFsxXTogInJlbmRlciBmdW5jdGlvbiIsDQogIFsyXTogIndhdGNoZXIgZ2V0dGVyIiwNCiAgWzNdOiAid2F0Y2hlciBjYWxsYmFjayIsDQogIFs0XTogIndhdGNoZXIgY2xlYW51cCBmdW5jdGlvbiIsDQogIFs1XTogIm5hdGl2ZSBldmVudCBoYW5kbGVyIiwNCiAgWzZdOiAiY29tcG9uZW50IGV2ZW50IGhhbmRsZXIiLA0KICBbN106ICJ2bm9kZSBob29rIiwNCiAgWzhdOiAiZGlyZWN0aXZlIGhvb2siLA0KICBbOV06ICJ0cmFuc2l0aW9uIGhvb2siLA0KICBbMTBdOiAiYXBwIGVycm9ySGFuZGxlciIsDQogIFsxMV06ICJhcHAgd2FybkhhbmRsZXIiLA0KICBbMTJdOiAicmVmIGZ1bmN0aW9uIiwNCiAgWzEzXTogImFzeW5jIGNvbXBvbmVudCBsb2FkZXIiLA0KICBbMTRdOiAic2NoZWR1bGVyIGZsdXNoIiwNCiAgWzE1XTogImNvbXBvbmVudCB1cGRhdGUiLA0KICBbMTZdOiAiYXBwIHVubW91bnQgY2xlYW51cCBmdW5jdGlvbiINCn07DQpmdW5jdGlvbiBjYWxsV2l0aEVycm9ySGFuZGxpbmcoZm4sIGluc3RhbmNlLCB0eXBlLCBhcmdzKSB7DQogIHRyeSB7DQogICAgcmV0dXJuIGFyZ3MgPyBmbiguLi5hcmdzKSA6IGZuKCk7DQogIH0gY2F0Y2ggKGVycikgew0KICAgIGhhbmRsZUVycm9yKGVyciwgaW5zdGFuY2UsIHR5cGUpOw0KICB9DQp9DQpmdW5jdGlvbiBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZyhmbiwgaW5zdGFuY2UsIHR5cGUsIGFyZ3MpIHsNCiAgaWYgKGlzRnVuY3Rpb24oZm4pKSB7DQogICAgY29uc3QgcmVzID0gY2FsbFdpdGhFcnJvckhhbmRsaW5nKGZuLCBpbnN0YW5jZSwgdHlwZSwgYXJncyk7DQogICAgaWYgKHJlcyAmJiBpc1Byb21pc2UocmVzKSkgew0KICAgICAgcmVzLmNhdGNoKChlcnIpID0+IHsNCiAgICAgICAgaGFuZGxlRXJyb3IoZXJyLCBpbnN0YW5jZSwgdHlwZSk7DQogICAgICB9KTsNCiAgICB9DQogICAgcmV0dXJuIHJlczsNCiAgfQ0KICBpZiAoaXNBcnJheShmbikpIHsNCiAgICBjb25zdCB2YWx1ZXMgPSBbXTsNCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZuLmxlbmd0aDsgaSsrKSB7DQogICAgICB2YWx1ZXMucHVzaChjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZyhmbltpXSwgaW5zdGFuY2UsIHR5cGUsIGFyZ3MpKTsNCiAgICB9DQogICAgcmV0dXJuIHZhbHVlczsNCiAgfSBlbHNlIHsNCiAgICB3YXJuJDEoDQogICAgICBgSW52YWxpZCB2YWx1ZSB0eXBlIHBhc3NlZCB0byBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZygpOiAke3R5cGVvZiBmbn1gDQogICAgKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gaGFuZGxlRXJyb3IoZXJyLCBpbnN0YW5jZSwgdHlwZSwgdGhyb3dJbkRldiA9IHRydWUpIHsNCiAgY29uc3QgY29udGV4dFZOb2RlID0gaW5zdGFuY2UgPyBpbnN0YW5jZS52bm9kZSA6IG51bGw7DQogIGNvbnN0IHsgZXJyb3JIYW5kbGVyLCB0aHJvd1VuaGFuZGxlZEVycm9ySW5Qcm9kdWN0aW9uIH0gPSBpbnN0YW5jZSAmJiBpbnN0YW5jZS5hcHBDb250ZXh0LmNvbmZpZyB8fCBFTVBUWV9PQko7DQogIGlmIChpbnN0YW5jZSkgew0KICAgIGxldCBjdXIgPSBpbnN0YW5jZS5wYXJlbnQ7DQogICAgY29uc3QgZXhwb3NlZEluc3RhbmNlID0gaW5zdGFuY2UucHJveHk7DQogICAgY29uc3QgZXJyb3JJbmZvID0gRXJyb3JUeXBlU3RyaW5nc1t0eXBlXSA7DQogICAgd2hpbGUgKGN1cikgew0KICAgICAgY29uc3QgZXJyb3JDYXB0dXJlZEhvb2tzID0gY3VyLmVjOw0KICAgICAgaWYgKGVycm9yQ2FwdHVyZWRIb29rcykgew0KICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGVycm9yQ2FwdHVyZWRIb29rcy5sZW5ndGg7IGkrKykgew0KICAgICAgICAgIGlmIChlcnJvckNhcHR1cmVkSG9va3NbaV0oZXJyLCBleHBvc2VkSW5zdGFuY2UsIGVycm9ySW5mbykgPT09IGZhbHNlKSB7DQogICAgICAgICAgICByZXR1cm47DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICB9DQogICAgICBjdXIgPSBjdXIucGFyZW50Ow0KICAgIH0NCiAgICBpZiAoZXJyb3JIYW5kbGVyKSB7DQogICAgICBwYXVzZVRyYWNraW5nKCk7DQogICAgICBjYWxsV2l0aEVycm9ySGFuZGxpbmcoZXJyb3JIYW5kbGVyLCBudWxsLCAxMCwgWw0KICAgICAgICBlcnIsDQogICAgICAgIGV4cG9zZWRJbnN0YW5jZSwNCiAgICAgICAgZXJyb3JJbmZvDQogICAgICBdKTsNCiAgICAgIHJlc2V0VHJhY2tpbmcoKTsNCiAgICAgIHJldHVybjsNCiAgICB9DQogIH0NCiAgbG9nRXJyb3IoZXJyLCB0eXBlLCBjb250ZXh0Vk5vZGUsIHRocm93SW5EZXYsIHRocm93VW5oYW5kbGVkRXJyb3JJblByb2R1Y3Rpb24pOw0KfQ0KZnVuY3Rpb24gbG9nRXJyb3IoZXJyLCB0eXBlLCBjb250ZXh0Vk5vZGUsIHRocm93SW5EZXYgPSB0cnVlLCB0aHJvd0luUHJvZCA9IGZhbHNlKSB7DQogIHsNCiAgICBjb25zdCBpbmZvID0gRXJyb3JUeXBlU3RyaW5nc1t0eXBlXTsNCiAgICBpZiAoY29udGV4dFZOb2RlKSB7DQogICAgICBwdXNoV2FybmluZ0NvbnRleHQkMShjb250ZXh0Vk5vZGUpOw0KICAgIH0NCiAgICB3YXJuJDEoYFVuaGFuZGxlZCBlcnJvciR7aW5mbyA/IGAgZHVyaW5nIGV4ZWN1dGlvbiBvZiAke2luZm99YCA6IGBgfWApOw0KICAgIGlmIChjb250ZXh0Vk5vZGUpIHsNCiAgICAgIHBvcFdhcm5pbmdDb250ZXh0JDEoKTsNCiAgICB9DQogICAgaWYgKHRocm93SW5EZXYpIHsNCiAgICAgIHRocm93IGVycjsNCiAgICB9IGVsc2Ugew0KICAgICAgY29uc29sZS5lcnJvcihlcnIpOw0KICAgIH0NCiAgfQ0KfQ0KDQpjb25zdCBxdWV1ZSA9IFtdOw0KbGV0IGZsdXNoSW5kZXggPSAtMTsNCmNvbnN0IHBlbmRpbmdQb3N0Rmx1c2hDYnMgPSBbXTsNCmxldCBhY3RpdmVQb3N0Rmx1c2hDYnMgPSBudWxsOw0KbGV0IHBvc3RGbHVzaEluZGV4ID0gMDsNCmNvbnN0IHJlc29sdmVkUHJvbWlzZSA9IC8qIEBfX1BVUkVfXyAqLyBQcm9taXNlLnJlc29sdmUoKTsNCmxldCBjdXJyZW50Rmx1c2hQcm9taXNlID0gbnVsbDsNCmNvbnN0IFJFQ1VSU0lPTl9MSU1JVCA9IDEwMDsNCmZ1bmN0aW9uIG5leHRUaWNrKGZuKSB7DQogIGNvbnN0IHAgPSBjdXJyZW50Rmx1c2hQcm9taXNlIHx8IHJlc29sdmVkUHJvbWlzZTsNCiAgcmV0dXJuIGZuID8gcC50aGVuKHRoaXMgPyBmbi5iaW5kKHRoaXMpIDogZm4pIDogcDsNCn0NCmZ1bmN0aW9uIGZpbmRJbnNlcnRpb25JbmRleChpZCkgew0KICBsZXQgc3RhcnQgPSBmbHVzaEluZGV4ICsgMTsNCiAgbGV0IGVuZCA9IHF1ZXVlLmxlbmd0aDsNCiAgd2hpbGUgKHN0YXJ0IDwgZW5kKSB7DQogICAgY29uc3QgbWlkZGxlID0gc3RhcnQgKyBlbmQgPj4+IDE7DQogICAgY29uc3QgbWlkZGxlSm9iID0gcXVldWVbbWlkZGxlXTsNCiAgICBjb25zdCBtaWRkbGVKb2JJZCA9IGdldElkKG1pZGRsZUpvYik7DQogICAgaWYgKG1pZGRsZUpvYklkIDwgaWQgfHwgbWlkZGxlSm9iSWQgPT09IGlkICYmIG1pZGRsZUpvYi5mbGFncyAmIDIpIHsNCiAgICAgIHN0YXJ0ID0gbWlkZGxlICsgMTsNCiAgICB9IGVsc2Ugew0KICAgICAgZW5kID0gbWlkZGxlOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gc3RhcnQ7DQp9DQpmdW5jdGlvbiBxdWV1ZUpvYihqb2IpIHsNCiAgaWYgKCEoam9iLmZsYWdzICYgMSkpIHsNCiAgICBjb25zdCBqb2JJZCA9IGdldElkKGpvYik7DQogICAgY29uc3QgbGFzdEpvYiA9IHF1ZXVlW3F1ZXVlLmxlbmd0aCAtIDFdOw0KICAgIGlmICghbGFzdEpvYiB8fCAvLyBmYXN0IHBhdGggd2hlbiB0aGUgam9iIGlkIGlzIGxhcmdlciB0aGFuIHRoZSB0YWlsDQogICAgIShqb2IuZmxhZ3MgJiAyKSAmJiBqb2JJZCA+PSBnZXRJZChsYXN0Sm9iKSkgew0KICAgICAgcXVldWUucHVzaChqb2IpOw0KICAgIH0gZWxzZSB7DQogICAgICBxdWV1ZS5zcGxpY2UoZmluZEluc2VydGlvbkluZGV4KGpvYklkKSwgMCwgam9iKTsNCiAgICB9DQogICAgam9iLmZsYWdzIHw9IDE7DQogICAgcXVldWVGbHVzaCgpOw0KICB9DQp9DQpmdW5jdGlvbiBxdWV1ZUZsdXNoKCkgew0KICBpZiAoIWN1cnJlbnRGbHVzaFByb21pc2UpIHsNCiAgICBjdXJyZW50Rmx1c2hQcm9taXNlID0gcmVzb2x2ZWRQcm9taXNlLnRoZW4oZmx1c2hKb2JzKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gcXVldWVQb3N0Rmx1c2hDYihjYikgew0KICBpZiAoIWlzQXJyYXkoY2IpKSB7DQogICAgaWYgKGFjdGl2ZVBvc3RGbHVzaENicyAmJiBjYi5pZCA9PT0gLTEpIHsNCiAgICAgIGFjdGl2ZVBvc3RGbHVzaENicy5zcGxpY2UocG9zdEZsdXNoSW5kZXggKyAxLCAwLCBjYik7DQogICAgfSBlbHNlIGlmICghKGNiLmZsYWdzICYgMSkpIHsNCiAgICAgIHBlbmRpbmdQb3N0Rmx1c2hDYnMucHVzaChjYik7DQogICAgICBjYi5mbGFncyB8PSAxOw0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICBwZW5kaW5nUG9zdEZsdXNoQ2JzLnB1c2goLi4uY2IpOw0KICB9DQogIHF1ZXVlRmx1c2goKTsNCn0NCmZ1bmN0aW9uIGZsdXNoUHJlRmx1c2hDYnMoaW5zdGFuY2UsIHNlZW4sIGkgPSBmbHVzaEluZGV4ICsgMSkgew0KICB7DQogICAgc2VlbiA9IHNlZW4gfHwgLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTsNCiAgfQ0KICBmb3IgKDsgaSA8IHF1ZXVlLmxlbmd0aDsgaSsrKSB7DQogICAgY29uc3QgY2IgPSBxdWV1ZVtpXTsNCiAgICBpZiAoY2IgJiYgY2IuZmxhZ3MgJiAyKSB7DQogICAgICBpZiAoaW5zdGFuY2UgJiYgY2IuaWQgIT09IGluc3RhbmNlLnVpZCkgew0KICAgICAgICBjb250aW51ZTsNCiAgICAgIH0NCiAgICAgIGlmIChjaGVja1JlY3Vyc2l2ZVVwZGF0ZXMoc2VlbiwgY2IpKSB7DQogICAgICAgIGNvbnRpbnVlOw0KICAgICAgfQ0KICAgICAgcXVldWUuc3BsaWNlKGksIDEpOw0KICAgICAgaS0tOw0KICAgICAgaWYgKGNiLmZsYWdzICYgNCkgew0KICAgICAgICBjYi5mbGFncyAmPSAtMjsNCiAgICAgIH0NCiAgICAgIGNiKCk7DQogICAgICBpZiAoIShjYi5mbGFncyAmIDQpKSB7DQogICAgICAgIGNiLmZsYWdzICY9IC0yOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KfQ0KZnVuY3Rpb24gZmx1c2hQb3N0Rmx1c2hDYnMoc2Vlbikgew0KICBpZiAocGVuZGluZ1Bvc3RGbHVzaENicy5sZW5ndGgpIHsNCiAgICBjb25zdCBkZWR1cGVkID0gWy4uLm5ldyBTZXQocGVuZGluZ1Bvc3RGbHVzaENicyldLnNvcnQoDQogICAgICAoYSwgYikgPT4gZ2V0SWQoYSkgLSBnZXRJZChiKQ0KICAgICk7DQogICAgcGVuZGluZ1Bvc3RGbHVzaENicy5sZW5ndGggPSAwOw0KICAgIGlmIChhY3RpdmVQb3N0Rmx1c2hDYnMpIHsNCiAgICAgIGFjdGl2ZVBvc3RGbHVzaENicy5wdXNoKC4uLmRlZHVwZWQpOw0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBhY3RpdmVQb3N0Rmx1c2hDYnMgPSBkZWR1cGVkOw0KICAgIHsNCiAgICAgIHNlZW4gPSBzZWVuIHx8IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7DQogICAgfQ0KICAgIGZvciAocG9zdEZsdXNoSW5kZXggPSAwOyBwb3N0Rmx1c2hJbmRleCA8IGFjdGl2ZVBvc3RGbHVzaENicy5sZW5ndGg7IHBvc3RGbHVzaEluZGV4KyspIHsNCiAgICAgIGNvbnN0IGNiID0gYWN0aXZlUG9zdEZsdXNoQ2JzW3Bvc3RGbHVzaEluZGV4XTsNCiAgICAgIGlmIChjaGVja1JlY3Vyc2l2ZVVwZGF0ZXMoc2VlbiwgY2IpKSB7DQogICAgICAgIGNvbnRpbnVlOw0KICAgICAgfQ0KICAgICAgaWYgKGNiLmZsYWdzICYgNCkgew0KICAgICAgICBjYi5mbGFncyAmPSAtMjsNCiAgICAgIH0NCiAgICAgIGlmICghKGNiLmZsYWdzICYgOCkpIGNiKCk7DQogICAgICBjYi5mbGFncyAmPSAtMjsNCiAgICB9DQogICAgYWN0aXZlUG9zdEZsdXNoQ2JzID0gbnVsbDsNCiAgICBwb3N0Rmx1c2hJbmRleCA9IDA7DQogIH0NCn0NCmNvbnN0IGdldElkID0gKGpvYikgPT4gam9iLmlkID09IG51bGwgPyBqb2IuZmxhZ3MgJiAyID8gLTEgOiBJbmZpbml0eSA6IGpvYi5pZDsNCmZ1bmN0aW9uIGZsdXNoSm9icyhzZWVuKSB7DQogIHsNCiAgICBzZWVuID0gc2VlbiB8fCAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOw0KICB9DQogIGNvbnN0IGNoZWNrID0gKGpvYikgPT4gY2hlY2tSZWN1cnNpdmVVcGRhdGVzKHNlZW4sIGpvYikgOw0KICB0cnkgew0KICAgIGZvciAoZmx1c2hJbmRleCA9IDA7IGZsdXNoSW5kZXggPCBxdWV1ZS5sZW5ndGg7IGZsdXNoSW5kZXgrKykgew0KICAgICAgY29uc3Qgam9iID0gcXVldWVbZmx1c2hJbmRleF07DQogICAgICBpZiAoam9iICYmICEoam9iLmZsYWdzICYgOCkpIHsNCiAgICAgICAgaWYgKGNoZWNrKGpvYikpIHsNCiAgICAgICAgICBjb250aW51ZTsNCiAgICAgICAgfQ0KICAgICAgICBpZiAoam9iLmZsYWdzICYgNCkgew0KICAgICAgICAgIGpvYi5mbGFncyAmPSB+MTsNCiAgICAgICAgfQ0KICAgICAgICBjYWxsV2l0aEVycm9ySGFuZGxpbmcoDQogICAgICAgICAgam9iLA0KICAgICAgICAgIGpvYi5pLA0KICAgICAgICAgIGpvYi5pID8gMTUgOiAxNA0KICAgICAgICApOw0KICAgICAgICBpZiAoIShqb2IuZmxhZ3MgJiA0KSkgew0KICAgICAgICAgIGpvYi5mbGFncyAmPSB+MTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgfSBmaW5hbGx5IHsNCiAgICBmb3IgKDsgZmx1c2hJbmRleCA8IHF1ZXVlLmxlbmd0aDsgZmx1c2hJbmRleCsrKSB7DQogICAgICBjb25zdCBqb2IgPSBxdWV1ZVtmbHVzaEluZGV4XTsNCiAgICAgIGlmIChqb2IpIHsNCiAgICAgICAgam9iLmZsYWdzICY9IC0yOw0KICAgICAgfQ0KICAgIH0NCiAgICBmbHVzaEluZGV4ID0gLTE7DQogICAgcXVldWUubGVuZ3RoID0gMDsNCiAgICBmbHVzaFBvc3RGbHVzaENicyhzZWVuKTsNCiAgICBjdXJyZW50Rmx1c2hQcm9taXNlID0gbnVsbDsNCiAgICBpZiAocXVldWUubGVuZ3RoIHx8IHBlbmRpbmdQb3N0Rmx1c2hDYnMubGVuZ3RoKSB7DQogICAgICBmbHVzaEpvYnMoc2Vlbik7DQogICAgfQ0KICB9DQp9DQpmdW5jdGlvbiBjaGVja1JlY3Vyc2l2ZVVwZGF0ZXMoc2VlbiwgZm4pIHsNCiAgY29uc3QgY291bnQgPSBzZWVuLmdldChmbikgfHwgMDsNCiAgaWYgKGNvdW50ID4gUkVDVVJTSU9OX0xJTUlUKSB7DQogICAgY29uc3QgaW5zdGFuY2UgPSBmbi5pOw0KICAgIGNvbnN0IGNvbXBvbmVudE5hbWUgPSBpbnN0YW5jZSAmJiBnZXRDb21wb25lbnROYW1lKGluc3RhbmNlLnR5cGUpOw0KICAgIGhhbmRsZUVycm9yKA0KICAgICAgYE1heGltdW0gcmVjdXJzaXZlIHVwZGF0ZXMgZXhjZWVkZWQke2NvbXBvbmVudE5hbWUgPyBgIGluIGNvbXBvbmVudCA8JHtjb21wb25lbnROYW1lfT5gIDogYGB9LiBUaGlzIG1lYW5zIHlvdSBoYXZlIGEgcmVhY3RpdmUgZWZmZWN0IHRoYXQgaXMgbXV0YXRpbmcgaXRzIG93biBkZXBlbmRlbmNpZXMgYW5kIHRodXMgcmVjdXJzaXZlbHkgdHJpZ2dlcmluZyBpdHNlbGYuIFBvc3NpYmxlIHNvdXJjZXMgaW5jbHVkZSBjb21wb25lbnQgdGVtcGxhdGUsIHJlbmRlciBmdW5jdGlvbiwgdXBkYXRlZCBob29rIG9yIHdhdGNoZXIgc291cmNlIGZ1bmN0aW9uLmAsDQogICAgICBudWxsLA0KICAgICAgMTANCiAgICApOw0KICAgIHJldHVybiB0cnVlOw0KICB9DQogIHNlZW4uc2V0KGZuLCBjb3VudCArIDEpOw0KICByZXR1cm4gZmFsc2U7DQp9DQoNCmxldCBpc0htclVwZGF0aW5nID0gZmFsc2U7DQpjb25zdCBobXJEaXJ0eUNvbXBvbmVudHMgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOw0Kew0KICBnZXRHbG9iYWxUaGlzKCkuX19WVUVfSE1SX1JVTlRJTUVfXyA9IHsNCiAgICBjcmVhdGVSZWNvcmQ6IHRyeVdyYXAoY3JlYXRlUmVjb3JkKSwNCiAgICByZXJlbmRlcjogdHJ5V3JhcChyZXJlbmRlciksDQogICAgcmVsb2FkOiB0cnlXcmFwKHJlbG9hZCkNCiAgfTsNCn0NCmNvbnN0IG1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7DQpmdW5jdGlvbiByZWdpc3RlckhNUihpbnN0YW5jZSkgew0KICBjb25zdCBpZCA9IGluc3RhbmNlLnR5cGUuX19obXJJZDsNCiAgbGV0IHJlY29yZCA9IG1hcC5nZXQoaWQpOw0KICBpZiAoIXJlY29yZCkgew0KICAgIGNyZWF0ZVJlY29yZChpZCwgaW5zdGFuY2UudHlwZSk7DQogICAgcmVjb3JkID0gbWFwLmdldChpZCk7DQogIH0NCiAgcmVjb3JkLmluc3RhbmNlcy5hZGQoaW5zdGFuY2UpOw0KfQ0KZnVuY3Rpb24gdW5yZWdpc3RlckhNUihpbnN0YW5jZSkgew0KICBtYXAuZ2V0KGluc3RhbmNlLnR5cGUuX19obXJJZCkuaW5zdGFuY2VzLmRlbGV0ZShpbnN0YW5jZSk7DQp9DQpmdW5jdGlvbiBjcmVhdGVSZWNvcmQoaWQsIGluaXRpYWxEZWYpIHsNCiAgaWYgKG1hcC5oYXMoaWQpKSB7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9DQogIG1hcC5zZXQoaWQsIHsNCiAgICBpbml0aWFsRGVmOiBub3JtYWxpemVDbGFzc0NvbXBvbmVudChpbml0aWFsRGVmKSwNCiAgICBpbnN0YW5jZXM6IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KCkNCiAgfSk7DQogIHJldHVybiB0cnVlOw0KfQ0KZnVuY3Rpb24gbm9ybWFsaXplQ2xhc3NDb21wb25lbnQoY29tcG9uZW50KSB7DQogIHJldHVybiBpc0NsYXNzQ29tcG9uZW50KGNvbXBvbmVudCkgPyBjb21wb25lbnQuX192Y2NPcHRzIDogY29tcG9uZW50Ow0KfQ0KZnVuY3Rpb24gcmVyZW5kZXIoaWQsIG5ld1JlbmRlcikgew0KICBjb25zdCByZWNvcmQgPSBtYXAuZ2V0KGlkKTsNCiAgaWYgKCFyZWNvcmQpIHsNCiAgICByZXR1cm47DQogIH0NCiAgcmVjb3JkLmluaXRpYWxEZWYucmVuZGVyID0gbmV3UmVuZGVyOw0KICBbLi4ucmVjb3JkLmluc3RhbmNlc10uZm9yRWFjaCgoaW5zdGFuY2UpID0+IHsNCiAgICBpZiAobmV3UmVuZGVyKSB7DQogICAgICBpbnN0YW5jZS5yZW5kZXIgPSBuZXdSZW5kZXI7DQogICAgICBub3JtYWxpemVDbGFzc0NvbXBvbmVudChpbnN0YW5jZS50eXBlKS5yZW5kZXIgPSBuZXdSZW5kZXI7DQogICAgfQ0KICAgIGluc3RhbmNlLnJlbmRlckNhY2hlID0gW107DQogICAgaXNIbXJVcGRhdGluZyA9IHRydWU7DQogICAgaW5zdGFuY2UudXBkYXRlKCk7DQogICAgaXNIbXJVcGRhdGluZyA9IGZhbHNlOw0KICB9KTsNCn0NCmZ1bmN0aW9uIHJlbG9hZChpZCwgbmV3Q29tcCkgew0KICBjb25zdCByZWNvcmQgPSBtYXAuZ2V0KGlkKTsNCiAgaWYgKCFyZWNvcmQpIHJldHVybjsNCiAgbmV3Q29tcCA9IG5vcm1hbGl6ZUNsYXNzQ29tcG9uZW50KG5ld0NvbXApOw0KICB1cGRhdGVDb21wb25lbnREZWYocmVjb3JkLmluaXRpYWxEZWYsIG5ld0NvbXApOw0KICBjb25zdCBpbnN0YW5jZXMgPSBbLi4ucmVjb3JkLmluc3RhbmNlc107DQogIGZvciAobGV0IGkgPSAwOyBpIDwgaW5zdGFuY2VzLmxlbmd0aDsgaSsrKSB7DQogICAgY29uc3QgaW5zdGFuY2UgPSBpbnN0YW5jZXNbaV07DQogICAgY29uc3Qgb2xkQ29tcCA9IG5vcm1hbGl6ZUNsYXNzQ29tcG9uZW50KGluc3RhbmNlLnR5cGUpOw0KICAgIGxldCBkaXJ0eUluc3RhbmNlcyA9IGhtckRpcnR5Q29tcG9uZW50cy5nZXQob2xkQ29tcCk7DQogICAgaWYgKCFkaXJ0eUluc3RhbmNlcykgew0KICAgICAgaWYgKG9sZENvbXAgIT09IHJlY29yZC5pbml0aWFsRGVmKSB7DQogICAgICAgIHVwZGF0ZUNvbXBvbmVudERlZihvbGRDb21wLCBuZXdDb21wKTsNCiAgICAgIH0NCiAgICAgIGhtckRpcnR5Q29tcG9uZW50cy5zZXQob2xkQ29tcCwgZGlydHlJbnN0YW5jZXMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpKTsNCiAgICB9DQogICAgZGlydHlJbnN0YW5jZXMuYWRkKGluc3RhbmNlKTsNCiAgICBpbnN0YW5jZS5hcHBDb250ZXh0LnByb3BzQ2FjaGUuZGVsZXRlKGluc3RhbmNlLnR5cGUpOw0KICAgIGluc3RhbmNlLmFwcENvbnRleHQuZW1pdHNDYWNoZS5kZWxldGUoaW5zdGFuY2UudHlwZSk7DQogICAgaW5zdGFuY2UuYXBwQ29udGV4dC5vcHRpb25zQ2FjaGUuZGVsZXRlKGluc3RhbmNlLnR5cGUpOw0KICAgIGlmIChpbnN0YW5jZS5jZVJlbG9hZCkgew0KICAgICAgZGlydHlJbnN0YW5jZXMuYWRkKGluc3RhbmNlKTsNCiAgICAgIGluc3RhbmNlLmNlUmVsb2FkKG5ld0NvbXAuc3R5bGVzKTsNCiAgICAgIGRpcnR5SW5zdGFuY2VzLmRlbGV0ZShpbnN0YW5jZSk7DQogICAgfSBlbHNlIGlmIChpbnN0YW5jZS5wYXJlbnQpIHsNCiAgICAgIHF1ZXVlSm9iKCgpID0+IHsNCiAgICAgICAgaXNIbXJVcGRhdGluZyA9IHRydWU7DQogICAgICAgIGluc3RhbmNlLnBhcmVudC51cGRhdGUoKTsNCiAgICAgICAgaXNIbXJVcGRhdGluZyA9IGZhbHNlOw0KICAgICAgICBkaXJ0eUluc3RhbmNlcy5kZWxldGUoaW5zdGFuY2UpOw0KICAgICAgfSk7DQogICAgfSBlbHNlIGlmIChpbnN0YW5jZS5hcHBDb250ZXh0LnJlbG9hZCkgew0KICAgICAgaW5zdGFuY2UuYXBwQ29udGV4dC5yZWxvYWQoKTsNCiAgICB9IGVsc2UgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICJ1bmRlZmluZWQiKSB7DQogICAgICB3aW5kb3cubG9jYXRpb24ucmVsb2FkKCk7DQogICAgfSBlbHNlIHsNCiAgICAgIGNvbnNvbGUud2FybigNCiAgICAgICAgIltITVJdIFJvb3Qgb3IgbWFudWFsbHkgbW91bnRlZCBpbnN0YW5jZSBtb2RpZmllZC4gRnVsbCByZWxvYWQgcmVxdWlyZWQuIg0KICAgICAgKTsNCiAgICB9DQogICAgaWYgKGluc3RhbmNlLnJvb3QuY2UgJiYgaW5zdGFuY2UgIT09IGluc3RhbmNlLnJvb3QpIHsNCiAgICAgIGluc3RhbmNlLnJvb3QuY2UuX3JlbW92ZUNoaWxkU3R5bGUob2xkQ29tcCk7DQogICAgfQ0KICB9DQogIHF1ZXVlUG9zdEZsdXNoQ2IoKCkgPT4gew0KICAgIGhtckRpcnR5Q29tcG9uZW50cy5jbGVhcigpOw0KICB9KTsNCn0NCmZ1bmN0aW9uIHVwZGF0ZUNvbXBvbmVudERlZihvbGRDb21wLCBuZXdDb21wKSB7DQogIGV4dGVuZChvbGRDb21wLCBuZXdDb21wKTsNCiAgZm9yIChjb25zdCBrZXkgaW4gb2xkQ29tcCkgew0KICAgIGlmIChrZXkgIT09ICJfX2ZpbGUiICYmICEoa2V5IGluIG5ld0NvbXApKSB7DQogICAgICBkZWxldGUgb2xkQ29tcFtrZXldOw0KICAgIH0NCiAgfQ0KfQ0KZnVuY3Rpb24gdHJ5V3JhcChmbikgew0KICByZXR1cm4gKGlkLCBhcmcpID0+IHsNCiAgICB0cnkgew0KICAgICAgcmV0dXJuIGZuKGlkLCBhcmcpOw0KICAgIH0gY2F0Y2ggKGUpIHsNCiAgICAgIGNvbnNvbGUuZXJyb3IoZSk7DQogICAgICBjb25zb2xlLndhcm4oDQogICAgICAgIGBbSE1SXSBTb21ldGhpbmcgd2VudCB3cm9uZyBkdXJpbmcgVnVlIGNvbXBvbmVudCBob3QtcmVsb2FkLiBGdWxsIHJlbG9hZCByZXF1aXJlZC5gDQogICAgICApOw0KICAgIH0NCiAgfTsNCn0NCg0KbGV0IGRldnRvb2xzOw0KbGV0IGJ1ZmZlciA9IFtdOw0KbGV0IGRldnRvb2xzTm90SW5zdGFsbGVkID0gZmFsc2U7DQpmdW5jdGlvbiBlbWl0JDEoZXZlbnQsIC4uLmFyZ3MpIHsNCiAgaWYgKGRldnRvb2xzKSB7DQogICAgZGV2dG9vbHMuZW1pdChldmVudCwgLi4uYXJncyk7DQogIH0gZWxzZSBpZiAoIWRldnRvb2xzTm90SW5zdGFsbGVkKSB7DQogICAgYnVmZmVyLnB1c2goeyBldmVudCwgYXJncyB9KTsNCiAgfQ0KfQ0KZnVuY3Rpb24gc2V0RGV2dG9vbHNIb29rKGhvb2ssIHRhcmdldCkgew0KICB2YXIgX2EsIF9iOw0KICBkZXZ0b29scyA9IGhvb2s7DQogIGlmIChkZXZ0b29scykgew0KICAgIGRldnRvb2xzLmVuYWJsZWQgPSB0cnVlOw0KICAgIGJ1ZmZlci5mb3JFYWNoKCh7IGV2ZW50LCBhcmdzIH0pID0+IGRldnRvb2xzLmVtaXQoZXZlbnQsIC4uLmFyZ3MpKTsNCiAgICBidWZmZXIgPSBbXTsNCiAgfSBlbHNlIGlmICgNCiAgICAvLyBoYW5kbGUgbGF0ZSBkZXZ0b29scyBpbmplY3Rpb24gLSBvbmx5IGRvIHRoaXMgaWYgd2UgYXJlIGluIGFuIGFjdHVhbA0KICAgIC8vIGJyb3dzZXIgZW52aXJvbm1lbnQgdG8gYXZvaWQgdGhlIHRpbWVyIGhhbmRsZSBzdGFsbGluZyB0ZXN0IHJ1bm5lciBleGl0DQogICAgLy8gKCM0ODE1KQ0KICAgIHR5cGVvZiB3aW5kb3cgIT09ICJ1bmRlZmluZWQiICYmIC8vIHNvbWUgZW52cyBtb2NrIHdpbmRvdyBidXQgbm90IGZ1bGx5DQogICAgd2luZG93LkhUTUxFbGVtZW50ICYmIC8vIGFsc28gZXhjbHVkZSBqc2RvbQ0KICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheA0KICAgICEoKF9iID0gKF9hID0gd2luZG93Lm5hdmlnYXRvcikgPT0gbnVsbCA/IHZvaWQgMCA6IF9hLnVzZXJBZ2VudCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9iLmluY2x1ZGVzKCJqc2RvbSIpKQ0KICApIHsNCiAgICBjb25zdCByZXBsYXkgPSB0YXJnZXQuX19WVUVfREVWVE9PTFNfSE9PS19SRVBMQVlfXyA9IHRhcmdldC5fX1ZVRV9ERVZUT09MU19IT09LX1JFUExBWV9fIHx8IFtdOw0KICAgIHJlcGxheS5wdXNoKChuZXdIb29rKSA9PiB7DQogICAgICBzZXREZXZ0b29sc0hvb2sobmV3SG9vaywgdGFyZ2V0KTsNCiAgICB9KTsNCiAgICBzZXRUaW1lb3V0KCgpID0+IHsNCiAgICAgIGlmICghZGV2dG9vbHMpIHsNCiAgICAgICAgdGFyZ2V0Ll9fVlVFX0RFVlRPT0xTX0hPT0tfUkVQTEFZX18gPSBudWxsOw0KICAgICAgICBkZXZ0b29sc05vdEluc3RhbGxlZCA9IHRydWU7DQogICAgICAgIGJ1ZmZlciA9IFtdOw0KICAgICAgfQ0KICAgIH0sIDNlMyk7DQogIH0gZWxzZSB7DQogICAgZGV2dG9vbHNOb3RJbnN0YWxsZWQgPSB0cnVlOw0KICAgIGJ1ZmZlciA9IFtdOw0KICB9DQp9DQpmdW5jdGlvbiBkZXZ0b29sc0luaXRBcHAoYXBwLCB2ZXJzaW9uKSB7DQogIGVtaXQkMSgiYXBwOmluaXQiIC8qIEFQUF9JTklUICovLCBhcHAsIHZlcnNpb24sIHsNCiAgICBGcmFnbWVudCwNCiAgICBUZXh0LA0KICAgIENvbW1lbnQsDQogICAgU3RhdGljDQogIH0pOw0KfQ0KZnVuY3Rpb24gZGV2dG9vbHNVbm1vdW50QXBwKGFwcCkgew0KICBlbWl0JDEoImFwcDp1bm1vdW50IiAvKiBBUFBfVU5NT1VOVCAqLywgYXBwKTsNCn0NCmNvbnN0IGRldnRvb2xzQ29tcG9uZW50QWRkZWQgPSAvKiBAX19QVVJFX18gKi8gY3JlYXRlRGV2dG9vbHNDb21wb25lbnRIb29rKCJjb21wb25lbnQ6YWRkZWQiIC8qIENPTVBPTkVOVF9BRERFRCAqLyk7DQpjb25zdCBkZXZ0b29sc0NvbXBvbmVudFVwZGF0ZWQgPSAvKiBAX19QVVJFX18gKi8gY3JlYXRlRGV2dG9vbHNDb21wb25lbnRIb29rKCJjb21wb25lbnQ6dXBkYXRlZCIgLyogQ09NUE9ORU5UX1VQREFURUQgKi8pOw0KY29uc3QgX2RldnRvb2xzQ29tcG9uZW50UmVtb3ZlZCA9IC8qIEBfX1BVUkVfXyAqLyBjcmVhdGVEZXZ0b29sc0NvbXBvbmVudEhvb2soDQogICJjb21wb25lbnQ6cmVtb3ZlZCIgLyogQ09NUE9ORU5UX1JFTU9WRUQgKi8NCik7DQpjb25zdCBkZXZ0b29sc0NvbXBvbmVudFJlbW92ZWQgPSAoY29tcG9uZW50KSA9PiB7DQogIGlmIChkZXZ0b29scyAmJiB0eXBlb2YgZGV2dG9vbHMuY2xlYW51cEJ1ZmZlciA9PT0gImZ1bmN0aW9uIiAmJiAvLyByZW1vdmUgdGhlIGNvbXBvbmVudCBpZiBpdCB3YXNuJ3QgYnVmZmVyZWQNCiAgIWRldnRvb2xzLmNsZWFudXBCdWZmZXIoY29tcG9uZW50KSkgew0KICAgIF9kZXZ0b29sc0NvbXBvbmVudFJlbW92ZWQoY29tcG9uZW50KTsNCiAgfQ0KfTsNCi8qISAjX19OT19TSURFX0VGRkVDVFNfXyAqLw0KLy8gQF9fTk9fU0lERV9FRkZFQ1RTX18NCmZ1bmN0aW9uIGNyZWF0ZURldnRvb2xzQ29tcG9uZW50SG9vayhob29rKSB7DQogIHJldHVybiAoY29tcG9uZW50KSA9PiB7DQogICAgZW1pdCQxKA0KICAgICAgaG9vaywNCiAgICAgIGNvbXBvbmVudC5hcHBDb250ZXh0LmFwcCwNCiAgICAgIGNvbXBvbmVudC51aWQsDQogICAgICBjb21wb25lbnQucGFyZW50ID8gY29tcG9uZW50LnBhcmVudC51aWQgOiB2b2lkIDAsDQogICAgICBjb21wb25lbnQNCiAgICApOw0KICB9Ow0KfQ0KY29uc3QgZGV2dG9vbHNQZXJmU3RhcnQgPSAvKiBAX19QVVJFX18gKi8gY3JlYXRlRGV2dG9vbHNQZXJmb3JtYW5jZUhvb2soInBlcmY6c3RhcnQiIC8qIFBFUkZPUk1BTkNFX1NUQVJUICovKTsNCmNvbnN0IGRldnRvb2xzUGVyZkVuZCA9IC8qIEBfX1BVUkVfXyAqLyBjcmVhdGVEZXZ0b29sc1BlcmZvcm1hbmNlSG9vaygicGVyZjplbmQiIC8qIFBFUkZPUk1BTkNFX0VORCAqLyk7DQpmdW5jdGlvbiBjcmVhdGVEZXZ0b29sc1BlcmZvcm1hbmNlSG9vayhob29rKSB7DQogIHJldHVybiAoY29tcG9uZW50LCB0eXBlLCB0aW1lKSA9PiB7DQogICAgZW1pdCQxKGhvb2ssIGNvbXBvbmVudC5hcHBDb250ZXh0LmFwcCwgY29tcG9uZW50LnVpZCwgY29tcG9uZW50LCB0eXBlLCB0aW1lKTsNCiAgfTsNCn0NCmZ1bmN0aW9uIGRldnRvb2xzQ29tcG9uZW50RW1pdChjb21wb25lbnQsIGV2ZW50LCBwYXJhbXMpIHsNCiAgZW1pdCQxKA0KICAgICJjb21wb25lbnQ6ZW1pdCIgLyogQ09NUE9ORU5UX0VNSVQgKi8sDQogICAgY29tcG9uZW50LmFwcENvbnRleHQuYXBwLA0KICAgIGNvbXBvbmVudCwNCiAgICBldmVudCwNCiAgICBwYXJhbXMNCiAgKTsNCn0NCg0KbGV0IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSA9IG51bGw7DQpsZXQgY3VycmVudFNjb3BlSWQgPSBudWxsOw0KZnVuY3Rpb24gc2V0Q3VycmVudFJlbmRlcmluZ0luc3RhbmNlJDEoaW5zdGFuY2UpIHsNCiAgY29uc3QgcHJldiA9IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZTsNCiAgY3VycmVudFJlbmRlcmluZ0luc3RhbmNlID0gaW5zdGFuY2U7DQogIGN1cnJlbnRTY29wZUlkID0gaW5zdGFuY2UgJiYgaW5zdGFuY2UudHlwZS5fX3Njb3BlSWQgfHwgbnVsbDsNCiAgcmV0dXJuIHByZXY7DQp9DQpmdW5jdGlvbiB3aXRoQ3R4KGZuLCBjdHggPSBjdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UsIGlzTm9uU2NvcGVkU2xvdCkgew0KICBpZiAoIWN0eCkgcmV0dXJuIGZuOw0KICBpZiAoZm4uX24pIHsNCiAgICByZXR1cm4gZm47DQogIH0NCiAgY29uc3QgcmVuZGVyRm5XaXRoQ29udGV4dCA9ICguLi5hcmdzKSA9PiB7DQogICAgaWYgKHJlbmRlckZuV2l0aENvbnRleHQuX2QpIHsNCiAgICAgIHNldEJsb2NrVHJhY2tpbmcoLTEpOw0KICAgIH0NCiAgICBjb25zdCBwcmV2SW5zdGFuY2UgPSBzZXRDdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UkMShjdHgpOw0KICAgIGxldCByZXM7DQogICAgdHJ5IHsNCiAgICAgIHJlcyA9IGZuKC4uLmFyZ3MpOw0KICAgIH0gZmluYWxseSB7DQogICAgICBzZXRDdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UkMShwcmV2SW5zdGFuY2UpOw0KICAgICAgaWYgKHJlbmRlckZuV2l0aENvbnRleHQuX2QpIHsNCiAgICAgICAgc2V0QmxvY2tUcmFja2luZygxKTsNCiAgICAgIH0NCiAgICB9DQogICAgew0KICAgICAgZGV2dG9vbHNDb21wb25lbnRVcGRhdGVkKGN0eCk7DQogICAgfQ0KICAgIHJldHVybiByZXM7DQogIH07DQogIHJlbmRlckZuV2l0aENvbnRleHQuX24gPSB0cnVlOw0KICByZW5kZXJGbldpdGhDb250ZXh0Ll9jID0gdHJ1ZTsNCiAgcmVuZGVyRm5XaXRoQ29udGV4dC5fZCA9IHRydWU7DQogIHJldHVybiByZW5kZXJGbldpdGhDb250ZXh0Ow0KfQ0KDQpmdW5jdGlvbiB2YWxpZGF0ZURpcmVjdGl2ZU5hbWUobmFtZSkgew0KICBpZiAoaXNCdWlsdEluRGlyZWN0aXZlKG5hbWUpKSB7DQogICAgd2FybiQxKCJEbyBub3QgdXNlIGJ1aWx0LWluIGRpcmVjdGl2ZSBpZHMgYXMgY3VzdG9tIGRpcmVjdGl2ZSBpZDogIiArIG5hbWUpOw0KICB9DQp9DQpmdW5jdGlvbiBpbnZva2VEaXJlY3RpdmVIb29rKHZub2RlLCBwcmV2Vk5vZGUsIGluc3RhbmNlLCBuYW1lKSB7DQogIGNvbnN0IGJpbmRpbmdzID0gdm5vZGUuZGlyczsNCiAgY29uc3Qgb2xkQmluZGluZ3MgPSBwcmV2Vk5vZGUgJiYgcHJldlZOb2RlLmRpcnM7DQogIGZvciAobGV0IGkgPSAwOyBpIDwgYmluZGluZ3MubGVuZ3RoOyBpKyspIHsNCiAgICBjb25zdCBiaW5kaW5nID0gYmluZGluZ3NbaV07DQogICAgaWYgKG9sZEJpbmRpbmdzKSB7DQogICAgICBiaW5kaW5nLm9sZFZhbHVlID0gb2xkQmluZGluZ3NbaV0udmFsdWU7DQogICAgfQ0KICAgIGxldCBob29rID0gYmluZGluZy5kaXJbbmFtZV07DQogICAgaWYgKGhvb2spIHsNCiAgICAgIHBhdXNlVHJhY2tpbmcoKTsNCiAgICAgIGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nKGhvb2ssIGluc3RhbmNlLCA4LCBbDQogICAgICAgIHZub2RlLmVsLA0KICAgICAgICBiaW5kaW5nLA0KICAgICAgICB2bm9kZSwNCiAgICAgICAgcHJldlZOb2RlDQogICAgICBdKTsNCiAgICAgIHJlc2V0VHJhY2tpbmcoKTsNCiAgICB9DQogIH0NCn0NCg0KY29uc3QgVGVsZXBvcnRFbmRLZXkgPSBTeW1ib2woIl92dGUiKTsNCmNvbnN0IGlzVGVsZXBvcnQgPSAodHlwZSkgPT4gdHlwZS5fX2lzVGVsZXBvcnQ7DQoNCmZ1bmN0aW9uIHNldFRyYW5zaXRpb25Ib29rcyh2bm9kZSwgaG9va3MpIHsNCiAgaWYgKHZub2RlLnNoYXBlRmxhZyAmIDYgJiYgdm5vZGUuY29tcG9uZW50KSB7DQogICAgdm5vZGUudHJhbnNpdGlvbiA9IGhvb2tzOw0KICAgIHNldFRyYW5zaXRpb25Ib29rcyh2bm9kZS5jb21wb25lbnQuc3ViVHJlZSwgaG9va3MpOw0KICB9IGVsc2UgaWYgKHZub2RlLnNoYXBlRmxhZyAmIDEyOCkgew0KICAgIHZub2RlLnNzQ29udGVudC50cmFuc2l0aW9uID0gaG9va3MuY2xvbmUodm5vZGUuc3NDb250ZW50KTsNCiAgICB2bm9kZS5zc0ZhbGxiYWNrLnRyYW5zaXRpb24gPSBob29rcy5jbG9uZSh2bm9kZS5zc0ZhbGxiYWNrKTsNCiAgfSBlbHNlIHsNCiAgICB2bm9kZS50cmFuc2l0aW9uID0gaG9va3M7DQogIH0NCn0NCg0KZnVuY3Rpb24gbWFya0FzeW5jQm91bmRhcnkoaW5zdGFuY2UpIHsNCiAgaW5zdGFuY2UuaWRzID0gW2luc3RhbmNlLmlkc1swXSArIGluc3RhbmNlLmlkc1syXSsrICsgIi0iLCAwLCAwXTsNCn0NCg0KY29uc3Qga25vd25UZW1wbGF0ZVJlZnMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtTZXQoKTsNCg0KZnVuY3Rpb24gc2V0UmVmKHJhd1JlZiwgb2xkUmF3UmVmLCBwYXJlbnRTdXNwZW5zZSwgdm5vZGUsIGlzVW5tb3VudCA9IGZhbHNlKSB7DQogIGlmIChpc0FycmF5KHJhd1JlZikpIHsNCiAgICByYXdSZWYuZm9yRWFjaCgNCiAgICAgIChyLCBpKSA9PiBzZXRSZWYoDQogICAgICAgIHIsDQogICAgICAgIG9sZFJhd1JlZiAmJiAoaXNBcnJheShvbGRSYXdSZWYpID8gb2xkUmF3UmVmW2ldIDogb2xkUmF3UmVmKSwNCiAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgIHZub2RlLA0KICAgICAgICBpc1VubW91bnQNCiAgICAgICkNCiAgICApOw0KICAgIHJldHVybjsNCiAgfQ0KICBpZiAoaXNBc3luY1dyYXBwZXIodm5vZGUpICYmICFpc1VubW91bnQpIHsNCiAgICBpZiAodm5vZGUuc2hhcGVGbGFnICYgNTEyICYmIHZub2RlLnR5cGUuX19hc3luY1Jlc29sdmVkICYmIHZub2RlLmNvbXBvbmVudC5zdWJUcmVlLmNvbXBvbmVudCkgew0KICAgICAgc2V0UmVmKHJhd1JlZiwgb2xkUmF3UmVmLCBwYXJlbnRTdXNwZW5zZSwgdm5vZGUuY29tcG9uZW50LnN1YlRyZWUpOw0KICAgIH0NCiAgICByZXR1cm47DQogIH0NCiAgY29uc3QgcmVmVmFsdWUgPSB2bm9kZS5zaGFwZUZsYWcgJiA0ID8gZ2V0Q29tcG9uZW50UHVibGljSW5zdGFuY2Uodm5vZGUuY29tcG9uZW50KSA6IHZub2RlLmVsOw0KICBjb25zdCB2YWx1ZSA9IGlzVW5tb3VudCA/IG51bGwgOiByZWZWYWx1ZTsNCiAgY29uc3QgeyBpOiBvd25lciwgcjogcmVmIH0gPSByYXdSZWY7DQogIGlmICghb3duZXIpIHsNCiAgICB3YXJuJDEoDQogICAgICBgTWlzc2luZyByZWYgb3duZXIgY29udGV4dC4gcmVmIGNhbm5vdCBiZSB1c2VkIG9uIGhvaXN0ZWQgdm5vZGVzLiBBIHZub2RlIHdpdGggcmVmIG11c3QgYmUgY3JlYXRlZCBpbnNpZGUgdGhlIHJlbmRlciBmdW5jdGlvbi5gDQogICAgKTsNCiAgICByZXR1cm47DQogIH0NCiAgY29uc3Qgb2xkUmVmID0gb2xkUmF3UmVmICYmIG9sZFJhd1JlZi5yOw0KICBjb25zdCByZWZzID0gb3duZXIucmVmcyA9PT0gRU1QVFlfT0JKID8gb3duZXIucmVmcyA9IHt9IDogb3duZXIucmVmczsNCiAgY29uc3Qgc2V0dXBTdGF0ZSA9IG93bmVyLnNldHVwU3RhdGU7DQogIGNvbnN0IHJhd1NldHVwU3RhdGUgPSB0b1JhdyhzZXR1cFN0YXRlKTsNCiAgY29uc3QgY2FuU2V0U2V0dXBSZWYgPSBzZXR1cFN0YXRlID09PSBFTVBUWV9PQkogPyAoKSA9PiBmYWxzZSA6IChrZXkpID0+IHsNCiAgICB7DQogICAgICBpZiAoaGFzT3duKHJhd1NldHVwU3RhdGUsIGtleSkgJiYgIWlzUmVmKHJhd1NldHVwU3RhdGVba2V5XSkpIHsNCiAgICAgICAgd2FybiQxKA0KICAgICAgICAgIGBUZW1wbGF0ZSByZWYgIiR7a2V5fSIgdXNlZCBvbiBhIG5vbi1yZWYgdmFsdWUuIEl0IHdpbGwgbm90IHdvcmsgaW4gdGhlIHByb2R1Y3Rpb24gYnVpbGQuYA0KICAgICAgICApOw0KICAgICAgfQ0KICAgICAgaWYgKGtub3duVGVtcGxhdGVSZWZzLmhhcyhyYXdTZXR1cFN0YXRlW2tleV0pKSB7DQogICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAgIH0NCiAgICB9DQogICAgcmV0dXJuIGhhc093bihyYXdTZXR1cFN0YXRlLCBrZXkpOw0KICB9Ow0KICBpZiAob2xkUmVmICE9IG51bGwgJiYgb2xkUmVmICE9PSByZWYpIHsNCiAgICBpZiAoaXNTdHJpbmcob2xkUmVmKSkgew0KICAgICAgcmVmc1tvbGRSZWZdID0gbnVsbDsNCiAgICAgIGlmIChjYW5TZXRTZXR1cFJlZihvbGRSZWYpKSB7DQogICAgICAgIHNldHVwU3RhdGVbb2xkUmVmXSA9IG51bGw7DQogICAgICB9DQogICAgfSBlbHNlIGlmIChpc1JlZihvbGRSZWYpKSB7DQogICAgICBvbGRSZWYudmFsdWUgPSBudWxsOw0KICAgIH0NCiAgfQ0KICBpZiAoaXNGdW5jdGlvbihyZWYpKSB7DQogICAgY2FsbFdpdGhFcnJvckhhbmRsaW5nKHJlZiwgb3duZXIsIDEyLCBbdmFsdWUsIHJlZnNdKTsNCiAgfSBlbHNlIHsNCiAgICBjb25zdCBfaXNTdHJpbmcgPSBpc1N0cmluZyhyZWYpOw0KICAgIGNvbnN0IF9pc1JlZiA9IGlzUmVmKHJlZik7DQogICAgaWYgKF9pc1N0cmluZyB8fCBfaXNSZWYpIHsNCiAgICAgIGNvbnN0IGRvU2V0ID0gKCkgPT4gew0KICAgICAgICBpZiAocmF3UmVmLmYpIHsNCiAgICAgICAgICBjb25zdCBleGlzdGluZyA9IF9pc1N0cmluZyA/IGNhblNldFNldHVwUmVmKHJlZikgPyBzZXR1cFN0YXRlW3JlZl0gOiByZWZzW3JlZl0gOiByZWYudmFsdWU7DQogICAgICAgICAgaWYgKGlzVW5tb3VudCkgew0KICAgICAgICAgICAgaXNBcnJheShleGlzdGluZykgJiYgcmVtb3ZlKGV4aXN0aW5nLCByZWZWYWx1ZSk7DQogICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIGlmICghaXNBcnJheShleGlzdGluZykpIHsNCiAgICAgICAgICAgICAgaWYgKF9pc1N0cmluZykgew0KICAgICAgICAgICAgICAgIHJlZnNbcmVmXSA9IFtyZWZWYWx1ZV07DQogICAgICAgICAgICAgICAgaWYgKGNhblNldFNldHVwUmVmKHJlZikpIHsNCiAgICAgICAgICAgICAgICAgIHNldHVwU3RhdGVbcmVmXSA9IHJlZnNbcmVmXTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgcmVmLnZhbHVlID0gW3JlZlZhbHVlXTsNCiAgICAgICAgICAgICAgICBpZiAocmF3UmVmLmspIHJlZnNbcmF3UmVmLmtdID0gcmVmLnZhbHVlOw0KICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9IGVsc2UgaWYgKCFleGlzdGluZy5pbmNsdWRlcyhyZWZWYWx1ZSkpIHsNCiAgICAgICAgICAgICAgZXhpc3RpbmcucHVzaChyZWZWYWx1ZSk7DQogICAgICAgICAgICB9DQogICAgICAgICAgfQ0KICAgICAgICB9IGVsc2UgaWYgKF9pc1N0cmluZykgew0KICAgICAgICAgIHJlZnNbcmVmXSA9IHZhbHVlOw0KICAgICAgICAgIGlmIChjYW5TZXRTZXR1cFJlZihyZWYpKSB7DQogICAgICAgICAgICBzZXR1cFN0YXRlW3JlZl0gPSB2YWx1ZTsNCiAgICAgICAgICB9DQogICAgICAgIH0gZWxzZSBpZiAoX2lzUmVmKSB7DQogICAgICAgICAgcmVmLnZhbHVlID0gdmFsdWU7DQogICAgICAgICAgaWYgKHJhd1JlZi5rKSByZWZzW3Jhd1JlZi5rXSA9IHZhbHVlOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIHdhcm4kMSgiSW52YWxpZCB0ZW1wbGF0ZSByZWYgdHlwZToiLCByZWYsIGAoJHt0eXBlb2YgcmVmfSlgKTsNCiAgICAgICAgfQ0KICAgICAgfTsNCiAgICAgIGlmICh2YWx1ZSkgew0KICAgICAgICBkb1NldC5pZCA9IC0xOw0KICAgICAgICBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QoZG9TZXQsIHBhcmVudFN1c3BlbnNlKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGRvU2V0KCk7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIHdhcm4kMSgiSW52YWxpZCB0ZW1wbGF0ZSByZWYgdHlwZToiLCByZWYsIGAoJHt0eXBlb2YgcmVmfSlgKTsNCiAgICB9DQogIH0NCn0NCg0KY29uc3QgaXNBc3luY1dyYXBwZXIgPSAoaSkgPT4gISFpLnR5cGUuX19hc3luY0xvYWRlcjsNCg0KY29uc3QgaXNLZWVwQWxpdmUgPSAodm5vZGUpID0+IHZub2RlLnR5cGUuX19pc0tlZXBBbGl2ZTsNCmZ1bmN0aW9uIG9uQWN0aXZhdGVkKGhvb2ssIHRhcmdldCkgew0KICByZWdpc3RlcktlZXBBbGl2ZUhvb2soaG9vaywgImEiLCB0YXJnZXQpOw0KfQ0KZnVuY3Rpb24gb25EZWFjdGl2YXRlZChob29rLCB0YXJnZXQpIHsNCiAgcmVnaXN0ZXJLZWVwQWxpdmVIb29rKGhvb2ssICJkYSIsIHRhcmdldCk7DQp9DQpmdW5jdGlvbiByZWdpc3RlcktlZXBBbGl2ZUhvb2soaG9vaywgdHlwZSwgdGFyZ2V0ID0gY3VycmVudEluc3RhbmNlKSB7DQogIGNvbnN0IHdyYXBwZWRIb29rID0gaG9vay5fX3dkYyB8fCAoaG9vay5fX3dkYyA9ICgpID0+IHsNCiAgICBsZXQgY3VycmVudCA9IHRhcmdldDsNCiAgICB3aGlsZSAoY3VycmVudCkgew0KICAgICAgaWYgKGN1cnJlbnQuaXNEZWFjdGl2YXRlZCkgew0KICAgICAgICByZXR1cm47DQogICAgICB9DQogICAgICBjdXJyZW50ID0gY3VycmVudC5wYXJlbnQ7DQogICAgfQ0KICAgIHJldHVybiBob29rKCk7DQogIH0pOw0KICBpbmplY3RIb29rKHR5cGUsIHdyYXBwZWRIb29rLCB0YXJnZXQpOw0KICBpZiAodGFyZ2V0KSB7DQogICAgbGV0IGN1cnJlbnQgPSB0YXJnZXQucGFyZW50Ow0KICAgIHdoaWxlIChjdXJyZW50ICYmIGN1cnJlbnQucGFyZW50KSB7DQogICAgICBpZiAoaXNLZWVwQWxpdmUoY3VycmVudC5wYXJlbnQudm5vZGUpKSB7DQogICAgICAgIGluamVjdFRvS2VlcEFsaXZlUm9vdCh3cmFwcGVkSG9vaywgdHlwZSwgdGFyZ2V0LCBjdXJyZW50KTsNCiAgICAgIH0NCiAgICAgIGN1cnJlbnQgPSBjdXJyZW50LnBhcmVudDsNCiAgICB9DQogIH0NCn0NCmZ1bmN0aW9uIGluamVjdFRvS2VlcEFsaXZlUm9vdChob29rLCB0eXBlLCB0YXJnZXQsIGtlZXBBbGl2ZVJvb3QpIHsNCiAgY29uc3QgaW5qZWN0ZWQgPSBpbmplY3RIb29rKA0KICAgIHR5cGUsDQogICAgaG9vaywNCiAgICBrZWVwQWxpdmVSb290LA0KICAgIHRydWUNCiAgICAvKiBwcmVwZW5kICovDQogICk7DQogIG9uVW5tb3VudGVkKCgpID0+IHsNCiAgICByZW1vdmUoa2VlcEFsaXZlUm9vdFt0eXBlXSwgaW5qZWN0ZWQpOw0KICB9LCB0YXJnZXQpOw0KfQ0KDQpmdW5jdGlvbiBpbmplY3RIb29rKHR5cGUsIGhvb2ssIHRhcmdldCA9IGN1cnJlbnRJbnN0YW5jZSwgcHJlcGVuZCA9IGZhbHNlKSB7DQogIGlmICh0YXJnZXQpIHsNCiAgICBjb25zdCBob29rcyA9IHRhcmdldFt0eXBlXSB8fCAodGFyZ2V0W3R5cGVdID0gW10pOw0KICAgIGNvbnN0IHdyYXBwZWRIb29rID0gaG9vay5fX3dlaCB8fCAoaG9vay5fX3dlaCA9ICguLi5hcmdzKSA9PiB7DQogICAgICBwYXVzZVRyYWNraW5nKCk7DQogICAgICBjb25zdCByZXNldCA9IHNldEN1cnJlbnRJbnN0YW5jZSh0YXJnZXQpOw0KICAgICAgY29uc3QgcmVzID0gY2FsbFdpdGhBc3luY0Vycm9ySGFuZGxpbmcoaG9vaywgdGFyZ2V0LCB0eXBlLCBhcmdzKTsNCiAgICAgIHJlc2V0KCk7DQogICAgICByZXNldFRyYWNraW5nKCk7DQogICAgICByZXR1cm4gcmVzOw0KICAgIH0pOw0KICAgIGlmIChwcmVwZW5kKSB7DQogICAgICBob29rcy51bnNoaWZ0KHdyYXBwZWRIb29rKTsNCiAgICB9IGVsc2Ugew0KICAgICAgaG9va3MucHVzaCh3cmFwcGVkSG9vayk7DQogICAgfQ0KICAgIHJldHVybiB3cmFwcGVkSG9vazsNCiAgfSBlbHNlIHsNCiAgICBjb25zdCBhcGlOYW1lID0gdG9IYW5kbGVyS2V5KEVycm9yVHlwZVN0cmluZ3NbdHlwZV0ucmVwbGFjZSgvIGhvb2skLywgIiIpKTsNCiAgICB3YXJuJDEoDQogICAgICBgJHthcGlOYW1lfSBpcyBjYWxsZWQgd2hlbiB0aGVyZSBpcyBubyBhY3RpdmUgY29tcG9uZW50IGluc3RhbmNlIHRvIGJlIGFzc29jaWF0ZWQgd2l0aC4gTGlmZWN5Y2xlIGluamVjdGlvbiBBUElzIGNhbiBvbmx5IGJlIHVzZWQgZHVyaW5nIGV4ZWN1dGlvbiBvZiBzZXR1cCgpLmAgKyAoYCBJZiB5b3UgYXJlIHVzaW5nIGFzeW5jIHNldHVwKCksIG1ha2Ugc3VyZSB0byByZWdpc3RlciBsaWZlY3ljbGUgaG9va3MgYmVmb3JlIHRoZSBmaXJzdCBhd2FpdCBzdGF0ZW1lbnQuYCApDQogICAgKTsNCiAgfQ0KfQ0KY29uc3QgY3JlYXRlSG9vayA9IChsaWZlY3ljbGUpID0+IChob29rLCB0YXJnZXQgPSBjdXJyZW50SW5zdGFuY2UpID0+IHsNCiAgaWYgKCFpc0luU1NSQ29tcG9uZW50U2V0dXAgfHwgbGlmZWN5Y2xlID09PSAic3AiKSB7DQogICAgaW5qZWN0SG9vayhsaWZlY3ljbGUsICguLi5hcmdzKSA9PiBob29rKC4uLmFyZ3MpLCB0YXJnZXQpOw0KICB9DQp9Ow0KY29uc3Qgb25CZWZvcmVNb3VudCA9IGNyZWF0ZUhvb2soImJtIik7DQpjb25zdCBvbk1vdW50ZWQgPSBjcmVhdGVIb29rKCJtIik7DQpjb25zdCBvbkJlZm9yZVVwZGF0ZSA9IGNyZWF0ZUhvb2soDQogICJidSINCik7DQpjb25zdCBvblVwZGF0ZWQgPSBjcmVhdGVIb29rKCJ1Iik7DQpjb25zdCBvbkJlZm9yZVVubW91bnQgPSBjcmVhdGVIb29rKA0KICAiYnVtIg0KKTsNCmNvbnN0IG9uVW5tb3VudGVkID0gY3JlYXRlSG9vaygidW0iKTsNCmNvbnN0IG9uU2VydmVyUHJlZmV0Y2ggPSBjcmVhdGVIb29rKA0KICAic3AiDQopOw0KY29uc3Qgb25SZW5kZXJUcmlnZ2VyZWQgPSBjcmVhdGVIb29rKCJydGciKTsNCmNvbnN0IG9uUmVuZGVyVHJhY2tlZCA9IGNyZWF0ZUhvb2soInJ0YyIpOw0KZnVuY3Rpb24gb25FcnJvckNhcHR1cmVkKGhvb2ssIHRhcmdldCA9IGN1cnJlbnRJbnN0YW5jZSkgew0KICBpbmplY3RIb29rKCJlYyIsIGhvb2ssIHRhcmdldCk7DQp9DQoNCmNvbnN0IE5VTExfRFlOQU1JQ19DT01QT05FTlQgPSBTeW1ib2wuZm9yKCJ2LW5kYyIpOw0KDQpmdW5jdGlvbiBlbnN1cmVWYWxpZFZOb2RlJDEodm5vZGVzKSB7DQogIHJldHVybiB2bm9kZXMuc29tZSgoY2hpbGQpID0+IHsNCiAgICBpZiAoIWlzVk5vZGUkMihjaGlsZCkpIHJldHVybiB0cnVlOw0KICAgIGlmIChjaGlsZC50eXBlID09PSBDb21tZW50KSByZXR1cm4gZmFsc2U7DQogICAgaWYgKGNoaWxkLnR5cGUgPT09IEZyYWdtZW50ICYmICFlbnN1cmVWYWxpZFZOb2RlJDEoY2hpbGQuY2hpbGRyZW4pKQ0KICAgICAgcmV0dXJuIGZhbHNlOw0KICAgIHJldHVybiB0cnVlOw0KICB9KSA/IHZub2RlcyA6IG51bGw7DQp9DQoNCmNvbnN0IGdldFB1YmxpY0luc3RhbmNlID0gKGkpID0+IHsNCiAgaWYgKCFpKSByZXR1cm4gbnVsbDsNCiAgaWYgKGlzU3RhdGVmdWxDb21wb25lbnQoaSkpIHJldHVybiBnZXRDb21wb25lbnRQdWJsaWNJbnN0YW5jZShpKTsNCiAgcmV0dXJuIGdldFB1YmxpY0luc3RhbmNlKGkucGFyZW50KTsNCn07DQpjb25zdCBwdWJsaWNQcm9wZXJ0aWVzTWFwID0gKA0KICAvLyBNb3ZlIFBVUkUgbWFya2VyIHRvIG5ldyBsaW5lIHRvIHdvcmthcm91bmQgY29tcGlsZXIgZGlzY2FyZGluZyBpdA0KICAvLyBkdWUgdG8gdHlwZSBhbm5vdGF0aW9uDQogIC8qIEBfX1BVUkVfXyAqLyBleHRlbmQoLyogQF9fUFVSRV9fICovIE9iamVjdC5jcmVhdGUobnVsbCksIHsNCiAgICAkOiAoaSkgPT4gaSwNCiAgICAkZWw6IChpKSA9PiBpLnZub2RlLmVsLA0KICAgICRkYXRhOiAoaSkgPT4gaS5kYXRhLA0KICAgICRwcm9wczogKGkpID0+IHNoYWxsb3dSZWFkb25seShpLnByb3BzKSAsDQogICAgJGF0dHJzOiAoaSkgPT4gc2hhbGxvd1JlYWRvbmx5KGkuYXR0cnMpICwNCiAgICAkc2xvdHM6IChpKSA9PiBzaGFsbG93UmVhZG9ubHkoaS5zbG90cykgLA0KICAgICRyZWZzOiAoaSkgPT4gc2hhbGxvd1JlYWRvbmx5KGkucmVmcykgLA0KICAgICRwYXJlbnQ6IChpKSA9PiBnZXRQdWJsaWNJbnN0YW5jZShpLnBhcmVudCksDQogICAgJHJvb3Q6IChpKSA9PiBnZXRQdWJsaWNJbnN0YW5jZShpLnJvb3QpLA0KICAgICRob3N0OiAoaSkgPT4gaS5jZSwNCiAgICAkZW1pdDogKGkpID0+IGkuZW1pdCwNCiAgICAkb3B0aW9uczogKGkpID0+IHJlc29sdmVNZXJnZWRPcHRpb25zKGkpICwNCiAgICAkZm9yY2VVcGRhdGU6IChpKSA9PiBpLmYgfHwgKGkuZiA9ICgpID0+IHsNCiAgICAgIHF1ZXVlSm9iKGkudXBkYXRlKTsNCiAgICB9KSwNCiAgICAkbmV4dFRpY2s6IChpKSA9PiBpLm4gfHwgKGkubiA9IG5leHRUaWNrLmJpbmQoaS5wcm94eSkpLA0KICAgICR3YXRjaDogKGkpID0+IGluc3RhbmNlV2F0Y2guYmluZChpKSANCiAgfSkNCik7DQpjb25zdCBpc1Jlc2VydmVkUHJlZml4ID0gKGtleSkgPT4ga2V5ID09PSAiXyIgfHwga2V5ID09PSAiJCI7DQpjb25zdCBoYXNTZXR1cEJpbmRpbmcgPSAoc3RhdGUsIGtleSkgPT4gc3RhdGUgIT09IEVNUFRZX09CSiAmJiAhc3RhdGUuX19pc1NjcmlwdFNldHVwICYmIGhhc093bihzdGF0ZSwga2V5KTsNCmNvbnN0IFB1YmxpY0luc3RhbmNlUHJveHlIYW5kbGVycyA9IHsNCiAgZ2V0KHsgXzogaW5zdGFuY2UgfSwga2V5KSB7DQogICAgaWYgKGtleSA9PT0gIl9fdl9za2lwIikgew0KICAgICAgcmV0dXJuIHRydWU7DQogICAgfQ0KICAgIGNvbnN0IHsgY3R4LCBzZXR1cFN0YXRlLCBkYXRhLCBwcm9wcywgYWNjZXNzQ2FjaGUsIHR5cGUsIGFwcENvbnRleHQgfSA9IGluc3RhbmNlOw0KICAgIGlmIChrZXkgPT09ICJfX2lzVnVlIikgew0KICAgICAgcmV0dXJuIHRydWU7DQogICAgfQ0KICAgIGxldCBub3JtYWxpemVkUHJvcHM7DQogICAgaWYgKGtleVswXSAhPT0gIiQiKSB7DQogICAgICBjb25zdCBuID0gYWNjZXNzQ2FjaGVba2V5XTsNCiAgICAgIGlmIChuICE9PSB2b2lkIDApIHsNCiAgICAgICAgc3dpdGNoIChuKSB7DQogICAgICAgICAgY2FzZSAxIC8qIFNFVFVQICovOg0KICAgICAgICAgICAgcmV0dXJuIHNldHVwU3RhdGVba2V5XTsNCiAgICAgICAgICBjYXNlIDIgLyogREFUQSAqLzoNCiAgICAgICAgICAgIHJldHVybiBkYXRhW2tleV07DQogICAgICAgICAgY2FzZSA0IC8qIENPTlRFWFQgKi86DQogICAgICAgICAgICByZXR1cm4gY3R4W2tleV07DQogICAgICAgICAgY2FzZSAzIC8qIFBST1BTICovOg0KICAgICAgICAgICAgcmV0dXJuIHByb3BzW2tleV07DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSBpZiAoaGFzU2V0dXBCaW5kaW5nKHNldHVwU3RhdGUsIGtleSkpIHsNCiAgICAgICAgYWNjZXNzQ2FjaGVba2V5XSA9IDEgLyogU0VUVVAgKi87DQogICAgICAgIHJldHVybiBzZXR1cFN0YXRlW2tleV07DQogICAgICB9IGVsc2UgaWYgKGRhdGEgIT09IEVNUFRZX09CSiAmJiBoYXNPd24oZGF0YSwga2V5KSkgew0KICAgICAgICBhY2Nlc3NDYWNoZVtrZXldID0gMiAvKiBEQVRBICovOw0KICAgICAgICByZXR1cm4gZGF0YVtrZXldOw0KICAgICAgfSBlbHNlIGlmICgNCiAgICAgICAgLy8gb25seSBjYWNoZSBvdGhlciBwcm9wZXJ0aWVzIHdoZW4gaW5zdGFuY2UgaGFzIGRlY2xhcmVkICh0aHVzIHN0YWJsZSkNCiAgICAgICAgLy8gcHJvcHMNCiAgICAgICAgKG5vcm1hbGl6ZWRQcm9wcyA9IGluc3RhbmNlLnByb3BzT3B0aW9uc1swXSkgJiYgaGFzT3duKG5vcm1hbGl6ZWRQcm9wcywga2V5KQ0KICAgICAgKSB7DQogICAgICAgIGFjY2Vzc0NhY2hlW2tleV0gPSAzIC8qIFBST1BTICovOw0KICAgICAgICByZXR1cm4gcHJvcHNba2V5XTsNCiAgICAgIH0gZWxzZSBpZiAoY3R4ICE9PSBFTVBUWV9PQkogJiYgaGFzT3duKGN0eCwga2V5KSkgew0KICAgICAgICBhY2Nlc3NDYWNoZVtrZXldID0gNCAvKiBDT05URVhUICovOw0KICAgICAgICByZXR1cm4gY3R4W2tleV07DQogICAgICB9IGVsc2UgaWYgKHNob3VsZENhY2hlQWNjZXNzKSB7DQogICAgICAgIGFjY2Vzc0NhY2hlW2tleV0gPSAwIC8qIE9USEVSICovOw0KICAgICAgfQ0KICAgIH0NCiAgICBjb25zdCBwdWJsaWNHZXR0ZXIgPSBwdWJsaWNQcm9wZXJ0aWVzTWFwW2tleV07DQogICAgbGV0IGNzc01vZHVsZSwgZ2xvYmFsUHJvcGVydGllczsNCiAgICBpZiAocHVibGljR2V0dGVyKSB7DQogICAgICBpZiAoa2V5ID09PSAiJGF0dHJzIikgew0KICAgICAgICB0cmFjayhpbnN0YW5jZS5hdHRycywgImdldCIsICIiKTsNCiAgICAgICAgbWFya0F0dHJzQWNjZXNzZWQoKTsNCiAgICAgIH0gZWxzZSBpZiAoa2V5ID09PSAiJHNsb3RzIikgew0KICAgICAgICB0cmFjayhpbnN0YW5jZSwgImdldCIsIGtleSk7DQogICAgICB9DQogICAgICByZXR1cm4gcHVibGljR2V0dGVyKGluc3RhbmNlKTsNCiAgICB9IGVsc2UgaWYgKA0KICAgICAgLy8gY3NzIG1vZHVsZSAoaW5qZWN0ZWQgYnkgdnVlLWxvYWRlcikNCiAgICAgIChjc3NNb2R1bGUgPSB0eXBlLl9fY3NzTW9kdWxlcykgJiYgKGNzc01vZHVsZSA9IGNzc01vZHVsZVtrZXldKQ0KICAgICkgew0KICAgICAgcmV0dXJuIGNzc01vZHVsZTsNCiAgICB9IGVsc2UgaWYgKGN0eCAhPT0gRU1QVFlfT0JKICYmIGhhc093bihjdHgsIGtleSkpIHsNCiAgICAgIGFjY2Vzc0NhY2hlW2tleV0gPSA0IC8qIENPTlRFWFQgKi87DQogICAgICByZXR1cm4gY3R4W2tleV07DQogICAgfSBlbHNlIGlmICgNCiAgICAgIC8vIGdsb2JhbCBwcm9wZXJ0aWVzDQogICAgICBnbG9iYWxQcm9wZXJ0aWVzID0gYXBwQ29udGV4dC5jb25maWcuZ2xvYmFsUHJvcGVydGllcywgaGFzT3duKGdsb2JhbFByb3BlcnRpZXMsIGtleSkNCiAgICApIHsNCiAgICAgIHsNCiAgICAgICAgcmV0dXJuIGdsb2JhbFByb3BlcnRpZXNba2V5XTsNCiAgICAgIH0NCiAgICB9IGVsc2UgaWYgKGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSAmJiAoIWlzU3RyaW5nKGtleSkgfHwgLy8gIzEwOTEgYXZvaWQgaW50ZXJuYWwgaXNSZWYvaXNWTm9kZSBjaGVja3Mgb24gY29tcG9uZW50IGluc3RhbmNlIGxlYWRpbmcNCiAgICAvLyB0byBpbmZpbml0ZSB3YXJuaW5nIGxvb3ANCiAgICBrZXkuaW5kZXhPZigiX192IikgIT09IDApKSB7DQogICAgICBpZiAoZGF0YSAhPT0gRU1QVFlfT0JKICYmIGlzUmVzZXJ2ZWRQcmVmaXgoa2V5WzBdKSAmJiBoYXNPd24oZGF0YSwga2V5KSkgew0KICAgICAgICB3YXJuJDEoDQogICAgICAgICAgYFByb3BlcnR5ICR7SlNPTi5zdHJpbmdpZnkoDQogICAgICAgICAgICBrZXkNCiAgICAgICAgICApfSBtdXN0IGJlIGFjY2Vzc2VkIHZpYSAkZGF0YSBiZWNhdXNlIGl0IHN0YXJ0cyB3aXRoIGEgcmVzZXJ2ZWQgY2hhcmFjdGVyICgiJCIgb3IgIl8iKSBhbmQgaXMgbm90IHByb3hpZWQgb24gdGhlIHJlbmRlciBjb250ZXh0LmANCiAgICAgICAgKTsNCiAgICAgIH0gZWxzZSBpZiAoaW5zdGFuY2UgPT09IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSkgew0KICAgICAgICB3YXJuJDEoDQogICAgICAgICAgYFByb3BlcnR5ICR7SlNPTi5zdHJpbmdpZnkoa2V5KX0gd2FzIGFjY2Vzc2VkIGR1cmluZyByZW5kZXIgYnV0IGlzIG5vdCBkZWZpbmVkIG9uIGluc3RhbmNlLmANCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICB9DQogIH0sDQogIHNldCh7IF86IGluc3RhbmNlIH0sIGtleSwgdmFsdWUpIHsNCiAgICBjb25zdCB7IGRhdGEsIHNldHVwU3RhdGUsIGN0eCB9ID0gaW5zdGFuY2U7DQogICAgaWYgKGhhc1NldHVwQmluZGluZyhzZXR1cFN0YXRlLCBrZXkpKSB7DQogICAgICBzZXR1cFN0YXRlW2tleV0gPSB2YWx1ZTsNCiAgICAgIHJldHVybiB0cnVlOw0KICAgIH0gZWxzZSBpZiAoc2V0dXBTdGF0ZS5fX2lzU2NyaXB0U2V0dXAgJiYgaGFzT3duKHNldHVwU3RhdGUsIGtleSkpIHsNCiAgICAgIHdhcm4kMShgQ2Fubm90IG11dGF0ZSA8c2NyaXB0IHNldHVwPiBiaW5kaW5nICIke2tleX0iIGZyb20gT3B0aW9ucyBBUEkuYCk7DQogICAgICByZXR1cm4gZmFsc2U7DQogICAgfSBlbHNlIGlmIChkYXRhICE9PSBFTVBUWV9PQkogJiYgaGFzT3duKGRhdGEsIGtleSkpIHsNCiAgICAgIGRhdGFba2V5XSA9IHZhbHVlOw0KICAgICAgcmV0dXJuIHRydWU7DQogICAgfSBlbHNlIGlmIChoYXNPd24oaW5zdGFuY2UucHJvcHMsIGtleSkpIHsNCiAgICAgIHdhcm4kMShgQXR0ZW1wdGluZyB0byBtdXRhdGUgcHJvcCAiJHtrZXl9Ii4gUHJvcHMgYXJlIHJlYWRvbmx5LmApOw0KICAgICAgcmV0dXJuIGZhbHNlOw0KICAgIH0NCiAgICBpZiAoa2V5WzBdID09PSAiJCIgJiYga2V5LnNsaWNlKDEpIGluIGluc3RhbmNlKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGBBdHRlbXB0aW5nIHRvIG11dGF0ZSBwdWJsaWMgcHJvcGVydHkgIiR7a2V5fSIuIFByb3BlcnRpZXMgc3RhcnRpbmcgd2l0aCAkIGFyZSByZXNlcnZlZCBhbmQgcmVhZG9ubHkuYA0KICAgICAgKTsNCiAgICAgIHJldHVybiBmYWxzZTsNCiAgICB9IGVsc2Ugew0KICAgICAgaWYgKGtleSBpbiBpbnN0YW5jZS5hcHBDb250ZXh0LmNvbmZpZy5nbG9iYWxQcm9wZXJ0aWVzKSB7DQogICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIGtleSwgew0KICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsDQogICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLA0KICAgICAgICAgIHZhbHVlDQogICAgICAgIH0pOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgY3R4W2tleV0gPSB2YWx1ZTsNCiAgICAgIH0NCiAgICB9DQogICAgcmV0dXJuIHRydWU7DQogIH0sDQogIGhhcyh7DQogICAgXzogeyBkYXRhLCBzZXR1cFN0YXRlLCBhY2Nlc3NDYWNoZSwgY3R4LCBhcHBDb250ZXh0LCBwcm9wc09wdGlvbnMgfQ0KICB9LCBrZXkpIHsNCiAgICBsZXQgbm9ybWFsaXplZFByb3BzOw0KICAgIHJldHVybiAhIWFjY2Vzc0NhY2hlW2tleV0gfHwgZGF0YSAhPT0gRU1QVFlfT0JKICYmIGhhc093bihkYXRhLCBrZXkpIHx8IGhhc1NldHVwQmluZGluZyhzZXR1cFN0YXRlLCBrZXkpIHx8IChub3JtYWxpemVkUHJvcHMgPSBwcm9wc09wdGlvbnNbMF0pICYmIGhhc093bihub3JtYWxpemVkUHJvcHMsIGtleSkgfHwgaGFzT3duKGN0eCwga2V5KSB8fCBoYXNPd24ocHVibGljUHJvcGVydGllc01hcCwga2V5KSB8fCBoYXNPd24oYXBwQ29udGV4dC5jb25maWcuZ2xvYmFsUHJvcGVydGllcywga2V5KTsNCiAgfSwNCiAgZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIGRlc2NyaXB0b3IpIHsNCiAgICBpZiAoZGVzY3JpcHRvci5nZXQgIT0gbnVsbCkgew0KICAgICAgdGFyZ2V0Ll8uYWNjZXNzQ2FjaGVba2V5XSA9IDA7DQogICAgfSBlbHNlIGlmIChoYXNPd24oZGVzY3JpcHRvciwgInZhbHVlIikpIHsNCiAgICAgIHRoaXMuc2V0KHRhcmdldCwga2V5LCBkZXNjcmlwdG9yLnZhbHVlLCBudWxsKTsNCiAgICB9DQogICAgcmV0dXJuIFJlZmxlY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIGRlc2NyaXB0b3IpOw0KICB9DQp9Ow0Kew0KICBQdWJsaWNJbnN0YW5jZVByb3h5SGFuZGxlcnMub3duS2V5cyA9ICh0YXJnZXQpID0+IHsNCiAgICB3YXJuJDEoDQogICAgICBgQXZvaWQgYXBwIGxvZ2ljIHRoYXQgcmVsaWVzIG9uIGVudW1lcmF0aW5nIGtleXMgb24gYSBjb21wb25lbnQgaW5zdGFuY2UuIFRoZSBrZXlzIHdpbGwgYmUgZW1wdHkgaW4gcHJvZHVjdGlvbiBtb2RlIHRvIGF2b2lkIHBlcmZvcm1hbmNlIG92ZXJoZWFkLmANCiAgICApOw0KICAgIHJldHVybiBSZWZsZWN0Lm93bktleXModGFyZ2V0KTsNCiAgfTsNCn0NCmZ1bmN0aW9uIGNyZWF0ZURldlJlbmRlckNvbnRleHQoaW5zdGFuY2UpIHsNCiAgY29uc3QgdGFyZ2V0ID0ge307DQogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGBfYCwgew0KICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSwNCiAgICBlbnVtZXJhYmxlOiBmYWxzZSwNCiAgICBnZXQ6ICgpID0+IGluc3RhbmNlDQogIH0pOw0KICBPYmplY3Qua2V5cyhwdWJsaWNQcm9wZXJ0aWVzTWFwKS5mb3JFYWNoKChrZXkpID0+IHsNCiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHsNCiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSwNCiAgICAgIGVudW1lcmFibGU6IGZhbHNlLA0KICAgICAgZ2V0OiAoKSA9PiBwdWJsaWNQcm9wZXJ0aWVzTWFwW2tleV0oaW5zdGFuY2UpLA0KICAgICAgLy8gaW50ZXJjZXB0ZWQgYnkgdGhlIHByb3h5IHNvIG5vIG5lZWQgZm9yIGltcGxlbWVudGF0aW9uLA0KICAgICAgLy8gYnV0IG5lZWRlZCB0byBwcmV2ZW50IHNldCBlcnJvcnMNCiAgICAgIHNldDogTk9PUA0KICAgIH0pOw0KICB9KTsNCiAgcmV0dXJuIHRhcmdldDsNCn0NCmZ1bmN0aW9uIGV4cG9zZVByb3BzT25SZW5kZXJDb250ZXh0KGluc3RhbmNlKSB7DQogIGNvbnN0IHsNCiAgICBjdHgsDQogICAgcHJvcHNPcHRpb25zOiBbcHJvcHNPcHRpb25zXQ0KICB9ID0gaW5zdGFuY2U7DQogIGlmIChwcm9wc09wdGlvbnMpIHsNCiAgICBPYmplY3Qua2V5cyhwcm9wc09wdGlvbnMpLmZvckVhY2goKGtleSkgPT4gew0KICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGN0eCwga2V5LCB7DQogICAgICAgIGVudW1lcmFibGU6IHRydWUsDQogICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSwNCiAgICAgICAgZ2V0OiAoKSA9PiBpbnN0YW5jZS5wcm9wc1trZXldLA0KICAgICAgICBzZXQ6IE5PT1ANCiAgICAgIH0pOw0KICAgIH0pOw0KICB9DQp9DQpmdW5jdGlvbiBleHBvc2VTZXR1cFN0YXRlT25SZW5kZXJDb250ZXh0KGluc3RhbmNlKSB7DQogIGNvbnN0IHsgY3R4LCBzZXR1cFN0YXRlIH0gPSBpbnN0YW5jZTsNCiAgT2JqZWN0LmtleXModG9SYXcoc2V0dXBTdGF0ZSkpLmZvckVhY2goKGtleSkgPT4gew0KICAgIGlmICghc2V0dXBTdGF0ZS5fX2lzU2NyaXB0U2V0dXApIHsNCiAgICAgIGlmIChpc1Jlc2VydmVkUHJlZml4KGtleVswXSkpIHsNCiAgICAgICAgd2FybiQxKA0KICAgICAgICAgIGBzZXR1cCgpIHJldHVybiBwcm9wZXJ0eSAke0pTT04uc3RyaW5naWZ5KA0KICAgICAgICAgICAga2V5DQogICAgICAgICAgKX0gc2hvdWxkIG5vdCBzdGFydCB3aXRoICIkIiBvciAiXyIgd2hpY2ggYXJlIHJlc2VydmVkIHByZWZpeGVzIGZvciBWdWUgaW50ZXJuYWxzLmANCiAgICAgICAgKTsNCiAgICAgICAgcmV0dXJuOw0KICAgICAgfQ0KICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGN0eCwga2V5LCB7DQogICAgICAgIGVudW1lcmFibGU6IHRydWUsDQogICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSwNCiAgICAgICAgZ2V0OiAoKSA9PiBzZXR1cFN0YXRlW2tleV0sDQogICAgICAgIHNldDogTk9PUA0KICAgICAgfSk7DQogICAgfQ0KICB9KTsNCn0NCg0KZnVuY3Rpb24gbm9ybWFsaXplUHJvcHNPckVtaXRzKHByb3BzKSB7DQogIHJldHVybiBpc0FycmF5KHByb3BzKSA/IHByb3BzLnJlZHVjZSgNCiAgICAobm9ybWFsaXplZCwgcCkgPT4gKG5vcm1hbGl6ZWRbcF0gPSBudWxsLCBub3JtYWxpemVkKSwNCiAgICB7fQ0KICApIDogcHJvcHM7DQp9DQoNCmZ1bmN0aW9uIGNyZWF0ZUR1cGxpY2F0ZUNoZWNrZXIoKSB7DQogIGNvbnN0IGNhY2hlID0gLyogQF9fUFVSRV9fICovIE9iamVjdC5jcmVhdGUobnVsbCk7DQogIHJldHVybiAodHlwZSwga2V5KSA9PiB7DQogICAgaWYgKGNhY2hlW2tleV0pIHsNCiAgICAgIHdhcm4kMShgJHt0eXBlfSBwcm9wZXJ0eSAiJHtrZXl9IiBpcyBhbHJlYWR5IGRlZmluZWQgaW4gJHtjYWNoZVtrZXldfS5gKTsNCiAgICB9IGVsc2Ugew0KICAgICAgY2FjaGVba2V5XSA9IHR5cGU7DQogICAgfQ0KICB9Ow0KfQ0KbGV0IHNob3VsZENhY2hlQWNjZXNzID0gdHJ1ZTsNCmZ1bmN0aW9uIGFwcGx5T3B0aW9ucyhpbnN0YW5jZSkgew0KICBjb25zdCBvcHRpb25zID0gcmVzb2x2ZU1lcmdlZE9wdGlvbnMoaW5zdGFuY2UpOw0KICBjb25zdCBwdWJsaWNUaGlzID0gaW5zdGFuY2UucHJveHk7DQogIGNvbnN0IGN0eCA9IGluc3RhbmNlLmN0eDsNCiAgc2hvdWxkQ2FjaGVBY2Nlc3MgPSBmYWxzZTsNCiAgaWYgKG9wdGlvbnMuYmVmb3JlQ3JlYXRlKSB7DQogICAgY2FsbEhvb2sob3B0aW9ucy5iZWZvcmVDcmVhdGUsIGluc3RhbmNlLCAiYmMiKTsNCiAgfQ0KICBjb25zdCB7DQogICAgLy8gc3RhdGUNCiAgICBkYXRhOiBkYXRhT3B0aW9ucywNCiAgICBjb21wdXRlZDogY29tcHV0ZWRPcHRpb25zLA0KICAgIG1ldGhvZHMsDQogICAgd2F0Y2g6IHdhdGNoT3B0aW9ucywNCiAgICBwcm92aWRlOiBwcm92aWRlT3B0aW9ucywNCiAgICBpbmplY3Q6IGluamVjdE9wdGlvbnMsDQogICAgLy8gbGlmZWN5Y2xlDQogICAgY3JlYXRlZCwNCiAgICBiZWZvcmVNb3VudCwNCiAgICBtb3VudGVkLA0KICAgIGJlZm9yZVVwZGF0ZSwNCiAgICB1cGRhdGVkLA0KICAgIGFjdGl2YXRlZCwNCiAgICBkZWFjdGl2YXRlZCwNCiAgICBiZWZvcmVEZXN0cm95LA0KICAgIGJlZm9yZVVubW91bnQsDQogICAgZGVzdHJveWVkLA0KICAgIHVubW91bnRlZCwNCiAgICByZW5kZXIsDQogICAgcmVuZGVyVHJhY2tlZCwNCiAgICByZW5kZXJUcmlnZ2VyZWQsDQogICAgZXJyb3JDYXB0dXJlZCwNCiAgICBzZXJ2ZXJQcmVmZXRjaCwNCiAgICAvLyBwdWJsaWMgQVBJDQogICAgZXhwb3NlLA0KICAgIGluaGVyaXRBdHRycywNCiAgICAvLyBhc3NldHMNCiAgICBjb21wb25lbnRzLA0KICAgIGRpcmVjdGl2ZXMsDQogICAgZmlsdGVycw0KICB9ID0gb3B0aW9uczsNCiAgY29uc3QgY2hlY2tEdXBsaWNhdGVQcm9wZXJ0aWVzID0gY3JlYXRlRHVwbGljYXRlQ2hlY2tlcigpIDsNCiAgew0KICAgIGNvbnN0IFtwcm9wc09wdGlvbnNdID0gaW5zdGFuY2UucHJvcHNPcHRpb25zOw0KICAgIGlmIChwcm9wc09wdGlvbnMpIHsNCiAgICAgIGZvciAoY29uc3Qga2V5IGluIHByb3BzT3B0aW9ucykgew0KICAgICAgICBjaGVja0R1cGxpY2F0ZVByb3BlcnRpZXMoIlByb3BzIiAvKiBQUk9QUyAqLywga2V5KTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgaWYgKGluamVjdE9wdGlvbnMpIHsNCiAgICByZXNvbHZlSW5qZWN0aW9ucyhpbmplY3RPcHRpb25zLCBjdHgsIGNoZWNrRHVwbGljYXRlUHJvcGVydGllcyk7DQogIH0NCiAgaWYgKG1ldGhvZHMpIHsNCiAgICBmb3IgKGNvbnN0IGtleSBpbiBtZXRob2RzKSB7DQogICAgICBjb25zdCBtZXRob2RIYW5kbGVyID0gbWV0aG9kc1trZXldOw0KICAgICAgaWYgKGlzRnVuY3Rpb24obWV0aG9kSGFuZGxlcikpIHsNCiAgICAgICAgew0KICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIGtleSwgew0KICAgICAgICAgICAgdmFsdWU6IG1ldGhvZEhhbmRsZXIuYmluZChwdWJsaWNUaGlzKSwNCiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSwNCiAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsDQogICAgICAgICAgICB3cml0YWJsZTogdHJ1ZQ0KICAgICAgICAgIH0pOw0KICAgICAgICB9DQogICAgICAgIHsNCiAgICAgICAgICBjaGVja0R1cGxpY2F0ZVByb3BlcnRpZXMoIk1ldGhvZHMiIC8qIE1FVEhPRFMgKi8sIGtleSk7DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHdhcm4kMSgNCiAgICAgICAgICBgTWV0aG9kICIke2tleX0iIGhhcyB0eXBlICIke3R5cGVvZiBtZXRob2RIYW5kbGVyfSIgaW4gdGhlIGNvbXBvbmVudCBkZWZpbml0aW9uLiBEaWQgeW91IHJlZmVyZW5jZSB0aGUgZnVuY3Rpb24gY29ycmVjdGx5P2ANCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgaWYgKGRhdGFPcHRpb25zKSB7DQogICAgaWYgKCFpc0Z1bmN0aW9uKGRhdGFPcHRpb25zKSkgew0KICAgICAgd2FybiQxKA0KICAgICAgICBgVGhlIGRhdGEgb3B0aW9uIG11c3QgYmUgYSBmdW5jdGlvbi4gUGxhaW4gb2JqZWN0IHVzYWdlIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWQuYA0KICAgICAgKTsNCiAgICB9DQogICAgY29uc3QgZGF0YSA9IGRhdGFPcHRpb25zLmNhbGwocHVibGljVGhpcywgcHVibGljVGhpcyk7DQogICAgaWYgKGlzUHJvbWlzZShkYXRhKSkgew0KICAgICAgd2FybiQxKA0KICAgICAgICBgZGF0YSgpIHJldHVybmVkIGEgUHJvbWlzZSAtIG5vdGUgZGF0YSgpIGNhbm5vdCBiZSBhc3luYzsgSWYgeW91IGludGVuZCB0byBwZXJmb3JtIGRhdGEgZmV0Y2hpbmcgYmVmb3JlIGNvbXBvbmVudCByZW5kZXJzLCB1c2UgYXN5bmMgc2V0dXAoKSArIDxTdXNwZW5zZT4uYA0KICAgICAgKTsNCiAgICB9DQogICAgaWYgKCFpc09iamVjdChkYXRhKSkgew0KICAgICAgd2FybiQxKGBkYXRhKCkgc2hvdWxkIHJldHVybiBhbiBvYmplY3QuYCk7DQogICAgfSBlbHNlIHsNCiAgICAgIGluc3RhbmNlLmRhdGEgPSByZWFjdGl2ZShkYXRhKTsNCiAgICAgIHsNCiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gZGF0YSkgew0KICAgICAgICAgIGNoZWNrRHVwbGljYXRlUHJvcGVydGllcygiRGF0YSIgLyogREFUQSAqLywga2V5KTsNCiAgICAgICAgICBpZiAoIWlzUmVzZXJ2ZWRQcmVmaXgoa2V5WzBdKSkgew0KICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGN0eCwga2V5LCB7DQogICAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSwNCiAgICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSwNCiAgICAgICAgICAgICAgZ2V0OiAoKSA9PiBkYXRhW2tleV0sDQogICAgICAgICAgICAgIHNldDogTk9PUA0KICAgICAgICAgICAgfSk7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICB9DQogIHNob3VsZENhY2hlQWNjZXNzID0gdHJ1ZTsNCiAgaWYgKGNvbXB1dGVkT3B0aW9ucykgew0KICAgIGZvciAoY29uc3Qga2V5IGluIGNvbXB1dGVkT3B0aW9ucykgew0KICAgICAgY29uc3Qgb3B0ID0gY29tcHV0ZWRPcHRpb25zW2tleV07DQogICAgICBjb25zdCBnZXQgPSBpc0Z1bmN0aW9uKG9wdCkgPyBvcHQuYmluZChwdWJsaWNUaGlzLCBwdWJsaWNUaGlzKSA6IGlzRnVuY3Rpb24ob3B0LmdldCkgPyBvcHQuZ2V0LmJpbmQocHVibGljVGhpcywgcHVibGljVGhpcykgOiBOT09QOw0KICAgICAgaWYgKGdldCA9PT0gTk9PUCkgew0KICAgICAgICB3YXJuJDEoYENvbXB1dGVkIHByb3BlcnR5ICIke2tleX0iIGhhcyBubyBnZXR0ZXIuYCk7DQogICAgICB9DQogICAgICBjb25zdCBzZXQgPSAhaXNGdW5jdGlvbihvcHQpICYmIGlzRnVuY3Rpb24ob3B0LnNldCkgPyBvcHQuc2V0LmJpbmQocHVibGljVGhpcykgOiAoKSA9PiB7DQogICAgICAgIHdhcm4kMSgNCiAgICAgICAgICBgV3JpdGUgb3BlcmF0aW9uIGZhaWxlZDogY29tcHV0ZWQgcHJvcGVydHkgIiR7a2V5fSIgaXMgcmVhZG9ubHkuYA0KICAgICAgICApOw0KICAgICAgfSA7DQogICAgICBjb25zdCBjID0gY29tcHV0ZWQoew0KICAgICAgICBnZXQsDQogICAgICAgIHNldA0KICAgICAgfSk7DQogICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY3R4LCBrZXksIHsNCiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSwNCiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLA0KICAgICAgICBnZXQ6ICgpID0+IGMudmFsdWUsDQogICAgICAgIHNldDogKHYpID0+IGMudmFsdWUgPSB2DQogICAgICB9KTsNCiAgICAgIHsNCiAgICAgICAgY2hlY2tEdXBsaWNhdGVQcm9wZXJ0aWVzKCJDb21wdXRlZCIgLyogQ09NUFVURUQgKi8sIGtleSk7DQogICAgICB9DQogICAgfQ0KICB9DQogIGlmICh3YXRjaE9wdGlvbnMpIHsNCiAgICBmb3IgKGNvbnN0IGtleSBpbiB3YXRjaE9wdGlvbnMpIHsNCiAgICAgIGNyZWF0ZVdhdGNoZXIod2F0Y2hPcHRpb25zW2tleV0sIGN0eCwgcHVibGljVGhpcywga2V5KTsNCiAgICB9DQogIH0NCiAgaWYgKHByb3ZpZGVPcHRpb25zKSB7DQogICAgY29uc3QgcHJvdmlkZXMgPSBpc0Z1bmN0aW9uKHByb3ZpZGVPcHRpb25zKSA/IHByb3ZpZGVPcHRpb25zLmNhbGwocHVibGljVGhpcykgOiBwcm92aWRlT3B0aW9uczsNCiAgICBSZWZsZWN0Lm93bktleXMocHJvdmlkZXMpLmZvckVhY2goKGtleSkgPT4gew0KICAgICAgcHJvdmlkZShrZXksIHByb3ZpZGVzW2tleV0pOw0KICAgIH0pOw0KICB9DQogIGlmIChjcmVhdGVkKSB7DQogICAgY2FsbEhvb2soY3JlYXRlZCwgaW5zdGFuY2UsICJjIik7DQogIH0NCiAgZnVuY3Rpb24gcmVnaXN0ZXJMaWZlY3ljbGVIb29rKHJlZ2lzdGVyLCBob29rKSB7DQogICAgaWYgKGlzQXJyYXkoaG9vaykpIHsNCiAgICAgIGhvb2suZm9yRWFjaCgoX2hvb2spID0+IHJlZ2lzdGVyKF9ob29rLmJpbmQocHVibGljVGhpcykpKTsNCiAgICB9IGVsc2UgaWYgKGhvb2spIHsNCiAgICAgIHJlZ2lzdGVyKGhvb2suYmluZChwdWJsaWNUaGlzKSk7DQogICAgfQ0KICB9DQogIHJlZ2lzdGVyTGlmZWN5Y2xlSG9vayhvbkJlZm9yZU1vdW50LCBiZWZvcmVNb3VudCk7DQogIHJlZ2lzdGVyTGlmZWN5Y2xlSG9vayhvbk1vdW50ZWQsIG1vdW50ZWQpOw0KICByZWdpc3RlckxpZmVjeWNsZUhvb2sob25CZWZvcmVVcGRhdGUsIGJlZm9yZVVwZGF0ZSk7DQogIHJlZ2lzdGVyTGlmZWN5Y2xlSG9vayhvblVwZGF0ZWQsIHVwZGF0ZWQpOw0KICByZWdpc3RlckxpZmVjeWNsZUhvb2sob25BY3RpdmF0ZWQsIGFjdGl2YXRlZCk7DQogIHJlZ2lzdGVyTGlmZWN5Y2xlSG9vayhvbkRlYWN0aXZhdGVkLCBkZWFjdGl2YXRlZCk7DQogIHJlZ2lzdGVyTGlmZWN5Y2xlSG9vayhvbkVycm9yQ2FwdHVyZWQsIGVycm9yQ2FwdHVyZWQpOw0KICByZWdpc3RlckxpZmVjeWNsZUhvb2sob25SZW5kZXJUcmFja2VkLCByZW5kZXJUcmFja2VkKTsNCiAgcmVnaXN0ZXJMaWZlY3ljbGVIb29rKG9uUmVuZGVyVHJpZ2dlcmVkLCByZW5kZXJUcmlnZ2VyZWQpOw0KICByZWdpc3RlckxpZmVjeWNsZUhvb2sob25CZWZvcmVVbm1vdW50LCBiZWZvcmVVbm1vdW50KTsNCiAgcmVnaXN0ZXJMaWZlY3ljbGVIb29rKG9uVW5tb3VudGVkLCB1bm1vdW50ZWQpOw0KICByZWdpc3RlckxpZmVjeWNsZUhvb2sob25TZXJ2ZXJQcmVmZXRjaCwgc2VydmVyUHJlZmV0Y2gpOw0KICBpZiAoaXNBcnJheShleHBvc2UpKSB7DQogICAgaWYgKGV4cG9zZS5sZW5ndGgpIHsNCiAgICAgIGNvbnN0IGV4cG9zZWQgPSBpbnN0YW5jZS5leHBvc2VkIHx8IChpbnN0YW5jZS5leHBvc2VkID0ge30pOw0KICAgICAgZXhwb3NlLmZvckVhY2goKGtleSkgPT4gew0KICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3NlZCwga2V5LCB7DQogICAgICAgICAgZ2V0OiAoKSA9PiBwdWJsaWNUaGlzW2tleV0sDQogICAgICAgICAgc2V0OiAodmFsKSA9PiBwdWJsaWNUaGlzW2tleV0gPSB2YWwNCiAgICAgICAgfSk7DQogICAgICB9KTsNCiAgICB9IGVsc2UgaWYgKCFpbnN0YW5jZS5leHBvc2VkKSB7DQogICAgICBpbnN0YW5jZS5leHBvc2VkID0ge307DQogICAgfQ0KICB9DQogIGlmIChyZW5kZXIgJiYgaW5zdGFuY2UucmVuZGVyID09PSBOT09QKSB7DQogICAgaW5zdGFuY2UucmVuZGVyID0gcmVuZGVyOw0KICB9DQogIGlmIChpbmhlcml0QXR0cnMgIT0gbnVsbCkgew0KICAgIGluc3RhbmNlLmluaGVyaXRBdHRycyA9IGluaGVyaXRBdHRyczsNCiAgfQ0KICBpZiAoY29tcG9uZW50cykgaW5zdGFuY2UuY29tcG9uZW50cyA9IGNvbXBvbmVudHM7DQogIGlmIChkaXJlY3RpdmVzKSBpbnN0YW5jZS5kaXJlY3RpdmVzID0gZGlyZWN0aXZlczsNCiAgaWYgKHNlcnZlclByZWZldGNoKSB7DQogICAgbWFya0FzeW5jQm91bmRhcnkoaW5zdGFuY2UpOw0KICB9DQp9DQpmdW5jdGlvbiByZXNvbHZlSW5qZWN0aW9ucyhpbmplY3RPcHRpb25zLCBjdHgsIGNoZWNrRHVwbGljYXRlUHJvcGVydGllcyA9IE5PT1ApIHsNCiAgaWYgKGlzQXJyYXkoaW5qZWN0T3B0aW9ucykpIHsNCiAgICBpbmplY3RPcHRpb25zID0gbm9ybWFsaXplSW5qZWN0KGluamVjdE9wdGlvbnMpOw0KICB9DQogIGZvciAoY29uc3Qga2V5IGluIGluamVjdE9wdGlvbnMpIHsNCiAgICBjb25zdCBvcHQgPSBpbmplY3RPcHRpb25zW2tleV07DQogICAgbGV0IGluamVjdGVkOw0KICAgIGlmIChpc09iamVjdChvcHQpKSB7DQogICAgICBpZiAoImRlZmF1bHQiIGluIG9wdCkgew0KICAgICAgICBpbmplY3RlZCA9IGluamVjdCgNCiAgICAgICAgICBvcHQuZnJvbSB8fCBrZXksDQogICAgICAgICAgb3B0LmRlZmF1bHQsDQogICAgICAgICAgdHJ1ZQ0KICAgICAgICApOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgaW5qZWN0ZWQgPSBpbmplY3Qob3B0LmZyb20gfHwga2V5KTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgaW5qZWN0ZWQgPSBpbmplY3Qob3B0KTsNCiAgICB9DQogICAgaWYgKGlzUmVmKGluamVjdGVkKSkgew0KICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGN0eCwga2V5LCB7DQogICAgICAgIGVudW1lcmFibGU6IHRydWUsDQogICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSwNCiAgICAgICAgZ2V0OiAoKSA9PiBpbmplY3RlZC52YWx1ZSwNCiAgICAgICAgc2V0OiAodikgPT4gaW5qZWN0ZWQudmFsdWUgPSB2DQogICAgICB9KTsNCiAgICB9IGVsc2Ugew0KICAgICAgY3R4W2tleV0gPSBpbmplY3RlZDsNCiAgICB9DQogICAgew0KICAgICAgY2hlY2tEdXBsaWNhdGVQcm9wZXJ0aWVzKCJJbmplY3QiIC8qIElOSkVDVCAqLywga2V5KTsNCiAgICB9DQogIH0NCn0NCmZ1bmN0aW9uIGNhbGxIb29rKGhvb2ssIGluc3RhbmNlLCB0eXBlKSB7DQogIGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nKA0KICAgIGlzQXJyYXkoaG9vaykgPyBob29rLm1hcCgoaCkgPT4gaC5iaW5kKGluc3RhbmNlLnByb3h5KSkgOiBob29rLmJpbmQoaW5zdGFuY2UucHJveHkpLA0KICAgIGluc3RhbmNlLA0KICAgIHR5cGUNCiAgKTsNCn0NCmZ1bmN0aW9uIGNyZWF0ZVdhdGNoZXIocmF3LCBjdHgsIHB1YmxpY1RoaXMsIGtleSkgew0KICBsZXQgZ2V0dGVyID0ga2V5LmluY2x1ZGVzKCIuIikgPyBjcmVhdGVQYXRoR2V0dGVyKHB1YmxpY1RoaXMsIGtleSkgOiAoKSA9PiBwdWJsaWNUaGlzW2tleV07DQogIGlmIChpc1N0cmluZyhyYXcpKSB7DQogICAgY29uc3QgaGFuZGxlciA9IGN0eFtyYXddOw0KICAgIGlmIChpc0Z1bmN0aW9uKGhhbmRsZXIpKSB7DQogICAgICB7DQogICAgICAgIHdhdGNoKGdldHRlciwgaGFuZGxlcik7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIHdhcm4kMShgSW52YWxpZCB3YXRjaCBoYW5kbGVyIHNwZWNpZmllZCBieSBrZXkgIiR7cmF3fSJgLCBoYW5kbGVyKTsNCiAgICB9DQogIH0gZWxzZSBpZiAoaXNGdW5jdGlvbihyYXcpKSB7DQogICAgew0KICAgICAgd2F0Y2goZ2V0dGVyLCByYXcuYmluZChwdWJsaWNUaGlzKSk7DQogICAgfQ0KICB9IGVsc2UgaWYgKGlzT2JqZWN0KHJhdykpIHsNCiAgICBpZiAoaXNBcnJheShyYXcpKSB7DQogICAgICByYXcuZm9yRWFjaCgocikgPT4gY3JlYXRlV2F0Y2hlcihyLCBjdHgsIHB1YmxpY1RoaXMsIGtleSkpOw0KICAgIH0gZWxzZSB7DQogICAgICBjb25zdCBoYW5kbGVyID0gaXNGdW5jdGlvbihyYXcuaGFuZGxlcikgPyByYXcuaGFuZGxlci5iaW5kKHB1YmxpY1RoaXMpIDogY3R4W3Jhdy5oYW5kbGVyXTsNCiAgICAgIGlmIChpc0Z1bmN0aW9uKGhhbmRsZXIpKSB7DQogICAgICAgIHdhdGNoKGdldHRlciwgaGFuZGxlciwgcmF3KTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHdhcm4kMShgSW52YWxpZCB3YXRjaCBoYW5kbGVyIHNwZWNpZmllZCBieSBrZXkgIiR7cmF3LmhhbmRsZXJ9ImAsIGhhbmRsZXIpOw0KICAgICAgfQ0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICB3YXJuJDEoYEludmFsaWQgd2F0Y2ggb3B0aW9uOiAiJHtrZXl9ImAsIHJhdyk7DQogIH0NCn0NCmZ1bmN0aW9uIHJlc29sdmVNZXJnZWRPcHRpb25zKGluc3RhbmNlKSB7DQogIGNvbnN0IGJhc2UgPSBpbnN0YW5jZS50eXBlOw0KICBjb25zdCB7IG1peGlucywgZXh0ZW5kczogZXh0ZW5kc09wdGlvbnMgfSA9IGJhc2U7DQogIGNvbnN0IHsNCiAgICBtaXhpbnM6IGdsb2JhbE1peGlucywNCiAgICBvcHRpb25zQ2FjaGU6IGNhY2hlLA0KICAgIGNvbmZpZzogeyBvcHRpb25NZXJnZVN0cmF0ZWdpZXMgfQ0KICB9ID0gaW5zdGFuY2UuYXBwQ29udGV4dDsNCiAgY29uc3QgY2FjaGVkID0gY2FjaGUuZ2V0KGJhc2UpOw0KICBsZXQgcmVzb2x2ZWQ7DQogIGlmIChjYWNoZWQpIHsNCiAgICByZXNvbHZlZCA9IGNhY2hlZDsNCiAgfSBlbHNlIGlmICghZ2xvYmFsTWl4aW5zLmxlbmd0aCAmJiAhbWl4aW5zICYmICFleHRlbmRzT3B0aW9ucykgew0KICAgIHsNCiAgICAgIHJlc29sdmVkID0gYmFzZTsNCiAgICB9DQogIH0gZWxzZSB7DQogICAgcmVzb2x2ZWQgPSB7fTsNCiAgICBpZiAoZ2xvYmFsTWl4aW5zLmxlbmd0aCkgew0KICAgICAgZ2xvYmFsTWl4aW5zLmZvckVhY2goDQogICAgICAgIChtKSA9PiBtZXJnZU9wdGlvbnMocmVzb2x2ZWQsIG0sIG9wdGlvbk1lcmdlU3RyYXRlZ2llcywgdHJ1ZSkNCiAgICAgICk7DQogICAgfQ0KICAgIG1lcmdlT3B0aW9ucyhyZXNvbHZlZCwgYmFzZSwgb3B0aW9uTWVyZ2VTdHJhdGVnaWVzKTsNCiAgfQ0KICBpZiAoaXNPYmplY3QoYmFzZSkpIHsNCiAgICBjYWNoZS5zZXQoYmFzZSwgcmVzb2x2ZWQpOw0KICB9DQogIHJldHVybiByZXNvbHZlZDsNCn0NCmZ1bmN0aW9uIG1lcmdlT3B0aW9ucyh0bywgZnJvbSwgc3RyYXRzLCBhc01peGluID0gZmFsc2UpIHsNCiAgY29uc3QgeyBtaXhpbnMsIGV4dGVuZHM6IGV4dGVuZHNPcHRpb25zIH0gPSBmcm9tOw0KICBpZiAoZXh0ZW5kc09wdGlvbnMpIHsNCiAgICBtZXJnZU9wdGlvbnModG8sIGV4dGVuZHNPcHRpb25zLCBzdHJhdHMsIHRydWUpOw0KICB9DQogIGlmIChtaXhpbnMpIHsNCiAgICBtaXhpbnMuZm9yRWFjaCgNCiAgICAgIChtKSA9PiBtZXJnZU9wdGlvbnModG8sIG0sIHN0cmF0cywgdHJ1ZSkNCiAgICApOw0KICB9DQogIGZvciAoY29uc3Qga2V5IGluIGZyb20pIHsNCiAgICBpZiAoYXNNaXhpbiAmJiBrZXkgPT09ICJleHBvc2UiKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGAiZXhwb3NlIiBvcHRpb24gaXMgaWdub3JlZCB3aGVuIGRlY2xhcmVkIGluIG1peGlucyBvciBleHRlbmRzLiBJdCBzaG91bGQgb25seSBiZSBkZWNsYXJlZCBpbiB0aGUgYmFzZSBjb21wb25lbnQgaXRzZWxmLmANCiAgICAgICk7DQogICAgfSBlbHNlIHsNCiAgICAgIGNvbnN0IHN0cmF0ID0gaW50ZXJuYWxPcHRpb25NZXJnZVN0cmF0c1trZXldIHx8IHN0cmF0cyAmJiBzdHJhdHNba2V5XTsNCiAgICAgIHRvW2tleV0gPSBzdHJhdCA/IHN0cmF0KHRvW2tleV0sIGZyb21ba2V5XSkgOiBmcm9tW2tleV07DQogICAgfQ0KICB9DQogIHJldHVybiB0bzsNCn0NCmNvbnN0IGludGVybmFsT3B0aW9uTWVyZ2VTdHJhdHMgPSB7DQogIGRhdGE6IG1lcmdlRGF0YUZuLA0KICBwcm9wczogbWVyZ2VFbWl0c09yUHJvcHNPcHRpb25zLA0KICBlbWl0czogbWVyZ2VFbWl0c09yUHJvcHNPcHRpb25zLA0KICAvLyBvYmplY3RzDQogIG1ldGhvZHM6IG1lcmdlT2JqZWN0T3B0aW9ucywNCiAgY29tcHV0ZWQ6IG1lcmdlT2JqZWN0T3B0aW9ucywNCiAgLy8gbGlmZWN5Y2xlDQogIGJlZm9yZUNyZWF0ZTogbWVyZ2VBc0FycmF5LA0KICBjcmVhdGVkOiBtZXJnZUFzQXJyYXksDQogIGJlZm9yZU1vdW50OiBtZXJnZUFzQXJyYXksDQogIG1vdW50ZWQ6IG1lcmdlQXNBcnJheSwNCiAgYmVmb3JlVXBkYXRlOiBtZXJnZUFzQXJyYXksDQogIHVwZGF0ZWQ6IG1lcmdlQXNBcnJheSwNCiAgYmVmb3JlRGVzdHJveTogbWVyZ2VBc0FycmF5LA0KICBiZWZvcmVVbm1vdW50OiBtZXJnZUFzQXJyYXksDQogIGRlc3Ryb3llZDogbWVyZ2VBc0FycmF5LA0KICB1bm1vdW50ZWQ6IG1lcmdlQXNBcnJheSwNCiAgYWN0aXZhdGVkOiBtZXJnZUFzQXJyYXksDQogIGRlYWN0aXZhdGVkOiBtZXJnZUFzQXJyYXksDQogIGVycm9yQ2FwdHVyZWQ6IG1lcmdlQXNBcnJheSwNCiAgc2VydmVyUHJlZmV0Y2g6IG1lcmdlQXNBcnJheSwNCiAgLy8gYXNzZXRzDQogIGNvbXBvbmVudHM6IG1lcmdlT2JqZWN0T3B0aW9ucywNCiAgZGlyZWN0aXZlczogbWVyZ2VPYmplY3RPcHRpb25zLA0KICAvLyB3YXRjaA0KICB3YXRjaDogbWVyZ2VXYXRjaE9wdGlvbnMsDQogIC8vIHByb3ZpZGUgLyBpbmplY3QNCiAgcHJvdmlkZTogbWVyZ2VEYXRhRm4sDQogIGluamVjdDogbWVyZ2VJbmplY3QNCn07DQpmdW5jdGlvbiBtZXJnZURhdGFGbih0bywgZnJvbSkgew0KICBpZiAoIWZyb20pIHsNCiAgICByZXR1cm4gdG87DQogIH0NCiAgaWYgKCF0bykgew0KICAgIHJldHVybiBmcm9tOw0KICB9DQogIHJldHVybiBmdW5jdGlvbiBtZXJnZWREYXRhRm4oKSB7DQogICAgcmV0dXJuIChleHRlbmQpKA0KICAgICAgaXNGdW5jdGlvbih0bykgPyB0by5jYWxsKHRoaXMsIHRoaXMpIDogdG8sDQogICAgICBpc0Z1bmN0aW9uKGZyb20pID8gZnJvbS5jYWxsKHRoaXMsIHRoaXMpIDogZnJvbQ0KICAgICk7DQogIH07DQp9DQpmdW5jdGlvbiBtZXJnZUluamVjdCh0bywgZnJvbSkgew0KICByZXR1cm4gbWVyZ2VPYmplY3RPcHRpb25zKG5vcm1hbGl6ZUluamVjdCh0byksIG5vcm1hbGl6ZUluamVjdChmcm9tKSk7DQp9DQpmdW5jdGlvbiBub3JtYWxpemVJbmplY3QocmF3KSB7DQogIGlmIChpc0FycmF5KHJhdykpIHsNCiAgICBjb25zdCByZXMgPSB7fTsNCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhdy5sZW5ndGg7IGkrKykgew0KICAgICAgcmVzW3Jhd1tpXV0gPSByYXdbaV07DQogICAgfQ0KICAgIHJldHVybiByZXM7DQogIH0NCiAgcmV0dXJuIHJhdzsNCn0NCmZ1bmN0aW9uIG1lcmdlQXNBcnJheSh0bywgZnJvbSkgew0KICByZXR1cm4gdG8gPyBbLi4ubmV3IFNldChbXS5jb25jYXQodG8sIGZyb20pKV0gOiBmcm9tOw0KfQ0KZnVuY3Rpb24gbWVyZ2VPYmplY3RPcHRpb25zKHRvLCBmcm9tKSB7DQogIHJldHVybiB0byA/IGV4dGVuZCgvKiBAX19QVVJFX18gKi8gT2JqZWN0LmNyZWF0ZShudWxsKSwgdG8sIGZyb20pIDogZnJvbTsNCn0NCmZ1bmN0aW9uIG1lcmdlRW1pdHNPclByb3BzT3B0aW9ucyh0bywgZnJvbSkgew0KICBpZiAodG8pIHsNCiAgICBpZiAoaXNBcnJheSh0bykgJiYgaXNBcnJheShmcm9tKSkgew0KICAgICAgcmV0dXJuIFsuLi4vKiBAX19QVVJFX18gKi8gbmV3IFNldChbLi4udG8sIC4uLmZyb21dKV07DQogICAgfQ0KICAgIHJldHVybiBleHRlbmQoDQogICAgICAvKiBAX19QVVJFX18gKi8gT2JqZWN0LmNyZWF0ZShudWxsKSwNCiAgICAgIG5vcm1hbGl6ZVByb3BzT3JFbWl0cyh0byksDQogICAgICBub3JtYWxpemVQcm9wc09yRW1pdHMoZnJvbSAhPSBudWxsID8gZnJvbSA6IHt9KQ0KICAgICk7DQogIH0gZWxzZSB7DQogICAgcmV0dXJuIGZyb207DQogIH0NCn0NCmZ1bmN0aW9uIG1lcmdlV2F0Y2hPcHRpb25zKHRvLCBmcm9tKSB7DQogIGlmICghdG8pIHJldHVybiBmcm9tOw0KICBpZiAoIWZyb20pIHJldHVybiB0bzsNCiAgY29uc3QgbWVyZ2VkID0gZXh0ZW5kKC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuY3JlYXRlKG51bGwpLCB0byk7DQogIGZvciAoY29uc3Qga2V5IGluIGZyb20pIHsNCiAgICBtZXJnZWRba2V5XSA9IG1lcmdlQXNBcnJheSh0b1trZXldLCBmcm9tW2tleV0pOw0KICB9DQogIHJldHVybiBtZXJnZWQ7DQp9DQoNCmZ1bmN0aW9uIGNyZWF0ZUFwcENvbnRleHQoKSB7DQogIHJldHVybiB7DQogICAgYXBwOiBudWxsLA0KICAgIGNvbmZpZzogew0KICAgICAgaXNOYXRpdmVUYWc6IE5PLA0KICAgICAgcGVyZm9ybWFuY2U6IGZhbHNlLA0KICAgICAgZ2xvYmFsUHJvcGVydGllczoge30sDQogICAgICBvcHRpb25NZXJnZVN0cmF0ZWdpZXM6IHt9LA0KICAgICAgZXJyb3JIYW5kbGVyOiB2b2lkIDAsDQogICAgICB3YXJuSGFuZGxlcjogdm9pZCAwLA0KICAgICAgY29tcGlsZXJPcHRpb25zOiB7fQ0KICAgIH0sDQogICAgbWl4aW5zOiBbXSwNCiAgICBjb21wb25lbnRzOiB7fSwNCiAgICBkaXJlY3RpdmVzOiB7fSwNCiAgICBwcm92aWRlczogLyogQF9fUFVSRV9fICovIE9iamVjdC5jcmVhdGUobnVsbCksDQogICAgb3B0aW9uc0NhY2hlOiAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtNYXAoKSwNCiAgICBwcm9wc0NhY2hlOiAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtNYXAoKSwNCiAgICBlbWl0c0NhY2hlOiAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtNYXAoKQ0KICB9Ow0KfQ0KbGV0IHVpZCQxID0gMDsNCmZ1bmN0aW9uIGNyZWF0ZUFwcEFQSShyZW5kZXIsIGh5ZHJhdGUpIHsNCiAgcmV0dXJuIGZ1bmN0aW9uIGNyZWF0ZUFwcChyb290Q29tcG9uZW50LCByb290UHJvcHMgPSBudWxsKSB7DQogICAgaWYgKCFpc0Z1bmN0aW9uKHJvb3RDb21wb25lbnQpKSB7DQogICAgICByb290Q29tcG9uZW50ID0gZXh0ZW5kKHt9LCByb290Q29tcG9uZW50KTsNCiAgICB9DQogICAgaWYgKHJvb3RQcm9wcyAhPSBudWxsICYmICFpc09iamVjdChyb290UHJvcHMpKSB7DQogICAgICB3YXJuJDEoYHJvb3QgcHJvcHMgcGFzc2VkIHRvIGFwcC5tb3VudCgpIG11c3QgYmUgYW4gb2JqZWN0LmApOw0KICAgICAgcm9vdFByb3BzID0gbnVsbDsNCiAgICB9DQogICAgY29uc3QgY29udGV4dCA9IGNyZWF0ZUFwcENvbnRleHQoKTsNCiAgICBjb25zdCBpbnN0YWxsZWRQbHVnaW5zID0gLyogQF9fUFVSRV9fICovIG5ldyBXZWFrU2V0KCk7DQogICAgY29uc3QgcGx1Z2luQ2xlYW51cEZucyA9IFtdOw0KICAgIGxldCBpc01vdW50ZWQgPSBmYWxzZTsNCiAgICBjb25zdCBhcHAgPSBjb250ZXh0LmFwcCA9IHsNCiAgICAgIF91aWQ6IHVpZCQxKyssDQogICAgICBfY29tcG9uZW50OiByb290Q29tcG9uZW50LA0KICAgICAgX3Byb3BzOiByb290UHJvcHMsDQogICAgICBfY29udGFpbmVyOiBudWxsLA0KICAgICAgX2NvbnRleHQ6IGNvbnRleHQsDQogICAgICBfaW5zdGFuY2U6IG51bGwsDQogICAgICB2ZXJzaW9uLA0KICAgICAgZ2V0IGNvbmZpZygpIHsNCiAgICAgICAgcmV0dXJuIGNvbnRleHQuY29uZmlnOw0KICAgICAgfSwNCiAgICAgIHNldCBjb25maWcodikgew0KICAgICAgICB7DQogICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgYGFwcC5jb25maWcgY2Fubm90IGJlIHJlcGxhY2VkLiBNb2RpZnkgaW5kaXZpZHVhbCBvcHRpb25zIGluc3RlYWQuYA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH0sDQogICAgICB1c2UocGx1Z2luLCAuLi5vcHRpb25zKSB7DQogICAgICAgIGlmIChpbnN0YWxsZWRQbHVnaW5zLmhhcyhwbHVnaW4pKSB7DQogICAgICAgICAgd2FybiQxKGBQbHVnaW4gaGFzIGFscmVhZHkgYmVlbiBhcHBsaWVkIHRvIHRhcmdldCBhcHAuYCk7DQogICAgICAgIH0gZWxzZSBpZiAocGx1Z2luICYmIGlzRnVuY3Rpb24ocGx1Z2luLmluc3RhbGwpKSB7DQogICAgICAgICAgaW5zdGFsbGVkUGx1Z2lucy5hZGQocGx1Z2luKTsNCiAgICAgICAgICBwbHVnaW4uaW5zdGFsbChhcHAsIC4uLm9wdGlvbnMpOw0KICAgICAgICB9IGVsc2UgaWYgKGlzRnVuY3Rpb24ocGx1Z2luKSkgew0KICAgICAgICAgIGluc3RhbGxlZFBsdWdpbnMuYWRkKHBsdWdpbik7DQogICAgICAgICAgcGx1Z2luKGFwcCwgLi4ub3B0aW9ucyk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgYEEgcGx1Z2luIG11c3QgZWl0aGVyIGJlIGEgZnVuY3Rpb24gb3IgYW4gb2JqZWN0IHdpdGggYW4gImluc3RhbGwiIGZ1bmN0aW9uLmANCiAgICAgICAgICApOw0KICAgICAgICB9DQogICAgICAgIHJldHVybiBhcHA7DQogICAgICB9LA0KICAgICAgbWl4aW4obWl4aW4pIHsNCiAgICAgICAgew0KICAgICAgICAgIGlmICghY29udGV4dC5taXhpbnMuaW5jbHVkZXMobWl4aW4pKSB7DQogICAgICAgICAgICBjb250ZXh0Lm1peGlucy5wdXNoKG1peGluKTsNCiAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgICAiTWl4aW4gaGFzIGFscmVhZHkgYmVlbiBhcHBsaWVkIHRvIHRhcmdldCBhcHAiICsgKG1peGluLm5hbWUgPyBgOiAke21peGluLm5hbWV9YCA6ICIiKQ0KICAgICAgICAgICAgKTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIGFwcDsNCiAgICAgIH0sDQogICAgICBjb21wb25lbnQobmFtZSwgY29tcG9uZW50KSB7DQogICAgICAgIHsNCiAgICAgICAgICB2YWxpZGF0ZUNvbXBvbmVudE5hbWUobmFtZSwgY29udGV4dC5jb25maWcpOw0KICAgICAgICB9DQogICAgICAgIGlmICghY29tcG9uZW50KSB7DQogICAgICAgICAgcmV0dXJuIGNvbnRleHQuY29tcG9uZW50c1tuYW1lXTsNCiAgICAgICAgfQ0KICAgICAgICBpZiAoY29udGV4dC5jb21wb25lbnRzW25hbWVdKSB7DQogICAgICAgICAgd2FybiQxKGBDb21wb25lbnQgIiR7bmFtZX0iIGhhcyBhbHJlYWR5IGJlZW4gcmVnaXN0ZXJlZCBpbiB0YXJnZXQgYXBwLmApOw0KICAgICAgICB9DQogICAgICAgIGNvbnRleHQuY29tcG9uZW50c1tuYW1lXSA9IGNvbXBvbmVudDsNCiAgICAgICAgcmV0dXJuIGFwcDsNCiAgICAgIH0sDQogICAgICBkaXJlY3RpdmUobmFtZSwgZGlyZWN0aXZlKSB7DQogICAgICAgIHsNCiAgICAgICAgICB2YWxpZGF0ZURpcmVjdGl2ZU5hbWUobmFtZSk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKCFkaXJlY3RpdmUpIHsNCiAgICAgICAgICByZXR1cm4gY29udGV4dC5kaXJlY3RpdmVzW25hbWVdOw0KICAgICAgICB9DQogICAgICAgIGlmIChjb250ZXh0LmRpcmVjdGl2ZXNbbmFtZV0pIHsNCiAgICAgICAgICB3YXJuJDEoYERpcmVjdGl2ZSAiJHtuYW1lfSIgaGFzIGFscmVhZHkgYmVlbiByZWdpc3RlcmVkIGluIHRhcmdldCBhcHAuYCk7DQogICAgICAgIH0NCiAgICAgICAgY29udGV4dC5kaXJlY3RpdmVzW25hbWVdID0gZGlyZWN0aXZlOw0KICAgICAgICByZXR1cm4gYXBwOw0KICAgICAgfSwNCiAgICAgIG1vdW50KHJvb3RDb250YWluZXIsIGlzSHlkcmF0ZSwgbmFtZXNwYWNlKSB7DQogICAgICAgIGlmICghaXNNb3VudGVkKSB7DQogICAgICAgICAgaWYgKHJvb3RDb250YWluZXIuX192dWVfYXBwX18pIHsNCiAgICAgICAgICAgIHdhcm4kMSgNCiAgICAgICAgICAgICAgYFRoZXJlIGlzIGFscmVhZHkgYW4gYXBwIGluc3RhbmNlIG1vdW50ZWQgb24gdGhlIGhvc3QgY29udGFpbmVyLg0KIElmIHlvdSB3YW50IHRvIG1vdW50IGFub3RoZXIgYXBwIG9uIHRoZSBzYW1lIGhvc3QgY29udGFpbmVyLCB5b3UgbmVlZCB0byB1bm1vdW50IHRoZSBwcmV2aW91cyBhcHAgYnkgY2FsbGluZyBcYGFwcC51bm1vdW50KClcYCBmaXJzdC5gDQogICAgICAgICAgICApOw0KICAgICAgICAgIH0NCiAgICAgICAgICBjb25zdCB2bm9kZSA9IGFwcC5fY2VWTm9kZSB8fCBjcmVhdGVWTm9kZShyb290Q29tcG9uZW50LCByb290UHJvcHMpOw0KICAgICAgICAgIHZub2RlLmFwcENvbnRleHQgPSBjb250ZXh0Ow0KICAgICAgICAgIGlmIChuYW1lc3BhY2UgPT09IHRydWUpIHsNCiAgICAgICAgICAgIG5hbWVzcGFjZSA9ICJzdmciOw0KICAgICAgICAgIH0gZWxzZSBpZiAobmFtZXNwYWNlID09PSBmYWxzZSkgew0KICAgICAgICAgICAgbmFtZXNwYWNlID0gdm9pZCAwOw0KICAgICAgICAgIH0NCiAgICAgICAgICB7DQogICAgICAgICAgICBjb250ZXh0LnJlbG9hZCA9ICgpID0+IHsNCiAgICAgICAgICAgICAgY29uc3QgY2xvbmVkID0gY2xvbmVWTm9kZSh2bm9kZSk7DQogICAgICAgICAgICAgIGNsb25lZC5lbCA9IG51bGw7DQogICAgICAgICAgICAgIHJlbmRlcihjbG9uZWQsIHJvb3RDb250YWluZXIsIG5hbWVzcGFjZSk7DQogICAgICAgICAgICB9Ow0KICAgICAgICAgIH0NCiAgICAgICAgICB7DQogICAgICAgICAgICByZW5kZXIodm5vZGUsIHJvb3RDb250YWluZXIsIG5hbWVzcGFjZSk7DQogICAgICAgICAgfQ0KICAgICAgICAgIGlzTW91bnRlZCA9IHRydWU7DQogICAgICAgICAgYXBwLl9jb250YWluZXIgPSByb290Q29udGFpbmVyOw0KICAgICAgICAgIHJvb3RDb250YWluZXIuX192dWVfYXBwX18gPSBhcHA7DQogICAgICAgICAgew0KICAgICAgICAgICAgYXBwLl9pbnN0YW5jZSA9IHZub2RlLmNvbXBvbmVudDsNCiAgICAgICAgICAgIGRldnRvb2xzSW5pdEFwcChhcHAsIHZlcnNpb24pOw0KICAgICAgICAgIH0NCiAgICAgICAgICByZXR1cm4gZ2V0Q29tcG9uZW50UHVibGljSW5zdGFuY2Uodm5vZGUuY29tcG9uZW50KTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICB3YXJuJDEoDQogICAgICAgICAgICBgQXBwIGhhcyBhbHJlYWR5IGJlZW4gbW91bnRlZC4NCklmIHlvdSB3YW50IHRvIHJlbW91bnQgdGhlIHNhbWUgYXBwLCBtb3ZlIHlvdXIgYXBwIGNyZWF0aW9uIGxvZ2ljIGludG8gYSBmYWN0b3J5IGZ1bmN0aW9uIGFuZCBjcmVhdGUgZnJlc2ggYXBwIGluc3RhbmNlcyBmb3IgZWFjaCBtb3VudCAtIGUuZy4gXGBjb25zdCBjcmVhdGVNeUFwcCA9ICgpID0+IGNyZWF0ZUFwcChBcHApXGBgDQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgfSwNCiAgICAgIG9uVW5tb3VudChjbGVhbnVwRm4pIHsNCiAgICAgICAgaWYgKHR5cGVvZiBjbGVhbnVwRm4gIT09ICJmdW5jdGlvbiIpIHsNCiAgICAgICAgICB3YXJuJDEoDQogICAgICAgICAgICBgRXhwZWN0ZWQgZnVuY3Rpb24gYXMgZmlyc3QgYXJndW1lbnQgdG8gYXBwLm9uVW5tb3VudCgpLCBidXQgZ290ICR7dHlwZW9mIGNsZWFudXBGbn1gDQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgICBwbHVnaW5DbGVhbnVwRm5zLnB1c2goY2xlYW51cEZuKTsNCiAgICAgIH0sDQogICAgICB1bm1vdW50KCkgew0KICAgICAgICBpZiAoaXNNb3VudGVkKSB7DQogICAgICAgICAgY2FsbFdpdGhBc3luY0Vycm9ySGFuZGxpbmcoDQogICAgICAgICAgICBwbHVnaW5DbGVhbnVwRm5zLA0KICAgICAgICAgICAgYXBwLl9pbnN0YW5jZSwNCiAgICAgICAgICAgIDE2DQogICAgICAgICAgKTsNCiAgICAgICAgICByZW5kZXIobnVsbCwgYXBwLl9jb250YWluZXIpOw0KICAgICAgICAgIHsNCiAgICAgICAgICAgIGFwcC5faW5zdGFuY2UgPSBudWxsOw0KICAgICAgICAgICAgZGV2dG9vbHNVbm1vdW50QXBwKGFwcCk7DQogICAgICAgICAgfQ0KICAgICAgICAgIGRlbGV0ZSBhcHAuX2NvbnRhaW5lci5fX3Z1ZV9hcHBfXzsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICB3YXJuJDEoYENhbm5vdCB1bm1vdW50IGFuIGFwcCB0aGF0IGlzIG5vdCBtb3VudGVkLmApOw0KICAgICAgICB9DQogICAgICB9LA0KICAgICAgcHJvdmlkZShrZXksIHZhbHVlKSB7DQogICAgICAgIGlmIChrZXkgaW4gY29udGV4dC5wcm92aWRlcykgew0KICAgICAgICAgIGlmIChoYXNPd24oY29udGV4dC5wcm92aWRlcywga2V5KSkgew0KICAgICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgICBgQXBwIGFscmVhZHkgcHJvdmlkZXMgcHJvcGVydHkgd2l0aCBrZXkgIiR7U3RyaW5nKGtleSl9Ii4gSXQgd2lsbCBiZSBvdmVyd3JpdHRlbiB3aXRoIHRoZSBuZXcgdmFsdWUuYA0KICAgICAgICAgICAgKTsNCiAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgICBgQXBwIGFscmVhZHkgcHJvdmlkZXMgcHJvcGVydHkgd2l0aCBrZXkgIiR7U3RyaW5nKGtleSl9IiBpbmhlcml0ZWQgZnJvbSBpdHMgcGFyZW50IGVsZW1lbnQuIEl0IHdpbGwgYmUgb3ZlcndyaXR0ZW4gd2l0aCB0aGUgbmV3IHZhbHVlLmANCiAgICAgICAgICAgICk7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGNvbnRleHQucHJvdmlkZXNba2V5XSA9IHZhbHVlOw0KICAgICAgICByZXR1cm4gYXBwOw0KICAgICAgfSwNCiAgICAgIHJ1bldpdGhDb250ZXh0KGZuKSB7DQogICAgICAgIGNvbnN0IGxhc3RBcHAgPSBjdXJyZW50QXBwOw0KICAgICAgICBjdXJyZW50QXBwID0gYXBwOw0KICAgICAgICB0cnkgew0KICAgICAgICAgIHJldHVybiBmbigpOw0KICAgICAgICB9IGZpbmFsbHkgew0KICAgICAgICAgIGN1cnJlbnRBcHAgPSBsYXN0QXBwOw0KICAgICAgICB9DQogICAgICB9DQogICAgfTsNCiAgICByZXR1cm4gYXBwOw0KICB9Ow0KfQ0KbGV0IGN1cnJlbnRBcHAgPSBudWxsOw0KDQpmdW5jdGlvbiBwcm92aWRlKGtleSwgdmFsdWUpIHsNCiAgaWYgKCFjdXJyZW50SW5zdGFuY2UpIHsNCiAgICB7DQogICAgICB3YXJuJDEoYHByb3ZpZGUoKSBjYW4gb25seSBiZSB1c2VkIGluc2lkZSBzZXR1cCgpLmApOw0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICBsZXQgcHJvdmlkZXMgPSBjdXJyZW50SW5zdGFuY2UucHJvdmlkZXM7DQogICAgY29uc3QgcGFyZW50UHJvdmlkZXMgPSBjdXJyZW50SW5zdGFuY2UucGFyZW50ICYmIGN1cnJlbnRJbnN0YW5jZS5wYXJlbnQucHJvdmlkZXM7DQogICAgaWYgKHBhcmVudFByb3ZpZGVzID09PSBwcm92aWRlcykgew0KICAgICAgcHJvdmlkZXMgPSBjdXJyZW50SW5zdGFuY2UucHJvdmlkZXMgPSBPYmplY3QuY3JlYXRlKHBhcmVudFByb3ZpZGVzKTsNCiAgICB9DQogICAgcHJvdmlkZXNba2V5XSA9IHZhbHVlOw0KICB9DQp9DQpmdW5jdGlvbiBpbmplY3Qoa2V5LCBkZWZhdWx0VmFsdWUsIHRyZWF0RGVmYXVsdEFzRmFjdG9yeSA9IGZhbHNlKSB7DQogIGNvbnN0IGluc3RhbmNlID0gY3VycmVudEluc3RhbmNlIHx8IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZTsNCiAgaWYgKGluc3RhbmNlIHx8IGN1cnJlbnRBcHApIHsNCiAgICBsZXQgcHJvdmlkZXMgPSBjdXJyZW50QXBwID8gY3VycmVudEFwcC5fY29udGV4dC5wcm92aWRlcyA6IGluc3RhbmNlID8gaW5zdGFuY2UucGFyZW50ID09IG51bGwgfHwgaW5zdGFuY2UuY2UgPyBpbnN0YW5jZS52bm9kZS5hcHBDb250ZXh0ICYmIGluc3RhbmNlLnZub2RlLmFwcENvbnRleHQucHJvdmlkZXMgOiBpbnN0YW5jZS5wYXJlbnQucHJvdmlkZXMgOiB2b2lkIDA7DQogICAgaWYgKHByb3ZpZGVzICYmIGtleSBpbiBwcm92aWRlcykgew0KICAgICAgcmV0dXJuIHByb3ZpZGVzW2tleV07DQogICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkgew0KICAgICAgcmV0dXJuIHRyZWF0RGVmYXVsdEFzRmFjdG9yeSAmJiBpc0Z1bmN0aW9uKGRlZmF1bHRWYWx1ZSkgPyBkZWZhdWx0VmFsdWUuY2FsbChpbnN0YW5jZSAmJiBpbnN0YW5jZS5wcm94eSkgOiBkZWZhdWx0VmFsdWU7DQogICAgfSBlbHNlIHsNCiAgICAgIHdhcm4kMShgaW5qZWN0aW9uICIke1N0cmluZyhrZXkpfSIgbm90IGZvdW5kLmApOw0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICB3YXJuJDEoYGluamVjdCgpIGNhbiBvbmx5IGJlIHVzZWQgaW5zaWRlIHNldHVwKCkgb3IgZnVuY3Rpb25hbCBjb21wb25lbnRzLmApOw0KICB9DQp9DQoNCmNvbnN0IGludGVybmFsT2JqZWN0UHJvdG8gPSB7fTsNCmNvbnN0IGNyZWF0ZUludGVybmFsT2JqZWN0ID0gKCkgPT4gT2JqZWN0LmNyZWF0ZShpbnRlcm5hbE9iamVjdFByb3RvKTsNCmNvbnN0IGlzSW50ZXJuYWxPYmplY3QgPSAob2JqKSA9PiBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqKSA9PT0gaW50ZXJuYWxPYmplY3RQcm90bzsNCg0KZnVuY3Rpb24gaW5pdFByb3BzKGluc3RhbmNlLCByYXdQcm9wcywgaXNTdGF0ZWZ1bCwgaXNTU1IgPSBmYWxzZSkgew0KICBjb25zdCBwcm9wcyA9IHt9Ow0KICBjb25zdCBhdHRycyA9IGNyZWF0ZUludGVybmFsT2JqZWN0KCk7DQogIGluc3RhbmNlLnByb3BzRGVmYXVsdHMgPSAvKiBAX19QVVJFX18gKi8gT2JqZWN0LmNyZWF0ZShudWxsKTsNCiAgc2V0RnVsbFByb3BzKGluc3RhbmNlLCByYXdQcm9wcywgcHJvcHMsIGF0dHJzKTsNCiAgZm9yIChjb25zdCBrZXkgaW4gaW5zdGFuY2UucHJvcHNPcHRpb25zWzBdKSB7DQogICAgaWYgKCEoa2V5IGluIHByb3BzKSkgew0KICAgICAgcHJvcHNba2V5XSA9IHZvaWQgMDsNCiAgICB9DQogIH0NCiAgew0KICAgIHZhbGlkYXRlUHJvcHMocmF3UHJvcHMgfHwge30sIHByb3BzLCBpbnN0YW5jZSk7DQogIH0NCiAgaWYgKGlzU3RhdGVmdWwpIHsNCiAgICBpbnN0YW5jZS5wcm9wcyA9IGlzU1NSID8gcHJvcHMgOiBzaGFsbG93UmVhY3RpdmUocHJvcHMpOw0KICB9IGVsc2Ugew0KICAgIGlmICghaW5zdGFuY2UudHlwZS5wcm9wcykgew0KICAgICAgaW5zdGFuY2UucHJvcHMgPSBhdHRyczsNCiAgICB9IGVsc2Ugew0KICAgICAgaW5zdGFuY2UucHJvcHMgPSBwcm9wczsNCiAgICB9DQogIH0NCiAgaW5zdGFuY2UuYXR0cnMgPSBhdHRyczsNCn0NCmZ1bmN0aW9uIGlzSW5IbXJDb250ZXh0KGluc3RhbmNlKSB7DQogIHdoaWxlIChpbnN0YW5jZSkgew0KICAgIGlmIChpbnN0YW5jZS50eXBlLl9faG1ySWQpIHJldHVybiB0cnVlOw0KICAgIGluc3RhbmNlID0gaW5zdGFuY2UucGFyZW50Ow0KICB9DQp9DQpmdW5jdGlvbiB1cGRhdGVQcm9wcyhpbnN0YW5jZSwgcmF3UHJvcHMsIHJhd1ByZXZQcm9wcywgb3B0aW1pemVkKSB7DQogIGNvbnN0IHsNCiAgICBwcm9wcywNCiAgICBhdHRycywNCiAgICB2bm9kZTogeyBwYXRjaEZsYWcgfQ0KICB9ID0gaW5zdGFuY2U7DQogIGNvbnN0IHJhd0N1cnJlbnRQcm9wcyA9IHRvUmF3KHByb3BzKTsNCiAgY29uc3QgW29wdGlvbnNdID0gaW5zdGFuY2UucHJvcHNPcHRpb25zOw0KICBsZXQgaGFzQXR0cnNDaGFuZ2VkID0gZmFsc2U7DQogIGlmICgNCiAgICAvLyBhbHdheXMgZm9yY2UgZnVsbCBkaWZmIGluIGRldg0KICAgIC8vIC0gIzE5NDIgaWYgaG1yIGlzIGVuYWJsZWQgd2l0aCBzZmMgY29tcG9uZW50DQogICAgLy8gLSB2aXRlIzg3MiBub24tc2ZjIGNvbXBvbmVudCB1c2VkIGJ5IHNmYyBjb21wb25lbnQNCiAgICAhaXNJbkhtckNvbnRleHQoaW5zdGFuY2UpICYmIChvcHRpbWl6ZWQgfHwgcGF0Y2hGbGFnID4gMCkgJiYgIShwYXRjaEZsYWcgJiAxNikNCiAgKSB7DQogICAgaWYgKHBhdGNoRmxhZyAmIDgpIHsNCiAgICAgIGNvbnN0IHByb3BzVG9VcGRhdGUgPSBpbnN0YW5jZS52bm9kZS5keW5hbWljUHJvcHM7DQogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByb3BzVG9VcGRhdGUubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgbGV0IGtleSA9IHByb3BzVG9VcGRhdGVbaV07DQogICAgICAgIGlmIChpc0VtaXRMaXN0ZW5lcihpbnN0YW5jZS5lbWl0c09wdGlvbnMsIGtleSkpIHsNCiAgICAgICAgICBjb250aW51ZTsNCiAgICAgICAgfQ0KICAgICAgICBjb25zdCB2YWx1ZSA9IHJhd1Byb3BzW2tleV07DQogICAgICAgIGlmIChvcHRpb25zKSB7DQogICAgICAgICAgaWYgKGhhc093bihhdHRycywga2V5KSkgew0KICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBhdHRyc1trZXldKSB7DQogICAgICAgICAgICAgIGF0dHJzW2tleV0gPSB2YWx1ZTsNCiAgICAgICAgICAgICAgaGFzQXR0cnNDaGFuZ2VkID0gdHJ1ZTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgY29uc3QgY2FtZWxpemVkS2V5ID0gY2FtZWxpemUoa2V5KTsNCiAgICAgICAgICAgIHByb3BzW2NhbWVsaXplZEtleV0gPSByZXNvbHZlUHJvcFZhbHVlKA0KICAgICAgICAgICAgICBvcHRpb25zLA0KICAgICAgICAgICAgICByYXdDdXJyZW50UHJvcHMsDQogICAgICAgICAgICAgIGNhbWVsaXplZEtleSwNCiAgICAgICAgICAgICAgdmFsdWUsDQogICAgICAgICAgICAgIGluc3RhbmNlLA0KICAgICAgICAgICAgICBmYWxzZQ0KICAgICAgICAgICAgKTsNCiAgICAgICAgICB9DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgaWYgKHZhbHVlICE9PSBhdHRyc1trZXldKSB7DQogICAgICAgICAgICBhdHRyc1trZXldID0gdmFsdWU7DQogICAgICAgICAgICBoYXNBdHRyc0NoYW5nZWQgPSB0cnVlOw0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICBpZiAoc2V0RnVsbFByb3BzKGluc3RhbmNlLCByYXdQcm9wcywgcHJvcHMsIGF0dHJzKSkgew0KICAgICAgaGFzQXR0cnNDaGFuZ2VkID0gdHJ1ZTsNCiAgICB9DQogICAgbGV0IGtlYmFiS2V5Ow0KICAgIGZvciAoY29uc3Qga2V5IGluIHJhd0N1cnJlbnRQcm9wcykgew0KICAgICAgaWYgKCFyYXdQcm9wcyB8fCAvLyBmb3IgY2FtZWxDYXNlDQogICAgICAhaGFzT3duKHJhd1Byb3BzLCBrZXkpICYmIC8vIGl0J3MgcG9zc2libGUgdGhlIG9yaWdpbmFsIHByb3BzIHdhcyBwYXNzZWQgaW4gYXMga2ViYWItY2FzZQ0KICAgICAgLy8gYW5kIGNvbnZlcnRlZCB0byBjYW1lbENhc2UgKCM5NTUpDQogICAgICAoKGtlYmFiS2V5ID0gaHlwaGVuYXRlKGtleSkpID09PSBrZXkgfHwgIWhhc093bihyYXdQcm9wcywga2ViYWJLZXkpKSkgew0KICAgICAgICBpZiAob3B0aW9ucykgew0KICAgICAgICAgIGlmIChyYXdQcmV2UHJvcHMgJiYgLy8gZm9yIGNhbWVsQ2FzZQ0KICAgICAgICAgIChyYXdQcmV2UHJvcHNba2V5XSAhPT0gdm9pZCAwIHx8IC8vIGZvciBrZWJhYi1jYXNlDQogICAgICAgICAgcmF3UHJldlByb3BzW2tlYmFiS2V5XSAhPT0gdm9pZCAwKSkgew0KICAgICAgICAgICAgcHJvcHNba2V5XSA9IHJlc29sdmVQcm9wVmFsdWUoDQogICAgICAgICAgICAgIG9wdGlvbnMsDQogICAgICAgICAgICAgIHJhd0N1cnJlbnRQcm9wcywNCiAgICAgICAgICAgICAga2V5LA0KICAgICAgICAgICAgICB2b2lkIDAsDQogICAgICAgICAgICAgIGluc3RhbmNlLA0KICAgICAgICAgICAgICB0cnVlDQogICAgICAgICAgICApOw0KICAgICAgICAgIH0NCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBkZWxldGUgcHJvcHNba2V5XTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgICBpZiAoYXR0cnMgIT09IHJhd0N1cnJlbnRQcm9wcykgew0KICAgICAgZm9yIChjb25zdCBrZXkgaW4gYXR0cnMpIHsNCiAgICAgICAgaWYgKCFyYXdQcm9wcyB8fCAhaGFzT3duKHJhd1Byb3BzLCBrZXkpICYmIHRydWUpIHsNCiAgICAgICAgICBkZWxldGUgYXR0cnNba2V5XTsNCiAgICAgICAgICBoYXNBdHRyc0NoYW5nZWQgPSB0cnVlOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICB9DQogIGlmIChoYXNBdHRyc0NoYW5nZWQpIHsNCiAgICB0cmlnZ2VyKGluc3RhbmNlLmF0dHJzLCAic2V0IiwgIiIpOw0KICB9DQogIHsNCiAgICB2YWxpZGF0ZVByb3BzKHJhd1Byb3BzIHx8IHt9LCBwcm9wcywgaW5zdGFuY2UpOw0KICB9DQp9DQpmdW5jdGlvbiBzZXRGdWxsUHJvcHMoaW5zdGFuY2UsIHJhd1Byb3BzLCBwcm9wcywgYXR0cnMpIHsNCiAgY29uc3QgW29wdGlvbnMsIG5lZWRDYXN0S2V5c10gPSBpbnN0YW5jZS5wcm9wc09wdGlvbnM7DQogIGxldCBoYXNBdHRyc0NoYW5nZWQgPSBmYWxzZTsNCiAgbGV0IHJhd0Nhc3RWYWx1ZXM7DQogIGlmIChyYXdQcm9wcykgew0KICAgIGZvciAobGV0IGtleSBpbiByYXdQcm9wcykgew0KICAgICAgaWYgKGlzUmVzZXJ2ZWRQcm9wKGtleSkpIHsNCiAgICAgICAgY29udGludWU7DQogICAgICB9DQogICAgICBjb25zdCB2YWx1ZSA9IHJhd1Byb3BzW2tleV07DQogICAgICBsZXQgY2FtZWxLZXk7DQogICAgICBpZiAob3B0aW9ucyAmJiBoYXNPd24ob3B0aW9ucywgY2FtZWxLZXkgPSBjYW1lbGl6ZShrZXkpKSkgew0KICAgICAgICBpZiAoIW5lZWRDYXN0S2V5cyB8fCAhbmVlZENhc3RLZXlzLmluY2x1ZGVzKGNhbWVsS2V5KSkgew0KICAgICAgICAgIHByb3BzW2NhbWVsS2V5XSA9IHZhbHVlOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIChyYXdDYXN0VmFsdWVzIHx8IChyYXdDYXN0VmFsdWVzID0ge30pKVtjYW1lbEtleV0gPSB2YWx1ZTsNCiAgICAgICAgfQ0KICAgICAgfSBlbHNlIGlmICghaXNFbWl0TGlzdGVuZXIoaW5zdGFuY2UuZW1pdHNPcHRpb25zLCBrZXkpKSB7DQogICAgICAgIGlmICghKGtleSBpbiBhdHRycykgfHwgdmFsdWUgIT09IGF0dHJzW2tleV0pIHsNCiAgICAgICAgICBhdHRyc1trZXldID0gdmFsdWU7DQogICAgICAgICAgaGFzQXR0cnNDaGFuZ2VkID0gdHJ1ZTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICBpZiAobmVlZENhc3RLZXlzKSB7DQogICAgY29uc3QgcmF3Q3VycmVudFByb3BzID0gdG9SYXcocHJvcHMpOw0KICAgIGNvbnN0IGNhc3RWYWx1ZXMgPSByYXdDYXN0VmFsdWVzIHx8IEVNUFRZX09CSjsNCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5lZWRDYXN0S2V5cy5sZW5ndGg7IGkrKykgew0KICAgICAgY29uc3Qga2V5ID0gbmVlZENhc3RLZXlzW2ldOw0KICAgICAgcHJvcHNba2V5XSA9IHJlc29sdmVQcm9wVmFsdWUoDQogICAgICAgIG9wdGlvbnMsDQogICAgICAgIHJhd0N1cnJlbnRQcm9wcywNCiAgICAgICAga2V5LA0KICAgICAgICBjYXN0VmFsdWVzW2tleV0sDQogICAgICAgIGluc3RhbmNlLA0KICAgICAgICAhaGFzT3duKGNhc3RWYWx1ZXMsIGtleSkNCiAgICAgICk7DQogICAgfQ0KICB9DQogIHJldHVybiBoYXNBdHRyc0NoYW5nZWQ7DQp9DQpmdW5jdGlvbiByZXNvbHZlUHJvcFZhbHVlKG9wdGlvbnMsIHByb3BzLCBrZXksIHZhbHVlLCBpbnN0YW5jZSwgaXNBYnNlbnQpIHsNCiAgY29uc3Qgb3B0ID0gb3B0aW9uc1trZXldOw0KICBpZiAob3B0ICE9IG51bGwpIHsNCiAgICBjb25zdCBoYXNEZWZhdWx0ID0gaGFzT3duKG9wdCwgImRlZmF1bHQiKTsNCiAgICBpZiAoaGFzRGVmYXVsdCAmJiB2YWx1ZSA9PT0gdm9pZCAwKSB7DQogICAgICBjb25zdCBkZWZhdWx0VmFsdWUgPSBvcHQuZGVmYXVsdDsNCiAgICAgIGlmIChvcHQudHlwZSAhPT0gRnVuY3Rpb24gJiYgIW9wdC5za2lwRmFjdG9yeSAmJiBpc0Z1bmN0aW9uKGRlZmF1bHRWYWx1ZSkpIHsNCiAgICAgICAgY29uc3QgeyBwcm9wc0RlZmF1bHRzIH0gPSBpbnN0YW5jZTsNCiAgICAgICAgaWYgKGtleSBpbiBwcm9wc0RlZmF1bHRzKSB7DQogICAgICAgICAgdmFsdWUgPSBwcm9wc0RlZmF1bHRzW2tleV07DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgY29uc3QgcmVzZXQgPSBzZXRDdXJyZW50SW5zdGFuY2UoaW5zdGFuY2UpOw0KICAgICAgICAgIHZhbHVlID0gcHJvcHNEZWZhdWx0c1trZXldID0gZGVmYXVsdFZhbHVlLmNhbGwoDQogICAgICAgICAgICBudWxsLA0KICAgICAgICAgICAgcHJvcHMNCiAgICAgICAgICApOw0KICAgICAgICAgIHJlc2V0KCk7DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHZhbHVlID0gZGVmYXVsdFZhbHVlOw0KICAgICAgfQ0KICAgICAgaWYgKGluc3RhbmNlLmNlKSB7DQogICAgICAgIGluc3RhbmNlLmNlLl9zZXRQcm9wKGtleSwgdmFsdWUpOw0KICAgICAgfQ0KICAgIH0NCiAgICBpZiAob3B0WzAgLyogc2hvdWxkQ2FzdCAqL10pIHsNCiAgICAgIGlmIChpc0Fic2VudCAmJiAhaGFzRGVmYXVsdCkgew0KICAgICAgICB2YWx1ZSA9IGZhbHNlOw0KICAgICAgfSBlbHNlIGlmIChvcHRbMSAvKiBzaG91bGRDYXN0VHJ1ZSAqL10gJiYgKHZhbHVlID09PSAiIiB8fCB2YWx1ZSA9PT0gaHlwaGVuYXRlKGtleSkpKSB7DQogICAgICAgIHZhbHVlID0gdHJ1ZTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgcmV0dXJuIHZhbHVlOw0KfQ0KY29uc3QgbWl4aW5Qcm9wc0NhY2hlID0gLyogQF9fUFVSRV9fICovIG5ldyBXZWFrTWFwKCk7DQpmdW5jdGlvbiBub3JtYWxpemVQcm9wc09wdGlvbnMoY29tcCwgYXBwQ29udGV4dCwgYXNNaXhpbiA9IGZhbHNlKSB7DQogIGNvbnN0IGNhY2hlID0gYXNNaXhpbiA/IG1peGluUHJvcHNDYWNoZSA6IGFwcENvbnRleHQucHJvcHNDYWNoZTsNCiAgY29uc3QgY2FjaGVkID0gY2FjaGUuZ2V0KGNvbXApOw0KICBpZiAoY2FjaGVkKSB7DQogICAgcmV0dXJuIGNhY2hlZDsNCiAgfQ0KICBjb25zdCByYXcgPSBjb21wLnByb3BzOw0KICBjb25zdCBub3JtYWxpemVkID0ge307DQogIGNvbnN0IG5lZWRDYXN0S2V5cyA9IFtdOw0KICBsZXQgaGFzRXh0ZW5kcyA9IGZhbHNlOw0KICBpZiAoIWlzRnVuY3Rpb24oY29tcCkpIHsNCiAgICBjb25zdCBleHRlbmRQcm9wcyA9IChyYXcyKSA9PiB7DQogICAgICBoYXNFeHRlbmRzID0gdHJ1ZTsNCiAgICAgIGNvbnN0IFtwcm9wcywga2V5c10gPSBub3JtYWxpemVQcm9wc09wdGlvbnMocmF3MiwgYXBwQ29udGV4dCwgdHJ1ZSk7DQogICAgICBleHRlbmQobm9ybWFsaXplZCwgcHJvcHMpOw0KICAgICAgaWYgKGtleXMpIG5lZWRDYXN0S2V5cy5wdXNoKC4uLmtleXMpOw0KICAgIH07DQogICAgaWYgKCFhc01peGluICYmIGFwcENvbnRleHQubWl4aW5zLmxlbmd0aCkgew0KICAgICAgYXBwQ29udGV4dC5taXhpbnMuZm9yRWFjaChleHRlbmRQcm9wcyk7DQogICAgfQ0KICAgIGlmIChjb21wLmV4dGVuZHMpIHsNCiAgICAgIGV4dGVuZFByb3BzKGNvbXAuZXh0ZW5kcyk7DQogICAgfQ0KICAgIGlmIChjb21wLm1peGlucykgew0KICAgICAgY29tcC5taXhpbnMuZm9yRWFjaChleHRlbmRQcm9wcyk7DQogICAgfQ0KICB9DQogIGlmICghcmF3ICYmICFoYXNFeHRlbmRzKSB7DQogICAgaWYgKGlzT2JqZWN0KGNvbXApKSB7DQogICAgICBjYWNoZS5zZXQoY29tcCwgRU1QVFlfQVJSKTsNCiAgICB9DQogICAgcmV0dXJuIEVNUFRZX0FSUjsNCiAgfQ0KICBpZiAoaXNBcnJheShyYXcpKSB7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYXcubGVuZ3RoOyBpKyspIHsNCiAgICAgIGlmICghaXNTdHJpbmcocmF3W2ldKSkgew0KICAgICAgICB3YXJuJDEoYHByb3BzIG11c3QgYmUgc3RyaW5ncyB3aGVuIHVzaW5nIGFycmF5IHN5bnRheC5gLCByYXdbaV0pOw0KICAgICAgfQ0KICAgICAgY29uc3Qgbm9ybWFsaXplZEtleSA9IGNhbWVsaXplKHJhd1tpXSk7DQogICAgICBpZiAodmFsaWRhdGVQcm9wTmFtZShub3JtYWxpemVkS2V5KSkgew0KICAgICAgICBub3JtYWxpemVkW25vcm1hbGl6ZWRLZXldID0gRU1QVFlfT0JKOw0KICAgICAgfQ0KICAgIH0NCiAgfSBlbHNlIGlmIChyYXcpIHsNCiAgICBpZiAoIWlzT2JqZWN0KHJhdykpIHsNCiAgICAgIHdhcm4kMShgaW52YWxpZCBwcm9wcyBvcHRpb25zYCwgcmF3KTsNCiAgICB9DQogICAgZm9yIChjb25zdCBrZXkgaW4gcmF3KSB7DQogICAgICBjb25zdCBub3JtYWxpemVkS2V5ID0gY2FtZWxpemUoa2V5KTsNCiAgICAgIGlmICh2YWxpZGF0ZVByb3BOYW1lKG5vcm1hbGl6ZWRLZXkpKSB7DQogICAgICAgIGNvbnN0IG9wdCA9IHJhd1trZXldOw0KICAgICAgICBjb25zdCBwcm9wID0gbm9ybWFsaXplZFtub3JtYWxpemVkS2V5XSA9IGlzQXJyYXkob3B0KSB8fCBpc0Z1bmN0aW9uKG9wdCkgPyB7IHR5cGU6IG9wdCB9IDogZXh0ZW5kKHt9LCBvcHQpOw0KICAgICAgICBjb25zdCBwcm9wVHlwZSA9IHByb3AudHlwZTsNCiAgICAgICAgbGV0IHNob3VsZENhc3QgPSBmYWxzZTsNCiAgICAgICAgbGV0IHNob3VsZENhc3RUcnVlID0gdHJ1ZTsNCiAgICAgICAgaWYgKGlzQXJyYXkocHJvcFR5cGUpKSB7DQogICAgICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHByb3BUeXBlLmxlbmd0aDsgKytpbmRleCkgew0KICAgICAgICAgICAgY29uc3QgdHlwZSA9IHByb3BUeXBlW2luZGV4XTsNCiAgICAgICAgICAgIGNvbnN0IHR5cGVOYW1lID0gaXNGdW5jdGlvbih0eXBlKSAmJiB0eXBlLm5hbWU7DQogICAgICAgICAgICBpZiAodHlwZU5hbWUgPT09ICJCb29sZWFuIikgew0KICAgICAgICAgICAgICBzaG91bGRDYXN0ID0gdHJ1ZTsNCiAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVOYW1lID09PSAiU3RyaW5nIikgew0KICAgICAgICAgICAgICBzaG91bGRDYXN0VHJ1ZSA9IGZhbHNlOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgIH0NCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBzaG91bGRDYXN0ID0gaXNGdW5jdGlvbihwcm9wVHlwZSkgJiYgcHJvcFR5cGUubmFtZSA9PT0gIkJvb2xlYW4iOw0KICAgICAgICB9DQogICAgICAgIHByb3BbMCAvKiBzaG91bGRDYXN0ICovXSA9IHNob3VsZENhc3Q7DQogICAgICAgIHByb3BbMSAvKiBzaG91bGRDYXN0VHJ1ZSAqL10gPSBzaG91bGRDYXN0VHJ1ZTsNCiAgICAgICAgaWYgKHNob3VsZENhc3QgfHwgaGFzT3duKHByb3AsICJkZWZhdWx0IikpIHsNCiAgICAgICAgICBuZWVkQ2FzdEtleXMucHVzaChub3JtYWxpemVkS2V5KTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICBjb25zdCByZXMgPSBbbm9ybWFsaXplZCwgbmVlZENhc3RLZXlzXTsNCiAgaWYgKGlzT2JqZWN0KGNvbXApKSB7DQogICAgY2FjaGUuc2V0KGNvbXAsIHJlcyk7DQogIH0NCiAgcmV0dXJuIHJlczsNCn0NCmZ1bmN0aW9uIHZhbGlkYXRlUHJvcE5hbWUoa2V5KSB7DQogIGlmIChrZXlbMF0gIT09ICIkIiAmJiAhaXNSZXNlcnZlZFByb3Aoa2V5KSkgew0KICAgIHJldHVybiB0cnVlOw0KICB9IGVsc2Ugew0KICAgIHdhcm4kMShgSW52YWxpZCBwcm9wIG5hbWU6ICIke2tleX0iIGlzIGEgcmVzZXJ2ZWQgcHJvcGVydHkuYCk7DQogIH0NCiAgcmV0dXJuIGZhbHNlOw0KfQ0KZnVuY3Rpb24gZ2V0VHlwZShjdG9yKSB7DQogIGlmIChjdG9yID09PSBudWxsKSB7DQogICAgcmV0dXJuICJudWxsIjsNCiAgfQ0KICBpZiAodHlwZW9mIGN0b3IgPT09ICJmdW5jdGlvbiIpIHsNCiAgICByZXR1cm4gY3Rvci5uYW1lIHx8ICIiOw0KICB9IGVsc2UgaWYgKHR5cGVvZiBjdG9yID09PSAib2JqZWN0Iikgew0KICAgIGNvbnN0IG5hbWUgPSBjdG9yLmNvbnN0cnVjdG9yICYmIGN0b3IuY29uc3RydWN0b3IubmFtZTsNCiAgICByZXR1cm4gbmFtZSB8fCAiIjsNCiAgfQ0KICByZXR1cm4gIiI7DQp9DQpmdW5jdGlvbiB2YWxpZGF0ZVByb3BzKHJhd1Byb3BzLCBwcm9wcywgaW5zdGFuY2UpIHsNCiAgY29uc3QgcmVzb2x2ZWRWYWx1ZXMgPSB0b1Jhdyhwcm9wcyk7DQogIGNvbnN0IG9wdGlvbnMgPSBpbnN0YW5jZS5wcm9wc09wdGlvbnNbMF07DQogIGNvbnN0IGNhbWVsaXplUHJvcHNLZXkgPSBPYmplY3Qua2V5cyhyYXdQcm9wcykubWFwKChrZXkpID0+IGNhbWVsaXplKGtleSkpOw0KICBmb3IgKGNvbnN0IGtleSBpbiBvcHRpb25zKSB7DQogICAgbGV0IG9wdCA9IG9wdGlvbnNba2V5XTsNCiAgICBpZiAob3B0ID09IG51bGwpIGNvbnRpbnVlOw0KICAgIHZhbGlkYXRlUHJvcCgNCiAgICAgIGtleSwNCiAgICAgIHJlc29sdmVkVmFsdWVzW2tleV0sDQogICAgICBvcHQsDQogICAgICBzaGFsbG93UmVhZG9ubHkocmVzb2x2ZWRWYWx1ZXMpICwNCiAgICAgICFjYW1lbGl6ZVByb3BzS2V5LmluY2x1ZGVzKGtleSkNCiAgICApOw0KICB9DQp9DQpmdW5jdGlvbiB2YWxpZGF0ZVByb3AobmFtZSwgdmFsdWUsIHByb3AsIHByb3BzLCBpc0Fic2VudCkgew0KICBjb25zdCB7IHR5cGUsIHJlcXVpcmVkLCB2YWxpZGF0b3IsIHNraXBDaGVjayB9ID0gcHJvcDsNCiAgaWYgKHJlcXVpcmVkICYmIGlzQWJzZW50KSB7DQogICAgd2FybiQxKCdNaXNzaW5nIHJlcXVpcmVkIHByb3A6ICInICsgbmFtZSArICciJyk7DQogICAgcmV0dXJuOw0KICB9DQogIGlmICh2YWx1ZSA9PSBudWxsICYmICFyZXF1aXJlZCkgew0KICAgIHJldHVybjsNCiAgfQ0KICBpZiAodHlwZSAhPSBudWxsICYmIHR5cGUgIT09IHRydWUgJiYgIXNraXBDaGVjaykgew0KICAgIGxldCBpc1ZhbGlkID0gZmFsc2U7DQogICAgY29uc3QgdHlwZXMgPSBpc0FycmF5KHR5cGUpID8gdHlwZSA6IFt0eXBlXTsNCiAgICBjb25zdCBleHBlY3RlZFR5cGVzID0gW107DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0eXBlcy5sZW5ndGggJiYgIWlzVmFsaWQ7IGkrKykgew0KICAgICAgY29uc3QgeyB2YWxpZCwgZXhwZWN0ZWRUeXBlIH0gPSBhc3NlcnRUeXBlKHZhbHVlLCB0eXBlc1tpXSk7DQogICAgICBleHBlY3RlZFR5cGVzLnB1c2goZXhwZWN0ZWRUeXBlIHx8ICIiKTsNCiAgICAgIGlzVmFsaWQgPSB2YWxpZDsNCiAgICB9DQogICAgaWYgKCFpc1ZhbGlkKSB7DQogICAgICB3YXJuJDEoZ2V0SW52YWxpZFR5cGVNZXNzYWdlKG5hbWUsIHZhbHVlLCBleHBlY3RlZFR5cGVzKSk7DQogICAgICByZXR1cm47DQogICAgfQ0KICB9DQogIGlmICh2YWxpZGF0b3IgJiYgIXZhbGlkYXRvcih2YWx1ZSwgcHJvcHMpKSB7DQogICAgd2FybiQxKCdJbnZhbGlkIHByb3A6IGN1c3RvbSB2YWxpZGF0b3IgY2hlY2sgZmFpbGVkIGZvciBwcm9wICInICsgbmFtZSArICciLicpOw0KICB9DQp9DQpjb25zdCBpc1NpbXBsZVR5cGUgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcCgNCiAgIlN0cmluZyxOdW1iZXIsQm9vbGVhbixGdW5jdGlvbixTeW1ib2wsQmlnSW50Ig0KKTsNCmZ1bmN0aW9uIGFzc2VydFR5cGUodmFsdWUsIHR5cGUpIHsNCiAgbGV0IHZhbGlkOw0KICBjb25zdCBleHBlY3RlZFR5cGUgPSBnZXRUeXBlKHR5cGUpOw0KICBpZiAoZXhwZWN0ZWRUeXBlID09PSAibnVsbCIpIHsNCiAgICB2YWxpZCA9IHZhbHVlID09PSBudWxsOw0KICB9IGVsc2UgaWYgKGlzU2ltcGxlVHlwZShleHBlY3RlZFR5cGUpKSB7DQogICAgY29uc3QgdCA9IHR5cGVvZiB2YWx1ZTsNCiAgICB2YWxpZCA9IHQgPT09IGV4cGVjdGVkVHlwZS50b0xvd2VyQ2FzZSgpOw0KICAgIGlmICghdmFsaWQgJiYgdCA9PT0gIm9iamVjdCIpIHsNCiAgICAgIHZhbGlkID0gdmFsdWUgaW5zdGFuY2VvZiB0eXBlOw0KICAgIH0NCiAgfSBlbHNlIGlmIChleHBlY3RlZFR5cGUgPT09ICJPYmplY3QiKSB7DQogICAgdmFsaWQgPSBpc09iamVjdCh2YWx1ZSk7DQogIH0gZWxzZSBpZiAoZXhwZWN0ZWRUeXBlID09PSAiQXJyYXkiKSB7DQogICAgdmFsaWQgPSBpc0FycmF5KHZhbHVlKTsNCiAgfSBlbHNlIHsNCiAgICB2YWxpZCA9IHZhbHVlIGluc3RhbmNlb2YgdHlwZTsNCiAgfQ0KICByZXR1cm4gew0KICAgIHZhbGlkLA0KICAgIGV4cGVjdGVkVHlwZQ0KICB9Ow0KfQ0KZnVuY3Rpb24gZ2V0SW52YWxpZFR5cGVNZXNzYWdlKG5hbWUsIHZhbHVlLCBleHBlY3RlZFR5cGVzKSB7DQogIGlmIChleHBlY3RlZFR5cGVzLmxlbmd0aCA9PT0gMCkgew0KICAgIHJldHVybiBgUHJvcCB0eXBlIFtdIGZvciBwcm9wICIke25hbWV9IiB3b24ndCBtYXRjaCBhbnl0aGluZy4gRGlkIHlvdSBtZWFuIHRvIHVzZSB0eXBlIEFycmF5IGluc3RlYWQ/YDsNCiAgfQ0KICBsZXQgbWVzc2FnZSA9IGBJbnZhbGlkIHByb3A6IHR5cGUgY2hlY2sgZmFpbGVkIGZvciBwcm9wICIke25hbWV9Ii4gRXhwZWN0ZWQgJHtleHBlY3RlZFR5cGVzLm1hcChjYXBpdGFsaXplKS5qb2luKCIgfCAiKX1gOw0KICBjb25zdCBleHBlY3RlZFR5cGUgPSBleHBlY3RlZFR5cGVzWzBdOw0KICBjb25zdCByZWNlaXZlZFR5cGUgPSB0b1Jhd1R5cGUodmFsdWUpOw0KICBjb25zdCBleHBlY3RlZFZhbHVlID0gc3R5bGVWYWx1ZSh2YWx1ZSwgZXhwZWN0ZWRUeXBlKTsNCiAgY29uc3QgcmVjZWl2ZWRWYWx1ZSA9IHN0eWxlVmFsdWUodmFsdWUsIHJlY2VpdmVkVHlwZSk7DQogIGlmIChleHBlY3RlZFR5cGVzLmxlbmd0aCA9PT0gMSAmJiBpc0V4cGxpY2FibGUoZXhwZWN0ZWRUeXBlKSAmJiAhaXNCb29sZWFuKGV4cGVjdGVkVHlwZSwgcmVjZWl2ZWRUeXBlKSkgew0KICAgIG1lc3NhZ2UgKz0gYCB3aXRoIHZhbHVlICR7ZXhwZWN0ZWRWYWx1ZX1gOw0KICB9DQogIG1lc3NhZ2UgKz0gYCwgZ290ICR7cmVjZWl2ZWRUeXBlfSBgOw0KICBpZiAoaXNFeHBsaWNhYmxlKHJlY2VpdmVkVHlwZSkpIHsNCiAgICBtZXNzYWdlICs9IGB3aXRoIHZhbHVlICR7cmVjZWl2ZWRWYWx1ZX0uYDsNCiAgfQ0KICByZXR1cm4gbWVzc2FnZTsNCn0NCmZ1bmN0aW9uIHN0eWxlVmFsdWUodmFsdWUsIHR5cGUpIHsNCiAgaWYgKHR5cGUgPT09ICJTdHJpbmciKSB7DQogICAgcmV0dXJuIGAiJHt2YWx1ZX0iYDsNCiAgfSBlbHNlIGlmICh0eXBlID09PSAiTnVtYmVyIikgew0KICAgIHJldHVybiBgJHtOdW1iZXIodmFsdWUpfWA7DQogIH0gZWxzZSB7DQogICAgcmV0dXJuIGAke3ZhbHVlfWA7DQogIH0NCn0NCmZ1bmN0aW9uIGlzRXhwbGljYWJsZSh0eXBlKSB7DQogIGNvbnN0IGV4cGxpY2l0VHlwZXMgPSBbInN0cmluZyIsICJudW1iZXIiLCAiYm9vbGVhbiJdOw0KICByZXR1cm4gZXhwbGljaXRUeXBlcy5zb21lKChlbGVtKSA9PiB0eXBlLnRvTG93ZXJDYXNlKCkgPT09IGVsZW0pOw0KfQ0KZnVuY3Rpb24gaXNCb29sZWFuKC4uLmFyZ3MpIHsNCiAgcmV0dXJuIGFyZ3Muc29tZSgoZWxlbSkgPT4gZWxlbS50b0xvd2VyQ2FzZSgpID09PSAiYm9vbGVhbiIpOw0KfQ0KDQpjb25zdCBpc0ludGVybmFsS2V5ID0gKGtleSkgPT4ga2V5WzBdID09PSAiXyIgfHwga2V5ID09PSAiJHN0YWJsZSI7DQpjb25zdCBub3JtYWxpemVTbG90VmFsdWUgPSAodmFsdWUpID0+IGlzQXJyYXkodmFsdWUpID8gdmFsdWUubWFwKG5vcm1hbGl6ZVZOb2RlJDEpIDogW25vcm1hbGl6ZVZOb2RlJDEodmFsdWUpXTsNCmNvbnN0IG5vcm1hbGl6ZVNsb3QgPSAoa2V5LCByYXdTbG90LCBjdHgpID0+IHsNCiAgaWYgKHJhd1Nsb3QuX24pIHsNCiAgICByZXR1cm4gcmF3U2xvdDsNCiAgfQ0KICBjb25zdCBub3JtYWxpemVkID0gd2l0aEN0eCgoLi4uYXJncykgPT4gew0KICAgIGlmIChjdXJyZW50SW5zdGFuY2UgJiYgIShjdHggPT09IG51bGwgJiYgY3VycmVudFJlbmRlcmluZ0luc3RhbmNlKSAmJiAhKGN0eCAmJiBjdHgucm9vdCAhPT0gY3VycmVudEluc3RhbmNlLnJvb3QpKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGBTbG90ICIke2tleX0iIGludm9rZWQgb3V0c2lkZSBvZiB0aGUgcmVuZGVyIGZ1bmN0aW9uOiB0aGlzIHdpbGwgbm90IHRyYWNrIGRlcGVuZGVuY2llcyB1c2VkIGluIHRoZSBzbG90LiBJbnZva2UgdGhlIHNsb3QgZnVuY3Rpb24gaW5zaWRlIHRoZSByZW5kZXIgZnVuY3Rpb24gaW5zdGVhZC5gDQogICAgICApOw0KICAgIH0NCiAgICByZXR1cm4gbm9ybWFsaXplU2xvdFZhbHVlKHJhd1Nsb3QoLi4uYXJncykpOw0KICB9LCBjdHgpOw0KICBub3JtYWxpemVkLl9jID0gZmFsc2U7DQogIHJldHVybiBub3JtYWxpemVkOw0KfTsNCmNvbnN0IG5vcm1hbGl6ZU9iamVjdFNsb3RzID0gKHJhd1Nsb3RzLCBzbG90cywgaW5zdGFuY2UpID0+IHsNCiAgY29uc3QgY3R4ID0gcmF3U2xvdHMuX2N0eDsNCiAgZm9yIChjb25zdCBrZXkgaW4gcmF3U2xvdHMpIHsNCiAgICBpZiAoaXNJbnRlcm5hbEtleShrZXkpKSBjb250aW51ZTsNCiAgICBjb25zdCB2YWx1ZSA9IHJhd1Nsb3RzW2tleV07DQogICAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7DQogICAgICBzbG90c1trZXldID0gbm9ybWFsaXplU2xvdChrZXksIHZhbHVlLCBjdHgpOw0KICAgIH0gZWxzZSBpZiAodmFsdWUgIT0gbnVsbCkgew0KICAgICAgew0KICAgICAgICB3YXJuJDEoDQogICAgICAgICAgYE5vbi1mdW5jdGlvbiB2YWx1ZSBlbmNvdW50ZXJlZCBmb3Igc2xvdCAiJHtrZXl9Ii4gUHJlZmVyIGZ1bmN0aW9uIHNsb3RzIGZvciBiZXR0ZXIgcGVyZm9ybWFuY2UuYA0KICAgICAgICApOw0KICAgICAgfQ0KICAgICAgY29uc3Qgbm9ybWFsaXplZCA9IG5vcm1hbGl6ZVNsb3RWYWx1ZSh2YWx1ZSk7DQogICAgICBzbG90c1trZXldID0gKCkgPT4gbm9ybWFsaXplZDsNCiAgICB9DQogIH0NCn07DQpjb25zdCBub3JtYWxpemVWTm9kZVNsb3RzID0gKGluc3RhbmNlLCBjaGlsZHJlbikgPT4gew0KICBpZiAoIWlzS2VlcEFsaXZlKGluc3RhbmNlLnZub2RlKSAmJiB0cnVlKSB7DQogICAgd2FybiQxKA0KICAgICAgYE5vbi1mdW5jdGlvbiB2YWx1ZSBlbmNvdW50ZXJlZCBmb3IgZGVmYXVsdCBzbG90LiBQcmVmZXIgZnVuY3Rpb24gc2xvdHMgZm9yIGJldHRlciBwZXJmb3JtYW5jZS5gDQogICAgKTsNCiAgfQ0KICBjb25zdCBub3JtYWxpemVkID0gbm9ybWFsaXplU2xvdFZhbHVlKGNoaWxkcmVuKTsNCiAgaW5zdGFuY2Uuc2xvdHMuZGVmYXVsdCA9ICgpID0+IG5vcm1hbGl6ZWQ7DQp9Ow0KY29uc3QgYXNzaWduU2xvdHMgPSAoc2xvdHMsIGNoaWxkcmVuLCBvcHRpbWl6ZWQpID0+IHsNCiAgZm9yIChjb25zdCBrZXkgaW4gY2hpbGRyZW4pIHsNCiAgICBpZiAob3B0aW1pemVkIHx8ICFpc0ludGVybmFsS2V5KGtleSkpIHsNCiAgICAgIHNsb3RzW2tleV0gPSBjaGlsZHJlbltrZXldOw0KICAgIH0NCiAgfQ0KfTsNCmNvbnN0IGluaXRTbG90cyA9IChpbnN0YW5jZSwgY2hpbGRyZW4sIG9wdGltaXplZCkgPT4gew0KICBjb25zdCBzbG90cyA9IGluc3RhbmNlLnNsb3RzID0gY3JlYXRlSW50ZXJuYWxPYmplY3QoKTsNCiAgaWYgKGluc3RhbmNlLnZub2RlLnNoYXBlRmxhZyAmIDMyKSB7DQogICAgY29uc3QgY2FjaGVJbmRleGVzID0gY2hpbGRyZW4uX187DQogICAgaWYgKGNhY2hlSW5kZXhlcykgZGVmKHNsb3RzLCAiX18iLCBjYWNoZUluZGV4ZXMsIHRydWUpOw0KICAgIGNvbnN0IHR5cGUgPSBjaGlsZHJlbi5fOw0KICAgIGlmICh0eXBlKSB7DQogICAgICBhc3NpZ25TbG90cyhzbG90cywgY2hpbGRyZW4sIG9wdGltaXplZCk7DQogICAgICBpZiAob3B0aW1pemVkKSB7DQogICAgICAgIGRlZihzbG90cywgIl8iLCB0eXBlLCB0cnVlKTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgbm9ybWFsaXplT2JqZWN0U2xvdHMoY2hpbGRyZW4sIHNsb3RzKTsNCiAgICB9DQogIH0gZWxzZSBpZiAoY2hpbGRyZW4pIHsNCiAgICBub3JtYWxpemVWTm9kZVNsb3RzKGluc3RhbmNlLCBjaGlsZHJlbik7DQogIH0NCn07DQpjb25zdCB1cGRhdGVTbG90cyA9IChpbnN0YW5jZSwgY2hpbGRyZW4sIG9wdGltaXplZCkgPT4gew0KICBjb25zdCB7IHZub2RlLCBzbG90cyB9ID0gaW5zdGFuY2U7DQogIGxldCBuZWVkRGVsZXRpb25DaGVjayA9IHRydWU7DQogIGxldCBkZWxldGlvbkNvbXBhcmlzb25UYXJnZXQgPSBFTVBUWV9PQko7DQogIGlmICh2bm9kZS5zaGFwZUZsYWcgJiAzMikgew0KICAgIGNvbnN0IHR5cGUgPSBjaGlsZHJlbi5fOw0KICAgIGlmICh0eXBlKSB7DQogICAgICBpZiAoaXNIbXJVcGRhdGluZykgew0KICAgICAgICBhc3NpZ25TbG90cyhzbG90cywgY2hpbGRyZW4sIG9wdGltaXplZCk7DQogICAgICAgIHRyaWdnZXIoaW5zdGFuY2UsICJzZXQiLCAiJHNsb3RzIik7DQogICAgICB9IGVsc2UgaWYgKG9wdGltaXplZCAmJiB0eXBlID09PSAxKSB7DQogICAgICAgIG5lZWREZWxldGlvbkNoZWNrID0gZmFsc2U7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBhc3NpZ25TbG90cyhzbG90cywgY2hpbGRyZW4sIG9wdGltaXplZCk7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIG5lZWREZWxldGlvbkNoZWNrID0gIWNoaWxkcmVuLiRzdGFibGU7DQogICAgICBub3JtYWxpemVPYmplY3RTbG90cyhjaGlsZHJlbiwgc2xvdHMpOw0KICAgIH0NCiAgICBkZWxldGlvbkNvbXBhcmlzb25UYXJnZXQgPSBjaGlsZHJlbjsNCiAgfSBlbHNlIGlmIChjaGlsZHJlbikgew0KICAgIG5vcm1hbGl6ZVZOb2RlU2xvdHMoaW5zdGFuY2UsIGNoaWxkcmVuKTsNCiAgICBkZWxldGlvbkNvbXBhcmlzb25UYXJnZXQgPSB7IGRlZmF1bHQ6IDEgfTsNCiAgfQ0KICBpZiAobmVlZERlbGV0aW9uQ2hlY2spIHsNCiAgICBmb3IgKGNvbnN0IGtleSBpbiBzbG90cykgew0KICAgICAgaWYgKCFpc0ludGVybmFsS2V5KGtleSkgJiYgZGVsZXRpb25Db21wYXJpc29uVGFyZ2V0W2tleV0gPT0gbnVsbCkgew0KICAgICAgICBkZWxldGUgc2xvdHNba2V5XTsNCiAgICAgIH0NCiAgICB9DQogIH0NCn07DQoNCmxldCBzdXBwb3J0ZWQ7DQpsZXQgcGVyZjsNCmZ1bmN0aW9uIHN0YXJ0TWVhc3VyZShpbnN0YW5jZSwgdHlwZSkgew0KICBpZiAoaW5zdGFuY2UuYXBwQ29udGV4dC5jb25maWcucGVyZm9ybWFuY2UgJiYgaXNTdXBwb3J0ZWQoKSkgew0KICAgIHBlcmYubWFyayhgdnVlLSR7dHlwZX0tJHtpbnN0YW5jZS51aWR9YCk7DQogIH0NCiAgew0KICAgIGRldnRvb2xzUGVyZlN0YXJ0KGluc3RhbmNlLCB0eXBlLCBpc1N1cHBvcnRlZCgpID8gcGVyZi5ub3coKSA6IERhdGUubm93KCkpOw0KICB9DQp9DQpmdW5jdGlvbiBlbmRNZWFzdXJlKGluc3RhbmNlLCB0eXBlKSB7DQogIGlmIChpbnN0YW5jZS5hcHBDb250ZXh0LmNvbmZpZy5wZXJmb3JtYW5jZSAmJiBpc1N1cHBvcnRlZCgpKSB7DQogICAgY29uc3Qgc3RhcnRUYWcgPSBgdnVlLSR7dHlwZX0tJHtpbnN0YW5jZS51aWR9YDsNCiAgICBjb25zdCBlbmRUYWcgPSBzdGFydFRhZyArIGA6ZW5kYDsNCiAgICBwZXJmLm1hcmsoZW5kVGFnKTsNCiAgICBwZXJmLm1lYXN1cmUoDQogICAgICBgPCR7Zm9ybWF0Q29tcG9uZW50TmFtZShpbnN0YW5jZSwgaW5zdGFuY2UudHlwZSl9PiAke3R5cGV9YCwNCiAgICAgIHN0YXJ0VGFnLA0KICAgICAgZW5kVGFnDQogICAgKTsNCiAgICBwZXJmLmNsZWFyTWFya3Moc3RhcnRUYWcpOw0KICAgIHBlcmYuY2xlYXJNYXJrcyhlbmRUYWcpOw0KICB9DQogIHsNCiAgICBkZXZ0b29sc1BlcmZFbmQoaW5zdGFuY2UsIHR5cGUsIGlzU3VwcG9ydGVkKCkgPyBwZXJmLm5vdygpIDogRGF0ZS5ub3coKSk7DQogIH0NCn0NCmZ1bmN0aW9uIGlzU3VwcG9ydGVkKCkgew0KICBpZiAoc3VwcG9ydGVkICE9PSB2b2lkIDApIHsNCiAgICByZXR1cm4gc3VwcG9ydGVkOw0KICB9DQogIGlmICh0eXBlb2Ygd2luZG93ICE9PSAidW5kZWZpbmVkIiAmJiB3aW5kb3cucGVyZm9ybWFuY2UpIHsNCiAgICBzdXBwb3J0ZWQgPSB0cnVlOw0KICAgIHBlcmYgPSB3aW5kb3cucGVyZm9ybWFuY2U7DQogIH0gZWxzZSB7DQogICAgc3VwcG9ydGVkID0gZmFsc2U7DQogIH0NCiAgcmV0dXJuIHN1cHBvcnRlZDsNCn0NCg0KY29uc3QgcXVldWVQb3N0UmVuZGVyRWZmZWN0ID0gcXVldWVFZmZlY3RXaXRoU3VzcGVuc2UgOw0KZnVuY3Rpb24gY3JlYXRlUmVuZGVyZXIob3B0aW9ucykgew0KICByZXR1cm4gYmFzZUNyZWF0ZVJlbmRlcmVyKG9wdGlvbnMpOw0KfQ0KZnVuY3Rpb24gYmFzZUNyZWF0ZVJlbmRlcmVyKG9wdGlvbnMsIGNyZWF0ZUh5ZHJhdGlvbkZucykgew0KICBjb25zdCB0YXJnZXQgPSBnZXRHbG9iYWxUaGlzKCk7DQogIHRhcmdldC5fX1ZVRV9fID0gdHJ1ZTsNCiAgew0KICAgIHNldERldnRvb2xzSG9vayh0YXJnZXQuX19WVUVfREVWVE9PTFNfR0xPQkFMX0hPT0tfXywgdGFyZ2V0KTsNCiAgfQ0KICBjb25zdCB7DQogICAgaW5zZXJ0OiBob3N0SW5zZXJ0LA0KICAgIHJlbW92ZTogaG9zdFJlbW92ZSwNCiAgICBwYXRjaFByb3A6IGhvc3RQYXRjaFByb3AsDQogICAgY3JlYXRlRWxlbWVudDogaG9zdENyZWF0ZUVsZW1lbnQsDQogICAgY3JlYXRlVGV4dDogaG9zdENyZWF0ZVRleHQsDQogICAgY3JlYXRlQ29tbWVudDogaG9zdENyZWF0ZUNvbW1lbnQsDQogICAgc2V0VGV4dDogaG9zdFNldFRleHQsDQogICAgc2V0RWxlbWVudFRleHQ6IGhvc3RTZXRFbGVtZW50VGV4dCwNCiAgICBwYXJlbnROb2RlOiBob3N0UGFyZW50Tm9kZSwNCiAgICBuZXh0U2libGluZzogaG9zdE5leHRTaWJsaW5nLA0KICAgIHNldFNjb3BlSWQ6IGhvc3RTZXRTY29wZUlkID0gTk9PUCwNCiAgICBpbnNlcnRTdGF0aWNDb250ZW50OiBob3N0SW5zZXJ0U3RhdGljQ29udGVudA0KICB9ID0gb3B0aW9uczsNCiAgY29uc3QgcGF0Y2ggPSAobjEsIG4yLCBjb250YWluZXIsIGFuY2hvciA9IG51bGwsIHBhcmVudENvbXBvbmVudCA9IG51bGwsIHBhcmVudFN1c3BlbnNlID0gbnVsbCwgbmFtZXNwYWNlID0gdm9pZCAwLCBzbG90U2NvcGVJZHMgPSBudWxsLCBvcHRpbWl6ZWQgPSBpc0htclVwZGF0aW5nID8gZmFsc2UgOiAhIW4yLmR5bmFtaWNDaGlsZHJlbikgPT4gew0KICAgIGlmIChuMSA9PT0gbjIpIHsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgaWYgKG4xICYmICFpc1NhbWVWTm9kZVR5cGUobjEsIG4yKSkgew0KICAgICAgYW5jaG9yID0gZ2V0TmV4dEhvc3ROb2RlKG4xKTsNCiAgICAgIHVubW91bnQobjEsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIHRydWUpOw0KICAgICAgbjEgPSBudWxsOw0KICAgIH0NCiAgICBpZiAobjIucGF0Y2hGbGFnID09PSAtMikgew0KICAgICAgb3B0aW1pemVkID0gZmFsc2U7DQogICAgICBuMi5keW5hbWljQ2hpbGRyZW4gPSBudWxsOw0KICAgIH0NCiAgICBjb25zdCB7IHR5cGUsIHJlZiwgc2hhcGVGbGFnIH0gPSBuMjsNCiAgICBzd2l0Y2ggKHR5cGUpIHsNCiAgICAgIGNhc2UgVGV4dDoNCiAgICAgICAgcHJvY2Vzc1RleHQobjEsIG4yLCBjb250YWluZXIsIGFuY2hvcik7DQogICAgICAgIGJyZWFrOw0KICAgICAgY2FzZSBDb21tZW50Og0KICAgICAgICBwcm9jZXNzQ29tbWVudE5vZGUobjEsIG4yLCBjb250YWluZXIsIGFuY2hvcik7DQogICAgICAgIGJyZWFrOw0KICAgICAgY2FzZSBTdGF0aWM6DQogICAgICAgIGlmIChuMSA9PSBudWxsKSB7DQogICAgICAgICAgbW91bnRTdGF0aWNOb2RlKG4yLCBjb250YWluZXIsIGFuY2hvciwgbmFtZXNwYWNlKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBwYXRjaFN0YXRpY05vZGUobjEsIG4yLCBjb250YWluZXIsIG5hbWVzcGFjZSk7DQogICAgICAgIH0NCiAgICAgICAgYnJlYWs7DQogICAgICBjYXNlIEZyYWdtZW50Og0KICAgICAgICBwcm9jZXNzRnJhZ21lbnQoDQogICAgICAgICAgbjEsDQogICAgICAgICAgbjIsDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIGFuY2hvciwNCiAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgKTsNCiAgICAgICAgYnJlYWs7DQogICAgICBkZWZhdWx0Og0KICAgICAgICBpZiAoc2hhcGVGbGFnICYgMSkgew0KICAgICAgICAgIHByb2Nlc3NFbGVtZW50KA0KICAgICAgICAgICAgbjEsDQogICAgICAgICAgICBuMiwNCiAgICAgICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgICAgIGFuY2hvciwNCiAgICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICAgKTsNCiAgICAgICAgfSBlbHNlIGlmIChzaGFwZUZsYWcgJiA2KSB7DQogICAgICAgICAgcHJvY2Vzc0NvbXBvbmVudCgNCiAgICAgICAgICAgIG4xLA0KICAgICAgICAgICAgbjIsDQogICAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgICBhbmNob3IsDQogICAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICAgICk7DQogICAgICAgIH0gZWxzZSBpZiAoc2hhcGVGbGFnICYgNjQpIHsNCiAgICAgICAgICB0eXBlLnByb2Nlc3MoDQogICAgICAgICAgICBuMSwNCiAgICAgICAgICAgIG4yLA0KICAgICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgICBvcHRpbWl6ZWQsDQogICAgICAgICAgICBpbnRlcm5hbHMNCiAgICAgICAgICApOw0KICAgICAgICB9IGVsc2UgaWYgKHNoYXBlRmxhZyAmIDEyOCkgew0KICAgICAgICAgIHR5cGUucHJvY2VzcygNCiAgICAgICAgICAgIG4xLA0KICAgICAgICAgICAgbjIsDQogICAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgICBhbmNob3IsDQogICAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICAgIG9wdGltaXplZCwNCiAgICAgICAgICAgIGludGVybmFscw0KICAgICAgICAgICk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgd2FybiQxKCJJbnZhbGlkIFZOb2RlIHR5cGU6IiwgdHlwZSwgYCgke3R5cGVvZiB0eXBlfSlgKTsNCiAgICAgICAgfQ0KICAgIH0NCiAgICBpZiAocmVmICE9IG51bGwgJiYgcGFyZW50Q29tcG9uZW50KSB7DQogICAgICBzZXRSZWYocmVmLCBuMSAmJiBuMS5yZWYsIHBhcmVudFN1c3BlbnNlLCBuMiB8fCBuMSwgIW4yKTsNCiAgICB9IGVsc2UgaWYgKHJlZiA9PSBudWxsICYmIG4xICYmIG4xLnJlZiAhPSBudWxsKSB7DQogICAgICBzZXRSZWYobjEucmVmLCBudWxsLCBwYXJlbnRTdXNwZW5zZSwgbjEsIHRydWUpOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgcHJvY2Vzc1RleHQgPSAobjEsIG4yLCBjb250YWluZXIsIGFuY2hvcikgPT4gew0KICAgIGlmIChuMSA9PSBudWxsKSB7DQogICAgICBob3N0SW5zZXJ0KA0KICAgICAgICBuMi5lbCA9IGhvc3RDcmVhdGVUZXh0KG4yLmNoaWxkcmVuKSwNCiAgICAgICAgY29udGFpbmVyLA0KICAgICAgICBhbmNob3INCiAgICAgICk7DQogICAgfSBlbHNlIHsNCiAgICAgIGNvbnN0IGVsID0gbjIuZWwgPSBuMS5lbDsNCiAgICAgIGlmIChuMi5jaGlsZHJlbiAhPT0gbjEuY2hpbGRyZW4pIHsNCiAgICAgICAgaG9zdFNldFRleHQoZWwsIG4yLmNoaWxkcmVuKTsNCiAgICAgIH0NCiAgICB9DQogIH07DQogIGNvbnN0IHByb2Nlc3NDb21tZW50Tm9kZSA9IChuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yKSA9PiB7DQogICAgaWYgKG4xID09IG51bGwpIHsNCiAgICAgIGhvc3RJbnNlcnQoDQogICAgICAgIG4yLmVsID0gaG9zdENyZWF0ZUNvbW1lbnQobjIuY2hpbGRyZW4gfHwgIiIpLA0KICAgICAgICBjb250YWluZXIsDQogICAgICAgIGFuY2hvcg0KICAgICAgKTsNCiAgICB9IGVsc2Ugew0KICAgICAgbjIuZWwgPSBuMS5lbDsNCiAgICB9DQogIH07DQogIGNvbnN0IG1vdW50U3RhdGljTm9kZSA9IChuMiwgY29udGFpbmVyLCBhbmNob3IsIG5hbWVzcGFjZSkgPT4gew0KICAgIFtuMi5lbCwgbjIuYW5jaG9yXSA9IGhvc3RJbnNlcnRTdGF0aWNDb250ZW50KA0KICAgICAgbjIuY2hpbGRyZW4sDQogICAgICBjb250YWluZXIsDQogICAgICBhbmNob3IsDQogICAgICBuYW1lc3BhY2UsDQogICAgICBuMi5lbCwNCiAgICAgIG4yLmFuY2hvcg0KICAgICk7DQogIH07DQogIGNvbnN0IHBhdGNoU3RhdGljTm9kZSA9IChuMSwgbjIsIGNvbnRhaW5lciwgbmFtZXNwYWNlKSA9PiB7DQogICAgaWYgKG4yLmNoaWxkcmVuICE9PSBuMS5jaGlsZHJlbikgew0KICAgICAgY29uc3QgYW5jaG9yID0gaG9zdE5leHRTaWJsaW5nKG4xLmFuY2hvcik7DQogICAgICByZW1vdmVTdGF0aWNOb2RlKG4xKTsNCiAgICAgIFtuMi5lbCwgbjIuYW5jaG9yXSA9IGhvc3RJbnNlcnRTdGF0aWNDb250ZW50KA0KICAgICAgICBuMi5jaGlsZHJlbiwNCiAgICAgICAgY29udGFpbmVyLA0KICAgICAgICBhbmNob3IsDQogICAgICAgIG5hbWVzcGFjZQ0KICAgICAgKTsNCiAgICB9IGVsc2Ugew0KICAgICAgbjIuZWwgPSBuMS5lbDsNCiAgICAgIG4yLmFuY2hvciA9IG4xLmFuY2hvcjsNCiAgICB9DQogIH07DQogIGNvbnN0IG1vdmVTdGF0aWNOb2RlID0gKHsgZWwsIGFuY2hvciB9LCBjb250YWluZXIsIG5leHRTaWJsaW5nKSA9PiB7DQogICAgbGV0IG5leHQ7DQogICAgd2hpbGUgKGVsICYmIGVsICE9PSBhbmNob3IpIHsNCiAgICAgIG5leHQgPSBob3N0TmV4dFNpYmxpbmcoZWwpOw0KICAgICAgaG9zdEluc2VydChlbCwgY29udGFpbmVyLCBuZXh0U2libGluZyk7DQogICAgICBlbCA9IG5leHQ7DQogICAgfQ0KICAgIGhvc3RJbnNlcnQoYW5jaG9yLCBjb250YWluZXIsIG5leHRTaWJsaW5nKTsNCiAgfTsNCiAgY29uc3QgcmVtb3ZlU3RhdGljTm9kZSA9ICh7IGVsLCBhbmNob3IgfSkgPT4gew0KICAgIGxldCBuZXh0Ow0KICAgIHdoaWxlIChlbCAmJiBlbCAhPT0gYW5jaG9yKSB7DQogICAgICBuZXh0ID0gaG9zdE5leHRTaWJsaW5nKGVsKTsNCiAgICAgIGhvc3RSZW1vdmUoZWwpOw0KICAgICAgZWwgPSBuZXh0Ow0KICAgIH0NCiAgICBob3N0UmVtb3ZlKGFuY2hvcik7DQogIH07DQogIGNvbnN0IHByb2Nlc3NFbGVtZW50ID0gKG4xLCBuMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQpID0+IHsNCiAgICBpZiAobjIudHlwZSA9PT0gInN2ZyIpIHsNCiAgICAgIG5hbWVzcGFjZSA9ICJzdmciOw0KICAgIH0gZWxzZSBpZiAobjIudHlwZSA9PT0gIm1hdGgiKSB7DQogICAgICBuYW1lc3BhY2UgPSAibWF0aG1sIjsNCiAgICB9DQogICAgaWYgKG4xID09IG51bGwpIHsNCiAgICAgIG1vdW50RWxlbWVudCgNCiAgICAgICAgbjIsDQogICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgYW5jaG9yLA0KICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgb3B0aW1pemVkDQogICAgICApOw0KICAgIH0gZWxzZSB7DQogICAgICBwYXRjaEVsZW1lbnQoDQogICAgICAgIG4xLA0KICAgICAgICBuMiwNCiAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgIG9wdGltaXplZA0KICAgICAgKTsNCiAgICB9DQogIH07DQogIGNvbnN0IG1vdW50RWxlbWVudCA9ICh2bm9kZSwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQpID0+IHsNCiAgICBsZXQgZWw7DQogICAgbGV0IHZub2RlSG9vazsNCiAgICBjb25zdCB7IHByb3BzLCBzaGFwZUZsYWcsIHRyYW5zaXRpb24sIGRpcnMgfSA9IHZub2RlOw0KICAgIGVsID0gdm5vZGUuZWwgPSBob3N0Q3JlYXRlRWxlbWVudCgNCiAgICAgIHZub2RlLnR5cGUsDQogICAgICBuYW1lc3BhY2UsDQogICAgICBwcm9wcyAmJiBwcm9wcy5pcywNCiAgICAgIHByb3BzDQogICAgKTsNCiAgICBpZiAoc2hhcGVGbGFnICYgOCkgew0KICAgICAgaG9zdFNldEVsZW1lbnRUZXh0KGVsLCB2bm9kZS5jaGlsZHJlbik7DQogICAgfSBlbHNlIGlmIChzaGFwZUZsYWcgJiAxNikgew0KICAgICAgbW91bnRDaGlsZHJlbigNCiAgICAgICAgdm5vZGUuY2hpbGRyZW4sDQogICAgICAgIGVsLA0KICAgICAgICBudWxsLA0KICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICByZXNvbHZlQ2hpbGRyZW5OYW1lc3BhY2Uodm5vZGUsIG5hbWVzcGFjZSksDQogICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgb3B0aW1pemVkDQogICAgICApOw0KICAgIH0NCiAgICBpZiAoZGlycykgew0KICAgICAgaW52b2tlRGlyZWN0aXZlSG9vayh2bm9kZSwgbnVsbCwgcGFyZW50Q29tcG9uZW50LCAiY3JlYXRlZCIpOw0KICAgIH0NCiAgICBzZXRTY29wZUlkKGVsLCB2bm9kZSwgdm5vZGUuc2NvcGVJZCwgc2xvdFNjb3BlSWRzLCBwYXJlbnRDb21wb25lbnQpOw0KICAgIGlmIChwcm9wcykgew0KICAgICAgZm9yIChjb25zdCBrZXkgaW4gcHJvcHMpIHsNCiAgICAgICAgaWYgKGtleSAhPT0gInZhbHVlIiAmJiAhaXNSZXNlcnZlZFByb3Aoa2V5KSkgew0KICAgICAgICAgIGhvc3RQYXRjaFByb3AoZWwsIGtleSwgbnVsbCwgcHJvcHNba2V5XSwgbmFtZXNwYWNlLCBwYXJlbnRDb21wb25lbnQpOw0KICAgICAgICB9DQogICAgICB9DQogICAgICBpZiAoInZhbHVlIiBpbiBwcm9wcykgew0KICAgICAgICBob3N0UGF0Y2hQcm9wKGVsLCAidmFsdWUiLCBudWxsLCBwcm9wcy52YWx1ZSwgbmFtZXNwYWNlKTsNCiAgICAgIH0NCiAgICAgIGlmICh2bm9kZUhvb2sgPSBwcm9wcy5vblZub2RlQmVmb3JlTW91bnQpIHsNCiAgICAgICAgaW52b2tlVk5vZGVIb29rKHZub2RlSG9vaywgcGFyZW50Q29tcG9uZW50LCB2bm9kZSk7DQogICAgICB9DQogICAgfQ0KICAgIHsNCiAgICAgIGRlZihlbCwgIl9fdm5vZGUiLCB2bm9kZSwgdHJ1ZSk7DQogICAgICBkZWYoZWwsICJfX3Z1ZVBhcmVudENvbXBvbmVudCIsIHBhcmVudENvbXBvbmVudCwgdHJ1ZSk7DQogICAgfQ0KICAgIGlmIChkaXJzKSB7DQogICAgICBpbnZva2VEaXJlY3RpdmVIb29rKHZub2RlLCBudWxsLCBwYXJlbnRDb21wb25lbnQsICJiZWZvcmVNb3VudCIpOw0KICAgIH0NCiAgICBjb25zdCBuZWVkQ2FsbFRyYW5zaXRpb25Ib29rcyA9IG5lZWRUcmFuc2l0aW9uKHBhcmVudFN1c3BlbnNlLCB0cmFuc2l0aW9uKTsNCiAgICBpZiAobmVlZENhbGxUcmFuc2l0aW9uSG9va3MpIHsNCiAgICAgIHRyYW5zaXRpb24uYmVmb3JlRW50ZXIoZWwpOw0KICAgIH0NCiAgICBob3N0SW5zZXJ0KGVsLCBjb250YWluZXIsIGFuY2hvcik7DQogICAgaWYgKCh2bm9kZUhvb2sgPSBwcm9wcyAmJiBwcm9wcy5vblZub2RlTW91bnRlZCkgfHwgbmVlZENhbGxUcmFuc2l0aW9uSG9va3MgfHwgZGlycykgew0KICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KCgpID0+IHsNCiAgICAgICAgdm5vZGVIb29rICYmIGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIHBhcmVudENvbXBvbmVudCwgdm5vZGUpOw0KICAgICAgICBuZWVkQ2FsbFRyYW5zaXRpb25Ib29rcyAmJiB0cmFuc2l0aW9uLmVudGVyKGVsKTsNCiAgICAgICAgZGlycyAmJiBpbnZva2VEaXJlY3RpdmVIb29rKHZub2RlLCBudWxsLCBwYXJlbnRDb21wb25lbnQsICJtb3VudGVkIik7DQogICAgICB9LCBwYXJlbnRTdXNwZW5zZSk7DQogICAgfQ0KICB9Ow0KICBjb25zdCBzZXRTY29wZUlkID0gKGVsLCB2bm9kZSwgc2NvcGVJZCwgc2xvdFNjb3BlSWRzLCBwYXJlbnRDb21wb25lbnQpID0+IHsNCiAgICBpZiAoc2NvcGVJZCkgew0KICAgICAgaG9zdFNldFNjb3BlSWQoZWwsIHNjb3BlSWQpOw0KICAgIH0NCiAgICBpZiAoc2xvdFNjb3BlSWRzKSB7DQogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNsb3RTY29wZUlkcy5sZW5ndGg7IGkrKykgew0KICAgICAgICBob3N0U2V0U2NvcGVJZChlbCwgc2xvdFNjb3BlSWRzW2ldKTsNCiAgICAgIH0NCiAgICB9DQogICAgaWYgKHBhcmVudENvbXBvbmVudCkgew0KICAgICAgbGV0IHN1YlRyZWUgPSBwYXJlbnRDb21wb25lbnQuc3ViVHJlZTsNCiAgICAgIGlmIChzdWJUcmVlLnBhdGNoRmxhZyA+IDAgJiYgc3ViVHJlZS5wYXRjaEZsYWcgJiAyMDQ4KSB7DQogICAgICAgIHN1YlRyZWUgPSBmaWx0ZXJTaW5nbGVSb290KHN1YlRyZWUuY2hpbGRyZW4pIHx8IHN1YlRyZWU7DQogICAgICB9DQogICAgICBpZiAodm5vZGUgPT09IHN1YlRyZWUgfHwgaXNTdXNwZW5zZShzdWJUcmVlLnR5cGUpICYmIChzdWJUcmVlLnNzQ29udGVudCA9PT0gdm5vZGUgfHwgc3ViVHJlZS5zc0ZhbGxiYWNrID09PSB2bm9kZSkpIHsNCiAgICAgICAgY29uc3QgcGFyZW50Vk5vZGUgPSBwYXJlbnRDb21wb25lbnQudm5vZGU7DQogICAgICAgIHNldFNjb3BlSWQoDQogICAgICAgICAgZWwsDQogICAgICAgICAgcGFyZW50Vk5vZGUsDQogICAgICAgICAgcGFyZW50Vk5vZGUuc2NvcGVJZCwNCiAgICAgICAgICBwYXJlbnRWTm9kZS5zbG90U2NvcGVJZHMsDQogICAgICAgICAgcGFyZW50Q29tcG9uZW50LnBhcmVudA0KICAgICAgICApOw0KICAgICAgfQ0KICAgIH0NCiAgfTsNCiAgY29uc3QgbW91bnRDaGlsZHJlbiA9IChjaGlsZHJlbiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQsIHN0YXJ0ID0gMCkgPT4gew0KICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7DQogICAgICBjb25zdCBjaGlsZCA9IGNoaWxkcmVuW2ldID0gb3B0aW1pemVkID8gY2xvbmVJZk1vdW50ZWQoY2hpbGRyZW5baV0pIDogbm9ybWFsaXplVk5vZGUkMShjaGlsZHJlbltpXSk7DQogICAgICBwYXRjaCgNCiAgICAgICAgbnVsbCwNCiAgICAgICAgY2hpbGQsDQogICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgYW5jaG9yLA0KICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgb3B0aW1pemVkDQogICAgICApOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgcGF0Y2hFbGVtZW50ID0gKG4xLCBuMiwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgbmFtZXNwYWNlLCBzbG90U2NvcGVJZHMsIG9wdGltaXplZCkgPT4gew0KICAgIGNvbnN0IGVsID0gbjIuZWwgPSBuMS5lbDsNCiAgICB7DQogICAgICBlbC5fX3Zub2RlID0gbjI7DQogICAgfQ0KICAgIGxldCB7IHBhdGNoRmxhZywgZHluYW1pY0NoaWxkcmVuLCBkaXJzIH0gPSBuMjsNCiAgICBwYXRjaEZsYWcgfD0gbjEucGF0Y2hGbGFnICYgMTY7DQogICAgY29uc3Qgb2xkUHJvcHMgPSBuMS5wcm9wcyB8fCBFTVBUWV9PQko7DQogICAgY29uc3QgbmV3UHJvcHMgPSBuMi5wcm9wcyB8fCBFTVBUWV9PQko7DQogICAgbGV0IHZub2RlSG9vazsNCiAgICBwYXJlbnRDb21wb25lbnQgJiYgdG9nZ2xlUmVjdXJzZShwYXJlbnRDb21wb25lbnQsIGZhbHNlKTsNCiAgICBpZiAodm5vZGVIb29rID0gbmV3UHJvcHMub25Wbm9kZUJlZm9yZVVwZGF0ZSkgew0KICAgICAgaW52b2tlVk5vZGVIb29rKHZub2RlSG9vaywgcGFyZW50Q29tcG9uZW50LCBuMiwgbjEpOw0KICAgIH0NCiAgICBpZiAoZGlycykgew0KICAgICAgaW52b2tlRGlyZWN0aXZlSG9vayhuMiwgbjEsIHBhcmVudENvbXBvbmVudCwgImJlZm9yZVVwZGF0ZSIpOw0KICAgIH0NCiAgICBwYXJlbnRDb21wb25lbnQgJiYgdG9nZ2xlUmVjdXJzZShwYXJlbnRDb21wb25lbnQsIHRydWUpOw0KICAgIGlmIChpc0htclVwZGF0aW5nKSB7DQogICAgICBwYXRjaEZsYWcgPSAwOw0KICAgICAgb3B0aW1pemVkID0gZmFsc2U7DQogICAgICBkeW5hbWljQ2hpbGRyZW4gPSBudWxsOw0KICAgIH0NCiAgICBpZiAob2xkUHJvcHMuaW5uZXJIVE1MICYmIG5ld1Byb3BzLmlubmVySFRNTCA9PSBudWxsIHx8IG9sZFByb3BzLnRleHRDb250ZW50ICYmIG5ld1Byb3BzLnRleHRDb250ZW50ID09IG51bGwpIHsNCiAgICAgIGhvc3RTZXRFbGVtZW50VGV4dChlbCwgIiIpOw0KICAgIH0NCiAgICBpZiAoZHluYW1pY0NoaWxkcmVuKSB7DQogICAgICBwYXRjaEJsb2NrQ2hpbGRyZW4oDQogICAgICAgIG4xLmR5bmFtaWNDaGlsZHJlbiwNCiAgICAgICAgZHluYW1pY0NoaWxkcmVuLA0KICAgICAgICBlbCwNCiAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgcmVzb2x2ZUNoaWxkcmVuTmFtZXNwYWNlKG4yLCBuYW1lc3BhY2UpLA0KICAgICAgICBzbG90U2NvcGVJZHMNCiAgICAgICk7DQogICAgICB7DQogICAgICAgIHRyYXZlcnNlU3RhdGljQ2hpbGRyZW4objEsIG4yKTsNCiAgICAgIH0NCiAgICB9IGVsc2UgaWYgKCFvcHRpbWl6ZWQpIHsNCiAgICAgIHBhdGNoQ2hpbGRyZW4oDQogICAgICAgIG4xLA0KICAgICAgICBuMiwNCiAgICAgICAgZWwsDQogICAgICAgIG51bGwsDQogICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgIHJlc29sdmVDaGlsZHJlbk5hbWVzcGFjZShuMiwgbmFtZXNwYWNlKSwNCiAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICBmYWxzZQ0KICAgICAgKTsNCiAgICB9DQogICAgaWYgKHBhdGNoRmxhZyA+IDApIHsNCiAgICAgIGlmIChwYXRjaEZsYWcgJiAxNikgew0KICAgICAgICBwYXRjaFByb3BzKGVsLCBvbGRQcm9wcywgbmV3UHJvcHMsIHBhcmVudENvbXBvbmVudCwgbmFtZXNwYWNlKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGlmIChwYXRjaEZsYWcgJiAyKSB7DQogICAgICAgICAgaWYgKG9sZFByb3BzLmNsYXNzICE9PSBuZXdQcm9wcy5jbGFzcykgew0KICAgICAgICAgICAgaG9zdFBhdGNoUHJvcChlbCwgImNsYXNzIiwgbnVsbCwgbmV3UHJvcHMuY2xhc3MsIG5hbWVzcGFjZSk7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGlmIChwYXRjaEZsYWcgJiA0KSB7DQogICAgICAgICAgaG9zdFBhdGNoUHJvcChlbCwgInN0eWxlIiwgb2xkUHJvcHMuc3R5bGUsIG5ld1Byb3BzLnN0eWxlLCBuYW1lc3BhY2UpOw0KICAgICAgICB9DQogICAgICAgIGlmIChwYXRjaEZsYWcgJiA4KSB7DQogICAgICAgICAgY29uc3QgcHJvcHNUb1VwZGF0ZSA9IG4yLmR5bmFtaWNQcm9wczsNCiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByb3BzVG9VcGRhdGUubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgICAgIGNvbnN0IGtleSA9IHByb3BzVG9VcGRhdGVbaV07DQogICAgICAgICAgICBjb25zdCBwcmV2ID0gb2xkUHJvcHNba2V5XTsNCiAgICAgICAgICAgIGNvbnN0IG5leHQgPSBuZXdQcm9wc1trZXldOw0KICAgICAgICAgICAgaWYgKG5leHQgIT09IHByZXYgfHwga2V5ID09PSAidmFsdWUiKSB7DQogICAgICAgICAgICAgIGhvc3RQYXRjaFByb3AoZWwsIGtleSwgcHJldiwgbmV4dCwgbmFtZXNwYWNlLCBwYXJlbnRDb21wb25lbnQpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgaWYgKHBhdGNoRmxhZyAmIDEpIHsNCiAgICAgICAgaWYgKG4xLmNoaWxkcmVuICE9PSBuMi5jaGlsZHJlbikgew0KICAgICAgICAgIGhvc3RTZXRFbGVtZW50VGV4dChlbCwgbjIuY2hpbGRyZW4pOw0KICAgICAgICB9DQogICAgICB9DQogICAgfSBlbHNlIGlmICghb3B0aW1pemVkICYmIGR5bmFtaWNDaGlsZHJlbiA9PSBudWxsKSB7DQogICAgICBwYXRjaFByb3BzKGVsLCBvbGRQcm9wcywgbmV3UHJvcHMsIHBhcmVudENvbXBvbmVudCwgbmFtZXNwYWNlKTsNCiAgICB9DQogICAgaWYgKCh2bm9kZUhvb2sgPSBuZXdQcm9wcy5vblZub2RlVXBkYXRlZCkgfHwgZGlycykgew0KICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KCgpID0+IHsNCiAgICAgICAgdm5vZGVIb29rICYmIGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIHBhcmVudENvbXBvbmVudCwgbjIsIG4xKTsNCiAgICAgICAgZGlycyAmJiBpbnZva2VEaXJlY3RpdmVIb29rKG4yLCBuMSwgcGFyZW50Q29tcG9uZW50LCAidXBkYXRlZCIpOw0KICAgICAgfSwgcGFyZW50U3VzcGVuc2UpOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgcGF0Y2hCbG9ja0NoaWxkcmVuID0gKG9sZENoaWxkcmVuLCBuZXdDaGlsZHJlbiwgZmFsbGJhY2tDb250YWluZXIsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzKSA9PiB7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuZXdDaGlsZHJlbi5sZW5ndGg7IGkrKykgew0KICAgICAgY29uc3Qgb2xkVk5vZGUgPSBvbGRDaGlsZHJlbltpXTsNCiAgICAgIGNvbnN0IG5ld1ZOb2RlID0gbmV3Q2hpbGRyZW5baV07DQogICAgICBjb25zdCBjb250YWluZXIgPSAoDQogICAgICAgIC8vIG9sZFZOb2RlIG1heSBiZSBhbiBlcnJvcmVkIGFzeW5jIHNldHVwKCkgY29tcG9uZW50IGluc2lkZSBTdXNwZW5zZQ0KICAgICAgICAvLyB3aGljaCB3aWxsIG5vdCBoYXZlIGEgbW91bnRlZCBlbGVtZW50DQogICAgICAgIG9sZFZOb2RlLmVsICYmIC8vIC0gSW4gdGhlIGNhc2Ugb2YgYSBGcmFnbWVudCwgd2UgbmVlZCB0byBwcm92aWRlIHRoZSBhY3R1YWwgcGFyZW50DQogICAgICAgIC8vIG9mIHRoZSBGcmFnbWVudCBpdHNlbGYgc28gaXQgY2FuIG1vdmUgaXRzIGNoaWxkcmVuLg0KICAgICAgICAob2xkVk5vZGUudHlwZSA9PT0gRnJhZ21lbnQgfHwgLy8gLSBJbiB0aGUgY2FzZSBvZiBkaWZmZXJlbnQgbm9kZXMsIHRoZXJlIGlzIGdvaW5nIHRvIGJlIGEgcmVwbGFjZW1lbnQNCiAgICAgICAgLy8gd2hpY2ggYWxzbyByZXF1aXJlcyB0aGUgY29ycmVjdCBwYXJlbnQgY29udGFpbmVyDQogICAgICAgICFpc1NhbWVWTm9kZVR5cGUob2xkVk5vZGUsIG5ld1ZOb2RlKSB8fCAvLyAtIEluIHRoZSBjYXNlIG9mIGEgY29tcG9uZW50LCBpdCBjb3VsZCBjb250YWluIGFueXRoaW5nLg0KICAgICAgICBvbGRWTm9kZS5zaGFwZUZsYWcgJiAoNiB8IDY0IHwgMTI4KSkgPyBob3N0UGFyZW50Tm9kZShvbGRWTm9kZS5lbCkgOiAoDQogICAgICAgICAgLy8gSW4gb3RoZXIgY2FzZXMsIHRoZSBwYXJlbnQgY29udGFpbmVyIGlzIG5vdCBhY3R1YWxseSB1c2VkIHNvIHdlDQogICAgICAgICAgLy8ganVzdCBwYXNzIHRoZSBibG9jayBlbGVtZW50IGhlcmUgdG8gYXZvaWQgYSBET00gcGFyZW50Tm9kZSBjYWxsLg0KICAgICAgICAgIGZhbGxiYWNrQ29udGFpbmVyDQogICAgICAgICkNCiAgICAgICk7DQogICAgICBwYXRjaCgNCiAgICAgICAgb2xkVk5vZGUsDQogICAgICAgIG5ld1ZOb2RlLA0KICAgICAgICBjb250YWluZXIsDQogICAgICAgIG51bGwsDQogICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICB0cnVlDQogICAgICApOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgcGF0Y2hQcm9wcyA9IChlbCwgb2xkUHJvcHMsIG5ld1Byb3BzLCBwYXJlbnRDb21wb25lbnQsIG5hbWVzcGFjZSkgPT4gew0KICAgIGlmIChvbGRQcm9wcyAhPT0gbmV3UHJvcHMpIHsNCiAgICAgIGlmIChvbGRQcm9wcyAhPT0gRU1QVFlfT0JKKSB7DQogICAgICAgIGZvciAoY29uc3Qga2V5IGluIG9sZFByb3BzKSB7DQogICAgICAgICAgaWYgKCFpc1Jlc2VydmVkUHJvcChrZXkpICYmICEoa2V5IGluIG5ld1Byb3BzKSkgew0KICAgICAgICAgICAgaG9zdFBhdGNoUHJvcCgNCiAgICAgICAgICAgICAgZWwsDQogICAgICAgICAgICAgIGtleSwNCiAgICAgICAgICAgICAgb2xkUHJvcHNba2V5XSwNCiAgICAgICAgICAgICAgbnVsbCwNCiAgICAgICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgICAgICBwYXJlbnRDb21wb25lbnQNCiAgICAgICAgICAgICk7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICB9DQogICAgICBmb3IgKGNvbnN0IGtleSBpbiBuZXdQcm9wcykgew0KICAgICAgICBpZiAoaXNSZXNlcnZlZFByb3Aoa2V5KSkgY29udGludWU7DQogICAgICAgIGNvbnN0IG5leHQgPSBuZXdQcm9wc1trZXldOw0KICAgICAgICBjb25zdCBwcmV2ID0gb2xkUHJvcHNba2V5XTsNCiAgICAgICAgaWYgKG5leHQgIT09IHByZXYgJiYga2V5ICE9PSAidmFsdWUiKSB7DQogICAgICAgICAgaG9zdFBhdGNoUHJvcChlbCwga2V5LCBwcmV2LCBuZXh0LCBuYW1lc3BhY2UsIHBhcmVudENvbXBvbmVudCk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGlmICgidmFsdWUiIGluIG5ld1Byb3BzKSB7DQogICAgICAgIGhvc3RQYXRjaFByb3AoZWwsICJ2YWx1ZSIsIG9sZFByb3BzLnZhbHVlLCBuZXdQcm9wcy52YWx1ZSwgbmFtZXNwYWNlKTsNCiAgICAgIH0NCiAgICB9DQogIH07DQogIGNvbnN0IHByb2Nlc3NGcmFnbWVudCA9IChuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBuYW1lc3BhY2UsIHNsb3RTY29wZUlkcywgb3B0aW1pemVkKSA9PiB7DQogICAgY29uc3QgZnJhZ21lbnRTdGFydEFuY2hvciA9IG4yLmVsID0gbjEgPyBuMS5lbCA6IGhvc3RDcmVhdGVUZXh0KCIiKTsNCiAgICBjb25zdCBmcmFnbWVudEVuZEFuY2hvciA9IG4yLmFuY2hvciA9IG4xID8gbjEuYW5jaG9yIDogaG9zdENyZWF0ZVRleHQoIiIpOw0KICAgIGxldCB7IHBhdGNoRmxhZywgZHluYW1pY0NoaWxkcmVuLCBzbG90U2NvcGVJZHM6IGZyYWdtZW50U2xvdFNjb3BlSWRzIH0gPSBuMjsNCiAgICBpZiAoDQogICAgICAvLyAjNTUyMyBkZXYgcm9vdCBmcmFnbWVudCBtYXkgaW5oZXJpdCBkaXJlY3RpdmVzDQogICAgICBpc0htclVwZGF0aW5nIHx8IHBhdGNoRmxhZyAmIDIwNDgNCiAgICApIHsNCiAgICAgIHBhdGNoRmxhZyA9IDA7DQogICAgICBvcHRpbWl6ZWQgPSBmYWxzZTsNCiAgICAgIGR5bmFtaWNDaGlsZHJlbiA9IG51bGw7DQogICAgfQ0KICAgIGlmIChmcmFnbWVudFNsb3RTY29wZUlkcykgew0KICAgICAgc2xvdFNjb3BlSWRzID0gc2xvdFNjb3BlSWRzID8gc2xvdFNjb3BlSWRzLmNvbmNhdChmcmFnbWVudFNsb3RTY29wZUlkcykgOiBmcmFnbWVudFNsb3RTY29wZUlkczsNCiAgICB9DQogICAgaWYgKG4xID09IG51bGwpIHsNCiAgICAgIGhvc3RJbnNlcnQoZnJhZ21lbnRTdGFydEFuY2hvciwgY29udGFpbmVyLCBhbmNob3IpOw0KICAgICAgaG9zdEluc2VydChmcmFnbWVudEVuZEFuY2hvciwgY29udGFpbmVyLCBhbmNob3IpOw0KICAgICAgbW91bnRDaGlsZHJlbigNCiAgICAgICAgLy8gIzEwMDA3DQogICAgICAgIC8vIHN1Y2ggZnJhZ21lbnQgbGlrZSBgPD48Lz5gIHdpbGwgYmUgY29tcGlsZWQgaW50bw0KICAgICAgICAvLyBhIGZyYWdtZW50IHdoaWNoIGRvZXNuJ3QgaGF2ZSBhIGNoaWxkcmVuLg0KICAgICAgICAvLyBJbiB0aGlzIGNhc2UgZmFsbGJhY2sgdG8gYW4gZW1wdHkgYXJyYXkNCiAgICAgICAgbjIuY2hpbGRyZW4gfHwgW10sDQogICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgZnJhZ21lbnRFbmRBbmNob3IsDQogICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICk7DQogICAgfSBlbHNlIHsNCiAgICAgIGlmIChwYXRjaEZsYWcgPiAwICYmIHBhdGNoRmxhZyAmIDY0ICYmIGR5bmFtaWNDaGlsZHJlbiAmJiAvLyAjMjcxNSB0aGUgcHJldmlvdXMgZnJhZ21lbnQgY291bGQndmUgYmVlbiBhIEJBSUxlZCBvbmUgYXMgYSByZXN1bHQNCiAgICAgIC8vIG9mIHJlbmRlclNsb3QoKSB3aXRoIG5vIHZhbGlkIGNoaWxkcmVuDQogICAgICBuMS5keW5hbWljQ2hpbGRyZW4pIHsNCiAgICAgICAgcGF0Y2hCbG9ja0NoaWxkcmVuKA0KICAgICAgICAgIG4xLmR5bmFtaWNDaGlsZHJlbiwNCiAgICAgICAgICBkeW5hbWljQ2hpbGRyZW4sDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzDQogICAgICAgICk7DQogICAgICAgIHsNCiAgICAgICAgICB0cmF2ZXJzZVN0YXRpY0NoaWxkcmVuKG4xLCBuMik7DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHBhdGNoQ2hpbGRyZW4oDQogICAgICAgICAgbjEsDQogICAgICAgICAgbjIsDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIGZyYWdtZW50RW5kQW5jaG9yLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICApOw0KICAgICAgfQ0KICAgIH0NCiAgfTsNCiAgY29uc3QgcHJvY2Vzc0NvbXBvbmVudCA9IChuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBuYW1lc3BhY2UsIHNsb3RTY29wZUlkcywgb3B0aW1pemVkKSA9PiB7DQogICAgbjIuc2xvdFNjb3BlSWRzID0gc2xvdFNjb3BlSWRzOw0KICAgIGlmIChuMSA9PSBudWxsKSB7DQogICAgICBpZiAobjIuc2hhcGVGbGFnICYgNTEyKSB7DQogICAgICAgIHBhcmVudENvbXBvbmVudC5jdHguYWN0aXZhdGUoDQogICAgICAgICAgbjIsDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIGFuY2hvciwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBtb3VudENvbXBvbmVudCgNCiAgICAgICAgICBuMiwNCiAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICk7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIHVwZGF0ZUNvbXBvbmVudChuMSwgbjIsIG9wdGltaXplZCk7DQogICAgfQ0KICB9Ow0KICBjb25zdCBtb3VudENvbXBvbmVudCA9IChpbml0aWFsVk5vZGUsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBuYW1lc3BhY2UsIG9wdGltaXplZCkgPT4gew0KICAgIGNvbnN0IGluc3RhbmNlID0gKGluaXRpYWxWTm9kZS5jb21wb25lbnQgPSBjcmVhdGVDb21wb25lbnRJbnN0YW5jZSQxKA0KICAgICAgaW5pdGlhbFZOb2RlLA0KICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgcGFyZW50U3VzcGVuc2UNCiAgICApKTsNCiAgICBpZiAoaW5zdGFuY2UudHlwZS5fX2htcklkKSB7DQogICAgICByZWdpc3RlckhNUihpbnN0YW5jZSk7DQogICAgfQ0KICAgIHsNCiAgICAgIHB1c2hXYXJuaW5nQ29udGV4dCQxKGluaXRpYWxWTm9kZSk7DQogICAgICBzdGFydE1lYXN1cmUoaW5zdGFuY2UsIGBtb3VudGApOw0KICAgIH0NCiAgICBpZiAoaXNLZWVwQWxpdmUoaW5pdGlhbFZOb2RlKSkgew0KICAgICAgaW5zdGFuY2UuY3R4LnJlbmRlcmVyID0gaW50ZXJuYWxzOw0KICAgIH0NCiAgICB7DQogICAgICB7DQogICAgICAgIHN0YXJ0TWVhc3VyZShpbnN0YW5jZSwgYGluaXRgKTsNCiAgICAgIH0NCiAgICAgIHNldHVwQ29tcG9uZW50JDEoaW5zdGFuY2UsIGZhbHNlLCBvcHRpbWl6ZWQpOw0KICAgICAgew0KICAgICAgICBlbmRNZWFzdXJlKGluc3RhbmNlLCBgaW5pdGApOw0KICAgICAgfQ0KICAgIH0NCiAgICBpZiAoaXNIbXJVcGRhdGluZykgaW5pdGlhbFZOb2RlLmVsID0gbnVsbDsNCiAgICBpZiAoaW5zdGFuY2UuYXN5bmNEZXApIHsNCiAgICAgIHBhcmVudFN1c3BlbnNlICYmIHBhcmVudFN1c3BlbnNlLnJlZ2lzdGVyRGVwKGluc3RhbmNlLCBzZXR1cFJlbmRlckVmZmVjdCwgb3B0aW1pemVkKTsNCiAgICAgIGlmICghaW5pdGlhbFZOb2RlLmVsKSB7DQogICAgICAgIGNvbnN0IHBsYWNlaG9sZGVyID0gaW5zdGFuY2Uuc3ViVHJlZSA9IGNyZWF0ZVZOb2RlKENvbW1lbnQpOw0KICAgICAgICBwcm9jZXNzQ29tbWVudE5vZGUobnVsbCwgcGxhY2Vob2xkZXIsIGNvbnRhaW5lciwgYW5jaG9yKTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgc2V0dXBSZW5kZXJFZmZlY3QoDQogICAgICAgIGluc3RhbmNlLA0KICAgICAgICBpbml0aWFsVk5vZGUsDQogICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgYW5jaG9yLA0KICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICk7DQogICAgfQ0KICAgIHsNCiAgICAgIHBvcFdhcm5pbmdDb250ZXh0JDEoKTsNCiAgICAgIGVuZE1lYXN1cmUoaW5zdGFuY2UsIGBtb3VudGApOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgdXBkYXRlQ29tcG9uZW50ID0gKG4xLCBuMiwgb3B0aW1pemVkKSA9PiB7DQogICAgY29uc3QgaW5zdGFuY2UgPSBuMi5jb21wb25lbnQgPSBuMS5jb21wb25lbnQ7DQogICAgaWYgKHNob3VsZFVwZGF0ZUNvbXBvbmVudChuMSwgbjIsIG9wdGltaXplZCkpIHsNCiAgICAgIGlmIChpbnN0YW5jZS5hc3luY0RlcCAmJiAhaW5zdGFuY2UuYXN5bmNSZXNvbHZlZCkgew0KICAgICAgICB7DQogICAgICAgICAgcHVzaFdhcm5pbmdDb250ZXh0JDEobjIpOw0KICAgICAgICB9DQogICAgICAgIHVwZGF0ZUNvbXBvbmVudFByZVJlbmRlcihpbnN0YW5jZSwgbjIsIG9wdGltaXplZCk7DQogICAgICAgIHsNCiAgICAgICAgICBwb3BXYXJuaW5nQ29udGV4dCQxKCk7DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgaW5zdGFuY2UubmV4dCA9IG4yOw0KICAgICAgICBpbnN0YW5jZS51cGRhdGUoKTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgbjIuZWwgPSBuMS5lbDsNCiAgICAgIGluc3RhbmNlLnZub2RlID0gbjI7DQogICAgfQ0KICB9Ow0KICBjb25zdCBzZXR1cFJlbmRlckVmZmVjdCA9IChpbnN0YW5jZSwgaW5pdGlhbFZOb2RlLCBjb250YWluZXIsIGFuY2hvciwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgb3B0aW1pemVkKSA9PiB7DQogICAgY29uc3QgY29tcG9uZW50VXBkYXRlRm4gPSAoKSA9PiB7DQogICAgICBpZiAoIWluc3RhbmNlLmlzTW91bnRlZCkgew0KICAgICAgICBsZXQgdm5vZGVIb29rOw0KICAgICAgICBjb25zdCB7IGVsLCBwcm9wcyB9ID0gaW5pdGlhbFZOb2RlOw0KICAgICAgICBjb25zdCB7IGJtLCBtLCBwYXJlbnQsIHJvb3QsIHR5cGUgfSA9IGluc3RhbmNlOw0KICAgICAgICBjb25zdCBpc0FzeW5jV3JhcHBlclZOb2RlID0gaXNBc3luY1dyYXBwZXIoaW5pdGlhbFZOb2RlKTsNCiAgICAgICAgdG9nZ2xlUmVjdXJzZShpbnN0YW5jZSwgZmFsc2UpOw0KICAgICAgICBpZiAoYm0pIHsNCiAgICAgICAgICBpbnZva2VBcnJheUZucyhibSk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKCFpc0FzeW5jV3JhcHBlclZOb2RlICYmICh2bm9kZUhvb2sgPSBwcm9wcyAmJiBwcm9wcy5vblZub2RlQmVmb3JlTW91bnQpKSB7DQogICAgICAgICAgaW52b2tlVk5vZGVIb29rKHZub2RlSG9vaywgcGFyZW50LCBpbml0aWFsVk5vZGUpOw0KICAgICAgICB9DQogICAgICAgIHRvZ2dsZVJlY3Vyc2UoaW5zdGFuY2UsIHRydWUpOw0KICAgICAgICB7DQogICAgICAgICAgaWYgKHJvb3QuY2UgJiYgLy8gQHRzLWV4cGVjdC1lcnJvciBfZGVmIGlzIHByaXZhdGUNCiAgICAgICAgICByb290LmNlLl9kZWYuc2hhZG93Um9vdCAhPT0gZmFsc2UpIHsNCiAgICAgICAgICAgIHJvb3QuY2UuX2luamVjdENoaWxkU3R5bGUodHlwZSk7DQogICAgICAgICAgfQ0KICAgICAgICAgIHsNCiAgICAgICAgICAgIHN0YXJ0TWVhc3VyZShpbnN0YW5jZSwgYHJlbmRlcmApOw0KICAgICAgICAgIH0NCiAgICAgICAgICBjb25zdCBzdWJUcmVlID0gaW5zdGFuY2Uuc3ViVHJlZSA9IHJlbmRlckNvbXBvbmVudFJvb3QkMShpbnN0YW5jZSk7DQogICAgICAgICAgew0KICAgICAgICAgICAgZW5kTWVhc3VyZShpbnN0YW5jZSwgYHJlbmRlcmApOw0KICAgICAgICAgIH0NCiAgICAgICAgICB7DQogICAgICAgICAgICBzdGFydE1lYXN1cmUoaW5zdGFuY2UsIGBwYXRjaGApOw0KICAgICAgICAgIH0NCiAgICAgICAgICBwYXRjaCgNCiAgICAgICAgICAgIG51bGwsDQogICAgICAgICAgICBzdWJUcmVlLA0KICAgICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgICAgaW5zdGFuY2UsDQogICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgIG5hbWVzcGFjZQ0KICAgICAgICAgICk7DQogICAgICAgICAgew0KICAgICAgICAgICAgZW5kTWVhc3VyZShpbnN0YW5jZSwgYHBhdGNoYCk7DQogICAgICAgICAgfQ0KICAgICAgICAgIGluaXRpYWxWTm9kZS5lbCA9IHN1YlRyZWUuZWw7DQogICAgICAgIH0NCiAgICAgICAgaWYgKG0pIHsNCiAgICAgICAgICBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QobSwgcGFyZW50U3VzcGVuc2UpOw0KICAgICAgICB9DQogICAgICAgIGlmICghaXNBc3luY1dyYXBwZXJWTm9kZSAmJiAodm5vZGVIb29rID0gcHJvcHMgJiYgcHJvcHMub25Wbm9kZU1vdW50ZWQpKSB7DQogICAgICAgICAgY29uc3Qgc2NvcGVkSW5pdGlhbFZOb2RlID0gaW5pdGlhbFZOb2RlOw0KICAgICAgICAgIHF1ZXVlUG9zdFJlbmRlckVmZmVjdCgNCiAgICAgICAgICAgICgpID0+IGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIHBhcmVudCwgc2NvcGVkSW5pdGlhbFZOb2RlKSwNCiAgICAgICAgICAgIHBhcmVudFN1c3BlbnNlDQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgICBpZiAoaW5pdGlhbFZOb2RlLnNoYXBlRmxhZyAmIDI1NiB8fCBwYXJlbnQgJiYgaXNBc3luY1dyYXBwZXIocGFyZW50LnZub2RlKSAmJiBwYXJlbnQudm5vZGUuc2hhcGVGbGFnICYgMjU2KSB7DQogICAgICAgICAgaW5zdGFuY2UuYSAmJiBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QoaW5zdGFuY2UuYSwgcGFyZW50U3VzcGVuc2UpOw0KICAgICAgICB9DQogICAgICAgIGluc3RhbmNlLmlzTW91bnRlZCA9IHRydWU7DQogICAgICAgIHsNCiAgICAgICAgICBkZXZ0b29sc0NvbXBvbmVudEFkZGVkKGluc3RhbmNlKTsNCiAgICAgICAgfQ0KICAgICAgICBpbml0aWFsVk5vZGUgPSBjb250YWluZXIgPSBhbmNob3IgPSBudWxsOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgbGV0IHsgbmV4dCwgYnUsIHUsIHBhcmVudCwgdm5vZGUgfSA9IGluc3RhbmNlOw0KICAgICAgICB7DQogICAgICAgICAgY29uc3Qgbm9uSHlkcmF0ZWRBc3luY1Jvb3QgPSBsb2NhdGVOb25IeWRyYXRlZEFzeW5jUm9vdChpbnN0YW5jZSk7DQogICAgICAgICAgaWYgKG5vbkh5ZHJhdGVkQXN5bmNSb290KSB7DQogICAgICAgICAgICBpZiAobmV4dCkgew0KICAgICAgICAgICAgICBuZXh0LmVsID0gdm5vZGUuZWw7DQogICAgICAgICAgICAgIHVwZGF0ZUNvbXBvbmVudFByZVJlbmRlcihpbnN0YW5jZSwgbmV4dCwgb3B0aW1pemVkKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIG5vbkh5ZHJhdGVkQXN5bmNSb290LmFzeW5jRGVwLnRoZW4oKCkgPT4gew0KICAgICAgICAgICAgICBpZiAoIWluc3RhbmNlLmlzVW5tb3VudGVkKSB7DQogICAgICAgICAgICAgICAgY29tcG9uZW50VXBkYXRlRm4oKTsNCiAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSk7DQogICAgICAgICAgICByZXR1cm47DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGxldCBvcmlnaW5OZXh0ID0gbmV4dDsNCiAgICAgICAgbGV0IHZub2RlSG9vazsNCiAgICAgICAgew0KICAgICAgICAgIHB1c2hXYXJuaW5nQ29udGV4dCQxKG5leHQgfHwgaW5zdGFuY2Uudm5vZGUpOw0KICAgICAgICB9DQogICAgICAgIHRvZ2dsZVJlY3Vyc2UoaW5zdGFuY2UsIGZhbHNlKTsNCiAgICAgICAgaWYgKG5leHQpIHsNCiAgICAgICAgICBuZXh0LmVsID0gdm5vZGUuZWw7DQogICAgICAgICAgdXBkYXRlQ29tcG9uZW50UHJlUmVuZGVyKGluc3RhbmNlLCBuZXh0LCBvcHRpbWl6ZWQpOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIG5leHQgPSB2bm9kZTsNCiAgICAgICAgfQ0KICAgICAgICBpZiAoYnUpIHsNCiAgICAgICAgICBpbnZva2VBcnJheUZucyhidSk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKHZub2RlSG9vayA9IG5leHQucHJvcHMgJiYgbmV4dC5wcm9wcy5vblZub2RlQmVmb3JlVXBkYXRlKSB7DQogICAgICAgICAgaW52b2tlVk5vZGVIb29rKHZub2RlSG9vaywgcGFyZW50LCBuZXh0LCB2bm9kZSk7DQogICAgICAgIH0NCiAgICAgICAgdG9nZ2xlUmVjdXJzZShpbnN0YW5jZSwgdHJ1ZSk7DQogICAgICAgIHsNCiAgICAgICAgICBzdGFydE1lYXN1cmUoaW5zdGFuY2UsIGByZW5kZXJgKTsNCiAgICAgICAgfQ0KICAgICAgICBjb25zdCBuZXh0VHJlZSA9IHJlbmRlckNvbXBvbmVudFJvb3QkMShpbnN0YW5jZSk7DQogICAgICAgIHsNCiAgICAgICAgICBlbmRNZWFzdXJlKGluc3RhbmNlLCBgcmVuZGVyYCk7DQogICAgICAgIH0NCiAgICAgICAgY29uc3QgcHJldlRyZWUgPSBpbnN0YW5jZS5zdWJUcmVlOw0KICAgICAgICBpbnN0YW5jZS5zdWJUcmVlID0gbmV4dFRyZWU7DQogICAgICAgIHsNCiAgICAgICAgICBzdGFydE1lYXN1cmUoaW5zdGFuY2UsIGBwYXRjaGApOw0KICAgICAgICB9DQogICAgICAgIHBhdGNoKA0KICAgICAgICAgIHByZXZUcmVlLA0KICAgICAgICAgIG5leHRUcmVlLA0KICAgICAgICAgIC8vIHBhcmVudCBtYXkgaGF2ZSBjaGFuZ2VkIGlmIGl0J3MgaW4gYSB0ZWxlcG9ydA0KICAgICAgICAgIGhvc3RQYXJlbnROb2RlKHByZXZUcmVlLmVsKSwNCiAgICAgICAgICAvLyBhbmNob3IgbWF5IGhhdmUgY2hhbmdlZCBpZiBpdCdzIGluIGEgZnJhZ21lbnQNCiAgICAgICAgICBnZXROZXh0SG9zdE5vZGUocHJldlRyZWUpLA0KICAgICAgICAgIGluc3RhbmNlLA0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgIG5hbWVzcGFjZQ0KICAgICAgICApOw0KICAgICAgICB7DQogICAgICAgICAgZW5kTWVhc3VyZShpbnN0YW5jZSwgYHBhdGNoYCk7DQogICAgICAgIH0NCiAgICAgICAgbmV4dC5lbCA9IG5leHRUcmVlLmVsOw0KICAgICAgICBpZiAob3JpZ2luTmV4dCA9PT0gbnVsbCkgew0KICAgICAgICAgIHVwZGF0ZUhPQ0hvc3RFbChpbnN0YW5jZSwgbmV4dFRyZWUuZWwpOw0KICAgICAgICB9DQogICAgICAgIGlmICh1KSB7DQogICAgICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KHUsIHBhcmVudFN1c3BlbnNlKTsNCiAgICAgICAgfQ0KICAgICAgICBpZiAodm5vZGVIb29rID0gbmV4dC5wcm9wcyAmJiBuZXh0LnByb3BzLm9uVm5vZGVVcGRhdGVkKSB7DQogICAgICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KA0KICAgICAgICAgICAgKCkgPT4gaW52b2tlVk5vZGVIb29rKHZub2RlSG9vaywgcGFyZW50LCBuZXh0LCB2bm9kZSksDQogICAgICAgICAgICBwYXJlbnRTdXNwZW5zZQ0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgICAgew0KICAgICAgICAgIGRldnRvb2xzQ29tcG9uZW50VXBkYXRlZChpbnN0YW5jZSk7DQogICAgICAgIH0NCiAgICAgICAgew0KICAgICAgICAgIHBvcFdhcm5pbmdDb250ZXh0JDEoKTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH07DQogICAgaW5zdGFuY2Uuc2NvcGUub24oKTsNCiAgICBjb25zdCBlZmZlY3QgPSBpbnN0YW5jZS5lZmZlY3QgPSBuZXcgUmVhY3RpdmVFZmZlY3QoY29tcG9uZW50VXBkYXRlRm4pOw0KICAgIGluc3RhbmNlLnNjb3BlLm9mZigpOw0KICAgIGNvbnN0IHVwZGF0ZSA9IGluc3RhbmNlLnVwZGF0ZSA9IGVmZmVjdC5ydW4uYmluZChlZmZlY3QpOw0KICAgIGNvbnN0IGpvYiA9IGluc3RhbmNlLmpvYiA9IGVmZmVjdC5ydW5JZkRpcnR5LmJpbmQoZWZmZWN0KTsNCiAgICBqb2IuaSA9IGluc3RhbmNlOw0KICAgIGpvYi5pZCA9IGluc3RhbmNlLnVpZDsNCiAgICBlZmZlY3Quc2NoZWR1bGVyID0gKCkgPT4gcXVldWVKb2Ioam9iKTsNCiAgICB0b2dnbGVSZWN1cnNlKGluc3RhbmNlLCB0cnVlKTsNCiAgICB7DQogICAgICBlZmZlY3Qub25UcmFjayA9IGluc3RhbmNlLnJ0YyA/IChlKSA9PiBpbnZva2VBcnJheUZucyhpbnN0YW5jZS5ydGMsIGUpIDogdm9pZCAwOw0KICAgICAgZWZmZWN0Lm9uVHJpZ2dlciA9IGluc3RhbmNlLnJ0ZyA/IChlKSA9PiBpbnZva2VBcnJheUZucyhpbnN0YW5jZS5ydGcsIGUpIDogdm9pZCAwOw0KICAgIH0NCiAgICB1cGRhdGUoKTsNCiAgfTsNCiAgY29uc3QgdXBkYXRlQ29tcG9uZW50UHJlUmVuZGVyID0gKGluc3RhbmNlLCBuZXh0Vk5vZGUsIG9wdGltaXplZCkgPT4gew0KICAgIG5leHRWTm9kZS5jb21wb25lbnQgPSBpbnN0YW5jZTsNCiAgICBjb25zdCBwcmV2UHJvcHMgPSBpbnN0YW5jZS52bm9kZS5wcm9wczsNCiAgICBpbnN0YW5jZS52bm9kZSA9IG5leHRWTm9kZTsNCiAgICBpbnN0YW5jZS5uZXh0ID0gbnVsbDsNCiAgICB1cGRhdGVQcm9wcyhpbnN0YW5jZSwgbmV4dFZOb2RlLnByb3BzLCBwcmV2UHJvcHMsIG9wdGltaXplZCk7DQogICAgdXBkYXRlU2xvdHMoaW5zdGFuY2UsIG5leHRWTm9kZS5jaGlsZHJlbiwgb3B0aW1pemVkKTsNCiAgICBwYXVzZVRyYWNraW5nKCk7DQogICAgZmx1c2hQcmVGbHVzaENicyhpbnN0YW5jZSk7DQogICAgcmVzZXRUcmFja2luZygpOw0KICB9Ow0KICBjb25zdCBwYXRjaENoaWxkcmVuID0gKG4xLCBuMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQgPSBmYWxzZSkgPT4gew0KICAgIGNvbnN0IGMxID0gbjEgJiYgbjEuY2hpbGRyZW47DQogICAgY29uc3QgcHJldlNoYXBlRmxhZyA9IG4xID8gbjEuc2hhcGVGbGFnIDogMDsNCiAgICBjb25zdCBjMiA9IG4yLmNoaWxkcmVuOw0KICAgIGNvbnN0IHsgcGF0Y2hGbGFnLCBzaGFwZUZsYWcgfSA9IG4yOw0KICAgIGlmIChwYXRjaEZsYWcgPiAwKSB7DQogICAgICBpZiAocGF0Y2hGbGFnICYgMTI4KSB7DQogICAgICAgIHBhdGNoS2V5ZWRDaGlsZHJlbigNCiAgICAgICAgICBjMSwNCiAgICAgICAgICBjMiwNCiAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICApOw0KICAgICAgICByZXR1cm47DQogICAgICB9IGVsc2UgaWYgKHBhdGNoRmxhZyAmIDI1Nikgew0KICAgICAgICBwYXRjaFVua2V5ZWRDaGlsZHJlbigNCiAgICAgICAgICBjMSwNCiAgICAgICAgICBjMiwNCiAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICApOw0KICAgICAgICByZXR1cm47DQogICAgICB9DQogICAgfQ0KICAgIGlmIChzaGFwZUZsYWcgJiA4KSB7DQogICAgICBpZiAocHJldlNoYXBlRmxhZyAmIDE2KSB7DQogICAgICAgIHVubW91bnRDaGlsZHJlbihjMSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSk7DQogICAgICB9DQogICAgICBpZiAoYzIgIT09IGMxKSB7DQogICAgICAgIGhvc3RTZXRFbGVtZW50VGV4dChjb250YWluZXIsIGMyKTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgaWYgKHByZXZTaGFwZUZsYWcgJiAxNikgew0KICAgICAgICBpZiAoc2hhcGVGbGFnICYgMTYpIHsNCiAgICAgICAgICBwYXRjaEtleWVkQ2hpbGRyZW4oDQogICAgICAgICAgICBjMSwNCiAgICAgICAgICAgIGMyLA0KICAgICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgICApOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIHVubW91bnRDaGlsZHJlbihjMSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgdHJ1ZSk7DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGlmIChwcmV2U2hhcGVGbGFnICYgOCkgew0KICAgICAgICAgIGhvc3RTZXRFbGVtZW50VGV4dChjb250YWluZXIsICIiKTsNCiAgICAgICAgfQ0KICAgICAgICBpZiAoc2hhcGVGbGFnICYgMTYpIHsNCiAgICAgICAgICBtb3VudENoaWxkcmVuKA0KICAgICAgICAgICAgYzIsDQogICAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgICBhbmNob3IsDQogICAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH07DQogIGNvbnN0IHBhdGNoVW5rZXllZENoaWxkcmVuID0gKGMxLCBjMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQpID0+IHsNCiAgICBjMSA9IGMxIHx8IEVNUFRZX0FSUjsNCiAgICBjMiA9IGMyIHx8IEVNUFRZX0FSUjsNCiAgICBjb25zdCBvbGRMZW5ndGggPSBjMS5sZW5ndGg7DQogICAgY29uc3QgbmV3TGVuZ3RoID0gYzIubGVuZ3RoOw0KICAgIGNvbnN0IGNvbW1vbkxlbmd0aCA9IE1hdGgubWluKG9sZExlbmd0aCwgbmV3TGVuZ3RoKTsNCiAgICBsZXQgaTsNCiAgICBmb3IgKGkgPSAwOyBpIDwgY29tbW9uTGVuZ3RoOyBpKyspIHsNCiAgICAgIGNvbnN0IG5leHRDaGlsZCA9IGMyW2ldID0gb3B0aW1pemVkID8gY2xvbmVJZk1vdW50ZWQoYzJbaV0pIDogbm9ybWFsaXplVk5vZGUkMShjMltpXSk7DQogICAgICBwYXRjaCgNCiAgICAgICAgYzFbaV0sDQogICAgICAgIG5leHRDaGlsZCwNCiAgICAgICAgY29udGFpbmVyLA0KICAgICAgICBudWxsLA0KICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgb3B0aW1pemVkDQogICAgICApOw0KICAgIH0NCiAgICBpZiAob2xkTGVuZ3RoID4gbmV3TGVuZ3RoKSB7DQogICAgICB1bm1vdW50Q2hpbGRyZW4oDQogICAgICAgIGMxLA0KICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICB0cnVlLA0KICAgICAgICBmYWxzZSwNCiAgICAgICAgY29tbW9uTGVuZ3RoDQogICAgICApOw0KICAgIH0gZWxzZSB7DQogICAgICBtb3VudENoaWxkcmVuKA0KICAgICAgICBjMiwNCiAgICAgICAgY29udGFpbmVyLA0KICAgICAgICBhbmNob3IsDQogICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICBvcHRpbWl6ZWQsDQogICAgICAgIGNvbW1vbkxlbmd0aA0KICAgICAgKTsNCiAgICB9DQogIH07DQogIGNvbnN0IHBhdGNoS2V5ZWRDaGlsZHJlbiA9IChjMSwgYzIsIGNvbnRhaW5lciwgcGFyZW50QW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBuYW1lc3BhY2UsIHNsb3RTY29wZUlkcywgb3B0aW1pemVkKSA9PiB7DQogICAgbGV0IGkgPSAwOw0KICAgIGNvbnN0IGwyID0gYzIubGVuZ3RoOw0KICAgIGxldCBlMSA9IGMxLmxlbmd0aCAtIDE7DQogICAgbGV0IGUyID0gbDIgLSAxOw0KICAgIHdoaWxlIChpIDw9IGUxICYmIGkgPD0gZTIpIHsNCiAgICAgIGNvbnN0IG4xID0gYzFbaV07DQogICAgICBjb25zdCBuMiA9IGMyW2ldID0gb3B0aW1pemVkID8gY2xvbmVJZk1vdW50ZWQoYzJbaV0pIDogbm9ybWFsaXplVk5vZGUkMShjMltpXSk7DQogICAgICBpZiAoaXNTYW1lVk5vZGVUeXBlKG4xLCBuMikpIHsNCiAgICAgICAgcGF0Y2goDQogICAgICAgICAgbjEsDQogICAgICAgICAgbjIsDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIG51bGwsDQogICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBicmVhazsNCiAgICAgIH0NCiAgICAgIGkrKzsNCiAgICB9DQogICAgd2hpbGUgKGkgPD0gZTEgJiYgaSA8PSBlMikgew0KICAgICAgY29uc3QgbjEgPSBjMVtlMV07DQogICAgICBjb25zdCBuMiA9IGMyW2UyXSA9IG9wdGltaXplZCA/IGNsb25lSWZNb3VudGVkKGMyW2UyXSkgOiBub3JtYWxpemVWTm9kZSQxKGMyW2UyXSk7DQogICAgICBpZiAoaXNTYW1lVk5vZGVUeXBlKG4xLCBuMikpIHsNCiAgICAgICAgcGF0Y2goDQogICAgICAgICAgbjEsDQogICAgICAgICAgbjIsDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIG51bGwsDQogICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBicmVhazsNCiAgICAgIH0NCiAgICAgIGUxLS07DQogICAgICBlMi0tOw0KICAgIH0NCiAgICBpZiAoaSA+IGUxKSB7DQogICAgICBpZiAoaSA8PSBlMikgew0KICAgICAgICBjb25zdCBuZXh0UG9zID0gZTIgKyAxOw0KICAgICAgICBjb25zdCBhbmNob3IgPSBuZXh0UG9zIDwgbDIgPyBjMltuZXh0UG9zXS5lbCA6IHBhcmVudEFuY2hvcjsNCiAgICAgICAgd2hpbGUgKGkgPD0gZTIpIHsNCiAgICAgICAgICBwYXRjaCgNCiAgICAgICAgICAgIG51bGwsDQogICAgICAgICAgICBjMltpXSA9IG9wdGltaXplZCA/IGNsb25lSWZNb3VudGVkKGMyW2ldKSA6IG5vcm1hbGl6ZVZOb2RlJDEoYzJbaV0pLA0KICAgICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgICApOw0KICAgICAgICAgIGkrKzsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0gZWxzZSBpZiAoaSA+IGUyKSB7DQogICAgICB3aGlsZSAoaSA8PSBlMSkgew0KICAgICAgICB1bm1vdW50KGMxW2ldLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCB0cnVlKTsNCiAgICAgICAgaSsrOw0KICAgICAgfQ0KICAgIH0gZWxzZSB7DQogICAgICBjb25zdCBzMSA9IGk7DQogICAgICBjb25zdCBzMiA9IGk7DQogICAgICBjb25zdCBrZXlUb05ld0luZGV4TWFwID0gLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTsNCiAgICAgIGZvciAoaSA9IHMyOyBpIDw9IGUyOyBpKyspIHsNCiAgICAgICAgY29uc3QgbmV4dENoaWxkID0gYzJbaV0gPSBvcHRpbWl6ZWQgPyBjbG9uZUlmTW91bnRlZChjMltpXSkgOiBub3JtYWxpemVWTm9kZSQxKGMyW2ldKTsNCiAgICAgICAgaWYgKG5leHRDaGlsZC5rZXkgIT0gbnVsbCkgew0KICAgICAgICAgIGlmIChrZXlUb05ld0luZGV4TWFwLmhhcyhuZXh0Q2hpbGQua2V5KSkgew0KICAgICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgICBgRHVwbGljYXRlIGtleXMgZm91bmQgZHVyaW5nIHVwZGF0ZTpgLA0KICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShuZXh0Q2hpbGQua2V5KSwNCiAgICAgICAgICAgICAgYE1ha2Ugc3VyZSBrZXlzIGFyZSB1bmlxdWUuYA0KICAgICAgICAgICAgKTsNCiAgICAgICAgICB9DQogICAgICAgICAga2V5VG9OZXdJbmRleE1hcC5zZXQobmV4dENoaWxkLmtleSwgaSk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGxldCBqOw0KICAgICAgbGV0IHBhdGNoZWQgPSAwOw0KICAgICAgY29uc3QgdG9CZVBhdGNoZWQgPSBlMiAtIHMyICsgMTsNCiAgICAgIGxldCBtb3ZlZCA9IGZhbHNlOw0KICAgICAgbGV0IG1heE5ld0luZGV4U29GYXIgPSAwOw0KICAgICAgY29uc3QgbmV3SW5kZXhUb09sZEluZGV4TWFwID0gbmV3IEFycmF5KHRvQmVQYXRjaGVkKTsNCiAgICAgIGZvciAoaSA9IDA7IGkgPCB0b0JlUGF0Y2hlZDsgaSsrKSBuZXdJbmRleFRvT2xkSW5kZXhNYXBbaV0gPSAwOw0KICAgICAgZm9yIChpID0gczE7IGkgPD0gZTE7IGkrKykgew0KICAgICAgICBjb25zdCBwcmV2Q2hpbGQgPSBjMVtpXTsNCiAgICAgICAgaWYgKHBhdGNoZWQgPj0gdG9CZVBhdGNoZWQpIHsNCiAgICAgICAgICB1bm1vdW50KHByZXZDaGlsZCwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgdHJ1ZSk7DQogICAgICAgICAgY29udGludWU7DQogICAgICAgIH0NCiAgICAgICAgbGV0IG5ld0luZGV4Ow0KICAgICAgICBpZiAocHJldkNoaWxkLmtleSAhPSBudWxsKSB7DQogICAgICAgICAgbmV3SW5kZXggPSBrZXlUb05ld0luZGV4TWFwLmdldChwcmV2Q2hpbGQua2V5KTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBmb3IgKGogPSBzMjsgaiA8PSBlMjsgaisrKSB7DQogICAgICAgICAgICBpZiAobmV3SW5kZXhUb09sZEluZGV4TWFwW2ogLSBzMl0gPT09IDAgJiYgaXNTYW1lVk5vZGVUeXBlKHByZXZDaGlsZCwgYzJbal0pKSB7DQogICAgICAgICAgICAgIG5ld0luZGV4ID0gajsNCiAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICB9DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGlmIChuZXdJbmRleCA9PT0gdm9pZCAwKSB7DQogICAgICAgICAgdW5tb3VudChwcmV2Q2hpbGQsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIHRydWUpOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIG5ld0luZGV4VG9PbGRJbmRleE1hcFtuZXdJbmRleCAtIHMyXSA9IGkgKyAxOw0KICAgICAgICAgIGlmIChuZXdJbmRleCA+PSBtYXhOZXdJbmRleFNvRmFyKSB7DQogICAgICAgICAgICBtYXhOZXdJbmRleFNvRmFyID0gbmV3SW5kZXg7DQogICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIG1vdmVkID0gdHJ1ZTsNCiAgICAgICAgICB9DQogICAgICAgICAgcGF0Y2goDQogICAgICAgICAgICBwcmV2Q2hpbGQsDQogICAgICAgICAgICBjMltuZXdJbmRleF0sDQogICAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgICBudWxsLA0KICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgICApOw0KICAgICAgICAgIHBhdGNoZWQrKzsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgY29uc3QgaW5jcmVhc2luZ05ld0luZGV4U2VxdWVuY2UgPSBtb3ZlZCA/IGdldFNlcXVlbmNlKG5ld0luZGV4VG9PbGRJbmRleE1hcCkgOiBFTVBUWV9BUlI7DQogICAgICBqID0gaW5jcmVhc2luZ05ld0luZGV4U2VxdWVuY2UubGVuZ3RoIC0gMTsNCiAgICAgIGZvciAoaSA9IHRvQmVQYXRjaGVkIC0gMTsgaSA+PSAwOyBpLS0pIHsNCiAgICAgICAgY29uc3QgbmV4dEluZGV4ID0gczIgKyBpOw0KICAgICAgICBjb25zdCBuZXh0Q2hpbGQgPSBjMltuZXh0SW5kZXhdOw0KICAgICAgICBjb25zdCBhbmNob3IgPSBuZXh0SW5kZXggKyAxIDwgbDIgPyBjMltuZXh0SW5kZXggKyAxXS5lbCA6IHBhcmVudEFuY2hvcjsNCiAgICAgICAgaWYgKG5ld0luZGV4VG9PbGRJbmRleE1hcFtpXSA9PT0gMCkgew0KICAgICAgICAgIHBhdGNoKA0KICAgICAgICAgICAgbnVsbCwNCiAgICAgICAgICAgIG5leHRDaGlsZCwNCiAgICAgICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgICAgIGFuY2hvciwNCiAgICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICAgKTsNCiAgICAgICAgfSBlbHNlIGlmIChtb3ZlZCkgew0KICAgICAgICAgIGlmIChqIDwgMCB8fCBpICE9PSBpbmNyZWFzaW5nTmV3SW5kZXhTZXF1ZW5jZVtqXSkgew0KICAgICAgICAgICAgbW92ZShuZXh0Q2hpbGQsIGNvbnRhaW5lciwgYW5jaG9yLCAyKTsNCiAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgai0tOw0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgfTsNCiAgY29uc3QgbW92ZSA9ICh2bm9kZSwgY29udGFpbmVyLCBhbmNob3IsIG1vdmVUeXBlLCBwYXJlbnRTdXNwZW5zZSA9IG51bGwpID0+IHsNCiAgICBjb25zdCB7IGVsLCB0eXBlLCB0cmFuc2l0aW9uLCBjaGlsZHJlbiwgc2hhcGVGbGFnIH0gPSB2bm9kZTsNCiAgICBpZiAoc2hhcGVGbGFnICYgNikgew0KICAgICAgbW92ZSh2bm9kZS5jb21wb25lbnQuc3ViVHJlZSwgY29udGFpbmVyLCBhbmNob3IsIG1vdmVUeXBlKTsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgaWYgKHNoYXBlRmxhZyAmIDEyOCkgew0KICAgICAgdm5vZGUuc3VzcGVuc2UubW92ZShjb250YWluZXIsIGFuY2hvciwgbW92ZVR5cGUpOw0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBpZiAoc2hhcGVGbGFnICYgNjQpIHsNCiAgICAgIHR5cGUubW92ZSh2bm9kZSwgY29udGFpbmVyLCBhbmNob3IsIGludGVybmFscyk7DQogICAgICByZXR1cm47DQogICAgfQ0KICAgIGlmICh0eXBlID09PSBGcmFnbWVudCkgew0KICAgICAgaG9zdEluc2VydChlbCwgY29udGFpbmVyLCBhbmNob3IpOw0KICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykgew0KICAgICAgICBtb3ZlKGNoaWxkcmVuW2ldLCBjb250YWluZXIsIGFuY2hvciwgbW92ZVR5cGUpOw0KICAgICAgfQ0KICAgICAgaG9zdEluc2VydCh2bm9kZS5hbmNob3IsIGNvbnRhaW5lciwgYW5jaG9yKTsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgaWYgKHR5cGUgPT09IFN0YXRpYykgew0KICAgICAgbW92ZVN0YXRpY05vZGUodm5vZGUsIGNvbnRhaW5lciwgYW5jaG9yKTsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgY29uc3QgbmVlZFRyYW5zaXRpb24yID0gbW92ZVR5cGUgIT09IDIgJiYgc2hhcGVGbGFnICYgMSAmJiB0cmFuc2l0aW9uOw0KICAgIGlmIChuZWVkVHJhbnNpdGlvbjIpIHsNCiAgICAgIGlmIChtb3ZlVHlwZSA9PT0gMCkgew0KICAgICAgICB0cmFuc2l0aW9uLmJlZm9yZUVudGVyKGVsKTsNCiAgICAgICAgaG9zdEluc2VydChlbCwgY29udGFpbmVyLCBhbmNob3IpOw0KICAgICAgICBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QoKCkgPT4gdHJhbnNpdGlvbi5lbnRlcihlbCksIHBhcmVudFN1c3BlbnNlKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGNvbnN0IHsgbGVhdmUsIGRlbGF5TGVhdmUsIGFmdGVyTGVhdmUgfSA9IHRyYW5zaXRpb247DQogICAgICAgIGNvbnN0IHJlbW92ZTIgPSAoKSA9PiB7DQogICAgICAgICAgaWYgKHZub2RlLmN0eC5pc1VubW91bnRlZCkgew0KICAgICAgICAgICAgaG9zdFJlbW92ZShlbCk7DQogICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIGhvc3RJbnNlcnQoZWwsIGNvbnRhaW5lciwgYW5jaG9yKTsNCiAgICAgICAgICB9DQogICAgICAgIH07DQogICAgICAgIGNvbnN0IHBlcmZvcm1MZWF2ZSA9ICgpID0+IHsNCiAgICAgICAgICBsZWF2ZShlbCwgKCkgPT4gew0KICAgICAgICAgICAgcmVtb3ZlMigpOw0KICAgICAgICAgICAgYWZ0ZXJMZWF2ZSAmJiBhZnRlckxlYXZlKCk7DQogICAgICAgICAgfSk7DQogICAgICAgIH07DQogICAgICAgIGlmIChkZWxheUxlYXZlKSB7DQogICAgICAgICAgZGVsYXlMZWF2ZShlbCwgcmVtb3ZlMiwgcGVyZm9ybUxlYXZlKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBwZXJmb3JtTGVhdmUoKTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0gZWxzZSB7DQogICAgICBob3N0SW5zZXJ0KGVsLCBjb250YWluZXIsIGFuY2hvcik7DQogICAgfQ0KICB9Ow0KICBjb25zdCB1bm1vdW50ID0gKHZub2RlLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBkb1JlbW92ZSA9IGZhbHNlLCBvcHRpbWl6ZWQgPSBmYWxzZSkgPT4gew0KICAgIGNvbnN0IHsNCiAgICAgIHR5cGUsDQogICAgICBwcm9wcywNCiAgICAgIHJlZiwNCiAgICAgIGNoaWxkcmVuLA0KICAgICAgZHluYW1pY0NoaWxkcmVuLA0KICAgICAgc2hhcGVGbGFnLA0KICAgICAgcGF0Y2hGbGFnLA0KICAgICAgZGlycywNCiAgICAgIGNhY2hlSW5kZXgNCiAgICB9ID0gdm5vZGU7DQogICAgaWYgKHBhdGNoRmxhZyA9PT0gLTIpIHsNCiAgICAgIG9wdGltaXplZCA9IGZhbHNlOw0KICAgIH0NCiAgICBpZiAocmVmICE9IG51bGwpIHsNCiAgICAgIHBhdXNlVHJhY2tpbmcoKTsNCiAgICAgIHNldFJlZihyZWYsIG51bGwsIHBhcmVudFN1c3BlbnNlLCB2bm9kZSwgdHJ1ZSk7DQogICAgICByZXNldFRyYWNraW5nKCk7DQogICAgfQ0KICAgIGlmIChjYWNoZUluZGV4ICE9IG51bGwpIHsNCiAgICAgIHBhcmVudENvbXBvbmVudC5yZW5kZXJDYWNoZVtjYWNoZUluZGV4XSA9IHZvaWQgMDsNCiAgICB9DQogICAgaWYgKHNoYXBlRmxhZyAmIDI1Nikgew0KICAgICAgcGFyZW50Q29tcG9uZW50LmN0eC5kZWFjdGl2YXRlKHZub2RlKTsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgY29uc3Qgc2hvdWxkSW52b2tlRGlycyA9IHNoYXBlRmxhZyAmIDEgJiYgZGlyczsNCiAgICBjb25zdCBzaG91bGRJbnZva2VWbm9kZUhvb2sgPSAhaXNBc3luY1dyYXBwZXIodm5vZGUpOw0KICAgIGxldCB2bm9kZUhvb2s7DQogICAgaWYgKHNob3VsZEludm9rZVZub2RlSG9vayAmJiAodm5vZGVIb29rID0gcHJvcHMgJiYgcHJvcHMub25Wbm9kZUJlZm9yZVVubW91bnQpKSB7DQogICAgICBpbnZva2VWTm9kZUhvb2sodm5vZGVIb29rLCBwYXJlbnRDb21wb25lbnQsIHZub2RlKTsNCiAgICB9DQogICAgaWYgKHNoYXBlRmxhZyAmIDYpIHsNCiAgICAgIHVubW91bnRDb21wb25lbnQodm5vZGUuY29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgZG9SZW1vdmUpOw0KICAgIH0gZWxzZSB7DQogICAgICBpZiAoc2hhcGVGbGFnICYgMTI4KSB7DQogICAgICAgIHZub2RlLnN1c3BlbnNlLnVubW91bnQocGFyZW50U3VzcGVuc2UsIGRvUmVtb3ZlKTsNCiAgICAgICAgcmV0dXJuOw0KICAgICAgfQ0KICAgICAgaWYgKHNob3VsZEludm9rZURpcnMpIHsNCiAgICAgICAgaW52b2tlRGlyZWN0aXZlSG9vayh2bm9kZSwgbnVsbCwgcGFyZW50Q29tcG9uZW50LCAiYmVmb3JlVW5tb3VudCIpOw0KICAgICAgfQ0KICAgICAgaWYgKHNoYXBlRmxhZyAmIDY0KSB7DQogICAgICAgIHZub2RlLnR5cGUucmVtb3ZlKA0KICAgICAgICAgIHZub2RlLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBpbnRlcm5hbHMsDQogICAgICAgICAgZG9SZW1vdmUNCiAgICAgICAgKTsNCiAgICAgIH0gZWxzZSBpZiAoZHluYW1pY0NoaWxkcmVuICYmIC8vICM1MTU0DQogICAgICAvLyB3aGVuIHYtb25jZSBpcyB1c2VkIGluc2lkZSBhIGJsb2NrLCBzZXRCbG9ja1RyYWNraW5nKC0xKSBtYXJrcyB0aGUNCiAgICAgIC8vIHBhcmVudCBibG9jayB3aXRoIGhhc09uY2U6IHRydWUNCiAgICAgIC8vIHNvIHRoYXQgaXQgZG9lc24ndCB0YWtlIHRoZSBmYXN0IHBhdGggZHVyaW5nIHVubW91bnQgLSBvdGhlcndpc2UNCiAgICAgIC8vIGNvbXBvbmVudHMgbmVzdGVkIGluIHYtb25jZSBhcmUgbmV2ZXIgdW5tb3VudGVkLg0KICAgICAgIWR5bmFtaWNDaGlsZHJlbi5oYXNPbmNlICYmIC8vICMxMTUzOiBmYXN0IHBhdGggc2hvdWxkIG5vdCBiZSB0YWtlbiBmb3Igbm9uLXN0YWJsZSAodi1mb3IpIGZyYWdtZW50cw0KICAgICAgKHR5cGUgIT09IEZyYWdtZW50IHx8IHBhdGNoRmxhZyA+IDAgJiYgcGF0Y2hGbGFnICYgNjQpKSB7DQogICAgICAgIHVubW91bnRDaGlsZHJlbigNCiAgICAgICAgICBkeW5hbWljQ2hpbGRyZW4sDQogICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgIGZhbHNlLA0KICAgICAgICAgIHRydWUNCiAgICAgICAgKTsNCiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gRnJhZ21lbnQgJiYgcGF0Y2hGbGFnICYgKDEyOCB8IDI1NikgfHwgIW9wdGltaXplZCAmJiBzaGFwZUZsYWcgJiAxNikgew0KICAgICAgICB1bm1vdW50Q2hpbGRyZW4oY2hpbGRyZW4sIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UpOw0KICAgICAgfQ0KICAgICAgaWYgKGRvUmVtb3ZlKSB7DQogICAgICAgIHJlbW92ZSh2bm9kZSk7DQogICAgICB9DQogICAgfQ0KICAgIGlmIChzaG91bGRJbnZva2VWbm9kZUhvb2sgJiYgKHZub2RlSG9vayA9IHByb3BzICYmIHByb3BzLm9uVm5vZGVVbm1vdW50ZWQpIHx8IHNob3VsZEludm9rZURpcnMpIHsNCiAgICAgIHF1ZXVlUG9zdFJlbmRlckVmZmVjdCgoKSA9PiB7DQogICAgICAgIHZub2RlSG9vayAmJiBpbnZva2VWTm9kZUhvb2sodm5vZGVIb29rLCBwYXJlbnRDb21wb25lbnQsIHZub2RlKTsNCiAgICAgICAgc2hvdWxkSW52b2tlRGlycyAmJiBpbnZva2VEaXJlY3RpdmVIb29rKHZub2RlLCBudWxsLCBwYXJlbnRDb21wb25lbnQsICJ1bm1vdW50ZWQiKTsNCiAgICAgIH0sIHBhcmVudFN1c3BlbnNlKTsNCiAgICB9DQogIH07DQogIGNvbnN0IHJlbW92ZSA9ICh2bm9kZSkgPT4gew0KICAgIGNvbnN0IHsgdHlwZSwgZWwsIGFuY2hvciwgdHJhbnNpdGlvbiB9ID0gdm5vZGU7DQogICAgaWYgKHR5cGUgPT09IEZyYWdtZW50KSB7DQogICAgICBpZiAodm5vZGUucGF0Y2hGbGFnID4gMCAmJiB2bm9kZS5wYXRjaEZsYWcgJiAyMDQ4ICYmIHRyYW5zaXRpb24gJiYgIXRyYW5zaXRpb24ucGVyc2lzdGVkKSB7DQogICAgICAgIHZub2RlLmNoaWxkcmVuLmZvckVhY2goKGNoaWxkKSA9PiB7DQogICAgICAgICAgaWYgKGNoaWxkLnR5cGUgPT09IENvbW1lbnQpIHsNCiAgICAgICAgICAgIGhvc3RSZW1vdmUoY2hpbGQuZWwpOw0KICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICByZW1vdmUoY2hpbGQpOw0KICAgICAgICAgIH0NCiAgICAgICAgfSk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICByZW1vdmVGcmFnbWVudChlbCwgYW5jaG9yKTsNCiAgICAgIH0NCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgaWYgKHR5cGUgPT09IFN0YXRpYykgew0KICAgICAgcmVtb3ZlU3RhdGljTm9kZSh2bm9kZSk7DQogICAgICByZXR1cm47DQogICAgfQ0KICAgIGNvbnN0IHBlcmZvcm1SZW1vdmUgPSAoKSA9PiB7DQogICAgICBob3N0UmVtb3ZlKGVsKTsNCiAgICAgIGlmICh0cmFuc2l0aW9uICYmICF0cmFuc2l0aW9uLnBlcnNpc3RlZCAmJiB0cmFuc2l0aW9uLmFmdGVyTGVhdmUpIHsNCiAgICAgICAgdHJhbnNpdGlvbi5hZnRlckxlYXZlKCk7DQogICAgICB9DQogICAgfTsNCiAgICBpZiAodm5vZGUuc2hhcGVGbGFnICYgMSAmJiB0cmFuc2l0aW9uICYmICF0cmFuc2l0aW9uLnBlcnNpc3RlZCkgew0KICAgICAgY29uc3QgeyBsZWF2ZSwgZGVsYXlMZWF2ZSB9ID0gdHJhbnNpdGlvbjsNCiAgICAgIGNvbnN0IHBlcmZvcm1MZWF2ZSA9ICgpID0+IGxlYXZlKGVsLCBwZXJmb3JtUmVtb3ZlKTsNCiAgICAgIGlmIChkZWxheUxlYXZlKSB7DQogICAgICAgIGRlbGF5TGVhdmUodm5vZGUuZWwsIHBlcmZvcm1SZW1vdmUsIHBlcmZvcm1MZWF2ZSk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBwZXJmb3JtTGVhdmUoKTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgcGVyZm9ybVJlbW92ZSgpOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgcmVtb3ZlRnJhZ21lbnQgPSAoY3VyLCBlbmQpID0+IHsNCiAgICBsZXQgbmV4dDsNCiAgICB3aGlsZSAoY3VyICE9PSBlbmQpIHsNCiAgICAgIG5leHQgPSBob3N0TmV4dFNpYmxpbmcoY3VyKTsNCiAgICAgIGhvc3RSZW1vdmUoY3VyKTsNCiAgICAgIGN1ciA9IG5leHQ7DQogICAgfQ0KICAgIGhvc3RSZW1vdmUoZW5kKTsNCiAgfTsNCiAgY29uc3QgdW5tb3VudENvbXBvbmVudCA9IChpbnN0YW5jZSwgcGFyZW50U3VzcGVuc2UsIGRvUmVtb3ZlKSA9PiB7DQogICAgaWYgKGluc3RhbmNlLnR5cGUuX19obXJJZCkgew0KICAgICAgdW5yZWdpc3RlckhNUihpbnN0YW5jZSk7DQogICAgfQ0KICAgIGNvbnN0IHsNCiAgICAgIGJ1bSwNCiAgICAgIHNjb3BlLA0KICAgICAgam9iLA0KICAgICAgc3ViVHJlZSwNCiAgICAgIHVtLA0KICAgICAgbSwNCiAgICAgIGEsDQogICAgICBwYXJlbnQsDQogICAgICBzbG90czogeyBfXzogc2xvdENhY2hlS2V5cyB9DQogICAgfSA9IGluc3RhbmNlOw0KICAgIGludmFsaWRhdGVNb3VudChtKTsNCiAgICBpbnZhbGlkYXRlTW91bnQoYSk7DQogICAgaWYgKGJ1bSkgew0KICAgICAgaW52b2tlQXJyYXlGbnMoYnVtKTsNCiAgICB9DQogICAgaWYgKHBhcmVudCAmJiBpc0FycmF5KHNsb3RDYWNoZUtleXMpKSB7DQogICAgICBzbG90Q2FjaGVLZXlzLmZvckVhY2goKHYpID0+IHsNCiAgICAgICAgcGFyZW50LnJlbmRlckNhY2hlW3ZdID0gdm9pZCAwOw0KICAgICAgfSk7DQogICAgfQ0KICAgIHNjb3BlLnN0b3AoKTsNCiAgICBpZiAoam9iKSB7DQogICAgICBqb2IuZmxhZ3MgfD0gODsNCiAgICAgIHVubW91bnQoc3ViVHJlZSwgaW5zdGFuY2UsIHBhcmVudFN1c3BlbnNlLCBkb1JlbW92ZSk7DQogICAgfQ0KICAgIGlmICh1bSkgew0KICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KHVtLCBwYXJlbnRTdXNwZW5zZSk7DQogICAgfQ0KICAgIHF1ZXVlUG9zdFJlbmRlckVmZmVjdCgoKSA9PiB7DQogICAgICBpbnN0YW5jZS5pc1VubW91bnRlZCA9IHRydWU7DQogICAgfSwgcGFyZW50U3VzcGVuc2UpOw0KICAgIGlmIChwYXJlbnRTdXNwZW5zZSAmJiBwYXJlbnRTdXNwZW5zZS5wZW5kaW5nQnJhbmNoICYmICFwYXJlbnRTdXNwZW5zZS5pc1VubW91bnRlZCAmJiBpbnN0YW5jZS5hc3luY0RlcCAmJiAhaW5zdGFuY2UuYXN5bmNSZXNvbHZlZCAmJiBpbnN0YW5jZS5zdXNwZW5zZUlkID09PSBwYXJlbnRTdXNwZW5zZS5wZW5kaW5nSWQpIHsNCiAgICAgIHBhcmVudFN1c3BlbnNlLmRlcHMtLTsNCiAgICAgIGlmIChwYXJlbnRTdXNwZW5zZS5kZXBzID09PSAwKSB7DQogICAgICAgIHBhcmVudFN1c3BlbnNlLnJlc29sdmUoKTsNCiAgICAgIH0NCiAgICB9DQogICAgew0KICAgICAgZGV2dG9vbHNDb21wb25lbnRSZW1vdmVkKGluc3RhbmNlKTsNCiAgICB9DQogIH07DQogIGNvbnN0IHVubW91bnRDaGlsZHJlbiA9IChjaGlsZHJlbiwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgZG9SZW1vdmUgPSBmYWxzZSwgb3B0aW1pemVkID0gZmFsc2UsIHN0YXJ0ID0gMCkgPT4gew0KICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7DQogICAgICB1bm1vdW50KGNoaWxkcmVuW2ldLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBkb1JlbW92ZSwgb3B0aW1pemVkKTsNCiAgICB9DQogIH07DQogIGNvbnN0IGdldE5leHRIb3N0Tm9kZSA9ICh2bm9kZSkgPT4gew0KICAgIGlmICh2bm9kZS5zaGFwZUZsYWcgJiA2KSB7DQogICAgICByZXR1cm4gZ2V0TmV4dEhvc3ROb2RlKHZub2RlLmNvbXBvbmVudC5zdWJUcmVlKTsNCiAgICB9DQogICAgaWYgKHZub2RlLnNoYXBlRmxhZyAmIDEyOCkgew0KICAgICAgcmV0dXJuIHZub2RlLnN1c3BlbnNlLm5leHQoKTsNCiAgICB9DQogICAgY29uc3QgZWwgPSBob3N0TmV4dFNpYmxpbmcodm5vZGUuYW5jaG9yIHx8IHZub2RlLmVsKTsNCiAgICBjb25zdCB0ZWxlcG9ydEVuZCA9IGVsICYmIGVsW1RlbGVwb3J0RW5kS2V5XTsNCiAgICByZXR1cm4gdGVsZXBvcnRFbmQgPyBob3N0TmV4dFNpYmxpbmcodGVsZXBvcnRFbmQpIDogZWw7DQogIH07DQogIGxldCBpc0ZsdXNoaW5nID0gZmFsc2U7DQogIGNvbnN0IHJlbmRlciA9ICh2bm9kZSwgY29udGFpbmVyLCBuYW1lc3BhY2UpID0+IHsNCiAgICBpZiAodm5vZGUgPT0gbnVsbCkgew0KICAgICAgaWYgKGNvbnRhaW5lci5fdm5vZGUpIHsNCiAgICAgICAgdW5tb3VudChjb250YWluZXIuX3Zub2RlLCBudWxsLCBudWxsLCB0cnVlKTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgcGF0Y2goDQogICAgICAgIGNvbnRhaW5lci5fdm5vZGUgfHwgbnVsbCwNCiAgICAgICAgdm5vZGUsDQogICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgbnVsbCwNCiAgICAgICAgbnVsbCwNCiAgICAgICAgbnVsbCwNCiAgICAgICAgbmFtZXNwYWNlDQogICAgICApOw0KICAgIH0NCiAgICBjb250YWluZXIuX3Zub2RlID0gdm5vZGU7DQogICAgaWYgKCFpc0ZsdXNoaW5nKSB7DQogICAgICBpc0ZsdXNoaW5nID0gdHJ1ZTsNCiAgICAgIGZsdXNoUHJlRmx1c2hDYnMoKTsNCiAgICAgIGZsdXNoUG9zdEZsdXNoQ2JzKCk7DQogICAgICBpc0ZsdXNoaW5nID0gZmFsc2U7DQogICAgfQ0KICB9Ow0KICBjb25zdCBpbnRlcm5hbHMgPSB7DQogICAgcDogcGF0Y2gsDQogICAgdW06IHVubW91bnQsDQogICAgbTogbW92ZSwNCiAgICByOiByZW1vdmUsDQogICAgbXQ6IG1vdW50Q29tcG9uZW50LA0KICAgIG1jOiBtb3VudENoaWxkcmVuLA0KICAgIHBjOiBwYXRjaENoaWxkcmVuLA0KICAgIHBiYzogcGF0Y2hCbG9ja0NoaWxkcmVuLA0KICAgIG46IGdldE5leHRIb3N0Tm9kZSwNCiAgICBvOiBvcHRpb25zDQogIH07DQogIGxldCBoeWRyYXRlOw0KICByZXR1cm4gew0KICAgIHJlbmRlciwNCiAgICBoeWRyYXRlLA0KICAgIGNyZWF0ZUFwcDogY3JlYXRlQXBwQVBJKHJlbmRlcikNCiAgfTsNCn0NCmZ1bmN0aW9uIHJlc29sdmVDaGlsZHJlbk5hbWVzcGFjZSh7IHR5cGUsIHByb3BzIH0sIGN1cnJlbnROYW1lc3BhY2UpIHsNCiAgcmV0dXJuIGN1cnJlbnROYW1lc3BhY2UgPT09ICJzdmciICYmIHR5cGUgPT09ICJmb3JlaWduT2JqZWN0IiB8fCBjdXJyZW50TmFtZXNwYWNlID09PSAibWF0aG1sIiAmJiB0eXBlID09PSAiYW5ub3RhdGlvbi14bWwiICYmIHByb3BzICYmIHByb3BzLmVuY29kaW5nICYmIHByb3BzLmVuY29kaW5nLmluY2x1ZGVzKCJodG1sIikgPyB2b2lkIDAgOiBjdXJyZW50TmFtZXNwYWNlOw0KfQ0KZnVuY3Rpb24gdG9nZ2xlUmVjdXJzZSh7IGVmZmVjdCwgam9iIH0sIGFsbG93ZWQpIHsNCiAgaWYgKGFsbG93ZWQpIHsNCiAgICBlZmZlY3QuZmxhZ3MgfD0gMzI7DQogICAgam9iLmZsYWdzIHw9IDQ7DQogIH0gZWxzZSB7DQogICAgZWZmZWN0LmZsYWdzICY9IC0zMzsNCiAgICBqb2IuZmxhZ3MgJj0gLTU7DQogIH0NCn0NCmZ1bmN0aW9uIG5lZWRUcmFuc2l0aW9uKHBhcmVudFN1c3BlbnNlLCB0cmFuc2l0aW9uKSB7DQogIHJldHVybiAoIXBhcmVudFN1c3BlbnNlIHx8IHBhcmVudFN1c3BlbnNlICYmICFwYXJlbnRTdXNwZW5zZS5wZW5kaW5nQnJhbmNoKSAmJiB0cmFuc2l0aW9uICYmICF0cmFuc2l0aW9uLnBlcnNpc3RlZDsNCn0NCmZ1bmN0aW9uIHRyYXZlcnNlU3RhdGljQ2hpbGRyZW4objEsIG4yLCBzaGFsbG93ID0gZmFsc2UpIHsNCiAgY29uc3QgY2gxID0gbjEuY2hpbGRyZW47DQogIGNvbnN0IGNoMiA9IG4yLmNoaWxkcmVuOw0KICBpZiAoaXNBcnJheShjaDEpICYmIGlzQXJyYXkoY2gyKSkgew0KICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2gxLmxlbmd0aDsgaSsrKSB7DQogICAgICBjb25zdCBjMSA9IGNoMVtpXTsNCiAgICAgIGxldCBjMiA9IGNoMltpXTsNCiAgICAgIGlmIChjMi5zaGFwZUZsYWcgJiAxICYmICFjMi5keW5hbWljQ2hpbGRyZW4pIHsNCiAgICAgICAgaWYgKGMyLnBhdGNoRmxhZyA8PSAwIHx8IGMyLnBhdGNoRmxhZyA9PT0gMzIpIHsNCiAgICAgICAgICBjMiA9IGNoMltpXSA9IGNsb25lSWZNb3VudGVkKGNoMltpXSk7DQogICAgICAgICAgYzIuZWwgPSBjMS5lbDsNCiAgICAgICAgfQ0KICAgICAgICBpZiAoIXNoYWxsb3cgJiYgYzIucGF0Y2hGbGFnICE9PSAtMikNCiAgICAgICAgICB0cmF2ZXJzZVN0YXRpY0NoaWxkcmVuKGMxLCBjMik7DQogICAgICB9DQogICAgICBpZiAoYzIudHlwZSA9PT0gVGV4dCkgew0KICAgICAgICBjMi5lbCA9IGMxLmVsOw0KICAgICAgfQ0KICAgICAgaWYgKGMyLnR5cGUgPT09IENvbW1lbnQgJiYgIWMyLmVsKSB7DQogICAgICAgIGMyLmVsID0gYzEuZWw7DQogICAgICB9DQogICAgICB7DQogICAgICAgIGMyLmVsICYmIChjMi5lbC5fX3Zub2RlID0gYzIpOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KfQ0KZnVuY3Rpb24gZ2V0U2VxdWVuY2UoYXJyKSB7DQogIGNvbnN0IHAgPSBhcnIuc2xpY2UoKTsNCiAgY29uc3QgcmVzdWx0ID0gWzBdOw0KICBsZXQgaSwgaiwgdSwgdiwgYzsNCiAgY29uc3QgbGVuID0gYXJyLmxlbmd0aDsNCiAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7DQogICAgY29uc3QgYXJySSA9IGFycltpXTsNCiAgICBpZiAoYXJySSAhPT0gMCkgew0KICAgICAgaiA9IHJlc3VsdFtyZXN1bHQubGVuZ3RoIC0gMV07DQogICAgICBpZiAoYXJyW2pdIDwgYXJySSkgew0KICAgICAgICBwW2ldID0gajsNCiAgICAgICAgcmVzdWx0LnB1c2goaSk7DQogICAgICAgIGNvbnRpbnVlOw0KICAgICAgfQ0KICAgICAgdSA9IDA7DQogICAgICB2ID0gcmVzdWx0Lmxlbmd0aCAtIDE7DQogICAgICB3aGlsZSAodSA8IHYpIHsNCiAgICAgICAgYyA9IHUgKyB2ID4+IDE7DQogICAgICAgIGlmIChhcnJbcmVzdWx0W2NdXSA8IGFyckkpIHsNCiAgICAgICAgICB1ID0gYyArIDE7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgdiA9IGM7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGlmIChhcnJJIDwgYXJyW3Jlc3VsdFt1XV0pIHsNCiAgICAgICAgaWYgKHUgPiAwKSB7DQogICAgICAgICAgcFtpXSA9IHJlc3VsdFt1IC0gMV07DQogICAgICAgIH0NCiAgICAgICAgcmVzdWx0W3VdID0gaTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgdSA9IHJlc3VsdC5sZW5ndGg7DQogIHYgPSByZXN1bHRbdSAtIDFdOw0KICB3aGlsZSAodS0tID4gMCkgew0KICAgIHJlc3VsdFt1XSA9IHY7DQogICAgdiA9IHBbdl07DQogIH0NCiAgcmV0dXJuIHJlc3VsdDsNCn0NCmZ1bmN0aW9uIGxvY2F0ZU5vbkh5ZHJhdGVkQXN5bmNSb290KGluc3RhbmNlKSB7DQogIGNvbnN0IHN1YkNvbXBvbmVudCA9IGluc3RhbmNlLnN1YlRyZWUuY29tcG9uZW50Ow0KICBpZiAoc3ViQ29tcG9uZW50KSB7DQogICAgaWYgKHN1YkNvbXBvbmVudC5hc3luY0RlcCAmJiAhc3ViQ29tcG9uZW50LmFzeW5jUmVzb2x2ZWQpIHsNCiAgICAgIHJldHVybiBzdWJDb21wb25lbnQ7DQogICAgfSBlbHNlIHsNCiAgICAgIHJldHVybiBsb2NhdGVOb25IeWRyYXRlZEFzeW5jUm9vdChzdWJDb21wb25lbnQpOw0KICAgIH0NCiAgfQ0KfQ0KZnVuY3Rpb24gaW52YWxpZGF0ZU1vdW50KGhvb2tzKSB7DQogIGlmIChob29rcykgew0KICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaG9va3MubGVuZ3RoOyBpKyspDQogICAgICBob29rc1tpXS5mbGFncyB8PSA4Ow0KICB9DQp9DQoNCmNvbnN0IHNzckNvbnRleHRLZXkgPSBTeW1ib2wuZm9yKCJ2LXNjeCIpOw0KY29uc3QgdXNlU1NSQ29udGV4dCA9ICgpID0+IHsNCiAgew0KICAgIGNvbnN0IGN0eCA9IGluamVjdChzc3JDb250ZXh0S2V5KTsNCiAgICBpZiAoIWN0eCkgew0KICAgICAgd2FybiQxKA0KICAgICAgICBgU2VydmVyIHJlbmRlcmluZyBjb250ZXh0IG5vdCBwcm92aWRlZC4gTWFrZSBzdXJlIHRvIG9ubHkgY2FsbCB1c2VTU1JDb250ZXh0KCkgY29uZGl0aW9uYWxseSBpbiB0aGUgc2VydmVyIGJ1aWxkLmANCiAgICAgICk7DQogICAgfQ0KICAgIHJldHVybiBjdHg7DQogIH0NCn07DQoNCmZ1bmN0aW9uIHdhdGNoKHNvdXJjZSwgY2IsIG9wdGlvbnMpIHsNCiAgaWYgKCFpc0Z1bmN0aW9uKGNiKSkgew0KICAgIHdhcm4kMSgNCiAgICAgIGBcYHdhdGNoKGZuLCBvcHRpb25zPylcYCBzaWduYXR1cmUgaGFzIGJlZW4gbW92ZWQgdG8gYSBzZXBhcmF0ZSBBUEkuIFVzZSBcYHdhdGNoRWZmZWN0KGZuLCBvcHRpb25zPylcYCBpbnN0ZWFkLiBcYHdhdGNoXGAgbm93IG9ubHkgc3VwcG9ydHMgXGB3YXRjaChzb3VyY2UsIGNiLCBvcHRpb25zPykgc2lnbmF0dXJlLmANCiAgICApOw0KICB9DQogIHJldHVybiBkb1dhdGNoKHNvdXJjZSwgY2IsIG9wdGlvbnMpOw0KfQ0KZnVuY3Rpb24gZG9XYXRjaChzb3VyY2UsIGNiLCBvcHRpb25zID0gRU1QVFlfT0JKKSB7DQogIGNvbnN0IHsgaW1tZWRpYXRlLCBkZWVwLCBmbHVzaCwgb25jZSB9ID0gb3B0aW9uczsNCiAgaWYgKCFjYikgew0KICAgIGlmIChpbW1lZGlhdGUgIT09IHZvaWQgMCkgew0KICAgICAgd2FybiQxKA0KICAgICAgICBgd2F0Y2goKSAiaW1tZWRpYXRlIiBvcHRpb24gaXMgb25seSByZXNwZWN0ZWQgd2hlbiB1c2luZyB0aGUgd2F0Y2goc291cmNlLCBjYWxsYmFjaywgb3B0aW9ucz8pIHNpZ25hdHVyZS5gDQogICAgICApOw0KICAgIH0NCiAgICBpZiAoZGVlcCAhPT0gdm9pZCAwKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGB3YXRjaCgpICJkZWVwIiBvcHRpb24gaXMgb25seSByZXNwZWN0ZWQgd2hlbiB1c2luZyB0aGUgd2F0Y2goc291cmNlLCBjYWxsYmFjaywgb3B0aW9ucz8pIHNpZ25hdHVyZS5gDQogICAgICApOw0KICAgIH0NCiAgICBpZiAob25jZSAhPT0gdm9pZCAwKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGB3YXRjaCgpICJvbmNlIiBvcHRpb24gaXMgb25seSByZXNwZWN0ZWQgd2hlbiB1c2luZyB0aGUgd2F0Y2goc291cmNlLCBjYWxsYmFjaywgb3B0aW9ucz8pIHNpZ25hdHVyZS5gDQogICAgICApOw0KICAgIH0NCiAgfQ0KICBjb25zdCBiYXNlV2F0Y2hPcHRpb25zID0gZXh0ZW5kKHt9LCBvcHRpb25zKTsNCiAgYmFzZVdhdGNoT3B0aW9ucy5vbldhcm4gPSB3YXJuJDE7DQogIGNvbnN0IHJ1bnNJbW1lZGlhdGVseSA9IGNiICYmIGltbWVkaWF0ZSB8fCAhY2IgJiYgZmx1c2ggIT09ICJwb3N0IjsNCiAgbGV0IHNzckNsZWFudXA7DQogIGlmIChpc0luU1NSQ29tcG9uZW50U2V0dXApIHsNCiAgICBpZiAoZmx1c2ggPT09ICJzeW5jIikgew0KICAgICAgY29uc3QgY3R4ID0gdXNlU1NSQ29udGV4dCgpOw0KICAgICAgc3NyQ2xlYW51cCA9IGN0eC5fX3dhdGNoZXJIYW5kbGVzIHx8IChjdHguX193YXRjaGVySGFuZGxlcyA9IFtdKTsNCiAgICB9IGVsc2UgaWYgKCFydW5zSW1tZWRpYXRlbHkpIHsNCiAgICAgIGNvbnN0IHdhdGNoU3RvcEhhbmRsZSA9ICgpID0+IHsNCiAgICAgIH07DQogICAgICB3YXRjaFN0b3BIYW5kbGUuc3RvcCA9IE5PT1A7DQogICAgICB3YXRjaFN0b3BIYW5kbGUucmVzdW1lID0gTk9PUDsNCiAgICAgIHdhdGNoU3RvcEhhbmRsZS5wYXVzZSA9IE5PT1A7DQogICAgICByZXR1cm4gd2F0Y2hTdG9wSGFuZGxlOw0KICAgIH0NCiAgfQ0KICBjb25zdCBpbnN0YW5jZSA9IGN1cnJlbnRJbnN0YW5jZTsNCiAgYmFzZVdhdGNoT3B0aW9ucy5jYWxsID0gKGZuLCB0eXBlLCBhcmdzKSA9PiBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZyhmbiwgaW5zdGFuY2UsIHR5cGUsIGFyZ3MpOw0KICBsZXQgaXNQcmUgPSBmYWxzZTsNCiAgaWYgKGZsdXNoID09PSAicG9zdCIpIHsNCiAgICBiYXNlV2F0Y2hPcHRpb25zLnNjaGVkdWxlciA9IChqb2IpID0+IHsNCiAgICAgIHF1ZXVlUG9zdFJlbmRlckVmZmVjdChqb2IsIGluc3RhbmNlICYmIGluc3RhbmNlLnN1c3BlbnNlKTsNCiAgICB9Ow0KICB9IGVsc2UgaWYgKGZsdXNoICE9PSAic3luYyIpIHsNCiAgICBpc1ByZSA9IHRydWU7DQogICAgYmFzZVdhdGNoT3B0aW9ucy5zY2hlZHVsZXIgPSAoam9iLCBpc0ZpcnN0UnVuKSA9PiB7DQogICAgICBpZiAoaXNGaXJzdFJ1bikgew0KICAgICAgICBqb2IoKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHF1ZXVlSm9iKGpvYik7DQogICAgICB9DQogICAgfTsNCiAgfQ0KICBiYXNlV2F0Y2hPcHRpb25zLmF1Z21lbnRKb2IgPSAoam9iKSA9PiB7DQogICAgaWYgKGNiKSB7DQogICAgICBqb2IuZmxhZ3MgfD0gNDsNCiAgICB9DQogICAgaWYgKGlzUHJlKSB7DQogICAgICBqb2IuZmxhZ3MgfD0gMjsNCiAgICAgIGlmIChpbnN0YW5jZSkgew0KICAgICAgICBqb2IuaWQgPSBpbnN0YW5jZS51aWQ7DQogICAgICAgIGpvYi5pID0gaW5zdGFuY2U7DQogICAgICB9DQogICAgfQ0KICB9Ow0KICBjb25zdCB3YXRjaEhhbmRsZSA9IHdhdGNoJDEoc291cmNlLCBjYiwgYmFzZVdhdGNoT3B0aW9ucyk7DQogIGlmIChpc0luU1NSQ29tcG9uZW50U2V0dXApIHsNCiAgICBpZiAoc3NyQ2xlYW51cCkgew0KICAgICAgc3NyQ2xlYW51cC5wdXNoKHdhdGNoSGFuZGxlKTsNCiAgICB9IGVsc2UgaWYgKHJ1bnNJbW1lZGlhdGVseSkgew0KICAgICAgd2F0Y2hIYW5kbGUoKTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIHdhdGNoSGFuZGxlOw0KfQ0KZnVuY3Rpb24gaW5zdGFuY2VXYXRjaChzb3VyY2UsIHZhbHVlLCBvcHRpb25zKSB7DQogIGNvbnN0IHB1YmxpY1RoaXMgPSB0aGlzLnByb3h5Ow0KICBjb25zdCBnZXR0ZXIgPSBpc1N0cmluZyhzb3VyY2UpID8gc291cmNlLmluY2x1ZGVzKCIuIikgPyBjcmVhdGVQYXRoR2V0dGVyKHB1YmxpY1RoaXMsIHNvdXJjZSkgOiAoKSA9PiBwdWJsaWNUaGlzW3NvdXJjZV0gOiBzb3VyY2UuYmluZChwdWJsaWNUaGlzLCBwdWJsaWNUaGlzKTsNCiAgbGV0IGNiOw0KICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHsNCiAgICBjYiA9IHZhbHVlOw0KICB9IGVsc2Ugew0KICAgIGNiID0gdmFsdWUuaGFuZGxlcjsNCiAgICBvcHRpb25zID0gdmFsdWU7DQogIH0NCiAgY29uc3QgcmVzZXQgPSBzZXRDdXJyZW50SW5zdGFuY2UodGhpcyk7DQogIGNvbnN0IHJlcyA9IGRvV2F0Y2goZ2V0dGVyLCBjYi5iaW5kKHB1YmxpY1RoaXMpLCBvcHRpb25zKTsNCiAgcmVzZXQoKTsNCiAgcmV0dXJuIHJlczsNCn0NCmZ1bmN0aW9uIGNyZWF0ZVBhdGhHZXR0ZXIoY3R4LCBwYXRoKSB7DQogIGNvbnN0IHNlZ21lbnRzID0gcGF0aC5zcGxpdCgiLiIpOw0KICByZXR1cm4gKCkgPT4gew0KICAgIGxldCBjdXIgPSBjdHg7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWdtZW50cy5sZW5ndGggJiYgY3VyOyBpKyspIHsNCiAgICAgIGN1ciA9IGN1cltzZWdtZW50c1tpXV07DQogICAgfQ0KICAgIHJldHVybiBjdXI7DQogIH07DQp9DQoNCmNvbnN0IGdldE1vZGVsTW9kaWZpZXJzID0gKHByb3BzLCBtb2RlbE5hbWUpID0+IHsNCiAgcmV0dXJuIG1vZGVsTmFtZSA9PT0gIm1vZGVsVmFsdWUiIHx8IG1vZGVsTmFtZSA9PT0gIm1vZGVsLXZhbHVlIiA/IHByb3BzLm1vZGVsTW9kaWZpZXJzIDogcHJvcHNbYCR7bW9kZWxOYW1lfU1vZGlmaWVyc2BdIHx8IHByb3BzW2Ake2NhbWVsaXplKG1vZGVsTmFtZSl9TW9kaWZpZXJzYF0gfHwgcHJvcHNbYCR7aHlwaGVuYXRlKG1vZGVsTmFtZSl9TW9kaWZpZXJzYF07DQp9Ow0KDQpmdW5jdGlvbiBlbWl0KGluc3RhbmNlLCBldmVudCwgLi4ucmF3QXJncykgew0KICBpZiAoaW5zdGFuY2UuaXNVbm1vdW50ZWQpIHJldHVybjsNCiAgY29uc3QgcHJvcHMgPSBpbnN0YW5jZS52bm9kZS5wcm9wcyB8fCBFTVBUWV9PQko7DQogIHsNCiAgICBjb25zdCB7DQogICAgICBlbWl0c09wdGlvbnMsDQogICAgICBwcm9wc09wdGlvbnM6IFtwcm9wc09wdGlvbnNdDQogICAgfSA9IGluc3RhbmNlOw0KICAgIGlmIChlbWl0c09wdGlvbnMpIHsNCiAgICAgIGlmICghKGV2ZW50IGluIGVtaXRzT3B0aW9ucykgJiYgdHJ1ZSkgew0KICAgICAgICBpZiAoIXByb3BzT3B0aW9ucyB8fCAhKHRvSGFuZGxlcktleShjYW1lbGl6ZShldmVudCkpIGluIHByb3BzT3B0aW9ucykpIHsNCiAgICAgICAgICB3YXJuJDEoDQogICAgICAgICAgICBgQ29tcG9uZW50IGVtaXR0ZWQgZXZlbnQgIiR7ZXZlbnR9IiBidXQgaXQgaXMgbmVpdGhlciBkZWNsYXJlZCBpbiB0aGUgZW1pdHMgb3B0aW9uIG5vciBhcyBhbiAiJHt0b0hhbmRsZXJLZXkoY2FtZWxpemUoZXZlbnQpKX0iIHByb3AuYA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGNvbnN0IHZhbGlkYXRvciA9IGVtaXRzT3B0aW9uc1tldmVudF07DQogICAgICAgIGlmIChpc0Z1bmN0aW9uKHZhbGlkYXRvcikpIHsNCiAgICAgICAgICBjb25zdCBpc1ZhbGlkID0gdmFsaWRhdG9yKC4uLnJhd0FyZ3MpOw0KICAgICAgICAgIGlmICghaXNWYWxpZCkgew0KICAgICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgICBgSW52YWxpZCBldmVudCBhcmd1bWVudHM6IGV2ZW50IHZhbGlkYXRpb24gZmFpbGVkIGZvciBldmVudCAiJHtldmVudH0iLmANCiAgICAgICAgICAgICk7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICB9DQogIGxldCBhcmdzID0gcmF3QXJnczsNCiAgY29uc3QgaXNNb2RlbExpc3RlbmVyID0gZXZlbnQuc3RhcnRzV2l0aCgidXBkYXRlOiIpOw0KICBjb25zdCBtb2RpZmllcnMgPSBpc01vZGVsTGlzdGVuZXIgJiYgZ2V0TW9kZWxNb2RpZmllcnMocHJvcHMsIGV2ZW50LnNsaWNlKDcpKTsNCiAgaWYgKG1vZGlmaWVycykgew0KICAgIGlmIChtb2RpZmllcnMudHJpbSkgew0KICAgICAgYXJncyA9IHJhd0FyZ3MubWFwKChhKSA9PiBpc1N0cmluZyhhKSA/IGEudHJpbSgpIDogYSk7DQogICAgfQ0KICAgIGlmIChtb2RpZmllcnMubnVtYmVyKSB7DQogICAgICBhcmdzID0gcmF3QXJncy5tYXAobG9vc2VUb051bWJlcik7DQogICAgfQ0KICB9DQogIHsNCiAgICBkZXZ0b29sc0NvbXBvbmVudEVtaXQoaW5zdGFuY2UsIGV2ZW50LCBhcmdzKTsNCiAgfQ0KICB7DQogICAgY29uc3QgbG93ZXJDYXNlRXZlbnQgPSBldmVudC50b0xvd2VyQ2FzZSgpOw0KICAgIGlmIChsb3dlckNhc2VFdmVudCAhPT0gZXZlbnQgJiYgcHJvcHNbdG9IYW5kbGVyS2V5KGxvd2VyQ2FzZUV2ZW50KV0pIHsNCiAgICAgIHdhcm4kMSgNCiAgICAgICAgYEV2ZW50ICIke2xvd2VyQ2FzZUV2ZW50fSIgaXMgZW1pdHRlZCBpbiBjb21wb25lbnQgJHtmb3JtYXRDb21wb25lbnROYW1lKA0KICAgICAgICAgIGluc3RhbmNlLA0KICAgICAgICAgIGluc3RhbmNlLnR5cGUNCiAgICAgICAgKX0gYnV0IHRoZSBoYW5kbGVyIGlzIHJlZ2lzdGVyZWQgZm9yICIke2V2ZW50fSIuIE5vdGUgdGhhdCBIVE1MIGF0dHJpYnV0ZXMgYXJlIGNhc2UtaW5zZW5zaXRpdmUgYW5kIHlvdSBjYW5ub3QgdXNlIHYtb24gdG8gbGlzdGVuIHRvIGNhbWVsQ2FzZSBldmVudHMgd2hlbiB1c2luZyBpbi1ET00gdGVtcGxhdGVzLiBZb3Ugc2hvdWxkIHByb2JhYmx5IHVzZSAiJHtoeXBoZW5hdGUoDQogICAgICAgICAgZXZlbnQNCiAgICAgICAgKX0iIGluc3RlYWQgb2YgIiR7ZXZlbnR9Ii5gDQogICAgICApOw0KICAgIH0NCiAgfQ0KICBsZXQgaGFuZGxlck5hbWU7DQogIGxldCBoYW5kbGVyID0gcHJvcHNbaGFuZGxlck5hbWUgPSB0b0hhbmRsZXJLZXkoZXZlbnQpXSB8fCAvLyBhbHNvIHRyeSBjYW1lbENhc2UgZXZlbnQgaGFuZGxlciAoIzIyNDkpDQogIHByb3BzW2hhbmRsZXJOYW1lID0gdG9IYW5kbGVyS2V5KGNhbWVsaXplKGV2ZW50KSldOw0KICBpZiAoIWhhbmRsZXIgJiYgaXNNb2RlbExpc3RlbmVyKSB7DQogICAgaGFuZGxlciA9IHByb3BzW2hhbmRsZXJOYW1lID0gdG9IYW5kbGVyS2V5KGh5cGhlbmF0ZShldmVudCkpXTsNCiAgfQ0KICBpZiAoaGFuZGxlcikgew0KICAgIGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nKA0KICAgICAgaGFuZGxlciwNCiAgICAgIGluc3RhbmNlLA0KICAgICAgNiwNCiAgICAgIGFyZ3MNCiAgICApOw0KICB9DQogIGNvbnN0IG9uY2VIYW5kbGVyID0gcHJvcHNbaGFuZGxlck5hbWUgKyBgT25jZWBdOw0KICBpZiAob25jZUhhbmRsZXIpIHsNCiAgICBpZiAoIWluc3RhbmNlLmVtaXR0ZWQpIHsNCiAgICAgIGluc3RhbmNlLmVtaXR0ZWQgPSB7fTsNCiAgICB9IGVsc2UgaWYgKGluc3RhbmNlLmVtaXR0ZWRbaGFuZGxlck5hbWVdKSB7DQogICAgICByZXR1cm47DQogICAgfQ0KICAgIGluc3RhbmNlLmVtaXR0ZWRbaGFuZGxlck5hbWVdID0gdHJ1ZTsNCiAgICBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZygNCiAgICAgIG9uY2VIYW5kbGVyLA0KICAgICAgaW5zdGFuY2UsDQogICAgICA2LA0KICAgICAgYXJncw0KICAgICk7DQogIH0NCn0NCmZ1bmN0aW9uIG5vcm1hbGl6ZUVtaXRzT3B0aW9ucyhjb21wLCBhcHBDb250ZXh0LCBhc01peGluID0gZmFsc2UpIHsNCiAgY29uc3QgY2FjaGUgPSBhcHBDb250ZXh0LmVtaXRzQ2FjaGU7DQogIGNvbnN0IGNhY2hlZCA9IGNhY2hlLmdldChjb21wKTsNCiAgaWYgKGNhY2hlZCAhPT0gdm9pZCAwKSB7DQogICAgcmV0dXJuIGNhY2hlZDsNCiAgfQ0KICBjb25zdCByYXcgPSBjb21wLmVtaXRzOw0KICBsZXQgbm9ybWFsaXplZCA9IHt9Ow0KICBsZXQgaGFzRXh0ZW5kcyA9IGZhbHNlOw0KICBpZiAoIWlzRnVuY3Rpb24oY29tcCkpIHsNCiAgICBjb25zdCBleHRlbmRFbWl0cyA9IChyYXcyKSA9PiB7DQogICAgICBjb25zdCBub3JtYWxpemVkRnJvbUV4dGVuZCA9IG5vcm1hbGl6ZUVtaXRzT3B0aW9ucyhyYXcyLCBhcHBDb250ZXh0LCB0cnVlKTsNCiAgICAgIGlmIChub3JtYWxpemVkRnJvbUV4dGVuZCkgew0KICAgICAgICBoYXNFeHRlbmRzID0gdHJ1ZTsNCiAgICAgICAgZXh0ZW5kKG5vcm1hbGl6ZWQsIG5vcm1hbGl6ZWRGcm9tRXh0ZW5kKTsNCiAgICAgIH0NCiAgICB9Ow0KICAgIGlmICghYXNNaXhpbiAmJiBhcHBDb250ZXh0Lm1peGlucy5sZW5ndGgpIHsNCiAgICAgIGFwcENvbnRleHQubWl4aW5zLmZvckVhY2goZXh0ZW5kRW1pdHMpOw0KICAgIH0NCiAgICBpZiAoY29tcC5leHRlbmRzKSB7DQogICAgICBleHRlbmRFbWl0cyhjb21wLmV4dGVuZHMpOw0KICAgIH0NCiAgICBpZiAoY29tcC5taXhpbnMpIHsNCiAgICAgIGNvbXAubWl4aW5zLmZvckVhY2goZXh0ZW5kRW1pdHMpOw0KICAgIH0NCiAgfQ0KICBpZiAoIXJhdyAmJiAhaGFzRXh0ZW5kcykgew0KICAgIGlmIChpc09iamVjdChjb21wKSkgew0KICAgICAgY2FjaGUuc2V0KGNvbXAsIG51bGwpOw0KICAgIH0NCiAgICByZXR1cm4gbnVsbDsNCiAgfQ0KICBpZiAoaXNBcnJheShyYXcpKSB7DQogICAgcmF3LmZvckVhY2goKGtleSkgPT4gbm9ybWFsaXplZFtrZXldID0gbnVsbCk7DQogIH0gZWxzZSB7DQogICAgZXh0ZW5kKG5vcm1hbGl6ZWQsIHJhdyk7DQogIH0NCiAgaWYgKGlzT2JqZWN0KGNvbXApKSB7DQogICAgY2FjaGUuc2V0KGNvbXAsIG5vcm1hbGl6ZWQpOw0KICB9DQogIHJldHVybiBub3JtYWxpemVkOw0KfQ0KZnVuY3Rpb24gaXNFbWl0TGlzdGVuZXIob3B0aW9ucywga2V5KSB7DQogIGlmICghb3B0aW9ucyB8fCAhaXNPbihrZXkpKSB7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9DQogIGtleSA9IGtleS5zbGljZSgyKS5yZXBsYWNlKC9PbmNlJC8sICIiKTsNCiAgcmV0dXJuIGhhc093bihvcHRpb25zLCBrZXlbMF0udG9Mb3dlckNhc2UoKSArIGtleS5zbGljZSgxKSkgfHwgaGFzT3duKG9wdGlvbnMsIGh5cGhlbmF0ZShrZXkpKSB8fCBoYXNPd24ob3B0aW9ucywga2V5KTsNCn0NCg0KbGV0IGFjY2Vzc2VkQXR0cnMgPSBmYWxzZTsNCmZ1bmN0aW9uIG1hcmtBdHRyc0FjY2Vzc2VkKCkgew0KICBhY2Nlc3NlZEF0dHJzID0gdHJ1ZTsNCn0NCmZ1bmN0aW9uIHJlbmRlckNvbXBvbmVudFJvb3QkMShpbnN0YW5jZSkgew0KICBjb25zdCB7DQogICAgdHlwZTogQ29tcG9uZW50LA0KICAgIHZub2RlLA0KICAgIHByb3h5LA0KICAgIHdpdGhQcm94eSwNCiAgICBwcm9wc09wdGlvbnM6IFtwcm9wc09wdGlvbnNdLA0KICAgIHNsb3RzLA0KICAgIGF0dHJzLA0KICAgIGVtaXQsDQogICAgcmVuZGVyLA0KICAgIHJlbmRlckNhY2hlLA0KICAgIHByb3BzLA0KICAgIGRhdGEsDQogICAgc2V0dXBTdGF0ZSwNCiAgICBjdHgsDQogICAgaW5oZXJpdEF0dHJzDQogIH0gPSBpbnN0YW5jZTsNCiAgY29uc3QgcHJldiA9IHNldEN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSQxKGluc3RhbmNlKTsNCiAgbGV0IHJlc3VsdDsNCiAgbGV0IGZhbGx0aHJvdWdoQXR0cnM7DQogIHsNCiAgICBhY2Nlc3NlZEF0dHJzID0gZmFsc2U7DQogIH0NCiAgdHJ5IHsNCiAgICBpZiAodm5vZGUuc2hhcGVGbGFnICYgNCkgew0KICAgICAgY29uc3QgcHJveHlUb1VzZSA9IHdpdGhQcm94eSB8fCBwcm94eTsNCiAgICAgIGNvbnN0IHRoaXNQcm94eSA9IHNldHVwU3RhdGUuX19pc1NjcmlwdFNldHVwID8gbmV3IFByb3h5KHByb3h5VG9Vc2UsIHsNCiAgICAgICAgZ2V0KHRhcmdldCwga2V5LCByZWNlaXZlcikgew0KICAgICAgICAgIHdhcm4kMSgNCiAgICAgICAgICAgIGBQcm9wZXJ0eSAnJHtTdHJpbmcoDQogICAgICAgICAgICAgIGtleQ0KICAgICAgICAgICAgKX0nIHdhcyBhY2Nlc3NlZCB2aWEgJ3RoaXMnLiBBdm9pZCB1c2luZyAndGhpcycgaW4gdGVtcGxhdGVzLmANCiAgICAgICAgICApOw0KICAgICAgICAgIHJldHVybiBSZWZsZWN0LmdldCh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpOw0KICAgICAgICB9DQogICAgICB9KSA6IHByb3h5VG9Vc2U7DQogICAgICByZXN1bHQgPSBub3JtYWxpemVWTm9kZSQxKA0KICAgICAgICByZW5kZXIuY2FsbCgNCiAgICAgICAgICB0aGlzUHJveHksDQogICAgICAgICAgcHJveHlUb1VzZSwNCiAgICAgICAgICByZW5kZXJDYWNoZSwNCiAgICAgICAgICB0cnVlID8gc2hhbGxvd1JlYWRvbmx5KHByb3BzKSA6IHByb3BzLA0KICAgICAgICAgIHNldHVwU3RhdGUsDQogICAgICAgICAgZGF0YSwNCiAgICAgICAgICBjdHgNCiAgICAgICAgKQ0KICAgICAgKTsNCiAgICAgIGZhbGx0aHJvdWdoQXR0cnMgPSBhdHRyczsNCiAgICB9IGVsc2Ugew0KICAgICAgY29uc3QgcmVuZGVyMiA9IENvbXBvbmVudDsNCiAgICAgIGlmIChhdHRycyA9PT0gcHJvcHMpIHsNCiAgICAgICAgbWFya0F0dHJzQWNjZXNzZWQoKTsNCiAgICAgIH0NCiAgICAgIHJlc3VsdCA9IG5vcm1hbGl6ZVZOb2RlJDEoDQogICAgICAgIHJlbmRlcjIubGVuZ3RoID4gMSA/IHJlbmRlcjIoDQogICAgICAgICAgdHJ1ZSA/IHNoYWxsb3dSZWFkb25seShwcm9wcykgOiBwcm9wcywNCiAgICAgICAgICB0cnVlID8gew0KICAgICAgICAgICAgZ2V0IGF0dHJzKCkgew0KICAgICAgICAgICAgICBtYXJrQXR0cnNBY2Nlc3NlZCgpOw0KICAgICAgICAgICAgICByZXR1cm4gc2hhbGxvd1JlYWRvbmx5KGF0dHJzKTsNCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICBzbG90cywNCiAgICAgICAgICAgIGVtaXQNCiAgICAgICAgICB9IDogeyBhdHRycywgc2xvdHMsIGVtaXQgfQ0KICAgICAgICApIDogcmVuZGVyMigNCiAgICAgICAgICB0cnVlID8gc2hhbGxvd1JlYWRvbmx5KHByb3BzKSA6IHByb3BzLA0KICAgICAgICAgIG51bGwNCiAgICAgICAgKQ0KICAgICAgKTsNCiAgICAgIGZhbGx0aHJvdWdoQXR0cnMgPSBDb21wb25lbnQucHJvcHMgPyBhdHRycyA6IGdldEZ1bmN0aW9uYWxGYWxsdGhyb3VnaChhdHRycyk7DQogICAgfQ0KICB9IGNhdGNoIChlcnIpIHsNCiAgICBoYW5kbGVFcnJvcihlcnIsIGluc3RhbmNlLCAxKTsNCiAgICByZXN1bHQgPSBjcmVhdGVWTm9kZShDb21tZW50KTsNCiAgfQ0KICBsZXQgcm9vdCA9IHJlc3VsdDsNCiAgbGV0IHNldFJvb3QgPSB2b2lkIDA7DQogIGlmIChyZXN1bHQucGF0Y2hGbGFnID4gMCAmJiByZXN1bHQucGF0Y2hGbGFnICYgMjA0OCkgew0KICAgIFtyb290LCBzZXRSb290XSA9IGdldENoaWxkUm9vdChyZXN1bHQpOw0KICB9DQogIGlmIChmYWxsdGhyb3VnaEF0dHJzICYmIGluaGVyaXRBdHRycyAhPT0gZmFsc2UpIHsNCiAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoZmFsbHRocm91Z2hBdHRycyk7DQogICAgY29uc3QgeyBzaGFwZUZsYWcgfSA9IHJvb3Q7DQogICAgaWYgKGtleXMubGVuZ3RoKSB7DQogICAgICBpZiAoc2hhcGVGbGFnICYgKDEgfCA2KSkgew0KICAgICAgICBpZiAocHJvcHNPcHRpb25zICYmIGtleXMuc29tZShpc01vZGVsTGlzdGVuZXIpKSB7DQogICAgICAgICAgZmFsbHRocm91Z2hBdHRycyA9IGZpbHRlck1vZGVsTGlzdGVuZXJzKA0KICAgICAgICAgICAgZmFsbHRocm91Z2hBdHRycywNCiAgICAgICAgICAgIHByb3BzT3B0aW9ucw0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgICAgcm9vdCA9IGNsb25lVk5vZGUocm9vdCwgZmFsbHRocm91Z2hBdHRycywgZmFsc2UsIHRydWUpOw0KICAgICAgfSBlbHNlIGlmICghYWNjZXNzZWRBdHRycyAmJiByb290LnR5cGUgIT09IENvbW1lbnQpIHsNCiAgICAgICAgY29uc3QgYWxsQXR0cnMgPSBPYmplY3Qua2V5cyhhdHRycyk7DQogICAgICAgIGNvbnN0IGV2ZW50QXR0cnMgPSBbXTsNCiAgICAgICAgY29uc3QgZXh0cmFBdHRycyA9IFtdOw0KICAgICAgICBmb3IgKGxldCBpID0gMCwgbCA9IGFsbEF0dHJzLmxlbmd0aDsgaSA8IGw7IGkrKykgew0KICAgICAgICAgIGNvbnN0IGtleSA9IGFsbEF0dHJzW2ldOw0KICAgICAgICAgIGlmIChpc09uKGtleSkpIHsNCiAgICAgICAgICAgIGlmICghaXNNb2RlbExpc3RlbmVyKGtleSkpIHsNCiAgICAgICAgICAgICAgZXZlbnRBdHRycy5wdXNoKGtleVsyXS50b0xvd2VyQ2FzZSgpICsga2V5LnNsaWNlKDMpKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgZXh0cmFBdHRycy5wdXNoKGtleSk7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGlmIChleHRyYUF0dHJzLmxlbmd0aCkgew0KICAgICAgICAgIHdhcm4kMSgNCiAgICAgICAgICAgIGBFeHRyYW5lb3VzIG5vbi1wcm9wcyBhdHRyaWJ1dGVzICgke2V4dHJhQXR0cnMuam9pbigiLCAiKX0pIHdlcmUgcGFzc2VkIHRvIGNvbXBvbmVudCBidXQgY291bGQgbm90IGJlIGF1dG9tYXRpY2FsbHkgaW5oZXJpdGVkIGJlY2F1c2UgY29tcG9uZW50IHJlbmRlcnMgZnJhZ21lbnQgb3IgdGV4dCBvciB0ZWxlcG9ydCByb290IG5vZGVzLmANCiAgICAgICAgICApOw0KICAgICAgICB9DQogICAgICAgIGlmIChldmVudEF0dHJzLmxlbmd0aCkgew0KICAgICAgICAgIHdhcm4kMSgNCiAgICAgICAgICAgIGBFeHRyYW5lb3VzIG5vbi1lbWl0cyBldmVudCBsaXN0ZW5lcnMgKCR7ZXZlbnRBdHRycy5qb2luKCIsICIpfSkgd2VyZSBwYXNzZWQgdG8gY29tcG9uZW50IGJ1dCBjb3VsZCBub3QgYmUgYXV0b21hdGljYWxseSBpbmhlcml0ZWQgYmVjYXVzZSBjb21wb25lbnQgcmVuZGVycyBmcmFnbWVudCBvciB0ZXh0IHJvb3Qgbm9kZXMuIElmIHRoZSBsaXN0ZW5lciBpcyBpbnRlbmRlZCB0byBiZSBhIGNvbXBvbmVudCBjdXN0b20gZXZlbnQgbGlzdGVuZXIgb25seSwgZGVjbGFyZSBpdCB1c2luZyB0aGUgImVtaXRzIiBvcHRpb24uYA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH0NCiAgaWYgKHZub2RlLmRpcnMpIHsNCiAgICBpZiAoIWlzRWxlbWVudFJvb3Qocm9vdCkpIHsNCiAgICAgIHdhcm4kMSgNCiAgICAgICAgYFJ1bnRpbWUgZGlyZWN0aXZlIHVzZWQgb24gY29tcG9uZW50IHdpdGggbm9uLWVsZW1lbnQgcm9vdCBub2RlLiBUaGUgZGlyZWN0aXZlcyB3aWxsIG5vdCBmdW5jdGlvbiBhcyBpbnRlbmRlZC5gDQogICAgICApOw0KICAgIH0NCiAgICByb290ID0gY2xvbmVWTm9kZShyb290LCBudWxsLCBmYWxzZSwgdHJ1ZSk7DQogICAgcm9vdC5kaXJzID0gcm9vdC5kaXJzID8gcm9vdC5kaXJzLmNvbmNhdCh2bm9kZS5kaXJzKSA6IHZub2RlLmRpcnM7DQogIH0NCiAgaWYgKHZub2RlLnRyYW5zaXRpb24pIHsNCiAgICBpZiAoIWlzRWxlbWVudFJvb3Qocm9vdCkpIHsNCiAgICAgIHdhcm4kMSgNCiAgICAgICAgYENvbXBvbmVudCBpbnNpZGUgPFRyYW5zaXRpb24+IHJlbmRlcnMgbm9uLWVsZW1lbnQgcm9vdCBub2RlIHRoYXQgY2Fubm90IGJlIGFuaW1hdGVkLmANCiAgICAgICk7DQogICAgfQ0KICAgIHNldFRyYW5zaXRpb25Ib29rcyhyb290LCB2bm9kZS50cmFuc2l0aW9uKTsNCiAgfQ0KICBpZiAoc2V0Um9vdCkgew0KICAgIHNldFJvb3Qocm9vdCk7DQogIH0gZWxzZSB7DQogICAgcmVzdWx0ID0gcm9vdDsNCiAgfQ0KICBzZXRDdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UkMShwcmV2KTsNCiAgcmV0dXJuIHJlc3VsdDsNCn0NCmNvbnN0IGdldENoaWxkUm9vdCA9ICh2bm9kZSkgPT4gew0KICBjb25zdCByYXdDaGlsZHJlbiA9IHZub2RlLmNoaWxkcmVuOw0KICBjb25zdCBkeW5hbWljQ2hpbGRyZW4gPSB2bm9kZS5keW5hbWljQ2hpbGRyZW47DQogIGNvbnN0IGNoaWxkUm9vdCA9IGZpbHRlclNpbmdsZVJvb3QocmF3Q2hpbGRyZW4sIGZhbHNlKTsNCiAgaWYgKCFjaGlsZFJvb3QpIHsNCiAgICByZXR1cm4gW3Zub2RlLCB2b2lkIDBdOw0KICB9IGVsc2UgaWYgKGNoaWxkUm9vdC5wYXRjaEZsYWcgPiAwICYmIGNoaWxkUm9vdC5wYXRjaEZsYWcgJiAyMDQ4KSB7DQogICAgcmV0dXJuIGdldENoaWxkUm9vdChjaGlsZFJvb3QpOw0KICB9DQogIGNvbnN0IGluZGV4ID0gcmF3Q2hpbGRyZW4uaW5kZXhPZihjaGlsZFJvb3QpOw0KICBjb25zdCBkeW5hbWljSW5kZXggPSBkeW5hbWljQ2hpbGRyZW4gPyBkeW5hbWljQ2hpbGRyZW4uaW5kZXhPZihjaGlsZFJvb3QpIDogLTE7DQogIGNvbnN0IHNldFJvb3QgPSAodXBkYXRlZFJvb3QpID0+IHsNCiAgICByYXdDaGlsZHJlbltpbmRleF0gPSB1cGRhdGVkUm9vdDsNCiAgICBpZiAoZHluYW1pY0NoaWxkcmVuKSB7DQogICAgICBpZiAoZHluYW1pY0luZGV4ID4gLTEpIHsNCiAgICAgICAgZHluYW1pY0NoaWxkcmVuW2R5bmFtaWNJbmRleF0gPSB1cGRhdGVkUm9vdDsNCiAgICAgIH0gZWxzZSBpZiAodXBkYXRlZFJvb3QucGF0Y2hGbGFnID4gMCkgew0KICAgICAgICB2bm9kZS5keW5hbWljQ2hpbGRyZW4gPSBbLi4uZHluYW1pY0NoaWxkcmVuLCB1cGRhdGVkUm9vdF07DQogICAgICB9DQogICAgfQ0KICB9Ow0KICByZXR1cm4gW25vcm1hbGl6ZVZOb2RlJDEoY2hpbGRSb290KSwgc2V0Um9vdF07DQp9Ow0KZnVuY3Rpb24gZmlsdGVyU2luZ2xlUm9vdChjaGlsZHJlbiwgcmVjdXJzZSA9IHRydWUpIHsNCiAgbGV0IHNpbmdsZVJvb3Q7DQogIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHsNCiAgICBjb25zdCBjaGlsZCA9IGNoaWxkcmVuW2ldOw0KICAgIGlmIChpc1ZOb2RlJDIoY2hpbGQpKSB7DQogICAgICBpZiAoY2hpbGQudHlwZSAhPT0gQ29tbWVudCB8fCBjaGlsZC5jaGlsZHJlbiA9PT0gInYtaWYiKSB7DQogICAgICAgIGlmIChzaW5nbGVSb290KSB7DQogICAgICAgICAgcmV0dXJuOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIHNpbmdsZVJvb3QgPSBjaGlsZDsNCiAgICAgICAgICBpZiAocmVjdXJzZSAmJiBzaW5nbGVSb290LnBhdGNoRmxhZyA+IDAgJiYgc2luZ2xlUm9vdC5wYXRjaEZsYWcgJiAyMDQ4KSB7DQogICAgICAgICAgICByZXR1cm4gZmlsdGVyU2luZ2xlUm9vdChzaW5nbGVSb290LmNoaWxkcmVuKTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gc2luZ2xlUm9vdDsNCn0NCmNvbnN0IGdldEZ1bmN0aW9uYWxGYWxsdGhyb3VnaCA9IChhdHRycykgPT4gew0KICBsZXQgcmVzOw0KICBmb3IgKGNvbnN0IGtleSBpbiBhdHRycykgew0KICAgIGlmIChrZXkgPT09ICJjbGFzcyIgfHwga2V5ID09PSAic3R5bGUiIHx8IGlzT24oa2V5KSkgew0KICAgICAgKHJlcyB8fCAocmVzID0ge30pKVtrZXldID0gYXR0cnNba2V5XTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIHJlczsNCn07DQpjb25zdCBmaWx0ZXJNb2RlbExpc3RlbmVycyA9IChhdHRycywgcHJvcHMpID0+IHsNCiAgY29uc3QgcmVzID0ge307DQogIGZvciAoY29uc3Qga2V5IGluIGF0dHJzKSB7DQogICAgaWYgKCFpc01vZGVsTGlzdGVuZXIoa2V5KSB8fCAhKGtleS5zbGljZSg5KSBpbiBwcm9wcykpIHsNCiAgICAgIHJlc1trZXldID0gYXR0cnNba2V5XTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIHJlczsNCn07DQpjb25zdCBpc0VsZW1lbnRSb290ID0gKHZub2RlKSA9PiB7DQogIHJldHVybiB2bm9kZS5zaGFwZUZsYWcgJiAoNiB8IDEpIHx8IHZub2RlLnR5cGUgPT09IENvbW1lbnQ7DQp9Ow0KZnVuY3Rpb24gc2hvdWxkVXBkYXRlQ29tcG9uZW50KHByZXZWTm9kZSwgbmV4dFZOb2RlLCBvcHRpbWl6ZWQpIHsNCiAgY29uc3QgeyBwcm9wczogcHJldlByb3BzLCBjaGlsZHJlbjogcHJldkNoaWxkcmVuLCBjb21wb25lbnQgfSA9IHByZXZWTm9kZTsNCiAgY29uc3QgeyBwcm9wczogbmV4dFByb3BzLCBjaGlsZHJlbjogbmV4dENoaWxkcmVuLCBwYXRjaEZsYWcgfSA9IG5leHRWTm9kZTsNCiAgY29uc3QgZW1pdHMgPSBjb21wb25lbnQuZW1pdHNPcHRpb25zOw0KICBpZiAoKHByZXZDaGlsZHJlbiB8fCBuZXh0Q2hpbGRyZW4pICYmIGlzSG1yVXBkYXRpbmcpIHsNCiAgICByZXR1cm4gdHJ1ZTsNCiAgfQ0KICBpZiAobmV4dFZOb2RlLmRpcnMgfHwgbmV4dFZOb2RlLnRyYW5zaXRpb24pIHsNCiAgICByZXR1cm4gdHJ1ZTsNCiAgfQ0KICBpZiAob3B0aW1pemVkICYmIHBhdGNoRmxhZyA+PSAwKSB7DQogICAgaWYgKHBhdGNoRmxhZyAmIDEwMjQpIHsNCiAgICAgIHJldHVybiB0cnVlOw0KICAgIH0NCiAgICBpZiAocGF0Y2hGbGFnICYgMTYpIHsNCiAgICAgIGlmICghcHJldlByb3BzKSB7DQogICAgICAgIHJldHVybiAhIW5leHRQcm9wczsNCiAgICAgIH0NCiAgICAgIHJldHVybiBoYXNQcm9wc0NoYW5nZWQocHJldlByb3BzLCBuZXh0UHJvcHMsIGVtaXRzKTsNCiAgICB9IGVsc2UgaWYgKHBhdGNoRmxhZyAmIDgpIHsNCiAgICAgIGNvbnN0IGR5bmFtaWNQcm9wcyA9IG5leHRWTm9kZS5keW5hbWljUHJvcHM7DQogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGR5bmFtaWNQcm9wcy5sZW5ndGg7IGkrKykgew0KICAgICAgICBjb25zdCBrZXkgPSBkeW5hbWljUHJvcHNbaV07DQogICAgICAgIGlmIChuZXh0UHJvcHNba2V5XSAhPT0gcHJldlByb3BzW2tleV0gJiYgIWlzRW1pdExpc3RlbmVyKGVtaXRzLCBrZXkpKSB7DQogICAgICAgICAgcmV0dXJuIHRydWU7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH0gZWxzZSB7DQogICAgaWYgKHByZXZDaGlsZHJlbiB8fCBuZXh0Q2hpbGRyZW4pIHsNCiAgICAgIGlmICghbmV4dENoaWxkcmVuIHx8ICFuZXh0Q2hpbGRyZW4uJHN0YWJsZSkgew0KICAgICAgICByZXR1cm4gdHJ1ZTsNCiAgICAgIH0NCiAgICB9DQogICAgaWYgKHByZXZQcm9wcyA9PT0gbmV4dFByb3BzKSB7DQogICAgICByZXR1cm4gZmFsc2U7DQogICAgfQ0KICAgIGlmICghcHJldlByb3BzKSB7DQogICAgICByZXR1cm4gISFuZXh0UHJvcHM7DQogICAgfQ0KICAgIGlmICghbmV4dFByb3BzKSB7DQogICAgICByZXR1cm4gdHJ1ZTsNCiAgICB9DQogICAgcmV0dXJuIGhhc1Byb3BzQ2hhbmdlZChwcmV2UHJvcHMsIG5leHRQcm9wcywgZW1pdHMpOw0KICB9DQogIHJldHVybiBmYWxzZTsNCn0NCmZ1bmN0aW9uIGhhc1Byb3BzQ2hhbmdlZChwcmV2UHJvcHMsIG5leHRQcm9wcywgZW1pdHNPcHRpb25zKSB7DQogIGNvbnN0IG5leHRLZXlzID0gT2JqZWN0LmtleXMobmV4dFByb3BzKTsNCiAgaWYgKG5leHRLZXlzLmxlbmd0aCAhPT0gT2JqZWN0LmtleXMocHJldlByb3BzKS5sZW5ndGgpIHsNCiAgICByZXR1cm4gdHJ1ZTsNCiAgfQ0KICBmb3IgKGxldCBpID0gMDsgaSA8IG5leHRLZXlzLmxlbmd0aDsgaSsrKSB7DQogICAgY29uc3Qga2V5ID0gbmV4dEtleXNbaV07DQogICAgaWYgKG5leHRQcm9wc1trZXldICE9PSBwcmV2UHJvcHNba2V5XSAmJiAhaXNFbWl0TGlzdGVuZXIoZW1pdHNPcHRpb25zLCBrZXkpKSB7DQogICAgICByZXR1cm4gdHJ1ZTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIGZhbHNlOw0KfQ0KZnVuY3Rpb24gdXBkYXRlSE9DSG9zdEVsKHsgdm5vZGUsIHBhcmVudCB9LCBlbCkgew0KICB3aGlsZSAocGFyZW50KSB7DQogICAgY29uc3Qgcm9vdCA9IHBhcmVudC5zdWJUcmVlOw0KICAgIGlmIChyb290LnN1c3BlbnNlICYmIHJvb3Quc3VzcGVuc2UuYWN0aXZlQnJhbmNoID09PSB2bm9kZSkgew0KICAgICAgcm9vdC5lbCA9IHZub2RlLmVsOw0KICAgIH0NCiAgICBpZiAocm9vdCA9PT0gdm5vZGUpIHsNCiAgICAgICh2bm9kZSA9IHBhcmVudC52bm9kZSkuZWwgPSBlbDsNCiAgICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnQ7DQogICAgfSBlbHNlIHsNCiAgICAgIGJyZWFrOw0KICAgIH0NCiAgfQ0KfQ0KDQpjb25zdCBpc1N1c3BlbnNlID0gKHR5cGUpID0+IHR5cGUuX19pc1N1c3BlbnNlOw0KZnVuY3Rpb24gcXVldWVFZmZlY3RXaXRoU3VzcGVuc2UoZm4sIHN1c3BlbnNlKSB7DQogIGlmIChzdXNwZW5zZSAmJiBzdXNwZW5zZS5wZW5kaW5nQnJhbmNoKSB7DQogICAgaWYgKGlzQXJyYXkoZm4pKSB7DQogICAgICBzdXNwZW5zZS5lZmZlY3RzLnB1c2goLi4uZm4pOw0KICAgIH0gZWxzZSB7DQogICAgICBzdXNwZW5zZS5lZmZlY3RzLnB1c2goZm4pOw0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICBxdWV1ZVBvc3RGbHVzaENiKGZuKTsNCiAgfQ0KfQ0KDQpjb25zdCBGcmFnbWVudCA9IFN5bWJvbC5mb3IoInYtZmd0Iik7DQpjb25zdCBUZXh0ID0gU3ltYm9sLmZvcigidi10eHQiKTsNCmNvbnN0IENvbW1lbnQgPSBTeW1ib2wuZm9yKCJ2LWNtdCIpOw0KY29uc3QgU3RhdGljID0gU3ltYm9sLmZvcigidi1zdGMiKTsNCmxldCBjdXJyZW50QmxvY2sgPSBudWxsOw0KbGV0IGlzQmxvY2tUcmVlRW5hYmxlZCA9IDE7DQpmdW5jdGlvbiBzZXRCbG9ja1RyYWNraW5nKHZhbHVlLCBpblZPbmNlID0gZmFsc2UpIHsNCiAgaXNCbG9ja1RyZWVFbmFibGVkICs9IHZhbHVlOw0KICBpZiAodmFsdWUgPCAwICYmIGN1cnJlbnRCbG9jayAmJiBpblZPbmNlKSB7DQogICAgY3VycmVudEJsb2NrLmhhc09uY2UgPSB0cnVlOw0KICB9DQp9DQpmdW5jdGlvbiBpc1ZOb2RlJDIodmFsdWUpIHsNCiAgcmV0dXJuIHZhbHVlID8gdmFsdWUuX192X2lzVk5vZGUgPT09IHRydWUgOiBmYWxzZTsNCn0NCmZ1bmN0aW9uIGlzU2FtZVZOb2RlVHlwZShuMSwgbjIpIHsNCiAgaWYgKG4yLnNoYXBlRmxhZyAmIDYgJiYgbjEuY29tcG9uZW50KSB7DQogICAgY29uc3QgZGlydHlJbnN0YW5jZXMgPSBobXJEaXJ0eUNvbXBvbmVudHMuZ2V0KG4yLnR5cGUpOw0KICAgIGlmIChkaXJ0eUluc3RhbmNlcyAmJiBkaXJ0eUluc3RhbmNlcy5oYXMobjEuY29tcG9uZW50KSkgew0KICAgICAgbjEuc2hhcGVGbGFnICY9IC0yNTc7DQogICAgICBuMi5zaGFwZUZsYWcgJj0gLTUxMzsNCiAgICAgIHJldHVybiBmYWxzZTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIG4xLnR5cGUgPT09IG4yLnR5cGUgJiYgbjEua2V5ID09PSBuMi5rZXk7DQp9DQpjb25zdCBjcmVhdGVWTm9kZVdpdGhBcmdzVHJhbnNmb3JtID0gKC4uLmFyZ3MpID0+IHsNCiAgcmV0dXJuIF9jcmVhdGVWTm9kZSgNCiAgICAuLi5hcmdzDQogICk7DQp9Ow0KY29uc3Qgbm9ybWFsaXplS2V5ID0gKHsga2V5IH0pID0+IGtleSAhPSBudWxsID8ga2V5IDogbnVsbDsNCmNvbnN0IG5vcm1hbGl6ZVJlZiA9ICh7DQogIHJlZiwNCiAgcmVmX2tleSwNCiAgcmVmX2Zvcg0KfSkgPT4gew0KICBpZiAodHlwZW9mIHJlZiA9PT0gIm51bWJlciIpIHsNCiAgICByZWYgPSAiIiArIHJlZjsNCiAgfQ0KICByZXR1cm4gcmVmICE9IG51bGwgPyBpc1N0cmluZyhyZWYpIHx8IGlzUmVmKHJlZikgfHwgaXNGdW5jdGlvbihyZWYpID8geyBpOiBjdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UsIHI6IHJlZiwgazogcmVmX2tleSwgZjogISFyZWZfZm9yIH0gOiByZWYgOiBudWxsOw0KfTsNCmZ1bmN0aW9uIGNyZWF0ZUJhc2VWTm9kZSh0eXBlLCBwcm9wcyA9IG51bGwsIGNoaWxkcmVuID0gbnVsbCwgcGF0Y2hGbGFnID0gMCwgZHluYW1pY1Byb3BzID0gbnVsbCwgc2hhcGVGbGFnID0gdHlwZSA9PT0gRnJhZ21lbnQgPyAwIDogMSwgaXNCbG9ja05vZGUgPSBmYWxzZSwgbmVlZEZ1bGxDaGlsZHJlbk5vcm1hbGl6YXRpb24gPSBmYWxzZSkgew0KICBjb25zdCB2bm9kZSA9IHsNCiAgICBfX3ZfaXNWTm9kZTogdHJ1ZSwNCiAgICBfX3Zfc2tpcDogdHJ1ZSwNCiAgICB0eXBlLA0KICAgIHByb3BzLA0KICAgIGtleTogcHJvcHMgJiYgbm9ybWFsaXplS2V5KHByb3BzKSwNCiAgICByZWY6IHByb3BzICYmIG5vcm1hbGl6ZVJlZihwcm9wcyksDQogICAgc2NvcGVJZDogY3VycmVudFNjb3BlSWQsDQogICAgc2xvdFNjb3BlSWRzOiBudWxsLA0KICAgIGNoaWxkcmVuLA0KICAgIGNvbXBvbmVudDogbnVsbCwNCiAgICBzdXNwZW5zZTogbnVsbCwNCiAgICBzc0NvbnRlbnQ6IG51bGwsDQogICAgc3NGYWxsYmFjazogbnVsbCwNCiAgICBkaXJzOiBudWxsLA0KICAgIHRyYW5zaXRpb246IG51bGwsDQogICAgZWw6IG51bGwsDQogICAgYW5jaG9yOiBudWxsLA0KICAgIHRhcmdldDogbnVsbCwNCiAgICB0YXJnZXRTdGFydDogbnVsbCwNCiAgICB0YXJnZXRBbmNob3I6IG51bGwsDQogICAgc3RhdGljQ291bnQ6IDAsDQogICAgc2hhcGVGbGFnLA0KICAgIHBhdGNoRmxhZywNCiAgICBkeW5hbWljUHJvcHMsDQogICAgZHluYW1pY0NoaWxkcmVuOiBudWxsLA0KICAgIGFwcENvbnRleHQ6IG51bGwsDQogICAgY3R4OiBjdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UNCiAgfTsNCiAgaWYgKG5lZWRGdWxsQ2hpbGRyZW5Ob3JtYWxpemF0aW9uKSB7DQogICAgbm9ybWFsaXplQ2hpbGRyZW4odm5vZGUsIGNoaWxkcmVuKTsNCiAgICBpZiAoc2hhcGVGbGFnICYgMTI4KSB7DQogICAgICB0eXBlLm5vcm1hbGl6ZSh2bm9kZSk7DQogICAgfQ0KICB9IGVsc2UgaWYgKGNoaWxkcmVuKSB7DQogICAgdm5vZGUuc2hhcGVGbGFnIHw9IGlzU3RyaW5nKGNoaWxkcmVuKSA/IDggOiAxNjsNCiAgfQ0KICBpZiAodm5vZGUua2V5ICE9PSB2bm9kZS5rZXkpIHsNCiAgICB3YXJuJDEoYFZOb2RlIGNyZWF0ZWQgd2l0aCBpbnZhbGlkIGtleSAoTmFOKS4gVk5vZGUgdHlwZTpgLCB2bm9kZS50eXBlKTsNCiAgfQ0KICBpZiAoaXNCbG9ja1RyZWVFbmFibGVkID4gMCAmJiAvLyBhdm9pZCBhIGJsb2NrIG5vZGUgZnJvbSB0cmFja2luZyBpdHNlbGYNCiAgIWlzQmxvY2tOb2RlICYmIC8vIGhhcyBjdXJyZW50IHBhcmVudCBibG9jaw0KICBjdXJyZW50QmxvY2sgJiYgLy8gcHJlc2VuY2Ugb2YgYSBwYXRjaCBmbGFnIGluZGljYXRlcyB0aGlzIG5vZGUgbmVlZHMgcGF0Y2hpbmcgb24gdXBkYXRlcy4NCiAgLy8gY29tcG9uZW50IG5vZGVzIGFsc28gc2hvdWxkIGFsd2F5cyBiZSBwYXRjaGVkLCBiZWNhdXNlIGV2ZW4gaWYgdGhlDQogIC8vIGNvbXBvbmVudCBkb2Vzbid0IG5lZWQgdG8gdXBkYXRlLCBpdCBuZWVkcyB0byBwZXJzaXN0IHRoZSBpbnN0YW5jZSBvbiB0bw0KICAvLyB0aGUgbmV4dCB2bm9kZSBzbyB0aGF0IGl0IGNhbiBiZSBwcm9wZXJseSB1bm1vdW50ZWQgbGF0ZXIuDQogICh2bm9kZS5wYXRjaEZsYWcgPiAwIHx8IHNoYXBlRmxhZyAmIDYpICYmIC8vIHRoZSBFVkVOVFMgZmxhZyBpcyBvbmx5IGZvciBoeWRyYXRpb24gYW5kIGlmIGl0IGlzIHRoZSBvbmx5IGZsYWcsIHRoZQ0KICAvLyB2bm9kZSBzaG91bGQgbm90IGJlIGNvbnNpZGVyZWQgZHluYW1pYyBkdWUgdG8gaGFuZGxlciBjYWNoaW5nLg0KICB2bm9kZS5wYXRjaEZsYWcgIT09IDMyKSB7DQogICAgY3VycmVudEJsb2NrLnB1c2godm5vZGUpOw0KICB9DQogIHJldHVybiB2bm9kZTsNCn0NCmNvbnN0IGNyZWF0ZVZOb2RlID0gY3JlYXRlVk5vZGVXaXRoQXJnc1RyYW5zZm9ybSA7DQpmdW5jdGlvbiBfY3JlYXRlVk5vZGUodHlwZSwgcHJvcHMgPSBudWxsLCBjaGlsZHJlbiA9IG51bGwsIHBhdGNoRmxhZyA9IDAsIGR5bmFtaWNQcm9wcyA9IG51bGwsIGlzQmxvY2tOb2RlID0gZmFsc2UpIHsNCiAgaWYgKCF0eXBlIHx8IHR5cGUgPT09IE5VTExfRFlOQU1JQ19DT01QT05FTlQpIHsNCiAgICBpZiAoIXR5cGUpIHsNCiAgICAgIHdhcm4kMShgSW52YWxpZCB2bm9kZSB0eXBlIHdoZW4gY3JlYXRpbmcgdm5vZGU6ICR7dHlwZX0uYCk7DQogICAgfQ0KICAgIHR5cGUgPSBDb21tZW50Ow0KICB9DQogIGlmIChpc1ZOb2RlJDIodHlwZSkpIHsNCiAgICBjb25zdCBjbG9uZWQgPSBjbG9uZVZOb2RlKA0KICAgICAgdHlwZSwNCiAgICAgIHByb3BzLA0KICAgICAgdHJ1ZQ0KICAgICAgLyogbWVyZ2VSZWY6IHRydWUgKi8NCiAgICApOw0KICAgIGlmIChjaGlsZHJlbikgew0KICAgICAgbm9ybWFsaXplQ2hpbGRyZW4oY2xvbmVkLCBjaGlsZHJlbik7DQogICAgfQ0KICAgIGlmIChpc0Jsb2NrVHJlZUVuYWJsZWQgPiAwICYmICFpc0Jsb2NrTm9kZSAmJiBjdXJyZW50QmxvY2spIHsNCiAgICAgIGlmIChjbG9uZWQuc2hhcGVGbGFnICYgNikgew0KICAgICAgICBjdXJyZW50QmxvY2tbY3VycmVudEJsb2NrLmluZGV4T2YodHlwZSldID0gY2xvbmVkOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgY3VycmVudEJsb2NrLnB1c2goY2xvbmVkKTsNCiAgICAgIH0NCiAgICB9DQogICAgY2xvbmVkLnBhdGNoRmxhZyA9IC0yOw0KICAgIHJldHVybiBjbG9uZWQ7DQogIH0NCiAgaWYgKGlzQ2xhc3NDb21wb25lbnQodHlwZSkpIHsNCiAgICB0eXBlID0gdHlwZS5fX3ZjY09wdHM7DQogIH0NCiAgaWYgKHByb3BzKSB7DQogICAgcHJvcHMgPSBndWFyZFJlYWN0aXZlUHJvcHMocHJvcHMpOw0KICAgIGxldCB7IGNsYXNzOiBrbGFzcywgc3R5bGUgfSA9IHByb3BzOw0KICAgIGlmIChrbGFzcyAmJiAhaXNTdHJpbmcoa2xhc3MpKSB7DQogICAgICBwcm9wcy5jbGFzcyA9IG5vcm1hbGl6ZUNsYXNzKGtsYXNzKTsNCiAgICB9DQogICAgaWYgKGlzT2JqZWN0KHN0eWxlKSkgew0KICAgICAgaWYgKGlzUHJveHkoc3R5bGUpICYmICFpc0FycmF5KHN0eWxlKSkgew0KICAgICAgICBzdHlsZSA9IGV4dGVuZCh7fSwgc3R5bGUpOw0KICAgICAgfQ0KICAgICAgcHJvcHMuc3R5bGUgPSBub3JtYWxpemVTdHlsZShzdHlsZSk7DQogICAgfQ0KICB9DQogIGNvbnN0IHNoYXBlRmxhZyA9IGlzU3RyaW5nKHR5cGUpID8gMSA6IGlzU3VzcGVuc2UodHlwZSkgPyAxMjggOiBpc1RlbGVwb3J0KHR5cGUpID8gNjQgOiBpc09iamVjdCh0eXBlKSA/IDQgOiBpc0Z1bmN0aW9uKHR5cGUpID8gMiA6IDA7DQogIGlmIChzaGFwZUZsYWcgJiA0ICYmIGlzUHJveHkodHlwZSkpIHsNCiAgICB0eXBlID0gdG9SYXcodHlwZSk7DQogICAgd2FybiQxKA0KICAgICAgYFZ1ZSByZWNlaXZlZCBhIENvbXBvbmVudCB0aGF0IHdhcyBtYWRlIGEgcmVhY3RpdmUgb2JqZWN0LiBUaGlzIGNhbiBsZWFkIHRvIHVubmVjZXNzYXJ5IHBlcmZvcm1hbmNlIG92ZXJoZWFkIGFuZCBzaG91bGQgYmUgYXZvaWRlZCBieSBtYXJraW5nIHRoZSBjb21wb25lbnQgd2l0aCBcYG1hcmtSYXdcYCBvciB1c2luZyBcYHNoYWxsb3dSZWZcYCBpbnN0ZWFkIG9mIFxgcmVmXGAuYCwNCiAgICAgIGANCkNvbXBvbmVudCB0aGF0IHdhcyBtYWRlIHJlYWN0aXZlOiBgLA0KICAgICAgdHlwZQ0KICAgICk7DQogIH0NCiAgcmV0dXJuIGNyZWF0ZUJhc2VWTm9kZSgNCiAgICB0eXBlLA0KICAgIHByb3BzLA0KICAgIGNoaWxkcmVuLA0KICAgIHBhdGNoRmxhZywNCiAgICBkeW5hbWljUHJvcHMsDQogICAgc2hhcGVGbGFnLA0KICAgIGlzQmxvY2tOb2RlLA0KICAgIHRydWUNCiAgKTsNCn0NCmZ1bmN0aW9uIGd1YXJkUmVhY3RpdmVQcm9wcyhwcm9wcykgew0KICBpZiAoIXByb3BzKSByZXR1cm4gbnVsbDsNCiAgcmV0dXJuIGlzUHJveHkocHJvcHMpIHx8IGlzSW50ZXJuYWxPYmplY3QocHJvcHMpID8gZXh0ZW5kKHt9LCBwcm9wcykgOiBwcm9wczsNCn0NCmZ1bmN0aW9uIGNsb25lVk5vZGUodm5vZGUsIGV4dHJhUHJvcHMsIG1lcmdlUmVmID0gZmFsc2UsIGNsb25lVHJhbnNpdGlvbiA9IGZhbHNlKSB7DQogIGNvbnN0IHsgcHJvcHMsIHJlZiwgcGF0Y2hGbGFnLCBjaGlsZHJlbiwgdHJhbnNpdGlvbiB9ID0gdm5vZGU7DQogIGNvbnN0IG1lcmdlZFByb3BzID0gZXh0cmFQcm9wcyA/IG1lcmdlUHJvcHMocHJvcHMgfHwge30sIGV4dHJhUHJvcHMpIDogcHJvcHM7DQogIGNvbnN0IGNsb25lZCA9IHsNCiAgICBfX3ZfaXNWTm9kZTogdHJ1ZSwNCiAgICBfX3Zfc2tpcDogdHJ1ZSwNCiAgICB0eXBlOiB2bm9kZS50eXBlLA0KICAgIHByb3BzOiBtZXJnZWRQcm9wcywNCiAgICBrZXk6IG1lcmdlZFByb3BzICYmIG5vcm1hbGl6ZUtleShtZXJnZWRQcm9wcyksDQogICAgcmVmOiBleHRyYVByb3BzICYmIGV4dHJhUHJvcHMucmVmID8gKA0KICAgICAgLy8gIzIwNzggaW4gdGhlIGNhc2Ugb2YgPGNvbXBvbmVudCA6aXM9InZub2RlIiByZWY9ImV4dHJhIi8+DQogICAgICAvLyBpZiB0aGUgdm5vZGUgaXRzZWxmIGFscmVhZHkgaGFzIGEgcmVmLCBjbG9uZVZOb2RlIHdpbGwgbmVlZCB0byBtZXJnZQ0KICAgICAgLy8gdGhlIHJlZnMgc28gdGhlIHNpbmdsZSB2bm9kZSBjYW4gYmUgc2V0IG9uIG11bHRpcGxlIHJlZnMNCiAgICAgIG1lcmdlUmVmICYmIHJlZiA/IGlzQXJyYXkocmVmKSA/IHJlZi5jb25jYXQobm9ybWFsaXplUmVmKGV4dHJhUHJvcHMpKSA6IFtyZWYsIG5vcm1hbGl6ZVJlZihleHRyYVByb3BzKV0gOiBub3JtYWxpemVSZWYoZXh0cmFQcm9wcykNCiAgICApIDogcmVmLA0KICAgIHNjb3BlSWQ6IHZub2RlLnNjb3BlSWQsDQogICAgc2xvdFNjb3BlSWRzOiB2bm9kZS5zbG90U2NvcGVJZHMsDQogICAgY2hpbGRyZW46IHBhdGNoRmxhZyA9PT0gLTEgJiYgaXNBcnJheShjaGlsZHJlbikgPyBjaGlsZHJlbi5tYXAoZGVlcENsb25lVk5vZGUpIDogY2hpbGRyZW4sDQogICAgdGFyZ2V0OiB2bm9kZS50YXJnZXQsDQogICAgdGFyZ2V0U3RhcnQ6IHZub2RlLnRhcmdldFN0YXJ0LA0KICAgIHRhcmdldEFuY2hvcjogdm5vZGUudGFyZ2V0QW5jaG9yLA0KICAgIHN0YXRpY0NvdW50OiB2bm9kZS5zdGF0aWNDb3VudCwNCiAgICBzaGFwZUZsYWc6IHZub2RlLnNoYXBlRmxhZywNCiAgICAvLyBpZiB0aGUgdm5vZGUgaXMgY2xvbmVkIHdpdGggZXh0cmEgcHJvcHMsIHdlIGNhbiBubyBsb25nZXIgYXNzdW1lIGl0cw0KICAgIC8vIGV4aXN0aW5nIHBhdGNoIGZsYWcgdG8gYmUgcmVsaWFibGUgYW5kIG5lZWQgdG8gYWRkIHRoZSBGVUxMX1BST1BTIGZsYWcuDQogICAgLy8gbm90ZTogcHJlc2VydmUgZmxhZyBmb3IgZnJhZ21lbnRzIHNpbmNlIHRoZXkgdXNlIHRoZSBmbGFnIGZvciBjaGlsZHJlbg0KICAgIC8vIGZhc3QgcGF0aHMgb25seS4NCiAgICBwYXRjaEZsYWc6IGV4dHJhUHJvcHMgJiYgdm5vZGUudHlwZSAhPT0gRnJhZ21lbnQgPyBwYXRjaEZsYWcgPT09IC0xID8gMTYgOiBwYXRjaEZsYWcgfCAxNiA6IHBhdGNoRmxhZywNCiAgICBkeW5hbWljUHJvcHM6IHZub2RlLmR5bmFtaWNQcm9wcywNCiAgICBkeW5hbWljQ2hpbGRyZW46IHZub2RlLmR5bmFtaWNDaGlsZHJlbiwNCiAgICBhcHBDb250ZXh0OiB2bm9kZS5hcHBDb250ZXh0LA0KICAgIGRpcnM6IHZub2RlLmRpcnMsDQogICAgdHJhbnNpdGlvbiwNCiAgICAvLyBUaGVzZSBzaG91bGQgdGVjaG5pY2FsbHkgb25seSBiZSBub24tbnVsbCBvbiBtb3VudGVkIFZOb2Rlcy4gSG93ZXZlciwNCiAgICAvLyB0aGV5ICpzaG91bGQqIGJlIGNvcGllZCBmb3Iga2VwdC1hbGl2ZSB2bm9kZXMuIFNvIHdlIGp1c3QgYWx3YXlzIGNvcHkNCiAgICAvLyB0aGVtIHNpbmNlIHRoZW0gYmVpbmcgbm9uLW51bGwgZHVyaW5nIGEgbW91bnQgZG9lc24ndCBhZmZlY3QgdGhlIGxvZ2ljIGFzDQogICAgLy8gdGhleSB3aWxsIHNpbXBseSBiZSBvdmVyd3JpdHRlbi4NCiAgICBjb21wb25lbnQ6IHZub2RlLmNvbXBvbmVudCwNCiAgICBzdXNwZW5zZTogdm5vZGUuc3VzcGVuc2UsDQogICAgc3NDb250ZW50OiB2bm9kZS5zc0NvbnRlbnQgJiYgY2xvbmVWTm9kZSh2bm9kZS5zc0NvbnRlbnQpLA0KICAgIHNzRmFsbGJhY2s6IHZub2RlLnNzRmFsbGJhY2sgJiYgY2xvbmVWTm9kZSh2bm9kZS5zc0ZhbGxiYWNrKSwNCiAgICBlbDogdm5vZGUuZWwsDQogICAgYW5jaG9yOiB2bm9kZS5hbmNob3IsDQogICAgY3R4OiB2bm9kZS5jdHgsDQogICAgY2U6IHZub2RlLmNlDQogIH07DQogIGlmICh0cmFuc2l0aW9uICYmIGNsb25lVHJhbnNpdGlvbikgew0KICAgIHNldFRyYW5zaXRpb25Ib29rcygNCiAgICAgIGNsb25lZCwNCiAgICAgIHRyYW5zaXRpb24uY2xvbmUoY2xvbmVkKQ0KICAgICk7DQogIH0NCiAgcmV0dXJuIGNsb25lZDsNCn0NCmZ1bmN0aW9uIGRlZXBDbG9uZVZOb2RlKHZub2RlKSB7DQogIGNvbnN0IGNsb25lZCA9IGNsb25lVk5vZGUodm5vZGUpOw0KICBpZiAoaXNBcnJheSh2bm9kZS5jaGlsZHJlbikpIHsNCiAgICBjbG9uZWQuY2hpbGRyZW4gPSB2bm9kZS5jaGlsZHJlbi5tYXAoZGVlcENsb25lVk5vZGUpOw0KICB9DQogIHJldHVybiBjbG9uZWQ7DQp9DQpmdW5jdGlvbiBjcmVhdGVUZXh0Vk5vZGUodGV4dCA9ICIgIiwgZmxhZyA9IDApIHsNCiAgcmV0dXJuIGNyZWF0ZVZOb2RlKFRleHQsIG51bGwsIHRleHQsIGZsYWcpOw0KfQ0KZnVuY3Rpb24gbm9ybWFsaXplVk5vZGUkMShjaGlsZCkgew0KICBpZiAoY2hpbGQgPT0gbnVsbCB8fCB0eXBlb2YgY2hpbGQgPT09ICJib29sZWFuIikgew0KICAgIHJldHVybiBjcmVhdGVWTm9kZShDb21tZW50KTsNCiAgfSBlbHNlIGlmIChpc0FycmF5KGNoaWxkKSkgew0KICAgIHJldHVybiBjcmVhdGVWTm9kZSgNCiAgICAgIEZyYWdtZW50LA0KICAgICAgbnVsbCwNCiAgICAgIC8vICMzNjY2LCBhdm9pZCByZWZlcmVuY2UgcG9sbHV0aW9uIHdoZW4gcmV1c2luZyB2bm9kZQ0KICAgICAgY2hpbGQuc2xpY2UoKQ0KICAgICk7DQogIH0gZWxzZSBpZiAoaXNWTm9kZSQyKGNoaWxkKSkgew0KICAgIHJldHVybiBjbG9uZUlmTW91bnRlZChjaGlsZCk7DQogIH0gZWxzZSB7DQogICAgcmV0dXJuIGNyZWF0ZVZOb2RlKFRleHQsIG51bGwsIFN0cmluZyhjaGlsZCkpOw0KICB9DQp9DQpmdW5jdGlvbiBjbG9uZUlmTW91bnRlZChjaGlsZCkgew0KICByZXR1cm4gY2hpbGQuZWwgPT09IG51bGwgJiYgY2hpbGQucGF0Y2hGbGFnICE9PSAtMSB8fCBjaGlsZC5tZW1vID8gY2hpbGQgOiBjbG9uZVZOb2RlKGNoaWxkKTsNCn0NCmZ1bmN0aW9uIG5vcm1hbGl6ZUNoaWxkcmVuKHZub2RlLCBjaGlsZHJlbikgew0KICBsZXQgdHlwZSA9IDA7DQogIGNvbnN0IHsgc2hhcGVGbGFnIH0gPSB2bm9kZTsNCiAgaWYgKGNoaWxkcmVuID09IG51bGwpIHsNCiAgICBjaGlsZHJlbiA9IG51bGw7DQogIH0gZWxzZSBpZiAoaXNBcnJheShjaGlsZHJlbikpIHsNCiAgICB0eXBlID0gMTY7DQogIH0gZWxzZSBpZiAodHlwZW9mIGNoaWxkcmVuID09PSAib2JqZWN0Iikgew0KICAgIGlmIChzaGFwZUZsYWcgJiAoMSB8IDY0KSkgew0KICAgICAgY29uc3Qgc2xvdCA9IGNoaWxkcmVuLmRlZmF1bHQ7DQogICAgICBpZiAoc2xvdCkgew0KICAgICAgICBzbG90Ll9jICYmIChzbG90Ll9kID0gZmFsc2UpOw0KICAgICAgICBub3JtYWxpemVDaGlsZHJlbih2bm9kZSwgc2xvdCgpKTsNCiAgICAgICAgc2xvdC5fYyAmJiAoc2xvdC5fZCA9IHRydWUpOw0KICAgICAgfQ0KICAgICAgcmV0dXJuOw0KICAgIH0gZWxzZSB7DQogICAgICB0eXBlID0gMzI7DQogICAgICBjb25zdCBzbG90RmxhZyA9IGNoaWxkcmVuLl87DQogICAgICBpZiAoIXNsb3RGbGFnICYmICFpc0ludGVybmFsT2JqZWN0KGNoaWxkcmVuKSkgew0KICAgICAgICBjaGlsZHJlbi5fY3R4ID0gY3VycmVudFJlbmRlcmluZ0luc3RhbmNlOw0KICAgICAgfSBlbHNlIGlmIChzbG90RmxhZyA9PT0gMyAmJiBjdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UpIHsNCiAgICAgICAgaWYgKGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZS5zbG90cy5fID09PSAxKSB7DQogICAgICAgICAgY2hpbGRyZW4uXyA9IDE7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgY2hpbGRyZW4uXyA9IDI7DQogICAgICAgICAgdm5vZGUucGF0Y2hGbGFnIHw9IDEwMjQ7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH0gZWxzZSBpZiAoaXNGdW5jdGlvbihjaGlsZHJlbikpIHsNCiAgICBjaGlsZHJlbiA9IHsgZGVmYXVsdDogY2hpbGRyZW4sIF9jdHg6IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSB9Ow0KICAgIHR5cGUgPSAzMjsNCiAgfSBlbHNlIHsNCiAgICBjaGlsZHJlbiA9IFN0cmluZyhjaGlsZHJlbik7DQogICAgaWYgKHNoYXBlRmxhZyAmIDY0KSB7DQogICAgICB0eXBlID0gMTY7DQogICAgICBjaGlsZHJlbiA9IFtjcmVhdGVUZXh0Vk5vZGUoY2hpbGRyZW4pXTsNCiAgICB9IGVsc2Ugew0KICAgICAgdHlwZSA9IDg7DQogICAgfQ0KICB9DQogIHZub2RlLmNoaWxkcmVuID0gY2hpbGRyZW47DQogIHZub2RlLnNoYXBlRmxhZyB8PSB0eXBlOw0KfQ0KZnVuY3Rpb24gbWVyZ2VQcm9wcyguLi5hcmdzKSB7DQogIGNvbnN0IHJldCA9IHt9Ow0KICBmb3IgKGxldCBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHsNCiAgICBjb25zdCB0b01lcmdlID0gYXJnc1tpXTsNCiAgICBmb3IgKGNvbnN0IGtleSBpbiB0b01lcmdlKSB7DQogICAgICBpZiAoa2V5ID09PSAiY2xhc3MiKSB7DQogICAgICAgIGlmIChyZXQuY2xhc3MgIT09IHRvTWVyZ2UuY2xhc3MpIHsNCiAgICAgICAgICByZXQuY2xhc3MgPSBub3JtYWxpemVDbGFzcyhbcmV0LmNsYXNzLCB0b01lcmdlLmNsYXNzXSk7DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSBpZiAoa2V5ID09PSAic3R5bGUiKSB7DQogICAgICAgIHJldC5zdHlsZSA9IG5vcm1hbGl6ZVN0eWxlKFtyZXQuc3R5bGUsIHRvTWVyZ2Uuc3R5bGVdKTsNCiAgICAgIH0gZWxzZSBpZiAoaXNPbihrZXkpKSB7DQogICAgICAgIGNvbnN0IGV4aXN0aW5nID0gcmV0W2tleV07DQogICAgICAgIGNvbnN0IGluY29taW5nID0gdG9NZXJnZVtrZXldOw0KICAgICAgICBpZiAoaW5jb21pbmcgJiYgZXhpc3RpbmcgIT09IGluY29taW5nICYmICEoaXNBcnJheShleGlzdGluZykgJiYgZXhpc3RpbmcuaW5jbHVkZXMoaW5jb21pbmcpKSkgew0KICAgICAgICAgIHJldFtrZXldID0gZXhpc3RpbmcgPyBbXS5jb25jYXQoZXhpc3RpbmcsIGluY29taW5nKSA6IGluY29taW5nOw0KICAgICAgICB9DQogICAgICB9IGVsc2UgaWYgKGtleSAhPT0gIiIpIHsNCiAgICAgICAgcmV0W2tleV0gPSB0b01lcmdlW2tleV07DQogICAgICB9DQogICAgfQ0KICB9DQogIHJldHVybiByZXQ7DQp9DQpmdW5jdGlvbiBpbnZva2VWTm9kZUhvb2soaG9vaywgaW5zdGFuY2UsIHZub2RlLCBwcmV2Vk5vZGUgPSBudWxsKSB7DQogIGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nKGhvb2ssIGluc3RhbmNlLCA3LCBbDQogICAgdm5vZGUsDQogICAgcHJldlZOb2RlDQogIF0pOw0KfQ0KDQpjb25zdCBlbXB0eUFwcENvbnRleHQgPSBjcmVhdGVBcHBDb250ZXh0KCk7DQpsZXQgdWlkID0gMDsNCmZ1bmN0aW9uIGNyZWF0ZUNvbXBvbmVudEluc3RhbmNlJDEodm5vZGUsIHBhcmVudCwgc3VzcGVuc2UpIHsNCiAgY29uc3QgdHlwZSA9IHZub2RlLnR5cGU7DQogIGNvbnN0IGFwcENvbnRleHQgPSAocGFyZW50ID8gcGFyZW50LmFwcENvbnRleHQgOiB2bm9kZS5hcHBDb250ZXh0KSB8fCBlbXB0eUFwcENvbnRleHQ7DQogIGNvbnN0IGluc3RhbmNlID0gew0KICAgIHVpZDogdWlkKyssDQogICAgdm5vZGUsDQogICAgdHlwZSwNCiAgICBwYXJlbnQsDQogICAgYXBwQ29udGV4dCwNCiAgICByb290OiBudWxsLA0KICAgIC8vIHRvIGJlIGltbWVkaWF0ZWx5IHNldA0KICAgIG5leHQ6IG51bGwsDQogICAgc3ViVHJlZTogbnVsbCwNCiAgICAvLyB3aWxsIGJlIHNldCBzeW5jaHJvbm91c2x5IHJpZ2h0IGFmdGVyIGNyZWF0aW9uDQogICAgZWZmZWN0OiBudWxsLA0KICAgIHVwZGF0ZTogbnVsbCwNCiAgICAvLyB3aWxsIGJlIHNldCBzeW5jaHJvbm91c2x5IHJpZ2h0IGFmdGVyIGNyZWF0aW9uDQogICAgam9iOiBudWxsLA0KICAgIHNjb3BlOiBuZXcgRWZmZWN0U2NvcGUoDQogICAgICB0cnVlDQogICAgICAvKiBkZXRhY2hlZCAqLw0KICAgICksDQogICAgcmVuZGVyOiBudWxsLA0KICAgIHByb3h5OiBudWxsLA0KICAgIGV4cG9zZWQ6IG51bGwsDQogICAgZXhwb3NlUHJveHk6IG51bGwsDQogICAgd2l0aFByb3h5OiBudWxsLA0KICAgIHByb3ZpZGVzOiBwYXJlbnQgPyBwYXJlbnQucHJvdmlkZXMgOiBPYmplY3QuY3JlYXRlKGFwcENvbnRleHQucHJvdmlkZXMpLA0KICAgIGlkczogcGFyZW50ID8gcGFyZW50LmlkcyA6IFsiIiwgMCwgMF0sDQogICAgYWNjZXNzQ2FjaGU6IG51bGwsDQogICAgcmVuZGVyQ2FjaGU6IFtdLA0KICAgIC8vIGxvY2FsIHJlc29sdmVkIGFzc2V0cw0KICAgIGNvbXBvbmVudHM6IG51bGwsDQogICAgZGlyZWN0aXZlczogbnVsbCwNCiAgICAvLyByZXNvbHZlZCBwcm9wcyBhbmQgZW1pdHMgb3B0aW9ucw0KICAgIHByb3BzT3B0aW9uczogbm9ybWFsaXplUHJvcHNPcHRpb25zKHR5cGUsIGFwcENvbnRleHQpLA0KICAgIGVtaXRzT3B0aW9uczogbm9ybWFsaXplRW1pdHNPcHRpb25zKHR5cGUsIGFwcENvbnRleHQpLA0KICAgIC8vIGVtaXQNCiAgICBlbWl0OiBudWxsLA0KICAgIC8vIHRvIGJlIHNldCBpbW1lZGlhdGVseQ0KICAgIGVtaXR0ZWQ6IG51bGwsDQogICAgLy8gcHJvcHMgZGVmYXVsdCB2YWx1ZQ0KICAgIHByb3BzRGVmYXVsdHM6IEVNUFRZX09CSiwNCiAgICAvLyBpbmhlcml0QXR0cnMNCiAgICBpbmhlcml0QXR0cnM6IHR5cGUuaW5oZXJpdEF0dHJzLA0KICAgIC8vIHN0YXRlDQogICAgY3R4OiBFTVBUWV9PQkosDQogICAgZGF0YTogRU1QVFlfT0JKLA0KICAgIHByb3BzOiBFTVBUWV9PQkosDQogICAgYXR0cnM6IEVNUFRZX09CSiwNCiAgICBzbG90czogRU1QVFlfT0JKLA0KICAgIHJlZnM6IEVNUFRZX09CSiwNCiAgICBzZXR1cFN0YXRlOiBFTVBUWV9PQkosDQogICAgc2V0dXBDb250ZXh0OiBudWxsLA0KICAgIC8vIHN1c3BlbnNlIHJlbGF0ZWQNCiAgICBzdXNwZW5zZSwNCiAgICBzdXNwZW5zZUlkOiBzdXNwZW5zZSA/IHN1c3BlbnNlLnBlbmRpbmdJZCA6IDAsDQogICAgYXN5bmNEZXA6IG51bGwsDQogICAgYXN5bmNSZXNvbHZlZDogZmFsc2UsDQogICAgLy8gbGlmZWN5Y2xlIGhvb2tzDQogICAgLy8gbm90IHVzaW5nIGVudW1zIGhlcmUgYmVjYXVzZSBpdCByZXN1bHRzIGluIGNvbXB1dGVkIHByb3BlcnRpZXMNCiAgICBpc01vdW50ZWQ6IGZhbHNlLA0KICAgIGlzVW5tb3VudGVkOiBmYWxzZSwNCiAgICBpc0RlYWN0aXZhdGVkOiBmYWxzZSwNCiAgICBiYzogbnVsbCwNCiAgICBjOiBudWxsLA0KICAgIGJtOiBudWxsLA0KICAgIG06IG51bGwsDQogICAgYnU6IG51bGwsDQogICAgdTogbnVsbCwNCiAgICB1bTogbnVsbCwNCiAgICBidW06IG51bGwsDQogICAgZGE6IG51bGwsDQogICAgYTogbnVsbCwNCiAgICBydGc6IG51bGwsDQogICAgcnRjOiBudWxsLA0KICAgIGVjOiBudWxsLA0KICAgIHNwOiBudWxsDQogIH07DQogIHsNCiAgICBpbnN0YW5jZS5jdHggPSBjcmVhdGVEZXZSZW5kZXJDb250ZXh0KGluc3RhbmNlKTsNCiAgfQ0KICBpbnN0YW5jZS5yb290ID0gcGFyZW50ID8gcGFyZW50LnJvb3QgOiBpbnN0YW5jZTsNCiAgaW5zdGFuY2UuZW1pdCA9IGVtaXQuYmluZChudWxsLCBpbnN0YW5jZSk7DQogIGlmICh2bm9kZS5jZSkgew0KICAgIHZub2RlLmNlKGluc3RhbmNlKTsNCiAgfQ0KICByZXR1cm4gaW5zdGFuY2U7DQp9DQpsZXQgY3VycmVudEluc3RhbmNlID0gbnVsbDsNCmNvbnN0IGdldEN1cnJlbnRJbnN0YW5jZSA9ICgpID0+IGN1cnJlbnRJbnN0YW5jZSB8fCBjdXJyZW50UmVuZGVyaW5nSW5zdGFuY2U7DQpsZXQgaW50ZXJuYWxTZXRDdXJyZW50SW5zdGFuY2U7DQpsZXQgc2V0SW5TU1JTZXR1cFN0YXRlOw0Kew0KICBjb25zdCBnID0gZ2V0R2xvYmFsVGhpcygpOw0KICBjb25zdCByZWdpc3Rlckdsb2JhbFNldHRlciA9IChrZXksIHNldHRlcikgPT4gew0KICAgIGxldCBzZXR0ZXJzOw0KICAgIGlmICghKHNldHRlcnMgPSBnW2tleV0pKSBzZXR0ZXJzID0gZ1trZXldID0gW107DQogICAgc2V0dGVycy5wdXNoKHNldHRlcik7DQogICAgcmV0dXJuICh2KSA9PiB7DQogICAgICBpZiAoc2V0dGVycy5sZW5ndGggPiAxKSBzZXR0ZXJzLmZvckVhY2goKHNldCkgPT4gc2V0KHYpKTsNCiAgICAgIGVsc2Ugc2V0dGVyc1swXSh2KTsNCiAgICB9Ow0KICB9Ow0KICBpbnRlcm5hbFNldEN1cnJlbnRJbnN0YW5jZSA9IHJlZ2lzdGVyR2xvYmFsU2V0dGVyKA0KICAgIGBfX1ZVRV9JTlNUQU5DRV9TRVRURVJTX19gLA0KICAgICh2KSA9PiBjdXJyZW50SW5zdGFuY2UgPSB2DQogICk7DQogIHNldEluU1NSU2V0dXBTdGF0ZSA9IHJlZ2lzdGVyR2xvYmFsU2V0dGVyKA0KICAgIGBfX1ZVRV9TU1JfU0VUVEVSU19fYCwNCiAgICAodikgPT4gaXNJblNTUkNvbXBvbmVudFNldHVwID0gdg0KICApOw0KfQ0KY29uc3Qgc2V0Q3VycmVudEluc3RhbmNlID0gKGluc3RhbmNlKSA9PiB7DQogIGNvbnN0IHByZXYgPSBjdXJyZW50SW5zdGFuY2U7DQogIGludGVybmFsU2V0Q3VycmVudEluc3RhbmNlKGluc3RhbmNlKTsNCiAgaW5zdGFuY2Uuc2NvcGUub24oKTsNCiAgcmV0dXJuICgpID0+IHsNCiAgICBpbnN0YW5jZS5zY29wZS5vZmYoKTsNCiAgICBpbnRlcm5hbFNldEN1cnJlbnRJbnN0YW5jZShwcmV2KTsNCiAgfTsNCn07DQpjb25zdCB1bnNldEN1cnJlbnRJbnN0YW5jZSA9ICgpID0+IHsNCiAgY3VycmVudEluc3RhbmNlICYmIGN1cnJlbnRJbnN0YW5jZS5zY29wZS5vZmYoKTsNCiAgaW50ZXJuYWxTZXRDdXJyZW50SW5zdGFuY2UobnVsbCk7DQp9Ow0KY29uc3QgaXNCdWlsdEluVGFnID0gLyogQF9fUFVSRV9fICovIG1ha2VNYXAoInNsb3QsY29tcG9uZW50Iik7DQpmdW5jdGlvbiB2YWxpZGF0ZUNvbXBvbmVudE5hbWUobmFtZSwgeyBpc05hdGl2ZVRhZyB9KSB7DQogIGlmIChpc0J1aWx0SW5UYWcobmFtZSkgfHwgaXNOYXRpdmVUYWcobmFtZSkpIHsNCiAgICB3YXJuJDEoDQogICAgICAiRG8gbm90IHVzZSBidWlsdC1pbiBvciByZXNlcnZlZCBIVE1MIGVsZW1lbnRzIGFzIGNvbXBvbmVudCBpZDogIiArIG5hbWUNCiAgICApOw0KICB9DQp9DQpmdW5jdGlvbiBpc1N0YXRlZnVsQ29tcG9uZW50KGluc3RhbmNlKSB7DQogIHJldHVybiBpbnN0YW5jZS52bm9kZS5zaGFwZUZsYWcgJiA0Ow0KfQ0KbGV0IGlzSW5TU1JDb21wb25lbnRTZXR1cCA9IGZhbHNlOw0KZnVuY3Rpb24gc2V0dXBDb21wb25lbnQkMShpbnN0YW5jZSwgaXNTU1IgPSBmYWxzZSwgb3B0aW1pemVkID0gZmFsc2UpIHsNCiAgaXNTU1IgJiYgc2V0SW5TU1JTZXR1cFN0YXRlKGlzU1NSKTsNCiAgY29uc3QgeyBwcm9wcywgY2hpbGRyZW4gfSA9IGluc3RhbmNlLnZub2RlOw0KICBjb25zdCBpc1N0YXRlZnVsID0gaXNTdGF0ZWZ1bENvbXBvbmVudChpbnN0YW5jZSk7DQogIGluaXRQcm9wcyhpbnN0YW5jZSwgcHJvcHMsIGlzU3RhdGVmdWwsIGlzU1NSKTsNCiAgaW5pdFNsb3RzKGluc3RhbmNlLCBjaGlsZHJlbiwgb3B0aW1pemVkIHx8IGlzU1NSKTsNCiAgY29uc3Qgc2V0dXBSZXN1bHQgPSBpc1N0YXRlZnVsID8gc2V0dXBTdGF0ZWZ1bENvbXBvbmVudChpbnN0YW5jZSwgaXNTU1IpIDogdm9pZCAwOw0KICBpc1NTUiAmJiBzZXRJblNTUlNldHVwU3RhdGUoZmFsc2UpOw0KICByZXR1cm4gc2V0dXBSZXN1bHQ7DQp9DQpmdW5jdGlvbiBzZXR1cFN0YXRlZnVsQ29tcG9uZW50KGluc3RhbmNlLCBpc1NTUikgew0KICB2YXIgX2E7DQogIGNvbnN0IENvbXBvbmVudCA9IGluc3RhbmNlLnR5cGU7DQogIHsNCiAgICBpZiAoQ29tcG9uZW50Lm5hbWUpIHsNCiAgICAgIHZhbGlkYXRlQ29tcG9uZW50TmFtZShDb21wb25lbnQubmFtZSwgaW5zdGFuY2UuYXBwQ29udGV4dC5jb25maWcpOw0KICAgIH0NCiAgICBpZiAoQ29tcG9uZW50LmNvbXBvbmVudHMpIHsNCiAgICAgIGNvbnN0IG5hbWVzID0gT2JqZWN0LmtleXMoQ29tcG9uZW50LmNvbXBvbmVudHMpOw0KICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuYW1lcy5sZW5ndGg7IGkrKykgew0KICAgICAgICB2YWxpZGF0ZUNvbXBvbmVudE5hbWUobmFtZXNbaV0sIGluc3RhbmNlLmFwcENvbnRleHQuY29uZmlnKTsNCiAgICAgIH0NCiAgICB9DQogICAgaWYgKENvbXBvbmVudC5kaXJlY3RpdmVzKSB7DQogICAgICBjb25zdCBuYW1lcyA9IE9iamVjdC5rZXlzKENvbXBvbmVudC5kaXJlY3RpdmVzKTsNCiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbmFtZXMubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgdmFsaWRhdGVEaXJlY3RpdmVOYW1lKG5hbWVzW2ldKTsNCiAgICAgIH0NCiAgICB9DQogICAgaWYgKENvbXBvbmVudC5jb21waWxlck9wdGlvbnMgJiYgaXNSdW50aW1lT25seSgpKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGAiY29tcGlsZXJPcHRpb25zIiBpcyBvbmx5IHN1cHBvcnRlZCB3aGVuIHVzaW5nIGEgYnVpbGQgb2YgVnVlIHRoYXQgaW5jbHVkZXMgdGhlIHJ1bnRpbWUgY29tcGlsZXIuIFNpbmNlIHlvdSBhcmUgdXNpbmcgYSBydW50aW1lLW9ubHkgYnVpbGQsIHRoZSBvcHRpb25zIHNob3VsZCBiZSBwYXNzZWQgdmlhIHlvdXIgYnVpbGQgdG9vbCBjb25maWcgaW5zdGVhZC5gDQogICAgICApOw0KICAgIH0NCiAgfQ0KICBpbnN0YW5jZS5hY2Nlc3NDYWNoZSA9IC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuY3JlYXRlKG51bGwpOw0KICBpbnN0YW5jZS5wcm94eSA9IG5ldyBQcm94eShpbnN0YW5jZS5jdHgsIFB1YmxpY0luc3RhbmNlUHJveHlIYW5kbGVycyk7DQogIHsNCiAgICBleHBvc2VQcm9wc09uUmVuZGVyQ29udGV4dChpbnN0YW5jZSk7DQogIH0NCiAgY29uc3QgeyBzZXR1cCB9ID0gQ29tcG9uZW50Ow0KICBpZiAoc2V0dXApIHsNCiAgICBwYXVzZVRyYWNraW5nKCk7DQogICAgY29uc3Qgc2V0dXBDb250ZXh0ID0gaW5zdGFuY2Uuc2V0dXBDb250ZXh0ID0gc2V0dXAubGVuZ3RoID4gMSA/IGNyZWF0ZVNldHVwQ29udGV4dChpbnN0YW5jZSkgOiBudWxsOw0KICAgIGNvbnN0IHJlc2V0ID0gc2V0Q3VycmVudEluc3RhbmNlKGluc3RhbmNlKTsNCiAgICBjb25zdCBzZXR1cFJlc3VsdCA9IGNhbGxXaXRoRXJyb3JIYW5kbGluZygNCiAgICAgIHNldHVwLA0KICAgICAgaW5zdGFuY2UsDQogICAgICAwLA0KICAgICAgWw0KICAgICAgICBzaGFsbG93UmVhZG9ubHkoaW5zdGFuY2UucHJvcHMpICwNCiAgICAgICAgc2V0dXBDb250ZXh0DQogICAgICBdDQogICAgKTsNCiAgICBjb25zdCBpc0FzeW5jU2V0dXAgPSBpc1Byb21pc2Uoc2V0dXBSZXN1bHQpOw0KICAgIHJlc2V0VHJhY2tpbmcoKTsNCiAgICByZXNldCgpOw0KICAgIGlmICgoaXNBc3luY1NldHVwIHx8IGluc3RhbmNlLnNwKSAmJiAhaXNBc3luY1dyYXBwZXIoaW5zdGFuY2UpKSB7DQogICAgICBtYXJrQXN5bmNCb3VuZGFyeShpbnN0YW5jZSk7DQogICAgfQ0KICAgIGlmIChpc0FzeW5jU2V0dXApIHsNCiAgICAgIHNldHVwUmVzdWx0LnRoZW4odW5zZXRDdXJyZW50SW5zdGFuY2UsIHVuc2V0Q3VycmVudEluc3RhbmNlKTsNCiAgICAgIGlmIChpc1NTUikgew0KICAgICAgICByZXR1cm4gc2V0dXBSZXN1bHQudGhlbigocmVzb2x2ZWRSZXN1bHQpID0+IHsNCiAgICAgICAgICBoYW5kbGVTZXR1cFJlc3VsdChpbnN0YW5jZSwgcmVzb2x2ZWRSZXN1bHQsIGlzU1NSKTsNCiAgICAgICAgfSkuY2F0Y2goKGUpID0+IHsNCiAgICAgICAgICBoYW5kbGVFcnJvcihlLCBpbnN0YW5jZSwgMCk7DQogICAgICAgIH0pOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgaW5zdGFuY2UuYXN5bmNEZXAgPSBzZXR1cFJlc3VsdDsNCiAgICAgICAgaWYgKCFpbnN0YW5jZS5zdXNwZW5zZSkgew0KICAgICAgICAgIGNvbnN0IG5hbWUgPSAoX2EgPSBDb21wb25lbnQubmFtZSkgIT0gbnVsbCA/IF9hIDogIkFub255bW91cyI7DQogICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgYENvbXBvbmVudCA8JHtuYW1lfT46IHNldHVwIGZ1bmN0aW9uIHJldHVybmVkIGEgcHJvbWlzZSwgYnV0IG5vIDxTdXNwZW5zZT4gYm91bmRhcnkgd2FzIGZvdW5kIGluIHRoZSBwYXJlbnQgY29tcG9uZW50IHRyZWUuIEEgY29tcG9uZW50IHdpdGggYXN5bmMgc2V0dXAoKSBtdXN0IGJlIG5lc3RlZCBpbiBhIDxTdXNwZW5zZT4gaW4gb3JkZXIgdG8gYmUgcmVuZGVyZWQuYA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgaGFuZGxlU2V0dXBSZXN1bHQoaW5zdGFuY2UsIHNldHVwUmVzdWx0LCBpc1NTUik7DQogICAgfQ0KICB9IGVsc2Ugew0KICAgIGZpbmlzaENvbXBvbmVudFNldHVwKGluc3RhbmNlLCBpc1NTUik7DQogIH0NCn0NCmZ1bmN0aW9uIGhhbmRsZVNldHVwUmVzdWx0KGluc3RhbmNlLCBzZXR1cFJlc3VsdCwgaXNTU1IpIHsNCiAgaWYgKGlzRnVuY3Rpb24oc2V0dXBSZXN1bHQpKSB7DQogICAgaWYgKGluc3RhbmNlLnR5cGUuX19zc3JJbmxpbmVSZW5kZXIpIHsNCiAgICAgIGluc3RhbmNlLnNzclJlbmRlciA9IHNldHVwUmVzdWx0Ow0KICAgIH0gZWxzZSB7DQogICAgICBpbnN0YW5jZS5yZW5kZXIgPSBzZXR1cFJlc3VsdDsNCiAgICB9DQogIH0gZWxzZSBpZiAoaXNPYmplY3Qoc2V0dXBSZXN1bHQpKSB7DQogICAgaWYgKGlzVk5vZGUkMihzZXR1cFJlc3VsdCkpIHsNCiAgICAgIHdhcm4kMSgNCiAgICAgICAgYHNldHVwKCkgc2hvdWxkIG5vdCByZXR1cm4gVk5vZGVzIGRpcmVjdGx5IC0gcmV0dXJuIGEgcmVuZGVyIGZ1bmN0aW9uIGluc3RlYWQuYA0KICAgICAgKTsNCiAgICB9DQogICAgew0KICAgICAgaW5zdGFuY2UuZGV2dG9vbHNSYXdTZXR1cFN0YXRlID0gc2V0dXBSZXN1bHQ7DQogICAgfQ0KICAgIGluc3RhbmNlLnNldHVwU3RhdGUgPSBwcm94eVJlZnMoc2V0dXBSZXN1bHQpOw0KICAgIHsNCiAgICAgIGV4cG9zZVNldHVwU3RhdGVPblJlbmRlckNvbnRleHQoaW5zdGFuY2UpOw0KICAgIH0NCiAgfSBlbHNlIGlmIChzZXR1cFJlc3VsdCAhPT0gdm9pZCAwKSB7DQogICAgd2FybiQxKA0KICAgICAgYHNldHVwKCkgc2hvdWxkIHJldHVybiBhbiBvYmplY3QuIFJlY2VpdmVkOiAke3NldHVwUmVzdWx0ID09PSBudWxsID8gIm51bGwiIDogdHlwZW9mIHNldHVwUmVzdWx0fWANCiAgICApOw0KICB9DQogIGZpbmlzaENvbXBvbmVudFNldHVwKGluc3RhbmNlLCBpc1NTUik7DQp9DQpjb25zdCBpc1J1bnRpbWVPbmx5ID0gKCkgPT4gdHJ1ZTsNCmZ1bmN0aW9uIGZpbmlzaENvbXBvbmVudFNldHVwKGluc3RhbmNlLCBpc1NTUiwgc2tpcE9wdGlvbnMpIHsNCiAgY29uc3QgQ29tcG9uZW50ID0gaW5zdGFuY2UudHlwZTsNCiAgaWYgKCFpbnN0YW5jZS5yZW5kZXIpIHsNCiAgICBpbnN0YW5jZS5yZW5kZXIgPSBDb21wb25lbnQucmVuZGVyIHx8IE5PT1A7DQogIH0NCiAgew0KICAgIGNvbnN0IHJlc2V0ID0gc2V0Q3VycmVudEluc3RhbmNlKGluc3RhbmNlKTsNCiAgICBwYXVzZVRyYWNraW5nKCk7DQogICAgdHJ5IHsNCiAgICAgIGFwcGx5T3B0aW9ucyhpbnN0YW5jZSk7DQogICAgfSBmaW5hbGx5IHsNCiAgICAgIHJlc2V0VHJhY2tpbmcoKTsNCiAgICAgIHJlc2V0KCk7DQogICAgfQ0KICB9DQogIGlmICghQ29tcG9uZW50LnJlbmRlciAmJiBpbnN0YW5jZS5yZW5kZXIgPT09IE5PT1AgJiYgIWlzU1NSKSB7DQogICAgaWYgKENvbXBvbmVudC50ZW1wbGF0ZSkgew0KICAgICAgd2FybiQxKA0KICAgICAgICBgQ29tcG9uZW50IHByb3ZpZGVkIHRlbXBsYXRlIG9wdGlvbiBidXQgcnVudGltZSBjb21waWxhdGlvbiBpcyBub3Qgc3VwcG9ydGVkIGluIHRoaXMgYnVpbGQgb2YgVnVlLmAgKyAoYCBVc2UgInZ1ZS5lc20tYnJvd3Nlci5qcyIgaW5zdGVhZC5gICkNCiAgICAgICk7DQogICAgfSBlbHNlIHsNCiAgICAgIHdhcm4kMShgQ29tcG9uZW50IGlzIG1pc3NpbmcgdGVtcGxhdGUgb3IgcmVuZGVyIGZ1bmN0aW9uOiBgLCBDb21wb25lbnQpOw0KICAgIH0NCiAgfQ0KfQ0KY29uc3QgYXR0cnNQcm94eUhhbmRsZXJzID0gew0KICBnZXQodGFyZ2V0LCBrZXkpIHsNCiAgICBtYXJrQXR0cnNBY2Nlc3NlZCgpOw0KICAgIHRyYWNrKHRhcmdldCwgImdldCIsICIiKTsNCiAgICByZXR1cm4gdGFyZ2V0W2tleV07DQogIH0sDQogIHNldCgpIHsNCiAgICB3YXJuJDEoYHNldHVwQ29udGV4dC5hdHRycyBpcyByZWFkb25seS5gKTsNCiAgICByZXR1cm4gZmFsc2U7DQogIH0sDQogIGRlbGV0ZVByb3BlcnR5KCkgew0KICAgIHdhcm4kMShgc2V0dXBDb250ZXh0LmF0dHJzIGlzIHJlYWRvbmx5LmApOw0KICAgIHJldHVybiBmYWxzZTsNCiAgfQ0KfSA7DQpmdW5jdGlvbiBnZXRTbG90c1Byb3h5KGluc3RhbmNlKSB7DQogIHJldHVybiBuZXcgUHJveHkoaW5zdGFuY2Uuc2xvdHMsIHsNCiAgICBnZXQodGFyZ2V0LCBrZXkpIHsNCiAgICAgIHRyYWNrKGluc3RhbmNlLCAiZ2V0IiwgIiRzbG90cyIpOw0KICAgICAgcmV0dXJuIHRhcmdldFtrZXldOw0KICAgIH0NCiAgfSk7DQp9DQpmdW5jdGlvbiBjcmVhdGVTZXR1cENvbnRleHQoaW5zdGFuY2UpIHsNCiAgY29uc3QgZXhwb3NlID0gKGV4cG9zZWQpID0+IHsNCiAgICB7DQogICAgICBpZiAoaW5zdGFuY2UuZXhwb3NlZCkgew0KICAgICAgICB3YXJuJDEoYGV4cG9zZSgpIHNob3VsZCBiZSBjYWxsZWQgb25seSBvbmNlIHBlciBzZXR1cCgpLmApOw0KICAgICAgfQ0KICAgICAgaWYgKGV4cG9zZWQgIT0gbnVsbCkgew0KICAgICAgICBsZXQgZXhwb3NlZFR5cGUgPSB0eXBlb2YgZXhwb3NlZDsNCiAgICAgICAgaWYgKGV4cG9zZWRUeXBlID09PSAib2JqZWN0Iikgew0KICAgICAgICAgIGlmIChpc0FycmF5KGV4cG9zZWQpKSB7DQogICAgICAgICAgICBleHBvc2VkVHlwZSA9ICJhcnJheSI7DQogICAgICAgICAgfSBlbHNlIGlmIChpc1JlZihleHBvc2VkKSkgew0KICAgICAgICAgICAgZXhwb3NlZFR5cGUgPSAicmVmIjsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgaWYgKGV4cG9zZWRUeXBlICE9PSAib2JqZWN0Iikgew0KICAgICAgICAgIHdhcm4kMSgNCiAgICAgICAgICAgIGBleHBvc2UoKSBzaG91bGQgYmUgcGFzc2VkIGEgcGxhaW4gb2JqZWN0LCByZWNlaXZlZCAke2V4cG9zZWRUeXBlfS5gDQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgICBpbnN0YW5jZS5leHBvc2VkID0gZXhwb3NlZCB8fCB7fTsNCiAgfTsNCiAgew0KICAgIGxldCBhdHRyc1Byb3h5Ow0KICAgIGxldCBzbG90c1Byb3h5Ow0KICAgIHJldHVybiBPYmplY3QuZnJlZXplKHsNCiAgICAgIGdldCBhdHRycygpIHsNCiAgICAgICAgcmV0dXJuIGF0dHJzUHJveHkgfHwgKGF0dHJzUHJveHkgPSBuZXcgUHJveHkoaW5zdGFuY2UuYXR0cnMsIGF0dHJzUHJveHlIYW5kbGVycykpOw0KICAgICAgfSwNCiAgICAgIGdldCBzbG90cygpIHsNCiAgICAgICAgcmV0dXJuIHNsb3RzUHJveHkgfHwgKHNsb3RzUHJveHkgPSBnZXRTbG90c1Byb3h5KGluc3RhbmNlKSk7DQogICAgICB9LA0KICAgICAgZ2V0IGVtaXQoKSB7DQogICAgICAgIHJldHVybiAoZXZlbnQsIC4uLmFyZ3MpID0+IGluc3RhbmNlLmVtaXQoZXZlbnQsIC4uLmFyZ3MpOw0KICAgICAgfSwNCiAgICAgIGV4cG9zZQ0KICAgIH0pOw0KICB9DQp9DQpmdW5jdGlvbiBnZXRDb21wb25lbnRQdWJsaWNJbnN0YW5jZShpbnN0YW5jZSkgew0KICBpZiAoaW5zdGFuY2UuZXhwb3NlZCkgew0KICAgIHJldHVybiBpbnN0YW5jZS5leHBvc2VQcm94eSB8fCAoaW5zdGFuY2UuZXhwb3NlUHJveHkgPSBuZXcgUHJveHkocHJveHlSZWZzKG1hcmtSYXcoaW5zdGFuY2UuZXhwb3NlZCkpLCB7DQogICAgICBnZXQodGFyZ2V0LCBrZXkpIHsNCiAgICAgICAgaWYgKGtleSBpbiB0YXJnZXQpIHsNCiAgICAgICAgICByZXR1cm4gdGFyZ2V0W2tleV07DQogICAgICAgIH0gZWxzZSBpZiAoa2V5IGluIHB1YmxpY1Byb3BlcnRpZXNNYXApIHsNCiAgICAgICAgICByZXR1cm4gcHVibGljUHJvcGVydGllc01hcFtrZXldKGluc3RhbmNlKTsNCiAgICAgICAgfQ0KICAgICAgfSwNCiAgICAgIGhhcyh0YXJnZXQsIGtleSkgew0KICAgICAgICByZXR1cm4ga2V5IGluIHRhcmdldCB8fCBrZXkgaW4gcHVibGljUHJvcGVydGllc01hcDsNCiAgICAgIH0NCiAgICB9KSk7DQogIH0gZWxzZSB7DQogICAgcmV0dXJuIGluc3RhbmNlLnByb3h5Ow0KICB9DQp9DQpjb25zdCBjbGFzc2lmeVJFID0gLyg/Ol58Wy1fXSkoXHcpL2c7DQpjb25zdCBjbGFzc2lmeSA9IChzdHIpID0+IHN0ci5yZXBsYWNlKGNsYXNzaWZ5UkUsIChjKSA9PiBjLnRvVXBwZXJDYXNlKCkpLnJlcGxhY2UoL1stX10vZywgIiIpOw0KZnVuY3Rpb24gZ2V0Q29tcG9uZW50TmFtZShDb21wb25lbnQsIGluY2x1ZGVJbmZlcnJlZCA9IHRydWUpIHsNCiAgcmV0dXJuIGlzRnVuY3Rpb24oQ29tcG9uZW50KSA/IENvbXBvbmVudC5kaXNwbGF5TmFtZSB8fCBDb21wb25lbnQubmFtZSA6IENvbXBvbmVudC5uYW1lIHx8IGluY2x1ZGVJbmZlcnJlZCAmJiBDb21wb25lbnQuX19uYW1lOw0KfQ0KZnVuY3Rpb24gZm9ybWF0Q29tcG9uZW50TmFtZShpbnN0YW5jZSwgQ29tcG9uZW50LCBpc1Jvb3QgPSBmYWxzZSkgew0KICBsZXQgbmFtZSA9IGdldENvbXBvbmVudE5hbWUoQ29tcG9uZW50KTsNCiAgaWYgKCFuYW1lICYmIENvbXBvbmVudC5fX2ZpbGUpIHsNCiAgICBjb25zdCBtYXRjaCA9IENvbXBvbmVudC5fX2ZpbGUubWF0Y2goLyhbXi9cXF0rKVwuXHcrJC8pOw0KICAgIGlmIChtYXRjaCkgew0KICAgICAgbmFtZSA9IG1hdGNoWzFdOw0KICAgIH0NCiAgfQ0KICBpZiAoIW5hbWUgJiYgaW5zdGFuY2UgJiYgaW5zdGFuY2UucGFyZW50KSB7DQogICAgY29uc3QgaW5mZXJGcm9tUmVnaXN0cnkgPSAocmVnaXN0cnkpID0+IHsNCiAgICAgIGZvciAoY29uc3Qga2V5IGluIHJlZ2lzdHJ5KSB7DQogICAgICAgIGlmIChyZWdpc3RyeVtrZXldID09PSBDb21wb25lbnQpIHsNCiAgICAgICAgICByZXR1cm4ga2V5Ow0KICAgICAgICB9DQogICAgICB9DQogICAgfTsNCiAgICBuYW1lID0gaW5mZXJGcm9tUmVnaXN0cnkoDQogICAgICBpbnN0YW5jZS5jb21wb25lbnRzIHx8IGluc3RhbmNlLnBhcmVudC50eXBlLmNvbXBvbmVudHMNCiAgICApIHx8IGluZmVyRnJvbVJlZ2lzdHJ5KGluc3RhbmNlLmFwcENvbnRleHQuY29tcG9uZW50cyk7DQogIH0NCiAgcmV0dXJuIG5hbWUgPyBjbGFzc2lmeShuYW1lKSA6IGlzUm9vdCA/IGBBcHBgIDogYEFub255bW91c2A7DQp9DQpmdW5jdGlvbiBpc0NsYXNzQ29tcG9uZW50KHZhbHVlKSB7DQogIHJldHVybiBpc0Z1bmN0aW9uKHZhbHVlKSAmJiAiX192Y2NPcHRzIiBpbiB2YWx1ZTsNCn0NCg0KY29uc3QgY29tcHV0ZWQgPSAoZ2V0dGVyT3JPcHRpb25zLCBkZWJ1Z09wdGlvbnMpID0+IHsNCiAgY29uc3QgYyA9IGNvbXB1dGVkJDEoZ2V0dGVyT3JPcHRpb25zLCBkZWJ1Z09wdGlvbnMsIGlzSW5TU1JDb21wb25lbnRTZXR1cCk7DQogIHsNCiAgICBjb25zdCBpID0gZ2V0Q3VycmVudEluc3RhbmNlKCk7DQogICAgaWYgKGkgJiYgaS5hcHBDb250ZXh0LmNvbmZpZy53YXJuUmVjdXJzaXZlQ29tcHV0ZWQpIHsNCiAgICAgIGMuX3dhcm5SZWN1cnNpdmUgPSB0cnVlOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gYzsNCn07DQoNCmNvbnN0IHZlcnNpb24gPSAiMy41LjE3IjsNCmNvbnN0IHdhcm4gPSB3YXJuJDEgOw0KY29uc3QgX3NzclV0aWxzID0gew0KICBjcmVhdGVDb21wb25lbnRJbnN0YW5jZTogY3JlYXRlQ29tcG9uZW50SW5zdGFuY2UkMSwNCiAgc2V0dXBDb21wb25lbnQ6IHNldHVwQ29tcG9uZW50JDEsDQogIHJlbmRlckNvbXBvbmVudFJvb3Q6IHJlbmRlckNvbXBvbmVudFJvb3QkMSwNCiAgc2V0Q3VycmVudFJlbmRlcmluZ0luc3RhbmNlOiBzZXRDdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UkMSwNCiAgaXNWTm9kZTogaXNWTm9kZSQyLA0KICBub3JtYWxpemVWTm9kZTogbm9ybWFsaXplVk5vZGUkMSwNCiAgZ2V0Q29tcG9uZW50UHVibGljSW5zdGFuY2UsDQogIGVuc3VyZVZhbGlkVk5vZGU6IGVuc3VyZVZhbGlkVk5vZGUkMSwNCiAgcHVzaFdhcm5pbmdDb250ZXh0OiBwdXNoV2FybmluZ0NvbnRleHQkMSwNCiAgcG9wV2FybmluZ0NvbnRleHQ6IHBvcFdhcm5pbmdDb250ZXh0JDENCn07DQpjb25zdCBzc3JVdGlscyA9IF9zc3JVdGlscyA7DQoNCmxldCBwb2xpY3kgPSB2b2lkIDA7DQpjb25zdCB0dCA9IHR5cGVvZiB3aW5kb3cgIT09ICJ1bmRlZmluZWQiICYmIHdpbmRvdy50cnVzdGVkVHlwZXM7DQppZiAodHQpIHsNCiAgdHJ5IHsNCiAgICBwb2xpY3kgPSAvKiBAX19QVVJFX18gKi8gdHQuY3JlYXRlUG9saWN5KCJ2dWUiLCB7DQogICAgICBjcmVhdGVIVE1MOiAodmFsKSA9PiB2YWwNCiAgICB9KTsNCiAgfSBjYXRjaCAoZSkgew0KICAgIHdhcm4oYEVycm9yIGNyZWF0aW5nIHRydXN0ZWQgdHlwZXMgcG9saWN5OiAke2V9YCk7DQogIH0NCn0NCmNvbnN0IHVuc2FmZVRvVHJ1c3RlZEhUTUwgPSBwb2xpY3kgPyAodmFsKSA9PiBwb2xpY3kuY3JlYXRlSFRNTCh2YWwpIDogKHZhbCkgPT4gdmFsOw0KY29uc3Qgc3ZnTlMgPSAiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciOw0KY29uc3QgbWF0aG1sTlMgPSAiaHR0cDovL3d3dy53My5vcmcvMTk5OC9NYXRoL01hdGhNTCI7DQpjb25zdCBkb2MgPSB0eXBlb2YgZG9jdW1lbnQgIT09ICJ1bmRlZmluZWQiID8gZG9jdW1lbnQgOiBudWxsOw0KY29uc3QgdGVtcGxhdGVDb250YWluZXIgPSBkb2MgJiYgLyogQF9fUFVSRV9fICovIGRvYy5jcmVhdGVFbGVtZW50KCJ0ZW1wbGF0ZSIpOw0KY29uc3Qgbm9kZU9wcyA9IHsNCiAgaW5zZXJ0OiAoY2hpbGQsIHBhcmVudCwgYW5jaG9yKSA9PiB7DQogICAgcGFyZW50Lmluc2VydEJlZm9yZShjaGlsZCwgYW5jaG9yIHx8IG51bGwpOw0KICB9LA0KICByZW1vdmU6IChjaGlsZCkgPT4gew0KICAgIGNvbnN0IHBhcmVudCA9IGNoaWxkLnBhcmVudE5vZGU7DQogICAgaWYgKHBhcmVudCkgew0KICAgICAgcGFyZW50LnJlbW92ZUNoaWxkKGNoaWxkKTsNCiAgICB9DQogIH0sDQogIGNyZWF0ZUVsZW1lbnQ6ICh0YWcsIG5hbWVzcGFjZSwgaXMsIHByb3BzKSA9PiB7DQogICAgY29uc3QgZWwgPSBuYW1lc3BhY2UgPT09ICJzdmciID8gZG9jLmNyZWF0ZUVsZW1lbnROUyhzdmdOUywgdGFnKSA6IG5hbWVzcGFjZSA9PT0gIm1hdGhtbCIgPyBkb2MuY3JlYXRlRWxlbWVudE5TKG1hdGhtbE5TLCB0YWcpIDogaXMgPyBkb2MuY3JlYXRlRWxlbWVudCh0YWcsIHsgaXMgfSkgOiBkb2MuY3JlYXRlRWxlbWVudCh0YWcpOw0KICAgIGlmICh0YWcgPT09ICJzZWxlY3QiICYmIHByb3BzICYmIHByb3BzLm11bHRpcGxlICE9IG51bGwpIHsNCiAgICAgIGVsLnNldEF0dHJpYnV0ZSgibXVsdGlwbGUiLCBwcm9wcy5tdWx0aXBsZSk7DQogICAgfQ0KICAgIHJldHVybiBlbDsNCiAgfSwNCiAgY3JlYXRlVGV4dDogKHRleHQpID0+IGRvYy5jcmVhdGVUZXh0Tm9kZSh0ZXh0KSwNCiAgY3JlYXRlQ29tbWVudDogKHRleHQpID0+IGRvYy5jcmVhdGVDb21tZW50KHRleHQpLA0KICBzZXRUZXh0OiAobm9kZSwgdGV4dCkgPT4gew0KICAgIG5vZGUubm9kZVZhbHVlID0gdGV4dDsNCiAgfSwNCiAgc2V0RWxlbWVudFRleHQ6IChlbCwgdGV4dCkgPT4gew0KICAgIGVsLnRleHRDb250ZW50ID0gdGV4dDsNCiAgfSwNCiAgcGFyZW50Tm9kZTogKG5vZGUpID0+IG5vZGUucGFyZW50Tm9kZSwNCiAgbmV4dFNpYmxpbmc6IChub2RlKSA9PiBub2RlLm5leHRTaWJsaW5nLA0KICBxdWVyeVNlbGVjdG9yOiAoc2VsZWN0b3IpID0+IGRvYy5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKSwNCiAgc2V0U2NvcGVJZChlbCwgaWQpIHsNCiAgICBlbC5zZXRBdHRyaWJ1dGUoaWQsICIiKTsNCiAgfSwNCiAgLy8gX19VTlNBRkVfXw0KICAvLyBSZWFzb246IGlubmVySFRNTC4NCiAgLy8gU3RhdGljIGNvbnRlbnQgaGVyZSBjYW4gb25seSBjb21lIGZyb20gY29tcGlsZWQgdGVtcGxhdGVzLg0KICAvLyBBcyBsb25nIGFzIHRoZSB1c2VyIG9ubHkgdXNlcyB0cnVzdGVkIHRlbXBsYXRlcywgdGhpcyBpcyBzYWZlLg0KICBpbnNlcnRTdGF0aWNDb250ZW50KGNvbnRlbnQsIHBhcmVudCwgYW5jaG9yLCBuYW1lc3BhY2UsIHN0YXJ0LCBlbmQpIHsNCiAgICBjb25zdCBiZWZvcmUgPSBhbmNob3IgPyBhbmNob3IucHJldmlvdXNTaWJsaW5nIDogcGFyZW50Lmxhc3RDaGlsZDsNCiAgICBpZiAoc3RhcnQgJiYgKHN0YXJ0ID09PSBlbmQgfHwgc3RhcnQubmV4dFNpYmxpbmcpKSB7DQogICAgICB3aGlsZSAodHJ1ZSkgew0KICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKHN0YXJ0LmNsb25lTm9kZSh0cnVlKSwgYW5jaG9yKTsNCiAgICAgICAgaWYgKHN0YXJ0ID09PSBlbmQgfHwgIShzdGFydCA9IHN0YXJ0Lm5leHRTaWJsaW5nKSkgYnJlYWs7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIHRlbXBsYXRlQ29udGFpbmVyLmlubmVySFRNTCA9IHVuc2FmZVRvVHJ1c3RlZEhUTUwoDQogICAgICAgIG5hbWVzcGFjZSA9PT0gInN2ZyIgPyBgPHN2Zz4ke2NvbnRlbnR9PC9zdmc+YCA6IG5hbWVzcGFjZSA9PT0gIm1hdGhtbCIgPyBgPG1hdGg+JHtjb250ZW50fTwvbWF0aD5gIDogY29udGVudA0KICAgICAgKTsNCiAgICAgIGNvbnN0IHRlbXBsYXRlID0gdGVtcGxhdGVDb250YWluZXIuY29udGVudDsNCiAgICAgIGlmIChuYW1lc3BhY2UgPT09ICJzdmciIHx8IG5hbWVzcGFjZSA9PT0gIm1hdGhtbCIpIHsNCiAgICAgICAgY29uc3Qgd3JhcHBlciA9IHRlbXBsYXRlLmZpcnN0Q2hpbGQ7DQogICAgICAgIHdoaWxlICh3cmFwcGVyLmZpcnN0Q2hpbGQpIHsNCiAgICAgICAgICB0ZW1wbGF0ZS5hcHBlbmRDaGlsZCh3cmFwcGVyLmZpcnN0Q2hpbGQpOw0KICAgICAgICB9DQogICAgICAgIHRlbXBsYXRlLnJlbW92ZUNoaWxkKHdyYXBwZXIpOw0KICAgICAgfQ0KICAgICAgcGFyZW50Lmluc2VydEJlZm9yZSh0ZW1wbGF0ZSwgYW5jaG9yKTsNCiAgICB9DQogICAgcmV0dXJuIFsNCiAgICAgIC8vIGZpcnN0DQogICAgICBiZWZvcmUgPyBiZWZvcmUubmV4dFNpYmxpbmcgOiBwYXJlbnQuZmlyc3RDaGlsZCwNCiAgICAgIC8vIGxhc3QNCiAgICAgIGFuY2hvciA/IGFuY2hvci5wcmV2aW91c1NpYmxpbmcgOiBwYXJlbnQubGFzdENoaWxkDQogICAgXTsNCiAgfQ0KfTsNCg0KY29uc3QgdnRjS2V5ID0gU3ltYm9sKCJfdnRjIik7DQoNCmZ1bmN0aW9uIHBhdGNoQ2xhc3MoZWwsIHZhbHVlLCBpc1NWRykgew0KICBjb25zdCB0cmFuc2l0aW9uQ2xhc3NlcyA9IGVsW3Z0Y0tleV07DQogIGlmICh0cmFuc2l0aW9uQ2xhc3Nlcykgew0KICAgIHZhbHVlID0gKHZhbHVlID8gW3ZhbHVlLCAuLi50cmFuc2l0aW9uQ2xhc3Nlc10gOiBbLi4udHJhbnNpdGlvbkNsYXNzZXNdKS5qb2luKCIgIik7DQogIH0NCiAgaWYgKHZhbHVlID09IG51bGwpIHsNCiAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoImNsYXNzIik7DQogIH0gZWxzZSBpZiAoaXNTVkcpIHsNCiAgICBlbC5zZXRBdHRyaWJ1dGUoImNsYXNzIiwgdmFsdWUpOw0KICB9IGVsc2Ugew0KICAgIGVsLmNsYXNzTmFtZSA9IHZhbHVlOw0KICB9DQp9DQoNCmNvbnN0IHZTaG93T3JpZ2luYWxEaXNwbGF5ID0gU3ltYm9sKCJfdm9kIik7DQpjb25zdCB2U2hvd0hpZGRlbiA9IFN5bWJvbCgiX3ZzaCIpOw0KDQpjb25zdCBDU1NfVkFSX1RFWFQgPSBTeW1ib2woIkNTU19WQVJfVEVYVCIgKTsNCg0KY29uc3QgZGlzcGxheVJFID0gLyhefDspXHMqZGlzcGxheVxzKjovOw0KZnVuY3Rpb24gcGF0Y2hTdHlsZShlbCwgcHJldiwgbmV4dCkgew0KICBjb25zdCBzdHlsZSA9IGVsLnN0eWxlOw0KICBjb25zdCBpc0Nzc1N0cmluZyA9IGlzU3RyaW5nKG5leHQpOw0KICBsZXQgaGFzQ29udHJvbGxlZERpc3BsYXkgPSBmYWxzZTsNCiAgaWYgKG5leHQgJiYgIWlzQ3NzU3RyaW5nKSB7DQogICAgaWYgKHByZXYpIHsNCiAgICAgIGlmICghaXNTdHJpbmcocHJldikpIHsNCiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gcHJldikgew0KICAgICAgICAgIGlmIChuZXh0W2tleV0gPT0gbnVsbCkgew0KICAgICAgICAgICAgc2V0U3R5bGUoc3R5bGUsIGtleSwgIiIpOw0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgZm9yIChjb25zdCBwcmV2U3R5bGUgb2YgcHJldi5zcGxpdCgiOyIpKSB7DQogICAgICAgICAgY29uc3Qga2V5ID0gcHJldlN0eWxlLnNsaWNlKDAsIHByZXZTdHlsZS5pbmRleE9mKCI6IikpLnRyaW0oKTsNCiAgICAgICAgICBpZiAobmV4dFtrZXldID09IG51bGwpIHsNCiAgICAgICAgICAgIHNldFN0eWxlKHN0eWxlLCBrZXksICIiKTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogICAgZm9yIChjb25zdCBrZXkgaW4gbmV4dCkgew0KICAgICAgaWYgKGtleSA9PT0gImRpc3BsYXkiKSB7DQogICAgICAgIGhhc0NvbnRyb2xsZWREaXNwbGF5ID0gdHJ1ZTsNCiAgICAgIH0NCiAgICAgIHNldFN0eWxlKHN0eWxlLCBrZXksIG5leHRba2V5XSk7DQogICAgfQ0KICB9IGVsc2Ugew0KICAgIGlmIChpc0Nzc1N0cmluZykgew0KICAgICAgaWYgKHByZXYgIT09IG5leHQpIHsNCiAgICAgICAgY29uc3QgY3NzVmFyVGV4dCA9IHN0eWxlW0NTU19WQVJfVEVYVF07DQogICAgICAgIGlmIChjc3NWYXJUZXh0KSB7DQogICAgICAgICAgbmV4dCArPSAiOyIgKyBjc3NWYXJUZXh0Ow0KICAgICAgICB9DQogICAgICAgIHN0eWxlLmNzc1RleHQgPSBuZXh0Ow0KICAgICAgICBoYXNDb250cm9sbGVkRGlzcGxheSA9IGRpc3BsYXlSRS50ZXN0KG5leHQpOw0KICAgICAgfQ0KICAgIH0gZWxzZSBpZiAocHJldikgew0KICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKCJzdHlsZSIpOw0KICAgIH0NCiAgfQ0KICBpZiAodlNob3dPcmlnaW5hbERpc3BsYXkgaW4gZWwpIHsNCiAgICBlbFt2U2hvd09yaWdpbmFsRGlzcGxheV0gPSBoYXNDb250cm9sbGVkRGlzcGxheSA/IHN0eWxlLmRpc3BsYXkgOiAiIjsNCiAgICBpZiAoZWxbdlNob3dIaWRkZW5dKSB7DQogICAgICBzdHlsZS5kaXNwbGF5ID0gIm5vbmUiOw0KICAgIH0NCiAgfQ0KfQ0KY29uc3Qgc2VtaWNvbG9uUkUgPSAvW15cXF07XHMqJC87DQpjb25zdCBpbXBvcnRhbnRSRSA9IC9ccyohaW1wb3J0YW50JC87DQpmdW5jdGlvbiBzZXRTdHlsZShzdHlsZSwgbmFtZSwgdmFsKSB7DQogIGlmIChpc0FycmF5KHZhbCkpIHsNCiAgICB2YWwuZm9yRWFjaCgodikgPT4gc2V0U3R5bGUoc3R5bGUsIG5hbWUsIHYpKTsNCiAgfSBlbHNlIHsNCiAgICBpZiAodmFsID09IG51bGwpIHZhbCA9ICIiOw0KICAgIHsNCiAgICAgIGlmIChzZW1pY29sb25SRS50ZXN0KHZhbCkpIHsNCiAgICAgICAgd2FybigNCiAgICAgICAgICBgVW5leHBlY3RlZCBzZW1pY29sb24gYXQgdGhlIGVuZCBvZiAnJHtuYW1lfScgc3R5bGUgdmFsdWU6ICcke3ZhbH0nYA0KICAgICAgICApOw0KICAgICAgfQ0KICAgIH0NCiAgICBpZiAobmFtZS5zdGFydHNXaXRoKCItLSIpKSB7DQogICAgICBzdHlsZS5zZXRQcm9wZXJ0eShuYW1lLCB2YWwpOw0KICAgIH0gZWxzZSB7DQogICAgICBjb25zdCBwcmVmaXhlZCA9IGF1dG9QcmVmaXgoc3R5bGUsIG5hbWUpOw0KICAgICAgaWYgKGltcG9ydGFudFJFLnRlc3QodmFsKSkgew0KICAgICAgICBzdHlsZS5zZXRQcm9wZXJ0eSgNCiAgICAgICAgICBoeXBoZW5hdGUocHJlZml4ZWQpLA0KICAgICAgICAgIHZhbC5yZXBsYWNlKGltcG9ydGFudFJFLCAiIiksDQogICAgICAgICAgImltcG9ydGFudCINCiAgICAgICAgKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHN0eWxlW3ByZWZpeGVkXSA9IHZhbDsNCiAgICAgIH0NCiAgICB9DQogIH0NCn0NCmNvbnN0IHByZWZpeGVzID0gWyJXZWJraXQiLCAiTW96IiwgIm1zIl07DQpjb25zdCBwcmVmaXhDYWNoZSA9IHt9Ow0KZnVuY3Rpb24gYXV0b1ByZWZpeChzdHlsZSwgcmF3TmFtZSkgew0KICBjb25zdCBjYWNoZWQgPSBwcmVmaXhDYWNoZVtyYXdOYW1lXTsNCiAgaWYgKGNhY2hlZCkgew0KICAgIHJldHVybiBjYWNoZWQ7DQogIH0NCiAgbGV0IG5hbWUgPSBjYW1lbGl6ZShyYXdOYW1lKTsNCiAgaWYgKG5hbWUgIT09ICJmaWx0ZXIiICYmIG5hbWUgaW4gc3R5bGUpIHsNCiAgICByZXR1cm4gcHJlZml4Q2FjaGVbcmF3TmFtZV0gPSBuYW1lOw0KICB9DQogIG5hbWUgPSBjYXBpdGFsaXplKG5hbWUpOw0KICBmb3IgKGxldCBpID0gMDsgaSA8IHByZWZpeGVzLmxlbmd0aDsgaSsrKSB7DQogICAgY29uc3QgcHJlZml4ZWQgPSBwcmVmaXhlc1tpXSArIG5hbWU7DQogICAgaWYgKHByZWZpeGVkIGluIHN0eWxlKSB7DQogICAgICByZXR1cm4gcHJlZml4Q2FjaGVbcmF3TmFtZV0gPSBwcmVmaXhlZDsNCiAgICB9DQogIH0NCiAgcmV0dXJuIHJhd05hbWU7DQp9DQoNCmNvbnN0IHhsaW5rTlMgPSAiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI7DQpmdW5jdGlvbiBwYXRjaEF0dHIoZWwsIGtleSwgdmFsdWUsIGlzU1ZHLCBpbnN0YW5jZSwgaXNCb29sZWFuID0gaXNTcGVjaWFsQm9vbGVhbkF0dHIoa2V5KSkgew0KICBpZiAoaXNTVkcgJiYga2V5LnN0YXJ0c1dpdGgoInhsaW5rOiIpKSB7DQogICAgaWYgKHZhbHVlID09IG51bGwpIHsNCiAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZU5TKHhsaW5rTlMsIGtleS5zbGljZSg2LCBrZXkubGVuZ3RoKSk7DQogICAgfSBlbHNlIHsNCiAgICAgIGVsLnNldEF0dHJpYnV0ZU5TKHhsaW5rTlMsIGtleSwgdmFsdWUpOw0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICBpZiAodmFsdWUgPT0gbnVsbCB8fCBpc0Jvb2xlYW4gJiYgIWluY2x1ZGVCb29sZWFuQXR0cih2YWx1ZSkpIHsNCiAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZShrZXkpOw0KICAgIH0gZWxzZSB7DQogICAgICBlbC5zZXRBdHRyaWJ1dGUoDQogICAgICAgIGtleSwNCiAgICAgICAgaXNCb29sZWFuID8gIiIgOiBpc1N5bWJvbCh2YWx1ZSkgPyBTdHJpbmcodmFsdWUpIDogdmFsdWUNCiAgICAgICk7DQogICAgfQ0KICB9DQp9DQoNCmZ1bmN0aW9uIHBhdGNoRE9NUHJvcChlbCwga2V5LCB2YWx1ZSwgcGFyZW50Q29tcG9uZW50LCBhdHRyTmFtZSkgew0KICBpZiAoa2V5ID09PSAiaW5uZXJIVE1MIiB8fCBrZXkgPT09ICJ0ZXh0Q29udGVudCIpIHsNCiAgICBpZiAodmFsdWUgIT0gbnVsbCkgew0KICAgICAgZWxba2V5XSA9IGtleSA9PT0gImlubmVySFRNTCIgPyB1bnNhZmVUb1RydXN0ZWRIVE1MKHZhbHVlKSA6IHZhbHVlOw0KICAgIH0NCiAgICByZXR1cm47DQogIH0NCiAgY29uc3QgdGFnID0gZWwudGFnTmFtZTsNCiAgaWYgKGtleSA9PT0gInZhbHVlIiAmJiB0YWcgIT09ICJQUk9HUkVTUyIgJiYgLy8gY3VzdG9tIGVsZW1lbnRzIG1heSB1c2UgX3ZhbHVlIGludGVybmFsbHkNCiAgIXRhZy5pbmNsdWRlcygiLSIpKSB7DQogICAgY29uc3Qgb2xkVmFsdWUgPSB0YWcgPT09ICJPUFRJT04iID8gZWwuZ2V0QXR0cmlidXRlKCJ2YWx1ZSIpIHx8ICIiIDogZWwudmFsdWU7DQogICAgY29uc3QgbmV3VmFsdWUgPSB2YWx1ZSA9PSBudWxsID8gKA0KICAgICAgLy8gIzExNjQ3OiB2YWx1ZSBzaG91bGQgYmUgc2V0IGFzIGVtcHR5IHN0cmluZyBmb3IgbnVsbCBhbmQgdW5kZWZpbmVkLA0KICAgICAgLy8gYnV0IDxpbnB1dCB0eXBlPSJjaGVja2JveCI+IHNob3VsZCBiZSBzZXQgYXMgJ29uJy4NCiAgICAgIGVsLnR5cGUgPT09ICJjaGVja2JveCIgPyAib24iIDogIiINCiAgICApIDogU3RyaW5nKHZhbHVlKTsNCiAgICBpZiAob2xkVmFsdWUgIT09IG5ld1ZhbHVlIHx8ICEoIl92YWx1ZSIgaW4gZWwpKSB7DQogICAgICBlbC52YWx1ZSA9IG5ld1ZhbHVlOw0KICAgIH0NCiAgICBpZiAodmFsdWUgPT0gbnVsbCkgew0KICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKGtleSk7DQogICAgfQ0KICAgIGVsLl92YWx1ZSA9IHZhbHVlOw0KICAgIHJldHVybjsNCiAgfQ0KICBsZXQgbmVlZFJlbW92ZSA9IGZhbHNlOw0KICBpZiAodmFsdWUgPT09ICIiIHx8IHZhbHVlID09IG51bGwpIHsNCiAgICBjb25zdCB0eXBlID0gdHlwZW9mIGVsW2tleV07DQogICAgaWYgKHR5cGUgPT09ICJib29sZWFuIikgew0KICAgICAgdmFsdWUgPSBpbmNsdWRlQm9vbGVhbkF0dHIodmFsdWUpOw0KICAgIH0gZWxzZSBpZiAodmFsdWUgPT0gbnVsbCAmJiB0eXBlID09PSAic3RyaW5nIikgew0KICAgICAgdmFsdWUgPSAiIjsNCiAgICAgIG5lZWRSZW1vdmUgPSB0cnVlOw0KICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gIm51bWJlciIpIHsNCiAgICAgIHZhbHVlID0gMDsNCiAgICAgIG5lZWRSZW1vdmUgPSB0cnVlOw0KICAgIH0NCiAgfQ0KICB0cnkgew0KICAgIGVsW2tleV0gPSB2YWx1ZTsNCiAgfSBjYXRjaCAoZSkgew0KICAgIGlmICghbmVlZFJlbW92ZSkgew0KICAgICAgd2FybigNCiAgICAgICAgYEZhaWxlZCBzZXR0aW5nIHByb3AgIiR7a2V5fSIgb24gPCR7dGFnLnRvTG93ZXJDYXNlKCl9PjogdmFsdWUgJHt2YWx1ZX0gaXMgaW52YWxpZC5gLA0KICAgICAgICBlDQogICAgICApOw0KICAgIH0NCiAgfQ0KICBuZWVkUmVtb3ZlICYmIGVsLnJlbW92ZUF0dHJpYnV0ZShhdHRyTmFtZSB8fCBrZXkpOw0KfQ0KDQpmdW5jdGlvbiBhZGRFdmVudExpc3RlbmVyKGVsLCBldmVudCwgaGFuZGxlciwgb3B0aW9ucykgew0KICBlbC5hZGRFdmVudExpc3RlbmVyKGV2ZW50LCBoYW5kbGVyLCBvcHRpb25zKTsNCn0NCmZ1bmN0aW9uIHJlbW92ZUV2ZW50TGlzdGVuZXIoZWwsIGV2ZW50LCBoYW5kbGVyLCBvcHRpb25zKSB7DQogIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnQsIGhhbmRsZXIsIG9wdGlvbnMpOw0KfQ0KY29uc3QgdmVpS2V5ID0gU3ltYm9sKCJfdmVpIik7DQpmdW5jdGlvbiBwYXRjaEV2ZW50KGVsLCByYXdOYW1lLCBwcmV2VmFsdWUsIG5leHRWYWx1ZSwgaW5zdGFuY2UgPSBudWxsKSB7DQogIGNvbnN0IGludm9rZXJzID0gZWxbdmVpS2V5XSB8fCAoZWxbdmVpS2V5XSA9IHt9KTsNCiAgY29uc3QgZXhpc3RpbmdJbnZva2VyID0gaW52b2tlcnNbcmF3TmFtZV07DQogIGlmIChuZXh0VmFsdWUgJiYgZXhpc3RpbmdJbnZva2VyKSB7DQogICAgZXhpc3RpbmdJbnZva2VyLnZhbHVlID0gc2FuaXRpemVFdmVudFZhbHVlKG5leHRWYWx1ZSwgcmF3TmFtZSkgOw0KICB9IGVsc2Ugew0KICAgIGNvbnN0IFtuYW1lLCBvcHRpb25zXSA9IHBhcnNlTmFtZShyYXdOYW1lKTsNCiAgICBpZiAobmV4dFZhbHVlKSB7DQogICAgICBjb25zdCBpbnZva2VyID0gaW52b2tlcnNbcmF3TmFtZV0gPSBjcmVhdGVJbnZva2VyKA0KICAgICAgICBzYW5pdGl6ZUV2ZW50VmFsdWUobmV4dFZhbHVlLCByYXdOYW1lKSAsDQogICAgICAgIGluc3RhbmNlDQogICAgICApOw0KICAgICAgYWRkRXZlbnRMaXN0ZW5lcihlbCwgbmFtZSwgaW52b2tlciwgb3B0aW9ucyk7DQogICAgfSBlbHNlIGlmIChleGlzdGluZ0ludm9rZXIpIHsNCiAgICAgIHJlbW92ZUV2ZW50TGlzdGVuZXIoZWwsIG5hbWUsIGV4aXN0aW5nSW52b2tlciwgb3B0aW9ucyk7DQogICAgICBpbnZva2Vyc1tyYXdOYW1lXSA9IHZvaWQgMDsNCiAgICB9DQogIH0NCn0NCmNvbnN0IG9wdGlvbnNNb2RpZmllclJFID0gLyg/Ok9uY2V8UGFzc2l2ZXxDYXB0dXJlKSQvOw0KZnVuY3Rpb24gcGFyc2VOYW1lKG5hbWUpIHsNCiAgbGV0IG9wdGlvbnM7DQogIGlmIChvcHRpb25zTW9kaWZpZXJSRS50ZXN0KG5hbWUpKSB7DQogICAgb3B0aW9ucyA9IHt9Ow0KICAgIGxldCBtOw0KICAgIHdoaWxlIChtID0gbmFtZS5tYXRjaChvcHRpb25zTW9kaWZpZXJSRSkpIHsNCiAgICAgIG5hbWUgPSBuYW1lLnNsaWNlKDAsIG5hbWUubGVuZ3RoIC0gbVswXS5sZW5ndGgpOw0KICAgICAgb3B0aW9uc1ttWzBdLnRvTG93ZXJDYXNlKCldID0gdHJ1ZTsNCiAgICB9DQogIH0NCiAgY29uc3QgZXZlbnQgPSBuYW1lWzJdID09PSAiOiIgPyBuYW1lLnNsaWNlKDMpIDogaHlwaGVuYXRlKG5hbWUuc2xpY2UoMikpOw0KICByZXR1cm4gW2V2ZW50LCBvcHRpb25zXTsNCn0NCmxldCBjYWNoZWROb3cgPSAwOw0KY29uc3QgcCA9IC8qIEBfX1BVUkVfXyAqLyBQcm9taXNlLnJlc29sdmUoKTsNCmNvbnN0IGdldE5vdyA9ICgpID0+IGNhY2hlZE5vdyB8fCAocC50aGVuKCgpID0+IGNhY2hlZE5vdyA9IDApLCBjYWNoZWROb3cgPSBEYXRlLm5vdygpKTsNCmZ1bmN0aW9uIGNyZWF0ZUludm9rZXIoaW5pdGlhbFZhbHVlLCBpbnN0YW5jZSkgew0KICBjb25zdCBpbnZva2VyID0gKGUpID0+IHsNCiAgICBpZiAoIWUuX3Z0cykgew0KICAgICAgZS5fdnRzID0gRGF0ZS5ub3coKTsNCiAgICB9IGVsc2UgaWYgKGUuX3Z0cyA8PSBpbnZva2VyLmF0dGFjaGVkKSB7DQogICAgICByZXR1cm47DQogICAgfQ0KICAgIGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nKA0KICAgICAgcGF0Y2hTdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oZSwgaW52b2tlci52YWx1ZSksDQogICAgICBpbnN0YW5jZSwNCiAgICAgIDUsDQogICAgICBbZV0NCiAgICApOw0KICB9Ow0KICBpbnZva2VyLnZhbHVlID0gaW5pdGlhbFZhbHVlOw0KICBpbnZva2VyLmF0dGFjaGVkID0gZ2V0Tm93KCk7DQogIHJldHVybiBpbnZva2VyOw0KfQ0KZnVuY3Rpb24gc2FuaXRpemVFdmVudFZhbHVlKHZhbHVlLCBwcm9wTmFtZSkgew0KICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkgfHwgaXNBcnJheSh2YWx1ZSkpIHsNCiAgICByZXR1cm4gdmFsdWU7DQogIH0NCiAgd2FybigNCiAgICBgV3JvbmcgdHlwZSBwYXNzZWQgYXMgZXZlbnQgaGFuZGxlciB0byAke3Byb3BOYW1lfSAtIGRpZCB5b3UgZm9yZ2V0IEAgb3IgOiBpbiBmcm9udCBvZiB5b3VyIHByb3A/DQpFeHBlY3RlZCBmdW5jdGlvbiBvciBhcnJheSBvZiBmdW5jdGlvbnMsIHJlY2VpdmVkIHR5cGUgJHt0eXBlb2YgdmFsdWV9LmANCiAgKTsNCiAgcmV0dXJuIE5PT1A7DQp9DQpmdW5jdGlvbiBwYXRjaFN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbihlLCB2YWx1ZSkgew0KICBpZiAoaXNBcnJheSh2YWx1ZSkpIHsNCiAgICBjb25zdCBvcmlnaW5hbFN0b3AgPSBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbjsNCiAgICBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiA9ICgpID0+IHsNCiAgICAgIG9yaWdpbmFsU3RvcC5jYWxsKGUpOw0KICAgICAgZS5fc3RvcHBlZCA9IHRydWU7DQogICAgfTsNCiAgICByZXR1cm4gdmFsdWUubWFwKA0KICAgICAgKGZuKSA9PiAoZTIpID0+ICFlMi5fc3RvcHBlZCAmJiBmbiAmJiBmbihlMikNCiAgICApOw0KICB9IGVsc2Ugew0KICAgIHJldHVybiB2YWx1ZTsNCiAgfQ0KfQ0KDQpjb25zdCBpc05hdGl2ZU9uID0gKGtleSkgPT4ga2V5LmNoYXJDb2RlQXQoMCkgPT09IDExMSAmJiBrZXkuY2hhckNvZGVBdCgxKSA9PT0gMTEwICYmIC8vIGxvd2VyY2FzZSBsZXR0ZXINCmtleS5jaGFyQ29kZUF0KDIpID4gOTYgJiYga2V5LmNoYXJDb2RlQXQoMikgPCAxMjM7DQpjb25zdCBwYXRjaFByb3AgPSAoZWwsIGtleSwgcHJldlZhbHVlLCBuZXh0VmFsdWUsIG5hbWVzcGFjZSwgcGFyZW50Q29tcG9uZW50KSA9PiB7DQogIGNvbnN0IGlzU1ZHID0gbmFtZXNwYWNlID09PSAic3ZnIjsNCiAgaWYgKGtleSA9PT0gImNsYXNzIikgew0KICAgIHBhdGNoQ2xhc3MoZWwsIG5leHRWYWx1ZSwgaXNTVkcpOw0KICB9IGVsc2UgaWYgKGtleSA9PT0gInN0eWxlIikgew0KICAgIHBhdGNoU3R5bGUoZWwsIHByZXZWYWx1ZSwgbmV4dFZhbHVlKTsNCiAgfSBlbHNlIGlmIChpc09uKGtleSkpIHsNCiAgICBpZiAoIWlzTW9kZWxMaXN0ZW5lcihrZXkpKSB7DQogICAgICBwYXRjaEV2ZW50KGVsLCBrZXksIHByZXZWYWx1ZSwgbmV4dFZhbHVlLCBwYXJlbnRDb21wb25lbnQpOw0KICAgIH0NCiAgfSBlbHNlIGlmIChrZXlbMF0gPT09ICIuIiA/IChrZXkgPSBrZXkuc2xpY2UoMSksIHRydWUpIDoga2V5WzBdID09PSAiXiIgPyAoa2V5ID0ga2V5LnNsaWNlKDEpLCBmYWxzZSkgOiBzaG91bGRTZXRBc1Byb3AoZWwsIGtleSwgbmV4dFZhbHVlLCBpc1NWRykpIHsNCiAgICBwYXRjaERPTVByb3AoZWwsIGtleSwgbmV4dFZhbHVlKTsNCiAgICBpZiAoIWVsLnRhZ05hbWUuaW5jbHVkZXMoIi0iKSAmJiAoa2V5ID09PSAidmFsdWUiIHx8IGtleSA9PT0gImNoZWNrZWQiIHx8IGtleSA9PT0gInNlbGVjdGVkIikpIHsNCiAgICAgIHBhdGNoQXR0cihlbCwga2V5LCBuZXh0VmFsdWUsIGlzU1ZHLCBwYXJlbnRDb21wb25lbnQsIGtleSAhPT0gInZhbHVlIik7DQogICAgfQ0KICB9IGVsc2UgaWYgKA0KICAgIC8vICMxMTA4MSBmb3JjZSBzZXQgcHJvcHMgZm9yIHBvc3NpYmxlIGFzeW5jIGN1c3RvbSBlbGVtZW50DQogICAgZWwuX2lzVnVlQ0UgJiYgKC9bQS1aXS8udGVzdChrZXkpIHx8ICFpc1N0cmluZyhuZXh0VmFsdWUpKQ0KICApIHsNCiAgICBwYXRjaERPTVByb3AoZWwsIGNhbWVsaXplKGtleSksIG5leHRWYWx1ZSwgcGFyZW50Q29tcG9uZW50LCBrZXkpOw0KICB9IGVsc2Ugew0KICAgIGlmIChrZXkgPT09ICJ0cnVlLXZhbHVlIikgew0KICAgICAgZWwuX3RydWVWYWx1ZSA9IG5leHRWYWx1ZTsNCiAgICB9IGVsc2UgaWYgKGtleSA9PT0gImZhbHNlLXZhbHVlIikgew0KICAgICAgZWwuX2ZhbHNlVmFsdWUgPSBuZXh0VmFsdWU7DQogICAgfQ0KICAgIHBhdGNoQXR0cihlbCwga2V5LCBuZXh0VmFsdWUsIGlzU1ZHKTsNCiAgfQ0KfTsNCmZ1bmN0aW9uIHNob3VsZFNldEFzUHJvcChlbCwga2V5LCB2YWx1ZSwgaXNTVkcpIHsNCiAgaWYgKGlzU1ZHKSB7DQogICAgaWYgKGtleSA9PT0gImlubmVySFRNTCIgfHwga2V5ID09PSAidGV4dENvbnRlbnQiKSB7DQogICAgICByZXR1cm4gdHJ1ZTsNCiAgICB9DQogICAgaWYgKGtleSBpbiBlbCAmJiBpc05hdGl2ZU9uKGtleSkgJiYgaXNGdW5jdGlvbih2YWx1ZSkpIHsNCiAgICAgIHJldHVybiB0cnVlOw0KICAgIH0NCiAgICByZXR1cm4gZmFsc2U7DQogIH0NCiAgaWYgKGtleSA9PT0gInNwZWxsY2hlY2siIHx8IGtleSA9PT0gImRyYWdnYWJsZSIgfHwga2V5ID09PSAidHJhbnNsYXRlIiB8fCBrZXkgPT09ICJhdXRvY29ycmVjdCIpIHsNCiAgICByZXR1cm4gZmFsc2U7DQogIH0NCiAgaWYgKGtleSA9PT0gImZvcm0iKSB7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9DQogIGlmIChrZXkgPT09ICJsaXN0IiAmJiBlbC50YWdOYW1lID09PSAiSU5QVVQiKSB7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9DQogIGlmIChrZXkgPT09ICJ0eXBlIiAmJiBlbC50YWdOYW1lID09PSAiVEVYVEFSRUEiKSB7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9DQogIGlmIChrZXkgPT09ICJ3aWR0aCIgfHwga2V5ID09PSAiaGVpZ2h0Iikgew0KICAgIGNvbnN0IHRhZyA9IGVsLnRhZ05hbWU7DQogICAgaWYgKHRhZyA9PT0gIklNRyIgfHwgdGFnID09PSAiVklERU8iIHx8IHRhZyA9PT0gIkNBTlZBUyIgfHwgdGFnID09PSAiU09VUkNFIikgew0KICAgICAgcmV0dXJuIGZhbHNlOw0KICAgIH0NCiAgfQ0KICBpZiAoaXNOYXRpdmVPbihrZXkpICYmIGlzU3RyaW5nKHZhbHVlKSkgew0KICAgIHJldHVybiBmYWxzZTsNCiAgfQ0KICByZXR1cm4ga2V5IGluIGVsOw0KfQ0KDQpjb25zdCB2TW9kZWxUZXh0ID0gew0KICB9Ow0KY29uc3Qgdk1vZGVsQ2hlY2tib3ggPSB7DQogIH07DQpjb25zdCB2TW9kZWxSYWRpbyA9IHsNCiAgfTsNCmZ1bmN0aW9uIGluaXRWTW9kZWxGb3JTU1IoKSB7DQogIHZNb2RlbFRleHQuZ2V0U1NSUHJvcHMgPSAoeyB2YWx1ZSB9KSA9PiAoeyB2YWx1ZSB9KTsNCiAgdk1vZGVsUmFkaW8uZ2V0U1NSUHJvcHMgPSAoeyB2YWx1ZSB9LCB2bm9kZSkgPT4gew0KICAgIGlmICh2bm9kZS5wcm9wcyAmJiBsb29zZUVxdWFsKHZub2RlLnByb3BzLnZhbHVlLCB2YWx1ZSkpIHsNCiAgICAgIHJldHVybiB7IGNoZWNrZWQ6IHRydWUgfTsNCiAgICB9DQogIH07DQogIHZNb2RlbENoZWNrYm94LmdldFNTUlByb3BzID0gKHsgdmFsdWUgfSwgdm5vZGUpID0+IHsNCiAgICBpZiAoaXNBcnJheSh2YWx1ZSkpIHsNCiAgICAgIGlmICh2bm9kZS5wcm9wcyAmJiBsb29zZUluZGV4T2YodmFsdWUsIHZub2RlLnByb3BzLnZhbHVlKSA+IC0xKSB7DQogICAgICAgIHJldHVybiB7IGNoZWNrZWQ6IHRydWUgfTsNCiAgICAgIH0NCiAgICB9IGVsc2UgaWYgKGlzU2V0KHZhbHVlKSkgew0KICAgICAgaWYgKHZub2RlLnByb3BzICYmIHZhbHVlLmhhcyh2bm9kZS5wcm9wcy52YWx1ZSkpIHsNCiAgICAgICAgcmV0dXJuIHsgY2hlY2tlZDogdHJ1ZSB9Ow0KICAgICAgfQ0KICAgIH0gZWxzZSBpZiAodmFsdWUpIHsNCiAgICAgIHJldHVybiB7IGNoZWNrZWQ6IHRydWUgfTsNCiAgICB9DQogIH07DQp9DQoNCmNvbnN0IHJlbmRlcmVyT3B0aW9ucyA9IC8qIEBfX1BVUkVfXyAqLyBleHRlbmQoeyBwYXRjaFByb3AgfSwgbm9kZU9wcyk7DQpsZXQgcmVuZGVyZXI7DQpmdW5jdGlvbiBlbnN1cmVSZW5kZXJlcigpIHsNCiAgcmV0dXJuIHJlbmRlcmVyIHx8IChyZW5kZXJlciA9IGNyZWF0ZVJlbmRlcmVyKHJlbmRlcmVyT3B0aW9ucykpOw0KfQ0KY29uc3QgY3JlYXRlQXBwID0gKC4uLmFyZ3MpID0+IHsNCiAgY29uc3QgYXBwID0gZW5zdXJlUmVuZGVyZXIoKS5jcmVhdGVBcHAoLi4uYXJncyk7DQogIHsNCiAgICBpbmplY3ROYXRpdmVUYWdDaGVjayhhcHApOw0KICAgIGluamVjdENvbXBpbGVyT3B0aW9uc0NoZWNrKGFwcCk7DQogIH0NCiAgY29uc3QgeyBtb3VudCB9ID0gYXBwOw0KICBhcHAubW91bnQgPSAoY29udGFpbmVyT3JTZWxlY3RvcikgPT4gew0KICAgIGNvbnN0IGNvbnRhaW5lciA9IG5vcm1hbGl6ZUNvbnRhaW5lcihjb250YWluZXJPclNlbGVjdG9yKTsNCiAgICBpZiAoIWNvbnRhaW5lcikgcmV0dXJuOw0KICAgIGNvbnN0IGNvbXBvbmVudCA9IGFwcC5fY29tcG9uZW50Ow0KICAgIGlmICghaXNGdW5jdGlvbihjb21wb25lbnQpICYmICFjb21wb25lbnQucmVuZGVyICYmICFjb21wb25lbnQudGVtcGxhdGUpIHsNCiAgICAgIGNvbXBvbmVudC50ZW1wbGF0ZSA9IGNvbnRhaW5lci5pbm5lckhUTUw7DQogICAgfQ0KICAgIGlmIChjb250YWluZXIubm9kZVR5cGUgPT09IDEpIHsNCiAgICAgIGNvbnRhaW5lci50ZXh0Q29udGVudCA9ICIiOw0KICAgIH0NCiAgICBjb25zdCBwcm94eSA9IG1vdW50KGNvbnRhaW5lciwgZmFsc2UsIHJlc29sdmVSb290TmFtZXNwYWNlKGNvbnRhaW5lcikpOw0KICAgIGlmIChjb250YWluZXIgaW5zdGFuY2VvZiBFbGVtZW50KSB7DQogICAgICBjb250YWluZXIucmVtb3ZlQXR0cmlidXRlKCJ2LWNsb2FrIik7DQogICAgICBjb250YWluZXIuc2V0QXR0cmlidXRlKCJkYXRhLXYtYXBwIiwgIiIpOw0KICAgIH0NCiAgICByZXR1cm4gcHJveHk7DQogIH07DQogIHJldHVybiBhcHA7DQp9Ow0KZnVuY3Rpb24gcmVzb2x2ZVJvb3ROYW1lc3BhY2UoY29udGFpbmVyKSB7DQogIGlmIChjb250YWluZXIgaW5zdGFuY2VvZiBTVkdFbGVtZW50KSB7DQogICAgcmV0dXJuICJzdmciOw0KICB9DQogIGlmICh0eXBlb2YgTWF0aE1MRWxlbWVudCA9PT0gImZ1bmN0aW9uIiAmJiBjb250YWluZXIgaW5zdGFuY2VvZiBNYXRoTUxFbGVtZW50KSB7DQogICAgcmV0dXJuICJtYXRobWwiOw0KICB9DQp9DQpmdW5jdGlvbiBpbmplY3ROYXRpdmVUYWdDaGVjayhhcHApIHsNCiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGFwcC5jb25maWcsICJpc05hdGl2ZVRhZyIsIHsNCiAgICB2YWx1ZTogKHRhZykgPT4gaXNIVE1MVGFnKHRhZykgfHwgaXNTVkdUYWcodGFnKSB8fCBpc01hdGhNTFRhZyh0YWcpLA0KICAgIHdyaXRhYmxlOiBmYWxzZQ0KICB9KTsNCn0NCmZ1bmN0aW9uIGluamVjdENvbXBpbGVyT3B0aW9uc0NoZWNrKGFwcCkgew0KICB7DQogICAgY29uc3QgaXNDdXN0b21FbGVtZW50ID0gYXBwLmNvbmZpZy5pc0N1c3RvbUVsZW1lbnQ7DQogICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGFwcC5jb25maWcsICJpc0N1c3RvbUVsZW1lbnQiLCB7DQogICAgICBnZXQoKSB7DQogICAgICAgIHJldHVybiBpc0N1c3RvbUVsZW1lbnQ7DQogICAgICB9LA0KICAgICAgc2V0KCkgew0KICAgICAgICB3YXJuKA0KICAgICAgICAgIGBUaGUgXGBpc0N1c3RvbUVsZW1lbnRcYCBjb25maWcgb3B0aW9uIGlzIGRlcHJlY2F0ZWQuIFVzZSBcYGNvbXBpbGVyT3B0aW9ucy5pc0N1c3RvbUVsZW1lbnRcYCBpbnN0ZWFkLmANCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICB9KTsNCiAgICBjb25zdCBjb21waWxlck9wdGlvbnMgPSBhcHAuY29uZmlnLmNvbXBpbGVyT3B0aW9uczsNCiAgICBjb25zdCBtc2cgPSBgVGhlIFxgY29tcGlsZXJPcHRpb25zXGAgY29uZmlnIG9wdGlvbiBpcyBvbmx5IHJlc3BlY3RlZCB3aGVuIHVzaW5nIGEgYnVpbGQgb2YgVnVlLmpzIHRoYXQgaW5jbHVkZXMgdGhlIHJ1bnRpbWUgY29tcGlsZXIgKGFrYSAiZnVsbCBidWlsZCIpLiBTaW5jZSB5b3UgYXJlIHVzaW5nIHRoZSBydW50aW1lLW9ubHkgYnVpbGQsIFxgY29tcGlsZXJPcHRpb25zXGAgbXVzdCBiZSBwYXNzZWQgdG8gXGBAdnVlL2NvbXBpbGVyLWRvbVxgIGluIHRoZSBidWlsZCBzZXR1cCBpbnN0ZWFkLg0KLSBGb3IgdnVlLWxvYWRlcjogcGFzcyBpdCB2aWEgdnVlLWxvYWRlcidzIFxgY29tcGlsZXJPcHRpb25zXGAgbG9hZGVyIG9wdGlvbi4NCi0gRm9yIHZ1ZS1jbGk6IHNlZSBodHRwczovL2NsaS52dWVqcy5vcmcvZ3VpZGUvd2VicGFjay5odG1sI21vZGlmeWluZy1vcHRpb25zLW9mLWEtbG9hZGVyDQotIEZvciB2aXRlOiBwYXNzIGl0IHZpYSBAdml0ZWpzL3BsdWdpbi12dWUgb3B0aW9ucy4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS92aXRlanMvdml0ZS1wbHVnaW4tdnVlL3RyZWUvbWFpbi9wYWNrYWdlcy9wbHVnaW4tdnVlI2V4YW1wbGUtZm9yLXBhc3Npbmctb3B0aW9ucy10by12dWVjb21waWxlci1zZmNgOw0KICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhcHAuY29uZmlnLCAiY29tcGlsZXJPcHRpb25zIiwgew0KICAgICAgZ2V0KCkgew0KICAgICAgICB3YXJuKG1zZyk7DQogICAgICAgIHJldHVybiBjb21waWxlck9wdGlvbnM7DQogICAgICB9LA0KICAgICAgc2V0KCkgew0KICAgICAgICB3YXJuKG1zZyk7DQogICAgICB9DQogICAgfSk7DQogIH0NCn0NCmZ1bmN0aW9uIG5vcm1hbGl6ZUNvbnRhaW5lcihjb250YWluZXIpIHsNCiAgaWYgKGlzU3RyaW5nKGNvbnRhaW5lcikpIHsNCiAgICBjb25zdCByZXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGNvbnRhaW5lcik7DQogICAgaWYgKCFyZXMpIHsNCiAgICAgIHdhcm4oDQogICAgICAgIGBGYWlsZWQgdG8gbW91bnQgYXBwOiBtb3VudCB0YXJnZXQgc2VsZWN0b3IgIiR7Y29udGFpbmVyfSIgcmV0dXJuZWQgbnVsbC5gDQogICAgICApOw0KICAgIH0NCiAgICByZXR1cm4gcmVzOw0KICB9DQogIGlmICh3aW5kb3cuU2hhZG93Um9vdCAmJiBjb250YWluZXIgaW5zdGFuY2VvZiB3aW5kb3cuU2hhZG93Um9vdCAmJiBjb250YWluZXIubW9kZSA9PT0gImNsb3NlZCIpIHsNCiAgICB3YXJuKA0KICAgICAgYG1vdW50aW5nIG9uIGEgU2hhZG93Um9vdCB3aXRoIFxge21vZGU6ICJjbG9zZWQifVxgIG1heSBsZWFkIHRvIHVucHJlZGljdGFibGUgYnVnc2ANCiAgICApOw0KICB9DQogIHJldHVybiBjb250YWluZXI7DQp9DQpsZXQgc3NyRGlyZWN0aXZlSW5pdGlhbGl6ZWQgPSBmYWxzZTsNCmNvbnN0IGluaXREaXJlY3RpdmVzRm9yU1NSID0gKCkgPT4gew0KICBpZiAoIXNzckRpcmVjdGl2ZUluaXRpYWxpemVkKSB7DQogICAgc3NyRGlyZWN0aXZlSW5pdGlhbGl6ZWQgPSB0cnVlOw0KICAgIGluaXRWTW9kZWxGb3JTU1IoKTsNCiAgfQ0KfSA7DQoNCmNvbnN0IHNob3VsZElnbm9yZVByb3AgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcCgNCiAgYCxrZXkscmVmLGlubmVySFRNTCx0ZXh0Q29udGVudCxyZWZfa2V5LHJlZl9mb3JgDQopOw0KZnVuY3Rpb24gc3NyUmVuZGVyQXR0cnMocHJvcHMsIHRhZykgew0KICBsZXQgcmV0ID0gIiI7DQogIGZvciAoY29uc3Qga2V5IGluIHByb3BzKSB7DQogICAgaWYgKHNob3VsZElnbm9yZVByb3Aoa2V5KSB8fCBpc09uKGtleSkgfHwgdGFnID09PSAidGV4dGFyZWEiICYmIGtleSA9PT0gInZhbHVlIikgew0KICAgICAgY29udGludWU7DQogICAgfQ0KICAgIGNvbnN0IHZhbHVlID0gcHJvcHNba2V5XTsNCiAgICBpZiAoa2V5ID09PSAiY2xhc3MiKSB7DQogICAgICByZXQgKz0gYCBjbGFzcz0iJHtzc3JSZW5kZXJDbGFzcyh2YWx1ZSl9ImA7DQogICAgfSBlbHNlIGlmIChrZXkgPT09ICJzdHlsZSIpIHsNCiAgICAgIHJldCArPSBgIHN0eWxlPSIke3NzclJlbmRlclN0eWxlKHZhbHVlKX0iYDsNCiAgICB9IGVsc2UgaWYgKGtleSA9PT0gImNsYXNzTmFtZSIpIHsNCiAgICAgIHJldCArPSBgIGNsYXNzPSIke1N0cmluZyh2YWx1ZSl9ImA7DQogICAgfSBlbHNlIHsNCiAgICAgIHJldCArPSBzc3JSZW5kZXJEeW5hbWljQXR0cihrZXksIHZhbHVlLCB0YWcpOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gcmV0Ow0KfQ0KZnVuY3Rpb24gc3NyUmVuZGVyRHluYW1pY0F0dHIoa2V5LCB2YWx1ZSwgdGFnKSB7DQogIGlmICghaXNSZW5kZXJhYmxlQXR0clZhbHVlKHZhbHVlKSkgew0KICAgIHJldHVybiBgYDsNCiAgfQ0KICBjb25zdCBhdHRyS2V5ID0gdGFnICYmICh0YWcuaW5kZXhPZigiLSIpID4gMCB8fCBpc1NWR1RhZyh0YWcpKSA/IGtleSA6IHByb3BzVG9BdHRyTWFwW2tleV0gfHwga2V5LnRvTG93ZXJDYXNlKCk7DQogIGlmIChpc0Jvb2xlYW5BdHRyKGF0dHJLZXkpKSB7DQogICAgcmV0dXJuIGluY2x1ZGVCb29sZWFuQXR0cih2YWx1ZSkgPyBgICR7YXR0cktleX1gIDogYGA7DQogIH0gZWxzZSBpZiAoaXNTU1JTYWZlQXR0ck5hbWUoYXR0cktleSkpIHsNCiAgICByZXR1cm4gdmFsdWUgPT09ICIiID8gYCAke2F0dHJLZXl9YCA6IGAgJHthdHRyS2V5fT0iJHtlc2NhcGVIdG1sKHZhbHVlKX0iYDsNCiAgfSBlbHNlIHsNCiAgICBjb25zb2xlLndhcm4oDQogICAgICBgW0B2dWUvc2VydmVyLXJlbmRlcmVyXSBTa2lwcGVkIHJlbmRlcmluZyB1bnNhZmUgYXR0cmlidXRlIG5hbWU6ICR7YXR0cktleX1gDQogICAgKTsNCiAgICByZXR1cm4gYGA7DQogIH0NCn0NCmZ1bmN0aW9uIHNzclJlbmRlckF0dHIoa2V5LCB2YWx1ZSkgew0KICBpZiAoIWlzUmVuZGVyYWJsZUF0dHJWYWx1ZSh2YWx1ZSkpIHsNCiAgICByZXR1cm4gYGA7DQogIH0NCiAgcmV0dXJuIGAgJHtrZXl9PSIke2VzY2FwZUh0bWwodmFsdWUpfSJgOw0KfQ0KZnVuY3Rpb24gc3NyUmVuZGVyQ2xhc3MocmF3KSB7DQogIHJldHVybiBlc2NhcGVIdG1sKG5vcm1hbGl6ZUNsYXNzKHJhdykpOw0KfQ0KZnVuY3Rpb24gc3NyUmVuZGVyU3R5bGUocmF3KSB7DQogIGlmICghcmF3KSB7DQogICAgcmV0dXJuICIiOw0KICB9DQogIGlmIChpc1N0cmluZyhyYXcpKSB7DQogICAgcmV0dXJuIGVzY2FwZUh0bWwocmF3KTsNCiAgfQ0KICBjb25zdCBzdHlsZXMgPSBub3JtYWxpemVTdHlsZShyYXcpOw0KICByZXR1cm4gZXNjYXBlSHRtbChzdHJpbmdpZnlTdHlsZShzdHlsZXMpKTsNCn0NCg0KZnVuY3Rpb24gc3NyUmVuZGVyQ29tcG9uZW50KGNvbXAsIHByb3BzID0gbnVsbCwgY2hpbGRyZW4gPSBudWxsLCBwYXJlbnRDb21wb25lbnQgPSBudWxsLCBzbG90U2NvcGVJZCkgew0KICByZXR1cm4gcmVuZGVyQ29tcG9uZW50Vk5vZGUoDQogICAgY3JlYXRlVk5vZGUoY29tcCwgcHJvcHMsIGNoaWxkcmVuKSwNCiAgICBwYXJlbnRDb21wb25lbnQsDQogICAgc2xvdFNjb3BlSWQNCiAgKTsNCn0NCg0KY29uc3QgeyBlbnN1cmVWYWxpZFZOb2RlIH0gPSBzc3JVdGlsczsNCmZ1bmN0aW9uIHNzclJlbmRlclNsb3Qoc2xvdHMsIHNsb3ROYW1lLCBzbG90UHJvcHMsIGZhbGxiYWNrUmVuZGVyRm4sIHB1c2gsIHBhcmVudENvbXBvbmVudCwgc2xvdFNjb3BlSWQpIHsNCiAgcHVzaChgPCEtLVstLT5gKTsNCiAgc3NyUmVuZGVyU2xvdElubmVyKA0KICAgIHNsb3RzLA0KICAgIHNsb3ROYW1lLA0KICAgIHNsb3RQcm9wcywNCiAgICBmYWxsYmFja1JlbmRlckZuLA0KICAgIHB1c2gsDQogICAgcGFyZW50Q29tcG9uZW50LA0KICAgIHNsb3RTY29wZUlkDQogICk7DQogIHB1c2goYDwhLS1dLS0+YCk7DQp9DQpmdW5jdGlvbiBzc3JSZW5kZXJTbG90SW5uZXIoc2xvdHMsIHNsb3ROYW1lLCBzbG90UHJvcHMsIGZhbGxiYWNrUmVuZGVyRm4sIHB1c2gsIHBhcmVudENvbXBvbmVudCwgc2xvdFNjb3BlSWQsIHRyYW5zaXRpb24pIHsNCiAgY29uc3Qgc2xvdEZuID0gc2xvdHNbc2xvdE5hbWVdOw0KICBpZiAoc2xvdEZuKSB7DQogICAgY29uc3Qgc2xvdEJ1ZmZlciA9IFtdOw0KICAgIGNvbnN0IGJ1ZmZlcmVkUHVzaCA9IChpdGVtKSA9PiB7DQogICAgICBzbG90QnVmZmVyLnB1c2goaXRlbSk7DQogICAgfTsNCiAgICBjb25zdCByZXQgPSBzbG90Rm4oDQogICAgICBzbG90UHJvcHMsDQogICAgICBidWZmZXJlZFB1c2gsDQogICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICBzbG90U2NvcGVJZCA/ICIgIiArIHNsb3RTY29wZUlkIDogIiINCiAgICApOw0KICAgIGlmIChpc0FycmF5KHJldCkpIHsNCiAgICAgIGNvbnN0IHZhbGlkU2xvdENvbnRlbnQgPSBlbnN1cmVWYWxpZFZOb2RlKHJldCk7DQogICAgICBpZiAodmFsaWRTbG90Q29udGVudCkgew0KICAgICAgICByZW5kZXJWTm9kZUNoaWxkcmVuKA0KICAgICAgICAgIHB1c2gsDQogICAgICAgICAgdmFsaWRTbG90Q29udGVudCwNCiAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgc2xvdFNjb3BlSWQNCiAgICAgICAgKTsNCiAgICAgIH0gZWxzZSBpZiAoZmFsbGJhY2tSZW5kZXJGbikgew0KICAgICAgICBmYWxsYmFja1JlbmRlckZuKCk7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIGxldCBpc0VtcHR5U2xvdCA9IHRydWU7DQogICAgICBpZiAodHJhbnNpdGlvbikgew0KICAgICAgICBpc0VtcHR5U2xvdCA9IGZhbHNlOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbG90QnVmZmVyLmxlbmd0aDsgaSsrKSB7DQogICAgICAgICAgaWYgKCFpc0NvbW1lbnQoc2xvdEJ1ZmZlcltpXSkpIHsNCiAgICAgICAgICAgIGlzRW1wdHlTbG90ID0gZmFsc2U7DQogICAgICAgICAgICBicmVhazsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGlmIChpc0VtcHR5U2xvdCkgew0KICAgICAgICBpZiAoZmFsbGJhY2tSZW5kZXJGbikgew0KICAgICAgICAgIGZhbGxiYWNrUmVuZGVyRm4oKTsNCiAgICAgICAgfQ0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgbGV0IHN0YXJ0ID0gMDsNCiAgICAgICAgbGV0IGVuZCA9IHNsb3RCdWZmZXIubGVuZ3RoOw0KICAgICAgICBpZiAodHJhbnNpdGlvbiAmJiBzbG90QnVmZmVyWzBdID09PSAiPCEtLVstLT4iICYmIHNsb3RCdWZmZXJbZW5kIC0gMV0gPT09ICI8IS0tXS0tPiIpIHsNCiAgICAgICAgICBzdGFydCsrOw0KICAgICAgICAgIGVuZC0tOw0KICAgICAgICB9DQogICAgICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7DQogICAgICAgICAgcHVzaChzbG90QnVmZmVyW2ldKTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgfSBlbHNlIGlmIChmYWxsYmFja1JlbmRlckZuKSB7DQogICAgZmFsbGJhY2tSZW5kZXJGbigpOw0KICB9DQp9DQpjb25zdCBjb21tZW50VGVzdFJFID0gL148IS0tW1xzXFNdKi0tPiQvOw0KY29uc3QgY29tbWVudFJFID0gLzwhLS1bXl0qPy0tPi9nbTsNCmZ1bmN0aW9uIGlzQ29tbWVudChpdGVtKSB7DQogIGlmICh0eXBlb2YgaXRlbSAhPT0gInN0cmluZyIgfHwgIWNvbW1lbnRUZXN0UkUudGVzdChpdGVtKSkgcmV0dXJuIGZhbHNlOw0KICBpZiAoaXRlbS5sZW5ndGggPD0gOCkgcmV0dXJuIHRydWU7DQogIHJldHVybiAhaXRlbS5yZXBsYWNlKGNvbW1lbnRSRSwgIiIpLnRyaW0oKTsNCn0NCg0KZnVuY3Rpb24gc3NyUmVuZGVyVGVsZXBvcnQocGFyZW50UHVzaCwgY29udGVudFJlbmRlckZuLCB0YXJnZXQsIGRpc2FibGVkLCBwYXJlbnRDb21wb25lbnQpIHsNCiAgcGFyZW50UHVzaCgiPCEtLXRlbGVwb3J0IHN0YXJ0LS0+Iik7DQogIGNvbnN0IGNvbnRleHQgPSBwYXJlbnRDb21wb25lbnQuYXBwQ29udGV4dC5wcm92aWRlc1tzc3JDb250ZXh0S2V5XTsNCiAgY29uc3QgdGVsZXBvcnRCdWZmZXJzID0gY29udGV4dC5fX3RlbGVwb3J0QnVmZmVycyB8fCAoY29udGV4dC5fX3RlbGVwb3J0QnVmZmVycyA9IHt9KTsNCiAgY29uc3QgdGFyZ2V0QnVmZmVyID0gdGVsZXBvcnRCdWZmZXJzW3RhcmdldF0gfHwgKHRlbGVwb3J0QnVmZmVyc1t0YXJnZXRdID0gW10pOw0KICBjb25zdCBidWZmZXJJbmRleCA9IHRhcmdldEJ1ZmZlci5sZW5ndGg7DQogIGxldCB0ZWxlcG9ydENvbnRlbnQ7DQogIGlmIChkaXNhYmxlZCkgew0KICAgIGNvbnRlbnRSZW5kZXJGbihwYXJlbnRQdXNoKTsNCiAgICB0ZWxlcG9ydENvbnRlbnQgPSBgPCEtLXRlbGVwb3J0IHN0YXJ0IGFuY2hvci0tPjwhLS10ZWxlcG9ydCBhbmNob3ItLT5gOw0KICB9IGVsc2Ugew0KICAgIGNvbnN0IHsgZ2V0QnVmZmVyLCBwdXNoIH0gPSBjcmVhdGVCdWZmZXIoKTsNCiAgICBwdXNoKGA8IS0tdGVsZXBvcnQgc3RhcnQgYW5jaG9yLS0+YCk7DQogICAgY29udGVudFJlbmRlckZuKHB1c2gpOw0KICAgIHB1c2goYDwhLS10ZWxlcG9ydCBhbmNob3ItLT5gKTsNCiAgICB0ZWxlcG9ydENvbnRlbnQgPSBnZXRCdWZmZXIoKTsNCiAgfQ0KICB0YXJnZXRCdWZmZXIuc3BsaWNlKGJ1ZmZlckluZGV4LCAwLCB0ZWxlcG9ydENvbnRlbnQpOw0KICBwYXJlbnRQdXNoKCI8IS0tdGVsZXBvcnQgZW5kLS0+Iik7DQp9DQoNCmZ1bmN0aW9uIHNzckludGVycG9sYXRlKHZhbHVlKSB7DQogIHJldHVybiBlc2NhcGVIdG1sKHRvRGlzcGxheVN0cmluZyh2YWx1ZSkpOw0KfQ0KDQpmdW5jdGlvbiBzc3JSZW5kZXJMaXN0KHNvdXJjZSwgcmVuZGVySXRlbSkgew0KICBpZiAoaXNBcnJheShzb3VyY2UpIHx8IGlzU3RyaW5nKHNvdXJjZSkpIHsNCiAgICBmb3IgKGxldCBpID0gMCwgbCA9IHNvdXJjZS5sZW5ndGg7IGkgPCBsOyBpKyspIHsNCiAgICAgIHJlbmRlckl0ZW0oc291cmNlW2ldLCBpKTsNCiAgICB9DQogIH0gZWxzZSBpZiAodHlwZW9mIHNvdXJjZSA9PT0gIm51bWJlciIpIHsNCiAgICBpZiAoIU51bWJlci5pc0ludGVnZXIoc291cmNlKSkgew0KICAgICAgd2FybihgVGhlIHYtZm9yIHJhbmdlIGV4cGVjdCBhbiBpbnRlZ2VyIHZhbHVlIGJ1dCBnb3QgJHtzb3VyY2V9LmApOw0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNvdXJjZTsgaSsrKSB7DQogICAgICByZW5kZXJJdGVtKGkgKyAxLCBpKTsNCiAgICB9DQogIH0gZWxzZSBpZiAoaXNPYmplY3Qoc291cmNlKSkgew0KICAgIGlmIChzb3VyY2VbU3ltYm9sLml0ZXJhdG9yXSkgew0KICAgICAgY29uc3QgYXJyID0gQXJyYXkuZnJvbShzb3VyY2UpOw0KICAgICAgZm9yIChsZXQgaSA9IDAsIGwgPSBhcnIubGVuZ3RoOyBpIDwgbDsgaSsrKSB7DQogICAgICAgIHJlbmRlckl0ZW0oYXJyW2ldLCBpKTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHNvdXJjZSk7DQogICAgICBmb3IgKGxldCBpID0gMCwgbCA9IGtleXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7DQogICAgICAgIGNvbnN0IGtleSA9IGtleXNbaV07DQogICAgICAgIHJlbmRlckl0ZW0oc291cmNlW2tleV0sIGtleSwgaSk7DQogICAgICB9DQogICAgfQ0KICB9DQp9DQoNCmFzeW5jIGZ1bmN0aW9uIHNzclJlbmRlclN1c3BlbnNlKHB1c2gsIHsgZGVmYXVsdDogcmVuZGVyQ29udGVudCB9KSB7DQogIGlmIChyZW5kZXJDb250ZW50KSB7DQogICAgcmVuZGVyQ29udGVudCgpOw0KICB9IGVsc2Ugew0KICAgIHB1c2goYDwhLS0tLT5gKTsNCiAgfQ0KfQ0KDQpmdW5jdGlvbiBzc3JHZXREaXJlY3RpdmVQcm9wcyhpbnN0YW5jZSwgZGlyLCB2YWx1ZSwgYXJnLCBtb2RpZmllcnMgPSB7fSkgew0KICBpZiAodHlwZW9mIGRpciAhPT0gImZ1bmN0aW9uIiAmJiBkaXIuZ2V0U1NSUHJvcHMpIHsNCiAgICByZXR1cm4gZGlyLmdldFNTUlByb3BzKA0KICAgICAgew0KICAgICAgICBkaXIsDQogICAgICAgIGluc3RhbmNlOiBzc3JVdGlscy5nZXRDb21wb25lbnRQdWJsaWNJbnN0YW5jZShpbnN0YW5jZS4kKSwNCiAgICAgICAgdmFsdWUsDQogICAgICAgIG9sZFZhbHVlOiB2b2lkIDAsDQogICAgICAgIGFyZywNCiAgICAgICAgbW9kaWZpZXJzDQogICAgICB9LA0KICAgICAgbnVsbA0KICAgICkgfHwge307DQogIH0NCiAgcmV0dXJuIHt9Ow0KfQ0KDQpjb25zdCBzc3JMb29zZUVxdWFsID0gbG9vc2VFcXVhbDsNCmZ1bmN0aW9uIHNzckxvb3NlQ29udGFpbihhcnIsIHZhbHVlKSB7DQogIHJldHVybiBsb29zZUluZGV4T2YoYXJyLCB2YWx1ZSkgPiAtMTsNCn0NCmZ1bmN0aW9uIHNzclJlbmRlckR5bmFtaWNNb2RlbCh0eXBlLCBtb2RlbCwgdmFsdWUpIHsNCiAgc3dpdGNoICh0eXBlKSB7DQogICAgY2FzZSAicmFkaW8iOg0KICAgICAgcmV0dXJuIGxvb3NlRXF1YWwobW9kZWwsIHZhbHVlKSA/ICIgY2hlY2tlZCIgOiAiIjsNCiAgICBjYXNlICJjaGVja2JveCI6DQogICAgICByZXR1cm4gKGlzQXJyYXkobW9kZWwpID8gc3NyTG9vc2VDb250YWluKG1vZGVsLCB2YWx1ZSkgOiBtb2RlbCkgPyAiIGNoZWNrZWQiIDogIiI7DQogICAgZGVmYXVsdDoNCiAgICAgIHJldHVybiBzc3JSZW5kZXJBdHRyKCJ2YWx1ZSIsIG1vZGVsKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gc3NyR2V0RHluYW1pY01vZGVsUHJvcHMoZXhpc3RpbmdQcm9wcyA9IHt9LCBtb2RlbCkgew0KICBjb25zdCB7IHR5cGUsIHZhbHVlIH0gPSBleGlzdGluZ1Byb3BzOw0KICBzd2l0Y2ggKHR5cGUpIHsNCiAgICBjYXNlICJyYWRpbyI6DQogICAgICByZXR1cm4gbG9vc2VFcXVhbChtb2RlbCwgdmFsdWUpID8geyBjaGVja2VkOiB0cnVlIH0gOiBudWxsOw0KICAgIGNhc2UgImNoZWNrYm94IjoNCiAgICAgIHJldHVybiAoaXNBcnJheShtb2RlbCkgPyBzc3JMb29zZUNvbnRhaW4obW9kZWwsIHZhbHVlKSA6IG1vZGVsKSA/IHsgY2hlY2tlZDogdHJ1ZSB9IDogbnVsbDsNCiAgICBkZWZhdWx0Og0KICAgICAgcmV0dXJuIHsgdmFsdWU6IG1vZGVsIH07DQogIH0NCn0NCg0KZnVuY3Rpb24gc3NyQ29tcGlsZSh0ZW1wbGF0ZSwgaW5zdGFuY2UpIHsNCiAgew0KICAgIHRocm93IG5ldyBFcnJvcigNCiAgICAgIGBPbi10aGUtZmx5IHRlbXBsYXRlIGNvbXBpbGF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgaW4gdGhlIEVTTSBidWlsZCBvZiBAdnVlL3NlcnZlci1yZW5kZXJlci4gQWxsIHRlbXBsYXRlcyBtdXN0IGJlIHByZS1jb21waWxlZCBpbnRvIHJlbmRlciBmdW5jdGlvbnMuYA0KICAgICk7DQogIH0NCn0NCg0KY29uc3Qgew0KICBjcmVhdGVDb21wb25lbnRJbnN0YW5jZSwNCiAgc2V0Q3VycmVudFJlbmRlcmluZ0luc3RhbmNlLA0KICBzZXR1cENvbXBvbmVudCwNCiAgcmVuZGVyQ29tcG9uZW50Um9vdCwNCiAgbm9ybWFsaXplVk5vZGUsDQogIHB1c2hXYXJuaW5nQ29udGV4dCwNCiAgcG9wV2FybmluZ0NvbnRleHQNCn0gPSBzc3JVdGlsczsNCmZ1bmN0aW9uIGNyZWF0ZUJ1ZmZlcigpIHsNCiAgbGV0IGFwcGVuZGFibGUgPSBmYWxzZTsNCiAgY29uc3QgYnVmZmVyID0gW107DQogIHJldHVybiB7DQogICAgZ2V0QnVmZmVyKCkgew0KICAgICAgcmV0dXJuIGJ1ZmZlcjsNCiAgICB9LA0KICAgIHB1c2goaXRlbSkgew0KICAgICAgY29uc3QgaXNTdHJpbmdJdGVtID0gaXNTdHJpbmcoaXRlbSk7DQogICAgICBpZiAoYXBwZW5kYWJsZSAmJiBpc1N0cmluZ0l0ZW0pIHsNCiAgICAgICAgYnVmZmVyW2J1ZmZlci5sZW5ndGggLSAxXSArPSBpdGVtOw0KICAgICAgICByZXR1cm47DQogICAgICB9DQogICAgICBidWZmZXIucHVzaChpdGVtKTsNCiAgICAgIGFwcGVuZGFibGUgPSBpc1N0cmluZ0l0ZW07DQogICAgICBpZiAoaXNQcm9taXNlKGl0ZW0pIHx8IGlzQXJyYXkoaXRlbSkgJiYgaXRlbS5oYXNBc3luYykgew0KICAgICAgICBidWZmZXIuaGFzQXN5bmMgPSB0cnVlOw0KICAgICAgfQ0KICAgIH0NCiAgfTsNCn0NCmZ1bmN0aW9uIHJlbmRlckNvbXBvbmVudFZOb2RlKHZub2RlLCBwYXJlbnRDb21wb25lbnQgPSBudWxsLCBzbG90U2NvcGVJZCkgew0KICBjb25zdCBpbnN0YW5jZSA9IHZub2RlLmNvbXBvbmVudCA9IGNyZWF0ZUNvbXBvbmVudEluc3RhbmNlKA0KICAgIHZub2RlLA0KICAgIHBhcmVudENvbXBvbmVudCwNCiAgICBudWxsDQogICk7DQogIHB1c2hXYXJuaW5nQ29udGV4dCh2bm9kZSk7DQogIGNvbnN0IHJlcyA9IHNldHVwQ29tcG9uZW50KA0KICAgIGluc3RhbmNlLA0KICAgIHRydWUNCiAgICAvKiBpc1NTUiAqLw0KICApOw0KICBwb3BXYXJuaW5nQ29udGV4dCgpOw0KICBjb25zdCBoYXNBc3luY1NldHVwID0gaXNQcm9taXNlKHJlcyk7DQogIGxldCBwcmVmZXRjaGVzID0gaW5zdGFuY2Uuc3A7DQogIGlmIChoYXNBc3luY1NldHVwIHx8IHByZWZldGNoZXMpIHsNCiAgICBjb25zdCBwID0gUHJvbWlzZS5yZXNvbHZlKHJlcykudGhlbigoKSA9PiB7DQogICAgICBpZiAoaGFzQXN5bmNTZXR1cCkgcHJlZmV0Y2hlcyA9IGluc3RhbmNlLnNwOw0KICAgICAgaWYgKHByZWZldGNoZXMpIHsNCiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKA0KICAgICAgICAgIHByZWZldGNoZXMubWFwKChwcmVmZXRjaCkgPT4gcHJlZmV0Y2guY2FsbChpbnN0YW5jZS5wcm94eSkpDQogICAgICAgICk7DQogICAgICB9DQogICAgfSkuY2F0Y2goTk9PUCk7DQogICAgcmV0dXJuIHAudGhlbigoKSA9PiByZW5kZXJDb21wb25lbnRTdWJUcmVlKGluc3RhbmNlLCBzbG90U2NvcGVJZCkpOw0KICB9IGVsc2Ugew0KICAgIHJldHVybiByZW5kZXJDb21wb25lbnRTdWJUcmVlKGluc3RhbmNlLCBzbG90U2NvcGVJZCk7DQogIH0NCn0NCmZ1bmN0aW9uIHJlbmRlckNvbXBvbmVudFN1YlRyZWUoaW5zdGFuY2UsIHNsb3RTY29wZUlkKSB7DQogIHB1c2hXYXJuaW5nQ29udGV4dChpbnN0YW5jZS52bm9kZSk7DQogIGNvbnN0IGNvbXAgPSBpbnN0YW5jZS50eXBlOw0KICBjb25zdCB7IGdldEJ1ZmZlciwgcHVzaCB9ID0gY3JlYXRlQnVmZmVyKCk7DQogIGlmIChpc0Z1bmN0aW9uKGNvbXApKSB7DQogICAgbGV0IHJvb3QgPSByZW5kZXJDb21wb25lbnRSb290KGluc3RhbmNlKTsNCiAgICBpZiAoIWNvbXAucHJvcHMpIHsNCiAgICAgIGZvciAoY29uc3Qga2V5IGluIGluc3RhbmNlLmF0dHJzKSB7DQogICAgICAgIGlmIChrZXkuc3RhcnRzV2l0aChgZGF0YS12LWApKSB7DQogICAgICAgICAgKHJvb3QucHJvcHMgfHwgKHJvb3QucHJvcHMgPSB7fSkpW2tleV0gPSBgYDsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgICByZW5kZXJWTm9kZShwdXNoLCBpbnN0YW5jZS5zdWJUcmVlID0gcm9vdCwgaW5zdGFuY2UsIHNsb3RTY29wZUlkKTsNCiAgfSBlbHNlIHsNCiAgICBpZiAoKCFpbnN0YW5jZS5yZW5kZXIgfHwgaW5zdGFuY2UucmVuZGVyID09PSBOT09QKSAmJiAhaW5zdGFuY2Uuc3NyUmVuZGVyICYmICFjb21wLnNzclJlbmRlciAmJiBpc1N0cmluZyhjb21wLnRlbXBsYXRlKSkgew0KICAgICAgY29tcC5zc3JSZW5kZXIgPSBzc3JDb21waWxlKGNvbXAudGVtcGxhdGUpOw0KICAgIH0NCiAgICBjb25zdCBzc3JSZW5kZXIgPSBpbnN0YW5jZS5zc3JSZW5kZXIgfHwgY29tcC5zc3JSZW5kZXI7DQogICAgaWYgKHNzclJlbmRlcikgew0KICAgICAgbGV0IGF0dHJzID0gaW5zdGFuY2UuaW5oZXJpdEF0dHJzICE9PSBmYWxzZSA/IGluc3RhbmNlLmF0dHJzIDogdm9pZCAwOw0KICAgICAgbGV0IGhhc0Nsb25lZCA9IGZhbHNlOw0KICAgICAgbGV0IGN1ciA9IGluc3RhbmNlOw0KICAgICAgd2hpbGUgKHRydWUpIHsNCiAgICAgICAgY29uc3Qgc2NvcGVJZCA9IGN1ci52bm9kZS5zY29wZUlkOw0KICAgICAgICBpZiAoc2NvcGVJZCkgew0KICAgICAgICAgIGlmICghaGFzQ2xvbmVkKSB7DQogICAgICAgICAgICBhdHRycyA9IHsgLi4uYXR0cnMgfTsNCiAgICAgICAgICAgIGhhc0Nsb25lZCA9IHRydWU7DQogICAgICAgICAgfQ0KICAgICAgICAgIGF0dHJzW3Njb3BlSWRdID0gIiI7DQogICAgICAgIH0NCiAgICAgICAgY29uc3QgcGFyZW50ID0gY3VyLnBhcmVudDsNCiAgICAgICAgaWYgKHBhcmVudCAmJiBwYXJlbnQuc3ViVHJlZSAmJiBwYXJlbnQuc3ViVHJlZSA9PT0gY3VyLnZub2RlKSB7DQogICAgICAgICAgY3VyID0gcGFyZW50Ow0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIGJyZWFrOw0KICAgICAgICB9DQogICAgICB9DQogICAgICBpZiAoc2xvdFNjb3BlSWQpIHsNCiAgICAgICAgaWYgKCFoYXNDbG9uZWQpIGF0dHJzID0geyAuLi5hdHRycyB9Ow0KICAgICAgICBjb25zdCBzbG90U2NvcGVJZExpc3QgPSBzbG90U2NvcGVJZC50cmltKCkuc3BsaXQoIiAiKTsNCiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbG90U2NvcGVJZExpc3QubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgICBhdHRyc1tzbG90U2NvcGVJZExpc3RbaV1dID0gIiI7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGNvbnN0IHByZXYgPSBzZXRDdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UoaW5zdGFuY2UpOw0KICAgICAgdHJ5IHsNCiAgICAgICAgc3NyUmVuZGVyKA0KICAgICAgICAgIGluc3RhbmNlLnByb3h5LA0KICAgICAgICAgIHB1c2gsDQogICAgICAgICAgaW5zdGFuY2UsDQogICAgICAgICAgYXR0cnMsDQogICAgICAgICAgLy8gY29tcGlsZXItb3B0aW1pemVkIGJpbmRpbmdzDQogICAgICAgICAgaW5zdGFuY2UucHJvcHMsDQogICAgICAgICAgaW5zdGFuY2Uuc2V0dXBTdGF0ZSwNCiAgICAgICAgICBpbnN0YW5jZS5kYXRhLA0KICAgICAgICAgIGluc3RhbmNlLmN0eA0KICAgICAgICApOw0KICAgICAgfSBmaW5hbGx5IHsNCiAgICAgICAgc2V0Q3VycmVudFJlbmRlcmluZ0luc3RhbmNlKHByZXYpOw0KICAgICAgfQ0KICAgIH0gZWxzZSBpZiAoaW5zdGFuY2UucmVuZGVyICYmIGluc3RhbmNlLnJlbmRlciAhPT0gTk9PUCkgew0KICAgICAgcmVuZGVyVk5vZGUoDQogICAgICAgIHB1c2gsDQogICAgICAgIGluc3RhbmNlLnN1YlRyZWUgPSByZW5kZXJDb21wb25lbnRSb290KGluc3RhbmNlKSwNCiAgICAgICAgaW5zdGFuY2UsDQogICAgICAgIHNsb3RTY29wZUlkDQogICAgICApOw0KICAgIH0gZWxzZSB7DQogICAgICBjb25zdCBjb21wb25lbnROYW1lID0gY29tcC5uYW1lIHx8IGNvbXAuX19maWxlIHx8IGA8QW5vbnltb3VzPmA7DQogICAgICB3YXJuKGBDb21wb25lbnQgJHtjb21wb25lbnROYW1lfSBpcyBtaXNzaW5nIHRlbXBsYXRlIG9yIHJlbmRlciBmdW5jdGlvbi5gKTsNCiAgICAgIHB1c2goYDwhLS0tLT5gKTsNCiAgICB9DQogIH0NCiAgcG9wV2FybmluZ0NvbnRleHQoKTsNCiAgcmV0dXJuIGdldEJ1ZmZlcigpOw0KfQ0KZnVuY3Rpb24gcmVuZGVyVk5vZGUocHVzaCwgdm5vZGUsIHBhcmVudENvbXBvbmVudCwgc2xvdFNjb3BlSWQpIHsNCiAgY29uc3QgeyB0eXBlLCBzaGFwZUZsYWcsIGNoaWxkcmVuLCBkaXJzLCBwcm9wcyB9ID0gdm5vZGU7DQogIGlmIChkaXJzKSB7DQogICAgdm5vZGUucHJvcHMgPSBhcHBseVNTUkRpcmVjdGl2ZXModm5vZGUsIHByb3BzLCBkaXJzKTsNCiAgfQ0KICBzd2l0Y2ggKHR5cGUpIHsNCiAgICBjYXNlIFRleHQ6DQogICAgICBwdXNoKGVzY2FwZUh0bWwoY2hpbGRyZW4pKTsNCiAgICAgIGJyZWFrOw0KICAgIGNhc2UgQ29tbWVudDoNCiAgICAgIHB1c2goDQogICAgICAgIGNoaWxkcmVuID8gYDwhLS0ke2VzY2FwZUh0bWxDb21tZW50KGNoaWxkcmVuKX0tLT5gIDogYDwhLS0tLT5gDQogICAgICApOw0KICAgICAgYnJlYWs7DQogICAgY2FzZSBTdGF0aWM6DQogICAgICBwdXNoKGNoaWxkcmVuKTsNCiAgICAgIGJyZWFrOw0KICAgIGNhc2UgRnJhZ21lbnQ6DQogICAgICBpZiAodm5vZGUuc2xvdFNjb3BlSWRzKSB7DQogICAgICAgIHNsb3RTY29wZUlkID0gKHNsb3RTY29wZUlkID8gc2xvdFNjb3BlSWQgKyAiICIgOiAiIikgKyB2bm9kZS5zbG90U2NvcGVJZHMuam9pbigiICIpOw0KICAgICAgfQ0KICAgICAgcHVzaChgPCEtLVstLT5gKTsNCiAgICAgIHJlbmRlclZOb2RlQ2hpbGRyZW4oDQogICAgICAgIHB1c2gsDQogICAgICAgIGNoaWxkcmVuLA0KICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgIHNsb3RTY29wZUlkDQogICAgICApOw0KICAgICAgcHVzaChgPCEtLV0tLT5gKTsNCiAgICAgIGJyZWFrOw0KICAgIGRlZmF1bHQ6DQogICAgICBpZiAoc2hhcGVGbGFnICYgMSkgew0KICAgICAgICByZW5kZXJFbGVtZW50Vk5vZGUocHVzaCwgdm5vZGUsIHBhcmVudENvbXBvbmVudCwgc2xvdFNjb3BlSWQpOw0KICAgICAgfSBlbHNlIGlmIChzaGFwZUZsYWcgJiA2KSB7DQogICAgICAgIHB1c2gocmVuZGVyQ29tcG9uZW50Vk5vZGUodm5vZGUsIHBhcmVudENvbXBvbmVudCwgc2xvdFNjb3BlSWQpKTsNCiAgICAgIH0gZWxzZSBpZiAoc2hhcGVGbGFnICYgNjQpIHsNCiAgICAgICAgcmVuZGVyVGVsZXBvcnRWTm9kZShwdXNoLCB2bm9kZSwgcGFyZW50Q29tcG9uZW50LCBzbG90U2NvcGVJZCk7DQogICAgICB9IGVsc2UgaWYgKHNoYXBlRmxhZyAmIDEyOCkgew0KICAgICAgICByZW5kZXJWTm9kZShwdXNoLCB2bm9kZS5zc0NvbnRlbnQsIHBhcmVudENvbXBvbmVudCwgc2xvdFNjb3BlSWQpOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgd2FybigNCiAgICAgICAgICAiW0B2dWUvc2VydmVyLXJlbmRlcmVyXSBJbnZhbGlkIFZOb2RlIHR5cGU6IiwNCiAgICAgICAgICB0eXBlLA0KICAgICAgICAgIGAoJHt0eXBlb2YgdHlwZX0pYA0KICAgICAgICApOw0KICAgICAgfQ0KICB9DQp9DQpmdW5jdGlvbiByZW5kZXJWTm9kZUNoaWxkcmVuKHB1c2gsIGNoaWxkcmVuLCBwYXJlbnRDb21wb25lbnQsIHNsb3RTY29wZUlkKSB7DQogIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHsNCiAgICByZW5kZXJWTm9kZShwdXNoLCBub3JtYWxpemVWTm9kZShjaGlsZHJlbltpXSksIHBhcmVudENvbXBvbmVudCwgc2xvdFNjb3BlSWQpOw0KICB9DQp9DQpmdW5jdGlvbiByZW5kZXJFbGVtZW50Vk5vZGUocHVzaCwgdm5vZGUsIHBhcmVudENvbXBvbmVudCwgc2xvdFNjb3BlSWQpIHsNCiAgY29uc3QgdGFnID0gdm5vZGUudHlwZTsNCiAgbGV0IHsgcHJvcHMsIGNoaWxkcmVuLCBzaGFwZUZsYWcsIHNjb3BlSWQgfSA9IHZub2RlOw0KICBsZXQgb3BlblRhZyA9IGA8JHt0YWd9YDsNCiAgaWYgKHByb3BzKSB7DQogICAgb3BlblRhZyArPSBzc3JSZW5kZXJBdHRycyhwcm9wcywgdGFnKTsNCiAgfQ0KICBpZiAoc2NvcGVJZCkgew0KICAgIG9wZW5UYWcgKz0gYCAke3Njb3BlSWR9YDsNCiAgfQ0KICBsZXQgY3VyUGFyZW50ID0gcGFyZW50Q29tcG9uZW50Ow0KICBsZXQgY3VyVm5vZGUgPSB2bm9kZTsNCiAgd2hpbGUgKGN1clBhcmVudCAmJiBjdXJWbm9kZSA9PT0gY3VyUGFyZW50LnN1YlRyZWUpIHsNCiAgICBjdXJWbm9kZSA9IGN1clBhcmVudC52bm9kZTsNCiAgICBpZiAoY3VyVm5vZGUuc2NvcGVJZCkgew0KICAgICAgb3BlblRhZyArPSBgICR7Y3VyVm5vZGUuc2NvcGVJZH1gOw0KICAgIH0NCiAgICBjdXJQYXJlbnQgPSBjdXJQYXJlbnQucGFyZW50Ow0KICB9DQogIGlmIChzbG90U2NvcGVJZCkgew0KICAgIG9wZW5UYWcgKz0gYCAke3Nsb3RTY29wZUlkfWA7DQogIH0NCiAgcHVzaChvcGVuVGFnICsgYD5gKTsNCiAgaWYgKCFpc1ZvaWRUYWcodGFnKSkgew0KICAgIGxldCBoYXNDaGlsZHJlbk92ZXJyaWRlID0gZmFsc2U7DQogICAgaWYgKHByb3BzKSB7DQogICAgICBpZiAocHJvcHMuaW5uZXJIVE1MKSB7DQogICAgICAgIGhhc0NoaWxkcmVuT3ZlcnJpZGUgPSB0cnVlOw0KICAgICAgICBwdXNoKHByb3BzLmlubmVySFRNTCk7DQogICAgICB9IGVsc2UgaWYgKHByb3BzLnRleHRDb250ZW50KSB7DQogICAgICAgIGhhc0NoaWxkcmVuT3ZlcnJpZGUgPSB0cnVlOw0KICAgICAgICBwdXNoKGVzY2FwZUh0bWwocHJvcHMudGV4dENvbnRlbnQpKTsNCiAgICAgIH0gZWxzZSBpZiAodGFnID09PSAidGV4dGFyZWEiICYmIHByb3BzLnZhbHVlKSB7DQogICAgICAgIGhhc0NoaWxkcmVuT3ZlcnJpZGUgPSB0cnVlOw0KICAgICAgICBwdXNoKGVzY2FwZUh0bWwocHJvcHMudmFsdWUpKTsNCiAgICAgIH0NCiAgICB9DQogICAgaWYgKCFoYXNDaGlsZHJlbk92ZXJyaWRlKSB7DQogICAgICBpZiAoc2hhcGVGbGFnICYgOCkgew0KICAgICAgICBwdXNoKGVzY2FwZUh0bWwoY2hpbGRyZW4pKTsNCiAgICAgIH0gZWxzZSBpZiAoc2hhcGVGbGFnICYgMTYpIHsNCiAgICAgICAgcmVuZGVyVk5vZGVDaGlsZHJlbigNCiAgICAgICAgICBwdXNoLA0KICAgICAgICAgIGNoaWxkcmVuLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBzbG90U2NvcGVJZA0KICAgICAgICApOw0KICAgICAgfQ0KICAgIH0NCiAgICBwdXNoKGA8LyR7dGFnfT5gKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gYXBwbHlTU1JEaXJlY3RpdmVzKHZub2RlLCByYXdQcm9wcywgZGlycykgew0KICBjb25zdCB0b01lcmdlID0gW107DQogIGZvciAobGV0IGkgPSAwOyBpIDwgZGlycy5sZW5ndGg7IGkrKykgew0KICAgIGNvbnN0IGJpbmRpbmcgPSBkaXJzW2ldOw0KICAgIGNvbnN0IHsNCiAgICAgIGRpcjogeyBnZXRTU1JQcm9wcyB9DQogICAgfSA9IGJpbmRpbmc7DQogICAgaWYgKGdldFNTUlByb3BzKSB7DQogICAgICBjb25zdCBwcm9wcyA9IGdldFNTUlByb3BzKGJpbmRpbmcsIHZub2RlKTsNCiAgICAgIGlmIChwcm9wcykgdG9NZXJnZS5wdXNoKHByb3BzKTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIG1lcmdlUHJvcHMocmF3UHJvcHMgfHwge30sIC4uLnRvTWVyZ2UpOw0KfQ0KZnVuY3Rpb24gcmVuZGVyVGVsZXBvcnRWTm9kZShwdXNoLCB2bm9kZSwgcGFyZW50Q29tcG9uZW50LCBzbG90U2NvcGVJZCkgew0KICBjb25zdCB0YXJnZXQgPSB2bm9kZS5wcm9wcyAmJiB2bm9kZS5wcm9wcy50bzsNCiAgY29uc3QgZGlzYWJsZWQgPSB2bm9kZS5wcm9wcyAmJiB2bm9kZS5wcm9wcy5kaXNhYmxlZDsNCiAgaWYgKCF0YXJnZXQpIHsNCiAgICBpZiAoIWRpc2FibGVkKSB7DQogICAgICB3YXJuKGBbQHZ1ZS9zZXJ2ZXItcmVuZGVyZXJdIFRlbGVwb3J0IGlzIG1pc3NpbmcgdGFyZ2V0IHByb3AuYCk7DQogICAgfQ0KICAgIHJldHVybiBbXTsNCiAgfQ0KICBpZiAoIWlzU3RyaW5nKHRhcmdldCkpIHsNCiAgICB3YXJuKA0KICAgICAgYFtAdnVlL3NlcnZlci1yZW5kZXJlcl0gVGVsZXBvcnQgdGFyZ2V0IG11c3QgYmUgYSBxdWVyeSBzZWxlY3RvciBzdHJpbmcuYA0KICAgICk7DQogICAgcmV0dXJuIFtdOw0KICB9DQogIHNzclJlbmRlclRlbGVwb3J0KA0KICAgIHB1c2gsDQogICAgKHB1c2gyKSA9PiB7DQogICAgICByZW5kZXJWTm9kZUNoaWxkcmVuKA0KICAgICAgICBwdXNoMiwNCiAgICAgICAgdm5vZGUuY2hpbGRyZW4sDQogICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgc2xvdFNjb3BlSWQNCiAgICAgICk7DQogICAgfSwNCiAgICB0YXJnZXQsDQogICAgZGlzYWJsZWQgfHwgZGlzYWJsZWQgPT09ICIiLA0KICAgIHBhcmVudENvbXBvbmVudA0KICApOw0KfQ0KDQpjb25zdCB7IGlzVk5vZGU6IGlzVk5vZGUkMSB9ID0gc3NyVXRpbHM7DQpmdW5jdGlvbiBuZXN0ZWRVbnJvbGxCdWZmZXIoYnVmZmVyLCBwYXJlbnRSZXQsIHN0YXJ0SW5kZXgpIHsNCiAgaWYgKCFidWZmZXIuaGFzQXN5bmMpIHsNCiAgICByZXR1cm4gcGFyZW50UmV0ICsgdW5yb2xsQnVmZmVyU3luYyQxKGJ1ZmZlcik7DQogIH0NCiAgbGV0IHJldCA9IHBhcmVudFJldDsNCiAgZm9yIChsZXQgaSA9IHN0YXJ0SW5kZXg7IGkgPCBidWZmZXIubGVuZ3RoOyBpICs9IDEpIHsNCiAgICBjb25zdCBpdGVtID0gYnVmZmVyW2ldOw0KICAgIGlmIChpc1N0cmluZyhpdGVtKSkgew0KICAgICAgcmV0ICs9IGl0ZW07DQogICAgICBjb250aW51ZTsNCiAgICB9DQogICAgaWYgKGlzUHJvbWlzZShpdGVtKSkgew0KICAgICAgcmV0dXJuIGl0ZW0udGhlbigobmVzdGVkSXRlbSkgPT4gew0KICAgICAgICBidWZmZXJbaV0gPSBuZXN0ZWRJdGVtOw0KICAgICAgICByZXR1cm4gbmVzdGVkVW5yb2xsQnVmZmVyKGJ1ZmZlciwgcmV0LCBpKTsNCiAgICAgIH0pOw0KICAgIH0NCiAgICBjb25zdCByZXN1bHQgPSBuZXN0ZWRVbnJvbGxCdWZmZXIoaXRlbSwgcmV0LCAwKTsNCiAgICBpZiAoaXNQcm9taXNlKHJlc3VsdCkpIHsNCiAgICAgIHJldHVybiByZXN1bHQudGhlbigobmVzdGVkSXRlbSkgPT4gew0KICAgICAgICBidWZmZXJbaV0gPSBuZXN0ZWRJdGVtOw0KICAgICAgICByZXR1cm4gbmVzdGVkVW5yb2xsQnVmZmVyKGJ1ZmZlciwgIiIsIGkpOw0KICAgICAgfSk7DQogICAgfQ0KICAgIHJldCA9IHJlc3VsdDsNCiAgfQ0KICByZXR1cm4gcmV0Ow0KfQ0KZnVuY3Rpb24gdW5yb2xsQnVmZmVyJDEoYnVmZmVyKSB7DQogIHJldHVybiBuZXN0ZWRVbnJvbGxCdWZmZXIoYnVmZmVyLCAiIiwgMCk7DQp9DQpmdW5jdGlvbiB1bnJvbGxCdWZmZXJTeW5jJDEoYnVmZmVyKSB7DQogIGxldCByZXQgPSAiIjsNCiAgZm9yIChsZXQgaSA9IDA7IGkgPCBidWZmZXIubGVuZ3RoOyBpKyspIHsNCiAgICBsZXQgaXRlbSA9IGJ1ZmZlcltpXTsNCiAgICBpZiAoaXNTdHJpbmcoaXRlbSkpIHsNCiAgICAgIHJldCArPSBpdGVtOw0KICAgIH0gZWxzZSB7DQogICAgICByZXQgKz0gdW5yb2xsQnVmZmVyU3luYyQxKGl0ZW0pOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gcmV0Ow0KfQ0KYXN5bmMgZnVuY3Rpb24gcmVuZGVyVG9TdHJpbmcoaW5wdXQsIGNvbnRleHQgPSB7fSkgew0KICBpZiAoaXNWTm9kZSQxKGlucHV0KSkgew0KICAgIHJldHVybiByZW5kZXJUb1N0cmluZyhjcmVhdGVBcHAoeyByZW5kZXI6ICgpID0+IGlucHV0IH0pLCBjb250ZXh0KTsNCiAgfQ0KICBjb25zdCB2bm9kZSA9IGNyZWF0ZVZOb2RlKGlucHV0Ll9jb21wb25lbnQsIGlucHV0Ll9wcm9wcyk7DQogIHZub2RlLmFwcENvbnRleHQgPSBpbnB1dC5fY29udGV4dDsNCiAgaW5wdXQucHJvdmlkZShzc3JDb250ZXh0S2V5LCBjb250ZXh0KTsNCiAgY29uc3QgYnVmZmVyID0gYXdhaXQgcmVuZGVyQ29tcG9uZW50Vk5vZGUodm5vZGUpOw0KICBjb25zdCByZXN1bHQgPSBhd2FpdCB1bnJvbGxCdWZmZXIkMShidWZmZXIpOw0KICBhd2FpdCByZXNvbHZlVGVsZXBvcnRzKGNvbnRleHQpOw0KICBpZiAoY29udGV4dC5fX3dhdGNoZXJIYW5kbGVzKSB7DQogICAgZm9yIChjb25zdCB1bndhdGNoIG9mIGNvbnRleHQuX193YXRjaGVySGFuZGxlcykgew0KICAgICAgdW53YXRjaCgpOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gcmVzdWx0Ow0KfQ0KYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZVRlbGVwb3J0cyhjb250ZXh0KSB7DQogIGlmIChjb250ZXh0Ll9fdGVsZXBvcnRCdWZmZXJzKSB7DQogICAgY29udGV4dC50ZWxlcG9ydHMgPSBjb250ZXh0LnRlbGVwb3J0cyB8fCB7fTsNCiAgICBmb3IgKGNvbnN0IGtleSBpbiBjb250ZXh0Ll9fdGVsZXBvcnRCdWZmZXJzKSB7DQogICAgICBjb250ZXh0LnRlbGVwb3J0c1trZXldID0gYXdhaXQgdW5yb2xsQnVmZmVyJDEoDQogICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFtjb250ZXh0Ll9fdGVsZXBvcnRCdWZmZXJzW2tleV1dKQ0KICAgICAgKTsNCiAgICB9DQogIH0NCn0NCg0KY29uc3QgeyBpc1ZOb2RlIH0gPSBzc3JVdGlsczsNCmFzeW5jIGZ1bmN0aW9uIHVucm9sbEJ1ZmZlcihidWZmZXIsIHN0cmVhbSkgew0KICBpZiAoYnVmZmVyLmhhc0FzeW5jKSB7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBidWZmZXIubGVuZ3RoOyBpKyspIHsNCiAgICAgIGxldCBpdGVtID0gYnVmZmVyW2ldOw0KICAgICAgaWYgKGlzUHJvbWlzZShpdGVtKSkgew0KICAgICAgICBpdGVtID0gYXdhaXQgaXRlbTsNCiAgICAgIH0NCiAgICAgIGlmIChpc1N0cmluZyhpdGVtKSkgew0KICAgICAgICBzdHJlYW0ucHVzaChpdGVtKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGF3YWl0IHVucm9sbEJ1ZmZlcihpdGVtLCBzdHJlYW0pOw0KICAgICAgfQ0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICB1bnJvbGxCdWZmZXJTeW5jKGJ1ZmZlciwgc3RyZWFtKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gdW5yb2xsQnVmZmVyU3luYyhidWZmZXIsIHN0cmVhbSkgew0KICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1ZmZlci5sZW5ndGg7IGkrKykgew0KICAgIGxldCBpdGVtID0gYnVmZmVyW2ldOw0KICAgIGlmIChpc1N0cmluZyhpdGVtKSkgew0KICAgICAgc3RyZWFtLnB1c2goaXRlbSk7DQogICAgfSBlbHNlIHsNCiAgICAgIHVucm9sbEJ1ZmZlclN5bmMoaXRlbSwgc3RyZWFtKTsNCiAgICB9DQogIH0NCn0NCmZ1bmN0aW9uIHJlbmRlclRvU2ltcGxlU3RyZWFtKGlucHV0LCBjb250ZXh0LCBzdHJlYW0pIHsNCiAgaWYgKGlzVk5vZGUoaW5wdXQpKSB7DQogICAgcmV0dXJuIHJlbmRlclRvU2ltcGxlU3RyZWFtKA0KICAgICAgY3JlYXRlQXBwKHsgcmVuZGVyOiAoKSA9PiBpbnB1dCB9KSwNCiAgICAgIGNvbnRleHQsDQogICAgICBzdHJlYW0NCiAgICApOw0KICB9DQogIGNvbnN0IHZub2RlID0gY3JlYXRlVk5vZGUoaW5wdXQuX2NvbXBvbmVudCwgaW5wdXQuX3Byb3BzKTsNCiAgdm5vZGUuYXBwQ29udGV4dCA9IGlucHV0Ll9jb250ZXh0Ow0KICBpbnB1dC5wcm92aWRlKHNzckNvbnRleHRLZXksIGNvbnRleHQpOw0KICBQcm9taXNlLnJlc29sdmUocmVuZGVyQ29tcG9uZW50Vk5vZGUodm5vZGUpKS50aGVuKChidWZmZXIpID0+IHVucm9sbEJ1ZmZlcihidWZmZXIsIHN0cmVhbSkpLnRoZW4oKCkgPT4gcmVzb2x2ZVRlbGVwb3J0cyhjb250ZXh0KSkudGhlbigoKSA9PiB7DQogICAgaWYgKGNvbnRleHQuX193YXRjaGVySGFuZGxlcykgew0KICAgICAgZm9yIChjb25zdCB1bndhdGNoIG9mIGNvbnRleHQuX193YXRjaGVySGFuZGxlcykgew0KICAgICAgICB1bndhdGNoKCk7DQogICAgICB9DQogICAgfQ0KICB9KS50aGVuKCgpID0+IHN0cmVhbS5wdXNoKG51bGwpKS5jYXRjaCgoZXJyb3IpID0+IHsNCiAgICBzdHJlYW0uZGVzdHJveShlcnJvcik7DQogIH0pOw0KICByZXR1cm4gc3RyZWFtOw0KfQ0KZnVuY3Rpb24gcmVuZGVyVG9TdHJlYW0oaW5wdXQsIGNvbnRleHQgPSB7fSkgew0KICBjb25zb2xlLndhcm4oDQogICAgYFtAdnVlL3NlcnZlci1yZW5kZXJlcl0gcmVuZGVyVG9TdHJlYW0gaXMgZGVwcmVjYXRlZCAtIHVzZSByZW5kZXJUb05vZGVTdHJlYW0gaW5zdGVhZC5gDQogICk7DQogIHJldHVybiByZW5kZXJUb05vZGVTdHJlYW0oaW5wdXQsIGNvbnRleHQpOw0KfQ0KZnVuY3Rpb24gcmVuZGVyVG9Ob2RlU3RyZWFtKGlucHV0LCBjb250ZXh0ID0ge30pIHsNCiAgew0KICAgIHRocm93IG5ldyBFcnJvcigNCiAgICAgIGBFU00gYnVpbGQgb2YgcmVuZGVyVG9TdHJlYW0oKSBkb2VzIG5vdCBzdXBwb3J0IHJlbmRlclRvTm9kZVN0cmVhbSgpLiBVc2UgcGlwZVRvTm9kZVdyaXRhYmxlKCkgd2l0aCBhbiBleGlzdGluZyBOb2RlLmpzIFdyaXRhYmxlIHN0cmVhbSBpbnN0YW5jZSBpbnN0ZWFkLmANCiAgICApOw0KICB9DQp9DQpmdW5jdGlvbiBwaXBlVG9Ob2RlV3JpdGFibGUoaW5wdXQsIGNvbnRleHQgPSB7fSwgd3JpdGFibGUpIHsNCiAgcmVuZGVyVG9TaW1wbGVTdHJlYW0oaW5wdXQsIGNvbnRleHQsIHsNCiAgICBwdXNoKGNvbnRlbnQpIHsNCiAgICAgIGlmIChjb250ZW50ICE9IG51bGwpIHsNCiAgICAgICAgd3JpdGFibGUud3JpdGUoY29udGVudCk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICB3cml0YWJsZS5lbmQoKTsNCiAgICAgIH0NCiAgICB9LA0KICAgIGRlc3Ryb3koZXJyKSB7DQogICAgICB3cml0YWJsZS5kZXN0cm95KGVycik7DQogICAgfQ0KICB9KTsNCn0NCmZ1bmN0aW9uIHJlbmRlclRvV2ViU3RyZWFtKGlucHV0LCBjb250ZXh0ID0ge30pIHsNCiAgaWYgKHR5cGVvZiBSZWFkYWJsZVN0cmVhbSAhPT0gImZ1bmN0aW9uIikgew0KICAgIHRocm93IG5ldyBFcnJvcigNCiAgICAgIGBSZWFkYWJsZVN0cmVhbSBjb25zdHJ1Y3RvciBpcyBub3QgYXZhaWxhYmxlIGluIHRoZSBnbG9iYWwgc2NvcGUuIElmIHRoZSB0YXJnZXQgZW52aXJvbm1lbnQgZG9lcyBzdXBwb3J0IHdlYiBzdHJlYW1zLCBjb25zaWRlciB1c2luZyBwaXBlVG9XZWJXcml0YWJsZSgpIHdpdGggYW4gZXhpc3RpbmcgV3JpdGFibGVTdHJlYW0gaW5zdGFuY2UgaW5zdGVhZC5gDQogICAgKTsNCiAgfQ0KICBjb25zdCBlbmNvZGVyID0gbmV3IFRleHRFbmNvZGVyKCk7DQogIGxldCBjYW5jZWxsZWQgPSBmYWxzZTsNCiAgcmV0dXJuIG5ldyBSZWFkYWJsZVN0cmVhbSh7DQogICAgc3RhcnQoY29udHJvbGxlcikgew0KICAgICAgcmVuZGVyVG9TaW1wbGVTdHJlYW0oaW5wdXQsIGNvbnRleHQsIHsNCiAgICAgICAgcHVzaChjb250ZW50KSB7DQogICAgICAgICAgaWYgKGNhbmNlbGxlZCkgcmV0dXJuOw0KICAgICAgICAgIGlmIChjb250ZW50ICE9IG51bGwpIHsNCiAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShlbmNvZGVyLmVuY29kZShjb250ZW50KSk7DQogICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIGNvbnRyb2xsZXIuY2xvc2UoKTsNCiAgICAgICAgICB9DQogICAgICAgIH0sDQogICAgICAgIGRlc3Ryb3koZXJyKSB7DQogICAgICAgICAgY29udHJvbGxlci5lcnJvcihlcnIpOw0KICAgICAgICB9DQogICAgICB9KTsNCiAgICB9LA0KICAgIGNhbmNlbCgpIHsNCiAgICAgIGNhbmNlbGxlZCA9IHRydWU7DQogICAgfQ0KICB9KTsNCn0NCmZ1bmN0aW9uIHBpcGVUb1dlYldyaXRhYmxlKGlucHV0LCBjb250ZXh0ID0ge30sIHdyaXRhYmxlKSB7DQogIGNvbnN0IHdyaXRlciA9IHdyaXRhYmxlLmdldFdyaXRlcigpOw0KICBjb25zdCBlbmNvZGVyID0gbmV3IFRleHRFbmNvZGVyKCk7DQogIGxldCBoYXNSZWFkeSA9IGZhbHNlOw0KICB0cnkgew0KICAgIGhhc1JlYWR5ID0gaXNQcm9taXNlKHdyaXRlci5yZWFkeSk7DQogIH0gY2F0Y2ggKGUpIHsNCiAgfQ0KICByZW5kZXJUb1NpbXBsZVN0cmVhbShpbnB1dCwgY29udGV4dCwgew0KICAgIGFzeW5jIHB1c2goY29udGVudCkgew0KICAgICAgaWYgKGhhc1JlYWR5KSB7DQogICAgICAgIGF3YWl0IHdyaXRlci5yZWFkeTsNCiAgICAgIH0NCiAgICAgIGlmIChjb250ZW50ICE9IG51bGwpIHsNCiAgICAgICAgcmV0dXJuIHdyaXRlci53cml0ZShlbmNvZGVyLmVuY29kZShjb250ZW50KSk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICByZXR1cm4gd3JpdGVyLmNsb3NlKCk7DQogICAgICB9DQogICAgfSwNCiAgICBkZXN0cm95KGVycikgew0KICAgICAgY29uc29sZS5sb2coZXJyKTsNCiAgICAgIHdyaXRlci5jbG9zZSgpOw0KICAgIH0NCiAgfSk7DQp9DQoNCmluaXREaXJlY3RpdmVzRm9yU1NSKCk7DQoNCmV4cG9ydCB7IHBpcGVUb05vZGVXcml0YWJsZSwgcGlwZVRvV2ViV3JpdGFibGUsIHJlbmRlclRvTm9kZVN0cmVhbSwgcmVuZGVyVG9TaW1wbGVTdHJlYW0sIHJlbmRlclRvU3RyZWFtLCByZW5kZXJUb1N0cmluZywgcmVuZGVyVG9XZWJTdHJlYW0sIHNzckdldERpcmVjdGl2ZVByb3BzLCBzc3JHZXREeW5hbWljTW9kZWxQcm9wcywgaW5jbHVkZUJvb2xlYW5BdHRyIGFzIHNzckluY2x1ZGVCb29sZWFuQXR0ciwgc3NySW50ZXJwb2xhdGUsIHNzckxvb3NlQ29udGFpbiwgc3NyTG9vc2VFcXVhbCwgc3NyUmVuZGVyQXR0ciwgc3NyUmVuZGVyQXR0cnMsIHNzclJlbmRlckNsYXNzLCBzc3JSZW5kZXJDb21wb25lbnQsIHNzclJlbmRlckR5bmFtaWNBdHRyLCBzc3JSZW5kZXJEeW5hbWljTW9kZWwsIHNzclJlbmRlckxpc3QsIHNzclJlbmRlclNsb3QsIHNzclJlbmRlclNsb3RJbm5lciwgc3NyUmVuZGVyU3R5bGUsIHNzclJlbmRlclN1c3BlbnNlLCBzc3JSZW5kZXJUZWxlcG9ydCwgcmVuZGVyVk5vZGUgYXMgc3NyUmVuZGVyVk5vZGUgfTsNCg==",Dnn={class:"custom-component-render"},Enn=er({...er({name:"ShjCustomComponentRender"}),props:{option:{},sources:{},useEvents:{}},setup(i,{expose:e}){window.Axios=LK,window.Hls=t2,ha(()=>{window.SHJDatasourceV2=Jo,window.SHJParseEvent=xi});const t=ti(()=>bnn(i.option)),{productionMode:r,vueVersion:n,importMap:s}=aQt({runtimeDev:hqt,runtimeProd:hqt,serverRenderer:Inn}),a=ti(()=>({script:{inlineTemplate:r.value,isProd:r.value,propsDestructure:!0},style:{isProd:r.value},template:{isProd:r.value}})),o=Zt(!0),l=A8(null),u=Zt("");(()=>{const x=t.value.hash;if(!(u.value===x&&l.value)){u.value=x,o.value=!0;try{const v=cnn({builtinImportMap:s,vueVersion:n,sfcOptions:a},x);v.files["src/source.json"]&&(v.files["src/source.json"].code=JSON.stringify(i.sources,null,2)),v.files["src/option.json"]&&(v.files["src/option.json"].code=JSON.stringify(t.value.option,null,2)),l.value=v,o.value=!1}catch{o.value=!1}}})();const d=()=>{if(!l.value||!g.value)return;const x=g.value.querySelector("iframe").contentWindow;x&&x.postMessage(JSON.stringify(i.sources),"*")},h=()=>{l.value&&(o.value=!0,l.value.files["src/source.json"]&&(l.value.files["src/source.json"].code=JSON.stringify(i.sources,null,2)),l.value.files["src/option.json"]&&(l.value.files["src/option.json"].code=JSON.stringify(t.value.option,null,2)),setTimeout(()=>{o.value=!1},10))};Ann({option:t,sources:i.sources},d,h),e({refresh:()=>{h(),d()},refreshView:()=>{h(),d()},refreshData:()=>{d()}});const p=ti(()=>({customCode:{useCode:`
|
|
5208
|
+
}`),await h.eval(B)}catch(T){u.value=T.message}}function C(){d.contentWindow?.location.reload()}return e({reload:C,container:l}),(I,S)=>(Vt(),kr(ta,null,[vv(Xi("div",{ref:"container",class:Ba(["iframe-container",Nr(n)])},null,2),[[S8,t.show]]),$a(aqt,{err:(Nr(a)?.showRuntimeError??!0)&&u.value},null,8,["err"]),!u.value&&(Nr(a)?.showRuntimeWarning??!0)?(Vt(),Pi(aqt,{key:0,warn:c.value},null,8,["warn"])):Hi("",!0)],64))}}),[["__scopeId","data-v-da180541"]]),Ann=(i,e,t)=>{bi(()=>i.sources,()=>{e()},{deep:!0}),bi(()=>i.option.value.option,(r,n)=>{Ht.isEqual(r,n)||t()},{deep:!0})},dqt="2.0.0",bnn=i=>{const e=Ht.cloneDeep(i);return e.version!==dqt?{hash:e.hash,option:e.option,version:dqt}:i},hqt="data:text/javascript;base64,LyoqDQoqIEB2dWUvcnVudGltZS1kb20gdjMuNS4xNw0KKiAoYykgMjAxOC1wcmVzZW50IFl1eGkgKEV2YW4pIFlvdSBhbmQgVnVlIGNvbnRyaWJ1dG9ycw0KKiBAbGljZW5zZSBNSVQNCioqLw0KLyohICNfX05PX1NJREVfRUZGRUNUU19fICovDQovLyBAX19OT19TSURFX0VGRkVDVFNfXw0KZnVuY3Rpb24gbWFrZU1hcChzdHIpIHsNCiAgY29uc3QgbWFwID0gLyogQF9fUFVSRV9fICovIE9iamVjdC5jcmVhdGUobnVsbCk7DQogIGZvciAoY29uc3Qga2V5IG9mIHN0ci5zcGxpdCgiLCIpKSBtYXBba2V5XSA9IDE7DQogIHJldHVybiAodmFsKSA9PiB2YWwgaW4gbWFwOw0KfQ0KDQpjb25zdCBFTVBUWV9PQkogPSBPYmplY3QuZnJlZXplKHt9KSA7DQpjb25zdCBFTVBUWV9BUlIgPSBPYmplY3QuZnJlZXplKFtdKSA7DQpjb25zdCBOT09QID0gKCkgPT4gew0KfTsNCmNvbnN0IE5PID0gKCkgPT4gZmFsc2U7DQpjb25zdCBpc09uID0gKGtleSkgPT4ga2V5LmNoYXJDb2RlQXQoMCkgPT09IDExMSAmJiBrZXkuY2hhckNvZGVBdCgxKSA9PT0gMTEwICYmIC8vIHVwcGVyY2FzZSBsZXR0ZXINCihrZXkuY2hhckNvZGVBdCgyKSA+IDEyMiB8fCBrZXkuY2hhckNvZGVBdCgyKSA8IDk3KTsNCmNvbnN0IGlzTW9kZWxMaXN0ZW5lciA9IChrZXkpID0+IGtleS5zdGFydHNXaXRoKCJvblVwZGF0ZToiKTsNCmNvbnN0IGV4dGVuZCA9IE9iamVjdC5hc3NpZ247DQpjb25zdCByZW1vdmUgPSAoYXJyLCBlbCkgPT4gew0KICBjb25zdCBpID0gYXJyLmluZGV4T2YoZWwpOw0KICBpZiAoaSA+IC0xKSB7DQogICAgYXJyLnNwbGljZShpLCAxKTsNCiAgfQ0KfTsNCmNvbnN0IGhhc093blByb3BlcnR5JDEgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5Ow0KY29uc3QgaGFzT3duID0gKHZhbCwga2V5KSA9PiBoYXNPd25Qcm9wZXJ0eSQxLmNhbGwodmFsLCBrZXkpOw0KY29uc3QgaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7DQpjb25zdCBpc01hcCA9ICh2YWwpID0+IHRvVHlwZVN0cmluZyh2YWwpID09PSAiW29iamVjdCBNYXBdIjsNCmNvbnN0IGlzU2V0ID0gKHZhbCkgPT4gdG9UeXBlU3RyaW5nKHZhbCkgPT09ICJbb2JqZWN0IFNldF0iOw0KY29uc3QgaXNEYXRlID0gKHZhbCkgPT4gdG9UeXBlU3RyaW5nKHZhbCkgPT09ICJbb2JqZWN0IERhdGVdIjsNCmNvbnN0IGlzUmVnRXhwID0gKHZhbCkgPT4gdG9UeXBlU3RyaW5nKHZhbCkgPT09ICJbb2JqZWN0IFJlZ0V4cF0iOw0KY29uc3QgaXNGdW5jdGlvbiA9ICh2YWwpID0+IHR5cGVvZiB2YWwgPT09ICJmdW5jdGlvbiI7DQpjb25zdCBpc1N0cmluZyA9ICh2YWwpID0+IHR5cGVvZiB2YWwgPT09ICJzdHJpbmciOw0KY29uc3QgaXNTeW1ib2wgPSAodmFsKSA9PiB0eXBlb2YgdmFsID09PSAic3ltYm9sIjsNCmNvbnN0IGlzT2JqZWN0ID0gKHZhbCkgPT4gdmFsICE9PSBudWxsICYmIHR5cGVvZiB2YWwgPT09ICJvYmplY3QiOw0KY29uc3QgaXNQcm9taXNlID0gKHZhbCkgPT4gew0KICByZXR1cm4gKGlzT2JqZWN0KHZhbCkgfHwgaXNGdW5jdGlvbih2YWwpKSAmJiBpc0Z1bmN0aW9uKHZhbC50aGVuKSAmJiBpc0Z1bmN0aW9uKHZhbC5jYXRjaCk7DQp9Ow0KY29uc3Qgb2JqZWN0VG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nOw0KY29uc3QgdG9UeXBlU3RyaW5nID0gKHZhbHVlKSA9PiBvYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKTsNCmNvbnN0IHRvUmF3VHlwZSA9ICh2YWx1ZSkgPT4gew0KICByZXR1cm4gdG9UeXBlU3RyaW5nKHZhbHVlKS5zbGljZSg4LCAtMSk7DQp9Ow0KY29uc3QgaXNQbGFpbk9iamVjdCA9ICh2YWwpID0+IHRvVHlwZVN0cmluZyh2YWwpID09PSAiW29iamVjdCBPYmplY3RdIjsNCmNvbnN0IGlzSW50ZWdlcktleSA9IChrZXkpID0+IGlzU3RyaW5nKGtleSkgJiYga2V5ICE9PSAiTmFOIiAmJiBrZXlbMF0gIT09ICItIiAmJiAiIiArIHBhcnNlSW50KGtleSwgMTApID09PSBrZXk7DQpjb25zdCBpc1Jlc2VydmVkUHJvcCA9IC8qIEBfX1BVUkVfXyAqLyBtYWtlTWFwKA0KICAvLyB0aGUgbGVhZGluZyBjb21tYSBpcyBpbnRlbnRpb25hbCBzbyBlbXB0eSBzdHJpbmcgIiIgaXMgYWxzbyBpbmNsdWRlZA0KICAiLGtleSxyZWYscmVmX2ZvcixyZWZfa2V5LG9uVm5vZGVCZWZvcmVNb3VudCxvblZub2RlTW91bnRlZCxvblZub2RlQmVmb3JlVXBkYXRlLG9uVm5vZGVVcGRhdGVkLG9uVm5vZGVCZWZvcmVVbm1vdW50LG9uVm5vZGVVbm1vdW50ZWQiDQopOw0KY29uc3QgaXNCdWlsdEluRGlyZWN0aXZlID0gLyogQF9fUFVSRV9fICovIG1ha2VNYXAoDQogICJiaW5kLGNsb2FrLGVsc2UtaWYsZWxzZSxmb3IsaHRtbCxpZixtb2RlbCxvbixvbmNlLHByZSxzaG93LHNsb3QsdGV4dCxtZW1vIg0KKTsNCmNvbnN0IGNhY2hlU3RyaW5nRnVuY3Rpb24gPSAoZm4pID0+IHsNCiAgY29uc3QgY2FjaGUgPSAvKiBAX19QVVJFX18gKi8gT2JqZWN0LmNyZWF0ZShudWxsKTsNCiAgcmV0dXJuIChzdHIpID0+IHsNCiAgICBjb25zdCBoaXQgPSBjYWNoZVtzdHJdOw0KICAgIHJldHVybiBoaXQgfHwgKGNhY2hlW3N0cl0gPSBmbihzdHIpKTsNCiAgfTsNCn07DQpjb25zdCBjYW1lbGl6ZVJFID0gLy0oXHcpL2c7DQpjb25zdCBjYW1lbGl6ZSA9IGNhY2hlU3RyaW5nRnVuY3Rpb24oDQogIChzdHIpID0+IHsNCiAgICByZXR1cm4gc3RyLnJlcGxhY2UoY2FtZWxpemVSRSwgKF8sIGMpID0+IGMgPyBjLnRvVXBwZXJDYXNlKCkgOiAiIik7DQogIH0NCik7DQpjb25zdCBoeXBoZW5hdGVSRSA9IC9cQihbQS1aXSkvZzsNCmNvbnN0IGh5cGhlbmF0ZSA9IGNhY2hlU3RyaW5nRnVuY3Rpb24oDQogIChzdHIpID0+IHN0ci5yZXBsYWNlKGh5cGhlbmF0ZVJFLCAiLSQxIikudG9Mb3dlckNhc2UoKQ0KKTsNCmNvbnN0IGNhcGl0YWxpemUgPSBjYWNoZVN0cmluZ0Z1bmN0aW9uKChzdHIpID0+IHsNCiAgcmV0dXJuIHN0ci5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHN0ci5zbGljZSgxKTsNCn0pOw0KY29uc3QgdG9IYW5kbGVyS2V5ID0gY2FjaGVTdHJpbmdGdW5jdGlvbigNCiAgKHN0cikgPT4gew0KICAgIGNvbnN0IHMgPSBzdHIgPyBgb24ke2NhcGl0YWxpemUoc3RyKX1gIDogYGA7DQogICAgcmV0dXJuIHM7DQogIH0NCik7DQpjb25zdCBoYXNDaGFuZ2VkID0gKHZhbHVlLCBvbGRWYWx1ZSkgPT4gIU9iamVjdC5pcyh2YWx1ZSwgb2xkVmFsdWUpOw0KY29uc3QgaW52b2tlQXJyYXlGbnMgPSAoZm5zLCAuLi5hcmcpID0+IHsNCiAgZm9yIChsZXQgaSA9IDA7IGkgPCBmbnMubGVuZ3RoOyBpKyspIHsNCiAgICBmbnNbaV0oLi4uYXJnKTsNCiAgfQ0KfTsNCmNvbnN0IGRlZiA9IChvYmosIGtleSwgdmFsdWUsIHdyaXRhYmxlID0gZmFsc2UpID0+IHsNCiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwga2V5LCB7DQogICAgY29uZmlndXJhYmxlOiB0cnVlLA0KICAgIGVudW1lcmFibGU6IGZhbHNlLA0KICAgIHdyaXRhYmxlLA0KICAgIHZhbHVlDQogIH0pOw0KfTsNCmNvbnN0IGxvb3NlVG9OdW1iZXIgPSAodmFsKSA9PiB7DQogIGNvbnN0IG4gPSBwYXJzZUZsb2F0KHZhbCk7DQogIHJldHVybiBpc05hTihuKSA/IHZhbCA6IG47DQp9Ow0KY29uc3QgdG9OdW1iZXIgPSAodmFsKSA9PiB7DQogIGNvbnN0IG4gPSBpc1N0cmluZyh2YWwpID8gTnVtYmVyKHZhbCkgOiBOYU47DQogIHJldHVybiBpc05hTihuKSA/IHZhbCA6IG47DQp9Ow0KbGV0IF9nbG9iYWxUaGlzOw0KY29uc3QgZ2V0R2xvYmFsVGhpcyA9ICgpID0+IHsNCiAgcmV0dXJuIF9nbG9iYWxUaGlzIHx8IChfZ2xvYmFsVGhpcyA9IHR5cGVvZiBnbG9iYWxUaGlzICE9PSAidW5kZWZpbmVkIiA/IGdsb2JhbFRoaXMgOiB0eXBlb2Ygc2VsZiAhPT0gInVuZGVmaW5lZCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gInVuZGVmaW5lZCIgPyB3aW5kb3cgOiB0eXBlb2YgZ2xvYmFsICE9PSAidW5kZWZpbmVkIiA/IGdsb2JhbCA6IHt9KTsNCn07DQoNCmNvbnN0IEdMT0JBTFNfQUxMT1dFRCA9ICJJbmZpbml0eSx1bmRlZmluZWQsTmFOLGlzRmluaXRlLGlzTmFOLHBhcnNlRmxvYXQscGFyc2VJbnQsZGVjb2RlVVJJLGRlY29kZVVSSUNvbXBvbmVudCxlbmNvZGVVUkksZW5jb2RlVVJJQ29tcG9uZW50LE1hdGgsTnVtYmVyLERhdGUsQXJyYXksT2JqZWN0LEJvb2xlYW4sU3RyaW5nLFJlZ0V4cCxNYXAsU2V0LEpTT04sSW50bCxCaWdJbnQsY29uc29sZSxFcnJvcixTeW1ib2wiOw0KY29uc3QgaXNHbG9iYWxseUFsbG93ZWQgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcChHTE9CQUxTX0FMTE9XRUQpOw0KDQpmdW5jdGlvbiBub3JtYWxpemVTdHlsZSh2YWx1ZSkgew0KICBpZiAoaXNBcnJheSh2YWx1ZSkpIHsNCiAgICBjb25zdCByZXMgPSB7fTsNCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKSB7DQogICAgICBjb25zdCBpdGVtID0gdmFsdWVbaV07DQogICAgICBjb25zdCBub3JtYWxpemVkID0gaXNTdHJpbmcoaXRlbSkgPyBwYXJzZVN0cmluZ1N0eWxlKGl0ZW0pIDogbm9ybWFsaXplU3R5bGUoaXRlbSk7DQogICAgICBpZiAobm9ybWFsaXplZCkgew0KICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBub3JtYWxpemVkKSB7DQogICAgICAgICAgcmVzW2tleV0gPSBub3JtYWxpemVkW2tleV07DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogICAgcmV0dXJuIHJlczsNCiAgfSBlbHNlIGlmIChpc1N0cmluZyh2YWx1ZSkgfHwgaXNPYmplY3QodmFsdWUpKSB7DQogICAgcmV0dXJuIHZhbHVlOw0KICB9DQp9DQpjb25zdCBsaXN0RGVsaW1pdGVyUkUgPSAvOyg/IVteKF0qXCkpL2c7DQpjb25zdCBwcm9wZXJ0eURlbGltaXRlclJFID0gLzooW15dKykvOw0KY29uc3Qgc3R5bGVDb21tZW50UkUgPSAvXC9cKlteXSo/XCpcLy9nOw0KZnVuY3Rpb24gcGFyc2VTdHJpbmdTdHlsZShjc3NUZXh0KSB7DQogIGNvbnN0IHJldCA9IHt9Ow0KICBjc3NUZXh0LnJlcGxhY2Uoc3R5bGVDb21tZW50UkUsICIiKS5zcGxpdChsaXN0RGVsaW1pdGVyUkUpLmZvckVhY2goKGl0ZW0pID0+IHsNCiAgICBpZiAoaXRlbSkgew0KICAgICAgY29uc3QgdG1wID0gaXRlbS5zcGxpdChwcm9wZXJ0eURlbGltaXRlclJFKTsNCiAgICAgIHRtcC5sZW5ndGggPiAxICYmIChyZXRbdG1wWzBdLnRyaW0oKV0gPSB0bXBbMV0udHJpbSgpKTsNCiAgICB9DQogIH0pOw0KICByZXR1cm4gcmV0Ow0KfQ0KZnVuY3Rpb24gc3RyaW5naWZ5U3R5bGUoc3R5bGVzKSB7DQogIGlmICghc3R5bGVzKSByZXR1cm4gIiI7DQogIGlmIChpc1N0cmluZyhzdHlsZXMpKSByZXR1cm4gc3R5bGVzOw0KICBsZXQgcmV0ID0gIiI7DQogIGZvciAoY29uc3Qga2V5IGluIHN0eWxlcykgew0KICAgIGNvbnN0IHZhbHVlID0gc3R5bGVzW2tleV07DQogICAgaWYgKGlzU3RyaW5nKHZhbHVlKSB8fCB0eXBlb2YgdmFsdWUgPT09ICJudW1iZXIiKSB7DQogICAgICBjb25zdCBub3JtYWxpemVkS2V5ID0ga2V5LnN0YXJ0c1dpdGgoYC0tYCkgPyBrZXkgOiBoeXBoZW5hdGUoa2V5KTsNCiAgICAgIHJldCArPSBgJHtub3JtYWxpemVkS2V5fToke3ZhbHVlfTtgOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gcmV0Ow0KfQ0KZnVuY3Rpb24gbm9ybWFsaXplQ2xhc3ModmFsdWUpIHsNCiAgbGV0IHJlcyA9ICIiOw0KICBpZiAoaXNTdHJpbmcodmFsdWUpKSB7DQogICAgcmVzID0gdmFsdWU7DQogIH0gZWxzZSBpZiAoaXNBcnJheSh2YWx1ZSkpIHsNCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKSB7DQogICAgICBjb25zdCBub3JtYWxpemVkID0gbm9ybWFsaXplQ2xhc3ModmFsdWVbaV0pOw0KICAgICAgaWYgKG5vcm1hbGl6ZWQpIHsNCiAgICAgICAgcmVzICs9IG5vcm1hbGl6ZWQgKyAiICI7DQogICAgICB9DQogICAgfQ0KICB9IGVsc2UgaWYgKGlzT2JqZWN0KHZhbHVlKSkgew0KICAgIGZvciAoY29uc3QgbmFtZSBpbiB2YWx1ZSkgew0KICAgICAgaWYgKHZhbHVlW25hbWVdKSB7DQogICAgICAgIHJlcyArPSBuYW1lICsgIiAiOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICByZXR1cm4gcmVzLnRyaW0oKTsNCn0NCmZ1bmN0aW9uIG5vcm1hbGl6ZVByb3BzKHByb3BzKSB7DQogIGlmICghcHJvcHMpIHJldHVybiBudWxsOw0KICBsZXQgeyBjbGFzczoga2xhc3MsIHN0eWxlIH0gPSBwcm9wczsNCiAgaWYgKGtsYXNzICYmICFpc1N0cmluZyhrbGFzcykpIHsNCiAgICBwcm9wcy5jbGFzcyA9IG5vcm1hbGl6ZUNsYXNzKGtsYXNzKTsNCiAgfQ0KICBpZiAoc3R5bGUpIHsNCiAgICBwcm9wcy5zdHlsZSA9IG5vcm1hbGl6ZVN0eWxlKHN0eWxlKTsNCiAgfQ0KICByZXR1cm4gcHJvcHM7DQp9DQoNCmNvbnN0IEhUTUxfVEFHUyA9ICJodG1sLGJvZHksYmFzZSxoZWFkLGxpbmssbWV0YSxzdHlsZSx0aXRsZSxhZGRyZXNzLGFydGljbGUsYXNpZGUsZm9vdGVyLGhlYWRlcixoZ3JvdXAsaDEsaDIsaDMsaDQsaDUsaDYsbmF2LHNlY3Rpb24sZGl2LGRkLGRsLGR0LGZpZ2NhcHRpb24sZmlndXJlLHBpY3R1cmUsaHIsaW1nLGxpLG1haW4sb2wscCxwcmUsdWwsYSxiLGFiYnIsYmRpLGJkbyxicixjaXRlLGNvZGUsZGF0YSxkZm4sZW0saSxrYmQsbWFyayxxLHJwLHJ0LHJ1YnkscyxzYW1wLHNtYWxsLHNwYW4sc3Ryb25nLHN1YixzdXAsdGltZSx1LHZhcix3YnIsYXJlYSxhdWRpbyxtYXAsdHJhY2ssdmlkZW8sZW1iZWQsb2JqZWN0LHBhcmFtLHNvdXJjZSxjYW52YXMsc2NyaXB0LG5vc2NyaXB0LGRlbCxpbnMsY2FwdGlvbixjb2wsY29sZ3JvdXAsdGFibGUsdGhlYWQsdGJvZHksdGQsdGgsdHIsYnV0dG9uLGRhdGFsaXN0LGZpZWxkc2V0LGZvcm0saW5wdXQsbGFiZWwsbGVnZW5kLG1ldGVyLG9wdGdyb3VwLG9wdGlvbixvdXRwdXQscHJvZ3Jlc3Msc2VsZWN0LHRleHRhcmVhLGRldGFpbHMsZGlhbG9nLG1lbnUsc3VtbWFyeSx0ZW1wbGF0ZSxibG9ja3F1b3RlLGlmcmFtZSx0Zm9vdCI7DQpjb25zdCBTVkdfVEFHUyA9ICJzdmcsYW5pbWF0ZSxhbmltYXRlTW90aW9uLGFuaW1hdGVUcmFuc2Zvcm0sY2lyY2xlLGNsaXBQYXRoLGNvbG9yLXByb2ZpbGUsZGVmcyxkZXNjLGRpc2NhcmQsZWxsaXBzZSxmZUJsZW5kLGZlQ29sb3JNYXRyaXgsZmVDb21wb25lbnRUcmFuc2ZlcixmZUNvbXBvc2l0ZSxmZUNvbnZvbHZlTWF0cml4LGZlRGlmZnVzZUxpZ2h0aW5nLGZlRGlzcGxhY2VtZW50TWFwLGZlRGlzdGFudExpZ2h0LGZlRHJvcFNoYWRvdyxmZUZsb29kLGZlRnVuY0EsZmVGdW5jQixmZUZ1bmNHLGZlRnVuY1IsZmVHYXVzc2lhbkJsdXIsZmVJbWFnZSxmZU1lcmdlLGZlTWVyZ2VOb2RlLGZlTW9ycGhvbG9neSxmZU9mZnNldCxmZVBvaW50TGlnaHQsZmVTcGVjdWxhckxpZ2h0aW5nLGZlU3BvdExpZ2h0LGZlVGlsZSxmZVR1cmJ1bGVuY2UsZmlsdGVyLGZvcmVpZ25PYmplY3QsZyxoYXRjaCxoYXRjaHBhdGgsaW1hZ2UsbGluZSxsaW5lYXJHcmFkaWVudCxtYXJrZXIsbWFzayxtZXNoLG1lc2hncmFkaWVudCxtZXNocGF0Y2gsbWVzaHJvdyxtZXRhZGF0YSxtcGF0aCxwYXRoLHBhdHRlcm4scG9seWdvbixwb2x5bGluZSxyYWRpYWxHcmFkaWVudCxyZWN0LHNldCxzb2xpZGNvbG9yLHN0b3Asc3dpdGNoLHN5bWJvbCx0ZXh0LHRleHRQYXRoLHRpdGxlLHRzcGFuLHVua25vd24sdXNlLHZpZXciOw0KY29uc3QgTUFUSF9UQUdTID0gImFubm90YXRpb24sYW5ub3RhdGlvbi14bWwsbWFjdGlvbixtYWxpZ25ncm91cCxtYWxpZ25tYXJrLG1hdGgsbWVuY2xvc2UsbWVycm9yLG1mZW5jZWQsbWZyYWMsbWZyYWN0aW9uLG1nbHlwaCxtaSxtbGFiZWxlZHRyLG1sb25nZGl2LG1tdWx0aXNjcmlwdHMsbW4sbW8sbW92ZXIsbXBhZGRlZCxtcGhhbnRvbSxtcHJlc2NyaXB0cyxtcm9vdCxtcm93LG1zLG1zY2Fycmllcyxtc2NhcnJ5LG1zZ3JvdXAsbXNsaW5lLG1zcGFjZSxtc3FydCxtc3Jvdyxtc3RhY2ssbXN0eWxlLG1zdWIsbXN1YnN1cCxtc3VwLG10YWJsZSxtdGQsbXRleHQsbXRyLG11bmRlcixtdW5kZXJvdmVyLG5vbmUsc2VtYW50aWNzIjsNCmNvbnN0IGlzSFRNTFRhZyA9IC8qIEBfX1BVUkVfXyAqLyBtYWtlTWFwKEhUTUxfVEFHUyk7DQpjb25zdCBpc1NWR1RhZyA9IC8qIEBfX1BVUkVfXyAqLyBtYWtlTWFwKFNWR19UQUdTKTsNCmNvbnN0IGlzTWF0aE1MVGFnID0gLyogQF9fUFVSRV9fICovIG1ha2VNYXAoTUFUSF9UQUdTKTsNCg0KY29uc3Qgc3BlY2lhbEJvb2xlYW5BdHRycyA9IGBpdGVtc2NvcGUsYWxsb3dmdWxsc2NyZWVuLGZvcm1ub3ZhbGlkYXRlLGlzbWFwLG5vbW9kdWxlLG5vdmFsaWRhdGUscmVhZG9ubHlgOw0KY29uc3QgaXNTcGVjaWFsQm9vbGVhbkF0dHIgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcChzcGVjaWFsQm9vbGVhbkF0dHJzKTsNCmNvbnN0IGlzQm9vbGVhbkF0dHIgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcCgNCiAgc3BlY2lhbEJvb2xlYW5BdHRycyArIGAsYXN5bmMsYXV0b2ZvY3VzLGF1dG9wbGF5LGNvbnRyb2xzLGRlZmF1bHQsZGVmZXIsZGlzYWJsZWQsaGlkZGVuLGluZXJ0LGxvb3Asb3BlbixyZXF1aXJlZCxyZXZlcnNlZCxzY29wZWQsc2VhbWxlc3MsY2hlY2tlZCxtdXRlZCxtdWx0aXBsZSxzZWxlY3RlZGANCik7DQpmdW5jdGlvbiBpbmNsdWRlQm9vbGVhbkF0dHIodmFsdWUpIHsNCiAgcmV0dXJuICEhdmFsdWUgfHwgdmFsdWUgPT09ICIiOw0KfQ0KY29uc3QgaXNLbm93bkh0bWxBdHRyID0gLyogQF9fUFVSRV9fICovIG1ha2VNYXAoDQogIGBhY2NlcHQsYWNjZXB0LWNoYXJzZXQsYWNjZXNza2V5LGFjdGlvbixhbGlnbixhbGxvdyxhbHQsYXN5bmMsYXV0b2NhcGl0YWxpemUsYXV0b2NvbXBsZXRlLGF1dG9mb2N1cyxhdXRvcGxheSxiYWNrZ3JvdW5kLGJnY29sb3IsYm9yZGVyLGJ1ZmZlcmVkLGNhcHR1cmUsY2hhbGxlbmdlLGNoYXJzZXQsY2hlY2tlZCxjaXRlLGNsYXNzLGNvZGUsY29kZWJhc2UsY29sb3IsY29scyxjb2xzcGFuLGNvbnRlbnQsY29udGVudGVkaXRhYmxlLGNvbnRleHRtZW51LGNvbnRyb2xzLGNvb3Jkcyxjcm9zc29yaWdpbixjc3AsZGF0YSxkYXRldGltZSxkZWNvZGluZyxkZWZhdWx0LGRlZmVyLGRpcixkaXJuYW1lLGRpc2FibGVkLGRvd25sb2FkLGRyYWdnYWJsZSxkcm9wem9uZSxlbmN0eXBlLGVudGVya2V5aGludCxmb3IsZm9ybSxmb3JtYWN0aW9uLGZvcm1lbmN0eXBlLGZvcm1tZXRob2QsZm9ybW5vdmFsaWRhdGUsZm9ybXRhcmdldCxoZWFkZXJzLGhlaWdodCxoaWRkZW4saGlnaCxocmVmLGhyZWZsYW5nLGh0dHAtZXF1aXYsaWNvbixpZCxpbXBvcnRhbmNlLGluZXJ0LGludGVncml0eSxpc21hcCxpdGVtcHJvcCxrZXl0eXBlLGtpbmQsbGFiZWwsbGFuZyxsYW5ndWFnZSxsb2FkaW5nLGxpc3QsbG9vcCxsb3csbWFuaWZlc3QsbWF4LG1heGxlbmd0aCxtaW5sZW5ndGgsbWVkaWEsbWluLG11bHRpcGxlLG11dGVkLG5hbWUsbm92YWxpZGF0ZSxvcGVuLG9wdGltdW0scGF0dGVybixwaW5nLHBsYWNlaG9sZGVyLHBvc3RlcixwcmVsb2FkLHJhZGlvZ3JvdXAscmVhZG9ubHkscmVmZXJyZXJwb2xpY3kscmVsLHJlcXVpcmVkLHJldmVyc2VkLHJvd3Mscm93c3BhbixzYW5kYm94LHNjb3BlLHNjb3BlZCxzZWxlY3RlZCxzaGFwZSxzaXplLHNpemVzLHNsb3Qsc3BhbixzcGVsbGNoZWNrLHNyYyxzcmNkb2Msc3JjbGFuZyxzcmNzZXQsc3RhcnQsc3RlcCxzdHlsZSxzdW1tYXJ5LHRhYmluZGV4LHRhcmdldCx0aXRsZSx0cmFuc2xhdGUsdHlwZSx1c2VtYXAsdmFsdWUsd2lkdGgsd3JhcGANCik7DQpjb25zdCBpc0tub3duU3ZnQXR0ciA9IC8qIEBfX1BVUkVfXyAqLyBtYWtlTWFwKA0KICBgeG1sbnMsYWNjZW50LWhlaWdodCxhY2N1bXVsYXRlLGFkZGl0aXZlLGFsaWdubWVudC1iYXNlbGluZSxhbHBoYWJldGljLGFtcGxpdHVkZSxhcmFiaWMtZm9ybSxhc2NlbnQsYXR0cmlidXRlTmFtZSxhdHRyaWJ1dGVUeXBlLGF6aW11dGgsYmFzZUZyZXF1ZW5jeSxiYXNlbGluZS1zaGlmdCxiYXNlUHJvZmlsZSxiYm94LGJlZ2luLGJpYXMsYnksY2FsY01vZGUsY2FwLWhlaWdodCxjbGFzcyxjbGlwLGNsaXBQYXRoVW5pdHMsY2xpcC1wYXRoLGNsaXAtcnVsZSxjb2xvcixjb2xvci1pbnRlcnBvbGF0aW9uLGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycyxjb2xvci1wcm9maWxlLGNvbG9yLXJlbmRlcmluZyxjb250ZW50U2NyaXB0VHlwZSxjb250ZW50U3R5bGVUeXBlLGNyb3Nzb3JpZ2luLGN1cnNvcixjeCxjeSxkLGRlY2VsZXJhdGUsZGVzY2VudCxkaWZmdXNlQ29uc3RhbnQsZGlyZWN0aW9uLGRpc3BsYXksZGl2aXNvcixkb21pbmFudC1iYXNlbGluZSxkdXIsZHgsZHksZWRnZU1vZGUsZWxldmF0aW9uLGVuYWJsZS1iYWNrZ3JvdW5kLGVuZCxleHBvbmVudCxmaWxsLGZpbGwtb3BhY2l0eSxmaWxsLXJ1bGUsZmlsdGVyLGZpbHRlclJlcyxmaWx0ZXJVbml0cyxmbG9vZC1jb2xvcixmbG9vZC1vcGFjaXR5LGZvbnQtZmFtaWx5LGZvbnQtc2l6ZSxmb250LXNpemUtYWRqdXN0LGZvbnQtc3RyZXRjaCxmb250LXN0eWxlLGZvbnQtdmFyaWFudCxmb250LXdlaWdodCxmb3JtYXQsZnJvbSxmcixmeCxmeSxnMSxnMixnbHlwaC1uYW1lLGdseXBoLW9yaWVudGF0aW9uLWhvcml6b250YWwsZ2x5cGgtb3JpZW50YXRpb24tdmVydGljYWwsZ2x5cGhSZWYsZ3JhZGllbnRUcmFuc2Zvcm0sZ3JhZGllbnRVbml0cyxoYW5naW5nLGhlaWdodCxocmVmLGhyZWZsYW5nLGhvcml6LWFkdi14LGhvcml6LW9yaWdpbi14LGlkLGlkZW9ncmFwaGljLGltYWdlLXJlbmRlcmluZyxpbixpbjIsaW50ZXJjZXB0LGssazEsazIsazMsazQsa2VybmVsTWF0cml4LGtlcm5lbFVuaXRMZW5ndGgsa2VybmluZyxrZXlQb2ludHMsa2V5U3BsaW5lcyxrZXlUaW1lcyxsYW5nLGxlbmd0aEFkanVzdCxsZXR0ZXItc3BhY2luZyxsaWdodGluZy1jb2xvcixsaW1pdGluZ0NvbmVBbmdsZSxsb2NhbCxtYXJrZXItZW5kLG1hcmtlci1taWQsbWFya2VyLXN0YXJ0LG1hcmtlckhlaWdodCxtYXJrZXJVbml0cyxtYXJrZXJXaWR0aCxtYXNrLG1hc2tDb250ZW50VW5pdHMsbWFza1VuaXRzLG1hdGhlbWF0aWNhbCxtYXgsbWVkaWEsbWV0aG9kLG1pbixtb2RlLG5hbWUsbnVtT2N0YXZlcyxvZmZzZXQsb3BhY2l0eSxvcGVyYXRvcixvcmRlcixvcmllbnQsb3JpZW50YXRpb24sb3JpZ2luLG92ZXJmbG93LG92ZXJsaW5lLXBvc2l0aW9uLG92ZXJsaW5lLXRoaWNrbmVzcyxwYW5vc2UtMSxwYWludC1vcmRlcixwYXRoLHBhdGhMZW5ndGgscGF0dGVybkNvbnRlbnRVbml0cyxwYXR0ZXJuVHJhbnNmb3JtLHBhdHRlcm5Vbml0cyxwaW5nLHBvaW50ZXItZXZlbnRzLHBvaW50cyxwb2ludHNBdFgscG9pbnRzQXRZLHBvaW50c0F0WixwcmVzZXJ2ZUFscGhhLHByZXNlcnZlQXNwZWN0UmF0aW8scHJpbWl0aXZlVW5pdHMscixyYWRpdXMscmVmZXJyZXJQb2xpY3kscmVmWCxyZWZZLHJlbCxyZW5kZXJpbmctaW50ZW50LHJlcGVhdENvdW50LHJlcGVhdER1cixyZXF1aXJlZEV4dGVuc2lvbnMscmVxdWlyZWRGZWF0dXJlcyxyZXN0YXJ0LHJlc3VsdCxyb3RhdGUscngscnksc2NhbGUsc2VlZCxzaGFwZS1yZW5kZXJpbmcsc2xvcGUsc3BhY2luZyxzcGVjdWxhckNvbnN0YW50LHNwZWN1bGFyRXhwb25lbnQsc3BlZWQsc3ByZWFkTWV0aG9kLHN0YXJ0T2Zmc2V0LHN0ZERldmlhdGlvbixzdGVtaCxzdGVtdixzdGl0Y2hUaWxlcyxzdG9wLWNvbG9yLHN0b3Atb3BhY2l0eSxzdHJpa2V0aHJvdWdoLXBvc2l0aW9uLHN0cmlrZXRocm91Z2gtdGhpY2tuZXNzLHN0cmluZyxzdHJva2Usc3Ryb2tlLWRhc2hhcnJheSxzdHJva2UtZGFzaG9mZnNldCxzdHJva2UtbGluZWNhcCxzdHJva2UtbGluZWpvaW4sc3Ryb2tlLW1pdGVybGltaXQsc3Ryb2tlLW9wYWNpdHksc3Ryb2tlLXdpZHRoLHN0eWxlLHN1cmZhY2VTY2FsZSxzeXN0ZW1MYW5ndWFnZSx0YWJpbmRleCx0YWJsZVZhbHVlcyx0YXJnZXQsdGFyZ2V0WCx0YXJnZXRZLHRleHQtYW5jaG9yLHRleHQtZGVjb3JhdGlvbix0ZXh0LXJlbmRlcmluZyx0ZXh0TGVuZ3RoLHRvLHRyYW5zZm9ybSx0cmFuc2Zvcm0tb3JpZ2luLHR5cGUsdTEsdTIsdW5kZXJsaW5lLXBvc2l0aW9uLHVuZGVybGluZS10aGlja25lc3MsdW5pY29kZSx1bmljb2RlLWJpZGksdW5pY29kZS1yYW5nZSx1bml0cy1wZXItZW0sdi1hbHBoYWJldGljLHYtaGFuZ2luZyx2LWlkZW9ncmFwaGljLHYtbWF0aGVtYXRpY2FsLHZhbHVlcyx2ZWN0b3ItZWZmZWN0LHZlcnNpb24sdmVydC1hZHYteSx2ZXJ0LW9yaWdpbi14LHZlcnQtb3JpZ2luLXksdmlld0JveCx2aWV3VGFyZ2V0LHZpc2liaWxpdHksd2lkdGgsd2lkdGhzLHdvcmQtc3BhY2luZyx3cml0aW5nLW1vZGUseCx4LWhlaWdodCx4MSx4Mix4Q2hhbm5lbFNlbGVjdG9yLHhsaW5rOmFjdHVhdGUseGxpbms6YXJjcm9sZSx4bGluazpocmVmLHhsaW5rOnJvbGUseGxpbms6c2hvdyx4bGluazp0aXRsZSx4bGluazp0eXBlLHhtbG5zOnhsaW5rLHhtbDpiYXNlLHhtbDpsYW5nLHhtbDpzcGFjZSx5LHkxLHkyLHlDaGFubmVsU2VsZWN0b3Iseix6b29tQW5kUGFuYA0KKTsNCmZ1bmN0aW9uIGlzUmVuZGVyYWJsZUF0dHJWYWx1ZSh2YWx1ZSkgew0KICBpZiAodmFsdWUgPT0gbnVsbCkgew0KICAgIHJldHVybiBmYWxzZTsNCiAgfQ0KICBjb25zdCB0eXBlID0gdHlwZW9mIHZhbHVlOw0KICByZXR1cm4gdHlwZSA9PT0gInN0cmluZyIgfHwgdHlwZSA9PT0gIm51bWJlciIgfHwgdHlwZSA9PT0gImJvb2xlYW4iOw0KfQ0KDQpjb25zdCBjc3NWYXJOYW1lRXNjYXBlU3ltYm9sc1JFID0gL1sgISIjJCUmJygpKissLi86Ozw9Pj9AW1xcXF1eYHt8fX5dL2c7DQpmdW5jdGlvbiBnZXRFc2NhcGVkQ3NzVmFyTmFtZShrZXksIGRvdWJsZUVzY2FwZSkgew0KICByZXR1cm4ga2V5LnJlcGxhY2UoDQogICAgY3NzVmFyTmFtZUVzY2FwZVN5bWJvbHNSRSwNCiAgICAocykgPT4gYFxcJHtzfWANCiAgKTsNCn0NCg0KZnVuY3Rpb24gbG9vc2VDb21wYXJlQXJyYXlzKGEsIGIpIHsNCiAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkgcmV0dXJuIGZhbHNlOw0KICBsZXQgZXF1YWwgPSB0cnVlOw0KICBmb3IgKGxldCBpID0gMDsgZXF1YWwgJiYgaSA8IGEubGVuZ3RoOyBpKyspIHsNCiAgICBlcXVhbCA9IGxvb3NlRXF1YWwoYVtpXSwgYltpXSk7DQogIH0NCiAgcmV0dXJuIGVxdWFsOw0KfQ0KZnVuY3Rpb24gbG9vc2VFcXVhbChhLCBiKSB7DQogIGlmIChhID09PSBiKSByZXR1cm4gdHJ1ZTsNCiAgbGV0IGFWYWxpZFR5cGUgPSBpc0RhdGUoYSk7DQogIGxldCBiVmFsaWRUeXBlID0gaXNEYXRlKGIpOw0KICBpZiAoYVZhbGlkVHlwZSB8fCBiVmFsaWRUeXBlKSB7DQogICAgcmV0dXJuIGFWYWxpZFR5cGUgJiYgYlZhbGlkVHlwZSA/IGEuZ2V0VGltZSgpID09PSBiLmdldFRpbWUoKSA6IGZhbHNlOw0KICB9DQogIGFWYWxpZFR5cGUgPSBpc1N5bWJvbChhKTsNCiAgYlZhbGlkVHlwZSA9IGlzU3ltYm9sKGIpOw0KICBpZiAoYVZhbGlkVHlwZSB8fCBiVmFsaWRUeXBlKSB7DQogICAgcmV0dXJuIGEgPT09IGI7DQogIH0NCiAgYVZhbGlkVHlwZSA9IGlzQXJyYXkoYSk7DQogIGJWYWxpZFR5cGUgPSBpc0FycmF5KGIpOw0KICBpZiAoYVZhbGlkVHlwZSB8fCBiVmFsaWRUeXBlKSB7DQogICAgcmV0dXJuIGFWYWxpZFR5cGUgJiYgYlZhbGlkVHlwZSA/IGxvb3NlQ29tcGFyZUFycmF5cyhhLCBiKSA6IGZhbHNlOw0KICB9DQogIGFWYWxpZFR5cGUgPSBpc09iamVjdChhKTsNCiAgYlZhbGlkVHlwZSA9IGlzT2JqZWN0KGIpOw0KICBpZiAoYVZhbGlkVHlwZSB8fCBiVmFsaWRUeXBlKSB7DQogICAgaWYgKCFhVmFsaWRUeXBlIHx8ICFiVmFsaWRUeXBlKSB7DQogICAgICByZXR1cm4gZmFsc2U7DQogICAgfQ0KICAgIGNvbnN0IGFLZXlzQ291bnQgPSBPYmplY3Qua2V5cyhhKS5sZW5ndGg7DQogICAgY29uc3QgYktleXNDb3VudCA9IE9iamVjdC5rZXlzKGIpLmxlbmd0aDsNCiAgICBpZiAoYUtleXNDb3VudCAhPT0gYktleXNDb3VudCkgew0KICAgICAgcmV0dXJuIGZhbHNlOw0KICAgIH0NCiAgICBmb3IgKGNvbnN0IGtleSBpbiBhKSB7DQogICAgICBjb25zdCBhSGFzS2V5ID0gYS5oYXNPd25Qcm9wZXJ0eShrZXkpOw0KICAgICAgY29uc3QgYkhhc0tleSA9IGIuaGFzT3duUHJvcGVydHkoa2V5KTsNCiAgICAgIGlmIChhSGFzS2V5ICYmICFiSGFzS2V5IHx8ICFhSGFzS2V5ICYmIGJIYXNLZXkgfHwgIWxvb3NlRXF1YWwoYVtrZXldLCBiW2tleV0pKSB7DQogICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgcmV0dXJuIFN0cmluZyhhKSA9PT0gU3RyaW5nKGIpOw0KfQ0KZnVuY3Rpb24gbG9vc2VJbmRleE9mKGFyciwgdmFsKSB7DQogIHJldHVybiBhcnIuZmluZEluZGV4KChpdGVtKSA9PiBsb29zZUVxdWFsKGl0ZW0sIHZhbCkpOw0KfQ0KDQpjb25zdCBpc1JlZiQxID0gKHZhbCkgPT4gew0KICByZXR1cm4gISEodmFsICYmIHZhbFsiX192X2lzUmVmIl0gPT09IHRydWUpOw0KfTsNCmNvbnN0IHRvRGlzcGxheVN0cmluZyA9ICh2YWwpID0+IHsNCiAgcmV0dXJuIGlzU3RyaW5nKHZhbCkgPyB2YWwgOiB2YWwgPT0gbnVsbCA/ICIiIDogaXNBcnJheSh2YWwpIHx8IGlzT2JqZWN0KHZhbCkgJiYgKHZhbC50b1N0cmluZyA9PT0gb2JqZWN0VG9TdHJpbmcgfHwgIWlzRnVuY3Rpb24odmFsLnRvU3RyaW5nKSkgPyBpc1JlZiQxKHZhbCkgPyB0b0Rpc3BsYXlTdHJpbmcodmFsLnZhbHVlKSA6IEpTT04uc3RyaW5naWZ5KHZhbCwgcmVwbGFjZXIsIDIpIDogU3RyaW5nKHZhbCk7DQp9Ow0KY29uc3QgcmVwbGFjZXIgPSAoX2tleSwgdmFsKSA9PiB7DQogIGlmIChpc1JlZiQxKHZhbCkpIHsNCiAgICByZXR1cm4gcmVwbGFjZXIoX2tleSwgdmFsLnZhbHVlKTsNCiAgfSBlbHNlIGlmIChpc01hcCh2YWwpKSB7DQogICAgcmV0dXJuIHsNCiAgICAgIFtgTWFwKCR7dmFsLnNpemV9KWBdOiBbLi4udmFsLmVudHJpZXMoKV0ucmVkdWNlKA0KICAgICAgICAoZW50cmllcywgW2tleSwgdmFsMl0sIGkpID0+IHsNCiAgICAgICAgICBlbnRyaWVzW3N0cmluZ2lmeVN5bWJvbChrZXksIGkpICsgIiA9PiJdID0gdmFsMjsNCiAgICAgICAgICByZXR1cm4gZW50cmllczsNCiAgICAgICAgfSwNCiAgICAgICAge30NCiAgICAgICkNCiAgICB9Ow0KICB9IGVsc2UgaWYgKGlzU2V0KHZhbCkpIHsNCiAgICByZXR1cm4gew0KICAgICAgW2BTZXQoJHt2YWwuc2l6ZX0pYF06IFsuLi52YWwudmFsdWVzKCldLm1hcCgodikgPT4gc3RyaW5naWZ5U3ltYm9sKHYpKQ0KICAgIH07DQogIH0gZWxzZSBpZiAoaXNTeW1ib2wodmFsKSkgew0KICAgIHJldHVybiBzdHJpbmdpZnlTeW1ib2wodmFsKTsNCiAgfSBlbHNlIGlmIChpc09iamVjdCh2YWwpICYmICFpc0FycmF5KHZhbCkgJiYgIWlzUGxhaW5PYmplY3QodmFsKSkgew0KICAgIHJldHVybiBTdHJpbmcodmFsKTsNCiAgfQ0KICByZXR1cm4gdmFsOw0KfTsNCmNvbnN0IHN0cmluZ2lmeVN5bWJvbCA9ICh2LCBpID0gIiIpID0+IHsNCiAgdmFyIF9hOw0KICByZXR1cm4gKA0KICAgIC8vIFN5bWJvbC5kZXNjcmlwdGlvbiBpbiBlczIwMTkrIHNvIHdlIG5lZWQgdG8gY2FzdCBoZXJlIHRvIHBhc3MNCiAgICAvLyB0aGUgbGliOiBlczIwMTYgY2hlY2sNCiAgICBpc1N5bWJvbCh2KSA/IGBTeW1ib2woJHsoX2EgPSB2LmRlc2NyaXB0aW9uKSAhPSBudWxsID8gX2EgOiBpfSlgIDogdg0KICApOw0KfTsNCg0KZnVuY3Rpb24gd2FybiQyKG1zZywgLi4uYXJncykgew0KICBjb25zb2xlLndhcm4oYFtWdWUgd2Fybl0gJHttc2d9YCwgLi4uYXJncyk7DQp9DQoNCmxldCBhY3RpdmVFZmZlY3RTY29wZTsNCmNsYXNzIEVmZmVjdFNjb3BlIHsNCiAgY29uc3RydWN0b3IoZGV0YWNoZWQgPSBmYWxzZSkgew0KICAgIHRoaXMuZGV0YWNoZWQgPSBkZXRhY2hlZDsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLl9hY3RpdmUgPSB0cnVlOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbCB0cmFjayBgb25gIGNhbGxzLCBhbGxvdyBgb25gIGNhbGwgbXVsdGlwbGUgdGltZXMNCiAgICAgKi8NCiAgICB0aGlzLl9vbiA9IDA7DQogICAgLyoqDQogICAgICogQGludGVybmFsDQogICAgICovDQogICAgdGhpcy5lZmZlY3RzID0gW107DQogICAgLyoqDQogICAgICogQGludGVybmFsDQogICAgICovDQogICAgdGhpcy5jbGVhbnVwcyA9IFtdOw0KICAgIHRoaXMuX2lzUGF1c2VkID0gZmFsc2U7DQogICAgdGhpcy5wYXJlbnQgPSBhY3RpdmVFZmZlY3RTY29wZTsNCiAgICBpZiAoIWRldGFjaGVkICYmIGFjdGl2ZUVmZmVjdFNjb3BlKSB7DQogICAgICB0aGlzLmluZGV4ID0gKGFjdGl2ZUVmZmVjdFNjb3BlLnNjb3BlcyB8fCAoYWN0aXZlRWZmZWN0U2NvcGUuc2NvcGVzID0gW10pKS5wdXNoKA0KICAgICAgICB0aGlzDQogICAgICApIC0gMTsNCiAgICB9DQogIH0NCiAgZ2V0IGFjdGl2ZSgpIHsNCiAgICByZXR1cm4gdGhpcy5fYWN0aXZlOw0KICB9DQogIHBhdXNlKCkgew0KICAgIGlmICh0aGlzLl9hY3RpdmUpIHsNCiAgICAgIHRoaXMuX2lzUGF1c2VkID0gdHJ1ZTsNCiAgICAgIGxldCBpLCBsOw0KICAgICAgaWYgKHRoaXMuc2NvcGVzKSB7DQogICAgICAgIGZvciAoaSA9IDAsIGwgPSB0aGlzLnNjb3Blcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsNCiAgICAgICAgICB0aGlzLnNjb3Blc1tpXS5wYXVzZSgpOw0KICAgICAgICB9DQogICAgICB9DQogICAgICBmb3IgKGkgPSAwLCBsID0gdGhpcy5lZmZlY3RzLmxlbmd0aDsgaSA8IGw7IGkrKykgew0KICAgICAgICB0aGlzLmVmZmVjdHNbaV0ucGF1c2UoKTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgLyoqDQogICAqIFJlc3VtZXMgdGhlIGVmZmVjdCBzY29wZSwgaW5jbHVkaW5nIGFsbCBjaGlsZCBzY29wZXMgYW5kIGVmZmVjdHMuDQogICAqLw0KICByZXN1bWUoKSB7DQogICAgaWYgKHRoaXMuX2FjdGl2ZSkgew0KICAgICAgaWYgKHRoaXMuX2lzUGF1c2VkKSB7DQogICAgICAgIHRoaXMuX2lzUGF1c2VkID0gZmFsc2U7DQogICAgICAgIGxldCBpLCBsOw0KICAgICAgICBpZiAodGhpcy5zY29wZXMpIHsNCiAgICAgICAgICBmb3IgKGkgPSAwLCBsID0gdGhpcy5zY29wZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7DQogICAgICAgICAgICB0aGlzLnNjb3Blc1tpXS5yZXN1bWUoKTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgZm9yIChpID0gMCwgbCA9IHRoaXMuZWZmZWN0cy5sZW5ndGg7IGkgPCBsOyBpKyspIHsNCiAgICAgICAgICB0aGlzLmVmZmVjdHNbaV0ucmVzdW1lKCk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH0NCiAgcnVuKGZuKSB7DQogICAgaWYgKHRoaXMuX2FjdGl2ZSkgew0KICAgICAgY29uc3QgY3VycmVudEVmZmVjdFNjb3BlID0gYWN0aXZlRWZmZWN0U2NvcGU7DQogICAgICB0cnkgew0KICAgICAgICBhY3RpdmVFZmZlY3RTY29wZSA9IHRoaXM7DQogICAgICAgIHJldHVybiBmbigpOw0KICAgICAgfSBmaW5hbGx5IHsNCiAgICAgICAgYWN0aXZlRWZmZWN0U2NvcGUgPSBjdXJyZW50RWZmZWN0U2NvcGU7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIHdhcm4kMihgY2Fubm90IHJ1biBhbiBpbmFjdGl2ZSBlZmZlY3Qgc2NvcGUuYCk7DQogICAgfQ0KICB9DQogIC8qKg0KICAgKiBUaGlzIHNob3VsZCBvbmx5IGJlIGNhbGxlZCBvbiBub24tZGV0YWNoZWQgc2NvcGVzDQogICAqIEBpbnRlcm5hbA0KICAgKi8NCiAgb24oKSB7DQogICAgaWYgKCsrdGhpcy5fb24gPT09IDEpIHsNCiAgICAgIHRoaXMucHJldlNjb3BlID0gYWN0aXZlRWZmZWN0U2NvcGU7DQogICAgICBhY3RpdmVFZmZlY3RTY29wZSA9IHRoaXM7DQogICAgfQ0KICB9DQogIC8qKg0KICAgKiBUaGlzIHNob3VsZCBvbmx5IGJlIGNhbGxlZCBvbiBub24tZGV0YWNoZWQgc2NvcGVzDQogICAqIEBpbnRlcm5hbA0KICAgKi8NCiAgb2ZmKCkgew0KICAgIGlmICh0aGlzLl9vbiA+IDAgJiYgLS10aGlzLl9vbiA9PT0gMCkgew0KICAgICAgYWN0aXZlRWZmZWN0U2NvcGUgPSB0aGlzLnByZXZTY29wZTsNCiAgICAgIHRoaXMucHJldlNjb3BlID0gdm9pZCAwOw0KICAgIH0NCiAgfQ0KICBzdG9wKGZyb21QYXJlbnQpIHsNCiAgICBpZiAodGhpcy5fYWN0aXZlKSB7DQogICAgICB0aGlzLl9hY3RpdmUgPSBmYWxzZTsNCiAgICAgIGxldCBpLCBsOw0KICAgICAgZm9yIChpID0gMCwgbCA9IHRoaXMuZWZmZWN0cy5sZW5ndGg7IGkgPCBsOyBpKyspIHsNCiAgICAgICAgdGhpcy5lZmZlY3RzW2ldLnN0b3AoKTsNCiAgICAgIH0NCiAgICAgIHRoaXMuZWZmZWN0cy5sZW5ndGggPSAwOw0KICAgICAgZm9yIChpID0gMCwgbCA9IHRoaXMuY2xlYW51cHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7DQogICAgICAgIHRoaXMuY2xlYW51cHNbaV0oKTsNCiAgICAgIH0NCiAgICAgIHRoaXMuY2xlYW51cHMubGVuZ3RoID0gMDsNCiAgICAgIGlmICh0aGlzLnNjb3Blcykgew0KICAgICAgICBmb3IgKGkgPSAwLCBsID0gdGhpcy5zY29wZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7DQogICAgICAgICAgdGhpcy5zY29wZXNbaV0uc3RvcCh0cnVlKTsNCiAgICAgICAgfQ0KICAgICAgICB0aGlzLnNjb3Blcy5sZW5ndGggPSAwOw0KICAgICAgfQ0KICAgICAgaWYgKCF0aGlzLmRldGFjaGVkICYmIHRoaXMucGFyZW50ICYmICFmcm9tUGFyZW50KSB7DQogICAgICAgIGNvbnN0IGxhc3QgPSB0aGlzLnBhcmVudC5zY29wZXMucG9wKCk7DQogICAgICAgIGlmIChsYXN0ICYmIGxhc3QgIT09IHRoaXMpIHsNCiAgICAgICAgICB0aGlzLnBhcmVudC5zY29wZXNbdGhpcy5pbmRleF0gPSBsYXN0Ow0KICAgICAgICAgIGxhc3QuaW5kZXggPSB0aGlzLmluZGV4Ow0KICAgICAgICB9DQogICAgICB9DQogICAgICB0aGlzLnBhcmVudCA9IHZvaWQgMDsNCiAgICB9DQogIH0NCn0NCmZ1bmN0aW9uIGVmZmVjdFNjb3BlKGRldGFjaGVkKSB7DQogIHJldHVybiBuZXcgRWZmZWN0U2NvcGUoZGV0YWNoZWQpOw0KfQ0KZnVuY3Rpb24gZ2V0Q3VycmVudFNjb3BlKCkgew0KICByZXR1cm4gYWN0aXZlRWZmZWN0U2NvcGU7DQp9DQpmdW5jdGlvbiBvblNjb3BlRGlzcG9zZShmbiwgZmFpbFNpbGVudGx5ID0gZmFsc2UpIHsNCiAgaWYgKGFjdGl2ZUVmZmVjdFNjb3BlKSB7DQogICAgYWN0aXZlRWZmZWN0U2NvcGUuY2xlYW51cHMucHVzaChmbik7DQogIH0gZWxzZSBpZiAoIWZhaWxTaWxlbnRseSkgew0KICAgIHdhcm4kMigNCiAgICAgIGBvblNjb3BlRGlzcG9zZSgpIGlzIGNhbGxlZCB3aGVuIHRoZXJlIGlzIG5vIGFjdGl2ZSBlZmZlY3Qgc2NvcGUgdG8gYmUgYXNzb2NpYXRlZCB3aXRoLmANCiAgICApOw0KICB9DQp9DQoNCmxldCBhY3RpdmVTdWI7DQpjb25zdCBwYXVzZWRRdWV1ZUVmZmVjdHMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtTZXQoKTsNCmNsYXNzIFJlYWN0aXZlRWZmZWN0IHsNCiAgY29uc3RydWN0b3IoZm4pIHsNCiAgICB0aGlzLmZuID0gZm47DQogICAgLyoqDQogICAgICogQGludGVybmFsDQogICAgICovDQogICAgdGhpcy5kZXBzID0gdm9pZCAwOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuZGVwc1RhaWwgPSB2b2lkIDA7DQogICAgLyoqDQogICAgICogQGludGVybmFsDQogICAgICovDQogICAgdGhpcy5mbGFncyA9IDEgfCA0Ow0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMubmV4dCA9IHZvaWQgMDsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLmNsZWFudXAgPSB2b2lkIDA7DQogICAgdGhpcy5zY2hlZHVsZXIgPSB2b2lkIDA7DQogICAgaWYgKGFjdGl2ZUVmZmVjdFNjb3BlICYmIGFjdGl2ZUVmZmVjdFNjb3BlLmFjdGl2ZSkgew0KICAgICAgYWN0aXZlRWZmZWN0U2NvcGUuZWZmZWN0cy5wdXNoKHRoaXMpOw0KICAgIH0NCiAgfQ0KICBwYXVzZSgpIHsNCiAgICB0aGlzLmZsYWdzIHw9IDY0Ow0KICB9DQogIHJlc3VtZSgpIHsNCiAgICBpZiAodGhpcy5mbGFncyAmIDY0KSB7DQogICAgICB0aGlzLmZsYWdzICY9IC02NTsNCiAgICAgIGlmIChwYXVzZWRRdWV1ZUVmZmVjdHMuaGFzKHRoaXMpKSB7DQogICAgICAgIHBhdXNlZFF1ZXVlRWZmZWN0cy5kZWxldGUodGhpcyk7DQogICAgICAgIHRoaXMudHJpZ2dlcigpOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICAvKioNCiAgICogQGludGVybmFsDQogICAqLw0KICBub3RpZnkoKSB7DQogICAgaWYgKHRoaXMuZmxhZ3MgJiAyICYmICEodGhpcy5mbGFncyAmIDMyKSkgew0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBpZiAoISh0aGlzLmZsYWdzICYgOCkpIHsNCiAgICAgIGJhdGNoKHRoaXMpOw0KICAgIH0NCiAgfQ0KICBydW4oKSB7DQogICAgaWYgKCEodGhpcy5mbGFncyAmIDEpKSB7DQogICAgICByZXR1cm4gdGhpcy5mbigpOw0KICAgIH0NCiAgICB0aGlzLmZsYWdzIHw9IDI7DQogICAgY2xlYW51cEVmZmVjdCh0aGlzKTsNCiAgICBwcmVwYXJlRGVwcyh0aGlzKTsNCiAgICBjb25zdCBwcmV2RWZmZWN0ID0gYWN0aXZlU3ViOw0KICAgIGNvbnN0IHByZXZTaG91bGRUcmFjayA9IHNob3VsZFRyYWNrOw0KICAgIGFjdGl2ZVN1YiA9IHRoaXM7DQogICAgc2hvdWxkVHJhY2sgPSB0cnVlOw0KICAgIHRyeSB7DQogICAgICByZXR1cm4gdGhpcy5mbigpOw0KICAgIH0gZmluYWxseSB7DQogICAgICBpZiAoYWN0aXZlU3ViICE9PSB0aGlzKSB7DQogICAgICAgIHdhcm4kMigNCiAgICAgICAgICAiQWN0aXZlIGVmZmVjdCB3YXMgbm90IHJlc3RvcmVkIGNvcnJlY3RseSAtIHRoaXMgaXMgbGlrZWx5IGEgVnVlIGludGVybmFsIGJ1Zy4iDQogICAgICAgICk7DQogICAgICB9DQogICAgICBjbGVhbnVwRGVwcyh0aGlzKTsNCiAgICAgIGFjdGl2ZVN1YiA9IHByZXZFZmZlY3Q7DQogICAgICBzaG91bGRUcmFjayA9IHByZXZTaG91bGRUcmFjazsNCiAgICAgIHRoaXMuZmxhZ3MgJj0gLTM7DQogICAgfQ0KICB9DQogIHN0b3AoKSB7DQogICAgaWYgKHRoaXMuZmxhZ3MgJiAxKSB7DQogICAgICBmb3IgKGxldCBsaW5rID0gdGhpcy5kZXBzOyBsaW5rOyBsaW5rID0gbGluay5uZXh0RGVwKSB7DQogICAgICAgIHJlbW92ZVN1YihsaW5rKTsNCiAgICAgIH0NCiAgICAgIHRoaXMuZGVwcyA9IHRoaXMuZGVwc1RhaWwgPSB2b2lkIDA7DQogICAgICBjbGVhbnVwRWZmZWN0KHRoaXMpOw0KICAgICAgdGhpcy5vblN0b3AgJiYgdGhpcy5vblN0b3AoKTsNCiAgICAgIHRoaXMuZmxhZ3MgJj0gLTI7DQogICAgfQ0KICB9DQogIHRyaWdnZXIoKSB7DQogICAgaWYgKHRoaXMuZmxhZ3MgJiA2NCkgew0KICAgICAgcGF1c2VkUXVldWVFZmZlY3RzLmFkZCh0aGlzKTsNCiAgICB9IGVsc2UgaWYgKHRoaXMuc2NoZWR1bGVyKSB7DQogICAgICB0aGlzLnNjaGVkdWxlcigpOw0KICAgIH0gZWxzZSB7DQogICAgICB0aGlzLnJ1bklmRGlydHkoKTsNCiAgICB9DQogIH0NCiAgLyoqDQogICAqIEBpbnRlcm5hbA0KICAgKi8NCiAgcnVuSWZEaXJ0eSgpIHsNCiAgICBpZiAoaXNEaXJ0eSh0aGlzKSkgew0KICAgICAgdGhpcy5ydW4oKTsNCiAgICB9DQogIH0NCiAgZ2V0IGRpcnR5KCkgew0KICAgIHJldHVybiBpc0RpcnR5KHRoaXMpOw0KICB9DQp9DQpsZXQgYmF0Y2hEZXB0aCA9IDA7DQpsZXQgYmF0Y2hlZFN1YjsNCmxldCBiYXRjaGVkQ29tcHV0ZWQ7DQpmdW5jdGlvbiBiYXRjaChzdWIsIGlzQ29tcHV0ZWQgPSBmYWxzZSkgew0KICBzdWIuZmxhZ3MgfD0gODsNCiAgaWYgKGlzQ29tcHV0ZWQpIHsNCiAgICBzdWIubmV4dCA9IGJhdGNoZWRDb21wdXRlZDsNCiAgICBiYXRjaGVkQ29tcHV0ZWQgPSBzdWI7DQogICAgcmV0dXJuOw0KICB9DQogIHN1Yi5uZXh0ID0gYmF0Y2hlZFN1YjsNCiAgYmF0Y2hlZFN1YiA9IHN1YjsNCn0NCmZ1bmN0aW9uIHN0YXJ0QmF0Y2goKSB7DQogIGJhdGNoRGVwdGgrKzsNCn0NCmZ1bmN0aW9uIGVuZEJhdGNoKCkgew0KICBpZiAoLS1iYXRjaERlcHRoID4gMCkgew0KICAgIHJldHVybjsNCiAgfQ0KICBpZiAoYmF0Y2hlZENvbXB1dGVkKSB7DQogICAgbGV0IGUgPSBiYXRjaGVkQ29tcHV0ZWQ7DQogICAgYmF0Y2hlZENvbXB1dGVkID0gdm9pZCAwOw0KICAgIHdoaWxlIChlKSB7DQogICAgICBjb25zdCBuZXh0ID0gZS5uZXh0Ow0KICAgICAgZS5uZXh0ID0gdm9pZCAwOw0KICAgICAgZS5mbGFncyAmPSAtOTsNCiAgICAgIGUgPSBuZXh0Ow0KICAgIH0NCiAgfQ0KICBsZXQgZXJyb3I7DQogIHdoaWxlIChiYXRjaGVkU3ViKSB7DQogICAgbGV0IGUgPSBiYXRjaGVkU3ViOw0KICAgIGJhdGNoZWRTdWIgPSB2b2lkIDA7DQogICAgd2hpbGUgKGUpIHsNCiAgICAgIGNvbnN0IG5leHQgPSBlLm5leHQ7DQogICAgICBlLm5leHQgPSB2b2lkIDA7DQogICAgICBlLmZsYWdzICY9IC05Ow0KICAgICAgaWYgKGUuZmxhZ3MgJiAxKSB7DQogICAgICAgIHRyeSB7DQogICAgICAgICAgOw0KICAgICAgICAgIGUudHJpZ2dlcigpOw0KICAgICAgICB9IGNhdGNoIChlcnIpIHsNCiAgICAgICAgICBpZiAoIWVycm9yKSBlcnJvciA9IGVycjsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgZSA9IG5leHQ7DQogICAgfQ0KICB9DQogIGlmIChlcnJvcikgdGhyb3cgZXJyb3I7DQp9DQpmdW5jdGlvbiBwcmVwYXJlRGVwcyhzdWIpIHsNCiAgZm9yIChsZXQgbGluayA9IHN1Yi5kZXBzOyBsaW5rOyBsaW5rID0gbGluay5uZXh0RGVwKSB7DQogICAgbGluay52ZXJzaW9uID0gLTE7DQogICAgbGluay5wcmV2QWN0aXZlTGluayA9IGxpbmsuZGVwLmFjdGl2ZUxpbms7DQogICAgbGluay5kZXAuYWN0aXZlTGluayA9IGxpbms7DQogIH0NCn0NCmZ1bmN0aW9uIGNsZWFudXBEZXBzKHN1Yikgew0KICBsZXQgaGVhZDsNCiAgbGV0IHRhaWwgPSBzdWIuZGVwc1RhaWw7DQogIGxldCBsaW5rID0gdGFpbDsNCiAgd2hpbGUgKGxpbmspIHsNCiAgICBjb25zdCBwcmV2ID0gbGluay5wcmV2RGVwOw0KICAgIGlmIChsaW5rLnZlcnNpb24gPT09IC0xKSB7DQogICAgICBpZiAobGluayA9PT0gdGFpbCkgdGFpbCA9IHByZXY7DQogICAgICByZW1vdmVTdWIobGluayk7DQogICAgICByZW1vdmVEZXAobGluayk7DQogICAgfSBlbHNlIHsNCiAgICAgIGhlYWQgPSBsaW5rOw0KICAgIH0NCiAgICBsaW5rLmRlcC5hY3RpdmVMaW5rID0gbGluay5wcmV2QWN0aXZlTGluazsNCiAgICBsaW5rLnByZXZBY3RpdmVMaW5rID0gdm9pZCAwOw0KICAgIGxpbmsgPSBwcmV2Ow0KICB9DQogIHN1Yi5kZXBzID0gaGVhZDsNCiAgc3ViLmRlcHNUYWlsID0gdGFpbDsNCn0NCmZ1bmN0aW9uIGlzRGlydHkoc3ViKSB7DQogIGZvciAobGV0IGxpbmsgPSBzdWIuZGVwczsgbGluazsgbGluayA9IGxpbmsubmV4dERlcCkgew0KICAgIGlmIChsaW5rLmRlcC52ZXJzaW9uICE9PSBsaW5rLnZlcnNpb24gfHwgbGluay5kZXAuY29tcHV0ZWQgJiYgKHJlZnJlc2hDb21wdXRlZChsaW5rLmRlcC5jb21wdXRlZCkgfHwgbGluay5kZXAudmVyc2lvbiAhPT0gbGluay52ZXJzaW9uKSkgew0KICAgICAgcmV0dXJuIHRydWU7DQogICAgfQ0KICB9DQogIGlmIChzdWIuX2RpcnR5KSB7DQogICAgcmV0dXJuIHRydWU7DQogIH0NCiAgcmV0dXJuIGZhbHNlOw0KfQ0KZnVuY3Rpb24gcmVmcmVzaENvbXB1dGVkKGNvbXB1dGVkKSB7DQogIGlmIChjb21wdXRlZC5mbGFncyAmIDQgJiYgIShjb21wdXRlZC5mbGFncyAmIDE2KSkgew0KICAgIHJldHVybjsNCiAgfQ0KICBjb21wdXRlZC5mbGFncyAmPSAtMTc7DQogIGlmIChjb21wdXRlZC5nbG9iYWxWZXJzaW9uID09PSBnbG9iYWxWZXJzaW9uKSB7DQogICAgcmV0dXJuOw0KICB9DQogIGNvbXB1dGVkLmdsb2JhbFZlcnNpb24gPSBnbG9iYWxWZXJzaW9uOw0KICBpZiAoIWNvbXB1dGVkLmlzU1NSICYmIGNvbXB1dGVkLmZsYWdzICYgMTI4ICYmICghY29tcHV0ZWQuZGVwcyAmJiAhY29tcHV0ZWQuX2RpcnR5IHx8ICFpc0RpcnR5KGNvbXB1dGVkKSkpIHsNCiAgICByZXR1cm47DQogIH0NCiAgY29tcHV0ZWQuZmxhZ3MgfD0gMjsNCiAgY29uc3QgZGVwID0gY29tcHV0ZWQuZGVwOw0KICBjb25zdCBwcmV2U3ViID0gYWN0aXZlU3ViOw0KICBjb25zdCBwcmV2U2hvdWxkVHJhY2sgPSBzaG91bGRUcmFjazsNCiAgYWN0aXZlU3ViID0gY29tcHV0ZWQ7DQogIHNob3VsZFRyYWNrID0gdHJ1ZTsNCiAgdHJ5IHsNCiAgICBwcmVwYXJlRGVwcyhjb21wdXRlZCk7DQogICAgY29uc3QgdmFsdWUgPSBjb21wdXRlZC5mbihjb21wdXRlZC5fdmFsdWUpOw0KICAgIGlmIChkZXAudmVyc2lvbiA9PT0gMCB8fCBoYXNDaGFuZ2VkKHZhbHVlLCBjb21wdXRlZC5fdmFsdWUpKSB7DQogICAgICBjb21wdXRlZC5mbGFncyB8PSAxMjg7DQogICAgICBjb21wdXRlZC5fdmFsdWUgPSB2YWx1ZTsNCiAgICAgIGRlcC52ZXJzaW9uKys7DQogICAgfQ0KICB9IGNhdGNoIChlcnIpIHsNCiAgICBkZXAudmVyc2lvbisrOw0KICAgIHRocm93IGVycjsNCiAgfSBmaW5hbGx5IHsNCiAgICBhY3RpdmVTdWIgPSBwcmV2U3ViOw0KICAgIHNob3VsZFRyYWNrID0gcHJldlNob3VsZFRyYWNrOw0KICAgIGNsZWFudXBEZXBzKGNvbXB1dGVkKTsNCiAgICBjb21wdXRlZC5mbGFncyAmPSAtMzsNCiAgfQ0KfQ0KZnVuY3Rpb24gcmVtb3ZlU3ViKGxpbmssIHNvZnQgPSBmYWxzZSkgew0KICBjb25zdCB7IGRlcCwgcHJldlN1YiwgbmV4dFN1YiB9ID0gbGluazsNCiAgaWYgKHByZXZTdWIpIHsNCiAgICBwcmV2U3ViLm5leHRTdWIgPSBuZXh0U3ViOw0KICAgIGxpbmsucHJldlN1YiA9IHZvaWQgMDsNCiAgfQ0KICBpZiAobmV4dFN1Yikgew0KICAgIG5leHRTdWIucHJldlN1YiA9IHByZXZTdWI7DQogICAgbGluay5uZXh0U3ViID0gdm9pZCAwOw0KICB9DQogIGlmIChkZXAuc3Vic0hlYWQgPT09IGxpbmspIHsNCiAgICBkZXAuc3Vic0hlYWQgPSBuZXh0U3ViOw0KICB9DQogIGlmIChkZXAuc3VicyA9PT0gbGluaykgew0KICAgIGRlcC5zdWJzID0gcHJldlN1YjsNCiAgICBpZiAoIXByZXZTdWIgJiYgZGVwLmNvbXB1dGVkKSB7DQogICAgICBkZXAuY29tcHV0ZWQuZmxhZ3MgJj0gLTU7DQogICAgICBmb3IgKGxldCBsID0gZGVwLmNvbXB1dGVkLmRlcHM7IGw7IGwgPSBsLm5leHREZXApIHsNCiAgICAgICAgcmVtb3ZlU3ViKGwsIHRydWUpOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICBpZiAoIXNvZnQgJiYgIS0tZGVwLnNjICYmIGRlcC5tYXApIHsNCiAgICBkZXAubWFwLmRlbGV0ZShkZXAua2V5KTsNCiAgfQ0KfQ0KZnVuY3Rpb24gcmVtb3ZlRGVwKGxpbmspIHsNCiAgY29uc3QgeyBwcmV2RGVwLCBuZXh0RGVwIH0gPSBsaW5rOw0KICBpZiAocHJldkRlcCkgew0KICAgIHByZXZEZXAubmV4dERlcCA9IG5leHREZXA7DQogICAgbGluay5wcmV2RGVwID0gdm9pZCAwOw0KICB9DQogIGlmIChuZXh0RGVwKSB7DQogICAgbmV4dERlcC5wcmV2RGVwID0gcHJldkRlcDsNCiAgICBsaW5rLm5leHREZXAgPSB2b2lkIDA7DQogIH0NCn0NCmZ1bmN0aW9uIGVmZmVjdChmbiwgb3B0aW9ucykgew0KICBpZiAoZm4uZWZmZWN0IGluc3RhbmNlb2YgUmVhY3RpdmVFZmZlY3QpIHsNCiAgICBmbiA9IGZuLmVmZmVjdC5mbjsNCiAgfQ0KICBjb25zdCBlID0gbmV3IFJlYWN0aXZlRWZmZWN0KGZuKTsNCiAgaWYgKG9wdGlvbnMpIHsNCiAgICBleHRlbmQoZSwgb3B0aW9ucyk7DQogIH0NCiAgdHJ5IHsNCiAgICBlLnJ1bigpOw0KICB9IGNhdGNoIChlcnIpIHsNCiAgICBlLnN0b3AoKTsNCiAgICB0aHJvdyBlcnI7DQogIH0NCiAgY29uc3QgcnVubmVyID0gZS5ydW4uYmluZChlKTsNCiAgcnVubmVyLmVmZmVjdCA9IGU7DQogIHJldHVybiBydW5uZXI7DQp9DQpmdW5jdGlvbiBzdG9wKHJ1bm5lcikgew0KICBydW5uZXIuZWZmZWN0LnN0b3AoKTsNCn0NCmxldCBzaG91bGRUcmFjayA9IHRydWU7DQpjb25zdCB0cmFja1N0YWNrID0gW107DQpmdW5jdGlvbiBwYXVzZVRyYWNraW5nKCkgew0KICB0cmFja1N0YWNrLnB1c2goc2hvdWxkVHJhY2spOw0KICBzaG91bGRUcmFjayA9IGZhbHNlOw0KfQ0KZnVuY3Rpb24gcmVzZXRUcmFja2luZygpIHsNCiAgY29uc3QgbGFzdCA9IHRyYWNrU3RhY2sucG9wKCk7DQogIHNob3VsZFRyYWNrID0gbGFzdCA9PT0gdm9pZCAwID8gdHJ1ZSA6IGxhc3Q7DQp9DQpmdW5jdGlvbiBjbGVhbnVwRWZmZWN0KGUpIHsNCiAgY29uc3QgeyBjbGVhbnVwIH0gPSBlOw0KICBlLmNsZWFudXAgPSB2b2lkIDA7DQogIGlmIChjbGVhbnVwKSB7DQogICAgY29uc3QgcHJldlN1YiA9IGFjdGl2ZVN1YjsNCiAgICBhY3RpdmVTdWIgPSB2b2lkIDA7DQogICAgdHJ5IHsNCiAgICAgIGNsZWFudXAoKTsNCiAgICB9IGZpbmFsbHkgew0KICAgICAgYWN0aXZlU3ViID0gcHJldlN1YjsNCiAgICB9DQogIH0NCn0NCg0KbGV0IGdsb2JhbFZlcnNpb24gPSAwOw0KY2xhc3MgTGluayB7DQogIGNvbnN0cnVjdG9yKHN1YiwgZGVwKSB7DQogICAgdGhpcy5zdWIgPSBzdWI7DQogICAgdGhpcy5kZXAgPSBkZXA7DQogICAgdGhpcy52ZXJzaW9uID0gZGVwLnZlcnNpb247DQogICAgdGhpcy5uZXh0RGVwID0gdGhpcy5wcmV2RGVwID0gdGhpcy5uZXh0U3ViID0gdGhpcy5wcmV2U3ViID0gdGhpcy5wcmV2QWN0aXZlTGluayA9IHZvaWQgMDsNCiAgfQ0KfQ0KY2xhc3MgRGVwIHsNCiAgLy8gVE9ETyBpc29sYXRlZERlY2xhcmF0aW9ucyAiX192X3NraXAiDQogIGNvbnN0cnVjdG9yKGNvbXB1dGVkKSB7DQogICAgdGhpcy5jb21wdXRlZCA9IGNvbXB1dGVkOw0KICAgIHRoaXMudmVyc2lvbiA9IDA7DQogICAgLyoqDQogICAgICogTGluayBiZXR3ZWVuIHRoaXMgZGVwIGFuZCB0aGUgY3VycmVudCBhY3RpdmUgZWZmZWN0DQogICAgICovDQogICAgdGhpcy5hY3RpdmVMaW5rID0gdm9pZCAwOw0KICAgIC8qKg0KICAgICAqIERvdWJseSBsaW5rZWQgbGlzdCByZXByZXNlbnRpbmcgdGhlIHN1YnNjcmliaW5nIGVmZmVjdHMgKHRhaWwpDQogICAgICovDQogICAgdGhpcy5zdWJzID0gdm9pZCAwOw0KICAgIC8qKg0KICAgICAqIEZvciBvYmplY3QgcHJvcGVydHkgZGVwcyBjbGVhbnVwDQogICAgICovDQogICAgdGhpcy5tYXAgPSB2b2lkIDA7DQogICAgdGhpcy5rZXkgPSB2b2lkIDA7DQogICAgLyoqDQogICAgICogU3Vic2NyaWJlciBjb3VudGVyDQogICAgICovDQogICAgdGhpcy5zYyA9IDA7DQogICAgLyoqDQogICAgICogQGludGVybmFsDQogICAgICovDQogICAgdGhpcy5fX3Zfc2tpcCA9IHRydWU7DQogICAgew0KICAgICAgdGhpcy5zdWJzSGVhZCA9IHZvaWQgMDsNCiAgICB9DQogIH0NCiAgdHJhY2soZGVidWdJbmZvKSB7DQogICAgaWYgKCFhY3RpdmVTdWIgfHwgIXNob3VsZFRyYWNrIHx8IGFjdGl2ZVN1YiA9PT0gdGhpcy5jb21wdXRlZCkgew0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBsZXQgbGluayA9IHRoaXMuYWN0aXZlTGluazsNCiAgICBpZiAobGluayA9PT0gdm9pZCAwIHx8IGxpbmsuc3ViICE9PSBhY3RpdmVTdWIpIHsNCiAgICAgIGxpbmsgPSB0aGlzLmFjdGl2ZUxpbmsgPSBuZXcgTGluayhhY3RpdmVTdWIsIHRoaXMpOw0KICAgICAgaWYgKCFhY3RpdmVTdWIuZGVwcykgew0KICAgICAgICBhY3RpdmVTdWIuZGVwcyA9IGFjdGl2ZVN1Yi5kZXBzVGFpbCA9IGxpbms7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBsaW5rLnByZXZEZXAgPSBhY3RpdmVTdWIuZGVwc1RhaWw7DQogICAgICAgIGFjdGl2ZVN1Yi5kZXBzVGFpbC5uZXh0RGVwID0gbGluazsNCiAgICAgICAgYWN0aXZlU3ViLmRlcHNUYWlsID0gbGluazsNCiAgICAgIH0NCiAgICAgIGFkZFN1YihsaW5rKTsNCiAgICB9IGVsc2UgaWYgKGxpbmsudmVyc2lvbiA9PT0gLTEpIHsNCiAgICAgIGxpbmsudmVyc2lvbiA9IHRoaXMudmVyc2lvbjsNCiAgICAgIGlmIChsaW5rLm5leHREZXApIHsNCiAgICAgICAgY29uc3QgbmV4dCA9IGxpbmsubmV4dERlcDsNCiAgICAgICAgbmV4dC5wcmV2RGVwID0gbGluay5wcmV2RGVwOw0KICAgICAgICBpZiAobGluay5wcmV2RGVwKSB7DQogICAgICAgICAgbGluay5wcmV2RGVwLm5leHREZXAgPSBuZXh0Ow0KICAgICAgICB9DQogICAgICAgIGxpbmsucHJldkRlcCA9IGFjdGl2ZVN1Yi5kZXBzVGFpbDsNCiAgICAgICAgbGluay5uZXh0RGVwID0gdm9pZCAwOw0KICAgICAgICBhY3RpdmVTdWIuZGVwc1RhaWwubmV4dERlcCA9IGxpbms7DQogICAgICAgIGFjdGl2ZVN1Yi5kZXBzVGFpbCA9IGxpbms7DQogICAgICAgIGlmIChhY3RpdmVTdWIuZGVwcyA9PT0gbGluaykgew0KICAgICAgICAgIGFjdGl2ZVN1Yi5kZXBzID0gbmV4dDsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgICBpZiAoYWN0aXZlU3ViLm9uVHJhY2spIHsNCiAgICAgIGFjdGl2ZVN1Yi5vblRyYWNrKA0KICAgICAgICBleHRlbmQoDQogICAgICAgICAgew0KICAgICAgICAgICAgZWZmZWN0OiBhY3RpdmVTdWINCiAgICAgICAgICB9LA0KICAgICAgICAgIGRlYnVnSW5mbw0KICAgICAgICApDQogICAgICApOw0KICAgIH0NCiAgICByZXR1cm4gbGluazsNCiAgfQ0KICB0cmlnZ2VyKGRlYnVnSW5mbykgew0KICAgIHRoaXMudmVyc2lvbisrOw0KICAgIGdsb2JhbFZlcnNpb24rKzsNCiAgICB0aGlzLm5vdGlmeShkZWJ1Z0luZm8pOw0KICB9DQogIG5vdGlmeShkZWJ1Z0luZm8pIHsNCiAgICBzdGFydEJhdGNoKCk7DQogICAgdHJ5IHsNCiAgICAgIGlmICh0cnVlKSB7DQogICAgICAgIGZvciAobGV0IGhlYWQgPSB0aGlzLnN1YnNIZWFkOyBoZWFkOyBoZWFkID0gaGVhZC5uZXh0U3ViKSB7DQogICAgICAgICAgaWYgKGhlYWQuc3ViLm9uVHJpZ2dlciAmJiAhKGhlYWQuc3ViLmZsYWdzICYgOCkpIHsNCiAgICAgICAgICAgIGhlYWQuc3ViLm9uVHJpZ2dlcigNCiAgICAgICAgICAgICAgZXh0ZW5kKA0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgIGVmZmVjdDogaGVhZC5zdWINCiAgICAgICAgICAgICAgICB9LA0KICAgICAgICAgICAgICAgIGRlYnVnSW5mbw0KICAgICAgICAgICAgICApDQogICAgICAgICAgICApOw0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgZm9yIChsZXQgbGluayA9IHRoaXMuc3ViczsgbGluazsgbGluayA9IGxpbmsucHJldlN1Yikgew0KICAgICAgICBpZiAobGluay5zdWIubm90aWZ5KCkpIHsNCiAgICAgICAgICA7DQogICAgICAgICAgbGluay5zdWIuZGVwLm5vdGlmeSgpOw0KICAgICAgICB9DQogICAgICB9DQogICAgfSBmaW5hbGx5IHsNCiAgICAgIGVuZEJhdGNoKCk7DQogICAgfQ0KICB9DQp9DQpmdW5jdGlvbiBhZGRTdWIobGluaykgew0KICBsaW5rLmRlcC5zYysrOw0KICBpZiAobGluay5zdWIuZmxhZ3MgJiA0KSB7DQogICAgY29uc3QgY29tcHV0ZWQgPSBsaW5rLmRlcC5jb21wdXRlZDsNCiAgICBpZiAoY29tcHV0ZWQgJiYgIWxpbmsuZGVwLnN1YnMpIHsNCiAgICAgIGNvbXB1dGVkLmZsYWdzIHw9IDQgfCAxNjsNCiAgICAgIGZvciAobGV0IGwgPSBjb21wdXRlZC5kZXBzOyBsOyBsID0gbC5uZXh0RGVwKSB7DQogICAgICAgIGFkZFN1YihsKTsNCiAgICAgIH0NCiAgICB9DQogICAgY29uc3QgY3VycmVudFRhaWwgPSBsaW5rLmRlcC5zdWJzOw0KICAgIGlmIChjdXJyZW50VGFpbCAhPT0gbGluaykgew0KICAgICAgbGluay5wcmV2U3ViID0gY3VycmVudFRhaWw7DQogICAgICBpZiAoY3VycmVudFRhaWwpIGN1cnJlbnRUYWlsLm5leHRTdWIgPSBsaW5rOw0KICAgIH0NCiAgICBpZiAobGluay5kZXAuc3Vic0hlYWQgPT09IHZvaWQgMCkgew0KICAgICAgbGluay5kZXAuc3Vic0hlYWQgPSBsaW5rOw0KICAgIH0NCiAgICBsaW5rLmRlcC5zdWJzID0gbGluazsNCiAgfQ0KfQ0KY29uc3QgdGFyZ2V0TWFwID0gLyogQF9fUFVSRV9fICovIG5ldyBXZWFrTWFwKCk7DQpjb25zdCBJVEVSQVRFX0tFWSA9IFN5bWJvbCgNCiAgIk9iamVjdCBpdGVyYXRlIiANCik7DQpjb25zdCBNQVBfS0VZX0lURVJBVEVfS0VZID0gU3ltYm9sKA0KICAiTWFwIGtleXMgaXRlcmF0ZSIgDQopOw0KY29uc3QgQVJSQVlfSVRFUkFURV9LRVkgPSBTeW1ib2woDQogICJBcnJheSBpdGVyYXRlIiANCik7DQpmdW5jdGlvbiB0cmFjayh0YXJnZXQsIHR5cGUsIGtleSkgew0KICBpZiAoc2hvdWxkVHJhY2sgJiYgYWN0aXZlU3ViKSB7DQogICAgbGV0IGRlcHNNYXAgPSB0YXJnZXRNYXAuZ2V0KHRhcmdldCk7DQogICAgaWYgKCFkZXBzTWFwKSB7DQogICAgICB0YXJnZXRNYXAuc2V0KHRhcmdldCwgZGVwc01hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCkpOw0KICAgIH0NCiAgICBsZXQgZGVwID0gZGVwc01hcC5nZXQoa2V5KTsNCiAgICBpZiAoIWRlcCkgew0KICAgICAgZGVwc01hcC5zZXQoa2V5LCBkZXAgPSBuZXcgRGVwKCkpOw0KICAgICAgZGVwLm1hcCA9IGRlcHNNYXA7DQogICAgICBkZXAua2V5ID0ga2V5Ow0KICAgIH0NCiAgICB7DQogICAgICBkZXAudHJhY2soew0KICAgICAgICB0YXJnZXQsDQogICAgICAgIHR5cGUsDQogICAgICAgIGtleQ0KICAgICAgfSk7DQogICAgfQ0KICB9DQp9DQpmdW5jdGlvbiB0cmlnZ2VyKHRhcmdldCwgdHlwZSwga2V5LCBuZXdWYWx1ZSwgb2xkVmFsdWUsIG9sZFRhcmdldCkgew0KICBjb25zdCBkZXBzTWFwID0gdGFyZ2V0TWFwLmdldCh0YXJnZXQpOw0KICBpZiAoIWRlcHNNYXApIHsNCiAgICBnbG9iYWxWZXJzaW9uKys7DQogICAgcmV0dXJuOw0KICB9DQogIGNvbnN0IHJ1biA9IChkZXApID0+IHsNCiAgICBpZiAoZGVwKSB7DQogICAgICB7DQogICAgICAgIGRlcC50cmlnZ2VyKHsNCiAgICAgICAgICB0YXJnZXQsDQogICAgICAgICAgdHlwZSwNCiAgICAgICAgICBrZXksDQogICAgICAgICAgbmV3VmFsdWUsDQogICAgICAgICAgb2xkVmFsdWUsDQogICAgICAgICAgb2xkVGFyZ2V0DQogICAgICAgIH0pOw0KICAgICAgfQ0KICAgIH0NCiAgfTsNCiAgc3RhcnRCYXRjaCgpOw0KICBpZiAodHlwZSA9PT0gImNsZWFyIikgew0KICAgIGRlcHNNYXAuZm9yRWFjaChydW4pOw0KICB9IGVsc2Ugew0KICAgIGNvbnN0IHRhcmdldElzQXJyYXkgPSBpc0FycmF5KHRhcmdldCk7DQogICAgY29uc3QgaXNBcnJheUluZGV4ID0gdGFyZ2V0SXNBcnJheSAmJiBpc0ludGVnZXJLZXkoa2V5KTsNCiAgICBpZiAodGFyZ2V0SXNBcnJheSAmJiBrZXkgPT09ICJsZW5ndGgiKSB7DQogICAgICBjb25zdCBuZXdMZW5ndGggPSBOdW1iZXIobmV3VmFsdWUpOw0KICAgICAgZGVwc01hcC5mb3JFYWNoKChkZXAsIGtleTIpID0+IHsNCiAgICAgICAgaWYgKGtleTIgPT09ICJsZW5ndGgiIHx8IGtleTIgPT09IEFSUkFZX0lURVJBVEVfS0VZIHx8ICFpc1N5bWJvbChrZXkyKSAmJiBrZXkyID49IG5ld0xlbmd0aCkgew0KICAgICAgICAgIHJ1bihkZXApOw0KICAgICAgICB9DQogICAgICB9KTsNCiAgICB9IGVsc2Ugew0KICAgICAgaWYgKGtleSAhPT0gdm9pZCAwIHx8IGRlcHNNYXAuaGFzKHZvaWQgMCkpIHsNCiAgICAgICAgcnVuKGRlcHNNYXAuZ2V0KGtleSkpOw0KICAgICAgfQ0KICAgICAgaWYgKGlzQXJyYXlJbmRleCkgew0KICAgICAgICBydW4oZGVwc01hcC5nZXQoQVJSQVlfSVRFUkFURV9LRVkpKTsNCiAgICAgIH0NCiAgICAgIHN3aXRjaCAodHlwZSkgew0KICAgICAgICBjYXNlICJhZGQiOg0KICAgICAgICAgIGlmICghdGFyZ2V0SXNBcnJheSkgew0KICAgICAgICAgICAgcnVuKGRlcHNNYXAuZ2V0KElURVJBVEVfS0VZKSk7DQogICAgICAgICAgICBpZiAoaXNNYXAodGFyZ2V0KSkgew0KICAgICAgICAgICAgICBydW4oZGVwc01hcC5nZXQoTUFQX0tFWV9JVEVSQVRFX0tFWSkpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgIH0gZWxzZSBpZiAoaXNBcnJheUluZGV4KSB7DQogICAgICAgICAgICBydW4oZGVwc01hcC5nZXQoImxlbmd0aCIpKTsNCiAgICAgICAgICB9DQogICAgICAgICAgYnJlYWs7DQogICAgICAgIGNhc2UgImRlbGV0ZSI6DQogICAgICAgICAgaWYgKCF0YXJnZXRJc0FycmF5KSB7DQogICAgICAgICAgICBydW4oZGVwc01hcC5nZXQoSVRFUkFURV9LRVkpKTsNCiAgICAgICAgICAgIGlmIChpc01hcCh0YXJnZXQpKSB7DQogICAgICAgICAgICAgIHJ1bihkZXBzTWFwLmdldChNQVBfS0VZX0lURVJBVEVfS0VZKSk7DQogICAgICAgICAgICB9DQogICAgICAgICAgfQ0KICAgICAgICAgIGJyZWFrOw0KICAgICAgICBjYXNlICJzZXQiOg0KICAgICAgICAgIGlmIChpc01hcCh0YXJnZXQpKSB7DQogICAgICAgICAgICBydW4oZGVwc01hcC5nZXQoSVRFUkFURV9LRVkpKTsNCiAgICAgICAgICB9DQogICAgICAgICAgYnJlYWs7DQogICAgICB9DQogICAgfQ0KICB9DQogIGVuZEJhdGNoKCk7DQp9DQpmdW5jdGlvbiBnZXREZXBGcm9tUmVhY3RpdmUob2JqZWN0LCBrZXkpIHsNCiAgY29uc3QgZGVwTWFwID0gdGFyZ2V0TWFwLmdldChvYmplY3QpOw0KICByZXR1cm4gZGVwTWFwICYmIGRlcE1hcC5nZXQoa2V5KTsNCn0NCg0KZnVuY3Rpb24gcmVhY3RpdmVSZWFkQXJyYXkoYXJyYXkpIHsNCiAgY29uc3QgcmF3ID0gdG9SYXcoYXJyYXkpOw0KICBpZiAocmF3ID09PSBhcnJheSkgcmV0dXJuIHJhdzsNCiAgdHJhY2socmF3LCAiaXRlcmF0ZSIsIEFSUkFZX0lURVJBVEVfS0VZKTsNCiAgcmV0dXJuIGlzU2hhbGxvdyhhcnJheSkgPyByYXcgOiByYXcubWFwKHRvUmVhY3RpdmUpOw0KfQ0KZnVuY3Rpb24gc2hhbGxvd1JlYWRBcnJheShhcnIpIHsNCiAgdHJhY2soYXJyID0gdG9SYXcoYXJyKSwgIml0ZXJhdGUiLCBBUlJBWV9JVEVSQVRFX0tFWSk7DQogIHJldHVybiBhcnI7DQp9DQpjb25zdCBhcnJheUluc3RydW1lbnRhdGlvbnMgPSB7DQogIF9fcHJvdG9fXzogbnVsbCwNCiAgW1N5bWJvbC5pdGVyYXRvcl0oKSB7DQogICAgcmV0dXJuIGl0ZXJhdG9yKHRoaXMsIFN5bWJvbC5pdGVyYXRvciwgdG9SZWFjdGl2ZSk7DQogIH0sDQogIGNvbmNhdCguLi5hcmdzKSB7DQogICAgcmV0dXJuIHJlYWN0aXZlUmVhZEFycmF5KHRoaXMpLmNvbmNhdCgNCiAgICAgIC4uLmFyZ3MubWFwKCh4KSA9PiBpc0FycmF5KHgpID8gcmVhY3RpdmVSZWFkQXJyYXkoeCkgOiB4KQ0KICAgICk7DQogIH0sDQogIGVudHJpZXMoKSB7DQogICAgcmV0dXJuIGl0ZXJhdG9yKHRoaXMsICJlbnRyaWVzIiwgKHZhbHVlKSA9PiB7DQogICAgICB2YWx1ZVsxXSA9IHRvUmVhY3RpdmUodmFsdWVbMV0pOw0KICAgICAgcmV0dXJuIHZhbHVlOw0KICAgIH0pOw0KICB9LA0KICBldmVyeShmbiwgdGhpc0FyZykgew0KICAgIHJldHVybiBhcHBseSh0aGlzLCAiZXZlcnkiLCBmbiwgdGhpc0FyZywgdm9pZCAwLCBhcmd1bWVudHMpOw0KICB9LA0KICBmaWx0ZXIoZm4sIHRoaXNBcmcpIHsNCiAgICByZXR1cm4gYXBwbHkodGhpcywgImZpbHRlciIsIGZuLCB0aGlzQXJnLCAodikgPT4gdi5tYXAodG9SZWFjdGl2ZSksIGFyZ3VtZW50cyk7DQogIH0sDQogIGZpbmQoZm4sIHRoaXNBcmcpIHsNCiAgICByZXR1cm4gYXBwbHkodGhpcywgImZpbmQiLCBmbiwgdGhpc0FyZywgdG9SZWFjdGl2ZSwgYXJndW1lbnRzKTsNCiAgfSwNCiAgZmluZEluZGV4KGZuLCB0aGlzQXJnKSB7DQogICAgcmV0dXJuIGFwcGx5KHRoaXMsICJmaW5kSW5kZXgiLCBmbiwgdGhpc0FyZywgdm9pZCAwLCBhcmd1bWVudHMpOw0KICB9LA0KICBmaW5kTGFzdChmbiwgdGhpc0FyZykgew0KICAgIHJldHVybiBhcHBseSh0aGlzLCAiZmluZExhc3QiLCBmbiwgdGhpc0FyZywgdG9SZWFjdGl2ZSwgYXJndW1lbnRzKTsNCiAgfSwNCiAgZmluZExhc3RJbmRleChmbiwgdGhpc0FyZykgew0KICAgIHJldHVybiBhcHBseSh0aGlzLCAiZmluZExhc3RJbmRleCIsIGZuLCB0aGlzQXJnLCB2b2lkIDAsIGFyZ3VtZW50cyk7DQogIH0sDQogIC8vIGZsYXQsIGZsYXRNYXAgY291bGQgYmVuZWZpdCBmcm9tIEFSUkFZX0lURVJBVEUgYnV0IGFyZSBub3Qgc3RyYWlnaHQtZm9yd2FyZCB0byBpbXBsZW1lbnQNCiAgZm9yRWFjaChmbiwgdGhpc0FyZykgew0KICAgIHJldHVybiBhcHBseSh0aGlzLCAiZm9yRWFjaCIsIGZuLCB0aGlzQXJnLCB2b2lkIDAsIGFyZ3VtZW50cyk7DQogIH0sDQogIGluY2x1ZGVzKC4uLmFyZ3MpIHsNCiAgICByZXR1cm4gc2VhcmNoUHJveHkodGhpcywgImluY2x1ZGVzIiwgYXJncyk7DQogIH0sDQogIGluZGV4T2YoLi4uYXJncykgew0KICAgIHJldHVybiBzZWFyY2hQcm94eSh0aGlzLCAiaW5kZXhPZiIsIGFyZ3MpOw0KICB9LA0KICBqb2luKHNlcGFyYXRvcikgew0KICAgIHJldHVybiByZWFjdGl2ZVJlYWRBcnJheSh0aGlzKS5qb2luKHNlcGFyYXRvcik7DQogIH0sDQogIC8vIGtleXMoKSBpdGVyYXRvciBvbmx5IHJlYWRzIGBsZW5ndGhgLCBubyBvcHRpbWlzYXRpb24gcmVxdWlyZWQNCiAgbGFzdEluZGV4T2YoLi4uYXJncykgew0KICAgIHJldHVybiBzZWFyY2hQcm94eSh0aGlzLCAibGFzdEluZGV4T2YiLCBhcmdzKTsNCiAgfSwNCiAgbWFwKGZuLCB0aGlzQXJnKSB7DQogICAgcmV0dXJuIGFwcGx5KHRoaXMsICJtYXAiLCBmbiwgdGhpc0FyZywgdm9pZCAwLCBhcmd1bWVudHMpOw0KICB9LA0KICBwb3AoKSB7DQogICAgcmV0dXJuIG5vVHJhY2tpbmcodGhpcywgInBvcCIpOw0KICB9LA0KICBwdXNoKC4uLmFyZ3MpIHsNCiAgICByZXR1cm4gbm9UcmFja2luZyh0aGlzLCAicHVzaCIsIGFyZ3MpOw0KICB9LA0KICByZWR1Y2UoZm4sIC4uLmFyZ3MpIHsNCiAgICByZXR1cm4gcmVkdWNlKHRoaXMsICJyZWR1Y2UiLCBmbiwgYXJncyk7DQogIH0sDQogIHJlZHVjZVJpZ2h0KGZuLCAuLi5hcmdzKSB7DQogICAgcmV0dXJuIHJlZHVjZSh0aGlzLCAicmVkdWNlUmlnaHQiLCBmbiwgYXJncyk7DQogIH0sDQogIHNoaWZ0KCkgew0KICAgIHJldHVybiBub1RyYWNraW5nKHRoaXMsICJzaGlmdCIpOw0KICB9LA0KICAvLyBzbGljZSBjb3VsZCB1c2UgQVJSQVlfSVRFUkFURSBidXQgYWxzbyBzZWVtcyB0byBiZWcgZm9yIHJhbmdlIHRyYWNraW5nDQogIHNvbWUoZm4sIHRoaXNBcmcpIHsNCiAgICByZXR1cm4gYXBwbHkodGhpcywgInNvbWUiLCBmbiwgdGhpc0FyZywgdm9pZCAwLCBhcmd1bWVudHMpOw0KICB9LA0KICBzcGxpY2UoLi4uYXJncykgew0KICAgIHJldHVybiBub1RyYWNraW5nKHRoaXMsICJzcGxpY2UiLCBhcmdzKTsNCiAgfSwNCiAgdG9SZXZlcnNlZCgpIHsNCiAgICByZXR1cm4gcmVhY3RpdmVSZWFkQXJyYXkodGhpcykudG9SZXZlcnNlZCgpOw0KICB9LA0KICB0b1NvcnRlZChjb21wYXJlcikgew0KICAgIHJldHVybiByZWFjdGl2ZVJlYWRBcnJheSh0aGlzKS50b1NvcnRlZChjb21wYXJlcik7DQogIH0sDQogIHRvU3BsaWNlZCguLi5hcmdzKSB7DQogICAgcmV0dXJuIHJlYWN0aXZlUmVhZEFycmF5KHRoaXMpLnRvU3BsaWNlZCguLi5hcmdzKTsNCiAgfSwNCiAgdW5zaGlmdCguLi5hcmdzKSB7DQogICAgcmV0dXJuIG5vVHJhY2tpbmcodGhpcywgInVuc2hpZnQiLCBhcmdzKTsNCiAgfSwNCiAgdmFsdWVzKCkgew0KICAgIHJldHVybiBpdGVyYXRvcih0aGlzLCAidmFsdWVzIiwgdG9SZWFjdGl2ZSk7DQogIH0NCn07DQpmdW5jdGlvbiBpdGVyYXRvcihzZWxmLCBtZXRob2QsIHdyYXBWYWx1ZSkgew0KICBjb25zdCBhcnIgPSBzaGFsbG93UmVhZEFycmF5KHNlbGYpOw0KICBjb25zdCBpdGVyID0gYXJyW21ldGhvZF0oKTsNCiAgaWYgKGFyciAhPT0gc2VsZiAmJiAhaXNTaGFsbG93KHNlbGYpKSB7DQogICAgaXRlci5fbmV4dCA9IGl0ZXIubmV4dDsNCiAgICBpdGVyLm5leHQgPSAoKSA9PiB7DQogICAgICBjb25zdCByZXN1bHQgPSBpdGVyLl9uZXh0KCk7DQogICAgICBpZiAocmVzdWx0LnZhbHVlKSB7DQogICAgICAgIHJlc3VsdC52YWx1ZSA9IHdyYXBWYWx1ZShyZXN1bHQudmFsdWUpOw0KICAgICAgfQ0KICAgICAgcmV0dXJuIHJlc3VsdDsNCiAgICB9Ow0KICB9DQogIHJldHVybiBpdGVyOw0KfQ0KY29uc3QgYXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZTsNCmZ1bmN0aW9uIGFwcGx5KHNlbGYsIG1ldGhvZCwgZm4sIHRoaXNBcmcsIHdyYXBwZWRSZXRGbiwgYXJncykgew0KICBjb25zdCBhcnIgPSBzaGFsbG93UmVhZEFycmF5KHNlbGYpOw0KICBjb25zdCBuZWVkc1dyYXAgPSBhcnIgIT09IHNlbGYgJiYgIWlzU2hhbGxvdyhzZWxmKTsNCiAgY29uc3QgbWV0aG9kRm4gPSBhcnJbbWV0aG9kXTsNCiAgaWYgKG1ldGhvZEZuICE9PSBhcnJheVByb3RvW21ldGhvZF0pIHsNCiAgICBjb25zdCByZXN1bHQyID0gbWV0aG9kRm4uYXBwbHkoc2VsZiwgYXJncyk7DQogICAgcmV0dXJuIG5lZWRzV3JhcCA/IHRvUmVhY3RpdmUocmVzdWx0MikgOiByZXN1bHQyOw0KICB9DQogIGxldCB3cmFwcGVkRm4gPSBmbjsNCiAgaWYgKGFyciAhPT0gc2VsZikgew0KICAgIGlmIChuZWVkc1dyYXApIHsNCiAgICAgIHdyYXBwZWRGbiA9IGZ1bmN0aW9uKGl0ZW0sIGluZGV4KSB7DQogICAgICAgIHJldHVybiBmbi5jYWxsKHRoaXMsIHRvUmVhY3RpdmUoaXRlbSksIGluZGV4LCBzZWxmKTsNCiAgICAgIH07DQogICAgfSBlbHNlIGlmIChmbi5sZW5ndGggPiAyKSB7DQogICAgICB3cmFwcGVkRm4gPSBmdW5jdGlvbihpdGVtLCBpbmRleCkgew0KICAgICAgICByZXR1cm4gZm4uY2FsbCh0aGlzLCBpdGVtLCBpbmRleCwgc2VsZik7DQogICAgICB9Ow0KICAgIH0NCiAgfQ0KICBjb25zdCByZXN1bHQgPSBtZXRob2RGbi5jYWxsKGFyciwgd3JhcHBlZEZuLCB0aGlzQXJnKTsNCiAgcmV0dXJuIG5lZWRzV3JhcCAmJiB3cmFwcGVkUmV0Rm4gPyB3cmFwcGVkUmV0Rm4ocmVzdWx0KSA6IHJlc3VsdDsNCn0NCmZ1bmN0aW9uIHJlZHVjZShzZWxmLCBtZXRob2QsIGZuLCBhcmdzKSB7DQogIGNvbnN0IGFyciA9IHNoYWxsb3dSZWFkQXJyYXkoc2VsZik7DQogIGxldCB3cmFwcGVkRm4gPSBmbjsNCiAgaWYgKGFyciAhPT0gc2VsZikgew0KICAgIGlmICghaXNTaGFsbG93KHNlbGYpKSB7DQogICAgICB3cmFwcGVkRm4gPSBmdW5jdGlvbihhY2MsIGl0ZW0sIGluZGV4KSB7DQogICAgICAgIHJldHVybiBmbi5jYWxsKHRoaXMsIGFjYywgdG9SZWFjdGl2ZShpdGVtKSwgaW5kZXgsIHNlbGYpOw0KICAgICAgfTsNCiAgICB9IGVsc2UgaWYgKGZuLmxlbmd0aCA+IDMpIHsNCiAgICAgIHdyYXBwZWRGbiA9IGZ1bmN0aW9uKGFjYywgaXRlbSwgaW5kZXgpIHsNCiAgICAgICAgcmV0dXJuIGZuLmNhbGwodGhpcywgYWNjLCBpdGVtLCBpbmRleCwgc2VsZik7DQogICAgICB9Ow0KICAgIH0NCiAgfQ0KICByZXR1cm4gYXJyW21ldGhvZF0od3JhcHBlZEZuLCAuLi5hcmdzKTsNCn0NCmZ1bmN0aW9uIHNlYXJjaFByb3h5KHNlbGYsIG1ldGhvZCwgYXJncykgew0KICBjb25zdCBhcnIgPSB0b1JhdyhzZWxmKTsNCiAgdHJhY2soYXJyLCAiaXRlcmF0ZSIsIEFSUkFZX0lURVJBVEVfS0VZKTsNCiAgY29uc3QgcmVzID0gYXJyW21ldGhvZF0oLi4uYXJncyk7DQogIGlmICgocmVzID09PSAtMSB8fCByZXMgPT09IGZhbHNlKSAmJiBpc1Byb3h5KGFyZ3NbMF0pKSB7DQogICAgYXJnc1swXSA9IHRvUmF3KGFyZ3NbMF0pOw0KICAgIHJldHVybiBhcnJbbWV0aG9kXSguLi5hcmdzKTsNCiAgfQ0KICByZXR1cm4gcmVzOw0KfQ0KZnVuY3Rpb24gbm9UcmFja2luZyhzZWxmLCBtZXRob2QsIGFyZ3MgPSBbXSkgew0KICBwYXVzZVRyYWNraW5nKCk7DQogIHN0YXJ0QmF0Y2goKTsNCiAgY29uc3QgcmVzID0gdG9SYXcoc2VsZilbbWV0aG9kXS5hcHBseShzZWxmLCBhcmdzKTsNCiAgZW5kQmF0Y2goKTsNCiAgcmVzZXRUcmFja2luZygpOw0KICByZXR1cm4gcmVzOw0KfQ0KDQpjb25zdCBpc05vblRyYWNrYWJsZUtleXMgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcChgX19wcm90b19fLF9fdl9pc1JlZixfX2lzVnVlYCk7DQpjb25zdCBidWlsdEluU3ltYm9scyA9IG5ldyBTZXQoDQogIC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhTeW1ib2wpLmZpbHRlcigoa2V5KSA9PiBrZXkgIT09ICJhcmd1bWVudHMiICYmIGtleSAhPT0gImNhbGxlciIpLm1hcCgoa2V5KSA9PiBTeW1ib2xba2V5XSkuZmlsdGVyKGlzU3ltYm9sKQ0KKTsNCmZ1bmN0aW9uIGhhc093blByb3BlcnR5KGtleSkgew0KICBpZiAoIWlzU3ltYm9sKGtleSkpIGtleSA9IFN0cmluZyhrZXkpOw0KICBjb25zdCBvYmogPSB0b1Jhdyh0aGlzKTsNCiAgdHJhY2sob2JqLCAiaGFzIiwga2V5KTsNCiAgcmV0dXJuIG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpOw0KfQ0KY2xhc3MgQmFzZVJlYWN0aXZlSGFuZGxlciB7DQogIGNvbnN0cnVjdG9yKF9pc1JlYWRvbmx5ID0gZmFsc2UsIF9pc1NoYWxsb3cgPSBmYWxzZSkgew0KICAgIHRoaXMuX2lzUmVhZG9ubHkgPSBfaXNSZWFkb25seTsNCiAgICB0aGlzLl9pc1NoYWxsb3cgPSBfaXNTaGFsbG93Ow0KICB9DQogIGdldCh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpIHsNCiAgICBpZiAoa2V5ID09PSAiX192X3NraXAiKSByZXR1cm4gdGFyZ2V0WyJfX3Zfc2tpcCJdOw0KICAgIGNvbnN0IGlzUmVhZG9ubHkyID0gdGhpcy5faXNSZWFkb25seSwgaXNTaGFsbG93MiA9IHRoaXMuX2lzU2hhbGxvdzsNCiAgICBpZiAoa2V5ID09PSAiX192X2lzUmVhY3RpdmUiKSB7DQogICAgICByZXR1cm4gIWlzUmVhZG9ubHkyOw0KICAgIH0gZWxzZSBpZiAoa2V5ID09PSAiX192X2lzUmVhZG9ubHkiKSB7DQogICAgICByZXR1cm4gaXNSZWFkb25seTI7DQogICAgfSBlbHNlIGlmIChrZXkgPT09ICJfX3ZfaXNTaGFsbG93Iikgew0KICAgICAgcmV0dXJuIGlzU2hhbGxvdzI7DQogICAgfSBlbHNlIGlmIChrZXkgPT09ICJfX3ZfcmF3Iikgew0KICAgICAgaWYgKHJlY2VpdmVyID09PSAoaXNSZWFkb25seTIgPyBpc1NoYWxsb3cyID8gc2hhbGxvd1JlYWRvbmx5TWFwIDogcmVhZG9ubHlNYXAgOiBpc1NoYWxsb3cyID8gc2hhbGxvd1JlYWN0aXZlTWFwIDogcmVhY3RpdmVNYXApLmdldCh0YXJnZXQpIHx8IC8vIHJlY2VpdmVyIGlzIG5vdCB0aGUgcmVhY3RpdmUgcHJveHksIGJ1dCBoYXMgdGhlIHNhbWUgcHJvdG90eXBlDQogICAgICAvLyB0aGlzIG1lYW5zIHRoZSByZWNlaXZlciBpcyBhIHVzZXIgcHJveHkgb2YgdGhlIHJlYWN0aXZlIHByb3h5DQogICAgICBPYmplY3QuZ2V0UHJvdG90eXBlT2YodGFyZ2V0KSA9PT0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHJlY2VpdmVyKSkgew0KICAgICAgICByZXR1cm4gdGFyZ2V0Ow0KICAgICAgfQ0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBjb25zdCB0YXJnZXRJc0FycmF5ID0gaXNBcnJheSh0YXJnZXQpOw0KICAgIGlmICghaXNSZWFkb25seTIpIHsNCiAgICAgIGxldCBmbjsNCiAgICAgIGlmICh0YXJnZXRJc0FycmF5ICYmIChmbiA9IGFycmF5SW5zdHJ1bWVudGF0aW9uc1trZXldKSkgew0KICAgICAgICByZXR1cm4gZm47DQogICAgICB9DQogICAgICBpZiAoa2V5ID09PSAiaGFzT3duUHJvcGVydHkiKSB7DQogICAgICAgIHJldHVybiBoYXNPd25Qcm9wZXJ0eTsNCiAgICAgIH0NCiAgICB9DQogICAgY29uc3QgcmVzID0gUmVmbGVjdC5nZXQoDQogICAgICB0YXJnZXQsDQogICAgICBrZXksDQogICAgICAvLyBpZiB0aGlzIGlzIGEgcHJveHkgd3JhcHBpbmcgYSByZWYsIHJldHVybiBtZXRob2RzIHVzaW5nIHRoZSByYXcgcmVmDQogICAgICAvLyBhcyByZWNlaXZlciBzbyB0aGF0IHdlIGRvbid0IGhhdmUgdG8gY2FsbCBgdG9SYXdgIG9uIHRoZSByZWYgaW4gYWxsDQogICAgICAvLyBpdHMgY2xhc3MgbWV0aG9kcw0KICAgICAgaXNSZWYodGFyZ2V0KSA/IHRhcmdldCA6IHJlY2VpdmVyDQogICAgKTsNCiAgICBpZiAoaXNTeW1ib2woa2V5KSA/IGJ1aWx0SW5TeW1ib2xzLmhhcyhrZXkpIDogaXNOb25UcmFja2FibGVLZXlzKGtleSkpIHsNCiAgICAgIHJldHVybiByZXM7DQogICAgfQ0KICAgIGlmICghaXNSZWFkb25seTIpIHsNCiAgICAgIHRyYWNrKHRhcmdldCwgImdldCIsIGtleSk7DQogICAgfQ0KICAgIGlmIChpc1NoYWxsb3cyKSB7DQogICAgICByZXR1cm4gcmVzOw0KICAgIH0NCiAgICBpZiAoaXNSZWYocmVzKSkgew0KICAgICAgcmV0dXJuIHRhcmdldElzQXJyYXkgJiYgaXNJbnRlZ2VyS2V5KGtleSkgPyByZXMgOiByZXMudmFsdWU7DQogICAgfQ0KICAgIGlmIChpc09iamVjdChyZXMpKSB7DQogICAgICByZXR1cm4gaXNSZWFkb25seTIgPyByZWFkb25seShyZXMpIDogcmVhY3RpdmUocmVzKTsNCiAgICB9DQogICAgcmV0dXJuIHJlczsNCiAgfQ0KfQ0KY2xhc3MgTXV0YWJsZVJlYWN0aXZlSGFuZGxlciBleHRlbmRzIEJhc2VSZWFjdGl2ZUhhbmRsZXIgew0KICBjb25zdHJ1Y3Rvcihpc1NoYWxsb3cyID0gZmFsc2UpIHsNCiAgICBzdXBlcihmYWxzZSwgaXNTaGFsbG93Mik7DQogIH0NCiAgc2V0KHRhcmdldCwga2V5LCB2YWx1ZSwgcmVjZWl2ZXIpIHsNCiAgICBsZXQgb2xkVmFsdWUgPSB0YXJnZXRba2V5XTsNCiAgICBpZiAoIXRoaXMuX2lzU2hhbGxvdykgew0KICAgICAgY29uc3QgaXNPbGRWYWx1ZVJlYWRvbmx5ID0gaXNSZWFkb25seShvbGRWYWx1ZSk7DQogICAgICBpZiAoIWlzU2hhbGxvdyh2YWx1ZSkgJiYgIWlzUmVhZG9ubHkodmFsdWUpKSB7DQogICAgICAgIG9sZFZhbHVlID0gdG9SYXcob2xkVmFsdWUpOw0KICAgICAgICB2YWx1ZSA9IHRvUmF3KHZhbHVlKTsNCiAgICAgIH0NCiAgICAgIGlmICghaXNBcnJheSh0YXJnZXQpICYmIGlzUmVmKG9sZFZhbHVlKSAmJiAhaXNSZWYodmFsdWUpKSB7DQogICAgICAgIGlmIChpc09sZFZhbHVlUmVhZG9ubHkpIHsNCiAgICAgICAgICByZXR1cm4gZmFsc2U7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgb2xkVmFsdWUudmFsdWUgPSB2YWx1ZTsNCiAgICAgICAgICByZXR1cm4gdHJ1ZTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgICBjb25zdCBoYWRLZXkgPSBpc0FycmF5KHRhcmdldCkgJiYgaXNJbnRlZ2VyS2V5KGtleSkgPyBOdW1iZXIoa2V5KSA8IHRhcmdldC5sZW5ndGggOiBoYXNPd24odGFyZ2V0LCBrZXkpOw0KICAgIGNvbnN0IHJlc3VsdCA9IFJlZmxlY3Quc2V0KA0KICAgICAgdGFyZ2V0LA0KICAgICAga2V5LA0KICAgICAgdmFsdWUsDQogICAgICBpc1JlZih0YXJnZXQpID8gdGFyZ2V0IDogcmVjZWl2ZXINCiAgICApOw0KICAgIGlmICh0YXJnZXQgPT09IHRvUmF3KHJlY2VpdmVyKSkgew0KICAgICAgaWYgKCFoYWRLZXkpIHsNCiAgICAgICAgdHJpZ2dlcih0YXJnZXQsICJhZGQiLCBrZXksIHZhbHVlKTsNCiAgICAgIH0gZWxzZSBpZiAoaGFzQ2hhbmdlZCh2YWx1ZSwgb2xkVmFsdWUpKSB7DQogICAgICAgIHRyaWdnZXIodGFyZ2V0LCAic2V0Iiwga2V5LCB2YWx1ZSwgb2xkVmFsdWUpOw0KICAgICAgfQ0KICAgIH0NCiAgICByZXR1cm4gcmVzdWx0Ow0KICB9DQogIGRlbGV0ZVByb3BlcnR5KHRhcmdldCwga2V5KSB7DQogICAgY29uc3QgaGFkS2V5ID0gaGFzT3duKHRhcmdldCwga2V5KTsNCiAgICBjb25zdCBvbGRWYWx1ZSA9IHRhcmdldFtrZXldOw0KICAgIGNvbnN0IHJlc3VsdCA9IFJlZmxlY3QuZGVsZXRlUHJvcGVydHkodGFyZ2V0LCBrZXkpOw0KICAgIGlmIChyZXN1bHQgJiYgaGFkS2V5KSB7DQogICAgICB0cmlnZ2VyKHRhcmdldCwgImRlbGV0ZSIsIGtleSwgdm9pZCAwLCBvbGRWYWx1ZSk7DQogICAgfQ0KICAgIHJldHVybiByZXN1bHQ7DQogIH0NCiAgaGFzKHRhcmdldCwga2V5KSB7DQogICAgY29uc3QgcmVzdWx0ID0gUmVmbGVjdC5oYXModGFyZ2V0LCBrZXkpOw0KICAgIGlmICghaXNTeW1ib2woa2V5KSB8fCAhYnVpbHRJblN5bWJvbHMuaGFzKGtleSkpIHsNCiAgICAgIHRyYWNrKHRhcmdldCwgImhhcyIsIGtleSk7DQogICAgfQ0KICAgIHJldHVybiByZXN1bHQ7DQogIH0NCiAgb3duS2V5cyh0YXJnZXQpIHsNCiAgICB0cmFjaygNCiAgICAgIHRhcmdldCwNCiAgICAgICJpdGVyYXRlIiwNCiAgICAgIGlzQXJyYXkodGFyZ2V0KSA/ICJsZW5ndGgiIDogSVRFUkFURV9LRVkNCiAgICApOw0KICAgIHJldHVybiBSZWZsZWN0Lm93bktleXModGFyZ2V0KTsNCiAgfQ0KfQ0KY2xhc3MgUmVhZG9ubHlSZWFjdGl2ZUhhbmRsZXIgZXh0ZW5kcyBCYXNlUmVhY3RpdmVIYW5kbGVyIHsNCiAgY29uc3RydWN0b3IoaXNTaGFsbG93MiA9IGZhbHNlKSB7DQogICAgc3VwZXIodHJ1ZSwgaXNTaGFsbG93Mik7DQogIH0NCiAgc2V0KHRhcmdldCwga2V5KSB7DQogICAgew0KICAgICAgd2FybiQyKA0KICAgICAgICBgU2V0IG9wZXJhdGlvbiBvbiBrZXkgIiR7U3RyaW5nKGtleSl9IiBmYWlsZWQ6IHRhcmdldCBpcyByZWFkb25seS5gLA0KICAgICAgICB0YXJnZXQNCiAgICAgICk7DQogICAgfQ0KICAgIHJldHVybiB0cnVlOw0KICB9DQogIGRlbGV0ZVByb3BlcnR5KHRhcmdldCwga2V5KSB7DQogICAgew0KICAgICAgd2FybiQyKA0KICAgICAgICBgRGVsZXRlIG9wZXJhdGlvbiBvbiBrZXkgIiR7U3RyaW5nKGtleSl9IiBmYWlsZWQ6IHRhcmdldCBpcyByZWFkb25seS5gLA0KICAgICAgICB0YXJnZXQNCiAgICAgICk7DQogICAgfQ0KICAgIHJldHVybiB0cnVlOw0KICB9DQp9DQpjb25zdCBtdXRhYmxlSGFuZGxlcnMgPSAvKiBAX19QVVJFX18gKi8gbmV3IE11dGFibGVSZWFjdGl2ZUhhbmRsZXIoKTsNCmNvbnN0IHJlYWRvbmx5SGFuZGxlcnMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFJlYWRvbmx5UmVhY3RpdmVIYW5kbGVyKCk7DQpjb25zdCBzaGFsbG93UmVhY3RpdmVIYW5kbGVycyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTXV0YWJsZVJlYWN0aXZlSGFuZGxlcih0cnVlKTsNCmNvbnN0IHNoYWxsb3dSZWFkb25seUhhbmRsZXJzID0gLyogQF9fUFVSRV9fICovIG5ldyBSZWFkb25seVJlYWN0aXZlSGFuZGxlcih0cnVlKTsNCg0KY29uc3QgdG9TaGFsbG93ID0gKHZhbHVlKSA9PiB2YWx1ZTsNCmNvbnN0IGdldFByb3RvID0gKHYpID0+IFJlZmxlY3QuZ2V0UHJvdG90eXBlT2Yodik7DQpmdW5jdGlvbiBjcmVhdGVJdGVyYWJsZU1ldGhvZChtZXRob2QsIGlzUmVhZG9ubHkyLCBpc1NoYWxsb3cyKSB7DQogIHJldHVybiBmdW5jdGlvbiguLi5hcmdzKSB7DQogICAgY29uc3QgdGFyZ2V0ID0gdGhpc1siX192X3JhdyJdOw0KICAgIGNvbnN0IHJhd1RhcmdldCA9IHRvUmF3KHRhcmdldCk7DQogICAgY29uc3QgdGFyZ2V0SXNNYXAgPSBpc01hcChyYXdUYXJnZXQpOw0KICAgIGNvbnN0IGlzUGFpciA9IG1ldGhvZCA9PT0gImVudHJpZXMiIHx8IG1ldGhvZCA9PT0gU3ltYm9sLml0ZXJhdG9yICYmIHRhcmdldElzTWFwOw0KICAgIGNvbnN0IGlzS2V5T25seSA9IG1ldGhvZCA9PT0gImtleXMiICYmIHRhcmdldElzTWFwOw0KICAgIGNvbnN0IGlubmVySXRlcmF0b3IgPSB0YXJnZXRbbWV0aG9kXSguLi5hcmdzKTsNCiAgICBjb25zdCB3cmFwID0gaXNTaGFsbG93MiA/IHRvU2hhbGxvdyA6IGlzUmVhZG9ubHkyID8gdG9SZWFkb25seSA6IHRvUmVhY3RpdmU7DQogICAgIWlzUmVhZG9ubHkyICYmIHRyYWNrKA0KICAgICAgcmF3VGFyZ2V0LA0KICAgICAgIml0ZXJhdGUiLA0KICAgICAgaXNLZXlPbmx5ID8gTUFQX0tFWV9JVEVSQVRFX0tFWSA6IElURVJBVEVfS0VZDQogICAgKTsNCiAgICByZXR1cm4gew0KICAgICAgLy8gaXRlcmF0b3IgcHJvdG9jb2wNCiAgICAgIG5leHQoKSB7DQogICAgICAgIGNvbnN0IHsgdmFsdWUsIGRvbmUgfSA9IGlubmVySXRlcmF0b3IubmV4dCgpOw0KICAgICAgICByZXR1cm4gZG9uZSA/IHsgdmFsdWUsIGRvbmUgfSA6IHsNCiAgICAgICAgICB2YWx1ZTogaXNQYWlyID8gW3dyYXAodmFsdWVbMF0pLCB3cmFwKHZhbHVlWzFdKV0gOiB3cmFwKHZhbHVlKSwNCiAgICAgICAgICBkb25lDQogICAgICAgIH07DQogICAgICB9LA0KICAgICAgLy8gaXRlcmFibGUgcHJvdG9jb2wNCiAgICAgIFtTeW1ib2wuaXRlcmF0b3JdKCkgew0KICAgICAgICByZXR1cm4gdGhpczsNCiAgICAgIH0NCiAgICB9Ow0KICB9Ow0KfQ0KZnVuY3Rpb24gY3JlYXRlUmVhZG9ubHlNZXRob2QodHlwZSkgew0KICByZXR1cm4gZnVuY3Rpb24oLi4uYXJncykgew0KICAgIHsNCiAgICAgIGNvbnN0IGtleSA9IGFyZ3NbMF0gPyBgb24ga2V5ICIke2FyZ3NbMF19IiBgIDogYGA7DQogICAgICB3YXJuJDIoDQogICAgICAgIGAke2NhcGl0YWxpemUodHlwZSl9IG9wZXJhdGlvbiAke2tleX1mYWlsZWQ6IHRhcmdldCBpcyByZWFkb25seS5gLA0KICAgICAgICB0b1Jhdyh0aGlzKQ0KICAgICAgKTsNCiAgICB9DQogICAgcmV0dXJuIHR5cGUgPT09ICJkZWxldGUiID8gZmFsc2UgOiB0eXBlID09PSAiY2xlYXIiID8gdm9pZCAwIDogdGhpczsNCiAgfTsNCn0NCmZ1bmN0aW9uIGNyZWF0ZUluc3RydW1lbnRhdGlvbnMocmVhZG9ubHksIHNoYWxsb3cpIHsNCiAgY29uc3QgaW5zdHJ1bWVudGF0aW9ucyA9IHsNCiAgICBnZXQoa2V5KSB7DQogICAgICBjb25zdCB0YXJnZXQgPSB0aGlzWyJfX3ZfcmF3Il07DQogICAgICBjb25zdCByYXdUYXJnZXQgPSB0b1Jhdyh0YXJnZXQpOw0KICAgICAgY29uc3QgcmF3S2V5ID0gdG9SYXcoa2V5KTsNCiAgICAgIGlmICghcmVhZG9ubHkpIHsNCiAgICAgICAgaWYgKGhhc0NoYW5nZWQoa2V5LCByYXdLZXkpKSB7DQogICAgICAgICAgdHJhY2socmF3VGFyZ2V0LCAiZ2V0Iiwga2V5KTsNCiAgICAgICAgfQ0KICAgICAgICB0cmFjayhyYXdUYXJnZXQsICJnZXQiLCByYXdLZXkpOw0KICAgICAgfQ0KICAgICAgY29uc3QgeyBoYXMgfSA9IGdldFByb3RvKHJhd1RhcmdldCk7DQogICAgICBjb25zdCB3cmFwID0gc2hhbGxvdyA/IHRvU2hhbGxvdyA6IHJlYWRvbmx5ID8gdG9SZWFkb25seSA6IHRvUmVhY3RpdmU7DQogICAgICBpZiAoaGFzLmNhbGwocmF3VGFyZ2V0LCBrZXkpKSB7DQogICAgICAgIHJldHVybiB3cmFwKHRhcmdldC5nZXQoa2V5KSk7DQogICAgICB9IGVsc2UgaWYgKGhhcy5jYWxsKHJhd1RhcmdldCwgcmF3S2V5KSkgew0KICAgICAgICByZXR1cm4gd3JhcCh0YXJnZXQuZ2V0KHJhd0tleSkpOw0KICAgICAgfSBlbHNlIGlmICh0YXJnZXQgIT09IHJhd1RhcmdldCkgew0KICAgICAgICB0YXJnZXQuZ2V0KGtleSk7DQogICAgICB9DQogICAgfSwNCiAgICBnZXQgc2l6ZSgpIHsNCiAgICAgIGNvbnN0IHRhcmdldCA9IHRoaXNbIl9fdl9yYXciXTsNCiAgICAgICFyZWFkb25seSAmJiB0cmFjayh0b1Jhdyh0YXJnZXQpLCAiaXRlcmF0ZSIsIElURVJBVEVfS0VZKTsNCiAgICAgIHJldHVybiBSZWZsZWN0LmdldCh0YXJnZXQsICJzaXplIiwgdGFyZ2V0KTsNCiAgICB9LA0KICAgIGhhcyhrZXkpIHsNCiAgICAgIGNvbnN0IHRhcmdldCA9IHRoaXNbIl9fdl9yYXciXTsNCiAgICAgIGNvbnN0IHJhd1RhcmdldCA9IHRvUmF3KHRhcmdldCk7DQogICAgICBjb25zdCByYXdLZXkgPSB0b1JhdyhrZXkpOw0KICAgICAgaWYgKCFyZWFkb25seSkgew0KICAgICAgICBpZiAoaGFzQ2hhbmdlZChrZXksIHJhd0tleSkpIHsNCiAgICAgICAgICB0cmFjayhyYXdUYXJnZXQsICJoYXMiLCBrZXkpOw0KICAgICAgICB9DQogICAgICAgIHRyYWNrKHJhd1RhcmdldCwgImhhcyIsIHJhd0tleSk7DQogICAgICB9DQogICAgICByZXR1cm4ga2V5ID09PSByYXdLZXkgPyB0YXJnZXQuaGFzKGtleSkgOiB0YXJnZXQuaGFzKGtleSkgfHwgdGFyZ2V0LmhhcyhyYXdLZXkpOw0KICAgIH0sDQogICAgZm9yRWFjaChjYWxsYmFjaywgdGhpc0FyZykgew0KICAgICAgY29uc3Qgb2JzZXJ2ZWQgPSB0aGlzOw0KICAgICAgY29uc3QgdGFyZ2V0ID0gb2JzZXJ2ZWRbIl9fdl9yYXciXTsNCiAgICAgIGNvbnN0IHJhd1RhcmdldCA9IHRvUmF3KHRhcmdldCk7DQogICAgICBjb25zdCB3cmFwID0gc2hhbGxvdyA/IHRvU2hhbGxvdyA6IHJlYWRvbmx5ID8gdG9SZWFkb25seSA6IHRvUmVhY3RpdmU7DQogICAgICAhcmVhZG9ubHkgJiYgdHJhY2socmF3VGFyZ2V0LCAiaXRlcmF0ZSIsIElURVJBVEVfS0VZKTsNCiAgICAgIHJldHVybiB0YXJnZXQuZm9yRWFjaCgodmFsdWUsIGtleSkgPT4gew0KICAgICAgICByZXR1cm4gY2FsbGJhY2suY2FsbCh0aGlzQXJnLCB3cmFwKHZhbHVlKSwgd3JhcChrZXkpLCBvYnNlcnZlZCk7DQogICAgICB9KTsNCiAgICB9DQogIH07DQogIGV4dGVuZCgNCiAgICBpbnN0cnVtZW50YXRpb25zLA0KICAgIHJlYWRvbmx5ID8gew0KICAgICAgYWRkOiBjcmVhdGVSZWFkb25seU1ldGhvZCgiYWRkIiksDQogICAgICBzZXQ6IGNyZWF0ZVJlYWRvbmx5TWV0aG9kKCJzZXQiKSwNCiAgICAgIGRlbGV0ZTogY3JlYXRlUmVhZG9ubHlNZXRob2QoImRlbGV0ZSIpLA0KICAgICAgY2xlYXI6IGNyZWF0ZVJlYWRvbmx5TWV0aG9kKCJjbGVhciIpDQogICAgfSA6IHsNCiAgICAgIGFkZCh2YWx1ZSkgew0KICAgICAgICBpZiAoIXNoYWxsb3cgJiYgIWlzU2hhbGxvdyh2YWx1ZSkgJiYgIWlzUmVhZG9ubHkodmFsdWUpKSB7DQogICAgICAgICAgdmFsdWUgPSB0b1Jhdyh2YWx1ZSk7DQogICAgICAgIH0NCiAgICAgICAgY29uc3QgdGFyZ2V0ID0gdG9SYXcodGhpcyk7DQogICAgICAgIGNvbnN0IHByb3RvID0gZ2V0UHJvdG8odGFyZ2V0KTsNCiAgICAgICAgY29uc3QgaGFkS2V5ID0gcHJvdG8uaGFzLmNhbGwodGFyZ2V0LCB2YWx1ZSk7DQogICAgICAgIGlmICghaGFkS2V5KSB7DQogICAgICAgICAgdGFyZ2V0LmFkZCh2YWx1ZSk7DQogICAgICAgICAgdHJpZ2dlcih0YXJnZXQsICJhZGQiLCB2YWx1ZSwgdmFsdWUpOw0KICAgICAgICB9DQogICAgICAgIHJldHVybiB0aGlzOw0KICAgICAgfSwNCiAgICAgIHNldChrZXksIHZhbHVlKSB7DQogICAgICAgIGlmICghc2hhbGxvdyAmJiAhaXNTaGFsbG93KHZhbHVlKSAmJiAhaXNSZWFkb25seSh2YWx1ZSkpIHsNCiAgICAgICAgICB2YWx1ZSA9IHRvUmF3KHZhbHVlKTsNCiAgICAgICAgfQ0KICAgICAgICBjb25zdCB0YXJnZXQgPSB0b1Jhdyh0aGlzKTsNCiAgICAgICAgY29uc3QgeyBoYXMsIGdldCB9ID0gZ2V0UHJvdG8odGFyZ2V0KTsNCiAgICAgICAgbGV0IGhhZEtleSA9IGhhcy5jYWxsKHRhcmdldCwga2V5KTsNCiAgICAgICAgaWYgKCFoYWRLZXkpIHsNCiAgICAgICAgICBrZXkgPSB0b1JhdyhrZXkpOw0KICAgICAgICAgIGhhZEtleSA9IGhhcy5jYWxsKHRhcmdldCwga2V5KTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBjaGVja0lkZW50aXR5S2V5cyh0YXJnZXQsIGhhcywga2V5KTsNCiAgICAgICAgfQ0KICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IGdldC5jYWxsKHRhcmdldCwga2V5KTsNCiAgICAgICAgdGFyZ2V0LnNldChrZXksIHZhbHVlKTsNCiAgICAgICAgaWYgKCFoYWRLZXkpIHsNCiAgICAgICAgICB0cmlnZ2VyKHRhcmdldCwgImFkZCIsIGtleSwgdmFsdWUpOw0KICAgICAgICB9IGVsc2UgaWYgKGhhc0NoYW5nZWQodmFsdWUsIG9sZFZhbHVlKSkgew0KICAgICAgICAgIHRyaWdnZXIodGFyZ2V0LCAic2V0Iiwga2V5LCB2YWx1ZSwgb2xkVmFsdWUpOw0KICAgICAgICB9DQogICAgICAgIHJldHVybiB0aGlzOw0KICAgICAgfSwNCiAgICAgIGRlbGV0ZShrZXkpIHsNCiAgICAgICAgY29uc3QgdGFyZ2V0ID0gdG9SYXcodGhpcyk7DQogICAgICAgIGNvbnN0IHsgaGFzLCBnZXQgfSA9IGdldFByb3RvKHRhcmdldCk7DQogICAgICAgIGxldCBoYWRLZXkgPSBoYXMuY2FsbCh0YXJnZXQsIGtleSk7DQogICAgICAgIGlmICghaGFkS2V5KSB7DQogICAgICAgICAga2V5ID0gdG9SYXcoa2V5KTsNCiAgICAgICAgICBoYWRLZXkgPSBoYXMuY2FsbCh0YXJnZXQsIGtleSk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgY2hlY2tJZGVudGl0eUtleXModGFyZ2V0LCBoYXMsIGtleSk7DQogICAgICAgIH0NCiAgICAgICAgY29uc3Qgb2xkVmFsdWUgPSBnZXQgPyBnZXQuY2FsbCh0YXJnZXQsIGtleSkgOiB2b2lkIDA7DQogICAgICAgIGNvbnN0IHJlc3VsdCA9IHRhcmdldC5kZWxldGUoa2V5KTsNCiAgICAgICAgaWYgKGhhZEtleSkgew0KICAgICAgICAgIHRyaWdnZXIodGFyZ2V0LCAiZGVsZXRlIiwga2V5LCB2b2lkIDAsIG9sZFZhbHVlKTsNCiAgICAgICAgfQ0KICAgICAgICByZXR1cm4gcmVzdWx0Ow0KICAgICAgfSwNCiAgICAgIGNsZWFyKCkgew0KICAgICAgICBjb25zdCB0YXJnZXQgPSB0b1Jhdyh0aGlzKTsNCiAgICAgICAgY29uc3QgaGFkSXRlbXMgPSB0YXJnZXQuc2l6ZSAhPT0gMDsNCiAgICAgICAgY29uc3Qgb2xkVGFyZ2V0ID0gaXNNYXAodGFyZ2V0KSA/IG5ldyBNYXAodGFyZ2V0KSA6IG5ldyBTZXQodGFyZ2V0KSA7DQogICAgICAgIGNvbnN0IHJlc3VsdCA9IHRhcmdldC5jbGVhcigpOw0KICAgICAgICBpZiAoaGFkSXRlbXMpIHsNCiAgICAgICAgICB0cmlnZ2VyKA0KICAgICAgICAgICAgdGFyZ2V0LA0KICAgICAgICAgICAgImNsZWFyIiwNCiAgICAgICAgICAgIHZvaWQgMCwNCiAgICAgICAgICAgIHZvaWQgMCwNCiAgICAgICAgICAgIG9sZFRhcmdldA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIHJlc3VsdDsNCiAgICAgIH0NCiAgICB9DQogICk7DQogIGNvbnN0IGl0ZXJhdG9yTWV0aG9kcyA9IFsNCiAgICAia2V5cyIsDQogICAgInZhbHVlcyIsDQogICAgImVudHJpZXMiLA0KICAgIFN5bWJvbC5pdGVyYXRvcg0KICBdOw0KICBpdGVyYXRvck1ldGhvZHMuZm9yRWFjaCgobWV0aG9kKSA9PiB7DQogICAgaW5zdHJ1bWVudGF0aW9uc1ttZXRob2RdID0gY3JlYXRlSXRlcmFibGVNZXRob2QobWV0aG9kLCByZWFkb25seSwgc2hhbGxvdyk7DQogIH0pOw0KICByZXR1cm4gaW5zdHJ1bWVudGF0aW9uczsNCn0NCmZ1bmN0aW9uIGNyZWF0ZUluc3RydW1lbnRhdGlvbkdldHRlcihpc1JlYWRvbmx5Miwgc2hhbGxvdykgew0KICBjb25zdCBpbnN0cnVtZW50YXRpb25zID0gY3JlYXRlSW5zdHJ1bWVudGF0aW9ucyhpc1JlYWRvbmx5Miwgc2hhbGxvdyk7DQogIHJldHVybiAodGFyZ2V0LCBrZXksIHJlY2VpdmVyKSA9PiB7DQogICAgaWYgKGtleSA9PT0gIl9fdl9pc1JlYWN0aXZlIikgew0KICAgICAgcmV0dXJuICFpc1JlYWRvbmx5MjsNCiAgICB9IGVsc2UgaWYgKGtleSA9PT0gIl9fdl9pc1JlYWRvbmx5Iikgew0KICAgICAgcmV0dXJuIGlzUmVhZG9ubHkyOw0KICAgIH0gZWxzZSBpZiAoa2V5ID09PSAiX192X3JhdyIpIHsNCiAgICAgIHJldHVybiB0YXJnZXQ7DQogICAgfQ0KICAgIHJldHVybiBSZWZsZWN0LmdldCgNCiAgICAgIGhhc093bihpbnN0cnVtZW50YXRpb25zLCBrZXkpICYmIGtleSBpbiB0YXJnZXQgPyBpbnN0cnVtZW50YXRpb25zIDogdGFyZ2V0LA0KICAgICAga2V5LA0KICAgICAgcmVjZWl2ZXINCiAgICApOw0KICB9Ow0KfQ0KY29uc3QgbXV0YWJsZUNvbGxlY3Rpb25IYW5kbGVycyA9IHsNCiAgZ2V0OiAvKiBAX19QVVJFX18gKi8gY3JlYXRlSW5zdHJ1bWVudGF0aW9uR2V0dGVyKGZhbHNlLCBmYWxzZSkNCn07DQpjb25zdCBzaGFsbG93Q29sbGVjdGlvbkhhbmRsZXJzID0gew0KICBnZXQ6IC8qIEBfX1BVUkVfXyAqLyBjcmVhdGVJbnN0cnVtZW50YXRpb25HZXR0ZXIoZmFsc2UsIHRydWUpDQp9Ow0KY29uc3QgcmVhZG9ubHlDb2xsZWN0aW9uSGFuZGxlcnMgPSB7DQogIGdldDogLyogQF9fUFVSRV9fICovIGNyZWF0ZUluc3RydW1lbnRhdGlvbkdldHRlcih0cnVlLCBmYWxzZSkNCn07DQpjb25zdCBzaGFsbG93UmVhZG9ubHlDb2xsZWN0aW9uSGFuZGxlcnMgPSB7DQogIGdldDogLyogQF9fUFVSRV9fICovIGNyZWF0ZUluc3RydW1lbnRhdGlvbkdldHRlcih0cnVlLCB0cnVlKQ0KfTsNCmZ1bmN0aW9uIGNoZWNrSWRlbnRpdHlLZXlzKHRhcmdldCwgaGFzLCBrZXkpIHsNCiAgY29uc3QgcmF3S2V5ID0gdG9SYXcoa2V5KTsNCiAgaWYgKHJhd0tleSAhPT0ga2V5ICYmIGhhcy5jYWxsKHRhcmdldCwgcmF3S2V5KSkgew0KICAgIGNvbnN0IHR5cGUgPSB0b1Jhd1R5cGUodGFyZ2V0KTsNCiAgICB3YXJuJDIoDQogICAgICBgUmVhY3RpdmUgJHt0eXBlfSBjb250YWlucyBib3RoIHRoZSByYXcgYW5kIHJlYWN0aXZlIHZlcnNpb25zIG9mIHRoZSBzYW1lIG9iamVjdCR7dHlwZSA9PT0gYE1hcGAgPyBgIGFzIGtleXNgIDogYGB9LCB3aGljaCBjYW4gbGVhZCB0byBpbmNvbnNpc3RlbmNpZXMuIEF2b2lkIGRpZmZlcmVudGlhdGluZyBiZXR3ZWVuIHRoZSByYXcgYW5kIHJlYWN0aXZlIHZlcnNpb25zIG9mIGFuIG9iamVjdCBhbmQgb25seSB1c2UgdGhlIHJlYWN0aXZlIHZlcnNpb24gaWYgcG9zc2libGUuYA0KICAgICk7DQogIH0NCn0NCg0KY29uc3QgcmVhY3RpdmVNYXAgPSAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtNYXAoKTsNCmNvbnN0IHNoYWxsb3dSZWFjdGl2ZU1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgV2Vha01hcCgpOw0KY29uc3QgcmVhZG9ubHlNYXAgPSAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtNYXAoKTsNCmNvbnN0IHNoYWxsb3dSZWFkb25seU1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgV2Vha01hcCgpOw0KZnVuY3Rpb24gdGFyZ2V0VHlwZU1hcChyYXdUeXBlKSB7DQogIHN3aXRjaCAocmF3VHlwZSkgew0KICAgIGNhc2UgIk9iamVjdCI6DQogICAgY2FzZSAiQXJyYXkiOg0KICAgICAgcmV0dXJuIDEgLyogQ09NTU9OICovOw0KICAgIGNhc2UgIk1hcCI6DQogICAgY2FzZSAiU2V0IjoNCiAgICBjYXNlICJXZWFrTWFwIjoNCiAgICBjYXNlICJXZWFrU2V0IjoNCiAgICAgIHJldHVybiAyIC8qIENPTExFQ1RJT04gKi87DQogICAgZGVmYXVsdDoNCiAgICAgIHJldHVybiAwIC8qIElOVkFMSUQgKi87DQogIH0NCn0NCmZ1bmN0aW9uIGdldFRhcmdldFR5cGUodmFsdWUpIHsNCiAgcmV0dXJuIHZhbHVlWyJfX3Zfc2tpcCJdIHx8ICFPYmplY3QuaXNFeHRlbnNpYmxlKHZhbHVlKSA/IDAgLyogSU5WQUxJRCAqLyA6IHRhcmdldFR5cGVNYXAodG9SYXdUeXBlKHZhbHVlKSk7DQp9DQpmdW5jdGlvbiByZWFjdGl2ZSh0YXJnZXQpIHsNCiAgaWYgKGlzUmVhZG9ubHkodGFyZ2V0KSkgew0KICAgIHJldHVybiB0YXJnZXQ7DQogIH0NCiAgcmV0dXJuIGNyZWF0ZVJlYWN0aXZlT2JqZWN0KA0KICAgIHRhcmdldCwNCiAgICBmYWxzZSwNCiAgICBtdXRhYmxlSGFuZGxlcnMsDQogICAgbXV0YWJsZUNvbGxlY3Rpb25IYW5kbGVycywNCiAgICByZWFjdGl2ZU1hcA0KICApOw0KfQ0KZnVuY3Rpb24gc2hhbGxvd1JlYWN0aXZlKHRhcmdldCkgew0KICByZXR1cm4gY3JlYXRlUmVhY3RpdmVPYmplY3QoDQogICAgdGFyZ2V0LA0KICAgIGZhbHNlLA0KICAgIHNoYWxsb3dSZWFjdGl2ZUhhbmRsZXJzLA0KICAgIHNoYWxsb3dDb2xsZWN0aW9uSGFuZGxlcnMsDQogICAgc2hhbGxvd1JlYWN0aXZlTWFwDQogICk7DQp9DQpmdW5jdGlvbiByZWFkb25seSh0YXJnZXQpIHsNCiAgcmV0dXJuIGNyZWF0ZVJlYWN0aXZlT2JqZWN0KA0KICAgIHRhcmdldCwNCiAgICB0cnVlLA0KICAgIHJlYWRvbmx5SGFuZGxlcnMsDQogICAgcmVhZG9ubHlDb2xsZWN0aW9uSGFuZGxlcnMsDQogICAgcmVhZG9ubHlNYXANCiAgKTsNCn0NCmZ1bmN0aW9uIHNoYWxsb3dSZWFkb25seSh0YXJnZXQpIHsNCiAgcmV0dXJuIGNyZWF0ZVJlYWN0aXZlT2JqZWN0KA0KICAgIHRhcmdldCwNCiAgICB0cnVlLA0KICAgIHNoYWxsb3dSZWFkb25seUhhbmRsZXJzLA0KICAgIHNoYWxsb3dSZWFkb25seUNvbGxlY3Rpb25IYW5kbGVycywNCiAgICBzaGFsbG93UmVhZG9ubHlNYXANCiAgKTsNCn0NCmZ1bmN0aW9uIGNyZWF0ZVJlYWN0aXZlT2JqZWN0KHRhcmdldCwgaXNSZWFkb25seTIsIGJhc2VIYW5kbGVycywgY29sbGVjdGlvbkhhbmRsZXJzLCBwcm94eU1hcCkgew0KICBpZiAoIWlzT2JqZWN0KHRhcmdldCkpIHsNCiAgICB7DQogICAgICB3YXJuJDIoDQogICAgICAgIGB2YWx1ZSBjYW5ub3QgYmUgbWFkZSAke2lzUmVhZG9ubHkyID8gInJlYWRvbmx5IiA6ICJyZWFjdGl2ZSJ9OiAke1N0cmluZygNCiAgICAgICAgICB0YXJnZXQNCiAgICAgICAgKX1gDQogICAgICApOw0KICAgIH0NCiAgICByZXR1cm4gdGFyZ2V0Ow0KICB9DQogIGlmICh0YXJnZXRbIl9fdl9yYXciXSAmJiAhKGlzUmVhZG9ubHkyICYmIHRhcmdldFsiX192X2lzUmVhY3RpdmUiXSkpIHsNCiAgICByZXR1cm4gdGFyZ2V0Ow0KICB9DQogIGNvbnN0IHRhcmdldFR5cGUgPSBnZXRUYXJnZXRUeXBlKHRhcmdldCk7DQogIGlmICh0YXJnZXRUeXBlID09PSAwIC8qIElOVkFMSUQgKi8pIHsNCiAgICByZXR1cm4gdGFyZ2V0Ow0KICB9DQogIGNvbnN0IGV4aXN0aW5nUHJveHkgPSBwcm94eU1hcC5nZXQodGFyZ2V0KTsNCiAgaWYgKGV4aXN0aW5nUHJveHkpIHsNCiAgICByZXR1cm4gZXhpc3RpbmdQcm94eTsNCiAgfQ0KICBjb25zdCBwcm94eSA9IG5ldyBQcm94eSgNCiAgICB0YXJnZXQsDQogICAgdGFyZ2V0VHlwZSA9PT0gMiAvKiBDT0xMRUNUSU9OICovID8gY29sbGVjdGlvbkhhbmRsZXJzIDogYmFzZUhhbmRsZXJzDQogICk7DQogIHByb3h5TWFwLnNldCh0YXJnZXQsIHByb3h5KTsNCiAgcmV0dXJuIHByb3h5Ow0KfQ0KZnVuY3Rpb24gaXNSZWFjdGl2ZSh2YWx1ZSkgew0KICBpZiAoaXNSZWFkb25seSh2YWx1ZSkpIHsNCiAgICByZXR1cm4gaXNSZWFjdGl2ZSh2YWx1ZVsiX192X3JhdyJdKTsNCiAgfQ0KICByZXR1cm4gISEodmFsdWUgJiYgdmFsdWVbIl9fdl9pc1JlYWN0aXZlIl0pOw0KfQ0KZnVuY3Rpb24gaXNSZWFkb25seSh2YWx1ZSkgew0KICByZXR1cm4gISEodmFsdWUgJiYgdmFsdWVbIl9fdl9pc1JlYWRvbmx5Il0pOw0KfQ0KZnVuY3Rpb24gaXNTaGFsbG93KHZhbHVlKSB7DQogIHJldHVybiAhISh2YWx1ZSAmJiB2YWx1ZVsiX192X2lzU2hhbGxvdyJdKTsNCn0NCmZ1bmN0aW9uIGlzUHJveHkodmFsdWUpIHsNCiAgcmV0dXJuIHZhbHVlID8gISF2YWx1ZVsiX192X3JhdyJdIDogZmFsc2U7DQp9DQpmdW5jdGlvbiB0b1JhdyhvYnNlcnZlZCkgew0KICBjb25zdCByYXcgPSBvYnNlcnZlZCAmJiBvYnNlcnZlZFsiX192X3JhdyJdOw0KICByZXR1cm4gcmF3ID8gdG9SYXcocmF3KSA6IG9ic2VydmVkOw0KfQ0KZnVuY3Rpb24gbWFya1Jhdyh2YWx1ZSkgew0KICBpZiAoIWhhc093bih2YWx1ZSwgIl9fdl9za2lwIikgJiYgT2JqZWN0LmlzRXh0ZW5zaWJsZSh2YWx1ZSkpIHsNCiAgICBkZWYodmFsdWUsICJfX3Zfc2tpcCIsIHRydWUpOw0KICB9DQogIHJldHVybiB2YWx1ZTsNCn0NCmNvbnN0IHRvUmVhY3RpdmUgPSAodmFsdWUpID0+IGlzT2JqZWN0KHZhbHVlKSA/IHJlYWN0aXZlKHZhbHVlKSA6IHZhbHVlOw0KY29uc3QgdG9SZWFkb25seSA9ICh2YWx1ZSkgPT4gaXNPYmplY3QodmFsdWUpID8gcmVhZG9ubHkodmFsdWUpIDogdmFsdWU7DQoNCmZ1bmN0aW9uIGlzUmVmKHIpIHsNCiAgcmV0dXJuIHIgPyByWyJfX3ZfaXNSZWYiXSA9PT0gdHJ1ZSA6IGZhbHNlOw0KfQ0KZnVuY3Rpb24gcmVmKHZhbHVlKSB7DQogIHJldHVybiBjcmVhdGVSZWYodmFsdWUsIGZhbHNlKTsNCn0NCmZ1bmN0aW9uIHNoYWxsb3dSZWYodmFsdWUpIHsNCiAgcmV0dXJuIGNyZWF0ZVJlZih2YWx1ZSwgdHJ1ZSk7DQp9DQpmdW5jdGlvbiBjcmVhdGVSZWYocmF3VmFsdWUsIHNoYWxsb3cpIHsNCiAgaWYgKGlzUmVmKHJhd1ZhbHVlKSkgew0KICAgIHJldHVybiByYXdWYWx1ZTsNCiAgfQ0KICByZXR1cm4gbmV3IFJlZkltcGwocmF3VmFsdWUsIHNoYWxsb3cpOw0KfQ0KY2xhc3MgUmVmSW1wbCB7DQogIGNvbnN0cnVjdG9yKHZhbHVlLCBpc1NoYWxsb3cyKSB7DQogICAgdGhpcy5kZXAgPSBuZXcgRGVwKCk7DQogICAgdGhpc1siX192X2lzUmVmIl0gPSB0cnVlOw0KICAgIHRoaXNbIl9fdl9pc1NoYWxsb3ciXSA9IGZhbHNlOw0KICAgIHRoaXMuX3Jhd1ZhbHVlID0gaXNTaGFsbG93MiA/IHZhbHVlIDogdG9SYXcodmFsdWUpOw0KICAgIHRoaXMuX3ZhbHVlID0gaXNTaGFsbG93MiA/IHZhbHVlIDogdG9SZWFjdGl2ZSh2YWx1ZSk7DQogICAgdGhpc1siX192X2lzU2hhbGxvdyJdID0gaXNTaGFsbG93MjsNCiAgfQ0KICBnZXQgdmFsdWUoKSB7DQogICAgew0KICAgICAgdGhpcy5kZXAudHJhY2soew0KICAgICAgICB0YXJnZXQ6IHRoaXMsDQogICAgICAgIHR5cGU6ICJnZXQiLA0KICAgICAgICBrZXk6ICJ2YWx1ZSINCiAgICAgIH0pOw0KICAgIH0NCiAgICByZXR1cm4gdGhpcy5fdmFsdWU7DQogIH0NCiAgc2V0IHZhbHVlKG5ld1ZhbHVlKSB7DQogICAgY29uc3Qgb2xkVmFsdWUgPSB0aGlzLl9yYXdWYWx1ZTsNCiAgICBjb25zdCB1c2VEaXJlY3RWYWx1ZSA9IHRoaXNbIl9fdl9pc1NoYWxsb3ciXSB8fCBpc1NoYWxsb3cobmV3VmFsdWUpIHx8IGlzUmVhZG9ubHkobmV3VmFsdWUpOw0KICAgIG5ld1ZhbHVlID0gdXNlRGlyZWN0VmFsdWUgPyBuZXdWYWx1ZSA6IHRvUmF3KG5ld1ZhbHVlKTsNCiAgICBpZiAoaGFzQ2hhbmdlZChuZXdWYWx1ZSwgb2xkVmFsdWUpKSB7DQogICAgICB0aGlzLl9yYXdWYWx1ZSA9IG5ld1ZhbHVlOw0KICAgICAgdGhpcy5fdmFsdWUgPSB1c2VEaXJlY3RWYWx1ZSA/IG5ld1ZhbHVlIDogdG9SZWFjdGl2ZShuZXdWYWx1ZSk7DQogICAgICB7DQogICAgICAgIHRoaXMuZGVwLnRyaWdnZXIoew0KICAgICAgICAgIHRhcmdldDogdGhpcywNCiAgICAgICAgICB0eXBlOiAic2V0IiwNCiAgICAgICAgICBrZXk6ICJ2YWx1ZSIsDQogICAgICAgICAgbmV3VmFsdWUsDQogICAgICAgICAgb2xkVmFsdWUNCiAgICAgICAgfSk7DQogICAgICB9DQogICAgfQ0KICB9DQp9DQpmdW5jdGlvbiB0cmlnZ2VyUmVmKHJlZjIpIHsNCiAgaWYgKHJlZjIuZGVwKSB7DQogICAgew0KICAgICAgcmVmMi5kZXAudHJpZ2dlcih7DQogICAgICAgIHRhcmdldDogcmVmMiwNCiAgICAgICAgdHlwZTogInNldCIsDQogICAgICAgIGtleTogInZhbHVlIiwNCiAgICAgICAgbmV3VmFsdWU6IHJlZjIuX3ZhbHVlDQogICAgICB9KTsNCiAgICB9DQogIH0NCn0NCmZ1bmN0aW9uIHVucmVmKHJlZjIpIHsNCiAgcmV0dXJuIGlzUmVmKHJlZjIpID8gcmVmMi52YWx1ZSA6IHJlZjI7DQp9DQpmdW5jdGlvbiB0b1ZhbHVlKHNvdXJjZSkgew0KICByZXR1cm4gaXNGdW5jdGlvbihzb3VyY2UpID8gc291cmNlKCkgOiB1bnJlZihzb3VyY2UpOw0KfQ0KY29uc3Qgc2hhbGxvd1Vud3JhcEhhbmRsZXJzID0gew0KICBnZXQ6ICh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpID0+IGtleSA9PT0gIl9fdl9yYXciID8gdGFyZ2V0IDogdW5yZWYoUmVmbGVjdC5nZXQodGFyZ2V0LCBrZXksIHJlY2VpdmVyKSksDQogIHNldDogKHRhcmdldCwga2V5LCB2YWx1ZSwgcmVjZWl2ZXIpID0+IHsNCiAgICBjb25zdCBvbGRWYWx1ZSA9IHRhcmdldFtrZXldOw0KICAgIGlmIChpc1JlZihvbGRWYWx1ZSkgJiYgIWlzUmVmKHZhbHVlKSkgew0KICAgICAgb2xkVmFsdWUudmFsdWUgPSB2YWx1ZTsNCiAgICAgIHJldHVybiB0cnVlOw0KICAgIH0gZWxzZSB7DQogICAgICByZXR1cm4gUmVmbGVjdC5zZXQodGFyZ2V0LCBrZXksIHZhbHVlLCByZWNlaXZlcik7DQogICAgfQ0KICB9DQp9Ow0KZnVuY3Rpb24gcHJveHlSZWZzKG9iamVjdFdpdGhSZWZzKSB7DQogIHJldHVybiBpc1JlYWN0aXZlKG9iamVjdFdpdGhSZWZzKSA/IG9iamVjdFdpdGhSZWZzIDogbmV3IFByb3h5KG9iamVjdFdpdGhSZWZzLCBzaGFsbG93VW53cmFwSGFuZGxlcnMpOw0KfQ0KY2xhc3MgQ3VzdG9tUmVmSW1wbCB7DQogIGNvbnN0cnVjdG9yKGZhY3RvcnkpIHsNCiAgICB0aGlzWyJfX3ZfaXNSZWYiXSA9IHRydWU7DQogICAgdGhpcy5fdmFsdWUgPSB2b2lkIDA7DQogICAgY29uc3QgZGVwID0gdGhpcy5kZXAgPSBuZXcgRGVwKCk7DQogICAgY29uc3QgeyBnZXQsIHNldCB9ID0gZmFjdG9yeShkZXAudHJhY2suYmluZChkZXApLCBkZXAudHJpZ2dlci5iaW5kKGRlcCkpOw0KICAgIHRoaXMuX2dldCA9IGdldDsNCiAgICB0aGlzLl9zZXQgPSBzZXQ7DQogIH0NCiAgZ2V0IHZhbHVlKCkgew0KICAgIHJldHVybiB0aGlzLl92YWx1ZSA9IHRoaXMuX2dldCgpOw0KICB9DQogIHNldCB2YWx1ZShuZXdWYWwpIHsNCiAgICB0aGlzLl9zZXQobmV3VmFsKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gY3VzdG9tUmVmKGZhY3RvcnkpIHsNCiAgcmV0dXJuIG5ldyBDdXN0b21SZWZJbXBsKGZhY3RvcnkpOw0KfQ0KZnVuY3Rpb24gdG9SZWZzKG9iamVjdCkgew0KICBpZiAoIWlzUHJveHkob2JqZWN0KSkgew0KICAgIHdhcm4kMihgdG9SZWZzKCkgZXhwZWN0cyBhIHJlYWN0aXZlIG9iamVjdCBidXQgcmVjZWl2ZWQgYSBwbGFpbiBvbmUuYCk7DQogIH0NCiAgY29uc3QgcmV0ID0gaXNBcnJheShvYmplY3QpID8gbmV3IEFycmF5KG9iamVjdC5sZW5ndGgpIDoge307DQogIGZvciAoY29uc3Qga2V5IGluIG9iamVjdCkgew0KICAgIHJldFtrZXldID0gcHJvcGVydHlUb1JlZihvYmplY3QsIGtleSk7DQogIH0NCiAgcmV0dXJuIHJldDsNCn0NCmNsYXNzIE9iamVjdFJlZkltcGwgew0KICBjb25zdHJ1Y3Rvcihfb2JqZWN0LCBfa2V5LCBfZGVmYXVsdFZhbHVlKSB7DQogICAgdGhpcy5fb2JqZWN0ID0gX29iamVjdDsNCiAgICB0aGlzLl9rZXkgPSBfa2V5Ow0KICAgIHRoaXMuX2RlZmF1bHRWYWx1ZSA9IF9kZWZhdWx0VmFsdWU7DQogICAgdGhpc1siX192X2lzUmVmIl0gPSB0cnVlOw0KICAgIHRoaXMuX3ZhbHVlID0gdm9pZCAwOw0KICB9DQogIGdldCB2YWx1ZSgpIHsNCiAgICBjb25zdCB2YWwgPSB0aGlzLl9vYmplY3RbdGhpcy5fa2V5XTsNCiAgICByZXR1cm4gdGhpcy5fdmFsdWUgPSB2YWwgPT09IHZvaWQgMCA/IHRoaXMuX2RlZmF1bHRWYWx1ZSA6IHZhbDsNCiAgfQ0KICBzZXQgdmFsdWUobmV3VmFsKSB7DQogICAgdGhpcy5fb2JqZWN0W3RoaXMuX2tleV0gPSBuZXdWYWw7DQogIH0NCiAgZ2V0IGRlcCgpIHsNCiAgICByZXR1cm4gZ2V0RGVwRnJvbVJlYWN0aXZlKHRvUmF3KHRoaXMuX29iamVjdCksIHRoaXMuX2tleSk7DQogIH0NCn0NCmNsYXNzIEdldHRlclJlZkltcGwgew0KICBjb25zdHJ1Y3RvcihfZ2V0dGVyKSB7DQogICAgdGhpcy5fZ2V0dGVyID0gX2dldHRlcjsNCiAgICB0aGlzWyJfX3ZfaXNSZWYiXSA9IHRydWU7DQogICAgdGhpc1siX192X2lzUmVhZG9ubHkiXSA9IHRydWU7DQogICAgdGhpcy5fdmFsdWUgPSB2b2lkIDA7DQogIH0NCiAgZ2V0IHZhbHVlKCkgew0KICAgIHJldHVybiB0aGlzLl92YWx1ZSA9IHRoaXMuX2dldHRlcigpOw0KICB9DQp9DQpmdW5jdGlvbiB0b1JlZihzb3VyY2UsIGtleSwgZGVmYXVsdFZhbHVlKSB7DQogIGlmIChpc1JlZihzb3VyY2UpKSB7DQogICAgcmV0dXJuIHNvdXJjZTsNCiAgfSBlbHNlIGlmIChpc0Z1bmN0aW9uKHNvdXJjZSkpIHsNCiAgICByZXR1cm4gbmV3IEdldHRlclJlZkltcGwoc291cmNlKTsNCiAgfSBlbHNlIGlmIChpc09iamVjdChzb3VyY2UpICYmIGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7DQogICAgcmV0dXJuIHByb3BlcnR5VG9SZWYoc291cmNlLCBrZXksIGRlZmF1bHRWYWx1ZSk7DQogIH0gZWxzZSB7DQogICAgcmV0dXJuIHJlZihzb3VyY2UpOw0KICB9DQp9DQpmdW5jdGlvbiBwcm9wZXJ0eVRvUmVmKHNvdXJjZSwga2V5LCBkZWZhdWx0VmFsdWUpIHsNCiAgY29uc3QgdmFsID0gc291cmNlW2tleV07DQogIHJldHVybiBpc1JlZih2YWwpID8gdmFsIDogbmV3IE9iamVjdFJlZkltcGwoc291cmNlLCBrZXksIGRlZmF1bHRWYWx1ZSk7DQp9DQoNCmNsYXNzIENvbXB1dGVkUmVmSW1wbCB7DQogIGNvbnN0cnVjdG9yKGZuLCBzZXR0ZXIsIGlzU1NSKSB7DQogICAgdGhpcy5mbiA9IGZuOw0KICAgIHRoaXMuc2V0dGVyID0gc2V0dGVyOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuX3ZhbHVlID0gdm9pZCAwOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuZGVwID0gbmV3IERlcCh0aGlzKTsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLl9fdl9pc1JlZiA9IHRydWU7DQogICAgLy8gVE9ETyBpc29sYXRlZERlY2xhcmF0aW9ucyAiX192X2lzUmVhZG9ubHkiDQogICAgLy8gQSBjb21wdXRlZCBpcyBhbHNvIGEgc3Vic2NyaWJlciB0aGF0IHRyYWNrcyBvdGhlciBkZXBzDQogICAgLyoqDQogICAgICogQGludGVybmFsDQogICAgICovDQogICAgdGhpcy5kZXBzID0gdm9pZCAwOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuZGVwc1RhaWwgPSB2b2lkIDA7DQogICAgLyoqDQogICAgICogQGludGVybmFsDQogICAgICovDQogICAgdGhpcy5mbGFncyA9IDE2Ow0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuZ2xvYmFsVmVyc2lvbiA9IGdsb2JhbFZlcnNpb24gLSAxOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMubmV4dCA9IHZvaWQgMDsNCiAgICAvLyBmb3IgYmFja3dhcmRzIGNvbXBhdA0KICAgIHRoaXMuZWZmZWN0ID0gdGhpczsNCiAgICB0aGlzWyJfX3ZfaXNSZWFkb25seSJdID0gIXNldHRlcjsNCiAgICB0aGlzLmlzU1NSID0gaXNTU1I7DQogIH0NCiAgLyoqDQogICAqIEBpbnRlcm5hbA0KICAgKi8NCiAgbm90aWZ5KCkgew0KICAgIHRoaXMuZmxhZ3MgfD0gMTY7DQogICAgaWYgKCEodGhpcy5mbGFncyAmIDgpICYmIC8vIGF2b2lkIGluZmluaXRlIHNlbGYgcmVjdXJzaW9uDQogICAgYWN0aXZlU3ViICE9PSB0aGlzKSB7DQogICAgICBiYXRjaCh0aGlzLCB0cnVlKTsNCiAgICAgIHJldHVybiB0cnVlOw0KICAgIH0NCiAgfQ0KICBnZXQgdmFsdWUoKSB7DQogICAgY29uc3QgbGluayA9IHRoaXMuZGVwLnRyYWNrKHsNCiAgICAgIHRhcmdldDogdGhpcywNCiAgICAgIHR5cGU6ICJnZXQiLA0KICAgICAga2V5OiAidmFsdWUiDQogICAgfSkgOw0KICAgIHJlZnJlc2hDb21wdXRlZCh0aGlzKTsNCiAgICBpZiAobGluaykgew0KICAgICAgbGluay52ZXJzaW9uID0gdGhpcy5kZXAudmVyc2lvbjsNCiAgICB9DQogICAgcmV0dXJuIHRoaXMuX3ZhbHVlOw0KICB9DQogIHNldCB2YWx1ZShuZXdWYWx1ZSkgew0KICAgIGlmICh0aGlzLnNldHRlcikgew0KICAgICAgdGhpcy5zZXR0ZXIobmV3VmFsdWUpOw0KICAgIH0gZWxzZSB7DQogICAgICB3YXJuJDIoIldyaXRlIG9wZXJhdGlvbiBmYWlsZWQ6IGNvbXB1dGVkIHZhbHVlIGlzIHJlYWRvbmx5Iik7DQogICAgfQ0KICB9DQp9DQpmdW5jdGlvbiBjb21wdXRlZCQxKGdldHRlck9yT3B0aW9ucywgZGVidWdPcHRpb25zLCBpc1NTUiA9IGZhbHNlKSB7DQogIGxldCBnZXR0ZXI7DQogIGxldCBzZXR0ZXI7DQogIGlmIChpc0Z1bmN0aW9uKGdldHRlck9yT3B0aW9ucykpIHsNCiAgICBnZXR0ZXIgPSBnZXR0ZXJPck9wdGlvbnM7DQogIH0gZWxzZSB7DQogICAgZ2V0dGVyID0gZ2V0dGVyT3JPcHRpb25zLmdldDsNCiAgICBzZXR0ZXIgPSBnZXR0ZXJPck9wdGlvbnMuc2V0Ow0KICB9DQogIGNvbnN0IGNSZWYgPSBuZXcgQ29tcHV0ZWRSZWZJbXBsKGdldHRlciwgc2V0dGVyLCBpc1NTUik7DQogIGlmIChkZWJ1Z09wdGlvbnMgJiYgIWlzU1NSKSB7DQogICAgY1JlZi5vblRyYWNrID0gZGVidWdPcHRpb25zLm9uVHJhY2s7DQogICAgY1JlZi5vblRyaWdnZXIgPSBkZWJ1Z09wdGlvbnMub25UcmlnZ2VyOw0KICB9DQogIHJldHVybiBjUmVmOw0KfQ0KDQpjb25zdCBUcmFja09wVHlwZXMgPSB7DQogICJHRVQiOiAiZ2V0IiwNCiAgIkhBUyI6ICJoYXMiLA0KICAiSVRFUkFURSI6ICJpdGVyYXRlIg0KfTsNCmNvbnN0IFRyaWdnZXJPcFR5cGVzID0gew0KICAiU0VUIjogInNldCIsDQogICJBREQiOiAiYWRkIiwNCiAgIkRFTEVURSI6ICJkZWxldGUiLA0KICAiQ0xFQVIiOiAiY2xlYXIiDQp9Ow0KDQpjb25zdCBJTklUSUFMX1dBVENIRVJfVkFMVUUgPSB7fTsNCmNvbnN0IGNsZWFudXBNYXAgPSAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtNYXAoKTsNCmxldCBhY3RpdmVXYXRjaGVyID0gdm9pZCAwOw0KZnVuY3Rpb24gZ2V0Q3VycmVudFdhdGNoZXIoKSB7DQogIHJldHVybiBhY3RpdmVXYXRjaGVyOw0KfQ0KZnVuY3Rpb24gb25XYXRjaGVyQ2xlYW51cChjbGVhbnVwRm4sIGZhaWxTaWxlbnRseSA9IGZhbHNlLCBvd25lciA9IGFjdGl2ZVdhdGNoZXIpIHsNCiAgaWYgKG93bmVyKSB7DQogICAgbGV0IGNsZWFudXBzID0gY2xlYW51cE1hcC5nZXQob3duZXIpOw0KICAgIGlmICghY2xlYW51cHMpIGNsZWFudXBNYXAuc2V0KG93bmVyLCBjbGVhbnVwcyA9IFtdKTsNCiAgICBjbGVhbnVwcy5wdXNoKGNsZWFudXBGbik7DQogIH0gZWxzZSBpZiAoIWZhaWxTaWxlbnRseSkgew0KICAgIHdhcm4kMigNCiAgICAgIGBvbldhdGNoZXJDbGVhbnVwKCkgd2FzIGNhbGxlZCB3aGVuIHRoZXJlIHdhcyBubyBhY3RpdmUgd2F0Y2hlciB0byBhc3NvY2lhdGUgd2l0aC5gDQogICAgKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gd2F0Y2gkMShzb3VyY2UsIGNiLCBvcHRpb25zID0gRU1QVFlfT0JKKSB7DQogIGNvbnN0IHsgaW1tZWRpYXRlLCBkZWVwLCBvbmNlLCBzY2hlZHVsZXIsIGF1Z21lbnRKb2IsIGNhbGwgfSA9IG9wdGlvbnM7DQogIGNvbnN0IHdhcm5JbnZhbGlkU291cmNlID0gKHMpID0+IHsNCiAgICAob3B0aW9ucy5vbldhcm4gfHwgd2FybiQyKSgNCiAgICAgIGBJbnZhbGlkIHdhdGNoIHNvdXJjZTogYCwNCiAgICAgIHMsDQogICAgICBgQSB3YXRjaCBzb3VyY2UgY2FuIG9ubHkgYmUgYSBnZXR0ZXIvZWZmZWN0IGZ1bmN0aW9uLCBhIHJlZiwgYSByZWFjdGl2ZSBvYmplY3QsIG9yIGFuIGFycmF5IG9mIHRoZXNlIHR5cGVzLmANCiAgICApOw0KICB9Ow0KICBjb25zdCByZWFjdGl2ZUdldHRlciA9IChzb3VyY2UyKSA9PiB7DQogICAgaWYgKGRlZXApIHJldHVybiBzb3VyY2UyOw0KICAgIGlmIChpc1NoYWxsb3coc291cmNlMikgfHwgZGVlcCA9PT0gZmFsc2UgfHwgZGVlcCA9PT0gMCkNCiAgICAgIHJldHVybiB0cmF2ZXJzZShzb3VyY2UyLCAxKTsNCiAgICByZXR1cm4gdHJhdmVyc2Uoc291cmNlMik7DQogIH07DQogIGxldCBlZmZlY3Q7DQogIGxldCBnZXR0ZXI7DQogIGxldCBjbGVhbnVwOw0KICBsZXQgYm91bmRDbGVhbnVwOw0KICBsZXQgZm9yY2VUcmlnZ2VyID0gZmFsc2U7DQogIGxldCBpc011bHRpU291cmNlID0gZmFsc2U7DQogIGlmIChpc1JlZihzb3VyY2UpKSB7DQogICAgZ2V0dGVyID0gKCkgPT4gc291cmNlLnZhbHVlOw0KICAgIGZvcmNlVHJpZ2dlciA9IGlzU2hhbGxvdyhzb3VyY2UpOw0KICB9IGVsc2UgaWYgKGlzUmVhY3RpdmUoc291cmNlKSkgew0KICAgIGdldHRlciA9ICgpID0+IHJlYWN0aXZlR2V0dGVyKHNvdXJjZSk7DQogICAgZm9yY2VUcmlnZ2VyID0gdHJ1ZTsNCiAgfSBlbHNlIGlmIChpc0FycmF5KHNvdXJjZSkpIHsNCiAgICBpc011bHRpU291cmNlID0gdHJ1ZTsNCiAgICBmb3JjZVRyaWdnZXIgPSBzb3VyY2Uuc29tZSgocykgPT4gaXNSZWFjdGl2ZShzKSB8fCBpc1NoYWxsb3cocykpOw0KICAgIGdldHRlciA9ICgpID0+IHNvdXJjZS5tYXAoKHMpID0+IHsNCiAgICAgIGlmIChpc1JlZihzKSkgew0KICAgICAgICByZXR1cm4gcy52YWx1ZTsNCiAgICAgIH0gZWxzZSBpZiAoaXNSZWFjdGl2ZShzKSkgew0KICAgICAgICByZXR1cm4gcmVhY3RpdmVHZXR0ZXIocyk7DQogICAgICB9IGVsc2UgaWYgKGlzRnVuY3Rpb24ocykpIHsNCiAgICAgICAgcmV0dXJuIGNhbGwgPyBjYWxsKHMsIDIpIDogcygpOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgd2FybkludmFsaWRTb3VyY2Uocyk7DQogICAgICB9DQogICAgfSk7DQogIH0gZWxzZSBpZiAoaXNGdW5jdGlvbihzb3VyY2UpKSB7DQogICAgaWYgKGNiKSB7DQogICAgICBnZXR0ZXIgPSBjYWxsID8gKCkgPT4gY2FsbChzb3VyY2UsIDIpIDogc291cmNlOw0KICAgIH0gZWxzZSB7DQogICAgICBnZXR0ZXIgPSAoKSA9PiB7DQogICAgICAgIGlmIChjbGVhbnVwKSB7DQogICAgICAgICAgcGF1c2VUcmFja2luZygpOw0KICAgICAgICAgIHRyeSB7DQogICAgICAgICAgICBjbGVhbnVwKCk7DQogICAgICAgICAgfSBmaW5hbGx5IHsNCiAgICAgICAgICAgIHJlc2V0VHJhY2tpbmcoKTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgY29uc3QgY3VycmVudEVmZmVjdCA9IGFjdGl2ZVdhdGNoZXI7DQogICAgICAgIGFjdGl2ZVdhdGNoZXIgPSBlZmZlY3Q7DQogICAgICAgIHRyeSB7DQogICAgICAgICAgcmV0dXJuIGNhbGwgPyBjYWxsKHNvdXJjZSwgMywgW2JvdW5kQ2xlYW51cF0pIDogc291cmNlKGJvdW5kQ2xlYW51cCk7DQogICAgICAgIH0gZmluYWxseSB7DQogICAgICAgICAgYWN0aXZlV2F0Y2hlciA9IGN1cnJlbnRFZmZlY3Q7DQogICAgICAgIH0NCiAgICAgIH07DQogICAgfQ0KICB9IGVsc2Ugew0KICAgIGdldHRlciA9IE5PT1A7DQogICAgd2FybkludmFsaWRTb3VyY2Uoc291cmNlKTsNCiAgfQ0KICBpZiAoY2IgJiYgZGVlcCkgew0KICAgIGNvbnN0IGJhc2VHZXR0ZXIgPSBnZXR0ZXI7DQogICAgY29uc3QgZGVwdGggPSBkZWVwID09PSB0cnVlID8gSW5maW5pdHkgOiBkZWVwOw0KICAgIGdldHRlciA9ICgpID0+IHRyYXZlcnNlKGJhc2VHZXR0ZXIoKSwgZGVwdGgpOw0KICB9DQogIGNvbnN0IHNjb3BlID0gZ2V0Q3VycmVudFNjb3BlKCk7DQogIGNvbnN0IHdhdGNoSGFuZGxlID0gKCkgPT4gew0KICAgIGVmZmVjdC5zdG9wKCk7DQogICAgaWYgKHNjb3BlICYmIHNjb3BlLmFjdGl2ZSkgew0KICAgICAgcmVtb3ZlKHNjb3BlLmVmZmVjdHMsIGVmZmVjdCk7DQogICAgfQ0KICB9Ow0KICBpZiAob25jZSAmJiBjYikgew0KICAgIGNvbnN0IF9jYiA9IGNiOw0KICAgIGNiID0gKC4uLmFyZ3MpID0+IHsNCiAgICAgIF9jYiguLi5hcmdzKTsNCiAgICAgIHdhdGNoSGFuZGxlKCk7DQogICAgfTsNCiAgfQ0KICBsZXQgb2xkVmFsdWUgPSBpc011bHRpU291cmNlID8gbmV3IEFycmF5KHNvdXJjZS5sZW5ndGgpLmZpbGwoSU5JVElBTF9XQVRDSEVSX1ZBTFVFKSA6IElOSVRJQUxfV0FUQ0hFUl9WQUxVRTsNCiAgY29uc3Qgam9iID0gKGltbWVkaWF0ZUZpcnN0UnVuKSA9PiB7DQogICAgaWYgKCEoZWZmZWN0LmZsYWdzICYgMSkgfHwgIWVmZmVjdC5kaXJ0eSAmJiAhaW1tZWRpYXRlRmlyc3RSdW4pIHsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgaWYgKGNiKSB7DQogICAgICBjb25zdCBuZXdWYWx1ZSA9IGVmZmVjdC5ydW4oKTsNCiAgICAgIGlmIChkZWVwIHx8IGZvcmNlVHJpZ2dlciB8fCAoaXNNdWx0aVNvdXJjZSA/IG5ld1ZhbHVlLnNvbWUoKHYsIGkpID0+IGhhc0NoYW5nZWQodiwgb2xkVmFsdWVbaV0pKSA6IGhhc0NoYW5nZWQobmV3VmFsdWUsIG9sZFZhbHVlKSkpIHsNCiAgICAgICAgaWYgKGNsZWFudXApIHsNCiAgICAgICAgICBjbGVhbnVwKCk7DQogICAgICAgIH0NCiAgICAgICAgY29uc3QgY3VycmVudFdhdGNoZXIgPSBhY3RpdmVXYXRjaGVyOw0KICAgICAgICBhY3RpdmVXYXRjaGVyID0gZWZmZWN0Ow0KICAgICAgICB0cnkgew0KICAgICAgICAgIGNvbnN0IGFyZ3MgPSBbDQogICAgICAgICAgICBuZXdWYWx1ZSwNCiAgICAgICAgICAgIC8vIHBhc3MgdW5kZWZpbmVkIGFzIHRoZSBvbGQgdmFsdWUgd2hlbiBpdCdzIGNoYW5nZWQgZm9yIHRoZSBmaXJzdCB0aW1lDQogICAgICAgICAgICBvbGRWYWx1ZSA9PT0gSU5JVElBTF9XQVRDSEVSX1ZBTFVFID8gdm9pZCAwIDogaXNNdWx0aVNvdXJjZSAmJiBvbGRWYWx1ZVswXSA9PT0gSU5JVElBTF9XQVRDSEVSX1ZBTFVFID8gW10gOiBvbGRWYWx1ZSwNCiAgICAgICAgICAgIGJvdW5kQ2xlYW51cA0KICAgICAgICAgIF07DQogICAgICAgICAgb2xkVmFsdWUgPSBuZXdWYWx1ZTsNCiAgICAgICAgICBjYWxsID8gY2FsbChjYiwgMywgYXJncykgOiAoDQogICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yDQogICAgICAgICAgICBjYiguLi5hcmdzKQ0KICAgICAgICAgICk7DQogICAgICAgIH0gZmluYWxseSB7DQogICAgICAgICAgYWN0aXZlV2F0Y2hlciA9IGN1cnJlbnRXYXRjaGVyOw0KICAgICAgICB9DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIGVmZmVjdC5ydW4oKTsNCiAgICB9DQogIH07DQogIGlmIChhdWdtZW50Sm9iKSB7DQogICAgYXVnbWVudEpvYihqb2IpOw0KICB9DQogIGVmZmVjdCA9IG5ldyBSZWFjdGl2ZUVmZmVjdChnZXR0ZXIpOw0KICBlZmZlY3Quc2NoZWR1bGVyID0gc2NoZWR1bGVyID8gKCkgPT4gc2NoZWR1bGVyKGpvYiwgZmFsc2UpIDogam9iOw0KICBib3VuZENsZWFudXAgPSAoZm4pID0+IG9uV2F0Y2hlckNsZWFudXAoZm4sIGZhbHNlLCBlZmZlY3QpOw0KICBjbGVhbnVwID0gZWZmZWN0Lm9uU3RvcCA9ICgpID0+IHsNCiAgICBjb25zdCBjbGVhbnVwcyA9IGNsZWFudXBNYXAuZ2V0KGVmZmVjdCk7DQogICAgaWYgKGNsZWFudXBzKSB7DQogICAgICBpZiAoY2FsbCkgew0KICAgICAgICBjYWxsKGNsZWFudXBzLCA0KTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGZvciAoY29uc3QgY2xlYW51cDIgb2YgY2xlYW51cHMpIGNsZWFudXAyKCk7DQogICAgICB9DQogICAgICBjbGVhbnVwTWFwLmRlbGV0ZShlZmZlY3QpOw0KICAgIH0NCiAgfTsNCiAgew0KICAgIGVmZmVjdC5vblRyYWNrID0gb3B0aW9ucy5vblRyYWNrOw0KICAgIGVmZmVjdC5vblRyaWdnZXIgPSBvcHRpb25zLm9uVHJpZ2dlcjsNCiAgfQ0KICBpZiAoY2IpIHsNCiAgICBpZiAoaW1tZWRpYXRlKSB7DQogICAgICBqb2IodHJ1ZSk7DQogICAgfSBlbHNlIHsNCiAgICAgIG9sZFZhbHVlID0gZWZmZWN0LnJ1bigpOw0KICAgIH0NCiAgfSBlbHNlIGlmIChzY2hlZHVsZXIpIHsNCiAgICBzY2hlZHVsZXIoam9iLmJpbmQobnVsbCwgdHJ1ZSksIHRydWUpOw0KICB9IGVsc2Ugew0KICAgIGVmZmVjdC5ydW4oKTsNCiAgfQ0KICB3YXRjaEhhbmRsZS5wYXVzZSA9IGVmZmVjdC5wYXVzZS5iaW5kKGVmZmVjdCk7DQogIHdhdGNoSGFuZGxlLnJlc3VtZSA9IGVmZmVjdC5yZXN1bWUuYmluZChlZmZlY3QpOw0KICB3YXRjaEhhbmRsZS5zdG9wID0gd2F0Y2hIYW5kbGU7DQogIHJldHVybiB3YXRjaEhhbmRsZTsNCn0NCmZ1bmN0aW9uIHRyYXZlcnNlKHZhbHVlLCBkZXB0aCA9IEluZmluaXR5LCBzZWVuKSB7DQogIGlmIChkZXB0aCA8PSAwIHx8ICFpc09iamVjdCh2YWx1ZSkgfHwgdmFsdWVbIl9fdl9za2lwIl0pIHsNCiAgICByZXR1cm4gdmFsdWU7DQogIH0NCiAgc2VlbiA9IHNlZW4gfHwgLyogQF9fUFVSRV9fICovIG5ldyBTZXQoKTsNCiAgaWYgKHNlZW4uaGFzKHZhbHVlKSkgew0KICAgIHJldHVybiB2YWx1ZTsNCiAgfQ0KICBzZWVuLmFkZCh2YWx1ZSk7DQogIGRlcHRoLS07DQogIGlmIChpc1JlZih2YWx1ZSkpIHsNCiAgICB0cmF2ZXJzZSh2YWx1ZS52YWx1ZSwgZGVwdGgsIHNlZW4pOw0KICB9IGVsc2UgaWYgKGlzQXJyYXkodmFsdWUpKSB7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykgew0KICAgICAgdHJhdmVyc2UodmFsdWVbaV0sIGRlcHRoLCBzZWVuKTsNCiAgICB9DQogIH0gZWxzZSBpZiAoaXNTZXQodmFsdWUpIHx8IGlzTWFwKHZhbHVlKSkgew0KICAgIHZhbHVlLmZvckVhY2goKHYpID0+IHsNCiAgICAgIHRyYXZlcnNlKHYsIGRlcHRoLCBzZWVuKTsNCiAgICB9KTsNCiAgfSBlbHNlIGlmIChpc1BsYWluT2JqZWN0KHZhbHVlKSkgew0KICAgIGZvciAoY29uc3Qga2V5IGluIHZhbHVlKSB7DQogICAgICB0cmF2ZXJzZSh2YWx1ZVtrZXldLCBkZXB0aCwgc2Vlbik7DQogICAgfQ0KICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHModmFsdWUpKSB7DQogICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHZhbHVlLCBrZXkpKSB7DQogICAgICAgIHRyYXZlcnNlKHZhbHVlW2tleV0sIGRlcHRoLCBzZWVuKTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgcmV0dXJuIHZhbHVlOw0KfQ0KDQpjb25zdCBzdGFjayA9IFtdOw0KZnVuY3Rpb24gcHVzaFdhcm5pbmdDb250ZXh0KHZub2RlKSB7DQogIHN0YWNrLnB1c2godm5vZGUpOw0KfQ0KZnVuY3Rpb24gcG9wV2FybmluZ0NvbnRleHQoKSB7DQogIHN0YWNrLnBvcCgpOw0KfQ0KbGV0IGlzV2FybmluZyA9IGZhbHNlOw0KZnVuY3Rpb24gd2FybiQxKG1zZywgLi4uYXJncykgew0KICBpZiAoaXNXYXJuaW5nKSByZXR1cm47DQogIGlzV2FybmluZyA9IHRydWU7DQogIHBhdXNlVHJhY2tpbmcoKTsNCiAgY29uc3QgaW5zdGFuY2UgPSBzdGFjay5sZW5ndGggPyBzdGFja1tzdGFjay5sZW5ndGggLSAxXS5jb21wb25lbnQgOiBudWxsOw0KICBjb25zdCBhcHBXYXJuSGFuZGxlciA9IGluc3RhbmNlICYmIGluc3RhbmNlLmFwcENvbnRleHQuY29uZmlnLndhcm5IYW5kbGVyOw0KICBjb25zdCB0cmFjZSA9IGdldENvbXBvbmVudFRyYWNlKCk7DQogIGlmIChhcHBXYXJuSGFuZGxlcikgew0KICAgIGNhbGxXaXRoRXJyb3JIYW5kbGluZygNCiAgICAgIGFwcFdhcm5IYW5kbGVyLA0KICAgICAgaW5zdGFuY2UsDQogICAgICAxMSwNCiAgICAgIFsNCiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4DQogICAgICAgIG1zZyArIGFyZ3MubWFwKChhKSA9PiB7DQogICAgICAgICAgdmFyIF9hLCBfYjsNCiAgICAgICAgICByZXR1cm4gKF9iID0gKF9hID0gYS50b1N0cmluZykgPT0gbnVsbCA/IHZvaWQgMCA6IF9hLmNhbGwoYSkpICE9IG51bGwgPyBfYiA6IEpTT04uc3RyaW5naWZ5KGEpOw0KICAgICAgICB9KS5qb2luKCIiKSwNCiAgICAgICAgaW5zdGFuY2UgJiYgaW5zdGFuY2UucHJveHksDQogICAgICAgIHRyYWNlLm1hcCgNCiAgICAgICAgICAoeyB2bm9kZSB9KSA9PiBgYXQgPCR7Zm9ybWF0Q29tcG9uZW50TmFtZShpbnN0YW5jZSwgdm5vZGUudHlwZSl9PmANCiAgICAgICAgKS5qb2luKCJcbiIpLA0KICAgICAgICB0cmFjZQ0KICAgICAgXQ0KICAgICk7DQogIH0gZWxzZSB7DQogICAgY29uc3Qgd2FybkFyZ3MgPSBbYFtWdWUgd2Fybl06ICR7bXNnfWAsIC4uLmFyZ3NdOw0KICAgIGlmICh0cmFjZS5sZW5ndGggJiYgLy8gYXZvaWQgc3BhbW1pbmcgY29uc29sZSBkdXJpbmcgdGVzdHMNCiAgICB0cnVlKSB7DQogICAgICB3YXJuQXJncy5wdXNoKGANCmAsIC4uLmZvcm1hdFRyYWNlKHRyYWNlKSk7DQogICAgfQ0KICAgIGNvbnNvbGUud2FybiguLi53YXJuQXJncyk7DQogIH0NCiAgcmVzZXRUcmFja2luZygpOw0KICBpc1dhcm5pbmcgPSBmYWxzZTsNCn0NCmZ1bmN0aW9uIGdldENvbXBvbmVudFRyYWNlKCkgew0KICBsZXQgY3VycmVudFZOb2RlID0gc3RhY2tbc3RhY2subGVuZ3RoIC0gMV07DQogIGlmICghY3VycmVudFZOb2RlKSB7DQogICAgcmV0dXJuIFtdOw0KICB9DQogIGNvbnN0IG5vcm1hbGl6ZWRTdGFjayA9IFtdOw0KICB3aGlsZSAoY3VycmVudFZOb2RlKSB7DQogICAgY29uc3QgbGFzdCA9IG5vcm1hbGl6ZWRTdGFja1swXTsNCiAgICBpZiAobGFzdCAmJiBsYXN0LnZub2RlID09PSBjdXJyZW50Vk5vZGUpIHsNCiAgICAgIGxhc3QucmVjdXJzZUNvdW50Kys7DQogICAgfSBlbHNlIHsNCiAgICAgIG5vcm1hbGl6ZWRTdGFjay5wdXNoKHsNCiAgICAgICAgdm5vZGU6IGN1cnJlbnRWTm9kZSwNCiAgICAgICAgcmVjdXJzZUNvdW50OiAwDQogICAgICB9KTsNCiAgICB9DQogICAgY29uc3QgcGFyZW50SW5zdGFuY2UgPSBjdXJyZW50Vk5vZGUuY29tcG9uZW50ICYmIGN1cnJlbnRWTm9kZS5jb21wb25lbnQucGFyZW50Ow0KICAgIGN1cnJlbnRWTm9kZSA9IHBhcmVudEluc3RhbmNlICYmIHBhcmVudEluc3RhbmNlLnZub2RlOw0KICB9DQogIHJldHVybiBub3JtYWxpemVkU3RhY2s7DQp9DQpmdW5jdGlvbiBmb3JtYXRUcmFjZSh0cmFjZSkgew0KICBjb25zdCBsb2dzID0gW107DQogIHRyYWNlLmZvckVhY2goKGVudHJ5LCBpKSA9PiB7DQogICAgbG9ncy5wdXNoKC4uLmkgPT09IDAgPyBbXSA6IFtgDQpgXSwgLi4uZm9ybWF0VHJhY2VFbnRyeShlbnRyeSkpOw0KICB9KTsNCiAgcmV0dXJuIGxvZ3M7DQp9DQpmdW5jdGlvbiBmb3JtYXRUcmFjZUVudHJ5KHsgdm5vZGUsIHJlY3Vyc2VDb3VudCB9KSB7DQogIGNvbnN0IHBvc3RmaXggPSByZWN1cnNlQ291bnQgPiAwID8gYC4uLiAoJHtyZWN1cnNlQ291bnR9IHJlY3Vyc2l2ZSBjYWxscylgIDogYGA7DQogIGNvbnN0IGlzUm9vdCA9IHZub2RlLmNvbXBvbmVudCA/IHZub2RlLmNvbXBvbmVudC5wYXJlbnQgPT0gbnVsbCA6IGZhbHNlOw0KICBjb25zdCBvcGVuID0gYCBhdCA8JHtmb3JtYXRDb21wb25lbnROYW1lKA0KICAgIHZub2RlLmNvbXBvbmVudCwNCiAgICB2bm9kZS50eXBlLA0KICAgIGlzUm9vdA0KICApfWA7DQogIGNvbnN0IGNsb3NlID0gYD5gICsgcG9zdGZpeDsNCiAgcmV0dXJuIHZub2RlLnByb3BzID8gW29wZW4sIC4uLmZvcm1hdFByb3BzKHZub2RlLnByb3BzKSwgY2xvc2VdIDogW29wZW4gKyBjbG9zZV07DQp9DQpmdW5jdGlvbiBmb3JtYXRQcm9wcyhwcm9wcykgew0KICBjb25zdCByZXMgPSBbXTsNCiAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHByb3BzKTsNCiAga2V5cy5zbGljZSgwLCAzKS5mb3JFYWNoKChrZXkpID0+IHsNCiAgICByZXMucHVzaCguLi5mb3JtYXRQcm9wKGtleSwgcHJvcHNba2V5XSkpOw0KICB9KTsNCiAgaWYgKGtleXMubGVuZ3RoID4gMykgew0KICAgIHJlcy5wdXNoKGAgLi4uYCk7DQogIH0NCiAgcmV0dXJuIHJlczsNCn0NCmZ1bmN0aW9uIGZvcm1hdFByb3Aoa2V5LCB2YWx1ZSwgcmF3KSB7DQogIGlmIChpc1N0cmluZyh2YWx1ZSkpIHsNCiAgICB2YWx1ZSA9IEpTT04uc3RyaW5naWZ5KHZhbHVlKTsNCiAgICByZXR1cm4gcmF3ID8gdmFsdWUgOiBbYCR7a2V5fT0ke3ZhbHVlfWBdOw0KICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gIm51bWJlciIgfHwgdHlwZW9mIHZhbHVlID09PSAiYm9vbGVhbiIgfHwgdmFsdWUgPT0gbnVsbCkgew0KICAgIHJldHVybiByYXcgPyB2YWx1ZSA6IFtgJHtrZXl9PSR7dmFsdWV9YF07DQogIH0gZWxzZSBpZiAoaXNSZWYodmFsdWUpKSB7DQogICAgdmFsdWUgPSBmb3JtYXRQcm9wKGtleSwgdG9SYXcodmFsdWUudmFsdWUpLCB0cnVlKTsNCiAgICByZXR1cm4gcmF3ID8gdmFsdWUgOiBbYCR7a2V5fT1SZWY8YCwgdmFsdWUsIGA+YF07DQogIH0gZWxzZSBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHsNCiAgICByZXR1cm4gW2Ake2tleX09Zm4ke3ZhbHVlLm5hbWUgPyBgPCR7dmFsdWUubmFtZX0+YCA6IGBgfWBdOw0KICB9IGVsc2Ugew0KICAgIHZhbHVlID0gdG9SYXcodmFsdWUpOw0KICAgIHJldHVybiByYXcgPyB2YWx1ZSA6IFtgJHtrZXl9PWAsIHZhbHVlXTsNCiAgfQ0KfQ0KZnVuY3Rpb24gYXNzZXJ0TnVtYmVyKHZhbCwgdHlwZSkgew0KICBpZiAodmFsID09PSB2b2lkIDApIHsNCiAgICByZXR1cm47DQogIH0gZWxzZSBpZiAodHlwZW9mIHZhbCAhPT0gIm51bWJlciIpIHsNCiAgICB3YXJuJDEoYCR7dHlwZX0gaXMgbm90IGEgdmFsaWQgbnVtYmVyIC0gZ290ICR7SlNPTi5zdHJpbmdpZnkodmFsKX0uYCk7DQogIH0gZWxzZSBpZiAoaXNOYU4odmFsKSkgew0KICAgIHdhcm4kMShgJHt0eXBlfSBpcyBOYU4gLSB0aGUgZHVyYXRpb24gZXhwcmVzc2lvbiBtaWdodCBiZSBpbmNvcnJlY3QuYCk7DQogIH0NCn0NCg0KY29uc3QgRXJyb3JDb2RlcyA9IHsNCiAgIlNFVFVQX0ZVTkNUSU9OIjogMCwNCiAgIjAiOiAiU0VUVVBfRlVOQ1RJT04iLA0KICAiUkVOREVSX0ZVTkNUSU9OIjogMSwNCiAgIjEiOiAiUkVOREVSX0ZVTkNUSU9OIiwNCiAgIk5BVElWRV9FVkVOVF9IQU5ETEVSIjogNSwNCiAgIjUiOiAiTkFUSVZFX0VWRU5UX0hBTkRMRVIiLA0KICAiQ09NUE9ORU5UX0VWRU5UX0hBTkRMRVIiOiA2LA0KICAiNiI6ICJDT01QT05FTlRfRVZFTlRfSEFORExFUiIsDQogICJWTk9ERV9IT09LIjogNywNCiAgIjciOiAiVk5PREVfSE9PSyIsDQogICJESVJFQ1RJVkVfSE9PSyI6IDgsDQogICI4IjogIkRJUkVDVElWRV9IT09LIiwNCiAgIlRSQU5TSVRJT05fSE9PSyI6IDksDQogICI5IjogIlRSQU5TSVRJT05fSE9PSyIsDQogICJBUFBfRVJST1JfSEFORExFUiI6IDEwLA0KICAiMTAiOiAiQVBQX0VSUk9SX0hBTkRMRVIiLA0KICAiQVBQX1dBUk5fSEFORExFUiI6IDExLA0KICAiMTEiOiAiQVBQX1dBUk5fSEFORExFUiIsDQogICJGVU5DVElPTl9SRUYiOiAxMiwNCiAgIjEyIjogIkZVTkNUSU9OX1JFRiIsDQogICJBU1lOQ19DT01QT05FTlRfTE9BREVSIjogMTMsDQogICIxMyI6ICJBU1lOQ19DT01QT05FTlRfTE9BREVSIiwNCiAgIlNDSEVEVUxFUiI6IDE0LA0KICAiMTQiOiAiU0NIRURVTEVSIiwNCiAgIkNPTVBPTkVOVF9VUERBVEUiOiAxNSwNCiAgIjE1IjogIkNPTVBPTkVOVF9VUERBVEUiLA0KICAiQVBQX1VOTU9VTlRfQ0xFQU5VUCI6IDE2LA0KICAiMTYiOiAiQVBQX1VOTU9VTlRfQ0xFQU5VUCINCn07DQpjb25zdCBFcnJvclR5cGVTdHJpbmdzJDEgPSB7DQogIFsic3AiXTogInNlcnZlclByZWZldGNoIGhvb2siLA0KICBbImJjIl06ICJiZWZvcmVDcmVhdGUgaG9vayIsDQogIFsiYyJdOiAiY3JlYXRlZCBob29rIiwNCiAgWyJibSJdOiAiYmVmb3JlTW91bnQgaG9vayIsDQogIFsibSJdOiAibW91bnRlZCBob29rIiwNCiAgWyJidSJdOiAiYmVmb3JlVXBkYXRlIGhvb2siLA0KICBbInUiXTogInVwZGF0ZWQiLA0KICBbImJ1bSJdOiAiYmVmb3JlVW5tb3VudCBob29rIiwNCiAgWyJ1bSJdOiAidW5tb3VudGVkIGhvb2siLA0KICBbImEiXTogImFjdGl2YXRlZCBob29rIiwNCiAgWyJkYSJdOiAiZGVhY3RpdmF0ZWQgaG9vayIsDQogIFsiZWMiXTogImVycm9yQ2FwdHVyZWQgaG9vayIsDQogIFsicnRjIl06ICJyZW5kZXJUcmFja2VkIGhvb2siLA0KICBbInJ0ZyJdOiAicmVuZGVyVHJpZ2dlcmVkIGhvb2siLA0KICBbMF06ICJzZXR1cCBmdW5jdGlvbiIsDQogIFsxXTogInJlbmRlciBmdW5jdGlvbiIsDQogIFsyXTogIndhdGNoZXIgZ2V0dGVyIiwNCiAgWzNdOiAid2F0Y2hlciBjYWxsYmFjayIsDQogIFs0XTogIndhdGNoZXIgY2xlYW51cCBmdW5jdGlvbiIsDQogIFs1XTogIm5hdGl2ZSBldmVudCBoYW5kbGVyIiwNCiAgWzZdOiAiY29tcG9uZW50IGV2ZW50IGhhbmRsZXIiLA0KICBbN106ICJ2bm9kZSBob29rIiwNCiAgWzhdOiAiZGlyZWN0aXZlIGhvb2siLA0KICBbOV06ICJ0cmFuc2l0aW9uIGhvb2siLA0KICBbMTBdOiAiYXBwIGVycm9ySGFuZGxlciIsDQogIFsxMV06ICJhcHAgd2FybkhhbmRsZXIiLA0KICBbMTJdOiAicmVmIGZ1bmN0aW9uIiwNCiAgWzEzXTogImFzeW5jIGNvbXBvbmVudCBsb2FkZXIiLA0KICBbMTRdOiAic2NoZWR1bGVyIGZsdXNoIiwNCiAgWzE1XTogImNvbXBvbmVudCB1cGRhdGUiLA0KICBbMTZdOiAiYXBwIHVubW91bnQgY2xlYW51cCBmdW5jdGlvbiINCn07DQpmdW5jdGlvbiBjYWxsV2l0aEVycm9ySGFuZGxpbmcoZm4sIGluc3RhbmNlLCB0eXBlLCBhcmdzKSB7DQogIHRyeSB7DQogICAgcmV0dXJuIGFyZ3MgPyBmbiguLi5hcmdzKSA6IGZuKCk7DQogIH0gY2F0Y2ggKGVycikgew0KICAgIGhhbmRsZUVycm9yKGVyciwgaW5zdGFuY2UsIHR5cGUpOw0KICB9DQp9DQpmdW5jdGlvbiBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZyhmbiwgaW5zdGFuY2UsIHR5cGUsIGFyZ3MpIHsNCiAgaWYgKGlzRnVuY3Rpb24oZm4pKSB7DQogICAgY29uc3QgcmVzID0gY2FsbFdpdGhFcnJvckhhbmRsaW5nKGZuLCBpbnN0YW5jZSwgdHlwZSwgYXJncyk7DQogICAgaWYgKHJlcyAmJiBpc1Byb21pc2UocmVzKSkgew0KICAgICAgcmVzLmNhdGNoKChlcnIpID0+IHsNCiAgICAgICAgaGFuZGxlRXJyb3IoZXJyLCBpbnN0YW5jZSwgdHlwZSk7DQogICAgICB9KTsNCiAgICB9DQogICAgcmV0dXJuIHJlczsNCiAgfQ0KICBpZiAoaXNBcnJheShmbikpIHsNCiAgICBjb25zdCB2YWx1ZXMgPSBbXTsNCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZuLmxlbmd0aDsgaSsrKSB7DQogICAgICB2YWx1ZXMucHVzaChjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZyhmbltpXSwgaW5zdGFuY2UsIHR5cGUsIGFyZ3MpKTsNCiAgICB9DQogICAgcmV0dXJuIHZhbHVlczsNCiAgfSBlbHNlIHsNCiAgICB3YXJuJDEoDQogICAgICBgSW52YWxpZCB2YWx1ZSB0eXBlIHBhc3NlZCB0byBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZygpOiAke3R5cGVvZiBmbn1gDQogICAgKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gaGFuZGxlRXJyb3IoZXJyLCBpbnN0YW5jZSwgdHlwZSwgdGhyb3dJbkRldiA9IHRydWUpIHsNCiAgY29uc3QgY29udGV4dFZOb2RlID0gaW5zdGFuY2UgPyBpbnN0YW5jZS52bm9kZSA6IG51bGw7DQogIGNvbnN0IHsgZXJyb3JIYW5kbGVyLCB0aHJvd1VuaGFuZGxlZEVycm9ySW5Qcm9kdWN0aW9uIH0gPSBpbnN0YW5jZSAmJiBpbnN0YW5jZS5hcHBDb250ZXh0LmNvbmZpZyB8fCBFTVBUWV9PQko7DQogIGlmIChpbnN0YW5jZSkgew0KICAgIGxldCBjdXIgPSBpbnN0YW5jZS5wYXJlbnQ7DQogICAgY29uc3QgZXhwb3NlZEluc3RhbmNlID0gaW5zdGFuY2UucHJveHk7DQogICAgY29uc3QgZXJyb3JJbmZvID0gRXJyb3JUeXBlU3RyaW5ncyQxW3R5cGVdIDsNCiAgICB3aGlsZSAoY3VyKSB7DQogICAgICBjb25zdCBlcnJvckNhcHR1cmVkSG9va3MgPSBjdXIuZWM7DQogICAgICBpZiAoZXJyb3JDYXB0dXJlZEhvb2tzKSB7DQogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXJyb3JDYXB0dXJlZEhvb2tzLmxlbmd0aDsgaSsrKSB7DQogICAgICAgICAgaWYgKGVycm9yQ2FwdHVyZWRIb29rc1tpXShlcnIsIGV4cG9zZWRJbnN0YW5jZSwgZXJyb3JJbmZvKSA9PT0gZmFsc2UpIHsNCiAgICAgICAgICAgIHJldHVybjsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGN1ciA9IGN1ci5wYXJlbnQ7DQogICAgfQ0KICAgIGlmIChlcnJvckhhbmRsZXIpIHsNCiAgICAgIHBhdXNlVHJhY2tpbmcoKTsNCiAgICAgIGNhbGxXaXRoRXJyb3JIYW5kbGluZyhlcnJvckhhbmRsZXIsIG51bGwsIDEwLCBbDQogICAgICAgIGVyciwNCiAgICAgICAgZXhwb3NlZEluc3RhbmNlLA0KICAgICAgICBlcnJvckluZm8NCiAgICAgIF0pOw0KICAgICAgcmVzZXRUcmFja2luZygpOw0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgfQ0KICBsb2dFcnJvcihlcnIsIHR5cGUsIGNvbnRleHRWTm9kZSwgdGhyb3dJbkRldiwgdGhyb3dVbmhhbmRsZWRFcnJvckluUHJvZHVjdGlvbik7DQp9DQpmdW5jdGlvbiBsb2dFcnJvcihlcnIsIHR5cGUsIGNvbnRleHRWTm9kZSwgdGhyb3dJbkRldiA9IHRydWUsIHRocm93SW5Qcm9kID0gZmFsc2UpIHsNCiAgew0KICAgIGNvbnN0IGluZm8gPSBFcnJvclR5cGVTdHJpbmdzJDFbdHlwZV07DQogICAgaWYgKGNvbnRleHRWTm9kZSkgew0KICAgICAgcHVzaFdhcm5pbmdDb250ZXh0KGNvbnRleHRWTm9kZSk7DQogICAgfQ0KICAgIHdhcm4kMShgVW5oYW5kbGVkIGVycm9yJHtpbmZvID8gYCBkdXJpbmcgZXhlY3V0aW9uIG9mICR7aW5mb31gIDogYGB9YCk7DQogICAgaWYgKGNvbnRleHRWTm9kZSkgew0KICAgICAgcG9wV2FybmluZ0NvbnRleHQoKTsNCiAgICB9DQogICAgaWYgKHRocm93SW5EZXYpIHsNCiAgICAgIHRocm93IGVycjsNCiAgICB9IGVsc2Ugew0KICAgICAgY29uc29sZS5lcnJvcihlcnIpOw0KICAgIH0NCiAgfQ0KfQ0KDQpjb25zdCBxdWV1ZSA9IFtdOw0KbGV0IGZsdXNoSW5kZXggPSAtMTsNCmNvbnN0IHBlbmRpbmdQb3N0Rmx1c2hDYnMgPSBbXTsNCmxldCBhY3RpdmVQb3N0Rmx1c2hDYnMgPSBudWxsOw0KbGV0IHBvc3RGbHVzaEluZGV4ID0gMDsNCmNvbnN0IHJlc29sdmVkUHJvbWlzZSA9IC8qIEBfX1BVUkVfXyAqLyBQcm9taXNlLnJlc29sdmUoKTsNCmxldCBjdXJyZW50Rmx1c2hQcm9taXNlID0gbnVsbDsNCmNvbnN0IFJFQ1VSU0lPTl9MSU1JVCA9IDEwMDsNCmZ1bmN0aW9uIG5leHRUaWNrKGZuKSB7DQogIGNvbnN0IHAgPSBjdXJyZW50Rmx1c2hQcm9taXNlIHx8IHJlc29sdmVkUHJvbWlzZTsNCiAgcmV0dXJuIGZuID8gcC50aGVuKHRoaXMgPyBmbi5iaW5kKHRoaXMpIDogZm4pIDogcDsNCn0NCmZ1bmN0aW9uIGZpbmRJbnNlcnRpb25JbmRleChpZCkgew0KICBsZXQgc3RhcnQgPSBmbHVzaEluZGV4ICsgMTsNCiAgbGV0IGVuZCA9IHF1ZXVlLmxlbmd0aDsNCiAgd2hpbGUgKHN0YXJ0IDwgZW5kKSB7DQogICAgY29uc3QgbWlkZGxlID0gc3RhcnQgKyBlbmQgPj4+IDE7DQogICAgY29uc3QgbWlkZGxlSm9iID0gcXVldWVbbWlkZGxlXTsNCiAgICBjb25zdCBtaWRkbGVKb2JJZCA9IGdldElkKG1pZGRsZUpvYik7DQogICAgaWYgKG1pZGRsZUpvYklkIDwgaWQgfHwgbWlkZGxlSm9iSWQgPT09IGlkICYmIG1pZGRsZUpvYi5mbGFncyAmIDIpIHsNCiAgICAgIHN0YXJ0ID0gbWlkZGxlICsgMTsNCiAgICB9IGVsc2Ugew0KICAgICAgZW5kID0gbWlkZGxlOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gc3RhcnQ7DQp9DQpmdW5jdGlvbiBxdWV1ZUpvYihqb2IpIHsNCiAgaWYgKCEoam9iLmZsYWdzICYgMSkpIHsNCiAgICBjb25zdCBqb2JJZCA9IGdldElkKGpvYik7DQogICAgY29uc3QgbGFzdEpvYiA9IHF1ZXVlW3F1ZXVlLmxlbmd0aCAtIDFdOw0KICAgIGlmICghbGFzdEpvYiB8fCAvLyBmYXN0IHBhdGggd2hlbiB0aGUgam9iIGlkIGlzIGxhcmdlciB0aGFuIHRoZSB0YWlsDQogICAgIShqb2IuZmxhZ3MgJiAyKSAmJiBqb2JJZCA+PSBnZXRJZChsYXN0Sm9iKSkgew0KICAgICAgcXVldWUucHVzaChqb2IpOw0KICAgIH0gZWxzZSB7DQogICAgICBxdWV1ZS5zcGxpY2UoZmluZEluc2VydGlvbkluZGV4KGpvYklkKSwgMCwgam9iKTsNCiAgICB9DQogICAgam9iLmZsYWdzIHw9IDE7DQogICAgcXVldWVGbHVzaCgpOw0KICB9DQp9DQpmdW5jdGlvbiBxdWV1ZUZsdXNoKCkgew0KICBpZiAoIWN1cnJlbnRGbHVzaFByb21pc2UpIHsNCiAgICBjdXJyZW50Rmx1c2hQcm9taXNlID0gcmVzb2x2ZWRQcm9taXNlLnRoZW4oZmx1c2hKb2JzKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gcXVldWVQb3N0Rmx1c2hDYihjYikgew0KICBpZiAoIWlzQXJyYXkoY2IpKSB7DQogICAgaWYgKGFjdGl2ZVBvc3RGbHVzaENicyAmJiBjYi5pZCA9PT0gLTEpIHsNCiAgICAgIGFjdGl2ZVBvc3RGbHVzaENicy5zcGxpY2UocG9zdEZsdXNoSW5kZXggKyAxLCAwLCBjYik7DQogICAgfSBlbHNlIGlmICghKGNiLmZsYWdzICYgMSkpIHsNCiAgICAgIHBlbmRpbmdQb3N0Rmx1c2hDYnMucHVzaChjYik7DQogICAgICBjYi5mbGFncyB8PSAxOw0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICBwZW5kaW5nUG9zdEZsdXNoQ2JzLnB1c2goLi4uY2IpOw0KICB9DQogIHF1ZXVlRmx1c2goKTsNCn0NCmZ1bmN0aW9uIGZsdXNoUHJlRmx1c2hDYnMoaW5zdGFuY2UsIHNlZW4sIGkgPSBmbHVzaEluZGV4ICsgMSkgew0KICB7DQogICAgc2VlbiA9IHNlZW4gfHwgLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTsNCiAgfQ0KICBmb3IgKDsgaSA8IHF1ZXVlLmxlbmd0aDsgaSsrKSB7DQogICAgY29uc3QgY2IgPSBxdWV1ZVtpXTsNCiAgICBpZiAoY2IgJiYgY2IuZmxhZ3MgJiAyKSB7DQogICAgICBpZiAoaW5zdGFuY2UgJiYgY2IuaWQgIT09IGluc3RhbmNlLnVpZCkgew0KICAgICAgICBjb250aW51ZTsNCiAgICAgIH0NCiAgICAgIGlmIChjaGVja1JlY3Vyc2l2ZVVwZGF0ZXMoc2VlbiwgY2IpKSB7DQogICAgICAgIGNvbnRpbnVlOw0KICAgICAgfQ0KICAgICAgcXVldWUuc3BsaWNlKGksIDEpOw0KICAgICAgaS0tOw0KICAgICAgaWYgKGNiLmZsYWdzICYgNCkgew0KICAgICAgICBjYi5mbGFncyAmPSAtMjsNCiAgICAgIH0NCiAgICAgIGNiKCk7DQogICAgICBpZiAoIShjYi5mbGFncyAmIDQpKSB7DQogICAgICAgIGNiLmZsYWdzICY9IC0yOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KfQ0KZnVuY3Rpb24gZmx1c2hQb3N0Rmx1c2hDYnMoc2Vlbikgew0KICBpZiAocGVuZGluZ1Bvc3RGbHVzaENicy5sZW5ndGgpIHsNCiAgICBjb25zdCBkZWR1cGVkID0gWy4uLm5ldyBTZXQocGVuZGluZ1Bvc3RGbHVzaENicyldLnNvcnQoDQogICAgICAoYSwgYikgPT4gZ2V0SWQoYSkgLSBnZXRJZChiKQ0KICAgICk7DQogICAgcGVuZGluZ1Bvc3RGbHVzaENicy5sZW5ndGggPSAwOw0KICAgIGlmIChhY3RpdmVQb3N0Rmx1c2hDYnMpIHsNCiAgICAgIGFjdGl2ZVBvc3RGbHVzaENicy5wdXNoKC4uLmRlZHVwZWQpOw0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBhY3RpdmVQb3N0Rmx1c2hDYnMgPSBkZWR1cGVkOw0KICAgIHsNCiAgICAgIHNlZW4gPSBzZWVuIHx8IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7DQogICAgfQ0KICAgIGZvciAocG9zdEZsdXNoSW5kZXggPSAwOyBwb3N0Rmx1c2hJbmRleCA8IGFjdGl2ZVBvc3RGbHVzaENicy5sZW5ndGg7IHBvc3RGbHVzaEluZGV4KyspIHsNCiAgICAgIGNvbnN0IGNiID0gYWN0aXZlUG9zdEZsdXNoQ2JzW3Bvc3RGbHVzaEluZGV4XTsNCiAgICAgIGlmIChjaGVja1JlY3Vyc2l2ZVVwZGF0ZXMoc2VlbiwgY2IpKSB7DQogICAgICAgIGNvbnRpbnVlOw0KICAgICAgfQ0KICAgICAgaWYgKGNiLmZsYWdzICYgNCkgew0KICAgICAgICBjYi5mbGFncyAmPSAtMjsNCiAgICAgIH0NCiAgICAgIGlmICghKGNiLmZsYWdzICYgOCkpIGNiKCk7DQogICAgICBjYi5mbGFncyAmPSAtMjsNCiAgICB9DQogICAgYWN0aXZlUG9zdEZsdXNoQ2JzID0gbnVsbDsNCiAgICBwb3N0Rmx1c2hJbmRleCA9IDA7DQogIH0NCn0NCmNvbnN0IGdldElkID0gKGpvYikgPT4gam9iLmlkID09IG51bGwgPyBqb2IuZmxhZ3MgJiAyID8gLTEgOiBJbmZpbml0eSA6IGpvYi5pZDsNCmZ1bmN0aW9uIGZsdXNoSm9icyhzZWVuKSB7DQogIHsNCiAgICBzZWVuID0gc2VlbiB8fCAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOw0KICB9DQogIGNvbnN0IGNoZWNrID0gKGpvYikgPT4gY2hlY2tSZWN1cnNpdmVVcGRhdGVzKHNlZW4sIGpvYikgOw0KICB0cnkgew0KICAgIGZvciAoZmx1c2hJbmRleCA9IDA7IGZsdXNoSW5kZXggPCBxdWV1ZS5sZW5ndGg7IGZsdXNoSW5kZXgrKykgew0KICAgICAgY29uc3Qgam9iID0gcXVldWVbZmx1c2hJbmRleF07DQogICAgICBpZiAoam9iICYmICEoam9iLmZsYWdzICYgOCkpIHsNCiAgICAgICAgaWYgKGNoZWNrKGpvYikpIHsNCiAgICAgICAgICBjb250aW51ZTsNCiAgICAgICAgfQ0KICAgICAgICBpZiAoam9iLmZsYWdzICYgNCkgew0KICAgICAgICAgIGpvYi5mbGFncyAmPSB+MTsNCiAgICAgICAgfQ0KICAgICAgICBjYWxsV2l0aEVycm9ySGFuZGxpbmcoDQogICAgICAgICAgam9iLA0KICAgICAgICAgIGpvYi5pLA0KICAgICAgICAgIGpvYi5pID8gMTUgOiAxNA0KICAgICAgICApOw0KICAgICAgICBpZiAoIShqb2IuZmxhZ3MgJiA0KSkgew0KICAgICAgICAgIGpvYi5mbGFncyAmPSB+MTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgfSBmaW5hbGx5IHsNCiAgICBmb3IgKDsgZmx1c2hJbmRleCA8IHF1ZXVlLmxlbmd0aDsgZmx1c2hJbmRleCsrKSB7DQogICAgICBjb25zdCBqb2IgPSBxdWV1ZVtmbHVzaEluZGV4XTsNCiAgICAgIGlmIChqb2IpIHsNCiAgICAgICAgam9iLmZsYWdzICY9IC0yOw0KICAgICAgfQ0KICAgIH0NCiAgICBmbHVzaEluZGV4ID0gLTE7DQogICAgcXVldWUubGVuZ3RoID0gMDsNCiAgICBmbHVzaFBvc3RGbHVzaENicyhzZWVuKTsNCiAgICBjdXJyZW50Rmx1c2hQcm9taXNlID0gbnVsbDsNCiAgICBpZiAocXVldWUubGVuZ3RoIHx8IHBlbmRpbmdQb3N0Rmx1c2hDYnMubGVuZ3RoKSB7DQogICAgICBmbHVzaEpvYnMoc2Vlbik7DQogICAgfQ0KICB9DQp9DQpmdW5jdGlvbiBjaGVja1JlY3Vyc2l2ZVVwZGF0ZXMoc2VlbiwgZm4pIHsNCiAgY29uc3QgY291bnQgPSBzZWVuLmdldChmbikgfHwgMDsNCiAgaWYgKGNvdW50ID4gUkVDVVJTSU9OX0xJTUlUKSB7DQogICAgY29uc3QgaW5zdGFuY2UgPSBmbi5pOw0KICAgIGNvbnN0IGNvbXBvbmVudE5hbWUgPSBpbnN0YW5jZSAmJiBnZXRDb21wb25lbnROYW1lKGluc3RhbmNlLnR5cGUpOw0KICAgIGhhbmRsZUVycm9yKA0KICAgICAgYE1heGltdW0gcmVjdXJzaXZlIHVwZGF0ZXMgZXhjZWVkZWQke2NvbXBvbmVudE5hbWUgPyBgIGluIGNvbXBvbmVudCA8JHtjb21wb25lbnROYW1lfT5gIDogYGB9LiBUaGlzIG1lYW5zIHlvdSBoYXZlIGEgcmVhY3RpdmUgZWZmZWN0IHRoYXQgaXMgbXV0YXRpbmcgaXRzIG93biBkZXBlbmRlbmNpZXMgYW5kIHRodXMgcmVjdXJzaXZlbHkgdHJpZ2dlcmluZyBpdHNlbGYuIFBvc3NpYmxlIHNvdXJjZXMgaW5jbHVkZSBjb21wb25lbnQgdGVtcGxhdGUsIHJlbmRlciBmdW5jdGlvbiwgdXBkYXRlZCBob29rIG9yIHdhdGNoZXIgc291cmNlIGZ1bmN0aW9uLmAsDQogICAgICBudWxsLA0KICAgICAgMTANCiAgICApOw0KICAgIHJldHVybiB0cnVlOw0KICB9DQogIHNlZW4uc2V0KGZuLCBjb3VudCArIDEpOw0KICByZXR1cm4gZmFsc2U7DQp9DQoNCmxldCBpc0htclVwZGF0aW5nID0gZmFsc2U7DQpjb25zdCBobXJEaXJ0eUNvbXBvbmVudHMgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOw0Kew0KICBnZXRHbG9iYWxUaGlzKCkuX19WVUVfSE1SX1JVTlRJTUVfXyA9IHsNCiAgICBjcmVhdGVSZWNvcmQ6IHRyeVdyYXAoY3JlYXRlUmVjb3JkKSwNCiAgICByZXJlbmRlcjogdHJ5V3JhcChyZXJlbmRlciksDQogICAgcmVsb2FkOiB0cnlXcmFwKHJlbG9hZCkNCiAgfTsNCn0NCmNvbnN0IG1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7DQpmdW5jdGlvbiByZWdpc3RlckhNUihpbnN0YW5jZSkgew0KICBjb25zdCBpZCA9IGluc3RhbmNlLnR5cGUuX19obXJJZDsNCiAgbGV0IHJlY29yZCA9IG1hcC5nZXQoaWQpOw0KICBpZiAoIXJlY29yZCkgew0KICAgIGNyZWF0ZVJlY29yZChpZCwgaW5zdGFuY2UudHlwZSk7DQogICAgcmVjb3JkID0gbWFwLmdldChpZCk7DQogIH0NCiAgcmVjb3JkLmluc3RhbmNlcy5hZGQoaW5zdGFuY2UpOw0KfQ0KZnVuY3Rpb24gdW5yZWdpc3RlckhNUihpbnN0YW5jZSkgew0KICBtYXAuZ2V0KGluc3RhbmNlLnR5cGUuX19obXJJZCkuaW5zdGFuY2VzLmRlbGV0ZShpbnN0YW5jZSk7DQp9DQpmdW5jdGlvbiBjcmVhdGVSZWNvcmQoaWQsIGluaXRpYWxEZWYpIHsNCiAgaWYgKG1hcC5oYXMoaWQpKSB7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9DQogIG1hcC5zZXQoaWQsIHsNCiAgICBpbml0aWFsRGVmOiBub3JtYWxpemVDbGFzc0NvbXBvbmVudChpbml0aWFsRGVmKSwNCiAgICBpbnN0YW5jZXM6IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KCkNCiAgfSk7DQogIHJldHVybiB0cnVlOw0KfQ0KZnVuY3Rpb24gbm9ybWFsaXplQ2xhc3NDb21wb25lbnQoY29tcG9uZW50KSB7DQogIHJldHVybiBpc0NsYXNzQ29tcG9uZW50KGNvbXBvbmVudCkgPyBjb21wb25lbnQuX192Y2NPcHRzIDogY29tcG9uZW50Ow0KfQ0KZnVuY3Rpb24gcmVyZW5kZXIoaWQsIG5ld1JlbmRlcikgew0KICBjb25zdCByZWNvcmQgPSBtYXAuZ2V0KGlkKTsNCiAgaWYgKCFyZWNvcmQpIHsNCiAgICByZXR1cm47DQogIH0NCiAgcmVjb3JkLmluaXRpYWxEZWYucmVuZGVyID0gbmV3UmVuZGVyOw0KICBbLi4ucmVjb3JkLmluc3RhbmNlc10uZm9yRWFjaCgoaW5zdGFuY2UpID0+IHsNCiAgICBpZiAobmV3UmVuZGVyKSB7DQogICAgICBpbnN0YW5jZS5yZW5kZXIgPSBuZXdSZW5kZXI7DQogICAgICBub3JtYWxpemVDbGFzc0NvbXBvbmVudChpbnN0YW5jZS50eXBlKS5yZW5kZXIgPSBuZXdSZW5kZXI7DQogICAgfQ0KICAgIGluc3RhbmNlLnJlbmRlckNhY2hlID0gW107DQogICAgaXNIbXJVcGRhdGluZyA9IHRydWU7DQogICAgaW5zdGFuY2UudXBkYXRlKCk7DQogICAgaXNIbXJVcGRhdGluZyA9IGZhbHNlOw0KICB9KTsNCn0NCmZ1bmN0aW9uIHJlbG9hZChpZCwgbmV3Q29tcCkgew0KICBjb25zdCByZWNvcmQgPSBtYXAuZ2V0KGlkKTsNCiAgaWYgKCFyZWNvcmQpIHJldHVybjsNCiAgbmV3Q29tcCA9IG5vcm1hbGl6ZUNsYXNzQ29tcG9uZW50KG5ld0NvbXApOw0KICB1cGRhdGVDb21wb25lbnREZWYocmVjb3JkLmluaXRpYWxEZWYsIG5ld0NvbXApOw0KICBjb25zdCBpbnN0YW5jZXMgPSBbLi4ucmVjb3JkLmluc3RhbmNlc107DQogIGZvciAobGV0IGkgPSAwOyBpIDwgaW5zdGFuY2VzLmxlbmd0aDsgaSsrKSB7DQogICAgY29uc3QgaW5zdGFuY2UgPSBpbnN0YW5jZXNbaV07DQogICAgY29uc3Qgb2xkQ29tcCA9IG5vcm1hbGl6ZUNsYXNzQ29tcG9uZW50KGluc3RhbmNlLnR5cGUpOw0KICAgIGxldCBkaXJ0eUluc3RhbmNlcyA9IGhtckRpcnR5Q29tcG9uZW50cy5nZXQob2xkQ29tcCk7DQogICAgaWYgKCFkaXJ0eUluc3RhbmNlcykgew0KICAgICAgaWYgKG9sZENvbXAgIT09IHJlY29yZC5pbml0aWFsRGVmKSB7DQogICAgICAgIHVwZGF0ZUNvbXBvbmVudERlZihvbGRDb21wLCBuZXdDb21wKTsNCiAgICAgIH0NCiAgICAgIGhtckRpcnR5Q29tcG9uZW50cy5zZXQob2xkQ29tcCwgZGlydHlJbnN0YW5jZXMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpKTsNCiAgICB9DQogICAgZGlydHlJbnN0YW5jZXMuYWRkKGluc3RhbmNlKTsNCiAgICBpbnN0YW5jZS5hcHBDb250ZXh0LnByb3BzQ2FjaGUuZGVsZXRlKGluc3RhbmNlLnR5cGUpOw0KICAgIGluc3RhbmNlLmFwcENvbnRleHQuZW1pdHNDYWNoZS5kZWxldGUoaW5zdGFuY2UudHlwZSk7DQogICAgaW5zdGFuY2UuYXBwQ29udGV4dC5vcHRpb25zQ2FjaGUuZGVsZXRlKGluc3RhbmNlLnR5cGUpOw0KICAgIGlmIChpbnN0YW5jZS5jZVJlbG9hZCkgew0KICAgICAgZGlydHlJbnN0YW5jZXMuYWRkKGluc3RhbmNlKTsNCiAgICAgIGluc3RhbmNlLmNlUmVsb2FkKG5ld0NvbXAuc3R5bGVzKTsNCiAgICAgIGRpcnR5SW5zdGFuY2VzLmRlbGV0ZShpbnN0YW5jZSk7DQogICAgfSBlbHNlIGlmIChpbnN0YW5jZS5wYXJlbnQpIHsNCiAgICAgIHF1ZXVlSm9iKCgpID0+IHsNCiAgICAgICAgaXNIbXJVcGRhdGluZyA9IHRydWU7DQogICAgICAgIGluc3RhbmNlLnBhcmVudC51cGRhdGUoKTsNCiAgICAgICAgaXNIbXJVcGRhdGluZyA9IGZhbHNlOw0KICAgICAgICBkaXJ0eUluc3RhbmNlcy5kZWxldGUoaW5zdGFuY2UpOw0KICAgICAgfSk7DQogICAgfSBlbHNlIGlmIChpbnN0YW5jZS5hcHBDb250ZXh0LnJlbG9hZCkgew0KICAgICAgaW5zdGFuY2UuYXBwQ29udGV4dC5yZWxvYWQoKTsNCiAgICB9IGVsc2UgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICJ1bmRlZmluZWQiKSB7DQogICAgICB3aW5kb3cubG9jYXRpb24ucmVsb2FkKCk7DQogICAgfSBlbHNlIHsNCiAgICAgIGNvbnNvbGUud2FybigNCiAgICAgICAgIltITVJdIFJvb3Qgb3IgbWFudWFsbHkgbW91bnRlZCBpbnN0YW5jZSBtb2RpZmllZC4gRnVsbCByZWxvYWQgcmVxdWlyZWQuIg0KICAgICAgKTsNCiAgICB9DQogICAgaWYgKGluc3RhbmNlLnJvb3QuY2UgJiYgaW5zdGFuY2UgIT09IGluc3RhbmNlLnJvb3QpIHsNCiAgICAgIGluc3RhbmNlLnJvb3QuY2UuX3JlbW92ZUNoaWxkU3R5bGUob2xkQ29tcCk7DQogICAgfQ0KICB9DQogIHF1ZXVlUG9zdEZsdXNoQ2IoKCkgPT4gew0KICAgIGhtckRpcnR5Q29tcG9uZW50cy5jbGVhcigpOw0KICB9KTsNCn0NCmZ1bmN0aW9uIHVwZGF0ZUNvbXBvbmVudERlZihvbGRDb21wLCBuZXdDb21wKSB7DQogIGV4dGVuZChvbGRDb21wLCBuZXdDb21wKTsNCiAgZm9yIChjb25zdCBrZXkgaW4gb2xkQ29tcCkgew0KICAgIGlmIChrZXkgIT09ICJfX2ZpbGUiICYmICEoa2V5IGluIG5ld0NvbXApKSB7DQogICAgICBkZWxldGUgb2xkQ29tcFtrZXldOw0KICAgIH0NCiAgfQ0KfQ0KZnVuY3Rpb24gdHJ5V3JhcChmbikgew0KICByZXR1cm4gKGlkLCBhcmcpID0+IHsNCiAgICB0cnkgew0KICAgICAgcmV0dXJuIGZuKGlkLCBhcmcpOw0KICAgIH0gY2F0Y2ggKGUpIHsNCiAgICAgIGNvbnNvbGUuZXJyb3IoZSk7DQogICAgICBjb25zb2xlLndhcm4oDQogICAgICAgIGBbSE1SXSBTb21ldGhpbmcgd2VudCB3cm9uZyBkdXJpbmcgVnVlIGNvbXBvbmVudCBob3QtcmVsb2FkLiBGdWxsIHJlbG9hZCByZXF1aXJlZC5gDQogICAgICApOw0KICAgIH0NCiAgfTsNCn0NCg0KbGV0IGRldnRvb2xzJDE7DQpsZXQgYnVmZmVyID0gW107DQpsZXQgZGV2dG9vbHNOb3RJbnN0YWxsZWQgPSBmYWxzZTsNCmZ1bmN0aW9uIGVtaXQkMShldmVudCwgLi4uYXJncykgew0KICBpZiAoZGV2dG9vbHMkMSkgew0KICAgIGRldnRvb2xzJDEuZW1pdChldmVudCwgLi4uYXJncyk7DQogIH0gZWxzZSBpZiAoIWRldnRvb2xzTm90SW5zdGFsbGVkKSB7DQogICAgYnVmZmVyLnB1c2goeyBldmVudCwgYXJncyB9KTsNCiAgfQ0KfQ0KZnVuY3Rpb24gc2V0RGV2dG9vbHNIb29rJDEoaG9vaywgdGFyZ2V0KSB7DQogIHZhciBfYSwgX2I7DQogIGRldnRvb2xzJDEgPSBob29rOw0KICBpZiAoZGV2dG9vbHMkMSkgew0KICAgIGRldnRvb2xzJDEuZW5hYmxlZCA9IHRydWU7DQogICAgYnVmZmVyLmZvckVhY2goKHsgZXZlbnQsIGFyZ3MgfSkgPT4gZGV2dG9vbHMkMS5lbWl0KGV2ZW50LCAuLi5hcmdzKSk7DQogICAgYnVmZmVyID0gW107DQogIH0gZWxzZSBpZiAoDQogICAgLy8gaGFuZGxlIGxhdGUgZGV2dG9vbHMgaW5qZWN0aW9uIC0gb25seSBkbyB0aGlzIGlmIHdlIGFyZSBpbiBhbiBhY3R1YWwNCiAgICAvLyBicm93c2VyIGVudmlyb25tZW50IHRvIGF2b2lkIHRoZSB0aW1lciBoYW5kbGUgc3RhbGxpbmcgdGVzdCBydW5uZXIgZXhpdA0KICAgIC8vICgjNDgxNSkNCiAgICB0eXBlb2Ygd2luZG93ICE9PSAidW5kZWZpbmVkIiAmJiAvLyBzb21lIGVudnMgbW9jayB3aW5kb3cgYnV0IG5vdCBmdWxseQ0KICAgIHdpbmRvdy5IVE1MRWxlbWVudCAmJiAvLyBhbHNvIGV4Y2x1ZGUganNkb20NCiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXgNCiAgICAhKChfYiA9IChfYSA9IHdpbmRvdy5uYXZpZ2F0b3IpID09IG51bGwgPyB2b2lkIDAgOiBfYS51c2VyQWdlbnQpID09IG51bGwgPyB2b2lkIDAgOiBfYi5pbmNsdWRlcygianNkb20iKSkNCiAgKSB7DQogICAgY29uc3QgcmVwbGF5ID0gdGFyZ2V0Ll9fVlVFX0RFVlRPT0xTX0hPT0tfUkVQTEFZX18gPSB0YXJnZXQuX19WVUVfREVWVE9PTFNfSE9PS19SRVBMQVlfXyB8fCBbXTsNCiAgICByZXBsYXkucHVzaCgobmV3SG9vaykgPT4gew0KICAgICAgc2V0RGV2dG9vbHNIb29rJDEobmV3SG9vaywgdGFyZ2V0KTsNCiAgICB9KTsNCiAgICBzZXRUaW1lb3V0KCgpID0+IHsNCiAgICAgIGlmICghZGV2dG9vbHMkMSkgew0KICAgICAgICB0YXJnZXQuX19WVUVfREVWVE9PTFNfSE9PS19SRVBMQVlfXyA9IG51bGw7DQogICAgICAgIGRldnRvb2xzTm90SW5zdGFsbGVkID0gdHJ1ZTsNCiAgICAgICAgYnVmZmVyID0gW107DQogICAgICB9DQogICAgfSwgM2UzKTsNCiAgfSBlbHNlIHsNCiAgICBkZXZ0b29sc05vdEluc3RhbGxlZCA9IHRydWU7DQogICAgYnVmZmVyID0gW107DQogIH0NCn0NCmZ1bmN0aW9uIGRldnRvb2xzSW5pdEFwcChhcHAsIHZlcnNpb24pIHsNCiAgZW1pdCQxKCJhcHA6aW5pdCIgLyogQVBQX0lOSVQgKi8sIGFwcCwgdmVyc2lvbiwgew0KICAgIEZyYWdtZW50LA0KICAgIFRleHQsDQogICAgQ29tbWVudCwNCiAgICBTdGF0aWMNCiAgfSk7DQp9DQpmdW5jdGlvbiBkZXZ0b29sc1VubW91bnRBcHAoYXBwKSB7DQogIGVtaXQkMSgiYXBwOnVubW91bnQiIC8qIEFQUF9VTk1PVU5UICovLCBhcHApOw0KfQ0KY29uc3QgZGV2dG9vbHNDb21wb25lbnRBZGRlZCA9IC8qIEBfX1BVUkVfXyAqLyBjcmVhdGVEZXZ0b29sc0NvbXBvbmVudEhvb2soImNvbXBvbmVudDphZGRlZCIgLyogQ09NUE9ORU5UX0FEREVEICovKTsNCmNvbnN0IGRldnRvb2xzQ29tcG9uZW50VXBkYXRlZCA9IC8qIEBfX1BVUkVfXyAqLyBjcmVhdGVEZXZ0b29sc0NvbXBvbmVudEhvb2soImNvbXBvbmVudDp1cGRhdGVkIiAvKiBDT01QT05FTlRfVVBEQVRFRCAqLyk7DQpjb25zdCBfZGV2dG9vbHNDb21wb25lbnRSZW1vdmVkID0gLyogQF9fUFVSRV9fICovIGNyZWF0ZURldnRvb2xzQ29tcG9uZW50SG9vaygNCiAgImNvbXBvbmVudDpyZW1vdmVkIiAvKiBDT01QT05FTlRfUkVNT1ZFRCAqLw0KKTsNCmNvbnN0IGRldnRvb2xzQ29tcG9uZW50UmVtb3ZlZCA9IChjb21wb25lbnQpID0+IHsNCiAgaWYgKGRldnRvb2xzJDEgJiYgdHlwZW9mIGRldnRvb2xzJDEuY2xlYW51cEJ1ZmZlciA9PT0gImZ1bmN0aW9uIiAmJiAvLyByZW1vdmUgdGhlIGNvbXBvbmVudCBpZiBpdCB3YXNuJ3QgYnVmZmVyZWQNCiAgIWRldnRvb2xzJDEuY2xlYW51cEJ1ZmZlcihjb21wb25lbnQpKSB7DQogICAgX2RldnRvb2xzQ29tcG9uZW50UmVtb3ZlZChjb21wb25lbnQpOw0KICB9DQp9Ow0KLyohICNfX05PX1NJREVfRUZGRUNUU19fICovDQovLyBAX19OT19TSURFX0VGRkVDVFNfXw0KZnVuY3Rpb24gY3JlYXRlRGV2dG9vbHNDb21wb25lbnRIb29rKGhvb2spIHsNCiAgcmV0dXJuIChjb21wb25lbnQpID0+IHsNCiAgICBlbWl0JDEoDQogICAgICBob29rLA0KICAgICAgY29tcG9uZW50LmFwcENvbnRleHQuYXBwLA0KICAgICAgY29tcG9uZW50LnVpZCwNCiAgICAgIGNvbXBvbmVudC5wYXJlbnQgPyBjb21wb25lbnQucGFyZW50LnVpZCA6IHZvaWQgMCwNCiAgICAgIGNvbXBvbmVudA0KICAgICk7DQogIH07DQp9DQpjb25zdCBkZXZ0b29sc1BlcmZTdGFydCA9IC8qIEBfX1BVUkVfXyAqLyBjcmVhdGVEZXZ0b29sc1BlcmZvcm1hbmNlSG9vaygicGVyZjpzdGFydCIgLyogUEVSRk9STUFOQ0VfU1RBUlQgKi8pOw0KY29uc3QgZGV2dG9vbHNQZXJmRW5kID0gLyogQF9fUFVSRV9fICovIGNyZWF0ZURldnRvb2xzUGVyZm9ybWFuY2VIb29rKCJwZXJmOmVuZCIgLyogUEVSRk9STUFOQ0VfRU5EICovKTsNCmZ1bmN0aW9uIGNyZWF0ZURldnRvb2xzUGVyZm9ybWFuY2VIb29rKGhvb2spIHsNCiAgcmV0dXJuIChjb21wb25lbnQsIHR5cGUsIHRpbWUpID0+IHsNCiAgICBlbWl0JDEoaG9vaywgY29tcG9uZW50LmFwcENvbnRleHQuYXBwLCBjb21wb25lbnQudWlkLCBjb21wb25lbnQsIHR5cGUsIHRpbWUpOw0KICB9Ow0KfQ0KZnVuY3Rpb24gZGV2dG9vbHNDb21wb25lbnRFbWl0KGNvbXBvbmVudCwgZXZlbnQsIHBhcmFtcykgew0KICBlbWl0JDEoDQogICAgImNvbXBvbmVudDplbWl0IiAvKiBDT01QT05FTlRfRU1JVCAqLywNCiAgICBjb21wb25lbnQuYXBwQ29udGV4dC5hcHAsDQogICAgY29tcG9uZW50LA0KICAgIGV2ZW50LA0KICAgIHBhcmFtcw0KICApOw0KfQ0KDQpsZXQgY3VycmVudFJlbmRlcmluZ0luc3RhbmNlID0gbnVsbDsNCmxldCBjdXJyZW50U2NvcGVJZCA9IG51bGw7DQpmdW5jdGlvbiBzZXRDdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UoaW5zdGFuY2UpIHsNCiAgY29uc3QgcHJldiA9IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZTsNCiAgY3VycmVudFJlbmRlcmluZ0luc3RhbmNlID0gaW5zdGFuY2U7DQogIGN1cnJlbnRTY29wZUlkID0gaW5zdGFuY2UgJiYgaW5zdGFuY2UudHlwZS5fX3Njb3BlSWQgfHwgbnVsbDsNCiAgcmV0dXJuIHByZXY7DQp9DQpmdW5jdGlvbiBwdXNoU2NvcGVJZChpZCkgew0KICBjdXJyZW50U2NvcGVJZCA9IGlkOw0KfQ0KZnVuY3Rpb24gcG9wU2NvcGVJZCgpIHsNCiAgY3VycmVudFNjb3BlSWQgPSBudWxsOw0KfQ0KY29uc3Qgd2l0aFNjb3BlSWQgPSAoX2lkKSA9PiB3aXRoQ3R4Ow0KZnVuY3Rpb24gd2l0aEN0eChmbiwgY3R4ID0gY3VycmVudFJlbmRlcmluZ0luc3RhbmNlLCBpc05vblNjb3BlZFNsb3QpIHsNCiAgaWYgKCFjdHgpIHJldHVybiBmbjsNCiAgaWYgKGZuLl9uKSB7DQogICAgcmV0dXJuIGZuOw0KICB9DQogIGNvbnN0IHJlbmRlckZuV2l0aENvbnRleHQgPSAoLi4uYXJncykgPT4gew0KICAgIGlmIChyZW5kZXJGbldpdGhDb250ZXh0Ll9kKSB7DQogICAgICBzZXRCbG9ja1RyYWNraW5nKC0xKTsNCiAgICB9DQogICAgY29uc3QgcHJldkluc3RhbmNlID0gc2V0Q3VycmVudFJlbmRlcmluZ0luc3RhbmNlKGN0eCk7DQogICAgbGV0IHJlczsNCiAgICB0cnkgew0KICAgICAgcmVzID0gZm4oLi4uYXJncyk7DQogICAgfSBmaW5hbGx5IHsNCiAgICAgIHNldEN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZShwcmV2SW5zdGFuY2UpOw0KICAgICAgaWYgKHJlbmRlckZuV2l0aENvbnRleHQuX2QpIHsNCiAgICAgICAgc2V0QmxvY2tUcmFja2luZygxKTsNCiAgICAgIH0NCiAgICB9DQogICAgew0KICAgICAgZGV2dG9vbHNDb21wb25lbnRVcGRhdGVkKGN0eCk7DQogICAgfQ0KICAgIHJldHVybiByZXM7DQogIH07DQogIHJlbmRlckZuV2l0aENvbnRleHQuX24gPSB0cnVlOw0KICByZW5kZXJGbldpdGhDb250ZXh0Ll9jID0gdHJ1ZTsNCiAgcmVuZGVyRm5XaXRoQ29udGV4dC5fZCA9IHRydWU7DQogIHJldHVybiByZW5kZXJGbldpdGhDb250ZXh0Ow0KfQ0KDQpmdW5jdGlvbiB2YWxpZGF0ZURpcmVjdGl2ZU5hbWUobmFtZSkgew0KICBpZiAoaXNCdWlsdEluRGlyZWN0aXZlKG5hbWUpKSB7DQogICAgd2FybiQxKCJEbyBub3QgdXNlIGJ1aWx0LWluIGRpcmVjdGl2ZSBpZHMgYXMgY3VzdG9tIGRpcmVjdGl2ZSBpZDogIiArIG5hbWUpOw0KICB9DQp9DQpmdW5jdGlvbiB3aXRoRGlyZWN0aXZlcyh2bm9kZSwgZGlyZWN0aXZlcykgew0KICBpZiAoY3VycmVudFJlbmRlcmluZ0luc3RhbmNlID09PSBudWxsKSB7DQogICAgd2FybiQxKGB3aXRoRGlyZWN0aXZlcyBjYW4gb25seSBiZSB1c2VkIGluc2lkZSByZW5kZXIgZnVuY3Rpb25zLmApOw0KICAgIHJldHVybiB2bm9kZTsNCiAgfQ0KICBjb25zdCBpbnN0YW5jZSA9IGdldENvbXBvbmVudFB1YmxpY0luc3RhbmNlKGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSk7DQogIGNvbnN0IGJpbmRpbmdzID0gdm5vZGUuZGlycyB8fCAodm5vZGUuZGlycyA9IFtdKTsNCiAgZm9yIChsZXQgaSA9IDA7IGkgPCBkaXJlY3RpdmVzLmxlbmd0aDsgaSsrKSB7DQogICAgbGV0IFtkaXIsIHZhbHVlLCBhcmcsIG1vZGlmaWVycyA9IEVNUFRZX09CSl0gPSBkaXJlY3RpdmVzW2ldOw0KICAgIGlmIChkaXIpIHsNCiAgICAgIGlmIChpc0Z1bmN0aW9uKGRpcikpIHsNCiAgICAgICAgZGlyID0gew0KICAgICAgICAgIG1vdW50ZWQ6IGRpciwNCiAgICAgICAgICB1cGRhdGVkOiBkaXINCiAgICAgICAgfTsNCiAgICAgIH0NCiAgICAgIGlmIChkaXIuZGVlcCkgew0KICAgICAgICB0cmF2ZXJzZSh2YWx1ZSk7DQogICAgICB9DQogICAgICBiaW5kaW5ncy5wdXNoKHsNCiAgICAgICAgZGlyLA0KICAgICAgICBpbnN0YW5jZSwNCiAgICAgICAgdmFsdWUsDQogICAgICAgIG9sZFZhbHVlOiB2b2lkIDAsDQogICAgICAgIGFyZywNCiAgICAgICAgbW9kaWZpZXJzDQogICAgICB9KTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIHZub2RlOw0KfQ0KZnVuY3Rpb24gaW52b2tlRGlyZWN0aXZlSG9vayh2bm9kZSwgcHJldlZOb2RlLCBpbnN0YW5jZSwgbmFtZSkgew0KICBjb25zdCBiaW5kaW5ncyA9IHZub2RlLmRpcnM7DQogIGNvbnN0IG9sZEJpbmRpbmdzID0gcHJldlZOb2RlICYmIHByZXZWTm9kZS5kaXJzOw0KICBmb3IgKGxldCBpID0gMDsgaSA8IGJpbmRpbmdzLmxlbmd0aDsgaSsrKSB7DQogICAgY29uc3QgYmluZGluZyA9IGJpbmRpbmdzW2ldOw0KICAgIGlmIChvbGRCaW5kaW5ncykgew0KICAgICAgYmluZGluZy5vbGRWYWx1ZSA9IG9sZEJpbmRpbmdzW2ldLnZhbHVlOw0KICAgIH0NCiAgICBsZXQgaG9vayA9IGJpbmRpbmcuZGlyW25hbWVdOw0KICAgIGlmIChob29rKSB7DQogICAgICBwYXVzZVRyYWNraW5nKCk7DQogICAgICBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZyhob29rLCBpbnN0YW5jZSwgOCwgWw0KICAgICAgICB2bm9kZS5lbCwNCiAgICAgICAgYmluZGluZywNCiAgICAgICAgdm5vZGUsDQogICAgICAgIHByZXZWTm9kZQ0KICAgICAgXSk7DQogICAgICByZXNldFRyYWNraW5nKCk7DQogICAgfQ0KICB9DQp9DQoNCmNvbnN0IFRlbGVwb3J0RW5kS2V5ID0gU3ltYm9sKCJfdnRlIik7DQpjb25zdCBpc1RlbGVwb3J0ID0gKHR5cGUpID0+IHR5cGUuX19pc1RlbGVwb3J0Ow0KY29uc3QgaXNUZWxlcG9ydERpc2FibGVkID0gKHByb3BzKSA9PiBwcm9wcyAmJiAocHJvcHMuZGlzYWJsZWQgfHwgcHJvcHMuZGlzYWJsZWQgPT09ICIiKTsNCmNvbnN0IGlzVGVsZXBvcnREZWZlcnJlZCA9IChwcm9wcykgPT4gcHJvcHMgJiYgKHByb3BzLmRlZmVyIHx8IHByb3BzLmRlZmVyID09PSAiIik7DQpjb25zdCBpc1RhcmdldFNWRyA9ICh0YXJnZXQpID0+IHR5cGVvZiBTVkdFbGVtZW50ICE9PSAidW5kZWZpbmVkIiAmJiB0YXJnZXQgaW5zdGFuY2VvZiBTVkdFbGVtZW50Ow0KY29uc3QgaXNUYXJnZXRNYXRoTUwgPSAodGFyZ2V0KSA9PiB0eXBlb2YgTWF0aE1MRWxlbWVudCA9PT0gImZ1bmN0aW9uIiAmJiB0YXJnZXQgaW5zdGFuY2VvZiBNYXRoTUxFbGVtZW50Ow0KY29uc3QgcmVzb2x2ZVRhcmdldCA9IChwcm9wcywgc2VsZWN0KSA9PiB7DQogIGNvbnN0IHRhcmdldFNlbGVjdG9yID0gcHJvcHMgJiYgcHJvcHMudG87DQogIGlmIChpc1N0cmluZyh0YXJnZXRTZWxlY3RvcikpIHsNCiAgICBpZiAoIXNlbGVjdCkgew0KICAgICAgd2FybiQxKA0KICAgICAgICBgQ3VycmVudCByZW5kZXJlciBkb2VzIG5vdCBzdXBwb3J0IHN0cmluZyB0YXJnZXQgZm9yIFRlbGVwb3J0cy4gKG1pc3NpbmcgcXVlcnlTZWxlY3RvciByZW5kZXJlciBvcHRpb24pYA0KICAgICAgKTsNCiAgICAgIHJldHVybiBudWxsOw0KICAgIH0gZWxzZSB7DQogICAgICBjb25zdCB0YXJnZXQgPSBzZWxlY3QodGFyZ2V0U2VsZWN0b3IpOw0KICAgICAgaWYgKCF0YXJnZXQgJiYgIWlzVGVsZXBvcnREaXNhYmxlZChwcm9wcykpIHsNCiAgICAgICAgd2FybiQxKA0KICAgICAgICAgIGBGYWlsZWQgdG8gbG9jYXRlIFRlbGVwb3J0IHRhcmdldCB3aXRoIHNlbGVjdG9yICIke3RhcmdldFNlbGVjdG9yfSIuIE5vdGUgdGhlIHRhcmdldCBlbGVtZW50IG11c3QgZXhpc3QgYmVmb3JlIHRoZSBjb21wb25lbnQgaXMgbW91bnRlZCAtIGkuZS4gdGhlIHRhcmdldCBjYW5ub3QgYmUgcmVuZGVyZWQgYnkgdGhlIGNvbXBvbmVudCBpdHNlbGYsIGFuZCBpZGVhbGx5IHNob3VsZCBiZSBvdXRzaWRlIG9mIHRoZSBlbnRpcmUgVnVlIGNvbXBvbmVudCB0cmVlLmANCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICAgIHJldHVybiB0YXJnZXQ7DQogICAgfQ0KICB9IGVsc2Ugew0KICAgIGlmICghdGFyZ2V0U2VsZWN0b3IgJiYgIWlzVGVsZXBvcnREaXNhYmxlZChwcm9wcykpIHsNCiAgICAgIHdhcm4kMShgSW52YWxpZCBUZWxlcG9ydCB0YXJnZXQ6ICR7dGFyZ2V0U2VsZWN0b3J9YCk7DQogICAgfQ0KICAgIHJldHVybiB0YXJnZXRTZWxlY3RvcjsNCiAgfQ0KfTsNCmNvbnN0IFRlbGVwb3J0SW1wbCA9IHsNCiAgbmFtZTogIlRlbGVwb3J0IiwNCiAgX19pc1RlbGVwb3J0OiB0cnVlLA0KICBwcm9jZXNzKG4xLCBuMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQsIGludGVybmFscykgew0KICAgIGNvbnN0IHsNCiAgICAgIG1jOiBtb3VudENoaWxkcmVuLA0KICAgICAgcGM6IHBhdGNoQ2hpbGRyZW4sDQogICAgICBwYmM6IHBhdGNoQmxvY2tDaGlsZHJlbiwNCiAgICAgIG86IHsgaW5zZXJ0LCBxdWVyeVNlbGVjdG9yLCBjcmVhdGVUZXh0LCBjcmVhdGVDb21tZW50IH0NCiAgICB9ID0gaW50ZXJuYWxzOw0KICAgIGNvbnN0IGRpc2FibGVkID0gaXNUZWxlcG9ydERpc2FibGVkKG4yLnByb3BzKTsNCiAgICBsZXQgeyBzaGFwZUZsYWcsIGNoaWxkcmVuLCBkeW5hbWljQ2hpbGRyZW4gfSA9IG4yOw0KICAgIGlmIChpc0htclVwZGF0aW5nKSB7DQogICAgICBvcHRpbWl6ZWQgPSBmYWxzZTsNCiAgICAgIGR5bmFtaWNDaGlsZHJlbiA9IG51bGw7DQogICAgfQ0KICAgIGlmIChuMSA9PSBudWxsKSB7DQogICAgICBjb25zdCBwbGFjZWhvbGRlciA9IG4yLmVsID0gY3JlYXRlQ29tbWVudCgidGVsZXBvcnQgc3RhcnQiKSA7DQogICAgICBjb25zdCBtYWluQW5jaG9yID0gbjIuYW5jaG9yID0gY3JlYXRlQ29tbWVudCgidGVsZXBvcnQgZW5kIikgOw0KICAgICAgaW5zZXJ0KHBsYWNlaG9sZGVyLCBjb250YWluZXIsIGFuY2hvcik7DQogICAgICBpbnNlcnQobWFpbkFuY2hvciwgY29udGFpbmVyLCBhbmNob3IpOw0KICAgICAgY29uc3QgbW91bnQgPSAoY29udGFpbmVyMiwgYW5jaG9yMikgPT4gew0KICAgICAgICBpZiAoc2hhcGVGbGFnICYgMTYpIHsNCiAgICAgICAgICBpZiAocGFyZW50Q29tcG9uZW50ICYmIHBhcmVudENvbXBvbmVudC5pc0NFKSB7DQogICAgICAgICAgICBwYXJlbnRDb21wb25lbnQuY2UuX3RlbGVwb3J0VGFyZ2V0ID0gY29udGFpbmVyMjsNCiAgICAgICAgICB9DQogICAgICAgICAgbW91bnRDaGlsZHJlbigNCiAgICAgICAgICAgIGNoaWxkcmVuLA0KICAgICAgICAgICAgY29udGFpbmVyMiwNCiAgICAgICAgICAgIGFuY2hvcjIsDQogICAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH07DQogICAgICBjb25zdCBtb3VudFRvVGFyZ2V0ID0gKCkgPT4gew0KICAgICAgICBjb25zdCB0YXJnZXQgPSBuMi50YXJnZXQgPSByZXNvbHZlVGFyZ2V0KG4yLnByb3BzLCBxdWVyeVNlbGVjdG9yKTsNCiAgICAgICAgY29uc3QgdGFyZ2V0QW5jaG9yID0gcHJlcGFyZUFuY2hvcih0YXJnZXQsIG4yLCBjcmVhdGVUZXh0LCBpbnNlcnQpOw0KICAgICAgICBpZiAodGFyZ2V0KSB7DQogICAgICAgICAgaWYgKG5hbWVzcGFjZSAhPT0gInN2ZyIgJiYgaXNUYXJnZXRTVkcodGFyZ2V0KSkgew0KICAgICAgICAgICAgbmFtZXNwYWNlID0gInN2ZyI7DQogICAgICAgICAgfSBlbHNlIGlmIChuYW1lc3BhY2UgIT09ICJtYXRobWwiICYmIGlzVGFyZ2V0TWF0aE1MKHRhcmdldCkpIHsNCiAgICAgICAgICAgIG5hbWVzcGFjZSA9ICJtYXRobWwiOw0KICAgICAgICAgIH0NCiAgICAgICAgICBpZiAoIWRpc2FibGVkKSB7DQogICAgICAgICAgICBtb3VudCh0YXJnZXQsIHRhcmdldEFuY2hvcik7DQogICAgICAgICAgICB1cGRhdGVDc3NWYXJzKG4yLCBmYWxzZSk7DQogICAgICAgICAgfQ0KICAgICAgICB9IGVsc2UgaWYgKCFkaXNhYmxlZCkgew0KICAgICAgICAgIHdhcm4kMSgNCiAgICAgICAgICAgICJJbnZhbGlkIFRlbGVwb3J0IHRhcmdldCBvbiBtb3VudDoiLA0KICAgICAgICAgICAgdGFyZ2V0LA0KICAgICAgICAgICAgYCgke3R5cGVvZiB0YXJnZXR9KWANCiAgICAgICAgICApOw0KICAgICAgICB9DQogICAgICB9Ow0KICAgICAgaWYgKGRpc2FibGVkKSB7DQogICAgICAgIG1vdW50KGNvbnRhaW5lciwgbWFpbkFuY2hvcik7DQogICAgICAgIHVwZGF0ZUNzc1ZhcnMobjIsIHRydWUpOw0KICAgICAgfQ0KICAgICAgaWYgKGlzVGVsZXBvcnREZWZlcnJlZChuMi5wcm9wcykpIHsNCiAgICAgICAgbjIuZWwuX19pc01vdW50ZWQgPSBmYWxzZTsNCiAgICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KCgpID0+IHsNCiAgICAgICAgICBtb3VudFRvVGFyZ2V0KCk7DQogICAgICAgICAgZGVsZXRlIG4yLmVsLl9faXNNb3VudGVkOw0KICAgICAgICB9LCBwYXJlbnRTdXNwZW5zZSk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBtb3VudFRvVGFyZ2V0KCk7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIGlmIChpc1RlbGVwb3J0RGVmZXJyZWQobjIucHJvcHMpICYmIG4xLmVsLl9faXNNb3VudGVkID09PSBmYWxzZSkgew0KICAgICAgICBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QoKCkgPT4gew0KICAgICAgICAgIFRlbGVwb3J0SW1wbC5wcm9jZXNzKA0KICAgICAgICAgICAgbjEsDQogICAgICAgICAgICBuMiwNCiAgICAgICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgICAgIGFuY2hvciwNCiAgICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgICAgb3B0aW1pemVkLA0KICAgICAgICAgICAgaW50ZXJuYWxzDQogICAgICAgICAgKTsNCiAgICAgICAgfSwgcGFyZW50U3VzcGVuc2UpOw0KICAgICAgICByZXR1cm47DQogICAgICB9DQogICAgICBuMi5lbCA9IG4xLmVsOw0KICAgICAgbjIudGFyZ2V0U3RhcnQgPSBuMS50YXJnZXRTdGFydDsNCiAgICAgIGNvbnN0IG1haW5BbmNob3IgPSBuMi5hbmNob3IgPSBuMS5hbmNob3I7DQogICAgICBjb25zdCB0YXJnZXQgPSBuMi50YXJnZXQgPSBuMS50YXJnZXQ7DQogICAgICBjb25zdCB0YXJnZXRBbmNob3IgPSBuMi50YXJnZXRBbmNob3IgPSBuMS50YXJnZXRBbmNob3I7DQogICAgICBjb25zdCB3YXNEaXNhYmxlZCA9IGlzVGVsZXBvcnREaXNhYmxlZChuMS5wcm9wcyk7DQogICAgICBjb25zdCBjdXJyZW50Q29udGFpbmVyID0gd2FzRGlzYWJsZWQgPyBjb250YWluZXIgOiB0YXJnZXQ7DQogICAgICBjb25zdCBjdXJyZW50QW5jaG9yID0gd2FzRGlzYWJsZWQgPyBtYWluQW5jaG9yIDogdGFyZ2V0QW5jaG9yOw0KICAgICAgaWYgKG5hbWVzcGFjZSA9PT0gInN2ZyIgfHwgaXNUYXJnZXRTVkcodGFyZ2V0KSkgew0KICAgICAgICBuYW1lc3BhY2UgPSAic3ZnIjsNCiAgICAgIH0gZWxzZSBpZiAobmFtZXNwYWNlID09PSAibWF0aG1sIiB8fCBpc1RhcmdldE1hdGhNTCh0YXJnZXQpKSB7DQogICAgICAgIG5hbWVzcGFjZSA9ICJtYXRobWwiOw0KICAgICAgfQ0KICAgICAgaWYgKGR5bmFtaWNDaGlsZHJlbikgew0KICAgICAgICBwYXRjaEJsb2NrQ2hpbGRyZW4oDQogICAgICAgICAgbjEuZHluYW1pY0NoaWxkcmVuLA0KICAgICAgICAgIGR5bmFtaWNDaGlsZHJlbiwNCiAgICAgICAgICBjdXJyZW50Q29udGFpbmVyLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzDQogICAgICAgICk7DQogICAgICAgIHRyYXZlcnNlU3RhdGljQ2hpbGRyZW4objEsIG4yLCBmYWxzZSk7DQogICAgICB9IGVsc2UgaWYgKCFvcHRpbWl6ZWQpIHsNCiAgICAgICAgcGF0Y2hDaGlsZHJlbigNCiAgICAgICAgICBuMSwNCiAgICAgICAgICBuMiwNCiAgICAgICAgICBjdXJyZW50Q29udGFpbmVyLA0KICAgICAgICAgIGN1cnJlbnRBbmNob3IsDQogICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgZmFsc2UNCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICAgIGlmIChkaXNhYmxlZCkgew0KICAgICAgICBpZiAoIXdhc0Rpc2FibGVkKSB7DQogICAgICAgICAgbW92ZVRlbGVwb3J0KA0KICAgICAgICAgICAgbjIsDQogICAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgICBtYWluQW5jaG9yLA0KICAgICAgICAgICAgaW50ZXJuYWxzLA0KICAgICAgICAgICAgMQ0KICAgICAgICAgICk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgaWYgKG4yLnByb3BzICYmIG4xLnByb3BzICYmIG4yLnByb3BzLnRvICE9PSBuMS5wcm9wcy50bykgew0KICAgICAgICAgICAgbjIucHJvcHMudG8gPSBuMS5wcm9wcy50bzsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGlmICgobjIucHJvcHMgJiYgbjIucHJvcHMudG8pICE9PSAobjEucHJvcHMgJiYgbjEucHJvcHMudG8pKSB7DQogICAgICAgICAgY29uc3QgbmV4dFRhcmdldCA9IG4yLnRhcmdldCA9IHJlc29sdmVUYXJnZXQoDQogICAgICAgICAgICBuMi5wcm9wcywNCiAgICAgICAgICAgIHF1ZXJ5U2VsZWN0b3INCiAgICAgICAgICApOw0KICAgICAgICAgIGlmIChuZXh0VGFyZ2V0KSB7DQogICAgICAgICAgICBtb3ZlVGVsZXBvcnQoDQogICAgICAgICAgICAgIG4yLA0KICAgICAgICAgICAgICBuZXh0VGFyZ2V0LA0KICAgICAgICAgICAgICBudWxsLA0KICAgICAgICAgICAgICBpbnRlcm5hbHMsDQogICAgICAgICAgICAgIDANCiAgICAgICAgICAgICk7DQogICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIHdhcm4kMSgNCiAgICAgICAgICAgICAgIkludmFsaWQgVGVsZXBvcnQgdGFyZ2V0IG9uIHVwZGF0ZToiLA0KICAgICAgICAgICAgICB0YXJnZXQsDQogICAgICAgICAgICAgIGAoJHt0eXBlb2YgdGFyZ2V0fSlgDQogICAgICAgICAgICApOw0KICAgICAgICAgIH0NCiAgICAgICAgfSBlbHNlIGlmICh3YXNEaXNhYmxlZCkgew0KICAgICAgICAgIG1vdmVUZWxlcG9ydCgNCiAgICAgICAgICAgIG4yLA0KICAgICAgICAgICAgdGFyZ2V0LA0KICAgICAgICAgICAgdGFyZ2V0QW5jaG9yLA0KICAgICAgICAgICAgaW50ZXJuYWxzLA0KICAgICAgICAgICAgMQ0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIHVwZGF0ZUNzc1ZhcnMobjIsIGRpc2FibGVkKTsNCiAgICB9DQogIH0sDQogIHJlbW92ZSh2bm9kZSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgeyB1bTogdW5tb3VudCwgbzogeyByZW1vdmU6IGhvc3RSZW1vdmUgfSB9LCBkb1JlbW92ZSkgew0KICAgIGNvbnN0IHsNCiAgICAgIHNoYXBlRmxhZywNCiAgICAgIGNoaWxkcmVuLA0KICAgICAgYW5jaG9yLA0KICAgICAgdGFyZ2V0U3RhcnQsDQogICAgICB0YXJnZXRBbmNob3IsDQogICAgICB0YXJnZXQsDQogICAgICBwcm9wcw0KICAgIH0gPSB2bm9kZTsNCiAgICBpZiAodGFyZ2V0KSB7DQogICAgICBob3N0UmVtb3ZlKHRhcmdldFN0YXJ0KTsNCiAgICAgIGhvc3RSZW1vdmUodGFyZ2V0QW5jaG9yKTsNCiAgICB9DQogICAgZG9SZW1vdmUgJiYgaG9zdFJlbW92ZShhbmNob3IpOw0KICAgIGlmIChzaGFwZUZsYWcgJiAxNikgew0KICAgICAgY29uc3Qgc2hvdWxkUmVtb3ZlID0gZG9SZW1vdmUgfHwgIWlzVGVsZXBvcnREaXNhYmxlZChwcm9wcyk7DQogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7DQogICAgICAgIGNvbnN0IGNoaWxkID0gY2hpbGRyZW5baV07DQogICAgICAgIHVubW91bnQoDQogICAgICAgICAgY2hpbGQsDQogICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgIHNob3VsZFJlbW92ZSwNCiAgICAgICAgICAhIWNoaWxkLmR5bmFtaWNDaGlsZHJlbg0KICAgICAgICApOw0KICAgICAgfQ0KICAgIH0NCiAgfSwNCiAgbW92ZTogbW92ZVRlbGVwb3J0LA0KICBoeWRyYXRlOiBoeWRyYXRlVGVsZXBvcnQNCn07DQpmdW5jdGlvbiBtb3ZlVGVsZXBvcnQodm5vZGUsIGNvbnRhaW5lciwgcGFyZW50QW5jaG9yLCB7IG86IHsgaW5zZXJ0IH0sIG06IG1vdmUgfSwgbW92ZVR5cGUgPSAyKSB7DQogIGlmIChtb3ZlVHlwZSA9PT0gMCkgew0KICAgIGluc2VydCh2bm9kZS50YXJnZXRBbmNob3IsIGNvbnRhaW5lciwgcGFyZW50QW5jaG9yKTsNCiAgfQ0KICBjb25zdCB7IGVsLCBhbmNob3IsIHNoYXBlRmxhZywgY2hpbGRyZW4sIHByb3BzIH0gPSB2bm9kZTsNCiAgY29uc3QgaXNSZW9yZGVyID0gbW92ZVR5cGUgPT09IDI7DQogIGlmIChpc1Jlb3JkZXIpIHsNCiAgICBpbnNlcnQoZWwsIGNvbnRhaW5lciwgcGFyZW50QW5jaG9yKTsNCiAgfQ0KICBpZiAoIWlzUmVvcmRlciB8fCBpc1RlbGVwb3J0RGlzYWJsZWQocHJvcHMpKSB7DQogICAgaWYgKHNoYXBlRmxhZyAmIDE2KSB7DQogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7DQogICAgICAgIG1vdmUoDQogICAgICAgICAgY2hpbGRyZW5baV0sDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIHBhcmVudEFuY2hvciwNCiAgICAgICAgICAyDQogICAgICAgICk7DQogICAgICB9DQogICAgfQ0KICB9DQogIGlmIChpc1Jlb3JkZXIpIHsNCiAgICBpbnNlcnQoYW5jaG9yLCBjb250YWluZXIsIHBhcmVudEFuY2hvcik7DQogIH0NCn0NCmZ1bmN0aW9uIGh5ZHJhdGVUZWxlcG9ydChub2RlLCB2bm9kZSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQsIHsNCiAgbzogeyBuZXh0U2libGluZywgcGFyZW50Tm9kZSwgcXVlcnlTZWxlY3RvciwgaW5zZXJ0LCBjcmVhdGVUZXh0IH0NCn0sIGh5ZHJhdGVDaGlsZHJlbikgew0KICBjb25zdCB0YXJnZXQgPSB2bm9kZS50YXJnZXQgPSByZXNvbHZlVGFyZ2V0KA0KICAgIHZub2RlLnByb3BzLA0KICAgIHF1ZXJ5U2VsZWN0b3INCiAgKTsNCiAgaWYgKHRhcmdldCkgew0KICAgIGNvbnN0IGRpc2FibGVkID0gaXNUZWxlcG9ydERpc2FibGVkKHZub2RlLnByb3BzKTsNCiAgICBjb25zdCB0YXJnZXROb2RlID0gdGFyZ2V0Ll9scGEgfHwgdGFyZ2V0LmZpcnN0Q2hpbGQ7DQogICAgaWYgKHZub2RlLnNoYXBlRmxhZyAmIDE2KSB7DQogICAgICBpZiAoZGlzYWJsZWQpIHsNCiAgICAgICAgdm5vZGUuYW5jaG9yID0gaHlkcmF0ZUNoaWxkcmVuKA0KICAgICAgICAgIG5leHRTaWJsaW5nKG5vZGUpLA0KICAgICAgICAgIHZub2RlLA0KICAgICAgICAgIHBhcmVudE5vZGUobm9kZSksDQogICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgKTsNCiAgICAgICAgdm5vZGUudGFyZ2V0U3RhcnQgPSB0YXJnZXROb2RlOw0KICAgICAgICB2bm9kZS50YXJnZXRBbmNob3IgPSB0YXJnZXROb2RlICYmIG5leHRTaWJsaW5nKHRhcmdldE5vZGUpOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgdm5vZGUuYW5jaG9yID0gbmV4dFNpYmxpbmcobm9kZSk7DQogICAgICAgIGxldCB0YXJnZXRBbmNob3IgPSB0YXJnZXROb2RlOw0KICAgICAgICB3aGlsZSAodGFyZ2V0QW5jaG9yKSB7DQogICAgICAgICAgaWYgKHRhcmdldEFuY2hvciAmJiB0YXJnZXRBbmNob3Iubm9kZVR5cGUgPT09IDgpIHsNCiAgICAgICAgICAgIGlmICh0YXJnZXRBbmNob3IuZGF0YSA9PT0gInRlbGVwb3J0IHN0YXJ0IGFuY2hvciIpIHsNCiAgICAgICAgICAgICAgdm5vZGUudGFyZ2V0U3RhcnQgPSB0YXJnZXRBbmNob3I7DQogICAgICAgICAgICB9IGVsc2UgaWYgKHRhcmdldEFuY2hvci5kYXRhID09PSAidGVsZXBvcnQgYW5jaG9yIikgew0KICAgICAgICAgICAgICB2bm9kZS50YXJnZXRBbmNob3IgPSB0YXJnZXRBbmNob3I7DQogICAgICAgICAgICAgIHRhcmdldC5fbHBhID0gdm5vZGUudGFyZ2V0QW5jaG9yICYmIG5leHRTaWJsaW5nKHZub2RlLnRhcmdldEFuY2hvcik7DQogICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgIH0NCiAgICAgICAgICB0YXJnZXRBbmNob3IgPSBuZXh0U2libGluZyh0YXJnZXRBbmNob3IpOw0KICAgICAgICB9DQogICAgICAgIGlmICghdm5vZGUudGFyZ2V0QW5jaG9yKSB7DQogICAgICAgICAgcHJlcGFyZUFuY2hvcih0YXJnZXQsIHZub2RlLCBjcmVhdGVUZXh0LCBpbnNlcnQpOw0KICAgICAgICB9DQogICAgICAgIGh5ZHJhdGVDaGlsZHJlbigNCiAgICAgICAgICB0YXJnZXROb2RlICYmIG5leHRTaWJsaW5nKHRhcmdldE5vZGUpLA0KICAgICAgICAgIHZub2RlLA0KICAgICAgICAgIHRhcmdldCwNCiAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICApOw0KICAgICAgfQ0KICAgIH0NCiAgICB1cGRhdGVDc3NWYXJzKHZub2RlLCBkaXNhYmxlZCk7DQogIH0NCiAgcmV0dXJuIHZub2RlLmFuY2hvciAmJiBuZXh0U2libGluZyh2bm9kZS5hbmNob3IpOw0KfQ0KY29uc3QgVGVsZXBvcnQgPSBUZWxlcG9ydEltcGw7DQpmdW5jdGlvbiB1cGRhdGVDc3NWYXJzKHZub2RlLCBpc0Rpc2FibGVkKSB7DQogIGNvbnN0IGN0eCA9IHZub2RlLmN0eDsNCiAgaWYgKGN0eCAmJiBjdHgudXQpIHsNCiAgICBsZXQgbm9kZSwgYW5jaG9yOw0KICAgIGlmIChpc0Rpc2FibGVkKSB7DQogICAgICBub2RlID0gdm5vZGUuZWw7DQogICAgICBhbmNob3IgPSB2bm9kZS5hbmNob3I7DQogICAgfSBlbHNlIHsNCiAgICAgIG5vZGUgPSB2bm9kZS50YXJnZXRTdGFydDsNCiAgICAgIGFuY2hvciA9IHZub2RlLnRhcmdldEFuY2hvcjsNCiAgICB9DQogICAgd2hpbGUgKG5vZGUgJiYgbm9kZSAhPT0gYW5jaG9yKSB7DQogICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PT0gMSkgbm9kZS5zZXRBdHRyaWJ1dGUoImRhdGEtdi1vd25lciIsIGN0eC51aWQpOw0KICAgICAgbm9kZSA9IG5vZGUubmV4dFNpYmxpbmc7DQogICAgfQ0KICAgIGN0eC51dCgpOw0KICB9DQp9DQpmdW5jdGlvbiBwcmVwYXJlQW5jaG9yKHRhcmdldCwgdm5vZGUsIGNyZWF0ZVRleHQsIGluc2VydCkgew0KICBjb25zdCB0YXJnZXRTdGFydCA9IHZub2RlLnRhcmdldFN0YXJ0ID0gY3JlYXRlVGV4dCgiIik7DQogIGNvbnN0IHRhcmdldEFuY2hvciA9IHZub2RlLnRhcmdldEFuY2hvciA9IGNyZWF0ZVRleHQoIiIpOw0KICB0YXJnZXRTdGFydFtUZWxlcG9ydEVuZEtleV0gPSB0YXJnZXRBbmNob3I7DQogIGlmICh0YXJnZXQpIHsNCiAgICBpbnNlcnQodGFyZ2V0U3RhcnQsIHRhcmdldCk7DQogICAgaW5zZXJ0KHRhcmdldEFuY2hvciwgdGFyZ2V0KTsNCiAgfQ0KICByZXR1cm4gdGFyZ2V0QW5jaG9yOw0KfQ0KDQpjb25zdCBsZWF2ZUNiS2V5ID0gU3ltYm9sKCJfbGVhdmVDYiIpOw0KY29uc3QgZW50ZXJDYktleSQxID0gU3ltYm9sKCJfZW50ZXJDYiIpOw0KZnVuY3Rpb24gdXNlVHJhbnNpdGlvblN0YXRlKCkgew0KICBjb25zdCBzdGF0ZSA9IHsNCiAgICBpc01vdW50ZWQ6IGZhbHNlLA0KICAgIGlzTGVhdmluZzogZmFsc2UsDQogICAgaXNVbm1vdW50aW5nOiBmYWxzZSwNCiAgICBsZWF2aW5nVk5vZGVzOiAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpDQogIH07DQogIG9uTW91bnRlZCgoKSA9PiB7DQogICAgc3RhdGUuaXNNb3VudGVkID0gdHJ1ZTsNCiAgfSk7DQogIG9uQmVmb3JlVW5tb3VudCgoKSA9PiB7DQogICAgc3RhdGUuaXNVbm1vdW50aW5nID0gdHJ1ZTsNCiAgfSk7DQogIHJldHVybiBzdGF0ZTsNCn0NCmNvbnN0IFRyYW5zaXRpb25Ib29rVmFsaWRhdG9yID0gW0Z1bmN0aW9uLCBBcnJheV07DQpjb25zdCBCYXNlVHJhbnNpdGlvblByb3BzVmFsaWRhdG9ycyA9IHsNCiAgbW9kZTogU3RyaW5nLA0KICBhcHBlYXI6IEJvb2xlYW4sDQogIHBlcnNpc3RlZDogQm9vbGVhbiwNCiAgLy8gZW50ZXINCiAgb25CZWZvcmVFbnRlcjogVHJhbnNpdGlvbkhvb2tWYWxpZGF0b3IsDQogIG9uRW50ZXI6IFRyYW5zaXRpb25Ib29rVmFsaWRhdG9yLA0KICBvbkFmdGVyRW50ZXI6IFRyYW5zaXRpb25Ib29rVmFsaWRhdG9yLA0KICBvbkVudGVyQ2FuY2VsbGVkOiBUcmFuc2l0aW9uSG9va1ZhbGlkYXRvciwNCiAgLy8gbGVhdmUNCiAgb25CZWZvcmVMZWF2ZTogVHJhbnNpdGlvbkhvb2tWYWxpZGF0b3IsDQogIG9uTGVhdmU6IFRyYW5zaXRpb25Ib29rVmFsaWRhdG9yLA0KICBvbkFmdGVyTGVhdmU6IFRyYW5zaXRpb25Ib29rVmFsaWRhdG9yLA0KICBvbkxlYXZlQ2FuY2VsbGVkOiBUcmFuc2l0aW9uSG9va1ZhbGlkYXRvciwNCiAgLy8gYXBwZWFyDQogIG9uQmVmb3JlQXBwZWFyOiBUcmFuc2l0aW9uSG9va1ZhbGlkYXRvciwNCiAgb25BcHBlYXI6IFRyYW5zaXRpb25Ib29rVmFsaWRhdG9yLA0KICBvbkFmdGVyQXBwZWFyOiBUcmFuc2l0aW9uSG9va1ZhbGlkYXRvciwNCiAgb25BcHBlYXJDYW5jZWxsZWQ6IFRyYW5zaXRpb25Ib29rVmFsaWRhdG9yDQp9Ow0KY29uc3QgcmVjdXJzaXZlR2V0U3VidHJlZSA9IChpbnN0YW5jZSkgPT4gew0KICBjb25zdCBzdWJUcmVlID0gaW5zdGFuY2Uuc3ViVHJlZTsNCiAgcmV0dXJuIHN1YlRyZWUuY29tcG9uZW50ID8gcmVjdXJzaXZlR2V0U3VidHJlZShzdWJUcmVlLmNvbXBvbmVudCkgOiBzdWJUcmVlOw0KfTsNCmNvbnN0IEJhc2VUcmFuc2l0aW9uSW1wbCA9IHsNCiAgbmFtZTogYEJhc2VUcmFuc2l0aW9uYCwNCiAgcHJvcHM6IEJhc2VUcmFuc2l0aW9uUHJvcHNWYWxpZGF0b3JzLA0KICBzZXR1cChwcm9wcywgeyBzbG90cyB9KSB7DQogICAgY29uc3QgaW5zdGFuY2UgPSBnZXRDdXJyZW50SW5zdGFuY2UoKTsNCiAgICBjb25zdCBzdGF0ZSA9IHVzZVRyYW5zaXRpb25TdGF0ZSgpOw0KICAgIHJldHVybiAoKSA9PiB7DQogICAgICBjb25zdCBjaGlsZHJlbiA9IHNsb3RzLmRlZmF1bHQgJiYgZ2V0VHJhbnNpdGlvblJhd0NoaWxkcmVuKHNsb3RzLmRlZmF1bHQoKSwgdHJ1ZSk7DQogICAgICBpZiAoIWNoaWxkcmVuIHx8ICFjaGlsZHJlbi5sZW5ndGgpIHsNCiAgICAgICAgcmV0dXJuOw0KICAgICAgfQ0KICAgICAgY29uc3QgY2hpbGQgPSBmaW5kTm9uQ29tbWVudENoaWxkKGNoaWxkcmVuKTsNCiAgICAgIGNvbnN0IHJhd1Byb3BzID0gdG9SYXcocHJvcHMpOw0KICAgICAgY29uc3QgeyBtb2RlIH0gPSByYXdQcm9wczsNCiAgICAgIGlmIChtb2RlICYmIG1vZGUgIT09ICJpbi1vdXQiICYmIG1vZGUgIT09ICJvdXQtaW4iICYmIG1vZGUgIT09ICJkZWZhdWx0Iikgew0KICAgICAgICB3YXJuJDEoYGludmFsaWQgPHRyYW5zaXRpb24+IG1vZGU6ICR7bW9kZX1gKTsNCiAgICAgIH0NCiAgICAgIGlmIChzdGF0ZS5pc0xlYXZpbmcpIHsNCiAgICAgICAgcmV0dXJuIGVtcHR5UGxhY2Vob2xkZXIoY2hpbGQpOw0KICAgICAgfQ0KICAgICAgY29uc3QgaW5uZXJDaGlsZCA9IGdldElubmVyQ2hpbGQkMShjaGlsZCk7DQogICAgICBpZiAoIWlubmVyQ2hpbGQpIHsNCiAgICAgICAgcmV0dXJuIGVtcHR5UGxhY2Vob2xkZXIoY2hpbGQpOw0KICAgICAgfQ0KICAgICAgbGV0IGVudGVySG9va3MgPSByZXNvbHZlVHJhbnNpdGlvbkhvb2tzKA0KICAgICAgICBpbm5lckNoaWxkLA0KICAgICAgICByYXdQcm9wcywNCiAgICAgICAgc3RhdGUsDQogICAgICAgIGluc3RhbmNlLA0KICAgICAgICAvLyAjMTEwNjEsIGVuc3VyZSBlbnRlckhvb2tzIGlzIGZyZXNoIGFmdGVyIGNsb25lDQogICAgICAgIChob29rcykgPT4gZW50ZXJIb29rcyA9IGhvb2tzDQogICAgICApOw0KICAgICAgaWYgKGlubmVyQ2hpbGQudHlwZSAhPT0gQ29tbWVudCkgew0KICAgICAgICBzZXRUcmFuc2l0aW9uSG9va3MoaW5uZXJDaGlsZCwgZW50ZXJIb29rcyk7DQogICAgICB9DQogICAgICBsZXQgb2xkSW5uZXJDaGlsZCA9IGluc3RhbmNlLnN1YlRyZWUgJiYgZ2V0SW5uZXJDaGlsZCQxKGluc3RhbmNlLnN1YlRyZWUpOw0KICAgICAgaWYgKG9sZElubmVyQ2hpbGQgJiYgb2xkSW5uZXJDaGlsZC50eXBlICE9PSBDb21tZW50ICYmICFpc1NhbWVWTm9kZVR5cGUoaW5uZXJDaGlsZCwgb2xkSW5uZXJDaGlsZCkgJiYgcmVjdXJzaXZlR2V0U3VidHJlZShpbnN0YW5jZSkudHlwZSAhPT0gQ29tbWVudCkgew0KICAgICAgICBsZXQgbGVhdmluZ0hvb2tzID0gcmVzb2x2ZVRyYW5zaXRpb25Ib29rcygNCiAgICAgICAgICBvbGRJbm5lckNoaWxkLA0KICAgICAgICAgIHJhd1Byb3BzLA0KICAgICAgICAgIHN0YXRlLA0KICAgICAgICAgIGluc3RhbmNlDQogICAgICAgICk7DQogICAgICAgIHNldFRyYW5zaXRpb25Ib29rcyhvbGRJbm5lckNoaWxkLCBsZWF2aW5nSG9va3MpOw0KICAgICAgICBpZiAobW9kZSA9PT0gIm91dC1pbiIgJiYgaW5uZXJDaGlsZC50eXBlICE9PSBDb21tZW50KSB7DQogICAgICAgICAgc3RhdGUuaXNMZWF2aW5nID0gdHJ1ZTsNCiAgICAgICAgICBsZWF2aW5nSG9va3MuYWZ0ZXJMZWF2ZSA9ICgpID0+IHsNCiAgICAgICAgICAgIHN0YXRlLmlzTGVhdmluZyA9IGZhbHNlOw0KICAgICAgICAgICAgaWYgKCEoaW5zdGFuY2Uuam9iLmZsYWdzICYgOCkpIHsNCiAgICAgICAgICAgICAgaW5zdGFuY2UudXBkYXRlKCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBkZWxldGUgbGVhdmluZ0hvb2tzLmFmdGVyTGVhdmU7DQogICAgICAgICAgICBvbGRJbm5lckNoaWxkID0gdm9pZCAwOw0KICAgICAgICAgIH07DQogICAgICAgICAgcmV0dXJuIGVtcHR5UGxhY2Vob2xkZXIoY2hpbGQpOw0KICAgICAgICB9IGVsc2UgaWYgKG1vZGUgPT09ICJpbi1vdXQiICYmIGlubmVyQ2hpbGQudHlwZSAhPT0gQ29tbWVudCkgew0KICAgICAgICAgIGxlYXZpbmdIb29rcy5kZWxheUxlYXZlID0gKGVsLCBlYXJseVJlbW92ZSwgZGVsYXllZExlYXZlKSA9PiB7DQogICAgICAgICAgICBjb25zdCBsZWF2aW5nVk5vZGVzQ2FjaGUgPSBnZXRMZWF2aW5nTm9kZXNGb3JUeXBlKA0KICAgICAgICAgICAgICBzdGF0ZSwNCiAgICAgICAgICAgICAgb2xkSW5uZXJDaGlsZA0KICAgICAgICAgICAgKTsNCiAgICAgICAgICAgIGxlYXZpbmdWTm9kZXNDYWNoZVtTdHJpbmcob2xkSW5uZXJDaGlsZC5rZXkpXSA9IG9sZElubmVyQ2hpbGQ7DQogICAgICAgICAgICBlbFtsZWF2ZUNiS2V5XSA9ICgpID0+IHsNCiAgICAgICAgICAgICAgZWFybHlSZW1vdmUoKTsNCiAgICAgICAgICAgICAgZWxbbGVhdmVDYktleV0gPSB2b2lkIDA7DQogICAgICAgICAgICAgIGRlbGV0ZSBlbnRlckhvb2tzLmRlbGF5ZWRMZWF2ZTsNCiAgICAgICAgICAgICAgb2xkSW5uZXJDaGlsZCA9IHZvaWQgMDsNCiAgICAgICAgICAgIH07DQogICAgICAgICAgICBlbnRlckhvb2tzLmRlbGF5ZWRMZWF2ZSA9ICgpID0+IHsNCiAgICAgICAgICAgICAgZGVsYXllZExlYXZlKCk7DQogICAgICAgICAgICAgIGRlbGV0ZSBlbnRlckhvb2tzLmRlbGF5ZWRMZWF2ZTsNCiAgICAgICAgICAgICAgb2xkSW5uZXJDaGlsZCA9IHZvaWQgMDsNCiAgICAgICAgICAgIH07DQogICAgICAgICAgfTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBvbGRJbm5lckNoaWxkID0gdm9pZCAwOw0KICAgICAgICB9DQogICAgICB9IGVsc2UgaWYgKG9sZElubmVyQ2hpbGQpIHsNCiAgICAgICAgb2xkSW5uZXJDaGlsZCA9IHZvaWQgMDsNCiAgICAgIH0NCiAgICAgIHJldHVybiBjaGlsZDsNCiAgICB9Ow0KICB9DQp9Ow0KZnVuY3Rpb24gZmluZE5vbkNvbW1lbnRDaGlsZChjaGlsZHJlbikgew0KICBsZXQgY2hpbGQgPSBjaGlsZHJlblswXTsNCiAgaWYgKGNoaWxkcmVuLmxlbmd0aCA+IDEpIHsNCiAgICBsZXQgaGFzRm91bmQgPSBmYWxzZTsNCiAgICBmb3IgKGNvbnN0IGMgb2YgY2hpbGRyZW4pIHsNCiAgICAgIGlmIChjLnR5cGUgIT09IENvbW1lbnQpIHsNCiAgICAgICAgaWYgKGhhc0ZvdW5kKSB7DQogICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgIjx0cmFuc2l0aW9uPiBjYW4gb25seSBiZSB1c2VkIG9uIGEgc2luZ2xlIGVsZW1lbnQgb3IgY29tcG9uZW50LiBVc2UgPHRyYW5zaXRpb24tZ3JvdXA+IGZvciBsaXN0cy4iDQogICAgICAgICAgKTsNCiAgICAgICAgICBicmVhazsNCiAgICAgICAgfQ0KICAgICAgICBjaGlsZCA9IGM7DQogICAgICAgIGhhc0ZvdW5kID0gdHJ1ZTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgcmV0dXJuIGNoaWxkOw0KfQ0KY29uc3QgQmFzZVRyYW5zaXRpb24gPSBCYXNlVHJhbnNpdGlvbkltcGw7DQpmdW5jdGlvbiBnZXRMZWF2aW5nTm9kZXNGb3JUeXBlKHN0YXRlLCB2bm9kZSkgew0KICBjb25zdCB7IGxlYXZpbmdWTm9kZXMgfSA9IHN0YXRlOw0KICBsZXQgbGVhdmluZ1ZOb2Rlc0NhY2hlID0gbGVhdmluZ1ZOb2Rlcy5nZXQodm5vZGUudHlwZSk7DQogIGlmICghbGVhdmluZ1ZOb2Rlc0NhY2hlKSB7DQogICAgbGVhdmluZ1ZOb2Rlc0NhY2hlID0gLyogQF9fUFVSRV9fICovIE9iamVjdC5jcmVhdGUobnVsbCk7DQogICAgbGVhdmluZ1ZOb2Rlcy5zZXQodm5vZGUudHlwZSwgbGVhdmluZ1ZOb2Rlc0NhY2hlKTsNCiAgfQ0KICByZXR1cm4gbGVhdmluZ1ZOb2Rlc0NhY2hlOw0KfQ0KZnVuY3Rpb24gcmVzb2x2ZVRyYW5zaXRpb25Ib29rcyh2bm9kZSwgcHJvcHMsIHN0YXRlLCBpbnN0YW5jZSwgcG9zdENsb25lKSB7DQogIGNvbnN0IHsNCiAgICBhcHBlYXIsDQogICAgbW9kZSwNCiAgICBwZXJzaXN0ZWQgPSBmYWxzZSwNCiAgICBvbkJlZm9yZUVudGVyLA0KICAgIG9uRW50ZXIsDQogICAgb25BZnRlckVudGVyLA0KICAgIG9uRW50ZXJDYW5jZWxsZWQsDQogICAgb25CZWZvcmVMZWF2ZSwNCiAgICBvbkxlYXZlLA0KICAgIG9uQWZ0ZXJMZWF2ZSwNCiAgICBvbkxlYXZlQ2FuY2VsbGVkLA0KICAgIG9uQmVmb3JlQXBwZWFyLA0KICAgIG9uQXBwZWFyLA0KICAgIG9uQWZ0ZXJBcHBlYXIsDQogICAgb25BcHBlYXJDYW5jZWxsZWQNCiAgfSA9IHByb3BzOw0KICBjb25zdCBrZXkgPSBTdHJpbmcodm5vZGUua2V5KTsNCiAgY29uc3QgbGVhdmluZ1ZOb2Rlc0NhY2hlID0gZ2V0TGVhdmluZ05vZGVzRm9yVHlwZShzdGF0ZSwgdm5vZGUpOw0KICBjb25zdCBjYWxsSG9vayA9IChob29rLCBhcmdzKSA9PiB7DQogICAgaG9vayAmJiBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZygNCiAgICAgIGhvb2ssDQogICAgICBpbnN0YW5jZSwNCiAgICAgIDksDQogICAgICBhcmdzDQogICAgKTsNCiAgfTsNCiAgY29uc3QgY2FsbEFzeW5jSG9vayA9IChob29rLCBhcmdzKSA9PiB7DQogICAgY29uc3QgZG9uZSA9IGFyZ3NbMV07DQogICAgY2FsbEhvb2soaG9vaywgYXJncyk7DQogICAgaWYgKGlzQXJyYXkoaG9vaykpIHsNCiAgICAgIGlmIChob29rLmV2ZXJ5KChob29rMikgPT4gaG9vazIubGVuZ3RoIDw9IDEpKSBkb25lKCk7DQogICAgfSBlbHNlIGlmIChob29rLmxlbmd0aCA8PSAxKSB7DQogICAgICBkb25lKCk7DQogICAgfQ0KICB9Ow0KICBjb25zdCBob29rcyA9IHsNCiAgICBtb2RlLA0KICAgIHBlcnNpc3RlZCwNCiAgICBiZWZvcmVFbnRlcihlbCkgew0KICAgICAgbGV0IGhvb2sgPSBvbkJlZm9yZUVudGVyOw0KICAgICAgaWYgKCFzdGF0ZS5pc01vdW50ZWQpIHsNCiAgICAgICAgaWYgKGFwcGVhcikgew0KICAgICAgICAgIGhvb2sgPSBvbkJlZm9yZUFwcGVhciB8fCBvbkJlZm9yZUVudGVyOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIHJldHVybjsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgaWYgKGVsW2xlYXZlQ2JLZXldKSB7DQogICAgICAgIGVsW2xlYXZlQ2JLZXldKA0KICAgICAgICAgIHRydWUNCiAgICAgICAgICAvKiBjYW5jZWxsZWQgKi8NCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICAgIGNvbnN0IGxlYXZpbmdWTm9kZSA9IGxlYXZpbmdWTm9kZXNDYWNoZVtrZXldOw0KICAgICAgaWYgKGxlYXZpbmdWTm9kZSAmJiBpc1NhbWVWTm9kZVR5cGUodm5vZGUsIGxlYXZpbmdWTm9kZSkgJiYgbGVhdmluZ1ZOb2RlLmVsW2xlYXZlQ2JLZXldKSB7DQogICAgICAgIGxlYXZpbmdWTm9kZS5lbFtsZWF2ZUNiS2V5XSgpOw0KICAgICAgfQ0KICAgICAgY2FsbEhvb2soaG9vaywgW2VsXSk7DQogICAgfSwNCiAgICBlbnRlcihlbCkgew0KICAgICAgbGV0IGhvb2sgPSBvbkVudGVyOw0KICAgICAgbGV0IGFmdGVySG9vayA9IG9uQWZ0ZXJFbnRlcjsNCiAgICAgIGxldCBjYW5jZWxIb29rID0gb25FbnRlckNhbmNlbGxlZDsNCiAgICAgIGlmICghc3RhdGUuaXNNb3VudGVkKSB7DQogICAgICAgIGlmIChhcHBlYXIpIHsNCiAgICAgICAgICBob29rID0gb25BcHBlYXIgfHwgb25FbnRlcjsNCiAgICAgICAgICBhZnRlckhvb2sgPSBvbkFmdGVyQXBwZWFyIHx8IG9uQWZ0ZXJFbnRlcjsNCiAgICAgICAgICBjYW5jZWxIb29rID0gb25BcHBlYXJDYW5jZWxsZWQgfHwgb25FbnRlckNhbmNlbGxlZDsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICByZXR1cm47DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGxldCBjYWxsZWQgPSBmYWxzZTsNCiAgICAgIGNvbnN0IGRvbmUgPSBlbFtlbnRlckNiS2V5JDFdID0gKGNhbmNlbGxlZCkgPT4gew0KICAgICAgICBpZiAoY2FsbGVkKSByZXR1cm47DQogICAgICAgIGNhbGxlZCA9IHRydWU7DQogICAgICAgIGlmIChjYW5jZWxsZWQpIHsNCiAgICAgICAgICBjYWxsSG9vayhjYW5jZWxIb29rLCBbZWxdKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBjYWxsSG9vayhhZnRlckhvb2ssIFtlbF0pOw0KICAgICAgICB9DQogICAgICAgIGlmIChob29rcy5kZWxheWVkTGVhdmUpIHsNCiAgICAgICAgICBob29rcy5kZWxheWVkTGVhdmUoKTsNCiAgICAgICAgfQ0KICAgICAgICBlbFtlbnRlckNiS2V5JDFdID0gdm9pZCAwOw0KICAgICAgfTsNCiAgICAgIGlmIChob29rKSB7DQogICAgICAgIGNhbGxBc3luY0hvb2soaG9vaywgW2VsLCBkb25lXSk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBkb25lKCk7DQogICAgICB9DQogICAgfSwNCiAgICBsZWF2ZShlbCwgcmVtb3ZlKSB7DQogICAgICBjb25zdCBrZXkyID0gU3RyaW5nKHZub2RlLmtleSk7DQogICAgICBpZiAoZWxbZW50ZXJDYktleSQxXSkgew0KICAgICAgICBlbFtlbnRlckNiS2V5JDFdKA0KICAgICAgICAgIHRydWUNCiAgICAgICAgICAvKiBjYW5jZWxsZWQgKi8NCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICAgIGlmIChzdGF0ZS5pc1VubW91bnRpbmcpIHsNCiAgICAgICAgcmV0dXJuIHJlbW92ZSgpOw0KICAgICAgfQ0KICAgICAgY2FsbEhvb2sob25CZWZvcmVMZWF2ZSwgW2VsXSk7DQogICAgICBsZXQgY2FsbGVkID0gZmFsc2U7DQogICAgICBjb25zdCBkb25lID0gZWxbbGVhdmVDYktleV0gPSAoY2FuY2VsbGVkKSA9PiB7DQogICAgICAgIGlmIChjYWxsZWQpIHJldHVybjsNCiAgICAgICAgY2FsbGVkID0gdHJ1ZTsNCiAgICAgICAgcmVtb3ZlKCk7DQogICAgICAgIGlmIChjYW5jZWxsZWQpIHsNCiAgICAgICAgICBjYWxsSG9vayhvbkxlYXZlQ2FuY2VsbGVkLCBbZWxdKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBjYWxsSG9vayhvbkFmdGVyTGVhdmUsIFtlbF0pOw0KICAgICAgICB9DQogICAgICAgIGVsW2xlYXZlQ2JLZXldID0gdm9pZCAwOw0KICAgICAgICBpZiAobGVhdmluZ1ZOb2Rlc0NhY2hlW2tleTJdID09PSB2bm9kZSkgew0KICAgICAgICAgIGRlbGV0ZSBsZWF2aW5nVk5vZGVzQ2FjaGVba2V5Ml07DQogICAgICAgIH0NCiAgICAgIH07DQogICAgICBsZWF2aW5nVk5vZGVzQ2FjaGVba2V5Ml0gPSB2bm9kZTsNCiAgICAgIGlmIChvbkxlYXZlKSB7DQogICAgICAgIGNhbGxBc3luY0hvb2sob25MZWF2ZSwgW2VsLCBkb25lXSk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBkb25lKCk7DQogICAgICB9DQogICAgfSwNCiAgICBjbG9uZSh2bm9kZTIpIHsNCiAgICAgIGNvbnN0IGhvb2tzMiA9IHJlc29sdmVUcmFuc2l0aW9uSG9va3MoDQogICAgICAgIHZub2RlMiwNCiAgICAgICAgcHJvcHMsDQogICAgICAgIHN0YXRlLA0KICAgICAgICBpbnN0YW5jZSwNCiAgICAgICAgcG9zdENsb25lDQogICAgICApOw0KICAgICAgaWYgKHBvc3RDbG9uZSkgcG9zdENsb25lKGhvb2tzMik7DQogICAgICByZXR1cm4gaG9va3MyOw0KICAgIH0NCiAgfTsNCiAgcmV0dXJuIGhvb2tzOw0KfQ0KZnVuY3Rpb24gZW1wdHlQbGFjZWhvbGRlcih2bm9kZSkgew0KICBpZiAoaXNLZWVwQWxpdmUodm5vZGUpKSB7DQogICAgdm5vZGUgPSBjbG9uZVZOb2RlKHZub2RlKTsNCiAgICB2bm9kZS5jaGlsZHJlbiA9IG51bGw7DQogICAgcmV0dXJuIHZub2RlOw0KICB9DQp9DQpmdW5jdGlvbiBnZXRJbm5lckNoaWxkJDEodm5vZGUpIHsNCiAgaWYgKCFpc0tlZXBBbGl2ZSh2bm9kZSkpIHsNCiAgICBpZiAoaXNUZWxlcG9ydCh2bm9kZS50eXBlKSAmJiB2bm9kZS5jaGlsZHJlbikgew0KICAgICAgcmV0dXJuIGZpbmROb25Db21tZW50Q2hpbGQodm5vZGUuY2hpbGRyZW4pOw0KICAgIH0NCiAgICByZXR1cm4gdm5vZGU7DQogIH0NCiAgaWYgKHZub2RlLmNvbXBvbmVudCkgew0KICAgIHJldHVybiB2bm9kZS5jb21wb25lbnQuc3ViVHJlZTsNCiAgfQ0KICBjb25zdCB7IHNoYXBlRmxhZywgY2hpbGRyZW4gfSA9IHZub2RlOw0KICBpZiAoY2hpbGRyZW4pIHsNCiAgICBpZiAoc2hhcGVGbGFnICYgMTYpIHsNCiAgICAgIHJldHVybiBjaGlsZHJlblswXTsNCiAgICB9DQogICAgaWYgKHNoYXBlRmxhZyAmIDMyICYmIGlzRnVuY3Rpb24oY2hpbGRyZW4uZGVmYXVsdCkpIHsNCiAgICAgIHJldHVybiBjaGlsZHJlbi5kZWZhdWx0KCk7DQogICAgfQ0KICB9DQp9DQpmdW5jdGlvbiBzZXRUcmFuc2l0aW9uSG9va3Modm5vZGUsIGhvb2tzKSB7DQogIGlmICh2bm9kZS5zaGFwZUZsYWcgJiA2ICYmIHZub2RlLmNvbXBvbmVudCkgew0KICAgIHZub2RlLnRyYW5zaXRpb24gPSBob29rczsNCiAgICBzZXRUcmFuc2l0aW9uSG9va3Modm5vZGUuY29tcG9uZW50LnN1YlRyZWUsIGhvb2tzKTsNCiAgfSBlbHNlIGlmICh2bm9kZS5zaGFwZUZsYWcgJiAxMjgpIHsNCiAgICB2bm9kZS5zc0NvbnRlbnQudHJhbnNpdGlvbiA9IGhvb2tzLmNsb25lKHZub2RlLnNzQ29udGVudCk7DQogICAgdm5vZGUuc3NGYWxsYmFjay50cmFuc2l0aW9uID0gaG9va3MuY2xvbmUodm5vZGUuc3NGYWxsYmFjayk7DQogIH0gZWxzZSB7DQogICAgdm5vZGUudHJhbnNpdGlvbiA9IGhvb2tzOw0KICB9DQp9DQpmdW5jdGlvbiBnZXRUcmFuc2l0aW9uUmF3Q2hpbGRyZW4oY2hpbGRyZW4sIGtlZXBDb21tZW50ID0gZmFsc2UsIHBhcmVudEtleSkgew0KICBsZXQgcmV0ID0gW107DQogIGxldCBrZXllZEZyYWdtZW50Q291bnQgPSAwOw0KICBmb3IgKGxldCBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7DQogICAgbGV0IGNoaWxkID0gY2hpbGRyZW5baV07DQogICAgY29uc3Qga2V5ID0gcGFyZW50S2V5ID09IG51bGwgPyBjaGlsZC5rZXkgOiBTdHJpbmcocGFyZW50S2V5KSArIFN0cmluZyhjaGlsZC5rZXkgIT0gbnVsbCA/IGNoaWxkLmtleSA6IGkpOw0KICAgIGlmIChjaGlsZC50eXBlID09PSBGcmFnbWVudCkgew0KICAgICAgaWYgKGNoaWxkLnBhdGNoRmxhZyAmIDEyOCkga2V5ZWRGcmFnbWVudENvdW50Kys7DQogICAgICByZXQgPSByZXQuY29uY2F0KA0KICAgICAgICBnZXRUcmFuc2l0aW9uUmF3Q2hpbGRyZW4oY2hpbGQuY2hpbGRyZW4sIGtlZXBDb21tZW50LCBrZXkpDQogICAgICApOw0KICAgIH0gZWxzZSBpZiAoa2VlcENvbW1lbnQgfHwgY2hpbGQudHlwZSAhPT0gQ29tbWVudCkgew0KICAgICAgcmV0LnB1c2goa2V5ICE9IG51bGwgPyBjbG9uZVZOb2RlKGNoaWxkLCB7IGtleSB9KSA6IGNoaWxkKTsNCiAgICB9DQogIH0NCiAgaWYgKGtleWVkRnJhZ21lbnRDb3VudCA+IDEpIHsNCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJldC5sZW5ndGg7IGkrKykgew0KICAgICAgcmV0W2ldLnBhdGNoRmxhZyA9IC0yOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gcmV0Ow0KfQ0KDQovKiEgI19fTk9fU0lERV9FRkZFQ1RTX18gKi8NCi8vIEBfX05PX1NJREVfRUZGRUNUU19fDQpmdW5jdGlvbiBkZWZpbmVDb21wb25lbnQob3B0aW9ucywgZXh0cmFPcHRpb25zKSB7DQogIHJldHVybiBpc0Z1bmN0aW9uKG9wdGlvbnMpID8gKA0KICAgIC8vICM4MjM2OiBleHRlbmQgY2FsbCBhbmQgb3B0aW9ucy5uYW1lIGFjY2VzcyBhcmUgY29uc2lkZXJlZCBzaWRlLWVmZmVjdHMNCiAgICAvLyBieSBSb2xsdXAsIHNvIHdlIGhhdmUgdG8gd3JhcCBpdCBpbiBhIHB1cmUtYW5ub3RhdGVkIElJRkUuDQogICAgLyogQF9fUFVSRV9fICovICgoKSA9PiBleHRlbmQoeyBuYW1lOiBvcHRpb25zLm5hbWUgfSwgZXh0cmFPcHRpb25zLCB7IHNldHVwOiBvcHRpb25zIH0pKSgpDQogICkgOiBvcHRpb25zOw0KfQ0KDQpmdW5jdGlvbiB1c2VJZCgpIHsNCiAgY29uc3QgaSA9IGdldEN1cnJlbnRJbnN0YW5jZSgpOw0KICBpZiAoaSkgew0KICAgIHJldHVybiAoaS5hcHBDb250ZXh0LmNvbmZpZy5pZFByZWZpeCB8fCAidiIpICsgIi0iICsgaS5pZHNbMF0gKyBpLmlkc1sxXSsrOw0KICB9IGVsc2Ugew0KICAgIHdhcm4kMSgNCiAgICAgIGB1c2VJZCgpIGlzIGNhbGxlZCB3aGVuIHRoZXJlIGlzIG5vIGFjdGl2ZSBjb21wb25lbnQgaW5zdGFuY2UgdG8gYmUgYXNzb2NpYXRlZCB3aXRoLmANCiAgICApOw0KICB9DQogIHJldHVybiAiIjsNCn0NCmZ1bmN0aW9uIG1hcmtBc3luY0JvdW5kYXJ5KGluc3RhbmNlKSB7DQogIGluc3RhbmNlLmlkcyA9IFtpbnN0YW5jZS5pZHNbMF0gKyBpbnN0YW5jZS5pZHNbMl0rKyArICItIiwgMCwgMF07DQp9DQoNCmNvbnN0IGtub3duVGVtcGxhdGVSZWZzID0gLyogQF9fUFVSRV9fICovIG5ldyBXZWFrU2V0KCk7DQpmdW5jdGlvbiB1c2VUZW1wbGF0ZVJlZihrZXkpIHsNCiAgY29uc3QgaSA9IGdldEN1cnJlbnRJbnN0YW5jZSgpOw0KICBjb25zdCByID0gc2hhbGxvd1JlZihudWxsKTsNCiAgaWYgKGkpIHsNCiAgICBjb25zdCByZWZzID0gaS5yZWZzID09PSBFTVBUWV9PQkogPyBpLnJlZnMgPSB7fSA6IGkucmVmczsNCiAgICBsZXQgZGVzYzsNCiAgICBpZiAoKGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHJlZnMsIGtleSkpICYmICFkZXNjLmNvbmZpZ3VyYWJsZSkgew0KICAgICAgd2FybiQxKGB1c2VUZW1wbGF0ZVJlZignJHtrZXl9JykgYWxyZWFkeSBleGlzdHMuYCk7DQogICAgfSBlbHNlIHsNCiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyZWZzLCBrZXksIHsNCiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSwNCiAgICAgICAgZ2V0OiAoKSA9PiByLnZhbHVlLA0KICAgICAgICBzZXQ6ICh2YWwpID0+IHIudmFsdWUgPSB2YWwNCiAgICAgIH0pOw0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICB3YXJuJDEoDQogICAgICBgdXNlVGVtcGxhdGVSZWYoKSBpcyBjYWxsZWQgd2hlbiB0aGVyZSBpcyBubyBhY3RpdmUgY29tcG9uZW50IGluc3RhbmNlIHRvIGJlIGFzc29jaWF0ZWQgd2l0aC5gDQogICAgKTsNCiAgfQ0KICBjb25zdCByZXQgPSByZWFkb25seShyKSA7DQogIHsNCiAgICBrbm93blRlbXBsYXRlUmVmcy5hZGQocmV0KTsNCiAgfQ0KICByZXR1cm4gcmV0Ow0KfQ0KDQpmdW5jdGlvbiBzZXRSZWYocmF3UmVmLCBvbGRSYXdSZWYsIHBhcmVudFN1c3BlbnNlLCB2bm9kZSwgaXNVbm1vdW50ID0gZmFsc2UpIHsNCiAgaWYgKGlzQXJyYXkocmF3UmVmKSkgew0KICAgIHJhd1JlZi5mb3JFYWNoKA0KICAgICAgKHIsIGkpID0+IHNldFJlZigNCiAgICAgICAgciwNCiAgICAgICAgb2xkUmF3UmVmICYmIChpc0FycmF5KG9sZFJhd1JlZikgPyBvbGRSYXdSZWZbaV0gOiBvbGRSYXdSZWYpLA0KICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgdm5vZGUsDQogICAgICAgIGlzVW5tb3VudA0KICAgICAgKQ0KICAgICk7DQogICAgcmV0dXJuOw0KICB9DQogIGlmIChpc0FzeW5jV3JhcHBlcih2bm9kZSkgJiYgIWlzVW5tb3VudCkgew0KICAgIGlmICh2bm9kZS5zaGFwZUZsYWcgJiA1MTIgJiYgdm5vZGUudHlwZS5fX2FzeW5jUmVzb2x2ZWQgJiYgdm5vZGUuY29tcG9uZW50LnN1YlRyZWUuY29tcG9uZW50KSB7DQogICAgICBzZXRSZWYocmF3UmVmLCBvbGRSYXdSZWYsIHBhcmVudFN1c3BlbnNlLCB2bm9kZS5jb21wb25lbnQuc3ViVHJlZSk7DQogICAgfQ0KICAgIHJldHVybjsNCiAgfQ0KICBjb25zdCByZWZWYWx1ZSA9IHZub2RlLnNoYXBlRmxhZyAmIDQgPyBnZXRDb21wb25lbnRQdWJsaWNJbnN0YW5jZSh2bm9kZS5jb21wb25lbnQpIDogdm5vZGUuZWw7DQogIGNvbnN0IHZhbHVlID0gaXNVbm1vdW50ID8gbnVsbCA6IHJlZlZhbHVlOw0KICBjb25zdCB7IGk6IG93bmVyLCByOiByZWYgfSA9IHJhd1JlZjsNCiAgaWYgKCFvd25lcikgew0KICAgIHdhcm4kMSgNCiAgICAgIGBNaXNzaW5nIHJlZiBvd25lciBjb250ZXh0LiByZWYgY2Fubm90IGJlIHVzZWQgb24gaG9pc3RlZCB2bm9kZXMuIEEgdm5vZGUgd2l0aCByZWYgbXVzdCBiZSBjcmVhdGVkIGluc2lkZSB0aGUgcmVuZGVyIGZ1bmN0aW9uLmANCiAgICApOw0KICAgIHJldHVybjsNCiAgfQ0KICBjb25zdCBvbGRSZWYgPSBvbGRSYXdSZWYgJiYgb2xkUmF3UmVmLnI7DQogIGNvbnN0IHJlZnMgPSBvd25lci5yZWZzID09PSBFTVBUWV9PQkogPyBvd25lci5yZWZzID0ge30gOiBvd25lci5yZWZzOw0KICBjb25zdCBzZXR1cFN0YXRlID0gb3duZXIuc2V0dXBTdGF0ZTsNCiAgY29uc3QgcmF3U2V0dXBTdGF0ZSA9IHRvUmF3KHNldHVwU3RhdGUpOw0KICBjb25zdCBjYW5TZXRTZXR1cFJlZiA9IHNldHVwU3RhdGUgPT09IEVNUFRZX09CSiA/ICgpID0+IGZhbHNlIDogKGtleSkgPT4gew0KICAgIHsNCiAgICAgIGlmIChoYXNPd24ocmF3U2V0dXBTdGF0ZSwga2V5KSAmJiAhaXNSZWYocmF3U2V0dXBTdGF0ZVtrZXldKSkgew0KICAgICAgICB3YXJuJDEoDQogICAgICAgICAgYFRlbXBsYXRlIHJlZiAiJHtrZXl9IiB1c2VkIG9uIGEgbm9uLXJlZiB2YWx1ZS4gSXQgd2lsbCBub3Qgd29yayBpbiB0aGUgcHJvZHVjdGlvbiBidWlsZC5gDQogICAgICAgICk7DQogICAgICB9DQogICAgICBpZiAoa25vd25UZW1wbGF0ZVJlZnMuaGFzKHJhd1NldHVwU3RhdGVba2V5XSkpIHsNCiAgICAgICAgcmV0dXJuIGZhbHNlOw0KICAgICAgfQ0KICAgIH0NCiAgICByZXR1cm4gaGFzT3duKHJhd1NldHVwU3RhdGUsIGtleSk7DQogIH07DQogIGlmIChvbGRSZWYgIT0gbnVsbCAmJiBvbGRSZWYgIT09IHJlZikgew0KICAgIGlmIChpc1N0cmluZyhvbGRSZWYpKSB7DQogICAgICByZWZzW29sZFJlZl0gPSBudWxsOw0KICAgICAgaWYgKGNhblNldFNldHVwUmVmKG9sZFJlZikpIHsNCiAgICAgICAgc2V0dXBTdGF0ZVtvbGRSZWZdID0gbnVsbDsNCiAgICAgIH0NCiAgICB9IGVsc2UgaWYgKGlzUmVmKG9sZFJlZikpIHsNCiAgICAgIG9sZFJlZi52YWx1ZSA9IG51bGw7DQogICAgfQ0KICB9DQogIGlmIChpc0Z1bmN0aW9uKHJlZikpIHsNCiAgICBjYWxsV2l0aEVycm9ySGFuZGxpbmcocmVmLCBvd25lciwgMTIsIFt2YWx1ZSwgcmVmc10pOw0KICB9IGVsc2Ugew0KICAgIGNvbnN0IF9pc1N0cmluZyA9IGlzU3RyaW5nKHJlZik7DQogICAgY29uc3QgX2lzUmVmID0gaXNSZWYocmVmKTsNCiAgICBpZiAoX2lzU3RyaW5nIHx8IF9pc1JlZikgew0KICAgICAgY29uc3QgZG9TZXQgPSAoKSA9PiB7DQogICAgICAgIGlmIChyYXdSZWYuZikgew0KICAgICAgICAgIGNvbnN0IGV4aXN0aW5nID0gX2lzU3RyaW5nID8gY2FuU2V0U2V0dXBSZWYocmVmKSA/IHNldHVwU3RhdGVbcmVmXSA6IHJlZnNbcmVmXSA6IHJlZi52YWx1ZTsNCiAgICAgICAgICBpZiAoaXNVbm1vdW50KSB7DQogICAgICAgICAgICBpc0FycmF5KGV4aXN0aW5nKSAmJiByZW1vdmUoZXhpc3RpbmcsIHJlZlZhbHVlKTsNCiAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgaWYgKCFpc0FycmF5KGV4aXN0aW5nKSkgew0KICAgICAgICAgICAgICBpZiAoX2lzU3RyaW5nKSB7DQogICAgICAgICAgICAgICAgcmVmc1tyZWZdID0gW3JlZlZhbHVlXTsNCiAgICAgICAgICAgICAgICBpZiAoY2FuU2V0U2V0dXBSZWYocmVmKSkgew0KICAgICAgICAgICAgICAgICAgc2V0dXBTdGF0ZVtyZWZdID0gcmVmc1tyZWZdOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICByZWYudmFsdWUgPSBbcmVmVmFsdWVdOw0KICAgICAgICAgICAgICAgIGlmIChyYXdSZWYuaykgcmVmc1tyYXdSZWYua10gPSByZWYudmFsdWU7DQogICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0gZWxzZSBpZiAoIWV4aXN0aW5nLmluY2x1ZGVzKHJlZlZhbHVlKSkgew0KICAgICAgICAgICAgICBleGlzdGluZy5wdXNoKHJlZlZhbHVlKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICB9DQogICAgICAgIH0gZWxzZSBpZiAoX2lzU3RyaW5nKSB7DQogICAgICAgICAgcmVmc1tyZWZdID0gdmFsdWU7DQogICAgICAgICAgaWYgKGNhblNldFNldHVwUmVmKHJlZikpIHsNCiAgICAgICAgICAgIHNldHVwU3RhdGVbcmVmXSA9IHZhbHVlOw0KICAgICAgICAgIH0NCiAgICAgICAgfSBlbHNlIGlmIChfaXNSZWYpIHsNCiAgICAgICAgICByZWYudmFsdWUgPSB2YWx1ZTsNCiAgICAgICAgICBpZiAocmF3UmVmLmspIHJlZnNbcmF3UmVmLmtdID0gdmFsdWU7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgd2FybiQxKCJJbnZhbGlkIHRlbXBsYXRlIHJlZiB0eXBlOiIsIHJlZiwgYCgke3R5cGVvZiByZWZ9KWApOw0KICAgICAgICB9DQogICAgICB9Ow0KICAgICAgaWYgKHZhbHVlKSB7DQogICAgICAgIGRvU2V0LmlkID0gLTE7DQogICAgICAgIHF1ZXVlUG9zdFJlbmRlckVmZmVjdChkb1NldCwgcGFyZW50U3VzcGVuc2UpOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgZG9TZXQoKTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgd2FybiQxKCJJbnZhbGlkIHRlbXBsYXRlIHJlZiB0eXBlOiIsIHJlZiwgYCgke3R5cGVvZiByZWZ9KWApOw0KICAgIH0NCiAgfQ0KfQ0KDQpsZXQgaGFzTG9nZ2VkTWlzbWF0Y2hFcnJvciA9IGZhbHNlOw0KY29uc3QgbG9nTWlzbWF0Y2hFcnJvciA9ICgpID0+IHsNCiAgaWYgKGhhc0xvZ2dlZE1pc21hdGNoRXJyb3IpIHsNCiAgICByZXR1cm47DQogIH0NCiAgY29uc29sZS5lcnJvcigiSHlkcmF0aW9uIGNvbXBsZXRlZCBidXQgY29udGFpbnMgbWlzbWF0Y2hlcy4iKTsNCiAgaGFzTG9nZ2VkTWlzbWF0Y2hFcnJvciA9IHRydWU7DQp9Ow0KY29uc3QgaXNTVkdDb250YWluZXIgPSAoY29udGFpbmVyKSA9PiBjb250YWluZXIubmFtZXNwYWNlVVJJLmluY2x1ZGVzKCJzdmciKSAmJiBjb250YWluZXIudGFnTmFtZSAhPT0gImZvcmVpZ25PYmplY3QiOw0KY29uc3QgaXNNYXRoTUxDb250YWluZXIgPSAoY29udGFpbmVyKSA9PiBjb250YWluZXIubmFtZXNwYWNlVVJJLmluY2x1ZGVzKCJNYXRoTUwiKTsNCmNvbnN0IGdldENvbnRhaW5lclR5cGUgPSAoY29udGFpbmVyKSA9PiB7DQogIGlmIChjb250YWluZXIubm9kZVR5cGUgIT09IDEpIHJldHVybiB2b2lkIDA7DQogIGlmIChpc1NWR0NvbnRhaW5lcihjb250YWluZXIpKSByZXR1cm4gInN2ZyI7DQogIGlmIChpc01hdGhNTENvbnRhaW5lcihjb250YWluZXIpKSByZXR1cm4gIm1hdGhtbCI7DQogIHJldHVybiB2b2lkIDA7DQp9Ow0KY29uc3QgaXNDb21tZW50ID0gKG5vZGUpID0+IG5vZGUubm9kZVR5cGUgPT09IDg7DQpmdW5jdGlvbiBjcmVhdGVIeWRyYXRpb25GdW5jdGlvbnMocmVuZGVyZXJJbnRlcm5hbHMpIHsNCiAgY29uc3Qgew0KICAgIG10OiBtb3VudENvbXBvbmVudCwNCiAgICBwOiBwYXRjaCwNCiAgICBvOiB7DQogICAgICBwYXRjaFByb3AsDQogICAgICBjcmVhdGVUZXh0LA0KICAgICAgbmV4dFNpYmxpbmcsDQogICAgICBwYXJlbnROb2RlLA0KICAgICAgcmVtb3ZlLA0KICAgICAgaW5zZXJ0LA0KICAgICAgY3JlYXRlQ29tbWVudA0KICAgIH0NCiAgfSA9IHJlbmRlcmVySW50ZXJuYWxzOw0KICBjb25zdCBoeWRyYXRlID0gKHZub2RlLCBjb250YWluZXIpID0+IHsNCiAgICBpZiAoIWNvbnRhaW5lci5oYXNDaGlsZE5vZGVzKCkpIHsNCiAgICAgIHdhcm4kMSgNCiAgICAgICAgYEF0dGVtcHRpbmcgdG8gaHlkcmF0ZSBleGlzdGluZyBtYXJrdXAgYnV0IGNvbnRhaW5lciBpcyBlbXB0eS4gUGVyZm9ybWluZyBmdWxsIG1vdW50IGluc3RlYWQuYA0KICAgICAgKTsNCiAgICAgIHBhdGNoKG51bGwsIHZub2RlLCBjb250YWluZXIpOw0KICAgICAgZmx1c2hQb3N0Rmx1c2hDYnMoKTsNCiAgICAgIGNvbnRhaW5lci5fdm5vZGUgPSB2bm9kZTsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgaHlkcmF0ZU5vZGUoY29udGFpbmVyLmZpcnN0Q2hpbGQsIHZub2RlLCBudWxsLCBudWxsLCBudWxsKTsNCiAgICBmbHVzaFBvc3RGbHVzaENicygpOw0KICAgIGNvbnRhaW5lci5fdm5vZGUgPSB2bm9kZTsNCiAgfTsNCiAgY29uc3QgaHlkcmF0ZU5vZGUgPSAobm9kZSwgdm5vZGUsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIHNsb3RTY29wZUlkcywgb3B0aW1pemVkID0gZmFsc2UpID0+IHsNCiAgICBvcHRpbWl6ZWQgPSBvcHRpbWl6ZWQgfHwgISF2bm9kZS5keW5hbWljQ2hpbGRyZW47DQogICAgY29uc3QgaXNGcmFnbWVudFN0YXJ0ID0gaXNDb21tZW50KG5vZGUpICYmIG5vZGUuZGF0YSA9PT0gIlsiOw0KICAgIGNvbnN0IG9uTWlzbWF0Y2ggPSAoKSA9PiBoYW5kbGVNaXNtYXRjaCgNCiAgICAgIG5vZGUsDQogICAgICB2bm9kZSwNCiAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgaXNGcmFnbWVudFN0YXJ0DQogICAgKTsNCiAgICBjb25zdCB7IHR5cGUsIHJlZiwgc2hhcGVGbGFnLCBwYXRjaEZsYWcgfSA9IHZub2RlOw0KICAgIGxldCBkb21UeXBlID0gbm9kZS5ub2RlVHlwZTsNCiAgICB2bm9kZS5lbCA9IG5vZGU7DQogICAgew0KICAgICAgZGVmKG5vZGUsICJfX3Zub2RlIiwgdm5vZGUsIHRydWUpOw0KICAgICAgZGVmKG5vZGUsICJfX3Z1ZVBhcmVudENvbXBvbmVudCIsIHBhcmVudENvbXBvbmVudCwgdHJ1ZSk7DQogICAgfQ0KICAgIGlmIChwYXRjaEZsYWcgPT09IC0yKSB7DQogICAgICBvcHRpbWl6ZWQgPSBmYWxzZTsNCiAgICAgIHZub2RlLmR5bmFtaWNDaGlsZHJlbiA9IG51bGw7DQogICAgfQ0KICAgIGxldCBuZXh0Tm9kZSA9IG51bGw7DQogICAgc3dpdGNoICh0eXBlKSB7DQogICAgICBjYXNlIFRleHQ6DQogICAgICAgIGlmIChkb21UeXBlICE9PSAzKSB7DQogICAgICAgICAgaWYgKHZub2RlLmNoaWxkcmVuID09PSAiIikgew0KICAgICAgICAgICAgaW5zZXJ0KHZub2RlLmVsID0gY3JlYXRlVGV4dCgiIiksIHBhcmVudE5vZGUobm9kZSksIG5vZGUpOw0KICAgICAgICAgICAgbmV4dE5vZGUgPSBub2RlOw0KICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBuZXh0Tm9kZSA9IG9uTWlzbWF0Y2goKTsNCiAgICAgICAgICB9DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgaWYgKG5vZGUuZGF0YSAhPT0gdm5vZGUuY2hpbGRyZW4pIHsNCiAgICAgICAgICAgIHdhcm4kMSgNCiAgICAgICAgICAgICAgYEh5ZHJhdGlvbiB0ZXh0IG1pc21hdGNoIGluYCwNCiAgICAgICAgICAgICAgbm9kZS5wYXJlbnROb2RlLA0KICAgICAgICAgICAgICBgDQogIC0gcmVuZGVyZWQgb24gc2VydmVyOiAke0pTT04uc3RyaW5naWZ5KA0KICAgICAgICAgICAgICAgIG5vZGUuZGF0YQ0KICAgICAgICAgICAgICApfQ0KICAtIGV4cGVjdGVkIG9uIGNsaWVudDogJHtKU09OLnN0cmluZ2lmeSh2bm9kZS5jaGlsZHJlbil9YA0KICAgICAgICAgICAgKTsNCiAgICAgICAgICAgIGxvZ01pc21hdGNoRXJyb3IoKTsNCiAgICAgICAgICAgIG5vZGUuZGF0YSA9IHZub2RlLmNoaWxkcmVuOw0KICAgICAgICAgIH0NCiAgICAgICAgICBuZXh0Tm9kZSA9IG5leHRTaWJsaW5nKG5vZGUpOw0KICAgICAgICB9DQogICAgICAgIGJyZWFrOw0KICAgICAgY2FzZSBDb21tZW50Og0KICAgICAgICBpZiAoaXNUZW1wbGF0ZU5vZGUobm9kZSkpIHsNCiAgICAgICAgICBuZXh0Tm9kZSA9IG5leHRTaWJsaW5nKG5vZGUpOw0KICAgICAgICAgIHJlcGxhY2VOb2RlKA0KICAgICAgICAgICAgdm5vZGUuZWwgPSBub2RlLmNvbnRlbnQuZmlyc3RDaGlsZCwNCiAgICAgICAgICAgIG5vZGUsDQogICAgICAgICAgICBwYXJlbnRDb21wb25lbnQNCiAgICAgICAgICApOw0KICAgICAgICB9IGVsc2UgaWYgKGRvbVR5cGUgIT09IDggfHwgaXNGcmFnbWVudFN0YXJ0KSB7DQogICAgICAgICAgbmV4dE5vZGUgPSBvbk1pc21hdGNoKCk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgbmV4dE5vZGUgPSBuZXh0U2libGluZyhub2RlKTsNCiAgICAgICAgfQ0KICAgICAgICBicmVhazsNCiAgICAgIGNhc2UgU3RhdGljOg0KICAgICAgICBpZiAoaXNGcmFnbWVudFN0YXJ0KSB7DQogICAgICAgICAgbm9kZSA9IG5leHRTaWJsaW5nKG5vZGUpOw0KICAgICAgICAgIGRvbVR5cGUgPSBub2RlLm5vZGVUeXBlOw0KICAgICAgICB9DQogICAgICAgIGlmIChkb21UeXBlID09PSAxIHx8IGRvbVR5cGUgPT09IDMpIHsNCiAgICAgICAgICBuZXh0Tm9kZSA9IG5vZGU7DQogICAgICAgICAgY29uc3QgbmVlZFRvQWRvcHRDb250ZW50ID0gIXZub2RlLmNoaWxkcmVuLmxlbmd0aDsNCiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZub2RlLnN0YXRpY0NvdW50OyBpKyspIHsNCiAgICAgICAgICAgIGlmIChuZWVkVG9BZG9wdENvbnRlbnQpDQogICAgICAgICAgICAgIHZub2RlLmNoaWxkcmVuICs9IG5leHROb2RlLm5vZGVUeXBlID09PSAxID8gbmV4dE5vZGUub3V0ZXJIVE1MIDogbmV4dE5vZGUuZGF0YTsNCiAgICAgICAgICAgIGlmIChpID09PSB2bm9kZS5zdGF0aWNDb3VudCAtIDEpIHsNCiAgICAgICAgICAgICAgdm5vZGUuYW5jaG9yID0gbmV4dE5vZGU7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBuZXh0Tm9kZSA9IG5leHRTaWJsaW5nKG5leHROb2RlKTsNCiAgICAgICAgICB9DQogICAgICAgICAgcmV0dXJuIGlzRnJhZ21lbnRTdGFydCA/IG5leHRTaWJsaW5nKG5leHROb2RlKSA6IG5leHROb2RlOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIG9uTWlzbWF0Y2goKTsNCiAgICAgICAgfQ0KICAgICAgICBicmVhazsNCiAgICAgIGNhc2UgRnJhZ21lbnQ6DQogICAgICAgIGlmICghaXNGcmFnbWVudFN0YXJ0KSB7DQogICAgICAgICAgbmV4dE5vZGUgPSBvbk1pc21hdGNoKCk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgbmV4dE5vZGUgPSBoeWRyYXRlRnJhZ21lbnQoDQogICAgICAgICAgICBub2RlLA0KICAgICAgICAgICAgdm5vZGUsDQogICAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgICAgYnJlYWs7DQogICAgICBkZWZhdWx0Og0KICAgICAgICBpZiAoc2hhcGVGbGFnICYgMSkgew0KICAgICAgICAgIGlmICgoZG9tVHlwZSAhPT0gMSB8fCB2bm9kZS50eXBlLnRvTG93ZXJDYXNlKCkgIT09IG5vZGUudGFnTmFtZS50b0xvd2VyQ2FzZSgpKSAmJiAhaXNUZW1wbGF0ZU5vZGUobm9kZSkpIHsNCiAgICAgICAgICAgIG5leHROb2RlID0gb25NaXNtYXRjaCgpOw0KICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBuZXh0Tm9kZSA9IGh5ZHJhdGVFbGVtZW50KA0KICAgICAgICAgICAgICBub2RlLA0KICAgICAgICAgICAgICB2bm9kZSwNCiAgICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgICAgICk7DQogICAgICAgICAgfQ0KICAgICAgICB9IGVsc2UgaWYgKHNoYXBlRmxhZyAmIDYpIHsNCiAgICAgICAgICB2bm9kZS5zbG90U2NvcGVJZHMgPSBzbG90U2NvcGVJZHM7DQogICAgICAgICAgY29uc3QgY29udGFpbmVyID0gcGFyZW50Tm9kZShub2RlKTsNCiAgICAgICAgICBpZiAoaXNGcmFnbWVudFN0YXJ0KSB7DQogICAgICAgICAgICBuZXh0Tm9kZSA9IGxvY2F0ZUNsb3NpbmdBbmNob3Iobm9kZSk7DQogICAgICAgICAgfSBlbHNlIGlmIChpc0NvbW1lbnQobm9kZSkgJiYgbm9kZS5kYXRhID09PSAidGVsZXBvcnQgc3RhcnQiKSB7DQogICAgICAgICAgICBuZXh0Tm9kZSA9IGxvY2F0ZUNsb3NpbmdBbmNob3Iobm9kZSwgbm9kZS5kYXRhLCAidGVsZXBvcnQgZW5kIik7DQogICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIG5leHROb2RlID0gbmV4dFNpYmxpbmcobm9kZSk7DQogICAgICAgICAgfQ0KICAgICAgICAgIG1vdW50Q29tcG9uZW50KA0KICAgICAgICAgICAgdm5vZGUsDQogICAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgICBudWxsLA0KICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgICBnZXRDb250YWluZXJUeXBlKGNvbnRhaW5lciksDQogICAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgICApOw0KICAgICAgICAgIGlmIChpc0FzeW5jV3JhcHBlcih2bm9kZSkgJiYgIXZub2RlLnR5cGUuX19hc3luY1Jlc29sdmVkKSB7DQogICAgICAgICAgICBsZXQgc3ViVHJlZTsNCiAgICAgICAgICAgIGlmIChpc0ZyYWdtZW50U3RhcnQpIHsNCiAgICAgICAgICAgICAgc3ViVHJlZSA9IGNyZWF0ZVZOb2RlKEZyYWdtZW50KTsNCiAgICAgICAgICAgICAgc3ViVHJlZS5hbmNob3IgPSBuZXh0Tm9kZSA/IG5leHROb2RlLnByZXZpb3VzU2libGluZyA6IGNvbnRhaW5lci5sYXN0Q2hpbGQ7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICBzdWJUcmVlID0gbm9kZS5ub2RlVHlwZSA9PT0gMyA/IGNyZWF0ZVRleHRWTm9kZSgiIikgOiBjcmVhdGVWTm9kZSgiZGl2Iik7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBzdWJUcmVlLmVsID0gbm9kZTsNCiAgICAgICAgICAgIHZub2RlLmNvbXBvbmVudC5zdWJUcmVlID0gc3ViVHJlZTsNCiAgICAgICAgICB9DQogICAgICAgIH0gZWxzZSBpZiAoc2hhcGVGbGFnICYgNjQpIHsNCiAgICAgICAgICBpZiAoZG9tVHlwZSAhPT0gOCkgew0KICAgICAgICAgICAgbmV4dE5vZGUgPSBvbk1pc21hdGNoKCk7DQogICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIG5leHROb2RlID0gdm5vZGUudHlwZS5oeWRyYXRlKA0KICAgICAgICAgICAgICBub2RlLA0KICAgICAgICAgICAgICB2bm9kZSwNCiAgICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgICAgICBvcHRpbWl6ZWQsDQogICAgICAgICAgICAgIHJlbmRlcmVySW50ZXJuYWxzLA0KICAgICAgICAgICAgICBoeWRyYXRlQ2hpbGRyZW4NCiAgICAgICAgICAgICk7DQogICAgICAgICAgfQ0KICAgICAgICB9IGVsc2UgaWYgKHNoYXBlRmxhZyAmIDEyOCkgew0KICAgICAgICAgIG5leHROb2RlID0gdm5vZGUudHlwZS5oeWRyYXRlKA0KICAgICAgICAgICAgbm9kZSwNCiAgICAgICAgICAgIHZub2RlLA0KICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgICBnZXRDb250YWluZXJUeXBlKHBhcmVudE5vZGUobm9kZSkpLA0KICAgICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgICAgb3B0aW1pemVkLA0KICAgICAgICAgICAgcmVuZGVyZXJJbnRlcm5hbHMsDQogICAgICAgICAgICBoeWRyYXRlTm9kZQ0KICAgICAgICAgICk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgd2FybiQxKCJJbnZhbGlkIEhvc3RWTm9kZSB0eXBlOiIsIHR5cGUsIGAoJHt0eXBlb2YgdHlwZX0pYCk7DQogICAgICAgIH0NCiAgICB9DQogICAgaWYgKHJlZiAhPSBudWxsKSB7DQogICAgICBzZXRSZWYocmVmLCBudWxsLCBwYXJlbnRTdXNwZW5zZSwgdm5vZGUpOw0KICAgIH0NCiAgICByZXR1cm4gbmV4dE5vZGU7DQogIH07DQogIGNvbnN0IGh5ZHJhdGVFbGVtZW50ID0gKGVsLCB2bm9kZSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQpID0+IHsNCiAgICBvcHRpbWl6ZWQgPSBvcHRpbWl6ZWQgfHwgISF2bm9kZS5keW5hbWljQ2hpbGRyZW47DQogICAgY29uc3QgeyB0eXBlLCBwcm9wcywgcGF0Y2hGbGFnLCBzaGFwZUZsYWcsIGRpcnMsIHRyYW5zaXRpb24gfSA9IHZub2RlOw0KICAgIGNvbnN0IGZvcmNlUGF0Y2ggPSB0eXBlID09PSAiaW5wdXQiIHx8IHR5cGUgPT09ICJvcHRpb24iOw0KICAgIHsNCiAgICAgIGlmIChkaXJzKSB7DQogICAgICAgIGludm9rZURpcmVjdGl2ZUhvb2sodm5vZGUsIG51bGwsIHBhcmVudENvbXBvbmVudCwgImNyZWF0ZWQiKTsNCiAgICAgIH0NCiAgICAgIGxldCBuZWVkQ2FsbFRyYW5zaXRpb25Ib29rcyA9IGZhbHNlOw0KICAgICAgaWYgKGlzVGVtcGxhdGVOb2RlKGVsKSkgew0KICAgICAgICBuZWVkQ2FsbFRyYW5zaXRpb25Ib29rcyA9IG5lZWRUcmFuc2l0aW9uKA0KICAgICAgICAgIG51bGwsDQogICAgICAgICAgLy8gbm8gbmVlZCBjaGVjayBwYXJlbnRTdXNwZW5zZSBpbiBoeWRyYXRpb24NCiAgICAgICAgICB0cmFuc2l0aW9uDQogICAgICAgICkgJiYgcGFyZW50Q29tcG9uZW50ICYmIHBhcmVudENvbXBvbmVudC52bm9kZS5wcm9wcyAmJiBwYXJlbnRDb21wb25lbnQudm5vZGUucHJvcHMuYXBwZWFyOw0KICAgICAgICBjb25zdCBjb250ZW50ID0gZWwuY29udGVudC5maXJzdENoaWxkOw0KICAgICAgICBpZiAobmVlZENhbGxUcmFuc2l0aW9uSG9va3MpIHsNCiAgICAgICAgICBjb25zdCBjbHMgPSBjb250ZW50LmdldEF0dHJpYnV0ZSgiY2xhc3MiKTsNCiAgICAgICAgICBpZiAoY2xzKSBjb250ZW50LiRjbHMgPSBjbHM7DQogICAgICAgICAgdHJhbnNpdGlvbi5iZWZvcmVFbnRlcihjb250ZW50KTsNCiAgICAgICAgfQ0KICAgICAgICByZXBsYWNlTm9kZShjb250ZW50LCBlbCwgcGFyZW50Q29tcG9uZW50KTsNCiAgICAgICAgdm5vZGUuZWwgPSBlbCA9IGNvbnRlbnQ7DQogICAgICB9DQogICAgICBpZiAoc2hhcGVGbGFnICYgMTYgJiYgLy8gc2tpcCBpZiBlbGVtZW50IGhhcyBpbm5lckhUTUwgLyB0ZXh0Q29udGVudA0KICAgICAgIShwcm9wcyAmJiAocHJvcHMuaW5uZXJIVE1MIHx8IHByb3BzLnRleHRDb250ZW50KSkpIHsNCiAgICAgICAgbGV0IG5leHQgPSBoeWRyYXRlQ2hpbGRyZW4oDQogICAgICAgICAgZWwuZmlyc3RDaGlsZCwNCiAgICAgICAgICB2bm9kZSwNCiAgICAgICAgICBlbCwNCiAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICApOw0KICAgICAgICBsZXQgaGFzV2FybmVkID0gZmFsc2U7DQogICAgICAgIHdoaWxlIChuZXh0KSB7DQogICAgICAgICAgaWYgKCFpc01pc21hdGNoQWxsb3dlZChlbCwgMSAvKiBDSElMRFJFTiAqLykpIHsNCiAgICAgICAgICAgIGlmICghaGFzV2FybmVkKSB7DQogICAgICAgICAgICAgIHdhcm4kMSgNCiAgICAgICAgICAgICAgICBgSHlkcmF0aW9uIGNoaWxkcmVuIG1pc21hdGNoIG9uYCwNCiAgICAgICAgICAgICAgICBlbCwNCiAgICAgICAgICAgICAgICBgDQpTZXJ2ZXIgcmVuZGVyZWQgZWxlbWVudCBjb250YWlucyBtb3JlIGNoaWxkIG5vZGVzIHRoYW4gY2xpZW50IHZkb20uYA0KICAgICAgICAgICAgICApOw0KICAgICAgICAgICAgICBoYXNXYXJuZWQgPSB0cnVlOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgbG9nTWlzbWF0Y2hFcnJvcigpOw0KICAgICAgICAgIH0NCiAgICAgICAgICBjb25zdCBjdXIgPSBuZXh0Ow0KICAgICAgICAgIG5leHQgPSBuZXh0Lm5leHRTaWJsaW5nOw0KICAgICAgICAgIHJlbW92ZShjdXIpOw0KICAgICAgICB9DQogICAgICB9IGVsc2UgaWYgKHNoYXBlRmxhZyAmIDgpIHsNCiAgICAgICAgbGV0IGNsaWVudFRleHQgPSB2bm9kZS5jaGlsZHJlbjsNCiAgICAgICAgaWYgKGNsaWVudFRleHRbMF0gPT09ICJcbiIgJiYgKGVsLnRhZ05hbWUgPT09ICJQUkUiIHx8IGVsLnRhZ05hbWUgPT09ICJURVhUQVJFQSIpKSB7DQogICAgICAgICAgY2xpZW50VGV4dCA9IGNsaWVudFRleHQuc2xpY2UoMSk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKGVsLnRleHRDb250ZW50ICE9PSBjbGllbnRUZXh0KSB7DQogICAgICAgICAgaWYgKCFpc01pc21hdGNoQWxsb3dlZChlbCwgMCAvKiBURVhUICovKSkgew0KICAgICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgICBgSHlkcmF0aW9uIHRleHQgY29udGVudCBtaXNtYXRjaCBvbmAsDQogICAgICAgICAgICAgIGVsLA0KICAgICAgICAgICAgICBgDQogIC0gcmVuZGVyZWQgb24gc2VydmVyOiAke2VsLnRleHRDb250ZW50fQ0KICAtIGV4cGVjdGVkIG9uIGNsaWVudDogJHt2bm9kZS5jaGlsZHJlbn1gDQogICAgICAgICAgICApOw0KICAgICAgICAgICAgbG9nTWlzbWF0Y2hFcnJvcigpOw0KICAgICAgICAgIH0NCiAgICAgICAgICBlbC50ZXh0Q29udGVudCA9IHZub2RlLmNoaWxkcmVuOw0KICAgICAgICB9DQogICAgICB9DQogICAgICBpZiAocHJvcHMpIHsNCiAgICAgICAgew0KICAgICAgICAgIGNvbnN0IGlzQ3VzdG9tRWxlbWVudCA9IGVsLnRhZ05hbWUuaW5jbHVkZXMoIi0iKTsNCiAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBwcm9wcykgew0KICAgICAgICAgICAgaWYgKC8vICMxMTE4OSBza2lwIGlmIHRoaXMgbm9kZSBoYXMgZGlyZWN0aXZlcyB0aGF0IGhhdmUgY3JlYXRlZCBob29rcw0KICAgICAgICAgICAgLy8gYXMgaXQgY291bGQgaGF2ZSBtdXRhdGVkIHRoZSBET00gaW4gYW55IHBvc3NpYmxlIHdheQ0KICAgICAgICAgICAgIShkaXJzICYmIGRpcnMuc29tZSgoZCkgPT4gZC5kaXIuY3JlYXRlZCkpICYmIHByb3BIYXNNaXNtYXRjaChlbCwga2V5LCBwcm9wc1trZXldLCB2bm9kZSwgcGFyZW50Q29tcG9uZW50KSkgew0KICAgICAgICAgICAgICBsb2dNaXNtYXRjaEVycm9yKCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZiAoZm9yY2VQYXRjaCAmJiAoa2V5LmVuZHNXaXRoKCJ2YWx1ZSIpIHx8IGtleSA9PT0gImluZGV0ZXJtaW5hdGUiKSB8fCBpc09uKGtleSkgJiYgIWlzUmVzZXJ2ZWRQcm9wKGtleSkgfHwgLy8gZm9yY2UgaHlkcmF0ZSB2LWJpbmQgd2l0aCAucHJvcCBtb2RpZmllcnMNCiAgICAgICAgICAgIGtleVswXSA9PT0gIi4iIHx8IGlzQ3VzdG9tRWxlbWVudCkgew0KICAgICAgICAgICAgICBwYXRjaFByb3AoZWwsIGtleSwgbnVsbCwgcHJvcHNba2V5XSwgdm9pZCAwLCBwYXJlbnRDb21wb25lbnQpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgbGV0IHZub2RlSG9va3M7DQogICAgICBpZiAodm5vZGVIb29rcyA9IHByb3BzICYmIHByb3BzLm9uVm5vZGVCZWZvcmVNb3VudCkgew0KICAgICAgICBpbnZva2VWTm9kZUhvb2sodm5vZGVIb29rcywgcGFyZW50Q29tcG9uZW50LCB2bm9kZSk7DQogICAgICB9DQogICAgICBpZiAoZGlycykgew0KICAgICAgICBpbnZva2VEaXJlY3RpdmVIb29rKHZub2RlLCBudWxsLCBwYXJlbnRDb21wb25lbnQsICJiZWZvcmVNb3VudCIpOw0KICAgICAgfQ0KICAgICAgaWYgKCh2bm9kZUhvb2tzID0gcHJvcHMgJiYgcHJvcHMub25Wbm9kZU1vdW50ZWQpIHx8IGRpcnMgfHwgbmVlZENhbGxUcmFuc2l0aW9uSG9va3MpIHsNCiAgICAgICAgcXVldWVFZmZlY3RXaXRoU3VzcGVuc2UoKCkgPT4gew0KICAgICAgICAgIHZub2RlSG9va3MgJiYgaW52b2tlVk5vZGVIb29rKHZub2RlSG9va3MsIHBhcmVudENvbXBvbmVudCwgdm5vZGUpOw0KICAgICAgICAgIG5lZWRDYWxsVHJhbnNpdGlvbkhvb2tzICYmIHRyYW5zaXRpb24uZW50ZXIoZWwpOw0KICAgICAgICAgIGRpcnMgJiYgaW52b2tlRGlyZWN0aXZlSG9vayh2bm9kZSwgbnVsbCwgcGFyZW50Q29tcG9uZW50LCAibW91bnRlZCIpOw0KICAgICAgICB9LCBwYXJlbnRTdXNwZW5zZSk7DQogICAgICB9DQogICAgfQ0KICAgIHJldHVybiBlbC5uZXh0U2libGluZzsNCiAgfTsNCiAgY29uc3QgaHlkcmF0ZUNoaWxkcmVuID0gKG5vZGUsIHBhcmVudFZOb2RlLCBjb250YWluZXIsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIHNsb3RTY29wZUlkcywgb3B0aW1pemVkKSA9PiB7DQogICAgb3B0aW1pemVkID0gb3B0aW1pemVkIHx8ICEhcGFyZW50Vk5vZGUuZHluYW1pY0NoaWxkcmVuOw0KICAgIGNvbnN0IGNoaWxkcmVuID0gcGFyZW50Vk5vZGUuY2hpbGRyZW47DQogICAgY29uc3QgbCA9IGNoaWxkcmVuLmxlbmd0aDsNCiAgICBsZXQgaGFzV2FybmVkID0gZmFsc2U7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsOyBpKyspIHsNCiAgICAgIGNvbnN0IHZub2RlID0gb3B0aW1pemVkID8gY2hpbGRyZW5baV0gOiBjaGlsZHJlbltpXSA9IG5vcm1hbGl6ZVZOb2RlKGNoaWxkcmVuW2ldKTsNCiAgICAgIGNvbnN0IGlzVGV4dCA9IHZub2RlLnR5cGUgPT09IFRleHQ7DQogICAgICBpZiAobm9kZSkgew0KICAgICAgICBpZiAoaXNUZXh0ICYmICFvcHRpbWl6ZWQpIHsNCiAgICAgICAgICBpZiAoaSArIDEgPCBsICYmIG5vcm1hbGl6ZVZOb2RlKGNoaWxkcmVuW2kgKyAxXSkudHlwZSA9PT0gVGV4dCkgew0KICAgICAgICAgICAgaW5zZXJ0KA0KICAgICAgICAgICAgICBjcmVhdGVUZXh0KA0KICAgICAgICAgICAgICAgIG5vZGUuZGF0YS5zbGljZSh2bm9kZS5jaGlsZHJlbi5sZW5ndGgpDQogICAgICAgICAgICAgICksDQogICAgICAgICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgICAgICAgbmV4dFNpYmxpbmcobm9kZSkNCiAgICAgICAgICAgICk7DQogICAgICAgICAgICBub2RlLmRhdGEgPSB2bm9kZS5jaGlsZHJlbjsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgbm9kZSA9IGh5ZHJhdGVOb2RlKA0KICAgICAgICAgIG5vZGUsDQogICAgICAgICAgdm5vZGUsDQogICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgKTsNCiAgICAgIH0gZWxzZSBpZiAoaXNUZXh0ICYmICF2bm9kZS5jaGlsZHJlbikgew0KICAgICAgICBpbnNlcnQodm5vZGUuZWwgPSBjcmVhdGVUZXh0KCIiKSwgY29udGFpbmVyKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGlmICghaXNNaXNtYXRjaEFsbG93ZWQoY29udGFpbmVyLCAxIC8qIENISUxEUkVOICovKSkgew0KICAgICAgICAgIGlmICghaGFzV2FybmVkKSB7DQogICAgICAgICAgICB3YXJuJDEoDQogICAgICAgICAgICAgIGBIeWRyYXRpb24gY2hpbGRyZW4gbWlzbWF0Y2ggb25gLA0KICAgICAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgICAgIGANClNlcnZlciByZW5kZXJlZCBlbGVtZW50IGNvbnRhaW5zIGZld2VyIGNoaWxkIG5vZGVzIHRoYW4gY2xpZW50IHZkb20uYA0KICAgICAgICAgICAgKTsNCiAgICAgICAgICAgIGhhc1dhcm5lZCA9IHRydWU7DQogICAgICAgICAgfQ0KICAgICAgICAgIGxvZ01pc21hdGNoRXJyb3IoKTsNCiAgICAgICAgfQ0KICAgICAgICBwYXRjaCgNCiAgICAgICAgICBudWxsLA0KICAgICAgICAgIHZub2RlLA0KICAgICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgICBudWxsLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBnZXRDb250YWluZXJUeXBlKGNvbnRhaW5lciksDQogICAgICAgICAgc2xvdFNjb3BlSWRzDQogICAgICAgICk7DQogICAgICB9DQogICAgfQ0KICAgIHJldHVybiBub2RlOw0KICB9Ow0KICBjb25zdCBoeWRyYXRlRnJhZ21lbnQgPSAobm9kZSwgdm5vZGUsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIHNsb3RTY29wZUlkcywgb3B0aW1pemVkKSA9PiB7DQogICAgY29uc3QgeyBzbG90U2NvcGVJZHM6IGZyYWdtZW50U2xvdFNjb3BlSWRzIH0gPSB2bm9kZTsNCiAgICBpZiAoZnJhZ21lbnRTbG90U2NvcGVJZHMpIHsNCiAgICAgIHNsb3RTY29wZUlkcyA9IHNsb3RTY29wZUlkcyA/IHNsb3RTY29wZUlkcy5jb25jYXQoZnJhZ21lbnRTbG90U2NvcGVJZHMpIDogZnJhZ21lbnRTbG90U2NvcGVJZHM7DQogICAgfQ0KICAgIGNvbnN0IGNvbnRhaW5lciA9IHBhcmVudE5vZGUobm9kZSk7DQogICAgY29uc3QgbmV4dCA9IGh5ZHJhdGVDaGlsZHJlbigNCiAgICAgIG5leHRTaWJsaW5nKG5vZGUpLA0KICAgICAgdm5vZGUsDQogICAgICBjb250YWluZXIsDQogICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgIG9wdGltaXplZA0KICAgICk7DQogICAgaWYgKG5leHQgJiYgaXNDb21tZW50KG5leHQpICYmIG5leHQuZGF0YSA9PT0gIl0iKSB7DQogICAgICByZXR1cm4gbmV4dFNpYmxpbmcodm5vZGUuYW5jaG9yID0gbmV4dCk7DQogICAgfSBlbHNlIHsNCiAgICAgIGxvZ01pc21hdGNoRXJyb3IoKTsNCiAgICAgIGluc2VydCh2bm9kZS5hbmNob3IgPSBjcmVhdGVDb21tZW50KGBdYCksIGNvbnRhaW5lciwgbmV4dCk7DQogICAgICByZXR1cm4gbmV4dDsNCiAgICB9DQogIH07DQogIGNvbnN0IGhhbmRsZU1pc21hdGNoID0gKG5vZGUsIHZub2RlLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBzbG90U2NvcGVJZHMsIGlzRnJhZ21lbnQpID0+IHsNCiAgICBpZiAoIWlzTWlzbWF0Y2hBbGxvd2VkKG5vZGUucGFyZW50RWxlbWVudCwgMSAvKiBDSElMRFJFTiAqLykpIHsNCiAgICAgIHdhcm4kMSgNCiAgICAgICAgYEh5ZHJhdGlvbiBub2RlIG1pc21hdGNoOg0KLSByZW5kZXJlZCBvbiBzZXJ2ZXI6YCwNCiAgICAgICAgbm9kZSwNCiAgICAgICAgbm9kZS5ub2RlVHlwZSA9PT0gMyA/IGAodGV4dClgIDogaXNDb21tZW50KG5vZGUpICYmIG5vZGUuZGF0YSA9PT0gIlsiID8gYChzdGFydCBvZiBmcmFnbWVudClgIDogYGAsDQogICAgICAgIGANCi0gZXhwZWN0ZWQgb24gY2xpZW50OmAsDQogICAgICAgIHZub2RlLnR5cGUNCiAgICAgICk7DQogICAgICBsb2dNaXNtYXRjaEVycm9yKCk7DQogICAgfQ0KICAgIHZub2RlLmVsID0gbnVsbDsNCiAgICBpZiAoaXNGcmFnbWVudCkgew0KICAgICAgY29uc3QgZW5kID0gbG9jYXRlQ2xvc2luZ0FuY2hvcihub2RlKTsNCiAgICAgIHdoaWxlICh0cnVlKSB7DQogICAgICAgIGNvbnN0IG5leHQyID0gbmV4dFNpYmxpbmcobm9kZSk7DQogICAgICAgIGlmIChuZXh0MiAmJiBuZXh0MiAhPT0gZW5kKSB7DQogICAgICAgICAgcmVtb3ZlKG5leHQyKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBicmVhazsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgICBjb25zdCBuZXh0ID0gbmV4dFNpYmxpbmcobm9kZSk7DQogICAgY29uc3QgY29udGFpbmVyID0gcGFyZW50Tm9kZShub2RlKTsNCiAgICByZW1vdmUobm9kZSk7DQogICAgcGF0Y2goDQogICAgICBudWxsLA0KICAgICAgdm5vZGUsDQogICAgICBjb250YWluZXIsDQogICAgICBuZXh0LA0KICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICBnZXRDb250YWluZXJUeXBlKGNvbnRhaW5lciksDQogICAgICBzbG90U2NvcGVJZHMNCiAgICApOw0KICAgIGlmIChwYXJlbnRDb21wb25lbnQpIHsNCiAgICAgIHBhcmVudENvbXBvbmVudC52bm9kZS5lbCA9IHZub2RlLmVsOw0KICAgICAgdXBkYXRlSE9DSG9zdEVsKHBhcmVudENvbXBvbmVudCwgdm5vZGUuZWwpOw0KICAgIH0NCiAgICByZXR1cm4gbmV4dDsNCiAgfTsNCiAgY29uc3QgbG9jYXRlQ2xvc2luZ0FuY2hvciA9IChub2RlLCBvcGVuID0gIlsiLCBjbG9zZSA9ICJdIikgPT4gew0KICAgIGxldCBtYXRjaCA9IDA7DQogICAgd2hpbGUgKG5vZGUpIHsNCiAgICAgIG5vZGUgPSBuZXh0U2libGluZyhub2RlKTsNCiAgICAgIGlmIChub2RlICYmIGlzQ29tbWVudChub2RlKSkgew0KICAgICAgICBpZiAobm9kZS5kYXRhID09PSBvcGVuKSBtYXRjaCsrOw0KICAgICAgICBpZiAobm9kZS5kYXRhID09PSBjbG9zZSkgew0KICAgICAgICAgIGlmIChtYXRjaCA9PT0gMCkgew0KICAgICAgICAgICAgcmV0dXJuIG5leHRTaWJsaW5nKG5vZGUpOw0KICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBtYXRjaC0tOw0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgICByZXR1cm4gbm9kZTsNCiAgfTsNCiAgY29uc3QgcmVwbGFjZU5vZGUgPSAobmV3Tm9kZSwgb2xkTm9kZSwgcGFyZW50Q29tcG9uZW50KSA9PiB7DQogICAgY29uc3QgcGFyZW50Tm9kZTIgPSBvbGROb2RlLnBhcmVudE5vZGU7DQogICAgaWYgKHBhcmVudE5vZGUyKSB7DQogICAgICBwYXJlbnROb2RlMi5yZXBsYWNlQ2hpbGQobmV3Tm9kZSwgb2xkTm9kZSk7DQogICAgfQ0KICAgIGxldCBwYXJlbnQgPSBwYXJlbnRDb21wb25lbnQ7DQogICAgd2hpbGUgKHBhcmVudCkgew0KICAgICAgaWYgKHBhcmVudC52bm9kZS5lbCA9PT0gb2xkTm9kZSkgew0KICAgICAgICBwYXJlbnQudm5vZGUuZWwgPSBwYXJlbnQuc3ViVHJlZS5lbCA9IG5ld05vZGU7DQogICAgICB9DQogICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50Ow0KICAgIH0NCiAgfTsNCiAgY29uc3QgaXNUZW1wbGF0ZU5vZGUgPSAobm9kZSkgPT4gew0KICAgIHJldHVybiBub2RlLm5vZGVUeXBlID09PSAxICYmIG5vZGUudGFnTmFtZSA9PT0gIlRFTVBMQVRFIjsNCiAgfTsNCiAgcmV0dXJuIFtoeWRyYXRlLCBoeWRyYXRlTm9kZV07DQp9DQpmdW5jdGlvbiBwcm9wSGFzTWlzbWF0Y2goZWwsIGtleSwgY2xpZW50VmFsdWUsIHZub2RlLCBpbnN0YW5jZSkgew0KICBsZXQgbWlzbWF0Y2hUeXBlOw0KICBsZXQgbWlzbWF0Y2hLZXk7DQogIGxldCBhY3R1YWw7DQogIGxldCBleHBlY3RlZDsNCiAgaWYgKGtleSA9PT0gImNsYXNzIikgew0KICAgIGlmIChlbC4kY2xzKSB7DQogICAgICBhY3R1YWwgPSBlbC4kY2xzOw0KICAgICAgZGVsZXRlIGVsLiRjbHM7DQogICAgfSBlbHNlIHsNCiAgICAgIGFjdHVhbCA9IGVsLmdldEF0dHJpYnV0ZSgiY2xhc3MiKTsNCiAgICB9DQogICAgZXhwZWN0ZWQgPSBub3JtYWxpemVDbGFzcyhjbGllbnRWYWx1ZSk7DQogICAgaWYgKCFpc1NldEVxdWFsKHRvQ2xhc3NTZXQoYWN0dWFsIHx8ICIiKSwgdG9DbGFzc1NldChleHBlY3RlZCkpKSB7DQogICAgICBtaXNtYXRjaFR5cGUgPSAyIC8qIENMQVNTICovOw0KICAgICAgbWlzbWF0Y2hLZXkgPSBgY2xhc3NgOw0KICAgIH0NCiAgfSBlbHNlIGlmIChrZXkgPT09ICJzdHlsZSIpIHsNCiAgICBhY3R1YWwgPSBlbC5nZXRBdHRyaWJ1dGUoInN0eWxlIikgfHwgIiI7DQogICAgZXhwZWN0ZWQgPSBpc1N0cmluZyhjbGllbnRWYWx1ZSkgPyBjbGllbnRWYWx1ZSA6IHN0cmluZ2lmeVN0eWxlKG5vcm1hbGl6ZVN0eWxlKGNsaWVudFZhbHVlKSk7DQogICAgY29uc3QgYWN0dWFsTWFwID0gdG9TdHlsZU1hcChhY3R1YWwpOw0KICAgIGNvbnN0IGV4cGVjdGVkTWFwID0gdG9TdHlsZU1hcChleHBlY3RlZCk7DQogICAgaWYgKHZub2RlLmRpcnMpIHsNCiAgICAgIGZvciAoY29uc3QgeyBkaXIsIHZhbHVlIH0gb2Ygdm5vZGUuZGlycykgew0KICAgICAgICBpZiAoZGlyLm5hbWUgPT09ICJzaG93IiAmJiAhdmFsdWUpIHsNCiAgICAgICAgICBleHBlY3RlZE1hcC5zZXQoImRpc3BsYXkiLCAibm9uZSIpOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICAgIGlmIChpbnN0YW5jZSkgew0KICAgICAgcmVzb2x2ZUNzc1ZhcnMoaW5zdGFuY2UsIHZub2RlLCBleHBlY3RlZE1hcCk7DQogICAgfQ0KICAgIGlmICghaXNNYXBFcXVhbChhY3R1YWxNYXAsIGV4cGVjdGVkTWFwKSkgew0KICAgICAgbWlzbWF0Y2hUeXBlID0gMyAvKiBTVFlMRSAqLzsNCiAgICAgIG1pc21hdGNoS2V5ID0gInN0eWxlIjsNCiAgICB9DQogIH0gZWxzZSBpZiAoZWwgaW5zdGFuY2VvZiBTVkdFbGVtZW50ICYmIGlzS25vd25TdmdBdHRyKGtleSkgfHwgZWwgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCAmJiAoaXNCb29sZWFuQXR0cihrZXkpIHx8IGlzS25vd25IdG1sQXR0cihrZXkpKSkgew0KICAgIGlmIChpc0Jvb2xlYW5BdHRyKGtleSkpIHsNCiAgICAgIGFjdHVhbCA9IGVsLmhhc0F0dHJpYnV0ZShrZXkpOw0KICAgICAgZXhwZWN0ZWQgPSBpbmNsdWRlQm9vbGVhbkF0dHIoY2xpZW50VmFsdWUpOw0KICAgIH0gZWxzZSBpZiAoY2xpZW50VmFsdWUgPT0gbnVsbCkgew0KICAgICAgYWN0dWFsID0gZWwuaGFzQXR0cmlidXRlKGtleSk7DQogICAgICBleHBlY3RlZCA9IGZhbHNlOw0KICAgIH0gZWxzZSB7DQogICAgICBpZiAoZWwuaGFzQXR0cmlidXRlKGtleSkpIHsNCiAgICAgICAgYWN0dWFsID0gZWwuZ2V0QXR0cmlidXRlKGtleSk7DQogICAgICB9IGVsc2UgaWYgKGtleSA9PT0gInZhbHVlIiAmJiBlbC50YWdOYW1lID09PSAiVEVYVEFSRUEiKSB7DQogICAgICAgIGFjdHVhbCA9IGVsLnZhbHVlOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgYWN0dWFsID0gZmFsc2U7DQogICAgICB9DQogICAgICBleHBlY3RlZCA9IGlzUmVuZGVyYWJsZUF0dHJWYWx1ZShjbGllbnRWYWx1ZSkgPyBTdHJpbmcoY2xpZW50VmFsdWUpIDogZmFsc2U7DQogICAgfQ0KICAgIGlmIChhY3R1YWwgIT09IGV4cGVjdGVkKSB7DQogICAgICBtaXNtYXRjaFR5cGUgPSA0IC8qIEFUVFJJQlVURSAqLzsNCiAgICAgIG1pc21hdGNoS2V5ID0ga2V5Ow0KICAgIH0NCiAgfQ0KICBpZiAobWlzbWF0Y2hUeXBlICE9IG51bGwgJiYgIWlzTWlzbWF0Y2hBbGxvd2VkKGVsLCBtaXNtYXRjaFR5cGUpKSB7DQogICAgY29uc3QgZm9ybWF0ID0gKHYpID0+IHYgPT09IGZhbHNlID8gYChub3QgcmVuZGVyZWQpYCA6IGAke21pc21hdGNoS2V5fT0iJHt2fSJgOw0KICAgIGNvbnN0IHByZVNlZ21lbnQgPSBgSHlkcmF0aW9uICR7TWlzbWF0Y2hUeXBlU3RyaW5nW21pc21hdGNoVHlwZV19IG1pc21hdGNoIG9uYDsNCiAgICBjb25zdCBwb3N0U2VnbWVudCA9IGANCiAgLSByZW5kZXJlZCBvbiBzZXJ2ZXI6ICR7Zm9ybWF0KGFjdHVhbCl9DQogIC0gZXhwZWN0ZWQgb24gY2xpZW50OiAke2Zvcm1hdChleHBlY3RlZCl9DQogIE5vdGU6IHRoaXMgbWlzbWF0Y2ggaXMgY2hlY2stb25seS4gVGhlIERPTSB3aWxsIG5vdCBiZSByZWN0aWZpZWQgaW4gcHJvZHVjdGlvbiBkdWUgdG8gcGVyZm9ybWFuY2Ugb3ZlcmhlYWQuDQogIFlvdSBzaG91bGQgZml4IHRoZSBzb3VyY2Ugb2YgdGhlIG1pc21hdGNoLmA7DQogICAgew0KICAgICAgd2FybiQxKHByZVNlZ21lbnQsIGVsLCBwb3N0U2VnbWVudCk7DQogICAgfQ0KICAgIHJldHVybiB0cnVlOw0KICB9DQogIHJldHVybiBmYWxzZTsNCn0NCmZ1bmN0aW9uIHRvQ2xhc3NTZXQoc3RyKSB7DQogIHJldHVybiBuZXcgU2V0KHN0ci50cmltKCkuc3BsaXQoL1xzKy8pKTsNCn0NCmZ1bmN0aW9uIGlzU2V0RXF1YWwoYSwgYikgew0KICBpZiAoYS5zaXplICE9PSBiLnNpemUpIHsNCiAgICByZXR1cm4gZmFsc2U7DQogIH0NCiAgZm9yIChjb25zdCBzIG9mIGEpIHsNCiAgICBpZiAoIWIuaGFzKHMpKSB7DQogICAgICByZXR1cm4gZmFsc2U7DQogICAgfQ0KICB9DQogIHJldHVybiB0cnVlOw0KfQ0KZnVuY3Rpb24gdG9TdHlsZU1hcChzdHIpIHsNCiAgY29uc3Qgc3R5bGVNYXAgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOw0KICBmb3IgKGNvbnN0IGl0ZW0gb2Ygc3RyLnNwbGl0KCI7IikpIHsNCiAgICBsZXQgW2tleSwgdmFsdWVdID0gaXRlbS5zcGxpdCgiOiIpOw0KICAgIGtleSA9IGtleS50cmltKCk7DQogICAgdmFsdWUgPSB2YWx1ZSAmJiB2YWx1ZS50cmltKCk7DQogICAgaWYgKGtleSAmJiB2YWx1ZSkgew0KICAgICAgc3R5bGVNYXAuc2V0KGtleSwgdmFsdWUpOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gc3R5bGVNYXA7DQp9DQpmdW5jdGlvbiBpc01hcEVxdWFsKGEsIGIpIHsNCiAgaWYgKGEuc2l6ZSAhPT0gYi5zaXplKSB7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9DQogIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIGEpIHsNCiAgICBpZiAodmFsdWUgIT09IGIuZ2V0KGtleSkpIHsNCiAgICAgIHJldHVybiBmYWxzZTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIHRydWU7DQp9DQpmdW5jdGlvbiByZXNvbHZlQ3NzVmFycyhpbnN0YW5jZSwgdm5vZGUsIGV4cGVjdGVkTWFwKSB7DQogIGNvbnN0IHJvb3QgPSBpbnN0YW5jZS5zdWJUcmVlOw0KICBpZiAoaW5zdGFuY2UuZ2V0Q3NzVmFycyAmJiAodm5vZGUgPT09IHJvb3QgfHwgcm9vdCAmJiByb290LnR5cGUgPT09IEZyYWdtZW50ICYmIHJvb3QuY2hpbGRyZW4uaW5jbHVkZXModm5vZGUpKSkgew0KICAgIGNvbnN0IGNzc1ZhcnMgPSBpbnN0YW5jZS5nZXRDc3NWYXJzKCk7DQogICAgZm9yIChjb25zdCBrZXkgaW4gY3NzVmFycykgew0KICAgICAgZXhwZWN0ZWRNYXAuc2V0KA0KICAgICAgICBgLS0ke2dldEVzY2FwZWRDc3NWYXJOYW1lKGtleSl9YCwNCiAgICAgICAgU3RyaW5nKGNzc1ZhcnNba2V5XSkNCiAgICAgICk7DQogICAgfQ0KICB9DQogIGlmICh2bm9kZSA9PT0gcm9vdCAmJiBpbnN0YW5jZS5wYXJlbnQpIHsNCiAgICByZXNvbHZlQ3NzVmFycyhpbnN0YW5jZS5wYXJlbnQsIGluc3RhbmNlLnZub2RlLCBleHBlY3RlZE1hcCk7DQogIH0NCn0NCmNvbnN0IGFsbG93TWlzbWF0Y2hBdHRyID0gImRhdGEtYWxsb3ctbWlzbWF0Y2giOw0KY29uc3QgTWlzbWF0Y2hUeXBlU3RyaW5nID0gew0KICBbMCAvKiBURVhUICovXTogInRleHQiLA0KICBbMSAvKiBDSElMRFJFTiAqL106ICJjaGlsZHJlbiIsDQogIFsyIC8qIENMQVNTICovXTogImNsYXNzIiwNCiAgWzMgLyogU1RZTEUgKi9dOiAic3R5bGUiLA0KICBbNCAvKiBBVFRSSUJVVEUgKi9dOiAiYXR0cmlidXRlIg0KfTsNCmZ1bmN0aW9uIGlzTWlzbWF0Y2hBbGxvd2VkKGVsLCBhbGxvd2VkVHlwZSkgew0KICBpZiAoYWxsb3dlZFR5cGUgPT09IDAgLyogVEVYVCAqLyB8fCBhbGxvd2VkVHlwZSA9PT0gMSAvKiBDSElMRFJFTiAqLykgew0KICAgIHdoaWxlIChlbCAmJiAhZWwuaGFzQXR0cmlidXRlKGFsbG93TWlzbWF0Y2hBdHRyKSkgew0KICAgICAgZWwgPSBlbC5wYXJlbnRFbGVtZW50Ow0KICAgIH0NCiAgfQ0KICBjb25zdCBhbGxvd2VkQXR0ciA9IGVsICYmIGVsLmdldEF0dHJpYnV0ZShhbGxvd01pc21hdGNoQXR0cik7DQogIGlmIChhbGxvd2VkQXR0ciA9PSBudWxsKSB7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9IGVsc2UgaWYgKGFsbG93ZWRBdHRyID09PSAiIikgew0KICAgIHJldHVybiB0cnVlOw0KICB9IGVsc2Ugew0KICAgIGNvbnN0IGxpc3QgPSBhbGxvd2VkQXR0ci5zcGxpdCgiLCIpOw0KICAgIGlmIChhbGxvd2VkVHlwZSA9PT0gMCAvKiBURVhUICovICYmIGxpc3QuaW5jbHVkZXMoImNoaWxkcmVuIikpIHsNCiAgICAgIHJldHVybiB0cnVlOw0KICAgIH0NCiAgICByZXR1cm4gbGlzdC5pbmNsdWRlcyhNaXNtYXRjaFR5cGVTdHJpbmdbYWxsb3dlZFR5cGVdKTsNCiAgfQ0KfQ0KDQpjb25zdCByZXF1ZXN0SWRsZUNhbGxiYWNrID0gZ2V0R2xvYmFsVGhpcygpLnJlcXVlc3RJZGxlQ2FsbGJhY2sgfHwgKChjYikgPT4gc2V0VGltZW91dChjYiwgMSkpOw0KY29uc3QgY2FuY2VsSWRsZUNhbGxiYWNrID0gZ2V0R2xvYmFsVGhpcygpLmNhbmNlbElkbGVDYWxsYmFjayB8fCAoKGlkKSA9PiBjbGVhclRpbWVvdXQoaWQpKTsNCmNvbnN0IGh5ZHJhdGVPbklkbGUgPSAodGltZW91dCA9IDFlNCkgPT4gKGh5ZHJhdGUpID0+IHsNCiAgY29uc3QgaWQgPSByZXF1ZXN0SWRsZUNhbGxiYWNrKGh5ZHJhdGUsIHsgdGltZW91dCB9KTsNCiAgcmV0dXJuICgpID0+IGNhbmNlbElkbGVDYWxsYmFjayhpZCk7DQp9Ow0KZnVuY3Rpb24gZWxlbWVudElzVmlzaWJsZUluVmlld3BvcnQoZWwpIHsNCiAgY29uc3QgeyB0b3AsIGxlZnQsIGJvdHRvbSwgcmlnaHQgfSA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOw0KICBjb25zdCB7IGlubmVySGVpZ2h0LCBpbm5lcldpZHRoIH0gPSB3aW5kb3c7DQogIHJldHVybiAodG9wID4gMCAmJiB0b3AgPCBpbm5lckhlaWdodCB8fCBib3R0b20gPiAwICYmIGJvdHRvbSA8IGlubmVySGVpZ2h0KSAmJiAobGVmdCA+IDAgJiYgbGVmdCA8IGlubmVyV2lkdGggfHwgcmlnaHQgPiAwICYmIHJpZ2h0IDwgaW5uZXJXaWR0aCk7DQp9DQpjb25zdCBoeWRyYXRlT25WaXNpYmxlID0gKG9wdHMpID0+IChoeWRyYXRlLCBmb3JFYWNoKSA9PiB7DQogIGNvbnN0IG9iID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKChlbnRyaWVzKSA9PiB7DQogICAgZm9yIChjb25zdCBlIG9mIGVudHJpZXMpIHsNCiAgICAgIGlmICghZS5pc0ludGVyc2VjdGluZykgY29udGludWU7DQogICAgICBvYi5kaXNjb25uZWN0KCk7DQogICAgICBoeWRyYXRlKCk7DQogICAgICBicmVhazsNCiAgICB9DQogIH0sIG9wdHMpOw0KICBmb3JFYWNoKChlbCkgPT4gew0KICAgIGlmICghKGVsIGluc3RhbmNlb2YgRWxlbWVudCkpIHJldHVybjsNCiAgICBpZiAoZWxlbWVudElzVmlzaWJsZUluVmlld3BvcnQoZWwpKSB7DQogICAgICBoeWRyYXRlKCk7DQogICAgICBvYi5kaXNjb25uZWN0KCk7DQogICAgICByZXR1cm4gZmFsc2U7DQogICAgfQ0KICAgIG9iLm9ic2VydmUoZWwpOw0KICB9KTsNCiAgcmV0dXJuICgpID0+IG9iLmRpc2Nvbm5lY3QoKTsNCn07DQpjb25zdCBoeWRyYXRlT25NZWRpYVF1ZXJ5ID0gKHF1ZXJ5KSA9PiAoaHlkcmF0ZSkgPT4gew0KICBpZiAocXVlcnkpIHsNCiAgICBjb25zdCBtcWwgPSBtYXRjaE1lZGlhKHF1ZXJ5KTsNCiAgICBpZiAobXFsLm1hdGNoZXMpIHsNCiAgICAgIGh5ZHJhdGUoKTsNCiAgICB9IGVsc2Ugew0KICAgICAgbXFsLmFkZEV2ZW50TGlzdGVuZXIoImNoYW5nZSIsIGh5ZHJhdGUsIHsgb25jZTogdHJ1ZSB9KTsNCiAgICAgIHJldHVybiAoKSA9PiBtcWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigiY2hhbmdlIiwgaHlkcmF0ZSk7DQogICAgfQ0KICB9DQp9Ow0KY29uc3QgaHlkcmF0ZU9uSW50ZXJhY3Rpb24gPSAoaW50ZXJhY3Rpb25zID0gW10pID0+IChoeWRyYXRlLCBmb3JFYWNoKSA9PiB7DQogIGlmIChpc1N0cmluZyhpbnRlcmFjdGlvbnMpKSBpbnRlcmFjdGlvbnMgPSBbaW50ZXJhY3Rpb25zXTsNCiAgbGV0IGhhc0h5ZHJhdGVkID0gZmFsc2U7DQogIGNvbnN0IGRvSHlkcmF0ZSA9IChlKSA9PiB7DQogICAgaWYgKCFoYXNIeWRyYXRlZCkgew0KICAgICAgaGFzSHlkcmF0ZWQgPSB0cnVlOw0KICAgICAgdGVhcmRvd24oKTsNCiAgICAgIGh5ZHJhdGUoKTsNCiAgICAgIGUudGFyZ2V0LmRpc3BhdGNoRXZlbnQobmV3IGUuY29uc3RydWN0b3IoZS50eXBlLCBlKSk7DQogICAgfQ0KICB9Ow0KICBjb25zdCB0ZWFyZG93biA9ICgpID0+IHsNCiAgICBmb3JFYWNoKChlbCkgPT4gew0KICAgICAgZm9yIChjb25zdCBpIG9mIGludGVyYWN0aW9ucykgew0KICAgICAgICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKGksIGRvSHlkcmF0ZSk7DQogICAgICB9DQogICAgfSk7DQogIH07DQogIGZvckVhY2goKGVsKSA9PiB7DQogICAgZm9yIChjb25zdCBpIG9mIGludGVyYWN0aW9ucykgew0KICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcihpLCBkb0h5ZHJhdGUsIHsgb25jZTogdHJ1ZSB9KTsNCiAgICB9DQogIH0pOw0KICByZXR1cm4gdGVhcmRvd247DQp9Ow0KZnVuY3Rpb24gZm9yRWFjaEVsZW1lbnQobm9kZSwgY2IpIHsNCiAgaWYgKGlzQ29tbWVudChub2RlKSAmJiBub2RlLmRhdGEgPT09ICJbIikgew0KICAgIGxldCBkZXB0aCA9IDE7DQogICAgbGV0IG5leHQgPSBub2RlLm5leHRTaWJsaW5nOw0KICAgIHdoaWxlIChuZXh0KSB7DQogICAgICBpZiAobmV4dC5ub2RlVHlwZSA9PT0gMSkgew0KICAgICAgICBjb25zdCByZXN1bHQgPSBjYihuZXh0KTsNCiAgICAgICAgaWYgKHJlc3VsdCA9PT0gZmFsc2UpIHsNCiAgICAgICAgICBicmVhazsNCiAgICAgICAgfQ0KICAgICAgfSBlbHNlIGlmIChpc0NvbW1lbnQobmV4dCkpIHsNCiAgICAgICAgaWYgKG5leHQuZGF0YSA9PT0gIl0iKSB7DQogICAgICAgICAgaWYgKC0tZGVwdGggPT09IDApIGJyZWFrOw0KICAgICAgICB9IGVsc2UgaWYgKG5leHQuZGF0YSA9PT0gIlsiKSB7DQogICAgICAgICAgZGVwdGgrKzsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgbmV4dCA9IG5leHQubmV4dFNpYmxpbmc7DQogICAgfQ0KICB9IGVsc2Ugew0KICAgIGNiKG5vZGUpOw0KICB9DQp9DQoNCmNvbnN0IGlzQXN5bmNXcmFwcGVyID0gKGkpID0+ICEhaS50eXBlLl9fYXN5bmNMb2FkZXI7DQovKiEgI19fTk9fU0lERV9FRkZFQ1RTX18gKi8NCi8vIEBfX05PX1NJREVfRUZGRUNUU19fDQpmdW5jdGlvbiBkZWZpbmVBc3luY0NvbXBvbmVudChzb3VyY2UpIHsNCiAgaWYgKGlzRnVuY3Rpb24oc291cmNlKSkgew0KICAgIHNvdXJjZSA9IHsgbG9hZGVyOiBzb3VyY2UgfTsNCiAgfQ0KICBjb25zdCB7DQogICAgbG9hZGVyLA0KICAgIGxvYWRpbmdDb21wb25lbnQsDQogICAgZXJyb3JDb21wb25lbnQsDQogICAgZGVsYXkgPSAyMDAsDQogICAgaHlkcmF0ZTogaHlkcmF0ZVN0cmF0ZWd5LA0KICAgIHRpbWVvdXQsDQogICAgLy8gdW5kZWZpbmVkID0gbmV2ZXIgdGltZXMgb3V0DQogICAgc3VzcGVuc2libGUgPSB0cnVlLA0KICAgIG9uRXJyb3I6IHVzZXJPbkVycm9yDQogIH0gPSBzb3VyY2U7DQogIGxldCBwZW5kaW5nUmVxdWVzdCA9IG51bGw7DQogIGxldCByZXNvbHZlZENvbXA7DQogIGxldCByZXRyaWVzID0gMDsNCiAgY29uc3QgcmV0cnkgPSAoKSA9PiB7DQogICAgcmV0cmllcysrOw0KICAgIHBlbmRpbmdSZXF1ZXN0ID0gbnVsbDsNCiAgICByZXR1cm4gbG9hZCgpOw0KICB9Ow0KICBjb25zdCBsb2FkID0gKCkgPT4gew0KICAgIGxldCB0aGlzUmVxdWVzdDsNCiAgICByZXR1cm4gcGVuZGluZ1JlcXVlc3QgfHwgKHRoaXNSZXF1ZXN0ID0gcGVuZGluZ1JlcXVlc3QgPSBsb2FkZXIoKS5jYXRjaCgoZXJyKSA9PiB7DQogICAgICBlcnIgPSBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyKSk7DQogICAgICBpZiAodXNlck9uRXJyb3IpIHsNCiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHsNCiAgICAgICAgICBjb25zdCB1c2VyUmV0cnkgPSAoKSA9PiByZXNvbHZlKHJldHJ5KCkpOw0KICAgICAgICAgIGNvbnN0IHVzZXJGYWlsID0gKCkgPT4gcmVqZWN0KGVycik7DQogICAgICAgICAgdXNlck9uRXJyb3IoZXJyLCB1c2VyUmV0cnksIHVzZXJGYWlsLCByZXRyaWVzICsgMSk7DQogICAgICAgIH0pOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgdGhyb3cgZXJyOw0KICAgICAgfQ0KICAgIH0pLnRoZW4oKGNvbXApID0+IHsNCiAgICAgIGlmICh0aGlzUmVxdWVzdCAhPT0gcGVuZGluZ1JlcXVlc3QgJiYgcGVuZGluZ1JlcXVlc3QpIHsNCiAgICAgICAgcmV0dXJuIHBlbmRpbmdSZXF1ZXN0Ow0KICAgICAgfQ0KICAgICAgaWYgKCFjb21wKSB7DQogICAgICAgIHdhcm4kMSgNCiAgICAgICAgICBgQXN5bmMgY29tcG9uZW50IGxvYWRlciByZXNvbHZlZCB0byB1bmRlZmluZWQuIElmIHlvdSBhcmUgdXNpbmcgcmV0cnkoKSwgbWFrZSBzdXJlIHRvIHJldHVybiBpdHMgcmV0dXJuIHZhbHVlLmANCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICAgIGlmIChjb21wICYmIChjb21wLl9fZXNNb2R1bGUgfHwgY29tcFtTeW1ib2wudG9TdHJpbmdUYWddID09PSAiTW9kdWxlIikpIHsNCiAgICAgICAgY29tcCA9IGNvbXAuZGVmYXVsdDsNCiAgICAgIH0NCiAgICAgIGlmIChjb21wICYmICFpc09iamVjdChjb21wKSAmJiAhaXNGdW5jdGlvbihjb21wKSkgew0KICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgYXN5bmMgY29tcG9uZW50IGxvYWQgcmVzdWx0OiAke2NvbXB9YCk7DQogICAgICB9DQogICAgICByZXNvbHZlZENvbXAgPSBjb21wOw0KICAgICAgcmV0dXJuIGNvbXA7DQogICAgfSkpOw0KICB9Ow0KICByZXR1cm4gZGVmaW5lQ29tcG9uZW50KHsNCiAgICBuYW1lOiAiQXN5bmNDb21wb25lbnRXcmFwcGVyIiwNCiAgICBfX2FzeW5jTG9hZGVyOiBsb2FkLA0KICAgIF9fYXN5bmNIeWRyYXRlKGVsLCBpbnN0YW5jZSwgaHlkcmF0ZSkgew0KICAgICAgbGV0IHBhdGNoZWQgPSBmYWxzZTsNCiAgICAgIGNvbnN0IGRvSHlkcmF0ZSA9IGh5ZHJhdGVTdHJhdGVneSA/ICgpID0+IHsNCiAgICAgICAgY29uc3QgcGVyZm9ybUh5ZHJhdGUgPSAoKSA9PiB7DQogICAgICAgICAgaWYgKHBhdGNoZWQpIHsNCiAgICAgICAgICAgIHdhcm4kMSgNCiAgICAgICAgICAgICAgYFNraXBwaW5nIGxhenkgaHlkcmF0aW9uIGZvciBjb21wb25lbnQgJyR7Z2V0Q29tcG9uZW50TmFtZShyZXNvbHZlZENvbXApfSc6IGl0IHdhcyB1cGRhdGVkIGJlZm9yZSBsYXp5IGh5ZHJhdGlvbiBwZXJmb3JtZWQuYA0KICAgICAgICAgICAgKTsNCiAgICAgICAgICAgIHJldHVybjsNCiAgICAgICAgICB9DQogICAgICAgICAgaHlkcmF0ZSgpOw0KICAgICAgICB9Ow0KICAgICAgICBjb25zdCB0ZWFyZG93biA9IGh5ZHJhdGVTdHJhdGVneSgNCiAgICAgICAgICBwZXJmb3JtSHlkcmF0ZSwNCiAgICAgICAgICAoY2IpID0+IGZvckVhY2hFbGVtZW50KGVsLCBjYikNCiAgICAgICAgKTsNCiAgICAgICAgaWYgKHRlYXJkb3duKSB7DQogICAgICAgICAgKGluc3RhbmNlLmJ1bSB8fCAoaW5zdGFuY2UuYnVtID0gW10pKS5wdXNoKHRlYXJkb3duKTsNCiAgICAgICAgfQ0KICAgICAgICAoaW5zdGFuY2UudSB8fCAoaW5zdGFuY2UudSA9IFtdKSkucHVzaCgoKSA9PiBwYXRjaGVkID0gdHJ1ZSk7DQogICAgICB9IDogaHlkcmF0ZTsNCiAgICAgIGlmIChyZXNvbHZlZENvbXApIHsNCiAgICAgICAgZG9IeWRyYXRlKCk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBsb2FkKCkudGhlbigoKSA9PiAhaW5zdGFuY2UuaXNVbm1vdW50ZWQgJiYgZG9IeWRyYXRlKCkpOw0KICAgICAgfQ0KICAgIH0sDQogICAgZ2V0IF9fYXN5bmNSZXNvbHZlZCgpIHsNCiAgICAgIHJldHVybiByZXNvbHZlZENvbXA7DQogICAgfSwNCiAgICBzZXR1cCgpIHsNCiAgICAgIGNvbnN0IGluc3RhbmNlID0gY3VycmVudEluc3RhbmNlOw0KICAgICAgbWFya0FzeW5jQm91bmRhcnkoaW5zdGFuY2UpOw0KICAgICAgaWYgKHJlc29sdmVkQ29tcCkgew0KICAgICAgICByZXR1cm4gKCkgPT4gY3JlYXRlSW5uZXJDb21wKHJlc29sdmVkQ29tcCwgaW5zdGFuY2UpOw0KICAgICAgfQ0KICAgICAgY29uc3Qgb25FcnJvciA9IChlcnIpID0+IHsNCiAgICAgICAgcGVuZGluZ1JlcXVlc3QgPSBudWxsOw0KICAgICAgICBoYW5kbGVFcnJvcigNCiAgICAgICAgICBlcnIsDQogICAgICAgICAgaW5zdGFuY2UsDQogICAgICAgICAgMTMsDQogICAgICAgICAgIWVycm9yQ29tcG9uZW50DQogICAgICAgICk7DQogICAgICB9Ow0KICAgICAgaWYgKHN1c3BlbnNpYmxlICYmIGluc3RhbmNlLnN1c3BlbnNlIHx8IGlzSW5TU1JDb21wb25lbnRTZXR1cCkgew0KICAgICAgICByZXR1cm4gbG9hZCgpLnRoZW4oKGNvbXApID0+IHsNCiAgICAgICAgICByZXR1cm4gKCkgPT4gY3JlYXRlSW5uZXJDb21wKGNvbXAsIGluc3RhbmNlKTsNCiAgICAgICAgfSkuY2F0Y2goKGVycikgPT4gew0KICAgICAgICAgIG9uRXJyb3IoZXJyKTsNCiAgICAgICAgICByZXR1cm4gKCkgPT4gZXJyb3JDb21wb25lbnQgPyBjcmVhdGVWTm9kZShlcnJvckNvbXBvbmVudCwgew0KICAgICAgICAgICAgZXJyb3I6IGVycg0KICAgICAgICAgIH0pIDogbnVsbDsNCiAgICAgICAgfSk7DQogICAgICB9DQogICAgICBjb25zdCBsb2FkZWQgPSByZWYoZmFsc2UpOw0KICAgICAgY29uc3QgZXJyb3IgPSByZWYoKTsNCiAgICAgIGNvbnN0IGRlbGF5ZWQgPSByZWYoISFkZWxheSk7DQogICAgICBpZiAoZGVsYXkpIHsNCiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7DQogICAgICAgICAgZGVsYXllZC52YWx1ZSA9IGZhbHNlOw0KICAgICAgICB9LCBkZWxheSk7DQogICAgICB9DQogICAgICBpZiAodGltZW91dCAhPSBudWxsKSB7DQogICAgICAgIHNldFRpbWVvdXQoKCkgPT4gew0KICAgICAgICAgIGlmICghbG9hZGVkLnZhbHVlICYmICFlcnJvci52YWx1ZSkgew0KICAgICAgICAgICAgY29uc3QgZXJyID0gbmV3IEVycm9yKA0KICAgICAgICAgICAgICBgQXN5bmMgY29tcG9uZW50IHRpbWVkIG91dCBhZnRlciAke3RpbWVvdXR9bXMuYA0KICAgICAgICAgICAgKTsNCiAgICAgICAgICAgIG9uRXJyb3IoZXJyKTsNCiAgICAgICAgICAgIGVycm9yLnZhbHVlID0gZXJyOw0KICAgICAgICAgIH0NCiAgICAgICAgfSwgdGltZW91dCk7DQogICAgICB9DQogICAgICBsb2FkKCkudGhlbigoKSA9PiB7DQogICAgICAgIGxvYWRlZC52YWx1ZSA9IHRydWU7DQogICAgICAgIGlmIChpbnN0YW5jZS5wYXJlbnQgJiYgaXNLZWVwQWxpdmUoaW5zdGFuY2UucGFyZW50LnZub2RlKSkgew0KICAgICAgICAgIGluc3RhbmNlLnBhcmVudC51cGRhdGUoKTsNCiAgICAgICAgfQ0KICAgICAgfSkuY2F0Y2goKGVycikgPT4gew0KICAgICAgICBvbkVycm9yKGVycik7DQogICAgICAgIGVycm9yLnZhbHVlID0gZXJyOw0KICAgICAgfSk7DQogICAgICByZXR1cm4gKCkgPT4gew0KICAgICAgICBpZiAobG9hZGVkLnZhbHVlICYmIHJlc29sdmVkQ29tcCkgew0KICAgICAgICAgIHJldHVybiBjcmVhdGVJbm5lckNvbXAocmVzb2x2ZWRDb21wLCBpbnN0YW5jZSk7DQogICAgICAgIH0gZWxzZSBpZiAoZXJyb3IudmFsdWUgJiYgZXJyb3JDb21wb25lbnQpIHsNCiAgICAgICAgICByZXR1cm4gY3JlYXRlVk5vZGUoZXJyb3JDb21wb25lbnQsIHsNCiAgICAgICAgICAgIGVycm9yOiBlcnJvci52YWx1ZQ0KICAgICAgICAgIH0pOw0KICAgICAgICB9IGVsc2UgaWYgKGxvYWRpbmdDb21wb25lbnQgJiYgIWRlbGF5ZWQudmFsdWUpIHsNCiAgICAgICAgICByZXR1cm4gY3JlYXRlVk5vZGUobG9hZGluZ0NvbXBvbmVudCk7DQogICAgICAgIH0NCiAgICAgIH07DQogICAgfQ0KICB9KTsNCn0NCmZ1bmN0aW9uIGNyZWF0ZUlubmVyQ29tcChjb21wLCBwYXJlbnQpIHsNCiAgY29uc3QgeyByZWY6IHJlZjIsIHByb3BzLCBjaGlsZHJlbiwgY2UgfSA9IHBhcmVudC52bm9kZTsNCiAgY29uc3Qgdm5vZGUgPSBjcmVhdGVWTm9kZShjb21wLCBwcm9wcywgY2hpbGRyZW4pOw0KICB2bm9kZS5yZWYgPSByZWYyOw0KICB2bm9kZS5jZSA9IGNlOw0KICBkZWxldGUgcGFyZW50LnZub2RlLmNlOw0KICByZXR1cm4gdm5vZGU7DQp9DQoNCmNvbnN0IGlzS2VlcEFsaXZlID0gKHZub2RlKSA9PiB2bm9kZS50eXBlLl9faXNLZWVwQWxpdmU7DQpjb25zdCBLZWVwQWxpdmVJbXBsID0gew0KICBuYW1lOiBgS2VlcEFsaXZlYCwNCiAgLy8gTWFya2VyIGZvciBzcGVjaWFsIGhhbmRsaW5nIGluc2lkZSB0aGUgcmVuZGVyZXIuIFdlIGFyZSBub3QgdXNpbmcgYSA9PT0NCiAgLy8gY2hlY2sgZGlyZWN0bHkgb24gS2VlcEFsaXZlIGluIHRoZSByZW5kZXJlciwgYmVjYXVzZSBpbXBvcnRpbmcgaXQgZGlyZWN0bHkNCiAgLy8gd291bGQgcHJldmVudCBpdCBmcm9tIGJlaW5nIHRyZWUtc2hha2VuLg0KICBfX2lzS2VlcEFsaXZlOiB0cnVlLA0KICBwcm9wczogew0KICAgIGluY2x1ZGU6IFtTdHJpbmcsIFJlZ0V4cCwgQXJyYXldLA0KICAgIGV4Y2x1ZGU6IFtTdHJpbmcsIFJlZ0V4cCwgQXJyYXldLA0KICAgIG1heDogW1N0cmluZywgTnVtYmVyXQ0KICB9LA0KICBzZXR1cChwcm9wcywgeyBzbG90cyB9KSB7DQogICAgY29uc3QgaW5zdGFuY2UgPSBnZXRDdXJyZW50SW5zdGFuY2UoKTsNCiAgICBjb25zdCBzaGFyZWRDb250ZXh0ID0gaW5zdGFuY2UuY3R4Ow0KICAgIGlmICghc2hhcmVkQ29udGV4dC5yZW5kZXJlcikgew0KICAgICAgcmV0dXJuICgpID0+IHsNCiAgICAgICAgY29uc3QgY2hpbGRyZW4gPSBzbG90cy5kZWZhdWx0ICYmIHNsb3RzLmRlZmF1bHQoKTsNCiAgICAgICAgcmV0dXJuIGNoaWxkcmVuICYmIGNoaWxkcmVuLmxlbmd0aCA9PT0gMSA/IGNoaWxkcmVuWzBdIDogY2hpbGRyZW47DQogICAgICB9Ow0KICAgIH0NCiAgICBjb25zdCBjYWNoZSA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7DQogICAgY29uc3Qga2V5cyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KCk7DQogICAgbGV0IGN1cnJlbnQgPSBudWxsOw0KICAgIHsNCiAgICAgIGluc3RhbmNlLl9fdl9jYWNoZSA9IGNhY2hlOw0KICAgIH0NCiAgICBjb25zdCBwYXJlbnRTdXNwZW5zZSA9IGluc3RhbmNlLnN1c3BlbnNlOw0KICAgIGNvbnN0IHsNCiAgICAgIHJlbmRlcmVyOiB7DQogICAgICAgIHA6IHBhdGNoLA0KICAgICAgICBtOiBtb3ZlLA0KICAgICAgICB1bTogX3VubW91bnQsDQogICAgICAgIG86IHsgY3JlYXRlRWxlbWVudCB9DQogICAgICB9DQogICAgfSA9IHNoYXJlZENvbnRleHQ7DQogICAgY29uc3Qgc3RvcmFnZUNvbnRhaW5lciA9IGNyZWF0ZUVsZW1lbnQoImRpdiIpOw0KICAgIHNoYXJlZENvbnRleHQuYWN0aXZhdGUgPSAodm5vZGUsIGNvbnRhaW5lciwgYW5jaG9yLCBuYW1lc3BhY2UsIG9wdGltaXplZCkgPT4gew0KICAgICAgY29uc3QgaW5zdGFuY2UyID0gdm5vZGUuY29tcG9uZW50Ow0KICAgICAgbW92ZSh2bm9kZSwgY29udGFpbmVyLCBhbmNob3IsIDAsIHBhcmVudFN1c3BlbnNlKTsNCiAgICAgIHBhdGNoKA0KICAgICAgICBpbnN0YW5jZTIudm5vZGUsDQogICAgICAgIHZub2RlLA0KICAgICAgICBjb250YWluZXIsDQogICAgICAgIGFuY2hvciwNCiAgICAgICAgaW5zdGFuY2UyLA0KICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICB2bm9kZS5zbG90U2NvcGVJZHMsDQogICAgICAgIG9wdGltaXplZA0KICAgICAgKTsNCiAgICAgIHF1ZXVlUG9zdFJlbmRlckVmZmVjdCgoKSA9PiB7DQogICAgICAgIGluc3RhbmNlMi5pc0RlYWN0aXZhdGVkID0gZmFsc2U7DQogICAgICAgIGlmIChpbnN0YW5jZTIuYSkgew0KICAgICAgICAgIGludm9rZUFycmF5Rm5zKGluc3RhbmNlMi5hKTsNCiAgICAgICAgfQ0KICAgICAgICBjb25zdCB2bm9kZUhvb2sgPSB2bm9kZS5wcm9wcyAmJiB2bm9kZS5wcm9wcy5vblZub2RlTW91bnRlZDsNCiAgICAgICAgaWYgKHZub2RlSG9vaykgew0KICAgICAgICAgIGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIGluc3RhbmNlMi5wYXJlbnQsIHZub2RlKTsNCiAgICAgICAgfQ0KICAgICAgfSwgcGFyZW50U3VzcGVuc2UpOw0KICAgICAgew0KICAgICAgICBkZXZ0b29sc0NvbXBvbmVudEFkZGVkKGluc3RhbmNlMik7DQogICAgICB9DQogICAgfTsNCiAgICBzaGFyZWRDb250ZXh0LmRlYWN0aXZhdGUgPSAodm5vZGUpID0+IHsNCiAgICAgIGNvbnN0IGluc3RhbmNlMiA9IHZub2RlLmNvbXBvbmVudDsNCiAgICAgIGludmFsaWRhdGVNb3VudChpbnN0YW5jZTIubSk7DQogICAgICBpbnZhbGlkYXRlTW91bnQoaW5zdGFuY2UyLmEpOw0KICAgICAgbW92ZSh2bm9kZSwgc3RvcmFnZUNvbnRhaW5lciwgbnVsbCwgMSwgcGFyZW50U3VzcGVuc2UpOw0KICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KCgpID0+IHsNCiAgICAgICAgaWYgKGluc3RhbmNlMi5kYSkgew0KICAgICAgICAgIGludm9rZUFycmF5Rm5zKGluc3RhbmNlMi5kYSk7DQogICAgICAgIH0NCiAgICAgICAgY29uc3Qgdm5vZGVIb29rID0gdm5vZGUucHJvcHMgJiYgdm5vZGUucHJvcHMub25Wbm9kZVVubW91bnRlZDsNCiAgICAgICAgaWYgKHZub2RlSG9vaykgew0KICAgICAgICAgIGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIGluc3RhbmNlMi5wYXJlbnQsIHZub2RlKTsNCiAgICAgICAgfQ0KICAgICAgICBpbnN0YW5jZTIuaXNEZWFjdGl2YXRlZCA9IHRydWU7DQogICAgICB9LCBwYXJlbnRTdXNwZW5zZSk7DQogICAgICB7DQogICAgICAgIGRldnRvb2xzQ29tcG9uZW50QWRkZWQoaW5zdGFuY2UyKTsNCiAgICAgIH0NCiAgICAgIHsNCiAgICAgICAgaW5zdGFuY2UyLl9fa2VlcEFsaXZlU3RvcmFnZUNvbnRhaW5lciA9IHN0b3JhZ2VDb250YWluZXI7DQogICAgICB9DQogICAgfTsNCiAgICBmdW5jdGlvbiB1bm1vdW50KHZub2RlKSB7DQogICAgICByZXNldFNoYXBlRmxhZyh2bm9kZSk7DQogICAgICBfdW5tb3VudCh2bm9kZSwgaW5zdGFuY2UsIHBhcmVudFN1c3BlbnNlLCB0cnVlKTsNCiAgICB9DQogICAgZnVuY3Rpb24gcHJ1bmVDYWNoZShmaWx0ZXIpIHsNCiAgICAgIGNhY2hlLmZvckVhY2goKHZub2RlLCBrZXkpID0+IHsNCiAgICAgICAgY29uc3QgbmFtZSA9IGdldENvbXBvbmVudE5hbWUodm5vZGUudHlwZSk7DQogICAgICAgIGlmIChuYW1lICYmICFmaWx0ZXIobmFtZSkpIHsNCiAgICAgICAgICBwcnVuZUNhY2hlRW50cnkoa2V5KTsNCiAgICAgICAgfQ0KICAgICAgfSk7DQogICAgfQ0KICAgIGZ1bmN0aW9uIHBydW5lQ2FjaGVFbnRyeShrZXkpIHsNCiAgICAgIGNvbnN0IGNhY2hlZCA9IGNhY2hlLmdldChrZXkpOw0KICAgICAgaWYgKGNhY2hlZCAmJiAoIWN1cnJlbnQgfHwgIWlzU2FtZVZOb2RlVHlwZShjYWNoZWQsIGN1cnJlbnQpKSkgew0KICAgICAgICB1bm1vdW50KGNhY2hlZCk7DQogICAgICB9IGVsc2UgaWYgKGN1cnJlbnQpIHsNCiAgICAgICAgcmVzZXRTaGFwZUZsYWcoY3VycmVudCk7DQogICAgICB9DQogICAgICBjYWNoZS5kZWxldGUoa2V5KTsNCiAgICAgIGtleXMuZGVsZXRlKGtleSk7DQogICAgfQ0KICAgIHdhdGNoKA0KICAgICAgKCkgPT4gW3Byb3BzLmluY2x1ZGUsIHByb3BzLmV4Y2x1ZGVdLA0KICAgICAgKFtpbmNsdWRlLCBleGNsdWRlXSkgPT4gew0KICAgICAgICBpbmNsdWRlICYmIHBydW5lQ2FjaGUoKG5hbWUpID0+IG1hdGNoZXMoaW5jbHVkZSwgbmFtZSkpOw0KICAgICAgICBleGNsdWRlICYmIHBydW5lQ2FjaGUoKG5hbWUpID0+ICFtYXRjaGVzKGV4Y2x1ZGUsIG5hbWUpKTsNCiAgICAgIH0sDQogICAgICAvLyBwcnVuZSBwb3N0LXJlbmRlciBhZnRlciBgY3VycmVudGAgaGFzIGJlZW4gdXBkYXRlZA0KICAgICAgeyBmbHVzaDogInBvc3QiLCBkZWVwOiB0cnVlIH0NCiAgICApOw0KICAgIGxldCBwZW5kaW5nQ2FjaGVLZXkgPSBudWxsOw0KICAgIGNvbnN0IGNhY2hlU3VidHJlZSA9ICgpID0+IHsNCiAgICAgIGlmIChwZW5kaW5nQ2FjaGVLZXkgIT0gbnVsbCkgew0KICAgICAgICBpZiAoaXNTdXNwZW5zZShpbnN0YW5jZS5zdWJUcmVlLnR5cGUpKSB7DQogICAgICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KCgpID0+IHsNCiAgICAgICAgICAgIGNhY2hlLnNldChwZW5kaW5nQ2FjaGVLZXksIGdldElubmVyQ2hpbGQoaW5zdGFuY2Uuc3ViVHJlZSkpOw0KICAgICAgICAgIH0sIGluc3RhbmNlLnN1YlRyZWUuc3VzcGVuc2UpOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIGNhY2hlLnNldChwZW5kaW5nQ2FjaGVLZXksIGdldElubmVyQ2hpbGQoaW5zdGFuY2Uuc3ViVHJlZSkpOw0KICAgICAgICB9DQogICAgICB9DQogICAgfTsNCiAgICBvbk1vdW50ZWQoY2FjaGVTdWJ0cmVlKTsNCiAgICBvblVwZGF0ZWQoY2FjaGVTdWJ0cmVlKTsNCiAgICBvbkJlZm9yZVVubW91bnQoKCkgPT4gew0KICAgICAgY2FjaGUuZm9yRWFjaCgoY2FjaGVkKSA9PiB7DQogICAgICAgIGNvbnN0IHsgc3ViVHJlZSwgc3VzcGVuc2UgfSA9IGluc3RhbmNlOw0KICAgICAgICBjb25zdCB2bm9kZSA9IGdldElubmVyQ2hpbGQoc3ViVHJlZSk7DQogICAgICAgIGlmIChjYWNoZWQudHlwZSA9PT0gdm5vZGUudHlwZSAmJiBjYWNoZWQua2V5ID09PSB2bm9kZS5rZXkpIHsNCiAgICAgICAgICByZXNldFNoYXBlRmxhZyh2bm9kZSk7DQogICAgICAgICAgY29uc3QgZGEgPSB2bm9kZS5jb21wb25lbnQuZGE7DQogICAgICAgICAgZGEgJiYgcXVldWVQb3N0UmVuZGVyRWZmZWN0KGRhLCBzdXNwZW5zZSk7DQogICAgICAgICAgcmV0dXJuOw0KICAgICAgICB9DQogICAgICAgIHVubW91bnQoY2FjaGVkKTsNCiAgICAgIH0pOw0KICAgIH0pOw0KICAgIHJldHVybiAoKSA9PiB7DQogICAgICBwZW5kaW5nQ2FjaGVLZXkgPSBudWxsOw0KICAgICAgaWYgKCFzbG90cy5kZWZhdWx0KSB7DQogICAgICAgIHJldHVybiBjdXJyZW50ID0gbnVsbDsNCiAgICAgIH0NCiAgICAgIGNvbnN0IGNoaWxkcmVuID0gc2xvdHMuZGVmYXVsdCgpOw0KICAgICAgY29uc3QgcmF3Vk5vZGUgPSBjaGlsZHJlblswXTsNCiAgICAgIGlmIChjaGlsZHJlbi5sZW5ndGggPiAxKSB7DQogICAgICAgIHsNCiAgICAgICAgICB3YXJuJDEoYEtlZXBBbGl2ZSBzaG91bGQgY29udGFpbiBleGFjdGx5IG9uZSBjb21wb25lbnQgY2hpbGQuYCk7DQogICAgICAgIH0NCiAgICAgICAgY3VycmVudCA9IG51bGw7DQogICAgICAgIHJldHVybiBjaGlsZHJlbjsNCiAgICAgIH0gZWxzZSBpZiAoIWlzVk5vZGUocmF3Vk5vZGUpIHx8ICEocmF3Vk5vZGUuc2hhcGVGbGFnICYgNCkgJiYgIShyYXdWTm9kZS5zaGFwZUZsYWcgJiAxMjgpKSB7DQogICAgICAgIGN1cnJlbnQgPSBudWxsOw0KICAgICAgICByZXR1cm4gcmF3Vk5vZGU7DQogICAgICB9DQogICAgICBsZXQgdm5vZGUgPSBnZXRJbm5lckNoaWxkKHJhd1ZOb2RlKTsNCiAgICAgIGlmICh2bm9kZS50eXBlID09PSBDb21tZW50KSB7DQogICAgICAgIGN1cnJlbnQgPSBudWxsOw0KICAgICAgICByZXR1cm4gdm5vZGU7DQogICAgICB9DQogICAgICBjb25zdCBjb21wID0gdm5vZGUudHlwZTsNCiAgICAgIGNvbnN0IG5hbWUgPSBnZXRDb21wb25lbnROYW1lKA0KICAgICAgICBpc0FzeW5jV3JhcHBlcih2bm9kZSkgPyB2bm9kZS50eXBlLl9fYXN5bmNSZXNvbHZlZCB8fCB7fSA6IGNvbXANCiAgICAgICk7DQogICAgICBjb25zdCB7IGluY2x1ZGUsIGV4Y2x1ZGUsIG1heCB9ID0gcHJvcHM7DQogICAgICBpZiAoaW5jbHVkZSAmJiAoIW5hbWUgfHwgIW1hdGNoZXMoaW5jbHVkZSwgbmFtZSkpIHx8IGV4Y2x1ZGUgJiYgbmFtZSAmJiBtYXRjaGVzKGV4Y2x1ZGUsIG5hbWUpKSB7DQogICAgICAgIHZub2RlLnNoYXBlRmxhZyAmPSAtMjU3Ow0KICAgICAgICBjdXJyZW50ID0gdm5vZGU7DQogICAgICAgIHJldHVybiByYXdWTm9kZTsNCiAgICAgIH0NCiAgICAgIGNvbnN0IGtleSA9IHZub2RlLmtleSA9PSBudWxsID8gY29tcCA6IHZub2RlLmtleTsNCiAgICAgIGNvbnN0IGNhY2hlZFZOb2RlID0gY2FjaGUuZ2V0KGtleSk7DQogICAgICBpZiAodm5vZGUuZWwpIHsNCiAgICAgICAgdm5vZGUgPSBjbG9uZVZOb2RlKHZub2RlKTsNCiAgICAgICAgaWYgKHJhd1ZOb2RlLnNoYXBlRmxhZyAmIDEyOCkgew0KICAgICAgICAgIHJhd1ZOb2RlLnNzQ29udGVudCA9IHZub2RlOw0KICAgICAgICB9DQogICAgICB9DQogICAgICBwZW5kaW5nQ2FjaGVLZXkgPSBrZXk7DQogICAgICBpZiAoY2FjaGVkVk5vZGUpIHsNCiAgICAgICAgdm5vZGUuZWwgPSBjYWNoZWRWTm9kZS5lbDsNCiAgICAgICAgdm5vZGUuY29tcG9uZW50ID0gY2FjaGVkVk5vZGUuY29tcG9uZW50Ow0KICAgICAgICBpZiAodm5vZGUudHJhbnNpdGlvbikgew0KICAgICAgICAgIHNldFRyYW5zaXRpb25Ib29rcyh2bm9kZSwgdm5vZGUudHJhbnNpdGlvbik7DQogICAgICAgIH0NCiAgICAgICAgdm5vZGUuc2hhcGVGbGFnIHw9IDUxMjsNCiAgICAgICAga2V5cy5kZWxldGUoa2V5KTsNCiAgICAgICAga2V5cy5hZGQoa2V5KTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGtleXMuYWRkKGtleSk7DQogICAgICAgIGlmIChtYXggJiYga2V5cy5zaXplID4gcGFyc2VJbnQobWF4LCAxMCkpIHsNCiAgICAgICAgICBwcnVuZUNhY2hlRW50cnkoa2V5cy52YWx1ZXMoKS5uZXh0KCkudmFsdWUpOw0KICAgICAgICB9DQogICAgICB9DQogICAgICB2bm9kZS5zaGFwZUZsYWcgfD0gMjU2Ow0KICAgICAgY3VycmVudCA9IHZub2RlOw0KICAgICAgcmV0dXJuIGlzU3VzcGVuc2UocmF3Vk5vZGUudHlwZSkgPyByYXdWTm9kZSA6IHZub2RlOw0KICAgIH07DQogIH0NCn07DQpjb25zdCBLZWVwQWxpdmUgPSBLZWVwQWxpdmVJbXBsOw0KZnVuY3Rpb24gbWF0Y2hlcyhwYXR0ZXJuLCBuYW1lKSB7DQogIGlmIChpc0FycmF5KHBhdHRlcm4pKSB7DQogICAgcmV0dXJuIHBhdHRlcm4uc29tZSgocCkgPT4gbWF0Y2hlcyhwLCBuYW1lKSk7DQogIH0gZWxzZSBpZiAoaXNTdHJpbmcocGF0dGVybikpIHsNCiAgICByZXR1cm4gcGF0dGVybi5zcGxpdCgiLCIpLmluY2x1ZGVzKG5hbWUpOw0KICB9IGVsc2UgaWYgKGlzUmVnRXhwKHBhdHRlcm4pKSB7DQogICAgcGF0dGVybi5sYXN0SW5kZXggPSAwOw0KICAgIHJldHVybiBwYXR0ZXJuLnRlc3QobmFtZSk7DQogIH0NCiAgcmV0dXJuIGZhbHNlOw0KfQ0KZnVuY3Rpb24gb25BY3RpdmF0ZWQoaG9vaywgdGFyZ2V0KSB7DQogIHJlZ2lzdGVyS2VlcEFsaXZlSG9vayhob29rLCAiYSIsIHRhcmdldCk7DQp9DQpmdW5jdGlvbiBvbkRlYWN0aXZhdGVkKGhvb2ssIHRhcmdldCkgew0KICByZWdpc3RlcktlZXBBbGl2ZUhvb2soaG9vaywgImRhIiwgdGFyZ2V0KTsNCn0NCmZ1bmN0aW9uIHJlZ2lzdGVyS2VlcEFsaXZlSG9vayhob29rLCB0eXBlLCB0YXJnZXQgPSBjdXJyZW50SW5zdGFuY2UpIHsNCiAgY29uc3Qgd3JhcHBlZEhvb2sgPSBob29rLl9fd2RjIHx8IChob29rLl9fd2RjID0gKCkgPT4gew0KICAgIGxldCBjdXJyZW50ID0gdGFyZ2V0Ow0KICAgIHdoaWxlIChjdXJyZW50KSB7DQogICAgICBpZiAoY3VycmVudC5pc0RlYWN0aXZhdGVkKSB7DQogICAgICAgIHJldHVybjsNCiAgICAgIH0NCiAgICAgIGN1cnJlbnQgPSBjdXJyZW50LnBhcmVudDsNCiAgICB9DQogICAgcmV0dXJuIGhvb2soKTsNCiAgfSk7DQogIGluamVjdEhvb2sodHlwZSwgd3JhcHBlZEhvb2ssIHRhcmdldCk7DQogIGlmICh0YXJnZXQpIHsNCiAgICBsZXQgY3VycmVudCA9IHRhcmdldC5wYXJlbnQ7DQogICAgd2hpbGUgKGN1cnJlbnQgJiYgY3VycmVudC5wYXJlbnQpIHsNCiAgICAgIGlmIChpc0tlZXBBbGl2ZShjdXJyZW50LnBhcmVudC52bm9kZSkpIHsNCiAgICAgICAgaW5qZWN0VG9LZWVwQWxpdmVSb290KHdyYXBwZWRIb29rLCB0eXBlLCB0YXJnZXQsIGN1cnJlbnQpOw0KICAgICAgfQ0KICAgICAgY3VycmVudCA9IGN1cnJlbnQucGFyZW50Ow0KICAgIH0NCiAgfQ0KfQ0KZnVuY3Rpb24gaW5qZWN0VG9LZWVwQWxpdmVSb290KGhvb2ssIHR5cGUsIHRhcmdldCwga2VlcEFsaXZlUm9vdCkgew0KICBjb25zdCBpbmplY3RlZCA9IGluamVjdEhvb2soDQogICAgdHlwZSwNCiAgICBob29rLA0KICAgIGtlZXBBbGl2ZVJvb3QsDQogICAgdHJ1ZQ0KICAgIC8qIHByZXBlbmQgKi8NCiAgKTsNCiAgb25Vbm1vdW50ZWQoKCkgPT4gew0KICAgIHJlbW92ZShrZWVwQWxpdmVSb290W3R5cGVdLCBpbmplY3RlZCk7DQogIH0sIHRhcmdldCk7DQp9DQpmdW5jdGlvbiByZXNldFNoYXBlRmxhZyh2bm9kZSkgew0KICB2bm9kZS5zaGFwZUZsYWcgJj0gLTI1NzsNCiAgdm5vZGUuc2hhcGVGbGFnICY9IC01MTM7DQp9DQpmdW5jdGlvbiBnZXRJbm5lckNoaWxkKHZub2RlKSB7DQogIHJldHVybiB2bm9kZS5zaGFwZUZsYWcgJiAxMjggPyB2bm9kZS5zc0NvbnRlbnQgOiB2bm9kZTsNCn0NCg0KZnVuY3Rpb24gaW5qZWN0SG9vayh0eXBlLCBob29rLCB0YXJnZXQgPSBjdXJyZW50SW5zdGFuY2UsIHByZXBlbmQgPSBmYWxzZSkgew0KICBpZiAodGFyZ2V0KSB7DQogICAgY29uc3QgaG9va3MgPSB0YXJnZXRbdHlwZV0gfHwgKHRhcmdldFt0eXBlXSA9IFtdKTsNCiAgICBjb25zdCB3cmFwcGVkSG9vayA9IGhvb2suX193ZWggfHwgKGhvb2suX193ZWggPSAoLi4uYXJncykgPT4gew0KICAgICAgcGF1c2VUcmFja2luZygpOw0KICAgICAgY29uc3QgcmVzZXQgPSBzZXRDdXJyZW50SW5zdGFuY2UodGFyZ2V0KTsNCiAgICAgIGNvbnN0IHJlcyA9IGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nKGhvb2ssIHRhcmdldCwgdHlwZSwgYXJncyk7DQogICAgICByZXNldCgpOw0KICAgICAgcmVzZXRUcmFja2luZygpOw0KICAgICAgcmV0dXJuIHJlczsNCiAgICB9KTsNCiAgICBpZiAocHJlcGVuZCkgew0KICAgICAgaG9va3MudW5zaGlmdCh3cmFwcGVkSG9vayk7DQogICAgfSBlbHNlIHsNCiAgICAgIGhvb2tzLnB1c2god3JhcHBlZEhvb2spOw0KICAgIH0NCiAgICByZXR1cm4gd3JhcHBlZEhvb2s7DQogIH0gZWxzZSB7DQogICAgY29uc3QgYXBpTmFtZSA9IHRvSGFuZGxlcktleShFcnJvclR5cGVTdHJpbmdzJDFbdHlwZV0ucmVwbGFjZSgvIGhvb2skLywgIiIpKTsNCiAgICB3YXJuJDEoDQogICAgICBgJHthcGlOYW1lfSBpcyBjYWxsZWQgd2hlbiB0aGVyZSBpcyBubyBhY3RpdmUgY29tcG9uZW50IGluc3RhbmNlIHRvIGJlIGFzc29jaWF0ZWQgd2l0aC4gTGlmZWN5Y2xlIGluamVjdGlvbiBBUElzIGNhbiBvbmx5IGJlIHVzZWQgZHVyaW5nIGV4ZWN1dGlvbiBvZiBzZXR1cCgpLmAgKyAoYCBJZiB5b3UgYXJlIHVzaW5nIGFzeW5jIHNldHVwKCksIG1ha2Ugc3VyZSB0byByZWdpc3RlciBsaWZlY3ljbGUgaG9va3MgYmVmb3JlIHRoZSBmaXJzdCBhd2FpdCBzdGF0ZW1lbnQuYCApDQogICAgKTsNCiAgfQ0KfQ0KY29uc3QgY3JlYXRlSG9vayA9IChsaWZlY3ljbGUpID0+IChob29rLCB0YXJnZXQgPSBjdXJyZW50SW5zdGFuY2UpID0+IHsNCiAgaWYgKCFpc0luU1NSQ29tcG9uZW50U2V0dXAgfHwgbGlmZWN5Y2xlID09PSAic3AiKSB7DQogICAgaW5qZWN0SG9vayhsaWZlY3ljbGUsICguLi5hcmdzKSA9PiBob29rKC4uLmFyZ3MpLCB0YXJnZXQpOw0KICB9DQp9Ow0KY29uc3Qgb25CZWZvcmVNb3VudCA9IGNyZWF0ZUhvb2soImJtIik7DQpjb25zdCBvbk1vdW50ZWQgPSBjcmVhdGVIb29rKCJtIik7DQpjb25zdCBvbkJlZm9yZVVwZGF0ZSA9IGNyZWF0ZUhvb2soDQogICJidSINCik7DQpjb25zdCBvblVwZGF0ZWQgPSBjcmVhdGVIb29rKCJ1Iik7DQpjb25zdCBvbkJlZm9yZVVubW91bnQgPSBjcmVhdGVIb29rKA0KICAiYnVtIg0KKTsNCmNvbnN0IG9uVW5tb3VudGVkID0gY3JlYXRlSG9vaygidW0iKTsNCmNvbnN0IG9uU2VydmVyUHJlZmV0Y2ggPSBjcmVhdGVIb29rKA0KICAic3AiDQopOw0KY29uc3Qgb25SZW5kZXJUcmlnZ2VyZWQgPSBjcmVhdGVIb29rKCJydGciKTsNCmNvbnN0IG9uUmVuZGVyVHJhY2tlZCA9IGNyZWF0ZUhvb2soInJ0YyIpOw0KZnVuY3Rpb24gb25FcnJvckNhcHR1cmVkKGhvb2ssIHRhcmdldCA9IGN1cnJlbnRJbnN0YW5jZSkgew0KICBpbmplY3RIb29rKCJlYyIsIGhvb2ssIHRhcmdldCk7DQp9DQoNCmNvbnN0IENPTVBPTkVOVFMgPSAiY29tcG9uZW50cyI7DQpjb25zdCBESVJFQ1RJVkVTID0gImRpcmVjdGl2ZXMiOw0KZnVuY3Rpb24gcmVzb2x2ZUNvbXBvbmVudChuYW1lLCBtYXliZVNlbGZSZWZlcmVuY2UpIHsNCiAgcmV0dXJuIHJlc29sdmVBc3NldChDT01QT05FTlRTLCBuYW1lLCB0cnVlLCBtYXliZVNlbGZSZWZlcmVuY2UpIHx8IG5hbWU7DQp9DQpjb25zdCBOVUxMX0RZTkFNSUNfQ09NUE9ORU5UID0gU3ltYm9sLmZvcigidi1uZGMiKTsNCmZ1bmN0aW9uIHJlc29sdmVEeW5hbWljQ29tcG9uZW50KGNvbXBvbmVudCkgew0KICBpZiAoaXNTdHJpbmcoY29tcG9uZW50KSkgew0KICAgIHJldHVybiByZXNvbHZlQXNzZXQoQ09NUE9ORU5UUywgY29tcG9uZW50LCBmYWxzZSkgfHwgY29tcG9uZW50Ow0KICB9IGVsc2Ugew0KICAgIHJldHVybiBjb21wb25lbnQgfHwgTlVMTF9EWU5BTUlDX0NPTVBPTkVOVDsNCiAgfQ0KfQ0KZnVuY3Rpb24gcmVzb2x2ZURpcmVjdGl2ZShuYW1lKSB7DQogIHJldHVybiByZXNvbHZlQXNzZXQoRElSRUNUSVZFUywgbmFtZSk7DQp9DQpmdW5jdGlvbiByZXNvbHZlQXNzZXQodHlwZSwgbmFtZSwgd2Fybk1pc3NpbmcgPSB0cnVlLCBtYXliZVNlbGZSZWZlcmVuY2UgPSBmYWxzZSkgew0KICBjb25zdCBpbnN0YW5jZSA9IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSB8fCBjdXJyZW50SW5zdGFuY2U7DQogIGlmIChpbnN0YW5jZSkgew0KICAgIGNvbnN0IENvbXBvbmVudCA9IGluc3RhbmNlLnR5cGU7DQogICAgaWYgKHR5cGUgPT09IENPTVBPTkVOVFMpIHsNCiAgICAgIGNvbnN0IHNlbGZOYW1lID0gZ2V0Q29tcG9uZW50TmFtZSgNCiAgICAgICAgQ29tcG9uZW50LA0KICAgICAgICBmYWxzZQ0KICAgICAgKTsNCiAgICAgIGlmIChzZWxmTmFtZSAmJiAoc2VsZk5hbWUgPT09IG5hbWUgfHwgc2VsZk5hbWUgPT09IGNhbWVsaXplKG5hbWUpIHx8IHNlbGZOYW1lID09PSBjYXBpdGFsaXplKGNhbWVsaXplKG5hbWUpKSkpIHsNCiAgICAgICAgcmV0dXJuIENvbXBvbmVudDsNCiAgICAgIH0NCiAgICB9DQogICAgY29uc3QgcmVzID0gKA0KICAgICAgLy8gbG9jYWwgcmVnaXN0cmF0aW9uDQogICAgICAvLyBjaGVjayBpbnN0YW5jZVt0eXBlXSBmaXJzdCB3aGljaCBpcyByZXNvbHZlZCBmb3Igb3B0aW9ucyBBUEkNCiAgICAgIHJlc29sdmUoaW5zdGFuY2VbdHlwZV0gfHwgQ29tcG9uZW50W3R5cGVdLCBuYW1lKSB8fCAvLyBnbG9iYWwgcmVnaXN0cmF0aW9uDQogICAgICByZXNvbHZlKGluc3RhbmNlLmFwcENvbnRleHRbdHlwZV0sIG5hbWUpDQogICAgKTsNCiAgICBpZiAoIXJlcyAmJiBtYXliZVNlbGZSZWZlcmVuY2UpIHsNCiAgICAgIHJldHVybiBDb21wb25lbnQ7DQogICAgfQ0KICAgIGlmICh3YXJuTWlzc2luZyAmJiAhcmVzKSB7DQogICAgICBjb25zdCBleHRyYSA9IHR5cGUgPT09IENPTVBPTkVOVFMgPyBgDQpJZiB0aGlzIGlzIGEgbmF0aXZlIGN1c3RvbSBlbGVtZW50LCBtYWtlIHN1cmUgdG8gZXhjbHVkZSBpdCBmcm9tIGNvbXBvbmVudCByZXNvbHV0aW9uIHZpYSBjb21waWxlck9wdGlvbnMuaXNDdXN0b21FbGVtZW50LmAgOiBgYDsNCiAgICAgIHdhcm4kMShgRmFpbGVkIHRvIHJlc29sdmUgJHt0eXBlLnNsaWNlKDAsIC0xKX06ICR7bmFtZX0ke2V4dHJhfWApOw0KICAgIH0NCiAgICByZXR1cm4gcmVzOw0KICB9IGVsc2Ugew0KICAgIHdhcm4kMSgNCiAgICAgIGByZXNvbHZlJHtjYXBpdGFsaXplKHR5cGUuc2xpY2UoMCwgLTEpKX0gY2FuIG9ubHkgYmUgdXNlZCBpbiByZW5kZXIoKSBvciBzZXR1cCgpLmANCiAgICApOw0KICB9DQp9DQpmdW5jdGlvbiByZXNvbHZlKHJlZ2lzdHJ5LCBuYW1lKSB7DQogIHJldHVybiByZWdpc3RyeSAmJiAocmVnaXN0cnlbbmFtZV0gfHwgcmVnaXN0cnlbY2FtZWxpemUobmFtZSldIHx8IHJlZ2lzdHJ5W2NhcGl0YWxpemUoY2FtZWxpemUobmFtZSkpXSk7DQp9DQoNCmZ1bmN0aW9uIHJlbmRlckxpc3Qoc291cmNlLCByZW5kZXJJdGVtLCBjYWNoZSwgaW5kZXgpIHsNCiAgbGV0IHJldDsNCiAgY29uc3QgY2FjaGVkID0gY2FjaGUgJiYgY2FjaGVbaW5kZXhdOw0KICBjb25zdCBzb3VyY2VJc0FycmF5ID0gaXNBcnJheShzb3VyY2UpOw0KICBpZiAoc291cmNlSXNBcnJheSB8fCBpc1N0cmluZyhzb3VyY2UpKSB7DQogICAgY29uc3Qgc291cmNlSXNSZWFjdGl2ZUFycmF5ID0gc291cmNlSXNBcnJheSAmJiBpc1JlYWN0aXZlKHNvdXJjZSk7DQogICAgbGV0IG5lZWRzV3JhcCA9IGZhbHNlOw0KICAgIGxldCBpc1JlYWRvbmx5U291cmNlID0gZmFsc2U7DQogICAgaWYgKHNvdXJjZUlzUmVhY3RpdmVBcnJheSkgew0KICAgICAgbmVlZHNXcmFwID0gIWlzU2hhbGxvdyhzb3VyY2UpOw0KICAgICAgaXNSZWFkb25seVNvdXJjZSA9IGlzUmVhZG9ubHkoc291cmNlKTsNCiAgICAgIHNvdXJjZSA9IHNoYWxsb3dSZWFkQXJyYXkoc291cmNlKTsNCiAgICB9DQogICAgcmV0ID0gbmV3IEFycmF5KHNvdXJjZS5sZW5ndGgpOw0KICAgIGZvciAobGV0IGkgPSAwLCBsID0gc291cmNlLmxlbmd0aDsgaSA8IGw7IGkrKykgew0KICAgICAgcmV0W2ldID0gcmVuZGVySXRlbSgNCiAgICAgICAgbmVlZHNXcmFwID8gaXNSZWFkb25seVNvdXJjZSA/IHRvUmVhZG9ubHkodG9SZWFjdGl2ZShzb3VyY2VbaV0pKSA6IHRvUmVhY3RpdmUoc291cmNlW2ldKSA6IHNvdXJjZVtpXSwNCiAgICAgICAgaSwNCiAgICAgICAgdm9pZCAwLA0KICAgICAgICBjYWNoZWQgJiYgY2FjaGVkW2ldDQogICAgICApOw0KICAgIH0NCiAgfSBlbHNlIGlmICh0eXBlb2Ygc291cmNlID09PSAibnVtYmVyIikgew0KICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihzb3VyY2UpKSB7DQogICAgICB3YXJuJDEoYFRoZSB2LWZvciByYW5nZSBleHBlY3QgYW4gaW50ZWdlciB2YWx1ZSBidXQgZ290ICR7c291cmNlfS5gKTsNCiAgICB9DQogICAgcmV0ID0gbmV3IEFycmF5KHNvdXJjZSk7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzb3VyY2U7IGkrKykgew0KICAgICAgcmV0W2ldID0gcmVuZGVySXRlbShpICsgMSwgaSwgdm9pZCAwLCBjYWNoZWQgJiYgY2FjaGVkW2ldKTsNCiAgICB9DQogIH0gZWxzZSBpZiAoaXNPYmplY3Qoc291cmNlKSkgew0KICAgIGlmIChzb3VyY2VbU3ltYm9sLml0ZXJhdG9yXSkgew0KICAgICAgcmV0ID0gQXJyYXkuZnJvbSgNCiAgICAgICAgc291cmNlLA0KICAgICAgICAoaXRlbSwgaSkgPT4gcmVuZGVySXRlbShpdGVtLCBpLCB2b2lkIDAsIGNhY2hlZCAmJiBjYWNoZWRbaV0pDQogICAgICApOw0KICAgIH0gZWxzZSB7DQogICAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoc291cmNlKTsNCiAgICAgIHJldCA9IG5ldyBBcnJheShrZXlzLmxlbmd0aCk7DQogICAgICBmb3IgKGxldCBpID0gMCwgbCA9IGtleXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7DQogICAgICAgIGNvbnN0IGtleSA9IGtleXNbaV07DQogICAgICAgIHJldFtpXSA9IHJlbmRlckl0ZW0oc291cmNlW2tleV0sIGtleSwgaSwgY2FjaGVkICYmIGNhY2hlZFtpXSk7DQogICAgICB9DQogICAgfQ0KICB9IGVsc2Ugew0KICAgIHJldCA9IFtdOw0KICB9DQogIGlmIChjYWNoZSkgew0KICAgIGNhY2hlW2luZGV4XSA9IHJldDsNCiAgfQ0KICByZXR1cm4gcmV0Ow0KfQ0KDQpmdW5jdGlvbiBjcmVhdGVTbG90cyhzbG90cywgZHluYW1pY1Nsb3RzKSB7DQogIGZvciAobGV0IGkgPSAwOyBpIDwgZHluYW1pY1Nsb3RzLmxlbmd0aDsgaSsrKSB7DQogICAgY29uc3Qgc2xvdCA9IGR5bmFtaWNTbG90c1tpXTsNCiAgICBpZiAoaXNBcnJheShzbG90KSkgew0KICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBzbG90Lmxlbmd0aDsgaisrKSB7DQogICAgICAgIHNsb3RzW3Nsb3Rbal0ubmFtZV0gPSBzbG90W2pdLmZuOw0KICAgICAgfQ0KICAgIH0gZWxzZSBpZiAoc2xvdCkgew0KICAgICAgc2xvdHNbc2xvdC5uYW1lXSA9IHNsb3Qua2V5ID8gKC4uLmFyZ3MpID0+IHsNCiAgICAgICAgY29uc3QgcmVzID0gc2xvdC5mbiguLi5hcmdzKTsNCiAgICAgICAgaWYgKHJlcykgcmVzLmtleSA9IHNsb3Qua2V5Ow0KICAgICAgICByZXR1cm4gcmVzOw0KICAgICAgfSA6IHNsb3QuZm47DQogICAgfQ0KICB9DQogIHJldHVybiBzbG90czsNCn0NCg0KZnVuY3Rpb24gcmVuZGVyU2xvdChzbG90cywgbmFtZSwgcHJvcHMgPSB7fSwgZmFsbGJhY2ssIG5vU2xvdHRlZCkgew0KICBpZiAoY3VycmVudFJlbmRlcmluZ0luc3RhbmNlLmNlIHx8IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZS5wYXJlbnQgJiYgaXNBc3luY1dyYXBwZXIoY3VycmVudFJlbmRlcmluZ0luc3RhbmNlLnBhcmVudCkgJiYgY3VycmVudFJlbmRlcmluZ0luc3RhbmNlLnBhcmVudC5jZSkgew0KICAgIGlmIChuYW1lICE9PSAiZGVmYXVsdCIpIHByb3BzLm5hbWUgPSBuYW1lOw0KICAgIHJldHVybiBvcGVuQmxvY2soKSwgY3JlYXRlQmxvY2soDQogICAgICBGcmFnbWVudCwNCiAgICAgIG51bGwsDQogICAgICBbY3JlYXRlVk5vZGUoInNsb3QiLCBwcm9wcywgZmFsbGJhY2sgJiYgZmFsbGJhY2soKSldLA0KICAgICAgNjQNCiAgICApOw0KICB9DQogIGxldCBzbG90ID0gc2xvdHNbbmFtZV07DQogIGlmIChzbG90ICYmIHNsb3QubGVuZ3RoID4gMSkgew0KICAgIHdhcm4kMSgNCiAgICAgIGBTU1Itb3B0aW1pemVkIHNsb3QgZnVuY3Rpb24gZGV0ZWN0ZWQgaW4gYSBub24tU1NSLW9wdGltaXplZCByZW5kZXIgZnVuY3Rpb24uIFlvdSBuZWVkIHRvIG1hcmsgdGhpcyBjb21wb25lbnQgd2l0aCAkZHluYW1pYy1zbG90cyBpbiB0aGUgcGFyZW50IHRlbXBsYXRlLmANCiAgICApOw0KICAgIHNsb3QgPSAoKSA9PiBbXTsNCiAgfQ0KICBpZiAoc2xvdCAmJiBzbG90Ll9jKSB7DQogICAgc2xvdC5fZCA9IGZhbHNlOw0KICB9DQogIG9wZW5CbG9jaygpOw0KICBjb25zdCB2YWxpZFNsb3RDb250ZW50ID0gc2xvdCAmJiBlbnN1cmVWYWxpZFZOb2RlKHNsb3QocHJvcHMpKTsNCiAgY29uc3Qgc2xvdEtleSA9IHByb3BzLmtleSB8fCAvLyBzbG90IGNvbnRlbnQgYXJyYXkgb2YgYSBkeW5hbWljIGNvbmRpdGlvbmFsIHNsb3QgbWF5IGhhdmUgYSBicmFuY2gNCiAgLy8ga2V5IGF0dGFjaGVkIGluIHRoZSBgY3JlYXRlU2xvdHNgIGhlbHBlciwgcmVzcGVjdCB0aGF0DQogIHZhbGlkU2xvdENvbnRlbnQgJiYgdmFsaWRTbG90Q29udGVudC5rZXk7DQogIGNvbnN0IHJlbmRlcmVkID0gY3JlYXRlQmxvY2soDQogICAgRnJhZ21lbnQsDQogICAgew0KICAgICAga2V5OiAoc2xvdEtleSAmJiAhaXNTeW1ib2woc2xvdEtleSkgPyBzbG90S2V5IDogYF8ke25hbWV9YCkgKyAvLyAjNzI1NiBmb3JjZSBkaWZmZXJlbnRpYXRlIGZhbGxiYWNrIGNvbnRlbnQgZnJvbSBhY3R1YWwgY29udGVudA0KICAgICAgKCF2YWxpZFNsb3RDb250ZW50ICYmIGZhbGxiYWNrID8gIl9mYiIgOiAiIikNCiAgICB9LA0KICAgIHZhbGlkU2xvdENvbnRlbnQgfHwgKGZhbGxiYWNrID8gZmFsbGJhY2soKSA6IFtdKSwNCiAgICB2YWxpZFNsb3RDb250ZW50ICYmIHNsb3RzLl8gPT09IDEgPyA2NCA6IC0yDQogICk7DQogIGlmICghbm9TbG90dGVkICYmIHJlbmRlcmVkLnNjb3BlSWQpIHsNCiAgICByZW5kZXJlZC5zbG90U2NvcGVJZHMgPSBbcmVuZGVyZWQuc2NvcGVJZCArICItcyJdOw0KICB9DQogIGlmIChzbG90ICYmIHNsb3QuX2MpIHsNCiAgICBzbG90Ll9kID0gdHJ1ZTsNCiAgfQ0KICByZXR1cm4gcmVuZGVyZWQ7DQp9DQpmdW5jdGlvbiBlbnN1cmVWYWxpZFZOb2RlKHZub2Rlcykgew0KICByZXR1cm4gdm5vZGVzLnNvbWUoKGNoaWxkKSA9PiB7DQogICAgaWYgKCFpc1ZOb2RlKGNoaWxkKSkgcmV0dXJuIHRydWU7DQogICAgaWYgKGNoaWxkLnR5cGUgPT09IENvbW1lbnQpIHJldHVybiBmYWxzZTsNCiAgICBpZiAoY2hpbGQudHlwZSA9PT0gRnJhZ21lbnQgJiYgIWVuc3VyZVZhbGlkVk5vZGUoY2hpbGQuY2hpbGRyZW4pKQ0KICAgICAgcmV0dXJuIGZhbHNlOw0KICAgIHJldHVybiB0cnVlOw0KICB9KSA/IHZub2RlcyA6IG51bGw7DQp9DQoNCmZ1bmN0aW9uIHRvSGFuZGxlcnMob2JqLCBwcmVzZXJ2ZUNhc2VJZk5lY2Vzc2FyeSkgew0KICBjb25zdCByZXQgPSB7fTsNCiAgaWYgKCFpc09iamVjdChvYmopKSB7DQogICAgd2FybiQxKGB2LW9uIHdpdGggbm8gYXJndW1lbnQgZXhwZWN0cyBhbiBvYmplY3QgdmFsdWUuYCk7DQogICAgcmV0dXJuIHJldDsNCiAgfQ0KICBmb3IgKGNvbnN0IGtleSBpbiBvYmopIHsNCiAgICByZXRbcHJlc2VydmVDYXNlSWZOZWNlc3NhcnkgJiYgL1tBLVpdLy50ZXN0KGtleSkgPyBgb246JHtrZXl9YCA6IHRvSGFuZGxlcktleShrZXkpXSA9IG9ialtrZXldOw0KICB9DQogIHJldHVybiByZXQ7DQp9DQoNCmNvbnN0IGdldFB1YmxpY0luc3RhbmNlID0gKGkpID0+IHsNCiAgaWYgKCFpKSByZXR1cm4gbnVsbDsNCiAgaWYgKGlzU3RhdGVmdWxDb21wb25lbnQoaSkpIHJldHVybiBnZXRDb21wb25lbnRQdWJsaWNJbnN0YW5jZShpKTsNCiAgcmV0dXJuIGdldFB1YmxpY0luc3RhbmNlKGkucGFyZW50KTsNCn07DQpjb25zdCBwdWJsaWNQcm9wZXJ0aWVzTWFwID0gKA0KICAvLyBNb3ZlIFBVUkUgbWFya2VyIHRvIG5ldyBsaW5lIHRvIHdvcmthcm91bmQgY29tcGlsZXIgZGlzY2FyZGluZyBpdA0KICAvLyBkdWUgdG8gdHlwZSBhbm5vdGF0aW9uDQogIC8qIEBfX1BVUkVfXyAqLyBleHRlbmQoLyogQF9fUFVSRV9fICovIE9iamVjdC5jcmVhdGUobnVsbCksIHsNCiAgICAkOiAoaSkgPT4gaSwNCiAgICAkZWw6IChpKSA9PiBpLnZub2RlLmVsLA0KICAgICRkYXRhOiAoaSkgPT4gaS5kYXRhLA0KICAgICRwcm9wczogKGkpID0+IHNoYWxsb3dSZWFkb25seShpLnByb3BzKSAsDQogICAgJGF0dHJzOiAoaSkgPT4gc2hhbGxvd1JlYWRvbmx5KGkuYXR0cnMpICwNCiAgICAkc2xvdHM6IChpKSA9PiBzaGFsbG93UmVhZG9ubHkoaS5zbG90cykgLA0KICAgICRyZWZzOiAoaSkgPT4gc2hhbGxvd1JlYWRvbmx5KGkucmVmcykgLA0KICAgICRwYXJlbnQ6IChpKSA9PiBnZXRQdWJsaWNJbnN0YW5jZShpLnBhcmVudCksDQogICAgJHJvb3Q6IChpKSA9PiBnZXRQdWJsaWNJbnN0YW5jZShpLnJvb3QpLA0KICAgICRob3N0OiAoaSkgPT4gaS5jZSwNCiAgICAkZW1pdDogKGkpID0+IGkuZW1pdCwNCiAgICAkb3B0aW9uczogKGkpID0+IHJlc29sdmVNZXJnZWRPcHRpb25zKGkpICwNCiAgICAkZm9yY2VVcGRhdGU6IChpKSA9PiBpLmYgfHwgKGkuZiA9ICgpID0+IHsNCiAgICAgIHF1ZXVlSm9iKGkudXBkYXRlKTsNCiAgICB9KSwNCiAgICAkbmV4dFRpY2s6IChpKSA9PiBpLm4gfHwgKGkubiA9IG5leHRUaWNrLmJpbmQoaS5wcm94eSkpLA0KICAgICR3YXRjaDogKGkpID0+IGluc3RhbmNlV2F0Y2guYmluZChpKSANCiAgfSkNCik7DQpjb25zdCBpc1Jlc2VydmVkUHJlZml4ID0gKGtleSkgPT4ga2V5ID09PSAiXyIgfHwga2V5ID09PSAiJCI7DQpjb25zdCBoYXNTZXR1cEJpbmRpbmcgPSAoc3RhdGUsIGtleSkgPT4gc3RhdGUgIT09IEVNUFRZX09CSiAmJiAhc3RhdGUuX19pc1NjcmlwdFNldHVwICYmIGhhc093bihzdGF0ZSwga2V5KTsNCmNvbnN0IFB1YmxpY0luc3RhbmNlUHJveHlIYW5kbGVycyA9IHsNCiAgZ2V0KHsgXzogaW5zdGFuY2UgfSwga2V5KSB7DQogICAgaWYgKGtleSA9PT0gIl9fdl9za2lwIikgew0KICAgICAgcmV0dXJuIHRydWU7DQogICAgfQ0KICAgIGNvbnN0IHsgY3R4LCBzZXR1cFN0YXRlLCBkYXRhLCBwcm9wcywgYWNjZXNzQ2FjaGUsIHR5cGUsIGFwcENvbnRleHQgfSA9IGluc3RhbmNlOw0KICAgIGlmIChrZXkgPT09ICJfX2lzVnVlIikgew0KICAgICAgcmV0dXJuIHRydWU7DQogICAgfQ0KICAgIGxldCBub3JtYWxpemVkUHJvcHM7DQogICAgaWYgKGtleVswXSAhPT0gIiQiKSB7DQogICAgICBjb25zdCBuID0gYWNjZXNzQ2FjaGVba2V5XTsNCiAgICAgIGlmIChuICE9PSB2b2lkIDApIHsNCiAgICAgICAgc3dpdGNoIChuKSB7DQogICAgICAgICAgY2FzZSAxIC8qIFNFVFVQICovOg0KICAgICAgICAgICAgcmV0dXJuIHNldHVwU3RhdGVba2V5XTsNCiAgICAgICAgICBjYXNlIDIgLyogREFUQSAqLzoNCiAgICAgICAgICAgIHJldHVybiBkYXRhW2tleV07DQogICAgICAgICAgY2FzZSA0IC8qIENPTlRFWFQgKi86DQogICAgICAgICAgICByZXR1cm4gY3R4W2tleV07DQogICAgICAgICAgY2FzZSAzIC8qIFBST1BTICovOg0KICAgICAgICAgICAgcmV0dXJuIHByb3BzW2tleV07DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSBpZiAoaGFzU2V0dXBCaW5kaW5nKHNldHVwU3RhdGUsIGtleSkpIHsNCiAgICAgICAgYWNjZXNzQ2FjaGVba2V5XSA9IDEgLyogU0VUVVAgKi87DQogICAgICAgIHJldHVybiBzZXR1cFN0YXRlW2tleV07DQogICAgICB9IGVsc2UgaWYgKGRhdGEgIT09IEVNUFRZX09CSiAmJiBoYXNPd24oZGF0YSwga2V5KSkgew0KICAgICAgICBhY2Nlc3NDYWNoZVtrZXldID0gMiAvKiBEQVRBICovOw0KICAgICAgICByZXR1cm4gZGF0YVtrZXldOw0KICAgICAgfSBlbHNlIGlmICgNCiAgICAgICAgLy8gb25seSBjYWNoZSBvdGhlciBwcm9wZXJ0aWVzIHdoZW4gaW5zdGFuY2UgaGFzIGRlY2xhcmVkICh0aHVzIHN0YWJsZSkNCiAgICAgICAgLy8gcHJvcHMNCiAgICAgICAgKG5vcm1hbGl6ZWRQcm9wcyA9IGluc3RhbmNlLnByb3BzT3B0aW9uc1swXSkgJiYgaGFzT3duKG5vcm1hbGl6ZWRQcm9wcywga2V5KQ0KICAgICAgKSB7DQogICAgICAgIGFjY2Vzc0NhY2hlW2tleV0gPSAzIC8qIFBST1BTICovOw0KICAgICAgICByZXR1cm4gcHJvcHNba2V5XTsNCiAgICAgIH0gZWxzZSBpZiAoY3R4ICE9PSBFTVBUWV9PQkogJiYgaGFzT3duKGN0eCwga2V5KSkgew0KICAgICAgICBhY2Nlc3NDYWNoZVtrZXldID0gNCAvKiBDT05URVhUICovOw0KICAgICAgICByZXR1cm4gY3R4W2tleV07DQogICAgICB9IGVsc2UgaWYgKHNob3VsZENhY2hlQWNjZXNzKSB7DQogICAgICAgIGFjY2Vzc0NhY2hlW2tleV0gPSAwIC8qIE9USEVSICovOw0KICAgICAgfQ0KICAgIH0NCiAgICBjb25zdCBwdWJsaWNHZXR0ZXIgPSBwdWJsaWNQcm9wZXJ0aWVzTWFwW2tleV07DQogICAgbGV0IGNzc01vZHVsZSwgZ2xvYmFsUHJvcGVydGllczsNCiAgICBpZiAocHVibGljR2V0dGVyKSB7DQogICAgICBpZiAoa2V5ID09PSAiJGF0dHJzIikgew0KICAgICAgICB0cmFjayhpbnN0YW5jZS5hdHRycywgImdldCIsICIiKTsNCiAgICAgICAgbWFya0F0dHJzQWNjZXNzZWQoKTsNCiAgICAgIH0gZWxzZSBpZiAoa2V5ID09PSAiJHNsb3RzIikgew0KICAgICAgICB0cmFjayhpbnN0YW5jZSwgImdldCIsIGtleSk7DQogICAgICB9DQogICAgICByZXR1cm4gcHVibGljR2V0dGVyKGluc3RhbmNlKTsNCiAgICB9IGVsc2UgaWYgKA0KICAgICAgLy8gY3NzIG1vZHVsZSAoaW5qZWN0ZWQgYnkgdnVlLWxvYWRlcikNCiAgICAgIChjc3NNb2R1bGUgPSB0eXBlLl9fY3NzTW9kdWxlcykgJiYgKGNzc01vZHVsZSA9IGNzc01vZHVsZVtrZXldKQ0KICAgICkgew0KICAgICAgcmV0dXJuIGNzc01vZHVsZTsNCiAgICB9IGVsc2UgaWYgKGN0eCAhPT0gRU1QVFlfT0JKICYmIGhhc093bihjdHgsIGtleSkpIHsNCiAgICAgIGFjY2Vzc0NhY2hlW2tleV0gPSA0IC8qIENPTlRFWFQgKi87DQogICAgICByZXR1cm4gY3R4W2tleV07DQogICAgfSBlbHNlIGlmICgNCiAgICAgIC8vIGdsb2JhbCBwcm9wZXJ0aWVzDQogICAgICBnbG9iYWxQcm9wZXJ0aWVzID0gYXBwQ29udGV4dC5jb25maWcuZ2xvYmFsUHJvcGVydGllcywgaGFzT3duKGdsb2JhbFByb3BlcnRpZXMsIGtleSkNCiAgICApIHsNCiAgICAgIHsNCiAgICAgICAgcmV0dXJuIGdsb2JhbFByb3BlcnRpZXNba2V5XTsNCiAgICAgIH0NCiAgICB9IGVsc2UgaWYgKGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSAmJiAoIWlzU3RyaW5nKGtleSkgfHwgLy8gIzEwOTEgYXZvaWQgaW50ZXJuYWwgaXNSZWYvaXNWTm9kZSBjaGVja3Mgb24gY29tcG9uZW50IGluc3RhbmNlIGxlYWRpbmcNCiAgICAvLyB0byBpbmZpbml0ZSB3YXJuaW5nIGxvb3ANCiAgICBrZXkuaW5kZXhPZigiX192IikgIT09IDApKSB7DQogICAgICBpZiAoZGF0YSAhPT0gRU1QVFlfT0JKICYmIGlzUmVzZXJ2ZWRQcmVmaXgoa2V5WzBdKSAmJiBoYXNPd24oZGF0YSwga2V5KSkgew0KICAgICAgICB3YXJuJDEoDQogICAgICAgICAgYFByb3BlcnR5ICR7SlNPTi5zdHJpbmdpZnkoDQogICAgICAgICAgICBrZXkNCiAgICAgICAgICApfSBtdXN0IGJlIGFjY2Vzc2VkIHZpYSAkZGF0YSBiZWNhdXNlIGl0IHN0YXJ0cyB3aXRoIGEgcmVzZXJ2ZWQgY2hhcmFjdGVyICgiJCIgb3IgIl8iKSBhbmQgaXMgbm90IHByb3hpZWQgb24gdGhlIHJlbmRlciBjb250ZXh0LmANCiAgICAgICAgKTsNCiAgICAgIH0gZWxzZSBpZiAoaW5zdGFuY2UgPT09IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSkgew0KICAgICAgICB3YXJuJDEoDQogICAgICAgICAgYFByb3BlcnR5ICR7SlNPTi5zdHJpbmdpZnkoa2V5KX0gd2FzIGFjY2Vzc2VkIGR1cmluZyByZW5kZXIgYnV0IGlzIG5vdCBkZWZpbmVkIG9uIGluc3RhbmNlLmANCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICB9DQogIH0sDQogIHNldCh7IF86IGluc3RhbmNlIH0sIGtleSwgdmFsdWUpIHsNCiAgICBjb25zdCB7IGRhdGEsIHNldHVwU3RhdGUsIGN0eCB9ID0gaW5zdGFuY2U7DQogICAgaWYgKGhhc1NldHVwQmluZGluZyhzZXR1cFN0YXRlLCBrZXkpKSB7DQogICAgICBzZXR1cFN0YXRlW2tleV0gPSB2YWx1ZTsNCiAgICAgIHJldHVybiB0cnVlOw0KICAgIH0gZWxzZSBpZiAoc2V0dXBTdGF0ZS5fX2lzU2NyaXB0U2V0dXAgJiYgaGFzT3duKHNldHVwU3RhdGUsIGtleSkpIHsNCiAgICAgIHdhcm4kMShgQ2Fubm90IG11dGF0ZSA8c2NyaXB0IHNldHVwPiBiaW5kaW5nICIke2tleX0iIGZyb20gT3B0aW9ucyBBUEkuYCk7DQogICAgICByZXR1cm4gZmFsc2U7DQogICAgfSBlbHNlIGlmIChkYXRhICE9PSBFTVBUWV9PQkogJiYgaGFzT3duKGRhdGEsIGtleSkpIHsNCiAgICAgIGRhdGFba2V5XSA9IHZhbHVlOw0KICAgICAgcmV0dXJuIHRydWU7DQogICAgfSBlbHNlIGlmIChoYXNPd24oaW5zdGFuY2UucHJvcHMsIGtleSkpIHsNCiAgICAgIHdhcm4kMShgQXR0ZW1wdGluZyB0byBtdXRhdGUgcHJvcCAiJHtrZXl9Ii4gUHJvcHMgYXJlIHJlYWRvbmx5LmApOw0KICAgICAgcmV0dXJuIGZhbHNlOw0KICAgIH0NCiAgICBpZiAoa2V5WzBdID09PSAiJCIgJiYga2V5LnNsaWNlKDEpIGluIGluc3RhbmNlKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGBBdHRlbXB0aW5nIHRvIG11dGF0ZSBwdWJsaWMgcHJvcGVydHkgIiR7a2V5fSIuIFByb3BlcnRpZXMgc3RhcnRpbmcgd2l0aCAkIGFyZSByZXNlcnZlZCBhbmQgcmVhZG9ubHkuYA0KICAgICAgKTsNCiAgICAgIHJldHVybiBmYWxzZTsNCiAgICB9IGVsc2Ugew0KICAgICAgaWYgKGtleSBpbiBpbnN0YW5jZS5hcHBDb250ZXh0LmNvbmZpZy5nbG9iYWxQcm9wZXJ0aWVzKSB7DQogICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIGtleSwgew0KICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsDQogICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLA0KICAgICAgICAgIHZhbHVlDQogICAgICAgIH0pOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgY3R4W2tleV0gPSB2YWx1ZTsNCiAgICAgIH0NCiAgICB9DQogICAgcmV0dXJuIHRydWU7DQogIH0sDQogIGhhcyh7DQogICAgXzogeyBkYXRhLCBzZXR1cFN0YXRlLCBhY2Nlc3NDYWNoZSwgY3R4LCBhcHBDb250ZXh0LCBwcm9wc09wdGlvbnMgfQ0KICB9LCBrZXkpIHsNCiAgICBsZXQgbm9ybWFsaXplZFByb3BzOw0KICAgIHJldHVybiAhIWFjY2Vzc0NhY2hlW2tleV0gfHwgZGF0YSAhPT0gRU1QVFlfT0JKICYmIGhhc093bihkYXRhLCBrZXkpIHx8IGhhc1NldHVwQmluZGluZyhzZXR1cFN0YXRlLCBrZXkpIHx8IChub3JtYWxpemVkUHJvcHMgPSBwcm9wc09wdGlvbnNbMF0pICYmIGhhc093bihub3JtYWxpemVkUHJvcHMsIGtleSkgfHwgaGFzT3duKGN0eCwga2V5KSB8fCBoYXNPd24ocHVibGljUHJvcGVydGllc01hcCwga2V5KSB8fCBoYXNPd24oYXBwQ29udGV4dC5jb25maWcuZ2xvYmFsUHJvcGVydGllcywga2V5KTsNCiAgfSwNCiAgZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIGRlc2NyaXB0b3IpIHsNCiAgICBpZiAoZGVzY3JpcHRvci5nZXQgIT0gbnVsbCkgew0KICAgICAgdGFyZ2V0Ll8uYWNjZXNzQ2FjaGVba2V5XSA9IDA7DQogICAgfSBlbHNlIGlmIChoYXNPd24oZGVzY3JpcHRvciwgInZhbHVlIikpIHsNCiAgICAgIHRoaXMuc2V0KHRhcmdldCwga2V5LCBkZXNjcmlwdG9yLnZhbHVlLCBudWxsKTsNCiAgICB9DQogICAgcmV0dXJuIFJlZmxlY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIGRlc2NyaXB0b3IpOw0KICB9DQp9Ow0Kew0KICBQdWJsaWNJbnN0YW5jZVByb3h5SGFuZGxlcnMub3duS2V5cyA9ICh0YXJnZXQpID0+IHsNCiAgICB3YXJuJDEoDQogICAgICBgQXZvaWQgYXBwIGxvZ2ljIHRoYXQgcmVsaWVzIG9uIGVudW1lcmF0aW5nIGtleXMgb24gYSBjb21wb25lbnQgaW5zdGFuY2UuIFRoZSBrZXlzIHdpbGwgYmUgZW1wdHkgaW4gcHJvZHVjdGlvbiBtb2RlIHRvIGF2b2lkIHBlcmZvcm1hbmNlIG92ZXJoZWFkLmANCiAgICApOw0KICAgIHJldHVybiBSZWZsZWN0Lm93bktleXModGFyZ2V0KTsNCiAgfTsNCn0NCmNvbnN0IFJ1bnRpbWVDb21waWxlZFB1YmxpY0luc3RhbmNlUHJveHlIYW5kbGVycyA9IC8qIEBfX1BVUkVfXyAqLyBleHRlbmQoe30sIFB1YmxpY0luc3RhbmNlUHJveHlIYW5kbGVycywgew0KICBnZXQodGFyZ2V0LCBrZXkpIHsNCiAgICBpZiAoa2V5ID09PSBTeW1ib2wudW5zY29wYWJsZXMpIHsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgcmV0dXJuIFB1YmxpY0luc3RhbmNlUHJveHlIYW5kbGVycy5nZXQodGFyZ2V0LCBrZXksIHRhcmdldCk7DQogIH0sDQogIGhhcyhfLCBrZXkpIHsNCiAgICBjb25zdCBoYXMgPSBrZXlbMF0gIT09ICJfIiAmJiAhaXNHbG9iYWxseUFsbG93ZWQoa2V5KTsNCiAgICBpZiAoIWhhcyAmJiBQdWJsaWNJbnN0YW5jZVByb3h5SGFuZGxlcnMuaGFzKF8sIGtleSkpIHsNCiAgICAgIHdhcm4kMSgNCiAgICAgICAgYFByb3BlcnR5ICR7SlNPTi5zdHJpbmdpZnkoDQogICAgICAgICAga2V5DQogICAgICAgICl9IHNob3VsZCBub3Qgc3RhcnQgd2l0aCBfIHdoaWNoIGlzIGEgcmVzZXJ2ZWQgcHJlZml4IGZvciBWdWUgaW50ZXJuYWxzLmANCiAgICAgICk7DQogICAgfQ0KICAgIHJldHVybiBoYXM7DQogIH0NCn0pOw0KZnVuY3Rpb24gY3JlYXRlRGV2UmVuZGVyQ29udGV4dChpbnN0YW5jZSkgew0KICBjb25zdCB0YXJnZXQgPSB7fTsNCiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgYF9gLCB7DQogICAgY29uZmlndXJhYmxlOiB0cnVlLA0KICAgIGVudW1lcmFibGU6IGZhbHNlLA0KICAgIGdldDogKCkgPT4gaW5zdGFuY2UNCiAgfSk7DQogIE9iamVjdC5rZXlzKHB1YmxpY1Byb3BlcnRpZXNNYXApLmZvckVhY2goKGtleSkgPT4gew0KICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgew0KICAgICAgY29uZmlndXJhYmxlOiB0cnVlLA0KICAgICAgZW51bWVyYWJsZTogZmFsc2UsDQogICAgICBnZXQ6ICgpID0+IHB1YmxpY1Byb3BlcnRpZXNNYXBba2V5XShpbnN0YW5jZSksDQogICAgICAvLyBpbnRlcmNlcHRlZCBieSB0aGUgcHJveHkgc28gbm8gbmVlZCBmb3IgaW1wbGVtZW50YXRpb24sDQogICAgICAvLyBidXQgbmVlZGVkIHRvIHByZXZlbnQgc2V0IGVycm9ycw0KICAgICAgc2V0OiBOT09QDQogICAgfSk7DQogIH0pOw0KICByZXR1cm4gdGFyZ2V0Ow0KfQ0KZnVuY3Rpb24gZXhwb3NlUHJvcHNPblJlbmRlckNvbnRleHQoaW5zdGFuY2UpIHsNCiAgY29uc3Qgew0KICAgIGN0eCwNCiAgICBwcm9wc09wdGlvbnM6IFtwcm9wc09wdGlvbnNdDQogIH0gPSBpbnN0YW5jZTsNCiAgaWYgKHByb3BzT3B0aW9ucykgew0KICAgIE9iamVjdC5rZXlzKHByb3BzT3B0aW9ucykuZm9yRWFjaCgoa2V5KSA9PiB7DQogICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY3R4LCBrZXksIHsNCiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSwNCiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLA0KICAgICAgICBnZXQ6ICgpID0+IGluc3RhbmNlLnByb3BzW2tleV0sDQogICAgICAgIHNldDogTk9PUA0KICAgICAgfSk7DQogICAgfSk7DQogIH0NCn0NCmZ1bmN0aW9uIGV4cG9zZVNldHVwU3RhdGVPblJlbmRlckNvbnRleHQoaW5zdGFuY2UpIHsNCiAgY29uc3QgeyBjdHgsIHNldHVwU3RhdGUgfSA9IGluc3RhbmNlOw0KICBPYmplY3Qua2V5cyh0b1JhdyhzZXR1cFN0YXRlKSkuZm9yRWFjaCgoa2V5KSA9PiB7DQogICAgaWYgKCFzZXR1cFN0YXRlLl9faXNTY3JpcHRTZXR1cCkgew0KICAgICAgaWYgKGlzUmVzZXJ2ZWRQcmVmaXgoa2V5WzBdKSkgew0KICAgICAgICB3YXJuJDEoDQogICAgICAgICAgYHNldHVwKCkgcmV0dXJuIHByb3BlcnR5ICR7SlNPTi5zdHJpbmdpZnkoDQogICAgICAgICAgICBrZXkNCiAgICAgICAgICApfSBzaG91bGQgbm90IHN0YXJ0IHdpdGggIiQiIG9yICJfIiB3aGljaCBhcmUgcmVzZXJ2ZWQgcHJlZml4ZXMgZm9yIFZ1ZSBpbnRlcm5hbHMuYA0KICAgICAgICApOw0KICAgICAgICByZXR1cm47DQogICAgICB9DQogICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY3R4LCBrZXksIHsNCiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSwNCiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLA0KICAgICAgICBnZXQ6ICgpID0+IHNldHVwU3RhdGVba2V5XSwNCiAgICAgICAgc2V0OiBOT09QDQogICAgICB9KTsNCiAgICB9DQogIH0pOw0KfQ0KDQpjb25zdCB3YXJuUnVudGltZVVzYWdlID0gKG1ldGhvZCkgPT4gd2FybiQxKA0KICBgJHttZXRob2R9KCkgaXMgYSBjb21waWxlci1oaW50IGhlbHBlciB0aGF0IGlzIG9ubHkgdXNhYmxlIGluc2lkZSA8c2NyaXB0IHNldHVwPiBvZiBhIHNpbmdsZSBmaWxlIGNvbXBvbmVudC4gSXRzIGFyZ3VtZW50cyBzaG91bGQgYmUgY29tcGlsZWQgYXdheSBhbmQgcGFzc2luZyBpdCBhdCBydW50aW1lIGhhcyBubyBlZmZlY3QuYA0KKTsNCmZ1bmN0aW9uIGRlZmluZVByb3BzKCkgew0KICB7DQogICAgd2FyblJ1bnRpbWVVc2FnZShgZGVmaW5lUHJvcHNgKTsNCiAgfQ0KICByZXR1cm4gbnVsbDsNCn0NCmZ1bmN0aW9uIGRlZmluZUVtaXRzKCkgew0KICB7DQogICAgd2FyblJ1bnRpbWVVc2FnZShgZGVmaW5lRW1pdHNgKTsNCiAgfQ0KICByZXR1cm4gbnVsbDsNCn0NCmZ1bmN0aW9uIGRlZmluZUV4cG9zZShleHBvc2VkKSB7DQogIHsNCiAgICB3YXJuUnVudGltZVVzYWdlKGBkZWZpbmVFeHBvc2VgKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gZGVmaW5lT3B0aW9ucyhvcHRpb25zKSB7DQogIHsNCiAgICB3YXJuUnVudGltZVVzYWdlKGBkZWZpbmVPcHRpb25zYCk7DQogIH0NCn0NCmZ1bmN0aW9uIGRlZmluZVNsb3RzKCkgew0KICB7DQogICAgd2FyblJ1bnRpbWVVc2FnZShgZGVmaW5lU2xvdHNgKTsNCiAgfQ0KICByZXR1cm4gbnVsbDsNCn0NCmZ1bmN0aW9uIGRlZmluZU1vZGVsKCkgew0KICB7DQogICAgd2FyblJ1bnRpbWVVc2FnZSgiZGVmaW5lTW9kZWwiKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gd2l0aERlZmF1bHRzKHByb3BzLCBkZWZhdWx0cykgew0KICB7DQogICAgd2FyblJ1bnRpbWVVc2FnZShgd2l0aERlZmF1bHRzYCk7DQogIH0NCiAgcmV0dXJuIG51bGw7DQp9DQpmdW5jdGlvbiB1c2VTbG90cygpIHsNCiAgcmV0dXJuIGdldENvbnRleHQoKS5zbG90czsNCn0NCmZ1bmN0aW9uIHVzZUF0dHJzKCkgew0KICByZXR1cm4gZ2V0Q29udGV4dCgpLmF0dHJzOw0KfQ0KZnVuY3Rpb24gZ2V0Q29udGV4dCgpIHsNCiAgY29uc3QgaSA9IGdldEN1cnJlbnRJbnN0YW5jZSgpOw0KICBpZiAoIWkpIHsNCiAgICB3YXJuJDEoYHVzZUNvbnRleHQoKSBjYWxsZWQgd2l0aG91dCBhY3RpdmUgaW5zdGFuY2UuYCk7DQogIH0NCiAgcmV0dXJuIGkuc2V0dXBDb250ZXh0IHx8IChpLnNldHVwQ29udGV4dCA9IGNyZWF0ZVNldHVwQ29udGV4dChpKSk7DQp9DQpmdW5jdGlvbiBub3JtYWxpemVQcm9wc09yRW1pdHMocHJvcHMpIHsNCiAgcmV0dXJuIGlzQXJyYXkocHJvcHMpID8gcHJvcHMucmVkdWNlKA0KICAgIChub3JtYWxpemVkLCBwKSA9PiAobm9ybWFsaXplZFtwXSA9IG51bGwsIG5vcm1hbGl6ZWQpLA0KICAgIHt9DQogICkgOiBwcm9wczsNCn0NCmZ1bmN0aW9uIG1lcmdlRGVmYXVsdHMocmF3LCBkZWZhdWx0cykgew0KICBjb25zdCBwcm9wcyA9IG5vcm1hbGl6ZVByb3BzT3JFbWl0cyhyYXcpOw0KICBmb3IgKGNvbnN0IGtleSBpbiBkZWZhdWx0cykgew0KICAgIGlmIChrZXkuc3RhcnRzV2l0aCgiX19za2lwIikpIGNvbnRpbnVlOw0KICAgIGxldCBvcHQgPSBwcm9wc1trZXldOw0KICAgIGlmIChvcHQpIHsNCiAgICAgIGlmIChpc0FycmF5KG9wdCkgfHwgaXNGdW5jdGlvbihvcHQpKSB7DQogICAgICAgIG9wdCA9IHByb3BzW2tleV0gPSB7IHR5cGU6IG9wdCwgZGVmYXVsdDogZGVmYXVsdHNba2V5XSB9Ow0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgb3B0LmRlZmF1bHQgPSBkZWZhdWx0c1trZXldOw0KICAgICAgfQ0KICAgIH0gZWxzZSBpZiAob3B0ID09PSBudWxsKSB7DQogICAgICBvcHQgPSBwcm9wc1trZXldID0geyBkZWZhdWx0OiBkZWZhdWx0c1trZXldIH07DQogICAgfSBlbHNlIHsNCiAgICAgIHdhcm4kMShgcHJvcHMgZGVmYXVsdCBrZXkgIiR7a2V5fSIgaGFzIG5vIGNvcnJlc3BvbmRpbmcgZGVjbGFyYXRpb24uYCk7DQogICAgfQ0KICAgIGlmIChvcHQgJiYgZGVmYXVsdHNbYF9fc2tpcF8ke2tleX1gXSkgew0KICAgICAgb3B0LnNraXBGYWN0b3J5ID0gdHJ1ZTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIHByb3BzOw0KfQ0KZnVuY3Rpb24gbWVyZ2VNb2RlbHMoYSwgYikgew0KICBpZiAoIWEgfHwgIWIpIHJldHVybiBhIHx8IGI7DQogIGlmIChpc0FycmF5KGEpICYmIGlzQXJyYXkoYikpIHJldHVybiBhLmNvbmNhdChiKTsNCiAgcmV0dXJuIGV4dGVuZCh7fSwgbm9ybWFsaXplUHJvcHNPckVtaXRzKGEpLCBub3JtYWxpemVQcm9wc09yRW1pdHMoYikpOw0KfQ0KZnVuY3Rpb24gY3JlYXRlUHJvcHNSZXN0UHJveHkocHJvcHMsIGV4Y2x1ZGVkS2V5cykgew0KICBjb25zdCByZXQgPSB7fTsNCiAgZm9yIChjb25zdCBrZXkgaW4gcHJvcHMpIHsNCiAgICBpZiAoIWV4Y2x1ZGVkS2V5cy5pbmNsdWRlcyhrZXkpKSB7DQogICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocmV0LCBrZXksIHsNCiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSwNCiAgICAgICAgZ2V0OiAoKSA9PiBwcm9wc1trZXldDQogICAgICB9KTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIHJldDsNCn0NCmZ1bmN0aW9uIHdpdGhBc3luY0NvbnRleHQoZ2V0QXdhaXRhYmxlKSB7DQogIGNvbnN0IGN0eCA9IGdldEN1cnJlbnRJbnN0YW5jZSgpOw0KICBpZiAoIWN0eCkgew0KICAgIHdhcm4kMSgNCiAgICAgIGB3aXRoQXN5bmNDb250ZXh0IGNhbGxlZCB3aXRob3V0IGFjdGl2ZSBjdXJyZW50IGluc3RhbmNlLiBUaGlzIGlzIGxpa2VseSBhIGJ1Zy5gDQogICAgKTsNCiAgfQ0KICBsZXQgYXdhaXRhYmxlID0gZ2V0QXdhaXRhYmxlKCk7DQogIHVuc2V0Q3VycmVudEluc3RhbmNlKCk7DQogIGlmIChpc1Byb21pc2UoYXdhaXRhYmxlKSkgew0KICAgIGF3YWl0YWJsZSA9IGF3YWl0YWJsZS5jYXRjaCgoZSkgPT4gew0KICAgICAgc2V0Q3VycmVudEluc3RhbmNlKGN0eCk7DQogICAgICB0aHJvdyBlOw0KICAgIH0pOw0KICB9DQogIHJldHVybiBbYXdhaXRhYmxlLCAoKSA9PiBzZXRDdXJyZW50SW5zdGFuY2UoY3R4KV07DQp9DQoNCmZ1bmN0aW9uIGNyZWF0ZUR1cGxpY2F0ZUNoZWNrZXIoKSB7DQogIGNvbnN0IGNhY2hlID0gLyogQF9fUFVSRV9fICovIE9iamVjdC5jcmVhdGUobnVsbCk7DQogIHJldHVybiAodHlwZSwga2V5KSA9PiB7DQogICAgaWYgKGNhY2hlW2tleV0pIHsNCiAgICAgIHdhcm4kMShgJHt0eXBlfSBwcm9wZXJ0eSAiJHtrZXl9IiBpcyBhbHJlYWR5IGRlZmluZWQgaW4gJHtjYWNoZVtrZXldfS5gKTsNCiAgICB9IGVsc2Ugew0KICAgICAgY2FjaGVba2V5XSA9IHR5cGU7DQogICAgfQ0KICB9Ow0KfQ0KbGV0IHNob3VsZENhY2hlQWNjZXNzID0gdHJ1ZTsNCmZ1bmN0aW9uIGFwcGx5T3B0aW9ucyhpbnN0YW5jZSkgew0KICBjb25zdCBvcHRpb25zID0gcmVzb2x2ZU1lcmdlZE9wdGlvbnMoaW5zdGFuY2UpOw0KICBjb25zdCBwdWJsaWNUaGlzID0gaW5zdGFuY2UucHJveHk7DQogIGNvbnN0IGN0eCA9IGluc3RhbmNlLmN0eDsNCiAgc2hvdWxkQ2FjaGVBY2Nlc3MgPSBmYWxzZTsNCiAgaWYgKG9wdGlvbnMuYmVmb3JlQ3JlYXRlKSB7DQogICAgY2FsbEhvb2skMShvcHRpb25zLmJlZm9yZUNyZWF0ZSwgaW5zdGFuY2UsICJiYyIpOw0KICB9DQogIGNvbnN0IHsNCiAgICAvLyBzdGF0ZQ0KICAgIGRhdGE6IGRhdGFPcHRpb25zLA0KICAgIGNvbXB1dGVkOiBjb21wdXRlZE9wdGlvbnMsDQogICAgbWV0aG9kcywNCiAgICB3YXRjaDogd2F0Y2hPcHRpb25zLA0KICAgIHByb3ZpZGU6IHByb3ZpZGVPcHRpb25zLA0KICAgIGluamVjdDogaW5qZWN0T3B0aW9ucywNCiAgICAvLyBsaWZlY3ljbGUNCiAgICBjcmVhdGVkLA0KICAgIGJlZm9yZU1vdW50LA0KICAgIG1vdW50ZWQsDQogICAgYmVmb3JlVXBkYXRlLA0KICAgIHVwZGF0ZWQsDQogICAgYWN0aXZhdGVkLA0KICAgIGRlYWN0aXZhdGVkLA0KICAgIGJlZm9yZURlc3Ryb3ksDQogICAgYmVmb3JlVW5tb3VudCwNCiAgICBkZXN0cm95ZWQsDQogICAgdW5tb3VudGVkLA0KICAgIHJlbmRlciwNCiAgICByZW5kZXJUcmFja2VkLA0KICAgIHJlbmRlclRyaWdnZXJlZCwNCiAgICBlcnJvckNhcHR1cmVkLA0KICAgIHNlcnZlclByZWZldGNoLA0KICAgIC8vIHB1YmxpYyBBUEkNCiAgICBleHBvc2UsDQogICAgaW5oZXJpdEF0dHJzLA0KICAgIC8vIGFzc2V0cw0KICAgIGNvbXBvbmVudHMsDQogICAgZGlyZWN0aXZlcywNCiAgICBmaWx0ZXJzDQogIH0gPSBvcHRpb25zOw0KICBjb25zdCBjaGVja0R1cGxpY2F0ZVByb3BlcnRpZXMgPSBjcmVhdGVEdXBsaWNhdGVDaGVja2VyKCkgOw0KICB7DQogICAgY29uc3QgW3Byb3BzT3B0aW9uc10gPSBpbnN0YW5jZS5wcm9wc09wdGlvbnM7DQogICAgaWYgKHByb3BzT3B0aW9ucykgew0KICAgICAgZm9yIChjb25zdCBrZXkgaW4gcHJvcHNPcHRpb25zKSB7DQogICAgICAgIGNoZWNrRHVwbGljYXRlUHJvcGVydGllcygiUHJvcHMiIC8qIFBST1BTICovLCBrZXkpOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICBpZiAoaW5qZWN0T3B0aW9ucykgew0KICAgIHJlc29sdmVJbmplY3Rpb25zKGluamVjdE9wdGlvbnMsIGN0eCwgY2hlY2tEdXBsaWNhdGVQcm9wZXJ0aWVzKTsNCiAgfQ0KICBpZiAobWV0aG9kcykgew0KICAgIGZvciAoY29uc3Qga2V5IGluIG1ldGhvZHMpIHsNCiAgICAgIGNvbnN0IG1ldGhvZEhhbmRsZXIgPSBtZXRob2RzW2tleV07DQogICAgICBpZiAoaXNGdW5jdGlvbihtZXRob2RIYW5kbGVyKSkgew0KICAgICAgICB7DQogICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGN0eCwga2V5LCB7DQogICAgICAgICAgICB2YWx1ZTogbWV0aG9kSGFuZGxlci5iaW5kKHB1YmxpY1RoaXMpLA0KICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLA0KICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSwNCiAgICAgICAgICAgIHdyaXRhYmxlOiB0cnVlDQogICAgICAgICAgfSk7DQogICAgICAgIH0NCiAgICAgICAgew0KICAgICAgICAgIGNoZWNrRHVwbGljYXRlUHJvcGVydGllcygiTWV0aG9kcyIgLyogTUVUSE9EUyAqLywga2V5KTsNCiAgICAgICAgfQ0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgd2FybiQxKA0KICAgICAgICAgIGBNZXRob2QgIiR7a2V5fSIgaGFzIHR5cGUgIiR7dHlwZW9mIG1ldGhvZEhhbmRsZXJ9IiBpbiB0aGUgY29tcG9uZW50IGRlZmluaXRpb24uIERpZCB5b3UgcmVmZXJlbmNlIHRoZSBmdW5jdGlvbiBjb3JyZWN0bHk/YA0KICAgICAgICApOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICBpZiAoZGF0YU9wdGlvbnMpIHsNCiAgICBpZiAoIWlzRnVuY3Rpb24oZGF0YU9wdGlvbnMpKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGBUaGUgZGF0YSBvcHRpb24gbXVzdCBiZSBhIGZ1bmN0aW9uLiBQbGFpbiBvYmplY3QgdXNhZ2UgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZC5gDQogICAgICApOw0KICAgIH0NCiAgICBjb25zdCBkYXRhID0gZGF0YU9wdGlvbnMuY2FsbChwdWJsaWNUaGlzLCBwdWJsaWNUaGlzKTsNCiAgICBpZiAoaXNQcm9taXNlKGRhdGEpKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGBkYXRhKCkgcmV0dXJuZWQgYSBQcm9taXNlIC0gbm90ZSBkYXRhKCkgY2Fubm90IGJlIGFzeW5jOyBJZiB5b3UgaW50ZW5kIHRvIHBlcmZvcm0gZGF0YSBmZXRjaGluZyBiZWZvcmUgY29tcG9uZW50IHJlbmRlcnMsIHVzZSBhc3luYyBzZXR1cCgpICsgPFN1c3BlbnNlPi5gDQogICAgICApOw0KICAgIH0NCiAgICBpZiAoIWlzT2JqZWN0KGRhdGEpKSB7DQogICAgICB3YXJuJDEoYGRhdGEoKSBzaG91bGQgcmV0dXJuIGFuIG9iamVjdC5gKTsNCiAgICB9IGVsc2Ugew0KICAgICAgaW5zdGFuY2UuZGF0YSA9IHJlYWN0aXZlKGRhdGEpOw0KICAgICAgew0KICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBkYXRhKSB7DQogICAgICAgICAgY2hlY2tEdXBsaWNhdGVQcm9wZXJ0aWVzKCJEYXRhIiAvKiBEQVRBICovLCBrZXkpOw0KICAgICAgICAgIGlmICghaXNSZXNlcnZlZFByZWZpeChrZXlbMF0pKSB7DQogICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY3R4LCBrZXksIHsNCiAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLA0KICAgICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLA0KICAgICAgICAgICAgICBnZXQ6ICgpID0+IGRhdGFba2V5XSwNCiAgICAgICAgICAgICAgc2V0OiBOT09QDQogICAgICAgICAgICB9KTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH0NCiAgc2hvdWxkQ2FjaGVBY2Nlc3MgPSB0cnVlOw0KICBpZiAoY29tcHV0ZWRPcHRpb25zKSB7DQogICAgZm9yIChjb25zdCBrZXkgaW4gY29tcHV0ZWRPcHRpb25zKSB7DQogICAgICBjb25zdCBvcHQgPSBjb21wdXRlZE9wdGlvbnNba2V5XTsNCiAgICAgIGNvbnN0IGdldCA9IGlzRnVuY3Rpb24ob3B0KSA/IG9wdC5iaW5kKHB1YmxpY1RoaXMsIHB1YmxpY1RoaXMpIDogaXNGdW5jdGlvbihvcHQuZ2V0KSA/IG9wdC5nZXQuYmluZChwdWJsaWNUaGlzLCBwdWJsaWNUaGlzKSA6IE5PT1A7DQogICAgICBpZiAoZ2V0ID09PSBOT09QKSB7DQogICAgICAgIHdhcm4kMShgQ29tcHV0ZWQgcHJvcGVydHkgIiR7a2V5fSIgaGFzIG5vIGdldHRlci5gKTsNCiAgICAgIH0NCiAgICAgIGNvbnN0IHNldCA9ICFpc0Z1bmN0aW9uKG9wdCkgJiYgaXNGdW5jdGlvbihvcHQuc2V0KSA/IG9wdC5zZXQuYmluZChwdWJsaWNUaGlzKSA6ICgpID0+IHsNCiAgICAgICAgd2FybiQxKA0KICAgICAgICAgIGBXcml0ZSBvcGVyYXRpb24gZmFpbGVkOiBjb21wdXRlZCBwcm9wZXJ0eSAiJHtrZXl9IiBpcyByZWFkb25seS5gDQogICAgICAgICk7DQogICAgICB9IDsNCiAgICAgIGNvbnN0IGMgPSBjb21wdXRlZCh7DQogICAgICAgIGdldCwNCiAgICAgICAgc2V0DQogICAgICB9KTsNCiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIGtleSwgew0KICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLA0KICAgICAgICBjb25maWd1cmFibGU6IHRydWUsDQogICAgICAgIGdldDogKCkgPT4gYy52YWx1ZSwNCiAgICAgICAgc2V0OiAodikgPT4gYy52YWx1ZSA9IHYNCiAgICAgIH0pOw0KICAgICAgew0KICAgICAgICBjaGVja0R1cGxpY2F0ZVByb3BlcnRpZXMoIkNvbXB1dGVkIiAvKiBDT01QVVRFRCAqLywga2V5KTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgaWYgKHdhdGNoT3B0aW9ucykgew0KICAgIGZvciAoY29uc3Qga2V5IGluIHdhdGNoT3B0aW9ucykgew0KICAgICAgY3JlYXRlV2F0Y2hlcih3YXRjaE9wdGlvbnNba2V5XSwgY3R4LCBwdWJsaWNUaGlzLCBrZXkpOw0KICAgIH0NCiAgfQ0KICBpZiAocHJvdmlkZU9wdGlvbnMpIHsNCiAgICBjb25zdCBwcm92aWRlcyA9IGlzRnVuY3Rpb24ocHJvdmlkZU9wdGlvbnMpID8gcHJvdmlkZU9wdGlvbnMuY2FsbChwdWJsaWNUaGlzKSA6IHByb3ZpZGVPcHRpb25zOw0KICAgIFJlZmxlY3Qub3duS2V5cyhwcm92aWRlcykuZm9yRWFjaCgoa2V5KSA9PiB7DQogICAgICBwcm92aWRlKGtleSwgcHJvdmlkZXNba2V5XSk7DQogICAgfSk7DQogIH0NCiAgaWYgKGNyZWF0ZWQpIHsNCiAgICBjYWxsSG9vayQxKGNyZWF0ZWQsIGluc3RhbmNlLCAiYyIpOw0KICB9DQogIGZ1bmN0aW9uIHJlZ2lzdGVyTGlmZWN5Y2xlSG9vayhyZWdpc3RlciwgaG9vaykgew0KICAgIGlmIChpc0FycmF5KGhvb2spKSB7DQogICAgICBob29rLmZvckVhY2goKF9ob29rKSA9PiByZWdpc3RlcihfaG9vay5iaW5kKHB1YmxpY1RoaXMpKSk7DQogICAgfSBlbHNlIGlmIChob29rKSB7DQogICAgICByZWdpc3Rlcihob29rLmJpbmQocHVibGljVGhpcykpOw0KICAgIH0NCiAgfQ0KICByZWdpc3RlckxpZmVjeWNsZUhvb2sob25CZWZvcmVNb3VudCwgYmVmb3JlTW91bnQpOw0KICByZWdpc3RlckxpZmVjeWNsZUhvb2sob25Nb3VudGVkLCBtb3VudGVkKTsNCiAgcmVnaXN0ZXJMaWZlY3ljbGVIb29rKG9uQmVmb3JlVXBkYXRlLCBiZWZvcmVVcGRhdGUpOw0KICByZWdpc3RlckxpZmVjeWNsZUhvb2sob25VcGRhdGVkLCB1cGRhdGVkKTsNCiAgcmVnaXN0ZXJMaWZlY3ljbGVIb29rKG9uQWN0aXZhdGVkLCBhY3RpdmF0ZWQpOw0KICByZWdpc3RlckxpZmVjeWNsZUhvb2sob25EZWFjdGl2YXRlZCwgZGVhY3RpdmF0ZWQpOw0KICByZWdpc3RlckxpZmVjeWNsZUhvb2sob25FcnJvckNhcHR1cmVkLCBlcnJvckNhcHR1cmVkKTsNCiAgcmVnaXN0ZXJMaWZlY3ljbGVIb29rKG9uUmVuZGVyVHJhY2tlZCwgcmVuZGVyVHJhY2tlZCk7DQogIHJlZ2lzdGVyTGlmZWN5Y2xlSG9vayhvblJlbmRlclRyaWdnZXJlZCwgcmVuZGVyVHJpZ2dlcmVkKTsNCiAgcmVnaXN0ZXJMaWZlY3ljbGVIb29rKG9uQmVmb3JlVW5tb3VudCwgYmVmb3JlVW5tb3VudCk7DQogIHJlZ2lzdGVyTGlmZWN5Y2xlSG9vayhvblVubW91bnRlZCwgdW5tb3VudGVkKTsNCiAgcmVnaXN0ZXJMaWZlY3ljbGVIb29rKG9uU2VydmVyUHJlZmV0Y2gsIHNlcnZlclByZWZldGNoKTsNCiAgaWYgKGlzQXJyYXkoZXhwb3NlKSkgew0KICAgIGlmIChleHBvc2UubGVuZ3RoKSB7DQogICAgICBjb25zdCBleHBvc2VkID0gaW5zdGFuY2UuZXhwb3NlZCB8fCAoaW5zdGFuY2UuZXhwb3NlZCA9IHt9KTsNCiAgICAgIGV4cG9zZS5mb3JFYWNoKChrZXkpID0+IHsNCiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9zZWQsIGtleSwgew0KICAgICAgICAgIGdldDogKCkgPT4gcHVibGljVGhpc1trZXldLA0KICAgICAgICAgIHNldDogKHZhbCkgPT4gcHVibGljVGhpc1trZXldID0gdmFsDQogICAgICAgIH0pOw0KICAgICAgfSk7DQogICAgfSBlbHNlIGlmICghaW5zdGFuY2UuZXhwb3NlZCkgew0KICAgICAgaW5zdGFuY2UuZXhwb3NlZCA9IHt9Ow0KICAgIH0NCiAgfQ0KICBpZiAocmVuZGVyICYmIGluc3RhbmNlLnJlbmRlciA9PT0gTk9PUCkgew0KICAgIGluc3RhbmNlLnJlbmRlciA9IHJlbmRlcjsNCiAgfQ0KICBpZiAoaW5oZXJpdEF0dHJzICE9IG51bGwpIHsNCiAgICBpbnN0YW5jZS5pbmhlcml0QXR0cnMgPSBpbmhlcml0QXR0cnM7DQogIH0NCiAgaWYgKGNvbXBvbmVudHMpIGluc3RhbmNlLmNvbXBvbmVudHMgPSBjb21wb25lbnRzOw0KICBpZiAoZGlyZWN0aXZlcykgaW5zdGFuY2UuZGlyZWN0aXZlcyA9IGRpcmVjdGl2ZXM7DQogIGlmIChzZXJ2ZXJQcmVmZXRjaCkgew0KICAgIG1hcmtBc3luY0JvdW5kYXJ5KGluc3RhbmNlKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gcmVzb2x2ZUluamVjdGlvbnMoaW5qZWN0T3B0aW9ucywgY3R4LCBjaGVja0R1cGxpY2F0ZVByb3BlcnRpZXMgPSBOT09QKSB7DQogIGlmIChpc0FycmF5KGluamVjdE9wdGlvbnMpKSB7DQogICAgaW5qZWN0T3B0aW9ucyA9IG5vcm1hbGl6ZUluamVjdChpbmplY3RPcHRpb25zKTsNCiAgfQ0KICBmb3IgKGNvbnN0IGtleSBpbiBpbmplY3RPcHRpb25zKSB7DQogICAgY29uc3Qgb3B0ID0gaW5qZWN0T3B0aW9uc1trZXldOw0KICAgIGxldCBpbmplY3RlZDsNCiAgICBpZiAoaXNPYmplY3Qob3B0KSkgew0KICAgICAgaWYgKCJkZWZhdWx0IiBpbiBvcHQpIHsNCiAgICAgICAgaW5qZWN0ZWQgPSBpbmplY3QoDQogICAgICAgICAgb3B0LmZyb20gfHwga2V5LA0KICAgICAgICAgIG9wdC5kZWZhdWx0LA0KICAgICAgICAgIHRydWUNCiAgICAgICAgKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGluamVjdGVkID0gaW5qZWN0KG9wdC5mcm9tIHx8IGtleSk7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIGluamVjdGVkID0gaW5qZWN0KG9wdCk7DQogICAgfQ0KICAgIGlmIChpc1JlZihpbmplY3RlZCkpIHsNCiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIGtleSwgew0KICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLA0KICAgICAgICBjb25maWd1cmFibGU6IHRydWUsDQogICAgICAgIGdldDogKCkgPT4gaW5qZWN0ZWQudmFsdWUsDQogICAgICAgIHNldDogKHYpID0+IGluamVjdGVkLnZhbHVlID0gdg0KICAgICAgfSk7DQogICAgfSBlbHNlIHsNCiAgICAgIGN0eFtrZXldID0gaW5qZWN0ZWQ7DQogICAgfQ0KICAgIHsNCiAgICAgIGNoZWNrRHVwbGljYXRlUHJvcGVydGllcygiSW5qZWN0IiAvKiBJTkpFQ1QgKi8sIGtleSk7DQogICAgfQ0KICB9DQp9DQpmdW5jdGlvbiBjYWxsSG9vayQxKGhvb2ssIGluc3RhbmNlLCB0eXBlKSB7DQogIGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nKA0KICAgIGlzQXJyYXkoaG9vaykgPyBob29rLm1hcCgoaCkgPT4gaC5iaW5kKGluc3RhbmNlLnByb3h5KSkgOiBob29rLmJpbmQoaW5zdGFuY2UucHJveHkpLA0KICAgIGluc3RhbmNlLA0KICAgIHR5cGUNCiAgKTsNCn0NCmZ1bmN0aW9uIGNyZWF0ZVdhdGNoZXIocmF3LCBjdHgsIHB1YmxpY1RoaXMsIGtleSkgew0KICBsZXQgZ2V0dGVyID0ga2V5LmluY2x1ZGVzKCIuIikgPyBjcmVhdGVQYXRoR2V0dGVyKHB1YmxpY1RoaXMsIGtleSkgOiAoKSA9PiBwdWJsaWNUaGlzW2tleV07DQogIGlmIChpc1N0cmluZyhyYXcpKSB7DQogICAgY29uc3QgaGFuZGxlciA9IGN0eFtyYXddOw0KICAgIGlmIChpc0Z1bmN0aW9uKGhhbmRsZXIpKSB7DQogICAgICB7DQogICAgICAgIHdhdGNoKGdldHRlciwgaGFuZGxlcik7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIHdhcm4kMShgSW52YWxpZCB3YXRjaCBoYW5kbGVyIHNwZWNpZmllZCBieSBrZXkgIiR7cmF3fSJgLCBoYW5kbGVyKTsNCiAgICB9DQogIH0gZWxzZSBpZiAoaXNGdW5jdGlvbihyYXcpKSB7DQogICAgew0KICAgICAgd2F0Y2goZ2V0dGVyLCByYXcuYmluZChwdWJsaWNUaGlzKSk7DQogICAgfQ0KICB9IGVsc2UgaWYgKGlzT2JqZWN0KHJhdykpIHsNCiAgICBpZiAoaXNBcnJheShyYXcpKSB7DQogICAgICByYXcuZm9yRWFjaCgocikgPT4gY3JlYXRlV2F0Y2hlcihyLCBjdHgsIHB1YmxpY1RoaXMsIGtleSkpOw0KICAgIH0gZWxzZSB7DQogICAgICBjb25zdCBoYW5kbGVyID0gaXNGdW5jdGlvbihyYXcuaGFuZGxlcikgPyByYXcuaGFuZGxlci5iaW5kKHB1YmxpY1RoaXMpIDogY3R4W3Jhdy5oYW5kbGVyXTsNCiAgICAgIGlmIChpc0Z1bmN0aW9uKGhhbmRsZXIpKSB7DQogICAgICAgIHdhdGNoKGdldHRlciwgaGFuZGxlciwgcmF3KTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHdhcm4kMShgSW52YWxpZCB3YXRjaCBoYW5kbGVyIHNwZWNpZmllZCBieSBrZXkgIiR7cmF3LmhhbmRsZXJ9ImAsIGhhbmRsZXIpOw0KICAgICAgfQ0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICB3YXJuJDEoYEludmFsaWQgd2F0Y2ggb3B0aW9uOiAiJHtrZXl9ImAsIHJhdyk7DQogIH0NCn0NCmZ1bmN0aW9uIHJlc29sdmVNZXJnZWRPcHRpb25zKGluc3RhbmNlKSB7DQogIGNvbnN0IGJhc2UgPSBpbnN0YW5jZS50eXBlOw0KICBjb25zdCB7IG1peGlucywgZXh0ZW5kczogZXh0ZW5kc09wdGlvbnMgfSA9IGJhc2U7DQogIGNvbnN0IHsNCiAgICBtaXhpbnM6IGdsb2JhbE1peGlucywNCiAgICBvcHRpb25zQ2FjaGU6IGNhY2hlLA0KICAgIGNvbmZpZzogeyBvcHRpb25NZXJnZVN0cmF0ZWdpZXMgfQ0KICB9ID0gaW5zdGFuY2UuYXBwQ29udGV4dDsNCiAgY29uc3QgY2FjaGVkID0gY2FjaGUuZ2V0KGJhc2UpOw0KICBsZXQgcmVzb2x2ZWQ7DQogIGlmIChjYWNoZWQpIHsNCiAgICByZXNvbHZlZCA9IGNhY2hlZDsNCiAgfSBlbHNlIGlmICghZ2xvYmFsTWl4aW5zLmxlbmd0aCAmJiAhbWl4aW5zICYmICFleHRlbmRzT3B0aW9ucykgew0KICAgIHsNCiAgICAgIHJlc29sdmVkID0gYmFzZTsNCiAgICB9DQogIH0gZWxzZSB7DQogICAgcmVzb2x2ZWQgPSB7fTsNCiAgICBpZiAoZ2xvYmFsTWl4aW5zLmxlbmd0aCkgew0KICAgICAgZ2xvYmFsTWl4aW5zLmZvckVhY2goDQogICAgICAgIChtKSA9PiBtZXJnZU9wdGlvbnMocmVzb2x2ZWQsIG0sIG9wdGlvbk1lcmdlU3RyYXRlZ2llcywgdHJ1ZSkNCiAgICAgICk7DQogICAgfQ0KICAgIG1lcmdlT3B0aW9ucyhyZXNvbHZlZCwgYmFzZSwgb3B0aW9uTWVyZ2VTdHJhdGVnaWVzKTsNCiAgfQ0KICBpZiAoaXNPYmplY3QoYmFzZSkpIHsNCiAgICBjYWNoZS5zZXQoYmFzZSwgcmVzb2x2ZWQpOw0KICB9DQogIHJldHVybiByZXNvbHZlZDsNCn0NCmZ1bmN0aW9uIG1lcmdlT3B0aW9ucyh0bywgZnJvbSwgc3RyYXRzLCBhc01peGluID0gZmFsc2UpIHsNCiAgY29uc3QgeyBtaXhpbnMsIGV4dGVuZHM6IGV4dGVuZHNPcHRpb25zIH0gPSBmcm9tOw0KICBpZiAoZXh0ZW5kc09wdGlvbnMpIHsNCiAgICBtZXJnZU9wdGlvbnModG8sIGV4dGVuZHNPcHRpb25zLCBzdHJhdHMsIHRydWUpOw0KICB9DQogIGlmIChtaXhpbnMpIHsNCiAgICBtaXhpbnMuZm9yRWFjaCgNCiAgICAgIChtKSA9PiBtZXJnZU9wdGlvbnModG8sIG0sIHN0cmF0cywgdHJ1ZSkNCiAgICApOw0KICB9DQogIGZvciAoY29uc3Qga2V5IGluIGZyb20pIHsNCiAgICBpZiAoYXNNaXhpbiAmJiBrZXkgPT09ICJleHBvc2UiKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGAiZXhwb3NlIiBvcHRpb24gaXMgaWdub3JlZCB3aGVuIGRlY2xhcmVkIGluIG1peGlucyBvciBleHRlbmRzLiBJdCBzaG91bGQgb25seSBiZSBkZWNsYXJlZCBpbiB0aGUgYmFzZSBjb21wb25lbnQgaXRzZWxmLmANCiAgICAgICk7DQogICAgfSBlbHNlIHsNCiAgICAgIGNvbnN0IHN0cmF0ID0gaW50ZXJuYWxPcHRpb25NZXJnZVN0cmF0c1trZXldIHx8IHN0cmF0cyAmJiBzdHJhdHNba2V5XTsNCiAgICAgIHRvW2tleV0gPSBzdHJhdCA/IHN0cmF0KHRvW2tleV0sIGZyb21ba2V5XSkgOiBmcm9tW2tleV07DQogICAgfQ0KICB9DQogIHJldHVybiB0bzsNCn0NCmNvbnN0IGludGVybmFsT3B0aW9uTWVyZ2VTdHJhdHMgPSB7DQogIGRhdGE6IG1lcmdlRGF0YUZuLA0KICBwcm9wczogbWVyZ2VFbWl0c09yUHJvcHNPcHRpb25zLA0KICBlbWl0czogbWVyZ2VFbWl0c09yUHJvcHNPcHRpb25zLA0KICAvLyBvYmplY3RzDQogIG1ldGhvZHM6IG1lcmdlT2JqZWN0T3B0aW9ucywNCiAgY29tcHV0ZWQ6IG1lcmdlT2JqZWN0T3B0aW9ucywNCiAgLy8gbGlmZWN5Y2xlDQogIGJlZm9yZUNyZWF0ZTogbWVyZ2VBc0FycmF5LA0KICBjcmVhdGVkOiBtZXJnZUFzQXJyYXksDQogIGJlZm9yZU1vdW50OiBtZXJnZUFzQXJyYXksDQogIG1vdW50ZWQ6IG1lcmdlQXNBcnJheSwNCiAgYmVmb3JlVXBkYXRlOiBtZXJnZUFzQXJyYXksDQogIHVwZGF0ZWQ6IG1lcmdlQXNBcnJheSwNCiAgYmVmb3JlRGVzdHJveTogbWVyZ2VBc0FycmF5LA0KICBiZWZvcmVVbm1vdW50OiBtZXJnZUFzQXJyYXksDQogIGRlc3Ryb3llZDogbWVyZ2VBc0FycmF5LA0KICB1bm1vdW50ZWQ6IG1lcmdlQXNBcnJheSwNCiAgYWN0aXZhdGVkOiBtZXJnZUFzQXJyYXksDQogIGRlYWN0aXZhdGVkOiBtZXJnZUFzQXJyYXksDQogIGVycm9yQ2FwdHVyZWQ6IG1lcmdlQXNBcnJheSwNCiAgc2VydmVyUHJlZmV0Y2g6IG1lcmdlQXNBcnJheSwNCiAgLy8gYXNzZXRzDQogIGNvbXBvbmVudHM6IG1lcmdlT2JqZWN0T3B0aW9ucywNCiAgZGlyZWN0aXZlczogbWVyZ2VPYmplY3RPcHRpb25zLA0KICAvLyB3YXRjaA0KICB3YXRjaDogbWVyZ2VXYXRjaE9wdGlvbnMsDQogIC8vIHByb3ZpZGUgLyBpbmplY3QNCiAgcHJvdmlkZTogbWVyZ2VEYXRhRm4sDQogIGluamVjdDogbWVyZ2VJbmplY3QNCn07DQpmdW5jdGlvbiBtZXJnZURhdGFGbih0bywgZnJvbSkgew0KICBpZiAoIWZyb20pIHsNCiAgICByZXR1cm4gdG87DQogIH0NCiAgaWYgKCF0bykgew0KICAgIHJldHVybiBmcm9tOw0KICB9DQogIHJldHVybiBmdW5jdGlvbiBtZXJnZWREYXRhRm4oKSB7DQogICAgcmV0dXJuIChleHRlbmQpKA0KICAgICAgaXNGdW5jdGlvbih0bykgPyB0by5jYWxsKHRoaXMsIHRoaXMpIDogdG8sDQogICAgICBpc0Z1bmN0aW9uKGZyb20pID8gZnJvbS5jYWxsKHRoaXMsIHRoaXMpIDogZnJvbQ0KICAgICk7DQogIH07DQp9DQpmdW5jdGlvbiBtZXJnZUluamVjdCh0bywgZnJvbSkgew0KICByZXR1cm4gbWVyZ2VPYmplY3RPcHRpb25zKG5vcm1hbGl6ZUluamVjdCh0byksIG5vcm1hbGl6ZUluamVjdChmcm9tKSk7DQp9DQpmdW5jdGlvbiBub3JtYWxpemVJbmplY3QocmF3KSB7DQogIGlmIChpc0FycmF5KHJhdykpIHsNCiAgICBjb25zdCByZXMgPSB7fTsNCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhdy5sZW5ndGg7IGkrKykgew0KICAgICAgcmVzW3Jhd1tpXV0gPSByYXdbaV07DQogICAgfQ0KICAgIHJldHVybiByZXM7DQogIH0NCiAgcmV0dXJuIHJhdzsNCn0NCmZ1bmN0aW9uIG1lcmdlQXNBcnJheSh0bywgZnJvbSkgew0KICByZXR1cm4gdG8gPyBbLi4ubmV3IFNldChbXS5jb25jYXQodG8sIGZyb20pKV0gOiBmcm9tOw0KfQ0KZnVuY3Rpb24gbWVyZ2VPYmplY3RPcHRpb25zKHRvLCBmcm9tKSB7DQogIHJldHVybiB0byA/IGV4dGVuZCgvKiBAX19QVVJFX18gKi8gT2JqZWN0LmNyZWF0ZShudWxsKSwgdG8sIGZyb20pIDogZnJvbTsNCn0NCmZ1bmN0aW9uIG1lcmdlRW1pdHNPclByb3BzT3B0aW9ucyh0bywgZnJvbSkgew0KICBpZiAodG8pIHsNCiAgICBpZiAoaXNBcnJheSh0bykgJiYgaXNBcnJheShmcm9tKSkgew0KICAgICAgcmV0dXJuIFsuLi4vKiBAX19QVVJFX18gKi8gbmV3IFNldChbLi4udG8sIC4uLmZyb21dKV07DQogICAgfQ0KICAgIHJldHVybiBleHRlbmQoDQogICAgICAvKiBAX19QVVJFX18gKi8gT2JqZWN0LmNyZWF0ZShudWxsKSwNCiAgICAgIG5vcm1hbGl6ZVByb3BzT3JFbWl0cyh0byksDQogICAgICBub3JtYWxpemVQcm9wc09yRW1pdHMoZnJvbSAhPSBudWxsID8gZnJvbSA6IHt9KQ0KICAgICk7DQogIH0gZWxzZSB7DQogICAgcmV0dXJuIGZyb207DQogIH0NCn0NCmZ1bmN0aW9uIG1lcmdlV2F0Y2hPcHRpb25zKHRvLCBmcm9tKSB7DQogIGlmICghdG8pIHJldHVybiBmcm9tOw0KICBpZiAoIWZyb20pIHJldHVybiB0bzsNCiAgY29uc3QgbWVyZ2VkID0gZXh0ZW5kKC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuY3JlYXRlKG51bGwpLCB0byk7DQogIGZvciAoY29uc3Qga2V5IGluIGZyb20pIHsNCiAgICBtZXJnZWRba2V5XSA9IG1lcmdlQXNBcnJheSh0b1trZXldLCBmcm9tW2tleV0pOw0KICB9DQogIHJldHVybiBtZXJnZWQ7DQp9DQoNCmZ1bmN0aW9uIGNyZWF0ZUFwcENvbnRleHQoKSB7DQogIHJldHVybiB7DQogICAgYXBwOiBudWxsLA0KICAgIGNvbmZpZzogew0KICAgICAgaXNOYXRpdmVUYWc6IE5PLA0KICAgICAgcGVyZm9ybWFuY2U6IGZhbHNlLA0KICAgICAgZ2xvYmFsUHJvcGVydGllczoge30sDQogICAgICBvcHRpb25NZXJnZVN0cmF0ZWdpZXM6IHt9LA0KICAgICAgZXJyb3JIYW5kbGVyOiB2b2lkIDAsDQogICAgICB3YXJuSGFuZGxlcjogdm9pZCAwLA0KICAgICAgY29tcGlsZXJPcHRpb25zOiB7fQ0KICAgIH0sDQogICAgbWl4aW5zOiBbXSwNCiAgICBjb21wb25lbnRzOiB7fSwNCiAgICBkaXJlY3RpdmVzOiB7fSwNCiAgICBwcm92aWRlczogLyogQF9fUFVSRV9fICovIE9iamVjdC5jcmVhdGUobnVsbCksDQogICAgb3B0aW9uc0NhY2hlOiAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtNYXAoKSwNCiAgICBwcm9wc0NhY2hlOiAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtNYXAoKSwNCiAgICBlbWl0c0NhY2hlOiAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtNYXAoKQ0KICB9Ow0KfQ0KbGV0IHVpZCQxID0gMDsNCmZ1bmN0aW9uIGNyZWF0ZUFwcEFQSShyZW5kZXIsIGh5ZHJhdGUpIHsNCiAgcmV0dXJuIGZ1bmN0aW9uIGNyZWF0ZUFwcChyb290Q29tcG9uZW50LCByb290UHJvcHMgPSBudWxsKSB7DQogICAgaWYgKCFpc0Z1bmN0aW9uKHJvb3RDb21wb25lbnQpKSB7DQogICAgICByb290Q29tcG9uZW50ID0gZXh0ZW5kKHt9LCByb290Q29tcG9uZW50KTsNCiAgICB9DQogICAgaWYgKHJvb3RQcm9wcyAhPSBudWxsICYmICFpc09iamVjdChyb290UHJvcHMpKSB7DQogICAgICB3YXJuJDEoYHJvb3QgcHJvcHMgcGFzc2VkIHRvIGFwcC5tb3VudCgpIG11c3QgYmUgYW4gb2JqZWN0LmApOw0KICAgICAgcm9vdFByb3BzID0gbnVsbDsNCiAgICB9DQogICAgY29uc3QgY29udGV4dCA9IGNyZWF0ZUFwcENvbnRleHQoKTsNCiAgICBjb25zdCBpbnN0YWxsZWRQbHVnaW5zID0gLyogQF9fUFVSRV9fICovIG5ldyBXZWFrU2V0KCk7DQogICAgY29uc3QgcGx1Z2luQ2xlYW51cEZucyA9IFtdOw0KICAgIGxldCBpc01vdW50ZWQgPSBmYWxzZTsNCiAgICBjb25zdCBhcHAgPSBjb250ZXh0LmFwcCA9IHsNCiAgICAgIF91aWQ6IHVpZCQxKyssDQogICAgICBfY29tcG9uZW50OiByb290Q29tcG9uZW50LA0KICAgICAgX3Byb3BzOiByb290UHJvcHMsDQogICAgICBfY29udGFpbmVyOiBudWxsLA0KICAgICAgX2NvbnRleHQ6IGNvbnRleHQsDQogICAgICBfaW5zdGFuY2U6IG51bGwsDQogICAgICB2ZXJzaW9uLA0KICAgICAgZ2V0IGNvbmZpZygpIHsNCiAgICAgICAgcmV0dXJuIGNvbnRleHQuY29uZmlnOw0KICAgICAgfSwNCiAgICAgIHNldCBjb25maWcodikgew0KICAgICAgICB7DQogICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgYGFwcC5jb25maWcgY2Fubm90IGJlIHJlcGxhY2VkLiBNb2RpZnkgaW5kaXZpZHVhbCBvcHRpb25zIGluc3RlYWQuYA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH0sDQogICAgICB1c2UocGx1Z2luLCAuLi5vcHRpb25zKSB7DQogICAgICAgIGlmIChpbnN0YWxsZWRQbHVnaW5zLmhhcyhwbHVnaW4pKSB7DQogICAgICAgICAgd2FybiQxKGBQbHVnaW4gaGFzIGFscmVhZHkgYmVlbiBhcHBsaWVkIHRvIHRhcmdldCBhcHAuYCk7DQogICAgICAgIH0gZWxzZSBpZiAocGx1Z2luICYmIGlzRnVuY3Rpb24ocGx1Z2luLmluc3RhbGwpKSB7DQogICAgICAgICAgaW5zdGFsbGVkUGx1Z2lucy5hZGQocGx1Z2luKTsNCiAgICAgICAgICBwbHVnaW4uaW5zdGFsbChhcHAsIC4uLm9wdGlvbnMpOw0KICAgICAgICB9IGVsc2UgaWYgKGlzRnVuY3Rpb24ocGx1Z2luKSkgew0KICAgICAgICAgIGluc3RhbGxlZFBsdWdpbnMuYWRkKHBsdWdpbik7DQogICAgICAgICAgcGx1Z2luKGFwcCwgLi4ub3B0aW9ucyk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgYEEgcGx1Z2luIG11c3QgZWl0aGVyIGJlIGEgZnVuY3Rpb24gb3IgYW4gb2JqZWN0IHdpdGggYW4gImluc3RhbGwiIGZ1bmN0aW9uLmANCiAgICAgICAgICApOw0KICAgICAgICB9DQogICAgICAgIHJldHVybiBhcHA7DQogICAgICB9LA0KICAgICAgbWl4aW4obWl4aW4pIHsNCiAgICAgICAgew0KICAgICAgICAgIGlmICghY29udGV4dC5taXhpbnMuaW5jbHVkZXMobWl4aW4pKSB7DQogICAgICAgICAgICBjb250ZXh0Lm1peGlucy5wdXNoKG1peGluKTsNCiAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgICAiTWl4aW4gaGFzIGFscmVhZHkgYmVlbiBhcHBsaWVkIHRvIHRhcmdldCBhcHAiICsgKG1peGluLm5hbWUgPyBgOiAke21peGluLm5hbWV9YCA6ICIiKQ0KICAgICAgICAgICAgKTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIGFwcDsNCiAgICAgIH0sDQogICAgICBjb21wb25lbnQobmFtZSwgY29tcG9uZW50KSB7DQogICAgICAgIHsNCiAgICAgICAgICB2YWxpZGF0ZUNvbXBvbmVudE5hbWUobmFtZSwgY29udGV4dC5jb25maWcpOw0KICAgICAgICB9DQogICAgICAgIGlmICghY29tcG9uZW50KSB7DQogICAgICAgICAgcmV0dXJuIGNvbnRleHQuY29tcG9uZW50c1tuYW1lXTsNCiAgICAgICAgfQ0KICAgICAgICBpZiAoY29udGV4dC5jb21wb25lbnRzW25hbWVdKSB7DQogICAgICAgICAgd2FybiQxKGBDb21wb25lbnQgIiR7bmFtZX0iIGhhcyBhbHJlYWR5IGJlZW4gcmVnaXN0ZXJlZCBpbiB0YXJnZXQgYXBwLmApOw0KICAgICAgICB9DQogICAgICAgIGNvbnRleHQuY29tcG9uZW50c1tuYW1lXSA9IGNvbXBvbmVudDsNCiAgICAgICAgcmV0dXJuIGFwcDsNCiAgICAgIH0sDQogICAgICBkaXJlY3RpdmUobmFtZSwgZGlyZWN0aXZlKSB7DQogICAgICAgIHsNCiAgICAgICAgICB2YWxpZGF0ZURpcmVjdGl2ZU5hbWUobmFtZSk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKCFkaXJlY3RpdmUpIHsNCiAgICAgICAgICByZXR1cm4gY29udGV4dC5kaXJlY3RpdmVzW25hbWVdOw0KICAgICAgICB9DQogICAgICAgIGlmIChjb250ZXh0LmRpcmVjdGl2ZXNbbmFtZV0pIHsNCiAgICAgICAgICB3YXJuJDEoYERpcmVjdGl2ZSAiJHtuYW1lfSIgaGFzIGFscmVhZHkgYmVlbiByZWdpc3RlcmVkIGluIHRhcmdldCBhcHAuYCk7DQogICAgICAgIH0NCiAgICAgICAgY29udGV4dC5kaXJlY3RpdmVzW25hbWVdID0gZGlyZWN0aXZlOw0KICAgICAgICByZXR1cm4gYXBwOw0KICAgICAgfSwNCiAgICAgIG1vdW50KHJvb3RDb250YWluZXIsIGlzSHlkcmF0ZSwgbmFtZXNwYWNlKSB7DQogICAgICAgIGlmICghaXNNb3VudGVkKSB7DQogICAgICAgICAgaWYgKHJvb3RDb250YWluZXIuX192dWVfYXBwX18pIHsNCiAgICAgICAgICAgIHdhcm4kMSgNCiAgICAgICAgICAgICAgYFRoZXJlIGlzIGFscmVhZHkgYW4gYXBwIGluc3RhbmNlIG1vdW50ZWQgb24gdGhlIGhvc3QgY29udGFpbmVyLg0KIElmIHlvdSB3YW50IHRvIG1vdW50IGFub3RoZXIgYXBwIG9uIHRoZSBzYW1lIGhvc3QgY29udGFpbmVyLCB5b3UgbmVlZCB0byB1bm1vdW50IHRoZSBwcmV2aW91cyBhcHAgYnkgY2FsbGluZyBcYGFwcC51bm1vdW50KClcYCBmaXJzdC5gDQogICAgICAgICAgICApOw0KICAgICAgICAgIH0NCiAgICAgICAgICBjb25zdCB2bm9kZSA9IGFwcC5fY2VWTm9kZSB8fCBjcmVhdGVWTm9kZShyb290Q29tcG9uZW50LCByb290UHJvcHMpOw0KICAgICAgICAgIHZub2RlLmFwcENvbnRleHQgPSBjb250ZXh0Ow0KICAgICAgICAgIGlmIChuYW1lc3BhY2UgPT09IHRydWUpIHsNCiAgICAgICAgICAgIG5hbWVzcGFjZSA9ICJzdmciOw0KICAgICAgICAgIH0gZWxzZSBpZiAobmFtZXNwYWNlID09PSBmYWxzZSkgew0KICAgICAgICAgICAgbmFtZXNwYWNlID0gdm9pZCAwOw0KICAgICAgICAgIH0NCiAgICAgICAgICB7DQogICAgICAgICAgICBjb250ZXh0LnJlbG9hZCA9ICgpID0+IHsNCiAgICAgICAgICAgICAgY29uc3QgY2xvbmVkID0gY2xvbmVWTm9kZSh2bm9kZSk7DQogICAgICAgICAgICAgIGNsb25lZC5lbCA9IG51bGw7DQogICAgICAgICAgICAgIHJlbmRlcihjbG9uZWQsIHJvb3RDb250YWluZXIsIG5hbWVzcGFjZSk7DQogICAgICAgICAgICB9Ow0KICAgICAgICAgIH0NCiAgICAgICAgICBpZiAoaXNIeWRyYXRlICYmIGh5ZHJhdGUpIHsNCiAgICAgICAgICAgIGh5ZHJhdGUodm5vZGUsIHJvb3RDb250YWluZXIpOw0KICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICByZW5kZXIodm5vZGUsIHJvb3RDb250YWluZXIsIG5hbWVzcGFjZSk7DQogICAgICAgICAgfQ0KICAgICAgICAgIGlzTW91bnRlZCA9IHRydWU7DQogICAgICAgICAgYXBwLl9jb250YWluZXIgPSByb290Q29udGFpbmVyOw0KICAgICAgICAgIHJvb3RDb250YWluZXIuX192dWVfYXBwX18gPSBhcHA7DQogICAgICAgICAgew0KICAgICAgICAgICAgYXBwLl9pbnN0YW5jZSA9IHZub2RlLmNvbXBvbmVudDsNCiAgICAgICAgICAgIGRldnRvb2xzSW5pdEFwcChhcHAsIHZlcnNpb24pOw0KICAgICAgICAgIH0NCiAgICAgICAgICByZXR1cm4gZ2V0Q29tcG9uZW50UHVibGljSW5zdGFuY2Uodm5vZGUuY29tcG9uZW50KTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICB3YXJuJDEoDQogICAgICAgICAgICBgQXBwIGhhcyBhbHJlYWR5IGJlZW4gbW91bnRlZC4NCklmIHlvdSB3YW50IHRvIHJlbW91bnQgdGhlIHNhbWUgYXBwLCBtb3ZlIHlvdXIgYXBwIGNyZWF0aW9uIGxvZ2ljIGludG8gYSBmYWN0b3J5IGZ1bmN0aW9uIGFuZCBjcmVhdGUgZnJlc2ggYXBwIGluc3RhbmNlcyBmb3IgZWFjaCBtb3VudCAtIGUuZy4gXGBjb25zdCBjcmVhdGVNeUFwcCA9ICgpID0+IGNyZWF0ZUFwcChBcHApXGBgDQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgfSwNCiAgICAgIG9uVW5tb3VudChjbGVhbnVwRm4pIHsNCiAgICAgICAgaWYgKHR5cGVvZiBjbGVhbnVwRm4gIT09ICJmdW5jdGlvbiIpIHsNCiAgICAgICAgICB3YXJuJDEoDQogICAgICAgICAgICBgRXhwZWN0ZWQgZnVuY3Rpb24gYXMgZmlyc3QgYXJndW1lbnQgdG8gYXBwLm9uVW5tb3VudCgpLCBidXQgZ290ICR7dHlwZW9mIGNsZWFudXBGbn1gDQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgICBwbHVnaW5DbGVhbnVwRm5zLnB1c2goY2xlYW51cEZuKTsNCiAgICAgIH0sDQogICAgICB1bm1vdW50KCkgew0KICAgICAgICBpZiAoaXNNb3VudGVkKSB7DQogICAgICAgICAgY2FsbFdpdGhBc3luY0Vycm9ySGFuZGxpbmcoDQogICAgICAgICAgICBwbHVnaW5DbGVhbnVwRm5zLA0KICAgICAgICAgICAgYXBwLl9pbnN0YW5jZSwNCiAgICAgICAgICAgIDE2DQogICAgICAgICAgKTsNCiAgICAgICAgICByZW5kZXIobnVsbCwgYXBwLl9jb250YWluZXIpOw0KICAgICAgICAgIHsNCiAgICAgICAgICAgIGFwcC5faW5zdGFuY2UgPSBudWxsOw0KICAgICAgICAgICAgZGV2dG9vbHNVbm1vdW50QXBwKGFwcCk7DQogICAgICAgICAgfQ0KICAgICAgICAgIGRlbGV0ZSBhcHAuX2NvbnRhaW5lci5fX3Z1ZV9hcHBfXzsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICB3YXJuJDEoYENhbm5vdCB1bm1vdW50IGFuIGFwcCB0aGF0IGlzIG5vdCBtb3VudGVkLmApOw0KICAgICAgICB9DQogICAgICB9LA0KICAgICAgcHJvdmlkZShrZXksIHZhbHVlKSB7DQogICAgICAgIGlmIChrZXkgaW4gY29udGV4dC5wcm92aWRlcykgew0KICAgICAgICAgIGlmIChoYXNPd24oY29udGV4dC5wcm92aWRlcywga2V5KSkgew0KICAgICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgICBgQXBwIGFscmVhZHkgcHJvdmlkZXMgcHJvcGVydHkgd2l0aCBrZXkgIiR7U3RyaW5nKGtleSl9Ii4gSXQgd2lsbCBiZSBvdmVyd3JpdHRlbiB3aXRoIHRoZSBuZXcgdmFsdWUuYA0KICAgICAgICAgICAgKTsNCiAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgICBgQXBwIGFscmVhZHkgcHJvdmlkZXMgcHJvcGVydHkgd2l0aCBrZXkgIiR7U3RyaW5nKGtleSl9IiBpbmhlcml0ZWQgZnJvbSBpdHMgcGFyZW50IGVsZW1lbnQuIEl0IHdpbGwgYmUgb3ZlcndyaXR0ZW4gd2l0aCB0aGUgbmV3IHZhbHVlLmANCiAgICAgICAgICAgICk7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGNvbnRleHQucHJvdmlkZXNba2V5XSA9IHZhbHVlOw0KICAgICAgICByZXR1cm4gYXBwOw0KICAgICAgfSwNCiAgICAgIHJ1bldpdGhDb250ZXh0KGZuKSB7DQogICAgICAgIGNvbnN0IGxhc3RBcHAgPSBjdXJyZW50QXBwOw0KICAgICAgICBjdXJyZW50QXBwID0gYXBwOw0KICAgICAgICB0cnkgew0KICAgICAgICAgIHJldHVybiBmbigpOw0KICAgICAgICB9IGZpbmFsbHkgew0KICAgICAgICAgIGN1cnJlbnRBcHAgPSBsYXN0QXBwOw0KICAgICAgICB9DQogICAgICB9DQogICAgfTsNCiAgICByZXR1cm4gYXBwOw0KICB9Ow0KfQ0KbGV0IGN1cnJlbnRBcHAgPSBudWxsOw0KDQpmdW5jdGlvbiBwcm92aWRlKGtleSwgdmFsdWUpIHsNCiAgaWYgKCFjdXJyZW50SW5zdGFuY2UpIHsNCiAgICB7DQogICAgICB3YXJuJDEoYHByb3ZpZGUoKSBjYW4gb25seSBiZSB1c2VkIGluc2lkZSBzZXR1cCgpLmApOw0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICBsZXQgcHJvdmlkZXMgPSBjdXJyZW50SW5zdGFuY2UucHJvdmlkZXM7DQogICAgY29uc3QgcGFyZW50UHJvdmlkZXMgPSBjdXJyZW50SW5zdGFuY2UucGFyZW50ICYmIGN1cnJlbnRJbnN0YW5jZS5wYXJlbnQucHJvdmlkZXM7DQogICAgaWYgKHBhcmVudFByb3ZpZGVzID09PSBwcm92aWRlcykgew0KICAgICAgcHJvdmlkZXMgPSBjdXJyZW50SW5zdGFuY2UucHJvdmlkZXMgPSBPYmplY3QuY3JlYXRlKHBhcmVudFByb3ZpZGVzKTsNCiAgICB9DQogICAgcHJvdmlkZXNba2V5XSA9IHZhbHVlOw0KICB9DQp9DQpmdW5jdGlvbiBpbmplY3Qoa2V5LCBkZWZhdWx0VmFsdWUsIHRyZWF0RGVmYXVsdEFzRmFjdG9yeSA9IGZhbHNlKSB7DQogIGNvbnN0IGluc3RhbmNlID0gY3VycmVudEluc3RhbmNlIHx8IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZTsNCiAgaWYgKGluc3RhbmNlIHx8IGN1cnJlbnRBcHApIHsNCiAgICBsZXQgcHJvdmlkZXMgPSBjdXJyZW50QXBwID8gY3VycmVudEFwcC5fY29udGV4dC5wcm92aWRlcyA6IGluc3RhbmNlID8gaW5zdGFuY2UucGFyZW50ID09IG51bGwgfHwgaW5zdGFuY2UuY2UgPyBpbnN0YW5jZS52bm9kZS5hcHBDb250ZXh0ICYmIGluc3RhbmNlLnZub2RlLmFwcENvbnRleHQucHJvdmlkZXMgOiBpbnN0YW5jZS5wYXJlbnQucHJvdmlkZXMgOiB2b2lkIDA7DQogICAgaWYgKHByb3ZpZGVzICYmIGtleSBpbiBwcm92aWRlcykgew0KICAgICAgcmV0dXJuIHByb3ZpZGVzW2tleV07DQogICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkgew0KICAgICAgcmV0dXJuIHRyZWF0RGVmYXVsdEFzRmFjdG9yeSAmJiBpc0Z1bmN0aW9uKGRlZmF1bHRWYWx1ZSkgPyBkZWZhdWx0VmFsdWUuY2FsbChpbnN0YW5jZSAmJiBpbnN0YW5jZS5wcm94eSkgOiBkZWZhdWx0VmFsdWU7DQogICAgfSBlbHNlIHsNCiAgICAgIHdhcm4kMShgaW5qZWN0aW9uICIke1N0cmluZyhrZXkpfSIgbm90IGZvdW5kLmApOw0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICB3YXJuJDEoYGluamVjdCgpIGNhbiBvbmx5IGJlIHVzZWQgaW5zaWRlIHNldHVwKCkgb3IgZnVuY3Rpb25hbCBjb21wb25lbnRzLmApOw0KICB9DQp9DQpmdW5jdGlvbiBoYXNJbmplY3Rpb25Db250ZXh0KCkgew0KICByZXR1cm4gISEoY3VycmVudEluc3RhbmNlIHx8IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSB8fCBjdXJyZW50QXBwKTsNCn0NCg0KY29uc3QgaW50ZXJuYWxPYmplY3RQcm90byA9IHt9Ow0KY29uc3QgY3JlYXRlSW50ZXJuYWxPYmplY3QgPSAoKSA9PiBPYmplY3QuY3JlYXRlKGludGVybmFsT2JqZWN0UHJvdG8pOw0KY29uc3QgaXNJbnRlcm5hbE9iamVjdCA9IChvYmopID0+IE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmopID09PSBpbnRlcm5hbE9iamVjdFByb3RvOw0KDQpmdW5jdGlvbiBpbml0UHJvcHMoaW5zdGFuY2UsIHJhd1Byb3BzLCBpc1N0YXRlZnVsLCBpc1NTUiA9IGZhbHNlKSB7DQogIGNvbnN0IHByb3BzID0ge307DQogIGNvbnN0IGF0dHJzID0gY3JlYXRlSW50ZXJuYWxPYmplY3QoKTsNCiAgaW5zdGFuY2UucHJvcHNEZWZhdWx0cyA9IC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuY3JlYXRlKG51bGwpOw0KICBzZXRGdWxsUHJvcHMoaW5zdGFuY2UsIHJhd1Byb3BzLCBwcm9wcywgYXR0cnMpOw0KICBmb3IgKGNvbnN0IGtleSBpbiBpbnN0YW5jZS5wcm9wc09wdGlvbnNbMF0pIHsNCiAgICBpZiAoIShrZXkgaW4gcHJvcHMpKSB7DQogICAgICBwcm9wc1trZXldID0gdm9pZCAwOw0KICAgIH0NCiAgfQ0KICB7DQogICAgdmFsaWRhdGVQcm9wcyhyYXdQcm9wcyB8fCB7fSwgcHJvcHMsIGluc3RhbmNlKTsNCiAgfQ0KICBpZiAoaXNTdGF0ZWZ1bCkgew0KICAgIGluc3RhbmNlLnByb3BzID0gaXNTU1IgPyBwcm9wcyA6IHNoYWxsb3dSZWFjdGl2ZShwcm9wcyk7DQogIH0gZWxzZSB7DQogICAgaWYgKCFpbnN0YW5jZS50eXBlLnByb3BzKSB7DQogICAgICBpbnN0YW5jZS5wcm9wcyA9IGF0dHJzOw0KICAgIH0gZWxzZSB7DQogICAgICBpbnN0YW5jZS5wcm9wcyA9IHByb3BzOw0KICAgIH0NCiAgfQ0KICBpbnN0YW5jZS5hdHRycyA9IGF0dHJzOw0KfQ0KZnVuY3Rpb24gaXNJbkhtckNvbnRleHQoaW5zdGFuY2UpIHsNCiAgd2hpbGUgKGluc3RhbmNlKSB7DQogICAgaWYgKGluc3RhbmNlLnR5cGUuX19obXJJZCkgcmV0dXJuIHRydWU7DQogICAgaW5zdGFuY2UgPSBpbnN0YW5jZS5wYXJlbnQ7DQogIH0NCn0NCmZ1bmN0aW9uIHVwZGF0ZVByb3BzKGluc3RhbmNlLCByYXdQcm9wcywgcmF3UHJldlByb3BzLCBvcHRpbWl6ZWQpIHsNCiAgY29uc3Qgew0KICAgIHByb3BzLA0KICAgIGF0dHJzLA0KICAgIHZub2RlOiB7IHBhdGNoRmxhZyB9DQogIH0gPSBpbnN0YW5jZTsNCiAgY29uc3QgcmF3Q3VycmVudFByb3BzID0gdG9SYXcocHJvcHMpOw0KICBjb25zdCBbb3B0aW9uc10gPSBpbnN0YW5jZS5wcm9wc09wdGlvbnM7DQogIGxldCBoYXNBdHRyc0NoYW5nZWQgPSBmYWxzZTsNCiAgaWYgKA0KICAgIC8vIGFsd2F5cyBmb3JjZSBmdWxsIGRpZmYgaW4gZGV2DQogICAgLy8gLSAjMTk0MiBpZiBobXIgaXMgZW5hYmxlZCB3aXRoIHNmYyBjb21wb25lbnQNCiAgICAvLyAtIHZpdGUjODcyIG5vbi1zZmMgY29tcG9uZW50IHVzZWQgYnkgc2ZjIGNvbXBvbmVudA0KICAgICFpc0luSG1yQ29udGV4dChpbnN0YW5jZSkgJiYgKG9wdGltaXplZCB8fCBwYXRjaEZsYWcgPiAwKSAmJiAhKHBhdGNoRmxhZyAmIDE2KQ0KICApIHsNCiAgICBpZiAocGF0Y2hGbGFnICYgOCkgew0KICAgICAgY29uc3QgcHJvcHNUb1VwZGF0ZSA9IGluc3RhbmNlLnZub2RlLmR5bmFtaWNQcm9wczsNCiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcHJvcHNUb1VwZGF0ZS5sZW5ndGg7IGkrKykgew0KICAgICAgICBsZXQga2V5ID0gcHJvcHNUb1VwZGF0ZVtpXTsNCiAgICAgICAgaWYgKGlzRW1pdExpc3RlbmVyKGluc3RhbmNlLmVtaXRzT3B0aW9ucywga2V5KSkgew0KICAgICAgICAgIGNvbnRpbnVlOw0KICAgICAgICB9DQogICAgICAgIGNvbnN0IHZhbHVlID0gcmF3UHJvcHNba2V5XTsNCiAgICAgICAgaWYgKG9wdGlvbnMpIHsNCiAgICAgICAgICBpZiAoaGFzT3duKGF0dHJzLCBrZXkpKSB7DQogICAgICAgICAgICBpZiAodmFsdWUgIT09IGF0dHJzW2tleV0pIHsNCiAgICAgICAgICAgICAgYXR0cnNba2V5XSA9IHZhbHVlOw0KICAgICAgICAgICAgICBoYXNBdHRyc0NoYW5nZWQgPSB0cnVlOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBjb25zdCBjYW1lbGl6ZWRLZXkgPSBjYW1lbGl6ZShrZXkpOw0KICAgICAgICAgICAgcHJvcHNbY2FtZWxpemVkS2V5XSA9IHJlc29sdmVQcm9wVmFsdWUoDQogICAgICAgICAgICAgIG9wdGlvbnMsDQogICAgICAgICAgICAgIHJhd0N1cnJlbnRQcm9wcywNCiAgICAgICAgICAgICAgY2FtZWxpemVkS2V5LA0KICAgICAgICAgICAgICB2YWx1ZSwNCiAgICAgICAgICAgICAgaW5zdGFuY2UsDQogICAgICAgICAgICAgIGZhbHNlDQogICAgICAgICAgICApOw0KICAgICAgICAgIH0NCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBpZiAodmFsdWUgIT09IGF0dHJzW2tleV0pIHsNCiAgICAgICAgICAgIGF0dHJzW2tleV0gPSB2YWx1ZTsNCiAgICAgICAgICAgIGhhc0F0dHJzQ2hhbmdlZCA9IHRydWU7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICB9IGVsc2Ugew0KICAgIGlmIChzZXRGdWxsUHJvcHMoaW5zdGFuY2UsIHJhd1Byb3BzLCBwcm9wcywgYXR0cnMpKSB7DQogICAgICBoYXNBdHRyc0NoYW5nZWQgPSB0cnVlOw0KICAgIH0NCiAgICBsZXQga2ViYWJLZXk7DQogICAgZm9yIChjb25zdCBrZXkgaW4gcmF3Q3VycmVudFByb3BzKSB7DQogICAgICBpZiAoIXJhd1Byb3BzIHx8IC8vIGZvciBjYW1lbENhc2UNCiAgICAgICFoYXNPd24ocmF3UHJvcHMsIGtleSkgJiYgLy8gaXQncyBwb3NzaWJsZSB0aGUgb3JpZ2luYWwgcHJvcHMgd2FzIHBhc3NlZCBpbiBhcyBrZWJhYi1jYXNlDQogICAgICAvLyBhbmQgY29udmVydGVkIHRvIGNhbWVsQ2FzZSAoIzk1NSkNCiAgICAgICgoa2ViYWJLZXkgPSBoeXBoZW5hdGUoa2V5KSkgPT09IGtleSB8fCAhaGFzT3duKHJhd1Byb3BzLCBrZWJhYktleSkpKSB7DQogICAgICAgIGlmIChvcHRpb25zKSB7DQogICAgICAgICAgaWYgKHJhd1ByZXZQcm9wcyAmJiAvLyBmb3IgY2FtZWxDYXNlDQogICAgICAgICAgKHJhd1ByZXZQcm9wc1trZXldICE9PSB2b2lkIDAgfHwgLy8gZm9yIGtlYmFiLWNhc2UNCiAgICAgICAgICByYXdQcmV2UHJvcHNba2ViYWJLZXldICE9PSB2b2lkIDApKSB7DQogICAgICAgICAgICBwcm9wc1trZXldID0gcmVzb2x2ZVByb3BWYWx1ZSgNCiAgICAgICAgICAgICAgb3B0aW9ucywNCiAgICAgICAgICAgICAgcmF3Q3VycmVudFByb3BzLA0KICAgICAgICAgICAgICBrZXksDQogICAgICAgICAgICAgIHZvaWQgMCwNCiAgICAgICAgICAgICAgaW5zdGFuY2UsDQogICAgICAgICAgICAgIHRydWUNCiAgICAgICAgICAgICk7DQogICAgICAgICAgfQ0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIGRlbGV0ZSBwcm9wc1trZXldOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICAgIGlmIChhdHRycyAhPT0gcmF3Q3VycmVudFByb3BzKSB7DQogICAgICBmb3IgKGNvbnN0IGtleSBpbiBhdHRycykgew0KICAgICAgICBpZiAoIXJhd1Byb3BzIHx8ICFoYXNPd24ocmF3UHJvcHMsIGtleSkgJiYgdHJ1ZSkgew0KICAgICAgICAgIGRlbGV0ZSBhdHRyc1trZXldOw0KICAgICAgICAgIGhhc0F0dHJzQ2hhbmdlZCA9IHRydWU7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH0NCiAgaWYgKGhhc0F0dHJzQ2hhbmdlZCkgew0KICAgIHRyaWdnZXIoaW5zdGFuY2UuYXR0cnMsICJzZXQiLCAiIik7DQogIH0NCiAgew0KICAgIHZhbGlkYXRlUHJvcHMocmF3UHJvcHMgfHwge30sIHByb3BzLCBpbnN0YW5jZSk7DQogIH0NCn0NCmZ1bmN0aW9uIHNldEZ1bGxQcm9wcyhpbnN0YW5jZSwgcmF3UHJvcHMsIHByb3BzLCBhdHRycykgew0KICBjb25zdCBbb3B0aW9ucywgbmVlZENhc3RLZXlzXSA9IGluc3RhbmNlLnByb3BzT3B0aW9uczsNCiAgbGV0IGhhc0F0dHJzQ2hhbmdlZCA9IGZhbHNlOw0KICBsZXQgcmF3Q2FzdFZhbHVlczsNCiAgaWYgKHJhd1Byb3BzKSB7DQogICAgZm9yIChsZXQga2V5IGluIHJhd1Byb3BzKSB7DQogICAgICBpZiAoaXNSZXNlcnZlZFByb3Aoa2V5KSkgew0KICAgICAgICBjb250aW51ZTsNCiAgICAgIH0NCiAgICAgIGNvbnN0IHZhbHVlID0gcmF3UHJvcHNba2V5XTsNCiAgICAgIGxldCBjYW1lbEtleTsNCiAgICAgIGlmIChvcHRpb25zICYmIGhhc093bihvcHRpb25zLCBjYW1lbEtleSA9IGNhbWVsaXplKGtleSkpKSB7DQogICAgICAgIGlmICghbmVlZENhc3RLZXlzIHx8ICFuZWVkQ2FzdEtleXMuaW5jbHVkZXMoY2FtZWxLZXkpKSB7DQogICAgICAgICAgcHJvcHNbY2FtZWxLZXldID0gdmFsdWU7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgKHJhd0Nhc3RWYWx1ZXMgfHwgKHJhd0Nhc3RWYWx1ZXMgPSB7fSkpW2NhbWVsS2V5XSA9IHZhbHVlOw0KICAgICAgICB9DQogICAgICB9IGVsc2UgaWYgKCFpc0VtaXRMaXN0ZW5lcihpbnN0YW5jZS5lbWl0c09wdGlvbnMsIGtleSkpIHsNCiAgICAgICAgaWYgKCEoa2V5IGluIGF0dHJzKSB8fCB2YWx1ZSAhPT0gYXR0cnNba2V5XSkgew0KICAgICAgICAgIGF0dHJzW2tleV0gPSB2YWx1ZTsNCiAgICAgICAgICBoYXNBdHRyc0NoYW5nZWQgPSB0cnVlOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICB9DQogIGlmIChuZWVkQ2FzdEtleXMpIHsNCiAgICBjb25zdCByYXdDdXJyZW50UHJvcHMgPSB0b1Jhdyhwcm9wcyk7DQogICAgY29uc3QgY2FzdFZhbHVlcyA9IHJhd0Nhc3RWYWx1ZXMgfHwgRU1QVFlfT0JKOw0KICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbmVlZENhc3RLZXlzLmxlbmd0aDsgaSsrKSB7DQogICAgICBjb25zdCBrZXkgPSBuZWVkQ2FzdEtleXNbaV07DQogICAgICBwcm9wc1trZXldID0gcmVzb2x2ZVByb3BWYWx1ZSgNCiAgICAgICAgb3B0aW9ucywNCiAgICAgICAgcmF3Q3VycmVudFByb3BzLA0KICAgICAgICBrZXksDQogICAgICAgIGNhc3RWYWx1ZXNba2V5XSwNCiAgICAgICAgaW5zdGFuY2UsDQogICAgICAgICFoYXNPd24oY2FzdFZhbHVlcywga2V5KQ0KICAgICAgKTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIGhhc0F0dHJzQ2hhbmdlZDsNCn0NCmZ1bmN0aW9uIHJlc29sdmVQcm9wVmFsdWUob3B0aW9ucywgcHJvcHMsIGtleSwgdmFsdWUsIGluc3RhbmNlLCBpc0Fic2VudCkgew0KICBjb25zdCBvcHQgPSBvcHRpb25zW2tleV07DQogIGlmIChvcHQgIT0gbnVsbCkgew0KICAgIGNvbnN0IGhhc0RlZmF1bHQgPSBoYXNPd24ob3B0LCAiZGVmYXVsdCIpOw0KICAgIGlmIChoYXNEZWZhdWx0ICYmIHZhbHVlID09PSB2b2lkIDApIHsNCiAgICAgIGNvbnN0IGRlZmF1bHRWYWx1ZSA9IG9wdC5kZWZhdWx0Ow0KICAgICAgaWYgKG9wdC50eXBlICE9PSBGdW5jdGlvbiAmJiAhb3B0LnNraXBGYWN0b3J5ICYmIGlzRnVuY3Rpb24oZGVmYXVsdFZhbHVlKSkgew0KICAgICAgICBjb25zdCB7IHByb3BzRGVmYXVsdHMgfSA9IGluc3RhbmNlOw0KICAgICAgICBpZiAoa2V5IGluIHByb3BzRGVmYXVsdHMpIHsNCiAgICAgICAgICB2YWx1ZSA9IHByb3BzRGVmYXVsdHNba2V5XTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBjb25zdCByZXNldCA9IHNldEN1cnJlbnRJbnN0YW5jZShpbnN0YW5jZSk7DQogICAgICAgICAgdmFsdWUgPSBwcm9wc0RlZmF1bHRzW2tleV0gPSBkZWZhdWx0VmFsdWUuY2FsbCgNCiAgICAgICAgICAgIG51bGwsDQogICAgICAgICAgICBwcm9wcw0KICAgICAgICAgICk7DQogICAgICAgICAgcmVzZXQoKTsNCiAgICAgICAgfQ0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgdmFsdWUgPSBkZWZhdWx0VmFsdWU7DQogICAgICB9DQogICAgICBpZiAoaW5zdGFuY2UuY2UpIHsNCiAgICAgICAgaW5zdGFuY2UuY2UuX3NldFByb3Aoa2V5LCB2YWx1ZSk7DQogICAgICB9DQogICAgfQ0KICAgIGlmIChvcHRbMCAvKiBzaG91bGRDYXN0ICovXSkgew0KICAgICAgaWYgKGlzQWJzZW50ICYmICFoYXNEZWZhdWx0KSB7DQogICAgICAgIHZhbHVlID0gZmFsc2U7DQogICAgICB9IGVsc2UgaWYgKG9wdFsxIC8qIHNob3VsZENhc3RUcnVlICovXSAmJiAodmFsdWUgPT09ICIiIHx8IHZhbHVlID09PSBoeXBoZW5hdGUoa2V5KSkpIHsNCiAgICAgICAgdmFsdWUgPSB0cnVlOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICByZXR1cm4gdmFsdWU7DQp9DQpjb25zdCBtaXhpblByb3BzQ2FjaGUgPSAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtNYXAoKTsNCmZ1bmN0aW9uIG5vcm1hbGl6ZVByb3BzT3B0aW9ucyhjb21wLCBhcHBDb250ZXh0LCBhc01peGluID0gZmFsc2UpIHsNCiAgY29uc3QgY2FjaGUgPSBhc01peGluID8gbWl4aW5Qcm9wc0NhY2hlIDogYXBwQ29udGV4dC5wcm9wc0NhY2hlOw0KICBjb25zdCBjYWNoZWQgPSBjYWNoZS5nZXQoY29tcCk7DQogIGlmIChjYWNoZWQpIHsNCiAgICByZXR1cm4gY2FjaGVkOw0KICB9DQogIGNvbnN0IHJhdyA9IGNvbXAucHJvcHM7DQogIGNvbnN0IG5vcm1hbGl6ZWQgPSB7fTsNCiAgY29uc3QgbmVlZENhc3RLZXlzID0gW107DQogIGxldCBoYXNFeHRlbmRzID0gZmFsc2U7DQogIGlmICghaXNGdW5jdGlvbihjb21wKSkgew0KICAgIGNvbnN0IGV4dGVuZFByb3BzID0gKHJhdzIpID0+IHsNCiAgICAgIGhhc0V4dGVuZHMgPSB0cnVlOw0KICAgICAgY29uc3QgW3Byb3BzLCBrZXlzXSA9IG5vcm1hbGl6ZVByb3BzT3B0aW9ucyhyYXcyLCBhcHBDb250ZXh0LCB0cnVlKTsNCiAgICAgIGV4dGVuZChub3JtYWxpemVkLCBwcm9wcyk7DQogICAgICBpZiAoa2V5cykgbmVlZENhc3RLZXlzLnB1c2goLi4ua2V5cyk7DQogICAgfTsNCiAgICBpZiAoIWFzTWl4aW4gJiYgYXBwQ29udGV4dC5taXhpbnMubGVuZ3RoKSB7DQogICAgICBhcHBDb250ZXh0Lm1peGlucy5mb3JFYWNoKGV4dGVuZFByb3BzKTsNCiAgICB9DQogICAgaWYgKGNvbXAuZXh0ZW5kcykgew0KICAgICAgZXh0ZW5kUHJvcHMoY29tcC5leHRlbmRzKTsNCiAgICB9DQogICAgaWYgKGNvbXAubWl4aW5zKSB7DQogICAgICBjb21wLm1peGlucy5mb3JFYWNoKGV4dGVuZFByb3BzKTsNCiAgICB9DQogIH0NCiAgaWYgKCFyYXcgJiYgIWhhc0V4dGVuZHMpIHsNCiAgICBpZiAoaXNPYmplY3QoY29tcCkpIHsNCiAgICAgIGNhY2hlLnNldChjb21wLCBFTVBUWV9BUlIpOw0KICAgIH0NCiAgICByZXR1cm4gRU1QVFlfQVJSOw0KICB9DQogIGlmIChpc0FycmF5KHJhdykpIHsNCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhdy5sZW5ndGg7IGkrKykgew0KICAgICAgaWYgKCFpc1N0cmluZyhyYXdbaV0pKSB7DQogICAgICAgIHdhcm4kMShgcHJvcHMgbXVzdCBiZSBzdHJpbmdzIHdoZW4gdXNpbmcgYXJyYXkgc3ludGF4LmAsIHJhd1tpXSk7DQogICAgICB9DQogICAgICBjb25zdCBub3JtYWxpemVkS2V5ID0gY2FtZWxpemUocmF3W2ldKTsNCiAgICAgIGlmICh2YWxpZGF0ZVByb3BOYW1lKG5vcm1hbGl6ZWRLZXkpKSB7DQogICAgICAgIG5vcm1hbGl6ZWRbbm9ybWFsaXplZEtleV0gPSBFTVBUWV9PQko7DQogICAgICB9DQogICAgfQ0KICB9IGVsc2UgaWYgKHJhdykgew0KICAgIGlmICghaXNPYmplY3QocmF3KSkgew0KICAgICAgd2FybiQxKGBpbnZhbGlkIHByb3BzIG9wdGlvbnNgLCByYXcpOw0KICAgIH0NCiAgICBmb3IgKGNvbnN0IGtleSBpbiByYXcpIHsNCiAgICAgIGNvbnN0IG5vcm1hbGl6ZWRLZXkgPSBjYW1lbGl6ZShrZXkpOw0KICAgICAgaWYgKHZhbGlkYXRlUHJvcE5hbWUobm9ybWFsaXplZEtleSkpIHsNCiAgICAgICAgY29uc3Qgb3B0ID0gcmF3W2tleV07DQogICAgICAgIGNvbnN0IHByb3AgPSBub3JtYWxpemVkW25vcm1hbGl6ZWRLZXldID0gaXNBcnJheShvcHQpIHx8IGlzRnVuY3Rpb24ob3B0KSA/IHsgdHlwZTogb3B0IH0gOiBleHRlbmQoe30sIG9wdCk7DQogICAgICAgIGNvbnN0IHByb3BUeXBlID0gcHJvcC50eXBlOw0KICAgICAgICBsZXQgc2hvdWxkQ2FzdCA9IGZhbHNlOw0KICAgICAgICBsZXQgc2hvdWxkQ2FzdFRydWUgPSB0cnVlOw0KICAgICAgICBpZiAoaXNBcnJheShwcm9wVHlwZSkpIHsNCiAgICAgICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgcHJvcFR5cGUubGVuZ3RoOyArK2luZGV4KSB7DQogICAgICAgICAgICBjb25zdCB0eXBlID0gcHJvcFR5cGVbaW5kZXhdOw0KICAgICAgICAgICAgY29uc3QgdHlwZU5hbWUgPSBpc0Z1bmN0aW9uKHR5cGUpICYmIHR5cGUubmFtZTsNCiAgICAgICAgICAgIGlmICh0eXBlTmFtZSA9PT0gIkJvb2xlYW4iKSB7DQogICAgICAgICAgICAgIHNob3VsZENhc3QgPSB0cnVlOw0KICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZU5hbWUgPT09ICJTdHJpbmciKSB7DQogICAgICAgICAgICAgIHNob3VsZENhc3RUcnVlID0gZmFsc2U7DQogICAgICAgICAgICB9DQogICAgICAgICAgfQ0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIHNob3VsZENhc3QgPSBpc0Z1bmN0aW9uKHByb3BUeXBlKSAmJiBwcm9wVHlwZS5uYW1lID09PSAiQm9vbGVhbiI7DQogICAgICAgIH0NCiAgICAgICAgcHJvcFswIC8qIHNob3VsZENhc3QgKi9dID0gc2hvdWxkQ2FzdDsNCiAgICAgICAgcHJvcFsxIC8qIHNob3VsZENhc3RUcnVlICovXSA9IHNob3VsZENhc3RUcnVlOw0KICAgICAgICBpZiAoc2hvdWxkQ2FzdCB8fCBoYXNPd24ocHJvcCwgImRlZmF1bHQiKSkgew0KICAgICAgICAgIG5lZWRDYXN0S2V5cy5wdXNoKG5vcm1hbGl6ZWRLZXkpOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICB9DQogIGNvbnN0IHJlcyA9IFtub3JtYWxpemVkLCBuZWVkQ2FzdEtleXNdOw0KICBpZiAoaXNPYmplY3QoY29tcCkpIHsNCiAgICBjYWNoZS5zZXQoY29tcCwgcmVzKTsNCiAgfQ0KICByZXR1cm4gcmVzOw0KfQ0KZnVuY3Rpb24gdmFsaWRhdGVQcm9wTmFtZShrZXkpIHsNCiAgaWYgKGtleVswXSAhPT0gIiQiICYmICFpc1Jlc2VydmVkUHJvcChrZXkpKSB7DQogICAgcmV0dXJuIHRydWU7DQogIH0gZWxzZSB7DQogICAgd2FybiQxKGBJbnZhbGlkIHByb3AgbmFtZTogIiR7a2V5fSIgaXMgYSByZXNlcnZlZCBwcm9wZXJ0eS5gKTsNCiAgfQ0KICByZXR1cm4gZmFsc2U7DQp9DQpmdW5jdGlvbiBnZXRUeXBlKGN0b3IpIHsNCiAgaWYgKGN0b3IgPT09IG51bGwpIHsNCiAgICByZXR1cm4gIm51bGwiOw0KICB9DQogIGlmICh0eXBlb2YgY3RvciA9PT0gImZ1bmN0aW9uIikgew0KICAgIHJldHVybiBjdG9yLm5hbWUgfHwgIiI7DQogIH0gZWxzZSBpZiAodHlwZW9mIGN0b3IgPT09ICJvYmplY3QiKSB7DQogICAgY29uc3QgbmFtZSA9IGN0b3IuY29uc3RydWN0b3IgJiYgY3Rvci5jb25zdHJ1Y3Rvci5uYW1lOw0KICAgIHJldHVybiBuYW1lIHx8ICIiOw0KICB9DQogIHJldHVybiAiIjsNCn0NCmZ1bmN0aW9uIHZhbGlkYXRlUHJvcHMocmF3UHJvcHMsIHByb3BzLCBpbnN0YW5jZSkgew0KICBjb25zdCByZXNvbHZlZFZhbHVlcyA9IHRvUmF3KHByb3BzKTsNCiAgY29uc3Qgb3B0aW9ucyA9IGluc3RhbmNlLnByb3BzT3B0aW9uc1swXTsNCiAgY29uc3QgY2FtZWxpemVQcm9wc0tleSA9IE9iamVjdC5rZXlzKHJhd1Byb3BzKS5tYXAoKGtleSkgPT4gY2FtZWxpemUoa2V5KSk7DQogIGZvciAoY29uc3Qga2V5IGluIG9wdGlvbnMpIHsNCiAgICBsZXQgb3B0ID0gb3B0aW9uc1trZXldOw0KICAgIGlmIChvcHQgPT0gbnVsbCkgY29udGludWU7DQogICAgdmFsaWRhdGVQcm9wKA0KICAgICAga2V5LA0KICAgICAgcmVzb2x2ZWRWYWx1ZXNba2V5XSwNCiAgICAgIG9wdCwNCiAgICAgIHNoYWxsb3dSZWFkb25seShyZXNvbHZlZFZhbHVlcykgLA0KICAgICAgIWNhbWVsaXplUHJvcHNLZXkuaW5jbHVkZXMoa2V5KQ0KICAgICk7DQogIH0NCn0NCmZ1bmN0aW9uIHZhbGlkYXRlUHJvcChuYW1lLCB2YWx1ZSwgcHJvcCwgcHJvcHMsIGlzQWJzZW50KSB7DQogIGNvbnN0IHsgdHlwZSwgcmVxdWlyZWQsIHZhbGlkYXRvciwgc2tpcENoZWNrIH0gPSBwcm9wOw0KICBpZiAocmVxdWlyZWQgJiYgaXNBYnNlbnQpIHsNCiAgICB3YXJuJDEoJ01pc3NpbmcgcmVxdWlyZWQgcHJvcDogIicgKyBuYW1lICsgJyInKTsNCiAgICByZXR1cm47DQogIH0NCiAgaWYgKHZhbHVlID09IG51bGwgJiYgIXJlcXVpcmVkKSB7DQogICAgcmV0dXJuOw0KICB9DQogIGlmICh0eXBlICE9IG51bGwgJiYgdHlwZSAhPT0gdHJ1ZSAmJiAhc2tpcENoZWNrKSB7DQogICAgbGV0IGlzVmFsaWQgPSBmYWxzZTsNCiAgICBjb25zdCB0eXBlcyA9IGlzQXJyYXkodHlwZSkgPyB0eXBlIDogW3R5cGVdOw0KICAgIGNvbnN0IGV4cGVjdGVkVHlwZXMgPSBbXTsNCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHR5cGVzLmxlbmd0aCAmJiAhaXNWYWxpZDsgaSsrKSB7DQogICAgICBjb25zdCB7IHZhbGlkLCBleHBlY3RlZFR5cGUgfSA9IGFzc2VydFR5cGUodmFsdWUsIHR5cGVzW2ldKTsNCiAgICAgIGV4cGVjdGVkVHlwZXMucHVzaChleHBlY3RlZFR5cGUgfHwgIiIpOw0KICAgICAgaXNWYWxpZCA9IHZhbGlkOw0KICAgIH0NCiAgICBpZiAoIWlzVmFsaWQpIHsNCiAgICAgIHdhcm4kMShnZXRJbnZhbGlkVHlwZU1lc3NhZ2UobmFtZSwgdmFsdWUsIGV4cGVjdGVkVHlwZXMpKTsNCiAgICAgIHJldHVybjsNCiAgICB9DQogIH0NCiAgaWYgKHZhbGlkYXRvciAmJiAhdmFsaWRhdG9yKHZhbHVlLCBwcm9wcykpIHsNCiAgICB3YXJuJDEoJ0ludmFsaWQgcHJvcDogY3VzdG9tIHZhbGlkYXRvciBjaGVjayBmYWlsZWQgZm9yIHByb3AgIicgKyBuYW1lICsgJyIuJyk7DQogIH0NCn0NCmNvbnN0IGlzU2ltcGxlVHlwZSA9IC8qIEBfX1BVUkVfXyAqLyBtYWtlTWFwKA0KICAiU3RyaW5nLE51bWJlcixCb29sZWFuLEZ1bmN0aW9uLFN5bWJvbCxCaWdJbnQiDQopOw0KZnVuY3Rpb24gYXNzZXJ0VHlwZSh2YWx1ZSwgdHlwZSkgew0KICBsZXQgdmFsaWQ7DQogIGNvbnN0IGV4cGVjdGVkVHlwZSA9IGdldFR5cGUodHlwZSk7DQogIGlmIChleHBlY3RlZFR5cGUgPT09ICJudWxsIikgew0KICAgIHZhbGlkID0gdmFsdWUgPT09IG51bGw7DQogIH0gZWxzZSBpZiAoaXNTaW1wbGVUeXBlKGV4cGVjdGVkVHlwZSkpIHsNCiAgICBjb25zdCB0ID0gdHlwZW9mIHZhbHVlOw0KICAgIHZhbGlkID0gdCA9PT0gZXhwZWN0ZWRUeXBlLnRvTG93ZXJDYXNlKCk7DQogICAgaWYgKCF2YWxpZCAmJiB0ID09PSAib2JqZWN0Iikgew0KICAgICAgdmFsaWQgPSB2YWx1ZSBpbnN0YW5jZW9mIHR5cGU7DQogICAgfQ0KICB9IGVsc2UgaWYgKGV4cGVjdGVkVHlwZSA9PT0gIk9iamVjdCIpIHsNCiAgICB2YWxpZCA9IGlzT2JqZWN0KHZhbHVlKTsNCiAgfSBlbHNlIGlmIChleHBlY3RlZFR5cGUgPT09ICJBcnJheSIpIHsNCiAgICB2YWxpZCA9IGlzQXJyYXkodmFsdWUpOw0KICB9IGVsc2Ugew0KICAgIHZhbGlkID0gdmFsdWUgaW5zdGFuY2VvZiB0eXBlOw0KICB9DQogIHJldHVybiB7DQogICAgdmFsaWQsDQogICAgZXhwZWN0ZWRUeXBlDQogIH07DQp9DQpmdW5jdGlvbiBnZXRJbnZhbGlkVHlwZU1lc3NhZ2UobmFtZSwgdmFsdWUsIGV4cGVjdGVkVHlwZXMpIHsNCiAgaWYgKGV4cGVjdGVkVHlwZXMubGVuZ3RoID09PSAwKSB7DQogICAgcmV0dXJuIGBQcm9wIHR5cGUgW10gZm9yIHByb3AgIiR7bmFtZX0iIHdvbid0IG1hdGNoIGFueXRoaW5nLiBEaWQgeW91IG1lYW4gdG8gdXNlIHR5cGUgQXJyYXkgaW5zdGVhZD9gOw0KICB9DQogIGxldCBtZXNzYWdlID0gYEludmFsaWQgcHJvcDogdHlwZSBjaGVjayBmYWlsZWQgZm9yIHByb3AgIiR7bmFtZX0iLiBFeHBlY3RlZCAke2V4cGVjdGVkVHlwZXMubWFwKGNhcGl0YWxpemUpLmpvaW4oIiB8ICIpfWA7DQogIGNvbnN0IGV4cGVjdGVkVHlwZSA9IGV4cGVjdGVkVHlwZXNbMF07DQogIGNvbnN0IHJlY2VpdmVkVHlwZSA9IHRvUmF3VHlwZSh2YWx1ZSk7DQogIGNvbnN0IGV4cGVjdGVkVmFsdWUgPSBzdHlsZVZhbHVlKHZhbHVlLCBleHBlY3RlZFR5cGUpOw0KICBjb25zdCByZWNlaXZlZFZhbHVlID0gc3R5bGVWYWx1ZSh2YWx1ZSwgcmVjZWl2ZWRUeXBlKTsNCiAgaWYgKGV4cGVjdGVkVHlwZXMubGVuZ3RoID09PSAxICYmIGlzRXhwbGljYWJsZShleHBlY3RlZFR5cGUpICYmICFpc0Jvb2xlYW4oZXhwZWN0ZWRUeXBlLCByZWNlaXZlZFR5cGUpKSB7DQogICAgbWVzc2FnZSArPSBgIHdpdGggdmFsdWUgJHtleHBlY3RlZFZhbHVlfWA7DQogIH0NCiAgbWVzc2FnZSArPSBgLCBnb3QgJHtyZWNlaXZlZFR5cGV9IGA7DQogIGlmIChpc0V4cGxpY2FibGUocmVjZWl2ZWRUeXBlKSkgew0KICAgIG1lc3NhZ2UgKz0gYHdpdGggdmFsdWUgJHtyZWNlaXZlZFZhbHVlfS5gOw0KICB9DQogIHJldHVybiBtZXNzYWdlOw0KfQ0KZnVuY3Rpb24gc3R5bGVWYWx1ZSh2YWx1ZSwgdHlwZSkgew0KICBpZiAodHlwZSA9PT0gIlN0cmluZyIpIHsNCiAgICByZXR1cm4gYCIke3ZhbHVlfSJgOw0KICB9IGVsc2UgaWYgKHR5cGUgPT09ICJOdW1iZXIiKSB7DQogICAgcmV0dXJuIGAke051bWJlcih2YWx1ZSl9YDsNCiAgfSBlbHNlIHsNCiAgICByZXR1cm4gYCR7dmFsdWV9YDsNCiAgfQ0KfQ0KZnVuY3Rpb24gaXNFeHBsaWNhYmxlKHR5cGUpIHsNCiAgY29uc3QgZXhwbGljaXRUeXBlcyA9IFsic3RyaW5nIiwgIm51bWJlciIsICJib29sZWFuIl07DQogIHJldHVybiBleHBsaWNpdFR5cGVzLnNvbWUoKGVsZW0pID0+IHR5cGUudG9Mb3dlckNhc2UoKSA9PT0gZWxlbSk7DQp9DQpmdW5jdGlvbiBpc0Jvb2xlYW4oLi4uYXJncykgew0KICByZXR1cm4gYXJncy5zb21lKChlbGVtKSA9PiBlbGVtLnRvTG93ZXJDYXNlKCkgPT09ICJib29sZWFuIik7DQp9DQoNCmNvbnN0IGlzSW50ZXJuYWxLZXkgPSAoa2V5KSA9PiBrZXlbMF0gPT09ICJfIiB8fCBrZXkgPT09ICIkc3RhYmxlIjsNCmNvbnN0IG5vcm1hbGl6ZVNsb3RWYWx1ZSA9ICh2YWx1ZSkgPT4gaXNBcnJheSh2YWx1ZSkgPyB2YWx1ZS5tYXAobm9ybWFsaXplVk5vZGUpIDogW25vcm1hbGl6ZVZOb2RlKHZhbHVlKV07DQpjb25zdCBub3JtYWxpemVTbG90ID0gKGtleSwgcmF3U2xvdCwgY3R4KSA9PiB7DQogIGlmIChyYXdTbG90Ll9uKSB7DQogICAgcmV0dXJuIHJhd1Nsb3Q7DQogIH0NCiAgY29uc3Qgbm9ybWFsaXplZCA9IHdpdGhDdHgoKC4uLmFyZ3MpID0+IHsNCiAgICBpZiAoY3VycmVudEluc3RhbmNlICYmICEoY3R4ID09PSBudWxsICYmIGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSkgJiYgIShjdHggJiYgY3R4LnJvb3QgIT09IGN1cnJlbnRJbnN0YW5jZS5yb290KSkgew0KICAgICAgd2FybiQxKA0KICAgICAgICBgU2xvdCAiJHtrZXl9IiBpbnZva2VkIG91dHNpZGUgb2YgdGhlIHJlbmRlciBmdW5jdGlvbjogdGhpcyB3aWxsIG5vdCB0cmFjayBkZXBlbmRlbmNpZXMgdXNlZCBpbiB0aGUgc2xvdC4gSW52b2tlIHRoZSBzbG90IGZ1bmN0aW9uIGluc2lkZSB0aGUgcmVuZGVyIGZ1bmN0aW9uIGluc3RlYWQuYA0KICAgICAgKTsNCiAgICB9DQogICAgcmV0dXJuIG5vcm1hbGl6ZVNsb3RWYWx1ZShyYXdTbG90KC4uLmFyZ3MpKTsNCiAgfSwgY3R4KTsNCiAgbm9ybWFsaXplZC5fYyA9IGZhbHNlOw0KICByZXR1cm4gbm9ybWFsaXplZDsNCn07DQpjb25zdCBub3JtYWxpemVPYmplY3RTbG90cyA9IChyYXdTbG90cywgc2xvdHMsIGluc3RhbmNlKSA9PiB7DQogIGNvbnN0IGN0eCA9IHJhd1Nsb3RzLl9jdHg7DQogIGZvciAoY29uc3Qga2V5IGluIHJhd1Nsb3RzKSB7DQogICAgaWYgKGlzSW50ZXJuYWxLZXkoa2V5KSkgY29udGludWU7DQogICAgY29uc3QgdmFsdWUgPSByYXdTbG90c1trZXldOw0KICAgIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkgew0KICAgICAgc2xvdHNba2V5XSA9IG5vcm1hbGl6ZVNsb3Qoa2V5LCB2YWx1ZSwgY3R4KTsNCiAgICB9IGVsc2UgaWYgKHZhbHVlICE9IG51bGwpIHsNCiAgICAgIHsNCiAgICAgICAgd2FybiQxKA0KICAgICAgICAgIGBOb24tZnVuY3Rpb24gdmFsdWUgZW5jb3VudGVyZWQgZm9yIHNsb3QgIiR7a2V5fSIuIFByZWZlciBmdW5jdGlvbiBzbG90cyBmb3IgYmV0dGVyIHBlcmZvcm1hbmNlLmANCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBub3JtYWxpemVTbG90VmFsdWUodmFsdWUpOw0KICAgICAgc2xvdHNba2V5XSA9ICgpID0+IG5vcm1hbGl6ZWQ7DQogICAgfQ0KICB9DQp9Ow0KY29uc3Qgbm9ybWFsaXplVk5vZGVTbG90cyA9IChpbnN0YW5jZSwgY2hpbGRyZW4pID0+IHsNCiAgaWYgKCFpc0tlZXBBbGl2ZShpbnN0YW5jZS52bm9kZSkgJiYgdHJ1ZSkgew0KICAgIHdhcm4kMSgNCiAgICAgIGBOb24tZnVuY3Rpb24gdmFsdWUgZW5jb3VudGVyZWQgZm9yIGRlZmF1bHQgc2xvdC4gUHJlZmVyIGZ1bmN0aW9uIHNsb3RzIGZvciBiZXR0ZXIgcGVyZm9ybWFuY2UuYA0KICAgICk7DQogIH0NCiAgY29uc3Qgbm9ybWFsaXplZCA9IG5vcm1hbGl6ZVNsb3RWYWx1ZShjaGlsZHJlbik7DQogIGluc3RhbmNlLnNsb3RzLmRlZmF1bHQgPSAoKSA9PiBub3JtYWxpemVkOw0KfTsNCmNvbnN0IGFzc2lnblNsb3RzID0gKHNsb3RzLCBjaGlsZHJlbiwgb3B0aW1pemVkKSA9PiB7DQogIGZvciAoY29uc3Qga2V5IGluIGNoaWxkcmVuKSB7DQogICAgaWYgKG9wdGltaXplZCB8fCAhaXNJbnRlcm5hbEtleShrZXkpKSB7DQogICAgICBzbG90c1trZXldID0gY2hpbGRyZW5ba2V5XTsNCiAgICB9DQogIH0NCn07DQpjb25zdCBpbml0U2xvdHMgPSAoaW5zdGFuY2UsIGNoaWxkcmVuLCBvcHRpbWl6ZWQpID0+IHsNCiAgY29uc3Qgc2xvdHMgPSBpbnN0YW5jZS5zbG90cyA9IGNyZWF0ZUludGVybmFsT2JqZWN0KCk7DQogIGlmIChpbnN0YW5jZS52bm9kZS5zaGFwZUZsYWcgJiAzMikgew0KICAgIGNvbnN0IGNhY2hlSW5kZXhlcyA9IGNoaWxkcmVuLl9fOw0KICAgIGlmIChjYWNoZUluZGV4ZXMpIGRlZihzbG90cywgIl9fIiwgY2FjaGVJbmRleGVzLCB0cnVlKTsNCiAgICBjb25zdCB0eXBlID0gY2hpbGRyZW4uXzsNCiAgICBpZiAodHlwZSkgew0KICAgICAgYXNzaWduU2xvdHMoc2xvdHMsIGNoaWxkcmVuLCBvcHRpbWl6ZWQpOw0KICAgICAgaWYgKG9wdGltaXplZCkgew0KICAgICAgICBkZWYoc2xvdHMsICJfIiwgdHlwZSwgdHJ1ZSk7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIG5vcm1hbGl6ZU9iamVjdFNsb3RzKGNoaWxkcmVuLCBzbG90cyk7DQogICAgfQ0KICB9IGVsc2UgaWYgKGNoaWxkcmVuKSB7DQogICAgbm9ybWFsaXplVk5vZGVTbG90cyhpbnN0YW5jZSwgY2hpbGRyZW4pOw0KICB9DQp9Ow0KY29uc3QgdXBkYXRlU2xvdHMgPSAoaW5zdGFuY2UsIGNoaWxkcmVuLCBvcHRpbWl6ZWQpID0+IHsNCiAgY29uc3QgeyB2bm9kZSwgc2xvdHMgfSA9IGluc3RhbmNlOw0KICBsZXQgbmVlZERlbGV0aW9uQ2hlY2sgPSB0cnVlOw0KICBsZXQgZGVsZXRpb25Db21wYXJpc29uVGFyZ2V0ID0gRU1QVFlfT0JKOw0KICBpZiAodm5vZGUuc2hhcGVGbGFnICYgMzIpIHsNCiAgICBjb25zdCB0eXBlID0gY2hpbGRyZW4uXzsNCiAgICBpZiAodHlwZSkgew0KICAgICAgaWYgKGlzSG1yVXBkYXRpbmcpIHsNCiAgICAgICAgYXNzaWduU2xvdHMoc2xvdHMsIGNoaWxkcmVuLCBvcHRpbWl6ZWQpOw0KICAgICAgICB0cmlnZ2VyKGluc3RhbmNlLCAic2V0IiwgIiRzbG90cyIpOw0KICAgICAgfSBlbHNlIGlmIChvcHRpbWl6ZWQgJiYgdHlwZSA9PT0gMSkgew0KICAgICAgICBuZWVkRGVsZXRpb25DaGVjayA9IGZhbHNlOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgYXNzaWduU2xvdHMoc2xvdHMsIGNoaWxkcmVuLCBvcHRpbWl6ZWQpOw0KICAgICAgfQ0KICAgIH0gZWxzZSB7DQogICAgICBuZWVkRGVsZXRpb25DaGVjayA9ICFjaGlsZHJlbi4kc3RhYmxlOw0KICAgICAgbm9ybWFsaXplT2JqZWN0U2xvdHMoY2hpbGRyZW4sIHNsb3RzKTsNCiAgICB9DQogICAgZGVsZXRpb25Db21wYXJpc29uVGFyZ2V0ID0gY2hpbGRyZW47DQogIH0gZWxzZSBpZiAoY2hpbGRyZW4pIHsNCiAgICBub3JtYWxpemVWTm9kZVNsb3RzKGluc3RhbmNlLCBjaGlsZHJlbik7DQogICAgZGVsZXRpb25Db21wYXJpc29uVGFyZ2V0ID0geyBkZWZhdWx0OiAxIH07DQogIH0NCiAgaWYgKG5lZWREZWxldGlvbkNoZWNrKSB7DQogICAgZm9yIChjb25zdCBrZXkgaW4gc2xvdHMpIHsNCiAgICAgIGlmICghaXNJbnRlcm5hbEtleShrZXkpICYmIGRlbGV0aW9uQ29tcGFyaXNvblRhcmdldFtrZXldID09IG51bGwpIHsNCiAgICAgICAgZGVsZXRlIHNsb3RzW2tleV07DQogICAgICB9DQogICAgfQ0KICB9DQp9Ow0KDQpsZXQgc3VwcG9ydGVkOw0KbGV0IHBlcmY7DQpmdW5jdGlvbiBzdGFydE1lYXN1cmUoaW5zdGFuY2UsIHR5cGUpIHsNCiAgaWYgKGluc3RhbmNlLmFwcENvbnRleHQuY29uZmlnLnBlcmZvcm1hbmNlICYmIGlzU3VwcG9ydGVkKCkpIHsNCiAgICBwZXJmLm1hcmsoYHZ1ZS0ke3R5cGV9LSR7aW5zdGFuY2UudWlkfWApOw0KICB9DQogIHsNCiAgICBkZXZ0b29sc1BlcmZTdGFydChpbnN0YW5jZSwgdHlwZSwgaXNTdXBwb3J0ZWQoKSA/IHBlcmYubm93KCkgOiBEYXRlLm5vdygpKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gZW5kTWVhc3VyZShpbnN0YW5jZSwgdHlwZSkgew0KICBpZiAoaW5zdGFuY2UuYXBwQ29udGV4dC5jb25maWcucGVyZm9ybWFuY2UgJiYgaXNTdXBwb3J0ZWQoKSkgew0KICAgIGNvbnN0IHN0YXJ0VGFnID0gYHZ1ZS0ke3R5cGV9LSR7aW5zdGFuY2UudWlkfWA7DQogICAgY29uc3QgZW5kVGFnID0gc3RhcnRUYWcgKyBgOmVuZGA7DQogICAgcGVyZi5tYXJrKGVuZFRhZyk7DQogICAgcGVyZi5tZWFzdXJlKA0KICAgICAgYDwke2Zvcm1hdENvbXBvbmVudE5hbWUoaW5zdGFuY2UsIGluc3RhbmNlLnR5cGUpfT4gJHt0eXBlfWAsDQogICAgICBzdGFydFRhZywNCiAgICAgIGVuZFRhZw0KICAgICk7DQogICAgcGVyZi5jbGVhck1hcmtzKHN0YXJ0VGFnKTsNCiAgICBwZXJmLmNsZWFyTWFya3MoZW5kVGFnKTsNCiAgfQ0KICB7DQogICAgZGV2dG9vbHNQZXJmRW5kKGluc3RhbmNlLCB0eXBlLCBpc1N1cHBvcnRlZCgpID8gcGVyZi5ub3coKSA6IERhdGUubm93KCkpOw0KICB9DQp9DQpmdW5jdGlvbiBpc1N1cHBvcnRlZCgpIHsNCiAgaWYgKHN1cHBvcnRlZCAhPT0gdm9pZCAwKSB7DQogICAgcmV0dXJuIHN1cHBvcnRlZDsNCiAgfQ0KICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gInVuZGVmaW5lZCIgJiYgd2luZG93LnBlcmZvcm1hbmNlKSB7DQogICAgc3VwcG9ydGVkID0gdHJ1ZTsNCiAgICBwZXJmID0gd2luZG93LnBlcmZvcm1hbmNlOw0KICB9IGVsc2Ugew0KICAgIHN1cHBvcnRlZCA9IGZhbHNlOw0KICB9DQogIHJldHVybiBzdXBwb3J0ZWQ7DQp9DQoNCmNvbnN0IHF1ZXVlUG9zdFJlbmRlckVmZmVjdCA9IHF1ZXVlRWZmZWN0V2l0aFN1c3BlbnNlIDsNCmZ1bmN0aW9uIGNyZWF0ZVJlbmRlcmVyKG9wdGlvbnMpIHsNCiAgcmV0dXJuIGJhc2VDcmVhdGVSZW5kZXJlcihvcHRpb25zKTsNCn0NCmZ1bmN0aW9uIGNyZWF0ZUh5ZHJhdGlvblJlbmRlcmVyKG9wdGlvbnMpIHsNCiAgcmV0dXJuIGJhc2VDcmVhdGVSZW5kZXJlcihvcHRpb25zLCBjcmVhdGVIeWRyYXRpb25GdW5jdGlvbnMpOw0KfQ0KZnVuY3Rpb24gYmFzZUNyZWF0ZVJlbmRlcmVyKG9wdGlvbnMsIGNyZWF0ZUh5ZHJhdGlvbkZucykgew0KICBjb25zdCB0YXJnZXQgPSBnZXRHbG9iYWxUaGlzKCk7DQogIHRhcmdldC5fX1ZVRV9fID0gdHJ1ZTsNCiAgew0KICAgIHNldERldnRvb2xzSG9vayQxKHRhcmdldC5fX1ZVRV9ERVZUT09MU19HTE9CQUxfSE9PS19fLCB0YXJnZXQpOw0KICB9DQogIGNvbnN0IHsNCiAgICBpbnNlcnQ6IGhvc3RJbnNlcnQsDQogICAgcmVtb3ZlOiBob3N0UmVtb3ZlLA0KICAgIHBhdGNoUHJvcDogaG9zdFBhdGNoUHJvcCwNCiAgICBjcmVhdGVFbGVtZW50OiBob3N0Q3JlYXRlRWxlbWVudCwNCiAgICBjcmVhdGVUZXh0OiBob3N0Q3JlYXRlVGV4dCwNCiAgICBjcmVhdGVDb21tZW50OiBob3N0Q3JlYXRlQ29tbWVudCwNCiAgICBzZXRUZXh0OiBob3N0U2V0VGV4dCwNCiAgICBzZXRFbGVtZW50VGV4dDogaG9zdFNldEVsZW1lbnRUZXh0LA0KICAgIHBhcmVudE5vZGU6IGhvc3RQYXJlbnROb2RlLA0KICAgIG5leHRTaWJsaW5nOiBob3N0TmV4dFNpYmxpbmcsDQogICAgc2V0U2NvcGVJZDogaG9zdFNldFNjb3BlSWQgPSBOT09QLA0KICAgIGluc2VydFN0YXRpY0NvbnRlbnQ6IGhvc3RJbnNlcnRTdGF0aWNDb250ZW50DQogIH0gPSBvcHRpb25zOw0KICBjb25zdCBwYXRjaCA9IChuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yID0gbnVsbCwgcGFyZW50Q29tcG9uZW50ID0gbnVsbCwgcGFyZW50U3VzcGVuc2UgPSBudWxsLCBuYW1lc3BhY2UgPSB2b2lkIDAsIHNsb3RTY29wZUlkcyA9IG51bGwsIG9wdGltaXplZCA9IGlzSG1yVXBkYXRpbmcgPyBmYWxzZSA6ICEhbjIuZHluYW1pY0NoaWxkcmVuKSA9PiB7DQogICAgaWYgKG4xID09PSBuMikgew0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBpZiAobjEgJiYgIWlzU2FtZVZOb2RlVHlwZShuMSwgbjIpKSB7DQogICAgICBhbmNob3IgPSBnZXROZXh0SG9zdE5vZGUobjEpOw0KICAgICAgdW5tb3VudChuMSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgdHJ1ZSk7DQogICAgICBuMSA9IG51bGw7DQogICAgfQ0KICAgIGlmIChuMi5wYXRjaEZsYWcgPT09IC0yKSB7DQogICAgICBvcHRpbWl6ZWQgPSBmYWxzZTsNCiAgICAgIG4yLmR5bmFtaWNDaGlsZHJlbiA9IG51bGw7DQogICAgfQ0KICAgIGNvbnN0IHsgdHlwZSwgcmVmLCBzaGFwZUZsYWcgfSA9IG4yOw0KICAgIHN3aXRjaCAodHlwZSkgew0KICAgICAgY2FzZSBUZXh0Og0KICAgICAgICBwcm9jZXNzVGV4dChuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yKTsNCiAgICAgICAgYnJlYWs7DQogICAgICBjYXNlIENvbW1lbnQ6DQogICAgICAgIHByb2Nlc3NDb21tZW50Tm9kZShuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yKTsNCiAgICAgICAgYnJlYWs7DQogICAgICBjYXNlIFN0YXRpYzoNCiAgICAgICAgaWYgKG4xID09IG51bGwpIHsNCiAgICAgICAgICBtb3VudFN0YXRpY05vZGUobjIsIGNvbnRhaW5lciwgYW5jaG9yLCBuYW1lc3BhY2UpOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIHBhdGNoU3RhdGljTm9kZShuMSwgbjIsIGNvbnRhaW5lciwgbmFtZXNwYWNlKTsNCiAgICAgICAgfQ0KICAgICAgICBicmVhazsNCiAgICAgIGNhc2UgRnJhZ21lbnQ6DQogICAgICAgIHByb2Nlc3NGcmFnbWVudCgNCiAgICAgICAgICBuMSwNCiAgICAgICAgICBuMiwNCiAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICApOw0KICAgICAgICBicmVhazsNCiAgICAgIGRlZmF1bHQ6DQogICAgICAgIGlmIChzaGFwZUZsYWcgJiAxKSB7DQogICAgICAgICAgcHJvY2Vzc0VsZW1lbnQoDQogICAgICAgICAgICBuMSwNCiAgICAgICAgICAgIG4yLA0KICAgICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgICApOw0KICAgICAgICB9IGVsc2UgaWYgKHNoYXBlRmxhZyAmIDYpIHsNCiAgICAgICAgICBwcm9jZXNzQ29tcG9uZW50KA0KICAgICAgICAgICAgbjEsDQogICAgICAgICAgICBuMiwNCiAgICAgICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgICAgIGFuY2hvciwNCiAgICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICAgKTsNCiAgICAgICAgfSBlbHNlIGlmIChzaGFwZUZsYWcgJiA2NCkgew0KICAgICAgICAgIHR5cGUucHJvY2VzcygNCiAgICAgICAgICAgIG4xLA0KICAgICAgICAgICAgbjIsDQogICAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgICBhbmNob3IsDQogICAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICAgIG9wdGltaXplZCwNCiAgICAgICAgICAgIGludGVybmFscw0KICAgICAgICAgICk7DQogICAgICAgIH0gZWxzZSBpZiAoc2hhcGVGbGFnICYgMTI4KSB7DQogICAgICAgICAgdHlwZS5wcm9jZXNzKA0KICAgICAgICAgICAgbjEsDQogICAgICAgICAgICBuMiwNCiAgICAgICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgICAgIGFuY2hvciwNCiAgICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgICAgb3B0aW1pemVkLA0KICAgICAgICAgICAgaW50ZXJuYWxzDQogICAgICAgICAgKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICB3YXJuJDEoIkludmFsaWQgVk5vZGUgdHlwZToiLCB0eXBlLCBgKCR7dHlwZW9mIHR5cGV9KWApOw0KICAgICAgICB9DQogICAgfQ0KICAgIGlmIChyZWYgIT0gbnVsbCAmJiBwYXJlbnRDb21wb25lbnQpIHsNCiAgICAgIHNldFJlZihyZWYsIG4xICYmIG4xLnJlZiwgcGFyZW50U3VzcGVuc2UsIG4yIHx8IG4xLCAhbjIpOw0KICAgIH0gZWxzZSBpZiAocmVmID09IG51bGwgJiYgbjEgJiYgbjEucmVmICE9IG51bGwpIHsNCiAgICAgIHNldFJlZihuMS5yZWYsIG51bGwsIHBhcmVudFN1c3BlbnNlLCBuMSwgdHJ1ZSk7DQogICAgfQ0KICB9Ow0KICBjb25zdCBwcm9jZXNzVGV4dCA9IChuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yKSA9PiB7DQogICAgaWYgKG4xID09IG51bGwpIHsNCiAgICAgIGhvc3RJbnNlcnQoDQogICAgICAgIG4yLmVsID0gaG9zdENyZWF0ZVRleHQobjIuY2hpbGRyZW4pLA0KICAgICAgICBjb250YWluZXIsDQogICAgICAgIGFuY2hvcg0KICAgICAgKTsNCiAgICB9IGVsc2Ugew0KICAgICAgY29uc3QgZWwgPSBuMi5lbCA9IG4xLmVsOw0KICAgICAgaWYgKG4yLmNoaWxkcmVuICE9PSBuMS5jaGlsZHJlbikgew0KICAgICAgICBob3N0U2V0VGV4dChlbCwgbjIuY2hpbGRyZW4pOw0KICAgICAgfQ0KICAgIH0NCiAgfTsNCiAgY29uc3QgcHJvY2Vzc0NvbW1lbnROb2RlID0gKG4xLCBuMiwgY29udGFpbmVyLCBhbmNob3IpID0+IHsNCiAgICBpZiAobjEgPT0gbnVsbCkgew0KICAgICAgaG9zdEluc2VydCgNCiAgICAgICAgbjIuZWwgPSBob3N0Q3JlYXRlQ29tbWVudChuMi5jaGlsZHJlbiB8fCAiIiksDQogICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgYW5jaG9yDQogICAgICApOw0KICAgIH0gZWxzZSB7DQogICAgICBuMi5lbCA9IG4xLmVsOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgbW91bnRTdGF0aWNOb2RlID0gKG4yLCBjb250YWluZXIsIGFuY2hvciwgbmFtZXNwYWNlKSA9PiB7DQogICAgW24yLmVsLCBuMi5hbmNob3JdID0gaG9zdEluc2VydFN0YXRpY0NvbnRlbnQoDQogICAgICBuMi5jaGlsZHJlbiwNCiAgICAgIGNvbnRhaW5lciwNCiAgICAgIGFuY2hvciwNCiAgICAgIG5hbWVzcGFjZSwNCiAgICAgIG4yLmVsLA0KICAgICAgbjIuYW5jaG9yDQogICAgKTsNCiAgfTsNCiAgY29uc3QgcGF0Y2hTdGF0aWNOb2RlID0gKG4xLCBuMiwgY29udGFpbmVyLCBuYW1lc3BhY2UpID0+IHsNCiAgICBpZiAobjIuY2hpbGRyZW4gIT09IG4xLmNoaWxkcmVuKSB7DQogICAgICBjb25zdCBhbmNob3IgPSBob3N0TmV4dFNpYmxpbmcobjEuYW5jaG9yKTsNCiAgICAgIHJlbW92ZVN0YXRpY05vZGUobjEpOw0KICAgICAgW24yLmVsLCBuMi5hbmNob3JdID0gaG9zdEluc2VydFN0YXRpY0NvbnRlbnQoDQogICAgICAgIG4yLmNoaWxkcmVuLA0KICAgICAgICBjb250YWluZXIsDQogICAgICAgIGFuY2hvciwNCiAgICAgICAgbmFtZXNwYWNlDQogICAgICApOw0KICAgIH0gZWxzZSB7DQogICAgICBuMi5lbCA9IG4xLmVsOw0KICAgICAgbjIuYW5jaG9yID0gbjEuYW5jaG9yOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgbW92ZVN0YXRpY05vZGUgPSAoeyBlbCwgYW5jaG9yIH0sIGNvbnRhaW5lciwgbmV4dFNpYmxpbmcpID0+IHsNCiAgICBsZXQgbmV4dDsNCiAgICB3aGlsZSAoZWwgJiYgZWwgIT09IGFuY2hvcikgew0KICAgICAgbmV4dCA9IGhvc3ROZXh0U2libGluZyhlbCk7DQogICAgICBob3N0SW5zZXJ0KGVsLCBjb250YWluZXIsIG5leHRTaWJsaW5nKTsNCiAgICAgIGVsID0gbmV4dDsNCiAgICB9DQogICAgaG9zdEluc2VydChhbmNob3IsIGNvbnRhaW5lciwgbmV4dFNpYmxpbmcpOw0KICB9Ow0KICBjb25zdCByZW1vdmVTdGF0aWNOb2RlID0gKHsgZWwsIGFuY2hvciB9KSA9PiB7DQogICAgbGV0IG5leHQ7DQogICAgd2hpbGUgKGVsICYmIGVsICE9PSBhbmNob3IpIHsNCiAgICAgIG5leHQgPSBob3N0TmV4dFNpYmxpbmcoZWwpOw0KICAgICAgaG9zdFJlbW92ZShlbCk7DQogICAgICBlbCA9IG5leHQ7DQogICAgfQ0KICAgIGhvc3RSZW1vdmUoYW5jaG9yKTsNCiAgfTsNCiAgY29uc3QgcHJvY2Vzc0VsZW1lbnQgPSAobjEsIG4yLCBjb250YWluZXIsIGFuY2hvciwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgbmFtZXNwYWNlLCBzbG90U2NvcGVJZHMsIG9wdGltaXplZCkgPT4gew0KICAgIGlmIChuMi50eXBlID09PSAic3ZnIikgew0KICAgICAgbmFtZXNwYWNlID0gInN2ZyI7DQogICAgfSBlbHNlIGlmIChuMi50eXBlID09PSAibWF0aCIpIHsNCiAgICAgIG5hbWVzcGFjZSA9ICJtYXRobWwiOw0KICAgIH0NCiAgICBpZiAobjEgPT0gbnVsbCkgew0KICAgICAgbW91bnRFbGVtZW50KA0KICAgICAgICBuMiwNCiAgICAgICAgY29udGFpbmVyLA0KICAgICAgICBhbmNob3IsDQogICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICk7DQogICAgfSBlbHNlIHsNCiAgICAgIHBhdGNoRWxlbWVudCgNCiAgICAgICAgbjEsDQogICAgICAgIG4yLA0KICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgb3B0aW1pemVkDQogICAgICApOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgbW91bnRFbGVtZW50ID0gKHZub2RlLCBjb250YWluZXIsIGFuY2hvciwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgbmFtZXNwYWNlLCBzbG90U2NvcGVJZHMsIG9wdGltaXplZCkgPT4gew0KICAgIGxldCBlbDsNCiAgICBsZXQgdm5vZGVIb29rOw0KICAgIGNvbnN0IHsgcHJvcHMsIHNoYXBlRmxhZywgdHJhbnNpdGlvbiwgZGlycyB9ID0gdm5vZGU7DQogICAgZWwgPSB2bm9kZS5lbCA9IGhvc3RDcmVhdGVFbGVtZW50KA0KICAgICAgdm5vZGUudHlwZSwNCiAgICAgIG5hbWVzcGFjZSwNCiAgICAgIHByb3BzICYmIHByb3BzLmlzLA0KICAgICAgcHJvcHMNCiAgICApOw0KICAgIGlmIChzaGFwZUZsYWcgJiA4KSB7DQogICAgICBob3N0U2V0RWxlbWVudFRleHQoZWwsIHZub2RlLmNoaWxkcmVuKTsNCiAgICB9IGVsc2UgaWYgKHNoYXBlRmxhZyAmIDE2KSB7DQogICAgICBtb3VudENoaWxkcmVuKA0KICAgICAgICB2bm9kZS5jaGlsZHJlbiwNCiAgICAgICAgZWwsDQogICAgICAgIG51bGwsDQogICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgIHJlc29sdmVDaGlsZHJlbk5hbWVzcGFjZSh2bm9kZSwgbmFtZXNwYWNlKSwNCiAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICk7DQogICAgfQ0KICAgIGlmIChkaXJzKSB7DQogICAgICBpbnZva2VEaXJlY3RpdmVIb29rKHZub2RlLCBudWxsLCBwYXJlbnRDb21wb25lbnQsICJjcmVhdGVkIik7DQogICAgfQ0KICAgIHNldFNjb3BlSWQoZWwsIHZub2RlLCB2bm9kZS5zY29wZUlkLCBzbG90U2NvcGVJZHMsIHBhcmVudENvbXBvbmVudCk7DQogICAgaWYgKHByb3BzKSB7DQogICAgICBmb3IgKGNvbnN0IGtleSBpbiBwcm9wcykgew0KICAgICAgICBpZiAoa2V5ICE9PSAidmFsdWUiICYmICFpc1Jlc2VydmVkUHJvcChrZXkpKSB7DQogICAgICAgICAgaG9zdFBhdGNoUHJvcChlbCwga2V5LCBudWxsLCBwcm9wc1trZXldLCBuYW1lc3BhY2UsIHBhcmVudENvbXBvbmVudCk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGlmICgidmFsdWUiIGluIHByb3BzKSB7DQogICAgICAgIGhvc3RQYXRjaFByb3AoZWwsICJ2YWx1ZSIsIG51bGwsIHByb3BzLnZhbHVlLCBuYW1lc3BhY2UpOw0KICAgICAgfQ0KICAgICAgaWYgKHZub2RlSG9vayA9IHByb3BzLm9uVm5vZGVCZWZvcmVNb3VudCkgew0KICAgICAgICBpbnZva2VWTm9kZUhvb2sodm5vZGVIb29rLCBwYXJlbnRDb21wb25lbnQsIHZub2RlKTsNCiAgICAgIH0NCiAgICB9DQogICAgew0KICAgICAgZGVmKGVsLCAiX192bm9kZSIsIHZub2RlLCB0cnVlKTsNCiAgICAgIGRlZihlbCwgIl9fdnVlUGFyZW50Q29tcG9uZW50IiwgcGFyZW50Q29tcG9uZW50LCB0cnVlKTsNCiAgICB9DQogICAgaWYgKGRpcnMpIHsNCiAgICAgIGludm9rZURpcmVjdGl2ZUhvb2sodm5vZGUsIG51bGwsIHBhcmVudENvbXBvbmVudCwgImJlZm9yZU1vdW50Iik7DQogICAgfQ0KICAgIGNvbnN0IG5lZWRDYWxsVHJhbnNpdGlvbkhvb2tzID0gbmVlZFRyYW5zaXRpb24ocGFyZW50U3VzcGVuc2UsIHRyYW5zaXRpb24pOw0KICAgIGlmIChuZWVkQ2FsbFRyYW5zaXRpb25Ib29rcykgew0KICAgICAgdHJhbnNpdGlvbi5iZWZvcmVFbnRlcihlbCk7DQogICAgfQ0KICAgIGhvc3RJbnNlcnQoZWwsIGNvbnRhaW5lciwgYW5jaG9yKTsNCiAgICBpZiAoKHZub2RlSG9vayA9IHByb3BzICYmIHByb3BzLm9uVm5vZGVNb3VudGVkKSB8fCBuZWVkQ2FsbFRyYW5zaXRpb25Ib29rcyB8fCBkaXJzKSB7DQogICAgICBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QoKCkgPT4gew0KICAgICAgICB2bm9kZUhvb2sgJiYgaW52b2tlVk5vZGVIb29rKHZub2RlSG9vaywgcGFyZW50Q29tcG9uZW50LCB2bm9kZSk7DQogICAgICAgIG5lZWRDYWxsVHJhbnNpdGlvbkhvb2tzICYmIHRyYW5zaXRpb24uZW50ZXIoZWwpOw0KICAgICAgICBkaXJzICYmIGludm9rZURpcmVjdGl2ZUhvb2sodm5vZGUsIG51bGwsIHBhcmVudENvbXBvbmVudCwgIm1vdW50ZWQiKTsNCiAgICAgIH0sIHBhcmVudFN1c3BlbnNlKTsNCiAgICB9DQogIH07DQogIGNvbnN0IHNldFNjb3BlSWQgPSAoZWwsIHZub2RlLCBzY29wZUlkLCBzbG90U2NvcGVJZHMsIHBhcmVudENvbXBvbmVudCkgPT4gew0KICAgIGlmIChzY29wZUlkKSB7DQogICAgICBob3N0U2V0U2NvcGVJZChlbCwgc2NvcGVJZCk7DQogICAgfQ0KICAgIGlmIChzbG90U2NvcGVJZHMpIHsNCiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2xvdFNjb3BlSWRzLmxlbmd0aDsgaSsrKSB7DQogICAgICAgIGhvc3RTZXRTY29wZUlkKGVsLCBzbG90U2NvcGVJZHNbaV0pOw0KICAgICAgfQ0KICAgIH0NCiAgICBpZiAocGFyZW50Q29tcG9uZW50KSB7DQogICAgICBsZXQgc3ViVHJlZSA9IHBhcmVudENvbXBvbmVudC5zdWJUcmVlOw0KICAgICAgaWYgKHN1YlRyZWUucGF0Y2hGbGFnID4gMCAmJiBzdWJUcmVlLnBhdGNoRmxhZyAmIDIwNDgpIHsNCiAgICAgICAgc3ViVHJlZSA9IGZpbHRlclNpbmdsZVJvb3Qoc3ViVHJlZS5jaGlsZHJlbikgfHwgc3ViVHJlZTsNCiAgICAgIH0NCiAgICAgIGlmICh2bm9kZSA9PT0gc3ViVHJlZSB8fCBpc1N1c3BlbnNlKHN1YlRyZWUudHlwZSkgJiYgKHN1YlRyZWUuc3NDb250ZW50ID09PSB2bm9kZSB8fCBzdWJUcmVlLnNzRmFsbGJhY2sgPT09IHZub2RlKSkgew0KICAgICAgICBjb25zdCBwYXJlbnRWTm9kZSA9IHBhcmVudENvbXBvbmVudC52bm9kZTsNCiAgICAgICAgc2V0U2NvcGVJZCgNCiAgICAgICAgICBlbCwNCiAgICAgICAgICBwYXJlbnRWTm9kZSwNCiAgICAgICAgICBwYXJlbnRWTm9kZS5zY29wZUlkLA0KICAgICAgICAgIHBhcmVudFZOb2RlLnNsb3RTY29wZUlkcywNCiAgICAgICAgICBwYXJlbnRDb21wb25lbnQucGFyZW50DQogICAgICAgICk7DQogICAgICB9DQogICAgfQ0KICB9Ow0KICBjb25zdCBtb3VudENoaWxkcmVuID0gKGNoaWxkcmVuLCBjb250YWluZXIsIGFuY2hvciwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgbmFtZXNwYWNlLCBzbG90U2NvcGVJZHMsIG9wdGltaXplZCwgc3RhcnQgPSAwKSA9PiB7DQogICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHsNCiAgICAgIGNvbnN0IGNoaWxkID0gY2hpbGRyZW5baV0gPSBvcHRpbWl6ZWQgPyBjbG9uZUlmTW91bnRlZChjaGlsZHJlbltpXSkgOiBub3JtYWxpemVWTm9kZShjaGlsZHJlbltpXSk7DQogICAgICBwYXRjaCgNCiAgICAgICAgbnVsbCwNCiAgICAgICAgY2hpbGQsDQogICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgYW5jaG9yLA0KICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgb3B0aW1pemVkDQogICAgICApOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgcGF0Y2hFbGVtZW50ID0gKG4xLCBuMiwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgbmFtZXNwYWNlLCBzbG90U2NvcGVJZHMsIG9wdGltaXplZCkgPT4gew0KICAgIGNvbnN0IGVsID0gbjIuZWwgPSBuMS5lbDsNCiAgICB7DQogICAgICBlbC5fX3Zub2RlID0gbjI7DQogICAgfQ0KICAgIGxldCB7IHBhdGNoRmxhZywgZHluYW1pY0NoaWxkcmVuLCBkaXJzIH0gPSBuMjsNCiAgICBwYXRjaEZsYWcgfD0gbjEucGF0Y2hGbGFnICYgMTY7DQogICAgY29uc3Qgb2xkUHJvcHMgPSBuMS5wcm9wcyB8fCBFTVBUWV9PQko7DQogICAgY29uc3QgbmV3UHJvcHMgPSBuMi5wcm9wcyB8fCBFTVBUWV9PQko7DQogICAgbGV0IHZub2RlSG9vazsNCiAgICBwYXJlbnRDb21wb25lbnQgJiYgdG9nZ2xlUmVjdXJzZShwYXJlbnRDb21wb25lbnQsIGZhbHNlKTsNCiAgICBpZiAodm5vZGVIb29rID0gbmV3UHJvcHMub25Wbm9kZUJlZm9yZVVwZGF0ZSkgew0KICAgICAgaW52b2tlVk5vZGVIb29rKHZub2RlSG9vaywgcGFyZW50Q29tcG9uZW50LCBuMiwgbjEpOw0KICAgIH0NCiAgICBpZiAoZGlycykgew0KICAgICAgaW52b2tlRGlyZWN0aXZlSG9vayhuMiwgbjEsIHBhcmVudENvbXBvbmVudCwgImJlZm9yZVVwZGF0ZSIpOw0KICAgIH0NCiAgICBwYXJlbnRDb21wb25lbnQgJiYgdG9nZ2xlUmVjdXJzZShwYXJlbnRDb21wb25lbnQsIHRydWUpOw0KICAgIGlmIChpc0htclVwZGF0aW5nKSB7DQogICAgICBwYXRjaEZsYWcgPSAwOw0KICAgICAgb3B0aW1pemVkID0gZmFsc2U7DQogICAgICBkeW5hbWljQ2hpbGRyZW4gPSBudWxsOw0KICAgIH0NCiAgICBpZiAob2xkUHJvcHMuaW5uZXJIVE1MICYmIG5ld1Byb3BzLmlubmVySFRNTCA9PSBudWxsIHx8IG9sZFByb3BzLnRleHRDb250ZW50ICYmIG5ld1Byb3BzLnRleHRDb250ZW50ID09IG51bGwpIHsNCiAgICAgIGhvc3RTZXRFbGVtZW50VGV4dChlbCwgIiIpOw0KICAgIH0NCiAgICBpZiAoZHluYW1pY0NoaWxkcmVuKSB7DQogICAgICBwYXRjaEJsb2NrQ2hpbGRyZW4oDQogICAgICAgIG4xLmR5bmFtaWNDaGlsZHJlbiwNCiAgICAgICAgZHluYW1pY0NoaWxkcmVuLA0KICAgICAgICBlbCwNCiAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgcmVzb2x2ZUNoaWxkcmVuTmFtZXNwYWNlKG4yLCBuYW1lc3BhY2UpLA0KICAgICAgICBzbG90U2NvcGVJZHMNCiAgICAgICk7DQogICAgICB7DQogICAgICAgIHRyYXZlcnNlU3RhdGljQ2hpbGRyZW4objEsIG4yKTsNCiAgICAgIH0NCiAgICB9IGVsc2UgaWYgKCFvcHRpbWl6ZWQpIHsNCiAgICAgIHBhdGNoQ2hpbGRyZW4oDQogICAgICAgIG4xLA0KICAgICAgICBuMiwNCiAgICAgICAgZWwsDQogICAgICAgIG51bGwsDQogICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgIHJlc29sdmVDaGlsZHJlbk5hbWVzcGFjZShuMiwgbmFtZXNwYWNlKSwNCiAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICBmYWxzZQ0KICAgICAgKTsNCiAgICB9DQogICAgaWYgKHBhdGNoRmxhZyA+IDApIHsNCiAgICAgIGlmIChwYXRjaEZsYWcgJiAxNikgew0KICAgICAgICBwYXRjaFByb3BzKGVsLCBvbGRQcm9wcywgbmV3UHJvcHMsIHBhcmVudENvbXBvbmVudCwgbmFtZXNwYWNlKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGlmIChwYXRjaEZsYWcgJiAyKSB7DQogICAgICAgICAgaWYgKG9sZFByb3BzLmNsYXNzICE9PSBuZXdQcm9wcy5jbGFzcykgew0KICAgICAgICAgICAgaG9zdFBhdGNoUHJvcChlbCwgImNsYXNzIiwgbnVsbCwgbmV3UHJvcHMuY2xhc3MsIG5hbWVzcGFjZSk7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGlmIChwYXRjaEZsYWcgJiA0KSB7DQogICAgICAgICAgaG9zdFBhdGNoUHJvcChlbCwgInN0eWxlIiwgb2xkUHJvcHMuc3R5bGUsIG5ld1Byb3BzLnN0eWxlLCBuYW1lc3BhY2UpOw0KICAgICAgICB9DQogICAgICAgIGlmIChwYXRjaEZsYWcgJiA4KSB7DQogICAgICAgICAgY29uc3QgcHJvcHNUb1VwZGF0ZSA9IG4yLmR5bmFtaWNQcm9wczsNCiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByb3BzVG9VcGRhdGUubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgICAgIGNvbnN0IGtleSA9IHByb3BzVG9VcGRhdGVbaV07DQogICAgICAgICAgICBjb25zdCBwcmV2ID0gb2xkUHJvcHNba2V5XTsNCiAgICAgICAgICAgIGNvbnN0IG5leHQgPSBuZXdQcm9wc1trZXldOw0KICAgICAgICAgICAgaWYgKG5leHQgIT09IHByZXYgfHwga2V5ID09PSAidmFsdWUiKSB7DQogICAgICAgICAgICAgIGhvc3RQYXRjaFByb3AoZWwsIGtleSwgcHJldiwgbmV4dCwgbmFtZXNwYWNlLCBwYXJlbnRDb21wb25lbnQpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgaWYgKHBhdGNoRmxhZyAmIDEpIHsNCiAgICAgICAgaWYgKG4xLmNoaWxkcmVuICE9PSBuMi5jaGlsZHJlbikgew0KICAgICAgICAgIGhvc3RTZXRFbGVtZW50VGV4dChlbCwgbjIuY2hpbGRyZW4pOw0KICAgICAgICB9DQogICAgICB9DQogICAgfSBlbHNlIGlmICghb3B0aW1pemVkICYmIGR5bmFtaWNDaGlsZHJlbiA9PSBudWxsKSB7DQogICAgICBwYXRjaFByb3BzKGVsLCBvbGRQcm9wcywgbmV3UHJvcHMsIHBhcmVudENvbXBvbmVudCwgbmFtZXNwYWNlKTsNCiAgICB9DQogICAgaWYgKCh2bm9kZUhvb2sgPSBuZXdQcm9wcy5vblZub2RlVXBkYXRlZCkgfHwgZGlycykgew0KICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KCgpID0+IHsNCiAgICAgICAgdm5vZGVIb29rICYmIGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIHBhcmVudENvbXBvbmVudCwgbjIsIG4xKTsNCiAgICAgICAgZGlycyAmJiBpbnZva2VEaXJlY3RpdmVIb29rKG4yLCBuMSwgcGFyZW50Q29tcG9uZW50LCAidXBkYXRlZCIpOw0KICAgICAgfSwgcGFyZW50U3VzcGVuc2UpOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgcGF0Y2hCbG9ja0NoaWxkcmVuID0gKG9sZENoaWxkcmVuLCBuZXdDaGlsZHJlbiwgZmFsbGJhY2tDb250YWluZXIsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzKSA9PiB7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuZXdDaGlsZHJlbi5sZW5ndGg7IGkrKykgew0KICAgICAgY29uc3Qgb2xkVk5vZGUgPSBvbGRDaGlsZHJlbltpXTsNCiAgICAgIGNvbnN0IG5ld1ZOb2RlID0gbmV3Q2hpbGRyZW5baV07DQogICAgICBjb25zdCBjb250YWluZXIgPSAoDQogICAgICAgIC8vIG9sZFZOb2RlIG1heSBiZSBhbiBlcnJvcmVkIGFzeW5jIHNldHVwKCkgY29tcG9uZW50IGluc2lkZSBTdXNwZW5zZQ0KICAgICAgICAvLyB3aGljaCB3aWxsIG5vdCBoYXZlIGEgbW91bnRlZCBlbGVtZW50DQogICAgICAgIG9sZFZOb2RlLmVsICYmIC8vIC0gSW4gdGhlIGNhc2Ugb2YgYSBGcmFnbWVudCwgd2UgbmVlZCB0byBwcm92aWRlIHRoZSBhY3R1YWwgcGFyZW50DQogICAgICAgIC8vIG9mIHRoZSBGcmFnbWVudCBpdHNlbGYgc28gaXQgY2FuIG1vdmUgaXRzIGNoaWxkcmVuLg0KICAgICAgICAob2xkVk5vZGUudHlwZSA9PT0gRnJhZ21lbnQgfHwgLy8gLSBJbiB0aGUgY2FzZSBvZiBkaWZmZXJlbnQgbm9kZXMsIHRoZXJlIGlzIGdvaW5nIHRvIGJlIGEgcmVwbGFjZW1lbnQNCiAgICAgICAgLy8gd2hpY2ggYWxzbyByZXF1aXJlcyB0aGUgY29ycmVjdCBwYXJlbnQgY29udGFpbmVyDQogICAgICAgICFpc1NhbWVWTm9kZVR5cGUob2xkVk5vZGUsIG5ld1ZOb2RlKSB8fCAvLyAtIEluIHRoZSBjYXNlIG9mIGEgY29tcG9uZW50LCBpdCBjb3VsZCBjb250YWluIGFueXRoaW5nLg0KICAgICAgICBvbGRWTm9kZS5zaGFwZUZsYWcgJiAoNiB8IDY0IHwgMTI4KSkgPyBob3N0UGFyZW50Tm9kZShvbGRWTm9kZS5lbCkgOiAoDQogICAgICAgICAgLy8gSW4gb3RoZXIgY2FzZXMsIHRoZSBwYXJlbnQgY29udGFpbmVyIGlzIG5vdCBhY3R1YWxseSB1c2VkIHNvIHdlDQogICAgICAgICAgLy8ganVzdCBwYXNzIHRoZSBibG9jayBlbGVtZW50IGhlcmUgdG8gYXZvaWQgYSBET00gcGFyZW50Tm9kZSBjYWxsLg0KICAgICAgICAgIGZhbGxiYWNrQ29udGFpbmVyDQogICAgICAgICkNCiAgICAgICk7DQogICAgICBwYXRjaCgNCiAgICAgICAgb2xkVk5vZGUsDQogICAgICAgIG5ld1ZOb2RlLA0KICAgICAgICBjb250YWluZXIsDQogICAgICAgIG51bGwsDQogICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICB0cnVlDQogICAgICApOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgcGF0Y2hQcm9wcyA9IChlbCwgb2xkUHJvcHMsIG5ld1Byb3BzLCBwYXJlbnRDb21wb25lbnQsIG5hbWVzcGFjZSkgPT4gew0KICAgIGlmIChvbGRQcm9wcyAhPT0gbmV3UHJvcHMpIHsNCiAgICAgIGlmIChvbGRQcm9wcyAhPT0gRU1QVFlfT0JKKSB7DQogICAgICAgIGZvciAoY29uc3Qga2V5IGluIG9sZFByb3BzKSB7DQogICAgICAgICAgaWYgKCFpc1Jlc2VydmVkUHJvcChrZXkpICYmICEoa2V5IGluIG5ld1Byb3BzKSkgew0KICAgICAgICAgICAgaG9zdFBhdGNoUHJvcCgNCiAgICAgICAgICAgICAgZWwsDQogICAgICAgICAgICAgIGtleSwNCiAgICAgICAgICAgICAgb2xkUHJvcHNba2V5XSwNCiAgICAgICAgICAgICAgbnVsbCwNCiAgICAgICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgICAgICBwYXJlbnRDb21wb25lbnQNCiAgICAgICAgICAgICk7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICB9DQogICAgICBmb3IgKGNvbnN0IGtleSBpbiBuZXdQcm9wcykgew0KICAgICAgICBpZiAoaXNSZXNlcnZlZFByb3Aoa2V5KSkgY29udGludWU7DQogICAgICAgIGNvbnN0IG5leHQgPSBuZXdQcm9wc1trZXldOw0KICAgICAgICBjb25zdCBwcmV2ID0gb2xkUHJvcHNba2V5XTsNCiAgICAgICAgaWYgKG5leHQgIT09IHByZXYgJiYga2V5ICE9PSAidmFsdWUiKSB7DQogICAgICAgICAgaG9zdFBhdGNoUHJvcChlbCwga2V5LCBwcmV2LCBuZXh0LCBuYW1lc3BhY2UsIHBhcmVudENvbXBvbmVudCk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGlmICgidmFsdWUiIGluIG5ld1Byb3BzKSB7DQogICAgICAgIGhvc3RQYXRjaFByb3AoZWwsICJ2YWx1ZSIsIG9sZFByb3BzLnZhbHVlLCBuZXdQcm9wcy52YWx1ZSwgbmFtZXNwYWNlKTsNCiAgICAgIH0NCiAgICB9DQogIH07DQogIGNvbnN0IHByb2Nlc3NGcmFnbWVudCA9IChuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBuYW1lc3BhY2UsIHNsb3RTY29wZUlkcywgb3B0aW1pemVkKSA9PiB7DQogICAgY29uc3QgZnJhZ21lbnRTdGFydEFuY2hvciA9IG4yLmVsID0gbjEgPyBuMS5lbCA6IGhvc3RDcmVhdGVUZXh0KCIiKTsNCiAgICBjb25zdCBmcmFnbWVudEVuZEFuY2hvciA9IG4yLmFuY2hvciA9IG4xID8gbjEuYW5jaG9yIDogaG9zdENyZWF0ZVRleHQoIiIpOw0KICAgIGxldCB7IHBhdGNoRmxhZywgZHluYW1pY0NoaWxkcmVuLCBzbG90U2NvcGVJZHM6IGZyYWdtZW50U2xvdFNjb3BlSWRzIH0gPSBuMjsNCiAgICBpZiAoDQogICAgICAvLyAjNTUyMyBkZXYgcm9vdCBmcmFnbWVudCBtYXkgaW5oZXJpdCBkaXJlY3RpdmVzDQogICAgICBpc0htclVwZGF0aW5nIHx8IHBhdGNoRmxhZyAmIDIwNDgNCiAgICApIHsNCiAgICAgIHBhdGNoRmxhZyA9IDA7DQogICAgICBvcHRpbWl6ZWQgPSBmYWxzZTsNCiAgICAgIGR5bmFtaWNDaGlsZHJlbiA9IG51bGw7DQogICAgfQ0KICAgIGlmIChmcmFnbWVudFNsb3RTY29wZUlkcykgew0KICAgICAgc2xvdFNjb3BlSWRzID0gc2xvdFNjb3BlSWRzID8gc2xvdFNjb3BlSWRzLmNvbmNhdChmcmFnbWVudFNsb3RTY29wZUlkcykgOiBmcmFnbWVudFNsb3RTY29wZUlkczsNCiAgICB9DQogICAgaWYgKG4xID09IG51bGwpIHsNCiAgICAgIGhvc3RJbnNlcnQoZnJhZ21lbnRTdGFydEFuY2hvciwgY29udGFpbmVyLCBhbmNob3IpOw0KICAgICAgaG9zdEluc2VydChmcmFnbWVudEVuZEFuY2hvciwgY29udGFpbmVyLCBhbmNob3IpOw0KICAgICAgbW91bnRDaGlsZHJlbigNCiAgICAgICAgLy8gIzEwMDA3DQogICAgICAgIC8vIHN1Y2ggZnJhZ21lbnQgbGlrZSBgPD48Lz5gIHdpbGwgYmUgY29tcGlsZWQgaW50bw0KICAgICAgICAvLyBhIGZyYWdtZW50IHdoaWNoIGRvZXNuJ3QgaGF2ZSBhIGNoaWxkcmVuLg0KICAgICAgICAvLyBJbiB0aGlzIGNhc2UgZmFsbGJhY2sgdG8gYW4gZW1wdHkgYXJyYXkNCiAgICAgICAgbjIuY2hpbGRyZW4gfHwgW10sDQogICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgZnJhZ21lbnRFbmRBbmNob3IsDQogICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICk7DQogICAgfSBlbHNlIHsNCiAgICAgIGlmIChwYXRjaEZsYWcgPiAwICYmIHBhdGNoRmxhZyAmIDY0ICYmIGR5bmFtaWNDaGlsZHJlbiAmJiAvLyAjMjcxNSB0aGUgcHJldmlvdXMgZnJhZ21lbnQgY291bGQndmUgYmVlbiBhIEJBSUxlZCBvbmUgYXMgYSByZXN1bHQNCiAgICAgIC8vIG9mIHJlbmRlclNsb3QoKSB3aXRoIG5vIHZhbGlkIGNoaWxkcmVuDQogICAgICBuMS5keW5hbWljQ2hpbGRyZW4pIHsNCiAgICAgICAgcGF0Y2hCbG9ja0NoaWxkcmVuKA0KICAgICAgICAgIG4xLmR5bmFtaWNDaGlsZHJlbiwNCiAgICAgICAgICBkeW5hbWljQ2hpbGRyZW4sDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzDQogICAgICAgICk7DQogICAgICAgIHsNCiAgICAgICAgICB0cmF2ZXJzZVN0YXRpY0NoaWxkcmVuKG4xLCBuMik7DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHBhdGNoQ2hpbGRyZW4oDQogICAgICAgICAgbjEsDQogICAgICAgICAgbjIsDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIGZyYWdtZW50RW5kQW5jaG9yLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICApOw0KICAgICAgfQ0KICAgIH0NCiAgfTsNCiAgY29uc3QgcHJvY2Vzc0NvbXBvbmVudCA9IChuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBuYW1lc3BhY2UsIHNsb3RTY29wZUlkcywgb3B0aW1pemVkKSA9PiB7DQogICAgbjIuc2xvdFNjb3BlSWRzID0gc2xvdFNjb3BlSWRzOw0KICAgIGlmIChuMSA9PSBudWxsKSB7DQogICAgICBpZiAobjIuc2hhcGVGbGFnICYgNTEyKSB7DQogICAgICAgIHBhcmVudENvbXBvbmVudC5jdHguYWN0aXZhdGUoDQogICAgICAgICAgbjIsDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIGFuY2hvciwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBtb3VudENvbXBvbmVudCgNCiAgICAgICAgICBuMiwNCiAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICk7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIHVwZGF0ZUNvbXBvbmVudChuMSwgbjIsIG9wdGltaXplZCk7DQogICAgfQ0KICB9Ow0KICBjb25zdCBtb3VudENvbXBvbmVudCA9IChpbml0aWFsVk5vZGUsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBuYW1lc3BhY2UsIG9wdGltaXplZCkgPT4gew0KICAgIGNvbnN0IGluc3RhbmNlID0gKGluaXRpYWxWTm9kZS5jb21wb25lbnQgPSBjcmVhdGVDb21wb25lbnRJbnN0YW5jZSgNCiAgICAgIGluaXRpYWxWTm9kZSwNCiAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgIHBhcmVudFN1c3BlbnNlDQogICAgKSk7DQogICAgaWYgKGluc3RhbmNlLnR5cGUuX19obXJJZCkgew0KICAgICAgcmVnaXN0ZXJITVIoaW5zdGFuY2UpOw0KICAgIH0NCiAgICB7DQogICAgICBwdXNoV2FybmluZ0NvbnRleHQoaW5pdGlhbFZOb2RlKTsNCiAgICAgIHN0YXJ0TWVhc3VyZShpbnN0YW5jZSwgYG1vdW50YCk7DQogICAgfQ0KICAgIGlmIChpc0tlZXBBbGl2ZShpbml0aWFsVk5vZGUpKSB7DQogICAgICBpbnN0YW5jZS5jdHgucmVuZGVyZXIgPSBpbnRlcm5hbHM7DQogICAgfQ0KICAgIHsNCiAgICAgIHsNCiAgICAgICAgc3RhcnRNZWFzdXJlKGluc3RhbmNlLCBgaW5pdGApOw0KICAgICAgfQ0KICAgICAgc2V0dXBDb21wb25lbnQoaW5zdGFuY2UsIGZhbHNlLCBvcHRpbWl6ZWQpOw0KICAgICAgew0KICAgICAgICBlbmRNZWFzdXJlKGluc3RhbmNlLCBgaW5pdGApOw0KICAgICAgfQ0KICAgIH0NCiAgICBpZiAoaXNIbXJVcGRhdGluZykgaW5pdGlhbFZOb2RlLmVsID0gbnVsbDsNCiAgICBpZiAoaW5zdGFuY2UuYXN5bmNEZXApIHsNCiAgICAgIHBhcmVudFN1c3BlbnNlICYmIHBhcmVudFN1c3BlbnNlLnJlZ2lzdGVyRGVwKGluc3RhbmNlLCBzZXR1cFJlbmRlckVmZmVjdCwgb3B0aW1pemVkKTsNCiAgICAgIGlmICghaW5pdGlhbFZOb2RlLmVsKSB7DQogICAgICAgIGNvbnN0IHBsYWNlaG9sZGVyID0gaW5zdGFuY2Uuc3ViVHJlZSA9IGNyZWF0ZVZOb2RlKENvbW1lbnQpOw0KICAgICAgICBwcm9jZXNzQ29tbWVudE5vZGUobnVsbCwgcGxhY2Vob2xkZXIsIGNvbnRhaW5lciwgYW5jaG9yKTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgc2V0dXBSZW5kZXJFZmZlY3QoDQogICAgICAgIGluc3RhbmNlLA0KICAgICAgICBpbml0aWFsVk5vZGUsDQogICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgYW5jaG9yLA0KICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICk7DQogICAgfQ0KICAgIHsNCiAgICAgIHBvcFdhcm5pbmdDb250ZXh0KCk7DQogICAgICBlbmRNZWFzdXJlKGluc3RhbmNlLCBgbW91bnRgKTsNCiAgICB9DQogIH07DQogIGNvbnN0IHVwZGF0ZUNvbXBvbmVudCA9IChuMSwgbjIsIG9wdGltaXplZCkgPT4gew0KICAgIGNvbnN0IGluc3RhbmNlID0gbjIuY29tcG9uZW50ID0gbjEuY29tcG9uZW50Ow0KICAgIGlmIChzaG91bGRVcGRhdGVDb21wb25lbnQobjEsIG4yLCBvcHRpbWl6ZWQpKSB7DQogICAgICBpZiAoaW5zdGFuY2UuYXN5bmNEZXAgJiYgIWluc3RhbmNlLmFzeW5jUmVzb2x2ZWQpIHsNCiAgICAgICAgew0KICAgICAgICAgIHB1c2hXYXJuaW5nQ29udGV4dChuMik7DQogICAgICAgIH0NCiAgICAgICAgdXBkYXRlQ29tcG9uZW50UHJlUmVuZGVyKGluc3RhbmNlLCBuMiwgb3B0aW1pemVkKTsNCiAgICAgICAgew0KICAgICAgICAgIHBvcFdhcm5pbmdDb250ZXh0KCk7DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgaW5zdGFuY2UubmV4dCA9IG4yOw0KICAgICAgICBpbnN0YW5jZS51cGRhdGUoKTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgbjIuZWwgPSBuMS5lbDsNCiAgICAgIGluc3RhbmNlLnZub2RlID0gbjI7DQogICAgfQ0KICB9Ow0KICBjb25zdCBzZXR1cFJlbmRlckVmZmVjdCA9IChpbnN0YW5jZSwgaW5pdGlhbFZOb2RlLCBjb250YWluZXIsIGFuY2hvciwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgb3B0aW1pemVkKSA9PiB7DQogICAgY29uc3QgY29tcG9uZW50VXBkYXRlRm4gPSAoKSA9PiB7DQogICAgICBpZiAoIWluc3RhbmNlLmlzTW91bnRlZCkgew0KICAgICAgICBsZXQgdm5vZGVIb29rOw0KICAgICAgICBjb25zdCB7IGVsLCBwcm9wcyB9ID0gaW5pdGlhbFZOb2RlOw0KICAgICAgICBjb25zdCB7IGJtLCBtLCBwYXJlbnQsIHJvb3QsIHR5cGUgfSA9IGluc3RhbmNlOw0KICAgICAgICBjb25zdCBpc0FzeW5jV3JhcHBlclZOb2RlID0gaXNBc3luY1dyYXBwZXIoaW5pdGlhbFZOb2RlKTsNCiAgICAgICAgdG9nZ2xlUmVjdXJzZShpbnN0YW5jZSwgZmFsc2UpOw0KICAgICAgICBpZiAoYm0pIHsNCiAgICAgICAgICBpbnZva2VBcnJheUZucyhibSk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKCFpc0FzeW5jV3JhcHBlclZOb2RlICYmICh2bm9kZUhvb2sgPSBwcm9wcyAmJiBwcm9wcy5vblZub2RlQmVmb3JlTW91bnQpKSB7DQogICAgICAgICAgaW52b2tlVk5vZGVIb29rKHZub2RlSG9vaywgcGFyZW50LCBpbml0aWFsVk5vZGUpOw0KICAgICAgICB9DQogICAgICAgIHRvZ2dsZVJlY3Vyc2UoaW5zdGFuY2UsIHRydWUpOw0KICAgICAgICBpZiAoZWwgJiYgaHlkcmF0ZU5vZGUpIHsNCiAgICAgICAgICBjb25zdCBoeWRyYXRlU3ViVHJlZSA9ICgpID0+IHsNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgc3RhcnRNZWFzdXJlKGluc3RhbmNlLCBgcmVuZGVyYCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBpbnN0YW5jZS5zdWJUcmVlID0gcmVuZGVyQ29tcG9uZW50Um9vdChpbnN0YW5jZSk7DQogICAgICAgICAgICB7DQogICAgICAgICAgICAgIGVuZE1lYXN1cmUoaW5zdGFuY2UsIGByZW5kZXJgKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgc3RhcnRNZWFzdXJlKGluc3RhbmNlLCBgaHlkcmF0ZWApOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgaHlkcmF0ZU5vZGUoDQogICAgICAgICAgICAgIGVsLA0KICAgICAgICAgICAgICBpbnN0YW5jZS5zdWJUcmVlLA0KICAgICAgICAgICAgICBpbnN0YW5jZSwNCiAgICAgICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgICAgIG51bGwNCiAgICAgICAgICAgICk7DQogICAgICAgICAgICB7DQogICAgICAgICAgICAgIGVuZE1lYXN1cmUoaW5zdGFuY2UsIGBoeWRyYXRlYCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgfTsNCiAgICAgICAgICBpZiAoaXNBc3luY1dyYXBwZXJWTm9kZSAmJiB0eXBlLl9fYXN5bmNIeWRyYXRlKSB7DQogICAgICAgICAgICB0eXBlLl9fYXN5bmNIeWRyYXRlKA0KICAgICAgICAgICAgICBlbCwNCiAgICAgICAgICAgICAgaW5zdGFuY2UsDQogICAgICAgICAgICAgIGh5ZHJhdGVTdWJUcmVlDQogICAgICAgICAgICApOw0KICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBoeWRyYXRlU3ViVHJlZSgpOw0KICAgICAgICAgIH0NCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBpZiAocm9vdC5jZSAmJiAvLyBAdHMtZXhwZWN0LWVycm9yIF9kZWYgaXMgcHJpdmF0ZQ0KICAgICAgICAgIHJvb3QuY2UuX2RlZi5zaGFkb3dSb290ICE9PSBmYWxzZSkgew0KICAgICAgICAgICAgcm9vdC5jZS5faW5qZWN0Q2hpbGRTdHlsZSh0eXBlKTsNCiAgICAgICAgICB9DQogICAgICAgICAgew0KICAgICAgICAgICAgc3RhcnRNZWFzdXJlKGluc3RhbmNlLCBgcmVuZGVyYCk7DQogICAgICAgICAgfQ0KICAgICAgICAgIGNvbnN0IHN1YlRyZWUgPSBpbnN0YW5jZS5zdWJUcmVlID0gcmVuZGVyQ29tcG9uZW50Um9vdChpbnN0YW5jZSk7DQogICAgICAgICAgew0KICAgICAgICAgICAgZW5kTWVhc3VyZShpbnN0YW5jZSwgYHJlbmRlcmApOw0KICAgICAgICAgIH0NCiAgICAgICAgICB7DQogICAgICAgICAgICBzdGFydE1lYXN1cmUoaW5zdGFuY2UsIGBwYXRjaGApOw0KICAgICAgICAgIH0NCiAgICAgICAgICBwYXRjaCgNCiAgICAgICAgICAgIG51bGwsDQogICAgICAgICAgICBzdWJUcmVlLA0KICAgICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgICAgaW5zdGFuY2UsDQogICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgIG5hbWVzcGFjZQ0KICAgICAgICAgICk7DQogICAgICAgICAgew0KICAgICAgICAgICAgZW5kTWVhc3VyZShpbnN0YW5jZSwgYHBhdGNoYCk7DQogICAgICAgICAgfQ0KICAgICAgICAgIGluaXRpYWxWTm9kZS5lbCA9IHN1YlRyZWUuZWw7DQogICAgICAgIH0NCiAgICAgICAgaWYgKG0pIHsNCiAgICAgICAgICBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QobSwgcGFyZW50U3VzcGVuc2UpOw0KICAgICAgICB9DQogICAgICAgIGlmICghaXNBc3luY1dyYXBwZXJWTm9kZSAmJiAodm5vZGVIb29rID0gcHJvcHMgJiYgcHJvcHMub25Wbm9kZU1vdW50ZWQpKSB7DQogICAgICAgICAgY29uc3Qgc2NvcGVkSW5pdGlhbFZOb2RlID0gaW5pdGlhbFZOb2RlOw0KICAgICAgICAgIHF1ZXVlUG9zdFJlbmRlckVmZmVjdCgNCiAgICAgICAgICAgICgpID0+IGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIHBhcmVudCwgc2NvcGVkSW5pdGlhbFZOb2RlKSwNCiAgICAgICAgICAgIHBhcmVudFN1c3BlbnNlDQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgICBpZiAoaW5pdGlhbFZOb2RlLnNoYXBlRmxhZyAmIDI1NiB8fCBwYXJlbnQgJiYgaXNBc3luY1dyYXBwZXIocGFyZW50LnZub2RlKSAmJiBwYXJlbnQudm5vZGUuc2hhcGVGbGFnICYgMjU2KSB7DQogICAgICAgICAgaW5zdGFuY2UuYSAmJiBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QoaW5zdGFuY2UuYSwgcGFyZW50U3VzcGVuc2UpOw0KICAgICAgICB9DQogICAgICAgIGluc3RhbmNlLmlzTW91bnRlZCA9IHRydWU7DQogICAgICAgIHsNCiAgICAgICAgICBkZXZ0b29sc0NvbXBvbmVudEFkZGVkKGluc3RhbmNlKTsNCiAgICAgICAgfQ0KICAgICAgICBpbml0aWFsVk5vZGUgPSBjb250YWluZXIgPSBhbmNob3IgPSBudWxsOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgbGV0IHsgbmV4dCwgYnUsIHUsIHBhcmVudCwgdm5vZGUgfSA9IGluc3RhbmNlOw0KICAgICAgICB7DQogICAgICAgICAgY29uc3Qgbm9uSHlkcmF0ZWRBc3luY1Jvb3QgPSBsb2NhdGVOb25IeWRyYXRlZEFzeW5jUm9vdChpbnN0YW5jZSk7DQogICAgICAgICAgaWYgKG5vbkh5ZHJhdGVkQXN5bmNSb290KSB7DQogICAgICAgICAgICBpZiAobmV4dCkgew0KICAgICAgICAgICAgICBuZXh0LmVsID0gdm5vZGUuZWw7DQogICAgICAgICAgICAgIHVwZGF0ZUNvbXBvbmVudFByZVJlbmRlcihpbnN0YW5jZSwgbmV4dCwgb3B0aW1pemVkKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIG5vbkh5ZHJhdGVkQXN5bmNSb290LmFzeW5jRGVwLnRoZW4oKCkgPT4gew0KICAgICAgICAgICAgICBpZiAoIWluc3RhbmNlLmlzVW5tb3VudGVkKSB7DQogICAgICAgICAgICAgICAgY29tcG9uZW50VXBkYXRlRm4oKTsNCiAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSk7DQogICAgICAgICAgICByZXR1cm47DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGxldCBvcmlnaW5OZXh0ID0gbmV4dDsNCiAgICAgICAgbGV0IHZub2RlSG9vazsNCiAgICAgICAgew0KICAgICAgICAgIHB1c2hXYXJuaW5nQ29udGV4dChuZXh0IHx8IGluc3RhbmNlLnZub2RlKTsNCiAgICAgICAgfQ0KICAgICAgICB0b2dnbGVSZWN1cnNlKGluc3RhbmNlLCBmYWxzZSk7DQogICAgICAgIGlmIChuZXh0KSB7DQogICAgICAgICAgbmV4dC5lbCA9IHZub2RlLmVsOw0KICAgICAgICAgIHVwZGF0ZUNvbXBvbmVudFByZVJlbmRlcihpbnN0YW5jZSwgbmV4dCwgb3B0aW1pemVkKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBuZXh0ID0gdm5vZGU7DQogICAgICAgIH0NCiAgICAgICAgaWYgKGJ1KSB7DQogICAgICAgICAgaW52b2tlQXJyYXlGbnMoYnUpOw0KICAgICAgICB9DQogICAgICAgIGlmICh2bm9kZUhvb2sgPSBuZXh0LnByb3BzICYmIG5leHQucHJvcHMub25Wbm9kZUJlZm9yZVVwZGF0ZSkgew0KICAgICAgICAgIGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIHBhcmVudCwgbmV4dCwgdm5vZGUpOw0KICAgICAgICB9DQogICAgICAgIHRvZ2dsZVJlY3Vyc2UoaW5zdGFuY2UsIHRydWUpOw0KICAgICAgICB7DQogICAgICAgICAgc3RhcnRNZWFzdXJlKGluc3RhbmNlLCBgcmVuZGVyYCk7DQogICAgICAgIH0NCiAgICAgICAgY29uc3QgbmV4dFRyZWUgPSByZW5kZXJDb21wb25lbnRSb290KGluc3RhbmNlKTsNCiAgICAgICAgew0KICAgICAgICAgIGVuZE1lYXN1cmUoaW5zdGFuY2UsIGByZW5kZXJgKTsNCiAgICAgICAgfQ0KICAgICAgICBjb25zdCBwcmV2VHJlZSA9IGluc3RhbmNlLnN1YlRyZWU7DQogICAgICAgIGluc3RhbmNlLnN1YlRyZWUgPSBuZXh0VHJlZTsNCiAgICAgICAgew0KICAgICAgICAgIHN0YXJ0TWVhc3VyZShpbnN0YW5jZSwgYHBhdGNoYCk7DQogICAgICAgIH0NCiAgICAgICAgcGF0Y2goDQogICAgICAgICAgcHJldlRyZWUsDQogICAgICAgICAgbmV4dFRyZWUsDQogICAgICAgICAgLy8gcGFyZW50IG1heSBoYXZlIGNoYW5nZWQgaWYgaXQncyBpbiBhIHRlbGVwb3J0DQogICAgICAgICAgaG9zdFBhcmVudE5vZGUocHJldlRyZWUuZWwpLA0KICAgICAgICAgIC8vIGFuY2hvciBtYXkgaGF2ZSBjaGFuZ2VkIGlmIGl0J3MgaW4gYSBmcmFnbWVudA0KICAgICAgICAgIGdldE5leHRIb3N0Tm9kZShwcmV2VHJlZSksDQogICAgICAgICAgaW5zdGFuY2UsDQogICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgbmFtZXNwYWNlDQogICAgICAgICk7DQogICAgICAgIHsNCiAgICAgICAgICBlbmRNZWFzdXJlKGluc3RhbmNlLCBgcGF0Y2hgKTsNCiAgICAgICAgfQ0KICAgICAgICBuZXh0LmVsID0gbmV4dFRyZWUuZWw7DQogICAgICAgIGlmIChvcmlnaW5OZXh0ID09PSBudWxsKSB7DQogICAgICAgICAgdXBkYXRlSE9DSG9zdEVsKGluc3RhbmNlLCBuZXh0VHJlZS5lbCk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKHUpIHsNCiAgICAgICAgICBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QodSwgcGFyZW50U3VzcGVuc2UpOw0KICAgICAgICB9DQogICAgICAgIGlmICh2bm9kZUhvb2sgPSBuZXh0LnByb3BzICYmIG5leHQucHJvcHMub25Wbm9kZVVwZGF0ZWQpIHsNCiAgICAgICAgICBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QoDQogICAgICAgICAgICAoKSA9PiBpbnZva2VWTm9kZUhvb2sodm5vZGVIb29rLCBwYXJlbnQsIG5leHQsIHZub2RlKSwNCiAgICAgICAgICAgIHBhcmVudFN1c3BlbnNlDQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgICB7DQogICAgICAgICAgZGV2dG9vbHNDb21wb25lbnRVcGRhdGVkKGluc3RhbmNlKTsNCiAgICAgICAgfQ0KICAgICAgICB7DQogICAgICAgICAgcG9wV2FybmluZ0NvbnRleHQoKTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH07DQogICAgaW5zdGFuY2Uuc2NvcGUub24oKTsNCiAgICBjb25zdCBlZmZlY3QgPSBpbnN0YW5jZS5lZmZlY3QgPSBuZXcgUmVhY3RpdmVFZmZlY3QoY29tcG9uZW50VXBkYXRlRm4pOw0KICAgIGluc3RhbmNlLnNjb3BlLm9mZigpOw0KICAgIGNvbnN0IHVwZGF0ZSA9IGluc3RhbmNlLnVwZGF0ZSA9IGVmZmVjdC5ydW4uYmluZChlZmZlY3QpOw0KICAgIGNvbnN0IGpvYiA9IGluc3RhbmNlLmpvYiA9IGVmZmVjdC5ydW5JZkRpcnR5LmJpbmQoZWZmZWN0KTsNCiAgICBqb2IuaSA9IGluc3RhbmNlOw0KICAgIGpvYi5pZCA9IGluc3RhbmNlLnVpZDsNCiAgICBlZmZlY3Quc2NoZWR1bGVyID0gKCkgPT4gcXVldWVKb2Ioam9iKTsNCiAgICB0b2dnbGVSZWN1cnNlKGluc3RhbmNlLCB0cnVlKTsNCiAgICB7DQogICAgICBlZmZlY3Qub25UcmFjayA9IGluc3RhbmNlLnJ0YyA/IChlKSA9PiBpbnZva2VBcnJheUZucyhpbnN0YW5jZS5ydGMsIGUpIDogdm9pZCAwOw0KICAgICAgZWZmZWN0Lm9uVHJpZ2dlciA9IGluc3RhbmNlLnJ0ZyA/IChlKSA9PiBpbnZva2VBcnJheUZucyhpbnN0YW5jZS5ydGcsIGUpIDogdm9pZCAwOw0KICAgIH0NCiAgICB1cGRhdGUoKTsNCiAgfTsNCiAgY29uc3QgdXBkYXRlQ29tcG9uZW50UHJlUmVuZGVyID0gKGluc3RhbmNlLCBuZXh0Vk5vZGUsIG9wdGltaXplZCkgPT4gew0KICAgIG5leHRWTm9kZS5jb21wb25lbnQgPSBpbnN0YW5jZTsNCiAgICBjb25zdCBwcmV2UHJvcHMgPSBpbnN0YW5jZS52bm9kZS5wcm9wczsNCiAgICBpbnN0YW5jZS52bm9kZSA9IG5leHRWTm9kZTsNCiAgICBpbnN0YW5jZS5uZXh0ID0gbnVsbDsNCiAgICB1cGRhdGVQcm9wcyhpbnN0YW5jZSwgbmV4dFZOb2RlLnByb3BzLCBwcmV2UHJvcHMsIG9wdGltaXplZCk7DQogICAgdXBkYXRlU2xvdHMoaW5zdGFuY2UsIG5leHRWTm9kZS5jaGlsZHJlbiwgb3B0aW1pemVkKTsNCiAgICBwYXVzZVRyYWNraW5nKCk7DQogICAgZmx1c2hQcmVGbHVzaENicyhpbnN0YW5jZSk7DQogICAgcmVzZXRUcmFja2luZygpOw0KICB9Ow0KICBjb25zdCBwYXRjaENoaWxkcmVuID0gKG4xLCBuMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQgPSBmYWxzZSkgPT4gew0KICAgIGNvbnN0IGMxID0gbjEgJiYgbjEuY2hpbGRyZW47DQogICAgY29uc3QgcHJldlNoYXBlRmxhZyA9IG4xID8gbjEuc2hhcGVGbGFnIDogMDsNCiAgICBjb25zdCBjMiA9IG4yLmNoaWxkcmVuOw0KICAgIGNvbnN0IHsgcGF0Y2hGbGFnLCBzaGFwZUZsYWcgfSA9IG4yOw0KICAgIGlmIChwYXRjaEZsYWcgPiAwKSB7DQogICAgICBpZiAocGF0Y2hGbGFnICYgMTI4KSB7DQogICAgICAgIHBhdGNoS2V5ZWRDaGlsZHJlbigNCiAgICAgICAgICBjMSwNCiAgICAgICAgICBjMiwNCiAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICApOw0KICAgICAgICByZXR1cm47DQogICAgICB9IGVsc2UgaWYgKHBhdGNoRmxhZyAmIDI1Nikgew0KICAgICAgICBwYXRjaFVua2V5ZWRDaGlsZHJlbigNCiAgICAgICAgICBjMSwNCiAgICAgICAgICBjMiwNCiAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICApOw0KICAgICAgICByZXR1cm47DQogICAgICB9DQogICAgfQ0KICAgIGlmIChzaGFwZUZsYWcgJiA4KSB7DQogICAgICBpZiAocHJldlNoYXBlRmxhZyAmIDE2KSB7DQogICAgICAgIHVubW91bnRDaGlsZHJlbihjMSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSk7DQogICAgICB9DQogICAgICBpZiAoYzIgIT09IGMxKSB7DQogICAgICAgIGhvc3RTZXRFbGVtZW50VGV4dChjb250YWluZXIsIGMyKTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgaWYgKHByZXZTaGFwZUZsYWcgJiAxNikgew0KICAgICAgICBpZiAoc2hhcGVGbGFnICYgMTYpIHsNCiAgICAgICAgICBwYXRjaEtleWVkQ2hpbGRyZW4oDQogICAgICAgICAgICBjMSwNCiAgICAgICAgICAgIGMyLA0KICAgICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgICApOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIHVubW91bnRDaGlsZHJlbihjMSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgdHJ1ZSk7DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGlmIChwcmV2U2hhcGVGbGFnICYgOCkgew0KICAgICAgICAgIGhvc3RTZXRFbGVtZW50VGV4dChjb250YWluZXIsICIiKTsNCiAgICAgICAgfQ0KICAgICAgICBpZiAoc2hhcGVGbGFnICYgMTYpIHsNCiAgICAgICAgICBtb3VudENoaWxkcmVuKA0KICAgICAgICAgICAgYzIsDQogICAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgICBhbmNob3IsDQogICAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH07DQogIGNvbnN0IHBhdGNoVW5rZXllZENoaWxkcmVuID0gKGMxLCBjMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQpID0+IHsNCiAgICBjMSA9IGMxIHx8IEVNUFRZX0FSUjsNCiAgICBjMiA9IGMyIHx8IEVNUFRZX0FSUjsNCiAgICBjb25zdCBvbGRMZW5ndGggPSBjMS5sZW5ndGg7DQogICAgY29uc3QgbmV3TGVuZ3RoID0gYzIubGVuZ3RoOw0KICAgIGNvbnN0IGNvbW1vbkxlbmd0aCA9IE1hdGgubWluKG9sZExlbmd0aCwgbmV3TGVuZ3RoKTsNCiAgICBsZXQgaTsNCiAgICBmb3IgKGkgPSAwOyBpIDwgY29tbW9uTGVuZ3RoOyBpKyspIHsNCiAgICAgIGNvbnN0IG5leHRDaGlsZCA9IGMyW2ldID0gb3B0aW1pemVkID8gY2xvbmVJZk1vdW50ZWQoYzJbaV0pIDogbm9ybWFsaXplVk5vZGUoYzJbaV0pOw0KICAgICAgcGF0Y2goDQogICAgICAgIGMxW2ldLA0KICAgICAgICBuZXh0Q2hpbGQsDQogICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgbnVsbCwNCiAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgIG9wdGltaXplZA0KICAgICAgKTsNCiAgICB9DQogICAgaWYgKG9sZExlbmd0aCA+IG5ld0xlbmd0aCkgew0KICAgICAgdW5tb3VudENoaWxkcmVuKA0KICAgICAgICBjMSwNCiAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgdHJ1ZSwNCiAgICAgICAgZmFsc2UsDQogICAgICAgIGNvbW1vbkxlbmd0aA0KICAgICAgKTsNCiAgICB9IGVsc2Ugew0KICAgICAgbW91bnRDaGlsZHJlbigNCiAgICAgICAgYzIsDQogICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgYW5jaG9yLA0KICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgb3B0aW1pemVkLA0KICAgICAgICBjb21tb25MZW5ndGgNCiAgICAgICk7DQogICAgfQ0KICB9Ow0KICBjb25zdCBwYXRjaEtleWVkQ2hpbGRyZW4gPSAoYzEsIGMyLCBjb250YWluZXIsIHBhcmVudEFuY2hvciwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgbmFtZXNwYWNlLCBzbG90U2NvcGVJZHMsIG9wdGltaXplZCkgPT4gew0KICAgIGxldCBpID0gMDsNCiAgICBjb25zdCBsMiA9IGMyLmxlbmd0aDsNCiAgICBsZXQgZTEgPSBjMS5sZW5ndGggLSAxOw0KICAgIGxldCBlMiA9IGwyIC0gMTsNCiAgICB3aGlsZSAoaSA8PSBlMSAmJiBpIDw9IGUyKSB7DQogICAgICBjb25zdCBuMSA9IGMxW2ldOw0KICAgICAgY29uc3QgbjIgPSBjMltpXSA9IG9wdGltaXplZCA/IGNsb25lSWZNb3VudGVkKGMyW2ldKSA6IG5vcm1hbGl6ZVZOb2RlKGMyW2ldKTsNCiAgICAgIGlmIChpc1NhbWVWTm9kZVR5cGUobjEsIG4yKSkgew0KICAgICAgICBwYXRjaCgNCiAgICAgICAgICBuMSwNCiAgICAgICAgICBuMiwNCiAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgbnVsbCwNCiAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGJyZWFrOw0KICAgICAgfQ0KICAgICAgaSsrOw0KICAgIH0NCiAgICB3aGlsZSAoaSA8PSBlMSAmJiBpIDw9IGUyKSB7DQogICAgICBjb25zdCBuMSA9IGMxW2UxXTsNCiAgICAgIGNvbnN0IG4yID0gYzJbZTJdID0gb3B0aW1pemVkID8gY2xvbmVJZk1vdW50ZWQoYzJbZTJdKSA6IG5vcm1hbGl6ZVZOb2RlKGMyW2UyXSk7DQogICAgICBpZiAoaXNTYW1lVk5vZGVUeXBlKG4xLCBuMikpIHsNCiAgICAgICAgcGF0Y2goDQogICAgICAgICAgbjEsDQogICAgICAgICAgbjIsDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIG51bGwsDQogICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBicmVhazsNCiAgICAgIH0NCiAgICAgIGUxLS07DQogICAgICBlMi0tOw0KICAgIH0NCiAgICBpZiAoaSA+IGUxKSB7DQogICAgICBpZiAoaSA8PSBlMikgew0KICAgICAgICBjb25zdCBuZXh0UG9zID0gZTIgKyAxOw0KICAgICAgICBjb25zdCBhbmNob3IgPSBuZXh0UG9zIDwgbDIgPyBjMltuZXh0UG9zXS5lbCA6IHBhcmVudEFuY2hvcjsNCiAgICAgICAgd2hpbGUgKGkgPD0gZTIpIHsNCiAgICAgICAgICBwYXRjaCgNCiAgICAgICAgICAgIG51bGwsDQogICAgICAgICAgICBjMltpXSA9IG9wdGltaXplZCA/IGNsb25lSWZNb3VudGVkKGMyW2ldKSA6IG5vcm1hbGl6ZVZOb2RlKGMyW2ldKSwNCiAgICAgICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgICAgIGFuY2hvciwNCiAgICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICAgKTsNCiAgICAgICAgICBpKys7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9IGVsc2UgaWYgKGkgPiBlMikgew0KICAgICAgd2hpbGUgKGkgPD0gZTEpIHsNCiAgICAgICAgdW5tb3VudChjMVtpXSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgdHJ1ZSk7DQogICAgICAgIGkrKzsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgY29uc3QgczEgPSBpOw0KICAgICAgY29uc3QgczIgPSBpOw0KICAgICAgY29uc3Qga2V5VG9OZXdJbmRleE1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7DQogICAgICBmb3IgKGkgPSBzMjsgaSA8PSBlMjsgaSsrKSB7DQogICAgICAgIGNvbnN0IG5leHRDaGlsZCA9IGMyW2ldID0gb3B0aW1pemVkID8gY2xvbmVJZk1vdW50ZWQoYzJbaV0pIDogbm9ybWFsaXplVk5vZGUoYzJbaV0pOw0KICAgICAgICBpZiAobmV4dENoaWxkLmtleSAhPSBudWxsKSB7DQogICAgICAgICAgaWYgKGtleVRvTmV3SW5kZXhNYXAuaGFzKG5leHRDaGlsZC5rZXkpKSB7DQogICAgICAgICAgICB3YXJuJDEoDQogICAgICAgICAgICAgIGBEdXBsaWNhdGUga2V5cyBmb3VuZCBkdXJpbmcgdXBkYXRlOmAsDQogICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KG5leHRDaGlsZC5rZXkpLA0KICAgICAgICAgICAgICBgTWFrZSBzdXJlIGtleXMgYXJlIHVuaXF1ZS5gDQogICAgICAgICAgICApOw0KICAgICAgICAgIH0NCiAgICAgICAgICBrZXlUb05ld0luZGV4TWFwLnNldChuZXh0Q2hpbGQua2V5LCBpKTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgbGV0IGo7DQogICAgICBsZXQgcGF0Y2hlZCA9IDA7DQogICAgICBjb25zdCB0b0JlUGF0Y2hlZCA9IGUyIC0gczIgKyAxOw0KICAgICAgbGV0IG1vdmVkID0gZmFsc2U7DQogICAgICBsZXQgbWF4TmV3SW5kZXhTb0ZhciA9IDA7DQogICAgICBjb25zdCBuZXdJbmRleFRvT2xkSW5kZXhNYXAgPSBuZXcgQXJyYXkodG9CZVBhdGNoZWQpOw0KICAgICAgZm9yIChpID0gMDsgaSA8IHRvQmVQYXRjaGVkOyBpKyspIG5ld0luZGV4VG9PbGRJbmRleE1hcFtpXSA9IDA7DQogICAgICBmb3IgKGkgPSBzMTsgaSA8PSBlMTsgaSsrKSB7DQogICAgICAgIGNvbnN0IHByZXZDaGlsZCA9IGMxW2ldOw0KICAgICAgICBpZiAocGF0Y2hlZCA+PSB0b0JlUGF0Y2hlZCkgew0KICAgICAgICAgIHVubW91bnQocHJldkNoaWxkLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCB0cnVlKTsNCiAgICAgICAgICBjb250aW51ZTsNCiAgICAgICAgfQ0KICAgICAgICBsZXQgbmV3SW5kZXg7DQogICAgICAgIGlmIChwcmV2Q2hpbGQua2V5ICE9IG51bGwpIHsNCiAgICAgICAgICBuZXdJbmRleCA9IGtleVRvTmV3SW5kZXhNYXAuZ2V0KHByZXZDaGlsZC5rZXkpOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIGZvciAoaiA9IHMyOyBqIDw9IGUyOyBqKyspIHsNCiAgICAgICAgICAgIGlmIChuZXdJbmRleFRvT2xkSW5kZXhNYXBbaiAtIHMyXSA9PT0gMCAmJiBpc1NhbWVWTm9kZVR5cGUocHJldkNoaWxkLCBjMltqXSkpIHsNCiAgICAgICAgICAgICAgbmV3SW5kZXggPSBqOw0KICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgaWYgKG5ld0luZGV4ID09PSB2b2lkIDApIHsNCiAgICAgICAgICB1bm1vdW50KHByZXZDaGlsZCwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgdHJ1ZSk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgbmV3SW5kZXhUb09sZEluZGV4TWFwW25ld0luZGV4IC0gczJdID0gaSArIDE7DQogICAgICAgICAgaWYgKG5ld0luZGV4ID49IG1heE5ld0luZGV4U29GYXIpIHsNCiAgICAgICAgICAgIG1heE5ld0luZGV4U29GYXIgPSBuZXdJbmRleDsNCiAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgbW92ZWQgPSB0cnVlOw0KICAgICAgICAgIH0NCiAgICAgICAgICBwYXRjaCgNCiAgICAgICAgICAgIHByZXZDaGlsZCwNCiAgICAgICAgICAgIGMyW25ld0luZGV4XSwNCiAgICAgICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgICAgIG51bGwsDQogICAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICAgICk7DQogICAgICAgICAgcGF0Y2hlZCsrOw0KICAgICAgICB9DQogICAgICB9DQogICAgICBjb25zdCBpbmNyZWFzaW5nTmV3SW5kZXhTZXF1ZW5jZSA9IG1vdmVkID8gZ2V0U2VxdWVuY2UobmV3SW5kZXhUb09sZEluZGV4TWFwKSA6IEVNUFRZX0FSUjsNCiAgICAgIGogPSBpbmNyZWFzaW5nTmV3SW5kZXhTZXF1ZW5jZS5sZW5ndGggLSAxOw0KICAgICAgZm9yIChpID0gdG9CZVBhdGNoZWQgLSAxOyBpID49IDA7IGktLSkgew0KICAgICAgICBjb25zdCBuZXh0SW5kZXggPSBzMiArIGk7DQogICAgICAgIGNvbnN0IG5leHRDaGlsZCA9IGMyW25leHRJbmRleF07DQogICAgICAgIGNvbnN0IGFuY2hvciA9IG5leHRJbmRleCArIDEgPCBsMiA/IGMyW25leHRJbmRleCArIDFdLmVsIDogcGFyZW50QW5jaG9yOw0KICAgICAgICBpZiAobmV3SW5kZXhUb09sZEluZGV4TWFwW2ldID09PSAwKSB7DQogICAgICAgICAgcGF0Y2goDQogICAgICAgICAgICBudWxsLA0KICAgICAgICAgICAgbmV4dENoaWxkLA0KICAgICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgICApOw0KICAgICAgICB9IGVsc2UgaWYgKG1vdmVkKSB7DQogICAgICAgICAgaWYgKGogPCAwIHx8IGkgIT09IGluY3JlYXNpbmdOZXdJbmRleFNlcXVlbmNlW2pdKSB7DQogICAgICAgICAgICBtb3ZlKG5leHRDaGlsZCwgY29udGFpbmVyLCBhbmNob3IsIDIpOw0KICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBqLS07DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICB9Ow0KICBjb25zdCBtb3ZlID0gKHZub2RlLCBjb250YWluZXIsIGFuY2hvciwgbW92ZVR5cGUsIHBhcmVudFN1c3BlbnNlID0gbnVsbCkgPT4gew0KICAgIGNvbnN0IHsgZWwsIHR5cGUsIHRyYW5zaXRpb24sIGNoaWxkcmVuLCBzaGFwZUZsYWcgfSA9IHZub2RlOw0KICAgIGlmIChzaGFwZUZsYWcgJiA2KSB7DQogICAgICBtb3ZlKHZub2RlLmNvbXBvbmVudC5zdWJUcmVlLCBjb250YWluZXIsIGFuY2hvciwgbW92ZVR5cGUpOw0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBpZiAoc2hhcGVGbGFnICYgMTI4KSB7DQogICAgICB2bm9kZS5zdXNwZW5zZS5tb3ZlKGNvbnRhaW5lciwgYW5jaG9yLCBtb3ZlVHlwZSk7DQogICAgICByZXR1cm47DQogICAgfQ0KICAgIGlmIChzaGFwZUZsYWcgJiA2NCkgew0KICAgICAgdHlwZS5tb3ZlKHZub2RlLCBjb250YWluZXIsIGFuY2hvciwgaW50ZXJuYWxzKTsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgaWYgKHR5cGUgPT09IEZyYWdtZW50KSB7DQogICAgICBob3N0SW5zZXJ0KGVsLCBjb250YWluZXIsIGFuY2hvcik7DQogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7DQogICAgICAgIG1vdmUoY2hpbGRyZW5baV0sIGNvbnRhaW5lciwgYW5jaG9yLCBtb3ZlVHlwZSk7DQogICAgICB9DQogICAgICBob3N0SW5zZXJ0KHZub2RlLmFuY2hvciwgY29udGFpbmVyLCBhbmNob3IpOw0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBpZiAodHlwZSA9PT0gU3RhdGljKSB7DQogICAgICBtb3ZlU3RhdGljTm9kZSh2bm9kZSwgY29udGFpbmVyLCBhbmNob3IpOw0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBjb25zdCBuZWVkVHJhbnNpdGlvbjIgPSBtb3ZlVHlwZSAhPT0gMiAmJiBzaGFwZUZsYWcgJiAxICYmIHRyYW5zaXRpb247DQogICAgaWYgKG5lZWRUcmFuc2l0aW9uMikgew0KICAgICAgaWYgKG1vdmVUeXBlID09PSAwKSB7DQogICAgICAgIHRyYW5zaXRpb24uYmVmb3JlRW50ZXIoZWwpOw0KICAgICAgICBob3N0SW5zZXJ0KGVsLCBjb250YWluZXIsIGFuY2hvcik7DQogICAgICAgIHF1ZXVlUG9zdFJlbmRlckVmZmVjdCgoKSA9PiB0cmFuc2l0aW9uLmVudGVyKGVsKSwgcGFyZW50U3VzcGVuc2UpOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgY29uc3QgeyBsZWF2ZSwgZGVsYXlMZWF2ZSwgYWZ0ZXJMZWF2ZSB9ID0gdHJhbnNpdGlvbjsNCiAgICAgICAgY29uc3QgcmVtb3ZlMiA9ICgpID0+IHsNCiAgICAgICAgICBpZiAodm5vZGUuY3R4LmlzVW5tb3VudGVkKSB7DQogICAgICAgICAgICBob3N0UmVtb3ZlKGVsKTsNCiAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgaG9zdEluc2VydChlbCwgY29udGFpbmVyLCBhbmNob3IpOw0KICAgICAgICAgIH0NCiAgICAgICAgfTsNCiAgICAgICAgY29uc3QgcGVyZm9ybUxlYXZlID0gKCkgPT4gew0KICAgICAgICAgIGxlYXZlKGVsLCAoKSA9PiB7DQogICAgICAgICAgICByZW1vdmUyKCk7DQogICAgICAgICAgICBhZnRlckxlYXZlICYmIGFmdGVyTGVhdmUoKTsNCiAgICAgICAgICB9KTsNCiAgICAgICAgfTsNCiAgICAgICAgaWYgKGRlbGF5TGVhdmUpIHsNCiAgICAgICAgICBkZWxheUxlYXZlKGVsLCByZW1vdmUyLCBwZXJmb3JtTGVhdmUpOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIHBlcmZvcm1MZWF2ZSgpOw0KICAgICAgICB9DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIGhvc3RJbnNlcnQoZWwsIGNvbnRhaW5lciwgYW5jaG9yKTsNCiAgICB9DQogIH07DQogIGNvbnN0IHVubW91bnQgPSAodm5vZGUsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGRvUmVtb3ZlID0gZmFsc2UsIG9wdGltaXplZCA9IGZhbHNlKSA9PiB7DQogICAgY29uc3Qgew0KICAgICAgdHlwZSwNCiAgICAgIHByb3BzLA0KICAgICAgcmVmLA0KICAgICAgY2hpbGRyZW4sDQogICAgICBkeW5hbWljQ2hpbGRyZW4sDQogICAgICBzaGFwZUZsYWcsDQogICAgICBwYXRjaEZsYWcsDQogICAgICBkaXJzLA0KICAgICAgY2FjaGVJbmRleA0KICAgIH0gPSB2bm9kZTsNCiAgICBpZiAocGF0Y2hGbGFnID09PSAtMikgew0KICAgICAgb3B0aW1pemVkID0gZmFsc2U7DQogICAgfQ0KICAgIGlmIChyZWYgIT0gbnVsbCkgew0KICAgICAgcGF1c2VUcmFja2luZygpOw0KICAgICAgc2V0UmVmKHJlZiwgbnVsbCwgcGFyZW50U3VzcGVuc2UsIHZub2RlLCB0cnVlKTsNCiAgICAgIHJlc2V0VHJhY2tpbmcoKTsNCiAgICB9DQogICAgaWYgKGNhY2hlSW5kZXggIT0gbnVsbCkgew0KICAgICAgcGFyZW50Q29tcG9uZW50LnJlbmRlckNhY2hlW2NhY2hlSW5kZXhdID0gdm9pZCAwOw0KICAgIH0NCiAgICBpZiAoc2hhcGVGbGFnICYgMjU2KSB7DQogICAgICBwYXJlbnRDb21wb25lbnQuY3R4LmRlYWN0aXZhdGUodm5vZGUpOw0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBjb25zdCBzaG91bGRJbnZva2VEaXJzID0gc2hhcGVGbGFnICYgMSAmJiBkaXJzOw0KICAgIGNvbnN0IHNob3VsZEludm9rZVZub2RlSG9vayA9ICFpc0FzeW5jV3JhcHBlcih2bm9kZSk7DQogICAgbGV0IHZub2RlSG9vazsNCiAgICBpZiAoc2hvdWxkSW52b2tlVm5vZGVIb29rICYmICh2bm9kZUhvb2sgPSBwcm9wcyAmJiBwcm9wcy5vblZub2RlQmVmb3JlVW5tb3VudCkpIHsNCiAgICAgIGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIHBhcmVudENvbXBvbmVudCwgdm5vZGUpOw0KICAgIH0NCiAgICBpZiAoc2hhcGVGbGFnICYgNikgew0KICAgICAgdW5tb3VudENvbXBvbmVudCh2bm9kZS5jb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBkb1JlbW92ZSk7DQogICAgfSBlbHNlIHsNCiAgICAgIGlmIChzaGFwZUZsYWcgJiAxMjgpIHsNCiAgICAgICAgdm5vZGUuc3VzcGVuc2UudW5tb3VudChwYXJlbnRTdXNwZW5zZSwgZG9SZW1vdmUpOw0KICAgICAgICByZXR1cm47DQogICAgICB9DQogICAgICBpZiAoc2hvdWxkSW52b2tlRGlycykgew0KICAgICAgICBpbnZva2VEaXJlY3RpdmVIb29rKHZub2RlLCBudWxsLCBwYXJlbnRDb21wb25lbnQsICJiZWZvcmVVbm1vdW50Iik7DQogICAgICB9DQogICAgICBpZiAoc2hhcGVGbGFnICYgNjQpIHsNCiAgICAgICAgdm5vZGUudHlwZS5yZW1vdmUoDQogICAgICAgICAgdm5vZGUsDQogICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgIGludGVybmFscywNCiAgICAgICAgICBkb1JlbW92ZQ0KICAgICAgICApOw0KICAgICAgfSBlbHNlIGlmIChkeW5hbWljQ2hpbGRyZW4gJiYgLy8gIzUxNTQNCiAgICAgIC8vIHdoZW4gdi1vbmNlIGlzIHVzZWQgaW5zaWRlIGEgYmxvY2ssIHNldEJsb2NrVHJhY2tpbmcoLTEpIG1hcmtzIHRoZQ0KICAgICAgLy8gcGFyZW50IGJsb2NrIHdpdGggaGFzT25jZTogdHJ1ZQ0KICAgICAgLy8gc28gdGhhdCBpdCBkb2Vzbid0IHRha2UgdGhlIGZhc3QgcGF0aCBkdXJpbmcgdW5tb3VudCAtIG90aGVyd2lzZQ0KICAgICAgLy8gY29tcG9uZW50cyBuZXN0ZWQgaW4gdi1vbmNlIGFyZSBuZXZlciB1bm1vdW50ZWQuDQogICAgICAhZHluYW1pY0NoaWxkcmVuLmhhc09uY2UgJiYgLy8gIzExNTM6IGZhc3QgcGF0aCBzaG91bGQgbm90IGJlIHRha2VuIGZvciBub24tc3RhYmxlICh2LWZvcikgZnJhZ21lbnRzDQogICAgICAodHlwZSAhPT0gRnJhZ21lbnQgfHwgcGF0Y2hGbGFnID4gMCAmJiBwYXRjaEZsYWcgJiA2NCkpIHsNCiAgICAgICAgdW5tb3VudENoaWxkcmVuKA0KICAgICAgICAgIGR5bmFtaWNDaGlsZHJlbiwNCiAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgZmFsc2UsDQogICAgICAgICAgdHJ1ZQ0KICAgICAgICApOw0KICAgICAgfSBlbHNlIGlmICh0eXBlID09PSBGcmFnbWVudCAmJiBwYXRjaEZsYWcgJiAoMTI4IHwgMjU2KSB8fCAhb3B0aW1pemVkICYmIHNoYXBlRmxhZyAmIDE2KSB7DQogICAgICAgIHVubW91bnRDaGlsZHJlbihjaGlsZHJlbiwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSk7DQogICAgICB9DQogICAgICBpZiAoZG9SZW1vdmUpIHsNCiAgICAgICAgcmVtb3ZlKHZub2RlKTsNCiAgICAgIH0NCiAgICB9DQogICAgaWYgKHNob3VsZEludm9rZVZub2RlSG9vayAmJiAodm5vZGVIb29rID0gcHJvcHMgJiYgcHJvcHMub25Wbm9kZVVubW91bnRlZCkgfHwgc2hvdWxkSW52b2tlRGlycykgew0KICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KCgpID0+IHsNCiAgICAgICAgdm5vZGVIb29rICYmIGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIHBhcmVudENvbXBvbmVudCwgdm5vZGUpOw0KICAgICAgICBzaG91bGRJbnZva2VEaXJzICYmIGludm9rZURpcmVjdGl2ZUhvb2sodm5vZGUsIG51bGwsIHBhcmVudENvbXBvbmVudCwgInVubW91bnRlZCIpOw0KICAgICAgfSwgcGFyZW50U3VzcGVuc2UpOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgcmVtb3ZlID0gKHZub2RlKSA9PiB7DQogICAgY29uc3QgeyB0eXBlLCBlbCwgYW5jaG9yLCB0cmFuc2l0aW9uIH0gPSB2bm9kZTsNCiAgICBpZiAodHlwZSA9PT0gRnJhZ21lbnQpIHsNCiAgICAgIGlmICh2bm9kZS5wYXRjaEZsYWcgPiAwICYmIHZub2RlLnBhdGNoRmxhZyAmIDIwNDggJiYgdHJhbnNpdGlvbiAmJiAhdHJhbnNpdGlvbi5wZXJzaXN0ZWQpIHsNCiAgICAgICAgdm5vZGUuY2hpbGRyZW4uZm9yRWFjaCgoY2hpbGQpID0+IHsNCiAgICAgICAgICBpZiAoY2hpbGQudHlwZSA9PT0gQ29tbWVudCkgew0KICAgICAgICAgICAgaG9zdFJlbW92ZShjaGlsZC5lbCk7DQogICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIHJlbW92ZShjaGlsZCk7DQogICAgICAgICAgfQ0KICAgICAgICB9KTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHJlbW92ZUZyYWdtZW50KGVsLCBhbmNob3IpOw0KICAgICAgfQ0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBpZiAodHlwZSA9PT0gU3RhdGljKSB7DQogICAgICByZW1vdmVTdGF0aWNOb2RlKHZub2RlKTsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgY29uc3QgcGVyZm9ybVJlbW92ZSA9ICgpID0+IHsNCiAgICAgIGhvc3RSZW1vdmUoZWwpOw0KICAgICAgaWYgKHRyYW5zaXRpb24gJiYgIXRyYW5zaXRpb24ucGVyc2lzdGVkICYmIHRyYW5zaXRpb24uYWZ0ZXJMZWF2ZSkgew0KICAgICAgICB0cmFuc2l0aW9uLmFmdGVyTGVhdmUoKTsNCiAgICAgIH0NCiAgICB9Ow0KICAgIGlmICh2bm9kZS5zaGFwZUZsYWcgJiAxICYmIHRyYW5zaXRpb24gJiYgIXRyYW5zaXRpb24ucGVyc2lzdGVkKSB7DQogICAgICBjb25zdCB7IGxlYXZlLCBkZWxheUxlYXZlIH0gPSB0cmFuc2l0aW9uOw0KICAgICAgY29uc3QgcGVyZm9ybUxlYXZlID0gKCkgPT4gbGVhdmUoZWwsIHBlcmZvcm1SZW1vdmUpOw0KICAgICAgaWYgKGRlbGF5TGVhdmUpIHsNCiAgICAgICAgZGVsYXlMZWF2ZSh2bm9kZS5lbCwgcGVyZm9ybVJlbW92ZSwgcGVyZm9ybUxlYXZlKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHBlcmZvcm1MZWF2ZSgpOw0KICAgICAgfQ0KICAgIH0gZWxzZSB7DQogICAgICBwZXJmb3JtUmVtb3ZlKCk7DQogICAgfQ0KICB9Ow0KICBjb25zdCByZW1vdmVGcmFnbWVudCA9IChjdXIsIGVuZCkgPT4gew0KICAgIGxldCBuZXh0Ow0KICAgIHdoaWxlIChjdXIgIT09IGVuZCkgew0KICAgICAgbmV4dCA9IGhvc3ROZXh0U2libGluZyhjdXIpOw0KICAgICAgaG9zdFJlbW92ZShjdXIpOw0KICAgICAgY3VyID0gbmV4dDsNCiAgICB9DQogICAgaG9zdFJlbW92ZShlbmQpOw0KICB9Ow0KICBjb25zdCB1bm1vdW50Q29tcG9uZW50ID0gKGluc3RhbmNlLCBwYXJlbnRTdXNwZW5zZSwgZG9SZW1vdmUpID0+IHsNCiAgICBpZiAoaW5zdGFuY2UudHlwZS5fX2htcklkKSB7DQogICAgICB1bnJlZ2lzdGVySE1SKGluc3RhbmNlKTsNCiAgICB9DQogICAgY29uc3Qgew0KICAgICAgYnVtLA0KICAgICAgc2NvcGUsDQogICAgICBqb2IsDQogICAgICBzdWJUcmVlLA0KICAgICAgdW0sDQogICAgICBtLA0KICAgICAgYSwNCiAgICAgIHBhcmVudCwNCiAgICAgIHNsb3RzOiB7IF9fOiBzbG90Q2FjaGVLZXlzIH0NCiAgICB9ID0gaW5zdGFuY2U7DQogICAgaW52YWxpZGF0ZU1vdW50KG0pOw0KICAgIGludmFsaWRhdGVNb3VudChhKTsNCiAgICBpZiAoYnVtKSB7DQogICAgICBpbnZva2VBcnJheUZucyhidW0pOw0KICAgIH0NCiAgICBpZiAocGFyZW50ICYmIGlzQXJyYXkoc2xvdENhY2hlS2V5cykpIHsNCiAgICAgIHNsb3RDYWNoZUtleXMuZm9yRWFjaCgodikgPT4gew0KICAgICAgICBwYXJlbnQucmVuZGVyQ2FjaGVbdl0gPSB2b2lkIDA7DQogICAgICB9KTsNCiAgICB9DQogICAgc2NvcGUuc3RvcCgpOw0KICAgIGlmIChqb2IpIHsNCiAgICAgIGpvYi5mbGFncyB8PSA4Ow0KICAgICAgdW5tb3VudChzdWJUcmVlLCBpbnN0YW5jZSwgcGFyZW50U3VzcGVuc2UsIGRvUmVtb3ZlKTsNCiAgICB9DQogICAgaWYgKHVtKSB7DQogICAgICBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QodW0sIHBhcmVudFN1c3BlbnNlKTsNCiAgICB9DQogICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KCgpID0+IHsNCiAgICAgIGluc3RhbmNlLmlzVW5tb3VudGVkID0gdHJ1ZTsNCiAgICB9LCBwYXJlbnRTdXNwZW5zZSk7DQogICAgaWYgKHBhcmVudFN1c3BlbnNlICYmIHBhcmVudFN1c3BlbnNlLnBlbmRpbmdCcmFuY2ggJiYgIXBhcmVudFN1c3BlbnNlLmlzVW5tb3VudGVkICYmIGluc3RhbmNlLmFzeW5jRGVwICYmICFpbnN0YW5jZS5hc3luY1Jlc29sdmVkICYmIGluc3RhbmNlLnN1c3BlbnNlSWQgPT09IHBhcmVudFN1c3BlbnNlLnBlbmRpbmdJZCkgew0KICAgICAgcGFyZW50U3VzcGVuc2UuZGVwcy0tOw0KICAgICAgaWYgKHBhcmVudFN1c3BlbnNlLmRlcHMgPT09IDApIHsNCiAgICAgICAgcGFyZW50U3VzcGVuc2UucmVzb2x2ZSgpOw0KICAgICAgfQ0KICAgIH0NCiAgICB7DQogICAgICBkZXZ0b29sc0NvbXBvbmVudFJlbW92ZWQoaW5zdGFuY2UpOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgdW5tb3VudENoaWxkcmVuID0gKGNoaWxkcmVuLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBkb1JlbW92ZSA9IGZhbHNlLCBvcHRpbWl6ZWQgPSBmYWxzZSwgc3RhcnQgPSAwKSA9PiB7DQogICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHsNCiAgICAgIHVubW91bnQoY2hpbGRyZW5baV0sIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGRvUmVtb3ZlLCBvcHRpbWl6ZWQpOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgZ2V0TmV4dEhvc3ROb2RlID0gKHZub2RlKSA9PiB7DQogICAgaWYgKHZub2RlLnNoYXBlRmxhZyAmIDYpIHsNCiAgICAgIHJldHVybiBnZXROZXh0SG9zdE5vZGUodm5vZGUuY29tcG9uZW50LnN1YlRyZWUpOw0KICAgIH0NCiAgICBpZiAodm5vZGUuc2hhcGVGbGFnICYgMTI4KSB7DQogICAgICByZXR1cm4gdm5vZGUuc3VzcGVuc2UubmV4dCgpOw0KICAgIH0NCiAgICBjb25zdCBlbCA9IGhvc3ROZXh0U2libGluZyh2bm9kZS5hbmNob3IgfHwgdm5vZGUuZWwpOw0KICAgIGNvbnN0IHRlbGVwb3J0RW5kID0gZWwgJiYgZWxbVGVsZXBvcnRFbmRLZXldOw0KICAgIHJldHVybiB0ZWxlcG9ydEVuZCA/IGhvc3ROZXh0U2libGluZyh0ZWxlcG9ydEVuZCkgOiBlbDsNCiAgfTsNCiAgbGV0IGlzRmx1c2hpbmcgPSBmYWxzZTsNCiAgY29uc3QgcmVuZGVyID0gKHZub2RlLCBjb250YWluZXIsIG5hbWVzcGFjZSkgPT4gew0KICAgIGlmICh2bm9kZSA9PSBudWxsKSB7DQogICAgICBpZiAoY29udGFpbmVyLl92bm9kZSkgew0KICAgICAgICB1bm1vdW50KGNvbnRhaW5lci5fdm5vZGUsIG51bGwsIG51bGwsIHRydWUpOw0KICAgICAgfQ0KICAgIH0gZWxzZSB7DQogICAgICBwYXRjaCgNCiAgICAgICAgY29udGFpbmVyLl92bm9kZSB8fCBudWxsLA0KICAgICAgICB2bm9kZSwNCiAgICAgICAgY29udGFpbmVyLA0KICAgICAgICBudWxsLA0KICAgICAgICBudWxsLA0KICAgICAgICBudWxsLA0KICAgICAgICBuYW1lc3BhY2UNCiAgICAgICk7DQogICAgfQ0KICAgIGNvbnRhaW5lci5fdm5vZGUgPSB2bm9kZTsNCiAgICBpZiAoIWlzRmx1c2hpbmcpIHsNCiAgICAgIGlzRmx1c2hpbmcgPSB0cnVlOw0KICAgICAgZmx1c2hQcmVGbHVzaENicygpOw0KICAgICAgZmx1c2hQb3N0Rmx1c2hDYnMoKTsNCiAgICAgIGlzRmx1c2hpbmcgPSBmYWxzZTsNCiAgICB9DQogIH07DQogIGNvbnN0IGludGVybmFscyA9IHsNCiAgICBwOiBwYXRjaCwNCiAgICB1bTogdW5tb3VudCwNCiAgICBtOiBtb3ZlLA0KICAgIHI6IHJlbW92ZSwNCiAgICBtdDogbW91bnRDb21wb25lbnQsDQogICAgbWM6IG1vdW50Q2hpbGRyZW4sDQogICAgcGM6IHBhdGNoQ2hpbGRyZW4sDQogICAgcGJjOiBwYXRjaEJsb2NrQ2hpbGRyZW4sDQogICAgbjogZ2V0TmV4dEhvc3ROb2RlLA0KICAgIG86IG9wdGlvbnMNCiAgfTsNCiAgbGV0IGh5ZHJhdGU7DQogIGxldCBoeWRyYXRlTm9kZTsNCiAgaWYgKGNyZWF0ZUh5ZHJhdGlvbkZucykgew0KICAgIFtoeWRyYXRlLCBoeWRyYXRlTm9kZV0gPSBjcmVhdGVIeWRyYXRpb25GbnMoDQogICAgICBpbnRlcm5hbHMNCiAgICApOw0KICB9DQogIHJldHVybiB7DQogICAgcmVuZGVyLA0KICAgIGh5ZHJhdGUsDQogICAgY3JlYXRlQXBwOiBjcmVhdGVBcHBBUEkocmVuZGVyLCBoeWRyYXRlKQ0KICB9Ow0KfQ0KZnVuY3Rpb24gcmVzb2x2ZUNoaWxkcmVuTmFtZXNwYWNlKHsgdHlwZSwgcHJvcHMgfSwgY3VycmVudE5hbWVzcGFjZSkgew0KICByZXR1cm4gY3VycmVudE5hbWVzcGFjZSA9PT0gInN2ZyIgJiYgdHlwZSA9PT0gImZvcmVpZ25PYmplY3QiIHx8IGN1cnJlbnROYW1lc3BhY2UgPT09ICJtYXRobWwiICYmIHR5cGUgPT09ICJhbm5vdGF0aW9uLXhtbCIgJiYgcHJvcHMgJiYgcHJvcHMuZW5jb2RpbmcgJiYgcHJvcHMuZW5jb2RpbmcuaW5jbHVkZXMoImh0bWwiKSA/IHZvaWQgMCA6IGN1cnJlbnROYW1lc3BhY2U7DQp9DQpmdW5jdGlvbiB0b2dnbGVSZWN1cnNlKHsgZWZmZWN0LCBqb2IgfSwgYWxsb3dlZCkgew0KICBpZiAoYWxsb3dlZCkgew0KICAgIGVmZmVjdC5mbGFncyB8PSAzMjsNCiAgICBqb2IuZmxhZ3MgfD0gNDsNCiAgfSBlbHNlIHsNCiAgICBlZmZlY3QuZmxhZ3MgJj0gLTMzOw0KICAgIGpvYi5mbGFncyAmPSAtNTsNCiAgfQ0KfQ0KZnVuY3Rpb24gbmVlZFRyYW5zaXRpb24ocGFyZW50U3VzcGVuc2UsIHRyYW5zaXRpb24pIHsNCiAgcmV0dXJuICghcGFyZW50U3VzcGVuc2UgfHwgcGFyZW50U3VzcGVuc2UgJiYgIXBhcmVudFN1c3BlbnNlLnBlbmRpbmdCcmFuY2gpICYmIHRyYW5zaXRpb24gJiYgIXRyYW5zaXRpb24ucGVyc2lzdGVkOw0KfQ0KZnVuY3Rpb24gdHJhdmVyc2VTdGF0aWNDaGlsZHJlbihuMSwgbjIsIHNoYWxsb3cgPSBmYWxzZSkgew0KICBjb25zdCBjaDEgPSBuMS5jaGlsZHJlbjsNCiAgY29uc3QgY2gyID0gbjIuY2hpbGRyZW47DQogIGlmIChpc0FycmF5KGNoMSkgJiYgaXNBcnJheShjaDIpKSB7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaDEubGVuZ3RoOyBpKyspIHsNCiAgICAgIGNvbnN0IGMxID0gY2gxW2ldOw0KICAgICAgbGV0IGMyID0gY2gyW2ldOw0KICAgICAgaWYgKGMyLnNoYXBlRmxhZyAmIDEgJiYgIWMyLmR5bmFtaWNDaGlsZHJlbikgew0KICAgICAgICBpZiAoYzIucGF0Y2hGbGFnIDw9IDAgfHwgYzIucGF0Y2hGbGFnID09PSAzMikgew0KICAgICAgICAgIGMyID0gY2gyW2ldID0gY2xvbmVJZk1vdW50ZWQoY2gyW2ldKTsNCiAgICAgICAgICBjMi5lbCA9IGMxLmVsOw0KICAgICAgICB9DQogICAgICAgIGlmICghc2hhbGxvdyAmJiBjMi5wYXRjaEZsYWcgIT09IC0yKQ0KICAgICAgICAgIHRyYXZlcnNlU3RhdGljQ2hpbGRyZW4oYzEsIGMyKTsNCiAgICAgIH0NCiAgICAgIGlmIChjMi50eXBlID09PSBUZXh0KSB7DQogICAgICAgIGMyLmVsID0gYzEuZWw7DQogICAgICB9DQogICAgICBpZiAoYzIudHlwZSA9PT0gQ29tbWVudCAmJiAhYzIuZWwpIHsNCiAgICAgICAgYzIuZWwgPSBjMS5lbDsNCiAgICAgIH0NCiAgICAgIHsNCiAgICAgICAgYzIuZWwgJiYgKGMyLmVsLl9fdm5vZGUgPSBjMik7DQogICAgICB9DQogICAgfQ0KICB9DQp9DQpmdW5jdGlvbiBnZXRTZXF1ZW5jZShhcnIpIHsNCiAgY29uc3QgcCA9IGFyci5zbGljZSgpOw0KICBjb25zdCByZXN1bHQgPSBbMF07DQogIGxldCBpLCBqLCB1LCB2LCBjOw0KICBjb25zdCBsZW4gPSBhcnIubGVuZ3RoOw0KICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHsNCiAgICBjb25zdCBhcnJJID0gYXJyW2ldOw0KICAgIGlmIChhcnJJICE9PSAwKSB7DQogICAgICBqID0gcmVzdWx0W3Jlc3VsdC5sZW5ndGggLSAxXTsNCiAgICAgIGlmIChhcnJbal0gPCBhcnJJKSB7DQogICAgICAgIHBbaV0gPSBqOw0KICAgICAgICByZXN1bHQucHVzaChpKTsNCiAgICAgICAgY29udGludWU7DQogICAgICB9DQogICAgICB1ID0gMDsNCiAgICAgIHYgPSByZXN1bHQubGVuZ3RoIC0gMTsNCiAgICAgIHdoaWxlICh1IDwgdikgew0KICAgICAgICBjID0gdSArIHYgPj4gMTsNCiAgICAgICAgaWYgKGFycltyZXN1bHRbY11dIDwgYXJySSkgew0KICAgICAgICAgIHUgPSBjICsgMTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICB2ID0gYzsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgaWYgKGFyckkgPCBhcnJbcmVzdWx0W3VdXSkgew0KICAgICAgICBpZiAodSA+IDApIHsNCiAgICAgICAgICBwW2ldID0gcmVzdWx0W3UgLSAxXTsNCiAgICAgICAgfQ0KICAgICAgICByZXN1bHRbdV0gPSBpOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICB1ID0gcmVzdWx0Lmxlbmd0aDsNCiAgdiA9IHJlc3VsdFt1IC0gMV07DQogIHdoaWxlICh1LS0gPiAwKSB7DQogICAgcmVzdWx0W3VdID0gdjsNCiAgICB2ID0gcFt2XTsNCiAgfQ0KICByZXR1cm4gcmVzdWx0Ow0KfQ0KZnVuY3Rpb24gbG9jYXRlTm9uSHlkcmF0ZWRBc3luY1Jvb3QoaW5zdGFuY2UpIHsNCiAgY29uc3Qgc3ViQ29tcG9uZW50ID0gaW5zdGFuY2Uuc3ViVHJlZS5jb21wb25lbnQ7DQogIGlmIChzdWJDb21wb25lbnQpIHsNCiAgICBpZiAoc3ViQ29tcG9uZW50LmFzeW5jRGVwICYmICFzdWJDb21wb25lbnQuYXN5bmNSZXNvbHZlZCkgew0KICAgICAgcmV0dXJuIHN1YkNvbXBvbmVudDsNCiAgICB9IGVsc2Ugew0KICAgICAgcmV0dXJuIGxvY2F0ZU5vbkh5ZHJhdGVkQXN5bmNSb290KHN1YkNvbXBvbmVudCk7DQogICAgfQ0KICB9DQp9DQpmdW5jdGlvbiBpbnZhbGlkYXRlTW91bnQoaG9va3MpIHsNCiAgaWYgKGhvb2tzKSB7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBob29rcy5sZW5ndGg7IGkrKykNCiAgICAgIGhvb2tzW2ldLmZsYWdzIHw9IDg7DQogIH0NCn0NCg0KY29uc3Qgc3NyQ29udGV4dEtleSA9IFN5bWJvbC5mb3IoInYtc2N4Iik7DQpjb25zdCB1c2VTU1JDb250ZXh0ID0gKCkgPT4gew0KICB7DQogICAgY29uc3QgY3R4ID0gaW5qZWN0KHNzckNvbnRleHRLZXkpOw0KICAgIGlmICghY3R4KSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGBTZXJ2ZXIgcmVuZGVyaW5nIGNvbnRleHQgbm90IHByb3ZpZGVkLiBNYWtlIHN1cmUgdG8gb25seSBjYWxsIHVzZVNTUkNvbnRleHQoKSBjb25kaXRpb25hbGx5IGluIHRoZSBzZXJ2ZXIgYnVpbGQuYA0KICAgICAgKTsNCiAgICB9DQogICAgcmV0dXJuIGN0eDsNCiAgfQ0KfTsNCg0KZnVuY3Rpb24gd2F0Y2hFZmZlY3QoZWZmZWN0LCBvcHRpb25zKSB7DQogIHJldHVybiBkb1dhdGNoKGVmZmVjdCwgbnVsbCwgb3B0aW9ucyk7DQp9DQpmdW5jdGlvbiB3YXRjaFBvc3RFZmZlY3QoZWZmZWN0LCBvcHRpb25zKSB7DQogIHJldHVybiBkb1dhdGNoKA0KICAgIGVmZmVjdCwNCiAgICBudWxsLA0KICAgIGV4dGVuZCh7fSwgb3B0aW9ucywgeyBmbHVzaDogInBvc3QiIH0pIA0KICApOw0KfQ0KZnVuY3Rpb24gd2F0Y2hTeW5jRWZmZWN0KGVmZmVjdCwgb3B0aW9ucykgew0KICByZXR1cm4gZG9XYXRjaCgNCiAgICBlZmZlY3QsDQogICAgbnVsbCwNCiAgICBleHRlbmQoe30sIG9wdGlvbnMsIHsgZmx1c2g6ICJzeW5jIiB9KSANCiAgKTsNCn0NCmZ1bmN0aW9uIHdhdGNoKHNvdXJjZSwgY2IsIG9wdGlvbnMpIHsNCiAgaWYgKCFpc0Z1bmN0aW9uKGNiKSkgew0KICAgIHdhcm4kMSgNCiAgICAgIGBcYHdhdGNoKGZuLCBvcHRpb25zPylcYCBzaWduYXR1cmUgaGFzIGJlZW4gbW92ZWQgdG8gYSBzZXBhcmF0ZSBBUEkuIFVzZSBcYHdhdGNoRWZmZWN0KGZuLCBvcHRpb25zPylcYCBpbnN0ZWFkLiBcYHdhdGNoXGAgbm93IG9ubHkgc3VwcG9ydHMgXGB3YXRjaChzb3VyY2UsIGNiLCBvcHRpb25zPykgc2lnbmF0dXJlLmANCiAgICApOw0KICB9DQogIHJldHVybiBkb1dhdGNoKHNvdXJjZSwgY2IsIG9wdGlvbnMpOw0KfQ0KZnVuY3Rpb24gZG9XYXRjaChzb3VyY2UsIGNiLCBvcHRpb25zID0gRU1QVFlfT0JKKSB7DQogIGNvbnN0IHsgaW1tZWRpYXRlLCBkZWVwLCBmbHVzaCwgb25jZSB9ID0gb3B0aW9uczsNCiAgaWYgKCFjYikgew0KICAgIGlmIChpbW1lZGlhdGUgIT09IHZvaWQgMCkgew0KICAgICAgd2FybiQxKA0KICAgICAgICBgd2F0Y2goKSAiaW1tZWRpYXRlIiBvcHRpb24gaXMgb25seSByZXNwZWN0ZWQgd2hlbiB1c2luZyB0aGUgd2F0Y2goc291cmNlLCBjYWxsYmFjaywgb3B0aW9ucz8pIHNpZ25hdHVyZS5gDQogICAgICApOw0KICAgIH0NCiAgICBpZiAoZGVlcCAhPT0gdm9pZCAwKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGB3YXRjaCgpICJkZWVwIiBvcHRpb24gaXMgb25seSByZXNwZWN0ZWQgd2hlbiB1c2luZyB0aGUgd2F0Y2goc291cmNlLCBjYWxsYmFjaywgb3B0aW9ucz8pIHNpZ25hdHVyZS5gDQogICAgICApOw0KICAgIH0NCiAgICBpZiAob25jZSAhPT0gdm9pZCAwKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGB3YXRjaCgpICJvbmNlIiBvcHRpb24gaXMgb25seSByZXNwZWN0ZWQgd2hlbiB1c2luZyB0aGUgd2F0Y2goc291cmNlLCBjYWxsYmFjaywgb3B0aW9ucz8pIHNpZ25hdHVyZS5gDQogICAgICApOw0KICAgIH0NCiAgfQ0KICBjb25zdCBiYXNlV2F0Y2hPcHRpb25zID0gZXh0ZW5kKHt9LCBvcHRpb25zKTsNCiAgYmFzZVdhdGNoT3B0aW9ucy5vbldhcm4gPSB3YXJuJDE7DQogIGNvbnN0IHJ1bnNJbW1lZGlhdGVseSA9IGNiICYmIGltbWVkaWF0ZSB8fCAhY2IgJiYgZmx1c2ggIT09ICJwb3N0IjsNCiAgbGV0IHNzckNsZWFudXA7DQogIGlmIChpc0luU1NSQ29tcG9uZW50U2V0dXApIHsNCiAgICBpZiAoZmx1c2ggPT09ICJzeW5jIikgew0KICAgICAgY29uc3QgY3R4ID0gdXNlU1NSQ29udGV4dCgpOw0KICAgICAgc3NyQ2xlYW51cCA9IGN0eC5fX3dhdGNoZXJIYW5kbGVzIHx8IChjdHguX193YXRjaGVySGFuZGxlcyA9IFtdKTsNCiAgICB9IGVsc2UgaWYgKCFydW5zSW1tZWRpYXRlbHkpIHsNCiAgICAgIGNvbnN0IHdhdGNoU3RvcEhhbmRsZSA9ICgpID0+IHsNCiAgICAgIH07DQogICAgICB3YXRjaFN0b3BIYW5kbGUuc3RvcCA9IE5PT1A7DQogICAgICB3YXRjaFN0b3BIYW5kbGUucmVzdW1lID0gTk9PUDsNCiAgICAgIHdhdGNoU3RvcEhhbmRsZS5wYXVzZSA9IE5PT1A7DQogICAgICByZXR1cm4gd2F0Y2hTdG9wSGFuZGxlOw0KICAgIH0NCiAgfQ0KICBjb25zdCBpbnN0YW5jZSA9IGN1cnJlbnRJbnN0YW5jZTsNCiAgYmFzZVdhdGNoT3B0aW9ucy5jYWxsID0gKGZuLCB0eXBlLCBhcmdzKSA9PiBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZyhmbiwgaW5zdGFuY2UsIHR5cGUsIGFyZ3MpOw0KICBsZXQgaXNQcmUgPSBmYWxzZTsNCiAgaWYgKGZsdXNoID09PSAicG9zdCIpIHsNCiAgICBiYXNlV2F0Y2hPcHRpb25zLnNjaGVkdWxlciA9IChqb2IpID0+IHsNCiAgICAgIHF1ZXVlUG9zdFJlbmRlckVmZmVjdChqb2IsIGluc3RhbmNlICYmIGluc3RhbmNlLnN1c3BlbnNlKTsNCiAgICB9Ow0KICB9IGVsc2UgaWYgKGZsdXNoICE9PSAic3luYyIpIHsNCiAgICBpc1ByZSA9IHRydWU7DQogICAgYmFzZVdhdGNoT3B0aW9ucy5zY2hlZHVsZXIgPSAoam9iLCBpc0ZpcnN0UnVuKSA9PiB7DQogICAgICBpZiAoaXNGaXJzdFJ1bikgew0KICAgICAgICBqb2IoKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHF1ZXVlSm9iKGpvYik7DQogICAgICB9DQogICAgfTsNCiAgfQ0KICBiYXNlV2F0Y2hPcHRpb25zLmF1Z21lbnRKb2IgPSAoam9iKSA9PiB7DQogICAgaWYgKGNiKSB7DQogICAgICBqb2IuZmxhZ3MgfD0gNDsNCiAgICB9DQogICAgaWYgKGlzUHJlKSB7DQogICAgICBqb2IuZmxhZ3MgfD0gMjsNCiAgICAgIGlmIChpbnN0YW5jZSkgew0KICAgICAgICBqb2IuaWQgPSBpbnN0YW5jZS51aWQ7DQogICAgICAgIGpvYi5pID0gaW5zdGFuY2U7DQogICAgICB9DQogICAgfQ0KICB9Ow0KICBjb25zdCB3YXRjaEhhbmRsZSA9IHdhdGNoJDEoc291cmNlLCBjYiwgYmFzZVdhdGNoT3B0aW9ucyk7DQogIGlmIChpc0luU1NSQ29tcG9uZW50U2V0dXApIHsNCiAgICBpZiAoc3NyQ2xlYW51cCkgew0KICAgICAgc3NyQ2xlYW51cC5wdXNoKHdhdGNoSGFuZGxlKTsNCiAgICB9IGVsc2UgaWYgKHJ1bnNJbW1lZGlhdGVseSkgew0KICAgICAgd2F0Y2hIYW5kbGUoKTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIHdhdGNoSGFuZGxlOw0KfQ0KZnVuY3Rpb24gaW5zdGFuY2VXYXRjaChzb3VyY2UsIHZhbHVlLCBvcHRpb25zKSB7DQogIGNvbnN0IHB1YmxpY1RoaXMgPSB0aGlzLnByb3h5Ow0KICBjb25zdCBnZXR0ZXIgPSBpc1N0cmluZyhzb3VyY2UpID8gc291cmNlLmluY2x1ZGVzKCIuIikgPyBjcmVhdGVQYXRoR2V0dGVyKHB1YmxpY1RoaXMsIHNvdXJjZSkgOiAoKSA9PiBwdWJsaWNUaGlzW3NvdXJjZV0gOiBzb3VyY2UuYmluZChwdWJsaWNUaGlzLCBwdWJsaWNUaGlzKTsNCiAgbGV0IGNiOw0KICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHsNCiAgICBjYiA9IHZhbHVlOw0KICB9IGVsc2Ugew0KICAgIGNiID0gdmFsdWUuaGFuZGxlcjsNCiAgICBvcHRpb25zID0gdmFsdWU7DQogIH0NCiAgY29uc3QgcmVzZXQgPSBzZXRDdXJyZW50SW5zdGFuY2UodGhpcyk7DQogIGNvbnN0IHJlcyA9IGRvV2F0Y2goZ2V0dGVyLCBjYi5iaW5kKHB1YmxpY1RoaXMpLCBvcHRpb25zKTsNCiAgcmVzZXQoKTsNCiAgcmV0dXJuIHJlczsNCn0NCmZ1bmN0aW9uIGNyZWF0ZVBhdGhHZXR0ZXIoY3R4LCBwYXRoKSB7DQogIGNvbnN0IHNlZ21lbnRzID0gcGF0aC5zcGxpdCgiLiIpOw0KICByZXR1cm4gKCkgPT4gew0KICAgIGxldCBjdXIgPSBjdHg7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWdtZW50cy5sZW5ndGggJiYgY3VyOyBpKyspIHsNCiAgICAgIGN1ciA9IGN1cltzZWdtZW50c1tpXV07DQogICAgfQ0KICAgIHJldHVybiBjdXI7DQogIH07DQp9DQoNCmZ1bmN0aW9uIHVzZU1vZGVsKHByb3BzLCBuYW1lLCBvcHRpb25zID0gRU1QVFlfT0JKKSB7DQogIGNvbnN0IGkgPSBnZXRDdXJyZW50SW5zdGFuY2UoKTsNCiAgaWYgKCFpKSB7DQogICAgd2FybiQxKGB1c2VNb2RlbCgpIGNhbGxlZCB3aXRob3V0IGFjdGl2ZSBpbnN0YW5jZS5gKTsNCiAgICByZXR1cm4gcmVmKCk7DQogIH0NCiAgY29uc3QgY2FtZWxpemVkTmFtZSA9IGNhbWVsaXplKG5hbWUpOw0KICBpZiAoIWkucHJvcHNPcHRpb25zWzBdW2NhbWVsaXplZE5hbWVdKSB7DQogICAgd2FybiQxKGB1c2VNb2RlbCgpIGNhbGxlZCB3aXRoIHByb3AgIiR7bmFtZX0iIHdoaWNoIGlzIG5vdCBkZWNsYXJlZC5gKTsNCiAgICByZXR1cm4gcmVmKCk7DQogIH0NCiAgY29uc3QgaHlwaGVuYXRlZE5hbWUgPSBoeXBoZW5hdGUobmFtZSk7DQogIGNvbnN0IG1vZGlmaWVycyA9IGdldE1vZGVsTW9kaWZpZXJzKHByb3BzLCBjYW1lbGl6ZWROYW1lKTsNCiAgY29uc3QgcmVzID0gY3VzdG9tUmVmKCh0cmFjaywgdHJpZ2dlcikgPT4gew0KICAgIGxldCBsb2NhbFZhbHVlOw0KICAgIGxldCBwcmV2U2V0VmFsdWUgPSBFTVBUWV9PQko7DQogICAgbGV0IHByZXZFbWl0dGVkVmFsdWU7DQogICAgd2F0Y2hTeW5jRWZmZWN0KCgpID0+IHsNCiAgICAgIGNvbnN0IHByb3BWYWx1ZSA9IHByb3BzW2NhbWVsaXplZE5hbWVdOw0KICAgICAgaWYgKGhhc0NoYW5nZWQobG9jYWxWYWx1ZSwgcHJvcFZhbHVlKSkgew0KICAgICAgICBsb2NhbFZhbHVlID0gcHJvcFZhbHVlOw0KICAgICAgICB0cmlnZ2VyKCk7DQogICAgICB9DQogICAgfSk7DQogICAgcmV0dXJuIHsNCiAgICAgIGdldCgpIHsNCiAgICAgICAgdHJhY2soKTsNCiAgICAgICAgcmV0dXJuIG9wdGlvbnMuZ2V0ID8gb3B0aW9ucy5nZXQobG9jYWxWYWx1ZSkgOiBsb2NhbFZhbHVlOw0KICAgICAgfSwNCiAgICAgIHNldCh2YWx1ZSkgew0KICAgICAgICBjb25zdCBlbWl0dGVkVmFsdWUgPSBvcHRpb25zLnNldCA/IG9wdGlvbnMuc2V0KHZhbHVlKSA6IHZhbHVlOw0KICAgICAgICBpZiAoIWhhc0NoYW5nZWQoZW1pdHRlZFZhbHVlLCBsb2NhbFZhbHVlKSAmJiAhKHByZXZTZXRWYWx1ZSAhPT0gRU1QVFlfT0JKICYmIGhhc0NoYW5nZWQodmFsdWUsIHByZXZTZXRWYWx1ZSkpKSB7DQogICAgICAgICAgcmV0dXJuOw0KICAgICAgICB9DQogICAgICAgIGNvbnN0IHJhd1Byb3BzID0gaS52bm9kZS5wcm9wczsNCiAgICAgICAgaWYgKCEocmF3UHJvcHMgJiYgLy8gY2hlY2sgaWYgcGFyZW50IGhhcyBwYXNzZWQgdi1tb2RlbA0KICAgICAgICAobmFtZSBpbiByYXdQcm9wcyB8fCBjYW1lbGl6ZWROYW1lIGluIHJhd1Byb3BzIHx8IGh5cGhlbmF0ZWROYW1lIGluIHJhd1Byb3BzKSAmJiAoYG9uVXBkYXRlOiR7bmFtZX1gIGluIHJhd1Byb3BzIHx8IGBvblVwZGF0ZToke2NhbWVsaXplZE5hbWV9YCBpbiByYXdQcm9wcyB8fCBgb25VcGRhdGU6JHtoeXBoZW5hdGVkTmFtZX1gIGluIHJhd1Byb3BzKSkpIHsNCiAgICAgICAgICBsb2NhbFZhbHVlID0gdmFsdWU7DQogICAgICAgICAgdHJpZ2dlcigpOw0KICAgICAgICB9DQogICAgICAgIGkuZW1pdChgdXBkYXRlOiR7bmFtZX1gLCBlbWl0dGVkVmFsdWUpOw0KICAgICAgICBpZiAoaGFzQ2hhbmdlZCh2YWx1ZSwgZW1pdHRlZFZhbHVlKSAmJiBoYXNDaGFuZ2VkKHZhbHVlLCBwcmV2U2V0VmFsdWUpICYmICFoYXNDaGFuZ2VkKGVtaXR0ZWRWYWx1ZSwgcHJldkVtaXR0ZWRWYWx1ZSkpIHsNCiAgICAgICAgICB0cmlnZ2VyKCk7DQogICAgICAgIH0NCiAgICAgICAgcHJldlNldFZhbHVlID0gdmFsdWU7DQogICAgICAgIHByZXZFbWl0dGVkVmFsdWUgPSBlbWl0dGVkVmFsdWU7DQogICAgICB9DQogICAgfTsNCiAgfSk7DQogIHJlc1tTeW1ib2wuaXRlcmF0b3JdID0gKCkgPT4gew0KICAgIGxldCBpMiA9IDA7DQogICAgcmV0dXJuIHsNCiAgICAgIG5leHQoKSB7DQogICAgICAgIGlmIChpMiA8IDIpIHsNCiAgICAgICAgICByZXR1cm4geyB2YWx1ZTogaTIrKyA/IG1vZGlmaWVycyB8fCBFTVBUWV9PQkogOiByZXMsIGRvbmU6IGZhbHNlIH07DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgcmV0dXJuIHsgZG9uZTogdHJ1ZSB9Ow0KICAgICAgICB9DQogICAgICB9DQogICAgfTsNCiAgfTsNCiAgcmV0dXJuIHJlczsNCn0NCmNvbnN0IGdldE1vZGVsTW9kaWZpZXJzID0gKHByb3BzLCBtb2RlbE5hbWUpID0+IHsNCiAgcmV0dXJuIG1vZGVsTmFtZSA9PT0gIm1vZGVsVmFsdWUiIHx8IG1vZGVsTmFtZSA9PT0gIm1vZGVsLXZhbHVlIiA/IHByb3BzLm1vZGVsTW9kaWZpZXJzIDogcHJvcHNbYCR7bW9kZWxOYW1lfU1vZGlmaWVyc2BdIHx8IHByb3BzW2Ake2NhbWVsaXplKG1vZGVsTmFtZSl9TW9kaWZpZXJzYF0gfHwgcHJvcHNbYCR7aHlwaGVuYXRlKG1vZGVsTmFtZSl9TW9kaWZpZXJzYF07DQp9Ow0KDQpmdW5jdGlvbiBlbWl0KGluc3RhbmNlLCBldmVudCwgLi4ucmF3QXJncykgew0KICBpZiAoaW5zdGFuY2UuaXNVbm1vdW50ZWQpIHJldHVybjsNCiAgY29uc3QgcHJvcHMgPSBpbnN0YW5jZS52bm9kZS5wcm9wcyB8fCBFTVBUWV9PQko7DQogIHsNCiAgICBjb25zdCB7DQogICAgICBlbWl0c09wdGlvbnMsDQogICAgICBwcm9wc09wdGlvbnM6IFtwcm9wc09wdGlvbnNdDQogICAgfSA9IGluc3RhbmNlOw0KICAgIGlmIChlbWl0c09wdGlvbnMpIHsNCiAgICAgIGlmICghKGV2ZW50IGluIGVtaXRzT3B0aW9ucykgJiYgdHJ1ZSkgew0KICAgICAgICBpZiAoIXByb3BzT3B0aW9ucyB8fCAhKHRvSGFuZGxlcktleShjYW1lbGl6ZShldmVudCkpIGluIHByb3BzT3B0aW9ucykpIHsNCiAgICAgICAgICB3YXJuJDEoDQogICAgICAgICAgICBgQ29tcG9uZW50IGVtaXR0ZWQgZXZlbnQgIiR7ZXZlbnR9IiBidXQgaXQgaXMgbmVpdGhlciBkZWNsYXJlZCBpbiB0aGUgZW1pdHMgb3B0aW9uIG5vciBhcyBhbiAiJHt0b0hhbmRsZXJLZXkoY2FtZWxpemUoZXZlbnQpKX0iIHByb3AuYA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGNvbnN0IHZhbGlkYXRvciA9IGVtaXRzT3B0aW9uc1tldmVudF07DQogICAgICAgIGlmIChpc0Z1bmN0aW9uKHZhbGlkYXRvcikpIHsNCiAgICAgICAgICBjb25zdCBpc1ZhbGlkID0gdmFsaWRhdG9yKC4uLnJhd0FyZ3MpOw0KICAgICAgICAgIGlmICghaXNWYWxpZCkgew0KICAgICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgICBgSW52YWxpZCBldmVudCBhcmd1bWVudHM6IGV2ZW50IHZhbGlkYXRpb24gZmFpbGVkIGZvciBldmVudCAiJHtldmVudH0iLmANCiAgICAgICAgICAgICk7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICB9DQogIGxldCBhcmdzID0gcmF3QXJnczsNCiAgY29uc3QgaXNNb2RlbExpc3RlbmVyID0gZXZlbnQuc3RhcnRzV2l0aCgidXBkYXRlOiIpOw0KICBjb25zdCBtb2RpZmllcnMgPSBpc01vZGVsTGlzdGVuZXIgJiYgZ2V0TW9kZWxNb2RpZmllcnMocHJvcHMsIGV2ZW50LnNsaWNlKDcpKTsNCiAgaWYgKG1vZGlmaWVycykgew0KICAgIGlmIChtb2RpZmllcnMudHJpbSkgew0KICAgICAgYXJncyA9IHJhd0FyZ3MubWFwKChhKSA9PiBpc1N0cmluZyhhKSA/IGEudHJpbSgpIDogYSk7DQogICAgfQ0KICAgIGlmIChtb2RpZmllcnMubnVtYmVyKSB7DQogICAgICBhcmdzID0gcmF3QXJncy5tYXAobG9vc2VUb051bWJlcik7DQogICAgfQ0KICB9DQogIHsNCiAgICBkZXZ0b29sc0NvbXBvbmVudEVtaXQoaW5zdGFuY2UsIGV2ZW50LCBhcmdzKTsNCiAgfQ0KICB7DQogICAgY29uc3QgbG93ZXJDYXNlRXZlbnQgPSBldmVudC50b0xvd2VyQ2FzZSgpOw0KICAgIGlmIChsb3dlckNhc2VFdmVudCAhPT0gZXZlbnQgJiYgcHJvcHNbdG9IYW5kbGVyS2V5KGxvd2VyQ2FzZUV2ZW50KV0pIHsNCiAgICAgIHdhcm4kMSgNCiAgICAgICAgYEV2ZW50ICIke2xvd2VyQ2FzZUV2ZW50fSIgaXMgZW1pdHRlZCBpbiBjb21wb25lbnQgJHtmb3JtYXRDb21wb25lbnROYW1lKA0KICAgICAgICAgIGluc3RhbmNlLA0KICAgICAgICAgIGluc3RhbmNlLnR5cGUNCiAgICAgICAgKX0gYnV0IHRoZSBoYW5kbGVyIGlzIHJlZ2lzdGVyZWQgZm9yICIke2V2ZW50fSIuIE5vdGUgdGhhdCBIVE1MIGF0dHJpYnV0ZXMgYXJlIGNhc2UtaW5zZW5zaXRpdmUgYW5kIHlvdSBjYW5ub3QgdXNlIHYtb24gdG8gbGlzdGVuIHRvIGNhbWVsQ2FzZSBldmVudHMgd2hlbiB1c2luZyBpbi1ET00gdGVtcGxhdGVzLiBZb3Ugc2hvdWxkIHByb2JhYmx5IHVzZSAiJHtoeXBoZW5hdGUoDQogICAgICAgICAgZXZlbnQNCiAgICAgICAgKX0iIGluc3RlYWQgb2YgIiR7ZXZlbnR9Ii5gDQogICAgICApOw0KICAgIH0NCiAgfQ0KICBsZXQgaGFuZGxlck5hbWU7DQogIGxldCBoYW5kbGVyID0gcHJvcHNbaGFuZGxlck5hbWUgPSB0b0hhbmRsZXJLZXkoZXZlbnQpXSB8fCAvLyBhbHNvIHRyeSBjYW1lbENhc2UgZXZlbnQgaGFuZGxlciAoIzIyNDkpDQogIHByb3BzW2hhbmRsZXJOYW1lID0gdG9IYW5kbGVyS2V5KGNhbWVsaXplKGV2ZW50KSldOw0KICBpZiAoIWhhbmRsZXIgJiYgaXNNb2RlbExpc3RlbmVyKSB7DQogICAgaGFuZGxlciA9IHByb3BzW2hhbmRsZXJOYW1lID0gdG9IYW5kbGVyS2V5KGh5cGhlbmF0ZShldmVudCkpXTsNCiAgfQ0KICBpZiAoaGFuZGxlcikgew0KICAgIGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nKA0KICAgICAgaGFuZGxlciwNCiAgICAgIGluc3RhbmNlLA0KICAgICAgNiwNCiAgICAgIGFyZ3MNCiAgICApOw0KICB9DQogIGNvbnN0IG9uY2VIYW5kbGVyID0gcHJvcHNbaGFuZGxlck5hbWUgKyBgT25jZWBdOw0KICBpZiAob25jZUhhbmRsZXIpIHsNCiAgICBpZiAoIWluc3RhbmNlLmVtaXR0ZWQpIHsNCiAgICAgIGluc3RhbmNlLmVtaXR0ZWQgPSB7fTsNCiAgICB9IGVsc2UgaWYgKGluc3RhbmNlLmVtaXR0ZWRbaGFuZGxlck5hbWVdKSB7DQogICAgICByZXR1cm47DQogICAgfQ0KICAgIGluc3RhbmNlLmVtaXR0ZWRbaGFuZGxlck5hbWVdID0gdHJ1ZTsNCiAgICBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZygNCiAgICAgIG9uY2VIYW5kbGVyLA0KICAgICAgaW5zdGFuY2UsDQogICAgICA2LA0KICAgICAgYXJncw0KICAgICk7DQogIH0NCn0NCmZ1bmN0aW9uIG5vcm1hbGl6ZUVtaXRzT3B0aW9ucyhjb21wLCBhcHBDb250ZXh0LCBhc01peGluID0gZmFsc2UpIHsNCiAgY29uc3QgY2FjaGUgPSBhcHBDb250ZXh0LmVtaXRzQ2FjaGU7DQogIGNvbnN0IGNhY2hlZCA9IGNhY2hlLmdldChjb21wKTsNCiAgaWYgKGNhY2hlZCAhPT0gdm9pZCAwKSB7DQogICAgcmV0dXJuIGNhY2hlZDsNCiAgfQ0KICBjb25zdCByYXcgPSBjb21wLmVtaXRzOw0KICBsZXQgbm9ybWFsaXplZCA9IHt9Ow0KICBsZXQgaGFzRXh0ZW5kcyA9IGZhbHNlOw0KICBpZiAoIWlzRnVuY3Rpb24oY29tcCkpIHsNCiAgICBjb25zdCBleHRlbmRFbWl0cyA9IChyYXcyKSA9PiB7DQogICAgICBjb25zdCBub3JtYWxpemVkRnJvbUV4dGVuZCA9IG5vcm1hbGl6ZUVtaXRzT3B0aW9ucyhyYXcyLCBhcHBDb250ZXh0LCB0cnVlKTsNCiAgICAgIGlmIChub3JtYWxpemVkRnJvbUV4dGVuZCkgew0KICAgICAgICBoYXNFeHRlbmRzID0gdHJ1ZTsNCiAgICAgICAgZXh0ZW5kKG5vcm1hbGl6ZWQsIG5vcm1hbGl6ZWRGcm9tRXh0ZW5kKTsNCiAgICAgIH0NCiAgICB9Ow0KICAgIGlmICghYXNNaXhpbiAmJiBhcHBDb250ZXh0Lm1peGlucy5sZW5ndGgpIHsNCiAgICAgIGFwcENvbnRleHQubWl4aW5zLmZvckVhY2goZXh0ZW5kRW1pdHMpOw0KICAgIH0NCiAgICBpZiAoY29tcC5leHRlbmRzKSB7DQogICAgICBleHRlbmRFbWl0cyhjb21wLmV4dGVuZHMpOw0KICAgIH0NCiAgICBpZiAoY29tcC5taXhpbnMpIHsNCiAgICAgIGNvbXAubWl4aW5zLmZvckVhY2goZXh0ZW5kRW1pdHMpOw0KICAgIH0NCiAgfQ0KICBpZiAoIXJhdyAmJiAhaGFzRXh0ZW5kcykgew0KICAgIGlmIChpc09iamVjdChjb21wKSkgew0KICAgICAgY2FjaGUuc2V0KGNvbXAsIG51bGwpOw0KICAgIH0NCiAgICByZXR1cm4gbnVsbDsNCiAgfQ0KICBpZiAoaXNBcnJheShyYXcpKSB7DQogICAgcmF3LmZvckVhY2goKGtleSkgPT4gbm9ybWFsaXplZFtrZXldID0gbnVsbCk7DQogIH0gZWxzZSB7DQogICAgZXh0ZW5kKG5vcm1hbGl6ZWQsIHJhdyk7DQogIH0NCiAgaWYgKGlzT2JqZWN0KGNvbXApKSB7DQogICAgY2FjaGUuc2V0KGNvbXAsIG5vcm1hbGl6ZWQpOw0KICB9DQogIHJldHVybiBub3JtYWxpemVkOw0KfQ0KZnVuY3Rpb24gaXNFbWl0TGlzdGVuZXIob3B0aW9ucywga2V5KSB7DQogIGlmICghb3B0aW9ucyB8fCAhaXNPbihrZXkpKSB7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9DQogIGtleSA9IGtleS5zbGljZSgyKS5yZXBsYWNlKC9PbmNlJC8sICIiKTsNCiAgcmV0dXJuIGhhc093bihvcHRpb25zLCBrZXlbMF0udG9Mb3dlckNhc2UoKSArIGtleS5zbGljZSgxKSkgfHwgaGFzT3duKG9wdGlvbnMsIGh5cGhlbmF0ZShrZXkpKSB8fCBoYXNPd24ob3B0aW9ucywga2V5KTsNCn0NCg0KbGV0IGFjY2Vzc2VkQXR0cnMgPSBmYWxzZTsNCmZ1bmN0aW9uIG1hcmtBdHRyc0FjY2Vzc2VkKCkgew0KICBhY2Nlc3NlZEF0dHJzID0gdHJ1ZTsNCn0NCmZ1bmN0aW9uIHJlbmRlckNvbXBvbmVudFJvb3QoaW5zdGFuY2UpIHsNCiAgY29uc3Qgew0KICAgIHR5cGU6IENvbXBvbmVudCwNCiAgICB2bm9kZSwNCiAgICBwcm94eSwNCiAgICB3aXRoUHJveHksDQogICAgcHJvcHNPcHRpb25zOiBbcHJvcHNPcHRpb25zXSwNCiAgICBzbG90cywNCiAgICBhdHRycywNCiAgICBlbWl0LA0KICAgIHJlbmRlciwNCiAgICByZW5kZXJDYWNoZSwNCiAgICBwcm9wcywNCiAgICBkYXRhLA0KICAgIHNldHVwU3RhdGUsDQogICAgY3R4LA0KICAgIGluaGVyaXRBdHRycw0KICB9ID0gaW5zdGFuY2U7DQogIGNvbnN0IHByZXYgPSBzZXRDdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UoaW5zdGFuY2UpOw0KICBsZXQgcmVzdWx0Ow0KICBsZXQgZmFsbHRocm91Z2hBdHRyczsNCiAgew0KICAgIGFjY2Vzc2VkQXR0cnMgPSBmYWxzZTsNCiAgfQ0KICB0cnkgew0KICAgIGlmICh2bm9kZS5zaGFwZUZsYWcgJiA0KSB7DQogICAgICBjb25zdCBwcm94eVRvVXNlID0gd2l0aFByb3h5IHx8IHByb3h5Ow0KICAgICAgY29uc3QgdGhpc1Byb3h5ID0gc2V0dXBTdGF0ZS5fX2lzU2NyaXB0U2V0dXAgPyBuZXcgUHJveHkocHJveHlUb1VzZSwgew0KICAgICAgICBnZXQodGFyZ2V0LCBrZXksIHJlY2VpdmVyKSB7DQogICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgYFByb3BlcnR5ICcke1N0cmluZygNCiAgICAgICAgICAgICAga2V5DQogICAgICAgICAgICApfScgd2FzIGFjY2Vzc2VkIHZpYSAndGhpcycuIEF2b2lkIHVzaW5nICd0aGlzJyBpbiB0ZW1wbGF0ZXMuYA0KICAgICAgICAgICk7DQogICAgICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0KHRhcmdldCwga2V5LCByZWNlaXZlcik7DQogICAgICAgIH0NCiAgICAgIH0pIDogcHJveHlUb1VzZTsNCiAgICAgIHJlc3VsdCA9IG5vcm1hbGl6ZVZOb2RlKA0KICAgICAgICByZW5kZXIuY2FsbCgNCiAgICAgICAgICB0aGlzUHJveHksDQogICAgICAgICAgcHJveHlUb1VzZSwNCiAgICAgICAgICByZW5kZXJDYWNoZSwNCiAgICAgICAgICB0cnVlID8gc2hhbGxvd1JlYWRvbmx5KHByb3BzKSA6IHByb3BzLA0KICAgICAgICAgIHNldHVwU3RhdGUsDQogICAgICAgICAgZGF0YSwNCiAgICAgICAgICBjdHgNCiAgICAgICAgKQ0KICAgICAgKTsNCiAgICAgIGZhbGx0aHJvdWdoQXR0cnMgPSBhdHRyczsNCiAgICB9IGVsc2Ugew0KICAgICAgY29uc3QgcmVuZGVyMiA9IENvbXBvbmVudDsNCiAgICAgIGlmIChhdHRycyA9PT0gcHJvcHMpIHsNCiAgICAgICAgbWFya0F0dHJzQWNjZXNzZWQoKTsNCiAgICAgIH0NCiAgICAgIHJlc3VsdCA9IG5vcm1hbGl6ZVZOb2RlKA0KICAgICAgICByZW5kZXIyLmxlbmd0aCA+IDEgPyByZW5kZXIyKA0KICAgICAgICAgIHRydWUgPyBzaGFsbG93UmVhZG9ubHkocHJvcHMpIDogcHJvcHMsDQogICAgICAgICAgdHJ1ZSA/IHsNCiAgICAgICAgICAgIGdldCBhdHRycygpIHsNCiAgICAgICAgICAgICAgbWFya0F0dHJzQWNjZXNzZWQoKTsNCiAgICAgICAgICAgICAgcmV0dXJuIHNoYWxsb3dSZWFkb25seShhdHRycyk7DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgc2xvdHMsDQogICAgICAgICAgICBlbWl0DQogICAgICAgICAgfSA6IHsgYXR0cnMsIHNsb3RzLCBlbWl0IH0NCiAgICAgICAgKSA6IHJlbmRlcjIoDQogICAgICAgICAgdHJ1ZSA/IHNoYWxsb3dSZWFkb25seShwcm9wcykgOiBwcm9wcywNCiAgICAgICAgICBudWxsDQogICAgICAgICkNCiAgICAgICk7DQogICAgICBmYWxsdGhyb3VnaEF0dHJzID0gQ29tcG9uZW50LnByb3BzID8gYXR0cnMgOiBnZXRGdW5jdGlvbmFsRmFsbHRocm91Z2goYXR0cnMpOw0KICAgIH0NCiAgfSBjYXRjaCAoZXJyKSB7DQogICAgYmxvY2tTdGFjay5sZW5ndGggPSAwOw0KICAgIGhhbmRsZUVycm9yKGVyciwgaW5zdGFuY2UsIDEpOw0KICAgIHJlc3VsdCA9IGNyZWF0ZVZOb2RlKENvbW1lbnQpOw0KICB9DQogIGxldCByb290ID0gcmVzdWx0Ow0KICBsZXQgc2V0Um9vdCA9IHZvaWQgMDsNCiAgaWYgKHJlc3VsdC5wYXRjaEZsYWcgPiAwICYmIHJlc3VsdC5wYXRjaEZsYWcgJiAyMDQ4KSB7DQogICAgW3Jvb3QsIHNldFJvb3RdID0gZ2V0Q2hpbGRSb290KHJlc3VsdCk7DQogIH0NCiAgaWYgKGZhbGx0aHJvdWdoQXR0cnMgJiYgaW5oZXJpdEF0dHJzICE9PSBmYWxzZSkgew0KICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhmYWxsdGhyb3VnaEF0dHJzKTsNCiAgICBjb25zdCB7IHNoYXBlRmxhZyB9ID0gcm9vdDsNCiAgICBpZiAoa2V5cy5sZW5ndGgpIHsNCiAgICAgIGlmIChzaGFwZUZsYWcgJiAoMSB8IDYpKSB7DQogICAgICAgIGlmIChwcm9wc09wdGlvbnMgJiYga2V5cy5zb21lKGlzTW9kZWxMaXN0ZW5lcikpIHsNCiAgICAgICAgICBmYWxsdGhyb3VnaEF0dHJzID0gZmlsdGVyTW9kZWxMaXN0ZW5lcnMoDQogICAgICAgICAgICBmYWxsdGhyb3VnaEF0dHJzLA0KICAgICAgICAgICAgcHJvcHNPcHRpb25zDQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgICByb290ID0gY2xvbmVWTm9kZShyb290LCBmYWxsdGhyb3VnaEF0dHJzLCBmYWxzZSwgdHJ1ZSk7DQogICAgICB9IGVsc2UgaWYgKCFhY2Nlc3NlZEF0dHJzICYmIHJvb3QudHlwZSAhPT0gQ29tbWVudCkgew0KICAgICAgICBjb25zdCBhbGxBdHRycyA9IE9iamVjdC5rZXlzKGF0dHJzKTsNCiAgICAgICAgY29uc3QgZXZlbnRBdHRycyA9IFtdOw0KICAgICAgICBjb25zdCBleHRyYUF0dHJzID0gW107DQogICAgICAgIGZvciAobGV0IGkgPSAwLCBsID0gYWxsQXR0cnMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7DQogICAgICAgICAgY29uc3Qga2V5ID0gYWxsQXR0cnNbaV07DQogICAgICAgICAgaWYgKGlzT24oa2V5KSkgew0KICAgICAgICAgICAgaWYgKCFpc01vZGVsTGlzdGVuZXIoa2V5KSkgew0KICAgICAgICAgICAgICBldmVudEF0dHJzLnB1c2goa2V5WzJdLnRvTG93ZXJDYXNlKCkgKyBrZXkuc2xpY2UoMykpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBleHRyYUF0dHJzLnB1c2goa2V5KTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgaWYgKGV4dHJhQXR0cnMubGVuZ3RoKSB7DQogICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgYEV4dHJhbmVvdXMgbm9uLXByb3BzIGF0dHJpYnV0ZXMgKCR7ZXh0cmFBdHRycy5qb2luKCIsICIpfSkgd2VyZSBwYXNzZWQgdG8gY29tcG9uZW50IGJ1dCBjb3VsZCBub3QgYmUgYXV0b21hdGljYWxseSBpbmhlcml0ZWQgYmVjYXVzZSBjb21wb25lbnQgcmVuZGVycyBmcmFnbWVudCBvciB0ZXh0IG9yIHRlbGVwb3J0IHJvb3Qgbm9kZXMuYA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKGV2ZW50QXR0cnMubGVuZ3RoKSB7DQogICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgYEV4dHJhbmVvdXMgbm9uLWVtaXRzIGV2ZW50IGxpc3RlbmVycyAoJHtldmVudEF0dHJzLmpvaW4oIiwgIil9KSB3ZXJlIHBhc3NlZCB0byBjb21wb25lbnQgYnV0IGNvdWxkIG5vdCBiZSBhdXRvbWF0aWNhbGx5IGluaGVyaXRlZCBiZWNhdXNlIGNvbXBvbmVudCByZW5kZXJzIGZyYWdtZW50IG9yIHRleHQgcm9vdCBub2Rlcy4gSWYgdGhlIGxpc3RlbmVyIGlzIGludGVuZGVkIHRvIGJlIGEgY29tcG9uZW50IGN1c3RvbSBldmVudCBsaXN0ZW5lciBvbmx5LCBkZWNsYXJlIGl0IHVzaW5nIHRoZSAiZW1pdHMiIG9wdGlvbi5gDQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICBpZiAodm5vZGUuZGlycykgew0KICAgIGlmICghaXNFbGVtZW50Um9vdChyb290KSkgew0KICAgICAgd2FybiQxKA0KICAgICAgICBgUnVudGltZSBkaXJlY3RpdmUgdXNlZCBvbiBjb21wb25lbnQgd2l0aCBub24tZWxlbWVudCByb290IG5vZGUuIFRoZSBkaXJlY3RpdmVzIHdpbGwgbm90IGZ1bmN0aW9uIGFzIGludGVuZGVkLmANCiAgICAgICk7DQogICAgfQ0KICAgIHJvb3QgPSBjbG9uZVZOb2RlKHJvb3QsIG51bGwsIGZhbHNlLCB0cnVlKTsNCiAgICByb290LmRpcnMgPSByb290LmRpcnMgPyByb290LmRpcnMuY29uY2F0KHZub2RlLmRpcnMpIDogdm5vZGUuZGlyczsNCiAgfQ0KICBpZiAodm5vZGUudHJhbnNpdGlvbikgew0KICAgIGlmICghaXNFbGVtZW50Um9vdChyb290KSkgew0KICAgICAgd2FybiQxKA0KICAgICAgICBgQ29tcG9uZW50IGluc2lkZSA8VHJhbnNpdGlvbj4gcmVuZGVycyBub24tZWxlbWVudCByb290IG5vZGUgdGhhdCBjYW5ub3QgYmUgYW5pbWF0ZWQuYA0KICAgICAgKTsNCiAgICB9DQogICAgc2V0VHJhbnNpdGlvbkhvb2tzKHJvb3QsIHZub2RlLnRyYW5zaXRpb24pOw0KICB9DQogIGlmIChzZXRSb290KSB7DQogICAgc2V0Um9vdChyb290KTsNCiAgfSBlbHNlIHsNCiAgICByZXN1bHQgPSByb290Ow0KICB9DQogIHNldEN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZShwcmV2KTsNCiAgcmV0dXJuIHJlc3VsdDsNCn0NCmNvbnN0IGdldENoaWxkUm9vdCA9ICh2bm9kZSkgPT4gew0KICBjb25zdCByYXdDaGlsZHJlbiA9IHZub2RlLmNoaWxkcmVuOw0KICBjb25zdCBkeW5hbWljQ2hpbGRyZW4gPSB2bm9kZS5keW5hbWljQ2hpbGRyZW47DQogIGNvbnN0IGNoaWxkUm9vdCA9IGZpbHRlclNpbmdsZVJvb3QocmF3Q2hpbGRyZW4sIGZhbHNlKTsNCiAgaWYgKCFjaGlsZFJvb3QpIHsNCiAgICByZXR1cm4gW3Zub2RlLCB2b2lkIDBdOw0KICB9IGVsc2UgaWYgKGNoaWxkUm9vdC5wYXRjaEZsYWcgPiAwICYmIGNoaWxkUm9vdC5wYXRjaEZsYWcgJiAyMDQ4KSB7DQogICAgcmV0dXJuIGdldENoaWxkUm9vdChjaGlsZFJvb3QpOw0KICB9DQogIGNvbnN0IGluZGV4ID0gcmF3Q2hpbGRyZW4uaW5kZXhPZihjaGlsZFJvb3QpOw0KICBjb25zdCBkeW5hbWljSW5kZXggPSBkeW5hbWljQ2hpbGRyZW4gPyBkeW5hbWljQ2hpbGRyZW4uaW5kZXhPZihjaGlsZFJvb3QpIDogLTE7DQogIGNvbnN0IHNldFJvb3QgPSAodXBkYXRlZFJvb3QpID0+IHsNCiAgICByYXdDaGlsZHJlbltpbmRleF0gPSB1cGRhdGVkUm9vdDsNCiAgICBpZiAoZHluYW1pY0NoaWxkcmVuKSB7DQogICAgICBpZiAoZHluYW1pY0luZGV4ID4gLTEpIHsNCiAgICAgICAgZHluYW1pY0NoaWxkcmVuW2R5bmFtaWNJbmRleF0gPSB1cGRhdGVkUm9vdDsNCiAgICAgIH0gZWxzZSBpZiAodXBkYXRlZFJvb3QucGF0Y2hGbGFnID4gMCkgew0KICAgICAgICB2bm9kZS5keW5hbWljQ2hpbGRyZW4gPSBbLi4uZHluYW1pY0NoaWxkcmVuLCB1cGRhdGVkUm9vdF07DQogICAgICB9DQogICAgfQ0KICB9Ow0KICByZXR1cm4gW25vcm1hbGl6ZVZOb2RlKGNoaWxkUm9vdCksIHNldFJvb3RdOw0KfTsNCmZ1bmN0aW9uIGZpbHRlclNpbmdsZVJvb3QoY2hpbGRyZW4sIHJlY3Vyc2UgPSB0cnVlKSB7DQogIGxldCBzaW5nbGVSb290Ow0KICBmb3IgKGxldCBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7DQogICAgY29uc3QgY2hpbGQgPSBjaGlsZHJlbltpXTsNCiAgICBpZiAoaXNWTm9kZShjaGlsZCkpIHsNCiAgICAgIGlmIChjaGlsZC50eXBlICE9PSBDb21tZW50IHx8IGNoaWxkLmNoaWxkcmVuID09PSAidi1pZiIpIHsNCiAgICAgICAgaWYgKHNpbmdsZVJvb3QpIHsNCiAgICAgICAgICByZXR1cm47DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgc2luZ2xlUm9vdCA9IGNoaWxkOw0KICAgICAgICAgIGlmIChyZWN1cnNlICYmIHNpbmdsZVJvb3QucGF0Y2hGbGFnID4gMCAmJiBzaW5nbGVSb290LnBhdGNoRmxhZyAmIDIwNDgpIHsNCiAgICAgICAgICAgIHJldHVybiBmaWx0ZXJTaW5nbGVSb290KHNpbmdsZVJvb3QuY2hpbGRyZW4pOw0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0gZWxzZSB7DQogICAgICByZXR1cm47DQogICAgfQ0KICB9DQogIHJldHVybiBzaW5nbGVSb290Ow0KfQ0KY29uc3QgZ2V0RnVuY3Rpb25hbEZhbGx0aHJvdWdoID0gKGF0dHJzKSA9PiB7DQogIGxldCByZXM7DQogIGZvciAoY29uc3Qga2V5IGluIGF0dHJzKSB7DQogICAgaWYgKGtleSA9PT0gImNsYXNzIiB8fCBrZXkgPT09ICJzdHlsZSIgfHwgaXNPbihrZXkpKSB7DQogICAgICAocmVzIHx8IChyZXMgPSB7fSkpW2tleV0gPSBhdHRyc1trZXldOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gcmVzOw0KfTsNCmNvbnN0IGZpbHRlck1vZGVsTGlzdGVuZXJzID0gKGF0dHJzLCBwcm9wcykgPT4gew0KICBjb25zdCByZXMgPSB7fTsNCiAgZm9yIChjb25zdCBrZXkgaW4gYXR0cnMpIHsNCiAgICBpZiAoIWlzTW9kZWxMaXN0ZW5lcihrZXkpIHx8ICEoa2V5LnNsaWNlKDkpIGluIHByb3BzKSkgew0KICAgICAgcmVzW2tleV0gPSBhdHRyc1trZXldOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gcmVzOw0KfTsNCmNvbnN0IGlzRWxlbWVudFJvb3QgPSAodm5vZGUpID0+IHsNCiAgcmV0dXJuIHZub2RlLnNoYXBlRmxhZyAmICg2IHwgMSkgfHwgdm5vZGUudHlwZSA9PT0gQ29tbWVudDsNCn07DQpmdW5jdGlvbiBzaG91bGRVcGRhdGVDb21wb25lbnQocHJldlZOb2RlLCBuZXh0Vk5vZGUsIG9wdGltaXplZCkgew0KICBjb25zdCB7IHByb3BzOiBwcmV2UHJvcHMsIGNoaWxkcmVuOiBwcmV2Q2hpbGRyZW4sIGNvbXBvbmVudCB9ID0gcHJldlZOb2RlOw0KICBjb25zdCB7IHByb3BzOiBuZXh0UHJvcHMsIGNoaWxkcmVuOiBuZXh0Q2hpbGRyZW4sIHBhdGNoRmxhZyB9ID0gbmV4dFZOb2RlOw0KICBjb25zdCBlbWl0cyA9IGNvbXBvbmVudC5lbWl0c09wdGlvbnM7DQogIGlmICgocHJldkNoaWxkcmVuIHx8IG5leHRDaGlsZHJlbikgJiYgaXNIbXJVcGRhdGluZykgew0KICAgIHJldHVybiB0cnVlOw0KICB9DQogIGlmIChuZXh0Vk5vZGUuZGlycyB8fCBuZXh0Vk5vZGUudHJhbnNpdGlvbikgew0KICAgIHJldHVybiB0cnVlOw0KICB9DQogIGlmIChvcHRpbWl6ZWQgJiYgcGF0Y2hGbGFnID49IDApIHsNCiAgICBpZiAocGF0Y2hGbGFnICYgMTAyNCkgew0KICAgICAgcmV0dXJuIHRydWU7DQogICAgfQ0KICAgIGlmIChwYXRjaEZsYWcgJiAxNikgew0KICAgICAgaWYgKCFwcmV2UHJvcHMpIHsNCiAgICAgICAgcmV0dXJuICEhbmV4dFByb3BzOw0KICAgICAgfQ0KICAgICAgcmV0dXJuIGhhc1Byb3BzQ2hhbmdlZChwcmV2UHJvcHMsIG5leHRQcm9wcywgZW1pdHMpOw0KICAgIH0gZWxzZSBpZiAocGF0Y2hGbGFnICYgOCkgew0KICAgICAgY29uc3QgZHluYW1pY1Byb3BzID0gbmV4dFZOb2RlLmR5bmFtaWNQcm9wczsNCiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZHluYW1pY1Byb3BzLmxlbmd0aDsgaSsrKSB7DQogICAgICAgIGNvbnN0IGtleSA9IGR5bmFtaWNQcm9wc1tpXTsNCiAgICAgICAgaWYgKG5leHRQcm9wc1trZXldICE9PSBwcmV2UHJvcHNba2V5XSAmJiAhaXNFbWl0TGlzdGVuZXIoZW1pdHMsIGtleSkpIHsNCiAgICAgICAgICByZXR1cm4gdHJ1ZTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICBpZiAocHJldkNoaWxkcmVuIHx8IG5leHRDaGlsZHJlbikgew0KICAgICAgaWYgKCFuZXh0Q2hpbGRyZW4gfHwgIW5leHRDaGlsZHJlbi4kc3RhYmxlKSB7DQogICAgICAgIHJldHVybiB0cnVlOw0KICAgICAgfQ0KICAgIH0NCiAgICBpZiAocHJldlByb3BzID09PSBuZXh0UHJvcHMpIHsNCiAgICAgIHJldHVybiBmYWxzZTsNCiAgICB9DQogICAgaWYgKCFwcmV2UHJvcHMpIHsNCiAgICAgIHJldHVybiAhIW5leHRQcm9wczsNCiAgICB9DQogICAgaWYgKCFuZXh0UHJvcHMpIHsNCiAgICAgIHJldHVybiB0cnVlOw0KICAgIH0NCiAgICByZXR1cm4gaGFzUHJvcHNDaGFuZ2VkKHByZXZQcm9wcywgbmV4dFByb3BzLCBlbWl0cyk7DQogIH0NCiAgcmV0dXJuIGZhbHNlOw0KfQ0KZnVuY3Rpb24gaGFzUHJvcHNDaGFuZ2VkKHByZXZQcm9wcywgbmV4dFByb3BzLCBlbWl0c09wdGlvbnMpIHsNCiAgY29uc3QgbmV4dEtleXMgPSBPYmplY3Qua2V5cyhuZXh0UHJvcHMpOw0KICBpZiAobmV4dEtleXMubGVuZ3RoICE9PSBPYmplY3Qua2V5cyhwcmV2UHJvcHMpLmxlbmd0aCkgew0KICAgIHJldHVybiB0cnVlOw0KICB9DQogIGZvciAobGV0IGkgPSAwOyBpIDwgbmV4dEtleXMubGVuZ3RoOyBpKyspIHsNCiAgICBjb25zdCBrZXkgPSBuZXh0S2V5c1tpXTsNCiAgICBpZiAobmV4dFByb3BzW2tleV0gIT09IHByZXZQcm9wc1trZXldICYmICFpc0VtaXRMaXN0ZW5lcihlbWl0c09wdGlvbnMsIGtleSkpIHsNCiAgICAgIHJldHVybiB0cnVlOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gZmFsc2U7DQp9DQpmdW5jdGlvbiB1cGRhdGVIT0NIb3N0RWwoeyB2bm9kZSwgcGFyZW50IH0sIGVsKSB7DQogIHdoaWxlIChwYXJlbnQpIHsNCiAgICBjb25zdCByb290ID0gcGFyZW50LnN1YlRyZWU7DQogICAgaWYgKHJvb3Quc3VzcGVuc2UgJiYgcm9vdC5zdXNwZW5zZS5hY3RpdmVCcmFuY2ggPT09IHZub2RlKSB7DQogICAgICByb290LmVsID0gdm5vZGUuZWw7DQogICAgfQ0KICAgIGlmIChyb290ID09PSB2bm9kZSkgew0KICAgICAgKHZub2RlID0gcGFyZW50LnZub2RlKS5lbCA9IGVsOw0KICAgICAgcGFyZW50ID0gcGFyZW50LnBhcmVudDsNCiAgICB9IGVsc2Ugew0KICAgICAgYnJlYWs7DQogICAgfQ0KICB9DQp9DQoNCmNvbnN0IGlzU3VzcGVuc2UgPSAodHlwZSkgPT4gdHlwZS5fX2lzU3VzcGVuc2U7DQpsZXQgc3VzcGVuc2VJZCA9IDA7DQpjb25zdCBTdXNwZW5zZUltcGwgPSB7DQogIG5hbWU6ICJTdXNwZW5zZSIsDQogIC8vIEluIG9yZGVyIHRvIG1ha2UgU3VzcGVuc2UgdHJlZS1zaGFrYWJsZSwgd2UgbmVlZCB0byBhdm9pZCBpbXBvcnRpbmcgaXQNCiAgLy8gZGlyZWN0bHkgaW4gdGhlIHJlbmRlcmVyLiBUaGUgcmVuZGVyZXIgY2hlY2tzIGZvciB0aGUgX19pc1N1c3BlbnNlIGZsYWcNCiAgLy8gb24gYSB2bm9kZSdzIHR5cGUgYW5kIGNhbGxzIHRoZSBgcHJvY2Vzc2AgbWV0aG9kLCBwYXNzaW5nIGluIHJlbmRlcmVyDQogIC8vIGludGVybmFscy4NCiAgX19pc1N1c3BlbnNlOiB0cnVlLA0KICBwcm9jZXNzKG4xLCBuMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQsIHJlbmRlcmVySW50ZXJuYWxzKSB7DQogICAgaWYgKG4xID09IG51bGwpIHsNCiAgICAgIG1vdW50U3VzcGVuc2UoDQogICAgICAgIG4yLA0KICAgICAgICBjb250YWluZXIsDQogICAgICAgIGFuY2hvciwNCiAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgIG9wdGltaXplZCwNCiAgICAgICAgcmVuZGVyZXJJbnRlcm5hbHMNCiAgICAgICk7DQogICAgfSBlbHNlIHsNCiAgICAgIGlmIChwYXJlbnRTdXNwZW5zZSAmJiBwYXJlbnRTdXNwZW5zZS5kZXBzID4gMCAmJiAhbjEuc3VzcGVuc2UuaXNJbkZhbGxiYWNrKSB7DQogICAgICAgIG4yLnN1c3BlbnNlID0gbjEuc3VzcGVuc2U7DQogICAgICAgIG4yLnN1c3BlbnNlLnZub2RlID0gbjI7DQogICAgICAgIG4yLmVsID0gbjEuZWw7DQogICAgICAgIHJldHVybjsNCiAgICAgIH0NCiAgICAgIHBhdGNoU3VzcGVuc2UoDQogICAgICAgIG4xLA0KICAgICAgICBuMiwNCiAgICAgICAgY29udGFpbmVyLA0KICAgICAgICBhbmNob3IsDQogICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgIG9wdGltaXplZCwNCiAgICAgICAgcmVuZGVyZXJJbnRlcm5hbHMNCiAgICAgICk7DQogICAgfQ0KICB9LA0KICBoeWRyYXRlOiBoeWRyYXRlU3VzcGVuc2UsDQogIG5vcm1hbGl6ZTogbm9ybWFsaXplU3VzcGVuc2VDaGlsZHJlbg0KfTsNCmNvbnN0IFN1c3BlbnNlID0gU3VzcGVuc2VJbXBsIDsNCmZ1bmN0aW9uIHRyaWdnZXJFdmVudCh2bm9kZSwgbmFtZSkgew0KICBjb25zdCBldmVudExpc3RlbmVyID0gdm5vZGUucHJvcHMgJiYgdm5vZGUucHJvcHNbbmFtZV07DQogIGlmIChpc0Z1bmN0aW9uKGV2ZW50TGlzdGVuZXIpKSB7DQogICAgZXZlbnRMaXN0ZW5lcigpOw0KICB9DQp9DQpmdW5jdGlvbiBtb3VudFN1c3BlbnNlKHZub2RlLCBjb250YWluZXIsIGFuY2hvciwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgbmFtZXNwYWNlLCBzbG90U2NvcGVJZHMsIG9wdGltaXplZCwgcmVuZGVyZXJJbnRlcm5hbHMpIHsNCiAgY29uc3Qgew0KICAgIHA6IHBhdGNoLA0KICAgIG86IHsgY3JlYXRlRWxlbWVudCB9DQogIH0gPSByZW5kZXJlckludGVybmFsczsNCiAgY29uc3QgaGlkZGVuQ29udGFpbmVyID0gY3JlYXRlRWxlbWVudCgiZGl2Iik7DQogIGNvbnN0IHN1c3BlbnNlID0gdm5vZGUuc3VzcGVuc2UgPSBjcmVhdGVTdXNwZW5zZUJvdW5kYXJ5KA0KICAgIHZub2RlLA0KICAgIHBhcmVudFN1c3BlbnNlLA0KICAgIHBhcmVudENvbXBvbmVudCwNCiAgICBjb250YWluZXIsDQogICAgaGlkZGVuQ29udGFpbmVyLA0KICAgIGFuY2hvciwNCiAgICBuYW1lc3BhY2UsDQogICAgc2xvdFNjb3BlSWRzLA0KICAgIG9wdGltaXplZCwNCiAgICByZW5kZXJlckludGVybmFscw0KICApOw0KICBwYXRjaCgNCiAgICBudWxsLA0KICAgIHN1c3BlbnNlLnBlbmRpbmdCcmFuY2ggPSB2bm9kZS5zc0NvbnRlbnQsDQogICAgaGlkZGVuQ29udGFpbmVyLA0KICAgIG51bGwsDQogICAgcGFyZW50Q29tcG9uZW50LA0KICAgIHN1c3BlbnNlLA0KICAgIG5hbWVzcGFjZSwNCiAgICBzbG90U2NvcGVJZHMNCiAgKTsNCiAgaWYgKHN1c3BlbnNlLmRlcHMgPiAwKSB7DQogICAgdHJpZ2dlckV2ZW50KHZub2RlLCAib25QZW5kaW5nIik7DQogICAgdHJpZ2dlckV2ZW50KHZub2RlLCAib25GYWxsYmFjayIpOw0KICAgIHBhdGNoKA0KICAgICAgbnVsbCwNCiAgICAgIHZub2RlLnNzRmFsbGJhY2ssDQogICAgICBjb250YWluZXIsDQogICAgICBhbmNob3IsDQogICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICBudWxsLA0KICAgICAgLy8gZmFsbGJhY2sgdHJlZSB3aWxsIG5vdCBoYXZlIHN1c3BlbnNlIGNvbnRleHQNCiAgICAgIG5hbWVzcGFjZSwNCiAgICAgIHNsb3RTY29wZUlkcw0KICAgICk7DQogICAgc2V0QWN0aXZlQnJhbmNoKHN1c3BlbnNlLCB2bm9kZS5zc0ZhbGxiYWNrKTsNCiAgfSBlbHNlIHsNCiAgICBzdXNwZW5zZS5yZXNvbHZlKGZhbHNlLCB0cnVlKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gcGF0Y2hTdXNwZW5zZShuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQsIHsgcDogcGF0Y2gsIHVtOiB1bm1vdW50LCBvOiB7IGNyZWF0ZUVsZW1lbnQgfSB9KSB7DQogIGNvbnN0IHN1c3BlbnNlID0gbjIuc3VzcGVuc2UgPSBuMS5zdXNwZW5zZTsNCiAgc3VzcGVuc2Uudm5vZGUgPSBuMjsNCiAgbjIuZWwgPSBuMS5lbDsNCiAgY29uc3QgbmV3QnJhbmNoID0gbjIuc3NDb250ZW50Ow0KICBjb25zdCBuZXdGYWxsYmFjayA9IG4yLnNzRmFsbGJhY2s7DQogIGNvbnN0IHsgYWN0aXZlQnJhbmNoLCBwZW5kaW5nQnJhbmNoLCBpc0luRmFsbGJhY2ssIGlzSHlkcmF0aW5nIH0gPSBzdXNwZW5zZTsNCiAgaWYgKHBlbmRpbmdCcmFuY2gpIHsNCiAgICBzdXNwZW5zZS5wZW5kaW5nQnJhbmNoID0gbmV3QnJhbmNoOw0KICAgIGlmIChpc1NhbWVWTm9kZVR5cGUobmV3QnJhbmNoLCBwZW5kaW5nQnJhbmNoKSkgew0KICAgICAgcGF0Y2goDQogICAgICAgIHBlbmRpbmdCcmFuY2gsDQogICAgICAgIG5ld0JyYW5jaCwNCiAgICAgICAgc3VzcGVuc2UuaGlkZGVuQ29udGFpbmVyLA0KICAgICAgICBudWxsLA0KICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgIHN1c3BlbnNlLA0KICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgb3B0aW1pemVkDQogICAgICApOw0KICAgICAgaWYgKHN1c3BlbnNlLmRlcHMgPD0gMCkgew0KICAgICAgICBzdXNwZW5zZS5yZXNvbHZlKCk7DQogICAgICB9IGVsc2UgaWYgKGlzSW5GYWxsYmFjaykgew0KICAgICAgICBpZiAoIWlzSHlkcmF0aW5nKSB7DQogICAgICAgICAgcGF0Y2goDQogICAgICAgICAgICBhY3RpdmVCcmFuY2gsDQogICAgICAgICAgICBuZXdGYWxsYmFjaywNCiAgICAgICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgICAgIGFuY2hvciwNCiAgICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICAgIG51bGwsDQogICAgICAgICAgICAvLyBmYWxsYmFjayB0cmVlIHdpbGwgbm90IGhhdmUgc3VzcGVuc2UgY29udGV4dA0KICAgICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICAgKTsNCiAgICAgICAgICBzZXRBY3RpdmVCcmFuY2goc3VzcGVuc2UsIG5ld0ZhbGxiYWNrKTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0gZWxzZSB7DQogICAgICBzdXNwZW5zZS5wZW5kaW5nSWQgPSBzdXNwZW5zZUlkKys7DQogICAgICBpZiAoaXNIeWRyYXRpbmcpIHsNCiAgICAgICAgc3VzcGVuc2UuaXNIeWRyYXRpbmcgPSBmYWxzZTsNCiAgICAgICAgc3VzcGVuc2UuYWN0aXZlQnJhbmNoID0gcGVuZGluZ0JyYW5jaDsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHVubW91bnQocGVuZGluZ0JyYW5jaCwgcGFyZW50Q29tcG9uZW50LCBzdXNwZW5zZSk7DQogICAgICB9DQogICAgICBzdXNwZW5zZS5kZXBzID0gMDsNCiAgICAgIHN1c3BlbnNlLmVmZmVjdHMubGVuZ3RoID0gMDsNCiAgICAgIHN1c3BlbnNlLmhpZGRlbkNvbnRhaW5lciA9IGNyZWF0ZUVsZW1lbnQoImRpdiIpOw0KICAgICAgaWYgKGlzSW5GYWxsYmFjaykgew0KICAgICAgICBwYXRjaCgNCiAgICAgICAgICBudWxsLA0KICAgICAgICAgIG5ld0JyYW5jaCwNCiAgICAgICAgICBzdXNwZW5zZS5oaWRkZW5Db250YWluZXIsDQogICAgICAgICAgbnVsbCwNCiAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgc3VzcGVuc2UsDQogICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgKTsNCiAgICAgICAgaWYgKHN1c3BlbnNlLmRlcHMgPD0gMCkgew0KICAgICAgICAgIHN1c3BlbnNlLnJlc29sdmUoKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBwYXRjaCgNCiAgICAgICAgICAgIGFjdGl2ZUJyYW5jaCwNCiAgICAgICAgICAgIG5ld0ZhbGxiYWNrLA0KICAgICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgbnVsbCwNCiAgICAgICAgICAgIC8vIGZhbGxiYWNrIHRyZWUgd2lsbCBub3QgaGF2ZSBzdXNwZW5zZSBjb250ZXh0DQogICAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgICApOw0KICAgICAgICAgIHNldEFjdGl2ZUJyYW5jaChzdXNwZW5zZSwgbmV3RmFsbGJhY2spOw0KICAgICAgICB9DQogICAgICB9IGVsc2UgaWYgKGFjdGl2ZUJyYW5jaCAmJiBpc1NhbWVWTm9kZVR5cGUobmV3QnJhbmNoLCBhY3RpdmVCcmFuY2gpKSB7DQogICAgICAgIHBhdGNoKA0KICAgICAgICAgIGFjdGl2ZUJyYW5jaCwNCiAgICAgICAgICBuZXdCcmFuY2gsDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIGFuY2hvciwNCiAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgc3VzcGVuc2UsDQogICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgKTsNCiAgICAgICAgc3VzcGVuc2UucmVzb2x2ZSh0cnVlKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHBhdGNoKA0KICAgICAgICAgIG51bGwsDQogICAgICAgICAgbmV3QnJhbmNoLA0KICAgICAgICAgIHN1c3BlbnNlLmhpZGRlbkNvbnRhaW5lciwNCiAgICAgICAgICBudWxsLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBzdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICApOw0KICAgICAgICBpZiAoc3VzcGVuc2UuZGVwcyA8PSAwKSB7DQogICAgICAgICAgc3VzcGVuc2UucmVzb2x2ZSgpOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICB9IGVsc2Ugew0KICAgIGlmIChhY3RpdmVCcmFuY2ggJiYgaXNTYW1lVk5vZGVUeXBlKG5ld0JyYW5jaCwgYWN0aXZlQnJhbmNoKSkgew0KICAgICAgcGF0Y2goDQogICAgICAgIGFjdGl2ZUJyYW5jaCwNCiAgICAgICAgbmV3QnJhbmNoLA0KICAgICAgICBjb250YWluZXIsDQogICAgICAgIGFuY2hvciwNCiAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICBzdXNwZW5zZSwNCiAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgIG9wdGltaXplZA0KICAgICAgKTsNCiAgICAgIHNldEFjdGl2ZUJyYW5jaChzdXNwZW5zZSwgbmV3QnJhbmNoKTsNCiAgICB9IGVsc2Ugew0KICAgICAgdHJpZ2dlckV2ZW50KG4yLCAib25QZW5kaW5nIik7DQogICAgICBzdXNwZW5zZS5wZW5kaW5nQnJhbmNoID0gbmV3QnJhbmNoOw0KICAgICAgaWYgKG5ld0JyYW5jaC5zaGFwZUZsYWcgJiA1MTIpIHsNCiAgICAgICAgc3VzcGVuc2UucGVuZGluZ0lkID0gbmV3QnJhbmNoLmNvbXBvbmVudC5zdXNwZW5zZUlkOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgc3VzcGVuc2UucGVuZGluZ0lkID0gc3VzcGVuc2VJZCsrOw0KICAgICAgfQ0KICAgICAgcGF0Y2goDQogICAgICAgIG51bGwsDQogICAgICAgIG5ld0JyYW5jaCwNCiAgICAgICAgc3VzcGVuc2UuaGlkZGVuQ29udGFpbmVyLA0KICAgICAgICBudWxsLA0KICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgIHN1c3BlbnNlLA0KICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgb3B0aW1pemVkDQogICAgICApOw0KICAgICAgaWYgKHN1c3BlbnNlLmRlcHMgPD0gMCkgew0KICAgICAgICBzdXNwZW5zZS5yZXNvbHZlKCk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBjb25zdCB7IHRpbWVvdXQsIHBlbmRpbmdJZCB9ID0gc3VzcGVuc2U7DQogICAgICAgIGlmICh0aW1lb3V0ID4gMCkgew0KICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gew0KICAgICAgICAgICAgaWYgKHN1c3BlbnNlLnBlbmRpbmdJZCA9PT0gcGVuZGluZ0lkKSB7DQogICAgICAgICAgICAgIHN1c3BlbnNlLmZhbGxiYWNrKG5ld0ZhbGxiYWNrKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICB9LCB0aW1lb3V0KTsNCiAgICAgICAgfSBlbHNlIGlmICh0aW1lb3V0ID09PSAwKSB7DQogICAgICAgICAgc3VzcGVuc2UuZmFsbGJhY2sobmV3RmFsbGJhY2spOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICB9DQp9DQpsZXQgaGFzV2FybmVkID0gZmFsc2U7DQpmdW5jdGlvbiBjcmVhdGVTdXNwZW5zZUJvdW5kYXJ5KHZub2RlLCBwYXJlbnRTdXNwZW5zZSwgcGFyZW50Q29tcG9uZW50LCBjb250YWluZXIsIGhpZGRlbkNvbnRhaW5lciwgYW5jaG9yLCBuYW1lc3BhY2UsIHNsb3RTY29wZUlkcywgb3B0aW1pemVkLCByZW5kZXJlckludGVybmFscywgaXNIeWRyYXRpbmcgPSBmYWxzZSkgew0KICBpZiAoIWhhc1dhcm5lZCkgew0KICAgIGhhc1dhcm5lZCA9IHRydWU7DQogICAgY29uc29sZVtjb25zb2xlLmluZm8gPyAiaW5mbyIgOiAibG9nIl0oDQogICAgICBgPFN1c3BlbnNlPiBpcyBhbiBleHBlcmltZW50YWwgZmVhdHVyZSBhbmQgaXRzIEFQSSB3aWxsIGxpa2VseSBjaGFuZ2UuYA0KICAgICk7DQogIH0NCiAgY29uc3Qgew0KICAgIHA6IHBhdGNoLA0KICAgIG06IG1vdmUsDQogICAgdW06IHVubW91bnQsDQogICAgbjogbmV4dCwNCiAgICBvOiB7IHBhcmVudE5vZGUsIHJlbW92ZSB9DQogIH0gPSByZW5kZXJlckludGVybmFsczsNCiAgbGV0IHBhcmVudFN1c3BlbnNlSWQ7DQogIGNvbnN0IGlzU3VzcGVuc2libGUgPSBpc1ZOb2RlU3VzcGVuc2libGUodm5vZGUpOw0KICBpZiAoaXNTdXNwZW5zaWJsZSkgew0KICAgIGlmIChwYXJlbnRTdXNwZW5zZSAmJiBwYXJlbnRTdXNwZW5zZS5wZW5kaW5nQnJhbmNoKSB7DQogICAgICBwYXJlbnRTdXNwZW5zZUlkID0gcGFyZW50U3VzcGVuc2UucGVuZGluZ0lkOw0KICAgICAgcGFyZW50U3VzcGVuc2UuZGVwcysrOw0KICAgIH0NCiAgfQ0KICBjb25zdCB0aW1lb3V0ID0gdm5vZGUucHJvcHMgPyB0b051bWJlcih2bm9kZS5wcm9wcy50aW1lb3V0KSA6IHZvaWQgMDsNCiAgew0KICAgIGFzc2VydE51bWJlcih0aW1lb3V0LCBgU3VzcGVuc2UgdGltZW91dGApOw0KICB9DQogIGNvbnN0IGluaXRpYWxBbmNob3IgPSBhbmNob3I7DQogIGNvbnN0IHN1c3BlbnNlID0gew0KICAgIHZub2RlLA0KICAgIHBhcmVudDogcGFyZW50U3VzcGVuc2UsDQogICAgcGFyZW50Q29tcG9uZW50LA0KICAgIG5hbWVzcGFjZSwNCiAgICBjb250YWluZXIsDQogICAgaGlkZGVuQ29udGFpbmVyLA0KICAgIGRlcHM6IDAsDQogICAgcGVuZGluZ0lkOiBzdXNwZW5zZUlkKyssDQogICAgdGltZW91dDogdHlwZW9mIHRpbWVvdXQgPT09ICJudW1iZXIiID8gdGltZW91dCA6IC0xLA0KICAgIGFjdGl2ZUJyYW5jaDogbnVsbCwNCiAgICBwZW5kaW5nQnJhbmNoOiBudWxsLA0KICAgIGlzSW5GYWxsYmFjazogIWlzSHlkcmF0aW5nLA0KICAgIGlzSHlkcmF0aW5nLA0KICAgIGlzVW5tb3VudGVkOiBmYWxzZSwNCiAgICBlZmZlY3RzOiBbXSwNCiAgICByZXNvbHZlKHJlc3VtZSA9IGZhbHNlLCBzeW5jID0gZmFsc2UpIHsNCiAgICAgIHsNCiAgICAgICAgaWYgKCFyZXN1bWUgJiYgIXN1c3BlbnNlLnBlbmRpbmdCcmFuY2gpIHsNCiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoDQogICAgICAgICAgICBgc3VzcGVuc2UucmVzb2x2ZSgpIGlzIGNhbGxlZCB3aXRob3V0IGEgcGVuZGluZyBicmFuY2guYA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKHN1c3BlbnNlLmlzVW5tb3VudGVkKSB7DQogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKA0KICAgICAgICAgICAgYHN1c3BlbnNlLnJlc29sdmUoKSBpcyBjYWxsZWQgb24gYW4gYWxyZWFkeSB1bm1vdW50ZWQgc3VzcGVuc2UgYm91bmRhcnkuYA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGNvbnN0IHsNCiAgICAgICAgdm5vZGU6IHZub2RlMiwNCiAgICAgICAgYWN0aXZlQnJhbmNoLA0KICAgICAgICBwZW5kaW5nQnJhbmNoLA0KICAgICAgICBwZW5kaW5nSWQsDQogICAgICAgIGVmZmVjdHMsDQogICAgICAgIHBhcmVudENvbXBvbmVudDogcGFyZW50Q29tcG9uZW50MiwNCiAgICAgICAgY29udGFpbmVyOiBjb250YWluZXIyDQogICAgICB9ID0gc3VzcGVuc2U7DQogICAgICBsZXQgZGVsYXlFbnRlciA9IGZhbHNlOw0KICAgICAgaWYgKHN1c3BlbnNlLmlzSHlkcmF0aW5nKSB7DQogICAgICAgIHN1c3BlbnNlLmlzSHlkcmF0aW5nID0gZmFsc2U7DQogICAgICB9IGVsc2UgaWYgKCFyZXN1bWUpIHsNCiAgICAgICAgZGVsYXlFbnRlciA9IGFjdGl2ZUJyYW5jaCAmJiBwZW5kaW5nQnJhbmNoLnRyYW5zaXRpb24gJiYgcGVuZGluZ0JyYW5jaC50cmFuc2l0aW9uLm1vZGUgPT09ICJvdXQtaW4iOw0KICAgICAgICBpZiAoZGVsYXlFbnRlcikgew0KICAgICAgICAgIGFjdGl2ZUJyYW5jaC50cmFuc2l0aW9uLmFmdGVyTGVhdmUgPSAoKSA9PiB7DQogICAgICAgICAgICBpZiAocGVuZGluZ0lkID09PSBzdXNwZW5zZS5wZW5kaW5nSWQpIHsNCiAgICAgICAgICAgICAgbW92ZSgNCiAgICAgICAgICAgICAgICBwZW5kaW5nQnJhbmNoLA0KICAgICAgICAgICAgICAgIGNvbnRhaW5lcjIsDQogICAgICAgICAgICAgICAgYW5jaG9yID09PSBpbml0aWFsQW5jaG9yID8gbmV4dChhY3RpdmVCcmFuY2gpIDogYW5jaG9yLA0KICAgICAgICAgICAgICAgIDANCiAgICAgICAgICAgICAgKTsNCiAgICAgICAgICAgICAgcXVldWVQb3N0Rmx1c2hDYihlZmZlY3RzKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICB9Ow0KICAgICAgICB9DQogICAgICAgIGlmIChhY3RpdmVCcmFuY2gpIHsNCiAgICAgICAgICBpZiAocGFyZW50Tm9kZShhY3RpdmVCcmFuY2guZWwpID09PSBjb250YWluZXIyKSB7DQogICAgICAgICAgICBhbmNob3IgPSBuZXh0KGFjdGl2ZUJyYW5jaCk7DQogICAgICAgICAgfQ0KICAgICAgICAgIHVubW91bnQoYWN0aXZlQnJhbmNoLCBwYXJlbnRDb21wb25lbnQyLCBzdXNwZW5zZSwgdHJ1ZSk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKCFkZWxheUVudGVyKSB7DQogICAgICAgICAgbW92ZShwZW5kaW5nQnJhbmNoLCBjb250YWluZXIyLCBhbmNob3IsIDApOw0KICAgICAgICB9DQogICAgICB9DQogICAgICBzZXRBY3RpdmVCcmFuY2goc3VzcGVuc2UsIHBlbmRpbmdCcmFuY2gpOw0KICAgICAgc3VzcGVuc2UucGVuZGluZ0JyYW5jaCA9IG51bGw7DQogICAgICBzdXNwZW5zZS5pc0luRmFsbGJhY2sgPSBmYWxzZTsNCiAgICAgIGxldCBwYXJlbnQgPSBzdXNwZW5zZS5wYXJlbnQ7DQogICAgICBsZXQgaGFzVW5yZXNvbHZlZEFuY2VzdG9yID0gZmFsc2U7DQogICAgICB3aGlsZSAocGFyZW50KSB7DQogICAgICAgIGlmIChwYXJlbnQucGVuZGluZ0JyYW5jaCkgew0KICAgICAgICAgIHBhcmVudC5lZmZlY3RzLnB1c2goLi4uZWZmZWN0cyk7DQogICAgICAgICAgaGFzVW5yZXNvbHZlZEFuY2VzdG9yID0gdHJ1ZTsNCiAgICAgICAgICBicmVhazsNCiAgICAgICAgfQ0KICAgICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50Ow0KICAgICAgfQ0KICAgICAgaWYgKCFoYXNVbnJlc29sdmVkQW5jZXN0b3IgJiYgIWRlbGF5RW50ZXIpIHsNCiAgICAgICAgcXVldWVQb3N0Rmx1c2hDYihlZmZlY3RzKTsNCiAgICAgIH0NCiAgICAgIHN1c3BlbnNlLmVmZmVjdHMgPSBbXTsNCiAgICAgIGlmIChpc1N1c3BlbnNpYmxlKSB7DQogICAgICAgIGlmIChwYXJlbnRTdXNwZW5zZSAmJiBwYXJlbnRTdXNwZW5zZS5wZW5kaW5nQnJhbmNoICYmIHBhcmVudFN1c3BlbnNlSWQgPT09IHBhcmVudFN1c3BlbnNlLnBlbmRpbmdJZCkgew0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlLmRlcHMtLTsNCiAgICAgICAgICBpZiAocGFyZW50U3VzcGVuc2UuZGVwcyA9PT0gMCAmJiAhc3luYykgew0KICAgICAgICAgICAgcGFyZW50U3VzcGVuc2UucmVzb2x2ZSgpOw0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgdHJpZ2dlckV2ZW50KHZub2RlMiwgIm9uUmVzb2x2ZSIpOw0KICAgIH0sDQogICAgZmFsbGJhY2soZmFsbGJhY2tWTm9kZSkgew0KICAgICAgaWYgKCFzdXNwZW5zZS5wZW5kaW5nQnJhbmNoKSB7DQogICAgICAgIHJldHVybjsNCiAgICAgIH0NCiAgICAgIGNvbnN0IHsgdm5vZGU6IHZub2RlMiwgYWN0aXZlQnJhbmNoLCBwYXJlbnRDb21wb25lbnQ6IHBhcmVudENvbXBvbmVudDIsIGNvbnRhaW5lcjogY29udGFpbmVyMiwgbmFtZXNwYWNlOiBuYW1lc3BhY2UyIH0gPSBzdXNwZW5zZTsNCiAgICAgIHRyaWdnZXJFdmVudCh2bm9kZTIsICJvbkZhbGxiYWNrIik7DQogICAgICBjb25zdCBhbmNob3IyID0gbmV4dChhY3RpdmVCcmFuY2gpOw0KICAgICAgY29uc3QgbW91bnRGYWxsYmFjayA9ICgpID0+IHsNCiAgICAgICAgaWYgKCFzdXNwZW5zZS5pc0luRmFsbGJhY2spIHsNCiAgICAgICAgICByZXR1cm47DQogICAgICAgIH0NCiAgICAgICAgcGF0Y2goDQogICAgICAgICAgbnVsbCwNCiAgICAgICAgICBmYWxsYmFja1ZOb2RlLA0KICAgICAgICAgIGNvbnRhaW5lcjIsDQogICAgICAgICAgYW5jaG9yMiwNCiAgICAgICAgICBwYXJlbnRDb21wb25lbnQyLA0KICAgICAgICAgIG51bGwsDQogICAgICAgICAgLy8gZmFsbGJhY2sgdHJlZSB3aWxsIG5vdCBoYXZlIHN1c3BlbnNlIGNvbnRleHQNCiAgICAgICAgICBuYW1lc3BhY2UyLA0KICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgKTsNCiAgICAgICAgc2V0QWN0aXZlQnJhbmNoKHN1c3BlbnNlLCBmYWxsYmFja1ZOb2RlKTsNCiAgICAgIH07DQogICAgICBjb25zdCBkZWxheUVudGVyID0gZmFsbGJhY2tWTm9kZS50cmFuc2l0aW9uICYmIGZhbGxiYWNrVk5vZGUudHJhbnNpdGlvbi5tb2RlID09PSAib3V0LWluIjsNCiAgICAgIGlmIChkZWxheUVudGVyKSB7DQogICAgICAgIGFjdGl2ZUJyYW5jaC50cmFuc2l0aW9uLmFmdGVyTGVhdmUgPSBtb3VudEZhbGxiYWNrOw0KICAgICAgfQ0KICAgICAgc3VzcGVuc2UuaXNJbkZhbGxiYWNrID0gdHJ1ZTsNCiAgICAgIHVubW91bnQoDQogICAgICAgIGFjdGl2ZUJyYW5jaCwNCiAgICAgICAgcGFyZW50Q29tcG9uZW50MiwNCiAgICAgICAgbnVsbCwNCiAgICAgICAgLy8gbm8gc3VzcGVuc2Ugc28gdW5tb3VudCBob29rcyBmaXJlIG5vdw0KICAgICAgICB0cnVlDQogICAgICAgIC8vIHNob3VsZFJlbW92ZQ0KICAgICAgKTsNCiAgICAgIGlmICghZGVsYXlFbnRlcikgew0KICAgICAgICBtb3VudEZhbGxiYWNrKCk7DQogICAgICB9DQogICAgfSwNCiAgICBtb3ZlKGNvbnRhaW5lcjIsIGFuY2hvcjIsIHR5cGUpIHsNCiAgICAgIHN1c3BlbnNlLmFjdGl2ZUJyYW5jaCAmJiBtb3ZlKHN1c3BlbnNlLmFjdGl2ZUJyYW5jaCwgY29udGFpbmVyMiwgYW5jaG9yMiwgdHlwZSk7DQogICAgICBzdXNwZW5zZS5jb250YWluZXIgPSBjb250YWluZXIyOw0KICAgIH0sDQogICAgbmV4dCgpIHsNCiAgICAgIHJldHVybiBzdXNwZW5zZS5hY3RpdmVCcmFuY2ggJiYgbmV4dChzdXNwZW5zZS5hY3RpdmVCcmFuY2gpOw0KICAgIH0sDQogICAgcmVnaXN0ZXJEZXAoaW5zdGFuY2UsIHNldHVwUmVuZGVyRWZmZWN0LCBvcHRpbWl6ZWQyKSB7DQogICAgICBjb25zdCBpc0luUGVuZGluZ1N1c3BlbnNlID0gISFzdXNwZW5zZS5wZW5kaW5nQnJhbmNoOw0KICAgICAgaWYgKGlzSW5QZW5kaW5nU3VzcGVuc2UpIHsNCiAgICAgICAgc3VzcGVuc2UuZGVwcysrOw0KICAgICAgfQ0KICAgICAgY29uc3QgaHlkcmF0ZWRFbCA9IGluc3RhbmNlLnZub2RlLmVsOw0KICAgICAgaW5zdGFuY2UuYXN5bmNEZXAuY2F0Y2goKGVycikgPT4gew0KICAgICAgICBoYW5kbGVFcnJvcihlcnIsIGluc3RhbmNlLCAwKTsNCiAgICAgIH0pLnRoZW4oKGFzeW5jU2V0dXBSZXN1bHQpID0+IHsNCiAgICAgICAgaWYgKGluc3RhbmNlLmlzVW5tb3VudGVkIHx8IHN1c3BlbnNlLmlzVW5tb3VudGVkIHx8IHN1c3BlbnNlLnBlbmRpbmdJZCAhPT0gaW5zdGFuY2Uuc3VzcGVuc2VJZCkgew0KICAgICAgICAgIHJldHVybjsNCiAgICAgICAgfQ0KICAgICAgICBpbnN0YW5jZS5hc3luY1Jlc29sdmVkID0gdHJ1ZTsNCiAgICAgICAgY29uc3QgeyB2bm9kZTogdm5vZGUyIH0gPSBpbnN0YW5jZTsNCiAgICAgICAgew0KICAgICAgICAgIHB1c2hXYXJuaW5nQ29udGV4dCh2bm9kZTIpOw0KICAgICAgICB9DQogICAgICAgIGhhbmRsZVNldHVwUmVzdWx0KGluc3RhbmNlLCBhc3luY1NldHVwUmVzdWx0LCBmYWxzZSk7DQogICAgICAgIGlmIChoeWRyYXRlZEVsKSB7DQogICAgICAgICAgdm5vZGUyLmVsID0gaHlkcmF0ZWRFbDsNCiAgICAgICAgfQ0KICAgICAgICBjb25zdCBwbGFjZWhvbGRlciA9ICFoeWRyYXRlZEVsICYmIGluc3RhbmNlLnN1YlRyZWUuZWw7DQogICAgICAgIHNldHVwUmVuZGVyRWZmZWN0KA0KICAgICAgICAgIGluc3RhbmNlLA0KICAgICAgICAgIHZub2RlMiwNCiAgICAgICAgICAvLyBjb21wb25lbnQgbWF5IGhhdmUgYmVlbiBtb3ZlZCBiZWZvcmUgcmVzb2x2ZS4NCiAgICAgICAgICAvLyBpZiB0aGlzIGlzIG5vdCBhIGh5ZHJhdGlvbiwgaW5zdGFuY2Uuc3ViVHJlZSB3aWxsIGJlIHRoZSBjb21tZW50DQogICAgICAgICAgLy8gcGxhY2Vob2xkZXIuDQogICAgICAgICAgcGFyZW50Tm9kZShoeWRyYXRlZEVsIHx8IGluc3RhbmNlLnN1YlRyZWUuZWwpLA0KICAgICAgICAgIC8vIGFuY2hvciB3aWxsIG5vdCBiZSB1c2VkIGlmIHRoaXMgaXMgaHlkcmF0aW9uLCBzbyBvbmx5IG5lZWQgdG8NCiAgICAgICAgICAvLyBjb25zaWRlciB0aGUgY29tbWVudCBwbGFjZWhvbGRlciBjYXNlLg0KICAgICAgICAgIGh5ZHJhdGVkRWwgPyBudWxsIDogbmV4dChpbnN0YW5jZS5zdWJUcmVlKSwNCiAgICAgICAgICBzdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgb3B0aW1pemVkMg0KICAgICAgICApOw0KICAgICAgICBpZiAocGxhY2Vob2xkZXIpIHsNCiAgICAgICAgICByZW1vdmUocGxhY2Vob2xkZXIpOw0KICAgICAgICB9DQogICAgICAgIHVwZGF0ZUhPQ0hvc3RFbChpbnN0YW5jZSwgdm5vZGUyLmVsKTsNCiAgICAgICAgew0KICAgICAgICAgIHBvcFdhcm5pbmdDb250ZXh0KCk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKGlzSW5QZW5kaW5nU3VzcGVuc2UgJiYgLS1zdXNwZW5zZS5kZXBzID09PSAwKSB7DQogICAgICAgICAgc3VzcGVuc2UucmVzb2x2ZSgpOw0KICAgICAgICB9DQogICAgICB9KTsNCiAgICB9LA0KICAgIHVubW91bnQocGFyZW50U3VzcGVuc2UyLCBkb1JlbW92ZSkgew0KICAgICAgc3VzcGVuc2UuaXNVbm1vdW50ZWQgPSB0cnVlOw0KICAgICAgaWYgKHN1c3BlbnNlLmFjdGl2ZUJyYW5jaCkgew0KICAgICAgICB1bm1vdW50KA0KICAgICAgICAgIHN1c3BlbnNlLmFjdGl2ZUJyYW5jaCwNCiAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgcGFyZW50U3VzcGVuc2UyLA0KICAgICAgICAgIGRvUmVtb3ZlDQogICAgICAgICk7DQogICAgICB9DQogICAgICBpZiAoc3VzcGVuc2UucGVuZGluZ0JyYW5jaCkgew0KICAgICAgICB1bm1vdW50KA0KICAgICAgICAgIHN1c3BlbnNlLnBlbmRpbmdCcmFuY2gsDQogICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlMiwNCiAgICAgICAgICBkb1JlbW92ZQ0KICAgICAgICApOw0KICAgICAgfQ0KICAgIH0NCiAgfTsNCiAgcmV0dXJuIHN1c3BlbnNlOw0KfQ0KZnVuY3Rpb24gaHlkcmF0ZVN1c3BlbnNlKG5vZGUsIHZub2RlLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBuYW1lc3BhY2UsIHNsb3RTY29wZUlkcywgb3B0aW1pemVkLCByZW5kZXJlckludGVybmFscywgaHlkcmF0ZU5vZGUpIHsNCiAgY29uc3Qgc3VzcGVuc2UgPSB2bm9kZS5zdXNwZW5zZSA9IGNyZWF0ZVN1c3BlbnNlQm91bmRhcnkoDQogICAgdm5vZGUsDQogICAgcGFyZW50U3VzcGVuc2UsDQogICAgcGFyZW50Q29tcG9uZW50LA0KICAgIG5vZGUucGFyZW50Tm9kZSwNCiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1nbG9iYWxzDQogICAgZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2IiksDQogICAgbnVsbCwNCiAgICBuYW1lc3BhY2UsDQogICAgc2xvdFNjb3BlSWRzLA0KICAgIG9wdGltaXplZCwNCiAgICByZW5kZXJlckludGVybmFscywNCiAgICB0cnVlDQogICk7DQogIGNvbnN0IHJlc3VsdCA9IGh5ZHJhdGVOb2RlKA0KICAgIG5vZGUsDQogICAgc3VzcGVuc2UucGVuZGluZ0JyYW5jaCA9IHZub2RlLnNzQ29udGVudCwNCiAgICBwYXJlbnRDb21wb25lbnQsDQogICAgc3VzcGVuc2UsDQogICAgc2xvdFNjb3BlSWRzLA0KICAgIG9wdGltaXplZA0KICApOw0KICBpZiAoc3VzcGVuc2UuZGVwcyA9PT0gMCkgew0KICAgIHN1c3BlbnNlLnJlc29sdmUoZmFsc2UsIHRydWUpOw0KICB9DQogIHJldHVybiByZXN1bHQ7DQp9DQpmdW5jdGlvbiBub3JtYWxpemVTdXNwZW5zZUNoaWxkcmVuKHZub2RlKSB7DQogIGNvbnN0IHsgc2hhcGVGbGFnLCBjaGlsZHJlbiB9ID0gdm5vZGU7DQogIGNvbnN0IGlzU2xvdENoaWxkcmVuID0gc2hhcGVGbGFnICYgMzI7DQogIHZub2RlLnNzQ29udGVudCA9IG5vcm1hbGl6ZVN1c3BlbnNlU2xvdCgNCiAgICBpc1Nsb3RDaGlsZHJlbiA/IGNoaWxkcmVuLmRlZmF1bHQgOiBjaGlsZHJlbg0KICApOw0KICB2bm9kZS5zc0ZhbGxiYWNrID0gaXNTbG90Q2hpbGRyZW4gPyBub3JtYWxpemVTdXNwZW5zZVNsb3QoY2hpbGRyZW4uZmFsbGJhY2spIDogY3JlYXRlVk5vZGUoQ29tbWVudCk7DQp9DQpmdW5jdGlvbiBub3JtYWxpemVTdXNwZW5zZVNsb3Qocykgew0KICBsZXQgYmxvY2s7DQogIGlmIChpc0Z1bmN0aW9uKHMpKSB7DQogICAgY29uc3QgdHJhY2tCbG9jayA9IGlzQmxvY2tUcmVlRW5hYmxlZCAmJiBzLl9jOw0KICAgIGlmICh0cmFja0Jsb2NrKSB7DQogICAgICBzLl9kID0gZmFsc2U7DQogICAgICBvcGVuQmxvY2soKTsNCiAgICB9DQogICAgcyA9IHMoKTsNCiAgICBpZiAodHJhY2tCbG9jaykgew0KICAgICAgcy5fZCA9IHRydWU7DQogICAgICBibG9jayA9IGN1cnJlbnRCbG9jazsNCiAgICAgIGNsb3NlQmxvY2soKTsNCiAgICB9DQogIH0NCiAgaWYgKGlzQXJyYXkocykpIHsNCiAgICBjb25zdCBzaW5nbGVDaGlsZCA9IGZpbHRlclNpbmdsZVJvb3Qocyk7DQogICAgaWYgKCFzaW5nbGVDaGlsZCAmJiBzLmZpbHRlcigoY2hpbGQpID0+IGNoaWxkICE9PSBOVUxMX0RZTkFNSUNfQ09NUE9ORU5UKS5sZW5ndGggPiAwKSB7DQogICAgICB3YXJuJDEoYDxTdXNwZW5zZT4gc2xvdHMgZXhwZWN0IGEgc2luZ2xlIHJvb3Qgbm9kZS5gKTsNCiAgICB9DQogICAgcyA9IHNpbmdsZUNoaWxkOw0KICB9DQogIHMgPSBub3JtYWxpemVWTm9kZShzKTsNCiAgaWYgKGJsb2NrICYmICFzLmR5bmFtaWNDaGlsZHJlbikgew0KICAgIHMuZHluYW1pY0NoaWxkcmVuID0gYmxvY2suZmlsdGVyKChjKSA9PiBjICE9PSBzKTsNCiAgfQ0KICByZXR1cm4gczsNCn0NCmZ1bmN0aW9uIHF1ZXVlRWZmZWN0V2l0aFN1c3BlbnNlKGZuLCBzdXNwZW5zZSkgew0KICBpZiAoc3VzcGVuc2UgJiYgc3VzcGVuc2UucGVuZGluZ0JyYW5jaCkgew0KICAgIGlmIChpc0FycmF5KGZuKSkgew0KICAgICAgc3VzcGVuc2UuZWZmZWN0cy5wdXNoKC4uLmZuKTsNCiAgICB9IGVsc2Ugew0KICAgICAgc3VzcGVuc2UuZWZmZWN0cy5wdXNoKGZuKTsNCiAgICB9DQogIH0gZWxzZSB7DQogICAgcXVldWVQb3N0Rmx1c2hDYihmbik7DQogIH0NCn0NCmZ1bmN0aW9uIHNldEFjdGl2ZUJyYW5jaChzdXNwZW5zZSwgYnJhbmNoKSB7DQogIHN1c3BlbnNlLmFjdGl2ZUJyYW5jaCA9IGJyYW5jaDsNCiAgY29uc3QgeyB2bm9kZSwgcGFyZW50Q29tcG9uZW50IH0gPSBzdXNwZW5zZTsNCiAgbGV0IGVsID0gYnJhbmNoLmVsOw0KICB3aGlsZSAoIWVsICYmIGJyYW5jaC5jb21wb25lbnQpIHsNCiAgICBicmFuY2ggPSBicmFuY2guY29tcG9uZW50LnN1YlRyZWU7DQogICAgZWwgPSBicmFuY2guZWw7DQogIH0NCiAgdm5vZGUuZWwgPSBlbDsNCiAgaWYgKHBhcmVudENvbXBvbmVudCAmJiBwYXJlbnRDb21wb25lbnQuc3ViVHJlZSA9PT0gdm5vZGUpIHsNCiAgICBwYXJlbnRDb21wb25lbnQudm5vZGUuZWwgPSBlbDsNCiAgICB1cGRhdGVIT0NIb3N0RWwocGFyZW50Q29tcG9uZW50LCBlbCk7DQogIH0NCn0NCmZ1bmN0aW9uIGlzVk5vZGVTdXNwZW5zaWJsZSh2bm9kZSkgew0KICBjb25zdCBzdXNwZW5zaWJsZSA9IHZub2RlLnByb3BzICYmIHZub2RlLnByb3BzLnN1c3BlbnNpYmxlOw0KICByZXR1cm4gc3VzcGVuc2libGUgIT0gbnVsbCAmJiBzdXNwZW5zaWJsZSAhPT0gZmFsc2U7DQp9DQoNCmNvbnN0IEZyYWdtZW50ID0gU3ltYm9sLmZvcigidi1mZ3QiKTsNCmNvbnN0IFRleHQgPSBTeW1ib2wuZm9yKCJ2LXR4dCIpOw0KY29uc3QgQ29tbWVudCA9IFN5bWJvbC5mb3IoInYtY210Iik7DQpjb25zdCBTdGF0aWMgPSBTeW1ib2wuZm9yKCJ2LXN0YyIpOw0KY29uc3QgYmxvY2tTdGFjayA9IFtdOw0KbGV0IGN1cnJlbnRCbG9jayA9IG51bGw7DQpmdW5jdGlvbiBvcGVuQmxvY2soZGlzYWJsZVRyYWNraW5nID0gZmFsc2UpIHsNCiAgYmxvY2tTdGFjay5wdXNoKGN1cnJlbnRCbG9jayA9IGRpc2FibGVUcmFja2luZyA/IG51bGwgOiBbXSk7DQp9DQpmdW5jdGlvbiBjbG9zZUJsb2NrKCkgew0KICBibG9ja1N0YWNrLnBvcCgpOw0KICBjdXJyZW50QmxvY2sgPSBibG9ja1N0YWNrW2Jsb2NrU3RhY2subGVuZ3RoIC0gMV0gfHwgbnVsbDsNCn0NCmxldCBpc0Jsb2NrVHJlZUVuYWJsZWQgPSAxOw0KZnVuY3Rpb24gc2V0QmxvY2tUcmFja2luZyh2YWx1ZSwgaW5WT25jZSA9IGZhbHNlKSB7DQogIGlzQmxvY2tUcmVlRW5hYmxlZCArPSB2YWx1ZTsNCiAgaWYgKHZhbHVlIDwgMCAmJiBjdXJyZW50QmxvY2sgJiYgaW5WT25jZSkgew0KICAgIGN1cnJlbnRCbG9jay5oYXNPbmNlID0gdHJ1ZTsNCiAgfQ0KfQ0KZnVuY3Rpb24gc2V0dXBCbG9jayh2bm9kZSkgew0KICB2bm9kZS5keW5hbWljQ2hpbGRyZW4gPSBpc0Jsb2NrVHJlZUVuYWJsZWQgPiAwID8gY3VycmVudEJsb2NrIHx8IEVNUFRZX0FSUiA6IG51bGw7DQogIGNsb3NlQmxvY2soKTsNCiAgaWYgKGlzQmxvY2tUcmVlRW5hYmxlZCA+IDAgJiYgY3VycmVudEJsb2NrKSB7DQogICAgY3VycmVudEJsb2NrLnB1c2godm5vZGUpOw0KICB9DQogIHJldHVybiB2bm9kZTsNCn0NCmZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnRCbG9jayh0eXBlLCBwcm9wcywgY2hpbGRyZW4sIHBhdGNoRmxhZywgZHluYW1pY1Byb3BzLCBzaGFwZUZsYWcpIHsNCiAgcmV0dXJuIHNldHVwQmxvY2soDQogICAgY3JlYXRlQmFzZVZOb2RlKA0KICAgICAgdHlwZSwNCiAgICAgIHByb3BzLA0KICAgICAgY2hpbGRyZW4sDQogICAgICBwYXRjaEZsYWcsDQogICAgICBkeW5hbWljUHJvcHMsDQogICAgICBzaGFwZUZsYWcsDQogICAgICB0cnVlDQogICAgKQ0KICApOw0KfQ0KZnVuY3Rpb24gY3JlYXRlQmxvY2sodHlwZSwgcHJvcHMsIGNoaWxkcmVuLCBwYXRjaEZsYWcsIGR5bmFtaWNQcm9wcykgew0KICByZXR1cm4gc2V0dXBCbG9jaygNCiAgICBjcmVhdGVWTm9kZSgNCiAgICAgIHR5cGUsDQogICAgICBwcm9wcywNCiAgICAgIGNoaWxkcmVuLA0KICAgICAgcGF0Y2hGbGFnLA0KICAgICAgZHluYW1pY1Byb3BzLA0KICAgICAgdHJ1ZQ0KICAgICkNCiAgKTsNCn0NCmZ1bmN0aW9uIGlzVk5vZGUodmFsdWUpIHsNCiAgcmV0dXJuIHZhbHVlID8gdmFsdWUuX192X2lzVk5vZGUgPT09IHRydWUgOiBmYWxzZTsNCn0NCmZ1bmN0aW9uIGlzU2FtZVZOb2RlVHlwZShuMSwgbjIpIHsNCiAgaWYgKG4yLnNoYXBlRmxhZyAmIDYgJiYgbjEuY29tcG9uZW50KSB7DQogICAgY29uc3QgZGlydHlJbnN0YW5jZXMgPSBobXJEaXJ0eUNvbXBvbmVudHMuZ2V0KG4yLnR5cGUpOw0KICAgIGlmIChkaXJ0eUluc3RhbmNlcyAmJiBkaXJ0eUluc3RhbmNlcy5oYXMobjEuY29tcG9uZW50KSkgew0KICAgICAgbjEuc2hhcGVGbGFnICY9IC0yNTc7DQogICAgICBuMi5zaGFwZUZsYWcgJj0gLTUxMzsNCiAgICAgIHJldHVybiBmYWxzZTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIG4xLnR5cGUgPT09IG4yLnR5cGUgJiYgbjEua2V5ID09PSBuMi5rZXk7DQp9DQpsZXQgdm5vZGVBcmdzVHJhbnNmb3JtZXI7DQpmdW5jdGlvbiB0cmFuc2Zvcm1WTm9kZUFyZ3ModHJhbnNmb3JtZXIpIHsNCiAgdm5vZGVBcmdzVHJhbnNmb3JtZXIgPSB0cmFuc2Zvcm1lcjsNCn0NCmNvbnN0IGNyZWF0ZVZOb2RlV2l0aEFyZ3NUcmFuc2Zvcm0gPSAoLi4uYXJncykgPT4gew0KICByZXR1cm4gX2NyZWF0ZVZOb2RlKA0KICAgIC4uLnZub2RlQXJnc1RyYW5zZm9ybWVyID8gdm5vZGVBcmdzVHJhbnNmb3JtZXIoYXJncywgY3VycmVudFJlbmRlcmluZ0luc3RhbmNlKSA6IGFyZ3MNCiAgKTsNCn07DQpjb25zdCBub3JtYWxpemVLZXkgPSAoeyBrZXkgfSkgPT4ga2V5ICE9IG51bGwgPyBrZXkgOiBudWxsOw0KY29uc3Qgbm9ybWFsaXplUmVmID0gKHsNCiAgcmVmLA0KICByZWZfa2V5LA0KICByZWZfZm9yDQp9KSA9PiB7DQogIGlmICh0eXBlb2YgcmVmID09PSAibnVtYmVyIikgew0KICAgIHJlZiA9ICIiICsgcmVmOw0KICB9DQogIHJldHVybiByZWYgIT0gbnVsbCA/IGlzU3RyaW5nKHJlZikgfHwgaXNSZWYocmVmKSB8fCBpc0Z1bmN0aW9uKHJlZikgPyB7IGk6IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSwgcjogcmVmLCBrOiByZWZfa2V5LCBmOiAhIXJlZl9mb3IgfSA6IHJlZiA6IG51bGw7DQp9Ow0KZnVuY3Rpb24gY3JlYXRlQmFzZVZOb2RlKHR5cGUsIHByb3BzID0gbnVsbCwgY2hpbGRyZW4gPSBudWxsLCBwYXRjaEZsYWcgPSAwLCBkeW5hbWljUHJvcHMgPSBudWxsLCBzaGFwZUZsYWcgPSB0eXBlID09PSBGcmFnbWVudCA/IDAgOiAxLCBpc0Jsb2NrTm9kZSA9IGZhbHNlLCBuZWVkRnVsbENoaWxkcmVuTm9ybWFsaXphdGlvbiA9IGZhbHNlKSB7DQogIGNvbnN0IHZub2RlID0gew0KICAgIF9fdl9pc1ZOb2RlOiB0cnVlLA0KICAgIF9fdl9za2lwOiB0cnVlLA0KICAgIHR5cGUsDQogICAgcHJvcHMsDQogICAga2V5OiBwcm9wcyAmJiBub3JtYWxpemVLZXkocHJvcHMpLA0KICAgIHJlZjogcHJvcHMgJiYgbm9ybWFsaXplUmVmKHByb3BzKSwNCiAgICBzY29wZUlkOiBjdXJyZW50U2NvcGVJZCwNCiAgICBzbG90U2NvcGVJZHM6IG51bGwsDQogICAgY2hpbGRyZW4sDQogICAgY29tcG9uZW50OiBudWxsLA0KICAgIHN1c3BlbnNlOiBudWxsLA0KICAgIHNzQ29udGVudDogbnVsbCwNCiAgICBzc0ZhbGxiYWNrOiBudWxsLA0KICAgIGRpcnM6IG51bGwsDQogICAgdHJhbnNpdGlvbjogbnVsbCwNCiAgICBlbDogbnVsbCwNCiAgICBhbmNob3I6IG51bGwsDQogICAgdGFyZ2V0OiBudWxsLA0KICAgIHRhcmdldFN0YXJ0OiBudWxsLA0KICAgIHRhcmdldEFuY2hvcjogbnVsbCwNCiAgICBzdGF0aWNDb3VudDogMCwNCiAgICBzaGFwZUZsYWcsDQogICAgcGF0Y2hGbGFnLA0KICAgIGR5bmFtaWNQcm9wcywNCiAgICBkeW5hbWljQ2hpbGRyZW46IG51bGwsDQogICAgYXBwQ29udGV4dDogbnVsbCwNCiAgICBjdHg6IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZQ0KICB9Ow0KICBpZiAobmVlZEZ1bGxDaGlsZHJlbk5vcm1hbGl6YXRpb24pIHsNCiAgICBub3JtYWxpemVDaGlsZHJlbih2bm9kZSwgY2hpbGRyZW4pOw0KICAgIGlmIChzaGFwZUZsYWcgJiAxMjgpIHsNCiAgICAgIHR5cGUubm9ybWFsaXplKHZub2RlKTsNCiAgICB9DQogIH0gZWxzZSBpZiAoY2hpbGRyZW4pIHsNCiAgICB2bm9kZS5zaGFwZUZsYWcgfD0gaXNTdHJpbmcoY2hpbGRyZW4pID8gOCA6IDE2Ow0KICB9DQogIGlmICh2bm9kZS5rZXkgIT09IHZub2RlLmtleSkgew0KICAgIHdhcm4kMShgVk5vZGUgY3JlYXRlZCB3aXRoIGludmFsaWQga2V5IChOYU4pLiBWTm9kZSB0eXBlOmAsIHZub2RlLnR5cGUpOw0KICB9DQogIGlmIChpc0Jsb2NrVHJlZUVuYWJsZWQgPiAwICYmIC8vIGF2b2lkIGEgYmxvY2sgbm9kZSBmcm9tIHRyYWNraW5nIGl0c2VsZg0KICAhaXNCbG9ja05vZGUgJiYgLy8gaGFzIGN1cnJlbnQgcGFyZW50IGJsb2NrDQogIGN1cnJlbnRCbG9jayAmJiAvLyBwcmVzZW5jZSBvZiBhIHBhdGNoIGZsYWcgaW5kaWNhdGVzIHRoaXMgbm9kZSBuZWVkcyBwYXRjaGluZyBvbiB1cGRhdGVzLg0KICAvLyBjb21wb25lbnQgbm9kZXMgYWxzbyBzaG91bGQgYWx3YXlzIGJlIHBhdGNoZWQsIGJlY2F1c2UgZXZlbiBpZiB0aGUNCiAgLy8gY29tcG9uZW50IGRvZXNuJ3QgbmVlZCB0byB1cGRhdGUsIGl0IG5lZWRzIHRvIHBlcnNpc3QgdGhlIGluc3RhbmNlIG9uIHRvDQogIC8vIHRoZSBuZXh0IHZub2RlIHNvIHRoYXQgaXQgY2FuIGJlIHByb3Blcmx5IHVubW91bnRlZCBsYXRlci4NCiAgKHZub2RlLnBhdGNoRmxhZyA+IDAgfHwgc2hhcGVGbGFnICYgNikgJiYgLy8gdGhlIEVWRU5UUyBmbGFnIGlzIG9ubHkgZm9yIGh5ZHJhdGlvbiBhbmQgaWYgaXQgaXMgdGhlIG9ubHkgZmxhZywgdGhlDQogIC8vIHZub2RlIHNob3VsZCBub3QgYmUgY29uc2lkZXJlZCBkeW5hbWljIGR1ZSB0byBoYW5kbGVyIGNhY2hpbmcuDQogIHZub2RlLnBhdGNoRmxhZyAhPT0gMzIpIHsNCiAgICBjdXJyZW50QmxvY2sucHVzaCh2bm9kZSk7DQogIH0NCiAgcmV0dXJuIHZub2RlOw0KfQ0KY29uc3QgY3JlYXRlVk5vZGUgPSBjcmVhdGVWTm9kZVdpdGhBcmdzVHJhbnNmb3JtIDsNCmZ1bmN0aW9uIF9jcmVhdGVWTm9kZSh0eXBlLCBwcm9wcyA9IG51bGwsIGNoaWxkcmVuID0gbnVsbCwgcGF0Y2hGbGFnID0gMCwgZHluYW1pY1Byb3BzID0gbnVsbCwgaXNCbG9ja05vZGUgPSBmYWxzZSkgew0KICBpZiAoIXR5cGUgfHwgdHlwZSA9PT0gTlVMTF9EWU5BTUlDX0NPTVBPTkVOVCkgew0KICAgIGlmICghdHlwZSkgew0KICAgICAgd2FybiQxKGBJbnZhbGlkIHZub2RlIHR5cGUgd2hlbiBjcmVhdGluZyB2bm9kZTogJHt0eXBlfS5gKTsNCiAgICB9DQogICAgdHlwZSA9IENvbW1lbnQ7DQogIH0NCiAgaWYgKGlzVk5vZGUodHlwZSkpIHsNCiAgICBjb25zdCBjbG9uZWQgPSBjbG9uZVZOb2RlKA0KICAgICAgdHlwZSwNCiAgICAgIHByb3BzLA0KICAgICAgdHJ1ZQ0KICAgICAgLyogbWVyZ2VSZWY6IHRydWUgKi8NCiAgICApOw0KICAgIGlmIChjaGlsZHJlbikgew0KICAgICAgbm9ybWFsaXplQ2hpbGRyZW4oY2xvbmVkLCBjaGlsZHJlbik7DQogICAgfQ0KICAgIGlmIChpc0Jsb2NrVHJlZUVuYWJsZWQgPiAwICYmICFpc0Jsb2NrTm9kZSAmJiBjdXJyZW50QmxvY2spIHsNCiAgICAgIGlmIChjbG9uZWQuc2hhcGVGbGFnICYgNikgew0KICAgICAgICBjdXJyZW50QmxvY2tbY3VycmVudEJsb2NrLmluZGV4T2YodHlwZSldID0gY2xvbmVkOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgY3VycmVudEJsb2NrLnB1c2goY2xvbmVkKTsNCiAgICAgIH0NCiAgICB9DQogICAgY2xvbmVkLnBhdGNoRmxhZyA9IC0yOw0KICAgIHJldHVybiBjbG9uZWQ7DQogIH0NCiAgaWYgKGlzQ2xhc3NDb21wb25lbnQodHlwZSkpIHsNCiAgICB0eXBlID0gdHlwZS5fX3ZjY09wdHM7DQogIH0NCiAgaWYgKHByb3BzKSB7DQogICAgcHJvcHMgPSBndWFyZFJlYWN0aXZlUHJvcHMocHJvcHMpOw0KICAgIGxldCB7IGNsYXNzOiBrbGFzcywgc3R5bGUgfSA9IHByb3BzOw0KICAgIGlmIChrbGFzcyAmJiAhaXNTdHJpbmcoa2xhc3MpKSB7DQogICAgICBwcm9wcy5jbGFzcyA9IG5vcm1hbGl6ZUNsYXNzKGtsYXNzKTsNCiAgICB9DQogICAgaWYgKGlzT2JqZWN0KHN0eWxlKSkgew0KICAgICAgaWYgKGlzUHJveHkoc3R5bGUpICYmICFpc0FycmF5KHN0eWxlKSkgew0KICAgICAgICBzdHlsZSA9IGV4dGVuZCh7fSwgc3R5bGUpOw0KICAgICAgfQ0KICAgICAgcHJvcHMuc3R5bGUgPSBub3JtYWxpemVTdHlsZShzdHlsZSk7DQogICAgfQ0KICB9DQogIGNvbnN0IHNoYXBlRmxhZyA9IGlzU3RyaW5nKHR5cGUpID8gMSA6IGlzU3VzcGVuc2UodHlwZSkgPyAxMjggOiBpc1RlbGVwb3J0KHR5cGUpID8gNjQgOiBpc09iamVjdCh0eXBlKSA/IDQgOiBpc0Z1bmN0aW9uKHR5cGUpID8gMiA6IDA7DQogIGlmIChzaGFwZUZsYWcgJiA0ICYmIGlzUHJveHkodHlwZSkpIHsNCiAgICB0eXBlID0gdG9SYXcodHlwZSk7DQogICAgd2FybiQxKA0KICAgICAgYFZ1ZSByZWNlaXZlZCBhIENvbXBvbmVudCB0aGF0IHdhcyBtYWRlIGEgcmVhY3RpdmUgb2JqZWN0LiBUaGlzIGNhbiBsZWFkIHRvIHVubmVjZXNzYXJ5IHBlcmZvcm1hbmNlIG92ZXJoZWFkIGFuZCBzaG91bGQgYmUgYXZvaWRlZCBieSBtYXJraW5nIHRoZSBjb21wb25lbnQgd2l0aCBcYG1hcmtSYXdcYCBvciB1c2luZyBcYHNoYWxsb3dSZWZcYCBpbnN0ZWFkIG9mIFxgcmVmXGAuYCwNCiAgICAgIGANCkNvbXBvbmVudCB0aGF0IHdhcyBtYWRlIHJlYWN0aXZlOiBgLA0KICAgICAgdHlwZQ0KICAgICk7DQogIH0NCiAgcmV0dXJuIGNyZWF0ZUJhc2VWTm9kZSgNCiAgICB0eXBlLA0KICAgIHByb3BzLA0KICAgIGNoaWxkcmVuLA0KICAgIHBhdGNoRmxhZywNCiAgICBkeW5hbWljUHJvcHMsDQogICAgc2hhcGVGbGFnLA0KICAgIGlzQmxvY2tOb2RlLA0KICAgIHRydWUNCiAgKTsNCn0NCmZ1bmN0aW9uIGd1YXJkUmVhY3RpdmVQcm9wcyhwcm9wcykgew0KICBpZiAoIXByb3BzKSByZXR1cm4gbnVsbDsNCiAgcmV0dXJuIGlzUHJveHkocHJvcHMpIHx8IGlzSW50ZXJuYWxPYmplY3QocHJvcHMpID8gZXh0ZW5kKHt9LCBwcm9wcykgOiBwcm9wczsNCn0NCmZ1bmN0aW9uIGNsb25lVk5vZGUodm5vZGUsIGV4dHJhUHJvcHMsIG1lcmdlUmVmID0gZmFsc2UsIGNsb25lVHJhbnNpdGlvbiA9IGZhbHNlKSB7DQogIGNvbnN0IHsgcHJvcHMsIHJlZiwgcGF0Y2hGbGFnLCBjaGlsZHJlbiwgdHJhbnNpdGlvbiB9ID0gdm5vZGU7DQogIGNvbnN0IG1lcmdlZFByb3BzID0gZXh0cmFQcm9wcyA/IG1lcmdlUHJvcHMocHJvcHMgfHwge30sIGV4dHJhUHJvcHMpIDogcHJvcHM7DQogIGNvbnN0IGNsb25lZCA9IHsNCiAgICBfX3ZfaXNWTm9kZTogdHJ1ZSwNCiAgICBfX3Zfc2tpcDogdHJ1ZSwNCiAgICB0eXBlOiB2bm9kZS50eXBlLA0KICAgIHByb3BzOiBtZXJnZWRQcm9wcywNCiAgICBrZXk6IG1lcmdlZFByb3BzICYmIG5vcm1hbGl6ZUtleShtZXJnZWRQcm9wcyksDQogICAgcmVmOiBleHRyYVByb3BzICYmIGV4dHJhUHJvcHMucmVmID8gKA0KICAgICAgLy8gIzIwNzggaW4gdGhlIGNhc2Ugb2YgPGNvbXBvbmVudCA6aXM9InZub2RlIiByZWY9ImV4dHJhIi8+DQogICAgICAvLyBpZiB0aGUgdm5vZGUgaXRzZWxmIGFscmVhZHkgaGFzIGEgcmVmLCBjbG9uZVZOb2RlIHdpbGwgbmVlZCB0byBtZXJnZQ0KICAgICAgLy8gdGhlIHJlZnMgc28gdGhlIHNpbmdsZSB2bm9kZSBjYW4gYmUgc2V0IG9uIG11bHRpcGxlIHJlZnMNCiAgICAgIG1lcmdlUmVmICYmIHJlZiA/IGlzQXJyYXkocmVmKSA/IHJlZi5jb25jYXQobm9ybWFsaXplUmVmKGV4dHJhUHJvcHMpKSA6IFtyZWYsIG5vcm1hbGl6ZVJlZihleHRyYVByb3BzKV0gOiBub3JtYWxpemVSZWYoZXh0cmFQcm9wcykNCiAgICApIDogcmVmLA0KICAgIHNjb3BlSWQ6IHZub2RlLnNjb3BlSWQsDQogICAgc2xvdFNjb3BlSWRzOiB2bm9kZS5zbG90U2NvcGVJZHMsDQogICAgY2hpbGRyZW46IHBhdGNoRmxhZyA9PT0gLTEgJiYgaXNBcnJheShjaGlsZHJlbikgPyBjaGlsZHJlbi5tYXAoZGVlcENsb25lVk5vZGUpIDogY2hpbGRyZW4sDQogICAgdGFyZ2V0OiB2bm9kZS50YXJnZXQsDQogICAgdGFyZ2V0U3RhcnQ6IHZub2RlLnRhcmdldFN0YXJ0LA0KICAgIHRhcmdldEFuY2hvcjogdm5vZGUudGFyZ2V0QW5jaG9yLA0KICAgIHN0YXRpY0NvdW50OiB2bm9kZS5zdGF0aWNDb3VudCwNCiAgICBzaGFwZUZsYWc6IHZub2RlLnNoYXBlRmxhZywNCiAgICAvLyBpZiB0aGUgdm5vZGUgaXMgY2xvbmVkIHdpdGggZXh0cmEgcHJvcHMsIHdlIGNhbiBubyBsb25nZXIgYXNzdW1lIGl0cw0KICAgIC8vIGV4aXN0aW5nIHBhdGNoIGZsYWcgdG8gYmUgcmVsaWFibGUgYW5kIG5lZWQgdG8gYWRkIHRoZSBGVUxMX1BST1BTIGZsYWcuDQogICAgLy8gbm90ZTogcHJlc2VydmUgZmxhZyBmb3IgZnJhZ21lbnRzIHNpbmNlIHRoZXkgdXNlIHRoZSBmbGFnIGZvciBjaGlsZHJlbg0KICAgIC8vIGZhc3QgcGF0aHMgb25seS4NCiAgICBwYXRjaEZsYWc6IGV4dHJhUHJvcHMgJiYgdm5vZGUudHlwZSAhPT0gRnJhZ21lbnQgPyBwYXRjaEZsYWcgPT09IC0xID8gMTYgOiBwYXRjaEZsYWcgfCAxNiA6IHBhdGNoRmxhZywNCiAgICBkeW5hbWljUHJvcHM6IHZub2RlLmR5bmFtaWNQcm9wcywNCiAgICBkeW5hbWljQ2hpbGRyZW46IHZub2RlLmR5bmFtaWNDaGlsZHJlbiwNCiAgICBhcHBDb250ZXh0OiB2bm9kZS5hcHBDb250ZXh0LA0KICAgIGRpcnM6IHZub2RlLmRpcnMsDQogICAgdHJhbnNpdGlvbiwNCiAgICAvLyBUaGVzZSBzaG91bGQgdGVjaG5pY2FsbHkgb25seSBiZSBub24tbnVsbCBvbiBtb3VudGVkIFZOb2Rlcy4gSG93ZXZlciwNCiAgICAvLyB0aGV5ICpzaG91bGQqIGJlIGNvcGllZCBmb3Iga2VwdC1hbGl2ZSB2bm9kZXMuIFNvIHdlIGp1c3QgYWx3YXlzIGNvcHkNCiAgICAvLyB0aGVtIHNpbmNlIHRoZW0gYmVpbmcgbm9uLW51bGwgZHVyaW5nIGEgbW91bnQgZG9lc24ndCBhZmZlY3QgdGhlIGxvZ2ljIGFzDQogICAgLy8gdGhleSB3aWxsIHNpbXBseSBiZSBvdmVyd3JpdHRlbi4NCiAgICBjb21wb25lbnQ6IHZub2RlLmNvbXBvbmVudCwNCiAgICBzdXNwZW5zZTogdm5vZGUuc3VzcGVuc2UsDQogICAgc3NDb250ZW50OiB2bm9kZS5zc0NvbnRlbnQgJiYgY2xvbmVWTm9kZSh2bm9kZS5zc0NvbnRlbnQpLA0KICAgIHNzRmFsbGJhY2s6IHZub2RlLnNzRmFsbGJhY2sgJiYgY2xvbmVWTm9kZSh2bm9kZS5zc0ZhbGxiYWNrKSwNCiAgICBlbDogdm5vZGUuZWwsDQogICAgYW5jaG9yOiB2bm9kZS5hbmNob3IsDQogICAgY3R4OiB2bm9kZS5jdHgsDQogICAgY2U6IHZub2RlLmNlDQogIH07DQogIGlmICh0cmFuc2l0aW9uICYmIGNsb25lVHJhbnNpdGlvbikgew0KICAgIHNldFRyYW5zaXRpb25Ib29rcygNCiAgICAgIGNsb25lZCwNCiAgICAgIHRyYW5zaXRpb24uY2xvbmUoY2xvbmVkKQ0KICAgICk7DQogIH0NCiAgcmV0dXJuIGNsb25lZDsNCn0NCmZ1bmN0aW9uIGRlZXBDbG9uZVZOb2RlKHZub2RlKSB7DQogIGNvbnN0IGNsb25lZCA9IGNsb25lVk5vZGUodm5vZGUpOw0KICBpZiAoaXNBcnJheSh2bm9kZS5jaGlsZHJlbikpIHsNCiAgICBjbG9uZWQuY2hpbGRyZW4gPSB2bm9kZS5jaGlsZHJlbi5tYXAoZGVlcENsb25lVk5vZGUpOw0KICB9DQogIHJldHVybiBjbG9uZWQ7DQp9DQpmdW5jdGlvbiBjcmVhdGVUZXh0Vk5vZGUodGV4dCA9ICIgIiwgZmxhZyA9IDApIHsNCiAgcmV0dXJuIGNyZWF0ZVZOb2RlKFRleHQsIG51bGwsIHRleHQsIGZsYWcpOw0KfQ0KZnVuY3Rpb24gY3JlYXRlU3RhdGljVk5vZGUoY29udGVudCwgbnVtYmVyT2ZOb2Rlcykgew0KICBjb25zdCB2bm9kZSA9IGNyZWF0ZVZOb2RlKFN0YXRpYywgbnVsbCwgY29udGVudCk7DQogIHZub2RlLnN0YXRpY0NvdW50ID0gbnVtYmVyT2ZOb2RlczsNCiAgcmV0dXJuIHZub2RlOw0KfQ0KZnVuY3Rpb24gY3JlYXRlQ29tbWVudFZOb2RlKHRleHQgPSAiIiwgYXNCbG9jayA9IGZhbHNlKSB7DQogIHJldHVybiBhc0Jsb2NrID8gKG9wZW5CbG9jaygpLCBjcmVhdGVCbG9jayhDb21tZW50LCBudWxsLCB0ZXh0KSkgOiBjcmVhdGVWTm9kZShDb21tZW50LCBudWxsLCB0ZXh0KTsNCn0NCmZ1bmN0aW9uIG5vcm1hbGl6ZVZOb2RlKGNoaWxkKSB7DQogIGlmIChjaGlsZCA9PSBudWxsIHx8IHR5cGVvZiBjaGlsZCA9PT0gImJvb2xlYW4iKSB7DQogICAgcmV0dXJuIGNyZWF0ZVZOb2RlKENvbW1lbnQpOw0KICB9IGVsc2UgaWYgKGlzQXJyYXkoY2hpbGQpKSB7DQogICAgcmV0dXJuIGNyZWF0ZVZOb2RlKA0KICAgICAgRnJhZ21lbnQsDQogICAgICBudWxsLA0KICAgICAgLy8gIzM2NjYsIGF2b2lkIHJlZmVyZW5jZSBwb2xsdXRpb24gd2hlbiByZXVzaW5nIHZub2RlDQogICAgICBjaGlsZC5zbGljZSgpDQogICAgKTsNCiAgfSBlbHNlIGlmIChpc1ZOb2RlKGNoaWxkKSkgew0KICAgIHJldHVybiBjbG9uZUlmTW91bnRlZChjaGlsZCk7DQogIH0gZWxzZSB7DQogICAgcmV0dXJuIGNyZWF0ZVZOb2RlKFRleHQsIG51bGwsIFN0cmluZyhjaGlsZCkpOw0KICB9DQp9DQpmdW5jdGlvbiBjbG9uZUlmTW91bnRlZChjaGlsZCkgew0KICByZXR1cm4gY2hpbGQuZWwgPT09IG51bGwgJiYgY2hpbGQucGF0Y2hGbGFnICE9PSAtMSB8fCBjaGlsZC5tZW1vID8gY2hpbGQgOiBjbG9uZVZOb2RlKGNoaWxkKTsNCn0NCmZ1bmN0aW9uIG5vcm1hbGl6ZUNoaWxkcmVuKHZub2RlLCBjaGlsZHJlbikgew0KICBsZXQgdHlwZSA9IDA7DQogIGNvbnN0IHsgc2hhcGVGbGFnIH0gPSB2bm9kZTsNCiAgaWYgKGNoaWxkcmVuID09IG51bGwpIHsNCiAgICBjaGlsZHJlbiA9IG51bGw7DQogIH0gZWxzZSBpZiAoaXNBcnJheShjaGlsZHJlbikpIHsNCiAgICB0eXBlID0gMTY7DQogIH0gZWxzZSBpZiAodHlwZW9mIGNoaWxkcmVuID09PSAib2JqZWN0Iikgew0KICAgIGlmIChzaGFwZUZsYWcgJiAoMSB8IDY0KSkgew0KICAgICAgY29uc3Qgc2xvdCA9IGNoaWxkcmVuLmRlZmF1bHQ7DQogICAgICBpZiAoc2xvdCkgew0KICAgICAgICBzbG90Ll9jICYmIChzbG90Ll9kID0gZmFsc2UpOw0KICAgICAgICBub3JtYWxpemVDaGlsZHJlbih2bm9kZSwgc2xvdCgpKTsNCiAgICAgICAgc2xvdC5fYyAmJiAoc2xvdC5fZCA9IHRydWUpOw0KICAgICAgfQ0KICAgICAgcmV0dXJuOw0KICAgIH0gZWxzZSB7DQogICAgICB0eXBlID0gMzI7DQogICAgICBjb25zdCBzbG90RmxhZyA9IGNoaWxkcmVuLl87DQogICAgICBpZiAoIXNsb3RGbGFnICYmICFpc0ludGVybmFsT2JqZWN0KGNoaWxkcmVuKSkgew0KICAgICAgICBjaGlsZHJlbi5fY3R4ID0gY3VycmVudFJlbmRlcmluZ0luc3RhbmNlOw0KICAgICAgfSBlbHNlIGlmIChzbG90RmxhZyA9PT0gMyAmJiBjdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UpIHsNCiAgICAgICAgaWYgKGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZS5zbG90cy5fID09PSAxKSB7DQogICAgICAgICAgY2hpbGRyZW4uXyA9IDE7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgY2hpbGRyZW4uXyA9IDI7DQogICAgICAgICAgdm5vZGUucGF0Y2hGbGFnIHw9IDEwMjQ7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH0gZWxzZSBpZiAoaXNGdW5jdGlvbihjaGlsZHJlbikpIHsNCiAgICBjaGlsZHJlbiA9IHsgZGVmYXVsdDogY2hpbGRyZW4sIF9jdHg6IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSB9Ow0KICAgIHR5cGUgPSAzMjsNCiAgfSBlbHNlIHsNCiAgICBjaGlsZHJlbiA9IFN0cmluZyhjaGlsZHJlbik7DQogICAgaWYgKHNoYXBlRmxhZyAmIDY0KSB7DQogICAgICB0eXBlID0gMTY7DQogICAgICBjaGlsZHJlbiA9IFtjcmVhdGVUZXh0Vk5vZGUoY2hpbGRyZW4pXTsNCiAgICB9IGVsc2Ugew0KICAgICAgdHlwZSA9IDg7DQogICAgfQ0KICB9DQogIHZub2RlLmNoaWxkcmVuID0gY2hpbGRyZW47DQogIHZub2RlLnNoYXBlRmxhZyB8PSB0eXBlOw0KfQ0KZnVuY3Rpb24gbWVyZ2VQcm9wcyguLi5hcmdzKSB7DQogIGNvbnN0IHJldCA9IHt9Ow0KICBmb3IgKGxldCBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHsNCiAgICBjb25zdCB0b01lcmdlID0gYXJnc1tpXTsNCiAgICBmb3IgKGNvbnN0IGtleSBpbiB0b01lcmdlKSB7DQogICAgICBpZiAoa2V5ID09PSAiY2xhc3MiKSB7DQogICAgICAgIGlmIChyZXQuY2xhc3MgIT09IHRvTWVyZ2UuY2xhc3MpIHsNCiAgICAgICAgICByZXQuY2xhc3MgPSBub3JtYWxpemVDbGFzcyhbcmV0LmNsYXNzLCB0b01lcmdlLmNsYXNzXSk7DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSBpZiAoa2V5ID09PSAic3R5bGUiKSB7DQogICAgICAgIHJldC5zdHlsZSA9IG5vcm1hbGl6ZVN0eWxlKFtyZXQuc3R5bGUsIHRvTWVyZ2Uuc3R5bGVdKTsNCiAgICAgIH0gZWxzZSBpZiAoaXNPbihrZXkpKSB7DQogICAgICAgIGNvbnN0IGV4aXN0aW5nID0gcmV0W2tleV07DQogICAgICAgIGNvbnN0IGluY29taW5nID0gdG9NZXJnZVtrZXldOw0KICAgICAgICBpZiAoaW5jb21pbmcgJiYgZXhpc3RpbmcgIT09IGluY29taW5nICYmICEoaXNBcnJheShleGlzdGluZykgJiYgZXhpc3RpbmcuaW5jbHVkZXMoaW5jb21pbmcpKSkgew0KICAgICAgICAgIHJldFtrZXldID0gZXhpc3RpbmcgPyBbXS5jb25jYXQoZXhpc3RpbmcsIGluY29taW5nKSA6IGluY29taW5nOw0KICAgICAgICB9DQogICAgICB9IGVsc2UgaWYgKGtleSAhPT0gIiIpIHsNCiAgICAgICAgcmV0W2tleV0gPSB0b01lcmdlW2tleV07DQogICAgICB9DQogICAgfQ0KICB9DQogIHJldHVybiByZXQ7DQp9DQpmdW5jdGlvbiBpbnZva2VWTm9kZUhvb2soaG9vaywgaW5zdGFuY2UsIHZub2RlLCBwcmV2Vk5vZGUgPSBudWxsKSB7DQogIGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nKGhvb2ssIGluc3RhbmNlLCA3LCBbDQogICAgdm5vZGUsDQogICAgcHJldlZOb2RlDQogIF0pOw0KfQ0KDQpjb25zdCBlbXB0eUFwcENvbnRleHQgPSBjcmVhdGVBcHBDb250ZXh0KCk7DQpsZXQgdWlkID0gMDsNCmZ1bmN0aW9uIGNyZWF0ZUNvbXBvbmVudEluc3RhbmNlKHZub2RlLCBwYXJlbnQsIHN1c3BlbnNlKSB7DQogIGNvbnN0IHR5cGUgPSB2bm9kZS50eXBlOw0KICBjb25zdCBhcHBDb250ZXh0ID0gKHBhcmVudCA/IHBhcmVudC5hcHBDb250ZXh0IDogdm5vZGUuYXBwQ29udGV4dCkgfHwgZW1wdHlBcHBDb250ZXh0Ow0KICBjb25zdCBpbnN0YW5jZSA9IHsNCiAgICB1aWQ6IHVpZCsrLA0KICAgIHZub2RlLA0KICAgIHR5cGUsDQogICAgcGFyZW50LA0KICAgIGFwcENvbnRleHQsDQogICAgcm9vdDogbnVsbCwNCiAgICAvLyB0byBiZSBpbW1lZGlhdGVseSBzZXQNCiAgICBuZXh0OiBudWxsLA0KICAgIHN1YlRyZWU6IG51bGwsDQogICAgLy8gd2lsbCBiZSBzZXQgc3luY2hyb25vdXNseSByaWdodCBhZnRlciBjcmVhdGlvbg0KICAgIGVmZmVjdDogbnVsbCwNCiAgICB1cGRhdGU6IG51bGwsDQogICAgLy8gd2lsbCBiZSBzZXQgc3luY2hyb25vdXNseSByaWdodCBhZnRlciBjcmVhdGlvbg0KICAgIGpvYjogbnVsbCwNCiAgICBzY29wZTogbmV3IEVmZmVjdFNjb3BlKA0KICAgICAgdHJ1ZQ0KICAgICAgLyogZGV0YWNoZWQgKi8NCiAgICApLA0KICAgIHJlbmRlcjogbnVsbCwNCiAgICBwcm94eTogbnVsbCwNCiAgICBleHBvc2VkOiBudWxsLA0KICAgIGV4cG9zZVByb3h5OiBudWxsLA0KICAgIHdpdGhQcm94eTogbnVsbCwNCiAgICBwcm92aWRlczogcGFyZW50ID8gcGFyZW50LnByb3ZpZGVzIDogT2JqZWN0LmNyZWF0ZShhcHBDb250ZXh0LnByb3ZpZGVzKSwNCiAgICBpZHM6IHBhcmVudCA/IHBhcmVudC5pZHMgOiBbIiIsIDAsIDBdLA0KICAgIGFjY2Vzc0NhY2hlOiBudWxsLA0KICAgIHJlbmRlckNhY2hlOiBbXSwNCiAgICAvLyBsb2NhbCByZXNvbHZlZCBhc3NldHMNCiAgICBjb21wb25lbnRzOiBudWxsLA0KICAgIGRpcmVjdGl2ZXM6IG51bGwsDQogICAgLy8gcmVzb2x2ZWQgcHJvcHMgYW5kIGVtaXRzIG9wdGlvbnMNCiAgICBwcm9wc09wdGlvbnM6IG5vcm1hbGl6ZVByb3BzT3B0aW9ucyh0eXBlLCBhcHBDb250ZXh0KSwNCiAgICBlbWl0c09wdGlvbnM6IG5vcm1hbGl6ZUVtaXRzT3B0aW9ucyh0eXBlLCBhcHBDb250ZXh0KSwNCiAgICAvLyBlbWl0DQogICAgZW1pdDogbnVsbCwNCiAgICAvLyB0byBiZSBzZXQgaW1tZWRpYXRlbHkNCiAgICBlbWl0dGVkOiBudWxsLA0KICAgIC8vIHByb3BzIGRlZmF1bHQgdmFsdWUNCiAgICBwcm9wc0RlZmF1bHRzOiBFTVBUWV9PQkosDQogICAgLy8gaW5oZXJpdEF0dHJzDQogICAgaW5oZXJpdEF0dHJzOiB0eXBlLmluaGVyaXRBdHRycywNCiAgICAvLyBzdGF0ZQ0KICAgIGN0eDogRU1QVFlfT0JKLA0KICAgIGRhdGE6IEVNUFRZX09CSiwNCiAgICBwcm9wczogRU1QVFlfT0JKLA0KICAgIGF0dHJzOiBFTVBUWV9PQkosDQogICAgc2xvdHM6IEVNUFRZX09CSiwNCiAgICByZWZzOiBFTVBUWV9PQkosDQogICAgc2V0dXBTdGF0ZTogRU1QVFlfT0JKLA0KICAgIHNldHVwQ29udGV4dDogbnVsbCwNCiAgICAvLyBzdXNwZW5zZSByZWxhdGVkDQogICAgc3VzcGVuc2UsDQogICAgc3VzcGVuc2VJZDogc3VzcGVuc2UgPyBzdXNwZW5zZS5wZW5kaW5nSWQgOiAwLA0KICAgIGFzeW5jRGVwOiBudWxsLA0KICAgIGFzeW5jUmVzb2x2ZWQ6IGZhbHNlLA0KICAgIC8vIGxpZmVjeWNsZSBob29rcw0KICAgIC8vIG5vdCB1c2luZyBlbnVtcyBoZXJlIGJlY2F1c2UgaXQgcmVzdWx0cyBpbiBjb21wdXRlZCBwcm9wZXJ0aWVzDQogICAgaXNNb3VudGVkOiBmYWxzZSwNCiAgICBpc1VubW91bnRlZDogZmFsc2UsDQogICAgaXNEZWFjdGl2YXRlZDogZmFsc2UsDQogICAgYmM6IG51bGwsDQogICAgYzogbnVsbCwNCiAgICBibTogbnVsbCwNCiAgICBtOiBudWxsLA0KICAgIGJ1OiBudWxsLA0KICAgIHU6IG51bGwsDQogICAgdW06IG51bGwsDQogICAgYnVtOiBudWxsLA0KICAgIGRhOiBudWxsLA0KICAgIGE6IG51bGwsDQogICAgcnRnOiBudWxsLA0KICAgIHJ0YzogbnVsbCwNCiAgICBlYzogbnVsbCwNCiAgICBzcDogbnVsbA0KICB9Ow0KICB7DQogICAgaW5zdGFuY2UuY3R4ID0gY3JlYXRlRGV2UmVuZGVyQ29udGV4dChpbnN0YW5jZSk7DQogIH0NCiAgaW5zdGFuY2Uucm9vdCA9IHBhcmVudCA/IHBhcmVudC5yb290IDogaW5zdGFuY2U7DQogIGluc3RhbmNlLmVtaXQgPSBlbWl0LmJpbmQobnVsbCwgaW5zdGFuY2UpOw0KICBpZiAodm5vZGUuY2UpIHsNCiAgICB2bm9kZS5jZShpbnN0YW5jZSk7DQogIH0NCiAgcmV0dXJuIGluc3RhbmNlOw0KfQ0KbGV0IGN1cnJlbnRJbnN0YW5jZSA9IG51bGw7DQpjb25zdCBnZXRDdXJyZW50SW5zdGFuY2UgPSAoKSA9PiBjdXJyZW50SW5zdGFuY2UgfHwgY3VycmVudFJlbmRlcmluZ0luc3RhbmNlOw0KbGV0IGludGVybmFsU2V0Q3VycmVudEluc3RhbmNlOw0KbGV0IHNldEluU1NSU2V0dXBTdGF0ZTsNCnsNCiAgY29uc3QgZyA9IGdldEdsb2JhbFRoaXMoKTsNCiAgY29uc3QgcmVnaXN0ZXJHbG9iYWxTZXR0ZXIgPSAoa2V5LCBzZXR0ZXIpID0+IHsNCiAgICBsZXQgc2V0dGVyczsNCiAgICBpZiAoIShzZXR0ZXJzID0gZ1trZXldKSkgc2V0dGVycyA9IGdba2V5XSA9IFtdOw0KICAgIHNldHRlcnMucHVzaChzZXR0ZXIpOw0KICAgIHJldHVybiAodikgPT4gew0KICAgICAgaWYgKHNldHRlcnMubGVuZ3RoID4gMSkgc2V0dGVycy5mb3JFYWNoKChzZXQpID0+IHNldCh2KSk7DQogICAgICBlbHNlIHNldHRlcnNbMF0odik7DQogICAgfTsNCiAgfTsNCiAgaW50ZXJuYWxTZXRDdXJyZW50SW5zdGFuY2UgPSByZWdpc3Rlckdsb2JhbFNldHRlcigNCiAgICBgX19WVUVfSU5TVEFOQ0VfU0VUVEVSU19fYCwNCiAgICAodikgPT4gY3VycmVudEluc3RhbmNlID0gdg0KICApOw0KICBzZXRJblNTUlNldHVwU3RhdGUgPSByZWdpc3Rlckdsb2JhbFNldHRlcigNCiAgICBgX19WVUVfU1NSX1NFVFRFUlNfX2AsDQogICAgKHYpID0+IGlzSW5TU1JDb21wb25lbnRTZXR1cCA9IHYNCiAgKTsNCn0NCmNvbnN0IHNldEN1cnJlbnRJbnN0YW5jZSA9IChpbnN0YW5jZSkgPT4gew0KICBjb25zdCBwcmV2ID0gY3VycmVudEluc3RhbmNlOw0KICBpbnRlcm5hbFNldEN1cnJlbnRJbnN0YW5jZShpbnN0YW5jZSk7DQogIGluc3RhbmNlLnNjb3BlLm9uKCk7DQogIHJldHVybiAoKSA9PiB7DQogICAgaW5zdGFuY2Uuc2NvcGUub2ZmKCk7DQogICAgaW50ZXJuYWxTZXRDdXJyZW50SW5zdGFuY2UocHJldik7DQogIH07DQp9Ow0KY29uc3QgdW5zZXRDdXJyZW50SW5zdGFuY2UgPSAoKSA9PiB7DQogIGN1cnJlbnRJbnN0YW5jZSAmJiBjdXJyZW50SW5zdGFuY2Uuc2NvcGUub2ZmKCk7DQogIGludGVybmFsU2V0Q3VycmVudEluc3RhbmNlKG51bGwpOw0KfTsNCmNvbnN0IGlzQnVpbHRJblRhZyA9IC8qIEBfX1BVUkVfXyAqLyBtYWtlTWFwKCJzbG90LGNvbXBvbmVudCIpOw0KZnVuY3Rpb24gdmFsaWRhdGVDb21wb25lbnROYW1lKG5hbWUsIHsgaXNOYXRpdmVUYWcgfSkgew0KICBpZiAoaXNCdWlsdEluVGFnKG5hbWUpIHx8IGlzTmF0aXZlVGFnKG5hbWUpKSB7DQogICAgd2FybiQxKA0KICAgICAgIkRvIG5vdCB1c2UgYnVpbHQtaW4gb3IgcmVzZXJ2ZWQgSFRNTCBlbGVtZW50cyBhcyBjb21wb25lbnQgaWQ6ICIgKyBuYW1lDQogICAgKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gaXNTdGF0ZWZ1bENvbXBvbmVudChpbnN0YW5jZSkgew0KICByZXR1cm4gaW5zdGFuY2Uudm5vZGUuc2hhcGVGbGFnICYgNDsNCn0NCmxldCBpc0luU1NSQ29tcG9uZW50U2V0dXAgPSBmYWxzZTsNCmZ1bmN0aW9uIHNldHVwQ29tcG9uZW50KGluc3RhbmNlLCBpc1NTUiA9IGZhbHNlLCBvcHRpbWl6ZWQgPSBmYWxzZSkgew0KICBpc1NTUiAmJiBzZXRJblNTUlNldHVwU3RhdGUoaXNTU1IpOw0KICBjb25zdCB7IHByb3BzLCBjaGlsZHJlbiB9ID0gaW5zdGFuY2Uudm5vZGU7DQogIGNvbnN0IGlzU3RhdGVmdWwgPSBpc1N0YXRlZnVsQ29tcG9uZW50KGluc3RhbmNlKTsNCiAgaW5pdFByb3BzKGluc3RhbmNlLCBwcm9wcywgaXNTdGF0ZWZ1bCwgaXNTU1IpOw0KICBpbml0U2xvdHMoaW5zdGFuY2UsIGNoaWxkcmVuLCBvcHRpbWl6ZWQgfHwgaXNTU1IpOw0KICBjb25zdCBzZXR1cFJlc3VsdCA9IGlzU3RhdGVmdWwgPyBzZXR1cFN0YXRlZnVsQ29tcG9uZW50KGluc3RhbmNlLCBpc1NTUikgOiB2b2lkIDA7DQogIGlzU1NSICYmIHNldEluU1NSU2V0dXBTdGF0ZShmYWxzZSk7DQogIHJldHVybiBzZXR1cFJlc3VsdDsNCn0NCmZ1bmN0aW9uIHNldHVwU3RhdGVmdWxDb21wb25lbnQoaW5zdGFuY2UsIGlzU1NSKSB7DQogIHZhciBfYTsNCiAgY29uc3QgQ29tcG9uZW50ID0gaW5zdGFuY2UudHlwZTsNCiAgew0KICAgIGlmIChDb21wb25lbnQubmFtZSkgew0KICAgICAgdmFsaWRhdGVDb21wb25lbnROYW1lKENvbXBvbmVudC5uYW1lLCBpbnN0YW5jZS5hcHBDb250ZXh0LmNvbmZpZyk7DQogICAgfQ0KICAgIGlmIChDb21wb25lbnQuY29tcG9uZW50cykgew0KICAgICAgY29uc3QgbmFtZXMgPSBPYmplY3Qua2V5cyhDb21wb25lbnQuY29tcG9uZW50cyk7DQogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5hbWVzLmxlbmd0aDsgaSsrKSB7DQogICAgICAgIHZhbGlkYXRlQ29tcG9uZW50TmFtZShuYW1lc1tpXSwgaW5zdGFuY2UuYXBwQ29udGV4dC5jb25maWcpOw0KICAgICAgfQ0KICAgIH0NCiAgICBpZiAoQ29tcG9uZW50LmRpcmVjdGl2ZXMpIHsNCiAgICAgIGNvbnN0IG5hbWVzID0gT2JqZWN0LmtleXMoQ29tcG9uZW50LmRpcmVjdGl2ZXMpOw0KICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuYW1lcy5sZW5ndGg7IGkrKykgew0KICAgICAgICB2YWxpZGF0ZURpcmVjdGl2ZU5hbWUobmFtZXNbaV0pOw0KICAgICAgfQ0KICAgIH0NCiAgICBpZiAoQ29tcG9uZW50LmNvbXBpbGVyT3B0aW9ucyAmJiBpc1J1bnRpbWVPbmx5KCkpIHsNCiAgICAgIHdhcm4kMSgNCiAgICAgICAgYCJjb21waWxlck9wdGlvbnMiIGlzIG9ubHkgc3VwcG9ydGVkIHdoZW4gdXNpbmcgYSBidWlsZCBvZiBWdWUgdGhhdCBpbmNsdWRlcyB0aGUgcnVudGltZSBjb21waWxlci4gU2luY2UgeW91IGFyZSB1c2luZyBhIHJ1bnRpbWUtb25seSBidWlsZCwgdGhlIG9wdGlvbnMgc2hvdWxkIGJlIHBhc3NlZCB2aWEgeW91ciBidWlsZCB0b29sIGNvbmZpZyBpbnN0ZWFkLmANCiAgICAgICk7DQogICAgfQ0KICB9DQogIGluc3RhbmNlLmFjY2Vzc0NhY2hlID0gLyogQF9fUFVSRV9fICovIE9iamVjdC5jcmVhdGUobnVsbCk7DQogIGluc3RhbmNlLnByb3h5ID0gbmV3IFByb3h5KGluc3RhbmNlLmN0eCwgUHVibGljSW5zdGFuY2VQcm94eUhhbmRsZXJzKTsNCiAgew0KICAgIGV4cG9zZVByb3BzT25SZW5kZXJDb250ZXh0KGluc3RhbmNlKTsNCiAgfQ0KICBjb25zdCB7IHNldHVwIH0gPSBDb21wb25lbnQ7DQogIGlmIChzZXR1cCkgew0KICAgIHBhdXNlVHJhY2tpbmcoKTsNCiAgICBjb25zdCBzZXR1cENvbnRleHQgPSBpbnN0YW5jZS5zZXR1cENvbnRleHQgPSBzZXR1cC5sZW5ndGggPiAxID8gY3JlYXRlU2V0dXBDb250ZXh0KGluc3RhbmNlKSA6IG51bGw7DQogICAgY29uc3QgcmVzZXQgPSBzZXRDdXJyZW50SW5zdGFuY2UoaW5zdGFuY2UpOw0KICAgIGNvbnN0IHNldHVwUmVzdWx0ID0gY2FsbFdpdGhFcnJvckhhbmRsaW5nKA0KICAgICAgc2V0dXAsDQogICAgICBpbnN0YW5jZSwNCiAgICAgIDAsDQogICAgICBbDQogICAgICAgIHNoYWxsb3dSZWFkb25seShpbnN0YW5jZS5wcm9wcykgLA0KICAgICAgICBzZXR1cENvbnRleHQNCiAgICAgIF0NCiAgICApOw0KICAgIGNvbnN0IGlzQXN5bmNTZXR1cCA9IGlzUHJvbWlzZShzZXR1cFJlc3VsdCk7DQogICAgcmVzZXRUcmFja2luZygpOw0KICAgIHJlc2V0KCk7DQogICAgaWYgKChpc0FzeW5jU2V0dXAgfHwgaW5zdGFuY2Uuc3ApICYmICFpc0FzeW5jV3JhcHBlcihpbnN0YW5jZSkpIHsNCiAgICAgIG1hcmtBc3luY0JvdW5kYXJ5KGluc3RhbmNlKTsNCiAgICB9DQogICAgaWYgKGlzQXN5bmNTZXR1cCkgew0KICAgICAgc2V0dXBSZXN1bHQudGhlbih1bnNldEN1cnJlbnRJbnN0YW5jZSwgdW5zZXRDdXJyZW50SW5zdGFuY2UpOw0KICAgICAgaWYgKGlzU1NSKSB7DQogICAgICAgIHJldHVybiBzZXR1cFJlc3VsdC50aGVuKChyZXNvbHZlZFJlc3VsdCkgPT4gew0KICAgICAgICAgIGhhbmRsZVNldHVwUmVzdWx0KGluc3RhbmNlLCByZXNvbHZlZFJlc3VsdCwgaXNTU1IpOw0KICAgICAgICB9KS5jYXRjaCgoZSkgPT4gew0KICAgICAgICAgIGhhbmRsZUVycm9yKGUsIGluc3RhbmNlLCAwKTsNCiAgICAgICAgfSk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBpbnN0YW5jZS5hc3luY0RlcCA9IHNldHVwUmVzdWx0Ow0KICAgICAgICBpZiAoIWluc3RhbmNlLnN1c3BlbnNlKSB7DQogICAgICAgICAgY29uc3QgbmFtZSA9IChfYSA9IENvbXBvbmVudC5uYW1lKSAhPSBudWxsID8gX2EgOiAiQW5vbnltb3VzIjsNCiAgICAgICAgICB3YXJuJDEoDQogICAgICAgICAgICBgQ29tcG9uZW50IDwke25hbWV9Pjogc2V0dXAgZnVuY3Rpb24gcmV0dXJuZWQgYSBwcm9taXNlLCBidXQgbm8gPFN1c3BlbnNlPiBib3VuZGFyeSB3YXMgZm91bmQgaW4gdGhlIHBhcmVudCBjb21wb25lbnQgdHJlZS4gQSBjb21wb25lbnQgd2l0aCBhc3luYyBzZXR1cCgpIG11c3QgYmUgbmVzdGVkIGluIGEgPFN1c3BlbnNlPiBpbiBvcmRlciB0byBiZSByZW5kZXJlZC5gDQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0gZWxzZSB7DQogICAgICBoYW5kbGVTZXR1cFJlc3VsdChpbnN0YW5jZSwgc2V0dXBSZXN1bHQsIGlzU1NSKTsNCiAgICB9DQogIH0gZWxzZSB7DQogICAgZmluaXNoQ29tcG9uZW50U2V0dXAoaW5zdGFuY2UsIGlzU1NSKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gaGFuZGxlU2V0dXBSZXN1bHQoaW5zdGFuY2UsIHNldHVwUmVzdWx0LCBpc1NTUikgew0KICBpZiAoaXNGdW5jdGlvbihzZXR1cFJlc3VsdCkpIHsNCiAgICBpZiAoaW5zdGFuY2UudHlwZS5fX3NzcklubGluZVJlbmRlcikgew0KICAgICAgaW5zdGFuY2Uuc3NyUmVuZGVyID0gc2V0dXBSZXN1bHQ7DQogICAgfSBlbHNlIHsNCiAgICAgIGluc3RhbmNlLnJlbmRlciA9IHNldHVwUmVzdWx0Ow0KICAgIH0NCiAgfSBlbHNlIGlmIChpc09iamVjdChzZXR1cFJlc3VsdCkpIHsNCiAgICBpZiAoaXNWTm9kZShzZXR1cFJlc3VsdCkpIHsNCiAgICAgIHdhcm4kMSgNCiAgICAgICAgYHNldHVwKCkgc2hvdWxkIG5vdCByZXR1cm4gVk5vZGVzIGRpcmVjdGx5IC0gcmV0dXJuIGEgcmVuZGVyIGZ1bmN0aW9uIGluc3RlYWQuYA0KICAgICAgKTsNCiAgICB9DQogICAgew0KICAgICAgaW5zdGFuY2UuZGV2dG9vbHNSYXdTZXR1cFN0YXRlID0gc2V0dXBSZXN1bHQ7DQogICAgfQ0KICAgIGluc3RhbmNlLnNldHVwU3RhdGUgPSBwcm94eVJlZnMoc2V0dXBSZXN1bHQpOw0KICAgIHsNCiAgICAgIGV4cG9zZVNldHVwU3RhdGVPblJlbmRlckNvbnRleHQoaW5zdGFuY2UpOw0KICAgIH0NCiAgfSBlbHNlIGlmIChzZXR1cFJlc3VsdCAhPT0gdm9pZCAwKSB7DQogICAgd2FybiQxKA0KICAgICAgYHNldHVwKCkgc2hvdWxkIHJldHVybiBhbiBvYmplY3QuIFJlY2VpdmVkOiAke3NldHVwUmVzdWx0ID09PSBudWxsID8gIm51bGwiIDogdHlwZW9mIHNldHVwUmVzdWx0fWANCiAgICApOw0KICB9DQogIGZpbmlzaENvbXBvbmVudFNldHVwKGluc3RhbmNlLCBpc1NTUik7DQp9DQpsZXQgY29tcGlsZTsNCmxldCBpbnN0YWxsV2l0aFByb3h5Ow0KZnVuY3Rpb24gcmVnaXN0ZXJSdW50aW1lQ29tcGlsZXIoX2NvbXBpbGUpIHsNCiAgY29tcGlsZSA9IF9jb21waWxlOw0KICBpbnN0YWxsV2l0aFByb3h5ID0gKGkpID0+IHsNCiAgICBpZiAoaS5yZW5kZXIuX3JjKSB7DQogICAgICBpLndpdGhQcm94eSA9IG5ldyBQcm94eShpLmN0eCwgUnVudGltZUNvbXBpbGVkUHVibGljSW5zdGFuY2VQcm94eUhhbmRsZXJzKTsNCiAgICB9DQogIH07DQp9DQpjb25zdCBpc1J1bnRpbWVPbmx5ID0gKCkgPT4gIWNvbXBpbGU7DQpmdW5jdGlvbiBmaW5pc2hDb21wb25lbnRTZXR1cChpbnN0YW5jZSwgaXNTU1IsIHNraXBPcHRpb25zKSB7DQogIGNvbnN0IENvbXBvbmVudCA9IGluc3RhbmNlLnR5cGU7DQogIGlmICghaW5zdGFuY2UucmVuZGVyKSB7DQogICAgaWYgKCFpc1NTUiAmJiBjb21waWxlICYmICFDb21wb25lbnQucmVuZGVyKSB7DQogICAgICBjb25zdCB0ZW1wbGF0ZSA9IENvbXBvbmVudC50ZW1wbGF0ZSB8fCByZXNvbHZlTWVyZ2VkT3B0aW9ucyhpbnN0YW5jZSkudGVtcGxhdGU7DQogICAgICBpZiAodGVtcGxhdGUpIHsNCiAgICAgICAgew0KICAgICAgICAgIHN0YXJ0TWVhc3VyZShpbnN0YW5jZSwgYGNvbXBpbGVgKTsNCiAgICAgICAgfQ0KICAgICAgICBjb25zdCB7IGlzQ3VzdG9tRWxlbWVudCwgY29tcGlsZXJPcHRpb25zIH0gPSBpbnN0YW5jZS5hcHBDb250ZXh0LmNvbmZpZzsNCiAgICAgICAgY29uc3QgeyBkZWxpbWl0ZXJzLCBjb21waWxlck9wdGlvbnM6IGNvbXBvbmVudENvbXBpbGVyT3B0aW9ucyB9ID0gQ29tcG9uZW50Ow0KICAgICAgICBjb25zdCBmaW5hbENvbXBpbGVyT3B0aW9ucyA9IGV4dGVuZCgNCiAgICAgICAgICBleHRlbmQoDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgIGlzQ3VzdG9tRWxlbWVudCwNCiAgICAgICAgICAgICAgZGVsaW1pdGVycw0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIGNvbXBpbGVyT3B0aW9ucw0KICAgICAgICAgICksDQogICAgICAgICAgY29tcG9uZW50Q29tcGlsZXJPcHRpb25zDQogICAgICAgICk7DQogICAgICAgIENvbXBvbmVudC5yZW5kZXIgPSBjb21waWxlKHRlbXBsYXRlLCBmaW5hbENvbXBpbGVyT3B0aW9ucyk7DQogICAgICAgIHsNCiAgICAgICAgICBlbmRNZWFzdXJlKGluc3RhbmNlLCBgY29tcGlsZWApOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICAgIGluc3RhbmNlLnJlbmRlciA9IENvbXBvbmVudC5yZW5kZXIgfHwgTk9PUDsNCiAgICBpZiAoaW5zdGFsbFdpdGhQcm94eSkgew0KICAgICAgaW5zdGFsbFdpdGhQcm94eShpbnN0YW5jZSk7DQogICAgfQ0KICB9DQogIHsNCiAgICBjb25zdCByZXNldCA9IHNldEN1cnJlbnRJbnN0YW5jZShpbnN0YW5jZSk7DQogICAgcGF1c2VUcmFja2luZygpOw0KICAgIHRyeSB7DQogICAgICBhcHBseU9wdGlvbnMoaW5zdGFuY2UpOw0KICAgIH0gZmluYWxseSB7DQogICAgICByZXNldFRyYWNraW5nKCk7DQogICAgICByZXNldCgpOw0KICAgIH0NCiAgfQ0KICBpZiAoIUNvbXBvbmVudC5yZW5kZXIgJiYgaW5zdGFuY2UucmVuZGVyID09PSBOT09QICYmICFpc1NTUikgew0KICAgIGlmICghY29tcGlsZSAmJiBDb21wb25lbnQudGVtcGxhdGUpIHsNCiAgICAgIHdhcm4kMSgNCiAgICAgICAgYENvbXBvbmVudCBwcm92aWRlZCB0ZW1wbGF0ZSBvcHRpb24gYnV0IHJ1bnRpbWUgY29tcGlsYXRpb24gaXMgbm90IHN1cHBvcnRlZCBpbiB0aGlzIGJ1aWxkIG9mIFZ1ZS5gICsgKGAgVXNlICJ2dWUuZXNtLWJyb3dzZXIuanMiIGluc3RlYWQuYCApDQogICAgICApOw0KICAgIH0gZWxzZSB7DQogICAgICB3YXJuJDEoYENvbXBvbmVudCBpcyBtaXNzaW5nIHRlbXBsYXRlIG9yIHJlbmRlciBmdW5jdGlvbjogYCwgQ29tcG9uZW50KTsNCiAgICB9DQogIH0NCn0NCmNvbnN0IGF0dHJzUHJveHlIYW5kbGVycyA9IHsNCiAgZ2V0KHRhcmdldCwga2V5KSB7DQogICAgbWFya0F0dHJzQWNjZXNzZWQoKTsNCiAgICB0cmFjayh0YXJnZXQsICJnZXQiLCAiIik7DQogICAgcmV0dXJuIHRhcmdldFtrZXldOw0KICB9LA0KICBzZXQoKSB7DQogICAgd2FybiQxKGBzZXR1cENvbnRleHQuYXR0cnMgaXMgcmVhZG9ubHkuYCk7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9LA0KICBkZWxldGVQcm9wZXJ0eSgpIHsNCiAgICB3YXJuJDEoYHNldHVwQ29udGV4dC5hdHRycyBpcyByZWFkb25seS5gKTsNCiAgICByZXR1cm4gZmFsc2U7DQogIH0NCn0gOw0KZnVuY3Rpb24gZ2V0U2xvdHNQcm94eShpbnN0YW5jZSkgew0KICByZXR1cm4gbmV3IFByb3h5KGluc3RhbmNlLnNsb3RzLCB7DQogICAgZ2V0KHRhcmdldCwga2V5KSB7DQogICAgICB0cmFjayhpbnN0YW5jZSwgImdldCIsICIkc2xvdHMiKTsNCiAgICAgIHJldHVybiB0YXJnZXRba2V5XTsNCiAgICB9DQogIH0pOw0KfQ0KZnVuY3Rpb24gY3JlYXRlU2V0dXBDb250ZXh0KGluc3RhbmNlKSB7DQogIGNvbnN0IGV4cG9zZSA9IChleHBvc2VkKSA9PiB7DQogICAgew0KICAgICAgaWYgKGluc3RhbmNlLmV4cG9zZWQpIHsNCiAgICAgICAgd2FybiQxKGBleHBvc2UoKSBzaG91bGQgYmUgY2FsbGVkIG9ubHkgb25jZSBwZXIgc2V0dXAoKS5gKTsNCiAgICAgIH0NCiAgICAgIGlmIChleHBvc2VkICE9IG51bGwpIHsNCiAgICAgICAgbGV0IGV4cG9zZWRUeXBlID0gdHlwZW9mIGV4cG9zZWQ7DQogICAgICAgIGlmIChleHBvc2VkVHlwZSA9PT0gIm9iamVjdCIpIHsNCiAgICAgICAgICBpZiAoaXNBcnJheShleHBvc2VkKSkgew0KICAgICAgICAgICAgZXhwb3NlZFR5cGUgPSAiYXJyYXkiOw0KICAgICAgICAgIH0gZWxzZSBpZiAoaXNSZWYoZXhwb3NlZCkpIHsNCiAgICAgICAgICAgIGV4cG9zZWRUeXBlID0gInJlZiI7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGlmIChleHBvc2VkVHlwZSAhPT0gIm9iamVjdCIpIHsNCiAgICAgICAgICB3YXJuJDEoDQogICAgICAgICAgICBgZXhwb3NlKCkgc2hvdWxkIGJlIHBhc3NlZCBhIHBsYWluIG9iamVjdCwgcmVjZWl2ZWQgJHtleHBvc2VkVHlwZX0uYA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogICAgaW5zdGFuY2UuZXhwb3NlZCA9IGV4cG9zZWQgfHwge307DQogIH07DQogIHsNCiAgICBsZXQgYXR0cnNQcm94eTsNCiAgICBsZXQgc2xvdHNQcm94eTsNCiAgICByZXR1cm4gT2JqZWN0LmZyZWV6ZSh7DQogICAgICBnZXQgYXR0cnMoKSB7DQogICAgICAgIHJldHVybiBhdHRyc1Byb3h5IHx8IChhdHRyc1Byb3h5ID0gbmV3IFByb3h5KGluc3RhbmNlLmF0dHJzLCBhdHRyc1Byb3h5SGFuZGxlcnMpKTsNCiAgICAgIH0sDQogICAgICBnZXQgc2xvdHMoKSB7DQogICAgICAgIHJldHVybiBzbG90c1Byb3h5IHx8IChzbG90c1Byb3h5ID0gZ2V0U2xvdHNQcm94eShpbnN0YW5jZSkpOw0KICAgICAgfSwNCiAgICAgIGdldCBlbWl0KCkgew0KICAgICAgICByZXR1cm4gKGV2ZW50LCAuLi5hcmdzKSA9PiBpbnN0YW5jZS5lbWl0KGV2ZW50LCAuLi5hcmdzKTsNCiAgICAgIH0sDQogICAgICBleHBvc2UNCiAgICB9KTsNCiAgfQ0KfQ0KZnVuY3Rpb24gZ2V0Q29tcG9uZW50UHVibGljSW5zdGFuY2UoaW5zdGFuY2UpIHsNCiAgaWYgKGluc3RhbmNlLmV4cG9zZWQpIHsNCiAgICByZXR1cm4gaW5zdGFuY2UuZXhwb3NlUHJveHkgfHwgKGluc3RhbmNlLmV4cG9zZVByb3h5ID0gbmV3IFByb3h5KHByb3h5UmVmcyhtYXJrUmF3KGluc3RhbmNlLmV4cG9zZWQpKSwgew0KICAgICAgZ2V0KHRhcmdldCwga2V5KSB7DQogICAgICAgIGlmIChrZXkgaW4gdGFyZ2V0KSB7DQogICAgICAgICAgcmV0dXJuIHRhcmdldFtrZXldOw0KICAgICAgICB9IGVsc2UgaWYgKGtleSBpbiBwdWJsaWNQcm9wZXJ0aWVzTWFwKSB7DQogICAgICAgICAgcmV0dXJuIHB1YmxpY1Byb3BlcnRpZXNNYXBba2V5XShpbnN0YW5jZSk7DQogICAgICAgIH0NCiAgICAgIH0sDQogICAgICBoYXModGFyZ2V0LCBrZXkpIHsNCiAgICAgICAgcmV0dXJuIGtleSBpbiB0YXJnZXQgfHwga2V5IGluIHB1YmxpY1Byb3BlcnRpZXNNYXA7DQogICAgICB9DQogICAgfSkpOw0KICB9IGVsc2Ugew0KICAgIHJldHVybiBpbnN0YW5jZS5wcm94eTsNCiAgfQ0KfQ0KY29uc3QgY2xhc3NpZnlSRSA9IC8oPzpefFstX10pKFx3KS9nOw0KY29uc3QgY2xhc3NpZnkgPSAoc3RyKSA9PiBzdHIucmVwbGFjZShjbGFzc2lmeVJFLCAoYykgPT4gYy50b1VwcGVyQ2FzZSgpKS5yZXBsYWNlKC9bLV9dL2csICIiKTsNCmZ1bmN0aW9uIGdldENvbXBvbmVudE5hbWUoQ29tcG9uZW50LCBpbmNsdWRlSW5mZXJyZWQgPSB0cnVlKSB7DQogIHJldHVybiBpc0Z1bmN0aW9uKENvbXBvbmVudCkgPyBDb21wb25lbnQuZGlzcGxheU5hbWUgfHwgQ29tcG9uZW50Lm5hbWUgOiBDb21wb25lbnQubmFtZSB8fCBpbmNsdWRlSW5mZXJyZWQgJiYgQ29tcG9uZW50Ll9fbmFtZTsNCn0NCmZ1bmN0aW9uIGZvcm1hdENvbXBvbmVudE5hbWUoaW5zdGFuY2UsIENvbXBvbmVudCwgaXNSb290ID0gZmFsc2UpIHsNCiAgbGV0IG5hbWUgPSBnZXRDb21wb25lbnROYW1lKENvbXBvbmVudCk7DQogIGlmICghbmFtZSAmJiBDb21wb25lbnQuX19maWxlKSB7DQogICAgY29uc3QgbWF0Y2ggPSBDb21wb25lbnQuX19maWxlLm1hdGNoKC8oW14vXFxdKylcLlx3KyQvKTsNCiAgICBpZiAobWF0Y2gpIHsNCiAgICAgIG5hbWUgPSBtYXRjaFsxXTsNCiAgICB9DQogIH0NCiAgaWYgKCFuYW1lICYmIGluc3RhbmNlICYmIGluc3RhbmNlLnBhcmVudCkgew0KICAgIGNvbnN0IGluZmVyRnJvbVJlZ2lzdHJ5ID0gKHJlZ2lzdHJ5KSA9PiB7DQogICAgICBmb3IgKGNvbnN0IGtleSBpbiByZWdpc3RyeSkgew0KICAgICAgICBpZiAocmVnaXN0cnlba2V5XSA9PT0gQ29tcG9uZW50KSB7DQogICAgICAgICAgcmV0dXJuIGtleTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH07DQogICAgbmFtZSA9IGluZmVyRnJvbVJlZ2lzdHJ5KA0KICAgICAgaW5zdGFuY2UuY29tcG9uZW50cyB8fCBpbnN0YW5jZS5wYXJlbnQudHlwZS5jb21wb25lbnRzDQogICAgKSB8fCBpbmZlckZyb21SZWdpc3RyeShpbnN0YW5jZS5hcHBDb250ZXh0LmNvbXBvbmVudHMpOw0KICB9DQogIHJldHVybiBuYW1lID8gY2xhc3NpZnkobmFtZSkgOiBpc1Jvb3QgPyBgQXBwYCA6IGBBbm9ueW1vdXNgOw0KfQ0KZnVuY3Rpb24gaXNDbGFzc0NvbXBvbmVudCh2YWx1ZSkgew0KICByZXR1cm4gaXNGdW5jdGlvbih2YWx1ZSkgJiYgIl9fdmNjT3B0cyIgaW4gdmFsdWU7DQp9DQoNCmNvbnN0IGNvbXB1dGVkID0gKGdldHRlck9yT3B0aW9ucywgZGVidWdPcHRpb25zKSA9PiB7DQogIGNvbnN0IGMgPSBjb21wdXRlZCQxKGdldHRlck9yT3B0aW9ucywgZGVidWdPcHRpb25zLCBpc0luU1NSQ29tcG9uZW50U2V0dXApOw0KICB7DQogICAgY29uc3QgaSA9IGdldEN1cnJlbnRJbnN0YW5jZSgpOw0KICAgIGlmIChpICYmIGkuYXBwQ29udGV4dC5jb25maWcud2FyblJlY3Vyc2l2ZUNvbXB1dGVkKSB7DQogICAgICBjLl93YXJuUmVjdXJzaXZlID0gdHJ1ZTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIGM7DQp9Ow0KDQpmdW5jdGlvbiBoKHR5cGUsIHByb3BzT3JDaGlsZHJlbiwgY2hpbGRyZW4pIHsNCiAgY29uc3QgbCA9IGFyZ3VtZW50cy5sZW5ndGg7DQogIGlmIChsID09PSAyKSB7DQogICAgaWYgKGlzT2JqZWN0KHByb3BzT3JDaGlsZHJlbikgJiYgIWlzQXJyYXkocHJvcHNPckNoaWxkcmVuKSkgew0KICAgICAgaWYgKGlzVk5vZGUocHJvcHNPckNoaWxkcmVuKSkgew0KICAgICAgICByZXR1cm4gY3JlYXRlVk5vZGUodHlwZSwgbnVsbCwgW3Byb3BzT3JDaGlsZHJlbl0pOw0KICAgICAgfQ0KICAgICAgcmV0dXJuIGNyZWF0ZVZOb2RlKHR5cGUsIHByb3BzT3JDaGlsZHJlbik7DQogICAgfSBlbHNlIHsNCiAgICAgIHJldHVybiBjcmVhdGVWTm9kZSh0eXBlLCBudWxsLCBwcm9wc09yQ2hpbGRyZW4pOw0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICBpZiAobCA+IDMpIHsNCiAgICAgIGNoaWxkcmVuID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKTsNCiAgICB9IGVsc2UgaWYgKGwgPT09IDMgJiYgaXNWTm9kZShjaGlsZHJlbikpIHsNCiAgICAgIGNoaWxkcmVuID0gW2NoaWxkcmVuXTsNCiAgICB9DQogICAgcmV0dXJuIGNyZWF0ZVZOb2RlKHR5cGUsIHByb3BzT3JDaGlsZHJlbiwgY2hpbGRyZW4pOw0KICB9DQp9DQoNCmZ1bmN0aW9uIGluaXRDdXN0b21Gb3JtYXR0ZXIoKSB7DQogIGlmICh0eXBlb2Ygd2luZG93ID09PSAidW5kZWZpbmVkIikgew0KICAgIHJldHVybjsNCiAgfQ0KICBjb25zdCB2dWVTdHlsZSA9IHsgc3R5bGU6ICJjb2xvcjojM2JhNzc2IiB9Ow0KICBjb25zdCBudW1iZXJTdHlsZSA9IHsgc3R5bGU6ICJjb2xvcjojMTY3N2ZmIiB9Ow0KICBjb25zdCBzdHJpbmdTdHlsZSA9IHsgc3R5bGU6ICJjb2xvcjojZjUyMjJkIiB9Ow0KICBjb25zdCBrZXl3b3JkU3R5bGUgPSB7IHN0eWxlOiAiY29sb3I6I2ViMmY5NiIgfTsNCiAgY29uc3QgZm9ybWF0dGVyID0gew0KICAgIF9fdnVlX2N1c3RvbV9mb3JtYXR0ZXI6IHRydWUsDQogICAgaGVhZGVyKG9iaikgew0KICAgICAgaWYgKCFpc09iamVjdChvYmopKSB7DQogICAgICAgIHJldHVybiBudWxsOw0KICAgICAgfQ0KICAgICAgaWYgKG9iai5fX2lzVnVlKSB7DQogICAgICAgIHJldHVybiBbImRpdiIsIHZ1ZVN0eWxlLCBgVnVlSW5zdGFuY2VgXTsNCiAgICAgIH0gZWxzZSBpZiAoaXNSZWYob2JqKSkgew0KICAgICAgICBwYXVzZVRyYWNraW5nKCk7DQogICAgICAgIGNvbnN0IHZhbHVlID0gb2JqLnZhbHVlOw0KICAgICAgICByZXNldFRyYWNraW5nKCk7DQogICAgICAgIHJldHVybiBbDQogICAgICAgICAgImRpdiIsDQogICAgICAgICAge30sDQogICAgICAgICAgWyJzcGFuIiwgdnVlU3R5bGUsIGdlblJlZkZsYWcob2JqKV0sDQogICAgICAgICAgIjwiLA0KICAgICAgICAgIGZvcm1hdFZhbHVlKHZhbHVlKSwNCiAgICAgICAgICBgPmANCiAgICAgICAgXTsNCiAgICAgIH0gZWxzZSBpZiAoaXNSZWFjdGl2ZShvYmopKSB7DQogICAgICAgIHJldHVybiBbDQogICAgICAgICAgImRpdiIsDQogICAgICAgICAge30sDQogICAgICAgICAgWyJzcGFuIiwgdnVlU3R5bGUsIGlzU2hhbGxvdyhvYmopID8gIlNoYWxsb3dSZWFjdGl2ZSIgOiAiUmVhY3RpdmUiXSwNCiAgICAgICAgICAiPCIsDQogICAgICAgICAgZm9ybWF0VmFsdWUob2JqKSwNCiAgICAgICAgICBgPiR7aXNSZWFkb25seShvYmopID8gYCAocmVhZG9ubHkpYCA6IGBgfWANCiAgICAgICAgXTsNCiAgICAgIH0gZWxzZSBpZiAoaXNSZWFkb25seShvYmopKSB7DQogICAgICAgIHJldHVybiBbDQogICAgICAgICAgImRpdiIsDQogICAgICAgICAge30sDQogICAgICAgICAgWyJzcGFuIiwgdnVlU3R5bGUsIGlzU2hhbGxvdyhvYmopID8gIlNoYWxsb3dSZWFkb25seSIgOiAiUmVhZG9ubHkiXSwNCiAgICAgICAgICAiPCIsDQogICAgICAgICAgZm9ybWF0VmFsdWUob2JqKSwNCiAgICAgICAgICAiPiINCiAgICAgICAgXTsNCiAgICAgIH0NCiAgICAgIHJldHVybiBudWxsOw0KICAgIH0sDQogICAgaGFzQm9keShvYmopIHsNCiAgICAgIHJldHVybiBvYmogJiYgb2JqLl9faXNWdWU7DQogICAgfSwNCiAgICBib2R5KG9iaikgew0KICAgICAgaWYgKG9iaiAmJiBvYmouX19pc1Z1ZSkgew0KICAgICAgICByZXR1cm4gWw0KICAgICAgICAgICJkaXYiLA0KICAgICAgICAgIHt9LA0KICAgICAgICAgIC4uLmZvcm1hdEluc3RhbmNlKG9iai4kKQ0KICAgICAgICBdOw0KICAgICAgfQ0KICAgIH0NCiAgfTsNCiAgZnVuY3Rpb24gZm9ybWF0SW5zdGFuY2UoaW5zdGFuY2UpIHsNCiAgICBjb25zdCBibG9ja3MgPSBbXTsNCiAgICBpZiAoaW5zdGFuY2UudHlwZS5wcm9wcyAmJiBpbnN0YW5jZS5wcm9wcykgew0KICAgICAgYmxvY2tzLnB1c2goY3JlYXRlSW5zdGFuY2VCbG9jaygicHJvcHMiLCB0b1JhdyhpbnN0YW5jZS5wcm9wcykpKTsNCiAgICB9DQogICAgaWYgKGluc3RhbmNlLnNldHVwU3RhdGUgIT09IEVNUFRZX09CSikgew0KICAgICAgYmxvY2tzLnB1c2goY3JlYXRlSW5zdGFuY2VCbG9jaygic2V0dXAiLCBpbnN0YW5jZS5zZXR1cFN0YXRlKSk7DQogICAgfQ0KICAgIGlmIChpbnN0YW5jZS5kYXRhICE9PSBFTVBUWV9PQkopIHsNCiAgICAgIGJsb2Nrcy5wdXNoKGNyZWF0ZUluc3RhbmNlQmxvY2soImRhdGEiLCB0b1JhdyhpbnN0YW5jZS5kYXRhKSkpOw0KICAgIH0NCiAgICBjb25zdCBjb21wdXRlZCA9IGV4dHJhY3RLZXlzKGluc3RhbmNlLCAiY29tcHV0ZWQiKTsNCiAgICBpZiAoY29tcHV0ZWQpIHsNCiAgICAgIGJsb2Nrcy5wdXNoKGNyZWF0ZUluc3RhbmNlQmxvY2soImNvbXB1dGVkIiwgY29tcHV0ZWQpKTsNCiAgICB9DQogICAgY29uc3QgaW5qZWN0ZWQgPSBleHRyYWN0S2V5cyhpbnN0YW5jZSwgImluamVjdCIpOw0KICAgIGlmIChpbmplY3RlZCkgew0KICAgICAgYmxvY2tzLnB1c2goY3JlYXRlSW5zdGFuY2VCbG9jaygiaW5qZWN0ZWQiLCBpbmplY3RlZCkpOw0KICAgIH0NCiAgICBibG9ja3MucHVzaChbDQogICAgICAiZGl2IiwNCiAgICAgIHt9LA0KICAgICAgWw0KICAgICAgICAic3BhbiIsDQogICAgICAgIHsNCiAgICAgICAgICBzdHlsZToga2V5d29yZFN0eWxlLnN0eWxlICsgIjtvcGFjaXR5OjAuNjYiDQogICAgICAgIH0sDQogICAgICAgICIkIChpbnRlcm5hbCk6ICINCiAgICAgIF0sDQogICAgICBbIm9iamVjdCIsIHsgb2JqZWN0OiBpbnN0YW5jZSB9XQ0KICAgIF0pOw0KICAgIHJldHVybiBibG9ja3M7DQogIH0NCiAgZnVuY3Rpb24gY3JlYXRlSW5zdGFuY2VCbG9jayh0eXBlLCB0YXJnZXQpIHsNCiAgICB0YXJnZXQgPSBleHRlbmQoe30sIHRhcmdldCk7DQogICAgaWYgKCFPYmplY3Qua2V5cyh0YXJnZXQpLmxlbmd0aCkgew0KICAgICAgcmV0dXJuIFsic3BhbiIsIHt9XTsNCiAgICB9DQogICAgcmV0dXJuIFsNCiAgICAgICJkaXYiLA0KICAgICAgeyBzdHlsZTogImxpbmUtaGVpZ2h0OjEuMjVlbTttYXJnaW4tYm90dG9tOjAuNmVtIiB9LA0KICAgICAgWw0KICAgICAgICAiZGl2IiwNCiAgICAgICAgew0KICAgICAgICAgIHN0eWxlOiAiY29sb3I6IzQ3NjU4MiINCiAgICAgICAgfSwNCiAgICAgICAgdHlwZQ0KICAgICAgXSwNCiAgICAgIFsNCiAgICAgICAgImRpdiIsDQogICAgICAgIHsNCiAgICAgICAgICBzdHlsZTogInBhZGRpbmctbGVmdDoxLjI1ZW0iDQogICAgICAgIH0sDQogICAgICAgIC4uLk9iamVjdC5rZXlzKHRhcmdldCkubWFwKChrZXkpID0+IHsNCiAgICAgICAgICByZXR1cm4gWw0KICAgICAgICAgICAgImRpdiIsDQogICAgICAgICAgICB7fSwNCiAgICAgICAgICAgIFsic3BhbiIsIGtleXdvcmRTdHlsZSwga2V5ICsgIjogIl0sDQogICAgICAgICAgICBmb3JtYXRWYWx1ZSh0YXJnZXRba2V5XSwgZmFsc2UpDQogICAgICAgICAgXTsNCiAgICAgICAgfSkNCiAgICAgIF0NCiAgICBdOw0KICB9DQogIGZ1bmN0aW9uIGZvcm1hdFZhbHVlKHYsIGFzUmF3ID0gdHJ1ZSkgew0KICAgIGlmICh0eXBlb2YgdiA9PT0gIm51bWJlciIpIHsNCiAgICAgIHJldHVybiBbInNwYW4iLCBudW1iZXJTdHlsZSwgdl07DQogICAgfSBlbHNlIGlmICh0eXBlb2YgdiA9PT0gInN0cmluZyIpIHsNCiAgICAgIHJldHVybiBbInNwYW4iLCBzdHJpbmdTdHlsZSwgSlNPTi5zdHJpbmdpZnkodildOw0KICAgIH0gZWxzZSBpZiAodHlwZW9mIHYgPT09ICJib29sZWFuIikgew0KICAgICAgcmV0dXJuIFsic3BhbiIsIGtleXdvcmRTdHlsZSwgdl07DQogICAgfSBlbHNlIGlmIChpc09iamVjdCh2KSkgew0KICAgICAgcmV0dXJuIFsib2JqZWN0IiwgeyBvYmplY3Q6IGFzUmF3ID8gdG9SYXcodikgOiB2IH1dOw0KICAgIH0gZWxzZSB7DQogICAgICByZXR1cm4gWyJzcGFuIiwgc3RyaW5nU3R5bGUsIFN0cmluZyh2KV07DQogICAgfQ0KICB9DQogIGZ1bmN0aW9uIGV4dHJhY3RLZXlzKGluc3RhbmNlLCB0eXBlKSB7DQogICAgY29uc3QgQ29tcCA9IGluc3RhbmNlLnR5cGU7DQogICAgaWYgKGlzRnVuY3Rpb24oQ29tcCkpIHsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgY29uc3QgZXh0cmFjdGVkID0ge307DQogICAgZm9yIChjb25zdCBrZXkgaW4gaW5zdGFuY2UuY3R4KSB7DQogICAgICBpZiAoaXNLZXlPZlR5cGUoQ29tcCwga2V5LCB0eXBlKSkgew0KICAgICAgICBleHRyYWN0ZWRba2V5XSA9IGluc3RhbmNlLmN0eFtrZXldOw0KICAgICAgfQ0KICAgIH0NCiAgICByZXR1cm4gZXh0cmFjdGVkOw0KICB9DQogIGZ1bmN0aW9uIGlzS2V5T2ZUeXBlKENvbXAsIGtleSwgdHlwZSkgew0KICAgIGNvbnN0IG9wdHMgPSBDb21wW3R5cGVdOw0KICAgIGlmIChpc0FycmF5KG9wdHMpICYmIG9wdHMuaW5jbHVkZXMoa2V5KSB8fCBpc09iamVjdChvcHRzKSAmJiBrZXkgaW4gb3B0cykgew0KICAgICAgcmV0dXJuIHRydWU7DQogICAgfQ0KICAgIGlmIChDb21wLmV4dGVuZHMgJiYgaXNLZXlPZlR5cGUoQ29tcC5leHRlbmRzLCBrZXksIHR5cGUpKSB7DQogICAgICByZXR1cm4gdHJ1ZTsNCiAgICB9DQogICAgaWYgKENvbXAubWl4aW5zICYmIENvbXAubWl4aW5zLnNvbWUoKG0pID0+IGlzS2V5T2ZUeXBlKG0sIGtleSwgdHlwZSkpKSB7DQogICAgICByZXR1cm4gdHJ1ZTsNCiAgICB9DQogIH0NCiAgZnVuY3Rpb24gZ2VuUmVmRmxhZyh2KSB7DQogICAgaWYgKGlzU2hhbGxvdyh2KSkgew0KICAgICAgcmV0dXJuIGBTaGFsbG93UmVmYDsNCiAgICB9DQogICAgaWYgKHYuZWZmZWN0KSB7DQogICAgICByZXR1cm4gYENvbXB1dGVkUmVmYDsNCiAgICB9DQogICAgcmV0dXJuIGBSZWZgOw0KICB9DQogIGlmICh3aW5kb3cuZGV2dG9vbHNGb3JtYXR0ZXJzKSB7DQogICAgd2luZG93LmRldnRvb2xzRm9ybWF0dGVycy5wdXNoKGZvcm1hdHRlcik7DQogIH0gZWxzZSB7DQogICAgd2luZG93LmRldnRvb2xzRm9ybWF0dGVycyA9IFtmb3JtYXR0ZXJdOw0KICB9DQp9DQoNCmZ1bmN0aW9uIHdpdGhNZW1vKG1lbW8sIHJlbmRlciwgY2FjaGUsIGluZGV4KSB7DQogIGNvbnN0IGNhY2hlZCA9IGNhY2hlW2luZGV4XTsNCiAgaWYgKGNhY2hlZCAmJiBpc01lbW9TYW1lKGNhY2hlZCwgbWVtbykpIHsNCiAgICByZXR1cm4gY2FjaGVkOw0KICB9DQogIGNvbnN0IHJldCA9IHJlbmRlcigpOw0KICByZXQubWVtbyA9IG1lbW8uc2xpY2UoKTsNCiAgcmV0LmNhY2hlSW5kZXggPSBpbmRleDsNCiAgcmV0dXJuIGNhY2hlW2luZGV4XSA9IHJldDsNCn0NCmZ1bmN0aW9uIGlzTWVtb1NhbWUoY2FjaGVkLCBtZW1vKSB7DQogIGNvbnN0IHByZXYgPSBjYWNoZWQubWVtbzsNCiAgaWYgKHByZXYubGVuZ3RoICE9IG1lbW8ubGVuZ3RoKSB7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9DQogIGZvciAobGV0IGkgPSAwOyBpIDwgcHJldi5sZW5ndGg7IGkrKykgew0KICAgIGlmIChoYXNDaGFuZ2VkKHByZXZbaV0sIG1lbW9baV0pKSB7DQogICAgICByZXR1cm4gZmFsc2U7DQogICAgfQ0KICB9DQogIGlmIChpc0Jsb2NrVHJlZUVuYWJsZWQgPiAwICYmIGN1cnJlbnRCbG9jaykgew0KICAgIGN1cnJlbnRCbG9jay5wdXNoKGNhY2hlZCk7DQogIH0NCiAgcmV0dXJuIHRydWU7DQp9DQoNCmNvbnN0IHZlcnNpb24gPSAiMy41LjE3IjsNCmNvbnN0IHdhcm4gPSB3YXJuJDEgOw0KY29uc3QgRXJyb3JUeXBlU3RyaW5ncyA9IEVycm9yVHlwZVN0cmluZ3MkMSA7DQpjb25zdCBkZXZ0b29scyA9IGRldnRvb2xzJDEgOw0KY29uc3Qgc2V0RGV2dG9vbHNIb29rID0gc2V0RGV2dG9vbHNIb29rJDEgOw0KY29uc3QgX3NzclV0aWxzID0gew0KICBjcmVhdGVDb21wb25lbnRJbnN0YW5jZSwNCiAgc2V0dXBDb21wb25lbnQsDQogIHJlbmRlckNvbXBvbmVudFJvb3QsDQogIHNldEN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSwNCiAgaXNWTm9kZTogaXNWTm9kZSwNCiAgbm9ybWFsaXplVk5vZGUsDQogIGdldENvbXBvbmVudFB1YmxpY0luc3RhbmNlLA0KICBlbnN1cmVWYWxpZFZOb2RlLA0KICBwdXNoV2FybmluZ0NvbnRleHQsDQogIHBvcFdhcm5pbmdDb250ZXh0DQp9Ow0KY29uc3Qgc3NyVXRpbHMgPSBfc3NyVXRpbHMgOw0KY29uc3QgcmVzb2x2ZUZpbHRlciA9IG51bGw7DQpjb25zdCBjb21wYXRVdGlscyA9IG51bGw7DQpjb25zdCBEZXByZWNhdGlvblR5cGVzID0gbnVsbDsNCg0KbGV0IHBvbGljeSA9IHZvaWQgMDsNCmNvbnN0IHR0ID0gdHlwZW9mIHdpbmRvdyAhPT0gInVuZGVmaW5lZCIgJiYgd2luZG93LnRydXN0ZWRUeXBlczsNCmlmICh0dCkgew0KICB0cnkgew0KICAgIHBvbGljeSA9IC8qIEBfX1BVUkVfXyAqLyB0dC5jcmVhdGVQb2xpY3koInZ1ZSIsIHsNCiAgICAgIGNyZWF0ZUhUTUw6ICh2YWwpID0+IHZhbA0KICAgIH0pOw0KICB9IGNhdGNoIChlKSB7DQogICAgd2FybihgRXJyb3IgY3JlYXRpbmcgdHJ1c3RlZCB0eXBlcyBwb2xpY3k6ICR7ZX1gKTsNCiAgfQ0KfQ0KY29uc3QgdW5zYWZlVG9UcnVzdGVkSFRNTCA9IHBvbGljeSA/ICh2YWwpID0+IHBvbGljeS5jcmVhdGVIVE1MKHZhbCkgOiAodmFsKSA9PiB2YWw7DQpjb25zdCBzdmdOUyA9ICJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI7DQpjb25zdCBtYXRobWxOUyA9ICJodHRwOi8vd3d3LnczLm9yZy8xOTk4L01hdGgvTWF0aE1MIjsNCmNvbnN0IGRvYyA9IHR5cGVvZiBkb2N1bWVudCAhPT0gInVuZGVmaW5lZCIgPyBkb2N1bWVudCA6IG51bGw7DQpjb25zdCB0ZW1wbGF0ZUNvbnRhaW5lciA9IGRvYyAmJiAvKiBAX19QVVJFX18gKi8gZG9jLmNyZWF0ZUVsZW1lbnQoInRlbXBsYXRlIik7DQpjb25zdCBub2RlT3BzID0gew0KICBpbnNlcnQ6IChjaGlsZCwgcGFyZW50LCBhbmNob3IpID0+IHsNCiAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKGNoaWxkLCBhbmNob3IgfHwgbnVsbCk7DQogIH0sDQogIHJlbW92ZTogKGNoaWxkKSA9PiB7DQogICAgY29uc3QgcGFyZW50ID0gY2hpbGQucGFyZW50Tm9kZTsNCiAgICBpZiAocGFyZW50KSB7DQogICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQoY2hpbGQpOw0KICAgIH0NCiAgfSwNCiAgY3JlYXRlRWxlbWVudDogKHRhZywgbmFtZXNwYWNlLCBpcywgcHJvcHMpID0+IHsNCiAgICBjb25zdCBlbCA9IG5hbWVzcGFjZSA9PT0gInN2ZyIgPyBkb2MuY3JlYXRlRWxlbWVudE5TKHN2Z05TLCB0YWcpIDogbmFtZXNwYWNlID09PSAibWF0aG1sIiA/IGRvYy5jcmVhdGVFbGVtZW50TlMobWF0aG1sTlMsIHRhZykgOiBpcyA/IGRvYy5jcmVhdGVFbGVtZW50KHRhZywgeyBpcyB9KSA6IGRvYy5jcmVhdGVFbGVtZW50KHRhZyk7DQogICAgaWYgKHRhZyA9PT0gInNlbGVjdCIgJiYgcHJvcHMgJiYgcHJvcHMubXVsdGlwbGUgIT0gbnVsbCkgew0KICAgICAgZWwuc2V0QXR0cmlidXRlKCJtdWx0aXBsZSIsIHByb3BzLm11bHRpcGxlKTsNCiAgICB9DQogICAgcmV0dXJuIGVsOw0KICB9LA0KICBjcmVhdGVUZXh0OiAodGV4dCkgPT4gZG9jLmNyZWF0ZVRleHROb2RlKHRleHQpLA0KICBjcmVhdGVDb21tZW50OiAodGV4dCkgPT4gZG9jLmNyZWF0ZUNvbW1lbnQodGV4dCksDQogIHNldFRleHQ6IChub2RlLCB0ZXh0KSA9PiB7DQogICAgbm9kZS5ub2RlVmFsdWUgPSB0ZXh0Ow0KICB9LA0KICBzZXRFbGVtZW50VGV4dDogKGVsLCB0ZXh0KSA9PiB7DQogICAgZWwudGV4dENvbnRlbnQgPSB0ZXh0Ow0KICB9LA0KICBwYXJlbnROb2RlOiAobm9kZSkgPT4gbm9kZS5wYXJlbnROb2RlLA0KICBuZXh0U2libGluZzogKG5vZGUpID0+IG5vZGUubmV4dFNpYmxpbmcsDQogIHF1ZXJ5U2VsZWN0b3I6IChzZWxlY3RvcikgPT4gZG9jLnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpLA0KICBzZXRTY29wZUlkKGVsLCBpZCkgew0KICAgIGVsLnNldEF0dHJpYnV0ZShpZCwgIiIpOw0KICB9LA0KICAvLyBfX1VOU0FGRV9fDQogIC8vIFJlYXNvbjogaW5uZXJIVE1MLg0KICAvLyBTdGF0aWMgY29udGVudCBoZXJlIGNhbiBvbmx5IGNvbWUgZnJvbSBjb21waWxlZCB0ZW1wbGF0ZXMuDQogIC8vIEFzIGxvbmcgYXMgdGhlIHVzZXIgb25seSB1c2VzIHRydXN0ZWQgdGVtcGxhdGVzLCB0aGlzIGlzIHNhZmUuDQogIGluc2VydFN0YXRpY0NvbnRlbnQoY29udGVudCwgcGFyZW50LCBhbmNob3IsIG5hbWVzcGFjZSwgc3RhcnQsIGVuZCkgew0KICAgIGNvbnN0IGJlZm9yZSA9IGFuY2hvciA/IGFuY2hvci5wcmV2aW91c1NpYmxpbmcgOiBwYXJlbnQubGFzdENoaWxkOw0KICAgIGlmIChzdGFydCAmJiAoc3RhcnQgPT09IGVuZCB8fCBzdGFydC5uZXh0U2libGluZykpIHsNCiAgICAgIHdoaWxlICh0cnVlKSB7DQogICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoc3RhcnQuY2xvbmVOb2RlKHRydWUpLCBhbmNob3IpOw0KICAgICAgICBpZiAoc3RhcnQgPT09IGVuZCB8fCAhKHN0YXJ0ID0gc3RhcnQubmV4dFNpYmxpbmcpKSBicmVhazsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgdGVtcGxhdGVDb250YWluZXIuaW5uZXJIVE1MID0gdW5zYWZlVG9UcnVzdGVkSFRNTCgNCiAgICAgICAgbmFtZXNwYWNlID09PSAic3ZnIiA/IGA8c3ZnPiR7Y29udGVudH08L3N2Zz5gIDogbmFtZXNwYWNlID09PSAibWF0aG1sIiA/IGA8bWF0aD4ke2NvbnRlbnR9PC9tYXRoPmAgOiBjb250ZW50DQogICAgICApOw0KICAgICAgY29uc3QgdGVtcGxhdGUgPSB0ZW1wbGF0ZUNvbnRhaW5lci5jb250ZW50Ow0KICAgICAgaWYgKG5hbWVzcGFjZSA9PT0gInN2ZyIgfHwgbmFtZXNwYWNlID09PSAibWF0aG1sIikgew0KICAgICAgICBjb25zdCB3cmFwcGVyID0gdGVtcGxhdGUuZmlyc3RDaGlsZDsNCiAgICAgICAgd2hpbGUgKHdyYXBwZXIuZmlyc3RDaGlsZCkgew0KICAgICAgICAgIHRlbXBsYXRlLmFwcGVuZENoaWxkKHdyYXBwZXIuZmlyc3RDaGlsZCk7DQogICAgICAgIH0NCiAgICAgICAgdGVtcGxhdGUucmVtb3ZlQ2hpbGQod3JhcHBlcik7DQogICAgICB9DQogICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKHRlbXBsYXRlLCBhbmNob3IpOw0KICAgIH0NCiAgICByZXR1cm4gWw0KICAgICAgLy8gZmlyc3QNCiAgICAgIGJlZm9yZSA/IGJlZm9yZS5uZXh0U2libGluZyA6IHBhcmVudC5maXJzdENoaWxkLA0KICAgICAgLy8gbGFzdA0KICAgICAgYW5jaG9yID8gYW5jaG9yLnByZXZpb3VzU2libGluZyA6IHBhcmVudC5sYXN0Q2hpbGQNCiAgICBdOw0KICB9DQp9Ow0KDQpjb25zdCBUUkFOU0lUSU9OID0gInRyYW5zaXRpb24iOw0KY29uc3QgQU5JTUFUSU9OID0gImFuaW1hdGlvbiI7DQpjb25zdCB2dGNLZXkgPSBTeW1ib2woIl92dGMiKTsNCmNvbnN0IERPTVRyYW5zaXRpb25Qcm9wc1ZhbGlkYXRvcnMgPSB7DQogIG5hbWU6IFN0cmluZywNCiAgdHlwZTogU3RyaW5nLA0KICBjc3M6IHsNCiAgICB0eXBlOiBCb29sZWFuLA0KICAgIGRlZmF1bHQ6IHRydWUNCiAgfSwNCiAgZHVyYXRpb246IFtTdHJpbmcsIE51bWJlciwgT2JqZWN0XSwNCiAgZW50ZXJGcm9tQ2xhc3M6IFN0cmluZywNCiAgZW50ZXJBY3RpdmVDbGFzczogU3RyaW5nLA0KICBlbnRlclRvQ2xhc3M6IFN0cmluZywNCiAgYXBwZWFyRnJvbUNsYXNzOiBTdHJpbmcsDQogIGFwcGVhckFjdGl2ZUNsYXNzOiBTdHJpbmcsDQogIGFwcGVhclRvQ2xhc3M6IFN0cmluZywNCiAgbGVhdmVGcm9tQ2xhc3M6IFN0cmluZywNCiAgbGVhdmVBY3RpdmVDbGFzczogU3RyaW5nLA0KICBsZWF2ZVRvQ2xhc3M6IFN0cmluZw0KfTsNCmNvbnN0IFRyYW5zaXRpb25Qcm9wc1ZhbGlkYXRvcnMgPSAvKiBAX19QVVJFX18gKi8gZXh0ZW5kKA0KICB7fSwNCiAgQmFzZVRyYW5zaXRpb25Qcm9wc1ZhbGlkYXRvcnMsDQogIERPTVRyYW5zaXRpb25Qcm9wc1ZhbGlkYXRvcnMNCik7DQpjb25zdCBkZWNvcmF0ZSQxID0gKHQpID0+IHsNCiAgdC5kaXNwbGF5TmFtZSA9ICJUcmFuc2l0aW9uIjsNCiAgdC5wcm9wcyA9IFRyYW5zaXRpb25Qcm9wc1ZhbGlkYXRvcnM7DQogIHJldHVybiB0Ow0KfTsNCmNvbnN0IFRyYW5zaXRpb24gPSAvKiBAX19QVVJFX18gKi8gZGVjb3JhdGUkMSgNCiAgKHByb3BzLCB7IHNsb3RzIH0pID0+IGgoQmFzZVRyYW5zaXRpb24sIHJlc29sdmVUcmFuc2l0aW9uUHJvcHMocHJvcHMpLCBzbG90cykNCik7DQpjb25zdCBjYWxsSG9vayA9IChob29rLCBhcmdzID0gW10pID0+IHsNCiAgaWYgKGlzQXJyYXkoaG9vaykpIHsNCiAgICBob29rLmZvckVhY2goKGgyKSA9PiBoMiguLi5hcmdzKSk7DQogIH0gZWxzZSBpZiAoaG9vaykgew0KICAgIGhvb2soLi4uYXJncyk7DQogIH0NCn07DQpjb25zdCBoYXNFeHBsaWNpdENhbGxiYWNrID0gKGhvb2spID0+IHsNCiAgcmV0dXJuIGhvb2sgPyBpc0FycmF5KGhvb2spID8gaG9vay5zb21lKChoMikgPT4gaDIubGVuZ3RoID4gMSkgOiBob29rLmxlbmd0aCA+IDEgOiBmYWxzZTsNCn07DQpmdW5jdGlvbiByZXNvbHZlVHJhbnNpdGlvblByb3BzKHJhd1Byb3BzKSB7DQogIGNvbnN0IGJhc2VQcm9wcyA9IHt9Ow0KICBmb3IgKGNvbnN0IGtleSBpbiByYXdQcm9wcykgew0KICAgIGlmICghKGtleSBpbiBET01UcmFuc2l0aW9uUHJvcHNWYWxpZGF0b3JzKSkgew0KICAgICAgYmFzZVByb3BzW2tleV0gPSByYXdQcm9wc1trZXldOw0KICAgIH0NCiAgfQ0KICBpZiAocmF3UHJvcHMuY3NzID09PSBmYWxzZSkgew0KICAgIHJldHVybiBiYXNlUHJvcHM7DQogIH0NCiAgY29uc3Qgew0KICAgIG5hbWUgPSAidiIsDQogICAgdHlwZSwNCiAgICBkdXJhdGlvbiwNCiAgICBlbnRlckZyb21DbGFzcyA9IGAke25hbWV9LWVudGVyLWZyb21gLA0KICAgIGVudGVyQWN0aXZlQ2xhc3MgPSBgJHtuYW1lfS1lbnRlci1hY3RpdmVgLA0KICAgIGVudGVyVG9DbGFzcyA9IGAke25hbWV9LWVudGVyLXRvYCwNCiAgICBhcHBlYXJGcm9tQ2xhc3MgPSBlbnRlckZyb21DbGFzcywNCiAgICBhcHBlYXJBY3RpdmVDbGFzcyA9IGVudGVyQWN0aXZlQ2xhc3MsDQogICAgYXBwZWFyVG9DbGFzcyA9IGVudGVyVG9DbGFzcywNCiAgICBsZWF2ZUZyb21DbGFzcyA9IGAke25hbWV9LWxlYXZlLWZyb21gLA0KICAgIGxlYXZlQWN0aXZlQ2xhc3MgPSBgJHtuYW1lfS1sZWF2ZS1hY3RpdmVgLA0KICAgIGxlYXZlVG9DbGFzcyA9IGAke25hbWV9LWxlYXZlLXRvYA0KICB9ID0gcmF3UHJvcHM7DQogIGNvbnN0IGR1cmF0aW9ucyA9IG5vcm1hbGl6ZUR1cmF0aW9uKGR1cmF0aW9uKTsNCiAgY29uc3QgZW50ZXJEdXJhdGlvbiA9IGR1cmF0aW9ucyAmJiBkdXJhdGlvbnNbMF07DQogIGNvbnN0IGxlYXZlRHVyYXRpb24gPSBkdXJhdGlvbnMgJiYgZHVyYXRpb25zWzFdOw0KICBjb25zdCB7DQogICAgb25CZWZvcmVFbnRlciwNCiAgICBvbkVudGVyLA0KICAgIG9uRW50ZXJDYW5jZWxsZWQsDQogICAgb25MZWF2ZSwNCiAgICBvbkxlYXZlQ2FuY2VsbGVkLA0KICAgIG9uQmVmb3JlQXBwZWFyID0gb25CZWZvcmVFbnRlciwNCiAgICBvbkFwcGVhciA9IG9uRW50ZXIsDQogICAgb25BcHBlYXJDYW5jZWxsZWQgPSBvbkVudGVyQ2FuY2VsbGVkDQogIH0gPSBiYXNlUHJvcHM7DQogIGNvbnN0IGZpbmlzaEVudGVyID0gKGVsLCBpc0FwcGVhciwgZG9uZSwgaXNDYW5jZWxsZWQpID0+IHsNCiAgICBlbC5fZW50ZXJDYW5jZWxsZWQgPSBpc0NhbmNlbGxlZDsNCiAgICByZW1vdmVUcmFuc2l0aW9uQ2xhc3MoZWwsIGlzQXBwZWFyID8gYXBwZWFyVG9DbGFzcyA6IGVudGVyVG9DbGFzcyk7DQogICAgcmVtb3ZlVHJhbnNpdGlvbkNsYXNzKGVsLCBpc0FwcGVhciA/IGFwcGVhckFjdGl2ZUNsYXNzIDogZW50ZXJBY3RpdmVDbGFzcyk7DQogICAgZG9uZSAmJiBkb25lKCk7DQogIH07DQogIGNvbnN0IGZpbmlzaExlYXZlID0gKGVsLCBkb25lKSA9PiB7DQogICAgZWwuX2lzTGVhdmluZyA9IGZhbHNlOw0KICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgbGVhdmVGcm9tQ2xhc3MpOw0KICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgbGVhdmVUb0NsYXNzKTsNCiAgICByZW1vdmVUcmFuc2l0aW9uQ2xhc3MoZWwsIGxlYXZlQWN0aXZlQ2xhc3MpOw0KICAgIGRvbmUgJiYgZG9uZSgpOw0KICB9Ow0KICBjb25zdCBtYWtlRW50ZXJIb29rID0gKGlzQXBwZWFyKSA9PiB7DQogICAgcmV0dXJuIChlbCwgZG9uZSkgPT4gew0KICAgICAgY29uc3QgaG9vayA9IGlzQXBwZWFyID8gb25BcHBlYXIgOiBvbkVudGVyOw0KICAgICAgY29uc3QgcmVzb2x2ZSA9ICgpID0+IGZpbmlzaEVudGVyKGVsLCBpc0FwcGVhciwgZG9uZSk7DQogICAgICBjYWxsSG9vayhob29rLCBbZWwsIHJlc29sdmVdKTsNCiAgICAgIG5leHRGcmFtZSgoKSA9PiB7DQogICAgICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgaXNBcHBlYXIgPyBhcHBlYXJGcm9tQ2xhc3MgOiBlbnRlckZyb21DbGFzcyk7DQogICAgICAgIGFkZFRyYW5zaXRpb25DbGFzcyhlbCwgaXNBcHBlYXIgPyBhcHBlYXJUb0NsYXNzIDogZW50ZXJUb0NsYXNzKTsNCiAgICAgICAgaWYgKCFoYXNFeHBsaWNpdENhbGxiYWNrKGhvb2spKSB7DQogICAgICAgICAgd2hlblRyYW5zaXRpb25FbmRzKGVsLCB0eXBlLCBlbnRlckR1cmF0aW9uLCByZXNvbHZlKTsNCiAgICAgICAgfQ0KICAgICAgfSk7DQogICAgfTsNCiAgfTsNCiAgcmV0dXJuIGV4dGVuZChiYXNlUHJvcHMsIHsNCiAgICBvbkJlZm9yZUVudGVyKGVsKSB7DQogICAgICBjYWxsSG9vayhvbkJlZm9yZUVudGVyLCBbZWxdKTsNCiAgICAgIGFkZFRyYW5zaXRpb25DbGFzcyhlbCwgZW50ZXJGcm9tQ2xhc3MpOw0KICAgICAgYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCBlbnRlckFjdGl2ZUNsYXNzKTsNCiAgICB9LA0KICAgIG9uQmVmb3JlQXBwZWFyKGVsKSB7DQogICAgICBjYWxsSG9vayhvbkJlZm9yZUFwcGVhciwgW2VsXSk7DQogICAgICBhZGRUcmFuc2l0aW9uQ2xhc3MoZWwsIGFwcGVhckZyb21DbGFzcyk7DQogICAgICBhZGRUcmFuc2l0aW9uQ2xhc3MoZWwsIGFwcGVhckFjdGl2ZUNsYXNzKTsNCiAgICB9LA0KICAgIG9uRW50ZXI6IG1ha2VFbnRlckhvb2soZmFsc2UpLA0KICAgIG9uQXBwZWFyOiBtYWtlRW50ZXJIb29rKHRydWUpLA0KICAgIG9uTGVhdmUoZWwsIGRvbmUpIHsNCiAgICAgIGVsLl9pc0xlYXZpbmcgPSB0cnVlOw0KICAgICAgY29uc3QgcmVzb2x2ZSA9ICgpID0+IGZpbmlzaExlYXZlKGVsLCBkb25lKTsNCiAgICAgIGFkZFRyYW5zaXRpb25DbGFzcyhlbCwgbGVhdmVGcm9tQ2xhc3MpOw0KICAgICAgaWYgKCFlbC5fZW50ZXJDYW5jZWxsZWQpIHsNCiAgICAgICAgZm9yY2VSZWZsb3coKTsNCiAgICAgICAgYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCBsZWF2ZUFjdGl2ZUNsYXNzKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGFkZFRyYW5zaXRpb25DbGFzcyhlbCwgbGVhdmVBY3RpdmVDbGFzcyk7DQogICAgICAgIGZvcmNlUmVmbG93KCk7DQogICAgICB9DQogICAgICBuZXh0RnJhbWUoKCkgPT4gew0KICAgICAgICBpZiAoIWVsLl9pc0xlYXZpbmcpIHsNCiAgICAgICAgICByZXR1cm47DQogICAgICAgIH0NCiAgICAgICAgcmVtb3ZlVHJhbnNpdGlvbkNsYXNzKGVsLCBsZWF2ZUZyb21DbGFzcyk7DQogICAgICAgIGFkZFRyYW5zaXRpb25DbGFzcyhlbCwgbGVhdmVUb0NsYXNzKTsNCiAgICAgICAgaWYgKCFoYXNFeHBsaWNpdENhbGxiYWNrKG9uTGVhdmUpKSB7DQogICAgICAgICAgd2hlblRyYW5zaXRpb25FbmRzKGVsLCB0eXBlLCBsZWF2ZUR1cmF0aW9uLCByZXNvbHZlKTsNCiAgICAgICAgfQ0KICAgICAgfSk7DQogICAgICBjYWxsSG9vayhvbkxlYXZlLCBbZWwsIHJlc29sdmVdKTsNCiAgICB9LA0KICAgIG9uRW50ZXJDYW5jZWxsZWQoZWwpIHsNCiAgICAgIGZpbmlzaEVudGVyKGVsLCBmYWxzZSwgdm9pZCAwLCB0cnVlKTsNCiAgICAgIGNhbGxIb29rKG9uRW50ZXJDYW5jZWxsZWQsIFtlbF0pOw0KICAgIH0sDQogICAgb25BcHBlYXJDYW5jZWxsZWQoZWwpIHsNCiAgICAgIGZpbmlzaEVudGVyKGVsLCB0cnVlLCB2b2lkIDAsIHRydWUpOw0KICAgICAgY2FsbEhvb2sob25BcHBlYXJDYW5jZWxsZWQsIFtlbF0pOw0KICAgIH0sDQogICAgb25MZWF2ZUNhbmNlbGxlZChlbCkgew0KICAgICAgZmluaXNoTGVhdmUoZWwpOw0KICAgICAgY2FsbEhvb2sob25MZWF2ZUNhbmNlbGxlZCwgW2VsXSk7DQogICAgfQ0KICB9KTsNCn0NCmZ1bmN0aW9uIG5vcm1hbGl6ZUR1cmF0aW9uKGR1cmF0aW9uKSB7DQogIGlmIChkdXJhdGlvbiA9PSBudWxsKSB7DQogICAgcmV0dXJuIG51bGw7DQogIH0gZWxzZSBpZiAoaXNPYmplY3QoZHVyYXRpb24pKSB7DQogICAgcmV0dXJuIFtOdW1iZXJPZihkdXJhdGlvbi5lbnRlciksIE51bWJlck9mKGR1cmF0aW9uLmxlYXZlKV07DQogIH0gZWxzZSB7DQogICAgY29uc3QgbiA9IE51bWJlck9mKGR1cmF0aW9uKTsNCiAgICByZXR1cm4gW24sIG5dOw0KICB9DQp9DQpmdW5jdGlvbiBOdW1iZXJPZih2YWwpIHsNCiAgY29uc3QgcmVzID0gdG9OdW1iZXIodmFsKTsNCiAgew0KICAgIGFzc2VydE51bWJlcihyZXMsICI8dHJhbnNpdGlvbj4gZXhwbGljaXQgZHVyYXRpb24iKTsNCiAgfQ0KICByZXR1cm4gcmVzOw0KfQ0KZnVuY3Rpb24gYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCBjbHMpIHsNCiAgY2xzLnNwbGl0KC9ccysvKS5mb3JFYWNoKChjKSA9PiBjICYmIGVsLmNsYXNzTGlzdC5hZGQoYykpOw0KICAoZWxbdnRjS2V5XSB8fCAoZWxbdnRjS2V5XSA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KCkpKS5hZGQoY2xzKTsNCn0NCmZ1bmN0aW9uIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgY2xzKSB7DQogIGNscy5zcGxpdCgvXHMrLykuZm9yRWFjaCgoYykgPT4gYyAmJiBlbC5jbGFzc0xpc3QucmVtb3ZlKGMpKTsNCiAgY29uc3QgX3Z0YyA9IGVsW3Z0Y0tleV07DQogIGlmIChfdnRjKSB7DQogICAgX3Z0Yy5kZWxldGUoY2xzKTsNCiAgICBpZiAoIV92dGMuc2l6ZSkgew0KICAgICAgZWxbdnRjS2V5XSA9IHZvaWQgMDsNCiAgICB9DQogIH0NCn0NCmZ1bmN0aW9uIG5leHRGcmFtZShjYikgew0KICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4gew0KICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZShjYik7DQogIH0pOw0KfQ0KbGV0IGVuZElkID0gMDsNCmZ1bmN0aW9uIHdoZW5UcmFuc2l0aW9uRW5kcyhlbCwgZXhwZWN0ZWRUeXBlLCBleHBsaWNpdFRpbWVvdXQsIHJlc29sdmUpIHsNCiAgY29uc3QgaWQgPSBlbC5fZW5kSWQgPSArK2VuZElkOw0KICBjb25zdCByZXNvbHZlSWZOb3RTdGFsZSA9ICgpID0+IHsNCiAgICBpZiAoaWQgPT09IGVsLl9lbmRJZCkgew0KICAgICAgcmVzb2x2ZSgpOw0KICAgIH0NCiAgfTsNCiAgaWYgKGV4cGxpY2l0VGltZW91dCAhPSBudWxsKSB7DQogICAgcmV0dXJuIHNldFRpbWVvdXQocmVzb2x2ZUlmTm90U3RhbGUsIGV4cGxpY2l0VGltZW91dCk7DQogIH0NCiAgY29uc3QgeyB0eXBlLCB0aW1lb3V0LCBwcm9wQ291bnQgfSA9IGdldFRyYW5zaXRpb25JbmZvKGVsLCBleHBlY3RlZFR5cGUpOw0KICBpZiAoIXR5cGUpIHsNCiAgICByZXR1cm4gcmVzb2x2ZSgpOw0KICB9DQogIGNvbnN0IGVuZEV2ZW50ID0gdHlwZSArICJlbmQiOw0KICBsZXQgZW5kZWQgPSAwOw0KICBjb25zdCBlbmQgPSAoKSA9PiB7DQogICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihlbmRFdmVudCwgb25FbmQpOw0KICAgIHJlc29sdmVJZk5vdFN0YWxlKCk7DQogIH07DQogIGNvbnN0IG9uRW5kID0gKGUpID0+IHsNCiAgICBpZiAoZS50YXJnZXQgPT09IGVsICYmICsrZW5kZWQgPj0gcHJvcENvdW50KSB7DQogICAgICBlbmQoKTsNCiAgICB9DQogIH07DQogIHNldFRpbWVvdXQoKCkgPT4gew0KICAgIGlmIChlbmRlZCA8IHByb3BDb3VudCkgew0KICAgICAgZW5kKCk7DQogICAgfQ0KICB9LCB0aW1lb3V0ICsgMSk7DQogIGVsLmFkZEV2ZW50TGlzdGVuZXIoZW5kRXZlbnQsIG9uRW5kKTsNCn0NCmZ1bmN0aW9uIGdldFRyYW5zaXRpb25JbmZvKGVsLCBleHBlY3RlZFR5cGUpIHsNCiAgY29uc3Qgc3R5bGVzID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWwpOw0KICBjb25zdCBnZXRTdHlsZVByb3BlcnRpZXMgPSAoa2V5KSA9PiAoc3R5bGVzW2tleV0gfHwgIiIpLnNwbGl0KCIsICIpOw0KICBjb25zdCB0cmFuc2l0aW9uRGVsYXlzID0gZ2V0U3R5bGVQcm9wZXJ0aWVzKGAke1RSQU5TSVRJT059RGVsYXlgKTsNCiAgY29uc3QgdHJhbnNpdGlvbkR1cmF0aW9ucyA9IGdldFN0eWxlUHJvcGVydGllcyhgJHtUUkFOU0lUSU9OfUR1cmF0aW9uYCk7DQogIGNvbnN0IHRyYW5zaXRpb25UaW1lb3V0ID0gZ2V0VGltZW91dCh0cmFuc2l0aW9uRGVsYXlzLCB0cmFuc2l0aW9uRHVyYXRpb25zKTsNCiAgY29uc3QgYW5pbWF0aW9uRGVsYXlzID0gZ2V0U3R5bGVQcm9wZXJ0aWVzKGAke0FOSU1BVElPTn1EZWxheWApOw0KICBjb25zdCBhbmltYXRpb25EdXJhdGlvbnMgPSBnZXRTdHlsZVByb3BlcnRpZXMoYCR7QU5JTUFUSU9OfUR1cmF0aW9uYCk7DQogIGNvbnN0IGFuaW1hdGlvblRpbWVvdXQgPSBnZXRUaW1lb3V0KGFuaW1hdGlvbkRlbGF5cywgYW5pbWF0aW9uRHVyYXRpb25zKTsNCiAgbGV0IHR5cGUgPSBudWxsOw0KICBsZXQgdGltZW91dCA9IDA7DQogIGxldCBwcm9wQ291bnQgPSAwOw0KICBpZiAoZXhwZWN0ZWRUeXBlID09PSBUUkFOU0lUSU9OKSB7DQogICAgaWYgKHRyYW5zaXRpb25UaW1lb3V0ID4gMCkgew0KICAgICAgdHlwZSA9IFRSQU5TSVRJT047DQogICAgICB0aW1lb3V0ID0gdHJhbnNpdGlvblRpbWVvdXQ7DQogICAgICBwcm9wQ291bnQgPSB0cmFuc2l0aW9uRHVyYXRpb25zLmxlbmd0aDsNCiAgICB9DQogIH0gZWxzZSBpZiAoZXhwZWN0ZWRUeXBlID09PSBBTklNQVRJT04pIHsNCiAgICBpZiAoYW5pbWF0aW9uVGltZW91dCA+IDApIHsNCiAgICAgIHR5cGUgPSBBTklNQVRJT047DQogICAgICB0aW1lb3V0ID0gYW5pbWF0aW9uVGltZW91dDsNCiAgICAgIHByb3BDb3VudCA9IGFuaW1hdGlvbkR1cmF0aW9ucy5sZW5ndGg7DQogICAgfQ0KICB9IGVsc2Ugew0KICAgIHRpbWVvdXQgPSBNYXRoLm1heCh0cmFuc2l0aW9uVGltZW91dCwgYW5pbWF0aW9uVGltZW91dCk7DQogICAgdHlwZSA9IHRpbWVvdXQgPiAwID8gdHJhbnNpdGlvblRpbWVvdXQgPiBhbmltYXRpb25UaW1lb3V0ID8gVFJBTlNJVElPTiA6IEFOSU1BVElPTiA6IG51bGw7DQogICAgcHJvcENvdW50ID0gdHlwZSA/IHR5cGUgPT09IFRSQU5TSVRJT04gPyB0cmFuc2l0aW9uRHVyYXRpb25zLmxlbmd0aCA6IGFuaW1hdGlvbkR1cmF0aW9ucy5sZW5ndGggOiAwOw0KICB9DQogIGNvbnN0IGhhc1RyYW5zZm9ybSA9IHR5cGUgPT09IFRSQU5TSVRJT04gJiYgL1xiKHRyYW5zZm9ybXxhbGwpKCx8JCkvLnRlc3QoDQogICAgZ2V0U3R5bGVQcm9wZXJ0aWVzKGAke1RSQU5TSVRJT059UHJvcGVydHlgKS50b1N0cmluZygpDQogICk7DQogIHJldHVybiB7DQogICAgdHlwZSwNCiAgICB0aW1lb3V0LA0KICAgIHByb3BDb3VudCwNCiAgICBoYXNUcmFuc2Zvcm0NCiAgfTsNCn0NCmZ1bmN0aW9uIGdldFRpbWVvdXQoZGVsYXlzLCBkdXJhdGlvbnMpIHsNCiAgd2hpbGUgKGRlbGF5cy5sZW5ndGggPCBkdXJhdGlvbnMubGVuZ3RoKSB7DQogICAgZGVsYXlzID0gZGVsYXlzLmNvbmNhdChkZWxheXMpOw0KICB9DQogIHJldHVybiBNYXRoLm1heCguLi5kdXJhdGlvbnMubWFwKChkLCBpKSA9PiB0b01zKGQpICsgdG9NcyhkZWxheXNbaV0pKSk7DQp9DQpmdW5jdGlvbiB0b01zKHMpIHsNCiAgaWYgKHMgPT09ICJhdXRvIikgcmV0dXJuIDA7DQogIHJldHVybiBOdW1iZXIocy5zbGljZSgwLCAtMSkucmVwbGFjZSgiLCIsICIuIikpICogMWUzOw0KfQ0KZnVuY3Rpb24gZm9yY2VSZWZsb3coKSB7DQogIHJldHVybiBkb2N1bWVudC5ib2R5Lm9mZnNldEhlaWdodDsNCn0NCg0KZnVuY3Rpb24gcGF0Y2hDbGFzcyhlbCwgdmFsdWUsIGlzU1ZHKSB7DQogIGNvbnN0IHRyYW5zaXRpb25DbGFzc2VzID0gZWxbdnRjS2V5XTsNCiAgaWYgKHRyYW5zaXRpb25DbGFzc2VzKSB7DQogICAgdmFsdWUgPSAodmFsdWUgPyBbdmFsdWUsIC4uLnRyYW5zaXRpb25DbGFzc2VzXSA6IFsuLi50cmFuc2l0aW9uQ2xhc3Nlc10pLmpvaW4oIiAiKTsNCiAgfQ0KICBpZiAodmFsdWUgPT0gbnVsbCkgew0KICAgIGVsLnJlbW92ZUF0dHJpYnV0ZSgiY2xhc3MiKTsNCiAgfSBlbHNlIGlmIChpc1NWRykgew0KICAgIGVsLnNldEF0dHJpYnV0ZSgiY2xhc3MiLCB2YWx1ZSk7DQogIH0gZWxzZSB7DQogICAgZWwuY2xhc3NOYW1lID0gdmFsdWU7DQogIH0NCn0NCg0KY29uc3QgdlNob3dPcmlnaW5hbERpc3BsYXkgPSBTeW1ib2woIl92b2QiKTsNCmNvbnN0IHZTaG93SGlkZGVuID0gU3ltYm9sKCJfdnNoIik7DQpjb25zdCB2U2hvdyA9IHsNCiAgYmVmb3JlTW91bnQoZWwsIHsgdmFsdWUgfSwgeyB0cmFuc2l0aW9uIH0pIHsNCiAgICBlbFt2U2hvd09yaWdpbmFsRGlzcGxheV0gPSBlbC5zdHlsZS5kaXNwbGF5ID09PSAibm9uZSIgPyAiIiA6IGVsLnN0eWxlLmRpc3BsYXk7DQogICAgaWYgKHRyYW5zaXRpb24gJiYgdmFsdWUpIHsNCiAgICAgIHRyYW5zaXRpb24uYmVmb3JlRW50ZXIoZWwpOw0KICAgIH0gZWxzZSB7DQogICAgICBzZXREaXNwbGF5KGVsLCB2YWx1ZSk7DQogICAgfQ0KICB9LA0KICBtb3VudGVkKGVsLCB7IHZhbHVlIH0sIHsgdHJhbnNpdGlvbiB9KSB7DQogICAgaWYgKHRyYW5zaXRpb24gJiYgdmFsdWUpIHsNCiAgICAgIHRyYW5zaXRpb24uZW50ZXIoZWwpOw0KICAgIH0NCiAgfSwNCiAgdXBkYXRlZChlbCwgeyB2YWx1ZSwgb2xkVmFsdWUgfSwgeyB0cmFuc2l0aW9uIH0pIHsNCiAgICBpZiAoIXZhbHVlID09PSAhb2xkVmFsdWUpIHJldHVybjsNCiAgICBpZiAodHJhbnNpdGlvbikgew0KICAgICAgaWYgKHZhbHVlKSB7DQogICAgICAgIHRyYW5zaXRpb24uYmVmb3JlRW50ZXIoZWwpOw0KICAgICAgICBzZXREaXNwbGF5KGVsLCB0cnVlKTsNCiAgICAgICAgdHJhbnNpdGlvbi5lbnRlcihlbCk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICB0cmFuc2l0aW9uLmxlYXZlKGVsLCAoKSA9PiB7DQogICAgICAgICAgc2V0RGlzcGxheShlbCwgZmFsc2UpOw0KICAgICAgICB9KTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgc2V0RGlzcGxheShlbCwgdmFsdWUpOw0KICAgIH0NCiAgfSwNCiAgYmVmb3JlVW5tb3VudChlbCwgeyB2YWx1ZSB9KSB7DQogICAgc2V0RGlzcGxheShlbCwgdmFsdWUpOw0KICB9DQp9Ow0Kew0KICB2U2hvdy5uYW1lID0gInNob3ciOw0KfQ0KZnVuY3Rpb24gc2V0RGlzcGxheShlbCwgdmFsdWUpIHsNCiAgZWwuc3R5bGUuZGlzcGxheSA9IHZhbHVlID8gZWxbdlNob3dPcmlnaW5hbERpc3BsYXldIDogIm5vbmUiOw0KICBlbFt2U2hvd0hpZGRlbl0gPSAhdmFsdWU7DQp9DQpmdW5jdGlvbiBpbml0VlNob3dGb3JTU1IoKSB7DQogIHZTaG93LmdldFNTUlByb3BzID0gKHsgdmFsdWUgfSkgPT4gew0KICAgIGlmICghdmFsdWUpIHsNCiAgICAgIHJldHVybiB7IHN0eWxlOiB7IGRpc3BsYXk6ICJub25lIiB9IH07DQogICAgfQ0KICB9Ow0KfQ0KDQpjb25zdCBDU1NfVkFSX1RFWFQgPSBTeW1ib2woIkNTU19WQVJfVEVYVCIgKTsNCmZ1bmN0aW9uIHVzZUNzc1ZhcnMoZ2V0dGVyKSB7DQogIGNvbnN0IGluc3RhbmNlID0gZ2V0Q3VycmVudEluc3RhbmNlKCk7DQogIGlmICghaW5zdGFuY2UpIHsNCiAgICB3YXJuKGB1c2VDc3NWYXJzIGlzIGNhbGxlZCB3aXRob3V0IGN1cnJlbnQgYWN0aXZlIGNvbXBvbmVudCBpbnN0YW5jZS5gKTsNCiAgICByZXR1cm47DQogIH0NCiAgY29uc3QgdXBkYXRlVGVsZXBvcnRzID0gaW5zdGFuY2UudXQgPSAodmFycyA9IGdldHRlcihpbnN0YW5jZS5wcm94eSkpID0+IHsNCiAgICBBcnJheS5mcm9tKA0KICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChgW2RhdGEtdi1vd25lcj0iJHtpbnN0YW5jZS51aWR9Il1gKQ0KICAgICkuZm9yRWFjaCgobm9kZSkgPT4gc2V0VmFyc09uTm9kZShub2RlLCB2YXJzKSk7DQogIH07DQogIHsNCiAgICBpbnN0YW5jZS5nZXRDc3NWYXJzID0gKCkgPT4gZ2V0dGVyKGluc3RhbmNlLnByb3h5KTsNCiAgfQ0KICBjb25zdCBzZXRWYXJzID0gKCkgPT4gew0KICAgIGNvbnN0IHZhcnMgPSBnZXR0ZXIoaW5zdGFuY2UucHJveHkpOw0KICAgIGlmIChpbnN0YW5jZS5jZSkgew0KICAgICAgc2V0VmFyc09uTm9kZShpbnN0YW5jZS5jZSwgdmFycyk7DQogICAgfSBlbHNlIHsNCiAgICAgIHNldFZhcnNPblZOb2RlKGluc3RhbmNlLnN1YlRyZWUsIHZhcnMpOw0KICAgIH0NCiAgICB1cGRhdGVUZWxlcG9ydHModmFycyk7DQogIH07DQogIG9uQmVmb3JlVXBkYXRlKCgpID0+IHsNCiAgICBxdWV1ZVBvc3RGbHVzaENiKHNldFZhcnMpOw0KICB9KTsNCiAgb25Nb3VudGVkKCgpID0+IHsNCiAgICB3YXRjaChzZXRWYXJzLCBOT09QLCB7IGZsdXNoOiAicG9zdCIgfSk7DQogICAgY29uc3Qgb2IgPSBuZXcgTXV0YXRpb25PYnNlcnZlcihzZXRWYXJzKTsNCiAgICBvYi5vYnNlcnZlKGluc3RhbmNlLnN1YlRyZWUuZWwucGFyZW50Tm9kZSwgeyBjaGlsZExpc3Q6IHRydWUgfSk7DQogICAgb25Vbm1vdW50ZWQoKCkgPT4gb2IuZGlzY29ubmVjdCgpKTsNCiAgfSk7DQp9DQpmdW5jdGlvbiBzZXRWYXJzT25WTm9kZSh2bm9kZSwgdmFycykgew0KICBpZiAodm5vZGUuc2hhcGVGbGFnICYgMTI4KSB7DQogICAgY29uc3Qgc3VzcGVuc2UgPSB2bm9kZS5zdXNwZW5zZTsNCiAgICB2bm9kZSA9IHN1c3BlbnNlLmFjdGl2ZUJyYW5jaDsNCiAgICBpZiAoc3VzcGVuc2UucGVuZGluZ0JyYW5jaCAmJiAhc3VzcGVuc2UuaXNIeWRyYXRpbmcpIHsNCiAgICAgIHN1c3BlbnNlLmVmZmVjdHMucHVzaCgoKSA9PiB7DQogICAgICAgIHNldFZhcnNPblZOb2RlKHN1c3BlbnNlLmFjdGl2ZUJyYW5jaCwgdmFycyk7DQogICAgICB9KTsNCiAgICB9DQogIH0NCiAgd2hpbGUgKHZub2RlLmNvbXBvbmVudCkgew0KICAgIHZub2RlID0gdm5vZGUuY29tcG9uZW50LnN1YlRyZWU7DQogIH0NCiAgaWYgKHZub2RlLnNoYXBlRmxhZyAmIDEgJiYgdm5vZGUuZWwpIHsNCiAgICBzZXRWYXJzT25Ob2RlKHZub2RlLmVsLCB2YXJzKTsNCiAgfSBlbHNlIGlmICh2bm9kZS50eXBlID09PSBGcmFnbWVudCkgew0KICAgIHZub2RlLmNoaWxkcmVuLmZvckVhY2goKGMpID0+IHNldFZhcnNPblZOb2RlKGMsIHZhcnMpKTsNCiAgfSBlbHNlIGlmICh2bm9kZS50eXBlID09PSBTdGF0aWMpIHsNCiAgICBsZXQgeyBlbCwgYW5jaG9yIH0gPSB2bm9kZTsNCiAgICB3aGlsZSAoZWwpIHsNCiAgICAgIHNldFZhcnNPbk5vZGUoZWwsIHZhcnMpOw0KICAgICAgaWYgKGVsID09PSBhbmNob3IpIGJyZWFrOw0KICAgICAgZWwgPSBlbC5uZXh0U2libGluZzsNCiAgICB9DQogIH0NCn0NCmZ1bmN0aW9uIHNldFZhcnNPbk5vZGUoZWwsIHZhcnMpIHsNCiAgaWYgKGVsLm5vZGVUeXBlID09PSAxKSB7DQogICAgY29uc3Qgc3R5bGUgPSBlbC5zdHlsZTsNCiAgICBsZXQgY3NzVGV4dCA9ICIiOw0KICAgIGZvciAoY29uc3Qga2V5IGluIHZhcnMpIHsNCiAgICAgIHN0eWxlLnNldFByb3BlcnR5KGAtLSR7a2V5fWAsIHZhcnNba2V5XSk7DQogICAgICBjc3NUZXh0ICs9IGAtLSR7a2V5fTogJHt2YXJzW2tleV19O2A7DQogICAgfQ0KICAgIHN0eWxlW0NTU19WQVJfVEVYVF0gPSBjc3NUZXh0Ow0KICB9DQp9DQoNCmNvbnN0IGRpc3BsYXlSRSA9IC8oXnw7KVxzKmRpc3BsYXlccyo6LzsNCmZ1bmN0aW9uIHBhdGNoU3R5bGUoZWwsIHByZXYsIG5leHQpIHsNCiAgY29uc3Qgc3R5bGUgPSBlbC5zdHlsZTsNCiAgY29uc3QgaXNDc3NTdHJpbmcgPSBpc1N0cmluZyhuZXh0KTsNCiAgbGV0IGhhc0NvbnRyb2xsZWREaXNwbGF5ID0gZmFsc2U7DQogIGlmIChuZXh0ICYmICFpc0Nzc1N0cmluZykgew0KICAgIGlmIChwcmV2KSB7DQogICAgICBpZiAoIWlzU3RyaW5nKHByZXYpKSB7DQogICAgICAgIGZvciAoY29uc3Qga2V5IGluIHByZXYpIHsNCiAgICAgICAgICBpZiAobmV4dFtrZXldID09IG51bGwpIHsNCiAgICAgICAgICAgIHNldFN0eWxlKHN0eWxlLCBrZXksICIiKTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGZvciAoY29uc3QgcHJldlN0eWxlIG9mIHByZXYuc3BsaXQoIjsiKSkgew0KICAgICAgICAgIGNvbnN0IGtleSA9IHByZXZTdHlsZS5zbGljZSgwLCBwcmV2U3R5bGUuaW5kZXhPZigiOiIpKS50cmltKCk7DQogICAgICAgICAgaWYgKG5leHRba2V5XSA9PSBudWxsKSB7DQogICAgICAgICAgICBzZXRTdHlsZShzdHlsZSwga2V5LCAiIik7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICAgIGZvciAoY29uc3Qga2V5IGluIG5leHQpIHsNCiAgICAgIGlmIChrZXkgPT09ICJkaXNwbGF5Iikgew0KICAgICAgICBoYXNDb250cm9sbGVkRGlzcGxheSA9IHRydWU7DQogICAgICB9DQogICAgICBzZXRTdHlsZShzdHlsZSwga2V5LCBuZXh0W2tleV0pOw0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICBpZiAoaXNDc3NTdHJpbmcpIHsNCiAgICAgIGlmIChwcmV2ICE9PSBuZXh0KSB7DQogICAgICAgIGNvbnN0IGNzc1ZhclRleHQgPSBzdHlsZVtDU1NfVkFSX1RFWFRdOw0KICAgICAgICBpZiAoY3NzVmFyVGV4dCkgew0KICAgICAgICAgIG5leHQgKz0gIjsiICsgY3NzVmFyVGV4dDsNCiAgICAgICAgfQ0KICAgICAgICBzdHlsZS5jc3NUZXh0ID0gbmV4dDsNCiAgICAgICAgaGFzQ29udHJvbGxlZERpc3BsYXkgPSBkaXNwbGF5UkUudGVzdChuZXh0KTsNCiAgICAgIH0NCiAgICB9IGVsc2UgaWYgKHByZXYpIHsNCiAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZSgic3R5bGUiKTsNCiAgICB9DQogIH0NCiAgaWYgKHZTaG93T3JpZ2luYWxEaXNwbGF5IGluIGVsKSB7DQogICAgZWxbdlNob3dPcmlnaW5hbERpc3BsYXldID0gaGFzQ29udHJvbGxlZERpc3BsYXkgPyBzdHlsZS5kaXNwbGF5IDogIiI7DQogICAgaWYgKGVsW3ZTaG93SGlkZGVuXSkgew0KICAgICAgc3R5bGUuZGlzcGxheSA9ICJub25lIjsNCiAgICB9DQogIH0NCn0NCmNvbnN0IHNlbWljb2xvblJFID0gL1teXFxdO1xzKiQvOw0KY29uc3QgaW1wb3J0YW50UkUgPSAvXHMqIWltcG9ydGFudCQvOw0KZnVuY3Rpb24gc2V0U3R5bGUoc3R5bGUsIG5hbWUsIHZhbCkgew0KICBpZiAoaXNBcnJheSh2YWwpKSB7DQogICAgdmFsLmZvckVhY2goKHYpID0+IHNldFN0eWxlKHN0eWxlLCBuYW1lLCB2KSk7DQogIH0gZWxzZSB7DQogICAgaWYgKHZhbCA9PSBudWxsKSB2YWwgPSAiIjsNCiAgICB7DQogICAgICBpZiAoc2VtaWNvbG9uUkUudGVzdCh2YWwpKSB7DQogICAgICAgIHdhcm4oDQogICAgICAgICAgYFVuZXhwZWN0ZWQgc2VtaWNvbG9uIGF0IHRoZSBlbmQgb2YgJyR7bmFtZX0nIHN0eWxlIHZhbHVlOiAnJHt2YWx9J2ANCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICB9DQogICAgaWYgKG5hbWUuc3RhcnRzV2l0aCgiLS0iKSkgew0KICAgICAgc3R5bGUuc2V0UHJvcGVydHkobmFtZSwgdmFsKTsNCiAgICB9IGVsc2Ugew0KICAgICAgY29uc3QgcHJlZml4ZWQgPSBhdXRvUHJlZml4KHN0eWxlLCBuYW1lKTsNCiAgICAgIGlmIChpbXBvcnRhbnRSRS50ZXN0KHZhbCkpIHsNCiAgICAgICAgc3R5bGUuc2V0UHJvcGVydHkoDQogICAgICAgICAgaHlwaGVuYXRlKHByZWZpeGVkKSwNCiAgICAgICAgICB2YWwucmVwbGFjZShpbXBvcnRhbnRSRSwgIiIpLA0KICAgICAgICAgICJpbXBvcnRhbnQiDQogICAgICAgICk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBzdHlsZVtwcmVmaXhlZF0gPSB2YWw7DQogICAgICB9DQogICAgfQ0KICB9DQp9DQpjb25zdCBwcmVmaXhlcyA9IFsiV2Via2l0IiwgIk1veiIsICJtcyJdOw0KY29uc3QgcHJlZml4Q2FjaGUgPSB7fTsNCmZ1bmN0aW9uIGF1dG9QcmVmaXgoc3R5bGUsIHJhd05hbWUpIHsNCiAgY29uc3QgY2FjaGVkID0gcHJlZml4Q2FjaGVbcmF3TmFtZV07DQogIGlmIChjYWNoZWQpIHsNCiAgICByZXR1cm4gY2FjaGVkOw0KICB9DQogIGxldCBuYW1lID0gY2FtZWxpemUocmF3TmFtZSk7DQogIGlmIChuYW1lICE9PSAiZmlsdGVyIiAmJiBuYW1lIGluIHN0eWxlKSB7DQogICAgcmV0dXJuIHByZWZpeENhY2hlW3Jhd05hbWVdID0gbmFtZTsNCiAgfQ0KICBuYW1lID0gY2FwaXRhbGl6ZShuYW1lKTsNCiAgZm9yIChsZXQgaSA9IDA7IGkgPCBwcmVmaXhlcy5sZW5ndGg7IGkrKykgew0KICAgIGNvbnN0IHByZWZpeGVkID0gcHJlZml4ZXNbaV0gKyBuYW1lOw0KICAgIGlmIChwcmVmaXhlZCBpbiBzdHlsZSkgew0KICAgICAgcmV0dXJuIHByZWZpeENhY2hlW3Jhd05hbWVdID0gcHJlZml4ZWQ7DQogICAgfQ0KICB9DQogIHJldHVybiByYXdOYW1lOw0KfQ0KDQpjb25zdCB4bGlua05TID0gImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiOw0KZnVuY3Rpb24gcGF0Y2hBdHRyKGVsLCBrZXksIHZhbHVlLCBpc1NWRywgaW5zdGFuY2UsIGlzQm9vbGVhbiA9IGlzU3BlY2lhbEJvb2xlYW5BdHRyKGtleSkpIHsNCiAgaWYgKGlzU1ZHICYmIGtleS5zdGFydHNXaXRoKCJ4bGluazoiKSkgew0KICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7DQogICAgICBlbC5yZW1vdmVBdHRyaWJ1dGVOUyh4bGlua05TLCBrZXkuc2xpY2UoNiwga2V5Lmxlbmd0aCkpOw0KICAgIH0gZWxzZSB7DQogICAgICBlbC5zZXRBdHRyaWJ1dGVOUyh4bGlua05TLCBrZXksIHZhbHVlKTsNCiAgICB9DQogIH0gZWxzZSB7DQogICAgaWYgKHZhbHVlID09IG51bGwgfHwgaXNCb29sZWFuICYmICFpbmNsdWRlQm9vbGVhbkF0dHIodmFsdWUpKSB7DQogICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoa2V5KTsNCiAgICB9IGVsc2Ugew0KICAgICAgZWwuc2V0QXR0cmlidXRlKA0KICAgICAgICBrZXksDQogICAgICAgIGlzQm9vbGVhbiA/ICIiIDogaXNTeW1ib2wodmFsdWUpID8gU3RyaW5nKHZhbHVlKSA6IHZhbHVlDQogICAgICApOw0KICAgIH0NCiAgfQ0KfQ0KDQpmdW5jdGlvbiBwYXRjaERPTVByb3AoZWwsIGtleSwgdmFsdWUsIHBhcmVudENvbXBvbmVudCwgYXR0ck5hbWUpIHsNCiAgaWYgKGtleSA9PT0gImlubmVySFRNTCIgfHwga2V5ID09PSAidGV4dENvbnRlbnQiKSB7DQogICAgaWYgKHZhbHVlICE9IG51bGwpIHsNCiAgICAgIGVsW2tleV0gPSBrZXkgPT09ICJpbm5lckhUTUwiID8gdW5zYWZlVG9UcnVzdGVkSFRNTCh2YWx1ZSkgOiB2YWx1ZTsNCiAgICB9DQogICAgcmV0dXJuOw0KICB9DQogIGNvbnN0IHRhZyA9IGVsLnRhZ05hbWU7DQogIGlmIChrZXkgPT09ICJ2YWx1ZSIgJiYgdGFnICE9PSAiUFJPR1JFU1MiICYmIC8vIGN1c3RvbSBlbGVtZW50cyBtYXkgdXNlIF92YWx1ZSBpbnRlcm5hbGx5DQogICF0YWcuaW5jbHVkZXMoIi0iKSkgew0KICAgIGNvbnN0IG9sZFZhbHVlID0gdGFnID09PSAiT1BUSU9OIiA/IGVsLmdldEF0dHJpYnV0ZSgidmFsdWUiKSB8fCAiIiA6IGVsLnZhbHVlOw0KICAgIGNvbnN0IG5ld1ZhbHVlID0gdmFsdWUgPT0gbnVsbCA/ICgNCiAgICAgIC8vICMxMTY0NzogdmFsdWUgc2hvdWxkIGJlIHNldCBhcyBlbXB0eSBzdHJpbmcgZm9yIG51bGwgYW5kIHVuZGVmaW5lZCwNCiAgICAgIC8vIGJ1dCA8aW5wdXQgdHlwZT0iY2hlY2tib3giPiBzaG91bGQgYmUgc2V0IGFzICdvbicuDQogICAgICBlbC50eXBlID09PSAiY2hlY2tib3giID8gIm9uIiA6ICIiDQogICAgKSA6IFN0cmluZyh2YWx1ZSk7DQogICAgaWYgKG9sZFZhbHVlICE9PSBuZXdWYWx1ZSB8fCAhKCJfdmFsdWUiIGluIGVsKSkgew0KICAgICAgZWwudmFsdWUgPSBuZXdWYWx1ZTsNCiAgICB9DQogICAgaWYgKHZhbHVlID09IG51bGwpIHsNCiAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZShrZXkpOw0KICAgIH0NCiAgICBlbC5fdmFsdWUgPSB2YWx1ZTsNCiAgICByZXR1cm47DQogIH0NCiAgbGV0IG5lZWRSZW1vdmUgPSBmYWxzZTsNCiAgaWYgKHZhbHVlID09PSAiIiB8fCB2YWx1ZSA9PSBudWxsKSB7DQogICAgY29uc3QgdHlwZSA9IHR5cGVvZiBlbFtrZXldOw0KICAgIGlmICh0eXBlID09PSAiYm9vbGVhbiIpIHsNCiAgICAgIHZhbHVlID0gaW5jbHVkZUJvb2xlYW5BdHRyKHZhbHVlKTsNCiAgICB9IGVsc2UgaWYgKHZhbHVlID09IG51bGwgJiYgdHlwZSA9PT0gInN0cmluZyIpIHsNCiAgICAgIHZhbHVlID0gIiI7DQogICAgICBuZWVkUmVtb3ZlID0gdHJ1ZTsNCiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICJudW1iZXIiKSB7DQogICAgICB2YWx1ZSA9IDA7DQogICAgICBuZWVkUmVtb3ZlID0gdHJ1ZTsNCiAgICB9DQogIH0NCiAgdHJ5IHsNCiAgICBlbFtrZXldID0gdmFsdWU7DQogIH0gY2F0Y2ggKGUpIHsNCiAgICBpZiAoIW5lZWRSZW1vdmUpIHsNCiAgICAgIHdhcm4oDQogICAgICAgIGBGYWlsZWQgc2V0dGluZyBwcm9wICIke2tleX0iIG9uIDwke3RhZy50b0xvd2VyQ2FzZSgpfT46IHZhbHVlICR7dmFsdWV9IGlzIGludmFsaWQuYCwNCiAgICAgICAgZQ0KICAgICAgKTsNCiAgICB9DQogIH0NCiAgbmVlZFJlbW92ZSAmJiBlbC5yZW1vdmVBdHRyaWJ1dGUoYXR0ck5hbWUgfHwga2V5KTsNCn0NCg0KZnVuY3Rpb24gYWRkRXZlbnRMaXN0ZW5lcihlbCwgZXZlbnQsIGhhbmRsZXIsIG9wdGlvbnMpIHsNCiAgZWwuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgaGFuZGxlciwgb3B0aW9ucyk7DQp9DQpmdW5jdGlvbiByZW1vdmVFdmVudExpc3RlbmVyKGVsLCBldmVudCwgaGFuZGxlciwgb3B0aW9ucykgew0KICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50LCBoYW5kbGVyLCBvcHRpb25zKTsNCn0NCmNvbnN0IHZlaUtleSA9IFN5bWJvbCgiX3ZlaSIpOw0KZnVuY3Rpb24gcGF0Y2hFdmVudChlbCwgcmF3TmFtZSwgcHJldlZhbHVlLCBuZXh0VmFsdWUsIGluc3RhbmNlID0gbnVsbCkgew0KICBjb25zdCBpbnZva2VycyA9IGVsW3ZlaUtleV0gfHwgKGVsW3ZlaUtleV0gPSB7fSk7DQogIGNvbnN0IGV4aXN0aW5nSW52b2tlciA9IGludm9rZXJzW3Jhd05hbWVdOw0KICBpZiAobmV4dFZhbHVlICYmIGV4aXN0aW5nSW52b2tlcikgew0KICAgIGV4aXN0aW5nSW52b2tlci52YWx1ZSA9IHNhbml0aXplRXZlbnRWYWx1ZShuZXh0VmFsdWUsIHJhd05hbWUpIDsNCiAgfSBlbHNlIHsNCiAgICBjb25zdCBbbmFtZSwgb3B0aW9uc10gPSBwYXJzZU5hbWUocmF3TmFtZSk7DQogICAgaWYgKG5leHRWYWx1ZSkgew0KICAgICAgY29uc3QgaW52b2tlciA9IGludm9rZXJzW3Jhd05hbWVdID0gY3JlYXRlSW52b2tlcigNCiAgICAgICAgc2FuaXRpemVFdmVudFZhbHVlKG5leHRWYWx1ZSwgcmF3TmFtZSkgLA0KICAgICAgICBpbnN0YW5jZQ0KICAgICAgKTsNCiAgICAgIGFkZEV2ZW50TGlzdGVuZXIoZWwsIG5hbWUsIGludm9rZXIsIG9wdGlvbnMpOw0KICAgIH0gZWxzZSBpZiAoZXhpc3RpbmdJbnZva2VyKSB7DQogICAgICByZW1vdmVFdmVudExpc3RlbmVyKGVsLCBuYW1lLCBleGlzdGluZ0ludm9rZXIsIG9wdGlvbnMpOw0KICAgICAgaW52b2tlcnNbcmF3TmFtZV0gPSB2b2lkIDA7DQogICAgfQ0KICB9DQp9DQpjb25zdCBvcHRpb25zTW9kaWZpZXJSRSA9IC8oPzpPbmNlfFBhc3NpdmV8Q2FwdHVyZSkkLzsNCmZ1bmN0aW9uIHBhcnNlTmFtZShuYW1lKSB7DQogIGxldCBvcHRpb25zOw0KICBpZiAob3B0aW9uc01vZGlmaWVyUkUudGVzdChuYW1lKSkgew0KICAgIG9wdGlvbnMgPSB7fTsNCiAgICBsZXQgbTsNCiAgICB3aGlsZSAobSA9IG5hbWUubWF0Y2gob3B0aW9uc01vZGlmaWVyUkUpKSB7DQogICAgICBuYW1lID0gbmFtZS5zbGljZSgwLCBuYW1lLmxlbmd0aCAtIG1bMF0ubGVuZ3RoKTsNCiAgICAgIG9wdGlvbnNbbVswXS50b0xvd2VyQ2FzZSgpXSA9IHRydWU7DQogICAgfQ0KICB9DQogIGNvbnN0IGV2ZW50ID0gbmFtZVsyXSA9PT0gIjoiID8gbmFtZS5zbGljZSgzKSA6IGh5cGhlbmF0ZShuYW1lLnNsaWNlKDIpKTsNCiAgcmV0dXJuIFtldmVudCwgb3B0aW9uc107DQp9DQpsZXQgY2FjaGVkTm93ID0gMDsNCmNvbnN0IHAgPSAvKiBAX19QVVJFX18gKi8gUHJvbWlzZS5yZXNvbHZlKCk7DQpjb25zdCBnZXROb3cgPSAoKSA9PiBjYWNoZWROb3cgfHwgKHAudGhlbigoKSA9PiBjYWNoZWROb3cgPSAwKSwgY2FjaGVkTm93ID0gRGF0ZS5ub3coKSk7DQpmdW5jdGlvbiBjcmVhdGVJbnZva2VyKGluaXRpYWxWYWx1ZSwgaW5zdGFuY2UpIHsNCiAgY29uc3QgaW52b2tlciA9IChlKSA9PiB7DQogICAgaWYgKCFlLl92dHMpIHsNCiAgICAgIGUuX3Z0cyA9IERhdGUubm93KCk7DQogICAgfSBlbHNlIGlmIChlLl92dHMgPD0gaW52b2tlci5hdHRhY2hlZCkgew0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZygNCiAgICAgIHBhdGNoU3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKGUsIGludm9rZXIudmFsdWUpLA0KICAgICAgaW5zdGFuY2UsDQogICAgICA1LA0KICAgICAgW2VdDQogICAgKTsNCiAgfTsNCiAgaW52b2tlci52YWx1ZSA9IGluaXRpYWxWYWx1ZTsNCiAgaW52b2tlci5hdHRhY2hlZCA9IGdldE5vdygpOw0KICByZXR1cm4gaW52b2tlcjsNCn0NCmZ1bmN0aW9uIHNhbml0aXplRXZlbnRWYWx1ZSh2YWx1ZSwgcHJvcE5hbWUpIHsNCiAgaWYgKGlzRnVuY3Rpb24odmFsdWUpIHx8IGlzQXJyYXkodmFsdWUpKSB7DQogICAgcmV0dXJuIHZhbHVlOw0KICB9DQogIHdhcm4oDQogICAgYFdyb25nIHR5cGUgcGFzc2VkIGFzIGV2ZW50IGhhbmRsZXIgdG8gJHtwcm9wTmFtZX0gLSBkaWQgeW91IGZvcmdldCBAIG9yIDogaW4gZnJvbnQgb2YgeW91ciBwcm9wPw0KRXhwZWN0ZWQgZnVuY3Rpb24gb3IgYXJyYXkgb2YgZnVuY3Rpb25zLCByZWNlaXZlZCB0eXBlICR7dHlwZW9mIHZhbHVlfS5gDQogICk7DQogIHJldHVybiBOT09QOw0KfQ0KZnVuY3Rpb24gcGF0Y2hTdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oZSwgdmFsdWUpIHsNCiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7DQogICAgY29uc3Qgb3JpZ2luYWxTdG9wID0gZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb247DQogICAgZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24gPSAoKSA9PiB7DQogICAgICBvcmlnaW5hbFN0b3AuY2FsbChlKTsNCiAgICAgIGUuX3N0b3BwZWQgPSB0cnVlOw0KICAgIH07DQogICAgcmV0dXJuIHZhbHVlLm1hcCgNCiAgICAgIChmbikgPT4gKGUyKSA9PiAhZTIuX3N0b3BwZWQgJiYgZm4gJiYgZm4oZTIpDQogICAgKTsNCiAgfSBlbHNlIHsNCiAgICByZXR1cm4gdmFsdWU7DQogIH0NCn0NCg0KY29uc3QgaXNOYXRpdmVPbiA9IChrZXkpID0+IGtleS5jaGFyQ29kZUF0KDApID09PSAxMTEgJiYga2V5LmNoYXJDb2RlQXQoMSkgPT09IDExMCAmJiAvLyBsb3dlcmNhc2UgbGV0dGVyDQprZXkuY2hhckNvZGVBdCgyKSA+IDk2ICYmIGtleS5jaGFyQ29kZUF0KDIpIDwgMTIzOw0KY29uc3QgcGF0Y2hQcm9wID0gKGVsLCBrZXksIHByZXZWYWx1ZSwgbmV4dFZhbHVlLCBuYW1lc3BhY2UsIHBhcmVudENvbXBvbmVudCkgPT4gew0KICBjb25zdCBpc1NWRyA9IG5hbWVzcGFjZSA9PT0gInN2ZyI7DQogIGlmIChrZXkgPT09ICJjbGFzcyIpIHsNCiAgICBwYXRjaENsYXNzKGVsLCBuZXh0VmFsdWUsIGlzU1ZHKTsNCiAgfSBlbHNlIGlmIChrZXkgPT09ICJzdHlsZSIpIHsNCiAgICBwYXRjaFN0eWxlKGVsLCBwcmV2VmFsdWUsIG5leHRWYWx1ZSk7DQogIH0gZWxzZSBpZiAoaXNPbihrZXkpKSB7DQogICAgaWYgKCFpc01vZGVsTGlzdGVuZXIoa2V5KSkgew0KICAgICAgcGF0Y2hFdmVudChlbCwga2V5LCBwcmV2VmFsdWUsIG5leHRWYWx1ZSwgcGFyZW50Q29tcG9uZW50KTsNCiAgICB9DQogIH0gZWxzZSBpZiAoa2V5WzBdID09PSAiLiIgPyAoa2V5ID0ga2V5LnNsaWNlKDEpLCB0cnVlKSA6IGtleVswXSA9PT0gIl4iID8gKGtleSA9IGtleS5zbGljZSgxKSwgZmFsc2UpIDogc2hvdWxkU2V0QXNQcm9wKGVsLCBrZXksIG5leHRWYWx1ZSwgaXNTVkcpKSB7DQogICAgcGF0Y2hET01Qcm9wKGVsLCBrZXksIG5leHRWYWx1ZSk7DQogICAgaWYgKCFlbC50YWdOYW1lLmluY2x1ZGVzKCItIikgJiYgKGtleSA9PT0gInZhbHVlIiB8fCBrZXkgPT09ICJjaGVja2VkIiB8fCBrZXkgPT09ICJzZWxlY3RlZCIpKSB7DQogICAgICBwYXRjaEF0dHIoZWwsIGtleSwgbmV4dFZhbHVlLCBpc1NWRywgcGFyZW50Q29tcG9uZW50LCBrZXkgIT09ICJ2YWx1ZSIpOw0KICAgIH0NCiAgfSBlbHNlIGlmICgNCiAgICAvLyAjMTEwODEgZm9yY2Ugc2V0IHByb3BzIGZvciBwb3NzaWJsZSBhc3luYyBjdXN0b20gZWxlbWVudA0KICAgIGVsLl9pc1Z1ZUNFICYmICgvW0EtWl0vLnRlc3Qoa2V5KSB8fCAhaXNTdHJpbmcobmV4dFZhbHVlKSkNCiAgKSB7DQogICAgcGF0Y2hET01Qcm9wKGVsLCBjYW1lbGl6ZShrZXkpLCBuZXh0VmFsdWUsIHBhcmVudENvbXBvbmVudCwga2V5KTsNCiAgfSBlbHNlIHsNCiAgICBpZiAoa2V5ID09PSAidHJ1ZS12YWx1ZSIpIHsNCiAgICAgIGVsLl90cnVlVmFsdWUgPSBuZXh0VmFsdWU7DQogICAgfSBlbHNlIGlmIChrZXkgPT09ICJmYWxzZS12YWx1ZSIpIHsNCiAgICAgIGVsLl9mYWxzZVZhbHVlID0gbmV4dFZhbHVlOw0KICAgIH0NCiAgICBwYXRjaEF0dHIoZWwsIGtleSwgbmV4dFZhbHVlLCBpc1NWRyk7DQogIH0NCn07DQpmdW5jdGlvbiBzaG91bGRTZXRBc1Byb3AoZWwsIGtleSwgdmFsdWUsIGlzU1ZHKSB7DQogIGlmIChpc1NWRykgew0KICAgIGlmIChrZXkgPT09ICJpbm5lckhUTUwiIHx8IGtleSA9PT0gInRleHRDb250ZW50Iikgew0KICAgICAgcmV0dXJuIHRydWU7DQogICAgfQ0KICAgIGlmIChrZXkgaW4gZWwgJiYgaXNOYXRpdmVPbihrZXkpICYmIGlzRnVuY3Rpb24odmFsdWUpKSB7DQogICAgICByZXR1cm4gdHJ1ZTsNCiAgICB9DQogICAgcmV0dXJuIGZhbHNlOw0KICB9DQogIGlmIChrZXkgPT09ICJzcGVsbGNoZWNrIiB8fCBrZXkgPT09ICJkcmFnZ2FibGUiIHx8IGtleSA9PT0gInRyYW5zbGF0ZSIgfHwga2V5ID09PSAiYXV0b2NvcnJlY3QiKSB7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9DQogIGlmIChrZXkgPT09ICJmb3JtIikgew0KICAgIHJldHVybiBmYWxzZTsNCiAgfQ0KICBpZiAoa2V5ID09PSAibGlzdCIgJiYgZWwudGFnTmFtZSA9PT0gIklOUFVUIikgew0KICAgIHJldHVybiBmYWxzZTsNCiAgfQ0KICBpZiAoa2V5ID09PSAidHlwZSIgJiYgZWwudGFnTmFtZSA9PT0gIlRFWFRBUkVBIikgew0KICAgIHJldHVybiBmYWxzZTsNCiAgfQ0KICBpZiAoa2V5ID09PSAid2lkdGgiIHx8IGtleSA9PT0gImhlaWdodCIpIHsNCiAgICBjb25zdCB0YWcgPSBlbC50YWdOYW1lOw0KICAgIGlmICh0YWcgPT09ICJJTUciIHx8IHRhZyA9PT0gIlZJREVPIiB8fCB0YWcgPT09ICJDQU5WQVMiIHx8IHRhZyA9PT0gIlNPVVJDRSIpIHsNCiAgICAgIHJldHVybiBmYWxzZTsNCiAgICB9DQogIH0NCiAgaWYgKGlzTmF0aXZlT24oa2V5KSAmJiBpc1N0cmluZyh2YWx1ZSkpIHsNCiAgICByZXR1cm4gZmFsc2U7DQogIH0NCiAgcmV0dXJuIGtleSBpbiBlbDsNCn0NCg0KY29uc3QgUkVNT1ZBTCA9IHt9Ow0KLyohICNfX05PX1NJREVfRUZGRUNUU19fICovDQovLyBAX19OT19TSURFX0VGRkVDVFNfXw0KZnVuY3Rpb24gZGVmaW5lQ3VzdG9tRWxlbWVudChvcHRpb25zLCBleHRyYU9wdGlvbnMsIF9jcmVhdGVBcHApIHsNCiAgY29uc3QgQ29tcCA9IGRlZmluZUNvbXBvbmVudChvcHRpb25zLCBleHRyYU9wdGlvbnMpOw0KICBpZiAoaXNQbGFpbk9iamVjdChDb21wKSkgZXh0ZW5kKENvbXAsIGV4dHJhT3B0aW9ucyk7DQogIGNsYXNzIFZ1ZUN1c3RvbUVsZW1lbnQgZXh0ZW5kcyBWdWVFbGVtZW50IHsNCiAgICBjb25zdHJ1Y3Rvcihpbml0aWFsUHJvcHMpIHsNCiAgICAgIHN1cGVyKENvbXAsIGluaXRpYWxQcm9wcywgX2NyZWF0ZUFwcCk7DQogICAgfQ0KICB9DQogIFZ1ZUN1c3RvbUVsZW1lbnQuZGVmID0gQ29tcDsNCiAgcmV0dXJuIFZ1ZUN1c3RvbUVsZW1lbnQ7DQp9DQovKiEgI19fTk9fU0lERV9FRkZFQ1RTX18gKi8NCmNvbnN0IGRlZmluZVNTUkN1c3RvbUVsZW1lbnQgPSAvKiBAX19OT19TSURFX0VGRkVDVFNfXyAqLyAob3B0aW9ucywgZXh0cmFPcHRpb25zKSA9PiB7DQogIHJldHVybiAvKiBAX19QVVJFX18gKi8gZGVmaW5lQ3VzdG9tRWxlbWVudChvcHRpb25zLCBleHRyYU9wdGlvbnMsIGNyZWF0ZVNTUkFwcCk7DQp9Ow0KY29uc3QgQmFzZUNsYXNzID0gdHlwZW9mIEhUTUxFbGVtZW50ICE9PSAidW5kZWZpbmVkIiA/IEhUTUxFbGVtZW50IDogY2xhc3Mgew0KfTsNCmNsYXNzIFZ1ZUVsZW1lbnQgZXh0ZW5kcyBCYXNlQ2xhc3Mgew0KICBjb25zdHJ1Y3RvcihfZGVmLCBfcHJvcHMgPSB7fSwgX2NyZWF0ZUFwcCA9IGNyZWF0ZUFwcCkgew0KICAgIHN1cGVyKCk7DQogICAgdGhpcy5fZGVmID0gX2RlZjsNCiAgICB0aGlzLl9wcm9wcyA9IF9wcm9wczsNCiAgICB0aGlzLl9jcmVhdGVBcHAgPSBfY3JlYXRlQXBwOw0KICAgIHRoaXMuX2lzVnVlQ0UgPSB0cnVlOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuX2luc3RhbmNlID0gbnVsbDsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLl9hcHAgPSBudWxsOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuX25vbmNlID0gdGhpcy5fZGVmLm5vbmNlOw0KICAgIHRoaXMuX2Nvbm5lY3RlZCA9IGZhbHNlOw0KICAgIHRoaXMuX3Jlc29sdmVkID0gZmFsc2U7DQogICAgdGhpcy5fbnVtYmVyUHJvcHMgPSBudWxsOw0KICAgIHRoaXMuX3N0eWxlQ2hpbGRyZW4gPSAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtTZXQoKTsNCiAgICB0aGlzLl9vYiA9IG51bGw7DQogICAgaWYgKHRoaXMuc2hhZG93Um9vdCAmJiBfY3JlYXRlQXBwICE9PSBjcmVhdGVBcHApIHsNCiAgICAgIHRoaXMuX3Jvb3QgPSB0aGlzLnNoYWRvd1Jvb3Q7DQogICAgfSBlbHNlIHsNCiAgICAgIGlmICh0aGlzLnNoYWRvd1Jvb3QpIHsNCiAgICAgICAgd2FybigNCiAgICAgICAgICBgQ3VzdG9tIGVsZW1lbnQgaGFzIHByZS1yZW5kZXJlZCBkZWNsYXJhdGl2ZSBzaGFkb3cgcm9vdCBidXQgaXMgbm90IGRlZmluZWQgYXMgaHlkcmF0YWJsZS4gVXNlIFxgZGVmaW5lU1NSQ3VzdG9tRWxlbWVudFxgLmANCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICAgIGlmIChfZGVmLnNoYWRvd1Jvb3QgIT09IGZhbHNlKSB7DQogICAgICAgIHRoaXMuYXR0YWNoU2hhZG93KHsgbW9kZTogIm9wZW4iIH0pOw0KICAgICAgICB0aGlzLl9yb290ID0gdGhpcy5zaGFkb3dSb290Ow0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgdGhpcy5fcm9vdCA9IHRoaXM7DQogICAgICB9DQogICAgfQ0KICB9DQogIGNvbm5lY3RlZENhbGxiYWNrKCkgew0KICAgIGlmICghdGhpcy5pc0Nvbm5lY3RlZCkgcmV0dXJuOw0KICAgIGlmICghdGhpcy5zaGFkb3dSb290ICYmICF0aGlzLl9yZXNvbHZlZCkgew0KICAgICAgdGhpcy5fcGFyc2VTbG90cygpOw0KICAgIH0NCiAgICB0aGlzLl9jb25uZWN0ZWQgPSB0cnVlOw0KICAgIGxldCBwYXJlbnQgPSB0aGlzOw0KICAgIHdoaWxlIChwYXJlbnQgPSBwYXJlbnQgJiYgKHBhcmVudC5wYXJlbnROb2RlIHx8IHBhcmVudC5ob3N0KSkgew0KICAgICAgaWYgKHBhcmVudCBpbnN0YW5jZW9mIFZ1ZUVsZW1lbnQpIHsNCiAgICAgICAgdGhpcy5fcGFyZW50ID0gcGFyZW50Ow0KICAgICAgICBicmVhazsNCiAgICAgIH0NCiAgICB9DQogICAgaWYgKCF0aGlzLl9pbnN0YW5jZSkgew0KICAgICAgaWYgKHRoaXMuX3Jlc29sdmVkKSB7DQogICAgICAgIHRoaXMuX21vdW50KHRoaXMuX2RlZik7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBpZiAocGFyZW50ICYmIHBhcmVudC5fcGVuZGluZ1Jlc29sdmUpIHsNCiAgICAgICAgICB0aGlzLl9wZW5kaW5nUmVzb2x2ZSA9IHBhcmVudC5fcGVuZGluZ1Jlc29sdmUudGhlbigoKSA9PiB7DQogICAgICAgICAgICB0aGlzLl9wZW5kaW5nUmVzb2x2ZSA9IHZvaWQgMDsNCiAgICAgICAgICAgIHRoaXMuX3Jlc29sdmVEZWYoKTsNCiAgICAgICAgICB9KTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICB0aGlzLl9yZXNvbHZlRGVmKCk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH0NCiAgX3NldFBhcmVudChwYXJlbnQgPSB0aGlzLl9wYXJlbnQpIHsNCiAgICBpZiAocGFyZW50KSB7DQogICAgICB0aGlzLl9pbnN0YW5jZS5wYXJlbnQgPSBwYXJlbnQuX2luc3RhbmNlOw0KICAgICAgdGhpcy5faW5oZXJpdFBhcmVudENvbnRleHQocGFyZW50KTsNCiAgICB9DQogIH0NCiAgX2luaGVyaXRQYXJlbnRDb250ZXh0KHBhcmVudCA9IHRoaXMuX3BhcmVudCkgew0KICAgIGlmIChwYXJlbnQgJiYgdGhpcy5fYXBwKSB7DQogICAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YoDQogICAgICAgIHRoaXMuX2FwcC5fY29udGV4dC5wcm92aWRlcywNCiAgICAgICAgcGFyZW50Ll9pbnN0YW5jZS5wcm92aWRlcw0KICAgICAgKTsNCiAgICB9DQogIH0NCiAgZGlzY29ubmVjdGVkQ2FsbGJhY2soKSB7DQogICAgdGhpcy5fY29ubmVjdGVkID0gZmFsc2U7DQogICAgbmV4dFRpY2soKCkgPT4gew0KICAgICAgaWYgKCF0aGlzLl9jb25uZWN0ZWQpIHsNCiAgICAgICAgaWYgKHRoaXMuX29iKSB7DQogICAgICAgICAgdGhpcy5fb2IuZGlzY29ubmVjdCgpOw0KICAgICAgICAgIHRoaXMuX29iID0gbnVsbDsNCiAgICAgICAgfQ0KICAgICAgICB0aGlzLl9hcHAgJiYgdGhpcy5fYXBwLnVubW91bnQoKTsNCiAgICAgICAgaWYgKHRoaXMuX2luc3RhbmNlKSB0aGlzLl9pbnN0YW5jZS5jZSA9IHZvaWQgMDsNCiAgICAgICAgdGhpcy5fYXBwID0gdGhpcy5faW5zdGFuY2UgPSBudWxsOw0KICAgICAgfQ0KICAgIH0pOw0KICB9DQogIC8qKg0KICAgKiByZXNvbHZlIGlubmVyIGNvbXBvbmVudCBkZWZpbml0aW9uIChoYW5kbGUgcG9zc2libGUgYXN5bmMgY29tcG9uZW50KQ0KICAgKi8NCiAgX3Jlc29sdmVEZWYoKSB7DQogICAgaWYgKHRoaXMuX3BlbmRpbmdSZXNvbHZlKSB7DQogICAgICByZXR1cm47DQogICAgfQ0KICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5hdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKSB7DQogICAgICB0aGlzLl9zZXRBdHRyKHRoaXMuYXR0cmlidXRlc1tpXS5uYW1lKTsNCiAgICB9DQogICAgdGhpcy5fb2IgPSBuZXcgTXV0YXRpb25PYnNlcnZlcigobXV0YXRpb25zKSA9PiB7DQogICAgICBmb3IgKGNvbnN0IG0gb2YgbXV0YXRpb25zKSB7DQogICAgICAgIHRoaXMuX3NldEF0dHIobS5hdHRyaWJ1dGVOYW1lKTsNCiAgICAgIH0NCiAgICB9KTsNCiAgICB0aGlzLl9vYi5vYnNlcnZlKHRoaXMsIHsgYXR0cmlidXRlczogdHJ1ZSB9KTsNCiAgICBjb25zdCByZXNvbHZlID0gKGRlZiwgaXNBc3luYyA9IGZhbHNlKSA9PiB7DQogICAgICB0aGlzLl9yZXNvbHZlZCA9IHRydWU7DQogICAgICB0aGlzLl9wZW5kaW5nUmVzb2x2ZSA9IHZvaWQgMDsNCiAgICAgIGNvbnN0IHsgcHJvcHMsIHN0eWxlcyB9ID0gZGVmOw0KICAgICAgbGV0IG51bWJlclByb3BzOw0KICAgICAgaWYgKHByb3BzICYmICFpc0FycmF5KHByb3BzKSkgew0KICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBwcm9wcykgew0KICAgICAgICAgIGNvbnN0IG9wdCA9IHByb3BzW2tleV07DQogICAgICAgICAgaWYgKG9wdCA9PT0gTnVtYmVyIHx8IG9wdCAmJiBvcHQudHlwZSA9PT0gTnVtYmVyKSB7DQogICAgICAgICAgICBpZiAoa2V5IGluIHRoaXMuX3Byb3BzKSB7DQogICAgICAgICAgICAgIHRoaXMuX3Byb3BzW2tleV0gPSB0b051bWJlcih0aGlzLl9wcm9wc1trZXldKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIChudW1iZXJQcm9wcyB8fCAobnVtYmVyUHJvcHMgPSAvKiBAX19QVVJFX18gKi8gT2JqZWN0LmNyZWF0ZShudWxsKSkpW2NhbWVsaXplKGtleSldID0gdHJ1ZTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIHRoaXMuX251bWJlclByb3BzID0gbnVtYmVyUHJvcHM7DQogICAgICB0aGlzLl9yZXNvbHZlUHJvcHMoZGVmKTsNCiAgICAgIGlmICh0aGlzLnNoYWRvd1Jvb3QpIHsNCiAgICAgICAgdGhpcy5fYXBwbHlTdHlsZXMoc3R5bGVzKTsNCiAgICAgIH0gZWxzZSBpZiAoc3R5bGVzKSB7DQogICAgICAgIHdhcm4oDQogICAgICAgICAgIkN1c3RvbSBlbGVtZW50IHN0eWxlIGluamVjdGlvbiBpcyBub3Qgc3VwcG9ydGVkIHdoZW4gdXNpbmcgc2hhZG93Um9vdDogZmFsc2UiDQogICAgICAgICk7DQogICAgICB9DQogICAgICB0aGlzLl9tb3VudChkZWYpOw0KICAgIH07DQogICAgY29uc3QgYXN5bmNEZWYgPSB0aGlzLl9kZWYuX19hc3luY0xvYWRlcjsNCiAgICBpZiAoYXN5bmNEZWYpIHsNCiAgICAgIHRoaXMuX3BlbmRpbmdSZXNvbHZlID0gYXN5bmNEZWYoKS50aGVuKChkZWYpID0+IHsNCiAgICAgICAgZGVmLmNvbmZpZ3VyZUFwcCA9IHRoaXMuX2RlZi5jb25maWd1cmVBcHA7DQogICAgICAgIHJlc29sdmUodGhpcy5fZGVmID0gZGVmLCB0cnVlKTsNCiAgICAgIH0pOw0KICAgIH0gZWxzZSB7DQogICAgICByZXNvbHZlKHRoaXMuX2RlZik7DQogICAgfQ0KICB9DQogIF9tb3VudChkZWYpIHsNCiAgICBpZiAoIWRlZi5uYW1lKSB7DQogICAgICBkZWYubmFtZSA9ICJWdWVFbGVtZW50IjsNCiAgICB9DQogICAgdGhpcy5fYXBwID0gdGhpcy5fY3JlYXRlQXBwKGRlZik7DQogICAgdGhpcy5faW5oZXJpdFBhcmVudENvbnRleHQoKTsNCiAgICBpZiAoZGVmLmNvbmZpZ3VyZUFwcCkgew0KICAgICAgZGVmLmNvbmZpZ3VyZUFwcCh0aGlzLl9hcHApOw0KICAgIH0NCiAgICB0aGlzLl9hcHAuX2NlVk5vZGUgPSB0aGlzLl9jcmVhdGVWTm9kZSgpOw0KICAgIHRoaXMuX2FwcC5tb3VudCh0aGlzLl9yb290KTsNCiAgICBjb25zdCBleHBvc2VkID0gdGhpcy5faW5zdGFuY2UgJiYgdGhpcy5faW5zdGFuY2UuZXhwb3NlZDsNCiAgICBpZiAoIWV4cG9zZWQpIHJldHVybjsNCiAgICBmb3IgKGNvbnN0IGtleSBpbiBleHBvc2VkKSB7DQogICAgICBpZiAoIWhhc093bih0aGlzLCBrZXkpKSB7DQogICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBrZXksIHsNCiAgICAgICAgICAvLyB1bndyYXAgcmVmIHRvIGJlIGNvbnNpc3RlbnQgd2l0aCBwdWJsaWMgaW5zdGFuY2UgYmVoYXZpb3INCiAgICAgICAgICBnZXQ6ICgpID0+IHVucmVmKGV4cG9zZWRba2V5XSkNCiAgICAgICAgfSk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICB3YXJuKGBFeHBvc2VkIHByb3BlcnR5ICIke2tleX0iIGFscmVhZHkgZXhpc3RzIG9uIGN1c3RvbSBlbGVtZW50LmApOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICBfcmVzb2x2ZVByb3BzKGRlZikgew0KICAgIGNvbnN0IHsgcHJvcHMgfSA9IGRlZjsNCiAgICBjb25zdCBkZWNsYXJlZFByb3BLZXlzID0gaXNBcnJheShwcm9wcykgPyBwcm9wcyA6IE9iamVjdC5rZXlzKHByb3BzIHx8IHt9KTsNCiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyh0aGlzKSkgew0KICAgICAgaWYgKGtleVswXSAhPT0gIl8iICYmIGRlY2xhcmVkUHJvcEtleXMuaW5jbHVkZXMoa2V5KSkgew0KICAgICAgICB0aGlzLl9zZXRQcm9wKGtleSwgdGhpc1trZXldKTsNCiAgICAgIH0NCiAgICB9DQogICAgZm9yIChjb25zdCBrZXkgb2YgZGVjbGFyZWRQcm9wS2V5cy5tYXAoY2FtZWxpemUpKSB7DQogICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywga2V5LCB7DQogICAgICAgIGdldCgpIHsNCiAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0UHJvcChrZXkpOw0KICAgICAgICB9LA0KICAgICAgICBzZXQodmFsKSB7DQogICAgICAgICAgdGhpcy5fc2V0UHJvcChrZXksIHZhbCwgdHJ1ZSwgdHJ1ZSk7DQogICAgICAgIH0NCiAgICAgIH0pOw0KICAgIH0NCiAgfQ0KICBfc2V0QXR0cihrZXkpIHsNCiAgICBpZiAoa2V5LnN0YXJ0c1dpdGgoImRhdGEtdi0iKSkgcmV0dXJuOw0KICAgIGNvbnN0IGhhcyA9IHRoaXMuaGFzQXR0cmlidXRlKGtleSk7DQogICAgbGV0IHZhbHVlID0gaGFzID8gdGhpcy5nZXRBdHRyaWJ1dGUoa2V5KSA6IFJFTU9WQUw7DQogICAgY29uc3QgY2FtZWxLZXkgPSBjYW1lbGl6ZShrZXkpOw0KICAgIGlmIChoYXMgJiYgdGhpcy5fbnVtYmVyUHJvcHMgJiYgdGhpcy5fbnVtYmVyUHJvcHNbY2FtZWxLZXldKSB7DQogICAgICB2YWx1ZSA9IHRvTnVtYmVyKHZhbHVlKTsNCiAgICB9DQogICAgdGhpcy5fc2V0UHJvcChjYW1lbEtleSwgdmFsdWUsIGZhbHNlLCB0cnVlKTsNCiAgfQ0KICAvKioNCiAgICogQGludGVybmFsDQogICAqLw0KICBfZ2V0UHJvcChrZXkpIHsNCiAgICByZXR1cm4gdGhpcy5fcHJvcHNba2V5XTsNCiAgfQ0KICAvKioNCiAgICogQGludGVybmFsDQogICAqLw0KICBfc2V0UHJvcChrZXksIHZhbCwgc2hvdWxkUmVmbGVjdCA9IHRydWUsIHNob3VsZFVwZGF0ZSA9IGZhbHNlKSB7DQogICAgaWYgKHZhbCAhPT0gdGhpcy5fcHJvcHNba2V5XSkgew0KICAgICAgaWYgKHZhbCA9PT0gUkVNT1ZBTCkgew0KICAgICAgICBkZWxldGUgdGhpcy5fcHJvcHNba2V5XTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHRoaXMuX3Byb3BzW2tleV0gPSB2YWw7DQogICAgICAgIGlmIChrZXkgPT09ICJrZXkiICYmIHRoaXMuX2FwcCkgew0KICAgICAgICAgIHRoaXMuX2FwcC5fY2VWTm9kZS5rZXkgPSB2YWw7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGlmIChzaG91bGRVcGRhdGUgJiYgdGhpcy5faW5zdGFuY2UpIHsNCiAgICAgICAgdGhpcy5fdXBkYXRlKCk7DQogICAgICB9DQogICAgICBpZiAoc2hvdWxkUmVmbGVjdCkgew0KICAgICAgICBjb25zdCBvYiA9IHRoaXMuX29iOw0KICAgICAgICBvYiAmJiBvYi5kaXNjb25uZWN0KCk7DQogICAgICAgIGlmICh2YWwgPT09IHRydWUpIHsNCiAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZShoeXBoZW5hdGUoa2V5KSwgIiIpOw0KICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICJzdHJpbmciIHx8IHR5cGVvZiB2YWwgPT09ICJudW1iZXIiKSB7DQogICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUoaHlwaGVuYXRlKGtleSksIHZhbCArICIiKTsNCiAgICAgICAgfSBlbHNlIGlmICghdmFsKSB7DQogICAgICAgICAgdGhpcy5yZW1vdmVBdHRyaWJ1dGUoaHlwaGVuYXRlKGtleSkpOw0KICAgICAgICB9DQogICAgICAgIG9iICYmIG9iLm9ic2VydmUodGhpcywgeyBhdHRyaWJ1dGVzOiB0cnVlIH0pOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICBfdXBkYXRlKCkgew0KICAgIGNvbnN0IHZub2RlID0gdGhpcy5fY3JlYXRlVk5vZGUoKTsNCiAgICBpZiAodGhpcy5fYXBwKSB2bm9kZS5hcHBDb250ZXh0ID0gdGhpcy5fYXBwLl9jb250ZXh0Ow0KICAgIHJlbmRlcih2bm9kZSwgdGhpcy5fcm9vdCk7DQogIH0NCiAgX2NyZWF0ZVZOb2RlKCkgew0KICAgIGNvbnN0IGJhc2VQcm9wcyA9IHt9Ow0KICAgIGlmICghdGhpcy5zaGFkb3dSb290KSB7DQogICAgICBiYXNlUHJvcHMub25Wbm9kZU1vdW50ZWQgPSBiYXNlUHJvcHMub25Wbm9kZVVwZGF0ZWQgPSB0aGlzLl9yZW5kZXJTbG90cy5iaW5kKHRoaXMpOw0KICAgIH0NCiAgICBjb25zdCB2bm9kZSA9IGNyZWF0ZVZOb2RlKHRoaXMuX2RlZiwgZXh0ZW5kKGJhc2VQcm9wcywgdGhpcy5fcHJvcHMpKTsNCiAgICBpZiAoIXRoaXMuX2luc3RhbmNlKSB7DQogICAgICB2bm9kZS5jZSA9IChpbnN0YW5jZSkgPT4gew0KICAgICAgICB0aGlzLl9pbnN0YW5jZSA9IGluc3RhbmNlOw0KICAgICAgICBpbnN0YW5jZS5jZSA9IHRoaXM7DQogICAgICAgIGluc3RhbmNlLmlzQ0UgPSB0cnVlOw0KICAgICAgICB7DQogICAgICAgICAgaW5zdGFuY2UuY2VSZWxvYWQgPSAobmV3U3R5bGVzKSA9PiB7DQogICAgICAgICAgICBpZiAodGhpcy5fc3R5bGVzKSB7DQogICAgICAgICAgICAgIHRoaXMuX3N0eWxlcy5mb3JFYWNoKChzKSA9PiB0aGlzLl9yb290LnJlbW92ZUNoaWxkKHMpKTsNCiAgICAgICAgICAgICAgdGhpcy5fc3R5bGVzLmxlbmd0aCA9IDA7DQogICAgICAgICAgICB9DQogICAgICAgICAgICB0aGlzLl9hcHBseVN0eWxlcyhuZXdTdHlsZXMpOw0KICAgICAgICAgICAgdGhpcy5faW5zdGFuY2UgPSBudWxsOw0KICAgICAgICAgICAgdGhpcy5fdXBkYXRlKCk7DQogICAgICAgICAgfTsNCiAgICAgICAgfQ0KICAgICAgICBjb25zdCBkaXNwYXRjaCA9IChldmVudCwgYXJncykgPT4gew0KICAgICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudCgNCiAgICAgICAgICAgIG5ldyBDdXN0b21FdmVudCgNCiAgICAgICAgICAgICAgZXZlbnQsDQogICAgICAgICAgICAgIGlzUGxhaW5PYmplY3QoYXJnc1swXSkgPyBleHRlbmQoeyBkZXRhaWw6IGFyZ3MgfSwgYXJnc1swXSkgOiB7IGRldGFpbDogYXJncyB9DQogICAgICAgICAgICApDQogICAgICAgICAgKTsNCiAgICAgICAgfTsNCiAgICAgICAgaW5zdGFuY2UuZW1pdCA9IChldmVudCwgLi4uYXJncykgPT4gew0KICAgICAgICAgIGRpc3BhdGNoKGV2ZW50LCBhcmdzKTsNCiAgICAgICAgICBpZiAoaHlwaGVuYXRlKGV2ZW50KSAhPT0gZXZlbnQpIHsNCiAgICAgICAgICAgIGRpc3BhdGNoKGh5cGhlbmF0ZShldmVudCksIGFyZ3MpOw0KICAgICAgICAgIH0NCiAgICAgICAgfTsNCiAgICAgICAgdGhpcy5fc2V0UGFyZW50KCk7DQogICAgICB9Ow0KICAgIH0NCiAgICByZXR1cm4gdm5vZGU7DQogIH0NCiAgX2FwcGx5U3R5bGVzKHN0eWxlcywgb3duZXIpIHsNCiAgICBpZiAoIXN0eWxlcykgcmV0dXJuOw0KICAgIGlmIChvd25lcikgew0KICAgICAgaWYgKG93bmVyID09PSB0aGlzLl9kZWYgfHwgdGhpcy5fc3R5bGVDaGlsZHJlbi5oYXMob3duZXIpKSB7DQogICAgICAgIHJldHVybjsNCiAgICAgIH0NCiAgICAgIHRoaXMuX3N0eWxlQ2hpbGRyZW4uYWRkKG93bmVyKTsNCiAgICB9DQogICAgY29uc3Qgbm9uY2UgPSB0aGlzLl9ub25jZTsNCiAgICBmb3IgKGxldCBpID0gc3R5bGVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7DQogICAgICBjb25zdCBzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3R5bGUiKTsNCiAgICAgIGlmIChub25jZSkgcy5zZXRBdHRyaWJ1dGUoIm5vbmNlIiwgbm9uY2UpOw0KICAgICAgcy50ZXh0Q29udGVudCA9IHN0eWxlc1tpXTsNCiAgICAgIHRoaXMuc2hhZG93Um9vdC5wcmVwZW5kKHMpOw0KICAgICAgew0KICAgICAgICBpZiAob3duZXIpIHsNCiAgICAgICAgICBpZiAob3duZXIuX19obXJJZCkgew0KICAgICAgICAgICAgaWYgKCF0aGlzLl9jaGlsZFN0eWxlcykgdGhpcy5fY2hpbGRTdHlsZXMgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOw0KICAgICAgICAgICAgbGV0IGVudHJ5ID0gdGhpcy5fY2hpbGRTdHlsZXMuZ2V0KG93bmVyLl9faG1ySWQpOw0KICAgICAgICAgICAgaWYgKCFlbnRyeSkgew0KICAgICAgICAgICAgICB0aGlzLl9jaGlsZFN0eWxlcy5zZXQob3duZXIuX19obXJJZCwgZW50cnkgPSBbXSk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBlbnRyeS5wdXNoKHMpOw0KICAgICAgICAgIH0NCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAodGhpcy5fc3R5bGVzIHx8ICh0aGlzLl9zdHlsZXMgPSBbXSkpLnB1c2gocyk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH0NCiAgLyoqDQogICAqIE9ubHkgY2FsbGVkIHdoZW4gc2hhZG93Um9vdCBpcyBmYWxzZQ0KICAgKi8NCiAgX3BhcnNlU2xvdHMoKSB7DQogICAgY29uc3Qgc2xvdHMgPSB0aGlzLl9zbG90cyA9IHt9Ow0KICAgIGxldCBuOw0KICAgIHdoaWxlIChuID0gdGhpcy5maXJzdENoaWxkKSB7DQogICAgICBjb25zdCBzbG90TmFtZSA9IG4ubm9kZVR5cGUgPT09IDEgJiYgbi5nZXRBdHRyaWJ1dGUoInNsb3QiKSB8fCAiZGVmYXVsdCI7DQogICAgICAoc2xvdHNbc2xvdE5hbWVdIHx8IChzbG90c1tzbG90TmFtZV0gPSBbXSkpLnB1c2gobik7DQogICAgICB0aGlzLnJlbW92ZUNoaWxkKG4pOw0KICAgIH0NCiAgfQ0KICAvKioNCiAgICogT25seSBjYWxsZWQgd2hlbiBzaGFkb3dSb290IGlzIGZhbHNlDQogICAqLw0KICBfcmVuZGVyU2xvdHMoKSB7DQogICAgY29uc3Qgb3V0bGV0cyA9ICh0aGlzLl90ZWxlcG9ydFRhcmdldCB8fCB0aGlzKS5xdWVyeVNlbGVjdG9yQWxsKCJzbG90Iik7DQogICAgY29uc3Qgc2NvcGVJZCA9IHRoaXMuX2luc3RhbmNlLnR5cGUuX19zY29wZUlkOw0KICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3V0bGV0cy5sZW5ndGg7IGkrKykgew0KICAgICAgY29uc3QgbyA9IG91dGxldHNbaV07DQogICAgICBjb25zdCBzbG90TmFtZSA9IG8uZ2V0QXR0cmlidXRlKCJuYW1lIikgfHwgImRlZmF1bHQiOw0KICAgICAgY29uc3QgY29udGVudCA9IHRoaXMuX3Nsb3RzW3Nsb3ROYW1lXTsNCiAgICAgIGNvbnN0IHBhcmVudCA9IG8ucGFyZW50Tm9kZTsNCiAgICAgIGlmIChjb250ZW50KSB7DQogICAgICAgIGZvciAoY29uc3QgbiBvZiBjb250ZW50KSB7DQogICAgICAgICAgaWYgKHNjb3BlSWQgJiYgbi5ub2RlVHlwZSA9PT0gMSkgew0KICAgICAgICAgICAgY29uc3QgaWQgPSBzY29wZUlkICsgIi1zIjsNCiAgICAgICAgICAgIGNvbnN0IHdhbGtlciA9IGRvY3VtZW50LmNyZWF0ZVRyZWVXYWxrZXIobiwgMSk7DQogICAgICAgICAgICBuLnNldEF0dHJpYnV0ZShpZCwgIiIpOw0KICAgICAgICAgICAgbGV0IGNoaWxkOw0KICAgICAgICAgICAgd2hpbGUgKGNoaWxkID0gd2Fsa2VyLm5leHROb2RlKCkpIHsNCiAgICAgICAgICAgICAgY2hpbGQuc2V0QXR0cmlidXRlKGlkLCAiIik7DQogICAgICAgICAgICB9DQogICAgICAgICAgfQ0KICAgICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUobiwgbyk7DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHdoaWxlIChvLmZpcnN0Q2hpbGQpIHBhcmVudC5pbnNlcnRCZWZvcmUoby5maXJzdENoaWxkLCBvKTsNCiAgICAgIH0NCiAgICAgIHBhcmVudC5yZW1vdmVDaGlsZChvKTsNCiAgICB9DQogIH0NCiAgLyoqDQogICAqIEBpbnRlcm5hbA0KICAgKi8NCiAgX2luamVjdENoaWxkU3R5bGUoY29tcCkgew0KICAgIHRoaXMuX2FwcGx5U3R5bGVzKGNvbXAuc3R5bGVzLCBjb21wKTsNCiAgfQ0KICAvKioNCiAgICogQGludGVybmFsDQogICAqLw0KICBfcmVtb3ZlQ2hpbGRTdHlsZShjb21wKSB7DQogICAgew0KICAgICAgdGhpcy5fc3R5bGVDaGlsZHJlbi5kZWxldGUoY29tcCk7DQogICAgICBpZiAodGhpcy5fY2hpbGRTdHlsZXMgJiYgY29tcC5fX2htcklkKSB7DQogICAgICAgIGNvbnN0IG9sZFN0eWxlcyA9IHRoaXMuX2NoaWxkU3R5bGVzLmdldChjb21wLl9faG1ySWQpOw0KICAgICAgICBpZiAob2xkU3R5bGVzKSB7DQogICAgICAgICAgb2xkU3R5bGVzLmZvckVhY2goKHMpID0+IHRoaXMuX3Jvb3QucmVtb3ZlQ2hpbGQocykpOw0KICAgICAgICAgIG9sZFN0eWxlcy5sZW5ndGggPSAwOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICB9DQp9DQpmdW5jdGlvbiB1c2VIb3N0KGNhbGxlcikgew0KICBjb25zdCBpbnN0YW5jZSA9IGdldEN1cnJlbnRJbnN0YW5jZSgpOw0KICBjb25zdCBlbCA9IGluc3RhbmNlICYmIGluc3RhbmNlLmNlOw0KICBpZiAoZWwpIHsNCiAgICByZXR1cm4gZWw7DQogIH0gZWxzZSB7DQogICAgaWYgKCFpbnN0YW5jZSkgew0KICAgICAgd2FybigNCiAgICAgICAgYCR7Y2FsbGVyIHx8ICJ1c2VIb3N0In0gY2FsbGVkIHdpdGhvdXQgYW4gYWN0aXZlIGNvbXBvbmVudCBpbnN0YW5jZS5gDQogICAgICApOw0KICAgIH0gZWxzZSB7DQogICAgICB3YXJuKA0KICAgICAgICBgJHtjYWxsZXIgfHwgInVzZUhvc3QifSBjYW4gb25seSBiZSB1c2VkIGluIGNvbXBvbmVudHMgZGVmaW5lZCB2aWEgZGVmaW5lQ3VzdG9tRWxlbWVudC5gDQogICAgICApOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gbnVsbDsNCn0NCmZ1bmN0aW9uIHVzZVNoYWRvd1Jvb3QoKSB7DQogIGNvbnN0IGVsID0gdXNlSG9zdCgidXNlU2hhZG93Um9vdCIpIDsNCiAgcmV0dXJuIGVsICYmIGVsLnNoYWRvd1Jvb3Q7DQp9DQoNCmZ1bmN0aW9uIHVzZUNzc01vZHVsZShuYW1lID0gIiRzdHlsZSIpIHsNCiAgew0KICAgIGNvbnN0IGluc3RhbmNlID0gZ2V0Q3VycmVudEluc3RhbmNlKCk7DQogICAgaWYgKCFpbnN0YW5jZSkgew0KICAgICAgd2FybihgdXNlQ3NzTW9kdWxlIG11c3QgYmUgY2FsbGVkIGluc2lkZSBzZXR1cCgpYCk7DQogICAgICByZXR1cm4gRU1QVFlfT0JKOw0KICAgIH0NCiAgICBjb25zdCBtb2R1bGVzID0gaW5zdGFuY2UudHlwZS5fX2Nzc01vZHVsZXM7DQogICAgaWYgKCFtb2R1bGVzKSB7DQogICAgICB3YXJuKGBDdXJyZW50IGluc3RhbmNlIGRvZXMgbm90IGhhdmUgQ1NTIG1vZHVsZXMgaW5qZWN0ZWQuYCk7DQogICAgICByZXR1cm4gRU1QVFlfT0JKOw0KICAgIH0NCiAgICBjb25zdCBtb2QgPSBtb2R1bGVzW25hbWVdOw0KICAgIGlmICghbW9kKSB7DQogICAgICB3YXJuKGBDdXJyZW50IGluc3RhbmNlIGRvZXMgbm90IGhhdmUgQ1NTIG1vZHVsZSBuYW1lZCAiJHtuYW1lfSIuYCk7DQogICAgICByZXR1cm4gRU1QVFlfT0JKOw0KICAgIH0NCiAgICByZXR1cm4gbW9kOw0KICB9DQp9DQoNCmNvbnN0IHBvc2l0aW9uTWFwID0gLyogQF9fUFVSRV9fICovIG5ldyBXZWFrTWFwKCk7DQpjb25zdCBuZXdQb3NpdGlvbk1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgV2Vha01hcCgpOw0KY29uc3QgbW92ZUNiS2V5ID0gU3ltYm9sKCJfbW92ZUNiIik7DQpjb25zdCBlbnRlckNiS2V5ID0gU3ltYm9sKCJfZW50ZXJDYiIpOw0KY29uc3QgZGVjb3JhdGUgPSAodCkgPT4gew0KICBkZWxldGUgdC5wcm9wcy5tb2RlOw0KICByZXR1cm4gdDsNCn07DQpjb25zdCBUcmFuc2l0aW9uR3JvdXBJbXBsID0gLyogQF9fUFVSRV9fICovIGRlY29yYXRlKHsNCiAgbmFtZTogIlRyYW5zaXRpb25Hcm91cCIsDQogIHByb3BzOiAvKiBAX19QVVJFX18gKi8gZXh0ZW5kKHt9LCBUcmFuc2l0aW9uUHJvcHNWYWxpZGF0b3JzLCB7DQogICAgdGFnOiBTdHJpbmcsDQogICAgbW92ZUNsYXNzOiBTdHJpbmcNCiAgfSksDQogIHNldHVwKHByb3BzLCB7IHNsb3RzIH0pIHsNCiAgICBjb25zdCBpbnN0YW5jZSA9IGdldEN1cnJlbnRJbnN0YW5jZSgpOw0KICAgIGNvbnN0IHN0YXRlID0gdXNlVHJhbnNpdGlvblN0YXRlKCk7DQogICAgbGV0IHByZXZDaGlsZHJlbjsNCiAgICBsZXQgY2hpbGRyZW47DQogICAgb25VcGRhdGVkKCgpID0+IHsNCiAgICAgIGlmICghcHJldkNoaWxkcmVuLmxlbmd0aCkgew0KICAgICAgICByZXR1cm47DQogICAgICB9DQogICAgICBjb25zdCBtb3ZlQ2xhc3MgPSBwcm9wcy5tb3ZlQ2xhc3MgfHwgYCR7cHJvcHMubmFtZSB8fCAidiJ9LW1vdmVgOw0KICAgICAgaWYgKCFoYXNDU1NUcmFuc2Zvcm0oDQogICAgICAgIHByZXZDaGlsZHJlblswXS5lbCwNCiAgICAgICAgaW5zdGFuY2Uudm5vZGUuZWwsDQogICAgICAgIG1vdmVDbGFzcw0KICAgICAgKSkgew0KICAgICAgICBwcmV2Q2hpbGRyZW4gPSBbXTsNCiAgICAgICAgcmV0dXJuOw0KICAgICAgfQ0KICAgICAgcHJldkNoaWxkcmVuLmZvckVhY2goY2FsbFBlbmRpbmdDYnMpOw0KICAgICAgcHJldkNoaWxkcmVuLmZvckVhY2gocmVjb3JkUG9zaXRpb24pOw0KICAgICAgY29uc3QgbW92ZWRDaGlsZHJlbiA9IHByZXZDaGlsZHJlbi5maWx0ZXIoYXBwbHlUcmFuc2xhdGlvbik7DQogICAgICBmb3JjZVJlZmxvdygpOw0KICAgICAgbW92ZWRDaGlsZHJlbi5mb3JFYWNoKChjKSA9PiB7DQogICAgICAgIGNvbnN0IGVsID0gYy5lbDsNCiAgICAgICAgY29uc3Qgc3R5bGUgPSBlbC5zdHlsZTsNCiAgICAgICAgYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCBtb3ZlQ2xhc3MpOw0KICAgICAgICBzdHlsZS50cmFuc2Zvcm0gPSBzdHlsZS53ZWJraXRUcmFuc2Zvcm0gPSBzdHlsZS50cmFuc2l0aW9uRHVyYXRpb24gPSAiIjsNCiAgICAgICAgY29uc3QgY2IgPSBlbFttb3ZlQ2JLZXldID0gKGUpID0+IHsNCiAgICAgICAgICBpZiAoZSAmJiBlLnRhcmdldCAhPT0gZWwpIHsNCiAgICAgICAgICAgIHJldHVybjsNCiAgICAgICAgICB9DQogICAgICAgICAgaWYgKCFlIHx8IC90cmFuc2Zvcm0kLy50ZXN0KGUucHJvcGVydHlOYW1lKSkgew0KICAgICAgICAgICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigidHJhbnNpdGlvbmVuZCIsIGNiKTsNCiAgICAgICAgICAgIGVsW21vdmVDYktleV0gPSBudWxsOw0KICAgICAgICAgICAgcmVtb3ZlVHJhbnNpdGlvbkNsYXNzKGVsLCBtb3ZlQ2xhc3MpOw0KICAgICAgICAgIH0NCiAgICAgICAgfTsNCiAgICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcigidHJhbnNpdGlvbmVuZCIsIGNiKTsNCiAgICAgIH0pOw0KICAgICAgcHJldkNoaWxkcmVuID0gW107DQogICAgfSk7DQogICAgcmV0dXJuICgpID0+IHsNCiAgICAgIGNvbnN0IHJhd1Byb3BzID0gdG9SYXcocHJvcHMpOw0KICAgICAgY29uc3QgY3NzVHJhbnNpdGlvblByb3BzID0gcmVzb2x2ZVRyYW5zaXRpb25Qcm9wcyhyYXdQcm9wcyk7DQogICAgICBsZXQgdGFnID0gcmF3UHJvcHMudGFnIHx8IEZyYWdtZW50Ow0KICAgICAgcHJldkNoaWxkcmVuID0gW107DQogICAgICBpZiAoY2hpbGRyZW4pIHsNCiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykgew0KICAgICAgICAgIGNvbnN0IGNoaWxkID0gY2hpbGRyZW5baV07DQogICAgICAgICAgaWYgKGNoaWxkLmVsICYmIGNoaWxkLmVsIGluc3RhbmNlb2YgRWxlbWVudCkgew0KICAgICAgICAgICAgcHJldkNoaWxkcmVuLnB1c2goY2hpbGQpOw0KICAgICAgICAgICAgc2V0VHJhbnNpdGlvbkhvb2tzKA0KICAgICAgICAgICAgICBjaGlsZCwNCiAgICAgICAgICAgICAgcmVzb2x2ZVRyYW5zaXRpb25Ib29rcygNCiAgICAgICAgICAgICAgICBjaGlsZCwNCiAgICAgICAgICAgICAgICBjc3NUcmFuc2l0aW9uUHJvcHMsDQogICAgICAgICAgICAgICAgc3RhdGUsDQogICAgICAgICAgICAgICAgaW5zdGFuY2UNCiAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgKTsNCiAgICAgICAgICAgIHBvc2l0aW9uTWFwLnNldCgNCiAgICAgICAgICAgICAgY2hpbGQsDQogICAgICAgICAgICAgIGNoaWxkLmVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpDQogICAgICAgICAgICApOw0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgY2hpbGRyZW4gPSBzbG90cy5kZWZhdWx0ID8gZ2V0VHJhbnNpdGlvblJhd0NoaWxkcmVuKHNsb3RzLmRlZmF1bHQoKSkgOiBbXTsNCiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgY29uc3QgY2hpbGQgPSBjaGlsZHJlbltpXTsNCiAgICAgICAgaWYgKGNoaWxkLmtleSAhPSBudWxsKSB7DQogICAgICAgICAgc2V0VHJhbnNpdGlvbkhvb2tzKA0KICAgICAgICAgICAgY2hpbGQsDQogICAgICAgICAgICByZXNvbHZlVHJhbnNpdGlvbkhvb2tzKGNoaWxkLCBjc3NUcmFuc2l0aW9uUHJvcHMsIHN0YXRlLCBpbnN0YW5jZSkNCiAgICAgICAgICApOw0KICAgICAgICB9IGVsc2UgaWYgKGNoaWxkLnR5cGUgIT09IFRleHQpIHsNCiAgICAgICAgICB3YXJuKGA8VHJhbnNpdGlvbkdyb3VwPiBjaGlsZHJlbiBtdXN0IGJlIGtleWVkLmApOw0KICAgICAgICB9DQogICAgICB9DQogICAgICByZXR1cm4gY3JlYXRlVk5vZGUodGFnLCBudWxsLCBjaGlsZHJlbik7DQogICAgfTsNCiAgfQ0KfSk7DQpjb25zdCBUcmFuc2l0aW9uR3JvdXAgPSBUcmFuc2l0aW9uR3JvdXBJbXBsOw0KZnVuY3Rpb24gY2FsbFBlbmRpbmdDYnMoYykgew0KICBjb25zdCBlbCA9IGMuZWw7DQogIGlmIChlbFttb3ZlQ2JLZXldKSB7DQogICAgZWxbbW92ZUNiS2V5XSgpOw0KICB9DQogIGlmIChlbFtlbnRlckNiS2V5XSkgew0KICAgIGVsW2VudGVyQ2JLZXldKCk7DQogIH0NCn0NCmZ1bmN0aW9uIHJlY29yZFBvc2l0aW9uKGMpIHsNCiAgbmV3UG9zaXRpb25NYXAuc2V0KGMsIGMuZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpOw0KfQ0KZnVuY3Rpb24gYXBwbHlUcmFuc2xhdGlvbihjKSB7DQogIGNvbnN0IG9sZFBvcyA9IHBvc2l0aW9uTWFwLmdldChjKTsNCiAgY29uc3QgbmV3UG9zID0gbmV3UG9zaXRpb25NYXAuZ2V0KGMpOw0KICBjb25zdCBkeCA9IG9sZFBvcy5sZWZ0IC0gbmV3UG9zLmxlZnQ7DQogIGNvbnN0IGR5ID0gb2xkUG9zLnRvcCAtIG5ld1Bvcy50b3A7DQogIGlmIChkeCB8fCBkeSkgew0KICAgIGNvbnN0IHMgPSBjLmVsLnN0eWxlOw0KICAgIHMudHJhbnNmb3JtID0gcy53ZWJraXRUcmFuc2Zvcm0gPSBgdHJhbnNsYXRlKCR7ZHh9cHgsJHtkeX1weClgOw0KICAgIHMudHJhbnNpdGlvbkR1cmF0aW9uID0gIjBzIjsNCiAgICByZXR1cm4gYzsNCiAgfQ0KfQ0KZnVuY3Rpb24gaGFzQ1NTVHJhbnNmb3JtKGVsLCByb290LCBtb3ZlQ2xhc3MpIHsNCiAgY29uc3QgY2xvbmUgPSBlbC5jbG9uZU5vZGUoKTsNCiAgY29uc3QgX3Z0YyA9IGVsW3Z0Y0tleV07DQogIGlmIChfdnRjKSB7DQogICAgX3Z0Yy5mb3JFYWNoKChjbHMpID0+IHsNCiAgICAgIGNscy5zcGxpdCgvXHMrLykuZm9yRWFjaCgoYykgPT4gYyAmJiBjbG9uZS5jbGFzc0xpc3QucmVtb3ZlKGMpKTsNCiAgICB9KTsNCiAgfQ0KICBtb3ZlQ2xhc3Muc3BsaXQoL1xzKy8pLmZvckVhY2goKGMpID0+IGMgJiYgY2xvbmUuY2xhc3NMaXN0LmFkZChjKSk7DQogIGNsb25lLnN0eWxlLmRpc3BsYXkgPSAibm9uZSI7DQogIGNvbnN0IGNvbnRhaW5lciA9IHJvb3Qubm9kZVR5cGUgPT09IDEgPyByb290IDogcm9vdC5wYXJlbnROb2RlOw0KICBjb250YWluZXIuYXBwZW5kQ2hpbGQoY2xvbmUpOw0KICBjb25zdCB7IGhhc1RyYW5zZm9ybSB9ID0gZ2V0VHJhbnNpdGlvbkluZm8oY2xvbmUpOw0KICBjb250YWluZXIucmVtb3ZlQ2hpbGQoY2xvbmUpOw0KICByZXR1cm4gaGFzVHJhbnNmb3JtOw0KfQ0KDQpjb25zdCBnZXRNb2RlbEFzc2lnbmVyID0gKHZub2RlKSA9PiB7DQogIGNvbnN0IGZuID0gdm5vZGUucHJvcHNbIm9uVXBkYXRlOm1vZGVsVmFsdWUiXSB8fCBmYWxzZTsNCiAgcmV0dXJuIGlzQXJyYXkoZm4pID8gKHZhbHVlKSA9PiBpbnZva2VBcnJheUZucyhmbiwgdmFsdWUpIDogZm47DQp9Ow0KZnVuY3Rpb24gb25Db21wb3NpdGlvblN0YXJ0KGUpIHsNCiAgZS50YXJnZXQuY29tcG9zaW5nID0gdHJ1ZTsNCn0NCmZ1bmN0aW9uIG9uQ29tcG9zaXRpb25FbmQoZSkgew0KICBjb25zdCB0YXJnZXQgPSBlLnRhcmdldDsNCiAgaWYgKHRhcmdldC5jb21wb3NpbmcpIHsNCiAgICB0YXJnZXQuY29tcG9zaW5nID0gZmFsc2U7DQogICAgdGFyZ2V0LmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KCJpbnB1dCIpKTsNCiAgfQ0KfQ0KY29uc3QgYXNzaWduS2V5ID0gU3ltYm9sKCJfYXNzaWduIik7DQpjb25zdCB2TW9kZWxUZXh0ID0gew0KICBjcmVhdGVkKGVsLCB7IG1vZGlmaWVyczogeyBsYXp5LCB0cmltLCBudW1iZXIgfSB9LCB2bm9kZSkgew0KICAgIGVsW2Fzc2lnbktleV0gPSBnZXRNb2RlbEFzc2lnbmVyKHZub2RlKTsNCiAgICBjb25zdCBjYXN0VG9OdW1iZXIgPSBudW1iZXIgfHwgdm5vZGUucHJvcHMgJiYgdm5vZGUucHJvcHMudHlwZSA9PT0gIm51bWJlciI7DQogICAgYWRkRXZlbnRMaXN0ZW5lcihlbCwgbGF6eSA/ICJjaGFuZ2UiIDogImlucHV0IiwgKGUpID0+IHsNCiAgICAgIGlmIChlLnRhcmdldC5jb21wb3NpbmcpIHJldHVybjsNCiAgICAgIGxldCBkb21WYWx1ZSA9IGVsLnZhbHVlOw0KICAgICAgaWYgKHRyaW0pIHsNCiAgICAgICAgZG9tVmFsdWUgPSBkb21WYWx1ZS50cmltKCk7DQogICAgICB9DQogICAgICBpZiAoY2FzdFRvTnVtYmVyKSB7DQogICAgICAgIGRvbVZhbHVlID0gbG9vc2VUb051bWJlcihkb21WYWx1ZSk7DQogICAgICB9DQogICAgICBlbFthc3NpZ25LZXldKGRvbVZhbHVlKTsNCiAgICB9KTsNCiAgICBpZiAodHJpbSkgew0KICAgICAgYWRkRXZlbnRMaXN0ZW5lcihlbCwgImNoYW5nZSIsICgpID0+IHsNCiAgICAgICAgZWwudmFsdWUgPSBlbC52YWx1ZS50cmltKCk7DQogICAgICB9KTsNCiAgICB9DQogICAgaWYgKCFsYXp5KSB7DQogICAgICBhZGRFdmVudExpc3RlbmVyKGVsLCAiY29tcG9zaXRpb25zdGFydCIsIG9uQ29tcG9zaXRpb25TdGFydCk7DQogICAgICBhZGRFdmVudExpc3RlbmVyKGVsLCAiY29tcG9zaXRpb25lbmQiLCBvbkNvbXBvc2l0aW9uRW5kKTsNCiAgICAgIGFkZEV2ZW50TGlzdGVuZXIoZWwsICJjaGFuZ2UiLCBvbkNvbXBvc2l0aW9uRW5kKTsNCiAgICB9DQogIH0sDQogIC8vIHNldCB2YWx1ZSBvbiBtb3VudGVkIHNvIGl0J3MgYWZ0ZXIgbWluL21heCBmb3IgdHlwZT0icmFuZ2UiDQogIG1vdW50ZWQoZWwsIHsgdmFsdWUgfSkgew0KICAgIGVsLnZhbHVlID0gdmFsdWUgPT0gbnVsbCA/ICIiIDogdmFsdWU7DQogIH0sDQogIGJlZm9yZVVwZGF0ZShlbCwgeyB2YWx1ZSwgb2xkVmFsdWUsIG1vZGlmaWVyczogeyBsYXp5LCB0cmltLCBudW1iZXIgfSB9LCB2bm9kZSkgew0KICAgIGVsW2Fzc2lnbktleV0gPSBnZXRNb2RlbEFzc2lnbmVyKHZub2RlKTsNCiAgICBpZiAoZWwuY29tcG9zaW5nKSByZXR1cm47DQogICAgY29uc3QgZWxWYWx1ZSA9IChudW1iZXIgfHwgZWwudHlwZSA9PT0gIm51bWJlciIpICYmICEvXjBcZC8udGVzdChlbC52YWx1ZSkgPyBsb29zZVRvTnVtYmVyKGVsLnZhbHVlKSA6IGVsLnZhbHVlOw0KICAgIGNvbnN0IG5ld1ZhbHVlID0gdmFsdWUgPT0gbnVsbCA/ICIiIDogdmFsdWU7DQogICAgaWYgKGVsVmFsdWUgPT09IG5ld1ZhbHVlKSB7DQogICAgICByZXR1cm47DQogICAgfQ0KICAgIGlmIChkb2N1bWVudC5hY3RpdmVFbGVtZW50ID09PSBlbCAmJiBlbC50eXBlICE9PSAicmFuZ2UiKSB7DQogICAgICBpZiAobGF6eSAmJiB2YWx1ZSA9PT0gb2xkVmFsdWUpIHsNCiAgICAgICAgcmV0dXJuOw0KICAgICAgfQ0KICAgICAgaWYgKHRyaW0gJiYgZWwudmFsdWUudHJpbSgpID09PSBuZXdWYWx1ZSkgew0KICAgICAgICByZXR1cm47DQogICAgICB9DQogICAgfQ0KICAgIGVsLnZhbHVlID0gbmV3VmFsdWU7DQogIH0NCn07DQpjb25zdCB2TW9kZWxDaGVja2JveCA9IHsNCiAgLy8gIzQwOTYgYXJyYXkgY2hlY2tib3hlcyBuZWVkIHRvIGJlIGRlZXAgdHJhdmVyc2VkDQogIGRlZXA6IHRydWUsDQogIGNyZWF0ZWQoZWwsIF8sIHZub2RlKSB7DQogICAgZWxbYXNzaWduS2V5XSA9IGdldE1vZGVsQXNzaWduZXIodm5vZGUpOw0KICAgIGFkZEV2ZW50TGlzdGVuZXIoZWwsICJjaGFuZ2UiLCAoKSA9PiB7DQogICAgICBjb25zdCBtb2RlbFZhbHVlID0gZWwuX21vZGVsVmFsdWU7DQogICAgICBjb25zdCBlbGVtZW50VmFsdWUgPSBnZXRWYWx1ZShlbCk7DQogICAgICBjb25zdCBjaGVja2VkID0gZWwuY2hlY2tlZDsNCiAgICAgIGNvbnN0IGFzc2lnbiA9IGVsW2Fzc2lnbktleV07DQogICAgICBpZiAoaXNBcnJheShtb2RlbFZhbHVlKSkgew0KICAgICAgICBjb25zdCBpbmRleCA9IGxvb3NlSW5kZXhPZihtb2RlbFZhbHVlLCBlbGVtZW50VmFsdWUpOw0KICAgICAgICBjb25zdCBmb3VuZCA9IGluZGV4ICE9PSAtMTsNCiAgICAgICAgaWYgKGNoZWNrZWQgJiYgIWZvdW5kKSB7DQogICAgICAgICAgYXNzaWduKG1vZGVsVmFsdWUuY29uY2F0KGVsZW1lbnRWYWx1ZSkpOw0KICAgICAgICB9IGVsc2UgaWYgKCFjaGVja2VkICYmIGZvdW5kKSB7DQogICAgICAgICAgY29uc3QgZmlsdGVyZWQgPSBbLi4ubW9kZWxWYWx1ZV07DQogICAgICAgICAgZmlsdGVyZWQuc3BsaWNlKGluZGV4LCAxKTsNCiAgICAgICAgICBhc3NpZ24oZmlsdGVyZWQpOw0KICAgICAgICB9DQogICAgICB9IGVsc2UgaWYgKGlzU2V0KG1vZGVsVmFsdWUpKSB7DQogICAgICAgIGNvbnN0IGNsb25lZCA9IG5ldyBTZXQobW9kZWxWYWx1ZSk7DQogICAgICAgIGlmIChjaGVja2VkKSB7DQogICAgICAgICAgY2xvbmVkLmFkZChlbGVtZW50VmFsdWUpOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIGNsb25lZC5kZWxldGUoZWxlbWVudFZhbHVlKTsNCiAgICAgICAgfQ0KICAgICAgICBhc3NpZ24oY2xvbmVkKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGFzc2lnbihnZXRDaGVja2JveFZhbHVlKGVsLCBjaGVja2VkKSk7DQogICAgICB9DQogICAgfSk7DQogIH0sDQogIC8vIHNldCBpbml0aWFsIGNoZWNrZWQgb24gbW91bnQgdG8gd2FpdCBmb3IgdHJ1ZS12YWx1ZS9mYWxzZS12YWx1ZQ0KICBtb3VudGVkOiBzZXRDaGVja2VkLA0KICBiZWZvcmVVcGRhdGUoZWwsIGJpbmRpbmcsIHZub2RlKSB7DQogICAgZWxbYXNzaWduS2V5XSA9IGdldE1vZGVsQXNzaWduZXIodm5vZGUpOw0KICAgIHNldENoZWNrZWQoZWwsIGJpbmRpbmcsIHZub2RlKTsNCiAgfQ0KfTsNCmZ1bmN0aW9uIHNldENoZWNrZWQoZWwsIHsgdmFsdWUsIG9sZFZhbHVlIH0sIHZub2RlKSB7DQogIGVsLl9tb2RlbFZhbHVlID0gdmFsdWU7DQogIGxldCBjaGVja2VkOw0KICBpZiAoaXNBcnJheSh2YWx1ZSkpIHsNCiAgICBjaGVja2VkID0gbG9vc2VJbmRleE9mKHZhbHVlLCB2bm9kZS5wcm9wcy52YWx1ZSkgPiAtMTsNCiAgfSBlbHNlIGlmIChpc1NldCh2YWx1ZSkpIHsNCiAgICBjaGVja2VkID0gdmFsdWUuaGFzKHZub2RlLnByb3BzLnZhbHVlKTsNCiAgfSBlbHNlIHsNCiAgICBpZiAodmFsdWUgPT09IG9sZFZhbHVlKSByZXR1cm47DQogICAgY2hlY2tlZCA9IGxvb3NlRXF1YWwodmFsdWUsIGdldENoZWNrYm94VmFsdWUoZWwsIHRydWUpKTsNCiAgfQ0KICBpZiAoZWwuY2hlY2tlZCAhPT0gY2hlY2tlZCkgew0KICAgIGVsLmNoZWNrZWQgPSBjaGVja2VkOw0KICB9DQp9DQpjb25zdCB2TW9kZWxSYWRpbyA9IHsNCiAgY3JlYXRlZChlbCwgeyB2YWx1ZSB9LCB2bm9kZSkgew0KICAgIGVsLmNoZWNrZWQgPSBsb29zZUVxdWFsKHZhbHVlLCB2bm9kZS5wcm9wcy52YWx1ZSk7DQogICAgZWxbYXNzaWduS2V5XSA9IGdldE1vZGVsQXNzaWduZXIodm5vZGUpOw0KICAgIGFkZEV2ZW50TGlzdGVuZXIoZWwsICJjaGFuZ2UiLCAoKSA9PiB7DQogICAgICBlbFthc3NpZ25LZXldKGdldFZhbHVlKGVsKSk7DQogICAgfSk7DQogIH0sDQogIGJlZm9yZVVwZGF0ZShlbCwgeyB2YWx1ZSwgb2xkVmFsdWUgfSwgdm5vZGUpIHsNCiAgICBlbFthc3NpZ25LZXldID0gZ2V0TW9kZWxBc3NpZ25lcih2bm9kZSk7DQogICAgaWYgKHZhbHVlICE9PSBvbGRWYWx1ZSkgew0KICAgICAgZWwuY2hlY2tlZCA9IGxvb3NlRXF1YWwodmFsdWUsIHZub2RlLnByb3BzLnZhbHVlKTsNCiAgICB9DQogIH0NCn07DQpjb25zdCB2TW9kZWxTZWxlY3QgPSB7DQogIC8vIDxzZWxlY3QgbXVsdGlwbGU+IHZhbHVlIG5lZWQgdG8gYmUgZGVlcCB0cmF2ZXJzZWQNCiAgZGVlcDogdHJ1ZSwNCiAgY3JlYXRlZChlbCwgeyB2YWx1ZSwgbW9kaWZpZXJzOiB7IG51bWJlciB9IH0sIHZub2RlKSB7DQogICAgY29uc3QgaXNTZXRNb2RlbCA9IGlzU2V0KHZhbHVlKTsNCiAgICBhZGRFdmVudExpc3RlbmVyKGVsLCAiY2hhbmdlIiwgKCkgPT4gew0KICAgICAgY29uc3Qgc2VsZWN0ZWRWYWwgPSBBcnJheS5wcm90b3R5cGUuZmlsdGVyLmNhbGwoZWwub3B0aW9ucywgKG8pID0+IG8uc2VsZWN0ZWQpLm1hcCgNCiAgICAgICAgKG8pID0+IG51bWJlciA/IGxvb3NlVG9OdW1iZXIoZ2V0VmFsdWUobykpIDogZ2V0VmFsdWUobykNCiAgICAgICk7DQogICAgICBlbFthc3NpZ25LZXldKA0KICAgICAgICBlbC5tdWx0aXBsZSA/IGlzU2V0TW9kZWwgPyBuZXcgU2V0KHNlbGVjdGVkVmFsKSA6IHNlbGVjdGVkVmFsIDogc2VsZWN0ZWRWYWxbMF0NCiAgICAgICk7DQogICAgICBlbC5fYXNzaWduaW5nID0gdHJ1ZTsNCiAgICAgIG5leHRUaWNrKCgpID0+IHsNCiAgICAgICAgZWwuX2Fzc2lnbmluZyA9IGZhbHNlOw0KICAgICAgfSk7DQogICAgfSk7DQogICAgZWxbYXNzaWduS2V5XSA9IGdldE1vZGVsQXNzaWduZXIodm5vZGUpOw0KICB9LA0KICAvLyBzZXQgdmFsdWUgaW4gbW91bnRlZCAmIHVwZGF0ZWQgYmVjYXVzZSA8c2VsZWN0PiByZWxpZXMgb24gaXRzIGNoaWxkcmVuDQogIC8vIDxvcHRpb24+cy4NCiAgbW91bnRlZChlbCwgeyB2YWx1ZSB9KSB7DQogICAgc2V0U2VsZWN0ZWQoZWwsIHZhbHVlKTsNCiAgfSwNCiAgYmVmb3JlVXBkYXRlKGVsLCBfYmluZGluZywgdm5vZGUpIHsNCiAgICBlbFthc3NpZ25LZXldID0gZ2V0TW9kZWxBc3NpZ25lcih2bm9kZSk7DQogIH0sDQogIHVwZGF0ZWQoZWwsIHsgdmFsdWUgfSkgew0KICAgIGlmICghZWwuX2Fzc2lnbmluZykgew0KICAgICAgc2V0U2VsZWN0ZWQoZWwsIHZhbHVlKTsNCiAgICB9DQogIH0NCn07DQpmdW5jdGlvbiBzZXRTZWxlY3RlZChlbCwgdmFsdWUpIHsNCiAgY29uc3QgaXNNdWx0aXBsZSA9IGVsLm11bHRpcGxlOw0KICBjb25zdCBpc0FycmF5VmFsdWUgPSBpc0FycmF5KHZhbHVlKTsNCiAgaWYgKGlzTXVsdGlwbGUgJiYgIWlzQXJyYXlWYWx1ZSAmJiAhaXNTZXQodmFsdWUpKSB7DQogICAgd2FybigNCiAgICAgIGA8c2VsZWN0IG11bHRpcGxlIHYtbW9kZWw+IGV4cGVjdHMgYW4gQXJyYXkgb3IgU2V0IHZhbHVlIGZvciBpdHMgYmluZGluZywgYnV0IGdvdCAke09iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSkuc2xpY2UoOCwgLTEpfS5gDQogICAgKTsNCiAgICByZXR1cm47DQogIH0NCiAgZm9yIChsZXQgaSA9IDAsIGwgPSBlbC5vcHRpb25zLmxlbmd0aDsgaSA8IGw7IGkrKykgew0KICAgIGNvbnN0IG9wdGlvbiA9IGVsLm9wdGlvbnNbaV07DQogICAgY29uc3Qgb3B0aW9uVmFsdWUgPSBnZXRWYWx1ZShvcHRpb24pOw0KICAgIGlmIChpc011bHRpcGxlKSB7DQogICAgICBpZiAoaXNBcnJheVZhbHVlKSB7DQogICAgICAgIGNvbnN0IG9wdGlvblR5cGUgPSB0eXBlb2Ygb3B0aW9uVmFsdWU7DQogICAgICAgIGlmIChvcHRpb25UeXBlID09PSAic3RyaW5nIiB8fCBvcHRpb25UeXBlID09PSAibnVtYmVyIikgew0KICAgICAgICAgIG9wdGlvbi5zZWxlY3RlZCA9IHZhbHVlLnNvbWUoKHYpID0+IFN0cmluZyh2KSA9PT0gU3RyaW5nKG9wdGlvblZhbHVlKSk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgb3B0aW9uLnNlbGVjdGVkID0gbG9vc2VJbmRleE9mKHZhbHVlLCBvcHRpb25WYWx1ZSkgPiAtMTsNCiAgICAgICAgfQ0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgb3B0aW9uLnNlbGVjdGVkID0gdmFsdWUuaGFzKG9wdGlvblZhbHVlKTsNCiAgICAgIH0NCiAgICB9IGVsc2UgaWYgKGxvb3NlRXF1YWwoZ2V0VmFsdWUob3B0aW9uKSwgdmFsdWUpKSB7DQogICAgICBpZiAoZWwuc2VsZWN0ZWRJbmRleCAhPT0gaSkgZWwuc2VsZWN0ZWRJbmRleCA9IGk7DQogICAgICByZXR1cm47DQogICAgfQ0KICB9DQogIGlmICghaXNNdWx0aXBsZSAmJiBlbC5zZWxlY3RlZEluZGV4ICE9PSAtMSkgew0KICAgIGVsLnNlbGVjdGVkSW5kZXggPSAtMTsNCiAgfQ0KfQ0KZnVuY3Rpb24gZ2V0VmFsdWUoZWwpIHsNCiAgcmV0dXJuICJfdmFsdWUiIGluIGVsID8gZWwuX3ZhbHVlIDogZWwudmFsdWU7DQp9DQpmdW5jdGlvbiBnZXRDaGVja2JveFZhbHVlKGVsLCBjaGVja2VkKSB7DQogIGNvbnN0IGtleSA9IGNoZWNrZWQgPyAiX3RydWVWYWx1ZSIgOiAiX2ZhbHNlVmFsdWUiOw0KICByZXR1cm4ga2V5IGluIGVsID8gZWxba2V5XSA6IGNoZWNrZWQ7DQp9DQpjb25zdCB2TW9kZWxEeW5hbWljID0gew0KICBjcmVhdGVkKGVsLCBiaW5kaW5nLCB2bm9kZSkgew0KICAgIGNhbGxNb2RlbEhvb2soZWwsIGJpbmRpbmcsIHZub2RlLCBudWxsLCAiY3JlYXRlZCIpOw0KICB9LA0KICBtb3VudGVkKGVsLCBiaW5kaW5nLCB2bm9kZSkgew0KICAgIGNhbGxNb2RlbEhvb2soZWwsIGJpbmRpbmcsIHZub2RlLCBudWxsLCAibW91bnRlZCIpOw0KICB9LA0KICBiZWZvcmVVcGRhdGUoZWwsIGJpbmRpbmcsIHZub2RlLCBwcmV2Vk5vZGUpIHsNCiAgICBjYWxsTW9kZWxIb29rKGVsLCBiaW5kaW5nLCB2bm9kZSwgcHJldlZOb2RlLCAiYmVmb3JlVXBkYXRlIik7DQogIH0sDQogIHVwZGF0ZWQoZWwsIGJpbmRpbmcsIHZub2RlLCBwcmV2Vk5vZGUpIHsNCiAgICBjYWxsTW9kZWxIb29rKGVsLCBiaW5kaW5nLCB2bm9kZSwgcHJldlZOb2RlLCAidXBkYXRlZCIpOw0KICB9DQp9Ow0KZnVuY3Rpb24gcmVzb2x2ZUR5bmFtaWNNb2RlbCh0YWdOYW1lLCB0eXBlKSB7DQogIHN3aXRjaCAodGFnTmFtZSkgew0KICAgIGNhc2UgIlNFTEVDVCI6DQogICAgICByZXR1cm4gdk1vZGVsU2VsZWN0Ow0KICAgIGNhc2UgIlRFWFRBUkVBIjoNCiAgICAgIHJldHVybiB2TW9kZWxUZXh0Ow0KICAgIGRlZmF1bHQ6DQogICAgICBzd2l0Y2ggKHR5cGUpIHsNCiAgICAgICAgY2FzZSAiY2hlY2tib3giOg0KICAgICAgICAgIHJldHVybiB2TW9kZWxDaGVja2JveDsNCiAgICAgICAgY2FzZSAicmFkaW8iOg0KICAgICAgICAgIHJldHVybiB2TW9kZWxSYWRpbzsNCiAgICAgICAgZGVmYXVsdDoNCiAgICAgICAgICByZXR1cm4gdk1vZGVsVGV4dDsNCiAgICAgIH0NCiAgfQ0KfQ0KZnVuY3Rpb24gY2FsbE1vZGVsSG9vayhlbCwgYmluZGluZywgdm5vZGUsIHByZXZWTm9kZSwgaG9vaykgew0KICBjb25zdCBtb2RlbFRvVXNlID0gcmVzb2x2ZUR5bmFtaWNNb2RlbCgNCiAgICBlbC50YWdOYW1lLA0KICAgIHZub2RlLnByb3BzICYmIHZub2RlLnByb3BzLnR5cGUNCiAgKTsNCiAgY29uc3QgZm4gPSBtb2RlbFRvVXNlW2hvb2tdOw0KICBmbiAmJiBmbihlbCwgYmluZGluZywgdm5vZGUsIHByZXZWTm9kZSk7DQp9DQpmdW5jdGlvbiBpbml0Vk1vZGVsRm9yU1NSKCkgew0KICB2TW9kZWxUZXh0LmdldFNTUlByb3BzID0gKHsgdmFsdWUgfSkgPT4gKHsgdmFsdWUgfSk7DQogIHZNb2RlbFJhZGlvLmdldFNTUlByb3BzID0gKHsgdmFsdWUgfSwgdm5vZGUpID0+IHsNCiAgICBpZiAodm5vZGUucHJvcHMgJiYgbG9vc2VFcXVhbCh2bm9kZS5wcm9wcy52YWx1ZSwgdmFsdWUpKSB7DQogICAgICByZXR1cm4geyBjaGVja2VkOiB0cnVlIH07DQogICAgfQ0KICB9Ow0KICB2TW9kZWxDaGVja2JveC5nZXRTU1JQcm9wcyA9ICh7IHZhbHVlIH0sIHZub2RlKSA9PiB7DQogICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7DQogICAgICBpZiAodm5vZGUucHJvcHMgJiYgbG9vc2VJbmRleE9mKHZhbHVlLCB2bm9kZS5wcm9wcy52YWx1ZSkgPiAtMSkgew0KICAgICAgICByZXR1cm4geyBjaGVja2VkOiB0cnVlIH07DQogICAgICB9DQogICAgfSBlbHNlIGlmIChpc1NldCh2YWx1ZSkpIHsNCiAgICAgIGlmICh2bm9kZS5wcm9wcyAmJiB2YWx1ZS5oYXModm5vZGUucHJvcHMudmFsdWUpKSB7DQogICAgICAgIHJldHVybiB7IGNoZWNrZWQ6IHRydWUgfTsNCiAgICAgIH0NCiAgICB9IGVsc2UgaWYgKHZhbHVlKSB7DQogICAgICByZXR1cm4geyBjaGVja2VkOiB0cnVlIH07DQogICAgfQ0KICB9Ow0KICB2TW9kZWxEeW5hbWljLmdldFNTUlByb3BzID0gKGJpbmRpbmcsIHZub2RlKSA9PiB7DQogICAgaWYgKHR5cGVvZiB2bm9kZS50eXBlICE9PSAic3RyaW5nIikgew0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBjb25zdCBtb2RlbFRvVXNlID0gcmVzb2x2ZUR5bmFtaWNNb2RlbCgNCiAgICAgIC8vIHJlc29sdmVEeW5hbWljTW9kZWwgZXhwZWN0cyBhbiB1cHBlcmNhc2UgdGFnIG5hbWUsIGJ1dCB2bm9kZS50eXBlIGlzIGxvd2VyY2FzZQ0KICAgICAgdm5vZGUudHlwZS50b1VwcGVyQ2FzZSgpLA0KICAgICAgdm5vZGUucHJvcHMgJiYgdm5vZGUucHJvcHMudHlwZQ0KICAgICk7DQogICAgaWYgKG1vZGVsVG9Vc2UuZ2V0U1NSUHJvcHMpIHsNCiAgICAgIHJldHVybiBtb2RlbFRvVXNlLmdldFNTUlByb3BzKGJpbmRpbmcsIHZub2RlKTsNCiAgICB9DQogIH07DQp9DQoNCmNvbnN0IHN5c3RlbU1vZGlmaWVycyA9IFsiY3RybCIsICJzaGlmdCIsICJhbHQiLCAibWV0YSJdOw0KY29uc3QgbW9kaWZpZXJHdWFyZHMgPSB7DQogIHN0b3A6IChlKSA9PiBlLnN0b3BQcm9wYWdhdGlvbigpLA0KICBwcmV2ZW50OiAoZSkgPT4gZS5wcmV2ZW50RGVmYXVsdCgpLA0KICBzZWxmOiAoZSkgPT4gZS50YXJnZXQgIT09IGUuY3VycmVudFRhcmdldCwNCiAgY3RybDogKGUpID0+ICFlLmN0cmxLZXksDQogIHNoaWZ0OiAoZSkgPT4gIWUuc2hpZnRLZXksDQogIGFsdDogKGUpID0+ICFlLmFsdEtleSwNCiAgbWV0YTogKGUpID0+ICFlLm1ldGFLZXksDQogIGxlZnQ6IChlKSA9PiAiYnV0dG9uIiBpbiBlICYmIGUuYnV0dG9uICE9PSAwLA0KICBtaWRkbGU6IChlKSA9PiAiYnV0dG9uIiBpbiBlICYmIGUuYnV0dG9uICE9PSAxLA0KICByaWdodDogKGUpID0+ICJidXR0b24iIGluIGUgJiYgZS5idXR0b24gIT09IDIsDQogIGV4YWN0OiAoZSwgbW9kaWZpZXJzKSA9PiBzeXN0ZW1Nb2RpZmllcnMuc29tZSgobSkgPT4gZVtgJHttfUtleWBdICYmICFtb2RpZmllcnMuaW5jbHVkZXMobSkpDQp9Ow0KY29uc3Qgd2l0aE1vZGlmaWVycyA9IChmbiwgbW9kaWZpZXJzKSA9PiB7DQogIGNvbnN0IGNhY2hlID0gZm4uX3dpdGhNb2RzIHx8IChmbi5fd2l0aE1vZHMgPSB7fSk7DQogIGNvbnN0IGNhY2hlS2V5ID0gbW9kaWZpZXJzLmpvaW4oIi4iKTsNCiAgcmV0dXJuIGNhY2hlW2NhY2hlS2V5XSB8fCAoY2FjaGVbY2FjaGVLZXldID0gKGV2ZW50LCAuLi5hcmdzKSA9PiB7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtb2RpZmllcnMubGVuZ3RoOyBpKyspIHsNCiAgICAgIGNvbnN0IGd1YXJkID0gbW9kaWZpZXJHdWFyZHNbbW9kaWZpZXJzW2ldXTsNCiAgICAgIGlmIChndWFyZCAmJiBndWFyZChldmVudCwgbW9kaWZpZXJzKSkgcmV0dXJuOw0KICAgIH0NCiAgICByZXR1cm4gZm4oZXZlbnQsIC4uLmFyZ3MpOw0KICB9KTsNCn07DQpjb25zdCBrZXlOYW1lcyA9IHsNCiAgZXNjOiAiZXNjYXBlIiwNCiAgc3BhY2U6ICIgIiwNCiAgdXA6ICJhcnJvdy11cCIsDQogIGxlZnQ6ICJhcnJvdy1sZWZ0IiwNCiAgcmlnaHQ6ICJhcnJvdy1yaWdodCIsDQogIGRvd246ICJhcnJvdy1kb3duIiwNCiAgZGVsZXRlOiAiYmFja3NwYWNlIg0KfTsNCmNvbnN0IHdpdGhLZXlzID0gKGZuLCBtb2RpZmllcnMpID0+IHsNCiAgY29uc3QgY2FjaGUgPSBmbi5fd2l0aEtleXMgfHwgKGZuLl93aXRoS2V5cyA9IHt9KTsNCiAgY29uc3QgY2FjaGVLZXkgPSBtb2RpZmllcnMuam9pbigiLiIpOw0KICByZXR1cm4gY2FjaGVbY2FjaGVLZXldIHx8IChjYWNoZVtjYWNoZUtleV0gPSAoZXZlbnQpID0+IHsNCiAgICBpZiAoISgia2V5IiBpbiBldmVudCkpIHsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgY29uc3QgZXZlbnRLZXkgPSBoeXBoZW5hdGUoZXZlbnQua2V5KTsNCiAgICBpZiAobW9kaWZpZXJzLnNvbWUoDQogICAgICAoaykgPT4gayA9PT0gZXZlbnRLZXkgfHwga2V5TmFtZXNba10gPT09IGV2ZW50S2V5DQogICAgKSkgew0KICAgICAgcmV0dXJuIGZuKGV2ZW50KTsNCiAgICB9DQogIH0pOw0KfTsNCg0KY29uc3QgcmVuZGVyZXJPcHRpb25zID0gLyogQF9fUFVSRV9fICovIGV4dGVuZCh7IHBhdGNoUHJvcCB9LCBub2RlT3BzKTsNCmxldCByZW5kZXJlcjsNCmxldCBlbmFibGVkSHlkcmF0aW9uID0gZmFsc2U7DQpmdW5jdGlvbiBlbnN1cmVSZW5kZXJlcigpIHsNCiAgcmV0dXJuIHJlbmRlcmVyIHx8IChyZW5kZXJlciA9IGNyZWF0ZVJlbmRlcmVyKHJlbmRlcmVyT3B0aW9ucykpOw0KfQ0KZnVuY3Rpb24gZW5zdXJlSHlkcmF0aW9uUmVuZGVyZXIoKSB7DQogIHJlbmRlcmVyID0gZW5hYmxlZEh5ZHJhdGlvbiA/IHJlbmRlcmVyIDogY3JlYXRlSHlkcmF0aW9uUmVuZGVyZXIocmVuZGVyZXJPcHRpb25zKTsNCiAgZW5hYmxlZEh5ZHJhdGlvbiA9IHRydWU7DQogIHJldHVybiByZW5kZXJlcjsNCn0NCmNvbnN0IHJlbmRlciA9ICguLi5hcmdzKSA9PiB7DQogIGVuc3VyZVJlbmRlcmVyKCkucmVuZGVyKC4uLmFyZ3MpOw0KfTsNCmNvbnN0IGh5ZHJhdGUgPSAoLi4uYXJncykgPT4gew0KICBlbnN1cmVIeWRyYXRpb25SZW5kZXJlcigpLmh5ZHJhdGUoLi4uYXJncyk7DQp9Ow0KY29uc3QgY3JlYXRlQXBwID0gKC4uLmFyZ3MpID0+IHsNCiAgY29uc3QgYXBwID0gZW5zdXJlUmVuZGVyZXIoKS5jcmVhdGVBcHAoLi4uYXJncyk7DQogIHsNCiAgICBpbmplY3ROYXRpdmVUYWdDaGVjayhhcHApOw0KICAgIGluamVjdENvbXBpbGVyT3B0aW9uc0NoZWNrKGFwcCk7DQogIH0NCiAgY29uc3QgeyBtb3VudCB9ID0gYXBwOw0KICBhcHAubW91bnQgPSAoY29udGFpbmVyT3JTZWxlY3RvcikgPT4gew0KICAgIGNvbnN0IGNvbnRhaW5lciA9IG5vcm1hbGl6ZUNvbnRhaW5lcihjb250YWluZXJPclNlbGVjdG9yKTsNCiAgICBpZiAoIWNvbnRhaW5lcikgcmV0dXJuOw0KICAgIGNvbnN0IGNvbXBvbmVudCA9IGFwcC5fY29tcG9uZW50Ow0KICAgIGlmICghaXNGdW5jdGlvbihjb21wb25lbnQpICYmICFjb21wb25lbnQucmVuZGVyICYmICFjb21wb25lbnQudGVtcGxhdGUpIHsNCiAgICAgIGNvbXBvbmVudC50ZW1wbGF0ZSA9IGNvbnRhaW5lci5pbm5lckhUTUw7DQogICAgfQ0KICAgIGlmIChjb250YWluZXIubm9kZVR5cGUgPT09IDEpIHsNCiAgICAgIGNvbnRhaW5lci50ZXh0Q29udGVudCA9ICIiOw0KICAgIH0NCiAgICBjb25zdCBwcm94eSA9IG1vdW50KGNvbnRhaW5lciwgZmFsc2UsIHJlc29sdmVSb290TmFtZXNwYWNlKGNvbnRhaW5lcikpOw0KICAgIGlmIChjb250YWluZXIgaW5zdGFuY2VvZiBFbGVtZW50KSB7DQogICAgICBjb250YWluZXIucmVtb3ZlQXR0cmlidXRlKCJ2LWNsb2FrIik7DQogICAgICBjb250YWluZXIuc2V0QXR0cmlidXRlKCJkYXRhLXYtYXBwIiwgIiIpOw0KICAgIH0NCiAgICByZXR1cm4gcHJveHk7DQogIH07DQogIHJldHVybiBhcHA7DQp9Ow0KY29uc3QgY3JlYXRlU1NSQXBwID0gKC4uLmFyZ3MpID0+IHsNCiAgY29uc3QgYXBwID0gZW5zdXJlSHlkcmF0aW9uUmVuZGVyZXIoKS5jcmVhdGVBcHAoLi4uYXJncyk7DQogIHsNCiAgICBpbmplY3ROYXRpdmVUYWdDaGVjayhhcHApOw0KICAgIGluamVjdENvbXBpbGVyT3B0aW9uc0NoZWNrKGFwcCk7DQogIH0NCiAgY29uc3QgeyBtb3VudCB9ID0gYXBwOw0KICBhcHAubW91bnQgPSAoY29udGFpbmVyT3JTZWxlY3RvcikgPT4gew0KICAgIGNvbnN0IGNvbnRhaW5lciA9IG5vcm1hbGl6ZUNvbnRhaW5lcihjb250YWluZXJPclNlbGVjdG9yKTsNCiAgICBpZiAoY29udGFpbmVyKSB7DQogICAgICByZXR1cm4gbW91bnQoY29udGFpbmVyLCB0cnVlLCByZXNvbHZlUm9vdE5hbWVzcGFjZShjb250YWluZXIpKTsNCiAgICB9DQogIH07DQogIHJldHVybiBhcHA7DQp9Ow0KZnVuY3Rpb24gcmVzb2x2ZVJvb3ROYW1lc3BhY2UoY29udGFpbmVyKSB7DQogIGlmIChjb250YWluZXIgaW5zdGFuY2VvZiBTVkdFbGVtZW50KSB7DQogICAgcmV0dXJuICJzdmciOw0KICB9DQogIGlmICh0eXBlb2YgTWF0aE1MRWxlbWVudCA9PT0gImZ1bmN0aW9uIiAmJiBjb250YWluZXIgaW5zdGFuY2VvZiBNYXRoTUxFbGVtZW50KSB7DQogICAgcmV0dXJuICJtYXRobWwiOw0KICB9DQp9DQpmdW5jdGlvbiBpbmplY3ROYXRpdmVUYWdDaGVjayhhcHApIHsNCiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGFwcC5jb25maWcsICJpc05hdGl2ZVRhZyIsIHsNCiAgICB2YWx1ZTogKHRhZykgPT4gaXNIVE1MVGFnKHRhZykgfHwgaXNTVkdUYWcodGFnKSB8fCBpc01hdGhNTFRhZyh0YWcpLA0KICAgIHdyaXRhYmxlOiBmYWxzZQ0KICB9KTsNCn0NCmZ1bmN0aW9uIGluamVjdENvbXBpbGVyT3B0aW9uc0NoZWNrKGFwcCkgew0KICBpZiAoaXNSdW50aW1lT25seSgpKSB7DQogICAgY29uc3QgaXNDdXN0b21FbGVtZW50ID0gYXBwLmNvbmZpZy5pc0N1c3RvbUVsZW1lbnQ7DQogICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGFwcC5jb25maWcsICJpc0N1c3RvbUVsZW1lbnQiLCB7DQogICAgICBnZXQoKSB7DQogICAgICAgIHJldHVybiBpc0N1c3RvbUVsZW1lbnQ7DQogICAgICB9LA0KICAgICAgc2V0KCkgew0KICAgICAgICB3YXJuKA0KICAgICAgICAgIGBUaGUgXGBpc0N1c3RvbUVsZW1lbnRcYCBjb25maWcgb3B0aW9uIGlzIGRlcHJlY2F0ZWQuIFVzZSBcYGNvbXBpbGVyT3B0aW9ucy5pc0N1c3RvbUVsZW1lbnRcYCBpbnN0ZWFkLmANCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICB9KTsNCiAgICBjb25zdCBjb21waWxlck9wdGlvbnMgPSBhcHAuY29uZmlnLmNvbXBpbGVyT3B0aW9uczsNCiAgICBjb25zdCBtc2cgPSBgVGhlIFxgY29tcGlsZXJPcHRpb25zXGAgY29uZmlnIG9wdGlvbiBpcyBvbmx5IHJlc3BlY3RlZCB3aGVuIHVzaW5nIGEgYnVpbGQgb2YgVnVlLmpzIHRoYXQgaW5jbHVkZXMgdGhlIHJ1bnRpbWUgY29tcGlsZXIgKGFrYSAiZnVsbCBidWlsZCIpLiBTaW5jZSB5b3UgYXJlIHVzaW5nIHRoZSBydW50aW1lLW9ubHkgYnVpbGQsIFxgY29tcGlsZXJPcHRpb25zXGAgbXVzdCBiZSBwYXNzZWQgdG8gXGBAdnVlL2NvbXBpbGVyLWRvbVxgIGluIHRoZSBidWlsZCBzZXR1cCBpbnN0ZWFkLg0KLSBGb3IgdnVlLWxvYWRlcjogcGFzcyBpdCB2aWEgdnVlLWxvYWRlcidzIFxgY29tcGlsZXJPcHRpb25zXGAgbG9hZGVyIG9wdGlvbi4NCi0gRm9yIHZ1ZS1jbGk6IHNlZSBodHRwczovL2NsaS52dWVqcy5vcmcvZ3VpZGUvd2VicGFjay5odG1sI21vZGlmeWluZy1vcHRpb25zLW9mLWEtbG9hZGVyDQotIEZvciB2aXRlOiBwYXNzIGl0IHZpYSBAdml0ZWpzL3BsdWdpbi12dWUgb3B0aW9ucy4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS92aXRlanMvdml0ZS1wbHVnaW4tdnVlL3RyZWUvbWFpbi9wYWNrYWdlcy9wbHVnaW4tdnVlI2V4YW1wbGUtZm9yLXBhc3Npbmctb3B0aW9ucy10by12dWVjb21waWxlci1zZmNgOw0KICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhcHAuY29uZmlnLCAiY29tcGlsZXJPcHRpb25zIiwgew0KICAgICAgZ2V0KCkgew0KICAgICAgICB3YXJuKG1zZyk7DQogICAgICAgIHJldHVybiBjb21waWxlck9wdGlvbnM7DQogICAgICB9LA0KICAgICAgc2V0KCkgew0KICAgICAgICB3YXJuKG1zZyk7DQogICAgICB9DQogICAgfSk7DQogIH0NCn0NCmZ1bmN0aW9uIG5vcm1hbGl6ZUNvbnRhaW5lcihjb250YWluZXIpIHsNCiAgaWYgKGlzU3RyaW5nKGNvbnRhaW5lcikpIHsNCiAgICBjb25zdCByZXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGNvbnRhaW5lcik7DQogICAgaWYgKCFyZXMpIHsNCiAgICAgIHdhcm4oDQogICAgICAgIGBGYWlsZWQgdG8gbW91bnQgYXBwOiBtb3VudCB0YXJnZXQgc2VsZWN0b3IgIiR7Y29udGFpbmVyfSIgcmV0dXJuZWQgbnVsbC5gDQogICAgICApOw0KICAgIH0NCiAgICByZXR1cm4gcmVzOw0KICB9DQogIGlmICh3aW5kb3cuU2hhZG93Um9vdCAmJiBjb250YWluZXIgaW5zdGFuY2VvZiB3aW5kb3cuU2hhZG93Um9vdCAmJiBjb250YWluZXIubW9kZSA9PT0gImNsb3NlZCIpIHsNCiAgICB3YXJuKA0KICAgICAgYG1vdW50aW5nIG9uIGEgU2hhZG93Um9vdCB3aXRoIFxge21vZGU6ICJjbG9zZWQifVxgIG1heSBsZWFkIHRvIHVucHJlZGljdGFibGUgYnVnc2ANCiAgICApOw0KICB9DQogIHJldHVybiBjb250YWluZXI7DQp9DQpsZXQgc3NyRGlyZWN0aXZlSW5pdGlhbGl6ZWQgPSBmYWxzZTsNCmNvbnN0IGluaXREaXJlY3RpdmVzRm9yU1NSID0gKCkgPT4gew0KICBpZiAoIXNzckRpcmVjdGl2ZUluaXRpYWxpemVkKSB7DQogICAgc3NyRGlyZWN0aXZlSW5pdGlhbGl6ZWQgPSB0cnVlOw0KICAgIGluaXRWTW9kZWxGb3JTU1IoKTsNCiAgICBpbml0VlNob3dGb3JTU1IoKTsNCiAgfQ0KfSA7DQoNCmV4cG9ydCB7IEJhc2VUcmFuc2l0aW9uLCBCYXNlVHJhbnNpdGlvblByb3BzVmFsaWRhdG9ycywgQ29tbWVudCwgRGVwcmVjYXRpb25UeXBlcywgRWZmZWN0U2NvcGUsIEVycm9yQ29kZXMsIEVycm9yVHlwZVN0cmluZ3MsIEZyYWdtZW50LCBLZWVwQWxpdmUsIFJlYWN0aXZlRWZmZWN0LCBTdGF0aWMsIFN1c3BlbnNlLCBUZWxlcG9ydCwgVGV4dCwgVHJhY2tPcFR5cGVzLCBUcmFuc2l0aW9uLCBUcmFuc2l0aW9uR3JvdXAsIFRyaWdnZXJPcFR5cGVzLCBWdWVFbGVtZW50LCBhc3NlcnROdW1iZXIsIGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nLCBjYWxsV2l0aEVycm9ySGFuZGxpbmcsIGNhbWVsaXplLCBjYXBpdGFsaXplLCBjbG9uZVZOb2RlLCBjb21wYXRVdGlscywgY29tcHV0ZWQsIGNyZWF0ZUFwcCwgY3JlYXRlQmxvY2ssIGNyZWF0ZUNvbW1lbnRWTm9kZSwgY3JlYXRlRWxlbWVudEJsb2NrLCBjcmVhdGVCYXNlVk5vZGUgYXMgY3JlYXRlRWxlbWVudFZOb2RlLCBjcmVhdGVIeWRyYXRpb25SZW5kZXJlciwgY3JlYXRlUHJvcHNSZXN0UHJveHksIGNyZWF0ZVJlbmRlcmVyLCBjcmVhdGVTU1JBcHAsIGNyZWF0ZVNsb3RzLCBjcmVhdGVTdGF0aWNWTm9kZSwgY3JlYXRlVGV4dFZOb2RlLCBjcmVhdGVWTm9kZSwgY3VzdG9tUmVmLCBkZWZpbmVBc3luY0NvbXBvbmVudCwgZGVmaW5lQ29tcG9uZW50LCBkZWZpbmVDdXN0b21FbGVtZW50LCBkZWZpbmVFbWl0cywgZGVmaW5lRXhwb3NlLCBkZWZpbmVNb2RlbCwgZGVmaW5lT3B0aW9ucywgZGVmaW5lUHJvcHMsIGRlZmluZVNTUkN1c3RvbUVsZW1lbnQsIGRlZmluZVNsb3RzLCBkZXZ0b29scywgZWZmZWN0LCBlZmZlY3RTY29wZSwgZ2V0Q3VycmVudEluc3RhbmNlLCBnZXRDdXJyZW50U2NvcGUsIGdldEN1cnJlbnRXYXRjaGVyLCBnZXRUcmFuc2l0aW9uUmF3Q2hpbGRyZW4sIGd1YXJkUmVhY3RpdmVQcm9wcywgaCwgaGFuZGxlRXJyb3IsIGhhc0luamVjdGlvbkNvbnRleHQsIGh5ZHJhdGUsIGh5ZHJhdGVPbklkbGUsIGh5ZHJhdGVPbkludGVyYWN0aW9uLCBoeWRyYXRlT25NZWRpYVF1ZXJ5LCBoeWRyYXRlT25WaXNpYmxlLCBpbml0Q3VzdG9tRm9ybWF0dGVyLCBpbml0RGlyZWN0aXZlc0ZvclNTUiwgaW5qZWN0LCBpc01lbW9TYW1lLCBpc1Byb3h5LCBpc1JlYWN0aXZlLCBpc1JlYWRvbmx5LCBpc1JlZiwgaXNSdW50aW1lT25seSwgaXNTaGFsbG93LCBpc1ZOb2RlLCBtYXJrUmF3LCBtZXJnZURlZmF1bHRzLCBtZXJnZU1vZGVscywgbWVyZ2VQcm9wcywgbmV4dFRpY2ssIG5vcm1hbGl6ZUNsYXNzLCBub3JtYWxpemVQcm9wcywgbm9ybWFsaXplU3R5bGUsIG9uQWN0aXZhdGVkLCBvbkJlZm9yZU1vdW50LCBvbkJlZm9yZVVubW91bnQsIG9uQmVmb3JlVXBkYXRlLCBvbkRlYWN0aXZhdGVkLCBvbkVycm9yQ2FwdHVyZWQsIG9uTW91bnRlZCwgb25SZW5kZXJUcmFja2VkLCBvblJlbmRlclRyaWdnZXJlZCwgb25TY29wZURpc3Bvc2UsIG9uU2VydmVyUHJlZmV0Y2gsIG9uVW5tb3VudGVkLCBvblVwZGF0ZWQsIG9uV2F0Y2hlckNsZWFudXAsIG9wZW5CbG9jaywgcG9wU2NvcGVJZCwgcHJvdmlkZSwgcHJveHlSZWZzLCBwdXNoU2NvcGVJZCwgcXVldWVQb3N0Rmx1c2hDYiwgcmVhY3RpdmUsIHJlYWRvbmx5LCByZWYsIHJlZ2lzdGVyUnVudGltZUNvbXBpbGVyLCByZW5kZXIsIHJlbmRlckxpc3QsIHJlbmRlclNsb3QsIHJlc29sdmVDb21wb25lbnQsIHJlc29sdmVEaXJlY3RpdmUsIHJlc29sdmVEeW5hbWljQ29tcG9uZW50LCByZXNvbHZlRmlsdGVyLCByZXNvbHZlVHJhbnNpdGlvbkhvb2tzLCBzZXRCbG9ja1RyYWNraW5nLCBzZXREZXZ0b29sc0hvb2ssIHNldFRyYW5zaXRpb25Ib29rcywgc2hhbGxvd1JlYWN0aXZlLCBzaGFsbG93UmVhZG9ubHksIHNoYWxsb3dSZWYsIHNzckNvbnRleHRLZXksIHNzclV0aWxzLCBzdG9wLCB0b0Rpc3BsYXlTdHJpbmcsIHRvSGFuZGxlcktleSwgdG9IYW5kbGVycywgdG9SYXcsIHRvUmVmLCB0b1JlZnMsIHRvVmFsdWUsIHRyYW5zZm9ybVZOb2RlQXJncywgdHJpZ2dlclJlZiwgdW5yZWYsIHVzZUF0dHJzLCB1c2VDc3NNb2R1bGUsIHVzZUNzc1ZhcnMsIHVzZUhvc3QsIHVzZUlkLCB1c2VNb2RlbCwgdXNlU1NSQ29udGV4dCwgdXNlU2hhZG93Um9vdCwgdXNlU2xvdHMsIHVzZVRlbXBsYXRlUmVmLCB1c2VUcmFuc2l0aW9uU3RhdGUsIHZNb2RlbENoZWNrYm94LCB2TW9kZWxEeW5hbWljLCB2TW9kZWxSYWRpbywgdk1vZGVsU2VsZWN0LCB2TW9kZWxUZXh0LCB2U2hvdywgdmVyc2lvbiwgd2Fybiwgd2F0Y2gsIHdhdGNoRWZmZWN0LCB3YXRjaFBvc3RFZmZlY3QsIHdhdGNoU3luY0VmZmVjdCwgd2l0aEFzeW5jQ29udGV4dCwgd2l0aEN0eCwgd2l0aERlZmF1bHRzLCB3aXRoRGlyZWN0aXZlcywgd2l0aEtleXMsIHdpdGhNZW1vLCB3aXRoTW9kaWZpZXJzLCB3aXRoU2NvcGVJZCB9Ow0K",Inn="data:text/javascript;base64,LyoqDQoqIEB2dWUvc2VydmVyLXJlbmRlcmVyIHYzLjUuMTcNCiogKGMpIDIwMTgtcHJlc2VudCBZdXhpIChFdmFuKSBZb3UgYW5kIFZ1ZSBjb250cmlidXRvcnMNCiogQGxpY2Vuc2UgTUlUDQoqKi8NCi8qISAjX19OT19TSURFX0VGRkVDVFNfXyAqLw0KLy8gQF9fTk9fU0lERV9FRkZFQ1RTX18NCmZ1bmN0aW9uIG1ha2VNYXAoc3RyKSB7DQogIGNvbnN0IG1hcCA9IC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuY3JlYXRlKG51bGwpOw0KICBmb3IgKGNvbnN0IGtleSBvZiBzdHIuc3BsaXQoIiwiKSkgbWFwW2tleV0gPSAxOw0KICByZXR1cm4gKHZhbCkgPT4gdmFsIGluIG1hcDsNCn0NCg0KY29uc3QgRU1QVFlfT0JKID0gT2JqZWN0LmZyZWV6ZSh7fSkgOw0KY29uc3QgRU1QVFlfQVJSID0gT2JqZWN0LmZyZWV6ZShbXSkgOw0KY29uc3QgTk9PUCA9ICgpID0+IHsNCn07DQpjb25zdCBOTyA9ICgpID0+IGZhbHNlOw0KY29uc3QgaXNPbiA9IChrZXkpID0+IGtleS5jaGFyQ29kZUF0KDApID09PSAxMTEgJiYga2V5LmNoYXJDb2RlQXQoMSkgPT09IDExMCAmJiAvLyB1cHBlcmNhc2UgbGV0dGVyDQooa2V5LmNoYXJDb2RlQXQoMikgPiAxMjIgfHwga2V5LmNoYXJDb2RlQXQoMikgPCA5Nyk7DQpjb25zdCBpc01vZGVsTGlzdGVuZXIgPSAoa2V5KSA9PiBrZXkuc3RhcnRzV2l0aCgib25VcGRhdGU6Iik7DQpjb25zdCBleHRlbmQgPSBPYmplY3QuYXNzaWduOw0KY29uc3QgcmVtb3ZlID0gKGFyciwgZWwpID0+IHsNCiAgY29uc3QgaSA9IGFyci5pbmRleE9mKGVsKTsNCiAgaWYgKGkgPiAtMSkgew0KICAgIGFyci5zcGxpY2UoaSwgMSk7DQogIH0NCn07DQpjb25zdCBoYXNPd25Qcm9wZXJ0eSQxID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTsNCmNvbnN0IGhhc093biA9ICh2YWwsIGtleSkgPT4gaGFzT3duUHJvcGVydHkkMS5jYWxsKHZhbCwga2V5KTsNCmNvbnN0IGlzQXJyYXkgPSBBcnJheS5pc0FycmF5Ow0KY29uc3QgaXNNYXAgPSAodmFsKSA9PiB0b1R5cGVTdHJpbmcodmFsKSA9PT0gIltvYmplY3QgTWFwXSI7DQpjb25zdCBpc1NldCA9ICh2YWwpID0+IHRvVHlwZVN0cmluZyh2YWwpID09PSAiW29iamVjdCBTZXRdIjsNCmNvbnN0IGlzRGF0ZSA9ICh2YWwpID0+IHRvVHlwZVN0cmluZyh2YWwpID09PSAiW29iamVjdCBEYXRlXSI7DQpjb25zdCBpc0Z1bmN0aW9uID0gKHZhbCkgPT4gdHlwZW9mIHZhbCA9PT0gImZ1bmN0aW9uIjsNCmNvbnN0IGlzU3RyaW5nID0gKHZhbCkgPT4gdHlwZW9mIHZhbCA9PT0gInN0cmluZyI7DQpjb25zdCBpc1N5bWJvbCA9ICh2YWwpID0+IHR5cGVvZiB2YWwgPT09ICJzeW1ib2wiOw0KY29uc3QgaXNPYmplY3QgPSAodmFsKSA9PiB2YWwgIT09IG51bGwgJiYgdHlwZW9mIHZhbCA9PT0gIm9iamVjdCI7DQpjb25zdCBpc1Byb21pc2UgPSAodmFsKSA9PiB7DQogIHJldHVybiAoaXNPYmplY3QodmFsKSB8fCBpc0Z1bmN0aW9uKHZhbCkpICYmIGlzRnVuY3Rpb24odmFsLnRoZW4pICYmIGlzRnVuY3Rpb24odmFsLmNhdGNoKTsNCn07DQpjb25zdCBvYmplY3RUb1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7DQpjb25zdCB0b1R5cGVTdHJpbmcgPSAodmFsdWUpID0+IG9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpOw0KY29uc3QgdG9SYXdUeXBlID0gKHZhbHVlKSA9PiB7DQogIHJldHVybiB0b1R5cGVTdHJpbmcodmFsdWUpLnNsaWNlKDgsIC0xKTsNCn07DQpjb25zdCBpc1BsYWluT2JqZWN0ID0gKHZhbCkgPT4gdG9UeXBlU3RyaW5nKHZhbCkgPT09ICJbb2JqZWN0IE9iamVjdF0iOw0KY29uc3QgaXNJbnRlZ2VyS2V5ID0gKGtleSkgPT4gaXNTdHJpbmcoa2V5KSAmJiBrZXkgIT09ICJOYU4iICYmIGtleVswXSAhPT0gIi0iICYmICIiICsgcGFyc2VJbnQoa2V5LCAxMCkgPT09IGtleTsNCmNvbnN0IGlzUmVzZXJ2ZWRQcm9wID0gLyogQF9fUFVSRV9fICovIG1ha2VNYXAoDQogIC8vIHRoZSBsZWFkaW5nIGNvbW1hIGlzIGludGVudGlvbmFsIHNvIGVtcHR5IHN0cmluZyAiIiBpcyBhbHNvIGluY2x1ZGVkDQogICIsa2V5LHJlZixyZWZfZm9yLHJlZl9rZXksb25Wbm9kZUJlZm9yZU1vdW50LG9uVm5vZGVNb3VudGVkLG9uVm5vZGVCZWZvcmVVcGRhdGUsb25Wbm9kZVVwZGF0ZWQsb25Wbm9kZUJlZm9yZVVubW91bnQsb25Wbm9kZVVubW91bnRlZCINCik7DQpjb25zdCBpc0J1aWx0SW5EaXJlY3RpdmUgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcCgNCiAgImJpbmQsY2xvYWssZWxzZS1pZixlbHNlLGZvcixodG1sLGlmLG1vZGVsLG9uLG9uY2UscHJlLHNob3csc2xvdCx0ZXh0LG1lbW8iDQopOw0KY29uc3QgY2FjaGVTdHJpbmdGdW5jdGlvbiA9IChmbikgPT4gew0KICBjb25zdCBjYWNoZSA9IC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuY3JlYXRlKG51bGwpOw0KICByZXR1cm4gKHN0cikgPT4gew0KICAgIGNvbnN0IGhpdCA9IGNhY2hlW3N0cl07DQogICAgcmV0dXJuIGhpdCB8fCAoY2FjaGVbc3RyXSA9IGZuKHN0cikpOw0KICB9Ow0KfTsNCmNvbnN0IGNhbWVsaXplUkUgPSAvLShcdykvZzsNCmNvbnN0IGNhbWVsaXplID0gY2FjaGVTdHJpbmdGdW5jdGlvbigNCiAgKHN0cikgPT4gew0KICAgIHJldHVybiBzdHIucmVwbGFjZShjYW1lbGl6ZVJFLCAoXywgYykgPT4gYyA/IGMudG9VcHBlckNhc2UoKSA6ICIiKTsNCiAgfQ0KKTsNCmNvbnN0IGh5cGhlbmF0ZVJFID0gL1xCKFtBLVpdKS9nOw0KY29uc3QgaHlwaGVuYXRlID0gY2FjaGVTdHJpbmdGdW5jdGlvbigNCiAgKHN0cikgPT4gc3RyLnJlcGxhY2UoaHlwaGVuYXRlUkUsICItJDEiKS50b0xvd2VyQ2FzZSgpDQopOw0KY29uc3QgY2FwaXRhbGl6ZSA9IGNhY2hlU3RyaW5nRnVuY3Rpb24oKHN0cikgPT4gew0KICByZXR1cm4gc3RyLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3RyLnNsaWNlKDEpOw0KfSk7DQpjb25zdCB0b0hhbmRsZXJLZXkgPSBjYWNoZVN0cmluZ0Z1bmN0aW9uKA0KICAoc3RyKSA9PiB7DQogICAgY29uc3QgcyA9IHN0ciA/IGBvbiR7Y2FwaXRhbGl6ZShzdHIpfWAgOiBgYDsNCiAgICByZXR1cm4gczsNCiAgfQ0KKTsNCmNvbnN0IGhhc0NoYW5nZWQgPSAodmFsdWUsIG9sZFZhbHVlKSA9PiAhT2JqZWN0LmlzKHZhbHVlLCBvbGRWYWx1ZSk7DQpjb25zdCBpbnZva2VBcnJheUZucyA9IChmbnMsIC4uLmFyZykgPT4gew0KICBmb3IgKGxldCBpID0gMDsgaSA8IGZucy5sZW5ndGg7IGkrKykgew0KICAgIGZuc1tpXSguLi5hcmcpOw0KICB9DQp9Ow0KY29uc3QgZGVmID0gKG9iaiwga2V5LCB2YWx1ZSwgd3JpdGFibGUgPSBmYWxzZSkgPT4gew0KICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBrZXksIHsNCiAgICBjb25maWd1cmFibGU6IHRydWUsDQogICAgZW51bWVyYWJsZTogZmFsc2UsDQogICAgd3JpdGFibGUsDQogICAgdmFsdWUNCiAgfSk7DQp9Ow0KY29uc3QgbG9vc2VUb051bWJlciA9ICh2YWwpID0+IHsNCiAgY29uc3QgbiA9IHBhcnNlRmxvYXQodmFsKTsNCiAgcmV0dXJuIGlzTmFOKG4pID8gdmFsIDogbjsNCn07DQpsZXQgX2dsb2JhbFRoaXM7DQpjb25zdCBnZXRHbG9iYWxUaGlzID0gKCkgPT4gew0KICByZXR1cm4gX2dsb2JhbFRoaXMgfHwgKF9nbG9iYWxUaGlzID0gdHlwZW9mIGdsb2JhbFRoaXMgIT09ICJ1bmRlZmluZWQiID8gZ2xvYmFsVGhpcyA6IHR5cGVvZiBzZWxmICE9PSAidW5kZWZpbmVkIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSAidW5kZWZpbmVkIiA/IHdpbmRvdyA6IHR5cGVvZiBnbG9iYWwgIT09ICJ1bmRlZmluZWQiID8gZ2xvYmFsIDoge30pOw0KfTsNCg0KZnVuY3Rpb24gbm9ybWFsaXplU3R5bGUodmFsdWUpIHsNCiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7DQogICAgY29uc3QgcmVzID0ge307DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykgew0KICAgICAgY29uc3QgaXRlbSA9IHZhbHVlW2ldOw0KICAgICAgY29uc3Qgbm9ybWFsaXplZCA9IGlzU3RyaW5nKGl0ZW0pID8gcGFyc2VTdHJpbmdTdHlsZShpdGVtKSA6IG5vcm1hbGl6ZVN0eWxlKGl0ZW0pOw0KICAgICAgaWYgKG5vcm1hbGl6ZWQpIHsNCiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gbm9ybWFsaXplZCkgew0KICAgICAgICAgIHJlc1trZXldID0gbm9ybWFsaXplZFtrZXldOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICAgIHJldHVybiByZXM7DQogIH0gZWxzZSBpZiAoaXNTdHJpbmcodmFsdWUpIHx8IGlzT2JqZWN0KHZhbHVlKSkgew0KICAgIHJldHVybiB2YWx1ZTsNCiAgfQ0KfQ0KY29uc3QgbGlzdERlbGltaXRlclJFID0gLzsoPyFbXihdKlwpKS9nOw0KY29uc3QgcHJvcGVydHlEZWxpbWl0ZXJSRSA9IC86KFteXSspLzsNCmNvbnN0IHN0eWxlQ29tbWVudFJFID0gL1wvXCpbXl0qP1wqXC8vZzsNCmZ1bmN0aW9uIHBhcnNlU3RyaW5nU3R5bGUoY3NzVGV4dCkgew0KICBjb25zdCByZXQgPSB7fTsNCiAgY3NzVGV4dC5yZXBsYWNlKHN0eWxlQ29tbWVudFJFLCAiIikuc3BsaXQobGlzdERlbGltaXRlclJFKS5mb3JFYWNoKChpdGVtKSA9PiB7DQogICAgaWYgKGl0ZW0pIHsNCiAgICAgIGNvbnN0IHRtcCA9IGl0ZW0uc3BsaXQocHJvcGVydHlEZWxpbWl0ZXJSRSk7DQogICAgICB0bXAubGVuZ3RoID4gMSAmJiAocmV0W3RtcFswXS50cmltKCldID0gdG1wWzFdLnRyaW0oKSk7DQogICAgfQ0KICB9KTsNCiAgcmV0dXJuIHJldDsNCn0NCmZ1bmN0aW9uIHN0cmluZ2lmeVN0eWxlKHN0eWxlcykgew0KICBpZiAoIXN0eWxlcykgcmV0dXJuICIiOw0KICBpZiAoaXNTdHJpbmcoc3R5bGVzKSkgcmV0dXJuIHN0eWxlczsNCiAgbGV0IHJldCA9ICIiOw0KICBmb3IgKGNvbnN0IGtleSBpbiBzdHlsZXMpIHsNCiAgICBjb25zdCB2YWx1ZSA9IHN0eWxlc1trZXldOw0KICAgIGlmIChpc1N0cmluZyh2YWx1ZSkgfHwgdHlwZW9mIHZhbHVlID09PSAibnVtYmVyIikgew0KICAgICAgY29uc3Qgbm9ybWFsaXplZEtleSA9IGtleS5zdGFydHNXaXRoKGAtLWApID8ga2V5IDogaHlwaGVuYXRlKGtleSk7DQogICAgICByZXQgKz0gYCR7bm9ybWFsaXplZEtleX06JHt2YWx1ZX07YDsNCiAgICB9DQogIH0NCiAgcmV0dXJuIHJldDsNCn0NCmZ1bmN0aW9uIG5vcm1hbGl6ZUNsYXNzKHZhbHVlKSB7DQogIGxldCByZXMgPSAiIjsNCiAgaWYgKGlzU3RyaW5nKHZhbHVlKSkgew0KICAgIHJlcyA9IHZhbHVlOw0KICB9IGVsc2UgaWYgKGlzQXJyYXkodmFsdWUpKSB7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykgew0KICAgICAgY29uc3Qgbm9ybWFsaXplZCA9IG5vcm1hbGl6ZUNsYXNzKHZhbHVlW2ldKTsNCiAgICAgIGlmIChub3JtYWxpemVkKSB7DQogICAgICAgIHJlcyArPSBub3JtYWxpemVkICsgIiAiOw0KICAgICAgfQ0KICAgIH0NCiAgfSBlbHNlIGlmIChpc09iamVjdCh2YWx1ZSkpIHsNCiAgICBmb3IgKGNvbnN0IG5hbWUgaW4gdmFsdWUpIHsNCiAgICAgIGlmICh2YWx1ZVtuYW1lXSkgew0KICAgICAgICByZXMgKz0gbmFtZSArICIgIjsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgcmV0dXJuIHJlcy50cmltKCk7DQp9DQoNCmNvbnN0IEhUTUxfVEFHUyA9ICJodG1sLGJvZHksYmFzZSxoZWFkLGxpbmssbWV0YSxzdHlsZSx0aXRsZSxhZGRyZXNzLGFydGljbGUsYXNpZGUsZm9vdGVyLGhlYWRlcixoZ3JvdXAsaDEsaDIsaDMsaDQsaDUsaDYsbmF2LHNlY3Rpb24sZGl2LGRkLGRsLGR0LGZpZ2NhcHRpb24sZmlndXJlLHBpY3R1cmUsaHIsaW1nLGxpLG1haW4sb2wscCxwcmUsdWwsYSxiLGFiYnIsYmRpLGJkbyxicixjaXRlLGNvZGUsZGF0YSxkZm4sZW0saSxrYmQsbWFyayxxLHJwLHJ0LHJ1YnkscyxzYW1wLHNtYWxsLHNwYW4sc3Ryb25nLHN1YixzdXAsdGltZSx1LHZhcix3YnIsYXJlYSxhdWRpbyxtYXAsdHJhY2ssdmlkZW8sZW1iZWQsb2JqZWN0LHBhcmFtLHNvdXJjZSxjYW52YXMsc2NyaXB0LG5vc2NyaXB0LGRlbCxpbnMsY2FwdGlvbixjb2wsY29sZ3JvdXAsdGFibGUsdGhlYWQsdGJvZHksdGQsdGgsdHIsYnV0dG9uLGRhdGFsaXN0LGZpZWxkc2V0LGZvcm0saW5wdXQsbGFiZWwsbGVnZW5kLG1ldGVyLG9wdGdyb3VwLG9wdGlvbixvdXRwdXQscHJvZ3Jlc3Msc2VsZWN0LHRleHRhcmVhLGRldGFpbHMsZGlhbG9nLG1lbnUsc3VtbWFyeSx0ZW1wbGF0ZSxibG9ja3F1b3RlLGlmcmFtZSx0Zm9vdCI7DQpjb25zdCBTVkdfVEFHUyA9ICJzdmcsYW5pbWF0ZSxhbmltYXRlTW90aW9uLGFuaW1hdGVUcmFuc2Zvcm0sY2lyY2xlLGNsaXBQYXRoLGNvbG9yLXByb2ZpbGUsZGVmcyxkZXNjLGRpc2NhcmQsZWxsaXBzZSxmZUJsZW5kLGZlQ29sb3JNYXRyaXgsZmVDb21wb25lbnRUcmFuc2ZlcixmZUNvbXBvc2l0ZSxmZUNvbnZvbHZlTWF0cml4LGZlRGlmZnVzZUxpZ2h0aW5nLGZlRGlzcGxhY2VtZW50TWFwLGZlRGlzdGFudExpZ2h0LGZlRHJvcFNoYWRvdyxmZUZsb29kLGZlRnVuY0EsZmVGdW5jQixmZUZ1bmNHLGZlRnVuY1IsZmVHYXVzc2lhbkJsdXIsZmVJbWFnZSxmZU1lcmdlLGZlTWVyZ2VOb2RlLGZlTW9ycGhvbG9neSxmZU9mZnNldCxmZVBvaW50TGlnaHQsZmVTcGVjdWxhckxpZ2h0aW5nLGZlU3BvdExpZ2h0LGZlVGlsZSxmZVR1cmJ1bGVuY2UsZmlsdGVyLGZvcmVpZ25PYmplY3QsZyxoYXRjaCxoYXRjaHBhdGgsaW1hZ2UsbGluZSxsaW5lYXJHcmFkaWVudCxtYXJrZXIsbWFzayxtZXNoLG1lc2hncmFkaWVudCxtZXNocGF0Y2gsbWVzaHJvdyxtZXRhZGF0YSxtcGF0aCxwYXRoLHBhdHRlcm4scG9seWdvbixwb2x5bGluZSxyYWRpYWxHcmFkaWVudCxyZWN0LHNldCxzb2xpZGNvbG9yLHN0b3Asc3dpdGNoLHN5bWJvbCx0ZXh0LHRleHRQYXRoLHRpdGxlLHRzcGFuLHVua25vd24sdXNlLHZpZXciOw0KY29uc3QgTUFUSF9UQUdTID0gImFubm90YXRpb24sYW5ub3RhdGlvbi14bWwsbWFjdGlvbixtYWxpZ25ncm91cCxtYWxpZ25tYXJrLG1hdGgsbWVuY2xvc2UsbWVycm9yLG1mZW5jZWQsbWZyYWMsbWZyYWN0aW9uLG1nbHlwaCxtaSxtbGFiZWxlZHRyLG1sb25nZGl2LG1tdWx0aXNjcmlwdHMsbW4sbW8sbW92ZXIsbXBhZGRlZCxtcGhhbnRvbSxtcHJlc2NyaXB0cyxtcm9vdCxtcm93LG1zLG1zY2Fycmllcyxtc2NhcnJ5LG1zZ3JvdXAsbXNsaW5lLG1zcGFjZSxtc3FydCxtc3Jvdyxtc3RhY2ssbXN0eWxlLG1zdWIsbXN1YnN1cCxtc3VwLG10YWJsZSxtdGQsbXRleHQsbXRyLG11bmRlcixtdW5kZXJvdmVyLG5vbmUsc2VtYW50aWNzIjsNCmNvbnN0IFZPSURfVEFHUyA9ICJhcmVhLGJhc2UsYnIsY29sLGVtYmVkLGhyLGltZyxpbnB1dCxsaW5rLG1ldGEscGFyYW0sc291cmNlLHRyYWNrLHdiciI7DQpjb25zdCBpc0hUTUxUYWcgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcChIVE1MX1RBR1MpOw0KY29uc3QgaXNTVkdUYWcgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcChTVkdfVEFHUyk7DQpjb25zdCBpc01hdGhNTFRhZyA9IC8qIEBfX1BVUkVfXyAqLyBtYWtlTWFwKE1BVEhfVEFHUyk7DQpjb25zdCBpc1ZvaWRUYWcgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcChWT0lEX1RBR1MpOw0KDQpjb25zdCBzcGVjaWFsQm9vbGVhbkF0dHJzID0gYGl0ZW1zY29wZSxhbGxvd2Z1bGxzY3JlZW4sZm9ybW5vdmFsaWRhdGUsaXNtYXAsbm9tb2R1bGUsbm92YWxpZGF0ZSxyZWFkb25seWA7DQpjb25zdCBpc1NwZWNpYWxCb29sZWFuQXR0ciA9IC8qIEBfX1BVUkVfXyAqLyBtYWtlTWFwKHNwZWNpYWxCb29sZWFuQXR0cnMpOw0KY29uc3QgaXNCb29sZWFuQXR0ciA9IC8qIEBfX1BVUkVfXyAqLyBtYWtlTWFwKA0KICBzcGVjaWFsQm9vbGVhbkF0dHJzICsgYCxhc3luYyxhdXRvZm9jdXMsYXV0b3BsYXksY29udHJvbHMsZGVmYXVsdCxkZWZlcixkaXNhYmxlZCxoaWRkZW4saW5lcnQsbG9vcCxvcGVuLHJlcXVpcmVkLHJldmVyc2VkLHNjb3BlZCxzZWFtbGVzcyxjaGVja2VkLG11dGVkLG11bHRpcGxlLHNlbGVjdGVkYA0KKTsNCmZ1bmN0aW9uIGluY2x1ZGVCb29sZWFuQXR0cih2YWx1ZSkgew0KICByZXR1cm4gISF2YWx1ZSB8fCB2YWx1ZSA9PT0gIiI7DQp9DQpjb25zdCB1bnNhZmVBdHRyQ2hhclJFID0gL1s+Lz0iJ1x1MDAwOVx1MDAwYVx1MDAwY1x1MDAyMF0vOw0KY29uc3QgYXR0clZhbGlkYXRpb25DYWNoZSA9IHt9Ow0KZnVuY3Rpb24gaXNTU1JTYWZlQXR0ck5hbWUobmFtZSkgew0KICBpZiAoYXR0clZhbGlkYXRpb25DYWNoZS5oYXNPd25Qcm9wZXJ0eShuYW1lKSkgew0KICAgIHJldHVybiBhdHRyVmFsaWRhdGlvbkNhY2hlW25hbWVdOw0KICB9DQogIGNvbnN0IGlzVW5zYWZlID0gdW5zYWZlQXR0ckNoYXJSRS50ZXN0KG5hbWUpOw0KICBpZiAoaXNVbnNhZmUpIHsNCiAgICBjb25zb2xlLmVycm9yKGB1bnNhZmUgYXR0cmlidXRlIG5hbWU6ICR7bmFtZX1gKTsNCiAgfQ0KICByZXR1cm4gYXR0clZhbGlkYXRpb25DYWNoZVtuYW1lXSA9ICFpc1Vuc2FmZTsNCn0NCmNvbnN0IHByb3BzVG9BdHRyTWFwID0gew0KICBhY2NlcHRDaGFyc2V0OiAiYWNjZXB0LWNoYXJzZXQiLA0KICBjbGFzc05hbWU6ICJjbGFzcyIsDQogIGh0bWxGb3I6ICJmb3IiLA0KICBodHRwRXF1aXY6ICJodHRwLWVxdWl2Ig0KfTsNCmZ1bmN0aW9uIGlzUmVuZGVyYWJsZUF0dHJWYWx1ZSh2YWx1ZSkgew0KICBpZiAodmFsdWUgPT0gbnVsbCkgew0KICAgIHJldHVybiBmYWxzZTsNCiAgfQ0KICBjb25zdCB0eXBlID0gdHlwZW9mIHZhbHVlOw0KICByZXR1cm4gdHlwZSA9PT0gInN0cmluZyIgfHwgdHlwZSA9PT0gIm51bWJlciIgfHwgdHlwZSA9PT0gImJvb2xlYW4iOw0KfQ0KDQpjb25zdCBlc2NhcGVSRSA9IC9bIicmPD5dLzsNCmZ1bmN0aW9uIGVzY2FwZUh0bWwoc3RyaW5nKSB7DQogIGNvbnN0IHN0ciA9ICIiICsgc3RyaW5nOw0KICBjb25zdCBtYXRjaCA9IGVzY2FwZVJFLmV4ZWMoc3RyKTsNCiAgaWYgKCFtYXRjaCkgew0KICAgIHJldHVybiBzdHI7DQogIH0NCiAgbGV0IGh0bWwgPSAiIjsNCiAgbGV0IGVzY2FwZWQ7DQogIGxldCBpbmRleDsNCiAgbGV0IGxhc3RJbmRleCA9IDA7DQogIGZvciAoaW5kZXggPSBtYXRjaC5pbmRleDsgaW5kZXggPCBzdHIubGVuZ3RoOyBpbmRleCsrKSB7DQogICAgc3dpdGNoIChzdHIuY2hhckNvZGVBdChpbmRleCkpIHsNCiAgICAgIGNhc2UgMzQ6DQogICAgICAgIGVzY2FwZWQgPSAiJnF1b3Q7IjsNCiAgICAgICAgYnJlYWs7DQogICAgICBjYXNlIDM4Og0KICAgICAgICBlc2NhcGVkID0gIiZhbXA7IjsNCiAgICAgICAgYnJlYWs7DQogICAgICBjYXNlIDM5Og0KICAgICAgICBlc2NhcGVkID0gIiYjMzk7IjsNCiAgICAgICAgYnJlYWs7DQogICAgICBjYXNlIDYwOg0KICAgICAgICBlc2NhcGVkID0gIiZsdDsiOw0KICAgICAgICBicmVhazsNCiAgICAgIGNhc2UgNjI6DQogICAgICAgIGVzY2FwZWQgPSAiJmd0OyI7DQogICAgICAgIGJyZWFrOw0KICAgICAgZGVmYXVsdDoNCiAgICAgICAgY29udGludWU7DQogICAgfQ0KICAgIGlmIChsYXN0SW5kZXggIT09IGluZGV4KSB7DQogICAgICBodG1sICs9IHN0ci5zbGljZShsYXN0SW5kZXgsIGluZGV4KTsNCiAgICB9DQogICAgbGFzdEluZGV4ID0gaW5kZXggKyAxOw0KICAgIGh0bWwgKz0gZXNjYXBlZDsNCiAgfQ0KICByZXR1cm4gbGFzdEluZGV4ICE9PSBpbmRleCA/IGh0bWwgKyBzdHIuc2xpY2UobGFzdEluZGV4LCBpbmRleCkgOiBodG1sOw0KfQ0KY29uc3QgY29tbWVudFN0cmlwUkUgPSAvXi0/Pnw8IS0tfC0tPnwtLSE+fDwhLSQvZzsNCmZ1bmN0aW9uIGVzY2FwZUh0bWxDb21tZW50KHNyYykgew0KICByZXR1cm4gc3JjLnJlcGxhY2UoY29tbWVudFN0cmlwUkUsICIiKTsNCn0NCg0KZnVuY3Rpb24gbG9vc2VDb21wYXJlQXJyYXlzKGEsIGIpIHsNCiAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkgcmV0dXJuIGZhbHNlOw0KICBsZXQgZXF1YWwgPSB0cnVlOw0KICBmb3IgKGxldCBpID0gMDsgZXF1YWwgJiYgaSA8IGEubGVuZ3RoOyBpKyspIHsNCiAgICBlcXVhbCA9IGxvb3NlRXF1YWwoYVtpXSwgYltpXSk7DQogIH0NCiAgcmV0dXJuIGVxdWFsOw0KfQ0KZnVuY3Rpb24gbG9vc2VFcXVhbChhLCBiKSB7DQogIGlmIChhID09PSBiKSByZXR1cm4gdHJ1ZTsNCiAgbGV0IGFWYWxpZFR5cGUgPSBpc0RhdGUoYSk7DQogIGxldCBiVmFsaWRUeXBlID0gaXNEYXRlKGIpOw0KICBpZiAoYVZhbGlkVHlwZSB8fCBiVmFsaWRUeXBlKSB7DQogICAgcmV0dXJuIGFWYWxpZFR5cGUgJiYgYlZhbGlkVHlwZSA/IGEuZ2V0VGltZSgpID09PSBiLmdldFRpbWUoKSA6IGZhbHNlOw0KICB9DQogIGFWYWxpZFR5cGUgPSBpc1N5bWJvbChhKTsNCiAgYlZhbGlkVHlwZSA9IGlzU3ltYm9sKGIpOw0KICBpZiAoYVZhbGlkVHlwZSB8fCBiVmFsaWRUeXBlKSB7DQogICAgcmV0dXJuIGEgPT09IGI7DQogIH0NCiAgYVZhbGlkVHlwZSA9IGlzQXJyYXkoYSk7DQogIGJWYWxpZFR5cGUgPSBpc0FycmF5KGIpOw0KICBpZiAoYVZhbGlkVHlwZSB8fCBiVmFsaWRUeXBlKSB7DQogICAgcmV0dXJuIGFWYWxpZFR5cGUgJiYgYlZhbGlkVHlwZSA/IGxvb3NlQ29tcGFyZUFycmF5cyhhLCBiKSA6IGZhbHNlOw0KICB9DQogIGFWYWxpZFR5cGUgPSBpc09iamVjdChhKTsNCiAgYlZhbGlkVHlwZSA9IGlzT2JqZWN0KGIpOw0KICBpZiAoYVZhbGlkVHlwZSB8fCBiVmFsaWRUeXBlKSB7DQogICAgaWYgKCFhVmFsaWRUeXBlIHx8ICFiVmFsaWRUeXBlKSB7DQogICAgICByZXR1cm4gZmFsc2U7DQogICAgfQ0KICAgIGNvbnN0IGFLZXlzQ291bnQgPSBPYmplY3Qua2V5cyhhKS5sZW5ndGg7DQogICAgY29uc3QgYktleXNDb3VudCA9IE9iamVjdC5rZXlzKGIpLmxlbmd0aDsNCiAgICBpZiAoYUtleXNDb3VudCAhPT0gYktleXNDb3VudCkgew0KICAgICAgcmV0dXJuIGZhbHNlOw0KICAgIH0NCiAgICBmb3IgKGNvbnN0IGtleSBpbiBhKSB7DQogICAgICBjb25zdCBhSGFzS2V5ID0gYS5oYXNPd25Qcm9wZXJ0eShrZXkpOw0KICAgICAgY29uc3QgYkhhc0tleSA9IGIuaGFzT3duUHJvcGVydHkoa2V5KTsNCiAgICAgIGlmIChhSGFzS2V5ICYmICFiSGFzS2V5IHx8ICFhSGFzS2V5ICYmIGJIYXNLZXkgfHwgIWxvb3NlRXF1YWwoYVtrZXldLCBiW2tleV0pKSB7DQogICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgcmV0dXJuIFN0cmluZyhhKSA9PT0gU3RyaW5nKGIpOw0KfQ0KZnVuY3Rpb24gbG9vc2VJbmRleE9mKGFyciwgdmFsKSB7DQogIHJldHVybiBhcnIuZmluZEluZGV4KChpdGVtKSA9PiBsb29zZUVxdWFsKGl0ZW0sIHZhbCkpOw0KfQ0KDQpjb25zdCBpc1JlZiQxID0gKHZhbCkgPT4gew0KICByZXR1cm4gISEodmFsICYmIHZhbFsiX192X2lzUmVmIl0gPT09IHRydWUpOw0KfTsNCmNvbnN0IHRvRGlzcGxheVN0cmluZyA9ICh2YWwpID0+IHsNCiAgcmV0dXJuIGlzU3RyaW5nKHZhbCkgPyB2YWwgOiB2YWwgPT0gbnVsbCA/ICIiIDogaXNBcnJheSh2YWwpIHx8IGlzT2JqZWN0KHZhbCkgJiYgKHZhbC50b1N0cmluZyA9PT0gb2JqZWN0VG9TdHJpbmcgfHwgIWlzRnVuY3Rpb24odmFsLnRvU3RyaW5nKSkgPyBpc1JlZiQxKHZhbCkgPyB0b0Rpc3BsYXlTdHJpbmcodmFsLnZhbHVlKSA6IEpTT04uc3RyaW5naWZ5KHZhbCwgcmVwbGFjZXIsIDIpIDogU3RyaW5nKHZhbCk7DQp9Ow0KY29uc3QgcmVwbGFjZXIgPSAoX2tleSwgdmFsKSA9PiB7DQogIGlmIChpc1JlZiQxKHZhbCkpIHsNCiAgICByZXR1cm4gcmVwbGFjZXIoX2tleSwgdmFsLnZhbHVlKTsNCiAgfSBlbHNlIGlmIChpc01hcCh2YWwpKSB7DQogICAgcmV0dXJuIHsNCiAgICAgIFtgTWFwKCR7dmFsLnNpemV9KWBdOiBbLi4udmFsLmVudHJpZXMoKV0ucmVkdWNlKA0KICAgICAgICAoZW50cmllcywgW2tleSwgdmFsMl0sIGkpID0+IHsNCiAgICAgICAgICBlbnRyaWVzW3N0cmluZ2lmeVN5bWJvbChrZXksIGkpICsgIiA9PiJdID0gdmFsMjsNCiAgICAgICAgICByZXR1cm4gZW50cmllczsNCiAgICAgICAgfSwNCiAgICAgICAge30NCiAgICAgICkNCiAgICB9Ow0KICB9IGVsc2UgaWYgKGlzU2V0KHZhbCkpIHsNCiAgICByZXR1cm4gew0KICAgICAgW2BTZXQoJHt2YWwuc2l6ZX0pYF06IFsuLi52YWwudmFsdWVzKCldLm1hcCgodikgPT4gc3RyaW5naWZ5U3ltYm9sKHYpKQ0KICAgIH07DQogIH0gZWxzZSBpZiAoaXNTeW1ib2wodmFsKSkgew0KICAgIHJldHVybiBzdHJpbmdpZnlTeW1ib2wodmFsKTsNCiAgfSBlbHNlIGlmIChpc09iamVjdCh2YWwpICYmICFpc0FycmF5KHZhbCkgJiYgIWlzUGxhaW5PYmplY3QodmFsKSkgew0KICAgIHJldHVybiBTdHJpbmcodmFsKTsNCiAgfQ0KICByZXR1cm4gdmFsOw0KfTsNCmNvbnN0IHN0cmluZ2lmeVN5bWJvbCA9ICh2LCBpID0gIiIpID0+IHsNCiAgdmFyIF9hOw0KICByZXR1cm4gKA0KICAgIC8vIFN5bWJvbC5kZXNjcmlwdGlvbiBpbiBlczIwMTkrIHNvIHdlIG5lZWQgdG8gY2FzdCBoZXJlIHRvIHBhc3MNCiAgICAvLyB0aGUgbGliOiBlczIwMTYgY2hlY2sNCiAgICBpc1N5bWJvbCh2KSA/IGBTeW1ib2woJHsoX2EgPSB2LmRlc2NyaXB0aW9uKSAhPSBudWxsID8gX2EgOiBpfSlgIDogdg0KICApOw0KfTsNCg0KZnVuY3Rpb24gd2FybiQyKG1zZywgLi4uYXJncykgew0KICBjb25zb2xlLndhcm4oYFtWdWUgd2Fybl0gJHttc2d9YCwgLi4uYXJncyk7DQp9DQoNCmxldCBhY3RpdmVFZmZlY3RTY29wZTsNCmNsYXNzIEVmZmVjdFNjb3BlIHsNCiAgY29uc3RydWN0b3IoZGV0YWNoZWQgPSBmYWxzZSkgew0KICAgIHRoaXMuZGV0YWNoZWQgPSBkZXRhY2hlZDsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLl9hY3RpdmUgPSB0cnVlOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbCB0cmFjayBgb25gIGNhbGxzLCBhbGxvdyBgb25gIGNhbGwgbXVsdGlwbGUgdGltZXMNCiAgICAgKi8NCiAgICB0aGlzLl9vbiA9IDA7DQogICAgLyoqDQogICAgICogQGludGVybmFsDQogICAgICovDQogICAgdGhpcy5lZmZlY3RzID0gW107DQogICAgLyoqDQogICAgICogQGludGVybmFsDQogICAgICovDQogICAgdGhpcy5jbGVhbnVwcyA9IFtdOw0KICAgIHRoaXMuX2lzUGF1c2VkID0gZmFsc2U7DQogICAgdGhpcy5wYXJlbnQgPSBhY3RpdmVFZmZlY3RTY29wZTsNCiAgICBpZiAoIWRldGFjaGVkICYmIGFjdGl2ZUVmZmVjdFNjb3BlKSB7DQogICAgICB0aGlzLmluZGV4ID0gKGFjdGl2ZUVmZmVjdFNjb3BlLnNjb3BlcyB8fCAoYWN0aXZlRWZmZWN0U2NvcGUuc2NvcGVzID0gW10pKS5wdXNoKA0KICAgICAgICB0aGlzDQogICAgICApIC0gMTsNCiAgICB9DQogIH0NCiAgZ2V0IGFjdGl2ZSgpIHsNCiAgICByZXR1cm4gdGhpcy5fYWN0aXZlOw0KICB9DQogIHBhdXNlKCkgew0KICAgIGlmICh0aGlzLl9hY3RpdmUpIHsNCiAgICAgIHRoaXMuX2lzUGF1c2VkID0gdHJ1ZTsNCiAgICAgIGxldCBpLCBsOw0KICAgICAgaWYgKHRoaXMuc2NvcGVzKSB7DQogICAgICAgIGZvciAoaSA9IDAsIGwgPSB0aGlzLnNjb3Blcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsNCiAgICAgICAgICB0aGlzLnNjb3Blc1tpXS5wYXVzZSgpOw0KICAgICAgICB9DQogICAgICB9DQogICAgICBmb3IgKGkgPSAwLCBsID0gdGhpcy5lZmZlY3RzLmxlbmd0aDsgaSA8IGw7IGkrKykgew0KICAgICAgICB0aGlzLmVmZmVjdHNbaV0ucGF1c2UoKTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgLyoqDQogICAqIFJlc3VtZXMgdGhlIGVmZmVjdCBzY29wZSwgaW5jbHVkaW5nIGFsbCBjaGlsZCBzY29wZXMgYW5kIGVmZmVjdHMuDQogICAqLw0KICByZXN1bWUoKSB7DQogICAgaWYgKHRoaXMuX2FjdGl2ZSkgew0KICAgICAgaWYgKHRoaXMuX2lzUGF1c2VkKSB7DQogICAgICAgIHRoaXMuX2lzUGF1c2VkID0gZmFsc2U7DQogICAgICAgIGxldCBpLCBsOw0KICAgICAgICBpZiAodGhpcy5zY29wZXMpIHsNCiAgICAgICAgICBmb3IgKGkgPSAwLCBsID0gdGhpcy5zY29wZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7DQogICAgICAgICAgICB0aGlzLnNjb3Blc1tpXS5yZXN1bWUoKTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgZm9yIChpID0gMCwgbCA9IHRoaXMuZWZmZWN0cy5sZW5ndGg7IGkgPCBsOyBpKyspIHsNCiAgICAgICAgICB0aGlzLmVmZmVjdHNbaV0ucmVzdW1lKCk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH0NCiAgcnVuKGZuKSB7DQogICAgaWYgKHRoaXMuX2FjdGl2ZSkgew0KICAgICAgY29uc3QgY3VycmVudEVmZmVjdFNjb3BlID0gYWN0aXZlRWZmZWN0U2NvcGU7DQogICAgICB0cnkgew0KICAgICAgICBhY3RpdmVFZmZlY3RTY29wZSA9IHRoaXM7DQogICAgICAgIHJldHVybiBmbigpOw0KICAgICAgfSBmaW5hbGx5IHsNCiAgICAgICAgYWN0aXZlRWZmZWN0U2NvcGUgPSBjdXJyZW50RWZmZWN0U2NvcGU7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIHdhcm4kMihgY2Fubm90IHJ1biBhbiBpbmFjdGl2ZSBlZmZlY3Qgc2NvcGUuYCk7DQogICAgfQ0KICB9DQogIC8qKg0KICAgKiBUaGlzIHNob3VsZCBvbmx5IGJlIGNhbGxlZCBvbiBub24tZGV0YWNoZWQgc2NvcGVzDQogICAqIEBpbnRlcm5hbA0KICAgKi8NCiAgb24oKSB7DQogICAgaWYgKCsrdGhpcy5fb24gPT09IDEpIHsNCiAgICAgIHRoaXMucHJldlNjb3BlID0gYWN0aXZlRWZmZWN0U2NvcGU7DQogICAgICBhY3RpdmVFZmZlY3RTY29wZSA9IHRoaXM7DQogICAgfQ0KICB9DQogIC8qKg0KICAgKiBUaGlzIHNob3VsZCBvbmx5IGJlIGNhbGxlZCBvbiBub24tZGV0YWNoZWQgc2NvcGVzDQogICAqIEBpbnRlcm5hbA0KICAgKi8NCiAgb2ZmKCkgew0KICAgIGlmICh0aGlzLl9vbiA+IDAgJiYgLS10aGlzLl9vbiA9PT0gMCkgew0KICAgICAgYWN0aXZlRWZmZWN0U2NvcGUgPSB0aGlzLnByZXZTY29wZTsNCiAgICAgIHRoaXMucHJldlNjb3BlID0gdm9pZCAwOw0KICAgIH0NCiAgfQ0KICBzdG9wKGZyb21QYXJlbnQpIHsNCiAgICBpZiAodGhpcy5fYWN0aXZlKSB7DQogICAgICB0aGlzLl9hY3RpdmUgPSBmYWxzZTsNCiAgICAgIGxldCBpLCBsOw0KICAgICAgZm9yIChpID0gMCwgbCA9IHRoaXMuZWZmZWN0cy5sZW5ndGg7IGkgPCBsOyBpKyspIHsNCiAgICAgICAgdGhpcy5lZmZlY3RzW2ldLnN0b3AoKTsNCiAgICAgIH0NCiAgICAgIHRoaXMuZWZmZWN0cy5sZW5ndGggPSAwOw0KICAgICAgZm9yIChpID0gMCwgbCA9IHRoaXMuY2xlYW51cHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7DQogICAgICAgIHRoaXMuY2xlYW51cHNbaV0oKTsNCiAgICAgIH0NCiAgICAgIHRoaXMuY2xlYW51cHMubGVuZ3RoID0gMDsNCiAgICAgIGlmICh0aGlzLnNjb3Blcykgew0KICAgICAgICBmb3IgKGkgPSAwLCBsID0gdGhpcy5zY29wZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7DQogICAgICAgICAgdGhpcy5zY29wZXNbaV0uc3RvcCh0cnVlKTsNCiAgICAgICAgfQ0KICAgICAgICB0aGlzLnNjb3Blcy5sZW5ndGggPSAwOw0KICAgICAgfQ0KICAgICAgaWYgKCF0aGlzLmRldGFjaGVkICYmIHRoaXMucGFyZW50ICYmICFmcm9tUGFyZW50KSB7DQogICAgICAgIGNvbnN0IGxhc3QgPSB0aGlzLnBhcmVudC5zY29wZXMucG9wKCk7DQogICAgICAgIGlmIChsYXN0ICYmIGxhc3QgIT09IHRoaXMpIHsNCiAgICAgICAgICB0aGlzLnBhcmVudC5zY29wZXNbdGhpcy5pbmRleF0gPSBsYXN0Ow0KICAgICAgICAgIGxhc3QuaW5kZXggPSB0aGlzLmluZGV4Ow0KICAgICAgICB9DQogICAgICB9DQogICAgICB0aGlzLnBhcmVudCA9IHZvaWQgMDsNCiAgICB9DQogIH0NCn0NCmZ1bmN0aW9uIGdldEN1cnJlbnRTY29wZSgpIHsNCiAgcmV0dXJuIGFjdGl2ZUVmZmVjdFNjb3BlOw0KfQ0KDQpsZXQgYWN0aXZlU3ViOw0KY29uc3QgcGF1c2VkUXVldWVFZmZlY3RzID0gLyogQF9fUFVSRV9fICovIG5ldyBXZWFrU2V0KCk7DQpjbGFzcyBSZWFjdGl2ZUVmZmVjdCB7DQogIGNvbnN0cnVjdG9yKGZuKSB7DQogICAgdGhpcy5mbiA9IGZuOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuZGVwcyA9IHZvaWQgMDsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLmRlcHNUYWlsID0gdm9pZCAwOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuZmxhZ3MgPSAxIHwgNDsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLm5leHQgPSB2b2lkIDA7DQogICAgLyoqDQogICAgICogQGludGVybmFsDQogICAgICovDQogICAgdGhpcy5jbGVhbnVwID0gdm9pZCAwOw0KICAgIHRoaXMuc2NoZWR1bGVyID0gdm9pZCAwOw0KICAgIGlmIChhY3RpdmVFZmZlY3RTY29wZSAmJiBhY3RpdmVFZmZlY3RTY29wZS5hY3RpdmUpIHsNCiAgICAgIGFjdGl2ZUVmZmVjdFNjb3BlLmVmZmVjdHMucHVzaCh0aGlzKTsNCiAgICB9DQogIH0NCiAgcGF1c2UoKSB7DQogICAgdGhpcy5mbGFncyB8PSA2NDsNCiAgfQ0KICByZXN1bWUoKSB7DQogICAgaWYgKHRoaXMuZmxhZ3MgJiA2NCkgew0KICAgICAgdGhpcy5mbGFncyAmPSAtNjU7DQogICAgICBpZiAocGF1c2VkUXVldWVFZmZlY3RzLmhhcyh0aGlzKSkgew0KICAgICAgICBwYXVzZWRRdWV1ZUVmZmVjdHMuZGVsZXRlKHRoaXMpOw0KICAgICAgICB0aGlzLnRyaWdnZXIoKTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgLyoqDQogICAqIEBpbnRlcm5hbA0KICAgKi8NCiAgbm90aWZ5KCkgew0KICAgIGlmICh0aGlzLmZsYWdzICYgMiAmJiAhKHRoaXMuZmxhZ3MgJiAzMikpIHsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgaWYgKCEodGhpcy5mbGFncyAmIDgpKSB7DQogICAgICBiYXRjaCh0aGlzKTsNCiAgICB9DQogIH0NCiAgcnVuKCkgew0KICAgIGlmICghKHRoaXMuZmxhZ3MgJiAxKSkgew0KICAgICAgcmV0dXJuIHRoaXMuZm4oKTsNCiAgICB9DQogICAgdGhpcy5mbGFncyB8PSAyOw0KICAgIGNsZWFudXBFZmZlY3QodGhpcyk7DQogICAgcHJlcGFyZURlcHModGhpcyk7DQogICAgY29uc3QgcHJldkVmZmVjdCA9IGFjdGl2ZVN1YjsNCiAgICBjb25zdCBwcmV2U2hvdWxkVHJhY2sgPSBzaG91bGRUcmFjazsNCiAgICBhY3RpdmVTdWIgPSB0aGlzOw0KICAgIHNob3VsZFRyYWNrID0gdHJ1ZTsNCiAgICB0cnkgew0KICAgICAgcmV0dXJuIHRoaXMuZm4oKTsNCiAgICB9IGZpbmFsbHkgew0KICAgICAgaWYgKGFjdGl2ZVN1YiAhPT0gdGhpcykgew0KICAgICAgICB3YXJuJDIoDQogICAgICAgICAgIkFjdGl2ZSBlZmZlY3Qgd2FzIG5vdCByZXN0b3JlZCBjb3JyZWN0bHkgLSB0aGlzIGlzIGxpa2VseSBhIFZ1ZSBpbnRlcm5hbCBidWcuIg0KICAgICAgICApOw0KICAgICAgfQ0KICAgICAgY2xlYW51cERlcHModGhpcyk7DQogICAgICBhY3RpdmVTdWIgPSBwcmV2RWZmZWN0Ow0KICAgICAgc2hvdWxkVHJhY2sgPSBwcmV2U2hvdWxkVHJhY2s7DQogICAgICB0aGlzLmZsYWdzICY9IC0zOw0KICAgIH0NCiAgfQ0KICBzdG9wKCkgew0KICAgIGlmICh0aGlzLmZsYWdzICYgMSkgew0KICAgICAgZm9yIChsZXQgbGluayA9IHRoaXMuZGVwczsgbGluazsgbGluayA9IGxpbmsubmV4dERlcCkgew0KICAgICAgICByZW1vdmVTdWIobGluayk7DQogICAgICB9DQogICAgICB0aGlzLmRlcHMgPSB0aGlzLmRlcHNUYWlsID0gdm9pZCAwOw0KICAgICAgY2xlYW51cEVmZmVjdCh0aGlzKTsNCiAgICAgIHRoaXMub25TdG9wICYmIHRoaXMub25TdG9wKCk7DQogICAgICB0aGlzLmZsYWdzICY9IC0yOw0KICAgIH0NCiAgfQ0KICB0cmlnZ2VyKCkgew0KICAgIGlmICh0aGlzLmZsYWdzICYgNjQpIHsNCiAgICAgIHBhdXNlZFF1ZXVlRWZmZWN0cy5hZGQodGhpcyk7DQogICAgfSBlbHNlIGlmICh0aGlzLnNjaGVkdWxlcikgew0KICAgICAgdGhpcy5zY2hlZHVsZXIoKTsNCiAgICB9IGVsc2Ugew0KICAgICAgdGhpcy5ydW5JZkRpcnR5KCk7DQogICAgfQ0KICB9DQogIC8qKg0KICAgKiBAaW50ZXJuYWwNCiAgICovDQogIHJ1bklmRGlydHkoKSB7DQogICAgaWYgKGlzRGlydHkodGhpcykpIHsNCiAgICAgIHRoaXMucnVuKCk7DQogICAgfQ0KICB9DQogIGdldCBkaXJ0eSgpIHsNCiAgICByZXR1cm4gaXNEaXJ0eSh0aGlzKTsNCiAgfQ0KfQ0KbGV0IGJhdGNoRGVwdGggPSAwOw0KbGV0IGJhdGNoZWRTdWI7DQpsZXQgYmF0Y2hlZENvbXB1dGVkOw0KZnVuY3Rpb24gYmF0Y2goc3ViLCBpc0NvbXB1dGVkID0gZmFsc2UpIHsNCiAgc3ViLmZsYWdzIHw9IDg7DQogIGlmIChpc0NvbXB1dGVkKSB7DQogICAgc3ViLm5leHQgPSBiYXRjaGVkQ29tcHV0ZWQ7DQogICAgYmF0Y2hlZENvbXB1dGVkID0gc3ViOw0KICAgIHJldHVybjsNCiAgfQ0KICBzdWIubmV4dCA9IGJhdGNoZWRTdWI7DQogIGJhdGNoZWRTdWIgPSBzdWI7DQp9DQpmdW5jdGlvbiBzdGFydEJhdGNoKCkgew0KICBiYXRjaERlcHRoKys7DQp9DQpmdW5jdGlvbiBlbmRCYXRjaCgpIHsNCiAgaWYgKC0tYmF0Y2hEZXB0aCA+IDApIHsNCiAgICByZXR1cm47DQogIH0NCiAgaWYgKGJhdGNoZWRDb21wdXRlZCkgew0KICAgIGxldCBlID0gYmF0Y2hlZENvbXB1dGVkOw0KICAgIGJhdGNoZWRDb21wdXRlZCA9IHZvaWQgMDsNCiAgICB3aGlsZSAoZSkgew0KICAgICAgY29uc3QgbmV4dCA9IGUubmV4dDsNCiAgICAgIGUubmV4dCA9IHZvaWQgMDsNCiAgICAgIGUuZmxhZ3MgJj0gLTk7DQogICAgICBlID0gbmV4dDsNCiAgICB9DQogIH0NCiAgbGV0IGVycm9yOw0KICB3aGlsZSAoYmF0Y2hlZFN1Yikgew0KICAgIGxldCBlID0gYmF0Y2hlZFN1YjsNCiAgICBiYXRjaGVkU3ViID0gdm9pZCAwOw0KICAgIHdoaWxlIChlKSB7DQogICAgICBjb25zdCBuZXh0ID0gZS5uZXh0Ow0KICAgICAgZS5uZXh0ID0gdm9pZCAwOw0KICAgICAgZS5mbGFncyAmPSAtOTsNCiAgICAgIGlmIChlLmZsYWdzICYgMSkgew0KICAgICAgICB0cnkgew0KICAgICAgICAgIDsNCiAgICAgICAgICBlLnRyaWdnZXIoKTsNCiAgICAgICAgfSBjYXRjaCAoZXJyKSB7DQogICAgICAgICAgaWYgKCFlcnJvcikgZXJyb3IgPSBlcnI7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGUgPSBuZXh0Ow0KICAgIH0NCiAgfQ0KICBpZiAoZXJyb3IpIHRocm93IGVycm9yOw0KfQ0KZnVuY3Rpb24gcHJlcGFyZURlcHMoc3ViKSB7DQogIGZvciAobGV0IGxpbmsgPSBzdWIuZGVwczsgbGluazsgbGluayA9IGxpbmsubmV4dERlcCkgew0KICAgIGxpbmsudmVyc2lvbiA9IC0xOw0KICAgIGxpbmsucHJldkFjdGl2ZUxpbmsgPSBsaW5rLmRlcC5hY3RpdmVMaW5rOw0KICAgIGxpbmsuZGVwLmFjdGl2ZUxpbmsgPSBsaW5rOw0KICB9DQp9DQpmdW5jdGlvbiBjbGVhbnVwRGVwcyhzdWIpIHsNCiAgbGV0IGhlYWQ7DQogIGxldCB0YWlsID0gc3ViLmRlcHNUYWlsOw0KICBsZXQgbGluayA9IHRhaWw7DQogIHdoaWxlIChsaW5rKSB7DQogICAgY29uc3QgcHJldiA9IGxpbmsucHJldkRlcDsNCiAgICBpZiAobGluay52ZXJzaW9uID09PSAtMSkgew0KICAgICAgaWYgKGxpbmsgPT09IHRhaWwpIHRhaWwgPSBwcmV2Ow0KICAgICAgcmVtb3ZlU3ViKGxpbmspOw0KICAgICAgcmVtb3ZlRGVwKGxpbmspOw0KICAgIH0gZWxzZSB7DQogICAgICBoZWFkID0gbGluazsNCiAgICB9DQogICAgbGluay5kZXAuYWN0aXZlTGluayA9IGxpbmsucHJldkFjdGl2ZUxpbms7DQogICAgbGluay5wcmV2QWN0aXZlTGluayA9IHZvaWQgMDsNCiAgICBsaW5rID0gcHJldjsNCiAgfQ0KICBzdWIuZGVwcyA9IGhlYWQ7DQogIHN1Yi5kZXBzVGFpbCA9IHRhaWw7DQp9DQpmdW5jdGlvbiBpc0RpcnR5KHN1Yikgew0KICBmb3IgKGxldCBsaW5rID0gc3ViLmRlcHM7IGxpbms7IGxpbmsgPSBsaW5rLm5leHREZXApIHsNCiAgICBpZiAobGluay5kZXAudmVyc2lvbiAhPT0gbGluay52ZXJzaW9uIHx8IGxpbmsuZGVwLmNvbXB1dGVkICYmIChyZWZyZXNoQ29tcHV0ZWQobGluay5kZXAuY29tcHV0ZWQpIHx8IGxpbmsuZGVwLnZlcnNpb24gIT09IGxpbmsudmVyc2lvbikpIHsNCiAgICAgIHJldHVybiB0cnVlOw0KICAgIH0NCiAgfQ0KICBpZiAoc3ViLl9kaXJ0eSkgew0KICAgIHJldHVybiB0cnVlOw0KICB9DQogIHJldHVybiBmYWxzZTsNCn0NCmZ1bmN0aW9uIHJlZnJlc2hDb21wdXRlZChjb21wdXRlZCkgew0KICBpZiAoY29tcHV0ZWQuZmxhZ3MgJiA0ICYmICEoY29tcHV0ZWQuZmxhZ3MgJiAxNikpIHsNCiAgICByZXR1cm47DQogIH0NCiAgY29tcHV0ZWQuZmxhZ3MgJj0gLTE3Ow0KICBpZiAoY29tcHV0ZWQuZ2xvYmFsVmVyc2lvbiA9PT0gZ2xvYmFsVmVyc2lvbikgew0KICAgIHJldHVybjsNCiAgfQ0KICBjb21wdXRlZC5nbG9iYWxWZXJzaW9uID0gZ2xvYmFsVmVyc2lvbjsNCiAgaWYgKCFjb21wdXRlZC5pc1NTUiAmJiBjb21wdXRlZC5mbGFncyAmIDEyOCAmJiAoIWNvbXB1dGVkLmRlcHMgJiYgIWNvbXB1dGVkLl9kaXJ0eSB8fCAhaXNEaXJ0eShjb21wdXRlZCkpKSB7DQogICAgcmV0dXJuOw0KICB9DQogIGNvbXB1dGVkLmZsYWdzIHw9IDI7DQogIGNvbnN0IGRlcCA9IGNvbXB1dGVkLmRlcDsNCiAgY29uc3QgcHJldlN1YiA9IGFjdGl2ZVN1YjsNCiAgY29uc3QgcHJldlNob3VsZFRyYWNrID0gc2hvdWxkVHJhY2s7DQogIGFjdGl2ZVN1YiA9IGNvbXB1dGVkOw0KICBzaG91bGRUcmFjayA9IHRydWU7DQogIHRyeSB7DQogICAgcHJlcGFyZURlcHMoY29tcHV0ZWQpOw0KICAgIGNvbnN0IHZhbHVlID0gY29tcHV0ZWQuZm4oY29tcHV0ZWQuX3ZhbHVlKTsNCiAgICBpZiAoZGVwLnZlcnNpb24gPT09IDAgfHwgaGFzQ2hhbmdlZCh2YWx1ZSwgY29tcHV0ZWQuX3ZhbHVlKSkgew0KICAgICAgY29tcHV0ZWQuZmxhZ3MgfD0gMTI4Ow0KICAgICAgY29tcHV0ZWQuX3ZhbHVlID0gdmFsdWU7DQogICAgICBkZXAudmVyc2lvbisrOw0KICAgIH0NCiAgfSBjYXRjaCAoZXJyKSB7DQogICAgZGVwLnZlcnNpb24rKzsNCiAgICB0aHJvdyBlcnI7DQogIH0gZmluYWxseSB7DQogICAgYWN0aXZlU3ViID0gcHJldlN1YjsNCiAgICBzaG91bGRUcmFjayA9IHByZXZTaG91bGRUcmFjazsNCiAgICBjbGVhbnVwRGVwcyhjb21wdXRlZCk7DQogICAgY29tcHV0ZWQuZmxhZ3MgJj0gLTM7DQogIH0NCn0NCmZ1bmN0aW9uIHJlbW92ZVN1YihsaW5rLCBzb2Z0ID0gZmFsc2UpIHsNCiAgY29uc3QgeyBkZXAsIHByZXZTdWIsIG5leHRTdWIgfSA9IGxpbms7DQogIGlmIChwcmV2U3ViKSB7DQogICAgcHJldlN1Yi5uZXh0U3ViID0gbmV4dFN1YjsNCiAgICBsaW5rLnByZXZTdWIgPSB2b2lkIDA7DQogIH0NCiAgaWYgKG5leHRTdWIpIHsNCiAgICBuZXh0U3ViLnByZXZTdWIgPSBwcmV2U3ViOw0KICAgIGxpbmsubmV4dFN1YiA9IHZvaWQgMDsNCiAgfQ0KICBpZiAoZGVwLnN1YnNIZWFkID09PSBsaW5rKSB7DQogICAgZGVwLnN1YnNIZWFkID0gbmV4dFN1YjsNCiAgfQ0KICBpZiAoZGVwLnN1YnMgPT09IGxpbmspIHsNCiAgICBkZXAuc3VicyA9IHByZXZTdWI7DQogICAgaWYgKCFwcmV2U3ViICYmIGRlcC5jb21wdXRlZCkgew0KICAgICAgZGVwLmNvbXB1dGVkLmZsYWdzICY9IC01Ow0KICAgICAgZm9yIChsZXQgbCA9IGRlcC5jb21wdXRlZC5kZXBzOyBsOyBsID0gbC5uZXh0RGVwKSB7DQogICAgICAgIHJlbW92ZVN1YihsLCB0cnVlKTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgaWYgKCFzb2Z0ICYmICEtLWRlcC5zYyAmJiBkZXAubWFwKSB7DQogICAgZGVwLm1hcC5kZWxldGUoZGVwLmtleSk7DQogIH0NCn0NCmZ1bmN0aW9uIHJlbW92ZURlcChsaW5rKSB7DQogIGNvbnN0IHsgcHJldkRlcCwgbmV4dERlcCB9ID0gbGluazsNCiAgaWYgKHByZXZEZXApIHsNCiAgICBwcmV2RGVwLm5leHREZXAgPSBuZXh0RGVwOw0KICAgIGxpbmsucHJldkRlcCA9IHZvaWQgMDsNCiAgfQ0KICBpZiAobmV4dERlcCkgew0KICAgIG5leHREZXAucHJldkRlcCA9IHByZXZEZXA7DQogICAgbGluay5uZXh0RGVwID0gdm9pZCAwOw0KICB9DQp9DQpsZXQgc2hvdWxkVHJhY2sgPSB0cnVlOw0KY29uc3QgdHJhY2tTdGFjayA9IFtdOw0KZnVuY3Rpb24gcGF1c2VUcmFja2luZygpIHsNCiAgdHJhY2tTdGFjay5wdXNoKHNob3VsZFRyYWNrKTsNCiAgc2hvdWxkVHJhY2sgPSBmYWxzZTsNCn0NCmZ1bmN0aW9uIHJlc2V0VHJhY2tpbmcoKSB7DQogIGNvbnN0IGxhc3QgPSB0cmFja1N0YWNrLnBvcCgpOw0KICBzaG91bGRUcmFjayA9IGxhc3QgPT09IHZvaWQgMCA/IHRydWUgOiBsYXN0Ow0KfQ0KZnVuY3Rpb24gY2xlYW51cEVmZmVjdChlKSB7DQogIGNvbnN0IHsgY2xlYW51cCB9ID0gZTsNCiAgZS5jbGVhbnVwID0gdm9pZCAwOw0KICBpZiAoY2xlYW51cCkgew0KICAgIGNvbnN0IHByZXZTdWIgPSBhY3RpdmVTdWI7DQogICAgYWN0aXZlU3ViID0gdm9pZCAwOw0KICAgIHRyeSB7DQogICAgICBjbGVhbnVwKCk7DQogICAgfSBmaW5hbGx5IHsNCiAgICAgIGFjdGl2ZVN1YiA9IHByZXZTdWI7DQogICAgfQ0KICB9DQp9DQoNCmxldCBnbG9iYWxWZXJzaW9uID0gMDsNCmNsYXNzIExpbmsgew0KICBjb25zdHJ1Y3RvcihzdWIsIGRlcCkgew0KICAgIHRoaXMuc3ViID0gc3ViOw0KICAgIHRoaXMuZGVwID0gZGVwOw0KICAgIHRoaXMudmVyc2lvbiA9IGRlcC52ZXJzaW9uOw0KICAgIHRoaXMubmV4dERlcCA9IHRoaXMucHJldkRlcCA9IHRoaXMubmV4dFN1YiA9IHRoaXMucHJldlN1YiA9IHRoaXMucHJldkFjdGl2ZUxpbmsgPSB2b2lkIDA7DQogIH0NCn0NCmNsYXNzIERlcCB7DQogIC8vIFRPRE8gaXNvbGF0ZWREZWNsYXJhdGlvbnMgIl9fdl9za2lwIg0KICBjb25zdHJ1Y3Rvcihjb21wdXRlZCkgew0KICAgIHRoaXMuY29tcHV0ZWQgPSBjb21wdXRlZDsNCiAgICB0aGlzLnZlcnNpb24gPSAwOw0KICAgIC8qKg0KICAgICAqIExpbmsgYmV0d2VlbiB0aGlzIGRlcCBhbmQgdGhlIGN1cnJlbnQgYWN0aXZlIGVmZmVjdA0KICAgICAqLw0KICAgIHRoaXMuYWN0aXZlTGluayA9IHZvaWQgMDsNCiAgICAvKioNCiAgICAgKiBEb3VibHkgbGlua2VkIGxpc3QgcmVwcmVzZW50aW5nIHRoZSBzdWJzY3JpYmluZyBlZmZlY3RzICh0YWlsKQ0KICAgICAqLw0KICAgIHRoaXMuc3VicyA9IHZvaWQgMDsNCiAgICAvKioNCiAgICAgKiBGb3Igb2JqZWN0IHByb3BlcnR5IGRlcHMgY2xlYW51cA0KICAgICAqLw0KICAgIHRoaXMubWFwID0gdm9pZCAwOw0KICAgIHRoaXMua2V5ID0gdm9pZCAwOw0KICAgIC8qKg0KICAgICAqIFN1YnNjcmliZXIgY291bnRlcg0KICAgICAqLw0KICAgIHRoaXMuc2MgPSAwOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuX192X3NraXAgPSB0cnVlOw0KICAgIHsNCiAgICAgIHRoaXMuc3Vic0hlYWQgPSB2b2lkIDA7DQogICAgfQ0KICB9DQogIHRyYWNrKGRlYnVnSW5mbykgew0KICAgIGlmICghYWN0aXZlU3ViIHx8ICFzaG91bGRUcmFjayB8fCBhY3RpdmVTdWIgPT09IHRoaXMuY29tcHV0ZWQpIHsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgbGV0IGxpbmsgPSB0aGlzLmFjdGl2ZUxpbms7DQogICAgaWYgKGxpbmsgPT09IHZvaWQgMCB8fCBsaW5rLnN1YiAhPT0gYWN0aXZlU3ViKSB7DQogICAgICBsaW5rID0gdGhpcy5hY3RpdmVMaW5rID0gbmV3IExpbmsoYWN0aXZlU3ViLCB0aGlzKTsNCiAgICAgIGlmICghYWN0aXZlU3ViLmRlcHMpIHsNCiAgICAgICAgYWN0aXZlU3ViLmRlcHMgPSBhY3RpdmVTdWIuZGVwc1RhaWwgPSBsaW5rOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgbGluay5wcmV2RGVwID0gYWN0aXZlU3ViLmRlcHNUYWlsOw0KICAgICAgICBhY3RpdmVTdWIuZGVwc1RhaWwubmV4dERlcCA9IGxpbms7DQogICAgICAgIGFjdGl2ZVN1Yi5kZXBzVGFpbCA9IGxpbms7DQogICAgICB9DQogICAgICBhZGRTdWIobGluayk7DQogICAgfSBlbHNlIGlmIChsaW5rLnZlcnNpb24gPT09IC0xKSB7DQogICAgICBsaW5rLnZlcnNpb24gPSB0aGlzLnZlcnNpb247DQogICAgICBpZiAobGluay5uZXh0RGVwKSB7DQogICAgICAgIGNvbnN0IG5leHQgPSBsaW5rLm5leHREZXA7DQogICAgICAgIG5leHQucHJldkRlcCA9IGxpbmsucHJldkRlcDsNCiAgICAgICAgaWYgKGxpbmsucHJldkRlcCkgew0KICAgICAgICAgIGxpbmsucHJldkRlcC5uZXh0RGVwID0gbmV4dDsNCiAgICAgICAgfQ0KICAgICAgICBsaW5rLnByZXZEZXAgPSBhY3RpdmVTdWIuZGVwc1RhaWw7DQogICAgICAgIGxpbmsubmV4dERlcCA9IHZvaWQgMDsNCiAgICAgICAgYWN0aXZlU3ViLmRlcHNUYWlsLm5leHREZXAgPSBsaW5rOw0KICAgICAgICBhY3RpdmVTdWIuZGVwc1RhaWwgPSBsaW5rOw0KICAgICAgICBpZiAoYWN0aXZlU3ViLmRlcHMgPT09IGxpbmspIHsNCiAgICAgICAgICBhY3RpdmVTdWIuZGVwcyA9IG5leHQ7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogICAgaWYgKGFjdGl2ZVN1Yi5vblRyYWNrKSB7DQogICAgICBhY3RpdmVTdWIub25UcmFjaygNCiAgICAgICAgZXh0ZW5kKA0KICAgICAgICAgIHsNCiAgICAgICAgICAgIGVmZmVjdDogYWN0aXZlU3ViDQogICAgICAgICAgfSwNCiAgICAgICAgICBkZWJ1Z0luZm8NCiAgICAgICAgKQ0KICAgICAgKTsNCiAgICB9DQogICAgcmV0dXJuIGxpbms7DQogIH0NCiAgdHJpZ2dlcihkZWJ1Z0luZm8pIHsNCiAgICB0aGlzLnZlcnNpb24rKzsNCiAgICBnbG9iYWxWZXJzaW9uKys7DQogICAgdGhpcy5ub3RpZnkoZGVidWdJbmZvKTsNCiAgfQ0KICBub3RpZnkoZGVidWdJbmZvKSB7DQogICAgc3RhcnRCYXRjaCgpOw0KICAgIHRyeSB7DQogICAgICBpZiAodHJ1ZSkgew0KICAgICAgICBmb3IgKGxldCBoZWFkID0gdGhpcy5zdWJzSGVhZDsgaGVhZDsgaGVhZCA9IGhlYWQubmV4dFN1Yikgew0KICAgICAgICAgIGlmIChoZWFkLnN1Yi5vblRyaWdnZXIgJiYgIShoZWFkLnN1Yi5mbGFncyAmIDgpKSB7DQogICAgICAgICAgICBoZWFkLnN1Yi5vblRyaWdnZXIoDQogICAgICAgICAgICAgIGV4dGVuZCgNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICBlZmZlY3Q6IGhlYWQuc3ViDQogICAgICAgICAgICAgICAgfSwNCiAgICAgICAgICAgICAgICBkZWJ1Z0luZm8NCiAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgKTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGZvciAobGV0IGxpbmsgPSB0aGlzLnN1YnM7IGxpbms7IGxpbmsgPSBsaW5rLnByZXZTdWIpIHsNCiAgICAgICAgaWYgKGxpbmsuc3ViLm5vdGlmeSgpKSB7DQogICAgICAgICAgOw0KICAgICAgICAgIGxpbmsuc3ViLmRlcC5ub3RpZnkoKTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0gZmluYWxseSB7DQogICAgICBlbmRCYXRjaCgpOw0KICAgIH0NCiAgfQ0KfQ0KZnVuY3Rpb24gYWRkU3ViKGxpbmspIHsNCiAgbGluay5kZXAuc2MrKzsNCiAgaWYgKGxpbmsuc3ViLmZsYWdzICYgNCkgew0KICAgIGNvbnN0IGNvbXB1dGVkID0gbGluay5kZXAuY29tcHV0ZWQ7DQogICAgaWYgKGNvbXB1dGVkICYmICFsaW5rLmRlcC5zdWJzKSB7DQogICAgICBjb21wdXRlZC5mbGFncyB8PSA0IHwgMTY7DQogICAgICBmb3IgKGxldCBsID0gY29tcHV0ZWQuZGVwczsgbDsgbCA9IGwubmV4dERlcCkgew0KICAgICAgICBhZGRTdWIobCk7DQogICAgICB9DQogICAgfQ0KICAgIGNvbnN0IGN1cnJlbnRUYWlsID0gbGluay5kZXAuc3ViczsNCiAgICBpZiAoY3VycmVudFRhaWwgIT09IGxpbmspIHsNCiAgICAgIGxpbmsucHJldlN1YiA9IGN1cnJlbnRUYWlsOw0KICAgICAgaWYgKGN1cnJlbnRUYWlsKSBjdXJyZW50VGFpbC5uZXh0U3ViID0gbGluazsNCiAgICB9DQogICAgaWYgKGxpbmsuZGVwLnN1YnNIZWFkID09PSB2b2lkIDApIHsNCiAgICAgIGxpbmsuZGVwLnN1YnNIZWFkID0gbGluazsNCiAgICB9DQogICAgbGluay5kZXAuc3VicyA9IGxpbms7DQogIH0NCn0NCmNvbnN0IHRhcmdldE1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgV2Vha01hcCgpOw0KY29uc3QgSVRFUkFURV9LRVkgPSBTeW1ib2woDQogICJPYmplY3QgaXRlcmF0ZSIgDQopOw0KY29uc3QgTUFQX0tFWV9JVEVSQVRFX0tFWSA9IFN5bWJvbCgNCiAgIk1hcCBrZXlzIGl0ZXJhdGUiIA0KKTsNCmNvbnN0IEFSUkFZX0lURVJBVEVfS0VZID0gU3ltYm9sKA0KICAiQXJyYXkgaXRlcmF0ZSIgDQopOw0KZnVuY3Rpb24gdHJhY2sodGFyZ2V0LCB0eXBlLCBrZXkpIHsNCiAgaWYgKHNob3VsZFRyYWNrICYmIGFjdGl2ZVN1Yikgew0KICAgIGxldCBkZXBzTWFwID0gdGFyZ2V0TWFwLmdldCh0YXJnZXQpOw0KICAgIGlmICghZGVwc01hcCkgew0KICAgICAgdGFyZ2V0TWFwLnNldCh0YXJnZXQsIGRlcHNNYXAgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpKTsNCiAgICB9DQogICAgbGV0IGRlcCA9IGRlcHNNYXAuZ2V0KGtleSk7DQogICAgaWYgKCFkZXApIHsNCiAgICAgIGRlcHNNYXAuc2V0KGtleSwgZGVwID0gbmV3IERlcCgpKTsNCiAgICAgIGRlcC5tYXAgPSBkZXBzTWFwOw0KICAgICAgZGVwLmtleSA9IGtleTsNCiAgICB9DQogICAgew0KICAgICAgZGVwLnRyYWNrKHsNCiAgICAgICAgdGFyZ2V0LA0KICAgICAgICB0eXBlLA0KICAgICAgICBrZXkNCiAgICAgIH0pOw0KICAgIH0NCiAgfQ0KfQ0KZnVuY3Rpb24gdHJpZ2dlcih0YXJnZXQsIHR5cGUsIGtleSwgbmV3VmFsdWUsIG9sZFZhbHVlLCBvbGRUYXJnZXQpIHsNCiAgY29uc3QgZGVwc01hcCA9IHRhcmdldE1hcC5nZXQodGFyZ2V0KTsNCiAgaWYgKCFkZXBzTWFwKSB7DQogICAgZ2xvYmFsVmVyc2lvbisrOw0KICAgIHJldHVybjsNCiAgfQ0KICBjb25zdCBydW4gPSAoZGVwKSA9PiB7DQogICAgaWYgKGRlcCkgew0KICAgICAgew0KICAgICAgICBkZXAudHJpZ2dlcih7DQogICAgICAgICAgdGFyZ2V0LA0KICAgICAgICAgIHR5cGUsDQogICAgICAgICAga2V5LA0KICAgICAgICAgIG5ld1ZhbHVlLA0KICAgICAgICAgIG9sZFZhbHVlLA0KICAgICAgICAgIG9sZFRhcmdldA0KICAgICAgICB9KTsNCiAgICAgIH0NCiAgICB9DQogIH07DQogIHN0YXJ0QmF0Y2goKTsNCiAgaWYgKHR5cGUgPT09ICJjbGVhciIpIHsNCiAgICBkZXBzTWFwLmZvckVhY2gocnVuKTsNCiAgfSBlbHNlIHsNCiAgICBjb25zdCB0YXJnZXRJc0FycmF5ID0gaXNBcnJheSh0YXJnZXQpOw0KICAgIGNvbnN0IGlzQXJyYXlJbmRleCA9IHRhcmdldElzQXJyYXkgJiYgaXNJbnRlZ2VyS2V5KGtleSk7DQogICAgaWYgKHRhcmdldElzQXJyYXkgJiYga2V5ID09PSAibGVuZ3RoIikgew0KICAgICAgY29uc3QgbmV3TGVuZ3RoID0gTnVtYmVyKG5ld1ZhbHVlKTsNCiAgICAgIGRlcHNNYXAuZm9yRWFjaCgoZGVwLCBrZXkyKSA9PiB7DQogICAgICAgIGlmIChrZXkyID09PSAibGVuZ3RoIiB8fCBrZXkyID09PSBBUlJBWV9JVEVSQVRFX0tFWSB8fCAhaXNTeW1ib2woa2V5MikgJiYga2V5MiA+PSBuZXdMZW5ndGgpIHsNCiAgICAgICAgICBydW4oZGVwKTsNCiAgICAgICAgfQ0KICAgICAgfSk7DQogICAgfSBlbHNlIHsNCiAgICAgIGlmIChrZXkgIT09IHZvaWQgMCB8fCBkZXBzTWFwLmhhcyh2b2lkIDApKSB7DQogICAgICAgIHJ1bihkZXBzTWFwLmdldChrZXkpKTsNCiAgICAgIH0NCiAgICAgIGlmIChpc0FycmF5SW5kZXgpIHsNCiAgICAgICAgcnVuKGRlcHNNYXAuZ2V0KEFSUkFZX0lURVJBVEVfS0VZKSk7DQogICAgICB9DQogICAgICBzd2l0Y2ggKHR5cGUpIHsNCiAgICAgICAgY2FzZSAiYWRkIjoNCiAgICAgICAgICBpZiAoIXRhcmdldElzQXJyYXkpIHsNCiAgICAgICAgICAgIHJ1bihkZXBzTWFwLmdldChJVEVSQVRFX0tFWSkpOw0KICAgICAgICAgICAgaWYgKGlzTWFwKHRhcmdldCkpIHsNCiAgICAgICAgICAgICAgcnVuKGRlcHNNYXAuZ2V0KE1BUF9LRVlfSVRFUkFURV9LRVkpKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICB9IGVsc2UgaWYgKGlzQXJyYXlJbmRleCkgew0KICAgICAgICAgICAgcnVuKGRlcHNNYXAuZ2V0KCJsZW5ndGgiKSk7DQogICAgICAgICAgfQ0KICAgICAgICAgIGJyZWFrOw0KICAgICAgICBjYXNlICJkZWxldGUiOg0KICAgICAgICAgIGlmICghdGFyZ2V0SXNBcnJheSkgew0KICAgICAgICAgICAgcnVuKGRlcHNNYXAuZ2V0KElURVJBVEVfS0VZKSk7DQogICAgICAgICAgICBpZiAoaXNNYXAodGFyZ2V0KSkgew0KICAgICAgICAgICAgICBydW4oZGVwc01hcC5nZXQoTUFQX0tFWV9JVEVSQVRFX0tFWSkpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgIH0NCiAgICAgICAgICBicmVhazsNCiAgICAgICAgY2FzZSAic2V0IjoNCiAgICAgICAgICBpZiAoaXNNYXAodGFyZ2V0KSkgew0KICAgICAgICAgICAgcnVuKGRlcHNNYXAuZ2V0KElURVJBVEVfS0VZKSk7DQogICAgICAgICAgfQ0KICAgICAgICAgIGJyZWFrOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICBlbmRCYXRjaCgpOw0KfQ0KDQpmdW5jdGlvbiByZWFjdGl2ZVJlYWRBcnJheShhcnJheSkgew0KICBjb25zdCByYXcgPSB0b1JhdyhhcnJheSk7DQogIGlmIChyYXcgPT09IGFycmF5KSByZXR1cm4gcmF3Ow0KICB0cmFjayhyYXcsICJpdGVyYXRlIiwgQVJSQVlfSVRFUkFURV9LRVkpOw0KICByZXR1cm4gaXNTaGFsbG93KGFycmF5KSA/IHJhdyA6IHJhdy5tYXAodG9SZWFjdGl2ZSk7DQp9DQpmdW5jdGlvbiBzaGFsbG93UmVhZEFycmF5KGFycikgew0KICB0cmFjayhhcnIgPSB0b1JhdyhhcnIpLCAiaXRlcmF0ZSIsIEFSUkFZX0lURVJBVEVfS0VZKTsNCiAgcmV0dXJuIGFycjsNCn0NCmNvbnN0IGFycmF5SW5zdHJ1bWVudGF0aW9ucyA9IHsNCiAgX19wcm90b19fOiBudWxsLA0KICBbU3ltYm9sLml0ZXJhdG9yXSgpIHsNCiAgICByZXR1cm4gaXRlcmF0b3IodGhpcywgU3ltYm9sLml0ZXJhdG9yLCB0b1JlYWN0aXZlKTsNCiAgfSwNCiAgY29uY2F0KC4uLmFyZ3MpIHsNCiAgICByZXR1cm4gcmVhY3RpdmVSZWFkQXJyYXkodGhpcykuY29uY2F0KA0KICAgICAgLi4uYXJncy5tYXAoKHgpID0+IGlzQXJyYXkoeCkgPyByZWFjdGl2ZVJlYWRBcnJheSh4KSA6IHgpDQogICAgKTsNCiAgfSwNCiAgZW50cmllcygpIHsNCiAgICByZXR1cm4gaXRlcmF0b3IodGhpcywgImVudHJpZXMiLCAodmFsdWUpID0+IHsNCiAgICAgIHZhbHVlWzFdID0gdG9SZWFjdGl2ZSh2YWx1ZVsxXSk7DQogICAgICByZXR1cm4gdmFsdWU7DQogICAgfSk7DQogIH0sDQogIGV2ZXJ5KGZuLCB0aGlzQXJnKSB7DQogICAgcmV0dXJuIGFwcGx5KHRoaXMsICJldmVyeSIsIGZuLCB0aGlzQXJnLCB2b2lkIDAsIGFyZ3VtZW50cyk7DQogIH0sDQogIGZpbHRlcihmbiwgdGhpc0FyZykgew0KICAgIHJldHVybiBhcHBseSh0aGlzLCAiZmlsdGVyIiwgZm4sIHRoaXNBcmcsICh2KSA9PiB2Lm1hcCh0b1JlYWN0aXZlKSwgYXJndW1lbnRzKTsNCiAgfSwNCiAgZmluZChmbiwgdGhpc0FyZykgew0KICAgIHJldHVybiBhcHBseSh0aGlzLCAiZmluZCIsIGZuLCB0aGlzQXJnLCB0b1JlYWN0aXZlLCBhcmd1bWVudHMpOw0KICB9LA0KICBmaW5kSW5kZXgoZm4sIHRoaXNBcmcpIHsNCiAgICByZXR1cm4gYXBwbHkodGhpcywgImZpbmRJbmRleCIsIGZuLCB0aGlzQXJnLCB2b2lkIDAsIGFyZ3VtZW50cyk7DQogIH0sDQogIGZpbmRMYXN0KGZuLCB0aGlzQXJnKSB7DQogICAgcmV0dXJuIGFwcGx5KHRoaXMsICJmaW5kTGFzdCIsIGZuLCB0aGlzQXJnLCB0b1JlYWN0aXZlLCBhcmd1bWVudHMpOw0KICB9LA0KICBmaW5kTGFzdEluZGV4KGZuLCB0aGlzQXJnKSB7DQogICAgcmV0dXJuIGFwcGx5KHRoaXMsICJmaW5kTGFzdEluZGV4IiwgZm4sIHRoaXNBcmcsIHZvaWQgMCwgYXJndW1lbnRzKTsNCiAgfSwNCiAgLy8gZmxhdCwgZmxhdE1hcCBjb3VsZCBiZW5lZml0IGZyb20gQVJSQVlfSVRFUkFURSBidXQgYXJlIG5vdCBzdHJhaWdodC1mb3J3YXJkIHRvIGltcGxlbWVudA0KICBmb3JFYWNoKGZuLCB0aGlzQXJnKSB7DQogICAgcmV0dXJuIGFwcGx5KHRoaXMsICJmb3JFYWNoIiwgZm4sIHRoaXNBcmcsIHZvaWQgMCwgYXJndW1lbnRzKTsNCiAgfSwNCiAgaW5jbHVkZXMoLi4uYXJncykgew0KICAgIHJldHVybiBzZWFyY2hQcm94eSh0aGlzLCAiaW5jbHVkZXMiLCBhcmdzKTsNCiAgfSwNCiAgaW5kZXhPZiguLi5hcmdzKSB7DQogICAgcmV0dXJuIHNlYXJjaFByb3h5KHRoaXMsICJpbmRleE9mIiwgYXJncyk7DQogIH0sDQogIGpvaW4oc2VwYXJhdG9yKSB7DQogICAgcmV0dXJuIHJlYWN0aXZlUmVhZEFycmF5KHRoaXMpLmpvaW4oc2VwYXJhdG9yKTsNCiAgfSwNCiAgLy8ga2V5cygpIGl0ZXJhdG9yIG9ubHkgcmVhZHMgYGxlbmd0aGAsIG5vIG9wdGltaXNhdGlvbiByZXF1aXJlZA0KICBsYXN0SW5kZXhPZiguLi5hcmdzKSB7DQogICAgcmV0dXJuIHNlYXJjaFByb3h5KHRoaXMsICJsYXN0SW5kZXhPZiIsIGFyZ3MpOw0KICB9LA0KICBtYXAoZm4sIHRoaXNBcmcpIHsNCiAgICByZXR1cm4gYXBwbHkodGhpcywgIm1hcCIsIGZuLCB0aGlzQXJnLCB2b2lkIDAsIGFyZ3VtZW50cyk7DQogIH0sDQogIHBvcCgpIHsNCiAgICByZXR1cm4gbm9UcmFja2luZyh0aGlzLCAicG9wIik7DQogIH0sDQogIHB1c2goLi4uYXJncykgew0KICAgIHJldHVybiBub1RyYWNraW5nKHRoaXMsICJwdXNoIiwgYXJncyk7DQogIH0sDQogIHJlZHVjZShmbiwgLi4uYXJncykgew0KICAgIHJldHVybiByZWR1Y2UodGhpcywgInJlZHVjZSIsIGZuLCBhcmdzKTsNCiAgfSwNCiAgcmVkdWNlUmlnaHQoZm4sIC4uLmFyZ3MpIHsNCiAgICByZXR1cm4gcmVkdWNlKHRoaXMsICJyZWR1Y2VSaWdodCIsIGZuLCBhcmdzKTsNCiAgfSwNCiAgc2hpZnQoKSB7DQogICAgcmV0dXJuIG5vVHJhY2tpbmcodGhpcywgInNoaWZ0Iik7DQogIH0sDQogIC8vIHNsaWNlIGNvdWxkIHVzZSBBUlJBWV9JVEVSQVRFIGJ1dCBhbHNvIHNlZW1zIHRvIGJlZyBmb3IgcmFuZ2UgdHJhY2tpbmcNCiAgc29tZShmbiwgdGhpc0FyZykgew0KICAgIHJldHVybiBhcHBseSh0aGlzLCAic29tZSIsIGZuLCB0aGlzQXJnLCB2b2lkIDAsIGFyZ3VtZW50cyk7DQogIH0sDQogIHNwbGljZSguLi5hcmdzKSB7DQogICAgcmV0dXJuIG5vVHJhY2tpbmcodGhpcywgInNwbGljZSIsIGFyZ3MpOw0KICB9LA0KICB0b1JldmVyc2VkKCkgew0KICAgIHJldHVybiByZWFjdGl2ZVJlYWRBcnJheSh0aGlzKS50b1JldmVyc2VkKCk7DQogIH0sDQogIHRvU29ydGVkKGNvbXBhcmVyKSB7DQogICAgcmV0dXJuIHJlYWN0aXZlUmVhZEFycmF5KHRoaXMpLnRvU29ydGVkKGNvbXBhcmVyKTsNCiAgfSwNCiAgdG9TcGxpY2VkKC4uLmFyZ3MpIHsNCiAgICByZXR1cm4gcmVhY3RpdmVSZWFkQXJyYXkodGhpcykudG9TcGxpY2VkKC4uLmFyZ3MpOw0KICB9LA0KICB1bnNoaWZ0KC4uLmFyZ3MpIHsNCiAgICByZXR1cm4gbm9UcmFja2luZyh0aGlzLCAidW5zaGlmdCIsIGFyZ3MpOw0KICB9LA0KICB2YWx1ZXMoKSB7DQogICAgcmV0dXJuIGl0ZXJhdG9yKHRoaXMsICJ2YWx1ZXMiLCB0b1JlYWN0aXZlKTsNCiAgfQ0KfTsNCmZ1bmN0aW9uIGl0ZXJhdG9yKHNlbGYsIG1ldGhvZCwgd3JhcFZhbHVlKSB7DQogIGNvbnN0IGFyciA9IHNoYWxsb3dSZWFkQXJyYXkoc2VsZik7DQogIGNvbnN0IGl0ZXIgPSBhcnJbbWV0aG9kXSgpOw0KICBpZiAoYXJyICE9PSBzZWxmICYmICFpc1NoYWxsb3coc2VsZikpIHsNCiAgICBpdGVyLl9uZXh0ID0gaXRlci5uZXh0Ow0KICAgIGl0ZXIubmV4dCA9ICgpID0+IHsNCiAgICAgIGNvbnN0IHJlc3VsdCA9IGl0ZXIuX25leHQoKTsNCiAgICAgIGlmIChyZXN1bHQudmFsdWUpIHsNCiAgICAgICAgcmVzdWx0LnZhbHVlID0gd3JhcFZhbHVlKHJlc3VsdC52YWx1ZSk7DQogICAgICB9DQogICAgICByZXR1cm4gcmVzdWx0Ow0KICAgIH07DQogIH0NCiAgcmV0dXJuIGl0ZXI7DQp9DQpjb25zdCBhcnJheVByb3RvID0gQXJyYXkucHJvdG90eXBlOw0KZnVuY3Rpb24gYXBwbHkoc2VsZiwgbWV0aG9kLCBmbiwgdGhpc0FyZywgd3JhcHBlZFJldEZuLCBhcmdzKSB7DQogIGNvbnN0IGFyciA9IHNoYWxsb3dSZWFkQXJyYXkoc2VsZik7DQogIGNvbnN0IG5lZWRzV3JhcCA9IGFyciAhPT0gc2VsZiAmJiAhaXNTaGFsbG93KHNlbGYpOw0KICBjb25zdCBtZXRob2RGbiA9IGFyclttZXRob2RdOw0KICBpZiAobWV0aG9kRm4gIT09IGFycmF5UHJvdG9bbWV0aG9kXSkgew0KICAgIGNvbnN0IHJlc3VsdDIgPSBtZXRob2RGbi5hcHBseShzZWxmLCBhcmdzKTsNCiAgICByZXR1cm4gbmVlZHNXcmFwID8gdG9SZWFjdGl2ZShyZXN1bHQyKSA6IHJlc3VsdDI7DQogIH0NCiAgbGV0IHdyYXBwZWRGbiA9IGZuOw0KICBpZiAoYXJyICE9PSBzZWxmKSB7DQogICAgaWYgKG5lZWRzV3JhcCkgew0KICAgICAgd3JhcHBlZEZuID0gZnVuY3Rpb24oaXRlbSwgaW5kZXgpIHsNCiAgICAgICAgcmV0dXJuIGZuLmNhbGwodGhpcywgdG9SZWFjdGl2ZShpdGVtKSwgaW5kZXgsIHNlbGYpOw0KICAgICAgfTsNCiAgICB9IGVsc2UgaWYgKGZuLmxlbmd0aCA+IDIpIHsNCiAgICAgIHdyYXBwZWRGbiA9IGZ1bmN0aW9uKGl0ZW0sIGluZGV4KSB7DQogICAgICAgIHJldHVybiBmbi5jYWxsKHRoaXMsIGl0ZW0sIGluZGV4LCBzZWxmKTsNCiAgICAgIH07DQogICAgfQ0KICB9DQogIGNvbnN0IHJlc3VsdCA9IG1ldGhvZEZuLmNhbGwoYXJyLCB3cmFwcGVkRm4sIHRoaXNBcmcpOw0KICByZXR1cm4gbmVlZHNXcmFwICYmIHdyYXBwZWRSZXRGbiA/IHdyYXBwZWRSZXRGbihyZXN1bHQpIDogcmVzdWx0Ow0KfQ0KZnVuY3Rpb24gcmVkdWNlKHNlbGYsIG1ldGhvZCwgZm4sIGFyZ3MpIHsNCiAgY29uc3QgYXJyID0gc2hhbGxvd1JlYWRBcnJheShzZWxmKTsNCiAgbGV0IHdyYXBwZWRGbiA9IGZuOw0KICBpZiAoYXJyICE9PSBzZWxmKSB7DQogICAgaWYgKCFpc1NoYWxsb3coc2VsZikpIHsNCiAgICAgIHdyYXBwZWRGbiA9IGZ1bmN0aW9uKGFjYywgaXRlbSwgaW5kZXgpIHsNCiAgICAgICAgcmV0dXJuIGZuLmNhbGwodGhpcywgYWNjLCB0b1JlYWN0aXZlKGl0ZW0pLCBpbmRleCwgc2VsZik7DQogICAgICB9Ow0KICAgIH0gZWxzZSBpZiAoZm4ubGVuZ3RoID4gMykgew0KICAgICAgd3JhcHBlZEZuID0gZnVuY3Rpb24oYWNjLCBpdGVtLCBpbmRleCkgew0KICAgICAgICByZXR1cm4gZm4uY2FsbCh0aGlzLCBhY2MsIGl0ZW0sIGluZGV4LCBzZWxmKTsNCiAgICAgIH07DQogICAgfQ0KICB9DQogIHJldHVybiBhcnJbbWV0aG9kXSh3cmFwcGVkRm4sIC4uLmFyZ3MpOw0KfQ0KZnVuY3Rpb24gc2VhcmNoUHJveHkoc2VsZiwgbWV0aG9kLCBhcmdzKSB7DQogIGNvbnN0IGFyciA9IHRvUmF3KHNlbGYpOw0KICB0cmFjayhhcnIsICJpdGVyYXRlIiwgQVJSQVlfSVRFUkFURV9LRVkpOw0KICBjb25zdCByZXMgPSBhcnJbbWV0aG9kXSguLi5hcmdzKTsNCiAgaWYgKChyZXMgPT09IC0xIHx8IHJlcyA9PT0gZmFsc2UpICYmIGlzUHJveHkoYXJnc1swXSkpIHsNCiAgICBhcmdzWzBdID0gdG9SYXcoYXJnc1swXSk7DQogICAgcmV0dXJuIGFyclttZXRob2RdKC4uLmFyZ3MpOw0KICB9DQogIHJldHVybiByZXM7DQp9DQpmdW5jdGlvbiBub1RyYWNraW5nKHNlbGYsIG1ldGhvZCwgYXJncyA9IFtdKSB7DQogIHBhdXNlVHJhY2tpbmcoKTsNCiAgc3RhcnRCYXRjaCgpOw0KICBjb25zdCByZXMgPSB0b1JhdyhzZWxmKVttZXRob2RdLmFwcGx5KHNlbGYsIGFyZ3MpOw0KICBlbmRCYXRjaCgpOw0KICByZXNldFRyYWNraW5nKCk7DQogIHJldHVybiByZXM7DQp9DQoNCmNvbnN0IGlzTm9uVHJhY2thYmxlS2V5cyA9IC8qIEBfX1BVUkVfXyAqLyBtYWtlTWFwKGBfX3Byb3RvX18sX192X2lzUmVmLF9faXNWdWVgKTsNCmNvbnN0IGJ1aWx0SW5TeW1ib2xzID0gbmV3IFNldCgNCiAgLyogQF9fUFVSRV9fICovIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKFN5bWJvbCkuZmlsdGVyKChrZXkpID0+IGtleSAhPT0gImFyZ3VtZW50cyIgJiYga2V5ICE9PSAiY2FsbGVyIikubWFwKChrZXkpID0+IFN5bWJvbFtrZXldKS5maWx0ZXIoaXNTeW1ib2wpDQopOw0KZnVuY3Rpb24gaGFzT3duUHJvcGVydHkoa2V5KSB7DQogIGlmICghaXNTeW1ib2woa2V5KSkga2V5ID0gU3RyaW5nKGtleSk7DQogIGNvbnN0IG9iaiA9IHRvUmF3KHRoaXMpOw0KICB0cmFjayhvYmosICJoYXMiLCBrZXkpOw0KICByZXR1cm4gb2JqLmhhc093blByb3BlcnR5KGtleSk7DQp9DQpjbGFzcyBCYXNlUmVhY3RpdmVIYW5kbGVyIHsNCiAgY29uc3RydWN0b3IoX2lzUmVhZG9ubHkgPSBmYWxzZSwgX2lzU2hhbGxvdyA9IGZhbHNlKSB7DQogICAgdGhpcy5faXNSZWFkb25seSA9IF9pc1JlYWRvbmx5Ow0KICAgIHRoaXMuX2lzU2hhbGxvdyA9IF9pc1NoYWxsb3c7DQogIH0NCiAgZ2V0KHRhcmdldCwga2V5LCByZWNlaXZlcikgew0KICAgIGlmIChrZXkgPT09ICJfX3Zfc2tpcCIpIHJldHVybiB0YXJnZXRbIl9fdl9za2lwIl07DQogICAgY29uc3QgaXNSZWFkb25seTIgPSB0aGlzLl9pc1JlYWRvbmx5LCBpc1NoYWxsb3cyID0gdGhpcy5faXNTaGFsbG93Ow0KICAgIGlmIChrZXkgPT09ICJfX3ZfaXNSZWFjdGl2ZSIpIHsNCiAgICAgIHJldHVybiAhaXNSZWFkb25seTI7DQogICAgfSBlbHNlIGlmIChrZXkgPT09ICJfX3ZfaXNSZWFkb25seSIpIHsNCiAgICAgIHJldHVybiBpc1JlYWRvbmx5MjsNCiAgICB9IGVsc2UgaWYgKGtleSA9PT0gIl9fdl9pc1NoYWxsb3ciKSB7DQogICAgICByZXR1cm4gaXNTaGFsbG93MjsNCiAgICB9IGVsc2UgaWYgKGtleSA9PT0gIl9fdl9yYXciKSB7DQogICAgICBpZiAocmVjZWl2ZXIgPT09IChpc1JlYWRvbmx5MiA/IGlzU2hhbGxvdzIgPyBzaGFsbG93UmVhZG9ubHlNYXAgOiByZWFkb25seU1hcCA6IGlzU2hhbGxvdzIgPyBzaGFsbG93UmVhY3RpdmVNYXAgOiByZWFjdGl2ZU1hcCkuZ2V0KHRhcmdldCkgfHwgLy8gcmVjZWl2ZXIgaXMgbm90IHRoZSByZWFjdGl2ZSBwcm94eSwgYnV0IGhhcyB0aGUgc2FtZSBwcm90b3R5cGUNCiAgICAgIC8vIHRoaXMgbWVhbnMgdGhlIHJlY2VpdmVyIGlzIGEgdXNlciBwcm94eSBvZiB0aGUgcmVhY3RpdmUgcHJveHkNCiAgICAgIE9iamVjdC5nZXRQcm90b3R5cGVPZih0YXJnZXQpID09PSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocmVjZWl2ZXIpKSB7DQogICAgICAgIHJldHVybiB0YXJnZXQ7DQogICAgICB9DQogICAgICByZXR1cm47DQogICAgfQ0KICAgIGNvbnN0IHRhcmdldElzQXJyYXkgPSBpc0FycmF5KHRhcmdldCk7DQogICAgaWYgKCFpc1JlYWRvbmx5Mikgew0KICAgICAgbGV0IGZuOw0KICAgICAgaWYgKHRhcmdldElzQXJyYXkgJiYgKGZuID0gYXJyYXlJbnN0cnVtZW50YXRpb25zW2tleV0pKSB7DQogICAgICAgIHJldHVybiBmbjsNCiAgICAgIH0NCiAgICAgIGlmIChrZXkgPT09ICJoYXNPd25Qcm9wZXJ0eSIpIHsNCiAgICAgICAgcmV0dXJuIGhhc093blByb3BlcnR5Ow0KICAgICAgfQ0KICAgIH0NCiAgICBjb25zdCByZXMgPSBSZWZsZWN0LmdldCgNCiAgICAgIHRhcmdldCwNCiAgICAgIGtleSwNCiAgICAgIC8vIGlmIHRoaXMgaXMgYSBwcm94eSB3cmFwcGluZyBhIHJlZiwgcmV0dXJuIG1ldGhvZHMgdXNpbmcgdGhlIHJhdyByZWYNCiAgICAgIC8vIGFzIHJlY2VpdmVyIHNvIHRoYXQgd2UgZG9uJ3QgaGF2ZSB0byBjYWxsIGB0b1Jhd2Agb24gdGhlIHJlZiBpbiBhbGwNCiAgICAgIC8vIGl0cyBjbGFzcyBtZXRob2RzDQogICAgICBpc1JlZih0YXJnZXQpID8gdGFyZ2V0IDogcmVjZWl2ZXINCiAgICApOw0KICAgIGlmIChpc1N5bWJvbChrZXkpID8gYnVpbHRJblN5bWJvbHMuaGFzKGtleSkgOiBpc05vblRyYWNrYWJsZUtleXMoa2V5KSkgew0KICAgICAgcmV0dXJuIHJlczsNCiAgICB9DQogICAgaWYgKCFpc1JlYWRvbmx5Mikgew0KICAgICAgdHJhY2sodGFyZ2V0LCAiZ2V0Iiwga2V5KTsNCiAgICB9DQogICAgaWYgKGlzU2hhbGxvdzIpIHsNCiAgICAgIHJldHVybiByZXM7DQogICAgfQ0KICAgIGlmIChpc1JlZihyZXMpKSB7DQogICAgICByZXR1cm4gdGFyZ2V0SXNBcnJheSAmJiBpc0ludGVnZXJLZXkoa2V5KSA/IHJlcyA6IHJlcy52YWx1ZTsNCiAgICB9DQogICAgaWYgKGlzT2JqZWN0KHJlcykpIHsNCiAgICAgIHJldHVybiBpc1JlYWRvbmx5MiA/IHJlYWRvbmx5KHJlcykgOiByZWFjdGl2ZShyZXMpOw0KICAgIH0NCiAgICByZXR1cm4gcmVzOw0KICB9DQp9DQpjbGFzcyBNdXRhYmxlUmVhY3RpdmVIYW5kbGVyIGV4dGVuZHMgQmFzZVJlYWN0aXZlSGFuZGxlciB7DQogIGNvbnN0cnVjdG9yKGlzU2hhbGxvdzIgPSBmYWxzZSkgew0KICAgIHN1cGVyKGZhbHNlLCBpc1NoYWxsb3cyKTsNCiAgfQ0KICBzZXQodGFyZ2V0LCBrZXksIHZhbHVlLCByZWNlaXZlcikgew0KICAgIGxldCBvbGRWYWx1ZSA9IHRhcmdldFtrZXldOw0KICAgIGlmICghdGhpcy5faXNTaGFsbG93KSB7DQogICAgICBjb25zdCBpc09sZFZhbHVlUmVhZG9ubHkgPSBpc1JlYWRvbmx5KG9sZFZhbHVlKTsNCiAgICAgIGlmICghaXNTaGFsbG93KHZhbHVlKSAmJiAhaXNSZWFkb25seSh2YWx1ZSkpIHsNCiAgICAgICAgb2xkVmFsdWUgPSB0b1JhdyhvbGRWYWx1ZSk7DQogICAgICAgIHZhbHVlID0gdG9SYXcodmFsdWUpOw0KICAgICAgfQ0KICAgICAgaWYgKCFpc0FycmF5KHRhcmdldCkgJiYgaXNSZWYob2xkVmFsdWUpICYmICFpc1JlZih2YWx1ZSkpIHsNCiAgICAgICAgaWYgKGlzT2xkVmFsdWVSZWFkb25seSkgew0KICAgICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBvbGRWYWx1ZS52YWx1ZSA9IHZhbHVlOw0KICAgICAgICAgIHJldHVybiB0cnVlOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICAgIGNvbnN0IGhhZEtleSA9IGlzQXJyYXkodGFyZ2V0KSAmJiBpc0ludGVnZXJLZXkoa2V5KSA/IE51bWJlcihrZXkpIDwgdGFyZ2V0Lmxlbmd0aCA6IGhhc093bih0YXJnZXQsIGtleSk7DQogICAgY29uc3QgcmVzdWx0ID0gUmVmbGVjdC5zZXQoDQogICAgICB0YXJnZXQsDQogICAgICBrZXksDQogICAgICB2YWx1ZSwNCiAgICAgIGlzUmVmKHRhcmdldCkgPyB0YXJnZXQgOiByZWNlaXZlcg0KICAgICk7DQogICAgaWYgKHRhcmdldCA9PT0gdG9SYXcocmVjZWl2ZXIpKSB7DQogICAgICBpZiAoIWhhZEtleSkgew0KICAgICAgICB0cmlnZ2VyKHRhcmdldCwgImFkZCIsIGtleSwgdmFsdWUpOw0KICAgICAgfSBlbHNlIGlmIChoYXNDaGFuZ2VkKHZhbHVlLCBvbGRWYWx1ZSkpIHsNCiAgICAgICAgdHJpZ2dlcih0YXJnZXQsICJzZXQiLCBrZXksIHZhbHVlLCBvbGRWYWx1ZSk7DQogICAgICB9DQogICAgfQ0KICAgIHJldHVybiByZXN1bHQ7DQogIH0NCiAgZGVsZXRlUHJvcGVydHkodGFyZ2V0LCBrZXkpIHsNCiAgICBjb25zdCBoYWRLZXkgPSBoYXNPd24odGFyZ2V0LCBrZXkpOw0KICAgIGNvbnN0IG9sZFZhbHVlID0gdGFyZ2V0W2tleV07DQogICAgY29uc3QgcmVzdWx0ID0gUmVmbGVjdC5kZWxldGVQcm9wZXJ0eSh0YXJnZXQsIGtleSk7DQogICAgaWYgKHJlc3VsdCAmJiBoYWRLZXkpIHsNCiAgICAgIHRyaWdnZXIodGFyZ2V0LCAiZGVsZXRlIiwga2V5LCB2b2lkIDAsIG9sZFZhbHVlKTsNCiAgICB9DQogICAgcmV0dXJuIHJlc3VsdDsNCiAgfQ0KICBoYXModGFyZ2V0LCBrZXkpIHsNCiAgICBjb25zdCByZXN1bHQgPSBSZWZsZWN0Lmhhcyh0YXJnZXQsIGtleSk7DQogICAgaWYgKCFpc1N5bWJvbChrZXkpIHx8ICFidWlsdEluU3ltYm9scy5oYXMoa2V5KSkgew0KICAgICAgdHJhY2sodGFyZ2V0LCAiaGFzIiwga2V5KTsNCiAgICB9DQogICAgcmV0dXJuIHJlc3VsdDsNCiAgfQ0KICBvd25LZXlzKHRhcmdldCkgew0KICAgIHRyYWNrKA0KICAgICAgdGFyZ2V0LA0KICAgICAgIml0ZXJhdGUiLA0KICAgICAgaXNBcnJheSh0YXJnZXQpID8gImxlbmd0aCIgOiBJVEVSQVRFX0tFWQ0KICAgICk7DQogICAgcmV0dXJuIFJlZmxlY3Qub3duS2V5cyh0YXJnZXQpOw0KICB9DQp9DQpjbGFzcyBSZWFkb25seVJlYWN0aXZlSGFuZGxlciBleHRlbmRzIEJhc2VSZWFjdGl2ZUhhbmRsZXIgew0KICBjb25zdHJ1Y3Rvcihpc1NoYWxsb3cyID0gZmFsc2UpIHsNCiAgICBzdXBlcih0cnVlLCBpc1NoYWxsb3cyKTsNCiAgfQ0KICBzZXQodGFyZ2V0LCBrZXkpIHsNCiAgICB7DQogICAgICB3YXJuJDIoDQogICAgICAgIGBTZXQgb3BlcmF0aW9uIG9uIGtleSAiJHtTdHJpbmcoa2V5KX0iIGZhaWxlZDogdGFyZ2V0IGlzIHJlYWRvbmx5LmAsDQogICAgICAgIHRhcmdldA0KICAgICAgKTsNCiAgICB9DQogICAgcmV0dXJuIHRydWU7DQogIH0NCiAgZGVsZXRlUHJvcGVydHkodGFyZ2V0LCBrZXkpIHsNCiAgICB7DQogICAgICB3YXJuJDIoDQogICAgICAgIGBEZWxldGUgb3BlcmF0aW9uIG9uIGtleSAiJHtTdHJpbmcoa2V5KX0iIGZhaWxlZDogdGFyZ2V0IGlzIHJlYWRvbmx5LmAsDQogICAgICAgIHRhcmdldA0KICAgICAgKTsNCiAgICB9DQogICAgcmV0dXJuIHRydWU7DQogIH0NCn0NCmNvbnN0IG11dGFibGVIYW5kbGVycyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTXV0YWJsZVJlYWN0aXZlSGFuZGxlcigpOw0KY29uc3QgcmVhZG9ubHlIYW5kbGVycyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgUmVhZG9ubHlSZWFjdGl2ZUhhbmRsZXIoKTsNCmNvbnN0IHNoYWxsb3dSZWFjdGl2ZUhhbmRsZXJzID0gLyogQF9fUFVSRV9fICovIG5ldyBNdXRhYmxlUmVhY3RpdmVIYW5kbGVyKHRydWUpOw0KY29uc3Qgc2hhbGxvd1JlYWRvbmx5SGFuZGxlcnMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFJlYWRvbmx5UmVhY3RpdmVIYW5kbGVyKHRydWUpOw0KDQpjb25zdCB0b1NoYWxsb3cgPSAodmFsdWUpID0+IHZhbHVlOw0KY29uc3QgZ2V0UHJvdG8gPSAodikgPT4gUmVmbGVjdC5nZXRQcm90b3R5cGVPZih2KTsNCmZ1bmN0aW9uIGNyZWF0ZUl0ZXJhYmxlTWV0aG9kKG1ldGhvZCwgaXNSZWFkb25seTIsIGlzU2hhbGxvdzIpIHsNCiAgcmV0dXJuIGZ1bmN0aW9uKC4uLmFyZ3MpIHsNCiAgICBjb25zdCB0YXJnZXQgPSB0aGlzWyJfX3ZfcmF3Il07DQogICAgY29uc3QgcmF3VGFyZ2V0ID0gdG9SYXcodGFyZ2V0KTsNCiAgICBjb25zdCB0YXJnZXRJc01hcCA9IGlzTWFwKHJhd1RhcmdldCk7DQogICAgY29uc3QgaXNQYWlyID0gbWV0aG9kID09PSAiZW50cmllcyIgfHwgbWV0aG9kID09PSBTeW1ib2wuaXRlcmF0b3IgJiYgdGFyZ2V0SXNNYXA7DQogICAgY29uc3QgaXNLZXlPbmx5ID0gbWV0aG9kID09PSAia2V5cyIgJiYgdGFyZ2V0SXNNYXA7DQogICAgY29uc3QgaW5uZXJJdGVyYXRvciA9IHRhcmdldFttZXRob2RdKC4uLmFyZ3MpOw0KICAgIGNvbnN0IHdyYXAgPSBpc1NoYWxsb3cyID8gdG9TaGFsbG93IDogaXNSZWFkb25seTIgPyB0b1JlYWRvbmx5IDogdG9SZWFjdGl2ZTsNCiAgICAhaXNSZWFkb25seTIgJiYgdHJhY2soDQogICAgICByYXdUYXJnZXQsDQogICAgICAiaXRlcmF0ZSIsDQogICAgICBpc0tleU9ubHkgPyBNQVBfS0VZX0lURVJBVEVfS0VZIDogSVRFUkFURV9LRVkNCiAgICApOw0KICAgIHJldHVybiB7DQogICAgICAvLyBpdGVyYXRvciBwcm90b2NvbA0KICAgICAgbmV4dCgpIHsNCiAgICAgICAgY29uc3QgeyB2YWx1ZSwgZG9uZSB9ID0gaW5uZXJJdGVyYXRvci5uZXh0KCk7DQogICAgICAgIHJldHVybiBkb25lID8geyB2YWx1ZSwgZG9uZSB9IDogew0KICAgICAgICAgIHZhbHVlOiBpc1BhaXIgPyBbd3JhcCh2YWx1ZVswXSksIHdyYXAodmFsdWVbMV0pXSA6IHdyYXAodmFsdWUpLA0KICAgICAgICAgIGRvbmUNCiAgICAgICAgfTsNCiAgICAgIH0sDQogICAgICAvLyBpdGVyYWJsZSBwcm90b2NvbA0KICAgICAgW1N5bWJvbC5pdGVyYXRvcl0oKSB7DQogICAgICAgIHJldHVybiB0aGlzOw0KICAgICAgfQ0KICAgIH07DQogIH07DQp9DQpmdW5jdGlvbiBjcmVhdGVSZWFkb25seU1ldGhvZCh0eXBlKSB7DQogIHJldHVybiBmdW5jdGlvbiguLi5hcmdzKSB7DQogICAgew0KICAgICAgY29uc3Qga2V5ID0gYXJnc1swXSA/IGBvbiBrZXkgIiR7YXJnc1swXX0iIGAgOiBgYDsNCiAgICAgIHdhcm4kMigNCiAgICAgICAgYCR7Y2FwaXRhbGl6ZSh0eXBlKX0gb3BlcmF0aW9uICR7a2V5fWZhaWxlZDogdGFyZ2V0IGlzIHJlYWRvbmx5LmAsDQogICAgICAgIHRvUmF3KHRoaXMpDQogICAgICApOw0KICAgIH0NCiAgICByZXR1cm4gdHlwZSA9PT0gImRlbGV0ZSIgPyBmYWxzZSA6IHR5cGUgPT09ICJjbGVhciIgPyB2b2lkIDAgOiB0aGlzOw0KICB9Ow0KfQ0KZnVuY3Rpb24gY3JlYXRlSW5zdHJ1bWVudGF0aW9ucyhyZWFkb25seSwgc2hhbGxvdykgew0KICBjb25zdCBpbnN0cnVtZW50YXRpb25zID0gew0KICAgIGdldChrZXkpIHsNCiAgICAgIGNvbnN0IHRhcmdldCA9IHRoaXNbIl9fdl9yYXciXTsNCiAgICAgIGNvbnN0IHJhd1RhcmdldCA9IHRvUmF3KHRhcmdldCk7DQogICAgICBjb25zdCByYXdLZXkgPSB0b1JhdyhrZXkpOw0KICAgICAgaWYgKCFyZWFkb25seSkgew0KICAgICAgICBpZiAoaGFzQ2hhbmdlZChrZXksIHJhd0tleSkpIHsNCiAgICAgICAgICB0cmFjayhyYXdUYXJnZXQsICJnZXQiLCBrZXkpOw0KICAgICAgICB9DQogICAgICAgIHRyYWNrKHJhd1RhcmdldCwgImdldCIsIHJhd0tleSk7DQogICAgICB9DQogICAgICBjb25zdCB7IGhhcyB9ID0gZ2V0UHJvdG8ocmF3VGFyZ2V0KTsNCiAgICAgIGNvbnN0IHdyYXAgPSBzaGFsbG93ID8gdG9TaGFsbG93IDogcmVhZG9ubHkgPyB0b1JlYWRvbmx5IDogdG9SZWFjdGl2ZTsNCiAgICAgIGlmIChoYXMuY2FsbChyYXdUYXJnZXQsIGtleSkpIHsNCiAgICAgICAgcmV0dXJuIHdyYXAodGFyZ2V0LmdldChrZXkpKTsNCiAgICAgIH0gZWxzZSBpZiAoaGFzLmNhbGwocmF3VGFyZ2V0LCByYXdLZXkpKSB7DQogICAgICAgIHJldHVybiB3cmFwKHRhcmdldC5nZXQocmF3S2V5KSk7DQogICAgICB9IGVsc2UgaWYgKHRhcmdldCAhPT0gcmF3VGFyZ2V0KSB7DQogICAgICAgIHRhcmdldC5nZXQoa2V5KTsNCiAgICAgIH0NCiAgICB9LA0KICAgIGdldCBzaXplKCkgew0KICAgICAgY29uc3QgdGFyZ2V0ID0gdGhpc1siX192X3JhdyJdOw0KICAgICAgIXJlYWRvbmx5ICYmIHRyYWNrKHRvUmF3KHRhcmdldCksICJpdGVyYXRlIiwgSVRFUkFURV9LRVkpOw0KICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0KHRhcmdldCwgInNpemUiLCB0YXJnZXQpOw0KICAgIH0sDQogICAgaGFzKGtleSkgew0KICAgICAgY29uc3QgdGFyZ2V0ID0gdGhpc1siX192X3JhdyJdOw0KICAgICAgY29uc3QgcmF3VGFyZ2V0ID0gdG9SYXcodGFyZ2V0KTsNCiAgICAgIGNvbnN0IHJhd0tleSA9IHRvUmF3KGtleSk7DQogICAgICBpZiAoIXJlYWRvbmx5KSB7DQogICAgICAgIGlmIChoYXNDaGFuZ2VkKGtleSwgcmF3S2V5KSkgew0KICAgICAgICAgIHRyYWNrKHJhd1RhcmdldCwgImhhcyIsIGtleSk7DQogICAgICAgIH0NCiAgICAgICAgdHJhY2socmF3VGFyZ2V0LCAiaGFzIiwgcmF3S2V5KTsNCiAgICAgIH0NCiAgICAgIHJldHVybiBrZXkgPT09IHJhd0tleSA/IHRhcmdldC5oYXMoa2V5KSA6IHRhcmdldC5oYXMoa2V5KSB8fCB0YXJnZXQuaGFzKHJhd0tleSk7DQogICAgfSwNCiAgICBmb3JFYWNoKGNhbGxiYWNrLCB0aGlzQXJnKSB7DQogICAgICBjb25zdCBvYnNlcnZlZCA9IHRoaXM7DQogICAgICBjb25zdCB0YXJnZXQgPSBvYnNlcnZlZFsiX192X3JhdyJdOw0KICAgICAgY29uc3QgcmF3VGFyZ2V0ID0gdG9SYXcodGFyZ2V0KTsNCiAgICAgIGNvbnN0IHdyYXAgPSBzaGFsbG93ID8gdG9TaGFsbG93IDogcmVhZG9ubHkgPyB0b1JlYWRvbmx5IDogdG9SZWFjdGl2ZTsNCiAgICAgICFyZWFkb25seSAmJiB0cmFjayhyYXdUYXJnZXQsICJpdGVyYXRlIiwgSVRFUkFURV9LRVkpOw0KICAgICAgcmV0dXJuIHRhcmdldC5mb3JFYWNoKCh2YWx1ZSwga2V5KSA9PiB7DQogICAgICAgIHJldHVybiBjYWxsYmFjay5jYWxsKHRoaXNBcmcsIHdyYXAodmFsdWUpLCB3cmFwKGtleSksIG9ic2VydmVkKTsNCiAgICAgIH0pOw0KICAgIH0NCiAgfTsNCiAgZXh0ZW5kKA0KICAgIGluc3RydW1lbnRhdGlvbnMsDQogICAgcmVhZG9ubHkgPyB7DQogICAgICBhZGQ6IGNyZWF0ZVJlYWRvbmx5TWV0aG9kKCJhZGQiKSwNCiAgICAgIHNldDogY3JlYXRlUmVhZG9ubHlNZXRob2QoInNldCIpLA0KICAgICAgZGVsZXRlOiBjcmVhdGVSZWFkb25seU1ldGhvZCgiZGVsZXRlIiksDQogICAgICBjbGVhcjogY3JlYXRlUmVhZG9ubHlNZXRob2QoImNsZWFyIikNCiAgICB9IDogew0KICAgICAgYWRkKHZhbHVlKSB7DQogICAgICAgIGlmICghc2hhbGxvdyAmJiAhaXNTaGFsbG93KHZhbHVlKSAmJiAhaXNSZWFkb25seSh2YWx1ZSkpIHsNCiAgICAgICAgICB2YWx1ZSA9IHRvUmF3KHZhbHVlKTsNCiAgICAgICAgfQ0KICAgICAgICBjb25zdCB0YXJnZXQgPSB0b1Jhdyh0aGlzKTsNCiAgICAgICAgY29uc3QgcHJvdG8gPSBnZXRQcm90byh0YXJnZXQpOw0KICAgICAgICBjb25zdCBoYWRLZXkgPSBwcm90by5oYXMuY2FsbCh0YXJnZXQsIHZhbHVlKTsNCiAgICAgICAgaWYgKCFoYWRLZXkpIHsNCiAgICAgICAgICB0YXJnZXQuYWRkKHZhbHVlKTsNCiAgICAgICAgICB0cmlnZ2VyKHRhcmdldCwgImFkZCIsIHZhbHVlLCB2YWx1ZSk7DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIHRoaXM7DQogICAgICB9LA0KICAgICAgc2V0KGtleSwgdmFsdWUpIHsNCiAgICAgICAgaWYgKCFzaGFsbG93ICYmICFpc1NoYWxsb3codmFsdWUpICYmICFpc1JlYWRvbmx5KHZhbHVlKSkgew0KICAgICAgICAgIHZhbHVlID0gdG9SYXcodmFsdWUpOw0KICAgICAgICB9DQogICAgICAgIGNvbnN0IHRhcmdldCA9IHRvUmF3KHRoaXMpOw0KICAgICAgICBjb25zdCB7IGhhcywgZ2V0IH0gPSBnZXRQcm90byh0YXJnZXQpOw0KICAgICAgICBsZXQgaGFkS2V5ID0gaGFzLmNhbGwodGFyZ2V0LCBrZXkpOw0KICAgICAgICBpZiAoIWhhZEtleSkgew0KICAgICAgICAgIGtleSA9IHRvUmF3KGtleSk7DQogICAgICAgICAgaGFkS2V5ID0gaGFzLmNhbGwodGFyZ2V0LCBrZXkpOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIGNoZWNrSWRlbnRpdHlLZXlzKHRhcmdldCwgaGFzLCBrZXkpOw0KICAgICAgICB9DQogICAgICAgIGNvbnN0IG9sZFZhbHVlID0gZ2V0LmNhbGwodGFyZ2V0LCBrZXkpOw0KICAgICAgICB0YXJnZXQuc2V0KGtleSwgdmFsdWUpOw0KICAgICAgICBpZiAoIWhhZEtleSkgew0KICAgICAgICAgIHRyaWdnZXIodGFyZ2V0LCAiYWRkIiwga2V5LCB2YWx1ZSk7DQogICAgICAgIH0gZWxzZSBpZiAoaGFzQ2hhbmdlZCh2YWx1ZSwgb2xkVmFsdWUpKSB7DQogICAgICAgICAgdHJpZ2dlcih0YXJnZXQsICJzZXQiLCBrZXksIHZhbHVlLCBvbGRWYWx1ZSk7DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIHRoaXM7DQogICAgICB9LA0KICAgICAgZGVsZXRlKGtleSkgew0KICAgICAgICBjb25zdCB0YXJnZXQgPSB0b1Jhdyh0aGlzKTsNCiAgICAgICAgY29uc3QgeyBoYXMsIGdldCB9ID0gZ2V0UHJvdG8odGFyZ2V0KTsNCiAgICAgICAgbGV0IGhhZEtleSA9IGhhcy5jYWxsKHRhcmdldCwga2V5KTsNCiAgICAgICAgaWYgKCFoYWRLZXkpIHsNCiAgICAgICAgICBrZXkgPSB0b1JhdyhrZXkpOw0KICAgICAgICAgIGhhZEtleSA9IGhhcy5jYWxsKHRhcmdldCwga2V5KTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBjaGVja0lkZW50aXR5S2V5cyh0YXJnZXQsIGhhcywga2V5KTsNCiAgICAgICAgfQ0KICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IGdldCA/IGdldC5jYWxsKHRhcmdldCwga2V5KSA6IHZvaWQgMDsNCiAgICAgICAgY29uc3QgcmVzdWx0ID0gdGFyZ2V0LmRlbGV0ZShrZXkpOw0KICAgICAgICBpZiAoaGFkS2V5KSB7DQogICAgICAgICAgdHJpZ2dlcih0YXJnZXQsICJkZWxldGUiLCBrZXksIHZvaWQgMCwgb2xkVmFsdWUpOw0KICAgICAgICB9DQogICAgICAgIHJldHVybiByZXN1bHQ7DQogICAgICB9LA0KICAgICAgY2xlYXIoKSB7DQogICAgICAgIGNvbnN0IHRhcmdldCA9IHRvUmF3KHRoaXMpOw0KICAgICAgICBjb25zdCBoYWRJdGVtcyA9IHRhcmdldC5zaXplICE9PSAwOw0KICAgICAgICBjb25zdCBvbGRUYXJnZXQgPSBpc01hcCh0YXJnZXQpID8gbmV3IE1hcCh0YXJnZXQpIDogbmV3IFNldCh0YXJnZXQpIDsNCiAgICAgICAgY29uc3QgcmVzdWx0ID0gdGFyZ2V0LmNsZWFyKCk7DQogICAgICAgIGlmIChoYWRJdGVtcykgew0KICAgICAgICAgIHRyaWdnZXIoDQogICAgICAgICAgICB0YXJnZXQsDQogICAgICAgICAgICAiY2xlYXIiLA0KICAgICAgICAgICAgdm9pZCAwLA0KICAgICAgICAgICAgdm9pZCAwLA0KICAgICAgICAgICAgb2xkVGFyZ2V0DQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgICByZXR1cm4gcmVzdWx0Ow0KICAgICAgfQ0KICAgIH0NCiAgKTsNCiAgY29uc3QgaXRlcmF0b3JNZXRob2RzID0gWw0KICAgICJrZXlzIiwNCiAgICAidmFsdWVzIiwNCiAgICAiZW50cmllcyIsDQogICAgU3ltYm9sLml0ZXJhdG9yDQogIF07DQogIGl0ZXJhdG9yTWV0aG9kcy5mb3JFYWNoKChtZXRob2QpID0+IHsNCiAgICBpbnN0cnVtZW50YXRpb25zW21ldGhvZF0gPSBjcmVhdGVJdGVyYWJsZU1ldGhvZChtZXRob2QsIHJlYWRvbmx5LCBzaGFsbG93KTsNCiAgfSk7DQogIHJldHVybiBpbnN0cnVtZW50YXRpb25zOw0KfQ0KZnVuY3Rpb24gY3JlYXRlSW5zdHJ1bWVudGF0aW9uR2V0dGVyKGlzUmVhZG9ubHkyLCBzaGFsbG93KSB7DQogIGNvbnN0IGluc3RydW1lbnRhdGlvbnMgPSBjcmVhdGVJbnN0cnVtZW50YXRpb25zKGlzUmVhZG9ubHkyLCBzaGFsbG93KTsNCiAgcmV0dXJuICh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpID0+IHsNCiAgICBpZiAoa2V5ID09PSAiX192X2lzUmVhY3RpdmUiKSB7DQogICAgICByZXR1cm4gIWlzUmVhZG9ubHkyOw0KICAgIH0gZWxzZSBpZiAoa2V5ID09PSAiX192X2lzUmVhZG9ubHkiKSB7DQogICAgICByZXR1cm4gaXNSZWFkb25seTI7DQogICAgfSBlbHNlIGlmIChrZXkgPT09ICJfX3ZfcmF3Iikgew0KICAgICAgcmV0dXJuIHRhcmdldDsNCiAgICB9DQogICAgcmV0dXJuIFJlZmxlY3QuZ2V0KA0KICAgICAgaGFzT3duKGluc3RydW1lbnRhdGlvbnMsIGtleSkgJiYga2V5IGluIHRhcmdldCA/IGluc3RydW1lbnRhdGlvbnMgOiB0YXJnZXQsDQogICAgICBrZXksDQogICAgICByZWNlaXZlcg0KICAgICk7DQogIH07DQp9DQpjb25zdCBtdXRhYmxlQ29sbGVjdGlvbkhhbmRsZXJzID0gew0KICBnZXQ6IC8qIEBfX1BVUkVfXyAqLyBjcmVhdGVJbnN0cnVtZW50YXRpb25HZXR0ZXIoZmFsc2UsIGZhbHNlKQ0KfTsNCmNvbnN0IHNoYWxsb3dDb2xsZWN0aW9uSGFuZGxlcnMgPSB7DQogIGdldDogLyogQF9fUFVSRV9fICovIGNyZWF0ZUluc3RydW1lbnRhdGlvbkdldHRlcihmYWxzZSwgdHJ1ZSkNCn07DQpjb25zdCByZWFkb25seUNvbGxlY3Rpb25IYW5kbGVycyA9IHsNCiAgZ2V0OiAvKiBAX19QVVJFX18gKi8gY3JlYXRlSW5zdHJ1bWVudGF0aW9uR2V0dGVyKHRydWUsIGZhbHNlKQ0KfTsNCmNvbnN0IHNoYWxsb3dSZWFkb25seUNvbGxlY3Rpb25IYW5kbGVycyA9IHsNCiAgZ2V0OiAvKiBAX19QVVJFX18gKi8gY3JlYXRlSW5zdHJ1bWVudGF0aW9uR2V0dGVyKHRydWUsIHRydWUpDQp9Ow0KZnVuY3Rpb24gY2hlY2tJZGVudGl0eUtleXModGFyZ2V0LCBoYXMsIGtleSkgew0KICBjb25zdCByYXdLZXkgPSB0b1JhdyhrZXkpOw0KICBpZiAocmF3S2V5ICE9PSBrZXkgJiYgaGFzLmNhbGwodGFyZ2V0LCByYXdLZXkpKSB7DQogICAgY29uc3QgdHlwZSA9IHRvUmF3VHlwZSh0YXJnZXQpOw0KICAgIHdhcm4kMigNCiAgICAgIGBSZWFjdGl2ZSAke3R5cGV9IGNvbnRhaW5zIGJvdGggdGhlIHJhdyBhbmQgcmVhY3RpdmUgdmVyc2lvbnMgb2YgdGhlIHNhbWUgb2JqZWN0JHt0eXBlID09PSBgTWFwYCA/IGAgYXMga2V5c2AgOiBgYH0sIHdoaWNoIGNhbiBsZWFkIHRvIGluY29uc2lzdGVuY2llcy4gQXZvaWQgZGlmZmVyZW50aWF0aW5nIGJldHdlZW4gdGhlIHJhdyBhbmQgcmVhY3RpdmUgdmVyc2lvbnMgb2YgYW4gb2JqZWN0IGFuZCBvbmx5IHVzZSB0aGUgcmVhY3RpdmUgdmVyc2lvbiBpZiBwb3NzaWJsZS5gDQogICAgKTsNCiAgfQ0KfQ0KDQpjb25zdCByZWFjdGl2ZU1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgV2Vha01hcCgpOw0KY29uc3Qgc2hhbGxvd1JlYWN0aXZlTWFwID0gLyogQF9fUFVSRV9fICovIG5ldyBXZWFrTWFwKCk7DQpjb25zdCByZWFkb25seU1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgV2Vha01hcCgpOw0KY29uc3Qgc2hhbGxvd1JlYWRvbmx5TWFwID0gLyogQF9fUFVSRV9fICovIG5ldyBXZWFrTWFwKCk7DQpmdW5jdGlvbiB0YXJnZXRUeXBlTWFwKHJhd1R5cGUpIHsNCiAgc3dpdGNoIChyYXdUeXBlKSB7DQogICAgY2FzZSAiT2JqZWN0IjoNCiAgICBjYXNlICJBcnJheSI6DQogICAgICByZXR1cm4gMSAvKiBDT01NT04gKi87DQogICAgY2FzZSAiTWFwIjoNCiAgICBjYXNlICJTZXQiOg0KICAgIGNhc2UgIldlYWtNYXAiOg0KICAgIGNhc2UgIldlYWtTZXQiOg0KICAgICAgcmV0dXJuIDIgLyogQ09MTEVDVElPTiAqLzsNCiAgICBkZWZhdWx0Og0KICAgICAgcmV0dXJuIDAgLyogSU5WQUxJRCAqLzsNCiAgfQ0KfQ0KZnVuY3Rpb24gZ2V0VGFyZ2V0VHlwZSh2YWx1ZSkgew0KICByZXR1cm4gdmFsdWVbIl9fdl9za2lwIl0gfHwgIU9iamVjdC5pc0V4dGVuc2libGUodmFsdWUpID8gMCAvKiBJTlZBTElEICovIDogdGFyZ2V0VHlwZU1hcCh0b1Jhd1R5cGUodmFsdWUpKTsNCn0NCmZ1bmN0aW9uIHJlYWN0aXZlKHRhcmdldCkgew0KICBpZiAoaXNSZWFkb25seSh0YXJnZXQpKSB7DQogICAgcmV0dXJuIHRhcmdldDsNCiAgfQ0KICByZXR1cm4gY3JlYXRlUmVhY3RpdmVPYmplY3QoDQogICAgdGFyZ2V0LA0KICAgIGZhbHNlLA0KICAgIG11dGFibGVIYW5kbGVycywNCiAgICBtdXRhYmxlQ29sbGVjdGlvbkhhbmRsZXJzLA0KICAgIHJlYWN0aXZlTWFwDQogICk7DQp9DQpmdW5jdGlvbiBzaGFsbG93UmVhY3RpdmUodGFyZ2V0KSB7DQogIHJldHVybiBjcmVhdGVSZWFjdGl2ZU9iamVjdCgNCiAgICB0YXJnZXQsDQogICAgZmFsc2UsDQogICAgc2hhbGxvd1JlYWN0aXZlSGFuZGxlcnMsDQogICAgc2hhbGxvd0NvbGxlY3Rpb25IYW5kbGVycywNCiAgICBzaGFsbG93UmVhY3RpdmVNYXANCiAgKTsNCn0NCmZ1bmN0aW9uIHJlYWRvbmx5KHRhcmdldCkgew0KICByZXR1cm4gY3JlYXRlUmVhY3RpdmVPYmplY3QoDQogICAgdGFyZ2V0LA0KICAgIHRydWUsDQogICAgcmVhZG9ubHlIYW5kbGVycywNCiAgICByZWFkb25seUNvbGxlY3Rpb25IYW5kbGVycywNCiAgICByZWFkb25seU1hcA0KICApOw0KfQ0KZnVuY3Rpb24gc2hhbGxvd1JlYWRvbmx5KHRhcmdldCkgew0KICByZXR1cm4gY3JlYXRlUmVhY3RpdmVPYmplY3QoDQogICAgdGFyZ2V0LA0KICAgIHRydWUsDQogICAgc2hhbGxvd1JlYWRvbmx5SGFuZGxlcnMsDQogICAgc2hhbGxvd1JlYWRvbmx5Q29sbGVjdGlvbkhhbmRsZXJzLA0KICAgIHNoYWxsb3dSZWFkb25seU1hcA0KICApOw0KfQ0KZnVuY3Rpb24gY3JlYXRlUmVhY3RpdmVPYmplY3QodGFyZ2V0LCBpc1JlYWRvbmx5MiwgYmFzZUhhbmRsZXJzLCBjb2xsZWN0aW9uSGFuZGxlcnMsIHByb3h5TWFwKSB7DQogIGlmICghaXNPYmplY3QodGFyZ2V0KSkgew0KICAgIHsNCiAgICAgIHdhcm4kMigNCiAgICAgICAgYHZhbHVlIGNhbm5vdCBiZSBtYWRlICR7aXNSZWFkb25seTIgPyAicmVhZG9ubHkiIDogInJlYWN0aXZlIn06ICR7U3RyaW5nKA0KICAgICAgICAgIHRhcmdldA0KICAgICAgICApfWANCiAgICAgICk7DQogICAgfQ0KICAgIHJldHVybiB0YXJnZXQ7DQogIH0NCiAgaWYgKHRhcmdldFsiX192X3JhdyJdICYmICEoaXNSZWFkb25seTIgJiYgdGFyZ2V0WyJfX3ZfaXNSZWFjdGl2ZSJdKSkgew0KICAgIHJldHVybiB0YXJnZXQ7DQogIH0NCiAgY29uc3QgdGFyZ2V0VHlwZSA9IGdldFRhcmdldFR5cGUodGFyZ2V0KTsNCiAgaWYgKHRhcmdldFR5cGUgPT09IDAgLyogSU5WQUxJRCAqLykgew0KICAgIHJldHVybiB0YXJnZXQ7DQogIH0NCiAgY29uc3QgZXhpc3RpbmdQcm94eSA9IHByb3h5TWFwLmdldCh0YXJnZXQpOw0KICBpZiAoZXhpc3RpbmdQcm94eSkgew0KICAgIHJldHVybiBleGlzdGluZ1Byb3h5Ow0KICB9DQogIGNvbnN0IHByb3h5ID0gbmV3IFByb3h5KA0KICAgIHRhcmdldCwNCiAgICB0YXJnZXRUeXBlID09PSAyIC8qIENPTExFQ1RJT04gKi8gPyBjb2xsZWN0aW9uSGFuZGxlcnMgOiBiYXNlSGFuZGxlcnMNCiAgKTsNCiAgcHJveHlNYXAuc2V0KHRhcmdldCwgcHJveHkpOw0KICByZXR1cm4gcHJveHk7DQp9DQpmdW5jdGlvbiBpc1JlYWN0aXZlKHZhbHVlKSB7DQogIGlmIChpc1JlYWRvbmx5KHZhbHVlKSkgew0KICAgIHJldHVybiBpc1JlYWN0aXZlKHZhbHVlWyJfX3ZfcmF3Il0pOw0KICB9DQogIHJldHVybiAhISh2YWx1ZSAmJiB2YWx1ZVsiX192X2lzUmVhY3RpdmUiXSk7DQp9DQpmdW5jdGlvbiBpc1JlYWRvbmx5KHZhbHVlKSB7DQogIHJldHVybiAhISh2YWx1ZSAmJiB2YWx1ZVsiX192X2lzUmVhZG9ubHkiXSk7DQp9DQpmdW5jdGlvbiBpc1NoYWxsb3codmFsdWUpIHsNCiAgcmV0dXJuICEhKHZhbHVlICYmIHZhbHVlWyJfX3ZfaXNTaGFsbG93Il0pOw0KfQ0KZnVuY3Rpb24gaXNQcm94eSh2YWx1ZSkgew0KICByZXR1cm4gdmFsdWUgPyAhIXZhbHVlWyJfX3ZfcmF3Il0gOiBmYWxzZTsNCn0NCmZ1bmN0aW9uIHRvUmF3KG9ic2VydmVkKSB7DQogIGNvbnN0IHJhdyA9IG9ic2VydmVkICYmIG9ic2VydmVkWyJfX3ZfcmF3Il07DQogIHJldHVybiByYXcgPyB0b1JhdyhyYXcpIDogb2JzZXJ2ZWQ7DQp9DQpmdW5jdGlvbiBtYXJrUmF3KHZhbHVlKSB7DQogIGlmICghaGFzT3duKHZhbHVlLCAiX192X3NraXAiKSAmJiBPYmplY3QuaXNFeHRlbnNpYmxlKHZhbHVlKSkgew0KICAgIGRlZih2YWx1ZSwgIl9fdl9za2lwIiwgdHJ1ZSk7DQogIH0NCiAgcmV0dXJuIHZhbHVlOw0KfQ0KY29uc3QgdG9SZWFjdGl2ZSA9ICh2YWx1ZSkgPT4gaXNPYmplY3QodmFsdWUpID8gcmVhY3RpdmUodmFsdWUpIDogdmFsdWU7DQpjb25zdCB0b1JlYWRvbmx5ID0gKHZhbHVlKSA9PiBpc09iamVjdCh2YWx1ZSkgPyByZWFkb25seSh2YWx1ZSkgOiB2YWx1ZTsNCg0KZnVuY3Rpb24gaXNSZWYocikgew0KICByZXR1cm4gciA/IHJbIl9fdl9pc1JlZiJdID09PSB0cnVlIDogZmFsc2U7DQp9DQpmdW5jdGlvbiB1bnJlZihyZWYyKSB7DQogIHJldHVybiBpc1JlZihyZWYyKSA/IHJlZjIudmFsdWUgOiByZWYyOw0KfQ0KY29uc3Qgc2hhbGxvd1Vud3JhcEhhbmRsZXJzID0gew0KICBnZXQ6ICh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpID0+IGtleSA9PT0gIl9fdl9yYXciID8gdGFyZ2V0IDogdW5yZWYoUmVmbGVjdC5nZXQodGFyZ2V0LCBrZXksIHJlY2VpdmVyKSksDQogIHNldDogKHRhcmdldCwga2V5LCB2YWx1ZSwgcmVjZWl2ZXIpID0+IHsNCiAgICBjb25zdCBvbGRWYWx1ZSA9IHRhcmdldFtrZXldOw0KICAgIGlmIChpc1JlZihvbGRWYWx1ZSkgJiYgIWlzUmVmKHZhbHVlKSkgew0KICAgICAgb2xkVmFsdWUudmFsdWUgPSB2YWx1ZTsNCiAgICAgIHJldHVybiB0cnVlOw0KICAgIH0gZWxzZSB7DQogICAgICByZXR1cm4gUmVmbGVjdC5zZXQodGFyZ2V0LCBrZXksIHZhbHVlLCByZWNlaXZlcik7DQogICAgfQ0KICB9DQp9Ow0KZnVuY3Rpb24gcHJveHlSZWZzKG9iamVjdFdpdGhSZWZzKSB7DQogIHJldHVybiBpc1JlYWN0aXZlKG9iamVjdFdpdGhSZWZzKSA/IG9iamVjdFdpdGhSZWZzIDogbmV3IFByb3h5KG9iamVjdFdpdGhSZWZzLCBzaGFsbG93VW53cmFwSGFuZGxlcnMpOw0KfQ0KDQpjbGFzcyBDb21wdXRlZFJlZkltcGwgew0KICBjb25zdHJ1Y3Rvcihmbiwgc2V0dGVyLCBpc1NTUikgew0KICAgIHRoaXMuZm4gPSBmbjsNCiAgICB0aGlzLnNldHRlciA9IHNldHRlcjsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLl92YWx1ZSA9IHZvaWQgMDsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLmRlcCA9IG5ldyBEZXAodGhpcyk7DQogICAgLyoqDQogICAgICogQGludGVybmFsDQogICAgICovDQogICAgdGhpcy5fX3ZfaXNSZWYgPSB0cnVlOw0KICAgIC8vIFRPRE8gaXNvbGF0ZWREZWNsYXJhdGlvbnMgIl9fdl9pc1JlYWRvbmx5Ig0KICAgIC8vIEEgY29tcHV0ZWQgaXMgYWxzbyBhIHN1YnNjcmliZXIgdGhhdCB0cmFja3Mgb3RoZXIgZGVwcw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuZGVwcyA9IHZvaWQgMDsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLmRlcHNUYWlsID0gdm9pZCAwOw0KICAgIC8qKg0KICAgICAqIEBpbnRlcm5hbA0KICAgICAqLw0KICAgIHRoaXMuZmxhZ3MgPSAxNjsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLmdsb2JhbFZlcnNpb24gPSBnbG9iYWxWZXJzaW9uIC0gMTsNCiAgICAvKioNCiAgICAgKiBAaW50ZXJuYWwNCiAgICAgKi8NCiAgICB0aGlzLm5leHQgPSB2b2lkIDA7DQogICAgLy8gZm9yIGJhY2t3YXJkcyBjb21wYXQNCiAgICB0aGlzLmVmZmVjdCA9IHRoaXM7DQogICAgdGhpc1siX192X2lzUmVhZG9ubHkiXSA9ICFzZXR0ZXI7DQogICAgdGhpcy5pc1NTUiA9IGlzU1NSOw0KICB9DQogIC8qKg0KICAgKiBAaW50ZXJuYWwNCiAgICovDQogIG5vdGlmeSgpIHsNCiAgICB0aGlzLmZsYWdzIHw9IDE2Ow0KICAgIGlmICghKHRoaXMuZmxhZ3MgJiA4KSAmJiAvLyBhdm9pZCBpbmZpbml0ZSBzZWxmIHJlY3Vyc2lvbg0KICAgIGFjdGl2ZVN1YiAhPT0gdGhpcykgew0KICAgICAgYmF0Y2godGhpcywgdHJ1ZSk7DQogICAgICByZXR1cm4gdHJ1ZTsNCiAgICB9DQogIH0NCiAgZ2V0IHZhbHVlKCkgew0KICAgIGNvbnN0IGxpbmsgPSB0aGlzLmRlcC50cmFjayh7DQogICAgICB0YXJnZXQ6IHRoaXMsDQogICAgICB0eXBlOiAiZ2V0IiwNCiAgICAgIGtleTogInZhbHVlIg0KICAgIH0pIDsNCiAgICByZWZyZXNoQ29tcHV0ZWQodGhpcyk7DQogICAgaWYgKGxpbmspIHsNCiAgICAgIGxpbmsudmVyc2lvbiA9IHRoaXMuZGVwLnZlcnNpb247DQogICAgfQ0KICAgIHJldHVybiB0aGlzLl92YWx1ZTsNCiAgfQ0KICBzZXQgdmFsdWUobmV3VmFsdWUpIHsNCiAgICBpZiAodGhpcy5zZXR0ZXIpIHsNCiAgICAgIHRoaXMuc2V0dGVyKG5ld1ZhbHVlKTsNCiAgICB9IGVsc2Ugew0KICAgICAgd2FybiQyKCJXcml0ZSBvcGVyYXRpb24gZmFpbGVkOiBjb21wdXRlZCB2YWx1ZSBpcyByZWFkb25seSIpOw0KICAgIH0NCiAgfQ0KfQ0KZnVuY3Rpb24gY29tcHV0ZWQkMShnZXR0ZXJPck9wdGlvbnMsIGRlYnVnT3B0aW9ucywgaXNTU1IgPSBmYWxzZSkgew0KICBsZXQgZ2V0dGVyOw0KICBsZXQgc2V0dGVyOw0KICBpZiAoaXNGdW5jdGlvbihnZXR0ZXJPck9wdGlvbnMpKSB7DQogICAgZ2V0dGVyID0gZ2V0dGVyT3JPcHRpb25zOw0KICB9IGVsc2Ugew0KICAgIGdldHRlciA9IGdldHRlck9yT3B0aW9ucy5nZXQ7DQogICAgc2V0dGVyID0gZ2V0dGVyT3JPcHRpb25zLnNldDsNCiAgfQ0KICBjb25zdCBjUmVmID0gbmV3IENvbXB1dGVkUmVmSW1wbChnZXR0ZXIsIHNldHRlciwgaXNTU1IpOw0KICByZXR1cm4gY1JlZjsNCn0NCg0KY29uc3QgSU5JVElBTF9XQVRDSEVSX1ZBTFVFID0ge307DQpjb25zdCBjbGVhbnVwTWFwID0gLyogQF9fUFVSRV9fICovIG5ldyBXZWFrTWFwKCk7DQpsZXQgYWN0aXZlV2F0Y2hlciA9IHZvaWQgMDsNCmZ1bmN0aW9uIG9uV2F0Y2hlckNsZWFudXAoY2xlYW51cEZuLCBmYWlsU2lsZW50bHkgPSBmYWxzZSwgb3duZXIgPSBhY3RpdmVXYXRjaGVyKSB7DQogIGlmIChvd25lcikgew0KICAgIGxldCBjbGVhbnVwcyA9IGNsZWFudXBNYXAuZ2V0KG93bmVyKTsNCiAgICBpZiAoIWNsZWFudXBzKSBjbGVhbnVwTWFwLnNldChvd25lciwgY2xlYW51cHMgPSBbXSk7DQogICAgY2xlYW51cHMucHVzaChjbGVhbnVwRm4pOw0KICB9IGVsc2UgaWYgKCFmYWlsU2lsZW50bHkpIHsNCiAgICB3YXJuJDIoDQogICAgICBgb25XYXRjaGVyQ2xlYW51cCgpIHdhcyBjYWxsZWQgd2hlbiB0aGVyZSB3YXMgbm8gYWN0aXZlIHdhdGNoZXIgdG8gYXNzb2NpYXRlIHdpdGguYA0KICAgICk7DQogIH0NCn0NCmZ1bmN0aW9uIHdhdGNoJDEoc291cmNlLCBjYiwgb3B0aW9ucyA9IEVNUFRZX09CSikgew0KICBjb25zdCB7IGltbWVkaWF0ZSwgZGVlcCwgb25jZSwgc2NoZWR1bGVyLCBhdWdtZW50Sm9iLCBjYWxsIH0gPSBvcHRpb25zOw0KICBjb25zdCB3YXJuSW52YWxpZFNvdXJjZSA9IChzKSA9PiB7DQogICAgKG9wdGlvbnMub25XYXJuIHx8IHdhcm4kMikoDQogICAgICBgSW52YWxpZCB3YXRjaCBzb3VyY2U6IGAsDQogICAgICBzLA0KICAgICAgYEEgd2F0Y2ggc291cmNlIGNhbiBvbmx5IGJlIGEgZ2V0dGVyL2VmZmVjdCBmdW5jdGlvbiwgYSByZWYsIGEgcmVhY3RpdmUgb2JqZWN0LCBvciBhbiBhcnJheSBvZiB0aGVzZSB0eXBlcy5gDQogICAgKTsNCiAgfTsNCiAgY29uc3QgcmVhY3RpdmVHZXR0ZXIgPSAoc291cmNlMikgPT4gew0KICAgIGlmIChkZWVwKSByZXR1cm4gc291cmNlMjsNCiAgICBpZiAoaXNTaGFsbG93KHNvdXJjZTIpIHx8IGRlZXAgPT09IGZhbHNlIHx8IGRlZXAgPT09IDApDQogICAgICByZXR1cm4gdHJhdmVyc2Uoc291cmNlMiwgMSk7DQogICAgcmV0dXJuIHRyYXZlcnNlKHNvdXJjZTIpOw0KICB9Ow0KICBsZXQgZWZmZWN0Ow0KICBsZXQgZ2V0dGVyOw0KICBsZXQgY2xlYW51cDsNCiAgbGV0IGJvdW5kQ2xlYW51cDsNCiAgbGV0IGZvcmNlVHJpZ2dlciA9IGZhbHNlOw0KICBsZXQgaXNNdWx0aVNvdXJjZSA9IGZhbHNlOw0KICBpZiAoaXNSZWYoc291cmNlKSkgew0KICAgIGdldHRlciA9ICgpID0+IHNvdXJjZS52YWx1ZTsNCiAgICBmb3JjZVRyaWdnZXIgPSBpc1NoYWxsb3coc291cmNlKTsNCiAgfSBlbHNlIGlmIChpc1JlYWN0aXZlKHNvdXJjZSkpIHsNCiAgICBnZXR0ZXIgPSAoKSA9PiByZWFjdGl2ZUdldHRlcihzb3VyY2UpOw0KICAgIGZvcmNlVHJpZ2dlciA9IHRydWU7DQogIH0gZWxzZSBpZiAoaXNBcnJheShzb3VyY2UpKSB7DQogICAgaXNNdWx0aVNvdXJjZSA9IHRydWU7DQogICAgZm9yY2VUcmlnZ2VyID0gc291cmNlLnNvbWUoKHMpID0+IGlzUmVhY3RpdmUocykgfHwgaXNTaGFsbG93KHMpKTsNCiAgICBnZXR0ZXIgPSAoKSA9PiBzb3VyY2UubWFwKChzKSA9PiB7DQogICAgICBpZiAoaXNSZWYocykpIHsNCiAgICAgICAgcmV0dXJuIHMudmFsdWU7DQogICAgICB9IGVsc2UgaWYgKGlzUmVhY3RpdmUocykpIHsNCiAgICAgICAgcmV0dXJuIHJlYWN0aXZlR2V0dGVyKHMpOw0KICAgICAgfSBlbHNlIGlmIChpc0Z1bmN0aW9uKHMpKSB7DQogICAgICAgIHJldHVybiBjYWxsID8gY2FsbChzLCAyKSA6IHMoKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHdhcm5JbnZhbGlkU291cmNlKHMpOw0KICAgICAgfQ0KICAgIH0pOw0KICB9IGVsc2UgaWYgKGlzRnVuY3Rpb24oc291cmNlKSkgew0KICAgIGlmIChjYikgew0KICAgICAgZ2V0dGVyID0gY2FsbCA/ICgpID0+IGNhbGwoc291cmNlLCAyKSA6IHNvdXJjZTsNCiAgICB9IGVsc2Ugew0KICAgICAgZ2V0dGVyID0gKCkgPT4gew0KICAgICAgICBpZiAoY2xlYW51cCkgew0KICAgICAgICAgIHBhdXNlVHJhY2tpbmcoKTsNCiAgICAgICAgICB0cnkgew0KICAgICAgICAgICAgY2xlYW51cCgpOw0KICAgICAgICAgIH0gZmluYWxseSB7DQogICAgICAgICAgICByZXNldFRyYWNraW5nKCk7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGNvbnN0IGN1cnJlbnRFZmZlY3QgPSBhY3RpdmVXYXRjaGVyOw0KICAgICAgICBhY3RpdmVXYXRjaGVyID0gZWZmZWN0Ow0KICAgICAgICB0cnkgew0KICAgICAgICAgIHJldHVybiBjYWxsID8gY2FsbChzb3VyY2UsIDMsIFtib3VuZENsZWFudXBdKSA6IHNvdXJjZShib3VuZENsZWFudXApOw0KICAgICAgICB9IGZpbmFsbHkgew0KICAgICAgICAgIGFjdGl2ZVdhdGNoZXIgPSBjdXJyZW50RWZmZWN0Ow0KICAgICAgICB9DQogICAgICB9Ow0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICBnZXR0ZXIgPSBOT09QOw0KICAgIHdhcm5JbnZhbGlkU291cmNlKHNvdXJjZSk7DQogIH0NCiAgaWYgKGNiICYmIGRlZXApIHsNCiAgICBjb25zdCBiYXNlR2V0dGVyID0gZ2V0dGVyOw0KICAgIGNvbnN0IGRlcHRoID0gZGVlcCA9PT0gdHJ1ZSA/IEluZmluaXR5IDogZGVlcDsNCiAgICBnZXR0ZXIgPSAoKSA9PiB0cmF2ZXJzZShiYXNlR2V0dGVyKCksIGRlcHRoKTsNCiAgfQ0KICBjb25zdCBzY29wZSA9IGdldEN1cnJlbnRTY29wZSgpOw0KICBjb25zdCB3YXRjaEhhbmRsZSA9ICgpID0+IHsNCiAgICBlZmZlY3Quc3RvcCgpOw0KICAgIGlmIChzY29wZSAmJiBzY29wZS5hY3RpdmUpIHsNCiAgICAgIHJlbW92ZShzY29wZS5lZmZlY3RzLCBlZmZlY3QpOw0KICAgIH0NCiAgfTsNCiAgaWYgKG9uY2UgJiYgY2IpIHsNCiAgICBjb25zdCBfY2IgPSBjYjsNCiAgICBjYiA9ICguLi5hcmdzKSA9PiB7DQogICAgICBfY2IoLi4uYXJncyk7DQogICAgICB3YXRjaEhhbmRsZSgpOw0KICAgIH07DQogIH0NCiAgbGV0IG9sZFZhbHVlID0gaXNNdWx0aVNvdXJjZSA/IG5ldyBBcnJheShzb3VyY2UubGVuZ3RoKS5maWxsKElOSVRJQUxfV0FUQ0hFUl9WQUxVRSkgOiBJTklUSUFMX1dBVENIRVJfVkFMVUU7DQogIGNvbnN0IGpvYiA9IChpbW1lZGlhdGVGaXJzdFJ1bikgPT4gew0KICAgIGlmICghKGVmZmVjdC5mbGFncyAmIDEpIHx8ICFlZmZlY3QuZGlydHkgJiYgIWltbWVkaWF0ZUZpcnN0UnVuKSB7DQogICAgICByZXR1cm47DQogICAgfQ0KICAgIGlmIChjYikgew0KICAgICAgY29uc3QgbmV3VmFsdWUgPSBlZmZlY3QucnVuKCk7DQogICAgICBpZiAoZGVlcCB8fCBmb3JjZVRyaWdnZXIgfHwgKGlzTXVsdGlTb3VyY2UgPyBuZXdWYWx1ZS5zb21lKCh2LCBpKSA9PiBoYXNDaGFuZ2VkKHYsIG9sZFZhbHVlW2ldKSkgOiBoYXNDaGFuZ2VkKG5ld1ZhbHVlLCBvbGRWYWx1ZSkpKSB7DQogICAgICAgIGlmIChjbGVhbnVwKSB7DQogICAgICAgICAgY2xlYW51cCgpOw0KICAgICAgICB9DQogICAgICAgIGNvbnN0IGN1cnJlbnRXYXRjaGVyID0gYWN0aXZlV2F0Y2hlcjsNCiAgICAgICAgYWN0aXZlV2F0Y2hlciA9IGVmZmVjdDsNCiAgICAgICAgdHJ5IHsNCiAgICAgICAgICBjb25zdCBhcmdzID0gWw0KICAgICAgICAgICAgbmV3VmFsdWUsDQogICAgICAgICAgICAvLyBwYXNzIHVuZGVmaW5lZCBhcyB0aGUgb2xkIHZhbHVlIHdoZW4gaXQncyBjaGFuZ2VkIGZvciB0aGUgZmlyc3QgdGltZQ0KICAgICAgICAgICAgb2xkVmFsdWUgPT09IElOSVRJQUxfV0FUQ0hFUl9WQUxVRSA/IHZvaWQgMCA6IGlzTXVsdGlTb3VyY2UgJiYgb2xkVmFsdWVbMF0gPT09IElOSVRJQUxfV0FUQ0hFUl9WQUxVRSA/IFtdIDogb2xkVmFsdWUsDQogICAgICAgICAgICBib3VuZENsZWFudXANCiAgICAgICAgICBdOw0KICAgICAgICAgIG9sZFZhbHVlID0gbmV3VmFsdWU7DQogICAgICAgICAgY2FsbCA/IGNhbGwoY2IsIDMsIGFyZ3MpIDogKA0KICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvcg0KICAgICAgICAgICAgY2IoLi4uYXJncykNCiAgICAgICAgICApOw0KICAgICAgICB9IGZpbmFsbHkgew0KICAgICAgICAgIGFjdGl2ZVdhdGNoZXIgPSBjdXJyZW50V2F0Y2hlcjsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0gZWxzZSB7DQogICAgICBlZmZlY3QucnVuKCk7DQogICAgfQ0KICB9Ow0KICBpZiAoYXVnbWVudEpvYikgew0KICAgIGF1Z21lbnRKb2Ioam9iKTsNCiAgfQ0KICBlZmZlY3QgPSBuZXcgUmVhY3RpdmVFZmZlY3QoZ2V0dGVyKTsNCiAgZWZmZWN0LnNjaGVkdWxlciA9IHNjaGVkdWxlciA/ICgpID0+IHNjaGVkdWxlcihqb2IsIGZhbHNlKSA6IGpvYjsNCiAgYm91bmRDbGVhbnVwID0gKGZuKSA9PiBvbldhdGNoZXJDbGVhbnVwKGZuLCBmYWxzZSwgZWZmZWN0KTsNCiAgY2xlYW51cCA9IGVmZmVjdC5vblN0b3AgPSAoKSA9PiB7DQogICAgY29uc3QgY2xlYW51cHMgPSBjbGVhbnVwTWFwLmdldChlZmZlY3QpOw0KICAgIGlmIChjbGVhbnVwcykgew0KICAgICAgaWYgKGNhbGwpIHsNCiAgICAgICAgY2FsbChjbGVhbnVwcywgNCk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBmb3IgKGNvbnN0IGNsZWFudXAyIG9mIGNsZWFudXBzKSBjbGVhbnVwMigpOw0KICAgICAgfQ0KICAgICAgY2xlYW51cE1hcC5kZWxldGUoZWZmZWN0KTsNCiAgICB9DQogIH07DQogIHsNCiAgICBlZmZlY3Qub25UcmFjayA9IG9wdGlvbnMub25UcmFjazsNCiAgICBlZmZlY3Qub25UcmlnZ2VyID0gb3B0aW9ucy5vblRyaWdnZXI7DQogIH0NCiAgaWYgKGNiKSB7DQogICAgaWYgKGltbWVkaWF0ZSkgew0KICAgICAgam9iKHRydWUpOw0KICAgIH0gZWxzZSB7DQogICAgICBvbGRWYWx1ZSA9IGVmZmVjdC5ydW4oKTsNCiAgICB9DQogIH0gZWxzZSBpZiAoc2NoZWR1bGVyKSB7DQogICAgc2NoZWR1bGVyKGpvYi5iaW5kKG51bGwsIHRydWUpLCB0cnVlKTsNCiAgfSBlbHNlIHsNCiAgICBlZmZlY3QucnVuKCk7DQogIH0NCiAgd2F0Y2hIYW5kbGUucGF1c2UgPSBlZmZlY3QucGF1c2UuYmluZChlZmZlY3QpOw0KICB3YXRjaEhhbmRsZS5yZXN1bWUgPSBlZmZlY3QucmVzdW1lLmJpbmQoZWZmZWN0KTsNCiAgd2F0Y2hIYW5kbGUuc3RvcCA9IHdhdGNoSGFuZGxlOw0KICByZXR1cm4gd2F0Y2hIYW5kbGU7DQp9DQpmdW5jdGlvbiB0cmF2ZXJzZSh2YWx1ZSwgZGVwdGggPSBJbmZpbml0eSwgc2Vlbikgew0KICBpZiAoZGVwdGggPD0gMCB8fCAhaXNPYmplY3QodmFsdWUpIHx8IHZhbHVlWyJfX3Zfc2tpcCJdKSB7DQogICAgcmV0dXJuIHZhbHVlOw0KICB9DQogIHNlZW4gPSBzZWVuIHx8IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KCk7DQogIGlmIChzZWVuLmhhcyh2YWx1ZSkpIHsNCiAgICByZXR1cm4gdmFsdWU7DQogIH0NCiAgc2Vlbi5hZGQodmFsdWUpOw0KICBkZXB0aC0tOw0KICBpZiAoaXNSZWYodmFsdWUpKSB7DQogICAgdHJhdmVyc2UodmFsdWUudmFsdWUsIGRlcHRoLCBzZWVuKTsNCiAgfSBlbHNlIGlmIChpc0FycmF5KHZhbHVlKSkgew0KICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspIHsNCiAgICAgIHRyYXZlcnNlKHZhbHVlW2ldLCBkZXB0aCwgc2Vlbik7DQogICAgfQ0KICB9IGVsc2UgaWYgKGlzU2V0KHZhbHVlKSB8fCBpc01hcCh2YWx1ZSkpIHsNCiAgICB2YWx1ZS5mb3JFYWNoKCh2KSA9PiB7DQogICAgICB0cmF2ZXJzZSh2LCBkZXB0aCwgc2Vlbik7DQogICAgfSk7DQogIH0gZWxzZSBpZiAoaXNQbGFpbk9iamVjdCh2YWx1ZSkpIHsNCiAgICBmb3IgKGNvbnN0IGtleSBpbiB2YWx1ZSkgew0KICAgICAgdHJhdmVyc2UodmFsdWVba2V5XSwgZGVwdGgsIHNlZW4pOw0KICAgIH0NCiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHZhbHVlKSkgew0KICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbCh2YWx1ZSwga2V5KSkgew0KICAgICAgICB0cmF2ZXJzZSh2YWx1ZVtrZXldLCBkZXB0aCwgc2Vlbik7DQogICAgICB9DQogICAgfQ0KICB9DQogIHJldHVybiB2YWx1ZTsNCn0NCg0KY29uc3Qgc3RhY2sgPSBbXTsNCmZ1bmN0aW9uIHB1c2hXYXJuaW5nQ29udGV4dCQxKHZub2RlKSB7DQogIHN0YWNrLnB1c2godm5vZGUpOw0KfQ0KZnVuY3Rpb24gcG9wV2FybmluZ0NvbnRleHQkMSgpIHsNCiAgc3RhY2sucG9wKCk7DQp9DQpsZXQgaXNXYXJuaW5nID0gZmFsc2U7DQpmdW5jdGlvbiB3YXJuJDEobXNnLCAuLi5hcmdzKSB7DQogIGlmIChpc1dhcm5pbmcpIHJldHVybjsNCiAgaXNXYXJuaW5nID0gdHJ1ZTsNCiAgcGF1c2VUcmFja2luZygpOw0KICBjb25zdCBpbnN0YW5jZSA9IHN0YWNrLmxlbmd0aCA/IHN0YWNrW3N0YWNrLmxlbmd0aCAtIDFdLmNvbXBvbmVudCA6IG51bGw7DQogIGNvbnN0IGFwcFdhcm5IYW5kbGVyID0gaW5zdGFuY2UgJiYgaW5zdGFuY2UuYXBwQ29udGV4dC5jb25maWcud2FybkhhbmRsZXI7DQogIGNvbnN0IHRyYWNlID0gZ2V0Q29tcG9uZW50VHJhY2UoKTsNCiAgaWYgKGFwcFdhcm5IYW5kbGVyKSB7DQogICAgY2FsbFdpdGhFcnJvckhhbmRsaW5nKA0KICAgICAgYXBwV2FybkhhbmRsZXIsDQogICAgICBpbnN0YW5jZSwNCiAgICAgIDExLA0KICAgICAgWw0KICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXgNCiAgICAgICAgbXNnICsgYXJncy5tYXAoKGEpID0+IHsNCiAgICAgICAgICB2YXIgX2EsIF9iOw0KICAgICAgICAgIHJldHVybiAoX2IgPSAoX2EgPSBhLnRvU3RyaW5nKSA9PSBudWxsID8gdm9pZCAwIDogX2EuY2FsbChhKSkgIT0gbnVsbCA/IF9iIDogSlNPTi5zdHJpbmdpZnkoYSk7DQogICAgICAgIH0pLmpvaW4oIiIpLA0KICAgICAgICBpbnN0YW5jZSAmJiBpbnN0YW5jZS5wcm94eSwNCiAgICAgICAgdHJhY2UubWFwKA0KICAgICAgICAgICh7IHZub2RlIH0pID0+IGBhdCA8JHtmb3JtYXRDb21wb25lbnROYW1lKGluc3RhbmNlLCB2bm9kZS50eXBlKX0+YA0KICAgICAgICApLmpvaW4oIlxuIiksDQogICAgICAgIHRyYWNlDQogICAgICBdDQogICAgKTsNCiAgfSBlbHNlIHsNCiAgICBjb25zdCB3YXJuQXJncyA9IFtgW1Z1ZSB3YXJuXTogJHttc2d9YCwgLi4uYXJnc107DQogICAgaWYgKHRyYWNlLmxlbmd0aCAmJiAvLyBhdm9pZCBzcGFtbWluZyBjb25zb2xlIGR1cmluZyB0ZXN0cw0KICAgIHRydWUpIHsNCiAgICAgIHdhcm5BcmdzLnB1c2goYA0KYCwgLi4uZm9ybWF0VHJhY2UodHJhY2UpKTsNCiAgICB9DQogICAgY29uc29sZS53YXJuKC4uLndhcm5BcmdzKTsNCiAgfQ0KICByZXNldFRyYWNraW5nKCk7DQogIGlzV2FybmluZyA9IGZhbHNlOw0KfQ0KZnVuY3Rpb24gZ2V0Q29tcG9uZW50VHJhY2UoKSB7DQogIGxldCBjdXJyZW50Vk5vZGUgPSBzdGFja1tzdGFjay5sZW5ndGggLSAxXTsNCiAgaWYgKCFjdXJyZW50Vk5vZGUpIHsNCiAgICByZXR1cm4gW107DQogIH0NCiAgY29uc3Qgbm9ybWFsaXplZFN0YWNrID0gW107DQogIHdoaWxlIChjdXJyZW50Vk5vZGUpIHsNCiAgICBjb25zdCBsYXN0ID0gbm9ybWFsaXplZFN0YWNrWzBdOw0KICAgIGlmIChsYXN0ICYmIGxhc3Qudm5vZGUgPT09IGN1cnJlbnRWTm9kZSkgew0KICAgICAgbGFzdC5yZWN1cnNlQ291bnQrKzsNCiAgICB9IGVsc2Ugew0KICAgICAgbm9ybWFsaXplZFN0YWNrLnB1c2goew0KICAgICAgICB2bm9kZTogY3VycmVudFZOb2RlLA0KICAgICAgICByZWN1cnNlQ291bnQ6IDANCiAgICAgIH0pOw0KICAgIH0NCiAgICBjb25zdCBwYXJlbnRJbnN0YW5jZSA9IGN1cnJlbnRWTm9kZS5jb21wb25lbnQgJiYgY3VycmVudFZOb2RlLmNvbXBvbmVudC5wYXJlbnQ7DQogICAgY3VycmVudFZOb2RlID0gcGFyZW50SW5zdGFuY2UgJiYgcGFyZW50SW5zdGFuY2Uudm5vZGU7DQogIH0NCiAgcmV0dXJuIG5vcm1hbGl6ZWRTdGFjazsNCn0NCmZ1bmN0aW9uIGZvcm1hdFRyYWNlKHRyYWNlKSB7DQogIGNvbnN0IGxvZ3MgPSBbXTsNCiAgdHJhY2UuZm9yRWFjaCgoZW50cnksIGkpID0+IHsNCiAgICBsb2dzLnB1c2goLi4uaSA9PT0gMCA/IFtdIDogW2ANCmBdLCAuLi5mb3JtYXRUcmFjZUVudHJ5KGVudHJ5KSk7DQogIH0pOw0KICByZXR1cm4gbG9nczsNCn0NCmZ1bmN0aW9uIGZvcm1hdFRyYWNlRW50cnkoeyB2bm9kZSwgcmVjdXJzZUNvdW50IH0pIHsNCiAgY29uc3QgcG9zdGZpeCA9IHJlY3Vyc2VDb3VudCA+IDAgPyBgLi4uICgke3JlY3Vyc2VDb3VudH0gcmVjdXJzaXZlIGNhbGxzKWAgOiBgYDsNCiAgY29uc3QgaXNSb290ID0gdm5vZGUuY29tcG9uZW50ID8gdm5vZGUuY29tcG9uZW50LnBhcmVudCA9PSBudWxsIDogZmFsc2U7DQogIGNvbnN0IG9wZW4gPSBgIGF0IDwke2Zvcm1hdENvbXBvbmVudE5hbWUoDQogICAgdm5vZGUuY29tcG9uZW50LA0KICAgIHZub2RlLnR5cGUsDQogICAgaXNSb290DQogICl9YDsNCiAgY29uc3QgY2xvc2UgPSBgPmAgKyBwb3N0Zml4Ow0KICByZXR1cm4gdm5vZGUucHJvcHMgPyBbb3BlbiwgLi4uZm9ybWF0UHJvcHModm5vZGUucHJvcHMpLCBjbG9zZV0gOiBbb3BlbiArIGNsb3NlXTsNCn0NCmZ1bmN0aW9uIGZvcm1hdFByb3BzKHByb3BzKSB7DQogIGNvbnN0IHJlcyA9IFtdOw0KICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMocHJvcHMpOw0KICBrZXlzLnNsaWNlKDAsIDMpLmZvckVhY2goKGtleSkgPT4gew0KICAgIHJlcy5wdXNoKC4uLmZvcm1hdFByb3Aoa2V5LCBwcm9wc1trZXldKSk7DQogIH0pOw0KICBpZiAoa2V5cy5sZW5ndGggPiAzKSB7DQogICAgcmVzLnB1c2goYCAuLi5gKTsNCiAgfQ0KICByZXR1cm4gcmVzOw0KfQ0KZnVuY3Rpb24gZm9ybWF0UHJvcChrZXksIHZhbHVlLCByYXcpIHsNCiAgaWYgKGlzU3RyaW5nKHZhbHVlKSkgew0KICAgIHZhbHVlID0gSlNPTi5zdHJpbmdpZnkodmFsdWUpOw0KICAgIHJldHVybiByYXcgPyB2YWx1ZSA6IFtgJHtrZXl9PSR7dmFsdWV9YF07DQogIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAibnVtYmVyIiB8fCB0eXBlb2YgdmFsdWUgPT09ICJib29sZWFuIiB8fCB2YWx1ZSA9PSBudWxsKSB7DQogICAgcmV0dXJuIHJhdyA/IHZhbHVlIDogW2Ake2tleX09JHt2YWx1ZX1gXTsNCiAgfSBlbHNlIGlmIChpc1JlZih2YWx1ZSkpIHsNCiAgICB2YWx1ZSA9IGZvcm1hdFByb3Aoa2V5LCB0b1Jhdyh2YWx1ZS52YWx1ZSksIHRydWUpOw0KICAgIHJldHVybiByYXcgPyB2YWx1ZSA6IFtgJHtrZXl9PVJlZjxgLCB2YWx1ZSwgYD5gXTsNCiAgfSBlbHNlIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkgew0KICAgIHJldHVybiBbYCR7a2V5fT1mbiR7dmFsdWUubmFtZSA/IGA8JHt2YWx1ZS5uYW1lfT5gIDogYGB9YF07DQogIH0gZWxzZSB7DQogICAgdmFsdWUgPSB0b1Jhdyh2YWx1ZSk7DQogICAgcmV0dXJuIHJhdyA/IHZhbHVlIDogW2Ake2tleX09YCwgdmFsdWVdOw0KICB9DQp9DQoNCmNvbnN0IEVycm9yVHlwZVN0cmluZ3MgPSB7DQogIFsic3AiXTogInNlcnZlclByZWZldGNoIGhvb2siLA0KICBbImJjIl06ICJiZWZvcmVDcmVhdGUgaG9vayIsDQogIFsiYyJdOiAiY3JlYXRlZCBob29rIiwNCiAgWyJibSJdOiAiYmVmb3JlTW91bnQgaG9vayIsDQogIFsibSJdOiAibW91bnRlZCBob29rIiwNCiAgWyJidSJdOiAiYmVmb3JlVXBkYXRlIGhvb2siLA0KICBbInUiXTogInVwZGF0ZWQiLA0KICBbImJ1bSJdOiAiYmVmb3JlVW5tb3VudCBob29rIiwNCiAgWyJ1bSJdOiAidW5tb3VudGVkIGhvb2siLA0KICBbImEiXTogImFjdGl2YXRlZCBob29rIiwNCiAgWyJkYSJdOiAiZGVhY3RpdmF0ZWQgaG9vayIsDQogIFsiZWMiXTogImVycm9yQ2FwdHVyZWQgaG9vayIsDQogIFsicnRjIl06ICJyZW5kZXJUcmFja2VkIGhvb2siLA0KICBbInJ0ZyJdOiAicmVuZGVyVHJpZ2dlcmVkIGhvb2siLA0KICBbMF06ICJzZXR1cCBmdW5jdGlvbiIsDQogIFsxXTogInJlbmRlciBmdW5jdGlvbiIsDQogIFsyXTogIndhdGNoZXIgZ2V0dGVyIiwNCiAgWzNdOiAid2F0Y2hlciBjYWxsYmFjayIsDQogIFs0XTogIndhdGNoZXIgY2xlYW51cCBmdW5jdGlvbiIsDQogIFs1XTogIm5hdGl2ZSBldmVudCBoYW5kbGVyIiwNCiAgWzZdOiAiY29tcG9uZW50IGV2ZW50IGhhbmRsZXIiLA0KICBbN106ICJ2bm9kZSBob29rIiwNCiAgWzhdOiAiZGlyZWN0aXZlIGhvb2siLA0KICBbOV06ICJ0cmFuc2l0aW9uIGhvb2siLA0KICBbMTBdOiAiYXBwIGVycm9ySGFuZGxlciIsDQogIFsxMV06ICJhcHAgd2FybkhhbmRsZXIiLA0KICBbMTJdOiAicmVmIGZ1bmN0aW9uIiwNCiAgWzEzXTogImFzeW5jIGNvbXBvbmVudCBsb2FkZXIiLA0KICBbMTRdOiAic2NoZWR1bGVyIGZsdXNoIiwNCiAgWzE1XTogImNvbXBvbmVudCB1cGRhdGUiLA0KICBbMTZdOiAiYXBwIHVubW91bnQgY2xlYW51cCBmdW5jdGlvbiINCn07DQpmdW5jdGlvbiBjYWxsV2l0aEVycm9ySGFuZGxpbmcoZm4sIGluc3RhbmNlLCB0eXBlLCBhcmdzKSB7DQogIHRyeSB7DQogICAgcmV0dXJuIGFyZ3MgPyBmbiguLi5hcmdzKSA6IGZuKCk7DQogIH0gY2F0Y2ggKGVycikgew0KICAgIGhhbmRsZUVycm9yKGVyciwgaW5zdGFuY2UsIHR5cGUpOw0KICB9DQp9DQpmdW5jdGlvbiBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZyhmbiwgaW5zdGFuY2UsIHR5cGUsIGFyZ3MpIHsNCiAgaWYgKGlzRnVuY3Rpb24oZm4pKSB7DQogICAgY29uc3QgcmVzID0gY2FsbFdpdGhFcnJvckhhbmRsaW5nKGZuLCBpbnN0YW5jZSwgdHlwZSwgYXJncyk7DQogICAgaWYgKHJlcyAmJiBpc1Byb21pc2UocmVzKSkgew0KICAgICAgcmVzLmNhdGNoKChlcnIpID0+IHsNCiAgICAgICAgaGFuZGxlRXJyb3IoZXJyLCBpbnN0YW5jZSwgdHlwZSk7DQogICAgICB9KTsNCiAgICB9DQogICAgcmV0dXJuIHJlczsNCiAgfQ0KICBpZiAoaXNBcnJheShmbikpIHsNCiAgICBjb25zdCB2YWx1ZXMgPSBbXTsNCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZuLmxlbmd0aDsgaSsrKSB7DQogICAgICB2YWx1ZXMucHVzaChjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZyhmbltpXSwgaW5zdGFuY2UsIHR5cGUsIGFyZ3MpKTsNCiAgICB9DQogICAgcmV0dXJuIHZhbHVlczsNCiAgfSBlbHNlIHsNCiAgICB3YXJuJDEoDQogICAgICBgSW52YWxpZCB2YWx1ZSB0eXBlIHBhc3NlZCB0byBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZygpOiAke3R5cGVvZiBmbn1gDQogICAgKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gaGFuZGxlRXJyb3IoZXJyLCBpbnN0YW5jZSwgdHlwZSwgdGhyb3dJbkRldiA9IHRydWUpIHsNCiAgY29uc3QgY29udGV4dFZOb2RlID0gaW5zdGFuY2UgPyBpbnN0YW5jZS52bm9kZSA6IG51bGw7DQogIGNvbnN0IHsgZXJyb3JIYW5kbGVyLCB0aHJvd1VuaGFuZGxlZEVycm9ySW5Qcm9kdWN0aW9uIH0gPSBpbnN0YW5jZSAmJiBpbnN0YW5jZS5hcHBDb250ZXh0LmNvbmZpZyB8fCBFTVBUWV9PQko7DQogIGlmIChpbnN0YW5jZSkgew0KICAgIGxldCBjdXIgPSBpbnN0YW5jZS5wYXJlbnQ7DQogICAgY29uc3QgZXhwb3NlZEluc3RhbmNlID0gaW5zdGFuY2UucHJveHk7DQogICAgY29uc3QgZXJyb3JJbmZvID0gRXJyb3JUeXBlU3RyaW5nc1t0eXBlXSA7DQogICAgd2hpbGUgKGN1cikgew0KICAgICAgY29uc3QgZXJyb3JDYXB0dXJlZEhvb2tzID0gY3VyLmVjOw0KICAgICAgaWYgKGVycm9yQ2FwdHVyZWRIb29rcykgew0KICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGVycm9yQ2FwdHVyZWRIb29rcy5sZW5ndGg7IGkrKykgew0KICAgICAgICAgIGlmIChlcnJvckNhcHR1cmVkSG9va3NbaV0oZXJyLCBleHBvc2VkSW5zdGFuY2UsIGVycm9ySW5mbykgPT09IGZhbHNlKSB7DQogICAgICAgICAgICByZXR1cm47DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICB9DQogICAgICBjdXIgPSBjdXIucGFyZW50Ow0KICAgIH0NCiAgICBpZiAoZXJyb3JIYW5kbGVyKSB7DQogICAgICBwYXVzZVRyYWNraW5nKCk7DQogICAgICBjYWxsV2l0aEVycm9ySGFuZGxpbmcoZXJyb3JIYW5kbGVyLCBudWxsLCAxMCwgWw0KICAgICAgICBlcnIsDQogICAgICAgIGV4cG9zZWRJbnN0YW5jZSwNCiAgICAgICAgZXJyb3JJbmZvDQogICAgICBdKTsNCiAgICAgIHJlc2V0VHJhY2tpbmcoKTsNCiAgICAgIHJldHVybjsNCiAgICB9DQogIH0NCiAgbG9nRXJyb3IoZXJyLCB0eXBlLCBjb250ZXh0Vk5vZGUsIHRocm93SW5EZXYsIHRocm93VW5oYW5kbGVkRXJyb3JJblByb2R1Y3Rpb24pOw0KfQ0KZnVuY3Rpb24gbG9nRXJyb3IoZXJyLCB0eXBlLCBjb250ZXh0Vk5vZGUsIHRocm93SW5EZXYgPSB0cnVlLCB0aHJvd0luUHJvZCA9IGZhbHNlKSB7DQogIHsNCiAgICBjb25zdCBpbmZvID0gRXJyb3JUeXBlU3RyaW5nc1t0eXBlXTsNCiAgICBpZiAoY29udGV4dFZOb2RlKSB7DQogICAgICBwdXNoV2FybmluZ0NvbnRleHQkMShjb250ZXh0Vk5vZGUpOw0KICAgIH0NCiAgICB3YXJuJDEoYFVuaGFuZGxlZCBlcnJvciR7aW5mbyA/IGAgZHVyaW5nIGV4ZWN1dGlvbiBvZiAke2luZm99YCA6IGBgfWApOw0KICAgIGlmIChjb250ZXh0Vk5vZGUpIHsNCiAgICAgIHBvcFdhcm5pbmdDb250ZXh0JDEoKTsNCiAgICB9DQogICAgaWYgKHRocm93SW5EZXYpIHsNCiAgICAgIHRocm93IGVycjsNCiAgICB9IGVsc2Ugew0KICAgICAgY29uc29sZS5lcnJvcihlcnIpOw0KICAgIH0NCiAgfQ0KfQ0KDQpjb25zdCBxdWV1ZSA9IFtdOw0KbGV0IGZsdXNoSW5kZXggPSAtMTsNCmNvbnN0IHBlbmRpbmdQb3N0Rmx1c2hDYnMgPSBbXTsNCmxldCBhY3RpdmVQb3N0Rmx1c2hDYnMgPSBudWxsOw0KbGV0IHBvc3RGbHVzaEluZGV4ID0gMDsNCmNvbnN0IHJlc29sdmVkUHJvbWlzZSA9IC8qIEBfX1BVUkVfXyAqLyBQcm9taXNlLnJlc29sdmUoKTsNCmxldCBjdXJyZW50Rmx1c2hQcm9taXNlID0gbnVsbDsNCmNvbnN0IFJFQ1VSU0lPTl9MSU1JVCA9IDEwMDsNCmZ1bmN0aW9uIG5leHRUaWNrKGZuKSB7DQogIGNvbnN0IHAgPSBjdXJyZW50Rmx1c2hQcm9taXNlIHx8IHJlc29sdmVkUHJvbWlzZTsNCiAgcmV0dXJuIGZuID8gcC50aGVuKHRoaXMgPyBmbi5iaW5kKHRoaXMpIDogZm4pIDogcDsNCn0NCmZ1bmN0aW9uIGZpbmRJbnNlcnRpb25JbmRleChpZCkgew0KICBsZXQgc3RhcnQgPSBmbHVzaEluZGV4ICsgMTsNCiAgbGV0IGVuZCA9IHF1ZXVlLmxlbmd0aDsNCiAgd2hpbGUgKHN0YXJ0IDwgZW5kKSB7DQogICAgY29uc3QgbWlkZGxlID0gc3RhcnQgKyBlbmQgPj4+IDE7DQogICAgY29uc3QgbWlkZGxlSm9iID0gcXVldWVbbWlkZGxlXTsNCiAgICBjb25zdCBtaWRkbGVKb2JJZCA9IGdldElkKG1pZGRsZUpvYik7DQogICAgaWYgKG1pZGRsZUpvYklkIDwgaWQgfHwgbWlkZGxlSm9iSWQgPT09IGlkICYmIG1pZGRsZUpvYi5mbGFncyAmIDIpIHsNCiAgICAgIHN0YXJ0ID0gbWlkZGxlICsgMTsNCiAgICB9IGVsc2Ugew0KICAgICAgZW5kID0gbWlkZGxlOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gc3RhcnQ7DQp9DQpmdW5jdGlvbiBxdWV1ZUpvYihqb2IpIHsNCiAgaWYgKCEoam9iLmZsYWdzICYgMSkpIHsNCiAgICBjb25zdCBqb2JJZCA9IGdldElkKGpvYik7DQogICAgY29uc3QgbGFzdEpvYiA9IHF1ZXVlW3F1ZXVlLmxlbmd0aCAtIDFdOw0KICAgIGlmICghbGFzdEpvYiB8fCAvLyBmYXN0IHBhdGggd2hlbiB0aGUgam9iIGlkIGlzIGxhcmdlciB0aGFuIHRoZSB0YWlsDQogICAgIShqb2IuZmxhZ3MgJiAyKSAmJiBqb2JJZCA+PSBnZXRJZChsYXN0Sm9iKSkgew0KICAgICAgcXVldWUucHVzaChqb2IpOw0KICAgIH0gZWxzZSB7DQogICAgICBxdWV1ZS5zcGxpY2UoZmluZEluc2VydGlvbkluZGV4KGpvYklkKSwgMCwgam9iKTsNCiAgICB9DQogICAgam9iLmZsYWdzIHw9IDE7DQogICAgcXVldWVGbHVzaCgpOw0KICB9DQp9DQpmdW5jdGlvbiBxdWV1ZUZsdXNoKCkgew0KICBpZiAoIWN1cnJlbnRGbHVzaFByb21pc2UpIHsNCiAgICBjdXJyZW50Rmx1c2hQcm9taXNlID0gcmVzb2x2ZWRQcm9taXNlLnRoZW4oZmx1c2hKb2JzKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gcXVldWVQb3N0Rmx1c2hDYihjYikgew0KICBpZiAoIWlzQXJyYXkoY2IpKSB7DQogICAgaWYgKGFjdGl2ZVBvc3RGbHVzaENicyAmJiBjYi5pZCA9PT0gLTEpIHsNCiAgICAgIGFjdGl2ZVBvc3RGbHVzaENicy5zcGxpY2UocG9zdEZsdXNoSW5kZXggKyAxLCAwLCBjYik7DQogICAgfSBlbHNlIGlmICghKGNiLmZsYWdzICYgMSkpIHsNCiAgICAgIHBlbmRpbmdQb3N0Rmx1c2hDYnMucHVzaChjYik7DQogICAgICBjYi5mbGFncyB8PSAxOw0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICBwZW5kaW5nUG9zdEZsdXNoQ2JzLnB1c2goLi4uY2IpOw0KICB9DQogIHF1ZXVlRmx1c2goKTsNCn0NCmZ1bmN0aW9uIGZsdXNoUHJlRmx1c2hDYnMoaW5zdGFuY2UsIHNlZW4sIGkgPSBmbHVzaEluZGV4ICsgMSkgew0KICB7DQogICAgc2VlbiA9IHNlZW4gfHwgLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTsNCiAgfQ0KICBmb3IgKDsgaSA8IHF1ZXVlLmxlbmd0aDsgaSsrKSB7DQogICAgY29uc3QgY2IgPSBxdWV1ZVtpXTsNCiAgICBpZiAoY2IgJiYgY2IuZmxhZ3MgJiAyKSB7DQogICAgICBpZiAoaW5zdGFuY2UgJiYgY2IuaWQgIT09IGluc3RhbmNlLnVpZCkgew0KICAgICAgICBjb250aW51ZTsNCiAgICAgIH0NCiAgICAgIGlmIChjaGVja1JlY3Vyc2l2ZVVwZGF0ZXMoc2VlbiwgY2IpKSB7DQogICAgICAgIGNvbnRpbnVlOw0KICAgICAgfQ0KICAgICAgcXVldWUuc3BsaWNlKGksIDEpOw0KICAgICAgaS0tOw0KICAgICAgaWYgKGNiLmZsYWdzICYgNCkgew0KICAgICAgICBjYi5mbGFncyAmPSAtMjsNCiAgICAgIH0NCiAgICAgIGNiKCk7DQogICAgICBpZiAoIShjYi5mbGFncyAmIDQpKSB7DQogICAgICAgIGNiLmZsYWdzICY9IC0yOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KfQ0KZnVuY3Rpb24gZmx1c2hQb3N0Rmx1c2hDYnMoc2Vlbikgew0KICBpZiAocGVuZGluZ1Bvc3RGbHVzaENicy5sZW5ndGgpIHsNCiAgICBjb25zdCBkZWR1cGVkID0gWy4uLm5ldyBTZXQocGVuZGluZ1Bvc3RGbHVzaENicyldLnNvcnQoDQogICAgICAoYSwgYikgPT4gZ2V0SWQoYSkgLSBnZXRJZChiKQ0KICAgICk7DQogICAgcGVuZGluZ1Bvc3RGbHVzaENicy5sZW5ndGggPSAwOw0KICAgIGlmIChhY3RpdmVQb3N0Rmx1c2hDYnMpIHsNCiAgICAgIGFjdGl2ZVBvc3RGbHVzaENicy5wdXNoKC4uLmRlZHVwZWQpOw0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBhY3RpdmVQb3N0Rmx1c2hDYnMgPSBkZWR1cGVkOw0KICAgIHsNCiAgICAgIHNlZW4gPSBzZWVuIHx8IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7DQogICAgfQ0KICAgIGZvciAocG9zdEZsdXNoSW5kZXggPSAwOyBwb3N0Rmx1c2hJbmRleCA8IGFjdGl2ZVBvc3RGbHVzaENicy5sZW5ndGg7IHBvc3RGbHVzaEluZGV4KyspIHsNCiAgICAgIGNvbnN0IGNiID0gYWN0aXZlUG9zdEZsdXNoQ2JzW3Bvc3RGbHVzaEluZGV4XTsNCiAgICAgIGlmIChjaGVja1JlY3Vyc2l2ZVVwZGF0ZXMoc2VlbiwgY2IpKSB7DQogICAgICAgIGNvbnRpbnVlOw0KICAgICAgfQ0KICAgICAgaWYgKGNiLmZsYWdzICYgNCkgew0KICAgICAgICBjYi5mbGFncyAmPSAtMjsNCiAgICAgIH0NCiAgICAgIGlmICghKGNiLmZsYWdzICYgOCkpIGNiKCk7DQogICAgICBjYi5mbGFncyAmPSAtMjsNCiAgICB9DQogICAgYWN0aXZlUG9zdEZsdXNoQ2JzID0gbnVsbDsNCiAgICBwb3N0Rmx1c2hJbmRleCA9IDA7DQogIH0NCn0NCmNvbnN0IGdldElkID0gKGpvYikgPT4gam9iLmlkID09IG51bGwgPyBqb2IuZmxhZ3MgJiAyID8gLTEgOiBJbmZpbml0eSA6IGpvYi5pZDsNCmZ1bmN0aW9uIGZsdXNoSm9icyhzZWVuKSB7DQogIHsNCiAgICBzZWVuID0gc2VlbiB8fCAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOw0KICB9DQogIGNvbnN0IGNoZWNrID0gKGpvYikgPT4gY2hlY2tSZWN1cnNpdmVVcGRhdGVzKHNlZW4sIGpvYikgOw0KICB0cnkgew0KICAgIGZvciAoZmx1c2hJbmRleCA9IDA7IGZsdXNoSW5kZXggPCBxdWV1ZS5sZW5ndGg7IGZsdXNoSW5kZXgrKykgew0KICAgICAgY29uc3Qgam9iID0gcXVldWVbZmx1c2hJbmRleF07DQogICAgICBpZiAoam9iICYmICEoam9iLmZsYWdzICYgOCkpIHsNCiAgICAgICAgaWYgKGNoZWNrKGpvYikpIHsNCiAgICAgICAgICBjb250aW51ZTsNCiAgICAgICAgfQ0KICAgICAgICBpZiAoam9iLmZsYWdzICYgNCkgew0KICAgICAgICAgIGpvYi5mbGFncyAmPSB+MTsNCiAgICAgICAgfQ0KICAgICAgICBjYWxsV2l0aEVycm9ySGFuZGxpbmcoDQogICAgICAgICAgam9iLA0KICAgICAgICAgIGpvYi5pLA0KICAgICAgICAgIGpvYi5pID8gMTUgOiAxNA0KICAgICAgICApOw0KICAgICAgICBpZiAoIShqb2IuZmxhZ3MgJiA0KSkgew0KICAgICAgICAgIGpvYi5mbGFncyAmPSB+MTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgfSBmaW5hbGx5IHsNCiAgICBmb3IgKDsgZmx1c2hJbmRleCA8IHF1ZXVlLmxlbmd0aDsgZmx1c2hJbmRleCsrKSB7DQogICAgICBjb25zdCBqb2IgPSBxdWV1ZVtmbHVzaEluZGV4XTsNCiAgICAgIGlmIChqb2IpIHsNCiAgICAgICAgam9iLmZsYWdzICY9IC0yOw0KICAgICAgfQ0KICAgIH0NCiAgICBmbHVzaEluZGV4ID0gLTE7DQogICAgcXVldWUubGVuZ3RoID0gMDsNCiAgICBmbHVzaFBvc3RGbHVzaENicyhzZWVuKTsNCiAgICBjdXJyZW50Rmx1c2hQcm9taXNlID0gbnVsbDsNCiAgICBpZiAocXVldWUubGVuZ3RoIHx8IHBlbmRpbmdQb3N0Rmx1c2hDYnMubGVuZ3RoKSB7DQogICAgICBmbHVzaEpvYnMoc2Vlbik7DQogICAgfQ0KICB9DQp9DQpmdW5jdGlvbiBjaGVja1JlY3Vyc2l2ZVVwZGF0ZXMoc2VlbiwgZm4pIHsNCiAgY29uc3QgY291bnQgPSBzZWVuLmdldChmbikgfHwgMDsNCiAgaWYgKGNvdW50ID4gUkVDVVJTSU9OX0xJTUlUKSB7DQogICAgY29uc3QgaW5zdGFuY2UgPSBmbi5pOw0KICAgIGNvbnN0IGNvbXBvbmVudE5hbWUgPSBpbnN0YW5jZSAmJiBnZXRDb21wb25lbnROYW1lKGluc3RhbmNlLnR5cGUpOw0KICAgIGhhbmRsZUVycm9yKA0KICAgICAgYE1heGltdW0gcmVjdXJzaXZlIHVwZGF0ZXMgZXhjZWVkZWQke2NvbXBvbmVudE5hbWUgPyBgIGluIGNvbXBvbmVudCA8JHtjb21wb25lbnROYW1lfT5gIDogYGB9LiBUaGlzIG1lYW5zIHlvdSBoYXZlIGEgcmVhY3RpdmUgZWZmZWN0IHRoYXQgaXMgbXV0YXRpbmcgaXRzIG93biBkZXBlbmRlbmNpZXMgYW5kIHRodXMgcmVjdXJzaXZlbHkgdHJpZ2dlcmluZyBpdHNlbGYuIFBvc3NpYmxlIHNvdXJjZXMgaW5jbHVkZSBjb21wb25lbnQgdGVtcGxhdGUsIHJlbmRlciBmdW5jdGlvbiwgdXBkYXRlZCBob29rIG9yIHdhdGNoZXIgc291cmNlIGZ1bmN0aW9uLmAsDQogICAgICBudWxsLA0KICAgICAgMTANCiAgICApOw0KICAgIHJldHVybiB0cnVlOw0KICB9DQogIHNlZW4uc2V0KGZuLCBjb3VudCArIDEpOw0KICByZXR1cm4gZmFsc2U7DQp9DQoNCmxldCBpc0htclVwZGF0aW5nID0gZmFsc2U7DQpjb25zdCBobXJEaXJ0eUNvbXBvbmVudHMgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOw0Kew0KICBnZXRHbG9iYWxUaGlzKCkuX19WVUVfSE1SX1JVTlRJTUVfXyA9IHsNCiAgICBjcmVhdGVSZWNvcmQ6IHRyeVdyYXAoY3JlYXRlUmVjb3JkKSwNCiAgICByZXJlbmRlcjogdHJ5V3JhcChyZXJlbmRlciksDQogICAgcmVsb2FkOiB0cnlXcmFwKHJlbG9hZCkNCiAgfTsNCn0NCmNvbnN0IG1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7DQpmdW5jdGlvbiByZWdpc3RlckhNUihpbnN0YW5jZSkgew0KICBjb25zdCBpZCA9IGluc3RhbmNlLnR5cGUuX19obXJJZDsNCiAgbGV0IHJlY29yZCA9IG1hcC5nZXQoaWQpOw0KICBpZiAoIXJlY29yZCkgew0KICAgIGNyZWF0ZVJlY29yZChpZCwgaW5zdGFuY2UudHlwZSk7DQogICAgcmVjb3JkID0gbWFwLmdldChpZCk7DQogIH0NCiAgcmVjb3JkLmluc3RhbmNlcy5hZGQoaW5zdGFuY2UpOw0KfQ0KZnVuY3Rpb24gdW5yZWdpc3RlckhNUihpbnN0YW5jZSkgew0KICBtYXAuZ2V0KGluc3RhbmNlLnR5cGUuX19obXJJZCkuaW5zdGFuY2VzLmRlbGV0ZShpbnN0YW5jZSk7DQp9DQpmdW5jdGlvbiBjcmVhdGVSZWNvcmQoaWQsIGluaXRpYWxEZWYpIHsNCiAgaWYgKG1hcC5oYXMoaWQpKSB7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9DQogIG1hcC5zZXQoaWQsIHsNCiAgICBpbml0aWFsRGVmOiBub3JtYWxpemVDbGFzc0NvbXBvbmVudChpbml0aWFsRGVmKSwNCiAgICBpbnN0YW5jZXM6IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KCkNCiAgfSk7DQogIHJldHVybiB0cnVlOw0KfQ0KZnVuY3Rpb24gbm9ybWFsaXplQ2xhc3NDb21wb25lbnQoY29tcG9uZW50KSB7DQogIHJldHVybiBpc0NsYXNzQ29tcG9uZW50KGNvbXBvbmVudCkgPyBjb21wb25lbnQuX192Y2NPcHRzIDogY29tcG9uZW50Ow0KfQ0KZnVuY3Rpb24gcmVyZW5kZXIoaWQsIG5ld1JlbmRlcikgew0KICBjb25zdCByZWNvcmQgPSBtYXAuZ2V0KGlkKTsNCiAgaWYgKCFyZWNvcmQpIHsNCiAgICByZXR1cm47DQogIH0NCiAgcmVjb3JkLmluaXRpYWxEZWYucmVuZGVyID0gbmV3UmVuZGVyOw0KICBbLi4ucmVjb3JkLmluc3RhbmNlc10uZm9yRWFjaCgoaW5zdGFuY2UpID0+IHsNCiAgICBpZiAobmV3UmVuZGVyKSB7DQogICAgICBpbnN0YW5jZS5yZW5kZXIgPSBuZXdSZW5kZXI7DQogICAgICBub3JtYWxpemVDbGFzc0NvbXBvbmVudChpbnN0YW5jZS50eXBlKS5yZW5kZXIgPSBuZXdSZW5kZXI7DQogICAgfQ0KICAgIGluc3RhbmNlLnJlbmRlckNhY2hlID0gW107DQogICAgaXNIbXJVcGRhdGluZyA9IHRydWU7DQogICAgaW5zdGFuY2UudXBkYXRlKCk7DQogICAgaXNIbXJVcGRhdGluZyA9IGZhbHNlOw0KICB9KTsNCn0NCmZ1bmN0aW9uIHJlbG9hZChpZCwgbmV3Q29tcCkgew0KICBjb25zdCByZWNvcmQgPSBtYXAuZ2V0KGlkKTsNCiAgaWYgKCFyZWNvcmQpIHJldHVybjsNCiAgbmV3Q29tcCA9IG5vcm1hbGl6ZUNsYXNzQ29tcG9uZW50KG5ld0NvbXApOw0KICB1cGRhdGVDb21wb25lbnREZWYocmVjb3JkLmluaXRpYWxEZWYsIG5ld0NvbXApOw0KICBjb25zdCBpbnN0YW5jZXMgPSBbLi4ucmVjb3JkLmluc3RhbmNlc107DQogIGZvciAobGV0IGkgPSAwOyBpIDwgaW5zdGFuY2VzLmxlbmd0aDsgaSsrKSB7DQogICAgY29uc3QgaW5zdGFuY2UgPSBpbnN0YW5jZXNbaV07DQogICAgY29uc3Qgb2xkQ29tcCA9IG5vcm1hbGl6ZUNsYXNzQ29tcG9uZW50KGluc3RhbmNlLnR5cGUpOw0KICAgIGxldCBkaXJ0eUluc3RhbmNlcyA9IGhtckRpcnR5Q29tcG9uZW50cy5nZXQob2xkQ29tcCk7DQogICAgaWYgKCFkaXJ0eUluc3RhbmNlcykgew0KICAgICAgaWYgKG9sZENvbXAgIT09IHJlY29yZC5pbml0aWFsRGVmKSB7DQogICAgICAgIHVwZGF0ZUNvbXBvbmVudERlZihvbGRDb21wLCBuZXdDb21wKTsNCiAgICAgIH0NCiAgICAgIGhtckRpcnR5Q29tcG9uZW50cy5zZXQob2xkQ29tcCwgZGlydHlJbnN0YW5jZXMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpKTsNCiAgICB9DQogICAgZGlydHlJbnN0YW5jZXMuYWRkKGluc3RhbmNlKTsNCiAgICBpbnN0YW5jZS5hcHBDb250ZXh0LnByb3BzQ2FjaGUuZGVsZXRlKGluc3RhbmNlLnR5cGUpOw0KICAgIGluc3RhbmNlLmFwcENvbnRleHQuZW1pdHNDYWNoZS5kZWxldGUoaW5zdGFuY2UudHlwZSk7DQogICAgaW5zdGFuY2UuYXBwQ29udGV4dC5vcHRpb25zQ2FjaGUuZGVsZXRlKGluc3RhbmNlLnR5cGUpOw0KICAgIGlmIChpbnN0YW5jZS5jZVJlbG9hZCkgew0KICAgICAgZGlydHlJbnN0YW5jZXMuYWRkKGluc3RhbmNlKTsNCiAgICAgIGluc3RhbmNlLmNlUmVsb2FkKG5ld0NvbXAuc3R5bGVzKTsNCiAgICAgIGRpcnR5SW5zdGFuY2VzLmRlbGV0ZShpbnN0YW5jZSk7DQogICAgfSBlbHNlIGlmIChpbnN0YW5jZS5wYXJlbnQpIHsNCiAgICAgIHF1ZXVlSm9iKCgpID0+IHsNCiAgICAgICAgaXNIbXJVcGRhdGluZyA9IHRydWU7DQogICAgICAgIGluc3RhbmNlLnBhcmVudC51cGRhdGUoKTsNCiAgICAgICAgaXNIbXJVcGRhdGluZyA9IGZhbHNlOw0KICAgICAgICBkaXJ0eUluc3RhbmNlcy5kZWxldGUoaW5zdGFuY2UpOw0KICAgICAgfSk7DQogICAgfSBlbHNlIGlmIChpbnN0YW5jZS5hcHBDb250ZXh0LnJlbG9hZCkgew0KICAgICAgaW5zdGFuY2UuYXBwQ29udGV4dC5yZWxvYWQoKTsNCiAgICB9IGVsc2UgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICJ1bmRlZmluZWQiKSB7DQogICAgICB3aW5kb3cubG9jYXRpb24ucmVsb2FkKCk7DQogICAgfSBlbHNlIHsNCiAgICAgIGNvbnNvbGUud2FybigNCiAgICAgICAgIltITVJdIFJvb3Qgb3IgbWFudWFsbHkgbW91bnRlZCBpbnN0YW5jZSBtb2RpZmllZC4gRnVsbCByZWxvYWQgcmVxdWlyZWQuIg0KICAgICAgKTsNCiAgICB9DQogICAgaWYgKGluc3RhbmNlLnJvb3QuY2UgJiYgaW5zdGFuY2UgIT09IGluc3RhbmNlLnJvb3QpIHsNCiAgICAgIGluc3RhbmNlLnJvb3QuY2UuX3JlbW92ZUNoaWxkU3R5bGUob2xkQ29tcCk7DQogICAgfQ0KICB9DQogIHF1ZXVlUG9zdEZsdXNoQ2IoKCkgPT4gew0KICAgIGhtckRpcnR5Q29tcG9uZW50cy5jbGVhcigpOw0KICB9KTsNCn0NCmZ1bmN0aW9uIHVwZGF0ZUNvbXBvbmVudERlZihvbGRDb21wLCBuZXdDb21wKSB7DQogIGV4dGVuZChvbGRDb21wLCBuZXdDb21wKTsNCiAgZm9yIChjb25zdCBrZXkgaW4gb2xkQ29tcCkgew0KICAgIGlmIChrZXkgIT09ICJfX2ZpbGUiICYmICEoa2V5IGluIG5ld0NvbXApKSB7DQogICAgICBkZWxldGUgb2xkQ29tcFtrZXldOw0KICAgIH0NCiAgfQ0KfQ0KZnVuY3Rpb24gdHJ5V3JhcChmbikgew0KICByZXR1cm4gKGlkLCBhcmcpID0+IHsNCiAgICB0cnkgew0KICAgICAgcmV0dXJuIGZuKGlkLCBhcmcpOw0KICAgIH0gY2F0Y2ggKGUpIHsNCiAgICAgIGNvbnNvbGUuZXJyb3IoZSk7DQogICAgICBjb25zb2xlLndhcm4oDQogICAgICAgIGBbSE1SXSBTb21ldGhpbmcgd2VudCB3cm9uZyBkdXJpbmcgVnVlIGNvbXBvbmVudCBob3QtcmVsb2FkLiBGdWxsIHJlbG9hZCByZXF1aXJlZC5gDQogICAgICApOw0KICAgIH0NCiAgfTsNCn0NCg0KbGV0IGRldnRvb2xzOw0KbGV0IGJ1ZmZlciA9IFtdOw0KbGV0IGRldnRvb2xzTm90SW5zdGFsbGVkID0gZmFsc2U7DQpmdW5jdGlvbiBlbWl0JDEoZXZlbnQsIC4uLmFyZ3MpIHsNCiAgaWYgKGRldnRvb2xzKSB7DQogICAgZGV2dG9vbHMuZW1pdChldmVudCwgLi4uYXJncyk7DQogIH0gZWxzZSBpZiAoIWRldnRvb2xzTm90SW5zdGFsbGVkKSB7DQogICAgYnVmZmVyLnB1c2goeyBldmVudCwgYXJncyB9KTsNCiAgfQ0KfQ0KZnVuY3Rpb24gc2V0RGV2dG9vbHNIb29rKGhvb2ssIHRhcmdldCkgew0KICB2YXIgX2EsIF9iOw0KICBkZXZ0b29scyA9IGhvb2s7DQogIGlmIChkZXZ0b29scykgew0KICAgIGRldnRvb2xzLmVuYWJsZWQgPSB0cnVlOw0KICAgIGJ1ZmZlci5mb3JFYWNoKCh7IGV2ZW50LCBhcmdzIH0pID0+IGRldnRvb2xzLmVtaXQoZXZlbnQsIC4uLmFyZ3MpKTsNCiAgICBidWZmZXIgPSBbXTsNCiAgfSBlbHNlIGlmICgNCiAgICAvLyBoYW5kbGUgbGF0ZSBkZXZ0b29scyBpbmplY3Rpb24gLSBvbmx5IGRvIHRoaXMgaWYgd2UgYXJlIGluIGFuIGFjdHVhbA0KICAgIC8vIGJyb3dzZXIgZW52aXJvbm1lbnQgdG8gYXZvaWQgdGhlIHRpbWVyIGhhbmRsZSBzdGFsbGluZyB0ZXN0IHJ1bm5lciBleGl0DQogICAgLy8gKCM0ODE1KQ0KICAgIHR5cGVvZiB3aW5kb3cgIT09ICJ1bmRlZmluZWQiICYmIC8vIHNvbWUgZW52cyBtb2NrIHdpbmRvdyBidXQgbm90IGZ1bGx5DQogICAgd2luZG93LkhUTUxFbGVtZW50ICYmIC8vIGFsc28gZXhjbHVkZSBqc2RvbQ0KICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheA0KICAgICEoKF9iID0gKF9hID0gd2luZG93Lm5hdmlnYXRvcikgPT0gbnVsbCA/IHZvaWQgMCA6IF9hLnVzZXJBZ2VudCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9iLmluY2x1ZGVzKCJqc2RvbSIpKQ0KICApIHsNCiAgICBjb25zdCByZXBsYXkgPSB0YXJnZXQuX19WVUVfREVWVE9PTFNfSE9PS19SRVBMQVlfXyA9IHRhcmdldC5fX1ZVRV9ERVZUT09MU19IT09LX1JFUExBWV9fIHx8IFtdOw0KICAgIHJlcGxheS5wdXNoKChuZXdIb29rKSA9PiB7DQogICAgICBzZXREZXZ0b29sc0hvb2sobmV3SG9vaywgdGFyZ2V0KTsNCiAgICB9KTsNCiAgICBzZXRUaW1lb3V0KCgpID0+IHsNCiAgICAgIGlmICghZGV2dG9vbHMpIHsNCiAgICAgICAgdGFyZ2V0Ll9fVlVFX0RFVlRPT0xTX0hPT0tfUkVQTEFZX18gPSBudWxsOw0KICAgICAgICBkZXZ0b29sc05vdEluc3RhbGxlZCA9IHRydWU7DQogICAgICAgIGJ1ZmZlciA9IFtdOw0KICAgICAgfQ0KICAgIH0sIDNlMyk7DQogIH0gZWxzZSB7DQogICAgZGV2dG9vbHNOb3RJbnN0YWxsZWQgPSB0cnVlOw0KICAgIGJ1ZmZlciA9IFtdOw0KICB9DQp9DQpmdW5jdGlvbiBkZXZ0b29sc0luaXRBcHAoYXBwLCB2ZXJzaW9uKSB7DQogIGVtaXQkMSgiYXBwOmluaXQiIC8qIEFQUF9JTklUICovLCBhcHAsIHZlcnNpb24sIHsNCiAgICBGcmFnbWVudCwNCiAgICBUZXh0LA0KICAgIENvbW1lbnQsDQogICAgU3RhdGljDQogIH0pOw0KfQ0KZnVuY3Rpb24gZGV2dG9vbHNVbm1vdW50QXBwKGFwcCkgew0KICBlbWl0JDEoImFwcDp1bm1vdW50IiAvKiBBUFBfVU5NT1VOVCAqLywgYXBwKTsNCn0NCmNvbnN0IGRldnRvb2xzQ29tcG9uZW50QWRkZWQgPSAvKiBAX19QVVJFX18gKi8gY3JlYXRlRGV2dG9vbHNDb21wb25lbnRIb29rKCJjb21wb25lbnQ6YWRkZWQiIC8qIENPTVBPTkVOVF9BRERFRCAqLyk7DQpjb25zdCBkZXZ0b29sc0NvbXBvbmVudFVwZGF0ZWQgPSAvKiBAX19QVVJFX18gKi8gY3JlYXRlRGV2dG9vbHNDb21wb25lbnRIb29rKCJjb21wb25lbnQ6dXBkYXRlZCIgLyogQ09NUE9ORU5UX1VQREFURUQgKi8pOw0KY29uc3QgX2RldnRvb2xzQ29tcG9uZW50UmVtb3ZlZCA9IC8qIEBfX1BVUkVfXyAqLyBjcmVhdGVEZXZ0b29sc0NvbXBvbmVudEhvb2soDQogICJjb21wb25lbnQ6cmVtb3ZlZCIgLyogQ09NUE9ORU5UX1JFTU9WRUQgKi8NCik7DQpjb25zdCBkZXZ0b29sc0NvbXBvbmVudFJlbW92ZWQgPSAoY29tcG9uZW50KSA9PiB7DQogIGlmIChkZXZ0b29scyAmJiB0eXBlb2YgZGV2dG9vbHMuY2xlYW51cEJ1ZmZlciA9PT0gImZ1bmN0aW9uIiAmJiAvLyByZW1vdmUgdGhlIGNvbXBvbmVudCBpZiBpdCB3YXNuJ3QgYnVmZmVyZWQNCiAgIWRldnRvb2xzLmNsZWFudXBCdWZmZXIoY29tcG9uZW50KSkgew0KICAgIF9kZXZ0b29sc0NvbXBvbmVudFJlbW92ZWQoY29tcG9uZW50KTsNCiAgfQ0KfTsNCi8qISAjX19OT19TSURFX0VGRkVDVFNfXyAqLw0KLy8gQF9fTk9fU0lERV9FRkZFQ1RTX18NCmZ1bmN0aW9uIGNyZWF0ZURldnRvb2xzQ29tcG9uZW50SG9vayhob29rKSB7DQogIHJldHVybiAoY29tcG9uZW50KSA9PiB7DQogICAgZW1pdCQxKA0KICAgICAgaG9vaywNCiAgICAgIGNvbXBvbmVudC5hcHBDb250ZXh0LmFwcCwNCiAgICAgIGNvbXBvbmVudC51aWQsDQogICAgICBjb21wb25lbnQucGFyZW50ID8gY29tcG9uZW50LnBhcmVudC51aWQgOiB2b2lkIDAsDQogICAgICBjb21wb25lbnQNCiAgICApOw0KICB9Ow0KfQ0KY29uc3QgZGV2dG9vbHNQZXJmU3RhcnQgPSAvKiBAX19QVVJFX18gKi8gY3JlYXRlRGV2dG9vbHNQZXJmb3JtYW5jZUhvb2soInBlcmY6c3RhcnQiIC8qIFBFUkZPUk1BTkNFX1NUQVJUICovKTsNCmNvbnN0IGRldnRvb2xzUGVyZkVuZCA9IC8qIEBfX1BVUkVfXyAqLyBjcmVhdGVEZXZ0b29sc1BlcmZvcm1hbmNlSG9vaygicGVyZjplbmQiIC8qIFBFUkZPUk1BTkNFX0VORCAqLyk7DQpmdW5jdGlvbiBjcmVhdGVEZXZ0b29sc1BlcmZvcm1hbmNlSG9vayhob29rKSB7DQogIHJldHVybiAoY29tcG9uZW50LCB0eXBlLCB0aW1lKSA9PiB7DQogICAgZW1pdCQxKGhvb2ssIGNvbXBvbmVudC5hcHBDb250ZXh0LmFwcCwgY29tcG9uZW50LnVpZCwgY29tcG9uZW50LCB0eXBlLCB0aW1lKTsNCiAgfTsNCn0NCmZ1bmN0aW9uIGRldnRvb2xzQ29tcG9uZW50RW1pdChjb21wb25lbnQsIGV2ZW50LCBwYXJhbXMpIHsNCiAgZW1pdCQxKA0KICAgICJjb21wb25lbnQ6ZW1pdCIgLyogQ09NUE9ORU5UX0VNSVQgKi8sDQogICAgY29tcG9uZW50LmFwcENvbnRleHQuYXBwLA0KICAgIGNvbXBvbmVudCwNCiAgICBldmVudCwNCiAgICBwYXJhbXMNCiAgKTsNCn0NCg0KbGV0IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSA9IG51bGw7DQpsZXQgY3VycmVudFNjb3BlSWQgPSBudWxsOw0KZnVuY3Rpb24gc2V0Q3VycmVudFJlbmRlcmluZ0luc3RhbmNlJDEoaW5zdGFuY2UpIHsNCiAgY29uc3QgcHJldiA9IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZTsNCiAgY3VycmVudFJlbmRlcmluZ0luc3RhbmNlID0gaW5zdGFuY2U7DQogIGN1cnJlbnRTY29wZUlkID0gaW5zdGFuY2UgJiYgaW5zdGFuY2UudHlwZS5fX3Njb3BlSWQgfHwgbnVsbDsNCiAgcmV0dXJuIHByZXY7DQp9DQpmdW5jdGlvbiB3aXRoQ3R4KGZuLCBjdHggPSBjdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UsIGlzTm9uU2NvcGVkU2xvdCkgew0KICBpZiAoIWN0eCkgcmV0dXJuIGZuOw0KICBpZiAoZm4uX24pIHsNCiAgICByZXR1cm4gZm47DQogIH0NCiAgY29uc3QgcmVuZGVyRm5XaXRoQ29udGV4dCA9ICguLi5hcmdzKSA9PiB7DQogICAgaWYgKHJlbmRlckZuV2l0aENvbnRleHQuX2QpIHsNCiAgICAgIHNldEJsb2NrVHJhY2tpbmcoLTEpOw0KICAgIH0NCiAgICBjb25zdCBwcmV2SW5zdGFuY2UgPSBzZXRDdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UkMShjdHgpOw0KICAgIGxldCByZXM7DQogICAgdHJ5IHsNCiAgICAgIHJlcyA9IGZuKC4uLmFyZ3MpOw0KICAgIH0gZmluYWxseSB7DQogICAgICBzZXRDdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UkMShwcmV2SW5zdGFuY2UpOw0KICAgICAgaWYgKHJlbmRlckZuV2l0aENvbnRleHQuX2QpIHsNCiAgICAgICAgc2V0QmxvY2tUcmFja2luZygxKTsNCiAgICAgIH0NCiAgICB9DQogICAgew0KICAgICAgZGV2dG9vbHNDb21wb25lbnRVcGRhdGVkKGN0eCk7DQogICAgfQ0KICAgIHJldHVybiByZXM7DQogIH07DQogIHJlbmRlckZuV2l0aENvbnRleHQuX24gPSB0cnVlOw0KICByZW5kZXJGbldpdGhDb250ZXh0Ll9jID0gdHJ1ZTsNCiAgcmVuZGVyRm5XaXRoQ29udGV4dC5fZCA9IHRydWU7DQogIHJldHVybiByZW5kZXJGbldpdGhDb250ZXh0Ow0KfQ0KDQpmdW5jdGlvbiB2YWxpZGF0ZURpcmVjdGl2ZU5hbWUobmFtZSkgew0KICBpZiAoaXNCdWlsdEluRGlyZWN0aXZlKG5hbWUpKSB7DQogICAgd2FybiQxKCJEbyBub3QgdXNlIGJ1aWx0LWluIGRpcmVjdGl2ZSBpZHMgYXMgY3VzdG9tIGRpcmVjdGl2ZSBpZDogIiArIG5hbWUpOw0KICB9DQp9DQpmdW5jdGlvbiBpbnZva2VEaXJlY3RpdmVIb29rKHZub2RlLCBwcmV2Vk5vZGUsIGluc3RhbmNlLCBuYW1lKSB7DQogIGNvbnN0IGJpbmRpbmdzID0gdm5vZGUuZGlyczsNCiAgY29uc3Qgb2xkQmluZGluZ3MgPSBwcmV2Vk5vZGUgJiYgcHJldlZOb2RlLmRpcnM7DQogIGZvciAobGV0IGkgPSAwOyBpIDwgYmluZGluZ3MubGVuZ3RoOyBpKyspIHsNCiAgICBjb25zdCBiaW5kaW5nID0gYmluZGluZ3NbaV07DQogICAgaWYgKG9sZEJpbmRpbmdzKSB7DQogICAgICBiaW5kaW5nLm9sZFZhbHVlID0gb2xkQmluZGluZ3NbaV0udmFsdWU7DQogICAgfQ0KICAgIGxldCBob29rID0gYmluZGluZy5kaXJbbmFtZV07DQogICAgaWYgKGhvb2spIHsNCiAgICAgIHBhdXNlVHJhY2tpbmcoKTsNCiAgICAgIGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nKGhvb2ssIGluc3RhbmNlLCA4LCBbDQogICAgICAgIHZub2RlLmVsLA0KICAgICAgICBiaW5kaW5nLA0KICAgICAgICB2bm9kZSwNCiAgICAgICAgcHJldlZOb2RlDQogICAgICBdKTsNCiAgICAgIHJlc2V0VHJhY2tpbmcoKTsNCiAgICB9DQogIH0NCn0NCg0KY29uc3QgVGVsZXBvcnRFbmRLZXkgPSBTeW1ib2woIl92dGUiKTsNCmNvbnN0IGlzVGVsZXBvcnQgPSAodHlwZSkgPT4gdHlwZS5fX2lzVGVsZXBvcnQ7DQoNCmZ1bmN0aW9uIHNldFRyYW5zaXRpb25Ib29rcyh2bm9kZSwgaG9va3MpIHsNCiAgaWYgKHZub2RlLnNoYXBlRmxhZyAmIDYgJiYgdm5vZGUuY29tcG9uZW50KSB7DQogICAgdm5vZGUudHJhbnNpdGlvbiA9IGhvb2tzOw0KICAgIHNldFRyYW5zaXRpb25Ib29rcyh2bm9kZS5jb21wb25lbnQuc3ViVHJlZSwgaG9va3MpOw0KICB9IGVsc2UgaWYgKHZub2RlLnNoYXBlRmxhZyAmIDEyOCkgew0KICAgIHZub2RlLnNzQ29udGVudC50cmFuc2l0aW9uID0gaG9va3MuY2xvbmUodm5vZGUuc3NDb250ZW50KTsNCiAgICB2bm9kZS5zc0ZhbGxiYWNrLnRyYW5zaXRpb24gPSBob29rcy5jbG9uZSh2bm9kZS5zc0ZhbGxiYWNrKTsNCiAgfSBlbHNlIHsNCiAgICB2bm9kZS50cmFuc2l0aW9uID0gaG9va3M7DQogIH0NCn0NCg0KZnVuY3Rpb24gbWFya0FzeW5jQm91bmRhcnkoaW5zdGFuY2UpIHsNCiAgaW5zdGFuY2UuaWRzID0gW2luc3RhbmNlLmlkc1swXSArIGluc3RhbmNlLmlkc1syXSsrICsgIi0iLCAwLCAwXTsNCn0NCg0KY29uc3Qga25vd25UZW1wbGF0ZVJlZnMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtTZXQoKTsNCg0KZnVuY3Rpb24gc2V0UmVmKHJhd1JlZiwgb2xkUmF3UmVmLCBwYXJlbnRTdXNwZW5zZSwgdm5vZGUsIGlzVW5tb3VudCA9IGZhbHNlKSB7DQogIGlmIChpc0FycmF5KHJhd1JlZikpIHsNCiAgICByYXdSZWYuZm9yRWFjaCgNCiAgICAgIChyLCBpKSA9PiBzZXRSZWYoDQogICAgICAgIHIsDQogICAgICAgIG9sZFJhd1JlZiAmJiAoaXNBcnJheShvbGRSYXdSZWYpID8gb2xkUmF3UmVmW2ldIDogb2xkUmF3UmVmKSwNCiAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgIHZub2RlLA0KICAgICAgICBpc1VubW91bnQNCiAgICAgICkNCiAgICApOw0KICAgIHJldHVybjsNCiAgfQ0KICBpZiAoaXNBc3luY1dyYXBwZXIodm5vZGUpICYmICFpc1VubW91bnQpIHsNCiAgICBpZiAodm5vZGUuc2hhcGVGbGFnICYgNTEyICYmIHZub2RlLnR5cGUuX19hc3luY1Jlc29sdmVkICYmIHZub2RlLmNvbXBvbmVudC5zdWJUcmVlLmNvbXBvbmVudCkgew0KICAgICAgc2V0UmVmKHJhd1JlZiwgb2xkUmF3UmVmLCBwYXJlbnRTdXNwZW5zZSwgdm5vZGUuY29tcG9uZW50LnN1YlRyZWUpOw0KICAgIH0NCiAgICByZXR1cm47DQogIH0NCiAgY29uc3QgcmVmVmFsdWUgPSB2bm9kZS5zaGFwZUZsYWcgJiA0ID8gZ2V0Q29tcG9uZW50UHVibGljSW5zdGFuY2Uodm5vZGUuY29tcG9uZW50KSA6IHZub2RlLmVsOw0KICBjb25zdCB2YWx1ZSA9IGlzVW5tb3VudCA/IG51bGwgOiByZWZWYWx1ZTsNCiAgY29uc3QgeyBpOiBvd25lciwgcjogcmVmIH0gPSByYXdSZWY7DQogIGlmICghb3duZXIpIHsNCiAgICB3YXJuJDEoDQogICAgICBgTWlzc2luZyByZWYgb3duZXIgY29udGV4dC4gcmVmIGNhbm5vdCBiZSB1c2VkIG9uIGhvaXN0ZWQgdm5vZGVzLiBBIHZub2RlIHdpdGggcmVmIG11c3QgYmUgY3JlYXRlZCBpbnNpZGUgdGhlIHJlbmRlciBmdW5jdGlvbi5gDQogICAgKTsNCiAgICByZXR1cm47DQogIH0NCiAgY29uc3Qgb2xkUmVmID0gb2xkUmF3UmVmICYmIG9sZFJhd1JlZi5yOw0KICBjb25zdCByZWZzID0gb3duZXIucmVmcyA9PT0gRU1QVFlfT0JKID8gb3duZXIucmVmcyA9IHt9IDogb3duZXIucmVmczsNCiAgY29uc3Qgc2V0dXBTdGF0ZSA9IG93bmVyLnNldHVwU3RhdGU7DQogIGNvbnN0IHJhd1NldHVwU3RhdGUgPSB0b1JhdyhzZXR1cFN0YXRlKTsNCiAgY29uc3QgY2FuU2V0U2V0dXBSZWYgPSBzZXR1cFN0YXRlID09PSBFTVBUWV9PQkogPyAoKSA9PiBmYWxzZSA6IChrZXkpID0+IHsNCiAgICB7DQogICAgICBpZiAoaGFzT3duKHJhd1NldHVwU3RhdGUsIGtleSkgJiYgIWlzUmVmKHJhd1NldHVwU3RhdGVba2V5XSkpIHsNCiAgICAgICAgd2FybiQxKA0KICAgICAgICAgIGBUZW1wbGF0ZSByZWYgIiR7a2V5fSIgdXNlZCBvbiBhIG5vbi1yZWYgdmFsdWUuIEl0IHdpbGwgbm90IHdvcmsgaW4gdGhlIHByb2R1Y3Rpb24gYnVpbGQuYA0KICAgICAgICApOw0KICAgICAgfQ0KICAgICAgaWYgKGtub3duVGVtcGxhdGVSZWZzLmhhcyhyYXdTZXR1cFN0YXRlW2tleV0pKSB7DQogICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAgIH0NCiAgICB9DQogICAgcmV0dXJuIGhhc093bihyYXdTZXR1cFN0YXRlLCBrZXkpOw0KICB9Ow0KICBpZiAob2xkUmVmICE9IG51bGwgJiYgb2xkUmVmICE9PSByZWYpIHsNCiAgICBpZiAoaXNTdHJpbmcob2xkUmVmKSkgew0KICAgICAgcmVmc1tvbGRSZWZdID0gbnVsbDsNCiAgICAgIGlmIChjYW5TZXRTZXR1cFJlZihvbGRSZWYpKSB7DQogICAgICAgIHNldHVwU3RhdGVbb2xkUmVmXSA9IG51bGw7DQogICAgICB9DQogICAgfSBlbHNlIGlmIChpc1JlZihvbGRSZWYpKSB7DQogICAgICBvbGRSZWYudmFsdWUgPSBudWxsOw0KICAgIH0NCiAgfQ0KICBpZiAoaXNGdW5jdGlvbihyZWYpKSB7DQogICAgY2FsbFdpdGhFcnJvckhhbmRsaW5nKHJlZiwgb3duZXIsIDEyLCBbdmFsdWUsIHJlZnNdKTsNCiAgfSBlbHNlIHsNCiAgICBjb25zdCBfaXNTdHJpbmcgPSBpc1N0cmluZyhyZWYpOw0KICAgIGNvbnN0IF9pc1JlZiA9IGlzUmVmKHJlZik7DQogICAgaWYgKF9pc1N0cmluZyB8fCBfaXNSZWYpIHsNCiAgICAgIGNvbnN0IGRvU2V0ID0gKCkgPT4gew0KICAgICAgICBpZiAocmF3UmVmLmYpIHsNCiAgICAgICAgICBjb25zdCBleGlzdGluZyA9IF9pc1N0cmluZyA/IGNhblNldFNldHVwUmVmKHJlZikgPyBzZXR1cFN0YXRlW3JlZl0gOiByZWZzW3JlZl0gOiByZWYudmFsdWU7DQogICAgICAgICAgaWYgKGlzVW5tb3VudCkgew0KICAgICAgICAgICAgaXNBcnJheShleGlzdGluZykgJiYgcmVtb3ZlKGV4aXN0aW5nLCByZWZWYWx1ZSk7DQogICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIGlmICghaXNBcnJheShleGlzdGluZykpIHsNCiAgICAgICAgICAgICAgaWYgKF9pc1N0cmluZykgew0KICAgICAgICAgICAgICAgIHJlZnNbcmVmXSA9IFtyZWZWYWx1ZV07DQogICAgICAgICAgICAgICAgaWYgKGNhblNldFNldHVwUmVmKHJlZikpIHsNCiAgICAgICAgICAgICAgICAgIHNldHVwU3RhdGVbcmVmXSA9IHJlZnNbcmVmXTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgcmVmLnZhbHVlID0gW3JlZlZhbHVlXTsNCiAgICAgICAgICAgICAgICBpZiAocmF3UmVmLmspIHJlZnNbcmF3UmVmLmtdID0gcmVmLnZhbHVlOw0KICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9IGVsc2UgaWYgKCFleGlzdGluZy5pbmNsdWRlcyhyZWZWYWx1ZSkpIHsNCiAgICAgICAgICAgICAgZXhpc3RpbmcucHVzaChyZWZWYWx1ZSk7DQogICAgICAgICAgICB9DQogICAgICAgICAgfQ0KICAgICAgICB9IGVsc2UgaWYgKF9pc1N0cmluZykgew0KICAgICAgICAgIHJlZnNbcmVmXSA9IHZhbHVlOw0KICAgICAgICAgIGlmIChjYW5TZXRTZXR1cFJlZihyZWYpKSB7DQogICAgICAgICAgICBzZXR1cFN0YXRlW3JlZl0gPSB2YWx1ZTsNCiAgICAgICAgICB9DQogICAgICAgIH0gZWxzZSBpZiAoX2lzUmVmKSB7DQogICAgICAgICAgcmVmLnZhbHVlID0gdmFsdWU7DQogICAgICAgICAgaWYgKHJhd1JlZi5rKSByZWZzW3Jhd1JlZi5rXSA9IHZhbHVlOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIHdhcm4kMSgiSW52YWxpZCB0ZW1wbGF0ZSByZWYgdHlwZToiLCByZWYsIGAoJHt0eXBlb2YgcmVmfSlgKTsNCiAgICAgICAgfQ0KICAgICAgfTsNCiAgICAgIGlmICh2YWx1ZSkgew0KICAgICAgICBkb1NldC5pZCA9IC0xOw0KICAgICAgICBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QoZG9TZXQsIHBhcmVudFN1c3BlbnNlKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGRvU2V0KCk7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIHdhcm4kMSgiSW52YWxpZCB0ZW1wbGF0ZSByZWYgdHlwZToiLCByZWYsIGAoJHt0eXBlb2YgcmVmfSlgKTsNCiAgICB9DQogIH0NCn0NCg0KY29uc3QgaXNBc3luY1dyYXBwZXIgPSAoaSkgPT4gISFpLnR5cGUuX19hc3luY0xvYWRlcjsNCg0KY29uc3QgaXNLZWVwQWxpdmUgPSAodm5vZGUpID0+IHZub2RlLnR5cGUuX19pc0tlZXBBbGl2ZTsNCmZ1bmN0aW9uIG9uQWN0aXZhdGVkKGhvb2ssIHRhcmdldCkgew0KICByZWdpc3RlcktlZXBBbGl2ZUhvb2soaG9vaywgImEiLCB0YXJnZXQpOw0KfQ0KZnVuY3Rpb24gb25EZWFjdGl2YXRlZChob29rLCB0YXJnZXQpIHsNCiAgcmVnaXN0ZXJLZWVwQWxpdmVIb29rKGhvb2ssICJkYSIsIHRhcmdldCk7DQp9DQpmdW5jdGlvbiByZWdpc3RlcktlZXBBbGl2ZUhvb2soaG9vaywgdHlwZSwgdGFyZ2V0ID0gY3VycmVudEluc3RhbmNlKSB7DQogIGNvbnN0IHdyYXBwZWRIb29rID0gaG9vay5fX3dkYyB8fCAoaG9vay5fX3dkYyA9ICgpID0+IHsNCiAgICBsZXQgY3VycmVudCA9IHRhcmdldDsNCiAgICB3aGlsZSAoY3VycmVudCkgew0KICAgICAgaWYgKGN1cnJlbnQuaXNEZWFjdGl2YXRlZCkgew0KICAgICAgICByZXR1cm47DQogICAgICB9DQogICAgICBjdXJyZW50ID0gY3VycmVudC5wYXJlbnQ7DQogICAgfQ0KICAgIHJldHVybiBob29rKCk7DQogIH0pOw0KICBpbmplY3RIb29rKHR5cGUsIHdyYXBwZWRIb29rLCB0YXJnZXQpOw0KICBpZiAodGFyZ2V0KSB7DQogICAgbGV0IGN1cnJlbnQgPSB0YXJnZXQucGFyZW50Ow0KICAgIHdoaWxlIChjdXJyZW50ICYmIGN1cnJlbnQucGFyZW50KSB7DQogICAgICBpZiAoaXNLZWVwQWxpdmUoY3VycmVudC5wYXJlbnQudm5vZGUpKSB7DQogICAgICAgIGluamVjdFRvS2VlcEFsaXZlUm9vdCh3cmFwcGVkSG9vaywgdHlwZSwgdGFyZ2V0LCBjdXJyZW50KTsNCiAgICAgIH0NCiAgICAgIGN1cnJlbnQgPSBjdXJyZW50LnBhcmVudDsNCiAgICB9DQogIH0NCn0NCmZ1bmN0aW9uIGluamVjdFRvS2VlcEFsaXZlUm9vdChob29rLCB0eXBlLCB0YXJnZXQsIGtlZXBBbGl2ZVJvb3QpIHsNCiAgY29uc3QgaW5qZWN0ZWQgPSBpbmplY3RIb29rKA0KICAgIHR5cGUsDQogICAgaG9vaywNCiAgICBrZWVwQWxpdmVSb290LA0KICAgIHRydWUNCiAgICAvKiBwcmVwZW5kICovDQogICk7DQogIG9uVW5tb3VudGVkKCgpID0+IHsNCiAgICByZW1vdmUoa2VlcEFsaXZlUm9vdFt0eXBlXSwgaW5qZWN0ZWQpOw0KICB9LCB0YXJnZXQpOw0KfQ0KDQpmdW5jdGlvbiBpbmplY3RIb29rKHR5cGUsIGhvb2ssIHRhcmdldCA9IGN1cnJlbnRJbnN0YW5jZSwgcHJlcGVuZCA9IGZhbHNlKSB7DQogIGlmICh0YXJnZXQpIHsNCiAgICBjb25zdCBob29rcyA9IHRhcmdldFt0eXBlXSB8fCAodGFyZ2V0W3R5cGVdID0gW10pOw0KICAgIGNvbnN0IHdyYXBwZWRIb29rID0gaG9vay5fX3dlaCB8fCAoaG9vay5fX3dlaCA9ICguLi5hcmdzKSA9PiB7DQogICAgICBwYXVzZVRyYWNraW5nKCk7DQogICAgICBjb25zdCByZXNldCA9IHNldEN1cnJlbnRJbnN0YW5jZSh0YXJnZXQpOw0KICAgICAgY29uc3QgcmVzID0gY2FsbFdpdGhBc3luY0Vycm9ySGFuZGxpbmcoaG9vaywgdGFyZ2V0LCB0eXBlLCBhcmdzKTsNCiAgICAgIHJlc2V0KCk7DQogICAgICByZXNldFRyYWNraW5nKCk7DQogICAgICByZXR1cm4gcmVzOw0KICAgIH0pOw0KICAgIGlmIChwcmVwZW5kKSB7DQogICAgICBob29rcy51bnNoaWZ0KHdyYXBwZWRIb29rKTsNCiAgICB9IGVsc2Ugew0KICAgICAgaG9va3MucHVzaCh3cmFwcGVkSG9vayk7DQogICAgfQ0KICAgIHJldHVybiB3cmFwcGVkSG9vazsNCiAgfSBlbHNlIHsNCiAgICBjb25zdCBhcGlOYW1lID0gdG9IYW5kbGVyS2V5KEVycm9yVHlwZVN0cmluZ3NbdHlwZV0ucmVwbGFjZSgvIGhvb2skLywgIiIpKTsNCiAgICB3YXJuJDEoDQogICAgICBgJHthcGlOYW1lfSBpcyBjYWxsZWQgd2hlbiB0aGVyZSBpcyBubyBhY3RpdmUgY29tcG9uZW50IGluc3RhbmNlIHRvIGJlIGFzc29jaWF0ZWQgd2l0aC4gTGlmZWN5Y2xlIGluamVjdGlvbiBBUElzIGNhbiBvbmx5IGJlIHVzZWQgZHVyaW5nIGV4ZWN1dGlvbiBvZiBzZXR1cCgpLmAgKyAoYCBJZiB5b3UgYXJlIHVzaW5nIGFzeW5jIHNldHVwKCksIG1ha2Ugc3VyZSB0byByZWdpc3RlciBsaWZlY3ljbGUgaG9va3MgYmVmb3JlIHRoZSBmaXJzdCBhd2FpdCBzdGF0ZW1lbnQuYCApDQogICAgKTsNCiAgfQ0KfQ0KY29uc3QgY3JlYXRlSG9vayA9IChsaWZlY3ljbGUpID0+IChob29rLCB0YXJnZXQgPSBjdXJyZW50SW5zdGFuY2UpID0+IHsNCiAgaWYgKCFpc0luU1NSQ29tcG9uZW50U2V0dXAgfHwgbGlmZWN5Y2xlID09PSAic3AiKSB7DQogICAgaW5qZWN0SG9vayhsaWZlY3ljbGUsICguLi5hcmdzKSA9PiBob29rKC4uLmFyZ3MpLCB0YXJnZXQpOw0KICB9DQp9Ow0KY29uc3Qgb25CZWZvcmVNb3VudCA9IGNyZWF0ZUhvb2soImJtIik7DQpjb25zdCBvbk1vdW50ZWQgPSBjcmVhdGVIb29rKCJtIik7DQpjb25zdCBvbkJlZm9yZVVwZGF0ZSA9IGNyZWF0ZUhvb2soDQogICJidSINCik7DQpjb25zdCBvblVwZGF0ZWQgPSBjcmVhdGVIb29rKCJ1Iik7DQpjb25zdCBvbkJlZm9yZVVubW91bnQgPSBjcmVhdGVIb29rKA0KICAiYnVtIg0KKTsNCmNvbnN0IG9uVW5tb3VudGVkID0gY3JlYXRlSG9vaygidW0iKTsNCmNvbnN0IG9uU2VydmVyUHJlZmV0Y2ggPSBjcmVhdGVIb29rKA0KICAic3AiDQopOw0KY29uc3Qgb25SZW5kZXJUcmlnZ2VyZWQgPSBjcmVhdGVIb29rKCJydGciKTsNCmNvbnN0IG9uUmVuZGVyVHJhY2tlZCA9IGNyZWF0ZUhvb2soInJ0YyIpOw0KZnVuY3Rpb24gb25FcnJvckNhcHR1cmVkKGhvb2ssIHRhcmdldCA9IGN1cnJlbnRJbnN0YW5jZSkgew0KICBpbmplY3RIb29rKCJlYyIsIGhvb2ssIHRhcmdldCk7DQp9DQoNCmNvbnN0IE5VTExfRFlOQU1JQ19DT01QT05FTlQgPSBTeW1ib2wuZm9yKCJ2LW5kYyIpOw0KDQpmdW5jdGlvbiBlbnN1cmVWYWxpZFZOb2RlJDEodm5vZGVzKSB7DQogIHJldHVybiB2bm9kZXMuc29tZSgoY2hpbGQpID0+IHsNCiAgICBpZiAoIWlzVk5vZGUkMihjaGlsZCkpIHJldHVybiB0cnVlOw0KICAgIGlmIChjaGlsZC50eXBlID09PSBDb21tZW50KSByZXR1cm4gZmFsc2U7DQogICAgaWYgKGNoaWxkLnR5cGUgPT09IEZyYWdtZW50ICYmICFlbnN1cmVWYWxpZFZOb2RlJDEoY2hpbGQuY2hpbGRyZW4pKQ0KICAgICAgcmV0dXJuIGZhbHNlOw0KICAgIHJldHVybiB0cnVlOw0KICB9KSA/IHZub2RlcyA6IG51bGw7DQp9DQoNCmNvbnN0IGdldFB1YmxpY0luc3RhbmNlID0gKGkpID0+IHsNCiAgaWYgKCFpKSByZXR1cm4gbnVsbDsNCiAgaWYgKGlzU3RhdGVmdWxDb21wb25lbnQoaSkpIHJldHVybiBnZXRDb21wb25lbnRQdWJsaWNJbnN0YW5jZShpKTsNCiAgcmV0dXJuIGdldFB1YmxpY0luc3RhbmNlKGkucGFyZW50KTsNCn07DQpjb25zdCBwdWJsaWNQcm9wZXJ0aWVzTWFwID0gKA0KICAvLyBNb3ZlIFBVUkUgbWFya2VyIHRvIG5ldyBsaW5lIHRvIHdvcmthcm91bmQgY29tcGlsZXIgZGlzY2FyZGluZyBpdA0KICAvLyBkdWUgdG8gdHlwZSBhbm5vdGF0aW9uDQogIC8qIEBfX1BVUkVfXyAqLyBleHRlbmQoLyogQF9fUFVSRV9fICovIE9iamVjdC5jcmVhdGUobnVsbCksIHsNCiAgICAkOiAoaSkgPT4gaSwNCiAgICAkZWw6IChpKSA9PiBpLnZub2RlLmVsLA0KICAgICRkYXRhOiAoaSkgPT4gaS5kYXRhLA0KICAgICRwcm9wczogKGkpID0+IHNoYWxsb3dSZWFkb25seShpLnByb3BzKSAsDQogICAgJGF0dHJzOiAoaSkgPT4gc2hhbGxvd1JlYWRvbmx5KGkuYXR0cnMpICwNCiAgICAkc2xvdHM6IChpKSA9PiBzaGFsbG93UmVhZG9ubHkoaS5zbG90cykgLA0KICAgICRyZWZzOiAoaSkgPT4gc2hhbGxvd1JlYWRvbmx5KGkucmVmcykgLA0KICAgICRwYXJlbnQ6IChpKSA9PiBnZXRQdWJsaWNJbnN0YW5jZShpLnBhcmVudCksDQogICAgJHJvb3Q6IChpKSA9PiBnZXRQdWJsaWNJbnN0YW5jZShpLnJvb3QpLA0KICAgICRob3N0OiAoaSkgPT4gaS5jZSwNCiAgICAkZW1pdDogKGkpID0+IGkuZW1pdCwNCiAgICAkb3B0aW9uczogKGkpID0+IHJlc29sdmVNZXJnZWRPcHRpb25zKGkpICwNCiAgICAkZm9yY2VVcGRhdGU6IChpKSA9PiBpLmYgfHwgKGkuZiA9ICgpID0+IHsNCiAgICAgIHF1ZXVlSm9iKGkudXBkYXRlKTsNCiAgICB9KSwNCiAgICAkbmV4dFRpY2s6IChpKSA9PiBpLm4gfHwgKGkubiA9IG5leHRUaWNrLmJpbmQoaS5wcm94eSkpLA0KICAgICR3YXRjaDogKGkpID0+IGluc3RhbmNlV2F0Y2guYmluZChpKSANCiAgfSkNCik7DQpjb25zdCBpc1Jlc2VydmVkUHJlZml4ID0gKGtleSkgPT4ga2V5ID09PSAiXyIgfHwga2V5ID09PSAiJCI7DQpjb25zdCBoYXNTZXR1cEJpbmRpbmcgPSAoc3RhdGUsIGtleSkgPT4gc3RhdGUgIT09IEVNUFRZX09CSiAmJiAhc3RhdGUuX19pc1NjcmlwdFNldHVwICYmIGhhc093bihzdGF0ZSwga2V5KTsNCmNvbnN0IFB1YmxpY0luc3RhbmNlUHJveHlIYW5kbGVycyA9IHsNCiAgZ2V0KHsgXzogaW5zdGFuY2UgfSwga2V5KSB7DQogICAgaWYgKGtleSA9PT0gIl9fdl9za2lwIikgew0KICAgICAgcmV0dXJuIHRydWU7DQogICAgfQ0KICAgIGNvbnN0IHsgY3R4LCBzZXR1cFN0YXRlLCBkYXRhLCBwcm9wcywgYWNjZXNzQ2FjaGUsIHR5cGUsIGFwcENvbnRleHQgfSA9IGluc3RhbmNlOw0KICAgIGlmIChrZXkgPT09ICJfX2lzVnVlIikgew0KICAgICAgcmV0dXJuIHRydWU7DQogICAgfQ0KICAgIGxldCBub3JtYWxpemVkUHJvcHM7DQogICAgaWYgKGtleVswXSAhPT0gIiQiKSB7DQogICAgICBjb25zdCBuID0gYWNjZXNzQ2FjaGVba2V5XTsNCiAgICAgIGlmIChuICE9PSB2b2lkIDApIHsNCiAgICAgICAgc3dpdGNoIChuKSB7DQogICAgICAgICAgY2FzZSAxIC8qIFNFVFVQICovOg0KICAgICAgICAgICAgcmV0dXJuIHNldHVwU3RhdGVba2V5XTsNCiAgICAgICAgICBjYXNlIDIgLyogREFUQSAqLzoNCiAgICAgICAgICAgIHJldHVybiBkYXRhW2tleV07DQogICAgICAgICAgY2FzZSA0IC8qIENPTlRFWFQgKi86DQogICAgICAgICAgICByZXR1cm4gY3R4W2tleV07DQogICAgICAgICAgY2FzZSAzIC8qIFBST1BTICovOg0KICAgICAgICAgICAgcmV0dXJuIHByb3BzW2tleV07DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSBpZiAoaGFzU2V0dXBCaW5kaW5nKHNldHVwU3RhdGUsIGtleSkpIHsNCiAgICAgICAgYWNjZXNzQ2FjaGVba2V5XSA9IDEgLyogU0VUVVAgKi87DQogICAgICAgIHJldHVybiBzZXR1cFN0YXRlW2tleV07DQogICAgICB9IGVsc2UgaWYgKGRhdGEgIT09IEVNUFRZX09CSiAmJiBoYXNPd24oZGF0YSwga2V5KSkgew0KICAgICAgICBhY2Nlc3NDYWNoZVtrZXldID0gMiAvKiBEQVRBICovOw0KICAgICAgICByZXR1cm4gZGF0YVtrZXldOw0KICAgICAgfSBlbHNlIGlmICgNCiAgICAgICAgLy8gb25seSBjYWNoZSBvdGhlciBwcm9wZXJ0aWVzIHdoZW4gaW5zdGFuY2UgaGFzIGRlY2xhcmVkICh0aHVzIHN0YWJsZSkNCiAgICAgICAgLy8gcHJvcHMNCiAgICAgICAgKG5vcm1hbGl6ZWRQcm9wcyA9IGluc3RhbmNlLnByb3BzT3B0aW9uc1swXSkgJiYgaGFzT3duKG5vcm1hbGl6ZWRQcm9wcywga2V5KQ0KICAgICAgKSB7DQogICAgICAgIGFjY2Vzc0NhY2hlW2tleV0gPSAzIC8qIFBST1BTICovOw0KICAgICAgICByZXR1cm4gcHJvcHNba2V5XTsNCiAgICAgIH0gZWxzZSBpZiAoY3R4ICE9PSBFTVBUWV9PQkogJiYgaGFzT3duKGN0eCwga2V5KSkgew0KICAgICAgICBhY2Nlc3NDYWNoZVtrZXldID0gNCAvKiBDT05URVhUICovOw0KICAgICAgICByZXR1cm4gY3R4W2tleV07DQogICAgICB9IGVsc2UgaWYgKHNob3VsZENhY2hlQWNjZXNzKSB7DQogICAgICAgIGFjY2Vzc0NhY2hlW2tleV0gPSAwIC8qIE9USEVSICovOw0KICAgICAgfQ0KICAgIH0NCiAgICBjb25zdCBwdWJsaWNHZXR0ZXIgPSBwdWJsaWNQcm9wZXJ0aWVzTWFwW2tleV07DQogICAgbGV0IGNzc01vZHVsZSwgZ2xvYmFsUHJvcGVydGllczsNCiAgICBpZiAocHVibGljR2V0dGVyKSB7DQogICAgICBpZiAoa2V5ID09PSAiJGF0dHJzIikgew0KICAgICAgICB0cmFjayhpbnN0YW5jZS5hdHRycywgImdldCIsICIiKTsNCiAgICAgICAgbWFya0F0dHJzQWNjZXNzZWQoKTsNCiAgICAgIH0gZWxzZSBpZiAoa2V5ID09PSAiJHNsb3RzIikgew0KICAgICAgICB0cmFjayhpbnN0YW5jZSwgImdldCIsIGtleSk7DQogICAgICB9DQogICAgICByZXR1cm4gcHVibGljR2V0dGVyKGluc3RhbmNlKTsNCiAgICB9IGVsc2UgaWYgKA0KICAgICAgLy8gY3NzIG1vZHVsZSAoaW5qZWN0ZWQgYnkgdnVlLWxvYWRlcikNCiAgICAgIChjc3NNb2R1bGUgPSB0eXBlLl9fY3NzTW9kdWxlcykgJiYgKGNzc01vZHVsZSA9IGNzc01vZHVsZVtrZXldKQ0KICAgICkgew0KICAgICAgcmV0dXJuIGNzc01vZHVsZTsNCiAgICB9IGVsc2UgaWYgKGN0eCAhPT0gRU1QVFlfT0JKICYmIGhhc093bihjdHgsIGtleSkpIHsNCiAgICAgIGFjY2Vzc0NhY2hlW2tleV0gPSA0IC8qIENPTlRFWFQgKi87DQogICAgICByZXR1cm4gY3R4W2tleV07DQogICAgfSBlbHNlIGlmICgNCiAgICAgIC8vIGdsb2JhbCBwcm9wZXJ0aWVzDQogICAgICBnbG9iYWxQcm9wZXJ0aWVzID0gYXBwQ29udGV4dC5jb25maWcuZ2xvYmFsUHJvcGVydGllcywgaGFzT3duKGdsb2JhbFByb3BlcnRpZXMsIGtleSkNCiAgICApIHsNCiAgICAgIHsNCiAgICAgICAgcmV0dXJuIGdsb2JhbFByb3BlcnRpZXNba2V5XTsNCiAgICAgIH0NCiAgICB9IGVsc2UgaWYgKGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSAmJiAoIWlzU3RyaW5nKGtleSkgfHwgLy8gIzEwOTEgYXZvaWQgaW50ZXJuYWwgaXNSZWYvaXNWTm9kZSBjaGVja3Mgb24gY29tcG9uZW50IGluc3RhbmNlIGxlYWRpbmcNCiAgICAvLyB0byBpbmZpbml0ZSB3YXJuaW5nIGxvb3ANCiAgICBrZXkuaW5kZXhPZigiX192IikgIT09IDApKSB7DQogICAgICBpZiAoZGF0YSAhPT0gRU1QVFlfT0JKICYmIGlzUmVzZXJ2ZWRQcmVmaXgoa2V5WzBdKSAmJiBoYXNPd24oZGF0YSwga2V5KSkgew0KICAgICAgICB3YXJuJDEoDQogICAgICAgICAgYFByb3BlcnR5ICR7SlNPTi5zdHJpbmdpZnkoDQogICAgICAgICAgICBrZXkNCiAgICAgICAgICApfSBtdXN0IGJlIGFjY2Vzc2VkIHZpYSAkZGF0YSBiZWNhdXNlIGl0IHN0YXJ0cyB3aXRoIGEgcmVzZXJ2ZWQgY2hhcmFjdGVyICgiJCIgb3IgIl8iKSBhbmQgaXMgbm90IHByb3hpZWQgb24gdGhlIHJlbmRlciBjb250ZXh0LmANCiAgICAgICAgKTsNCiAgICAgIH0gZWxzZSBpZiAoaW5zdGFuY2UgPT09IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSkgew0KICAgICAgICB3YXJuJDEoDQogICAgICAgICAgYFByb3BlcnR5ICR7SlNPTi5zdHJpbmdpZnkoa2V5KX0gd2FzIGFjY2Vzc2VkIGR1cmluZyByZW5kZXIgYnV0IGlzIG5vdCBkZWZpbmVkIG9uIGluc3RhbmNlLmANCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICB9DQogIH0sDQogIHNldCh7IF86IGluc3RhbmNlIH0sIGtleSwgdmFsdWUpIHsNCiAgICBjb25zdCB7IGRhdGEsIHNldHVwU3RhdGUsIGN0eCB9ID0gaW5zdGFuY2U7DQogICAgaWYgKGhhc1NldHVwQmluZGluZyhzZXR1cFN0YXRlLCBrZXkpKSB7DQogICAgICBzZXR1cFN0YXRlW2tleV0gPSB2YWx1ZTsNCiAgICAgIHJldHVybiB0cnVlOw0KICAgIH0gZWxzZSBpZiAoc2V0dXBTdGF0ZS5fX2lzU2NyaXB0U2V0dXAgJiYgaGFzT3duKHNldHVwU3RhdGUsIGtleSkpIHsNCiAgICAgIHdhcm4kMShgQ2Fubm90IG11dGF0ZSA8c2NyaXB0IHNldHVwPiBiaW5kaW5nICIke2tleX0iIGZyb20gT3B0aW9ucyBBUEkuYCk7DQogICAgICByZXR1cm4gZmFsc2U7DQogICAgfSBlbHNlIGlmIChkYXRhICE9PSBFTVBUWV9PQkogJiYgaGFzT3duKGRhdGEsIGtleSkpIHsNCiAgICAgIGRhdGFba2V5XSA9IHZhbHVlOw0KICAgICAgcmV0dXJuIHRydWU7DQogICAgfSBlbHNlIGlmIChoYXNPd24oaW5zdGFuY2UucHJvcHMsIGtleSkpIHsNCiAgICAgIHdhcm4kMShgQXR0ZW1wdGluZyB0byBtdXRhdGUgcHJvcCAiJHtrZXl9Ii4gUHJvcHMgYXJlIHJlYWRvbmx5LmApOw0KICAgICAgcmV0dXJuIGZhbHNlOw0KICAgIH0NCiAgICBpZiAoa2V5WzBdID09PSAiJCIgJiYga2V5LnNsaWNlKDEpIGluIGluc3RhbmNlKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGBBdHRlbXB0aW5nIHRvIG11dGF0ZSBwdWJsaWMgcHJvcGVydHkgIiR7a2V5fSIuIFByb3BlcnRpZXMgc3RhcnRpbmcgd2l0aCAkIGFyZSByZXNlcnZlZCBhbmQgcmVhZG9ubHkuYA0KICAgICAgKTsNCiAgICAgIHJldHVybiBmYWxzZTsNCiAgICB9IGVsc2Ugew0KICAgICAgaWYgKGtleSBpbiBpbnN0YW5jZS5hcHBDb250ZXh0LmNvbmZpZy5nbG9iYWxQcm9wZXJ0aWVzKSB7DQogICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIGtleSwgew0KICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsDQogICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLA0KICAgICAgICAgIHZhbHVlDQogICAgICAgIH0pOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgY3R4W2tleV0gPSB2YWx1ZTsNCiAgICAgIH0NCiAgICB9DQogICAgcmV0dXJuIHRydWU7DQogIH0sDQogIGhhcyh7DQogICAgXzogeyBkYXRhLCBzZXR1cFN0YXRlLCBhY2Nlc3NDYWNoZSwgY3R4LCBhcHBDb250ZXh0LCBwcm9wc09wdGlvbnMgfQ0KICB9LCBrZXkpIHsNCiAgICBsZXQgbm9ybWFsaXplZFByb3BzOw0KICAgIHJldHVybiAhIWFjY2Vzc0NhY2hlW2tleV0gfHwgZGF0YSAhPT0gRU1QVFlfT0JKICYmIGhhc093bihkYXRhLCBrZXkpIHx8IGhhc1NldHVwQmluZGluZyhzZXR1cFN0YXRlLCBrZXkpIHx8IChub3JtYWxpemVkUHJvcHMgPSBwcm9wc09wdGlvbnNbMF0pICYmIGhhc093bihub3JtYWxpemVkUHJvcHMsIGtleSkgfHwgaGFzT3duKGN0eCwga2V5KSB8fCBoYXNPd24ocHVibGljUHJvcGVydGllc01hcCwga2V5KSB8fCBoYXNPd24oYXBwQ29udGV4dC5jb25maWcuZ2xvYmFsUHJvcGVydGllcywga2V5KTsNCiAgfSwNCiAgZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIGRlc2NyaXB0b3IpIHsNCiAgICBpZiAoZGVzY3JpcHRvci5nZXQgIT0gbnVsbCkgew0KICAgICAgdGFyZ2V0Ll8uYWNjZXNzQ2FjaGVba2V5XSA9IDA7DQogICAgfSBlbHNlIGlmIChoYXNPd24oZGVzY3JpcHRvciwgInZhbHVlIikpIHsNCiAgICAgIHRoaXMuc2V0KHRhcmdldCwga2V5LCBkZXNjcmlwdG9yLnZhbHVlLCBudWxsKTsNCiAgICB9DQogICAgcmV0dXJuIFJlZmxlY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIGRlc2NyaXB0b3IpOw0KICB9DQp9Ow0Kew0KICBQdWJsaWNJbnN0YW5jZVByb3h5SGFuZGxlcnMub3duS2V5cyA9ICh0YXJnZXQpID0+IHsNCiAgICB3YXJuJDEoDQogICAgICBgQXZvaWQgYXBwIGxvZ2ljIHRoYXQgcmVsaWVzIG9uIGVudW1lcmF0aW5nIGtleXMgb24gYSBjb21wb25lbnQgaW5zdGFuY2UuIFRoZSBrZXlzIHdpbGwgYmUgZW1wdHkgaW4gcHJvZHVjdGlvbiBtb2RlIHRvIGF2b2lkIHBlcmZvcm1hbmNlIG92ZXJoZWFkLmANCiAgICApOw0KICAgIHJldHVybiBSZWZsZWN0Lm93bktleXModGFyZ2V0KTsNCiAgfTsNCn0NCmZ1bmN0aW9uIGNyZWF0ZURldlJlbmRlckNvbnRleHQoaW5zdGFuY2UpIHsNCiAgY29uc3QgdGFyZ2V0ID0ge307DQogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGBfYCwgew0KICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSwNCiAgICBlbnVtZXJhYmxlOiBmYWxzZSwNCiAgICBnZXQ6ICgpID0+IGluc3RhbmNlDQogIH0pOw0KICBPYmplY3Qua2V5cyhwdWJsaWNQcm9wZXJ0aWVzTWFwKS5mb3JFYWNoKChrZXkpID0+IHsNCiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHsNCiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSwNCiAgICAgIGVudW1lcmFibGU6IGZhbHNlLA0KICAgICAgZ2V0OiAoKSA9PiBwdWJsaWNQcm9wZXJ0aWVzTWFwW2tleV0oaW5zdGFuY2UpLA0KICAgICAgLy8gaW50ZXJjZXB0ZWQgYnkgdGhlIHByb3h5IHNvIG5vIG5lZWQgZm9yIGltcGxlbWVudGF0aW9uLA0KICAgICAgLy8gYnV0IG5lZWRlZCB0byBwcmV2ZW50IHNldCBlcnJvcnMNCiAgICAgIHNldDogTk9PUA0KICAgIH0pOw0KICB9KTsNCiAgcmV0dXJuIHRhcmdldDsNCn0NCmZ1bmN0aW9uIGV4cG9zZVByb3BzT25SZW5kZXJDb250ZXh0KGluc3RhbmNlKSB7DQogIGNvbnN0IHsNCiAgICBjdHgsDQogICAgcHJvcHNPcHRpb25zOiBbcHJvcHNPcHRpb25zXQ0KICB9ID0gaW5zdGFuY2U7DQogIGlmIChwcm9wc09wdGlvbnMpIHsNCiAgICBPYmplY3Qua2V5cyhwcm9wc09wdGlvbnMpLmZvckVhY2goKGtleSkgPT4gew0KICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGN0eCwga2V5LCB7DQogICAgICAgIGVudW1lcmFibGU6IHRydWUsDQogICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSwNCiAgICAgICAgZ2V0OiAoKSA9PiBpbnN0YW5jZS5wcm9wc1trZXldLA0KICAgICAgICBzZXQ6IE5PT1ANCiAgICAgIH0pOw0KICAgIH0pOw0KICB9DQp9DQpmdW5jdGlvbiBleHBvc2VTZXR1cFN0YXRlT25SZW5kZXJDb250ZXh0KGluc3RhbmNlKSB7DQogIGNvbnN0IHsgY3R4LCBzZXR1cFN0YXRlIH0gPSBpbnN0YW5jZTsNCiAgT2JqZWN0LmtleXModG9SYXcoc2V0dXBTdGF0ZSkpLmZvckVhY2goKGtleSkgPT4gew0KICAgIGlmICghc2V0dXBTdGF0ZS5fX2lzU2NyaXB0U2V0dXApIHsNCiAgICAgIGlmIChpc1Jlc2VydmVkUHJlZml4KGtleVswXSkpIHsNCiAgICAgICAgd2FybiQxKA0KICAgICAgICAgIGBzZXR1cCgpIHJldHVybiBwcm9wZXJ0eSAke0pTT04uc3RyaW5naWZ5KA0KICAgICAgICAgICAga2V5DQogICAgICAgICAgKX0gc2hvdWxkIG5vdCBzdGFydCB3aXRoICIkIiBvciAiXyIgd2hpY2ggYXJlIHJlc2VydmVkIHByZWZpeGVzIGZvciBWdWUgaW50ZXJuYWxzLmANCiAgICAgICAgKTsNCiAgICAgICAgcmV0dXJuOw0KICAgICAgfQ0KICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGN0eCwga2V5LCB7DQogICAgICAgIGVudW1lcmFibGU6IHRydWUsDQogICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSwNCiAgICAgICAgZ2V0OiAoKSA9PiBzZXR1cFN0YXRlW2tleV0sDQogICAgICAgIHNldDogTk9PUA0KICAgICAgfSk7DQogICAgfQ0KICB9KTsNCn0NCg0KZnVuY3Rpb24gbm9ybWFsaXplUHJvcHNPckVtaXRzKHByb3BzKSB7DQogIHJldHVybiBpc0FycmF5KHByb3BzKSA/IHByb3BzLnJlZHVjZSgNCiAgICAobm9ybWFsaXplZCwgcCkgPT4gKG5vcm1hbGl6ZWRbcF0gPSBudWxsLCBub3JtYWxpemVkKSwNCiAgICB7fQ0KICApIDogcHJvcHM7DQp9DQoNCmZ1bmN0aW9uIGNyZWF0ZUR1cGxpY2F0ZUNoZWNrZXIoKSB7DQogIGNvbnN0IGNhY2hlID0gLyogQF9fUFVSRV9fICovIE9iamVjdC5jcmVhdGUobnVsbCk7DQogIHJldHVybiAodHlwZSwga2V5KSA9PiB7DQogICAgaWYgKGNhY2hlW2tleV0pIHsNCiAgICAgIHdhcm4kMShgJHt0eXBlfSBwcm9wZXJ0eSAiJHtrZXl9IiBpcyBhbHJlYWR5IGRlZmluZWQgaW4gJHtjYWNoZVtrZXldfS5gKTsNCiAgICB9IGVsc2Ugew0KICAgICAgY2FjaGVba2V5XSA9IHR5cGU7DQogICAgfQ0KICB9Ow0KfQ0KbGV0IHNob3VsZENhY2hlQWNjZXNzID0gdHJ1ZTsNCmZ1bmN0aW9uIGFwcGx5T3B0aW9ucyhpbnN0YW5jZSkgew0KICBjb25zdCBvcHRpb25zID0gcmVzb2x2ZU1lcmdlZE9wdGlvbnMoaW5zdGFuY2UpOw0KICBjb25zdCBwdWJsaWNUaGlzID0gaW5zdGFuY2UucHJveHk7DQogIGNvbnN0IGN0eCA9IGluc3RhbmNlLmN0eDsNCiAgc2hvdWxkQ2FjaGVBY2Nlc3MgPSBmYWxzZTsNCiAgaWYgKG9wdGlvbnMuYmVmb3JlQ3JlYXRlKSB7DQogICAgY2FsbEhvb2sob3B0aW9ucy5iZWZvcmVDcmVhdGUsIGluc3RhbmNlLCAiYmMiKTsNCiAgfQ0KICBjb25zdCB7DQogICAgLy8gc3RhdGUNCiAgICBkYXRhOiBkYXRhT3B0aW9ucywNCiAgICBjb21wdXRlZDogY29tcHV0ZWRPcHRpb25zLA0KICAgIG1ldGhvZHMsDQogICAgd2F0Y2g6IHdhdGNoT3B0aW9ucywNCiAgICBwcm92aWRlOiBwcm92aWRlT3B0aW9ucywNCiAgICBpbmplY3Q6IGluamVjdE9wdGlvbnMsDQogICAgLy8gbGlmZWN5Y2xlDQogICAgY3JlYXRlZCwNCiAgICBiZWZvcmVNb3VudCwNCiAgICBtb3VudGVkLA0KICAgIGJlZm9yZVVwZGF0ZSwNCiAgICB1cGRhdGVkLA0KICAgIGFjdGl2YXRlZCwNCiAgICBkZWFjdGl2YXRlZCwNCiAgICBiZWZvcmVEZXN0cm95LA0KICAgIGJlZm9yZVVubW91bnQsDQogICAgZGVzdHJveWVkLA0KICAgIHVubW91bnRlZCwNCiAgICByZW5kZXIsDQogICAgcmVuZGVyVHJhY2tlZCwNCiAgICByZW5kZXJUcmlnZ2VyZWQsDQogICAgZXJyb3JDYXB0dXJlZCwNCiAgICBzZXJ2ZXJQcmVmZXRjaCwNCiAgICAvLyBwdWJsaWMgQVBJDQogICAgZXhwb3NlLA0KICAgIGluaGVyaXRBdHRycywNCiAgICAvLyBhc3NldHMNCiAgICBjb21wb25lbnRzLA0KICAgIGRpcmVjdGl2ZXMsDQogICAgZmlsdGVycw0KICB9ID0gb3B0aW9uczsNCiAgY29uc3QgY2hlY2tEdXBsaWNhdGVQcm9wZXJ0aWVzID0gY3JlYXRlRHVwbGljYXRlQ2hlY2tlcigpIDsNCiAgew0KICAgIGNvbnN0IFtwcm9wc09wdGlvbnNdID0gaW5zdGFuY2UucHJvcHNPcHRpb25zOw0KICAgIGlmIChwcm9wc09wdGlvbnMpIHsNCiAgICAgIGZvciAoY29uc3Qga2V5IGluIHByb3BzT3B0aW9ucykgew0KICAgICAgICBjaGVja0R1cGxpY2F0ZVByb3BlcnRpZXMoIlByb3BzIiAvKiBQUk9QUyAqLywga2V5KTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgaWYgKGluamVjdE9wdGlvbnMpIHsNCiAgICByZXNvbHZlSW5qZWN0aW9ucyhpbmplY3RPcHRpb25zLCBjdHgsIGNoZWNrRHVwbGljYXRlUHJvcGVydGllcyk7DQogIH0NCiAgaWYgKG1ldGhvZHMpIHsNCiAgICBmb3IgKGNvbnN0IGtleSBpbiBtZXRob2RzKSB7DQogICAgICBjb25zdCBtZXRob2RIYW5kbGVyID0gbWV0aG9kc1trZXldOw0KICAgICAgaWYgKGlzRnVuY3Rpb24obWV0aG9kSGFuZGxlcikpIHsNCiAgICAgICAgew0KICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIGtleSwgew0KICAgICAgICAgICAgdmFsdWU6IG1ldGhvZEhhbmRsZXIuYmluZChwdWJsaWNUaGlzKSwNCiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSwNCiAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsDQogICAgICAgICAgICB3cml0YWJsZTogdHJ1ZQ0KICAgICAgICAgIH0pOw0KICAgICAgICB9DQogICAgICAgIHsNCiAgICAgICAgICBjaGVja0R1cGxpY2F0ZVByb3BlcnRpZXMoIk1ldGhvZHMiIC8qIE1FVEhPRFMgKi8sIGtleSk7DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHdhcm4kMSgNCiAgICAgICAgICBgTWV0aG9kICIke2tleX0iIGhhcyB0eXBlICIke3R5cGVvZiBtZXRob2RIYW5kbGVyfSIgaW4gdGhlIGNvbXBvbmVudCBkZWZpbml0aW9uLiBEaWQgeW91IHJlZmVyZW5jZSB0aGUgZnVuY3Rpb24gY29ycmVjdGx5P2ANCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgaWYgKGRhdGFPcHRpb25zKSB7DQogICAgaWYgKCFpc0Z1bmN0aW9uKGRhdGFPcHRpb25zKSkgew0KICAgICAgd2FybiQxKA0KICAgICAgICBgVGhlIGRhdGEgb3B0aW9uIG11c3QgYmUgYSBmdW5jdGlvbi4gUGxhaW4gb2JqZWN0IHVzYWdlIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWQuYA0KICAgICAgKTsNCiAgICB9DQogICAgY29uc3QgZGF0YSA9IGRhdGFPcHRpb25zLmNhbGwocHVibGljVGhpcywgcHVibGljVGhpcyk7DQogICAgaWYgKGlzUHJvbWlzZShkYXRhKSkgew0KICAgICAgd2FybiQxKA0KICAgICAgICBgZGF0YSgpIHJldHVybmVkIGEgUHJvbWlzZSAtIG5vdGUgZGF0YSgpIGNhbm5vdCBiZSBhc3luYzsgSWYgeW91IGludGVuZCB0byBwZXJmb3JtIGRhdGEgZmV0Y2hpbmcgYmVmb3JlIGNvbXBvbmVudCByZW5kZXJzLCB1c2UgYXN5bmMgc2V0dXAoKSArIDxTdXNwZW5zZT4uYA0KICAgICAgKTsNCiAgICB9DQogICAgaWYgKCFpc09iamVjdChkYXRhKSkgew0KICAgICAgd2FybiQxKGBkYXRhKCkgc2hvdWxkIHJldHVybiBhbiBvYmplY3QuYCk7DQogICAgfSBlbHNlIHsNCiAgICAgIGluc3RhbmNlLmRhdGEgPSByZWFjdGl2ZShkYXRhKTsNCiAgICAgIHsNCiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gZGF0YSkgew0KICAgICAgICAgIGNoZWNrRHVwbGljYXRlUHJvcGVydGllcygiRGF0YSIgLyogREFUQSAqLywga2V5KTsNCiAgICAgICAgICBpZiAoIWlzUmVzZXJ2ZWRQcmVmaXgoa2V5WzBdKSkgew0KICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGN0eCwga2V5LCB7DQogICAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSwNCiAgICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSwNCiAgICAgICAgICAgICAgZ2V0OiAoKSA9PiBkYXRhW2tleV0sDQogICAgICAgICAgICAgIHNldDogTk9PUA0KICAgICAgICAgICAgfSk7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICB9DQogIHNob3VsZENhY2hlQWNjZXNzID0gdHJ1ZTsNCiAgaWYgKGNvbXB1dGVkT3B0aW9ucykgew0KICAgIGZvciAoY29uc3Qga2V5IGluIGNvbXB1dGVkT3B0aW9ucykgew0KICAgICAgY29uc3Qgb3B0ID0gY29tcHV0ZWRPcHRpb25zW2tleV07DQogICAgICBjb25zdCBnZXQgPSBpc0Z1bmN0aW9uKG9wdCkgPyBvcHQuYmluZChwdWJsaWNUaGlzLCBwdWJsaWNUaGlzKSA6IGlzRnVuY3Rpb24ob3B0LmdldCkgPyBvcHQuZ2V0LmJpbmQocHVibGljVGhpcywgcHVibGljVGhpcykgOiBOT09QOw0KICAgICAgaWYgKGdldCA9PT0gTk9PUCkgew0KICAgICAgICB3YXJuJDEoYENvbXB1dGVkIHByb3BlcnR5ICIke2tleX0iIGhhcyBubyBnZXR0ZXIuYCk7DQogICAgICB9DQogICAgICBjb25zdCBzZXQgPSAhaXNGdW5jdGlvbihvcHQpICYmIGlzRnVuY3Rpb24ob3B0LnNldCkgPyBvcHQuc2V0LmJpbmQocHVibGljVGhpcykgOiAoKSA9PiB7DQogICAgICAgIHdhcm4kMSgNCiAgICAgICAgICBgV3JpdGUgb3BlcmF0aW9uIGZhaWxlZDogY29tcHV0ZWQgcHJvcGVydHkgIiR7a2V5fSIgaXMgcmVhZG9ubHkuYA0KICAgICAgICApOw0KICAgICAgfSA7DQogICAgICBjb25zdCBjID0gY29tcHV0ZWQoew0KICAgICAgICBnZXQsDQogICAgICAgIHNldA0KICAgICAgfSk7DQogICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY3R4LCBrZXksIHsNCiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSwNCiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLA0KICAgICAgICBnZXQ6ICgpID0+IGMudmFsdWUsDQogICAgICAgIHNldDogKHYpID0+IGMudmFsdWUgPSB2DQogICAgICB9KTsNCiAgICAgIHsNCiAgICAgICAgY2hlY2tEdXBsaWNhdGVQcm9wZXJ0aWVzKCJDb21wdXRlZCIgLyogQ09NUFVURUQgKi8sIGtleSk7DQogICAgICB9DQogICAgfQ0KICB9DQogIGlmICh3YXRjaE9wdGlvbnMpIHsNCiAgICBmb3IgKGNvbnN0IGtleSBpbiB3YXRjaE9wdGlvbnMpIHsNCiAgICAgIGNyZWF0ZVdhdGNoZXIod2F0Y2hPcHRpb25zW2tleV0sIGN0eCwgcHVibGljVGhpcywga2V5KTsNCiAgICB9DQogIH0NCiAgaWYgKHByb3ZpZGVPcHRpb25zKSB7DQogICAgY29uc3QgcHJvdmlkZXMgPSBpc0Z1bmN0aW9uKHByb3ZpZGVPcHRpb25zKSA/IHByb3ZpZGVPcHRpb25zLmNhbGwocHVibGljVGhpcykgOiBwcm92aWRlT3B0aW9uczsNCiAgICBSZWZsZWN0Lm93bktleXMocHJvdmlkZXMpLmZvckVhY2goKGtleSkgPT4gew0KICAgICAgcHJvdmlkZShrZXksIHByb3ZpZGVzW2tleV0pOw0KICAgIH0pOw0KICB9DQogIGlmIChjcmVhdGVkKSB7DQogICAgY2FsbEhvb2soY3JlYXRlZCwgaW5zdGFuY2UsICJjIik7DQogIH0NCiAgZnVuY3Rpb24gcmVnaXN0ZXJMaWZlY3ljbGVIb29rKHJlZ2lzdGVyLCBob29rKSB7DQogICAgaWYgKGlzQXJyYXkoaG9vaykpIHsNCiAgICAgIGhvb2suZm9yRWFjaCgoX2hvb2spID0+IHJlZ2lzdGVyKF9ob29rLmJpbmQocHVibGljVGhpcykpKTsNCiAgICB9IGVsc2UgaWYgKGhvb2spIHsNCiAgICAgIHJlZ2lzdGVyKGhvb2suYmluZChwdWJsaWNUaGlzKSk7DQogICAgfQ0KICB9DQogIHJlZ2lzdGVyTGlmZWN5Y2xlSG9vayhvbkJlZm9yZU1vdW50LCBiZWZvcmVNb3VudCk7DQogIHJlZ2lzdGVyTGlmZWN5Y2xlSG9vayhvbk1vdW50ZWQsIG1vdW50ZWQpOw0KICByZWdpc3RlckxpZmVjeWNsZUhvb2sob25CZWZvcmVVcGRhdGUsIGJlZm9yZVVwZGF0ZSk7DQogIHJlZ2lzdGVyTGlmZWN5Y2xlSG9vayhvblVwZGF0ZWQsIHVwZGF0ZWQpOw0KICByZWdpc3RlckxpZmVjeWNsZUhvb2sob25BY3RpdmF0ZWQsIGFjdGl2YXRlZCk7DQogIHJlZ2lzdGVyTGlmZWN5Y2xlSG9vayhvbkRlYWN0aXZhdGVkLCBkZWFjdGl2YXRlZCk7DQogIHJlZ2lzdGVyTGlmZWN5Y2xlSG9vayhvbkVycm9yQ2FwdHVyZWQsIGVycm9yQ2FwdHVyZWQpOw0KICByZWdpc3RlckxpZmVjeWNsZUhvb2sob25SZW5kZXJUcmFja2VkLCByZW5kZXJUcmFja2VkKTsNCiAgcmVnaXN0ZXJMaWZlY3ljbGVIb29rKG9uUmVuZGVyVHJpZ2dlcmVkLCByZW5kZXJUcmlnZ2VyZWQpOw0KICByZWdpc3RlckxpZmVjeWNsZUhvb2sob25CZWZvcmVVbm1vdW50LCBiZWZvcmVVbm1vdW50KTsNCiAgcmVnaXN0ZXJMaWZlY3ljbGVIb29rKG9uVW5tb3VudGVkLCB1bm1vdW50ZWQpOw0KICByZWdpc3RlckxpZmVjeWNsZUhvb2sob25TZXJ2ZXJQcmVmZXRjaCwgc2VydmVyUHJlZmV0Y2gpOw0KICBpZiAoaXNBcnJheShleHBvc2UpKSB7DQogICAgaWYgKGV4cG9zZS5sZW5ndGgpIHsNCiAgICAgIGNvbnN0IGV4cG9zZWQgPSBpbnN0YW5jZS5leHBvc2VkIHx8IChpbnN0YW5jZS5leHBvc2VkID0ge30pOw0KICAgICAgZXhwb3NlLmZvckVhY2goKGtleSkgPT4gew0KICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3NlZCwga2V5LCB7DQogICAgICAgICAgZ2V0OiAoKSA9PiBwdWJsaWNUaGlzW2tleV0sDQogICAgICAgICAgc2V0OiAodmFsKSA9PiBwdWJsaWNUaGlzW2tleV0gPSB2YWwNCiAgICAgICAgfSk7DQogICAgICB9KTsNCiAgICB9IGVsc2UgaWYgKCFpbnN0YW5jZS5leHBvc2VkKSB7DQogICAgICBpbnN0YW5jZS5leHBvc2VkID0ge307DQogICAgfQ0KICB9DQogIGlmIChyZW5kZXIgJiYgaW5zdGFuY2UucmVuZGVyID09PSBOT09QKSB7DQogICAgaW5zdGFuY2UucmVuZGVyID0gcmVuZGVyOw0KICB9DQogIGlmIChpbmhlcml0QXR0cnMgIT0gbnVsbCkgew0KICAgIGluc3RhbmNlLmluaGVyaXRBdHRycyA9IGluaGVyaXRBdHRyczsNCiAgfQ0KICBpZiAoY29tcG9uZW50cykgaW5zdGFuY2UuY29tcG9uZW50cyA9IGNvbXBvbmVudHM7DQogIGlmIChkaXJlY3RpdmVzKSBpbnN0YW5jZS5kaXJlY3RpdmVzID0gZGlyZWN0aXZlczsNCiAgaWYgKHNlcnZlclByZWZldGNoKSB7DQogICAgbWFya0FzeW5jQm91bmRhcnkoaW5zdGFuY2UpOw0KICB9DQp9DQpmdW5jdGlvbiByZXNvbHZlSW5qZWN0aW9ucyhpbmplY3RPcHRpb25zLCBjdHgsIGNoZWNrRHVwbGljYXRlUHJvcGVydGllcyA9IE5PT1ApIHsNCiAgaWYgKGlzQXJyYXkoaW5qZWN0T3B0aW9ucykpIHsNCiAgICBpbmplY3RPcHRpb25zID0gbm9ybWFsaXplSW5qZWN0KGluamVjdE9wdGlvbnMpOw0KICB9DQogIGZvciAoY29uc3Qga2V5IGluIGluamVjdE9wdGlvbnMpIHsNCiAgICBjb25zdCBvcHQgPSBpbmplY3RPcHRpb25zW2tleV07DQogICAgbGV0IGluamVjdGVkOw0KICAgIGlmIChpc09iamVjdChvcHQpKSB7DQogICAgICBpZiAoImRlZmF1bHQiIGluIG9wdCkgew0KICAgICAgICBpbmplY3RlZCA9IGluamVjdCgNCiAgICAgICAgICBvcHQuZnJvbSB8fCBrZXksDQogICAgICAgICAgb3B0LmRlZmF1bHQsDQogICAgICAgICAgdHJ1ZQ0KICAgICAgICApOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgaW5qZWN0ZWQgPSBpbmplY3Qob3B0LmZyb20gfHwga2V5KTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgaW5qZWN0ZWQgPSBpbmplY3Qob3B0KTsNCiAgICB9DQogICAgaWYgKGlzUmVmKGluamVjdGVkKSkgew0KICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGN0eCwga2V5LCB7DQogICAgICAgIGVudW1lcmFibGU6IHRydWUsDQogICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSwNCiAgICAgICAgZ2V0OiAoKSA9PiBpbmplY3RlZC52YWx1ZSwNCiAgICAgICAgc2V0OiAodikgPT4gaW5qZWN0ZWQudmFsdWUgPSB2DQogICAgICB9KTsNCiAgICB9IGVsc2Ugew0KICAgICAgY3R4W2tleV0gPSBpbmplY3RlZDsNCiAgICB9DQogICAgew0KICAgICAgY2hlY2tEdXBsaWNhdGVQcm9wZXJ0aWVzKCJJbmplY3QiIC8qIElOSkVDVCAqLywga2V5KTsNCiAgICB9DQogIH0NCn0NCmZ1bmN0aW9uIGNhbGxIb29rKGhvb2ssIGluc3RhbmNlLCB0eXBlKSB7DQogIGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nKA0KICAgIGlzQXJyYXkoaG9vaykgPyBob29rLm1hcCgoaCkgPT4gaC5iaW5kKGluc3RhbmNlLnByb3h5KSkgOiBob29rLmJpbmQoaW5zdGFuY2UucHJveHkpLA0KICAgIGluc3RhbmNlLA0KICAgIHR5cGUNCiAgKTsNCn0NCmZ1bmN0aW9uIGNyZWF0ZVdhdGNoZXIocmF3LCBjdHgsIHB1YmxpY1RoaXMsIGtleSkgew0KICBsZXQgZ2V0dGVyID0ga2V5LmluY2x1ZGVzKCIuIikgPyBjcmVhdGVQYXRoR2V0dGVyKHB1YmxpY1RoaXMsIGtleSkgOiAoKSA9PiBwdWJsaWNUaGlzW2tleV07DQogIGlmIChpc1N0cmluZyhyYXcpKSB7DQogICAgY29uc3QgaGFuZGxlciA9IGN0eFtyYXddOw0KICAgIGlmIChpc0Z1bmN0aW9uKGhhbmRsZXIpKSB7DQogICAgICB7DQogICAgICAgIHdhdGNoKGdldHRlciwgaGFuZGxlcik7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIHdhcm4kMShgSW52YWxpZCB3YXRjaCBoYW5kbGVyIHNwZWNpZmllZCBieSBrZXkgIiR7cmF3fSJgLCBoYW5kbGVyKTsNCiAgICB9DQogIH0gZWxzZSBpZiAoaXNGdW5jdGlvbihyYXcpKSB7DQogICAgew0KICAgICAgd2F0Y2goZ2V0dGVyLCByYXcuYmluZChwdWJsaWNUaGlzKSk7DQogICAgfQ0KICB9IGVsc2UgaWYgKGlzT2JqZWN0KHJhdykpIHsNCiAgICBpZiAoaXNBcnJheShyYXcpKSB7DQogICAgICByYXcuZm9yRWFjaCgocikgPT4gY3JlYXRlV2F0Y2hlcihyLCBjdHgsIHB1YmxpY1RoaXMsIGtleSkpOw0KICAgIH0gZWxzZSB7DQogICAgICBjb25zdCBoYW5kbGVyID0gaXNGdW5jdGlvbihyYXcuaGFuZGxlcikgPyByYXcuaGFuZGxlci5iaW5kKHB1YmxpY1RoaXMpIDogY3R4W3Jhdy5oYW5kbGVyXTsNCiAgICAgIGlmIChpc0Z1bmN0aW9uKGhhbmRsZXIpKSB7DQogICAgICAgIHdhdGNoKGdldHRlciwgaGFuZGxlciwgcmF3KTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHdhcm4kMShgSW52YWxpZCB3YXRjaCBoYW5kbGVyIHNwZWNpZmllZCBieSBrZXkgIiR7cmF3LmhhbmRsZXJ9ImAsIGhhbmRsZXIpOw0KICAgICAgfQ0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICB3YXJuJDEoYEludmFsaWQgd2F0Y2ggb3B0aW9uOiAiJHtrZXl9ImAsIHJhdyk7DQogIH0NCn0NCmZ1bmN0aW9uIHJlc29sdmVNZXJnZWRPcHRpb25zKGluc3RhbmNlKSB7DQogIGNvbnN0IGJhc2UgPSBpbnN0YW5jZS50eXBlOw0KICBjb25zdCB7IG1peGlucywgZXh0ZW5kczogZXh0ZW5kc09wdGlvbnMgfSA9IGJhc2U7DQogIGNvbnN0IHsNCiAgICBtaXhpbnM6IGdsb2JhbE1peGlucywNCiAgICBvcHRpb25zQ2FjaGU6IGNhY2hlLA0KICAgIGNvbmZpZzogeyBvcHRpb25NZXJnZVN0cmF0ZWdpZXMgfQ0KICB9ID0gaW5zdGFuY2UuYXBwQ29udGV4dDsNCiAgY29uc3QgY2FjaGVkID0gY2FjaGUuZ2V0KGJhc2UpOw0KICBsZXQgcmVzb2x2ZWQ7DQogIGlmIChjYWNoZWQpIHsNCiAgICByZXNvbHZlZCA9IGNhY2hlZDsNCiAgfSBlbHNlIGlmICghZ2xvYmFsTWl4aW5zLmxlbmd0aCAmJiAhbWl4aW5zICYmICFleHRlbmRzT3B0aW9ucykgew0KICAgIHsNCiAgICAgIHJlc29sdmVkID0gYmFzZTsNCiAgICB9DQogIH0gZWxzZSB7DQogICAgcmVzb2x2ZWQgPSB7fTsNCiAgICBpZiAoZ2xvYmFsTWl4aW5zLmxlbmd0aCkgew0KICAgICAgZ2xvYmFsTWl4aW5zLmZvckVhY2goDQogICAgICAgIChtKSA9PiBtZXJnZU9wdGlvbnMocmVzb2x2ZWQsIG0sIG9wdGlvbk1lcmdlU3RyYXRlZ2llcywgdHJ1ZSkNCiAgICAgICk7DQogICAgfQ0KICAgIG1lcmdlT3B0aW9ucyhyZXNvbHZlZCwgYmFzZSwgb3B0aW9uTWVyZ2VTdHJhdGVnaWVzKTsNCiAgfQ0KICBpZiAoaXNPYmplY3QoYmFzZSkpIHsNCiAgICBjYWNoZS5zZXQoYmFzZSwgcmVzb2x2ZWQpOw0KICB9DQogIHJldHVybiByZXNvbHZlZDsNCn0NCmZ1bmN0aW9uIG1lcmdlT3B0aW9ucyh0bywgZnJvbSwgc3RyYXRzLCBhc01peGluID0gZmFsc2UpIHsNCiAgY29uc3QgeyBtaXhpbnMsIGV4dGVuZHM6IGV4dGVuZHNPcHRpb25zIH0gPSBmcm9tOw0KICBpZiAoZXh0ZW5kc09wdGlvbnMpIHsNCiAgICBtZXJnZU9wdGlvbnModG8sIGV4dGVuZHNPcHRpb25zLCBzdHJhdHMsIHRydWUpOw0KICB9DQogIGlmIChtaXhpbnMpIHsNCiAgICBtaXhpbnMuZm9yRWFjaCgNCiAgICAgIChtKSA9PiBtZXJnZU9wdGlvbnModG8sIG0sIHN0cmF0cywgdHJ1ZSkNCiAgICApOw0KICB9DQogIGZvciAoY29uc3Qga2V5IGluIGZyb20pIHsNCiAgICBpZiAoYXNNaXhpbiAmJiBrZXkgPT09ICJleHBvc2UiKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGAiZXhwb3NlIiBvcHRpb24gaXMgaWdub3JlZCB3aGVuIGRlY2xhcmVkIGluIG1peGlucyBvciBleHRlbmRzLiBJdCBzaG91bGQgb25seSBiZSBkZWNsYXJlZCBpbiB0aGUgYmFzZSBjb21wb25lbnQgaXRzZWxmLmANCiAgICAgICk7DQogICAgfSBlbHNlIHsNCiAgICAgIGNvbnN0IHN0cmF0ID0gaW50ZXJuYWxPcHRpb25NZXJnZVN0cmF0c1trZXldIHx8IHN0cmF0cyAmJiBzdHJhdHNba2V5XTsNCiAgICAgIHRvW2tleV0gPSBzdHJhdCA/IHN0cmF0KHRvW2tleV0sIGZyb21ba2V5XSkgOiBmcm9tW2tleV07DQogICAgfQ0KICB9DQogIHJldHVybiB0bzsNCn0NCmNvbnN0IGludGVybmFsT3B0aW9uTWVyZ2VTdHJhdHMgPSB7DQogIGRhdGE6IG1lcmdlRGF0YUZuLA0KICBwcm9wczogbWVyZ2VFbWl0c09yUHJvcHNPcHRpb25zLA0KICBlbWl0czogbWVyZ2VFbWl0c09yUHJvcHNPcHRpb25zLA0KICAvLyBvYmplY3RzDQogIG1ldGhvZHM6IG1lcmdlT2JqZWN0T3B0aW9ucywNCiAgY29tcHV0ZWQ6IG1lcmdlT2JqZWN0T3B0aW9ucywNCiAgLy8gbGlmZWN5Y2xlDQogIGJlZm9yZUNyZWF0ZTogbWVyZ2VBc0FycmF5LA0KICBjcmVhdGVkOiBtZXJnZUFzQXJyYXksDQogIGJlZm9yZU1vdW50OiBtZXJnZUFzQXJyYXksDQogIG1vdW50ZWQ6IG1lcmdlQXNBcnJheSwNCiAgYmVmb3JlVXBkYXRlOiBtZXJnZUFzQXJyYXksDQogIHVwZGF0ZWQ6IG1lcmdlQXNBcnJheSwNCiAgYmVmb3JlRGVzdHJveTogbWVyZ2VBc0FycmF5LA0KICBiZWZvcmVVbm1vdW50OiBtZXJnZUFzQXJyYXksDQogIGRlc3Ryb3llZDogbWVyZ2VBc0FycmF5LA0KICB1bm1vdW50ZWQ6IG1lcmdlQXNBcnJheSwNCiAgYWN0aXZhdGVkOiBtZXJnZUFzQXJyYXksDQogIGRlYWN0aXZhdGVkOiBtZXJnZUFzQXJyYXksDQogIGVycm9yQ2FwdHVyZWQ6IG1lcmdlQXNBcnJheSwNCiAgc2VydmVyUHJlZmV0Y2g6IG1lcmdlQXNBcnJheSwNCiAgLy8gYXNzZXRzDQogIGNvbXBvbmVudHM6IG1lcmdlT2JqZWN0T3B0aW9ucywNCiAgZGlyZWN0aXZlczogbWVyZ2VPYmplY3RPcHRpb25zLA0KICAvLyB3YXRjaA0KICB3YXRjaDogbWVyZ2VXYXRjaE9wdGlvbnMsDQogIC8vIHByb3ZpZGUgLyBpbmplY3QNCiAgcHJvdmlkZTogbWVyZ2VEYXRhRm4sDQogIGluamVjdDogbWVyZ2VJbmplY3QNCn07DQpmdW5jdGlvbiBtZXJnZURhdGFGbih0bywgZnJvbSkgew0KICBpZiAoIWZyb20pIHsNCiAgICByZXR1cm4gdG87DQogIH0NCiAgaWYgKCF0bykgew0KICAgIHJldHVybiBmcm9tOw0KICB9DQogIHJldHVybiBmdW5jdGlvbiBtZXJnZWREYXRhRm4oKSB7DQogICAgcmV0dXJuIChleHRlbmQpKA0KICAgICAgaXNGdW5jdGlvbih0bykgPyB0by5jYWxsKHRoaXMsIHRoaXMpIDogdG8sDQogICAgICBpc0Z1bmN0aW9uKGZyb20pID8gZnJvbS5jYWxsKHRoaXMsIHRoaXMpIDogZnJvbQ0KICAgICk7DQogIH07DQp9DQpmdW5jdGlvbiBtZXJnZUluamVjdCh0bywgZnJvbSkgew0KICByZXR1cm4gbWVyZ2VPYmplY3RPcHRpb25zKG5vcm1hbGl6ZUluamVjdCh0byksIG5vcm1hbGl6ZUluamVjdChmcm9tKSk7DQp9DQpmdW5jdGlvbiBub3JtYWxpemVJbmplY3QocmF3KSB7DQogIGlmIChpc0FycmF5KHJhdykpIHsNCiAgICBjb25zdCByZXMgPSB7fTsNCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhdy5sZW5ndGg7IGkrKykgew0KICAgICAgcmVzW3Jhd1tpXV0gPSByYXdbaV07DQogICAgfQ0KICAgIHJldHVybiByZXM7DQogIH0NCiAgcmV0dXJuIHJhdzsNCn0NCmZ1bmN0aW9uIG1lcmdlQXNBcnJheSh0bywgZnJvbSkgew0KICByZXR1cm4gdG8gPyBbLi4ubmV3IFNldChbXS5jb25jYXQodG8sIGZyb20pKV0gOiBmcm9tOw0KfQ0KZnVuY3Rpb24gbWVyZ2VPYmplY3RPcHRpb25zKHRvLCBmcm9tKSB7DQogIHJldHVybiB0byA/IGV4dGVuZCgvKiBAX19QVVJFX18gKi8gT2JqZWN0LmNyZWF0ZShudWxsKSwgdG8sIGZyb20pIDogZnJvbTsNCn0NCmZ1bmN0aW9uIG1lcmdlRW1pdHNPclByb3BzT3B0aW9ucyh0bywgZnJvbSkgew0KICBpZiAodG8pIHsNCiAgICBpZiAoaXNBcnJheSh0bykgJiYgaXNBcnJheShmcm9tKSkgew0KICAgICAgcmV0dXJuIFsuLi4vKiBAX19QVVJFX18gKi8gbmV3IFNldChbLi4udG8sIC4uLmZyb21dKV07DQogICAgfQ0KICAgIHJldHVybiBleHRlbmQoDQogICAgICAvKiBAX19QVVJFX18gKi8gT2JqZWN0LmNyZWF0ZShudWxsKSwNCiAgICAgIG5vcm1hbGl6ZVByb3BzT3JFbWl0cyh0byksDQogICAgICBub3JtYWxpemVQcm9wc09yRW1pdHMoZnJvbSAhPSBudWxsID8gZnJvbSA6IHt9KQ0KICAgICk7DQogIH0gZWxzZSB7DQogICAgcmV0dXJuIGZyb207DQogIH0NCn0NCmZ1bmN0aW9uIG1lcmdlV2F0Y2hPcHRpb25zKHRvLCBmcm9tKSB7DQogIGlmICghdG8pIHJldHVybiBmcm9tOw0KICBpZiAoIWZyb20pIHJldHVybiB0bzsNCiAgY29uc3QgbWVyZ2VkID0gZXh0ZW5kKC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuY3JlYXRlKG51bGwpLCB0byk7DQogIGZvciAoY29uc3Qga2V5IGluIGZyb20pIHsNCiAgICBtZXJnZWRba2V5XSA9IG1lcmdlQXNBcnJheSh0b1trZXldLCBmcm9tW2tleV0pOw0KICB9DQogIHJldHVybiBtZXJnZWQ7DQp9DQoNCmZ1bmN0aW9uIGNyZWF0ZUFwcENvbnRleHQoKSB7DQogIHJldHVybiB7DQogICAgYXBwOiBudWxsLA0KICAgIGNvbmZpZzogew0KICAgICAgaXNOYXRpdmVUYWc6IE5PLA0KICAgICAgcGVyZm9ybWFuY2U6IGZhbHNlLA0KICAgICAgZ2xvYmFsUHJvcGVydGllczoge30sDQogICAgICBvcHRpb25NZXJnZVN0cmF0ZWdpZXM6IHt9LA0KICAgICAgZXJyb3JIYW5kbGVyOiB2b2lkIDAsDQogICAgICB3YXJuSGFuZGxlcjogdm9pZCAwLA0KICAgICAgY29tcGlsZXJPcHRpb25zOiB7fQ0KICAgIH0sDQogICAgbWl4aW5zOiBbXSwNCiAgICBjb21wb25lbnRzOiB7fSwNCiAgICBkaXJlY3RpdmVzOiB7fSwNCiAgICBwcm92aWRlczogLyogQF9fUFVSRV9fICovIE9iamVjdC5jcmVhdGUobnVsbCksDQogICAgb3B0aW9uc0NhY2hlOiAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtNYXAoKSwNCiAgICBwcm9wc0NhY2hlOiAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtNYXAoKSwNCiAgICBlbWl0c0NhY2hlOiAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtNYXAoKQ0KICB9Ow0KfQ0KbGV0IHVpZCQxID0gMDsNCmZ1bmN0aW9uIGNyZWF0ZUFwcEFQSShyZW5kZXIsIGh5ZHJhdGUpIHsNCiAgcmV0dXJuIGZ1bmN0aW9uIGNyZWF0ZUFwcChyb290Q29tcG9uZW50LCByb290UHJvcHMgPSBudWxsKSB7DQogICAgaWYgKCFpc0Z1bmN0aW9uKHJvb3RDb21wb25lbnQpKSB7DQogICAgICByb290Q29tcG9uZW50ID0gZXh0ZW5kKHt9LCByb290Q29tcG9uZW50KTsNCiAgICB9DQogICAgaWYgKHJvb3RQcm9wcyAhPSBudWxsICYmICFpc09iamVjdChyb290UHJvcHMpKSB7DQogICAgICB3YXJuJDEoYHJvb3QgcHJvcHMgcGFzc2VkIHRvIGFwcC5tb3VudCgpIG11c3QgYmUgYW4gb2JqZWN0LmApOw0KICAgICAgcm9vdFByb3BzID0gbnVsbDsNCiAgICB9DQogICAgY29uc3QgY29udGV4dCA9IGNyZWF0ZUFwcENvbnRleHQoKTsNCiAgICBjb25zdCBpbnN0YWxsZWRQbHVnaW5zID0gLyogQF9fUFVSRV9fICovIG5ldyBXZWFrU2V0KCk7DQogICAgY29uc3QgcGx1Z2luQ2xlYW51cEZucyA9IFtdOw0KICAgIGxldCBpc01vdW50ZWQgPSBmYWxzZTsNCiAgICBjb25zdCBhcHAgPSBjb250ZXh0LmFwcCA9IHsNCiAgICAgIF91aWQ6IHVpZCQxKyssDQogICAgICBfY29tcG9uZW50OiByb290Q29tcG9uZW50LA0KICAgICAgX3Byb3BzOiByb290UHJvcHMsDQogICAgICBfY29udGFpbmVyOiBudWxsLA0KICAgICAgX2NvbnRleHQ6IGNvbnRleHQsDQogICAgICBfaW5zdGFuY2U6IG51bGwsDQogICAgICB2ZXJzaW9uLA0KICAgICAgZ2V0IGNvbmZpZygpIHsNCiAgICAgICAgcmV0dXJuIGNvbnRleHQuY29uZmlnOw0KICAgICAgfSwNCiAgICAgIHNldCBjb25maWcodikgew0KICAgICAgICB7DQogICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgYGFwcC5jb25maWcgY2Fubm90IGJlIHJlcGxhY2VkLiBNb2RpZnkgaW5kaXZpZHVhbCBvcHRpb25zIGluc3RlYWQuYA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH0sDQogICAgICB1c2UocGx1Z2luLCAuLi5vcHRpb25zKSB7DQogICAgICAgIGlmIChpbnN0YWxsZWRQbHVnaW5zLmhhcyhwbHVnaW4pKSB7DQogICAgICAgICAgd2FybiQxKGBQbHVnaW4gaGFzIGFscmVhZHkgYmVlbiBhcHBsaWVkIHRvIHRhcmdldCBhcHAuYCk7DQogICAgICAgIH0gZWxzZSBpZiAocGx1Z2luICYmIGlzRnVuY3Rpb24ocGx1Z2luLmluc3RhbGwpKSB7DQogICAgICAgICAgaW5zdGFsbGVkUGx1Z2lucy5hZGQocGx1Z2luKTsNCiAgICAgICAgICBwbHVnaW4uaW5zdGFsbChhcHAsIC4uLm9wdGlvbnMpOw0KICAgICAgICB9IGVsc2UgaWYgKGlzRnVuY3Rpb24ocGx1Z2luKSkgew0KICAgICAgICAgIGluc3RhbGxlZFBsdWdpbnMuYWRkKHBsdWdpbik7DQogICAgICAgICAgcGx1Z2luKGFwcCwgLi4ub3B0aW9ucyk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgYEEgcGx1Z2luIG11c3QgZWl0aGVyIGJlIGEgZnVuY3Rpb24gb3IgYW4gb2JqZWN0IHdpdGggYW4gImluc3RhbGwiIGZ1bmN0aW9uLmANCiAgICAgICAgICApOw0KICAgICAgICB9DQogICAgICAgIHJldHVybiBhcHA7DQogICAgICB9LA0KICAgICAgbWl4aW4obWl4aW4pIHsNCiAgICAgICAgew0KICAgICAgICAgIGlmICghY29udGV4dC5taXhpbnMuaW5jbHVkZXMobWl4aW4pKSB7DQogICAgICAgICAgICBjb250ZXh0Lm1peGlucy5wdXNoKG1peGluKTsNCiAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgICAiTWl4aW4gaGFzIGFscmVhZHkgYmVlbiBhcHBsaWVkIHRvIHRhcmdldCBhcHAiICsgKG1peGluLm5hbWUgPyBgOiAke21peGluLm5hbWV9YCA6ICIiKQ0KICAgICAgICAgICAgKTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIGFwcDsNCiAgICAgIH0sDQogICAgICBjb21wb25lbnQobmFtZSwgY29tcG9uZW50KSB7DQogICAgICAgIHsNCiAgICAgICAgICB2YWxpZGF0ZUNvbXBvbmVudE5hbWUobmFtZSwgY29udGV4dC5jb25maWcpOw0KICAgICAgICB9DQogICAgICAgIGlmICghY29tcG9uZW50KSB7DQogICAgICAgICAgcmV0dXJuIGNvbnRleHQuY29tcG9uZW50c1tuYW1lXTsNCiAgICAgICAgfQ0KICAgICAgICBpZiAoY29udGV4dC5jb21wb25lbnRzW25hbWVdKSB7DQogICAgICAgICAgd2FybiQxKGBDb21wb25lbnQgIiR7bmFtZX0iIGhhcyBhbHJlYWR5IGJlZW4gcmVnaXN0ZXJlZCBpbiB0YXJnZXQgYXBwLmApOw0KICAgICAgICB9DQogICAgICAgIGNvbnRleHQuY29tcG9uZW50c1tuYW1lXSA9IGNvbXBvbmVudDsNCiAgICAgICAgcmV0dXJuIGFwcDsNCiAgICAgIH0sDQogICAgICBkaXJlY3RpdmUobmFtZSwgZGlyZWN0aXZlKSB7DQogICAgICAgIHsNCiAgICAgICAgICB2YWxpZGF0ZURpcmVjdGl2ZU5hbWUobmFtZSk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKCFkaXJlY3RpdmUpIHsNCiAgICAgICAgICByZXR1cm4gY29udGV4dC5kaXJlY3RpdmVzW25hbWVdOw0KICAgICAgICB9DQogICAgICAgIGlmIChjb250ZXh0LmRpcmVjdGl2ZXNbbmFtZV0pIHsNCiAgICAgICAgICB3YXJuJDEoYERpcmVjdGl2ZSAiJHtuYW1lfSIgaGFzIGFscmVhZHkgYmVlbiByZWdpc3RlcmVkIGluIHRhcmdldCBhcHAuYCk7DQogICAgICAgIH0NCiAgICAgICAgY29udGV4dC5kaXJlY3RpdmVzW25hbWVdID0gZGlyZWN0aXZlOw0KICAgICAgICByZXR1cm4gYXBwOw0KICAgICAgfSwNCiAgICAgIG1vdW50KHJvb3RDb250YWluZXIsIGlzSHlkcmF0ZSwgbmFtZXNwYWNlKSB7DQogICAgICAgIGlmICghaXNNb3VudGVkKSB7DQogICAgICAgICAgaWYgKHJvb3RDb250YWluZXIuX192dWVfYXBwX18pIHsNCiAgICAgICAgICAgIHdhcm4kMSgNCiAgICAgICAgICAgICAgYFRoZXJlIGlzIGFscmVhZHkgYW4gYXBwIGluc3RhbmNlIG1vdW50ZWQgb24gdGhlIGhvc3QgY29udGFpbmVyLg0KIElmIHlvdSB3YW50IHRvIG1vdW50IGFub3RoZXIgYXBwIG9uIHRoZSBzYW1lIGhvc3QgY29udGFpbmVyLCB5b3UgbmVlZCB0byB1bm1vdW50IHRoZSBwcmV2aW91cyBhcHAgYnkgY2FsbGluZyBcYGFwcC51bm1vdW50KClcYCBmaXJzdC5gDQogICAgICAgICAgICApOw0KICAgICAgICAgIH0NCiAgICAgICAgICBjb25zdCB2bm9kZSA9IGFwcC5fY2VWTm9kZSB8fCBjcmVhdGVWTm9kZShyb290Q29tcG9uZW50LCByb290UHJvcHMpOw0KICAgICAgICAgIHZub2RlLmFwcENvbnRleHQgPSBjb250ZXh0Ow0KICAgICAgICAgIGlmIChuYW1lc3BhY2UgPT09IHRydWUpIHsNCiAgICAgICAgICAgIG5hbWVzcGFjZSA9ICJzdmciOw0KICAgICAgICAgIH0gZWxzZSBpZiAobmFtZXNwYWNlID09PSBmYWxzZSkgew0KICAgICAgICAgICAgbmFtZXNwYWNlID0gdm9pZCAwOw0KICAgICAgICAgIH0NCiAgICAgICAgICB7DQogICAgICAgICAgICBjb250ZXh0LnJlbG9hZCA9ICgpID0+IHsNCiAgICAgICAgICAgICAgY29uc3QgY2xvbmVkID0gY2xvbmVWTm9kZSh2bm9kZSk7DQogICAgICAgICAgICAgIGNsb25lZC5lbCA9IG51bGw7DQogICAgICAgICAgICAgIHJlbmRlcihjbG9uZWQsIHJvb3RDb250YWluZXIsIG5hbWVzcGFjZSk7DQogICAgICAgICAgICB9Ow0KICAgICAgICAgIH0NCiAgICAgICAgICB7DQogICAgICAgICAgICByZW5kZXIodm5vZGUsIHJvb3RDb250YWluZXIsIG5hbWVzcGFjZSk7DQogICAgICAgICAgfQ0KICAgICAgICAgIGlzTW91bnRlZCA9IHRydWU7DQogICAgICAgICAgYXBwLl9jb250YWluZXIgPSByb290Q29udGFpbmVyOw0KICAgICAgICAgIHJvb3RDb250YWluZXIuX192dWVfYXBwX18gPSBhcHA7DQogICAgICAgICAgew0KICAgICAgICAgICAgYXBwLl9pbnN0YW5jZSA9IHZub2RlLmNvbXBvbmVudDsNCiAgICAgICAgICAgIGRldnRvb2xzSW5pdEFwcChhcHAsIHZlcnNpb24pOw0KICAgICAgICAgIH0NCiAgICAgICAgICByZXR1cm4gZ2V0Q29tcG9uZW50UHVibGljSW5zdGFuY2Uodm5vZGUuY29tcG9uZW50KTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICB3YXJuJDEoDQogICAgICAgICAgICBgQXBwIGhhcyBhbHJlYWR5IGJlZW4gbW91bnRlZC4NCklmIHlvdSB3YW50IHRvIHJlbW91bnQgdGhlIHNhbWUgYXBwLCBtb3ZlIHlvdXIgYXBwIGNyZWF0aW9uIGxvZ2ljIGludG8gYSBmYWN0b3J5IGZ1bmN0aW9uIGFuZCBjcmVhdGUgZnJlc2ggYXBwIGluc3RhbmNlcyBmb3IgZWFjaCBtb3VudCAtIGUuZy4gXGBjb25zdCBjcmVhdGVNeUFwcCA9ICgpID0+IGNyZWF0ZUFwcChBcHApXGBgDQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgfSwNCiAgICAgIG9uVW5tb3VudChjbGVhbnVwRm4pIHsNCiAgICAgICAgaWYgKHR5cGVvZiBjbGVhbnVwRm4gIT09ICJmdW5jdGlvbiIpIHsNCiAgICAgICAgICB3YXJuJDEoDQogICAgICAgICAgICBgRXhwZWN0ZWQgZnVuY3Rpb24gYXMgZmlyc3QgYXJndW1lbnQgdG8gYXBwLm9uVW5tb3VudCgpLCBidXQgZ290ICR7dHlwZW9mIGNsZWFudXBGbn1gDQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgICBwbHVnaW5DbGVhbnVwRm5zLnB1c2goY2xlYW51cEZuKTsNCiAgICAgIH0sDQogICAgICB1bm1vdW50KCkgew0KICAgICAgICBpZiAoaXNNb3VudGVkKSB7DQogICAgICAgICAgY2FsbFdpdGhBc3luY0Vycm9ySGFuZGxpbmcoDQogICAgICAgICAgICBwbHVnaW5DbGVhbnVwRm5zLA0KICAgICAgICAgICAgYXBwLl9pbnN0YW5jZSwNCiAgICAgICAgICAgIDE2DQogICAgICAgICAgKTsNCiAgICAgICAgICByZW5kZXIobnVsbCwgYXBwLl9jb250YWluZXIpOw0KICAgICAgICAgIHsNCiAgICAgICAgICAgIGFwcC5faW5zdGFuY2UgPSBudWxsOw0KICAgICAgICAgICAgZGV2dG9vbHNVbm1vdW50QXBwKGFwcCk7DQogICAgICAgICAgfQ0KICAgICAgICAgIGRlbGV0ZSBhcHAuX2NvbnRhaW5lci5fX3Z1ZV9hcHBfXzsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICB3YXJuJDEoYENhbm5vdCB1bm1vdW50IGFuIGFwcCB0aGF0IGlzIG5vdCBtb3VudGVkLmApOw0KICAgICAgICB9DQogICAgICB9LA0KICAgICAgcHJvdmlkZShrZXksIHZhbHVlKSB7DQogICAgICAgIGlmIChrZXkgaW4gY29udGV4dC5wcm92aWRlcykgew0KICAgICAgICAgIGlmIChoYXNPd24oY29udGV4dC5wcm92aWRlcywga2V5KSkgew0KICAgICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgICBgQXBwIGFscmVhZHkgcHJvdmlkZXMgcHJvcGVydHkgd2l0aCBrZXkgIiR7U3RyaW5nKGtleSl9Ii4gSXQgd2lsbCBiZSBvdmVyd3JpdHRlbiB3aXRoIHRoZSBuZXcgdmFsdWUuYA0KICAgICAgICAgICAgKTsNCiAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgICBgQXBwIGFscmVhZHkgcHJvdmlkZXMgcHJvcGVydHkgd2l0aCBrZXkgIiR7U3RyaW5nKGtleSl9IiBpbmhlcml0ZWQgZnJvbSBpdHMgcGFyZW50IGVsZW1lbnQuIEl0IHdpbGwgYmUgb3ZlcndyaXR0ZW4gd2l0aCB0aGUgbmV3IHZhbHVlLmANCiAgICAgICAgICAgICk7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGNvbnRleHQucHJvdmlkZXNba2V5XSA9IHZhbHVlOw0KICAgICAgICByZXR1cm4gYXBwOw0KICAgICAgfSwNCiAgICAgIHJ1bldpdGhDb250ZXh0KGZuKSB7DQogICAgICAgIGNvbnN0IGxhc3RBcHAgPSBjdXJyZW50QXBwOw0KICAgICAgICBjdXJyZW50QXBwID0gYXBwOw0KICAgICAgICB0cnkgew0KICAgICAgICAgIHJldHVybiBmbigpOw0KICAgICAgICB9IGZpbmFsbHkgew0KICAgICAgICAgIGN1cnJlbnRBcHAgPSBsYXN0QXBwOw0KICAgICAgICB9DQogICAgICB9DQogICAgfTsNCiAgICByZXR1cm4gYXBwOw0KICB9Ow0KfQ0KbGV0IGN1cnJlbnRBcHAgPSBudWxsOw0KDQpmdW5jdGlvbiBwcm92aWRlKGtleSwgdmFsdWUpIHsNCiAgaWYgKCFjdXJyZW50SW5zdGFuY2UpIHsNCiAgICB7DQogICAgICB3YXJuJDEoYHByb3ZpZGUoKSBjYW4gb25seSBiZSB1c2VkIGluc2lkZSBzZXR1cCgpLmApOw0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICBsZXQgcHJvdmlkZXMgPSBjdXJyZW50SW5zdGFuY2UucHJvdmlkZXM7DQogICAgY29uc3QgcGFyZW50UHJvdmlkZXMgPSBjdXJyZW50SW5zdGFuY2UucGFyZW50ICYmIGN1cnJlbnRJbnN0YW5jZS5wYXJlbnQucHJvdmlkZXM7DQogICAgaWYgKHBhcmVudFByb3ZpZGVzID09PSBwcm92aWRlcykgew0KICAgICAgcHJvdmlkZXMgPSBjdXJyZW50SW5zdGFuY2UucHJvdmlkZXMgPSBPYmplY3QuY3JlYXRlKHBhcmVudFByb3ZpZGVzKTsNCiAgICB9DQogICAgcHJvdmlkZXNba2V5XSA9IHZhbHVlOw0KICB9DQp9DQpmdW5jdGlvbiBpbmplY3Qoa2V5LCBkZWZhdWx0VmFsdWUsIHRyZWF0RGVmYXVsdEFzRmFjdG9yeSA9IGZhbHNlKSB7DQogIGNvbnN0IGluc3RhbmNlID0gY3VycmVudEluc3RhbmNlIHx8IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZTsNCiAgaWYgKGluc3RhbmNlIHx8IGN1cnJlbnRBcHApIHsNCiAgICBsZXQgcHJvdmlkZXMgPSBjdXJyZW50QXBwID8gY3VycmVudEFwcC5fY29udGV4dC5wcm92aWRlcyA6IGluc3RhbmNlID8gaW5zdGFuY2UucGFyZW50ID09IG51bGwgfHwgaW5zdGFuY2UuY2UgPyBpbnN0YW5jZS52bm9kZS5hcHBDb250ZXh0ICYmIGluc3RhbmNlLnZub2RlLmFwcENvbnRleHQucHJvdmlkZXMgOiBpbnN0YW5jZS5wYXJlbnQucHJvdmlkZXMgOiB2b2lkIDA7DQogICAgaWYgKHByb3ZpZGVzICYmIGtleSBpbiBwcm92aWRlcykgew0KICAgICAgcmV0dXJuIHByb3ZpZGVzW2tleV07DQogICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkgew0KICAgICAgcmV0dXJuIHRyZWF0RGVmYXVsdEFzRmFjdG9yeSAmJiBpc0Z1bmN0aW9uKGRlZmF1bHRWYWx1ZSkgPyBkZWZhdWx0VmFsdWUuY2FsbChpbnN0YW5jZSAmJiBpbnN0YW5jZS5wcm94eSkgOiBkZWZhdWx0VmFsdWU7DQogICAgfSBlbHNlIHsNCiAgICAgIHdhcm4kMShgaW5qZWN0aW9uICIke1N0cmluZyhrZXkpfSIgbm90IGZvdW5kLmApOw0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICB3YXJuJDEoYGluamVjdCgpIGNhbiBvbmx5IGJlIHVzZWQgaW5zaWRlIHNldHVwKCkgb3IgZnVuY3Rpb25hbCBjb21wb25lbnRzLmApOw0KICB9DQp9DQoNCmNvbnN0IGludGVybmFsT2JqZWN0UHJvdG8gPSB7fTsNCmNvbnN0IGNyZWF0ZUludGVybmFsT2JqZWN0ID0gKCkgPT4gT2JqZWN0LmNyZWF0ZShpbnRlcm5hbE9iamVjdFByb3RvKTsNCmNvbnN0IGlzSW50ZXJuYWxPYmplY3QgPSAob2JqKSA9PiBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqKSA9PT0gaW50ZXJuYWxPYmplY3RQcm90bzsNCg0KZnVuY3Rpb24gaW5pdFByb3BzKGluc3RhbmNlLCByYXdQcm9wcywgaXNTdGF0ZWZ1bCwgaXNTU1IgPSBmYWxzZSkgew0KICBjb25zdCBwcm9wcyA9IHt9Ow0KICBjb25zdCBhdHRycyA9IGNyZWF0ZUludGVybmFsT2JqZWN0KCk7DQogIGluc3RhbmNlLnByb3BzRGVmYXVsdHMgPSAvKiBAX19QVVJFX18gKi8gT2JqZWN0LmNyZWF0ZShudWxsKTsNCiAgc2V0RnVsbFByb3BzKGluc3RhbmNlLCByYXdQcm9wcywgcHJvcHMsIGF0dHJzKTsNCiAgZm9yIChjb25zdCBrZXkgaW4gaW5zdGFuY2UucHJvcHNPcHRpb25zWzBdKSB7DQogICAgaWYgKCEoa2V5IGluIHByb3BzKSkgew0KICAgICAgcHJvcHNba2V5XSA9IHZvaWQgMDsNCiAgICB9DQogIH0NCiAgew0KICAgIHZhbGlkYXRlUHJvcHMocmF3UHJvcHMgfHwge30sIHByb3BzLCBpbnN0YW5jZSk7DQogIH0NCiAgaWYgKGlzU3RhdGVmdWwpIHsNCiAgICBpbnN0YW5jZS5wcm9wcyA9IGlzU1NSID8gcHJvcHMgOiBzaGFsbG93UmVhY3RpdmUocHJvcHMpOw0KICB9IGVsc2Ugew0KICAgIGlmICghaW5zdGFuY2UudHlwZS5wcm9wcykgew0KICAgICAgaW5zdGFuY2UucHJvcHMgPSBhdHRyczsNCiAgICB9IGVsc2Ugew0KICAgICAgaW5zdGFuY2UucHJvcHMgPSBwcm9wczsNCiAgICB9DQogIH0NCiAgaW5zdGFuY2UuYXR0cnMgPSBhdHRyczsNCn0NCmZ1bmN0aW9uIGlzSW5IbXJDb250ZXh0KGluc3RhbmNlKSB7DQogIHdoaWxlIChpbnN0YW5jZSkgew0KICAgIGlmIChpbnN0YW5jZS50eXBlLl9faG1ySWQpIHJldHVybiB0cnVlOw0KICAgIGluc3RhbmNlID0gaW5zdGFuY2UucGFyZW50Ow0KICB9DQp9DQpmdW5jdGlvbiB1cGRhdGVQcm9wcyhpbnN0YW5jZSwgcmF3UHJvcHMsIHJhd1ByZXZQcm9wcywgb3B0aW1pemVkKSB7DQogIGNvbnN0IHsNCiAgICBwcm9wcywNCiAgICBhdHRycywNCiAgICB2bm9kZTogeyBwYXRjaEZsYWcgfQ0KICB9ID0gaW5zdGFuY2U7DQogIGNvbnN0IHJhd0N1cnJlbnRQcm9wcyA9IHRvUmF3KHByb3BzKTsNCiAgY29uc3QgW29wdGlvbnNdID0gaW5zdGFuY2UucHJvcHNPcHRpb25zOw0KICBsZXQgaGFzQXR0cnNDaGFuZ2VkID0gZmFsc2U7DQogIGlmICgNCiAgICAvLyBhbHdheXMgZm9yY2UgZnVsbCBkaWZmIGluIGRldg0KICAgIC8vIC0gIzE5NDIgaWYgaG1yIGlzIGVuYWJsZWQgd2l0aCBzZmMgY29tcG9uZW50DQogICAgLy8gLSB2aXRlIzg3MiBub24tc2ZjIGNvbXBvbmVudCB1c2VkIGJ5IHNmYyBjb21wb25lbnQNCiAgICAhaXNJbkhtckNvbnRleHQoaW5zdGFuY2UpICYmIChvcHRpbWl6ZWQgfHwgcGF0Y2hGbGFnID4gMCkgJiYgIShwYXRjaEZsYWcgJiAxNikNCiAgKSB7DQogICAgaWYgKHBhdGNoRmxhZyAmIDgpIHsNCiAgICAgIGNvbnN0IHByb3BzVG9VcGRhdGUgPSBpbnN0YW5jZS52bm9kZS5keW5hbWljUHJvcHM7DQogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByb3BzVG9VcGRhdGUubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgbGV0IGtleSA9IHByb3BzVG9VcGRhdGVbaV07DQogICAgICAgIGlmIChpc0VtaXRMaXN0ZW5lcihpbnN0YW5jZS5lbWl0c09wdGlvbnMsIGtleSkpIHsNCiAgICAgICAgICBjb250aW51ZTsNCiAgICAgICAgfQ0KICAgICAgICBjb25zdCB2YWx1ZSA9IHJhd1Byb3BzW2tleV07DQogICAgICAgIGlmIChvcHRpb25zKSB7DQogICAgICAgICAgaWYgKGhhc093bihhdHRycywga2V5KSkgew0KICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBhdHRyc1trZXldKSB7DQogICAgICAgICAgICAgIGF0dHJzW2tleV0gPSB2YWx1ZTsNCiAgICAgICAgICAgICAgaGFzQXR0cnNDaGFuZ2VkID0gdHJ1ZTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgY29uc3QgY2FtZWxpemVkS2V5ID0gY2FtZWxpemUoa2V5KTsNCiAgICAgICAgICAgIHByb3BzW2NhbWVsaXplZEtleV0gPSByZXNvbHZlUHJvcFZhbHVlKA0KICAgICAgICAgICAgICBvcHRpb25zLA0KICAgICAgICAgICAgICByYXdDdXJyZW50UHJvcHMsDQogICAgICAgICAgICAgIGNhbWVsaXplZEtleSwNCiAgICAgICAgICAgICAgdmFsdWUsDQogICAgICAgICAgICAgIGluc3RhbmNlLA0KICAgICAgICAgICAgICBmYWxzZQ0KICAgICAgICAgICAgKTsNCiAgICAgICAgICB9DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgaWYgKHZhbHVlICE9PSBhdHRyc1trZXldKSB7DQogICAgICAgICAgICBhdHRyc1trZXldID0gdmFsdWU7DQogICAgICAgICAgICBoYXNBdHRyc0NoYW5nZWQgPSB0cnVlOw0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICBpZiAoc2V0RnVsbFByb3BzKGluc3RhbmNlLCByYXdQcm9wcywgcHJvcHMsIGF0dHJzKSkgew0KICAgICAgaGFzQXR0cnNDaGFuZ2VkID0gdHJ1ZTsNCiAgICB9DQogICAgbGV0IGtlYmFiS2V5Ow0KICAgIGZvciAoY29uc3Qga2V5IGluIHJhd0N1cnJlbnRQcm9wcykgew0KICAgICAgaWYgKCFyYXdQcm9wcyB8fCAvLyBmb3IgY2FtZWxDYXNlDQogICAgICAhaGFzT3duKHJhd1Byb3BzLCBrZXkpICYmIC8vIGl0J3MgcG9zc2libGUgdGhlIG9yaWdpbmFsIHByb3BzIHdhcyBwYXNzZWQgaW4gYXMga2ViYWItY2FzZQ0KICAgICAgLy8gYW5kIGNvbnZlcnRlZCB0byBjYW1lbENhc2UgKCM5NTUpDQogICAgICAoKGtlYmFiS2V5ID0gaHlwaGVuYXRlKGtleSkpID09PSBrZXkgfHwgIWhhc093bihyYXdQcm9wcywga2ViYWJLZXkpKSkgew0KICAgICAgICBpZiAob3B0aW9ucykgew0KICAgICAgICAgIGlmIChyYXdQcmV2UHJvcHMgJiYgLy8gZm9yIGNhbWVsQ2FzZQ0KICAgICAgICAgIChyYXdQcmV2UHJvcHNba2V5XSAhPT0gdm9pZCAwIHx8IC8vIGZvciBrZWJhYi1jYXNlDQogICAgICAgICAgcmF3UHJldlByb3BzW2tlYmFiS2V5XSAhPT0gdm9pZCAwKSkgew0KICAgICAgICAgICAgcHJvcHNba2V5XSA9IHJlc29sdmVQcm9wVmFsdWUoDQogICAgICAgICAgICAgIG9wdGlvbnMsDQogICAgICAgICAgICAgIHJhd0N1cnJlbnRQcm9wcywNCiAgICAgICAgICAgICAga2V5LA0KICAgICAgICAgICAgICB2b2lkIDAsDQogICAgICAgICAgICAgIGluc3RhbmNlLA0KICAgICAgICAgICAgICB0cnVlDQogICAgICAgICAgICApOw0KICAgICAgICAgIH0NCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBkZWxldGUgcHJvcHNba2V5XTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgICBpZiAoYXR0cnMgIT09IHJhd0N1cnJlbnRQcm9wcykgew0KICAgICAgZm9yIChjb25zdCBrZXkgaW4gYXR0cnMpIHsNCiAgICAgICAgaWYgKCFyYXdQcm9wcyB8fCAhaGFzT3duKHJhd1Byb3BzLCBrZXkpICYmIHRydWUpIHsNCiAgICAgICAgICBkZWxldGUgYXR0cnNba2V5XTsNCiAgICAgICAgICBoYXNBdHRyc0NoYW5nZWQgPSB0cnVlOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICB9DQogIGlmIChoYXNBdHRyc0NoYW5nZWQpIHsNCiAgICB0cmlnZ2VyKGluc3RhbmNlLmF0dHJzLCAic2V0IiwgIiIpOw0KICB9DQogIHsNCiAgICB2YWxpZGF0ZVByb3BzKHJhd1Byb3BzIHx8IHt9LCBwcm9wcywgaW5zdGFuY2UpOw0KICB9DQp9DQpmdW5jdGlvbiBzZXRGdWxsUHJvcHMoaW5zdGFuY2UsIHJhd1Byb3BzLCBwcm9wcywgYXR0cnMpIHsNCiAgY29uc3QgW29wdGlvbnMsIG5lZWRDYXN0S2V5c10gPSBpbnN0YW5jZS5wcm9wc09wdGlvbnM7DQogIGxldCBoYXNBdHRyc0NoYW5nZWQgPSBmYWxzZTsNCiAgbGV0IHJhd0Nhc3RWYWx1ZXM7DQogIGlmIChyYXdQcm9wcykgew0KICAgIGZvciAobGV0IGtleSBpbiByYXdQcm9wcykgew0KICAgICAgaWYgKGlzUmVzZXJ2ZWRQcm9wKGtleSkpIHsNCiAgICAgICAgY29udGludWU7DQogICAgICB9DQogICAgICBjb25zdCB2YWx1ZSA9IHJhd1Byb3BzW2tleV07DQogICAgICBsZXQgY2FtZWxLZXk7DQogICAgICBpZiAob3B0aW9ucyAmJiBoYXNPd24ob3B0aW9ucywgY2FtZWxLZXkgPSBjYW1lbGl6ZShrZXkpKSkgew0KICAgICAgICBpZiAoIW5lZWRDYXN0S2V5cyB8fCAhbmVlZENhc3RLZXlzLmluY2x1ZGVzKGNhbWVsS2V5KSkgew0KICAgICAgICAgIHByb3BzW2NhbWVsS2V5XSA9IHZhbHVlOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIChyYXdDYXN0VmFsdWVzIHx8IChyYXdDYXN0VmFsdWVzID0ge30pKVtjYW1lbEtleV0gPSB2YWx1ZTsNCiAgICAgICAgfQ0KICAgICAgfSBlbHNlIGlmICghaXNFbWl0TGlzdGVuZXIoaW5zdGFuY2UuZW1pdHNPcHRpb25zLCBrZXkpKSB7DQogICAgICAgIGlmICghKGtleSBpbiBhdHRycykgfHwgdmFsdWUgIT09IGF0dHJzW2tleV0pIHsNCiAgICAgICAgICBhdHRyc1trZXldID0gdmFsdWU7DQogICAgICAgICAgaGFzQXR0cnNDaGFuZ2VkID0gdHJ1ZTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICBpZiAobmVlZENhc3RLZXlzKSB7DQogICAgY29uc3QgcmF3Q3VycmVudFByb3BzID0gdG9SYXcocHJvcHMpOw0KICAgIGNvbnN0IGNhc3RWYWx1ZXMgPSByYXdDYXN0VmFsdWVzIHx8IEVNUFRZX09CSjsNCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5lZWRDYXN0S2V5cy5sZW5ndGg7IGkrKykgew0KICAgICAgY29uc3Qga2V5ID0gbmVlZENhc3RLZXlzW2ldOw0KICAgICAgcHJvcHNba2V5XSA9IHJlc29sdmVQcm9wVmFsdWUoDQogICAgICAgIG9wdGlvbnMsDQogICAgICAgIHJhd0N1cnJlbnRQcm9wcywNCiAgICAgICAga2V5LA0KICAgICAgICBjYXN0VmFsdWVzW2tleV0sDQogICAgICAgIGluc3RhbmNlLA0KICAgICAgICAhaGFzT3duKGNhc3RWYWx1ZXMsIGtleSkNCiAgICAgICk7DQogICAgfQ0KICB9DQogIHJldHVybiBoYXNBdHRyc0NoYW5nZWQ7DQp9DQpmdW5jdGlvbiByZXNvbHZlUHJvcFZhbHVlKG9wdGlvbnMsIHByb3BzLCBrZXksIHZhbHVlLCBpbnN0YW5jZSwgaXNBYnNlbnQpIHsNCiAgY29uc3Qgb3B0ID0gb3B0aW9uc1trZXldOw0KICBpZiAob3B0ICE9IG51bGwpIHsNCiAgICBjb25zdCBoYXNEZWZhdWx0ID0gaGFzT3duKG9wdCwgImRlZmF1bHQiKTsNCiAgICBpZiAoaGFzRGVmYXVsdCAmJiB2YWx1ZSA9PT0gdm9pZCAwKSB7DQogICAgICBjb25zdCBkZWZhdWx0VmFsdWUgPSBvcHQuZGVmYXVsdDsNCiAgICAgIGlmIChvcHQudHlwZSAhPT0gRnVuY3Rpb24gJiYgIW9wdC5za2lwRmFjdG9yeSAmJiBpc0Z1bmN0aW9uKGRlZmF1bHRWYWx1ZSkpIHsNCiAgICAgICAgY29uc3QgeyBwcm9wc0RlZmF1bHRzIH0gPSBpbnN0YW5jZTsNCiAgICAgICAgaWYgKGtleSBpbiBwcm9wc0RlZmF1bHRzKSB7DQogICAgICAgICAgdmFsdWUgPSBwcm9wc0RlZmF1bHRzW2tleV07DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgY29uc3QgcmVzZXQgPSBzZXRDdXJyZW50SW5zdGFuY2UoaW5zdGFuY2UpOw0KICAgICAgICAgIHZhbHVlID0gcHJvcHNEZWZhdWx0c1trZXldID0gZGVmYXVsdFZhbHVlLmNhbGwoDQogICAgICAgICAgICBudWxsLA0KICAgICAgICAgICAgcHJvcHMNCiAgICAgICAgICApOw0KICAgICAgICAgIHJlc2V0KCk7DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHZhbHVlID0gZGVmYXVsdFZhbHVlOw0KICAgICAgfQ0KICAgICAgaWYgKGluc3RhbmNlLmNlKSB7DQogICAgICAgIGluc3RhbmNlLmNlLl9zZXRQcm9wKGtleSwgdmFsdWUpOw0KICAgICAgfQ0KICAgIH0NCiAgICBpZiAob3B0WzAgLyogc2hvdWxkQ2FzdCAqL10pIHsNCiAgICAgIGlmIChpc0Fic2VudCAmJiAhaGFzRGVmYXVsdCkgew0KICAgICAgICB2YWx1ZSA9IGZhbHNlOw0KICAgICAgfSBlbHNlIGlmIChvcHRbMSAvKiBzaG91bGRDYXN0VHJ1ZSAqL10gJiYgKHZhbHVlID09PSAiIiB8fCB2YWx1ZSA9PT0gaHlwaGVuYXRlKGtleSkpKSB7DQogICAgICAgIHZhbHVlID0gdHJ1ZTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgcmV0dXJuIHZhbHVlOw0KfQ0KY29uc3QgbWl4aW5Qcm9wc0NhY2hlID0gLyogQF9fUFVSRV9fICovIG5ldyBXZWFrTWFwKCk7DQpmdW5jdGlvbiBub3JtYWxpemVQcm9wc09wdGlvbnMoY29tcCwgYXBwQ29udGV4dCwgYXNNaXhpbiA9IGZhbHNlKSB7DQogIGNvbnN0IGNhY2hlID0gYXNNaXhpbiA/IG1peGluUHJvcHNDYWNoZSA6IGFwcENvbnRleHQucHJvcHNDYWNoZTsNCiAgY29uc3QgY2FjaGVkID0gY2FjaGUuZ2V0KGNvbXApOw0KICBpZiAoY2FjaGVkKSB7DQogICAgcmV0dXJuIGNhY2hlZDsNCiAgfQ0KICBjb25zdCByYXcgPSBjb21wLnByb3BzOw0KICBjb25zdCBub3JtYWxpemVkID0ge307DQogIGNvbnN0IG5lZWRDYXN0S2V5cyA9IFtdOw0KICBsZXQgaGFzRXh0ZW5kcyA9IGZhbHNlOw0KICBpZiAoIWlzRnVuY3Rpb24oY29tcCkpIHsNCiAgICBjb25zdCBleHRlbmRQcm9wcyA9IChyYXcyKSA9PiB7DQogICAgICBoYXNFeHRlbmRzID0gdHJ1ZTsNCiAgICAgIGNvbnN0IFtwcm9wcywga2V5c10gPSBub3JtYWxpemVQcm9wc09wdGlvbnMocmF3MiwgYXBwQ29udGV4dCwgdHJ1ZSk7DQogICAgICBleHRlbmQobm9ybWFsaXplZCwgcHJvcHMpOw0KICAgICAgaWYgKGtleXMpIG5lZWRDYXN0S2V5cy5wdXNoKC4uLmtleXMpOw0KICAgIH07DQogICAgaWYgKCFhc01peGluICYmIGFwcENvbnRleHQubWl4aW5zLmxlbmd0aCkgew0KICAgICAgYXBwQ29udGV4dC5taXhpbnMuZm9yRWFjaChleHRlbmRQcm9wcyk7DQogICAgfQ0KICAgIGlmIChjb21wLmV4dGVuZHMpIHsNCiAgICAgIGV4dGVuZFByb3BzKGNvbXAuZXh0ZW5kcyk7DQogICAgfQ0KICAgIGlmIChjb21wLm1peGlucykgew0KICAgICAgY29tcC5taXhpbnMuZm9yRWFjaChleHRlbmRQcm9wcyk7DQogICAgfQ0KICB9DQogIGlmICghcmF3ICYmICFoYXNFeHRlbmRzKSB7DQogICAgaWYgKGlzT2JqZWN0KGNvbXApKSB7DQogICAgICBjYWNoZS5zZXQoY29tcCwgRU1QVFlfQVJSKTsNCiAgICB9DQogICAgcmV0dXJuIEVNUFRZX0FSUjsNCiAgfQ0KICBpZiAoaXNBcnJheShyYXcpKSB7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYXcubGVuZ3RoOyBpKyspIHsNCiAgICAgIGlmICghaXNTdHJpbmcocmF3W2ldKSkgew0KICAgICAgICB3YXJuJDEoYHByb3BzIG11c3QgYmUgc3RyaW5ncyB3aGVuIHVzaW5nIGFycmF5IHN5bnRheC5gLCByYXdbaV0pOw0KICAgICAgfQ0KICAgICAgY29uc3Qgbm9ybWFsaXplZEtleSA9IGNhbWVsaXplKHJhd1tpXSk7DQogICAgICBpZiAodmFsaWRhdGVQcm9wTmFtZShub3JtYWxpemVkS2V5KSkgew0KICAgICAgICBub3JtYWxpemVkW25vcm1hbGl6ZWRLZXldID0gRU1QVFlfT0JKOw0KICAgICAgfQ0KICAgIH0NCiAgfSBlbHNlIGlmIChyYXcpIHsNCiAgICBpZiAoIWlzT2JqZWN0KHJhdykpIHsNCiAgICAgIHdhcm4kMShgaW52YWxpZCBwcm9wcyBvcHRpb25zYCwgcmF3KTsNCiAgICB9DQogICAgZm9yIChjb25zdCBrZXkgaW4gcmF3KSB7DQogICAgICBjb25zdCBub3JtYWxpemVkS2V5ID0gY2FtZWxpemUoa2V5KTsNCiAgICAgIGlmICh2YWxpZGF0ZVByb3BOYW1lKG5vcm1hbGl6ZWRLZXkpKSB7DQogICAgICAgIGNvbnN0IG9wdCA9IHJhd1trZXldOw0KICAgICAgICBjb25zdCBwcm9wID0gbm9ybWFsaXplZFtub3JtYWxpemVkS2V5XSA9IGlzQXJyYXkob3B0KSB8fCBpc0Z1bmN0aW9uKG9wdCkgPyB7IHR5cGU6IG9wdCB9IDogZXh0ZW5kKHt9LCBvcHQpOw0KICAgICAgICBjb25zdCBwcm9wVHlwZSA9IHByb3AudHlwZTsNCiAgICAgICAgbGV0IHNob3VsZENhc3QgPSBmYWxzZTsNCiAgICAgICAgbGV0IHNob3VsZENhc3RUcnVlID0gdHJ1ZTsNCiAgICAgICAgaWYgKGlzQXJyYXkocHJvcFR5cGUpKSB7DQogICAgICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHByb3BUeXBlLmxlbmd0aDsgKytpbmRleCkgew0KICAgICAgICAgICAgY29uc3QgdHlwZSA9IHByb3BUeXBlW2luZGV4XTsNCiAgICAgICAgICAgIGNvbnN0IHR5cGVOYW1lID0gaXNGdW5jdGlvbih0eXBlKSAmJiB0eXBlLm5hbWU7DQogICAgICAgICAgICBpZiAodHlwZU5hbWUgPT09ICJCb29sZWFuIikgew0KICAgICAgICAgICAgICBzaG91bGRDYXN0ID0gdHJ1ZTsNCiAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVOYW1lID09PSAiU3RyaW5nIikgew0KICAgICAgICAgICAgICBzaG91bGRDYXN0VHJ1ZSA9IGZhbHNlOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgIH0NCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBzaG91bGRDYXN0ID0gaXNGdW5jdGlvbihwcm9wVHlwZSkgJiYgcHJvcFR5cGUubmFtZSA9PT0gIkJvb2xlYW4iOw0KICAgICAgICB9DQogICAgICAgIHByb3BbMCAvKiBzaG91bGRDYXN0ICovXSA9IHNob3VsZENhc3Q7DQogICAgICAgIHByb3BbMSAvKiBzaG91bGRDYXN0VHJ1ZSAqL10gPSBzaG91bGRDYXN0VHJ1ZTsNCiAgICAgICAgaWYgKHNob3VsZENhc3QgfHwgaGFzT3duKHByb3AsICJkZWZhdWx0IikpIHsNCiAgICAgICAgICBuZWVkQ2FzdEtleXMucHVzaChub3JtYWxpemVkS2V5KTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICBjb25zdCByZXMgPSBbbm9ybWFsaXplZCwgbmVlZENhc3RLZXlzXTsNCiAgaWYgKGlzT2JqZWN0KGNvbXApKSB7DQogICAgY2FjaGUuc2V0KGNvbXAsIHJlcyk7DQogIH0NCiAgcmV0dXJuIHJlczsNCn0NCmZ1bmN0aW9uIHZhbGlkYXRlUHJvcE5hbWUoa2V5KSB7DQogIGlmIChrZXlbMF0gIT09ICIkIiAmJiAhaXNSZXNlcnZlZFByb3Aoa2V5KSkgew0KICAgIHJldHVybiB0cnVlOw0KICB9IGVsc2Ugew0KICAgIHdhcm4kMShgSW52YWxpZCBwcm9wIG5hbWU6ICIke2tleX0iIGlzIGEgcmVzZXJ2ZWQgcHJvcGVydHkuYCk7DQogIH0NCiAgcmV0dXJuIGZhbHNlOw0KfQ0KZnVuY3Rpb24gZ2V0VHlwZShjdG9yKSB7DQogIGlmIChjdG9yID09PSBudWxsKSB7DQogICAgcmV0dXJuICJudWxsIjsNCiAgfQ0KICBpZiAodHlwZW9mIGN0b3IgPT09ICJmdW5jdGlvbiIpIHsNCiAgICByZXR1cm4gY3Rvci5uYW1lIHx8ICIiOw0KICB9IGVsc2UgaWYgKHR5cGVvZiBjdG9yID09PSAib2JqZWN0Iikgew0KICAgIGNvbnN0IG5hbWUgPSBjdG9yLmNvbnN0cnVjdG9yICYmIGN0b3IuY29uc3RydWN0b3IubmFtZTsNCiAgICByZXR1cm4gbmFtZSB8fCAiIjsNCiAgfQ0KICByZXR1cm4gIiI7DQp9DQpmdW5jdGlvbiB2YWxpZGF0ZVByb3BzKHJhd1Byb3BzLCBwcm9wcywgaW5zdGFuY2UpIHsNCiAgY29uc3QgcmVzb2x2ZWRWYWx1ZXMgPSB0b1Jhdyhwcm9wcyk7DQogIGNvbnN0IG9wdGlvbnMgPSBpbnN0YW5jZS5wcm9wc09wdGlvbnNbMF07DQogIGNvbnN0IGNhbWVsaXplUHJvcHNLZXkgPSBPYmplY3Qua2V5cyhyYXdQcm9wcykubWFwKChrZXkpID0+IGNhbWVsaXplKGtleSkpOw0KICBmb3IgKGNvbnN0IGtleSBpbiBvcHRpb25zKSB7DQogICAgbGV0IG9wdCA9IG9wdGlvbnNba2V5XTsNCiAgICBpZiAob3B0ID09IG51bGwpIGNvbnRpbnVlOw0KICAgIHZhbGlkYXRlUHJvcCgNCiAgICAgIGtleSwNCiAgICAgIHJlc29sdmVkVmFsdWVzW2tleV0sDQogICAgICBvcHQsDQogICAgICBzaGFsbG93UmVhZG9ubHkocmVzb2x2ZWRWYWx1ZXMpICwNCiAgICAgICFjYW1lbGl6ZVByb3BzS2V5LmluY2x1ZGVzKGtleSkNCiAgICApOw0KICB9DQp9DQpmdW5jdGlvbiB2YWxpZGF0ZVByb3AobmFtZSwgdmFsdWUsIHByb3AsIHByb3BzLCBpc0Fic2VudCkgew0KICBjb25zdCB7IHR5cGUsIHJlcXVpcmVkLCB2YWxpZGF0b3IsIHNraXBDaGVjayB9ID0gcHJvcDsNCiAgaWYgKHJlcXVpcmVkICYmIGlzQWJzZW50KSB7DQogICAgd2FybiQxKCdNaXNzaW5nIHJlcXVpcmVkIHByb3A6ICInICsgbmFtZSArICciJyk7DQogICAgcmV0dXJuOw0KICB9DQogIGlmICh2YWx1ZSA9PSBudWxsICYmICFyZXF1aXJlZCkgew0KICAgIHJldHVybjsNCiAgfQ0KICBpZiAodHlwZSAhPSBudWxsICYmIHR5cGUgIT09IHRydWUgJiYgIXNraXBDaGVjaykgew0KICAgIGxldCBpc1ZhbGlkID0gZmFsc2U7DQogICAgY29uc3QgdHlwZXMgPSBpc0FycmF5KHR5cGUpID8gdHlwZSA6IFt0eXBlXTsNCiAgICBjb25zdCBleHBlY3RlZFR5cGVzID0gW107DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0eXBlcy5sZW5ndGggJiYgIWlzVmFsaWQ7IGkrKykgew0KICAgICAgY29uc3QgeyB2YWxpZCwgZXhwZWN0ZWRUeXBlIH0gPSBhc3NlcnRUeXBlKHZhbHVlLCB0eXBlc1tpXSk7DQogICAgICBleHBlY3RlZFR5cGVzLnB1c2goZXhwZWN0ZWRUeXBlIHx8ICIiKTsNCiAgICAgIGlzVmFsaWQgPSB2YWxpZDsNCiAgICB9DQogICAgaWYgKCFpc1ZhbGlkKSB7DQogICAgICB3YXJuJDEoZ2V0SW52YWxpZFR5cGVNZXNzYWdlKG5hbWUsIHZhbHVlLCBleHBlY3RlZFR5cGVzKSk7DQogICAgICByZXR1cm47DQogICAgfQ0KICB9DQogIGlmICh2YWxpZGF0b3IgJiYgIXZhbGlkYXRvcih2YWx1ZSwgcHJvcHMpKSB7DQogICAgd2FybiQxKCdJbnZhbGlkIHByb3A6IGN1c3RvbSB2YWxpZGF0b3IgY2hlY2sgZmFpbGVkIGZvciBwcm9wICInICsgbmFtZSArICciLicpOw0KICB9DQp9DQpjb25zdCBpc1NpbXBsZVR5cGUgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcCgNCiAgIlN0cmluZyxOdW1iZXIsQm9vbGVhbixGdW5jdGlvbixTeW1ib2wsQmlnSW50Ig0KKTsNCmZ1bmN0aW9uIGFzc2VydFR5cGUodmFsdWUsIHR5cGUpIHsNCiAgbGV0IHZhbGlkOw0KICBjb25zdCBleHBlY3RlZFR5cGUgPSBnZXRUeXBlKHR5cGUpOw0KICBpZiAoZXhwZWN0ZWRUeXBlID09PSAibnVsbCIpIHsNCiAgICB2YWxpZCA9IHZhbHVlID09PSBudWxsOw0KICB9IGVsc2UgaWYgKGlzU2ltcGxlVHlwZShleHBlY3RlZFR5cGUpKSB7DQogICAgY29uc3QgdCA9IHR5cGVvZiB2YWx1ZTsNCiAgICB2YWxpZCA9IHQgPT09IGV4cGVjdGVkVHlwZS50b0xvd2VyQ2FzZSgpOw0KICAgIGlmICghdmFsaWQgJiYgdCA9PT0gIm9iamVjdCIpIHsNCiAgICAgIHZhbGlkID0gdmFsdWUgaW5zdGFuY2VvZiB0eXBlOw0KICAgIH0NCiAgfSBlbHNlIGlmIChleHBlY3RlZFR5cGUgPT09ICJPYmplY3QiKSB7DQogICAgdmFsaWQgPSBpc09iamVjdCh2YWx1ZSk7DQogIH0gZWxzZSBpZiAoZXhwZWN0ZWRUeXBlID09PSAiQXJyYXkiKSB7DQogICAgdmFsaWQgPSBpc0FycmF5KHZhbHVlKTsNCiAgfSBlbHNlIHsNCiAgICB2YWxpZCA9IHZhbHVlIGluc3RhbmNlb2YgdHlwZTsNCiAgfQ0KICByZXR1cm4gew0KICAgIHZhbGlkLA0KICAgIGV4cGVjdGVkVHlwZQ0KICB9Ow0KfQ0KZnVuY3Rpb24gZ2V0SW52YWxpZFR5cGVNZXNzYWdlKG5hbWUsIHZhbHVlLCBleHBlY3RlZFR5cGVzKSB7DQogIGlmIChleHBlY3RlZFR5cGVzLmxlbmd0aCA9PT0gMCkgew0KICAgIHJldHVybiBgUHJvcCB0eXBlIFtdIGZvciBwcm9wICIke25hbWV9IiB3b24ndCBtYXRjaCBhbnl0aGluZy4gRGlkIHlvdSBtZWFuIHRvIHVzZSB0eXBlIEFycmF5IGluc3RlYWQ/YDsNCiAgfQ0KICBsZXQgbWVzc2FnZSA9IGBJbnZhbGlkIHByb3A6IHR5cGUgY2hlY2sgZmFpbGVkIGZvciBwcm9wICIke25hbWV9Ii4gRXhwZWN0ZWQgJHtleHBlY3RlZFR5cGVzLm1hcChjYXBpdGFsaXplKS5qb2luKCIgfCAiKX1gOw0KICBjb25zdCBleHBlY3RlZFR5cGUgPSBleHBlY3RlZFR5cGVzWzBdOw0KICBjb25zdCByZWNlaXZlZFR5cGUgPSB0b1Jhd1R5cGUodmFsdWUpOw0KICBjb25zdCBleHBlY3RlZFZhbHVlID0gc3R5bGVWYWx1ZSh2YWx1ZSwgZXhwZWN0ZWRUeXBlKTsNCiAgY29uc3QgcmVjZWl2ZWRWYWx1ZSA9IHN0eWxlVmFsdWUodmFsdWUsIHJlY2VpdmVkVHlwZSk7DQogIGlmIChleHBlY3RlZFR5cGVzLmxlbmd0aCA9PT0gMSAmJiBpc0V4cGxpY2FibGUoZXhwZWN0ZWRUeXBlKSAmJiAhaXNCb29sZWFuKGV4cGVjdGVkVHlwZSwgcmVjZWl2ZWRUeXBlKSkgew0KICAgIG1lc3NhZ2UgKz0gYCB3aXRoIHZhbHVlICR7ZXhwZWN0ZWRWYWx1ZX1gOw0KICB9DQogIG1lc3NhZ2UgKz0gYCwgZ290ICR7cmVjZWl2ZWRUeXBlfSBgOw0KICBpZiAoaXNFeHBsaWNhYmxlKHJlY2VpdmVkVHlwZSkpIHsNCiAgICBtZXNzYWdlICs9IGB3aXRoIHZhbHVlICR7cmVjZWl2ZWRWYWx1ZX0uYDsNCiAgfQ0KICByZXR1cm4gbWVzc2FnZTsNCn0NCmZ1bmN0aW9uIHN0eWxlVmFsdWUodmFsdWUsIHR5cGUpIHsNCiAgaWYgKHR5cGUgPT09ICJTdHJpbmciKSB7DQogICAgcmV0dXJuIGAiJHt2YWx1ZX0iYDsNCiAgfSBlbHNlIGlmICh0eXBlID09PSAiTnVtYmVyIikgew0KICAgIHJldHVybiBgJHtOdW1iZXIodmFsdWUpfWA7DQogIH0gZWxzZSB7DQogICAgcmV0dXJuIGAke3ZhbHVlfWA7DQogIH0NCn0NCmZ1bmN0aW9uIGlzRXhwbGljYWJsZSh0eXBlKSB7DQogIGNvbnN0IGV4cGxpY2l0VHlwZXMgPSBbInN0cmluZyIsICJudW1iZXIiLCAiYm9vbGVhbiJdOw0KICByZXR1cm4gZXhwbGljaXRUeXBlcy5zb21lKChlbGVtKSA9PiB0eXBlLnRvTG93ZXJDYXNlKCkgPT09IGVsZW0pOw0KfQ0KZnVuY3Rpb24gaXNCb29sZWFuKC4uLmFyZ3MpIHsNCiAgcmV0dXJuIGFyZ3Muc29tZSgoZWxlbSkgPT4gZWxlbS50b0xvd2VyQ2FzZSgpID09PSAiYm9vbGVhbiIpOw0KfQ0KDQpjb25zdCBpc0ludGVybmFsS2V5ID0gKGtleSkgPT4ga2V5WzBdID09PSAiXyIgfHwga2V5ID09PSAiJHN0YWJsZSI7DQpjb25zdCBub3JtYWxpemVTbG90VmFsdWUgPSAodmFsdWUpID0+IGlzQXJyYXkodmFsdWUpID8gdmFsdWUubWFwKG5vcm1hbGl6ZVZOb2RlJDEpIDogW25vcm1hbGl6ZVZOb2RlJDEodmFsdWUpXTsNCmNvbnN0IG5vcm1hbGl6ZVNsb3QgPSAoa2V5LCByYXdTbG90LCBjdHgpID0+IHsNCiAgaWYgKHJhd1Nsb3QuX24pIHsNCiAgICByZXR1cm4gcmF3U2xvdDsNCiAgfQ0KICBjb25zdCBub3JtYWxpemVkID0gd2l0aEN0eCgoLi4uYXJncykgPT4gew0KICAgIGlmIChjdXJyZW50SW5zdGFuY2UgJiYgIShjdHggPT09IG51bGwgJiYgY3VycmVudFJlbmRlcmluZ0luc3RhbmNlKSAmJiAhKGN0eCAmJiBjdHgucm9vdCAhPT0gY3VycmVudEluc3RhbmNlLnJvb3QpKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGBTbG90ICIke2tleX0iIGludm9rZWQgb3V0c2lkZSBvZiB0aGUgcmVuZGVyIGZ1bmN0aW9uOiB0aGlzIHdpbGwgbm90IHRyYWNrIGRlcGVuZGVuY2llcyB1c2VkIGluIHRoZSBzbG90LiBJbnZva2UgdGhlIHNsb3QgZnVuY3Rpb24gaW5zaWRlIHRoZSByZW5kZXIgZnVuY3Rpb24gaW5zdGVhZC5gDQogICAgICApOw0KICAgIH0NCiAgICByZXR1cm4gbm9ybWFsaXplU2xvdFZhbHVlKHJhd1Nsb3QoLi4uYXJncykpOw0KICB9LCBjdHgpOw0KICBub3JtYWxpemVkLl9jID0gZmFsc2U7DQogIHJldHVybiBub3JtYWxpemVkOw0KfTsNCmNvbnN0IG5vcm1hbGl6ZU9iamVjdFNsb3RzID0gKHJhd1Nsb3RzLCBzbG90cywgaW5zdGFuY2UpID0+IHsNCiAgY29uc3QgY3R4ID0gcmF3U2xvdHMuX2N0eDsNCiAgZm9yIChjb25zdCBrZXkgaW4gcmF3U2xvdHMpIHsNCiAgICBpZiAoaXNJbnRlcm5hbEtleShrZXkpKSBjb250aW51ZTsNCiAgICBjb25zdCB2YWx1ZSA9IHJhd1Nsb3RzW2tleV07DQogICAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7DQogICAgICBzbG90c1trZXldID0gbm9ybWFsaXplU2xvdChrZXksIHZhbHVlLCBjdHgpOw0KICAgIH0gZWxzZSBpZiAodmFsdWUgIT0gbnVsbCkgew0KICAgICAgew0KICAgICAgICB3YXJuJDEoDQogICAgICAgICAgYE5vbi1mdW5jdGlvbiB2YWx1ZSBlbmNvdW50ZXJlZCBmb3Igc2xvdCAiJHtrZXl9Ii4gUHJlZmVyIGZ1bmN0aW9uIHNsb3RzIGZvciBiZXR0ZXIgcGVyZm9ybWFuY2UuYA0KICAgICAgICApOw0KICAgICAgfQ0KICAgICAgY29uc3Qgbm9ybWFsaXplZCA9IG5vcm1hbGl6ZVNsb3RWYWx1ZSh2YWx1ZSk7DQogICAgICBzbG90c1trZXldID0gKCkgPT4gbm9ybWFsaXplZDsNCiAgICB9DQogIH0NCn07DQpjb25zdCBub3JtYWxpemVWTm9kZVNsb3RzID0gKGluc3RhbmNlLCBjaGlsZHJlbikgPT4gew0KICBpZiAoIWlzS2VlcEFsaXZlKGluc3RhbmNlLnZub2RlKSAmJiB0cnVlKSB7DQogICAgd2FybiQxKA0KICAgICAgYE5vbi1mdW5jdGlvbiB2YWx1ZSBlbmNvdW50ZXJlZCBmb3IgZGVmYXVsdCBzbG90LiBQcmVmZXIgZnVuY3Rpb24gc2xvdHMgZm9yIGJldHRlciBwZXJmb3JtYW5jZS5gDQogICAgKTsNCiAgfQ0KICBjb25zdCBub3JtYWxpemVkID0gbm9ybWFsaXplU2xvdFZhbHVlKGNoaWxkcmVuKTsNCiAgaW5zdGFuY2Uuc2xvdHMuZGVmYXVsdCA9ICgpID0+IG5vcm1hbGl6ZWQ7DQp9Ow0KY29uc3QgYXNzaWduU2xvdHMgPSAoc2xvdHMsIGNoaWxkcmVuLCBvcHRpbWl6ZWQpID0+IHsNCiAgZm9yIChjb25zdCBrZXkgaW4gY2hpbGRyZW4pIHsNCiAgICBpZiAob3B0aW1pemVkIHx8ICFpc0ludGVybmFsS2V5KGtleSkpIHsNCiAgICAgIHNsb3RzW2tleV0gPSBjaGlsZHJlbltrZXldOw0KICAgIH0NCiAgfQ0KfTsNCmNvbnN0IGluaXRTbG90cyA9IChpbnN0YW5jZSwgY2hpbGRyZW4sIG9wdGltaXplZCkgPT4gew0KICBjb25zdCBzbG90cyA9IGluc3RhbmNlLnNsb3RzID0gY3JlYXRlSW50ZXJuYWxPYmplY3QoKTsNCiAgaWYgKGluc3RhbmNlLnZub2RlLnNoYXBlRmxhZyAmIDMyKSB7DQogICAgY29uc3QgY2FjaGVJbmRleGVzID0gY2hpbGRyZW4uX187DQogICAgaWYgKGNhY2hlSW5kZXhlcykgZGVmKHNsb3RzLCAiX18iLCBjYWNoZUluZGV4ZXMsIHRydWUpOw0KICAgIGNvbnN0IHR5cGUgPSBjaGlsZHJlbi5fOw0KICAgIGlmICh0eXBlKSB7DQogICAgICBhc3NpZ25TbG90cyhzbG90cywgY2hpbGRyZW4sIG9wdGltaXplZCk7DQogICAgICBpZiAob3B0aW1pemVkKSB7DQogICAgICAgIGRlZihzbG90cywgIl8iLCB0eXBlLCB0cnVlKTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgbm9ybWFsaXplT2JqZWN0U2xvdHMoY2hpbGRyZW4sIHNsb3RzKTsNCiAgICB9DQogIH0gZWxzZSBpZiAoY2hpbGRyZW4pIHsNCiAgICBub3JtYWxpemVWTm9kZVNsb3RzKGluc3RhbmNlLCBjaGlsZHJlbik7DQogIH0NCn07DQpjb25zdCB1cGRhdGVTbG90cyA9IChpbnN0YW5jZSwgY2hpbGRyZW4sIG9wdGltaXplZCkgPT4gew0KICBjb25zdCB7IHZub2RlLCBzbG90cyB9ID0gaW5zdGFuY2U7DQogIGxldCBuZWVkRGVsZXRpb25DaGVjayA9IHRydWU7DQogIGxldCBkZWxldGlvbkNvbXBhcmlzb25UYXJnZXQgPSBFTVBUWV9PQko7DQogIGlmICh2bm9kZS5zaGFwZUZsYWcgJiAzMikgew0KICAgIGNvbnN0IHR5cGUgPSBjaGlsZHJlbi5fOw0KICAgIGlmICh0eXBlKSB7DQogICAgICBpZiAoaXNIbXJVcGRhdGluZykgew0KICAgICAgICBhc3NpZ25TbG90cyhzbG90cywgY2hpbGRyZW4sIG9wdGltaXplZCk7DQogICAgICAgIHRyaWdnZXIoaW5zdGFuY2UsICJzZXQiLCAiJHNsb3RzIik7DQogICAgICB9IGVsc2UgaWYgKG9wdGltaXplZCAmJiB0eXBlID09PSAxKSB7DQogICAgICAgIG5lZWREZWxldGlvbkNoZWNrID0gZmFsc2U7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBhc3NpZ25TbG90cyhzbG90cywgY2hpbGRyZW4sIG9wdGltaXplZCk7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIG5lZWREZWxldGlvbkNoZWNrID0gIWNoaWxkcmVuLiRzdGFibGU7DQogICAgICBub3JtYWxpemVPYmplY3RTbG90cyhjaGlsZHJlbiwgc2xvdHMpOw0KICAgIH0NCiAgICBkZWxldGlvbkNvbXBhcmlzb25UYXJnZXQgPSBjaGlsZHJlbjsNCiAgfSBlbHNlIGlmIChjaGlsZHJlbikgew0KICAgIG5vcm1hbGl6ZVZOb2RlU2xvdHMoaW5zdGFuY2UsIGNoaWxkcmVuKTsNCiAgICBkZWxldGlvbkNvbXBhcmlzb25UYXJnZXQgPSB7IGRlZmF1bHQ6IDEgfTsNCiAgfQ0KICBpZiAobmVlZERlbGV0aW9uQ2hlY2spIHsNCiAgICBmb3IgKGNvbnN0IGtleSBpbiBzbG90cykgew0KICAgICAgaWYgKCFpc0ludGVybmFsS2V5KGtleSkgJiYgZGVsZXRpb25Db21wYXJpc29uVGFyZ2V0W2tleV0gPT0gbnVsbCkgew0KICAgICAgICBkZWxldGUgc2xvdHNba2V5XTsNCiAgICAgIH0NCiAgICB9DQogIH0NCn07DQoNCmxldCBzdXBwb3J0ZWQ7DQpsZXQgcGVyZjsNCmZ1bmN0aW9uIHN0YXJ0TWVhc3VyZShpbnN0YW5jZSwgdHlwZSkgew0KICBpZiAoaW5zdGFuY2UuYXBwQ29udGV4dC5jb25maWcucGVyZm9ybWFuY2UgJiYgaXNTdXBwb3J0ZWQoKSkgew0KICAgIHBlcmYubWFyayhgdnVlLSR7dHlwZX0tJHtpbnN0YW5jZS51aWR9YCk7DQogIH0NCiAgew0KICAgIGRldnRvb2xzUGVyZlN0YXJ0KGluc3RhbmNlLCB0eXBlLCBpc1N1cHBvcnRlZCgpID8gcGVyZi5ub3coKSA6IERhdGUubm93KCkpOw0KICB9DQp9DQpmdW5jdGlvbiBlbmRNZWFzdXJlKGluc3RhbmNlLCB0eXBlKSB7DQogIGlmIChpbnN0YW5jZS5hcHBDb250ZXh0LmNvbmZpZy5wZXJmb3JtYW5jZSAmJiBpc1N1cHBvcnRlZCgpKSB7DQogICAgY29uc3Qgc3RhcnRUYWcgPSBgdnVlLSR7dHlwZX0tJHtpbnN0YW5jZS51aWR9YDsNCiAgICBjb25zdCBlbmRUYWcgPSBzdGFydFRhZyArIGA6ZW5kYDsNCiAgICBwZXJmLm1hcmsoZW5kVGFnKTsNCiAgICBwZXJmLm1lYXN1cmUoDQogICAgICBgPCR7Zm9ybWF0Q29tcG9uZW50TmFtZShpbnN0YW5jZSwgaW5zdGFuY2UudHlwZSl9PiAke3R5cGV9YCwNCiAgICAgIHN0YXJ0VGFnLA0KICAgICAgZW5kVGFnDQogICAgKTsNCiAgICBwZXJmLmNsZWFyTWFya3Moc3RhcnRUYWcpOw0KICAgIHBlcmYuY2xlYXJNYXJrcyhlbmRUYWcpOw0KICB9DQogIHsNCiAgICBkZXZ0b29sc1BlcmZFbmQoaW5zdGFuY2UsIHR5cGUsIGlzU3VwcG9ydGVkKCkgPyBwZXJmLm5vdygpIDogRGF0ZS5ub3coKSk7DQogIH0NCn0NCmZ1bmN0aW9uIGlzU3VwcG9ydGVkKCkgew0KICBpZiAoc3VwcG9ydGVkICE9PSB2b2lkIDApIHsNCiAgICByZXR1cm4gc3VwcG9ydGVkOw0KICB9DQogIGlmICh0eXBlb2Ygd2luZG93ICE9PSAidW5kZWZpbmVkIiAmJiB3aW5kb3cucGVyZm9ybWFuY2UpIHsNCiAgICBzdXBwb3J0ZWQgPSB0cnVlOw0KICAgIHBlcmYgPSB3aW5kb3cucGVyZm9ybWFuY2U7DQogIH0gZWxzZSB7DQogICAgc3VwcG9ydGVkID0gZmFsc2U7DQogIH0NCiAgcmV0dXJuIHN1cHBvcnRlZDsNCn0NCg0KY29uc3QgcXVldWVQb3N0UmVuZGVyRWZmZWN0ID0gcXVldWVFZmZlY3RXaXRoU3VzcGVuc2UgOw0KZnVuY3Rpb24gY3JlYXRlUmVuZGVyZXIob3B0aW9ucykgew0KICByZXR1cm4gYmFzZUNyZWF0ZVJlbmRlcmVyKG9wdGlvbnMpOw0KfQ0KZnVuY3Rpb24gYmFzZUNyZWF0ZVJlbmRlcmVyKG9wdGlvbnMsIGNyZWF0ZUh5ZHJhdGlvbkZucykgew0KICBjb25zdCB0YXJnZXQgPSBnZXRHbG9iYWxUaGlzKCk7DQogIHRhcmdldC5fX1ZVRV9fID0gdHJ1ZTsNCiAgew0KICAgIHNldERldnRvb2xzSG9vayh0YXJnZXQuX19WVUVfREVWVE9PTFNfR0xPQkFMX0hPT0tfXywgdGFyZ2V0KTsNCiAgfQ0KICBjb25zdCB7DQogICAgaW5zZXJ0OiBob3N0SW5zZXJ0LA0KICAgIHJlbW92ZTogaG9zdFJlbW92ZSwNCiAgICBwYXRjaFByb3A6IGhvc3RQYXRjaFByb3AsDQogICAgY3JlYXRlRWxlbWVudDogaG9zdENyZWF0ZUVsZW1lbnQsDQogICAgY3JlYXRlVGV4dDogaG9zdENyZWF0ZVRleHQsDQogICAgY3JlYXRlQ29tbWVudDogaG9zdENyZWF0ZUNvbW1lbnQsDQogICAgc2V0VGV4dDogaG9zdFNldFRleHQsDQogICAgc2V0RWxlbWVudFRleHQ6IGhvc3RTZXRFbGVtZW50VGV4dCwNCiAgICBwYXJlbnROb2RlOiBob3N0UGFyZW50Tm9kZSwNCiAgICBuZXh0U2libGluZzogaG9zdE5leHRTaWJsaW5nLA0KICAgIHNldFNjb3BlSWQ6IGhvc3RTZXRTY29wZUlkID0gTk9PUCwNCiAgICBpbnNlcnRTdGF0aWNDb250ZW50OiBob3N0SW5zZXJ0U3RhdGljQ29udGVudA0KICB9ID0gb3B0aW9uczsNCiAgY29uc3QgcGF0Y2ggPSAobjEsIG4yLCBjb250YWluZXIsIGFuY2hvciA9IG51bGwsIHBhcmVudENvbXBvbmVudCA9IG51bGwsIHBhcmVudFN1c3BlbnNlID0gbnVsbCwgbmFtZXNwYWNlID0gdm9pZCAwLCBzbG90U2NvcGVJZHMgPSBudWxsLCBvcHRpbWl6ZWQgPSBpc0htclVwZGF0aW5nID8gZmFsc2UgOiAhIW4yLmR5bmFtaWNDaGlsZHJlbikgPT4gew0KICAgIGlmIChuMSA9PT0gbjIpIHsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgaWYgKG4xICYmICFpc1NhbWVWTm9kZVR5cGUobjEsIG4yKSkgew0KICAgICAgYW5jaG9yID0gZ2V0TmV4dEhvc3ROb2RlKG4xKTsNCiAgICAgIHVubW91bnQobjEsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIHRydWUpOw0KICAgICAgbjEgPSBudWxsOw0KICAgIH0NCiAgICBpZiAobjIucGF0Y2hGbGFnID09PSAtMikgew0KICAgICAgb3B0aW1pemVkID0gZmFsc2U7DQogICAgICBuMi5keW5hbWljQ2hpbGRyZW4gPSBudWxsOw0KICAgIH0NCiAgICBjb25zdCB7IHR5cGUsIHJlZiwgc2hhcGVGbGFnIH0gPSBuMjsNCiAgICBzd2l0Y2ggKHR5cGUpIHsNCiAgICAgIGNhc2UgVGV4dDoNCiAgICAgICAgcHJvY2Vzc1RleHQobjEsIG4yLCBjb250YWluZXIsIGFuY2hvcik7DQogICAgICAgIGJyZWFrOw0KICAgICAgY2FzZSBDb21tZW50Og0KICAgICAgICBwcm9jZXNzQ29tbWVudE5vZGUobjEsIG4yLCBjb250YWluZXIsIGFuY2hvcik7DQogICAgICAgIGJyZWFrOw0KICAgICAgY2FzZSBTdGF0aWM6DQogICAgICAgIGlmIChuMSA9PSBudWxsKSB7DQogICAgICAgICAgbW91bnRTdGF0aWNOb2RlKG4yLCBjb250YWluZXIsIGFuY2hvciwgbmFtZXNwYWNlKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBwYXRjaFN0YXRpY05vZGUobjEsIG4yLCBjb250YWluZXIsIG5hbWVzcGFjZSk7DQogICAgICAgIH0NCiAgICAgICAgYnJlYWs7DQogICAgICBjYXNlIEZyYWdtZW50Og0KICAgICAgICBwcm9jZXNzRnJhZ21lbnQoDQogICAgICAgICAgbjEsDQogICAgICAgICAgbjIsDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIGFuY2hvciwNCiAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgKTsNCiAgICAgICAgYnJlYWs7DQogICAgICBkZWZhdWx0Og0KICAgICAgICBpZiAoc2hhcGVGbGFnICYgMSkgew0KICAgICAgICAgIHByb2Nlc3NFbGVtZW50KA0KICAgICAgICAgICAgbjEsDQogICAgICAgICAgICBuMiwNCiAgICAgICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgICAgIGFuY2hvciwNCiAgICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICAgKTsNCiAgICAgICAgfSBlbHNlIGlmIChzaGFwZUZsYWcgJiA2KSB7DQogICAgICAgICAgcHJvY2Vzc0NvbXBvbmVudCgNCiAgICAgICAgICAgIG4xLA0KICAgICAgICAgICAgbjIsDQogICAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgICBhbmNob3IsDQogICAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICAgICk7DQogICAgICAgIH0gZWxzZSBpZiAoc2hhcGVGbGFnICYgNjQpIHsNCiAgICAgICAgICB0eXBlLnByb2Nlc3MoDQogICAgICAgICAgICBuMSwNCiAgICAgICAgICAgIG4yLA0KICAgICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgICBvcHRpbWl6ZWQsDQogICAgICAgICAgICBpbnRlcm5hbHMNCiAgICAgICAgICApOw0KICAgICAgICB9IGVsc2UgaWYgKHNoYXBlRmxhZyAmIDEyOCkgew0KICAgICAgICAgIHR5cGUucHJvY2VzcygNCiAgICAgICAgICAgIG4xLA0KICAgICAgICAgICAgbjIsDQogICAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgICBhbmNob3IsDQogICAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICAgIG9wdGltaXplZCwNCiAgICAgICAgICAgIGludGVybmFscw0KICAgICAgICAgICk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgd2FybiQxKCJJbnZhbGlkIFZOb2RlIHR5cGU6IiwgdHlwZSwgYCgke3R5cGVvZiB0eXBlfSlgKTsNCiAgICAgICAgfQ0KICAgIH0NCiAgICBpZiAocmVmICE9IG51bGwgJiYgcGFyZW50Q29tcG9uZW50KSB7DQogICAgICBzZXRSZWYocmVmLCBuMSAmJiBuMS5yZWYsIHBhcmVudFN1c3BlbnNlLCBuMiB8fCBuMSwgIW4yKTsNCiAgICB9IGVsc2UgaWYgKHJlZiA9PSBudWxsICYmIG4xICYmIG4xLnJlZiAhPSBudWxsKSB7DQogICAgICBzZXRSZWYobjEucmVmLCBudWxsLCBwYXJlbnRTdXNwZW5zZSwgbjEsIHRydWUpOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgcHJvY2Vzc1RleHQgPSAobjEsIG4yLCBjb250YWluZXIsIGFuY2hvcikgPT4gew0KICAgIGlmIChuMSA9PSBudWxsKSB7DQogICAgICBob3N0SW5zZXJ0KA0KICAgICAgICBuMi5lbCA9IGhvc3RDcmVhdGVUZXh0KG4yLmNoaWxkcmVuKSwNCiAgICAgICAgY29udGFpbmVyLA0KICAgICAgICBhbmNob3INCiAgICAgICk7DQogICAgfSBlbHNlIHsNCiAgICAgIGNvbnN0IGVsID0gbjIuZWwgPSBuMS5lbDsNCiAgICAgIGlmIChuMi5jaGlsZHJlbiAhPT0gbjEuY2hpbGRyZW4pIHsNCiAgICAgICAgaG9zdFNldFRleHQoZWwsIG4yLmNoaWxkcmVuKTsNCiAgICAgIH0NCiAgICB9DQogIH07DQogIGNvbnN0IHByb2Nlc3NDb21tZW50Tm9kZSA9IChuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yKSA9PiB7DQogICAgaWYgKG4xID09IG51bGwpIHsNCiAgICAgIGhvc3RJbnNlcnQoDQogICAgICAgIG4yLmVsID0gaG9zdENyZWF0ZUNvbW1lbnQobjIuY2hpbGRyZW4gfHwgIiIpLA0KICAgICAgICBjb250YWluZXIsDQogICAgICAgIGFuY2hvcg0KICAgICAgKTsNCiAgICB9IGVsc2Ugew0KICAgICAgbjIuZWwgPSBuMS5lbDsNCiAgICB9DQogIH07DQogIGNvbnN0IG1vdW50U3RhdGljTm9kZSA9IChuMiwgY29udGFpbmVyLCBhbmNob3IsIG5hbWVzcGFjZSkgPT4gew0KICAgIFtuMi5lbCwgbjIuYW5jaG9yXSA9IGhvc3RJbnNlcnRTdGF0aWNDb250ZW50KA0KICAgICAgbjIuY2hpbGRyZW4sDQogICAgICBjb250YWluZXIsDQogICAgICBhbmNob3IsDQogICAgICBuYW1lc3BhY2UsDQogICAgICBuMi5lbCwNCiAgICAgIG4yLmFuY2hvcg0KICAgICk7DQogIH07DQogIGNvbnN0IHBhdGNoU3RhdGljTm9kZSA9IChuMSwgbjIsIGNvbnRhaW5lciwgbmFtZXNwYWNlKSA9PiB7DQogICAgaWYgKG4yLmNoaWxkcmVuICE9PSBuMS5jaGlsZHJlbikgew0KICAgICAgY29uc3QgYW5jaG9yID0gaG9zdE5leHRTaWJsaW5nKG4xLmFuY2hvcik7DQogICAgICByZW1vdmVTdGF0aWNOb2RlKG4xKTsNCiAgICAgIFtuMi5lbCwgbjIuYW5jaG9yXSA9IGhvc3RJbnNlcnRTdGF0aWNDb250ZW50KA0KICAgICAgICBuMi5jaGlsZHJlbiwNCiAgICAgICAgY29udGFpbmVyLA0KICAgICAgICBhbmNob3IsDQogICAgICAgIG5hbWVzcGFjZQ0KICAgICAgKTsNCiAgICB9IGVsc2Ugew0KICAgICAgbjIuZWwgPSBuMS5lbDsNCiAgICAgIG4yLmFuY2hvciA9IG4xLmFuY2hvcjsNCiAgICB9DQogIH07DQogIGNvbnN0IG1vdmVTdGF0aWNOb2RlID0gKHsgZWwsIGFuY2hvciB9LCBjb250YWluZXIsIG5leHRTaWJsaW5nKSA9PiB7DQogICAgbGV0IG5leHQ7DQogICAgd2hpbGUgKGVsICYmIGVsICE9PSBhbmNob3IpIHsNCiAgICAgIG5leHQgPSBob3N0TmV4dFNpYmxpbmcoZWwpOw0KICAgICAgaG9zdEluc2VydChlbCwgY29udGFpbmVyLCBuZXh0U2libGluZyk7DQogICAgICBlbCA9IG5leHQ7DQogICAgfQ0KICAgIGhvc3RJbnNlcnQoYW5jaG9yLCBjb250YWluZXIsIG5leHRTaWJsaW5nKTsNCiAgfTsNCiAgY29uc3QgcmVtb3ZlU3RhdGljTm9kZSA9ICh7IGVsLCBhbmNob3IgfSkgPT4gew0KICAgIGxldCBuZXh0Ow0KICAgIHdoaWxlIChlbCAmJiBlbCAhPT0gYW5jaG9yKSB7DQogICAgICBuZXh0ID0gaG9zdE5leHRTaWJsaW5nKGVsKTsNCiAgICAgIGhvc3RSZW1vdmUoZWwpOw0KICAgICAgZWwgPSBuZXh0Ow0KICAgIH0NCiAgICBob3N0UmVtb3ZlKGFuY2hvcik7DQogIH07DQogIGNvbnN0IHByb2Nlc3NFbGVtZW50ID0gKG4xLCBuMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQpID0+IHsNCiAgICBpZiAobjIudHlwZSA9PT0gInN2ZyIpIHsNCiAgICAgIG5hbWVzcGFjZSA9ICJzdmciOw0KICAgIH0gZWxzZSBpZiAobjIudHlwZSA9PT0gIm1hdGgiKSB7DQogICAgICBuYW1lc3BhY2UgPSAibWF0aG1sIjsNCiAgICB9DQogICAgaWYgKG4xID09IG51bGwpIHsNCiAgICAgIG1vdW50RWxlbWVudCgNCiAgICAgICAgbjIsDQogICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgYW5jaG9yLA0KICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgb3B0aW1pemVkDQogICAgICApOw0KICAgIH0gZWxzZSB7DQogICAgICBwYXRjaEVsZW1lbnQoDQogICAgICAgIG4xLA0KICAgICAgICBuMiwNCiAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgIG9wdGltaXplZA0KICAgICAgKTsNCiAgICB9DQogIH07DQogIGNvbnN0IG1vdW50RWxlbWVudCA9ICh2bm9kZSwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQpID0+IHsNCiAgICBsZXQgZWw7DQogICAgbGV0IHZub2RlSG9vazsNCiAgICBjb25zdCB7IHByb3BzLCBzaGFwZUZsYWcsIHRyYW5zaXRpb24sIGRpcnMgfSA9IHZub2RlOw0KICAgIGVsID0gdm5vZGUuZWwgPSBob3N0Q3JlYXRlRWxlbWVudCgNCiAgICAgIHZub2RlLnR5cGUsDQogICAgICBuYW1lc3BhY2UsDQogICAgICBwcm9wcyAmJiBwcm9wcy5pcywNCiAgICAgIHByb3BzDQogICAgKTsNCiAgICBpZiAoc2hhcGVGbGFnICYgOCkgew0KICAgICAgaG9zdFNldEVsZW1lbnRUZXh0KGVsLCB2bm9kZS5jaGlsZHJlbik7DQogICAgfSBlbHNlIGlmIChzaGFwZUZsYWcgJiAxNikgew0KICAgICAgbW91bnRDaGlsZHJlbigNCiAgICAgICAgdm5vZGUuY2hpbGRyZW4sDQogICAgICAgIGVsLA0KICAgICAgICBudWxsLA0KICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICByZXNvbHZlQ2hpbGRyZW5OYW1lc3BhY2Uodm5vZGUsIG5hbWVzcGFjZSksDQogICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgb3B0aW1pemVkDQogICAgICApOw0KICAgIH0NCiAgICBpZiAoZGlycykgew0KICAgICAgaW52b2tlRGlyZWN0aXZlSG9vayh2bm9kZSwgbnVsbCwgcGFyZW50Q29tcG9uZW50LCAiY3JlYXRlZCIpOw0KICAgIH0NCiAgICBzZXRTY29wZUlkKGVsLCB2bm9kZSwgdm5vZGUuc2NvcGVJZCwgc2xvdFNjb3BlSWRzLCBwYXJlbnRDb21wb25lbnQpOw0KICAgIGlmIChwcm9wcykgew0KICAgICAgZm9yIChjb25zdCBrZXkgaW4gcHJvcHMpIHsNCiAgICAgICAgaWYgKGtleSAhPT0gInZhbHVlIiAmJiAhaXNSZXNlcnZlZFByb3Aoa2V5KSkgew0KICAgICAgICAgIGhvc3RQYXRjaFByb3AoZWwsIGtleSwgbnVsbCwgcHJvcHNba2V5XSwgbmFtZXNwYWNlLCBwYXJlbnRDb21wb25lbnQpOw0KICAgICAgICB9DQogICAgICB9DQogICAgICBpZiAoInZhbHVlIiBpbiBwcm9wcykgew0KICAgICAgICBob3N0UGF0Y2hQcm9wKGVsLCAidmFsdWUiLCBudWxsLCBwcm9wcy52YWx1ZSwgbmFtZXNwYWNlKTsNCiAgICAgIH0NCiAgICAgIGlmICh2bm9kZUhvb2sgPSBwcm9wcy5vblZub2RlQmVmb3JlTW91bnQpIHsNCiAgICAgICAgaW52b2tlVk5vZGVIb29rKHZub2RlSG9vaywgcGFyZW50Q29tcG9uZW50LCB2bm9kZSk7DQogICAgICB9DQogICAgfQ0KICAgIHsNCiAgICAgIGRlZihlbCwgIl9fdm5vZGUiLCB2bm9kZSwgdHJ1ZSk7DQogICAgICBkZWYoZWwsICJfX3Z1ZVBhcmVudENvbXBvbmVudCIsIHBhcmVudENvbXBvbmVudCwgdHJ1ZSk7DQogICAgfQ0KICAgIGlmIChkaXJzKSB7DQogICAgICBpbnZva2VEaXJlY3RpdmVIb29rKHZub2RlLCBudWxsLCBwYXJlbnRDb21wb25lbnQsICJiZWZvcmVNb3VudCIpOw0KICAgIH0NCiAgICBjb25zdCBuZWVkQ2FsbFRyYW5zaXRpb25Ib29rcyA9IG5lZWRUcmFuc2l0aW9uKHBhcmVudFN1c3BlbnNlLCB0cmFuc2l0aW9uKTsNCiAgICBpZiAobmVlZENhbGxUcmFuc2l0aW9uSG9va3MpIHsNCiAgICAgIHRyYW5zaXRpb24uYmVmb3JlRW50ZXIoZWwpOw0KICAgIH0NCiAgICBob3N0SW5zZXJ0KGVsLCBjb250YWluZXIsIGFuY2hvcik7DQogICAgaWYgKCh2bm9kZUhvb2sgPSBwcm9wcyAmJiBwcm9wcy5vblZub2RlTW91bnRlZCkgfHwgbmVlZENhbGxUcmFuc2l0aW9uSG9va3MgfHwgZGlycykgew0KICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KCgpID0+IHsNCiAgICAgICAgdm5vZGVIb29rICYmIGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIHBhcmVudENvbXBvbmVudCwgdm5vZGUpOw0KICAgICAgICBuZWVkQ2FsbFRyYW5zaXRpb25Ib29rcyAmJiB0cmFuc2l0aW9uLmVudGVyKGVsKTsNCiAgICAgICAgZGlycyAmJiBpbnZva2VEaXJlY3RpdmVIb29rKHZub2RlLCBudWxsLCBwYXJlbnRDb21wb25lbnQsICJtb3VudGVkIik7DQogICAgICB9LCBwYXJlbnRTdXNwZW5zZSk7DQogICAgfQ0KICB9Ow0KICBjb25zdCBzZXRTY29wZUlkID0gKGVsLCB2bm9kZSwgc2NvcGVJZCwgc2xvdFNjb3BlSWRzLCBwYXJlbnRDb21wb25lbnQpID0+IHsNCiAgICBpZiAoc2NvcGVJZCkgew0KICAgICAgaG9zdFNldFNjb3BlSWQoZWwsIHNjb3BlSWQpOw0KICAgIH0NCiAgICBpZiAoc2xvdFNjb3BlSWRzKSB7DQogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNsb3RTY29wZUlkcy5sZW5ndGg7IGkrKykgew0KICAgICAgICBob3N0U2V0U2NvcGVJZChlbCwgc2xvdFNjb3BlSWRzW2ldKTsNCiAgICAgIH0NCiAgICB9DQogICAgaWYgKHBhcmVudENvbXBvbmVudCkgew0KICAgICAgbGV0IHN1YlRyZWUgPSBwYXJlbnRDb21wb25lbnQuc3ViVHJlZTsNCiAgICAgIGlmIChzdWJUcmVlLnBhdGNoRmxhZyA+IDAgJiYgc3ViVHJlZS5wYXRjaEZsYWcgJiAyMDQ4KSB7DQogICAgICAgIHN1YlRyZWUgPSBmaWx0ZXJTaW5nbGVSb290KHN1YlRyZWUuY2hpbGRyZW4pIHx8IHN1YlRyZWU7DQogICAgICB9DQogICAgICBpZiAodm5vZGUgPT09IHN1YlRyZWUgfHwgaXNTdXNwZW5zZShzdWJUcmVlLnR5cGUpICYmIChzdWJUcmVlLnNzQ29udGVudCA9PT0gdm5vZGUgfHwgc3ViVHJlZS5zc0ZhbGxiYWNrID09PSB2bm9kZSkpIHsNCiAgICAgICAgY29uc3QgcGFyZW50Vk5vZGUgPSBwYXJlbnRDb21wb25lbnQudm5vZGU7DQogICAgICAgIHNldFNjb3BlSWQoDQogICAgICAgICAgZWwsDQogICAgICAgICAgcGFyZW50Vk5vZGUsDQogICAgICAgICAgcGFyZW50Vk5vZGUuc2NvcGVJZCwNCiAgICAgICAgICBwYXJlbnRWTm9kZS5zbG90U2NvcGVJZHMsDQogICAgICAgICAgcGFyZW50Q29tcG9uZW50LnBhcmVudA0KICAgICAgICApOw0KICAgICAgfQ0KICAgIH0NCiAgfTsNCiAgY29uc3QgbW91bnRDaGlsZHJlbiA9IChjaGlsZHJlbiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQsIHN0YXJ0ID0gMCkgPT4gew0KICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7DQogICAgICBjb25zdCBjaGlsZCA9IGNoaWxkcmVuW2ldID0gb3B0aW1pemVkID8gY2xvbmVJZk1vdW50ZWQoY2hpbGRyZW5baV0pIDogbm9ybWFsaXplVk5vZGUkMShjaGlsZHJlbltpXSk7DQogICAgICBwYXRjaCgNCiAgICAgICAgbnVsbCwNCiAgICAgICAgY2hpbGQsDQogICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgYW5jaG9yLA0KICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgb3B0aW1pemVkDQogICAgICApOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgcGF0Y2hFbGVtZW50ID0gKG4xLCBuMiwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgbmFtZXNwYWNlLCBzbG90U2NvcGVJZHMsIG9wdGltaXplZCkgPT4gew0KICAgIGNvbnN0IGVsID0gbjIuZWwgPSBuMS5lbDsNCiAgICB7DQogICAgICBlbC5fX3Zub2RlID0gbjI7DQogICAgfQ0KICAgIGxldCB7IHBhdGNoRmxhZywgZHluYW1pY0NoaWxkcmVuLCBkaXJzIH0gPSBuMjsNCiAgICBwYXRjaEZsYWcgfD0gbjEucGF0Y2hGbGFnICYgMTY7DQogICAgY29uc3Qgb2xkUHJvcHMgPSBuMS5wcm9wcyB8fCBFTVBUWV9PQko7DQogICAgY29uc3QgbmV3UHJvcHMgPSBuMi5wcm9wcyB8fCBFTVBUWV9PQko7DQogICAgbGV0IHZub2RlSG9vazsNCiAgICBwYXJlbnRDb21wb25lbnQgJiYgdG9nZ2xlUmVjdXJzZShwYXJlbnRDb21wb25lbnQsIGZhbHNlKTsNCiAgICBpZiAodm5vZGVIb29rID0gbmV3UHJvcHMub25Wbm9kZUJlZm9yZVVwZGF0ZSkgew0KICAgICAgaW52b2tlVk5vZGVIb29rKHZub2RlSG9vaywgcGFyZW50Q29tcG9uZW50LCBuMiwgbjEpOw0KICAgIH0NCiAgICBpZiAoZGlycykgew0KICAgICAgaW52b2tlRGlyZWN0aXZlSG9vayhuMiwgbjEsIHBhcmVudENvbXBvbmVudCwgImJlZm9yZVVwZGF0ZSIpOw0KICAgIH0NCiAgICBwYXJlbnRDb21wb25lbnQgJiYgdG9nZ2xlUmVjdXJzZShwYXJlbnRDb21wb25lbnQsIHRydWUpOw0KICAgIGlmIChpc0htclVwZGF0aW5nKSB7DQogICAgICBwYXRjaEZsYWcgPSAwOw0KICAgICAgb3B0aW1pemVkID0gZmFsc2U7DQogICAgICBkeW5hbWljQ2hpbGRyZW4gPSBudWxsOw0KICAgIH0NCiAgICBpZiAob2xkUHJvcHMuaW5uZXJIVE1MICYmIG5ld1Byb3BzLmlubmVySFRNTCA9PSBudWxsIHx8IG9sZFByb3BzLnRleHRDb250ZW50ICYmIG5ld1Byb3BzLnRleHRDb250ZW50ID09IG51bGwpIHsNCiAgICAgIGhvc3RTZXRFbGVtZW50VGV4dChlbCwgIiIpOw0KICAgIH0NCiAgICBpZiAoZHluYW1pY0NoaWxkcmVuKSB7DQogICAgICBwYXRjaEJsb2NrQ2hpbGRyZW4oDQogICAgICAgIG4xLmR5bmFtaWNDaGlsZHJlbiwNCiAgICAgICAgZHluYW1pY0NoaWxkcmVuLA0KICAgICAgICBlbCwNCiAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgcmVzb2x2ZUNoaWxkcmVuTmFtZXNwYWNlKG4yLCBuYW1lc3BhY2UpLA0KICAgICAgICBzbG90U2NvcGVJZHMNCiAgICAgICk7DQogICAgICB7DQogICAgICAgIHRyYXZlcnNlU3RhdGljQ2hpbGRyZW4objEsIG4yKTsNCiAgICAgIH0NCiAgICB9IGVsc2UgaWYgKCFvcHRpbWl6ZWQpIHsNCiAgICAgIHBhdGNoQ2hpbGRyZW4oDQogICAgICAgIG4xLA0KICAgICAgICBuMiwNCiAgICAgICAgZWwsDQogICAgICAgIG51bGwsDQogICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgIHJlc29sdmVDaGlsZHJlbk5hbWVzcGFjZShuMiwgbmFtZXNwYWNlKSwNCiAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICBmYWxzZQ0KICAgICAgKTsNCiAgICB9DQogICAgaWYgKHBhdGNoRmxhZyA+IDApIHsNCiAgICAgIGlmIChwYXRjaEZsYWcgJiAxNikgew0KICAgICAgICBwYXRjaFByb3BzKGVsLCBvbGRQcm9wcywgbmV3UHJvcHMsIHBhcmVudENvbXBvbmVudCwgbmFtZXNwYWNlKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGlmIChwYXRjaEZsYWcgJiAyKSB7DQogICAgICAgICAgaWYgKG9sZFByb3BzLmNsYXNzICE9PSBuZXdQcm9wcy5jbGFzcykgew0KICAgICAgICAgICAgaG9zdFBhdGNoUHJvcChlbCwgImNsYXNzIiwgbnVsbCwgbmV3UHJvcHMuY2xhc3MsIG5hbWVzcGFjZSk7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGlmIChwYXRjaEZsYWcgJiA0KSB7DQogICAgICAgICAgaG9zdFBhdGNoUHJvcChlbCwgInN0eWxlIiwgb2xkUHJvcHMuc3R5bGUsIG5ld1Byb3BzLnN0eWxlLCBuYW1lc3BhY2UpOw0KICAgICAgICB9DQogICAgICAgIGlmIChwYXRjaEZsYWcgJiA4KSB7DQogICAgICAgICAgY29uc3QgcHJvcHNUb1VwZGF0ZSA9IG4yLmR5bmFtaWNQcm9wczsNCiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByb3BzVG9VcGRhdGUubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgICAgIGNvbnN0IGtleSA9IHByb3BzVG9VcGRhdGVbaV07DQogICAgICAgICAgICBjb25zdCBwcmV2ID0gb2xkUHJvcHNba2V5XTsNCiAgICAgICAgICAgIGNvbnN0IG5leHQgPSBuZXdQcm9wc1trZXldOw0KICAgICAgICAgICAgaWYgKG5leHQgIT09IHByZXYgfHwga2V5ID09PSAidmFsdWUiKSB7DQogICAgICAgICAgICAgIGhvc3RQYXRjaFByb3AoZWwsIGtleSwgcHJldiwgbmV4dCwgbmFtZXNwYWNlLCBwYXJlbnRDb21wb25lbnQpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgaWYgKHBhdGNoRmxhZyAmIDEpIHsNCiAgICAgICAgaWYgKG4xLmNoaWxkcmVuICE9PSBuMi5jaGlsZHJlbikgew0KICAgICAgICAgIGhvc3RTZXRFbGVtZW50VGV4dChlbCwgbjIuY2hpbGRyZW4pOw0KICAgICAgICB9DQogICAgICB9DQogICAgfSBlbHNlIGlmICghb3B0aW1pemVkICYmIGR5bmFtaWNDaGlsZHJlbiA9PSBudWxsKSB7DQogICAgICBwYXRjaFByb3BzKGVsLCBvbGRQcm9wcywgbmV3UHJvcHMsIHBhcmVudENvbXBvbmVudCwgbmFtZXNwYWNlKTsNCiAgICB9DQogICAgaWYgKCh2bm9kZUhvb2sgPSBuZXdQcm9wcy5vblZub2RlVXBkYXRlZCkgfHwgZGlycykgew0KICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KCgpID0+IHsNCiAgICAgICAgdm5vZGVIb29rICYmIGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIHBhcmVudENvbXBvbmVudCwgbjIsIG4xKTsNCiAgICAgICAgZGlycyAmJiBpbnZva2VEaXJlY3RpdmVIb29rKG4yLCBuMSwgcGFyZW50Q29tcG9uZW50LCAidXBkYXRlZCIpOw0KICAgICAgfSwgcGFyZW50U3VzcGVuc2UpOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgcGF0Y2hCbG9ja0NoaWxkcmVuID0gKG9sZENoaWxkcmVuLCBuZXdDaGlsZHJlbiwgZmFsbGJhY2tDb250YWluZXIsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzKSA9PiB7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuZXdDaGlsZHJlbi5sZW5ndGg7IGkrKykgew0KICAgICAgY29uc3Qgb2xkVk5vZGUgPSBvbGRDaGlsZHJlbltpXTsNCiAgICAgIGNvbnN0IG5ld1ZOb2RlID0gbmV3Q2hpbGRyZW5baV07DQogICAgICBjb25zdCBjb250YWluZXIgPSAoDQogICAgICAgIC8vIG9sZFZOb2RlIG1heSBiZSBhbiBlcnJvcmVkIGFzeW5jIHNldHVwKCkgY29tcG9uZW50IGluc2lkZSBTdXNwZW5zZQ0KICAgICAgICAvLyB3aGljaCB3aWxsIG5vdCBoYXZlIGEgbW91bnRlZCBlbGVtZW50DQogICAgICAgIG9sZFZOb2RlLmVsICYmIC8vIC0gSW4gdGhlIGNhc2Ugb2YgYSBGcmFnbWVudCwgd2UgbmVlZCB0byBwcm92aWRlIHRoZSBhY3R1YWwgcGFyZW50DQogICAgICAgIC8vIG9mIHRoZSBGcmFnbWVudCBpdHNlbGYgc28gaXQgY2FuIG1vdmUgaXRzIGNoaWxkcmVuLg0KICAgICAgICAob2xkVk5vZGUudHlwZSA9PT0gRnJhZ21lbnQgfHwgLy8gLSBJbiB0aGUgY2FzZSBvZiBkaWZmZXJlbnQgbm9kZXMsIHRoZXJlIGlzIGdvaW5nIHRvIGJlIGEgcmVwbGFjZW1lbnQNCiAgICAgICAgLy8gd2hpY2ggYWxzbyByZXF1aXJlcyB0aGUgY29ycmVjdCBwYXJlbnQgY29udGFpbmVyDQogICAgICAgICFpc1NhbWVWTm9kZVR5cGUob2xkVk5vZGUsIG5ld1ZOb2RlKSB8fCAvLyAtIEluIHRoZSBjYXNlIG9mIGEgY29tcG9uZW50LCBpdCBjb3VsZCBjb250YWluIGFueXRoaW5nLg0KICAgICAgICBvbGRWTm9kZS5zaGFwZUZsYWcgJiAoNiB8IDY0IHwgMTI4KSkgPyBob3N0UGFyZW50Tm9kZShvbGRWTm9kZS5lbCkgOiAoDQogICAgICAgICAgLy8gSW4gb3RoZXIgY2FzZXMsIHRoZSBwYXJlbnQgY29udGFpbmVyIGlzIG5vdCBhY3R1YWxseSB1c2VkIHNvIHdlDQogICAgICAgICAgLy8ganVzdCBwYXNzIHRoZSBibG9jayBlbGVtZW50IGhlcmUgdG8gYXZvaWQgYSBET00gcGFyZW50Tm9kZSBjYWxsLg0KICAgICAgICAgIGZhbGxiYWNrQ29udGFpbmVyDQogICAgICAgICkNCiAgICAgICk7DQogICAgICBwYXRjaCgNCiAgICAgICAgb2xkVk5vZGUsDQogICAgICAgIG5ld1ZOb2RlLA0KICAgICAgICBjb250YWluZXIsDQogICAgICAgIG51bGwsDQogICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICB0cnVlDQogICAgICApOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgcGF0Y2hQcm9wcyA9IChlbCwgb2xkUHJvcHMsIG5ld1Byb3BzLCBwYXJlbnRDb21wb25lbnQsIG5hbWVzcGFjZSkgPT4gew0KICAgIGlmIChvbGRQcm9wcyAhPT0gbmV3UHJvcHMpIHsNCiAgICAgIGlmIChvbGRQcm9wcyAhPT0gRU1QVFlfT0JKKSB7DQogICAgICAgIGZvciAoY29uc3Qga2V5IGluIG9sZFByb3BzKSB7DQogICAgICAgICAgaWYgKCFpc1Jlc2VydmVkUHJvcChrZXkpICYmICEoa2V5IGluIG5ld1Byb3BzKSkgew0KICAgICAgICAgICAgaG9zdFBhdGNoUHJvcCgNCiAgICAgICAgICAgICAgZWwsDQogICAgICAgICAgICAgIGtleSwNCiAgICAgICAgICAgICAgb2xkUHJvcHNba2V5XSwNCiAgICAgICAgICAgICAgbnVsbCwNCiAgICAgICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgICAgICBwYXJlbnRDb21wb25lbnQNCiAgICAgICAgICAgICk7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICB9DQogICAgICBmb3IgKGNvbnN0IGtleSBpbiBuZXdQcm9wcykgew0KICAgICAgICBpZiAoaXNSZXNlcnZlZFByb3Aoa2V5KSkgY29udGludWU7DQogICAgICAgIGNvbnN0IG5leHQgPSBuZXdQcm9wc1trZXldOw0KICAgICAgICBjb25zdCBwcmV2ID0gb2xkUHJvcHNba2V5XTsNCiAgICAgICAgaWYgKG5leHQgIT09IHByZXYgJiYga2V5ICE9PSAidmFsdWUiKSB7DQogICAgICAgICAgaG9zdFBhdGNoUHJvcChlbCwga2V5LCBwcmV2LCBuZXh0LCBuYW1lc3BhY2UsIHBhcmVudENvbXBvbmVudCk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGlmICgidmFsdWUiIGluIG5ld1Byb3BzKSB7DQogICAgICAgIGhvc3RQYXRjaFByb3AoZWwsICJ2YWx1ZSIsIG9sZFByb3BzLnZhbHVlLCBuZXdQcm9wcy52YWx1ZSwgbmFtZXNwYWNlKTsNCiAgICAgIH0NCiAgICB9DQogIH07DQogIGNvbnN0IHByb2Nlc3NGcmFnbWVudCA9IChuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBuYW1lc3BhY2UsIHNsb3RTY29wZUlkcywgb3B0aW1pemVkKSA9PiB7DQogICAgY29uc3QgZnJhZ21lbnRTdGFydEFuY2hvciA9IG4yLmVsID0gbjEgPyBuMS5lbCA6IGhvc3RDcmVhdGVUZXh0KCIiKTsNCiAgICBjb25zdCBmcmFnbWVudEVuZEFuY2hvciA9IG4yLmFuY2hvciA9IG4xID8gbjEuYW5jaG9yIDogaG9zdENyZWF0ZVRleHQoIiIpOw0KICAgIGxldCB7IHBhdGNoRmxhZywgZHluYW1pY0NoaWxkcmVuLCBzbG90U2NvcGVJZHM6IGZyYWdtZW50U2xvdFNjb3BlSWRzIH0gPSBuMjsNCiAgICBpZiAoDQogICAgICAvLyAjNTUyMyBkZXYgcm9vdCBmcmFnbWVudCBtYXkgaW5oZXJpdCBkaXJlY3RpdmVzDQogICAgICBpc0htclVwZGF0aW5nIHx8IHBhdGNoRmxhZyAmIDIwNDgNCiAgICApIHsNCiAgICAgIHBhdGNoRmxhZyA9IDA7DQogICAgICBvcHRpbWl6ZWQgPSBmYWxzZTsNCiAgICAgIGR5bmFtaWNDaGlsZHJlbiA9IG51bGw7DQogICAgfQ0KICAgIGlmIChmcmFnbWVudFNsb3RTY29wZUlkcykgew0KICAgICAgc2xvdFNjb3BlSWRzID0gc2xvdFNjb3BlSWRzID8gc2xvdFNjb3BlSWRzLmNvbmNhdChmcmFnbWVudFNsb3RTY29wZUlkcykgOiBmcmFnbWVudFNsb3RTY29wZUlkczsNCiAgICB9DQogICAgaWYgKG4xID09IG51bGwpIHsNCiAgICAgIGhvc3RJbnNlcnQoZnJhZ21lbnRTdGFydEFuY2hvciwgY29udGFpbmVyLCBhbmNob3IpOw0KICAgICAgaG9zdEluc2VydChmcmFnbWVudEVuZEFuY2hvciwgY29udGFpbmVyLCBhbmNob3IpOw0KICAgICAgbW91bnRDaGlsZHJlbigNCiAgICAgICAgLy8gIzEwMDA3DQogICAgICAgIC8vIHN1Y2ggZnJhZ21lbnQgbGlrZSBgPD48Lz5gIHdpbGwgYmUgY29tcGlsZWQgaW50bw0KICAgICAgICAvLyBhIGZyYWdtZW50IHdoaWNoIGRvZXNuJ3QgaGF2ZSBhIGNoaWxkcmVuLg0KICAgICAgICAvLyBJbiB0aGlzIGNhc2UgZmFsbGJhY2sgdG8gYW4gZW1wdHkgYXJyYXkNCiAgICAgICAgbjIuY2hpbGRyZW4gfHwgW10sDQogICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgZnJhZ21lbnRFbmRBbmNob3IsDQogICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICk7DQogICAgfSBlbHNlIHsNCiAgICAgIGlmIChwYXRjaEZsYWcgPiAwICYmIHBhdGNoRmxhZyAmIDY0ICYmIGR5bmFtaWNDaGlsZHJlbiAmJiAvLyAjMjcxNSB0aGUgcHJldmlvdXMgZnJhZ21lbnQgY291bGQndmUgYmVlbiBhIEJBSUxlZCBvbmUgYXMgYSByZXN1bHQNCiAgICAgIC8vIG9mIHJlbmRlclNsb3QoKSB3aXRoIG5vIHZhbGlkIGNoaWxkcmVuDQogICAgICBuMS5keW5hbWljQ2hpbGRyZW4pIHsNCiAgICAgICAgcGF0Y2hCbG9ja0NoaWxkcmVuKA0KICAgICAgICAgIG4xLmR5bmFtaWNDaGlsZHJlbiwNCiAgICAgICAgICBkeW5hbWljQ2hpbGRyZW4sDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzDQogICAgICAgICk7DQogICAgICAgIHsNCiAgICAgICAgICB0cmF2ZXJzZVN0YXRpY0NoaWxkcmVuKG4xLCBuMik7DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHBhdGNoQ2hpbGRyZW4oDQogICAgICAgICAgbjEsDQogICAgICAgICAgbjIsDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIGZyYWdtZW50RW5kQW5jaG9yLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICApOw0KICAgICAgfQ0KICAgIH0NCiAgfTsNCiAgY29uc3QgcHJvY2Vzc0NvbXBvbmVudCA9IChuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBuYW1lc3BhY2UsIHNsb3RTY29wZUlkcywgb3B0aW1pemVkKSA9PiB7DQogICAgbjIuc2xvdFNjb3BlSWRzID0gc2xvdFNjb3BlSWRzOw0KICAgIGlmIChuMSA9PSBudWxsKSB7DQogICAgICBpZiAobjIuc2hhcGVGbGFnICYgNTEyKSB7DQogICAgICAgIHBhcmVudENvbXBvbmVudC5jdHguYWN0aXZhdGUoDQogICAgICAgICAgbjIsDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIGFuY2hvciwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBtb3VudENvbXBvbmVudCgNCiAgICAgICAgICBuMiwNCiAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICk7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIHVwZGF0ZUNvbXBvbmVudChuMSwgbjIsIG9wdGltaXplZCk7DQogICAgfQ0KICB9Ow0KICBjb25zdCBtb3VudENvbXBvbmVudCA9IChpbml0aWFsVk5vZGUsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBuYW1lc3BhY2UsIG9wdGltaXplZCkgPT4gew0KICAgIGNvbnN0IGluc3RhbmNlID0gKGluaXRpYWxWTm9kZS5jb21wb25lbnQgPSBjcmVhdGVDb21wb25lbnRJbnN0YW5jZSQxKA0KICAgICAgaW5pdGlhbFZOb2RlLA0KICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgcGFyZW50U3VzcGVuc2UNCiAgICApKTsNCiAgICBpZiAoaW5zdGFuY2UudHlwZS5fX2htcklkKSB7DQogICAgICByZWdpc3RlckhNUihpbnN0YW5jZSk7DQogICAgfQ0KICAgIHsNCiAgICAgIHB1c2hXYXJuaW5nQ29udGV4dCQxKGluaXRpYWxWTm9kZSk7DQogICAgICBzdGFydE1lYXN1cmUoaW5zdGFuY2UsIGBtb3VudGApOw0KICAgIH0NCiAgICBpZiAoaXNLZWVwQWxpdmUoaW5pdGlhbFZOb2RlKSkgew0KICAgICAgaW5zdGFuY2UuY3R4LnJlbmRlcmVyID0gaW50ZXJuYWxzOw0KICAgIH0NCiAgICB7DQogICAgICB7DQogICAgICAgIHN0YXJ0TWVhc3VyZShpbnN0YW5jZSwgYGluaXRgKTsNCiAgICAgIH0NCiAgICAgIHNldHVwQ29tcG9uZW50JDEoaW5zdGFuY2UsIGZhbHNlLCBvcHRpbWl6ZWQpOw0KICAgICAgew0KICAgICAgICBlbmRNZWFzdXJlKGluc3RhbmNlLCBgaW5pdGApOw0KICAgICAgfQ0KICAgIH0NCiAgICBpZiAoaXNIbXJVcGRhdGluZykgaW5pdGlhbFZOb2RlLmVsID0gbnVsbDsNCiAgICBpZiAoaW5zdGFuY2UuYXN5bmNEZXApIHsNCiAgICAgIHBhcmVudFN1c3BlbnNlICYmIHBhcmVudFN1c3BlbnNlLnJlZ2lzdGVyRGVwKGluc3RhbmNlLCBzZXR1cFJlbmRlckVmZmVjdCwgb3B0aW1pemVkKTsNCiAgICAgIGlmICghaW5pdGlhbFZOb2RlLmVsKSB7DQogICAgICAgIGNvbnN0IHBsYWNlaG9sZGVyID0gaW5zdGFuY2Uuc3ViVHJlZSA9IGNyZWF0ZVZOb2RlKENvbW1lbnQpOw0KICAgICAgICBwcm9jZXNzQ29tbWVudE5vZGUobnVsbCwgcGxhY2Vob2xkZXIsIGNvbnRhaW5lciwgYW5jaG9yKTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgc2V0dXBSZW5kZXJFZmZlY3QoDQogICAgICAgIGluc3RhbmNlLA0KICAgICAgICBpbml0aWFsVk5vZGUsDQogICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgYW5jaG9yLA0KICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICk7DQogICAgfQ0KICAgIHsNCiAgICAgIHBvcFdhcm5pbmdDb250ZXh0JDEoKTsNCiAgICAgIGVuZE1lYXN1cmUoaW5zdGFuY2UsIGBtb3VudGApOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgdXBkYXRlQ29tcG9uZW50ID0gKG4xLCBuMiwgb3B0aW1pemVkKSA9PiB7DQogICAgY29uc3QgaW5zdGFuY2UgPSBuMi5jb21wb25lbnQgPSBuMS5jb21wb25lbnQ7DQogICAgaWYgKHNob3VsZFVwZGF0ZUNvbXBvbmVudChuMSwgbjIsIG9wdGltaXplZCkpIHsNCiAgICAgIGlmIChpbnN0YW5jZS5hc3luY0RlcCAmJiAhaW5zdGFuY2UuYXN5bmNSZXNvbHZlZCkgew0KICAgICAgICB7DQogICAgICAgICAgcHVzaFdhcm5pbmdDb250ZXh0JDEobjIpOw0KICAgICAgICB9DQogICAgICAgIHVwZGF0ZUNvbXBvbmVudFByZVJlbmRlcihpbnN0YW5jZSwgbjIsIG9wdGltaXplZCk7DQogICAgICAgIHsNCiAgICAgICAgICBwb3BXYXJuaW5nQ29udGV4dCQxKCk7DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgaW5zdGFuY2UubmV4dCA9IG4yOw0KICAgICAgICBpbnN0YW5jZS51cGRhdGUoKTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgbjIuZWwgPSBuMS5lbDsNCiAgICAgIGluc3RhbmNlLnZub2RlID0gbjI7DQogICAgfQ0KICB9Ow0KICBjb25zdCBzZXR1cFJlbmRlckVmZmVjdCA9IChpbnN0YW5jZSwgaW5pdGlhbFZOb2RlLCBjb250YWluZXIsIGFuY2hvciwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgb3B0aW1pemVkKSA9PiB7DQogICAgY29uc3QgY29tcG9uZW50VXBkYXRlRm4gPSAoKSA9PiB7DQogICAgICBpZiAoIWluc3RhbmNlLmlzTW91bnRlZCkgew0KICAgICAgICBsZXQgdm5vZGVIb29rOw0KICAgICAgICBjb25zdCB7IGVsLCBwcm9wcyB9ID0gaW5pdGlhbFZOb2RlOw0KICAgICAgICBjb25zdCB7IGJtLCBtLCBwYXJlbnQsIHJvb3QsIHR5cGUgfSA9IGluc3RhbmNlOw0KICAgICAgICBjb25zdCBpc0FzeW5jV3JhcHBlclZOb2RlID0gaXNBc3luY1dyYXBwZXIoaW5pdGlhbFZOb2RlKTsNCiAgICAgICAgdG9nZ2xlUmVjdXJzZShpbnN0YW5jZSwgZmFsc2UpOw0KICAgICAgICBpZiAoYm0pIHsNCiAgICAgICAgICBpbnZva2VBcnJheUZucyhibSk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKCFpc0FzeW5jV3JhcHBlclZOb2RlICYmICh2bm9kZUhvb2sgPSBwcm9wcyAmJiBwcm9wcy5vblZub2RlQmVmb3JlTW91bnQpKSB7DQogICAgICAgICAgaW52b2tlVk5vZGVIb29rKHZub2RlSG9vaywgcGFyZW50LCBpbml0aWFsVk5vZGUpOw0KICAgICAgICB9DQogICAgICAgIHRvZ2dsZVJlY3Vyc2UoaW5zdGFuY2UsIHRydWUpOw0KICAgICAgICB7DQogICAgICAgICAgaWYgKHJvb3QuY2UgJiYgLy8gQHRzLWV4cGVjdC1lcnJvciBfZGVmIGlzIHByaXZhdGUNCiAgICAgICAgICByb290LmNlLl9kZWYuc2hhZG93Um9vdCAhPT0gZmFsc2UpIHsNCiAgICAgICAgICAgIHJvb3QuY2UuX2luamVjdENoaWxkU3R5bGUodHlwZSk7DQogICAgICAgICAgfQ0KICAgICAgICAgIHsNCiAgICAgICAgICAgIHN0YXJ0TWVhc3VyZShpbnN0YW5jZSwgYHJlbmRlcmApOw0KICAgICAgICAgIH0NCiAgICAgICAgICBjb25zdCBzdWJUcmVlID0gaW5zdGFuY2Uuc3ViVHJlZSA9IHJlbmRlckNvbXBvbmVudFJvb3QkMShpbnN0YW5jZSk7DQogICAgICAgICAgew0KICAgICAgICAgICAgZW5kTWVhc3VyZShpbnN0YW5jZSwgYHJlbmRlcmApOw0KICAgICAgICAgIH0NCiAgICAgICAgICB7DQogICAgICAgICAgICBzdGFydE1lYXN1cmUoaW5zdGFuY2UsIGBwYXRjaGApOw0KICAgICAgICAgIH0NCiAgICAgICAgICBwYXRjaCgNCiAgICAgICAgICAgIG51bGwsDQogICAgICAgICAgICBzdWJUcmVlLA0KICAgICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgICAgaW5zdGFuY2UsDQogICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgIG5hbWVzcGFjZQ0KICAgICAgICAgICk7DQogICAgICAgICAgew0KICAgICAgICAgICAgZW5kTWVhc3VyZShpbnN0YW5jZSwgYHBhdGNoYCk7DQogICAgICAgICAgfQ0KICAgICAgICAgIGluaXRpYWxWTm9kZS5lbCA9IHN1YlRyZWUuZWw7DQogICAgICAgIH0NCiAgICAgICAgaWYgKG0pIHsNCiAgICAgICAgICBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QobSwgcGFyZW50U3VzcGVuc2UpOw0KICAgICAgICB9DQogICAgICAgIGlmICghaXNBc3luY1dyYXBwZXJWTm9kZSAmJiAodm5vZGVIb29rID0gcHJvcHMgJiYgcHJvcHMub25Wbm9kZU1vdW50ZWQpKSB7DQogICAgICAgICAgY29uc3Qgc2NvcGVkSW5pdGlhbFZOb2RlID0gaW5pdGlhbFZOb2RlOw0KICAgICAgICAgIHF1ZXVlUG9zdFJlbmRlckVmZmVjdCgNCiAgICAgICAgICAgICgpID0+IGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIHBhcmVudCwgc2NvcGVkSW5pdGlhbFZOb2RlKSwNCiAgICAgICAgICAgIHBhcmVudFN1c3BlbnNlDQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgICBpZiAoaW5pdGlhbFZOb2RlLnNoYXBlRmxhZyAmIDI1NiB8fCBwYXJlbnQgJiYgaXNBc3luY1dyYXBwZXIocGFyZW50LnZub2RlKSAmJiBwYXJlbnQudm5vZGUuc2hhcGVGbGFnICYgMjU2KSB7DQogICAgICAgICAgaW5zdGFuY2UuYSAmJiBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QoaW5zdGFuY2UuYSwgcGFyZW50U3VzcGVuc2UpOw0KICAgICAgICB9DQogICAgICAgIGluc3RhbmNlLmlzTW91bnRlZCA9IHRydWU7DQogICAgICAgIHsNCiAgICAgICAgICBkZXZ0b29sc0NvbXBvbmVudEFkZGVkKGluc3RhbmNlKTsNCiAgICAgICAgfQ0KICAgICAgICBpbml0aWFsVk5vZGUgPSBjb250YWluZXIgPSBhbmNob3IgPSBudWxsOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgbGV0IHsgbmV4dCwgYnUsIHUsIHBhcmVudCwgdm5vZGUgfSA9IGluc3RhbmNlOw0KICAgICAgICB7DQogICAgICAgICAgY29uc3Qgbm9uSHlkcmF0ZWRBc3luY1Jvb3QgPSBsb2NhdGVOb25IeWRyYXRlZEFzeW5jUm9vdChpbnN0YW5jZSk7DQogICAgICAgICAgaWYgKG5vbkh5ZHJhdGVkQXN5bmNSb290KSB7DQogICAgICAgICAgICBpZiAobmV4dCkgew0KICAgICAgICAgICAgICBuZXh0LmVsID0gdm5vZGUuZWw7DQogICAgICAgICAgICAgIHVwZGF0ZUNvbXBvbmVudFByZVJlbmRlcihpbnN0YW5jZSwgbmV4dCwgb3B0aW1pemVkKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIG5vbkh5ZHJhdGVkQXN5bmNSb290LmFzeW5jRGVwLnRoZW4oKCkgPT4gew0KICAgICAgICAgICAgICBpZiAoIWluc3RhbmNlLmlzVW5tb3VudGVkKSB7DQogICAgICAgICAgICAgICAgY29tcG9uZW50VXBkYXRlRm4oKTsNCiAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSk7DQogICAgICAgICAgICByZXR1cm47DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGxldCBvcmlnaW5OZXh0ID0gbmV4dDsNCiAgICAgICAgbGV0IHZub2RlSG9vazsNCiAgICAgICAgew0KICAgICAgICAgIHB1c2hXYXJuaW5nQ29udGV4dCQxKG5leHQgfHwgaW5zdGFuY2Uudm5vZGUpOw0KICAgICAgICB9DQogICAgICAgIHRvZ2dsZVJlY3Vyc2UoaW5zdGFuY2UsIGZhbHNlKTsNCiAgICAgICAgaWYgKG5leHQpIHsNCiAgICAgICAgICBuZXh0LmVsID0gdm5vZGUuZWw7DQogICAgICAgICAgdXBkYXRlQ29tcG9uZW50UHJlUmVuZGVyKGluc3RhbmNlLCBuZXh0LCBvcHRpbWl6ZWQpOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIG5leHQgPSB2bm9kZTsNCiAgICAgICAgfQ0KICAgICAgICBpZiAoYnUpIHsNCiAgICAgICAgICBpbnZva2VBcnJheUZucyhidSk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKHZub2RlSG9vayA9IG5leHQucHJvcHMgJiYgbmV4dC5wcm9wcy5vblZub2RlQmVmb3JlVXBkYXRlKSB7DQogICAgICAgICAgaW52b2tlVk5vZGVIb29rKHZub2RlSG9vaywgcGFyZW50LCBuZXh0LCB2bm9kZSk7DQogICAgICAgIH0NCiAgICAgICAgdG9nZ2xlUmVjdXJzZShpbnN0YW5jZSwgdHJ1ZSk7DQogICAgICAgIHsNCiAgICAgICAgICBzdGFydE1lYXN1cmUoaW5zdGFuY2UsIGByZW5kZXJgKTsNCiAgICAgICAgfQ0KICAgICAgICBjb25zdCBuZXh0VHJlZSA9IHJlbmRlckNvbXBvbmVudFJvb3QkMShpbnN0YW5jZSk7DQogICAgICAgIHsNCiAgICAgICAgICBlbmRNZWFzdXJlKGluc3RhbmNlLCBgcmVuZGVyYCk7DQogICAgICAgIH0NCiAgICAgICAgY29uc3QgcHJldlRyZWUgPSBpbnN0YW5jZS5zdWJUcmVlOw0KICAgICAgICBpbnN0YW5jZS5zdWJUcmVlID0gbmV4dFRyZWU7DQogICAgICAgIHsNCiAgICAgICAgICBzdGFydE1lYXN1cmUoaW5zdGFuY2UsIGBwYXRjaGApOw0KICAgICAgICB9DQogICAgICAgIHBhdGNoKA0KICAgICAgICAgIHByZXZUcmVlLA0KICAgICAgICAgIG5leHRUcmVlLA0KICAgICAgICAgIC8vIHBhcmVudCBtYXkgaGF2ZSBjaGFuZ2VkIGlmIGl0J3MgaW4gYSB0ZWxlcG9ydA0KICAgICAgICAgIGhvc3RQYXJlbnROb2RlKHByZXZUcmVlLmVsKSwNCiAgICAgICAgICAvLyBhbmNob3IgbWF5IGhhdmUgY2hhbmdlZCBpZiBpdCdzIGluIGEgZnJhZ21lbnQNCiAgICAgICAgICBnZXROZXh0SG9zdE5vZGUocHJldlRyZWUpLA0KICAgICAgICAgIGluc3RhbmNlLA0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgIG5hbWVzcGFjZQ0KICAgICAgICApOw0KICAgICAgICB7DQogICAgICAgICAgZW5kTWVhc3VyZShpbnN0YW5jZSwgYHBhdGNoYCk7DQogICAgICAgIH0NCiAgICAgICAgbmV4dC5lbCA9IG5leHRUcmVlLmVsOw0KICAgICAgICBpZiAob3JpZ2luTmV4dCA9PT0gbnVsbCkgew0KICAgICAgICAgIHVwZGF0ZUhPQ0hvc3RFbChpbnN0YW5jZSwgbmV4dFRyZWUuZWwpOw0KICAgICAgICB9DQogICAgICAgIGlmICh1KSB7DQogICAgICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KHUsIHBhcmVudFN1c3BlbnNlKTsNCiAgICAgICAgfQ0KICAgICAgICBpZiAodm5vZGVIb29rID0gbmV4dC5wcm9wcyAmJiBuZXh0LnByb3BzLm9uVm5vZGVVcGRhdGVkKSB7DQogICAgICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KA0KICAgICAgICAgICAgKCkgPT4gaW52b2tlVk5vZGVIb29rKHZub2RlSG9vaywgcGFyZW50LCBuZXh0LCB2bm9kZSksDQogICAgICAgICAgICBwYXJlbnRTdXNwZW5zZQ0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgICAgew0KICAgICAgICAgIGRldnRvb2xzQ29tcG9uZW50VXBkYXRlZChpbnN0YW5jZSk7DQogICAgICAgIH0NCiAgICAgICAgew0KICAgICAgICAgIHBvcFdhcm5pbmdDb250ZXh0JDEoKTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH07DQogICAgaW5zdGFuY2Uuc2NvcGUub24oKTsNCiAgICBjb25zdCBlZmZlY3QgPSBpbnN0YW5jZS5lZmZlY3QgPSBuZXcgUmVhY3RpdmVFZmZlY3QoY29tcG9uZW50VXBkYXRlRm4pOw0KICAgIGluc3RhbmNlLnNjb3BlLm9mZigpOw0KICAgIGNvbnN0IHVwZGF0ZSA9IGluc3RhbmNlLnVwZGF0ZSA9IGVmZmVjdC5ydW4uYmluZChlZmZlY3QpOw0KICAgIGNvbnN0IGpvYiA9IGluc3RhbmNlLmpvYiA9IGVmZmVjdC5ydW5JZkRpcnR5LmJpbmQoZWZmZWN0KTsNCiAgICBqb2IuaSA9IGluc3RhbmNlOw0KICAgIGpvYi5pZCA9IGluc3RhbmNlLnVpZDsNCiAgICBlZmZlY3Quc2NoZWR1bGVyID0gKCkgPT4gcXVldWVKb2Ioam9iKTsNCiAgICB0b2dnbGVSZWN1cnNlKGluc3RhbmNlLCB0cnVlKTsNCiAgICB7DQogICAgICBlZmZlY3Qub25UcmFjayA9IGluc3RhbmNlLnJ0YyA/IChlKSA9PiBpbnZva2VBcnJheUZucyhpbnN0YW5jZS5ydGMsIGUpIDogdm9pZCAwOw0KICAgICAgZWZmZWN0Lm9uVHJpZ2dlciA9IGluc3RhbmNlLnJ0ZyA/IChlKSA9PiBpbnZva2VBcnJheUZucyhpbnN0YW5jZS5ydGcsIGUpIDogdm9pZCAwOw0KICAgIH0NCiAgICB1cGRhdGUoKTsNCiAgfTsNCiAgY29uc3QgdXBkYXRlQ29tcG9uZW50UHJlUmVuZGVyID0gKGluc3RhbmNlLCBuZXh0Vk5vZGUsIG9wdGltaXplZCkgPT4gew0KICAgIG5leHRWTm9kZS5jb21wb25lbnQgPSBpbnN0YW5jZTsNCiAgICBjb25zdCBwcmV2UHJvcHMgPSBpbnN0YW5jZS52bm9kZS5wcm9wczsNCiAgICBpbnN0YW5jZS52bm9kZSA9IG5leHRWTm9kZTsNCiAgICBpbnN0YW5jZS5uZXh0ID0gbnVsbDsNCiAgICB1cGRhdGVQcm9wcyhpbnN0YW5jZSwgbmV4dFZOb2RlLnByb3BzLCBwcmV2UHJvcHMsIG9wdGltaXplZCk7DQogICAgdXBkYXRlU2xvdHMoaW5zdGFuY2UsIG5leHRWTm9kZS5jaGlsZHJlbiwgb3B0aW1pemVkKTsNCiAgICBwYXVzZVRyYWNraW5nKCk7DQogICAgZmx1c2hQcmVGbHVzaENicyhpbnN0YW5jZSk7DQogICAgcmVzZXRUcmFja2luZygpOw0KICB9Ow0KICBjb25zdCBwYXRjaENoaWxkcmVuID0gKG4xLCBuMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQgPSBmYWxzZSkgPT4gew0KICAgIGNvbnN0IGMxID0gbjEgJiYgbjEuY2hpbGRyZW47DQogICAgY29uc3QgcHJldlNoYXBlRmxhZyA9IG4xID8gbjEuc2hhcGVGbGFnIDogMDsNCiAgICBjb25zdCBjMiA9IG4yLmNoaWxkcmVuOw0KICAgIGNvbnN0IHsgcGF0Y2hGbGFnLCBzaGFwZUZsYWcgfSA9IG4yOw0KICAgIGlmIChwYXRjaEZsYWcgPiAwKSB7DQogICAgICBpZiAocGF0Y2hGbGFnICYgMTI4KSB7DQogICAgICAgIHBhdGNoS2V5ZWRDaGlsZHJlbigNCiAgICAgICAgICBjMSwNCiAgICAgICAgICBjMiwNCiAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICApOw0KICAgICAgICByZXR1cm47DQogICAgICB9IGVsc2UgaWYgKHBhdGNoRmxhZyAmIDI1Nikgew0KICAgICAgICBwYXRjaFVua2V5ZWRDaGlsZHJlbigNCiAgICAgICAgICBjMSwNCiAgICAgICAgICBjMiwNCiAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICApOw0KICAgICAgICByZXR1cm47DQogICAgICB9DQogICAgfQ0KICAgIGlmIChzaGFwZUZsYWcgJiA4KSB7DQogICAgICBpZiAocHJldlNoYXBlRmxhZyAmIDE2KSB7DQogICAgICAgIHVubW91bnRDaGlsZHJlbihjMSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSk7DQogICAgICB9DQogICAgICBpZiAoYzIgIT09IGMxKSB7DQogICAgICAgIGhvc3RTZXRFbGVtZW50VGV4dChjb250YWluZXIsIGMyKTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgaWYgKHByZXZTaGFwZUZsYWcgJiAxNikgew0KICAgICAgICBpZiAoc2hhcGVGbGFnICYgMTYpIHsNCiAgICAgICAgICBwYXRjaEtleWVkQ2hpbGRyZW4oDQogICAgICAgICAgICBjMSwNCiAgICAgICAgICAgIGMyLA0KICAgICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgICApOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIHVubW91bnRDaGlsZHJlbihjMSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgdHJ1ZSk7DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGlmIChwcmV2U2hhcGVGbGFnICYgOCkgew0KICAgICAgICAgIGhvc3RTZXRFbGVtZW50VGV4dChjb250YWluZXIsICIiKTsNCiAgICAgICAgfQ0KICAgICAgICBpZiAoc2hhcGVGbGFnICYgMTYpIHsNCiAgICAgICAgICBtb3VudENoaWxkcmVuKA0KICAgICAgICAgICAgYzIsDQogICAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgICBhbmNob3IsDQogICAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgICAgIG9wdGltaXplZA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH07DQogIGNvbnN0IHBhdGNoVW5rZXllZENoaWxkcmVuID0gKGMxLCBjMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG5hbWVzcGFjZSwgc2xvdFNjb3BlSWRzLCBvcHRpbWl6ZWQpID0+IHsNCiAgICBjMSA9IGMxIHx8IEVNUFRZX0FSUjsNCiAgICBjMiA9IGMyIHx8IEVNUFRZX0FSUjsNCiAgICBjb25zdCBvbGRMZW5ndGggPSBjMS5sZW5ndGg7DQogICAgY29uc3QgbmV3TGVuZ3RoID0gYzIubGVuZ3RoOw0KICAgIGNvbnN0IGNvbW1vbkxlbmd0aCA9IE1hdGgubWluKG9sZExlbmd0aCwgbmV3TGVuZ3RoKTsNCiAgICBsZXQgaTsNCiAgICBmb3IgKGkgPSAwOyBpIDwgY29tbW9uTGVuZ3RoOyBpKyspIHsNCiAgICAgIGNvbnN0IG5leHRDaGlsZCA9IGMyW2ldID0gb3B0aW1pemVkID8gY2xvbmVJZk1vdW50ZWQoYzJbaV0pIDogbm9ybWFsaXplVk5vZGUkMShjMltpXSk7DQogICAgICBwYXRjaCgNCiAgICAgICAgYzFbaV0sDQogICAgICAgIG5leHRDaGlsZCwNCiAgICAgICAgY29udGFpbmVyLA0KICAgICAgICBudWxsLA0KICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgIHNsb3RTY29wZUlkcywNCiAgICAgICAgb3B0aW1pemVkDQogICAgICApOw0KICAgIH0NCiAgICBpZiAob2xkTGVuZ3RoID4gbmV3TGVuZ3RoKSB7DQogICAgICB1bm1vdW50Q2hpbGRyZW4oDQogICAgICAgIGMxLA0KICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICB0cnVlLA0KICAgICAgICBmYWxzZSwNCiAgICAgICAgY29tbW9uTGVuZ3RoDQogICAgICApOw0KICAgIH0gZWxzZSB7DQogICAgICBtb3VudENoaWxkcmVuKA0KICAgICAgICBjMiwNCiAgICAgICAgY29udGFpbmVyLA0KICAgICAgICBhbmNob3IsDQogICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICBvcHRpbWl6ZWQsDQogICAgICAgIGNvbW1vbkxlbmd0aA0KICAgICAgKTsNCiAgICB9DQogIH07DQogIGNvbnN0IHBhdGNoS2V5ZWRDaGlsZHJlbiA9IChjMSwgYzIsIGNvbnRhaW5lciwgcGFyZW50QW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBuYW1lc3BhY2UsIHNsb3RTY29wZUlkcywgb3B0aW1pemVkKSA9PiB7DQogICAgbGV0IGkgPSAwOw0KICAgIGNvbnN0IGwyID0gYzIubGVuZ3RoOw0KICAgIGxldCBlMSA9IGMxLmxlbmd0aCAtIDE7DQogICAgbGV0IGUyID0gbDIgLSAxOw0KICAgIHdoaWxlIChpIDw9IGUxICYmIGkgPD0gZTIpIHsNCiAgICAgIGNvbnN0IG4xID0gYzFbaV07DQogICAgICBjb25zdCBuMiA9IGMyW2ldID0gb3B0aW1pemVkID8gY2xvbmVJZk1vdW50ZWQoYzJbaV0pIDogbm9ybWFsaXplVk5vZGUkMShjMltpXSk7DQogICAgICBpZiAoaXNTYW1lVk5vZGVUeXBlKG4xLCBuMikpIHsNCiAgICAgICAgcGF0Y2goDQogICAgICAgICAgbjEsDQogICAgICAgICAgbjIsDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIG51bGwsDQogICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBicmVhazsNCiAgICAgIH0NCiAgICAgIGkrKzsNCiAgICB9DQogICAgd2hpbGUgKGkgPD0gZTEgJiYgaSA8PSBlMikgew0KICAgICAgY29uc3QgbjEgPSBjMVtlMV07DQogICAgICBjb25zdCBuMiA9IGMyW2UyXSA9IG9wdGltaXplZCA/IGNsb25lSWZNb3VudGVkKGMyW2UyXSkgOiBub3JtYWxpemVWTm9kZSQxKGMyW2UyXSk7DQogICAgICBpZiAoaXNTYW1lVk5vZGVUeXBlKG4xLCBuMikpIHsNCiAgICAgICAgcGF0Y2goDQogICAgICAgICAgbjEsDQogICAgICAgICAgbjIsDQogICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgIG51bGwsDQogICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgIG5hbWVzcGFjZSwNCiAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBicmVhazsNCiAgICAgIH0NCiAgICAgIGUxLS07DQogICAgICBlMi0tOw0KICAgIH0NCiAgICBpZiAoaSA+IGUxKSB7DQogICAgICBpZiAoaSA8PSBlMikgew0KICAgICAgICBjb25zdCBuZXh0UG9zID0gZTIgKyAxOw0KICAgICAgICBjb25zdCBhbmNob3IgPSBuZXh0UG9zIDwgbDIgPyBjMltuZXh0UG9zXS5lbCA6IHBhcmVudEFuY2hvcjsNCiAgICAgICAgd2hpbGUgKGkgPD0gZTIpIHsNCiAgICAgICAgICBwYXRjaCgNCiAgICAgICAgICAgIG51bGwsDQogICAgICAgICAgICBjMltpXSA9IG9wdGltaXplZCA/IGNsb25lSWZNb3VudGVkKGMyW2ldKSA6IG5vcm1hbGl6ZVZOb2RlJDEoYzJbaV0pLA0KICAgICAgICAgICAgY29udGFpbmVyLA0KICAgICAgICAgICAgYW5jaG9yLA0KICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgICApOw0KICAgICAgICAgIGkrKzsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0gZWxzZSBpZiAoaSA+IGUyKSB7DQogICAgICB3aGlsZSAoaSA8PSBlMSkgew0KICAgICAgICB1bm1vdW50KGMxW2ldLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCB0cnVlKTsNCiAgICAgICAgaSsrOw0KICAgICAgfQ0KICAgIH0gZWxzZSB7DQogICAgICBjb25zdCBzMSA9IGk7DQogICAgICBjb25zdCBzMiA9IGk7DQogICAgICBjb25zdCBrZXlUb05ld0luZGV4TWFwID0gLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTsNCiAgICAgIGZvciAoaSA9IHMyOyBpIDw9IGUyOyBpKyspIHsNCiAgICAgICAgY29uc3QgbmV4dENoaWxkID0gYzJbaV0gPSBvcHRpbWl6ZWQgPyBjbG9uZUlmTW91bnRlZChjMltpXSkgOiBub3JtYWxpemVWTm9kZSQxKGMyW2ldKTsNCiAgICAgICAgaWYgKG5leHRDaGlsZC5rZXkgIT0gbnVsbCkgew0KICAgICAgICAgIGlmIChrZXlUb05ld0luZGV4TWFwLmhhcyhuZXh0Q2hpbGQua2V5KSkgew0KICAgICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgICBgRHVwbGljYXRlIGtleXMgZm91bmQgZHVyaW5nIHVwZGF0ZTpgLA0KICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShuZXh0Q2hpbGQua2V5KSwNCiAgICAgICAgICAgICAgYE1ha2Ugc3VyZSBrZXlzIGFyZSB1bmlxdWUuYA0KICAgICAgICAgICAgKTsNCiAgICAgICAgICB9DQogICAgICAgICAga2V5VG9OZXdJbmRleE1hcC5zZXQobmV4dENoaWxkLmtleSwgaSk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGxldCBqOw0KICAgICAgbGV0IHBhdGNoZWQgPSAwOw0KICAgICAgY29uc3QgdG9CZVBhdGNoZWQgPSBlMiAtIHMyICsgMTsNCiAgICAgIGxldCBtb3ZlZCA9IGZhbHNlOw0KICAgICAgbGV0IG1heE5ld0luZGV4U29GYXIgPSAwOw0KICAgICAgY29uc3QgbmV3SW5kZXhUb09sZEluZGV4TWFwID0gbmV3IEFycmF5KHRvQmVQYXRjaGVkKTsNCiAgICAgIGZvciAoaSA9IDA7IGkgPCB0b0JlUGF0Y2hlZDsgaSsrKSBuZXdJbmRleFRvT2xkSW5kZXhNYXBbaV0gPSAwOw0KICAgICAgZm9yIChpID0gczE7IGkgPD0gZTE7IGkrKykgew0KICAgICAgICBjb25zdCBwcmV2Q2hpbGQgPSBjMVtpXTsNCiAgICAgICAgaWYgKHBhdGNoZWQgPj0gdG9CZVBhdGNoZWQpIHsNCiAgICAgICAgICB1bm1vdW50KHByZXZDaGlsZCwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgdHJ1ZSk7DQogICAgICAgICAgY29udGludWU7DQogICAgICAgIH0NCiAgICAgICAgbGV0IG5ld0luZGV4Ow0KICAgICAgICBpZiAocHJldkNoaWxkLmtleSAhPSBudWxsKSB7DQogICAgICAgICAgbmV3SW5kZXggPSBrZXlUb05ld0luZGV4TWFwLmdldChwcmV2Q2hpbGQua2V5KTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBmb3IgKGogPSBzMjsgaiA8PSBlMjsgaisrKSB7DQogICAgICAgICAgICBpZiAobmV3SW5kZXhUb09sZEluZGV4TWFwW2ogLSBzMl0gPT09IDAgJiYgaXNTYW1lVk5vZGVUeXBlKHByZXZDaGlsZCwgYzJbal0pKSB7DQogICAgICAgICAgICAgIG5ld0luZGV4ID0gajsNCiAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICB9DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGlmIChuZXdJbmRleCA9PT0gdm9pZCAwKSB7DQogICAgICAgICAgdW5tb3VudChwcmV2Q2hpbGQsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIHRydWUpOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIG5ld0luZGV4VG9PbGRJbmRleE1hcFtuZXdJbmRleCAtIHMyXSA9IGkgKyAxOw0KICAgICAgICAgIGlmIChuZXdJbmRleCA+PSBtYXhOZXdJbmRleFNvRmFyKSB7DQogICAgICAgICAgICBtYXhOZXdJbmRleFNvRmFyID0gbmV3SW5kZXg7DQogICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIG1vdmVkID0gdHJ1ZTsNCiAgICAgICAgICB9DQogICAgICAgICAgcGF0Y2goDQogICAgICAgICAgICBwcmV2Q2hpbGQsDQogICAgICAgICAgICBjMltuZXdJbmRleF0sDQogICAgICAgICAgICBjb250YWluZXIsDQogICAgICAgICAgICBudWxsLA0KICAgICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgICAgcGFyZW50U3VzcGVuc2UsDQogICAgICAgICAgICBuYW1lc3BhY2UsDQogICAgICAgICAgICBzbG90U2NvcGVJZHMsDQogICAgICAgICAgICBvcHRpbWl6ZWQNCiAgICAgICAgICApOw0KICAgICAgICAgIHBhdGNoZWQrKzsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgY29uc3QgaW5jcmVhc2luZ05ld0luZGV4U2VxdWVuY2UgPSBtb3ZlZCA/IGdldFNlcXVlbmNlKG5ld0luZGV4VG9PbGRJbmRleE1hcCkgOiBFTVBUWV9BUlI7DQogICAgICBqID0gaW5jcmVhc2luZ05ld0luZGV4U2VxdWVuY2UubGVuZ3RoIC0gMTsNCiAgICAgIGZvciAoaSA9IHRvQmVQYXRjaGVkIC0gMTsgaSA+PSAwOyBpLS0pIHsNCiAgICAgICAgY29uc3QgbmV4dEluZGV4ID0gczIgKyBpOw0KICAgICAgICBjb25zdCBuZXh0Q2hpbGQgPSBjMltuZXh0SW5kZXhdOw0KICAgICAgICBjb25zdCBhbmNob3IgPSBuZXh0SW5kZXggKyAxIDwgbDIgPyBjMltuZXh0SW5kZXggKyAxXS5lbCA6IHBhcmVudEFuY2hvcjsNCiAgICAgICAgaWYgKG5ld0luZGV4VG9PbGRJbmRleE1hcFtpXSA9PT0gMCkgew0KICAgICAgICAgIHBhdGNoKA0KICAgICAgICAgICAgbnVsbCwNCiAgICAgICAgICAgIG5leHRDaGlsZCwNCiAgICAgICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgICAgIGFuY2hvciwNCiAgICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgICAgbmFtZXNwYWNlLA0KICAgICAgICAgICAgc2xvdFNjb3BlSWRzLA0KICAgICAgICAgICAgb3B0aW1pemVkDQogICAgICAgICAgKTsNCiAgICAgICAgfSBlbHNlIGlmIChtb3ZlZCkgew0KICAgICAgICAgIGlmIChqIDwgMCB8fCBpICE9PSBpbmNyZWFzaW5nTmV3SW5kZXhTZXF1ZW5jZVtqXSkgew0KICAgICAgICAgICAgbW92ZShuZXh0Q2hpbGQsIGNvbnRhaW5lciwgYW5jaG9yLCAyKTsNCiAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgai0tOw0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgfTsNCiAgY29uc3QgbW92ZSA9ICh2bm9kZSwgY29udGFpbmVyLCBhbmNob3IsIG1vdmVUeXBlLCBwYXJlbnRTdXNwZW5zZSA9IG51bGwpID0+IHsNCiAgICBjb25zdCB7IGVsLCB0eXBlLCB0cmFuc2l0aW9uLCBjaGlsZHJlbiwgc2hhcGVGbGFnIH0gPSB2bm9kZTsNCiAgICBpZiAoc2hhcGVGbGFnICYgNikgew0KICAgICAgbW92ZSh2bm9kZS5jb21wb25lbnQuc3ViVHJlZSwgY29udGFpbmVyLCBhbmNob3IsIG1vdmVUeXBlKTsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgaWYgKHNoYXBlRmxhZyAmIDEyOCkgew0KICAgICAgdm5vZGUuc3VzcGVuc2UubW92ZShjb250YWluZXIsIGFuY2hvciwgbW92ZVR5cGUpOw0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBpZiAoc2hhcGVGbGFnICYgNjQpIHsNCiAgICAgIHR5cGUubW92ZSh2bm9kZSwgY29udGFpbmVyLCBhbmNob3IsIGludGVybmFscyk7DQogICAgICByZXR1cm47DQogICAgfQ0KICAgIGlmICh0eXBlID09PSBGcmFnbWVudCkgew0KICAgICAgaG9zdEluc2VydChlbCwgY29udGFpbmVyLCBhbmNob3IpOw0KICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykgew0KICAgICAgICBtb3ZlKGNoaWxkcmVuW2ldLCBjb250YWluZXIsIGFuY2hvciwgbW92ZVR5cGUpOw0KICAgICAgfQ0KICAgICAgaG9zdEluc2VydCh2bm9kZS5hbmNob3IsIGNvbnRhaW5lciwgYW5jaG9yKTsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgaWYgKHR5cGUgPT09IFN0YXRpYykgew0KICAgICAgbW92ZVN0YXRpY05vZGUodm5vZGUsIGNvbnRhaW5lciwgYW5jaG9yKTsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgY29uc3QgbmVlZFRyYW5zaXRpb24yID0gbW92ZVR5cGUgIT09IDIgJiYgc2hhcGVGbGFnICYgMSAmJiB0cmFuc2l0aW9uOw0KICAgIGlmIChuZWVkVHJhbnNpdGlvbjIpIHsNCiAgICAgIGlmIChtb3ZlVHlwZSA9PT0gMCkgew0KICAgICAgICB0cmFuc2l0aW9uLmJlZm9yZUVudGVyKGVsKTsNCiAgICAgICAgaG9zdEluc2VydChlbCwgY29udGFpbmVyLCBhbmNob3IpOw0KICAgICAgICBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QoKCkgPT4gdHJhbnNpdGlvbi5lbnRlcihlbCksIHBhcmVudFN1c3BlbnNlKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGNvbnN0IHsgbGVhdmUsIGRlbGF5TGVhdmUsIGFmdGVyTGVhdmUgfSA9IHRyYW5zaXRpb247DQogICAgICAgIGNvbnN0IHJlbW92ZTIgPSAoKSA9PiB7DQogICAgICAgICAgaWYgKHZub2RlLmN0eC5pc1VubW91bnRlZCkgew0KICAgICAgICAgICAgaG9zdFJlbW92ZShlbCk7DQogICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIGhvc3RJbnNlcnQoZWwsIGNvbnRhaW5lciwgYW5jaG9yKTsNCiAgICAgICAgICB9DQogICAgICAgIH07DQogICAgICAgIGNvbnN0IHBlcmZvcm1MZWF2ZSA9ICgpID0+IHsNCiAgICAgICAgICBsZWF2ZShlbCwgKCkgPT4gew0KICAgICAgICAgICAgcmVtb3ZlMigpOw0KICAgICAgICAgICAgYWZ0ZXJMZWF2ZSAmJiBhZnRlckxlYXZlKCk7DQogICAgICAgICAgfSk7DQogICAgICAgIH07DQogICAgICAgIGlmIChkZWxheUxlYXZlKSB7DQogICAgICAgICAgZGVsYXlMZWF2ZShlbCwgcmVtb3ZlMiwgcGVyZm9ybUxlYXZlKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICBwZXJmb3JtTGVhdmUoKTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0gZWxzZSB7DQogICAgICBob3N0SW5zZXJ0KGVsLCBjb250YWluZXIsIGFuY2hvcik7DQogICAgfQ0KICB9Ow0KICBjb25zdCB1bm1vdW50ID0gKHZub2RlLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBkb1JlbW92ZSA9IGZhbHNlLCBvcHRpbWl6ZWQgPSBmYWxzZSkgPT4gew0KICAgIGNvbnN0IHsNCiAgICAgIHR5cGUsDQogICAgICBwcm9wcywNCiAgICAgIHJlZiwNCiAgICAgIGNoaWxkcmVuLA0KICAgICAgZHluYW1pY0NoaWxkcmVuLA0KICAgICAgc2hhcGVGbGFnLA0KICAgICAgcGF0Y2hGbGFnLA0KICAgICAgZGlycywNCiAgICAgIGNhY2hlSW5kZXgNCiAgICB9ID0gdm5vZGU7DQogICAgaWYgKHBhdGNoRmxhZyA9PT0gLTIpIHsNCiAgICAgIG9wdGltaXplZCA9IGZhbHNlOw0KICAgIH0NCiAgICBpZiAocmVmICE9IG51bGwpIHsNCiAgICAgIHBhdXNlVHJhY2tpbmcoKTsNCiAgICAgIHNldFJlZihyZWYsIG51bGwsIHBhcmVudFN1c3BlbnNlLCB2bm9kZSwgdHJ1ZSk7DQogICAgICByZXNldFRyYWNraW5nKCk7DQogICAgfQ0KICAgIGlmIChjYWNoZUluZGV4ICE9IG51bGwpIHsNCiAgICAgIHBhcmVudENvbXBvbmVudC5yZW5kZXJDYWNoZVtjYWNoZUluZGV4XSA9IHZvaWQgMDsNCiAgICB9DQogICAgaWYgKHNoYXBlRmxhZyAmIDI1Nikgew0KICAgICAgcGFyZW50Q29tcG9uZW50LmN0eC5kZWFjdGl2YXRlKHZub2RlKTsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgY29uc3Qgc2hvdWxkSW52b2tlRGlycyA9IHNoYXBlRmxhZyAmIDEgJiYgZGlyczsNCiAgICBjb25zdCBzaG91bGRJbnZva2VWbm9kZUhvb2sgPSAhaXNBc3luY1dyYXBwZXIodm5vZGUpOw0KICAgIGxldCB2bm9kZUhvb2s7DQogICAgaWYgKHNob3VsZEludm9rZVZub2RlSG9vayAmJiAodm5vZGVIb29rID0gcHJvcHMgJiYgcHJvcHMub25Wbm9kZUJlZm9yZVVubW91bnQpKSB7DQogICAgICBpbnZva2VWTm9kZUhvb2sodm5vZGVIb29rLCBwYXJlbnRDb21wb25lbnQsIHZub2RlKTsNCiAgICB9DQogICAgaWYgKHNoYXBlRmxhZyAmIDYpIHsNCiAgICAgIHVubW91bnRDb21wb25lbnQodm5vZGUuY29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgZG9SZW1vdmUpOw0KICAgIH0gZWxzZSB7DQogICAgICBpZiAoc2hhcGVGbGFnICYgMTI4KSB7DQogICAgICAgIHZub2RlLnN1c3BlbnNlLnVubW91bnQocGFyZW50U3VzcGVuc2UsIGRvUmVtb3ZlKTsNCiAgICAgICAgcmV0dXJuOw0KICAgICAgfQ0KICAgICAgaWYgKHNob3VsZEludm9rZURpcnMpIHsNCiAgICAgICAgaW52b2tlRGlyZWN0aXZlSG9vayh2bm9kZSwgbnVsbCwgcGFyZW50Q29tcG9uZW50LCAiYmVmb3JlVW5tb3VudCIpOw0KICAgICAgfQ0KICAgICAgaWYgKHNoYXBlRmxhZyAmIDY0KSB7DQogICAgICAgIHZub2RlLnR5cGUucmVtb3ZlKA0KICAgICAgICAgIHZub2RlLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBwYXJlbnRTdXNwZW5zZSwNCiAgICAgICAgICBpbnRlcm5hbHMsDQogICAgICAgICAgZG9SZW1vdmUNCiAgICAgICAgKTsNCiAgICAgIH0gZWxzZSBpZiAoZHluYW1pY0NoaWxkcmVuICYmIC8vICM1MTU0DQogICAgICAvLyB3aGVuIHYtb25jZSBpcyB1c2VkIGluc2lkZSBhIGJsb2NrLCBzZXRCbG9ja1RyYWNraW5nKC0xKSBtYXJrcyB0aGUNCiAgICAgIC8vIHBhcmVudCBibG9jayB3aXRoIGhhc09uY2U6IHRydWUNCiAgICAgIC8vIHNvIHRoYXQgaXQgZG9lc24ndCB0YWtlIHRoZSBmYXN0IHBhdGggZHVyaW5nIHVubW91bnQgLSBvdGhlcndpc2UNCiAgICAgIC8vIGNvbXBvbmVudHMgbmVzdGVkIGluIHYtb25jZSBhcmUgbmV2ZXIgdW5tb3VudGVkLg0KICAgICAgIWR5bmFtaWNDaGlsZHJlbi5oYXNPbmNlICYmIC8vICMxMTUzOiBmYXN0IHBhdGggc2hvdWxkIG5vdCBiZSB0YWtlbiBmb3Igbm9uLXN0YWJsZSAodi1mb3IpIGZyYWdtZW50cw0KICAgICAgKHR5cGUgIT09IEZyYWdtZW50IHx8IHBhdGNoRmxhZyA+IDAgJiYgcGF0Y2hGbGFnICYgNjQpKSB7DQogICAgICAgIHVubW91bnRDaGlsZHJlbigNCiAgICAgICAgICBkeW5hbWljQ2hpbGRyZW4sDQogICAgICAgICAgcGFyZW50Q29tcG9uZW50LA0KICAgICAgICAgIHBhcmVudFN1c3BlbnNlLA0KICAgICAgICAgIGZhbHNlLA0KICAgICAgICAgIHRydWUNCiAgICAgICAgKTsNCiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gRnJhZ21lbnQgJiYgcGF0Y2hGbGFnICYgKDEyOCB8IDI1NikgfHwgIW9wdGltaXplZCAmJiBzaGFwZUZsYWcgJiAxNikgew0KICAgICAgICB1bm1vdW50Q2hpbGRyZW4oY2hpbGRyZW4sIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UpOw0KICAgICAgfQ0KICAgICAgaWYgKGRvUmVtb3ZlKSB7DQogICAgICAgIHJlbW92ZSh2bm9kZSk7DQogICAgICB9DQogICAgfQ0KICAgIGlmIChzaG91bGRJbnZva2VWbm9kZUhvb2sgJiYgKHZub2RlSG9vayA9IHByb3BzICYmIHByb3BzLm9uVm5vZGVVbm1vdW50ZWQpIHx8IHNob3VsZEludm9rZURpcnMpIHsNCiAgICAgIHF1ZXVlUG9zdFJlbmRlckVmZmVjdCgoKSA9PiB7DQogICAgICAgIHZub2RlSG9vayAmJiBpbnZva2VWTm9kZUhvb2sodm5vZGVIb29rLCBwYXJlbnRDb21wb25lbnQsIHZub2RlKTsNCiAgICAgICAgc2hvdWxkSW52b2tlRGlycyAmJiBpbnZva2VEaXJlY3RpdmVIb29rKHZub2RlLCBudWxsLCBwYXJlbnRDb21wb25lbnQsICJ1bm1vdW50ZWQiKTsNCiAgICAgIH0sIHBhcmVudFN1c3BlbnNlKTsNCiAgICB9DQogIH07DQogIGNvbnN0IHJlbW92ZSA9ICh2bm9kZSkgPT4gew0KICAgIGNvbnN0IHsgdHlwZSwgZWwsIGFuY2hvciwgdHJhbnNpdGlvbiB9ID0gdm5vZGU7DQogICAgaWYgKHR5cGUgPT09IEZyYWdtZW50KSB7DQogICAgICBpZiAodm5vZGUucGF0Y2hGbGFnID4gMCAmJiB2bm9kZS5wYXRjaEZsYWcgJiAyMDQ4ICYmIHRyYW5zaXRpb24gJiYgIXRyYW5zaXRpb24ucGVyc2lzdGVkKSB7DQogICAgICAgIHZub2RlLmNoaWxkcmVuLmZvckVhY2goKGNoaWxkKSA9PiB7DQogICAgICAgICAgaWYgKGNoaWxkLnR5cGUgPT09IENvbW1lbnQpIHsNCiAgICAgICAgICAgIGhvc3RSZW1vdmUoY2hpbGQuZWwpOw0KICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICByZW1vdmUoY2hpbGQpOw0KICAgICAgICAgIH0NCiAgICAgICAgfSk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICByZW1vdmVGcmFnbWVudChlbCwgYW5jaG9yKTsNCiAgICAgIH0NCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgaWYgKHR5cGUgPT09IFN0YXRpYykgew0KICAgICAgcmVtb3ZlU3RhdGljTm9kZSh2bm9kZSk7DQogICAgICByZXR1cm47DQogICAgfQ0KICAgIGNvbnN0IHBlcmZvcm1SZW1vdmUgPSAoKSA9PiB7DQogICAgICBob3N0UmVtb3ZlKGVsKTsNCiAgICAgIGlmICh0cmFuc2l0aW9uICYmICF0cmFuc2l0aW9uLnBlcnNpc3RlZCAmJiB0cmFuc2l0aW9uLmFmdGVyTGVhdmUpIHsNCiAgICAgICAgdHJhbnNpdGlvbi5hZnRlckxlYXZlKCk7DQogICAgICB9DQogICAgfTsNCiAgICBpZiAodm5vZGUuc2hhcGVGbGFnICYgMSAmJiB0cmFuc2l0aW9uICYmICF0cmFuc2l0aW9uLnBlcnNpc3RlZCkgew0KICAgICAgY29uc3QgeyBsZWF2ZSwgZGVsYXlMZWF2ZSB9ID0gdHJhbnNpdGlvbjsNCiAgICAgIGNvbnN0IHBlcmZvcm1MZWF2ZSA9ICgpID0+IGxlYXZlKGVsLCBwZXJmb3JtUmVtb3ZlKTsNCiAgICAgIGlmIChkZWxheUxlYXZlKSB7DQogICAgICAgIGRlbGF5TGVhdmUodm5vZGUuZWwsIHBlcmZvcm1SZW1vdmUsIHBlcmZvcm1MZWF2ZSk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBwZXJmb3JtTGVhdmUoKTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgcGVyZm9ybVJlbW92ZSgpOw0KICAgIH0NCiAgfTsNCiAgY29uc3QgcmVtb3ZlRnJhZ21lbnQgPSAoY3VyLCBlbmQpID0+IHsNCiAgICBsZXQgbmV4dDsNCiAgICB3aGlsZSAoY3VyICE9PSBlbmQpIHsNCiAgICAgIG5leHQgPSBob3N0TmV4dFNpYmxpbmcoY3VyKTsNCiAgICAgIGhvc3RSZW1vdmUoY3VyKTsNCiAgICAgIGN1ciA9IG5leHQ7DQogICAgfQ0KICAgIGhvc3RSZW1vdmUoZW5kKTsNCiAgfTsNCiAgY29uc3QgdW5tb3VudENvbXBvbmVudCA9IChpbnN0YW5jZSwgcGFyZW50U3VzcGVuc2UsIGRvUmVtb3ZlKSA9PiB7DQogICAgaWYgKGluc3RhbmNlLnR5cGUuX19obXJJZCkgew0KICAgICAgdW5yZWdpc3RlckhNUihpbnN0YW5jZSk7DQogICAgfQ0KICAgIGNvbnN0IHsNCiAgICAgIGJ1bSwNCiAgICAgIHNjb3BlLA0KICAgICAgam9iLA0KICAgICAgc3ViVHJlZSwNCiAgICAgIHVtLA0KICAgICAgbSwNCiAgICAgIGEsDQogICAgICBwYXJlbnQsDQogICAgICBzbG90czogeyBfXzogc2xvdENhY2hlS2V5cyB9DQogICAgfSA9IGluc3RhbmNlOw0KICAgIGludmFsaWRhdGVNb3VudChtKTsNCiAgICBpbnZhbGlkYXRlTW91bnQoYSk7DQogICAgaWYgKGJ1bSkgew0KICAgICAgaW52b2tlQXJyYXlGbnMoYnVtKTsNCiAgICB9DQogICAgaWYgKHBhcmVudCAmJiBpc0FycmF5KHNsb3RDYWNoZUtleXMpKSB7DQogICAgICBzbG90Q2FjaGVLZXlzLmZvckVhY2goKHYpID0+IHsNCiAgICAgICAgcGFyZW50LnJlbmRlckNhY2hlW3ZdID0gdm9pZCAwOw0KICAgICAgfSk7DQogICAgfQ0KICAgIHNjb3BlLnN0b3AoKTsNCiAgICBpZiAoam9iKSB7DQogICAgICBqb2IuZmxhZ3MgfD0gODsNCiAgICAgIHVubW91bnQoc3ViVHJlZSwgaW5zdGFuY2UsIHBhcmVudFN1c3BlbnNlLCBkb1JlbW92ZSk7DQogICAgfQ0KICAgIGlmICh1bSkgew0KICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KHVtLCBwYXJlbnRTdXNwZW5zZSk7DQogICAgfQ0KICAgIHF1ZXVlUG9zdFJlbmRlckVmZmVjdCgoKSA9PiB7DQogICAgICBpbnN0YW5jZS5pc1VubW91bnRlZCA9IHRydWU7DQogICAgfSwgcGFyZW50U3VzcGVuc2UpOw0KICAgIGlmIChwYXJlbnRTdXNwZW5zZSAmJiBwYXJlbnRTdXNwZW5zZS5wZW5kaW5nQnJhbmNoICYmICFwYXJlbnRTdXNwZW5zZS5pc1VubW91bnRlZCAmJiBpbnN0YW5jZS5hc3luY0RlcCAmJiAhaW5zdGFuY2UuYXN5bmNSZXNvbHZlZCAmJiBpbnN0YW5jZS5zdXNwZW5zZUlkID09PSBwYXJlbnRTdXNwZW5zZS5wZW5kaW5nSWQpIHsNCiAgICAgIHBhcmVudFN1c3BlbnNlLmRlcHMtLTsNCiAgICAgIGlmIChwYXJlbnRTdXNwZW5zZS5kZXBzID09PSAwKSB7DQogICAgICAgIHBhcmVudFN1c3BlbnNlLnJlc29sdmUoKTsNCiAgICAgIH0NCiAgICB9DQogICAgew0KICAgICAgZGV2dG9vbHNDb21wb25lbnRSZW1vdmVkKGluc3RhbmNlKTsNCiAgICB9DQogIH07DQogIGNvbnN0IHVubW91bnRDaGlsZHJlbiA9IChjaGlsZHJlbiwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgZG9SZW1vdmUgPSBmYWxzZSwgb3B0aW1pemVkID0gZmFsc2UsIHN0YXJ0ID0gMCkgPT4gew0KICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7DQogICAgICB1bm1vdW50KGNoaWxkcmVuW2ldLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBkb1JlbW92ZSwgb3B0aW1pemVkKTsNCiAgICB9DQogIH07DQogIGNvbnN0IGdldE5leHRIb3N0Tm9kZSA9ICh2bm9kZSkgPT4gew0KICAgIGlmICh2bm9kZS5zaGFwZUZsYWcgJiA2KSB7DQogICAgICByZXR1cm4gZ2V0TmV4dEhvc3ROb2RlKHZub2RlLmNvbXBvbmVudC5zdWJUcmVlKTsNCiAgICB9DQogICAgaWYgKHZub2RlLnNoYXBlRmxhZyAmIDEyOCkgew0KICAgICAgcmV0dXJuIHZub2RlLnN1c3BlbnNlLm5leHQoKTsNCiAgICB9DQogICAgY29uc3QgZWwgPSBob3N0TmV4dFNpYmxpbmcodm5vZGUuYW5jaG9yIHx8IHZub2RlLmVsKTsNCiAgICBjb25zdCB0ZWxlcG9ydEVuZCA9IGVsICYmIGVsW1RlbGVwb3J0RW5kS2V5XTsNCiAgICByZXR1cm4gdGVsZXBvcnRFbmQgPyBob3N0TmV4dFNpYmxpbmcodGVsZXBvcnRFbmQpIDogZWw7DQogIH07DQogIGxldCBpc0ZsdXNoaW5nID0gZmFsc2U7DQogIGNvbnN0IHJlbmRlciA9ICh2bm9kZSwgY29udGFpbmVyLCBuYW1lc3BhY2UpID0+IHsNCiAgICBpZiAodm5vZGUgPT0gbnVsbCkgew0KICAgICAgaWYgKGNvbnRhaW5lci5fdm5vZGUpIHsNCiAgICAgICAgdW5tb3VudChjb250YWluZXIuX3Zub2RlLCBudWxsLCBudWxsLCB0cnVlKTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgcGF0Y2goDQogICAgICAgIGNvbnRhaW5lci5fdm5vZGUgfHwgbnVsbCwNCiAgICAgICAgdm5vZGUsDQogICAgICAgIGNvbnRhaW5lciwNCiAgICAgICAgbnVsbCwNCiAgICAgICAgbnVsbCwNCiAgICAgICAgbnVsbCwNCiAgICAgICAgbmFtZXNwYWNlDQogICAgICApOw0KICAgIH0NCiAgICBjb250YWluZXIuX3Zub2RlID0gdm5vZGU7DQogICAgaWYgKCFpc0ZsdXNoaW5nKSB7DQogICAgICBpc0ZsdXNoaW5nID0gdHJ1ZTsNCiAgICAgIGZsdXNoUHJlRmx1c2hDYnMoKTsNCiAgICAgIGZsdXNoUG9zdEZsdXNoQ2JzKCk7DQogICAgICBpc0ZsdXNoaW5nID0gZmFsc2U7DQogICAgfQ0KICB9Ow0KICBjb25zdCBpbnRlcm5hbHMgPSB7DQogICAgcDogcGF0Y2gsDQogICAgdW06IHVubW91bnQsDQogICAgbTogbW92ZSwNCiAgICByOiByZW1vdmUsDQogICAgbXQ6IG1vdW50Q29tcG9uZW50LA0KICAgIG1jOiBtb3VudENoaWxkcmVuLA0KICAgIHBjOiBwYXRjaENoaWxkcmVuLA0KICAgIHBiYzogcGF0Y2hCbG9ja0NoaWxkcmVuLA0KICAgIG46IGdldE5leHRIb3N0Tm9kZSwNCiAgICBvOiBvcHRpb25zDQogIH07DQogIGxldCBoeWRyYXRlOw0KICByZXR1cm4gew0KICAgIHJlbmRlciwNCiAgICBoeWRyYXRlLA0KICAgIGNyZWF0ZUFwcDogY3JlYXRlQXBwQVBJKHJlbmRlcikNCiAgfTsNCn0NCmZ1bmN0aW9uIHJlc29sdmVDaGlsZHJlbk5hbWVzcGFjZSh7IHR5cGUsIHByb3BzIH0sIGN1cnJlbnROYW1lc3BhY2UpIHsNCiAgcmV0dXJuIGN1cnJlbnROYW1lc3BhY2UgPT09ICJzdmciICYmIHR5cGUgPT09ICJmb3JlaWduT2JqZWN0IiB8fCBjdXJyZW50TmFtZXNwYWNlID09PSAibWF0aG1sIiAmJiB0eXBlID09PSAiYW5ub3RhdGlvbi14bWwiICYmIHByb3BzICYmIHByb3BzLmVuY29kaW5nICYmIHByb3BzLmVuY29kaW5nLmluY2x1ZGVzKCJodG1sIikgPyB2b2lkIDAgOiBjdXJyZW50TmFtZXNwYWNlOw0KfQ0KZnVuY3Rpb24gdG9nZ2xlUmVjdXJzZSh7IGVmZmVjdCwgam9iIH0sIGFsbG93ZWQpIHsNCiAgaWYgKGFsbG93ZWQpIHsNCiAgICBlZmZlY3QuZmxhZ3MgfD0gMzI7DQogICAgam9iLmZsYWdzIHw9IDQ7DQogIH0gZWxzZSB7DQogICAgZWZmZWN0LmZsYWdzICY9IC0zMzsNCiAgICBqb2IuZmxhZ3MgJj0gLTU7DQogIH0NCn0NCmZ1bmN0aW9uIG5lZWRUcmFuc2l0aW9uKHBhcmVudFN1c3BlbnNlLCB0cmFuc2l0aW9uKSB7DQogIHJldHVybiAoIXBhcmVudFN1c3BlbnNlIHx8IHBhcmVudFN1c3BlbnNlICYmICFwYXJlbnRTdXNwZW5zZS5wZW5kaW5nQnJhbmNoKSAmJiB0cmFuc2l0aW9uICYmICF0cmFuc2l0aW9uLnBlcnNpc3RlZDsNCn0NCmZ1bmN0aW9uIHRyYXZlcnNlU3RhdGljQ2hpbGRyZW4objEsIG4yLCBzaGFsbG93ID0gZmFsc2UpIHsNCiAgY29uc3QgY2gxID0gbjEuY2hpbGRyZW47DQogIGNvbnN0IGNoMiA9IG4yLmNoaWxkcmVuOw0KICBpZiAoaXNBcnJheShjaDEpICYmIGlzQXJyYXkoY2gyKSkgew0KICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2gxLmxlbmd0aDsgaSsrKSB7DQogICAgICBjb25zdCBjMSA9IGNoMVtpXTsNCiAgICAgIGxldCBjMiA9IGNoMltpXTsNCiAgICAgIGlmIChjMi5zaGFwZUZsYWcgJiAxICYmICFjMi5keW5hbWljQ2hpbGRyZW4pIHsNCiAgICAgICAgaWYgKGMyLnBhdGNoRmxhZyA8PSAwIHx8IGMyLnBhdGNoRmxhZyA9PT0gMzIpIHsNCiAgICAgICAgICBjMiA9IGNoMltpXSA9IGNsb25lSWZNb3VudGVkKGNoMltpXSk7DQogICAgICAgICAgYzIuZWwgPSBjMS5lbDsNCiAgICAgICAgfQ0KICAgICAgICBpZiAoIXNoYWxsb3cgJiYgYzIucGF0Y2hGbGFnICE9PSAtMikNCiAgICAgICAgICB0cmF2ZXJzZVN0YXRpY0NoaWxkcmVuKGMxLCBjMik7DQogICAgICB9DQogICAgICBpZiAoYzIudHlwZSA9PT0gVGV4dCkgew0KICAgICAgICBjMi5lbCA9IGMxLmVsOw0KICAgICAgfQ0KICAgICAgaWYgKGMyLnR5cGUgPT09IENvbW1lbnQgJiYgIWMyLmVsKSB7DQogICAgICAgIGMyLmVsID0gYzEuZWw7DQogICAgICB9DQogICAgICB7DQogICAgICAgIGMyLmVsICYmIChjMi5lbC5fX3Zub2RlID0gYzIpOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KfQ0KZnVuY3Rpb24gZ2V0U2VxdWVuY2UoYXJyKSB7DQogIGNvbnN0IHAgPSBhcnIuc2xpY2UoKTsNCiAgY29uc3QgcmVzdWx0ID0gWzBdOw0KICBsZXQgaSwgaiwgdSwgdiwgYzsNCiAgY29uc3QgbGVuID0gYXJyLmxlbmd0aDsNCiAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7DQogICAgY29uc3QgYXJySSA9IGFycltpXTsNCiAgICBpZiAoYXJySSAhPT0gMCkgew0KICAgICAgaiA9IHJlc3VsdFtyZXN1bHQubGVuZ3RoIC0gMV07DQogICAgICBpZiAoYXJyW2pdIDwgYXJySSkgew0KICAgICAgICBwW2ldID0gajsNCiAgICAgICAgcmVzdWx0LnB1c2goaSk7DQogICAgICAgIGNvbnRpbnVlOw0KICAgICAgfQ0KICAgICAgdSA9IDA7DQogICAgICB2ID0gcmVzdWx0Lmxlbmd0aCAtIDE7DQogICAgICB3aGlsZSAodSA8IHYpIHsNCiAgICAgICAgYyA9IHUgKyB2ID4+IDE7DQogICAgICAgIGlmIChhcnJbcmVzdWx0W2NdXSA8IGFyckkpIHsNCiAgICAgICAgICB1ID0gYyArIDE7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgdiA9IGM7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGlmIChhcnJJIDwgYXJyW3Jlc3VsdFt1XV0pIHsNCiAgICAgICAgaWYgKHUgPiAwKSB7DQogICAgICAgICAgcFtpXSA9IHJlc3VsdFt1IC0gMV07DQogICAgICAgIH0NCiAgICAgICAgcmVzdWx0W3VdID0gaTsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgdSA9IHJlc3VsdC5sZW5ndGg7DQogIHYgPSByZXN1bHRbdSAtIDFdOw0KICB3aGlsZSAodS0tID4gMCkgew0KICAgIHJlc3VsdFt1XSA9IHY7DQogICAgdiA9IHBbdl07DQogIH0NCiAgcmV0dXJuIHJlc3VsdDsNCn0NCmZ1bmN0aW9uIGxvY2F0ZU5vbkh5ZHJhdGVkQXN5bmNSb290KGluc3RhbmNlKSB7DQogIGNvbnN0IHN1YkNvbXBvbmVudCA9IGluc3RhbmNlLnN1YlRyZWUuY29tcG9uZW50Ow0KICBpZiAoc3ViQ29tcG9uZW50KSB7DQogICAgaWYgKHN1YkNvbXBvbmVudC5hc3luY0RlcCAmJiAhc3ViQ29tcG9uZW50LmFzeW5jUmVzb2x2ZWQpIHsNCiAgICAgIHJldHVybiBzdWJDb21wb25lbnQ7DQogICAgfSBlbHNlIHsNCiAgICAgIHJldHVybiBsb2NhdGVOb25IeWRyYXRlZEFzeW5jUm9vdChzdWJDb21wb25lbnQpOw0KICAgIH0NCiAgfQ0KfQ0KZnVuY3Rpb24gaW52YWxpZGF0ZU1vdW50KGhvb2tzKSB7DQogIGlmIChob29rcykgew0KICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaG9va3MubGVuZ3RoOyBpKyspDQogICAgICBob29rc1tpXS5mbGFncyB8PSA4Ow0KICB9DQp9DQoNCmNvbnN0IHNzckNvbnRleHRLZXkgPSBTeW1ib2wuZm9yKCJ2LXNjeCIpOw0KY29uc3QgdXNlU1NSQ29udGV4dCA9ICgpID0+IHsNCiAgew0KICAgIGNvbnN0IGN0eCA9IGluamVjdChzc3JDb250ZXh0S2V5KTsNCiAgICBpZiAoIWN0eCkgew0KICAgICAgd2FybiQxKA0KICAgICAgICBgU2VydmVyIHJlbmRlcmluZyBjb250ZXh0IG5vdCBwcm92aWRlZC4gTWFrZSBzdXJlIHRvIG9ubHkgY2FsbCB1c2VTU1JDb250ZXh0KCkgY29uZGl0aW9uYWxseSBpbiB0aGUgc2VydmVyIGJ1aWxkLmANCiAgICAgICk7DQogICAgfQ0KICAgIHJldHVybiBjdHg7DQogIH0NCn07DQoNCmZ1bmN0aW9uIHdhdGNoKHNvdXJjZSwgY2IsIG9wdGlvbnMpIHsNCiAgaWYgKCFpc0Z1bmN0aW9uKGNiKSkgew0KICAgIHdhcm4kMSgNCiAgICAgIGBcYHdhdGNoKGZuLCBvcHRpb25zPylcYCBzaWduYXR1cmUgaGFzIGJlZW4gbW92ZWQgdG8gYSBzZXBhcmF0ZSBBUEkuIFVzZSBcYHdhdGNoRWZmZWN0KGZuLCBvcHRpb25zPylcYCBpbnN0ZWFkLiBcYHdhdGNoXGAgbm93IG9ubHkgc3VwcG9ydHMgXGB3YXRjaChzb3VyY2UsIGNiLCBvcHRpb25zPykgc2lnbmF0dXJlLmANCiAgICApOw0KICB9DQogIHJldHVybiBkb1dhdGNoKHNvdXJjZSwgY2IsIG9wdGlvbnMpOw0KfQ0KZnVuY3Rpb24gZG9XYXRjaChzb3VyY2UsIGNiLCBvcHRpb25zID0gRU1QVFlfT0JKKSB7DQogIGNvbnN0IHsgaW1tZWRpYXRlLCBkZWVwLCBmbHVzaCwgb25jZSB9ID0gb3B0aW9uczsNCiAgaWYgKCFjYikgew0KICAgIGlmIChpbW1lZGlhdGUgIT09IHZvaWQgMCkgew0KICAgICAgd2FybiQxKA0KICAgICAgICBgd2F0Y2goKSAiaW1tZWRpYXRlIiBvcHRpb24gaXMgb25seSByZXNwZWN0ZWQgd2hlbiB1c2luZyB0aGUgd2F0Y2goc291cmNlLCBjYWxsYmFjaywgb3B0aW9ucz8pIHNpZ25hdHVyZS5gDQogICAgICApOw0KICAgIH0NCiAgICBpZiAoZGVlcCAhPT0gdm9pZCAwKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGB3YXRjaCgpICJkZWVwIiBvcHRpb24gaXMgb25seSByZXNwZWN0ZWQgd2hlbiB1c2luZyB0aGUgd2F0Y2goc291cmNlLCBjYWxsYmFjaywgb3B0aW9ucz8pIHNpZ25hdHVyZS5gDQogICAgICApOw0KICAgIH0NCiAgICBpZiAob25jZSAhPT0gdm9pZCAwKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGB3YXRjaCgpICJvbmNlIiBvcHRpb24gaXMgb25seSByZXNwZWN0ZWQgd2hlbiB1c2luZyB0aGUgd2F0Y2goc291cmNlLCBjYWxsYmFjaywgb3B0aW9ucz8pIHNpZ25hdHVyZS5gDQogICAgICApOw0KICAgIH0NCiAgfQ0KICBjb25zdCBiYXNlV2F0Y2hPcHRpb25zID0gZXh0ZW5kKHt9LCBvcHRpb25zKTsNCiAgYmFzZVdhdGNoT3B0aW9ucy5vbldhcm4gPSB3YXJuJDE7DQogIGNvbnN0IHJ1bnNJbW1lZGlhdGVseSA9IGNiICYmIGltbWVkaWF0ZSB8fCAhY2IgJiYgZmx1c2ggIT09ICJwb3N0IjsNCiAgbGV0IHNzckNsZWFudXA7DQogIGlmIChpc0luU1NSQ29tcG9uZW50U2V0dXApIHsNCiAgICBpZiAoZmx1c2ggPT09ICJzeW5jIikgew0KICAgICAgY29uc3QgY3R4ID0gdXNlU1NSQ29udGV4dCgpOw0KICAgICAgc3NyQ2xlYW51cCA9IGN0eC5fX3dhdGNoZXJIYW5kbGVzIHx8IChjdHguX193YXRjaGVySGFuZGxlcyA9IFtdKTsNCiAgICB9IGVsc2UgaWYgKCFydW5zSW1tZWRpYXRlbHkpIHsNCiAgICAgIGNvbnN0IHdhdGNoU3RvcEhhbmRsZSA9ICgpID0+IHsNCiAgICAgIH07DQogICAgICB3YXRjaFN0b3BIYW5kbGUuc3RvcCA9IE5PT1A7DQogICAgICB3YXRjaFN0b3BIYW5kbGUucmVzdW1lID0gTk9PUDsNCiAgICAgIHdhdGNoU3RvcEhhbmRsZS5wYXVzZSA9IE5PT1A7DQogICAgICByZXR1cm4gd2F0Y2hTdG9wSGFuZGxlOw0KICAgIH0NCiAgfQ0KICBjb25zdCBpbnN0YW5jZSA9IGN1cnJlbnRJbnN0YW5jZTsNCiAgYmFzZVdhdGNoT3B0aW9ucy5jYWxsID0gKGZuLCB0eXBlLCBhcmdzKSA9PiBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZyhmbiwgaW5zdGFuY2UsIHR5cGUsIGFyZ3MpOw0KICBsZXQgaXNQcmUgPSBmYWxzZTsNCiAgaWYgKGZsdXNoID09PSAicG9zdCIpIHsNCiAgICBiYXNlV2F0Y2hPcHRpb25zLnNjaGVkdWxlciA9IChqb2IpID0+IHsNCiAgICAgIHF1ZXVlUG9zdFJlbmRlckVmZmVjdChqb2IsIGluc3RhbmNlICYmIGluc3RhbmNlLnN1c3BlbnNlKTsNCiAgICB9Ow0KICB9IGVsc2UgaWYgKGZsdXNoICE9PSAic3luYyIpIHsNCiAgICBpc1ByZSA9IHRydWU7DQogICAgYmFzZVdhdGNoT3B0aW9ucy5zY2hlZHVsZXIgPSAoam9iLCBpc0ZpcnN0UnVuKSA9PiB7DQogICAgICBpZiAoaXNGaXJzdFJ1bikgew0KICAgICAgICBqb2IoKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHF1ZXVlSm9iKGpvYik7DQogICAgICB9DQogICAgfTsNCiAgfQ0KICBiYXNlV2F0Y2hPcHRpb25zLmF1Z21lbnRKb2IgPSAoam9iKSA9PiB7DQogICAgaWYgKGNiKSB7DQogICAgICBqb2IuZmxhZ3MgfD0gNDsNCiAgICB9DQogICAgaWYgKGlzUHJlKSB7DQogICAgICBqb2IuZmxhZ3MgfD0gMjsNCiAgICAgIGlmIChpbnN0YW5jZSkgew0KICAgICAgICBqb2IuaWQgPSBpbnN0YW5jZS51aWQ7DQogICAgICAgIGpvYi5pID0gaW5zdGFuY2U7DQogICAgICB9DQogICAgfQ0KICB9Ow0KICBjb25zdCB3YXRjaEhhbmRsZSA9IHdhdGNoJDEoc291cmNlLCBjYiwgYmFzZVdhdGNoT3B0aW9ucyk7DQogIGlmIChpc0luU1NSQ29tcG9uZW50U2V0dXApIHsNCiAgICBpZiAoc3NyQ2xlYW51cCkgew0KICAgICAgc3NyQ2xlYW51cC5wdXNoKHdhdGNoSGFuZGxlKTsNCiAgICB9IGVsc2UgaWYgKHJ1bnNJbW1lZGlhdGVseSkgew0KICAgICAgd2F0Y2hIYW5kbGUoKTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIHdhdGNoSGFuZGxlOw0KfQ0KZnVuY3Rpb24gaW5zdGFuY2VXYXRjaChzb3VyY2UsIHZhbHVlLCBvcHRpb25zKSB7DQogIGNvbnN0IHB1YmxpY1RoaXMgPSB0aGlzLnByb3h5Ow0KICBjb25zdCBnZXR0ZXIgPSBpc1N0cmluZyhzb3VyY2UpID8gc291cmNlLmluY2x1ZGVzKCIuIikgPyBjcmVhdGVQYXRoR2V0dGVyKHB1YmxpY1RoaXMsIHNvdXJjZSkgOiAoKSA9PiBwdWJsaWNUaGlzW3NvdXJjZV0gOiBzb3VyY2UuYmluZChwdWJsaWNUaGlzLCBwdWJsaWNUaGlzKTsNCiAgbGV0IGNiOw0KICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHsNCiAgICBjYiA9IHZhbHVlOw0KICB9IGVsc2Ugew0KICAgIGNiID0gdmFsdWUuaGFuZGxlcjsNCiAgICBvcHRpb25zID0gdmFsdWU7DQogIH0NCiAgY29uc3QgcmVzZXQgPSBzZXRDdXJyZW50SW5zdGFuY2UodGhpcyk7DQogIGNvbnN0IHJlcyA9IGRvV2F0Y2goZ2V0dGVyLCBjYi5iaW5kKHB1YmxpY1RoaXMpLCBvcHRpb25zKTsNCiAgcmVzZXQoKTsNCiAgcmV0dXJuIHJlczsNCn0NCmZ1bmN0aW9uIGNyZWF0ZVBhdGhHZXR0ZXIoY3R4LCBwYXRoKSB7DQogIGNvbnN0IHNlZ21lbnRzID0gcGF0aC5zcGxpdCgiLiIpOw0KICByZXR1cm4gKCkgPT4gew0KICAgIGxldCBjdXIgPSBjdHg7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWdtZW50cy5sZW5ndGggJiYgY3VyOyBpKyspIHsNCiAgICAgIGN1ciA9IGN1cltzZWdtZW50c1tpXV07DQogICAgfQ0KICAgIHJldHVybiBjdXI7DQogIH07DQp9DQoNCmNvbnN0IGdldE1vZGVsTW9kaWZpZXJzID0gKHByb3BzLCBtb2RlbE5hbWUpID0+IHsNCiAgcmV0dXJuIG1vZGVsTmFtZSA9PT0gIm1vZGVsVmFsdWUiIHx8IG1vZGVsTmFtZSA9PT0gIm1vZGVsLXZhbHVlIiA/IHByb3BzLm1vZGVsTW9kaWZpZXJzIDogcHJvcHNbYCR7bW9kZWxOYW1lfU1vZGlmaWVyc2BdIHx8IHByb3BzW2Ake2NhbWVsaXplKG1vZGVsTmFtZSl9TW9kaWZpZXJzYF0gfHwgcHJvcHNbYCR7aHlwaGVuYXRlKG1vZGVsTmFtZSl9TW9kaWZpZXJzYF07DQp9Ow0KDQpmdW5jdGlvbiBlbWl0KGluc3RhbmNlLCBldmVudCwgLi4ucmF3QXJncykgew0KICBpZiAoaW5zdGFuY2UuaXNVbm1vdW50ZWQpIHJldHVybjsNCiAgY29uc3QgcHJvcHMgPSBpbnN0YW5jZS52bm9kZS5wcm9wcyB8fCBFTVBUWV9PQko7DQogIHsNCiAgICBjb25zdCB7DQogICAgICBlbWl0c09wdGlvbnMsDQogICAgICBwcm9wc09wdGlvbnM6IFtwcm9wc09wdGlvbnNdDQogICAgfSA9IGluc3RhbmNlOw0KICAgIGlmIChlbWl0c09wdGlvbnMpIHsNCiAgICAgIGlmICghKGV2ZW50IGluIGVtaXRzT3B0aW9ucykgJiYgdHJ1ZSkgew0KICAgICAgICBpZiAoIXByb3BzT3B0aW9ucyB8fCAhKHRvSGFuZGxlcktleShjYW1lbGl6ZShldmVudCkpIGluIHByb3BzT3B0aW9ucykpIHsNCiAgICAgICAgICB3YXJuJDEoDQogICAgICAgICAgICBgQ29tcG9uZW50IGVtaXR0ZWQgZXZlbnQgIiR7ZXZlbnR9IiBidXQgaXQgaXMgbmVpdGhlciBkZWNsYXJlZCBpbiB0aGUgZW1pdHMgb3B0aW9uIG5vciBhcyBhbiAiJHt0b0hhbmRsZXJLZXkoY2FtZWxpemUoZXZlbnQpKX0iIHByb3AuYA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGNvbnN0IHZhbGlkYXRvciA9IGVtaXRzT3B0aW9uc1tldmVudF07DQogICAgICAgIGlmIChpc0Z1bmN0aW9uKHZhbGlkYXRvcikpIHsNCiAgICAgICAgICBjb25zdCBpc1ZhbGlkID0gdmFsaWRhdG9yKC4uLnJhd0FyZ3MpOw0KICAgICAgICAgIGlmICghaXNWYWxpZCkgew0KICAgICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgICBgSW52YWxpZCBldmVudCBhcmd1bWVudHM6IGV2ZW50IHZhbGlkYXRpb24gZmFpbGVkIGZvciBldmVudCAiJHtldmVudH0iLmANCiAgICAgICAgICAgICk7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICB9DQogIGxldCBhcmdzID0gcmF3QXJnczsNCiAgY29uc3QgaXNNb2RlbExpc3RlbmVyID0gZXZlbnQuc3RhcnRzV2l0aCgidXBkYXRlOiIpOw0KICBjb25zdCBtb2RpZmllcnMgPSBpc01vZGVsTGlzdGVuZXIgJiYgZ2V0TW9kZWxNb2RpZmllcnMocHJvcHMsIGV2ZW50LnNsaWNlKDcpKTsNCiAgaWYgKG1vZGlmaWVycykgew0KICAgIGlmIChtb2RpZmllcnMudHJpbSkgew0KICAgICAgYXJncyA9IHJhd0FyZ3MubWFwKChhKSA9PiBpc1N0cmluZyhhKSA/IGEudHJpbSgpIDogYSk7DQogICAgfQ0KICAgIGlmIChtb2RpZmllcnMubnVtYmVyKSB7DQogICAgICBhcmdzID0gcmF3QXJncy5tYXAobG9vc2VUb051bWJlcik7DQogICAgfQ0KICB9DQogIHsNCiAgICBkZXZ0b29sc0NvbXBvbmVudEVtaXQoaW5zdGFuY2UsIGV2ZW50LCBhcmdzKTsNCiAgfQ0KICB7DQogICAgY29uc3QgbG93ZXJDYXNlRXZlbnQgPSBldmVudC50b0xvd2VyQ2FzZSgpOw0KICAgIGlmIChsb3dlckNhc2VFdmVudCAhPT0gZXZlbnQgJiYgcHJvcHNbdG9IYW5kbGVyS2V5KGxvd2VyQ2FzZUV2ZW50KV0pIHsNCiAgICAgIHdhcm4kMSgNCiAgICAgICAgYEV2ZW50ICIke2xvd2VyQ2FzZUV2ZW50fSIgaXMgZW1pdHRlZCBpbiBjb21wb25lbnQgJHtmb3JtYXRDb21wb25lbnROYW1lKA0KICAgICAgICAgIGluc3RhbmNlLA0KICAgICAgICAgIGluc3RhbmNlLnR5cGUNCiAgICAgICAgKX0gYnV0IHRoZSBoYW5kbGVyIGlzIHJlZ2lzdGVyZWQgZm9yICIke2V2ZW50fSIuIE5vdGUgdGhhdCBIVE1MIGF0dHJpYnV0ZXMgYXJlIGNhc2UtaW5zZW5zaXRpdmUgYW5kIHlvdSBjYW5ub3QgdXNlIHYtb24gdG8gbGlzdGVuIHRvIGNhbWVsQ2FzZSBldmVudHMgd2hlbiB1c2luZyBpbi1ET00gdGVtcGxhdGVzLiBZb3Ugc2hvdWxkIHByb2JhYmx5IHVzZSAiJHtoeXBoZW5hdGUoDQogICAgICAgICAgZXZlbnQNCiAgICAgICAgKX0iIGluc3RlYWQgb2YgIiR7ZXZlbnR9Ii5gDQogICAgICApOw0KICAgIH0NCiAgfQ0KICBsZXQgaGFuZGxlck5hbWU7DQogIGxldCBoYW5kbGVyID0gcHJvcHNbaGFuZGxlck5hbWUgPSB0b0hhbmRsZXJLZXkoZXZlbnQpXSB8fCAvLyBhbHNvIHRyeSBjYW1lbENhc2UgZXZlbnQgaGFuZGxlciAoIzIyNDkpDQogIHByb3BzW2hhbmRsZXJOYW1lID0gdG9IYW5kbGVyS2V5KGNhbWVsaXplKGV2ZW50KSldOw0KICBpZiAoIWhhbmRsZXIgJiYgaXNNb2RlbExpc3RlbmVyKSB7DQogICAgaGFuZGxlciA9IHByb3BzW2hhbmRsZXJOYW1lID0gdG9IYW5kbGVyS2V5KGh5cGhlbmF0ZShldmVudCkpXTsNCiAgfQ0KICBpZiAoaGFuZGxlcikgew0KICAgIGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nKA0KICAgICAgaGFuZGxlciwNCiAgICAgIGluc3RhbmNlLA0KICAgICAgNiwNCiAgICAgIGFyZ3MNCiAgICApOw0KICB9DQogIGNvbnN0IG9uY2VIYW5kbGVyID0gcHJvcHNbaGFuZGxlck5hbWUgKyBgT25jZWBdOw0KICBpZiAob25jZUhhbmRsZXIpIHsNCiAgICBpZiAoIWluc3RhbmNlLmVtaXR0ZWQpIHsNCiAgICAgIGluc3RhbmNlLmVtaXR0ZWQgPSB7fTsNCiAgICB9IGVsc2UgaWYgKGluc3RhbmNlLmVtaXR0ZWRbaGFuZGxlck5hbWVdKSB7DQogICAgICByZXR1cm47DQogICAgfQ0KICAgIGluc3RhbmNlLmVtaXR0ZWRbaGFuZGxlck5hbWVdID0gdHJ1ZTsNCiAgICBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZygNCiAgICAgIG9uY2VIYW5kbGVyLA0KICAgICAgaW5zdGFuY2UsDQogICAgICA2LA0KICAgICAgYXJncw0KICAgICk7DQogIH0NCn0NCmZ1bmN0aW9uIG5vcm1hbGl6ZUVtaXRzT3B0aW9ucyhjb21wLCBhcHBDb250ZXh0LCBhc01peGluID0gZmFsc2UpIHsNCiAgY29uc3QgY2FjaGUgPSBhcHBDb250ZXh0LmVtaXRzQ2FjaGU7DQogIGNvbnN0IGNhY2hlZCA9IGNhY2hlLmdldChjb21wKTsNCiAgaWYgKGNhY2hlZCAhPT0gdm9pZCAwKSB7DQogICAgcmV0dXJuIGNhY2hlZDsNCiAgfQ0KICBjb25zdCByYXcgPSBjb21wLmVtaXRzOw0KICBsZXQgbm9ybWFsaXplZCA9IHt9Ow0KICBsZXQgaGFzRXh0ZW5kcyA9IGZhbHNlOw0KICBpZiAoIWlzRnVuY3Rpb24oY29tcCkpIHsNCiAgICBjb25zdCBleHRlbmRFbWl0cyA9IChyYXcyKSA9PiB7DQogICAgICBjb25zdCBub3JtYWxpemVkRnJvbUV4dGVuZCA9IG5vcm1hbGl6ZUVtaXRzT3B0aW9ucyhyYXcyLCBhcHBDb250ZXh0LCB0cnVlKTsNCiAgICAgIGlmIChub3JtYWxpemVkRnJvbUV4dGVuZCkgew0KICAgICAgICBoYXNFeHRlbmRzID0gdHJ1ZTsNCiAgICAgICAgZXh0ZW5kKG5vcm1hbGl6ZWQsIG5vcm1hbGl6ZWRGcm9tRXh0ZW5kKTsNCiAgICAgIH0NCiAgICB9Ow0KICAgIGlmICghYXNNaXhpbiAmJiBhcHBDb250ZXh0Lm1peGlucy5sZW5ndGgpIHsNCiAgICAgIGFwcENvbnRleHQubWl4aW5zLmZvckVhY2goZXh0ZW5kRW1pdHMpOw0KICAgIH0NCiAgICBpZiAoY29tcC5leHRlbmRzKSB7DQogICAgICBleHRlbmRFbWl0cyhjb21wLmV4dGVuZHMpOw0KICAgIH0NCiAgICBpZiAoY29tcC5taXhpbnMpIHsNCiAgICAgIGNvbXAubWl4aW5zLmZvckVhY2goZXh0ZW5kRW1pdHMpOw0KICAgIH0NCiAgfQ0KICBpZiAoIXJhdyAmJiAhaGFzRXh0ZW5kcykgew0KICAgIGlmIChpc09iamVjdChjb21wKSkgew0KICAgICAgY2FjaGUuc2V0KGNvbXAsIG51bGwpOw0KICAgIH0NCiAgICByZXR1cm4gbnVsbDsNCiAgfQ0KICBpZiAoaXNBcnJheShyYXcpKSB7DQogICAgcmF3LmZvckVhY2goKGtleSkgPT4gbm9ybWFsaXplZFtrZXldID0gbnVsbCk7DQogIH0gZWxzZSB7DQogICAgZXh0ZW5kKG5vcm1hbGl6ZWQsIHJhdyk7DQogIH0NCiAgaWYgKGlzT2JqZWN0KGNvbXApKSB7DQogICAgY2FjaGUuc2V0KGNvbXAsIG5vcm1hbGl6ZWQpOw0KICB9DQogIHJldHVybiBub3JtYWxpemVkOw0KfQ0KZnVuY3Rpb24gaXNFbWl0TGlzdGVuZXIob3B0aW9ucywga2V5KSB7DQogIGlmICghb3B0aW9ucyB8fCAhaXNPbihrZXkpKSB7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9DQogIGtleSA9IGtleS5zbGljZSgyKS5yZXBsYWNlKC9PbmNlJC8sICIiKTsNCiAgcmV0dXJuIGhhc093bihvcHRpb25zLCBrZXlbMF0udG9Mb3dlckNhc2UoKSArIGtleS5zbGljZSgxKSkgfHwgaGFzT3duKG9wdGlvbnMsIGh5cGhlbmF0ZShrZXkpKSB8fCBoYXNPd24ob3B0aW9ucywga2V5KTsNCn0NCg0KbGV0IGFjY2Vzc2VkQXR0cnMgPSBmYWxzZTsNCmZ1bmN0aW9uIG1hcmtBdHRyc0FjY2Vzc2VkKCkgew0KICBhY2Nlc3NlZEF0dHJzID0gdHJ1ZTsNCn0NCmZ1bmN0aW9uIHJlbmRlckNvbXBvbmVudFJvb3QkMShpbnN0YW5jZSkgew0KICBjb25zdCB7DQogICAgdHlwZTogQ29tcG9uZW50LA0KICAgIHZub2RlLA0KICAgIHByb3h5LA0KICAgIHdpdGhQcm94eSwNCiAgICBwcm9wc09wdGlvbnM6IFtwcm9wc09wdGlvbnNdLA0KICAgIHNsb3RzLA0KICAgIGF0dHJzLA0KICAgIGVtaXQsDQogICAgcmVuZGVyLA0KICAgIHJlbmRlckNhY2hlLA0KICAgIHByb3BzLA0KICAgIGRhdGEsDQogICAgc2V0dXBTdGF0ZSwNCiAgICBjdHgsDQogICAgaW5oZXJpdEF0dHJzDQogIH0gPSBpbnN0YW5jZTsNCiAgY29uc3QgcHJldiA9IHNldEN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSQxKGluc3RhbmNlKTsNCiAgbGV0IHJlc3VsdDsNCiAgbGV0IGZhbGx0aHJvdWdoQXR0cnM7DQogIHsNCiAgICBhY2Nlc3NlZEF0dHJzID0gZmFsc2U7DQogIH0NCiAgdHJ5IHsNCiAgICBpZiAodm5vZGUuc2hhcGVGbGFnICYgNCkgew0KICAgICAgY29uc3QgcHJveHlUb1VzZSA9IHdpdGhQcm94eSB8fCBwcm94eTsNCiAgICAgIGNvbnN0IHRoaXNQcm94eSA9IHNldHVwU3RhdGUuX19pc1NjcmlwdFNldHVwID8gbmV3IFByb3h5KHByb3h5VG9Vc2UsIHsNCiAgICAgICAgZ2V0KHRhcmdldCwga2V5LCByZWNlaXZlcikgew0KICAgICAgICAgIHdhcm4kMSgNCiAgICAgICAgICAgIGBQcm9wZXJ0eSAnJHtTdHJpbmcoDQogICAgICAgICAgICAgIGtleQ0KICAgICAgICAgICAgKX0nIHdhcyBhY2Nlc3NlZCB2aWEgJ3RoaXMnLiBBdm9pZCB1c2luZyAndGhpcycgaW4gdGVtcGxhdGVzLmANCiAgICAgICAgICApOw0KICAgICAgICAgIHJldHVybiBSZWZsZWN0LmdldCh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpOw0KICAgICAgICB9DQogICAgICB9KSA6IHByb3h5VG9Vc2U7DQogICAgICByZXN1bHQgPSBub3JtYWxpemVWTm9kZSQxKA0KICAgICAgICByZW5kZXIuY2FsbCgNCiAgICAgICAgICB0aGlzUHJveHksDQogICAgICAgICAgcHJveHlUb1VzZSwNCiAgICAgICAgICByZW5kZXJDYWNoZSwNCiAgICAgICAgICB0cnVlID8gc2hhbGxvd1JlYWRvbmx5KHByb3BzKSA6IHByb3BzLA0KICAgICAgICAgIHNldHVwU3RhdGUsDQogICAgICAgICAgZGF0YSwNCiAgICAgICAgICBjdHgNCiAgICAgICAgKQ0KICAgICAgKTsNCiAgICAgIGZhbGx0aHJvdWdoQXR0cnMgPSBhdHRyczsNCiAgICB9IGVsc2Ugew0KICAgICAgY29uc3QgcmVuZGVyMiA9IENvbXBvbmVudDsNCiAgICAgIGlmIChhdHRycyA9PT0gcHJvcHMpIHsNCiAgICAgICAgbWFya0F0dHJzQWNjZXNzZWQoKTsNCiAgICAgIH0NCiAgICAgIHJlc3VsdCA9IG5vcm1hbGl6ZVZOb2RlJDEoDQogICAgICAgIHJlbmRlcjIubGVuZ3RoID4gMSA/IHJlbmRlcjIoDQogICAgICAgICAgdHJ1ZSA/IHNoYWxsb3dSZWFkb25seShwcm9wcykgOiBwcm9wcywNCiAgICAgICAgICB0cnVlID8gew0KICAgICAgICAgICAgZ2V0IGF0dHJzKCkgew0KICAgICAgICAgICAgICBtYXJrQXR0cnNBY2Nlc3NlZCgpOw0KICAgICAgICAgICAgICByZXR1cm4gc2hhbGxvd1JlYWRvbmx5KGF0dHJzKTsNCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICBzbG90cywNCiAgICAgICAgICAgIGVtaXQNCiAgICAgICAgICB9IDogeyBhdHRycywgc2xvdHMsIGVtaXQgfQ0KICAgICAgICApIDogcmVuZGVyMigNCiAgICAgICAgICB0cnVlID8gc2hhbGxvd1JlYWRvbmx5KHByb3BzKSA6IHByb3BzLA0KICAgICAgICAgIG51bGwNCiAgICAgICAgKQ0KICAgICAgKTsNCiAgICAgIGZhbGx0aHJvdWdoQXR0cnMgPSBDb21wb25lbnQucHJvcHMgPyBhdHRycyA6IGdldEZ1bmN0aW9uYWxGYWxsdGhyb3VnaChhdHRycyk7DQogICAgfQ0KICB9IGNhdGNoIChlcnIpIHsNCiAgICBoYW5kbGVFcnJvcihlcnIsIGluc3RhbmNlLCAxKTsNCiAgICByZXN1bHQgPSBjcmVhdGVWTm9kZShDb21tZW50KTsNCiAgfQ0KICBsZXQgcm9vdCA9IHJlc3VsdDsNCiAgbGV0IHNldFJvb3QgPSB2b2lkIDA7DQogIGlmIChyZXN1bHQucGF0Y2hGbGFnID4gMCAmJiByZXN1bHQucGF0Y2hGbGFnICYgMjA0OCkgew0KICAgIFtyb290LCBzZXRSb290XSA9IGdldENoaWxkUm9vdChyZXN1bHQpOw0KICB9DQogIGlmIChmYWxsdGhyb3VnaEF0dHJzICYmIGluaGVyaXRBdHRycyAhPT0gZmFsc2UpIHsNCiAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoZmFsbHRocm91Z2hBdHRycyk7DQogICAgY29uc3QgeyBzaGFwZUZsYWcgfSA9IHJvb3Q7DQogICAgaWYgKGtleXMubGVuZ3RoKSB7DQogICAgICBpZiAoc2hhcGVGbGFnICYgKDEgfCA2KSkgew0KICAgICAgICBpZiAocHJvcHNPcHRpb25zICYmIGtleXMuc29tZShpc01vZGVsTGlzdGVuZXIpKSB7DQogICAgICAgICAgZmFsbHRocm91Z2hBdHRycyA9IGZpbHRlck1vZGVsTGlzdGVuZXJzKA0KICAgICAgICAgICAgZmFsbHRocm91Z2hBdHRycywNCiAgICAgICAgICAgIHByb3BzT3B0aW9ucw0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgICAgcm9vdCA9IGNsb25lVk5vZGUocm9vdCwgZmFsbHRocm91Z2hBdHRycywgZmFsc2UsIHRydWUpOw0KICAgICAgfSBlbHNlIGlmICghYWNjZXNzZWRBdHRycyAmJiByb290LnR5cGUgIT09IENvbW1lbnQpIHsNCiAgICAgICAgY29uc3QgYWxsQXR0cnMgPSBPYmplY3Qua2V5cyhhdHRycyk7DQogICAgICAgIGNvbnN0IGV2ZW50QXR0cnMgPSBbXTsNCiAgICAgICAgY29uc3QgZXh0cmFBdHRycyA9IFtdOw0KICAgICAgICBmb3IgKGxldCBpID0gMCwgbCA9IGFsbEF0dHJzLmxlbmd0aDsgaSA8IGw7IGkrKykgew0KICAgICAgICAgIGNvbnN0IGtleSA9IGFsbEF0dHJzW2ldOw0KICAgICAgICAgIGlmIChpc09uKGtleSkpIHsNCiAgICAgICAgICAgIGlmICghaXNNb2RlbExpc3RlbmVyKGtleSkpIHsNCiAgICAgICAgICAgICAgZXZlbnRBdHRycy5wdXNoKGtleVsyXS50b0xvd2VyQ2FzZSgpICsga2V5LnNsaWNlKDMpKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgZXh0cmFBdHRycy5wdXNoKGtleSk7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGlmIChleHRyYUF0dHJzLmxlbmd0aCkgew0KICAgICAgICAgIHdhcm4kMSgNCiAgICAgICAgICAgIGBFeHRyYW5lb3VzIG5vbi1wcm9wcyBhdHRyaWJ1dGVzICgke2V4dHJhQXR0cnMuam9pbigiLCAiKX0pIHdlcmUgcGFzc2VkIHRvIGNvbXBvbmVudCBidXQgY291bGQgbm90IGJlIGF1dG9tYXRpY2FsbHkgaW5oZXJpdGVkIGJlY2F1c2UgY29tcG9uZW50IHJlbmRlcnMgZnJhZ21lbnQgb3IgdGV4dCBvciB0ZWxlcG9ydCByb290IG5vZGVzLmANCiAgICAgICAgICApOw0KICAgICAgICB9DQogICAgICAgIGlmIChldmVudEF0dHJzLmxlbmd0aCkgew0KICAgICAgICAgIHdhcm4kMSgNCiAgICAgICAgICAgIGBFeHRyYW5lb3VzIG5vbi1lbWl0cyBldmVudCBsaXN0ZW5lcnMgKCR7ZXZlbnRBdHRycy5qb2luKCIsICIpfSkgd2VyZSBwYXNzZWQgdG8gY29tcG9uZW50IGJ1dCBjb3VsZCBub3QgYmUgYXV0b21hdGljYWxseSBpbmhlcml0ZWQgYmVjYXVzZSBjb21wb25lbnQgcmVuZGVycyBmcmFnbWVudCBvciB0ZXh0IHJvb3Qgbm9kZXMuIElmIHRoZSBsaXN0ZW5lciBpcyBpbnRlbmRlZCB0byBiZSBhIGNvbXBvbmVudCBjdXN0b20gZXZlbnQgbGlzdGVuZXIgb25seSwgZGVjbGFyZSBpdCB1c2luZyB0aGUgImVtaXRzIiBvcHRpb24uYA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH0NCiAgaWYgKHZub2RlLmRpcnMpIHsNCiAgICBpZiAoIWlzRWxlbWVudFJvb3Qocm9vdCkpIHsNCiAgICAgIHdhcm4kMSgNCiAgICAgICAgYFJ1bnRpbWUgZGlyZWN0aXZlIHVzZWQgb24gY29tcG9uZW50IHdpdGggbm9uLWVsZW1lbnQgcm9vdCBub2RlLiBUaGUgZGlyZWN0aXZlcyB3aWxsIG5vdCBmdW5jdGlvbiBhcyBpbnRlbmRlZC5gDQogICAgICApOw0KICAgIH0NCiAgICByb290ID0gY2xvbmVWTm9kZShyb290LCBudWxsLCBmYWxzZSwgdHJ1ZSk7DQogICAgcm9vdC5kaXJzID0gcm9vdC5kaXJzID8gcm9vdC5kaXJzLmNvbmNhdCh2bm9kZS5kaXJzKSA6IHZub2RlLmRpcnM7DQogIH0NCiAgaWYgKHZub2RlLnRyYW5zaXRpb24pIHsNCiAgICBpZiAoIWlzRWxlbWVudFJvb3Qocm9vdCkpIHsNCiAgICAgIHdhcm4kMSgNCiAgICAgICAgYENvbXBvbmVudCBpbnNpZGUgPFRyYW5zaXRpb24+IHJlbmRlcnMgbm9uLWVsZW1lbnQgcm9vdCBub2RlIHRoYXQgY2Fubm90IGJlIGFuaW1hdGVkLmANCiAgICAgICk7DQogICAgfQ0KICAgIHNldFRyYW5zaXRpb25Ib29rcyhyb290LCB2bm9kZS50cmFuc2l0aW9uKTsNCiAgfQ0KICBpZiAoc2V0Um9vdCkgew0KICAgIHNldFJvb3Qocm9vdCk7DQogIH0gZWxzZSB7DQogICAgcmVzdWx0ID0gcm9vdDsNCiAgfQ0KICBzZXRDdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UkMShwcmV2KTsNCiAgcmV0dXJuIHJlc3VsdDsNCn0NCmNvbnN0IGdldENoaWxkUm9vdCA9ICh2bm9kZSkgPT4gew0KICBjb25zdCByYXdDaGlsZHJlbiA9IHZub2RlLmNoaWxkcmVuOw0KICBjb25zdCBkeW5hbWljQ2hpbGRyZW4gPSB2bm9kZS5keW5hbWljQ2hpbGRyZW47DQogIGNvbnN0IGNoaWxkUm9vdCA9IGZpbHRlclNpbmdsZVJvb3QocmF3Q2hpbGRyZW4sIGZhbHNlKTsNCiAgaWYgKCFjaGlsZFJvb3QpIHsNCiAgICByZXR1cm4gW3Zub2RlLCB2b2lkIDBdOw0KICB9IGVsc2UgaWYgKGNoaWxkUm9vdC5wYXRjaEZsYWcgPiAwICYmIGNoaWxkUm9vdC5wYXRjaEZsYWcgJiAyMDQ4KSB7DQogICAgcmV0dXJuIGdldENoaWxkUm9vdChjaGlsZFJvb3QpOw0KICB9DQogIGNvbnN0IGluZGV4ID0gcmF3Q2hpbGRyZW4uaW5kZXhPZihjaGlsZFJvb3QpOw0KICBjb25zdCBkeW5hbWljSW5kZXggPSBkeW5hbWljQ2hpbGRyZW4gPyBkeW5hbWljQ2hpbGRyZW4uaW5kZXhPZihjaGlsZFJvb3QpIDogLTE7DQogIGNvbnN0IHNldFJvb3QgPSAodXBkYXRlZFJvb3QpID0+IHsNCiAgICByYXdDaGlsZHJlbltpbmRleF0gPSB1cGRhdGVkUm9vdDsNCiAgICBpZiAoZHluYW1pY0NoaWxkcmVuKSB7DQogICAgICBpZiAoZHluYW1pY0luZGV4ID4gLTEpIHsNCiAgICAgICAgZHluYW1pY0NoaWxkcmVuW2R5bmFtaWNJbmRleF0gPSB1cGRhdGVkUm9vdDsNCiAgICAgIH0gZWxzZSBpZiAodXBkYXRlZFJvb3QucGF0Y2hGbGFnID4gMCkgew0KICAgICAgICB2bm9kZS5keW5hbWljQ2hpbGRyZW4gPSBbLi4uZHluYW1pY0NoaWxkcmVuLCB1cGRhdGVkUm9vdF07DQogICAgICB9DQogICAgfQ0KICB9Ow0KICByZXR1cm4gW25vcm1hbGl6ZVZOb2RlJDEoY2hpbGRSb290KSwgc2V0Um9vdF07DQp9Ow0KZnVuY3Rpb24gZmlsdGVyU2luZ2xlUm9vdChjaGlsZHJlbiwgcmVjdXJzZSA9IHRydWUpIHsNCiAgbGV0IHNpbmdsZVJvb3Q7DQogIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHsNCiAgICBjb25zdCBjaGlsZCA9IGNoaWxkcmVuW2ldOw0KICAgIGlmIChpc1ZOb2RlJDIoY2hpbGQpKSB7DQogICAgICBpZiAoY2hpbGQudHlwZSAhPT0gQ29tbWVudCB8fCBjaGlsZC5jaGlsZHJlbiA9PT0gInYtaWYiKSB7DQogICAgICAgIGlmIChzaW5nbGVSb290KSB7DQogICAgICAgICAgcmV0dXJuOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIHNpbmdsZVJvb3QgPSBjaGlsZDsNCiAgICAgICAgICBpZiAocmVjdXJzZSAmJiBzaW5nbGVSb290LnBhdGNoRmxhZyA+IDAgJiYgc2luZ2xlUm9vdC5wYXRjaEZsYWcgJiAyMDQ4KSB7DQogICAgICAgICAgICByZXR1cm4gZmlsdGVyU2luZ2xlUm9vdChzaW5nbGVSb290LmNoaWxkcmVuKTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gc2luZ2xlUm9vdDsNCn0NCmNvbnN0IGdldEZ1bmN0aW9uYWxGYWxsdGhyb3VnaCA9IChhdHRycykgPT4gew0KICBsZXQgcmVzOw0KICBmb3IgKGNvbnN0IGtleSBpbiBhdHRycykgew0KICAgIGlmIChrZXkgPT09ICJjbGFzcyIgfHwga2V5ID09PSAic3R5bGUiIHx8IGlzT24oa2V5KSkgew0KICAgICAgKHJlcyB8fCAocmVzID0ge30pKVtrZXldID0gYXR0cnNba2V5XTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIHJlczsNCn07DQpjb25zdCBmaWx0ZXJNb2RlbExpc3RlbmVycyA9IChhdHRycywgcHJvcHMpID0+IHsNCiAgY29uc3QgcmVzID0ge307DQogIGZvciAoY29uc3Qga2V5IGluIGF0dHJzKSB7DQogICAgaWYgKCFpc01vZGVsTGlzdGVuZXIoa2V5KSB8fCAhKGtleS5zbGljZSg5KSBpbiBwcm9wcykpIHsNCiAgICAgIHJlc1trZXldID0gYXR0cnNba2V5XTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIHJlczsNCn07DQpjb25zdCBpc0VsZW1lbnRSb290ID0gKHZub2RlKSA9PiB7DQogIHJldHVybiB2bm9kZS5zaGFwZUZsYWcgJiAoNiB8IDEpIHx8IHZub2RlLnR5cGUgPT09IENvbW1lbnQ7DQp9Ow0KZnVuY3Rpb24gc2hvdWxkVXBkYXRlQ29tcG9uZW50KHByZXZWTm9kZSwgbmV4dFZOb2RlLCBvcHRpbWl6ZWQpIHsNCiAgY29uc3QgeyBwcm9wczogcHJldlByb3BzLCBjaGlsZHJlbjogcHJldkNoaWxkcmVuLCBjb21wb25lbnQgfSA9IHByZXZWTm9kZTsNCiAgY29uc3QgeyBwcm9wczogbmV4dFByb3BzLCBjaGlsZHJlbjogbmV4dENoaWxkcmVuLCBwYXRjaEZsYWcgfSA9IG5leHRWTm9kZTsNCiAgY29uc3QgZW1pdHMgPSBjb21wb25lbnQuZW1pdHNPcHRpb25zOw0KICBpZiAoKHByZXZDaGlsZHJlbiB8fCBuZXh0Q2hpbGRyZW4pICYmIGlzSG1yVXBkYXRpbmcpIHsNCiAgICByZXR1cm4gdHJ1ZTsNCiAgfQ0KICBpZiAobmV4dFZOb2RlLmRpcnMgfHwgbmV4dFZOb2RlLnRyYW5zaXRpb24pIHsNCiAgICByZXR1cm4gdHJ1ZTsNCiAgfQ0KICBpZiAob3B0aW1pemVkICYmIHBhdGNoRmxhZyA+PSAwKSB7DQogICAgaWYgKHBhdGNoRmxhZyAmIDEwMjQpIHsNCiAgICAgIHJldHVybiB0cnVlOw0KICAgIH0NCiAgICBpZiAocGF0Y2hGbGFnICYgMTYpIHsNCiAgICAgIGlmICghcHJldlByb3BzKSB7DQogICAgICAgIHJldHVybiAhIW5leHRQcm9wczsNCiAgICAgIH0NCiAgICAgIHJldHVybiBoYXNQcm9wc0NoYW5nZWQocHJldlByb3BzLCBuZXh0UHJvcHMsIGVtaXRzKTsNCiAgICB9IGVsc2UgaWYgKHBhdGNoRmxhZyAmIDgpIHsNCiAgICAgIGNvbnN0IGR5bmFtaWNQcm9wcyA9IG5leHRWTm9kZS5keW5hbWljUHJvcHM7DQogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGR5bmFtaWNQcm9wcy5sZW5ndGg7IGkrKykgew0KICAgICAgICBjb25zdCBrZXkgPSBkeW5hbWljUHJvcHNbaV07DQogICAgICAgIGlmIChuZXh0UHJvcHNba2V5XSAhPT0gcHJldlByb3BzW2tleV0gJiYgIWlzRW1pdExpc3RlbmVyKGVtaXRzLCBrZXkpKSB7DQogICAgICAgICAgcmV0dXJuIHRydWU7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH0gZWxzZSB7DQogICAgaWYgKHByZXZDaGlsZHJlbiB8fCBuZXh0Q2hpbGRyZW4pIHsNCiAgICAgIGlmICghbmV4dENoaWxkcmVuIHx8ICFuZXh0Q2hpbGRyZW4uJHN0YWJsZSkgew0KICAgICAgICByZXR1cm4gdHJ1ZTsNCiAgICAgIH0NCiAgICB9DQogICAgaWYgKHByZXZQcm9wcyA9PT0gbmV4dFByb3BzKSB7DQogICAgICByZXR1cm4gZmFsc2U7DQogICAgfQ0KICAgIGlmICghcHJldlByb3BzKSB7DQogICAgICByZXR1cm4gISFuZXh0UHJvcHM7DQogICAgfQ0KICAgIGlmICghbmV4dFByb3BzKSB7DQogICAgICByZXR1cm4gdHJ1ZTsNCiAgICB9DQogICAgcmV0dXJuIGhhc1Byb3BzQ2hhbmdlZChwcmV2UHJvcHMsIG5leHRQcm9wcywgZW1pdHMpOw0KICB9DQogIHJldHVybiBmYWxzZTsNCn0NCmZ1bmN0aW9uIGhhc1Byb3BzQ2hhbmdlZChwcmV2UHJvcHMsIG5leHRQcm9wcywgZW1pdHNPcHRpb25zKSB7DQogIGNvbnN0IG5leHRLZXlzID0gT2JqZWN0LmtleXMobmV4dFByb3BzKTsNCiAgaWYgKG5leHRLZXlzLmxlbmd0aCAhPT0gT2JqZWN0LmtleXMocHJldlByb3BzKS5sZW5ndGgpIHsNCiAgICByZXR1cm4gdHJ1ZTsNCiAgfQ0KICBmb3IgKGxldCBpID0gMDsgaSA8IG5leHRLZXlzLmxlbmd0aDsgaSsrKSB7DQogICAgY29uc3Qga2V5ID0gbmV4dEtleXNbaV07DQogICAgaWYgKG5leHRQcm9wc1trZXldICE9PSBwcmV2UHJvcHNba2V5XSAmJiAhaXNFbWl0TGlzdGVuZXIoZW1pdHNPcHRpb25zLCBrZXkpKSB7DQogICAgICByZXR1cm4gdHJ1ZTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIGZhbHNlOw0KfQ0KZnVuY3Rpb24gdXBkYXRlSE9DSG9zdEVsKHsgdm5vZGUsIHBhcmVudCB9LCBlbCkgew0KICB3aGlsZSAocGFyZW50KSB7DQogICAgY29uc3Qgcm9vdCA9IHBhcmVudC5zdWJUcmVlOw0KICAgIGlmIChyb290LnN1c3BlbnNlICYmIHJvb3Quc3VzcGVuc2UuYWN0aXZlQnJhbmNoID09PSB2bm9kZSkgew0KICAgICAgcm9vdC5lbCA9IHZub2RlLmVsOw0KICAgIH0NCiAgICBpZiAocm9vdCA9PT0gdm5vZGUpIHsNCiAgICAgICh2bm9kZSA9IHBhcmVudC52bm9kZSkuZWwgPSBlbDsNCiAgICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnQ7DQogICAgfSBlbHNlIHsNCiAgICAgIGJyZWFrOw0KICAgIH0NCiAgfQ0KfQ0KDQpjb25zdCBpc1N1c3BlbnNlID0gKHR5cGUpID0+IHR5cGUuX19pc1N1c3BlbnNlOw0KZnVuY3Rpb24gcXVldWVFZmZlY3RXaXRoU3VzcGVuc2UoZm4sIHN1c3BlbnNlKSB7DQogIGlmIChzdXNwZW5zZSAmJiBzdXNwZW5zZS5wZW5kaW5nQnJhbmNoKSB7DQogICAgaWYgKGlzQXJyYXkoZm4pKSB7DQogICAgICBzdXNwZW5zZS5lZmZlY3RzLnB1c2goLi4uZm4pOw0KICAgIH0gZWxzZSB7DQogICAgICBzdXNwZW5zZS5lZmZlY3RzLnB1c2goZm4pOw0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICBxdWV1ZVBvc3RGbHVzaENiKGZuKTsNCiAgfQ0KfQ0KDQpjb25zdCBGcmFnbWVudCA9IFN5bWJvbC5mb3IoInYtZmd0Iik7DQpjb25zdCBUZXh0ID0gU3ltYm9sLmZvcigidi10eHQiKTsNCmNvbnN0IENvbW1lbnQgPSBTeW1ib2wuZm9yKCJ2LWNtdCIpOw0KY29uc3QgU3RhdGljID0gU3ltYm9sLmZvcigidi1zdGMiKTsNCmxldCBjdXJyZW50QmxvY2sgPSBudWxsOw0KbGV0IGlzQmxvY2tUcmVlRW5hYmxlZCA9IDE7DQpmdW5jdGlvbiBzZXRCbG9ja1RyYWNraW5nKHZhbHVlLCBpblZPbmNlID0gZmFsc2UpIHsNCiAgaXNCbG9ja1RyZWVFbmFibGVkICs9IHZhbHVlOw0KICBpZiAodmFsdWUgPCAwICYmIGN1cnJlbnRCbG9jayAmJiBpblZPbmNlKSB7DQogICAgY3VycmVudEJsb2NrLmhhc09uY2UgPSB0cnVlOw0KICB9DQp9DQpmdW5jdGlvbiBpc1ZOb2RlJDIodmFsdWUpIHsNCiAgcmV0dXJuIHZhbHVlID8gdmFsdWUuX192X2lzVk5vZGUgPT09IHRydWUgOiBmYWxzZTsNCn0NCmZ1bmN0aW9uIGlzU2FtZVZOb2RlVHlwZShuMSwgbjIpIHsNCiAgaWYgKG4yLnNoYXBlRmxhZyAmIDYgJiYgbjEuY29tcG9uZW50KSB7DQogICAgY29uc3QgZGlydHlJbnN0YW5jZXMgPSBobXJEaXJ0eUNvbXBvbmVudHMuZ2V0KG4yLnR5cGUpOw0KICAgIGlmIChkaXJ0eUluc3RhbmNlcyAmJiBkaXJ0eUluc3RhbmNlcy5oYXMobjEuY29tcG9uZW50KSkgew0KICAgICAgbjEuc2hhcGVGbGFnICY9IC0yNTc7DQogICAgICBuMi5zaGFwZUZsYWcgJj0gLTUxMzsNCiAgICAgIHJldHVybiBmYWxzZTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIG4xLnR5cGUgPT09IG4yLnR5cGUgJiYgbjEua2V5ID09PSBuMi5rZXk7DQp9DQpjb25zdCBjcmVhdGVWTm9kZVdpdGhBcmdzVHJhbnNmb3JtID0gKC4uLmFyZ3MpID0+IHsNCiAgcmV0dXJuIF9jcmVhdGVWTm9kZSgNCiAgICAuLi5hcmdzDQogICk7DQp9Ow0KY29uc3Qgbm9ybWFsaXplS2V5ID0gKHsga2V5IH0pID0+IGtleSAhPSBudWxsID8ga2V5IDogbnVsbDsNCmNvbnN0IG5vcm1hbGl6ZVJlZiA9ICh7DQogIHJlZiwNCiAgcmVmX2tleSwNCiAgcmVmX2Zvcg0KfSkgPT4gew0KICBpZiAodHlwZW9mIHJlZiA9PT0gIm51bWJlciIpIHsNCiAgICByZWYgPSAiIiArIHJlZjsNCiAgfQ0KICByZXR1cm4gcmVmICE9IG51bGwgPyBpc1N0cmluZyhyZWYpIHx8IGlzUmVmKHJlZikgfHwgaXNGdW5jdGlvbihyZWYpID8geyBpOiBjdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UsIHI6IHJlZiwgazogcmVmX2tleSwgZjogISFyZWZfZm9yIH0gOiByZWYgOiBudWxsOw0KfTsNCmZ1bmN0aW9uIGNyZWF0ZUJhc2VWTm9kZSh0eXBlLCBwcm9wcyA9IG51bGwsIGNoaWxkcmVuID0gbnVsbCwgcGF0Y2hGbGFnID0gMCwgZHluYW1pY1Byb3BzID0gbnVsbCwgc2hhcGVGbGFnID0gdHlwZSA9PT0gRnJhZ21lbnQgPyAwIDogMSwgaXNCbG9ja05vZGUgPSBmYWxzZSwgbmVlZEZ1bGxDaGlsZHJlbk5vcm1hbGl6YXRpb24gPSBmYWxzZSkgew0KICBjb25zdCB2bm9kZSA9IHsNCiAgICBfX3ZfaXNWTm9kZTogdHJ1ZSwNCiAgICBfX3Zfc2tpcDogdHJ1ZSwNCiAgICB0eXBlLA0KICAgIHByb3BzLA0KICAgIGtleTogcHJvcHMgJiYgbm9ybWFsaXplS2V5KHByb3BzKSwNCiAgICByZWY6IHByb3BzICYmIG5vcm1hbGl6ZVJlZihwcm9wcyksDQogICAgc2NvcGVJZDogY3VycmVudFNjb3BlSWQsDQogICAgc2xvdFNjb3BlSWRzOiBudWxsLA0KICAgIGNoaWxkcmVuLA0KICAgIGNvbXBvbmVudDogbnVsbCwNCiAgICBzdXNwZW5zZTogbnVsbCwNCiAgICBzc0NvbnRlbnQ6IG51bGwsDQogICAgc3NGYWxsYmFjazogbnVsbCwNCiAgICBkaXJzOiBudWxsLA0KICAgIHRyYW5zaXRpb246IG51bGwsDQogICAgZWw6IG51bGwsDQogICAgYW5jaG9yOiBudWxsLA0KICAgIHRhcmdldDogbnVsbCwNCiAgICB0YXJnZXRTdGFydDogbnVsbCwNCiAgICB0YXJnZXRBbmNob3I6IG51bGwsDQogICAgc3RhdGljQ291bnQ6IDAsDQogICAgc2hhcGVGbGFnLA0KICAgIHBhdGNoRmxhZywNCiAgICBkeW5hbWljUHJvcHMsDQogICAgZHluYW1pY0NoaWxkcmVuOiBudWxsLA0KICAgIGFwcENvbnRleHQ6IG51bGwsDQogICAgY3R4OiBjdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UNCiAgfTsNCiAgaWYgKG5lZWRGdWxsQ2hpbGRyZW5Ob3JtYWxpemF0aW9uKSB7DQogICAgbm9ybWFsaXplQ2hpbGRyZW4odm5vZGUsIGNoaWxkcmVuKTsNCiAgICBpZiAoc2hhcGVGbGFnICYgMTI4KSB7DQogICAgICB0eXBlLm5vcm1hbGl6ZSh2bm9kZSk7DQogICAgfQ0KICB9IGVsc2UgaWYgKGNoaWxkcmVuKSB7DQogICAgdm5vZGUuc2hhcGVGbGFnIHw9IGlzU3RyaW5nKGNoaWxkcmVuKSA/IDggOiAxNjsNCiAgfQ0KICBpZiAodm5vZGUua2V5ICE9PSB2bm9kZS5rZXkpIHsNCiAgICB3YXJuJDEoYFZOb2RlIGNyZWF0ZWQgd2l0aCBpbnZhbGlkIGtleSAoTmFOKS4gVk5vZGUgdHlwZTpgLCB2bm9kZS50eXBlKTsNCiAgfQ0KICBpZiAoaXNCbG9ja1RyZWVFbmFibGVkID4gMCAmJiAvLyBhdm9pZCBhIGJsb2NrIG5vZGUgZnJvbSB0cmFja2luZyBpdHNlbGYNCiAgIWlzQmxvY2tOb2RlICYmIC8vIGhhcyBjdXJyZW50IHBhcmVudCBibG9jaw0KICBjdXJyZW50QmxvY2sgJiYgLy8gcHJlc2VuY2Ugb2YgYSBwYXRjaCBmbGFnIGluZGljYXRlcyB0aGlzIG5vZGUgbmVlZHMgcGF0Y2hpbmcgb24gdXBkYXRlcy4NCiAgLy8gY29tcG9uZW50IG5vZGVzIGFsc28gc2hvdWxkIGFsd2F5cyBiZSBwYXRjaGVkLCBiZWNhdXNlIGV2ZW4gaWYgdGhlDQogIC8vIGNvbXBvbmVudCBkb2Vzbid0IG5lZWQgdG8gdXBkYXRlLCBpdCBuZWVkcyB0byBwZXJzaXN0IHRoZSBpbnN0YW5jZSBvbiB0bw0KICAvLyB0aGUgbmV4dCB2bm9kZSBzbyB0aGF0IGl0IGNhbiBiZSBwcm9wZXJseSB1bm1vdW50ZWQgbGF0ZXIuDQogICh2bm9kZS5wYXRjaEZsYWcgPiAwIHx8IHNoYXBlRmxhZyAmIDYpICYmIC8vIHRoZSBFVkVOVFMgZmxhZyBpcyBvbmx5IGZvciBoeWRyYXRpb24gYW5kIGlmIGl0IGlzIHRoZSBvbmx5IGZsYWcsIHRoZQ0KICAvLyB2bm9kZSBzaG91bGQgbm90IGJlIGNvbnNpZGVyZWQgZHluYW1pYyBkdWUgdG8gaGFuZGxlciBjYWNoaW5nLg0KICB2bm9kZS5wYXRjaEZsYWcgIT09IDMyKSB7DQogICAgY3VycmVudEJsb2NrLnB1c2godm5vZGUpOw0KICB9DQogIHJldHVybiB2bm9kZTsNCn0NCmNvbnN0IGNyZWF0ZVZOb2RlID0gY3JlYXRlVk5vZGVXaXRoQXJnc1RyYW5zZm9ybSA7DQpmdW5jdGlvbiBfY3JlYXRlVk5vZGUodHlwZSwgcHJvcHMgPSBudWxsLCBjaGlsZHJlbiA9IG51bGwsIHBhdGNoRmxhZyA9IDAsIGR5bmFtaWNQcm9wcyA9IG51bGwsIGlzQmxvY2tOb2RlID0gZmFsc2UpIHsNCiAgaWYgKCF0eXBlIHx8IHR5cGUgPT09IE5VTExfRFlOQU1JQ19DT01QT05FTlQpIHsNCiAgICBpZiAoIXR5cGUpIHsNCiAgICAgIHdhcm4kMShgSW52YWxpZCB2bm9kZSB0eXBlIHdoZW4gY3JlYXRpbmcgdm5vZGU6ICR7dHlwZX0uYCk7DQogICAgfQ0KICAgIHR5cGUgPSBDb21tZW50Ow0KICB9DQogIGlmIChpc1ZOb2RlJDIodHlwZSkpIHsNCiAgICBjb25zdCBjbG9uZWQgPSBjbG9uZVZOb2RlKA0KICAgICAgdHlwZSwNCiAgICAgIHByb3BzLA0KICAgICAgdHJ1ZQ0KICAgICAgLyogbWVyZ2VSZWY6IHRydWUgKi8NCiAgICApOw0KICAgIGlmIChjaGlsZHJlbikgew0KICAgICAgbm9ybWFsaXplQ2hpbGRyZW4oY2xvbmVkLCBjaGlsZHJlbik7DQogICAgfQ0KICAgIGlmIChpc0Jsb2NrVHJlZUVuYWJsZWQgPiAwICYmICFpc0Jsb2NrTm9kZSAmJiBjdXJyZW50QmxvY2spIHsNCiAgICAgIGlmIChjbG9uZWQuc2hhcGVGbGFnICYgNikgew0KICAgICAgICBjdXJyZW50QmxvY2tbY3VycmVudEJsb2NrLmluZGV4T2YodHlwZSldID0gY2xvbmVkOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgY3VycmVudEJsb2NrLnB1c2goY2xvbmVkKTsNCiAgICAgIH0NCiAgICB9DQogICAgY2xvbmVkLnBhdGNoRmxhZyA9IC0yOw0KICAgIHJldHVybiBjbG9uZWQ7DQogIH0NCiAgaWYgKGlzQ2xhc3NDb21wb25lbnQodHlwZSkpIHsNCiAgICB0eXBlID0gdHlwZS5fX3ZjY09wdHM7DQogIH0NCiAgaWYgKHByb3BzKSB7DQogICAgcHJvcHMgPSBndWFyZFJlYWN0aXZlUHJvcHMocHJvcHMpOw0KICAgIGxldCB7IGNsYXNzOiBrbGFzcywgc3R5bGUgfSA9IHByb3BzOw0KICAgIGlmIChrbGFzcyAmJiAhaXNTdHJpbmcoa2xhc3MpKSB7DQogICAgICBwcm9wcy5jbGFzcyA9IG5vcm1hbGl6ZUNsYXNzKGtsYXNzKTsNCiAgICB9DQogICAgaWYgKGlzT2JqZWN0KHN0eWxlKSkgew0KICAgICAgaWYgKGlzUHJveHkoc3R5bGUpICYmICFpc0FycmF5KHN0eWxlKSkgew0KICAgICAgICBzdHlsZSA9IGV4dGVuZCh7fSwgc3R5bGUpOw0KICAgICAgfQ0KICAgICAgcHJvcHMuc3R5bGUgPSBub3JtYWxpemVTdHlsZShzdHlsZSk7DQogICAgfQ0KICB9DQogIGNvbnN0IHNoYXBlRmxhZyA9IGlzU3RyaW5nKHR5cGUpID8gMSA6IGlzU3VzcGVuc2UodHlwZSkgPyAxMjggOiBpc1RlbGVwb3J0KHR5cGUpID8gNjQgOiBpc09iamVjdCh0eXBlKSA/IDQgOiBpc0Z1bmN0aW9uKHR5cGUpID8gMiA6IDA7DQogIGlmIChzaGFwZUZsYWcgJiA0ICYmIGlzUHJveHkodHlwZSkpIHsNCiAgICB0eXBlID0gdG9SYXcodHlwZSk7DQogICAgd2FybiQxKA0KICAgICAgYFZ1ZSByZWNlaXZlZCBhIENvbXBvbmVudCB0aGF0IHdhcyBtYWRlIGEgcmVhY3RpdmUgb2JqZWN0LiBUaGlzIGNhbiBsZWFkIHRvIHVubmVjZXNzYXJ5IHBlcmZvcm1hbmNlIG92ZXJoZWFkIGFuZCBzaG91bGQgYmUgYXZvaWRlZCBieSBtYXJraW5nIHRoZSBjb21wb25lbnQgd2l0aCBcYG1hcmtSYXdcYCBvciB1c2luZyBcYHNoYWxsb3dSZWZcYCBpbnN0ZWFkIG9mIFxgcmVmXGAuYCwNCiAgICAgIGANCkNvbXBvbmVudCB0aGF0IHdhcyBtYWRlIHJlYWN0aXZlOiBgLA0KICAgICAgdHlwZQ0KICAgICk7DQogIH0NCiAgcmV0dXJuIGNyZWF0ZUJhc2VWTm9kZSgNCiAgICB0eXBlLA0KICAgIHByb3BzLA0KICAgIGNoaWxkcmVuLA0KICAgIHBhdGNoRmxhZywNCiAgICBkeW5hbWljUHJvcHMsDQogICAgc2hhcGVGbGFnLA0KICAgIGlzQmxvY2tOb2RlLA0KICAgIHRydWUNCiAgKTsNCn0NCmZ1bmN0aW9uIGd1YXJkUmVhY3RpdmVQcm9wcyhwcm9wcykgew0KICBpZiAoIXByb3BzKSByZXR1cm4gbnVsbDsNCiAgcmV0dXJuIGlzUHJveHkocHJvcHMpIHx8IGlzSW50ZXJuYWxPYmplY3QocHJvcHMpID8gZXh0ZW5kKHt9LCBwcm9wcykgOiBwcm9wczsNCn0NCmZ1bmN0aW9uIGNsb25lVk5vZGUodm5vZGUsIGV4dHJhUHJvcHMsIG1lcmdlUmVmID0gZmFsc2UsIGNsb25lVHJhbnNpdGlvbiA9IGZhbHNlKSB7DQogIGNvbnN0IHsgcHJvcHMsIHJlZiwgcGF0Y2hGbGFnLCBjaGlsZHJlbiwgdHJhbnNpdGlvbiB9ID0gdm5vZGU7DQogIGNvbnN0IG1lcmdlZFByb3BzID0gZXh0cmFQcm9wcyA/IG1lcmdlUHJvcHMocHJvcHMgfHwge30sIGV4dHJhUHJvcHMpIDogcHJvcHM7DQogIGNvbnN0IGNsb25lZCA9IHsNCiAgICBfX3ZfaXNWTm9kZTogdHJ1ZSwNCiAgICBfX3Zfc2tpcDogdHJ1ZSwNCiAgICB0eXBlOiB2bm9kZS50eXBlLA0KICAgIHByb3BzOiBtZXJnZWRQcm9wcywNCiAgICBrZXk6IG1lcmdlZFByb3BzICYmIG5vcm1hbGl6ZUtleShtZXJnZWRQcm9wcyksDQogICAgcmVmOiBleHRyYVByb3BzICYmIGV4dHJhUHJvcHMucmVmID8gKA0KICAgICAgLy8gIzIwNzggaW4gdGhlIGNhc2Ugb2YgPGNvbXBvbmVudCA6aXM9InZub2RlIiByZWY9ImV4dHJhIi8+DQogICAgICAvLyBpZiB0aGUgdm5vZGUgaXRzZWxmIGFscmVhZHkgaGFzIGEgcmVmLCBjbG9uZVZOb2RlIHdpbGwgbmVlZCB0byBtZXJnZQ0KICAgICAgLy8gdGhlIHJlZnMgc28gdGhlIHNpbmdsZSB2bm9kZSBjYW4gYmUgc2V0IG9uIG11bHRpcGxlIHJlZnMNCiAgICAgIG1lcmdlUmVmICYmIHJlZiA/IGlzQXJyYXkocmVmKSA/IHJlZi5jb25jYXQobm9ybWFsaXplUmVmKGV4dHJhUHJvcHMpKSA6IFtyZWYsIG5vcm1hbGl6ZVJlZihleHRyYVByb3BzKV0gOiBub3JtYWxpemVSZWYoZXh0cmFQcm9wcykNCiAgICApIDogcmVmLA0KICAgIHNjb3BlSWQ6IHZub2RlLnNjb3BlSWQsDQogICAgc2xvdFNjb3BlSWRzOiB2bm9kZS5zbG90U2NvcGVJZHMsDQogICAgY2hpbGRyZW46IHBhdGNoRmxhZyA9PT0gLTEgJiYgaXNBcnJheShjaGlsZHJlbikgPyBjaGlsZHJlbi5tYXAoZGVlcENsb25lVk5vZGUpIDogY2hpbGRyZW4sDQogICAgdGFyZ2V0OiB2bm9kZS50YXJnZXQsDQogICAgdGFyZ2V0U3RhcnQ6IHZub2RlLnRhcmdldFN0YXJ0LA0KICAgIHRhcmdldEFuY2hvcjogdm5vZGUudGFyZ2V0QW5jaG9yLA0KICAgIHN0YXRpY0NvdW50OiB2bm9kZS5zdGF0aWNDb3VudCwNCiAgICBzaGFwZUZsYWc6IHZub2RlLnNoYXBlRmxhZywNCiAgICAvLyBpZiB0aGUgdm5vZGUgaXMgY2xvbmVkIHdpdGggZXh0cmEgcHJvcHMsIHdlIGNhbiBubyBsb25nZXIgYXNzdW1lIGl0cw0KICAgIC8vIGV4aXN0aW5nIHBhdGNoIGZsYWcgdG8gYmUgcmVsaWFibGUgYW5kIG5lZWQgdG8gYWRkIHRoZSBGVUxMX1BST1BTIGZsYWcuDQogICAgLy8gbm90ZTogcHJlc2VydmUgZmxhZyBmb3IgZnJhZ21lbnRzIHNpbmNlIHRoZXkgdXNlIHRoZSBmbGFnIGZvciBjaGlsZHJlbg0KICAgIC8vIGZhc3QgcGF0aHMgb25seS4NCiAgICBwYXRjaEZsYWc6IGV4dHJhUHJvcHMgJiYgdm5vZGUudHlwZSAhPT0gRnJhZ21lbnQgPyBwYXRjaEZsYWcgPT09IC0xID8gMTYgOiBwYXRjaEZsYWcgfCAxNiA6IHBhdGNoRmxhZywNCiAgICBkeW5hbWljUHJvcHM6IHZub2RlLmR5bmFtaWNQcm9wcywNCiAgICBkeW5hbWljQ2hpbGRyZW46IHZub2RlLmR5bmFtaWNDaGlsZHJlbiwNCiAgICBhcHBDb250ZXh0OiB2bm9kZS5hcHBDb250ZXh0LA0KICAgIGRpcnM6IHZub2RlLmRpcnMsDQogICAgdHJhbnNpdGlvbiwNCiAgICAvLyBUaGVzZSBzaG91bGQgdGVjaG5pY2FsbHkgb25seSBiZSBub24tbnVsbCBvbiBtb3VudGVkIFZOb2Rlcy4gSG93ZXZlciwNCiAgICAvLyB0aGV5ICpzaG91bGQqIGJlIGNvcGllZCBmb3Iga2VwdC1hbGl2ZSB2bm9kZXMuIFNvIHdlIGp1c3QgYWx3YXlzIGNvcHkNCiAgICAvLyB0aGVtIHNpbmNlIHRoZW0gYmVpbmcgbm9uLW51bGwgZHVyaW5nIGEgbW91bnQgZG9lc24ndCBhZmZlY3QgdGhlIGxvZ2ljIGFzDQogICAgLy8gdGhleSB3aWxsIHNpbXBseSBiZSBvdmVyd3JpdHRlbi4NCiAgICBjb21wb25lbnQ6IHZub2RlLmNvbXBvbmVudCwNCiAgICBzdXNwZW5zZTogdm5vZGUuc3VzcGVuc2UsDQogICAgc3NDb250ZW50OiB2bm9kZS5zc0NvbnRlbnQgJiYgY2xvbmVWTm9kZSh2bm9kZS5zc0NvbnRlbnQpLA0KICAgIHNzRmFsbGJhY2s6IHZub2RlLnNzRmFsbGJhY2sgJiYgY2xvbmVWTm9kZSh2bm9kZS5zc0ZhbGxiYWNrKSwNCiAgICBlbDogdm5vZGUuZWwsDQogICAgYW5jaG9yOiB2bm9kZS5hbmNob3IsDQogICAgY3R4OiB2bm9kZS5jdHgsDQogICAgY2U6IHZub2RlLmNlDQogIH07DQogIGlmICh0cmFuc2l0aW9uICYmIGNsb25lVHJhbnNpdGlvbikgew0KICAgIHNldFRyYW5zaXRpb25Ib29rcygNCiAgICAgIGNsb25lZCwNCiAgICAgIHRyYW5zaXRpb24uY2xvbmUoY2xvbmVkKQ0KICAgICk7DQogIH0NCiAgcmV0dXJuIGNsb25lZDsNCn0NCmZ1bmN0aW9uIGRlZXBDbG9uZVZOb2RlKHZub2RlKSB7DQogIGNvbnN0IGNsb25lZCA9IGNsb25lVk5vZGUodm5vZGUpOw0KICBpZiAoaXNBcnJheSh2bm9kZS5jaGlsZHJlbikpIHsNCiAgICBjbG9uZWQuY2hpbGRyZW4gPSB2bm9kZS5jaGlsZHJlbi5tYXAoZGVlcENsb25lVk5vZGUpOw0KICB9DQogIHJldHVybiBjbG9uZWQ7DQp9DQpmdW5jdGlvbiBjcmVhdGVUZXh0Vk5vZGUodGV4dCA9ICIgIiwgZmxhZyA9IDApIHsNCiAgcmV0dXJuIGNyZWF0ZVZOb2RlKFRleHQsIG51bGwsIHRleHQsIGZsYWcpOw0KfQ0KZnVuY3Rpb24gbm9ybWFsaXplVk5vZGUkMShjaGlsZCkgew0KICBpZiAoY2hpbGQgPT0gbnVsbCB8fCB0eXBlb2YgY2hpbGQgPT09ICJib29sZWFuIikgew0KICAgIHJldHVybiBjcmVhdGVWTm9kZShDb21tZW50KTsNCiAgfSBlbHNlIGlmIChpc0FycmF5KGNoaWxkKSkgew0KICAgIHJldHVybiBjcmVhdGVWTm9kZSgNCiAgICAgIEZyYWdtZW50LA0KICAgICAgbnVsbCwNCiAgICAgIC8vICMzNjY2LCBhdm9pZCByZWZlcmVuY2UgcG9sbHV0aW9uIHdoZW4gcmV1c2luZyB2bm9kZQ0KICAgICAgY2hpbGQuc2xpY2UoKQ0KICAgICk7DQogIH0gZWxzZSBpZiAoaXNWTm9kZSQyKGNoaWxkKSkgew0KICAgIHJldHVybiBjbG9uZUlmTW91bnRlZChjaGlsZCk7DQogIH0gZWxzZSB7DQogICAgcmV0dXJuIGNyZWF0ZVZOb2RlKFRleHQsIG51bGwsIFN0cmluZyhjaGlsZCkpOw0KICB9DQp9DQpmdW5jdGlvbiBjbG9uZUlmTW91bnRlZChjaGlsZCkgew0KICByZXR1cm4gY2hpbGQuZWwgPT09IG51bGwgJiYgY2hpbGQucGF0Y2hGbGFnICE9PSAtMSB8fCBjaGlsZC5tZW1vID8gY2hpbGQgOiBjbG9uZVZOb2RlKGNoaWxkKTsNCn0NCmZ1bmN0aW9uIG5vcm1hbGl6ZUNoaWxkcmVuKHZub2RlLCBjaGlsZHJlbikgew0KICBsZXQgdHlwZSA9IDA7DQogIGNvbnN0IHsgc2hhcGVGbGFnIH0gPSB2bm9kZTsNCiAgaWYgKGNoaWxkcmVuID09IG51bGwpIHsNCiAgICBjaGlsZHJlbiA9IG51bGw7DQogIH0gZWxzZSBpZiAoaXNBcnJheShjaGlsZHJlbikpIHsNCiAgICB0eXBlID0gMTY7DQogIH0gZWxzZSBpZiAodHlwZW9mIGNoaWxkcmVuID09PSAib2JqZWN0Iikgew0KICAgIGlmIChzaGFwZUZsYWcgJiAoMSB8IDY0KSkgew0KICAgICAgY29uc3Qgc2xvdCA9IGNoaWxkcmVuLmRlZmF1bHQ7DQogICAgICBpZiAoc2xvdCkgew0KICAgICAgICBzbG90Ll9jICYmIChzbG90Ll9kID0gZmFsc2UpOw0KICAgICAgICBub3JtYWxpemVDaGlsZHJlbih2bm9kZSwgc2xvdCgpKTsNCiAgICAgICAgc2xvdC5fYyAmJiAoc2xvdC5fZCA9IHRydWUpOw0KICAgICAgfQ0KICAgICAgcmV0dXJuOw0KICAgIH0gZWxzZSB7DQogICAgICB0eXBlID0gMzI7DQogICAgICBjb25zdCBzbG90RmxhZyA9IGNoaWxkcmVuLl87DQogICAgICBpZiAoIXNsb3RGbGFnICYmICFpc0ludGVybmFsT2JqZWN0KGNoaWxkcmVuKSkgew0KICAgICAgICBjaGlsZHJlbi5fY3R4ID0gY3VycmVudFJlbmRlcmluZ0luc3RhbmNlOw0KICAgICAgfSBlbHNlIGlmIChzbG90RmxhZyA9PT0gMyAmJiBjdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UpIHsNCiAgICAgICAgaWYgKGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZS5zbG90cy5fID09PSAxKSB7DQogICAgICAgICAgY2hpbGRyZW4uXyA9IDE7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgY2hpbGRyZW4uXyA9IDI7DQogICAgICAgICAgdm5vZGUucGF0Y2hGbGFnIHw9IDEwMjQ7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH0gZWxzZSBpZiAoaXNGdW5jdGlvbihjaGlsZHJlbikpIHsNCiAgICBjaGlsZHJlbiA9IHsgZGVmYXVsdDogY2hpbGRyZW4sIF9jdHg6IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSB9Ow0KICAgIHR5cGUgPSAzMjsNCiAgfSBlbHNlIHsNCiAgICBjaGlsZHJlbiA9IFN0cmluZyhjaGlsZHJlbik7DQogICAgaWYgKHNoYXBlRmxhZyAmIDY0KSB7DQogICAgICB0eXBlID0gMTY7DQogICAgICBjaGlsZHJlbiA9IFtjcmVhdGVUZXh0Vk5vZGUoY2hpbGRyZW4pXTsNCiAgICB9IGVsc2Ugew0KICAgICAgdHlwZSA9IDg7DQogICAgfQ0KICB9DQogIHZub2RlLmNoaWxkcmVuID0gY2hpbGRyZW47DQogIHZub2RlLnNoYXBlRmxhZyB8PSB0eXBlOw0KfQ0KZnVuY3Rpb24gbWVyZ2VQcm9wcyguLi5hcmdzKSB7DQogIGNvbnN0IHJldCA9IHt9Ow0KICBmb3IgKGxldCBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHsNCiAgICBjb25zdCB0b01lcmdlID0gYXJnc1tpXTsNCiAgICBmb3IgKGNvbnN0IGtleSBpbiB0b01lcmdlKSB7DQogICAgICBpZiAoa2V5ID09PSAiY2xhc3MiKSB7DQogICAgICAgIGlmIChyZXQuY2xhc3MgIT09IHRvTWVyZ2UuY2xhc3MpIHsNCiAgICAgICAgICByZXQuY2xhc3MgPSBub3JtYWxpemVDbGFzcyhbcmV0LmNsYXNzLCB0b01lcmdlLmNsYXNzXSk7DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSBpZiAoa2V5ID09PSAic3R5bGUiKSB7DQogICAgICAgIHJldC5zdHlsZSA9IG5vcm1hbGl6ZVN0eWxlKFtyZXQuc3R5bGUsIHRvTWVyZ2Uuc3R5bGVdKTsNCiAgICAgIH0gZWxzZSBpZiAoaXNPbihrZXkpKSB7DQogICAgICAgIGNvbnN0IGV4aXN0aW5nID0gcmV0W2tleV07DQogICAgICAgIGNvbnN0IGluY29taW5nID0gdG9NZXJnZVtrZXldOw0KICAgICAgICBpZiAoaW5jb21pbmcgJiYgZXhpc3RpbmcgIT09IGluY29taW5nICYmICEoaXNBcnJheShleGlzdGluZykgJiYgZXhpc3RpbmcuaW5jbHVkZXMoaW5jb21pbmcpKSkgew0KICAgICAgICAgIHJldFtrZXldID0gZXhpc3RpbmcgPyBbXS5jb25jYXQoZXhpc3RpbmcsIGluY29taW5nKSA6IGluY29taW5nOw0KICAgICAgICB9DQogICAgICB9IGVsc2UgaWYgKGtleSAhPT0gIiIpIHsNCiAgICAgICAgcmV0W2tleV0gPSB0b01lcmdlW2tleV07DQogICAgICB9DQogICAgfQ0KICB9DQogIHJldHVybiByZXQ7DQp9DQpmdW5jdGlvbiBpbnZva2VWTm9kZUhvb2soaG9vaywgaW5zdGFuY2UsIHZub2RlLCBwcmV2Vk5vZGUgPSBudWxsKSB7DQogIGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nKGhvb2ssIGluc3RhbmNlLCA3LCBbDQogICAgdm5vZGUsDQogICAgcHJldlZOb2RlDQogIF0pOw0KfQ0KDQpjb25zdCBlbXB0eUFwcENvbnRleHQgPSBjcmVhdGVBcHBDb250ZXh0KCk7DQpsZXQgdWlkID0gMDsNCmZ1bmN0aW9uIGNyZWF0ZUNvbXBvbmVudEluc3RhbmNlJDEodm5vZGUsIHBhcmVudCwgc3VzcGVuc2UpIHsNCiAgY29uc3QgdHlwZSA9IHZub2RlLnR5cGU7DQogIGNvbnN0IGFwcENvbnRleHQgPSAocGFyZW50ID8gcGFyZW50LmFwcENvbnRleHQgOiB2bm9kZS5hcHBDb250ZXh0KSB8fCBlbXB0eUFwcENvbnRleHQ7DQogIGNvbnN0IGluc3RhbmNlID0gew0KICAgIHVpZDogdWlkKyssDQogICAgdm5vZGUsDQogICAgdHlwZSwNCiAgICBwYXJlbnQsDQogICAgYXBwQ29udGV4dCwNCiAgICByb290OiBudWxsLA0KICAgIC8vIHRvIGJlIGltbWVkaWF0ZWx5IHNldA0KICAgIG5leHQ6IG51bGwsDQogICAgc3ViVHJlZTogbnVsbCwNCiAgICAvLyB3aWxsIGJlIHNldCBzeW5jaHJvbm91c2x5IHJpZ2h0IGFmdGVyIGNyZWF0aW9uDQogICAgZWZmZWN0OiBudWxsLA0KICAgIHVwZGF0ZTogbnVsbCwNCiAgICAvLyB3aWxsIGJlIHNldCBzeW5jaHJvbm91c2x5IHJpZ2h0IGFmdGVyIGNyZWF0aW9uDQogICAgam9iOiBudWxsLA0KICAgIHNjb3BlOiBuZXcgRWZmZWN0U2NvcGUoDQogICAgICB0cnVlDQogICAgICAvKiBkZXRhY2hlZCAqLw0KICAgICksDQogICAgcmVuZGVyOiBudWxsLA0KICAgIHByb3h5OiBudWxsLA0KICAgIGV4cG9zZWQ6IG51bGwsDQogICAgZXhwb3NlUHJveHk6IG51bGwsDQogICAgd2l0aFByb3h5OiBudWxsLA0KICAgIHByb3ZpZGVzOiBwYXJlbnQgPyBwYXJlbnQucHJvdmlkZXMgOiBPYmplY3QuY3JlYXRlKGFwcENvbnRleHQucHJvdmlkZXMpLA0KICAgIGlkczogcGFyZW50ID8gcGFyZW50LmlkcyA6IFsiIiwgMCwgMF0sDQogICAgYWNjZXNzQ2FjaGU6IG51bGwsDQogICAgcmVuZGVyQ2FjaGU6IFtdLA0KICAgIC8vIGxvY2FsIHJlc29sdmVkIGFzc2V0cw0KICAgIGNvbXBvbmVudHM6IG51bGwsDQogICAgZGlyZWN0aXZlczogbnVsbCwNCiAgICAvLyByZXNvbHZlZCBwcm9wcyBhbmQgZW1pdHMgb3B0aW9ucw0KICAgIHByb3BzT3B0aW9uczogbm9ybWFsaXplUHJvcHNPcHRpb25zKHR5cGUsIGFwcENvbnRleHQpLA0KICAgIGVtaXRzT3B0aW9uczogbm9ybWFsaXplRW1pdHNPcHRpb25zKHR5cGUsIGFwcENvbnRleHQpLA0KICAgIC8vIGVtaXQNCiAgICBlbWl0OiBudWxsLA0KICAgIC8vIHRvIGJlIHNldCBpbW1lZGlhdGVseQ0KICAgIGVtaXR0ZWQ6IG51bGwsDQogICAgLy8gcHJvcHMgZGVmYXVsdCB2YWx1ZQ0KICAgIHByb3BzRGVmYXVsdHM6IEVNUFRZX09CSiwNCiAgICAvLyBpbmhlcml0QXR0cnMNCiAgICBpbmhlcml0QXR0cnM6IHR5cGUuaW5oZXJpdEF0dHJzLA0KICAgIC8vIHN0YXRlDQogICAgY3R4OiBFTVBUWV9PQkosDQogICAgZGF0YTogRU1QVFlfT0JKLA0KICAgIHByb3BzOiBFTVBUWV9PQkosDQogICAgYXR0cnM6IEVNUFRZX09CSiwNCiAgICBzbG90czogRU1QVFlfT0JKLA0KICAgIHJlZnM6IEVNUFRZX09CSiwNCiAgICBzZXR1cFN0YXRlOiBFTVBUWV9PQkosDQogICAgc2V0dXBDb250ZXh0OiBudWxsLA0KICAgIC8vIHN1c3BlbnNlIHJlbGF0ZWQNCiAgICBzdXNwZW5zZSwNCiAgICBzdXNwZW5zZUlkOiBzdXNwZW5zZSA/IHN1c3BlbnNlLnBlbmRpbmdJZCA6IDAsDQogICAgYXN5bmNEZXA6IG51bGwsDQogICAgYXN5bmNSZXNvbHZlZDogZmFsc2UsDQogICAgLy8gbGlmZWN5Y2xlIGhvb2tzDQogICAgLy8gbm90IHVzaW5nIGVudW1zIGhlcmUgYmVjYXVzZSBpdCByZXN1bHRzIGluIGNvbXB1dGVkIHByb3BlcnRpZXMNCiAgICBpc01vdW50ZWQ6IGZhbHNlLA0KICAgIGlzVW5tb3VudGVkOiBmYWxzZSwNCiAgICBpc0RlYWN0aXZhdGVkOiBmYWxzZSwNCiAgICBiYzogbnVsbCwNCiAgICBjOiBudWxsLA0KICAgIGJtOiBudWxsLA0KICAgIG06IG51bGwsDQogICAgYnU6IG51bGwsDQogICAgdTogbnVsbCwNCiAgICB1bTogbnVsbCwNCiAgICBidW06IG51bGwsDQogICAgZGE6IG51bGwsDQogICAgYTogbnVsbCwNCiAgICBydGc6IG51bGwsDQogICAgcnRjOiBudWxsLA0KICAgIGVjOiBudWxsLA0KICAgIHNwOiBudWxsDQogIH07DQogIHsNCiAgICBpbnN0YW5jZS5jdHggPSBjcmVhdGVEZXZSZW5kZXJDb250ZXh0KGluc3RhbmNlKTsNCiAgfQ0KICBpbnN0YW5jZS5yb290ID0gcGFyZW50ID8gcGFyZW50LnJvb3QgOiBpbnN0YW5jZTsNCiAgaW5zdGFuY2UuZW1pdCA9IGVtaXQuYmluZChudWxsLCBpbnN0YW5jZSk7DQogIGlmICh2bm9kZS5jZSkgew0KICAgIHZub2RlLmNlKGluc3RhbmNlKTsNCiAgfQ0KICByZXR1cm4gaW5zdGFuY2U7DQp9DQpsZXQgY3VycmVudEluc3RhbmNlID0gbnVsbDsNCmNvbnN0IGdldEN1cnJlbnRJbnN0YW5jZSA9ICgpID0+IGN1cnJlbnRJbnN0YW5jZSB8fCBjdXJyZW50UmVuZGVyaW5nSW5zdGFuY2U7DQpsZXQgaW50ZXJuYWxTZXRDdXJyZW50SW5zdGFuY2U7DQpsZXQgc2V0SW5TU1JTZXR1cFN0YXRlOw0Kew0KICBjb25zdCBnID0gZ2V0R2xvYmFsVGhpcygpOw0KICBjb25zdCByZWdpc3Rlckdsb2JhbFNldHRlciA9IChrZXksIHNldHRlcikgPT4gew0KICAgIGxldCBzZXR0ZXJzOw0KICAgIGlmICghKHNldHRlcnMgPSBnW2tleV0pKSBzZXR0ZXJzID0gZ1trZXldID0gW107DQogICAgc2V0dGVycy5wdXNoKHNldHRlcik7DQogICAgcmV0dXJuICh2KSA9PiB7DQogICAgICBpZiAoc2V0dGVycy5sZW5ndGggPiAxKSBzZXR0ZXJzLmZvckVhY2goKHNldCkgPT4gc2V0KHYpKTsNCiAgICAgIGVsc2Ugc2V0dGVyc1swXSh2KTsNCiAgICB9Ow0KICB9Ow0KICBpbnRlcm5hbFNldEN1cnJlbnRJbnN0YW5jZSA9IHJlZ2lzdGVyR2xvYmFsU2V0dGVyKA0KICAgIGBfX1ZVRV9JTlNUQU5DRV9TRVRURVJTX19gLA0KICAgICh2KSA9PiBjdXJyZW50SW5zdGFuY2UgPSB2DQogICk7DQogIHNldEluU1NSU2V0dXBTdGF0ZSA9IHJlZ2lzdGVyR2xvYmFsU2V0dGVyKA0KICAgIGBfX1ZVRV9TU1JfU0VUVEVSU19fYCwNCiAgICAodikgPT4gaXNJblNTUkNvbXBvbmVudFNldHVwID0gdg0KICApOw0KfQ0KY29uc3Qgc2V0Q3VycmVudEluc3RhbmNlID0gKGluc3RhbmNlKSA9PiB7DQogIGNvbnN0IHByZXYgPSBjdXJyZW50SW5zdGFuY2U7DQogIGludGVybmFsU2V0Q3VycmVudEluc3RhbmNlKGluc3RhbmNlKTsNCiAgaW5zdGFuY2Uuc2NvcGUub24oKTsNCiAgcmV0dXJuICgpID0+IHsNCiAgICBpbnN0YW5jZS5zY29wZS5vZmYoKTsNCiAgICBpbnRlcm5hbFNldEN1cnJlbnRJbnN0YW5jZShwcmV2KTsNCiAgfTsNCn07DQpjb25zdCB1bnNldEN1cnJlbnRJbnN0YW5jZSA9ICgpID0+IHsNCiAgY3VycmVudEluc3RhbmNlICYmIGN1cnJlbnRJbnN0YW5jZS5zY29wZS5vZmYoKTsNCiAgaW50ZXJuYWxTZXRDdXJyZW50SW5zdGFuY2UobnVsbCk7DQp9Ow0KY29uc3QgaXNCdWlsdEluVGFnID0gLyogQF9fUFVSRV9fICovIG1ha2VNYXAoInNsb3QsY29tcG9uZW50Iik7DQpmdW5jdGlvbiB2YWxpZGF0ZUNvbXBvbmVudE5hbWUobmFtZSwgeyBpc05hdGl2ZVRhZyB9KSB7DQogIGlmIChpc0J1aWx0SW5UYWcobmFtZSkgfHwgaXNOYXRpdmVUYWcobmFtZSkpIHsNCiAgICB3YXJuJDEoDQogICAgICAiRG8gbm90IHVzZSBidWlsdC1pbiBvciByZXNlcnZlZCBIVE1MIGVsZW1lbnRzIGFzIGNvbXBvbmVudCBpZDogIiArIG5hbWUNCiAgICApOw0KICB9DQp9DQpmdW5jdGlvbiBpc1N0YXRlZnVsQ29tcG9uZW50KGluc3RhbmNlKSB7DQogIHJldHVybiBpbnN0YW5jZS52bm9kZS5zaGFwZUZsYWcgJiA0Ow0KfQ0KbGV0IGlzSW5TU1JDb21wb25lbnRTZXR1cCA9IGZhbHNlOw0KZnVuY3Rpb24gc2V0dXBDb21wb25lbnQkMShpbnN0YW5jZSwgaXNTU1IgPSBmYWxzZSwgb3B0aW1pemVkID0gZmFsc2UpIHsNCiAgaXNTU1IgJiYgc2V0SW5TU1JTZXR1cFN0YXRlKGlzU1NSKTsNCiAgY29uc3QgeyBwcm9wcywgY2hpbGRyZW4gfSA9IGluc3RhbmNlLnZub2RlOw0KICBjb25zdCBpc1N0YXRlZnVsID0gaXNTdGF0ZWZ1bENvbXBvbmVudChpbnN0YW5jZSk7DQogIGluaXRQcm9wcyhpbnN0YW5jZSwgcHJvcHMsIGlzU3RhdGVmdWwsIGlzU1NSKTsNCiAgaW5pdFNsb3RzKGluc3RhbmNlLCBjaGlsZHJlbiwgb3B0aW1pemVkIHx8IGlzU1NSKTsNCiAgY29uc3Qgc2V0dXBSZXN1bHQgPSBpc1N0YXRlZnVsID8gc2V0dXBTdGF0ZWZ1bENvbXBvbmVudChpbnN0YW5jZSwgaXNTU1IpIDogdm9pZCAwOw0KICBpc1NTUiAmJiBzZXRJblNTUlNldHVwU3RhdGUoZmFsc2UpOw0KICByZXR1cm4gc2V0dXBSZXN1bHQ7DQp9DQpmdW5jdGlvbiBzZXR1cFN0YXRlZnVsQ29tcG9uZW50KGluc3RhbmNlLCBpc1NTUikgew0KICB2YXIgX2E7DQogIGNvbnN0IENvbXBvbmVudCA9IGluc3RhbmNlLnR5cGU7DQogIHsNCiAgICBpZiAoQ29tcG9uZW50Lm5hbWUpIHsNCiAgICAgIHZhbGlkYXRlQ29tcG9uZW50TmFtZShDb21wb25lbnQubmFtZSwgaW5zdGFuY2UuYXBwQ29udGV4dC5jb25maWcpOw0KICAgIH0NCiAgICBpZiAoQ29tcG9uZW50LmNvbXBvbmVudHMpIHsNCiAgICAgIGNvbnN0IG5hbWVzID0gT2JqZWN0LmtleXMoQ29tcG9uZW50LmNvbXBvbmVudHMpOw0KICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuYW1lcy5sZW5ndGg7IGkrKykgew0KICAgICAgICB2YWxpZGF0ZUNvbXBvbmVudE5hbWUobmFtZXNbaV0sIGluc3RhbmNlLmFwcENvbnRleHQuY29uZmlnKTsNCiAgICAgIH0NCiAgICB9DQogICAgaWYgKENvbXBvbmVudC5kaXJlY3RpdmVzKSB7DQogICAgICBjb25zdCBuYW1lcyA9IE9iamVjdC5rZXlzKENvbXBvbmVudC5kaXJlY3RpdmVzKTsNCiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbmFtZXMubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgdmFsaWRhdGVEaXJlY3RpdmVOYW1lKG5hbWVzW2ldKTsNCiAgICAgIH0NCiAgICB9DQogICAgaWYgKENvbXBvbmVudC5jb21waWxlck9wdGlvbnMgJiYgaXNSdW50aW1lT25seSgpKSB7DQogICAgICB3YXJuJDEoDQogICAgICAgIGAiY29tcGlsZXJPcHRpb25zIiBpcyBvbmx5IHN1cHBvcnRlZCB3aGVuIHVzaW5nIGEgYnVpbGQgb2YgVnVlIHRoYXQgaW5jbHVkZXMgdGhlIHJ1bnRpbWUgY29tcGlsZXIuIFNpbmNlIHlvdSBhcmUgdXNpbmcgYSBydW50aW1lLW9ubHkgYnVpbGQsIHRoZSBvcHRpb25zIHNob3VsZCBiZSBwYXNzZWQgdmlhIHlvdXIgYnVpbGQgdG9vbCBjb25maWcgaW5zdGVhZC5gDQogICAgICApOw0KICAgIH0NCiAgfQ0KICBpbnN0YW5jZS5hY2Nlc3NDYWNoZSA9IC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuY3JlYXRlKG51bGwpOw0KICBpbnN0YW5jZS5wcm94eSA9IG5ldyBQcm94eShpbnN0YW5jZS5jdHgsIFB1YmxpY0luc3RhbmNlUHJveHlIYW5kbGVycyk7DQogIHsNCiAgICBleHBvc2VQcm9wc09uUmVuZGVyQ29udGV4dChpbnN0YW5jZSk7DQogIH0NCiAgY29uc3QgeyBzZXR1cCB9ID0gQ29tcG9uZW50Ow0KICBpZiAoc2V0dXApIHsNCiAgICBwYXVzZVRyYWNraW5nKCk7DQogICAgY29uc3Qgc2V0dXBDb250ZXh0ID0gaW5zdGFuY2Uuc2V0dXBDb250ZXh0ID0gc2V0dXAubGVuZ3RoID4gMSA/IGNyZWF0ZVNldHVwQ29udGV4dChpbnN0YW5jZSkgOiBudWxsOw0KICAgIGNvbnN0IHJlc2V0ID0gc2V0Q3VycmVudEluc3RhbmNlKGluc3RhbmNlKTsNCiAgICBjb25zdCBzZXR1cFJlc3VsdCA9IGNhbGxXaXRoRXJyb3JIYW5kbGluZygNCiAgICAgIHNldHVwLA0KICAgICAgaW5zdGFuY2UsDQogICAgICAwLA0KICAgICAgWw0KICAgICAgICBzaGFsbG93UmVhZG9ubHkoaW5zdGFuY2UucHJvcHMpICwNCiAgICAgICAgc2V0dXBDb250ZXh0DQogICAgICBdDQogICAgKTsNCiAgICBjb25zdCBpc0FzeW5jU2V0dXAgPSBpc1Byb21pc2Uoc2V0dXBSZXN1bHQpOw0KICAgIHJlc2V0VHJhY2tpbmcoKTsNCiAgICByZXNldCgpOw0KICAgIGlmICgoaXNBc3luY1NldHVwIHx8IGluc3RhbmNlLnNwKSAmJiAhaXNBc3luY1dyYXBwZXIoaW5zdGFuY2UpKSB7DQogICAgICBtYXJrQXN5bmNCb3VuZGFyeShpbnN0YW5jZSk7DQogICAgfQ0KICAgIGlmIChpc0FzeW5jU2V0dXApIHsNCiAgICAgIHNldHVwUmVzdWx0LnRoZW4odW5zZXRDdXJyZW50SW5zdGFuY2UsIHVuc2V0Q3VycmVudEluc3RhbmNlKTsNCiAgICAgIGlmIChpc1NTUikgew0KICAgICAgICByZXR1cm4gc2V0dXBSZXN1bHQudGhlbigocmVzb2x2ZWRSZXN1bHQpID0+IHsNCiAgICAgICAgICBoYW5kbGVTZXR1cFJlc3VsdChpbnN0YW5jZSwgcmVzb2x2ZWRSZXN1bHQsIGlzU1NSKTsNCiAgICAgICAgfSkuY2F0Y2goKGUpID0+IHsNCiAgICAgICAgICBoYW5kbGVFcnJvcihlLCBpbnN0YW5jZSwgMCk7DQogICAgICAgIH0pOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgaW5zdGFuY2UuYXN5bmNEZXAgPSBzZXR1cFJlc3VsdDsNCiAgICAgICAgaWYgKCFpbnN0YW5jZS5zdXNwZW5zZSkgew0KICAgICAgICAgIGNvbnN0IG5hbWUgPSAoX2EgPSBDb21wb25lbnQubmFtZSkgIT0gbnVsbCA/IF9hIDogIkFub255bW91cyI7DQogICAgICAgICAgd2FybiQxKA0KICAgICAgICAgICAgYENvbXBvbmVudCA8JHtuYW1lfT46IHNldHVwIGZ1bmN0aW9uIHJldHVybmVkIGEgcHJvbWlzZSwgYnV0IG5vIDxTdXNwZW5zZT4gYm91bmRhcnkgd2FzIGZvdW5kIGluIHRoZSBwYXJlbnQgY29tcG9uZW50IHRyZWUuIEEgY29tcG9uZW50IHdpdGggYXN5bmMgc2V0dXAoKSBtdXN0IGJlIG5lc3RlZCBpbiBhIDxTdXNwZW5zZT4gaW4gb3JkZXIgdG8gYmUgcmVuZGVyZWQuYA0KICAgICAgICAgICk7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgaGFuZGxlU2V0dXBSZXN1bHQoaW5zdGFuY2UsIHNldHVwUmVzdWx0LCBpc1NTUik7DQogICAgfQ0KICB9IGVsc2Ugew0KICAgIGZpbmlzaENvbXBvbmVudFNldHVwKGluc3RhbmNlLCBpc1NTUik7DQogIH0NCn0NCmZ1bmN0aW9uIGhhbmRsZVNldHVwUmVzdWx0KGluc3RhbmNlLCBzZXR1cFJlc3VsdCwgaXNTU1IpIHsNCiAgaWYgKGlzRnVuY3Rpb24oc2V0dXBSZXN1bHQpKSB7DQogICAgaWYgKGluc3RhbmNlLnR5cGUuX19zc3JJbmxpbmVSZW5kZXIpIHsNCiAgICAgIGluc3RhbmNlLnNzclJlbmRlciA9IHNldHVwUmVzdWx0Ow0KICAgIH0gZWxzZSB7DQogICAgICBpbnN0YW5jZS5yZW5kZXIgPSBzZXR1cFJlc3VsdDsNCiAgICB9DQogIH0gZWxzZSBpZiAoaXNPYmplY3Qoc2V0dXBSZXN1bHQpKSB7DQogICAgaWYgKGlzVk5vZGUkMihzZXR1cFJlc3VsdCkpIHsNCiAgICAgIHdhcm4kMSgNCiAgICAgICAgYHNldHVwKCkgc2hvdWxkIG5vdCByZXR1cm4gVk5vZGVzIGRpcmVjdGx5IC0gcmV0dXJuIGEgcmVuZGVyIGZ1bmN0aW9uIGluc3RlYWQuYA0KICAgICAgKTsNCiAgICB9DQogICAgew0KICAgICAgaW5zdGFuY2UuZGV2dG9vbHNSYXdTZXR1cFN0YXRlID0gc2V0dXBSZXN1bHQ7DQogICAgfQ0KICAgIGluc3RhbmNlLnNldHVwU3RhdGUgPSBwcm94eVJlZnMoc2V0dXBSZXN1bHQpOw0KICAgIHsNCiAgICAgIGV4cG9zZVNldHVwU3RhdGVPblJlbmRlckNvbnRleHQoaW5zdGFuY2UpOw0KICAgIH0NCiAgfSBlbHNlIGlmIChzZXR1cFJlc3VsdCAhPT0gdm9pZCAwKSB7DQogICAgd2FybiQxKA0KICAgICAgYHNldHVwKCkgc2hvdWxkIHJldHVybiBhbiBvYmplY3QuIFJlY2VpdmVkOiAke3NldHVwUmVzdWx0ID09PSBudWxsID8gIm51bGwiIDogdHlwZW9mIHNldHVwUmVzdWx0fWANCiAgICApOw0KICB9DQogIGZpbmlzaENvbXBvbmVudFNldHVwKGluc3RhbmNlLCBpc1NTUik7DQp9DQpjb25zdCBpc1J1bnRpbWVPbmx5ID0gKCkgPT4gdHJ1ZTsNCmZ1bmN0aW9uIGZpbmlzaENvbXBvbmVudFNldHVwKGluc3RhbmNlLCBpc1NTUiwgc2tpcE9wdGlvbnMpIHsNCiAgY29uc3QgQ29tcG9uZW50ID0gaW5zdGFuY2UudHlwZTsNCiAgaWYgKCFpbnN0YW5jZS5yZW5kZXIpIHsNCiAgICBpbnN0YW5jZS5yZW5kZXIgPSBDb21wb25lbnQucmVuZGVyIHx8IE5PT1A7DQogIH0NCiAgew0KICAgIGNvbnN0IHJlc2V0ID0gc2V0Q3VycmVudEluc3RhbmNlKGluc3RhbmNlKTsNCiAgICBwYXVzZVRyYWNraW5nKCk7DQogICAgdHJ5IHsNCiAgICAgIGFwcGx5T3B0aW9ucyhpbnN0YW5jZSk7DQogICAgfSBmaW5hbGx5IHsNCiAgICAgIHJlc2V0VHJhY2tpbmcoKTsNCiAgICAgIHJlc2V0KCk7DQogICAgfQ0KICB9DQogIGlmICghQ29tcG9uZW50LnJlbmRlciAmJiBpbnN0YW5jZS5yZW5kZXIgPT09IE5PT1AgJiYgIWlzU1NSKSB7DQogICAgaWYgKENvbXBvbmVudC50ZW1wbGF0ZSkgew0KICAgICAgd2FybiQxKA0KICAgICAgICBgQ29tcG9uZW50IHByb3ZpZGVkIHRlbXBsYXRlIG9wdGlvbiBidXQgcnVudGltZSBjb21waWxhdGlvbiBpcyBub3Qgc3VwcG9ydGVkIGluIHRoaXMgYnVpbGQgb2YgVnVlLmAgKyAoYCBVc2UgInZ1ZS5lc20tYnJvd3Nlci5qcyIgaW5zdGVhZC5gICkNCiAgICAgICk7DQogICAgfSBlbHNlIHsNCiAgICAgIHdhcm4kMShgQ29tcG9uZW50IGlzIG1pc3NpbmcgdGVtcGxhdGUgb3IgcmVuZGVyIGZ1bmN0aW9uOiBgLCBDb21wb25lbnQpOw0KICAgIH0NCiAgfQ0KfQ0KY29uc3QgYXR0cnNQcm94eUhhbmRsZXJzID0gew0KICBnZXQodGFyZ2V0LCBrZXkpIHsNCiAgICBtYXJrQXR0cnNBY2Nlc3NlZCgpOw0KICAgIHRyYWNrKHRhcmdldCwgImdldCIsICIiKTsNCiAgICByZXR1cm4gdGFyZ2V0W2tleV07DQogIH0sDQogIHNldCgpIHsNCiAgICB3YXJuJDEoYHNldHVwQ29udGV4dC5hdHRycyBpcyByZWFkb25seS5gKTsNCiAgICByZXR1cm4gZmFsc2U7DQogIH0sDQogIGRlbGV0ZVByb3BlcnR5KCkgew0KICAgIHdhcm4kMShgc2V0dXBDb250ZXh0LmF0dHJzIGlzIHJlYWRvbmx5LmApOw0KICAgIHJldHVybiBmYWxzZTsNCiAgfQ0KfSA7DQpmdW5jdGlvbiBnZXRTbG90c1Byb3h5KGluc3RhbmNlKSB7DQogIHJldHVybiBuZXcgUHJveHkoaW5zdGFuY2Uuc2xvdHMsIHsNCiAgICBnZXQodGFyZ2V0LCBrZXkpIHsNCiAgICAgIHRyYWNrKGluc3RhbmNlLCAiZ2V0IiwgIiRzbG90cyIpOw0KICAgICAgcmV0dXJuIHRhcmdldFtrZXldOw0KICAgIH0NCiAgfSk7DQp9DQpmdW5jdGlvbiBjcmVhdGVTZXR1cENvbnRleHQoaW5zdGFuY2UpIHsNCiAgY29uc3QgZXhwb3NlID0gKGV4cG9zZWQpID0+IHsNCiAgICB7DQogICAgICBpZiAoaW5zdGFuY2UuZXhwb3NlZCkgew0KICAgICAgICB3YXJuJDEoYGV4cG9zZSgpIHNob3VsZCBiZSBjYWxsZWQgb25seSBvbmNlIHBlciBzZXR1cCgpLmApOw0KICAgICAgfQ0KICAgICAgaWYgKGV4cG9zZWQgIT0gbnVsbCkgew0KICAgICAgICBsZXQgZXhwb3NlZFR5cGUgPSB0eXBlb2YgZXhwb3NlZDsNCiAgICAgICAgaWYgKGV4cG9zZWRUeXBlID09PSAib2JqZWN0Iikgew0KICAgICAgICAgIGlmIChpc0FycmF5KGV4cG9zZWQpKSB7DQogICAgICAgICAgICBleHBvc2VkVHlwZSA9ICJhcnJheSI7DQogICAgICAgICAgfSBlbHNlIGlmIChpc1JlZihleHBvc2VkKSkgew0KICAgICAgICAgICAgZXhwb3NlZFR5cGUgPSAicmVmIjsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgaWYgKGV4cG9zZWRUeXBlICE9PSAib2JqZWN0Iikgew0KICAgICAgICAgIHdhcm4kMSgNCiAgICAgICAgICAgIGBleHBvc2UoKSBzaG91bGQgYmUgcGFzc2VkIGEgcGxhaW4gb2JqZWN0LCByZWNlaXZlZCAke2V4cG9zZWRUeXBlfS5gDQogICAgICAgICAgKTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgICBpbnN0YW5jZS5leHBvc2VkID0gZXhwb3NlZCB8fCB7fTsNCiAgfTsNCiAgew0KICAgIGxldCBhdHRyc1Byb3h5Ow0KICAgIGxldCBzbG90c1Byb3h5Ow0KICAgIHJldHVybiBPYmplY3QuZnJlZXplKHsNCiAgICAgIGdldCBhdHRycygpIHsNCiAgICAgICAgcmV0dXJuIGF0dHJzUHJveHkgfHwgKGF0dHJzUHJveHkgPSBuZXcgUHJveHkoaW5zdGFuY2UuYXR0cnMsIGF0dHJzUHJveHlIYW5kbGVycykpOw0KICAgICAgfSwNCiAgICAgIGdldCBzbG90cygpIHsNCiAgICAgICAgcmV0dXJuIHNsb3RzUHJveHkgfHwgKHNsb3RzUHJveHkgPSBnZXRTbG90c1Byb3h5KGluc3RhbmNlKSk7DQogICAgICB9LA0KICAgICAgZ2V0IGVtaXQoKSB7DQogICAgICAgIHJldHVybiAoZXZlbnQsIC4uLmFyZ3MpID0+IGluc3RhbmNlLmVtaXQoZXZlbnQsIC4uLmFyZ3MpOw0KICAgICAgfSwNCiAgICAgIGV4cG9zZQ0KICAgIH0pOw0KICB9DQp9DQpmdW5jdGlvbiBnZXRDb21wb25lbnRQdWJsaWNJbnN0YW5jZShpbnN0YW5jZSkgew0KICBpZiAoaW5zdGFuY2UuZXhwb3NlZCkgew0KICAgIHJldHVybiBpbnN0YW5jZS5leHBvc2VQcm94eSB8fCAoaW5zdGFuY2UuZXhwb3NlUHJveHkgPSBuZXcgUHJveHkocHJveHlSZWZzKG1hcmtSYXcoaW5zdGFuY2UuZXhwb3NlZCkpLCB7DQogICAgICBnZXQodGFyZ2V0LCBrZXkpIHsNCiAgICAgICAgaWYgKGtleSBpbiB0YXJnZXQpIHsNCiAgICAgICAgICByZXR1cm4gdGFyZ2V0W2tleV07DQogICAgICAgIH0gZWxzZSBpZiAoa2V5IGluIHB1YmxpY1Byb3BlcnRpZXNNYXApIHsNCiAgICAgICAgICByZXR1cm4gcHVibGljUHJvcGVydGllc01hcFtrZXldKGluc3RhbmNlKTsNCiAgICAgICAgfQ0KICAgICAgfSwNCiAgICAgIGhhcyh0YXJnZXQsIGtleSkgew0KICAgICAgICByZXR1cm4ga2V5IGluIHRhcmdldCB8fCBrZXkgaW4gcHVibGljUHJvcGVydGllc01hcDsNCiAgICAgIH0NCiAgICB9KSk7DQogIH0gZWxzZSB7DQogICAgcmV0dXJuIGluc3RhbmNlLnByb3h5Ow0KICB9DQp9DQpjb25zdCBjbGFzc2lmeVJFID0gLyg/Ol58Wy1fXSkoXHcpL2c7DQpjb25zdCBjbGFzc2lmeSA9IChzdHIpID0+IHN0ci5yZXBsYWNlKGNsYXNzaWZ5UkUsIChjKSA9PiBjLnRvVXBwZXJDYXNlKCkpLnJlcGxhY2UoL1stX10vZywgIiIpOw0KZnVuY3Rpb24gZ2V0Q29tcG9uZW50TmFtZShDb21wb25lbnQsIGluY2x1ZGVJbmZlcnJlZCA9IHRydWUpIHsNCiAgcmV0dXJuIGlzRnVuY3Rpb24oQ29tcG9uZW50KSA/IENvbXBvbmVudC5kaXNwbGF5TmFtZSB8fCBDb21wb25lbnQubmFtZSA6IENvbXBvbmVudC5uYW1lIHx8IGluY2x1ZGVJbmZlcnJlZCAmJiBDb21wb25lbnQuX19uYW1lOw0KfQ0KZnVuY3Rpb24gZm9ybWF0Q29tcG9uZW50TmFtZShpbnN0YW5jZSwgQ29tcG9uZW50LCBpc1Jvb3QgPSBmYWxzZSkgew0KICBsZXQgbmFtZSA9IGdldENvbXBvbmVudE5hbWUoQ29tcG9uZW50KTsNCiAgaWYgKCFuYW1lICYmIENvbXBvbmVudC5fX2ZpbGUpIHsNCiAgICBjb25zdCBtYXRjaCA9IENvbXBvbmVudC5fX2ZpbGUubWF0Y2goLyhbXi9cXF0rKVwuXHcrJC8pOw0KICAgIGlmIChtYXRjaCkgew0KICAgICAgbmFtZSA9IG1hdGNoWzFdOw0KICAgIH0NCiAgfQ0KICBpZiAoIW5hbWUgJiYgaW5zdGFuY2UgJiYgaW5zdGFuY2UucGFyZW50KSB7DQogICAgY29uc3QgaW5mZXJGcm9tUmVnaXN0cnkgPSAocmVnaXN0cnkpID0+IHsNCiAgICAgIGZvciAoY29uc3Qga2V5IGluIHJlZ2lzdHJ5KSB7DQogICAgICAgIGlmIChyZWdpc3RyeVtrZXldID09PSBDb21wb25lbnQpIHsNCiAgICAgICAgICByZXR1cm4ga2V5Ow0KICAgICAgICB9DQogICAgICB9DQogICAgfTsNCiAgICBuYW1lID0gaW5mZXJGcm9tUmVnaXN0cnkoDQogICAgICBpbnN0YW5jZS5jb21wb25lbnRzIHx8IGluc3RhbmNlLnBhcmVudC50eXBlLmNvbXBvbmVudHMNCiAgICApIHx8IGluZmVyRnJvbVJlZ2lzdHJ5KGluc3RhbmNlLmFwcENvbnRleHQuY29tcG9uZW50cyk7DQogIH0NCiAgcmV0dXJuIG5hbWUgPyBjbGFzc2lmeShuYW1lKSA6IGlzUm9vdCA/IGBBcHBgIDogYEFub255bW91c2A7DQp9DQpmdW5jdGlvbiBpc0NsYXNzQ29tcG9uZW50KHZhbHVlKSB7DQogIHJldHVybiBpc0Z1bmN0aW9uKHZhbHVlKSAmJiAiX192Y2NPcHRzIiBpbiB2YWx1ZTsNCn0NCg0KY29uc3QgY29tcHV0ZWQgPSAoZ2V0dGVyT3JPcHRpb25zLCBkZWJ1Z09wdGlvbnMpID0+IHsNCiAgY29uc3QgYyA9IGNvbXB1dGVkJDEoZ2V0dGVyT3JPcHRpb25zLCBkZWJ1Z09wdGlvbnMsIGlzSW5TU1JDb21wb25lbnRTZXR1cCk7DQogIHsNCiAgICBjb25zdCBpID0gZ2V0Q3VycmVudEluc3RhbmNlKCk7DQogICAgaWYgKGkgJiYgaS5hcHBDb250ZXh0LmNvbmZpZy53YXJuUmVjdXJzaXZlQ29tcHV0ZWQpIHsNCiAgICAgIGMuX3dhcm5SZWN1cnNpdmUgPSB0cnVlOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gYzsNCn07DQoNCmNvbnN0IHZlcnNpb24gPSAiMy41LjE3IjsNCmNvbnN0IHdhcm4gPSB3YXJuJDEgOw0KY29uc3QgX3NzclV0aWxzID0gew0KICBjcmVhdGVDb21wb25lbnRJbnN0YW5jZTogY3JlYXRlQ29tcG9uZW50SW5zdGFuY2UkMSwNCiAgc2V0dXBDb21wb25lbnQ6IHNldHVwQ29tcG9uZW50JDEsDQogIHJlbmRlckNvbXBvbmVudFJvb3Q6IHJlbmRlckNvbXBvbmVudFJvb3QkMSwNCiAgc2V0Q3VycmVudFJlbmRlcmluZ0luc3RhbmNlOiBzZXRDdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UkMSwNCiAgaXNWTm9kZTogaXNWTm9kZSQyLA0KICBub3JtYWxpemVWTm9kZTogbm9ybWFsaXplVk5vZGUkMSwNCiAgZ2V0Q29tcG9uZW50UHVibGljSW5zdGFuY2UsDQogIGVuc3VyZVZhbGlkVk5vZGU6IGVuc3VyZVZhbGlkVk5vZGUkMSwNCiAgcHVzaFdhcm5pbmdDb250ZXh0OiBwdXNoV2FybmluZ0NvbnRleHQkMSwNCiAgcG9wV2FybmluZ0NvbnRleHQ6IHBvcFdhcm5pbmdDb250ZXh0JDENCn07DQpjb25zdCBzc3JVdGlscyA9IF9zc3JVdGlscyA7DQoNCmxldCBwb2xpY3kgPSB2b2lkIDA7DQpjb25zdCB0dCA9IHR5cGVvZiB3aW5kb3cgIT09ICJ1bmRlZmluZWQiICYmIHdpbmRvdy50cnVzdGVkVHlwZXM7DQppZiAodHQpIHsNCiAgdHJ5IHsNCiAgICBwb2xpY3kgPSAvKiBAX19QVVJFX18gKi8gdHQuY3JlYXRlUG9saWN5KCJ2dWUiLCB7DQogICAgICBjcmVhdGVIVE1MOiAodmFsKSA9PiB2YWwNCiAgICB9KTsNCiAgfSBjYXRjaCAoZSkgew0KICAgIHdhcm4oYEVycm9yIGNyZWF0aW5nIHRydXN0ZWQgdHlwZXMgcG9saWN5OiAke2V9YCk7DQogIH0NCn0NCmNvbnN0IHVuc2FmZVRvVHJ1c3RlZEhUTUwgPSBwb2xpY3kgPyAodmFsKSA9PiBwb2xpY3kuY3JlYXRlSFRNTCh2YWwpIDogKHZhbCkgPT4gdmFsOw0KY29uc3Qgc3ZnTlMgPSAiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciOw0KY29uc3QgbWF0aG1sTlMgPSAiaHR0cDovL3d3dy53My5vcmcvMTk5OC9NYXRoL01hdGhNTCI7DQpjb25zdCBkb2MgPSB0eXBlb2YgZG9jdW1lbnQgIT09ICJ1bmRlZmluZWQiID8gZG9jdW1lbnQgOiBudWxsOw0KY29uc3QgdGVtcGxhdGVDb250YWluZXIgPSBkb2MgJiYgLyogQF9fUFVSRV9fICovIGRvYy5jcmVhdGVFbGVtZW50KCJ0ZW1wbGF0ZSIpOw0KY29uc3Qgbm9kZU9wcyA9IHsNCiAgaW5zZXJ0OiAoY2hpbGQsIHBhcmVudCwgYW5jaG9yKSA9PiB7DQogICAgcGFyZW50Lmluc2VydEJlZm9yZShjaGlsZCwgYW5jaG9yIHx8IG51bGwpOw0KICB9LA0KICByZW1vdmU6IChjaGlsZCkgPT4gew0KICAgIGNvbnN0IHBhcmVudCA9IGNoaWxkLnBhcmVudE5vZGU7DQogICAgaWYgKHBhcmVudCkgew0KICAgICAgcGFyZW50LnJlbW92ZUNoaWxkKGNoaWxkKTsNCiAgICB9DQogIH0sDQogIGNyZWF0ZUVsZW1lbnQ6ICh0YWcsIG5hbWVzcGFjZSwgaXMsIHByb3BzKSA9PiB7DQogICAgY29uc3QgZWwgPSBuYW1lc3BhY2UgPT09ICJzdmciID8gZG9jLmNyZWF0ZUVsZW1lbnROUyhzdmdOUywgdGFnKSA6IG5hbWVzcGFjZSA9PT0gIm1hdGhtbCIgPyBkb2MuY3JlYXRlRWxlbWVudE5TKG1hdGhtbE5TLCB0YWcpIDogaXMgPyBkb2MuY3JlYXRlRWxlbWVudCh0YWcsIHsgaXMgfSkgOiBkb2MuY3JlYXRlRWxlbWVudCh0YWcpOw0KICAgIGlmICh0YWcgPT09ICJzZWxlY3QiICYmIHByb3BzICYmIHByb3BzLm11bHRpcGxlICE9IG51bGwpIHsNCiAgICAgIGVsLnNldEF0dHJpYnV0ZSgibXVsdGlwbGUiLCBwcm9wcy5tdWx0aXBsZSk7DQogICAgfQ0KICAgIHJldHVybiBlbDsNCiAgfSwNCiAgY3JlYXRlVGV4dDogKHRleHQpID0+IGRvYy5jcmVhdGVUZXh0Tm9kZSh0ZXh0KSwNCiAgY3JlYXRlQ29tbWVudDogKHRleHQpID0+IGRvYy5jcmVhdGVDb21tZW50KHRleHQpLA0KICBzZXRUZXh0OiAobm9kZSwgdGV4dCkgPT4gew0KICAgIG5vZGUubm9kZVZhbHVlID0gdGV4dDsNCiAgfSwNCiAgc2V0RWxlbWVudFRleHQ6IChlbCwgdGV4dCkgPT4gew0KICAgIGVsLnRleHRDb250ZW50ID0gdGV4dDsNCiAgfSwNCiAgcGFyZW50Tm9kZTogKG5vZGUpID0+IG5vZGUucGFyZW50Tm9kZSwNCiAgbmV4dFNpYmxpbmc6IChub2RlKSA9PiBub2RlLm5leHRTaWJsaW5nLA0KICBxdWVyeVNlbGVjdG9yOiAoc2VsZWN0b3IpID0+IGRvYy5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKSwNCiAgc2V0U2NvcGVJZChlbCwgaWQpIHsNCiAgICBlbC5zZXRBdHRyaWJ1dGUoaWQsICIiKTsNCiAgfSwNCiAgLy8gX19VTlNBRkVfXw0KICAvLyBSZWFzb246IGlubmVySFRNTC4NCiAgLy8gU3RhdGljIGNvbnRlbnQgaGVyZSBjYW4gb25seSBjb21lIGZyb20gY29tcGlsZWQgdGVtcGxhdGVzLg0KICAvLyBBcyBsb25nIGFzIHRoZSB1c2VyIG9ubHkgdXNlcyB0cnVzdGVkIHRlbXBsYXRlcywgdGhpcyBpcyBzYWZlLg0KICBpbnNlcnRTdGF0aWNDb250ZW50KGNvbnRlbnQsIHBhcmVudCwgYW5jaG9yLCBuYW1lc3BhY2UsIHN0YXJ0LCBlbmQpIHsNCiAgICBjb25zdCBiZWZvcmUgPSBhbmNob3IgPyBhbmNob3IucHJldmlvdXNTaWJsaW5nIDogcGFyZW50Lmxhc3RDaGlsZDsNCiAgICBpZiAoc3RhcnQgJiYgKHN0YXJ0ID09PSBlbmQgfHwgc3RhcnQubmV4dFNpYmxpbmcpKSB7DQogICAgICB3aGlsZSAodHJ1ZSkgew0KICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKHN0YXJ0LmNsb25lTm9kZSh0cnVlKSwgYW5jaG9yKTsNCiAgICAgICAgaWYgKHN0YXJ0ID09PSBlbmQgfHwgIShzdGFydCA9IHN0YXJ0Lm5leHRTaWJsaW5nKSkgYnJlYWs7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIHRlbXBsYXRlQ29udGFpbmVyLmlubmVySFRNTCA9IHVuc2FmZVRvVHJ1c3RlZEhUTUwoDQogICAgICAgIG5hbWVzcGFjZSA9PT0gInN2ZyIgPyBgPHN2Zz4ke2NvbnRlbnR9PC9zdmc+YCA6IG5hbWVzcGFjZSA9PT0gIm1hdGhtbCIgPyBgPG1hdGg+JHtjb250ZW50fTwvbWF0aD5gIDogY29udGVudA0KICAgICAgKTsNCiAgICAgIGNvbnN0IHRlbXBsYXRlID0gdGVtcGxhdGVDb250YWluZXIuY29udGVudDsNCiAgICAgIGlmIChuYW1lc3BhY2UgPT09ICJzdmciIHx8IG5hbWVzcGFjZSA9PT0gIm1hdGhtbCIpIHsNCiAgICAgICAgY29uc3Qgd3JhcHBlciA9IHRlbXBsYXRlLmZpcnN0Q2hpbGQ7DQogICAgICAgIHdoaWxlICh3cmFwcGVyLmZpcnN0Q2hpbGQpIHsNCiAgICAgICAgICB0ZW1wbGF0ZS5hcHBlbmRDaGlsZCh3cmFwcGVyLmZpcnN0Q2hpbGQpOw0KICAgICAgICB9DQogICAgICAgIHRlbXBsYXRlLnJlbW92ZUNoaWxkKHdyYXBwZXIpOw0KICAgICAgfQ0KICAgICAgcGFyZW50Lmluc2VydEJlZm9yZSh0ZW1wbGF0ZSwgYW5jaG9yKTsNCiAgICB9DQogICAgcmV0dXJuIFsNCiAgICAgIC8vIGZpcnN0DQogICAgICBiZWZvcmUgPyBiZWZvcmUubmV4dFNpYmxpbmcgOiBwYXJlbnQuZmlyc3RDaGlsZCwNCiAgICAgIC8vIGxhc3QNCiAgICAgIGFuY2hvciA/IGFuY2hvci5wcmV2aW91c1NpYmxpbmcgOiBwYXJlbnQubGFzdENoaWxkDQogICAgXTsNCiAgfQ0KfTsNCg0KY29uc3QgdnRjS2V5ID0gU3ltYm9sKCJfdnRjIik7DQoNCmZ1bmN0aW9uIHBhdGNoQ2xhc3MoZWwsIHZhbHVlLCBpc1NWRykgew0KICBjb25zdCB0cmFuc2l0aW9uQ2xhc3NlcyA9IGVsW3Z0Y0tleV07DQogIGlmICh0cmFuc2l0aW9uQ2xhc3Nlcykgew0KICAgIHZhbHVlID0gKHZhbHVlID8gW3ZhbHVlLCAuLi50cmFuc2l0aW9uQ2xhc3Nlc10gOiBbLi4udHJhbnNpdGlvbkNsYXNzZXNdKS5qb2luKCIgIik7DQogIH0NCiAgaWYgKHZhbHVlID09IG51bGwpIHsNCiAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoImNsYXNzIik7DQogIH0gZWxzZSBpZiAoaXNTVkcpIHsNCiAgICBlbC5zZXRBdHRyaWJ1dGUoImNsYXNzIiwgdmFsdWUpOw0KICB9IGVsc2Ugew0KICAgIGVsLmNsYXNzTmFtZSA9IHZhbHVlOw0KICB9DQp9DQoNCmNvbnN0IHZTaG93T3JpZ2luYWxEaXNwbGF5ID0gU3ltYm9sKCJfdm9kIik7DQpjb25zdCB2U2hvd0hpZGRlbiA9IFN5bWJvbCgiX3ZzaCIpOw0KDQpjb25zdCBDU1NfVkFSX1RFWFQgPSBTeW1ib2woIkNTU19WQVJfVEVYVCIgKTsNCg0KY29uc3QgZGlzcGxheVJFID0gLyhefDspXHMqZGlzcGxheVxzKjovOw0KZnVuY3Rpb24gcGF0Y2hTdHlsZShlbCwgcHJldiwgbmV4dCkgew0KICBjb25zdCBzdHlsZSA9IGVsLnN0eWxlOw0KICBjb25zdCBpc0Nzc1N0cmluZyA9IGlzU3RyaW5nKG5leHQpOw0KICBsZXQgaGFzQ29udHJvbGxlZERpc3BsYXkgPSBmYWxzZTsNCiAgaWYgKG5leHQgJiYgIWlzQ3NzU3RyaW5nKSB7DQogICAgaWYgKHByZXYpIHsNCiAgICAgIGlmICghaXNTdHJpbmcocHJldikpIHsNCiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gcHJldikgew0KICAgICAgICAgIGlmIChuZXh0W2tleV0gPT0gbnVsbCkgew0KICAgICAgICAgICAgc2V0U3R5bGUoc3R5bGUsIGtleSwgIiIpOw0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgZm9yIChjb25zdCBwcmV2U3R5bGUgb2YgcHJldi5zcGxpdCgiOyIpKSB7DQogICAgICAgICAgY29uc3Qga2V5ID0gcHJldlN0eWxlLnNsaWNlKDAsIHByZXZTdHlsZS5pbmRleE9mKCI6IikpLnRyaW0oKTsNCiAgICAgICAgICBpZiAobmV4dFtrZXldID09IG51bGwpIHsNCiAgICAgICAgICAgIHNldFN0eWxlKHN0eWxlLCBrZXksICIiKTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogICAgZm9yIChjb25zdCBrZXkgaW4gbmV4dCkgew0KICAgICAgaWYgKGtleSA9PT0gImRpc3BsYXkiKSB7DQogICAgICAgIGhhc0NvbnRyb2xsZWREaXNwbGF5ID0gdHJ1ZTsNCiAgICAgIH0NCiAgICAgIHNldFN0eWxlKHN0eWxlLCBrZXksIG5leHRba2V5XSk7DQogICAgfQ0KICB9IGVsc2Ugew0KICAgIGlmIChpc0Nzc1N0cmluZykgew0KICAgICAgaWYgKHByZXYgIT09IG5leHQpIHsNCiAgICAgICAgY29uc3QgY3NzVmFyVGV4dCA9IHN0eWxlW0NTU19WQVJfVEVYVF07DQogICAgICAgIGlmIChjc3NWYXJUZXh0KSB7DQogICAgICAgICAgbmV4dCArPSAiOyIgKyBjc3NWYXJUZXh0Ow0KICAgICAgICB9DQogICAgICAgIHN0eWxlLmNzc1RleHQgPSBuZXh0Ow0KICAgICAgICBoYXNDb250cm9sbGVkRGlzcGxheSA9IGRpc3BsYXlSRS50ZXN0KG5leHQpOw0KICAgICAgfQ0KICAgIH0gZWxzZSBpZiAocHJldikgew0KICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKCJzdHlsZSIpOw0KICAgIH0NCiAgfQ0KICBpZiAodlNob3dPcmlnaW5hbERpc3BsYXkgaW4gZWwpIHsNCiAgICBlbFt2U2hvd09yaWdpbmFsRGlzcGxheV0gPSBoYXNDb250cm9sbGVkRGlzcGxheSA/IHN0eWxlLmRpc3BsYXkgOiAiIjsNCiAgICBpZiAoZWxbdlNob3dIaWRkZW5dKSB7DQogICAgICBzdHlsZS5kaXNwbGF5ID0gIm5vbmUiOw0KICAgIH0NCiAgfQ0KfQ0KY29uc3Qgc2VtaWNvbG9uUkUgPSAvW15cXF07XHMqJC87DQpjb25zdCBpbXBvcnRhbnRSRSA9IC9ccyohaW1wb3J0YW50JC87DQpmdW5jdGlvbiBzZXRTdHlsZShzdHlsZSwgbmFtZSwgdmFsKSB7DQogIGlmIChpc0FycmF5KHZhbCkpIHsNCiAgICB2YWwuZm9yRWFjaCgodikgPT4gc2V0U3R5bGUoc3R5bGUsIG5hbWUsIHYpKTsNCiAgfSBlbHNlIHsNCiAgICBpZiAodmFsID09IG51bGwpIHZhbCA9ICIiOw0KICAgIHsNCiAgICAgIGlmIChzZW1pY29sb25SRS50ZXN0KHZhbCkpIHsNCiAgICAgICAgd2FybigNCiAgICAgICAgICBgVW5leHBlY3RlZCBzZW1pY29sb24gYXQgdGhlIGVuZCBvZiAnJHtuYW1lfScgc3R5bGUgdmFsdWU6ICcke3ZhbH0nYA0KICAgICAgICApOw0KICAgICAgfQ0KICAgIH0NCiAgICBpZiAobmFtZS5zdGFydHNXaXRoKCItLSIpKSB7DQogICAgICBzdHlsZS5zZXRQcm9wZXJ0eShuYW1lLCB2YWwpOw0KICAgIH0gZWxzZSB7DQogICAgICBjb25zdCBwcmVmaXhlZCA9IGF1dG9QcmVmaXgoc3R5bGUsIG5hbWUpOw0KICAgICAgaWYgKGltcG9ydGFudFJFLnRlc3QodmFsKSkgew0KICAgICAgICBzdHlsZS5zZXRQcm9wZXJ0eSgNCiAgICAgICAgICBoeXBoZW5hdGUocHJlZml4ZWQpLA0KICAgICAgICAgIHZhbC5yZXBsYWNlKGltcG9ydGFudFJFLCAiIiksDQogICAgICAgICAgImltcG9ydGFudCINCiAgICAgICAgKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHN0eWxlW3ByZWZpeGVkXSA9IHZhbDsNCiAgICAgIH0NCiAgICB9DQogIH0NCn0NCmNvbnN0IHByZWZpeGVzID0gWyJXZWJraXQiLCAiTW96IiwgIm1zIl07DQpjb25zdCBwcmVmaXhDYWNoZSA9IHt9Ow0KZnVuY3Rpb24gYXV0b1ByZWZpeChzdHlsZSwgcmF3TmFtZSkgew0KICBjb25zdCBjYWNoZWQgPSBwcmVmaXhDYWNoZVtyYXdOYW1lXTsNCiAgaWYgKGNhY2hlZCkgew0KICAgIHJldHVybiBjYWNoZWQ7DQogIH0NCiAgbGV0IG5hbWUgPSBjYW1lbGl6ZShyYXdOYW1lKTsNCiAgaWYgKG5hbWUgIT09ICJmaWx0ZXIiICYmIG5hbWUgaW4gc3R5bGUpIHsNCiAgICByZXR1cm4gcHJlZml4Q2FjaGVbcmF3TmFtZV0gPSBuYW1lOw0KICB9DQogIG5hbWUgPSBjYXBpdGFsaXplKG5hbWUpOw0KICBmb3IgKGxldCBpID0gMDsgaSA8IHByZWZpeGVzLmxlbmd0aDsgaSsrKSB7DQogICAgY29uc3QgcHJlZml4ZWQgPSBwcmVmaXhlc1tpXSArIG5hbWU7DQogICAgaWYgKHByZWZpeGVkIGluIHN0eWxlKSB7DQogICAgICByZXR1cm4gcHJlZml4Q2FjaGVbcmF3TmFtZV0gPSBwcmVmaXhlZDsNCiAgICB9DQogIH0NCiAgcmV0dXJuIHJhd05hbWU7DQp9DQoNCmNvbnN0IHhsaW5rTlMgPSAiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI7DQpmdW5jdGlvbiBwYXRjaEF0dHIoZWwsIGtleSwgdmFsdWUsIGlzU1ZHLCBpbnN0YW5jZSwgaXNCb29sZWFuID0gaXNTcGVjaWFsQm9vbGVhbkF0dHIoa2V5KSkgew0KICBpZiAoaXNTVkcgJiYga2V5LnN0YXJ0c1dpdGgoInhsaW5rOiIpKSB7DQogICAgaWYgKHZhbHVlID09IG51bGwpIHsNCiAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZU5TKHhsaW5rTlMsIGtleS5zbGljZSg2LCBrZXkubGVuZ3RoKSk7DQogICAgfSBlbHNlIHsNCiAgICAgIGVsLnNldEF0dHJpYnV0ZU5TKHhsaW5rTlMsIGtleSwgdmFsdWUpOw0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICBpZiAodmFsdWUgPT0gbnVsbCB8fCBpc0Jvb2xlYW4gJiYgIWluY2x1ZGVCb29sZWFuQXR0cih2YWx1ZSkpIHsNCiAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZShrZXkpOw0KICAgIH0gZWxzZSB7DQogICAgICBlbC5zZXRBdHRyaWJ1dGUoDQogICAgICAgIGtleSwNCiAgICAgICAgaXNCb29sZWFuID8gIiIgOiBpc1N5bWJvbCh2YWx1ZSkgPyBTdHJpbmcodmFsdWUpIDogdmFsdWUNCiAgICAgICk7DQogICAgfQ0KICB9DQp9DQoNCmZ1bmN0aW9uIHBhdGNoRE9NUHJvcChlbCwga2V5LCB2YWx1ZSwgcGFyZW50Q29tcG9uZW50LCBhdHRyTmFtZSkgew0KICBpZiAoa2V5ID09PSAiaW5uZXJIVE1MIiB8fCBrZXkgPT09ICJ0ZXh0Q29udGVudCIpIHsNCiAgICBpZiAodmFsdWUgIT0gbnVsbCkgew0KICAgICAgZWxba2V5XSA9IGtleSA9PT0gImlubmVySFRNTCIgPyB1bnNhZmVUb1RydXN0ZWRIVE1MKHZhbHVlKSA6IHZhbHVlOw0KICAgIH0NCiAgICByZXR1cm47DQogIH0NCiAgY29uc3QgdGFnID0gZWwudGFnTmFtZTsNCiAgaWYgKGtleSA9PT0gInZhbHVlIiAmJiB0YWcgIT09ICJQUk9HUkVTUyIgJiYgLy8gY3VzdG9tIGVsZW1lbnRzIG1heSB1c2UgX3ZhbHVlIGludGVybmFsbHkNCiAgIXRhZy5pbmNsdWRlcygiLSIpKSB7DQogICAgY29uc3Qgb2xkVmFsdWUgPSB0YWcgPT09ICJPUFRJT04iID8gZWwuZ2V0QXR0cmlidXRlKCJ2YWx1ZSIpIHx8ICIiIDogZWwudmFsdWU7DQogICAgY29uc3QgbmV3VmFsdWUgPSB2YWx1ZSA9PSBudWxsID8gKA0KICAgICAgLy8gIzExNjQ3OiB2YWx1ZSBzaG91bGQgYmUgc2V0IGFzIGVtcHR5IHN0cmluZyBmb3IgbnVsbCBhbmQgdW5kZWZpbmVkLA0KICAgICAgLy8gYnV0IDxpbnB1dCB0eXBlPSJjaGVja2JveCI+IHNob3VsZCBiZSBzZXQgYXMgJ29uJy4NCiAgICAgIGVsLnR5cGUgPT09ICJjaGVja2JveCIgPyAib24iIDogIiINCiAgICApIDogU3RyaW5nKHZhbHVlKTsNCiAgICBpZiAob2xkVmFsdWUgIT09IG5ld1ZhbHVlIHx8ICEoIl92YWx1ZSIgaW4gZWwpKSB7DQogICAgICBlbC52YWx1ZSA9IG5ld1ZhbHVlOw0KICAgIH0NCiAgICBpZiAodmFsdWUgPT0gbnVsbCkgew0KICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKGtleSk7DQogICAgfQ0KICAgIGVsLl92YWx1ZSA9IHZhbHVlOw0KICAgIHJldHVybjsNCiAgfQ0KICBsZXQgbmVlZFJlbW92ZSA9IGZhbHNlOw0KICBpZiAodmFsdWUgPT09ICIiIHx8IHZhbHVlID09IG51bGwpIHsNCiAgICBjb25zdCB0eXBlID0gdHlwZW9mIGVsW2tleV07DQogICAgaWYgKHR5cGUgPT09ICJib29sZWFuIikgew0KICAgICAgdmFsdWUgPSBpbmNsdWRlQm9vbGVhbkF0dHIodmFsdWUpOw0KICAgIH0gZWxzZSBpZiAodmFsdWUgPT0gbnVsbCAmJiB0eXBlID09PSAic3RyaW5nIikgew0KICAgICAgdmFsdWUgPSAiIjsNCiAgICAgIG5lZWRSZW1vdmUgPSB0cnVlOw0KICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gIm51bWJlciIpIHsNCiAgICAgIHZhbHVlID0gMDsNCiAgICAgIG5lZWRSZW1vdmUgPSB0cnVlOw0KICAgIH0NCiAgfQ0KICB0cnkgew0KICAgIGVsW2tleV0gPSB2YWx1ZTsNCiAgfSBjYXRjaCAoZSkgew0KICAgIGlmICghbmVlZFJlbW92ZSkgew0KICAgICAgd2FybigNCiAgICAgICAgYEZhaWxlZCBzZXR0aW5nIHByb3AgIiR7a2V5fSIgb24gPCR7dGFnLnRvTG93ZXJDYXNlKCl9PjogdmFsdWUgJHt2YWx1ZX0gaXMgaW52YWxpZC5gLA0KICAgICAgICBlDQogICAgICApOw0KICAgIH0NCiAgfQ0KICBuZWVkUmVtb3ZlICYmIGVsLnJlbW92ZUF0dHJpYnV0ZShhdHRyTmFtZSB8fCBrZXkpOw0KfQ0KDQpmdW5jdGlvbiBhZGRFdmVudExpc3RlbmVyKGVsLCBldmVudCwgaGFuZGxlciwgb3B0aW9ucykgew0KICBlbC5hZGRFdmVudExpc3RlbmVyKGV2ZW50LCBoYW5kbGVyLCBvcHRpb25zKTsNCn0NCmZ1bmN0aW9uIHJlbW92ZUV2ZW50TGlzdGVuZXIoZWwsIGV2ZW50LCBoYW5kbGVyLCBvcHRpb25zKSB7DQogIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnQsIGhhbmRsZXIsIG9wdGlvbnMpOw0KfQ0KY29uc3QgdmVpS2V5ID0gU3ltYm9sKCJfdmVpIik7DQpmdW5jdGlvbiBwYXRjaEV2ZW50KGVsLCByYXdOYW1lLCBwcmV2VmFsdWUsIG5leHRWYWx1ZSwgaW5zdGFuY2UgPSBudWxsKSB7DQogIGNvbnN0IGludm9rZXJzID0gZWxbdmVpS2V5XSB8fCAoZWxbdmVpS2V5XSA9IHt9KTsNCiAgY29uc3QgZXhpc3RpbmdJbnZva2VyID0gaW52b2tlcnNbcmF3TmFtZV07DQogIGlmIChuZXh0VmFsdWUgJiYgZXhpc3RpbmdJbnZva2VyKSB7DQogICAgZXhpc3RpbmdJbnZva2VyLnZhbHVlID0gc2FuaXRpemVFdmVudFZhbHVlKG5leHRWYWx1ZSwgcmF3TmFtZSkgOw0KICB9IGVsc2Ugew0KICAgIGNvbnN0IFtuYW1lLCBvcHRpb25zXSA9IHBhcnNlTmFtZShyYXdOYW1lKTsNCiAgICBpZiAobmV4dFZhbHVlKSB7DQogICAgICBjb25zdCBpbnZva2VyID0gaW52b2tlcnNbcmF3TmFtZV0gPSBjcmVhdGVJbnZva2VyKA0KICAgICAgICBzYW5pdGl6ZUV2ZW50VmFsdWUobmV4dFZhbHVlLCByYXdOYW1lKSAsDQogICAgICAgIGluc3RhbmNlDQogICAgICApOw0KICAgICAgYWRkRXZlbnRMaXN0ZW5lcihlbCwgbmFtZSwgaW52b2tlciwgb3B0aW9ucyk7DQogICAgfSBlbHNlIGlmIChleGlzdGluZ0ludm9rZXIpIHsNCiAgICAgIHJlbW92ZUV2ZW50TGlzdGVuZXIoZWwsIG5hbWUsIGV4aXN0aW5nSW52b2tlciwgb3B0aW9ucyk7DQogICAgICBpbnZva2Vyc1tyYXdOYW1lXSA9IHZvaWQgMDsNCiAgICB9DQogIH0NCn0NCmNvbnN0IG9wdGlvbnNNb2RpZmllclJFID0gLyg/Ok9uY2V8UGFzc2l2ZXxDYXB0dXJlKSQvOw0KZnVuY3Rpb24gcGFyc2VOYW1lKG5hbWUpIHsNCiAgbGV0IG9wdGlvbnM7DQogIGlmIChvcHRpb25zTW9kaWZpZXJSRS50ZXN0KG5hbWUpKSB7DQogICAgb3B0aW9ucyA9IHt9Ow0KICAgIGxldCBtOw0KICAgIHdoaWxlIChtID0gbmFtZS5tYXRjaChvcHRpb25zTW9kaWZpZXJSRSkpIHsNCiAgICAgIG5hbWUgPSBuYW1lLnNsaWNlKDAsIG5hbWUubGVuZ3RoIC0gbVswXS5sZW5ndGgpOw0KICAgICAgb3B0aW9uc1ttWzBdLnRvTG93ZXJDYXNlKCldID0gdHJ1ZTsNCiAgICB9DQogIH0NCiAgY29uc3QgZXZlbnQgPSBuYW1lWzJdID09PSAiOiIgPyBuYW1lLnNsaWNlKDMpIDogaHlwaGVuYXRlKG5hbWUuc2xpY2UoMikpOw0KICByZXR1cm4gW2V2ZW50LCBvcHRpb25zXTsNCn0NCmxldCBjYWNoZWROb3cgPSAwOw0KY29uc3QgcCA9IC8qIEBfX1BVUkVfXyAqLyBQcm9taXNlLnJlc29sdmUoKTsNCmNvbnN0IGdldE5vdyA9ICgpID0+IGNhY2hlZE5vdyB8fCAocC50aGVuKCgpID0+IGNhY2hlZE5vdyA9IDApLCBjYWNoZWROb3cgPSBEYXRlLm5vdygpKTsNCmZ1bmN0aW9uIGNyZWF0ZUludm9rZXIoaW5pdGlhbFZhbHVlLCBpbnN0YW5jZSkgew0KICBjb25zdCBpbnZva2VyID0gKGUpID0+IHsNCiAgICBpZiAoIWUuX3Z0cykgew0KICAgICAgZS5fdnRzID0gRGF0ZS5ub3coKTsNCiAgICB9IGVsc2UgaWYgKGUuX3Z0cyA8PSBpbnZva2VyLmF0dGFjaGVkKSB7DQogICAgICByZXR1cm47DQogICAgfQ0KICAgIGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nKA0KICAgICAgcGF0Y2hTdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oZSwgaW52b2tlci52YWx1ZSksDQogICAgICBpbnN0YW5jZSwNCiAgICAgIDUsDQogICAgICBbZV0NCiAgICApOw0KICB9Ow0KICBpbnZva2VyLnZhbHVlID0gaW5pdGlhbFZhbHVlOw0KICBpbnZva2VyLmF0dGFjaGVkID0gZ2V0Tm93KCk7DQogIHJldHVybiBpbnZva2VyOw0KfQ0KZnVuY3Rpb24gc2FuaXRpemVFdmVudFZhbHVlKHZhbHVlLCBwcm9wTmFtZSkgew0KICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkgfHwgaXNBcnJheSh2YWx1ZSkpIHsNCiAgICByZXR1cm4gdmFsdWU7DQogIH0NCiAgd2FybigNCiAgICBgV3JvbmcgdHlwZSBwYXNzZWQgYXMgZXZlbnQgaGFuZGxlciB0byAke3Byb3BOYW1lfSAtIGRpZCB5b3UgZm9yZ2V0IEAgb3IgOiBpbiBmcm9udCBvZiB5b3VyIHByb3A/DQpFeHBlY3RlZCBmdW5jdGlvbiBvciBhcnJheSBvZiBmdW5jdGlvbnMsIHJlY2VpdmVkIHR5cGUgJHt0eXBlb2YgdmFsdWV9LmANCiAgKTsNCiAgcmV0dXJuIE5PT1A7DQp9DQpmdW5jdGlvbiBwYXRjaFN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbihlLCB2YWx1ZSkgew0KICBpZiAoaXNBcnJheSh2YWx1ZSkpIHsNCiAgICBjb25zdCBvcmlnaW5hbFN0b3AgPSBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbjsNCiAgICBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiA9ICgpID0+IHsNCiAgICAgIG9yaWdpbmFsU3RvcC5jYWxsKGUpOw0KICAgICAgZS5fc3RvcHBlZCA9IHRydWU7DQogICAgfTsNCiAgICByZXR1cm4gdmFsdWUubWFwKA0KICAgICAgKGZuKSA9PiAoZTIpID0+ICFlMi5fc3RvcHBlZCAmJiBmbiAmJiBmbihlMikNCiAgICApOw0KICB9IGVsc2Ugew0KICAgIHJldHVybiB2YWx1ZTsNCiAgfQ0KfQ0KDQpjb25zdCBpc05hdGl2ZU9uID0gKGtleSkgPT4ga2V5LmNoYXJDb2RlQXQoMCkgPT09IDExMSAmJiBrZXkuY2hhckNvZGVBdCgxKSA9PT0gMTEwICYmIC8vIGxvd2VyY2FzZSBsZXR0ZXINCmtleS5jaGFyQ29kZUF0KDIpID4gOTYgJiYga2V5LmNoYXJDb2RlQXQoMikgPCAxMjM7DQpjb25zdCBwYXRjaFByb3AgPSAoZWwsIGtleSwgcHJldlZhbHVlLCBuZXh0VmFsdWUsIG5hbWVzcGFjZSwgcGFyZW50Q29tcG9uZW50KSA9PiB7DQogIGNvbnN0IGlzU1ZHID0gbmFtZXNwYWNlID09PSAic3ZnIjsNCiAgaWYgKGtleSA9PT0gImNsYXNzIikgew0KICAgIHBhdGNoQ2xhc3MoZWwsIG5leHRWYWx1ZSwgaXNTVkcpOw0KICB9IGVsc2UgaWYgKGtleSA9PT0gInN0eWxlIikgew0KICAgIHBhdGNoU3R5bGUoZWwsIHByZXZWYWx1ZSwgbmV4dFZhbHVlKTsNCiAgfSBlbHNlIGlmIChpc09uKGtleSkpIHsNCiAgICBpZiAoIWlzTW9kZWxMaXN0ZW5lcihrZXkpKSB7DQogICAgICBwYXRjaEV2ZW50KGVsLCBrZXksIHByZXZWYWx1ZSwgbmV4dFZhbHVlLCBwYXJlbnRDb21wb25lbnQpOw0KICAgIH0NCiAgfSBlbHNlIGlmIChrZXlbMF0gPT09ICIuIiA/IChrZXkgPSBrZXkuc2xpY2UoMSksIHRydWUpIDoga2V5WzBdID09PSAiXiIgPyAoa2V5ID0ga2V5LnNsaWNlKDEpLCBmYWxzZSkgOiBzaG91bGRTZXRBc1Byb3AoZWwsIGtleSwgbmV4dFZhbHVlLCBpc1NWRykpIHsNCiAgICBwYXRjaERPTVByb3AoZWwsIGtleSwgbmV4dFZhbHVlKTsNCiAgICBpZiAoIWVsLnRhZ05hbWUuaW5jbHVkZXMoIi0iKSAmJiAoa2V5ID09PSAidmFsdWUiIHx8IGtleSA9PT0gImNoZWNrZWQiIHx8IGtleSA9PT0gInNlbGVjdGVkIikpIHsNCiAgICAgIHBhdGNoQXR0cihlbCwga2V5LCBuZXh0VmFsdWUsIGlzU1ZHLCBwYXJlbnRDb21wb25lbnQsIGtleSAhPT0gInZhbHVlIik7DQogICAgfQ0KICB9IGVsc2UgaWYgKA0KICAgIC8vICMxMTA4MSBmb3JjZSBzZXQgcHJvcHMgZm9yIHBvc3NpYmxlIGFzeW5jIGN1c3RvbSBlbGVtZW50DQogICAgZWwuX2lzVnVlQ0UgJiYgKC9bQS1aXS8udGVzdChrZXkpIHx8ICFpc1N0cmluZyhuZXh0VmFsdWUpKQ0KICApIHsNCiAgICBwYXRjaERPTVByb3AoZWwsIGNhbWVsaXplKGtleSksIG5leHRWYWx1ZSwgcGFyZW50Q29tcG9uZW50LCBrZXkpOw0KICB9IGVsc2Ugew0KICAgIGlmIChrZXkgPT09ICJ0cnVlLXZhbHVlIikgew0KICAgICAgZWwuX3RydWVWYWx1ZSA9IG5leHRWYWx1ZTsNCiAgICB9IGVsc2UgaWYgKGtleSA9PT0gImZhbHNlLXZhbHVlIikgew0KICAgICAgZWwuX2ZhbHNlVmFsdWUgPSBuZXh0VmFsdWU7DQogICAgfQ0KICAgIHBhdGNoQXR0cihlbCwga2V5LCBuZXh0VmFsdWUsIGlzU1ZHKTsNCiAgfQ0KfTsNCmZ1bmN0aW9uIHNob3VsZFNldEFzUHJvcChlbCwga2V5LCB2YWx1ZSwgaXNTVkcpIHsNCiAgaWYgKGlzU1ZHKSB7DQogICAgaWYgKGtleSA9PT0gImlubmVySFRNTCIgfHwga2V5ID09PSAidGV4dENvbnRlbnQiKSB7DQogICAgICByZXR1cm4gdHJ1ZTsNCiAgICB9DQogICAgaWYgKGtleSBpbiBlbCAmJiBpc05hdGl2ZU9uKGtleSkgJiYgaXNGdW5jdGlvbih2YWx1ZSkpIHsNCiAgICAgIHJldHVybiB0cnVlOw0KICAgIH0NCiAgICByZXR1cm4gZmFsc2U7DQogIH0NCiAgaWYgKGtleSA9PT0gInNwZWxsY2hlY2siIHx8IGtleSA9PT0gImRyYWdnYWJsZSIgfHwga2V5ID09PSAidHJhbnNsYXRlIiB8fCBrZXkgPT09ICJhdXRvY29ycmVjdCIpIHsNCiAgICByZXR1cm4gZmFsc2U7DQogIH0NCiAgaWYgKGtleSA9PT0gImZvcm0iKSB7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9DQogIGlmIChrZXkgPT09ICJsaXN0IiAmJiBlbC50YWdOYW1lID09PSAiSU5QVVQiKSB7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9DQogIGlmIChrZXkgPT09ICJ0eXBlIiAmJiBlbC50YWdOYW1lID09PSAiVEVYVEFSRUEiKSB7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9DQogIGlmIChrZXkgPT09ICJ3aWR0aCIgfHwga2V5ID09PSAiaGVpZ2h0Iikgew0KICAgIGNvbnN0IHRhZyA9IGVsLnRhZ05hbWU7DQogICAgaWYgKHRhZyA9PT0gIklNRyIgfHwgdGFnID09PSAiVklERU8iIHx8IHRhZyA9PT0gIkNBTlZBUyIgfHwgdGFnID09PSAiU09VUkNFIikgew0KICAgICAgcmV0dXJuIGZhbHNlOw0KICAgIH0NCiAgfQ0KICBpZiAoaXNOYXRpdmVPbihrZXkpICYmIGlzU3RyaW5nKHZhbHVlKSkgew0KICAgIHJldHVybiBmYWxzZTsNCiAgfQ0KICByZXR1cm4ga2V5IGluIGVsOw0KfQ0KDQpjb25zdCB2TW9kZWxUZXh0ID0gew0KICB9Ow0KY29uc3Qgdk1vZGVsQ2hlY2tib3ggPSB7DQogIH07DQpjb25zdCB2TW9kZWxSYWRpbyA9IHsNCiAgfTsNCmZ1bmN0aW9uIGluaXRWTW9kZWxGb3JTU1IoKSB7DQogIHZNb2RlbFRleHQuZ2V0U1NSUHJvcHMgPSAoeyB2YWx1ZSB9KSA9PiAoeyB2YWx1ZSB9KTsNCiAgdk1vZGVsUmFkaW8uZ2V0U1NSUHJvcHMgPSAoeyB2YWx1ZSB9LCB2bm9kZSkgPT4gew0KICAgIGlmICh2bm9kZS5wcm9wcyAmJiBsb29zZUVxdWFsKHZub2RlLnByb3BzLnZhbHVlLCB2YWx1ZSkpIHsNCiAgICAgIHJldHVybiB7IGNoZWNrZWQ6IHRydWUgfTsNCiAgICB9DQogIH07DQogIHZNb2RlbENoZWNrYm94LmdldFNTUlByb3BzID0gKHsgdmFsdWUgfSwgdm5vZGUpID0+IHsNCiAgICBpZiAoaXNBcnJheSh2YWx1ZSkpIHsNCiAgICAgIGlmICh2bm9kZS5wcm9wcyAmJiBsb29zZUluZGV4T2YodmFsdWUsIHZub2RlLnByb3BzLnZhbHVlKSA+IC0xKSB7DQogICAgICAgIHJldHVybiB7IGNoZWNrZWQ6IHRydWUgfTsNCiAgICAgIH0NCiAgICB9IGVsc2UgaWYgKGlzU2V0KHZhbHVlKSkgew0KICAgICAgaWYgKHZub2RlLnByb3BzICYmIHZhbHVlLmhhcyh2bm9kZS5wcm9wcy52YWx1ZSkpIHsNCiAgICAgICAgcmV0dXJuIHsgY2hlY2tlZDogdHJ1ZSB9Ow0KICAgICAgfQ0KICAgIH0gZWxzZSBpZiAodmFsdWUpIHsNCiAgICAgIHJldHVybiB7IGNoZWNrZWQ6IHRydWUgfTsNCiAgICB9DQogIH07DQp9DQoNCmNvbnN0IHJlbmRlcmVyT3B0aW9ucyA9IC8qIEBfX1BVUkVfXyAqLyBleHRlbmQoeyBwYXRjaFByb3AgfSwgbm9kZU9wcyk7DQpsZXQgcmVuZGVyZXI7DQpmdW5jdGlvbiBlbnN1cmVSZW5kZXJlcigpIHsNCiAgcmV0dXJuIHJlbmRlcmVyIHx8IChyZW5kZXJlciA9IGNyZWF0ZVJlbmRlcmVyKHJlbmRlcmVyT3B0aW9ucykpOw0KfQ0KY29uc3QgY3JlYXRlQXBwID0gKC4uLmFyZ3MpID0+IHsNCiAgY29uc3QgYXBwID0gZW5zdXJlUmVuZGVyZXIoKS5jcmVhdGVBcHAoLi4uYXJncyk7DQogIHsNCiAgICBpbmplY3ROYXRpdmVUYWdDaGVjayhhcHApOw0KICAgIGluamVjdENvbXBpbGVyT3B0aW9uc0NoZWNrKGFwcCk7DQogIH0NCiAgY29uc3QgeyBtb3VudCB9ID0gYXBwOw0KICBhcHAubW91bnQgPSAoY29udGFpbmVyT3JTZWxlY3RvcikgPT4gew0KICAgIGNvbnN0IGNvbnRhaW5lciA9IG5vcm1hbGl6ZUNvbnRhaW5lcihjb250YWluZXJPclNlbGVjdG9yKTsNCiAgICBpZiAoIWNvbnRhaW5lcikgcmV0dXJuOw0KICAgIGNvbnN0IGNvbXBvbmVudCA9IGFwcC5fY29tcG9uZW50Ow0KICAgIGlmICghaXNGdW5jdGlvbihjb21wb25lbnQpICYmICFjb21wb25lbnQucmVuZGVyICYmICFjb21wb25lbnQudGVtcGxhdGUpIHsNCiAgICAgIGNvbXBvbmVudC50ZW1wbGF0ZSA9IGNvbnRhaW5lci5pbm5lckhUTUw7DQogICAgfQ0KICAgIGlmIChjb250YWluZXIubm9kZVR5cGUgPT09IDEpIHsNCiAgICAgIGNvbnRhaW5lci50ZXh0Q29udGVudCA9ICIiOw0KICAgIH0NCiAgICBjb25zdCBwcm94eSA9IG1vdW50KGNvbnRhaW5lciwgZmFsc2UsIHJlc29sdmVSb290TmFtZXNwYWNlKGNvbnRhaW5lcikpOw0KICAgIGlmIChjb250YWluZXIgaW5zdGFuY2VvZiBFbGVtZW50KSB7DQogICAgICBjb250YWluZXIucmVtb3ZlQXR0cmlidXRlKCJ2LWNsb2FrIik7DQogICAgICBjb250YWluZXIuc2V0QXR0cmlidXRlKCJkYXRhLXYtYXBwIiwgIiIpOw0KICAgIH0NCiAgICByZXR1cm4gcHJveHk7DQogIH07DQogIHJldHVybiBhcHA7DQp9Ow0KZnVuY3Rpb24gcmVzb2x2ZVJvb3ROYW1lc3BhY2UoY29udGFpbmVyKSB7DQogIGlmIChjb250YWluZXIgaW5zdGFuY2VvZiBTVkdFbGVtZW50KSB7DQogICAgcmV0dXJuICJzdmciOw0KICB9DQogIGlmICh0eXBlb2YgTWF0aE1MRWxlbWVudCA9PT0gImZ1bmN0aW9uIiAmJiBjb250YWluZXIgaW5zdGFuY2VvZiBNYXRoTUxFbGVtZW50KSB7DQogICAgcmV0dXJuICJtYXRobWwiOw0KICB9DQp9DQpmdW5jdGlvbiBpbmplY3ROYXRpdmVUYWdDaGVjayhhcHApIHsNCiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGFwcC5jb25maWcsICJpc05hdGl2ZVRhZyIsIHsNCiAgICB2YWx1ZTogKHRhZykgPT4gaXNIVE1MVGFnKHRhZykgfHwgaXNTVkdUYWcodGFnKSB8fCBpc01hdGhNTFRhZyh0YWcpLA0KICAgIHdyaXRhYmxlOiBmYWxzZQ0KICB9KTsNCn0NCmZ1bmN0aW9uIGluamVjdENvbXBpbGVyT3B0aW9uc0NoZWNrKGFwcCkgew0KICB7DQogICAgY29uc3QgaXNDdXN0b21FbGVtZW50ID0gYXBwLmNvbmZpZy5pc0N1c3RvbUVsZW1lbnQ7DQogICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGFwcC5jb25maWcsICJpc0N1c3RvbUVsZW1lbnQiLCB7DQogICAgICBnZXQoKSB7DQogICAgICAgIHJldHVybiBpc0N1c3RvbUVsZW1lbnQ7DQogICAgICB9LA0KICAgICAgc2V0KCkgew0KICAgICAgICB3YXJuKA0KICAgICAgICAgIGBUaGUgXGBpc0N1c3RvbUVsZW1lbnRcYCBjb25maWcgb3B0aW9uIGlzIGRlcHJlY2F0ZWQuIFVzZSBcYGNvbXBpbGVyT3B0aW9ucy5pc0N1c3RvbUVsZW1lbnRcYCBpbnN0ZWFkLmANCiAgICAgICAgKTsNCiAgICAgIH0NCiAgICB9KTsNCiAgICBjb25zdCBjb21waWxlck9wdGlvbnMgPSBhcHAuY29uZmlnLmNvbXBpbGVyT3B0aW9uczsNCiAgICBjb25zdCBtc2cgPSBgVGhlIFxgY29tcGlsZXJPcHRpb25zXGAgY29uZmlnIG9wdGlvbiBpcyBvbmx5IHJlc3BlY3RlZCB3aGVuIHVzaW5nIGEgYnVpbGQgb2YgVnVlLmpzIHRoYXQgaW5jbHVkZXMgdGhlIHJ1bnRpbWUgY29tcGlsZXIgKGFrYSAiZnVsbCBidWlsZCIpLiBTaW5jZSB5b3UgYXJlIHVzaW5nIHRoZSBydW50aW1lLW9ubHkgYnVpbGQsIFxgY29tcGlsZXJPcHRpb25zXGAgbXVzdCBiZSBwYXNzZWQgdG8gXGBAdnVlL2NvbXBpbGVyLWRvbVxgIGluIHRoZSBidWlsZCBzZXR1cCBpbnN0ZWFkLg0KLSBGb3IgdnVlLWxvYWRlcjogcGFzcyBpdCB2aWEgdnVlLWxvYWRlcidzIFxgY29tcGlsZXJPcHRpb25zXGAgbG9hZGVyIG9wdGlvbi4NCi0gRm9yIHZ1ZS1jbGk6IHNlZSBodHRwczovL2NsaS52dWVqcy5vcmcvZ3VpZGUvd2VicGFjay5odG1sI21vZGlmeWluZy1vcHRpb25zLW9mLWEtbG9hZGVyDQotIEZvciB2aXRlOiBwYXNzIGl0IHZpYSBAdml0ZWpzL3BsdWdpbi12dWUgb3B0aW9ucy4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS92aXRlanMvdml0ZS1wbHVnaW4tdnVlL3RyZWUvbWFpbi9wYWNrYWdlcy9wbHVnaW4tdnVlI2V4YW1wbGUtZm9yLXBhc3Npbmctb3B0aW9ucy10by12dWVjb21waWxlci1zZmNgOw0KICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhcHAuY29uZmlnLCAiY29tcGlsZXJPcHRpb25zIiwgew0KICAgICAgZ2V0KCkgew0KICAgICAgICB3YXJuKG1zZyk7DQogICAgICAgIHJldHVybiBjb21waWxlck9wdGlvbnM7DQogICAgICB9LA0KICAgICAgc2V0KCkgew0KICAgICAgICB3YXJuKG1zZyk7DQogICAgICB9DQogICAgfSk7DQogIH0NCn0NCmZ1bmN0aW9uIG5vcm1hbGl6ZUNvbnRhaW5lcihjb250YWluZXIpIHsNCiAgaWYgKGlzU3RyaW5nKGNvbnRhaW5lcikpIHsNCiAgICBjb25zdCByZXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGNvbnRhaW5lcik7DQogICAgaWYgKCFyZXMpIHsNCiAgICAgIHdhcm4oDQogICAgICAgIGBGYWlsZWQgdG8gbW91bnQgYXBwOiBtb3VudCB0YXJnZXQgc2VsZWN0b3IgIiR7Y29udGFpbmVyfSIgcmV0dXJuZWQgbnVsbC5gDQogICAgICApOw0KICAgIH0NCiAgICByZXR1cm4gcmVzOw0KICB9DQogIGlmICh3aW5kb3cuU2hhZG93Um9vdCAmJiBjb250YWluZXIgaW5zdGFuY2VvZiB3aW5kb3cuU2hhZG93Um9vdCAmJiBjb250YWluZXIubW9kZSA9PT0gImNsb3NlZCIpIHsNCiAgICB3YXJuKA0KICAgICAgYG1vdW50aW5nIG9uIGEgU2hhZG93Um9vdCB3aXRoIFxge21vZGU6ICJjbG9zZWQifVxgIG1heSBsZWFkIHRvIHVucHJlZGljdGFibGUgYnVnc2ANCiAgICApOw0KICB9DQogIHJldHVybiBjb250YWluZXI7DQp9DQpsZXQgc3NyRGlyZWN0aXZlSW5pdGlhbGl6ZWQgPSBmYWxzZTsNCmNvbnN0IGluaXREaXJlY3RpdmVzRm9yU1NSID0gKCkgPT4gew0KICBpZiAoIXNzckRpcmVjdGl2ZUluaXRpYWxpemVkKSB7DQogICAgc3NyRGlyZWN0aXZlSW5pdGlhbGl6ZWQgPSB0cnVlOw0KICAgIGluaXRWTW9kZWxGb3JTU1IoKTsNCiAgfQ0KfSA7DQoNCmNvbnN0IHNob3VsZElnbm9yZVByb3AgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcCgNCiAgYCxrZXkscmVmLGlubmVySFRNTCx0ZXh0Q29udGVudCxyZWZfa2V5LHJlZl9mb3JgDQopOw0KZnVuY3Rpb24gc3NyUmVuZGVyQXR0cnMocHJvcHMsIHRhZykgew0KICBsZXQgcmV0ID0gIiI7DQogIGZvciAoY29uc3Qga2V5IGluIHByb3BzKSB7DQogICAgaWYgKHNob3VsZElnbm9yZVByb3Aoa2V5KSB8fCBpc09uKGtleSkgfHwgdGFnID09PSAidGV4dGFyZWEiICYmIGtleSA9PT0gInZhbHVlIikgew0KICAgICAgY29udGludWU7DQogICAgfQ0KICAgIGNvbnN0IHZhbHVlID0gcHJvcHNba2V5XTsNCiAgICBpZiAoa2V5ID09PSAiY2xhc3MiKSB7DQogICAgICByZXQgKz0gYCBjbGFzcz0iJHtzc3JSZW5kZXJDbGFzcyh2YWx1ZSl9ImA7DQogICAgfSBlbHNlIGlmIChrZXkgPT09ICJzdHlsZSIpIHsNCiAgICAgIHJldCArPSBgIHN0eWxlPSIke3NzclJlbmRlclN0eWxlKHZhbHVlKX0iYDsNCiAgICB9IGVsc2UgaWYgKGtleSA9PT0gImNsYXNzTmFtZSIpIHsNCiAgICAgIHJldCArPSBgIGNsYXNzPSIke1N0cmluZyh2YWx1ZSl9ImA7DQogICAgfSBlbHNlIHsNCiAgICAgIHJldCArPSBzc3JSZW5kZXJEeW5hbWljQXR0cihrZXksIHZhbHVlLCB0YWcpOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gcmV0Ow0KfQ0KZnVuY3Rpb24gc3NyUmVuZGVyRHluYW1pY0F0dHIoa2V5LCB2YWx1ZSwgdGFnKSB7DQogIGlmICghaXNSZW5kZXJhYmxlQXR0clZhbHVlKHZhbHVlKSkgew0KICAgIHJldHVybiBgYDsNCiAgfQ0KICBjb25zdCBhdHRyS2V5ID0gdGFnICYmICh0YWcuaW5kZXhPZigiLSIpID4gMCB8fCBpc1NWR1RhZyh0YWcpKSA/IGtleSA6IHByb3BzVG9BdHRyTWFwW2tleV0gfHwga2V5LnRvTG93ZXJDYXNlKCk7DQogIGlmIChpc0Jvb2xlYW5BdHRyKGF0dHJLZXkpKSB7DQogICAgcmV0dXJuIGluY2x1ZGVCb29sZWFuQXR0cih2YWx1ZSkgPyBgICR7YXR0cktleX1gIDogYGA7DQogIH0gZWxzZSBpZiAoaXNTU1JTYWZlQXR0ck5hbWUoYXR0cktleSkpIHsNCiAgICByZXR1cm4gdmFsdWUgPT09ICIiID8gYCAke2F0dHJLZXl9YCA6IGAgJHthdHRyS2V5fT0iJHtlc2NhcGVIdG1sKHZhbHVlKX0iYDsNCiAgfSBlbHNlIHsNCiAgICBjb25zb2xlLndhcm4oDQogICAgICBgW0B2dWUvc2VydmVyLXJlbmRlcmVyXSBTa2lwcGVkIHJlbmRlcmluZyB1bnNhZmUgYXR0cmlidXRlIG5hbWU6ICR7YXR0cktleX1gDQogICAgKTsNCiAgICByZXR1cm4gYGA7DQogIH0NCn0NCmZ1bmN0aW9uIHNzclJlbmRlckF0dHIoa2V5LCB2YWx1ZSkgew0KICBpZiAoIWlzUmVuZGVyYWJsZUF0dHJWYWx1ZSh2YWx1ZSkpIHsNCiAgICByZXR1cm4gYGA7DQogIH0NCiAgcmV0dXJuIGAgJHtrZXl9PSIke2VzY2FwZUh0bWwodmFsdWUpfSJgOw0KfQ0KZnVuY3Rpb24gc3NyUmVuZGVyQ2xhc3MocmF3KSB7DQogIHJldHVybiBlc2NhcGVIdG1sKG5vcm1hbGl6ZUNsYXNzKHJhdykpOw0KfQ0KZnVuY3Rpb24gc3NyUmVuZGVyU3R5bGUocmF3KSB7DQogIGlmICghcmF3KSB7DQogICAgcmV0dXJuICIiOw0KICB9DQogIGlmIChpc1N0cmluZyhyYXcpKSB7DQogICAgcmV0dXJuIGVzY2FwZUh0bWwocmF3KTsNCiAgfQ0KICBjb25zdCBzdHlsZXMgPSBub3JtYWxpemVTdHlsZShyYXcpOw0KICByZXR1cm4gZXNjYXBlSHRtbChzdHJpbmdpZnlTdHlsZShzdHlsZXMpKTsNCn0NCg0KZnVuY3Rpb24gc3NyUmVuZGVyQ29tcG9uZW50KGNvbXAsIHByb3BzID0gbnVsbCwgY2hpbGRyZW4gPSBudWxsLCBwYXJlbnRDb21wb25lbnQgPSBudWxsLCBzbG90U2NvcGVJZCkgew0KICByZXR1cm4gcmVuZGVyQ29tcG9uZW50Vk5vZGUoDQogICAgY3JlYXRlVk5vZGUoY29tcCwgcHJvcHMsIGNoaWxkcmVuKSwNCiAgICBwYXJlbnRDb21wb25lbnQsDQogICAgc2xvdFNjb3BlSWQNCiAgKTsNCn0NCg0KY29uc3QgeyBlbnN1cmVWYWxpZFZOb2RlIH0gPSBzc3JVdGlsczsNCmZ1bmN0aW9uIHNzclJlbmRlclNsb3Qoc2xvdHMsIHNsb3ROYW1lLCBzbG90UHJvcHMsIGZhbGxiYWNrUmVuZGVyRm4sIHB1c2gsIHBhcmVudENvbXBvbmVudCwgc2xvdFNjb3BlSWQpIHsNCiAgcHVzaChgPCEtLVstLT5gKTsNCiAgc3NyUmVuZGVyU2xvdElubmVyKA0KICAgIHNsb3RzLA0KICAgIHNsb3ROYW1lLA0KICAgIHNsb3RQcm9wcywNCiAgICBmYWxsYmFja1JlbmRlckZuLA0KICAgIHB1c2gsDQogICAgcGFyZW50Q29tcG9uZW50LA0KICAgIHNsb3RTY29wZUlkDQogICk7DQogIHB1c2goYDwhLS1dLS0+YCk7DQp9DQpmdW5jdGlvbiBzc3JSZW5kZXJTbG90SW5uZXIoc2xvdHMsIHNsb3ROYW1lLCBzbG90UHJvcHMsIGZhbGxiYWNrUmVuZGVyRm4sIHB1c2gsIHBhcmVudENvbXBvbmVudCwgc2xvdFNjb3BlSWQsIHRyYW5zaXRpb24pIHsNCiAgY29uc3Qgc2xvdEZuID0gc2xvdHNbc2xvdE5hbWVdOw0KICBpZiAoc2xvdEZuKSB7DQogICAgY29uc3Qgc2xvdEJ1ZmZlciA9IFtdOw0KICAgIGNvbnN0IGJ1ZmZlcmVkUHVzaCA9IChpdGVtKSA9PiB7DQogICAgICBzbG90QnVmZmVyLnB1c2goaXRlbSk7DQogICAgfTsNCiAgICBjb25zdCByZXQgPSBzbG90Rm4oDQogICAgICBzbG90UHJvcHMsDQogICAgICBidWZmZXJlZFB1c2gsDQogICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICBzbG90U2NvcGVJZCA/ICIgIiArIHNsb3RTY29wZUlkIDogIiINCiAgICApOw0KICAgIGlmIChpc0FycmF5KHJldCkpIHsNCiAgICAgIGNvbnN0IHZhbGlkU2xvdENvbnRlbnQgPSBlbnN1cmVWYWxpZFZOb2RlKHJldCk7DQogICAgICBpZiAodmFsaWRTbG90Q29udGVudCkgew0KICAgICAgICByZW5kZXJWTm9kZUNoaWxkcmVuKA0KICAgICAgICAgIHB1c2gsDQogICAgICAgICAgdmFsaWRTbG90Q29udGVudCwNCiAgICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgICAgc2xvdFNjb3BlSWQNCiAgICAgICAgKTsNCiAgICAgIH0gZWxzZSBpZiAoZmFsbGJhY2tSZW5kZXJGbikgew0KICAgICAgICBmYWxsYmFja1JlbmRlckZuKCk7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIGxldCBpc0VtcHR5U2xvdCA9IHRydWU7DQogICAgICBpZiAodHJhbnNpdGlvbikgew0KICAgICAgICBpc0VtcHR5U2xvdCA9IGZhbHNlOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbG90QnVmZmVyLmxlbmd0aDsgaSsrKSB7DQogICAgICAgICAgaWYgKCFpc0NvbW1lbnQoc2xvdEJ1ZmZlcltpXSkpIHsNCiAgICAgICAgICAgIGlzRW1wdHlTbG90ID0gZmFsc2U7DQogICAgICAgICAgICBicmVhazsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGlmIChpc0VtcHR5U2xvdCkgew0KICAgICAgICBpZiAoZmFsbGJhY2tSZW5kZXJGbikgew0KICAgICAgICAgIGZhbGxiYWNrUmVuZGVyRm4oKTsNCiAgICAgICAgfQ0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgbGV0IHN0YXJ0ID0gMDsNCiAgICAgICAgbGV0IGVuZCA9IHNsb3RCdWZmZXIubGVuZ3RoOw0KICAgICAgICBpZiAodHJhbnNpdGlvbiAmJiBzbG90QnVmZmVyWzBdID09PSAiPCEtLVstLT4iICYmIHNsb3RCdWZmZXJbZW5kIC0gMV0gPT09ICI8IS0tXS0tPiIpIHsNCiAgICAgICAgICBzdGFydCsrOw0KICAgICAgICAgIGVuZC0tOw0KICAgICAgICB9DQogICAgICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7DQogICAgICAgICAgcHVzaChzbG90QnVmZmVyW2ldKTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgfSBlbHNlIGlmIChmYWxsYmFja1JlbmRlckZuKSB7DQogICAgZmFsbGJhY2tSZW5kZXJGbigpOw0KICB9DQp9DQpjb25zdCBjb21tZW50VGVzdFJFID0gL148IS0tW1xzXFNdKi0tPiQvOw0KY29uc3QgY29tbWVudFJFID0gLzwhLS1bXl0qPy0tPi9nbTsNCmZ1bmN0aW9uIGlzQ29tbWVudChpdGVtKSB7DQogIGlmICh0eXBlb2YgaXRlbSAhPT0gInN0cmluZyIgfHwgIWNvbW1lbnRUZXN0UkUudGVzdChpdGVtKSkgcmV0dXJuIGZhbHNlOw0KICBpZiAoaXRlbS5sZW5ndGggPD0gOCkgcmV0dXJuIHRydWU7DQogIHJldHVybiAhaXRlbS5yZXBsYWNlKGNvbW1lbnRSRSwgIiIpLnRyaW0oKTsNCn0NCg0KZnVuY3Rpb24gc3NyUmVuZGVyVGVsZXBvcnQocGFyZW50UHVzaCwgY29udGVudFJlbmRlckZuLCB0YXJnZXQsIGRpc2FibGVkLCBwYXJlbnRDb21wb25lbnQpIHsNCiAgcGFyZW50UHVzaCgiPCEtLXRlbGVwb3J0IHN0YXJ0LS0+Iik7DQogIGNvbnN0IGNvbnRleHQgPSBwYXJlbnRDb21wb25lbnQuYXBwQ29udGV4dC5wcm92aWRlc1tzc3JDb250ZXh0S2V5XTsNCiAgY29uc3QgdGVsZXBvcnRCdWZmZXJzID0gY29udGV4dC5fX3RlbGVwb3J0QnVmZmVycyB8fCAoY29udGV4dC5fX3RlbGVwb3J0QnVmZmVycyA9IHt9KTsNCiAgY29uc3QgdGFyZ2V0QnVmZmVyID0gdGVsZXBvcnRCdWZmZXJzW3RhcmdldF0gfHwgKHRlbGVwb3J0QnVmZmVyc1t0YXJnZXRdID0gW10pOw0KICBjb25zdCBidWZmZXJJbmRleCA9IHRhcmdldEJ1ZmZlci5sZW5ndGg7DQogIGxldCB0ZWxlcG9ydENvbnRlbnQ7DQogIGlmIChkaXNhYmxlZCkgew0KICAgIGNvbnRlbnRSZW5kZXJGbihwYXJlbnRQdXNoKTsNCiAgICB0ZWxlcG9ydENvbnRlbnQgPSBgPCEtLXRlbGVwb3J0IHN0YXJ0IGFuY2hvci0tPjwhLS10ZWxlcG9ydCBhbmNob3ItLT5gOw0KICB9IGVsc2Ugew0KICAgIGNvbnN0IHsgZ2V0QnVmZmVyLCBwdXNoIH0gPSBjcmVhdGVCdWZmZXIoKTsNCiAgICBwdXNoKGA8IS0tdGVsZXBvcnQgc3RhcnQgYW5jaG9yLS0+YCk7DQogICAgY29udGVudFJlbmRlckZuKHB1c2gpOw0KICAgIHB1c2goYDwhLS10ZWxlcG9ydCBhbmNob3ItLT5gKTsNCiAgICB0ZWxlcG9ydENvbnRlbnQgPSBnZXRCdWZmZXIoKTsNCiAgfQ0KICB0YXJnZXRCdWZmZXIuc3BsaWNlKGJ1ZmZlckluZGV4LCAwLCB0ZWxlcG9ydENvbnRlbnQpOw0KICBwYXJlbnRQdXNoKCI8IS0tdGVsZXBvcnQgZW5kLS0+Iik7DQp9DQoNCmZ1bmN0aW9uIHNzckludGVycG9sYXRlKHZhbHVlKSB7DQogIHJldHVybiBlc2NhcGVIdG1sKHRvRGlzcGxheVN0cmluZyh2YWx1ZSkpOw0KfQ0KDQpmdW5jdGlvbiBzc3JSZW5kZXJMaXN0KHNvdXJjZSwgcmVuZGVySXRlbSkgew0KICBpZiAoaXNBcnJheShzb3VyY2UpIHx8IGlzU3RyaW5nKHNvdXJjZSkpIHsNCiAgICBmb3IgKGxldCBpID0gMCwgbCA9IHNvdXJjZS5sZW5ndGg7IGkgPCBsOyBpKyspIHsNCiAgICAgIHJlbmRlckl0ZW0oc291cmNlW2ldLCBpKTsNCiAgICB9DQogIH0gZWxzZSBpZiAodHlwZW9mIHNvdXJjZSA9PT0gIm51bWJlciIpIHsNCiAgICBpZiAoIU51bWJlci5pc0ludGVnZXIoc291cmNlKSkgew0KICAgICAgd2FybihgVGhlIHYtZm9yIHJhbmdlIGV4cGVjdCBhbiBpbnRlZ2VyIHZhbHVlIGJ1dCBnb3QgJHtzb3VyY2V9LmApOw0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNvdXJjZTsgaSsrKSB7DQogICAgICByZW5kZXJJdGVtKGkgKyAxLCBpKTsNCiAgICB9DQogIH0gZWxzZSBpZiAoaXNPYmplY3Qoc291cmNlKSkgew0KICAgIGlmIChzb3VyY2VbU3ltYm9sLml0ZXJhdG9yXSkgew0KICAgICAgY29uc3QgYXJyID0gQXJyYXkuZnJvbShzb3VyY2UpOw0KICAgICAgZm9yIChsZXQgaSA9IDAsIGwgPSBhcnIubGVuZ3RoOyBpIDwgbDsgaSsrKSB7DQogICAgICAgIHJlbmRlckl0ZW0oYXJyW2ldLCBpKTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KICAgICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHNvdXJjZSk7DQogICAgICBmb3IgKGxldCBpID0gMCwgbCA9IGtleXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7DQogICAgICAgIGNvbnN0IGtleSA9IGtleXNbaV07DQogICAgICAgIHJlbmRlckl0ZW0oc291cmNlW2tleV0sIGtleSwgaSk7DQogICAgICB9DQogICAgfQ0KICB9DQp9DQoNCmFzeW5jIGZ1bmN0aW9uIHNzclJlbmRlclN1c3BlbnNlKHB1c2gsIHsgZGVmYXVsdDogcmVuZGVyQ29udGVudCB9KSB7DQogIGlmIChyZW5kZXJDb250ZW50KSB7DQogICAgcmVuZGVyQ29udGVudCgpOw0KICB9IGVsc2Ugew0KICAgIHB1c2goYDwhLS0tLT5gKTsNCiAgfQ0KfQ0KDQpmdW5jdGlvbiBzc3JHZXREaXJlY3RpdmVQcm9wcyhpbnN0YW5jZSwgZGlyLCB2YWx1ZSwgYXJnLCBtb2RpZmllcnMgPSB7fSkgew0KICBpZiAodHlwZW9mIGRpciAhPT0gImZ1bmN0aW9uIiAmJiBkaXIuZ2V0U1NSUHJvcHMpIHsNCiAgICByZXR1cm4gZGlyLmdldFNTUlByb3BzKA0KICAgICAgew0KICAgICAgICBkaXIsDQogICAgICAgIGluc3RhbmNlOiBzc3JVdGlscy5nZXRDb21wb25lbnRQdWJsaWNJbnN0YW5jZShpbnN0YW5jZS4kKSwNCiAgICAgICAgdmFsdWUsDQogICAgICAgIG9sZFZhbHVlOiB2b2lkIDAsDQogICAgICAgIGFyZywNCiAgICAgICAgbW9kaWZpZXJzDQogICAgICB9LA0KICAgICAgbnVsbA0KICAgICkgfHwge307DQogIH0NCiAgcmV0dXJuIHt9Ow0KfQ0KDQpjb25zdCBzc3JMb29zZUVxdWFsID0gbG9vc2VFcXVhbDsNCmZ1bmN0aW9uIHNzckxvb3NlQ29udGFpbihhcnIsIHZhbHVlKSB7DQogIHJldHVybiBsb29zZUluZGV4T2YoYXJyLCB2YWx1ZSkgPiAtMTsNCn0NCmZ1bmN0aW9uIHNzclJlbmRlckR5bmFtaWNNb2RlbCh0eXBlLCBtb2RlbCwgdmFsdWUpIHsNCiAgc3dpdGNoICh0eXBlKSB7DQogICAgY2FzZSAicmFkaW8iOg0KICAgICAgcmV0dXJuIGxvb3NlRXF1YWwobW9kZWwsIHZhbHVlKSA/ICIgY2hlY2tlZCIgOiAiIjsNCiAgICBjYXNlICJjaGVja2JveCI6DQogICAgICByZXR1cm4gKGlzQXJyYXkobW9kZWwpID8gc3NyTG9vc2VDb250YWluKG1vZGVsLCB2YWx1ZSkgOiBtb2RlbCkgPyAiIGNoZWNrZWQiIDogIiI7DQogICAgZGVmYXVsdDoNCiAgICAgIHJldHVybiBzc3JSZW5kZXJBdHRyKCJ2YWx1ZSIsIG1vZGVsKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gc3NyR2V0RHluYW1pY01vZGVsUHJvcHMoZXhpc3RpbmdQcm9wcyA9IHt9LCBtb2RlbCkgew0KICBjb25zdCB7IHR5cGUsIHZhbHVlIH0gPSBleGlzdGluZ1Byb3BzOw0KICBzd2l0Y2ggKHR5cGUpIHsNCiAgICBjYXNlICJyYWRpbyI6DQogICAgICByZXR1cm4gbG9vc2VFcXVhbChtb2RlbCwgdmFsdWUpID8geyBjaGVja2VkOiB0cnVlIH0gOiBudWxsOw0KICAgIGNhc2UgImNoZWNrYm94IjoNCiAgICAgIHJldHVybiAoaXNBcnJheShtb2RlbCkgPyBzc3JMb29zZUNvbnRhaW4obW9kZWwsIHZhbHVlKSA6IG1vZGVsKSA/IHsgY2hlY2tlZDogdHJ1ZSB9IDogbnVsbDsNCiAgICBkZWZhdWx0Og0KICAgICAgcmV0dXJuIHsgdmFsdWU6IG1vZGVsIH07DQogIH0NCn0NCg0KZnVuY3Rpb24gc3NyQ29tcGlsZSh0ZW1wbGF0ZSwgaW5zdGFuY2UpIHsNCiAgew0KICAgIHRocm93IG5ldyBFcnJvcigNCiAgICAgIGBPbi10aGUtZmx5IHRlbXBsYXRlIGNvbXBpbGF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgaW4gdGhlIEVTTSBidWlsZCBvZiBAdnVlL3NlcnZlci1yZW5kZXJlci4gQWxsIHRlbXBsYXRlcyBtdXN0IGJlIHByZS1jb21waWxlZCBpbnRvIHJlbmRlciBmdW5jdGlvbnMuYA0KICAgICk7DQogIH0NCn0NCg0KY29uc3Qgew0KICBjcmVhdGVDb21wb25lbnRJbnN0YW5jZSwNCiAgc2V0Q3VycmVudFJlbmRlcmluZ0luc3RhbmNlLA0KICBzZXR1cENvbXBvbmVudCwNCiAgcmVuZGVyQ29tcG9uZW50Um9vdCwNCiAgbm9ybWFsaXplVk5vZGUsDQogIHB1c2hXYXJuaW5nQ29udGV4dCwNCiAgcG9wV2FybmluZ0NvbnRleHQNCn0gPSBzc3JVdGlsczsNCmZ1bmN0aW9uIGNyZWF0ZUJ1ZmZlcigpIHsNCiAgbGV0IGFwcGVuZGFibGUgPSBmYWxzZTsNCiAgY29uc3QgYnVmZmVyID0gW107DQogIHJldHVybiB7DQogICAgZ2V0QnVmZmVyKCkgew0KICAgICAgcmV0dXJuIGJ1ZmZlcjsNCiAgICB9LA0KICAgIHB1c2goaXRlbSkgew0KICAgICAgY29uc3QgaXNTdHJpbmdJdGVtID0gaXNTdHJpbmcoaXRlbSk7DQogICAgICBpZiAoYXBwZW5kYWJsZSAmJiBpc1N0cmluZ0l0ZW0pIHsNCiAgICAgICAgYnVmZmVyW2J1ZmZlci5sZW5ndGggLSAxXSArPSBpdGVtOw0KICAgICAgICByZXR1cm47DQogICAgICB9DQogICAgICBidWZmZXIucHVzaChpdGVtKTsNCiAgICAgIGFwcGVuZGFibGUgPSBpc1N0cmluZ0l0ZW07DQogICAgICBpZiAoaXNQcm9taXNlKGl0ZW0pIHx8IGlzQXJyYXkoaXRlbSkgJiYgaXRlbS5oYXNBc3luYykgew0KICAgICAgICBidWZmZXIuaGFzQXN5bmMgPSB0cnVlOw0KICAgICAgfQ0KICAgIH0NCiAgfTsNCn0NCmZ1bmN0aW9uIHJlbmRlckNvbXBvbmVudFZOb2RlKHZub2RlLCBwYXJlbnRDb21wb25lbnQgPSBudWxsLCBzbG90U2NvcGVJZCkgew0KICBjb25zdCBpbnN0YW5jZSA9IHZub2RlLmNvbXBvbmVudCA9IGNyZWF0ZUNvbXBvbmVudEluc3RhbmNlKA0KICAgIHZub2RlLA0KICAgIHBhcmVudENvbXBvbmVudCwNCiAgICBudWxsDQogICk7DQogIHB1c2hXYXJuaW5nQ29udGV4dCh2bm9kZSk7DQogIGNvbnN0IHJlcyA9IHNldHVwQ29tcG9uZW50KA0KICAgIGluc3RhbmNlLA0KICAgIHRydWUNCiAgICAvKiBpc1NTUiAqLw0KICApOw0KICBwb3BXYXJuaW5nQ29udGV4dCgpOw0KICBjb25zdCBoYXNBc3luY1NldHVwID0gaXNQcm9taXNlKHJlcyk7DQogIGxldCBwcmVmZXRjaGVzID0gaW5zdGFuY2Uuc3A7DQogIGlmIChoYXNBc3luY1NldHVwIHx8IHByZWZldGNoZXMpIHsNCiAgICBjb25zdCBwID0gUHJvbWlzZS5yZXNvbHZlKHJlcykudGhlbigoKSA9PiB7DQogICAgICBpZiAoaGFzQXN5bmNTZXR1cCkgcHJlZmV0Y2hlcyA9IGluc3RhbmNlLnNwOw0KICAgICAgaWYgKHByZWZldGNoZXMpIHsNCiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKA0KICAgICAgICAgIHByZWZldGNoZXMubWFwKChwcmVmZXRjaCkgPT4gcHJlZmV0Y2guY2FsbChpbnN0YW5jZS5wcm94eSkpDQogICAgICAgICk7DQogICAgICB9DQogICAgfSkuY2F0Y2goTk9PUCk7DQogICAgcmV0dXJuIHAudGhlbigoKSA9PiByZW5kZXJDb21wb25lbnRTdWJUcmVlKGluc3RhbmNlLCBzbG90U2NvcGVJZCkpOw0KICB9IGVsc2Ugew0KICAgIHJldHVybiByZW5kZXJDb21wb25lbnRTdWJUcmVlKGluc3RhbmNlLCBzbG90U2NvcGVJZCk7DQogIH0NCn0NCmZ1bmN0aW9uIHJlbmRlckNvbXBvbmVudFN1YlRyZWUoaW5zdGFuY2UsIHNsb3RTY29wZUlkKSB7DQogIHB1c2hXYXJuaW5nQ29udGV4dChpbnN0YW5jZS52bm9kZSk7DQogIGNvbnN0IGNvbXAgPSBpbnN0YW5jZS50eXBlOw0KICBjb25zdCB7IGdldEJ1ZmZlciwgcHVzaCB9ID0gY3JlYXRlQnVmZmVyKCk7DQogIGlmIChpc0Z1bmN0aW9uKGNvbXApKSB7DQogICAgbGV0IHJvb3QgPSByZW5kZXJDb21wb25lbnRSb290KGluc3RhbmNlKTsNCiAgICBpZiAoIWNvbXAucHJvcHMpIHsNCiAgICAgIGZvciAoY29uc3Qga2V5IGluIGluc3RhbmNlLmF0dHJzKSB7DQogICAgICAgIGlmIChrZXkuc3RhcnRzV2l0aChgZGF0YS12LWApKSB7DQogICAgICAgICAgKHJvb3QucHJvcHMgfHwgKHJvb3QucHJvcHMgPSB7fSkpW2tleV0gPSBgYDsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCiAgICByZW5kZXJWTm9kZShwdXNoLCBpbnN0YW5jZS5zdWJUcmVlID0gcm9vdCwgaW5zdGFuY2UsIHNsb3RTY29wZUlkKTsNCiAgfSBlbHNlIHsNCiAgICBpZiAoKCFpbnN0YW5jZS5yZW5kZXIgfHwgaW5zdGFuY2UucmVuZGVyID09PSBOT09QKSAmJiAhaW5zdGFuY2Uuc3NyUmVuZGVyICYmICFjb21wLnNzclJlbmRlciAmJiBpc1N0cmluZyhjb21wLnRlbXBsYXRlKSkgew0KICAgICAgY29tcC5zc3JSZW5kZXIgPSBzc3JDb21waWxlKGNvbXAudGVtcGxhdGUpOw0KICAgIH0NCiAgICBjb25zdCBzc3JSZW5kZXIgPSBpbnN0YW5jZS5zc3JSZW5kZXIgfHwgY29tcC5zc3JSZW5kZXI7DQogICAgaWYgKHNzclJlbmRlcikgew0KICAgICAgbGV0IGF0dHJzID0gaW5zdGFuY2UuaW5oZXJpdEF0dHJzICE9PSBmYWxzZSA/IGluc3RhbmNlLmF0dHJzIDogdm9pZCAwOw0KICAgICAgbGV0IGhhc0Nsb25lZCA9IGZhbHNlOw0KICAgICAgbGV0IGN1ciA9IGluc3RhbmNlOw0KICAgICAgd2hpbGUgKHRydWUpIHsNCiAgICAgICAgY29uc3Qgc2NvcGVJZCA9IGN1ci52bm9kZS5zY29wZUlkOw0KICAgICAgICBpZiAoc2NvcGVJZCkgew0KICAgICAgICAgIGlmICghaGFzQ2xvbmVkKSB7DQogICAgICAgICAgICBhdHRycyA9IHsgLi4uYXR0cnMgfTsNCiAgICAgICAgICAgIGhhc0Nsb25lZCA9IHRydWU7DQogICAgICAgICAgfQ0KICAgICAgICAgIGF0dHJzW3Njb3BlSWRdID0gIiI7DQogICAgICAgIH0NCiAgICAgICAgY29uc3QgcGFyZW50ID0gY3VyLnBhcmVudDsNCiAgICAgICAgaWYgKHBhcmVudCAmJiBwYXJlbnQuc3ViVHJlZSAmJiBwYXJlbnQuc3ViVHJlZSA9PT0gY3VyLnZub2RlKSB7DQogICAgICAgICAgY3VyID0gcGFyZW50Ow0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIGJyZWFrOw0KICAgICAgICB9DQogICAgICB9DQogICAgICBpZiAoc2xvdFNjb3BlSWQpIHsNCiAgICAgICAgaWYgKCFoYXNDbG9uZWQpIGF0dHJzID0geyAuLi5hdHRycyB9Ow0KICAgICAgICBjb25zdCBzbG90U2NvcGVJZExpc3QgPSBzbG90U2NvcGVJZC50cmltKCkuc3BsaXQoIiAiKTsNCiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbG90U2NvcGVJZExpc3QubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgICBhdHRyc1tzbG90U2NvcGVJZExpc3RbaV1dID0gIiI7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgIGNvbnN0IHByZXYgPSBzZXRDdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UoaW5zdGFuY2UpOw0KICAgICAgdHJ5IHsNCiAgICAgICAgc3NyUmVuZGVyKA0KICAgICAgICAgIGluc3RhbmNlLnByb3h5LA0KICAgICAgICAgIHB1c2gsDQogICAgICAgICAgaW5zdGFuY2UsDQogICAgICAgICAgYXR0cnMsDQogICAgICAgICAgLy8gY29tcGlsZXItb3B0aW1pemVkIGJpbmRpbmdzDQogICAgICAgICAgaW5zdGFuY2UucHJvcHMsDQogICAgICAgICAgaW5zdGFuY2Uuc2V0dXBTdGF0ZSwNCiAgICAgICAgICBpbnN0YW5jZS5kYXRhLA0KICAgICAgICAgIGluc3RhbmNlLmN0eA0KICAgICAgICApOw0KICAgICAgfSBmaW5hbGx5IHsNCiAgICAgICAgc2V0Q3VycmVudFJlbmRlcmluZ0luc3RhbmNlKHByZXYpOw0KICAgICAgfQ0KICAgIH0gZWxzZSBpZiAoaW5zdGFuY2UucmVuZGVyICYmIGluc3RhbmNlLnJlbmRlciAhPT0gTk9PUCkgew0KICAgICAgcmVuZGVyVk5vZGUoDQogICAgICAgIHB1c2gsDQogICAgICAgIGluc3RhbmNlLnN1YlRyZWUgPSByZW5kZXJDb21wb25lbnRSb290KGluc3RhbmNlKSwNCiAgICAgICAgaW5zdGFuY2UsDQogICAgICAgIHNsb3RTY29wZUlkDQogICAgICApOw0KICAgIH0gZWxzZSB7DQogICAgICBjb25zdCBjb21wb25lbnROYW1lID0gY29tcC5uYW1lIHx8IGNvbXAuX19maWxlIHx8IGA8QW5vbnltb3VzPmA7DQogICAgICB3YXJuKGBDb21wb25lbnQgJHtjb21wb25lbnROYW1lfSBpcyBtaXNzaW5nIHRlbXBsYXRlIG9yIHJlbmRlciBmdW5jdGlvbi5gKTsNCiAgICAgIHB1c2goYDwhLS0tLT5gKTsNCiAgICB9DQogIH0NCiAgcG9wV2FybmluZ0NvbnRleHQoKTsNCiAgcmV0dXJuIGdldEJ1ZmZlcigpOw0KfQ0KZnVuY3Rpb24gcmVuZGVyVk5vZGUocHVzaCwgdm5vZGUsIHBhcmVudENvbXBvbmVudCwgc2xvdFNjb3BlSWQpIHsNCiAgY29uc3QgeyB0eXBlLCBzaGFwZUZsYWcsIGNoaWxkcmVuLCBkaXJzLCBwcm9wcyB9ID0gdm5vZGU7DQogIGlmIChkaXJzKSB7DQogICAgdm5vZGUucHJvcHMgPSBhcHBseVNTUkRpcmVjdGl2ZXModm5vZGUsIHByb3BzLCBkaXJzKTsNCiAgfQ0KICBzd2l0Y2ggKHR5cGUpIHsNCiAgICBjYXNlIFRleHQ6DQogICAgICBwdXNoKGVzY2FwZUh0bWwoY2hpbGRyZW4pKTsNCiAgICAgIGJyZWFrOw0KICAgIGNhc2UgQ29tbWVudDoNCiAgICAgIHB1c2goDQogICAgICAgIGNoaWxkcmVuID8gYDwhLS0ke2VzY2FwZUh0bWxDb21tZW50KGNoaWxkcmVuKX0tLT5gIDogYDwhLS0tLT5gDQogICAgICApOw0KICAgICAgYnJlYWs7DQogICAgY2FzZSBTdGF0aWM6DQogICAgICBwdXNoKGNoaWxkcmVuKTsNCiAgICAgIGJyZWFrOw0KICAgIGNhc2UgRnJhZ21lbnQ6DQogICAgICBpZiAodm5vZGUuc2xvdFNjb3BlSWRzKSB7DQogICAgICAgIHNsb3RTY29wZUlkID0gKHNsb3RTY29wZUlkID8gc2xvdFNjb3BlSWQgKyAiICIgOiAiIikgKyB2bm9kZS5zbG90U2NvcGVJZHMuam9pbigiICIpOw0KICAgICAgfQ0KICAgICAgcHVzaChgPCEtLVstLT5gKTsNCiAgICAgIHJlbmRlclZOb2RlQ2hpbGRyZW4oDQogICAgICAgIHB1c2gsDQogICAgICAgIGNoaWxkcmVuLA0KICAgICAgICBwYXJlbnRDb21wb25lbnQsDQogICAgICAgIHNsb3RTY29wZUlkDQogICAgICApOw0KICAgICAgcHVzaChgPCEtLV0tLT5gKTsNCiAgICAgIGJyZWFrOw0KICAgIGRlZmF1bHQ6DQogICAgICBpZiAoc2hhcGVGbGFnICYgMSkgew0KICAgICAgICByZW5kZXJFbGVtZW50Vk5vZGUocHVzaCwgdm5vZGUsIHBhcmVudENvbXBvbmVudCwgc2xvdFNjb3BlSWQpOw0KICAgICAgfSBlbHNlIGlmIChzaGFwZUZsYWcgJiA2KSB7DQogICAgICAgIHB1c2gocmVuZGVyQ29tcG9uZW50Vk5vZGUodm5vZGUsIHBhcmVudENvbXBvbmVudCwgc2xvdFNjb3BlSWQpKTsNCiAgICAgIH0gZWxzZSBpZiAoc2hhcGVGbGFnICYgNjQpIHsNCiAgICAgICAgcmVuZGVyVGVsZXBvcnRWTm9kZShwdXNoLCB2bm9kZSwgcGFyZW50Q29tcG9uZW50LCBzbG90U2NvcGVJZCk7DQogICAgICB9IGVsc2UgaWYgKHNoYXBlRmxhZyAmIDEyOCkgew0KICAgICAgICByZW5kZXJWTm9kZShwdXNoLCB2bm9kZS5zc0NvbnRlbnQsIHBhcmVudENvbXBvbmVudCwgc2xvdFNjb3BlSWQpOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgd2FybigNCiAgICAgICAgICAiW0B2dWUvc2VydmVyLXJlbmRlcmVyXSBJbnZhbGlkIFZOb2RlIHR5cGU6IiwNCiAgICAgICAgICB0eXBlLA0KICAgICAgICAgIGAoJHt0eXBlb2YgdHlwZX0pYA0KICAgICAgICApOw0KICAgICAgfQ0KICB9DQp9DQpmdW5jdGlvbiByZW5kZXJWTm9kZUNoaWxkcmVuKHB1c2gsIGNoaWxkcmVuLCBwYXJlbnRDb21wb25lbnQsIHNsb3RTY29wZUlkKSB7DQogIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHsNCiAgICByZW5kZXJWTm9kZShwdXNoLCBub3JtYWxpemVWTm9kZShjaGlsZHJlbltpXSksIHBhcmVudENvbXBvbmVudCwgc2xvdFNjb3BlSWQpOw0KICB9DQp9DQpmdW5jdGlvbiByZW5kZXJFbGVtZW50Vk5vZGUocHVzaCwgdm5vZGUsIHBhcmVudENvbXBvbmVudCwgc2xvdFNjb3BlSWQpIHsNCiAgY29uc3QgdGFnID0gdm5vZGUudHlwZTsNCiAgbGV0IHsgcHJvcHMsIGNoaWxkcmVuLCBzaGFwZUZsYWcsIHNjb3BlSWQgfSA9IHZub2RlOw0KICBsZXQgb3BlblRhZyA9IGA8JHt0YWd9YDsNCiAgaWYgKHByb3BzKSB7DQogICAgb3BlblRhZyArPSBzc3JSZW5kZXJBdHRycyhwcm9wcywgdGFnKTsNCiAgfQ0KICBpZiAoc2NvcGVJZCkgew0KICAgIG9wZW5UYWcgKz0gYCAke3Njb3BlSWR9YDsNCiAgfQ0KICBsZXQgY3VyUGFyZW50ID0gcGFyZW50Q29tcG9uZW50Ow0KICBsZXQgY3VyVm5vZGUgPSB2bm9kZTsNCiAgd2hpbGUgKGN1clBhcmVudCAmJiBjdXJWbm9kZSA9PT0gY3VyUGFyZW50LnN1YlRyZWUpIHsNCiAgICBjdXJWbm9kZSA9IGN1clBhcmVudC52bm9kZTsNCiAgICBpZiAoY3VyVm5vZGUuc2NvcGVJZCkgew0KICAgICAgb3BlblRhZyArPSBgICR7Y3VyVm5vZGUuc2NvcGVJZH1gOw0KICAgIH0NCiAgICBjdXJQYXJlbnQgPSBjdXJQYXJlbnQucGFyZW50Ow0KICB9DQogIGlmIChzbG90U2NvcGVJZCkgew0KICAgIG9wZW5UYWcgKz0gYCAke3Nsb3RTY29wZUlkfWA7DQogIH0NCiAgcHVzaChvcGVuVGFnICsgYD5gKTsNCiAgaWYgKCFpc1ZvaWRUYWcodGFnKSkgew0KICAgIGxldCBoYXNDaGlsZHJlbk92ZXJyaWRlID0gZmFsc2U7DQogICAgaWYgKHByb3BzKSB7DQogICAgICBpZiAocHJvcHMuaW5uZXJIVE1MKSB7DQogICAgICAgIGhhc0NoaWxkcmVuT3ZlcnJpZGUgPSB0cnVlOw0KICAgICAgICBwdXNoKHByb3BzLmlubmVySFRNTCk7DQogICAgICB9IGVsc2UgaWYgKHByb3BzLnRleHRDb250ZW50KSB7DQogICAgICAgIGhhc0NoaWxkcmVuT3ZlcnJpZGUgPSB0cnVlOw0KICAgICAgICBwdXNoKGVzY2FwZUh0bWwocHJvcHMudGV4dENvbnRlbnQpKTsNCiAgICAgIH0gZWxzZSBpZiAodGFnID09PSAidGV4dGFyZWEiICYmIHByb3BzLnZhbHVlKSB7DQogICAgICAgIGhhc0NoaWxkcmVuT3ZlcnJpZGUgPSB0cnVlOw0KICAgICAgICBwdXNoKGVzY2FwZUh0bWwocHJvcHMudmFsdWUpKTsNCiAgICAgIH0NCiAgICB9DQogICAgaWYgKCFoYXNDaGlsZHJlbk92ZXJyaWRlKSB7DQogICAgICBpZiAoc2hhcGVGbGFnICYgOCkgew0KICAgICAgICBwdXNoKGVzY2FwZUh0bWwoY2hpbGRyZW4pKTsNCiAgICAgIH0gZWxzZSBpZiAoc2hhcGVGbGFnICYgMTYpIHsNCiAgICAgICAgcmVuZGVyVk5vZGVDaGlsZHJlbigNCiAgICAgICAgICBwdXNoLA0KICAgICAgICAgIGNoaWxkcmVuLA0KICAgICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgICBzbG90U2NvcGVJZA0KICAgICAgICApOw0KICAgICAgfQ0KICAgIH0NCiAgICBwdXNoKGA8LyR7dGFnfT5gKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gYXBwbHlTU1JEaXJlY3RpdmVzKHZub2RlLCByYXdQcm9wcywgZGlycykgew0KICBjb25zdCB0b01lcmdlID0gW107DQogIGZvciAobGV0IGkgPSAwOyBpIDwgZGlycy5sZW5ndGg7IGkrKykgew0KICAgIGNvbnN0IGJpbmRpbmcgPSBkaXJzW2ldOw0KICAgIGNvbnN0IHsNCiAgICAgIGRpcjogeyBnZXRTU1JQcm9wcyB9DQogICAgfSA9IGJpbmRpbmc7DQogICAgaWYgKGdldFNTUlByb3BzKSB7DQogICAgICBjb25zdCBwcm9wcyA9IGdldFNTUlByb3BzKGJpbmRpbmcsIHZub2RlKTsNCiAgICAgIGlmIChwcm9wcykgdG9NZXJnZS5wdXNoKHByb3BzKTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIG1lcmdlUHJvcHMocmF3UHJvcHMgfHwge30sIC4uLnRvTWVyZ2UpOw0KfQ0KZnVuY3Rpb24gcmVuZGVyVGVsZXBvcnRWTm9kZShwdXNoLCB2bm9kZSwgcGFyZW50Q29tcG9uZW50LCBzbG90U2NvcGVJZCkgew0KICBjb25zdCB0YXJnZXQgPSB2bm9kZS5wcm9wcyAmJiB2bm9kZS5wcm9wcy50bzsNCiAgY29uc3QgZGlzYWJsZWQgPSB2bm9kZS5wcm9wcyAmJiB2bm9kZS5wcm9wcy5kaXNhYmxlZDsNCiAgaWYgKCF0YXJnZXQpIHsNCiAgICBpZiAoIWRpc2FibGVkKSB7DQogICAgICB3YXJuKGBbQHZ1ZS9zZXJ2ZXItcmVuZGVyZXJdIFRlbGVwb3J0IGlzIG1pc3NpbmcgdGFyZ2V0IHByb3AuYCk7DQogICAgfQ0KICAgIHJldHVybiBbXTsNCiAgfQ0KICBpZiAoIWlzU3RyaW5nKHRhcmdldCkpIHsNCiAgICB3YXJuKA0KICAgICAgYFtAdnVlL3NlcnZlci1yZW5kZXJlcl0gVGVsZXBvcnQgdGFyZ2V0IG11c3QgYmUgYSBxdWVyeSBzZWxlY3RvciBzdHJpbmcuYA0KICAgICk7DQogICAgcmV0dXJuIFtdOw0KICB9DQogIHNzclJlbmRlclRlbGVwb3J0KA0KICAgIHB1c2gsDQogICAgKHB1c2gyKSA9PiB7DQogICAgICByZW5kZXJWTm9kZUNoaWxkcmVuKA0KICAgICAgICBwdXNoMiwNCiAgICAgICAgdm5vZGUuY2hpbGRyZW4sDQogICAgICAgIHBhcmVudENvbXBvbmVudCwNCiAgICAgICAgc2xvdFNjb3BlSWQNCiAgICAgICk7DQogICAgfSwNCiAgICB0YXJnZXQsDQogICAgZGlzYWJsZWQgfHwgZGlzYWJsZWQgPT09ICIiLA0KICAgIHBhcmVudENvbXBvbmVudA0KICApOw0KfQ0KDQpjb25zdCB7IGlzVk5vZGU6IGlzVk5vZGUkMSB9ID0gc3NyVXRpbHM7DQpmdW5jdGlvbiBuZXN0ZWRVbnJvbGxCdWZmZXIoYnVmZmVyLCBwYXJlbnRSZXQsIHN0YXJ0SW5kZXgpIHsNCiAgaWYgKCFidWZmZXIuaGFzQXN5bmMpIHsNCiAgICByZXR1cm4gcGFyZW50UmV0ICsgdW5yb2xsQnVmZmVyU3luYyQxKGJ1ZmZlcik7DQogIH0NCiAgbGV0IHJldCA9IHBhcmVudFJldDsNCiAgZm9yIChsZXQgaSA9IHN0YXJ0SW5kZXg7IGkgPCBidWZmZXIubGVuZ3RoOyBpICs9IDEpIHsNCiAgICBjb25zdCBpdGVtID0gYnVmZmVyW2ldOw0KICAgIGlmIChpc1N0cmluZyhpdGVtKSkgew0KICAgICAgcmV0ICs9IGl0ZW07DQogICAgICBjb250aW51ZTsNCiAgICB9DQogICAgaWYgKGlzUHJvbWlzZShpdGVtKSkgew0KICAgICAgcmV0dXJuIGl0ZW0udGhlbigobmVzdGVkSXRlbSkgPT4gew0KICAgICAgICBidWZmZXJbaV0gPSBuZXN0ZWRJdGVtOw0KICAgICAgICByZXR1cm4gbmVzdGVkVW5yb2xsQnVmZmVyKGJ1ZmZlciwgcmV0LCBpKTsNCiAgICAgIH0pOw0KICAgIH0NCiAgICBjb25zdCByZXN1bHQgPSBuZXN0ZWRVbnJvbGxCdWZmZXIoaXRlbSwgcmV0LCAwKTsNCiAgICBpZiAoaXNQcm9taXNlKHJlc3VsdCkpIHsNCiAgICAgIHJldHVybiByZXN1bHQudGhlbigobmVzdGVkSXRlbSkgPT4gew0KICAgICAgICBidWZmZXJbaV0gPSBuZXN0ZWRJdGVtOw0KICAgICAgICByZXR1cm4gbmVzdGVkVW5yb2xsQnVmZmVyKGJ1ZmZlciwgIiIsIGkpOw0KICAgICAgfSk7DQogICAgfQ0KICAgIHJldCA9IHJlc3VsdDsNCiAgfQ0KICByZXR1cm4gcmV0Ow0KfQ0KZnVuY3Rpb24gdW5yb2xsQnVmZmVyJDEoYnVmZmVyKSB7DQogIHJldHVybiBuZXN0ZWRVbnJvbGxCdWZmZXIoYnVmZmVyLCAiIiwgMCk7DQp9DQpmdW5jdGlvbiB1bnJvbGxCdWZmZXJTeW5jJDEoYnVmZmVyKSB7DQogIGxldCByZXQgPSAiIjsNCiAgZm9yIChsZXQgaSA9IDA7IGkgPCBidWZmZXIubGVuZ3RoOyBpKyspIHsNCiAgICBsZXQgaXRlbSA9IGJ1ZmZlcltpXTsNCiAgICBpZiAoaXNTdHJpbmcoaXRlbSkpIHsNCiAgICAgIHJldCArPSBpdGVtOw0KICAgIH0gZWxzZSB7DQogICAgICByZXQgKz0gdW5yb2xsQnVmZmVyU3luYyQxKGl0ZW0pOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gcmV0Ow0KfQ0KYXN5bmMgZnVuY3Rpb24gcmVuZGVyVG9TdHJpbmcoaW5wdXQsIGNvbnRleHQgPSB7fSkgew0KICBpZiAoaXNWTm9kZSQxKGlucHV0KSkgew0KICAgIHJldHVybiByZW5kZXJUb1N0cmluZyhjcmVhdGVBcHAoeyByZW5kZXI6ICgpID0+IGlucHV0IH0pLCBjb250ZXh0KTsNCiAgfQ0KICBjb25zdCB2bm9kZSA9IGNyZWF0ZVZOb2RlKGlucHV0Ll9jb21wb25lbnQsIGlucHV0Ll9wcm9wcyk7DQogIHZub2RlLmFwcENvbnRleHQgPSBpbnB1dC5fY29udGV4dDsNCiAgaW5wdXQucHJvdmlkZShzc3JDb250ZXh0S2V5LCBjb250ZXh0KTsNCiAgY29uc3QgYnVmZmVyID0gYXdhaXQgcmVuZGVyQ29tcG9uZW50Vk5vZGUodm5vZGUpOw0KICBjb25zdCByZXN1bHQgPSBhd2FpdCB1bnJvbGxCdWZmZXIkMShidWZmZXIpOw0KICBhd2FpdCByZXNvbHZlVGVsZXBvcnRzKGNvbnRleHQpOw0KICBpZiAoY29udGV4dC5fX3dhdGNoZXJIYW5kbGVzKSB7DQogICAgZm9yIChjb25zdCB1bndhdGNoIG9mIGNvbnRleHQuX193YXRjaGVySGFuZGxlcykgew0KICAgICAgdW53YXRjaCgpOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gcmVzdWx0Ow0KfQ0KYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZVRlbGVwb3J0cyhjb250ZXh0KSB7DQogIGlmIChjb250ZXh0Ll9fdGVsZXBvcnRCdWZmZXJzKSB7DQogICAgY29udGV4dC50ZWxlcG9ydHMgPSBjb250ZXh0LnRlbGVwb3J0cyB8fCB7fTsNCiAgICBmb3IgKGNvbnN0IGtleSBpbiBjb250ZXh0Ll9fdGVsZXBvcnRCdWZmZXJzKSB7DQogICAgICBjb250ZXh0LnRlbGVwb3J0c1trZXldID0gYXdhaXQgdW5yb2xsQnVmZmVyJDEoDQogICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFtjb250ZXh0Ll9fdGVsZXBvcnRCdWZmZXJzW2tleV1dKQ0KICAgICAgKTsNCiAgICB9DQogIH0NCn0NCg0KY29uc3QgeyBpc1ZOb2RlIH0gPSBzc3JVdGlsczsNCmFzeW5jIGZ1bmN0aW9uIHVucm9sbEJ1ZmZlcihidWZmZXIsIHN0cmVhbSkgew0KICBpZiAoYnVmZmVyLmhhc0FzeW5jKSB7DQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBidWZmZXIubGVuZ3RoOyBpKyspIHsNCiAgICAgIGxldCBpdGVtID0gYnVmZmVyW2ldOw0KICAgICAgaWYgKGlzUHJvbWlzZShpdGVtKSkgew0KICAgICAgICBpdGVtID0gYXdhaXQgaXRlbTsNCiAgICAgIH0NCiAgICAgIGlmIChpc1N0cmluZyhpdGVtKSkgew0KICAgICAgICBzdHJlYW0ucHVzaChpdGVtKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGF3YWl0IHVucm9sbEJ1ZmZlcihpdGVtLCBzdHJlYW0pOw0KICAgICAgfQ0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICB1bnJvbGxCdWZmZXJTeW5jKGJ1ZmZlciwgc3RyZWFtKTsNCiAgfQ0KfQ0KZnVuY3Rpb24gdW5yb2xsQnVmZmVyU3luYyhidWZmZXIsIHN0cmVhbSkgew0KICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1ZmZlci5sZW5ndGg7IGkrKykgew0KICAgIGxldCBpdGVtID0gYnVmZmVyW2ldOw0KICAgIGlmIChpc1N0cmluZyhpdGVtKSkgew0KICAgICAgc3RyZWFtLnB1c2goaXRlbSk7DQogICAgfSBlbHNlIHsNCiAgICAgIHVucm9sbEJ1ZmZlclN5bmMoaXRlbSwgc3RyZWFtKTsNCiAgICB9DQogIH0NCn0NCmZ1bmN0aW9uIHJlbmRlclRvU2ltcGxlU3RyZWFtKGlucHV0LCBjb250ZXh0LCBzdHJlYW0pIHsNCiAgaWYgKGlzVk5vZGUoaW5wdXQpKSB7DQogICAgcmV0dXJuIHJlbmRlclRvU2ltcGxlU3RyZWFtKA0KICAgICAgY3JlYXRlQXBwKHsgcmVuZGVyOiAoKSA9PiBpbnB1dCB9KSwNCiAgICAgIGNvbnRleHQsDQogICAgICBzdHJlYW0NCiAgICApOw0KICB9DQogIGNvbnN0IHZub2RlID0gY3JlYXRlVk5vZGUoaW5wdXQuX2NvbXBvbmVudCwgaW5wdXQuX3Byb3BzKTsNCiAgdm5vZGUuYXBwQ29udGV4dCA9IGlucHV0Ll9jb250ZXh0Ow0KICBpbnB1dC5wcm92aWRlKHNzckNvbnRleHRLZXksIGNvbnRleHQpOw0KICBQcm9taXNlLnJlc29sdmUocmVuZGVyQ29tcG9uZW50Vk5vZGUodm5vZGUpKS50aGVuKChidWZmZXIpID0+IHVucm9sbEJ1ZmZlcihidWZmZXIsIHN0cmVhbSkpLnRoZW4oKCkgPT4gcmVzb2x2ZVRlbGVwb3J0cyhjb250ZXh0KSkudGhlbigoKSA9PiB7DQogICAgaWYgKGNvbnRleHQuX193YXRjaGVySGFuZGxlcykgew0KICAgICAgZm9yIChjb25zdCB1bndhdGNoIG9mIGNvbnRleHQuX193YXRjaGVySGFuZGxlcykgew0KICAgICAgICB1bndhdGNoKCk7DQogICAgICB9DQogICAgfQ0KICB9KS50aGVuKCgpID0+IHN0cmVhbS5wdXNoKG51bGwpKS5jYXRjaCgoZXJyb3IpID0+IHsNCiAgICBzdHJlYW0uZGVzdHJveShlcnJvcik7DQogIH0pOw0KICByZXR1cm4gc3RyZWFtOw0KfQ0KZnVuY3Rpb24gcmVuZGVyVG9TdHJlYW0oaW5wdXQsIGNvbnRleHQgPSB7fSkgew0KICBjb25zb2xlLndhcm4oDQogICAgYFtAdnVlL3NlcnZlci1yZW5kZXJlcl0gcmVuZGVyVG9TdHJlYW0gaXMgZGVwcmVjYXRlZCAtIHVzZSByZW5kZXJUb05vZGVTdHJlYW0gaW5zdGVhZC5gDQogICk7DQogIHJldHVybiByZW5kZXJUb05vZGVTdHJlYW0oaW5wdXQsIGNvbnRleHQpOw0KfQ0KZnVuY3Rpb24gcmVuZGVyVG9Ob2RlU3RyZWFtKGlucHV0LCBjb250ZXh0ID0ge30pIHsNCiAgew0KICAgIHRocm93IG5ldyBFcnJvcigNCiAgICAgIGBFU00gYnVpbGQgb2YgcmVuZGVyVG9TdHJlYW0oKSBkb2VzIG5vdCBzdXBwb3J0IHJlbmRlclRvTm9kZVN0cmVhbSgpLiBVc2UgcGlwZVRvTm9kZVdyaXRhYmxlKCkgd2l0aCBhbiBleGlzdGluZyBOb2RlLmpzIFdyaXRhYmxlIHN0cmVhbSBpbnN0YW5jZSBpbnN0ZWFkLmANCiAgICApOw0KICB9DQp9DQpmdW5jdGlvbiBwaXBlVG9Ob2RlV3JpdGFibGUoaW5wdXQsIGNvbnRleHQgPSB7fSwgd3JpdGFibGUpIHsNCiAgcmVuZGVyVG9TaW1wbGVTdHJlYW0oaW5wdXQsIGNvbnRleHQsIHsNCiAgICBwdXNoKGNvbnRlbnQpIHsNCiAgICAgIGlmIChjb250ZW50ICE9IG51bGwpIHsNCiAgICAgICAgd3JpdGFibGUud3JpdGUoY29udGVudCk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICB3cml0YWJsZS5lbmQoKTsNCiAgICAgIH0NCiAgICB9LA0KICAgIGRlc3Ryb3koZXJyKSB7DQogICAgICB3cml0YWJsZS5kZXN0cm95KGVycik7DQogICAgfQ0KICB9KTsNCn0NCmZ1bmN0aW9uIHJlbmRlclRvV2ViU3RyZWFtKGlucHV0LCBjb250ZXh0ID0ge30pIHsNCiAgaWYgKHR5cGVvZiBSZWFkYWJsZVN0cmVhbSAhPT0gImZ1bmN0aW9uIikgew0KICAgIHRocm93IG5ldyBFcnJvcigNCiAgICAgIGBSZWFkYWJsZVN0cmVhbSBjb25zdHJ1Y3RvciBpcyBub3QgYXZhaWxhYmxlIGluIHRoZSBnbG9iYWwgc2NvcGUuIElmIHRoZSB0YXJnZXQgZW52aXJvbm1lbnQgZG9lcyBzdXBwb3J0IHdlYiBzdHJlYW1zLCBjb25zaWRlciB1c2luZyBwaXBlVG9XZWJXcml0YWJsZSgpIHdpdGggYW4gZXhpc3RpbmcgV3JpdGFibGVTdHJlYW0gaW5zdGFuY2UgaW5zdGVhZC5gDQogICAgKTsNCiAgfQ0KICBjb25zdCBlbmNvZGVyID0gbmV3IFRleHRFbmNvZGVyKCk7DQogIGxldCBjYW5jZWxsZWQgPSBmYWxzZTsNCiAgcmV0dXJuIG5ldyBSZWFkYWJsZVN0cmVhbSh7DQogICAgc3RhcnQoY29udHJvbGxlcikgew0KICAgICAgcmVuZGVyVG9TaW1wbGVTdHJlYW0oaW5wdXQsIGNvbnRleHQsIHsNCiAgICAgICAgcHVzaChjb250ZW50KSB7DQogICAgICAgICAgaWYgKGNhbmNlbGxlZCkgcmV0dXJuOw0KICAgICAgICAgIGlmIChjb250ZW50ICE9IG51bGwpIHsNCiAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShlbmNvZGVyLmVuY29kZShjb250ZW50KSk7DQogICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIGNvbnRyb2xsZXIuY2xvc2UoKTsNCiAgICAgICAgICB9DQogICAgICAgIH0sDQogICAgICAgIGRlc3Ryb3koZXJyKSB7DQogICAgICAgICAgY29udHJvbGxlci5lcnJvcihlcnIpOw0KICAgICAgICB9DQogICAgICB9KTsNCiAgICB9LA0KICAgIGNhbmNlbCgpIHsNCiAgICAgIGNhbmNlbGxlZCA9IHRydWU7DQogICAgfQ0KICB9KTsNCn0NCmZ1bmN0aW9uIHBpcGVUb1dlYldyaXRhYmxlKGlucHV0LCBjb250ZXh0ID0ge30sIHdyaXRhYmxlKSB7DQogIGNvbnN0IHdyaXRlciA9IHdyaXRhYmxlLmdldFdyaXRlcigpOw0KICBjb25zdCBlbmNvZGVyID0gbmV3IFRleHRFbmNvZGVyKCk7DQogIGxldCBoYXNSZWFkeSA9IGZhbHNlOw0KICB0cnkgew0KICAgIGhhc1JlYWR5ID0gaXNQcm9taXNlKHdyaXRlci5yZWFkeSk7DQogIH0gY2F0Y2ggKGUpIHsNCiAgfQ0KICByZW5kZXJUb1NpbXBsZVN0cmVhbShpbnB1dCwgY29udGV4dCwgew0KICAgIGFzeW5jIHB1c2goY29udGVudCkgew0KICAgICAgaWYgKGhhc1JlYWR5KSB7DQogICAgICAgIGF3YWl0IHdyaXRlci5yZWFkeTsNCiAgICAgIH0NCiAgICAgIGlmIChjb250ZW50ICE9IG51bGwpIHsNCiAgICAgICAgcmV0dXJuIHdyaXRlci53cml0ZShlbmNvZGVyLmVuY29kZShjb250ZW50KSk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICByZXR1cm4gd3JpdGVyLmNsb3NlKCk7DQogICAgICB9DQogICAgfSwNCiAgICBkZXN0cm95KGVycikgew0KICAgICAgY29uc29sZS5sb2coZXJyKTsNCiAgICAgIHdyaXRlci5jbG9zZSgpOw0KICAgIH0NCiAgfSk7DQp9DQoNCmluaXREaXJlY3RpdmVzRm9yU1NSKCk7DQoNCmV4cG9ydCB7IHBpcGVUb05vZGVXcml0YWJsZSwgcGlwZVRvV2ViV3JpdGFibGUsIHJlbmRlclRvTm9kZVN0cmVhbSwgcmVuZGVyVG9TaW1wbGVTdHJlYW0sIHJlbmRlclRvU3RyZWFtLCByZW5kZXJUb1N0cmluZywgcmVuZGVyVG9XZWJTdHJlYW0sIHNzckdldERpcmVjdGl2ZVByb3BzLCBzc3JHZXREeW5hbWljTW9kZWxQcm9wcywgaW5jbHVkZUJvb2xlYW5BdHRyIGFzIHNzckluY2x1ZGVCb29sZWFuQXR0ciwgc3NySW50ZXJwb2xhdGUsIHNzckxvb3NlQ29udGFpbiwgc3NyTG9vc2VFcXVhbCwgc3NyUmVuZGVyQXR0ciwgc3NyUmVuZGVyQXR0cnMsIHNzclJlbmRlckNsYXNzLCBzc3JSZW5kZXJDb21wb25lbnQsIHNzclJlbmRlckR5bmFtaWNBdHRyLCBzc3JSZW5kZXJEeW5hbWljTW9kZWwsIHNzclJlbmRlckxpc3QsIHNzclJlbmRlclNsb3QsIHNzclJlbmRlclNsb3RJbm5lciwgc3NyUmVuZGVyU3R5bGUsIHNzclJlbmRlclN1c3BlbnNlLCBzc3JSZW5kZXJUZWxlcG9ydCwgcmVuZGVyVk5vZGUgYXMgc3NyUmVuZGVyVk5vZGUgfTsNCg==",Dnn={class:"custom-component-render"},Enn=er({...er({name:"ShjCustomComponentRender"}),props:{option:{},sources:{},useEvents:{}},setup(i,{expose:e}){window.Axios=LK,window.Hls=t2,ha(()=>{window.SHJDatasourceV2=Jo,window.SHJParseEvent=xi});const t=ti(()=>bnn(i.option)),{productionMode:r,vueVersion:n,importMap:s}=aQt({runtimeDev:hqt,runtimeProd:hqt,serverRenderer:Inn}),a=ti(()=>({script:{inlineTemplate:r.value,isProd:r.value,propsDestructure:!0},style:{isProd:r.value},template:{isProd:r.value}})),o=Zt(!0),l=A8(null),u=Zt("");(()=>{const x=t.value.hash;if(!(u.value===x&&l.value)){u.value=x,o.value=!0;try{const v=cnn({builtinImportMap:s,vueVersion:n,sfcOptions:a},x);v.files["src/source.json"]&&(v.files["src/source.json"].code=JSON.stringify(i.sources,null,2)),v.files["src/option.json"]&&(v.files["src/option.json"].code=JSON.stringify(t.value.option,null,2)),l.value=v,o.value=!1}catch{o.value=!1}}})();const d=()=>{if(!l.value||!g.value)return;const x=g.value.querySelector("iframe").contentWindow;x&&x.postMessage(JSON.stringify(i.sources),"*")},h=()=>{l.value&&(o.value=!0,l.value.files["src/source.json"]&&(l.value.files["src/source.json"].code=JSON.stringify(i.sources,null,2)),l.value.files["src/option.json"]&&(l.value.files["src/option.json"].code=JSON.stringify(t.value.option,null,2)),setTimeout(()=>{o.value=!1},10))};Ann({option:t,sources:i.sources},d,h),e({refresh:()=>{h(),d()},refreshView:()=>{h(),d()},refreshData:()=>{d()}});const p=ti(()=>({showRuntimeError:!1,showRuntimeWarning:!1,customCode:{useCode:`
|
|
5209
5209
|
/** 导入山河鉴必须的变量 **/
|
|
5210
5210
|
window.useEvents = ${JSON.stringify(i.useEvents)};
|
|
5211
5211
|
window.Axios = window.parent.Axios;
|
|
@@ -5235,7 +5235,7 @@ Tip: edit the "Import Map" tab to specify import paths for dependencies.`:u.valu
|
|
|
5235
5235
|
background-color: transparent !important;
|
|
5236
5236
|
}
|
|
5237
5237
|
</style>
|
|
5238
|
-
`})),g=Zt();return(x,v)=>(Vt(),kr("div",Dnn,[Xi("div",{ref_key:"sandboxRef",ref:g,class:"preview-content"},[!o.value&&l.value?(Vt(),Pi(Nr(Cnn),{key:0,store:l.value,"clear-console":!1,"preview-options":p.value},null,8,["store","preview-options"])):Hi("",!0)],512)]))}}),fqt=zi(qu(Enn,[["__scopeId","data-v-50082aa2"]])),pqt="2.0.0",Snn=i=>{const e=Ht.cloneDeep(i);return e.version!==pqt?{base:{fill:e.fill,fillOpacity:e.fillOpacity,stroke:e.stroke,strokeWidth:e.strokeWidth,strokeOpacity:e.strokeOpacity,type:"circle"},version:pqt}:i},_nn={key:0,viewBox:"0 0 100 100",preserveAspectRatio:"none"},Tnn=["r","stroke","stroke-width","fill"],Rnn={key:1,viewBox:"0 0 100 100",preserveAspectRatio:"none"},wnn=["stroke","stroke-width","fill"],Fnn={key:2,viewBox:"0 0 100 100",preserveAspectRatio:"none"},Bnn=["stroke","stroke-width","fill"],Pnn={key:3,viewBox:"0 0 100 100",preserveAspectRatio:"none"},Nnn=["stroke","stroke-width","fill"],Mnn={key:4,viewBox:"0 0 100 100",preserveAspectRatio:"none"},Onn=["stroke","stroke-width","fill"],Lnn={key:5,viewBox:"0 0 100 100",preserveAspectRatio:"none"},knn=["stroke","stroke-width","fill"],Gnn={key:6,viewBox:"0 0 100 100",preserveAspectRatio:"none"},Vnn=["stroke","stroke-width","fill"],Wnn=er({...er({name:"ShjGraphical"}),props:{option:{}},setup(i){const e=ti(()=>Snn(i.option));return(t,r)=>e.value.base.type==="circle"?(Vt(),kr("svg",_nn,[Xi("circle",{cx:"50",cy:"50",r:Math.max(10,50-e.value.base.strokeWidth),stroke:e.value.base.stroke,"stroke-width":e.value.base.strokeWidth,fill:e.value.base.fill},null,8,Tnn)])):e.value.base.type==="diamond"?(Vt(),kr("svg",Rnn,[Xi("polygon",{points:"50,10 90,50 50,90 10,50",stroke:e.value.base.stroke,"stroke-width":e.value.base.strokeWidth,fill:e.value.base.fill},null,8,wnn)])):e.value.base.type==="hexagon"?(Vt(),kr("svg",Fnn,[Xi("polygon",{points:"50,5 90,25 90,75 50,95 10,75 10,25",stroke:e.value.base.stroke,"stroke-width":e.value.base.strokeWidth,fill:e.value.base.fill},null,8,Bnn)])):e.value.base.type==="isosceles-triangle"?(Vt(),kr("svg",Pnn,[Xi("polygon",{points:"50,10 90,90 10,90",stroke:e.value.base.stroke,"stroke-width":e.value.base.strokeWidth,fill:e.value.base.fill},null,8,Nnn)])):e.value.base.type==="pentagon"?(Vt(),kr("svg",Mnn,[Xi("polygon",{points:"50,5 95,30 85,85 15,85 5,30",stroke:e.value.base.stroke,"stroke-width":e.value.base.strokeWidth,fill:e.value.base.fill},null,8,Onn)])):e.value.base.type==="rect"?(Vt(),kr("svg",Lnn,[Xi("rect",{x:"0",y:"0",width:"100",height:"100",stroke:e.value.base.stroke,"stroke-width":e.value.base.strokeWidth,fill:e.value.base.fill},null,8,knn)])):e.value.base.type==="right-triangle"?(Vt(),kr("svg",Gnn,[Xi("polygon",{points:"10,10 10,90 90,90",stroke:e.value.base.stroke,"stroke-width":e.value.base.strokeWidth,fill:e.value.base.fill},null,8,Vnn)])):Hi("",!0)}}),gqt=zi(qu(Wnn,[["__scopeId","data-v-b1fbfaeb"]]));var qpe={exports:{}},m0={},$pe={exports:{}},dN={},mqt;function xqt(){if(mqt)return dN;mqt=1;function i(){var s={};return s["align-content"]=!1,s["align-items"]=!1,s["align-self"]=!1,s["alignment-adjust"]=!1,s["alignment-baseline"]=!1,s.all=!1,s["anchor-point"]=!1,s.animation=!1,s["animation-delay"]=!1,s["animation-direction"]=!1,s["animation-duration"]=!1,s["animation-fill-mode"]=!1,s["animation-iteration-count"]=!1,s["animation-name"]=!1,s["animation-play-state"]=!1,s["animation-timing-function"]=!1,s.azimuth=!1,s["backface-visibility"]=!1,s.background=!0,s["background-attachment"]=!0,s["background-clip"]=!0,s["background-color"]=!0,s["background-image"]=!0,s["background-origin"]=!0,s["background-position"]=!0,s["background-repeat"]=!0,s["background-size"]=!0,s["baseline-shift"]=!1,s.binding=!1,s.bleed=!1,s["bookmark-label"]=!1,s["bookmark-level"]=!1,s["bookmark-state"]=!1,s.border=!0,s["border-bottom"]=!0,s["border-bottom-color"]=!0,s["border-bottom-left-radius"]=!0,s["border-bottom-right-radius"]=!0,s["border-bottom-style"]=!0,s["border-bottom-width"]=!0,s["border-collapse"]=!0,s["border-color"]=!0,s["border-image"]=!0,s["border-image-outset"]=!0,s["border-image-repeat"]=!0,s["border-image-slice"]=!0,s["border-image-source"]=!0,s["border-image-width"]=!0,s["border-left"]=!0,s["border-left-color"]=!0,s["border-left-style"]=!0,s["border-left-width"]=!0,s["border-radius"]=!0,s["border-right"]=!0,s["border-right-color"]=!0,s["border-right-style"]=!0,s["border-right-width"]=!0,s["border-spacing"]=!0,s["border-style"]=!0,s["border-top"]=!0,s["border-top-color"]=!0,s["border-top-left-radius"]=!0,s["border-top-right-radius"]=!0,s["border-top-style"]=!0,s["border-top-width"]=!0,s["border-width"]=!0,s.bottom=!1,s["box-decoration-break"]=!0,s["box-shadow"]=!0,s["box-sizing"]=!0,s["box-snap"]=!0,s["box-suppress"]=!0,s["break-after"]=!0,s["break-before"]=!0,s["break-inside"]=!0,s["caption-side"]=!1,s.chains=!1,s.clear=!0,s.clip=!1,s["clip-path"]=!1,s["clip-rule"]=!1,s.color=!0,s["color-interpolation-filters"]=!0,s["column-count"]=!1,s["column-fill"]=!1,s["column-gap"]=!1,s["column-rule"]=!1,s["column-rule-color"]=!1,s["column-rule-style"]=!1,s["column-rule-width"]=!1,s["column-span"]=!1,s["column-width"]=!1,s.columns=!1,s.contain=!1,s.content=!1,s["counter-increment"]=!1,s["counter-reset"]=!1,s["counter-set"]=!1,s.crop=!1,s.cue=!1,s["cue-after"]=!1,s["cue-before"]=!1,s.cursor=!1,s.direction=!1,s.display=!0,s["display-inside"]=!0,s["display-list"]=!0,s["display-outside"]=!0,s["dominant-baseline"]=!1,s.elevation=!1,s["empty-cells"]=!1,s.filter=!1,s.flex=!1,s["flex-basis"]=!1,s["flex-direction"]=!1,s["flex-flow"]=!1,s["flex-grow"]=!1,s["flex-shrink"]=!1,s["flex-wrap"]=!1,s.float=!1,s["float-offset"]=!1,s["flood-color"]=!1,s["flood-opacity"]=!1,s["flow-from"]=!1,s["flow-into"]=!1,s.font=!0,s["font-family"]=!0,s["font-feature-settings"]=!0,s["font-kerning"]=!0,s["font-language-override"]=!0,s["font-size"]=!0,s["font-size-adjust"]=!0,s["font-stretch"]=!0,s["font-style"]=!0,s["font-synthesis"]=!0,s["font-variant"]=!0,s["font-variant-alternates"]=!0,s["font-variant-caps"]=!0,s["font-variant-east-asian"]=!0,s["font-variant-ligatures"]=!0,s["font-variant-numeric"]=!0,s["font-variant-position"]=!0,s["font-weight"]=!0,s.grid=!1,s["grid-area"]=!1,s["grid-auto-columns"]=!1,s["grid-auto-flow"]=!1,s["grid-auto-rows"]=!1,s["grid-column"]=!1,s["grid-column-end"]=!1,s["grid-column-start"]=!1,s["grid-row"]=!1,s["grid-row-end"]=!1,s["grid-row-start"]=!1,s["grid-template"]=!1,s["grid-template-areas"]=!1,s["grid-template-columns"]=!1,s["grid-template-rows"]=!1,s["hanging-punctuation"]=!1,s.height=!0,s.hyphens=!1,s.icon=!1,s["image-orientation"]=!1,s["image-resolution"]=!1,s["ime-mode"]=!1,s["initial-letters"]=!1,s["inline-box-align"]=!1,s["justify-content"]=!1,s["justify-items"]=!1,s["justify-self"]=!1,s.left=!1,s["letter-spacing"]=!0,s["lighting-color"]=!0,s["line-box-contain"]=!1,s["line-break"]=!1,s["line-grid"]=!1,s["line-height"]=!1,s["line-snap"]=!1,s["line-stacking"]=!1,s["line-stacking-ruby"]=!1,s["line-stacking-shift"]=!1,s["line-stacking-strategy"]=!1,s["list-style"]=!0,s["list-style-image"]=!0,s["list-style-position"]=!0,s["list-style-type"]=!0,s.margin=!0,s["margin-bottom"]=!0,s["margin-left"]=!0,s["margin-right"]=!0,s["margin-top"]=!0,s["marker-offset"]=!1,s["marker-side"]=!1,s.marks=!1,s.mask=!1,s["mask-box"]=!1,s["mask-box-outset"]=!1,s["mask-box-repeat"]=!1,s["mask-box-slice"]=!1,s["mask-box-source"]=!1,s["mask-box-width"]=!1,s["mask-clip"]=!1,s["mask-image"]=!1,s["mask-origin"]=!1,s["mask-position"]=!1,s["mask-repeat"]=!1,s["mask-size"]=!1,s["mask-source-type"]=!1,s["mask-type"]=!1,s["max-height"]=!0,s["max-lines"]=!1,s["max-width"]=!0,s["min-height"]=!0,s["min-width"]=!0,s["move-to"]=!1,s["nav-down"]=!1,s["nav-index"]=!1,s["nav-left"]=!1,s["nav-right"]=!1,s["nav-up"]=!1,s["object-fit"]=!1,s["object-position"]=!1,s.opacity=!1,s.order=!1,s.orphans=!1,s.outline=!1,s["outline-color"]=!1,s["outline-offset"]=!1,s["outline-style"]=!1,s["outline-width"]=!1,s.overflow=!1,s["overflow-wrap"]=!1,s["overflow-x"]=!1,s["overflow-y"]=!1,s.padding=!0,s["padding-bottom"]=!0,s["padding-left"]=!0,s["padding-right"]=!0,s["padding-top"]=!0,s.page=!1,s["page-break-after"]=!1,s["page-break-before"]=!1,s["page-break-inside"]=!1,s["page-policy"]=!1,s.pause=!1,s["pause-after"]=!1,s["pause-before"]=!1,s.perspective=!1,s["perspective-origin"]=!1,s.pitch=!1,s["pitch-range"]=!1,s["play-during"]=!1,s.position=!1,s["presentation-level"]=!1,s.quotes=!1,s["region-fragment"]=!1,s.resize=!1,s.rest=!1,s["rest-after"]=!1,s["rest-before"]=!1,s.richness=!1,s.right=!1,s.rotation=!1,s["rotation-point"]=!1,s["ruby-align"]=!1,s["ruby-merge"]=!1,s["ruby-position"]=!1,s["shape-image-threshold"]=!1,s["shape-outside"]=!1,s["shape-margin"]=!1,s.size=!1,s.speak=!1,s["speak-as"]=!1,s["speak-header"]=!1,s["speak-numeral"]=!1,s["speak-punctuation"]=!1,s["speech-rate"]=!1,s.stress=!1,s["string-set"]=!1,s["tab-size"]=!1,s["table-layout"]=!1,s["text-align"]=!0,s["text-align-last"]=!0,s["text-combine-upright"]=!0,s["text-decoration"]=!0,s["text-decoration-color"]=!0,s["text-decoration-line"]=!0,s["text-decoration-skip"]=!0,s["text-decoration-style"]=!0,s["text-emphasis"]=!0,s["text-emphasis-color"]=!0,s["text-emphasis-position"]=!0,s["text-emphasis-style"]=!0,s["text-height"]=!0,s["text-indent"]=!0,s["text-justify"]=!0,s["text-orientation"]=!0,s["text-overflow"]=!0,s["text-shadow"]=!0,s["text-space-collapse"]=!0,s["text-transform"]=!0,s["text-underline-position"]=!0,s["text-wrap"]=!0,s.top=!1,s.transform=!1,s["transform-origin"]=!1,s["transform-style"]=!1,s.transition=!1,s["transition-delay"]=!1,s["transition-duration"]=!1,s["transition-property"]=!1,s["transition-timing-function"]=!1,s["unicode-bidi"]=!1,s["vertical-align"]=!1,s.visibility=!1,s["voice-balance"]=!1,s["voice-duration"]=!1,s["voice-family"]=!1,s["voice-pitch"]=!1,s["voice-range"]=!1,s["voice-rate"]=!1,s["voice-stress"]=!1,s["voice-volume"]=!1,s.volume=!1,s["white-space"]=!1,s.widows=!1,s.width=!0,s["will-change"]=!1,s["word-break"]=!0,s["word-spacing"]=!0,s["word-wrap"]=!0,s["wrap-flow"]=!1,s["wrap-through"]=!1,s["writing-mode"]=!1,s["z-index"]=!1,s}function e(s,a,o){}function t(s,a,o){}var r=/javascript\s*\:/img;function n(s,a){return r.test(a)?"":a}return dN.whiteList=i(),dN.getDefaultWhiteList=i,dN.onAttr=e,dN.onIgnoreAttr=t,dN.safeAttrValue=n,dN}var sLe,vqt;function yqt(){return vqt||(vqt=1,sLe={indexOf:function(i,e){var t,r;if(Array.prototype.indexOf)return i.indexOf(e);for(t=0,r=i.length;t<r;t++)if(i[t]===e)return t;return-1},forEach:function(i,e,t){var r,n;if(Array.prototype.forEach)return i.forEach(e,t);for(r=0,n=i.length;r<n;r++)e.call(t,i[r],r,i)},trim:function(i){return String.prototype.trim?i.trim():i.replace(/(^\s*)|(\s*$)/g,"")},trimRight:function(i){return String.prototype.trimRight?i.trimRight():i.replace(/(\s*$)/g,"")}}),sLe}var aLe,Cqt;function Unn(){if(Cqt)return aLe;Cqt=1;var i=yqt();function e(t,r){t=i.trimRight(t),t[t.length-1]!==";"&&(t+=";");var n=t.length,s=!1,a=0,o=0,l="";function u(){if(!s){var h=i.trim(t.slice(a,o)),p=h.indexOf(":");if(p!==-1){var g=i.trim(h.slice(0,p)),x=i.trim(h.slice(p+1));if(g){var v=r(a,l.length,g,x,h);v&&(l+=v+"; ")}}}a=o+1}for(;o<n;o++){var c=t[o];if(c==="/"&&t[o+1]==="*"){var d=t.indexOf("*/",o+2);if(d===-1)break;o=d+1,a=o+1,s=!1}else c==="("?s=!0:c===")"?s=!1:c===";"?s||u():c===`
|
|
5238
|
+
`})),g=Zt();return(x,v)=>(Vt(),kr("div",Dnn,[Xi("div",{ref_key:"sandboxRef",ref:g,class:"preview-content"},[!o.value&&l.value?(Vt(),Pi(Nr(Cnn),{key:0,store:l.value,"clear-console":!0,"preview-options":p.value},null,8,["store","preview-options"])):Hi("",!0)],512)]))}}),fqt=zi(qu(Enn,[["__scopeId","data-v-f1d151c0"]])),pqt="2.0.0",Snn=i=>{const e=Ht.cloneDeep(i);return e.version!==pqt?{base:{fill:e.fill,fillOpacity:e.fillOpacity,stroke:e.stroke,strokeWidth:e.strokeWidth,strokeOpacity:e.strokeOpacity,type:"circle"},version:pqt}:i},_nn={key:0,viewBox:"0 0 100 100",preserveAspectRatio:"none"},Tnn=["r","stroke","stroke-width","fill"],Rnn={key:1,viewBox:"0 0 100 100",preserveAspectRatio:"none"},wnn=["stroke","stroke-width","fill"],Fnn={key:2,viewBox:"0 0 100 100",preserveAspectRatio:"none"},Bnn=["stroke","stroke-width","fill"],Pnn={key:3,viewBox:"0 0 100 100",preserveAspectRatio:"none"},Nnn=["stroke","stroke-width","fill"],Mnn={key:4,viewBox:"0 0 100 100",preserveAspectRatio:"none"},Onn=["stroke","stroke-width","fill"],Lnn={key:5,viewBox:"0 0 100 100",preserveAspectRatio:"none"},knn=["stroke","stroke-width","fill"],Gnn={key:6,viewBox:"0 0 100 100",preserveAspectRatio:"none"},Vnn=["stroke","stroke-width","fill"],Wnn=er({...er({name:"ShjGraphical"}),props:{option:{}},setup(i){const e=ti(()=>Snn(i.option));return(t,r)=>e.value.base.type==="circle"?(Vt(),kr("svg",_nn,[Xi("circle",{cx:"50",cy:"50",r:Math.max(10,50-e.value.base.strokeWidth),stroke:e.value.base.stroke,"stroke-width":e.value.base.strokeWidth,fill:e.value.base.fill},null,8,Tnn)])):e.value.base.type==="diamond"?(Vt(),kr("svg",Rnn,[Xi("polygon",{points:"50,10 90,50 50,90 10,50",stroke:e.value.base.stroke,"stroke-width":e.value.base.strokeWidth,fill:e.value.base.fill},null,8,wnn)])):e.value.base.type==="hexagon"?(Vt(),kr("svg",Fnn,[Xi("polygon",{points:"50,5 90,25 90,75 50,95 10,75 10,25",stroke:e.value.base.stroke,"stroke-width":e.value.base.strokeWidth,fill:e.value.base.fill},null,8,Bnn)])):e.value.base.type==="isosceles-triangle"?(Vt(),kr("svg",Pnn,[Xi("polygon",{points:"50,10 90,90 10,90",stroke:e.value.base.stroke,"stroke-width":e.value.base.strokeWidth,fill:e.value.base.fill},null,8,Nnn)])):e.value.base.type==="pentagon"?(Vt(),kr("svg",Mnn,[Xi("polygon",{points:"50,5 95,30 85,85 15,85 5,30",stroke:e.value.base.stroke,"stroke-width":e.value.base.strokeWidth,fill:e.value.base.fill},null,8,Onn)])):e.value.base.type==="rect"?(Vt(),kr("svg",Lnn,[Xi("rect",{x:"0",y:"0",width:"100",height:"100",stroke:e.value.base.stroke,"stroke-width":e.value.base.strokeWidth,fill:e.value.base.fill},null,8,knn)])):e.value.base.type==="right-triangle"?(Vt(),kr("svg",Gnn,[Xi("polygon",{points:"10,10 10,90 90,90",stroke:e.value.base.stroke,"stroke-width":e.value.base.strokeWidth,fill:e.value.base.fill},null,8,Vnn)])):Hi("",!0)}}),gqt=zi(qu(Wnn,[["__scopeId","data-v-b1fbfaeb"]]));var qpe={exports:{}},m0={},$pe={exports:{}},dN={},mqt;function xqt(){if(mqt)return dN;mqt=1;function i(){var s={};return s["align-content"]=!1,s["align-items"]=!1,s["align-self"]=!1,s["alignment-adjust"]=!1,s["alignment-baseline"]=!1,s.all=!1,s["anchor-point"]=!1,s.animation=!1,s["animation-delay"]=!1,s["animation-direction"]=!1,s["animation-duration"]=!1,s["animation-fill-mode"]=!1,s["animation-iteration-count"]=!1,s["animation-name"]=!1,s["animation-play-state"]=!1,s["animation-timing-function"]=!1,s.azimuth=!1,s["backface-visibility"]=!1,s.background=!0,s["background-attachment"]=!0,s["background-clip"]=!0,s["background-color"]=!0,s["background-image"]=!0,s["background-origin"]=!0,s["background-position"]=!0,s["background-repeat"]=!0,s["background-size"]=!0,s["baseline-shift"]=!1,s.binding=!1,s.bleed=!1,s["bookmark-label"]=!1,s["bookmark-level"]=!1,s["bookmark-state"]=!1,s.border=!0,s["border-bottom"]=!0,s["border-bottom-color"]=!0,s["border-bottom-left-radius"]=!0,s["border-bottom-right-radius"]=!0,s["border-bottom-style"]=!0,s["border-bottom-width"]=!0,s["border-collapse"]=!0,s["border-color"]=!0,s["border-image"]=!0,s["border-image-outset"]=!0,s["border-image-repeat"]=!0,s["border-image-slice"]=!0,s["border-image-source"]=!0,s["border-image-width"]=!0,s["border-left"]=!0,s["border-left-color"]=!0,s["border-left-style"]=!0,s["border-left-width"]=!0,s["border-radius"]=!0,s["border-right"]=!0,s["border-right-color"]=!0,s["border-right-style"]=!0,s["border-right-width"]=!0,s["border-spacing"]=!0,s["border-style"]=!0,s["border-top"]=!0,s["border-top-color"]=!0,s["border-top-left-radius"]=!0,s["border-top-right-radius"]=!0,s["border-top-style"]=!0,s["border-top-width"]=!0,s["border-width"]=!0,s.bottom=!1,s["box-decoration-break"]=!0,s["box-shadow"]=!0,s["box-sizing"]=!0,s["box-snap"]=!0,s["box-suppress"]=!0,s["break-after"]=!0,s["break-before"]=!0,s["break-inside"]=!0,s["caption-side"]=!1,s.chains=!1,s.clear=!0,s.clip=!1,s["clip-path"]=!1,s["clip-rule"]=!1,s.color=!0,s["color-interpolation-filters"]=!0,s["column-count"]=!1,s["column-fill"]=!1,s["column-gap"]=!1,s["column-rule"]=!1,s["column-rule-color"]=!1,s["column-rule-style"]=!1,s["column-rule-width"]=!1,s["column-span"]=!1,s["column-width"]=!1,s.columns=!1,s.contain=!1,s.content=!1,s["counter-increment"]=!1,s["counter-reset"]=!1,s["counter-set"]=!1,s.crop=!1,s.cue=!1,s["cue-after"]=!1,s["cue-before"]=!1,s.cursor=!1,s.direction=!1,s.display=!0,s["display-inside"]=!0,s["display-list"]=!0,s["display-outside"]=!0,s["dominant-baseline"]=!1,s.elevation=!1,s["empty-cells"]=!1,s.filter=!1,s.flex=!1,s["flex-basis"]=!1,s["flex-direction"]=!1,s["flex-flow"]=!1,s["flex-grow"]=!1,s["flex-shrink"]=!1,s["flex-wrap"]=!1,s.float=!1,s["float-offset"]=!1,s["flood-color"]=!1,s["flood-opacity"]=!1,s["flow-from"]=!1,s["flow-into"]=!1,s.font=!0,s["font-family"]=!0,s["font-feature-settings"]=!0,s["font-kerning"]=!0,s["font-language-override"]=!0,s["font-size"]=!0,s["font-size-adjust"]=!0,s["font-stretch"]=!0,s["font-style"]=!0,s["font-synthesis"]=!0,s["font-variant"]=!0,s["font-variant-alternates"]=!0,s["font-variant-caps"]=!0,s["font-variant-east-asian"]=!0,s["font-variant-ligatures"]=!0,s["font-variant-numeric"]=!0,s["font-variant-position"]=!0,s["font-weight"]=!0,s.grid=!1,s["grid-area"]=!1,s["grid-auto-columns"]=!1,s["grid-auto-flow"]=!1,s["grid-auto-rows"]=!1,s["grid-column"]=!1,s["grid-column-end"]=!1,s["grid-column-start"]=!1,s["grid-row"]=!1,s["grid-row-end"]=!1,s["grid-row-start"]=!1,s["grid-template"]=!1,s["grid-template-areas"]=!1,s["grid-template-columns"]=!1,s["grid-template-rows"]=!1,s["hanging-punctuation"]=!1,s.height=!0,s.hyphens=!1,s.icon=!1,s["image-orientation"]=!1,s["image-resolution"]=!1,s["ime-mode"]=!1,s["initial-letters"]=!1,s["inline-box-align"]=!1,s["justify-content"]=!1,s["justify-items"]=!1,s["justify-self"]=!1,s.left=!1,s["letter-spacing"]=!0,s["lighting-color"]=!0,s["line-box-contain"]=!1,s["line-break"]=!1,s["line-grid"]=!1,s["line-height"]=!1,s["line-snap"]=!1,s["line-stacking"]=!1,s["line-stacking-ruby"]=!1,s["line-stacking-shift"]=!1,s["line-stacking-strategy"]=!1,s["list-style"]=!0,s["list-style-image"]=!0,s["list-style-position"]=!0,s["list-style-type"]=!0,s.margin=!0,s["margin-bottom"]=!0,s["margin-left"]=!0,s["margin-right"]=!0,s["margin-top"]=!0,s["marker-offset"]=!1,s["marker-side"]=!1,s.marks=!1,s.mask=!1,s["mask-box"]=!1,s["mask-box-outset"]=!1,s["mask-box-repeat"]=!1,s["mask-box-slice"]=!1,s["mask-box-source"]=!1,s["mask-box-width"]=!1,s["mask-clip"]=!1,s["mask-image"]=!1,s["mask-origin"]=!1,s["mask-position"]=!1,s["mask-repeat"]=!1,s["mask-size"]=!1,s["mask-source-type"]=!1,s["mask-type"]=!1,s["max-height"]=!0,s["max-lines"]=!1,s["max-width"]=!0,s["min-height"]=!0,s["min-width"]=!0,s["move-to"]=!1,s["nav-down"]=!1,s["nav-index"]=!1,s["nav-left"]=!1,s["nav-right"]=!1,s["nav-up"]=!1,s["object-fit"]=!1,s["object-position"]=!1,s.opacity=!1,s.order=!1,s.orphans=!1,s.outline=!1,s["outline-color"]=!1,s["outline-offset"]=!1,s["outline-style"]=!1,s["outline-width"]=!1,s.overflow=!1,s["overflow-wrap"]=!1,s["overflow-x"]=!1,s["overflow-y"]=!1,s.padding=!0,s["padding-bottom"]=!0,s["padding-left"]=!0,s["padding-right"]=!0,s["padding-top"]=!0,s.page=!1,s["page-break-after"]=!1,s["page-break-before"]=!1,s["page-break-inside"]=!1,s["page-policy"]=!1,s.pause=!1,s["pause-after"]=!1,s["pause-before"]=!1,s.perspective=!1,s["perspective-origin"]=!1,s.pitch=!1,s["pitch-range"]=!1,s["play-during"]=!1,s.position=!1,s["presentation-level"]=!1,s.quotes=!1,s["region-fragment"]=!1,s.resize=!1,s.rest=!1,s["rest-after"]=!1,s["rest-before"]=!1,s.richness=!1,s.right=!1,s.rotation=!1,s["rotation-point"]=!1,s["ruby-align"]=!1,s["ruby-merge"]=!1,s["ruby-position"]=!1,s["shape-image-threshold"]=!1,s["shape-outside"]=!1,s["shape-margin"]=!1,s.size=!1,s.speak=!1,s["speak-as"]=!1,s["speak-header"]=!1,s["speak-numeral"]=!1,s["speak-punctuation"]=!1,s["speech-rate"]=!1,s.stress=!1,s["string-set"]=!1,s["tab-size"]=!1,s["table-layout"]=!1,s["text-align"]=!0,s["text-align-last"]=!0,s["text-combine-upright"]=!0,s["text-decoration"]=!0,s["text-decoration-color"]=!0,s["text-decoration-line"]=!0,s["text-decoration-skip"]=!0,s["text-decoration-style"]=!0,s["text-emphasis"]=!0,s["text-emphasis-color"]=!0,s["text-emphasis-position"]=!0,s["text-emphasis-style"]=!0,s["text-height"]=!0,s["text-indent"]=!0,s["text-justify"]=!0,s["text-orientation"]=!0,s["text-overflow"]=!0,s["text-shadow"]=!0,s["text-space-collapse"]=!0,s["text-transform"]=!0,s["text-underline-position"]=!0,s["text-wrap"]=!0,s.top=!1,s.transform=!1,s["transform-origin"]=!1,s["transform-style"]=!1,s.transition=!1,s["transition-delay"]=!1,s["transition-duration"]=!1,s["transition-property"]=!1,s["transition-timing-function"]=!1,s["unicode-bidi"]=!1,s["vertical-align"]=!1,s.visibility=!1,s["voice-balance"]=!1,s["voice-duration"]=!1,s["voice-family"]=!1,s["voice-pitch"]=!1,s["voice-range"]=!1,s["voice-rate"]=!1,s["voice-stress"]=!1,s["voice-volume"]=!1,s.volume=!1,s["white-space"]=!1,s.widows=!1,s.width=!0,s["will-change"]=!1,s["word-break"]=!0,s["word-spacing"]=!0,s["word-wrap"]=!0,s["wrap-flow"]=!1,s["wrap-through"]=!1,s["writing-mode"]=!1,s["z-index"]=!1,s}function e(s,a,o){}function t(s,a,o){}var r=/javascript\s*\:/img;function n(s,a){return r.test(a)?"":a}return dN.whiteList=i(),dN.getDefaultWhiteList=i,dN.onAttr=e,dN.onIgnoreAttr=t,dN.safeAttrValue=n,dN}var sLe,vqt;function yqt(){return vqt||(vqt=1,sLe={indexOf:function(i,e){var t,r;if(Array.prototype.indexOf)return i.indexOf(e);for(t=0,r=i.length;t<r;t++)if(i[t]===e)return t;return-1},forEach:function(i,e,t){var r,n;if(Array.prototype.forEach)return i.forEach(e,t);for(r=0,n=i.length;r<n;r++)e.call(t,i[r],r,i)},trim:function(i){return String.prototype.trim?i.trim():i.replace(/(^\s*)|(\s*$)/g,"")},trimRight:function(i){return String.prototype.trimRight?i.trimRight():i.replace(/(\s*$)/g,"")}}),sLe}var aLe,Cqt;function Unn(){if(Cqt)return aLe;Cqt=1;var i=yqt();function e(t,r){t=i.trimRight(t),t[t.length-1]!==";"&&(t+=";");var n=t.length,s=!1,a=0,o=0,l="";function u(){if(!s){var h=i.trim(t.slice(a,o)),p=h.indexOf(":");if(p!==-1){var g=i.trim(h.slice(0,p)),x=i.trim(h.slice(p+1));if(g){var v=r(a,l.length,g,x,h);v&&(l+=v+"; ")}}}a=o+1}for(;o<n;o++){var c=t[o];if(c==="/"&&t[o+1]==="*"){var d=t.indexOf("*/",o+2);if(d===-1)break;o=d+1,a=o+1,s=!1}else c==="("?s=!0:c===")"?s=!1:c===";"?s||u():c===`
|
|
5239
5239
|
`&&u()}return i.trim(l)}return aLe=e,aLe}var oLe,Aqt;function Hnn(){if(Aqt)return oLe;Aqt=1;var i=xqt(),e=Unn();yqt();function t(s){return s==null}function r(s){var a={};for(var o in s)a[o]=s[o];return a}function n(s){s=r(s||{}),s.whiteList=s.whiteList||i.whiteList,s.onAttr=s.onAttr||i.onAttr,s.onIgnoreAttr=s.onIgnoreAttr||i.onIgnoreAttr,s.safeAttrValue=s.safeAttrValue||i.safeAttrValue,this.options=s}return n.prototype.process=function(s){if(s=s||"",s=s.toString(),!s)return"";var a=this,o=a.options,l=o.whiteList,u=o.onAttr,c=o.onIgnoreAttr,d=o.safeAttrValue,h=e(s,function(p,g,x,v,C){var I=l[x],S=!1;if(I===!0?S=I:typeof I=="function"?S=I(v):I instanceof RegExp&&(S=I.test(v)),S!==!0&&(S=!1),v=d(x,v),!!v){var T={position:g,sourcePosition:p,source:C,isWhite:S};if(S){var _=u(x,v,T);return t(_)?x+":"+v:_}else{var _=c(x,v,T);if(!t(_))return _}}});return h},oLe=n,oLe}var bqt;function lLe(){return bqt||(bqt=1,(function(i,e){var t=xqt(),r=Hnn();function n(a,o){var l=new r(o);return l.process(a)}e=i.exports=n,e.FilterCSS=r;for(var s in t)e[s]=t[s];typeof window<"u"&&(window.filterCSS=i.exports)})($pe,$pe.exports)),$pe.exports}var uLe,Iqt;function cLe(){return Iqt||(Iqt=1,uLe={indexOf:function(i,e){var t,r;if(Array.prototype.indexOf)return i.indexOf(e);for(t=0,r=i.length;t<r;t++)if(i[t]===e)return t;return-1},forEach:function(i,e,t){var r,n;if(Array.prototype.forEach)return i.forEach(e,t);for(r=0,n=i.length;r<n;r++)e.call(t,i[r],r,i)},trim:function(i){return String.prototype.trim?i.trim():i.replace(/(^\s*)|(\s*$)/g,"")},spaceIndex:function(i){var e=/\s|\n|\t/,t=e.exec(i);return t?t.index:-1}}),uLe}var Dqt;function Eqt(){if(Dqt)return m0;Dqt=1;var i=lLe().FilterCSS,e=lLe().getDefaultWhiteList,t=cLe();function r(){return{a:["target","href","title"],abbr:["title"],address:[],area:["shape","coords","href","alt"],article:[],aside:[],audio:["autoplay","controls","crossorigin","loop","muted","preload","src"],b:[],bdi:["dir"],bdo:["dir"],big:[],blockquote:["cite"],br:[],caption:[],center:[],cite:[],code:[],col:["align","valign","span","width"],colgroup:["align","valign","span","width"],dd:[],del:["datetime"],details:["open"],div:[],dl:[],dt:[],em:[],figcaption:[],figure:[],font:["color","size","face"],footer:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],header:[],hr:[],i:[],img:["src","alt","title","width","height","loading"],ins:["datetime"],kbd:[],li:[],mark:[],nav:[],ol:[],p:[],pre:[],s:[],section:[],small:[],span:[],sub:[],summary:[],sup:[],strong:[],strike:[],table:["width","border","align","valign"],tbody:["align","valign"],td:["width","rowspan","colspan","align","valign"],tfoot:["align","valign"],th:["width","rowspan","colspan","align","valign"],thead:["align","valign"],tr:["rowspan","align","valign"],tt:[],u:[],ul:[],video:["autoplay","controls","crossorigin","loop","muted","playsinline","poster","preload","src","height","width"]}}var n=new i;function s(K,q,J){}function a(K,q,J){}function o(K,q,J){}function l(K,q,J){}function u(K){return K.replace(d,"<").replace(h,">")}function c(K,q,J,ie){if(J=k(J),q==="href"||q==="src"){if(J=t.trim(J),J==="#")return"#";if(!(J.substr(0,7)==="http://"||J.substr(0,8)==="https://"||J.substr(0,7)==="mailto:"||J.substr(0,4)==="tel:"||J.substr(0,11)==="data:image/"||J.substr(0,6)==="ftp://"||J.substr(0,2)==="./"||J.substr(0,3)==="../"||J[0]==="#"||J[0]==="/"))return""}else if(q==="background"){if(I.lastIndex=0,I.test(J))return""}else if(q==="style"){if(S.lastIndex=0,S.test(J)||(T.lastIndex=0,T.test(J)&&(I.lastIndex=0,I.test(J))))return"";ie!==!1&&(ie=ie||n,J=ie.process(J))}return J=V(J),J}var d=/</g,h=/>/g,p=/"/g,g=/"/g,x=/&#([a-zA-Z0-9]*);?/gim,v=/:?/gim,C=/&newline;?/gim,I=/((j\s*a\s*v\s*a|v\s*b|l\s*i\s*v\s*e)\s*s\s*c\s*r\s*i\s*p\s*t\s*|m\s*o\s*c\s*h\s*a):/gi,S=/e\s*x\s*p\s*r\s*e\s*s\s*s\s*i\s*o\s*n\s*\(.*/gi,T=/u\s*r\s*l\s*\(.*/gi;function _(K){return K.replace(p,""")}function B(K){return K.replace(g,'"')}function P(K){return K.replace(x,function(J,ie){return ie[0]==="x"||ie[0]==="X"?String.fromCharCode(parseInt(ie.substr(1),16)):String.fromCharCode(parseInt(ie,10))})}function O(K){return K.replace(v,":").replace(C," ")}function L(K){for(var q="",J=0,ie=K.length;J<ie;J++)q+=K.charCodeAt(J)<32?" ":K.charAt(J);return t.trim(q)}function k(K){return K=B(K),K=P(K),K=O(K),K=L(K),K}function V(K){return K=_(K),K=u(K),K}function U(){return""}function z(K,q){typeof q!="function"&&(q=function(){});var J=!Array.isArray(K);function ie(oe){return J?!0:t.indexOf(K,oe)!==-1}var ce=[],ue=!1;return{onIgnoreTag:function(oe,he,ge){if(ie(oe))if(ge.isClosing){var de="[/removed]",me=ge.position+de.length;return ce.push([ue!==!1?ue:ge.position,me]),ue=!1,de}else return ue||(ue=ge.position),"[removed]";else return q(oe,he,ge)},remove:function(oe){var he="",ge=0;return t.forEach(ce,function(de){he+=oe.slice(ge,de[0]),ge=de[1]}),he+=oe.slice(ge),he}}}function Z(K){for(var q="",J=0;J<K.length;){var ie=K.indexOf("<!--",J);if(ie===-1){q+=K.slice(J);break}q+=K.slice(J,ie);var ce=K.indexOf("-->",ie);if(ce===-1)break;J=ce+3}return q}function j(K){var q=K.split("");return q=q.filter(function(J){var ie=J.charCodeAt(0);return ie===127?!1:ie<=31?ie===10||ie===13:!0}),q.join("")}return m0.whiteList=r(),m0.getDefaultWhiteList=r,m0.onTag=s,m0.onIgnoreTag=a,m0.onTagAttr=o,m0.onIgnoreTagAttr=l,m0.safeAttrValue=c,m0.escapeHtml=u,m0.escapeQuote=_,m0.unescapeQuote=B,m0.escapeHtmlEntities=P,m0.escapeDangerHtml5Entities=O,m0.clearNonPrintableCharacter=L,m0.friendlyAttrValue=k,m0.escapeAttrValue=V,m0.onIgnoreTagStripAll=U,m0.StripTagBody=z,m0.stripCommentTag=Z,m0.stripBlankChar=j,m0.attributeWrapSign='"',m0.cssFilter=n,m0.getDefaultCSSWhiteList=e,m0}var ege={},Sqt;function _qt(){if(Sqt)return ege;Sqt=1;var i=cLe();function e(d){var h=i.spaceIndex(d),p;return h===-1?p=d.slice(1,-1):p=d.slice(1,h+1),p=i.trim(p).toLowerCase(),p.slice(0,1)==="/"&&(p=p.slice(1)),p.slice(-1)==="/"&&(p=p.slice(0,-1)),p}function t(d){return d.slice(0,2)==="</"}function r(d,h,p){var g="",x=0,v=!1,C=!1,I=0,S=d.length,T="",_="";e:for(I=0;I<S;I++){var B=d.charAt(I);if(v===!1){if(B==="<"){v=I;continue}}else if(C===!1){if(B==="<"){g+=p(d.slice(x,I)),v=I,x=I;continue}if(B===">"||I===S-1){g+=p(d.slice(x,v)),_=d.slice(v,I+1),T=e(_),g+=h(v,g.length,T,_,t(_)),x=I+1,v=!1;continue}if(B==='"'||B==="'")for(var P=1,O=d.charAt(I-P);O.trim()===""||O==="=";){if(O==="="){C=B;continue e}O=d.charAt(I-++P)}}else if(B===C){C=!1;continue}}return x<S&&(g+=p(d.substr(x))),g}var n=/[^a-zA-Z0-9\\_:.-]/gim;function s(d,h){var p=0,g=0,x=[],v=!1,C=d.length;function I(P,O){if(P=i.trim(P),P=P.replace(n,"").toLowerCase(),!(P.length<1)){var L=h(P,O||"");L&&x.push(L)}}for(var S=0;S<C;S++){var T=d.charAt(S),_,B;if(v===!1&&T==="="){v=d.slice(p,S),p=S+1,g=d.charAt(p)==='"'||d.charAt(p)==="'"?p:o(d,S+1);continue}if(v!==!1&&S===g){if(B=d.indexOf(T,S+1),B===-1)break;_=i.trim(d.slice(g+1,B)),I(v,_),v=!1,S=B,p=S+1;continue}if(/\s|\n|\t/.test(T))if(d=d.replace(/\s|\n|\t/g," "),v===!1)if(B=a(d,S),B===-1){_=i.trim(d.slice(p,S)),I(_),v=!1,p=S+1;continue}else{S=B-1;continue}else if(B=l(d,S-1),B===-1){_=i.trim(d.slice(p,S)),_=c(_),I(v,_),v=!1,p=S+1;continue}else continue}return p<d.length&&(v===!1?I(d.slice(p)):I(v,c(i.trim(d.slice(p))))),i.trim(x.join(" "))}function a(d,h){for(;h<d.length;h++){var p=d[h];if(p!==" ")return p==="="?h:-1}}function o(d,h){for(;h<d.length;h++){var p=d[h];if(p!==" ")return p==="'"||p==='"'?h:-1}}function l(d,h){for(;h>0;h--){var p=d[h];if(p!==" ")return p==="="?h:-1}}function u(d){return d[0]==='"'&&d[d.length-1]==='"'||d[0]==="'"&&d[d.length-1]==="'"}function c(d){return u(d)?d.substr(1,d.length-2):d}return ege.parseTag=r,ege.parseAttr=s,ege}var dLe,Tqt;function Znn(){if(Tqt)return dLe;Tqt=1;var i=lLe().FilterCSS,e=Eqt(),t=_qt(),r=t.parseTag,n=t.parseAttr,s=cLe();function a(d){return d==null}function o(d){var h=s.spaceIndex(d);if(h===-1)return{html:"",closing:d[d.length-2]==="/"};d=s.trim(d.slice(h+1,-1));var p=d[d.length-1]==="/";return p&&(d=s.trim(d.slice(0,-1))),{html:d,closing:p}}function l(d){var h={};for(var p in d)h[p]=d[p];return h}function u(d){var h={};for(var p in d)Array.isArray(d[p])?h[p.toLowerCase()]=d[p].map(function(g){return g.toLowerCase()}):h[p.toLowerCase()]=d[p];return h}function c(d){d=l(d||{}),d.stripIgnoreTag&&(d.onIgnoreTag,d.onIgnoreTag=e.onIgnoreTagStripAll),d.whiteList||d.allowList?d.whiteList=u(d.whiteList||d.allowList):d.whiteList=e.whiteList,this.attributeWrapSign=d.singleQuotedAttributeValue===!0?"'":e.attributeWrapSign,d.onTag=d.onTag||e.onTag,d.onTagAttr=d.onTagAttr||e.onTagAttr,d.onIgnoreTag=d.onIgnoreTag||e.onIgnoreTag,d.onIgnoreTagAttr=d.onIgnoreTagAttr||e.onIgnoreTagAttr,d.safeAttrValue=d.safeAttrValue||e.safeAttrValue,d.escapeHtml=d.escapeHtml||e.escapeHtml,this.options=d,d.css===!1?this.cssFilter=!1:(d.css=d.css||{},this.cssFilter=new i(d.css))}return c.prototype.process=function(d){if(d=d||"",d=d.toString(),!d)return"";var h=this,p=h.options,g=p.whiteList,x=p.onTag,v=p.onIgnoreTag,C=p.onTagAttr,I=p.onIgnoreTagAttr,S=p.safeAttrValue,T=p.escapeHtml,_=h.attributeWrapSign,B=h.cssFilter;p.stripBlankChar&&(d=e.stripBlankChar(d)),p.allowCommentTag||(d=e.stripCommentTag(d));var P=!1;p.stripIgnoreTagBody&&(P=e.StripTagBody(p.stripIgnoreTagBody,v),v=P.onIgnoreTag);var O=r(d,function(L,k,V,U,z){var Z={sourcePosition:L,position:k,isClosing:z,isWhite:Object.prototype.hasOwnProperty.call(g,V)},j=x(V,U,Z);if(!a(j))return j;if(Z.isWhite){if(Z.isClosing)return"</"+V+">";var K=o(U),q=g[V],J=n(K.html,function(ie,ce){var ue=s.indexOf(q,ie)!==-1,oe=C(V,ie,ce,ue);return a(oe)?ue?(ce=S(V,ie,ce,B),ce?ie+"="+_+ce+_:ie):(oe=I(V,ie,ce,ue),a(oe)?void 0:oe):oe});return U="<"+V,J&&(U+=" "+J),K.closing&&(U+=" /"),U+=">",U}else return j=v(V,U,Z),a(j)?T(U):j},T);return P&&(O=P.remove(O)),O},dLe=c,dLe}var Rqt;function znn(){return Rqt||(Rqt=1,(function(i,e){var t=Eqt(),r=_qt(),n=Znn();function s(o,l){var u=new n(l);return u.process(o)}e=i.exports=s,e.filterXSS=s,e.FilterXSS=n,(function(){for(var o in t)e[o]=t[o];for(var l in r)e[l]=r[l]})(),typeof window<"u"&&(window.filterXSS=i.exports);function a(){return typeof self<"u"&&typeof DedicatedWorkerGlobalScope<"u"&&self instanceof DedicatedWorkerGlobalScope}a()&&(self.filterXSS=i.exports)})(qpe,qpe.exports)),qpe.exports}var Xnn=znn();const Ynn=eT(Xnn),wqt="2.0.0",jnn=i=>{const e=Ht.cloneDeep(i);return e.version!==wqt?(e.version=wqt,e):i},Knn=["innerHTML"],Qnn=er({...er({name:"ShjSvg"}),props:{option:{},sources:{},useEvents:{}},setup(i){const e=ti(()=>jnn(i.option)),t=ti(()=>Ynn(e.value.code,{whiteList:{svg:["width","height","viewBox","xmlns","fill","stroke","stroke-width","opacity","style","class","id","xmlns:xlink"],g:["fill","stroke","stroke-width","opacity","transform","class","id"],path:["d","fill","stroke","stroke-width","opacity","transform","class","id"],rect:["width","height","x","y","rx","ry","fill","stroke","stroke-width","opacity","transform","class","id"],circle:["cx","cy","r","fill","stroke","stroke-width","opacity","transform","class","id"],ellipse:["cx","cy","rx","ry","fill","stroke","stroke-width","opacity","transform","class","id"],line:["x1","y1","x2","y2","stroke","stroke-width","opacity","transform","class","id"],polyline:["points","fill","stroke","stroke-width","opacity","transform","class","id"],polygon:["points","fill","stroke","stroke-width","opacity","transform","class","id"],text:["x","y","dx","dy","rotate","textLength","lengthAdjust","font-size","fill","stroke","stroke-width","opacity","transform","class","id","text-anchor"],tspan:["x","y","dx","dy","rotate","textLength","lengthAdjust","font-size","fill","stroke","stroke-width","opacity","transform","class","id"],defs:["class","id"],linearGradient:["id","x1","y1","x2","y2","gradientUnits","gradientTransform","spreadMethod","class"],radialGradient:["id","cx","cy","r","fx","fy","gradientUnits","gradientTransform","spreadMethod","class"],stop:["offset","stop-color","stop-opacity","class"],clipPath:["id","class"],pattern:["id","width","height","patternUnits","patternTransform","viewBox","preserveAspectRatio","class"],use:["href","x","y","width","height","fill","stroke","stroke-width","opacity","transform","class","id"],symbol:["id","viewBox","preserveAspectRatio","class"],image:["href","x","y","width","height","preserveAspectRatio","transform","class","id"],animate:["attributeName","from","to","begin","dur","repeatCount","fill","class","id"],animateMotion:["path","keyPoints","keyTimes","rotate","from","to","begin","dur","repeatCount","fill","class","id"],animateTransform:["attributeName","type","from","to","begin","dur","repeatCount","fill","class","id"],marker:["id","viewBox","refX","refY","markerWidth","markerHeight","orient","class"],foreignObject:["x","y","width","height","class","id"],filter:["id","x","y","width","height","filterUnits","primitiveUnits","class"],feGaussianBlur:["in","stdDeviation","class"],feOffset:["in","dx","dy","result","class"],feBlend:["in","in2","mode","class"],feColorMatrix:["in","type","values","class"],feComponentTransfer:["in","class"],feComposite:["in","in2","operator","k1","k2","k3","k4","class"],feFlood:["flood-color","flood-opacity","result","class"],feImage:["href","result","preserveAspectRatio","class"],feMerge:["class"],feMergeNode:["in","class"],feMorphology:["in","operator","radius","result","class"],feSpecularLighting:["in","surfaceScale","specularConstant","specularExponent","result","class"],feTile:["in","result","class"],feTurbulence:["baseFrequency","numOctaves","seed","stitchTiles","type","class"]},stripIgnoreTag:!0,stripIgnoreTagBody:["script"]}));return(r,n)=>(Vt(),kr("div",{class:"zerov-widget svg-wrap",innerHTML:t.value},null,8,Knn))}}),Fqt=zi(Qnn),Jnn=typeof WeakRef<"u";class hLe{constructor(e,t=!1,r,n){this.initialize(e,t,r,n)}initialize(e,t=!1,r,n){return this.mask=e,this.skipNextObservers=t,this.target=r,this.currentTarget=n,this}}class Bqt{constructor(e,t,r=null){this.callback=e,this.mask=t,this.scope=r,this._willBeUnregistered=!1,this.unregisterOnNextCall=!1,this._remove=null}remove(e=!1){this._remove&&this._remove(e)}}class Pt{static FromPromise(e,t){const r=new Pt;return e.then(n=>{r.notifyObservers(n)}).catch(n=>{if(t)t.notifyObservers(n);else throw n}),r}get observers(){return this._observers}constructor(e,t=!1){this.notifyIfTriggered=t,this._observers=new Array,this._numObserversMarkedAsDeleted=0,this._hasNotified=!1,this._eventState=new hLe(0),e&&(this._onObserverAdded=e)}add(e,t=-1,r=!1,n=null,s=!1){if(!e)return null;const a=new Bqt(e,t,n);a.unregisterOnNextCall=s,r?this._observers.unshift(a):this._observers.push(a),this._onObserverAdded&&this._onObserverAdded(a),this._hasNotified&&this.notifyIfTriggered&&this._lastNotifiedValue!==void 0&&this.notifyObserver(a,this._lastNotifiedValue);const o=Jnn?new WeakRef(this):{deref:()=>this};return a._remove=(l=!1)=>{const u=o.deref();u&&(l?u.remove(a):u._remove(a))},a}addOnce(e){return this.add(e,void 0,void 0,void 0,!0)}remove(e){return e?(e._remove=null,this._observers.indexOf(e)!==-1?(this._deferUnregister(e),!0):!1):!1}removeCallback(e,t){for(let r=0;r<this._observers.length;r++){const n=this._observers[r];if(!n._willBeUnregistered&&n.callback===e&&(!t||t===n.scope))return this._deferUnregister(n),!0}return!1}_deferUnregister(e){e._willBeUnregistered||(this._numObserversMarkedAsDeleted++,e.unregisterOnNextCall=!1,e._willBeUnregistered=!0,setTimeout(()=>{this._remove(e)},0))}_remove(e,t=!0){if(!e)return!1;const r=this._observers.indexOf(e);return r!==-1?(t&&this._numObserversMarkedAsDeleted--,this._observers.splice(r,1),!0):!1}makeObserverTopPriority(e){this._remove(e,!1),this._observers.unshift(e)}makeObserverBottomPriority(e){this._remove(e,!1),this._observers.push(e)}notifyObservers(e,t=-1,r,n,s){if(this.notifyIfTriggered&&(this._hasNotified=!0,this._lastNotifiedValue=e),!this._observers.length)return!0;const a=this._eventState;a.mask=t,a.target=r,a.currentTarget=n,a.skipNextObservers=!1,a.lastReturnValue=e,a.userInfo=s;for(const o of this._observers)if(!o._willBeUnregistered&&(o.mask&t&&(o.unregisterOnNextCall&&this._deferUnregister(o),o.scope?a.lastReturnValue=o.callback.apply(o.scope,[e,a]):a.lastReturnValue=o.callback(e,a)),a.skipNextObservers))return!1;return!0}notifyObserver(e,t,r=-1){if(this.notifyIfTriggered&&(this._hasNotified=!0,this._lastNotifiedValue=t),e._willBeUnregistered)return;const n=this._eventState;n.mask=r,n.skipNextObservers=!1,e.unregisterOnNextCall&&this._deferUnregister(e),e.callback(t,n)}hasObservers(){return this._observers.length-this._numObserversMarkedAsDeleted>0}clear(){for(;this._observers.length;){const e=this._observers.pop();e&&(e._remove=null)}this._onObserverAdded=null,this._numObserversMarkedAsDeleted=0,this.cleanLastNotifiedState()}cleanLastNotifiedState(){this._hasNotified=!1,this._lastNotifiedValue=void 0}clone(){const e=new Pt;return e._observers=this._observers.slice(0),e}hasSpecificMask(e=-1){for(const t of this._observers)if(t.mask&e||t.mask===e)return!0;return!1}}function x0(){return typeof window<"u"}function O7(){return typeof navigator<"u"}function L7(){return typeof document<"u"}function B$(i){let e="",t=i.firstChild;for(;t;)t.nodeType===3&&(e+=t.textContent),t=t.nextSibling;return e}const qnn={IsWindowObjectExist:x0,IsNavigatorAvailable:O7,IsDocumentAvailable:L7,GetDOMTextContent:B$};class at{static _CheckLimit(e,t){let r=at._LogLimitOutputs[e];return r?r.current++:(r={limit:t,current:1},at._LogLimitOutputs[e]=r),r.current<=r.limit}static _GenerateLimitMessage(e,t=1){const r=at._LogLimitOutputs[e];if(!r||!at.MessageLimitReached)return;const n=this._Levels[t];r.current===r.limit&&at[n.name](at.MessageLimitReached.replace(/%LIMIT%/g,""+r.limit).replace(/%TYPE%/g,n.name??""))}static _AddLogEntry(e){at._LogCache=e+at._LogCache,at.OnNewCacheEntry&&at.OnNewCacheEntry(e)}static _FormatMessage(e){const t=n=>n<10?"0"+n:""+n,r=new Date;return"["+t(r.getHours())+":"+t(r.getMinutes())+":"+t(r.getSeconds())+"]: "+e}static _LogDisabled(e,t){}static _LogEnabled(e=1,t,r){const n=Array.isArray(t)?t[0]:t;if(r!==void 0&&!at._CheckLimit(n,r))return;const s=at._FormatMessage(n),a=this._Levels[e],o=Array.isArray(t)?t.slice(1):[];a.logFunc&&a.logFunc("BJS - "+s,...o);const l=`<div style='color:${a.color}'>${s}</div><br>`;at._AddLogEntry(l),at._GenerateLimitMessage(n,e)}static get LogCache(){return at._LogCache}static ClearLogCache(){at._LogCache="",at._LogLimitOutputs={},at.errorsCount=0}static set LogLevels(e){at.Log=at._LogDisabled,at.Warn=at._LogDisabled,at.Error=at._LogDisabled;const t=[at.MessageLogLevel,at.WarningLogLevel,at.ErrorLogLevel];for(const r of t)if((e&r)===r){const n=this._Levels[r];at[n.name]=at._LogEnabled.bind(at,r)}}}at.NoneLogLevel=0,at.MessageLogLevel=1,at.WarningLogLevel=2,at.ErrorLogLevel=4,at.AllLogLevel=7,at.MessageLimitReached="Too many %TYPE%s (%LIMIT%), no more %TYPE%s will be reported for this message.",at._LogCache="",at._LogLimitOutputs={},at._Levels=[{},{color:"white",logFunc:console.log,name:"Log"},{color:"orange",logFunc:console.warn,name:"Warn"},{},{color:"red",logFunc:console.error,name:"Error"}],at.errorsCount=0,at.Log=at._LogEnabled.bind(at,at.MessageLogLevel),at.Warn=at._LogEnabled.bind(at,at.WarningLogLevel),at.Error=at._LogEnabled.bind(at,at.ErrorLogLevel);const Pqt=(i,e,t)=>!i||i.getClassName&&i.getClassName()==="Mesh"?null:i.getClassName&&(i.getClassName()==="SubMesh"||i.getClassName()==="PhysicsBody")?i.clone(e):i.clone?i.clone():Array.isArray(i)?i.slice():t&&typeof i=="object"?{...i}:null;function $nn(i){const e=[];do{const t=Object.getOwnPropertyNames(i);for(const r of t)e.indexOf(r)===-1&&e.push(r)}while(i=Object.getPrototypeOf(i));return e}class wp{static DeepCopy(e,t,r,n,s=!1){const a=$nn(e);for(const o of a){if(o[0]==="_"&&(!n||n.indexOf(o)===-1)||o.endsWith("Observable")||r&&r.indexOf(o)!==-1)continue;const l=e[o],u=typeof l;if(u!=="function")try{if(u==="object")if(l instanceof Uint8Array)t[o]=Uint8Array.from(l);else if(l instanceof Array){if(t[o]=[],l.length>0)if(typeof l[0]=="object")for(let c=0;c<l.length;c++){const d=Pqt(l[c],t,s);t[o].indexOf(d)===-1&&t[o].push(d)}else t[o]=l.slice(0)}else t[o]=Pqt(l,t,s);else t[o]=l}catch(c){at.Warn(c.message)}}}}class Mo{static get Now(){return x0()&&window.performance&&window.performance.now?window.performance.now():Date.now()}}const Nqt={};function Hs(i,e=!1){if(!(e&&Nqt[i]))return Nqt[i]=!0,`${i} needs to be imported before as it contains a side-effect required by your code.`}function esn(){return typeof _native<"u"&&_native.XMLHttpRequest?new _native.XMLHttpRequest:new XMLHttpRequest}class Pc{constructor(){this._xhr=esn(),this._requestURL=""}static get IsCustomRequestAvailable(){return Object.keys(Pc.CustomRequestHeaders).length>0||Pc.CustomRequestModifiers.length>0}get requestURL(){return this._requestURL}_injectCustomRequestHeaders(){if(!this._shouldSkipRequestModifications(this._requestURL))for(const e in Pc.CustomRequestHeaders){const t=Pc.CustomRequestHeaders[e];t&&this._xhr.setRequestHeader(e,t)}}_shouldSkipRequestModifications(e){return Pc.SkipRequestModificationForBabylonCDN&&(e.includes("preview.babylonjs.com")||e.includes("cdn.babylonjs.com"))}get onprogress(){return this._xhr.onprogress}set onprogress(e){this._xhr.onprogress=e}get readyState(){return this._xhr.readyState}get status(){return this._xhr.status}get statusText(){return this._xhr.statusText}get response(){return this._xhr.response}get responseURL(){return this._xhr.responseURL}get responseText(){return this._xhr.responseText}get responseType(){return this._xhr.responseType}set responseType(e){this._xhr.responseType=e}get timeout(){return this._xhr.timeout}set timeout(e){this._xhr.timeout=e}addEventListener(e,t,r){this._xhr.addEventListener(e,t,r)}removeEventListener(e,t,r){this._xhr.removeEventListener(e,t,r)}abort(){this._xhr.abort()}send(e){Pc.CustomRequestHeaders&&this._injectCustomRequestHeaders(),this._xhr.send(e)}open(e,t){for(const r of Pc.CustomRequestModifiers){if(this._shouldSkipRequestModifications(t))return;t=r(this._xhr,t)||t}t=t.replace("file:http:","http:"),t=t.replace("file:https:","https:"),this._requestURL=t,this._xhr.open(e,t,!0)}setRequestHeader(e,t){this._xhr.setRequestHeader(e,t)}getResponseHeader(e){return this._xhr.getResponseHeader(e)}}Pc.CustomRequestHeaders={},Pc.CustomRequestModifiers=new Array,Pc.SkipRequestModificationForBabylonCDN=!0;class cn{static get LastCreatedEngine(){return this.Instances.length===0?null:this.Instances[this.Instances.length-1]}static get LastCreatedScene(){return this._LastCreatedScene}}cn.Instances=[],cn.OnEnginesDisposedObservable=new Pt,cn._LastCreatedScene=null,cn.UseFallbackTexture=!0,cn.FallbackTexture="";class hN{}hN.FilesToLoad={};class Mqt{static ExponentialBackoff(e=3,t=500){return(r,n,s)=>n.status!==0||s>=e||r.indexOf("file:")!==-1?-1:Math.pow(2,s)*t}}class _5 extends Error{}_5._setPrototypeOf=Object.setPrototypeOf||((i,e)=>(i.__proto__=e,i));const BS={MeshInvalidPositionsError:0,UnsupportedTextureError:1e3,GLTFLoaderUnexpectedMagicError:2e3,SceneLoaderError:3e3,LoadFileError:4e3,RequestFileError:4001,ReadFileError:4002};class mb extends _5{constructor(e,t,r){super(e),this.errorCode=t,this.innerError=r,this.name="RuntimeError",_5._setPrototypeOf(this,mb.prototype)}}class P$ extends _5{constructor(e="Operation aborted"){super(e),this.name="AbortError",_5._setPrototypeOf(this,P$.prototype)}}const Oqt=(i,e)=>i.endsWith(e),Lqt=(i,e)=>i?i.startsWith(e):!1,fLe=i=>{if(typeof TextDecoder<"u")return new TextDecoder().decode(i);let e="";for(let t=0;t<i.byteLength;t++)e+=String.fromCharCode(i[t]);return e},HW=i=>{const e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";let t="",r,n,s,a,o,l,u,c=0;const d=ArrayBuffer.isView(i)?new Uint8Array(i.buffer,i.byteOffset,i.byteLength):new Uint8Array(i);for(;c<d.length;)r=d[c++],n=c<d.length?d[c++]:Number.NaN,s=c<d.length?d[c++]:Number.NaN,a=r>>2,o=(r&3)<<4|n>>4,l=(n&15)<<2|s>>6,u=s&63,isNaN(n)?l=u=64:isNaN(s)&&(u=64),t+=e.charAt(a)+e.charAt(o)+e.charAt(l)+e.charAt(u);return t},tge=i=>atob(i),rge=i=>{const e=tge(i),t=e.length,r=new Uint8Array(new ArrayBuffer(t));for(let n=0;n<t;n++)r[n]=e.charCodeAt(n);return r.buffer},kqt=(i,e)=>{let t=String(i);for(;t.length<e;)t="0"+t;return t},tsn={EndsWith:Oqt,StartsWith:Lqt,Decode:fLe,EncodeArrayBufferToBase64:HW,DecodeBase64ToString:tge,DecodeBase64ToBinary:rge,PadNumber:kqt},rsn="attribute",isn="varying";class N${constructor(){this.children=[]}isValid(e){return!0}process(e,t,r){let n="";if(this.line){let s=this.line;const a=t.processor;if(a){a.lineProcessor&&(s=a.lineProcessor(s,t.isFragment,t.processingContext));const o=t.processor?.attributeKeywordName??rsn,l=t.isFragment&&t.processor?.varyingFragmentKeywordName?t.processor?.varyingFragmentKeywordName:!t.isFragment&&t.processor?.varyingVertexKeywordName?t.processor?.varyingVertexKeywordName:isn;!t.isFragment&&a.attributeProcessor&&this.line.startsWith(o)?s=a.attributeProcessor(this.line,e,t.processingContext):a.varyingProcessor&&(a.varyingCheck?.(this.line,t.isFragment)||!a.varyingCheck&&this.line.startsWith(l))?s=a.varyingProcessor(this.line,t.isFragment,e,t.processingContext):a.uniformProcessor&&a.uniformRegexp&&a.uniformRegexp.test(this.line)?t.lookForClosingBracketForUniformBuffer||(s=a.uniformProcessor(this.line,t.isFragment,e,t.processingContext)):a.uniformBufferProcessor&&a.uniformBufferRegexp&&a.uniformBufferRegexp.test(this.line)?t.lookForClosingBracketForUniformBuffer||(s=a.uniformBufferProcessor(this.line,t.isFragment,t.processingContext),t.lookForClosingBracketForUniformBuffer=!0):a.textureProcessor&&a.textureRegexp&&a.textureRegexp.test(this.line)?s=a.textureProcessor(this.line,t.isFragment,e,t.processingContext):(a.uniformProcessor||a.uniformBufferProcessor)&&this.line.startsWith("uniform")&&!t.lookForClosingBracketForUniformBuffer&&(/uniform\s+(?:(?:highp)?|(?:lowp)?)\s*(\S+)\s+(\S+)\s*;/.test(this.line)?a.uniformProcessor&&(s=a.uniformProcessor(this.line,t.isFragment,e,t.processingContext)):a.uniformBufferProcessor&&(s=a.uniformBufferProcessor(this.line,t.isFragment,t.processingContext),t.lookForClosingBracketForUniformBuffer=!0)),t.lookForClosingBracketForUniformBuffer&&this.line.indexOf("}")!==-1&&(t.lookForClosingBracketForUniformBuffer=!1,a.endOfUniformBufferProcessor&&(s=a.endOfUniformBufferProcessor(this.line,t.isFragment,t.processingContext)))}n+=s+`
|
|
5240
5240
|
`}for(const s of this.children)n+=s.process(e,t,r);return this.additionalDefineKey&&(e[this.additionalDefineKey]=this.additionalDefineValue||"true",r[this.additionalDefineKey]=e[this.additionalDefineKey]),n}}class nsn{constructor(){this._lines=[]}get currentLine(){return this._lines[this.lineIndex]}get canRead(){return this.lineIndex<this._lines.length-1}set lines(e){this._lines.length=0;for(const t of e){if(!t||t==="\r")continue;if(t[0]==="#"){this._lines.push(t);continue}const r=t.trim();if(!r)continue;if(r.startsWith("//")){this._lines.push(t);continue}const n=r.indexOf(";");if(n===-1)this._lines.push(r);else if(n===r.length-1)r.length>1&&this._lines.push(r);else{const s=t.split(";");for(let a=0;a<s.length;a++){let o=s[a];o&&(o=o.trim(),o&&this._lines.push(o+(a!==s.length-1?";":"")))}}}}}class pLe extends N${process(e,t,r){for(let n=0;n<this.children.length;n++){const s=this.children[n];if(s.isValid(e))return s.process(e,t,r)}return""}}class ssn extends N${isValid(e){return this.testExpression.isTrue(e)}}class Kh{isTrue(e){return!0}static postfixToInfix(e){const t=[];for(const r of e)if(Kh._OperatorPriority[r]===void 0)t.push(r);else{const n=t[t.length-1],s=t[t.length-2];t.length-=2,t.push(`(${s}${r}${n})`)}return t[t.length-1]}static infixToPostfix(e){const t=Kh._InfixToPostfixCache.get(e);if(t)return t.accessTime=Date.now(),t.result;if(!e.includes("&&")&&!e.includes("||")&&!e.includes(")")&&!e.includes("("))return[e];const r=[];let n=-1;const s=()=>{c=c.trim(),c!==""&&(r.push(c),c="")},a=d=>{n<Kh._Stack.length-1&&(Kh._Stack[++n]=d)},o=()=>Kh._Stack[n],l=()=>n===-1?"!!INVALID EXPRESSION!!":Kh._Stack[n--];let u=0,c="";for(;u<e.length;){const d=e.charAt(u),h=u<e.length-1?e.substring(u,2+u):"";if(d==="(")c="",a(d);else if(d===")"){for(s();n!==-1&&o()!=="(";)r.push(l());l()}else if(Kh._OperatorPriority[h]>1){for(s();n!==-1&&Kh._OperatorPriority[o()]>=Kh._OperatorPriority[h];)r.push(l());a(h),u++}else c+=d;u++}for(s();n!==-1;)o()==="("?l():r.push(l());return Kh._InfixToPostfixCache.size>=Kh.InfixToPostfixCacheLimitSize&&Kh.ClearCache(),Kh._InfixToPostfixCache.set(e,{result:r,accessTime:Date.now()}),r}static ClearCache(){const e=Array.from(Kh._InfixToPostfixCache.entries()).sort((t,r)=>t[1].accessTime-r[1].accessTime);for(let t=0;t<Kh.InfixToPostfixCacheCleanupSize;t++)Kh._InfixToPostfixCache.delete(e[t][0])}}Kh.InfixToPostfixCacheLimitSize=5e4,Kh.InfixToPostfixCacheCleanupSize=25e3,Kh._InfixToPostfixCache=new Map,Kh._OperatorPriority={")":0,"(":1,"||":2,"&&":3},Kh._Stack=["","","","","","","","","","","","","","","","","","","",""];class ige extends Kh{constructor(e,t=!1){super(),this.define=e,this.not=t}isTrue(e){let t=e[this.define]!==void 0;return this.not&&(t=!t),t}}class asn extends Kh{isTrue(e){return this.leftOperand.isTrue(e)||this.rightOperand.isTrue(e)}}class osn extends Kh{isTrue(e){return this.leftOperand.isTrue(e)&&this.rightOperand.isTrue(e)}}class lsn extends Kh{constructor(e,t,r){super(),this.define=e,this.operand=t,this.testValue=r}toString(){return`${this.define} ${this.operand} ${this.testValue}`}isTrue(e){let t=!1;const r=parseInt(e[this.define]!=null?e[this.define]:this.define),n=parseInt(e[this.testValue]!=null?e[this.testValue]:this.testValue);if(isNaN(r)||isNaN(n))return!1;switch(this.operand){case">":t=r>n;break;case"<":t=r<n;break;case"<=":t=r<=n;break;case">=":t=r>=n;break;case"==":t=r===n;break;case"!=":t=r!==n;break}return t}}const nge={};function Gqt(i,e,t=""){return t+(e?e+`
|
|
5241
5241
|
`:"")+i}function Vqt(i,e,t,r,n,s,a){const o=a||nge.loadFile;if(o)return o(i,e,t,r,n,s);throw Hs("FileTools")}function Wqt(i,e,t,r){if(i){e?i.IS_NDC_HALF_ZRANGE="":delete i.IS_NDC_HALF_ZRANGE,t?i.USE_REVERSE_DEPTHBUFFER="":delete i.USE_REVERSE_DEPTHBUFFER,r?i.USE_EXACT_SRGB_CONVERSIONS="":delete i.USE_EXACT_SRGB_CONVERSIONS;return}else{let n="";return e&&(n+="#define IS_NDC_HALF_ZRANGE"),t&&(n&&(n+=`
|