nk027 / bvar

Toolkit for the estimation of hierarchical Bayesian vector autoregressions. Implements hierarchical prior selection for conjugate priors in the fashion of Giannone, Lenza & Primiceri (2015). Allows for the computation of impulse responses and forecasts and provides functionality for assessing results.
https://cran.r-project.org/package=BVAR
Other
50 stars 21 forks source link

Todo: use optim Hessian for proposals (Question: Variance covariance matrix of proposal distribution) #94

Open NeilDiamond opened 2 months ago

NeilDiamond commented 2 months ago

Can anyone please explain this code in bvar giving the variance covariance matrix for the multivariate normal proposals? For the alpha parameter with bounds 1 to 3, for example, why should the J term be larger for values near 1 than for values near 3?

H <- diag(length(opt[["par"]])) mh[["scale_hess"]] J <- unlist(lapply(names(hyper), function(name) { exp(opt[["par"]][[name]])/(1 + exp(opt[["par"]][[name]]))^2 (priors[[name]][["max"]] - priors[[name]][["min"]]) })) ... if (hyper_n != 1) { J <- diag(J) } HH <- J %% H %% t(J)

Many thanks Neil

nk027 commented 2 months ago

Hi Neil, This is a heuristic that is only set at the start. There's two parts – the sigmoid-like part using the ML estimates, and a scalar that depends on the potential range of the parameter. The goal of these is to start off with a scale that allows the sampler to efficiently explore the posterior, which can be proxied by the acceptance rate. (There are also adaptations to the scale during the burn-in phase.) To be honest, I don't recall the idea behind the first part that would lead to larger scale for smaller values. Looking at it now, I'd think that the ² should be on the sigmoid and not the denominator... I'll look into this. (It might lead to better acceptance rates, but I assume that most parameters fall in a similar range, so the impact might be limited.)

NeilDiamond commented 2 months ago

Hi Nikolas,

Many thanks for that.

I thought I had understood that in terms of a transformation from the constrained space to an unconstrained space (see attached), but obviously I was wrong since the partial derivatives in my equation (1) are in terms of the unconstrained parameters, not the original parameters.

As you say the scale will be adapted during the burn-in phase in any case.

Again, thanks for a great package and your response to my questions.

Cheers, Neil

On 2024-09-26 21:08, Nikolas Kuschnig wrote:

Hi Neil, This is a heuristic that is only set at the start. There's two parts – the sigmoid-like part using the ML estimates, and a scalar that depends on the potential range of the parameter. The goal of these is to start off with a scale that allows the sampler to efficiently explore the posterior, which can be proxied by the acceptance rate. (There are also adaptations to the scale during the burn-in phase.) To be honest, I don't recall the idea behind the first part that would lead to larger scale for smaller values. Looking at it now, I'd think that the ² should be on the sigmoid and not the denominator... I'll look into this. (It might lead to better acceptance rates, but I assume that most parameters fall in a similar range, so the impact might be limited.)

-- Reply to this email directly, view it on GitHub [1], or unsubscribe [2]. You are receiving this because you authored the thread.Message ID: @.***>

Links:

[1] https://github.com/nk027/bvar/issues/94#issuecomment-2376640582 [2] https://github.com/notifications/unsubscribe-auth/ABEJDFX6JFJNWSJG5RDGWL3ZYPTLTAVCNFSM6AAAAABO4VWL3SVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGNZWGY2DANJYGI

--=_e74cec8f387369d5a297af3a52984a85 Content-Transfer-Encoding: base64 Content-Type: text/x-tex; name=CodeMotivationn.html Content-Disposition: attachment; filename=CodeMotivationn.html; size=20025

PCFET0NUWVBFIGh0bWw+CjxodG1sIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1s IiBsYW5nPSJlbiIgeG1sOmxhbmc9ImVuIj48aGVhZD4KCjxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4K PG1ldGEgbmFtZT0iZ2VuZXJhdG9yIiBjb250ZW50PSJxdWFydG8tMS41LjU3Ij4KCjxtZXRhIG5h bWU9InZpZXdwb3J0IiBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgsIGluaXRpYWwtc2NhbGU9 MS4wLCB1c2VyLXNjYWxhYmxlPXllcyI+CgoKPHRpdGxlPk1vdGl2YXRpb24gZm9yIENvZGUgaW4g QlZBUiBQYWNrYWdlPC90aXRsZT4KPHN0eWxlPgpjb2Rle3doaXRlLXNwYWNlOiBwcmUtd3JhcDt9 CnNwYW4uc21hbGxjYXBze2ZvbnQtdmFyaWFudDogc21hbGwtY2Fwczt9CmRpdi5jb2x1bW5ze2Rp c3BsYXk6IGZsZXg7IGdhcDogbWluKDR2dywgMS41ZW0pO30KZGl2LmNvbHVtbntmbGV4OiBhdXRv OyBvdmVyZmxvdy14OiBhdXRvO30KZGl2LmhhbmdpbmctaW5kZW50e21hcmdpbi1sZWZ0OiAxLjVl bTsgdGV4dC1pbmRlbnQ6IC0xLjVlbTt9CnVsLnRhc2stbGlzdHtsaXN0LXN0eWxlOiBub25lO30K dWwudGFzay1saXN0IGxpIGlucHV0W3R5cGU9ImNoZWNrYm94Il0gewogIHdpZHRoOiAwLjhlbTsK ICBtYXJnaW46IDAgMC44ZW0gMC4yZW0gLTFlbTsgLyogcXVhcnRvLXNwZWNpZmljLCBzZWUgaHR0 cHM6Ly9naXRodWIuY29tL3F1YXJ0by1kZXYvcXVhcnRvLWNsaS9pc3N1ZXMvNDU1NiAqLyAKICB2 ZXJ0aWNhbC1hbGlnbjogbWlkZGxlOwp9Cjwvc3R5bGU+CgoKPHNjcmlwdCBzcmM9IkNvZGVNb3Rp dmF0aW9ubl9maWxlcy9saWJzL2NsaXBib2FyZC9jbGlwYm9hcmQubWluLmpzIj48L3NjcmlwdD4K PHNjcmlwdCBzcmM9IkNvZGVNb3RpdmF0aW9ubl9maWxlcy9saWJzL3F1YXJ0by1odG1sL3F1YXJ0 by5qcyI+PC9zY3JpcHQ+CjxzY3JpcHQgc3JjPSJDb2RlTW90aXZhdGlvbm5fZmlsZXMvbGlicy9x dWFydG8taHRtbC9wb3BwZXIubWluLmpzIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9IkNvZGVNb3Rp dmF0aW9ubl9maWxlcy9saWJzL3F1YXJ0by1odG1sL3RpcHB5LnVtZC5taW4uanMiPjwvc2NyaXB0 Pgo8c2NyaXB0IHNyYz0iQ29kZU1vdGl2YXRpb25uX2ZpbGVzL2xpYnMvcXVhcnRvLWh0bWwvYW5j aG9yLm1pbi5qcyI+PC9zY3JpcHQ+CjxsaW5rIGhyZWY9IkNvZGVNb3RpdmF0aW9ubl9maWxlcy9s aWJzL3F1YXJ0by1odG1sL3RpcHB5LmNzcyIgcmVsPSJzdHlsZXNoZWV0Ij4KPGxpbmsgaHJlZj0i Q29kZU1vdGl2YXRpb25uX2ZpbGVzL2xpYnMvcXVhcnRvLWh0bWwvcXVhcnRvLXN5bnRheC1oaWdo bGlnaHRpbmcuY3NzIiByZWw9InN0eWxlc2hlZXQiIGlkPSJxdWFydG8tdGV4dC1oaWdobGlnaHRp bmctc3R5bGVzIj4KPHNjcmlwdCBzcmM9IkNvZGVNb3RpdmF0aW9ubl9maWxlcy9saWJzL2Jvb3Rz dHJhcC9ib290c3RyYXAubWluLmpzIj48L3NjcmlwdD4KPGxpbmsgaHJlZj0iQ29kZU1vdGl2YXRp b25uX2ZpbGVzL2xpYnMvYm9vdHN0cmFwL2Jvb3RzdHJhcC1pY29ucy5jc3MiIHJlbD0ic3R5bGVz aGVldCI+CjxsaW5rIGhyZWY9IkNvZGVNb3RpdmF0aW9ubl9maWxlcy9saWJzL2Jvb3RzdHJhcC9i b290c3RyYXAubWluLmNzcyIgcmVsPSJzdHlsZXNoZWV0IiBpZD0icXVhcnRvLWJvb3RzdHJhcCIg ZGF0YS1tb2RlPSJsaWdodCI+CgogIDxzY3JpcHQgc3JjPSJodHRwczovL2NkbmpzLmNsb3VkZmxh cmUuY29tL3BvbHlmaWxsL3YzL3BvbHlmaWxsLm1pbi5qcz9mZWF0dXJlcz1lczYiPjwvc2NyaXB0 PgogIDxzY3JpcHQgc3JjPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL21hdGhqYXhAMy9l czUvdGV4LWNodG1sLWZ1bGwuanMiIHR5cGU9InRleHQvamF2YXNjcmlwdCI+PC9zY3JpcHQ+Cgo8 c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+CmNvbnN0IHR5cGVzZXRNYXRoID0gKGVsKSA9 PiB7CiAgaWYgKHdpbmRvdy5NYXRoSmF4KSB7CiAgICAvLyBNYXRoSmF4IFR5cGVzZXQKICAgIHdp bmRvdy5NYXRoSmF4LnR5cGVzZXQoW2VsXSk7CiAgfSBlbHNlIGlmICh3aW5kb3cua2F0ZXgpIHsK ICAgIC8vIEthVGVYIFJlbmRlcgogICAgdmFyIG1hdGhFbGVtZW50cyA9IGVsLmdldEVsZW1lbnRz QnlDbGFzc05hbWUoIm1hdGgiKTsKICAgIHZhciBtYWNyb3MgPSBbXTsKICAgIGZvciAodmFyIGkg PSAwOyBpIDwgbWF0aEVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciB0ZXhUZXh0ID0g bWF0aEVsZW1lbnRzW2ldLmZpcnN0Q2hpbGQ7CiAgICAgIGlmIChtYXRoRWxlbWVudHNbaV0udGFn TmFtZSA9PSAiU1BBTiIpIHsKICAgICAgICB3aW5kb3cua2F0ZXgucmVuZGVyKHRleFRleHQuZGF0 YSwgbWF0aEVsZW1lbnRzW2ldLCB7CiAgICAgICAgICBkaXNwbGF5TW9kZTogbWF0aEVsZW1lbnRz W2ldLmNsYXNzTGlzdC5jb250YWlucygnZGlzcGxheScpLAogICAgICAgICAgdGhyb3dPbkVycm9y OiBmYWxzZSwKICAgICAgICAgIG1hY3JvczogbWFjcm9zLAogICAgICAgICAgZmxlcW46IGZhbHNl CiAgICAgICAgfSk7CiAgICAgIH0KICAgIH0KICB9Cn0Kd2luZG93LlF1YXJ0byA9IHsKICB0eXBl c2V0TWF0aAp9Owo8L3NjcmlwdD4KCjwvaGVhZD4KCjxib2R5IGNsYXNzPSJmdWxsY29udGVudCI+ Cgo8ZGl2IGlkPSJxdWFydG8tY29udGVudCIgY2xhc3M9InBhZ2UtY29sdW1ucyBwYWdlLXJvd3Mt Y29udGVudHMgcGFnZS1sYXlvdXQtYXJ0aWNsZSI+Cgo8bWFpbiBjbGFzcz0iY29udGVudCIgaWQ9 InF1YXJ0by1kb2N1bWVudC1jb250ZW50Ij4KCjxoZWFkZXIgaWQ9InRpdGxlLWJsb2NrLWhlYWRl ciIgY2xhc3M9InF1YXJ0by10aXRsZS1ibG9jayBkZWZhdWx0Ij4KPGRpdiBjbGFzcz0icXVhcnRv LXRpdGxlIj4KPGgxIGNsYXNzPSJ0aXRsZSI+TW90aXZhdGlvbiBmb3IgQ29kZSBpbiBCVkFSIFBh Y2thZ2U8L2gxPgo8L2Rpdj4KCgoKPGRpdiBjbGFzcz0icXVhcnRvLXRpdGxlLW1ldGEiPgoKICAg IAogIAogICAgCiAgPC9kaXY+CiAgCgoKPC9oZWFkZXI+CgoKPHA+QXNzdW1lIHR3byBjb25zdHJh aW5lZCBwYXJhbWV0ZXJzLCBzYXkgPHNwYW4gY2xhc3M9Im1hdGggaW5saW5lIj5cKFx0aGV0YV8x XCk8L3NwYW4+IGFuZCA8c3BhbiBjbGFzcz0ibWF0aCBpbmxpbmUiPlwoXHRoZXRhXzJcKTwvc3Bh bj4gd2l0aCA8c3BhbiBjbGFzcz0ibWF0aCBkaXNwbGF5Ij5cW2FfaSAmbHQ7IFx0aGV0YV9pICZs dDsgYl9pOyAgXCBcIGk9MSwyLlxdPC9zcGFuPiBUaGVzZSBwYXJhbWV0ZXJzIGNhbiBiZSB0cmFu c2Zvcm1lZCBpbnRvIHVuY29uc3RyYWluZWQgcGFyYW1ldGVycyA8c3BhbiBjbGFzcz0ibWF0aCBk aXNwbGF5Ij5cW1xwaGlfaT1cbG9nXGxlZnQoXGZyYWN7XHRoZXRhX2ktYV9pfXtiX2ktXHRoZXRh X2l9XHJpZ2h0KVwgXCBpPTEsMi5cXTwvc3Bhbj4gVGhlIHJldmVyc2UgdHJhbnNmb3JtYXRpb24g aXMgPHNwYW4gY2xhc3M9Im1hdGggZGlzcGxheSI+XFtcdGhldGFfaT1cZnJhY3thX2krYl9pXGV4 cChccGhpX2kpfXsxK1xleHAoXHBoaV8xKX07XCBcIGk9MSwyLiBcXTwvc3Bhbj4gVGhlIEphY29i aWFuIG1hdHJpeCBpcyA8c3BhbiBjbGFzcz0ibWF0aCBkaXNwbGF5Ij5cW0o9XGxlZnRbIFxiZWdp bnthcnJheX17Y2N9ClxmcmFje1xwYXJ0aWFsXHRoZXRhXzF9e1xwYXJ0aWFsXHBoaV8xfSAmYW1w OwpcZnJhY3tccGFydGlhbFx0aGV0YV8yfXtccGFydGlhbFxwaGlfMX0gXFwKXGZyYWN7XHBhcnRp YWxcdGhldGFfMn17XHBhcnRpYWxccGhpXzJ9ICZhbXA7ClxmcmFje1xwYXJ0aWFsXHRoZXRhXzJ9 e1xwYXJ0aWFsXHBoaV8yfSBcXApcZW5ke2FycmF5fQpccmlnaHRdXF08L3NwYW4+IHdoZXJlIDxz cGFuIGlkPSJlcS0xIj48c3BhbiBjbGFzcz0ibWF0aCBkaXNwbGF5Ij5cW1xmcmFje1xwYXJ0aWFs XHRoZXRhX2l9e1xwYXJ0aWFsXHBoaV9pfT1cZnJhY3soYl9pLWFfaSlcZXhwKFxwaGlfaSl9eygx K1xleHAoXHBoaV9pKSleMn07XCBcIGk9MSwyLiBcdGFnezF9XF08L3NwYW4+PC9zcGFuPiB3aGls ZSA8c3BhbiBjbGFzcz0ibWF0aCBkaXNwbGF5Ij5cW1xmcmFje1xwYXJ0aWFsXHRoZXRhXzF9e1xw YXJ0aWFsXHBoaV8yfT1cZnJhY3tccGFydGlhbFx0aGV0YV8yfXtccGFydGlhbFxwaGlfMX09MC5c XTwvc3Bhbj4gQXNzdW1lIHRoZSBvcHRpbXVtIGluIHRoZSB1bmNvbnN0cmFpbmVkIHNwYWNlIGlz IGFjaGlldmVkIGF0IDxzcGFuIGNsYXNzPSJtYXRoIGlubGluZSI+XChcaGF0e1xtYXRoYmZ7XHBo aX19XCk8L3NwYW4+LiBUaGUgYXBwcm94aW1hdGUgdmFyaWFuY2UtY292YXJpYW5jZSBtYXRyaXgg aXMgZ2l2ZW4gYnkgPHNwYW4gY2xhc3M9Im1hdGggaW5saW5lIj5cKFxTaWdtYT0tSF57LTF9XCk8 L3NwYW4+IHdoZXJlIDxzcGFuIGNsYXNzPSJtYXRoIGlubGluZSI+XChIXCk8L3NwYW4+IGlzIHRo ZSBIZXNzaWFuIGdpdmVuIGJ5IHRoZSA8Y29kZT5vcHRpbTwvY29kZT4gZnVuY3Rpb24uIFRoZSBh cHByb3hpbWF0ZSB2YXJpYW5jZS1jb3ZhcmlhbmNlIG1hdHJpeCBpbiB0aGUgdHJhbnNmb3JtZWQg KGkuZS4mbmJzcDtvcmlnaW5hbCkgc3BhY2UgaXMgPHNwYW4gY2xhc3M9Im1hdGggZGlzcGxheSI+ XFtKXntccHJpbWV9XFNpZ21hIEpcXTwvc3Bhbj4uPC9wPgoKPC9tYWluPgo8IS0tIC9tYWluIGNv bHVtbiAtLT4KPHNjcmlwdCBpZD0icXVhcnRvLWh0bWwtYWZ0ZXItYm9keSIgdHlwZT0iYXBwbGlj YXRpb24vamF2YXNjcmlwdCI+CndpbmRvdy5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJET01D b250ZW50TG9hZGVkIiwgZnVuY3Rpb24gKGV2ZW50KSB7CiAgY29uc3QgdG9nZ2xlQm9keUNvbG9y TW9kZSA9IChic1NoZWV0RWwpID0+IHsKICAgIGNvbnN0IG1vZGUgPSBic1NoZWV0RWwuZ2V0QXR0 cmlidXRlKCJkYXRhLW1vZGUiKTsKICAgIGNvbnN0IGJvZHlFbCA9IHdpbmRvdy5kb2N1bWVudC5x dWVyeVNlbGVjdG9yKCJib2R5Iik7CiAgICBpZiAobW9kZSA9PT0gImRhcmsiKSB7CiAgICAgIGJv ZHlFbC5jbGFzc0xpc3QuYWRkKCJxdWFydG8tZGFyayIpOwogICAgICBib2R5RWwuY2xhc3NMaXN0 LnJlbW92ZSgicXVhcnRvLWxpZ2h0Iik7CiAgICB9IGVsc2UgewogICAgICBib2R5RWwuY2xhc3NM aXN0LmFkZCgicXVhcnRvLWxpZ2h0Iik7CiAgICAgIGJvZHlFbC5jbGFzc0xpc3QucmVtb3ZlKCJx dWFydG8tZGFyayIpOwogICAgfQogIH0KICBjb25zdCB0b2dnbGVCb2R5Q29sb3JQcmltYXJ5ID0g KCkgPT4gewogICAgY29uc3QgYnNTaGVldEVsID0gd2luZG93LmRvY3VtZW50LnF1ZXJ5U2VsZWN0 b3IoImxpbmsjcXVhcnRvLWJvb3RzdHJhcCIpOwogICAgaWYgKGJzU2hlZXRFbCkgewogICAgICB0 b2dnbGVCb2R5Q29sb3JNb2RlKGJzU2hlZXRFbCk7CiAgICB9CiAgfQogIHRvZ2dsZUJvZHlDb2xv clByaW1hcnkoKTsgIAogIGNvbnN0IGljb24gPSAi7qeLIjsKICBjb25zdCBhbmNob3JKUyA9IG5l dyB3aW5kb3cuQW5jaG9ySlMoKTsKICBhbmNob3JKUy5vcHRpb25zID0gewogICAgcGxhY2VtZW50 OiAncmlnaHQnLAogICAgaWNvbjogaWNvbgogIH07CiAgYW5jaG9ySlMuYWRkKCcuYW5jaG9yZWQn KTsKICBjb25zdCBpc0NvZGVBbm5vdGF0aW9uID0gKGVsKSA9PiB7CiAgICBmb3IgKGNvbnN0IGNs eiBvZiBlbC5jbGFzc0xpc3QpIHsKICAgICAgaWYgKGNsei5zdGFydHNXaXRoKCdjb2RlLWFubm90 YXRpb24tJykpIHsgICAgICAgICAgICAgICAgICAgICAKICAgICAgICByZXR1cm4gdHJ1ZTsKICAg ICAgfQogICAgfQogICAgcmV0dXJuIGZhbHNlOwogIH0KICBjb25zdCBvbkNvcHlTdWNjZXNzID0g ZnVuY3Rpb24oZSkgewogICAgLy8gYnV0dG9uIHRhcmdldAogICAgY29uc3QgYnV0dG9uID0gZS50 cmlnZ2VyOwogICAgLy8gZG9uJ3Qga2VlcCBmb2N1cwogICAgYnV0dG9uLmJsdXIoKTsKICAgIC8v IGZsYXNoICJjaGVja2VkIgogICAgYnV0dG9uLmNsYXNzTGlzdC5hZGQoJ2NvZGUtY29weS1idXR0 b24tY2hlY2tlZCcpOwogICAgdmFyIGN1cnJlbnRUaXRsZSA9IGJ1dHRvbi5nZXRBdHRyaWJ1dGUo InRpdGxlIik7CiAgICBidXR0b24uc2V0QXR0cmlidXRlKCJ0aXRsZSIsICJDb3BpZWQhIik7CiAg ICBsZXQgdG9vbHRpcDsKICAgIGlmICh3aW5kb3cuYm9vdHN0cmFwKSB7CiAgICAgIGJ1dHRvbi5z ZXRBdHRyaWJ1dGUoImRhdGEtYnMtdG9nZ2xlIiwgInRvb2x0aXAiKTsKICAgICAgYnV0dG9uLnNl dEF0dHJpYnV0ZSgiZGF0YS1icy1wbGFjZW1lbnQiLCAibGVmdCIpOwogICAgICBidXR0b24uc2V0 QXR0cmlidXRlKCJkYXRhLWJzLXRpdGxlIiwgIkNvcGllZCEiKTsKICAgICAgdG9vbHRpcCA9IG5l dyBib290c3RyYXAuVG9vbHRpcChidXR0b24sIAogICAgICAgIHsgdHJpZ2dlcjogIm1hbnVhbCIs IAogICAgICAgICAgY3VzdG9tQ2xhc3M6ICJjb2RlLWNvcHktYnV0dG9uLXRvb2x0aXAiLAogICAg ICAgICAgb2Zmc2V0OiBbMCwgLThdfSk7CiAgICAgIHRvb2x0aXAuc2hvdygpOyAgICAKICAgIH0K ICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7CiAgICAgIGlmICh0b29sdGlwKSB7CiAgICAgICAg dG9vbHRpcC5oaWRlKCk7CiAgICAgICAgYnV0dG9uLnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1icy10 aXRsZSIpOwogICAgICAgIGJ1dHRvbi5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtYnMtdG9nZ2xlIik7 CiAgICAgICAgYnV0dG9uLnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1icy1wbGFjZW1lbnQiKTsKICAg ICAgfQogICAgICBidXR0b24uc2V0QXR0cmlidXRlKCJ0aXRsZSIsIGN1cnJlbnRUaXRsZSk7CiAg ICAgIGJ1dHRvbi5jbGFzc0xpc3QucmVtb3ZlKCdjb2RlLWNvcHktYnV0dG9uLWNoZWNrZWQnKTsK ICAgIH0sIDEwMDApOwogICAgLy8gY2xlYXIgY29kZSBzZWxlY3Rpb24KICAgIGUuY2xlYXJTZWxl Y3Rpb24oKTsKICB9CiAgY29uc3QgZ2V0VGV4dFRvQ29weSA9IGZ1bmN0aW9uKHRyaWdnZXIpIHsK ICAgICAgY29uc3QgY29kZUVsID0gdHJpZ2dlci5wcmV2aW91c0VsZW1lbnRTaWJsaW5nLmNsb25l Tm9kZSh0cnVlKTsKICAgICAgZm9yIChjb25zdCBjaGlsZEVsIG9mIGNvZGVFbC5jaGlsZHJlbikg ewogICAgICAgIGlmIChpc0NvZGVBbm5vdGF0aW9uKGNoaWxkRWwpKSB7CiAgICAgICAgICBjaGls ZEVsLnJlbW92ZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gY29kZUVsLmlubmVy VGV4dDsKICB9CiAgY29uc3QgY2xpcGJvYXJkID0gbmV3IHdpbmRvdy5DbGlwYm9hcmRKUygnLmNv ZGUtY29weS1idXR0b246bm90KFtkYXRhLWluLXF1YXJ0by1tb2RhbF0pJywgewogICAgdGV4dDog Z2V0VGV4dFRvQ29weQogIH0pOwogIGNsaXBib2FyZC5vbignc3VjY2VzcycsIG9uQ29weVN1Y2Nl c3MpOwogIGlmICh3aW5kb3cuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3F1YXJ0by1lbWJlZGRl ZC1zb3VyY2UtY29kZS1tb2RhbCcpKSB7CiAgICAvLyBGb3IgY29kZSBjb250ZW50IGluc2lkZSBt b2RhbHMsIGNsaXBCb2FyZEpTIG5lZWRzIHRvIGJlIGluaXRpYWxpemVkIHdpdGggYSBjb250YWlu ZXIgb3B0aW9uCiAgICAvLyBUT0RPOiBDaGVjayB3aGVuIGl0IGNvdWxkIGJlIGEgZnVuY3Rpb24g KGh0dHBzOi8vZ2l0aHViLmNvbS96ZW5vcm9jaGEvY2xpcGJvYXJkLmpzL2lzc3Vlcy84NjApCiAg ICBjb25zdCBjbGlwYm9hcmRNb2RhbCA9IG5ldyB3aW5kb3cuQ2xpcGJvYXJkSlMoJy5jb2RlLWNv cHktYnV0dG9uW2RhdGEtaW4tcXVhcnRvLW1vZGFsXScsIHsKICAgICAgdGV4dDogZ2V0VGV4dFRv Q29weSwKICAgICAgY29udGFpbmVyOiB3aW5kb3cuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3F1 YXJ0by1lbWJlZGRlZC1zb3VyY2UtY29kZS1tb2RhbCcpCiAgICB9KTsKICAgIGNsaXBib2FyZE1v ZGFsLm9uKCdzdWNjZXNzJywgb25Db3B5U3VjY2Vzcyk7CiAgfQogICAgdmFyIGxvY2FsaG9zdFJl Z2V4ID0gbmV3IFJlZ0V4cCgvXig/Omh0dHB8aHR0cHMpOlwvXC9sb2NhbGhvc3RcOj9bMC05XSpc Ly8pOwogICAgdmFyIG1haWx0b1JlZ2V4ID0gbmV3IFJlZ0V4cCgvXm1haWx0bzovKTsKICAgICAg dmFyIGZpbHRlclJlZ2V4ID0gbmV3IFJlZ0V4cCgnLycgKyB3aW5kb3cubG9jYXRpb24uaG9zdCAr ICcvJyk7CiAgICB2YXIgaXNJbnRlcm5hbCA9IChocmVmKSA9PiB7CiAgICAgICAgcmV0dXJuIGZp bHRlclJlZ2V4LnRlc3QoaHJlZikgfHwgbG9jYWxob3N0UmVnZXgudGVzdChocmVmKSB8fCBtYWls dG9SZWdleC50ZXN0KGhyZWYpOwogICAgfQogICAgLy8gSW5zcGVjdCBub24tbmF2aWdhdGlvbiBs aW5rcyBhbmQgYWRvcm4gdGhlbSBpZiBleHRlcm5hbAogCXZhciBsaW5rcyA9IHdpbmRvdy5kb2N1 bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdhW2hyZWZdOm5vdCgubmF2LWxpbmspOm5vdCgubmF2YmFy LWJyYW5kKTpub3QoLnRvYy1hY3Rpb24pOm5vdCguc2lkZWJhci1saW5rKTpub3QoLnNpZGViYXIt aXRlbS10b2dnbGUpOm5vdCgucGFnaW5hdGlvbi1saW5rKTpub3QoLm5vLWV4dGVybmFsKTpub3Qo W2FyaWEtaGlkZGVuXSk6bm90KC5kcm9wZG93bi1pdGVtKTpub3QoLnF1YXJ0by1uYXZpZ2F0aW9u LXRvb2wpOm5vdCguYWJvdXQtbGluayknKTsKICAgIGZvciAodmFyIGk9MDsgaTxsaW5rcy5sZW5n dGg7IGkrKykgewogICAgICBjb25zdCBsaW5rID0gbGlua3NbaV07CiAgICAgIGlmICghaXNJbnRl cm5hbChsaW5rLmhyZWYpKSB7CiAgICAgICAgLy8gdW5kbyB0aGUgZGFtYWdlIHRoYXQgbWlnaHQg aGF2ZSBiZWVuIGRvbmUgYnkgcXVhcnRvLW5hdi5qcyBpbiB0aGUgY2FzZSBvZgogICAgICAgIC8v IGxpbmtzIHRoYXQgd2Ugd2FudCB0byBjb25zaWRlciBleHRlcm5hbAogICAgICAgIGlmIChsaW5r LmRhdGFzZXQub3JpZ2luYWxIcmVmICE9PSB1bmRlZmluZWQpIHsKICAgICAgICAgIGxpbmsuaHJl ZiA9IGxpbmsuZGF0YXNldC5vcmlnaW5hbEhyZWY7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAg ZnVuY3Rpb24gdGlwcHlIb3ZlcihlbCwgY29udGVudEZuLCBvblRyaWdnZXJGbiwgb25VbnRyaWdn ZXJGbikgewogICAgY29uc3QgY29uZmlnID0gewogICAgICBhbGxvd0hUTUw6IHRydWUsCiAgICAg IG1heFdpZHRoOiA1MDAsCiAgICAgIGRlbGF5OiAxMDAsCiAgICAgIGFycm93OiBmYWxzZSwKICAg ICAgYXBwZW5kVG86IGZ1bmN0aW9uKGVsKSB7CiAgICAgICAgICByZXR1cm4gZWwucGFyZW50RWxl bWVudDsKICAgICAgfSwKICAgICAgaW50ZXJhY3RpdmU6IHRydWUsCiAgICAgIGludGVyYWN0aXZl Qm9yZGVyOiAxMCwKICAgICAgdGhlbWU6ICdxdWFydG8nLAogICAgICBwbGFjZW1lbnQ6ICdib3R0 b20tc3RhcnQnLAogICAgfTsKICAgIGlmIChjb250ZW50Rm4pIHsKICAgICAgY29uZmlnLmNvbnRl bnQgPSBjb250ZW50Rm47CiAgICB9CiAgICBpZiAob25UcmlnZ2VyRm4pIHsKICAgICAgY29uZmln Lm9uVHJpZ2dlciA9IG9uVHJpZ2dlckZuOwogICAgfQogICAgaWYgKG9uVW50cmlnZ2VyRm4pIHsK ICAgICAgY29uZmlnLm9uVW50cmlnZ2VyID0gb25VbnRyaWdnZXJGbjsKICAgIH0KICAgIHdpbmRv dy50aXBweShlbCwgY29uZmlnKTsgCiAgfQogIGNvbnN0IG5vdGVyZWZzID0gd2luZG93LmRvY3Vt ZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2Fbcm9sZT0iZG9jLW5vdGVyZWYiXScpOwogIGZvciAodmFy IGk9MDsgaTxub3RlcmVmcy5sZW5ndGg7IGkrKykgewogICAgY29uc3QgcmVmID0gbm90ZXJlZnNb aV07CiAgICB0aXBweUhvdmVyKHJlZiwgZnVuY3Rpb24oKSB7CiAgICAgIC8vIHVzZSBpZCBvciBk YXRhIGF0dHJpYnV0ZSBpbnN0ZWFkIGhlcmUKICAgICAgbGV0IGhyZWYgPSByZWYuZ2V0QXR0cmli dXRlKCdkYXRhLWZvb3Rub3RlLWhyZWYnKSB8fCByZWYuZ2V0QXR0cmlidXRlKCdocmVmJyk7CiAg ICAgIHRyeSB7IGhyZWYgPSBuZXcgVVJMKGhyZWYpLmhhc2g7IH0gY2F0Y2gge30KICAgICAgY29u c3QgaWQgPSBocmVmLnJlcGxhY2UoL14jXC8/LywgIiIpOwogICAgICBjb25zdCBub3RlID0gd2lu ZG93LmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKTsKICAgICAgaWYgKG5vdGUpIHsKICAgICAg ICByZXR1cm4gbm90ZS5pbm5lckhUTUw7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuICIi OwogICAgICB9CiAgICB9KTsKICB9CiAgY29uc3QgeHJlZnMgPSB3aW5kb3cuZG9jdW1lbnQucXVl cnlTZWxlY3RvckFsbCgnYS5xdWFydG8teHJlZicpOwogIGNvbnN0IHByb2Nlc3NYUmVmID0gKGlk LCBub3RlKSA9PiB7CiAgICAvLyBTdHJpcCBjb2x1bW4gY29udGFpbmVyIGNsYXNzZXMKICAgIGNv bnN0IHN0cmlwQ29sdW1uQ2x6ID0gKGVsKSA9PiB7CiAgICAgIGVsLmNsYXNzTGlzdC5yZW1vdmUo InBhZ2UtZnVsbCIsICJwYWdlLWNvbHVtbnMiKTsKICAgICAgaWYgKGVsLmNoaWxkcmVuKSB7CiAg ICAgICAgZm9yIChjb25zdCBjaGlsZCBvZiBlbC5jaGlsZHJlbikgewogICAgICAgICAgc3RyaXBD b2x1bW5DbHooY2hpbGQpOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgc3RyaXBDb2x1bW5D bHoobm90ZSkKICAgIGlmIChpZCA9PT0gbnVsbCB8fCBpZC5zdGFydHNXaXRoKCdzZWMtJykpIHsK ICAgICAgLy8gU3BlY2lhbCBjYXNlIHNlY3Rpb25zLCBvbmx5IHRoZWlyIGZpcnN0IGNvdXBsZSBl bGVtZW50cwogICAgICBjb25zdCBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJk aXYiKTsKICAgICAgaWYgKG5vdGUuY2hpbGRyZW4gJiYgbm90ZS5jaGlsZHJlbi5sZW5ndGggPiAy KSB7CiAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKG5vdGUuY2hpbGRyZW5bMF0uY2xvbmVO b2RlKHRydWUpKTsKICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IG5vdGUuY2hpbGRyZW4ubGVu Z3RoOyBpKyspIHsKICAgICAgICAgIGNvbnN0IGNoaWxkID0gbm90ZS5jaGlsZHJlbltpXTsKICAg ICAgICAgIGlmIChjaGlsZC50YWdOYW1lID09PSAiUCIgJiYgY2hpbGQuaW5uZXJUZXh0ID09PSAi IikgewogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAg IGNvbnRhaW5lci5hcHBlbmRDaGlsZChjaGlsZC5jbG9uZU5vZGUodHJ1ZSkpOwogICAgICAgICAg ICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKHdpbmRvdy5RdWFydG8/ LnR5cGVzZXRNYXRoKSB7CiAgICAgICAgICB3aW5kb3cuUXVhcnRvLnR5cGVzZXRNYXRoKGNvbnRh aW5lcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb250YWluZXIuaW5uZXJIVE1MCiAgICAg IH0gZWxzZSB7CiAgICAgICAgaWYgKHdpbmRvdy5RdWFydG8/LnR5cGVzZXRNYXRoKSB7CiAgICAg ICAgICB3aW5kb3cuUXVhcnRvLnR5cGVzZXRNYXRoKG5vdGUpOwogICAgICAgIH0KICAgICAgICBy ZXR1cm4gbm90ZS5pbm5lckhUTUw7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIC8vIFJlbW92 ZSBhbnkgYW5jaG9yIGxpbmtzIGlmIHRoZXkgYXJlIHByZXNlbnQKICAgICAgY29uc3QgYW5jaG9y TGluayA9IG5vdGUucXVlcnlTZWxlY3RvcignYS5hbmNob3Jqcy1saW5rJyk7CiAgICAgIGlmIChh bmNob3JMaW5rKSB7CiAgICAgICAgYW5jaG9yTGluay5yZW1vdmUoKTsKICAgICAgfQogICAgICBp ZiAod2luZG93LlF1YXJ0bz8udHlwZXNldE1hdGgpIHsKICAgICAgICB3aW5kb3cuUXVhcnRvLnR5 cGVzZXRNYXRoKG5vdGUpOwogICAgICB9CiAgICAgIC8vIFRPRE8gaW4gMS41LCB3ZSBzaG91bGQg bWFrZSBzdXJlIHRoaXMgd29ya3Mgd2l0aG91dCBhIGNhbGxvdXQgc3BlY2lhbCBjYXNlCiAgICAg IGlmIChub3RlLmNsYXNzTGlzdC5jb250YWlucygiY2FsbG91dCIpKSB7CiAgICAgICAgcmV0dXJu IG5vdGUub3V0ZXJIVE1MOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBub3RlLmlubmVy SFRNTDsKICAgICAgfQogICAgfQogIH0KICBmb3IgKHZhciBpPTA7IGk8eHJlZnMubGVuZ3RoOyBp KyspIHsKICAgIGNvbnN0IHhyZWYgPSB4cmVmc1tpXTsKICAgIHRpcHB5SG92ZXIoeHJlZiwgdW5k ZWZpbmVkLCBmdW5jdGlvbihpbnN0YW5jZSkgewogICAgICBpbnN0YW5jZS5kaXNhYmxlKCk7CiAg ICAgIGxldCB1cmwgPSB4cmVmLmdldEF0dHJpYnV0ZSgnaHJlZicpOwogICAgICBsZXQgaGFzaCA9 IHVuZGVmaW5lZDsgCiAgICAgIGlmICh1cmwuc3RhcnRzV2l0aCgnIycpKSB7CiAgICAgICAgaGFz aCA9IHVybDsKICAgICAgfSBlbHNlIHsKICAgICAgICB0cnkgeyBoYXNoID0gbmV3IFVSTCh1cmwp Lmhhc2g7IH0gY2F0Y2gge30KICAgICAgfQogICAgICBpZiAoaGFzaCkgewogICAgICAgIGNvbnN0 IGlkID0gaGFzaC5yZXBsYWNlKC9eI1wvPy8sICIiKTsKICAgICAgICBjb25zdCBub3RlID0gd2lu ZG93LmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKTsKICAgICAgICBpZiAobm90ZSAhPT0gbnVs bCkgewogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgY29uc3QgaHRtbCA9IHByb2Nlc3NYUmVm KGlkLCBub3RlLmNsb25lTm9kZSh0cnVlKSk7CiAgICAgICAgICAgIGluc3RhbmNlLnNldENvbnRl bnQoaHRtbCk7CiAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBpbnN0YW5jZS5lbmFi bGUoKTsKICAgICAgICAgICAgaW5zdGFuY2Uuc2hvdygpOwogICAgICAgICAgfQogICAgICAgIH0g ZWxzZSB7CiAgICAgICAgICAvLyBTZWUgaWYgd2UgY2FuIGZldGNoIHRoaXMKICAgICAgICAgIGZl dGNoKHVybC5zcGxpdCgnIycpWzBdKQogICAgICAgICAgLnRoZW4ocmVzID0+IHJlcy50ZXh0KCkp CiAgICAgICAgICAudGhlbihodG1sID0+IHsKICAgICAgICAgICAgY29uc3QgcGFyc2VyID0gbmV3 IERPTVBhcnNlcigpOwogICAgICAgICAgICBjb25zdCBodG1sRG9jID0gcGFyc2VyLnBhcnNlRnJv bVN0cmluZyhodG1sLCAidGV4dC9odG1sIik7CiAgICAgICAgICAgIGNvbnN0IG5vdGUgPSBodG1s RG9jLmdldEVsZW1lbnRCeUlkKGlkKTsKICAgICAgICAgICAgaWYgKG5vdGUgIT09IG51bGwpIHsK ICAgICAgICAgICAgICBjb25zdCBodG1sID0gcHJvY2Vzc1hSZWYoaWQsIG5vdGUpOwogICAgICAg ICAgICAgIGluc3RhbmNlLnNldENvbnRlbnQoaHRtbCk7CiAgICAgICAgICAgIH0gCiAgICAgICAg ICB9KS5maW5hbGx5KCgpID0+IHsKICAgICAgICAgICAgaW5zdGFuY2UuZW5hYmxlKCk7CiAgICAg ICAgICAgIGluc3RhbmNlLnNob3coKTsKICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgfSBl bHNlIHsKICAgICAgICAvLyBTZWUgaWYgd2UgY2FuIGZldGNoIGEgZnVsbCB1cmwgKHdpdGggbm8g aGFzaCB0byB0YXJnZXQpCiAgICAgICAgLy8gVGhpcyBpcyBhIHNwZWNpYWwgY2FzZSBhbmQgd2Ug c2hvdWxkIHByb2JhYmx5IGRvIHNvbWUgY29udGVudCB0aGlubmluZyAvIHRhcmdldGluZwogICAg ICAgIGZldGNoKHVybCkKICAgICAgICAudGhlbihyZXMgPT4gcmVzLnRleHQoKSkKICAgICAgICAu dGhlbihodG1sID0+IHsKICAgICAgICAgIGNvbnN0IHBhcnNlciA9IG5ldyBET01QYXJzZXIoKTsK ICAgICAgICAgIGNvbnN0IGh0bWxEb2MgPSBwYXJzZXIucGFyc2VGcm9tU3RyaW5nKGh0bWwsICJ0 ZXh0L2h0bWwiKTsKICAgICAgICAgIGNvbnN0IG5vdGUgPSBodG1sRG9jLnF1ZXJ5U2VsZWN0b3Io J21haW4uY29udGVudCcpOwogICAgICAgICAgaWYgKG5vdGUgIT09IG51bGwpIHsKICAgICAgICAg ICAgLy8gVGhpcyBzaG91bGQgb25seSBoYXBwZW4gZm9yIGNoYXB0ZXIgY3Jvc3MgcmVmZXJlbmNl cwogICAgICAgICAgICAvLyAoc2luY2UgdGhlcmUgaXMgbm8gaWQgaW4gdGhlIFVSTCkKICAgICAg ICAgICAgLy8gcmVtb3ZlIHRoZSBmaXJzdCBoZWFkZXIKICAgICAgICAgICAgaWYgKG5vdGUuY2hp bGRyZW4ubGVuZ3RoID4gMCAmJiBub3RlLmNoaWxkcmVuWzBdLnRhZ05hbWUgPT09ICJIRUFERVIi KSB7CiAgICAgICAgICAgICAgbm90ZS5jaGlsZHJlblswXS5yZW1vdmUoKTsKICAgICAgICAgICAg fQogICAgICAgICAgICBjb25zdCBodG1sID0gcHJvY2Vzc1hSZWYobnVsbCwgbm90ZSk7CiAgICAg ICAgICAgIGluc3RhbmNlLnNldENvbnRlbnQoaHRtbCk7CiAgICAgICAgICB9IAogICAgICAgIH0p LmZpbmFsbHkoKCkgPT4gewogICAgICAgICAgaW5zdGFuY2UuZW5hYmxlKCk7CiAgICAgICAgICBp bnN0YW5jZS5zaG93KCk7CiAgICAgICAgfSk7CiAgICAgIH0KICAgIH0sIGZ1bmN0aW9uKGluc3Rh bmNlKSB7CiAgICB9KTsKICB9CiAgICAgIGxldCBzZWxlY3RlZEFubm90ZUVsOwogICAgICBjb25z dCBzZWxlY3RvckZvckFubm90YXRpb24gPSAoIGNlbGwsIGFubm90YXRpb24pID0+IHsKICAgICAg ICBsZXQgY2VsbEF0dHIgPSAnZGF0YS1jb2RlLWNlbGw9IicgKyBjZWxsICsgJyInOwogICAgICAg IGxldCBsaW5lQXR0ciA9ICdkYXRhLWNvZGUtYW5ub3RhdGlvbj0iJyArICBhbm5vdGF0aW9uICsg JyInOwogICAgICAgIGNvbnN0IHNlbGVjdG9yID0gJ3NwYW5bJyArIGNlbGxBdHRyICsgJ11bJyAr IGxpbmVBdHRyICsgJ10nOwogICAgICAgIHJldHVybiBzZWxlY3RvcjsKICAgICAgfQogICAgICBj b25zdCBzZWxlY3RDb2RlTGluZXMgPSAoYW5ub3RlRWwpID0+IHsKICAgICAgICBjb25zdCBkb2Mg PSB3aW5kb3cuZG9jdW1lbnQ7CiAgICAgICAgY29uc3QgdGFyZ2V0Q2VsbCA9IGFubm90ZUVsLmdl dEF0dHJpYnV0ZSgiZGF0YS10YXJnZXQtY2VsbCIpOwogICAgICAgIGNvbnN0IHRhcmdldEFubm90 YXRpb24gPSBhbm5vdGVFbC5nZXRBdHRyaWJ1dGUoImRhdGEtdGFyZ2V0LWFubm90YXRpb24iKTsK ICAgICAgICBjb25zdCBhbm5vdGVTcGFuID0gd2luZG93LmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Io c2VsZWN0b3JGb3JBbm5vdGF0aW9uKHRhcmdldENlbGwsIHRhcmdldEFubm90YXRpb24pKTsKICAg ICAgICBjb25zdCBsaW5lcyA9IGFubm90ZVNwYW4uZ2V0QXR0cmlidXRlKCJkYXRhLWNvZGUtbGlu ZXMiKS5zcGxpdCgiLCIpOwogICAgICAgIGNvbnN0IGxpbmVJZHMgPSBsaW5lcy5tYXAoKGxpbmUp ID0+IHsKICAgICAgICAgIHJldHVybiB0YXJnZXRDZWxsICsgIi0iICsgbGluZTsKICAgICAgICB9 KQogICAgICAgIGxldCB0b3AgPSBudWxsOwogICAgICAgIGxldCBoZWlnaHQgPSBudWxsOwogICAg ICAgIGxldCBwYXJlbnQgPSBudWxsOwogICAgICAgIGlmIChsaW5lSWRzLmxlbmd0aCA+IDApIHsK ICAgICAgICAgICAgLy9jb21wdXRlIHRoZSBwb3NpdGlvbiBvZiB0aGUgc2luZ2xlIGVsICh0b3Ag YW5kIGJvdHRvbSBhbmQgbWFrZSBhIGRpdikKICAgICAgICAgICAgY29uc3QgZWwgPSB3aW5kb3cu ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQobGluZUlkc1swXSk7CiAgICAgICAgICAgIHRvcCA9IGVs Lm9mZnNldFRvcDsKICAgICAgICAgICAgaGVpZ2h0ID0gZWwub2Zmc2V0SGVpZ2h0OwogICAgICAg ICAgICBwYXJlbnQgPSBlbC5wYXJlbnRFbGVtZW50LnBhcmVudEVsZW1lbnQ7CiAgICAgICAgICBp ZiAobGluZUlkcy5sZW5ndGggPiAxKSB7CiAgICAgICAgICAgIGNvbnN0IGxhc3RFbCA9IHdpbmRv dy5kb2N1bWVudC5nZXRFbGVtZW50QnlJZChsaW5lSWRzW2xpbmVJZHMubGVuZ3RoIC0gMV0pOwog ICAgICAgICAgICBjb25zdCBib3R0b20gPSBsYXN0RWwub2Zmc2V0VG9wICsgbGFzdEVsLm9mZnNl dEhlaWdodDsKICAgICAgICAgICAgaGVpZ2h0ID0gYm90dG9tIC0gdG9wOwogICAgICAgICAgfQog ICAgICAgICAgaWYgKHRvcCAhPT0gbnVsbCAmJiBoZWlnaHQgIT09IG51bGwgJiYgcGFyZW50ICE9 PSBudWxsKSB7CiAgICAgICAgICAgIC8vIGNvb2sgdXAgYSBkaXYgKGlmIG5lY2Vzc2FyeSkgYW5k IHBvc2l0aW9uIGl0IAogICAgICAgICAgICBsZXQgZGl2ID0gd2luZG93LmRvY3VtZW50LmdldEVs ZW1lbnRCeUlkKCJjb2RlLWFubm90YXRpb24tbGluZS1oaWdobGlnaHQiKTsKICAgICAgICAgICAg aWYgKGRpdiA9PT0gbnVsbCkgewogICAgICAgICAgICAgIGRpdiA9IHdpbmRvdy5kb2N1bWVudC5j cmVhdGVFbGVtZW50KCJkaXYiKTsKICAgICAgICAgICAgICBkaXYuc2V0QXR0cmlidXRlKCJpZCIs ICJjb2RlLWFubm90YXRpb24tbGluZS1oaWdobGlnaHQiKTsKICAgICAgICAgICAgICBkaXYuc3R5 bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnOwogICAgICAgICAgICAgIHBhcmVudC5hcHBlbmRDaGls ZChkaXYpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGRpdi5zdHlsZS50b3AgPSB0b3AgLSAy ICsgInB4IjsKICAgICAgICAgICAgZGl2LnN0eWxlLmhlaWdodCA9IGhlaWdodCArIDQgKyAicHgi OwogICAgICAgICAgICBkaXYuc3R5bGUubGVmdCA9IDA7CiAgICAgICAgICAgIGxldCBndXR0ZXJE aXYgPSB3aW5kb3cuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImNvZGUtYW5ub3RhdGlvbi1saW5l LWhpZ2hsaWdodC1ndXR0ZXIiKTsKICAgICAgICAgICAgaWYgKGd1dHRlckRpdiA9PT0gbnVsbCkg ewogICAgICAgICAgICAgIGd1dHRlckRpdiA9IHdpbmRvdy5kb2N1bWVudC5jcmVhdGVFbGVtZW50 KCJkaXYiKTsKICAgICAgICAgICAgICBndXR0ZXJEaXYuc2V0QXR0cmlidXRlKCJpZCIsICJjb2Rl LWFubm90YXRpb24tbGluZS1oaWdobGlnaHQtZ3V0dGVyIik7CiAgICAgICAgICAgICAgZ3V0dGVy RGl2LnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJzsKICAgICAgICAgICAgICBjb25zdCBjb2Rl Q2VsbCA9IHdpbmRvdy5kb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0YXJnZXRDZWxsKTsKICAgICAg ICAgICAgICBjb25zdCBndXR0ZXIgPSBjb2RlQ2VsbC5xdWVyeVNlbGVjdG9yKCcuY29kZS1hbm5v dGF0aW9uLWd1dHRlcicpOwogICAgICAgICAgICAgIGd1dHRlci5hcHBlbmRDaGlsZChndXR0ZXJE aXYpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGd1dHRlckRpdi5zdHlsZS50b3AgPSB0b3Ag LSAyICsgInB4IjsKICAgICAgICAgICAgZ3V0dGVyRGl2LnN0eWxlLmhlaWdodCA9IGhlaWdodCAr IDQgKyAicHgiOwogICAgICAgICAgfQogICAgICAgICAgc2VsZWN0ZWRBbm5vdGVFbCA9IGFubm90 ZUVsOwogICAgICAgIH0KICAgICAgfTsKICAgICAgY29uc3QgdW5zZWxlY3RDb2RlTGluZXMgPSAo KSA9PiB7CiAgICAgICAgY29uc3QgZWxlbWVudHNJZHMgPSBbImNvZGUtYW5ub3RhdGlvbi1saW5l LWhpZ2hsaWdodCIsICJjb2RlLWFubm90YXRpb24tbGluZS1oaWdobGlnaHQtZ3V0dGVyIl07CiAg ICAgICAgZWxlbWVudHNJZHMuZm9yRWFjaCgoZWxJZCkgPT4gewogICAgICAgICAgY29uc3QgZGl2 ID0gd2luZG93LmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsSWQpOwogICAgICAgICAgaWYgKGRp dikgewogICAgICAgICAgICBkaXYucmVtb3ZlKCk7CiAgICAgICAgICB9CiAgICAgICAgfSk7CiAg ICAgICAgc2VsZWN0ZWRBbm5vdGVFbCA9IHVuZGVmaW5lZDsKICAgICAgfTsKICAgICAgICAvLyBI YW5kbGUgcG9zaXRpb25pbmcgb2YgdGhlIHRvZ2dsZQogICAgd2luZG93LmFkZEV2ZW50TGlzdGVu ZXIoCiAgICAgICJyZXNpemUiLAogICAgICB0aHJvdHRsZSgoKSA9PiB7CiAgICAgICAgZWxSZWN0 ID0gdW5kZWZpbmVkOwogICAgICAgIGlmIChzZWxlY3RlZEFubm90ZUVsKSB7CiAgICAgICAgICBz ZWxlY3RDb2RlTGluZXMoc2VsZWN0ZWRBbm5vdGVFbCk7CiAgICAgICAgfQogICAgICB9LCAxMCkK ICAgICk7CiAgICBmdW5jdGlvbiB0aHJvdHRsZShmbiwgbXMpIHsKICAgIGxldCB0aHJvdHRsZSA9 IGZhbHNlOwogICAgbGV0IHRpbWVyOwogICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHsKICAgICAg ICBpZighdGhyb3R0bGUpIHsgLy8gZmlyc3QgY2FsbCBnZXRzIHRocm91Z2gKICAgICAgICAgICAg Zm4uYXBwbHkodGhpcywgYXJncyk7CiAgICAgICAgICAgIHRocm90dGxlID0gdHJ1ZTsKICAgICAg ICB9IGVsc2UgeyAvLyBhbGwgdGhlIG90aGVycyBnZXQgdGhyb3R0bGVkCiAgICAgICAgICAgIGlm KHRpbWVyKSBjbGVhclRpbWVvdXQodGltZXIpOyAvLyBjYW5jZWwgIzIKICAgICAgICAgICAgdGlt ZXIgPSBzZXRUaW1lb3V0KCgpID0+IHsKICAgICAgICAgICAgICBmbi5hcHBseSh0aGlzLCBhcmdz KTsKICAgICAgICAgICAgICB0aW1lciA9IHRocm90dGxlID0gZmFsc2U7CiAgICAgICAgICAgIH0s IG1zKTsKICAgICAgICB9CiAgICAgIH07CiAgICB9CiAgICAgIC8vIEF0dGFjaCBjbGljayBoYW5k bGVyIHRvIHRoZSBEVAogICAgICBjb25zdCBhbm5vdGVEbHMgPSB3aW5kb3cuZG9jdW1lbnQucXVl cnlTZWxlY3RvckFsbCgnZHRbZGF0YS10YXJnZXQtY2VsbF0nKTsKICAgICAgZm9yIChjb25zdCBh bm5vdGVEbE5vZGUgb2YgYW5ub3RlRGxzKSB7CiAgICAgICAgYW5ub3RlRGxOb2RlLmFkZEV2ZW50 TGlzdGVuZXIoJ2NsaWNrJywgKGV2ZW50KSA9PiB7CiAgICAgICAgICBjb25zdCBjbGlja2VkRWwg PSBldmVudC50YXJnZXQ7CiAgICAgICAgICBpZiAoY2xpY2tlZEVsICE9PSBzZWxlY3RlZEFubm90 ZUVsKSB7CiAgICAgICAgICAgIHVuc2VsZWN0Q29kZUxpbmVzKCk7CiAgICAgICAgICAgIGNvbnN0 IGFjdGl2ZUVsID0gd2luZG93LmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2R0W2RhdGEtdGFyZ2V0 LWNlbGxdLmNvZGUtYW5ub3RhdGlvbi1hY3RpdmUnKTsKICAgICAgICAgICAgaWYgKGFjdGl2ZUVs KSB7CiAgICAgICAgICAgICAgYWN0aXZlRWwuY2xhc3NMaXN0LnJlbW92ZSgnY29kZS1hbm5vdGF0 aW9uLWFjdGl2ZScpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNlbGVjdENvZGVMaW5lcyhj bGlja2VkRWwpOwogICAgICAgICAgICBjbGlja2VkRWwuY2xhc3NMaXN0LmFkZCgnY29kZS1hbm5v dGF0aW9uLWFjdGl2ZScpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gVW5zZWxl Y3QgdGhlIGxpbmUKICAgICAgICAgICAgdW5zZWxlY3RDb2RlTGluZXMoKTsKICAgICAgICAgICAg Y2xpY2tlZEVsLmNsYXNzTGlzdC5yZW1vdmUoJ2NvZGUtYW5ub3RhdGlvbi1hY3RpdmUnKTsKICAg ICAgICAgIH0KICAgICAgICB9KTsKICAgICAgfQogIGNvbnN0IGZpbmRDaXRlcyA9IChlbCkgPT4g ewogICAgY29uc3QgcGFyZW50RWwgPSBlbC5wYXJlbnRFbGVtZW50OwogICAgaWYgKHBhcmVudEVs KSB7CiAgICAgIGNvbnN0IGNpdGVzID0gcGFyZW50RWwuZGF0YXNldC5jaXRlczsKICAgICAgaWYg KGNpdGVzKSB7CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgIGVsLAogICAgICAgICAgY2l0ZXM6 IGNpdGVzLnNwbGl0KCcgJykKICAgICAgICB9OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVy biBmaW5kQ2l0ZXMoZWwucGFyZW50RWxlbWVudCkKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAg cmV0dXJuIHVuZGVmaW5lZDsKICAgIH0KICB9OwogIHZhciBiaWJsaW9yZWZzID0gd2luZG93LmRv Y3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2Fbcm9sZT0iZG9jLWJpYmxpb3JlZiJdJyk7CiAgZm9y ICh2YXIgaT0wOyBpPGJpYmxpb3JlZnMubGVuZ3RoOyBpKyspIHsKICAgIGNvbnN0IHJlZiA9IGJp Ymxpb3JlZnNbaV07CiAgICBjb25zdCBjaXRlSW5mbyA9IGZpbmRDaXRlcyhyZWYpOwogICAgaWYg KGNpdGVJbmZvKSB7CiAgICAgIHRpcHB5SG92ZXIoY2l0ZUluZm8uZWwsIGZ1bmN0aW9uKCkgewog ICAgICAgIHZhciBwb3B1cCA9IHdpbmRvdy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTsK ICAgICAgICBjaXRlSW5mby5jaXRlcy5mb3JFYWNoKGZ1bmN0aW9uKGNpdGUpIHsKICAgICAgICAg IHZhciBjaXRlRGl2ID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpOwogICAg ICAgICAgY2l0ZURpdi5jbGFzc0xpc3QuYWRkKCdoYW5naW5nLWluZGVudCcpOwogICAgICAgICAg Y2l0ZURpdi5jbGFzc0xpc3QuYWRkKCdjc2wtZW50cnknKTsKICAgICAgICAgIHZhciBiaWJsaW9E aXYgPSB3aW5kb3cuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3JlZi0nICsgY2l0ZSk7CiAgICAg ICAgICBpZiAoYmlibGlvRGl2KSB7CiAgICAgICAgICAgIGNpdGVEaXYuaW5uZXJIVE1MID0gYmli bGlvRGl2LmlubmVySFRNTDsKICAgICAgICAgIH0KICAgICAgICAgIHBvcHVwLmFwcGVuZENoaWxk KGNpdGVEaXYpOwogICAgICAgIH0pOwogICAgICAgIHJldHVybiBwb3B1cC5pbm5lckhUTUw7CiAg ICAgIH0pOwogICAgfQogIH0KfSk7Cjwvc2NyaXB0Pgo8L2Rpdj4gPCEtLSAvY29udGVudCAtLT4K CgoKCjwvYm9keT48L2h0bWw+ --=_e74cec8f387369d5a297af3a52984a85--