From 908dbcb8947e6db26ec9bcb206c3ae7c78b43879 Mon Sep 17 00:00:00 2001 From: niccostantini <65295160+niccostantini@users.noreply.github.com> Date: Wed, 9 Oct 2024 23:33:50 +0200 Subject: [PATCH 1/3] Add dist to .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 57d9462..c6863bb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +/dist + # Logs logs *.log From fb9146354dac717fca6a25ec7a2aca6dd04cf2b4 Mon Sep 17 00:00:00 2001 From: niccostantini <65295160+niccostantini@users.noreply.github.com> Date: Wed, 9 Oct 2024 23:34:52 +0200 Subject: [PATCH 2/3] Stop tracking dist folder --- dist/4373ba701fcf92e48a9e.png | Bin 700 -> 0 bytes dist/522c61dacbe66475b709.png | Bin 1479 -> 0 bytes dist/7a2dab2be5c29e53e51d.js | 1 - dist/7e687123cd4528224ce5.ttf | Bin 394140 -> 0 bytes dist/index.html | 1 - dist/main.js | 1 - 6 files changed, 3 deletions(-) delete mode 100644 dist/4373ba701fcf92e48a9e.png delete mode 100644 dist/522c61dacbe66475b709.png delete mode 100644 dist/7a2dab2be5c29e53e51d.js delete mode 100644 dist/7e687123cd4528224ce5.ttf delete mode 100644 dist/index.html delete mode 100644 dist/main.js diff --git a/dist/4373ba701fcf92e48a9e.png b/dist/4373ba701fcf92e48a9e.png deleted file mode 100644 index d80833a70d46d22f74f732fdb087cea98050b0a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 700 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGojKx9jP7LeL$-HD>U@G%;aSW-5 zdwVC>@34VDOX72`5Um1f3rX9k{KM^6j73~mTv*omw)d^<;yr)-Hovu*r^4H)_(9n> zVS-j(q>$bH8XP$gYd3 zoc`hXPX-I^n0EdKiy8(Q#%0?7jb=GdU_KP|!^AwA8GekRM7=Q_j4TUN-&`uE)#vkPzT+{!3% zyx7``d!g(B8>g(exB7LFiZQuY?xwEz%6upP{CbtelFPzUEDz)g2Yt?Pn0qAs+o5Dl z-$h$(MUOW}$|@YWf9M&X<5rg(--vl!4vikXEDT%>$EHtHVhG>}=wfhSZ4hE%&|+NU z%CJD`fE19)93jY%!I0p{ut3m3kBNbou}FX+gJ*&h!vRKxHiib_142v;eGJ7M3>M5j zf(!x-G0F@IOgj`lyno%wVB1qxueYL||L)~#28T6_z~sep9E$4g17FW RPQc{I;OXk;vd$@?2>|{n5N7}Y diff --git a/dist/522c61dacbe66475b709.png b/dist/522c61dacbe66475b709.png deleted file mode 100644 index b2ed9ac571bdad3880d5f5ad923e7f43931d1601..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1479 zcmV;&1vvVNP)Px)fk{L`RCr$PoNHF&FbstgW(UK8f!&mq0V|`k8Xi5cgCTR=o`9Ps)|D*TN-=-& z^M2Nq?WF0u_E%MbzH0BS^R5A?ya*bA2B5M6mAh{d&;V3cpmO&u0vdqI3RLdCML+{k zS%J#k!x8Yj+ikkfi_Pty%ZJKiKCA8_073kIxOfUPABOI+LC{+RB!F1_vD-C4czJst z!g#~jJuaLifI0Ek1|a~5*Q+-eivUvMuL;5wz!XO9s8|G$8n~B9Jiop_Py!==v|OA2(kDU01na6 zZ-@Th2*pbAvgNk$jLF1ttJWLZAU09!W}t zLY^m3V@O4i8Gup{sL7u^6K3vS5G%^r5t#xg0f7rZa*(2}NWLRt13*F&I|I&_;#h_J znJ`Z<%P4RMAjhxg6Y245DPtK9=)>7yzMZf3nASGda|u8bLh`i~hG&nadWBuPZby}vXPAOPUXJzD@JPR!}UA+~bQ8bDnL7y#rz#&rPo z9KapGbY)uE5!Eg_ZpzZoc3kBE4-in{eguFTc7y<+a{&Fi{B*Iov!Hl@lx;{4Yp3mE zIe-R$wG)rqH2@^(X+S_v+Vp~O03f~HI|)GYEi=k$=L$micML(JKMe@fIHY|z1aO>~sfp7-4<)1m#k-|c zU()uS0{DhN0SFUEe*q~K$;y627KE<2rEQ^fv@p0OeKtL9Ob^n2xFG+ zd}0`G07xNF3D69}Znx3+#k?y35(pFkZkrmmLixVi2#_RZ1b}ApEwo8uxVVMne3AcC<0fIq-41;IT43IYn?aHsR@p1RzdOQ4pKunGVv2o!)E;bRz9 z5LN?V2?7Oxx=QA387&~J3cwtMk^n;g+7MO;U<#o$0Bs1X1Q0{e1JG~7S5>SZZ%!?5 zwE#v4)P)$G1CGBFZFP6#{x+183^`?&0W5!@yCj5FM*sri7{EdFP>;IFECt~Q0Qh)9 zMV|sK0paWcAW@PkV-2AJ00>z^XaE2J)P2;^l?CGyIH6tx00KZDpx>N`yKDd$08$Vn z;g<^-wu4S*0p90@t%Hvky`_7D_aO=&qG6GCqF1|V0#%=!&LrhvKC8-QE| hGwU}1nF8ik{|~ejC9K9$yOaO`002ovPDHLkV1hxJZ|(p9 diff --git a/dist/7a2dab2be5c29e53e51d.js b/dist/7a2dab2be5c29e53e51d.js deleted file mode 100644 index 083feda..0000000 --- a/dist/7a2dab2be5c29e53e51d.js +++ /dev/null @@ -1 +0,0 @@ -import"./normalize.css";import"./styles.css";import Chart from"chart.js/auto";import Muted from"./assets/images/muted.png";import Unmuted from"./assets/images/unmuted.png";import ChartDataLabels from"chartjs-plugin-datalabels";document.addEventListener("DOMContentLoaded",(function(){const t=document.getElementById("countup");let e=null;requestAnimationFrame((function n(o){e||(e=o);const r=Math.min((o-e)/2500,1),a=(i=r)*(2-i);var i;t.textContent=Math.floor(34*a),r<1?requestAnimationFrame(n):t.textContent=34}))}));const ctx=document.getElementById("choirChart").getContext("2d"),choirChart=new Chart(ctx,{type:"pie",data:{labels:["Bassi","Tenori","Contralti","Soprani"],datasets:[{label:" ",data:[7,6,14,7],backgroundColor:["#e43b3bff","#568ea3ff","#5fb75f","#dba159ff"],borderColor:"#ffffff",borderWidth:2}]},options:{responsive:!0,animation:{duration:1e3,easing:"easeOutQuad",animateScale:!0},plugins:{legend:{position:"bottom",labels:{boxWidth:20,font:{size:14,weight:"bold"},color:"#333",padding:15,usePointStyle:!0}},tooltip:{enabled:!0},datalabels:{color:"#000",formatter:t=>t,anchor:"center",align:"center",offset:0,borderRadius:5,backgroundColor:"rgba(255, 255, 255, 0.8)",borderWidth:1,borderColor:"#ccc"}}}});document.addEventListener("DOMContentLoaded",(function(){const t=["il coro di Spin Time Labs.","aperto a tuttə.","per musicisti e no.","di sinistra.","divertente ed economico.","inclusivo."],e=document.getElementById("controcoroText");let n=0;function o(t){e.innerHTML="";let n=0;!function o(){n"),n++,setTimeout(o,100))}()}o(t[n]),setInterval((function(){n=(n+1)%t.length,o(t[n])}),3500)})),document.addEventListener("DOMContentLoaded",(function(){const t=document.querySelectorAll(".fadein"),e=new IntersectionObserver(((t,e)=>{t.forEach((t=>{t.isIntersecting&&(t.target.style.opacity=1,e.unobserve(t.target))}))}),{threshold:1});t.forEach((t=>{e.observe(t)}))})),document.getElementById("unmuteButton").addEventListener("click",(function(){const t=document.getElementById("backgroundVideo");t.muted?(t.muted=!t.muted,this.innerHTML=""):(t.muted=!t.muted,this.innerHTML="")})); \ No newline at end of file diff --git a/dist/7e687123cd4528224ce5.ttf b/dist/7e687123cd4528224ce5.ttf deleted file mode 100644 index 797c4a570ab4ec5b077a670bdcd53cfd5d680da6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 394140 zcmdpf2YgjUx9_yQ&q=SOk(``VLV6>OkVYzmmV{mdp|=1Dz4s<1Kqw;8n~F%0A|PS| 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

%k}0?+1EY%Q7sV=&(Uqv# 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

ipo@E zpB#0ZLS);YBrs@4-*qa}y$4vXg+(z3;AHuxz?l=N%`$Z_6KI`g;DU?>(`Aoo;j53R9_WQ< zrE%GGd}#lNI?Cz7dsF>uyuLdSz3-q`%kSfYCHlNhb?v*39qsS6;r(Fwa|X=!kpJX` zXPws0dHKT_`+cmwT5juW^`alWH#i?(oIfI-_sJvlp?ov*o06huvY{O^FMqU#bIpGV z{%5}8@3F0wOKqvMelpk9lrMAN5U*{lV_N$vdWTHwZANNG8-|~7E}{Md;~4dsdB;H` zYpEz`pwd3g$Sb~I=(9LFzV2(yigo_euKO!<+|K(d_rL3`Ggldkm+vPnOT512%J~1m zxc|iG|2jASZ+8V{$l|U)q&&sPui7$SmFO?jFKGHh@(Abb1GHe?Ea?OPH%?Jf`acu@ zWBZZ0pZ`03@83;oyttxy|G>)@tqX~9l_^`TA}*PUQ^#?eC3vZ=pNUM-&+yQggK0AH z;rbl%gJ?}L{u#c9sX8%-R8FDmd7Pi7!4=F;G-lusr0Y7xZ#}ealq)DV(Y4<=M7Up4 zJKmQVXSNZCu<#z0;m6is^%Zl7#c_&W^Y2K0)3A=s45D?G{TcUX$QeR?xIQc<^Aehp%VaWmfk5V9)>7hvTAnABOjqwpmmUuKEf4C^}QtcC$VR+db6y z_eywtxqoktxpK?3r_81Ie?6|~{qKK8O~NsE;GTb|{(*bmzh)LUj(@ANf3qAK`yV^p zza_4LIUHu9l+POC{aoT5YE|OiEs-xUcUqdwVeGwP-G619$G$DkxX$+e|K9UUxM$2% z)dG9(lj3$uv~k2^sgIsBg!?O zE$+i?qO~Qt{uNoop=kY$p99CyIi9y#lCFh`_Z#9eT6-qeve-@BUa?*ruUE6twMqBo znX|y?_pa7n*==Apx}WEraa|*{J#8

-5HGU5?sV-?KM8ZMU`T|5aDtPtyIW?ZMeQ z$LnmkX7@4wdZu7`;Qvd0hrqLZJ6Fy!zGrRWJJJ zvvczw_qqO7pce0T^Bxp!5T0q+dk63a-4END81G2GrM@D6@jhGIz{-cMy+;-25?!P7 z)2NMj&$=i*bMM7tl6NgEHR3w)zMXpM?=ZD3!uH`E{le)9KXwj7n(f_*&v3SE?i#<# zR=6y|9my*!6C6dypPfPG=c{+?FWNgUGxZG1r)e4fU;KTc=&U7+OXfeI{^C#Jp8Oda z=I?(@jpOLw5_X>aMnmT>7vJMW7CL5&zFB#r`IB=Uym1b-M$>7xMn!tX%S(!$byh6$ z75a_p!Ea}=x3d)L-_y#WzKhQTC6qoKJLvy0|LLMKgrWF;<98*`Tb>p7u48c<{f-^~ z?{V?+D#ye=IWNTbVP=jmvN1o#k7*kl19onvb+tB3`j5*H-+N}OdksG5W%M)cl(jc0 zi1uw6eLbH`{FWp1u5ppStTWv()$%dBP=|L_BK~aUjP93M*RDDGBbi5*Zfvi-nsap8 z(fYecCoEg|J({caxAM^^_RARV7RMdPwaBg{?JzG*we#7i&z19Yw!J-RWxjM=CdNfk zdXb-^xS|mC4clJ(Af7|wWc!{-kK&{GpS~hb#*9Jd&M+L^FQoDNa*KOQ=P>=93g7kJ zEc*?ZriTvEV{VD|Y19Fmp1M{Lr@zbyNj)! zOY<%hZKmh{I`(w^QCooju+I9P+fL$iF4e1^vFjMK`9IVvoPs~IiEZ_&c6+x^SPo<~ zrx&ixUqm^wMkV!&+C9?Fdj5lN%Ap@Cuazsje|b-MVBsT?ZM6T>HnzE2p94|m?DK)B zT^C0-$-k+jW9BpJ$vuFNM*6-l`&|BZX3>2RzYCD*D{aGN=xaMEhtf4&&*PUx?HbQJ z`g=6?&)V08i)knQJ%#?>PUG!&X4+4hpZXy#Zd>)M>pwR1PcwUNrEzP+^~d@yT&u0m z;&+td-+@yP8v)QLM_h_!|4Bj2Rp5{ct^t=AT&SK(5989*E6PtrPBxio70J-xcZqw})(9 zNQ~`degB!~Ke1ot=L|iiG(8gJ3N{Om)g#?PV)zs%o|%*M{kl`pQ1{O5T8KdEnd z!`F1p1|cuqn7>QylX{u8HW{gFJZopX-Wu18=2z{Lxcr4{@>wC7(^OvynuacN&v9WI zGJf}7+br{*K$yyU3a`MwmRI*o)w0VPYQ>WLqP-n+QzPnSwqYva%J8b41$~vb8UG9W zD5`suPy9D+*5+?BJ6#j7GkxVoS!)3GBAtGOgN2_19mlc$54u`j2WDaC6#G*xalPBy zFkavGPNDw)#QMK4zn0ezC}Xa&#c_Mz!*NP@wR=(dZn1emQZV&b_x*(Y(KJJ+*}M@0A~UWcoDAyY6{)AIwo61kgl1>QxC^^;f2FFF46!gCtq7@SKb%b|O;*p~j&{e6Y_JNiAs zJs;&XA4TOgom$cQ&v^smG2_S5lrLZtuKmhoqW1~(8m|9E`~L(ND9ZcChl;m#E>Cg$ zCeyOog@oesTljrHyiDy9ZC~7HoL_do7BD(W{$%UMdJ!jwNB*aO80*Y|+3SBv?Q&ps ziRR;Cd#kveIM?dOx#-uqd@;UlKGuDBI5*_d3ghDWO~;D*X5QbUXSeoU_a|9r3-KAO z){|#`@!vm4w*C8#{{GiK z6z%+9&-$bJQu~WGvpU9OCVZYs-Bo8b=c#&)%97y#(VP-~kLIapyjYyh%h7pU{Cu6c zYOvPL`Z{q(>Y2S2S>Gkl^JMl{nKrO;hUrD+q;K?ZBdwlb_0VV4`dgN0|7uy)GMU-S&@R*``dC`D*VA(fJO3q3+g;l@u`kT^ z4twn8|BdVZdB^`7?ZDX3dsO*Bv^NaL37lJhOOhFT#wRven=sDIM(?9|4$x;q(fx}} zw{X7Ddx>X#@f`4*h|4FQx5MZ4nO=DQp=HQ=N0aZmXOG5wvOlm1*OV<$Y^0-qACWTg z{zNzzWPGER`P+&1J|_|Jy&08H@5{KXcJC!KRQve1CdJ~zuh|@>cs+8Os84SLuySX35r11k^DFkr*d^X;D5mnGzJ_gl(e5S&P-co z+N{WQU!ja$bg%8DtIz&)p3mI3361EPSR%%Pv2NTx`d#zEkG?|~-kbVfRoti1eWS*# zztMeI#EI;=JNxWRe@Av%Yqc8d+FopL$Joz2JC6Lf)2rR9wd^@AW0-vP-7S5WO5bzh z@0!}ZtM9St8H4UWuVSp9#M-IPsiXUVd&kyxb%%Y?{xPnX-8YGOPW6`Ik3K?Q=fey? zP#^pHs9l&I`-`vHR`}KZTJP*w@>4FNbHSA4-jMJ5dog`CP1_)IJ|9|}jh+i@eO$rN z%o(_TxA$QpJ?6}Kt`B4OmT@}QOq&&Hh4V|%_w10ByVyLQtwH{YHKBOgUf&brElx|G z1I2NA)w$oeW&Ey2g2(ZmMYp7G(fnV+^U{Pe{iGapuko5t$qLdpMRRW^C2ltx3r#iJ z-c8Z7{^+Ca0^s5Wvu)h*H;&^pz3OjR7+ds7$mg=s^gRmB6Ew|qcSido>wjYGeh4k% z_D|aXl;O<1zaOUus<$6EIg^X~E@{la-+vGY^;{df7vb${=#PDz`1-<+$wx)$b&kK^zYt$lIK z-q*}IK+G@pR@rAvvaDH(%5f6w1!XmUqB^XdIm;cdbyZ^?A_hfzvC9Mzjw!gV#HVM7B@6ZW(Rb)qe z=6ogLDrXQ|dk&H_k;or%FJ`q_2@ZdVKdGf>D7=e6f9OZ+6^4*`1p`P6;_svxAK+R0 z_Zk=L#@ARcyxN*Q0Q>FP@!>bM$+pwH)Mr6CFr74hFA(LUf1fWZmzFawtLg6vb;+k3 zz(@F7IcyKsbpBt0>BMnnmThNgp}wY*A9}UIGN>QT+iaq-5a+LUdZw!5Gkmv1{o42m z->Zy%SAmZ5>gbG6c{O@ER`nf9eJ4fFcH`fSCZhA2<>3ij$ANOQL1u>?^Z>i2nYAs!}fgue5L;K(8HTffL0a z9S`)?;)2Yng6f2+oWVtByxPXGMe!^77VRCP#JCTwE%be3+9%hi_`Iic68Tdm%Dr0u zPXey`H^i93!Z|oucH$E4VK&A0PwG$m<;#M);XGK-fV#jnK^NMeaTD5wR|{wAkAJl- zsq8u8bzGQ_wFRxzHu7h2MLB3)=!cwRHq^p4dp_D;aFY4bxkmY`6m$TaLhVrIeE-Li zrq+)2tUcrQO|+ekql^x}$BDxSa%GIzypgRN`m^!2pZU@3;`e{HWP7oFowYM#BC(DY zX(i?}B5D83Sk(I?v(JmpdCX3q3+lSqB~j)uMm zVxqlVvDlnnX@8rWq<(ZhpI6W|R@D7l9JXtG9-?!_0epT)JH_`|PPgpMtv}+#9Q|zf zimlN_eWvOezd6dBnJ@HyNv0bo!cWiavxGSNf99H#3)uad+iN)2W#7lD$^D<&hPfzBxgz#nd{!&mwqBGvtlITN(%lE-7Ft*+vt5xS&RG8`tgb9+VEQ>Z5*+- zMeoYQwtBu~Yi4F`%d#pOQ|fmw9;0#L`2=Zu@xEMrlNqClY+}9ex;KZ4(-S6{U~zxw z=9qsY^^;hG>g$>se$UdicPEm+Q>3kRoh_xU8WA<*xefCw7X;F%OCSMLm#hqn5NueH}AqKY%_T9CBfj_`Q^Io~TV!JI-Ij z@h3UIk=`zjFMd_dRy;2GojHN|G<)7krfWFfU!t2>zlv*x-&t=DXnrBy0e!{;; zrf0*6cOb%hCdb&(`It{!|M;qLnUBt=x(-##U3Yu`C(*vlztLFI`&plXg`TY6Y;F$E zcPNvdDHp8(dCY@0e_|i5+u3_o8^he=de)cVGv-~_d~A#dC|BZlQem#-r- z{_d3b?J1kSKU8$Cp=Ue#w;}PV`>14Ywy%orIpzTS{h!UX5jR)gv3~LQ05v{&f5dum zohXOSv$Hetsvo^$L|RymqB}aNX5pl7n>T(_Y+a3?U&dGUUu;iNbe3JzN9G(G>!;*; z6Y*`zW^+LC0?`&lZI@Z$!}%%J)!!*<*yaL$I~j(N@!uz{rD+-)UG-UW{E5ec#^@Y{ zuC=AcXWmhX<_zUGN$#rumqV`kU+4MgLz&uHQ2i^kELUqE@k#o!h?rm5mu#VB3%N4B zqxx%E%`f>`xG3MGaa{LIoa*XF|JH%p>j&S-b=%rf@1fQ4T7i!KjS02YwMOfh_?zA8 z!qQLToM0CB!-8mDYZmePW{gQ~PyPF+nrFlns);i^P}Qrh}Zn^ zxnXvFGG|NCnO$rfznd0+w`*4Z#p|4X?`PS`)K1Co%+t|bU+`iwzN9d7O@{B4q!Y$x zmm%(#xc<3p<9mxSv)?|X+zVo#xqRh{S&fQ8}%3Su-x&y4!2?{-!Lx1 zek|GtX}sobSJgFsi5-8FT;sAnx+e3XoN&>s6m1{7M+-lXe)k`*|N5*!%dB;X>#22( z|4z$Wq&*epWqHCEtR3|IF^5kpFSgOT#Ju%|l_A4-!}-_J(Ix$ROV70B)D---wEE2A zzd7IQ$*$86`BwD4Q^{78G4VT>+?+*diHdp@&o$dOMxA0(4>ezE;kGLkU5 z?75j&O5nE4MVY;DG1JUf=C=}fTjE*UmQbgp`;YSJ-;~PiFf-0`1gtK$2V>9AJ8*?t zr?%$WPAV1g&mS}{iseyK8H=f9e~q3O*&2~pKaxtcrOgq^xSu9m;#~L7knrvjUqe>ZM zvYN@?B0Z^SGA!F?7T?R{M3c=-K5X)SlWSFawJp5SWav4ca9R#G8P@s+3m=B`B&_Mz zgj3!@D&<0x)lHsivW&^oO!hJPbCbuKyxQcQNKZ;z_&SrzO)fOq#N>LUClxF_++-z_ zbxrm|dQ!^5);@BV#dsFe+GJ0YZA?C8a;(WNCR>^uYVr(xbrg}#@)*}y@|-*>FUULc zti0X>Sn>YTbM)gpCs>bca}IOV>_)l&+iZoR)OA^sVWm(&N*2r~9VwO)p9hPA^GsOXsI|`04bkzVq9s zKk&QwgZzX2!T!De@&2#;eE%YUs{f3Cu|Ln>?BC#T@xS$F`+s+y|C&p?(*AN+)?MkZ za#y>_?l^akd&HgP9(B*UOWbpAzPrjTbg#M*LDis|8yVCHYPeCskwG1IQ*caB-;D{{ z1Z~~e;FRDLH!e6eIMv-2bP77V@xd9v8E!&wW^ksvJvci!+uaeI6ZCd>1{VZ<-7kXy z!2owxFfbVCCI?ps*SWic>x1iEesDuD(iH?Z2e-QWf(gL{H$C`eFv&d_Ob#ZyhlBfq z``nD+q2OWnNH8;)=^hPU3tn@N1+NFMyT^k!g5_>juqIgRW|z9A)HUvDM&u-VvAUFz z!=(m1v?l+Wz|ZSSRXLh}X{pD*I&zFOB;1I9HKZ}Uoky>CMzf3kJ574XA##?Si?2TX zD<$X2Ai|f)V8TC>E2OOq;a@ZPIsZz@P#H$}TDcB6Tt=XI1OH0NNV%EtE!@VQ+$uB4 z@lpQeF}@y?QyF2ihcjaT`2Khve zlr8+LCV!Nj)alRiB{ka3zf$s*S5C@#<-H1$=T-D7N*%9~S4nDk2YJUxc}8$kImA2O zJ6@`L&AeuE0wcOP;g;U1$PQj7Vmf=Br6J?{G-Ow=D>0{gJqY*o&PMj~&XKg&+v_V$ zy$e0sgnQsxoNc}i+=x6DI6=RHTM zp7&Ou^OpA(I@~{UJa^7V*#5=aEhl3+mqlAR%?^T;&h{plHUSo)Fl z9IT#7&yzOk=hE{D|2DlyPGOdLOB$zFrdLzWchlRXVtPk<2jQK5N)GnZep*U1`;?PI z{qlZAIoz-0SCX>+L4GyD)&1&{@(=fG60YUfCVZrStkm}#_zeg*^cxXw>^H_k6ThV# z=C|^xso&mjFKw91&LrH!?}fK>{CA*ZUNXjtN4VEVU&-^Q-y+6bs zBFFeY_pg*Z|0@3~spenpUrp*TpONWb=U+$aaQ}MZNBAR&xzWE-(*7ua6yclvo8(k~ zv_D#^`ZxPGOI?4Ae~TRHkM+l*bE|(VR^$9}Xx`@EhM)2Nc*4K%e?fSHKY{S={vC3h zf2V&Z;fek)2~YATNp1fw|1Nw^_9x@#ZvP%q@AdDMQq0c3A|~I@CuXWYRZjEo^Y0^< zY5p|g@AvN~_Xqq3q>KM+|JS5W_otKkp#LB>ddPp6@C<*3wDlkHA0a%`pGip`^&h1j z9`hf==i~n468N+HS>*nN{{%If?LR3;`*Zv`=s)E@js7$KGic89pCiZT{pSh4;J-lX zi~fsv{*C_|VqWrJLi1(+Wy16Q`GkM#FQDaL@fXt0ulkFyUFfx|cl>t#xOXoxcvN-}%3z z4L|TdpkIFP|DM$K{)goLk^d37f9!vZ<_3QQ?X%I}NWPo=KTy-n{$?r1I=2;{fAY6s z^|}8!G28v^_}Ss_kf#1l|If7lE`Jvu{^EZ@E?@dzqPg4uityL|*K&gYSO2fH`5u1{ z`v2p9gNMKQf1|$N`rqRD@BTl~FLZDY)=`#b#|6W0X& zWOp*D?OZ!ba*AtD_*8eQoaj2Z4um_oPH1*6GUY_Xy#~-7NHHyC;!z+#K?H#?2-5S@$fd zFT0nCneXOH8F)>xEhEXs#(bR@PD zY^lC+B~O$s`LHF}fH9$JB<$%!ErRgUN%zyhVE`M>)n@<*kyA zF#UDJ{LcHB)D7MaSj$dtmo$O9d`Zl17>t9#d`CEDEe$0FN8x`+N;QV5LW z#Tj2Y-1y4j##i!;uhdGNnHmKDDB>$M6MUr(`-!P|P}Wio*76+T=TooXS=mX-*hwDj z~&!}WPBc0$GrF=eek+F?Z#x|-M+ejPRsAg;8BD@6Ceg^4gl9~mvN4JJFp29)9pR6VM(n0y4&lQgZX#aU zgKzBN5MvLOjXn6jvWLpX9-8{M`M0Ba2VCKh3|E+lw_m~-JYx*ijWPJf80se&Lob*CA3Yjgvzjlmxxzp(A1cL2QzpDuC@?n;2AUU zjTuxnW>7!F43?AQoA87B#t$kRKWGX+SdEo(g387TDjFwfWSqb^PH-%oAm#y$j0co8 z9^e}f@QeZY#sJFupZK51S;hk@CV0S!#skV54>;O*Kvm-bK0M$raL_Mc1BVzJC=DCf zO}~5vC-96DG&fGr%Q(T&#tF(BCn#&2pkjg(R5eb(AcYf@c6_9qF#{iFkjJ`J)|Hip z#tc%%3~CxPIK~|WGjQ%OcNnQvT{XhW5>oDPSb{T_kTRCgIKdK9#u93}I<5|DSY1~i z&0}EuRfN(?C5O0lO56;-b;l>_P#vYDwP2KUtH*?LTi7|;AjY&Ay(zTSDu9a&g zdB!Rl8>^^ktRj_Q6_*;TaK!)M9TO?;{>0m>AJh_ zl=e*5gYql4$TMznigAlPxJ7SDaxM(RxjwEBbve(SPxu0N0s4JiU&0rz$V zyV2c9D~)oa&{1}hGInyfyV>1LSUE~f<0!|tv2Gmxm8s;p@oqf&Az!(}O(Om-SW9DL zEqU&4cQ<8F?sANAmy~fAXWZpnm+$gPEpP?+pX%y$OF?w%p)Wxm7aIz2n}Ii`{Cs8ryf>yK=o-x8R1Xf9 z_Qtdt1T}-2azRils3jK$M+8U6l|k*Gwp?uttco$Pmch}%(Q-miFQ_Lc85=u3Xb?0Y zreV;Kn8rb484@%Jn#j+Cra@CVIXFHzUit*hf@XwU1TAD}&?;yp?Sj@pYos!{D#qlh z1nq=03f*!$H zFua~YPdVQBU+17#(2KCLz|O`38wBSD=Stt8PtZsD1?L6l$yLGm!TB=G*kOalu%% z9t;nLOUl?}yl=LsPkCz2NrXb{P{)3?|b4$~&tV@2mpvoJLrAXW58%J`y}a3}<-ag2#f#<#c1B zey}uHD(4slehtpPmGUgK1zP*n&X-8h{?)S}+wX z0Gm1H_5n}pIY*MzFpv-CgAICE4(fug;3_Z$yaYZH;k-ipi98s`XHWsO0DZw2Fbk{# zyG2S-mQs|Z)FMEBrSVz1HfRq9fXBcJuv4T=CD01srwo3|kXDAYGNk2^mPa0W=Y!E; z23Q8RiIgn|nu6Y7B$y7CfX%{I7jzOSUm3Ip{lHj&@ACLAkM9br_+yfJ0RI*7UlIQm z@m~@D6~7RvGz{c}`Cx;{K?3T6Zh&?x} z(4#m~86TC=tBhXdd%%leJ@{Va(0X7Zm@85R-74r-LAMIJRnV=1ZWVM78wBnEPlGig zRVRbz!3W@5k!rO-CvZ8K1m=Nt;2V+ZH9&iSkLviSj*r7B+u_uq26d>>1q=cBtbxxO z_^g4?n)s~Qffpmk0s6YuO0Y}hh=V~Z&{w2(b%4JkTZDN8|fwd>@VPdibt~?|S&IH&)~rP=7cekNVWRKK_rz|FQT#7XQcM z|5)0wL2b|pQ2z##0QGM`{TqBE(vbQ$Y!3zj>faDw4e`|wUybn92w#ox)d*jW=7=<& z0Q9;V>=tR#3_Ji9fh{7(1)u?#21svO1+)d!rz!PmN`0EH1k~qv>T^8xIX)lE2OGi{ zaGTZTx>TfjFE9e&zd8P!Zxv}#8Z-hu!Eiu6EfxauZb{xP$-89_a4nb$7JyA6tx}*K z=mxF=Q@~5$BasuR-wD+3gxO$)NNe(HjlVYdYlFWw#)qXG6EmVs>|9m|2Hpbx-z$6X?w4hF4-7ECgfL>q(cmON{TZE+!P>wTufNQ~2umEfl=|Nq4)Cb+cFpw{D7U8o9pQYjXfHv$& zoqJN}p49nl>U=hJKD##<38sT3V5>;4LEsKRS$nMkUyGbW8PB1Ny(wdF%Gevb-q`iV zt~YkQu{*akXap$#xs?B0%6~59KbP|Nq5OR)e;>-OX(1w+9-0Q>&qz$~y5>=L=SGH4C@ z0n#oe?PAg{CT+mMpcUu~#(jW+b zlfXQ%4tygrxQ58jnu3?WN8leKmmdYXfFWQqm=87x56%GfxPp3IK|QX({}uSZVmJ?x_s$cTYbs7LeyXE5R<2d&%qGR-iAy&%HAN<+yjd$dn3zzM0Yoi~;Ix+pf2bNhJt&*i(ozYUSwu%@BkpcndJ8<`8`Tm9^ESPSRQB!Xrsru zK0XnU$KxLWY-gc2t0x!%rh}z`@$^Ima1s~@?f`QE<$B^)5`I z?d#Ysqwa4|_cy5f8~p%vf8#N*LS*?kkvA)We32FSe5*QW2L^%(U=COfc8jd60=^b` zyDB&d;OlLCy^XK8@%8pjkyZFw)dHLkX#Z97!3N>g4Nw=*4)4$o@6ZnKyeP7|Dd-JG zg6Uuh*eddFX+S%^+Y<~2)4)QoS!9h5>VxiJ7{~|Yvxa=$l@_T;>_()_e z-`Cay*sP`f*5YSfYtRpj1&@IhV5i9MDuEW@d@vf|?00)aKA>$rplv>&Z9bsQe@~nL zo;Lq|FE9qo1k1s8k@XcoGtdXn#_MN+m0*|1hX;dJpfAAgL+n1p?nCT8!tNvNKEm#! zQNm*&Ks`S0Dzbt24a9FCe#1ime;e?(5q}#g*G9^^5Qd2kbWY0wY8|p}wDBw`B;J44wxcfNw?qSPOIz*^2&F^52U7)(1rX)C%+kV*qvd z6Lt90c9BmjfMx*QPe*}0BA-AD`pnb9`*a$98;d z-z2ib2lV$2`fg_)7!T%vH2~j#t^p|DpDzcLeHXU7u-!%eyU2gnLtrWRROBz%|D_4& z1xA1ez#_0k z8k?`N`5K$AuL4s<{#p(+1--#YFkNI%fABuoBl17QebX9@0F><;;{V1N{2O|ITLQL< zd^HUNnomYoSk?F zQNDv_fMwzx+yTr5yfJaeZt*Ht0mN0lT)acc^Uzsfm3UPK0LoQm4p;;5dl-JJl6Tem zfHGFSR=jGpL3@CHHT0_w0h7V=-~;fjc!%TnaPl~OFqkM_4eV=tAzn?s*XkwS5qY2y z;BA)LeBi(cZjYz@YN zSzslgzOBfk)g9uUa1@vbDBB6U#A}VO*7$8b8W7hS-8SUi<{R3h&bHzKO7NGskm;siF*B#&8 zhl+P*C5}iNfS!PQ^_VH%S(NoG%G&c_&kuAy37Z($7R&@GU|F6z6MjC!IX9IPVs(LNxaL+i~X;6c_)D0<>+0G&J`^H<+_6Q zx`Or`G7yXdGr@B4eoncEqQhR+yQ(yJUc9S^gK1zPpl-tiyaed`VgC^C8uGcO3m5_> zgBQiSb_7@^-gR@t8%|k=Q?~0T0m?9f@{GXW4JUz5#T!Zb$nE0Y__cVWx{G%cWg1OC z-Aw*BqjU3S@y1L9TgAHt|F=-zu>q(D$am~6@owz|xQ?3&c8Yh~L*k7muU}Bs2?vXJ zdu>2_-+|2?E5*B$w!CwNcoP|S6Z63~@qU>SZxU@csR6*>B+4*pB$xv5HEB7ZERz`T zcU1;s!D{g)_X6a3cYE-Gc=yZ(wBNntH-&bcLc2{NehP8F$^&&lJ8(Xr9KV_bW`QMu zHvJXtkY54R2OU5^Kzruj1LlDD!5;AnsssEK&|U=-0BHr3r(m~uQ>%dCfO_3m4m1V$ zxo@R-(^`vne^r3q13kbZ@qSHxe?1+n0QjDc@9FrSPM*^#|MczRJ;?V5(Rq;iKeS%F zho1+;&!`Qk`-}l#ESLe7fX(7Pk_Q?9@_FQ1Fcr)LYXJ3}NjYY=0=)rw&)g;6qm@Bh zFju_C=R18g7D@3iyd2LsCc_~n4MV=w1DzD~SZ%>a3`Z}Xn`NW9r|#Cx(9=mLg< zDdNrX!6<;2H zPvt#FJ3aq^crQ?w7akJt#gXFu<_&EhSg9!tiE_ZoG1ZHstI z@w>Da_(Hs8ly%vQU>*2cyf^Us24#KYQ}LDu;=Ku0)DrKlMdGcbjaGI8_Wt}**#ru%*e)y?)A5r#?^TgXgIXAQe zgTO>U8*TVVyp5D|%v)SPC`(`e$b)K)H8z0{y{AFa=QFoy!5`-${A@ zTp3W0KU20p-vLPfGwHjC-!)FWzX<37MuAyii+Ep9pD)Pwi|yilSpnetOY+>^?Eho$ zIl$Yh&OP^PZ%eW)$wQv<-m&92v13~v*@FxM1VTmwl)cI*h3ZBQ&2+0Xzf zqhW*)2q7VZEGHy!y!VusWR3TqJ1pC>jFT5eU#t6xIOO=;bN+q)b>Mq1BJ6zlCc^hO z@P&QaVLp2wBKlx|eHHM17QROj(Vq(6E8q)b`cJ?Y)-wm*_YK0_gBJK+3g6q{`v`nrW50*tPY)u7;NOQ}Ee?2}GaSAyL=5jlgbTiI7~|QF z2yYI2YY~ZX#m9w+B;{cP#mGvcU=&)65Q1-XF@gUdQuMXWEv^=&EY~GFR49k46dpW? zj+jhGY()LR5=c&bjQnTN`eO94AY)y347v>lfE0as_UxB!^n4iMe<2Lh;M)wen`+x7~Yw-*&!MeZJ=T&))s{g5vp}N5at}SxnP? zG5UkmNBKgQVuj2ok|0PTGzU^(iCMQ1wG6#ZWz1AooyoqdY%RmthQ33YnYE$IBMh0D zzbq@e>bjB=mC9nd4rNoD6kE1b(_EgAaQyhvr8Z*A7F&=C4)+B9knD$F|KxQa6#(y( zmKoPopl47k`XdxqJ%Res%~XkZop+sZ8;F9J7i=v?f1!%K>#Sor&W)MPTn=2Xl{j|dMBSIY{C>W@GExSGh%AFlrN(@(313z3Yn z$p(kr!-In|nN%ziQ0n>f=clXtPMkOq7Z)e$IP~6o@7dH_x9Vn=mzP_nn-i0Ai;Iin zb;am@!oAhvy#hait?s+;?)j(1dkubwfA+w?T9FZ^?sa+{U0nu)RxTA$7W5c?WS5)U zKK$@Qi^Za-deP#&9zQl_r}No8tmCL4#y!+;x7+(29zqovQ{Ukc>ar@9En8NRr4xEO z>SH2RNJ&LIoz7toA_YSDI6Aj(dH3CSw;%06s^sEDixw?es1Z4BTEf}cSX*1$*y$u< zD;DiM;!<)rowe(=c0;O6iq4cD~FLlrhre+iE{4-@1+<$@cf4V zY7L59RgNmrU+Cv==vmUNvX7PCQkG_{;N?+Ln`t_gMiazXd`@kYPZL1CG}Z*&utFB+ zoD7q3@Zve}3qgW+OJNiR$D=V?WomDnd{i2Xqat>Xy6S3@F9ASF_++7{@w2zydh4@B zPod2QHCxE#rld=kF3s1W_FY?OreHXN{Vz$7;;npXh{+Tp~1E#Sr%f?)Sg%-#4LH zYV#(vgxg0DyTTCW{URYNO@zVu>S|3PNhTa$N)b>yn0|NS*5nd&KN1juFoACoXkY~JjtR!FJg#JURLAhBP{8o0Ab19FsECO81~Vv1 zFGduBS@c0D9m;=tlzv~v{{Amn8Dotf(R!phDz3THD+(FWdd`-n@L=9&pM{4b4`m*$ z`JCPFy~Aq0pcJh6=9D;`PO(DauxY(R9gOxH=9?ER|LT}KD0{T_Q-b!hf4!?HRj_$; zQ4ty*s{!rR<=(5jYkeB97DZiDjyAIz@G-Pm*xP3h3JvXLw9P~onA8K>j|dqiNJeg+ zuQC4k;Q?F#KVsMgi=XrLu1i=v-NfQ4rKLq6KvTmNpGvApOsttAzVv6#goKF1x0w?tKfY4pm!^xytjD!Y~(Ae z7>sfnSIR<%Cpm!>lof@5#(fQi!%yj~mFJH$H%69~bfP{EXFui`3A=B_TE@~BR96=k z!iw+Xfqg=vt(awtH!-{9P6e~rU0QYa>f;VKNwj_a_1B4si6%My%OXnZbh?Q}3xN%j zB@{nMhMXZ3z(PaR{qyCXVWNMR&1PG@dUbi&R(k#itw=@j>~@!^4E-5B%RIzN4aJYr zA$vLnz#C)9`EyPoD$EqiT^hA%wYzT83yW`r-@GqX@6Mf9wr2=C{W#5cN1-tAXE{%epR zq;BihGO${U|0VUng}2`hs(ll2_uaM<&vDOj;^ayC&wzB|g;@cD9&8XW(18R5 z1lU7yYgunCtfTIePr}3Z8$jX@!{m3~X(R5tuTmn06Do-%6iIH~_;IoKdb0T8yb^S; zw~s1D!<&k|g0WQMgZD6s$8YUJE4jD&!~3VzcT-tUHVdh87GrSAPp!jHYHDgcBjI;9 zeuBXkPGO)a??m_AhurSYhSUO(LQxc%9qhIV0C^wNFhlo>_IH`vrM1K>@Ip1C!*O!=>boqU{qR#lkyj)+0_nVA#s=?0rRN*QoQ%Dep%ASGn*dl) z(9(iO3gGV=N58$_D+oQrQkVR3ePp8wsu+RCAprOD@NvjW3Xwc8q<*+D{@wr{ei?WJ zgm^^(y#YVmiu`H+Kj&TCIrBM&wi6RbOpTZ>X;H`i$o!QhdH7eL`~*z!P7yI|Z>p)O z(dr>g)LH%Q*NbOHGA!_^U7NWKb3wwei}u2bL?YMFphVzqIdtgIv11K2%?S7+rTYjt zW_wWaA}CW6V*0PGZR&;A3f_)GJ9g~&d`D(pQBjeoVdsmFf&*E4O-XVxW)5NXvt=xI z0DthGtrn(@KD+X6OaoGiw*#NJ5nlqVqEM++z%4x;8rg8it`}Z-;nml6e}1qFxq*W$ z^r5wqf1wH0zE;$HruiGIX^OPoo}Qio=a5=1 z;CY?2``_v1iR3{VjYc09Zioc3h&4q-M8wA$c=jWog3sgABX*uPlMW1IY6*}qMRq$O zR_XOxIB<_Xa|;C|;)w*v<&~(7k&%(%hAz8((V~)6HR?W0&vdvOsZ&c9+0xUcZEbBX znIs`p#?flG2jsOGUO%m{IIkQ|Zwuzmttel)Jby|gn$pnVQbeRAMfdfA+3llNxrC2| z3W;~XrH;;=F=Iw{OF^P49Io)<(G$_{)@$X8Gg`qmQuKL+B^oLDkXq{ zRsh&W0SG8lVM+D;RH?}nB&{w~%0L>|Y~LOf#B+6ZZ9=?_8%JKO{8+Sco6PM;k=m!KTxv0s57+rLvHP&ST74%yBGALEFHp*bjpz{J-!6 zf5!PNFVfL==Fr#4X1!#fD@0`n&2og(LUBG@tg*4V%O#GDO-xIR>S$b4jC!_@s35Z+ zTZ6I@bnSot>CKm~%n6n@pU5^(iLqnGb2C;nd-m)<=}^y|yZq8iFSS(dnY!MY$wFp1 zOE;#mbo23!xTw*zqo8bJOgr^w&YY1~NZz{(VYrw=5K0-NQ5EYbfTW7f0Sxr4<{hLGrM7pat@{*(Ln?>~6# zyEBc=&CR_6wLUII4Teb642YYT7S6~?PfbmYQ6mGD=5+RU%q*HackT?6%G*|Rx~8GI z#f~6!EfIgb?Sl_K*mb501xH3lMHuu-!fA_Ck`0H{F;VKKHy?TAkw3lg=7&4M)mST! z&t0}5AtEMreg*h%m{{~v=pnR8eA_h}H*Q>VH@djMR^VE%x(_8-H=NVF{6 z1YKPVXM;Zl&gRHtBaR<00jJc%;C;E5;<*XJ9q8oeKeNBS`TsG-|Li2d8-ufx48xv1 zJ6+Avqm_lLMyV2sH3}io3PjSz7s-^UlQPLvaiDQPyR^8a3Vlpm-270ZUT=s2QzkkX zd^Sd>b7-)%0%$T>*>eOwM_s(nFfATvrgSYm9w1JUSbCs7B0MZCEJP_0c$_v(a-^n>X*{NsUq7PKq>`ma%F|x^?T;JE`(I_ zRLC81lY-FDy?c?|TmXL4S#jcFzWpdDig(|B`<>na%$hr;S?F77?F(dRGWz03*6jii&onLY*mjK=)XwBd`d(KH6uGfB7yxcJ&?mP@W-xg-@c zhTagJ5FZ~O8EP~dV*V#kqgb}TO@0--p%}eqMfcFNQ}6}|pUn2o4j2y!$0;jT zvIu@7pmh4-#+ccCPhJ?UcQZV1ksqp|lAgt&YFl_dA zideRcBDM#HYY5B-aLtDC0pa@JF{9zbVJCGh8;2Vj`s^F0(`34EUUW3lQC42j5r|&% zK1*4;baX5ZbrySXARn-oW0H7jf4B8S{_?cqOpqKF@LuhMIGuLrUY-i@y4MpC~wWSphwVj^oS(0B!1hrYGHi%5)1kR zJc)2RUB`INtvt)$>iWU4z5+kw-%bTOk4ljSLq(4g1Iu#%dVukHzMID7+5dvw?Qd8a zooP}zySlnsPVD{WWGnnIC^yBVWQFR(qo*%kyf{stloS+I06$HS(FFykm?L1ibjbJ< zNCZNOWMIJI=y%XAJ;i6Ay#N0D$2!GeWgk0stlk}zG;iL#qUo)@PMfhjruX>qUSrEm$@!LAili*JW zY77@EnE)>cXv>`27=LM_#uI_8O~7vpC~N;6-u7d{@xSjHT^;LB9gnb_{CAdNVCFE<0#loQUv*!O`n*V=s-7nXyS+iu}!uj(qUR4OZV`^w{%0jh6$D81Yd^SSC z!UzS`-8UZY4Kl@KaM9;LmY6@ZxhU;S7TS;}RxJ$HYSa#o+>j1FIK3X+)sP3SInf7( zqeQj+L$Dh6oSzlEfPC~uV+og z$KOLw=jT7op8Hp_xW1Nsdy=!irw3pF^@3w7C(6>*yy379=3KO9_IxxkwT$x zq;{gqtw=5csaa915;~Dvq)=39o6ej(O_vT%SUmA;&{c`zfiGVb28%xUU{v`;U;m(& z&PExZhX2YbN7%}82--YDKaV1t=n|71IaQ&dj783IxX+&>#VL%mKL;u(0#*^8`>2U* z1|D6pAs!}pV>R*lSk+}L-fm^_mWC@Sri?q1O6F=Qrh-3xeSK)?+2T+(QciL1cnny( z*HAi~Hk_77x&(CX9{Ri(J;U$2y6@^W#2_Tqj;{UvVe1XJLn0GC1oyU%J0u3KH_&0j z%SvXTHJpX;^FH5l+~o5H`0wDS7~|t3dOb9EXRP78wLis*eoP4Yvg*rddMZZGT748X zmE9+@GGwG0LMfw7Nkvf>k{+nplyDBT6%V7N_@Ob9g5(JO`*^;L<#$kfgY`L zQzH6@oegfAG&n{MDmFMHD_Cgbr_JzrV&tzh#z5fpzWeUmBcBc-M>>s&z*#$$s8aTe zU##D-X4PfJ*bF#m@)QbJ7e%x{VLr|`TSvUqKk9F!^|OAPv?CZ7#_J*z^a@rFb9?qt z5D!)gQo`;#yK}TJdlK|YgwEFr}3{XMOFk!ap>=4MT#*-%@N^{g$Cl537gZI{W!Obe&Ek=$XHHG%l2iOjma&uhRG9i z6Xm`PvoSek(NK$nr-rOLChs50CmC-EoAwXI15ZEwx2vwYc_jNkSylg63|_zF|38yg zC(5lV!?Np_8AfUV+;jlcAz(v)vC`RD7qPqj6-y7v#9(Vf z(2!6#bxefdqX_cG!>2ra(AzbSaiIS^vIou5!7 zeyaaYOekCeg!{YiPk^9zn8fa|fZd@sc)%58N+~W+h)*zu=(@TVErQIVpm$u@1A|=e zybY&}x6!dw%*-e4?q&Q4~#8_+sCViwT?S6kqQDEk@8o@i9mEU?=VWZvD+RX}rc#-}Gt zOnq4y!iyQ_efjZ5`N`?ir`c?Z{v#ktA|t=}qWlxtgkOm)jht1KPdHU(6Z@&5F^x<6;MO}RH#fbw>`^n5u zEjWCD!&TuF5wnrw@QpF!{w4`mfvaZU^Uv=K$n|zu7gz*z>Tn>d;fEW;!SNRy9Q%9f zs}bqxI}LKM{^Xg~S_Z6P{YPoR7#U0e-ZgG_fBTGb=z5eU?`mir92|sNQK2{i^l3av z@o+TPCT_3(;zJ}HKJyMM9z}n6=x^`6<%2C*;C!3?Cn4CqaDkPR;yWCzCvL%c+;mJ= zvf9wS^CaZ!^bS&lXt9N<;3mq4DISjV2DHq7ZW2(z@JfV_SAGf(pG-q=8nKY21KrTj z&I4|DbTrOZ=;<+LCMS!!=&XeqIBP+^8?qMAcL@n*^YP=~*@#X^TDY12sKc>fK?&N0 zUXd+WaQgJj8!o?Gbpmn(ti&ykmw4BE*Mo)l&~>=L^DkD>wz+f5%HDr}TcA^mipepE z@#Pr!!|Z&GkuvWx_}<0!LAjiTM@nt&sZ*!g2YE7OSD#l9mY0|3arJ?dyI&AgTN{!* zXU?1y^-#m9rj|b32PDxx)LjK9-Gf!(p-|EV))S;Vh@@&G#W7hoJpJvT3vR2C$ zR;m<9J&XuxY6?jK5t6D!AZ1Rq5AkU+!!V zyaM7WjSazSv1_2awINb3h3m1YBDY(l)Ua~Kp~7+|#yeUTMP{YNfJjow1>_KvI!8ok z1T|lM^;Hc|MTF#m0#_90dBADn9_;Dr?&@>fWFZbl82#&Cg*URoD0*F{6NJ{5Lmdc9 zEs;_bU)t#wB2j2+etv#l?k%@GS>nCTdt3O^M_nfD{IW|N(eCFuU%*=T5^FROj&!3a= z;?%3yvI51O8(qWTlIf~FeWtb}uuUMvrJ^{e0!n)rJ8L ztLp0kdinXD_We*Tw!hsIlvYqskQM}%p9&11L6IKIcC}nYc-)(`6{4@u{P}rCa8`l= zdaPe$%$sjhXQh>Z%~+O|l|2LInvwnKr)7*Y0AgdC$l-4vwRo??5C73`hvUGG{2hLH z8{?qLOyzL&0s>QD|8b!z-mqg+F?xhlK8Q-tpU|J=H%?Qvy?Our_rKYuns#F``V*r^ zE$p6_vJ@5>By!-;uqY^YdQPWZpo%U8+qW=UC9rqqOpk>wGZByuCJ;%Luocwx^{$b% z&!1mW9u?%a1;wel!3OMB#Vx)2_M>(3*hOVvo`F9Bo(Cn1V&!#5Z@+sfs-ScZhex8) zMZ$U=#~%4Tx3n_6T6i8o50P`sf$^hcI^IOXOaV30RL01dd5pe!{ADs!3`Js%WW;X^ zsF9}fHvcgfuozg!VjxlI9RLgrc!dOJD=$ywK6CKk!82|S6^9Q)Rb5gNP*tqk?IA>R zHJ~C?FB`7Q!22lPd{X8OB z`uy{M{No=tY(O!Xl7@Mz&^W+MN~{W~YGMkq5)UeY#8`OT%7snGMmC0m= zOiQL&srJ@_m2&VvC@!@M7B~looMmO{DzfJ=oG}{7;Av(1d7^J^sRmgOP+n7eW7UUS zKKsLcR;%^dFON6(4>b0)G^s35n_e21Jn-)0k3atYV9YN|(cAR%sBnd=X7z1oCMAPJ z0ijBx)9dxwko$DMZv6sNtozGXUU}t>*JsTF3ocRC*VzT$MjNupE;jM&UW4etH~hr) z#mL6{kWlRkc)o}LWPvQ13$SHrb)vH`sURe9fl&;h33RRtVdk0co5x@CO=XM-ilbpY zYP5h`&k7cM8#yY}2nPXsPO&CD0gS|y2CdQi}Cm|jL z0$(Ii0Tn92h0f>*&q>e`C*7=$02SeJ+f<1vT!hrCiJ!J)!-fs()|Nm?`NKl{OE2x_ zCoU*Q_o7$X=RV1jjOhNJilOTG0cPUPfFAlLb{Tn~IYFyS3X z!+Zgyg$g!v_GA2|g$hpu(gM=9ErF%Qzr)-7sq5TU{oi>;=VzT83^%hJ`bU;Si-K_u zSAV@+sh$$A!qGb&r*FkYLcfKCI3ofgoo%=C0xqL9YmiG)wv|9n7DyK z3QIjOiDhDFbqau!szVae(|dc}>SF3x zzWeTy65PvDd*|%Xfsa5FKef%SjahU-OQ#n=pfj6I!78x_05Hf4HszOz3)Bx=%X)w7!zk^q#YL#6tKIXPzF^=q4iW{U`S+ONjD3|u+ot0ZDwKT z&_l+6BtAJcJ=_$ZG93!n%F71^l9QpH%Nl&3naAUaWM6ED#u~d1_wPersZ?LtqCfA4CP;Gircy}9g`Rfa8~6{r(E22T z(m04SasBSEW$C<@uCiqkL-kc5a@76V2$nNWo?O5F^zjpb=@V6_ zs=fkD?>-*q{sb`ni92q78Jx116U^_(`B3`}jrqEoetCxlL9Pg@H0kRSIz`xsg7PX5iWWI|hMr`QhQ?i}A;xGQcdc5HbOt8IRk^u)*2qGEU;~ z)U$y|?zN)$V)T#|2<6`YJNA=&w^PKi+?>w7FGxtb911b&g)=ztax}bK>2^B@3n7M; zpRQ6(4}~l-r<={jZah(52dlT1;_29vp>{%!0i~i50B?}A2vmF-8B&e*nF77=J+b` z@vEIliJ8?Rm5Tb_1#e~+EW`^&CKKgbvxLRaNN;lt4?qjs+nf;!Y;SXJf1@)7)G@R) zTR47qJ}S&)q|goiQph*PpLe)-jfQ2;O@s@f+lvXfku8ul=RXrC$$aoWSMGt-YXmq# ztn@^669ferqoboO-sSjFJo5EW-l|or ze)l`L%{2YG(TWeerLv3Gt)6e0w?ttGMfDTtzvqthj#h{GuX2+~Tabs{UdcIGtX||` z>BHO*tQd4mC(O!P&(l~aan|z$8XWI<0u4?HRI2aM;jop-bT}n2nS5H@f3<@CnK*zO zvB`u$%KC&ZXFiPpU(Xm&mq)dp*}to+VfX7`O8MDRK0L^2TM9(+Xz|SZ)#YPstM9{$ z3T0s`ia|G>Z+IuO)VN|To!c3#Mfk=FNbO|OF6m4io)-MNLPM%q<*7M%u*QSk{Dmeh zoMkl{J{_09VToh?#yo_KF^VoQjJp&uc`Kof+RD5b#|Pj<{lF2k0C%fm4C4pL1)!k8 zbLf((1|UbrFxY)Cedslq29T( zWA*xLuf29rgs^kxzb@GTtgvDdR)Dl`jum2}qN0L>)k% zbR*zFheH7=d2u)b1r-tU{;8r+J~o_MB$r9V3T?RATvyuPNP-j)j5wdi2Rm(9 zW&%o5`^7@NDSE8Rnm>IGT#&iUQdCq}uyB56VEvWAbk;KKhn%3?IsOHT7CD9ly2zMp z&dEG+M3m8MBX&Hae`$ToH$i4BAXr47V(~qT{<2igXut5EM*I1%$Di*0#Nzo)P6GIl z8x8y#ZJ@1*QTXhx!U3-_0mf(y}kRpCLXkU)9Ws} zsMLFh_ab=i)_m}tX9fg}SI;2o4!ra?CFC*=P1U#=9j}Z~c%~As>KOYWG6J(Y^^tFFTY@jns6k-xOe5+J*#JjTWI2?AT%A5+~I2KY%oDMipL;q4T=pi<_|or_c}^BNVX5QCq}U^Ligbf0EoZ4Yu}H+q9d;?upBQ_T_8vyjWrpXIALgtjvXQ*S3$~qU2Lum9%3S2uHkbK5;>i1$yi-Xeb)BWCK`G`{+_a~q>(=86CL&a;MvHJ3e>CKI^^pa+Jw zA2Rr=>zX@olLlc}lsRXn0hC-mWLeBBFD{sYGxszojY@I5hkEl1aX(_6sK2eLxvkqy z;`<*$3mZ95qK(KJvp7N7d8+C}O;K0X|8uJrZw$_@sTlU`x%Fxmu6MC;ofc{c zQibX@Izc^1sBV!=)&-_mmnZ_*9%!Wti8WCPkgy-0k~KX&3F1+S(U1#k1PSMvGY4$m znUV4?_(fx=xA72e=j5bxU4sZB!>*pT))x4H!k0?;koTi6$WKZw$c+oNzx&Wb51mvS zjmN>P{#IVj$_)eD`B3GSC(Hx&v?xC+IIZMDh-R%`2+c2{WuMbo2DOQgGg*PMJBp2` zpMCb(X}Qi_&s*4r*zdR~-N{xD#Fm{+r%oK&w`WgOl*yo#df04szgh)ISrD6(QqsaA z%*lDsjkUiYav2k#AIsRtHWSyDLF!r1ybCs5ZJBe)MjYIw8As68Hft8TY@(nx`M?V! zA#E$R^x!%QnxeV;F@sGah^|8q{29s7;Tb8hbYMLa7s;qnwA!Q@5Ev)~KI>GZofTXeMlIw+EW z4rFn2i4%-Q^XH3HCMR;^WVZ>9WHQbT%-#NDCR&dnlHemEZ!RGXv>yL?{MYP1CWnQ4 z5liugq5k%UhK8b|qG(~?Ng(!=l%q!*YZ@UE7z9);ge#K5v*EI~Suq9(Fz{T5>fy$= zBS-f_td$MHsFoYs-=?!9pMQS$j?cl%FLpTG%4m~m?)9Z0mhiKQw`4km8+h{irhwHH zVkT;;#bJU#d;aeja#Hwsu+Q2`4x{Ol!H^!K{r4I}=Xp%J_aBosQW#qO#ZN=4I+lkc zSRR&i4KB+Q^^`9}1(X$HCn+glFB8YxiqS{pJ?hgX=sENch+*6h|7bE@d@&fh41aN! zF4q}FJ?L08Q%x?+4d{##@vDj=Zt0H$5g4V*muvBz=n z$Y$ZH?&kA57UwGaSI(Zjv{RCO0bIjtl|;0uR7uGyRYw>_)Sas2eJ2$hDMs7KJ7YUa z(GF0{kD(99{RT+=ejkAT2lx%kE`Y}}lj-Ojiui0R0}DIWZ+ZMkD1* zdde?ZIcHk`;Iip}(hx{^N0tgWwHIZ^!i!_Iq}!oV<=7M#FHVlVeDy_(%99L|;M1jm zhy7?L`YU;BBgQ>(7r^v>Y%aK6<>)>Lp#PD6Z1VMUSAld+5IA~GrfbH=9emNzD0nsG z7R;w787Gl{{820|0O4MM*M(`P1bv8UdbHo@$6wdvZ{+${$1xO-6b{F+dZ#ljZAn>X zCbSB)N@g^F1vbsGggJ9Y_pj!6|MgS*l_gMx@GNoN62UF|9yGlUoq!%2yIWuEFc{_n z-bwRiT=?4p=WC3Lc~`9OU9(tuw2Yo-EQ`s%f1@p8Gm6rG@-XNbIv z5_FmtX-~mqAY(+?*-*Uc%LN zoewF2bWwXo_PljhUJ0G8#B(bw<@49w2KP)04GJ90=`I6j)V=6`@DsE$rt@F$`G^dE z?lEw4{HuuyYT<$7*c_kq;gRA3Xuq8m&2Tg4WAgXMd~f{>_Q!m0{mdADOviEX$DHg5 z;E#Fc8CWXkk2#A9nh}4DKPBs!ijS5$XH$9C zfA;RD0->LF3@&d2DS!F-r~9ew>uFYozQjuTDb?M&23$&GNMdUB_AkC|?3W}!!B}2` z(mU8tr%_5>L-vkly5v?o<&s-9+0mOB+23_yTq%`XJbATk1Y2!;cuch|8X#h4PG5WF z2PNJ+y?2K_v)>-E8dut05<|3qxg#ZV*lDk03T<`Nj42k{#s&3xE}5Yn+yOqpoui9v zF=-XMmPzaD^S}kS(F}W?^*?=nIMc{3&kjOWC}Xk6SI7aaohIg>6+3r77z;BAJWFdg&_z_WfOX(7qNrluy+5p0Z` z5-;l+US4s*(u*#ET+#&0E79bpIP)|vNg!Zs z!XL_z8DjG~Fkv|M`zgaQWGjnmbA&2Dd%=RZlCO^Dw~wnl^Q#(zzyTQUQs9U`L+fSo?Q;_2&9U)O zdI*T{z`-6*NoWWAoH-DzweeHj@P0N7A-R3^h08BkHE%k)5<3!1aCO$oo6A_w`eP97 zc00LP7w5GZ?NwK&(OKbF2F?o4V&Y*p!TbTWT`)5y%{PX7*O;vEbxc+`st%kL?mrVJ z>3rw-Z2TJNwgi5U_H$X&==~o|gA5nq4_CsrugB9^r(JSZ9$aGO-24qpQ)UmL(FjplT0dq*RquQLSrO5VdZwBo5*9$5jJBZ0*bH0*iMvrC*g!CW zjO@6ukR)@2!4MY*?(m5tNV$YBfFZx_!lG%bmzPYRzHAwE)|@*G)5djN}d%sf^=^0TEfyW*GE`8*vY`%FnAQQ zIKflXvg_~Mjqc!E+5hFCBYS&Vd(g*JwA(F%h*D4{1e7vlDwQk)e#i_`sf036YON@XqyqbmuxU~Re!#v zv#sU$2N0+G{DbXd;&&n@eg~lpaN9#s?%0A|#pSUft^K%AHzwC)x)i&kKA@jJ5gXX(W7&1rEi_bD7v1uk-++_WDgyWMgC=kwmq2LZF{|jv(W7(c z&Y5#0AokeXTM~U9UjH5ZaAS&D`LdC<`iSOcN)jAgQ89nPau5WYRAJe3)%E`aD4$)Df);^{ zqJuiSI4QN5g%#Aog$=;Z=6P@>j?oyGF%x{$kWb+b&zyV3E%3SevelPdeCf(XbXvs* zO6qbc%?*3OnY_1w3aP5;hZL3mnyREcNVBM@@VH!bo<%WwNqEOh_^i0L6jd_m76Qn; z=*qoz5qc4|5Mt&*z33=9i1wkq=v#nY(UpP;vA%y@fTCNeWK9fgc6#I|Dv z{089|tKmmmnCCi*yN6xD?uD+MDWoVU6SR^QOyrY7Y4cK%b3GPN9=z*I*VZ?Unav-K`I29&2*|W$$V6O z-{rMMUl19dcfl1)^h7_`0@vSNG+rjX6Mg>@(+WmQ26!N!YtIhw^=8V$q1p>t5!?llHZb&6h}Senbv%b zkZRku*ae^kR~D3%UU=b!Gh&O;?^Mb?m6eryl=s|2?1ru>y9xMzR@^aI4o%yHGDzc! zjnxH7A$NN-ew3?|2KVjT2MR*p`pILDJ;q2y3%lZxo`*t&{l|ky7@CmW+0T=N&w^Vl zXN606{hi4PMmVKJz~y$NKmy(@waB&OGl&5m?GuFLfc}^_SIKkQf|Nu%R0FjW%8X@e zj@1eDrDYJs+)6+HBPrDj>W-~hmH{p1bbWn8JXvrg*!4l(ly%dlO|Le~(yl9GFQR+` z{gI3p^|96p2mjG0FNu+GBO-VvoP@_v<78tvx)yOV8Ln-i^P-%vA{N)2l#+2{cy4@T zqLAAL7ykysKngj}^SU_iQ91igeQm8sss){{m5K@l9eW{jd2ffH5Xr!y@w-CM_?Rf0{rZJR121zL!vgs9-+b5eTnK8trFe#rX{Lh1VNt*{5H2x!BolMx;u zi>L6zzad@L@-lmFV`zf&lyflJgx?BP?pBguU^OaNXEdybWWWzZr;+0Z0ZUr~c25+{ zQ%S)T0W;tSVFaAV+VE=vos_3CW&p+Ed0NmiZXQVWr!xUUn6-$6>}|Ee@T}0tU)z1r*YowRpW8hCdkF{w7S38c_`Ld9R_D+vjsfWhyVIfL5tD8Z$@TD;^r%nkqnUIX0uJlRn(K2{U+W_O~(tR%yGkegZ8OYf{<*>w?~FmrfHDkJTpBU zlDN&FZ-l|=={t8e%N9e4$0Avaw*56wJHLC{U;rf)87xDCeSM4!6*K!>(VdV5dS4-J{k`EnC(PZbx8)Rbv>xT`I9CMd!rjpM|L6Cw4Ve=d_9Bq5Ze z)2R5vwkS!^a6?3DB=OB({_>X-A$4^h?d|MbvEtW8%c8Yw*Dg;3-7V;cxC>&oyEulCOb}OXzcX7grlO(jR$v*l3&zR`gVSy~$KR70ei#no?5E0y|+; zglztN*;!%;OcYul>&ENj+QL2YdkV#TS+We(P-q)AWj3$cjEPgj*I%Yb|DpnG<3nO1 z1QAbZi1a|#1E0Z-1YZ&#cpknO^N~cu@zF%QHhzph9r(YC8#AW=T5Vw@m_2A4-r`)O zXHHiBwo@dwo#t}3(?ly$MdDRMEeq?*n9ahNlVK4=Z`~=E*W+$GeE2XljyKfS&Ys=U zm~A>)Wex%X76t{If(4NNF+W`c?WUD(qfBOW>vV4XwW)cvAOB+zQa2Ag^UO2XU3cB| zZS;zNFWI~Ema;ehzQPPQUBVqfJXsmIeV3JpgnaeKOeNbb|T!{ z)I-PKd9l5>yW_0)09!OQ0*DWu^=x1$@WrkV=G z5?N}W#_m+36WTlD<3fXbdU}S2AmEe+%_@Un=idAxI0Q%S*ddc82RUu>oZybr%a%-! z169<~VL|`E4|yHBhT`}24S0TA3WsNC&5a%w6>Zw2*RP6ZErf~I6q}AYaLF|s2XbB9 zSZ@VV& zlt5#l%~o_Ng_?`eXF|PR{3HVRCh=PC*!qgm+C`R#R}y+Dw-OG{KDv}KH`9i~ysRYj zmpO@8=3L6j9IjWKl7TQEF2f{AUTvY#NXX_fqMDeQkMzapiAiL1kdc;B`P|ATf}gw8#l@a&#A5G zfRT_R;?aDshYSp#1S;m1=scA=#REODvp6c<=GvL-h60 ze^#ouZM(9t`Ga3v@#@Q;6xLpH#~skf-YU@R@4g#|qr}Ve@`$D;`pz8O>NQ%{YqTo7)%^4J5bUe7N9yHx|u z_hQrrs;t6R=&7fW(>c(KgD~l!I}43Yn*fk>>@^xJ_XV9k{Pm~8fp1=Y;DHAqyDAiH5FDo{ z1yB**RBx&k1Wsowbkb#RJl!}`ufHdol{WtS7UM!bE2)9vZx(m{W6ljWTnuIvLjy_$ zK?(>y2^}P$n*@)iAbLg0aHajwcKfWwvy=)asaBKDIk|n{2+T#`^TaMry5|J#m&L6o z!2QXSlkI2P$*A0t+$eS3Q%uK+r|ODuJ7Me`{2hvxfPoL@y@~JWE5Q{@(i^iIUf#6n zWqJ0EP%1Xs-#l8-&aryNg8FDQ4#S8#ppiCtt(1ON^&EC1=!n*cu&=-N4Nm^fGh%- z#Q6@paNdno%EbJn7!ALFAKZEV&f6W0ZC)A2CGs1y<(N%2z1#qdQjGpMiD!B|et%57 zoG<+T+~(mrasG~>w>U63d>@{GAv+MB^oNt7u|nJexnp2ZB9w}HMd9H_g(@Nfx8yU1 z$T-Ow3*EoOD!pFo1b+&tmXIFDumA`&+|XsWbMh7?>v|v&wsF{{Q-+LCUt}&&S$>i! z#$vH#XJn+M7Rg}|vg~zyBOwb%~xUY9WIlA2!$mT#)=TA`rhSOz} zbGnq4;vqkY6rT!3agn{t7%bCT4g?B~R{S3}`bdVj`g(i&NSQbc{9-f1#IpYMrDKtc@ZrRUd$RpAM+udUJ>`LF^I2OM1DptKksbu4O`kHEY(ycYOet|DIr_QZBn1 z?mTKtOJm=kmNv31?3aMWgxKNAxJY3Kq@F+^EEqywgLXTT%PVzPT*1EgiYrFe#JVH! zDnc55{p(*_WQU)7?zw5xrX_~RP*+0(E;D5yQoyd^b_SQwHH)@y7!DozFUP9kjJcyk zou>|Fq?j~8$Qcu<<9IZjv3?pGTOH!)=s3vT4{K>`9AVDr5sn1I2jqT~!EyNQ$FIEH z5+C8Q&$A?b4^NtWY5*7!B>vZ5f7=sOS~?#Z_!S)g_G{Wq@@GZbRw`z9IiJP5X)NA% zf1R8(4)=h1jC*?<)C{O71)m=n|MYDNJZkgWHGueWRFFkkWh@mOfj-wJN+FRK0O@#y7jX&i)05#hCc@2x3v}w~~lww{_i%6wb;=<$; zr_MAqLu($mOej1(7hm9!42OzRXn~bG4T3Q#VKNW6*n2wiX2JhX&$-Eaq8t1)}_+MDt+ zl9M)+Gg-9IS?FPOAOE*^+zJKTlI&;!c-@;$-wbDx`|)F17%gl#wEx=^^-a!TuuI}% z|M2L;4?n!euF5W(H)nQkV84$f0%KNJIvHlikMZ|M5FjLUS>m3+~|X><^Prl#5|ofbQU6JC!jL z;qixh7w0pb!E&cg;An-`0H7;D8G%iYb*CChD6P{;NFZfLmIh@;sqm*nLcob%*0T?) z``JQ&`8>rzIPQbmoEr~fN!-^*sFIp!%dN#Q97>uLhV&T4$e4-N3?V(d=A=p2JZ_!|@pZn&{Dic@ zX|by~ErvNmr-V8TsKn5KCJNQdMRqVG+q>HpaI%|OjoCe;CJ-;Wy_c^ zxRtN;UO6`EFedkNHgFl51Hqf|eD>pw;^4r=fz&+`NyoB$S?{WXf@Q7p{EKlb8cB4W zOcoz6lQl$B#3|_JbXqJrT!KD9n~Cr-;IOWfT;JF=L)T8D`F9j6c-nOmE*XG@pZd49oWgYw7bn&WIlIC_s4!Nvgnh zX?H2YVqPG0N@go40e`L`XzRRrTLWACOyouyJQ+;RWejJ{`m%H3pem*q z%U3Fe#riDYi8SxIyz}Qa&;NHA_|rWb$-?NJMB4n6xbgxJMhM<_4Gb7cqor(2uH~R@EUncwHlTWG#5piUd1-*bS zMlVP%%+LGelg6Mt^FpSmU=B~e`GPN@+o4rZ{;plD*IS^U4m{+?9g{@t)O4Ow!W>RA z_(N_0nXztZ!DV#J*SO(mMLUq!cJ6QkBXBSFk(bs$z)JgzVc3Ersgra&X;21l<})TTg_Xq znZ)wc#bf=Fv5JG(MDpld#`wz-a2>?6vNR(Db~3pv{dali`GVK^n#Z5wG1!6PF~}#8 zZ|4H<^R?#lHP1sVCqK(_a!~~Cujn2W%8h5i(AnVFpEfNm5l)=^%(NJQUXk7I6)GgI z*50#W^A4w2#a^RBLR8HbQyvZCQLk4<lo(086|3Uw-*zmtK4IQov?< zLxWQmsvSDse3lYHb?Y_92ZK#98Qi(`Eabyt7RIYt7@Nhe)|&dgC(SdGR8rRoHve8I z)0{dzz~^9_1q_Utzp8+Hi`Gp>_byx48; z_D^-s)dvZ>>SbD8Lj#-d4nQNsGNE)-MclD|VdN}u3YHd%kP~^uN@bp0@q$&cI%jLV*p`>fL_V&LM-&1PrLvD3M zMBo$Sx#XBn#OG6)M=T}?L};`GFR(XnD)WpVvx>zF*V8oF>y3z*8gBGd0?vA$5`F-m zNl9mgqYx?-C%&I8o&r{))fCv1?a2{Bk$^5!MgJ;B5Ay3a)NQCBlu*CN6r(b*^^c51 z;K)b?HA!SdMMq#_D>xfsHVfBztc;jEJ6!R9&JOp_7(UDF@Nw&(h)&1v@y8tFuhUgb z6e$+)GKo(Aq1MbvQ7+OBncv3_4LBh48{+AsGrxz2z5E69@Lf7enM@}eHbCw_&isD+ z#kL;E{D#|K*N@Bm9vJY7%OJ!5k4){2^rA?;KGiUg1-br#{Q=|m$-&E)XIntSi_RoC zD~JWi{5Fow{D#|8JbAN0twmy=Pm;>PWq#*Qkon!yV;{b&6jI%xCpCIdRDd(TSD1PN z?=FVU{9Zhg`R%{EiL!{7vOLIDSXs>iaM`@_$}78?C2+MfL~$EMOk?UE1(yzoM;aS5Bd zLEwZ5XfP+c=7w8uyZPE%lBbn{PUXeM28$`7=TmU;>=^X})Ra5o@x6BDq-hDU3>>&U zidYGP8!0tlD^}<`@n*0)qZN zuea75smkJ$7Oas_!r`5;;4g&~=!Bdd?THhova)g^ zX(t?Vba09?f~uy(cr1$^4)97J@`{cfb9<|1VclFZaInyyraU zIp+lS4F<+#mru*eNRJB(?(Rm4M>}WQqNK2dM!AJ%R@g$$oT*Y|H1(xVzrjvkByX#( zTe*CCes*oGoobFw3QCvwA5iLpu``49JQ0jtyLK&p=VW&7yht0k&<7J~XU>6wf(J1B zf2yxtcvq|)F_UB(y-UooAkF3QjK`wYnDJ?t@nX$!= z%JiZ1Uy|uc{vQ4Ldw#CX0GFvuPnXuQv_dcRuwDF||J8f`f1LM`T6 z>BY~HqR}Nx!^ZZW#pXqtvS?W&YH^^h_)y(<@4WL4(u@t%H#gTRy&iIoiwAXD1GPw> zg~0qQ{RQ9XG&nHpwr{TkXD7t7pWoPzBGm5D$jZ=as7k=(%E1ch zGr`w)_Owi?@-{;Xb~LxN(vgLFCW*zAXbt8*&h74M9bHHnhuThvLyt#(p^P+Z{BBp^ zz`5_Ys8r0konSp}eD8}rn}-FaZi;3*e!FDJlF|@lcu{nA)*o59+Chh$JgT1^>fc+3 zVe=ut(KK74M@_{~wh;d>Xx`#FIiGdrXZNG9kN!{Yv1u43VdjQ2`k$VwKanB-hwZs| zd?dS2;)w(g4D3BRG?bc3z2bd+mXy@gP=rUehjH*4mnR)$--zm2lNKRo8#8c5P_rn=8ePliy9BK5g2!-+uQC+PH=HoM+Da zCCUAt+%r;o83fOH;;>I?fvAx!5bc-L=H`Zmh7LE8DY|<6j2RLIp$}bMKH0f*hG<%& zTkUCXXm0BzIxgAW)zi@cr_iYyrBW`Jds^N7{X>2w>U=gfHV!bl=xEftKHS*vO8wyn zWFJ3v&ZE*bv=NyN;q}dR00P}=)aGeEJVh_><4JrI%|qBr)t2U)qC9qdnPIe5^NMD#iafxI-jkN+n+d7~-1AiDA6kMnQ1Ax78c zSF8KmrbZrr`*`F<9z9WOBdni{=BgMq^uKiy{$v%~RU)*DMi5HD5@?)EUma42YQI6I zLRH;nmC-5xFeJpR;S^Na`hge?^ll+2g7!zoY{*4wGev&UIWTg<5w3UL6fVc&oM>nequV3cI+hBR!&M=%8?{>98XagIi= z{(fqbJJ}Z8DB7!NI?qA32qPr1f~&u<6oxt(|N9)-Q0iYv((v#cCmF)y1^&x;@!v`3 zaOCOJlO|7|I_rvSWPVRyUtfPwky1H!Y<2bG#mHN0$UuHp)99(QC(oK)J}Ly0oMD(X z%YYQl1{d?;hvi5?_IL6ESx-J7yGV_a9cXDdbEbg@CKLhc+i#}{2X=#kMHX>n5ucBh zW#U&(BF~anG2iRSYvf6GMOF~UEQ+GFkk>O&QK$tV;1d!`DoS3Is}19-ki#sF6A<%} zqvXaN7^RNkSfzjE9%)1*i#@tNc*U%-W2a2H&eAh~N$1IoncdwpQ36hXq@^+o){;}* zWh47-w*5U`7h~&k$@k-j9**Fr@5YsrR?yElT<_rWFr!g+aThtkHvIFZ67nU}+>FnP zWVbu{o#Q3sQ|4A|yI1kVx(f1gMa9dFeJ-Y=&Lw{tKQwZrPh3sQ#5t4V4YK-8Mz*8+ zz<~oj!G6E43;94!H1?~Ey@UGb^f6<`jLyl;9Zg+qIhl!}3g~;bGug#cr;Lv?^+66{ zJ1APJcYgZe#!WhnQsy6Yd-{8Ol}Z_hKuf>3x7n3-COX1*@SQ*Y@sFp{`uc*8A^r5L zThC}BPj`eAF24EZo3Fq2#+z=q0ZBxzT~?VTL!1V)>uLwOj8uyHyGvtR-g@gTYzpm> zFMnU^zr}yG|9b!Z!C^sq6&dL2Zfk1N>6BD1_y?Mf2s0fj_AgG{E!yhp!oshu)-7Ac z6Cbw*CFNX@7*#au8!w5-hDqcR{~e^ve+yabcRNd%G_GXmpctz@a?bnl6s(I@;+A%g zw6>(&c5CPzYli9SQRgypi<;lJJAP5#DS^WJ+j(*7Z4+B6|F<70X2-|r){ad%xsl|onwXfZPN zNi7++&BBF~umHDFj9F%{_FeF{{|_a1@V1$U3xU-_UG) zROVV->TlkEe_Lp{S?+O}9eJTDqeeN@cyRyT>#u+I*)7Y;$XdXskHZC5#a@k<%KG{| zLuKT3Fiz?9B6Dq`i>&2$wc_FIF*c2~UX#W7OqRx_x;i7cWq(ZU_HBm(o0E_g!OyK> zCQfwOY059Ay`BGBW!|u1WzLV!RZM$$-HVy~79t}8z3u+{UG|})Lr0ktC-|=-Dk9C` zuypY9(xH$0S$`T~2S_h&=pfCU_ymc!8z;6Bt1d8bD>WH??@KjI{(@dTmUWbGweW8_<7yHso3M1>nVhqEb$i({4`wWhU|D3zl}7fhWB zOwP%oH5^WkZ>m)L_IcInn{K*~hJ5_PN$%vFWZeY`ugN;GO(Sr1nTF}__aDuzu%{~9 zhdSqtMxk&;`Q);(dBvO}-s0}`ws9oar7}dzySwG@;stM$zsQ#do|c^{Av@T+$#ppS z{sMvjNA|Xx9^@1=GQ6$K365NQDLmPP7hn}<;2(-B^*XVa>%?B>ss}sU+S)n?)d9h= zv1vRlAT!Yx8elYqga))6J$kfR9fsoWk$K3KInLV9fVqj|as~%c?NF|SsYpMRGKTmD z=?A2a!;urncI@BGf9!8(ETbH5mCEf(338u?zIWOa9Fj9_+VVT@#>aIF=jVmmlExN< z9Rz59AY^=gif!TprQ}Wis$wVa*g=!GJnBRu%1|7QgR%evDr?gZy;|mXFd92Vc`h+qv&B)+H!qB7n0LjzGclL9HsFNe z$aIb{9C?qjBFU)|@*^|vfCC5V3GzL&7g@xPvb6_ra=gz$!9oE_s9SO<5IAF{Yy}e5 zD!n1Nrb(vvwzjrHea()vbe}wYc+40iI8z=zg=oP6J*SMowj7t8{E+JNz3SM091{-m z7QHk#PE4==X#INZ#!OE6_U8x*?1h5iJnd9E7$q^>U9 zZu|Pj?co|Hs$zO1`2Z|S;d0w`j{qe_~ z9P9C&I};P>@sLL395btslNHXIRk)TZoaNH(`0HP9zPaozr*q!C4I6k(4n_9@I6Rfy z%aMC|1%uqXmfVZqh%=!Q-!d#+cM0*%k5eHlNO_}pkC=sTIQOV6;}E(hb7CCPIoa%M zUfSTmxpY5KIzecmed0$aUHtdO;%o<-0+CZt2bHj}(0?5E^)WwIwU(1ZxiqP(0>TiD zWb8uuh{-N>Vmi$DXp7h#X6S8)e+9jmH;4ERI!Poa&&f%TGgpxu-fUAWveqF#Aso)a zuFMhNZWrGk8fSy|FgmQGL#eE+G__zpn@yFK^f~1>+w{DGrTM*I4y35NfWCH!^EFI#v`fEd56OjDkYenGWNBNY zRKZIZZc(od593!XHCte~;LCXnh9w)2;>5p-l;i(L*z%}P9R6GVHouMiB&xi`ze-&m zRomh7ojZEkiP|shvjhR&yeXrd+x)=?$BD7DwA5x^BeeY@Y=f{0tgZ1;G(%cotYyGr0?@pTZE;^w_CemK?s@s$_385V8 z#l~037sim9HzxU4i``q|U%?*l(hI$jGHB_=wWpwK4?E`}nk51&g>K1Wajqwb>vW>n z^XTeo0CENt%rQhJL)0cSJ#}?;J&ZmkCPokJz!lok;?;z~yBenPwp{qVi~0CtTD|eH z@FK8LeQ`yXfrWLM>?|m#XJuBbFDnY1yFw2g>I=%5J9lnQP~V{ozZWIl&#b*{tUWoo zMp}DPrh#cd2#hsMXPV0h$Oql9uqMPW5!Ho7g`sjr9-5kws%km1XU~zAWXFQ5u3F#- zafYWIBpxqzhhoS(!=7&JJh2?wqOCNf{gM{Z@_-I0fJ6ws61gC}u$O1xB z?Q@o1vviK#v~T^RkFMW$c{#LzZ^%hp-{8BkPSe8INq0}bJV2+{>kzEb({0BhTPs@_ zQ}c$ye;?M@eX=)dV!)4D>*UXgB5}n?x!kQ=w;memI|nGYv3DpYroN%H9KZ2LL&b@g z9U?<88@p?2YR)vbcX_JxN+k)|`TqOw@9)$j>jO0F)&AA`Hx=E7fLi z?6*Z~{5~0jY?dzh-n|}`s*ENkB==$`uGi#Gjy&)Z0$Dx@0AKET!1OPZKdJ9P{``eA zN|3(&r}{3tj`UHP`#gC{e$yz$&fk^z@6kT?az%ddkVhpO8Wb~DN|=^iSVa`m5)%lq zG|EQbGdnFOCn;`r_`YzaD9$Mh4Ag;_FnMz7Zd)w@GDpt_`aeGC{p45)c~>!S(TWw* z?f6cfdHm5#FV!#{PB}=e)<6j)lFxg(^hZ&rLF);W9CD*Leu-VDYpRbQ-NY~xCaebM z^olE{G|Kdu6Q@k+>>M;?=FMIi9et2?SlLDlNG`LJQ|`tW-B2qhKXD4NlUx8kRi7ZA zn@pd(6pdef`TpOZF7e-oA}dp{Rv$r@Ixj(WEOLw-A#cm}8k0e&d=3WO>++_iq2wDK z5ZYTwi)>28TWHpw@Sejx`Y@~Y5l;C?OiZ|;`yeNO_rvF(f1Xp|)5q_U68~LHTpT_N z>p>y*N3xnEY_SJuUvZIQr zK378as-`!dOIGTG^C4#DPjLXoLtGQSdGH-7(>h)=srY;6oMI}40K zpRRWwLMiq%s#6Q>rA4D`G$XW*fdRKBf-dXsqLM64*Qu=^f3#(PVj%399#4N)dxuL- zO-I3Il)1wjpKGQk^Z^a;5g{}jMS00lnUhKAZ2`^5H3Zx*9qNU+Bf z5b!f7i}FZt@DXwW(ju#?i;8mi@AUVQ7uer?@B#l?rn1t(hlXyHx4(Elnae4wM~$i` z7eFq;s7Y^~D6XquswyAUEiCTrtgOt&)3K(_9to%(u@qx><+B8wYc{_=WyO* z>8{~ww3IYge-JQ^axAx3;oJOzxI1S&tPar(~GyVQR|4a)}?B72aPy}!CtJo#4D*tlR zA3pobd^=<$-66bX3GWCssn5d%{76XcQ;B2jWKRhBnm3XPsdb~p)=4rXys0TY{q#9j z=fNTetdtdD?mBVkP;M^F1C1s)STh0>(P}iaX8jT_q6tY)5BYg)M3N<$Vhe+jS*vb< ziOn0GYF36J|0r)m1aeM&!*S3c_8m=)gKeble%K5S+NL(9;@(wD67~708YF@MPAX{i zyFNmJ%@;nHHwkdR>CD4|+!{F={E~IDe;Te!x=I|4Ka1_jAC;9H8x<85pO&4Kky8M; zVSGVsnA+3RJ8RzDspB)-Po6qA6qQx7_?G+byYJ>JN^+7d%4t)_lQG;_4|eh(qt*pr zCu{T?nWq+3^~rO7lR_OxGnA3;qg%1@w;Vy5hD>{9Wo5-A4eN2~S6(%z6c$kVWh<^; zb}e!fRnbfJ;JuDf+SZc@-(LsB`S--7zG>NyZ@#^wuVDEUfN;CvObMhH86Z2!W3p@K z!~>34PhMdkAiw31YplNFiFRBgZfWeT7_|kJpGhJ3t)63+zB-*NwWs4t$(AE-B5!1jd~m z%lTF5iIc=9O3^Fv!s(ipHm(21u?E(yll7g$;2zjt(_5Bb08=-aWN4=!N;H}-9KVF*Ow3^^lCk(X#bHGz<&Dm0|O46 zN`D~_DIREqa*p59X85?C_&Tj!RgXqyh_Cyt&zJznI+NPIkpxRyeX zHlIDV8{tWXg%Tvzdt-@D`Whs*q{=*26n z8#a{Euk>dXCHyeo!mZ1+KR{U~Pa}igoy*s+cQKPEbMh6AAh+a4m*#9(N^OOYUp(ic zq%oH4$jM@Bqcj6Z(S@TUBh=7-?BrRpXHRx^d_uzh{Ro{ja5BGN8_DTX#?6{FYjSaW zpC67-jtMe6B#-Wa!_7g}X!3f{b%iN4?|-^S@zhhd-8OH*f)`%6?KYZ8-{%W0fY839 zj8Gf+AFxlHvXd=7s6#MtAjF~sAU-M9|gtIB+#_wMq93_s&G!z)ofqR?xaj z-xV(0ReIrF5(;qM`!6HY;Qcq@p1*OTRxQ16xJ?~`U-jg$U-e3Hz1}O1WhQ_GFTn5t zPk(>u{CO3lgV^>1Um@G+rXSn=n%E3r%#2KJuvjcQ1;BbP9f_8^`@t28jXiyu7*Zx8 z!TZD%-BA01P54KjeBS4SOi`)j{(+u;kINY#8*E3y&2w#yjkI9MSIF(~lKkd$=J21& zfQC-vuipeccgSNYTMAUf#~30}c`ZymMEW^HcX#ud7LPvLZbw1M$T?-uyr1VUr+iNM z;E7iz`S0~F=dbJhx9M8EkRT?L+SlIL(k<%R3bD7+i16M*Cp(CzUviG(gk3)G!d*Uc zWVM1mZW-3c%f)xi6-PEsV^sUXV?vcpP>(vz0|TcU874iwG%z_e6Gb4>BN26B0du@D zzX-}&s;LLJnNiW1(`*?;8oywR$q4UWur^fLmRXp>ZUuLIe`Ia#TVD+fEClxOgeInP z_F@zpUXTOxLDAiP{D)f*9?jQeR?Uw+`{Ii)#=l{wU>HoL2Lk%(D{XOBwJ0s6k&!IG zi~Xp-_V{c5Z97vHKIiXljH=rLMq2Lccc&as<^y9|qH?4t1M}ZgB>XOcHzUeGkT|!>Cl-4s15>&02KjLYyciDNs}c;4e3hjV>YT*y$vzFkJ8(i9nG zLOwdS_Q)Z4Uzy9!l!8cdfGi^i4aK<;rU?lF&CnOC*`%DwFzw0?yW^7D)VM!t@?&lNkJ#(P!UQwf5tBuhmw^Og&GtB)< z#g!t-cd5EsT(i&JataE?gpv|_VOC6pUJ-yoUjyxJtvLWB13ifA4imMf_umf<4^+a> z?I!^G=gu5!ku)jQuI{E?Z-J*%1{%(z=)x1k6|~$wHbjYdnYlhuQnGkUODWEg#J2#3Gz9-a2WjO*y&+D# zL$m^kxv_2LIA!PLOm9=^lzLstbPV1aRO{yOzl(Y4r7Gqi;$SvGKMg+z2$j8+IZCyo z_t;%YD^cFnNtK&5%#tM>{s*32>=&)yUqfj@Y8 zm3k?nDi!*}wV?naT&BL7AGd!9!oq$Mfg@k@Bch#ntX}?v`s6l=V=zKD?@=;64JS^V z7&mUyrl_b*n_z)uMaqB~DaF;rK{IzL4;&D5bJba+@+{@D(gHebDV2e7ILhc(`ZEB^ z8%xxXFF#pL95i#6a{c-Xb#sTfDi(?(75lT?q|)M1`}WlzIt0mWrDe{~FL0MepeSM4 z8-h3%+{0gDD*c{R1zi2uV;i4+7Io*q4H&tmCBl*lge5Hcs5Fk($R*BUqS)GT%LMPT zS)s7oo13q=V$Q5)<%Ahsy`-Fz3k*n=fyBqx)y2nGfrHEYjwtd+F+UY5r2BV6Aa5ie zGP_`&WI z{ukz>UOOBlU$QMnAy4Vfc;%IK{LYkganRuSYVw&u%HCF3Hm$wNpoH8)auh(}QG!bLOX;5kkMKI#((!xt2&8hdlnaF4 zj{l(O5S%akhXXr*J$Y2V#3rkKy$l+;;9b5~{(7y)YR|3)1*#qPue>v*lF%Y&1V#U?k0mDemFSGKnzF= z2kvu+DPima$bQ)RClao62pWRoO#SlZfB(B32J9P7tY~=u+8CHUOj`rT41f;J55DZ3 z0V3F|KgY_IG=2^&Vf0|O)Ps?_r5Sf%6q1MeivP+zBS#9y4GK43`aOL-w#_!-p0&cf z0(>XfEMz#>T;JEYX`PcamH6*);znTyjcku!c$RPYSrW%m;?abIkhX={5S!+!optTudN6%fka^(|GJaIJkHxBY4 zy%aUY#kJsq{QN|)m^=cnQ4JG= zlL!PTXGDt^n~d@Fc7g%6_lwZvv17+tx(`CQ?{BTr|MQ>!{Bh7S3dmoYrT9MJL-M;8 zhBko$&ohnK&zMPK78WOrRcG*#F5v!be+vcs-mXfTdczGjB%FQS0Y4Qk=A~oeN|yA6 z^GJi5M;Z*6kM+_V{x{}Wl76ct=@+c(Z^PWQ^{ay8b0=T~CgjEkn}%92N-aaC;E0SO zAZ0}v5t8)tdIx>53T1M13!xOm?;G@1R@&1|q~qXMn7XeHb`Vp#y)ydr>1dZO>%8>K zs$5kDn}CmgB2|V}m01Zxhv6qYJd}_%?x)gk+-_uj{R8=flPuu^QI*aOj*d!$s1S_` z>=t)l4_^pCdH-BQe!mS9@j7}b*SuXrtaITEd|KxC+%|agQ3!&PtApDlb~TFu$_mIFYRQxZoQc|V1D9psPnV#{TpJN(zuOY!KA_Nc|HX&eF+0SIs`90LMH z?ceBuq^(Q1Y{D;(w%fg60W8;FY5hb0&WLw*+Q~Mu%?V5RUupM4g5;A>{>R0U&yNq+ zDFPH~Ps`bJt*|T_G72Xa=V#htTTj6BfT3aR-2d*o?|!nsMVFYIk(Z)V1{e$mKkQQ- zRu9h?9~aKT`>3OY@y>&X8ey>h;;J&0@y3U`zwYqMV3F7O>j~MlWhsfmG-@8s z)|{(32dL%Omm@DXr3lm&%LF|s@#Ma3Kf$WI`(ax3H=X?MT~r>~avF=-&_OylrN=X< zH2?5}i?Ld{AetQ8pcwR&mls$K0|>z|So6zW5#ho?O%~&p{9P{@La(B)>o0rOTK!dHRAW8A&PN3B@oBJQva8 zijBOKj5wQ`de$YkwBY=5kay{&xypK|s;cVMT22044)C2`BF_h0Sx~+J0dW(&JP~HS z69j^bmu$$-2#Zsdm8X7+fejShIp!vJgs{K&-YpAQJ1{OC*0#1zGvj= zW1$)bhEo{nk?&CpnoQ8JCNuIG41ESGJwy7tO5BHQKzeBO|TT-$-YJ7wP3|igCvHPeXaxcG?q>J9d0oUPMp`ypwvb zH#Qa=X+g67$~yHQ1u*77G!ia$hW2a9*u^FP;}89|6%@yNf;X#h;2kB*exBA|S;NakpARKSQD^}8S&Z8nje2`i{T!!K*xC{dGc$BrXC@{k-LNuxtC zZe!pw>Fn%1v1{KMx8M8b2Os@&`!Tms1+H&Vni2_AJ34!M2Rsf(mZtN_M=!qk;)dfr z`fP{GVhHFujtWs=jUuOCEqFKMae-dSr;(8qaKVn#X=RH?Wn>!yOqR^_XLm(sH zVfiby+T2^ER2aAB0#Vgh$U+U}&8>utYThYOn?ZjXE`F#^|I64gy=nu$eq(AmLmIn>VMFfwMRr z)pZsxUOaiss_43Z{No=-16QpItOIOP7q|-h*r|Xdhj)aNCnj3M%$)h2d+u47DX*rE z*9jq=d+;wrjY}uapi!7Xg`AJvl-JubinE+DvZaqEtWyxspl&=<-q&=S8($>Q9X>E@X{n)OOkY;jQ%1!1xn5A)a8o*q%k= zii&J$DJrp-O_?#<-PhIG(a~OB?(>zDw6+2R0bH53b*o2_P&lP*#!P#vfi)V_^fPAY z^&HW=nB&LG0S5mSaOW%Fe*cqfReHLc8yo8DsA>2*Pz^iXL(HjD6sOzdB=>PjHWmJ1^&z4ZkqB7!3k;>eBI9Rnm0m|-{A2$z(x0koiqlMNZp z;xSVCsqh%w6Ew_fC>F;=iUp7M#Qt_gQPG?^tD@B_FK=%ey};*N5Q@y8r(36v1@X(N z@uZQHDJdrhWkzV6X&x@XXgrBu3>u9x7vq~(4w^wbDm6Sqwv+9QfvL3G!K6IM)*pKS z97RR}@wQhnQLmr)b+sKvb(OP(9Kch17LZTp&i!;i2~~kv(8C2-t)Jo-16He29Fvt| zOQl%OoZw_ix)?WMd{HsJj*d`3Km-`g7Hv18%saIqDpiaE-?fqe4T`lAE!J+f*NfU3 zupfqoSfxU33JnUh1nu4P-M2gUH}osQ;^X5H)Z@2U^U5brv5#)<^SW{pidTX)e%HNs z-@6)LR}@4V+o}UBVd07cQ2Tz6$0`(ggZS=ScUY)3sBtKiOyZIe?xzY22@CUjWm;Xh zEhRb0mi)%ce|!F~@9b|=rlPnTT#Y2L5D^b92-UUnRaYK5+b8U9i`YvM(~{_ytg^oN z^q6Dg!U%$D)}Xff;~d!xY?Ix1=Nl9z%OlnjM#F&6?hh8xv5~Xy7rfC7EubsxwUPHI zgnM+u_efZPWRE&!iWXSh>zp#(0k~q;2~SEA+nq1$T4Fw}oH4b&zPQ+C8#nGUS=)3h zIVa;u*N`OXNcXZqdU?QLyEMaci1HomZE{OIJE@BldJwf?D7 zX?%!H){fP!MZ(zQtxbIXY@bVm;-~=uzSc9RPo1<=vq`pXTiZ(N^>`BM=I@mEESpgh zi5)@^>G=vSN?!Pf;z7InD3-MLb&h-M$2|vWdTfzbohXjj`8cim`bn|g(|P#~4P7yw zWJH;P1FkR{$Bjc%6d%6U)%D)TRm^70`ri!|J)hop|F&;x%DXPR>n`B6R3_hkJKjTm zrWH(Go!!64ze3==Nl{qAg47$1!m2MmoO8H1SZ+);5(Fdi%jxBtU#3DcTW+0iB^$++ zG(sA=i3!rE2a-mVMp6uBv?y7%_4Ucgd-hak07lVb-q8cu!L3^lR;e~`zWnmX9^1f6 z{l}fa_ng!?kYRXU7oR1)P11i@Kd^f!KtY_)AL;MsH3v5ainiu_7Eq}*apGFk_V)*9 zG{waeXU`^6kgem;)~!Y(A_A)50;8*s0Wtl|8H1@5NADw8f6qFVZ*W!)2a>STq&G@C zfc4^dr~+OM61Fq~(oPy)jnw6Z)oADM68D>gx!f#{6AF~Zp`<2oNfI0qm!44yE1)zr z!J<$oED5P8(NPKcz#j4vBBN5=Zk$R}xKx;r@Ob*wCQBgw2(qaCp2?H*!qt68;FiP3 zp|VWkNrt&+)8F}zFT2c{SFXl~ zz{~lWvC79-sW1vJOJkKOuKYZ46oQ)v)C#C*o!EM#qJjsT8X8JUh>f$f;&+|?K%+5& z=AIanNsPuS)&9;veKX{`1K>U`x=iM?XBIL5Ue)NFp@zsLr?e(p?qrTQ=dOIGY8_8ydbmUY{OS3 z;-@n2yw7*Asi~|i2VvP26;$+5XMVtp@kS#piAuKs{m#V>P)Hv<5!o%WW5?_;(O<=` z=J{sq3ed>ti|({q@8q=t7T<9!exh`TpUORzIC@UDpOOaXmz9##Gl?S{BHS~)=SPpN zsV_bf;#BAf?WpXwyZ^Zv#|ZOku9J=6JBc$ycu$u23<P(8FD7qjeU2Lw1S*|JKpd&)7LaNTu`;rr?&*KnGm;w)RZ zjKvI1up=q-BZ`HogS&Tq3pb5$8fJ@am?ZX9SuzFMwmqNIYcz`%Wm|fCd$SiUB4wOB zE-u)tU8AErI}Vy{5SD=5H3^*czaqm1y&jj}<#wA)lvTf7u>v%~YRDjb@1*e?@(B~t z6GGO=IgW1$vV+PmPXXVQHbfYWJh3GeVoSo!=IgJIPXz!JA3;Y1F;NE*5rq+%$vH!C z#{K-LBqvjCs7HO-Z*IBemdhqd1CwzM>UCp=Ffb+LWAIe1R`P43BgvfMmEfn!A61jj z$BoB}?Ji!%YtvvD({wld2cP(cH3p`HX^#|RRg9MHJ|`O;&Df$j?O|fH8Eq4jPM(~I z7#^y(pZ`YyXB6p+7w3hohsPBs_2bI*w<>?9ytR~_Iw6!(yhW^2t*}wnF!T1}v-2l9 z{RJ{R1~R(|%qdaoOID4fhbHKBiHWMAZp65E52=FUle-5L+VC8}wK?Hh#Xxs*d=Nmj zxYVYmRIk@3Q|Zh>K|w0t?(Yyvb!tErk^|s!QmI+xb%B>Ocdo%(2b-wQYsi?fu(nkj zmJeDAA8o3+DL+ixTDx#Y2Ff~x&pU8n9u8=QA zP>=E)IqL<;NTM{;>Juz4z}rI;$$^PD($vV_ZEt; zxkGLC$|E&0gaH}9n>Ovcw6w$slfr|&V6@Scolgk0HFVcxnL7XZ?6c24^~|6-P1sKo zwjj*|2jjE~pvnyKY#q6x%(w$9DhaF}@eKR6Jlikl+tl&GGbprG)Gcnm1U zp@|8h4wJgNqN0?HWUxh5tq~Ee7K>T4M%8^1e3Bnq`(3i2qI8SPR8y0hI-_zSEK)e( zeo&9SMaqP`X%oLw&~6IbZK(1anvc|^AU~7 zVlind!g>#HJKP&a2n6>es7sIYBaW|{X$8@Mf1?YgU3rgKI#vseAifq3hT8aP@cMpC zj`G*X?CsZ?EhoVeY7M1;hG-+=1WYQLM-x_d@2BF5r-7 zL|G*1w58$*gO%7E;DP1h*5u^W)=aSDXKfT`inp` z8<%x{`i*q@>5?FM5x&Ow_(qqp>GTgf+RuFZ78b&Ym4GwGgq0wyl%=sJPa-Ja#>w68 zUP^xk5={OeyJP83SB8#9?XztwW$$ZROw>%Izzd`~P-JHCx0Y^4xz^AiyB>3=Q_PEh_oOLN`cYJ@irfCxC zB7=;QF)|^<%Z^>Xibm3WPQD@EAhC2@;dS?ba?jj|t$&z3pwl_PQu~2X;^;hyx72D< zk&7%dRa?u+zuf-mr=M~LeA@9P$$s-q#RjW&gF;-llH`yyd*s66px6W15YE^{ar6ts zewuqb=GfK#A!Bywgz@8x9W#MxJM~6mMn*_TSg7T*PrulCpo-~jvXgJg%kns_Cg+}V zs8fH$j6a2Q{}r+YEqouoVXJk~qO|m^jCe{6y3W6f`Q3|xMkwh?7i6fQ_JB;;Kk969 zwtbY+@FSr(mF&>68t5}?VT!I&CT#)LMzReYVw)vCQ%rq*YAVbgWth4N8o}xAfVhm* zF-1lBK4SaKI7b3CHHf7Pm0D=KVc0isT^9nliM131)6WSzyKYk23es=sWURUE4x zQifO*o&jN9tHf3gTPJc_NYBZ{krMKiB-w8g@481E|FQor!cx-GQUa7E_uoZX^ibzq z+5axm0_%&}y&IpM1GM|3RCwi03ox5U138`Tc zt7#;(y>#_z{$)<4XFg|u0!R@tx5{euL`HhVJ(Moakz{iO4-TfKosv(VLQm9$g#7#k zOzSjoO_hzd_(tMMt5Qi|oeN19X3qRbL-CYq6V;Bwm-*^h{~#CCat zQ&MqAdKOfvBtT9WA*t^r%LFf=imKp)@z<^7w2Ky%l+2%hdyM9{DEy=R#%TNoZ~iIL zGcv#vdv7b#>?kJ<`~)$qYVKiNba z(kdQ#Pd9cQ?x{t#2T_L^dCx)M6u9S&VaAcP8y=E&gIUoBZM6P)avtSDq{oGLajtqo zQ^qfZJ9gPD`-Gx`^w>}wTp@93JbSDFF$Sqzt_Rp-kkK66+eJ)~*$7)s3)Xp0g8FjO zs}D*XTR48u<9e{Z4b$^f5AU78Hex z@2?;qk%Rp8ExvmegZC&|6Y$&0JmkR`J$31=RA1$J351hfT?G0>E;7spro_aipQ~fz z3YOh<*Ik!qhIx2}(i@pP<+u0T-rv*F<UomN6tsGh|GFo0j&+WzTNoSH*hDf$vbW@reHyExER;4W;V`3z0X^{i7R zz%MD-4KFZ3qCE-=oZuHERh$p~VE4>1@-{oL4!|d4IQ1c;F+JUAJe0wa3>V{vDEg9p z&{AEBP_=cS=f26FIDvovJ5K$E)q45mR_hy!kXlh#+ezZH$BNH3yWIr^7d>BB7ad*q z({~IE*b#5{`(JpMZhvOx{*mvKMpV+noop9Op|xu$NP=;Ne7{a!9cQ{m0xtNmlm&5;buYDGcqg^- zcokbmZjt6x(uO2y7v9-9YE)CdO5WSi(E;5rJ2J?7?#!8q6QOQ}$il;AKZn;~Syxv6 z8fFs`SW*&rN!&)llq9_Yh#;>x*f`-7mv~+0&tMdKX_kkLE-sEuOif9MPsW0#Hu}+{ z%DsD04l9atnmUew|MEj)PiO?)v1YBTiqU{3J7b2%rF`nCr}hTq!FvRnj&|z2rHg0I zxNO<7Wz<;5Z`7~7W_aqU6)SLnI*08IE$od^dD((aS;YjUfF4UpoI#@8zCoN%DSC9w zRI6#Irx$fu3Nofn$clrjHX&zx*{pf<=FOdb-F0!^L4DfzX)Cc!?^-#%I4?eSW@R~! zxzX?w)^{s>Lk4h^V35dF0YOGv-XETwfbqH|Jd#MO-Y1E;JGNm{hBBz?T{x zmS77}48pV`CsR{T(v#k$o0J_^mK{k>ojP@HP)+?A|3s)0&;203XP1hrh?zUr!Q*4p z#evfwBl#ze1-GRX-W=X$3BO@(p|*Ws?&wkFQ&N=uu)WTE$iy`@au4_7yn*~^2eu}j zbQiNP!`!`XO@sZ-r@%xmE~dTPzds`*!wf`U>+^XB1XJw92~KS^0s%3O3WMjP^X#GT z`&#yX_}p{P@rJjASE`ZW6 zVGhX1H^~I=uXfn`J5OBSSBhs^N^~0amyS(}4pf8GDn}anF_&F7IU`!%Q;&}xeMD^T zSe4ogVV-2M7`18z5D!2e=8)v9EF=Rr(*$t2fyCgZj)w1#n9UZKC81~uXsnlyOAMn_ zf~Mv#zPQXmsIs!gGC9G&?PYv?GZ>Y=U{P1U8hUXsC<8%8^^n``?w18wL8otO8i>Ba zL7eo`UlBbJ(nX`I*MAmoOT6SNx1xzyQN1 zk4MyR*V!x`2!+jjK8@*n8a=A5Pi32$*i<_qW=m4(oH=t!lPvx^@G0y3mf|uv#a|;Y`>Xs9 z$X`BdX?U>=@nJ4l^KX)M>_n2t#YrHU1e(3@!grxlri6a?!h;XaQ5-m+nDgMJMo0z4 zf$v$OG~XjfNDqV-_oM?}z2xeO6nuNrvATZuzj@cNtPB&@d;wk7my$>=w8>8PBqhoG z^q%2;VTIIN>txE%@{gsv9OCTG5+y}UdwX_vMTH3w=N2RIYmlzk_IBWj`LRt+2s9c6 z{fS~2kPn0ILRvAkARAGlGiIctK4p7qYP(BTUA<}*jlOxukdYc0kd|y=&Vli%tF9Jt zMb-UN4jx>(lw1qy2L&+zfcCauf2Sx2*lXt{Z~-^oxV+ftK2=(JN|XfB-n>d|XKZu( znJMv}D`rNA1VkZz%umT&{qiE@c|dlO!W2@>Iiul0FU9eUc-CS&4({Ce=s*H>gH+otE| zPp)B7CpR}wnL@`kAhsS>Op4LilE5izj+5G`s9Kk7AMx%gAs?_ehu48+4qFLY8N1E! z+Y*FFQD6}nVW2;(!9REGfNe9!YCSZWQ*QZ~94II_AhckmILCL0W0zy_(xMN|jprK9 z(BcmPV2@=*1O}SJM`5CK!t_y5a+)GB&lV9L9Fm$4{vWYt!sAud&_}=DwP*LY_)?1tPp?Hte&2km7KF=N)|-&|Aa>)A=1AQ`EM4gA^qID6kD{K_dO57e1OHGHn_%EeOProN%8@7ZofYv_%ZopjKh~ zFbl-Uvp_CjiiovxkOXDkPn9IY?Mp>Y$XR%9JpM95A;8{i zK1H)EU*5SDK+u!yKO<+Bkhh)iB|E{vqINR!wVp6ISKkvs~b0t#`LrwKy|qv+le`ow$_~NK156MrTKhrpUM(UEkQIC zT945my4Xa@;8NQ_|)g;>d>`&CNY}6dkka)MU^Q;Ol@U2SXR}MwD}7 zIduy9`|yIM(78*#{?=R9uXn(ciAy^p%;4*d4(vY)bC}PS%C5)RMmaeFpMMVBoyuiN zuUFi@lp^Vu)XSO$>!Wtq`jGsiPc7s123rD;3JFYqsyVPMyvfubE&Ad3UnM{ufxnxO z5FcRY7V3yN_&dQp=il?mW^>jF~0s1Vx`0`A7$u!QS2gq%HM%hBRYK^EAhg zTdner?Vo@C`L}(9L}PdEZy3^sk1mInF%vGw@l!z{D9?>DvS;@ToDunTsj4%tisW5p zUocN32~h7to$S}^WJ%YG#F7XuR@2hQ2B0_|lB)DGuoD9V)vTKJq6S3oz@R+15dKM_ zq|>d1!DpbmLEBcJ{Ol12jbQMvVxRb?S(wG;;%dD~oW<-2vkzuYb7Ot=3B-oAsRC50 zfKCr9*CpiT<&7&WDVq#iJ}cO04hhbP4~Ny8IXKAZ5%-f|iwje_>%da}{s58-06#Rb zeLWqmE$!}rkaQe(B?V);dInuFnUS3^`1Wl7@}sw3d+oLTh?JKH9BUqAOcPhESaIzw z_s|vm2t_xL*JOS|NTe-(R#6(ZuWev}4bK`q!BJM6sq5Jd_w&ndf1EQKAfr{$)?9bu zSWTBX6-knK{atbQbyuG`Hz2N$5mL*8h`K67zeh+?t56&VDI)9N=AOD#|9$4EOLY*o?6$ zp}sxuz4zYk!H9tYc{RS<$}ukF+9VMg|;oqd`VB1 zFgPbbI9Lg5aL3x8>YBqkt3t3Nw8Qr#h+}y^)4|VpE+|X%0Np?JA#(+_p{>PC61Hi^$e*!)93FM*l;;k z%K(DUDa4w<1=h5PbhuFXdGg0522!L$wP|~^|19WC4j~D->bCOqcFF@3!^Y=ufm@D< zgt$>tz&g5qdJ=^-E@4BC^rtKkNAgy2BvU>8ZQvRpejv%jDi3g7Ykir_&ZKBu&)-XRd@TTCa+6z`0)1-)}p$k zTNvH`{*zBWiTwGoXFn?ip<@xfn3NQ|{~G@_+TX8x>~H`0`*X*B*h3mQwcG7gg<7q} z$aze4sP%+XRAl_*XBqvO(`akY;y~-_X==SBCiM*sFmkeMh(cP|lGP!h%dy&C98e`C zMWZv)vr#H2IauSa1-Yn8A2S~Gq&URGSW$Zsti|zZ2*#s1kp?{D$7ciw^aC8|VAV0> zUGk^~=ph0*;W6`V%dff~OvTGbg?E4T$}6wbL{Fg+e>@1tR>GrZ?e3O=&Uohn_>l9{ zg9qEY@4owrbW1Cam}-To}s) zLmq)y@<%S7((3-DK1g=bZOiywdr6i~T@f5`@u8;B`1Fb8>8-84qRX$n zHpdxs36{>LO+w%f1*V|%1T3F929j{h%;m^3_aqO~zd)W0xMTS^H!ukIxaH+I$9EBg zFyh)pP{m{wwc&S$0>D!B+=ZVCTk{{`}@9Jgz%(+_)R>6`6T~ z%d<1b1KBN#wVZn$bfeeLSqkwtKJ%pP-U-lx3|%y8r{=pazu5NX)9b&eUQ>z?W*P$i zfaZ}GcDEs$QGZ`Aa>LT3D_2H#Y)63jVtUEfZ10G?61k!;DdEA2qj{P{2``PIboK#{ zg(ib&9Z`a-#L*i*`P4WAc$^93Ibp8wI$n!-Kpf%BPd_av_%|e}wJScp>tB|prBqr% zrCakq5UaYzsZ$&OBhf1KSUUHlQA6Am9kl3+M^!pE*%A8T$R|Y6C)lMYj2w3}lr4;V zDor7HsXa3C9?7bb(3voIUn?)-OX5|%C!sfIWE?(xw)QO48I#X9qy&*J3duaDPlykL zktG{EQ18R}b>w@jU@@ZJI6t!OBTz4|x#s1UcYU)Bx&RI-pCQg_opO_ONUf30%)_B1 z)7787=roc>Y^09$GqE`5&?>~@Xm{f!>n_#jk(!uvS}YUSqfKpz#Kw*e4+>9+bvSUq zw?eI@d;CzBEO-g0^A@tt*LVzh`;=OfrJ|xBT-765$q@w=E^Sb15kSGx zqP&V*U_L<`RRR1t;!&M`!QsD$Uh)^JRoM~+S9Vi2wi4*RiBU#{7eeIFcLzC{J~Td2 zu!mQTF`lC=$hR8}V*r{u~CA?m0lvrWcsww4FxM$?q-^VYE zvZ6Hp>`w{S^qt1p-)@MXfFVl29EfLs*=Tz92O(K2&i+)h+Jm#dlT}-PdiFnVzHKRg z_AkQOzX@mm>FA15$gBVK?7v2uO`QEp{#$21l6sbqUGjx-CP|MS4A zfIQ;*lluC3S#CHyqb{2S^nMe6({A!GPXDJadHOF(lQfuOQG=N#%1EigrtQ3@m7bmj z-G|q-5Y5u5i{&+~z`z@CL_~RO5uEnD_mu;>`=M;)^d< zM_s6JWq^k7CT_I-GcN8|w3cE2;O%1De=p8Jfs9os6rRp@6cTi3(+i7>^0SlUl*$+4G-@gB>2U#P; zeqM5AY1AsUM%{n*boI#-aGf(f*OWq$`8|yKb(*_Z&YLz$Z##>sRSuq%`m}lVb=Td7 zkjCW&ao!!s;n>tBzDTz~!bV;R2M| z98YPm5NlJXzV#Nl`|dKU2QQ7UxVyVsoo2PdNiaT9CFNX^B%?=wEi1UNZE@com229im2ML1f<;h&s z-Isw~QIHwp=vyl6t|yJvqbojFhZu zDmh{HUg{ZI;oP+jpS#j%&X?w08+eVX zS}uOr^E{-BjjZm7h#5=W&OwU)qd1EMud^{?%-rS6m(Lt!wR9Y--tgWcJ7m#wmb>lI z{hx!P@I`N6{ERtG9SmAy8Fn~(^l7o*G-#7RZRgP{-4${2mSJb}CG26bXMF1MOZ9%_ z={j;I{*`-1YK)uq14OETMYac6kSG` z1n7KhXpoymy4ka{#}t6%7Cr2T`vs;`ef{hj1SF21{a2$E*y zB<$qG7;SG$H!_ANs86q7zkc6JkXXUf@H{TSVHeY<&ed5zn{r9AHwdPKr2ZdyiiG}0*R1EZ7Dr&44Ak_54Y&&ux~{r|Q1 zCh$>JXaD%QclLcxCi^nk$U;I0Bw3--=u7 zQY)y4C<-D9vJ)VL?EAh=Cdp(b$;|J2?%c~3aOtn_=lB1A-sU2V~0e>ZZw@WhxXk~vAcC#3BbA>R<2+E=7#>(7P=u&FxsZ)*hjRW$Klu2-( z=$$2+3xr?Q@X4w^co=$XU8M{Kl;WKr<|}RO?;wn0?bQL~Z4RrJAlT#B+^ES*0rWIsu7T`pC~ZD}WC6d)byP*IWac&r;We zC>N}-Xk>fs?;4RR$a%x zeF|$5h5oQAe63Y>yH>&Ad?pH=J-Ci1@^d8LIgv~(j88nHMdYJ6m3#~hjLB7+5MVil zXjE=m7Pic-iphr?B|iq4cQHPnXM`yE)vY8W9v|xa04eh@R`y|FWlmkjnXU4Em=5~o z*0?<6_vFP{8&JvVZhA@n*kCO#LeSwS{Pi?j4DcX>+dbeRDm~V)UPU|uKte%8mUM%I z)I3)R$P`@C=W2*!0}%Iv<5COrVhGNQ3{faxPSPf=zc7xe-LjG06){=>j`sNVdr_R9tgmF;h7uCJ-V5eCDhFdw4UaW)1?s`B@RL|Y^+=x4Wj zVBl2q=xA!{723E&bT!F_lbZtBcjnE5xg^an0Gq6-oE9Vfd<+#)L>zl_pe=P~g5(Qy zw#;5v_m5peL)TuLPo7XkEr*#Xd%ufh1vP7>0)rW!{|S z047aa8;sU4rJo9Q%0m+q5v!i~8%amUV_4ruJL?X?dZxu*j*{ zGs_pH&77SU9qqs#jxj5SYk;@YqmG&h5p-5G$du&+#^ex>eHj@0;6t2-wF+%w)`qJy zz%Z;vox<-cDw-Cq?8OSG^{FhGMVva$?!*4_#?M~yU_L34PRp86@X!^)mihoNG!Mhp z$(e3lwR{y!y?`z3+ydy#a{GJ=z8FM>dyHKGYodmt6Lt0xtVX}52>a}gAQqtXV?)>y zOxK^)4=n_1OO21vk6}}Cgwx!fZLC4L*jl$!u^DA>^=1WF_el+bpUx5Zz5wbz@L zww#LfvKq|C7hgEZ=cST;&+bFaCe1K(xo*Kj-YcQWUF0JkXpr5-akOfJupb@}+I?JT zcZOCmN)-^P)=D!bBTd>4xDGnBlR@aoTA2@@`Q%!2G(L;5XuDv0=+a`duE;>7WiBKX zh1Lvk7JG3twf#aR~JG zSRxbi5v5&_5_y=}7U8aWiIGPI*D_lciC_Rej)=Vj zNtL* z`C+|!u0U;Z-H8^(Omj#)wnD5yI@;N)P|4UXY=L8^+%1i6!i>V`AJB!S6o3p_R;C51 zX>fpH-O1$|y+%n<^cm?=tj0z0UL5?-y;Ft&sP2BZkCpG-d9ZE73`a*i@IjC7B|T)n-v4-@PNV`olP~oXmkBD0uZL;nR@dA>KzCkQBPr~B+w%Y#eC(on6E}o z%i!`Ns&qp#sl*Y*gO5s|L(m6~DA7vwe{)8Oybl4UEmgpRJl?O4$js|^E6tH9;KQkj zNw+OZO5)F`>7hD*f5$24kvl%?^kM;%VOK|ELvtL?D2>mzf9qeKefHVYA=B>!r_j{b z$tKOZ9_sPkcic*IC*P2)SwoL0`F)w;zM3O{FA5F?&~LvC9#RrlTYcr3s`*sUdNJrZ z6#4VnGs+hjY|&a(-YO&)Hj^b`d7}Vi4tHml>irr65#(7=brdnJALkS@wpQ}zp!6P z!alz~xX;Zd=${BS7IwLWs->p>j*fm~XsEIC>yJMAIwTjxyiC3^fcpVzblEf$zu8UG zNQr5nib@UxM4t#lN}`?|L7nRx=p`*ZLb73x;T2Ejk!eT_Vsy> z9vyMHGC4L06|hiAIH`8amPfT4)QO1|74D~>?yafWz>&FpqEIkhh?%>CuX+O?#(8+v zq75Z#XsGt&R|wQP)Fm^;O=@qK=v8KDEphR2t5$`Ca3vA*!gS;PEmeCVtA4n%-vd6N z@b~xkcJ-uz4@g>D|Mt{;M5f(EFVo`(0x?%_IIySLVw;Req2dLF1!M<#naR%PsK6?p z5l@2mU_XdlqEwH=zWG|p_Us;aNg$>FH9suZNv(NRb#`yRVJpS-SIGHKG= zZ*SlJ;Da2MRF#6HIy@ZYg$snyUn|Uh%)rQSXT4mfa98ccdA`4Xu(>fLgvp(!RcowB z^sYVHzxEXu4?$A{Ws z+HC0yXzXbjwC;Aq6bb;I8=agGYPN=Bk%cI|ZAYL59_<)6qyh*i-N+%c)iX5g9uCm+ zX6(HWAhquAQL7ypcPvh(6|{_WAVoz}?MhEI}~rRHS70OjECjk^25mJ z$cWiLo=@XEacwd@a@DOj%*&ZRkLFmJ`}d=oHsVeL_eg(ta3pRW#mmFR+@8n*QghJN z-O}yHieyHL0_z~R1`(`(cg7ZS#f?z!)%R1eH7z~@nW6>As&Z;?$u#zV_VUXwf7Wk| zhw1~955LdC1Zs%8SAF7>L-s|B`udEg4{ZWT#_H7SXM z#OjyptsrP@DXFNvy{&t|huS@IiEp60tvxoD?X7~uTGhisVr52K z5YW)>XQW|J6eAVPTZMtE>BYXqAWw(K&oW=j1UhKy#R#L0#$9#^^N+&78hWwsGOL6X zDzb)yygI55iOT@wQAS*ddKB{N!stP)@4@JWzdmy0cumKU43i-n>Zmz>WbRyL{dSz< z+v}8~ygFgcNi=p?7a~l|P)GTRLHFQb>ruq3?fts(Om%y2S1Y9G&Jl$@8-BGZAre

ZLu0FSyimZp*MpOxqSrb$vRAx0R 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 diff --git a/dist/index.html b/dist/index.html deleted file mode 100644 index 963e593..0000000 --- a/dist/index.html +++ /dev/null @@ -1 +0,0 @@ -ControCoro

ControCoro

Noi siamo il
ControCoro

Il ControCoro è

Quantə siamo?

0 ControCoristə

Chi canta nel ControCoro?

\ No newline at end of file diff --git a/dist/main.js b/dist/main.js deleted file mode 100644 index c6fe911..0000000 --- a/dist/main.js +++ /dev/null @@ -1 +0,0 @@ -(()=>{"use strict";var __webpack_modules__={874:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */\n\n/* Document\n ========================================================================== */\n\n/**\n * 1. Correct the line height in all browsers.\n * 2. Prevent adjustments of font size after orientation changes in iOS.\n */\n\nhtml {\n line-height: 1.15; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/* Sections\n ========================================================================== */\n\n/**\n * Remove the margin in all browsers.\n */\n\nbody {\n margin: 0;\n}\n\n/**\n * Render the \\`main\\` element consistently in IE.\n */\n\nmain {\n display: block;\n}\n\n/**\n * Correct the font size and margin on \\`h1\\` elements within \\`section\\` and\n * \\`article\\` contexts in Chrome, Firefox, and Safari.\n */\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n/* Grouping content\n ========================================================================== */\n\n/**\n * 1. Add the correct box sizing in Firefox.\n * 2. Show the overflow in Edge and IE.\n */\n\nhr {\n box-sizing: content-box; /* 1 */\n height: 0; /* 1 */\n overflow: visible; /* 2 */\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd \\`em\\` font sizing in all browsers.\n */\n\npre {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/* Text-level semantics\n ========================================================================== */\n\n/**\n * Remove the gray background on active links in IE 10.\n */\n\na {\n background-color: transparent;\n}\n\n/**\n * 1. Remove the bottom border in Chrome 57-\n * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n */\n\nabbr[title] {\n border-bottom: none; /* 1 */\n text-decoration: underline; /* 2 */\n text-decoration: underline dotted; /* 2 */\n}\n\n/**\n * Add the correct font weight in Chrome, Edge, and Safari.\n */\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd \\`em\\` font sizing in all browsers.\n */\n\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/**\n * Add the correct font size in all browsers.\n */\n\nsmall {\n font-size: 80%;\n}\n\n/**\n * Prevent \\`sub\\` and \\`sup\\` elements from affecting the line height in\n * all browsers.\n */\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/* Embedded content\n ========================================================================== */\n\n/**\n * Remove the border on images inside links in IE 10.\n */\n\nimg {\n border-style: none;\n}\n\n/* Forms\n ========================================================================== */\n\n/**\n * 1. Change the font styles in all browsers.\n * 2. Remove the margin in Firefox and Safari.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-size: 100%; /* 1 */\n line-height: 1.15; /* 1 */\n margin: 0; /* 2 */\n}\n\n/**\n * Show the overflow in IE.\n * 1. Show the overflow in Edge.\n */\n\nbutton,\ninput { /* 1 */\n overflow: visible;\n}\n\n/**\n * Remove the inheritance of text transform in Edge, Firefox, and IE.\n * 1. Remove the inheritance of text transform in Firefox.\n */\n\nbutton,\nselect { /* 1 */\n text-transform: none;\n}\n\n/**\n * Correct the inability to style clickable types in iOS and Safari.\n */\n\nbutton,\n[type="button"],\n[type="reset"],\n[type="submit"] {\n -webkit-appearance: button;\n}\n\n/**\n * Remove the inner border and padding in Firefox.\n */\n\nbutton::-moz-focus-inner,\n[type="button"]::-moz-focus-inner,\n[type="reset"]::-moz-focus-inner,\n[type="submit"]::-moz-focus-inner {\n border-style: none;\n padding: 0;\n}\n\n/**\n * Restore the focus styles unset by the previous rule.\n */\n\nbutton:-moz-focusring,\n[type="button"]:-moz-focusring,\n[type="reset"]:-moz-focusring,\n[type="submit"]:-moz-focusring {\n outline: 1px dotted ButtonText;\n}\n\n/**\n * Correct the padding in Firefox.\n */\n\nfieldset {\n padding: 0.35em 0.75em 0.625em;\n}\n\n/**\n * 1. Correct the text wrapping in Edge and IE.\n * 2. Correct the color inheritance from \\`fieldset\\` elements in IE.\n * 3. Remove the padding so developers are not caught out when they zero out\n * \\`fieldset\\` elements in all browsers.\n */\n\nlegend {\n box-sizing: border-box; /* 1 */\n color: inherit; /* 2 */\n display: table; /* 1 */\n max-width: 100%; /* 1 */\n padding: 0; /* 3 */\n white-space: normal; /* 1 */\n}\n\n/**\n * Add the correct vertical alignment in Chrome, Firefox, and Opera.\n */\n\nprogress {\n vertical-align: baseline;\n}\n\n/**\n * Remove the default vertical scrollbar in IE 10+.\n */\n\ntextarea {\n overflow: auto;\n}\n\n/**\n * 1. Add the correct box sizing in IE 10.\n * 2. Remove the padding in IE 10.\n */\n\n[type="checkbox"],\n[type="radio"] {\n box-sizing: border-box; /* 1 */\n padding: 0; /* 2 */\n}\n\n/**\n * Correct the cursor style of increment and decrement buttons in Chrome.\n */\n\n[type="number"]::-webkit-inner-spin-button,\n[type="number"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n/**\n * 1. Correct the odd appearance in Chrome and Safari.\n * 2. Correct the outline style in Safari.\n */\n\n[type="search"] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/**\n * Remove the inner padding in Chrome and Safari on macOS.\n */\n\n[type="search"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/**\n * 1. Correct the inability to style clickable types in iOS and Safari.\n * 2. Change font properties to \\`inherit\\` in Safari.\n */\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/* Interactive\n ========================================================================== */\n\n/*\n * Add the correct display in Edge, IE 10+, and Firefox.\n */\n\ndetails {\n display: block;\n}\n\n/*\n * Add the correct display in all browsers.\n */\n\nsummary {\n display: list-item;\n}\n\n/* Misc\n ========================================================================== */\n\n/**\n * Add the correct display in IE 10+.\n */\n\ntemplate {\n display: none;\n}\n\n/**\n * Add the correct display in IE 10.\n */\n\n[hidden] {\n display: none;\n}\n`, "",{"version":3,"sources":["webpack://./src/normalize.css"],"names":[],"mappings":"AAAA,2EAA2E;;AAE3E;+EAC+E;;AAE/E;;;EAGE;;AAEF;EACE,iBAAiB,EAAE,MAAM;EACzB,8BAA8B,EAAE,MAAM;AACxC;;AAEA;+EAC+E;;AAE/E;;EAEE;;AAEF;EACE,SAAS;AACX;;AAEA;;EAEE;;AAEF;EACE,cAAc;AAChB;;AAEA;;;EAGE;;AAEF;EACE,cAAc;EACd,gBAAgB;AAClB;;AAEA;+EAC+E;;AAE/E;;;EAGE;;AAEF;EACE,uBAAuB,EAAE,MAAM;EAC/B,SAAS,EAAE,MAAM;EACjB,iBAAiB,EAAE,MAAM;AAC3B;;AAEA;;;EAGE;;AAEF;EACE,iCAAiC,EAAE,MAAM;EACzC,cAAc,EAAE,MAAM;AACxB;;AAEA;+EAC+E;;AAE/E;;EAEE;;AAEF;EACE,6BAA6B;AAC/B;;AAEA;;;EAGE;;AAEF;EACE,mBAAmB,EAAE,MAAM;EAC3B,0BAA0B,EAAE,MAAM;EAClC,iCAAiC,EAAE,MAAM;AAC3C;;AAEA;;EAEE;;AAEF;;EAEE,mBAAmB;AACrB;;AAEA;;;EAGE;;AAEF;;;EAGE,iCAAiC,EAAE,MAAM;EACzC,cAAc,EAAE,MAAM;AACxB;;AAEA;;EAEE;;AAEF;EACE,cAAc;AAChB;;AAEA;;;EAGE;;AAEF;;EAEE,cAAc;EACd,cAAc;EACd,kBAAkB;EAClB,wBAAwB;AAC1B;;AAEA;EACE,eAAe;AACjB;;AAEA;EACE,WAAW;AACb;;AAEA;+EAC+E;;AAE/E;;EAEE;;AAEF;EACE,kBAAkB;AACpB;;AAEA;+EAC+E;;AAE/E;;;EAGE;;AAEF;;;;;EAKE,oBAAoB,EAAE,MAAM;EAC5B,eAAe,EAAE,MAAM;EACvB,iBAAiB,EAAE,MAAM;EACzB,SAAS,EAAE,MAAM;AACnB;;AAEA;;;EAGE;;AAEF;QACQ,MAAM;EACZ,iBAAiB;AACnB;;AAEA;;;EAGE;;AAEF;SACS,MAAM;EACb,oBAAoB;AACtB;;AAEA;;EAEE;;AAEF;;;;EAIE,0BAA0B;AAC5B;;AAEA;;EAEE;;AAEF;;;;EAIE,kBAAkB;EAClB,UAAU;AACZ;;AAEA;;EAEE;;AAEF;;;;EAIE,8BAA8B;AAChC;;AAEA;;EAEE;;AAEF;EACE,8BAA8B;AAChC;;AAEA;;;;;EAKE;;AAEF;EACE,sBAAsB,EAAE,MAAM;EAC9B,cAAc,EAAE,MAAM;EACtB,cAAc,EAAE,MAAM;EACtB,eAAe,EAAE,MAAM;EACvB,UAAU,EAAE,MAAM;EAClB,mBAAmB,EAAE,MAAM;AAC7B;;AAEA;;EAEE;;AAEF;EACE,wBAAwB;AAC1B;;AAEA;;EAEE;;AAEF;EACE,cAAc;AAChB;;AAEA;;;EAGE;;AAEF;;EAEE,sBAAsB,EAAE,MAAM;EAC9B,UAAU,EAAE,MAAM;AACpB;;AAEA;;EAEE;;AAEF;;EAEE,YAAY;AACd;;AAEA;;;EAGE;;AAEF;EACE,6BAA6B,EAAE,MAAM;EACrC,oBAAoB,EAAE,MAAM;AAC9B;;AAEA;;EAEE;;AAEF;EACE,wBAAwB;AAC1B;;AAEA;;;EAGE;;AAEF;EACE,0BAA0B,EAAE,MAAM;EAClC,aAAa,EAAE,MAAM;AACvB;;AAEA;+EAC+E;;AAE/E;;EAEE;;AAEF;EACE,cAAc;AAChB;;AAEA;;EAEE;;AAEF;EACE,kBAAkB;AACpB;;AAEA;+EAC+E;;AAE/E;;EAEE;;AAEF;EACE,aAAa;AACf;;AAEA;;EAEE;;AAEF;EACE,aAAa;AACf","sourcesContent":["/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */\\n\\n/* Document\\n ========================================================================== */\\n\\n/**\\n * 1. Correct the line height in all browsers.\\n * 2. Prevent adjustments of font size after orientation changes in iOS.\\n */\\n\\nhtml {\\n line-height: 1.15; /* 1 */\\n -webkit-text-size-adjust: 100%; /* 2 */\\n}\\n\\n/* Sections\\n ========================================================================== */\\n\\n/**\\n * Remove the margin in all browsers.\\n */\\n\\nbody {\\n margin: 0;\\n}\\n\\n/**\\n * Render the `main` element consistently in IE.\\n */\\n\\nmain {\\n display: block;\\n}\\n\\n/**\\n * Correct the font size and margin on `h1` elements within `section` and\\n * `article` contexts in Chrome, Firefox, and Safari.\\n */\\n\\nh1 {\\n font-size: 2em;\\n margin: 0.67em 0;\\n}\\n\\n/* Grouping content\\n ========================================================================== */\\n\\n/**\\n * 1. Add the correct box sizing in Firefox.\\n * 2. Show the overflow in Edge and IE.\\n */\\n\\nhr {\\n box-sizing: content-box; /* 1 */\\n height: 0; /* 1 */\\n overflow: visible; /* 2 */\\n}\\n\\n/**\\n * 1. Correct the inheritance and scaling of font size in all browsers.\\n * 2. Correct the odd `em` font sizing in all browsers.\\n */\\n\\npre {\\n font-family: monospace, monospace; /* 1 */\\n font-size: 1em; /* 2 */\\n}\\n\\n/* Text-level semantics\\n ========================================================================== */\\n\\n/**\\n * Remove the gray background on active links in IE 10.\\n */\\n\\na {\\n background-color: transparent;\\n}\\n\\n/**\\n * 1. Remove the bottom border in Chrome 57-\\n * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\\n */\\n\\nabbr[title] {\\n border-bottom: none; /* 1 */\\n text-decoration: underline; /* 2 */\\n text-decoration: underline dotted; /* 2 */\\n}\\n\\n/**\\n * Add the correct font weight in Chrome, Edge, and Safari.\\n */\\n\\nb,\\nstrong {\\n font-weight: bolder;\\n}\\n\\n/**\\n * 1. Correct the inheritance and scaling of font size in all browsers.\\n * 2. Correct the odd `em` font sizing in all browsers.\\n */\\n\\ncode,\\nkbd,\\nsamp {\\n font-family: monospace, monospace; /* 1 */\\n font-size: 1em; /* 2 */\\n}\\n\\n/**\\n * Add the correct font size in all browsers.\\n */\\n\\nsmall {\\n font-size: 80%;\\n}\\n\\n/**\\n * Prevent `sub` and `sup` elements from affecting the line height in\\n * all browsers.\\n */\\n\\nsub,\\nsup {\\n font-size: 75%;\\n line-height: 0;\\n position: relative;\\n vertical-align: baseline;\\n}\\n\\nsub {\\n bottom: -0.25em;\\n}\\n\\nsup {\\n top: -0.5em;\\n}\\n\\n/* Embedded content\\n ========================================================================== */\\n\\n/**\\n * Remove the border on images inside links in IE 10.\\n */\\n\\nimg {\\n border-style: none;\\n}\\n\\n/* Forms\\n ========================================================================== */\\n\\n/**\\n * 1. Change the font styles in all browsers.\\n * 2. Remove the margin in Firefox and Safari.\\n */\\n\\nbutton,\\ninput,\\noptgroup,\\nselect,\\ntextarea {\\n font-family: inherit; /* 1 */\\n font-size: 100%; /* 1 */\\n line-height: 1.15; /* 1 */\\n margin: 0; /* 2 */\\n}\\n\\n/**\\n * Show the overflow in IE.\\n * 1. Show the overflow in Edge.\\n */\\n\\nbutton,\\ninput { /* 1 */\\n overflow: visible;\\n}\\n\\n/**\\n * Remove the inheritance of text transform in Edge, Firefox, and IE.\\n * 1. Remove the inheritance of text transform in Firefox.\\n */\\n\\nbutton,\\nselect { /* 1 */\\n text-transform: none;\\n}\\n\\n/**\\n * Correct the inability to style clickable types in iOS and Safari.\\n */\\n\\nbutton,\\n[type=\\"button\\"],\\n[type=\\"reset\\"],\\n[type=\\"submit\\"] {\\n -webkit-appearance: button;\\n}\\n\\n/**\\n * Remove the inner border and padding in Firefox.\\n */\\n\\nbutton::-moz-focus-inner,\\n[type=\\"button\\"]::-moz-focus-inner,\\n[type=\\"reset\\"]::-moz-focus-inner,\\n[type=\\"submit\\"]::-moz-focus-inner {\\n border-style: none;\\n padding: 0;\\n}\\n\\n/**\\n * Restore the focus styles unset by the previous rule.\\n */\\n\\nbutton:-moz-focusring,\\n[type=\\"button\\"]:-moz-focusring,\\n[type=\\"reset\\"]:-moz-focusring,\\n[type=\\"submit\\"]:-moz-focusring {\\n outline: 1px dotted ButtonText;\\n}\\n\\n/**\\n * Correct the padding in Firefox.\\n */\\n\\nfieldset {\\n padding: 0.35em 0.75em 0.625em;\\n}\\n\\n/**\\n * 1. Correct the text wrapping in Edge and IE.\\n * 2. Correct the color inheritance from `fieldset` elements in IE.\\n * 3. Remove the padding so developers are not caught out when they zero out\\n * `fieldset` elements in all browsers.\\n */\\n\\nlegend {\\n box-sizing: border-box; /* 1 */\\n color: inherit; /* 2 */\\n display: table; /* 1 */\\n max-width: 100%; /* 1 */\\n padding: 0; /* 3 */\\n white-space: normal; /* 1 */\\n}\\n\\n/**\\n * Add the correct vertical alignment in Chrome, Firefox, and Opera.\\n */\\n\\nprogress {\\n vertical-align: baseline;\\n}\\n\\n/**\\n * Remove the default vertical scrollbar in IE 10+.\\n */\\n\\ntextarea {\\n overflow: auto;\\n}\\n\\n/**\\n * 1. Add the correct box sizing in IE 10.\\n * 2. Remove the padding in IE 10.\\n */\\n\\n[type=\\"checkbox\\"],\\n[type=\\"radio\\"] {\\n box-sizing: border-box; /* 1 */\\n padding: 0; /* 2 */\\n}\\n\\n/**\\n * Correct the cursor style of increment and decrement buttons in Chrome.\\n */\\n\\n[type=\\"number\\"]::-webkit-inner-spin-button,\\n[type=\\"number\\"]::-webkit-outer-spin-button {\\n height: auto;\\n}\\n\\n/**\\n * 1. Correct the odd appearance in Chrome and Safari.\\n * 2. Correct the outline style in Safari.\\n */\\n\\n[type=\\"search\\"] {\\n -webkit-appearance: textfield; /* 1 */\\n outline-offset: -2px; /* 2 */\\n}\\n\\n/**\\n * Remove the inner padding in Chrome and Safari on macOS.\\n */\\n\\n[type=\\"search\\"]::-webkit-search-decoration {\\n -webkit-appearance: none;\\n}\\n\\n/**\\n * 1. Correct the inability to style clickable types in iOS and Safari.\\n * 2. Change font properties to `inherit` in Safari.\\n */\\n\\n::-webkit-file-upload-button {\\n -webkit-appearance: button; /* 1 */\\n font: inherit; /* 2 */\\n}\\n\\n/* Interactive\\n ========================================================================== */\\n\\n/*\\n * Add the correct display in Edge, IE 10+, and Firefox.\\n */\\n\\ndetails {\\n display: block;\\n}\\n\\n/*\\n * Add the correct display in all browsers.\\n */\\n\\nsummary {\\n display: list-item;\\n}\\n\\n/* Misc\\n ========================================================================== */\\n\\n/**\\n * Add the correct display in IE 10+.\\n */\\n\\ntemplate {\\n display: none;\\n}\\n\\n/**\\n * Add the correct display in IE 10.\\n */\\n\\n[hidden] {\\n display: none;\\n}\\n"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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LFFBQVEsTUFBTSxLQUFLLHNCQUFzQix1QkFBdUIsT0FBTyxLQUFLLFFBQVEsT0FBTyxNQUFNLEtBQUssVUFBVSxNQUFNLE1BQU0sTUFBTSxLQUFLLFVBQVUsT0FBTyxPQUFPLE1BQU0sS0FBSyxVQUFVLFlBQVksT0FBTyxLQUFLLFFBQVEsUUFBUSxNQUFNLEtBQUssc0JBQXNCLHFCQUFxQix1QkFBdUIsT0FBTyxPQUFPLE1BQU0sS0FBSyxzQkFBc0IscUJBQXFCLE9BQU8sS0FBSyxRQUFRLE9BQU8sTUFBTSxLQUFLLFlBQVksT0FBTyxPQUFPLE1BQU0sS0FBSyxzQkFBc0IsdUJBQXVCLHVCQUF1QixPQUFPLE1BQU0sTUFBTSxNQUFNLFlBQVksT0FBTyxPQUFPLE1BQU0sT0FBTyxzQkFBc0IscUJBQXFCLE9BQU8sTUFBTSxNQUFNLEtBQUssVUFBVSxPQUFPLE9BQU8sTUFBTSxNQUFNLFVBQVUsVUFBVSxZQUFZLGFBQWEsT0FBTyxLQUFLLFVBQVUsT0FBTyxLQUFLLFVBQVUsTUFBTSxLQUFLLFFBQVEsT0FBTyxNQUFNLEtBQUssWUFBWSxPQUFPLEtBQUssUUFBUSxRQUFRLE1BQU0sU0FBUyxzQkFBc0IscUJBQXFCLHVCQUF1QixxQkFBcUIsT0FBTyxPQUFPLE1BQU0sS0FBSyxVQUFVLFlBQVksT0FBTyxPQUFPLE1BQU0sS0FBSyxVQUFVLFlBQVksT0FBTyxNQUFNLE1BQU0sUUFBUSxZQUFZLE9BQU8sTUFBTSxNQUFNLFFBQVEsWUFBWSxXQUFXLE1BQU0sTUFBTSxNQUFNLFFBQVEsWUFBWSxPQUFPLE1BQU0sTUFBTSxLQUFLLFlBQVksT0FBTyxTQUFTLE1BQU0sS0FBSyxzQkFBc0IscUJBQXFCLHFCQUFxQixxQkFBcUIscUJBQXFCLHVCQUF1QixPQUFPLE1BQU0sTUFBTSxLQUFLLFlBQVksT0FBTyxNQUFNLE1BQU0sS0FBSyxVQUFVLE9BQU8sT0FBTyxNQUFNLE1BQU0sc0JBQXNCLHFCQUFxQixPQUFPLE1BQU0sTUFBTSxNQUFNLFVBQVUsTUFBTSxPQUFPLE1BQU0sS0FBSyxzQkFBc0IsdUJBQXVCLE9BQU8sTUFBTSxNQUFNLEtBQUssWUFBWSxPQUFPLE9BQU8sTUFBTSxLQUFLLHNCQUFzQixxQkFBcUIsT0FBTyxLQUFLLFFBQVEsT0FBTyxNQUFNLEtBQUssVUFBVSxPQUFPLE1BQU0sTUFBTSxLQUFLLFlBQVksT0FBTyxLQUFLLFFBQVEsT0FBTyxNQUFNLEtBQUssVUFBVSxNQUFNLE1BQU0sTUFBTSxLQUFLLFVBQVUsc1ZBQXNWLHVCQUF1QiwyQ0FBMkMsVUFBVSw4SkFBOEosY0FBYyxHQUFHLHdFQUF3RSxtQkFBbUIsR0FBRyxzSkFBc0osbUJBQW1CLHFCQUFxQixHQUFHLG9OQUFvTiw2QkFBNkIsc0JBQXNCLDhCQUE4QixVQUFVLHVKQUF1Six1Q0FBdUMsMkJBQTJCLFVBQVUseUxBQXlMLGtDQUFrQyxHQUFHLDBKQUEwSix5QkFBeUIsdUNBQXVDLDhDQUE4QyxVQUFVLHlGQUF5Rix3QkFBd0IsR0FBRyxxS0FBcUssdUNBQXVDLDJCQUEyQixVQUFVLHNFQUFzRSxtQkFBbUIsR0FBRyxvSEFBb0gsbUJBQW1CLG1CQUFtQix1QkFBdUIsNkJBQTZCLEdBQUcsU0FBUyxvQkFBb0IsR0FBRyxTQUFTLGdCQUFnQixHQUFHLHFMQUFxTCx1QkFBdUIsR0FBRyw0UEFBNFAsMEJBQTBCLDRCQUE0Qiw4QkFBOEIsc0JBQXNCLFVBQVUsZ0dBQWdHLDZCQUE2QixHQUFHLHFLQUFxSyxnQ0FBZ0MsR0FBRyx5SkFBeUosK0JBQStCLEdBQUcsK01BQStNLHVCQUF1QixlQUFlLEdBQUcsd01BQXdNLG1DQUFtQyxHQUFHLDhEQUE4RCxtQ0FBbUMsR0FBRyx3UUFBd1EsNEJBQTRCLDJCQUEyQiwyQkFBMkIsNEJBQTRCLHVCQUF1QixnQ0FBZ0MsVUFBVSxnR0FBZ0csNkJBQTZCLEdBQUcsK0VBQStFLG1CQUFtQixHQUFHLHdJQUF3SSw0QkFBNEIsdUJBQXVCLFVBQVUsd0xBQXdMLGlCQUFpQixHQUFHLHVJQUF1SSxtQ0FBbUMsaUNBQWlDLFVBQVUsMEhBQTBILDZCQUE2QixHQUFHLDZLQUE2SyxnQ0FBZ0MsMEJBQTBCLFVBQVUsc0xBQXNMLG1CQUFtQixHQUFHLHFFQUFxRSx1QkFBdUIsR0FBRyw4SkFBOEosa0JBQWtCLEdBQUcsZ0VBQWdFLGtCQUFrQixHQUFHLHFCQUFxQjtBQUM5MVE7QUFDQSxpRUFBZSx1QkFBdUIsRUFBQyIsInNvdXJjZXMiOlsid2VicGFjazovL2NvbnRyb2Nvcm8tbGFuZGluZy1wYWdlLy4vc3JjL25vcm1hbGl6ZS5jc3M/NjExNCJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBJbXBvcnRzXG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyBmcm9tIFwiLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL3NvdXJjZU1hcHMuanNcIjtcbmltcG9ydCBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18gZnJvbSBcIi4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9hcGkuanNcIjtcbnZhciBfX19DU1NfTE9BREVSX0VYUE9SVF9fXyA9IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyhfX19DU1NfTE9BREVSX0FQSV9TT1VSQ0VNQVBfSU1QT1JUX19fKTtcbi8vIE1vZHVsZVxuX19fQ1NTX0xPQURFUl9FWFBPUlRfX18ucHVzaChbbW9kdWxlLmlkLCBgLyohIG5vcm1hbGl6ZS5jc3MgdjguMC4xIHwgTUlUIExpY2Vuc2UgfCBnaXRodWIuY29tL25lY29sYXMvbm9ybWFsaXplLmNzcyAqL1xuXG4vKiBEb2N1bWVudFxuICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuLyoqXG4gKiAxLiBDb3JyZWN0IHRoZSBsaW5lIGhlaWdodCBpbiBhbGwgYnJvd3NlcnMuXG4gKiAyLiBQcmV2ZW50IGFkanVzdG1lbnRzIG9mIGZvbnQgc2l6ZSBhZnRlciBvcmllbnRhdGlvbiBjaGFuZ2VzIGluIGlPUy5cbiAqL1xuXG5odG1sIHtcbiAgbGluZS1oZWlnaHQ6IDEuMTU7IC8qIDEgKi9cbiAgLXdlYmtpdC10ZXh0LXNpemUtYWRqdXN0OiAxMDAlOyAvKiAyICovXG59XG5cbi8qIFNlY3Rpb25zXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4vKipcbiAqIFJlbW92ZSB0aGUgbWFyZ2luIGluIGFsbCBicm93c2Vycy5cbiAqL1xuXG5ib2R5IHtcbiAgbWFyZ2luOiAwO1xufVxuXG4vKipcbiAqIFJlbmRlciB0aGUgXFxgbWFpblxcYCBlbGVtZW50IGNvbnNpc3RlbnRseSBpbiBJRS5cbiAqL1xuXG5tYWluIHtcbiAgZGlzcGxheTogYmxvY2s7XG59XG5cbi8qKlxuICogQ29ycmVjdCB0aGUgZm9udCBzaXplIGFuZCBtYXJnaW4gb24gXFxgaDFcXGAgZWxlbWVudHMgd2l0aGluIFxcYHNlY3Rpb25cXGAgYW5kXG4gKiBcXGBhcnRpY2xlXFxgIGNvbnRleHRzIGluIENocm9tZSwgRmlyZWZveCwgYW5kIFNhZmFyaS5cbiAqL1xuXG5oMSB7XG4gIGZvbnQtc2l6ZTogMmVtO1xuICBtYXJnaW46IDAuNjdlbSAwO1xufVxuXG4vKiBHcm91cGluZyBjb250ZW50XG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4vKipcbiAqIDEuIEFkZCB0aGUgY29ycmVjdCBib3ggc2l6aW5nIGluIEZpcmVmb3guXG4gKiAyLiBTaG93IHRoZSBvdmVyZmxvdyBpbiBFZGdlIGFuZCBJRS5cbiAqL1xuXG5ociB7XG4gIGJveC1zaXppbmc6IGNvbnRlbnQtYm94OyAvKiAxICovXG4gIGhlaWdodDogMDsgLyogMSAqL1xuICBvdmVyZmxvdzogdmlzaWJsZTsgLyogMiAqL1xufVxuXG4vKipcbiAqIDEuIENvcnJlY3QgdGhlIGluaGVyaXRhbmNlIGFuZCBzY2FsaW5nIG9mIGZvbnQgc2l6ZSBpbiBhbGwgYnJvd3NlcnMuXG4gKiAyLiBDb3JyZWN0IHRoZSBvZGQgXFxgZW1cXGAgZm9udCBzaXppbmcgaW4gYWxsIGJyb3dzZXJzLlxuICovXG5cbnByZSB7XG4gIGZvbnQtZmFtaWx5OiBtb25vc3BhY2UsIG1vbm9zcGFjZTsgLyogMSAqL1xuICBmb250LXNpemU6IDFlbTsgLyogMiAqL1xufVxuXG4vKiBUZXh0LWxldmVsIHNlbWFudGljc1xuICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuLyoqXG4gKiBSZW1vdmUgdGhlIGdyYXkgYmFja2dyb3VuZCBvbiBhY3RpdmUgbGlua3MgaW4gSUUgMTAuXG4gKi9cblxuYSB7XG4gIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50O1xufVxuXG4vKipcbiAqIDEuIFJlbW92ZSB0aGUgYm90dG9tIGJvcmRlciBpbiBDaHJvbWUgNTctXG4gKiAyLiBBZGQgdGhlIGNvcnJlY3QgdGV4dCBkZWNvcmF0aW9uIGluIENocm9tZSwgRWRnZSwgSUUsIE9wZXJhLCBhbmQgU2FmYXJpLlxuICovXG5cbmFiYnJbdGl0bGVdIHtcbiAgYm9yZGVyLWJvdHRvbTogbm9uZTsgLyogMSAqL1xuICB0ZXh0LWRlY29yYXRpb246IHVuZGVybGluZTsgLyogMiAqL1xuICB0ZXh0LWRlY29yYXRpb246IHVuZGVybGluZSBkb3R0ZWQ7IC8qIDIgKi9cbn1cblxuLyoqXG4gKiBBZGQgdGhlIGNvcnJlY3QgZm9udCB3ZWlnaHQgaW4gQ2hyb21lLCBFZGdlLCBhbmQgU2FmYXJpLlxuICovXG5cbmIsXG5zdHJvbmcge1xuICBmb250LXdlaWdodDogYm9sZGVyO1xufVxuXG4vKipcbiAqIDEuIENvcnJlY3QgdGhlIGluaGVyaXRhbmNlIGFuZCBzY2FsaW5nIG9mIGZvbnQgc2l6ZSBpbiBhbGwgYnJvd3NlcnMuXG4gKiAyLiBDb3JyZWN0IHRoZSBvZGQgXFxgZW1cXGAgZm9udCBzaXppbmcgaW4gYWxsIGJyb3dzZXJzLlxuICovXG5cbmNvZGUsXG5rYmQsXG5zYW1wIHtcbiAgZm9udC1mYW1pbHk6IG1vbm9zcGFjZSwgbW9ub3NwYWNlOyAvKiAxICovXG4gIGZvbnQtc2l6ZTogMWVtOyAvKiAyICovXG59XG5cbi8qKlxuICogQWRkIHRoZSBjb3JyZWN0IGZvbnQgc2l6ZSBpbiBhbGwgYnJvd3NlcnMuXG4gKi9cblxuc21hbGwge1xuICBmb250LXNpemU6IDgwJTtcbn1cblxuLyoqXG4gKiBQcmV2ZW50IFxcYHN1YlxcYCBhbmQgXFxgc3VwXFxgIGVsZW1lbnRzIGZyb20gYWZmZWN0aW5nIHRoZSBsaW5lIGhlaWdodCBpblxuICogYWxsIGJyb3dzZXJzLlxuICovXG5cbnN1YixcbnN1cCB7XG4gIGZvbnQtc2l6ZTogNzUlO1xuICBsaW5lLWhlaWdodDogMDtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICB2ZXJ0aWNhbC1hbGlnbjogYmFzZWxpbmU7XG59XG5cbnN1YiB7XG4gIGJvdHRvbTogLTAuMjVlbTtcbn1cblxuc3VwIHtcbiAgdG9wOiAtMC41ZW07XG59XG5cbi8qIEVtYmVkZGVkIGNvbnRlbnRcbiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG5cbi8qKlxuICogUmVtb3ZlIHRoZSBib3JkZXIgb24gaW1hZ2VzIGluc2lkZSBsaW5rcyBpbiBJRSAxMC5cbiAqL1xuXG5pbWcge1xuICBib3JkZXItc3R5bGU6IG5vbmU7XG59XG5cbi8qIEZvcm1zXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4vKipcbiAqIDEuIENoYW5nZSB0aGUgZm9udCBzdHlsZXMgaW4gYWxsIGJyb3dzZXJzLlxuICogMi4gUmVtb3ZlIHRoZSBtYXJnaW4gaW4gRmlyZWZveCBhbmQgU2FmYXJpLlxuICovXG5cbmJ1dHRvbixcbmlucHV0LFxub3B0Z3JvdXAsXG5zZWxlY3QsXG50ZXh0YXJlYSB7XG4gIGZvbnQtZmFtaWx5OiBpbmhlcml0OyAvKiAxICovXG4gIGZvbnQtc2l6ZTogMTAwJTsgLyogMSAqL1xuICBsaW5lLWhlaWdodDogMS4xNTsgLyogMSAqL1xuICBtYXJnaW46IDA7IC8qIDIgKi9cbn1cblxuLyoqXG4gKiBTaG93IHRoZSBvdmVyZmxvdyBpbiBJRS5cbiAqIDEuIFNob3cgdGhlIG92ZXJmbG93IGluIEVkZ2UuXG4gKi9cblxuYnV0dG9uLFxuaW5wdXQgeyAvKiAxICovXG4gIG92ZXJmbG93OiB2aXNpYmxlO1xufVxuXG4vKipcbiAqIFJlbW92ZSB0aGUgaW5oZXJpdGFuY2Ugb2YgdGV4dCB0cmFuc2Zvcm0gaW4gRWRnZSwgRmlyZWZveCwgYW5kIElFLlxuICogMS4gUmVtb3ZlIHRoZSBpbmhlcml0YW5jZSBvZiB0ZXh0IHRyYW5zZm9ybSBpbiBGaXJlZm94LlxuICovXG5cbmJ1dHRvbixcbnNlbGVjdCB7IC8qIDEgKi9cbiAgdGV4dC10cmFuc2Zvcm06IG5vbmU7XG59XG5cbi8qKlxuICogQ29ycmVjdCB0aGUgaW5hYmlsaXR5IHRvIHN0eWxlIGNsaWNrYWJsZSB0eXBlcyBpbiBpT1MgYW5kIFNhZmFyaS5cbiAqL1xuXG5idXR0b24sXG5bdHlwZT1cImJ1dHRvblwiXSxcblt0eXBlPVwicmVzZXRcIl0sXG5bdHlwZT1cInN1Ym1pdFwiXSB7XG4gIC13ZWJraXQtYXBwZWFyYW5jZTogYnV0dG9uO1xufVxuXG4vKipcbiAqIFJlbW92ZSB0aGUgaW5uZXIgYm9yZGVyIGFuZCBwYWRkaW5nIGluIEZpcmVmb3guXG4gKi9cblxuYnV0dG9uOjotbW96LWZvY3VzLWlubmVyLFxuW3R5cGU9XCJidXR0b25cIl06Oi1tb3otZm9jdXMtaW5uZXIsXG5bdHlwZT1cInJlc2V0XCJdOjotbW96LWZvY3VzLWlubmVyLFxuW3R5cGU9XCJzdWJtaXRcIl06Oi1tb3otZm9jdXMtaW5uZXIge1xuICBib3JkZXItc3R5bGU6IG5vbmU7XG4gIHBhZGRpbmc6IDA7XG59XG5cbi8qKlxuICogUmVzdG9yZSB0aGUgZm9jdXMgc3R5bGVzIHVuc2V0IGJ5IHRoZSBwcmV2aW91cyBydWxlLlxuICovXG5cbmJ1dHRvbjotbW96LWZvY3VzcmluZyxcblt0eXBlPVwiYnV0dG9uXCJdOi1tb3otZm9jdXNyaW5nLFxuW3R5cGU9XCJyZXNldFwiXTotbW96LWZvY3VzcmluZyxcblt0eXBlPVwic3VibWl0XCJdOi1tb3otZm9jdXNyaW5nIHtcbiAgb3V0bGluZTogMXB4IGRvdHRlZCBCdXR0b25UZXh0O1xufVxuXG4vKipcbiAqIENvcnJlY3QgdGhlIHBhZGRpbmcgaW4gRmlyZWZveC5cbiAqL1xuXG5maWVsZHNldCB7XG4gIHBhZGRpbmc6IDAuMzVlbSAwLjc1ZW0gMC42MjVlbTtcbn1cblxuLyoqXG4gKiAxLiBDb3JyZWN0IHRoZSB0ZXh0IHdyYXBwaW5nIGluIEVkZ2UgYW5kIElFLlxuICogMi4gQ29ycmVjdCB0aGUgY29sb3IgaW5oZXJpdGFuY2UgZnJvbSBcXGBmaWVsZHNldFxcYCBlbGVtZW50cyBpbiBJRS5cbiAqIDMuIFJlbW92ZSB0aGUgcGFkZGluZyBzbyBkZXZlbG9wZXJzIGFyZSBub3QgY2F1Z2h0IG91dCB3aGVuIHRoZXkgemVybyBvdXRcbiAqICAgIFxcYGZpZWxkc2V0XFxgIGVsZW1lbnRzIGluIGFsbCBicm93c2Vycy5cbiAqL1xuXG5sZWdlbmQge1xuICBib3gtc2l6aW5nOiBib3JkZXItYm94OyAvKiAxICovXG4gIGNvbG9yOiBpbmhlcml0OyAvKiAyICovXG4gIGRpc3BsYXk6IHRhYmxlOyAvKiAxICovXG4gIG1heC13aWR0aDogMTAwJTsgLyogMSAqL1xuICBwYWRkaW5nOiAwOyAvKiAzICovXG4gIHdoaXRlLXNwYWNlOiBub3JtYWw7IC8qIDEgKi9cbn1cblxuLyoqXG4gKiBBZGQgdGhlIGNvcnJlY3QgdmVydGljYWwgYWxpZ25tZW50IGluIENocm9tZSwgRmlyZWZveCwgYW5kIE9wZXJhLlxuICovXG5cbnByb2dyZXNzIHtcbiAgdmVydGljYWwtYWxpZ246IGJhc2VsaW5lO1xufVxuXG4vKipcbiAqIFJlbW92ZSB0aGUgZGVmYXVsdCB2ZXJ0aWNhbCBzY3JvbGxiYXIgaW4gSUUgMTArLlxuICovXG5cbnRleHRhcmVhIHtcbiAgb3ZlcmZsb3c6IGF1dG87XG59XG5cbi8qKlxuICogMS4gQWRkIHRoZSBjb3JyZWN0IGJveCBzaXppbmcgaW4gSUUgMTAuXG4gKiAyLiBSZW1vdmUgdGhlIHBhZGRpbmcgaW4gSUUgMTAuXG4gKi9cblxuW3R5cGU9XCJjaGVja2JveFwiXSxcblt0eXBlPVwicmFkaW9cIl0ge1xuICBib3gtc2l6aW5nOiBib3JkZXItYm94OyAvKiAxICovXG4gIHBhZGRpbmc6IDA7IC8qIDIgKi9cbn1cblxuLyoqXG4gKiBDb3JyZWN0IHRoZSBjdXJzb3Igc3R5bGUgb2YgaW5jcmVtZW50IGFuZCBkZWNyZW1lbnQgYnV0dG9ucyBpbiBDaHJvbWUuXG4gKi9cblxuW3R5cGU9XCJudW1iZXJcIl06Oi13ZWJraXQtaW5uZXItc3Bpbi1idXR0b24sXG5bdHlwZT1cIm51bWJlclwiXTo6LXdlYmtpdC1vdXRlci1zcGluLWJ1dHRvbiB7XG4gIGhlaWdodDogYXV0bztcbn1cblxuLyoqXG4gKiAxLiBDb3JyZWN0IHRoZSBvZGQgYXBwZWFyYW5jZSBpbiBDaHJvbWUgYW5kIFNhZmFyaS5cbiAqIDIuIENvcnJlY3QgdGhlIG91dGxpbmUgc3R5bGUgaW4gU2FmYXJpLlxuICovXG5cblt0eXBlPVwic2VhcmNoXCJdIHtcbiAgLXdlYmtpdC1hcHBlYXJhbmNlOiB0ZXh0ZmllbGQ7IC8qIDEgKi9cbiAgb3V0bGluZS1vZmZzZXQ6IC0ycHg7IC8qIDIgKi9cbn1cblxuLyoqXG4gKiBSZW1vdmUgdGhlIGlubmVyIHBhZGRpbmcgaW4gQ2hyb21lIGFuZCBTYWZhcmkgb24gbWFjT1MuXG4gKi9cblxuW3R5cGU9XCJzZWFyY2hcIl06Oi13ZWJraXQtc2VhcmNoLWRlY29yYXRpb24ge1xuICAtd2Via2l0LWFwcGVhcmFuY2U6IG5vbmU7XG59XG5cbi8qKlxuICogMS4gQ29ycmVjdCB0aGUgaW5hYmlsaXR5IHRvIHN0eWxlIGNsaWNrYWJsZSB0eXBlcyBpbiBpT1MgYW5kIFNhZmFyaS5cbiAqIDIuIENoYW5nZSBmb250IHByb3BlcnRpZXMgdG8gXFxgaW5oZXJpdFxcYCBpbiBTYWZhcmkuXG4gKi9cblxuOjotd2Via2l0LWZpbGUtdXBsb2FkLWJ1dHRvbiB7XG4gIC13ZWJraXQtYXBwZWFyYW5jZTogYnV0dG9uOyAvKiAxICovXG4gIGZvbnQ6IGluaGVyaXQ7IC8qIDIgKi9cbn1cblxuLyogSW50ZXJhY3RpdmVcbiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG5cbi8qXG4gKiBBZGQgdGhlIGNvcnJlY3QgZGlzcGxheSBpbiBFZGdlLCBJRSAxMCssIGFuZCBGaXJlZm94LlxuICovXG5cbmRldGFpbHMge1xuICBkaXNwbGF5OiBibG9jaztcbn1cblxuLypcbiAqIEFkZCB0aGUgY29ycmVjdCBkaXNwbGF5IGluIGFsbCBicm93c2Vycy5cbiAqL1xuXG5zdW1tYXJ5IHtcbiAgZGlzcGxheTogbGlzdC1pdGVtO1xufVxuXG4vKiBNaXNjXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4vKipcbiAqIEFkZCB0aGUgY29ycmVjdCBkaXNwbGF5IGluIElFIDEwKy5cbiAqL1xuXG50ZW1wbGF0ZSB7XG4gIGRpc3BsYXk6IG5vbmU7XG59XG5cbi8qKlxuICogQWRkIHRoZSBjb3JyZWN0IGRpc3BsYXkgaW4gSUUgMTAuXG4gKi9cblxuW2hpZGRlbl0ge1xuICBkaXNwbGF5OiBub25lO1xufVxuYCwgXCJcIix7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCJ3ZWJwYWNrOi8vLi9zcmMvbm9ybWFsaXplLmNz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O0VBQ0UsY0FBYztBQUNoQjs7QUFFQTs7RUFFRTs7QUFFRjtFQUNFLGtCQUFrQjtBQUNwQjs7QUFFQTsrRUFDK0U7O0FBRS9FOztFQUVFOztBQUVGO0VBQ0UsYUFBYTtBQUNmOztBQUVBOztFQUVFOztBQUVGO0VBQ0UsYUFBYTtBQUNmXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIi8qISBub3JtYWxpemUuY3NzIHY4LjAuMSB8IE1JVCBMaWNlbnNlIHwgZ2l0aHViLmNvbS9uZWNvbGFzL25vcm1hbGl6ZS5jc3MgKi9cXG5cXG4vKiBEb2N1bWVudFxcbiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXFxuXFxuLyoqXFxuICogMS4gQ29ycmVjdCB0aGUgbGluZSBoZWlnaHQgaW4gYWxsIGJyb3dzZXJzLlxcbiAqIDIuIFByZXZlbnQgYWRqdXN0bWVudHMgb2YgZm9udCBzaXplIGFmdGVyIG9yaWVudGF0aW9uIGNoYW5nZXMgaW4gaU9TLlxcbiAqL1xcblxcbmh0bWwge1xcbiAgbGluZS1oZWlnaHQ6IDEuMTU7IC8qIDEgKi9cXG4gIC13ZWJraXQtdGV4dC1zaXplLWFkanVzdDogMTAwJTsgLyogMiAqL1xcbn1cXG5cXG4vKiBTZWN0aW9uc1xcbiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXFxuXFxuLyoqXFxuICogUmVtb3ZlIHRoZSBtYXJnaW4gaW4gYWxsIGJyb3dzZXJzLlxcbiAqL1xcblxcbmJvZHkge1xcbiAgbWFyZ2luOiAwO1xcbn1cXG5cXG4vKipcXG4gKiBSZW5kZXIgdGhlIGBtYWluYCBlbGVtZW50IGNvbnNpc3RlbnRseSBpbiBJRS5cXG4gKi9cXG5cXG5tYWluIHtcXG4gIGRpc3BsYXk6IGJsb2NrO1xcbn1cXG5cXG4vKipcXG4gKiBDb3JyZWN0IHRoZSBmb250IHNpemUgYW5kIG1hcmdpbiBvbiBgaDFgIGVsZW1lbnRzIHdpdGhpbiBgc2VjdGlvbmAgYW5kXFxuICogYGFydGljbGVgIGNvbnRleHRzIGluIENocm9tZSwgRmlyZWZveCwgYW5kIFNhZmFyaS5cXG4gKi9cXG5cXG5oMSB7XFxuICBmb250LXNpemU6IDJlbTtcXG4gIG1hcmdpbjogMC42N2VtIDA7XFxufVxcblxcbi8qIEdyb3VwaW5nIGNvbnRlbnRcXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xcblxcbi8qKlxcbiAqIDEuIEFkZCB0aGUgY29ycmVjdCBib3ggc2l6aW5nIGluIEZpcmVmb3guXFxuICogMi4gU2hvdyB0aGUgb3ZlcmZsb3cgaW4gRWRnZSBhbmQgSUUuXFxuICovXFxuXFxuaHIge1xcbiAgYm94LXNpemluZzogY29udGVudC1ib3g7IC8qIDEgKi9cXG4gIGhlaWdodDogMDsgLyogMSAqL1xcbiAgb3ZlcmZsb3c6IHZpc2libGU7IC8qIDIgKi9cXG59XFxuXFxuLyoqXFxuICogMS4gQ29ycmVjdCB0aGUgaW5oZXJpdGFuY2UgYW5kIHNjYWxpbmcgb2YgZm9udCBzaXplIGluIGFsbCBicm93c2Vycy5cXG4gKiAyLiBDb3JyZWN0IHRoZSBvZGQgYGVtYCBmb250IHNpemluZyBpbiBhbGwgYnJvd3NlcnMuXFxuICovXFxuXFxucHJlIHtcXG4gIGZvbnQtZmFtaWx5OiBtb25vc3BhY2UsIG1vbm9zcGFjZTsgLyogMSAqL1xcbiAgZm9udC1zaXplOiAxZW07IC8qIDIgKi9cXG59XFxuXFxuLyogVGV4dC1sZXZlbCBzZW1hbnRpY3NcXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xcblxcbi8qKlxcbiAqIFJlbW92ZSB0aGUgZ3JheSBiYWNrZ3JvdW5kIG9uIGFjdGl2ZSBsaW5rcyBpbiBJRSAxMC5cXG4gKi9cXG5cXG5hIHtcXG4gIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50O1xcbn1cXG5cXG4vKipcXG4gKiAxLiBSZW1vdmUgdGhlIGJvdHRvbSBib3JkZXIgaW4gQ2hyb21lIDU3LVxcbiAqIDIuIEFkZCB0aGUgY29ycmVjdCB0ZXh0IGRlY29yYXRpb24gaW4gQ2hyb21lLCBFZGdlLCBJRSwgT3BlcmEsIGFuZCBTYWZhcmkuXFxuICovXFxuXFxuYWJiclt0aXRsZV0ge1xcbiAgYm9yZGVyLWJvdHRvbTogbm9uZTsgLyogMSAqL1xcbiAgdGV4dC1kZWNvcmF0aW9uOiB1bmRlcmxpbmU7IC8qIDIgKi9cXG4gIHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lIGRvdHRlZDsgLyogMiAqL1xcbn1cXG5cXG4vKipcXG4gKiBBZGQgdGhlIGNvcnJlY3QgZm9udCB3ZWlnaHQgaW4gQ2hyb21lLCBFZGdlLCBhbmQgU2FmYXJpLlxcbiAqL1xcblxcbmIsXFxuc3Ryb25nIHtcXG4gIGZvbnQtd2VpZ2h0OiBib2xkZXI7XFxufVxcblxcbi8qKlxcbiAqIDEuIENvcnJlY3QgdGhlIGluaGVyaXRhbmNlIGFuZCBzY2FsaW5nIG9mIGZvbnQgc2l6ZSBpbiBhbGwgYnJvd3NlcnMuXFxuICogMi4gQ29ycmVjdCB0aGUgb2RkIGBlbWAgZm9udCBzaXppbmcgaW4gYWxsIGJyb3dzZXJzLlxcbiAqL1xcblxcbmNvZGUsXFxua2JkLFxcbnNhbXAge1xcbiAgZm9udC1mYW1pbHk6IG1vbm9zcGFjZSwgbW9ub3NwYWNlOyAvKiAxICovXFxuICBmb250LXNpemU6IDFlbTsgLyogMiAqL1xcbn1cXG5cXG4vKipcXG4gKiBBZGQgdGhlIGNvcnJlY3QgZm9udCBzaXplIGluIGFsbCBicm93c2Vycy5cXG4gKi9cXG5cXG5zbWFsbCB7XFxuICBmb250LXNpemU6IDgwJTtcXG59XFxuXFxuLyoqXFxuICogUHJldmVudCBgc3ViYCBhbmQgYHN1cGAgZWxlbWVudHMgZnJvbSBhZmZlY3RpbmcgdGhlIGxpbmUgaGVpZ2h0IGluXFxuICogYWxsIGJyb3dzZXJzLlxcbiAqL1xcblxcbnN1YixcXG5zdXAge1xcbiAgZm9udC1zaXplOiA3NSU7XFxuICBsaW5lLWhlaWdodDogMDtcXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcXG4gIHZlcnRpY2FsLWFsaWduOiBiYXNlbGluZTtcXG59XFxuXFxuc3ViIHtcXG4gIGJvdHRvbTogLTAuMjVlbTtcXG59XFxuXFxuc3VwIHtcXG4gIHRvcDogLTAuNWVtO1xcbn1cXG5cXG4vKiBFbWJlZGRlZCBjb250ZW50XFxuICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cXG5cXG4vKipcXG4gKiBSZW1vdmUgdGhlIGJvcmRlciBvbiBpbWFnZXMgaW5zaWRlIGxpbmtzIGluIElFIDEwLlxcbiAqL1xcblxcbmltZyB7XFxuICBib3JkZXItc3R5bGU6IG5vbmU7XFxufVxcblxcbi8qIEZvcm1zXFxuICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cXG5cXG4vKipcXG4gKiAxLiBDaGFuZ2UgdGhlIGZvbnQgc3R5bGVzIGluIGFsbCBicm93c2Vycy5cXG4gKiAyLiBSZW1vdmUgdGhlIG1hcmdpbiBpbiBGaXJlZm94IGFuZCBTYWZhcmkuXFxuICovXFxuXFxuYnV0dG9uLFxcbmlucHV0LFxcbm9wdGdyb3VwLFxcbnNlbGVjdCxcXG50ZXh0YXJlYSB7XFxuICBmb250LWZhbWlseTogaW5oZXJpdDsgLyogMSAqL1xcbiAgZm9udC1zaXplOiAxMDAlOyAvKiAxICovXFxuICBsaW5lLWhlaWdodDogMS4xNTsgLyogMSAqL1xcbiAgbWFyZ2luOiAwOyAvKiAyICovXFxufVxcblxcbi8qKlxcbiAqIFNob3cgdGhlIG92ZXJmbG93IGluIElFLlxcbiAqIDEuIFNob3cgdGhlIG92ZXJmbG93IGluIEVkZ2UuXFxuICovXFxuXFxuYnV0dG9uLFxcbmlucHV0IHsgLyogMSAqL1xcbiAgb3ZlcmZsb3c6IHZpc2libGU7XFxufVxcblxcbi8qKlxcbiAqIFJlbW92ZSB0aGUgaW5oZXJpdGFuY2Ugb2YgdGV4dCB0cmFuc2Zvcm0gaW4gRWRnZSwgRmlyZWZveCwgYW5kIElFLlxcbiAqIDEuIFJlbW92ZSB0aGUgaW5oZXJpdGFuY2Ugb2YgdGV4dCB0cmFuc2Zvcm0gaW4gRmlyZWZveC5cXG4gKi9cXG5cXG5idXR0b24sXFxuc2VsZWN0IHsgLyogMSAqL1xcbiAgdGV4dC10cmFuc2Zvcm06IG5vbmU7XFxufVxcblxcbi8qKlxcbiAqIENvcnJlY3QgdGhlIGluYWJpbGl0eSB0byBzdHlsZSBjbGlja2FibGUgdHlwZXMgaW4gaU9TIGFuZCBTYWZhcmkuXFxuICovXFxuXFxuYnV0dG9uLFxcblt0eXBlPVxcXCJidXR0b25cXFwiXSxcXG5bdHlwZT1cXFwicmVzZXRcXFwiXSxcXG5bdHlwZT1cXFwic3VibWl0XFxcIl0ge1xcbiAgLXdlYmtpdC1hcHBlYXJhbmNlOiBidXR0b247XFxufVxcblxcbi8qKlxcbiAqIFJlbW92ZSB0aGUgaW5uZXIgYm9yZGVyIGFuZCBwYWRkaW5nIGluIEZpcmVmb3guXFxuICovXFxuXFxuYnV0dG9uOjotbW96LWZvY3VzLWlubmVyLFxcblt0eXBlPVxcXCJidXR0b25cXFwiXTo6LW1vei1mb2N1cy1pbm5lcixcXG5bdHlwZT1cXFwicmVzZXRcXFwiXTo6LW1vei1mb2N1cy1pbm5lcixcXG5bdHlwZT1cXFwic3VibWl0XFxcIl06Oi1tb3otZm9jdXMtaW5uZXIge1xcbiAgYm9yZGVyLXN0eWxlOiBub25lO1xcbiAgcGFkZGluZzogMDtcXG59XFxuXFxuLyoqXFxuICogUmVzdG9yZSB0aGUgZm9jdXMgc3R5bGVzIHVuc2V0IGJ5IHRoZSBwcmV2aW91cyBydWxlLlxcbiAqL1xcblxcbmJ1dHRvbjotbW96LWZvY3VzcmluZyxcXG5bdHlwZT1cXFwiYnV0dG9uXFxcIl06LW1vei1mb2N1c3JpbmcsXFxuW3R5cGU9XFxcInJlc2V0XFxcIl06LW1vei1mb2N1c3JpbmcsXFxuW3R5cGU9XFxcInN1Ym1pdFxcXCJdOi1tb3otZm9jdXNyaW5nIHtcXG4gIG91dGxpbmU6IDFweCBkb3R0ZWQgQnV0dG9uVGV4dDtcXG59XFxuXFxuLyoqXFxuICogQ29ycmVjdCB0aGUgcGFkZGluZyBpbiBGaXJlZm94LlxcbiAqL1xcblxcbmZpZWxkc2V0IHtcXG4gIHBhZGRpbmc6IDAuMzVlbSAwLjc1ZW0gMC42MjVlbTtcXG59XFxuXFxuLyoqXFxuICogMS4gQ29ycmVjdCB0aGUgdGV4dCB3cmFwcGluZyBpbiBFZGdlIGFuZCBJRS5cXG4gKiAyLiBDb3JyZWN0IHRoZSBjb2xvciBpbmhlcml0YW5jZSBmcm9tIGBmaWVsZHNldGAgZWxlbWVudHMgaW4gSUUuXFxuICogMy4gUmVtb3ZlIHRoZSBwYWRkaW5nIHNvIGRldmVsb3BlcnMgYXJlIG5vdCBjYXVnaHQgb3V0IHdoZW4gdGhleSB6ZXJvIG91dFxcbiAqICAgIGBmaWVsZHNldGAgZWxlbWVudHMgaW4gYWxsIGJyb3dzZXJzLlxcbiAqL1xcblxcbmxlZ2VuZCB7XFxuICBib3gtc2l6aW5nOiBib3JkZXItYm94OyAvKiAxICovXFxuICBjb2xvcjogaW5oZXJpdDsgLyogMiAqL1xcbiAgZGlzcGxheTogdGFibGU7IC8qIDEgKi9cXG4gIG1heC13aWR0aDogMTAwJTsgLyogMSAqL1xcbiAgcGFkZGluZzogMDsgLyogMyAqL1xcbiAgd2hpdGUtc3BhY2U6IG5vcm1hbDsgLyogMSAqL1xcbn1cXG5cXG4vKipcXG4gKiBBZGQgdGhlIGNvcnJlY3QgdmVydGljYWwgYWxpZ25tZW50IGluIENocm9tZSwgRmlyZWZveCwgYW5kIE9wZXJhLlxcbiAqL1xcblxcbnByb2dyZXNzIHtcXG4gIHZlcnRpY2FsLWFsaWduOiBiYXNlbGluZTtcXG59XFxuXFxuLyoqXFxuICogUmVtb3ZlIHRoZSBkZWZhdWx0IHZlcnRpY2FsIHNjcm9sbGJhciBpbiBJRSAxMCsuXFxuICovXFxuXFxudGV4dGFyZWEge1xcbiAgb3ZlcmZsb3c6IGF1dG87XFxufVxcblxcbi8qKlxcbiAqIDEuIEFkZCB0aGUgY29ycmVjdCBib3ggc2l6aW5nIGluIElFIDEwLlxcbiAqIDIuIFJlbW92ZSB0aGUgcGFkZGluZyBpbiBJRSAxMC5cXG4gKi9cXG5cXG5bdHlwZT1cXFwiY2hlY2tib3hcXFwiXSxcXG5bdHlwZT1cXFwicmFkaW9cXFwiXSB7XFxuICBib3gtc2l6aW5nOiBib3JkZXItYm94OyAvKiAxICovXFxuICBwYWRkaW5nOiAwOyAvKiAyICovXFxufVxcblxcbi8qKlxcbiAqIENvcnJlY3QgdGhlIGN1cnNvciBzdHlsZSBvZiBpbmNyZW1lbnQgYW5kIGRlY3JlbWVudCBidXR0b25zIGluIENocm9tZS5cXG4gKi9cXG5cXG5bdHlwZT1cXFwibnVtYmVyXFxcIl06Oi13ZWJraXQtaW5uZXItc3Bpbi1idXR0b24sXFxuW3R5cGU9XFxcIm51bWJlclxcXCJdOjotd2Via2l0LW91dGVyLXNwaW4tYnV0dG9uIHtcXG4gIGhlaWdodDogYXV0bztcXG59XFxuXFxuLyoqXFxuICogMS4gQ29ycmVjdCB0aGUgb2RkIGFwcGVhcmFuY2UgaW4gQ2hyb21lIGFuZCBTYWZhcmkuXFxuICogMi4gQ29ycmVjdCB0aGUgb3V0bGluZSBzdHlsZSBpbiBTYWZhcmkuXFxuICovXFxuXFxuW3R5cGU9XFxcInNlYXJjaFxcXCJdIHtcXG4gIC13ZWJraXQtYXBwZWFyYW5jZTogdGV4dGZpZWxkOyAvKiAxICovXFxuICBvdXRsaW5lLW9mZnNldDogLTJweDsgLyogMiAqL1xcbn1cXG5cXG4vKipcXG4gKiBSZW1vdmUgdGhlIGlubmVyIHBhZGRpbmcgaW4gQ2hyb21lIGFuZCBTYWZhcmkgb24gbWFjT1MuXFxuICovXFxuXFxuW3R5cGU9XFxcInNlYXJjaFxcXCJdOjotd2Via2l0LXNlYXJjaC1kZWNvcmF0aW9uIHtcXG4gIC13ZWJraXQtYXBwZWFyYW5jZTogbm9uZTtcXG59XFxuXFxuLyoqXFxuICogMS4gQ29ycmVjdCB0aGUgaW5hYmlsaXR5IHRvIHN0eWxlIGNsaWNrYWJsZSB0eXBlcyBpbiBpT1MgYW5kIFNhZmFyaS5cXG4gKiAyLiBDaGFuZ2UgZm9udCBwcm9wZXJ0aWVzIHRvIGBpbmhlcml0YCBpbiBTYWZhcmkuXFxuICovXFxuXFxuOjotd2Via2l0LWZpbGUtdXBsb2FkLWJ1dHRvbiB7XFxuICAtd2Via2l0LWFwcGVhcmFuY2U6IGJ1dHRvbjsgLyogMSAqL1xcbiAgZm9udDogaW5oZXJpdDsgLyogMiAqL1xcbn1cXG5cXG4vKiBJbnRlcmFjdGl2ZVxcbiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXFxuXFxuLypcXG4gKiBBZGQgdGhlIGNvcnJlY3QgZGlzcGxheSBpbiBFZGdlLCBJRSAxMCssIGFuZCBGaXJlZm94LlxcbiAqL1xcblxcbmRldGFpbHMge1xcbiAgZGlzcGxheTogYmxvY2s7XFxufVxcblxcbi8qXFxuICogQWRkIHRoZSBjb3JyZWN0IGRpc3BsYXkgaW4gYWxsIGJyb3dzZXJzLlxcbiAqL1xcblxcbnN1bW1hcnkge1xcbiAgZGlzcGxheTogbGlzdC1pdGVtO1xcbn1cXG5cXG4vKiBNaXNjXFxuICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cXG5cXG4vKipcXG4gKiBBZGQgdGhlIGNvcnJlY3QgZGlzcGxheSBpbiBJRSAxMCsuXFxuICovXFxuXFxudGVtcGxhdGUge1xcbiAgZGlzcGxheTogbm9uZTtcXG59XFxuXFxuLyoqXFxuICogQWRkIHRoZSBjb3JyZWN0IGRpc3BsYXkgaW4gSUUgMTAuXFxuICovXFxuXFxuW2hpZGRlbl0ge1xcbiAgZGlzcGxheTogbm9uZTtcXG59XFxuXCJdLFwic291cmNlUm9vdFwiOlwiXCJ9XSk7XG4vLyBFeHBvcnRzXG5leHBvcnQgZGVmYXVsdCBfX19DU1NfTE9BREVSX0VYUE9SVF9fXztcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///874\n')},365:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(417);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_2__);\n// Imports\n\n\n\nvar ___CSS_LOADER_URL_IMPORT_0___ = new URL(/* asset import */ __webpack_require__(953), __webpack_require__.b);\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\nvar ___CSS_LOADER_URL_REPLACEMENT_0___ = _node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_2___default()(___CSS_LOADER_URL_IMPORT_0___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `@font-face {\n font-family: Montserrat;\n src: url(${___CSS_LOADER_URL_REPLACEMENT_0___});\n}\n\n:root {\n --imperial-red: #e43b3bff;\n --jet: #2c2c2cff;\n --creamy-white: rgb(255, 253, 239);\n --earth-yellow: #dba159ff;\n --air-force-blue: #568ea3ff;\n --verde: #5fb75f;\n}\n\nhtml {\n font-family: Montserrat, system-ui, -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, Oxygen, Ubuntu, Cantarell, \'Open Sans\', \'Helvetica Neue\', sans-serif;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin: 0;\n}\n\n@keyframes fadeIn {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\n\n.fadein {\n opacity: 0;\n transition: opacity 1.5s ease-in-out;\n}\n\nr {\n display: inline;\n color: var(--imperial-red);\n font-weight: 700;\n}\n\nheader {\n box-shadow: 0px 5px 18px -6px rgba(0,0,0,0.75);\n}\n\nfooter {\n box-shadow: 0px -5px 18px -6px rgba(0,0,0,0.75);\n}\n\n@media only screen and\n (max-width: 768px) {\n\n header {\n display: flex;\n align-items: center;\n justify-content: space-between;;\n background-color: var(--imperial-red);\n color: var(--creamy-white);\n position: sticky;\n top: 0;\n width: 100%;\n height: 100px;\n z-index: 2;\n\n h1 {\n padding-left: 25px;\n }\n\n svg {\n height: 70px;\n width: 70px;\n padding-right: 25px;\n \n path {\n fill: var(--creamy-white);\n }\n\n }\n\n}\n\n.unmute-button {\n position: absolute;\n bottom: 20px;\n right: 20px;\n z-index: 1.5;\n background-color: rgba(0, 0, 0, 0.7);\n color: #fff;\n border: none;\n padding: 10px;\n cursor: pointer;\n font-size: 16px;\n}\n\nmain {\n display: grid;\n text-align: center;\n grid-template: calc(100vh - 170px) 300px 300px 500px 500px / 1fr;\n background-color: var(--creamy-white);\n\n div {\n display: flex;\n flex-direction: column;\n justify-content: center;\n }\n\n > div:nth-child(even) {\n background-color: var(--imperial-red);\n\n r {\n color: var(--creamy-white);\n }\n }\n\n #whoWeAre {\n position: relative;\n overflow: hidden;\n\n video {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n z-index: 0;\n }\n\n h2 {\n position: relative;\n z-index: 1;\n padding: 15px 0;\n color: #fff;\n\n ::before {\n content: ""; /* Required for pseudo-elements */\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: #00000066;\n filter: blur(30px);\n z-index: -1; /* Ensure it is behind the actual content */\n }\n }\n\n img {\n height: 30px;\n width: 30px;\n }\n }\n\n .animation {\n\n font-size: large;\n \n #controcoroText {\n padding-top: 0px;\n font-size: x-large;\n font-weight: 700;\n }\n }\n\n #quanti, #chartContainer {\n display: flex;\n flex-direction: column;\n gap: 25px;\n }\n\n #countup {\n font-size: xxx-large;\n font-weight: 700;\n letter-spacing: 2.5px;\n }\n\n #chartContainer {\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n\n h2 {\n padding-top: 20px\n }\n\n canvas {\n height: 50%;\n width: 50%;\n padding: 10px 20px 20px 20px;\n }\n }\n\n}\n\n#chartContainer {\n width: 70%;\n max-width: 600px;\n}\n\nfooter {\n display: flex;\n flex-direction: column;\n position: sticky;\n bottom: 0;\n\n div {\n display: flex;\n flex-direction: row;\n justify-content:center;\n gap: 5px;\n align-items: center;\n color: var(--creamy-white);\n background-color: var(--imperial-red);\n padding: 10px 0 0 0;\n \n a {\n text-decoration: underline dotted;\n color: var(--earth-yellow);\n font-weight: 600;\n }\n }\n\n div:has(span) {\n display: flex;\n flex-direction: column;\n }\n}\n\n\n\nfooter div:last-child {\n padding-bottom: 10px;\n}\n\n .contacts {\n display: flex;\n flex-direction: column;\n gap: 18px;\n align-items: center;\n\n a {\n text-decoration: none;\n color: var(--creamy-white);\n }\n\n .harmony {\n display: flex;\n flex-direction: row;\n gap: 10px;\n padding-bottom: 10px;\n\n svg {\n height: 45px;\n width: 45px;\n padding-left: 15px;\n }\n }\n\n .card {\n cursor: pointer;\n\n display: flex;\n flex-direction: row;\n align-items: center;\n height: 75px;\n\n background-color: var(--air-force-blue);\n color: var(--creamy-white);\n font-weight: 600;\n font-size: 13px;\n\n border: none;\n border-radius: 10px;\n box-shadow: -4px 5px 8px #00000036;\n\n\n padding: 0 10px 0 10px;\n\n svg, path {\n height: 30px;\n width: 30px;\n padding: 0 15px 0 10px;\n fill: var(--creamy-white)\n }\n\n .details {\n padding-right: 15px;\n }\n\n\n .details.address p::before {\n content: "Via di S. Croce \\\\A in Gerusalemme, 55 \\\\a (Roma, RM) c/o Spin Time";\n white-space: pre-wrap;\n }\n\n }\n\n .card:hover {\n \n background-color: rgb(37, 117, 147);\n transition: all 0.4s ease-out;\n box-shadow: -6px 7px 5px #0000008f;\n }\n\n .ig {\n background: #833ab4;\n background: linear-gradient(\n to right,\n #833ab4,#fd1d1d,#fcb045\n );\n transition: all 0.4s ease-out;\n }\n\n .wapp {\n background-color: var(--verde);\n }\n\n .wapp:hover {\n background-color: #389538;\n }\n }\n\n\n \n}\n\n@media screen and (min-width: 1024px) {\n header {\n display: flex;\n align-items: center;\n justify-content: space-between;;\n background-color: var(--imperial-red);\n color: var(--creamy-white);\n position: sticky;\n top: 0;\n width: 100%;\n height: 100px;\n z-index: 2;\n\n h1 {\n padding-left: 30px;\n font-size: 40px;\n }\n\n svg {\n height: 70px;\n width: 70px;\n padding-right: 25px;\n \n path {\n fill: var(--creamy-white);\n }\n\n }\n\n }\n\n .unmute-button {\n position: absolute;\n bottom: 20px;\n right: 20px;\n z-index: 1.5;\n background-color: rgba(0, 0, 0, 0.7);\n color: #fff;\n border: none;\n padding: 10px;\n cursor: pointer;\n font-size: 16px;\n }\n\n main {\n display: grid;\n text-align: center;\n grid-template: calc(100vh - 170px) 300px 300px 500px 500px / 1fr;\n background-color: var(--creamy-white);\n\n div {\n display: flex;\n flex-direction: column;\n justify-content: center;\n }\n\n > div:nth-child(even) {\n background-color: var(--imperial-red);\n\n r {\n color: var(--creamy-white);\n }\n }\n\n #whoWeAre {\n position: relative;\n overflow: hidden;\n background-color: var(--jet);\n\n video {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n object-fit:scale-down;\n z-index: 0;\n }\n\n h2 {\n position: relative;\n z-index: 1;\n padding: 15px 0;\n color: #fff;\n\n ::before {\n content: ""; /* Required for pseudo-elements */\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: #00000036;\n filter: blur(30px);\n z-index: -1; /* Ensure it is behind the actual content */\n }\n }\n\n img {\n height: 30px;\n width: 30px;\n }\n }\n\n .animation {\n\n font-size: xx-large;\n \n #controcoroText {\n padding-top: 0px;\n font-size: xxx-large;\n font-weight: 700;\n }\n }\n\n #quanti, #chartContainer {\n display: flex;\n flex-direction: column;\n gap: 25px;\n }\n\n #quanti {\n h2 {\n font-size: xx-large;\n }\n }\n\n #countup {\n font-size: xxx-large;\n font-weight: 700;\n letter-spacing: 2.5px;\n }\n\n #chartContainer {\n width: 100vw;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n\n h2 {\n padding-top: 20px;\n font-size:2em;\n }\n\n canvas {\n max-height: 400px;\n max-width: 400px;\n padding: 10px 20px 20px 20px;\n }\n }\n\n }\n\n footer {\n display: flex;\n flex-direction: column;\n position: sticky;\n bottom: 0;\n }\n\n footer div {\n display: flex;\n flex-direction: row;\n justify-content:center;\n gap: 5px;\n align-items: center;\n color: var(--creamy-white);\n background-color: var(--imperial-red);\n width: 100%;\n padding: 10px 0 0 0;\n\n a {\n text-decoration: underline dotted;\n color: var(--earth-yellow);\n font-weight: 600;\n }\n }\n\n footer div:last-child {\n padding-bottom: 10px;\n }\n\n .contacts {\n display: flex;\n flex-direction: column;\n gap: 18px;\n align-items: center;\n\n a {\n text-decoration: none;\n color: var(--creamy-white);\n }\n\n .harmony {\n display: flex;\n flex-direction: row;\n gap: 10px;\n padding-bottom: 10px;\n\n h2 {\n font-size: 40px;\n }\n\n svg {\n height: 60px;\n width: 60px;\n align-self: flex-end;\n padding-left: 18px;\n }\n }\n\n .card {\n cursor: pointer;\n\n display: flex;\n flex-direction: row;\n align-items: center;\n height: 75px;\n\n background-color: var(--air-force-blue);\n color: var(--creamy-white);\n font-weight: 600;\n\n border: none;\n border-radius: 10px;\n box-shadow: -4px 5px 8px #00000036;\n\n svg, path {\n height: 50px;\n width: 50px;\n padding: 0 10px 0 10px;\n fill: var(--creamy-white)\n }\n\n .details {\n width: 400px;\n font-size: larger;\n padding-right: 15px;\n }\n\n .details.address p::before {\n content: "Via di S. Croce in Gerusalemme, 55 (Roma, RM) c/o Spin Time";\n }\n }\n\n .card:hover {\n \n background-color: rgb(37, 117, 147);\n transition: all 0.4s ease-out;\n box-shadow: -6px 7px 5px #0000008f;\n }\n\n .ig {\n background: #833ab4;\n background: linear-gradient(\n to right,\n #833ab4,#fd1d1d,#fcb045\n );\n transition: all 0.4s ease-out;\n }\n\n .wapp {\n background-color: var(--verde);\n }\n\n .wapp:hover {\n background-color: #389538;\n }\n }\n}`, "",{"version":3,"sources":["webpack://./src/styles.css"],"names":[],"mappings":"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","sourcesContent":["@font-face {\\n font-family: Montserrat;\\n src: url(./assets/fonts/Montserrat-VariableFont_wght.ttf);\\n}\\n\\n:root {\\n --imperial-red: #e43b3bff;\\n --jet: #2c2c2cff;\\n --creamy-white: rgb(255, 253, 239);\\n --earth-yellow: #dba159ff;\\n --air-force-blue: #568ea3ff;\\n --verde: #5fb75f;\\n}\\n\\nhtml {\\n font-family: Montserrat, system-ui, -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, Oxygen, Ubuntu, Cantarell, \'Open Sans\', \'Helvetica Neue\', sans-serif;\\n}\\n\\nh1, h2, h3, h4, h5, h6 {\\n margin: 0;\\n}\\n\\n@keyframes fadeIn {\\n 0% {\\n opacity: 0;\\n }\\n 100% {\\n opacity: 1;\\n }\\n}\\n\\n.fadein {\\n opacity: 0;\\n transition: opacity 1.5s ease-in-out;\\n}\\n\\nr {\\n display: inline;\\n color: var(--imperial-red);\\n font-weight: 700;\\n}\\n\\nheader {\\n box-shadow: 0px 5px 18px -6px rgba(0,0,0,0.75);\\n}\\n\\nfooter {\\n box-shadow: 0px -5px 18px -6px rgba(0,0,0,0.75);\\n}\\n\\n@media only screen and\\n (max-width: 768px) {\\n\\n header {\\n display: flex;\\n align-items: center;\\n justify-content: space-between;;\\n background-color: var(--imperial-red);\\n color: var(--creamy-white);\\n position: sticky;\\n top: 0;\\n width: 100%;\\n height: 100px;\\n z-index: 2;\\n\\n h1 {\\n padding-left: 25px;\\n }\\n\\n svg {\\n height: 70px;\\n width: 70px;\\n padding-right: 25px;\\n \\n path {\\n fill: var(--creamy-white);\\n }\\n\\n }\\n\\n}\\n\\n.unmute-button {\\n position: absolute;\\n bottom: 20px;\\n right: 20px;\\n z-index: 1.5;\\n background-color: rgba(0, 0, 0, 0.7);\\n color: #fff;\\n border: none;\\n padding: 10px;\\n cursor: pointer;\\n font-size: 16px;\\n}\\n\\nmain {\\n display: grid;\\n text-align: center;\\n grid-template: calc(100vh - 170px) 300px 300px 500px 500px / 1fr;\\n background-color: var(--creamy-white);\\n\\n div {\\n display: flex;\\n flex-direction: column;\\n justify-content: center;\\n }\\n\\n > div:nth-child(even) {\\n background-color: var(--imperial-red);\\n\\n r {\\n color: var(--creamy-white);\\n }\\n }\\n\\n #whoWeAre {\\n position: relative;\\n overflow: hidden;\\n\\n video {\\n position: absolute;\\n top: 0;\\n left: 0;\\n width: 100%;\\n height: 100%;\\n object-fit: cover;\\n z-index: 0;\\n }\\n\\n h2 {\\n position: relative;\\n z-index: 1;\\n padding: 15px 0;\\n color: #fff;\\n\\n ::before {\\n content: \\"\\"; /* Required for pseudo-elements */\\n position: absolute;\\n top: 0;\\n left: 0;\\n width: 100%;\\n height: 100%;\\n background-color: #00000066;\\n filter: blur(30px);\\n z-index: -1; /* Ensure it is behind the actual content */\\n }\\n }\\n\\n img {\\n height: 30px;\\n width: 30px;\\n }\\n }\\n\\n .animation {\\n\\n font-size: large;\\n \\n #controcoroText {\\n padding-top: 0px;\\n font-size: x-large;\\n font-weight: 700;\\n }\\n }\\n\\n #quanti, #chartContainer {\\n display: flex;\\n flex-direction: column;\\n gap: 25px;\\n }\\n\\n #countup {\\n font-size: xxx-large;\\n font-weight: 700;\\n letter-spacing: 2.5px;\\n }\\n\\n #chartContainer {\\n width: 100%;\\n display: flex;\\n flex-direction: column;\\n align-items: center;\\n justify-content: center;\\n\\n h2 {\\n padding-top: 20px\\n }\\n\\n canvas {\\n height: 50%;\\n width: 50%;\\n padding: 10px 20px 20px 20px;\\n }\\n }\\n\\n}\\n\\n#chartContainer {\\n width: 70%;\\n max-width: 600px;\\n}\\n\\nfooter {\\n display: flex;\\n flex-direction: column;\\n position: sticky;\\n bottom: 0;\\n\\n div {\\n display: flex;\\n flex-direction: row;\\n justify-content:center;\\n gap: 5px;\\n align-items: center;\\n color: var(--creamy-white);\\n background-color: var(--imperial-red);\\n padding: 10px 0 0 0;\\n \\n a {\\n text-decoration: underline dotted;\\n color: var(--earth-yellow);\\n font-weight: 600;\\n }\\n }\\n\\n div:has(span) {\\n display: flex;\\n flex-direction: column;\\n }\\n}\\n\\n\\n\\nfooter div:last-child {\\n padding-bottom: 10px;\\n}\\n\\n .contacts {\\n display: flex;\\n flex-direction: column;\\n gap: 18px;\\n align-items: center;\\n\\n a {\\n text-decoration: none;\\n color: var(--creamy-white);\\n }\\n\\n .harmony {\\n display: flex;\\n flex-direction: row;\\n gap: 10px;\\n padding-bottom: 10px;\\n\\n svg {\\n height: 45px;\\n width: 45px;\\n padding-left: 15px;\\n }\\n }\\n\\n .card {\\n cursor: pointer;\\n\\n display: flex;\\n flex-direction: row;\\n align-items: center;\\n height: 75px;\\n\\n background-color: var(--air-force-blue);\\n color: var(--creamy-white);\\n font-weight: 600;\\n font-size: 13px;\\n\\n border: none;\\n border-radius: 10px;\\n box-shadow: -4px 5px 8px #00000036;\\n\\n\\n padding: 0 10px 0 10px;\\n\\n svg, path {\\n height: 30px;\\n width: 30px;\\n padding: 0 15px 0 10px;\\n fill: var(--creamy-white)\\n }\\n\\n .details {\\n padding-right: 15px;\\n }\\n\\n\\n .details.address p::before {\\n content: \\"Via di S. Croce \\\\A in Gerusalemme, 55 \\\\a (Roma, RM) c/o Spin Time\\";\\n white-space: pre-wrap;\\n }\\n\\n }\\n\\n .card:hover {\\n \\n background-color: rgb(37, 117, 147);\\n transition: all 0.4s ease-out;\\n box-shadow: -6px 7px 5px #0000008f;\\n }\\n\\n .ig {\\n background: #833ab4;\\n background: linear-gradient(\\n to right,\\n #833ab4,#fd1d1d,#fcb045\\n );\\n transition: all 0.4s ease-out;\\n }\\n\\n .wapp {\\n background-color: var(--verde);\\n }\\n\\n .wapp:hover {\\n background-color: #389538;\\n }\\n }\\n\\n\\n \\n}\\n\\n@media screen and (min-width: 1024px) {\\n header {\\n display: flex;\\n align-items: center;\\n justify-content: space-between;;\\n background-color: var(--imperial-red);\\n color: var(--creamy-white);\\n position: sticky;\\n top: 0;\\n width: 100%;\\n height: 100px;\\n z-index: 2;\\n\\n h1 {\\n padding-left: 30px;\\n font-size: 40px;\\n }\\n\\n svg {\\n height: 70px;\\n width: 70px;\\n padding-right: 25px;\\n \\n path {\\n fill: var(--creamy-white);\\n }\\n\\n }\\n\\n }\\n\\n .unmute-button {\\n position: absolute;\\n bottom: 20px;\\n right: 20px;\\n z-index: 1.5;\\n background-color: rgba(0, 0, 0, 0.7);\\n color: #fff;\\n border: none;\\n padding: 10px;\\n cursor: pointer;\\n font-size: 16px;\\n }\\n\\n main {\\n display: grid;\\n text-align: center;\\n grid-template: calc(100vh - 170px) 300px 300px 500px 500px / 1fr;\\n background-color: var(--creamy-white);\\n\\n div {\\n display: flex;\\n flex-direction: column;\\n justify-content: center;\\n }\\n\\n > div:nth-child(even) {\\n background-color: var(--imperial-red);\\n\\n r {\\n color: var(--creamy-white);\\n }\\n }\\n\\n #whoWeAre {\\n position: relative;\\n overflow: hidden;\\n background-color: var(--jet);\\n\\n video {\\n position: absolute;\\n top: 0;\\n left: 0;\\n width: 100%;\\n height: 100%;\\n object-fit:scale-down;\\n z-index: 0;\\n }\\n\\n h2 {\\n position: relative;\\n z-index: 1;\\n padding: 15px 0;\\n color: #fff;\\n\\n ::before {\\n content: \\"\\"; /* Required for pseudo-elements */\\n position: absolute;\\n top: 0;\\n left: 0;\\n width: 100%;\\n height: 100%;\\n background-color: #00000036;\\n filter: blur(30px);\\n z-index: -1; /* Ensure it is behind the actual content */\\n }\\n }\\n\\n img {\\n height: 30px;\\n width: 30px;\\n }\\n }\\n\\n .animation {\\n\\n font-size: xx-large;\\n \\n #controcoroText {\\n padding-top: 0px;\\n font-size: xxx-large;\\n font-weight: 700;\\n }\\n }\\n\\n #quanti, #chartContainer {\\n display: flex;\\n flex-direction: column;\\n gap: 25px;\\n }\\n\\n #quanti {\\n h2 {\\n font-size: xx-large;\\n }\\n }\\n\\n #countup {\\n font-size: xxx-large;\\n font-weight: 700;\\n letter-spacing: 2.5px;\\n }\\n\\n #chartContainer {\\n width: 100vw;\\n display: flex;\\n flex-direction: column;\\n align-items: center;\\n justify-content: center;\\n\\n h2 {\\n padding-top: 20px;\\n font-size:2em;\\n }\\n\\n canvas {\\n max-height: 400px;\\n max-width: 400px;\\n padding: 10px 20px 20px 20px;\\n }\\n }\\n\\n }\\n\\n footer {\\n display: flex;\\n flex-direction: column;\\n position: sticky;\\n bottom: 0;\\n }\\n\\n footer div {\\n display: flex;\\n flex-direction: row;\\n justify-content:center;\\n gap: 5px;\\n align-items: center;\\n color: var(--creamy-white);\\n background-color: var(--imperial-red);\\n width: 100%;\\n padding: 10px 0 0 0;\\n\\n a {\\n text-decoration: underline dotted;\\n color: var(--earth-yellow);\\n font-weight: 600;\\n }\\n }\\n\\n footer div:last-child {\\n padding-bottom: 10px;\\n }\\n\\n .contacts {\\n display: flex;\\n flex-direction: column;\\n gap: 18px;\\n align-items: center;\\n\\n a {\\n text-decoration: none;\\n color: var(--creamy-white);\\n }\\n\\n .harmony {\\n display: flex;\\n flex-direction: row;\\n gap: 10px;\\n padding-bottom: 10px;\\n\\n h2 {\\n font-size: 40px;\\n }\\n\\n svg {\\n height: 60px;\\n width: 60px;\\n align-self: flex-end;\\n padding-left: 18px;\\n }\\n }\\n\\n .card {\\n cursor: pointer;\\n\\n display: flex;\\n flex-direction: row;\\n align-items: center;\\n height: 75px;\\n\\n background-color: var(--air-force-blue);\\n color: var(--creamy-white);\\n font-weight: 600;\\n\\n border: none;\\n border-radius: 10px;\\n box-shadow: -4px 5px 8px #00000036;\\n\\n svg, path {\\n height: 50px;\\n width: 50px;\\n padding: 0 10px 0 10px;\\n fill: var(--creamy-white)\\n }\\n\\n .details {\\n width: 400px;\\n font-size: larger;\\n padding-right: 15px;\\n }\\n\\n .details.address p::before {\\n content: \\"Via di S. Croce in Gerusalemme, 55 (Roma, RM) c/o Spin Time\\";\\n }\\n }\\n\\n .card:hover {\\n \\n background-color: rgb(37, 117, 147);\\n transition: all 0.4s ease-out;\\n box-shadow: -6px 7px 5px #0000008f;\\n }\\n\\n .ig {\\n background: #833ab4;\\n background: linear-gradient(\\n to right,\\n #833ab4,#fd1d1d,#fcb045\\n );\\n transition: all 0.4s ease-out;\\n }\\n\\n .wapp {\\n background-color: var(--verde);\\n }\\n\\n .wapp:hover {\\n background-color: #389538;\\n }\\n }\\n}"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzY1LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBO0FBQzBHO0FBQ2pCO0FBQ087QUFDaEcsNENBQTRDLGtFQUFrRTtBQUM5Ryw4QkFBOEIsbUZBQTJCLENBQUMsNEZBQXFDO0FBQy9GLHlDQUF5QyxzRkFBK0I7QUFDeEU7QUFDQTtBQUNBO0FBQ0EsZUFBZSxtQ0FBbUM7QUFDbEQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlDQUFpQztBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQztBQUNqQztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsT0FBTyxpRkFBaUYsWUFBWSxhQUFhLE9BQU8sS0FBSyxZQUFZLGFBQWEsYUFBYSxhQUFhLGFBQWEsYUFBYSxPQUFPLEtBQUssWUFBWSxPQUFPLEtBQUssVUFBVSxNQUFNLEtBQUssS0FBSyxVQUFVLEtBQUssS0FBSyxVQUFVLEtBQUssTUFBTSxLQUFLLFVBQVUsWUFBWSxPQUFPLEtBQUssVUFBVSxZQUFZLGFBQWEsT0FBTyxLQUFLLFlBQVksT0FBTyxLQUFLLFlBQVksT0FBTyxPQUFPLEtBQUssVUFBVSxZQUFZLGFBQWEsYUFBYSxhQUFhLGFBQWEsV0FBVyxVQUFVLFVBQVUsV0FBVyxLQUFLLFlBQVksT0FBTyxLQUFLLFVBQVUsVUFBVSxhQUFhLE1BQU0sWUFBWSxPQUFPLE1BQU0sTUFBTSxLQUFLLFlBQVksV0FBVyxVQUFVLFVBQVUsWUFBWSxXQUFXLFVBQVUsVUFBVSxVQUFVLFVBQVUsT0FBTyxLQUFLLFVBQVUsWUFBWSxhQUFhLGNBQWMsTUFBTSxVQUFVLFlBQVksYUFBYSxPQUFPLEtBQUssYUFBYSxNQUFNLFlBQVksTUFBTSxNQUFNLEtBQUssWUFBWSxjQUFjLE1BQU0sWUFBWSxXQUFXLFVBQVUsVUFBVSxVQUFVLFlBQVksV0FBVyxNQUFNLEtBQUssWUFBWSxXQUFXLFVBQVUsV0FBVyxLQUFLLHVCQUF1QixjQUFjLFlBQVksV0FBVyxXQUFXLFdBQVcsYUFBYSxjQUFjLHdCQUF3QixNQUFNLE1BQU0sS0FBSyxVQUFVLFVBQVUsS0FBSyxNQUFNLE1BQU0sYUFBYSxNQUFNLFlBQVksYUFBYSxhQUFhLE1BQU0sTUFBTSxLQUFLLFVBQVUsWUFBWSxXQUFXLE1BQU0sS0FBSyxZQUFZLGFBQWEsYUFBYSxPQUFPLEtBQUssVUFBVSxVQUFVLFlBQVksYUFBYSxjQUFjLE1BQU0sS0FBSyxNQUFNLEtBQUssVUFBVSxVQUFVLFlBQVksTUFBTSxNQUFNLE1BQU0sS0FBSyxVQUFVLFlBQVksT0FBTyxLQUFLLFVBQVUsWUFBWSxhQUFhLFlBQVksS0FBSyxVQUFVLFlBQVksYUFBYSxXQUFXLFlBQVksYUFBYSxhQUFhLGNBQWMsTUFBTSxZQUFZLGFBQWEsYUFBYSxNQUFNLE1BQU0sS0FBSyxVQUFVLFlBQVksTUFBTSxRQUFRLEtBQUssWUFBWSxPQUFPLEtBQUssVUFBVSxZQUFZLFdBQVcsYUFBYSxNQUFNLFlBQVksYUFBYSxPQUFPLEtBQUssVUFBVSxZQUFZLFdBQVcsYUFBYSxNQUFNLFdBQVcsV0FBVyxhQUFhLE1BQU0sTUFBTSxLQUFLLFdBQVcsVUFBVSxZQUFZLGFBQWEsWUFBWSxZQUFZLGFBQWEsYUFBYSxZQUFZLFVBQVUsWUFBWSxlQUFlLGNBQWMsTUFBTSxXQUFXLFdBQVcsYUFBYSxPQUFPLE1BQU0sS0FBSyxhQUFhLFFBQVEsS0FBSyxhQUFhLGNBQWMsT0FBTyxNQUFNLE1BQU0sWUFBWSxhQUFhLGFBQWEsT0FBTyxLQUFLLFlBQVksUUFBUSxNQUFNLGFBQWEsT0FBTyxLQUFLLFlBQVksT0FBTyxLQUFLLFlBQVksTUFBTSxRQUFRLE1BQU0sS0FBSyxLQUFLLFVBQVUsWUFBWSxhQUFhLGFBQWEsYUFBYSxhQUFhLFdBQVcsVUFBVSxVQUFVLFdBQVcsS0FBSyxZQUFZLFdBQVcsT0FBTyxLQUFLLFVBQVUsVUFBVSxhQUFhLE1BQU0sYUFBYSxPQUFPLE1BQU0sTUFBTSxLQUFLLFlBQVksV0FBVyxVQUFVLFVBQVUsWUFBWSxXQUFXLFVBQVUsVUFBVSxVQUFVLFVBQVUsT0FBTyxLQUFLLFVBQVUsWUFBWSxhQUFhLGNBQWMsTUFBTSxVQUFVLFlBQVksYUFBYSxPQUFPLEtBQUssYUFBYSxNQUFNLGFBQWEsTUFBTSxNQUFNLEtBQUssWUFBWSxhQUFhLGNBQWMsTUFBTSxhQUFhLFlBQVksV0FBVyxXQUFXLFdBQVcsYUFBYSxZQUFZLE1BQU0sS0FBSyxhQUFhLFlBQVksV0FBVyxZQUFZLE1BQU0sdUJBQXVCLGNBQWMsWUFBWSxXQUFXLFdBQVcsV0FBVyxhQUFhLGNBQWMsd0JB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eUMsK0JBQStCLDZCQUE2QixrQ0FBa0MsaURBQWlELDJCQUEyQiwrQkFBK0IsOEJBQThCLHlDQUF5QywwREFBMEQsMEJBQTBCLCtCQUErQixvQ0FBb0Msc0NBQXNDLGVBQWUsNENBQTRDLDJGQUEyRixlQUFlLFdBQVcseUJBQXlCLGdFQUFnRSw0Q0FBNEMsaURBQWlELFdBQVcsaUJBQWlCLGtDQUFrQyxrSUFBa0ksZ0RBQWdELGVBQWUsbUJBQW1CLDZDQUE2QyxXQUFXLHlCQUF5Qix3Q0FBd0MsV0FBVyxPQUFPLEdBQUcsbUJBQW1CO0FBQ3Y4aUI7QUFDQSxpRUFBZSx1QkFBdUIsRUFBQyIsInNvdXJjZXMiOlsid2VicGFjazovL2NvbnRyb2Nvcm8tbGFuZGluZy1wYWdlLy4vc3JjL3N0eWxlcy5jc3M/ZTlhYSJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBJbXBvcnRzXG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyBmcm9tIFwiLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL3NvdXJjZU1hcHMuanNcIjtcbmltcG9ydCBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18gZnJvbSBcIi4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9hcGkuanNcIjtcbmltcG9ydCBfX19DU1NfTE9BREVSX0dFVF9VUkxfSU1QT1JUX19fIGZyb20gXCIuLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvZ2V0VXJsLmpzXCI7XG52YXIgX19fQ1NTX0xPQURFUl9VUkxfSU1QT1JUXzBfX18gPSBuZXcgVVJMKFwiLi9hc3NldHMvZm9udHMvTW9udHNlcnJhdC1WYXJpYWJsZUZvbnRfd2dodC50dGZcIiwgaW1wb3J0Lm1ldGEudXJsKTtcbnZhciBfX19DU1NfTE9BREVSX0VYUE9SVF9fXyA9IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyhfX19DU1NfTE9BREVSX0FQSV9TT1VSQ0VNQVBfSU1QT1JUX19fKTtcbnZhciBfX19DU1NfTE9BREVSX1VSTF9SRVBMQUNFTUVOVF8wX19fID0gX19fQ1NTX0xPQURFUl9HRVRfVVJMX0lNUE9SVF9fXyhfX19DU1NfTE9BREVSX1VSTF9JTVBPUlRfMF9fXyk7XG4vLyBNb2R1bGVcbl9fX0NTU19MT0FERVJfRVhQT1JUX19fLnB1c2goW21vZHVsZS5pZCwgYEBmb250LWZhY2Uge1xuICAgIGZvbnQtZmFtaWx5OiBNb250c2VycmF0O1xuICAgIHNyYzogdXJsKCR7X19fQ1NTX0xPQURFUl9VUkxfUkVQTEFDRU1FTlRfMF9fX30pO1xufVxuXG46cm9vdCB7XG4gICAgLS1pbXBlcmlhbC1yZWQ6ICNlNDNiM2JmZjtcbiAgICAtLWpldDogIzJjMmMyY2ZmO1xuICAgIC0tY3JlYW15LXdoaXRlOiByZ2IoMjU1LCAyNTMsIDIzOSk7XG4gICAgLS1lYXJ0aC15ZWxsb3c6ICNkYmExNTlmZjtcbiAgICAtLWFpci1mb3JjZS1ibHVlOiAjNTY4ZWEzZmY7XG4gICAgLS12ZXJkZTogIzVmYjc1Zjtcbn1cblxuaHRtbCB7XG4gICAgZm9udC1mYW1pbHk6IE1vbnRzZXJyYXQsIHN5c3RlbS11aSwgLWFwcGxlLXN5c3RlbSwgQmxpbmtNYWNTeXN0ZW1Gb250LCAnU2Vnb2UgVUknLCBSb2JvdG8sIE94eWdlbiwgVWJ1bnR1LCBDYW50YXJlbGwsICdPcGVuIFNhbnMnLCAnSGVsdmV0aWNhIE5ldWUnLCBzYW5zLXNlcmlmO1xufVxuXG5oMSwgaDIsIGgzLCBoNCwgaDUsIGg2IHtcbiAgICBtYXJnaW46IDA7XG59XG5cbkBrZXlmcmFtZXMgZmFkZUluIHtcbiAgICAwJSB7XG4gICAgICAgIG9wYWNpdHk6IDA7XG4gICAgfVxuICAgIDEwMCUge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgIH1cbn1cblxuLmZhZGVpbiB7XG4gICAgb3BhY2l0eTogMDtcbiAgICB0cmFuc2l0aW9uOiBvcGFjaXR5IDEuNXMgZWFzZS1pbi1vdXQ7XG59XG5cbnIge1xuICAgIGRpc3BsYXk6IGlubGluZTtcbiAgICBjb2xvcjogdmFyKC0taW1wZXJpYWwtcmVkKTtcbiAgICBmb250LXdlaWdodDogNzAwO1xufVxuXG5oZWFkZXIge1xuICAgIGJveC1zaGFkb3c6IDBweCA1cHggMThweCAtNnB4IHJnYmEoMCwwLDAsMC43NSk7XG59XG5cbmZvb3RlciB7XG4gICAgYm94LXNoYWRvdzogMHB4IC01cHggMThweCAtNnB4IHJnYmEoMCwwLDAsMC43NSk7XG59XG5cbkBtZWRpYSBvbmx5IHNjcmVlbiBhbmRcbiAgICAobWF4LXdpZHRoOiA3NjhweCkge1xuXG4gICAgaGVhZGVyIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuOztcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1pbXBlcmlhbC1yZWQpO1xuICAgIGNvbG9yOiB2YXIoLS1jcmVhbXktd2hpdGUpO1xuICAgIHBvc2l0aW9uOiBzdGlja3k7XG4gICAgdG9wOiAwO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGhlaWdodDogMTAwcHg7XG4gICAgei1pbmRleDogMjtcblxuICAgIGgxIHtcbiAgICAgICAgcGFkZGluZy1sZWZ0OiAyNXB4O1xuICAgIH1cblxuICAgIHN2ZyB7XG4gICAgICAgIGhlaWdodDogNzBweDtcbiAgICAgICAgd2lkdGg6IDcwcHg7XG4gICAgICAgIHBhZGRpbmctcmlnaHQ6IDI1cHg7XG4gICAgICAgIFxuICAgICAgICBwYXRoIHtcbiAgICAgICAgICAgIGZpbGw6IHZhcigtLWNyZWFteS13aGl0ZSk7XG4gICAgICAgIH1cblxuICAgIH1cblxufVxuXG4udW5tdXRlLWJ1dHRvbiB7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIGJvdHRvbTogMjBweDtcbiAgICByaWdodDogMjBweDtcbiAgICB6LWluZGV4OiAxLjU7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwLjcpO1xuICAgIGNvbG9yOiAjZmZmO1xuICAgIGJvcmRlcjogbm9uZTtcbiAgICBwYWRkaW5nOiAxMHB4O1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICBmb250LXNpemU6IDE2cHg7XG59XG5cbm1haW4ge1xuICAgIGRpc3BsYXk6IGdyaWQ7XG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgIGdyaWQtdGVtcGxhdGU6IGNhbGMoMTAwdmggLSAxNzBweCkgMzAwcHggMzAwcHggNTAwcHggNTAwcHggLyAxZnI7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tY3JlYW15LXdoaXRlKTtcblxuICAgIGRpdiB7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgIH1cblxuICAgID4gZGl2Om50aC1jaGlsZChldmVuKSB7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWltcGVyaWFsLXJlZCk7XG5cbiAgICAgICAgciB7XG4gICAgICAgICAgICBjb2xvcjogdmFyKC0tY3JlYW15LXdoaXRlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgICN3aG9XZUFyZSB7XG4gICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcblxuICAgICAgICB2aWRlbyB7XG4gICAgICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgICAgICB0b3A6IDA7XG4gICAgICAgICAgICBsZWZ0OiAwO1xuICAgICAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICAgICAgICBvYmplY3QtZml0OiBjb3ZlcjtcbiAgICAgICAgICAgIHotaW5kZXg6IDA7XG4gICAgICAgIH1cblxuICAgICAgICBoMiB7XG4gICAgICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgICAgICB6LWluZGV4OiAxO1xuICAgICAgICAgICAgcGFkZGluZzogMTVweCAwO1xuICAgICAgICAgICAgY29sb3I6ICNmZmY7XG5cbiAgICAgICAgICAgIDo6YmVmb3JlIHtcbiAgICAgICAgICAgICAgICBjb250ZW50OiBcIlwiOyAvKiBSZXF1aXJlZCBmb3IgcHNldWRvLWVsZW1lbnRzICovXG4gICAgICAgICAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICAgICAgICAgIHRvcDogMDtcbiAgICAgICAgICAgICAgICBsZWZ0OiAwO1xuICAgICAgICAgICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICAgICAgICAgIGhlaWdodDogMTAwJTtcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwMDAwNjY7XG4gICAgICAgICAgICAgICAgZmlsdGVyOiBibHVyKDMwcHgpO1xuICAgICAgICAgICAgICAgIHotaW5kZXg6IC0xOyAvKiBFbnN1cmUgaXQgaXMgYmVoaW5kIHRoZSBhY3R1YWwgY29udGVudCAqL1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaW1nIHtcbiAgICAgICAgICAgIGhlaWdodDogMzBweDtcbiAgICAgICAgICAgIHdpZHRoOiAzMHB4O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLmFuaW1hdGlvbiB7XG5cbiAgICAgICAgZm9udC1zaXplOiBsYXJnZTtcbiAgICAgICAgXG4gICAgICAgICNjb250cm9jb3JvVGV4dCB7XG4gICAgICAgICAgICBwYWRkaW5nLXRvcDogMHB4O1xuICAgICAgICAgICAgZm9udC1zaXplOiB4LWxhcmdlO1xuICAgICAgICAgICAgZm9udC13ZWlnaHQ6IDcwMDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgICNxdWFudGksICNjaGFydENvbnRhaW5lciB7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICAgIGdhcDogMjVweDtcbiAgICB9XG5cbiAgICAjY291bnR1cCB7XG4gICAgICAgIGZvbnQtc2l6ZTogeHh4LWxhcmdlO1xuICAgICAgICBmb250LXdlaWdodDogNzAwO1xuICAgICAgICBsZXR0ZXItc3BhY2luZzogMi41cHg7XG4gICAgfVxuXG4gICAgI2NoYXJ0Q29udGFpbmVyIHtcbiAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuXG4gICAgICAgIGgyIHtcbiAgICAgICAgICAgIHBhZGRpbmctdG9wOiAyMHB4XG4gICAgICAgIH1cblxuICAgICAgICBjYW52YXMge1xuICAgICAgICAgICAgaGVpZ2h0OiA1MCU7XG4gICAgICAgICAgICB3aWR0aDogNTAlO1xuICAgICAgICAgICAgcGFkZGluZzogMTBweCAyMHB4IDIwcHggMjBweDtcbiAgICAgICAgfVxuICAgIH1cblxufVxuXG4jY2hhcnRDb250YWluZXIge1xuICAgIHdpZHRoOiA3MCU7XG4gICAgbWF4LXdpZHRoOiA2MDBweDtcbn1cblxuZm9vdGVyIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgcG9zaXRpb246IHN0aWNreTtcbiAgICBib3R0b206IDA7XG5cbiAgICBkaXYge1xuICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICBmbGV4LWRpcmVjdGlvbjogcm93O1xuICAgICAgICBqdXN0aWZ5LWNvbnRlbnQ6Y2VudGVyO1xuICAgICAgICBnYXA6IDVweDtcbiAgICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgICAgY29sb3I6IHZhcigtLWNyZWFteS13aGl0ZSk7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWltcGVyaWFsLXJlZCk7XG4gICAgICAgIHBhZGRpbmc6IDEwcHggMCAwIDA7XG4gICAgXG4gICAgICAgIGEge1xuICAgICAgICAgICAgdGV4dC1kZWNvcmF0aW9uOiB1bmRlcmxpbmUgZG90dGVkO1xuICAgICAgICAgICAgY29sb3I6IHZhcigtLWVhcnRoLXllbGxvdyk7XG4gICAgICAgICAgICBmb250LXdlaWdodDogNjAwO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZGl2OmhhcyhzcGFuKSB7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgfVxufVxuXG5cblxuZm9vdGVyIGRpdjpsYXN0LWNoaWxkIHtcbiAgICBwYWRkaW5nLWJvdHRvbTogMTBweDtcbn1cblxuICAgIC5jb250YWN0cyB7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICAgIGdhcDogMThweDtcbiAgICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcblxuICAgICAgICBhIHtcbiAgICAgICAgICAgIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcbiAgICAgICAgICAgIGNvbG9yOiB2YXIoLS1jcmVhbXktd2hpdGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLmhhcm1vbnkge1xuICAgICAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgICAgIGZsZXgtZGlyZWN0aW9uOiByb3c7XG4gICAgICAgICAgICBnYXA6IDEwcHg7XG4gICAgICAgICAgICBwYWRkaW5nLWJvdHRvbTogMTBweDtcblxuICAgICAgICAgICAgc3ZnIHtcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IDQ1cHg7XG4gICAgICAgICAgICAgICAgd2lkdGg6IDQ1cHg7XG4gICAgICAgICAgICAgICAgcGFkZGluZy1sZWZ0OiAxNXB4O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLmNhcmQge1xuICAgICAgICAgICAgY3Vyc29yOiBwb2ludGVyO1xuXG4gICAgICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICAgICAgZmxleC1kaXJlY3Rpb246IHJvdztcbiAgICAgICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICAgICAgICBoZWlnaHQ6IDc1cHg7XG5cbiAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWFpci1mb3JjZS1ibHVlKTtcbiAgICAgICAgICAgIGNvbG9yOiB2YXIoLS1jcmVhbXktd2hpdGUpO1xuICAgICAgICAgICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICAgICAgICAgIGZvbnQtc2l6ZTogMTNweDtcblxuICAgICAgICAgICAgYm9yZGVyOiBub25lO1xuICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogMTBweDtcbiAgICAgICAgICAgIGJveC1zaGFkb3c6IC00cHggNXB4IDhweCAjMDAwMDAwMzY7XG5cblxuICAgICAgICAgICAgcGFkZGluZzogMCAxMHB4IDAgMTBweDtcblxuICAgICAgICAgICAgc3ZnLCBwYXRoIHtcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IDMwcHg7XG4gICAgICAgICAgICAgICAgd2lkdGg6IDMwcHg7XG4gICAgICAgICAgICAgICAgcGFkZGluZzogMCAxNXB4IDAgMTBweDtcbiAgICAgICAgICAgICAgICBmaWxsOiB2YXIoLS1jcmVhbXktd2hpdGUpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC5kZXRhaWxzIHtcbiAgICAgICAgICAgICAgICBwYWRkaW5nLXJpZ2h0OiAxNXB4O1xuICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgIC5kZXRhaWxzLmFkZHJlc3MgcDo6YmVmb3JlIHtcbiAgICAgICAgICAgICAgICBjb250ZW50OiBcIlZpYSBkaSBTLiBDcm9jZSBcXFxcQSBpbiBHZXJ1c2FsZW1tZSwgNTUgXFxcXGEgKFJvbWEsIFJNKSBjL28gU3BpbiBUaW1lXCI7XG4gICAgICAgICAgICAgICAgd2hpdGUtc3BhY2U6IHByZS13cmFwO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH1cblxuICAgICAgICAuY2FyZDpob3ZlciB7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6IHJnYigzNywgMTE3LCAxNDcpO1xuICAgICAgICAgICAgdHJhbnNpdGlvbjogYWxsIDAuNHMgZWFzZS1vdXQ7XG4gICAgICAgICAgICBib3gtc2hhZG93OiAtNnB4IDdweCA1cHggIzAwMDAwMDhmO1xuICAgICAgICB9XG5cbiAgICAgICAgLmlnIHtcbiAgICAgICAgICAgIGJhY2tncm91bmQ6ICM4MzNhYjQ7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoXG4gICAgICAgICAgICAgICAgdG8gcmlnaHQsXG4gICAgICAgICAgICAgICAgIzgzM2FiNCwjZmQxZDFkLCNmY2IwNDVcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHRyYW5zaXRpb246IGFsbCAwLjRzIGVhc2Utb3V0O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIC53YXBwIHtcbiAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXZlcmRlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC53YXBwOmhvdmVyIHtcbiAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6ICMzODk1Mzg7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIFxufVxuXG5AbWVkaWEgc2NyZWVuIGFuZCAobWluLXdpZHRoOiAxMDI0cHgpIHtcbiBoZWFkZXIge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47O1xuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWltcGVyaWFsLXJlZCk7XG4gICAgY29sb3I6IHZhcigtLWNyZWFteS13aGl0ZSk7XG4gICAgcG9zaXRpb246IHN0aWNreTtcbiAgICB0b3A6IDA7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiAxMDBweDtcbiAgICB6LWluZGV4OiAyO1xuXG4gICAgICAgIGgxIHtcbiAgICAgICAgICAgIHBhZGRpbmctbGVmdDogMzBweDtcbiAgICAgICAgICAgIGZvbnQtc2l6ZTogNDBweDtcbiAgICAgICAgfVxuXG4gICAgICAgIHN2ZyB7XG4gICAgICAgICAgICBoZWlnaHQ6IDcwcHg7XG4gICAgICAgICAgICB3aWR0aDogNzBweDtcbiAgICAgICAgICAgIHBhZGRpbmctcmlnaHQ6IDI1cHg7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIHBhdGgge1xuICAgICAgICAgICAgICAgIGZpbGw6IHZhcigtLWNyZWFteS13aGl0ZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfVxuXG4gICAgfVxuXG4gICAgLnVubXV0ZS1idXR0b24ge1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIGJvdHRvbTogMjBweDtcbiAgICAgICAgcmlnaHQ6IDIwcHg7XG4gICAgICAgIHotaW5kZXg6IDEuNTtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwLjcpO1xuICAgICAgICBjb2xvcjogI2ZmZjtcbiAgICAgICAgYm9yZGVyOiBub25lO1xuICAgICAgICBwYWRkaW5nOiAxMHB4O1xuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICAgIGZvbnQtc2l6ZTogMTZweDtcbiAgICB9XG5cbiAgICBtYWluIHtcbiAgICAgICAgZGlzcGxheTogZ3JpZDtcbiAgICAgICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgICAgICBncmlkLXRlbXBsYXRlOiBjYWxjKDEwMHZoIC0gMTcwcHgpIDMwMHB4IDMwMHB4IDUwMHB4IDUwMHB4IC8gMWZyO1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1jcmVhbXktd2hpdGUpO1xuXG4gICAgICAgIGRpdiB7XG4gICAgICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgICAgICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgICAgICB9XG5cbiAgICAgICAgPiBkaXY6bnRoLWNoaWxkKGV2ZW4pIHtcbiAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWltcGVyaWFsLXJlZCk7XG5cbiAgICAgICAgICAgIHIge1xuICAgICAgICAgICAgICAgIGNvbG9yOiB2YXIoLS1jcmVhbXktd2hpdGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgI3dob1dlQXJlIHtcbiAgICAgICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgICAgICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1qZXQpO1xuXG4gICAgICAgICAgICB2aWRlbyB7XG4gICAgICAgICAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICAgICAgICAgIHRvcDogMDtcbiAgICAgICAgICAgICAgICBsZWZ0OiAwO1xuICAgICAgICAgICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICAgICAgICAgIGhlaWdodDogMTAwJTtcbiAgICAgICAgICAgICAgICBvYmplY3QtZml0OnNjYWxlLWRvd247XG4gICAgICAgICAgICAgICAgei1pbmRleDogMDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaDIge1xuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgICAgICAgICAgICB6LWluZGV4OiAxO1xuICAgICAgICAgICAgICAgIHBhZGRpbmc6IDE1cHggMDtcbiAgICAgICAgICAgICAgICBjb2xvcjogI2ZmZjtcblxuICAgICAgICAgICAgICAgIDo6YmVmb3JlIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGVudDogXCJcIjsgLyogUmVxdWlyZWQgZm9yIHBzZXVkby1lbGVtZW50cyAqL1xuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgICAgICAgICAgICAgIHRvcDogMDtcbiAgICAgICAgICAgICAgICAgICAgbGVmdDogMDtcbiAgICAgICAgICAgICAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgICAgICAgICAgICAgIGhlaWdodDogMTAwJTtcbiAgICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogIzAwMDAwMDM2O1xuICAgICAgICAgICAgICAgICAgICBmaWx0ZXI6IGJsdXIoMzBweCk7XG4gICAgICAgICAgICAgICAgICAgIHotaW5kZXg6IC0xOyAvKiBFbnN1cmUgaXQgaXMgYmVoaW5kIHRoZSBhY3R1YWwgY29udGVudCAqL1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaW1nIHtcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IDMwcHg7XG4gICAgICAgICAgICAgICAgd2lkdGg6IDMwcHg7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAuYW5pbWF0aW9uIHtcblxuICAgICAgICAgICAgZm9udC1zaXplOiB4eC1sYXJnZTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgI2NvbnRyb2Nvcm9UZXh0IHtcbiAgICAgICAgICAgICAgICBwYWRkaW5nLXRvcDogMHB4O1xuICAgICAgICAgICAgICAgIGZvbnQtc2l6ZTogeHh4LWxhcmdlO1xuICAgICAgICAgICAgICAgIGZvbnQtd2VpZ2h0OiA3MDA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAjcXVhbnRpLCAjY2hhcnRDb250YWluZXIge1xuICAgICAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICAgICAgICBnYXA6IDI1cHg7XG4gICAgICAgIH1cblxuICAgICAgICAjcXVhbnRpIHtcbiAgICAgICAgICAgIGgyIHtcbiAgICAgICAgICAgIGZvbnQtc2l6ZTogeHgtbGFyZ2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAjY291bnR1cCB7XG4gICAgICAgICAgICBmb250LXNpemU6IHh4eC1sYXJnZTtcbiAgICAgICAgICAgIGZvbnQtd2VpZ2h0OiA3MDA7XG4gICAgICAgICAgICBsZXR0ZXItc3BhY2luZzogMi41cHg7XG4gICAgICAgIH1cblxuICAgICAgICAjY2hhcnRDb250YWluZXIge1xuICAgICAgICAgICAgd2lkdGg6IDEwMHZ3O1xuICAgICAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG5cbiAgICAgICAgICAgIGgyIHtcbiAgICAgICAgICAgICAgICBwYWRkaW5nLXRvcDogMjBweDtcbiAgICAgICAgICAgICAgICBmb250LXNpemU6MmVtO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYW52YXMge1xuICAgICAgICAgICAgICAgIG1heC1oZWlnaHQ6IDQwMHB4O1xuICAgICAgICAgICAgICAgIG1heC13aWR0aDogNDAwcHg7XG4gICAgICAgICAgICAgICAgcGFkZGluZzogMTBweCAyMHB4IDIwcHggMjBweDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgfVxuXG4gICAgZm9vdGVyIHtcbiAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgICAgcG9zaXRpb246IHN0aWNreTtcbiAgICAgICAgYm90dG9tOiAwO1xuICAgIH1cblxuICAgIGZvb3RlciBkaXYge1xuICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICBmbGV4LWRpcmVjdGlvbjogcm93O1xuICAgICAgICBqdXN0aWZ5LWNvbnRlbnQ6Y2VudGVyO1xuICAgICAgICBnYXA6IDVweDtcbiAgICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgICAgY29sb3I6IHZhcigtLWNyZWFteS13aGl0ZSk7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWltcGVyaWFsLXJlZCk7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICBwYWRkaW5nOiAxMHB4IDAgMCAwO1xuXG4gICAgICAgIGEge1xuICAgICAgICAgICAgdGV4dC1kZWNvcmF0aW9uOiB1bmRlcmxpbmUgZG90dGVkO1xuICAgICAgICAgICAgY29sb3I6IHZhcigtLWVhcnRoLXllbGxvdyk7XG4gICAgICAgICAgICBmb250LXdlaWdodDogNjAwO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZm9vdGVyIGRpdjpsYXN0LWNoaWxkIHtcbiAgICAgICAgcGFkZGluZy1ib3R0b206IDEwcHg7XG4gICAgfVxuXG4gICAgLmNvbnRhY3RzIHtcbiAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgICAgZ2FwOiAxOHB4O1xuICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuXG4gICAgICAgIGEge1xuICAgICAgICAgICAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xuICAgICAgICAgICAgY29sb3I6IHZhcigtLWNyZWFteS13aGl0ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAuaGFybW9ueSB7XG4gICAgICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICAgICAgZmxleC1kaXJlY3Rpb246IHJvdztcbiAgICAgICAgICAgIGdhcDogMTBweDtcbiAgICAgICAgICAgIHBhZGRpbmctYm90dG9tOiAxMHB4O1xuXG4gICAgICAgICAgICBoMiB7XG4gICAgICAgICAgICAgICAgZm9udC1zaXplOiA0MHB4O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzdmcge1xuICAgICAgICAgICAgICAgIGhlaWdodDogNjBweDtcbiAgICAgICAgICAgICAgICB3aWR0aDogNjBweDtcbiAgICAgICAgICAgICAgICBhbGlnbi1zZWxmOiBmbGV4LWVuZDtcbiAgICAgICAgICAgICAgICBwYWRkaW5nLWxlZnQ6IDE4cHg7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAuY2FyZCB7XG4gICAgICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XG5cbiAgICAgICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgICAgICBmbGV4LWRpcmVjdGlvbjogcm93O1xuICAgICAgICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgICAgICAgIGhlaWdodDogNzVweDtcblxuICAgICAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tYWlyLWZvcmNlLWJsdWUpO1xuICAgICAgICAgICAgY29sb3I6IHZhcigtLWNyZWFteS13aGl0ZSk7XG4gICAgICAgICAgICBmb250LXdlaWdodDogNjAwO1xuXG4gICAgICAgICAgICBib3JkZXI6IG5vbmU7XG4gICAgICAgICAgICBib3JkZXItcmFkaXVzOiAxMHB4O1xuICAgICAgICAgICAgYm94LXNoYWRvdzogLTRweCA1cHggOHB4ICMwMDAwMDAzNjtcblxuICAgICAgICAgICAgc3ZnLCBwYXRoIHtcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IDUwcHg7XG4gICAgICAgICAgICAgICAgd2lkdGg6IDUwcHg7XG4gICAgICAgICAgICAgICAgcGFkZGluZzogMCAxMHB4IDAgMTBweDtcbiAgICAgICAgICAgICAgICBmaWxsOiB2YXIoLS1jcmVhbXktd2hpdGUpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC5kZXRhaWxzIHtcbiAgICAgICAgICAgICAgICB3aWR0aDogNDAwcHg7XG4gICAgICAgICAgICAgICAgZm9udC1zaXplOiBsYXJnZXI7XG4gICAgICAgICAgICAgICAgcGFkZGluZy1yaWdodDogMTVweDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLmRldGFpbHMuYWRkcmVzcyBwOjpiZWZvcmUge1xuICAgICAgICAgICAgICAgIGNvbnRlbnQ6IFwiVmlhIGRpIFMuIENyb2NlIGluIEdlcnVzYWxlbW1lLCA1NSAoUm9tYSwgUk0pIGMvbyBTcGluIFRpbWVcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC5jYXJkOmhvdmVyIHtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogcmdiKDM3LCAxMTcsIDE0Nyk7XG4gICAgICAgICAgICB0cmFuc2l0aW9uOiBhbGwgMC40cyBlYXNlLW91dDtcbiAgICAgICAgICAgIGJveC1zaGFkb3c6IC02cHggN3B4IDVweCAjMDAwMDAwOGY7XG4gICAgICAgIH1cblxuICAgICAgICAuaWcge1xuICAgICAgICAgICAgYmFja2dyb3VuZDogIzgzM2FiNDtcbiAgICAgICAgICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudChcbiAgICAgICAgICAgICAgICB0byByaWdodCxcbiAgICAgICAgICAgICAgICAjODMzYWI0LCNmZDFkMWQsI2ZjYjA0NVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgdHJhbnNpdGlvbjogYWxsIDAuNHMgZWFzZS1vdXQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgLndhcHAge1xuICAgICAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tdmVyZGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLndhcHA6aG92ZXIge1xuICAgICAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogIzM4OTUzODtcbiAgICAgICAgfVxuICAgIH1cbn1gLCBcIlwiLHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltcIndlYnBhY2s6Ly8uL3NyYy9zdHlsZXMuY3NzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJBQUFBO0lBQ0ksdUJBQXVCO0lBQ3ZCLDRDQUF5RDtBQUM3RDs7QUFFQTtJQUNJLHlCQUF5QjtJQUN6QixnQkFBZ0I7SUFDaEIsa0NBQWtDO0lBQ2xDLHlCQUF5QjtJQUN6QiwyQkFBMkI7SUFDM0IsZ0JBQWdCO0FBQ3BCOztBQUVBO0lBQ0ksK0pBQStKO0FBQ25L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bnRcIjpbXCJAZm9udC1mYWNlIHtcXG4gICAgZm9udC1mYW1pbHk6IE1vbnRzZXJyYXQ7XFxuICAgIHNyYzogdXJsKC4vYXNzZXRzL2ZvbnRzL01vbnRzZXJyYXQtVmFyaWFibGVGb250X3dnaHQudHRmKTtcXG59XFxuXFxuOnJvb3Qge1xcbiAgICAtLWltcGVyaWFsLXJlZDogI2U0M2IzYmZmO1xcbiAgICAtLWpldDogIzJjMmMyY2ZmO1xcbiAgICAtLWNyZWFteS13aGl0ZTogcmdiKDI1NSwgMjUzLCAyMzkpO1xcbiAgICAtLWVhcnRoLXllbGxvdzogI2RiYTE1OWZmO1xcbiAgICAtLWFpci1mb3JjZS1ibHVlOiAjNTY4ZWEzZmY7XFxuICAgIC0tdmVyZGU6ICM1ZmI3NWY7XFxufVxcblxcbmh0bWwge1xcbiAgICBmb250LWZhbWlseTogTW9udHNlcnJhdCwgc3lzdGVtLXVpLCAtYXBwbGUtc3lzdGVtLCBCbGlua01hY1N5c3RlbUZvbnQsICdTZWdvZSBVSScsIFJvYm90bywgT3h5Z2VuLCBVYnVudHUsIENhbnRhcmVsbCwgJ09wZW4gU2FucycsICdIZWx2ZXRpY2EgTmV1ZScsIHNhbnMtc2VyaWY7XFxufVxcblxcbmgxLCBoMiwgaDMsIGg0LCBoNSwgaDYge1xcbiAgICBtYXJnaW46IDA7XFxufVxcblxcbkBrZXlmcmFtZXMgZmFkZUluIHtcXG4gICAgMCUge1xcbiAgICAgICAgb3BhY2l0eTogMDtcXG4gICAgfVxcbiAgICAxMDAlIHtcXG4gICAgICAgIG9wYWNpdHk6IDE7XFxuICAgIH1cXG59XFxuXFxuLmZhZGVpbiB7XFxuICAgIG9wYWNpdHk6IDA7XFxuICAgIHRyYW5zaXRpb246IG9wYWNpdHkgMS41cyBlYXNlLWluLW91dDtcXG59XFxuXFxuciB7XFxuICAgIGRpc3BsYXk6IGlubGluZTtcXG4gICAgY29sb3I6IHZhcigtLWltcGVyaWFsLXJlZCk7XFxuICAgIGZvbnQtd2VpZ2h0OiA3MDA7XFxufVxcblxcbmhlYWRlciB7XFxuICAgIGJveC1zaGFkb3c6IDBweCA1cHggMThweCAtNnB4IHJnYmEoMCwwLDAsMC43NSk7XFxufVxcblxcbmZvb3RlciB7XFxuICAgIGJveC1zaGFkb3c6IDBweCAtNXB4IDE4cHggLTZweCByZ2JhKDAsMCwwLDAuNzUpO1xcbn1cXG5cXG5AbWVkaWEgb25seSBzY3JlZW4gYW5kXFxuICAgIChtYXgtd2lkdGg6IDc2OHB4KSB7XFxuXFxuICAgIGhlYWRlciB7XFxuICAgIGRpc3BsYXk6IGZsZXg7XFxuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XFxuICAgIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2Vlbjs7XFxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWltcGVyaWFsLXJlZCk7XFxuICAgIGNvbG9yOiB2YXIoLS1jcmVhbXktd2hpdGUpO1xcbiAgICBwb3NpdGlvbjogc3RpY2t5O1xcbiAgICB0b3A6IDA7XFxuICAgIHdpZHRoOiAxMDAlO1xcbiAgICBoZWlnaHQ6IDEwMHB4O1xcbiAgICB6LWluZGV4OiAyO1xcblxcbiAgICBoMSB7XFxuICAgICAgICBwYWRkaW5nLWxlZnQ6IDI1cHg7XFxuICAgIH1cXG5cXG4gICAgc3ZnIHtcXG4gICAgICAgIGhlaWdodDogNzBweDtcXG4gICAgICAgIHdpZHRoOiA3MHB4O1xcbiAgICAgICAgcGFkZGluZy1yaWdodDogMjVweDtcXG4gICAgICAgIFxcbiAgICAgICAgcGF0aCB7XFxuICAgICAgICAgICAgZmlsbDogdmFyKC0tY3JlYW15LXdoaXRlKTtcXG4gICAgICAgIH1cXG5cXG4gICAgfVxcblxcbn1cXG5cXG4udW5tdXRlLWJ1dHRvbiB7XFxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gICAgYm90dG9tOiAyMHB4O1xcbiAgICByaWdodDogMjBweDtcXG4gICAgei1pbmRleDogMS41O1xcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuNyk7XFxuICAgIGNvbG9yOiAjZmZmO1xcbiAgICBib3JkZXI6IG5vbmU7XFxuICAgIHBhZGRpbmc6IDEwcHg7XFxuICAgIGN1cnNvcjogcG9pbnRlcjtcXG4gICAgZm9udC1zaXplOiAxNnB4O1xcbn1cXG5cXG5tYWluIHtcXG4gICAgZGlzcGxheTogZ3JpZDtcXG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xcbiAgICBncmlkLXRlbXBsYXRlOiBjYWxjKDEwMHZoIC0gMTcwcHgpIDMwMHB4IDMwMHB4IDUwMHB4IDUwMHB4IC8gMWZyO1xcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1jcmVhbXktd2hpdGUpO1xcblxcbiAgICBkaXYge1xcbiAgICAgICAgZGlzcGxheTogZmxleDtcXG4gICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XFxuICAgICAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcXG4gICAgfVxcblxcbiAgICA+IGRpdjpudGgtY2hpbGQoZXZlbikge1xcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0taW1wZXJpYWwtcmVkKTtcXG5cXG4gICAgICAgIHIge1xcbiAgICAgICAgICAgIGNvbG9yOiB2YXIoLS1jcmVhbXktd2hpdGUpO1xcbiAgICAgICAgfVxcbiAgICB9XFxuXFxuICAgICN3aG9XZUFyZSB7XFxuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XFxuICAgICAgICBvdmVyZmxvdzogaGlkZGVuO1xcblxcbiAgICAgICAgdmlkZW8ge1xcbiAgICAgICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gICAgICAgICAgICB0b3A6IDA7XFxuICAgICAgICAgICAgbGVmdDogMDtcXG4gICAgICAgICAgICB3aWR0aDogMTAwJTtcXG4gICAgICAgICAgICBoZWlnaHQ6IDEwMCU7XFxuICAgICAgICAgICAgb2JqZWN0LWZpdDogY292ZXI7XFxuICAgICAgICAgICAgei1pbmRleDogMDtcXG4gICAgICAgIH1cXG5cXG4gICAgICAgIGgyIHtcXG4gICAgICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XFxuICAgICAgICAgICAgei1pbmRleDogMTtcXG4gICAgICAgICAgICBwYWRkaW5nOiAxNXB4IDA7XFxuICAgICAgICAgICAgY29sb3I6ICNmZmY7XFxuXFxuICAgICAgICAgICAgOjpiZWZvcmUge1xcbiAgICAgICAgICAgICAgICBjb250ZW50OiBcXFwiXFxcIjsgLyogUmVxdWlyZWQgZm9yIHBzZXVkby1lbGVtZW50cyAqL1xcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICAgICAgICAgICAgICAgIHRvcDogMDtcXG4gICAgICAgICAgICAgICAgbGVmdDogMDtcXG4gICAgICAgICAgICAgICAgd2lkdGg6IDEwMCU7XFxuICAgICAgICAgICAgICAgIGhlaWdodDogMTAwJTtcXG4gICAgICAgICAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogIzAwMDAwMDY2O1xcbiAgICAgICAgICAgICAgICBmaWx0ZXI6IGJsdXIoMzBweCk7XFxuICAgICAgICAgICAgICAgIHotaW5kZXg6IC0xOyAvKiBFbnN1cmUgaXQgaXMgYmVoaW5kIHRoZSBhY3R1YWwgY29udGVudCAqL1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgIH1cXG5cXG4gICAgICAgIGltZyB7XFxuICAgICAgICAgICAgaGVpZ2h0OiAzMHB4O1xcbiAgICAgICAgICAgIHdpZHRoOiAzMHB4O1xcbiAgICAgICAgfVxcbiAgICB9XFxuXFxuICAgIC5hbmltYXRpb24ge1xcblxcbiAgICAgICAgZm9udC1zaXplOiBsYXJnZTtcXG4gICAgICAgIFxcbiAgICAgICAgI2NvbnRyb2Nvcm9UZXh0IHtcXG4gICAgICAgICAgICBwYWRkaW5nLXRvcDogMHB4O1xcbiAgICAgICAgICAgIGZvbnQtc2l6ZTogeC1sYXJnZTtcXG4gICAgICAgICAgICBmb250LXdlaWdodDogNzAwO1xcbiAgICAgICAgfVxcbiAgICB9XFxuXFxuICAgICNxdWFudGksICNjaGFydENvbnRhaW5lciB7XFxuICAgICAgICBkaXNwbGF5OiBmbGV4O1xcbiAgICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcXG4gICAgICAgIGdhcDogMjVweDtcXG4gICAgfVxcblxcbiAgICAjY291bnR1cCB7XFxuICAgICAgICBmb250LXNpemU6IHh4eC1sYXJnZTtcXG4gICAgICAgIGZvbnQtd2VpZ2h0OiA3MDA7XFxuICAgICAgICBsZXR0ZXItc3BhY2luZzogMi41cHg7XFxuICAgIH1cXG5cXG4gICAgI2NoYXJ0Q29udGFpbmVyIHtcXG4gICAgICAgIHdpZHRoOiAxMDAlO1xcbiAgICAgICAgZGlzcGxheTogZmxleDtcXG4gICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XFxuICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xcbiAgICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XFxuXFxuICAgICAgICBoMiB7XFxuICAgICAgICAgICAgcGFkZGluZy10b3A6IDIwcHhcXG4gICAgICAgIH1cXG5cXG4gICAgICAgIGNhbnZhcyB7XFxuICAgICAgICAgICAgaGVpZ2h0OiA1MCU7XFxuICAgICAgICAgICAgd2lkdGg6IDUwJTtcXG4gICAgICAgICAgICBwYWRkaW5nOiAxMHB4IDIwcHggMjBweCAyMHB4O1xcbiAgICAgICAgfVxcbiAgICB9XFxuXFxufVxcblxcbiNjaGFydENvbnRhaW5lciB7XFxuICAgIHdpZHRoOiA3MCU7XFxuICAgIG1heC13aWR0aDogNjAwcHg7XFxufVxcblxcbmZvb3RlciB7XFxuICAgIGRpc3BsYXk6IGZsZXg7XFxuICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XFxuICAgIHBvc2l0aW9uOiBzdGlja3k7XFxuICAgIGJvdHRvbTogMDtcXG5cXG4gICAgZGl2IHtcXG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XFxuICAgICAgICBmbGV4LWRpcmVjdGlvbjogcm93O1xcbiAgICAgICAganVzdGlmeS1jb250ZW50OmNlbnRlcjtcXG4gICAgICAgIGdhcDogNXB4O1xcbiAgICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcXG4gICAgICAgIGNvbG9yOiB2YXIoLS1jcmVhbXktd2hpdGUpO1xcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0taW1wZXJpYWwtcmVkKTtcXG4gICAgICAgIHBhZGRpbmc6IDEwcHggMCAwIDA7XFxuICAgIFxcbiAgICAgICAgYSB7XFxuICAgICAgICAgICAgdGV4dC1kZWNvcmF0aW9uOiB1bmRlcmxpbmUgZG90dGVkO1xcbiAgICAgICAgICAgIGNvbG9yOiB2YXIoLS1lYXJ0aC15ZWxsb3cpO1xcbiAgICAgICAgICAgIGZvbnQtd2VpZ2h0OiA2MDA7XFxuICAgICAgICB9XFxuICAgIH1cXG5cXG4gICAgZGl2OmhhcyhzcGFuKSB7XFxuICAgICAgICBkaXNwbGF5OiBmbGV4O1xcbiAgICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcXG4gICAgfVxcbn1cXG5cXG5cXG5cXG5mb290ZXIgZGl2Omxhc3QtY2hpbGQge1xcbiAgICBwYWRkaW5nLWJvdHRvbTogMTBweDtcXG59XFxuXFxuICAgIC5jb250YWN0cyB7XFxuICAgICAgICBkaXNwbGF5OiBmbGV4O1xcbiAgICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcXG4gICAgICAgIGdhcDogMThweDtcXG4gICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XFxuXFxuICAgICAgICBhIHtcXG4gICAgICAgICAgICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XFxuICAgICAgICAgICAgY29sb3I6IHZhcigtLWNyZWFteS13aGl0ZSk7XFxuICAgICAgICB9XFxuXFxuICAgICAgICAuaGFybW9ueSB7XFxuICAgICAgICAgICAgZGlzcGxheTogZmxleDtcXG4gICAgICAgICAgICBmbGV4LWRpcmVjdGlvbjogcm93O1xcbiAgICAgICAgICAgIGdhcDogMTBweDtcXG4gICAgICAgICAgICBwYWRkaW5nLWJvdHRvbTogMTBweDtcXG5cXG4gICAgICAgICAgICBzdmcge1xcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IDQ1cHg7XFxuICAgICAgICAgICAgICAgIHdpZHRoOiA0NXB4O1xcbiAgICAgICAgICAgICAgICBwYWRkaW5nLWxlZnQ6IDE1cHg7XFxuICAgICAgICAgICAgfVxcbiAgICAgICAgfVxcblxcbiAgICAgICAgLmNhcmQge1xcbiAgICAgICAgICAgIGN1cnNvcjogcG9pbnRlcjtcXG5cXG4gICAgICAgICAgICBkaXNwbGF5OiBmbGV4O1xcbiAgICAgICAgICAgIGZsZXgtZGlyZWN0aW9uOiByb3c7XFxuICAgICAgICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcXG4gICAgICAgICAgICBoZWlnaHQ6IDc1cHg7XFxuXFxuICAgICAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tYWlyLWZvcmNlLWJsdWUpO1xcbiAgICAgICAgICAgIGNvbG9yOiB2YXIoLS1jcmVhbXktd2hpdGUpO1xcbiAgICAgICAgICAgIGZvbnQtd2VpZ2h0OiA2MDA7XFxuICAgICAgICAgICAgZm9udC1zaXplOiAxM3B4O1xcblxcbiAgICAgICAgICAgIGJvcmRlcjogbm9uZTtcXG4gICAgICAgICAgICBib3JkZXItcmFkaXVzOiAxMHB4O1xcbiAgICAgICAgICAgIGJveC1zaGFkb3c6IC00cHggNXB4IDhweCAjMDAwMDAwMzY7XFxuXFxuXFxuICAgICAgICAgICAgcGFkZGluZzogMCAxMHB4IDAgMTBweDtcXG5cXG4gICAgICAgICAgICBzdmcsIHBhdGgge1xcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IDMwcHg7XFxuICAgICAgICAgICAgICAgIHdpZHRoOiAzMHB4O1xcbiAgICAgICAgICAgICAgICBwYWRkaW5nOiAwIDE1cHggMCAxMHB4O1xcbiAgICAgICAgICAgICAgICBmaWxsOiB2YXIoLS1jcmVhbXktd2hpdGUpXFxuICAgICAgICAgICAgfVxcblxcbiAgICAgICAgICAgIC5kZXRhaWxzIHtcXG4gICAgICAgICAgICAgICAgcGFkZGluZy1yaWdodDogMTVweDtcXG4gICAgICAgICAgICB9XFxuXFxuXFxuICAgICAgICAgICAgLmRldGFpbHMuYWRkcmVzcyBwOjpiZWZvcmUge1xcbiAgICAgICAgICAgICAgICBjb250ZW50OiBcXFwiVmlhIGRpIFMuIENyb2NlIFxcXFxBIGluIEdlcnVzYWxlbW1lLCA1NSBcXFxcYSAoUm9tYSwgUk0pIGMvbyBTcGluIFRpbWVcXFwiO1xcbiAgICAgICAgICAgICAgICB3aGl0ZS1zcGFjZTogcHJlLXdyYXA7XFxuICAgICAgICAgICAgfVxcblxcbiAgICAgICAgfVxcblxcbiAgICAgICAgLmNhcmQ6aG92ZXIge1xcbiAgICAgICAgICAgIFxcbiAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6IHJnYigzNywgMTE3LCAxNDcpO1xcbiAgICAgICAgICAgIHRyYW5zaXRpb246IGFsbCAwLjRzIGVhc2Utb3V0O1xcbiAgICAgICAgICAgIGJveC1zaGFkb3c6IC02cHggN3B4IDVweCAjMDAwMDAwOGY7XFxuICAgICAgICB9XFxuXFxuICAgICAgICAuaWcge1xcbiAgICAgICAgICAgIGJhY2tncm91bmQ6ICM4MzNhYjQ7XFxuICAgICAgICAgICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KFxcbiAgICAgICAgICAgICAgICB0byByaWdodCxcXG4gICAgICAgICAgICAgICAgIzgzM2FiNCwjZmQxZDFkLCNmY2IwNDVcXG4gICAgICAgICAgICAgICAgKTtcXG4gICAgICAgICAgICAgICAgdHJhbnNpdGlvbjogYWxsIDAuNHMgZWFzZS1vdXQ7XFxuICAgICAgICAgICAgfVxcblxcbiAgICAgICAgLndhcHAge1xcbiAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXZlcmRlKTtcXG4gICAgICAgIH1cXG5cXG4gICAgICAgIC53YXBwOmhvdmVyIHtcXG4gICAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjMzg5NTM4O1xcbiAgICAgICAgfVxcbiAgICB9XFxuXFxuXFxuICAgIFxcbn1cXG5cXG5AbWVkaWEgc2NyZWVuIGFuZCAobWluLXdpZHRoOiAxMDI0cHgpIHtcXG4gaGVhZGVyIHtcXG4gICAgZGlzcGxheTogZmxleDtcXG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcXG4gICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuOztcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0taW1wZXJpYWwtcmVkKTtcXG4gICAgY29sb3I6IHZhcigtLWNyZWFteS13aGl0ZSk7XFxuICAgIHBvc2l0aW9uOiBzdGlja3k7XFxuICAgIHRvcDogMDtcXG4gICAgd2lkdGg6IDEwMCU7XFxuICAgIGhlaWdodDogMTAwcHg7XFxuICAgIHotaW5kZXg6IDI7XFxuXFxuICAgICAgICBoMSB7XFxuICAgICAgICAgICAgcGFkZGluZy1sZWZ0OiAzMHB4O1xcbiAgICAgICAgICAgIGZvbnQtc2l6ZTogNDBweDtcXG4gICAgICAgIH1cXG5cXG4gICAgICAgIHN2ZyB7XFxuICAgICAgICAgICAgaGVpZ2h0OiA3MHB4O1xcbiAgICAgICAgICAgIHdpZHRoOiA3MHB4O1xcbiAgICAgICAgICAgIHBhZGRpbmctcmlnaHQ6IDI1cHg7XFxuICAgICAgICAgICAgXFxuICAgICAgICAgICAgcGF0aCB7XFxuICAgICAgICAgICAgICAgIGZpbGw6IHZhcigtLWNyZWFteS13aGl0ZSk7XFxuICAgICAgICAgICAgfVxcblxcbiAgICAgICAgfVxcblxcbiAgICB9XFxuXFxuICAgIC51bm11dGUtYnV0dG9uIHtcXG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gICAgICAgIGJvdHRvbTogMjBweDtcXG4gICAgICAgIHJpZ2h0OiAyMHB4O1xcbiAgICAgICAgei1pbmRleDogMS41O1xcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwLjcpO1xcbiAgICAgICAgY29sb3I6ICNmZmY7XFxuICAgICAgICBib3JkZXI6IG5vbmU7XFxuICAgICAgICBwYWRkaW5nOiAxMHB4O1xcbiAgICAgICAgY3Vyc29yOiBwb2ludGVyO1xcbiAgICAgICAgZm9udC1zaXplOiAxNnB4O1xcbiAgICB9XFxuXFxuICAgIG1haW4ge1xcbiAgICAgICAgZGlzcGxheTogZ3JpZDtcXG4gICAgICAgIHRleHQtYWxpZ246IGNlbnRlcjtcXG4gICAgICAgIGdyaWQtdGVtcGxhdGU6IGNhbGMoMTAwdmggLSAxNzBweCkgMzAwcHggMzAwcHggNTAwcHggNTAwcHggLyAxZnI7XFxuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1jcmVhbXktd2hpdGUpO1xcblxcbiAgICAgICAgZGl2IHtcXG4gICAgICAgICAgICBkaXNwbGF5OiBmbGV4O1xcbiAgICAgICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XFxuICAgICAgICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XFxuICAgICAgICB9XFxuXFxuICAgICAgICA+IGRpdjpudGgtY2hpbGQoZXZlbikge1xcbiAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWltcGVyaWFsLXJlZCk7XFxuXFxuICAgICAgICAgICAgciB7XFxuICAgICAgICAgICAgICAgIGNvbG9yOiB2YXIoLS1jcmVhbXktd2hpdGUpO1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgIH1cXG5cXG4gICAgICAgICN3aG9XZUFyZSB7XFxuICAgICAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xcbiAgICAgICAgICAgIG92ZXJmbG93OiBoaWRkZW47XFxuICAgICAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tamV0KTtcXG5cXG4gICAgICAgICAgICB2aWRlbyB7XFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gICAgICAgICAgICAgICAgdG9wOiAwO1xcbiAgICAgICAgICAgICAgICBsZWZ0OiAwO1xcbiAgICAgICAgICAgICAgICB3aWR0aDogMTAwJTtcXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiAxMDAlO1xcbiAgICAgICAgICAgICAgICBvYmplY3QtZml0OnNjYWxlLWRvd247XFxuICAgICAgICAgICAgICAgIHotaW5kZXg6IDA7XFxuICAgICAgICAgICAgfVxcblxcbiAgICAgICAgICAgIGgyIHtcXG4gICAgICAgICAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xcbiAgICAgICAgICAgICAgICB6LWluZGV4OiAxO1xcbiAgICAgICAgICAgICAgICBwYWRkaW5nOiAxNXB4IDA7XFxuICAgICAgICAgICAgICAgIGNvbG9yOiAjZmZmO1xcblxcbiAgICAgICAgICAgICAgICA6OmJlZm9yZSB7XFxuICAgICAgICAgICAgICAgICAgICBjb250ZW50OiBcXFwiXFxcIjsgLyogUmVxdWlyZWQgZm9yIHBzZXVkby1lbGVtZW50cyAqL1xcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgICAgICAgICAgICAgICAgICAgdG9wOiAwO1xcbiAgICAgICAgICAgICAgICAgICAgbGVmdDogMDtcXG4gICAgICAgICAgICAgICAgICAgIHdpZHRoOiAxMDAlO1xcbiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiAxMDAlO1xcbiAgICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogIzAwMDAwMDM2O1xcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyOiBibHVyKDMwcHgpO1xcbiAgICAgICAgICAgICAgICAgICAgei1pbmRleDogLTE7IC8qIEVuc3VyZSBpdCBpcyBiZWhpbmQgdGhlIGFjdHVhbCBjb250ZW50ICovXFxuICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICB9XFxuXFxuICAgICAgICAgICAgaW1nIHtcXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiAzMHB4O1xcbiAgICAgICAgICAgICAgICB3aWR0aDogMzBweDtcXG4gICAgICAgICAgICB9XFxuICAgICAgICB9XFxuXFxuICAgICAgICAuYW5pbWF0aW9uIHtcXG5cXG4gICAgICAgICAgICBmb250LXNpemU6IHh4LWxhcmdlO1xcbiAgICAgICAgICAgIFxcbiAgICAgICAgICAgICNjb250cm9jb3JvVGV4dCB7XFxuICAgICAgICAgICAgICAgIHBhZGRpbmctdG9wOiAwcHg7XFxuICAgICAgICAgICAgICAgIGZvbnQtc2l6ZTogeHh4LWxhcmdlO1xcbiAgICAgICAgICAgICAgICBmb250LXdlaWdodDogNzAwO1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgIH1cXG5cXG4gICAgICAgICNxdWFudGksICNjaGFydENvbnRhaW5lciB7XFxuICAgICAgICAgICAgZGlzcGxheTogZmxleDtcXG4gICAgICAgICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xcbiAgICAgICAgICAgIGdhcDogMjVweDtcXG4gICAgICAgIH1cXG5cXG4gICAgICAgICNxdWFudGkge1xcbiAgICAgICAgICAgIGgyIHtcXG4gICAgICAgICAgICBmb250LXNpemU6IHh4LWxhcmdlO1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgIH1cXG5cXG4gICAgICAgICNjb3VudHVwIHtcXG4gICAgICAgICAgICBmb250LXNpemU6IHh4eC1sYXJnZTtcXG4gICAgICAgICAgICBmb250LXdlaWdodDogNzAwO1xcbiAgICAgICAgICAgIGxldHRlci1zcGFjaW5nOiAyLjVweDtcXG4gICAgICAgIH1cXG5cXG4gICAgICAgICNjaGFydENvbnRhaW5lciB7XFxuICAgICAgICAgICAgd2lkdGg6IDEwMHZ3O1xcbiAgICAgICAgICAgIGRpc3BsYXk6IGZsZXg7XFxuICAgICAgICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcXG4gICAgICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xcbiAgICAgICAgICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xcblxcbiAgICAgICAgICAgIGgyIHtcXG4gICAgICAgICAgICAgICAgcGFkZGluZy10b3A6IDIwcHg7XFxuICAgICAgICAgICAgICAgIGZvbnQtc2l6ZToyZW07XFxuICAgICAgICAgICAgfVxcblxcbiAgICAgICAgICAgIGNhbnZhcyB7XFxuICAgICAgICAgICAgICAgIG1heC1oZWlnaHQ6IDQwMHB4O1xcbiAgICAgICAgICAgICAgICBtYXgtd2lkdGg6IDQwMHB4O1xcbiAgICAgICAgICAgICAgICBwYWRkaW5nOiAxMHB4IDIwcHggMjBweCAyMHB4O1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgIH1cXG5cXG4gICAgfVxcblxcbiAgICBmb290ZXIge1xcbiAgICAgICAgZGlzcGxheTogZmxleDtcXG4gICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XFxuICAgICAgICBwb3NpdGlvbjogc3RpY2t5O1xcbiAgICAgICAgYm90dG9tOiAwO1xcbiAgICB9XFxuXFxuICAgIGZvb3RlciBkaXYge1xcbiAgICAgICAgZGlzcGxheTogZmxleDtcXG4gICAgICAgIGZsZXgtZGlyZWN0aW9uOiByb3c7XFxuICAgICAgICBqdXN0aWZ5LWNvbnRlbnQ6Y2VudGVyO1xcbiAgICAgICAgZ2FwOiA1cHg7XFxuICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xcbiAgICAgICAgY29sb3I6IHZhcigtLWNyZWFteS13aGl0ZSk7XFxuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1pbXBlcmlhbC1yZWQpO1xcbiAgICAgICAgd2lkdGg6IDEwMCU7XFxuICAgICAgICBwYWRkaW5nOiAxMHB4IDAgMCAwO1xcblxcbiAgICAgICAgYSB7XFxuICAgICAgICAgICAgdGV4dC1kZWNvcmF0aW9uOiB1bmRlcmxpbmUgZG90dGVkO1xcbiAgICAgICAgICAgIGNvbG9yOiB2YXIoLS1lYXJ0aC15ZWxsb3cpO1xcbiAgICAgICAgICAgIGZvbnQtd2VpZ2h0OiA2MDA7XFxuICAgICAgICB9XFxuICAgIH1cXG5cXG4gICAgZm9vdGVyIGRpdjpsYXN0LWNoaWxkIHtcXG4gICAgICAgIHBhZGRpbmctYm90dG9tOiAxMHB4O1xcbiAgICB9XFxuXFxuICAgIC5jb250YWN0cyB7XFxuICAgICAgICBkaXNwbGF5OiBmbGV4O1xcbiAgICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcXG4gICAgICAgIGdhcDogMThweDtcXG4gICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XFxuXFxuICAgICAgICBhIHtcXG4gICAgICAgICAgICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XFxuICAgICAgICAgICAgY29sb3I6IHZhcigtLWNyZWFteS13aGl0ZSk7XFxuICAgICAgICB9XFxuXFxuICAgICAgICAuaGFybW9ueSB7XFxuICAgICAgICAgICAgZGlzcGxheTogZmxleDtcXG4gICAgICAgICAgICBmbGV4LWRpcmVjdGlvbjogcm93O1xcbiAgICAgICAgICAgIGdhcDogMTBweDtcXG4gICAgICAgICAgICBwYWRkaW5nLWJvdHRvbTogMTBweDtcXG5cXG4gICAgICAgICAgICBoMiB7XFxuICAgICAgICAgICAgICAgIGZvbnQtc2l6ZTogNDBweDtcXG4gICAgICAgICAgICB9XFxuXFxuICAgICAgICAgICAgc3ZnIHtcXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiA2MHB4O1xcbiAgICAgICAgICAgICAgICB3aWR0aDogNjBweDtcXG4gICAgICAgICAgICAgICAgYWxpZ24tc2VsZjogZmxleC1lbmQ7XFxuICAgICAgICAgICAgICAgIHBhZGRpbmctbGVmdDogMThweDtcXG4gICAgICAgICAgICB9XFxuICAgICAgICB9XFxuXFxuICAgICAgICAuY2FyZCB7XFxuICAgICAgICAgICAgY3Vyc29yOiBwb2ludGVyO1xcblxcbiAgICAgICAgICAgIGRpc3BsYXk6IGZsZXg7XFxuICAgICAgICAgICAgZmxleC1kaXJlY3Rpb246IHJvdztcXG4gICAgICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xcbiAgICAgICAgICAgIGhlaWdodDogNzVweDtcXG5cXG4gICAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1haXItZm9yY2UtYmx1ZSk7XFxuICAgICAgICAgICAgY29sb3I6IHZhcigtLWNyZWFteS13aGl0ZSk7XFxuICAgICAgICAgICAgZm9udC13ZWlnaHQ6IDYwMDtcXG5cXG4gICAgICAgICAgICBib3JkZXI6IG5vbmU7XFxuICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogMTBweDtcXG4gICAgICAgICAgICBib3gtc2hhZG93OiAtNHB4IDVweCA4cHggIzAwMDAwMDM2O1xcblxcbiAgICAgICAgICAgIHN2ZywgcGF0aCB7XFxuICAgICAgICAgICAgICAgIGhlaWdodDogNTBweDtcXG4gICAgICAgICAgICAgICAgd2lkdGg6IDUwcHg7XFxuICAgICAgICAgICAgICAgIHBhZGRpbmc6IDAgMTBweCAwIDEwcHg7XFxuICAgICAgICAgICAgICAgIGZpbGw6IHZhcigtLWNyZWFteS13aGl0ZSlcXG4gICAgICAgICAgICB9XFxuXFxuICAgICAgICAgICAgLmRldGFpbHMge1xcbiAgICAgICAgICAgICAgICB3aWR0aDogNDAwcHg7XFxuICAgICAgICAgICAgICAgIGZvbnQtc2l6ZTogbGFyZ2VyO1xcbiAgICAgICAgICAgICAgICBwYWRkaW5nLXJpZ2h0OiAxNXB4O1xcbiAgICAgICAgICAgIH1cXG5cXG4gICAgICAgICAgICAuZGV0YWlscy5hZGRyZXNzIHA6OmJlZm9yZSB7XFxuICAgICAgICAgICAgICAgIGNvbnRlbnQ6IFxcXCJWaWEgZGkgUy4gQ3JvY2UgaW4gR2VydXNhbGVtbWUsIDU1IChSb21hLCBSTSkgYy9vIFNwaW4gVGltZVxcXCI7XFxuICAgICAgICAgICAgfVxcbiAgICAgICAgfVxcblxcbiAgICAgICAgLmNhcmQ6aG92ZXIge1xcbiAgICAgICAgICAgIFxcbiAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6IHJnYigzNywgMTE3LCAxNDcpO1xcbiAgICAgICAgICAgIHRyYW5zaXRpb246IGFsbCAwLjRzIGVhc2Utb3V0O1xcbiAgICAgICAgICAgIGJveC1zaGFkb3c6IC02cHggN3B4IDVweCAjMDAwMDAwOGY7XFxuICAgICAgICB9XFxuXFxuICAgICAgICAuaWcge1xcbiAgICAgICAgICAgIGJhY2tncm91bmQ6ICM4MzNhYjQ7XFxuICAgICAgICAgICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KFxcbiAgICAgICAgICAgICAgICB0byByaWdodCxcXG4gICAgICAgICAgICAgICAgIzgzM2FiNCwjZmQxZDFkLCNmY2IwNDVcXG4gICAgICAgICAgICAgICAgKTtcXG4gICAgICAgICAgICAgICAgdHJhbnNpdGlvbjogYWxsIDAuNHMgZWFzZS1vdXQ7XFxuICAgICAgICAgICAgfVxcblxcbiAgICAgICAgLndhcHAge1xcbiAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXZlcmRlKTtcXG4gICAgICAgIH1cXG5cXG4gICAgICAgIC53YXBwOmhvdmVyIHtcXG4gICAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjMzg5NTM4O1xcbiAgICAgICAgfVxcbiAgICB9XFxufVwiXSxcInNvdXJjZVJvb3RcIjpcIlwifV0pO1xuLy8gRXhwb3J0c1xuZXhwb3J0IGRlZmF1bHQgX19fQ1NTX0xPQURFUl9FWFBPUlRfX187XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///365\n')},314:module=>{eval('\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\nmodule.exports = function (cssWithMappingToString) {\n var list = [];\n\n // return the list of modules as css string\n list.toString = function toString() {\n return this.map(function (item) {\n var content = "";\n var needLayer = typeof item[5] !== "undefined";\n if (item[4]) {\n content += "@supports (".concat(item[4], ") {");\n }\n if (item[2]) {\n content += "@media ".concat(item[2], " {");\n }\n if (needLayer) {\n content += "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {");\n }\n content += cssWithMappingToString(item);\n if (needLayer) {\n content += "}";\n }\n if (item[2]) {\n content += "}";\n }\n if (item[4]) {\n content += "}";\n }\n return content;\n }).join("");\n };\n\n // import a list of modules into the list\n list.i = function i(modules, media, dedupe, supports, layer) {\n if (typeof modules === "string") {\n modules = [[null, modules, undefined]];\n }\n var alreadyImportedModules = {};\n if (dedupe) {\n for (var k = 0; k < this.length; k++) {\n var id = this[k][0];\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n for (var _k = 0; _k < modules.length; _k++) {\n var item = [].concat(modules[_k]);\n if (dedupe && alreadyImportedModules[item[0]]) {\n continue;\n }\n if (typeof layer !== "undefined") {\n if (typeof item[5] === "undefined") {\n item[5] = layer;\n } else {\n item[1] = "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {").concat(item[1], "}");\n item[5] = layer;\n }\n }\n if (media) {\n if (!item[2]) {\n item[2] = media;\n } else {\n item[1] = "@media ".concat(item[2], " {").concat(item[1], "}");\n item[2] = media;\n }\n }\n if (supports) {\n if (!item[4]) {\n item[4] = "".concat(supports);\n } else {\n item[1] = "@supports (".concat(item[4], ") {").concat(item[1], "}");\n item[4] = supports;\n }\n }\n list.push(item);\n }\n };\n return list;\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzE0LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxREFBcUQ7QUFDckQ7QUFDQTtBQUNBLGdEQUFnRDtBQUNoRDtBQUNBO0FBQ0EscUZBQXFGO0FBQ3JGO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQixpQkFBaUI7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLHFCQUFxQjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVixzRkFBc0YscUJBQXFCO0FBQzNHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVixpREFBaUQscUJBQXFCO0FBQ3RFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVixzREFBc0QscUJBQXFCO0FBQzNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9jb250cm9jb3JvLWxhbmRpbmctcGFnZS8uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9hcGkuanM/MjRmYiJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxuLypcbiAgTUlUIExpY2Vuc2UgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5waHBcbiAgQXV0aG9yIFRvYmlhcyBLb3BwZXJzIEBzb2tyYVxuKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGNzc1dpdGhNYXBwaW5nVG9TdHJpbmcpIHtcbiAgdmFyIGxpc3QgPSBbXTtcblxuICAvLyByZXR1cm4gdGhlIGxpc3Qgb2YgbW9kdWxlcyBhcyBjc3Mgc3RyaW5nXG4gIGxpc3QudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgIHZhciBjb250ZW50ID0gXCJcIjtcbiAgICAgIHZhciBuZWVkTGF5ZXIgPSB0eXBlb2YgaXRlbVs1XSAhPT0gXCJ1bmRlZmluZWRcIjtcbiAgICAgIGlmIChpdGVtWzRdKSB7XG4gICAgICAgIGNvbnRlbnQgKz0gXCJAc3VwcG9ydHMgKFwiLmNvbmNhdChpdGVtWzRdLCBcIikge1wiKTtcbiAgICAgIH1cbiAgICAgIGlmIChpdGVtWzJdKSB7XG4gICAgICAgIGNvbnRlbnQgKz0gXCJAbWVkaWEgXCIuY29uY2F0KGl0ZW1bMl0sIFwiIHtcIik7XG4gICAgICB9XG4gICAgICBpZiAobmVlZExheWVyKSB7XG4gICAgICAgIGNvbnRlbnQgKz0gXCJAbGF5ZXJcIi5jb25jYXQoaXRlbVs1XS5sZW5ndGggPiAwID8gXCIgXCIuY29uY2F0KGl0ZW1bNV0pIDogXCJcIiwgXCIge1wiKTtcbiAgICAgIH1cbiAgICAgIGNvbnRlbnQgKz0gY3NzV2l0aE1hcHBpbmdUb1N0cmluZyhpdGVtKTtcbiAgICAgIGlmIChuZWVkTGF5ZXIpIHtcbiAgICAgICAgY29udGVudCArPSBcIn1cIjtcbiAgICAgIH1cbiAgICAgIGlmIChpdGVtWzJdKSB7XG4gICAgICAgIGNvbnRlbnQgKz0gXCJ9XCI7XG4gICAgICB9XG4gICAgICBpZiAoaXRlbVs0XSkge1xuICAgICAgICBjb250ZW50ICs9IFwifVwiO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNvbnRlbnQ7XG4gICAgfSkuam9pbihcIlwiKTtcbiAgfTtcblxuICAvLyBpbXBvcnQgYSBsaXN0IG9mIG1vZHVsZXMgaW50byB0aGUgbGlzdFxuICBsaXN0LmkgPSBmdW5jdGlvbiBpKG1vZHVsZXMsIG1lZGlhLCBkZWR1cGUsIHN1cHBvcnRzLCBsYXllcikge1xuICAgIGlmICh0eXBlb2YgbW9kdWxlcyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgbW9kdWxlcyA9IFtbbnVsbCwgbW9kdWxlcywgdW5kZWZpbmVkXV07XG4gICAgfVxuICAgIHZhciBhbHJlYWR5SW1wb3J0ZWRNb2R1bGVzID0ge307XG4gICAgaWYgKGRlZHVwZSkge1xuICAgICAgZm9yICh2YXIgayA9IDA7IGsgPCB0aGlzLmxlbmd0aDsgaysrKSB7XG4gICAgICAgIHZhciBpZCA9IHRoaXNba11bMF07XG4gICAgICAgIGlmIChpZCAhPSBudWxsKSB7XG4gICAgICAgICAgYWxyZWFkeUltcG9ydGVkTW9kdWxlc1tpZF0gPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGZvciAodmFyIF9rID0gMDsgX2sgPCBtb2R1bGVzLmxlbmd0aDsgX2srKykge1xuICAgICAgdmFyIGl0ZW0gPSBbXS5jb25jYXQobW9kdWxlc1tfa10pO1xuICAgICAgaWYgKGRlZHVwZSAmJiBhbHJlYWR5SW1wb3J0ZWRNb2R1bGVzW2l0ZW1bMF1dKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBsYXllciAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICBpZiAodHlwZW9mIGl0ZW1bNV0gPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICBpdGVtWzVdID0gbGF5ZXI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaXRlbVsxXSA9IFwiQGxheWVyXCIuY29uY2F0KGl0ZW1bNV0ubGVuZ3RoID4gMCA/IFwiIFwiLmNvbmNhdChpdGVtWzVdKSA6IFwiXCIsIFwiIHtcIikuY29uY2F0KGl0ZW1bMV0sIFwifVwiKTtcbiAgICAgICAgICBpdGVtWzVdID0gbGF5ZXI7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZWRpYSkge1xuICAgICAgICBpZiAoIWl0ZW1bMl0pIHtcbiAgICAgICAgICBpdGVtWzJdID0gbWVkaWE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaXRlbVsxXSA9IFwiQG1lZGlhIFwiLmNvbmNhdChpdGVtWzJdLCBcIiB7XCIpLmNvbmNhdChpdGVtWzFdLCBcIn1cIik7XG4gICAgICAgICAgaXRlbVsyXSA9IG1lZGlhO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoc3VwcG9ydHMpIHtcbiAgICAgICAgaWYgKCFpdGVtWzRdKSB7XG4gICAgICAgICAgaXRlbVs0XSA9IFwiXCIuY29uY2F0KHN1cHBvcnRzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpdGVtWzFdID0gXCJAc3VwcG9ydHMgKFwiLmNvbmNhdChpdGVtWzRdLCBcIikge1wiKS5jb25jYXQoaXRlbVsxXSwgXCJ9XCIpO1xuICAgICAgICAgIGl0ZW1bNF0gPSBzdXBwb3J0cztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGlzdC5wdXNoKGl0ZW0pO1xuICAgIH1cbiAgfTtcbiAgcmV0dXJuIGxpc3Q7XG59OyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///314\n')},417:module=>{eval('\n\nmodule.exports = function (url, options) {\n if (!options) {\n options = {};\n }\n if (!url) {\n return url;\n }\n url = String(url.__esModule ? url.default : url);\n\n // If url is already wrapped in quotes, remove them\n if (/^[\'"].*[\'"]$/.test(url)) {\n url = url.slice(1, -1);\n }\n if (options.hash) {\n url += options.hash;\n }\n\n // Should url be wrapped?\n // See https://drafts.csswg.org/css-values-3/#urls\n if (/["\'() \\t\\n]|(%20)/.test(url) || options.needQuotes) {\n return "\\"".concat(url.replace(/"/g, \'\\\\"\').replace(/\\n/g, "\\\\n"), "\\"");\n }\n return url;\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDE3LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9jb250cm9jb3JvLWxhbmRpbmctcGFnZS8uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9nZXRVcmwuanM/MWRlNSJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodXJsLCBvcHRpb25zKSB7XG4gIGlmICghb3B0aW9ucykge1xuICAgIG9wdGlvbnMgPSB7fTtcbiAgfVxuICBpZiAoIXVybCkge1xuICAgIHJldHVybiB1cmw7XG4gIH1cbiAgdXJsID0gU3RyaW5nKHVybC5fX2VzTW9kdWxlID8gdXJsLmRlZmF1bHQgOiB1cmwpO1xuXG4gIC8vIElmIHVybCBpcyBhbHJlYWR5IHdyYXBwZWQgaW4gcXVvdGVzLCByZW1vdmUgdGhlbVxuICBpZiAoL15bJ1wiXS4qWydcIl0kLy50ZXN0KHVybCkpIHtcbiAgICB1cmwgPSB1cmwuc2xpY2UoMSwgLTEpO1xuICB9XG4gIGlmIChvcHRpb25zLmhhc2gpIHtcbiAgICB1cmwgKz0gb3B0aW9ucy5oYXNoO1xuICB9XG5cbiAgLy8gU2hvdWxkIHVybCBiZSB3cmFwcGVkP1xuICAvLyBTZWUgaHR0cHM6Ly9kcmFmdHMuY3Nzd2cub3JnL2Nzcy12YWx1ZXMtMy8jdXJsc1xuICBpZiAoL1tcIicoKSBcXHRcXG5dfCglMjApLy50ZXN0KHVybCkgfHwgb3B0aW9ucy5uZWVkUXVvdGVzKSB7XG4gICAgcmV0dXJuIFwiXFxcIlwiLmNvbmNhdCh1cmwucmVwbGFjZSgvXCIvZywgJ1xcXFxcIicpLnJlcGxhY2UoL1xcbi9nLCBcIlxcXFxuXCIpLCBcIlxcXCJcIik7XG4gIH1cbiAgcmV0dXJuIHVybDtcbn07Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///417\n')},354:module=>{eval('\n\nmodule.exports = function (item) {\n var content = item[1];\n var cssMapping = item[3];\n if (!cssMapping) {\n return content;\n }\n if (typeof btoa === "function") {\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));\n var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);\n var sourceMapping = "/*# ".concat(data, " */");\n return [content].concat([sourceMapping]).join("\\n");\n }\n return [content].join("\\n");\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzU0LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1REFBdUQsY0FBYztBQUNyRTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vY29udHJvY29yby1sYW5kaW5nLXBhZ2UvLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvc291cmNlTWFwcy5qcz9hZjEyIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdGVtKSB7XG4gIHZhciBjb250ZW50ID0gaXRlbVsxXTtcbiAgdmFyIGNzc01hcHBpbmcgPSBpdGVtWzNdO1xuICBpZiAoIWNzc01hcHBpbmcpIHtcbiAgICByZXR1cm4gY29udGVudDtcbiAgfVxuICBpZiAodHlwZW9mIGJ0b2EgPT09IFwiZnVuY3Rpb25cIikge1xuICAgIHZhciBiYXNlNjQgPSBidG9hKHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChKU09OLnN0cmluZ2lmeShjc3NNYXBwaW5nKSkpKTtcbiAgICB2YXIgZGF0YSA9IFwic291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtODtiYXNlNjQsXCIuY29uY2F0KGJhc2U2NCk7XG4gICAgdmFyIHNvdXJjZU1hcHBpbmcgPSBcIi8qIyBcIi5jb25jYXQoZGF0YSwgXCIgKi9cIik7XG4gICAgcmV0dXJuIFtjb250ZW50XS5jb25jYXQoW3NvdXJjZU1hcHBpbmddKS5qb2luKFwiXFxuXCIpO1xuICB9XG4gIHJldHVybiBbY29udGVudF0uam9pbihcIlxcblwiKTtcbn07Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///354\n')},72:module=>{eval('\n\nvar stylesInDOM = [];\nfunction getIndexByIdentifier(identifier) {\n var result = -1;\n for (var i = 0; i < stylesInDOM.length; i++) {\n if (stylesInDOM[i].identifier === identifier) {\n result = i;\n break;\n }\n }\n return result;\n}\nfunction modulesToDom(list, options) {\n var idCountMap = {};\n var identifiers = [];\n for (var i = 0; i < list.length; i++) {\n var item = list[i];\n var id = options.base ? item[0] + options.base : item[0];\n var count = idCountMap[id] || 0;\n var identifier = "".concat(id, " ").concat(count);\n idCountMap[id] = count + 1;\n var indexByIdentifier = getIndexByIdentifier(identifier);\n var obj = {\n css: item[1],\n media: item[2],\n sourceMap: item[3],\n supports: item[4],\n layer: item[5]\n };\n if (indexByIdentifier !== -1) {\n stylesInDOM[indexByIdentifier].references++;\n stylesInDOM[indexByIdentifier].updater(obj);\n } else {\n var updater = addElementStyle(obj, options);\n options.byIndex = i;\n stylesInDOM.splice(i, 0, {\n identifier: identifier,\n updater: updater,\n references: 1\n });\n }\n identifiers.push(identifier);\n }\n return identifiers;\n}\nfunction addElementStyle(obj, options) {\n var api = options.domAPI(options);\n api.update(obj);\n var updater = function updater(newObj) {\n if (newObj) {\n if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) {\n return;\n }\n api.update(obj = newObj);\n } else {\n api.remove();\n }\n };\n return updater;\n}\nmodule.exports = function (list, options) {\n options = options || {};\n list = list || [];\n var lastIdentifiers = modulesToDom(list, options);\n return function update(newList) {\n newList = newList || [];\n for (var i = 0; i < lastIdentifiers.length; i++) {\n var identifier = lastIdentifiers[i];\n var index = getIndexByIdentifier(identifier);\n stylesInDOM[index].references--;\n }\n var newLastIdentifiers = modulesToDom(newList, options);\n for (var _i = 0; _i < lastIdentifiers.length; _i++) {\n var _identifier = lastIdentifiers[_i];\n var _index = getIndexByIdentifier(_identifier);\n if (stylesInDOM[_index].references === 0) {\n stylesInDOM[_index].updater();\n stylesInDOM.splice(_index, 1);\n }\n }\n lastIdentifiers = newLastIdentifiers;\n };\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzIuanMiLCJtYXBwaW5ncyI6IkFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLHdCQUF3QjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixpQkFBaUI7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQiw0QkFBNEI7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQiw2QkFBNkI7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9jb250cm9jb3JvLWxhbmRpbmctcGFnZS8uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luamVjdFN0eWxlc0ludG9TdHlsZVRhZy5qcz8yZGJhIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG52YXIgc3R5bGVzSW5ET00gPSBbXTtcbmZ1bmN0aW9uIGdldEluZGV4QnlJZGVudGlmaWVyKGlkZW50aWZpZXIpIHtcbiAgdmFyIHJlc3VsdCA9IC0xO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0eWxlc0luRE9NLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHN0eWxlc0luRE9NW2ldLmlkZW50aWZpZXIgPT09IGlkZW50aWZpZXIpIHtcbiAgICAgIHJlc3VsdCA9IGk7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIG1vZHVsZXNUb0RvbShsaXN0LCBvcHRpb25zKSB7XG4gIHZhciBpZENvdW50TWFwID0ge307XG4gIHZhciBpZGVudGlmaWVycyA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgaXRlbSA9IGxpc3RbaV07XG4gICAgdmFyIGlkID0gb3B0aW9ucy5iYXNlID8gaXRlbVswXSArIG9wdGlvbnMuYmFzZSA6IGl0ZW1bMF07XG4gICAgdmFyIGNvdW50ID0gaWRDb3VudE1hcFtpZF0gfHwgMDtcbiAgICB2YXIgaWRlbnRpZmllciA9IFwiXCIuY29uY2F0KGlkLCBcIiBcIikuY29uY2F0KGNvdW50KTtcbiAgICBpZENvdW50TWFwW2lkXSA9IGNvdW50ICsgMTtcbiAgICB2YXIgaW5kZXhCeUlkZW50aWZpZXIgPSBnZXRJbmRleEJ5SWRlbnRpZmllcihpZGVudGlmaWVyKTtcbiAgICB2YXIgb2JqID0ge1xuICAgICAgY3NzOiBpdGVtWzFdLFxuICAgICAgbWVkaWE6IGl0ZW1bMl0sXG4gICAgICBzb3VyY2VNYXA6IGl0ZW1bM10sXG4gICAgICBzdXBwb3J0czogaXRlbVs0XSxcbiAgICAgIGxheWVyOiBpdGVtWzVdXG4gICAgfTtcbiAgICBpZiAoaW5kZXhCeUlkZW50aWZpZXIgIT09IC0xKSB7XG4gICAgICBzdHlsZXNJbkRPTVtpbmRleEJ5SWRlbnRpZmllcl0ucmVmZXJlbmNlcysrO1xuICAgICAgc3R5bGVzSW5ET01baW5kZXhCeUlkZW50aWZpZXJdLnVwZGF0ZXIob2JqKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHVwZGF0ZXIgPSBhZGRFbGVtZW50U3R5bGUob2JqLCBvcHRpb25zKTtcbiAgICAgIG9wdGlvbnMuYnlJbmRleCA9IGk7XG4gICAgICBzdHlsZXNJbkRPTS5zcGxpY2UoaSwgMCwge1xuICAgICAgICBpZGVudGlmaWVyOiBpZGVudGlmaWVyLFxuICAgICAgICB1cGRhdGVyOiB1cGRhdGVyLFxuICAgICAgICByZWZlcmVuY2VzOiAxXG4gICAgICB9KTtcbiAgICB9XG4gICAgaWRlbnRpZmllcnMucHVzaChpZGVudGlmaWVyKTtcbiAgfVxuICByZXR1cm4gaWRlbnRpZmllcnM7XG59XG5mdW5jdGlvbiBhZGRFbGVtZW50U3R5bGUob2JqLCBvcHRpb25zKSB7XG4gIHZhciBhcGkgPSBvcHRpb25zLmRvbUFQSShvcHRpb25zKTtcbiAgYXBpLnVwZGF0ZShvYmopO1xuICB2YXIgdXBkYXRlciA9IGZ1bmN0aW9uIHVwZGF0ZXIobmV3T2JqKSB7XG4gICAgaWYgKG5ld09iaikge1xuICAgICAgaWYgKG5ld09iai5jc3MgPT09IG9iai5jc3MgJiYgbmV3T2JqLm1lZGlhID09PSBvYmoubWVkaWEgJiYgbmV3T2JqLnNvdXJjZU1hcCA9PT0gb2JqLnNvdXJjZU1hcCAmJiBuZXdPYmouc3VwcG9ydHMgPT09IG9iai5zdXBwb3J0cyAmJiBuZXdPYmoubGF5ZXIgPT09IG9iai5sYXllcikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBhcGkudXBkYXRlKG9iaiA9IG5ld09iaik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFwaS5yZW1vdmUoKTtcbiAgICB9XG4gIH07XG4gIHJldHVybiB1cGRhdGVyO1xufVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAobGlzdCwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgbGlzdCA9IGxpc3QgfHwgW107XG4gIHZhciBsYXN0SWRlbnRpZmllcnMgPSBtb2R1bGVzVG9Eb20obGlzdCwgb3B0aW9ucyk7XG4gIHJldHVybiBmdW5jdGlvbiB1cGRhdGUobmV3TGlzdCkge1xuICAgIG5ld0xpc3QgPSBuZXdMaXN0IHx8IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGFzdElkZW50aWZpZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgaWRlbnRpZmllciA9IGxhc3RJZGVudGlmaWVyc1tpXTtcbiAgICAgIHZhciBpbmRleCA9IGdldEluZGV4QnlJZGVudGlmaWVyKGlkZW50aWZpZXIpO1xuICAgICAgc3R5bGVzSW5ET01baW5kZXhdLnJlZmVyZW5jZXMtLTtcbiAgICB9XG4gICAgdmFyIG5ld0xhc3RJZGVudGlmaWVycyA9IG1vZHVsZXNUb0RvbShuZXdMaXN0LCBvcHRpb25zKTtcbiAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgbGFzdElkZW50aWZpZXJzLmxlbmd0aDsgX2krKykge1xuICAgICAgdmFyIF9pZGVudGlmaWVyID0gbGFzdElkZW50aWZpZXJzW19pXTtcbiAgICAgIHZhciBfaW5kZXggPSBnZXRJbmRleEJ5SWRlbnRpZmllcihfaWRlbnRpZmllcik7XG4gICAgICBpZiAoc3R5bGVzSW5ET01bX2luZGV4XS5yZWZlcmVuY2VzID09PSAwKSB7XG4gICAgICAgIHN0eWxlc0luRE9NW19pbmRleF0udXBkYXRlcigpO1xuICAgICAgICBzdHlsZXNJbkRPTS5zcGxpY2UoX2luZGV4LCAxKTtcbiAgICAgIH1cbiAgICB9XG4gICAgbGFzdElkZW50aWZpZXJzID0gbmV3TGFzdElkZW50aWZpZXJzO1xuICB9O1xufTsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///72\n')},659:module=>{eval('\n\nvar memo = {};\n\n/* istanbul ignore next */\nfunction getTarget(target) {\n if (typeof memo[target] === "undefined") {\n var styleTarget = document.querySelector(target);\n\n // Special case to return head of iframe instead of iframe itself\n if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n try {\n // This will throw an exception if access to iframe is blocked\n // due to cross-origin restrictions\n styleTarget = styleTarget.contentDocument.head;\n } catch (e) {\n // istanbul ignore next\n styleTarget = null;\n }\n }\n memo[target] = styleTarget;\n }\n return memo[target];\n}\n\n/* istanbul ignore next */\nfunction insertBySelector(insert, style) {\n var target = getTarget(insert);\n if (!target) {\n throw new Error("Couldn\'t find a style target. This probably means that the value for the \'insert\' parameter is invalid.");\n }\n target.appendChild(style);\n}\nmodule.exports = insertBySelector;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjU5LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL2NvbnRyb2Nvcm8tbGFuZGluZy1wYWdlLy4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0QnlTZWxlY3Rvci5qcz9iMjE0Il0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG52YXIgbWVtbyA9IHt9O1xuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAgKi9cbmZ1bmN0aW9uIGdldFRhcmdldCh0YXJnZXQpIHtcbiAgaWYgKHR5cGVvZiBtZW1vW3RhcmdldF0gPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICB2YXIgc3R5bGVUYXJnZXQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRhcmdldCk7XG5cbiAgICAvLyBTcGVjaWFsIGNhc2UgdG8gcmV0dXJuIGhlYWQgb2YgaWZyYW1lIGluc3RlYWQgb2YgaWZyYW1lIGl0c2VsZlxuICAgIGlmICh3aW5kb3cuSFRNTElGcmFtZUVsZW1lbnQgJiYgc3R5bGVUYXJnZXQgaW5zdGFuY2VvZiB3aW5kb3cuSFRNTElGcmFtZUVsZW1lbnQpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIFRoaXMgd2lsbCB0aHJvdyBhbiBleGNlcHRpb24gaWYgYWNjZXNzIHRvIGlmcmFtZSBpcyBibG9ja2VkXG4gICAgICAgIC8vIGR1ZSB0byBjcm9zcy1vcmlnaW4gcmVzdHJpY3Rpb25zXG4gICAgICAgIHN0eWxlVGFyZ2V0ID0gc3R5bGVUYXJnZXQuY29udGVudERvY3VtZW50LmhlYWQ7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIGlzdGFuYnVsIGlnbm9yZSBuZXh0XG4gICAgICAgIHN0eWxlVGFyZ2V0ID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gICAgbWVtb1t0YXJnZXRdID0gc3R5bGVUYXJnZXQ7XG4gIH1cbiAgcmV0dXJuIG1lbW9bdGFyZ2V0XTtcbn1cblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgICovXG5mdW5jdGlvbiBpbnNlcnRCeVNlbGVjdG9yKGluc2VydCwgc3R5bGUpIHtcbiAgdmFyIHRhcmdldCA9IGdldFRhcmdldChpbnNlcnQpO1xuICBpZiAoIXRhcmdldCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkNvdWxkbid0IGZpbmQgYSBzdHlsZSB0YXJnZXQuIFRoaXMgcHJvYmFibHkgbWVhbnMgdGhhdCB0aGUgdmFsdWUgZm9yIHRoZSAnaW5zZXJ0JyBwYXJhbWV0ZXIgaXMgaW52YWxpZC5cIik7XG4gIH1cbiAgdGFyZ2V0LmFwcGVuZENoaWxkKHN0eWxlKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gaW5zZXJ0QnlTZWxlY3RvcjsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///659\n')},540:module=>{eval('\n\n/* istanbul ignore next */\nfunction insertStyleElement(options) {\n var element = document.createElement("style");\n options.setAttributes(element, options.attributes);\n options.insert(element, options.options);\n return element;\n}\nmodule.exports = insertStyleElement;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQwLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9jb250cm9jb3JvLWxhbmRpbmctcGFnZS8uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydFN0eWxlRWxlbWVudC5qcz9kZTZjIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAgKi9cbmZ1bmN0aW9uIGluc2VydFN0eWxlRWxlbWVudChvcHRpb25zKSB7XG4gIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInN0eWxlXCIpO1xuICBvcHRpb25zLnNldEF0dHJpYnV0ZXMoZWxlbWVudCwgb3B0aW9ucy5hdHRyaWJ1dGVzKTtcbiAgb3B0aW9ucy5pbnNlcnQoZWxlbWVudCwgb3B0aW9ucy5vcHRpb25zKTtcbiAgcmV0dXJuIGVsZW1lbnQ7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGluc2VydFN0eWxlRWxlbWVudDsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///540\n')},56:(module,__unused_webpack_exports,__webpack_require__)=>{eval('\n\n/* istanbul ignore next */\nfunction setAttributesWithoutAttributes(styleElement) {\n var nonce = true ? __webpack_require__.nc : 0;\n if (nonce) {\n styleElement.setAttribute("nonce", nonce);\n }\n}\nmodule.exports = setAttributesWithoutAttributes;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTYuanMiLCJtYXBwaW5ncyI6IkFBQWE7O0FBRWI7QUFDQTtBQUNBLGNBQWMsS0FBd0MsR0FBRyxzQkFBaUIsR0FBRyxDQUFJO0FBQ2pGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9jb250cm9jb3JvLWxhbmRpbmctcGFnZS8uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3NldEF0dHJpYnV0ZXNXaXRob3V0QXR0cmlidXRlcy5qcz9kZGNlIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAgKi9cbmZ1bmN0aW9uIHNldEF0dHJpYnV0ZXNXaXRob3V0QXR0cmlidXRlcyhzdHlsZUVsZW1lbnQpIHtcbiAgdmFyIG5vbmNlID0gdHlwZW9mIF9fd2VicGFja19ub25jZV9fICE9PSBcInVuZGVmaW5lZFwiID8gX193ZWJwYWNrX25vbmNlX18gOiBudWxsO1xuICBpZiAobm9uY2UpIHtcbiAgICBzdHlsZUVsZW1lbnQuc2V0QXR0cmlidXRlKFwibm9uY2VcIiwgbm9uY2UpO1xuICB9XG59XG5tb2R1bGUuZXhwb3J0cyA9IHNldEF0dHJpYnV0ZXNXaXRob3V0QXR0cmlidXRlczsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///56\n')},825:module=>{eval('\n\n/* istanbul ignore next */\nfunction apply(styleElement, options, obj) {\n var css = "";\n if (obj.supports) {\n css += "@supports (".concat(obj.supports, ") {");\n }\n if (obj.media) {\n css += "@media ".concat(obj.media, " {");\n }\n var needLayer = typeof obj.layer !== "undefined";\n if (needLayer) {\n css += "@layer".concat(obj.layer.length > 0 ? " ".concat(obj.layer) : "", " {");\n }\n css += obj.css;\n if (needLayer) {\n css += "}";\n }\n if (obj.media) {\n css += "}";\n }\n if (obj.supports) {\n css += "}";\n }\n var sourceMap = obj.sourceMap;\n if (sourceMap && typeof btoa !== "undefined") {\n css += "\\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), " */");\n }\n\n // For old IE\n /* istanbul ignore if */\n options.styleTagTransform(css, styleElement, options.options);\n}\nfunction removeStyleElement(styleElement) {\n // istanbul ignore if\n if (styleElement.parentNode === null) {\n return false;\n }\n styleElement.parentNode.removeChild(styleElement);\n}\n\n/* istanbul ignore next */\nfunction domAPI(options) {\n if (typeof document === "undefined") {\n return {\n update: function update() {},\n remove: function remove() {}\n };\n }\n var styleElement = options.insertStyleElement(options);\n return {\n update: function update(obj) {\n apply(styleElement, options, obj);\n },\n remove: function remove() {\n removeStyleElement(styleElement);\n }\n };\n}\nmodule.exports = domAPI;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODI1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0RBQWtEO0FBQ2xEO0FBQ0E7QUFDQSwwQ0FBMEM7QUFDMUM7QUFDQTtBQUNBO0FBQ0EsaUZBQWlGO0FBQ2pGO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EseURBQXlEO0FBQ3pEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0M7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vY29udHJvY29yby1sYW5kaW5nLXBhZ2UvLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZURvbUFQSS5qcz9lNDc5Il0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAgKi9cbmZ1bmN0aW9uIGFwcGx5KHN0eWxlRWxlbWVudCwgb3B0aW9ucywgb2JqKSB7XG4gIHZhciBjc3MgPSBcIlwiO1xuICBpZiAob2JqLnN1cHBvcnRzKSB7XG4gICAgY3NzICs9IFwiQHN1cHBvcnRzIChcIi5jb25jYXQob2JqLnN1cHBvcnRzLCBcIikge1wiKTtcbiAgfVxuICBpZiAob2JqLm1lZGlhKSB7XG4gICAgY3NzICs9IFwiQG1lZGlhIFwiLmNvbmNhdChvYmoubWVkaWEsIFwiIHtcIik7XG4gIH1cbiAgdmFyIG5lZWRMYXllciA9IHR5cGVvZiBvYmoubGF5ZXIgIT09IFwidW5kZWZpbmVkXCI7XG4gIGlmIChuZWVkTGF5ZXIpIHtcbiAgICBjc3MgKz0gXCJAbGF5ZXJcIi5jb25jYXQob2JqLmxheWVyLmxlbmd0aCA+IDAgPyBcIiBcIi5jb25jYXQob2JqLmxheWVyKSA6IFwiXCIsIFwiIHtcIik7XG4gIH1cbiAgY3NzICs9IG9iai5jc3M7XG4gIGlmIChuZWVkTGF5ZXIpIHtcbiAgICBjc3MgKz0gXCJ9XCI7XG4gIH1cbiAgaWYgKG9iai5tZWRpYSkge1xuICAgIGNzcyArPSBcIn1cIjtcbiAgfVxuICBpZiAob2JqLnN1cHBvcnRzKSB7XG4gICAgY3NzICs9IFwifVwiO1xuICB9XG4gIHZhciBzb3VyY2VNYXAgPSBvYmouc291cmNlTWFwO1xuICBpZiAoc291cmNlTWFwICYmIHR5cGVvZiBidG9hICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgY3NzICs9IFwiXFxuLyojIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2Jhc2U2NCxcIi5jb25jYXQoYnRvYSh1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoSlNPTi5zdHJpbmdpZnkoc291cmNlTWFwKSkpKSwgXCIgKi9cIik7XG4gIH1cblxuICAvLyBGb3Igb2xkIElFXG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAgKi9cbiAgb3B0aW9ucy5zdHlsZVRhZ1RyYW5zZm9ybShjc3MsIHN0eWxlRWxlbWVudCwgb3B0aW9ucy5vcHRpb25zKTtcbn1cbmZ1bmN0aW9uIHJlbW92ZVN0eWxlRWxlbWVudChzdHlsZUVsZW1lbnQpIHtcbiAgLy8gaXN0YW5idWwgaWdub3JlIGlmXG4gIGlmIChzdHlsZUVsZW1lbnQucGFyZW50Tm9kZSA9PT0gbnVsbCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBzdHlsZUVsZW1lbnQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChzdHlsZUVsZW1lbnQpO1xufVxuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAgKi9cbmZ1bmN0aW9uIGRvbUFQSShvcHRpb25zKSB7XG4gIGlmICh0eXBlb2YgZG9jdW1lbnQgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdXBkYXRlOiBmdW5jdGlvbiB1cGRhdGUoKSB7fSxcbiAgICAgIHJlbW92ZTogZnVuY3Rpb24gcmVtb3ZlKCkge31cbiAgICB9O1xuICB9XG4gIHZhciBzdHlsZUVsZW1lbnQgPSBvcHRpb25zLmluc2VydFN0eWxlRWxlbWVudChvcHRpb25zKTtcbiAgcmV0dXJuIHtcbiAgICB1cGRhdGU6IGZ1bmN0aW9uIHVwZGF0ZShvYmopIHtcbiAgICAgIGFwcGx5KHN0eWxlRWxlbWVudCwgb3B0aW9ucywgb2JqKTtcbiAgICB9LFxuICAgIHJlbW92ZTogZnVuY3Rpb24gcmVtb3ZlKCkge1xuICAgICAgcmVtb3ZlU3R5bGVFbGVtZW50KHN0eWxlRWxlbWVudCk7XG4gICAgfVxuICB9O1xufVxubW9kdWxlLmV4cG9ydHMgPSBkb21BUEk7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///825\n')},113:module=>{eval("\n\n/* istanbul ignore next */\nfunction styleTagTransform(css, styleElement) {\n if (styleElement.styleSheet) {\n styleElement.styleSheet.cssText = css;\n } else {\n while (styleElement.firstChild) {\n styleElement.removeChild(styleElement.firstChild);\n }\n styleElement.appendChild(document.createTextNode(css));\n }\n}\nmodule.exports = styleTagTransform;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTEzLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vY29udHJvY29yby1sYW5kaW5nLXBhZ2UvLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZVRhZ1RyYW5zZm9ybS5qcz8xZGRlIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAgKi9cbmZ1bmN0aW9uIHN0eWxlVGFnVHJhbnNmb3JtKGNzcywgc3R5bGVFbGVtZW50KSB7XG4gIGlmIChzdHlsZUVsZW1lbnQuc3R5bGVTaGVldCkge1xuICAgIHN0eWxlRWxlbWVudC5zdHlsZVNoZWV0LmNzc1RleHQgPSBjc3M7XG4gIH0gZWxzZSB7XG4gICAgd2hpbGUgKHN0eWxlRWxlbWVudC5maXJzdENoaWxkKSB7XG4gICAgICBzdHlsZUVsZW1lbnQucmVtb3ZlQ2hpbGQoc3R5bGVFbGVtZW50LmZpcnN0Q2hpbGQpO1xuICAgIH1cbiAgICBzdHlsZUVsZW1lbnQuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoY3NzKSk7XG4gIH1cbn1cbm1vZHVsZS5leHBvcnRzID0gc3R5bGVUYWdUcmFuc2Zvcm07Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///113\n")},318:(__unused_webpack_module,__unused_webpack___webpack_exports__,__webpack_require__)=>{eval("\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\nvar injectStylesIntoStyleTag = __webpack_require__(72);\nvar injectStylesIntoStyleTag_default = /*#__PURE__*/__webpack_require__.n(injectStylesIntoStyleTag);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/styleDomAPI.js\nvar styleDomAPI = __webpack_require__(825);\nvar styleDomAPI_default = /*#__PURE__*/__webpack_require__.n(styleDomAPI);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/insertBySelector.js\nvar insertBySelector = __webpack_require__(659);\nvar insertBySelector_default = /*#__PURE__*/__webpack_require__.n(insertBySelector);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\nvar setAttributesWithoutAttributes = __webpack_require__(56);\nvar setAttributesWithoutAttributes_default = /*#__PURE__*/__webpack_require__.n(setAttributesWithoutAttributes);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/insertStyleElement.js\nvar insertStyleElement = __webpack_require__(540);\nvar insertStyleElement_default = /*#__PURE__*/__webpack_require__.n(insertStyleElement);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/styleTagTransform.js\nvar styleTagTransform = __webpack_require__(113);\nvar styleTagTransform_default = /*#__PURE__*/__webpack_require__.n(styleTagTransform);\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/normalize.css\nvar normalize = __webpack_require__(874);\n;// ./src/normalize.css\n\n \n \n \n \n \n \n \n \n \n\nvar options = {};\n\noptions.styleTagTransform = (styleTagTransform_default());\noptions.setAttributes = (setAttributesWithoutAttributes_default());\noptions.insert = insertBySelector_default().bind(null, \"head\");\noptions.domAPI = (styleDomAPI_default());\noptions.insertStyleElement = (insertStyleElement_default());\n\nvar update = injectStylesIntoStyleTag_default()(normalize/* default */.A, options);\n\n\n\n\n /* harmony default export */ const src_normalize = (normalize/* default */.A && normalize/* default */.A.locals ? normalize/* default */.A.locals : undefined);\n\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/styles.css\nvar styles = __webpack_require__(365);\n;// ./src/styles.css\n\n \n \n \n \n \n \n \n \n \n\nvar styles_options = {};\n\nstyles_options.styleTagTransform = (styleTagTransform_default());\nstyles_options.setAttributes = (setAttributesWithoutAttributes_default());\nstyles_options.insert = insertBySelector_default().bind(null, \"head\");\nstyles_options.domAPI = (styleDomAPI_default());\nstyles_options.insertStyleElement = (insertStyleElement_default());\n\nvar styles_update = injectStylesIntoStyleTag_default()(styles/* default */.A, styles_options);\n\n\n\n\n /* harmony default export */ const src_styles = (styles/* default */.A && styles/* default */.A.locals ? styles/* default */.A.locals : undefined);\n\n;// ./node_modules/@kurkle/color/dist/color.esm.js\n/*!\n * @kurkle/color v0.3.2\n * https://github.com/kurkle/color#readme\n * (c) 2023 Jukka Kurkela\n * Released under the MIT License\n */\nfunction round(v) {\n return v + 0.5 | 0;\n}\nconst lim = (v, l, h) => Math.max(Math.min(v, h), l);\nfunction p2b(v) {\n return lim(round(v * 2.55), 0, 255);\n}\nfunction b2p(v) {\n return lim(round(v / 2.55), 0, 100);\n}\nfunction n2b(v) {\n return lim(round(v * 255), 0, 255);\n}\nfunction b2n(v) {\n return lim(round(v / 2.55) / 100, 0, 1);\n}\nfunction n2p(v) {\n return lim(round(v * 100), 0, 100);\n}\n\nconst map$1 = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, A: 10, B: 11, C: 12, D: 13, E: 14, F: 15, a: 10, b: 11, c: 12, d: 13, e: 14, f: 15};\nconst hex = [...'0123456789ABCDEF'];\nconst h1 = b => hex[b & 0xF];\nconst h2 = b => hex[(b & 0xF0) >> 4] + hex[b & 0xF];\nconst eq = b => ((b & 0xF0) >> 4) === (b & 0xF);\nconst isShort = v => eq(v.r) && eq(v.g) && eq(v.b) && eq(v.a);\nfunction hexParse(str) {\n var len = str.length;\n var ret;\n if (str[0] === '#') {\n if (len === 4 || len === 5) {\n ret = {\n r: 255 & map$1[str[1]] * 17,\n g: 255 & map$1[str[2]] * 17,\n b: 255 & map$1[str[3]] * 17,\n a: len === 5 ? map$1[str[4]] * 17 : 255\n };\n } else if (len === 7 || len === 9) {\n ret = {\n r: map$1[str[1]] << 4 | map$1[str[2]],\n g: map$1[str[3]] << 4 | map$1[str[4]],\n b: map$1[str[5]] << 4 | map$1[str[6]],\n a: len === 9 ? (map$1[str[7]] << 4 | map$1[str[8]]) : 255\n };\n }\n }\n return ret;\n}\nconst alpha = (a, f) => a < 255 ? f(a) : '';\nfunction hexString(v) {\n var f = isShort(v) ? h1 : h2;\n return v\n ? '#' + f(v.r) + f(v.g) + f(v.b) + alpha(v.a, f)\n : undefined;\n}\n\nconst HUE_RE = /^(hsla?|hwb|hsv)\\(\\s*([-+.e\\d]+)(?:deg)?[\\s,]+([-+.e\\d]+)%[\\s,]+([-+.e\\d]+)%(?:[\\s,]+([-+.e\\d]+)(%)?)?\\s*\\)$/;\nfunction hsl2rgbn(h, s, l) {\n const a = s * Math.min(l, 1 - l);\n const f = (n, k = (n + h / 30) % 12) => l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);\n return [f(0), f(8), f(4)];\n}\nfunction hsv2rgbn(h, s, v) {\n const f = (n, k = (n + h / 60) % 6) => v - v * s * Math.max(Math.min(k, 4 - k, 1), 0);\n return [f(5), f(3), f(1)];\n}\nfunction hwb2rgbn(h, w, b) {\n const rgb = hsl2rgbn(h, 1, 0.5);\n let i;\n if (w + b > 1) {\n i = 1 / (w + b);\n w *= i;\n b *= i;\n }\n for (i = 0; i < 3; i++) {\n rgb[i] *= 1 - w - b;\n rgb[i] += w;\n }\n return rgb;\n}\nfunction hueValue(r, g, b, d, max) {\n if (r === max) {\n return ((g - b) / d) + (g < b ? 6 : 0);\n }\n if (g === max) {\n return (b - r) / d + 2;\n }\n return (r - g) / d + 4;\n}\nfunction rgb2hsl(v) {\n const range = 255;\n const r = v.r / range;\n const g = v.g / range;\n const b = v.b / range;\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const l = (max + min) / 2;\n let h, s, d;\n if (max !== min) {\n d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n h = hueValue(r, g, b, d, max);\n h = h * 60 + 0.5;\n }\n return [h | 0, s || 0, l];\n}\nfunction calln(f, a, b, c) {\n return (\n Array.isArray(a)\n ? f(a[0], a[1], a[2])\n : f(a, b, c)\n ).map(n2b);\n}\nfunction hsl2rgb(h, s, l) {\n return calln(hsl2rgbn, h, s, l);\n}\nfunction hwb2rgb(h, w, b) {\n return calln(hwb2rgbn, h, w, b);\n}\nfunction hsv2rgb(h, s, v) {\n return calln(hsv2rgbn, h, s, v);\n}\nfunction hue(h) {\n return (h % 360 + 360) % 360;\n}\nfunction hueParse(str) {\n const m = HUE_RE.exec(str);\n let a = 255;\n let v;\n if (!m) {\n return;\n }\n if (m[5] !== v) {\n a = m[6] ? p2b(+m[5]) : n2b(+m[5]);\n }\n const h = hue(+m[2]);\n const p1 = +m[3] / 100;\n const p2 = +m[4] / 100;\n if (m[1] === 'hwb') {\n v = hwb2rgb(h, p1, p2);\n } else if (m[1] === 'hsv') {\n v = hsv2rgb(h, p1, p2);\n } else {\n v = hsl2rgb(h, p1, p2);\n }\n return {\n r: v[0],\n g: v[1],\n b: v[2],\n a: a\n };\n}\nfunction rotate(v, deg) {\n var h = rgb2hsl(v);\n h[0] = hue(h[0] + deg);\n h = hsl2rgb(h);\n v.r = h[0];\n v.g = h[1];\n v.b = h[2];\n}\nfunction hslString(v) {\n if (!v) {\n return;\n }\n const a = rgb2hsl(v);\n const h = a[0];\n const s = n2p(a[1]);\n const l = n2p(a[2]);\n return v.a < 255\n ? `hsla(${h}, ${s}%, ${l}%, ${b2n(v.a)})`\n : `hsl(${h}, ${s}%, ${l}%)`;\n}\n\nconst map = {\n x: 'dark',\n Z: 'light',\n Y: 're',\n X: 'blu',\n W: 'gr',\n V: 'medium',\n U: 'slate',\n A: 'ee',\n T: 'ol',\n S: 'or',\n B: 'ra',\n C: 'lateg',\n D: 'ights',\n R: 'in',\n Q: 'turquois',\n E: 'hi',\n P: 'ro',\n O: 'al',\n N: 'le',\n M: 'de',\n L: 'yello',\n F: 'en',\n K: 'ch',\n G: 'arks',\n H: 'ea',\n I: 'ightg',\n J: 'wh'\n};\nconst names$1 = {\n OiceXe: 'f0f8ff',\n antiquewEte: 'faebd7',\n aqua: 'ffff',\n aquamarRe: '7fffd4',\n azuY: 'f0ffff',\n beige: 'f5f5dc',\n bisque: 'ffe4c4',\n black: '0',\n blanKedOmond: 'ffebcd',\n Xe: 'ff',\n XeviTet: '8a2be2',\n bPwn: 'a52a2a',\n burlywood: 'deb887',\n caMtXe: '5f9ea0',\n KartYuse: '7fff00',\n KocTate: 'd2691e',\n cSO: 'ff7f50',\n cSnflowerXe: '6495ed',\n cSnsilk: 'fff8dc',\n crimson: 'dc143c',\n cyan: 'ffff',\n xXe: '8b',\n xcyan: '8b8b',\n xgTMnPd: 'b8860b',\n xWay: 'a9a9a9',\n xgYF: '6400',\n xgYy: 'a9a9a9',\n xkhaki: 'bdb76b',\n xmagFta: '8b008b',\n xTivegYF: '556b2f',\n xSange: 'ff8c00',\n xScEd: '9932cc',\n xYd: '8b0000',\n xsOmon: 'e9967a',\n xsHgYF: '8fbc8f',\n xUXe: '483d8b',\n xUWay: '2f4f4f',\n xUgYy: '2f4f4f',\n xQe: 'ced1',\n xviTet: '9400d3',\n dAppRk: 'ff1493',\n dApskyXe: 'bfff',\n dimWay: '696969',\n dimgYy: '696969',\n dodgerXe: '1e90ff',\n fiYbrick: 'b22222',\n flSOwEte: 'fffaf0',\n foYstWAn: '228b22',\n fuKsia: 'ff00ff',\n gaRsbSo: 'dcdcdc',\n ghostwEte: 'f8f8ff',\n gTd: 'ffd700',\n gTMnPd: 'daa520',\n Way: '808080',\n gYF: '8000',\n gYFLw: 'adff2f',\n gYy: '808080',\n honeyMw: 'f0fff0',\n hotpRk: 'ff69b4',\n RdianYd: 'cd5c5c',\n Rdigo: '4b0082',\n ivSy: 'fffff0',\n khaki: 'f0e68c',\n lavFMr: 'e6e6fa',\n lavFMrXsh: 'fff0f5',\n lawngYF: '7cfc00',\n NmoncEffon: 'fffacd',\n ZXe: 'add8e6',\n ZcSO: 'f08080',\n Zcyan: 'e0ffff',\n ZgTMnPdLw: 'fafad2',\n ZWay: 'd3d3d3',\n ZgYF: '90ee90',\n ZgYy: 'd3d3d3',\n ZpRk: 'ffb6c1',\n ZsOmon: 'ffa07a',\n ZsHgYF: '20b2aa',\n ZskyXe: '87cefa',\n ZUWay: '778899',\n ZUgYy: '778899',\n ZstAlXe: 'b0c4de',\n ZLw: 'ffffe0',\n lime: 'ff00',\n limegYF: '32cd32',\n lRF: 'faf0e6',\n magFta: 'ff00ff',\n maPon: '800000',\n VaquamarRe: '66cdaa',\n VXe: 'cd',\n VScEd: 'ba55d3',\n VpurpN: '9370db',\n VsHgYF: '3cb371',\n VUXe: '7b68ee',\n VsprRggYF: 'fa9a',\n VQe: '48d1cc',\n VviTetYd: 'c71585',\n midnightXe: '191970',\n mRtcYam: 'f5fffa',\n mistyPse: 'ffe4e1',\n moccasR: 'ffe4b5',\n navajowEte: 'ffdead',\n navy: '80',\n Tdlace: 'fdf5e6',\n Tive: '808000',\n TivedBb: '6b8e23',\n Sange: 'ffa500',\n SangeYd: 'ff4500',\n ScEd: 'da70d6',\n pOegTMnPd: 'eee8aa',\n pOegYF: '98fb98',\n pOeQe: 'afeeee',\n pOeviTetYd: 'db7093',\n papayawEp: 'ffefd5',\n pHKpuff: 'ffdab9',\n peru: 'cd853f',\n pRk: 'ffc0cb',\n plum: 'dda0dd',\n powMrXe: 'b0e0e6',\n purpN: '800080',\n YbeccapurpN: '663399',\n Yd: 'ff0000',\n Psybrown: 'bc8f8f',\n PyOXe: '4169e1',\n saddNbPwn: '8b4513',\n sOmon: 'fa8072',\n sandybPwn: 'f4a460',\n sHgYF: '2e8b57',\n sHshell: 'fff5ee',\n siFna: 'a0522d',\n silver: 'c0c0c0',\n skyXe: '87ceeb',\n UXe: '6a5acd',\n UWay: '708090',\n UgYy: '708090',\n snow: 'fffafa',\n sprRggYF: 'ff7f',\n stAlXe: '4682b4',\n tan: 'd2b48c',\n teO: '8080',\n tEstN: 'd8bfd8',\n tomato: 'ff6347',\n Qe: '40e0d0',\n viTet: 'ee82ee',\n JHt: 'f5deb3',\n wEte: 'ffffff',\n wEtesmoke: 'f5f5f5',\n Lw: 'ffff00',\n LwgYF: '9acd32'\n};\nfunction unpack() {\n const unpacked = {};\n const keys = Object.keys(names$1);\n const tkeys = Object.keys(map);\n let i, j, k, ok, nk;\n for (i = 0; i < keys.length; i++) {\n ok = nk = keys[i];\n for (j = 0; j < tkeys.length; j++) {\n k = tkeys[j];\n nk = nk.replace(k, map[k]);\n }\n k = parseInt(names$1[ok], 16);\n unpacked[nk] = [k >> 16 & 0xFF, k >> 8 & 0xFF, k & 0xFF];\n }\n return unpacked;\n}\n\nlet names;\nfunction nameParse(str) {\n if (!names) {\n names = unpack();\n names.transparent = [0, 0, 0, 0];\n }\n const a = names[str.toLowerCase()];\n return a && {\n r: a[0],\n g: a[1],\n b: a[2],\n a: a.length === 4 ? a[3] : 255\n };\n}\n\nconst RGB_RE = /^rgba?\\(\\s*([-+.\\d]+)(%)?[\\s,]+([-+.e\\d]+)(%)?[\\s,]+([-+.e\\d]+)(%)?(?:[\\s,/]+([-+.e\\d]+)(%)?)?\\s*\\)$/;\nfunction rgbParse(str) {\n const m = RGB_RE.exec(str);\n let a = 255;\n let r, g, b;\n if (!m) {\n return;\n }\n if (m[7] !== r) {\n const v = +m[7];\n a = m[8] ? p2b(v) : lim(v * 255, 0, 255);\n }\n r = +m[1];\n g = +m[3];\n b = +m[5];\n r = 255 & (m[2] ? p2b(r) : lim(r, 0, 255));\n g = 255 & (m[4] ? p2b(g) : lim(g, 0, 255));\n b = 255 & (m[6] ? p2b(b) : lim(b, 0, 255));\n return {\n r: r,\n g: g,\n b: b,\n a: a\n };\n}\nfunction rgbString(v) {\n return v && (\n v.a < 255\n ? `rgba(${v.r}, ${v.g}, ${v.b}, ${b2n(v.a)})`\n : `rgb(${v.r}, ${v.g}, ${v.b})`\n );\n}\n\nconst to = v => v <= 0.0031308 ? v * 12.92 : Math.pow(v, 1.0 / 2.4) * 1.055 - 0.055;\nconst from = v => v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);\nfunction interpolate(rgb1, rgb2, t) {\n const r = from(b2n(rgb1.r));\n const g = from(b2n(rgb1.g));\n const b = from(b2n(rgb1.b));\n return {\n r: n2b(to(r + t * (from(b2n(rgb2.r)) - r))),\n g: n2b(to(g + t * (from(b2n(rgb2.g)) - g))),\n b: n2b(to(b + t * (from(b2n(rgb2.b)) - b))),\n a: rgb1.a + t * (rgb2.a - rgb1.a)\n };\n}\n\nfunction modHSL(v, i, ratio) {\n if (v) {\n let tmp = rgb2hsl(v);\n tmp[i] = Math.max(0, Math.min(tmp[i] + tmp[i] * ratio, i === 0 ? 360 : 1));\n tmp = hsl2rgb(tmp);\n v.r = tmp[0];\n v.g = tmp[1];\n v.b = tmp[2];\n }\n}\nfunction clone(v, proto) {\n return v ? Object.assign(proto || {}, v) : v;\n}\nfunction fromObject(input) {\n var v = {r: 0, g: 0, b: 0, a: 255};\n if (Array.isArray(input)) {\n if (input.length >= 3) {\n v = {r: input[0], g: input[1], b: input[2], a: 255};\n if (input.length > 3) {\n v.a = n2b(input[3]);\n }\n }\n } else {\n v = clone(input, {r: 0, g: 0, b: 0, a: 1});\n v.a = n2b(v.a);\n }\n return v;\n}\nfunction functionParse(str) {\n if (str.charAt(0) === 'r') {\n return rgbParse(str);\n }\n return hueParse(str);\n}\nclass Color {\n constructor(input) {\n if (input instanceof Color) {\n return input;\n }\n const type = typeof input;\n let v;\n if (type === 'object') {\n v = fromObject(input);\n } else if (type === 'string') {\n v = hexParse(input) || nameParse(input) || functionParse(input);\n }\n this._rgb = v;\n this._valid = !!v;\n }\n get valid() {\n return this._valid;\n }\n get rgb() {\n var v = clone(this._rgb);\n if (v) {\n v.a = b2n(v.a);\n }\n return v;\n }\n set rgb(obj) {\n this._rgb = fromObject(obj);\n }\n rgbString() {\n return this._valid ? rgbString(this._rgb) : undefined;\n }\n hexString() {\n return this._valid ? hexString(this._rgb) : undefined;\n }\n hslString() {\n return this._valid ? hslString(this._rgb) : undefined;\n }\n mix(color, weight) {\n if (color) {\n const c1 = this.rgb;\n const c2 = color.rgb;\n let w2;\n const p = weight === w2 ? 0.5 : weight;\n const w = 2 * p - 1;\n const a = c1.a - c2.a;\n const w1 = ((w * a === -1 ? w : (w + a) / (1 + w * a)) + 1) / 2.0;\n w2 = 1 - w1;\n c1.r = 0xFF & w1 * c1.r + w2 * c2.r + 0.5;\n c1.g = 0xFF & w1 * c1.g + w2 * c2.g + 0.5;\n c1.b = 0xFF & w1 * c1.b + w2 * c2.b + 0.5;\n c1.a = p * c1.a + (1 - p) * c2.a;\n this.rgb = c1;\n }\n return this;\n }\n interpolate(color, t) {\n if (color) {\n this._rgb = interpolate(this._rgb, color._rgb, t);\n }\n return this;\n }\n clone() {\n return new Color(this.rgb);\n }\n alpha(a) {\n this._rgb.a = n2b(a);\n return this;\n }\n clearer(ratio) {\n const rgb = this._rgb;\n rgb.a *= 1 - ratio;\n return this;\n }\n greyscale() {\n const rgb = this._rgb;\n const val = round(rgb.r * 0.3 + rgb.g * 0.59 + rgb.b * 0.11);\n rgb.r = rgb.g = rgb.b = val;\n return this;\n }\n opaquer(ratio) {\n const rgb = this._rgb;\n rgb.a *= 1 + ratio;\n return this;\n }\n negate() {\n const v = this._rgb;\n v.r = 255 - v.r;\n v.g = 255 - v.g;\n v.b = 255 - v.b;\n return this;\n }\n lighten(ratio) {\n modHSL(this._rgb, 2, ratio);\n return this;\n }\n darken(ratio) {\n modHSL(this._rgb, 2, -ratio);\n return this;\n }\n saturate(ratio) {\n modHSL(this._rgb, 1, ratio);\n return this;\n }\n desaturate(ratio) {\n modHSL(this._rgb, 1, -ratio);\n return this;\n }\n rotate(deg) {\n rotate(this._rgb, deg);\n return this;\n }\n}\n\nfunction index_esm(input) {\n return new Color(input);\n}\n\n\n\n;// ./node_modules/chart.js/dist/chunks/helpers.segment.js\n/*!\n * Chart.js v4.4.4\n * https://www.chartjs.org\n * (c) 2024 Chart.js Contributors\n * Released under the MIT License\n */\n\n\n/**\n * @namespace Chart.helpers\n */ /**\n * An empty function that can be used, for example, for optional callback.\n */ function noop() {\n/* noop */ }\n/**\n * Returns a unique id, sequentially generated from a global variable.\n */ const uid = (()=>{\n let id = 0;\n return ()=>id++;\n})();\n/**\n * Returns true if `value` is neither null nor undefined, else returns false.\n * @param value - The value to test.\n * @since 2.7.0\n */ function isNullOrUndef(value) {\n return value === null || typeof value === 'undefined';\n}\n/**\n * Returns true if `value` is an array (including typed arrays), else returns false.\n * @param value - The value to test.\n * @function\n */ function isArray(value) {\n if (Array.isArray && Array.isArray(value)) {\n return true;\n }\n const type = Object.prototype.toString.call(value);\n if (type.slice(0, 7) === '[object' && type.slice(-6) === 'Array]') {\n return true;\n }\n return false;\n}\n/**\n * Returns true if `value` is an object (excluding null), else returns false.\n * @param value - The value to test.\n * @since 2.7.0\n */ function isObject(value) {\n return value !== null && Object.prototype.toString.call(value) === '[object Object]';\n}\n/**\n * Returns true if `value` is a finite number, else returns false\n * @param value - The value to test.\n */ function isNumberFinite(value) {\n return (typeof value === 'number' || value instanceof Number) && isFinite(+value);\n}\n/**\n * Returns `value` if finite, else returns `defaultValue`.\n * @param value - The value to return if defined.\n * @param defaultValue - The value to return if `value` is not finite.\n */ function finiteOrDefault(value, defaultValue) {\n return isNumberFinite(value) ? value : defaultValue;\n}\n/**\n * Returns `value` if defined, else returns `defaultValue`.\n * @param value - The value to return if defined.\n * @param defaultValue - The value to return if `value` is undefined.\n */ function valueOrDefault(value, defaultValue) {\n return typeof value === 'undefined' ? defaultValue : value;\n}\nconst toPercentage = (value, dimension)=>typeof value === 'string' && value.endsWith('%') ? parseFloat(value) / 100 : +value / dimension;\nconst toDimension = (value, dimension)=>typeof value === 'string' && value.endsWith('%') ? parseFloat(value) / 100 * dimension : +value;\n/**\n * Calls `fn` with the given `args` in the scope defined by `thisArg` and returns the\n * value returned by `fn`. If `fn` is not a function, this method returns undefined.\n * @param fn - The function to call.\n * @param args - The arguments with which `fn` should be called.\n * @param [thisArg] - The value of `this` provided for the call to `fn`.\n */ function callback(fn, args, thisArg) {\n if (fn && typeof fn.call === 'function') {\n return fn.apply(thisArg, args);\n }\n}\nfunction each(loopable, fn, thisArg, reverse) {\n let i, len, keys;\n if (isArray(loopable)) {\n len = loopable.length;\n if (reverse) {\n for(i = len - 1; i >= 0; i--){\n fn.call(thisArg, loopable[i], i);\n }\n } else {\n for(i = 0; i < len; i++){\n fn.call(thisArg, loopable[i], i);\n }\n }\n } else if (isObject(loopable)) {\n keys = Object.keys(loopable);\n len = keys.length;\n for(i = 0; i < len; i++){\n fn.call(thisArg, loopable[keys[i]], keys[i]);\n }\n }\n}\n/**\n * Returns true if the `a0` and `a1` arrays have the same content, else returns false.\n * @param a0 - The array to compare\n * @param a1 - The array to compare\n * @private\n */ function _elementsEqual(a0, a1) {\n let i, ilen, v0, v1;\n if (!a0 || !a1 || a0.length !== a1.length) {\n return false;\n }\n for(i = 0, ilen = a0.length; i < ilen; ++i){\n v0 = a0[i];\n v1 = a1[i];\n if (v0.datasetIndex !== v1.datasetIndex || v0.index !== v1.index) {\n return false;\n }\n }\n return true;\n}\n/**\n * Returns a deep copy of `source` without keeping references on objects and arrays.\n * @param source - The value to clone.\n */ function helpers_segment_clone(source) {\n if (isArray(source)) {\n return source.map(helpers_segment_clone);\n }\n if (isObject(source)) {\n const target = Object.create(null);\n const keys = Object.keys(source);\n const klen = keys.length;\n let k = 0;\n for(; k < klen; ++k){\n target[keys[k]] = helpers_segment_clone(source[keys[k]]);\n }\n return target;\n }\n return source;\n}\nfunction isValidKey(key) {\n return [\n '__proto__',\n 'prototype',\n 'constructor'\n ].indexOf(key) === -1;\n}\n/**\n * The default merger when Chart.helpers.merge is called without merger option.\n * Note(SB): also used by mergeConfig and mergeScaleConfig as fallback.\n * @private\n */ function _merger(key, target, source, options) {\n if (!isValidKey(key)) {\n return;\n }\n const tval = target[key];\n const sval = source[key];\n if (isObject(tval) && isObject(sval)) {\n // eslint-disable-next-line @typescript-eslint/no-use-before-define\n merge(tval, sval, options);\n } else {\n target[key] = helpers_segment_clone(sval);\n }\n}\nfunction merge(target, source, options) {\n const sources = isArray(source) ? source : [\n source\n ];\n const ilen = sources.length;\n if (!isObject(target)) {\n return target;\n }\n options = options || {};\n const merger = options.merger || _merger;\n let current;\n for(let i = 0; i < ilen; ++i){\n current = sources[i];\n if (!isObject(current)) {\n continue;\n }\n const keys = Object.keys(current);\n for(let k = 0, klen = keys.length; k < klen; ++k){\n merger(keys[k], target, current, options);\n }\n }\n return target;\n}\nfunction mergeIf(target, source) {\n // eslint-disable-next-line @typescript-eslint/no-use-before-define\n return merge(target, source, {\n merger: _mergerIf\n });\n}\n/**\n * Merges source[key] in target[key] only if target[key] is undefined.\n * @private\n */ function _mergerIf(key, target, source) {\n if (!isValidKey(key)) {\n return;\n }\n const tval = target[key];\n const sval = source[key];\n if (isObject(tval) && isObject(sval)) {\n mergeIf(tval, sval);\n } else if (!Object.prototype.hasOwnProperty.call(target, key)) {\n target[key] = helpers_segment_clone(sval);\n }\n}\n/**\n * @private\n */ function _deprecated(scope, value, previous, current) {\n if (value !== undefined) {\n console.warn(scope + ': \"' + previous + '\" is deprecated. Please use \"' + current + '\" instead');\n }\n}\n// resolveObjectKey resolver cache\nconst keyResolvers = {\n // Chart.helpers.core resolveObjectKey should resolve empty key to root object\n '': (v)=>v,\n // default resolvers\n x: (o)=>o.x,\n y: (o)=>o.y\n};\n/**\n * @private\n */ function _splitKey(key) {\n const parts = key.split('.');\n const keys = [];\n let tmp = '';\n for (const part of parts){\n tmp += part;\n if (tmp.endsWith('\\\\')) {\n tmp = tmp.slice(0, -1) + '.';\n } else {\n keys.push(tmp);\n tmp = '';\n }\n }\n return keys;\n}\nfunction _getKeyResolver(key) {\n const keys = _splitKey(key);\n return (obj)=>{\n for (const k of keys){\n if (k === '') {\n break;\n }\n obj = obj && obj[k];\n }\n return obj;\n };\n}\nfunction resolveObjectKey(obj, key) {\n const resolver = keyResolvers[key] || (keyResolvers[key] = _getKeyResolver(key));\n return resolver(obj);\n}\n/**\n * @private\n */ function _capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nconst defined = (value)=>typeof value !== 'undefined';\nconst isFunction = (value)=>typeof value === 'function';\n// Adapted from https://stackoverflow.com/questions/31128855/comparing-ecma6-sets-for-equality#31129384\nconst setsEqual = (a, b)=>{\n if (a.size !== b.size) {\n return false;\n }\n for (const item of a){\n if (!b.has(item)) {\n return false;\n }\n }\n return true;\n};\n/**\n * @param e - The event\n * @private\n */ function _isClickEvent(e) {\n return e.type === 'mouseup' || e.type === 'click' || e.type === 'contextmenu';\n}\n\n/**\n * @alias Chart.helpers.math\n * @namespace\n */ const PI = Math.PI;\nconst TAU = 2 * PI;\nconst PITAU = TAU + PI;\nconst INFINITY = Number.POSITIVE_INFINITY;\nconst RAD_PER_DEG = PI / 180;\nconst HALF_PI = PI / 2;\nconst QUARTER_PI = PI / 4;\nconst TWO_THIRDS_PI = PI * 2 / 3;\nconst log10 = Math.log10;\nconst sign = Math.sign;\nfunction almostEquals(x, y, epsilon) {\n return Math.abs(x - y) < epsilon;\n}\n/**\n * Implementation of the nice number algorithm used in determining where axis labels will go\n */ function niceNum(range) {\n const roundedRange = Math.round(range);\n range = almostEquals(range, roundedRange, range / 1000) ? roundedRange : range;\n const niceRange = Math.pow(10, Math.floor(log10(range)));\n const fraction = range / niceRange;\n const niceFraction = fraction <= 1 ? 1 : fraction <= 2 ? 2 : fraction <= 5 ? 5 : 10;\n return niceFraction * niceRange;\n}\n/**\n * Returns an array of factors sorted from 1 to sqrt(value)\n * @private\n */ function _factorize(value) {\n const result = [];\n const sqrt = Math.sqrt(value);\n let i;\n for(i = 1; i < sqrt; i++){\n if (value % i === 0) {\n result.push(i);\n result.push(value / i);\n }\n }\n if (sqrt === (sqrt | 0)) {\n result.push(sqrt);\n }\n result.sort((a, b)=>a - b).pop();\n return result;\n}\nfunction isNumber(n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n}\nfunction almostWhole(x, epsilon) {\n const rounded = Math.round(x);\n return rounded - epsilon <= x && rounded + epsilon >= x;\n}\n/**\n * @private\n */ function _setMinAndMaxByKey(array, target, property) {\n let i, ilen, value;\n for(i = 0, ilen = array.length; i < ilen; i++){\n value = array[i][property];\n if (!isNaN(value)) {\n target.min = Math.min(target.min, value);\n target.max = Math.max(target.max, value);\n }\n }\n}\nfunction toRadians(degrees) {\n return degrees * (PI / 180);\n}\nfunction toDegrees(radians) {\n return radians * (180 / PI);\n}\n/**\n * Returns the number of decimal places\n * i.e. the number of digits after the decimal point, of the value of this Number.\n * @param x - A number.\n * @returns The number of decimal places.\n * @private\n */ function _decimalPlaces(x) {\n if (!isNumberFinite(x)) {\n return;\n }\n let e = 1;\n let p = 0;\n while(Math.round(x * e) / e !== x){\n e *= 10;\n p++;\n }\n return p;\n}\n// Gets the angle from vertical upright to the point about a centre.\nfunction getAngleFromPoint(centrePoint, anglePoint) {\n const distanceFromXCenter = anglePoint.x - centrePoint.x;\n const distanceFromYCenter = anglePoint.y - centrePoint.y;\n const radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);\n let angle = Math.atan2(distanceFromYCenter, distanceFromXCenter);\n if (angle < -0.5 * PI) {\n angle += TAU; // make sure the returned angle is in the range of (-PI/2, 3PI/2]\n }\n return {\n angle,\n distance: radialDistanceFromCenter\n };\n}\nfunction distanceBetweenPoints(pt1, pt2) {\n return Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2));\n}\n/**\n * Shortest distance between angles, in either direction.\n * @private\n */ function _angleDiff(a, b) {\n return (a - b + PITAU) % TAU - PI;\n}\n/**\n * Normalize angle to be between 0 and 2*PI\n * @private\n */ function _normalizeAngle(a) {\n return (a % TAU + TAU) % TAU;\n}\n/**\n * @private\n */ function _angleBetween(angle, start, end, sameAngleIsFullCircle) {\n const a = _normalizeAngle(angle);\n const s = _normalizeAngle(start);\n const e = _normalizeAngle(end);\n const angleToStart = _normalizeAngle(s - a);\n const angleToEnd = _normalizeAngle(e - a);\n const startToAngle = _normalizeAngle(a - s);\n const endToAngle = _normalizeAngle(a - e);\n return a === s || a === e || sameAngleIsFullCircle && s === e || angleToStart > angleToEnd && startToAngle < endToAngle;\n}\n/**\n * Limit `value` between `min` and `max`\n * @param value\n * @param min\n * @param max\n * @private\n */ function _limitValue(value, min, max) {\n return Math.max(min, Math.min(max, value));\n}\n/**\n * @param {number} value\n * @private\n */ function _int16Range(value) {\n return _limitValue(value, -32768, 32767);\n}\n/**\n * @param value\n * @param start\n * @param end\n * @param [epsilon]\n * @private\n */ function _isBetween(value, start, end, epsilon = 1e-6) {\n return value >= Math.min(start, end) - epsilon && value <= Math.max(start, end) + epsilon;\n}\n\nfunction _lookup(table, value, cmp) {\n cmp = cmp || ((index)=>table[index] < value);\n let hi = table.length - 1;\n let lo = 0;\n let mid;\n while(hi - lo > 1){\n mid = lo + hi >> 1;\n if (cmp(mid)) {\n lo = mid;\n } else {\n hi = mid;\n }\n }\n return {\n lo,\n hi\n };\n}\n/**\n * Binary search\n * @param table - the table search. must be sorted!\n * @param key - property name for the value in each entry\n * @param value - value to find\n * @param last - lookup last index\n * @private\n */ const _lookupByKey = (table, key, value, last)=>_lookup(table, value, last ? (index)=>{\n const ti = table[index][key];\n return ti < value || ti === value && table[index + 1][key] === value;\n } : (index)=>table[index][key] < value);\n/**\n * Reverse binary search\n * @param table - the table search. must be sorted!\n * @param key - property name for the value in each entry\n * @param value - value to find\n * @private\n */ const _rlookupByKey = (table, key, value)=>_lookup(table, value, (index)=>table[index][key] >= value);\n/**\n * Return subset of `values` between `min` and `max` inclusive.\n * Values are assumed to be in sorted order.\n * @param values - sorted array of values\n * @param min - min value\n * @param max - max value\n */ function _filterBetween(values, min, max) {\n let start = 0;\n let end = values.length;\n while(start < end && values[start] < min){\n start++;\n }\n while(end > start && values[end - 1] > max){\n end--;\n }\n return start > 0 || end < values.length ? values.slice(start, end) : values;\n}\nconst arrayEvents = [\n 'push',\n 'pop',\n 'shift',\n 'splice',\n 'unshift'\n];\nfunction listenArrayEvents(array, listener) {\n if (array._chartjs) {\n array._chartjs.listeners.push(listener);\n return;\n }\n Object.defineProperty(array, '_chartjs', {\n configurable: true,\n enumerable: false,\n value: {\n listeners: [\n listener\n ]\n }\n });\n arrayEvents.forEach((key)=>{\n const method = '_onData' + _capitalize(key);\n const base = array[key];\n Object.defineProperty(array, key, {\n configurable: true,\n enumerable: false,\n value (...args) {\n const res = base.apply(this, args);\n array._chartjs.listeners.forEach((object)=>{\n if (typeof object[method] === 'function') {\n object[method](...args);\n }\n });\n return res;\n }\n });\n });\n}\nfunction unlistenArrayEvents(array, listener) {\n const stub = array._chartjs;\n if (!stub) {\n return;\n }\n const listeners = stub.listeners;\n const index = listeners.indexOf(listener);\n if (index !== -1) {\n listeners.splice(index, 1);\n }\n if (listeners.length > 0) {\n return;\n }\n arrayEvents.forEach((key)=>{\n delete array[key];\n });\n delete array._chartjs;\n}\n/**\n * @param items\n */ function _arrayUnique(items) {\n const set = new Set(items);\n if (set.size === items.length) {\n return items;\n }\n return Array.from(set);\n}\n\nfunction fontString(pixelSize, fontStyle, fontFamily) {\n return fontStyle + ' ' + pixelSize + 'px ' + fontFamily;\n}\n/**\n* Request animation polyfill\n*/ const requestAnimFrame = function() {\n if (typeof window === 'undefined') {\n return function(callback) {\n return callback();\n };\n }\n return window.requestAnimationFrame;\n}();\n/**\n * Throttles calling `fn` once per animation frame\n * Latest arguments are used on the actual call\n */ function throttled(fn, thisArg) {\n let argsToUse = [];\n let ticking = false;\n return function(...args) {\n // Save the args for use later\n argsToUse = args;\n if (!ticking) {\n ticking = true;\n requestAnimFrame.call(window, ()=>{\n ticking = false;\n fn.apply(thisArg, argsToUse);\n });\n }\n };\n}\n/**\n * Debounces calling `fn` for `delay` ms\n */ function debounce(fn, delay) {\n let timeout;\n return function(...args) {\n if (delay) {\n clearTimeout(timeout);\n timeout = setTimeout(fn, delay, args);\n } else {\n fn.apply(this, args);\n }\n return delay;\n };\n}\n/**\n * Converts 'start' to 'left', 'end' to 'right' and others to 'center'\n * @private\n */ const _toLeftRightCenter = (align)=>align === 'start' ? 'left' : align === 'end' ? 'right' : 'center';\n/**\n * Returns `start`, `end` or `(start + end) / 2` depending on `align`. Defaults to `center`\n * @private\n */ const _alignStartEnd = (align, start, end)=>align === 'start' ? start : align === 'end' ? end : (start + end) / 2;\n/**\n * Returns `left`, `right` or `(left + right) / 2` depending on `align`. Defaults to `left`\n * @private\n */ const _textX = (align, left, right, rtl)=>{\n const check = rtl ? 'left' : 'right';\n return align === check ? right : align === 'center' ? (left + right) / 2 : left;\n};\n/**\n * Return start and count of visible points.\n * @private\n */ function _getStartAndCountOfVisiblePoints(meta, points, animationsDisabled) {\n const pointCount = points.length;\n let start = 0;\n let count = pointCount;\n if (meta._sorted) {\n const { iScale , _parsed } = meta;\n const axis = iScale.axis;\n const { min , max , minDefined , maxDefined } = iScale.getUserBounds();\n if (minDefined) {\n start = _limitValue(Math.min(// @ts-expect-error Need to type _parsed\n _lookupByKey(_parsed, axis, min).lo, // @ts-expect-error Need to fix types on _lookupByKey\n animationsDisabled ? pointCount : _lookupByKey(points, axis, iScale.getPixelForValue(min)).lo), 0, pointCount - 1);\n }\n if (maxDefined) {\n count = _limitValue(Math.max(// @ts-expect-error Need to type _parsed\n _lookupByKey(_parsed, iScale.axis, max, true).hi + 1, // @ts-expect-error Need to fix types on _lookupByKey\n animationsDisabled ? 0 : _lookupByKey(points, axis, iScale.getPixelForValue(max), true).hi + 1), start, pointCount) - start;\n } else {\n count = pointCount - start;\n }\n }\n return {\n start,\n count\n };\n}\n/**\n * Checks if the scale ranges have changed.\n * @param {object} meta - dataset meta.\n * @returns {boolean}\n * @private\n */ function _scaleRangesChanged(meta) {\n const { xScale , yScale , _scaleRanges } = meta;\n const newRanges = {\n xmin: xScale.min,\n xmax: xScale.max,\n ymin: yScale.min,\n ymax: yScale.max\n };\n if (!_scaleRanges) {\n meta._scaleRanges = newRanges;\n return true;\n }\n const changed = _scaleRanges.xmin !== xScale.min || _scaleRanges.xmax !== xScale.max || _scaleRanges.ymin !== yScale.min || _scaleRanges.ymax !== yScale.max;\n Object.assign(_scaleRanges, newRanges);\n return changed;\n}\n\nconst atEdge = (t)=>t === 0 || t === 1;\nconst elasticIn = (t, s, p)=>-(Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * TAU / p));\nconst elasticOut = (t, s, p)=>Math.pow(2, -10 * t) * Math.sin((t - s) * TAU / p) + 1;\n/**\n * Easing functions adapted from Robert Penner's easing equations.\n * @namespace Chart.helpers.easing.effects\n * @see http://www.robertpenner.com/easing/\n */ const effects = {\n linear: (t)=>t,\n easeInQuad: (t)=>t * t,\n easeOutQuad: (t)=>-t * (t - 2),\n easeInOutQuad: (t)=>(t /= 0.5) < 1 ? 0.5 * t * t : -0.5 * (--t * (t - 2) - 1),\n easeInCubic: (t)=>t * t * t,\n easeOutCubic: (t)=>(t -= 1) * t * t + 1,\n easeInOutCubic: (t)=>(t /= 0.5) < 1 ? 0.5 * t * t * t : 0.5 * ((t -= 2) * t * t + 2),\n easeInQuart: (t)=>t * t * t * t,\n easeOutQuart: (t)=>-((t -= 1) * t * t * t - 1),\n easeInOutQuart: (t)=>(t /= 0.5) < 1 ? 0.5 * t * t * t * t : -0.5 * ((t -= 2) * t * t * t - 2),\n easeInQuint: (t)=>t * t * t * t * t,\n easeOutQuint: (t)=>(t -= 1) * t * t * t * t + 1,\n easeInOutQuint: (t)=>(t /= 0.5) < 1 ? 0.5 * t * t * t * t * t : 0.5 * ((t -= 2) * t * t * t * t + 2),\n easeInSine: (t)=>-Math.cos(t * HALF_PI) + 1,\n easeOutSine: (t)=>Math.sin(t * HALF_PI),\n easeInOutSine: (t)=>-0.5 * (Math.cos(PI * t) - 1),\n easeInExpo: (t)=>t === 0 ? 0 : Math.pow(2, 10 * (t - 1)),\n easeOutExpo: (t)=>t === 1 ? 1 : -Math.pow(2, -10 * t) + 1,\n easeInOutExpo: (t)=>atEdge(t) ? t : t < 0.5 ? 0.5 * Math.pow(2, 10 * (t * 2 - 1)) : 0.5 * (-Math.pow(2, -10 * (t * 2 - 1)) + 2),\n easeInCirc: (t)=>t >= 1 ? t : -(Math.sqrt(1 - t * t) - 1),\n easeOutCirc: (t)=>Math.sqrt(1 - (t -= 1) * t),\n easeInOutCirc: (t)=>(t /= 0.5) < 1 ? -0.5 * (Math.sqrt(1 - t * t) - 1) : 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1),\n easeInElastic: (t)=>atEdge(t) ? t : elasticIn(t, 0.075, 0.3),\n easeOutElastic: (t)=>atEdge(t) ? t : elasticOut(t, 0.075, 0.3),\n easeInOutElastic (t) {\n const s = 0.1125;\n const p = 0.45;\n return atEdge(t) ? t : t < 0.5 ? 0.5 * elasticIn(t * 2, s, p) : 0.5 + 0.5 * elasticOut(t * 2 - 1, s, p);\n },\n easeInBack (t) {\n const s = 1.70158;\n return t * t * ((s + 1) * t - s);\n },\n easeOutBack (t) {\n const s = 1.70158;\n return (t -= 1) * t * ((s + 1) * t + s) + 1;\n },\n easeInOutBack (t) {\n let s = 1.70158;\n if ((t /= 0.5) < 1) {\n return 0.5 * (t * t * (((s *= 1.525) + 1) * t - s));\n }\n return 0.5 * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2);\n },\n easeInBounce: (t)=>1 - effects.easeOutBounce(1 - t),\n easeOutBounce (t) {\n const m = 7.5625;\n const d = 2.75;\n if (t < 1 / d) {\n return m * t * t;\n }\n if (t < 2 / d) {\n return m * (t -= 1.5 / d) * t + 0.75;\n }\n if (t < 2.5 / d) {\n return m * (t -= 2.25 / d) * t + 0.9375;\n }\n return m * (t -= 2.625 / d) * t + 0.984375;\n },\n easeInOutBounce: (t)=>t < 0.5 ? effects.easeInBounce(t * 2) * 0.5 : effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5\n};\n\nfunction isPatternOrGradient(value) {\n if (value && typeof value === 'object') {\n const type = value.toString();\n return type === '[object CanvasPattern]' || type === '[object CanvasGradient]';\n }\n return false;\n}\nfunction color(value) {\n return isPatternOrGradient(value) ? value : new Color(value);\n}\nfunction getHoverColor(value) {\n return isPatternOrGradient(value) ? value : new Color(value).saturate(0.5).darken(0.1).hexString();\n}\n\nconst numbers = [\n 'x',\n 'y',\n 'borderWidth',\n 'radius',\n 'tension'\n];\nconst colors = [\n 'color',\n 'borderColor',\n 'backgroundColor'\n];\nfunction applyAnimationsDefaults(defaults) {\n defaults.set('animation', {\n delay: undefined,\n duration: 1000,\n easing: 'easeOutQuart',\n fn: undefined,\n from: undefined,\n loop: undefined,\n to: undefined,\n type: undefined\n });\n defaults.describe('animation', {\n _fallback: false,\n _indexable: false,\n _scriptable: (name)=>name !== 'onProgress' && name !== 'onComplete' && name !== 'fn'\n });\n defaults.set('animations', {\n colors: {\n type: 'color',\n properties: colors\n },\n numbers: {\n type: 'number',\n properties: numbers\n }\n });\n defaults.describe('animations', {\n _fallback: 'animation'\n });\n defaults.set('transitions', {\n active: {\n animation: {\n duration: 400\n }\n },\n resize: {\n animation: {\n duration: 0\n }\n },\n show: {\n animations: {\n colors: {\n from: 'transparent'\n },\n visible: {\n type: 'boolean',\n duration: 0\n }\n }\n },\n hide: {\n animations: {\n colors: {\n to: 'transparent'\n },\n visible: {\n type: 'boolean',\n easing: 'linear',\n fn: (v)=>v | 0\n }\n }\n }\n });\n}\n\nfunction applyLayoutsDefaults(defaults) {\n defaults.set('layout', {\n autoPadding: true,\n padding: {\n top: 0,\n right: 0,\n bottom: 0,\n left: 0\n }\n });\n}\n\nconst intlCache = new Map();\nfunction getNumberFormat(locale, options) {\n options = options || {};\n const cacheKey = locale + JSON.stringify(options);\n let formatter = intlCache.get(cacheKey);\n if (!formatter) {\n formatter = new Intl.NumberFormat(locale, options);\n intlCache.set(cacheKey, formatter);\n }\n return formatter;\n}\nfunction formatNumber(num, locale, options) {\n return getNumberFormat(locale, options).format(num);\n}\n\nconst formatters = {\n values (value) {\n return isArray(value) ? value : '' + value;\n },\n numeric (tickValue, index, ticks) {\n if (tickValue === 0) {\n return '0';\n }\n const locale = this.chart.options.locale;\n let notation;\n let delta = tickValue;\n if (ticks.length > 1) {\n const maxTick = Math.max(Math.abs(ticks[0].value), Math.abs(ticks[ticks.length - 1].value));\n if (maxTick < 1e-4 || maxTick > 1e+15) {\n notation = 'scientific';\n }\n delta = calculateDelta(tickValue, ticks);\n }\n const logDelta = log10(Math.abs(delta));\n const numDecimal = isNaN(logDelta) ? 1 : Math.max(Math.min(-1 * Math.floor(logDelta), 20), 0);\n const options = {\n notation,\n minimumFractionDigits: numDecimal,\n maximumFractionDigits: numDecimal\n };\n Object.assign(options, this.options.ticks.format);\n return formatNumber(tickValue, locale, options);\n },\n logarithmic (tickValue, index, ticks) {\n if (tickValue === 0) {\n return '0';\n }\n const remain = ticks[index].significand || tickValue / Math.pow(10, Math.floor(log10(tickValue)));\n if ([\n 1,\n 2,\n 3,\n 5,\n 10,\n 15\n ].includes(remain) || index > 0.8 * ticks.length) {\n return formatters.numeric.call(this, tickValue, index, ticks);\n }\n return '';\n }\n};\nfunction calculateDelta(tickValue, ticks) {\n let delta = ticks.length > 3 ? ticks[2].value - ticks[1].value : ticks[1].value - ticks[0].value;\n if (Math.abs(delta) >= 1 && tickValue !== Math.floor(tickValue)) {\n delta = tickValue - Math.floor(tickValue);\n }\n return delta;\n}\n var Ticks = {\n formatters\n};\n\nfunction applyScaleDefaults(defaults) {\n defaults.set('scale', {\n display: true,\n offset: false,\n reverse: false,\n beginAtZero: false,\n bounds: 'ticks',\n clip: true,\n grace: 0,\n grid: {\n display: true,\n lineWidth: 1,\n drawOnChartArea: true,\n drawTicks: true,\n tickLength: 8,\n tickWidth: (_ctx, options)=>options.lineWidth,\n tickColor: (_ctx, options)=>options.color,\n offset: false\n },\n border: {\n display: true,\n dash: [],\n dashOffset: 0.0,\n width: 1\n },\n title: {\n display: false,\n text: '',\n padding: {\n top: 4,\n bottom: 4\n }\n },\n ticks: {\n minRotation: 0,\n maxRotation: 50,\n mirror: false,\n textStrokeWidth: 0,\n textStrokeColor: '',\n padding: 3,\n display: true,\n autoSkip: true,\n autoSkipPadding: 3,\n labelOffset: 0,\n callback: Ticks.formatters.values,\n minor: {},\n major: {},\n align: 'center',\n crossAlign: 'near',\n showLabelBackdrop: false,\n backdropColor: 'rgba(255, 255, 255, 0.75)',\n backdropPadding: 2\n }\n });\n defaults.route('scale.ticks', 'color', '', 'color');\n defaults.route('scale.grid', 'color', '', 'borderColor');\n defaults.route('scale.border', 'color', '', 'borderColor');\n defaults.route('scale.title', 'color', '', 'color');\n defaults.describe('scale', {\n _fallback: false,\n _scriptable: (name)=>!name.startsWith('before') && !name.startsWith('after') && name !== 'callback' && name !== 'parser',\n _indexable: (name)=>name !== 'borderDash' && name !== 'tickBorderDash' && name !== 'dash'\n });\n defaults.describe('scales', {\n _fallback: 'scale'\n });\n defaults.describe('scale.ticks', {\n _scriptable: (name)=>name !== 'backdropPadding' && name !== 'callback',\n _indexable: (name)=>name !== 'backdropPadding'\n });\n}\n\nconst overrides = Object.create(null);\nconst descriptors = Object.create(null);\n function getScope$1(node, key) {\n if (!key) {\n return node;\n }\n const keys = key.split('.');\n for(let i = 0, n = keys.length; i < n; ++i){\n const k = keys[i];\n node = node[k] || (node[k] = Object.create(null));\n }\n return node;\n}\nfunction set(root, scope, values) {\n if (typeof scope === 'string') {\n return merge(getScope$1(root, scope), values);\n }\n return merge(getScope$1(root, ''), scope);\n}\n class Defaults {\n constructor(_descriptors, _appliers){\n this.animation = undefined;\n this.backgroundColor = 'rgba(0,0,0,0.1)';\n this.borderColor = 'rgba(0,0,0,0.1)';\n this.color = '#666';\n this.datasets = {};\n this.devicePixelRatio = (context)=>context.chart.platform.getDevicePixelRatio();\n this.elements = {};\n this.events = [\n 'mousemove',\n 'mouseout',\n 'click',\n 'touchstart',\n 'touchmove'\n ];\n this.font = {\n family: \"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\",\n size: 12,\n style: 'normal',\n lineHeight: 1.2,\n weight: null\n };\n this.hover = {};\n this.hoverBackgroundColor = (ctx, options)=>getHoverColor(options.backgroundColor);\n this.hoverBorderColor = (ctx, options)=>getHoverColor(options.borderColor);\n this.hoverColor = (ctx, options)=>getHoverColor(options.color);\n this.indexAxis = 'x';\n this.interaction = {\n mode: 'nearest',\n intersect: true,\n includeInvisible: false\n };\n this.maintainAspectRatio = true;\n this.onHover = null;\n this.onClick = null;\n this.parsing = true;\n this.plugins = {};\n this.responsive = true;\n this.scale = undefined;\n this.scales = {};\n this.showLine = true;\n this.drawActiveElementsOnTop = true;\n this.describe(_descriptors);\n this.apply(_appliers);\n }\n set(scope, values) {\n return set(this, scope, values);\n }\n get(scope) {\n return getScope$1(this, scope);\n }\n describe(scope, values) {\n return set(descriptors, scope, values);\n }\n override(scope, values) {\n return set(overrides, scope, values);\n }\n route(scope, name, targetScope, targetName) {\n const scopeObject = getScope$1(this, scope);\n const targetScopeObject = getScope$1(this, targetScope);\n const privateName = '_' + name;\n Object.defineProperties(scopeObject, {\n [privateName]: {\n value: scopeObject[name],\n writable: true\n },\n [name]: {\n enumerable: true,\n get () {\n const local = this[privateName];\n const target = targetScopeObject[targetName];\n if (isObject(local)) {\n return Object.assign({}, target, local);\n }\n return valueOrDefault(local, target);\n },\n set (value) {\n this[privateName] = value;\n }\n }\n });\n }\n apply(appliers) {\n appliers.forEach((apply)=>apply(this));\n }\n}\nvar defaults = /* #__PURE__ */ new Defaults({\n _scriptable: (name)=>!name.startsWith('on'),\n _indexable: (name)=>name !== 'events',\n hover: {\n _fallback: 'interaction'\n },\n interaction: {\n _scriptable: false,\n _indexable: false\n }\n}, [\n applyAnimationsDefaults,\n applyLayoutsDefaults,\n applyScaleDefaults\n]);\n\n/**\n * Converts the given font object into a CSS font string.\n * @param font - A font object.\n * @return The CSS font string. See https://developer.mozilla.org/en-US/docs/Web/CSS/font\n * @private\n */ function toFontString(font) {\n if (!font || isNullOrUndef(font.size) || isNullOrUndef(font.family)) {\n return null;\n }\n return (font.style ? font.style + ' ' : '') + (font.weight ? font.weight + ' ' : '') + font.size + 'px ' + font.family;\n}\n/**\n * @private\n */ function _measureText(ctx, data, gc, longest, string) {\n let textWidth = data[string];\n if (!textWidth) {\n textWidth = data[string] = ctx.measureText(string).width;\n gc.push(string);\n }\n if (textWidth > longest) {\n longest = textWidth;\n }\n return longest;\n}\n/**\n * @private\n */ // eslint-disable-next-line complexity\nfunction _longestText(ctx, font, arrayOfThings, cache) {\n cache = cache || {};\n let data = cache.data = cache.data || {};\n let gc = cache.garbageCollect = cache.garbageCollect || [];\n if (cache.font !== font) {\n data = cache.data = {};\n gc = cache.garbageCollect = [];\n cache.font = font;\n }\n ctx.save();\n ctx.font = font;\n let longest = 0;\n const ilen = arrayOfThings.length;\n let i, j, jlen, thing, nestedThing;\n for(i = 0; i < ilen; i++){\n thing = arrayOfThings[i];\n // Undefined strings and arrays should not be measured\n if (thing !== undefined && thing !== null && !isArray(thing)) {\n longest = _measureText(ctx, data, gc, longest, thing);\n } else if (isArray(thing)) {\n // if it is an array lets measure each element\n // to do maybe simplify this function a bit so we can do this more recursively?\n for(j = 0, jlen = thing.length; j < jlen; j++){\n nestedThing = thing[j];\n // Undefined strings and arrays should not be measured\n if (nestedThing !== undefined && nestedThing !== null && !isArray(nestedThing)) {\n longest = _measureText(ctx, data, gc, longest, nestedThing);\n }\n }\n }\n }\n ctx.restore();\n const gcLen = gc.length / 2;\n if (gcLen > arrayOfThings.length) {\n for(i = 0; i < gcLen; i++){\n delete data[gc[i]];\n }\n gc.splice(0, gcLen);\n }\n return longest;\n}\n/**\n * Returns the aligned pixel value to avoid anti-aliasing blur\n * @param chart - The chart instance.\n * @param pixel - A pixel value.\n * @param width - The width of the element.\n * @returns The aligned pixel value.\n * @private\n */ function _alignPixel(chart, pixel, width) {\n const devicePixelRatio = chart.currentDevicePixelRatio;\n const halfWidth = width !== 0 ? Math.max(width / 2, 0.5) : 0;\n return Math.round((pixel - halfWidth) * devicePixelRatio) / devicePixelRatio + halfWidth;\n}\n/**\n * Clears the entire canvas.\n */ function clearCanvas(canvas, ctx) {\n if (!ctx && !canvas) {\n return;\n }\n ctx = ctx || canvas.getContext('2d');\n ctx.save();\n // canvas.width and canvas.height do not consider the canvas transform,\n // while clearRect does\n ctx.resetTransform();\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n ctx.restore();\n}\nfunction drawPoint(ctx, options, x, y) {\n // eslint-disable-next-line @typescript-eslint/no-use-before-define\n drawPointLegend(ctx, options, x, y, null);\n}\n// eslint-disable-next-line complexity\nfunction drawPointLegend(ctx, options, x, y, w) {\n let type, xOffset, yOffset, size, cornerRadius, width, xOffsetW, yOffsetW;\n const style = options.pointStyle;\n const rotation = options.rotation;\n const radius = options.radius;\n let rad = (rotation || 0) * RAD_PER_DEG;\n if (style && typeof style === 'object') {\n type = style.toString();\n if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {\n ctx.save();\n ctx.translate(x, y);\n ctx.rotate(rad);\n ctx.drawImage(style, -style.width / 2, -style.height / 2, style.width, style.height);\n ctx.restore();\n return;\n }\n }\n if (isNaN(radius) || radius <= 0) {\n return;\n }\n ctx.beginPath();\n switch(style){\n // Default includes circle\n default:\n if (w) {\n ctx.ellipse(x, y, w / 2, radius, 0, 0, TAU);\n } else {\n ctx.arc(x, y, radius, 0, TAU);\n }\n ctx.closePath();\n break;\n case 'triangle':\n width = w ? w / 2 : radius;\n ctx.moveTo(x + Math.sin(rad) * width, y - Math.cos(rad) * radius);\n rad += TWO_THIRDS_PI;\n ctx.lineTo(x + Math.sin(rad) * width, y - Math.cos(rad) * radius);\n rad += TWO_THIRDS_PI;\n ctx.lineTo(x + Math.sin(rad) * width, y - Math.cos(rad) * radius);\n ctx.closePath();\n break;\n case 'rectRounded':\n // NOTE: the rounded rect implementation changed to use `arc` instead of\n // `quadraticCurveTo` since it generates better results when rect is\n // almost a circle. 0.516 (instead of 0.5) produces results with visually\n // closer proportion to the previous impl and it is inscribed in the\n // circle with `radius`. For more details, see the following PRs:\n // https://github.com/chartjs/Chart.js/issues/5597\n // https://github.com/chartjs/Chart.js/issues/5858\n cornerRadius = radius * 0.516;\n size = radius - cornerRadius;\n xOffset = Math.cos(rad + QUARTER_PI) * size;\n xOffsetW = Math.cos(rad + QUARTER_PI) * (w ? w / 2 - cornerRadius : size);\n yOffset = Math.sin(rad + QUARTER_PI) * size;\n yOffsetW = Math.sin(rad + QUARTER_PI) * (w ? w / 2 - cornerRadius : size);\n ctx.arc(x - xOffsetW, y - yOffset, cornerRadius, rad - PI, rad - HALF_PI);\n ctx.arc(x + yOffsetW, y - xOffset, cornerRadius, rad - HALF_PI, rad);\n ctx.arc(x + xOffsetW, y + yOffset, cornerRadius, rad, rad + HALF_PI);\n ctx.arc(x - yOffsetW, y + xOffset, cornerRadius, rad + HALF_PI, rad + PI);\n ctx.closePath();\n break;\n case 'rect':\n if (!rotation) {\n size = Math.SQRT1_2 * radius;\n width = w ? w / 2 : size;\n ctx.rect(x - width, y - size, 2 * width, 2 * size);\n break;\n }\n rad += QUARTER_PI;\n /* falls through */ case 'rectRot':\n xOffsetW = Math.cos(rad) * (w ? w / 2 : radius);\n xOffset = Math.cos(rad) * radius;\n yOffset = Math.sin(rad) * radius;\n yOffsetW = Math.sin(rad) * (w ? w / 2 : radius);\n ctx.moveTo(x - xOffsetW, y - yOffset);\n ctx.lineTo(x + yOffsetW, y - xOffset);\n ctx.lineTo(x + xOffsetW, y + yOffset);\n ctx.lineTo(x - yOffsetW, y + xOffset);\n ctx.closePath();\n break;\n case 'crossRot':\n rad += QUARTER_PI;\n /* falls through */ case 'cross':\n xOffsetW = Math.cos(rad) * (w ? w / 2 : radius);\n xOffset = Math.cos(rad) * radius;\n yOffset = Math.sin(rad) * radius;\n yOffsetW = Math.sin(rad) * (w ? w / 2 : radius);\n ctx.moveTo(x - xOffsetW, y - yOffset);\n ctx.lineTo(x + xOffsetW, y + yOffset);\n ctx.moveTo(x + yOffsetW, y - xOffset);\n ctx.lineTo(x - yOffsetW, y + xOffset);\n break;\n case 'star':\n xOffsetW = Math.cos(rad) * (w ? w / 2 : radius);\n xOffset = Math.cos(rad) * radius;\n yOffset = Math.sin(rad) * radius;\n yOffsetW = Math.sin(rad) * (w ? w / 2 : radius);\n ctx.moveTo(x - xOffsetW, y - yOffset);\n ctx.lineTo(x + xOffsetW, y + yOffset);\n ctx.moveTo(x + yOffsetW, y - xOffset);\n ctx.lineTo(x - yOffsetW, y + xOffset);\n rad += QUARTER_PI;\n xOffsetW = Math.cos(rad) * (w ? w / 2 : radius);\n xOffset = Math.cos(rad) * radius;\n yOffset = Math.sin(rad) * radius;\n yOffsetW = Math.sin(rad) * (w ? w / 2 : radius);\n ctx.moveTo(x - xOffsetW, y - yOffset);\n ctx.lineTo(x + xOffsetW, y + yOffset);\n ctx.moveTo(x + yOffsetW, y - xOffset);\n ctx.lineTo(x - yOffsetW, y + xOffset);\n break;\n case 'line':\n xOffset = w ? w / 2 : Math.cos(rad) * radius;\n yOffset = Math.sin(rad) * radius;\n ctx.moveTo(x - xOffset, y - yOffset);\n ctx.lineTo(x + xOffset, y + yOffset);\n break;\n case 'dash':\n ctx.moveTo(x, y);\n ctx.lineTo(x + Math.cos(rad) * (w ? w / 2 : radius), y + Math.sin(rad) * radius);\n break;\n case false:\n ctx.closePath();\n break;\n }\n ctx.fill();\n if (options.borderWidth > 0) {\n ctx.stroke();\n }\n}\n/**\n * Returns true if the point is inside the rectangle\n * @param point - The point to test\n * @param area - The rectangle\n * @param margin - allowed margin\n * @private\n */ function _isPointInArea(point, area, margin) {\n margin = margin || 0.5; // margin - default is to match rounded decimals\n return !area || point && point.x > area.left - margin && point.x < area.right + margin && point.y > area.top - margin && point.y < area.bottom + margin;\n}\nfunction clipArea(ctx, area) {\n ctx.save();\n ctx.beginPath();\n ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top);\n ctx.clip();\n}\nfunction unclipArea(ctx) {\n ctx.restore();\n}\n/**\n * @private\n */ function _steppedLineTo(ctx, previous, target, flip, mode) {\n if (!previous) {\n return ctx.lineTo(target.x, target.y);\n }\n if (mode === 'middle') {\n const midpoint = (previous.x + target.x) / 2.0;\n ctx.lineTo(midpoint, previous.y);\n ctx.lineTo(midpoint, target.y);\n } else if (mode === 'after' !== !!flip) {\n ctx.lineTo(previous.x, target.y);\n } else {\n ctx.lineTo(target.x, previous.y);\n }\n ctx.lineTo(target.x, target.y);\n}\n/**\n * @private\n */ function _bezierCurveTo(ctx, previous, target, flip) {\n if (!previous) {\n return ctx.lineTo(target.x, target.y);\n }\n ctx.bezierCurveTo(flip ? previous.cp1x : previous.cp2x, flip ? previous.cp1y : previous.cp2y, flip ? target.cp2x : target.cp1x, flip ? target.cp2y : target.cp1y, target.x, target.y);\n}\nfunction setRenderOpts(ctx, opts) {\n if (opts.translation) {\n ctx.translate(opts.translation[0], opts.translation[1]);\n }\n if (!isNullOrUndef(opts.rotation)) {\n ctx.rotate(opts.rotation);\n }\n if (opts.color) {\n ctx.fillStyle = opts.color;\n }\n if (opts.textAlign) {\n ctx.textAlign = opts.textAlign;\n }\n if (opts.textBaseline) {\n ctx.textBaseline = opts.textBaseline;\n }\n}\nfunction decorateText(ctx, x, y, line, opts) {\n if (opts.strikethrough || opts.underline) {\n /**\n * Now that IE11 support has been dropped, we can use more\n * of the TextMetrics object. The actual bounding boxes\n * are unflagged in Chrome, Firefox, Edge, and Safari so they\n * can be safely used.\n * See https://developer.mozilla.org/en-US/docs/Web/API/TextMetrics#Browser_compatibility\n */ const metrics = ctx.measureText(line);\n const left = x - metrics.actualBoundingBoxLeft;\n const right = x + metrics.actualBoundingBoxRight;\n const top = y - metrics.actualBoundingBoxAscent;\n const bottom = y + metrics.actualBoundingBoxDescent;\n const yDecoration = opts.strikethrough ? (top + bottom) / 2 : bottom;\n ctx.strokeStyle = ctx.fillStyle;\n ctx.beginPath();\n ctx.lineWidth = opts.decorationWidth || 2;\n ctx.moveTo(left, yDecoration);\n ctx.lineTo(right, yDecoration);\n ctx.stroke();\n }\n}\nfunction drawBackdrop(ctx, opts) {\n const oldColor = ctx.fillStyle;\n ctx.fillStyle = opts.color;\n ctx.fillRect(opts.left, opts.top, opts.width, opts.height);\n ctx.fillStyle = oldColor;\n}\n/**\n * Render text onto the canvas\n */ function renderText(ctx, text, x, y, font, opts = {}) {\n const lines = isArray(text) ? text : [\n text\n ];\n const stroke = opts.strokeWidth > 0 && opts.strokeColor !== '';\n let i, line;\n ctx.save();\n ctx.font = font.string;\n setRenderOpts(ctx, opts);\n for(i = 0; i < lines.length; ++i){\n line = lines[i];\n if (opts.backdrop) {\n drawBackdrop(ctx, opts.backdrop);\n }\n if (stroke) {\n if (opts.strokeColor) {\n ctx.strokeStyle = opts.strokeColor;\n }\n if (!isNullOrUndef(opts.strokeWidth)) {\n ctx.lineWidth = opts.strokeWidth;\n }\n ctx.strokeText(line, x, y, opts.maxWidth);\n }\n ctx.fillText(line, x, y, opts.maxWidth);\n decorateText(ctx, x, y, line, opts);\n y += Number(font.lineHeight);\n }\n ctx.restore();\n}\n/**\n * Add a path of a rectangle with rounded corners to the current sub-path\n * @param ctx - Context\n * @param rect - Bounding rect\n */ function addRoundedRectPath(ctx, rect) {\n const { x , y , w , h , radius } = rect;\n // top left arc\n ctx.arc(x + radius.topLeft, y + radius.topLeft, radius.topLeft, 1.5 * PI, PI, true);\n // line from top left to bottom left\n ctx.lineTo(x, y + h - radius.bottomLeft);\n // bottom left arc\n ctx.arc(x + radius.bottomLeft, y + h - radius.bottomLeft, radius.bottomLeft, PI, HALF_PI, true);\n // line from bottom left to bottom right\n ctx.lineTo(x + w - radius.bottomRight, y + h);\n // bottom right arc\n ctx.arc(x + w - radius.bottomRight, y + h - radius.bottomRight, radius.bottomRight, HALF_PI, 0, true);\n // line from bottom right to top right\n ctx.lineTo(x + w, y + radius.topRight);\n // top right arc\n ctx.arc(x + w - radius.topRight, y + radius.topRight, radius.topRight, 0, -HALF_PI, true);\n // line from top right to top left\n ctx.lineTo(x + radius.topLeft, y);\n}\n\nconst LINE_HEIGHT = /^(normal|(\\d+(?:\\.\\d+)?)(px|em|%)?)$/;\nconst FONT_STYLE = /^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/;\n/**\n * @alias Chart.helpers.options\n * @namespace\n */ /**\n * Converts the given line height `value` in pixels for a specific font `size`.\n * @param value - The lineHeight to parse (eg. 1.6, '14px', '75%', '1.6em').\n * @param size - The font size (in pixels) used to resolve relative `value`.\n * @returns The effective line height in pixels (size * 1.2 if value is invalid).\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/line-height\n * @since 2.7.0\n */ function toLineHeight(value, size) {\n const matches = ('' + value).match(LINE_HEIGHT);\n if (!matches || matches[1] === 'normal') {\n return size * 1.2;\n }\n value = +matches[2];\n switch(matches[3]){\n case 'px':\n return value;\n case '%':\n value /= 100;\n break;\n }\n return size * value;\n}\nconst numberOrZero = (v)=>+v || 0;\nfunction _readValueToProps(value, props) {\n const ret = {};\n const objProps = isObject(props);\n const keys = objProps ? Object.keys(props) : props;\n const read = isObject(value) ? objProps ? (prop)=>valueOrDefault(value[prop], value[props[prop]]) : (prop)=>value[prop] : ()=>value;\n for (const prop of keys){\n ret[prop] = numberOrZero(read(prop));\n }\n return ret;\n}\n/**\n * Converts the given value into a TRBL object.\n * @param value - If a number, set the value to all TRBL component,\n * else, if an object, use defined properties and sets undefined ones to 0.\n * x / y are shorthands for same value for left/right and top/bottom.\n * @returns The padding values (top, right, bottom, left)\n * @since 3.0.0\n */ function toTRBL(value) {\n return _readValueToProps(value, {\n top: 'y',\n right: 'x',\n bottom: 'y',\n left: 'x'\n });\n}\n/**\n * Converts the given value into a TRBL corners object (similar with css border-radius).\n * @param value - If a number, set the value to all TRBL corner components,\n * else, if an object, use defined properties and sets undefined ones to 0.\n * @returns The TRBL corner values (topLeft, topRight, bottomLeft, bottomRight)\n * @since 3.0.0\n */ function toTRBLCorners(value) {\n return _readValueToProps(value, [\n 'topLeft',\n 'topRight',\n 'bottomLeft',\n 'bottomRight'\n ]);\n}\n/**\n * Converts the given value into a padding object with pre-computed width/height.\n * @param value - If a number, set the value to all TRBL component,\n * else, if an object, use defined properties and sets undefined ones to 0.\n * x / y are shorthands for same value for left/right and top/bottom.\n * @returns The padding values (top, right, bottom, left, width, height)\n * @since 2.7.0\n */ function toPadding(value) {\n const obj = toTRBL(value);\n obj.width = obj.left + obj.right;\n obj.height = obj.top + obj.bottom;\n return obj;\n}\n/**\n * Parses font options and returns the font object.\n * @param options - A object that contains font options to be parsed.\n * @param fallback - A object that contains fallback font options.\n * @return The font object.\n * @private\n */ function toFont(options, fallback) {\n options = options || {};\n fallback = fallback || defaults.font;\n let size = valueOrDefault(options.size, fallback.size);\n if (typeof size === 'string') {\n size = parseInt(size, 10);\n }\n let style = valueOrDefault(options.style, fallback.style);\n if (style && !('' + style).match(FONT_STYLE)) {\n console.warn('Invalid font style specified: \"' + style + '\"');\n style = undefined;\n }\n const font = {\n family: valueOrDefault(options.family, fallback.family),\n lineHeight: toLineHeight(valueOrDefault(options.lineHeight, fallback.lineHeight), size),\n size,\n style,\n weight: valueOrDefault(options.weight, fallback.weight),\n string: ''\n };\n font.string = toFontString(font);\n return font;\n}\n/**\n * Evaluates the given `inputs` sequentially and returns the first defined value.\n * @param inputs - An array of values, falling back to the last value.\n * @param context - If defined and the current value is a function, the value\n * is called with `context` as first argument and the result becomes the new input.\n * @param index - If defined and the current value is an array, the value\n * at `index` become the new input.\n * @param info - object to return information about resolution in\n * @param info.cacheable - Will be set to `false` if option is not cacheable.\n * @since 2.7.0\n */ function resolve(inputs, context, index, info) {\n let cacheable = true;\n let i, ilen, value;\n for(i = 0, ilen = inputs.length; i < ilen; ++i){\n value = inputs[i];\n if (value === undefined) {\n continue;\n }\n if (context !== undefined && typeof value === 'function') {\n value = value(context);\n cacheable = false;\n }\n if (index !== undefined && isArray(value)) {\n value = value[index % value.length];\n cacheable = false;\n }\n if (value !== undefined) {\n if (info && !cacheable) {\n info.cacheable = false;\n }\n return value;\n }\n }\n}\n/**\n * @param minmax\n * @param grace\n * @param beginAtZero\n * @private\n */ function _addGrace(minmax, grace, beginAtZero) {\n const { min , max } = minmax;\n const change = toDimension(grace, (max - min) / 2);\n const keepZero = (value, add)=>beginAtZero && value === 0 ? 0 : value + add;\n return {\n min: keepZero(min, -Math.abs(change)),\n max: keepZero(max, change)\n };\n}\nfunction createContext(parentContext, context) {\n return Object.assign(Object.create(parentContext), context);\n}\n\n/**\n * Creates a Proxy for resolving raw values for options.\n * @param scopes - The option scopes to look for values, in resolution order\n * @param prefixes - The prefixes for values, in resolution order.\n * @param rootScopes - The root option scopes\n * @param fallback - Parent scopes fallback\n * @param getTarget - callback for getting the target for changed values\n * @returns Proxy\n * @private\n */ function _createResolver(scopes, prefixes = [\n ''\n], rootScopes, fallback, getTarget = ()=>scopes[0]) {\n const finalRootScopes = rootScopes || scopes;\n if (typeof fallback === 'undefined') {\n fallback = _resolve('_fallback', scopes);\n }\n const cache = {\n [Symbol.toStringTag]: 'Object',\n _cacheable: true,\n _scopes: scopes,\n _rootScopes: finalRootScopes,\n _fallback: fallback,\n _getTarget: getTarget,\n override: (scope)=>_createResolver([\n scope,\n ...scopes\n ], prefixes, finalRootScopes, fallback)\n };\n return new Proxy(cache, {\n /**\n * A trap for the delete operator.\n */ deleteProperty (target, prop) {\n delete target[prop]; // remove from cache\n delete target._keys; // remove cached keys\n delete scopes[0][prop]; // remove from top level scope\n return true;\n },\n /**\n * A trap for getting property values.\n */ get (target, prop) {\n return _cached(target, prop, ()=>_resolveWithPrefixes(prop, prefixes, scopes, target));\n },\n /**\n * A trap for Object.getOwnPropertyDescriptor.\n * Also used by Object.hasOwnProperty.\n */ getOwnPropertyDescriptor (target, prop) {\n return Reflect.getOwnPropertyDescriptor(target._scopes[0], prop);\n },\n /**\n * A trap for Object.getPrototypeOf.\n */ getPrototypeOf () {\n return Reflect.getPrototypeOf(scopes[0]);\n },\n /**\n * A trap for the in operator.\n */ has (target, prop) {\n return getKeysFromAllScopes(target).includes(prop);\n },\n /**\n * A trap for Object.getOwnPropertyNames and Object.getOwnPropertySymbols.\n */ ownKeys (target) {\n return getKeysFromAllScopes(target);\n },\n /**\n * A trap for setting property values.\n */ set (target, prop, value) {\n const storage = target._storage || (target._storage = getTarget());\n target[prop] = storage[prop] = value; // set to top level scope + cache\n delete target._keys; // remove cached keys\n return true;\n }\n });\n}\n/**\n * Returns an Proxy for resolving option values with context.\n * @param proxy - The Proxy returned by `_createResolver`\n * @param context - Context object for scriptable/indexable options\n * @param subProxy - The proxy provided for scriptable options\n * @param descriptorDefaults - Defaults for descriptors\n * @private\n */ function _attachContext(proxy, context, subProxy, descriptorDefaults) {\n const cache = {\n _cacheable: false,\n _proxy: proxy,\n _context: context,\n _subProxy: subProxy,\n _stack: new Set(),\n _descriptors: _descriptors(proxy, descriptorDefaults),\n setContext: (ctx)=>_attachContext(proxy, ctx, subProxy, descriptorDefaults),\n override: (scope)=>_attachContext(proxy.override(scope), context, subProxy, descriptorDefaults)\n };\n return new Proxy(cache, {\n /**\n * A trap for the delete operator.\n */ deleteProperty (target, prop) {\n delete target[prop]; // remove from cache\n delete proxy[prop]; // remove from proxy\n return true;\n },\n /**\n * A trap for getting property values.\n */ get (target, prop, receiver) {\n return _cached(target, prop, ()=>_resolveWithContext(target, prop, receiver));\n },\n /**\n * A trap for Object.getOwnPropertyDescriptor.\n * Also used by Object.hasOwnProperty.\n */ getOwnPropertyDescriptor (target, prop) {\n return target._descriptors.allKeys ? Reflect.has(proxy, prop) ? {\n enumerable: true,\n configurable: true\n } : undefined : Reflect.getOwnPropertyDescriptor(proxy, prop);\n },\n /**\n * A trap for Object.getPrototypeOf.\n */ getPrototypeOf () {\n return Reflect.getPrototypeOf(proxy);\n },\n /**\n * A trap for the in operator.\n */ has (target, prop) {\n return Reflect.has(proxy, prop);\n },\n /**\n * A trap for Object.getOwnPropertyNames and Object.getOwnPropertySymbols.\n */ ownKeys () {\n return Reflect.ownKeys(proxy);\n },\n /**\n * A trap for setting property values.\n */ set (target, prop, value) {\n proxy[prop] = value; // set to proxy\n delete target[prop]; // remove from cache\n return true;\n }\n });\n}\n/**\n * @private\n */ function _descriptors(proxy, defaults = {\n scriptable: true,\n indexable: true\n}) {\n const { _scriptable =defaults.scriptable , _indexable =defaults.indexable , _allKeys =defaults.allKeys } = proxy;\n return {\n allKeys: _allKeys,\n scriptable: _scriptable,\n indexable: _indexable,\n isScriptable: isFunction(_scriptable) ? _scriptable : ()=>_scriptable,\n isIndexable: isFunction(_indexable) ? _indexable : ()=>_indexable\n };\n}\nconst readKey = (prefix, name)=>prefix ? prefix + _capitalize(name) : name;\nconst needsSubResolver = (prop, value)=>isObject(value) && prop !== 'adapters' && (Object.getPrototypeOf(value) === null || value.constructor === Object);\nfunction _cached(target, prop, resolve) {\n if (Object.prototype.hasOwnProperty.call(target, prop) || prop === 'constructor') {\n return target[prop];\n }\n const value = resolve();\n // cache the resolved value\n target[prop] = value;\n return value;\n}\nfunction _resolveWithContext(target, prop, receiver) {\n const { _proxy , _context , _subProxy , _descriptors: descriptors } = target;\n let value = _proxy[prop]; // resolve from proxy\n // resolve with context\n if (isFunction(value) && descriptors.isScriptable(prop)) {\n value = _resolveScriptable(prop, value, target, receiver);\n }\n if (isArray(value) && value.length) {\n value = _resolveArray(prop, value, target, descriptors.isIndexable);\n }\n if (needsSubResolver(prop, value)) {\n // if the resolved value is an object, create a sub resolver for it\n value = _attachContext(value, _context, _subProxy && _subProxy[prop], descriptors);\n }\n return value;\n}\nfunction _resolveScriptable(prop, getValue, target, receiver) {\n const { _proxy , _context , _subProxy , _stack } = target;\n if (_stack.has(prop)) {\n throw new Error('Recursion detected: ' + Array.from(_stack).join('->') + '->' + prop);\n }\n _stack.add(prop);\n let value = getValue(_context, _subProxy || receiver);\n _stack.delete(prop);\n if (needsSubResolver(prop, value)) {\n // When scriptable option returns an object, create a resolver on that.\n value = createSubResolver(_proxy._scopes, _proxy, prop, value);\n }\n return value;\n}\nfunction _resolveArray(prop, value, target, isIndexable) {\n const { _proxy , _context , _subProxy , _descriptors: descriptors } = target;\n if (typeof _context.index !== 'undefined' && isIndexable(prop)) {\n return value[_context.index % value.length];\n } else if (isObject(value[0])) {\n // Array of objects, return array or resolvers\n const arr = value;\n const scopes = _proxy._scopes.filter((s)=>s !== arr);\n value = [];\n for (const item of arr){\n const resolver = createSubResolver(scopes, _proxy, prop, item);\n value.push(_attachContext(resolver, _context, _subProxy && _subProxy[prop], descriptors));\n }\n }\n return value;\n}\nfunction resolveFallback(fallback, prop, value) {\n return isFunction(fallback) ? fallback(prop, value) : fallback;\n}\nconst getScope = (key, parent)=>key === true ? parent : typeof key === 'string' ? resolveObjectKey(parent, key) : undefined;\nfunction addScopes(set, parentScopes, key, parentFallback, value) {\n for (const parent of parentScopes){\n const scope = getScope(key, parent);\n if (scope) {\n set.add(scope);\n const fallback = resolveFallback(scope._fallback, key, value);\n if (typeof fallback !== 'undefined' && fallback !== key && fallback !== parentFallback) {\n // When we reach the descriptor that defines a new _fallback, return that.\n // The fallback will resume to that new scope.\n return fallback;\n }\n } else if (scope === false && typeof parentFallback !== 'undefined' && key !== parentFallback) {\n // Fallback to `false` results to `false`, when falling back to different key.\n // For example `interaction` from `hover` or `plugins.tooltip` and `animation` from `animations`\n return null;\n }\n }\n return false;\n}\nfunction createSubResolver(parentScopes, resolver, prop, value) {\n const rootScopes = resolver._rootScopes;\n const fallback = resolveFallback(resolver._fallback, prop, value);\n const allScopes = [\n ...parentScopes,\n ...rootScopes\n ];\n const set = new Set();\n set.add(value);\n let key = addScopesFromKey(set, allScopes, prop, fallback || prop, value);\n if (key === null) {\n return false;\n }\n if (typeof fallback !== 'undefined' && fallback !== prop) {\n key = addScopesFromKey(set, allScopes, fallback, key, value);\n if (key === null) {\n return false;\n }\n }\n return _createResolver(Array.from(set), [\n ''\n ], rootScopes, fallback, ()=>subGetTarget(resolver, prop, value));\n}\nfunction addScopesFromKey(set, allScopes, key, fallback, item) {\n while(key){\n key = addScopes(set, allScopes, key, fallback, item);\n }\n return key;\n}\nfunction subGetTarget(resolver, prop, value) {\n const parent = resolver._getTarget();\n if (!(prop in parent)) {\n parent[prop] = {};\n }\n const target = parent[prop];\n if (isArray(target) && isObject(value)) {\n // For array of objects, the object is used to store updated values\n return value;\n }\n return target || {};\n}\nfunction _resolveWithPrefixes(prop, prefixes, scopes, proxy) {\n let value;\n for (const prefix of prefixes){\n value = _resolve(readKey(prefix, prop), scopes);\n if (typeof value !== 'undefined') {\n return needsSubResolver(prop, value) ? createSubResolver(scopes, proxy, prop, value) : value;\n }\n }\n}\nfunction _resolve(key, scopes) {\n for (const scope of scopes){\n if (!scope) {\n continue;\n }\n const value = scope[key];\n if (typeof value !== 'undefined') {\n return value;\n }\n }\n}\nfunction getKeysFromAllScopes(target) {\n let keys = target._keys;\n if (!keys) {\n keys = target._keys = resolveKeysFromAllScopes(target._scopes);\n }\n return keys;\n}\nfunction resolveKeysFromAllScopes(scopes) {\n const set = new Set();\n for (const scope of scopes){\n for (const key of Object.keys(scope).filter((k)=>!k.startsWith('_'))){\n set.add(key);\n }\n }\n return Array.from(set);\n}\nfunction _parseObjectDataRadialScale(meta, data, start, count) {\n const { iScale } = meta;\n const { key ='r' } = this._parsing;\n const parsed = new Array(count);\n let i, ilen, index, item;\n for(i = 0, ilen = count; i < ilen; ++i){\n index = i + start;\n item = data[index];\n parsed[i] = {\n r: iScale.parse(resolveObjectKey(item, key), index)\n };\n }\n return parsed;\n}\n\nconst EPSILON = Number.EPSILON || 1e-14;\nconst getPoint = (points, i)=>i < points.length && !points[i].skip && points[i];\nconst getValueAxis = (indexAxis)=>indexAxis === 'x' ? 'y' : 'x';\nfunction splineCurve(firstPoint, middlePoint, afterPoint, t) {\n // Props to Rob Spencer at scaled innovation for his post on splining between points\n // http://scaledinnovation.com/analytics/splines/aboutSplines.html\n // This function must also respect \"skipped\" points\n const previous = firstPoint.skip ? middlePoint : firstPoint;\n const current = middlePoint;\n const next = afterPoint.skip ? middlePoint : afterPoint;\n const d01 = distanceBetweenPoints(current, previous);\n const d12 = distanceBetweenPoints(next, current);\n let s01 = d01 / (d01 + d12);\n let s12 = d12 / (d01 + d12);\n // If all points are the same, s01 & s02 will be inf\n s01 = isNaN(s01) ? 0 : s01;\n s12 = isNaN(s12) ? 0 : s12;\n const fa = t * s01; // scaling factor for triangle Ta\n const fb = t * s12;\n return {\n previous: {\n x: current.x - fa * (next.x - previous.x),\n y: current.y - fa * (next.y - previous.y)\n },\n next: {\n x: current.x + fb * (next.x - previous.x),\n y: current.y + fb * (next.y - previous.y)\n }\n };\n}\n/**\n * Adjust tangents to ensure monotonic properties\n */ function monotoneAdjust(points, deltaK, mK) {\n const pointsLen = points.length;\n let alphaK, betaK, tauK, squaredMagnitude, pointCurrent;\n let pointAfter = getPoint(points, 0);\n for(let i = 0; i < pointsLen - 1; ++i){\n pointCurrent = pointAfter;\n pointAfter = getPoint(points, i + 1);\n if (!pointCurrent || !pointAfter) {\n continue;\n }\n if (almostEquals(deltaK[i], 0, EPSILON)) {\n mK[i] = mK[i + 1] = 0;\n continue;\n }\n alphaK = mK[i] / deltaK[i];\n betaK = mK[i + 1] / deltaK[i];\n squaredMagnitude = Math.pow(alphaK, 2) + Math.pow(betaK, 2);\n if (squaredMagnitude <= 9) {\n continue;\n }\n tauK = 3 / Math.sqrt(squaredMagnitude);\n mK[i] = alphaK * tauK * deltaK[i];\n mK[i + 1] = betaK * tauK * deltaK[i];\n }\n}\nfunction monotoneCompute(points, mK, indexAxis = 'x') {\n const valueAxis = getValueAxis(indexAxis);\n const pointsLen = points.length;\n let delta, pointBefore, pointCurrent;\n let pointAfter = getPoint(points, 0);\n for(let i = 0; i < pointsLen; ++i){\n pointBefore = pointCurrent;\n pointCurrent = pointAfter;\n pointAfter = getPoint(points, i + 1);\n if (!pointCurrent) {\n continue;\n }\n const iPixel = pointCurrent[indexAxis];\n const vPixel = pointCurrent[valueAxis];\n if (pointBefore) {\n delta = (iPixel - pointBefore[indexAxis]) / 3;\n pointCurrent[`cp1${indexAxis}`] = iPixel - delta;\n pointCurrent[`cp1${valueAxis}`] = vPixel - delta * mK[i];\n }\n if (pointAfter) {\n delta = (pointAfter[indexAxis] - iPixel) / 3;\n pointCurrent[`cp2${indexAxis}`] = iPixel + delta;\n pointCurrent[`cp2${valueAxis}`] = vPixel + delta * mK[i];\n }\n }\n}\n/**\n * This function calculates Bézier control points in a similar way than |splineCurve|,\n * but preserves monotonicity of the provided data and ensures no local extremums are added\n * between the dataset discrete points due to the interpolation.\n * See : https://en.wikipedia.org/wiki/Monotone_cubic_interpolation\n */ function splineCurveMonotone(points, indexAxis = 'x') {\n const valueAxis = getValueAxis(indexAxis);\n const pointsLen = points.length;\n const deltaK = Array(pointsLen).fill(0);\n const mK = Array(pointsLen);\n // Calculate slopes (deltaK) and initialize tangents (mK)\n let i, pointBefore, pointCurrent;\n let pointAfter = getPoint(points, 0);\n for(i = 0; i < pointsLen; ++i){\n pointBefore = pointCurrent;\n pointCurrent = pointAfter;\n pointAfter = getPoint(points, i + 1);\n if (!pointCurrent) {\n continue;\n }\n if (pointAfter) {\n const slopeDelta = pointAfter[indexAxis] - pointCurrent[indexAxis];\n // In the case of two points that appear at the same x pixel, slopeDeltaX is 0\n deltaK[i] = slopeDelta !== 0 ? (pointAfter[valueAxis] - pointCurrent[valueAxis]) / slopeDelta : 0;\n }\n mK[i] = !pointBefore ? deltaK[i] : !pointAfter ? deltaK[i - 1] : sign(deltaK[i - 1]) !== sign(deltaK[i]) ? 0 : (deltaK[i - 1] + deltaK[i]) / 2;\n }\n monotoneAdjust(points, deltaK, mK);\n monotoneCompute(points, mK, indexAxis);\n}\nfunction capControlPoint(pt, min, max) {\n return Math.max(Math.min(pt, max), min);\n}\nfunction capBezierPoints(points, area) {\n let i, ilen, point, inArea, inAreaPrev;\n let inAreaNext = _isPointInArea(points[0], area);\n for(i = 0, ilen = points.length; i < ilen; ++i){\n inAreaPrev = inArea;\n inArea = inAreaNext;\n inAreaNext = i < ilen - 1 && _isPointInArea(points[i + 1], area);\n if (!inArea) {\n continue;\n }\n point = points[i];\n if (inAreaPrev) {\n point.cp1x = capControlPoint(point.cp1x, area.left, area.right);\n point.cp1y = capControlPoint(point.cp1y, area.top, area.bottom);\n }\n if (inAreaNext) {\n point.cp2x = capControlPoint(point.cp2x, area.left, area.right);\n point.cp2y = capControlPoint(point.cp2y, area.top, area.bottom);\n }\n }\n}\n/**\n * @private\n */ function _updateBezierControlPoints(points, options, area, loop, indexAxis) {\n let i, ilen, point, controlPoints;\n // Only consider points that are drawn in case the spanGaps option is used\n if (options.spanGaps) {\n points = points.filter((pt)=>!pt.skip);\n }\n if (options.cubicInterpolationMode === 'monotone') {\n splineCurveMonotone(points, indexAxis);\n } else {\n let prev = loop ? points[points.length - 1] : points[0];\n for(i = 0, ilen = points.length; i < ilen; ++i){\n point = points[i];\n controlPoints = splineCurve(prev, point, points[Math.min(i + 1, ilen - (loop ? 0 : 1)) % ilen], options.tension);\n point.cp1x = controlPoints.previous.x;\n point.cp1y = controlPoints.previous.y;\n point.cp2x = controlPoints.next.x;\n point.cp2y = controlPoints.next.y;\n prev = point;\n }\n }\n if (options.capBezierPoints) {\n capBezierPoints(points, area);\n }\n}\n\n/**\n * Note: typedefs are auto-exported, so use a made-up `dom` namespace where\n * necessary to avoid duplicates with `export * from './helpers`; see\n * https://github.com/microsoft/TypeScript/issues/46011\n * @typedef { import('../core/core.controller.js').default } dom.Chart\n * @typedef { import('../../types').ChartEvent } ChartEvent\n */ /**\n * @private\n */ function _isDomSupported() {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n/**\n * @private\n */ function _getParentNode(domNode) {\n let parent = domNode.parentNode;\n if (parent && parent.toString() === '[object ShadowRoot]') {\n parent = parent.host;\n }\n return parent;\n}\n/**\n * convert max-width/max-height values that may be percentages into a number\n * @private\n */ function parseMaxStyle(styleValue, node, parentProperty) {\n let valueInPixels;\n if (typeof styleValue === 'string') {\n valueInPixels = parseInt(styleValue, 10);\n if (styleValue.indexOf('%') !== -1) {\n // percentage * size in dimension\n valueInPixels = valueInPixels / 100 * node.parentNode[parentProperty];\n }\n } else {\n valueInPixels = styleValue;\n }\n return valueInPixels;\n}\nconst getComputedStyle = (element)=>element.ownerDocument.defaultView.getComputedStyle(element, null);\nfunction getStyle(el, property) {\n return getComputedStyle(el).getPropertyValue(property);\n}\nconst positions = [\n 'top',\n 'right',\n 'bottom',\n 'left'\n];\nfunction getPositionedStyle(styles, style, suffix) {\n const result = {};\n suffix = suffix ? '-' + suffix : '';\n for(let i = 0; i < 4; i++){\n const pos = positions[i];\n result[pos] = parseFloat(styles[style + '-' + pos + suffix]) || 0;\n }\n result.width = result.left + result.right;\n result.height = result.top + result.bottom;\n return result;\n}\nconst useOffsetPos = (x, y, target)=>(x > 0 || y > 0) && (!target || !target.shadowRoot);\n/**\n * @param e\n * @param canvas\n * @returns Canvas position\n */ function getCanvasPosition(e, canvas) {\n const touches = e.touches;\n const source = touches && touches.length ? touches[0] : e;\n const { offsetX , offsetY } = source;\n let box = false;\n let x, y;\n if (useOffsetPos(offsetX, offsetY, e.target)) {\n x = offsetX;\n y = offsetY;\n } else {\n const rect = canvas.getBoundingClientRect();\n x = source.clientX - rect.left;\n y = source.clientY - rect.top;\n box = true;\n }\n return {\n x,\n y,\n box\n };\n}\n/**\n * Gets an event's x, y coordinates, relative to the chart area\n * @param event\n * @param chart\n * @returns x and y coordinates of the event\n */ function getRelativePosition(event, chart) {\n if ('native' in event) {\n return event;\n }\n const { canvas , currentDevicePixelRatio } = chart;\n const style = getComputedStyle(canvas);\n const borderBox = style.boxSizing === 'border-box';\n const paddings = getPositionedStyle(style, 'padding');\n const borders = getPositionedStyle(style, 'border', 'width');\n const { x , y , box } = getCanvasPosition(event, canvas);\n const xOffset = paddings.left + (box && borders.left);\n const yOffset = paddings.top + (box && borders.top);\n let { width , height } = chart;\n if (borderBox) {\n width -= paddings.width + borders.width;\n height -= paddings.height + borders.height;\n }\n return {\n x: Math.round((x - xOffset) / width * canvas.width / currentDevicePixelRatio),\n y: Math.round((y - yOffset) / height * canvas.height / currentDevicePixelRatio)\n };\n}\nfunction getContainerSize(canvas, width, height) {\n let maxWidth, maxHeight;\n if (width === undefined || height === undefined) {\n const container = canvas && _getParentNode(canvas);\n if (!container) {\n width = canvas.clientWidth;\n height = canvas.clientHeight;\n } else {\n const rect = container.getBoundingClientRect(); // this is the border box of the container\n const containerStyle = getComputedStyle(container);\n const containerBorder = getPositionedStyle(containerStyle, 'border', 'width');\n const containerPadding = getPositionedStyle(containerStyle, 'padding');\n width = rect.width - containerPadding.width - containerBorder.width;\n height = rect.height - containerPadding.height - containerBorder.height;\n maxWidth = parseMaxStyle(containerStyle.maxWidth, container, 'clientWidth');\n maxHeight = parseMaxStyle(containerStyle.maxHeight, container, 'clientHeight');\n }\n }\n return {\n width,\n height,\n maxWidth: maxWidth || INFINITY,\n maxHeight: maxHeight || INFINITY\n };\n}\nconst round1 = (v)=>Math.round(v * 10) / 10;\n// eslint-disable-next-line complexity\nfunction getMaximumSize(canvas, bbWidth, bbHeight, aspectRatio) {\n const style = getComputedStyle(canvas);\n const margins = getPositionedStyle(style, 'margin');\n const maxWidth = parseMaxStyle(style.maxWidth, canvas, 'clientWidth') || INFINITY;\n const maxHeight = parseMaxStyle(style.maxHeight, canvas, 'clientHeight') || INFINITY;\n const containerSize = getContainerSize(canvas, bbWidth, bbHeight);\n let { width , height } = containerSize;\n if (style.boxSizing === 'content-box') {\n const borders = getPositionedStyle(style, 'border', 'width');\n const paddings = getPositionedStyle(style, 'padding');\n width -= paddings.width + borders.width;\n height -= paddings.height + borders.height;\n }\n width = Math.max(0, width - margins.width);\n height = Math.max(0, aspectRatio ? width / aspectRatio : height - margins.height);\n width = round1(Math.min(width, maxWidth, containerSize.maxWidth));\n height = round1(Math.min(height, maxHeight, containerSize.maxHeight));\n if (width && !height) {\n // https://github.com/chartjs/Chart.js/issues/4659\n // If the canvas has width, but no height, default to aspectRatio of 2 (canvas default)\n height = round1(width / 2);\n }\n const maintainHeight = bbWidth !== undefined || bbHeight !== undefined;\n if (maintainHeight && aspectRatio && containerSize.height && height > containerSize.height) {\n height = containerSize.height;\n width = round1(Math.floor(height * aspectRatio));\n }\n return {\n width,\n height\n };\n}\n/**\n * @param chart\n * @param forceRatio\n * @param forceStyle\n * @returns True if the canvas context size or transformation has changed.\n */ function retinaScale(chart, forceRatio, forceStyle) {\n const pixelRatio = forceRatio || 1;\n const deviceHeight = Math.floor(chart.height * pixelRatio);\n const deviceWidth = Math.floor(chart.width * pixelRatio);\n chart.height = Math.floor(chart.height);\n chart.width = Math.floor(chart.width);\n const canvas = chart.canvas;\n // If no style has been set on the canvas, the render size is used as display size,\n // making the chart visually bigger, so let's enforce it to the \"correct\" values.\n // See https://github.com/chartjs/Chart.js/issues/3575\n if (canvas.style && (forceStyle || !canvas.style.height && !canvas.style.width)) {\n canvas.style.height = `${chart.height}px`;\n canvas.style.width = `${chart.width}px`;\n }\n if (chart.currentDevicePixelRatio !== pixelRatio || canvas.height !== deviceHeight || canvas.width !== deviceWidth) {\n chart.currentDevicePixelRatio = pixelRatio;\n canvas.height = deviceHeight;\n canvas.width = deviceWidth;\n chart.ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);\n return true;\n }\n return false;\n}\n/**\n * Detects support for options object argument in addEventListener.\n * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support\n * @private\n */ const supportsEventListenerOptions = function() {\n let passiveSupported = false;\n try {\n const options = {\n get passive () {\n passiveSupported = true;\n return false;\n }\n };\n if (_isDomSupported()) {\n window.addEventListener('test', null, options);\n window.removeEventListener('test', null, options);\n }\n } catch (e) {\n // continue regardless of error\n }\n return passiveSupported;\n}();\n/**\n * The \"used\" size is the final value of a dimension property after all calculations have\n * been performed. This method uses the computed style of `element` but returns undefined\n * if the computed style is not expressed in pixels. That can happen in some cases where\n * `element` has a size relative to its parent and this last one is not yet displayed,\n * for example because of `display: none` on a parent node.\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/used_value\n * @returns Size in pixels or undefined if unknown.\n */ function readUsedSize(element, property) {\n const value = getStyle(element, property);\n const matches = value && value.match(/^(\\d+)(\\.\\d+)?px$/);\n return matches ? +matches[1] : undefined;\n}\n\n/**\n * @private\n */ function _pointInLine(p1, p2, t, mode) {\n return {\n x: p1.x + t * (p2.x - p1.x),\n y: p1.y + t * (p2.y - p1.y)\n };\n}\n/**\n * @private\n */ function _steppedInterpolation(p1, p2, t, mode) {\n return {\n x: p1.x + t * (p2.x - p1.x),\n y: mode === 'middle' ? t < 0.5 ? p1.y : p2.y : mode === 'after' ? t < 1 ? p1.y : p2.y : t > 0 ? p2.y : p1.y\n };\n}\n/**\n * @private\n */ function _bezierInterpolation(p1, p2, t, mode) {\n const cp1 = {\n x: p1.cp2x,\n y: p1.cp2y\n };\n const cp2 = {\n x: p2.cp1x,\n y: p2.cp1y\n };\n const a = _pointInLine(p1, cp1, t);\n const b = _pointInLine(cp1, cp2, t);\n const c = _pointInLine(cp2, p2, t);\n const d = _pointInLine(a, b, t);\n const e = _pointInLine(b, c, t);\n return _pointInLine(d, e, t);\n}\n\nconst getRightToLeftAdapter = function(rectX, width) {\n return {\n x (x) {\n return rectX + rectX + width - x;\n },\n setWidth (w) {\n width = w;\n },\n textAlign (align) {\n if (align === 'center') {\n return align;\n }\n return align === 'right' ? 'left' : 'right';\n },\n xPlus (x, value) {\n return x - value;\n },\n leftForLtr (x, itemWidth) {\n return x - itemWidth;\n }\n };\n};\nconst getLeftToRightAdapter = function() {\n return {\n x (x) {\n return x;\n },\n setWidth (w) {},\n textAlign (align) {\n return align;\n },\n xPlus (x, value) {\n return x + value;\n },\n leftForLtr (x, _itemWidth) {\n return x;\n }\n };\n};\nfunction getRtlAdapter(rtl, rectX, width) {\n return rtl ? getRightToLeftAdapter(rectX, width) : getLeftToRightAdapter();\n}\nfunction overrideTextDirection(ctx, direction) {\n let style, original;\n if (direction === 'ltr' || direction === 'rtl') {\n style = ctx.canvas.style;\n original = [\n style.getPropertyValue('direction'),\n style.getPropertyPriority('direction')\n ];\n style.setProperty('direction', direction, 'important');\n ctx.prevTextDirection = original;\n }\n}\nfunction restoreTextDirection(ctx, original) {\n if (original !== undefined) {\n delete ctx.prevTextDirection;\n ctx.canvas.style.setProperty('direction', original[0], original[1]);\n }\n}\n\nfunction propertyFn(property) {\n if (property === 'angle') {\n return {\n between: _angleBetween,\n compare: _angleDiff,\n normalize: _normalizeAngle\n };\n }\n return {\n between: _isBetween,\n compare: (a, b)=>a - b,\n normalize: (x)=>x\n };\n}\nfunction normalizeSegment({ start , end , count , loop , style }) {\n return {\n start: start % count,\n end: end % count,\n loop: loop && (end - start + 1) % count === 0,\n style\n };\n}\nfunction getSegment(segment, points, bounds) {\n const { property , start: startBound , end: endBound } = bounds;\n const { between , normalize } = propertyFn(property);\n const count = points.length;\n let { start , end , loop } = segment;\n let i, ilen;\n if (loop) {\n start += count;\n end += count;\n for(i = 0, ilen = count; i < ilen; ++i){\n if (!between(normalize(points[start % count][property]), startBound, endBound)) {\n break;\n }\n start--;\n end--;\n }\n start %= count;\n end %= count;\n }\n if (end < start) {\n end += count;\n }\n return {\n start,\n end,\n loop,\n style: segment.style\n };\n}\n function _boundSegment(segment, points, bounds) {\n if (!bounds) {\n return [\n segment\n ];\n }\n const { property , start: startBound , end: endBound } = bounds;\n const count = points.length;\n const { compare , between , normalize } = propertyFn(property);\n const { start , end , loop , style } = getSegment(segment, points, bounds);\n const result = [];\n let inside = false;\n let subStart = null;\n let value, point, prevValue;\n const startIsBefore = ()=>between(startBound, prevValue, value) && compare(startBound, prevValue) !== 0;\n const endIsBefore = ()=>compare(endBound, value) === 0 || between(endBound, prevValue, value);\n const shouldStart = ()=>inside || startIsBefore();\n const shouldStop = ()=>!inside || endIsBefore();\n for(let i = start, prev = start; i <= end; ++i){\n point = points[i % count];\n if (point.skip) {\n continue;\n }\n value = normalize(point[property]);\n if (value === prevValue) {\n continue;\n }\n inside = between(value, startBound, endBound);\n if (subStart === null && shouldStart()) {\n subStart = compare(value, startBound) === 0 ? i : prev;\n }\n if (subStart !== null && shouldStop()) {\n result.push(normalizeSegment({\n start: subStart,\n end: i,\n loop,\n count,\n style\n }));\n subStart = null;\n }\n prev = i;\n prevValue = value;\n }\n if (subStart !== null) {\n result.push(normalizeSegment({\n start: subStart,\n end,\n loop,\n count,\n style\n }));\n }\n return result;\n}\n function _boundSegments(line, bounds) {\n const result = [];\n const segments = line.segments;\n for(let i = 0; i < segments.length; i++){\n const sub = _boundSegment(segments[i], line.points, bounds);\n if (sub.length) {\n result.push(...sub);\n }\n }\n return result;\n}\n function findStartAndEnd(points, count, loop, spanGaps) {\n let start = 0;\n let end = count - 1;\n if (loop && !spanGaps) {\n while(start < count && !points[start].skip){\n start++;\n }\n }\n while(start < count && points[start].skip){\n start++;\n }\n start %= count;\n if (loop) {\n end += start;\n }\n while(end > start && points[end % count].skip){\n end--;\n }\n end %= count;\n return {\n start,\n end\n };\n}\n function solidSegments(points, start, max, loop) {\n const count = points.length;\n const result = [];\n let last = start;\n let prev = points[start];\n let end;\n for(end = start + 1; end <= max; ++end){\n const cur = points[end % count];\n if (cur.skip || cur.stop) {\n if (!prev.skip) {\n loop = false;\n result.push({\n start: start % count,\n end: (end - 1) % count,\n loop\n });\n start = last = cur.stop ? end : null;\n }\n } else {\n last = end;\n if (prev.skip) {\n start = end;\n }\n }\n prev = cur;\n }\n if (last !== null) {\n result.push({\n start: start % count,\n end: last % count,\n loop\n });\n }\n return result;\n}\n function _computeSegments(line, segmentOptions) {\n const points = line.points;\n const spanGaps = line.options.spanGaps;\n const count = points.length;\n if (!count) {\n return [];\n }\n const loop = !!line._loop;\n const { start , end } = findStartAndEnd(points, count, loop, spanGaps);\n if (spanGaps === true) {\n return splitByStyles(line, [\n {\n start,\n end,\n loop\n }\n ], points, segmentOptions);\n }\n const max = end < start ? end + count : end;\n const completeLoop = !!line._fullLoop && start === 0 && end === count - 1;\n return splitByStyles(line, solidSegments(points, start, max, completeLoop), points, segmentOptions);\n}\n function splitByStyles(line, segments, points, segmentOptions) {\n if (!segmentOptions || !segmentOptions.setContext || !points) {\n return segments;\n }\n return doSplitByStyles(line, segments, points, segmentOptions);\n}\n function doSplitByStyles(line, segments, points, segmentOptions) {\n const chartContext = line._chart.getContext();\n const baseStyle = readStyle(line.options);\n const { _datasetIndex: datasetIndex , options: { spanGaps } } = line;\n const count = points.length;\n const result = [];\n let prevStyle = baseStyle;\n let start = segments[0].start;\n let i = start;\n function addStyle(s, e, l, st) {\n const dir = spanGaps ? -1 : 1;\n if (s === e) {\n return;\n }\n s += count;\n while(points[s % count].skip){\n s -= dir;\n }\n while(points[e % count].skip){\n e += dir;\n }\n if (s % count !== e % count) {\n result.push({\n start: s % count,\n end: e % count,\n loop: l,\n style: st\n });\n prevStyle = st;\n start = e % count;\n }\n }\n for (const segment of segments){\n start = spanGaps ? start : segment.start;\n let prev = points[start % count];\n let style;\n for(i = start + 1; i <= segment.end; i++){\n const pt = points[i % count];\n style = readStyle(segmentOptions.setContext(createContext(chartContext, {\n type: 'segment',\n p0: prev,\n p1: pt,\n p0DataIndex: (i - 1) % count,\n p1DataIndex: i % count,\n datasetIndex\n })));\n if (styleChanged(style, prevStyle)) {\n addStyle(start, i - 1, segment.loop, prevStyle);\n }\n prev = pt;\n prevStyle = style;\n }\n if (start < i - 1) {\n addStyle(start, i - 1, segment.loop, prevStyle);\n }\n }\n return result;\n}\nfunction readStyle(options) {\n return {\n backgroundColor: options.backgroundColor,\n borderCapStyle: options.borderCapStyle,\n borderDash: options.borderDash,\n borderDashOffset: options.borderDashOffset,\n borderJoinStyle: options.borderJoinStyle,\n borderWidth: options.borderWidth,\n borderColor: options.borderColor\n };\n}\nfunction styleChanged(style, prevStyle) {\n if (!prevStyle) {\n return false;\n }\n const cache = [];\n const replacer = function(key, value) {\n if (!isPatternOrGradient(value)) {\n return value;\n }\n if (!cache.includes(value)) {\n cache.push(value);\n }\n return cache.indexOf(value);\n };\n return JSON.stringify(style, replacer) !== JSON.stringify(prevStyle, replacer);\n}\n\n\n//# sourceMappingURL=helpers.segment.js.map\n\n;// ./node_modules/chart.js/dist/chart.js\n/*!\n * Chart.js v4.4.4\n * https://www.chartjs.org\n * (c) 2024 Chart.js Contributors\n * Released under the MIT License\n */\n\n\n\nclass Animator {\n constructor(){\n this._request = null;\n this._charts = new Map();\n this._running = false;\n this._lastDate = undefined;\n }\n _notify(chart, anims, date, type) {\n const callbacks = anims.listeners[type];\n const numSteps = anims.duration;\n callbacks.forEach((fn)=>fn({\n chart,\n initial: anims.initial,\n numSteps,\n currentStep: Math.min(date - anims.start, numSteps)\n }));\n }\n _refresh() {\n if (this._request) {\n return;\n }\n this._running = true;\n this._request = requestAnimFrame.call(window, ()=>{\n this._update();\n this._request = null;\n if (this._running) {\n this._refresh();\n }\n });\n }\n _update(date = Date.now()) {\n let remaining = 0;\n this._charts.forEach((anims, chart)=>{\n if (!anims.running || !anims.items.length) {\n return;\n }\n const items = anims.items;\n let i = items.length - 1;\n let draw = false;\n let item;\n for(; i >= 0; --i){\n item = items[i];\n if (item._active) {\n if (item._total > anims.duration) {\n anims.duration = item._total;\n }\n item.tick(date);\n draw = true;\n } else {\n items[i] = items[items.length - 1];\n items.pop();\n }\n }\n if (draw) {\n chart.draw();\n this._notify(chart, anims, date, 'progress');\n }\n if (!items.length) {\n anims.running = false;\n this._notify(chart, anims, date, 'complete');\n anims.initial = false;\n }\n remaining += items.length;\n });\n this._lastDate = date;\n if (remaining === 0) {\n this._running = false;\n }\n }\n _getAnims(chart) {\n const charts = this._charts;\n let anims = charts.get(chart);\n if (!anims) {\n anims = {\n running: false,\n initial: true,\n items: [],\n listeners: {\n complete: [],\n progress: []\n }\n };\n charts.set(chart, anims);\n }\n return anims;\n }\n listen(chart, event, cb) {\n this._getAnims(chart).listeners[event].push(cb);\n }\n add(chart, items) {\n if (!items || !items.length) {\n return;\n }\n this._getAnims(chart).items.push(...items);\n }\n has(chart) {\n return this._getAnims(chart).items.length > 0;\n }\n start(chart) {\n const anims = this._charts.get(chart);\n if (!anims) {\n return;\n }\n anims.running = true;\n anims.start = Date.now();\n anims.duration = anims.items.reduce((acc, cur)=>Math.max(acc, cur._duration), 0);\n this._refresh();\n }\n running(chart) {\n if (!this._running) {\n return false;\n }\n const anims = this._charts.get(chart);\n if (!anims || !anims.running || !anims.items.length) {\n return false;\n }\n return true;\n }\n stop(chart) {\n const anims = this._charts.get(chart);\n if (!anims || !anims.items.length) {\n return;\n }\n const items = anims.items;\n let i = items.length - 1;\n for(; i >= 0; --i){\n items[i].cancel();\n }\n anims.items = [];\n this._notify(chart, anims, Date.now(), 'complete');\n }\n remove(chart) {\n return this._charts.delete(chart);\n }\n}\nvar animator = /* #__PURE__ */ new Animator();\n\nconst transparent = 'transparent';\nconst interpolators = {\n boolean (from, to, factor) {\n return factor > 0.5 ? to : from;\n },\n color (from, to, factor) {\n const c0 = color(from || transparent);\n const c1 = c0.valid && color(to || transparent);\n return c1 && c1.valid ? c1.mix(c0, factor).hexString() : to;\n },\n number (from, to, factor) {\n return from + (to - from) * factor;\n }\n};\nclass Animation {\n constructor(cfg, target, prop, to){\n const currentValue = target[prop];\n to = resolve([\n cfg.to,\n to,\n currentValue,\n cfg.from\n ]);\n const from = resolve([\n cfg.from,\n currentValue,\n to\n ]);\n this._active = true;\n this._fn = cfg.fn || interpolators[cfg.type || typeof from];\n this._easing = effects[cfg.easing] || effects.linear;\n this._start = Math.floor(Date.now() + (cfg.delay || 0));\n this._duration = this._total = Math.floor(cfg.duration);\n this._loop = !!cfg.loop;\n this._target = target;\n this._prop = prop;\n this._from = from;\n this._to = to;\n this._promises = undefined;\n }\n active() {\n return this._active;\n }\n update(cfg, to, date) {\n if (this._active) {\n this._notify(false);\n const currentValue = this._target[this._prop];\n const elapsed = date - this._start;\n const remain = this._duration - elapsed;\n this._start = date;\n this._duration = Math.floor(Math.max(remain, cfg.duration));\n this._total += elapsed;\n this._loop = !!cfg.loop;\n this._to = resolve([\n cfg.to,\n to,\n currentValue,\n cfg.from\n ]);\n this._from = resolve([\n cfg.from,\n currentValue,\n to\n ]);\n }\n }\n cancel() {\n if (this._active) {\n this.tick(Date.now());\n this._active = false;\n this._notify(false);\n }\n }\n tick(date) {\n const elapsed = date - this._start;\n const duration = this._duration;\n const prop = this._prop;\n const from = this._from;\n const loop = this._loop;\n const to = this._to;\n let factor;\n this._active = from !== to && (loop || elapsed < duration);\n if (!this._active) {\n this._target[prop] = to;\n this._notify(true);\n return;\n }\n if (elapsed < 0) {\n this._target[prop] = from;\n return;\n }\n factor = elapsed / duration % 2;\n factor = loop && factor > 1 ? 2 - factor : factor;\n factor = this._easing(Math.min(1, Math.max(0, factor)));\n this._target[prop] = this._fn(from, to, factor);\n }\n wait() {\n const promises = this._promises || (this._promises = []);\n return new Promise((res, rej)=>{\n promises.push({\n res,\n rej\n });\n });\n }\n _notify(resolved) {\n const method = resolved ? 'res' : 'rej';\n const promises = this._promises || [];\n for(let i = 0; i < promises.length; i++){\n promises[i][method]();\n }\n }\n}\n\nclass Animations {\n constructor(chart, config){\n this._chart = chart;\n this._properties = new Map();\n this.configure(config);\n }\n configure(config) {\n if (!isObject(config)) {\n return;\n }\n const animationOptions = Object.keys(defaults.animation);\n const animatedProps = this._properties;\n Object.getOwnPropertyNames(config).forEach((key)=>{\n const cfg = config[key];\n if (!isObject(cfg)) {\n return;\n }\n const resolved = {};\n for (const option of animationOptions){\n resolved[option] = cfg[option];\n }\n (isArray(cfg.properties) && cfg.properties || [\n key\n ]).forEach((prop)=>{\n if (prop === key || !animatedProps.has(prop)) {\n animatedProps.set(prop, resolved);\n }\n });\n });\n }\n _animateOptions(target, values) {\n const newOptions = values.options;\n const options = resolveTargetOptions(target, newOptions);\n if (!options) {\n return [];\n }\n const animations = this._createAnimations(options, newOptions);\n if (newOptions.$shared) {\n awaitAll(target.options.$animations, newOptions).then(()=>{\n target.options = newOptions;\n }, ()=>{\n });\n }\n return animations;\n }\n _createAnimations(target, values) {\n const animatedProps = this._properties;\n const animations = [];\n const running = target.$animations || (target.$animations = {});\n const props = Object.keys(values);\n const date = Date.now();\n let i;\n for(i = props.length - 1; i >= 0; --i){\n const prop = props[i];\n if (prop.charAt(0) === '$') {\n continue;\n }\n if (prop === 'options') {\n animations.push(...this._animateOptions(target, values));\n continue;\n }\n const value = values[prop];\n let animation = running[prop];\n const cfg = animatedProps.get(prop);\n if (animation) {\n if (cfg && animation.active()) {\n animation.update(cfg, value, date);\n continue;\n } else {\n animation.cancel();\n }\n }\n if (!cfg || !cfg.duration) {\n target[prop] = value;\n continue;\n }\n running[prop] = animation = new Animation(cfg, target, prop, value);\n animations.push(animation);\n }\n return animations;\n }\n update(target, values) {\n if (this._properties.size === 0) {\n Object.assign(target, values);\n return;\n }\n const animations = this._createAnimations(target, values);\n if (animations.length) {\n animator.add(this._chart, animations);\n return true;\n }\n }\n}\nfunction awaitAll(animations, properties) {\n const running = [];\n const keys = Object.keys(properties);\n for(let i = 0; i < keys.length; i++){\n const anim = animations[keys[i]];\n if (anim && anim.active()) {\n running.push(anim.wait());\n }\n }\n return Promise.all(running);\n}\nfunction resolveTargetOptions(target, newOptions) {\n if (!newOptions) {\n return;\n }\n let options = target.options;\n if (!options) {\n target.options = newOptions;\n return;\n }\n if (options.$shared) {\n target.options = options = Object.assign({}, options, {\n $shared: false,\n $animations: {}\n });\n }\n return options;\n}\n\nfunction scaleClip(scale, allowedOverflow) {\n const opts = scale && scale.options || {};\n const reverse = opts.reverse;\n const min = opts.min === undefined ? allowedOverflow : 0;\n const max = opts.max === undefined ? allowedOverflow : 0;\n return {\n start: reverse ? max : min,\n end: reverse ? min : max\n };\n}\nfunction defaultClip(xScale, yScale, allowedOverflow) {\n if (allowedOverflow === false) {\n return false;\n }\n const x = scaleClip(xScale, allowedOverflow);\n const y = scaleClip(yScale, allowedOverflow);\n return {\n top: y.end,\n right: x.end,\n bottom: y.start,\n left: x.start\n };\n}\nfunction toClip(value) {\n let t, r, b, l;\n if (isObject(value)) {\n t = value.top;\n r = value.right;\n b = value.bottom;\n l = value.left;\n } else {\n t = r = b = l = value;\n }\n return {\n top: t,\n right: r,\n bottom: b,\n left: l,\n disabled: value === false\n };\n}\nfunction getSortedDatasetIndices(chart, filterVisible) {\n const keys = [];\n const metasets = chart._getSortedDatasetMetas(filterVisible);\n let i, ilen;\n for(i = 0, ilen = metasets.length; i < ilen; ++i){\n keys.push(metasets[i].index);\n }\n return keys;\n}\nfunction applyStack(stack, value, dsIndex, options = {}) {\n const keys = stack.keys;\n const singleMode = options.mode === 'single';\n let i, ilen, datasetIndex, otherValue;\n if (value === null) {\n return;\n }\n for(i = 0, ilen = keys.length; i < ilen; ++i){\n datasetIndex = +keys[i];\n if (datasetIndex === dsIndex) {\n if (options.all) {\n continue;\n }\n break;\n }\n otherValue = stack.values[datasetIndex];\n if (isNumberFinite(otherValue) && (singleMode || value === 0 || sign(value) === sign(otherValue))) {\n value += otherValue;\n }\n }\n return value;\n}\nfunction convertObjectDataToArray(data, meta) {\n const { iScale , vScale } = meta;\n const iAxisKey = iScale.axis === 'x' ? 'x' : 'y';\n const vAxisKey = vScale.axis === 'x' ? 'x' : 'y';\n const keys = Object.keys(data);\n const adata = new Array(keys.length);\n let i, ilen, key;\n for(i = 0, ilen = keys.length; i < ilen; ++i){\n key = keys[i];\n adata[i] = {\n [iAxisKey]: key,\n [vAxisKey]: data[key]\n };\n }\n return adata;\n}\nfunction isStacked(scale, meta) {\n const stacked = scale && scale.options.stacked;\n return stacked || stacked === undefined && meta.stack !== undefined;\n}\nfunction getStackKey(indexScale, valueScale, meta) {\n return `${indexScale.id}.${valueScale.id}.${meta.stack || meta.type}`;\n}\nfunction getUserBounds(scale) {\n const { min , max , minDefined , maxDefined } = scale.getUserBounds();\n return {\n min: minDefined ? min : Number.NEGATIVE_INFINITY,\n max: maxDefined ? max : Number.POSITIVE_INFINITY\n };\n}\nfunction getOrCreateStack(stacks, stackKey, indexValue) {\n const subStack = stacks[stackKey] || (stacks[stackKey] = {});\n return subStack[indexValue] || (subStack[indexValue] = {});\n}\nfunction getLastIndexInStack(stack, vScale, positive, type) {\n for (const meta of vScale.getMatchingVisibleMetas(type).reverse()){\n const value = stack[meta.index];\n if (positive && value > 0 || !positive && value < 0) {\n return meta.index;\n }\n }\n return null;\n}\nfunction updateStacks(controller, parsed) {\n const { chart , _cachedMeta: meta } = controller;\n const stacks = chart._stacks || (chart._stacks = {});\n const { iScale , vScale , index: datasetIndex } = meta;\n const iAxis = iScale.axis;\n const vAxis = vScale.axis;\n const key = getStackKey(iScale, vScale, meta);\n const ilen = parsed.length;\n let stack;\n for(let i = 0; i < ilen; ++i){\n const item = parsed[i];\n const { [iAxis]: index , [vAxis]: value } = item;\n const itemStacks = item._stacks || (item._stacks = {});\n stack = itemStacks[vAxis] = getOrCreateStack(stacks, key, index);\n stack[datasetIndex] = value;\n stack._top = getLastIndexInStack(stack, vScale, true, meta.type);\n stack._bottom = getLastIndexInStack(stack, vScale, false, meta.type);\n const visualValues = stack._visualValues || (stack._visualValues = {});\n visualValues[datasetIndex] = value;\n }\n}\nfunction getFirstScaleId(chart, axis) {\n const scales = chart.scales;\n return Object.keys(scales).filter((key)=>scales[key].axis === axis).shift();\n}\nfunction createDatasetContext(parent, index) {\n return createContext(parent, {\n active: false,\n dataset: undefined,\n datasetIndex: index,\n index,\n mode: 'default',\n type: 'dataset'\n });\n}\nfunction createDataContext(parent, index, element) {\n return createContext(parent, {\n active: false,\n dataIndex: index,\n parsed: undefined,\n raw: undefined,\n element,\n index,\n mode: 'default',\n type: 'data'\n });\n}\nfunction clearStacks(meta, items) {\n const datasetIndex = meta.controller.index;\n const axis = meta.vScale && meta.vScale.axis;\n if (!axis) {\n return;\n }\n items = items || meta._parsed;\n for (const parsed of items){\n const stacks = parsed._stacks;\n if (!stacks || stacks[axis] === undefined || stacks[axis][datasetIndex] === undefined) {\n return;\n }\n delete stacks[axis][datasetIndex];\n if (stacks[axis]._visualValues !== undefined && stacks[axis]._visualValues[datasetIndex] !== undefined) {\n delete stacks[axis]._visualValues[datasetIndex];\n }\n }\n}\nconst isDirectUpdateMode = (mode)=>mode === 'reset' || mode === 'none';\nconst cloneIfNotShared = (cached, shared)=>shared ? cached : Object.assign({}, cached);\nconst createStack = (canStack, meta, chart)=>canStack && !meta.hidden && meta._stacked && {\n keys: getSortedDatasetIndices(chart, true),\n values: null\n };\nclass DatasetController {\n static defaults = {};\n static datasetElementType = null;\n static dataElementType = null;\n constructor(chart, datasetIndex){\n this.chart = chart;\n this._ctx = chart.ctx;\n this.index = datasetIndex;\n this._cachedDataOpts = {};\n this._cachedMeta = this.getMeta();\n this._type = this._cachedMeta.type;\n this.options = undefined;\n this._parsing = false;\n this._data = undefined;\n this._objectData = undefined;\n this._sharedOptions = undefined;\n this._drawStart = undefined;\n this._drawCount = undefined;\n this.enableOptionSharing = false;\n this.supportsDecimation = false;\n this.$context = undefined;\n this._syncList = [];\n this.datasetElementType = new.target.datasetElementType;\n this.dataElementType = new.target.dataElementType;\n this.initialize();\n }\n initialize() {\n const meta = this._cachedMeta;\n this.configure();\n this.linkScales();\n meta._stacked = isStacked(meta.vScale, meta);\n this.addElements();\n if (this.options.fill && !this.chart.isPluginEnabled('filler')) {\n console.warn(\"Tried to use the 'fill' option without the 'Filler' plugin enabled. Please import and register the 'Filler' plugin and make sure it is not disabled in the options\");\n }\n }\n updateIndex(datasetIndex) {\n if (this.index !== datasetIndex) {\n clearStacks(this._cachedMeta);\n }\n this.index = datasetIndex;\n }\n linkScales() {\n const chart = this.chart;\n const meta = this._cachedMeta;\n const dataset = this.getDataset();\n const chooseId = (axis, x, y, r)=>axis === 'x' ? x : axis === 'r' ? r : y;\n const xid = meta.xAxisID = valueOrDefault(dataset.xAxisID, getFirstScaleId(chart, 'x'));\n const yid = meta.yAxisID = valueOrDefault(dataset.yAxisID, getFirstScaleId(chart, 'y'));\n const rid = meta.rAxisID = valueOrDefault(dataset.rAxisID, getFirstScaleId(chart, 'r'));\n const indexAxis = meta.indexAxis;\n const iid = meta.iAxisID = chooseId(indexAxis, xid, yid, rid);\n const vid = meta.vAxisID = chooseId(indexAxis, yid, xid, rid);\n meta.xScale = this.getScaleForId(xid);\n meta.yScale = this.getScaleForId(yid);\n meta.rScale = this.getScaleForId(rid);\n meta.iScale = this.getScaleForId(iid);\n meta.vScale = this.getScaleForId(vid);\n }\n getDataset() {\n return this.chart.data.datasets[this.index];\n }\n getMeta() {\n return this.chart.getDatasetMeta(this.index);\n }\n getScaleForId(scaleID) {\n return this.chart.scales[scaleID];\n }\n _getOtherScale(scale) {\n const meta = this._cachedMeta;\n return scale === meta.iScale ? meta.vScale : meta.iScale;\n }\n reset() {\n this._update('reset');\n }\n _destroy() {\n const meta = this._cachedMeta;\n if (this._data) {\n unlistenArrayEvents(this._data, this);\n }\n if (meta._stacked) {\n clearStacks(meta);\n }\n }\n _dataCheck() {\n const dataset = this.getDataset();\n const data = dataset.data || (dataset.data = []);\n const _data = this._data;\n if (isObject(data)) {\n const meta = this._cachedMeta;\n this._data = convertObjectDataToArray(data, meta);\n } else if (_data !== data) {\n if (_data) {\n unlistenArrayEvents(_data, this);\n const meta = this._cachedMeta;\n clearStacks(meta);\n meta._parsed = [];\n }\n if (data && Object.isExtensible(data)) {\n listenArrayEvents(data, this);\n }\n this._syncList = [];\n this._data = data;\n }\n }\n addElements() {\n const meta = this._cachedMeta;\n this._dataCheck();\n if (this.datasetElementType) {\n meta.dataset = new this.datasetElementType();\n }\n }\n buildOrUpdateElements(resetNewElements) {\n const meta = this._cachedMeta;\n const dataset = this.getDataset();\n let stackChanged = false;\n this._dataCheck();\n const oldStacked = meta._stacked;\n meta._stacked = isStacked(meta.vScale, meta);\n if (meta.stack !== dataset.stack) {\n stackChanged = true;\n clearStacks(meta);\n meta.stack = dataset.stack;\n }\n this._resyncElements(resetNewElements);\n if (stackChanged || oldStacked !== meta._stacked) {\n updateStacks(this, meta._parsed);\n }\n }\n configure() {\n const config = this.chart.config;\n const scopeKeys = config.datasetScopeKeys(this._type);\n const scopes = config.getOptionScopes(this.getDataset(), scopeKeys, true);\n this.options = config.createResolver(scopes, this.getContext());\n this._parsing = this.options.parsing;\n this._cachedDataOpts = {};\n }\n parse(start, count) {\n const { _cachedMeta: meta , _data: data } = this;\n const { iScale , _stacked } = meta;\n const iAxis = iScale.axis;\n let sorted = start === 0 && count === data.length ? true : meta._sorted;\n let prev = start > 0 && meta._parsed[start - 1];\n let i, cur, parsed;\n if (this._parsing === false) {\n meta._parsed = data;\n meta._sorted = true;\n parsed = data;\n } else {\n if (isArray(data[start])) {\n parsed = this.parseArrayData(meta, data, start, count);\n } else if (isObject(data[start])) {\n parsed = this.parseObjectData(meta, data, start, count);\n } else {\n parsed = this.parsePrimitiveData(meta, data, start, count);\n }\n const isNotInOrderComparedToPrev = ()=>cur[iAxis] === null || prev && cur[iAxis] < prev[iAxis];\n for(i = 0; i < count; ++i){\n meta._parsed[i + start] = cur = parsed[i];\n if (sorted) {\n if (isNotInOrderComparedToPrev()) {\n sorted = false;\n }\n prev = cur;\n }\n }\n meta._sorted = sorted;\n }\n if (_stacked) {\n updateStacks(this, parsed);\n }\n }\n parsePrimitiveData(meta, data, start, count) {\n const { iScale , vScale } = meta;\n const iAxis = iScale.axis;\n const vAxis = vScale.axis;\n const labels = iScale.getLabels();\n const singleScale = iScale === vScale;\n const parsed = new Array(count);\n let i, ilen, index;\n for(i = 0, ilen = count; i < ilen; ++i){\n index = i + start;\n parsed[i] = {\n [iAxis]: singleScale || iScale.parse(labels[index], index),\n [vAxis]: vScale.parse(data[index], index)\n };\n }\n return parsed;\n }\n parseArrayData(meta, data, start, count) {\n const { xScale , yScale } = meta;\n const parsed = new Array(count);\n let i, ilen, index, item;\n for(i = 0, ilen = count; i < ilen; ++i){\n index = i + start;\n item = data[index];\n parsed[i] = {\n x: xScale.parse(item[0], index),\n y: yScale.parse(item[1], index)\n };\n }\n return parsed;\n }\n parseObjectData(meta, data, start, count) {\n const { xScale , yScale } = meta;\n const { xAxisKey ='x' , yAxisKey ='y' } = this._parsing;\n const parsed = new Array(count);\n let i, ilen, index, item;\n for(i = 0, ilen = count; i < ilen; ++i){\n index = i + start;\n item = data[index];\n parsed[i] = {\n x: xScale.parse(resolveObjectKey(item, xAxisKey), index),\n y: yScale.parse(resolveObjectKey(item, yAxisKey), index)\n };\n }\n return parsed;\n }\n getParsed(index) {\n return this._cachedMeta._parsed[index];\n }\n getDataElement(index) {\n return this._cachedMeta.data[index];\n }\n applyStack(scale, parsed, mode) {\n const chart = this.chart;\n const meta = this._cachedMeta;\n const value = parsed[scale.axis];\n const stack = {\n keys: getSortedDatasetIndices(chart, true),\n values: parsed._stacks[scale.axis]._visualValues\n };\n return applyStack(stack, value, meta.index, {\n mode\n });\n }\n updateRangeFromParsed(range, scale, parsed, stack) {\n const parsedValue = parsed[scale.axis];\n let value = parsedValue === null ? NaN : parsedValue;\n const values = stack && parsed._stacks[scale.axis];\n if (stack && values) {\n stack.values = values;\n value = applyStack(stack, parsedValue, this._cachedMeta.index);\n }\n range.min = Math.min(range.min, value);\n range.max = Math.max(range.max, value);\n }\n getMinMax(scale, canStack) {\n const meta = this._cachedMeta;\n const _parsed = meta._parsed;\n const sorted = meta._sorted && scale === meta.iScale;\n const ilen = _parsed.length;\n const otherScale = this._getOtherScale(scale);\n const stack = createStack(canStack, meta, this.chart);\n const range = {\n min: Number.POSITIVE_INFINITY,\n max: Number.NEGATIVE_INFINITY\n };\n const { min: otherMin , max: otherMax } = getUserBounds(otherScale);\n let i, parsed;\n function _skip() {\n parsed = _parsed[i];\n const otherValue = parsed[otherScale.axis];\n return !isNumberFinite(parsed[scale.axis]) || otherMin > otherValue || otherMax < otherValue;\n }\n for(i = 0; i < ilen; ++i){\n if (_skip()) {\n continue;\n }\n this.updateRangeFromParsed(range, scale, parsed, stack);\n if (sorted) {\n break;\n }\n }\n if (sorted) {\n for(i = ilen - 1; i >= 0; --i){\n if (_skip()) {\n continue;\n }\n this.updateRangeFromParsed(range, scale, parsed, stack);\n break;\n }\n }\n return range;\n }\n getAllParsedValues(scale) {\n const parsed = this._cachedMeta._parsed;\n const values = [];\n let i, ilen, value;\n for(i = 0, ilen = parsed.length; i < ilen; ++i){\n value = parsed[i][scale.axis];\n if (isNumberFinite(value)) {\n values.push(value);\n }\n }\n return values;\n }\n getMaxOverflow() {\n return false;\n }\n getLabelAndValue(index) {\n const meta = this._cachedMeta;\n const iScale = meta.iScale;\n const vScale = meta.vScale;\n const parsed = this.getParsed(index);\n return {\n label: iScale ? '' + iScale.getLabelForValue(parsed[iScale.axis]) : '',\n value: vScale ? '' + vScale.getLabelForValue(parsed[vScale.axis]) : ''\n };\n }\n _update(mode) {\n const meta = this._cachedMeta;\n this.update(mode || 'default');\n meta._clip = toClip(valueOrDefault(this.options.clip, defaultClip(meta.xScale, meta.yScale, this.getMaxOverflow())));\n }\n update(mode) {}\n draw() {\n const ctx = this._ctx;\n const chart = this.chart;\n const meta = this._cachedMeta;\n const elements = meta.data || [];\n const area = chart.chartArea;\n const active = [];\n const start = this._drawStart || 0;\n const count = this._drawCount || elements.length - start;\n const drawActiveElementsOnTop = this.options.drawActiveElementsOnTop;\n let i;\n if (meta.dataset) {\n meta.dataset.draw(ctx, area, start, count);\n }\n for(i = start; i < start + count; ++i){\n const element = elements[i];\n if (element.hidden) {\n continue;\n }\n if (element.active && drawActiveElementsOnTop) {\n active.push(element);\n } else {\n element.draw(ctx, area);\n }\n }\n for(i = 0; i < active.length; ++i){\n active[i].draw(ctx, area);\n }\n }\n getStyle(index, active) {\n const mode = active ? 'active' : 'default';\n return index === undefined && this._cachedMeta.dataset ? this.resolveDatasetElementOptions(mode) : this.resolveDataElementOptions(index || 0, mode);\n }\n getContext(index, active, mode) {\n const dataset = this.getDataset();\n let context;\n if (index >= 0 && index < this._cachedMeta.data.length) {\n const element = this._cachedMeta.data[index];\n context = element.$context || (element.$context = createDataContext(this.getContext(), index, element));\n context.parsed = this.getParsed(index);\n context.raw = dataset.data[index];\n context.index = context.dataIndex = index;\n } else {\n context = this.$context || (this.$context = createDatasetContext(this.chart.getContext(), this.index));\n context.dataset = dataset;\n context.index = context.datasetIndex = this.index;\n }\n context.active = !!active;\n context.mode = mode;\n return context;\n }\n resolveDatasetElementOptions(mode) {\n return this._resolveElementOptions(this.datasetElementType.id, mode);\n }\n resolveDataElementOptions(index, mode) {\n return this._resolveElementOptions(this.dataElementType.id, mode, index);\n }\n _resolveElementOptions(elementType, mode = 'default', index) {\n const active = mode === 'active';\n const cache = this._cachedDataOpts;\n const cacheKey = elementType + '-' + mode;\n const cached = cache[cacheKey];\n const sharing = this.enableOptionSharing && defined(index);\n if (cached) {\n return cloneIfNotShared(cached, sharing);\n }\n const config = this.chart.config;\n const scopeKeys = config.datasetElementScopeKeys(this._type, elementType);\n const prefixes = active ? [\n `${elementType}Hover`,\n 'hover',\n elementType,\n ''\n ] : [\n elementType,\n ''\n ];\n const scopes = config.getOptionScopes(this.getDataset(), scopeKeys);\n const names = Object.keys(defaults.elements[elementType]);\n const context = ()=>this.getContext(index, active, mode);\n const values = config.resolveNamedOptions(scopes, names, context, prefixes);\n if (values.$shared) {\n values.$shared = sharing;\n cache[cacheKey] = Object.freeze(cloneIfNotShared(values, sharing));\n }\n return values;\n }\n _resolveAnimations(index, transition, active) {\n const chart = this.chart;\n const cache = this._cachedDataOpts;\n const cacheKey = `animation-${transition}`;\n const cached = cache[cacheKey];\n if (cached) {\n return cached;\n }\n let options;\n if (chart.options.animation !== false) {\n const config = this.chart.config;\n const scopeKeys = config.datasetAnimationScopeKeys(this._type, transition);\n const scopes = config.getOptionScopes(this.getDataset(), scopeKeys);\n options = config.createResolver(scopes, this.getContext(index, active, transition));\n }\n const animations = new Animations(chart, options && options.animations);\n if (options && options._cacheable) {\n cache[cacheKey] = Object.freeze(animations);\n }\n return animations;\n }\n getSharedOptions(options) {\n if (!options.$shared) {\n return;\n }\n return this._sharedOptions || (this._sharedOptions = Object.assign({}, options));\n }\n includeOptions(mode, sharedOptions) {\n return !sharedOptions || isDirectUpdateMode(mode) || this.chart._animationsDisabled;\n }\n _getSharedOptions(start, mode) {\n const firstOpts = this.resolveDataElementOptions(start, mode);\n const previouslySharedOptions = this._sharedOptions;\n const sharedOptions = this.getSharedOptions(firstOpts);\n const includeOptions = this.includeOptions(mode, sharedOptions) || sharedOptions !== previouslySharedOptions;\n this.updateSharedOptions(sharedOptions, mode, firstOpts);\n return {\n sharedOptions,\n includeOptions\n };\n }\n updateElement(element, index, properties, mode) {\n if (isDirectUpdateMode(mode)) {\n Object.assign(element, properties);\n } else {\n this._resolveAnimations(index, mode).update(element, properties);\n }\n }\n updateSharedOptions(sharedOptions, mode, newOptions) {\n if (sharedOptions && !isDirectUpdateMode(mode)) {\n this._resolveAnimations(undefined, mode).update(sharedOptions, newOptions);\n }\n }\n _setStyle(element, index, mode, active) {\n element.active = active;\n const options = this.getStyle(index, active);\n this._resolveAnimations(index, mode, active).update(element, {\n options: !active && this.getSharedOptions(options) || options\n });\n }\n removeHoverStyle(element, datasetIndex, index) {\n this._setStyle(element, index, 'active', false);\n }\n setHoverStyle(element, datasetIndex, index) {\n this._setStyle(element, index, 'active', true);\n }\n _removeDatasetHoverStyle() {\n const element = this._cachedMeta.dataset;\n if (element) {\n this._setStyle(element, undefined, 'active', false);\n }\n }\n _setDatasetHoverStyle() {\n const element = this._cachedMeta.dataset;\n if (element) {\n this._setStyle(element, undefined, 'active', true);\n }\n }\n _resyncElements(resetNewElements) {\n const data = this._data;\n const elements = this._cachedMeta.data;\n for (const [method, arg1, arg2] of this._syncList){\n this[method](arg1, arg2);\n }\n this._syncList = [];\n const numMeta = elements.length;\n const numData = data.length;\n const count = Math.min(numData, numMeta);\n if (count) {\n this.parse(0, count);\n }\n if (numData > numMeta) {\n this._insertElements(numMeta, numData - numMeta, resetNewElements);\n } else if (numData < numMeta) {\n this._removeElements(numData, numMeta - numData);\n }\n }\n _insertElements(start, count, resetNewElements = true) {\n const meta = this._cachedMeta;\n const data = meta.data;\n const end = start + count;\n let i;\n const move = (arr)=>{\n arr.length += count;\n for(i = arr.length - 1; i >= end; i--){\n arr[i] = arr[i - count];\n }\n };\n move(data);\n for(i = start; i < end; ++i){\n data[i] = new this.dataElementType();\n }\n if (this._parsing) {\n move(meta._parsed);\n }\n this.parse(start, count);\n if (resetNewElements) {\n this.updateElements(data, start, count, 'reset');\n }\n }\n updateElements(element, start, count, mode) {}\n _removeElements(start, count) {\n const meta = this._cachedMeta;\n if (this._parsing) {\n const removed = meta._parsed.splice(start, count);\n if (meta._stacked) {\n clearStacks(meta, removed);\n }\n }\n meta.data.splice(start, count);\n }\n _sync(args) {\n if (this._parsing) {\n this._syncList.push(args);\n } else {\n const [method, arg1, arg2] = args;\n this[method](arg1, arg2);\n }\n this.chart._dataChanges.push([\n this.index,\n ...args\n ]);\n }\n _onDataPush() {\n const count = arguments.length;\n this._sync([\n '_insertElements',\n this.getDataset().data.length - count,\n count\n ]);\n }\n _onDataPop() {\n this._sync([\n '_removeElements',\n this._cachedMeta.data.length - 1,\n 1\n ]);\n }\n _onDataShift() {\n this._sync([\n '_removeElements',\n 0,\n 1\n ]);\n }\n _onDataSplice(start, count) {\n if (count) {\n this._sync([\n '_removeElements',\n start,\n count\n ]);\n }\n const newCount = arguments.length - 2;\n if (newCount) {\n this._sync([\n '_insertElements',\n start,\n newCount\n ]);\n }\n }\n _onDataUnshift() {\n this._sync([\n '_insertElements',\n 0,\n arguments.length\n ]);\n }\n}\n\nfunction getAllScaleValues(scale, type) {\n if (!scale._cache.$bar) {\n const visibleMetas = scale.getMatchingVisibleMetas(type);\n let values = [];\n for(let i = 0, ilen = visibleMetas.length; i < ilen; i++){\n values = values.concat(visibleMetas[i].controller.getAllParsedValues(scale));\n }\n scale._cache.$bar = _arrayUnique(values.sort((a, b)=>a - b));\n }\n return scale._cache.$bar;\n}\n function computeMinSampleSize(meta) {\n const scale = meta.iScale;\n const values = getAllScaleValues(scale, meta.type);\n let min = scale._length;\n let i, ilen, curr, prev;\n const updateMinAndPrev = ()=>{\n if (curr === 32767 || curr === -32768) {\n return;\n }\n if (defined(prev)) {\n min = Math.min(min, Math.abs(curr - prev) || min);\n }\n prev = curr;\n };\n for(i = 0, ilen = values.length; i < ilen; ++i){\n curr = scale.getPixelForValue(values[i]);\n updateMinAndPrev();\n }\n prev = undefined;\n for(i = 0, ilen = scale.ticks.length; i < ilen; ++i){\n curr = scale.getPixelForTick(i);\n updateMinAndPrev();\n }\n return min;\n}\n function computeFitCategoryTraits(index, ruler, options, stackCount) {\n const thickness = options.barThickness;\n let size, ratio;\n if (isNullOrUndef(thickness)) {\n size = ruler.min * options.categoryPercentage;\n ratio = options.barPercentage;\n } else {\n size = thickness * stackCount;\n ratio = 1;\n }\n return {\n chunk: size / stackCount,\n ratio,\n start: ruler.pixels[index] - size / 2\n };\n}\n function computeFlexCategoryTraits(index, ruler, options, stackCount) {\n const pixels = ruler.pixels;\n const curr = pixels[index];\n let prev = index > 0 ? pixels[index - 1] : null;\n let next = index < pixels.length - 1 ? pixels[index + 1] : null;\n const percent = options.categoryPercentage;\n if (prev === null) {\n prev = curr - (next === null ? ruler.end - ruler.start : next - curr);\n }\n if (next === null) {\n next = curr + curr - prev;\n }\n const start = curr - (curr - Math.min(prev, next)) / 2 * percent;\n const size = Math.abs(next - prev) / 2 * percent;\n return {\n chunk: size / stackCount,\n ratio: options.barPercentage,\n start\n };\n}\nfunction parseFloatBar(entry, item, vScale, i) {\n const startValue = vScale.parse(entry[0], i);\n const endValue = vScale.parse(entry[1], i);\n const min = Math.min(startValue, endValue);\n const max = Math.max(startValue, endValue);\n let barStart = min;\n let barEnd = max;\n if (Math.abs(min) > Math.abs(max)) {\n barStart = max;\n barEnd = min;\n }\n item[vScale.axis] = barEnd;\n item._custom = {\n barStart,\n barEnd,\n start: startValue,\n end: endValue,\n min,\n max\n };\n}\nfunction parseValue(entry, item, vScale, i) {\n if (isArray(entry)) {\n parseFloatBar(entry, item, vScale, i);\n } else {\n item[vScale.axis] = vScale.parse(entry, i);\n }\n return item;\n}\nfunction parseArrayOrPrimitive(meta, data, start, count) {\n const iScale = meta.iScale;\n const vScale = meta.vScale;\n const labels = iScale.getLabels();\n const singleScale = iScale === vScale;\n const parsed = [];\n let i, ilen, item, entry;\n for(i = start, ilen = start + count; i < ilen; ++i){\n entry = data[i];\n item = {};\n item[iScale.axis] = singleScale || iScale.parse(labels[i], i);\n parsed.push(parseValue(entry, item, vScale, i));\n }\n return parsed;\n}\nfunction isFloatBar(custom) {\n return custom && custom.barStart !== undefined && custom.barEnd !== undefined;\n}\nfunction barSign(size, vScale, actualBase) {\n if (size !== 0) {\n return sign(size);\n }\n return (vScale.isHorizontal() ? 1 : -1) * (vScale.min >= actualBase ? 1 : -1);\n}\nfunction borderProps(properties) {\n let reverse, start, end, top, bottom;\n if (properties.horizontal) {\n reverse = properties.base > properties.x;\n start = 'left';\n end = 'right';\n } else {\n reverse = properties.base < properties.y;\n start = 'bottom';\n end = 'top';\n }\n if (reverse) {\n top = 'end';\n bottom = 'start';\n } else {\n top = 'start';\n bottom = 'end';\n }\n return {\n start,\n end,\n reverse,\n top,\n bottom\n };\n}\nfunction setBorderSkipped(properties, options, stack, index) {\n let edge = options.borderSkipped;\n const res = {};\n if (!edge) {\n properties.borderSkipped = res;\n return;\n }\n if (edge === true) {\n properties.borderSkipped = {\n top: true,\n right: true,\n bottom: true,\n left: true\n };\n return;\n }\n const { start , end , reverse , top , bottom } = borderProps(properties);\n if (edge === 'middle' && stack) {\n properties.enableBorderRadius = true;\n if ((stack._top || 0) === index) {\n edge = top;\n } else if ((stack._bottom || 0) === index) {\n edge = bottom;\n } else {\n res[parseEdge(bottom, start, end, reverse)] = true;\n edge = top;\n }\n }\n res[parseEdge(edge, start, end, reverse)] = true;\n properties.borderSkipped = res;\n}\nfunction parseEdge(edge, a, b, reverse) {\n if (reverse) {\n edge = swap(edge, a, b);\n edge = startEnd(edge, b, a);\n } else {\n edge = startEnd(edge, a, b);\n }\n return edge;\n}\nfunction swap(orig, v1, v2) {\n return orig === v1 ? v2 : orig === v2 ? v1 : orig;\n}\nfunction startEnd(v, start, end) {\n return v === 'start' ? start : v === 'end' ? end : v;\n}\nfunction setInflateAmount(properties, { inflateAmount }, ratio) {\n properties.inflateAmount = inflateAmount === 'auto' ? ratio === 1 ? 0.33 : 0 : inflateAmount;\n}\nclass BarController extends DatasetController {\n static id = 'bar';\n static defaults = {\n datasetElementType: false,\n dataElementType: 'bar',\n categoryPercentage: 0.8,\n barPercentage: 0.9,\n grouped: true,\n animations: {\n numbers: {\n type: 'number',\n properties: [\n 'x',\n 'y',\n 'base',\n 'width',\n 'height'\n ]\n }\n }\n };\n static overrides = {\n scales: {\n _index_: {\n type: 'category',\n offset: true,\n grid: {\n offset: true\n }\n },\n _value_: {\n type: 'linear',\n beginAtZero: true\n }\n }\n };\n parsePrimitiveData(meta, data, start, count) {\n return parseArrayOrPrimitive(meta, data, start, count);\n }\n parseArrayData(meta, data, start, count) {\n return parseArrayOrPrimitive(meta, data, start, count);\n }\n parseObjectData(meta, data, start, count) {\n const { iScale , vScale } = meta;\n const { xAxisKey ='x' , yAxisKey ='y' } = this._parsing;\n const iAxisKey = iScale.axis === 'x' ? xAxisKey : yAxisKey;\n const vAxisKey = vScale.axis === 'x' ? xAxisKey : yAxisKey;\n const parsed = [];\n let i, ilen, item, obj;\n for(i = start, ilen = start + count; i < ilen; ++i){\n obj = data[i];\n item = {};\n item[iScale.axis] = iScale.parse(resolveObjectKey(obj, iAxisKey), i);\n parsed.push(parseValue(resolveObjectKey(obj, vAxisKey), item, vScale, i));\n }\n return parsed;\n }\n updateRangeFromParsed(range, scale, parsed, stack) {\n super.updateRangeFromParsed(range, scale, parsed, stack);\n const custom = parsed._custom;\n if (custom && scale === this._cachedMeta.vScale) {\n range.min = Math.min(range.min, custom.min);\n range.max = Math.max(range.max, custom.max);\n }\n }\n getMaxOverflow() {\n return 0;\n }\n getLabelAndValue(index) {\n const meta = this._cachedMeta;\n const { iScale , vScale } = meta;\n const parsed = this.getParsed(index);\n const custom = parsed._custom;\n const value = isFloatBar(custom) ? '[' + custom.start + ', ' + custom.end + ']' : '' + vScale.getLabelForValue(parsed[vScale.axis]);\n return {\n label: '' + iScale.getLabelForValue(parsed[iScale.axis]),\n value\n };\n }\n initialize() {\n this.enableOptionSharing = true;\n super.initialize();\n const meta = this._cachedMeta;\n meta.stack = this.getDataset().stack;\n }\n update(mode) {\n const meta = this._cachedMeta;\n this.updateElements(meta.data, 0, meta.data.length, mode);\n }\n updateElements(bars, start, count, mode) {\n const reset = mode === 'reset';\n const { index , _cachedMeta: { vScale } } = this;\n const base = vScale.getBasePixel();\n const horizontal = vScale.isHorizontal();\n const ruler = this._getRuler();\n const { sharedOptions , includeOptions } = this._getSharedOptions(start, mode);\n for(let i = start; i < start + count; i++){\n const parsed = this.getParsed(i);\n const vpixels = reset || isNullOrUndef(parsed[vScale.axis]) ? {\n base,\n head: base\n } : this._calculateBarValuePixels(i);\n const ipixels = this._calculateBarIndexPixels(i, ruler);\n const stack = (parsed._stacks || {})[vScale.axis];\n const properties = {\n horizontal,\n base: vpixels.base,\n enableBorderRadius: !stack || isFloatBar(parsed._custom) || index === stack._top || index === stack._bottom,\n x: horizontal ? vpixels.head : ipixels.center,\n y: horizontal ? ipixels.center : vpixels.head,\n height: horizontal ? ipixels.size : Math.abs(vpixels.size),\n width: horizontal ? Math.abs(vpixels.size) : ipixels.size\n };\n if (includeOptions) {\n properties.options = sharedOptions || this.resolveDataElementOptions(i, bars[i].active ? 'active' : mode);\n }\n const options = properties.options || bars[i].options;\n setBorderSkipped(properties, options, stack, index);\n setInflateAmount(properties, options, ruler.ratio);\n this.updateElement(bars[i], i, properties, mode);\n }\n }\n _getStacks(last, dataIndex) {\n const { iScale } = this._cachedMeta;\n const metasets = iScale.getMatchingVisibleMetas(this._type).filter((meta)=>meta.controller.options.grouped);\n const stacked = iScale.options.stacked;\n const stacks = [];\n const currentParsed = this._cachedMeta.controller.getParsed(dataIndex);\n const iScaleValue = currentParsed && currentParsed[iScale.axis];\n const skipNull = (meta)=>{\n const parsed = meta._parsed.find((item)=>item[iScale.axis] === iScaleValue);\n const val = parsed && parsed[meta.vScale.axis];\n if (isNullOrUndef(val) || isNaN(val)) {\n return true;\n }\n };\n for (const meta of metasets){\n if (dataIndex !== undefined && skipNull(meta)) {\n continue;\n }\n if (stacked === false || stacks.indexOf(meta.stack) === -1 || stacked === undefined && meta.stack === undefined) {\n stacks.push(meta.stack);\n }\n if (meta.index === last) {\n break;\n }\n }\n if (!stacks.length) {\n stacks.push(undefined);\n }\n return stacks;\n }\n _getStackCount(index) {\n return this._getStacks(undefined, index).length;\n }\n _getStackIndex(datasetIndex, name, dataIndex) {\n const stacks = this._getStacks(datasetIndex, dataIndex);\n const index = name !== undefined ? stacks.indexOf(name) : -1;\n return index === -1 ? stacks.length - 1 : index;\n }\n _getRuler() {\n const opts = this.options;\n const meta = this._cachedMeta;\n const iScale = meta.iScale;\n const pixels = [];\n let i, ilen;\n for(i = 0, ilen = meta.data.length; i < ilen; ++i){\n pixels.push(iScale.getPixelForValue(this.getParsed(i)[iScale.axis], i));\n }\n const barThickness = opts.barThickness;\n const min = barThickness || computeMinSampleSize(meta);\n return {\n min,\n pixels,\n start: iScale._startPixel,\n end: iScale._endPixel,\n stackCount: this._getStackCount(),\n scale: iScale,\n grouped: opts.grouped,\n ratio: barThickness ? 1 : opts.categoryPercentage * opts.barPercentage\n };\n }\n _calculateBarValuePixels(index) {\n const { _cachedMeta: { vScale , _stacked , index: datasetIndex } , options: { base: baseValue , minBarLength } } = this;\n const actualBase = baseValue || 0;\n const parsed = this.getParsed(index);\n const custom = parsed._custom;\n const floating = isFloatBar(custom);\n let value = parsed[vScale.axis];\n let start = 0;\n let length = _stacked ? this.applyStack(vScale, parsed, _stacked) : value;\n let head, size;\n if (length !== value) {\n start = length - value;\n length = value;\n }\n if (floating) {\n value = custom.barStart;\n length = custom.barEnd - custom.barStart;\n if (value !== 0 && sign(value) !== sign(custom.barEnd)) {\n start = 0;\n }\n start += value;\n }\n const startValue = !isNullOrUndef(baseValue) && !floating ? baseValue : start;\n let base = vScale.getPixelForValue(startValue);\n if (this.chart.getDataVisibility(index)) {\n head = vScale.getPixelForValue(start + length);\n } else {\n head = base;\n }\n size = head - base;\n if (Math.abs(size) < minBarLength) {\n size = barSign(size, vScale, actualBase) * minBarLength;\n if (value === actualBase) {\n base -= size / 2;\n }\n const startPixel = vScale.getPixelForDecimal(0);\n const endPixel = vScale.getPixelForDecimal(1);\n const min = Math.min(startPixel, endPixel);\n const max = Math.max(startPixel, endPixel);\n base = Math.max(Math.min(base, max), min);\n head = base + size;\n if (_stacked && !floating) {\n parsed._stacks[vScale.axis]._visualValues[datasetIndex] = vScale.getValueForPixel(head) - vScale.getValueForPixel(base);\n }\n }\n if (base === vScale.getPixelForValue(actualBase)) {\n const halfGrid = sign(size) * vScale.getLineWidthForValue(actualBase) / 2;\n base += halfGrid;\n size -= halfGrid;\n }\n return {\n size,\n base,\n head,\n center: head + size / 2\n };\n }\n _calculateBarIndexPixels(index, ruler) {\n const scale = ruler.scale;\n const options = this.options;\n const skipNull = options.skipNull;\n const maxBarThickness = valueOrDefault(options.maxBarThickness, Infinity);\n let center, size;\n if (ruler.grouped) {\n const stackCount = skipNull ? this._getStackCount(index) : ruler.stackCount;\n const range = options.barThickness === 'flex' ? computeFlexCategoryTraits(index, ruler, options, stackCount) : computeFitCategoryTraits(index, ruler, options, stackCount);\n const stackIndex = this._getStackIndex(this.index, this._cachedMeta.stack, skipNull ? index : undefined);\n center = range.start + range.chunk * stackIndex + range.chunk / 2;\n size = Math.min(maxBarThickness, range.chunk * range.ratio);\n } else {\n center = scale.getPixelForValue(this.getParsed(index)[scale.axis], index);\n size = Math.min(maxBarThickness, ruler.min * ruler.ratio);\n }\n return {\n base: center - size / 2,\n head: center + size / 2,\n center,\n size\n };\n }\n draw() {\n const meta = this._cachedMeta;\n const vScale = meta.vScale;\n const rects = meta.data;\n const ilen = rects.length;\n let i = 0;\n for(; i < ilen; ++i){\n if (this.getParsed(i)[vScale.axis] !== null && !rects[i].hidden) {\n rects[i].draw(this._ctx);\n }\n }\n }\n}\n\nclass BubbleController extends DatasetController {\n static id = 'bubble';\n static defaults = {\n datasetElementType: false,\n dataElementType: 'point',\n animations: {\n numbers: {\n type: 'number',\n properties: [\n 'x',\n 'y',\n 'borderWidth',\n 'radius'\n ]\n }\n }\n };\n static overrides = {\n scales: {\n x: {\n type: 'linear'\n },\n y: {\n type: 'linear'\n }\n }\n };\n initialize() {\n this.enableOptionSharing = true;\n super.initialize();\n }\n parsePrimitiveData(meta, data, start, count) {\n const parsed = super.parsePrimitiveData(meta, data, start, count);\n for(let i = 0; i < parsed.length; i++){\n parsed[i]._custom = this.resolveDataElementOptions(i + start).radius;\n }\n return parsed;\n }\n parseArrayData(meta, data, start, count) {\n const parsed = super.parseArrayData(meta, data, start, count);\n for(let i = 0; i < parsed.length; i++){\n const item = data[start + i];\n parsed[i]._custom = valueOrDefault(item[2], this.resolveDataElementOptions(i + start).radius);\n }\n return parsed;\n }\n parseObjectData(meta, data, start, count) {\n const parsed = super.parseObjectData(meta, data, start, count);\n for(let i = 0; i < parsed.length; i++){\n const item = data[start + i];\n parsed[i]._custom = valueOrDefault(item && item.r && +item.r, this.resolveDataElementOptions(i + start).radius);\n }\n return parsed;\n }\n getMaxOverflow() {\n const data = this._cachedMeta.data;\n let max = 0;\n for(let i = data.length - 1; i >= 0; --i){\n max = Math.max(max, data[i].size(this.resolveDataElementOptions(i)) / 2);\n }\n return max > 0 && max;\n }\n getLabelAndValue(index) {\n const meta = this._cachedMeta;\n const labels = this.chart.data.labels || [];\n const { xScale , yScale } = meta;\n const parsed = this.getParsed(index);\n const x = xScale.getLabelForValue(parsed.x);\n const y = yScale.getLabelForValue(parsed.y);\n const r = parsed._custom;\n return {\n label: labels[index] || '',\n value: '(' + x + ', ' + y + (r ? ', ' + r : '') + ')'\n };\n }\n update(mode) {\n const points = this._cachedMeta.data;\n this.updateElements(points, 0, points.length, mode);\n }\n updateElements(points, start, count, mode) {\n const reset = mode === 'reset';\n const { iScale , vScale } = this._cachedMeta;\n const { sharedOptions , includeOptions } = this._getSharedOptions(start, mode);\n const iAxis = iScale.axis;\n const vAxis = vScale.axis;\n for(let i = start; i < start + count; i++){\n const point = points[i];\n const parsed = !reset && this.getParsed(i);\n const properties = {};\n const iPixel = properties[iAxis] = reset ? iScale.getPixelForDecimal(0.5) : iScale.getPixelForValue(parsed[iAxis]);\n const vPixel = properties[vAxis] = reset ? vScale.getBasePixel() : vScale.getPixelForValue(parsed[vAxis]);\n properties.skip = isNaN(iPixel) || isNaN(vPixel);\n if (includeOptions) {\n properties.options = sharedOptions || this.resolveDataElementOptions(i, point.active ? 'active' : mode);\n if (reset) {\n properties.options.radius = 0;\n }\n }\n this.updateElement(point, i, properties, mode);\n }\n }\n resolveDataElementOptions(index, mode) {\n const parsed = this.getParsed(index);\n let values = super.resolveDataElementOptions(index, mode);\n if (values.$shared) {\n values = Object.assign({}, values, {\n $shared: false\n });\n }\n const radius = values.radius;\n if (mode !== 'active') {\n values.radius = 0;\n }\n values.radius += valueOrDefault(parsed && parsed._custom, radius);\n return values;\n }\n}\n\nfunction getRatioAndOffset(rotation, circumference, cutout) {\n let ratioX = 1;\n let ratioY = 1;\n let offsetX = 0;\n let offsetY = 0;\n if (circumference < TAU) {\n const startAngle = rotation;\n const endAngle = startAngle + circumference;\n const startX = Math.cos(startAngle);\n const startY = Math.sin(startAngle);\n const endX = Math.cos(endAngle);\n const endY = Math.sin(endAngle);\n const calcMax = (angle, a, b)=>_angleBetween(angle, startAngle, endAngle, true) ? 1 : Math.max(a, a * cutout, b, b * cutout);\n const calcMin = (angle, a, b)=>_angleBetween(angle, startAngle, endAngle, true) ? -1 : Math.min(a, a * cutout, b, b * cutout);\n const maxX = calcMax(0, startX, endX);\n const maxY = calcMax(HALF_PI, startY, endY);\n const minX = calcMin(PI, startX, endX);\n const minY = calcMin(PI + HALF_PI, startY, endY);\n ratioX = (maxX - minX) / 2;\n ratioY = (maxY - minY) / 2;\n offsetX = -(maxX + minX) / 2;\n offsetY = -(maxY + minY) / 2;\n }\n return {\n ratioX,\n ratioY,\n offsetX,\n offsetY\n };\n}\nclass DoughnutController extends DatasetController {\n static id = 'doughnut';\n static defaults = {\n datasetElementType: false,\n dataElementType: 'arc',\n animation: {\n animateRotate: true,\n animateScale: false\n },\n animations: {\n numbers: {\n type: 'number',\n properties: [\n 'circumference',\n 'endAngle',\n 'innerRadius',\n 'outerRadius',\n 'startAngle',\n 'x',\n 'y',\n 'offset',\n 'borderWidth',\n 'spacing'\n ]\n }\n },\n cutout: '50%',\n rotation: 0,\n circumference: 360,\n radius: '100%',\n spacing: 0,\n indexAxis: 'r'\n };\n static descriptors = {\n _scriptable: (name)=>name !== 'spacing',\n _indexable: (name)=>name !== 'spacing' && !name.startsWith('borderDash') && !name.startsWith('hoverBorderDash')\n };\n static overrides = {\n aspectRatio: 1,\n plugins: {\n legend: {\n labels: {\n generateLabels (chart) {\n const data = chart.data;\n if (data.labels.length && data.datasets.length) {\n const { labels: { pointStyle , color } } = chart.legend.options;\n return data.labels.map((label, i)=>{\n const meta = chart.getDatasetMeta(0);\n const style = meta.controller.getStyle(i);\n return {\n text: label,\n fillStyle: style.backgroundColor,\n strokeStyle: style.borderColor,\n fontColor: color,\n lineWidth: style.borderWidth,\n pointStyle: pointStyle,\n hidden: !chart.getDataVisibility(i),\n index: i\n };\n });\n }\n return [];\n }\n },\n onClick (e, legendItem, legend) {\n legend.chart.toggleDataVisibility(legendItem.index);\n legend.chart.update();\n }\n }\n }\n };\n constructor(chart, datasetIndex){\n super(chart, datasetIndex);\n this.enableOptionSharing = true;\n this.innerRadius = undefined;\n this.outerRadius = undefined;\n this.offsetX = undefined;\n this.offsetY = undefined;\n }\n linkScales() {}\n parse(start, count) {\n const data = this.getDataset().data;\n const meta = this._cachedMeta;\n if (this._parsing === false) {\n meta._parsed = data;\n } else {\n let getter = (i)=>+data[i];\n if (isObject(data[start])) {\n const { key ='value' } = this._parsing;\n getter = (i)=>+resolveObjectKey(data[i], key);\n }\n let i, ilen;\n for(i = start, ilen = start + count; i < ilen; ++i){\n meta._parsed[i] = getter(i);\n }\n }\n }\n _getRotation() {\n return toRadians(this.options.rotation - 90);\n }\n _getCircumference() {\n return toRadians(this.options.circumference);\n }\n _getRotationExtents() {\n let min = TAU;\n let max = -TAU;\n for(let i = 0; i < this.chart.data.datasets.length; ++i){\n if (this.chart.isDatasetVisible(i) && this.chart.getDatasetMeta(i).type === this._type) {\n const controller = this.chart.getDatasetMeta(i).controller;\n const rotation = controller._getRotation();\n const circumference = controller._getCircumference();\n min = Math.min(min, rotation);\n max = Math.max(max, rotation + circumference);\n }\n }\n return {\n rotation: min,\n circumference: max - min\n };\n }\n update(mode) {\n const chart = this.chart;\n const { chartArea } = chart;\n const meta = this._cachedMeta;\n const arcs = meta.data;\n const spacing = this.getMaxBorderWidth() + this.getMaxOffset(arcs) + this.options.spacing;\n const maxSize = Math.max((Math.min(chartArea.width, chartArea.height) - spacing) / 2, 0);\n const cutout = Math.min(toPercentage(this.options.cutout, maxSize), 1);\n const chartWeight = this._getRingWeight(this.index);\n const { circumference , rotation } = this._getRotationExtents();\n const { ratioX , ratioY , offsetX , offsetY } = getRatioAndOffset(rotation, circumference, cutout);\n const maxWidth = (chartArea.width - spacing) / ratioX;\n const maxHeight = (chartArea.height - spacing) / ratioY;\n const maxRadius = Math.max(Math.min(maxWidth, maxHeight) / 2, 0);\n const outerRadius = toDimension(this.options.radius, maxRadius);\n const innerRadius = Math.max(outerRadius * cutout, 0);\n const radiusLength = (outerRadius - innerRadius) / this._getVisibleDatasetWeightTotal();\n this.offsetX = offsetX * outerRadius;\n this.offsetY = offsetY * outerRadius;\n meta.total = this.calculateTotal();\n this.outerRadius = outerRadius - radiusLength * this._getRingWeightOffset(this.index);\n this.innerRadius = Math.max(this.outerRadius - radiusLength * chartWeight, 0);\n this.updateElements(arcs, 0, arcs.length, mode);\n }\n _circumference(i, reset) {\n const opts = this.options;\n const meta = this._cachedMeta;\n const circumference = this._getCircumference();\n if (reset && opts.animation.animateRotate || !this.chart.getDataVisibility(i) || meta._parsed[i] === null || meta.data[i].hidden) {\n return 0;\n }\n return this.calculateCircumference(meta._parsed[i] * circumference / TAU);\n }\n updateElements(arcs, start, count, mode) {\n const reset = mode === 'reset';\n const chart = this.chart;\n const chartArea = chart.chartArea;\n const opts = chart.options;\n const animationOpts = opts.animation;\n const centerX = (chartArea.left + chartArea.right) / 2;\n const centerY = (chartArea.top + chartArea.bottom) / 2;\n const animateScale = reset && animationOpts.animateScale;\n const innerRadius = animateScale ? 0 : this.innerRadius;\n const outerRadius = animateScale ? 0 : this.outerRadius;\n const { sharedOptions , includeOptions } = this._getSharedOptions(start, mode);\n let startAngle = this._getRotation();\n let i;\n for(i = 0; i < start; ++i){\n startAngle += this._circumference(i, reset);\n }\n for(i = start; i < start + count; ++i){\n const circumference = this._circumference(i, reset);\n const arc = arcs[i];\n const properties = {\n x: centerX + this.offsetX,\n y: centerY + this.offsetY,\n startAngle,\n endAngle: startAngle + circumference,\n circumference,\n outerRadius,\n innerRadius\n };\n if (includeOptions) {\n properties.options = sharedOptions || this.resolveDataElementOptions(i, arc.active ? 'active' : mode);\n }\n startAngle += circumference;\n this.updateElement(arc, i, properties, mode);\n }\n }\n calculateTotal() {\n const meta = this._cachedMeta;\n const metaData = meta.data;\n let total = 0;\n let i;\n for(i = 0; i < metaData.length; i++){\n const value = meta._parsed[i];\n if (value !== null && !isNaN(value) && this.chart.getDataVisibility(i) && !metaData[i].hidden) {\n total += Math.abs(value);\n }\n }\n return total;\n }\n calculateCircumference(value) {\n const total = this._cachedMeta.total;\n if (total > 0 && !isNaN(value)) {\n return TAU * (Math.abs(value) / total);\n }\n return 0;\n }\n getLabelAndValue(index) {\n const meta = this._cachedMeta;\n const chart = this.chart;\n const labels = chart.data.labels || [];\n const value = formatNumber(meta._parsed[index], chart.options.locale);\n return {\n label: labels[index] || '',\n value\n };\n }\n getMaxBorderWidth(arcs) {\n let max = 0;\n const chart = this.chart;\n let i, ilen, meta, controller, options;\n if (!arcs) {\n for(i = 0, ilen = chart.data.datasets.length; i < ilen; ++i){\n if (chart.isDatasetVisible(i)) {\n meta = chart.getDatasetMeta(i);\n arcs = meta.data;\n controller = meta.controller;\n break;\n }\n }\n }\n if (!arcs) {\n return 0;\n }\n for(i = 0, ilen = arcs.length; i < ilen; ++i){\n options = controller.resolveDataElementOptions(i);\n if (options.borderAlign !== 'inner') {\n max = Math.max(max, options.borderWidth || 0, options.hoverBorderWidth || 0);\n }\n }\n return max;\n }\n getMaxOffset(arcs) {\n let max = 0;\n for(let i = 0, ilen = arcs.length; i < ilen; ++i){\n const options = this.resolveDataElementOptions(i);\n max = Math.max(max, options.offset || 0, options.hoverOffset || 0);\n }\n return max;\n }\n _getRingWeightOffset(datasetIndex) {\n let ringWeightOffset = 0;\n for(let i = 0; i < datasetIndex; ++i){\n if (this.chart.isDatasetVisible(i)) {\n ringWeightOffset += this._getRingWeight(i);\n }\n }\n return ringWeightOffset;\n }\n _getRingWeight(datasetIndex) {\n return Math.max(valueOrDefault(this.chart.data.datasets[datasetIndex].weight, 1), 0);\n }\n _getVisibleDatasetWeightTotal() {\n return this._getRingWeightOffset(this.chart.data.datasets.length) || 1;\n }\n}\n\nclass LineController extends DatasetController {\n static id = 'line';\n static defaults = {\n datasetElementType: 'line',\n dataElementType: 'point',\n showLine: true,\n spanGaps: false\n };\n static overrides = {\n scales: {\n _index_: {\n type: 'category'\n },\n _value_: {\n type: 'linear'\n }\n }\n };\n initialize() {\n this.enableOptionSharing = true;\n this.supportsDecimation = true;\n super.initialize();\n }\n update(mode) {\n const meta = this._cachedMeta;\n const { dataset: line , data: points = [] , _dataset } = meta;\n const animationsDisabled = this.chart._animationsDisabled;\n let { start , count } = _getStartAndCountOfVisiblePoints(meta, points, animationsDisabled);\n this._drawStart = start;\n this._drawCount = count;\n if (_scaleRangesChanged(meta)) {\n start = 0;\n count = points.length;\n }\n line._chart = this.chart;\n line._datasetIndex = this.index;\n line._decimated = !!_dataset._decimated;\n line.points = points;\n const options = this.resolveDatasetElementOptions(mode);\n if (!this.options.showLine) {\n options.borderWidth = 0;\n }\n options.segment = this.options.segment;\n this.updateElement(line, undefined, {\n animated: !animationsDisabled,\n options\n }, mode);\n this.updateElements(points, start, count, mode);\n }\n updateElements(points, start, count, mode) {\n const reset = mode === 'reset';\n const { iScale , vScale , _stacked , _dataset } = this._cachedMeta;\n const { sharedOptions , includeOptions } = this._getSharedOptions(start, mode);\n const iAxis = iScale.axis;\n const vAxis = vScale.axis;\n const { spanGaps , segment } = this.options;\n const maxGapLength = isNumber(spanGaps) ? spanGaps : Number.POSITIVE_INFINITY;\n const directUpdate = this.chart._animationsDisabled || reset || mode === 'none';\n const end = start + count;\n const pointsCount = points.length;\n let prevParsed = start > 0 && this.getParsed(start - 1);\n for(let i = 0; i < pointsCount; ++i){\n const point = points[i];\n const properties = directUpdate ? point : {};\n if (i < start || i >= end) {\n properties.skip = true;\n continue;\n }\n const parsed = this.getParsed(i);\n const nullData = isNullOrUndef(parsed[vAxis]);\n const iPixel = properties[iAxis] = iScale.getPixelForValue(parsed[iAxis], i);\n const vPixel = properties[vAxis] = reset || nullData ? vScale.getBasePixel() : vScale.getPixelForValue(_stacked ? this.applyStack(vScale, parsed, _stacked) : parsed[vAxis], i);\n properties.skip = isNaN(iPixel) || isNaN(vPixel) || nullData;\n properties.stop = i > 0 && Math.abs(parsed[iAxis] - prevParsed[iAxis]) > maxGapLength;\n if (segment) {\n properties.parsed = parsed;\n properties.raw = _dataset.data[i];\n }\n if (includeOptions) {\n properties.options = sharedOptions || this.resolveDataElementOptions(i, point.active ? 'active' : mode);\n }\n if (!directUpdate) {\n this.updateElement(point, i, properties, mode);\n }\n prevParsed = parsed;\n }\n }\n getMaxOverflow() {\n const meta = this._cachedMeta;\n const dataset = meta.dataset;\n const border = dataset.options && dataset.options.borderWidth || 0;\n const data = meta.data || [];\n if (!data.length) {\n return border;\n }\n const firstPoint = data[0].size(this.resolveDataElementOptions(0));\n const lastPoint = data[data.length - 1].size(this.resolveDataElementOptions(data.length - 1));\n return Math.max(border, firstPoint, lastPoint) / 2;\n }\n draw() {\n const meta = this._cachedMeta;\n meta.dataset.updateControlPoints(this.chart.chartArea, meta.iScale.axis);\n super.draw();\n }\n}\n\nclass PolarAreaController extends DatasetController {\n static id = 'polarArea';\n static defaults = {\n dataElementType: 'arc',\n animation: {\n animateRotate: true,\n animateScale: true\n },\n animations: {\n numbers: {\n type: 'number',\n properties: [\n 'x',\n 'y',\n 'startAngle',\n 'endAngle',\n 'innerRadius',\n 'outerRadius'\n ]\n }\n },\n indexAxis: 'r',\n startAngle: 0\n };\n static overrides = {\n aspectRatio: 1,\n plugins: {\n legend: {\n labels: {\n generateLabels (chart) {\n const data = chart.data;\n if (data.labels.length && data.datasets.length) {\n const { labels: { pointStyle , color } } = chart.legend.options;\n return data.labels.map((label, i)=>{\n const meta = chart.getDatasetMeta(0);\n const style = meta.controller.getStyle(i);\n return {\n text: label,\n fillStyle: style.backgroundColor,\n strokeStyle: style.borderColor,\n fontColor: color,\n lineWidth: style.borderWidth,\n pointStyle: pointStyle,\n hidden: !chart.getDataVisibility(i),\n index: i\n };\n });\n }\n return [];\n }\n },\n onClick (e, legendItem, legend) {\n legend.chart.toggleDataVisibility(legendItem.index);\n legend.chart.update();\n }\n }\n },\n scales: {\n r: {\n type: 'radialLinear',\n angleLines: {\n display: false\n },\n beginAtZero: true,\n grid: {\n circular: true\n },\n pointLabels: {\n display: false\n },\n startAngle: 0\n }\n }\n };\n constructor(chart, datasetIndex){\n super(chart, datasetIndex);\n this.innerRadius = undefined;\n this.outerRadius = undefined;\n }\n getLabelAndValue(index) {\n const meta = this._cachedMeta;\n const chart = this.chart;\n const labels = chart.data.labels || [];\n const value = formatNumber(meta._parsed[index].r, chart.options.locale);\n return {\n label: labels[index] || '',\n value\n };\n }\n parseObjectData(meta, data, start, count) {\n return _parseObjectDataRadialScale.bind(this)(meta, data, start, count);\n }\n update(mode) {\n const arcs = this._cachedMeta.data;\n this._updateRadius();\n this.updateElements(arcs, 0, arcs.length, mode);\n }\n getMinMax() {\n const meta = this._cachedMeta;\n const range = {\n min: Number.POSITIVE_INFINITY,\n max: Number.NEGATIVE_INFINITY\n };\n meta.data.forEach((element, index)=>{\n const parsed = this.getParsed(index).r;\n if (!isNaN(parsed) && this.chart.getDataVisibility(index)) {\n if (parsed < range.min) {\n range.min = parsed;\n }\n if (parsed > range.max) {\n range.max = parsed;\n }\n }\n });\n return range;\n }\n _updateRadius() {\n const chart = this.chart;\n const chartArea = chart.chartArea;\n const opts = chart.options;\n const minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);\n const outerRadius = Math.max(minSize / 2, 0);\n const innerRadius = Math.max(opts.cutoutPercentage ? outerRadius / 100 * opts.cutoutPercentage : 1, 0);\n const radiusLength = (outerRadius - innerRadius) / chart.getVisibleDatasetCount();\n this.outerRadius = outerRadius - radiusLength * this.index;\n this.innerRadius = this.outerRadius - radiusLength;\n }\n updateElements(arcs, start, count, mode) {\n const reset = mode === 'reset';\n const chart = this.chart;\n const opts = chart.options;\n const animationOpts = opts.animation;\n const scale = this._cachedMeta.rScale;\n const centerX = scale.xCenter;\n const centerY = scale.yCenter;\n const datasetStartAngle = scale.getIndexAngle(0) - 0.5 * PI;\n let angle = datasetStartAngle;\n let i;\n const defaultAngle = 360 / this.countVisibleElements();\n for(i = 0; i < start; ++i){\n angle += this._computeAngle(i, mode, defaultAngle);\n }\n for(i = start; i < start + count; i++){\n const arc = arcs[i];\n let startAngle = angle;\n let endAngle = angle + this._computeAngle(i, mode, defaultAngle);\n let outerRadius = chart.getDataVisibility(i) ? scale.getDistanceFromCenterForValue(this.getParsed(i).r) : 0;\n angle = endAngle;\n if (reset) {\n if (animationOpts.animateScale) {\n outerRadius = 0;\n }\n if (animationOpts.animateRotate) {\n startAngle = endAngle = datasetStartAngle;\n }\n }\n const properties = {\n x: centerX,\n y: centerY,\n innerRadius: 0,\n outerRadius,\n startAngle,\n endAngle,\n options: this.resolveDataElementOptions(i, arc.active ? 'active' : mode)\n };\n this.updateElement(arc, i, properties, mode);\n }\n }\n countVisibleElements() {\n const meta = this._cachedMeta;\n let count = 0;\n meta.data.forEach((element, index)=>{\n if (!isNaN(this.getParsed(index).r) && this.chart.getDataVisibility(index)) {\n count++;\n }\n });\n return count;\n }\n _computeAngle(index, mode, defaultAngle) {\n return this.chart.getDataVisibility(index) ? toRadians(this.resolveDataElementOptions(index, mode).angle || defaultAngle) : 0;\n }\n}\n\nclass PieController extends DoughnutController {\n static id = 'pie';\n static defaults = {\n cutout: 0,\n rotation: 0,\n circumference: 360,\n radius: '100%'\n };\n}\n\nclass RadarController extends DatasetController {\n static id = 'radar';\n static defaults = {\n datasetElementType: 'line',\n dataElementType: 'point',\n indexAxis: 'r',\n showLine: true,\n elements: {\n line: {\n fill: 'start'\n }\n }\n };\n static overrides = {\n aspectRatio: 1,\n scales: {\n r: {\n type: 'radialLinear'\n }\n }\n };\n getLabelAndValue(index) {\n const vScale = this._cachedMeta.vScale;\n const parsed = this.getParsed(index);\n return {\n label: vScale.getLabels()[index],\n value: '' + vScale.getLabelForValue(parsed[vScale.axis])\n };\n }\n parseObjectData(meta, data, start, count) {\n return _parseObjectDataRadialScale.bind(this)(meta, data, start, count);\n }\n update(mode) {\n const meta = this._cachedMeta;\n const line = meta.dataset;\n const points = meta.data || [];\n const labels = meta.iScale.getLabels();\n line.points = points;\n if (mode !== 'resize') {\n const options = this.resolveDatasetElementOptions(mode);\n if (!this.options.showLine) {\n options.borderWidth = 0;\n }\n const properties = {\n _loop: true,\n _fullLoop: labels.length === points.length,\n options\n };\n this.updateElement(line, undefined, properties, mode);\n }\n this.updateElements(points, 0, points.length, mode);\n }\n updateElements(points, start, count, mode) {\n const scale = this._cachedMeta.rScale;\n const reset = mode === 'reset';\n for(let i = start; i < start + count; i++){\n const point = points[i];\n const options = this.resolveDataElementOptions(i, point.active ? 'active' : mode);\n const pointPosition = scale.getPointPositionForValue(i, this.getParsed(i).r);\n const x = reset ? scale.xCenter : pointPosition.x;\n const y = reset ? scale.yCenter : pointPosition.y;\n const properties = {\n x,\n y,\n angle: pointPosition.angle,\n skip: isNaN(x) || isNaN(y),\n options\n };\n this.updateElement(point, i, properties, mode);\n }\n }\n}\n\nclass ScatterController extends DatasetController {\n static id = 'scatter';\n static defaults = {\n datasetElementType: false,\n dataElementType: 'point',\n showLine: false,\n fill: false\n };\n static overrides = {\n interaction: {\n mode: 'point'\n },\n scales: {\n x: {\n type: 'linear'\n },\n y: {\n type: 'linear'\n }\n }\n };\n getLabelAndValue(index) {\n const meta = this._cachedMeta;\n const labels = this.chart.data.labels || [];\n const { xScale , yScale } = meta;\n const parsed = this.getParsed(index);\n const x = xScale.getLabelForValue(parsed.x);\n const y = yScale.getLabelForValue(parsed.y);\n return {\n label: labels[index] || '',\n value: '(' + x + ', ' + y + ')'\n };\n }\n update(mode) {\n const meta = this._cachedMeta;\n const { data: points = [] } = meta;\n const animationsDisabled = this.chart._animationsDisabled;\n let { start , count } = _getStartAndCountOfVisiblePoints(meta, points, animationsDisabled);\n this._drawStart = start;\n this._drawCount = count;\n if (_scaleRangesChanged(meta)) {\n start = 0;\n count = points.length;\n }\n if (this.options.showLine) {\n if (!this.datasetElementType) {\n this.addElements();\n }\n const { dataset: line , _dataset } = meta;\n line._chart = this.chart;\n line._datasetIndex = this.index;\n line._decimated = !!_dataset._decimated;\n line.points = points;\n const options = this.resolveDatasetElementOptions(mode);\n options.segment = this.options.segment;\n this.updateElement(line, undefined, {\n animated: !animationsDisabled,\n options\n }, mode);\n } else if (this.datasetElementType) {\n delete meta.dataset;\n this.datasetElementType = false;\n }\n this.updateElements(points, start, count, mode);\n }\n addElements() {\n const { showLine } = this.options;\n if (!this.datasetElementType && showLine) {\n this.datasetElementType = this.chart.registry.getElement('line');\n }\n super.addElements();\n }\n updateElements(points, start, count, mode) {\n const reset = mode === 'reset';\n const { iScale , vScale , _stacked , _dataset } = this._cachedMeta;\n const firstOpts = this.resolveDataElementOptions(start, mode);\n const sharedOptions = this.getSharedOptions(firstOpts);\n const includeOptions = this.includeOptions(mode, sharedOptions);\n const iAxis = iScale.axis;\n const vAxis = vScale.axis;\n const { spanGaps , segment } = this.options;\n const maxGapLength = isNumber(spanGaps) ? spanGaps : Number.POSITIVE_INFINITY;\n const directUpdate = this.chart._animationsDisabled || reset || mode === 'none';\n let prevParsed = start > 0 && this.getParsed(start - 1);\n for(let i = start; i < start + count; ++i){\n const point = points[i];\n const parsed = this.getParsed(i);\n const properties = directUpdate ? point : {};\n const nullData = isNullOrUndef(parsed[vAxis]);\n const iPixel = properties[iAxis] = iScale.getPixelForValue(parsed[iAxis], i);\n const vPixel = properties[vAxis] = reset || nullData ? vScale.getBasePixel() : vScale.getPixelForValue(_stacked ? this.applyStack(vScale, parsed, _stacked) : parsed[vAxis], i);\n properties.skip = isNaN(iPixel) || isNaN(vPixel) || nullData;\n properties.stop = i > 0 && Math.abs(parsed[iAxis] - prevParsed[iAxis]) > maxGapLength;\n if (segment) {\n properties.parsed = parsed;\n properties.raw = _dataset.data[i];\n }\n if (includeOptions) {\n properties.options = sharedOptions || this.resolveDataElementOptions(i, point.active ? 'active' : mode);\n }\n if (!directUpdate) {\n this.updateElement(point, i, properties, mode);\n }\n prevParsed = parsed;\n }\n this.updateSharedOptions(sharedOptions, mode, firstOpts);\n }\n getMaxOverflow() {\n const meta = this._cachedMeta;\n const data = meta.data || [];\n if (!this.options.showLine) {\n let max = 0;\n for(let i = data.length - 1; i >= 0; --i){\n max = Math.max(max, data[i].size(this.resolveDataElementOptions(i)) / 2);\n }\n return max > 0 && max;\n }\n const dataset = meta.dataset;\n const border = dataset.options && dataset.options.borderWidth || 0;\n if (!data.length) {\n return border;\n }\n const firstPoint = data[0].size(this.resolveDataElementOptions(0));\n const lastPoint = data[data.length - 1].size(this.resolveDataElementOptions(data.length - 1));\n return Math.max(border, firstPoint, lastPoint) / 2;\n }\n}\n\nvar controllers = /*#__PURE__*/Object.freeze({\n__proto__: null,\nBarController: BarController,\nBubbleController: BubbleController,\nDoughnutController: DoughnutController,\nLineController: LineController,\nPieController: PieController,\nPolarAreaController: PolarAreaController,\nRadarController: RadarController,\nScatterController: ScatterController\n});\n\n/**\n * @namespace Chart._adapters\n * @since 2.8.0\n * @private\n */ function chart_abstract() {\n throw new Error('This method is not implemented: Check that a complete date adapter is provided.');\n}\n/**\n * Date adapter (current used by the time scale)\n * @namespace Chart._adapters._date\n * @memberof Chart._adapters\n * @private\n */ class DateAdapterBase {\n /**\n * Override default date adapter methods.\n * Accepts type parameter to define options type.\n * @example\n * Chart._adapters._date.override<{myAdapterOption: string}>({\n * init() {\n * console.log(this.options.myAdapterOption);\n * }\n * })\n */ static override(members) {\n Object.assign(DateAdapterBase.prototype, members);\n }\n options;\n constructor(options){\n this.options = options || {};\n }\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n init() {}\n formats() {\n return chart_abstract();\n }\n parse() {\n return chart_abstract();\n }\n format() {\n return chart_abstract();\n }\n add() {\n return chart_abstract();\n }\n diff() {\n return chart_abstract();\n }\n startOf() {\n return chart_abstract();\n }\n endOf() {\n return chart_abstract();\n }\n}\nvar adapters = {\n _date: DateAdapterBase\n};\n\nfunction binarySearch(metaset, axis, value, intersect) {\n const { controller , data , _sorted } = metaset;\n const iScale = controller._cachedMeta.iScale;\n if (iScale && axis === iScale.axis && axis !== 'r' && _sorted && data.length) {\n const lookupMethod = iScale._reversePixels ? _rlookupByKey : _lookupByKey;\n if (!intersect) {\n return lookupMethod(data, axis, value);\n } else if (controller._sharedOptions) {\n const el = data[0];\n const range = typeof el.getRange === 'function' && el.getRange(axis);\n if (range) {\n const start = lookupMethod(data, axis, value - range);\n const end = lookupMethod(data, axis, value + range);\n return {\n lo: start.lo,\n hi: end.hi\n };\n }\n }\n }\n return {\n lo: 0,\n hi: data.length - 1\n };\n}\n function evaluateInteractionItems(chart, axis, position, handler, intersect) {\n const metasets = chart.getSortedVisibleDatasetMetas();\n const value = position[axis];\n for(let i = 0, ilen = metasets.length; i < ilen; ++i){\n const { index , data } = metasets[i];\n const { lo , hi } = binarySearch(metasets[i], axis, value, intersect);\n for(let j = lo; j <= hi; ++j){\n const element = data[j];\n if (!element.skip) {\n handler(element, index, j);\n }\n }\n }\n}\n function getDistanceMetricForAxis(axis) {\n const useX = axis.indexOf('x') !== -1;\n const useY = axis.indexOf('y') !== -1;\n return function(pt1, pt2) {\n const deltaX = useX ? Math.abs(pt1.x - pt2.x) : 0;\n const deltaY = useY ? Math.abs(pt1.y - pt2.y) : 0;\n return Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));\n };\n}\n function getIntersectItems(chart, position, axis, useFinalPosition, includeInvisible) {\n const items = [];\n if (!includeInvisible && !chart.isPointInArea(position)) {\n return items;\n }\n const evaluationFunc = function(element, datasetIndex, index) {\n if (!includeInvisible && !_isPointInArea(element, chart.chartArea, 0)) {\n return;\n }\n if (element.inRange(position.x, position.y, useFinalPosition)) {\n items.push({\n element,\n datasetIndex,\n index\n });\n }\n };\n evaluateInteractionItems(chart, axis, position, evaluationFunc, true);\n return items;\n}\n function getNearestRadialItems(chart, position, axis, useFinalPosition) {\n let items = [];\n function evaluationFunc(element, datasetIndex, index) {\n const { startAngle , endAngle } = element.getProps([\n 'startAngle',\n 'endAngle'\n ], useFinalPosition);\n const { angle } = getAngleFromPoint(element, {\n x: position.x,\n y: position.y\n });\n if (_angleBetween(angle, startAngle, endAngle)) {\n items.push({\n element,\n datasetIndex,\n index\n });\n }\n }\n evaluateInteractionItems(chart, axis, position, evaluationFunc);\n return items;\n}\n function getNearestCartesianItems(chart, position, axis, intersect, useFinalPosition, includeInvisible) {\n let items = [];\n const distanceMetric = getDistanceMetricForAxis(axis);\n let minDistance = Number.POSITIVE_INFINITY;\n function evaluationFunc(element, datasetIndex, index) {\n const inRange = element.inRange(position.x, position.y, useFinalPosition);\n if (intersect && !inRange) {\n return;\n }\n const center = element.getCenterPoint(useFinalPosition);\n const pointInArea = !!includeInvisible || chart.isPointInArea(center);\n if (!pointInArea && !inRange) {\n return;\n }\n const distance = distanceMetric(position, center);\n if (distance < minDistance) {\n items = [\n {\n element,\n datasetIndex,\n index\n }\n ];\n minDistance = distance;\n } else if (distance === minDistance) {\n items.push({\n element,\n datasetIndex,\n index\n });\n }\n }\n evaluateInteractionItems(chart, axis, position, evaluationFunc);\n return items;\n}\n function getNearestItems(chart, position, axis, intersect, useFinalPosition, includeInvisible) {\n if (!includeInvisible && !chart.isPointInArea(position)) {\n return [];\n }\n return axis === 'r' && !intersect ? getNearestRadialItems(chart, position, axis, useFinalPosition) : getNearestCartesianItems(chart, position, axis, intersect, useFinalPosition, includeInvisible);\n}\n function getAxisItems(chart, position, axis, intersect, useFinalPosition) {\n const items = [];\n const rangeMethod = axis === 'x' ? 'inXRange' : 'inYRange';\n let intersectsItem = false;\n evaluateInteractionItems(chart, axis, position, (element, datasetIndex, index)=>{\n if (element[rangeMethod] && element[rangeMethod](position[axis], useFinalPosition)) {\n items.push({\n element,\n datasetIndex,\n index\n });\n intersectsItem = intersectsItem || element.inRange(position.x, position.y, useFinalPosition);\n }\n });\n if (intersect && !intersectsItem) {\n return [];\n }\n return items;\n}\n var Interaction = {\n evaluateInteractionItems,\n modes: {\n index (chart, e, options, useFinalPosition) {\n const position = getRelativePosition(e, chart);\n const axis = options.axis || 'x';\n const includeInvisible = options.includeInvisible || false;\n const items = options.intersect ? getIntersectItems(chart, position, axis, useFinalPosition, includeInvisible) : getNearestItems(chart, position, axis, false, useFinalPosition, includeInvisible);\n const elements = [];\n if (!items.length) {\n return [];\n }\n chart.getSortedVisibleDatasetMetas().forEach((meta)=>{\n const index = items[0].index;\n const element = meta.data[index];\n if (element && !element.skip) {\n elements.push({\n element,\n datasetIndex: meta.index,\n index\n });\n }\n });\n return elements;\n },\n dataset (chart, e, options, useFinalPosition) {\n const position = getRelativePosition(e, chart);\n const axis = options.axis || 'xy';\n const includeInvisible = options.includeInvisible || false;\n let items = options.intersect ? getIntersectItems(chart, position, axis, useFinalPosition, includeInvisible) : getNearestItems(chart, position, axis, false, useFinalPosition, includeInvisible);\n if (items.length > 0) {\n const datasetIndex = items[0].datasetIndex;\n const data = chart.getDatasetMeta(datasetIndex).data;\n items = [];\n for(let i = 0; i < data.length; ++i){\n items.push({\n element: data[i],\n datasetIndex,\n index: i\n });\n }\n }\n return items;\n },\n point (chart, e, options, useFinalPosition) {\n const position = getRelativePosition(e, chart);\n const axis = options.axis || 'xy';\n const includeInvisible = options.includeInvisible || false;\n return getIntersectItems(chart, position, axis, useFinalPosition, includeInvisible);\n },\n nearest (chart, e, options, useFinalPosition) {\n const position = getRelativePosition(e, chart);\n const axis = options.axis || 'xy';\n const includeInvisible = options.includeInvisible || false;\n return getNearestItems(chart, position, axis, options.intersect, useFinalPosition, includeInvisible);\n },\n x (chart, e, options, useFinalPosition) {\n const position = getRelativePosition(e, chart);\n return getAxisItems(chart, position, 'x', options.intersect, useFinalPosition);\n },\n y (chart, e, options, useFinalPosition) {\n const position = getRelativePosition(e, chart);\n return getAxisItems(chart, position, 'y', options.intersect, useFinalPosition);\n }\n }\n};\n\nconst STATIC_POSITIONS = [\n 'left',\n 'top',\n 'right',\n 'bottom'\n];\nfunction filterByPosition(array, position) {\n return array.filter((v)=>v.pos === position);\n}\nfunction filterDynamicPositionByAxis(array, axis) {\n return array.filter((v)=>STATIC_POSITIONS.indexOf(v.pos) === -1 && v.box.axis === axis);\n}\nfunction sortByWeight(array, reverse) {\n return array.sort((a, b)=>{\n const v0 = reverse ? b : a;\n const v1 = reverse ? a : b;\n return v0.weight === v1.weight ? v0.index - v1.index : v0.weight - v1.weight;\n });\n}\nfunction wrapBoxes(boxes) {\n const layoutBoxes = [];\n let i, ilen, box, pos, stack, stackWeight;\n for(i = 0, ilen = (boxes || []).length; i < ilen; ++i){\n box = boxes[i];\n ({ position: pos , options: { stack , stackWeight =1 } } = box);\n layoutBoxes.push({\n index: i,\n box,\n pos,\n horizontal: box.isHorizontal(),\n weight: box.weight,\n stack: stack && pos + stack,\n stackWeight\n });\n }\n return layoutBoxes;\n}\nfunction buildStacks(layouts) {\n const stacks = {};\n for (const wrap of layouts){\n const { stack , pos , stackWeight } = wrap;\n if (!stack || !STATIC_POSITIONS.includes(pos)) {\n continue;\n }\n const _stack = stacks[stack] || (stacks[stack] = {\n count: 0,\n placed: 0,\n weight: 0,\n size: 0\n });\n _stack.count++;\n _stack.weight += stackWeight;\n }\n return stacks;\n}\n function setLayoutDims(layouts, params) {\n const stacks = buildStacks(layouts);\n const { vBoxMaxWidth , hBoxMaxHeight } = params;\n let i, ilen, layout;\n for(i = 0, ilen = layouts.length; i < ilen; ++i){\n layout = layouts[i];\n const { fullSize } = layout.box;\n const stack = stacks[layout.stack];\n const factor = stack && layout.stackWeight / stack.weight;\n if (layout.horizontal) {\n layout.width = factor ? factor * vBoxMaxWidth : fullSize && params.availableWidth;\n layout.height = hBoxMaxHeight;\n } else {\n layout.width = vBoxMaxWidth;\n layout.height = factor ? factor * hBoxMaxHeight : fullSize && params.availableHeight;\n }\n }\n return stacks;\n}\nfunction buildLayoutBoxes(boxes) {\n const layoutBoxes = wrapBoxes(boxes);\n const fullSize = sortByWeight(layoutBoxes.filter((wrap)=>wrap.box.fullSize), true);\n const left = sortByWeight(filterByPosition(layoutBoxes, 'left'), true);\n const right = sortByWeight(filterByPosition(layoutBoxes, 'right'));\n const top = sortByWeight(filterByPosition(layoutBoxes, 'top'), true);\n const bottom = sortByWeight(filterByPosition(layoutBoxes, 'bottom'));\n const centerHorizontal = filterDynamicPositionByAxis(layoutBoxes, 'x');\n const centerVertical = filterDynamicPositionByAxis(layoutBoxes, 'y');\n return {\n fullSize,\n leftAndTop: left.concat(top),\n rightAndBottom: right.concat(centerVertical).concat(bottom).concat(centerHorizontal),\n chartArea: filterByPosition(layoutBoxes, 'chartArea'),\n vertical: left.concat(right).concat(centerVertical),\n horizontal: top.concat(bottom).concat(centerHorizontal)\n };\n}\nfunction getCombinedMax(maxPadding, chartArea, a, b) {\n return Math.max(maxPadding[a], chartArea[a]) + Math.max(maxPadding[b], chartArea[b]);\n}\nfunction updateMaxPadding(maxPadding, boxPadding) {\n maxPadding.top = Math.max(maxPadding.top, boxPadding.top);\n maxPadding.left = Math.max(maxPadding.left, boxPadding.left);\n maxPadding.bottom = Math.max(maxPadding.bottom, boxPadding.bottom);\n maxPadding.right = Math.max(maxPadding.right, boxPadding.right);\n}\nfunction updateDims(chartArea, params, layout, stacks) {\n const { pos , box } = layout;\n const maxPadding = chartArea.maxPadding;\n if (!isObject(pos)) {\n if (layout.size) {\n chartArea[pos] -= layout.size;\n }\n const stack = stacks[layout.stack] || {\n size: 0,\n count: 1\n };\n stack.size = Math.max(stack.size, layout.horizontal ? box.height : box.width);\n layout.size = stack.size / stack.count;\n chartArea[pos] += layout.size;\n }\n if (box.getPadding) {\n updateMaxPadding(maxPadding, box.getPadding());\n }\n const newWidth = Math.max(0, params.outerWidth - getCombinedMax(maxPadding, chartArea, 'left', 'right'));\n const newHeight = Math.max(0, params.outerHeight - getCombinedMax(maxPadding, chartArea, 'top', 'bottom'));\n const widthChanged = newWidth !== chartArea.w;\n const heightChanged = newHeight !== chartArea.h;\n chartArea.w = newWidth;\n chartArea.h = newHeight;\n return layout.horizontal ? {\n same: widthChanged,\n other: heightChanged\n } : {\n same: heightChanged,\n other: widthChanged\n };\n}\nfunction handleMaxPadding(chartArea) {\n const maxPadding = chartArea.maxPadding;\n function updatePos(pos) {\n const change = Math.max(maxPadding[pos] - chartArea[pos], 0);\n chartArea[pos] += change;\n return change;\n }\n chartArea.y += updatePos('top');\n chartArea.x += updatePos('left');\n updatePos('right');\n updatePos('bottom');\n}\nfunction getMargins(horizontal, chartArea) {\n const maxPadding = chartArea.maxPadding;\n function marginForPositions(positions) {\n const margin = {\n left: 0,\n top: 0,\n right: 0,\n bottom: 0\n };\n positions.forEach((pos)=>{\n margin[pos] = Math.max(chartArea[pos], maxPadding[pos]);\n });\n return margin;\n }\n return horizontal ? marginForPositions([\n 'left',\n 'right'\n ]) : marginForPositions([\n 'top',\n 'bottom'\n ]);\n}\nfunction fitBoxes(boxes, chartArea, params, stacks) {\n const refitBoxes = [];\n let i, ilen, layout, box, refit, changed;\n for(i = 0, ilen = boxes.length, refit = 0; i < ilen; ++i){\n layout = boxes[i];\n box = layout.box;\n box.update(layout.width || chartArea.w, layout.height || chartArea.h, getMargins(layout.horizontal, chartArea));\n const { same , other } = updateDims(chartArea, params, layout, stacks);\n refit |= same && refitBoxes.length;\n changed = changed || other;\n if (!box.fullSize) {\n refitBoxes.push(layout);\n }\n }\n return refit && fitBoxes(refitBoxes, chartArea, params, stacks) || changed;\n}\nfunction setBoxDims(box, left, top, width, height) {\n box.top = top;\n box.left = left;\n box.right = left + width;\n box.bottom = top + height;\n box.width = width;\n box.height = height;\n}\nfunction placeBoxes(boxes, chartArea, params, stacks) {\n const userPadding = params.padding;\n let { x , y } = chartArea;\n for (const layout of boxes){\n const box = layout.box;\n const stack = stacks[layout.stack] || {\n count: 1,\n placed: 0,\n weight: 1\n };\n const weight = layout.stackWeight / stack.weight || 1;\n if (layout.horizontal) {\n const width = chartArea.w * weight;\n const height = stack.size || box.height;\n if (defined(stack.start)) {\n y = stack.start;\n }\n if (box.fullSize) {\n setBoxDims(box, userPadding.left, y, params.outerWidth - userPadding.right - userPadding.left, height);\n } else {\n setBoxDims(box, chartArea.left + stack.placed, y, width, height);\n }\n stack.start = y;\n stack.placed += width;\n y = box.bottom;\n } else {\n const height = chartArea.h * weight;\n const width = stack.size || box.width;\n if (defined(stack.start)) {\n x = stack.start;\n }\n if (box.fullSize) {\n setBoxDims(box, x, userPadding.top, width, params.outerHeight - userPadding.bottom - userPadding.top);\n } else {\n setBoxDims(box, x, chartArea.top + stack.placed, width, height);\n }\n stack.start = x;\n stack.placed += height;\n x = box.right;\n }\n }\n chartArea.x = x;\n chartArea.y = y;\n}\nvar layouts = {\n addBox (chart, item) {\n if (!chart.boxes) {\n chart.boxes = [];\n }\n item.fullSize = item.fullSize || false;\n item.position = item.position || 'top';\n item.weight = item.weight || 0;\n item._layers = item._layers || function() {\n return [\n {\n z: 0,\n draw (chartArea) {\n item.draw(chartArea);\n }\n }\n ];\n };\n chart.boxes.push(item);\n },\n removeBox (chart, layoutItem) {\n const index = chart.boxes ? chart.boxes.indexOf(layoutItem) : -1;\n if (index !== -1) {\n chart.boxes.splice(index, 1);\n }\n },\n configure (chart, item, options) {\n item.fullSize = options.fullSize;\n item.position = options.position;\n item.weight = options.weight;\n },\n update (chart, width, height, minPadding) {\n if (!chart) {\n return;\n }\n const padding = toPadding(chart.options.layout.padding);\n const availableWidth = Math.max(width - padding.width, 0);\n const availableHeight = Math.max(height - padding.height, 0);\n const boxes = buildLayoutBoxes(chart.boxes);\n const verticalBoxes = boxes.vertical;\n const horizontalBoxes = boxes.horizontal;\n each(chart.boxes, (box)=>{\n if (typeof box.beforeLayout === 'function') {\n box.beforeLayout();\n }\n });\n const visibleVerticalBoxCount = verticalBoxes.reduce((total, wrap)=>wrap.box.options && wrap.box.options.display === false ? total : total + 1, 0) || 1;\n const params = Object.freeze({\n outerWidth: width,\n outerHeight: height,\n padding,\n availableWidth,\n availableHeight,\n vBoxMaxWidth: availableWidth / 2 / visibleVerticalBoxCount,\n hBoxMaxHeight: availableHeight / 2\n });\n const maxPadding = Object.assign({}, padding);\n updateMaxPadding(maxPadding, toPadding(minPadding));\n const chartArea = Object.assign({\n maxPadding,\n w: availableWidth,\n h: availableHeight,\n x: padding.left,\n y: padding.top\n }, padding);\n const stacks = setLayoutDims(verticalBoxes.concat(horizontalBoxes), params);\n fitBoxes(boxes.fullSize, chartArea, params, stacks);\n fitBoxes(verticalBoxes, chartArea, params, stacks);\n if (fitBoxes(horizontalBoxes, chartArea, params, stacks)) {\n fitBoxes(verticalBoxes, chartArea, params, stacks);\n }\n handleMaxPadding(chartArea);\n placeBoxes(boxes.leftAndTop, chartArea, params, stacks);\n chartArea.x += chartArea.w;\n chartArea.y += chartArea.h;\n placeBoxes(boxes.rightAndBottom, chartArea, params, stacks);\n chart.chartArea = {\n left: chartArea.left,\n top: chartArea.top,\n right: chartArea.left + chartArea.w,\n bottom: chartArea.top + chartArea.h,\n height: chartArea.h,\n width: chartArea.w\n };\n each(boxes.chartArea, (layout)=>{\n const box = layout.box;\n Object.assign(box, chart.chartArea);\n box.update(chartArea.w, chartArea.h, {\n left: 0,\n top: 0,\n right: 0,\n bottom: 0\n });\n });\n }\n};\n\nclass BasePlatform {\n acquireContext(canvas, aspectRatio) {}\n releaseContext(context) {\n return false;\n }\n addEventListener(chart, type, listener) {}\n removeEventListener(chart, type, listener) {}\n getDevicePixelRatio() {\n return 1;\n }\n getMaximumSize(element, width, height, aspectRatio) {\n width = Math.max(0, width || element.width);\n height = height || element.height;\n return {\n width,\n height: Math.max(0, aspectRatio ? Math.floor(width / aspectRatio) : height)\n };\n }\n isAttached(canvas) {\n return true;\n }\n updateConfig(config) {\n }\n}\n\nclass BasicPlatform extends BasePlatform {\n acquireContext(item) {\n return item && item.getContext && item.getContext('2d') || null;\n }\n updateConfig(config) {\n config.options.animation = false;\n }\n}\n\nconst EXPANDO_KEY = '$chartjs';\n const EVENT_TYPES = {\n touchstart: 'mousedown',\n touchmove: 'mousemove',\n touchend: 'mouseup',\n pointerenter: 'mouseenter',\n pointerdown: 'mousedown',\n pointermove: 'mousemove',\n pointerup: 'mouseup',\n pointerleave: 'mouseout',\n pointerout: 'mouseout'\n};\nconst isNullOrEmpty = (value)=>value === null || value === '';\n function initCanvas(canvas, aspectRatio) {\n const style = canvas.style;\n const renderHeight = canvas.getAttribute('height');\n const renderWidth = canvas.getAttribute('width');\n canvas[EXPANDO_KEY] = {\n initial: {\n height: renderHeight,\n width: renderWidth,\n style: {\n display: style.display,\n height: style.height,\n width: style.width\n }\n }\n };\n style.display = style.display || 'block';\n style.boxSizing = style.boxSizing || 'border-box';\n if (isNullOrEmpty(renderWidth)) {\n const displayWidth = readUsedSize(canvas, 'width');\n if (displayWidth !== undefined) {\n canvas.width = displayWidth;\n }\n }\n if (isNullOrEmpty(renderHeight)) {\n if (canvas.style.height === '') {\n canvas.height = canvas.width / (aspectRatio || 2);\n } else {\n const displayHeight = readUsedSize(canvas, 'height');\n if (displayHeight !== undefined) {\n canvas.height = displayHeight;\n }\n }\n }\n return canvas;\n}\nconst eventListenerOptions = supportsEventListenerOptions ? {\n passive: true\n} : false;\nfunction addListener(node, type, listener) {\n if (node) {\n node.addEventListener(type, listener, eventListenerOptions);\n }\n}\nfunction removeListener(chart, type, listener) {\n if (chart && chart.canvas) {\n chart.canvas.removeEventListener(type, listener, eventListenerOptions);\n }\n}\nfunction fromNativeEvent(event, chart) {\n const type = EVENT_TYPES[event.type] || event.type;\n const { x , y } = getRelativePosition(event, chart);\n return {\n type,\n chart,\n native: event,\n x: x !== undefined ? x : null,\n y: y !== undefined ? y : null\n };\n}\nfunction nodeListContains(nodeList, canvas) {\n for (const node of nodeList){\n if (node === canvas || node.contains(canvas)) {\n return true;\n }\n }\n}\nfunction createAttachObserver(chart, type, listener) {\n const canvas = chart.canvas;\n const observer = new MutationObserver((entries)=>{\n let trigger = false;\n for (const entry of entries){\n trigger = trigger || nodeListContains(entry.addedNodes, canvas);\n trigger = trigger && !nodeListContains(entry.removedNodes, canvas);\n }\n if (trigger) {\n listener();\n }\n });\n observer.observe(document, {\n childList: true,\n subtree: true\n });\n return observer;\n}\nfunction createDetachObserver(chart, type, listener) {\n const canvas = chart.canvas;\n const observer = new MutationObserver((entries)=>{\n let trigger = false;\n for (const entry of entries){\n trigger = trigger || nodeListContains(entry.removedNodes, canvas);\n trigger = trigger && !nodeListContains(entry.addedNodes, canvas);\n }\n if (trigger) {\n listener();\n }\n });\n observer.observe(document, {\n childList: true,\n subtree: true\n });\n return observer;\n}\nconst drpListeningCharts = new Map();\nlet oldDevicePixelRatio = 0;\nfunction onWindowResize() {\n const dpr = window.devicePixelRatio;\n if (dpr === oldDevicePixelRatio) {\n return;\n }\n oldDevicePixelRatio = dpr;\n drpListeningCharts.forEach((resize, chart)=>{\n if (chart.currentDevicePixelRatio !== dpr) {\n resize();\n }\n });\n}\nfunction listenDevicePixelRatioChanges(chart, resize) {\n if (!drpListeningCharts.size) {\n window.addEventListener('resize', onWindowResize);\n }\n drpListeningCharts.set(chart, resize);\n}\nfunction unlistenDevicePixelRatioChanges(chart) {\n drpListeningCharts.delete(chart);\n if (!drpListeningCharts.size) {\n window.removeEventListener('resize', onWindowResize);\n }\n}\nfunction createResizeObserver(chart, type, listener) {\n const canvas = chart.canvas;\n const container = canvas && _getParentNode(canvas);\n if (!container) {\n return;\n }\n const resize = throttled((width, height)=>{\n const w = container.clientWidth;\n listener(width, height);\n if (w < container.clientWidth) {\n listener();\n }\n }, window);\n const observer = new ResizeObserver((entries)=>{\n const entry = entries[0];\n const width = entry.contentRect.width;\n const height = entry.contentRect.height;\n if (width === 0 && height === 0) {\n return;\n }\n resize(width, height);\n });\n observer.observe(container);\n listenDevicePixelRatioChanges(chart, resize);\n return observer;\n}\nfunction releaseObserver(chart, type, observer) {\n if (observer) {\n observer.disconnect();\n }\n if (type === 'resize') {\n unlistenDevicePixelRatioChanges(chart);\n }\n}\nfunction createProxyAndListen(chart, type, listener) {\n const canvas = chart.canvas;\n const proxy = throttled((event)=>{\n if (chart.ctx !== null) {\n listener(fromNativeEvent(event, chart));\n }\n }, chart);\n addListener(canvas, type, proxy);\n return proxy;\n}\n class DomPlatform extends BasePlatform {\n acquireContext(canvas, aspectRatio) {\n const context = canvas && canvas.getContext && canvas.getContext('2d');\n if (context && context.canvas === canvas) {\n initCanvas(canvas, aspectRatio);\n return context;\n }\n return null;\n }\n releaseContext(context) {\n const canvas = context.canvas;\n if (!canvas[EXPANDO_KEY]) {\n return false;\n }\n const initial = canvas[EXPANDO_KEY].initial;\n [\n 'height',\n 'width'\n ].forEach((prop)=>{\n const value = initial[prop];\n if (isNullOrUndef(value)) {\n canvas.removeAttribute(prop);\n } else {\n canvas.setAttribute(prop, value);\n }\n });\n const style = initial.style || {};\n Object.keys(style).forEach((key)=>{\n canvas.style[key] = style[key];\n });\n canvas.width = canvas.width;\n delete canvas[EXPANDO_KEY];\n return true;\n }\n addEventListener(chart, type, listener) {\n this.removeEventListener(chart, type);\n const proxies = chart.$proxies || (chart.$proxies = {});\n const handlers = {\n attach: createAttachObserver,\n detach: createDetachObserver,\n resize: createResizeObserver\n };\n const handler = handlers[type] || createProxyAndListen;\n proxies[type] = handler(chart, type, listener);\n }\n removeEventListener(chart, type) {\n const proxies = chart.$proxies || (chart.$proxies = {});\n const proxy = proxies[type];\n if (!proxy) {\n return;\n }\n const handlers = {\n attach: releaseObserver,\n detach: releaseObserver,\n resize: releaseObserver\n };\n const handler = handlers[type] || removeListener;\n handler(chart, type, proxy);\n proxies[type] = undefined;\n }\n getDevicePixelRatio() {\n return window.devicePixelRatio;\n }\n getMaximumSize(canvas, width, height, aspectRatio) {\n return getMaximumSize(canvas, width, height, aspectRatio);\n }\n isAttached(canvas) {\n const container = canvas && _getParentNode(canvas);\n return !!(container && container.isConnected);\n }\n}\n\nfunction _detectPlatform(canvas) {\n if (!_isDomSupported() || typeof OffscreenCanvas !== 'undefined' && canvas instanceof OffscreenCanvas) {\n return BasicPlatform;\n }\n return DomPlatform;\n}\n\nclass Element {\n static defaults = {};\n static defaultRoutes = undefined;\n x;\n y;\n active = false;\n options;\n $animations;\n tooltipPosition(useFinalPosition) {\n const { x , y } = this.getProps([\n 'x',\n 'y'\n ], useFinalPosition);\n return {\n x,\n y\n };\n }\n hasValue() {\n return isNumber(this.x) && isNumber(this.y);\n }\n getProps(props, final) {\n const anims = this.$animations;\n if (!final || !anims) {\n // let's not create an object, if not needed\n return this;\n }\n const ret = {};\n props.forEach((prop)=>{\n ret[prop] = anims[prop] && anims[prop].active() ? anims[prop]._to : this[prop];\n });\n return ret;\n }\n}\n\nfunction autoSkip(scale, ticks) {\n const tickOpts = scale.options.ticks;\n const determinedMaxTicks = determineMaxTicks(scale);\n const ticksLimit = Math.min(tickOpts.maxTicksLimit || determinedMaxTicks, determinedMaxTicks);\n const majorIndices = tickOpts.major.enabled ? getMajorIndices(ticks) : [];\n const numMajorIndices = majorIndices.length;\n const first = majorIndices[0];\n const last = majorIndices[numMajorIndices - 1];\n const newTicks = [];\n if (numMajorIndices > ticksLimit) {\n skipMajors(ticks, newTicks, majorIndices, numMajorIndices / ticksLimit);\n return newTicks;\n }\n const spacing = calculateSpacing(majorIndices, ticks, ticksLimit);\n if (numMajorIndices > 0) {\n let i, ilen;\n const avgMajorSpacing = numMajorIndices > 1 ? Math.round((last - first) / (numMajorIndices - 1)) : null;\n skip(ticks, newTicks, spacing, isNullOrUndef(avgMajorSpacing) ? 0 : first - avgMajorSpacing, first);\n for(i = 0, ilen = numMajorIndices - 1; i < ilen; i++){\n skip(ticks, newTicks, spacing, majorIndices[i], majorIndices[i + 1]);\n }\n skip(ticks, newTicks, spacing, last, isNullOrUndef(avgMajorSpacing) ? ticks.length : last + avgMajorSpacing);\n return newTicks;\n }\n skip(ticks, newTicks, spacing);\n return newTicks;\n}\nfunction determineMaxTicks(scale) {\n const offset = scale.options.offset;\n const tickLength = scale._tickSize();\n const maxScale = scale._length / tickLength + (offset ? 0 : 1);\n const maxChart = scale._maxLength / tickLength;\n return Math.floor(Math.min(maxScale, maxChart));\n}\n function calculateSpacing(majorIndices, ticks, ticksLimit) {\n const evenMajorSpacing = getEvenSpacing(majorIndices);\n const spacing = ticks.length / ticksLimit;\n if (!evenMajorSpacing) {\n return Math.max(spacing, 1);\n }\n const factors = _factorize(evenMajorSpacing);\n for(let i = 0, ilen = factors.length - 1; i < ilen; i++){\n const factor = factors[i];\n if (factor > spacing) {\n return factor;\n }\n }\n return Math.max(spacing, 1);\n}\n function getMajorIndices(ticks) {\n const result = [];\n let i, ilen;\n for(i = 0, ilen = ticks.length; i < ilen; i++){\n if (ticks[i].major) {\n result.push(i);\n }\n }\n return result;\n}\n function skipMajors(ticks, newTicks, majorIndices, spacing) {\n let count = 0;\n let next = majorIndices[0];\n let i;\n spacing = Math.ceil(spacing);\n for(i = 0; i < ticks.length; i++){\n if (i === next) {\n newTicks.push(ticks[i]);\n count++;\n next = majorIndices[count * spacing];\n }\n }\n}\n function skip(ticks, newTicks, spacing, majorStart, majorEnd) {\n const start = valueOrDefault(majorStart, 0);\n const end = Math.min(valueOrDefault(majorEnd, ticks.length), ticks.length);\n let count = 0;\n let length, i, next;\n spacing = Math.ceil(spacing);\n if (majorEnd) {\n length = majorEnd - majorStart;\n spacing = length / Math.floor(length / spacing);\n }\n next = start;\n while(next < 0){\n count++;\n next = Math.round(start + count * spacing);\n }\n for(i = Math.max(start, 0); i < end; i++){\n if (i === next) {\n newTicks.push(ticks[i]);\n count++;\n next = Math.round(start + count * spacing);\n }\n }\n}\n function getEvenSpacing(arr) {\n const len = arr.length;\n let i, diff;\n if (len < 2) {\n return false;\n }\n for(diff = arr[0], i = 1; i < len; ++i){\n if (arr[i] - arr[i - 1] !== diff) {\n return false;\n }\n }\n return diff;\n}\n\nconst reverseAlign = (align)=>align === 'left' ? 'right' : align === 'right' ? 'left' : align;\nconst offsetFromEdge = (scale, edge, offset)=>edge === 'top' || edge === 'left' ? scale[edge] + offset : scale[edge] - offset;\nconst getTicksLimit = (ticksLength, maxTicksLimit)=>Math.min(maxTicksLimit || ticksLength, ticksLength);\n function sample(arr, numItems) {\n const result = [];\n const increment = arr.length / numItems;\n const len = arr.length;\n let i = 0;\n for(; i < len; i += increment){\n result.push(arr[Math.floor(i)]);\n }\n return result;\n}\n function getPixelForGridLine(scale, index, offsetGridLines) {\n const length = scale.ticks.length;\n const validIndex = Math.min(index, length - 1);\n const start = scale._startPixel;\n const end = scale._endPixel;\n const epsilon = 1e-6;\n let lineValue = scale.getPixelForTick(validIndex);\n let offset;\n if (offsetGridLines) {\n if (length === 1) {\n offset = Math.max(lineValue - start, end - lineValue);\n } else if (index === 0) {\n offset = (scale.getPixelForTick(1) - lineValue) / 2;\n } else {\n offset = (lineValue - scale.getPixelForTick(validIndex - 1)) / 2;\n }\n lineValue += validIndex < index ? offset : -offset;\n if (lineValue < start - epsilon || lineValue > end + epsilon) {\n return;\n }\n }\n return lineValue;\n}\n function garbageCollect(caches, length) {\n each(caches, (cache)=>{\n const gc = cache.gc;\n const gcLen = gc.length / 2;\n let i;\n if (gcLen > length) {\n for(i = 0; i < gcLen; ++i){\n delete cache.data[gc[i]];\n }\n gc.splice(0, gcLen);\n }\n });\n}\n function getTickMarkLength(options) {\n return options.drawTicks ? options.tickLength : 0;\n}\n function getTitleHeight(options, fallback) {\n if (!options.display) {\n return 0;\n }\n const font = toFont(options.font, fallback);\n const padding = toPadding(options.padding);\n const lines = isArray(options.text) ? options.text.length : 1;\n return lines * font.lineHeight + padding.height;\n}\nfunction createScaleContext(parent, scale) {\n return createContext(parent, {\n scale,\n type: 'scale'\n });\n}\nfunction createTickContext(parent, index, tick) {\n return createContext(parent, {\n tick,\n index,\n type: 'tick'\n });\n}\nfunction titleAlign(align, position, reverse) {\n let ret = _toLeftRightCenter(align);\n if (reverse && position !== 'right' || !reverse && position === 'right') {\n ret = reverseAlign(ret);\n }\n return ret;\n}\nfunction titleArgs(scale, offset, position, align) {\n const { top , left , bottom , right , chart } = scale;\n const { chartArea , scales } = chart;\n let rotation = 0;\n let maxWidth, titleX, titleY;\n const height = bottom - top;\n const width = right - left;\n if (scale.isHorizontal()) {\n titleX = _alignStartEnd(align, left, right);\n if (isObject(position)) {\n const positionAxisID = Object.keys(position)[0];\n const value = position[positionAxisID];\n titleY = scales[positionAxisID].getPixelForValue(value) + height - offset;\n } else if (position === 'center') {\n titleY = (chartArea.bottom + chartArea.top) / 2 + height - offset;\n } else {\n titleY = offsetFromEdge(scale, position, offset);\n }\n maxWidth = right - left;\n } else {\n if (isObject(position)) {\n const positionAxisID = Object.keys(position)[0];\n const value = position[positionAxisID];\n titleX = scales[positionAxisID].getPixelForValue(value) - width + offset;\n } else if (position === 'center') {\n titleX = (chartArea.left + chartArea.right) / 2 - width + offset;\n } else {\n titleX = offsetFromEdge(scale, position, offset);\n }\n titleY = _alignStartEnd(align, bottom, top);\n rotation = position === 'left' ? -HALF_PI : HALF_PI;\n }\n return {\n titleX,\n titleY,\n maxWidth,\n rotation\n };\n}\nclass Scale extends Element {\n constructor(cfg){\n super();\n this.id = cfg.id;\n this.type = cfg.type;\n this.options = undefined;\n this.ctx = cfg.ctx;\n this.chart = cfg.chart;\n this.top = undefined;\n this.bottom = undefined;\n this.left = undefined;\n this.right = undefined;\n this.width = undefined;\n this.height = undefined;\n this._margins = {\n left: 0,\n right: 0,\n top: 0,\n bottom: 0\n };\n this.maxWidth = undefined;\n this.maxHeight = undefined;\n this.paddingTop = undefined;\n this.paddingBottom = undefined;\n this.paddingLeft = undefined;\n this.paddingRight = undefined;\n this.axis = undefined;\n this.labelRotation = undefined;\n this.min = undefined;\n this.max = undefined;\n this._range = undefined;\n this.ticks = [];\n this._gridLineItems = null;\n this._labelItems = null;\n this._labelSizes = null;\n this._length = 0;\n this._maxLength = 0;\n this._longestTextCache = {};\n this._startPixel = undefined;\n this._endPixel = undefined;\n this._reversePixels = false;\n this._userMax = undefined;\n this._userMin = undefined;\n this._suggestedMax = undefined;\n this._suggestedMin = undefined;\n this._ticksLength = 0;\n this._borderValue = 0;\n this._cache = {};\n this._dataLimitsCached = false;\n this.$context = undefined;\n }\n init(options) {\n this.options = options.setContext(this.getContext());\n this.axis = options.axis;\n this._userMin = this.parse(options.min);\n this._userMax = this.parse(options.max);\n this._suggestedMin = this.parse(options.suggestedMin);\n this._suggestedMax = this.parse(options.suggestedMax);\n }\n parse(raw, index) {\n return raw;\n }\n getUserBounds() {\n let { _userMin , _userMax , _suggestedMin , _suggestedMax } = this;\n _userMin = finiteOrDefault(_userMin, Number.POSITIVE_INFINITY);\n _userMax = finiteOrDefault(_userMax, Number.NEGATIVE_INFINITY);\n _suggestedMin = finiteOrDefault(_suggestedMin, Number.POSITIVE_INFINITY);\n _suggestedMax = finiteOrDefault(_suggestedMax, Number.NEGATIVE_INFINITY);\n return {\n min: finiteOrDefault(_userMin, _suggestedMin),\n max: finiteOrDefault(_userMax, _suggestedMax),\n minDefined: isNumberFinite(_userMin),\n maxDefined: isNumberFinite(_userMax)\n };\n }\n getMinMax(canStack) {\n let { min , max , minDefined , maxDefined } = this.getUserBounds();\n let range;\n if (minDefined && maxDefined) {\n return {\n min,\n max\n };\n }\n const metas = this.getMatchingVisibleMetas();\n for(let i = 0, ilen = metas.length; i < ilen; ++i){\n range = metas[i].controller.getMinMax(this, canStack);\n if (!minDefined) {\n min = Math.min(min, range.min);\n }\n if (!maxDefined) {\n max = Math.max(max, range.max);\n }\n }\n min = maxDefined && min > max ? max : min;\n max = minDefined && min > max ? min : max;\n return {\n min: finiteOrDefault(min, finiteOrDefault(max, min)),\n max: finiteOrDefault(max, finiteOrDefault(min, max))\n };\n }\n getPadding() {\n return {\n left: this.paddingLeft || 0,\n top: this.paddingTop || 0,\n right: this.paddingRight || 0,\n bottom: this.paddingBottom || 0\n };\n }\n getTicks() {\n return this.ticks;\n }\n getLabels() {\n const data = this.chart.data;\n return this.options.labels || (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels || [];\n }\n getLabelItems(chartArea = this.chart.chartArea) {\n const items = this._labelItems || (this._labelItems = this._computeLabelItems(chartArea));\n return items;\n }\n beforeLayout() {\n this._cache = {};\n this._dataLimitsCached = false;\n }\n beforeUpdate() {\n callback(this.options.beforeUpdate, [\n this\n ]);\n }\n update(maxWidth, maxHeight, margins) {\n const { beginAtZero , grace , ticks: tickOpts } = this.options;\n const sampleSize = tickOpts.sampleSize;\n this.beforeUpdate();\n this.maxWidth = maxWidth;\n this.maxHeight = maxHeight;\n this._margins = margins = Object.assign({\n left: 0,\n right: 0,\n top: 0,\n bottom: 0\n }, margins);\n this.ticks = null;\n this._labelSizes = null;\n this._gridLineItems = null;\n this._labelItems = null;\n this.beforeSetDimensions();\n this.setDimensions();\n this.afterSetDimensions();\n this._maxLength = this.isHorizontal() ? this.width + margins.left + margins.right : this.height + margins.top + margins.bottom;\n if (!this._dataLimitsCached) {\n this.beforeDataLimits();\n this.determineDataLimits();\n this.afterDataLimits();\n this._range = _addGrace(this, grace, beginAtZero);\n this._dataLimitsCached = true;\n }\n this.beforeBuildTicks();\n this.ticks = this.buildTicks() || [];\n this.afterBuildTicks();\n const samplingEnabled = sampleSize < this.ticks.length;\n this._convertTicksToLabels(samplingEnabled ? sample(this.ticks, sampleSize) : this.ticks);\n this.configure();\n this.beforeCalculateLabelRotation();\n this.calculateLabelRotation();\n this.afterCalculateLabelRotation();\n if (tickOpts.display && (tickOpts.autoSkip || tickOpts.source === 'auto')) {\n this.ticks = autoSkip(this, this.ticks);\n this._labelSizes = null;\n this.afterAutoSkip();\n }\n if (samplingEnabled) {\n this._convertTicksToLabels(this.ticks);\n }\n this.beforeFit();\n this.fit();\n this.afterFit();\n this.afterUpdate();\n }\n configure() {\n let reversePixels = this.options.reverse;\n let startPixel, endPixel;\n if (this.isHorizontal()) {\n startPixel = this.left;\n endPixel = this.right;\n } else {\n startPixel = this.top;\n endPixel = this.bottom;\n reversePixels = !reversePixels;\n }\n this._startPixel = startPixel;\n this._endPixel = endPixel;\n this._reversePixels = reversePixels;\n this._length = endPixel - startPixel;\n this._alignToPixels = this.options.alignToPixels;\n }\n afterUpdate() {\n callback(this.options.afterUpdate, [\n this\n ]);\n }\n beforeSetDimensions() {\n callback(this.options.beforeSetDimensions, [\n this\n ]);\n }\n setDimensions() {\n if (this.isHorizontal()) {\n this.width = this.maxWidth;\n this.left = 0;\n this.right = this.width;\n } else {\n this.height = this.maxHeight;\n this.top = 0;\n this.bottom = this.height;\n }\n this.paddingLeft = 0;\n this.paddingTop = 0;\n this.paddingRight = 0;\n this.paddingBottom = 0;\n }\n afterSetDimensions() {\n callback(this.options.afterSetDimensions, [\n this\n ]);\n }\n _callHooks(name) {\n this.chart.notifyPlugins(name, this.getContext());\n callback(this.options[name], [\n this\n ]);\n }\n beforeDataLimits() {\n this._callHooks('beforeDataLimits');\n }\n determineDataLimits() {}\n afterDataLimits() {\n this._callHooks('afterDataLimits');\n }\n beforeBuildTicks() {\n this._callHooks('beforeBuildTicks');\n }\n buildTicks() {\n return [];\n }\n afterBuildTicks() {\n this._callHooks('afterBuildTicks');\n }\n beforeTickToLabelConversion() {\n callback(this.options.beforeTickToLabelConversion, [\n this\n ]);\n }\n generateTickLabels(ticks) {\n const tickOpts = this.options.ticks;\n let i, ilen, tick;\n for(i = 0, ilen = ticks.length; i < ilen; i++){\n tick = ticks[i];\n tick.label = callback(tickOpts.callback, [\n tick.value,\n i,\n ticks\n ], this);\n }\n }\n afterTickToLabelConversion() {\n callback(this.options.afterTickToLabelConversion, [\n this\n ]);\n }\n beforeCalculateLabelRotation() {\n callback(this.options.beforeCalculateLabelRotation, [\n this\n ]);\n }\n calculateLabelRotation() {\n const options = this.options;\n const tickOpts = options.ticks;\n const numTicks = getTicksLimit(this.ticks.length, options.ticks.maxTicksLimit);\n const minRotation = tickOpts.minRotation || 0;\n const maxRotation = tickOpts.maxRotation;\n let labelRotation = minRotation;\n let tickWidth, maxHeight, maxLabelDiagonal;\n if (!this._isVisible() || !tickOpts.display || minRotation >= maxRotation || numTicks <= 1 || !this.isHorizontal()) {\n this.labelRotation = minRotation;\n return;\n }\n const labelSizes = this._getLabelSizes();\n const maxLabelWidth = labelSizes.widest.width;\n const maxLabelHeight = labelSizes.highest.height;\n const maxWidth = _limitValue(this.chart.width - maxLabelWidth, 0, this.maxWidth);\n tickWidth = options.offset ? this.maxWidth / numTicks : maxWidth / (numTicks - 1);\n if (maxLabelWidth + 6 > tickWidth) {\n tickWidth = maxWidth / (numTicks - (options.offset ? 0.5 : 1));\n maxHeight = this.maxHeight - getTickMarkLength(options.grid) - tickOpts.padding - getTitleHeight(options.title, this.chart.options.font);\n maxLabelDiagonal = Math.sqrt(maxLabelWidth * maxLabelWidth + maxLabelHeight * maxLabelHeight);\n labelRotation = toDegrees(Math.min(Math.asin(_limitValue((labelSizes.highest.height + 6) / tickWidth, -1, 1)), Math.asin(_limitValue(maxHeight / maxLabelDiagonal, -1, 1)) - Math.asin(_limitValue(maxLabelHeight / maxLabelDiagonal, -1, 1))));\n labelRotation = Math.max(minRotation, Math.min(maxRotation, labelRotation));\n }\n this.labelRotation = labelRotation;\n }\n afterCalculateLabelRotation() {\n callback(this.options.afterCalculateLabelRotation, [\n this\n ]);\n }\n afterAutoSkip() {}\n beforeFit() {\n callback(this.options.beforeFit, [\n this\n ]);\n }\n fit() {\n const minSize = {\n width: 0,\n height: 0\n };\n const { chart , options: { ticks: tickOpts , title: titleOpts , grid: gridOpts } } = this;\n const display = this._isVisible();\n const isHorizontal = this.isHorizontal();\n if (display) {\n const titleHeight = getTitleHeight(titleOpts, chart.options.font);\n if (isHorizontal) {\n minSize.width = this.maxWidth;\n minSize.height = getTickMarkLength(gridOpts) + titleHeight;\n } else {\n minSize.height = this.maxHeight;\n minSize.width = getTickMarkLength(gridOpts) + titleHeight;\n }\n if (tickOpts.display && this.ticks.length) {\n const { first , last , widest , highest } = this._getLabelSizes();\n const tickPadding = tickOpts.padding * 2;\n const angleRadians = toRadians(this.labelRotation);\n const cos = Math.cos(angleRadians);\n const sin = Math.sin(angleRadians);\n if (isHorizontal) {\n const labelHeight = tickOpts.mirror ? 0 : sin * widest.width + cos * highest.height;\n minSize.height = Math.min(this.maxHeight, minSize.height + labelHeight + tickPadding);\n } else {\n const labelWidth = tickOpts.mirror ? 0 : cos * widest.width + sin * highest.height;\n minSize.width = Math.min(this.maxWidth, minSize.width + labelWidth + tickPadding);\n }\n this._calculatePadding(first, last, sin, cos);\n }\n }\n this._handleMargins();\n if (isHorizontal) {\n this.width = this._length = chart.width - this._margins.left - this._margins.right;\n this.height = minSize.height;\n } else {\n this.width = minSize.width;\n this.height = this._length = chart.height - this._margins.top - this._margins.bottom;\n }\n }\n _calculatePadding(first, last, sin, cos) {\n const { ticks: { align , padding } , position } = this.options;\n const isRotated = this.labelRotation !== 0;\n const labelsBelowTicks = position !== 'top' && this.axis === 'x';\n if (this.isHorizontal()) {\n const offsetLeft = this.getPixelForTick(0) - this.left;\n const offsetRight = this.right - this.getPixelForTick(this.ticks.length - 1);\n let paddingLeft = 0;\n let paddingRight = 0;\n if (isRotated) {\n if (labelsBelowTicks) {\n paddingLeft = cos * first.width;\n paddingRight = sin * last.height;\n } else {\n paddingLeft = sin * first.height;\n paddingRight = cos * last.width;\n }\n } else if (align === 'start') {\n paddingRight = last.width;\n } else if (align === 'end') {\n paddingLeft = first.width;\n } else if (align !== 'inner') {\n paddingLeft = first.width / 2;\n paddingRight = last.width / 2;\n }\n this.paddingLeft = Math.max((paddingLeft - offsetLeft + padding) * this.width / (this.width - offsetLeft), 0);\n this.paddingRight = Math.max((paddingRight - offsetRight + padding) * this.width / (this.width - offsetRight), 0);\n } else {\n let paddingTop = last.height / 2;\n let paddingBottom = first.height / 2;\n if (align === 'start') {\n paddingTop = 0;\n paddingBottom = first.height;\n } else if (align === 'end') {\n paddingTop = last.height;\n paddingBottom = 0;\n }\n this.paddingTop = paddingTop + padding;\n this.paddingBottom = paddingBottom + padding;\n }\n }\n _handleMargins() {\n if (this._margins) {\n this._margins.left = Math.max(this.paddingLeft, this._margins.left);\n this._margins.top = Math.max(this.paddingTop, this._margins.top);\n this._margins.right = Math.max(this.paddingRight, this._margins.right);\n this._margins.bottom = Math.max(this.paddingBottom, this._margins.bottom);\n }\n }\n afterFit() {\n callback(this.options.afterFit, [\n this\n ]);\n }\n isHorizontal() {\n const { axis , position } = this.options;\n return position === 'top' || position === 'bottom' || axis === 'x';\n }\n isFullSize() {\n return this.options.fullSize;\n }\n _convertTicksToLabels(ticks) {\n this.beforeTickToLabelConversion();\n this.generateTickLabels(ticks);\n let i, ilen;\n for(i = 0, ilen = ticks.length; i < ilen; i++){\n if (isNullOrUndef(ticks[i].label)) {\n ticks.splice(i, 1);\n ilen--;\n i--;\n }\n }\n this.afterTickToLabelConversion();\n }\n _getLabelSizes() {\n let labelSizes = this._labelSizes;\n if (!labelSizes) {\n const sampleSize = this.options.ticks.sampleSize;\n let ticks = this.ticks;\n if (sampleSize < ticks.length) {\n ticks = sample(ticks, sampleSize);\n }\n this._labelSizes = labelSizes = this._computeLabelSizes(ticks, ticks.length, this.options.ticks.maxTicksLimit);\n }\n return labelSizes;\n }\n _computeLabelSizes(ticks, length, maxTicksLimit) {\n const { ctx , _longestTextCache: caches } = this;\n const widths = [];\n const heights = [];\n const increment = Math.floor(length / getTicksLimit(length, maxTicksLimit));\n let widestLabelSize = 0;\n let highestLabelSize = 0;\n let i, j, jlen, label, tickFont, fontString, cache, lineHeight, width, height, nestedLabel;\n for(i = 0; i < length; i += increment){\n label = ticks[i].label;\n tickFont = this._resolveTickFontOptions(i);\n ctx.font = fontString = tickFont.string;\n cache = caches[fontString] = caches[fontString] || {\n data: {},\n gc: []\n };\n lineHeight = tickFont.lineHeight;\n width = height = 0;\n if (!isNullOrUndef(label) && !isArray(label)) {\n width = _measureText(ctx, cache.data, cache.gc, width, label);\n height = lineHeight;\n } else if (isArray(label)) {\n for(j = 0, jlen = label.length; j < jlen; ++j){\n nestedLabel = label[j];\n if (!isNullOrUndef(nestedLabel) && !isArray(nestedLabel)) {\n width = _measureText(ctx, cache.data, cache.gc, width, nestedLabel);\n height += lineHeight;\n }\n }\n }\n widths.push(width);\n heights.push(height);\n widestLabelSize = Math.max(width, widestLabelSize);\n highestLabelSize = Math.max(height, highestLabelSize);\n }\n garbageCollect(caches, length);\n const widest = widths.indexOf(widestLabelSize);\n const highest = heights.indexOf(highestLabelSize);\n const valueAt = (idx)=>({\n width: widths[idx] || 0,\n height: heights[idx] || 0\n });\n return {\n first: valueAt(0),\n last: valueAt(length - 1),\n widest: valueAt(widest),\n highest: valueAt(highest),\n widths,\n heights\n };\n }\n getLabelForValue(value) {\n return value;\n }\n getPixelForValue(value, index) {\n return NaN;\n }\n getValueForPixel(pixel) {}\n getPixelForTick(index) {\n const ticks = this.ticks;\n if (index < 0 || index > ticks.length - 1) {\n return null;\n }\n return this.getPixelForValue(ticks[index].value);\n }\n getPixelForDecimal(decimal) {\n if (this._reversePixels) {\n decimal = 1 - decimal;\n }\n const pixel = this._startPixel + decimal * this._length;\n return _int16Range(this._alignToPixels ? _alignPixel(this.chart, pixel, 0) : pixel);\n }\n getDecimalForPixel(pixel) {\n const decimal = (pixel - this._startPixel) / this._length;\n return this._reversePixels ? 1 - decimal : decimal;\n }\n getBasePixel() {\n return this.getPixelForValue(this.getBaseValue());\n }\n getBaseValue() {\n const { min , max } = this;\n return min < 0 && max < 0 ? max : min > 0 && max > 0 ? min : 0;\n }\n getContext(index) {\n const ticks = this.ticks || [];\n if (index >= 0 && index < ticks.length) {\n const tick = ticks[index];\n return tick.$context || (tick.$context = createTickContext(this.getContext(), index, tick));\n }\n return this.$context || (this.$context = createScaleContext(this.chart.getContext(), this));\n }\n _tickSize() {\n const optionTicks = this.options.ticks;\n const rot = toRadians(this.labelRotation);\n const cos = Math.abs(Math.cos(rot));\n const sin = Math.abs(Math.sin(rot));\n const labelSizes = this._getLabelSizes();\n const padding = optionTicks.autoSkipPadding || 0;\n const w = labelSizes ? labelSizes.widest.width + padding : 0;\n const h = labelSizes ? labelSizes.highest.height + padding : 0;\n return this.isHorizontal() ? h * cos > w * sin ? w / cos : h / sin : h * sin < w * cos ? h / cos : w / sin;\n }\n _isVisible() {\n const display = this.options.display;\n if (display !== 'auto') {\n return !!display;\n }\n return this.getMatchingVisibleMetas().length > 0;\n }\n _computeGridLineItems(chartArea) {\n const axis = this.axis;\n const chart = this.chart;\n const options = this.options;\n const { grid , position , border } = options;\n const offset = grid.offset;\n const isHorizontal = this.isHorizontal();\n const ticks = this.ticks;\n const ticksLength = ticks.length + (offset ? 1 : 0);\n const tl = getTickMarkLength(grid);\n const items = [];\n const borderOpts = border.setContext(this.getContext());\n const axisWidth = borderOpts.display ? borderOpts.width : 0;\n const axisHalfWidth = axisWidth / 2;\n const alignBorderValue = function(pixel) {\n return _alignPixel(chart, pixel, axisWidth);\n };\n let borderValue, i, lineValue, alignedLineValue;\n let tx1, ty1, tx2, ty2, x1, y1, x2, y2;\n if (position === 'top') {\n borderValue = alignBorderValue(this.bottom);\n ty1 = this.bottom - tl;\n ty2 = borderValue - axisHalfWidth;\n y1 = alignBorderValue(chartArea.top) + axisHalfWidth;\n y2 = chartArea.bottom;\n } else if (position === 'bottom') {\n borderValue = alignBorderValue(this.top);\n y1 = chartArea.top;\n y2 = alignBorderValue(chartArea.bottom) - axisHalfWidth;\n ty1 = borderValue + axisHalfWidth;\n ty2 = this.top + tl;\n } else if (position === 'left') {\n borderValue = alignBorderValue(this.right);\n tx1 = this.right - tl;\n tx2 = borderValue - axisHalfWidth;\n x1 = alignBorderValue(chartArea.left) + axisHalfWidth;\n x2 = chartArea.right;\n } else if (position === 'right') {\n borderValue = alignBorderValue(this.left);\n x1 = chartArea.left;\n x2 = alignBorderValue(chartArea.right) - axisHalfWidth;\n tx1 = borderValue + axisHalfWidth;\n tx2 = this.left + tl;\n } else if (axis === 'x') {\n if (position === 'center') {\n borderValue = alignBorderValue((chartArea.top + chartArea.bottom) / 2 + 0.5);\n } else if (isObject(position)) {\n const positionAxisID = Object.keys(position)[0];\n const value = position[positionAxisID];\n borderValue = alignBorderValue(this.chart.scales[positionAxisID].getPixelForValue(value));\n }\n y1 = chartArea.top;\n y2 = chartArea.bottom;\n ty1 = borderValue + axisHalfWidth;\n ty2 = ty1 + tl;\n } else if (axis === 'y') {\n if (position === 'center') {\n borderValue = alignBorderValue((chartArea.left + chartArea.right) / 2);\n } else if (isObject(position)) {\n const positionAxisID = Object.keys(position)[0];\n const value = position[positionAxisID];\n borderValue = alignBorderValue(this.chart.scales[positionAxisID].getPixelForValue(value));\n }\n tx1 = borderValue - axisHalfWidth;\n tx2 = tx1 - tl;\n x1 = chartArea.left;\n x2 = chartArea.right;\n }\n const limit = valueOrDefault(options.ticks.maxTicksLimit, ticksLength);\n const step = Math.max(1, Math.ceil(ticksLength / limit));\n for(i = 0; i < ticksLength; i += step){\n const context = this.getContext(i);\n const optsAtIndex = grid.setContext(context);\n const optsAtIndexBorder = border.setContext(context);\n const lineWidth = optsAtIndex.lineWidth;\n const lineColor = optsAtIndex.color;\n const borderDash = optsAtIndexBorder.dash || [];\n const borderDashOffset = optsAtIndexBorder.dashOffset;\n const tickWidth = optsAtIndex.tickWidth;\n const tickColor = optsAtIndex.tickColor;\n const tickBorderDash = optsAtIndex.tickBorderDash || [];\n const tickBorderDashOffset = optsAtIndex.tickBorderDashOffset;\n lineValue = getPixelForGridLine(this, i, offset);\n if (lineValue === undefined) {\n continue;\n }\n alignedLineValue = _alignPixel(chart, lineValue, lineWidth);\n if (isHorizontal) {\n tx1 = tx2 = x1 = x2 = alignedLineValue;\n } else {\n ty1 = ty2 = y1 = y2 = alignedLineValue;\n }\n items.push({\n tx1,\n ty1,\n tx2,\n ty2,\n x1,\n y1,\n x2,\n y2,\n width: lineWidth,\n color: lineColor,\n borderDash,\n borderDashOffset,\n tickWidth,\n tickColor,\n tickBorderDash,\n tickBorderDashOffset\n });\n }\n this._ticksLength = ticksLength;\n this._borderValue = borderValue;\n return items;\n }\n _computeLabelItems(chartArea) {\n const axis = this.axis;\n const options = this.options;\n const { position , ticks: optionTicks } = options;\n const isHorizontal = this.isHorizontal();\n const ticks = this.ticks;\n const { align , crossAlign , padding , mirror } = optionTicks;\n const tl = getTickMarkLength(options.grid);\n const tickAndPadding = tl + padding;\n const hTickAndPadding = mirror ? -padding : tickAndPadding;\n const rotation = -toRadians(this.labelRotation);\n const items = [];\n let i, ilen, tick, label, x, y, textAlign, pixel, font, lineHeight, lineCount, textOffset;\n let textBaseline = 'middle';\n if (position === 'top') {\n y = this.bottom - hTickAndPadding;\n textAlign = this._getXAxisLabelAlignment();\n } else if (position === 'bottom') {\n y = this.top + hTickAndPadding;\n textAlign = this._getXAxisLabelAlignment();\n } else if (position === 'left') {\n const ret = this._getYAxisLabelAlignment(tl);\n textAlign = ret.textAlign;\n x = ret.x;\n } else if (position === 'right') {\n const ret = this._getYAxisLabelAlignment(tl);\n textAlign = ret.textAlign;\n x = ret.x;\n } else if (axis === 'x') {\n if (position === 'center') {\n y = (chartArea.top + chartArea.bottom) / 2 + tickAndPadding;\n } else if (isObject(position)) {\n const positionAxisID = Object.keys(position)[0];\n const value = position[positionAxisID];\n y = this.chart.scales[positionAxisID].getPixelForValue(value) + tickAndPadding;\n }\n textAlign = this._getXAxisLabelAlignment();\n } else if (axis === 'y') {\n if (position === 'center') {\n x = (chartArea.left + chartArea.right) / 2 - tickAndPadding;\n } else if (isObject(position)) {\n const positionAxisID = Object.keys(position)[0];\n const value = position[positionAxisID];\n x = this.chart.scales[positionAxisID].getPixelForValue(value);\n }\n textAlign = this._getYAxisLabelAlignment(tl).textAlign;\n }\n if (axis === 'y') {\n if (align === 'start') {\n textBaseline = 'top';\n } else if (align === 'end') {\n textBaseline = 'bottom';\n }\n }\n const labelSizes = this._getLabelSizes();\n for(i = 0, ilen = ticks.length; i < ilen; ++i){\n tick = ticks[i];\n label = tick.label;\n const optsAtIndex = optionTicks.setContext(this.getContext(i));\n pixel = this.getPixelForTick(i) + optionTicks.labelOffset;\n font = this._resolveTickFontOptions(i);\n lineHeight = font.lineHeight;\n lineCount = isArray(label) ? label.length : 1;\n const halfCount = lineCount / 2;\n const color = optsAtIndex.color;\n const strokeColor = optsAtIndex.textStrokeColor;\n const strokeWidth = optsAtIndex.textStrokeWidth;\n let tickTextAlign = textAlign;\n if (isHorizontal) {\n x = pixel;\n if (textAlign === 'inner') {\n if (i === ilen - 1) {\n tickTextAlign = !this.options.reverse ? 'right' : 'left';\n } else if (i === 0) {\n tickTextAlign = !this.options.reverse ? 'left' : 'right';\n } else {\n tickTextAlign = 'center';\n }\n }\n if (position === 'top') {\n if (crossAlign === 'near' || rotation !== 0) {\n textOffset = -lineCount * lineHeight + lineHeight / 2;\n } else if (crossAlign === 'center') {\n textOffset = -labelSizes.highest.height / 2 - halfCount * lineHeight + lineHeight;\n } else {\n textOffset = -labelSizes.highest.height + lineHeight / 2;\n }\n } else {\n if (crossAlign === 'near' || rotation !== 0) {\n textOffset = lineHeight / 2;\n } else if (crossAlign === 'center') {\n textOffset = labelSizes.highest.height / 2 - halfCount * lineHeight;\n } else {\n textOffset = labelSizes.highest.height - lineCount * lineHeight;\n }\n }\n if (mirror) {\n textOffset *= -1;\n }\n if (rotation !== 0 && !optsAtIndex.showLabelBackdrop) {\n x += lineHeight / 2 * Math.sin(rotation);\n }\n } else {\n y = pixel;\n textOffset = (1 - lineCount) * lineHeight / 2;\n }\n let backdrop;\n if (optsAtIndex.showLabelBackdrop) {\n const labelPadding = toPadding(optsAtIndex.backdropPadding);\n const height = labelSizes.heights[i];\n const width = labelSizes.widths[i];\n let top = textOffset - labelPadding.top;\n let left = 0 - labelPadding.left;\n switch(textBaseline){\n case 'middle':\n top -= height / 2;\n break;\n case 'bottom':\n top -= height;\n break;\n }\n switch(textAlign){\n case 'center':\n left -= width / 2;\n break;\n case 'right':\n left -= width;\n break;\n case 'inner':\n if (i === ilen - 1) {\n left -= width;\n } else if (i > 0) {\n left -= width / 2;\n }\n break;\n }\n backdrop = {\n left,\n top,\n width: width + labelPadding.width,\n height: height + labelPadding.height,\n color: optsAtIndex.backdropColor\n };\n }\n items.push({\n label,\n font,\n textOffset,\n options: {\n rotation,\n color,\n strokeColor,\n strokeWidth,\n textAlign: tickTextAlign,\n textBaseline,\n translation: [\n x,\n y\n ],\n backdrop\n }\n });\n }\n return items;\n }\n _getXAxisLabelAlignment() {\n const { position , ticks } = this.options;\n const rotation = -toRadians(this.labelRotation);\n if (rotation) {\n return position === 'top' ? 'left' : 'right';\n }\n let align = 'center';\n if (ticks.align === 'start') {\n align = 'left';\n } else if (ticks.align === 'end') {\n align = 'right';\n } else if (ticks.align === 'inner') {\n align = 'inner';\n }\n return align;\n }\n _getYAxisLabelAlignment(tl) {\n const { position , ticks: { crossAlign , mirror , padding } } = this.options;\n const labelSizes = this._getLabelSizes();\n const tickAndPadding = tl + padding;\n const widest = labelSizes.widest.width;\n let textAlign;\n let x;\n if (position === 'left') {\n if (mirror) {\n x = this.right + padding;\n if (crossAlign === 'near') {\n textAlign = 'left';\n } else if (crossAlign === 'center') {\n textAlign = 'center';\n x += widest / 2;\n } else {\n textAlign = 'right';\n x += widest;\n }\n } else {\n x = this.right - tickAndPadding;\n if (crossAlign === 'near') {\n textAlign = 'right';\n } else if (crossAlign === 'center') {\n textAlign = 'center';\n x -= widest / 2;\n } else {\n textAlign = 'left';\n x = this.left;\n }\n }\n } else if (position === 'right') {\n if (mirror) {\n x = this.left + padding;\n if (crossAlign === 'near') {\n textAlign = 'right';\n } else if (crossAlign === 'center') {\n textAlign = 'center';\n x -= widest / 2;\n } else {\n textAlign = 'left';\n x -= widest;\n }\n } else {\n x = this.left + tickAndPadding;\n if (crossAlign === 'near') {\n textAlign = 'left';\n } else if (crossAlign === 'center') {\n textAlign = 'center';\n x += widest / 2;\n } else {\n textAlign = 'right';\n x = this.right;\n }\n }\n } else {\n textAlign = 'right';\n }\n return {\n textAlign,\n x\n };\n }\n _computeLabelArea() {\n if (this.options.ticks.mirror) {\n return;\n }\n const chart = this.chart;\n const position = this.options.position;\n if (position === 'left' || position === 'right') {\n return {\n top: 0,\n left: this.left,\n bottom: chart.height,\n right: this.right\n };\n }\n if (position === 'top' || position === 'bottom') {\n return {\n top: this.top,\n left: 0,\n bottom: this.bottom,\n right: chart.width\n };\n }\n }\n drawBackground() {\n const { ctx , options: { backgroundColor } , left , top , width , height } = this;\n if (backgroundColor) {\n ctx.save();\n ctx.fillStyle = backgroundColor;\n ctx.fillRect(left, top, width, height);\n ctx.restore();\n }\n }\n getLineWidthForValue(value) {\n const grid = this.options.grid;\n if (!this._isVisible() || !grid.display) {\n return 0;\n }\n const ticks = this.ticks;\n const index = ticks.findIndex((t)=>t.value === value);\n if (index >= 0) {\n const opts = grid.setContext(this.getContext(index));\n return opts.lineWidth;\n }\n return 0;\n }\n drawGrid(chartArea) {\n const grid = this.options.grid;\n const ctx = this.ctx;\n const items = this._gridLineItems || (this._gridLineItems = this._computeGridLineItems(chartArea));\n let i, ilen;\n const drawLine = (p1, p2, style)=>{\n if (!style.width || !style.color) {\n return;\n }\n ctx.save();\n ctx.lineWidth = style.width;\n ctx.strokeStyle = style.color;\n ctx.setLineDash(style.borderDash || []);\n ctx.lineDashOffset = style.borderDashOffset;\n ctx.beginPath();\n ctx.moveTo(p1.x, p1.y);\n ctx.lineTo(p2.x, p2.y);\n ctx.stroke();\n ctx.restore();\n };\n if (grid.display) {\n for(i = 0, ilen = items.length; i < ilen; ++i){\n const item = items[i];\n if (grid.drawOnChartArea) {\n drawLine({\n x: item.x1,\n y: item.y1\n }, {\n x: item.x2,\n y: item.y2\n }, item);\n }\n if (grid.drawTicks) {\n drawLine({\n x: item.tx1,\n y: item.ty1\n }, {\n x: item.tx2,\n y: item.ty2\n }, {\n color: item.tickColor,\n width: item.tickWidth,\n borderDash: item.tickBorderDash,\n borderDashOffset: item.tickBorderDashOffset\n });\n }\n }\n }\n }\n drawBorder() {\n const { chart , ctx , options: { border , grid } } = this;\n const borderOpts = border.setContext(this.getContext());\n const axisWidth = border.display ? borderOpts.width : 0;\n if (!axisWidth) {\n return;\n }\n const lastLineWidth = grid.setContext(this.getContext(0)).lineWidth;\n const borderValue = this._borderValue;\n let x1, x2, y1, y2;\n if (this.isHorizontal()) {\n x1 = _alignPixel(chart, this.left, axisWidth) - axisWidth / 2;\n x2 = _alignPixel(chart, this.right, lastLineWidth) + lastLineWidth / 2;\n y1 = y2 = borderValue;\n } else {\n y1 = _alignPixel(chart, this.top, axisWidth) - axisWidth / 2;\n y2 = _alignPixel(chart, this.bottom, lastLineWidth) + lastLineWidth / 2;\n x1 = x2 = borderValue;\n }\n ctx.save();\n ctx.lineWidth = borderOpts.width;\n ctx.strokeStyle = borderOpts.color;\n ctx.beginPath();\n ctx.moveTo(x1, y1);\n ctx.lineTo(x2, y2);\n ctx.stroke();\n ctx.restore();\n }\n drawLabels(chartArea) {\n const optionTicks = this.options.ticks;\n if (!optionTicks.display) {\n return;\n }\n const ctx = this.ctx;\n const area = this._computeLabelArea();\n if (area) {\n clipArea(ctx, area);\n }\n const items = this.getLabelItems(chartArea);\n for (const item of items){\n const renderTextOptions = item.options;\n const tickFont = item.font;\n const label = item.label;\n const y = item.textOffset;\n renderText(ctx, label, 0, y, tickFont, renderTextOptions);\n }\n if (area) {\n unclipArea(ctx);\n }\n }\n drawTitle() {\n const { ctx , options: { position , title , reverse } } = this;\n if (!title.display) {\n return;\n }\n const font = toFont(title.font);\n const padding = toPadding(title.padding);\n const align = title.align;\n let offset = font.lineHeight / 2;\n if (position === 'bottom' || position === 'center' || isObject(position)) {\n offset += padding.bottom;\n if (isArray(title.text)) {\n offset += font.lineHeight * (title.text.length - 1);\n }\n } else {\n offset += padding.top;\n }\n const { titleX , titleY , maxWidth , rotation } = titleArgs(this, offset, position, align);\n renderText(ctx, title.text, 0, 0, font, {\n color: title.color,\n maxWidth,\n rotation,\n textAlign: titleAlign(align, position, reverse),\n textBaseline: 'middle',\n translation: [\n titleX,\n titleY\n ]\n });\n }\n draw(chartArea) {\n if (!this._isVisible()) {\n return;\n }\n this.drawBackground();\n this.drawGrid(chartArea);\n this.drawBorder();\n this.drawTitle();\n this.drawLabels(chartArea);\n }\n _layers() {\n const opts = this.options;\n const tz = opts.ticks && opts.ticks.z || 0;\n const gz = valueOrDefault(opts.grid && opts.grid.z, -1);\n const bz = valueOrDefault(opts.border && opts.border.z, 0);\n if (!this._isVisible() || this.draw !== Scale.prototype.draw) {\n return [\n {\n z: tz,\n draw: (chartArea)=>{\n this.draw(chartArea);\n }\n }\n ];\n }\n return [\n {\n z: gz,\n draw: (chartArea)=>{\n this.drawBackground();\n this.drawGrid(chartArea);\n this.drawTitle();\n }\n },\n {\n z: bz,\n draw: ()=>{\n this.drawBorder();\n }\n },\n {\n z: tz,\n draw: (chartArea)=>{\n this.drawLabels(chartArea);\n }\n }\n ];\n }\n getMatchingVisibleMetas(type) {\n const metas = this.chart.getSortedVisibleDatasetMetas();\n const axisID = this.axis + 'AxisID';\n const result = [];\n let i, ilen;\n for(i = 0, ilen = metas.length; i < ilen; ++i){\n const meta = metas[i];\n if (meta[axisID] === this.id && (!type || meta.type === type)) {\n result.push(meta);\n }\n }\n return result;\n }\n _resolveTickFontOptions(index) {\n const opts = this.options.ticks.setContext(this.getContext(index));\n return toFont(opts.font);\n }\n _maxDigits() {\n const fontSize = this._resolveTickFontOptions(0).lineHeight;\n return (this.isHorizontal() ? this.width : this.height) / fontSize;\n }\n}\n\nclass TypedRegistry {\n constructor(type, scope, override){\n this.type = type;\n this.scope = scope;\n this.override = override;\n this.items = Object.create(null);\n }\n isForType(type) {\n return Object.prototype.isPrototypeOf.call(this.type.prototype, type.prototype);\n }\n register(item) {\n const proto = Object.getPrototypeOf(item);\n let parentScope;\n if (isIChartComponent(proto)) {\n parentScope = this.register(proto);\n }\n const items = this.items;\n const id = item.id;\n const scope = this.scope + '.' + id;\n if (!id) {\n throw new Error('class does not have id: ' + item);\n }\n if (id in items) {\n return scope;\n }\n items[id] = item;\n registerDefaults(item, scope, parentScope);\n if (this.override) {\n defaults.override(item.id, item.overrides);\n }\n return scope;\n }\n get(id) {\n return this.items[id];\n }\n unregister(item) {\n const items = this.items;\n const id = item.id;\n const scope = this.scope;\n if (id in items) {\n delete items[id];\n }\n if (scope && id in defaults[scope]) {\n delete defaults[scope][id];\n if (this.override) {\n delete overrides[id];\n }\n }\n }\n}\nfunction registerDefaults(item, scope, parentScope) {\n const itemDefaults = merge(Object.create(null), [\n parentScope ? defaults.get(parentScope) : {},\n defaults.get(scope),\n item.defaults\n ]);\n defaults.set(scope, itemDefaults);\n if (item.defaultRoutes) {\n routeDefaults(scope, item.defaultRoutes);\n }\n if (item.descriptors) {\n defaults.describe(scope, item.descriptors);\n }\n}\nfunction routeDefaults(scope, routes) {\n Object.keys(routes).forEach((property)=>{\n const propertyParts = property.split('.');\n const sourceName = propertyParts.pop();\n const sourceScope = [\n scope\n ].concat(propertyParts).join('.');\n const parts = routes[property].split('.');\n const targetName = parts.pop();\n const targetScope = parts.join('.');\n defaults.route(sourceScope, sourceName, targetScope, targetName);\n });\n}\nfunction isIChartComponent(proto) {\n return 'id' in proto && 'defaults' in proto;\n}\n\nclass Registry {\n constructor(){\n this.controllers = new TypedRegistry(DatasetController, 'datasets', true);\n this.elements = new TypedRegistry(Element, 'elements');\n this.plugins = new TypedRegistry(Object, 'plugins');\n this.scales = new TypedRegistry(Scale, 'scales');\n this._typedRegistries = [\n this.controllers,\n this.scales,\n this.elements\n ];\n }\n add(...args) {\n this._each('register', args);\n }\n remove(...args) {\n this._each('unregister', args);\n }\n addControllers(...args) {\n this._each('register', args, this.controllers);\n }\n addElements(...args) {\n this._each('register', args, this.elements);\n }\n addPlugins(...args) {\n this._each('register', args, this.plugins);\n }\n addScales(...args) {\n this._each('register', args, this.scales);\n }\n getController(id) {\n return this._get(id, this.controllers, 'controller');\n }\n getElement(id) {\n return this._get(id, this.elements, 'element');\n }\n getPlugin(id) {\n return this._get(id, this.plugins, 'plugin');\n }\n getScale(id) {\n return this._get(id, this.scales, 'scale');\n }\n removeControllers(...args) {\n this._each('unregister', args, this.controllers);\n }\n removeElements(...args) {\n this._each('unregister', args, this.elements);\n }\n removePlugins(...args) {\n this._each('unregister', args, this.plugins);\n }\n removeScales(...args) {\n this._each('unregister', args, this.scales);\n }\n _each(method, args, typedRegistry) {\n [\n ...args\n ].forEach((arg)=>{\n const reg = typedRegistry || this._getRegistryForType(arg);\n if (typedRegistry || reg.isForType(arg) || reg === this.plugins && arg.id) {\n this._exec(method, reg, arg);\n } else {\n each(arg, (item)=>{\n const itemReg = typedRegistry || this._getRegistryForType(item);\n this._exec(method, itemReg, item);\n });\n }\n });\n }\n _exec(method, registry, component) {\n const camelMethod = _capitalize(method);\n callback(component['before' + camelMethod], [], component);\n registry[method](component);\n callback(component['after' + camelMethod], [], component);\n }\n _getRegistryForType(type) {\n for(let i = 0; i < this._typedRegistries.length; i++){\n const reg = this._typedRegistries[i];\n if (reg.isForType(type)) {\n return reg;\n }\n }\n return this.plugins;\n }\n _get(id, typedRegistry, type) {\n const item = typedRegistry.get(id);\n if (item === undefined) {\n throw new Error('\"' + id + '\" is not a registered ' + type + '.');\n }\n return item;\n }\n}\nvar registry = /* #__PURE__ */ new Registry();\n\nclass PluginService {\n constructor(){\n this._init = [];\n }\n notify(chart, hook, args, filter) {\n if (hook === 'beforeInit') {\n this._init = this._createDescriptors(chart, true);\n this._notify(this._init, chart, 'install');\n }\n const descriptors = filter ? this._descriptors(chart).filter(filter) : this._descriptors(chart);\n const result = this._notify(descriptors, chart, hook, args);\n if (hook === 'afterDestroy') {\n this._notify(descriptors, chart, 'stop');\n this._notify(this._init, chart, 'uninstall');\n }\n return result;\n }\n _notify(descriptors, chart, hook, args) {\n args = args || {};\n for (const descriptor of descriptors){\n const plugin = descriptor.plugin;\n const method = plugin[hook];\n const params = [\n chart,\n args,\n descriptor.options\n ];\n if (callback(method, params, plugin) === false && args.cancelable) {\n return false;\n }\n }\n return true;\n }\n invalidate() {\n if (!isNullOrUndef(this._cache)) {\n this._oldCache = this._cache;\n this._cache = undefined;\n }\n }\n _descriptors(chart) {\n if (this._cache) {\n return this._cache;\n }\n const descriptors = this._cache = this._createDescriptors(chart);\n this._notifyStateChanges(chart);\n return descriptors;\n }\n _createDescriptors(chart, all) {\n const config = chart && chart.config;\n const options = valueOrDefault(config.options && config.options.plugins, {});\n const plugins = allPlugins(config);\n return options === false && !all ? [] : createDescriptors(chart, plugins, options, all);\n }\n _notifyStateChanges(chart) {\n const previousDescriptors = this._oldCache || [];\n const descriptors = this._cache;\n const diff = (a, b)=>a.filter((x)=>!b.some((y)=>x.plugin.id === y.plugin.id));\n this._notify(diff(previousDescriptors, descriptors), chart, 'stop');\n this._notify(diff(descriptors, previousDescriptors), chart, 'start');\n }\n}\n function allPlugins(config) {\n const localIds = {};\n const plugins = [];\n const keys = Object.keys(registry.plugins.items);\n for(let i = 0; i < keys.length; i++){\n plugins.push(registry.getPlugin(keys[i]));\n }\n const local = config.plugins || [];\n for(let i = 0; i < local.length; i++){\n const plugin = local[i];\n if (plugins.indexOf(plugin) === -1) {\n plugins.push(plugin);\n localIds[plugin.id] = true;\n }\n }\n return {\n plugins,\n localIds\n };\n}\nfunction getOpts(options, all) {\n if (!all && options === false) {\n return null;\n }\n if (options === true) {\n return {};\n }\n return options;\n}\nfunction createDescriptors(chart, { plugins , localIds }, options, all) {\n const result = [];\n const context = chart.getContext();\n for (const plugin of plugins){\n const id = plugin.id;\n const opts = getOpts(options[id], all);\n if (opts === null) {\n continue;\n }\n result.push({\n plugin,\n options: pluginOpts(chart.config, {\n plugin,\n local: localIds[id]\n }, opts, context)\n });\n }\n return result;\n}\nfunction pluginOpts(config, { plugin , local }, opts, context) {\n const keys = config.pluginScopeKeys(plugin);\n const scopes = config.getOptionScopes(opts, keys);\n if (local && plugin.defaults) {\n scopes.push(plugin.defaults);\n }\n return config.createResolver(scopes, context, [\n ''\n ], {\n scriptable: false,\n indexable: false,\n allKeys: true\n });\n}\n\nfunction getIndexAxis(type, options) {\n const datasetDefaults = defaults.datasets[type] || {};\n const datasetOptions = (options.datasets || {})[type] || {};\n return datasetOptions.indexAxis || options.indexAxis || datasetDefaults.indexAxis || 'x';\n}\nfunction getAxisFromDefaultScaleID(id, indexAxis) {\n let axis = id;\n if (id === '_index_') {\n axis = indexAxis;\n } else if (id === '_value_') {\n axis = indexAxis === 'x' ? 'y' : 'x';\n }\n return axis;\n}\nfunction getDefaultScaleIDFromAxis(axis, indexAxis) {\n return axis === indexAxis ? '_index_' : '_value_';\n}\nfunction idMatchesAxis(id) {\n if (id === 'x' || id === 'y' || id === 'r') {\n return id;\n }\n}\nfunction axisFromPosition(position) {\n if (position === 'top' || position === 'bottom') {\n return 'x';\n }\n if (position === 'left' || position === 'right') {\n return 'y';\n }\n}\nfunction determineAxis(id, ...scaleOptions) {\n if (idMatchesAxis(id)) {\n return id;\n }\n for (const opts of scaleOptions){\n const axis = opts.axis || axisFromPosition(opts.position) || id.length > 1 && idMatchesAxis(id[0].toLowerCase());\n if (axis) {\n return axis;\n }\n }\n throw new Error(`Cannot determine type of '${id}' axis. Please provide 'axis' or 'position' option.`);\n}\nfunction getAxisFromDataset(id, axis, dataset) {\n if (dataset[axis + 'AxisID'] === id) {\n return {\n axis\n };\n }\n}\nfunction retrieveAxisFromDatasets(id, config) {\n if (config.data && config.data.datasets) {\n const boundDs = config.data.datasets.filter((d)=>d.xAxisID === id || d.yAxisID === id);\n if (boundDs.length) {\n return getAxisFromDataset(id, 'x', boundDs[0]) || getAxisFromDataset(id, 'y', boundDs[0]);\n }\n }\n return {};\n}\nfunction mergeScaleConfig(config, options) {\n const chartDefaults = overrides[config.type] || {\n scales: {}\n };\n const configScales = options.scales || {};\n const chartIndexAxis = getIndexAxis(config.type, options);\n const scales = Object.create(null);\n Object.keys(configScales).forEach((id)=>{\n const scaleConf = configScales[id];\n if (!isObject(scaleConf)) {\n return console.error(`Invalid scale configuration for scale: ${id}`);\n }\n if (scaleConf._proxy) {\n return console.warn(`Ignoring resolver passed as options for scale: ${id}`);\n }\n const axis = determineAxis(id, scaleConf, retrieveAxisFromDatasets(id, config), defaults.scales[scaleConf.type]);\n const defaultId = getDefaultScaleIDFromAxis(axis, chartIndexAxis);\n const defaultScaleOptions = chartDefaults.scales || {};\n scales[id] = mergeIf(Object.create(null), [\n {\n axis\n },\n scaleConf,\n defaultScaleOptions[axis],\n defaultScaleOptions[defaultId]\n ]);\n });\n config.data.datasets.forEach((dataset)=>{\n const type = dataset.type || config.type;\n const indexAxis = dataset.indexAxis || getIndexAxis(type, options);\n const datasetDefaults = overrides[type] || {};\n const defaultScaleOptions = datasetDefaults.scales || {};\n Object.keys(defaultScaleOptions).forEach((defaultID)=>{\n const axis = getAxisFromDefaultScaleID(defaultID, indexAxis);\n const id = dataset[axis + 'AxisID'] || axis;\n scales[id] = scales[id] || Object.create(null);\n mergeIf(scales[id], [\n {\n axis\n },\n configScales[id],\n defaultScaleOptions[defaultID]\n ]);\n });\n });\n Object.keys(scales).forEach((key)=>{\n const scale = scales[key];\n mergeIf(scale, [\n defaults.scales[scale.type],\n defaults.scale\n ]);\n });\n return scales;\n}\nfunction initOptions(config) {\n const options = config.options || (config.options = {});\n options.plugins = valueOrDefault(options.plugins, {});\n options.scales = mergeScaleConfig(config, options);\n}\nfunction initData(data) {\n data = data || {};\n data.datasets = data.datasets || [];\n data.labels = data.labels || [];\n return data;\n}\nfunction initConfig(config) {\n config = config || {};\n config.data = initData(config.data);\n initOptions(config);\n return config;\n}\nconst keyCache = new Map();\nconst keysCached = new Set();\nfunction cachedKeys(cacheKey, generate) {\n let keys = keyCache.get(cacheKey);\n if (!keys) {\n keys = generate();\n keyCache.set(cacheKey, keys);\n keysCached.add(keys);\n }\n return keys;\n}\nconst addIfFound = (set, obj, key)=>{\n const opts = resolveObjectKey(obj, key);\n if (opts !== undefined) {\n set.add(opts);\n }\n};\nclass Config {\n constructor(config){\n this._config = initConfig(config);\n this._scopeCache = new Map();\n this._resolverCache = new Map();\n }\n get platform() {\n return this._config.platform;\n }\n get type() {\n return this._config.type;\n }\n set type(type) {\n this._config.type = type;\n }\n get data() {\n return this._config.data;\n }\n set data(data) {\n this._config.data = initData(data);\n }\n get options() {\n return this._config.options;\n }\n set options(options) {\n this._config.options = options;\n }\n get plugins() {\n return this._config.plugins;\n }\n update() {\n const config = this._config;\n this.clearCache();\n initOptions(config);\n }\n clearCache() {\n this._scopeCache.clear();\n this._resolverCache.clear();\n }\n datasetScopeKeys(datasetType) {\n return cachedKeys(datasetType, ()=>[\n [\n `datasets.${datasetType}`,\n ''\n ]\n ]);\n }\n datasetAnimationScopeKeys(datasetType, transition) {\n return cachedKeys(`${datasetType}.transition.${transition}`, ()=>[\n [\n `datasets.${datasetType}.transitions.${transition}`,\n `transitions.${transition}`\n ],\n [\n `datasets.${datasetType}`,\n ''\n ]\n ]);\n }\n datasetElementScopeKeys(datasetType, elementType) {\n return cachedKeys(`${datasetType}-${elementType}`, ()=>[\n [\n `datasets.${datasetType}.elements.${elementType}`,\n `datasets.${datasetType}`,\n `elements.${elementType}`,\n ''\n ]\n ]);\n }\n pluginScopeKeys(plugin) {\n const id = plugin.id;\n const type = this.type;\n return cachedKeys(`${type}-plugin-${id}`, ()=>[\n [\n `plugins.${id}`,\n ...plugin.additionalOptionScopes || []\n ]\n ]);\n }\n _cachedScopes(mainScope, resetCache) {\n const _scopeCache = this._scopeCache;\n let cache = _scopeCache.get(mainScope);\n if (!cache || resetCache) {\n cache = new Map();\n _scopeCache.set(mainScope, cache);\n }\n return cache;\n }\n getOptionScopes(mainScope, keyLists, resetCache) {\n const { options , type } = this;\n const cache = this._cachedScopes(mainScope, resetCache);\n const cached = cache.get(keyLists);\n if (cached) {\n return cached;\n }\n const scopes = new Set();\n keyLists.forEach((keys)=>{\n if (mainScope) {\n scopes.add(mainScope);\n keys.forEach((key)=>addIfFound(scopes, mainScope, key));\n }\n keys.forEach((key)=>addIfFound(scopes, options, key));\n keys.forEach((key)=>addIfFound(scopes, overrides[type] || {}, key));\n keys.forEach((key)=>addIfFound(scopes, defaults, key));\n keys.forEach((key)=>addIfFound(scopes, descriptors, key));\n });\n const array = Array.from(scopes);\n if (array.length === 0) {\n array.push(Object.create(null));\n }\n if (keysCached.has(keyLists)) {\n cache.set(keyLists, array);\n }\n return array;\n }\n chartOptionScopes() {\n const { options , type } = this;\n return [\n options,\n overrides[type] || {},\n defaults.datasets[type] || {},\n {\n type\n },\n defaults,\n descriptors\n ];\n }\n resolveNamedOptions(scopes, names, context, prefixes = [\n ''\n ]) {\n const result = {\n $shared: true\n };\n const { resolver , subPrefixes } = getResolver(this._resolverCache, scopes, prefixes);\n let options = resolver;\n if (needContext(resolver, names)) {\n result.$shared = false;\n context = isFunction(context) ? context() : context;\n const subResolver = this.createResolver(scopes, context, subPrefixes);\n options = _attachContext(resolver, context, subResolver);\n }\n for (const prop of names){\n result[prop] = options[prop];\n }\n return result;\n }\n createResolver(scopes, context, prefixes = [\n ''\n ], descriptorDefaults) {\n const { resolver } = getResolver(this._resolverCache, scopes, prefixes);\n return isObject(context) ? _attachContext(resolver, context, undefined, descriptorDefaults) : resolver;\n }\n}\nfunction getResolver(resolverCache, scopes, prefixes) {\n let cache = resolverCache.get(scopes);\n if (!cache) {\n cache = new Map();\n resolverCache.set(scopes, cache);\n }\n const cacheKey = prefixes.join();\n let cached = cache.get(cacheKey);\n if (!cached) {\n const resolver = _createResolver(scopes, prefixes);\n cached = {\n resolver,\n subPrefixes: prefixes.filter((p)=>!p.toLowerCase().includes('hover'))\n };\n cache.set(cacheKey, cached);\n }\n return cached;\n}\nconst hasFunction = (value)=>isObject(value) && Object.getOwnPropertyNames(value).some((key)=>isFunction(value[key]));\nfunction needContext(proxy, names) {\n const { isScriptable , isIndexable } = _descriptors(proxy);\n for (const prop of names){\n const scriptable = isScriptable(prop);\n const indexable = isIndexable(prop);\n const value = (indexable || scriptable) && proxy[prop];\n if (scriptable && (isFunction(value) || hasFunction(value)) || indexable && isArray(value)) {\n return true;\n }\n }\n return false;\n}\n\nvar version = \"4.4.4\";\n\nconst KNOWN_POSITIONS = [\n 'top',\n 'bottom',\n 'left',\n 'right',\n 'chartArea'\n];\nfunction positionIsHorizontal(position, axis) {\n return position === 'top' || position === 'bottom' || KNOWN_POSITIONS.indexOf(position) === -1 && axis === 'x';\n}\nfunction compare2Level(l1, l2) {\n return function(a, b) {\n return a[l1] === b[l1] ? a[l2] - b[l2] : a[l1] - b[l1];\n };\n}\nfunction onAnimationsComplete(context) {\n const chart = context.chart;\n const animationOptions = chart.options.animation;\n chart.notifyPlugins('afterRender');\n callback(animationOptions && animationOptions.onComplete, [\n context\n ], chart);\n}\nfunction onAnimationProgress(context) {\n const chart = context.chart;\n const animationOptions = chart.options.animation;\n callback(animationOptions && animationOptions.onProgress, [\n context\n ], chart);\n}\n function getCanvas(item) {\n if (_isDomSupported() && typeof item === 'string') {\n item = document.getElementById(item);\n } else if (item && item.length) {\n item = item[0];\n }\n if (item && item.canvas) {\n item = item.canvas;\n }\n return item;\n}\nconst instances = {};\nconst getChart = (key)=>{\n const canvas = getCanvas(key);\n return Object.values(instances).filter((c)=>c.canvas === canvas).pop();\n};\nfunction moveNumericKeys(obj, start, move) {\n const keys = Object.keys(obj);\n for (const key of keys){\n const intKey = +key;\n if (intKey >= start) {\n const value = obj[key];\n delete obj[key];\n if (move > 0 || intKey > start) {\n obj[intKey + move] = value;\n }\n }\n }\n}\n function determineLastEvent(e, lastEvent, inChartArea, isClick) {\n if (!inChartArea || e.type === 'mouseout') {\n return null;\n }\n if (isClick) {\n return lastEvent;\n }\n return e;\n}\nfunction getSizeForArea(scale, chartArea, field) {\n return scale.options.clip ? scale[field] : chartArea[field];\n}\nfunction getDatasetArea(meta, chartArea) {\n const { xScale , yScale } = meta;\n if (xScale && yScale) {\n return {\n left: getSizeForArea(xScale, chartArea, 'left'),\n right: getSizeForArea(xScale, chartArea, 'right'),\n top: getSizeForArea(yScale, chartArea, 'top'),\n bottom: getSizeForArea(yScale, chartArea, 'bottom')\n };\n }\n return chartArea;\n}\nclass Chart {\n static defaults = defaults;\n static instances = instances;\n static overrides = overrides;\n static registry = registry;\n static version = version;\n static getChart = getChart;\n static register(...items) {\n registry.add(...items);\n invalidatePlugins();\n }\n static unregister(...items) {\n registry.remove(...items);\n invalidatePlugins();\n }\n constructor(item, userConfig){\n const config = this.config = new Config(userConfig);\n const initialCanvas = getCanvas(item);\n const existingChart = getChart(initialCanvas);\n if (existingChart) {\n throw new Error('Canvas is already in use. Chart with ID \\'' + existingChart.id + '\\'' + ' must be destroyed before the canvas with ID \\'' + existingChart.canvas.id + '\\' can be reused.');\n }\n const options = config.createResolver(config.chartOptionScopes(), this.getContext());\n this.platform = new (config.platform || _detectPlatform(initialCanvas))();\n this.platform.updateConfig(config);\n const context = this.platform.acquireContext(initialCanvas, options.aspectRatio);\n const canvas = context && context.canvas;\n const height = canvas && canvas.height;\n const width = canvas && canvas.width;\n this.id = uid();\n this.ctx = context;\n this.canvas = canvas;\n this.width = width;\n this.height = height;\n this._options = options;\n this._aspectRatio = this.aspectRatio;\n this._layers = [];\n this._metasets = [];\n this._stacks = undefined;\n this.boxes = [];\n this.currentDevicePixelRatio = undefined;\n this.chartArea = undefined;\n this._active = [];\n this._lastEvent = undefined;\n this._listeners = {};\n this._responsiveListeners = undefined;\n this._sortedMetasets = [];\n this.scales = {};\n this._plugins = new PluginService();\n this.$proxies = {};\n this._hiddenIndices = {};\n this.attached = false;\n this._animationsDisabled = undefined;\n this.$context = undefined;\n this._doResize = debounce((mode)=>this.update(mode), options.resizeDelay || 0);\n this._dataChanges = [];\n instances[this.id] = this;\n if (!context || !canvas) {\n console.error(\"Failed to create chart: can't acquire context from the given item\");\n return;\n }\n animator.listen(this, 'complete', onAnimationsComplete);\n animator.listen(this, 'progress', onAnimationProgress);\n this._initialize();\n if (this.attached) {\n this.update();\n }\n }\n get aspectRatio() {\n const { options: { aspectRatio , maintainAspectRatio } , width , height , _aspectRatio } = this;\n if (!isNullOrUndef(aspectRatio)) {\n return aspectRatio;\n }\n if (maintainAspectRatio && _aspectRatio) {\n return _aspectRatio;\n }\n return height ? width / height : null;\n }\n get data() {\n return this.config.data;\n }\n set data(data) {\n this.config.data = data;\n }\n get options() {\n return this._options;\n }\n set options(options) {\n this.config.options = options;\n }\n get registry() {\n return registry;\n }\n _initialize() {\n this.notifyPlugins('beforeInit');\n if (this.options.responsive) {\n this.resize();\n } else {\n retinaScale(this, this.options.devicePixelRatio);\n }\n this.bindEvents();\n this.notifyPlugins('afterInit');\n return this;\n }\n clear() {\n clearCanvas(this.canvas, this.ctx);\n return this;\n }\n stop() {\n animator.stop(this);\n return this;\n }\n resize(width, height) {\n if (!animator.running(this)) {\n this._resize(width, height);\n } else {\n this._resizeBeforeDraw = {\n width,\n height\n };\n }\n }\n _resize(width, height) {\n const options = this.options;\n const canvas = this.canvas;\n const aspectRatio = options.maintainAspectRatio && this.aspectRatio;\n const newSize = this.platform.getMaximumSize(canvas, width, height, aspectRatio);\n const newRatio = options.devicePixelRatio || this.platform.getDevicePixelRatio();\n const mode = this.width ? 'resize' : 'attach';\n this.width = newSize.width;\n this.height = newSize.height;\n this._aspectRatio = this.aspectRatio;\n if (!retinaScale(this, newRatio, true)) {\n return;\n }\n this.notifyPlugins('resize', {\n size: newSize\n });\n callback(options.onResize, [\n this,\n newSize\n ], this);\n if (this.attached) {\n if (this._doResize(mode)) {\n this.render();\n }\n }\n }\n ensureScalesHaveIDs() {\n const options = this.options;\n const scalesOptions = options.scales || {};\n each(scalesOptions, (axisOptions, axisID)=>{\n axisOptions.id = axisID;\n });\n }\n buildOrUpdateScales() {\n const options = this.options;\n const scaleOpts = options.scales;\n const scales = this.scales;\n const updated = Object.keys(scales).reduce((obj, id)=>{\n obj[id] = false;\n return obj;\n }, {});\n let items = [];\n if (scaleOpts) {\n items = items.concat(Object.keys(scaleOpts).map((id)=>{\n const scaleOptions = scaleOpts[id];\n const axis = determineAxis(id, scaleOptions);\n const isRadial = axis === 'r';\n const isHorizontal = axis === 'x';\n return {\n options: scaleOptions,\n dposition: isRadial ? 'chartArea' : isHorizontal ? 'bottom' : 'left',\n dtype: isRadial ? 'radialLinear' : isHorizontal ? 'category' : 'linear'\n };\n }));\n }\n each(items, (item)=>{\n const scaleOptions = item.options;\n const id = scaleOptions.id;\n const axis = determineAxis(id, scaleOptions);\n const scaleType = valueOrDefault(scaleOptions.type, item.dtype);\n if (scaleOptions.position === undefined || positionIsHorizontal(scaleOptions.position, axis) !== positionIsHorizontal(item.dposition)) {\n scaleOptions.position = item.dposition;\n }\n updated[id] = true;\n let scale = null;\n if (id in scales && scales[id].type === scaleType) {\n scale = scales[id];\n } else {\n const scaleClass = registry.getScale(scaleType);\n scale = new scaleClass({\n id,\n type: scaleType,\n ctx: this.ctx,\n chart: this\n });\n scales[scale.id] = scale;\n }\n scale.init(scaleOptions, options);\n });\n each(updated, (hasUpdated, id)=>{\n if (!hasUpdated) {\n delete scales[id];\n }\n });\n each(scales, (scale)=>{\n layouts.configure(this, scale, scale.options);\n layouts.addBox(this, scale);\n });\n }\n _updateMetasets() {\n const metasets = this._metasets;\n const numData = this.data.datasets.length;\n const numMeta = metasets.length;\n metasets.sort((a, b)=>a.index - b.index);\n if (numMeta > numData) {\n for(let i = numData; i < numMeta; ++i){\n this._destroyDatasetMeta(i);\n }\n metasets.splice(numData, numMeta - numData);\n }\n this._sortedMetasets = metasets.slice(0).sort(compare2Level('order', 'index'));\n }\n _removeUnreferencedMetasets() {\n const { _metasets: metasets , data: { datasets } } = this;\n if (metasets.length > datasets.length) {\n delete this._stacks;\n }\n metasets.forEach((meta, index)=>{\n if (datasets.filter((x)=>x === meta._dataset).length === 0) {\n this._destroyDatasetMeta(index);\n }\n });\n }\n buildOrUpdateControllers() {\n const newControllers = [];\n const datasets = this.data.datasets;\n let i, ilen;\n this._removeUnreferencedMetasets();\n for(i = 0, ilen = datasets.length; i < ilen; i++){\n const dataset = datasets[i];\n let meta = this.getDatasetMeta(i);\n const type = dataset.type || this.config.type;\n if (meta.type && meta.type !== type) {\n this._destroyDatasetMeta(i);\n meta = this.getDatasetMeta(i);\n }\n meta.type = type;\n meta.indexAxis = dataset.indexAxis || getIndexAxis(type, this.options);\n meta.order = dataset.order || 0;\n meta.index = i;\n meta.label = '' + dataset.label;\n meta.visible = this.isDatasetVisible(i);\n if (meta.controller) {\n meta.controller.updateIndex(i);\n meta.controller.linkScales();\n } else {\n const ControllerClass = registry.getController(type);\n const { datasetElementType , dataElementType } = defaults.datasets[type];\n Object.assign(ControllerClass, {\n dataElementType: registry.getElement(dataElementType),\n datasetElementType: datasetElementType && registry.getElement(datasetElementType)\n });\n meta.controller = new ControllerClass(this, i);\n newControllers.push(meta.controller);\n }\n }\n this._updateMetasets();\n return newControllers;\n }\n _resetElements() {\n each(this.data.datasets, (dataset, datasetIndex)=>{\n this.getDatasetMeta(datasetIndex).controller.reset();\n }, this);\n }\n reset() {\n this._resetElements();\n this.notifyPlugins('reset');\n }\n update(mode) {\n const config = this.config;\n config.update();\n const options = this._options = config.createResolver(config.chartOptionScopes(), this.getContext());\n const animsDisabled = this._animationsDisabled = !options.animation;\n this._updateScales();\n this._checkEventBindings();\n this._updateHiddenIndices();\n this._plugins.invalidate();\n if (this.notifyPlugins('beforeUpdate', {\n mode,\n cancelable: true\n }) === false) {\n return;\n }\n const newControllers = this.buildOrUpdateControllers();\n this.notifyPlugins('beforeElementsUpdate');\n let minPadding = 0;\n for(let i = 0, ilen = this.data.datasets.length; i < ilen; i++){\n const { controller } = this.getDatasetMeta(i);\n const reset = !animsDisabled && newControllers.indexOf(controller) === -1;\n controller.buildOrUpdateElements(reset);\n minPadding = Math.max(+controller.getMaxOverflow(), minPadding);\n }\n minPadding = this._minPadding = options.layout.autoPadding ? minPadding : 0;\n this._updateLayout(minPadding);\n if (!animsDisabled) {\n each(newControllers, (controller)=>{\n controller.reset();\n });\n }\n this._updateDatasets(mode);\n this.notifyPlugins('afterUpdate', {\n mode\n });\n this._layers.sort(compare2Level('z', '_idx'));\n const { _active , _lastEvent } = this;\n if (_lastEvent) {\n this._eventHandler(_lastEvent, true);\n } else if (_active.length) {\n this._updateHoverStyles(_active, _active, true);\n }\n this.render();\n }\n _updateScales() {\n each(this.scales, (scale)=>{\n layouts.removeBox(this, scale);\n });\n this.ensureScalesHaveIDs();\n this.buildOrUpdateScales();\n }\n _checkEventBindings() {\n const options = this.options;\n const existingEvents = new Set(Object.keys(this._listeners));\n const newEvents = new Set(options.events);\n if (!setsEqual(existingEvents, newEvents) || !!this._responsiveListeners !== options.responsive) {\n this.unbindEvents();\n this.bindEvents();\n }\n }\n _updateHiddenIndices() {\n const { _hiddenIndices } = this;\n const changes = this._getUniformDataChanges() || [];\n for (const { method , start , count } of changes){\n const move = method === '_removeElements' ? -count : count;\n moveNumericKeys(_hiddenIndices, start, move);\n }\n }\n _getUniformDataChanges() {\n const _dataChanges = this._dataChanges;\n if (!_dataChanges || !_dataChanges.length) {\n return;\n }\n this._dataChanges = [];\n const datasetCount = this.data.datasets.length;\n const makeSet = (idx)=>new Set(_dataChanges.filter((c)=>c[0] === idx).map((c, i)=>i + ',' + c.splice(1).join(',')));\n const changeSet = makeSet(0);\n for(let i = 1; i < datasetCount; i++){\n if (!setsEqual(changeSet, makeSet(i))) {\n return;\n }\n }\n return Array.from(changeSet).map((c)=>c.split(',')).map((a)=>({\n method: a[1],\n start: +a[2],\n count: +a[3]\n }));\n }\n _updateLayout(minPadding) {\n if (this.notifyPlugins('beforeLayout', {\n cancelable: true\n }) === false) {\n return;\n }\n layouts.update(this, this.width, this.height, minPadding);\n const area = this.chartArea;\n const noArea = area.width <= 0 || area.height <= 0;\n this._layers = [];\n each(this.boxes, (box)=>{\n if (noArea && box.position === 'chartArea') {\n return;\n }\n if (box.configure) {\n box.configure();\n }\n this._layers.push(...box._layers());\n }, this);\n this._layers.forEach((item, index)=>{\n item._idx = index;\n });\n this.notifyPlugins('afterLayout');\n }\n _updateDatasets(mode) {\n if (this.notifyPlugins('beforeDatasetsUpdate', {\n mode,\n cancelable: true\n }) === false) {\n return;\n }\n for(let i = 0, ilen = this.data.datasets.length; i < ilen; ++i){\n this.getDatasetMeta(i).controller.configure();\n }\n for(let i = 0, ilen = this.data.datasets.length; i < ilen; ++i){\n this._updateDataset(i, isFunction(mode) ? mode({\n datasetIndex: i\n }) : mode);\n }\n this.notifyPlugins('afterDatasetsUpdate', {\n mode\n });\n }\n _updateDataset(index, mode) {\n const meta = this.getDatasetMeta(index);\n const args = {\n meta,\n index,\n mode,\n cancelable: true\n };\n if (this.notifyPlugins('beforeDatasetUpdate', args) === false) {\n return;\n }\n meta.controller._update(mode);\n args.cancelable = false;\n this.notifyPlugins('afterDatasetUpdate', args);\n }\n render() {\n if (this.notifyPlugins('beforeRender', {\n cancelable: true\n }) === false) {\n return;\n }\n if (animator.has(this)) {\n if (this.attached && !animator.running(this)) {\n animator.start(this);\n }\n } else {\n this.draw();\n onAnimationsComplete({\n chart: this\n });\n }\n }\n draw() {\n let i;\n if (this._resizeBeforeDraw) {\n const { width , height } = this._resizeBeforeDraw;\n this._resizeBeforeDraw = null;\n this._resize(width, height);\n }\n this.clear();\n if (this.width <= 0 || this.height <= 0) {\n return;\n }\n if (this.notifyPlugins('beforeDraw', {\n cancelable: true\n }) === false) {\n return;\n }\n const layers = this._layers;\n for(i = 0; i < layers.length && layers[i].z <= 0; ++i){\n layers[i].draw(this.chartArea);\n }\n this._drawDatasets();\n for(; i < layers.length; ++i){\n layers[i].draw(this.chartArea);\n }\n this.notifyPlugins('afterDraw');\n }\n _getSortedDatasetMetas(filterVisible) {\n const metasets = this._sortedMetasets;\n const result = [];\n let i, ilen;\n for(i = 0, ilen = metasets.length; i < ilen; ++i){\n const meta = metasets[i];\n if (!filterVisible || meta.visible) {\n result.push(meta);\n }\n }\n return result;\n }\n getSortedVisibleDatasetMetas() {\n return this._getSortedDatasetMetas(true);\n }\n _drawDatasets() {\n if (this.notifyPlugins('beforeDatasetsDraw', {\n cancelable: true\n }) === false) {\n return;\n }\n const metasets = this.getSortedVisibleDatasetMetas();\n for(let i = metasets.length - 1; i >= 0; --i){\n this._drawDataset(metasets[i]);\n }\n this.notifyPlugins('afterDatasetsDraw');\n }\n _drawDataset(meta) {\n const ctx = this.ctx;\n const clip = meta._clip;\n const useClip = !clip.disabled;\n const area = getDatasetArea(meta, this.chartArea);\n const args = {\n meta,\n index: meta.index,\n cancelable: true\n };\n if (this.notifyPlugins('beforeDatasetDraw', args) === false) {\n return;\n }\n if (useClip) {\n clipArea(ctx, {\n left: clip.left === false ? 0 : area.left - clip.left,\n right: clip.right === false ? this.width : area.right + clip.right,\n top: clip.top === false ? 0 : area.top - clip.top,\n bottom: clip.bottom === false ? this.height : area.bottom + clip.bottom\n });\n }\n meta.controller.draw();\n if (useClip) {\n unclipArea(ctx);\n }\n args.cancelable = false;\n this.notifyPlugins('afterDatasetDraw', args);\n }\n isPointInArea(point) {\n return _isPointInArea(point, this.chartArea, this._minPadding);\n }\n getElementsAtEventForMode(e, mode, options, useFinalPosition) {\n const method = Interaction.modes[mode];\n if (typeof method === 'function') {\n return method(this, e, options, useFinalPosition);\n }\n return [];\n }\n getDatasetMeta(datasetIndex) {\n const dataset = this.data.datasets[datasetIndex];\n const metasets = this._metasets;\n let meta = metasets.filter((x)=>x && x._dataset === dataset).pop();\n if (!meta) {\n meta = {\n type: null,\n data: [],\n dataset: null,\n controller: null,\n hidden: null,\n xAxisID: null,\n yAxisID: null,\n order: dataset && dataset.order || 0,\n index: datasetIndex,\n _dataset: dataset,\n _parsed: [],\n _sorted: false\n };\n metasets.push(meta);\n }\n return meta;\n }\n getContext() {\n return this.$context || (this.$context = createContext(null, {\n chart: this,\n type: 'chart'\n }));\n }\n getVisibleDatasetCount() {\n return this.getSortedVisibleDatasetMetas().length;\n }\n isDatasetVisible(datasetIndex) {\n const dataset = this.data.datasets[datasetIndex];\n if (!dataset) {\n return false;\n }\n const meta = this.getDatasetMeta(datasetIndex);\n return typeof meta.hidden === 'boolean' ? !meta.hidden : !dataset.hidden;\n }\n setDatasetVisibility(datasetIndex, visible) {\n const meta = this.getDatasetMeta(datasetIndex);\n meta.hidden = !visible;\n }\n toggleDataVisibility(index) {\n this._hiddenIndices[index] = !this._hiddenIndices[index];\n }\n getDataVisibility(index) {\n return !this._hiddenIndices[index];\n }\n _updateVisibility(datasetIndex, dataIndex, visible) {\n const mode = visible ? 'show' : 'hide';\n const meta = this.getDatasetMeta(datasetIndex);\n const anims = meta.controller._resolveAnimations(undefined, mode);\n if (defined(dataIndex)) {\n meta.data[dataIndex].hidden = !visible;\n this.update();\n } else {\n this.setDatasetVisibility(datasetIndex, visible);\n anims.update(meta, {\n visible\n });\n this.update((ctx)=>ctx.datasetIndex === datasetIndex ? mode : undefined);\n }\n }\n hide(datasetIndex, dataIndex) {\n this._updateVisibility(datasetIndex, dataIndex, false);\n }\n show(datasetIndex, dataIndex) {\n this._updateVisibility(datasetIndex, dataIndex, true);\n }\n _destroyDatasetMeta(datasetIndex) {\n const meta = this._metasets[datasetIndex];\n if (meta && meta.controller) {\n meta.controller._destroy();\n }\n delete this._metasets[datasetIndex];\n }\n _stop() {\n let i, ilen;\n this.stop();\n animator.remove(this);\n for(i = 0, ilen = this.data.datasets.length; i < ilen; ++i){\n this._destroyDatasetMeta(i);\n }\n }\n destroy() {\n this.notifyPlugins('beforeDestroy');\n const { canvas , ctx } = this;\n this._stop();\n this.config.clearCache();\n if (canvas) {\n this.unbindEvents();\n clearCanvas(canvas, ctx);\n this.platform.releaseContext(ctx);\n this.canvas = null;\n this.ctx = null;\n }\n delete instances[this.id];\n this.notifyPlugins('afterDestroy');\n }\n toBase64Image(...args) {\n return this.canvas.toDataURL(...args);\n }\n bindEvents() {\n this.bindUserEvents();\n if (this.options.responsive) {\n this.bindResponsiveEvents();\n } else {\n this.attached = true;\n }\n }\n bindUserEvents() {\n const listeners = this._listeners;\n const platform = this.platform;\n const _add = (type, listener)=>{\n platform.addEventListener(this, type, listener);\n listeners[type] = listener;\n };\n const listener = (e, x, y)=>{\n e.offsetX = x;\n e.offsetY = y;\n this._eventHandler(e);\n };\n each(this.options.events, (type)=>_add(type, listener));\n }\n bindResponsiveEvents() {\n if (!this._responsiveListeners) {\n this._responsiveListeners = {};\n }\n const listeners = this._responsiveListeners;\n const platform = this.platform;\n const _add = (type, listener)=>{\n platform.addEventListener(this, type, listener);\n listeners[type] = listener;\n };\n const _remove = (type, listener)=>{\n if (listeners[type]) {\n platform.removeEventListener(this, type, listener);\n delete listeners[type];\n }\n };\n const listener = (width, height)=>{\n if (this.canvas) {\n this.resize(width, height);\n }\n };\n let detached;\n const attached = ()=>{\n _remove('attach', attached);\n this.attached = true;\n this.resize();\n _add('resize', listener);\n _add('detach', detached);\n };\n detached = ()=>{\n this.attached = false;\n _remove('resize', listener);\n this._stop();\n this._resize(0, 0);\n _add('attach', attached);\n };\n if (platform.isAttached(this.canvas)) {\n attached();\n } else {\n detached();\n }\n }\n unbindEvents() {\n each(this._listeners, (listener, type)=>{\n this.platform.removeEventListener(this, type, listener);\n });\n this._listeners = {};\n each(this._responsiveListeners, (listener, type)=>{\n this.platform.removeEventListener(this, type, listener);\n });\n this._responsiveListeners = undefined;\n }\n updateHoverStyle(items, mode, enabled) {\n const prefix = enabled ? 'set' : 'remove';\n let meta, item, i, ilen;\n if (mode === 'dataset') {\n meta = this.getDatasetMeta(items[0].datasetIndex);\n meta.controller['_' + prefix + 'DatasetHoverStyle']();\n }\n for(i = 0, ilen = items.length; i < ilen; ++i){\n item = items[i];\n const controller = item && this.getDatasetMeta(item.datasetIndex).controller;\n if (controller) {\n controller[prefix + 'HoverStyle'](item.element, item.datasetIndex, item.index);\n }\n }\n }\n getActiveElements() {\n return this._active || [];\n }\n setActiveElements(activeElements) {\n const lastActive = this._active || [];\n const active = activeElements.map(({ datasetIndex , index })=>{\n const meta = this.getDatasetMeta(datasetIndex);\n if (!meta) {\n throw new Error('No dataset found at index ' + datasetIndex);\n }\n return {\n datasetIndex,\n element: meta.data[index],\n index\n };\n });\n const changed = !_elementsEqual(active, lastActive);\n if (changed) {\n this._active = active;\n this._lastEvent = null;\n this._updateHoverStyles(active, lastActive);\n }\n }\n notifyPlugins(hook, args, filter) {\n return this._plugins.notify(this, hook, args, filter);\n }\n isPluginEnabled(pluginId) {\n return this._plugins._cache.filter((p)=>p.plugin.id === pluginId).length === 1;\n }\n _updateHoverStyles(active, lastActive, replay) {\n const hoverOptions = this.options.hover;\n const diff = (a, b)=>a.filter((x)=>!b.some((y)=>x.datasetIndex === y.datasetIndex && x.index === y.index));\n const deactivated = diff(lastActive, active);\n const activated = replay ? active : diff(active, lastActive);\n if (deactivated.length) {\n this.updateHoverStyle(deactivated, hoverOptions.mode, false);\n }\n if (activated.length && hoverOptions.mode) {\n this.updateHoverStyle(activated, hoverOptions.mode, true);\n }\n }\n _eventHandler(e, replay) {\n const args = {\n event: e,\n replay,\n cancelable: true,\n inChartArea: this.isPointInArea(e)\n };\n const eventFilter = (plugin)=>(plugin.options.events || this.options.events).includes(e.native.type);\n if (this.notifyPlugins('beforeEvent', args, eventFilter) === false) {\n return;\n }\n const changed = this._handleEvent(e, replay, args.inChartArea);\n args.cancelable = false;\n this.notifyPlugins('afterEvent', args, eventFilter);\n if (changed || args.changed) {\n this.render();\n }\n return this;\n }\n _handleEvent(e, replay, inChartArea) {\n const { _active: lastActive = [] , options } = this;\n const useFinalPosition = replay;\n const active = this._getActiveElements(e, lastActive, inChartArea, useFinalPosition);\n const isClick = _isClickEvent(e);\n const lastEvent = determineLastEvent(e, this._lastEvent, inChartArea, isClick);\n if (inChartArea) {\n this._lastEvent = null;\n callback(options.onHover, [\n e,\n active,\n this\n ], this);\n if (isClick) {\n callback(options.onClick, [\n e,\n active,\n this\n ], this);\n }\n }\n const changed = !_elementsEqual(active, lastActive);\n if (changed || replay) {\n this._active = active;\n this._updateHoverStyles(active, lastActive, replay);\n }\n this._lastEvent = lastEvent;\n return changed;\n }\n _getActiveElements(e, lastActive, inChartArea, useFinalPosition) {\n if (e.type === 'mouseout') {\n return [];\n }\n if (!inChartArea) {\n return lastActive;\n }\n const hoverOptions = this.options.hover;\n return this.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions, useFinalPosition);\n }\n}\nfunction invalidatePlugins() {\n return each(Chart.instances, (chart)=>chart._plugins.invalidate());\n}\n\nfunction clipArc(ctx, element, endAngle) {\n const { startAngle , pixelMargin , x , y , outerRadius , innerRadius } = element;\n let angleMargin = pixelMargin / outerRadius;\n // Draw an inner border by clipping the arc and drawing a double-width border\n // Enlarge the clipping arc by 0.33 pixels to eliminate glitches between borders\n ctx.beginPath();\n ctx.arc(x, y, outerRadius, startAngle - angleMargin, endAngle + angleMargin);\n if (innerRadius > pixelMargin) {\n angleMargin = pixelMargin / innerRadius;\n ctx.arc(x, y, innerRadius, endAngle + angleMargin, startAngle - angleMargin, true);\n } else {\n ctx.arc(x, y, pixelMargin, endAngle + HALF_PI, startAngle - HALF_PI);\n }\n ctx.closePath();\n ctx.clip();\n}\nfunction toRadiusCorners(value) {\n return _readValueToProps(value, [\n 'outerStart',\n 'outerEnd',\n 'innerStart',\n 'innerEnd'\n ]);\n}\n/**\n * Parse border radius from the provided options\n */ function parseBorderRadius$1(arc, innerRadius, outerRadius, angleDelta) {\n const o = toRadiusCorners(arc.options.borderRadius);\n const halfThickness = (outerRadius - innerRadius) / 2;\n const innerLimit = Math.min(halfThickness, angleDelta * innerRadius / 2);\n // Outer limits are complicated. We want to compute the available angular distance at\n // a radius of outerRadius - borderRadius because for small angular distances, this term limits.\n // We compute at r = outerRadius - borderRadius because this circle defines the center of the border corners.\n //\n // If the borderRadius is large, that value can become negative.\n // This causes the outer borders to lose their radius entirely, which is rather unexpected. To solve that, if borderRadius > outerRadius\n // we know that the thickness term will dominate and compute the limits at that point\n const computeOuterLimit = (val)=>{\n const outerArcLimit = (outerRadius - Math.min(halfThickness, val)) * angleDelta / 2;\n return _limitValue(val, 0, Math.min(halfThickness, outerArcLimit));\n };\n return {\n outerStart: computeOuterLimit(o.outerStart),\n outerEnd: computeOuterLimit(o.outerEnd),\n innerStart: _limitValue(o.innerStart, 0, innerLimit),\n innerEnd: _limitValue(o.innerEnd, 0, innerLimit)\n };\n}\n/**\n * Convert (r, 𝜃) to (x, y)\n */ function rThetaToXY(r, theta, x, y) {\n return {\n x: x + r * Math.cos(theta),\n y: y + r * Math.sin(theta)\n };\n}\n/**\n * Path the arc, respecting border radius by separating into left and right halves.\n *\n * Start End\n *\n * 1---\x3ea---\x3e2 Outer\n * / \\\n * 8 3\n * | |\n * | |\n * 7 4\n * \\ /\n * 6<---b<---5 Inner\n */ function pathArc(ctx, element, offset, spacing, end, circular) {\n const { x , y , startAngle: start , pixelMargin , innerRadius: innerR } = element;\n const outerRadius = Math.max(element.outerRadius + spacing + offset - pixelMargin, 0);\n const innerRadius = innerR > 0 ? innerR + spacing + offset + pixelMargin : 0;\n let spacingOffset = 0;\n const alpha = end - start;\n if (spacing) {\n // When spacing is present, it is the same for all items\n // So we adjust the start and end angle of the arc such that\n // the distance is the same as it would be without the spacing\n const noSpacingInnerRadius = innerR > 0 ? innerR - spacing : 0;\n const noSpacingOuterRadius = outerRadius > 0 ? outerRadius - spacing : 0;\n const avNogSpacingRadius = (noSpacingInnerRadius + noSpacingOuterRadius) / 2;\n const adjustedAngle = avNogSpacingRadius !== 0 ? alpha * avNogSpacingRadius / (avNogSpacingRadius + spacing) : alpha;\n spacingOffset = (alpha - adjustedAngle) / 2;\n }\n const beta = Math.max(0.001, alpha * outerRadius - offset / PI) / outerRadius;\n const angleOffset = (alpha - beta) / 2;\n const startAngle = start + angleOffset + spacingOffset;\n const endAngle = end - angleOffset - spacingOffset;\n const { outerStart , outerEnd , innerStart , innerEnd } = parseBorderRadius$1(element, innerRadius, outerRadius, endAngle - startAngle);\n const outerStartAdjustedRadius = outerRadius - outerStart;\n const outerEndAdjustedRadius = outerRadius - outerEnd;\n const outerStartAdjustedAngle = startAngle + outerStart / outerStartAdjustedRadius;\n const outerEndAdjustedAngle = endAngle - outerEnd / outerEndAdjustedRadius;\n const innerStartAdjustedRadius = innerRadius + innerStart;\n const innerEndAdjustedRadius = innerRadius + innerEnd;\n const innerStartAdjustedAngle = startAngle + innerStart / innerStartAdjustedRadius;\n const innerEndAdjustedAngle = endAngle - innerEnd / innerEndAdjustedRadius;\n ctx.beginPath();\n if (circular) {\n // The first arc segments from point 1 to point a to point 2\n const outerMidAdjustedAngle = (outerStartAdjustedAngle + outerEndAdjustedAngle) / 2;\n ctx.arc(x, y, outerRadius, outerStartAdjustedAngle, outerMidAdjustedAngle);\n ctx.arc(x, y, outerRadius, outerMidAdjustedAngle, outerEndAdjustedAngle);\n // The corner segment from point 2 to point 3\n if (outerEnd > 0) {\n const pCenter = rThetaToXY(outerEndAdjustedRadius, outerEndAdjustedAngle, x, y);\n ctx.arc(pCenter.x, pCenter.y, outerEnd, outerEndAdjustedAngle, endAngle + HALF_PI);\n }\n // The line from point 3 to point 4\n const p4 = rThetaToXY(innerEndAdjustedRadius, endAngle, x, y);\n ctx.lineTo(p4.x, p4.y);\n // The corner segment from point 4 to point 5\n if (innerEnd > 0) {\n const pCenter = rThetaToXY(innerEndAdjustedRadius, innerEndAdjustedAngle, x, y);\n ctx.arc(pCenter.x, pCenter.y, innerEnd, endAngle + HALF_PI, innerEndAdjustedAngle + Math.PI);\n }\n // The inner arc from point 5 to point b to point 6\n const innerMidAdjustedAngle = (endAngle - innerEnd / innerRadius + (startAngle + innerStart / innerRadius)) / 2;\n ctx.arc(x, y, innerRadius, endAngle - innerEnd / innerRadius, innerMidAdjustedAngle, true);\n ctx.arc(x, y, innerRadius, innerMidAdjustedAngle, startAngle + innerStart / innerRadius, true);\n // The corner segment from point 6 to point 7\n if (innerStart > 0) {\n const pCenter = rThetaToXY(innerStartAdjustedRadius, innerStartAdjustedAngle, x, y);\n ctx.arc(pCenter.x, pCenter.y, innerStart, innerStartAdjustedAngle + Math.PI, startAngle - HALF_PI);\n }\n // The line from point 7 to point 8\n const p8 = rThetaToXY(outerStartAdjustedRadius, startAngle, x, y);\n ctx.lineTo(p8.x, p8.y);\n // The corner segment from point 8 to point 1\n if (outerStart > 0) {\n const pCenter = rThetaToXY(outerStartAdjustedRadius, outerStartAdjustedAngle, x, y);\n ctx.arc(pCenter.x, pCenter.y, outerStart, startAngle - HALF_PI, outerStartAdjustedAngle);\n }\n } else {\n ctx.moveTo(x, y);\n const outerStartX = Math.cos(outerStartAdjustedAngle) * outerRadius + x;\n const outerStartY = Math.sin(outerStartAdjustedAngle) * outerRadius + y;\n ctx.lineTo(outerStartX, outerStartY);\n const outerEndX = Math.cos(outerEndAdjustedAngle) * outerRadius + x;\n const outerEndY = Math.sin(outerEndAdjustedAngle) * outerRadius + y;\n ctx.lineTo(outerEndX, outerEndY);\n }\n ctx.closePath();\n}\nfunction drawArc(ctx, element, offset, spacing, circular) {\n const { fullCircles , startAngle , circumference } = element;\n let endAngle = element.endAngle;\n if (fullCircles) {\n pathArc(ctx, element, offset, spacing, endAngle, circular);\n for(let i = 0; i < fullCircles; ++i){\n ctx.fill();\n }\n if (!isNaN(circumference)) {\n endAngle = startAngle + (circumference % TAU || TAU);\n }\n }\n pathArc(ctx, element, offset, spacing, endAngle, circular);\n ctx.fill();\n return endAngle;\n}\nfunction drawBorder(ctx, element, offset, spacing, circular) {\n const { fullCircles , startAngle , circumference , options } = element;\n const { borderWidth , borderJoinStyle , borderDash , borderDashOffset } = options;\n const inner = options.borderAlign === 'inner';\n if (!borderWidth) {\n return;\n }\n ctx.setLineDash(borderDash || []);\n ctx.lineDashOffset = borderDashOffset;\n if (inner) {\n ctx.lineWidth = borderWidth * 2;\n ctx.lineJoin = borderJoinStyle || 'round';\n } else {\n ctx.lineWidth = borderWidth;\n ctx.lineJoin = borderJoinStyle || 'bevel';\n }\n let endAngle = element.endAngle;\n if (fullCircles) {\n pathArc(ctx, element, offset, spacing, endAngle, circular);\n for(let i = 0; i < fullCircles; ++i){\n ctx.stroke();\n }\n if (!isNaN(circumference)) {\n endAngle = startAngle + (circumference % TAU || TAU);\n }\n }\n if (inner) {\n clipArc(ctx, element, endAngle);\n }\n if (!fullCircles) {\n pathArc(ctx, element, offset, spacing, endAngle, circular);\n ctx.stroke();\n }\n}\nclass ArcElement extends Element {\n static id = 'arc';\n static defaults = {\n borderAlign: 'center',\n borderColor: '#fff',\n borderDash: [],\n borderDashOffset: 0,\n borderJoinStyle: undefined,\n borderRadius: 0,\n borderWidth: 2,\n offset: 0,\n spacing: 0,\n angle: undefined,\n circular: true\n };\n static defaultRoutes = {\n backgroundColor: 'backgroundColor'\n };\n static descriptors = {\n _scriptable: true,\n _indexable: (name)=>name !== 'borderDash'\n };\n circumference;\n endAngle;\n fullCircles;\n innerRadius;\n outerRadius;\n pixelMargin;\n startAngle;\n constructor(cfg){\n super();\n this.options = undefined;\n this.circumference = undefined;\n this.startAngle = undefined;\n this.endAngle = undefined;\n this.innerRadius = undefined;\n this.outerRadius = undefined;\n this.pixelMargin = 0;\n this.fullCircles = 0;\n if (cfg) {\n Object.assign(this, cfg);\n }\n }\n inRange(chartX, chartY, useFinalPosition) {\n const point = this.getProps([\n 'x',\n 'y'\n ], useFinalPosition);\n const { angle , distance } = getAngleFromPoint(point, {\n x: chartX,\n y: chartY\n });\n const { startAngle , endAngle , innerRadius , outerRadius , circumference } = this.getProps([\n 'startAngle',\n 'endAngle',\n 'innerRadius',\n 'outerRadius',\n 'circumference'\n ], useFinalPosition);\n const rAdjust = (this.options.spacing + this.options.borderWidth) / 2;\n const _circumference = valueOrDefault(circumference, endAngle - startAngle);\n const nonZeroBetween = _angleBetween(angle, startAngle, endAngle) && startAngle !== endAngle;\n const betweenAngles = _circumference >= TAU || nonZeroBetween;\n const withinRadius = _isBetween(distance, innerRadius + rAdjust, outerRadius + rAdjust);\n return betweenAngles && withinRadius;\n }\n getCenterPoint(useFinalPosition) {\n const { x , y , startAngle , endAngle , innerRadius , outerRadius } = this.getProps([\n 'x',\n 'y',\n 'startAngle',\n 'endAngle',\n 'innerRadius',\n 'outerRadius'\n ], useFinalPosition);\n const { offset , spacing } = this.options;\n const halfAngle = (startAngle + endAngle) / 2;\n const halfRadius = (innerRadius + outerRadius + spacing + offset) / 2;\n return {\n x: x + Math.cos(halfAngle) * halfRadius,\n y: y + Math.sin(halfAngle) * halfRadius\n };\n }\n tooltipPosition(useFinalPosition) {\n return this.getCenterPoint(useFinalPosition);\n }\n draw(ctx) {\n const { options , circumference } = this;\n const offset = (options.offset || 0) / 4;\n const spacing = (options.spacing || 0) / 2;\n const circular = options.circular;\n this.pixelMargin = options.borderAlign === 'inner' ? 0.33 : 0;\n this.fullCircles = circumference > TAU ? Math.floor(circumference / TAU) : 0;\n if (circumference === 0 || this.innerRadius < 0 || this.outerRadius < 0) {\n return;\n }\n ctx.save();\n const halfAngle = (this.startAngle + this.endAngle) / 2;\n ctx.translate(Math.cos(halfAngle) * offset, Math.sin(halfAngle) * offset);\n const fix = 1 - Math.sin(Math.min(PI, circumference || 0));\n const radiusOffset = offset * fix;\n ctx.fillStyle = options.backgroundColor;\n ctx.strokeStyle = options.borderColor;\n drawArc(ctx, this, radiusOffset, spacing, circular);\n drawBorder(ctx, this, radiusOffset, spacing, circular);\n ctx.restore();\n }\n}\n\nfunction setStyle(ctx, options, style = options) {\n ctx.lineCap = valueOrDefault(style.borderCapStyle, options.borderCapStyle);\n ctx.setLineDash(valueOrDefault(style.borderDash, options.borderDash));\n ctx.lineDashOffset = valueOrDefault(style.borderDashOffset, options.borderDashOffset);\n ctx.lineJoin = valueOrDefault(style.borderJoinStyle, options.borderJoinStyle);\n ctx.lineWidth = valueOrDefault(style.borderWidth, options.borderWidth);\n ctx.strokeStyle = valueOrDefault(style.borderColor, options.borderColor);\n}\nfunction lineTo(ctx, previous, target) {\n ctx.lineTo(target.x, target.y);\n}\n function getLineMethod(options) {\n if (options.stepped) {\n return _steppedLineTo;\n }\n if (options.tension || options.cubicInterpolationMode === 'monotone') {\n return _bezierCurveTo;\n }\n return lineTo;\n}\nfunction pathVars(points, segment, params = {}) {\n const count = points.length;\n const { start: paramsStart = 0 , end: paramsEnd = count - 1 } = params;\n const { start: segmentStart , end: segmentEnd } = segment;\n const start = Math.max(paramsStart, segmentStart);\n const end = Math.min(paramsEnd, segmentEnd);\n const outside = paramsStart < segmentStart && paramsEnd < segmentStart || paramsStart > segmentEnd && paramsEnd > segmentEnd;\n return {\n count,\n start,\n loop: segment.loop,\n ilen: end < start && !outside ? count + end - start : end - start\n };\n}\n function pathSegment(ctx, line, segment, params) {\n const { points , options } = line;\n const { count , start , loop , ilen } = pathVars(points, segment, params);\n const lineMethod = getLineMethod(options);\n let { move =true , reverse } = params || {};\n let i, point, prev;\n for(i = 0; i <= ilen; ++i){\n point = points[(start + (reverse ? ilen - i : i)) % count];\n if (point.skip) {\n continue;\n } else if (move) {\n ctx.moveTo(point.x, point.y);\n move = false;\n } else {\n lineMethod(ctx, prev, point, reverse, options.stepped);\n }\n prev = point;\n }\n if (loop) {\n point = points[(start + (reverse ? ilen : 0)) % count];\n lineMethod(ctx, prev, point, reverse, options.stepped);\n }\n return !!loop;\n}\n function fastPathSegment(ctx, line, segment, params) {\n const points = line.points;\n const { count , start , ilen } = pathVars(points, segment, params);\n const { move =true , reverse } = params || {};\n let avgX = 0;\n let countX = 0;\n let i, point, prevX, minY, maxY, lastY;\n const pointIndex = (index)=>(start + (reverse ? ilen - index : index)) % count;\n const drawX = ()=>{\n if (minY !== maxY) {\n ctx.lineTo(avgX, maxY);\n ctx.lineTo(avgX, minY);\n ctx.lineTo(avgX, lastY);\n }\n };\n if (move) {\n point = points[pointIndex(0)];\n ctx.moveTo(point.x, point.y);\n }\n for(i = 0; i <= ilen; ++i){\n point = points[pointIndex(i)];\n if (point.skip) {\n continue;\n }\n const x = point.x;\n const y = point.y;\n const truncX = x | 0;\n if (truncX === prevX) {\n if (y < minY) {\n minY = y;\n } else if (y > maxY) {\n maxY = y;\n }\n avgX = (countX * avgX + x) / ++countX;\n } else {\n drawX();\n ctx.lineTo(x, y);\n prevX = truncX;\n countX = 0;\n minY = maxY = y;\n }\n lastY = y;\n }\n drawX();\n}\n function _getSegmentMethod(line) {\n const opts = line.options;\n const borderDash = opts.borderDash && opts.borderDash.length;\n const useFastPath = !line._decimated && !line._loop && !opts.tension && opts.cubicInterpolationMode !== 'monotone' && !opts.stepped && !borderDash;\n return useFastPath ? fastPathSegment : pathSegment;\n}\n function _getInterpolationMethod(options) {\n if (options.stepped) {\n return _steppedInterpolation;\n }\n if (options.tension || options.cubicInterpolationMode === 'monotone') {\n return _bezierInterpolation;\n }\n return _pointInLine;\n}\nfunction strokePathWithCache(ctx, line, start, count) {\n let path = line._path;\n if (!path) {\n path = line._path = new Path2D();\n if (line.path(path, start, count)) {\n path.closePath();\n }\n }\n setStyle(ctx, line.options);\n ctx.stroke(path);\n}\nfunction strokePathDirect(ctx, line, start, count) {\n const { segments , options } = line;\n const segmentMethod = _getSegmentMethod(line);\n for (const segment of segments){\n setStyle(ctx, options, segment.style);\n ctx.beginPath();\n if (segmentMethod(ctx, line, segment, {\n start,\n end: start + count - 1\n })) {\n ctx.closePath();\n }\n ctx.stroke();\n }\n}\nconst usePath2D = typeof Path2D === 'function';\nfunction draw(ctx, line, start, count) {\n if (usePath2D && !line.options.segment) {\n strokePathWithCache(ctx, line, start, count);\n } else {\n strokePathDirect(ctx, line, start, count);\n }\n}\nclass LineElement extends Element {\n static id = 'line';\n static defaults = {\n borderCapStyle: 'butt',\n borderDash: [],\n borderDashOffset: 0,\n borderJoinStyle: 'miter',\n borderWidth: 3,\n capBezierPoints: true,\n cubicInterpolationMode: 'default',\n fill: false,\n spanGaps: false,\n stepped: false,\n tension: 0\n };\n static defaultRoutes = {\n backgroundColor: 'backgroundColor',\n borderColor: 'borderColor'\n };\n static descriptors = {\n _scriptable: true,\n _indexable: (name)=>name !== 'borderDash' && name !== 'fill'\n };\n constructor(cfg){\n super();\n this.animated = true;\n this.options = undefined;\n this._chart = undefined;\n this._loop = undefined;\n this._fullLoop = undefined;\n this._path = undefined;\n this._points = undefined;\n this._segments = undefined;\n this._decimated = false;\n this._pointsUpdated = false;\n this._datasetIndex = undefined;\n if (cfg) {\n Object.assign(this, cfg);\n }\n }\n updateControlPoints(chartArea, indexAxis) {\n const options = this.options;\n if ((options.tension || options.cubicInterpolationMode === 'monotone') && !options.stepped && !this._pointsUpdated) {\n const loop = options.spanGaps ? this._loop : this._fullLoop;\n _updateBezierControlPoints(this._points, options, chartArea, loop, indexAxis);\n this._pointsUpdated = true;\n }\n }\n set points(points) {\n this._points = points;\n delete this._segments;\n delete this._path;\n this._pointsUpdated = false;\n }\n get points() {\n return this._points;\n }\n get segments() {\n return this._segments || (this._segments = _computeSegments(this, this.options.segment));\n }\n first() {\n const segments = this.segments;\n const points = this.points;\n return segments.length && points[segments[0].start];\n }\n last() {\n const segments = this.segments;\n const points = this.points;\n const count = segments.length;\n return count && points[segments[count - 1].end];\n }\n interpolate(point, property) {\n const options = this.options;\n const value = point[property];\n const points = this.points;\n const segments = _boundSegments(this, {\n property,\n start: value,\n end: value\n });\n if (!segments.length) {\n return;\n }\n const result = [];\n const _interpolate = _getInterpolationMethod(options);\n let i, ilen;\n for(i = 0, ilen = segments.length; i < ilen; ++i){\n const { start , end } = segments[i];\n const p1 = points[start];\n const p2 = points[end];\n if (p1 === p2) {\n result.push(p1);\n continue;\n }\n const t = Math.abs((value - p1[property]) / (p2[property] - p1[property]));\n const interpolated = _interpolate(p1, p2, t, options.stepped);\n interpolated[property] = point[property];\n result.push(interpolated);\n }\n return result.length === 1 ? result[0] : result;\n }\n pathSegment(ctx, segment, params) {\n const segmentMethod = _getSegmentMethod(this);\n return segmentMethod(ctx, this, segment, params);\n }\n path(ctx, start, count) {\n const segments = this.segments;\n const segmentMethod = _getSegmentMethod(this);\n let loop = this._loop;\n start = start || 0;\n count = count || this.points.length - start;\n for (const segment of segments){\n loop &= segmentMethod(ctx, this, segment, {\n start,\n end: start + count - 1\n });\n }\n return !!loop;\n }\n draw(ctx, chartArea, start, count) {\n const options = this.options || {};\n const points = this.points || [];\n if (points.length && options.borderWidth) {\n ctx.save();\n draw(ctx, this, start, count);\n ctx.restore();\n }\n if (this.animated) {\n this._pointsUpdated = false;\n this._path = undefined;\n }\n }\n}\n\nfunction inRange$1(el, pos, axis, useFinalPosition) {\n const options = el.options;\n const { [axis]: value } = el.getProps([\n axis\n ], useFinalPosition);\n return Math.abs(pos - value) < options.radius + options.hitRadius;\n}\nclass PointElement extends Element {\n static id = 'point';\n parsed;\n skip;\n stop;\n /**\n * @type {any}\n */ static defaults = {\n borderWidth: 1,\n hitRadius: 1,\n hoverBorderWidth: 1,\n hoverRadius: 4,\n pointStyle: 'circle',\n radius: 3,\n rotation: 0\n };\n /**\n * @type {any}\n */ static defaultRoutes = {\n backgroundColor: 'backgroundColor',\n borderColor: 'borderColor'\n };\n constructor(cfg){\n super();\n this.options = undefined;\n this.parsed = undefined;\n this.skip = undefined;\n this.stop = undefined;\n if (cfg) {\n Object.assign(this, cfg);\n }\n }\n inRange(mouseX, mouseY, useFinalPosition) {\n const options = this.options;\n const { x , y } = this.getProps([\n 'x',\n 'y'\n ], useFinalPosition);\n return Math.pow(mouseX - x, 2) + Math.pow(mouseY - y, 2) < Math.pow(options.hitRadius + options.radius, 2);\n }\n inXRange(mouseX, useFinalPosition) {\n return inRange$1(this, mouseX, 'x', useFinalPosition);\n }\n inYRange(mouseY, useFinalPosition) {\n return inRange$1(this, mouseY, 'y', useFinalPosition);\n }\n getCenterPoint(useFinalPosition) {\n const { x , y } = this.getProps([\n 'x',\n 'y'\n ], useFinalPosition);\n return {\n x,\n y\n };\n }\n size(options) {\n options = options || this.options || {};\n let radius = options.radius || 0;\n radius = Math.max(radius, radius && options.hoverRadius || 0);\n const borderWidth = radius && options.borderWidth || 0;\n return (radius + borderWidth) * 2;\n }\n draw(ctx, area) {\n const options = this.options;\n if (this.skip || options.radius < 0.1 || !_isPointInArea(this, area, this.size(options) / 2)) {\n return;\n }\n ctx.strokeStyle = options.borderColor;\n ctx.lineWidth = options.borderWidth;\n ctx.fillStyle = options.backgroundColor;\n drawPoint(ctx, options, this.x, this.y);\n }\n getRange() {\n const options = this.options || {};\n // @ts-expect-error Fallbacks should never be hit in practice\n return options.radius + options.hitRadius;\n }\n}\n\nfunction getBarBounds(bar, useFinalPosition) {\n const { x , y , base , width , height } = bar.getProps([\n 'x',\n 'y',\n 'base',\n 'width',\n 'height'\n ], useFinalPosition);\n let left, right, top, bottom, half;\n if (bar.horizontal) {\n half = height / 2;\n left = Math.min(x, base);\n right = Math.max(x, base);\n top = y - half;\n bottom = y + half;\n } else {\n half = width / 2;\n left = x - half;\n right = x + half;\n top = Math.min(y, base);\n bottom = Math.max(y, base);\n }\n return {\n left,\n top,\n right,\n bottom\n };\n}\nfunction skipOrLimit(skip, value, min, max) {\n return skip ? 0 : _limitValue(value, min, max);\n}\nfunction parseBorderWidth(bar, maxW, maxH) {\n const value = bar.options.borderWidth;\n const skip = bar.borderSkipped;\n const o = toTRBL(value);\n return {\n t: skipOrLimit(skip.top, o.top, 0, maxH),\n r: skipOrLimit(skip.right, o.right, 0, maxW),\n b: skipOrLimit(skip.bottom, o.bottom, 0, maxH),\n l: skipOrLimit(skip.left, o.left, 0, maxW)\n };\n}\nfunction parseBorderRadius(bar, maxW, maxH) {\n const { enableBorderRadius } = bar.getProps([\n 'enableBorderRadius'\n ]);\n const value = bar.options.borderRadius;\n const o = toTRBLCorners(value);\n const maxR = Math.min(maxW, maxH);\n const skip = bar.borderSkipped;\n const enableBorder = enableBorderRadius || isObject(value);\n return {\n topLeft: skipOrLimit(!enableBorder || skip.top || skip.left, o.topLeft, 0, maxR),\n topRight: skipOrLimit(!enableBorder || skip.top || skip.right, o.topRight, 0, maxR),\n bottomLeft: skipOrLimit(!enableBorder || skip.bottom || skip.left, o.bottomLeft, 0, maxR),\n bottomRight: skipOrLimit(!enableBorder || skip.bottom || skip.right, o.bottomRight, 0, maxR)\n };\n}\nfunction boundingRects(bar) {\n const bounds = getBarBounds(bar);\n const width = bounds.right - bounds.left;\n const height = bounds.bottom - bounds.top;\n const border = parseBorderWidth(bar, width / 2, height / 2);\n const radius = parseBorderRadius(bar, width / 2, height / 2);\n return {\n outer: {\n x: bounds.left,\n y: bounds.top,\n w: width,\n h: height,\n radius\n },\n inner: {\n x: bounds.left + border.l,\n y: bounds.top + border.t,\n w: width - border.l - border.r,\n h: height - border.t - border.b,\n radius: {\n topLeft: Math.max(0, radius.topLeft - Math.max(border.t, border.l)),\n topRight: Math.max(0, radius.topRight - Math.max(border.t, border.r)),\n bottomLeft: Math.max(0, radius.bottomLeft - Math.max(border.b, border.l)),\n bottomRight: Math.max(0, radius.bottomRight - Math.max(border.b, border.r))\n }\n }\n };\n}\nfunction inRange(bar, x, y, useFinalPosition) {\n const skipX = x === null;\n const skipY = y === null;\n const skipBoth = skipX && skipY;\n const bounds = bar && !skipBoth && getBarBounds(bar, useFinalPosition);\n return bounds && (skipX || _isBetween(x, bounds.left, bounds.right)) && (skipY || _isBetween(y, bounds.top, bounds.bottom));\n}\nfunction hasRadius(radius) {\n return radius.topLeft || radius.topRight || radius.bottomLeft || radius.bottomRight;\n}\n function addNormalRectPath(ctx, rect) {\n ctx.rect(rect.x, rect.y, rect.w, rect.h);\n}\nfunction inflateRect(rect, amount, refRect = {}) {\n const x = rect.x !== refRect.x ? -amount : 0;\n const y = rect.y !== refRect.y ? -amount : 0;\n const w = (rect.x + rect.w !== refRect.x + refRect.w ? amount : 0) - x;\n const h = (rect.y + rect.h !== refRect.y + refRect.h ? amount : 0) - y;\n return {\n x: rect.x + x,\n y: rect.y + y,\n w: rect.w + w,\n h: rect.h + h,\n radius: rect.radius\n };\n}\nclass BarElement extends Element {\n static id = 'bar';\n static defaults = {\n borderSkipped: 'start',\n borderWidth: 0,\n borderRadius: 0,\n inflateAmount: 'auto',\n pointStyle: undefined\n };\n static defaultRoutes = {\n backgroundColor: 'backgroundColor',\n borderColor: 'borderColor'\n };\n constructor(cfg){\n super();\n this.options = undefined;\n this.horizontal = undefined;\n this.base = undefined;\n this.width = undefined;\n this.height = undefined;\n this.inflateAmount = undefined;\n if (cfg) {\n Object.assign(this, cfg);\n }\n }\n draw(ctx) {\n const { inflateAmount , options: { borderColor , backgroundColor } } = this;\n const { inner , outer } = boundingRects(this);\n const addRectPath = hasRadius(outer.radius) ? addRoundedRectPath : addNormalRectPath;\n ctx.save();\n if (outer.w !== inner.w || outer.h !== inner.h) {\n ctx.beginPath();\n addRectPath(ctx, inflateRect(outer, inflateAmount, inner));\n ctx.clip();\n addRectPath(ctx, inflateRect(inner, -inflateAmount, outer));\n ctx.fillStyle = borderColor;\n ctx.fill('evenodd');\n }\n ctx.beginPath();\n addRectPath(ctx, inflateRect(inner, inflateAmount));\n ctx.fillStyle = backgroundColor;\n ctx.fill();\n ctx.restore();\n }\n inRange(mouseX, mouseY, useFinalPosition) {\n return inRange(this, mouseX, mouseY, useFinalPosition);\n }\n inXRange(mouseX, useFinalPosition) {\n return inRange(this, mouseX, null, useFinalPosition);\n }\n inYRange(mouseY, useFinalPosition) {\n return inRange(this, null, mouseY, useFinalPosition);\n }\n getCenterPoint(useFinalPosition) {\n const { x , y , base , horizontal } = this.getProps([\n 'x',\n 'y',\n 'base',\n 'horizontal'\n ], useFinalPosition);\n return {\n x: horizontal ? (x + base) / 2 : x,\n y: horizontal ? y : (y + base) / 2\n };\n }\n getRange(axis) {\n return axis === 'x' ? this.width / 2 : this.height / 2;\n }\n}\n\nvar chart_elements = /*#__PURE__*/Object.freeze({\n__proto__: null,\nArcElement: ArcElement,\nBarElement: BarElement,\nLineElement: LineElement,\nPointElement: PointElement\n});\n\nconst BORDER_COLORS = [\n 'rgb(54, 162, 235)',\n 'rgb(255, 99, 132)',\n 'rgb(255, 159, 64)',\n 'rgb(255, 205, 86)',\n 'rgb(75, 192, 192)',\n 'rgb(153, 102, 255)',\n 'rgb(201, 203, 207)' // grey\n];\n// Border colors with 50% transparency\nconst BACKGROUND_COLORS = /* #__PURE__ */ BORDER_COLORS.map((color)=>color.replace('rgb(', 'rgba(').replace(')', ', 0.5)'));\nfunction getBorderColor(i) {\n return BORDER_COLORS[i % BORDER_COLORS.length];\n}\nfunction getBackgroundColor(i) {\n return BACKGROUND_COLORS[i % BACKGROUND_COLORS.length];\n}\nfunction colorizeDefaultDataset(dataset, i) {\n dataset.borderColor = getBorderColor(i);\n dataset.backgroundColor = getBackgroundColor(i);\n return ++i;\n}\nfunction colorizeDoughnutDataset(dataset, i) {\n dataset.backgroundColor = dataset.data.map(()=>getBorderColor(i++));\n return i;\n}\nfunction colorizePolarAreaDataset(dataset, i) {\n dataset.backgroundColor = dataset.data.map(()=>getBackgroundColor(i++));\n return i;\n}\nfunction getColorizer(chart) {\n let i = 0;\n return (dataset, datasetIndex)=>{\n const controller = chart.getDatasetMeta(datasetIndex).controller;\n if (controller instanceof DoughnutController) {\n i = colorizeDoughnutDataset(dataset, i);\n } else if (controller instanceof PolarAreaController) {\n i = colorizePolarAreaDataset(dataset, i);\n } else if (controller) {\n i = colorizeDefaultDataset(dataset, i);\n }\n };\n}\nfunction containsColorsDefinitions(descriptors) {\n let k;\n for(k in descriptors){\n if (descriptors[k].borderColor || descriptors[k].backgroundColor) {\n return true;\n }\n }\n return false;\n}\nfunction containsColorsDefinition(descriptor) {\n return descriptor && (descriptor.borderColor || descriptor.backgroundColor);\n}\nvar plugin_colors = {\n id: 'colors',\n defaults: {\n enabled: true,\n forceOverride: false\n },\n beforeLayout (chart, _args, options) {\n if (!options.enabled) {\n return;\n }\n const { data: { datasets } , options: chartOptions } = chart.config;\n const { elements } = chartOptions;\n if (!options.forceOverride && (containsColorsDefinitions(datasets) || containsColorsDefinition(chartOptions) || elements && containsColorsDefinitions(elements))) {\n return;\n }\n const colorizer = getColorizer(chart);\n datasets.forEach(colorizer);\n }\n};\n\nfunction lttbDecimation(data, start, count, availableWidth, options) {\n const samples = options.samples || availableWidth;\n if (samples >= count) {\n return data.slice(start, start + count);\n }\n const decimated = [];\n const bucketWidth = (count - 2) / (samples - 2);\n let sampledIndex = 0;\n const endIndex = start + count - 1;\n let a = start;\n let i, maxAreaPoint, maxArea, area, nextA;\n decimated[sampledIndex++] = data[a];\n for(i = 0; i < samples - 2; i++){\n let avgX = 0;\n let avgY = 0;\n let j;\n const avgRangeStart = Math.floor((i + 1) * bucketWidth) + 1 + start;\n const avgRangeEnd = Math.min(Math.floor((i + 2) * bucketWidth) + 1, count) + start;\n const avgRangeLength = avgRangeEnd - avgRangeStart;\n for(j = avgRangeStart; j < avgRangeEnd; j++){\n avgX += data[j].x;\n avgY += data[j].y;\n }\n avgX /= avgRangeLength;\n avgY /= avgRangeLength;\n const rangeOffs = Math.floor(i * bucketWidth) + 1 + start;\n const rangeTo = Math.min(Math.floor((i + 1) * bucketWidth) + 1, count) + start;\n const { x: pointAx , y: pointAy } = data[a];\n maxArea = area = -1;\n for(j = rangeOffs; j < rangeTo; j++){\n area = 0.5 * Math.abs((pointAx - avgX) * (data[j].y - pointAy) - (pointAx - data[j].x) * (avgY - pointAy));\n if (area > maxArea) {\n maxArea = area;\n maxAreaPoint = data[j];\n nextA = j;\n }\n }\n decimated[sampledIndex++] = maxAreaPoint;\n a = nextA;\n }\n decimated[sampledIndex++] = data[endIndex];\n return decimated;\n}\nfunction minMaxDecimation(data, start, count, availableWidth) {\n let avgX = 0;\n let countX = 0;\n let i, point, x, y, prevX, minIndex, maxIndex, startIndex, minY, maxY;\n const decimated = [];\n const endIndex = start + count - 1;\n const xMin = data[start].x;\n const xMax = data[endIndex].x;\n const dx = xMax - xMin;\n for(i = start; i < start + count; ++i){\n point = data[i];\n x = (point.x - xMin) / dx * availableWidth;\n y = point.y;\n const truncX = x | 0;\n if (truncX === prevX) {\n if (y < minY) {\n minY = y;\n minIndex = i;\n } else if (y > maxY) {\n maxY = y;\n maxIndex = i;\n }\n avgX = (countX * avgX + point.x) / ++countX;\n } else {\n const lastIndex = i - 1;\n if (!isNullOrUndef(minIndex) && !isNullOrUndef(maxIndex)) {\n const intermediateIndex1 = Math.min(minIndex, maxIndex);\n const intermediateIndex2 = Math.max(minIndex, maxIndex);\n if (intermediateIndex1 !== startIndex && intermediateIndex1 !== lastIndex) {\n decimated.push({\n ...data[intermediateIndex1],\n x: avgX\n });\n }\n if (intermediateIndex2 !== startIndex && intermediateIndex2 !== lastIndex) {\n decimated.push({\n ...data[intermediateIndex2],\n x: avgX\n });\n }\n }\n if (i > 0 && lastIndex !== startIndex) {\n decimated.push(data[lastIndex]);\n }\n decimated.push(point);\n prevX = truncX;\n countX = 0;\n minY = maxY = y;\n minIndex = maxIndex = startIndex = i;\n }\n }\n return decimated;\n}\nfunction cleanDecimatedDataset(dataset) {\n if (dataset._decimated) {\n const data = dataset._data;\n delete dataset._decimated;\n delete dataset._data;\n Object.defineProperty(dataset, 'data', {\n configurable: true,\n enumerable: true,\n writable: true,\n value: data\n });\n }\n}\nfunction cleanDecimatedData(chart) {\n chart.data.datasets.forEach((dataset)=>{\n cleanDecimatedDataset(dataset);\n });\n}\nfunction getStartAndCountOfVisiblePointsSimplified(meta, points) {\n const pointCount = points.length;\n let start = 0;\n let count;\n const { iScale } = meta;\n const { min , max , minDefined , maxDefined } = iScale.getUserBounds();\n if (minDefined) {\n start = _limitValue(_lookupByKey(points, iScale.axis, min).lo, 0, pointCount - 1);\n }\n if (maxDefined) {\n count = _limitValue(_lookupByKey(points, iScale.axis, max).hi + 1, start, pointCount) - start;\n } else {\n count = pointCount - start;\n }\n return {\n start,\n count\n };\n}\nvar plugin_decimation = {\n id: 'decimation',\n defaults: {\n algorithm: 'min-max',\n enabled: false\n },\n beforeElementsUpdate: (chart, args, options)=>{\n if (!options.enabled) {\n cleanDecimatedData(chart);\n return;\n }\n const availableWidth = chart.width;\n chart.data.datasets.forEach((dataset, datasetIndex)=>{\n const { _data , indexAxis } = dataset;\n const meta = chart.getDatasetMeta(datasetIndex);\n const data = _data || dataset.data;\n if (resolve([\n indexAxis,\n chart.options.indexAxis\n ]) === 'y') {\n return;\n }\n if (!meta.controller.supportsDecimation) {\n return;\n }\n const xAxis = chart.scales[meta.xAxisID];\n if (xAxis.type !== 'linear' && xAxis.type !== 'time') {\n return;\n }\n if (chart.options.parsing) {\n return;\n }\n let { start , count } = getStartAndCountOfVisiblePointsSimplified(meta, data);\n const threshold = options.threshold || 4 * availableWidth;\n if (count <= threshold) {\n cleanDecimatedDataset(dataset);\n return;\n }\n if (isNullOrUndef(_data)) {\n dataset._data = data;\n delete dataset.data;\n Object.defineProperty(dataset, 'data', {\n configurable: true,\n enumerable: true,\n get: function() {\n return this._decimated;\n },\n set: function(d) {\n this._data = d;\n }\n });\n }\n let decimated;\n switch(options.algorithm){\n case 'lttb':\n decimated = lttbDecimation(data, start, count, availableWidth, options);\n break;\n case 'min-max':\n decimated = minMaxDecimation(data, start, count, availableWidth);\n break;\n default:\n throw new Error(`Unsupported decimation algorithm '${options.algorithm}'`);\n }\n dataset._decimated = decimated;\n });\n },\n destroy (chart) {\n cleanDecimatedData(chart);\n }\n};\n\nfunction _segments(line, target, property) {\n const segments = line.segments;\n const points = line.points;\n const tpoints = target.points;\n const parts = [];\n for (const segment of segments){\n let { start , end } = segment;\n end = _findSegmentEnd(start, end, points);\n const bounds = _getBounds(property, points[start], points[end], segment.loop);\n if (!target.segments) {\n parts.push({\n source: segment,\n target: bounds,\n start: points[start],\n end: points[end]\n });\n continue;\n }\n const targetSegments = _boundSegments(target, bounds);\n for (const tgt of targetSegments){\n const subBounds = _getBounds(property, tpoints[tgt.start], tpoints[tgt.end], tgt.loop);\n const fillSources = _boundSegment(segment, points, subBounds);\n for (const fillSource of fillSources){\n parts.push({\n source: fillSource,\n target: tgt,\n start: {\n [property]: _getEdge(bounds, subBounds, 'start', Math.max)\n },\n end: {\n [property]: _getEdge(bounds, subBounds, 'end', Math.min)\n }\n });\n }\n }\n }\n return parts;\n}\nfunction _getBounds(property, first, last, loop) {\n if (loop) {\n return;\n }\n let start = first[property];\n let end = last[property];\n if (property === 'angle') {\n start = _normalizeAngle(start);\n end = _normalizeAngle(end);\n }\n return {\n property,\n start,\n end\n };\n}\nfunction _pointsFromSegments(boundary, line) {\n const { x =null , y =null } = boundary || {};\n const linePoints = line.points;\n const points = [];\n line.segments.forEach(({ start , end })=>{\n end = _findSegmentEnd(start, end, linePoints);\n const first = linePoints[start];\n const last = linePoints[end];\n if (y !== null) {\n points.push({\n x: first.x,\n y\n });\n points.push({\n x: last.x,\n y\n });\n } else if (x !== null) {\n points.push({\n x,\n y: first.y\n });\n points.push({\n x,\n y: last.y\n });\n }\n });\n return points;\n}\nfunction _findSegmentEnd(start, end, points) {\n for(; end > start; end--){\n const point = points[end];\n if (!isNaN(point.x) && !isNaN(point.y)) {\n break;\n }\n }\n return end;\n}\nfunction _getEdge(a, b, prop, fn) {\n if (a && b) {\n return fn(a[prop], b[prop]);\n }\n return a ? a[prop] : b ? b[prop] : 0;\n}\n\nfunction _createBoundaryLine(boundary, line) {\n let points = [];\n let _loop = false;\n if (isArray(boundary)) {\n _loop = true;\n points = boundary;\n } else {\n points = _pointsFromSegments(boundary, line);\n }\n return points.length ? new LineElement({\n points,\n options: {\n tension: 0\n },\n _loop,\n _fullLoop: _loop\n }) : null;\n}\nfunction _shouldApplyFill(source) {\n return source && source.fill !== false;\n}\n\nfunction _resolveTarget(sources, index, propagate) {\n const source = sources[index];\n let fill = source.fill;\n const visited = [\n index\n ];\n let target;\n if (!propagate) {\n return fill;\n }\n while(fill !== false && visited.indexOf(fill) === -1){\n if (!isNumberFinite(fill)) {\n return fill;\n }\n target = sources[fill];\n if (!target) {\n return false;\n }\n if (target.visible) {\n return fill;\n }\n visited.push(fill);\n fill = target.fill;\n }\n return false;\n}\n function _decodeFill(line, index, count) {\n const fill = parseFillOption(line);\n if (isObject(fill)) {\n return isNaN(fill.value) ? false : fill;\n }\n let target = parseFloat(fill);\n if (isNumberFinite(target) && Math.floor(target) === target) {\n return decodeTargetIndex(fill[0], index, target, count);\n }\n return [\n 'origin',\n 'start',\n 'end',\n 'stack',\n 'shape'\n ].indexOf(fill) >= 0 && fill;\n}\nfunction decodeTargetIndex(firstCh, index, target, count) {\n if (firstCh === '-' || firstCh === '+') {\n target = index + target;\n }\n if (target === index || target < 0 || target >= count) {\n return false;\n }\n return target;\n}\n function _getTargetPixel(fill, scale) {\n let pixel = null;\n if (fill === 'start') {\n pixel = scale.bottom;\n } else if (fill === 'end') {\n pixel = scale.top;\n } else if (isObject(fill)) {\n pixel = scale.getPixelForValue(fill.value);\n } else if (scale.getBasePixel) {\n pixel = scale.getBasePixel();\n }\n return pixel;\n}\n function _getTargetValue(fill, scale, startValue) {\n let value;\n if (fill === 'start') {\n value = startValue;\n } else if (fill === 'end') {\n value = scale.options.reverse ? scale.min : scale.max;\n } else if (isObject(fill)) {\n value = fill.value;\n } else {\n value = scale.getBaseValue();\n }\n return value;\n}\n function parseFillOption(line) {\n const options = line.options;\n const fillOption = options.fill;\n let fill = valueOrDefault(fillOption && fillOption.target, fillOption);\n if (fill === undefined) {\n fill = !!options.backgroundColor;\n }\n if (fill === false || fill === null) {\n return false;\n }\n if (fill === true) {\n return 'origin';\n }\n return fill;\n}\n\nfunction _buildStackLine(source) {\n const { scale , index , line } = source;\n const points = [];\n const segments = line.segments;\n const sourcePoints = line.points;\n const linesBelow = getLinesBelow(scale, index);\n linesBelow.push(_createBoundaryLine({\n x: null,\n y: scale.bottom\n }, line));\n for(let i = 0; i < segments.length; i++){\n const segment = segments[i];\n for(let j = segment.start; j <= segment.end; j++){\n addPointsBelow(points, sourcePoints[j], linesBelow);\n }\n }\n return new LineElement({\n points,\n options: {}\n });\n}\n function getLinesBelow(scale, index) {\n const below = [];\n const metas = scale.getMatchingVisibleMetas('line');\n for(let i = 0; i < metas.length; i++){\n const meta = metas[i];\n if (meta.index === index) {\n break;\n }\n if (!meta.hidden) {\n below.unshift(meta.dataset);\n }\n }\n return below;\n}\n function addPointsBelow(points, sourcePoint, linesBelow) {\n const postponed = [];\n for(let j = 0; j < linesBelow.length; j++){\n const line = linesBelow[j];\n const { first , last , point } = findPoint(line, sourcePoint, 'x');\n if (!point || first && last) {\n continue;\n }\n if (first) {\n postponed.unshift(point);\n } else {\n points.push(point);\n if (!last) {\n break;\n }\n }\n }\n points.push(...postponed);\n}\n function findPoint(line, sourcePoint, property) {\n const point = line.interpolate(sourcePoint, property);\n if (!point) {\n return {};\n }\n const pointValue = point[property];\n const segments = line.segments;\n const linePoints = line.points;\n let first = false;\n let last = false;\n for(let i = 0; i < segments.length; i++){\n const segment = segments[i];\n const firstValue = linePoints[segment.start][property];\n const lastValue = linePoints[segment.end][property];\n if (_isBetween(pointValue, firstValue, lastValue)) {\n first = pointValue === firstValue;\n last = pointValue === lastValue;\n break;\n }\n }\n return {\n first,\n last,\n point\n };\n}\n\nclass simpleArc {\n constructor(opts){\n this.x = opts.x;\n this.y = opts.y;\n this.radius = opts.radius;\n }\n pathSegment(ctx, bounds, opts) {\n const { x , y , radius } = this;\n bounds = bounds || {\n start: 0,\n end: TAU\n };\n ctx.arc(x, y, radius, bounds.end, bounds.start, true);\n return !opts.bounds;\n }\n interpolate(point) {\n const { x , y , radius } = this;\n const angle = point.angle;\n return {\n x: x + Math.cos(angle) * radius,\n y: y + Math.sin(angle) * radius,\n angle\n };\n }\n}\n\nfunction _getTarget(source) {\n const { chart , fill , line } = source;\n if (isNumberFinite(fill)) {\n return getLineByIndex(chart, fill);\n }\n if (fill === 'stack') {\n return _buildStackLine(source);\n }\n if (fill === 'shape') {\n return true;\n }\n const boundary = computeBoundary(source);\n if (boundary instanceof simpleArc) {\n return boundary;\n }\n return _createBoundaryLine(boundary, line);\n}\n function getLineByIndex(chart, index) {\n const meta = chart.getDatasetMeta(index);\n const visible = meta && chart.isDatasetVisible(index);\n return visible ? meta.dataset : null;\n}\nfunction computeBoundary(source) {\n const scale = source.scale || {};\n if (scale.getPointPositionForValue) {\n return computeCircularBoundary(source);\n }\n return computeLinearBoundary(source);\n}\nfunction computeLinearBoundary(source) {\n const { scale ={} , fill } = source;\n const pixel = _getTargetPixel(fill, scale);\n if (isNumberFinite(pixel)) {\n const horizontal = scale.isHorizontal();\n return {\n x: horizontal ? pixel : null,\n y: horizontal ? null : pixel\n };\n }\n return null;\n}\nfunction computeCircularBoundary(source) {\n const { scale , fill } = source;\n const options = scale.options;\n const length = scale.getLabels().length;\n const start = options.reverse ? scale.max : scale.min;\n const value = _getTargetValue(fill, scale, start);\n const target = [];\n if (options.grid.circular) {\n const center = scale.getPointPositionForValue(0, start);\n return new simpleArc({\n x: center.x,\n y: center.y,\n radius: scale.getDistanceFromCenterForValue(value)\n });\n }\n for(let i = 0; i < length; ++i){\n target.push(scale.getPointPositionForValue(i, value));\n }\n return target;\n}\n\nfunction _drawfill(ctx, source, area) {\n const target = _getTarget(source);\n const { line , scale , axis } = source;\n const lineOpts = line.options;\n const fillOption = lineOpts.fill;\n const color = lineOpts.backgroundColor;\n const { above =color , below =color } = fillOption || {};\n if (target && line.points.length) {\n clipArea(ctx, area);\n doFill(ctx, {\n line,\n target,\n above,\n below,\n area,\n scale,\n axis\n });\n unclipArea(ctx);\n }\n}\nfunction doFill(ctx, cfg) {\n const { line , target , above , below , area , scale } = cfg;\n const property = line._loop ? 'angle' : cfg.axis;\n ctx.save();\n if (property === 'x' && below !== above) {\n clipVertical(ctx, target, area.top);\n fill(ctx, {\n line,\n target,\n color: above,\n scale,\n property\n });\n ctx.restore();\n ctx.save();\n clipVertical(ctx, target, area.bottom);\n }\n fill(ctx, {\n line,\n target,\n color: below,\n scale,\n property\n });\n ctx.restore();\n}\nfunction clipVertical(ctx, target, clipY) {\n const { segments , points } = target;\n let first = true;\n let lineLoop = false;\n ctx.beginPath();\n for (const segment of segments){\n const { start , end } = segment;\n const firstPoint = points[start];\n const lastPoint = points[_findSegmentEnd(start, end, points)];\n if (first) {\n ctx.moveTo(firstPoint.x, firstPoint.y);\n first = false;\n } else {\n ctx.lineTo(firstPoint.x, clipY);\n ctx.lineTo(firstPoint.x, firstPoint.y);\n }\n lineLoop = !!target.pathSegment(ctx, segment, {\n move: lineLoop\n });\n if (lineLoop) {\n ctx.closePath();\n } else {\n ctx.lineTo(lastPoint.x, clipY);\n }\n }\n ctx.lineTo(target.first().x, clipY);\n ctx.closePath();\n ctx.clip();\n}\nfunction fill(ctx, cfg) {\n const { line , target , property , color , scale } = cfg;\n const segments = _segments(line, target, property);\n for (const { source: src , target: tgt , start , end } of segments){\n const { style: { backgroundColor =color } = {} } = src;\n const notShape = target !== true;\n ctx.save();\n ctx.fillStyle = backgroundColor;\n clipBounds(ctx, scale, notShape && _getBounds(property, start, end));\n ctx.beginPath();\n const lineLoop = !!line.pathSegment(ctx, src);\n let loop;\n if (notShape) {\n if (lineLoop) {\n ctx.closePath();\n } else {\n interpolatedLineTo(ctx, target, end, property);\n }\n const targetLoop = !!target.pathSegment(ctx, tgt, {\n move: lineLoop,\n reverse: true\n });\n loop = lineLoop && targetLoop;\n if (!loop) {\n interpolatedLineTo(ctx, target, start, property);\n }\n }\n ctx.closePath();\n ctx.fill(loop ? 'evenodd' : 'nonzero');\n ctx.restore();\n }\n}\nfunction clipBounds(ctx, scale, bounds) {\n const { top , bottom } = scale.chart.chartArea;\n const { property , start , end } = bounds || {};\n if (property === 'x') {\n ctx.beginPath();\n ctx.rect(start, top, end - start, bottom - top);\n ctx.clip();\n }\n}\nfunction interpolatedLineTo(ctx, target, point, property) {\n const interpolatedPoint = target.interpolate(point, property);\n if (interpolatedPoint) {\n ctx.lineTo(interpolatedPoint.x, interpolatedPoint.y);\n }\n}\n\nvar index = {\n id: 'filler',\n afterDatasetsUpdate (chart, _args, options) {\n const count = (chart.data.datasets || []).length;\n const sources = [];\n let meta, i, line, source;\n for(i = 0; i < count; ++i){\n meta = chart.getDatasetMeta(i);\n line = meta.dataset;\n source = null;\n if (line && line.options && line instanceof LineElement) {\n source = {\n visible: chart.isDatasetVisible(i),\n index: i,\n fill: _decodeFill(line, i, count),\n chart,\n axis: meta.controller.options.indexAxis,\n scale: meta.vScale,\n line\n };\n }\n meta.$filler = source;\n sources.push(source);\n }\n for(i = 0; i < count; ++i){\n source = sources[i];\n if (!source || source.fill === false) {\n continue;\n }\n source.fill = _resolveTarget(sources, i, options.propagate);\n }\n },\n beforeDraw (chart, _args, options) {\n const draw = options.drawTime === 'beforeDraw';\n const metasets = chart.getSortedVisibleDatasetMetas();\n const area = chart.chartArea;\n for(let i = metasets.length - 1; i >= 0; --i){\n const source = metasets[i].$filler;\n if (!source) {\n continue;\n }\n source.line.updateControlPoints(area, source.axis);\n if (draw && source.fill) {\n _drawfill(chart.ctx, source, area);\n }\n }\n },\n beforeDatasetsDraw (chart, _args, options) {\n if (options.drawTime !== 'beforeDatasetsDraw') {\n return;\n }\n const metasets = chart.getSortedVisibleDatasetMetas();\n for(let i = metasets.length - 1; i >= 0; --i){\n const source = metasets[i].$filler;\n if (_shouldApplyFill(source)) {\n _drawfill(chart.ctx, source, chart.chartArea);\n }\n }\n },\n beforeDatasetDraw (chart, args, options) {\n const source = args.meta.$filler;\n if (!_shouldApplyFill(source) || options.drawTime !== 'beforeDatasetDraw') {\n return;\n }\n _drawfill(chart.ctx, source, chart.chartArea);\n },\n defaults: {\n propagate: true,\n drawTime: 'beforeDatasetDraw'\n }\n};\n\nconst getBoxSize = (labelOpts, fontSize)=>{\n let { boxHeight =fontSize , boxWidth =fontSize } = labelOpts;\n if (labelOpts.usePointStyle) {\n boxHeight = Math.min(boxHeight, fontSize);\n boxWidth = labelOpts.pointStyleWidth || Math.min(boxWidth, fontSize);\n }\n return {\n boxWidth,\n boxHeight,\n itemHeight: Math.max(fontSize, boxHeight)\n };\n};\nconst itemsEqual = (a, b)=>a !== null && b !== null && a.datasetIndex === b.datasetIndex && a.index === b.index;\nclass Legend extends Element {\n constructor(config){\n super();\n this._added = false;\n this.legendHitBoxes = [];\n this._hoveredItem = null;\n this.doughnutMode = false;\n this.chart = config.chart;\n this.options = config.options;\n this.ctx = config.ctx;\n this.legendItems = undefined;\n this.columnSizes = undefined;\n this.lineWidths = undefined;\n this.maxHeight = undefined;\n this.maxWidth = undefined;\n this.top = undefined;\n this.bottom = undefined;\n this.left = undefined;\n this.right = undefined;\n this.height = undefined;\n this.width = undefined;\n this._margins = undefined;\n this.position = undefined;\n this.weight = undefined;\n this.fullSize = undefined;\n }\n update(maxWidth, maxHeight, margins) {\n this.maxWidth = maxWidth;\n this.maxHeight = maxHeight;\n this._margins = margins;\n this.setDimensions();\n this.buildLabels();\n this.fit();\n }\n setDimensions() {\n if (this.isHorizontal()) {\n this.width = this.maxWidth;\n this.left = this._margins.left;\n this.right = this.width;\n } else {\n this.height = this.maxHeight;\n this.top = this._margins.top;\n this.bottom = this.height;\n }\n }\n buildLabels() {\n const labelOpts = this.options.labels || {};\n let legendItems = callback(labelOpts.generateLabels, [\n this.chart\n ], this) || [];\n if (labelOpts.filter) {\n legendItems = legendItems.filter((item)=>labelOpts.filter(item, this.chart.data));\n }\n if (labelOpts.sort) {\n legendItems = legendItems.sort((a, b)=>labelOpts.sort(a, b, this.chart.data));\n }\n if (this.options.reverse) {\n legendItems.reverse();\n }\n this.legendItems = legendItems;\n }\n fit() {\n const { options , ctx } = this;\n if (!options.display) {\n this.width = this.height = 0;\n return;\n }\n const labelOpts = options.labels;\n const labelFont = toFont(labelOpts.font);\n const fontSize = labelFont.size;\n const titleHeight = this._computeTitleHeight();\n const { boxWidth , itemHeight } = getBoxSize(labelOpts, fontSize);\n let width, height;\n ctx.font = labelFont.string;\n if (this.isHorizontal()) {\n width = this.maxWidth;\n height = this._fitRows(titleHeight, fontSize, boxWidth, itemHeight) + 10;\n } else {\n height = this.maxHeight;\n width = this._fitCols(titleHeight, labelFont, boxWidth, itemHeight) + 10;\n }\n this.width = Math.min(width, options.maxWidth || this.maxWidth);\n this.height = Math.min(height, options.maxHeight || this.maxHeight);\n }\n _fitRows(titleHeight, fontSize, boxWidth, itemHeight) {\n const { ctx , maxWidth , options: { labels: { padding } } } = this;\n const hitboxes = this.legendHitBoxes = [];\n const lineWidths = this.lineWidths = [\n 0\n ];\n const lineHeight = itemHeight + padding;\n let totalHeight = titleHeight;\n ctx.textAlign = 'left';\n ctx.textBaseline = 'middle';\n let row = -1;\n let top = -lineHeight;\n this.legendItems.forEach((legendItem, i)=>{\n const itemWidth = boxWidth + fontSize / 2 + ctx.measureText(legendItem.text).width;\n if (i === 0 || lineWidths[lineWidths.length - 1] + itemWidth + 2 * padding > maxWidth) {\n totalHeight += lineHeight;\n lineWidths[lineWidths.length - (i > 0 ? 0 : 1)] = 0;\n top += lineHeight;\n row++;\n }\n hitboxes[i] = {\n left: 0,\n top,\n row,\n width: itemWidth,\n height: itemHeight\n };\n lineWidths[lineWidths.length - 1] += itemWidth + padding;\n });\n return totalHeight;\n }\n _fitCols(titleHeight, labelFont, boxWidth, _itemHeight) {\n const { ctx , maxHeight , options: { labels: { padding } } } = this;\n const hitboxes = this.legendHitBoxes = [];\n const columnSizes = this.columnSizes = [];\n const heightLimit = maxHeight - titleHeight;\n let totalWidth = padding;\n let currentColWidth = 0;\n let currentColHeight = 0;\n let left = 0;\n let col = 0;\n this.legendItems.forEach((legendItem, i)=>{\n const { itemWidth , itemHeight } = calculateItemSize(boxWidth, labelFont, ctx, legendItem, _itemHeight);\n if (i > 0 && currentColHeight + itemHeight + 2 * padding > heightLimit) {\n totalWidth += currentColWidth + padding;\n columnSizes.push({\n width: currentColWidth,\n height: currentColHeight\n });\n left += currentColWidth + padding;\n col++;\n currentColWidth = currentColHeight = 0;\n }\n hitboxes[i] = {\n left,\n top: currentColHeight,\n col,\n width: itemWidth,\n height: itemHeight\n };\n currentColWidth = Math.max(currentColWidth, itemWidth);\n currentColHeight += itemHeight + padding;\n });\n totalWidth += currentColWidth;\n columnSizes.push({\n width: currentColWidth,\n height: currentColHeight\n });\n return totalWidth;\n }\n adjustHitBoxes() {\n if (!this.options.display) {\n return;\n }\n const titleHeight = this._computeTitleHeight();\n const { legendHitBoxes: hitboxes , options: { align , labels: { padding } , rtl } } = this;\n const rtlHelper = getRtlAdapter(rtl, this.left, this.width);\n if (this.isHorizontal()) {\n let row = 0;\n let left = _alignStartEnd(align, this.left + padding, this.right - this.lineWidths[row]);\n for (const hitbox of hitboxes){\n if (row !== hitbox.row) {\n row = hitbox.row;\n left = _alignStartEnd(align, this.left + padding, this.right - this.lineWidths[row]);\n }\n hitbox.top += this.top + titleHeight + padding;\n hitbox.left = rtlHelper.leftForLtr(rtlHelper.x(left), hitbox.width);\n left += hitbox.width + padding;\n }\n } else {\n let col = 0;\n let top = _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - this.columnSizes[col].height);\n for (const hitbox of hitboxes){\n if (hitbox.col !== col) {\n col = hitbox.col;\n top = _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - this.columnSizes[col].height);\n }\n hitbox.top = top;\n hitbox.left += this.left + padding;\n hitbox.left = rtlHelper.leftForLtr(rtlHelper.x(hitbox.left), hitbox.width);\n top += hitbox.height + padding;\n }\n }\n }\n isHorizontal() {\n return this.options.position === 'top' || this.options.position === 'bottom';\n }\n draw() {\n if (this.options.display) {\n const ctx = this.ctx;\n clipArea(ctx, this);\n this._draw();\n unclipArea(ctx);\n }\n }\n _draw() {\n const { options: opts , columnSizes , lineWidths , ctx } = this;\n const { align , labels: labelOpts } = opts;\n const defaultColor = defaults.color;\n const rtlHelper = getRtlAdapter(opts.rtl, this.left, this.width);\n const labelFont = toFont(labelOpts.font);\n const { padding } = labelOpts;\n const fontSize = labelFont.size;\n const halfFontSize = fontSize / 2;\n let cursor;\n this.drawTitle();\n ctx.textAlign = rtlHelper.textAlign('left');\n ctx.textBaseline = 'middle';\n ctx.lineWidth = 0.5;\n ctx.font = labelFont.string;\n const { boxWidth , boxHeight , itemHeight } = getBoxSize(labelOpts, fontSize);\n const drawLegendBox = function(x, y, legendItem) {\n if (isNaN(boxWidth) || boxWidth <= 0 || isNaN(boxHeight) || boxHeight < 0) {\n return;\n }\n ctx.save();\n const lineWidth = valueOrDefault(legendItem.lineWidth, 1);\n ctx.fillStyle = valueOrDefault(legendItem.fillStyle, defaultColor);\n ctx.lineCap = valueOrDefault(legendItem.lineCap, 'butt');\n ctx.lineDashOffset = valueOrDefault(legendItem.lineDashOffset, 0);\n ctx.lineJoin = valueOrDefault(legendItem.lineJoin, 'miter');\n ctx.lineWidth = lineWidth;\n ctx.strokeStyle = valueOrDefault(legendItem.strokeStyle, defaultColor);\n ctx.setLineDash(valueOrDefault(legendItem.lineDash, []));\n if (labelOpts.usePointStyle) {\n const drawOptions = {\n radius: boxHeight * Math.SQRT2 / 2,\n pointStyle: legendItem.pointStyle,\n rotation: legendItem.rotation,\n borderWidth: lineWidth\n };\n const centerX = rtlHelper.xPlus(x, boxWidth / 2);\n const centerY = y + halfFontSize;\n drawPointLegend(ctx, drawOptions, centerX, centerY, labelOpts.pointStyleWidth && boxWidth);\n } else {\n const yBoxTop = y + Math.max((fontSize - boxHeight) / 2, 0);\n const xBoxLeft = rtlHelper.leftForLtr(x, boxWidth);\n const borderRadius = toTRBLCorners(legendItem.borderRadius);\n ctx.beginPath();\n if (Object.values(borderRadius).some((v)=>v !== 0)) {\n addRoundedRectPath(ctx, {\n x: xBoxLeft,\n y: yBoxTop,\n w: boxWidth,\n h: boxHeight,\n radius: borderRadius\n });\n } else {\n ctx.rect(xBoxLeft, yBoxTop, boxWidth, boxHeight);\n }\n ctx.fill();\n if (lineWidth !== 0) {\n ctx.stroke();\n }\n }\n ctx.restore();\n };\n const fillText = function(x, y, legendItem) {\n renderText(ctx, legendItem.text, x, y + itemHeight / 2, labelFont, {\n strikethrough: legendItem.hidden,\n textAlign: rtlHelper.textAlign(legendItem.textAlign)\n });\n };\n const isHorizontal = this.isHorizontal();\n const titleHeight = this._computeTitleHeight();\n if (isHorizontal) {\n cursor = {\n x: _alignStartEnd(align, this.left + padding, this.right - lineWidths[0]),\n y: this.top + padding + titleHeight,\n line: 0\n };\n } else {\n cursor = {\n x: this.left + padding,\n y: _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - columnSizes[0].height),\n line: 0\n };\n }\n overrideTextDirection(this.ctx, opts.textDirection);\n const lineHeight = itemHeight + padding;\n this.legendItems.forEach((legendItem, i)=>{\n ctx.strokeStyle = legendItem.fontColor;\n ctx.fillStyle = legendItem.fontColor;\n const textWidth = ctx.measureText(legendItem.text).width;\n const textAlign = rtlHelper.textAlign(legendItem.textAlign || (legendItem.textAlign = labelOpts.textAlign));\n const width = boxWidth + halfFontSize + textWidth;\n let x = cursor.x;\n let y = cursor.y;\n rtlHelper.setWidth(this.width);\n if (isHorizontal) {\n if (i > 0 && x + width + padding > this.right) {\n y = cursor.y += lineHeight;\n cursor.line++;\n x = cursor.x = _alignStartEnd(align, this.left + padding, this.right - lineWidths[cursor.line]);\n }\n } else if (i > 0 && y + lineHeight > this.bottom) {\n x = cursor.x = x + columnSizes[cursor.line].width + padding;\n cursor.line++;\n y = cursor.y = _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - columnSizes[cursor.line].height);\n }\n const realX = rtlHelper.x(x);\n drawLegendBox(realX, y, legendItem);\n x = _textX(textAlign, x + boxWidth + halfFontSize, isHorizontal ? x + width : this.right, opts.rtl);\n fillText(rtlHelper.x(x), y, legendItem);\n if (isHorizontal) {\n cursor.x += width + padding;\n } else if (typeof legendItem.text !== 'string') {\n const fontLineHeight = labelFont.lineHeight;\n cursor.y += calculateLegendItemHeight(legendItem, fontLineHeight) + padding;\n } else {\n cursor.y += lineHeight;\n }\n });\n restoreTextDirection(this.ctx, opts.textDirection);\n }\n drawTitle() {\n const opts = this.options;\n const titleOpts = opts.title;\n const titleFont = toFont(titleOpts.font);\n const titlePadding = toPadding(titleOpts.padding);\n if (!titleOpts.display) {\n return;\n }\n const rtlHelper = getRtlAdapter(opts.rtl, this.left, this.width);\n const ctx = this.ctx;\n const position = titleOpts.position;\n const halfFontSize = titleFont.size / 2;\n const topPaddingPlusHalfFontSize = titlePadding.top + halfFontSize;\n let y;\n let left = this.left;\n let maxWidth = this.width;\n if (this.isHorizontal()) {\n maxWidth = Math.max(...this.lineWidths);\n y = this.top + topPaddingPlusHalfFontSize;\n left = _alignStartEnd(opts.align, left, this.right - maxWidth);\n } else {\n const maxHeight = this.columnSizes.reduce((acc, size)=>Math.max(acc, size.height), 0);\n y = topPaddingPlusHalfFontSize + _alignStartEnd(opts.align, this.top, this.bottom - maxHeight - opts.labels.padding - this._computeTitleHeight());\n }\n const x = _alignStartEnd(position, left, left + maxWidth);\n ctx.textAlign = rtlHelper.textAlign(_toLeftRightCenter(position));\n ctx.textBaseline = 'middle';\n ctx.strokeStyle = titleOpts.color;\n ctx.fillStyle = titleOpts.color;\n ctx.font = titleFont.string;\n renderText(ctx, titleOpts.text, x, y, titleFont);\n }\n _computeTitleHeight() {\n const titleOpts = this.options.title;\n const titleFont = toFont(titleOpts.font);\n const titlePadding = toPadding(titleOpts.padding);\n return titleOpts.display ? titleFont.lineHeight + titlePadding.height : 0;\n }\n _getLegendItemAt(x, y) {\n let i, hitBox, lh;\n if (_isBetween(x, this.left, this.right) && _isBetween(y, this.top, this.bottom)) {\n lh = this.legendHitBoxes;\n for(i = 0; i < lh.length; ++i){\n hitBox = lh[i];\n if (_isBetween(x, hitBox.left, hitBox.left + hitBox.width) && _isBetween(y, hitBox.top, hitBox.top + hitBox.height)) {\n return this.legendItems[i];\n }\n }\n }\n return null;\n }\n handleEvent(e) {\n const opts = this.options;\n if (!isListened(e.type, opts)) {\n return;\n }\n const hoveredItem = this._getLegendItemAt(e.x, e.y);\n if (e.type === 'mousemove' || e.type === 'mouseout') {\n const previous = this._hoveredItem;\n const sameItem = itemsEqual(previous, hoveredItem);\n if (previous && !sameItem) {\n callback(opts.onLeave, [\n e,\n previous,\n this\n ], this);\n }\n this._hoveredItem = hoveredItem;\n if (hoveredItem && !sameItem) {\n callback(opts.onHover, [\n e,\n hoveredItem,\n this\n ], this);\n }\n } else if (hoveredItem) {\n callback(opts.onClick, [\n e,\n hoveredItem,\n this\n ], this);\n }\n }\n}\nfunction calculateItemSize(boxWidth, labelFont, ctx, legendItem, _itemHeight) {\n const itemWidth = calculateItemWidth(legendItem, boxWidth, labelFont, ctx);\n const itemHeight = calculateItemHeight(_itemHeight, legendItem, labelFont.lineHeight);\n return {\n itemWidth,\n itemHeight\n };\n}\nfunction calculateItemWidth(legendItem, boxWidth, labelFont, ctx) {\n let legendItemText = legendItem.text;\n if (legendItemText && typeof legendItemText !== 'string') {\n legendItemText = legendItemText.reduce((a, b)=>a.length > b.length ? a : b);\n }\n return boxWidth + labelFont.size / 2 + ctx.measureText(legendItemText).width;\n}\nfunction calculateItemHeight(_itemHeight, legendItem, fontLineHeight) {\n let itemHeight = _itemHeight;\n if (typeof legendItem.text !== 'string') {\n itemHeight = calculateLegendItemHeight(legendItem, fontLineHeight);\n }\n return itemHeight;\n}\nfunction calculateLegendItemHeight(legendItem, fontLineHeight) {\n const labelHeight = legendItem.text ? legendItem.text.length : 0;\n return fontLineHeight * labelHeight;\n}\nfunction isListened(type, opts) {\n if ((type === 'mousemove' || type === 'mouseout') && (opts.onHover || opts.onLeave)) {\n return true;\n }\n if (opts.onClick && (type === 'click' || type === 'mouseup')) {\n return true;\n }\n return false;\n}\nvar plugin_legend = {\n id: 'legend',\n _element: Legend,\n start (chart, _args, options) {\n const legend = chart.legend = new Legend({\n ctx: chart.ctx,\n options,\n chart\n });\n layouts.configure(chart, legend, options);\n layouts.addBox(chart, legend);\n },\n stop (chart) {\n layouts.removeBox(chart, chart.legend);\n delete chart.legend;\n },\n beforeUpdate (chart, _args, options) {\n const legend = chart.legend;\n layouts.configure(chart, legend, options);\n legend.options = options;\n },\n afterUpdate (chart) {\n const legend = chart.legend;\n legend.buildLabels();\n legend.adjustHitBoxes();\n },\n afterEvent (chart, args) {\n if (!args.replay) {\n chart.legend.handleEvent(args.event);\n }\n },\n defaults: {\n display: true,\n position: 'top',\n align: 'center',\n fullSize: true,\n reverse: false,\n weight: 1000,\n onClick (e, legendItem, legend) {\n const index = legendItem.datasetIndex;\n const ci = legend.chart;\n if (ci.isDatasetVisible(index)) {\n ci.hide(index);\n legendItem.hidden = true;\n } else {\n ci.show(index);\n legendItem.hidden = false;\n }\n },\n onHover: null,\n onLeave: null,\n labels: {\n color: (ctx)=>ctx.chart.options.color,\n boxWidth: 40,\n padding: 10,\n generateLabels (chart) {\n const datasets = chart.data.datasets;\n const { labels: { usePointStyle , pointStyle , textAlign , color , useBorderRadius , borderRadius } } = chart.legend.options;\n return chart._getSortedDatasetMetas().map((meta)=>{\n const style = meta.controller.getStyle(usePointStyle ? 0 : undefined);\n const borderWidth = toPadding(style.borderWidth);\n return {\n text: datasets[meta.index].label,\n fillStyle: style.backgroundColor,\n fontColor: color,\n hidden: !meta.visible,\n lineCap: style.borderCapStyle,\n lineDash: style.borderDash,\n lineDashOffset: style.borderDashOffset,\n lineJoin: style.borderJoinStyle,\n lineWidth: (borderWidth.width + borderWidth.height) / 4,\n strokeStyle: style.borderColor,\n pointStyle: pointStyle || style.pointStyle,\n rotation: style.rotation,\n textAlign: textAlign || style.textAlign,\n borderRadius: useBorderRadius && (borderRadius || style.borderRadius),\n datasetIndex: meta.index\n };\n }, this);\n }\n },\n title: {\n color: (ctx)=>ctx.chart.options.color,\n display: false,\n position: 'center',\n text: ''\n }\n },\n descriptors: {\n _scriptable: (name)=>!name.startsWith('on'),\n labels: {\n _scriptable: (name)=>![\n 'generateLabels',\n 'filter',\n 'sort'\n ].includes(name)\n }\n }\n};\n\nclass Title extends Element {\n constructor(config){\n super();\n this.chart = config.chart;\n this.options = config.options;\n this.ctx = config.ctx;\n this._padding = undefined;\n this.top = undefined;\n this.bottom = undefined;\n this.left = undefined;\n this.right = undefined;\n this.width = undefined;\n this.height = undefined;\n this.position = undefined;\n this.weight = undefined;\n this.fullSize = undefined;\n }\n update(maxWidth, maxHeight) {\n const opts = this.options;\n this.left = 0;\n this.top = 0;\n if (!opts.display) {\n this.width = this.height = this.right = this.bottom = 0;\n return;\n }\n this.width = this.right = maxWidth;\n this.height = this.bottom = maxHeight;\n const lineCount = isArray(opts.text) ? opts.text.length : 1;\n this._padding = toPadding(opts.padding);\n const textSize = lineCount * toFont(opts.font).lineHeight + this._padding.height;\n if (this.isHorizontal()) {\n this.height = textSize;\n } else {\n this.width = textSize;\n }\n }\n isHorizontal() {\n const pos = this.options.position;\n return pos === 'top' || pos === 'bottom';\n }\n _drawArgs(offset) {\n const { top , left , bottom , right , options } = this;\n const align = options.align;\n let rotation = 0;\n let maxWidth, titleX, titleY;\n if (this.isHorizontal()) {\n titleX = _alignStartEnd(align, left, right);\n titleY = top + offset;\n maxWidth = right - left;\n } else {\n if (options.position === 'left') {\n titleX = left + offset;\n titleY = _alignStartEnd(align, bottom, top);\n rotation = PI * -0.5;\n } else {\n titleX = right - offset;\n titleY = _alignStartEnd(align, top, bottom);\n rotation = PI * 0.5;\n }\n maxWidth = bottom - top;\n }\n return {\n titleX,\n titleY,\n maxWidth,\n rotation\n };\n }\n draw() {\n const ctx = this.ctx;\n const opts = this.options;\n if (!opts.display) {\n return;\n }\n const fontOpts = toFont(opts.font);\n const lineHeight = fontOpts.lineHeight;\n const offset = lineHeight / 2 + this._padding.top;\n const { titleX , titleY , maxWidth , rotation } = this._drawArgs(offset);\n renderText(ctx, opts.text, 0, 0, fontOpts, {\n color: opts.color,\n maxWidth,\n rotation,\n textAlign: _toLeftRightCenter(opts.align),\n textBaseline: 'middle',\n translation: [\n titleX,\n titleY\n ]\n });\n }\n}\nfunction createTitle(chart, titleOpts) {\n const title = new Title({\n ctx: chart.ctx,\n options: titleOpts,\n chart\n });\n layouts.configure(chart, title, titleOpts);\n layouts.addBox(chart, title);\n chart.titleBlock = title;\n}\nvar plugin_title = {\n id: 'title',\n _element: Title,\n start (chart, _args, options) {\n createTitle(chart, options);\n },\n stop (chart) {\n const titleBlock = chart.titleBlock;\n layouts.removeBox(chart, titleBlock);\n delete chart.titleBlock;\n },\n beforeUpdate (chart, _args, options) {\n const title = chart.titleBlock;\n layouts.configure(chart, title, options);\n title.options = options;\n },\n defaults: {\n align: 'center',\n display: false,\n font: {\n weight: 'bold'\n },\n fullSize: true,\n padding: 10,\n position: 'top',\n text: '',\n weight: 2000\n },\n defaultRoutes: {\n color: 'color'\n },\n descriptors: {\n _scriptable: true,\n _indexable: false\n }\n};\n\nconst chart_map = new WeakMap();\nvar plugin_subtitle = {\n id: 'subtitle',\n start (chart, _args, options) {\n const title = new Title({\n ctx: chart.ctx,\n options,\n chart\n });\n layouts.configure(chart, title, options);\n layouts.addBox(chart, title);\n chart_map.set(chart, title);\n },\n stop (chart) {\n layouts.removeBox(chart, chart_map.get(chart));\n chart_map.delete(chart);\n },\n beforeUpdate (chart, _args, options) {\n const title = chart_map.get(chart);\n layouts.configure(chart, title, options);\n title.options = options;\n },\n defaults: {\n align: 'center',\n display: false,\n font: {\n weight: 'normal'\n },\n fullSize: true,\n padding: 0,\n position: 'top',\n text: '',\n weight: 1500\n },\n defaultRoutes: {\n color: 'color'\n },\n descriptors: {\n _scriptable: true,\n _indexable: false\n }\n};\n\nconst positioners = {\n average (items) {\n if (!items.length) {\n return false;\n }\n let i, len;\n let xSet = new Set();\n let y = 0;\n let count = 0;\n for(i = 0, len = items.length; i < len; ++i){\n const el = items[i].element;\n if (el && el.hasValue()) {\n const pos = el.tooltipPosition();\n xSet.add(pos.x);\n y += pos.y;\n ++count;\n }\n }\n if (count === 0 || xSet.size === 0) {\n return false;\n }\n const xAverage = [\n ...xSet\n ].reduce((a, b)=>a + b) / xSet.size;\n return {\n x: xAverage,\n y: y / count\n };\n },\n nearest (items, eventPosition) {\n if (!items.length) {\n return false;\n }\n let x = eventPosition.x;\n let y = eventPosition.y;\n let minDistance = Number.POSITIVE_INFINITY;\n let i, len, nearestElement;\n for(i = 0, len = items.length; i < len; ++i){\n const el = items[i].element;\n if (el && el.hasValue()) {\n const center = el.getCenterPoint();\n const d = distanceBetweenPoints(eventPosition, center);\n if (d < minDistance) {\n minDistance = d;\n nearestElement = el;\n }\n }\n }\n if (nearestElement) {\n const tp = nearestElement.tooltipPosition();\n x = tp.x;\n y = tp.y;\n }\n return {\n x,\n y\n };\n }\n};\nfunction pushOrConcat(base, toPush) {\n if (toPush) {\n if (isArray(toPush)) {\n Array.prototype.push.apply(base, toPush);\n } else {\n base.push(toPush);\n }\n }\n return base;\n}\n function splitNewlines(str) {\n if ((typeof str === 'string' || str instanceof String) && str.indexOf('\\n') > -1) {\n return str.split('\\n');\n }\n return str;\n}\n function createTooltipItem(chart, item) {\n const { element , datasetIndex , index } = item;\n const controller = chart.getDatasetMeta(datasetIndex).controller;\n const { label , value } = controller.getLabelAndValue(index);\n return {\n chart,\n label,\n parsed: controller.getParsed(index),\n raw: chart.data.datasets[datasetIndex].data[index],\n formattedValue: value,\n dataset: controller.getDataset(),\n dataIndex: index,\n datasetIndex,\n element\n };\n}\n function getTooltipSize(tooltip, options) {\n const ctx = tooltip.chart.ctx;\n const { body , footer , title } = tooltip;\n const { boxWidth , boxHeight } = options;\n const bodyFont = toFont(options.bodyFont);\n const titleFont = toFont(options.titleFont);\n const footerFont = toFont(options.footerFont);\n const titleLineCount = title.length;\n const footerLineCount = footer.length;\n const bodyLineItemCount = body.length;\n const padding = toPadding(options.padding);\n let height = padding.height;\n let width = 0;\n let combinedBodyLength = body.reduce((count, bodyItem)=>count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length, 0);\n combinedBodyLength += tooltip.beforeBody.length + tooltip.afterBody.length;\n if (titleLineCount) {\n height += titleLineCount * titleFont.lineHeight + (titleLineCount - 1) * options.titleSpacing + options.titleMarginBottom;\n }\n if (combinedBodyLength) {\n const bodyLineHeight = options.displayColors ? Math.max(boxHeight, bodyFont.lineHeight) : bodyFont.lineHeight;\n height += bodyLineItemCount * bodyLineHeight + (combinedBodyLength - bodyLineItemCount) * bodyFont.lineHeight + (combinedBodyLength - 1) * options.bodySpacing;\n }\n if (footerLineCount) {\n height += options.footerMarginTop + footerLineCount * footerFont.lineHeight + (footerLineCount - 1) * options.footerSpacing;\n }\n let widthPadding = 0;\n const maxLineWidth = function(line) {\n width = Math.max(width, ctx.measureText(line).width + widthPadding);\n };\n ctx.save();\n ctx.font = titleFont.string;\n each(tooltip.title, maxLineWidth);\n ctx.font = bodyFont.string;\n each(tooltip.beforeBody.concat(tooltip.afterBody), maxLineWidth);\n widthPadding = options.displayColors ? boxWidth + 2 + options.boxPadding : 0;\n each(body, (bodyItem)=>{\n each(bodyItem.before, maxLineWidth);\n each(bodyItem.lines, maxLineWidth);\n each(bodyItem.after, maxLineWidth);\n });\n widthPadding = 0;\n ctx.font = footerFont.string;\n each(tooltip.footer, maxLineWidth);\n ctx.restore();\n width += padding.width;\n return {\n width,\n height\n };\n}\nfunction determineYAlign(chart, size) {\n const { y , height } = size;\n if (y < height / 2) {\n return 'top';\n } else if (y > chart.height - height / 2) {\n return 'bottom';\n }\n return 'center';\n}\nfunction doesNotFitWithAlign(xAlign, chart, options, size) {\n const { x , width } = size;\n const caret = options.caretSize + options.caretPadding;\n if (xAlign === 'left' && x + width + caret > chart.width) {\n return true;\n }\n if (xAlign === 'right' && x - width - caret < 0) {\n return true;\n }\n}\nfunction determineXAlign(chart, options, size, yAlign) {\n const { x , width } = size;\n const { width: chartWidth , chartArea: { left , right } } = chart;\n let xAlign = 'center';\n if (yAlign === 'center') {\n xAlign = x <= (left + right) / 2 ? 'left' : 'right';\n } else if (x <= width / 2) {\n xAlign = 'left';\n } else if (x >= chartWidth - width / 2) {\n xAlign = 'right';\n }\n if (doesNotFitWithAlign(xAlign, chart, options, size)) {\n xAlign = 'center';\n }\n return xAlign;\n}\n function determineAlignment(chart, options, size) {\n const yAlign = size.yAlign || options.yAlign || determineYAlign(chart, size);\n return {\n xAlign: size.xAlign || options.xAlign || determineXAlign(chart, options, size, yAlign),\n yAlign\n };\n}\nfunction alignX(size, xAlign) {\n let { x , width } = size;\n if (xAlign === 'right') {\n x -= width;\n } else if (xAlign === 'center') {\n x -= width / 2;\n }\n return x;\n}\nfunction alignY(size, yAlign, paddingAndSize) {\n let { y , height } = size;\n if (yAlign === 'top') {\n y += paddingAndSize;\n } else if (yAlign === 'bottom') {\n y -= height + paddingAndSize;\n } else {\n y -= height / 2;\n }\n return y;\n}\n function getBackgroundPoint(options, size, alignment, chart) {\n const { caretSize , caretPadding , cornerRadius } = options;\n const { xAlign , yAlign } = alignment;\n const paddingAndSize = caretSize + caretPadding;\n const { topLeft , topRight , bottomLeft , bottomRight } = toTRBLCorners(cornerRadius);\n let x = alignX(size, xAlign);\n const y = alignY(size, yAlign, paddingAndSize);\n if (yAlign === 'center') {\n if (xAlign === 'left') {\n x += paddingAndSize;\n } else if (xAlign === 'right') {\n x -= paddingAndSize;\n }\n } else if (xAlign === 'left') {\n x -= Math.max(topLeft, bottomLeft) + caretSize;\n } else if (xAlign === 'right') {\n x += Math.max(topRight, bottomRight) + caretSize;\n }\n return {\n x: _limitValue(x, 0, chart.width - size.width),\n y: _limitValue(y, 0, chart.height - size.height)\n };\n}\nfunction getAlignedX(tooltip, align, options) {\n const padding = toPadding(options.padding);\n return align === 'center' ? tooltip.x + tooltip.width / 2 : align === 'right' ? tooltip.x + tooltip.width - padding.right : tooltip.x + padding.left;\n}\n function getBeforeAfterBodyLines(callback) {\n return pushOrConcat([], splitNewlines(callback));\n}\nfunction createTooltipContext(parent, tooltip, tooltipItems) {\n return createContext(parent, {\n tooltip,\n tooltipItems,\n type: 'tooltip'\n });\n}\nfunction overrideCallbacks(callbacks, context) {\n const override = context && context.dataset && context.dataset.tooltip && context.dataset.tooltip.callbacks;\n return override ? callbacks.override(override) : callbacks;\n}\nconst defaultCallbacks = {\n beforeTitle: noop,\n title (tooltipItems) {\n if (tooltipItems.length > 0) {\n const item = tooltipItems[0];\n const labels = item.chart.data.labels;\n const labelCount = labels ? labels.length : 0;\n if (this && this.options && this.options.mode === 'dataset') {\n return item.dataset.label || '';\n } else if (item.label) {\n return item.label;\n } else if (labelCount > 0 && item.dataIndex < labelCount) {\n return labels[item.dataIndex];\n }\n }\n return '';\n },\n afterTitle: noop,\n beforeBody: noop,\n beforeLabel: noop,\n label (tooltipItem) {\n if (this && this.options && this.options.mode === 'dataset') {\n return tooltipItem.label + ': ' + tooltipItem.formattedValue || tooltipItem.formattedValue;\n }\n let label = tooltipItem.dataset.label || '';\n if (label) {\n label += ': ';\n }\n const value = tooltipItem.formattedValue;\n if (!isNullOrUndef(value)) {\n label += value;\n }\n return label;\n },\n labelColor (tooltipItem) {\n const meta = tooltipItem.chart.getDatasetMeta(tooltipItem.datasetIndex);\n const options = meta.controller.getStyle(tooltipItem.dataIndex);\n return {\n borderColor: options.borderColor,\n backgroundColor: options.backgroundColor,\n borderWidth: options.borderWidth,\n borderDash: options.borderDash,\n borderDashOffset: options.borderDashOffset,\n borderRadius: 0\n };\n },\n labelTextColor () {\n return this.options.bodyColor;\n },\n labelPointStyle (tooltipItem) {\n const meta = tooltipItem.chart.getDatasetMeta(tooltipItem.datasetIndex);\n const options = meta.controller.getStyle(tooltipItem.dataIndex);\n return {\n pointStyle: options.pointStyle,\n rotation: options.rotation\n };\n },\n afterLabel: noop,\n afterBody: noop,\n beforeFooter: noop,\n footer: noop,\n afterFooter: noop\n};\n function invokeCallbackWithFallback(callbacks, name, ctx, arg) {\n const result = callbacks[name].call(ctx, arg);\n if (typeof result === 'undefined') {\n return defaultCallbacks[name].call(ctx, arg);\n }\n return result;\n}\nclass Tooltip extends Element {\n static positioners = positioners;\n constructor(config){\n super();\n this.opacity = 0;\n this._active = [];\n this._eventPosition = undefined;\n this._size = undefined;\n this._cachedAnimations = undefined;\n this._tooltipItems = [];\n this.$animations = undefined;\n this.$context = undefined;\n this.chart = config.chart;\n this.options = config.options;\n this.dataPoints = undefined;\n this.title = undefined;\n this.beforeBody = undefined;\n this.body = undefined;\n this.afterBody = undefined;\n this.footer = undefined;\n this.xAlign = undefined;\n this.yAlign = undefined;\n this.x = undefined;\n this.y = undefined;\n this.height = undefined;\n this.width = undefined;\n this.caretX = undefined;\n this.caretY = undefined;\n this.labelColors = undefined;\n this.labelPointStyles = undefined;\n this.labelTextColors = undefined;\n }\n initialize(options) {\n this.options = options;\n this._cachedAnimations = undefined;\n this.$context = undefined;\n }\n _resolveAnimations() {\n const cached = this._cachedAnimations;\n if (cached) {\n return cached;\n }\n const chart = this.chart;\n const options = this.options.setContext(this.getContext());\n const opts = options.enabled && chart.options.animation && options.animations;\n const animations = new Animations(this.chart, opts);\n if (opts._cacheable) {\n this._cachedAnimations = Object.freeze(animations);\n }\n return animations;\n }\n getContext() {\n return this.$context || (this.$context = createTooltipContext(this.chart.getContext(), this, this._tooltipItems));\n }\n getTitle(context, options) {\n const { callbacks } = options;\n const beforeTitle = invokeCallbackWithFallback(callbacks, 'beforeTitle', this, context);\n const title = invokeCallbackWithFallback(callbacks, 'title', this, context);\n const afterTitle = invokeCallbackWithFallback(callbacks, 'afterTitle', this, context);\n let lines = [];\n lines = pushOrConcat(lines, splitNewlines(beforeTitle));\n lines = pushOrConcat(lines, splitNewlines(title));\n lines = pushOrConcat(lines, splitNewlines(afterTitle));\n return lines;\n }\n getBeforeBody(tooltipItems, options) {\n return getBeforeAfterBodyLines(invokeCallbackWithFallback(options.callbacks, 'beforeBody', this, tooltipItems));\n }\n getBody(tooltipItems, options) {\n const { callbacks } = options;\n const bodyItems = [];\n each(tooltipItems, (context)=>{\n const bodyItem = {\n before: [],\n lines: [],\n after: []\n };\n const scoped = overrideCallbacks(callbacks, context);\n pushOrConcat(bodyItem.before, splitNewlines(invokeCallbackWithFallback(scoped, 'beforeLabel', this, context)));\n pushOrConcat(bodyItem.lines, invokeCallbackWithFallback(scoped, 'label', this, context));\n pushOrConcat(bodyItem.after, splitNewlines(invokeCallbackWithFallback(scoped, 'afterLabel', this, context)));\n bodyItems.push(bodyItem);\n });\n return bodyItems;\n }\n getAfterBody(tooltipItems, options) {\n return getBeforeAfterBodyLines(invokeCallbackWithFallback(options.callbacks, 'afterBody', this, tooltipItems));\n }\n getFooter(tooltipItems, options) {\n const { callbacks } = options;\n const beforeFooter = invokeCallbackWithFallback(callbacks, 'beforeFooter', this, tooltipItems);\n const footer = invokeCallbackWithFallback(callbacks, 'footer', this, tooltipItems);\n const afterFooter = invokeCallbackWithFallback(callbacks, 'afterFooter', this, tooltipItems);\n let lines = [];\n lines = pushOrConcat(lines, splitNewlines(beforeFooter));\n lines = pushOrConcat(lines, splitNewlines(footer));\n lines = pushOrConcat(lines, splitNewlines(afterFooter));\n return lines;\n }\n _createItems(options) {\n const active = this._active;\n const data = this.chart.data;\n const labelColors = [];\n const labelPointStyles = [];\n const labelTextColors = [];\n let tooltipItems = [];\n let i, len;\n for(i = 0, len = active.length; i < len; ++i){\n tooltipItems.push(createTooltipItem(this.chart, active[i]));\n }\n if (options.filter) {\n tooltipItems = tooltipItems.filter((element, index, array)=>options.filter(element, index, array, data));\n }\n if (options.itemSort) {\n tooltipItems = tooltipItems.sort((a, b)=>options.itemSort(a, b, data));\n }\n each(tooltipItems, (context)=>{\n const scoped = overrideCallbacks(options.callbacks, context);\n labelColors.push(invokeCallbackWithFallback(scoped, 'labelColor', this, context));\n labelPointStyles.push(invokeCallbackWithFallback(scoped, 'labelPointStyle', this, context));\n labelTextColors.push(invokeCallbackWithFallback(scoped, 'labelTextColor', this, context));\n });\n this.labelColors = labelColors;\n this.labelPointStyles = labelPointStyles;\n this.labelTextColors = labelTextColors;\n this.dataPoints = tooltipItems;\n return tooltipItems;\n }\n update(changed, replay) {\n const options = this.options.setContext(this.getContext());\n const active = this._active;\n let properties;\n let tooltipItems = [];\n if (!active.length) {\n if (this.opacity !== 0) {\n properties = {\n opacity: 0\n };\n }\n } else {\n const position = positioners[options.position].call(this, active, this._eventPosition);\n tooltipItems = this._createItems(options);\n this.title = this.getTitle(tooltipItems, options);\n this.beforeBody = this.getBeforeBody(tooltipItems, options);\n this.body = this.getBody(tooltipItems, options);\n this.afterBody = this.getAfterBody(tooltipItems, options);\n this.footer = this.getFooter(tooltipItems, options);\n const size = this._size = getTooltipSize(this, options);\n const positionAndSize = Object.assign({}, position, size);\n const alignment = determineAlignment(this.chart, options, positionAndSize);\n const backgroundPoint = getBackgroundPoint(options, positionAndSize, alignment, this.chart);\n this.xAlign = alignment.xAlign;\n this.yAlign = alignment.yAlign;\n properties = {\n opacity: 1,\n x: backgroundPoint.x,\n y: backgroundPoint.y,\n width: size.width,\n height: size.height,\n caretX: position.x,\n caretY: position.y\n };\n }\n this._tooltipItems = tooltipItems;\n this.$context = undefined;\n if (properties) {\n this._resolveAnimations().update(this, properties);\n }\n if (changed && options.external) {\n options.external.call(this, {\n chart: this.chart,\n tooltip: this,\n replay\n });\n }\n }\n drawCaret(tooltipPoint, ctx, size, options) {\n const caretPosition = this.getCaretPosition(tooltipPoint, size, options);\n ctx.lineTo(caretPosition.x1, caretPosition.y1);\n ctx.lineTo(caretPosition.x2, caretPosition.y2);\n ctx.lineTo(caretPosition.x3, caretPosition.y3);\n }\n getCaretPosition(tooltipPoint, size, options) {\n const { xAlign , yAlign } = this;\n const { caretSize , cornerRadius } = options;\n const { topLeft , topRight , bottomLeft , bottomRight } = toTRBLCorners(cornerRadius);\n const { x: ptX , y: ptY } = tooltipPoint;\n const { width , height } = size;\n let x1, x2, x3, y1, y2, y3;\n if (yAlign === 'center') {\n y2 = ptY + height / 2;\n if (xAlign === 'left') {\n x1 = ptX;\n x2 = x1 - caretSize;\n y1 = y2 + caretSize;\n y3 = y2 - caretSize;\n } else {\n x1 = ptX + width;\n x2 = x1 + caretSize;\n y1 = y2 - caretSize;\n y3 = y2 + caretSize;\n }\n x3 = x1;\n } else {\n if (xAlign === 'left') {\n x2 = ptX + Math.max(topLeft, bottomLeft) + caretSize;\n } else if (xAlign === 'right') {\n x2 = ptX + width - Math.max(topRight, bottomRight) - caretSize;\n } else {\n x2 = this.caretX;\n }\n if (yAlign === 'top') {\n y1 = ptY;\n y2 = y1 - caretSize;\n x1 = x2 - caretSize;\n x3 = x2 + caretSize;\n } else {\n y1 = ptY + height;\n y2 = y1 + caretSize;\n x1 = x2 + caretSize;\n x3 = x2 - caretSize;\n }\n y3 = y1;\n }\n return {\n x1,\n x2,\n x3,\n y1,\n y2,\n y3\n };\n }\n drawTitle(pt, ctx, options) {\n const title = this.title;\n const length = title.length;\n let titleFont, titleSpacing, i;\n if (length) {\n const rtlHelper = getRtlAdapter(options.rtl, this.x, this.width);\n pt.x = getAlignedX(this, options.titleAlign, options);\n ctx.textAlign = rtlHelper.textAlign(options.titleAlign);\n ctx.textBaseline = 'middle';\n titleFont = toFont(options.titleFont);\n titleSpacing = options.titleSpacing;\n ctx.fillStyle = options.titleColor;\n ctx.font = titleFont.string;\n for(i = 0; i < length; ++i){\n ctx.fillText(title[i], rtlHelper.x(pt.x), pt.y + titleFont.lineHeight / 2);\n pt.y += titleFont.lineHeight + titleSpacing;\n if (i + 1 === length) {\n pt.y += options.titleMarginBottom - titleSpacing;\n }\n }\n }\n }\n _drawColorBox(ctx, pt, i, rtlHelper, options) {\n const labelColor = this.labelColors[i];\n const labelPointStyle = this.labelPointStyles[i];\n const { boxHeight , boxWidth } = options;\n const bodyFont = toFont(options.bodyFont);\n const colorX = getAlignedX(this, 'left', options);\n const rtlColorX = rtlHelper.x(colorX);\n const yOffSet = boxHeight < bodyFont.lineHeight ? (bodyFont.lineHeight - boxHeight) / 2 : 0;\n const colorY = pt.y + yOffSet;\n if (options.usePointStyle) {\n const drawOptions = {\n radius: Math.min(boxWidth, boxHeight) / 2,\n pointStyle: labelPointStyle.pointStyle,\n rotation: labelPointStyle.rotation,\n borderWidth: 1\n };\n const centerX = rtlHelper.leftForLtr(rtlColorX, boxWidth) + boxWidth / 2;\n const centerY = colorY + boxHeight / 2;\n ctx.strokeStyle = options.multiKeyBackground;\n ctx.fillStyle = options.multiKeyBackground;\n drawPoint(ctx, drawOptions, centerX, centerY);\n ctx.strokeStyle = labelColor.borderColor;\n ctx.fillStyle = labelColor.backgroundColor;\n drawPoint(ctx, drawOptions, centerX, centerY);\n } else {\n ctx.lineWidth = isObject(labelColor.borderWidth) ? Math.max(...Object.values(labelColor.borderWidth)) : labelColor.borderWidth || 1;\n ctx.strokeStyle = labelColor.borderColor;\n ctx.setLineDash(labelColor.borderDash || []);\n ctx.lineDashOffset = labelColor.borderDashOffset || 0;\n const outerX = rtlHelper.leftForLtr(rtlColorX, boxWidth);\n const innerX = rtlHelper.leftForLtr(rtlHelper.xPlus(rtlColorX, 1), boxWidth - 2);\n const borderRadius = toTRBLCorners(labelColor.borderRadius);\n if (Object.values(borderRadius).some((v)=>v !== 0)) {\n ctx.beginPath();\n ctx.fillStyle = options.multiKeyBackground;\n addRoundedRectPath(ctx, {\n x: outerX,\n y: colorY,\n w: boxWidth,\n h: boxHeight,\n radius: borderRadius\n });\n ctx.fill();\n ctx.stroke();\n ctx.fillStyle = labelColor.backgroundColor;\n ctx.beginPath();\n addRoundedRectPath(ctx, {\n x: innerX,\n y: colorY + 1,\n w: boxWidth - 2,\n h: boxHeight - 2,\n radius: borderRadius\n });\n ctx.fill();\n } else {\n ctx.fillStyle = options.multiKeyBackground;\n ctx.fillRect(outerX, colorY, boxWidth, boxHeight);\n ctx.strokeRect(outerX, colorY, boxWidth, boxHeight);\n ctx.fillStyle = labelColor.backgroundColor;\n ctx.fillRect(innerX, colorY + 1, boxWidth - 2, boxHeight - 2);\n }\n }\n ctx.fillStyle = this.labelTextColors[i];\n }\n drawBody(pt, ctx, options) {\n const { body } = this;\n const { bodySpacing , bodyAlign , displayColors , boxHeight , boxWidth , boxPadding } = options;\n const bodyFont = toFont(options.bodyFont);\n let bodyLineHeight = bodyFont.lineHeight;\n let xLinePadding = 0;\n const rtlHelper = getRtlAdapter(options.rtl, this.x, this.width);\n const fillLineOfText = function(line) {\n ctx.fillText(line, rtlHelper.x(pt.x + xLinePadding), pt.y + bodyLineHeight / 2);\n pt.y += bodyLineHeight + bodySpacing;\n };\n const bodyAlignForCalculation = rtlHelper.textAlign(bodyAlign);\n let bodyItem, textColor, lines, i, j, ilen, jlen;\n ctx.textAlign = bodyAlign;\n ctx.textBaseline = 'middle';\n ctx.font = bodyFont.string;\n pt.x = getAlignedX(this, bodyAlignForCalculation, options);\n ctx.fillStyle = options.bodyColor;\n each(this.beforeBody, fillLineOfText);\n xLinePadding = displayColors && bodyAlignForCalculation !== 'right' ? bodyAlign === 'center' ? boxWidth / 2 + boxPadding : boxWidth + 2 + boxPadding : 0;\n for(i = 0, ilen = body.length; i < ilen; ++i){\n bodyItem = body[i];\n textColor = this.labelTextColors[i];\n ctx.fillStyle = textColor;\n each(bodyItem.before, fillLineOfText);\n lines = bodyItem.lines;\n if (displayColors && lines.length) {\n this._drawColorBox(ctx, pt, i, rtlHelper, options);\n bodyLineHeight = Math.max(bodyFont.lineHeight, boxHeight);\n }\n for(j = 0, jlen = lines.length; j < jlen; ++j){\n fillLineOfText(lines[j]);\n bodyLineHeight = bodyFont.lineHeight;\n }\n each(bodyItem.after, fillLineOfText);\n }\n xLinePadding = 0;\n bodyLineHeight = bodyFont.lineHeight;\n each(this.afterBody, fillLineOfText);\n pt.y -= bodySpacing;\n }\n drawFooter(pt, ctx, options) {\n const footer = this.footer;\n const length = footer.length;\n let footerFont, i;\n if (length) {\n const rtlHelper = getRtlAdapter(options.rtl, this.x, this.width);\n pt.x = getAlignedX(this, options.footerAlign, options);\n pt.y += options.footerMarginTop;\n ctx.textAlign = rtlHelper.textAlign(options.footerAlign);\n ctx.textBaseline = 'middle';\n footerFont = toFont(options.footerFont);\n ctx.fillStyle = options.footerColor;\n ctx.font = footerFont.string;\n for(i = 0; i < length; ++i){\n ctx.fillText(footer[i], rtlHelper.x(pt.x), pt.y + footerFont.lineHeight / 2);\n pt.y += footerFont.lineHeight + options.footerSpacing;\n }\n }\n }\n drawBackground(pt, ctx, tooltipSize, options) {\n const { xAlign , yAlign } = this;\n const { x , y } = pt;\n const { width , height } = tooltipSize;\n const { topLeft , topRight , bottomLeft , bottomRight } = toTRBLCorners(options.cornerRadius);\n ctx.fillStyle = options.backgroundColor;\n ctx.strokeStyle = options.borderColor;\n ctx.lineWidth = options.borderWidth;\n ctx.beginPath();\n ctx.moveTo(x + topLeft, y);\n if (yAlign === 'top') {\n this.drawCaret(pt, ctx, tooltipSize, options);\n }\n ctx.lineTo(x + width - topRight, y);\n ctx.quadraticCurveTo(x + width, y, x + width, y + topRight);\n if (yAlign === 'center' && xAlign === 'right') {\n this.drawCaret(pt, ctx, tooltipSize, options);\n }\n ctx.lineTo(x + width, y + height - bottomRight);\n ctx.quadraticCurveTo(x + width, y + height, x + width - bottomRight, y + height);\n if (yAlign === 'bottom') {\n this.drawCaret(pt, ctx, tooltipSize, options);\n }\n ctx.lineTo(x + bottomLeft, y + height);\n ctx.quadraticCurveTo(x, y + height, x, y + height - bottomLeft);\n if (yAlign === 'center' && xAlign === 'left') {\n this.drawCaret(pt, ctx, tooltipSize, options);\n }\n ctx.lineTo(x, y + topLeft);\n ctx.quadraticCurveTo(x, y, x + topLeft, y);\n ctx.closePath();\n ctx.fill();\n if (options.borderWidth > 0) {\n ctx.stroke();\n }\n }\n _updateAnimationTarget(options) {\n const chart = this.chart;\n const anims = this.$animations;\n const animX = anims && anims.x;\n const animY = anims && anims.y;\n if (animX || animY) {\n const position = positioners[options.position].call(this, this._active, this._eventPosition);\n if (!position) {\n return;\n }\n const size = this._size = getTooltipSize(this, options);\n const positionAndSize = Object.assign({}, position, this._size);\n const alignment = determineAlignment(chart, options, positionAndSize);\n const point = getBackgroundPoint(options, positionAndSize, alignment, chart);\n if (animX._to !== point.x || animY._to !== point.y) {\n this.xAlign = alignment.xAlign;\n this.yAlign = alignment.yAlign;\n this.width = size.width;\n this.height = size.height;\n this.caretX = position.x;\n this.caretY = position.y;\n this._resolveAnimations().update(this, point);\n }\n }\n }\n _willRender() {\n return !!this.opacity;\n }\n draw(ctx) {\n const options = this.options.setContext(this.getContext());\n let opacity = this.opacity;\n if (!opacity) {\n return;\n }\n this._updateAnimationTarget(options);\n const tooltipSize = {\n width: this.width,\n height: this.height\n };\n const pt = {\n x: this.x,\n y: this.y\n };\n opacity = Math.abs(opacity) < 1e-3 ? 0 : opacity;\n const padding = toPadding(options.padding);\n const hasTooltipContent = this.title.length || this.beforeBody.length || this.body.length || this.afterBody.length || this.footer.length;\n if (options.enabled && hasTooltipContent) {\n ctx.save();\n ctx.globalAlpha = opacity;\n this.drawBackground(pt, ctx, tooltipSize, options);\n overrideTextDirection(ctx, options.textDirection);\n pt.y += padding.top;\n this.drawTitle(pt, ctx, options);\n this.drawBody(pt, ctx, options);\n this.drawFooter(pt, ctx, options);\n restoreTextDirection(ctx, options.textDirection);\n ctx.restore();\n }\n }\n getActiveElements() {\n return this._active || [];\n }\n setActiveElements(activeElements, eventPosition) {\n const lastActive = this._active;\n const active = activeElements.map(({ datasetIndex , index })=>{\n const meta = this.chart.getDatasetMeta(datasetIndex);\n if (!meta) {\n throw new Error('Cannot find a dataset at index ' + datasetIndex);\n }\n return {\n datasetIndex,\n element: meta.data[index],\n index\n };\n });\n const changed = !_elementsEqual(lastActive, active);\n const positionChanged = this._positionChanged(active, eventPosition);\n if (changed || positionChanged) {\n this._active = active;\n this._eventPosition = eventPosition;\n this._ignoreReplayEvents = true;\n this.update(true);\n }\n }\n handleEvent(e, replay, inChartArea = true) {\n if (replay && this._ignoreReplayEvents) {\n return false;\n }\n this._ignoreReplayEvents = false;\n const options = this.options;\n const lastActive = this._active || [];\n const active = this._getActiveElements(e, lastActive, replay, inChartArea);\n const positionChanged = this._positionChanged(active, e);\n const changed = replay || !_elementsEqual(active, lastActive) || positionChanged;\n if (changed) {\n this._active = active;\n if (options.enabled || options.external) {\n this._eventPosition = {\n x: e.x,\n y: e.y\n };\n this.update(true, replay);\n }\n }\n return changed;\n }\n _getActiveElements(e, lastActive, replay, inChartArea) {\n const options = this.options;\n if (e.type === 'mouseout') {\n return [];\n }\n if (!inChartArea) {\n return lastActive.filter((i)=>this.chart.data.datasets[i.datasetIndex] && this.chart.getDatasetMeta(i.datasetIndex).controller.getParsed(i.index) !== undefined);\n }\n const active = this.chart.getElementsAtEventForMode(e, options.mode, options, replay);\n if (options.reverse) {\n active.reverse();\n }\n return active;\n }\n _positionChanged(active, e) {\n const { caretX , caretY , options } = this;\n const position = positioners[options.position].call(this, active, e);\n return position !== false && (caretX !== position.x || caretY !== position.y);\n }\n}\nvar plugin_tooltip = {\n id: 'tooltip',\n _element: Tooltip,\n positioners,\n afterInit (chart, _args, options) {\n if (options) {\n chart.tooltip = new Tooltip({\n chart,\n options\n });\n }\n },\n beforeUpdate (chart, _args, options) {\n if (chart.tooltip) {\n chart.tooltip.initialize(options);\n }\n },\n reset (chart, _args, options) {\n if (chart.tooltip) {\n chart.tooltip.initialize(options);\n }\n },\n afterDraw (chart) {\n const tooltip = chart.tooltip;\n if (tooltip && tooltip._willRender()) {\n const args = {\n tooltip\n };\n if (chart.notifyPlugins('beforeTooltipDraw', {\n ...args,\n cancelable: true\n }) === false) {\n return;\n }\n tooltip.draw(chart.ctx);\n chart.notifyPlugins('afterTooltipDraw', args);\n }\n },\n afterEvent (chart, args) {\n if (chart.tooltip) {\n const useFinalPosition = args.replay;\n if (chart.tooltip.handleEvent(args.event, useFinalPosition, args.inChartArea)) {\n args.changed = true;\n }\n }\n },\n defaults: {\n enabled: true,\n external: null,\n position: 'average',\n backgroundColor: 'rgba(0,0,0,0.8)',\n titleColor: '#fff',\n titleFont: {\n weight: 'bold'\n },\n titleSpacing: 2,\n titleMarginBottom: 6,\n titleAlign: 'left',\n bodyColor: '#fff',\n bodySpacing: 2,\n bodyFont: {},\n bodyAlign: 'left',\n footerColor: '#fff',\n footerSpacing: 2,\n footerMarginTop: 6,\n footerFont: {\n weight: 'bold'\n },\n footerAlign: 'left',\n padding: 6,\n caretPadding: 2,\n caretSize: 5,\n cornerRadius: 6,\n boxHeight: (ctx, opts)=>opts.bodyFont.size,\n boxWidth: (ctx, opts)=>opts.bodyFont.size,\n multiKeyBackground: '#fff',\n displayColors: true,\n boxPadding: 0,\n borderColor: 'rgba(0,0,0,0)',\n borderWidth: 0,\n animation: {\n duration: 400,\n easing: 'easeOutQuart'\n },\n animations: {\n numbers: {\n type: 'number',\n properties: [\n 'x',\n 'y',\n 'width',\n 'height',\n 'caretX',\n 'caretY'\n ]\n },\n opacity: {\n easing: 'linear',\n duration: 200\n }\n },\n callbacks: defaultCallbacks\n },\n defaultRoutes: {\n bodyFont: 'font',\n footerFont: 'font',\n titleFont: 'font'\n },\n descriptors: {\n _scriptable: (name)=>name !== 'filter' && name !== 'itemSort' && name !== 'external',\n _indexable: false,\n callbacks: {\n _scriptable: false,\n _indexable: false\n },\n animation: {\n _fallback: false\n },\n animations: {\n _fallback: 'animation'\n }\n },\n additionalOptionScopes: [\n 'interaction'\n ]\n};\n\nvar plugins = /*#__PURE__*/Object.freeze({\n__proto__: null,\nColors: plugin_colors,\nDecimation: plugin_decimation,\nFiller: index,\nLegend: plugin_legend,\nSubTitle: plugin_subtitle,\nTitle: plugin_title,\nTooltip: plugin_tooltip\n});\n\nconst addIfString = (labels, raw, index, addedLabels)=>{\n if (typeof raw === 'string') {\n index = labels.push(raw) - 1;\n addedLabels.unshift({\n index,\n label: raw\n });\n } else if (isNaN(raw)) {\n index = null;\n }\n return index;\n};\nfunction findOrAddLabel(labels, raw, index, addedLabels) {\n const first = labels.indexOf(raw);\n if (first === -1) {\n return addIfString(labels, raw, index, addedLabels);\n }\n const last = labels.lastIndexOf(raw);\n return first !== last ? index : first;\n}\nconst validIndex = (index, max)=>index === null ? null : _limitValue(Math.round(index), 0, max);\nfunction _getLabelForValue(value) {\n const labels = this.getLabels();\n if (value >= 0 && value < labels.length) {\n return labels[value];\n }\n return value;\n}\nclass CategoryScale extends Scale {\n static id = 'category';\n static defaults = {\n ticks: {\n callback: _getLabelForValue\n }\n };\n constructor(cfg){\n super(cfg);\n this._startValue = undefined;\n this._valueRange = 0;\n this._addedLabels = [];\n }\n init(scaleOptions) {\n const added = this._addedLabels;\n if (added.length) {\n const labels = this.getLabels();\n for (const { index , label } of added){\n if (labels[index] === label) {\n labels.splice(index, 1);\n }\n }\n this._addedLabels = [];\n }\n super.init(scaleOptions);\n }\n parse(raw, index) {\n if (isNullOrUndef(raw)) {\n return null;\n }\n const labels = this.getLabels();\n index = isFinite(index) && labels[index] === raw ? index : findOrAddLabel(labels, raw, valueOrDefault(index, raw), this._addedLabels);\n return validIndex(index, labels.length - 1);\n }\n determineDataLimits() {\n const { minDefined , maxDefined } = this.getUserBounds();\n let { min , max } = this.getMinMax(true);\n if (this.options.bounds === 'ticks') {\n if (!minDefined) {\n min = 0;\n }\n if (!maxDefined) {\n max = this.getLabels().length - 1;\n }\n }\n this.min = min;\n this.max = max;\n }\n buildTicks() {\n const min = this.min;\n const max = this.max;\n const offset = this.options.offset;\n const ticks = [];\n let labels = this.getLabels();\n labels = min === 0 && max === labels.length - 1 ? labels : labels.slice(min, max + 1);\n this._valueRange = Math.max(labels.length - (offset ? 0 : 1), 1);\n this._startValue = this.min - (offset ? 0.5 : 0);\n for(let value = min; value <= max; value++){\n ticks.push({\n value\n });\n }\n return ticks;\n }\n getLabelForValue(value) {\n return _getLabelForValue.call(this, value);\n }\n configure() {\n super.configure();\n if (!this.isHorizontal()) {\n this._reversePixels = !this._reversePixels;\n }\n }\n getPixelForValue(value) {\n if (typeof value !== 'number') {\n value = this.parse(value);\n }\n return value === null ? NaN : this.getPixelForDecimal((value - this._startValue) / this._valueRange);\n }\n getPixelForTick(index) {\n const ticks = this.ticks;\n if (index < 0 || index > ticks.length - 1) {\n return null;\n }\n return this.getPixelForValue(ticks[index].value);\n }\n getValueForPixel(pixel) {\n return Math.round(this._startValue + this.getDecimalForPixel(pixel) * this._valueRange);\n }\n getBasePixel() {\n return this.bottom;\n }\n}\n\nfunction generateTicks$1(generationOptions, dataRange) {\n const ticks = [];\n const MIN_SPACING = 1e-14;\n const { bounds , step , min , max , precision , count , maxTicks , maxDigits , includeBounds } = generationOptions;\n const unit = step || 1;\n const maxSpaces = maxTicks - 1;\n const { min: rmin , max: rmax } = dataRange;\n const minDefined = !isNullOrUndef(min);\n const maxDefined = !isNullOrUndef(max);\n const countDefined = !isNullOrUndef(count);\n const minSpacing = (rmax - rmin) / (maxDigits + 1);\n let spacing = niceNum((rmax - rmin) / maxSpaces / unit) * unit;\n let factor, niceMin, niceMax, numSpaces;\n if (spacing < MIN_SPACING && !minDefined && !maxDefined) {\n return [\n {\n value: rmin\n },\n {\n value: rmax\n }\n ];\n }\n numSpaces = Math.ceil(rmax / spacing) - Math.floor(rmin / spacing);\n if (numSpaces > maxSpaces) {\n spacing = niceNum(numSpaces * spacing / maxSpaces / unit) * unit;\n }\n if (!isNullOrUndef(precision)) {\n factor = Math.pow(10, precision);\n spacing = Math.ceil(spacing * factor) / factor;\n }\n if (bounds === 'ticks') {\n niceMin = Math.floor(rmin / spacing) * spacing;\n niceMax = Math.ceil(rmax / spacing) * spacing;\n } else {\n niceMin = rmin;\n niceMax = rmax;\n }\n if (minDefined && maxDefined && step && almostWhole((max - min) / step, spacing / 1000)) {\n numSpaces = Math.round(Math.min((max - min) / spacing, maxTicks));\n spacing = (max - min) / numSpaces;\n niceMin = min;\n niceMax = max;\n } else if (countDefined) {\n niceMin = minDefined ? min : niceMin;\n niceMax = maxDefined ? max : niceMax;\n numSpaces = count - 1;\n spacing = (niceMax - niceMin) / numSpaces;\n } else {\n numSpaces = (niceMax - niceMin) / spacing;\n if (almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) {\n numSpaces = Math.round(numSpaces);\n } else {\n numSpaces = Math.ceil(numSpaces);\n }\n }\n const decimalPlaces = Math.max(_decimalPlaces(spacing), _decimalPlaces(niceMin));\n factor = Math.pow(10, isNullOrUndef(precision) ? decimalPlaces : precision);\n niceMin = Math.round(niceMin * factor) / factor;\n niceMax = Math.round(niceMax * factor) / factor;\n let j = 0;\n if (minDefined) {\n if (includeBounds && niceMin !== min) {\n ticks.push({\n value: min\n });\n if (niceMin < min) {\n j++;\n }\n if (almostEquals(Math.round((niceMin + j * spacing) * factor) / factor, min, relativeLabelSize(min, minSpacing, generationOptions))) {\n j++;\n }\n } else if (niceMin < min) {\n j++;\n }\n }\n for(; j < numSpaces; ++j){\n const tickValue = Math.round((niceMin + j * spacing) * factor) / factor;\n if (maxDefined && tickValue > max) {\n break;\n }\n ticks.push({\n value: tickValue\n });\n }\n if (maxDefined && includeBounds && niceMax !== max) {\n if (ticks.length && almostEquals(ticks[ticks.length - 1].value, max, relativeLabelSize(max, minSpacing, generationOptions))) {\n ticks[ticks.length - 1].value = max;\n } else {\n ticks.push({\n value: max\n });\n }\n } else if (!maxDefined || niceMax === max) {\n ticks.push({\n value: niceMax\n });\n }\n return ticks;\n}\nfunction relativeLabelSize(value, minSpacing, { horizontal , minRotation }) {\n const rad = toRadians(minRotation);\n const ratio = (horizontal ? Math.sin(rad) : Math.cos(rad)) || 0.001;\n const length = 0.75 * minSpacing * ('' + value).length;\n return Math.min(minSpacing / ratio, length);\n}\nclass LinearScaleBase extends Scale {\n constructor(cfg){\n super(cfg);\n this.start = undefined;\n this.end = undefined;\n this._startValue = undefined;\n this._endValue = undefined;\n this._valueRange = 0;\n }\n parse(raw, index) {\n if (isNullOrUndef(raw)) {\n return null;\n }\n if ((typeof raw === 'number' || raw instanceof Number) && !isFinite(+raw)) {\n return null;\n }\n return +raw;\n }\n handleTickRangeOptions() {\n const { beginAtZero } = this.options;\n const { minDefined , maxDefined } = this.getUserBounds();\n let { min , max } = this;\n const setMin = (v)=>min = minDefined ? min : v;\n const setMax = (v)=>max = maxDefined ? max : v;\n if (beginAtZero) {\n const minSign = sign(min);\n const maxSign = sign(max);\n if (minSign < 0 && maxSign < 0) {\n setMax(0);\n } else if (minSign > 0 && maxSign > 0) {\n setMin(0);\n }\n }\n if (min === max) {\n let offset = max === 0 ? 1 : Math.abs(max * 0.05);\n setMax(max + offset);\n if (!beginAtZero) {\n setMin(min - offset);\n }\n }\n this.min = min;\n this.max = max;\n }\n getTickLimit() {\n const tickOpts = this.options.ticks;\n let { maxTicksLimit , stepSize } = tickOpts;\n let maxTicks;\n if (stepSize) {\n maxTicks = Math.ceil(this.max / stepSize) - Math.floor(this.min / stepSize) + 1;\n if (maxTicks > 1000) {\n console.warn(`scales.${this.id}.ticks.stepSize: ${stepSize} would result generating up to ${maxTicks} ticks. Limiting to 1000.`);\n maxTicks = 1000;\n }\n } else {\n maxTicks = this.computeTickLimit();\n maxTicksLimit = maxTicksLimit || 11;\n }\n if (maxTicksLimit) {\n maxTicks = Math.min(maxTicksLimit, maxTicks);\n }\n return maxTicks;\n }\n computeTickLimit() {\n return Number.POSITIVE_INFINITY;\n }\n buildTicks() {\n const opts = this.options;\n const tickOpts = opts.ticks;\n let maxTicks = this.getTickLimit();\n maxTicks = Math.max(2, maxTicks);\n const numericGeneratorOptions = {\n maxTicks,\n bounds: opts.bounds,\n min: opts.min,\n max: opts.max,\n precision: tickOpts.precision,\n step: tickOpts.stepSize,\n count: tickOpts.count,\n maxDigits: this._maxDigits(),\n horizontal: this.isHorizontal(),\n minRotation: tickOpts.minRotation || 0,\n includeBounds: tickOpts.includeBounds !== false\n };\n const dataRange = this._range || this;\n const ticks = generateTicks$1(numericGeneratorOptions, dataRange);\n if (opts.bounds === 'ticks') {\n _setMinAndMaxByKey(ticks, this, 'value');\n }\n if (opts.reverse) {\n ticks.reverse();\n this.start = this.max;\n this.end = this.min;\n } else {\n this.start = this.min;\n this.end = this.max;\n }\n return ticks;\n }\n configure() {\n const ticks = this.ticks;\n let start = this.min;\n let end = this.max;\n super.configure();\n if (this.options.offset && ticks.length) {\n const offset = (end - start) / Math.max(ticks.length - 1, 1) / 2;\n start -= offset;\n end += offset;\n }\n this._startValue = start;\n this._endValue = end;\n this._valueRange = end - start;\n }\n getLabelForValue(value) {\n return formatNumber(value, this.chart.options.locale, this.options.ticks.format);\n }\n}\n\nclass LinearScale extends LinearScaleBase {\n static id = 'linear';\n static defaults = {\n ticks: {\n callback: Ticks.formatters.numeric\n }\n };\n determineDataLimits() {\n const { min , max } = this.getMinMax(true);\n this.min = isNumberFinite(min) ? min : 0;\n this.max = isNumberFinite(max) ? max : 1;\n this.handleTickRangeOptions();\n }\n computeTickLimit() {\n const horizontal = this.isHorizontal();\n const length = horizontal ? this.width : this.height;\n const minRotation = toRadians(this.options.ticks.minRotation);\n const ratio = (horizontal ? Math.sin(minRotation) : Math.cos(minRotation)) || 0.001;\n const tickFont = this._resolveTickFontOptions(0);\n return Math.ceil(length / Math.min(40, tickFont.lineHeight / ratio));\n }\n getPixelForValue(value) {\n return value === null ? NaN : this.getPixelForDecimal((value - this._startValue) / this._valueRange);\n }\n getValueForPixel(pixel) {\n return this._startValue + this.getDecimalForPixel(pixel) * this._valueRange;\n }\n}\n\nconst log10Floor = (v)=>Math.floor(log10(v));\nconst changeExponent = (v, m)=>Math.pow(10, log10Floor(v) + m);\nfunction isMajor(tickVal) {\n const remain = tickVal / Math.pow(10, log10Floor(tickVal));\n return remain === 1;\n}\nfunction steps(min, max, rangeExp) {\n const rangeStep = Math.pow(10, rangeExp);\n const start = Math.floor(min / rangeStep);\n const end = Math.ceil(max / rangeStep);\n return end - start;\n}\nfunction startExp(min, max) {\n const range = max - min;\n let rangeExp = log10Floor(range);\n while(steps(min, max, rangeExp) > 10){\n rangeExp++;\n }\n while(steps(min, max, rangeExp) < 10){\n rangeExp--;\n }\n return Math.min(rangeExp, log10Floor(min));\n}\n function generateTicks(generationOptions, { min , max }) {\n min = finiteOrDefault(generationOptions.min, min);\n const ticks = [];\n const minExp = log10Floor(min);\n let exp = startExp(min, max);\n let precision = exp < 0 ? Math.pow(10, Math.abs(exp)) : 1;\n const stepSize = Math.pow(10, exp);\n const base = minExp > exp ? Math.pow(10, minExp) : 0;\n const start = Math.round((min - base) * precision) / precision;\n const offset = Math.floor((min - base) / stepSize / 10) * stepSize * 10;\n let significand = Math.floor((start - offset) / Math.pow(10, exp));\n let value = finiteOrDefault(generationOptions.min, Math.round((base + offset + significand * Math.pow(10, exp)) * precision) / precision);\n while(value < max){\n ticks.push({\n value,\n major: isMajor(value),\n significand\n });\n if (significand >= 10) {\n significand = significand < 15 ? 15 : 20;\n } else {\n significand++;\n }\n if (significand >= 20) {\n exp++;\n significand = 2;\n precision = exp >= 0 ? 1 : precision;\n }\n value = Math.round((base + offset + significand * Math.pow(10, exp)) * precision) / precision;\n }\n const lastTick = finiteOrDefault(generationOptions.max, value);\n ticks.push({\n value: lastTick,\n major: isMajor(lastTick),\n significand\n });\n return ticks;\n}\nclass LogarithmicScale extends Scale {\n static id = 'logarithmic';\n static defaults = {\n ticks: {\n callback: Ticks.formatters.logarithmic,\n major: {\n enabled: true\n }\n }\n };\n constructor(cfg){\n super(cfg);\n this.start = undefined;\n this.end = undefined;\n this._startValue = undefined;\n this._valueRange = 0;\n }\n parse(raw, index) {\n const value = LinearScaleBase.prototype.parse.apply(this, [\n raw,\n index\n ]);\n if (value === 0) {\n this._zero = true;\n return undefined;\n }\n return isNumberFinite(value) && value > 0 ? value : null;\n }\n determineDataLimits() {\n const { min , max } = this.getMinMax(true);\n this.min = isNumberFinite(min) ? Math.max(0, min) : null;\n this.max = isNumberFinite(max) ? Math.max(0, max) : null;\n if (this.options.beginAtZero) {\n this._zero = true;\n }\n if (this._zero && this.min !== this._suggestedMin && !isNumberFinite(this._userMin)) {\n this.min = min === changeExponent(this.min, 0) ? changeExponent(this.min, -1) : changeExponent(this.min, 0);\n }\n this.handleTickRangeOptions();\n }\n handleTickRangeOptions() {\n const { minDefined , maxDefined } = this.getUserBounds();\n let min = this.min;\n let max = this.max;\n const setMin = (v)=>min = minDefined ? min : v;\n const setMax = (v)=>max = maxDefined ? max : v;\n if (min === max) {\n if (min <= 0) {\n setMin(1);\n setMax(10);\n } else {\n setMin(changeExponent(min, -1));\n setMax(changeExponent(max, +1));\n }\n }\n if (min <= 0) {\n setMin(changeExponent(max, -1));\n }\n if (max <= 0) {\n setMax(changeExponent(min, +1));\n }\n this.min = min;\n this.max = max;\n }\n buildTicks() {\n const opts = this.options;\n const generationOptions = {\n min: this._userMin,\n max: this._userMax\n };\n const ticks = generateTicks(generationOptions, this);\n if (opts.bounds === 'ticks') {\n _setMinAndMaxByKey(ticks, this, 'value');\n }\n if (opts.reverse) {\n ticks.reverse();\n this.start = this.max;\n this.end = this.min;\n } else {\n this.start = this.min;\n this.end = this.max;\n }\n return ticks;\n }\n getLabelForValue(value) {\n return value === undefined ? '0' : formatNumber(value, this.chart.options.locale, this.options.ticks.format);\n }\n configure() {\n const start = this.min;\n super.configure();\n this._startValue = log10(start);\n this._valueRange = log10(this.max) - log10(start);\n }\n getPixelForValue(value) {\n if (value === undefined || value === 0) {\n value = this.min;\n }\n if (value === null || isNaN(value)) {\n return NaN;\n }\n return this.getPixelForDecimal(value === this.min ? 0 : (log10(value) - this._startValue) / this._valueRange);\n }\n getValueForPixel(pixel) {\n const decimal = this.getDecimalForPixel(pixel);\n return Math.pow(10, this._startValue + decimal * this._valueRange);\n }\n}\n\nfunction getTickBackdropHeight(opts) {\n const tickOpts = opts.ticks;\n if (tickOpts.display && opts.display) {\n const padding = toPadding(tickOpts.backdropPadding);\n return valueOrDefault(tickOpts.font && tickOpts.font.size, defaults.font.size) + padding.height;\n }\n return 0;\n}\nfunction measureLabelSize(ctx, font, label) {\n label = isArray(label) ? label : [\n label\n ];\n return {\n w: _longestText(ctx, font.string, label),\n h: label.length * font.lineHeight\n };\n}\nfunction determineLimits(angle, pos, size, min, max) {\n if (angle === min || angle === max) {\n return {\n start: pos - size / 2,\n end: pos + size / 2\n };\n } else if (angle < min || angle > max) {\n return {\n start: pos - size,\n end: pos\n };\n }\n return {\n start: pos,\n end: pos + size\n };\n}\n function fitWithPointLabels(scale) {\n const orig = {\n l: scale.left + scale._padding.left,\n r: scale.right - scale._padding.right,\n t: scale.top + scale._padding.top,\n b: scale.bottom - scale._padding.bottom\n };\n const limits = Object.assign({}, orig);\n const labelSizes = [];\n const padding = [];\n const valueCount = scale._pointLabels.length;\n const pointLabelOpts = scale.options.pointLabels;\n const additionalAngle = pointLabelOpts.centerPointLabels ? PI / valueCount : 0;\n for(let i = 0; i < valueCount; i++){\n const opts = pointLabelOpts.setContext(scale.getPointLabelContext(i));\n padding[i] = opts.padding;\n const pointPosition = scale.getPointPosition(i, scale.drawingArea + padding[i], additionalAngle);\n const plFont = toFont(opts.font);\n const textSize = measureLabelSize(scale.ctx, plFont, scale._pointLabels[i]);\n labelSizes[i] = textSize;\n const angleRadians = _normalizeAngle(scale.getIndexAngle(i) + additionalAngle);\n const angle = Math.round(toDegrees(angleRadians));\n const hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180);\n const vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270);\n updateLimits(limits, orig, angleRadians, hLimits, vLimits);\n }\n scale.setCenterPoint(orig.l - limits.l, limits.r - orig.r, orig.t - limits.t, limits.b - orig.b);\n scale._pointLabelItems = buildPointLabelItems(scale, labelSizes, padding);\n}\nfunction updateLimits(limits, orig, angle, hLimits, vLimits) {\n const sin = Math.abs(Math.sin(angle));\n const cos = Math.abs(Math.cos(angle));\n let x = 0;\n let y = 0;\n if (hLimits.start < orig.l) {\n x = (orig.l - hLimits.start) / sin;\n limits.l = Math.min(limits.l, orig.l - x);\n } else if (hLimits.end > orig.r) {\n x = (hLimits.end - orig.r) / sin;\n limits.r = Math.max(limits.r, orig.r + x);\n }\n if (vLimits.start < orig.t) {\n y = (orig.t - vLimits.start) / cos;\n limits.t = Math.min(limits.t, orig.t - y);\n } else if (vLimits.end > orig.b) {\n y = (vLimits.end - orig.b) / cos;\n limits.b = Math.max(limits.b, orig.b + y);\n }\n}\nfunction createPointLabelItem(scale, index, itemOpts) {\n const outerDistance = scale.drawingArea;\n const { extra , additionalAngle , padding , size } = itemOpts;\n const pointLabelPosition = scale.getPointPosition(index, outerDistance + extra + padding, additionalAngle);\n const angle = Math.round(toDegrees(_normalizeAngle(pointLabelPosition.angle + HALF_PI)));\n const y = yForAngle(pointLabelPosition.y, size.h, angle);\n const textAlign = getTextAlignForAngle(angle);\n const left = leftForTextAlign(pointLabelPosition.x, size.w, textAlign);\n return {\n visible: true,\n x: pointLabelPosition.x,\n y,\n textAlign,\n left,\n top: y,\n right: left + size.w,\n bottom: y + size.h\n };\n}\nfunction isNotOverlapped(item, area) {\n if (!area) {\n return true;\n }\n const { left , top , right , bottom } = item;\n const apexesInArea = _isPointInArea({\n x: left,\n y: top\n }, area) || _isPointInArea({\n x: left,\n y: bottom\n }, area) || _isPointInArea({\n x: right,\n y: top\n }, area) || _isPointInArea({\n x: right,\n y: bottom\n }, area);\n return !apexesInArea;\n}\nfunction buildPointLabelItems(scale, labelSizes, padding) {\n const items = [];\n const valueCount = scale._pointLabels.length;\n const opts = scale.options;\n const { centerPointLabels , display } = opts.pointLabels;\n const itemOpts = {\n extra: getTickBackdropHeight(opts) / 2,\n additionalAngle: centerPointLabels ? PI / valueCount : 0\n };\n let area;\n for(let i = 0; i < valueCount; i++){\n itemOpts.padding = padding[i];\n itemOpts.size = labelSizes[i];\n const item = createPointLabelItem(scale, i, itemOpts);\n items.push(item);\n if (display === 'auto') {\n item.visible = isNotOverlapped(item, area);\n if (item.visible) {\n area = item;\n }\n }\n }\n return items;\n}\nfunction getTextAlignForAngle(angle) {\n if (angle === 0 || angle === 180) {\n return 'center';\n } else if (angle < 180) {\n return 'left';\n }\n return 'right';\n}\nfunction leftForTextAlign(x, w, align) {\n if (align === 'right') {\n x -= w;\n } else if (align === 'center') {\n x -= w / 2;\n }\n return x;\n}\nfunction yForAngle(y, h, angle) {\n if (angle === 90 || angle === 270) {\n y -= h / 2;\n } else if (angle > 270 || angle < 90) {\n y -= h;\n }\n return y;\n}\nfunction drawPointLabelBox(ctx, opts, item) {\n const { left , top , right , bottom } = item;\n const { backdropColor } = opts;\n if (!isNullOrUndef(backdropColor)) {\n const borderRadius = toTRBLCorners(opts.borderRadius);\n const padding = toPadding(opts.backdropPadding);\n ctx.fillStyle = backdropColor;\n const backdropLeft = left - padding.left;\n const backdropTop = top - padding.top;\n const backdropWidth = right - left + padding.width;\n const backdropHeight = bottom - top + padding.height;\n if (Object.values(borderRadius).some((v)=>v !== 0)) {\n ctx.beginPath();\n addRoundedRectPath(ctx, {\n x: backdropLeft,\n y: backdropTop,\n w: backdropWidth,\n h: backdropHeight,\n radius: borderRadius\n });\n ctx.fill();\n } else {\n ctx.fillRect(backdropLeft, backdropTop, backdropWidth, backdropHeight);\n }\n }\n}\nfunction drawPointLabels(scale, labelCount) {\n const { ctx , options: { pointLabels } } = scale;\n for(let i = labelCount - 1; i >= 0; i--){\n const item = scale._pointLabelItems[i];\n if (!item.visible) {\n continue;\n }\n const optsAtIndex = pointLabels.setContext(scale.getPointLabelContext(i));\n drawPointLabelBox(ctx, optsAtIndex, item);\n const plFont = toFont(optsAtIndex.font);\n const { x , y , textAlign } = item;\n renderText(ctx, scale._pointLabels[i], x, y + plFont.lineHeight / 2, plFont, {\n color: optsAtIndex.color,\n textAlign: textAlign,\n textBaseline: 'middle'\n });\n }\n}\nfunction pathRadiusLine(scale, radius, circular, labelCount) {\n const { ctx } = scale;\n if (circular) {\n ctx.arc(scale.xCenter, scale.yCenter, radius, 0, TAU);\n } else {\n let pointPosition = scale.getPointPosition(0, radius);\n ctx.moveTo(pointPosition.x, pointPosition.y);\n for(let i = 1; i < labelCount; i++){\n pointPosition = scale.getPointPosition(i, radius);\n ctx.lineTo(pointPosition.x, pointPosition.y);\n }\n }\n}\nfunction drawRadiusLine(scale, gridLineOpts, radius, labelCount, borderOpts) {\n const ctx = scale.ctx;\n const circular = gridLineOpts.circular;\n const { color , lineWidth } = gridLineOpts;\n if (!circular && !labelCount || !color || !lineWidth || radius < 0) {\n return;\n }\n ctx.save();\n ctx.strokeStyle = color;\n ctx.lineWidth = lineWidth;\n ctx.setLineDash(borderOpts.dash);\n ctx.lineDashOffset = borderOpts.dashOffset;\n ctx.beginPath();\n pathRadiusLine(scale, radius, circular, labelCount);\n ctx.closePath();\n ctx.stroke();\n ctx.restore();\n}\nfunction createPointLabelContext(parent, index, label) {\n return createContext(parent, {\n label,\n index,\n type: 'pointLabel'\n });\n}\nclass RadialLinearScale extends LinearScaleBase {\n static id = 'radialLinear';\n static defaults = {\n display: true,\n animate: true,\n position: 'chartArea',\n angleLines: {\n display: true,\n lineWidth: 1,\n borderDash: [],\n borderDashOffset: 0.0\n },\n grid: {\n circular: false\n },\n startAngle: 0,\n ticks: {\n showLabelBackdrop: true,\n callback: Ticks.formatters.numeric\n },\n pointLabels: {\n backdropColor: undefined,\n backdropPadding: 2,\n display: true,\n font: {\n size: 10\n },\n callback (label) {\n return label;\n },\n padding: 5,\n centerPointLabels: false\n }\n };\n static defaultRoutes = {\n 'angleLines.color': 'borderColor',\n 'pointLabels.color': 'color',\n 'ticks.color': 'color'\n };\n static descriptors = {\n angleLines: {\n _fallback: 'grid'\n }\n };\n constructor(cfg){\n super(cfg);\n this.xCenter = undefined;\n this.yCenter = undefined;\n this.drawingArea = undefined;\n this._pointLabels = [];\n this._pointLabelItems = [];\n }\n setDimensions() {\n const padding = this._padding = toPadding(getTickBackdropHeight(this.options) / 2);\n const w = this.width = this.maxWidth - padding.width;\n const h = this.height = this.maxHeight - padding.height;\n this.xCenter = Math.floor(this.left + w / 2 + padding.left);\n this.yCenter = Math.floor(this.top + h / 2 + padding.top);\n this.drawingArea = Math.floor(Math.min(w, h) / 2);\n }\n determineDataLimits() {\n const { min , max } = this.getMinMax(false);\n this.min = isNumberFinite(min) && !isNaN(min) ? min : 0;\n this.max = isNumberFinite(max) && !isNaN(max) ? max : 0;\n this.handleTickRangeOptions();\n }\n computeTickLimit() {\n return Math.ceil(this.drawingArea / getTickBackdropHeight(this.options));\n }\n generateTickLabels(ticks) {\n LinearScaleBase.prototype.generateTickLabels.call(this, ticks);\n this._pointLabels = this.getLabels().map((value, index)=>{\n const label = callback(this.options.pointLabels.callback, [\n value,\n index\n ], this);\n return label || label === 0 ? label : '';\n }).filter((v, i)=>this.chart.getDataVisibility(i));\n }\n fit() {\n const opts = this.options;\n if (opts.display && opts.pointLabels.display) {\n fitWithPointLabels(this);\n } else {\n this.setCenterPoint(0, 0, 0, 0);\n }\n }\n setCenterPoint(leftMovement, rightMovement, topMovement, bottomMovement) {\n this.xCenter += Math.floor((leftMovement - rightMovement) / 2);\n this.yCenter += Math.floor((topMovement - bottomMovement) / 2);\n this.drawingArea -= Math.min(this.drawingArea / 2, Math.max(leftMovement, rightMovement, topMovement, bottomMovement));\n }\n getIndexAngle(index) {\n const angleMultiplier = TAU / (this._pointLabels.length || 1);\n const startAngle = this.options.startAngle || 0;\n return _normalizeAngle(index * angleMultiplier + toRadians(startAngle));\n }\n getDistanceFromCenterForValue(value) {\n if (isNullOrUndef(value)) {\n return NaN;\n }\n const scalingFactor = this.drawingArea / (this.max - this.min);\n if (this.options.reverse) {\n return (this.max - value) * scalingFactor;\n }\n return (value - this.min) * scalingFactor;\n }\n getValueForDistanceFromCenter(distance) {\n if (isNullOrUndef(distance)) {\n return NaN;\n }\n const scaledDistance = distance / (this.drawingArea / (this.max - this.min));\n return this.options.reverse ? this.max - scaledDistance : this.min + scaledDistance;\n }\n getPointLabelContext(index) {\n const pointLabels = this._pointLabels || [];\n if (index >= 0 && index < pointLabels.length) {\n const pointLabel = pointLabels[index];\n return createPointLabelContext(this.getContext(), index, pointLabel);\n }\n }\n getPointPosition(index, distanceFromCenter, additionalAngle = 0) {\n const angle = this.getIndexAngle(index) - HALF_PI + additionalAngle;\n return {\n x: Math.cos(angle) * distanceFromCenter + this.xCenter,\n y: Math.sin(angle) * distanceFromCenter + this.yCenter,\n angle\n };\n }\n getPointPositionForValue(index, value) {\n return this.getPointPosition(index, this.getDistanceFromCenterForValue(value));\n }\n getBasePosition(index) {\n return this.getPointPositionForValue(index || 0, this.getBaseValue());\n }\n getPointLabelPosition(index) {\n const { left , top , right , bottom } = this._pointLabelItems[index];\n return {\n left,\n top,\n right,\n bottom\n };\n }\n drawBackground() {\n const { backgroundColor , grid: { circular } } = this.options;\n if (backgroundColor) {\n const ctx = this.ctx;\n ctx.save();\n ctx.beginPath();\n pathRadiusLine(this, this.getDistanceFromCenterForValue(this._endValue), circular, this._pointLabels.length);\n ctx.closePath();\n ctx.fillStyle = backgroundColor;\n ctx.fill();\n ctx.restore();\n }\n }\n drawGrid() {\n const ctx = this.ctx;\n const opts = this.options;\n const { angleLines , grid , border } = opts;\n const labelCount = this._pointLabels.length;\n let i, offset, position;\n if (opts.pointLabels.display) {\n drawPointLabels(this, labelCount);\n }\n if (grid.display) {\n this.ticks.forEach((tick, index)=>{\n if (index !== 0 || index === 0 && this.min < 0) {\n offset = this.getDistanceFromCenterForValue(tick.value);\n const context = this.getContext(index);\n const optsAtIndex = grid.setContext(context);\n const optsAtIndexBorder = border.setContext(context);\n drawRadiusLine(this, optsAtIndex, offset, labelCount, optsAtIndexBorder);\n }\n });\n }\n if (angleLines.display) {\n ctx.save();\n for(i = labelCount - 1; i >= 0; i--){\n const optsAtIndex = angleLines.setContext(this.getPointLabelContext(i));\n const { color , lineWidth } = optsAtIndex;\n if (!lineWidth || !color) {\n continue;\n }\n ctx.lineWidth = lineWidth;\n ctx.strokeStyle = color;\n ctx.setLineDash(optsAtIndex.borderDash);\n ctx.lineDashOffset = optsAtIndex.borderDashOffset;\n offset = this.getDistanceFromCenterForValue(opts.reverse ? this.min : this.max);\n position = this.getPointPosition(i, offset);\n ctx.beginPath();\n ctx.moveTo(this.xCenter, this.yCenter);\n ctx.lineTo(position.x, position.y);\n ctx.stroke();\n }\n ctx.restore();\n }\n }\n drawBorder() {}\n drawLabels() {\n const ctx = this.ctx;\n const opts = this.options;\n const tickOpts = opts.ticks;\n if (!tickOpts.display) {\n return;\n }\n const startAngle = this.getIndexAngle(0);\n let offset, width;\n ctx.save();\n ctx.translate(this.xCenter, this.yCenter);\n ctx.rotate(startAngle);\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n this.ticks.forEach((tick, index)=>{\n if (index === 0 && this.min >= 0 && !opts.reverse) {\n return;\n }\n const optsAtIndex = tickOpts.setContext(this.getContext(index));\n const tickFont = toFont(optsAtIndex.font);\n offset = this.getDistanceFromCenterForValue(this.ticks[index].value);\n if (optsAtIndex.showLabelBackdrop) {\n ctx.font = tickFont.string;\n width = ctx.measureText(tick.label).width;\n ctx.fillStyle = optsAtIndex.backdropColor;\n const padding = toPadding(optsAtIndex.backdropPadding);\n ctx.fillRect(-width / 2 - padding.left, -offset - tickFont.size / 2 - padding.top, width + padding.width, tickFont.size + padding.height);\n }\n renderText(ctx, tick.label, 0, -offset, tickFont, {\n color: optsAtIndex.color,\n strokeColor: optsAtIndex.textStrokeColor,\n strokeWidth: optsAtIndex.textStrokeWidth\n });\n });\n ctx.restore();\n }\n drawTitle() {}\n}\n\nconst INTERVALS = {\n millisecond: {\n common: true,\n size: 1,\n steps: 1000\n },\n second: {\n common: true,\n size: 1000,\n steps: 60\n },\n minute: {\n common: true,\n size: 60000,\n steps: 60\n },\n hour: {\n common: true,\n size: 3600000,\n steps: 24\n },\n day: {\n common: true,\n size: 86400000,\n steps: 30\n },\n week: {\n common: false,\n size: 604800000,\n steps: 4\n },\n month: {\n common: true,\n size: 2.628e9,\n steps: 12\n },\n quarter: {\n common: false,\n size: 7.884e9,\n steps: 4\n },\n year: {\n common: true,\n size: 3.154e10\n }\n};\n const UNITS = /* #__PURE__ */ Object.keys(INTERVALS);\n function sorter(a, b) {\n return a - b;\n}\n function parse(scale, input) {\n if (isNullOrUndef(input)) {\n return null;\n }\n const adapter = scale._adapter;\n const { parser , round , isoWeekday } = scale._parseOpts;\n let value = input;\n if (typeof parser === 'function') {\n value = parser(value);\n }\n if (!isNumberFinite(value)) {\n value = typeof parser === 'string' ? adapter.parse(value, parser) : adapter.parse(value);\n }\n if (value === null) {\n return null;\n }\n if (round) {\n value = round === 'week' && (isNumber(isoWeekday) || isoWeekday === true) ? adapter.startOf(value, 'isoWeek', isoWeekday) : adapter.startOf(value, round);\n }\n return +value;\n}\n function determineUnitForAutoTicks(minUnit, min, max, capacity) {\n const ilen = UNITS.length;\n for(let i = UNITS.indexOf(minUnit); i < ilen - 1; ++i){\n const interval = INTERVALS[UNITS[i]];\n const factor = interval.steps ? interval.steps : Number.MAX_SAFE_INTEGER;\n if (interval.common && Math.ceil((max - min) / (factor * interval.size)) <= capacity) {\n return UNITS[i];\n }\n }\n return UNITS[ilen - 1];\n}\n function determineUnitForFormatting(scale, numTicks, minUnit, min, max) {\n for(let i = UNITS.length - 1; i >= UNITS.indexOf(minUnit); i--){\n const unit = UNITS[i];\n if (INTERVALS[unit].common && scale._adapter.diff(max, min, unit) >= numTicks - 1) {\n return unit;\n }\n }\n return UNITS[minUnit ? UNITS.indexOf(minUnit) : 0];\n}\n function determineMajorUnit(unit) {\n for(let i = UNITS.indexOf(unit) + 1, ilen = UNITS.length; i < ilen; ++i){\n if (INTERVALS[UNITS[i]].common) {\n return UNITS[i];\n }\n }\n}\n function addTick(ticks, time, timestamps) {\n if (!timestamps) {\n ticks[time] = true;\n } else if (timestamps.length) {\n const { lo , hi } = _lookup(timestamps, time);\n const timestamp = timestamps[lo] >= time ? timestamps[lo] : timestamps[hi];\n ticks[timestamp] = true;\n }\n}\n function setMajorTicks(scale, ticks, map, majorUnit) {\n const adapter = scale._adapter;\n const first = +adapter.startOf(ticks[0].value, majorUnit);\n const last = ticks[ticks.length - 1].value;\n let major, index;\n for(major = first; major <= last; major = +adapter.add(major, 1, majorUnit)){\n index = map[major];\n if (index >= 0) {\n ticks[index].major = true;\n }\n }\n return ticks;\n}\n function ticksFromTimestamps(scale, values, majorUnit) {\n const ticks = [];\n const map = {};\n const ilen = values.length;\n let i, value;\n for(i = 0; i < ilen; ++i){\n value = values[i];\n map[value] = i;\n ticks.push({\n value,\n major: false\n });\n }\n return ilen === 0 || !majorUnit ? ticks : setMajorTicks(scale, ticks, map, majorUnit);\n}\nclass TimeScale extends Scale {\n static id = 'time';\n static defaults = {\n bounds: 'data',\n adapters: {},\n time: {\n parser: false,\n unit: false,\n round: false,\n isoWeekday: false,\n minUnit: 'millisecond',\n displayFormats: {}\n },\n ticks: {\n source: 'auto',\n callback: false,\n major: {\n enabled: false\n }\n }\n };\n constructor(props){\n super(props);\n this._cache = {\n data: [],\n labels: [],\n all: []\n };\n this._unit = 'day';\n this._majorUnit = undefined;\n this._offsets = {};\n this._normalized = false;\n this._parseOpts = undefined;\n }\n init(scaleOpts, opts = {}) {\n const time = scaleOpts.time || (scaleOpts.time = {});\n const adapter = this._adapter = new adapters._date(scaleOpts.adapters.date);\n adapter.init(opts);\n mergeIf(time.displayFormats, adapter.formats());\n this._parseOpts = {\n parser: time.parser,\n round: time.round,\n isoWeekday: time.isoWeekday\n };\n super.init(scaleOpts);\n this._normalized = opts.normalized;\n }\n parse(raw, index) {\n if (raw === undefined) {\n return null;\n }\n return parse(this, raw);\n }\n beforeLayout() {\n super.beforeLayout();\n this._cache = {\n data: [],\n labels: [],\n all: []\n };\n }\n determineDataLimits() {\n const options = this.options;\n const adapter = this._adapter;\n const unit = options.time.unit || 'day';\n let { min , max , minDefined , maxDefined } = this.getUserBounds();\n function _applyBounds(bounds) {\n if (!minDefined && !isNaN(bounds.min)) {\n min = Math.min(min, bounds.min);\n }\n if (!maxDefined && !isNaN(bounds.max)) {\n max = Math.max(max, bounds.max);\n }\n }\n if (!minDefined || !maxDefined) {\n _applyBounds(this._getLabelBounds());\n if (options.bounds !== 'ticks' || options.ticks.source !== 'labels') {\n _applyBounds(this.getMinMax(false));\n }\n }\n min = isNumberFinite(min) && !isNaN(min) ? min : +adapter.startOf(Date.now(), unit);\n max = isNumberFinite(max) && !isNaN(max) ? max : +adapter.endOf(Date.now(), unit) + 1;\n this.min = Math.min(min, max - 1);\n this.max = Math.max(min + 1, max);\n }\n _getLabelBounds() {\n const arr = this.getLabelTimestamps();\n let min = Number.POSITIVE_INFINITY;\n let max = Number.NEGATIVE_INFINITY;\n if (arr.length) {\n min = arr[0];\n max = arr[arr.length - 1];\n }\n return {\n min,\n max\n };\n }\n buildTicks() {\n const options = this.options;\n const timeOpts = options.time;\n const tickOpts = options.ticks;\n const timestamps = tickOpts.source === 'labels' ? this.getLabelTimestamps() : this._generate();\n if (options.bounds === 'ticks' && timestamps.length) {\n this.min = this._userMin || timestamps[0];\n this.max = this._userMax || timestamps[timestamps.length - 1];\n }\n const min = this.min;\n const max = this.max;\n const ticks = _filterBetween(timestamps, min, max);\n this._unit = timeOpts.unit || (tickOpts.autoSkip ? determineUnitForAutoTicks(timeOpts.minUnit, this.min, this.max, this._getLabelCapacity(min)) : determineUnitForFormatting(this, ticks.length, timeOpts.minUnit, this.min, this.max));\n this._majorUnit = !tickOpts.major.enabled || this._unit === 'year' ? undefined : determineMajorUnit(this._unit);\n this.initOffsets(timestamps);\n if (options.reverse) {\n ticks.reverse();\n }\n return ticksFromTimestamps(this, ticks, this._majorUnit);\n }\n afterAutoSkip() {\n if (this.options.offsetAfterAutoskip) {\n this.initOffsets(this.ticks.map((tick)=>+tick.value));\n }\n }\n initOffsets(timestamps = []) {\n let start = 0;\n let end = 0;\n let first, last;\n if (this.options.offset && timestamps.length) {\n first = this.getDecimalForValue(timestamps[0]);\n if (timestamps.length === 1) {\n start = 1 - first;\n } else {\n start = (this.getDecimalForValue(timestamps[1]) - first) / 2;\n }\n last = this.getDecimalForValue(timestamps[timestamps.length - 1]);\n if (timestamps.length === 1) {\n end = last;\n } else {\n end = (last - this.getDecimalForValue(timestamps[timestamps.length - 2])) / 2;\n }\n }\n const limit = timestamps.length < 3 ? 0.5 : 0.25;\n start = _limitValue(start, 0, limit);\n end = _limitValue(end, 0, limit);\n this._offsets = {\n start,\n end,\n factor: 1 / (start + 1 + end)\n };\n }\n _generate() {\n const adapter = this._adapter;\n const min = this.min;\n const max = this.max;\n const options = this.options;\n const timeOpts = options.time;\n const minor = timeOpts.unit || determineUnitForAutoTicks(timeOpts.minUnit, min, max, this._getLabelCapacity(min));\n const stepSize = valueOrDefault(options.ticks.stepSize, 1);\n const weekday = minor === 'week' ? timeOpts.isoWeekday : false;\n const hasWeekday = isNumber(weekday) || weekday === true;\n const ticks = {};\n let first = min;\n let time, count;\n if (hasWeekday) {\n first = +adapter.startOf(first, 'isoWeek', weekday);\n }\n first = +adapter.startOf(first, hasWeekday ? 'day' : minor);\n if (adapter.diff(max, min, minor) > 100000 * stepSize) {\n throw new Error(min + ' and ' + max + ' are too far apart with stepSize of ' + stepSize + ' ' + minor);\n }\n const timestamps = options.ticks.source === 'data' && this.getDataTimestamps();\n for(time = first, count = 0; time < max; time = +adapter.add(time, stepSize, minor), count++){\n addTick(ticks, time, timestamps);\n }\n if (time === max || options.bounds === 'ticks' || count === 1) {\n addTick(ticks, time, timestamps);\n }\n return Object.keys(ticks).sort(sorter).map((x)=>+x);\n }\n getLabelForValue(value) {\n const adapter = this._adapter;\n const timeOpts = this.options.time;\n if (timeOpts.tooltipFormat) {\n return adapter.format(value, timeOpts.tooltipFormat);\n }\n return adapter.format(value, timeOpts.displayFormats.datetime);\n }\n format(value, format) {\n const options = this.options;\n const formats = options.time.displayFormats;\n const unit = this._unit;\n const fmt = format || formats[unit];\n return this._adapter.format(value, fmt);\n }\n _tickFormatFunction(time, index, ticks, format) {\n const options = this.options;\n const formatter = options.ticks.callback;\n if (formatter) {\n return callback(formatter, [\n time,\n index,\n ticks\n ], this);\n }\n const formats = options.time.displayFormats;\n const unit = this._unit;\n const majorUnit = this._majorUnit;\n const minorFormat = unit && formats[unit];\n const majorFormat = majorUnit && formats[majorUnit];\n const tick = ticks[index];\n const major = majorUnit && majorFormat && tick && tick.major;\n return this._adapter.format(time, format || (major ? majorFormat : minorFormat));\n }\n generateTickLabels(ticks) {\n let i, ilen, tick;\n for(i = 0, ilen = ticks.length; i < ilen; ++i){\n tick = ticks[i];\n tick.label = this._tickFormatFunction(tick.value, i, ticks);\n }\n }\n getDecimalForValue(value) {\n return value === null ? NaN : (value - this.min) / (this.max - this.min);\n }\n getPixelForValue(value) {\n const offsets = this._offsets;\n const pos = this.getDecimalForValue(value);\n return this.getPixelForDecimal((offsets.start + pos) * offsets.factor);\n }\n getValueForPixel(pixel) {\n const offsets = this._offsets;\n const pos = this.getDecimalForPixel(pixel) / offsets.factor - offsets.end;\n return this.min + pos * (this.max - this.min);\n }\n _getLabelSize(label) {\n const ticksOpts = this.options.ticks;\n const tickLabelWidth = this.ctx.measureText(label).width;\n const angle = toRadians(this.isHorizontal() ? ticksOpts.maxRotation : ticksOpts.minRotation);\n const cosRotation = Math.cos(angle);\n const sinRotation = Math.sin(angle);\n const tickFontSize = this._resolveTickFontOptions(0).size;\n return {\n w: tickLabelWidth * cosRotation + tickFontSize * sinRotation,\n h: tickLabelWidth * sinRotation + tickFontSize * cosRotation\n };\n }\n _getLabelCapacity(exampleTime) {\n const timeOpts = this.options.time;\n const displayFormats = timeOpts.displayFormats;\n const format = displayFormats[timeOpts.unit] || displayFormats.millisecond;\n const exampleLabel = this._tickFormatFunction(exampleTime, 0, ticksFromTimestamps(this, [\n exampleTime\n ], this._majorUnit), format);\n const size = this._getLabelSize(exampleLabel);\n const capacity = Math.floor(this.isHorizontal() ? this.width / size.w : this.height / size.h) - 1;\n return capacity > 0 ? capacity : 1;\n }\n getDataTimestamps() {\n let timestamps = this._cache.data || [];\n let i, ilen;\n if (timestamps.length) {\n return timestamps;\n }\n const metas = this.getMatchingVisibleMetas();\n if (this._normalized && metas.length) {\n return this._cache.data = metas[0].controller.getAllParsedValues(this);\n }\n for(i = 0, ilen = metas.length; i < ilen; ++i){\n timestamps = timestamps.concat(metas[i].controller.getAllParsedValues(this));\n }\n return this._cache.data = this.normalize(timestamps);\n }\n getLabelTimestamps() {\n const timestamps = this._cache.labels || [];\n let i, ilen;\n if (timestamps.length) {\n return timestamps;\n }\n const labels = this.getLabels();\n for(i = 0, ilen = labels.length; i < ilen; ++i){\n timestamps.push(parse(this, labels[i]));\n }\n return this._cache.labels = this._normalized ? timestamps : this.normalize(timestamps);\n }\n normalize(values) {\n return _arrayUnique(values.sort(sorter));\n }\n}\n\nfunction chart_interpolate(table, val, reverse) {\n let lo = 0;\n let hi = table.length - 1;\n let prevSource, nextSource, prevTarget, nextTarget;\n if (reverse) {\n if (val >= table[lo].pos && val <= table[hi].pos) {\n ({ lo , hi } = _lookupByKey(table, 'pos', val));\n }\n ({ pos: prevSource , time: prevTarget } = table[lo]);\n ({ pos: nextSource , time: nextTarget } = table[hi]);\n } else {\n if (val >= table[lo].time && val <= table[hi].time) {\n ({ lo , hi } = _lookupByKey(table, 'time', val));\n }\n ({ time: prevSource , pos: prevTarget } = table[lo]);\n ({ time: nextSource , pos: nextTarget } = table[hi]);\n }\n const span = nextSource - prevSource;\n return span ? prevTarget + (nextTarget - prevTarget) * (val - prevSource) / span : prevTarget;\n}\nclass TimeSeriesScale extends TimeScale {\n static id = 'timeseries';\n static defaults = TimeScale.defaults;\n constructor(props){\n super(props);\n this._table = [];\n this._minPos = undefined;\n this._tableRange = undefined;\n }\n initOffsets() {\n const timestamps = this._getTimestampsForTable();\n const table = this._table = this.buildLookupTable(timestamps);\n this._minPos = chart_interpolate(table, this.min);\n this._tableRange = chart_interpolate(table, this.max) - this._minPos;\n super.initOffsets(timestamps);\n }\n buildLookupTable(timestamps) {\n const { min , max } = this;\n const items = [];\n const table = [];\n let i, ilen, prev, curr, next;\n for(i = 0, ilen = timestamps.length; i < ilen; ++i){\n curr = timestamps[i];\n if (curr >= min && curr <= max) {\n items.push(curr);\n }\n }\n if (items.length < 2) {\n return [\n {\n time: min,\n pos: 0\n },\n {\n time: max,\n pos: 1\n }\n ];\n }\n for(i = 0, ilen = items.length; i < ilen; ++i){\n next = items[i + 1];\n prev = items[i - 1];\n curr = items[i];\n if (Math.round((next + prev) / 2) !== curr) {\n table.push({\n time: curr,\n pos: i / (ilen - 1)\n });\n }\n }\n return table;\n }\n _generate() {\n const min = this.min;\n const max = this.max;\n let timestamps = super.getDataTimestamps();\n if (!timestamps.includes(min) || !timestamps.length) {\n timestamps.splice(0, 0, min);\n }\n if (!timestamps.includes(max) || timestamps.length === 1) {\n timestamps.push(max);\n }\n return timestamps.sort((a, b)=>a - b);\n }\n _getTimestampsForTable() {\n let timestamps = this._cache.all || [];\n if (timestamps.length) {\n return timestamps;\n }\n const data = this.getDataTimestamps();\n const label = this.getLabelTimestamps();\n if (data.length && label.length) {\n timestamps = this.normalize(data.concat(label));\n } else {\n timestamps = data.length ? data : label;\n }\n timestamps = this._cache.all = timestamps;\n return timestamps;\n }\n getDecimalForValue(value) {\n return (chart_interpolate(this._table, value) - this._minPos) / this._tableRange;\n }\n getValueForPixel(pixel) {\n const offsets = this._offsets;\n const decimal = this.getDecimalForPixel(pixel) / offsets.factor - offsets.end;\n return chart_interpolate(this._table, decimal * this._tableRange + this._minPos, true);\n }\n}\n\nvar scales = /*#__PURE__*/Object.freeze({\n__proto__: null,\nCategoryScale: CategoryScale,\nLinearScale: LinearScale,\nLogarithmicScale: LogarithmicScale,\nRadialLinearScale: RadialLinearScale,\nTimeScale: TimeScale,\nTimeSeriesScale: TimeSeriesScale\n});\n\nconst registerables = [\n controllers,\n chart_elements,\n plugins,\n scales\n];\n\n\n//# sourceMappingURL=chart.js.map\n\n;// ./node_modules/chart.js/auto/auto.js\n\n\nChart.register(...registerables);\n\n\n/* harmony default export */ const auto = (Chart);\n\n;// ./src/assets/images/muted.png\nconst muted_namespaceObject = __webpack_require__.p + \"522c61dacbe66475b709.png\";\n;// ./src/assets/images/unmuted.png\nconst unmuted_namespaceObject = __webpack_require__.p + \"4373ba701fcf92e48a9e.png\";\n;// ./node_modules/chartjs-plugin-datalabels/dist/chartjs-plugin-datalabels.esm.js\n/*!\n * chartjs-plugin-datalabels v2.2.0\n * https://chartjs-plugin-datalabels.netlify.app\n * (c) 2017-2022 chartjs-plugin-datalabels contributors\n * Released under the MIT license\n */\n\n\n\nvar devicePixelRatio = (function() {\n if (typeof window !== 'undefined') {\n if (window.devicePixelRatio) {\n return window.devicePixelRatio;\n }\n\n // devicePixelRatio is undefined on IE10\n // https://stackoverflow.com/a/20204180/8837887\n // https://github.com/chartjs/chartjs-plugin-datalabels/issues/85\n var screen = window.screen;\n if (screen) {\n return (screen.deviceXDPI || 1) / (screen.logicalXDPI || 1);\n }\n }\n\n return 1;\n}());\n\nvar utils = {\n // @todo move this in Chart.helpers.toTextLines\n toTextLines: function(inputs) {\n var lines = [];\n var input;\n\n inputs = [].concat(inputs);\n while (inputs.length) {\n input = inputs.pop();\n if (typeof input === 'string') {\n lines.unshift.apply(lines, input.split('\\n'));\n } else if (Array.isArray(input)) {\n inputs.push.apply(inputs, input);\n } else if (!isNullOrUndef(inputs)) {\n lines.unshift('' + input);\n }\n }\n\n return lines;\n },\n\n // @todo move this in Chart.helpers.canvas.textSize\n // @todo cache calls of measureText if font doesn't change?!\n textSize: function(ctx, lines, font) {\n var items = [].concat(lines);\n var ilen = items.length;\n var prev = ctx.font;\n var width = 0;\n var i;\n\n ctx.font = font.string;\n\n for (i = 0; i < ilen; ++i) {\n width = Math.max(ctx.measureText(items[i]).width, width);\n }\n\n ctx.font = prev;\n\n return {\n height: ilen * font.lineHeight,\n width: width\n };\n },\n\n /**\n * Returns value bounded by min and max. This is equivalent to max(min, min(value, max)).\n * @todo move this method in Chart.helpers.bound\n * https://doc.qt.io/qt-5/qtglobal.html#qBound\n */\n bound: function(min, value, max) {\n return Math.max(min, Math.min(value, max));\n },\n\n /**\n * Returns an array of pair [value, state] where state is:\n * * -1: value is only in a0 (removed)\n * * 1: value is only in a1 (added)\n */\n arrayDiff: function(a0, a1) {\n var prev = a0.slice();\n var updates = [];\n var i, j, ilen, v;\n\n for (i = 0, ilen = a1.length; i < ilen; ++i) {\n v = a1[i];\n j = prev.indexOf(v);\n\n if (j === -1) {\n updates.push([v, 1]);\n } else {\n prev.splice(j, 1);\n }\n }\n\n for (i = 0, ilen = prev.length; i < ilen; ++i) {\n updates.push([prev[i], -1]);\n }\n\n return updates;\n },\n\n /**\n * https://github.com/chartjs/chartjs-plugin-datalabels/issues/70\n */\n rasterize: function(v) {\n return Math.round(v * devicePixelRatio) / devicePixelRatio;\n }\n};\n\nfunction orient(point, origin) {\n var x0 = origin.x;\n var y0 = origin.y;\n\n if (x0 === null) {\n return {x: 0, y: -1};\n }\n if (y0 === null) {\n return {x: 1, y: 0};\n }\n\n var dx = point.x - x0;\n var dy = point.y - y0;\n var ln = Math.sqrt(dx * dx + dy * dy);\n\n return {\n x: ln ? dx / ln : 0,\n y: ln ? dy / ln : -1\n };\n}\n\nfunction aligned(x, y, vx, vy, align) {\n switch (align) {\n case 'center':\n vx = vy = 0;\n break;\n case 'bottom':\n vx = 0;\n vy = 1;\n break;\n case 'right':\n vx = 1;\n vy = 0;\n break;\n case 'left':\n vx = -1;\n vy = 0;\n break;\n case 'top':\n vx = 0;\n vy = -1;\n break;\n case 'start':\n vx = -vx;\n vy = -vy;\n break;\n case 'end':\n // keep natural orientation\n break;\n default:\n // clockwise rotation (in degree)\n align *= (Math.PI / 180);\n vx = Math.cos(align);\n vy = Math.sin(align);\n break;\n }\n\n return {\n x: x,\n y: y,\n vx: vx,\n vy: vy\n };\n}\n\n// Line clipping (Cohen–Sutherland algorithm)\n// https://en.wikipedia.org/wiki/Cohen–Sutherland_algorithm\n\nvar R_INSIDE = 0;\nvar R_LEFT = 1;\nvar R_RIGHT = 2;\nvar R_BOTTOM = 4;\nvar R_TOP = 8;\n\nfunction region(x, y, rect) {\n var res = R_INSIDE;\n\n if (x < rect.left) {\n res |= R_LEFT;\n } else if (x > rect.right) {\n res |= R_RIGHT;\n }\n if (y < rect.top) {\n res |= R_TOP;\n } else if (y > rect.bottom) {\n res |= R_BOTTOM;\n }\n\n return res;\n}\n\nfunction clipped(segment, area) {\n var x0 = segment.x0;\n var y0 = segment.y0;\n var x1 = segment.x1;\n var y1 = segment.y1;\n var r0 = region(x0, y0, area);\n var r1 = region(x1, y1, area);\n var r, x, y;\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n if (!(r0 | r1) || (r0 & r1)) {\n // both points inside or on the same side: no clipping\n break;\n }\n\n // at least one point is outside\n r = r0 || r1;\n\n if (r & R_TOP) {\n x = x0 + (x1 - x0) * (area.top - y0) / (y1 - y0);\n y = area.top;\n } else if (r & R_BOTTOM) {\n x = x0 + (x1 - x0) * (area.bottom - y0) / (y1 - y0);\n y = area.bottom;\n } else if (r & R_RIGHT) {\n y = y0 + (y1 - y0) * (area.right - x0) / (x1 - x0);\n x = area.right;\n } else if (r & R_LEFT) {\n y = y0 + (y1 - y0) * (area.left - x0) / (x1 - x0);\n x = area.left;\n }\n\n if (r === r0) {\n x0 = x;\n y0 = y;\n r0 = region(x0, y0, area);\n } else {\n x1 = x;\n y1 = y;\n r1 = region(x1, y1, area);\n }\n }\n\n return {\n x0: x0,\n x1: x1,\n y0: y0,\n y1: y1\n };\n}\n\nfunction compute$1(range, config) {\n var anchor = config.anchor;\n var segment = range;\n var x, y;\n\n if (config.clamp) {\n segment = clipped(segment, config.area);\n }\n\n if (anchor === 'start') {\n x = segment.x0;\n y = segment.y0;\n } else if (anchor === 'end') {\n x = segment.x1;\n y = segment.y1;\n } else {\n x = (segment.x0 + segment.x1) / 2;\n y = (segment.y0 + segment.y1) / 2;\n }\n\n return aligned(x, y, range.vx, range.vy, config.align);\n}\n\nvar chartjs_plugin_datalabels_esm_positioners = {\n arc: function(el, config) {\n var angle = (el.startAngle + el.endAngle) / 2;\n var vx = Math.cos(angle);\n var vy = Math.sin(angle);\n var r0 = el.innerRadius;\n var r1 = el.outerRadius;\n\n return compute$1({\n x0: el.x + vx * r0,\n y0: el.y + vy * r0,\n x1: el.x + vx * r1,\n y1: el.y + vy * r1,\n vx: vx,\n vy: vy\n }, config);\n },\n\n point: function(el, config) {\n var v = orient(el, config.origin);\n var rx = v.x * el.options.radius;\n var ry = v.y * el.options.radius;\n\n return compute$1({\n x0: el.x - rx,\n y0: el.y - ry,\n x1: el.x + rx,\n y1: el.y + ry,\n vx: v.x,\n vy: v.y\n }, config);\n },\n\n bar: function(el, config) {\n var v = orient(el, config.origin);\n var x = el.x;\n var y = el.y;\n var sx = 0;\n var sy = 0;\n\n if (el.horizontal) {\n x = Math.min(el.x, el.base);\n sx = Math.abs(el.base - el.x);\n } else {\n y = Math.min(el.y, el.base);\n sy = Math.abs(el.base - el.y);\n }\n\n return compute$1({\n x0: x,\n y0: y + sy,\n x1: x + sx,\n y1: y,\n vx: v.x,\n vy: v.y\n }, config);\n },\n\n fallback: function(el, config) {\n var v = orient(el, config.origin);\n\n return compute$1({\n x0: el.x,\n y0: el.y,\n x1: el.x + (el.width || 0),\n y1: el.y + (el.height || 0),\n vx: v.x,\n vy: v.y\n }, config);\n }\n};\n\nvar rasterize = utils.rasterize;\n\nfunction chartjs_plugin_datalabels_esm_boundingRects(model) {\n var borderWidth = model.borderWidth || 0;\n var padding = model.padding;\n var th = model.size.height;\n var tw = model.size.width;\n var tx = -tw / 2;\n var ty = -th / 2;\n\n return {\n frame: {\n x: tx - padding.left - borderWidth,\n y: ty - padding.top - borderWidth,\n w: tw + padding.width + borderWidth * 2,\n h: th + padding.height + borderWidth * 2\n },\n text: {\n x: tx,\n y: ty,\n w: tw,\n h: th\n }\n };\n}\n\nfunction getScaleOrigin(el, context) {\n var scale = context.chart.getDatasetMeta(context.datasetIndex).vScale;\n\n if (!scale) {\n return null;\n }\n\n if (scale.xCenter !== undefined && scale.yCenter !== undefined) {\n return {x: scale.xCenter, y: scale.yCenter};\n }\n\n var pixel = scale.getBasePixel();\n return el.horizontal ?\n {x: pixel, y: null} :\n {x: null, y: pixel};\n}\n\nfunction getPositioner(el) {\n if (el instanceof ArcElement) {\n return chartjs_plugin_datalabels_esm_positioners.arc;\n }\n if (el instanceof PointElement) {\n return chartjs_plugin_datalabels_esm_positioners.point;\n }\n if (el instanceof BarElement) {\n return chartjs_plugin_datalabels_esm_positioners.bar;\n }\n return chartjs_plugin_datalabels_esm_positioners.fallback;\n}\n\nfunction drawRoundedRect(ctx, x, y, w, h, radius) {\n var HALF_PI = Math.PI / 2;\n\n if (radius) {\n var r = Math.min(radius, h / 2, w / 2);\n var left = x + r;\n var top = y + r;\n var right = x + w - r;\n var bottom = y + h - r;\n\n ctx.moveTo(x, top);\n if (left < right && top < bottom) {\n ctx.arc(left, top, r, -Math.PI, -HALF_PI);\n ctx.arc(right, top, r, -HALF_PI, 0);\n ctx.arc(right, bottom, r, 0, HALF_PI);\n ctx.arc(left, bottom, r, HALF_PI, Math.PI);\n } else if (left < right) {\n ctx.moveTo(left, y);\n ctx.arc(right, top, r, -HALF_PI, HALF_PI);\n ctx.arc(left, top, r, HALF_PI, Math.PI + HALF_PI);\n } else if (top < bottom) {\n ctx.arc(left, top, r, -Math.PI, 0);\n ctx.arc(left, bottom, r, 0, Math.PI);\n } else {\n ctx.arc(left, top, r, -Math.PI, Math.PI);\n }\n ctx.closePath();\n ctx.moveTo(x, y);\n } else {\n ctx.rect(x, y, w, h);\n }\n}\n\nfunction drawFrame(ctx, rect, model) {\n var bgColor = model.backgroundColor;\n var borderColor = model.borderColor;\n var borderWidth = model.borderWidth;\n\n if (!bgColor && (!borderColor || !borderWidth)) {\n return;\n }\n\n ctx.beginPath();\n\n drawRoundedRect(\n ctx,\n rasterize(rect.x) + borderWidth / 2,\n rasterize(rect.y) + borderWidth / 2,\n rasterize(rect.w) - borderWidth,\n rasterize(rect.h) - borderWidth,\n model.borderRadius);\n\n ctx.closePath();\n\n if (bgColor) {\n ctx.fillStyle = bgColor;\n ctx.fill();\n }\n\n if (borderColor && borderWidth) {\n ctx.strokeStyle = borderColor;\n ctx.lineWidth = borderWidth;\n ctx.lineJoin = 'miter';\n ctx.stroke();\n }\n}\n\nfunction textGeometry(rect, align, font) {\n var h = font.lineHeight;\n var w = rect.w;\n var x = rect.x;\n var y = rect.y + h / 2;\n\n if (align === 'center') {\n x += w / 2;\n } else if (align === 'end' || align === 'right') {\n x += w;\n }\n\n return {\n h: h,\n w: w,\n x: x,\n y: y\n };\n}\n\nfunction drawTextLine(ctx, text, cfg) {\n var shadow = ctx.shadowBlur;\n var stroked = cfg.stroked;\n var x = rasterize(cfg.x);\n var y = rasterize(cfg.y);\n var w = rasterize(cfg.w);\n\n if (stroked) {\n ctx.strokeText(text, x, y, w);\n }\n\n if (cfg.filled) {\n if (shadow && stroked) {\n // Prevent drawing shadow on both the text stroke and fill, so\n // if the text is stroked, remove the shadow for the text fill.\n ctx.shadowBlur = 0;\n }\n\n ctx.fillText(text, x, y, w);\n\n if (shadow && stroked) {\n ctx.shadowBlur = shadow;\n }\n }\n}\n\nfunction drawText(ctx, lines, rect, model) {\n var align = model.textAlign;\n var color = model.color;\n var filled = !!color;\n var font = model.font;\n var ilen = lines.length;\n var strokeColor = model.textStrokeColor;\n var strokeWidth = model.textStrokeWidth;\n var stroked = strokeColor && strokeWidth;\n var i;\n\n if (!ilen || (!filled && !stroked)) {\n return;\n }\n\n // Adjust coordinates based on text alignment and line height\n rect = textGeometry(rect, align, font);\n\n ctx.font = font.string;\n ctx.textAlign = align;\n ctx.textBaseline = 'middle';\n ctx.shadowBlur = model.textShadowBlur;\n ctx.shadowColor = model.textShadowColor;\n\n if (filled) {\n ctx.fillStyle = color;\n }\n if (stroked) {\n ctx.lineJoin = 'round';\n ctx.lineWidth = strokeWidth;\n ctx.strokeStyle = strokeColor;\n }\n\n for (i = 0, ilen = lines.length; i < ilen; ++i) {\n drawTextLine(ctx, lines[i], {\n stroked: stroked,\n filled: filled,\n w: rect.w,\n x: rect.x,\n y: rect.y + rect.h * i\n });\n }\n}\n\nvar Label = function(config, ctx, el, index) {\n var me = this;\n\n me._config = config;\n me._index = index;\n me._model = null;\n me._rects = null;\n me._ctx = ctx;\n me._el = el;\n};\n\nmerge(Label.prototype, {\n /**\n * @private\n */\n _modelize: function(display, lines, config, context) {\n var me = this;\n var index = me._index;\n var font = toFont(resolve([config.font, {}], context, index));\n var color = resolve([config.color, defaults.color], context, index);\n\n return {\n align: resolve([config.align, 'center'], context, index),\n anchor: resolve([config.anchor, 'center'], context, index),\n area: context.chart.chartArea,\n backgroundColor: resolve([config.backgroundColor, null], context, index),\n borderColor: resolve([config.borderColor, null], context, index),\n borderRadius: resolve([config.borderRadius, 0], context, index),\n borderWidth: resolve([config.borderWidth, 0], context, index),\n clamp: resolve([config.clamp, false], context, index),\n clip: resolve([config.clip, false], context, index),\n color: color,\n display: display,\n font: font,\n lines: lines,\n offset: resolve([config.offset, 4], context, index),\n opacity: resolve([config.opacity, 1], context, index),\n origin: getScaleOrigin(me._el, context),\n padding: toPadding(resolve([config.padding, 4], context, index)),\n positioner: getPositioner(me._el),\n rotation: resolve([config.rotation, 0], context, index) * (Math.PI / 180),\n size: utils.textSize(me._ctx, lines, font),\n textAlign: resolve([config.textAlign, 'start'], context, index),\n textShadowBlur: resolve([config.textShadowBlur, 0], context, index),\n textShadowColor: resolve([config.textShadowColor, color], context, index),\n textStrokeColor: resolve([config.textStrokeColor, color], context, index),\n textStrokeWidth: resolve([config.textStrokeWidth, 0], context, index)\n };\n },\n\n update: function(context) {\n var me = this;\n var model = null;\n var rects = null;\n var index = me._index;\n var config = me._config;\n var value, label, lines;\n\n // We first resolve the display option (separately) to avoid computing\n // other options in case the label is hidden (i.e. display: false).\n var display = resolve([config.display, true], context, index);\n\n if (display) {\n value = context.dataset.data[index];\n label = valueOrDefault(callback(config.formatter, [value, context]), value);\n lines = isNullOrUndef(label) ? [] : utils.toTextLines(label);\n\n if (lines.length) {\n model = me._modelize(display, lines, config, context);\n rects = chartjs_plugin_datalabels_esm_boundingRects(model);\n }\n }\n\n me._model = model;\n me._rects = rects;\n },\n\n geometry: function() {\n return this._rects ? this._rects.frame : {};\n },\n\n rotation: function() {\n return this._model ? this._model.rotation : 0;\n },\n\n visible: function() {\n return this._model && this._model.opacity;\n },\n\n model: function() {\n return this._model;\n },\n\n draw: function(chart, center) {\n var me = this;\n var ctx = chart.ctx;\n var model = me._model;\n var rects = me._rects;\n var area;\n\n if (!this.visible()) {\n return;\n }\n\n ctx.save();\n\n if (model.clip) {\n area = model.area;\n ctx.beginPath();\n ctx.rect(\n area.left,\n area.top,\n area.right - area.left,\n area.bottom - area.top);\n ctx.clip();\n }\n\n ctx.globalAlpha = utils.bound(0, model.opacity, 1);\n ctx.translate(rasterize(center.x), rasterize(center.y));\n ctx.rotate(model.rotation);\n\n drawFrame(ctx, rects.frame, model);\n drawText(ctx, model.lines, rects.text, model);\n\n ctx.restore();\n }\n});\n\nvar MIN_INTEGER = Number.MIN_SAFE_INTEGER || -9007199254740991; // eslint-disable-line es/no-number-minsafeinteger\nvar MAX_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991; // eslint-disable-line es/no-number-maxsafeinteger\n\nfunction rotated(point, center, angle) {\n var cos = Math.cos(angle);\n var sin = Math.sin(angle);\n var cx = center.x;\n var cy = center.y;\n\n return {\n x: cx + cos * (point.x - cx) - sin * (point.y - cy),\n y: cy + sin * (point.x - cx) + cos * (point.y - cy)\n };\n}\n\nfunction projected(points, axis) {\n var min = MAX_INTEGER;\n var max = MIN_INTEGER;\n var origin = axis.origin;\n var i, pt, vx, vy, dp;\n\n for (i = 0; i < points.length; ++i) {\n pt = points[i];\n vx = pt.x - origin.x;\n vy = pt.y - origin.y;\n dp = axis.vx * vx + axis.vy * vy;\n min = Math.min(min, dp);\n max = Math.max(max, dp);\n }\n\n return {\n min: min,\n max: max\n };\n}\n\nfunction toAxis(p0, p1) {\n var vx = p1.x - p0.x;\n var vy = p1.y - p0.y;\n var ln = Math.sqrt(vx * vx + vy * vy);\n\n return {\n vx: (p1.x - p0.x) / ln,\n vy: (p1.y - p0.y) / ln,\n origin: p0,\n ln: ln\n };\n}\n\nvar HitBox = function() {\n this._rotation = 0;\n this._rect = {\n x: 0,\n y: 0,\n w: 0,\n h: 0\n };\n};\n\nmerge(HitBox.prototype, {\n center: function() {\n var r = this._rect;\n return {\n x: r.x + r.w / 2,\n y: r.y + r.h / 2\n };\n },\n\n update: function(center, rect, rotation) {\n this._rotation = rotation;\n this._rect = {\n x: rect.x + center.x,\n y: rect.y + center.y,\n w: rect.w,\n h: rect.h\n };\n },\n\n contains: function(point) {\n var me = this;\n var margin = 1;\n var rect = me._rect;\n\n point = rotated(point, me.center(), -me._rotation);\n\n return !(point.x < rect.x - margin\n || point.y < rect.y - margin\n || point.x > rect.x + rect.w + margin * 2\n || point.y > rect.y + rect.h + margin * 2);\n },\n\n // Separating Axis Theorem\n // https://gamedevelopment.tutsplus.com/tutorials/collision-detection-using-the-separating-axis-theorem--gamedev-169\n intersects: function(other) {\n var r0 = this._points();\n var r1 = other._points();\n var axes = [\n toAxis(r0[0], r0[1]),\n toAxis(r0[0], r0[3])\n ];\n var i, pr0, pr1;\n\n if (this._rotation !== other._rotation) {\n // Only separate with r1 axis if the rotation is different,\n // else it's enough to separate r0 and r1 with r0 axis only!\n axes.push(\n toAxis(r1[0], r1[1]),\n toAxis(r1[0], r1[3])\n );\n }\n\n for (i = 0; i < axes.length; ++i) {\n pr0 = projected(r0, axes[i]);\n pr1 = projected(r1, axes[i]);\n\n if (pr0.max < pr1.min || pr1.max < pr0.min) {\n return false;\n }\n }\n\n return true;\n },\n\n /**\n * @private\n */\n _points: function() {\n var me = this;\n var rect = me._rect;\n var angle = me._rotation;\n var center = me.center();\n\n return [\n rotated({x: rect.x, y: rect.y}, center, angle),\n rotated({x: rect.x + rect.w, y: rect.y}, center, angle),\n rotated({x: rect.x + rect.w, y: rect.y + rect.h}, center, angle),\n rotated({x: rect.x, y: rect.y + rect.h}, center, angle)\n ];\n }\n});\n\nfunction coordinates(el, model, geometry) {\n var point = model.positioner(el, model);\n var vx = point.vx;\n var vy = point.vy;\n\n if (!vx && !vy) {\n // if aligned center, we don't want to offset the center point\n return {x: point.x, y: point.y};\n }\n\n var w = geometry.w;\n var h = geometry.h;\n\n // take in account the label rotation\n var rotation = model.rotation;\n var dx = Math.abs(w / 2 * Math.cos(rotation)) + Math.abs(h / 2 * Math.sin(rotation));\n var dy = Math.abs(w / 2 * Math.sin(rotation)) + Math.abs(h / 2 * Math.cos(rotation));\n\n // scale the unit vector (vx, vy) to get at least dx or dy equal to\n // w or h respectively (else we would calculate the distance to the\n // ellipse inscribed in the bounding rect)\n var vs = 1 / Math.max(Math.abs(vx), Math.abs(vy));\n dx *= vx * vs;\n dy *= vy * vs;\n\n // finally, include the explicit offset\n dx += model.offset * vx;\n dy += model.offset * vy;\n\n return {\n x: point.x + dx,\n y: point.y + dy\n };\n}\n\nfunction collide(labels, collider) {\n var i, j, s0, s1;\n\n // IMPORTANT Iterate in the reverse order since items at the end of the\n // list have an higher weight/priority and thus should be less impacted\n // by the overlapping strategy.\n\n for (i = labels.length - 1; i >= 0; --i) {\n s0 = labels[i].$layout;\n\n for (j = i - 1; j >= 0 && s0._visible; --j) {\n s1 = labels[j].$layout;\n\n if (s1._visible && s0._box.intersects(s1._box)) {\n collider(s0, s1);\n }\n }\n }\n\n return labels;\n}\n\nfunction compute(labels) {\n var i, ilen, label, state, geometry, center, proxy;\n\n // Initialize labels for overlap detection\n for (i = 0, ilen = labels.length; i < ilen; ++i) {\n label = labels[i];\n state = label.$layout;\n\n if (state._visible) {\n // Chart.js 3 removed el._model in favor of getProps(), making harder to\n // abstract reading values in positioners. Also, using string arrays to\n // read values (i.e. var {a,b,c} = el.getProps([\"a\",\"b\",\"c\"])) would make\n // positioners inefficient in the normal case (i.e. not the final values)\n // and the code a bit ugly, so let's use a Proxy instead.\n proxy = new Proxy(label._el, {get: (el, p) => el.getProps([p], true)[p]});\n\n geometry = label.geometry();\n center = coordinates(proxy, label.model(), geometry);\n state._box.update(center, geometry, label.rotation());\n }\n }\n\n // Auto hide overlapping labels\n return collide(labels, function(s0, s1) {\n var h0 = s0._hidable;\n var h1 = s1._hidable;\n\n if ((h0 && h1) || h1) {\n s1._visible = false;\n } else if (h0) {\n s0._visible = false;\n }\n });\n}\n\nvar layout = {\n prepare: function(datasets) {\n var labels = [];\n var i, j, ilen, jlen, label;\n\n for (i = 0, ilen = datasets.length; i < ilen; ++i) {\n for (j = 0, jlen = datasets[i].length; j < jlen; ++j) {\n label = datasets[i][j];\n labels.push(label);\n label.$layout = {\n _box: new HitBox(),\n _hidable: false,\n _visible: true,\n _set: i,\n _idx: label._index\n };\n }\n }\n\n // TODO New `z` option: labels with a higher z-index are drawn\n // of top of the ones with a lower index. Lowest z-index labels\n // are also discarded first when hiding overlapping labels.\n labels.sort(function(a, b) {\n var sa = a.$layout;\n var sb = b.$layout;\n\n return sa._idx === sb._idx\n ? sb._set - sa._set\n : sb._idx - sa._idx;\n });\n\n this.update(labels);\n\n return labels;\n },\n\n update: function(labels) {\n var dirty = false;\n var i, ilen, label, model, state;\n\n for (i = 0, ilen = labels.length; i < ilen; ++i) {\n label = labels[i];\n model = label.model();\n state = label.$layout;\n state._hidable = model && model.display === 'auto';\n state._visible = label.visible();\n dirty |= state._hidable;\n }\n\n if (dirty) {\n compute(labels);\n }\n },\n\n lookup: function(labels, point) {\n var i, state;\n\n // IMPORTANT Iterate in the reverse order since items at the end of\n // the list have an higher z-index, thus should be picked first.\n\n for (i = labels.length - 1; i >= 0; --i) {\n state = labels[i].$layout;\n\n if (state && state._visible && state._box.contains(point)) {\n return labels[i];\n }\n }\n\n return null;\n },\n\n draw: function(chart, labels) {\n var i, ilen, label, state, geometry, center;\n\n for (i = 0, ilen = labels.length; i < ilen; ++i) {\n label = labels[i];\n state = label.$layout;\n\n if (state._visible) {\n geometry = label.geometry();\n center = coordinates(label._el, label.model(), geometry);\n state._box.update(center, geometry, label.rotation());\n label.draw(chart, center);\n }\n }\n }\n};\n\nvar formatter = function(value) {\n if (isNullOrUndef(value)) {\n return null;\n }\n\n var label = value;\n var keys, klen, k;\n if (isObject(value)) {\n if (!isNullOrUndef(value.label)) {\n label = value.label;\n } else if (!isNullOrUndef(value.r)) {\n label = value.r;\n } else {\n label = '';\n keys = Object.keys(value);\n for (k = 0, klen = keys.length; k < klen; ++k) {\n label += (k !== 0 ? ', ' : '') + keys[k] + ': ' + value[keys[k]];\n }\n }\n }\n\n return '' + label;\n};\n\n/**\n * IMPORTANT: make sure to also update tests and TypeScript definition\n * files (`/test/specs/defaults.spec.js` and `/types/options.d.ts`)\n */\n\nvar chartjs_plugin_datalabels_esm_defaults = {\n align: 'center',\n anchor: 'center',\n backgroundColor: null,\n borderColor: null,\n borderRadius: 0,\n borderWidth: 0,\n clamp: false,\n clip: false,\n color: undefined,\n display: true,\n font: {\n family: undefined,\n lineHeight: 1.2,\n size: undefined,\n style: undefined,\n weight: null\n },\n formatter: formatter,\n labels: undefined,\n listeners: {},\n offset: 4,\n opacity: 1,\n padding: {\n top: 4,\n right: 4,\n bottom: 4,\n left: 4\n },\n rotation: 0,\n textAlign: 'start',\n textStrokeColor: undefined,\n textStrokeWidth: 0,\n textShadowBlur: 0,\n textShadowColor: undefined\n};\n\n/**\n * @see https://github.com/chartjs/Chart.js/issues/4176\n */\n\nvar chartjs_plugin_datalabels_esm_EXPANDO_KEY = '$datalabels';\nvar DEFAULT_KEY = '$default';\n\nfunction configure(dataset, options) {\n var override = dataset.datalabels;\n var listeners = {};\n var configs = [];\n var labels, keys;\n\n if (override === false) {\n return null;\n }\n if (override === true) {\n override = {};\n }\n\n options = merge({}, [options, override]);\n labels = options.labels || {};\n keys = Object.keys(labels);\n delete options.labels;\n\n if (keys.length) {\n keys.forEach(function(key) {\n if (labels[key]) {\n configs.push(merge({}, [\n options,\n labels[key],\n {_key: key}\n ]));\n }\n });\n } else {\n // Default label if no \"named\" label defined.\n configs.push(options);\n }\n\n // listeners: {: {: }}\n listeners = configs.reduce(function(target, config) {\n each(config.listeners || {}, function(fn, event) {\n target[event] = target[event] || {};\n target[event][config._key || DEFAULT_KEY] = fn;\n });\n\n delete config.listeners;\n return target;\n }, {});\n\n return {\n labels: configs,\n listeners: listeners\n };\n}\n\nfunction dispatchEvent(chart, listeners, label, event) {\n if (!listeners) {\n return;\n }\n\n var context = label.$context;\n var groups = label.$groups;\n var callback$1;\n\n if (!listeners[groups._set]) {\n return;\n }\n\n callback$1 = listeners[groups._set][groups._key];\n if (!callback$1) {\n return;\n }\n\n if (callback(callback$1, [context, event]) === true) {\n // Users are allowed to tweak the given context by injecting values that can be\n // used in scriptable options to display labels differently based on the current\n // event (e.g. highlight an hovered label). That's why we update the label with\n // the output context and schedule a new chart render by setting it dirty.\n chart[chartjs_plugin_datalabels_esm_EXPANDO_KEY]._dirty = true;\n label.update(context);\n }\n}\n\nfunction dispatchMoveEvents(chart, listeners, previous, label, event) {\n var enter, leave;\n\n if (!previous && !label) {\n return;\n }\n\n if (!previous) {\n enter = true;\n } else if (!label) {\n leave = true;\n } else if (previous !== label) {\n leave = enter = true;\n }\n\n if (leave) {\n dispatchEvent(chart, listeners.leave, previous, event);\n }\n if (enter) {\n dispatchEvent(chart, listeners.enter, label, event);\n }\n}\n\nfunction handleMoveEvents(chart, event) {\n var expando = chart[chartjs_plugin_datalabels_esm_EXPANDO_KEY];\n var listeners = expando._listeners;\n var previous, label;\n\n if (!listeners.enter && !listeners.leave) {\n return;\n }\n\n if (event.type === 'mousemove') {\n label = layout.lookup(expando._labels, event);\n } else if (event.type !== 'mouseout') {\n return;\n }\n\n previous = expando._hovered;\n expando._hovered = label;\n dispatchMoveEvents(chart, listeners, previous, label, event);\n}\n\nfunction handleClickEvents(chart, event) {\n var expando = chart[chartjs_plugin_datalabels_esm_EXPANDO_KEY];\n var handlers = expando._listeners.click;\n var label = handlers && layout.lookup(expando._labels, event);\n if (label) {\n dispatchEvent(chart, handlers, label, event);\n }\n}\n\nvar chartjs_plugin_datalabels_esm_plugin = {\n id: 'datalabels',\n\n defaults: chartjs_plugin_datalabels_esm_defaults,\n\n beforeInit: function(chart) {\n chart[chartjs_plugin_datalabels_esm_EXPANDO_KEY] = {\n _actives: []\n };\n },\n\n beforeUpdate: function(chart) {\n var expando = chart[chartjs_plugin_datalabels_esm_EXPANDO_KEY];\n expando._listened = false;\n expando._listeners = {}; // {: {: {: }}}\n expando._datasets = []; // per dataset labels: [Label[]]\n expando._labels = []; // layouted labels: Label[]\n },\n\n afterDatasetUpdate: function(chart, args, options) {\n var datasetIndex = args.index;\n var expando = chart[chartjs_plugin_datalabels_esm_EXPANDO_KEY];\n var labels = expando._datasets[datasetIndex] = [];\n var visible = chart.isDatasetVisible(datasetIndex);\n var dataset = chart.data.datasets[datasetIndex];\n var config = configure(dataset, options);\n var elements = args.meta.data || [];\n var ctx = chart.ctx;\n var i, j, ilen, jlen, cfg, key, el, label;\n\n ctx.save();\n\n for (i = 0, ilen = elements.length; i < ilen; ++i) {\n el = elements[i];\n el[chartjs_plugin_datalabels_esm_EXPANDO_KEY] = [];\n\n if (visible && el && chart.getDataVisibility(i) && !el.skip) {\n for (j = 0, jlen = config.labels.length; j < jlen; ++j) {\n cfg = config.labels[j];\n key = cfg._key;\n\n label = new Label(cfg, ctx, el, i);\n label.$groups = {\n _set: datasetIndex,\n _key: key || DEFAULT_KEY\n };\n label.$context = {\n active: false,\n chart: chart,\n dataIndex: i,\n dataset: dataset,\n datasetIndex: datasetIndex\n };\n\n label.update(label.$context);\n el[chartjs_plugin_datalabels_esm_EXPANDO_KEY].push(label);\n labels.push(label);\n }\n }\n }\n\n ctx.restore();\n\n // Store listeners at the chart level and per event type to optimize\n // cases where no listeners are registered for a specific event.\n merge(expando._listeners, config.listeners, {\n merger: function(event, target, source) {\n target[event] = target[event] || {};\n target[event][args.index] = source[event];\n expando._listened = true;\n }\n });\n },\n\n afterUpdate: function(chart) {\n chart[chartjs_plugin_datalabels_esm_EXPANDO_KEY]._labels = layout.prepare(chart[chartjs_plugin_datalabels_esm_EXPANDO_KEY]._datasets);\n },\n\n // Draw labels on top of all dataset elements\n // https://github.com/chartjs/chartjs-plugin-datalabels/issues/29\n // https://github.com/chartjs/chartjs-plugin-datalabels/issues/32\n afterDatasetsDraw: function(chart) {\n layout.draw(chart, chart[chartjs_plugin_datalabels_esm_EXPANDO_KEY]._labels);\n },\n\n beforeEvent: function(chart, args) {\n // If there is no listener registered for this chart, `listened` will be false,\n // meaning we can immediately ignore the incoming event and avoid useless extra\n // computation for users who don't implement label interactions.\n if (chart[chartjs_plugin_datalabels_esm_EXPANDO_KEY]._listened) {\n var event = args.event;\n switch (event.type) {\n case 'mousemove':\n case 'mouseout':\n handleMoveEvents(chart, event);\n break;\n case 'click':\n handleClickEvents(chart, event);\n break;\n }\n }\n },\n\n afterEvent: function(chart) {\n var expando = chart[chartjs_plugin_datalabels_esm_EXPANDO_KEY];\n var previous = expando._actives;\n var actives = expando._actives = chart.getActiveElements();\n var updates = utils.arrayDiff(previous, actives);\n var i, ilen, j, jlen, update, label, labels;\n\n for (i = 0, ilen = updates.length; i < ilen; ++i) {\n update = updates[i];\n if (update[1]) {\n labels = update[0].element[chartjs_plugin_datalabels_esm_EXPANDO_KEY] || [];\n for (j = 0, jlen = labels.length; j < jlen; ++j) {\n label = labels[j];\n label.$context.active = (update[1] === 1);\n label.update(label.$context);\n }\n }\n }\n\n if (expando._dirty || updates.length) {\n layout.update(expando._labels);\n chart.render();\n }\n\n delete expando._dirty;\n }\n};\n\n\n\n;// ./src/index.js\n\n\n\n\n\n\n\n/**COUNTUP ANIMATION */\ndocument.addEventListener(\"DOMContentLoaded\", function() {\n const countupElement = document.getElementById(\"countup\");\n const target = 34; // The final value to count up to\n const duration = 2500; // Duration of the count-up animation in milliseconds (1 second)\n let start = null; // Timestamp when the animation starts, initialized to null\n\n // Easing function for ease-out effect\n // This function creates an ease-out effect, where the animation starts fast and slows down toward the end\n function easeOutQuad(t) {\n return t * (2 - t);\n }\n\n // The function that performs the count-up animation\n function countUp(timestamp) {\n if (!start) start = timestamp; // Set the start time if it's not set yet\n const progress = Math.min((timestamp - start) / duration, 1); // Calculate the progress from 0 to 1\n const easedProgress = easeOutQuad(progress); // Apply the easing function to the progress\n countupElement.textContent = Math.floor(easedProgress * target); // Update the displayed count based on progress\n\n if (progress < 1) {\n // If the animation is not yet complete, request the next animation frame\n requestAnimationFrame(countUp);\n } else {\n // When the animation is complete, set the final value with the label\n countupElement.textContent = target;\n }\n }\n\n // Start the animation by requesting the first animation frame\n requestAnimationFrame(countUp);\n});\n\n\n/**GRAFICO A TORTA */\nconst ctx = document.getElementById('choirChart').getContext('2d');\nconst choirChart = new auto(ctx, {\n type: 'pie',\n data: {\n labels: ['Bassi', 'Tenori', 'Contralti', 'Soprani'],\n datasets: [{\n label: ' ',\n data: [7, 6, 14, 7],\n backgroundColor: [\n '#e43b3bff', // Bass\n '#568ea3ff', // Tenors\n '#5fb75f', // Altos\n '#dba159ff' // Sopranos\n ],\n borderColor: '#ffffff',\n borderWidth: 2\n }]\n },\n options: {\n responsive: true,\n animation: {\n duration: 1000,\n easing: 'easeOutQuad',\n animateScale: true\n },\n plugins: {\n legend: {\n position: 'bottom',\n labels: {\n boxWidth: 20,\n font: {\n size: 14,\n weight: 'bold'\n },\n color: '#333',\n padding: 15,\n usePointStyle: true\n }\n },\n tooltip: {\n enabled: true\n },\n datalabels: {\n color: '#000',\n formatter: (value) => {\n return value;\n },\n anchor: 'center',\n align: 'center',\n offset: 0,\n borderRadius: 5,\n backgroundColor: 'rgba(255, 255, 255, 0.8)',\n borderWidth: 1,\n borderColor: '#ccc'\n }\n }\n }\n});\n\n/**APPEARING TEXT ANIMATION \"IL CONTROCORO È...\" */\ndocument.addEventListener(\"DOMContentLoaded\", function() {\n const phrases = [\n \"il coro di Spin Time Labs.\",\n \"aperto a tuttə.\",\n \"per musicisti e no.\",\n \"di sinistra.\",\n \"divertente ed economico.\",\n \"inclusivo.\",\n ];\n\n const textElement = document.getElementById(\"controcoroText\");\n let currentPhraseIndex = 0;\n const animationDuration = 3500; // Duration for each phrase in milliseconds (5 seconds)\n\n // Function to display the next phrase with a typewriter animation\n function typePhrase(phrase) {\n textElement.innerHTML = \"\"; // Clear existing text\n let charIndex = 0;\n\n function typeNextChar() {\n if (charIndex < phrase.length) {\n textElement.innerHTML += phrase[charIndex].replace(/</g, '<').replace(/>/g, '>');\n charIndex++;\n setTimeout(typeNextChar, 100); // Set delay for typing next character\n }\n }\n typeNextChar();\n }\n\n // Function to change to the next phrase\n function changePhrase() {\n currentPhraseIndex = (currentPhraseIndex + 1) % phrases.length;\n typePhrase(phrases[currentPhraseIndex]);\n }\n\n // Start the typewriter animation for the initial phrase\n typePhrase(phrases[currentPhraseIndex]);\n\n // Set interval to change the phrase every 5 seconds\n setInterval(changePhrase, animationDuration);\n});\n\ndocument.addEventListener(\"DOMContentLoaded\", function() {\n const sections = document.querySelectorAll(\".fadein\");\n \n const observer = new IntersectionObserver((entries, observer) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n entry.target.style.opacity = 1;\n observer.unobserve(entry.target);\n }\n });\n }, {\n threshold: 1.0\n });\n\n sections.forEach(section => {\n observer.observe(section);\n });\n});\n\n/**TOGGLE MUTE VIDEO */\ndocument.getElementById(\"unmuteButton\").addEventListener(\"click\", function() {\n const muted = \"\";\n const unmuted = \"\";\n const video = document.getElementById(\"backgroundVideo\");\n if (video.muted) {\n video.muted = !video.muted;\n this.innerHTML = unmuted;\n } else {\n video.muted = !video.muted;\n this.innerHTML = muted;\n }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzE4LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQ0EsTUFBK0Y7QUFDL0YsTUFBcUY7QUFDckYsTUFBNEY7QUFDNUYsTUFBK0c7QUFDL0csTUFBd0c7QUFDeEcsTUFBd0c7QUFDeEcsTUFBdUc7QUFDdkc7QUFDQTs7QUFFQTs7QUFFQSw0QkFBNEIsNkJBQW1CO0FBQy9DLHdCQUF3QiwwQ0FBYTtBQUNyQyxpQkFBaUIsK0JBQWE7QUFDOUIsaUJBQWlCLHVCQUFNO0FBQ3ZCLDZCQUE2Qiw4QkFBa0I7O0FBRS9DLGFBQWEsa0NBQUcsQ0FBQyx3QkFBTzs7OztBQUlpRDtBQUN6RSxPQUFPLG9EQUFlLHdCQUFPLElBQUksd0JBQU8sVUFBVSx3QkFBTyxtQkFBbUIsRUFBQzs7Ozs7O0FDdkI3RSxNQUErRjtBQUMvRixNQUFxRjtBQUNyRixNQUE0RjtBQUM1RixNQUErRztBQUMvRyxNQUF3RztBQUN4RyxNQUF3RztBQUN4RyxNQUFvRztBQUNwRztBQUNBOztBQUVBLElBQUksY0FBTzs7QUFFWCxjQUFPLHFCQUFxQiw2QkFBbUI7QUFDL0MsY0FBTyxpQkFBaUIsMENBQWE7QUFDckMsY0FBTyxVQUFVLCtCQUFhO0FBQzlCLGNBQU8sVUFBVSx1QkFBTTtBQUN2QixjQUFPLHNCQUFzQiw4QkFBa0I7O0FBRS9DLElBQUksYUFBTSxHQUFHLGtDQUFHLENBQUMscUJBQU8sRUFBRSxjQUFPOzs7O0FBSXFDO0FBQ3RFLE9BQU8saURBQWUscUJBQU8sSUFBSSxxQkFBTyxVQUFVLHFCQUFPLG1CQUFtQixFQUFDOzs7QUN4QjdFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsT0FBTztBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxLQUFLLFNBQVM7QUFDM0MsYUFBYSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUU7QUFDNUI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLGlCQUFpQjtBQUMvQjtBQUNBLGdCQUFnQixrQkFBa0I7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLElBQUksSUFBSSxJQUFJLElBQUksSUFBSSxJQUFJLFNBQVM7QUFDakQsZUFBZSxJQUFJLElBQUksSUFBSSxJQUFJLElBQUk7QUFDbkM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDO0FBQ3RDO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSixzQkFBc0IsdUJBQXVCO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRWtNOzs7QUM1a0JsTTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDc0M7O0FBRXRDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLFFBQVE7QUFDckM7QUFDQTtBQUNBLFVBQVU7QUFDVix1QkFBdUIsU0FBUztBQUNoQztBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLG1CQUFtQixTQUFTO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUMsVUFBVTtBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxxQkFBSztBQUNsQjtBQUNBLDBCQUEwQixxQkFBSztBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLFVBQVU7QUFDeEIsOEJBQThCLHFCQUFLO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOLHNCQUFzQixxQkFBSztBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixVQUFVO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQ0FBMkMsVUFBVTtBQUNyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOLHNCQUFzQixxQkFBSztBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFVBQVU7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0MsVUFBVTtBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLFNBQVM7QUFDVCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLG9CQUFvQjtBQUNwQztBQUNBLGdCQUFnQix1Q0FBdUM7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CLGFBQWE7QUFDYjtBQUNBO0FBQ0EsWUFBWSxrQ0FBa0M7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvREFBb0QsS0FBSztBQUN6RDtBQUNBO0FBQ0Esb0RBQW9ELEtBQUs7QUFDekQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQyxPQUFPO0FBQzNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0NBQStDO0FBQy9DO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0EsNENBQTRDLFVBQVU7QUFDdEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixXQUFXO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdEQUF3RDtBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxrQkFBa0I7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSwwQkFBMEI7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUMsVUFBVTtBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxhQUFhO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7QUFDakMsaUNBQWlDO0FBQ2pDLG9DQUFvQztBQUNwQztBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0RBQWtEO0FBQ2xELGlDQUFpQztBQUNqQztBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7QUFDakMsZ0NBQWdDO0FBQ2hDO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7QUFDakMsaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNELFlBQVksa0dBQWtHO0FBQzlHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLDZEQUE2RDtBQUN6RSw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksMENBQTBDO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSw2REFBNkQ7QUFDekU7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDViw0REFBNEQ7QUFDNUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVSxrQkFBa0I7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQyxhQUFhO0FBQzlDLGdDQUFnQyxZQUFZO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QUFD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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsT0FBTztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzRUFBc0U7QUFDdEU7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDLFFBQVE7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixpQkFBaUI7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1EQUFtRDtBQUNuRDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsUUFBUTtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDLFVBQVU7QUFDakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1REFBdUQ7QUFD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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQyxVQUFVO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLFNBQVM7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbURBQW1ELFVBQVU7QUFDN0Q7QUFDQTtBQUNBLDRCQUE0QixZQUFZO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksT0FBTztBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQyxVQUFVO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDLFVBQVU7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsYUFBYTtBQUNyQjtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsT0FBTztBQUNmO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUMsVUFBVTtBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLElBQUk7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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QUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0EsZ0JBQWdCLE9BQU87QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLFNBQVM7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsSUFBSTtBQUNaO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsMkNBQTJDO0FBQzNDLHFDQUFxQyxTQUFTO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsSUFBSTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtB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QUFpRCxhQUFhO0FBQzlEO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksT0FBTztBQUNuQjtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscURBQXFELFVBQVU7QUFDL0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixnQkFBZ0I7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLFdBQVc7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLElBQUk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLElBQUk7QUFDWjtBQUNBLFNBQVM7QUFDVDtBQUNBLFFBQVEsSUFBSTtBQUNaO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QyxVQUFVO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE2Qyx1QkFBdUI7QUFDcEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULHlCQUF5QixjQUFjO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0Isc0NBQXNDO0FBQ3REO0FBQ0E7QUFDQSx3QkFBd0IsYUFBYTtBQUNyQztBQUNBO0FBQ0E7QUFDQSxZQUFZLFFBQVE7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixRQUFRO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QixjQUFjO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxJQUFJO0FBQ2Y7O0FBRUE7QUFDQSxZQUFZLGdFQUFnRTtBQUM1RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOLDhDQUE4QyxPQUFPLGVBQWUsT0FBTztBQUMzRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxpQkFBaUI7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxXQUFXO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLFdBQVc7QUFDL0Isa0JBQWtCLFdBQVc7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxpRUFBaUU7QUFDN0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdFQUFnRSxFQUFFO0FBQ2xFO0FBQ0E7QUFDQTtBQUNBLFlBQVksaURBQWlEO0FBQzdEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzRkFBc0YsT0FBTztBQUM3RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtEQUErRCxPQUFPO0FBQ3RFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzR0FBc0csT0FBTztBQUM3RztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1FQUFtRSxPQUFPO0FBQzFFO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLDRDQUE0QztBQUN4RDtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsaUJBQWlCO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBLHFEQUFxRCxHQUFHLElBQUksR0FBRztBQUMvRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksc0RBQXNEO0FBQ2xFLFlBQVksaUVBQWlFO0FBQzdFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsaUJBQWlCO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBLHFEQUFxRCxHQUFHLElBQUksR0FBRztBQUMvRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixvQkFBb0IsRUFBRSxpQkFBaUI7QUFDdkQ7QUFDQTtBQUNBLFNBQVM7QUFDVCxnQkFBZ0IscUVBQXFFO0FBQ3JGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCLGNBQWM7QUFDN0MsK0JBQStCLGFBQWE7QUFDNUMsZ0RBQWdELEdBQUc7QUFDbkQsNkJBQTZCLFVBQVU7QUFDdkM7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLDZEQUE2RDtBQUM3RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixvQkFBb0I7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQiwyQkFBMkI7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQ0FBMkMsR0FBRyw4QkFBOEIsR0FBRztBQUMvRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQ0FBMEMsRUFBRTtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esa0JBQWtCLGNBQWM7QUFDaEMsb0JBQW9CLGNBQWM7QUFDbEMseUJBQXlCLGNBQWM7QUFDdkMsbUJBQW1CLGNBQWM7QUFDakMsb0JBQW9CLGNBQWM7QUFDbEMsc0JBQXNCLGNBQWM7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxjQUFjO0FBQzdCO0FBQ0E7QUFDQSxlQUFlLGNBQWM7QUFDN0I7QUFDQTtBQUNBO0FBQ0EsOENBQThDO0FBQzlDO0FBQ0EsWUFBWSx1REFBdUQ7QUFDbkUsWUFBWSx5Q0FBeUM7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksb0JBQW9CO0FBQ2hDLFlBQVksK0JBQStCO0FBQzNDO0FBQ0EsVUFBVSx3QkFBd0I7QUFDbEM7QUFDQSxlQUFlLFdBQVc7QUFDMUI7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSx3QkFBd0I7QUFDcEMsWUFBWSx3QkFBd0I7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxXQUFXO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLHFCQUFxQjtBQUNwQztBQUNBO0FBQ0EsZUFBZSxvQkFBb0I7QUFDbkM7QUFDQSxXQUFXLFlBQVk7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLHNCQUFzQjtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksMEJBQTBCO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbURBQW1ELGdCQUFnQjtBQUNuRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QixjQUFjO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQ0FBMkMsVUFBVTtBQUNyRCxvQkFBb0IsZUFBZTtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsWUFBWSxpQkFBaUI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsU0FBUztBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsU0FBUztBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0RBQWtELGNBQWM7QUFDaEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsU0FBUztBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFlBQVksaUNBQWlDO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IsV0FBVztBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsTUFBTTtBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxzQkFBc0I7QUFDbEM7QUFDQTtBQUNBO0FBQ0EsY0FBYyxhQUFhO0FBQzNCO0FBQ0E7QUFDQSwrQ0FBK0MsUUFBUTtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCLFVBQVUsNkNBQTZDLFVBQVU7QUFDaEc7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQ0FBK0M7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQiwyQkFBMkIsb0NBQW9DO0FBQy9FLGdCQUFnQixpQkFBaUI7QUFDakMsc0RBQXNELGtCQUFrQjtBQUN4RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQiw2QkFBNkI7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxJQUFJLGNBQVE7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFFBQVEsWUFBWSwyQkFBMkI7QUFDL0QsZ0JBQWdCLFlBQVk7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxpQkFBaUI7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCLGlCQUFpQjtBQUNoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQiwyQkFBMkI7QUFDM0M7QUFDQSwyQkFBMkIsYUFBYTtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixtQkFBbUI7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBLGlCQUFpQixhQUFhLGVBQWUsYUFBYTtBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxVQUFVO0FBQ3RCLFlBQVksdUNBQXVDO0FBQ25EO0FBQ0EsZ0JBQWdCLFdBQVcsQ0FBQyxZQUFZO0FBQ3hDO0FBQ0E7QUFDQSxnQkFBZ0IsV0FBVyxDQUFDLFlBQVk7QUFDeEMsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQixxQkFBcUI7QUFDekM7QUFDQTtBQUNBLGdCQUFnQixPQUFPO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixpQkFBaUI7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixhQUFhO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlFQUF5RSxrQkFBa0I7QUFDM0Y7QUFDQTtBQUNBLFNBQVM7QUFDVCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxlQUFlO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLCtCQUErQixjQUFjO0FBQzdDO0FBQ0E7QUFDQSxnQ0FBZ0MsYUFBYTtBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixlQUFlO0FBQy9CLGNBQWMsZUFBZTtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxxQkFBcUI7QUFDakM7QUFDQTtBQUNBLDZCQUE2QixjQUFjO0FBQzNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxVQUFVLGFBQWE7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsUUFBUSxPQUFPO0FBQ2Y7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxjQUFjO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxRQUFRO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBLFFBQVEsY0FBYztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTSxTQUFTLFFBQVE7QUFDdkI7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU0sU0FBUyxRQUFRO0FBQ3ZCO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxjQUFjO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxZQUFZLHdCQUF3QjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxtQkFBbUIscUJBQXFCO0FBQ3hDO0FBQ0EsbUNBQW1DLGtCQUFrQjtBQUNyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsa0JBQWtCO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQix1QkFBdUI7QUFDMUM7QUFDQSxnQkFBZ0Isd0JBQXdCO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLHFCQUFxQjtBQUN4QztBQUNBO0FBQ0E7QUFDQSxZQUFZLFVBQVU7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixrQkFBa0I7QUFDbEM7QUFDQTtBQUNBLGlCQUFpQixHQUFHO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0Isa0JBQWtCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxZQUFZLHVCQUF1QjtBQUNuQyxRQUFRLGNBQWM7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxVQUFVLFVBQVU7QUFDaEM7QUFDQSxRQUFRLGNBQWM7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxnQkFBZ0I7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLG1CQUFtQixZQUFZO0FBQy9CO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxZQUFZLHVCQUF1QjtBQUNuQztBQUNBO0FBQ0E7QUFDQSxZQUFZLCtCQUErQjtBQUMzQztBQUNBLFFBQVEsUUFBUTtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULFFBQVEsVUFBVTtBQUNsQjtBQUNBO0FBQ0E7QUFDQSxZQUFZLGdEQUFnRDtBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxZQUFZLHFCQUFxQjtBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixlQUFlO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLDRDQUE0QztBQUN4RDtBQUNBLGlCQUFpQiwyQ0FBMkM7QUFDNUQsZ0JBQWdCLFNBQVMsMEJBQTBCLFFBQVE7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxnQkFBZ0I7QUFDNUIsWUFBWSwwQkFBMEI7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixXQUFXO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsV0FBVztBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUMsUUFBUTtBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDQUF5QyxRQUFRO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxVQUFVLDRDQUE0QztBQUN0RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLFFBQVE7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixpQkFBaUI7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQixNQUFNO0FBQ2hDO0FBQ0E7QUFDQSxnQkFBZ0IseUJBQXlCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsNEJBQTRCLFVBQVUsaUJBQWlCO0FBQ3ZFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLDZCQUE2QixVQUFVLGlCQUFpQjtBQUN4RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsMEJBQTBCO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0Isc0NBQXNDLGtCQUFrQixXQUFXLFlBQVk7QUFDL0YsMEJBQTBCLGFBQWE7QUFDdkM7QUFDQTtBQUNBLHVCQUF1QixjQUFjO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQixjQUFjO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQSxzQkFBc0IsY0FBYztBQUNwQztBQUNBO0FBQ0E7QUFDQSwwQkFBMEIsY0FBYztBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxRQUFRO0FBQ3BCO0FBQ0EsWUFBWSxVQUFVO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixrREFBa0Q7QUFDbEUsZ0JBQWdCLDZCQUE2QjtBQUM3Qyw2QkFBNkIsUUFBUTtBQUNyQywwQkFBMEIsYUFBYTtBQUN2QywwQkFBMEIsTUFBTTtBQUNoQyxnQkFBZ0IsV0FBVztBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLHFDQUFxQztBQUNyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEJBQThCLGNBQWM7QUFDNUMsNEJBQTRCLGNBQWM7QUFDMUMsMEJBQTBCLGNBQWM7QUFDeEMsaUNBQWlDLGNBQWM7QUFDL0MsMkJBQTJCLGNBQWM7QUFDekM7QUFDQSw4QkFBOEIsY0FBYztBQUM1Qyw0QkFBNEIsY0FBYztBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsZUFBZTtBQUMvQixjQUFjO0FBQ2Q7QUFDQTtBQUNBLHFDQUFxQyxhQUFhO0FBQ2xEO0FBQ0E7QUFDQSxvQkFBb0Isa0JBQWtCO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckIsa0JBQWtCO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxVQUFVO0FBQ3RCO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixjQUFjO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0EsbUJBQW1CLGNBQWM7QUFDakM7QUFDQTtBQUNBO0FBQ0EsUUFBUSxxQkFBcUI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyxjQUFjO0FBQ2pEO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQSwrQkFBK0IsY0FBYztBQUM3QztBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsTUFBTTtBQUN0QjtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0EsU0FBUztBQUNULFFBQVEsb0JBQW9CO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLE1BQU07QUFDaEMsNkJBQTZCLFNBQVM7QUFDdEM7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLGFBQWE7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsY0FBYztBQUNqQyxVQUFVO0FBQ1Y7QUFDQSw2Q0FBNkMsY0FBYztBQUMzRDtBQUNBLGtCQUFrQixjQUFjO0FBQ2hDLDRDQUE0QyxrQkFBa0I7QUFDOUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLFVBQVU7QUFDbEI7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLE1BQU07QUFDaEMsNkJBQTZCLFNBQVM7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLFVBQVUsOEJBQThCLFVBQVU7QUFDOUQ7QUFDQSx1QkFBdUIsZUFBZTtBQUN0QztBQUNBLG9CQUFvQixVQUFVLGdEQUFnRCxVQUFVO0FBQ3hGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFFBQVE7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsUUFBUTtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWLFlBQVksUUFBUTtBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLFVBQVUsc0ZBQXNGO0FBQ3hIO0FBQ0E7QUFDQSx3Q0FBd0MsU0FBUztBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQixPQUFPO0FBQ2pDLHdCQUF3QixTQUFTO0FBQ2pDLHFDQUFxQyxNQUFNO0FBQzNDO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQix5Q0FBeUM7QUFDekQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsY0FBYztBQUNuQztBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQSx5QkFBeUIsY0FBYztBQUN2QywyQkFBMkIsRUFBRTtBQUM3QixjQUFjO0FBQ2Q7QUFDQSx5QkFBeUIsY0FBYztBQUN2QywyQkFBMkIsRUFBRTtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QixNQUFNO0FBQy9CO0FBQ0E7QUFDQSxnQkFBZ0IseUNBQXlDO0FBQ3pELFFBQVEsVUFBVTtBQUNsQjtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsa0JBQWtCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsTUFBTSxTQUFHO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFFBQVEsU0FBRztBQUNYLEtBQUs7QUFDTDtBQUNBLGlDQUFpQyxTQUFHO0FBQ3BDLFFBQVEsU0FBRztBQUNYLEtBQUs7QUFDTDtBQUNBLHNCQUFzQixTQUFHO0FBQ3pCO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUMsU0FBUztBQUNoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVDQUF1QyxTQUFTO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQixxQkFBcUI7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLE9BQU87QUFDbkI7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxrQ0FBa0M7QUFDOUM7QUFDQSxZQUFZLGlCQUFpQjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSx5QkFBeUI7QUFDckMsWUFBWSx3QkFBd0I7QUFDcEMscUJBQXFCLE1BQU07QUFDM0Isc0JBQXNCLE1BQU07QUFDNUIsdUJBQXVCLE1BQU07QUFDN0I7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLFNBQVM7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksSUFBSTtBQUNSO0FBQ0EsSUFBSSxJQUFJO0FBQ1I7QUFDQSxJQUFJLElBQUk7QUFDUixRQUFRLElBQUk7QUFDWixRQUFRLElBQUk7QUFDWixRQUFRLElBQUk7QUFDWixLQUFLO0FBQ0w7QUFDQTtBQUNBLElBQUksSUFBSTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLGNBQWM7QUFDMUI7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxhQUFhO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksYUFBYTtBQUN6QixZQUFZLGlDQUFpQyxtQkFBbUI7QUFDaEU7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVUsYUFBYTtBQUN2QjtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVLGNBQWM7QUFDeEI7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSwyQ0FBMkM7QUFDdkQsWUFBWSxtQkFBbUI7QUFDL0I7QUFDQSxZQUFZLGlEQUFpRCxFQUFFLGFBQWE7QUFDNUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLFdBQVcsV0FBVztBQUN0QixXQUFXLFdBQVc7QUFDdEI7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLFNBQVM7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxhQUFhO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsSUFBSTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxnQkFBZ0IsSUFBSTtBQUNwQixnQkFBZ0IsSUFBSTtBQUNwQixpQkFBaUIsSUFBSTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLGFBQWE7QUFDMUI7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxnQkFBZ0IsSUFBSTtBQUNwQixlQUFlLElBQUk7QUFDbkIsa0JBQWtCLElBQUk7QUFDdEIsWUFBWSxJQUFJO0FBQ2hCLGlCQUFpQixJQUFJO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixhQUFhO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLGFBQWE7QUFDN0I7QUFDQSxRQUFRLElBQUk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsYUFBYTtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0NBQXdDLFNBQVM7QUFDakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsSUFBSTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9EQUFvRDtBQUNwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLG1CQUFtQjtBQUNuQyxnQkFBZ0IsNEJBQTRCO0FBQzVDLGdCQUFnQixpREFBaUQsRUFBRSxhQUFhO0FBQ2hGLGdCQUFnQixtQkFBbUI7QUFDbkMsZ0JBQWdCLGtCQUFrQjtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QixhQUFhO0FBQzNDO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixNQUFNO0FBQzlCO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixZQUFZO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0Isd0JBQXdCO0FBQ3hDLHlCQUF5QixNQUFNO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksU0FBUztBQUNyQjtBQUNBO0FBQ0EsWUFBWSxTQUFTO0FBQ3JCLFVBQVU7QUFDViw0QkFBNEIsUUFBUTtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDLGFBQWE7QUFDOUM7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLGtCQUFrQjtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLGtCQUFrQjtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFFBQVE7QUFDeEIsZ0JBQWdCLCtFQUErRTtBQUMvRix5QkFBeUIsTUFBTTtBQUMvQjtBQUNBO0FBQ0EsMEJBQTBCLGFBQWE7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsSUFBSTtBQUNaO0FBQ0EsdUNBQXVDLFVBQVU7QUFDakQ7QUFDQTtBQUNBO0FBQ0EsWUFBWSxJQUFJO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0Q0FBNEMsVUFBVTtBQUN0RDtBQUNBO0FBQ0E7QUFDQSxZQUFZLElBQUk7QUFDaEI7QUFDQTtBQUNBO0FBQ0EsUUFBUSxJQUFJO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEIsYUFBYTtBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QixNQUFNO0FBQy9CO0FBQ0E7QUFDQSx1QkFBdUIsWUFBWTtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsbUJBQW1CO0FBQ25DLGdCQUFnQixTQUFTO0FBQ3pCLGdCQUFnQixrQkFBa0I7QUFDbEMsZ0JBQWdCLGlEQUFpRCxFQUFFLGFBQWE7QUFDaEY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0RBQW9EO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsU0FBUztBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxxQkFBcUI7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLG9CQUFvQjtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDLHVCQUF1QjtBQUNwRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QseUJBQXlCLGNBQWM7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyxjQUFjO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQiw2QkFBNkI7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlEQUF5RCxXQUFXO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QixpQkFBaUI7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxhQUFhO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBLCtGQUErRixjQUFjO0FBQzdHO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQiwyQkFBMkI7QUFDM0MsY0FBYyxhQUFhO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsY0FBYztBQUMzQztBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBWSx3RkFBd0Y7QUFDcEc7QUFDQTtBQUNBLFlBQVkseUJBQXlCO0FBQ3JDLHdCQUF3QixhQUFhO0FBQ3JDLHdCQUF3QixhQUFhO0FBQ3JDLDBCQUEwQixhQUFhO0FBQ3ZDO0FBQ0Esa0JBQWtCLE9BQU87QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixPQUFPO0FBQ3pCO0FBQ0EsU0FBUyxhQUFhO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSw0Q0FBNEMsV0FBVztBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLFlBQVksWUFBWTtBQUN4QjtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsY0FBYyxXQUFXLGNBQWM7QUFDMUUsMEJBQTBCLGFBQWE7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFlBQVk7QUFDNUI7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxVQUFVLGVBQWU7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSw0QkFBNEIsWUFBWTtBQUN4QztBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELDJCQUEyQjtBQUMzRSxnQkFBZ0IsU0FBUztBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxhQUFhO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsZUFBZTtBQUMvQixnQkFBZ0IsMkJBQTJCO0FBQzNDLGNBQWMsYUFBYTtBQUMzQjtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIsSUFBSTtBQUNoQyw0QkFBNEIsSUFBSTtBQUNoQztBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsNEJBQTRCO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDLFFBQVEsbUJBQW1CLFVBQVUsZ0NBQWdDLFVBQVU7QUFDdEg7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxrQkFBa0I7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxZQUFZO0FBQzNCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IsS0FBSztBQUMzQjtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsYUFBYTtBQUM3QixtQkFBbUIsY0FBYztBQUNqQyxtQkFBbUIsY0FBYztBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLFNBQVM7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxtQ0FBbUMsS0FBSztBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE2QyxZQUFZO0FBQ3pELFVBQVUsZUFBZTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsZUFBZTtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLGVBQWU7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLEtBQUs7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxjQUFjO0FBQzdCO0FBQ0E7QUFDQSxnQkFBZ0IsYUFBYTtBQUM3QixtQkFBbUIsY0FBYztBQUNqQyxtQkFBbUIsY0FBYztBQUNqQztBQUNBO0FBQ0E7QUFDQSw4REFBOEQsY0FBYztBQUM1RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLDJCQUEyQjtBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksa0JBQWtCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkNBQTJDLFlBQVk7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQkFBMkIsS0FBSztBQUNoQywyQkFBMkIsS0FBSyxhQUFhLEtBQUs7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlFQUFpRSxLQUFLO0FBQ3RFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsU0FBUztBQUNqQyxlQUFlLGNBQWMsc0NBQXNDLFFBQVE7QUFDM0U7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLE9BQU87QUFDbkI7QUFDQTtBQUNBO0FBQ0EsV0FBVyxZQUFZO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0RBQStELEVBQUU7QUFDakUsbUJBQW1CLGdCQUFnQjtBQUNuQztBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsTUFBTTtBQUM3QjtBQUNBO0FBQ0EsNkJBQTZCLGVBQWU7QUFDNUMsaUNBQWlDLFNBQVM7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLDRDQUE0QztBQUN4RDtBQUNBLDZCQUE2QixTQUFTLENBQUMsZUFBZSw0QkFBNEIsT0FBTztBQUN6RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLCtCQUErQjtBQUMzQyx5QkFBeUIsY0FBYztBQUN2QztBQUNBO0FBQ0EsS0FBSyxXQUFXLGNBQWM7QUFDOUI7QUFDQTtBQUNBLEtBQUssV0FBVyxjQUFjO0FBQzlCO0FBQ0E7QUFDQSxLQUFLLFdBQVcsY0FBYztBQUM5QjtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksK0JBQStCO0FBQzNDO0FBQ0E7QUFDQSw2Q0FBNkMsRUFBRTtBQUMvQztBQUNBO0FBQ0EsbUJBQW1CLGdCQUFnQjtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSwrQkFBK0I7QUFDM0MsWUFBWSxpQkFBaUI7QUFDN0IsU0FBUyxhQUFhO0FBQ3RCLDZCQUE2QixhQUFhO0FBQzFDLHdCQUF3QixTQUFTO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxrQkFBa0I7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxpQkFBaUIsa0JBQWtCO0FBQy9DLGdDQUFnQyxRQUFRO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixNQUFNO0FBQzdCLGdCQUFnQixxQkFBcUI7QUFDckMsUUFBUSxVQUFVO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxZQUFZLE9BQU87QUFDbkI7QUFDQSx5REFBeUQsR0FBRztBQUM1RCxNQUFNO0FBQ047QUFDQTtBQUNBLHVCQUF1QixnQkFBZ0I7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVkscUJBQXFCO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsYUFBYTtBQUN4QjtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLEtBQUs7QUFDM0IsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3Q0FBd0MsU0FBUztBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixhQUFhO0FBQzdCLG1CQUFtQixjQUFjO0FBQ2pDLG1CQUFtQixjQUFjO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEIsUUFBUTtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyxHQUFHO0FBQ25DO0FBQ0EsZUFBZSxlQUFlLDJCQUEyQixTQUFTO0FBQ2xFO0FBQ0E7QUFDQSxZQUFZLGFBQWE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxhQUFhO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0RBQWtELE9BQU87QUFDekQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsK0JBQStCO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsMEJBQTBCLGVBQWU7QUFDekQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQiw4QkFBOEI7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0MsUUFBUTtBQUM1QztBQUNBLHdCQUF3QixxQkFBcUI7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsTUFBTTtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLFNBQVM7QUFDekM7QUFDQTtBQUNBLFlBQVksVUFBVTtBQUN0QjtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLGFBQWE7QUFDckI7QUFDQTtBQUNBO0FBQ0EsWUFBWSwrQkFBK0I7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLGNBQWM7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUNBQXFDLFFBQVE7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QyxjQUFjO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQyw2QkFBNkI7QUFDL0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhEQUE4RCxVQUFVO0FBQ3hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ04sZ0JBQWdCLFdBQVcsRUFBRSxPQUFPO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixlQUFlO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QiwyREFBMkQ7QUFDM0Q7QUFDQTtBQUNBLFFBQVEsT0FBTztBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLHVDQUF1QztBQUNyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxjQUFjO0FBQzVCLGNBQWMsY0FBYztBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IsY0FBYztBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixXQUFXO0FBQzNCLGNBQWMsV0FBVztBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QixjQUFjO0FBQ3ZDO0FBQ0EsMkJBQTJCLFFBQVE7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQyxZQUFZO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsUUFBUTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QyxVQUFVO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IsU0FBUztBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0NBQXdDLFVBQVU7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDQUF5QyxVQUFVO0FBQ25EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFlBQVk7QUFDM0I7QUFDQTs7QUFFQSxTQUFTLGlCQUFXO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFdBQVcsRUFBRSxZQUFZO0FBQ3hDO0FBQ0EsV0FBVyxzQ0FBc0M7QUFDakQsV0FBVyxzQ0FBc0M7QUFDakQsTUFBTTtBQUNOO0FBQ0EsZUFBZSxXQUFXLEVBQUUsWUFBWTtBQUN4QztBQUNBLFdBQVcsc0NBQXNDO0FBQ2pELFdBQVcsc0NBQXNDO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLGlCQUFXO0FBQ2xDLDJCQUEyQixpQkFBVztBQUN0QztBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsYUFBYTtBQUM3QjtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkMsVUFBVTtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3Q0FBd0MsVUFBVTtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsaUJBQVc7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGlCQUFXO0FBQzFCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBLElBQUksY0FBUTtBQUNaO0FBQ0E7QUFDQTs7QUFFK3RCO0FBQy90Qjs7O0FDL3NXc0Q7O0FBRXRELEtBQUssYUFBYSxhQUFhOztBQUVFO0FBQ2pDLDJDQUFlLEtBQUssRUFBQzs7Ozs7OztBQ0xyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDOEg7QUFDdEM7O0FBRXhGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0EsUUFBUSxVQUFVLGFBQWE7QUFDL0I7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLGdCQUFnQixVQUFVO0FBQzFCO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsa0NBQWtDLFVBQVU7QUFDNUM7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTs7QUFFQSxvQ0FBb0MsVUFBVTtBQUM5QztBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBLFlBQVk7QUFDWjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsSUFBSSx5Q0FBVztBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsR0FBRzs7QUFFSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FB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QjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9DQUFvQzs7QUFFcEM7QUFDQTtBQUNBLG9DQUFvQztBQUNwQzs7QUFFQTtBQUNBO0FBQ0Esd0VBQXdFLHNCQUFzQjtBQUM5RjtBQUNBLCtDQUErQztBQUMvQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7QUFDTCxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsQ0FBQyIsInNvdXJjZXMiOlsid2VicGFjazovL2NvbnRyb2Nvcm8tbGFuZGluZy1wYWdlLy4vc3JjL25vcm1hbGl6ZS5jc3M/Njg1NiIsIndlYnBhY2s6Ly9jb250cm9jb3JvLWxhbmRpbmctcGFnZS8uL3NyYy9zdHlsZXMuY3NzPzQ0YjIiLCJ3ZWJwYWNrOi8vY29udHJvY29yby1sYW5kaW5nLXBhZ2UvLi9ub2RlX21vZHVsZXMvQGt1cmtsZS9jb2xvci9kaXN0L2NvbG9yLmVzbS5qcz84N2NkIiwid2VicGFjazovL2NvbnRyb2Nvcm8tbGFuZGluZy1wYWdlLy4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL2Rpc3QvY2h1bmtzL2hlbHBlcnMuc2VnbWVudC5qcz81MzljIiwid2VicGFjazovL2NvbnRyb2Nvcm8tbGFuZGluZy1wYWdlLy4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL2Rpc3QvY2hhcnQuanM/M2E2MCIsIndlYnBhY2s6Ly9jb250cm9jb3JvLWxhbmRpbmctcGFnZS8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9hdXRvL2F1dG8uanM/MzAxZSIsIndlYnBhY2s6Ly9jb250cm9jb3JvLWxhbmRpbmctcGFnZS8uL25vZGVfbW9kdWxlcy9jaGFydGpzLXBsdWdpbi1kYXRhbGFiZWxzL2Rpc3QvY2hhcnRqcy1wbHVnaW4tZGF0YWxhYmVscy5lc20uanM/ZDlmYSIsIndlYnBhY2s6Ly9jb250cm9jb3JvLWxhbmRpbmctcGFnZS8uL3NyYy9pbmRleC5qcz9iNjM1Il0sInNvdXJjZXNDb250ZW50IjpbIlxuICAgICAgaW1wb3J0IEFQSSBmcm9tIFwiIS4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luamVjdFN0eWxlc0ludG9TdHlsZVRhZy5qc1wiO1xuICAgICAgaW1wb3J0IGRvbUFQSSBmcm9tIFwiIS4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlRG9tQVBJLmpzXCI7XG4gICAgICBpbXBvcnQgaW5zZXJ0Rm4gZnJvbSBcIiEuLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRCeVNlbGVjdG9yLmpzXCI7XG4gICAgICBpbXBvcnQgc2V0QXR0cmlidXRlcyBmcm9tIFwiIS4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3NldEF0dHJpYnV0ZXNXaXRob3V0QXR0cmlidXRlcy5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydFN0eWxlRWxlbWVudCBmcm9tIFwiIS4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydFN0eWxlRWxlbWVudC5qc1wiO1xuICAgICAgaW1wb3J0IHN0eWxlVGFnVHJhbnNmb3JtRm4gZnJvbSBcIiEuLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZVRhZ1RyYW5zZm9ybS5qc1wiO1xuICAgICAgaW1wb3J0IGNvbnRlbnQsICogYXMgbmFtZWRFeHBvcnQgZnJvbSBcIiEhLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi9ub3JtYWxpemUuY3NzXCI7XG4gICAgICBcbiAgICAgIFxuXG52YXIgb3B0aW9ucyA9IHt9O1xuXG5vcHRpb25zLnN0eWxlVGFnVHJhbnNmb3JtID0gc3R5bGVUYWdUcmFuc2Zvcm1Gbjtcbm9wdGlvbnMuc2V0QXR0cmlidXRlcyA9IHNldEF0dHJpYnV0ZXM7XG5vcHRpb25zLmluc2VydCA9IGluc2VydEZuLmJpbmQobnVsbCwgXCJoZWFkXCIpO1xub3B0aW9ucy5kb21BUEkgPSBkb21BUEk7XG5vcHRpb25zLmluc2VydFN0eWxlRWxlbWVudCA9IGluc2VydFN0eWxlRWxlbWVudDtcblxudmFyIHVwZGF0ZSA9IEFQSShjb250ZW50LCBvcHRpb25zKTtcblxuXG5cbmV4cG9ydCAqIGZyb20gXCIhIS4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vbm9ybWFsaXplLmNzc1wiO1xuICAgICAgIGV4cG9ydCBkZWZhdWx0IGNvbnRlbnQgJiYgY29udGVudC5sb2NhbHMgPyBjb250ZW50LmxvY2FscyA6IHVuZGVmaW5lZDtcbiIsIlxuICAgICAgaW1wb3J0IEFQSSBmcm9tIFwiIS4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luamVjdFN0eWxlc0ludG9TdHlsZVRhZy5qc1wiO1xuICAgICAgaW1wb3J0IGRvbUFQSSBmcm9tIFwiIS4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlRG9tQVBJLmpzXCI7XG4gICAgICBpbXBvcnQgaW5zZXJ0Rm4gZnJvbSBcIiEuLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRCeVNlbGVjdG9yLmpzXCI7XG4gICAgICBpbXBvcnQgc2V0QXR0cmlidXRlcyBmcm9tIFwiIS4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3NldEF0dHJpYnV0ZXNXaXRob3V0QXR0cmlidXRlcy5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydFN0eWxlRWxlbWVudCBmcm9tIFwiIS4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydFN0eWxlRWxlbWVudC5qc1wiO1xuICAgICAgaW1wb3J0IHN0eWxlVGFnVHJhbnNmb3JtRm4gZnJvbSBcIiEuLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZVRhZ1RyYW5zZm9ybS5qc1wiO1xuICAgICAgaW1wb3J0IGNvbnRlbnQsICogYXMgbmFtZWRFeHBvcnQgZnJvbSBcIiEhLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi9zdHlsZXMuY3NzXCI7XG4gICAgICBcbiAgICAgIFxuXG52YXIgb3B0aW9ucyA9IHt9O1xuXG5vcHRpb25zLnN0eWxlVGFnVHJhbnNmb3JtID0gc3R5bGVUYWdUcmFuc2Zvcm1Gbjtcbm9wdGlvbnMuc2V0QXR0cmlidXRlcyA9IHNldEF0dHJpYnV0ZXM7XG5vcHRpb25zLmluc2VydCA9IGluc2VydEZuLmJpbmQobnVsbCwgXCJoZWFkXCIpO1xub3B0aW9ucy5kb21BUEkgPSBkb21BUEk7XG5vcHRpb25zLmluc2VydFN0eWxlRWxlbWVudCA9IGluc2VydFN0eWxlRWxlbWVudDtcblxudmFyIHVwZGF0ZSA9IEFQSShjb250ZW50LCBvcHRpb25zKTtcblxuXG5cbmV4cG9ydCAqIGZyb20gXCIhIS4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vc3R5bGVzLmNzc1wiO1xuICAgICAgIGV4cG9ydCBkZWZhdWx0IGNvbnRlbnQgJiYgY29udGVudC5sb2NhbHMgPyBjb250ZW50LmxvY2FscyA6IHVuZGVmaW5lZDtcbiIsIi8qIVxuICogQGt1cmtsZS9jb2xvciB2MC4zLjJcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9rdXJrbGUvY29sb3IjcmVhZG1lXG4gKiAoYykgMjAyMyBKdWtrYSBLdXJrZWxhXG4gKiBSZWxlYXNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2VcbiAqL1xuZnVuY3Rpb24gcm91bmQodikge1xuICByZXR1cm4gdiArIDAuNSB8IDA7XG59XG5jb25zdCBsaW0gPSAodiwgbCwgaCkgPT4gTWF0aC5tYXgoTWF0aC5taW4odiwgaCksIGwpO1xuZnVuY3Rpb24gcDJiKHYpIHtcbiAgcmV0dXJuIGxpbShyb3VuZCh2ICogMi41NSksIDAsIDI1NSk7XG59XG5mdW5jdGlvbiBiMnAodikge1xuICByZXR1cm4gbGltKHJvdW5kKHYgLyAyLjU1KSwgMCwgMTAwKTtcbn1cbmZ1bmN0aW9uIG4yYih2KSB7XG4gIHJldHVybiBsaW0ocm91bmQodiAqIDI1NSksIDAsIDI1NSk7XG59XG5mdW5jdGlvbiBiMm4odikge1xuICByZXR1cm4gbGltKHJvdW5kKHYgLyAyLjU1KSAvIDEwMCwgMCwgMSk7XG59XG5mdW5jdGlvbiBuMnAodikge1xuICByZXR1cm4gbGltKHJvdW5kKHYgKiAxMDApLCAwLCAxMDApO1xufVxuXG5jb25zdCBtYXAkMSA9IHswOiAwLCAxOiAxLCAyOiAyLCAzOiAzLCA0OiA0LCA1OiA1LCA2OiA2LCA3OiA3LCA4OiA4LCA5OiA5LCBBOiAxMCwgQjogMTEsIEM6IDEyLCBEOiAxMywgRTogMTQsIEY6IDE1LCBhOiAxMCwgYjogMTEsIGM6IDEyLCBkOiAxMywgZTogMTQsIGY6IDE1fTtcbmNvbnN0IGhleCA9IFsuLi4nMDEyMzQ1Njc4OUFCQ0RFRiddO1xuY29uc3QgaDEgPSBiID0+IGhleFtiICYgMHhGXTtcbmNvbnN0IGgyID0gYiA9PiBoZXhbKGIgJiAweEYwKSA+PiA0XSArIGhleFtiICYgMHhGXTtcbmNvbnN0IGVxID0gYiA9PiAoKGIgJiAweEYwKSA+PiA0KSA9PT0gKGIgJiAweEYpO1xuY29uc3QgaXNTaG9ydCA9IHYgPT4gZXEodi5yKSAmJiBlcSh2LmcpICYmIGVxKHYuYikgJiYgZXEodi5hKTtcbmZ1bmN0aW9uIGhleFBhcnNlKHN0cikge1xuICB2YXIgbGVuID0gc3RyLmxlbmd0aDtcbiAgdmFyIHJldDtcbiAgaWYgKHN0clswXSA9PT0gJyMnKSB7XG4gICAgaWYgKGxlbiA9PT0gNCB8fCBsZW4gPT09IDUpIHtcbiAgICAgIHJldCA9IHtcbiAgICAgICAgcjogMjU1ICYgbWFwJDFbc3RyWzFdXSAqIDE3LFxuICAgICAgICBnOiAyNTUgJiBtYXAkMVtzdHJbMl1dICogMTcsXG4gICAgICAgIGI6IDI1NSAmIG1hcCQxW3N0clszXV0gKiAxNyxcbiAgICAgICAgYTogbGVuID09PSA1ID8gbWFwJDFbc3RyWzRdXSAqIDE3IDogMjU1XG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAobGVuID09PSA3IHx8IGxlbiA9PT0gOSkge1xuICAgICAgcmV0ID0ge1xuICAgICAgICByOiBtYXAkMVtzdHJbMV1dIDw8IDQgfCBtYXAkMVtzdHJbMl1dLFxuICAgICAgICBnOiBtYXAkMVtzdHJbM11dIDw8IDQgfCBtYXAkMVtzdHJbNF1dLFxuICAgICAgICBiOiBtYXAkMVtzdHJbNV1dIDw8IDQgfCBtYXAkMVtzdHJbNl1dLFxuICAgICAgICBhOiBsZW4gPT09IDkgPyAobWFwJDFbc3RyWzddXSA8PCA0IHwgbWFwJDFbc3RyWzhdXSkgOiAyNTVcbiAgICAgIH07XG4gICAgfVxuICB9XG4gIHJldHVybiByZXQ7XG59XG5jb25zdCBhbHBoYSA9IChhLCBmKSA9PiBhIDwgMjU1ID8gZihhKSA6ICcnO1xuZnVuY3Rpb24gaGV4U3RyaW5nKHYpIHtcbiAgdmFyIGYgPSBpc1Nob3J0KHYpID8gaDEgOiBoMjtcbiAgcmV0dXJuIHZcbiAgICA/ICcjJyArIGYodi5yKSArIGYodi5nKSArIGYodi5iKSArIGFscGhhKHYuYSwgZilcbiAgICA6IHVuZGVmaW5lZDtcbn1cblxuY29uc3QgSFVFX1JFID0gL14oaHNsYT98aHdifGhzdilcXChcXHMqKFstKy5lXFxkXSspKD86ZGVnKT9bXFxzLF0rKFstKy5lXFxkXSspJVtcXHMsXSsoWy0rLmVcXGRdKyklKD86W1xccyxdKyhbLSsuZVxcZF0rKSglKT8pP1xccypcXCkkLztcbmZ1bmN0aW9uIGhzbDJyZ2JuKGgsIHMsIGwpIHtcbiAgY29uc3QgYSA9IHMgKiBNYXRoLm1pbihsLCAxIC0gbCk7XG4gIGNvbnN0IGYgPSAobiwgayA9IChuICsgaCAvIDMwKSAlIDEyKSA9PiBsIC0gYSAqIE1hdGgubWF4KE1hdGgubWluKGsgLSAzLCA5IC0gaywgMSksIC0xKTtcbiAgcmV0dXJuIFtmKDApLCBmKDgpLCBmKDQpXTtcbn1cbmZ1bmN0aW9uIGhzdjJyZ2JuKGgsIHMsIHYpIHtcbiAgY29uc3QgZiA9IChuLCBrID0gKG4gKyBoIC8gNjApICUgNikgPT4gdiAtIHYgKiBzICogTWF0aC5tYXgoTWF0aC5taW4oaywgNCAtIGssIDEpLCAwKTtcbiAgcmV0dXJuIFtmKDUpLCBmKDMpLCBmKDEpXTtcbn1cbmZ1bmN0aW9uIGh3YjJyZ2JuKGgsIHcsIGIpIHtcbiAgY29uc3QgcmdiID0gaHNsMnJnYm4oaCwgMSwgMC41KTtcbiAgbGV0IGk7XG4gIGlmICh3ICsgYiA+IDEpIHtcbiAgICBpID0gMSAvICh3ICsgYik7XG4gICAgdyAqPSBpO1xuICAgIGIgKj0gaTtcbiAgfVxuICBmb3IgKGkgPSAwOyBpIDwgMzsgaSsrKSB7XG4gICAgcmdiW2ldICo9IDEgLSB3IC0gYjtcbiAgICByZ2JbaV0gKz0gdztcbiAgfVxuICByZXR1cm4gcmdiO1xufVxuZnVuY3Rpb24gaHVlVmFsdWUociwgZywgYiwgZCwgbWF4KSB7XG4gIGlmIChyID09PSBtYXgpIHtcbiAgICByZXR1cm4gKChnIC0gYikgLyBkKSArIChnIDwgYiA/IDYgOiAwKTtcbiAgfVxuICBpZiAoZyA9PT0gbWF4KSB7XG4gICAgcmV0dXJuIChiIC0gcikgLyBkICsgMjtcbiAgfVxuICByZXR1cm4gKHIgLSBnKSAvIGQgKyA0O1xufVxuZnVuY3Rpb24gcmdiMmhzbCh2KSB7XG4gIGNvbnN0IHJhbmdlID0gMjU1O1xuICBjb25zdCByID0gdi5yIC8gcmFuZ2U7XG4gIGNvbnN0IGcgPSB2LmcgLyByYW5nZTtcbiAgY29uc3QgYiA9IHYuYiAvIHJhbmdlO1xuICBjb25zdCBtYXggPSBNYXRoLm1heChyLCBnLCBiKTtcbiAgY29uc3QgbWluID0gTWF0aC5taW4ociwgZywgYik7XG4gIGNvbnN0IGwgPSAobWF4ICsgbWluKSAvIDI7XG4gIGxldCBoLCBzLCBkO1xuICBpZiAobWF4ICE9PSBtaW4pIHtcbiAgICBkID0gbWF4IC0gbWluO1xuICAgIHMgPSBsID4gMC41ID8gZCAvICgyIC0gbWF4IC0gbWluKSA6IGQgLyAobWF4ICsgbWluKTtcbiAgICBoID0gaHVlVmFsdWUociwgZywgYiwgZCwgbWF4KTtcbiAgICBoID0gaCAqIDYwICsgMC41O1xuICB9XG4gIHJldHVybiBbaCB8IDAsIHMgfHwgMCwgbF07XG59XG5mdW5jdGlvbiBjYWxsbihmLCBhLCBiLCBjKSB7XG4gIHJldHVybiAoXG4gICAgQXJyYXkuaXNBcnJheShhKVxuICAgICAgPyBmKGFbMF0sIGFbMV0sIGFbMl0pXG4gICAgICA6IGYoYSwgYiwgYylcbiAgKS5tYXAobjJiKTtcbn1cbmZ1bmN0aW9uIGhzbDJyZ2IoaCwgcywgbCkge1xuICByZXR1cm4gY2FsbG4oaHNsMnJnYm4sIGgsIHMsIGwpO1xufVxuZnVuY3Rpb24gaHdiMnJnYihoLCB3LCBiKSB7XG4gIHJldHVybiBjYWxsbihod2IycmdibiwgaCwgdywgYik7XG59XG5mdW5jdGlvbiBoc3YycmdiKGgsIHMsIHYpIHtcbiAgcmV0dXJuIGNhbGxuKGhzdjJyZ2JuLCBoLCBzLCB2KTtcbn1cbmZ1bmN0aW9uIGh1ZShoKSB7XG4gIHJldHVybiAoaCAlIDM2MCArIDM2MCkgJSAzNjA7XG59XG5mdW5jdGlvbiBodWVQYXJzZShzdHIpIHtcbiAgY29uc3QgbSA9IEhVRV9SRS5leGVjKHN0cik7XG4gIGxldCBhID0gMjU1O1xuICBsZXQgdjtcbiAgaWYgKCFtKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmIChtWzVdICE9PSB2KSB7XG4gICAgYSA9IG1bNl0gPyBwMmIoK21bNV0pIDogbjJiKCttWzVdKTtcbiAgfVxuICBjb25zdCBoID0gaHVlKCttWzJdKTtcbiAgY29uc3QgcDEgPSArbVszXSAvIDEwMDtcbiAgY29uc3QgcDIgPSArbVs0XSAvIDEwMDtcbiAgaWYgKG1bMV0gPT09ICdod2InKSB7XG4gICAgdiA9IGh3YjJyZ2IoaCwgcDEsIHAyKTtcbiAgfSBlbHNlIGlmIChtWzFdID09PSAnaHN2Jykge1xuICAgIHYgPSBoc3YycmdiKGgsIHAxLCBwMik7XG4gIH0gZWxzZSB7XG4gICAgdiA9IGhzbDJyZ2IoaCwgcDEsIHAyKTtcbiAgfVxuICByZXR1cm4ge1xuICAgIHI6IHZbMF0sXG4gICAgZzogdlsxXSxcbiAgICBiOiB2WzJdLFxuICAgIGE6IGFcbiAgfTtcbn1cbmZ1bmN0aW9uIHJvdGF0ZSh2LCBkZWcpIHtcbiAgdmFyIGggPSByZ2IyaHNsKHYpO1xuICBoWzBdID0gaHVlKGhbMF0gKyBkZWcpO1xuICBoID0gaHNsMnJnYihoKTtcbiAgdi5yID0gaFswXTtcbiAgdi5nID0gaFsxXTtcbiAgdi5iID0gaFsyXTtcbn1cbmZ1bmN0aW9uIGhzbFN0cmluZyh2KSB7XG4gIGlmICghdikge1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCBhID0gcmdiMmhzbCh2KTtcbiAgY29uc3QgaCA9IGFbMF07XG4gIGNvbnN0IHMgPSBuMnAoYVsxXSk7XG4gIGNvbnN0IGwgPSBuMnAoYVsyXSk7XG4gIHJldHVybiB2LmEgPCAyNTVcbiAgICA/IGBoc2xhKCR7aH0sICR7c30lLCAke2x9JSwgJHtiMm4odi5hKX0pYFxuICAgIDogYGhzbCgke2h9LCAke3N9JSwgJHtsfSUpYDtcbn1cblxuY29uc3QgbWFwID0ge1xuICB4OiAnZGFyaycsXG4gIFo6ICdsaWdodCcsXG4gIFk6ICdyZScsXG4gIFg6ICdibHUnLFxuICBXOiAnZ3InLFxuICBWOiAnbWVkaXVtJyxcbiAgVTogJ3NsYXRlJyxcbiAgQTogJ2VlJyxcbiAgVDogJ29sJyxcbiAgUzogJ29yJyxcbiAgQjogJ3JhJyxcbiAgQzogJ2xhdGVnJyxcbiAgRDogJ2lnaHRzJyxcbiAgUjogJ2luJyxcbiAgUTogJ3R1cnF1b2lzJyxcbiAgRTogJ2hpJyxcbiAgUDogJ3JvJyxcbiAgTzogJ2FsJyxcbiAgTjogJ2xlJyxcbiAgTTogJ2RlJyxcbiAgTDogJ3llbGxvJyxcbiAgRjogJ2VuJyxcbiAgSzogJ2NoJyxcbiAgRzogJ2Fya3MnLFxuICBIOiAnZWEnLFxuICBJOiAnaWdodGcnLFxuICBKOiAnd2gnXG59O1xuY29uc3QgbmFtZXMkMSA9IHtcbiAgT2ljZVhlOiAnZjBmOGZmJyxcbiAgYW50aXF1ZXdFdGU6ICdmYWViZDcnLFxuICBhcXVhOiAnZmZmZicsXG4gIGFxdWFtYXJSZTogJzdmZmZkNCcsXG4gIGF6dVk6ICdmMGZmZmYnLFxuICBiZWlnZTogJ2Y1ZjVkYycsXG4gIGJpc3F1ZTogJ2ZmZTRjNCcsXG4gIGJsYWNrOiAnMCcsXG4gIGJsYW5LZWRPbW9uZDogJ2ZmZWJjZCcsXG4gIFhlOiAnZmYnLFxuICBYZXZpVGV0OiAnOGEyYmUyJyxcbiAgYlB3bjogJ2E1MmEyYScsXG4gIGJ1cmx5d29vZDogJ2RlYjg4NycsXG4gIGNhTXRYZTogJzVmOWVhMCcsXG4gIEthcnRZdXNlOiAnN2ZmZjAwJyxcbiAgS29jVGF0ZTogJ2QyNjkxZScsXG4gIGNTTzogJ2ZmN2Y1MCcsXG4gIGNTbmZsb3dlclhlOiAnNjQ5NWVkJyxcbiAgY1Nuc2lsazogJ2ZmZjhkYycsXG4gIGNyaW1zb246ICdkYzE0M2MnLFxuICBjeWFuOiAnZmZmZicsXG4gIHhYZTogJzhiJyxcbiAgeGN5YW46ICc4YjhiJyxcbiAgeGdUTW5QZDogJ2I4ODYwYicsXG4gIHhXYXk6ICdhOWE5YTknLFxuICB4Z1lGOiAnNjQwMCcsXG4gIHhnWXk6ICdhOWE5YTknLFxuICB4a2hha2k6ICdiZGI3NmInLFxuICB4bWFnRnRhOiAnOGIwMDhiJyxcbiAgeFRpdmVnWUY6ICc1NTZiMmYnLFxuICB4U2FuZ2U6ICdmZjhjMDAnLFxuICB4U2NFZDogJzk5MzJjYycsXG4gIHhZZDogJzhiMDAwMCcsXG4gIHhzT21vbjogJ2U5OTY3YScsXG4gIHhzSGdZRjogJzhmYmM4ZicsXG4gIHhVWGU6ICc0ODNkOGInLFxuICB4VVdheTogJzJmNGY0ZicsXG4gIHhVZ1l5OiAnMmY0ZjRmJyxcbiAgeFFlOiAnY2VkMScsXG4gIHh2aVRldDogJzk0MDBkMycsXG4gIGRBcHBSazogJ2ZmMTQ5MycsXG4gIGRBcHNreVhlOiAnYmZmZicsXG4gIGRpbVdheTogJzY5Njk2OScsXG4gIGRpbWdZeTogJzY5Njk2OScsXG4gIGRvZGdlclhlOiAnMWU5MGZmJyxcbiAgZmlZYnJpY2s6ICdiMjIyMjInLFxuICBmbFNPd0V0ZTogJ2ZmZmFmMCcsXG4gIGZvWXN0V0FuOiAnMjI4YjIyJyxcbiAgZnVLc2lhOiAnZmYwMGZmJyxcbiAgZ2FSc2JTbzogJ2RjZGNkYycsXG4gIGdob3N0d0V0ZTogJ2Y4ZjhmZicsXG4gIGdUZDogJ2ZmZDcwMCcsXG4gIGdUTW5QZDogJ2RhYTUyMCcsXG4gIFdheTogJzgwODA4MCcsXG4gIGdZRjogJzgwMDAnLFxuICBnWUZMdzogJ2FkZmYyZicsXG4gIGdZeTogJzgwODA4MCcsXG4gIGhvbmV5TXc6ICdmMGZmZjAnLFxuICBob3RwUms6ICdmZjY5YjQnLFxuICBSZGlhbllkOiAnY2Q1YzVjJyxcbiAgUmRpZ286ICc0YjAwODInLFxuICBpdlN5OiAnZmZmZmYwJyxcbiAga2hha2k6ICdmMGU2OGMnLFxuICBsYXZGTXI6ICdlNmU2ZmEnLFxuICBsYXZGTXJYc2g6ICdmZmYwZjUnLFxuICBsYXduZ1lGOiAnN2NmYzAwJyxcbiAgTm1vbmNFZmZvbjogJ2ZmZmFjZCcsXG4gIFpYZTogJ2FkZDhlNicsXG4gIFpjU086ICdmMDgwODAnLFxuICBaY3lhbjogJ2UwZmZmZicsXG4gIFpnVE1uUGRMdzogJ2ZhZmFkMicsXG4gIFpXYXk6ICdkM2QzZDMnLFxuICBaZ1lGOiAnOTBlZTkwJyxcbiAgWmdZeTogJ2QzZDNkMycsXG4gIFpwUms6ICdmZmI2YzEnLFxuICBac09tb246ICdmZmEwN2EnLFxuICBac0hnWUY6ICcyMGIyYWEnLFxuICBac2t5WGU6ICc4N2NlZmEnLFxuICBaVVdheTogJzc3ODg5OScsXG4gIFpVZ1l5OiAnNzc4ODk5JyxcbiAgWnN0QWxYZTogJ2IwYzRkZScsXG4gIFpMdzogJ2ZmZmZlMCcsXG4gIGxpbWU6ICdmZjAwJyxcbiAgbGltZWdZRjogJzMyY2QzMicsXG4gIGxSRjogJ2ZhZjBlNicsXG4gIG1hZ0Z0YTogJ2ZmMDBmZicsXG4gIG1hUG9uOiAnODAwMDAwJyxcbiAgVmFxdWFtYXJSZTogJzY2Y2RhYScsXG4gIFZYZTogJ2NkJyxcbiAgVlNjRWQ6ICdiYTU1ZDMnLFxuICBWcHVycE46ICc5MzcwZGInLFxuICBWc0hnWUY6ICczY2IzNzEnLFxuICBWVVhlOiAnN2I2OGVlJyxcbiAgVnNwclJnZ1lGOiAnZmE5YScsXG4gIFZRZTogJzQ4ZDFjYycsXG4gIFZ2aVRldFlkOiAnYzcxNTg1JyxcbiAgbWlkbmlnaHRYZTogJzE5MTk3MCcsXG4gIG1SdGNZYW06ICdmNWZmZmEnLFxuICBtaXN0eVBzZTogJ2ZmZTRlMScsXG4gIG1vY2Nhc1I6ICdmZmU0YjUnLFxuICBuYXZham93RXRlOiAnZmZkZWFkJyxcbiAgbmF2eTogJzgwJyxcbiAgVGRsYWNlOiAnZmRmNWU2JyxcbiAgVGl2ZTogJzgwODAwMCcsXG4gIFRpdmVkQmI6ICc2YjhlMjMnLFxuICBTYW5nZTogJ2ZmYTUwMCcsXG4gIFNhbmdlWWQ6ICdmZjQ1MDAnLFxuICBTY0VkOiAnZGE3MGQ2JyxcbiAgcE9lZ1RNblBkOiAnZWVlOGFhJyxcbiAgcE9lZ1lGOiAnOThmYjk4JyxcbiAgcE9lUWU6ICdhZmVlZWUnLFxuICBwT2V2aVRldFlkOiAnZGI3MDkzJyxcbiAgcGFwYXlhd0VwOiAnZmZlZmQ1JyxcbiAgcEhLcHVmZjogJ2ZmZGFiOScsXG4gIHBlcnU6ICdjZDg1M2YnLFxuICBwUms6ICdmZmMwY2InLFxuICBwbHVtOiAnZGRhMGRkJyxcbiAgcG93TXJYZTogJ2IwZTBlNicsXG4gIHB1cnBOOiAnODAwMDgwJyxcbiAgWWJlY2NhcHVycE46ICc2NjMzOTknLFxuICBZZDogJ2ZmMDAwMCcsXG4gIFBzeWJyb3duOiAnYmM4ZjhmJyxcbiAgUHlPWGU6ICc0MTY5ZTEnLFxuICBzYWRkTmJQd246ICc4YjQ1MTMnLFxuICBzT21vbjogJ2ZhODA3MicsXG4gIHNhbmR5YlB3bjogJ2Y0YTQ2MCcsXG4gIHNIZ1lGOiAnMmU4YjU3JyxcbiAgc0hzaGVsbDogJ2ZmZjVlZScsXG4gIHNpRm5hOiAnYTA1MjJkJyxcbiAgc2lsdmVyOiAnYzBjMGMwJyxcbiAgc2t5WGU6ICc4N2NlZWInLFxuICBVWGU6ICc2YTVhY2QnLFxuICBVV2F5OiAnNzA4MDkwJyxcbiAgVWdZeTogJzcwODA5MCcsXG4gIHNub3c6ICdmZmZhZmEnLFxuICBzcHJSZ2dZRjogJ2ZmN2YnLFxuICBzdEFsWGU6ICc0NjgyYjQnLFxuICB0YW46ICdkMmI0OGMnLFxuICB0ZU86ICc4MDgwJyxcbiAgdEVzdE46ICdkOGJmZDgnLFxuICB0b21hdG86ICdmZjYzNDcnLFxuICBRZTogJzQwZTBkMCcsXG4gIHZpVGV0OiAnZWU4MmVlJyxcbiAgSkh0OiAnZjVkZWIzJyxcbiAgd0V0ZTogJ2ZmZmZmZicsXG4gIHdFdGVzbW9rZTogJ2Y1ZjVmNScsXG4gIEx3OiAnZmZmZjAwJyxcbiAgTHdnWUY6ICc5YWNkMzInXG59O1xuZnVuY3Rpb24gdW5wYWNrKCkge1xuICBjb25zdCB1bnBhY2tlZCA9IHt9O1xuICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMobmFtZXMkMSk7XG4gIGNvbnN0IHRrZXlzID0gT2JqZWN0LmtleXMobWFwKTtcbiAgbGV0IGksIGosIGssIG9rLCBuaztcbiAgZm9yIChpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICBvayA9IG5rID0ga2V5c1tpXTtcbiAgICBmb3IgKGogPSAwOyBqIDwgdGtleXMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGsgPSB0a2V5c1tqXTtcbiAgICAgIG5rID0gbmsucmVwbGFjZShrLCBtYXBba10pO1xuICAgIH1cbiAgICBrID0gcGFyc2VJbnQobmFtZXMkMVtva10sIDE2KTtcbiAgICB1bnBhY2tlZFtua10gPSBbayA+PiAxNiAmIDB4RkYsIGsgPj4gOCAmIDB4RkYsIGsgJiAweEZGXTtcbiAgfVxuICByZXR1cm4gdW5wYWNrZWQ7XG59XG5cbmxldCBuYW1lcztcbmZ1bmN0aW9uIG5hbWVQYXJzZShzdHIpIHtcbiAgaWYgKCFuYW1lcykge1xuICAgIG5hbWVzID0gdW5wYWNrKCk7XG4gICAgbmFtZXMudHJhbnNwYXJlbnQgPSBbMCwgMCwgMCwgMF07XG4gIH1cbiAgY29uc3QgYSA9IG5hbWVzW3N0ci50b0xvd2VyQ2FzZSgpXTtcbiAgcmV0dXJuIGEgJiYge1xuICAgIHI6IGFbMF0sXG4gICAgZzogYVsxXSxcbiAgICBiOiBhWzJdLFxuICAgIGE6IGEubGVuZ3RoID09PSA0ID8gYVszXSA6IDI1NVxuICB9O1xufVxuXG5jb25zdCBSR0JfUkUgPSAvXnJnYmE/XFwoXFxzKihbLSsuXFxkXSspKCUpP1tcXHMsXSsoWy0rLmVcXGRdKykoJSk/W1xccyxdKyhbLSsuZVxcZF0rKSglKT8oPzpbXFxzLC9dKyhbLSsuZVxcZF0rKSglKT8pP1xccypcXCkkLztcbmZ1bmN0aW9uIHJnYlBhcnNlKHN0cikge1xuICBjb25zdCBtID0gUkdCX1JFLmV4ZWMoc3RyKTtcbiAgbGV0IGEgPSAyNTU7XG4gIGxldCByLCBnLCBiO1xuICBpZiAoIW0pIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKG1bN10gIT09IHIpIHtcbiAgICBjb25zdCB2ID0gK21bN107XG4gICAgYSA9IG1bOF0gPyBwMmIodikgOiBsaW0odiAqIDI1NSwgMCwgMjU1KTtcbiAgfVxuICByID0gK21bMV07XG4gIGcgPSArbVszXTtcbiAgYiA9ICttWzVdO1xuICByID0gMjU1ICYgKG1bMl0gPyBwMmIocikgOiBsaW0ociwgMCwgMjU1KSk7XG4gIGcgPSAyNTUgJiAobVs0XSA/IHAyYihnKSA6IGxpbShnLCAwLCAyNTUpKTtcbiAgYiA9IDI1NSAmIChtWzZdID8gcDJiKGIpIDogbGltKGIsIDAsIDI1NSkpO1xuICByZXR1cm4ge1xuICAgIHI6IHIsXG4gICAgZzogZyxcbiAgICBiOiBiLFxuICAgIGE6IGFcbiAgfTtcbn1cbmZ1bmN0aW9uIHJnYlN0cmluZyh2KSB7XG4gIHJldHVybiB2ICYmIChcbiAgICB2LmEgPCAyNTVcbiAgICAgID8gYHJnYmEoJHt2LnJ9LCAke3YuZ30sICR7di5ifSwgJHtiMm4odi5hKX0pYFxuICAgICAgOiBgcmdiKCR7di5yfSwgJHt2Lmd9LCAke3YuYn0pYFxuICApO1xufVxuXG5jb25zdCB0byA9IHYgPT4gdiA8PSAwLjAwMzEzMDggPyB2ICogMTIuOTIgOiBNYXRoLnBvdyh2LCAxLjAgLyAyLjQpICogMS4wNTUgLSAwLjA1NTtcbmNvbnN0IGZyb20gPSB2ID0+IHYgPD0gMC4wNDA0NSA/IHYgLyAxMi45MiA6IE1hdGgucG93KCh2ICsgMC4wNTUpIC8gMS4wNTUsIDIuNCk7XG5mdW5jdGlvbiBpbnRlcnBvbGF0ZShyZ2IxLCByZ2IyLCB0KSB7XG4gIGNvbnN0IHIgPSBmcm9tKGIybihyZ2IxLnIpKTtcbiAgY29uc3QgZyA9IGZyb20oYjJuKHJnYjEuZykpO1xuICBjb25zdCBiID0gZnJvbShiMm4ocmdiMS5iKSk7XG4gIHJldHVybiB7XG4gICAgcjogbjJiKHRvKHIgKyB0ICogKGZyb20oYjJuKHJnYjIucikpIC0gcikpKSxcbiAgICBnOiBuMmIodG8oZyArIHQgKiAoZnJvbShiMm4ocmdiMi5nKSkgLSBnKSkpLFxuICAgIGI6IG4yYih0byhiICsgdCAqIChmcm9tKGIybihyZ2IyLmIpKSAtIGIpKSksXG4gICAgYTogcmdiMS5hICsgdCAqIChyZ2IyLmEgLSByZ2IxLmEpXG4gIH07XG59XG5cbmZ1bmN0aW9uIG1vZEhTTCh2LCBpLCByYXRpbykge1xuICBpZiAodikge1xuICAgIGxldCB0bXAgPSByZ2IyaHNsKHYpO1xuICAgIHRtcFtpXSA9IE1hdGgubWF4KDAsIE1hdGgubWluKHRtcFtpXSArIHRtcFtpXSAqIHJhdGlvLCBpID09PSAwID8gMzYwIDogMSkpO1xuICAgIHRtcCA9IGhzbDJyZ2IodG1wKTtcbiAgICB2LnIgPSB0bXBbMF07XG4gICAgdi5nID0gdG1wWzFdO1xuICAgIHYuYiA9IHRtcFsyXTtcbiAgfVxufVxuZnVuY3Rpb24gY2xvbmUodiwgcHJvdG8pIHtcbiAgcmV0dXJuIHYgPyBPYmplY3QuYXNzaWduKHByb3RvIHx8IHt9LCB2KSA6IHY7XG59XG5mdW5jdGlvbiBmcm9tT2JqZWN0KGlucHV0KSB7XG4gIHZhciB2ID0ge3I6IDAsIGc6IDAsIGI6IDAsIGE6IDI1NX07XG4gIGlmIChBcnJheS5pc0FycmF5KGlucHV0KSkge1xuICAgIGlmIChpbnB1dC5sZW5ndGggPj0gMykge1xuICAgICAgdiA9IHtyOiBpbnB1dFswXSwgZzogaW5wdXRbMV0sIGI6IGlucHV0WzJdLCBhOiAyNTV9O1xuICAgICAgaWYgKGlucHV0Lmxlbmd0aCA+IDMpIHtcbiAgICAgICAgdi5hID0gbjJiKGlucHV0WzNdKTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdiA9IGNsb25lKGlucHV0LCB7cjogMCwgZzogMCwgYjogMCwgYTogMX0pO1xuICAgIHYuYSA9IG4yYih2LmEpO1xuICB9XG4gIHJldHVybiB2O1xufVxuZnVuY3Rpb24gZnVuY3Rpb25QYXJzZShzdHIpIHtcbiAgaWYgKHN0ci5jaGFyQXQoMCkgPT09ICdyJykge1xuICAgIHJldHVybiByZ2JQYXJzZShzdHIpO1xuICB9XG4gIHJldHVybiBodWVQYXJzZShzdHIpO1xufVxuY2xhc3MgQ29sb3Ige1xuICBjb25zdHJ1Y3RvcihpbnB1dCkge1xuICAgIGlmIChpbnB1dCBpbnN0YW5jZW9mIENvbG9yKSB7XG4gICAgICByZXR1cm4gaW5wdXQ7XG4gICAgfVxuICAgIGNvbnN0IHR5cGUgPSB0eXBlb2YgaW5wdXQ7XG4gICAgbGV0IHY7XG4gICAgaWYgKHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICB2ID0gZnJvbU9iamVjdChpbnB1dCk7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgdiA9IGhleFBhcnNlKGlucHV0KSB8fCBuYW1lUGFyc2UoaW5wdXQpIHx8IGZ1bmN0aW9uUGFyc2UoaW5wdXQpO1xuICAgIH1cbiAgICB0aGlzLl9yZ2IgPSB2O1xuICAgIHRoaXMuX3ZhbGlkID0gISF2O1xuICB9XG4gIGdldCB2YWxpZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsaWQ7XG4gIH1cbiAgZ2V0IHJnYigpIHtcbiAgICB2YXIgdiA9IGNsb25lKHRoaXMuX3JnYik7XG4gICAgaWYgKHYpIHtcbiAgICAgIHYuYSA9IGIybih2LmEpO1xuICAgIH1cbiAgICByZXR1cm4gdjtcbiAgfVxuICBzZXQgcmdiKG9iaikge1xuICAgIHRoaXMuX3JnYiA9IGZyb21PYmplY3Qob2JqKTtcbiAgfVxuICByZ2JTdHJpbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbGlkID8gcmdiU3RyaW5nKHRoaXMuX3JnYikgOiB1bmRlZmluZWQ7XG4gIH1cbiAgaGV4U3RyaW5nKCkge1xuICAgIHJldHVybiB0aGlzLl92YWxpZCA/IGhleFN0cmluZyh0aGlzLl9yZ2IpIDogdW5kZWZpbmVkO1xuICB9XG4gIGhzbFN0cmluZygpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsaWQgPyBoc2xTdHJpbmcodGhpcy5fcmdiKSA6IHVuZGVmaW5lZDtcbiAgfVxuICBtaXgoY29sb3IsIHdlaWdodCkge1xuICAgIGlmIChjb2xvcikge1xuICAgICAgY29uc3QgYzEgPSB0aGlzLnJnYjtcbiAgICAgIGNvbnN0IGMyID0gY29sb3IucmdiO1xuICAgICAgbGV0IHcyO1xuICAgICAgY29uc3QgcCA9IHdlaWdodCA9PT0gdzIgPyAwLjUgOiB3ZWlnaHQ7XG4gICAgICBjb25zdCB3ID0gMiAqIHAgLSAxO1xuICAgICAgY29uc3QgYSA9IGMxLmEgLSBjMi5hO1xuICAgICAgY29uc3QgdzEgPSAoKHcgKiBhID09PSAtMSA/IHcgOiAodyArIGEpIC8gKDEgKyB3ICogYSkpICsgMSkgLyAyLjA7XG4gICAgICB3MiA9IDEgLSB3MTtcbiAgICAgIGMxLnIgPSAweEZGICYgdzEgKiBjMS5yICsgdzIgKiBjMi5yICsgMC41O1xuICAgICAgYzEuZyA9IDB4RkYgJiB3MSAqIGMxLmcgKyB3MiAqIGMyLmcgKyAwLjU7XG4gICAgICBjMS5iID0gMHhGRiAmIHcxICogYzEuYiArIHcyICogYzIuYiArIDAuNTtcbiAgICAgIGMxLmEgPSBwICogYzEuYSArICgxIC0gcCkgKiBjMi5hO1xuICAgICAgdGhpcy5yZ2IgPSBjMTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgaW50ZXJwb2xhdGUoY29sb3IsIHQpIHtcbiAgICBpZiAoY29sb3IpIHtcbiAgICAgIHRoaXMuX3JnYiA9IGludGVycG9sYXRlKHRoaXMuX3JnYiwgY29sb3IuX3JnYiwgdCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIGNsb25lKCkge1xuICAgIHJldHVybiBuZXcgQ29sb3IodGhpcy5yZ2IpO1xuICB9XG4gIGFscGhhKGEpIHtcbiAgICB0aGlzLl9yZ2IuYSA9IG4yYihhKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICBjbGVhcmVyKHJhdGlvKSB7XG4gICAgY29uc3QgcmdiID0gdGhpcy5fcmdiO1xuICAgIHJnYi5hICo9IDEgLSByYXRpbztcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICBncmV5c2NhbGUoKSB7XG4gICAgY29uc3QgcmdiID0gdGhpcy5fcmdiO1xuICAgIGNvbnN0IHZhbCA9IHJvdW5kKHJnYi5yICogMC4zICsgcmdiLmcgKiAwLjU5ICsgcmdiLmIgKiAwLjExKTtcbiAgICByZ2IuciA9IHJnYi5nID0gcmdiLmIgPSB2YWw7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgb3BhcXVlcihyYXRpbykge1xuICAgIGNvbnN0IHJnYiA9IHRoaXMuX3JnYjtcbiAgICByZ2IuYSAqPSAxICsgcmF0aW87XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgbmVnYXRlKCkge1xuICAgIGNvbnN0IHYgPSB0aGlzLl9yZ2I7XG4gICAgdi5yID0gMjU1IC0gdi5yO1xuICAgIHYuZyA9IDI1NSAtIHYuZztcbiAgICB2LmIgPSAyNTUgLSB2LmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgbGlnaHRlbihyYXRpbykge1xuICAgIG1vZEhTTCh0aGlzLl9yZ2IsIDIsIHJhdGlvKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICBkYXJrZW4ocmF0aW8pIHtcbiAgICBtb2RIU0wodGhpcy5fcmdiLCAyLCAtcmF0aW8pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIHNhdHVyYXRlKHJhdGlvKSB7XG4gICAgbW9kSFNMKHRoaXMuX3JnYiwgMSwgcmF0aW8pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIGRlc2F0dXJhdGUocmF0aW8pIHtcbiAgICBtb2RIU0wodGhpcy5fcmdiLCAxLCAtcmF0aW8pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIHJvdGF0ZShkZWcpIHtcbiAgICByb3RhdGUodGhpcy5fcmdiLCBkZWcpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG59XG5cbmZ1bmN0aW9uIGluZGV4X2VzbShpbnB1dCkge1xuICByZXR1cm4gbmV3IENvbG9yKGlucHV0KTtcbn1cblxuZXhwb3J0IHsgQ29sb3IsIGIybiwgYjJwLCBpbmRleF9lc20gYXMgZGVmYXVsdCwgaGV4UGFyc2UsIGhleFN0cmluZywgaHNsMnJnYiwgaHNsU3RyaW5nLCBoc3YycmdiLCBodWVQYXJzZSwgaHdiMnJnYiwgbGltLCBuMmIsIG4ycCwgbmFtZVBhcnNlLCBwMmIsIHJnYjJoc2wsIHJnYlBhcnNlLCByZ2JTdHJpbmcsIHJvdGF0ZSwgcm91bmQgfTtcbiIsIi8qIVxuICogQ2hhcnQuanMgdjQuNC40XG4gKiBodHRwczovL3d3dy5jaGFydGpzLm9yZ1xuICogKGMpIDIwMjQgQ2hhcnQuanMgQ29udHJpYnV0b3JzXG4gKiBSZWxlYXNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2VcbiAqL1xuaW1wb3J0IHsgQ29sb3IgfSBmcm9tICdAa3Vya2xlL2NvbG9yJztcblxuLyoqXG4gKiBAbmFtZXNwYWNlIENoYXJ0LmhlbHBlcnNcbiAqLyAvKipcbiAqIEFuIGVtcHR5IGZ1bmN0aW9uIHRoYXQgY2FuIGJlIHVzZWQsIGZvciBleGFtcGxlLCBmb3Igb3B0aW9uYWwgY2FsbGJhY2suXG4gKi8gZnVuY3Rpb24gbm9vcCgpIHtcbi8qIG5vb3AgKi8gfVxuLyoqXG4gKiBSZXR1cm5zIGEgdW5pcXVlIGlkLCBzZXF1ZW50aWFsbHkgZ2VuZXJhdGVkIGZyb20gYSBnbG9iYWwgdmFyaWFibGUuXG4gKi8gY29uc3QgdWlkID0gKCgpPT57XG4gICAgbGV0IGlkID0gMDtcbiAgICByZXR1cm4gKCk9PmlkKys7XG59KSgpO1xuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgYHZhbHVlYCBpcyBuZWl0aGVyIG51bGwgbm9yIHVuZGVmaW5lZCwgZWxzZSByZXR1cm5zIGZhbHNlLlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRvIHRlc3QuXG4gKiBAc2luY2UgMi43LjBcbiAqLyBmdW5jdGlvbiBpc051bGxPclVuZGVmKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSBudWxsIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ3VuZGVmaW5lZCc7XG59XG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiBgdmFsdWVgIGlzIGFuIGFycmF5IChpbmNsdWRpbmcgdHlwZWQgYXJyYXlzKSwgZWxzZSByZXR1cm5zIGZhbHNlLlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRvIHRlc3QuXG4gKiBAZnVuY3Rpb25cbiAqLyBmdW5jdGlvbiBpc0FycmF5KHZhbHVlKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkgJiYgQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGNvbnN0IHR5cGUgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpO1xuICAgIGlmICh0eXBlLnNsaWNlKDAsIDcpID09PSAnW29iamVjdCcgJiYgdHlwZS5zbGljZSgtNikgPT09ICdBcnJheV0nKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiBgdmFsdWVgIGlzIGFuIG9iamVjdCAoZXhjbHVkaW5nIG51bGwpLCBlbHNlIHJldHVybnMgZmFsc2UuXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gdGVzdC5cbiAqIEBzaW5jZSAyLjcuMFxuICovIGZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlICE9PSBudWxsICYmIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT09ICdbb2JqZWN0IE9iamVjdF0nO1xufVxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgYHZhbHVlYCBpcyBhIGZpbml0ZSBudW1iZXIsIGVsc2UgcmV0dXJucyBmYWxzZVxuICogQHBhcmFtIHZhbHVlICAtIFRoZSB2YWx1ZSB0byB0ZXN0LlxuICovIGZ1bmN0aW9uIGlzTnVtYmVyRmluaXRlKHZhbHVlKSB7XG4gICAgcmV0dXJuICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInIHx8IHZhbHVlIGluc3RhbmNlb2YgTnVtYmVyKSAmJiBpc0Zpbml0ZSgrdmFsdWUpO1xufVxuLyoqXG4gKiBSZXR1cm5zIGB2YWx1ZWAgaWYgZmluaXRlLCBlbHNlIHJldHVybnMgYGRlZmF1bHRWYWx1ZWAuXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gcmV0dXJuIGlmIGRlZmluZWQuXG4gKiBAcGFyYW0gZGVmYXVsdFZhbHVlIC0gVGhlIHZhbHVlIHRvIHJldHVybiBpZiBgdmFsdWVgIGlzIG5vdCBmaW5pdGUuXG4gKi8gZnVuY3Rpb24gZmluaXRlT3JEZWZhdWx0KHZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcbiAgICByZXR1cm4gaXNOdW1iZXJGaW5pdGUodmFsdWUpID8gdmFsdWUgOiBkZWZhdWx0VmFsdWU7XG59XG4vKipcbiAqIFJldHVybnMgYHZhbHVlYCBpZiBkZWZpbmVkLCBlbHNlIHJldHVybnMgYGRlZmF1bHRWYWx1ZWAuXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gcmV0dXJuIGlmIGRlZmluZWQuXG4gKiBAcGFyYW0gZGVmYXVsdFZhbHVlIC0gVGhlIHZhbHVlIHRvIHJldHVybiBpZiBgdmFsdWVgIGlzIHVuZGVmaW5lZC5cbiAqLyBmdW5jdGlvbiB2YWx1ZU9yRGVmYXVsdCh2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ3VuZGVmaW5lZCcgPyBkZWZhdWx0VmFsdWUgOiB2YWx1ZTtcbn1cbmNvbnN0IHRvUGVyY2VudGFnZSA9ICh2YWx1ZSwgZGltZW5zaW9uKT0+dHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiB2YWx1ZS5lbmRzV2l0aCgnJScpID8gcGFyc2VGbG9hdCh2YWx1ZSkgLyAxMDAgOiArdmFsdWUgLyBkaW1lbnNpb247XG5jb25zdCB0b0RpbWVuc2lvbiA9ICh2YWx1ZSwgZGltZW5zaW9uKT0+dHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiB2YWx1ZS5lbmRzV2l0aCgnJScpID8gcGFyc2VGbG9hdCh2YWx1ZSkgLyAxMDAgKiBkaW1lbnNpb24gOiArdmFsdWU7XG4vKipcbiAqIENhbGxzIGBmbmAgd2l0aCB0aGUgZ2l2ZW4gYGFyZ3NgIGluIHRoZSBzY29wZSBkZWZpbmVkIGJ5IGB0aGlzQXJnYCBhbmQgcmV0dXJucyB0aGVcbiAqIHZhbHVlIHJldHVybmVkIGJ5IGBmbmAuIElmIGBmbmAgaXMgbm90IGEgZnVuY3Rpb24sIHRoaXMgbWV0aG9kIHJldHVybnMgdW5kZWZpbmVkLlxuICogQHBhcmFtIGZuIC0gVGhlIGZ1bmN0aW9uIHRvIGNhbGwuXG4gKiBAcGFyYW0gYXJncyAtIFRoZSBhcmd1bWVudHMgd2l0aCB3aGljaCBgZm5gIHNob3VsZCBiZSBjYWxsZWQuXG4gKiBAcGFyYW0gW3RoaXNBcmddIC0gVGhlIHZhbHVlIG9mIGB0aGlzYCBwcm92aWRlZCBmb3IgdGhlIGNhbGwgdG8gYGZuYC5cbiAqLyBmdW5jdGlvbiBjYWxsYmFjayhmbiwgYXJncywgdGhpc0FyZykge1xuICAgIGlmIChmbiAmJiB0eXBlb2YgZm4uY2FsbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gZm4uYXBwbHkodGhpc0FyZywgYXJncyk7XG4gICAgfVxufVxuZnVuY3Rpb24gZWFjaChsb29wYWJsZSwgZm4sIHRoaXNBcmcsIHJldmVyc2UpIHtcbiAgICBsZXQgaSwgbGVuLCBrZXlzO1xuICAgIGlmIChpc0FycmF5KGxvb3BhYmxlKSkge1xuICAgICAgICBsZW4gPSBsb29wYWJsZS5sZW5ndGg7XG4gICAgICAgIGlmIChyZXZlcnNlKSB7XG4gICAgICAgICAgICBmb3IoaSA9IGxlbiAtIDE7IGkgPj0gMDsgaS0tKXtcbiAgICAgICAgICAgICAgICBmbi5jYWxsKHRoaXNBcmcsIGxvb3BhYmxlW2ldLCBpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZvcihpID0gMDsgaSA8IGxlbjsgaSsrKXtcbiAgICAgICAgICAgICAgICBmbi5jYWxsKHRoaXNBcmcsIGxvb3BhYmxlW2ldLCBpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaXNPYmplY3QobG9vcGFibGUpKSB7XG4gICAgICAgIGtleXMgPSBPYmplY3Qua2V5cyhsb29wYWJsZSk7XG4gICAgICAgIGxlbiA9IGtleXMubGVuZ3RoO1xuICAgICAgICBmb3IoaSA9IDA7IGkgPCBsZW47IGkrKyl7XG4gICAgICAgICAgICBmbi5jYWxsKHRoaXNBcmcsIGxvb3BhYmxlW2tleXNbaV1dLCBrZXlzW2ldKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBgYTBgIGFuZCBgYTFgIGFycmF5cyBoYXZlIHRoZSBzYW1lIGNvbnRlbnQsIGVsc2UgcmV0dXJucyBmYWxzZS5cbiAqIEBwYXJhbSBhMCAtIFRoZSBhcnJheSB0byBjb21wYXJlXG4gKiBAcGFyYW0gYTEgLSBUaGUgYXJyYXkgdG8gY29tcGFyZVxuICogQHByaXZhdGVcbiAqLyBmdW5jdGlvbiBfZWxlbWVudHNFcXVhbChhMCwgYTEpIHtcbiAgICBsZXQgaSwgaWxlbiwgdjAsIHYxO1xuICAgIGlmICghYTAgfHwgIWExIHx8IGEwLmxlbmd0aCAhPT0gYTEubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZm9yKGkgPSAwLCBpbGVuID0gYTAubGVuZ3RoOyBpIDwgaWxlbjsgKytpKXtcbiAgICAgICAgdjAgPSBhMFtpXTtcbiAgICAgICAgdjEgPSBhMVtpXTtcbiAgICAgICAgaWYgKHYwLmRhdGFzZXRJbmRleCAhPT0gdjEuZGF0YXNldEluZGV4IHx8IHYwLmluZGV4ICE9PSB2MS5pbmRleCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuLyoqXG4gKiBSZXR1cm5zIGEgZGVlcCBjb3B5IG9mIGBzb3VyY2VgIHdpdGhvdXQga2VlcGluZyByZWZlcmVuY2VzIG9uIG9iamVjdHMgYW5kIGFycmF5cy5cbiAqIEBwYXJhbSBzb3VyY2UgLSBUaGUgdmFsdWUgdG8gY2xvbmUuXG4gKi8gZnVuY3Rpb24gY2xvbmUoc291cmNlKSB7XG4gICAgaWYgKGlzQXJyYXkoc291cmNlKSkge1xuICAgICAgICByZXR1cm4gc291cmNlLm1hcChjbG9uZSk7XG4gICAgfVxuICAgIGlmIChpc09iamVjdChzb3VyY2UpKSB7XG4gICAgICAgIGNvbnN0IHRhcmdldCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhzb3VyY2UpO1xuICAgICAgICBjb25zdCBrbGVuID0ga2V5cy5sZW5ndGg7XG4gICAgICAgIGxldCBrID0gMDtcbiAgICAgICAgZm9yKDsgayA8IGtsZW47ICsrayl7XG4gICAgICAgICAgICB0YXJnZXRba2V5c1trXV0gPSBjbG9uZShzb3VyY2Vba2V5c1trXV0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfVxuICAgIHJldHVybiBzb3VyY2U7XG59XG5mdW5jdGlvbiBpc1ZhbGlkS2V5KGtleSkge1xuICAgIHJldHVybiBbXG4gICAgICAgICdfX3Byb3RvX18nLFxuICAgICAgICAncHJvdG90eXBlJyxcbiAgICAgICAgJ2NvbnN0cnVjdG9yJ1xuICAgIF0uaW5kZXhPZihrZXkpID09PSAtMTtcbn1cbi8qKlxuICogVGhlIGRlZmF1bHQgbWVyZ2VyIHdoZW4gQ2hhcnQuaGVscGVycy5tZXJnZSBpcyBjYWxsZWQgd2l0aG91dCBtZXJnZXIgb3B0aW9uLlxuICogTm90ZShTQik6IGFsc28gdXNlZCBieSBtZXJnZUNvbmZpZyBhbmQgbWVyZ2VTY2FsZUNvbmZpZyBhcyBmYWxsYmFjay5cbiAqIEBwcml2YXRlXG4gKi8gZnVuY3Rpb24gX21lcmdlcihrZXksIHRhcmdldCwgc291cmNlLCBvcHRpb25zKSB7XG4gICAgaWYgKCFpc1ZhbGlkS2V5KGtleSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCB0dmFsID0gdGFyZ2V0W2tleV07XG4gICAgY29uc3Qgc3ZhbCA9IHNvdXJjZVtrZXldO1xuICAgIGlmIChpc09iamVjdCh0dmFsKSAmJiBpc09iamVjdChzdmFsKSkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVzZS1iZWZvcmUtZGVmaW5lXG4gICAgICAgIG1lcmdlKHR2YWwsIHN2YWwsIG9wdGlvbnMpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRhcmdldFtrZXldID0gY2xvbmUoc3ZhbCk7XG4gICAgfVxufVxuZnVuY3Rpb24gbWVyZ2UodGFyZ2V0LCBzb3VyY2UsIG9wdGlvbnMpIHtcbiAgICBjb25zdCBzb3VyY2VzID0gaXNBcnJheShzb3VyY2UpID8gc291cmNlIDogW1xuICAgICAgICBzb3VyY2VcbiAgICBdO1xuICAgIGNvbnN0IGlsZW4gPSBzb3VyY2VzLmxlbmd0aDtcbiAgICBpZiAoIWlzT2JqZWN0KHRhcmdldCkpIHtcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gICAgY29uc3QgbWVyZ2VyID0gb3B0aW9ucy5tZXJnZXIgfHwgX21lcmdlcjtcbiAgICBsZXQgY3VycmVudDtcbiAgICBmb3IobGV0IGkgPSAwOyBpIDwgaWxlbjsgKytpKXtcbiAgICAgICAgY3VycmVudCA9IHNvdXJjZXNbaV07XG4gICAgICAgIGlmICghaXNPYmplY3QoY3VycmVudCkpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhjdXJyZW50KTtcbiAgICAgICAgZm9yKGxldCBrID0gMCwga2xlbiA9IGtleXMubGVuZ3RoOyBrIDwga2xlbjsgKytrKXtcbiAgICAgICAgICAgIG1lcmdlcihrZXlzW2tdLCB0YXJnZXQsIGN1cnJlbnQsIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0YXJnZXQ7XG59XG5mdW5jdGlvbiBtZXJnZUlmKHRhcmdldCwgc291cmNlKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11c2UtYmVmb3JlLWRlZmluZVxuICAgIHJldHVybiBtZXJnZSh0YXJnZXQsIHNvdXJjZSwge1xuICAgICAgICBtZXJnZXI6IF9tZXJnZXJJZlxuICAgIH0pO1xufVxuLyoqXG4gKiBNZXJnZXMgc291cmNlW2tleV0gaW4gdGFyZ2V0W2tleV0gb25seSBpZiB0YXJnZXRba2V5XSBpcyB1bmRlZmluZWQuXG4gKiBAcHJpdmF0ZVxuICovIGZ1bmN0aW9uIF9tZXJnZXJJZihrZXksIHRhcmdldCwgc291cmNlKSB7XG4gICAgaWYgKCFpc1ZhbGlkS2V5KGtleSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCB0dmFsID0gdGFyZ2V0W2tleV07XG4gICAgY29uc3Qgc3ZhbCA9IHNvdXJjZVtrZXldO1xuICAgIGlmIChpc09iamVjdCh0dmFsKSAmJiBpc09iamVjdChzdmFsKSkge1xuICAgICAgICBtZXJnZUlmKHR2YWwsIHN2YWwpO1xuICAgIH0gZWxzZSBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0YXJnZXQsIGtleSkpIHtcbiAgICAgICAgdGFyZ2V0W2tleV0gPSBjbG9uZShzdmFsKTtcbiAgICB9XG59XG4vKipcbiAqIEBwcml2YXRlXG4gKi8gZnVuY3Rpb24gX2RlcHJlY2F0ZWQoc2NvcGUsIHZhbHVlLCBwcmV2aW91cywgY3VycmVudCkge1xuICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihzY29wZSArICc6IFwiJyArIHByZXZpb3VzICsgJ1wiIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSB1c2UgXCInICsgY3VycmVudCArICdcIiBpbnN0ZWFkJyk7XG4gICAgfVxufVxuLy8gcmVzb2x2ZU9iamVjdEtleSByZXNvbHZlciBjYWNoZVxuY29uc3Qga2V5UmVzb2x2ZXJzID0ge1xuICAgIC8vIENoYXJ0LmhlbHBlcnMuY29yZSByZXNvbHZlT2JqZWN0S2V5IHNob3VsZCByZXNvbHZlIGVtcHR5IGtleSB0byByb290IG9iamVjdFxuICAgICcnOiAodik9PnYsXG4gICAgLy8gZGVmYXVsdCByZXNvbHZlcnNcbiAgICB4OiAobyk9Pm8ueCxcbiAgICB5OiAobyk9Pm8ueVxufTtcbi8qKlxuICogQHByaXZhdGVcbiAqLyBmdW5jdGlvbiBfc3BsaXRLZXkoa2V5KSB7XG4gICAgY29uc3QgcGFydHMgPSBrZXkuc3BsaXQoJy4nKTtcbiAgICBjb25zdCBrZXlzID0gW107XG4gICAgbGV0IHRtcCA9ICcnO1xuICAgIGZvciAoY29uc3QgcGFydCBvZiBwYXJ0cyl7XG4gICAgICAgIHRtcCArPSBwYXJ0O1xuICAgICAgICBpZiAodG1wLmVuZHNXaXRoKCdcXFxcJykpIHtcbiAgICAgICAgICAgIHRtcCA9IHRtcC5zbGljZSgwLCAtMSkgKyAnLic7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBrZXlzLnB1c2godG1wKTtcbiAgICAgICAgICAgIHRtcCA9ICcnO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBrZXlzO1xufVxuZnVuY3Rpb24gX2dldEtleVJlc29sdmVyKGtleSkge1xuICAgIGNvbnN0IGtleXMgPSBfc3BsaXRLZXkoa2V5KTtcbiAgICByZXR1cm4gKG9iaik9PntcbiAgICAgICAgZm9yIChjb25zdCBrIG9mIGtleXMpe1xuICAgICAgICAgICAgaWYgKGsgPT09ICcnKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBvYmogPSBvYmogJiYgb2JqW2tdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgfTtcbn1cbmZ1bmN0aW9uIHJlc29sdmVPYmplY3RLZXkob2JqLCBrZXkpIHtcbiAgICBjb25zdCByZXNvbHZlciA9IGtleVJlc29sdmVyc1trZXldIHx8IChrZXlSZXNvbHZlcnNba2V5XSA9IF9nZXRLZXlSZXNvbHZlcihrZXkpKTtcbiAgICByZXR1cm4gcmVzb2x2ZXIob2JqKTtcbn1cbi8qKlxuICogQHByaXZhdGVcbiAqLyBmdW5jdGlvbiBfY2FwaXRhbGl6ZShzdHIpIHtcbiAgICByZXR1cm4gc3RyLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3RyLnNsaWNlKDEpO1xufVxuY29uc3QgZGVmaW5lZCA9ICh2YWx1ZSk9PnR5cGVvZiB2YWx1ZSAhPT0gJ3VuZGVmaW5lZCc7XG5jb25zdCBpc0Z1bmN0aW9uID0gKHZhbHVlKT0+dHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nO1xuLy8gQWRhcHRlZCBmcm9tIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzMxMTI4ODU1L2NvbXBhcmluZy1lY21hNi1zZXRzLWZvci1lcXVhbGl0eSMzMTEyOTM4NFxuY29uc3Qgc2V0c0VxdWFsID0gKGEsIGIpPT57XG4gICAgaWYgKGEuc2l6ZSAhPT0gYi5zaXplKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBpdGVtIG9mIGEpe1xuICAgICAgICBpZiAoIWIuaGFzKGl0ZW0pKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59O1xuLyoqXG4gKiBAcGFyYW0gZSAtIFRoZSBldmVudFxuICogQHByaXZhdGVcbiAqLyBmdW5jdGlvbiBfaXNDbGlja0V2ZW50KGUpIHtcbiAgICByZXR1cm4gZS50eXBlID09PSAnbW91c2V1cCcgfHwgZS50eXBlID09PSAnY2xpY2snIHx8IGUudHlwZSA9PT0gJ2NvbnRleHRtZW51Jztcbn1cblxuLyoqXG4gKiBAYWxpYXMgQ2hhcnQuaGVscGVycy5tYXRoXG4gKiBAbmFtZXNwYWNlXG4gKi8gY29uc3QgUEkgPSBNYXRoLlBJO1xuY29uc3QgVEFVID0gMiAqIFBJO1xuY29uc3QgUElUQVUgPSBUQVUgKyBQSTtcbmNvbnN0IElORklOSVRZID0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO1xuY29uc3QgUkFEX1BFUl9ERUcgPSBQSSAvIDE4MDtcbmNvbnN0IEhBTEZfUEkgPSBQSSAvIDI7XG5jb25zdCBRVUFSVEVSX1BJID0gUEkgLyA0O1xuY29uc3QgVFdPX1RISVJEU19QSSA9IFBJICogMiAvIDM7XG5jb25zdCBsb2cxMCA9IE1hdGgubG9nMTA7XG5jb25zdCBzaWduID0gTWF0aC5zaWduO1xuZnVuY3Rpb24gYWxtb3N0RXF1YWxzKHgsIHksIGVwc2lsb24pIHtcbiAgICByZXR1cm4gTWF0aC5hYnMoeCAtIHkpIDwgZXBzaWxvbjtcbn1cbi8qKlxuICogSW1wbGVtZW50YXRpb24gb2YgdGhlIG5pY2UgbnVtYmVyIGFsZ29yaXRobSB1c2VkIGluIGRldGVybWluaW5nIHdoZXJlIGF4aXMgbGFiZWxzIHdpbGwgZ29cbiAqLyBmdW5jdGlvbiBuaWNlTnVtKHJhbmdlKSB7XG4gICAgY29uc3Qgcm91bmRlZFJhbmdlID0gTWF0aC5yb3VuZChyYW5nZSk7XG4gICAgcmFuZ2UgPSBhbG1vc3RFcXVhbHMocmFuZ2UsIHJvdW5kZWRSYW5nZSwgcmFuZ2UgLyAxMDAwKSA/IHJvdW5kZWRSYW5nZSA6IHJhbmdlO1xuICAgIGNvbnN0IG5pY2VSYW5nZSA9IE1hdGgucG93KDEwLCBNYXRoLmZsb29yKGxvZzEwKHJhbmdlKSkpO1xuICAgIGNvbnN0IGZyYWN0aW9uID0gcmFuZ2UgLyBuaWNlUmFuZ2U7XG4gICAgY29uc3QgbmljZUZyYWN0aW9uID0gZnJhY3Rpb24gPD0gMSA/IDEgOiBmcmFjdGlvbiA8PSAyID8gMiA6IGZyYWN0aW9uIDw9IDUgPyA1IDogMTA7XG4gICAgcmV0dXJuIG5pY2VGcmFjdGlvbiAqIG5pY2VSYW5nZTtcbn1cbi8qKlxuICogUmV0dXJucyBhbiBhcnJheSBvZiBmYWN0b3JzIHNvcnRlZCBmcm9tIDEgdG8gc3FydCh2YWx1ZSlcbiAqIEBwcml2YXRlXG4gKi8gZnVuY3Rpb24gX2ZhY3Rvcml6ZSh2YWx1ZSkge1xuICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuICAgIGNvbnN0IHNxcnQgPSBNYXRoLnNxcnQodmFsdWUpO1xuICAgIGxldCBpO1xuICAgIGZvcihpID0gMTsgaSA8IHNxcnQ7IGkrKyl7XG4gICAgICAgIGlmICh2YWx1ZSAlIGkgPT09IDApIHtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKGkpO1xuICAgICAgICAgICAgcmVzdWx0LnB1c2godmFsdWUgLyBpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoc3FydCA9PT0gKHNxcnQgfCAwKSkge1xuICAgICAgICByZXN1bHQucHVzaChzcXJ0KTtcbiAgICB9XG4gICAgcmVzdWx0LnNvcnQoKGEsIGIpPT5hIC0gYikucG9wKCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIGlzTnVtYmVyKG4pIHtcbiAgICByZXR1cm4gIWlzTmFOKHBhcnNlRmxvYXQobikpICYmIGlzRmluaXRlKG4pO1xufVxuZnVuY3Rpb24gYWxtb3N0V2hvbGUoeCwgZXBzaWxvbikge1xuICAgIGNvbnN0IHJvdW5kZWQgPSBNYXRoLnJvdW5kKHgpO1xuICAgIHJldHVybiByb3VuZGVkIC0gZXBzaWxvbiA8PSB4ICYmIHJvdW5kZWQgKyBlcHNpbG9uID49IHg7XG59XG4vKipcbiAqIEBwcml2YXRlXG4gKi8gZnVuY3Rpb24gX3NldE1pbkFuZE1heEJ5S2V5KGFycmF5LCB0YXJnZXQsIHByb3BlcnR5KSB7XG4gICAgbGV0IGksIGlsZW4sIHZhbHVlO1xuICAgIGZvcihpID0gMCwgaWxlbiA9IGFycmF5Lmxlbmd0aDsgaSA8IGlsZW47IGkrKyl7XG4gICAgICAgIHZhbHVlID0gYXJyYXlbaV1bcHJvcGVydHldO1xuICAgICAgICBpZiAoIWlzTmFOKHZhbHVlKSkge1xuICAgICAgICAgICAgdGFyZ2V0Lm1pbiA9IE1hdGgubWluKHRhcmdldC5taW4sIHZhbHVlKTtcbiAgICAgICAgICAgIHRhcmdldC5tYXggPSBNYXRoLm1heCh0YXJnZXQubWF4LCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiB0b1JhZGlhbnMoZGVncmVlcykge1xuICAgIHJldHVybiBkZWdyZWVzICogKFBJIC8gMTgwKTtcbn1cbmZ1bmN0aW9uIHRvRGVncmVlcyhyYWRpYW5zKSB7XG4gICAgcmV0dXJuIHJhZGlhbnMgKiAoMTgwIC8gUEkpO1xufVxuLyoqXG4gKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZGVjaW1hbCBwbGFjZXNcbiAqIGkuZS4gdGhlIG51bWJlciBvZiBkaWdpdHMgYWZ0ZXIgdGhlIGRlY2ltYWwgcG9pbnQsIG9mIHRoZSB2YWx1ZSBvZiB0aGlzIE51bWJlci5cbiAqIEBwYXJhbSB4IC0gQSBudW1iZXIuXG4gKiBAcmV0dXJucyBUaGUgbnVtYmVyIG9mIGRlY2ltYWwgcGxhY2VzLlxuICogQHByaXZhdGVcbiAqLyBmdW5jdGlvbiBfZGVjaW1hbFBsYWNlcyh4KSB7XG4gICAgaWYgKCFpc051bWJlckZpbml0ZSh4KSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCBlID0gMTtcbiAgICBsZXQgcCA9IDA7XG4gICAgd2hpbGUoTWF0aC5yb3VuZCh4ICogZSkgLyBlICE9PSB4KXtcbiAgICAgICAgZSAqPSAxMDtcbiAgICAgICAgcCsrO1xuICAgIH1cbiAgICByZXR1cm4gcDtcbn1cbi8vIEdldHMgdGhlIGFuZ2xlIGZyb20gdmVydGljYWwgdXByaWdodCB0byB0aGUgcG9pbnQgYWJvdXQgYSBjZW50cmUuXG5mdW5jdGlvbiBnZXRBbmdsZUZyb21Qb2ludChjZW50cmVQb2ludCwgYW5nbGVQb2ludCkge1xuICAgIGNvbnN0IGRpc3RhbmNlRnJvbVhDZW50ZXIgPSBhbmdsZVBvaW50LnggLSBjZW50cmVQb2ludC54O1xuICAgIGNvbnN0IGRpc3RhbmNlRnJvbVlDZW50ZXIgPSBhbmdsZVBvaW50LnkgLSBjZW50cmVQb2ludC55O1xuICAgIGNvbnN0IHJhZGlhbERpc3RhbmNlRnJvbUNlbnRlciA9IE1hdGguc3FydChkaXN0YW5jZUZyb21YQ2VudGVyICogZGlzdGFuY2VGcm9tWENlbnRlciArIGRpc3RhbmNlRnJvbVlDZW50ZXIgKiBkaXN0YW5jZUZyb21ZQ2VudGVyKTtcbiAgICBsZXQgYW5nbGUgPSBNYXRoLmF0YW4yKGRpc3RhbmNlRnJvbVlDZW50ZXIsIGRpc3RhbmNlRnJvbVhDZW50ZXIpO1xuICAgIGlmIChhbmdsZSA8IC0wLjUgKiBQSSkge1xuICAgICAgICBhbmdsZSArPSBUQVU7IC8vIG1ha2Ugc3VyZSB0aGUgcmV0dXJuZWQgYW5nbGUgaXMgaW4gdGhlIHJhbmdlIG9mICgtUEkvMiwgM1BJLzJdXG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIGFuZ2xlLFxuICAgICAgICBkaXN0YW5jZTogcmFkaWFsRGlzdGFuY2VGcm9tQ2VudGVyXG4gICAgfTtcbn1cbmZ1bmN0aW9uIGRpc3RhbmNlQmV0d2VlblBvaW50cyhwdDEsIHB0Mikge1xuICAgIHJldHVybiBNYXRoLnNxcnQoTWF0aC5wb3cocHQyLnggLSBwdDEueCwgMikgKyBNYXRoLnBvdyhwdDIueSAtIHB0MS55LCAyKSk7XG59XG4vKipcbiAqIFNob3J0ZXN0IGRpc3RhbmNlIGJldHdlZW4gYW5nbGVzLCBpbiBlaXRoZXIgZGlyZWN0aW9uLlxuICogQHByaXZhdGVcbiAqLyBmdW5jdGlvbiBfYW5nbGVEaWZmKGEsIGIpIHtcbiAgICByZXR1cm4gKGEgLSBiICsgUElUQVUpICUgVEFVIC0gUEk7XG59XG4vKipcbiAqIE5vcm1hbGl6ZSBhbmdsZSB0byBiZSBiZXR3ZWVuIDAgYW5kIDIqUElcbiAqIEBwcml2YXRlXG4gKi8gZnVuY3Rpb24gX25vcm1hbGl6ZUFuZ2xlKGEpIHtcbiAgICByZXR1cm4gKGEgJSBUQVUgKyBUQVUpICUgVEFVO1xufVxuLyoqXG4gKiBAcHJpdmF0ZVxuICovIGZ1bmN0aW9uIF9hbmdsZUJldHdlZW4oYW5nbGUsIHN0YXJ0LCBlbmQsIHNhbWVBbmdsZUlzRnVsbENpcmNsZSkge1xuICAgIGNvbnN0IGEgPSBfbm9ybWFsaXplQW5nbGUoYW5nbGUpO1xuICAgIGNvbnN0IHMgPSBfbm9ybWFsaXplQW5nbGUoc3RhcnQpO1xuICAgIGNvbnN0IGUgPSBfbm9ybWFsaXplQW5nbGUoZW5kKTtcbiAgICBjb25zdCBhbmdsZVRvU3RhcnQgPSBfbm9ybWFsaXplQW5nbGUocyAtIGEpO1xuICAgIGNvbnN0IGFuZ2xlVG9FbmQgPSBfbm9ybWFsaXplQW5nbGUoZSAtIGEpO1xuICAgIGNvbnN0IHN0YXJ0VG9BbmdsZSA9IF9ub3JtYWxpemVBbmdsZShhIC0gcyk7XG4gICAgY29uc3QgZW5kVG9BbmdsZSA9IF9ub3JtYWxpemVBbmdsZShhIC0gZSk7XG4gICAgcmV0dXJuIGEgPT09IHMgfHwgYSA9PT0gZSB8fCBzYW1lQW5nbGVJc0Z1bGxDaXJjbGUgJiYgcyA9PT0gZSB8fCBhbmdsZVRvU3RhcnQgPiBhbmdsZVRvRW5kICYmIHN0YXJ0VG9BbmdsZSA8IGVuZFRvQW5nbGU7XG59XG4vKipcbiAqIExpbWl0IGB2YWx1ZWAgYmV0d2VlbiBgbWluYCBhbmQgYG1heGBcbiAqIEBwYXJhbSB2YWx1ZVxuICogQHBhcmFtIG1pblxuICogQHBhcmFtIG1heFxuICogQHByaXZhdGVcbiAqLyBmdW5jdGlvbiBfbGltaXRWYWx1ZSh2YWx1ZSwgbWluLCBtYXgpIHtcbiAgICByZXR1cm4gTWF0aC5tYXgobWluLCBNYXRoLm1pbihtYXgsIHZhbHVlKSk7XG59XG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxuICogQHByaXZhdGVcbiAqLyBmdW5jdGlvbiBfaW50MTZSYW5nZSh2YWx1ZSkge1xuICAgIHJldHVybiBfbGltaXRWYWx1ZSh2YWx1ZSwgLTMyNzY4LCAzMjc2Nyk7XG59XG4vKipcbiAqIEBwYXJhbSB2YWx1ZVxuICogQHBhcmFtIHN0YXJ0XG4gKiBAcGFyYW0gZW5kXG4gKiBAcGFyYW0gW2Vwc2lsb25dXG4gKiBAcHJpdmF0ZVxuICovIGZ1bmN0aW9uIF9pc0JldHdlZW4odmFsdWUsIHN0YXJ0LCBlbmQsIGVwc2lsb24gPSAxZS02KSB7XG4gICAgcmV0dXJuIHZhbHVlID49IE1hdGgubWluKHN0YXJ0LCBlbmQpIC0gZXBzaWxvbiAmJiB2YWx1ZSA8PSBNYXRoLm1heChzdGFydCwgZW5kKSArIGVwc2lsb247XG59XG5cbmZ1bmN0aW9uIF9sb29rdXAodGFibGUsIHZhbHVlLCBjbXApIHtcbiAgICBjbXAgPSBjbXAgfHwgKChpbmRleCk9PnRhYmxlW2luZGV4XSA8IHZhbHVlKTtcbiAgICBsZXQgaGkgPSB0YWJsZS5sZW5ndGggLSAxO1xuICAgIGxldCBsbyA9IDA7XG4gICAgbGV0IG1pZDtcbiAgICB3aGlsZShoaSAtIGxvID4gMSl7XG4gICAgICAgIG1pZCA9IGxvICsgaGkgPj4gMTtcbiAgICAgICAgaWYgKGNtcChtaWQpKSB7XG4gICAgICAgICAgICBsbyA9IG1pZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGhpID0gbWlkO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIGxvLFxuICAgICAgICBoaVxuICAgIH07XG59XG4vKipcbiAqIEJpbmFyeSBzZWFyY2hcbiAqIEBwYXJhbSB0YWJsZSAtIHRoZSB0YWJsZSBzZWFyY2guIG11c3QgYmUgc29ydGVkIVxuICogQHBhcmFtIGtleSAtIHByb3BlcnR5IG5hbWUgZm9yIHRoZSB2YWx1ZSBpbiBlYWNoIGVudHJ5XG4gKiBAcGFyYW0gdmFsdWUgLSB2YWx1ZSB0byBmaW5kXG4gKiBAcGFyYW0gbGFzdCAtIGxvb2t1cCBsYXN0IGluZGV4XG4gKiBAcHJpdmF0ZVxuICovIGNvbnN0IF9sb29rdXBCeUtleSA9ICh0YWJsZSwga2V5LCB2YWx1ZSwgbGFzdCk9Pl9sb29rdXAodGFibGUsIHZhbHVlLCBsYXN0ID8gKGluZGV4KT0+e1xuICAgICAgICBjb25zdCB0aSA9IHRhYmxlW2luZGV4XVtrZXldO1xuICAgICAgICByZXR1cm4gdGkgPCB2YWx1ZSB8fCB0aSA9PT0gdmFsdWUgJiYgdGFibGVbaW5kZXggKyAxXVtrZXldID09PSB2YWx1ZTtcbiAgICB9IDogKGluZGV4KT0+dGFibGVbaW5kZXhdW2tleV0gPCB2YWx1ZSk7XG4vKipcbiAqIFJldmVyc2UgYmluYXJ5IHNlYXJjaFxuICogQHBhcmFtIHRhYmxlIC0gdGhlIHRhYmxlIHNlYXJjaC4gbXVzdCBiZSBzb3J0ZWQhXG4gKiBAcGFyYW0ga2V5IC0gcHJvcGVydHkgbmFtZSBmb3IgdGhlIHZhbHVlIGluIGVhY2ggZW50cnlcbiAqIEBwYXJhbSB2YWx1ZSAtIHZhbHVlIHRvIGZpbmRcbiAqIEBwcml2YXRlXG4gKi8gY29uc3QgX3Jsb29rdXBCeUtleSA9ICh0YWJsZSwga2V5LCB2YWx1ZSk9Pl9sb29rdXAodGFibGUsIHZhbHVlLCAoaW5kZXgpPT50YWJsZVtpbmRleF1ba2V5XSA+PSB2YWx1ZSk7XG4vKipcbiAqIFJldHVybiBzdWJzZXQgb2YgYHZhbHVlc2AgYmV0d2VlbiBgbWluYCBhbmQgYG1heGAgaW5jbHVzaXZlLlxuICogVmFsdWVzIGFyZSBhc3N1bWVkIHRvIGJlIGluIHNvcnRlZCBvcmRlci5cbiAqIEBwYXJhbSB2YWx1ZXMgLSBzb3J0ZWQgYXJyYXkgb2YgdmFsdWVzXG4gKiBAcGFyYW0gbWluIC0gbWluIHZhbHVlXG4gKiBAcGFyYW0gbWF4IC0gbWF4IHZhbHVlXG4gKi8gZnVuY3Rpb24gX2ZpbHRlckJldHdlZW4odmFsdWVzLCBtaW4sIG1heCkge1xuICAgIGxldCBzdGFydCA9IDA7XG4gICAgbGV0IGVuZCA9IHZhbHVlcy5sZW5ndGg7XG4gICAgd2hpbGUoc3RhcnQgPCBlbmQgJiYgdmFsdWVzW3N0YXJ0XSA8IG1pbil7XG4gICAgICAgIHN0YXJ0Kys7XG4gICAgfVxuICAgIHdoaWxlKGVuZCA+IHN0YXJ0ICYmIHZhbHVlc1tlbmQgLSAxXSA+IG1heCl7XG4gICAgICAgIGVuZC0tO1xuICAgIH1cbiAgICByZXR1cm4gc3RhcnQgPiAwIHx8IGVuZCA8IHZhbHVlcy5sZW5ndGggPyB2YWx1ZXMuc2xpY2Uoc3RhcnQsIGVuZCkgOiB2YWx1ZXM7XG59XG5jb25zdCBhcnJheUV2ZW50cyA9IFtcbiAgICAncHVzaCcsXG4gICAgJ3BvcCcsXG4gICAgJ3NoaWZ0JyxcbiAgICAnc3BsaWNlJyxcbiAgICAndW5zaGlmdCdcbl07XG5mdW5jdGlvbiBsaXN0ZW5BcnJheUV2ZW50cyhhcnJheSwgbGlzdGVuZXIpIHtcbiAgICBpZiAoYXJyYXkuX2NoYXJ0anMpIHtcbiAgICAgICAgYXJyYXkuX2NoYXJ0anMubGlzdGVuZXJzLnB1c2gobGlzdGVuZXIpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhcnJheSwgJ19jaGFydGpzJywge1xuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICB2YWx1ZToge1xuICAgICAgICAgICAgbGlzdGVuZXJzOiBbXG4gICAgICAgICAgICAgICAgbGlzdGVuZXJcbiAgICAgICAgICAgIF1cbiAgICAgICAgfVxuICAgIH0pO1xuICAgIGFycmF5RXZlbnRzLmZvckVhY2goKGtleSk9PntcbiAgICAgICAgY29uc3QgbWV0aG9kID0gJ19vbkRhdGEnICsgX2NhcGl0YWxpemUoa2V5KTtcbiAgICAgICAgY29uc3QgYmFzZSA9IGFycmF5W2tleV07XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhcnJheSwga2V5LCB7XG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIHZhbHVlICguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzID0gYmFzZS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgICAgICBhcnJheS5fY2hhcnRqcy5saXN0ZW5lcnMuZm9yRWFjaCgob2JqZWN0KT0+e1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdFttZXRob2RdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvYmplY3RbbWV0aG9kXSguLi5hcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gdW5saXN0ZW5BcnJheUV2ZW50cyhhcnJheSwgbGlzdGVuZXIpIHtcbiAgICBjb25zdCBzdHViID0gYXJyYXkuX2NoYXJ0anM7XG4gICAgaWYgKCFzdHViKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgbGlzdGVuZXJzID0gc3R1Yi5saXN0ZW5lcnM7XG4gICAgY29uc3QgaW5kZXggPSBsaXN0ZW5lcnMuaW5kZXhPZihsaXN0ZW5lcik7XG4gICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICBsaXN0ZW5lcnMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICB9XG4gICAgaWYgKGxpc3RlbmVycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgYXJyYXlFdmVudHMuZm9yRWFjaCgoa2V5KT0+e1xuICAgICAgICBkZWxldGUgYXJyYXlba2V5XTtcbiAgICB9KTtcbiAgICBkZWxldGUgYXJyYXkuX2NoYXJ0anM7XG59XG4vKipcbiAqIEBwYXJhbSBpdGVtc1xuICovIGZ1bmN0aW9uIF9hcnJheVVuaXF1ZShpdGVtcykge1xuICAgIGNvbnN0IHNldCA9IG5ldyBTZXQoaXRlbXMpO1xuICAgIGlmIChzZXQuc2l6ZSA9PT0gaXRlbXMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBpdGVtcztcbiAgICB9XG4gICAgcmV0dXJuIEFycmF5LmZyb20oc2V0KTtcbn1cblxuZnVuY3Rpb24gZm9udFN0cmluZyhwaXhlbFNpemUsIGZvbnRTdHlsZSwgZm9udEZhbWlseSkge1xuICAgIHJldHVybiBmb250U3R5bGUgKyAnICcgKyBwaXhlbFNpemUgKyAncHggJyArIGZvbnRGYW1pbHk7XG59XG4vKipcbiogUmVxdWVzdCBhbmltYXRpb24gcG9seWZpbGxcbiovIGNvbnN0IHJlcXVlc3RBbmltRnJhbWUgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWU7XG59KCk7XG4vKipcbiAqIFRocm90dGxlcyBjYWxsaW5nIGBmbmAgb25jZSBwZXIgYW5pbWF0aW9uIGZyYW1lXG4gKiBMYXRlc3QgYXJndW1lbnRzIGFyZSB1c2VkIG9uIHRoZSBhY3R1YWwgY2FsbFxuICovIGZ1bmN0aW9uIHRocm90dGxlZChmbiwgdGhpc0FyZykge1xuICAgIGxldCBhcmdzVG9Vc2UgPSBbXTtcbiAgICBsZXQgdGlja2luZyA9IGZhbHNlO1xuICAgIHJldHVybiBmdW5jdGlvbiguLi5hcmdzKSB7XG4gICAgICAgIC8vIFNhdmUgdGhlIGFyZ3MgZm9yIHVzZSBsYXRlclxuICAgICAgICBhcmdzVG9Vc2UgPSBhcmdzO1xuICAgICAgICBpZiAoIXRpY2tpbmcpIHtcbiAgICAgICAgICAgIHRpY2tpbmcgPSB0cnVlO1xuICAgICAgICAgICAgcmVxdWVzdEFuaW1GcmFtZS5jYWxsKHdpbmRvdywgKCk9PntcbiAgICAgICAgICAgICAgICB0aWNraW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgZm4uYXBwbHkodGhpc0FyZywgYXJnc1RvVXNlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcbn1cbi8qKlxuICogRGVib3VuY2VzIGNhbGxpbmcgYGZuYCBmb3IgYGRlbGF5YCBtc1xuICovIGZ1bmN0aW9uIGRlYm91bmNlKGZuLCBkZWxheSkge1xuICAgIGxldCB0aW1lb3V0O1xuICAgIHJldHVybiBmdW5jdGlvbiguLi5hcmdzKSB7XG4gICAgICAgIGlmIChkZWxheSkge1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgICAgICAgdGltZW91dCA9IHNldFRpbWVvdXQoZm4sIGRlbGF5LCBhcmdzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZuLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkZWxheTtcbiAgICB9O1xufVxuLyoqXG4gKiBDb252ZXJ0cyAnc3RhcnQnIHRvICdsZWZ0JywgJ2VuZCcgdG8gJ3JpZ2h0JyBhbmQgb3RoZXJzIHRvICdjZW50ZXInXG4gKiBAcHJpdmF0ZVxuICovIGNvbnN0IF90b0xlZnRSaWdodENlbnRlciA9IChhbGlnbik9PmFsaWduID09PSAnc3RhcnQnID8gJ2xlZnQnIDogYWxpZ24gPT09ICdlbmQnID8gJ3JpZ2h0JyA6ICdjZW50ZXInO1xuLyoqXG4gKiBSZXR1cm5zIGBzdGFydGAsIGBlbmRgIG9yIGAoc3RhcnQgKyBlbmQpIC8gMmAgZGVwZW5kaW5nIG9uIGBhbGlnbmAuIERlZmF1bHRzIHRvIGBjZW50ZXJgXG4gKiBAcHJpdmF0ZVxuICovIGNvbnN0IF9hbGlnblN0YXJ0RW5kID0gKGFsaWduLCBzdGFydCwgZW5kKT0+YWxpZ24gPT09ICdzdGFydCcgPyBzdGFydCA6IGFsaWduID09PSAnZW5kJyA/IGVuZCA6IChzdGFydCArIGVuZCkgLyAyO1xuLyoqXG4gKiBSZXR1cm5zIGBsZWZ0YCwgYHJpZ2h0YCBvciBgKGxlZnQgKyByaWdodCkgLyAyYCBkZXBlbmRpbmcgb24gYGFsaWduYC4gRGVmYXVsdHMgdG8gYGxlZnRgXG4gKiBAcHJpdmF0ZVxuICovIGNvbnN0IF90ZXh0WCA9IChhbGlnbiwgbGVmdCwgcmlnaHQsIHJ0bCk9PntcbiAgICBjb25zdCBjaGVjayA9IHJ0bCA/ICdsZWZ0JyA6ICdyaWdodCc7XG4gICAgcmV0dXJuIGFsaWduID09PSBjaGVjayA/IHJpZ2h0IDogYWxpZ24gPT09ICdjZW50ZXInID8gKGxlZnQgKyByaWdodCkgLyAyIDogbGVmdDtcbn07XG4vKipcbiAqIFJldHVybiBzdGFydCBhbmQgY291bnQgb2YgdmlzaWJsZSBwb2ludHMuXG4gKiBAcHJpdmF0ZVxuICovIGZ1bmN0aW9uIF9nZXRTdGFydEFuZENvdW50T2ZWaXNpYmxlUG9pbnRzKG1ldGEsIHBvaW50cywgYW5pbWF0aW9uc0Rpc2FibGVkKSB7XG4gICAgY29uc3QgcG9pbnRDb3VudCA9IHBvaW50cy5sZW5ndGg7XG4gICAgbGV0IHN0YXJ0ID0gMDtcbiAgICBsZXQgY291bnQgPSBwb2ludENvdW50O1xuICAgIGlmIChtZXRhLl9zb3J0ZWQpIHtcbiAgICAgICAgY29uc3QgeyBpU2NhbGUgLCBfcGFyc2VkICB9ID0gbWV0YTtcbiAgICAgICAgY29uc3QgYXhpcyA9IGlTY2FsZS5heGlzO1xuICAgICAgICBjb25zdCB7IG1pbiAsIG1heCAsIG1pbkRlZmluZWQgLCBtYXhEZWZpbmVkICB9ID0gaVNjYWxlLmdldFVzZXJCb3VuZHMoKTtcbiAgICAgICAgaWYgKG1pbkRlZmluZWQpIHtcbiAgICAgICAgICAgIHN0YXJ0ID0gX2xpbWl0VmFsdWUoTWF0aC5taW4oLy8gQHRzLWV4cGVjdC1lcnJvciBOZWVkIHRvIHR5cGUgX3BhcnNlZFxuICAgICAgICAgICAgX2xvb2t1cEJ5S2V5KF9wYXJzZWQsIGF4aXMsIG1pbikubG8sIC8vIEB0cy1leHBlY3QtZXJyb3IgTmVlZCB0byBmaXggdHlwZXMgb24gX2xvb2t1cEJ5S2V5XG4gICAgICAgICAgICBhbmltYXRpb25zRGlzYWJsZWQgPyBwb2ludENvdW50IDogX2xvb2t1cEJ5S2V5KHBvaW50cywgYXhpcywgaVNjYWxlLmdldFBpeGVsRm9yVmFsdWUobWluKSkubG8pLCAwLCBwb2ludENvdW50IC0gMSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1heERlZmluZWQpIHtcbiAgICAgICAgICAgIGNvdW50ID0gX2xpbWl0VmFsdWUoTWF0aC5tYXgoLy8gQHRzLWV4cGVjdC1lcnJvciBOZWVkIHRvIHR5cGUgX3BhcnNlZFxuICAgICAgICAgICAgX2xvb2t1cEJ5S2V5KF9wYXJzZWQsIGlTY2FsZS5heGlzLCBtYXgsIHRydWUpLmhpICsgMSwgLy8gQHRzLWV4cGVjdC1lcnJvciBOZWVkIHRvIGZpeCB0eXBlcyBvbiBfbG9va3VwQnlLZXlcbiAgICAgICAgICAgIGFuaW1hdGlvbnNEaXNhYmxlZCA/IDAgOiBfbG9va3VwQnlLZXkocG9pbnRzLCBheGlzLCBpU2NhbGUuZ2V0UGl4ZWxGb3JWYWx1ZShtYXgpLCB0cnVlKS5oaSArIDEpLCBzdGFydCwgcG9pbnRDb3VudCkgLSBzdGFydDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvdW50ID0gcG9pbnRDb3VudCAtIHN0YXJ0O1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHN0YXJ0LFxuICAgICAgICBjb3VudFxuICAgIH07XG59XG4vKipcbiAqIENoZWNrcyBpZiB0aGUgc2NhbGUgcmFuZ2VzIGhhdmUgY2hhbmdlZC5cbiAqIEBwYXJhbSB7b2JqZWN0fSBtZXRhIC0gZGF0YXNldCBtZXRhLlxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKiBAcHJpdmF0ZVxuICovIGZ1bmN0aW9uIF9zY2FsZVJhbmdlc0NoYW5nZWQobWV0YSkge1xuICAgIGNvbnN0IHsgeFNjYWxlICwgeVNjYWxlICwgX3NjYWxlUmFuZ2VzICB9ID0gbWV0YTtcbiAgICBjb25zdCBuZXdSYW5nZXMgPSB7XG4gICAgICAgIHhtaW46IHhTY2FsZS5taW4sXG4gICAgICAgIHhtYXg6IHhTY2FsZS5tYXgsXG4gICAgICAgIHltaW46IHlTY2FsZS5taW4sXG4gICAgICAgIHltYXg6IHlTY2FsZS5tYXhcbiAgICB9O1xuICAgIGlmICghX3NjYWxlUmFuZ2VzKSB7XG4gICAgICAgIG1ldGEuX3NjYWxlUmFuZ2VzID0gbmV3UmFuZ2VzO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgY2hhbmdlZCA9IF9zY2FsZVJhbmdlcy54bWluICE9PSB4U2NhbGUubWluIHx8IF9zY2FsZVJhbmdlcy54bWF4ICE9PSB4U2NhbGUubWF4IHx8IF9zY2FsZVJhbmdlcy55bWluICE9PSB5U2NhbGUubWluIHx8IF9zY2FsZVJhbmdlcy55bWF4ICE9PSB5U2NhbGUubWF4O1xuICAgIE9iamVjdC5hc3NpZ24oX3NjYWxlUmFuZ2VzLCBuZXdSYW5nZXMpO1xuICAgIHJldHVybiBjaGFuZ2VkO1xufVxuXG5jb25zdCBhdEVkZ2UgPSAodCk9PnQgPT09IDAgfHwgdCA9PT0gMTtcbmNvbnN0IGVsYXN0aWNJbiA9ICh0LCBzLCBwKT0+LShNYXRoLnBvdygyLCAxMCAqICh0IC09IDEpKSAqIE1hdGguc2luKCh0IC0gcykgKiBUQVUgLyBwKSk7XG5jb25zdCBlbGFzdGljT3V0ID0gKHQsIHMsIHApPT5NYXRoLnBvdygyLCAtMTAgKiB0KSAqIE1hdGguc2luKCh0IC0gcykgKiBUQVUgLyBwKSArIDE7XG4vKipcbiAqIEVhc2luZyBmdW5jdGlvbnMgYWRhcHRlZCBmcm9tIFJvYmVydCBQZW5uZXIncyBlYXNpbmcgZXF1YXRpb25zLlxuICogQG5hbWVzcGFjZSBDaGFydC5oZWxwZXJzLmVhc2luZy5lZmZlY3RzXG4gKiBAc2VlIGh0dHA6Ly93d3cucm9iZXJ0cGVubmVyLmNvbS9lYXNpbmcvXG4gKi8gY29uc3QgZWZmZWN0cyA9IHtcbiAgICBsaW5lYXI6ICh0KT0+dCxcbiAgICBlYXNlSW5RdWFkOiAodCk9PnQgKiB0LFxuICAgIGVhc2VPdXRRdWFkOiAodCk9Pi10ICogKHQgLSAyKSxcbiAgICBlYXNlSW5PdXRRdWFkOiAodCk9Pih0IC89IDAuNSkgPCAxID8gMC41ICogdCAqIHQgOiAtMC41ICogKC0tdCAqICh0IC0gMikgLSAxKSxcbiAgICBlYXNlSW5DdWJpYzogKHQpPT50ICogdCAqIHQsXG4gICAgZWFzZU91dEN1YmljOiAodCk9Pih0IC09IDEpICogdCAqIHQgKyAxLFxuICAgIGVhc2VJbk91dEN1YmljOiAodCk9Pih0IC89IDAuNSkgPCAxID8gMC41ICogdCAqIHQgKiB0IDogMC41ICogKCh0IC09IDIpICogdCAqIHQgKyAyKSxcbiAgICBlYXNlSW5RdWFydDogKHQpPT50ICogdCAqIHQgKiB0LFxuICAgIGVhc2VPdXRRdWFydDogKHQpPT4tKCh0IC09IDEpICogdCAqIHQgKiB0IC0gMSksXG4gICAgZWFzZUluT3V0UXVhcnQ6ICh0KT0+KHQgLz0gMC41KSA8IDEgPyAwLjUgKiB0ICogdCAqIHQgKiB0IDogLTAuNSAqICgodCAtPSAyKSAqIHQgKiB0ICogdCAtIDIpLFxuICAgIGVhc2VJblF1aW50OiAodCk9PnQgKiB0ICogdCAqIHQgKiB0LFxuICAgIGVhc2VPdXRRdWludDogKHQpPT4odCAtPSAxKSAqIHQgKiB0ICogdCAqIHQgKyAxLFxuICAgIGVhc2VJbk91dFF1aW50OiAodCk9Pih0IC89IDAuNSkgPCAxID8gMC41ICogdCAqIHQgKiB0ICogdCAqIHQgOiAwLjUgKiAoKHQgLT0gMikgKiB0ICogdCAqIHQgKiB0ICsgMiksXG4gICAgZWFzZUluU2luZTogKHQpPT4tTWF0aC5jb3ModCAqIEhBTEZfUEkpICsgMSxcbiAgICBlYXNlT3V0U2luZTogKHQpPT5NYXRoLnNpbih0ICogSEFMRl9QSSksXG4gICAgZWFzZUluT3V0U2luZTogKHQpPT4tMC41ICogKE1hdGguY29zKFBJICogdCkgLSAxKSxcbiAgICBlYXNlSW5FeHBvOiAodCk9PnQgPT09IDAgPyAwIDogTWF0aC5wb3coMiwgMTAgKiAodCAtIDEpKSxcbiAgICBlYXNlT3V0RXhwbzogKHQpPT50ID09PSAxID8gMSA6IC1NYXRoLnBvdygyLCAtMTAgKiB0KSArIDEsXG4gICAgZWFzZUluT3V0RXhwbzogKHQpPT5hdEVkZ2UodCkgPyB0IDogdCA8IDAuNSA/IDAuNSAqIE1hdGgucG93KDIsIDEwICogKHQgKiAyIC0gMSkpIDogMC41ICogKC1NYXRoLnBvdygyLCAtMTAgKiAodCAqIDIgLSAxKSkgKyAyKSxcbiAgICBlYXNlSW5DaXJjOiAodCk9PnQgPj0gMSA/IHQgOiAtKE1hdGguc3FydCgxIC0gdCAqIHQpIC0gMSksXG4gICAgZWFzZU91dENpcmM6ICh0KT0+TWF0aC5zcXJ0KDEgLSAodCAtPSAxKSAqIHQpLFxuICAgIGVhc2VJbk91dENpcmM6ICh0KT0+KHQgLz0gMC41KSA8IDEgPyAtMC41ICogKE1hdGguc3FydCgxIC0gdCAqIHQpIC0gMSkgOiAwLjUgKiAoTWF0aC5zcXJ0KDEgLSAodCAtPSAyKSAqIHQpICsgMSksXG4gICAgZWFzZUluRWxhc3RpYzogKHQpPT5hdEVkZ2UodCkgPyB0IDogZWxhc3RpY0luKHQsIDAuMDc1LCAwLjMpLFxuICAgIGVhc2VPdXRFbGFzdGljOiAodCk9PmF0RWRnZSh0KSA/IHQgOiBlbGFzdGljT3V0KHQsIDAuMDc1LCAwLjMpLFxuICAgIGVhc2VJbk91dEVsYXN0aWMgKHQpIHtcbiAgICAgICAgY29uc3QgcyA9IDAuMTEyNTtcbiAgICAgICAgY29uc3QgcCA9IDAuNDU7XG4gICAgICAgIHJldHVybiBhdEVkZ2UodCkgPyB0IDogdCA8IDAuNSA/IDAuNSAqIGVsYXN0aWNJbih0ICogMiwgcywgcCkgOiAwLjUgKyAwLjUgKiBlbGFzdGljT3V0KHQgKiAyIC0gMSwgcywgcCk7XG4gICAgfSxcbiAgICBlYXNlSW5CYWNrICh0KSB7XG4gICAgICAgIGNvbnN0IHMgPSAxLjcwMTU4O1xuICAgICAgICByZXR1cm4gdCAqIHQgKiAoKHMgKyAxKSAqIHQgLSBzKTtcbiAgICB9LFxuICAgIGVhc2VPdXRCYWNrICh0KSB7XG4gICAgICAgIGNvbnN0IHMgPSAxLjcwMTU4O1xuICAgICAgICByZXR1cm4gKHQgLT0gMSkgKiB0ICogKChzICsgMSkgKiB0ICsgcykgKyAxO1xuICAgIH0sXG4gICAgZWFzZUluT3V0QmFjayAodCkge1xuICAgICAgICBsZXQgcyA9IDEuNzAxNTg7XG4gICAgICAgIGlmICgodCAvPSAwLjUpIDwgMSkge1xuICAgICAgICAgICAgcmV0dXJuIDAuNSAqICh0ICogdCAqICgoKHMgKj0gMS41MjUpICsgMSkgKiB0IC0gcykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAwLjUgKiAoKHQgLT0gMikgKiB0ICogKCgocyAqPSAxLjUyNSkgKyAxKSAqIHQgKyBzKSArIDIpO1xuICAgIH0sXG4gICAgZWFzZUluQm91bmNlOiAodCk9PjEgLSBlZmZlY3RzLmVhc2VPdXRCb3VuY2UoMSAtIHQpLFxuICAgIGVhc2VPdXRCb3VuY2UgKHQpIHtcbiAgICAgICAgY29uc3QgbSA9IDcuNTYyNTtcbiAgICAgICAgY29uc3QgZCA9IDIuNzU7XG4gICAgICAgIGlmICh0IDwgMSAvIGQpIHtcbiAgICAgICAgICAgIHJldHVybiBtICogdCAqIHQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHQgPCAyIC8gZCkge1xuICAgICAgICAgICAgcmV0dXJuIG0gKiAodCAtPSAxLjUgLyBkKSAqIHQgKyAwLjc1O1xuICAgICAgICB9XG4gICAgICAgIGlmICh0IDwgMi41IC8gZCkge1xuICAgICAgICAgICAgcmV0dXJuIG0gKiAodCAtPSAyLjI1IC8gZCkgKiB0ICsgMC45Mzc1O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtICogKHQgLT0gMi42MjUgLyBkKSAqIHQgKyAwLjk4NDM3NTtcbiAgICB9LFxuICAgIGVhc2VJbk91dEJvdW5jZTogKHQpPT50IDwgMC41ID8gZWZmZWN0cy5lYXNlSW5Cb3VuY2UodCAqIDIpICogMC41IDogZWZmZWN0cy5lYXNlT3V0Qm91bmNlKHQgKiAyIC0gMSkgKiAwLjUgKyAwLjVcbn07XG5cbmZ1bmN0aW9uIGlzUGF0dGVybk9yR3JhZGllbnQodmFsdWUpIHtcbiAgICBpZiAodmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgICBjb25zdCB0eXBlID0gdmFsdWUudG9TdHJpbmcoKTtcbiAgICAgICAgcmV0dXJuIHR5cGUgPT09ICdbb2JqZWN0IENhbnZhc1BhdHRlcm5dJyB8fCB0eXBlID09PSAnW29iamVjdCBDYW52YXNHcmFkaWVudF0nO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBjb2xvcih2YWx1ZSkge1xuICAgIHJldHVybiBpc1BhdHRlcm5PckdyYWRpZW50KHZhbHVlKSA/IHZhbHVlIDogbmV3IENvbG9yKHZhbHVlKTtcbn1cbmZ1bmN0aW9uIGdldEhvdmVyQ29sb3IodmFsdWUpIHtcbiAgICByZXR1cm4gaXNQYXR0ZXJuT3JHcmFkaWVudCh2YWx1ZSkgPyB2YWx1ZSA6IG5ldyBDb2xvcih2YWx1ZSkuc2F0dXJhdGUoMC41KS5kYXJrZW4oMC4xKS5oZXhTdHJpbmcoKTtcbn1cblxuY29uc3QgbnVtYmVycyA9IFtcbiAgICAneCcsXG4gICAgJ3knLFxuICAgICdib3JkZXJXaWR0aCcsXG4gICAgJ3JhZGl1cycsXG4gICAgJ3RlbnNpb24nXG5dO1xuY29uc3QgY29sb3JzID0gW1xuICAgICdjb2xvcicsXG4gICAgJ2JvcmRlckNvbG9yJyxcbiAgICAnYmFja2dyb3VuZENvbG9yJ1xuXTtcbmZ1bmN0aW9uIGFwcGx5QW5pbWF0aW9uc0RlZmF1bHRzKGRlZmF1bHRzKSB7XG4gICAgZGVmYXVsdHMuc2V0KCdhbmltYXRpb24nLCB7XG4gICAgICAgIGRlbGF5OiB1bmRlZmluZWQsXG4gICAgICAgIGR1cmF0aW9uOiAxMDAwLFxuICAgICAgICBlYXNpbmc6ICdlYXNlT3V0UXVhcnQnLFxuICAgICAgICBmbjogdW5kZWZpbmVkLFxuICAgICAgICBmcm9tOiB1bmRlZmluZWQsXG4gICAgICAgIGxvb3A6IHVuZGVmaW5lZCxcbiAgICAgICAgdG86IHVuZGVmaW5lZCxcbiAgICAgICAgdHlwZTogdW5kZWZpbmVkXG4gICAgfSk7XG4gICAgZGVmYXVsdHMuZGVzY3JpYmUoJ2FuaW1hdGlvbicsIHtcbiAgICAgICAgX2ZhbGxiYWNrOiBmYWxzZSxcbiAgICAgICAgX2luZGV4YWJsZTogZmFsc2UsXG4gICAgICAgIF9zY3JpcHRhYmxlOiAobmFtZSk9Pm5hbWUgIT09ICdvblByb2dyZXNzJyAmJiBuYW1lICE9PSAnb25Db21wbGV0ZScgJiYgbmFtZSAhPT0gJ2ZuJ1xuICAgIH0pO1xuICAgIGRlZmF1bHRzLnNldCgnYW5pbWF0aW9ucycsIHtcbiAgICAgICAgY29sb3JzOiB7XG4gICAgICAgICAgICB0eXBlOiAnY29sb3InLFxuICAgICAgICAgICAgcHJvcGVydGllczogY29sb3JzXG4gICAgICAgIH0sXG4gICAgICAgIG51bWJlcnM6IHtcbiAgICAgICAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgICAgICAgcHJvcGVydGllczogbnVtYmVyc1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgZGVmYXVsdHMuZGVzY3JpYmUoJ2FuaW1hdGlvbnMnLCB7XG4gICAgICAgIF9mYWxsYmFjazogJ2FuaW1hdGlvbidcbiAgICB9KTtcbiAgICBkZWZhdWx0cy5zZXQoJ3RyYW5zaXRpb25zJywge1xuICAgICAgICBhY3RpdmU6IHtcbiAgICAgICAgICAgIGFuaW1hdGlvbjoge1xuICAgICAgICAgICAgICAgIGR1cmF0aW9uOiA0MDBcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgcmVzaXplOiB7XG4gICAgICAgICAgICBhbmltYXRpb246IHtcbiAgICAgICAgICAgICAgICBkdXJhdGlvbjogMFxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBzaG93OiB7XG4gICAgICAgICAgICBhbmltYXRpb25zOiB7XG4gICAgICAgICAgICAgICAgY29sb3JzOiB7XG4gICAgICAgICAgICAgICAgICAgIGZyb206ICd0cmFuc3BhcmVudCdcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHZpc2libGU6IHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbjogMFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgaGlkZToge1xuICAgICAgICAgICAgYW5pbWF0aW9uczoge1xuICAgICAgICAgICAgICAgIGNvbG9yczoge1xuICAgICAgICAgICAgICAgICAgICB0bzogJ3RyYW5zcGFyZW50J1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdmlzaWJsZToge1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICAgICAgICAgICAgICAgIGVhc2luZzogJ2xpbmVhcicsXG4gICAgICAgICAgICAgICAgICAgIGZuOiAodik9PnYgfCAwXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIGFwcGx5TGF5b3V0c0RlZmF1bHRzKGRlZmF1bHRzKSB7XG4gICAgZGVmYXVsdHMuc2V0KCdsYXlvdXQnLCB7XG4gICAgICAgIGF1dG9QYWRkaW5nOiB0cnVlLFxuICAgICAgICBwYWRkaW5nOiB7XG4gICAgICAgICAgICB0b3A6IDAsXG4gICAgICAgICAgICByaWdodDogMCxcbiAgICAgICAgICAgIGJvdHRvbTogMCxcbiAgICAgICAgICAgIGxlZnQ6IDBcbiAgICAgICAgfVxuICAgIH0pO1xufVxuXG5jb25zdCBpbnRsQ2FjaGUgPSBuZXcgTWFwKCk7XG5mdW5jdGlvbiBnZXROdW1iZXJGb3JtYXQobG9jYWxlLCBvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gICAgY29uc3QgY2FjaGVLZXkgPSBsb2NhbGUgKyBKU09OLnN0cmluZ2lmeShvcHRpb25zKTtcbiAgICBsZXQgZm9ybWF0dGVyID0gaW50bENhY2hlLmdldChjYWNoZUtleSk7XG4gICAgaWYgKCFmb3JtYXR0ZXIpIHtcbiAgICAgICAgZm9ybWF0dGVyID0gbmV3IEludGwuTnVtYmVyRm9ybWF0KGxvY2FsZSwgb3B0aW9ucyk7XG4gICAgICAgIGludGxDYWNoZS5zZXQoY2FjaGVLZXksIGZvcm1hdHRlcik7XG4gICAgfVxuICAgIHJldHVybiBmb3JtYXR0ZXI7XG59XG5mdW5jdGlvbiBmb3JtYXROdW1iZXIobnVtLCBsb2NhbGUsIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gZ2V0TnVtYmVyRm9ybWF0KGxvY2FsZSwgb3B0aW9ucykuZm9ybWF0KG51bSk7XG59XG5cbmNvbnN0IGZvcm1hdHRlcnMgPSB7XG4gdmFsdWVzICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gaXNBcnJheSh2YWx1ZSkgPyAgdmFsdWUgOiAnJyArIHZhbHVlO1xuICAgIH0sXG4gbnVtZXJpYyAodGlja1ZhbHVlLCBpbmRleCwgdGlja3MpIHtcbiAgICAgICAgaWYgKHRpY2tWYWx1ZSA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuICcwJztcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBsb2NhbGUgPSB0aGlzLmNoYXJ0Lm9wdGlvbnMubG9jYWxlO1xuICAgICAgICBsZXQgbm90YXRpb247XG4gICAgICAgIGxldCBkZWx0YSA9IHRpY2tWYWx1ZTtcbiAgICAgICAgaWYgKHRpY2tzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IG1heFRpY2sgPSBNYXRoLm1heChNYXRoLmFicyh0aWNrc1swXS52YWx1ZSksIE1hdGguYWJzKHRpY2tzW3RpY2tzLmxlbmd0aCAtIDFdLnZhbHVlKSk7XG4gICAgICAgICAgICBpZiAobWF4VGljayA8IDFlLTQgfHwgbWF4VGljayA+IDFlKzE1KSB7XG4gICAgICAgICAgICAgICAgbm90YXRpb24gPSAnc2NpZW50aWZpYyc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWx0YSA9IGNhbGN1bGF0ZURlbHRhKHRpY2tWYWx1ZSwgdGlja3MpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGxvZ0RlbHRhID0gbG9nMTAoTWF0aC5hYnMoZGVsdGEpKTtcbiAgICAgICAgY29uc3QgbnVtRGVjaW1hbCA9IGlzTmFOKGxvZ0RlbHRhKSA/IDEgOiBNYXRoLm1heChNYXRoLm1pbigtMSAqIE1hdGguZmxvb3IobG9nRGVsdGEpLCAyMCksIDApO1xuICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgbm90YXRpb24sXG4gICAgICAgICAgICBtaW5pbXVtRnJhY3Rpb25EaWdpdHM6IG51bURlY2ltYWwsXG4gICAgICAgICAgICBtYXhpbXVtRnJhY3Rpb25EaWdpdHM6IG51bURlY2ltYWxcbiAgICAgICAgfTtcbiAgICAgICAgT2JqZWN0LmFzc2lnbihvcHRpb25zLCB0aGlzLm9wdGlvbnMudGlja3MuZm9ybWF0KTtcbiAgICAgICAgcmV0dXJuIGZvcm1hdE51bWJlcih0aWNrVmFsdWUsIGxvY2FsZSwgb3B0aW9ucyk7XG4gICAgfSxcbiBsb2dhcml0aG1pYyAodGlja1ZhbHVlLCBpbmRleCwgdGlja3MpIHtcbiAgICAgICAgaWYgKHRpY2tWYWx1ZSA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuICcwJztcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByZW1haW4gPSB0aWNrc1tpbmRleF0uc2lnbmlmaWNhbmQgfHwgdGlja1ZhbHVlIC8gTWF0aC5wb3coMTAsIE1hdGguZmxvb3IobG9nMTAodGlja1ZhbHVlKSkpO1xuICAgICAgICBpZiAoW1xuICAgICAgICAgICAgMSxcbiAgICAgICAgICAgIDIsXG4gICAgICAgICAgICAzLFxuICAgICAgICAgICAgNSxcbiAgICAgICAgICAgIDEwLFxuICAgICAgICAgICAgMTVcbiAgICAgICAgXS5pbmNsdWRlcyhyZW1haW4pIHx8IGluZGV4ID4gMC44ICogdGlja3MubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gZm9ybWF0dGVycy5udW1lcmljLmNhbGwodGhpcywgdGlja1ZhbHVlLCBpbmRleCwgdGlja3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAnJztcbiAgICB9XG59O1xuZnVuY3Rpb24gY2FsY3VsYXRlRGVsdGEodGlja1ZhbHVlLCB0aWNrcykge1xuICAgIGxldCBkZWx0YSA9IHRpY2tzLmxlbmd0aCA+IDMgPyB0aWNrc1syXS52YWx1ZSAtIHRpY2tzWzFdLnZhbHVlIDogdGlja3NbMV0udmFsdWUgLSB0aWNrc1swXS52YWx1ZTtcbiAgICBpZiAoTWF0aC5hYnMoZGVsdGEpID49IDEgJiYgdGlja1ZhbHVlICE9PSBNYXRoLmZsb29yKHRpY2tWYWx1ZSkpIHtcbiAgICAgICAgZGVsdGEgPSB0aWNrVmFsdWUgLSBNYXRoLmZsb29yKHRpY2tWYWx1ZSk7XG4gICAgfVxuICAgIHJldHVybiBkZWx0YTtcbn1cbiB2YXIgVGlja3MgPSB7XG4gICAgZm9ybWF0dGVyc1xufTtcblxuZnVuY3Rpb24gYXBwbHlTY2FsZURlZmF1bHRzKGRlZmF1bHRzKSB7XG4gICAgZGVmYXVsdHMuc2V0KCdzY2FsZScsIHtcbiAgICAgICAgZGlzcGxheTogdHJ1ZSxcbiAgICAgICAgb2Zmc2V0OiBmYWxzZSxcbiAgICAgICAgcmV2ZXJzZTogZmFsc2UsXG4gICAgICAgIGJlZ2luQXRaZXJvOiBmYWxzZSxcbiBib3VuZHM6ICd0aWNrcycsXG4gICAgICAgIGNsaXA6IHRydWUsXG4gZ3JhY2U6IDAsXG4gICAgICAgIGdyaWQ6IHtcbiAgICAgICAgICAgIGRpc3BsYXk6IHRydWUsXG4gICAgICAgICAgICBsaW5lV2lkdGg6IDEsXG4gICAgICAgICAgICBkcmF3T25DaGFydEFyZWE6IHRydWUsXG4gICAgICAgICAgICBkcmF3VGlja3M6IHRydWUsXG4gICAgICAgICAgICB0aWNrTGVuZ3RoOiA4LFxuICAgICAgICAgICAgdGlja1dpZHRoOiAoX2N0eCwgb3B0aW9ucyk9Pm9wdGlvbnMubGluZVdpZHRoLFxuICAgICAgICAgICAgdGlja0NvbG9yOiAoX2N0eCwgb3B0aW9ucyk9Pm9wdGlvbnMuY29sb3IsXG4gICAgICAgICAgICBvZmZzZXQ6IGZhbHNlXG4gICAgICAgIH0sXG4gICAgICAgIGJvcmRlcjoge1xuICAgICAgICAgICAgZGlzcGxheTogdHJ1ZSxcbiAgICAgICAgICAgIGRhc2g6IFtdLFxuICAgICAgICAgICAgZGFzaE9mZnNldDogMC4wLFxuICAgICAgICAgICAgd2lkdGg6IDFcbiAgICAgICAgfSxcbiAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICAgIGRpc3BsYXk6IGZhbHNlLFxuICAgICAgICAgICAgdGV4dDogJycsXG4gICAgICAgICAgICBwYWRkaW5nOiB7XG4gICAgICAgICAgICAgICAgdG9wOiA0LFxuICAgICAgICAgICAgICAgIGJvdHRvbTogNFxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB0aWNrczoge1xuICAgICAgICAgICAgbWluUm90YXRpb246IDAsXG4gICAgICAgICAgICBtYXhSb3RhdGlvbjogNTAsXG4gICAgICAgICAgICBtaXJyb3I6IGZhbHNlLFxuICAgICAgICAgICAgdGV4dFN0cm9rZVdpZHRoOiAwLFxuICAgICAgICAgICAgdGV4dFN0cm9rZUNvbG9yOiAnJyxcbiAgICAgICAgICAgIHBhZGRpbmc6IDMsXG4gICAgICAgICAgICBkaXNwbGF5OiB0cnVlLFxuICAgICAgICAgICAgYXV0b1NraXA6IHRydWUsXG4gICAgICAgICAgICBhdXRvU2tpcFBhZGRpbmc6IDMsXG4gICAgICAgICAgICBsYWJlbE9mZnNldDogMCxcbiAgICAgICAgICAgIGNhbGxiYWNrOiBUaWNrcy5mb3JtYXR0ZXJzLnZhbHVlcyxcbiAgICAgICAgICAgIG1pbm9yOiB7fSxcbiAgICAgICAgICAgIG1ham9yOiB7fSxcbiAgICAgICAgICAgIGFsaWduOiAnY2VudGVyJyxcbiAgICAgICAgICAgIGNyb3NzQWxpZ246ICduZWFyJyxcbiAgICAgICAgICAgIHNob3dMYWJlbEJhY2tkcm9wOiBmYWxzZSxcbiAgICAgICAgICAgIGJhY2tkcm9wQ29sb3I6ICdyZ2JhKDI1NSwgMjU1LCAyNTUsIDAuNzUpJyxcbiAgICAgICAgICAgIGJhY2tkcm9wUGFkZGluZzogMlxuICAgICAgICB9XG4gICAgfSk7XG4gICAgZGVmYXVsdHMucm91dGUoJ3NjYWxlLnRpY2tzJywgJ2NvbG9yJywgJycsICdjb2xvcicpO1xuICAgIGRlZmF1bHRzLnJvdXRlKCdzY2FsZS5ncmlkJywgJ2NvbG9yJywgJycsICdib3JkZXJDb2xvcicpO1xuICAgIGRlZmF1bHRzLnJvdXRlKCdzY2FsZS5ib3JkZXInLCAnY29sb3InLCAnJywgJ2JvcmRlckNvbG9yJyk7XG4gICAgZGVmYXVsdHMucm91dGUoJ3NjYWxlLnRpdGxlJywgJ2NvbG9yJywgJycsICdjb2xvcicpO1xuICAgIGRlZmF1bHRzLmRlc2NyaWJlKCdzY2FsZScsIHtcbiAgICAgICAgX2ZhbGxiYWNrOiBmYWxzZSxcbiAgICAgICAgX3NjcmlwdGFibGU6IChuYW1lKT0+IW5hbWUuc3RhcnRzV2l0aCgnYmVmb3JlJykgJiYgIW5hbWUuc3RhcnRzV2l0aCgnYWZ0ZXInKSAmJiBuYW1lICE9PSAnY2FsbGJhY2snICYmIG5hbWUgIT09ICdwYXJzZXInLFxuICAgICAgICBfaW5kZXhhYmxlOiAobmFtZSk9Pm5hbWUgIT09ICdib3JkZXJEYXNoJyAmJiBuYW1lICE9PSAndGlja0JvcmRlckRhc2gnICYmIG5hbWUgIT09ICdkYXNoJ1xuICAgIH0pO1xuICAgIGRlZmF1bHRzLmRlc2NyaWJlKCdzY2FsZXMnLCB7XG4gICAgICAgIF9mYWxsYmFjazogJ3NjYWxlJ1xuICAgIH0pO1xuICAgIGRlZmF1bHRzLmRlc2NyaWJlKCdzY2FsZS50aWNrcycsIHtcbiAgICAgICAgX3NjcmlwdGFibGU6IChuYW1lKT0+bmFtZSAhPT0gJ2JhY2tkcm9wUGFkZGluZycgJiYgbmFtZSAhPT0gJ2NhbGxiYWNrJyxcbiAgICAgICAgX2luZGV4YWJsZTogKG5hbWUpPT5uYW1lICE9PSAnYmFja2Ryb3BQYWRkaW5nJ1xuICAgIH0pO1xufVxuXG5jb25zdCBvdmVycmlkZXMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuY29uc3QgZGVzY3JpcHRvcnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuIGZ1bmN0aW9uIGdldFNjb3BlJDEobm9kZSwga2V5KSB7XG4gICAgaWYgKCFrZXkpIHtcbiAgICAgICAgcmV0dXJuIG5vZGU7XG4gICAgfVxuICAgIGNvbnN0IGtleXMgPSBrZXkuc3BsaXQoJy4nKTtcbiAgICBmb3IobGV0IGkgPSAwLCBuID0ga2V5cy5sZW5ndGg7IGkgPCBuOyArK2kpe1xuICAgICAgICBjb25zdCBrID0ga2V5c1tpXTtcbiAgICAgICAgbm9kZSA9IG5vZGVba10gfHwgKG5vZGVba10gPSBPYmplY3QuY3JlYXRlKG51bGwpKTtcbiAgICB9XG4gICAgcmV0dXJuIG5vZGU7XG59XG5mdW5jdGlvbiBzZXQocm9vdCwgc2NvcGUsIHZhbHVlcykge1xuICAgIGlmICh0eXBlb2Ygc2NvcGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiBtZXJnZShnZXRTY29wZSQxKHJvb3QsIHNjb3BlKSwgdmFsdWVzKTtcbiAgICB9XG4gICAgcmV0dXJuIG1lcmdlKGdldFNjb3BlJDEocm9vdCwgJycpLCBzY29wZSk7XG59XG4gY2xhc3MgRGVmYXVsdHMge1xuICAgIGNvbnN0cnVjdG9yKF9kZXNjcmlwdG9ycywgX2FwcGxpZXJzKXtcbiAgICAgICAgdGhpcy5hbmltYXRpb24gPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuYmFja2dyb3VuZENvbG9yID0gJ3JnYmEoMCwwLDAsMC4xKSc7XG4gICAgICAgIHRoaXMuYm9yZGVyQ29sb3IgPSAncmdiYSgwLDAsMCwwLjEpJztcbiAgICAgICAgdGhpcy5jb2xvciA9ICcjNjY2JztcbiAgICAgICAgdGhpcy5kYXRhc2V0cyA9IHt9O1xuICAgICAgICB0aGlzLmRldmljZVBpeGVsUmF0aW8gPSAoY29udGV4dCk9PmNvbnRleHQuY2hhcnQucGxhdGZvcm0uZ2V0RGV2aWNlUGl4ZWxSYXRpbygpO1xuICAgICAgICB0aGlzLmVsZW1lbnRzID0ge307XG4gICAgICAgIHRoaXMuZXZlbnRzID0gW1xuICAgICAgICAgICAgJ21vdXNlbW92ZScsXG4gICAgICAgICAgICAnbW91c2VvdXQnLFxuICAgICAgICAgICAgJ2NsaWNrJyxcbiAgICAgICAgICAgICd0b3VjaHN0YXJ0JyxcbiAgICAgICAgICAgICd0b3VjaG1vdmUnXG4gICAgICAgIF07XG4gICAgICAgIHRoaXMuZm9udCA9IHtcbiAgICAgICAgICAgIGZhbWlseTogXCInSGVsdmV0aWNhIE5ldWUnLCAnSGVsdmV0aWNhJywgJ0FyaWFsJywgc2Fucy1zZXJpZlwiLFxuICAgICAgICAgICAgc2l6ZTogMTIsXG4gICAgICAgICAgICBzdHlsZTogJ25vcm1hbCcsXG4gICAgICAgICAgICBsaW5lSGVpZ2h0OiAxLjIsXG4gICAgICAgICAgICB3ZWlnaHQ6IG51bGxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5ob3ZlciA9IHt9O1xuICAgICAgICB0aGlzLmhvdmVyQmFja2dyb3VuZENvbG9yID0gKGN0eCwgb3B0aW9ucyk9PmdldEhvdmVyQ29sb3Iob3B0aW9ucy5iYWNrZ3JvdW5kQ29sb3IpO1xuICAgICAgICB0aGlzLmhvdmVyQm9yZGVyQ29sb3IgPSAoY3R4LCBvcHRpb25zKT0+Z2V0SG92ZXJDb2xvcihvcHRpb25zLmJvcmRlckNvbG9yKTtcbiAgICAgICAgdGhpcy5ob3ZlckNvbG9yID0gKGN0eCwgb3B0aW9ucyk9PmdldEhvdmVyQ29sb3Iob3B0aW9ucy5jb2xvcik7XG4gICAgICAgIHRoaXMuaW5kZXhBeGlzID0gJ3gnO1xuICAgICAgICB0aGlzLmludGVyYWN0aW9uID0ge1xuICAgICAgICAgICAgbW9kZTogJ25lYXJlc3QnLFxuICAgICAgICAgICAgaW50ZXJzZWN0OiB0cnVlLFxuICAgICAgICAgICAgaW5jbHVkZUludmlzaWJsZTogZmFsc2VcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5tYWludGFpbkFzcGVjdFJhdGlvID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5vbkhvdmVyID0gbnVsbDtcbiAgICAgICAgdGhpcy5vbkNsaWNrID0gbnVsbDtcbiAgICAgICAgdGhpcy5wYXJzaW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5wbHVnaW5zID0ge307XG4gICAgICAgIHRoaXMucmVzcG9uc2l2ZSA9IHRydWU7XG4gICAgICAgIHRoaXMuc2NhbGUgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuc2NhbGVzID0ge307XG4gICAgICAgIHRoaXMuc2hvd0xpbmUgPSB0cnVlO1xuICAgICAgICB0aGlzLmRyYXdBY3RpdmVFbGVtZW50c09uVG9wID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5kZXNjcmliZShfZGVzY3JpcHRvcnMpO1xuICAgICAgICB0aGlzLmFwcGx5KF9hcHBsaWVycyk7XG4gICAgfVxuIHNldChzY29wZSwgdmFsdWVzKSB7XG4gICAgICAgIHJldHVybiBzZXQodGhpcywgc2NvcGUsIHZhbHVlcyk7XG4gICAgfVxuIGdldChzY29wZSkge1xuICAgICAgICByZXR1cm4gZ2V0U2NvcGUkMSh0aGlzLCBzY29wZSk7XG4gICAgfVxuIGRlc2NyaWJlKHNjb3BlLCB2YWx1ZXMpIHtcbiAgICAgICAgcmV0dXJuIHNldChkZXNjcmlwdG9ycywgc2NvcGUsIHZhbHVlcyk7XG4gICAgfVxuICAgIG92ZXJyaWRlKHNjb3BlLCB2YWx1ZXMpIHtcbiAgICAgICAgcmV0dXJuIHNldChvdmVycmlkZXMsIHNjb3BlLCB2YWx1ZXMpO1xuICAgIH1cbiByb3V0ZShzY29wZSwgbmFtZSwgdGFyZ2V0U2NvcGUsIHRhcmdldE5hbWUpIHtcbiAgICAgICAgY29uc3Qgc2NvcGVPYmplY3QgPSBnZXRTY29wZSQxKHRoaXMsIHNjb3BlKTtcbiAgICAgICAgY29uc3QgdGFyZ2V0U2NvcGVPYmplY3QgPSBnZXRTY29wZSQxKHRoaXMsIHRhcmdldFNjb3BlKTtcbiAgICAgICAgY29uc3QgcHJpdmF0ZU5hbWUgPSAnXycgKyBuYW1lO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhzY29wZU9iamVjdCwge1xuICAgICAgICAgICAgW3ByaXZhdGVOYW1lXToge1xuICAgICAgICAgICAgICAgIHZhbHVlOiBzY29wZU9iamVjdFtuYW1lXSxcbiAgICAgICAgICAgICAgICB3cml0YWJsZTogdHJ1ZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFtuYW1lXToge1xuICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgZ2V0ICgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbG9jYWwgPSB0aGlzW3ByaXZhdGVOYW1lXTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gdGFyZ2V0U2NvcGVPYmplY3RbdGFyZ2V0TmFtZV07XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc09iamVjdChsb2NhbCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCB0YXJnZXQsIGxvY2FsKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWVPckRlZmF1bHQobG9jYWwsIHRhcmdldCk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzZXQgKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXNbcHJpdmF0ZU5hbWVdID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgYXBwbHkoYXBwbGllcnMpIHtcbiAgICAgICAgYXBwbGllcnMuZm9yRWFjaCgoYXBwbHkpPT5hcHBseSh0aGlzKSk7XG4gICAgfVxufVxudmFyIGRlZmF1bHRzID0gLyogI19fUFVSRV9fICovIG5ldyBEZWZhdWx0cyh7XG4gICAgX3NjcmlwdGFibGU6IChuYW1lKT0+IW5hbWUuc3RhcnRzV2l0aCgnb24nKSxcbiAgICBfaW5kZXhhYmxlOiAobmFtZSk9Pm5hbWUgIT09ICdldmVudHMnLFxuICAgIGhvdmVyOiB7XG4gICAgICAgIF9mYWxsYmFjazogJ2ludGVyYWN0aW9uJ1xuICAgIH0sXG4gICAgaW50ZXJhY3Rpb246IHtcbiAgICAgICAgX3NjcmlwdGFibGU6IGZhbHNlLFxuICAgICAgICBfaW5kZXhhYmxlOiBmYWxzZVxuICAgIH1cbn0sIFtcbiAgICBhcHBseUFuaW1hdGlvbnNEZWZhdWx0cyxcbiAgICBhcHBseUxheW91dHNEZWZhdWx0cyxcbiAgICBhcHBseVNjYWxlRGVmYXVsdHNcbl0pO1xuXG4vKipcbiAqIENvbnZlcnRzIHRoZSBnaXZlbiBmb250IG9iamVjdCBpbnRvIGEgQ1NTIGZvbnQgc3RyaW5nLlxuICogQHBhcmFtIGZvbnQgLSBBIGZvbnQgb2JqZWN0LlxuICogQHJldHVybiBUaGUgQ1NTIGZvbnQgc3RyaW5nLiBTZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL2ZvbnRcbiAqIEBwcml2YXRlXG4gKi8gZnVuY3Rpb24gdG9Gb250U3RyaW5nKGZvbnQpIHtcbiAgICBpZiAoIWZvbnQgfHwgaXNOdWxsT3JVbmRlZihmb250LnNpemUpIHx8IGlzTnVsbE9yVW5kZWYoZm9udC5mYW1pbHkpKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gKGZvbnQuc3R5bGUgPyBmb250LnN0eWxlICsgJyAnIDogJycpICsgKGZvbnQud2VpZ2h0ID8gZm9udC53ZWlnaHQgKyAnICcgOiAnJykgKyBmb250LnNpemUgKyAncHggJyArIGZvbnQuZmFtaWx5O1xufVxuLyoqXG4gKiBAcHJpdmF0ZVxuICovIGZ1bmN0aW9uIF9tZWFzdXJlVGV4dChjdHgsIGRhdGEsIGdjLCBsb25nZXN0LCBzdHJpbmcpIHtcbiAgICBsZXQgdGV4dFdpZHRoID0gZGF0YVtzdHJpbmddO1xuICAgIGlmICghdGV4dFdpZHRoKSB7XG4gICAgICAgIHRleHRXaWR0aCA9IGRhdGFbc3RyaW5nXSA9IGN0eC5tZWFzdXJlVGV4dChzdHJpbmcpLndpZHRoO1xuICAgICAgICBnYy5wdXNoKHN0cmluZyk7XG4gICAgfVxuICAgIGlmICh0ZXh0V2lkdGggPiBsb25nZXN0KSB7XG4gICAgICAgIGxvbmdlc3QgPSB0ZXh0V2lkdGg7XG4gICAgfVxuICAgIHJldHVybiBsb25nZXN0O1xufVxuLyoqXG4gKiBAcHJpdmF0ZVxuICovIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb21wbGV4aXR5XG5mdW5jdGlvbiBfbG9uZ2VzdFRleHQoY3R4LCBmb250LCBhcnJheU9mVGhpbmdzLCBjYWNoZSkge1xuICAgIGNhY2hlID0gY2FjaGUgfHwge307XG4gICAgbGV0IGRhdGEgPSBjYWNoZS5kYXRhID0gY2FjaGUuZGF0YSB8fCB7fTtcbiAgICBsZXQgZ2MgPSBjYWNoZS5nYXJiYWdlQ29sbGVjdCA9IGNhY2hlLmdhcmJhZ2VDb2xsZWN0IHx8IFtdO1xuICAgIGlmIChjYWNoZS5mb250ICE9PSBmb250KSB7XG4gICAgICAgIGRhdGEgPSBjYWNoZS5kYXRhID0ge307XG4gICAgICAgIGdjID0gY2FjaGUuZ2FyYmFnZUNvbGxlY3QgPSBbXTtcbiAgICAgICAgY2FjaGUuZm9udCA9IGZvbnQ7XG4gICAgfVxuICAgIGN0eC5zYXZlKCk7XG4gICAgY3R4LmZvbnQgPSBmb250O1xuICAgIGxldCBsb25nZXN0ID0gMDtcbiAgICBjb25zdCBpbGVuID0gYXJyYXlPZlRoaW5ncy5sZW5ndGg7XG4gICAgbGV0IGksIGosIGpsZW4sIHRoaW5nLCBuZXN0ZWRUaGluZztcbiAgICBmb3IoaSA9IDA7IGkgPCBpbGVuOyBpKyspe1xuICAgICAgICB0aGluZyA9IGFycmF5T2ZUaGluZ3NbaV07XG4gICAgICAgIC8vIFVuZGVmaW5lZCBzdHJpbmdzIGFuZCBhcnJheXMgc2hvdWxkIG5vdCBiZSBtZWFzdXJlZFxuICAgICAgICBpZiAodGhpbmcgIT09IHVuZGVmaW5lZCAmJiB0aGluZyAhPT0gbnVsbCAmJiAhaXNBcnJheSh0aGluZykpIHtcbiAgICAgICAgICAgIGxvbmdlc3QgPSBfbWVhc3VyZVRleHQoY3R4LCBkYXRhLCBnYywgbG9uZ2VzdCwgdGhpbmcpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzQXJyYXkodGhpbmcpKSB7XG4gICAgICAgICAgICAvLyBpZiBpdCBpcyBhbiBhcnJheSBsZXRzIG1lYXN1cmUgZWFjaCBlbGVtZW50XG4gICAgICAgICAgICAvLyB0byBkbyBtYXliZSBzaW1wbGlmeSB0aGlzIGZ1bmN0aW9uIGEgYml0IHNvIHdlIGNhbiBkbyB0aGlzIG1vcmUgcmVjdXJzaXZlbHk/XG4gICAgICAgICAgICBmb3IoaiA9IDAsIGpsZW4gPSB0aGluZy5sZW5ndGg7IGogPCBqbGVuOyBqKyspe1xuICAgICAgICAgICAgICAgIG5lc3RlZFRoaW5nID0gdGhpbmdbal07XG4gICAgICAgICAgICAgICAgLy8gVW5kZWZpbmVkIHN0cmluZ3MgYW5kIGFycmF5cyBzaG91bGQgbm90IGJlIG1lYXN1cmVkXG4gICAgICAgICAgICAgICAgaWYgKG5lc3RlZFRoaW5nICE9PSB1bmRlZmluZWQgJiYgbmVzdGVkVGhpbmcgIT09IG51bGwgJiYgIWlzQXJyYXkobmVzdGVkVGhpbmcpKSB7XG4gICAgICAgICAgICAgICAgICAgIGxvbmdlc3QgPSBfbWVhc3VyZVRleHQoY3R4LCBkYXRhLCBnYywgbG9uZ2VzdCwgbmVzdGVkVGhpbmcpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBjdHgucmVzdG9yZSgpO1xuICAgIGNvbnN0IGdjTGVuID0gZ2MubGVuZ3RoIC8gMjtcbiAgICBpZiAoZ2NMZW4gPiBhcnJheU9mVGhpbmdzLmxlbmd0aCkge1xuICAgICAgICBmb3IoaSA9IDA7IGkgPCBnY0xlbjsgaSsrKXtcbiAgICAgICAgICAgIGRlbGV0ZSBkYXRhW2djW2ldXTtcbiAgICAgICAgfVxuICAgICAgICBnYy5zcGxpY2UoMCwgZ2NMZW4pO1xuICAgIH1cbiAgICByZXR1cm4gbG9uZ2VzdDtcbn1cbi8qKlxuICogUmV0dXJucyB0aGUgYWxpZ25lZCBwaXhlbCB2YWx1ZSB0byBhdm9pZCBhbnRpLWFsaWFzaW5nIGJsdXJcbiAqIEBwYXJhbSBjaGFydCAtIFRoZSBjaGFydCBpbnN0YW5jZS5cbiAqIEBwYXJhbSBwaXhlbCAtIEEgcGl4ZWwgdmFsdWUuXG4gKiBAcGFyYW0gd2lkdGggLSBUaGUgd2lkdGggb2YgdGhlIGVsZW1lbnQuXG4gKiBAcmV0dXJucyBUaGUgYWxpZ25lZCBwaXhlbCB2YWx1ZS5cbiAqIEBwcml2YXRlXG4gKi8gZnVuY3Rpb24gX2FsaWduUGl4ZWwoY2hhcnQsIHBpeGVsLCB3aWR0aCkge1xuICAgIGNvbnN0IGRldmljZVBpeGVsUmF0aW8gPSBjaGFydC5jdXJyZW50RGV2aWNlUGl4ZWxSYXRpbztcbiAgICBjb25zdCBoYWxmV2lkdGggPSB3aWR0aCAhPT0gMCA/IE1hdGgubWF4KHdpZHRoIC8gMiwgMC41KSA6IDA7XG4gICAgcmV0dXJuIE1hdGgucm91bmQoKHBpeGVsIC0gaGFsZldpZHRoKSAqIGRldmljZVBpeGVsUmF0aW8pIC8gZGV2aWNlUGl4ZWxSYXRpbyArIGhhbGZXaWR0aDtcbn1cbi8qKlxuICogQ2xlYXJzIHRoZSBlbnRpcmUgY2FudmFzLlxuICovIGZ1bmN0aW9uIGNsZWFyQ2FudmFzKGNhbnZhcywgY3R4KSB7XG4gICAgaWYgKCFjdHggJiYgIWNhbnZhcykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGN0eCA9IGN0eCB8fCBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICBjdHguc2F2ZSgpO1xuICAgIC8vIGNhbnZhcy53aWR0aCBhbmQgY2FudmFzLmhlaWdodCBkbyBub3QgY29uc2lkZXIgdGhlIGNhbnZhcyB0cmFuc2Zvcm0sXG4gICAgLy8gd2hpbGUgY2xlYXJSZWN0IGRvZXNcbiAgICBjdHgucmVzZXRUcmFuc2Zvcm0oKTtcbiAgICBjdHguY2xlYXJSZWN0KDAsIDAsIGNhbnZhcy53aWR0aCwgY2FudmFzLmhlaWdodCk7XG4gICAgY3R4LnJlc3RvcmUoKTtcbn1cbmZ1bmN0aW9uIGRyYXdQb2ludChjdHgsIG9wdGlvbnMsIHgsIHkpIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVzZS1iZWZvcmUtZGVmaW5lXG4gICAgZHJhd1BvaW50TGVnZW5kKGN0eCwgb3B0aW9ucywgeCwgeSwgbnVsbCk7XG59XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29tcGxleGl0eVxuZnVuY3Rpb24gZHJhd1BvaW50TGVnZW5kKGN0eCwgb3B0aW9ucywgeCwgeSwgdykge1xuICAgIGxldCB0eXBlLCB4T2Zmc2V0LCB5T2Zmc2V0LCBzaXplLCBjb3JuZXJSYWRpdXMsIHdpZHRoLCB4T2Zmc2V0VywgeU9mZnNldFc7XG4gICAgY29uc3Qgc3R5bGUgPSBvcHRpb25zLnBvaW50U3R5bGU7XG4gICAgY29uc3Qgcm90YXRpb24gPSBvcHRpb25zLnJvdGF0aW9uO1xuICAgIGNvbnN0IHJhZGl1cyA9IG9wdGlvbnMucmFkaXVzO1xuICAgIGxldCByYWQgPSAocm90YXRpb24gfHwgMCkgKiBSQURfUEVSX0RFRztcbiAgICBpZiAoc3R5bGUgJiYgdHlwZW9mIHN0eWxlID09PSAnb2JqZWN0Jykge1xuICAgICAgICB0eXBlID0gc3R5bGUudG9TdHJpbmcoKTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICdbb2JqZWN0IEhUTUxJbWFnZUVsZW1lbnRdJyB8fCB0eXBlID09PSAnW29iamVjdCBIVE1MQ2FudmFzRWxlbWVudF0nKSB7XG4gICAgICAgICAgICBjdHguc2F2ZSgpO1xuICAgICAgICAgICAgY3R4LnRyYW5zbGF0ZSh4LCB5KTtcbiAgICAgICAgICAgIGN0eC5yb3RhdGUocmFkKTtcbiAgICAgICAgICAgIGN0eC5kcmF3SW1hZ2Uoc3R5bGUsIC1zdHlsZS53aWR0aCAvIDIsIC1zdHlsZS5oZWlnaHQgLyAyLCBzdHlsZS53aWR0aCwgc3R5bGUuaGVpZ2h0KTtcbiAgICAgICAgICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGlzTmFOKHJhZGl1cykgfHwgcmFkaXVzIDw9IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgc3dpdGNoKHN0eWxlKXtcbiAgICAgICAgLy8gRGVmYXVsdCBpbmNsdWRlcyBjaXJjbGVcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGlmICh3KSB7XG4gICAgICAgICAgICAgICAgY3R4LmVsbGlwc2UoeCwgeSwgdyAvIDIsIHJhZGl1cywgMCwgMCwgVEFVKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY3R4LmFyYyh4LCB5LCByYWRpdXMsIDAsIFRBVSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjdHguY2xvc2VQYXRoKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAndHJpYW5nbGUnOlxuICAgICAgICAgICAgd2lkdGggPSB3ID8gdyAvIDIgOiByYWRpdXM7XG4gICAgICAgICAgICBjdHgubW92ZVRvKHggKyBNYXRoLnNpbihyYWQpICogd2lkdGgsIHkgLSBNYXRoLmNvcyhyYWQpICogcmFkaXVzKTtcbiAgICAgICAgICAgIHJhZCArPSBUV09fVEhJUkRTX1BJO1xuICAgICAgICAgICAgY3R4LmxpbmVUbyh4ICsgTWF0aC5zaW4ocmFkKSAqIHdpZHRoLCB5IC0gTWF0aC5jb3MocmFkKSAqIHJhZGl1cyk7XG4gICAgICAgICAgICByYWQgKz0gVFdPX1RISVJEU19QSTtcbiAgICAgICAgICAgIGN0eC5saW5lVG8oeCArIE1hdGguc2luKHJhZCkgKiB3aWR0aCwgeSAtIE1hdGguY29zKHJhZCkgKiByYWRpdXMpO1xuICAgICAgICAgICAgY3R4LmNsb3NlUGF0aCgpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3JlY3RSb3VuZGVkJzpcbiAgICAgICAgICAgIC8vIE5PVEU6IHRoZSByb3VuZGVkIHJlY3QgaW1wbGVtZW50YXRpb24gY2hhbmdlZCB0byB1c2UgYGFyY2AgaW5zdGVhZCBvZlxuICAgICAgICAgICAgLy8gYHF1YWRyYXRpY0N1cnZlVG9gIHNpbmNlIGl0IGdlbmVyYXRlcyBiZXR0ZXIgcmVzdWx0cyB3aGVuIHJlY3QgaXNcbiAgICAgICAgICAgIC8vIGFsbW9zdCBhIGNpcmNsZS4gMC41MTYgKGluc3RlYWQgb2YgMC41KSBwcm9kdWNlcyByZXN1bHRzIHdpdGggdmlzdWFsbHlcbiAgICAgICAgICAgIC8vIGNsb3NlciBwcm9wb3J0aW9uIHRvIHRoZSBwcmV2aW91cyBpbXBsIGFuZCBpdCBpcyBpbnNjcmliZWQgaW4gdGhlXG4gICAgICAgICAgICAvLyBjaXJjbGUgd2l0aCBgcmFkaXVzYC4gRm9yIG1vcmUgZGV0YWlscywgc2VlIHRoZSBmb2xsb3dpbmcgUFJzOlxuICAgICAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzU1OTdcbiAgICAgICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy81ODU4XG4gICAgICAgICAgICBjb3JuZXJSYWRpdXMgPSByYWRpdXMgKiAwLjUxNjtcbiAgICAgICAgICAgIHNpemUgPSByYWRpdXMgLSBjb3JuZXJSYWRpdXM7XG4gICAgICAgICAgICB4T2Zmc2V0ID0gTWF0aC5jb3MocmFkICsgUVVBUlRFUl9QSSkgKiBzaXplO1xuICAgICAgICAgICAgeE9mZnNldFcgPSBNYXRoLmNvcyhyYWQgKyBRVUFSVEVSX1BJKSAqICh3ID8gdyAvIDIgLSBjb3JuZXJSYWRpdXMgOiBzaXplKTtcbiAgICAgICAgICAgIHlPZmZzZXQgPSBNYXRoLnNpbihyYWQgKyBRVUFSVEVSX1BJKSAqIHNpemU7XG4gICAgICAgICAgICB5T2Zmc2V0VyA9IE1hdGguc2luKHJhZCArIFFVQVJURVJfUEkpICogKHcgPyB3IC8gMiAtIGNvcm5lclJhZGl1cyA6IHNpemUpO1xuICAgICAgICAgICAgY3R4LmFyYyh4IC0geE9mZnNldFcsIHkgLSB5T2Zmc2V0LCBjb3JuZXJSYWRpdXMsIHJhZCAtIFBJLCByYWQgLSBIQUxGX1BJKTtcbiAgICAgICAgICAgIGN0eC5hcmMoeCArIHlPZmZzZXRXLCB5IC0geE9mZnNldCwgY29ybmVyUmFkaXVzLCByYWQgLSBIQUxGX1BJLCByYWQpO1xuICAgICAgICAgICAgY3R4LmFyYyh4ICsgeE9mZnNldFcsIHkgKyB5T2Zmc2V0LCBjb3JuZXJSYWRpdXMsIHJhZCwgcmFkICsgSEFMRl9QSSk7XG4gICAgICAgICAgICBjdHguYXJjKHggLSB5T2Zmc2V0VywgeSArIHhPZmZzZXQsIGNvcm5lclJhZGl1cywgcmFkICsgSEFMRl9QSSwgcmFkICsgUEkpO1xuICAgICAgICAgICAgY3R4LmNsb3NlUGF0aCgpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3JlY3QnOlxuICAgICAgICAgICAgaWYgKCFyb3RhdGlvbikge1xuICAgICAgICAgICAgICAgIHNpemUgPSBNYXRoLlNRUlQxXzIgKiByYWRpdXM7XG4gICAgICAgICAgICAgICAgd2lkdGggPSB3ID8gdyAvIDIgOiBzaXplO1xuICAgICAgICAgICAgICAgIGN0eC5yZWN0KHggLSB3aWR0aCwgeSAtIHNpemUsIDIgKiB3aWR0aCwgMiAqIHNpemUpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmFkICs9IFFVQVJURVJfUEk7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi8gY2FzZSAncmVjdFJvdCc6XG4gICAgICAgICAgICB4T2Zmc2V0VyA9IE1hdGguY29zKHJhZCkgKiAodyA/IHcgLyAyIDogcmFkaXVzKTtcbiAgICAgICAgICAgIHhPZmZzZXQgPSBNYXRoLmNvcyhyYWQpICogcmFkaXVzO1xuICAgICAgICAgICAgeU9mZnNldCA9IE1hdGguc2luKHJhZCkgKiByYWRpdXM7XG4gICAgICAgICAgICB5T2Zmc2V0VyA9IE1hdGguc2luKHJhZCkgKiAodyA/IHcgLyAyIDogcmFkaXVzKTtcbiAgICAgICAgICAgIGN0eC5tb3ZlVG8oeCAtIHhPZmZzZXRXLCB5IC0geU9mZnNldCk7XG4gICAgICAgICAgICBjdHgubGluZVRvKHggKyB5T2Zmc2V0VywgeSAtIHhPZmZzZXQpO1xuICAgICAgICAgICAgY3R4LmxpbmVUbyh4ICsgeE9mZnNldFcsIHkgKyB5T2Zmc2V0KTtcbiAgICAgICAgICAgIGN0eC5saW5lVG8oeCAtIHlPZmZzZXRXLCB5ICsgeE9mZnNldCk7XG4gICAgICAgICAgICBjdHguY2xvc2VQYXRoKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnY3Jvc3NSb3QnOlxuICAgICAgICAgICAgcmFkICs9IFFVQVJURVJfUEk7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi8gY2FzZSAnY3Jvc3MnOlxuICAgICAgICAgICAgeE9mZnNldFcgPSBNYXRoLmNvcyhyYWQpICogKHcgPyB3IC8gMiA6IHJhZGl1cyk7XG4gICAgICAgICAgICB4T2Zmc2V0ID0gTWF0aC5jb3MocmFkKSAqIHJhZGl1cztcbiAgICAgICAgICAgIHlPZmZzZXQgPSBNYXRoLnNpbihyYWQpICogcmFkaXVzO1xuICAgICAgICAgICAgeU9mZnNldFcgPSBNYXRoLnNpbihyYWQpICogKHcgPyB3IC8gMiA6IHJhZGl1cyk7XG4gICAgICAgICAgICBjdHgubW92ZVRvKHggLSB4T2Zmc2V0VywgeSAtIHlPZmZzZXQpO1xuICAgICAgICAgICAgY3R4LmxpbmVUbyh4ICsgeE9mZnNldFcsIHkgKyB5T2Zmc2V0KTtcbiAgICAgICAgICAgIGN0eC5tb3ZlVG8oeCArIHlPZmZzZXRXLCB5IC0geE9mZnNldCk7XG4gICAgICAgICAgICBjdHgubGluZVRvKHggLSB5T2Zmc2V0VywgeSArIHhPZmZzZXQpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3N0YXInOlxuICAgICAgICAgICAgeE9mZnNldFcgPSBNYXRoLmNvcyhyYWQpICogKHcgPyB3IC8gMiA6IHJhZGl1cyk7XG4gICAgICAgICAgICB4T2Zmc2V0ID0gTWF0aC5jb3MocmFkKSAqIHJhZGl1cztcbiAgICAgICAgICAgIHlPZmZzZXQgPSBNYXRoLnNpbihyYWQpICogcmFkaXVzO1xuICAgICAgICAgICAgeU9mZnNldFcgPSBNYXRoLnNpbihyYWQpICogKHcgPyB3IC8gMiA6IHJhZGl1cyk7XG4gICAgICAgICAgICBjdHgubW92ZVRvKHggLSB4T2Zmc2V0VywgeSAtIHlPZmZzZXQpO1xuICAgICAgICAgICAgY3R4LmxpbmVUbyh4ICsgeE9mZnNldFcsIHkgKyB5T2Zmc2V0KTtcbiAgICAgICAgICAgIGN0eC5tb3ZlVG8oeCArIHlPZmZzZXRXLCB5IC0geE9mZnNldCk7XG4gICAgICAgICAgICBjdHgubGluZVRvKHggLSB5T2Zmc2V0VywgeSArIHhPZmZzZXQpO1xuICAgICAgICAgICAgcmFkICs9IFFVQVJURVJfUEk7XG4gICAgICAgICAgICB4T2Zmc2V0VyA9IE1hdGguY29zKHJhZCkgKiAodyA/IHcgLyAyIDogcmFkaXVzKTtcbiAgICAgICAgICAgIHhPZmZzZXQgPSBNYXRoLmNvcyhyYWQpICogcmFkaXVzO1xuICAgICAgICAgICAgeU9mZnNldCA9IE1hdGguc2luKHJhZCkgKiByYWRpdXM7XG4gICAgICAgICAgICB5T2Zmc2V0VyA9IE1hdGguc2luKHJhZCkgKiAodyA/IHcgLyAyIDogcmFkaXVzKTtcbiAgICAgICAgICAgIGN0eC5tb3ZlVG8oeCAtIHhPZmZzZXRXLCB5IC0geU9mZnNldCk7XG4gICAgICAgICAgICBjdHgubGluZVRvKHggKyB4T2Zmc2V0VywgeSArIHlPZmZzZXQpO1xuICAgICAgICAgICAgY3R4Lm1vdmVUbyh4ICsgeU9mZnNldFcsIHkgLSB4T2Zmc2V0KTtcbiAgICAgICAgICAgIGN0eC5saW5lVG8oeCAtIHlPZmZzZXRXLCB5ICsgeE9mZnNldCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnbGluZSc6XG4gICAgICAgICAgICB4T2Zmc2V0ID0gdyA/IHcgLyAyIDogTWF0aC5jb3MocmFkKSAqIHJhZGl1cztcbiAgICAgICAgICAgIHlPZmZzZXQgPSBNYXRoLnNpbihyYWQpICogcmFkaXVzO1xuICAgICAgICAgICAgY3R4Lm1vdmVUbyh4IC0geE9mZnNldCwgeSAtIHlPZmZzZXQpO1xuICAgICAgICAgICAgY3R4LmxpbmVUbyh4ICsgeE9mZnNldCwgeSArIHlPZmZzZXQpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2Rhc2gnOlxuICAgICAgICAgICAgY3R4Lm1vdmVUbyh4LCB5KTtcbiAgICAgICAgICAgIGN0eC5saW5lVG8oeCArIE1hdGguY29zKHJhZCkgKiAodyA/IHcgLyAyIDogcmFkaXVzKSwgeSArIE1hdGguc2luKHJhZCkgKiByYWRpdXMpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgZmFsc2U6XG4gICAgICAgICAgICBjdHguY2xvc2VQYXRoKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICB9XG4gICAgY3R4LmZpbGwoKTtcbiAgICBpZiAob3B0aW9ucy5ib3JkZXJXaWR0aCA+IDApIHtcbiAgICAgICAgY3R4LnN0cm9rZSgpO1xuICAgIH1cbn1cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBwb2ludCBpcyBpbnNpZGUgdGhlIHJlY3RhbmdsZVxuICogQHBhcmFtIHBvaW50IC0gVGhlIHBvaW50IHRvIHRlc3RcbiAqIEBwYXJhbSBhcmVhIC0gVGhlIHJlY3RhbmdsZVxuICogQHBhcmFtIG1hcmdpbiAtIGFsbG93ZWQgbWFyZ2luXG4gKiBAcHJpdmF0ZVxuICovIGZ1bmN0aW9uIF9pc1BvaW50SW5BcmVhKHBvaW50LCBhcmVhLCBtYXJnaW4pIHtcbiAgICBtYXJnaW4gPSBtYXJnaW4gfHwgMC41OyAvLyBtYXJnaW4gLSBkZWZhdWx0IGlzIHRvIG1hdGNoIHJvdW5kZWQgZGVjaW1hbHNcbiAgICByZXR1cm4gIWFyZWEgfHwgcG9pbnQgJiYgcG9pbnQueCA+IGFyZWEubGVmdCAtIG1hcmdpbiAmJiBwb2ludC54IDwgYXJlYS5yaWdodCArIG1hcmdpbiAmJiBwb2ludC55ID4gYXJlYS50b3AgLSBtYXJnaW4gJiYgcG9pbnQueSA8IGFyZWEuYm90dG9tICsgbWFyZ2luO1xufVxuZnVuY3Rpb24gY2xpcEFyZWEoY3R4LCBhcmVhKSB7XG4gICAgY3R4LnNhdmUoKTtcbiAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgY3R4LnJlY3QoYXJlYS5sZWZ0LCBhcmVhLnRvcCwgYXJlYS5yaWdodCAtIGFyZWEubGVmdCwgYXJlYS5ib3R0b20gLSBhcmVhLnRvcCk7XG4gICAgY3R4LmNsaXAoKTtcbn1cbmZ1bmN0aW9uIHVuY2xpcEFyZWEoY3R4KSB7XG4gICAgY3R4LnJlc3RvcmUoKTtcbn1cbi8qKlxuICogQHByaXZhdGVcbiAqLyBmdW5jdGlvbiBfc3RlcHBlZExpbmVUbyhjdHgsIHByZXZpb3VzLCB0YXJnZXQsIGZsaXAsIG1vZGUpIHtcbiAgICBpZiAoIXByZXZpb3VzKSB7XG4gICAgICAgIHJldHVybiBjdHgubGluZVRvKHRhcmdldC54LCB0YXJnZXQueSk7XG4gICAgfVxuICAgIGlmIChtb2RlID09PSAnbWlkZGxlJykge1xuICAgICAgICBjb25zdCBtaWRwb2ludCA9IChwcmV2aW91cy54ICsgdGFyZ2V0LngpIC8gMi4wO1xuICAgICAgICBjdHgubGluZVRvKG1pZHBvaW50LCBwcmV2aW91cy55KTtcbiAgICAgICAgY3R4LmxpbmVUbyhtaWRwb2ludCwgdGFyZ2V0LnkpO1xuICAgIH0gZWxzZSBpZiAobW9kZSA9PT0gJ2FmdGVyJyAhPT0gISFmbGlwKSB7XG4gICAgICAgIGN0eC5saW5lVG8ocHJldmlvdXMueCwgdGFyZ2V0LnkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGN0eC5saW5lVG8odGFyZ2V0LngsIHByZXZpb3VzLnkpO1xuICAgIH1cbiAgICBjdHgubGluZVRvKHRhcmdldC54LCB0YXJnZXQueSk7XG59XG4vKipcbiAqIEBwcml2YXRlXG4gKi8gZnVuY3Rpb24gX2JlemllckN1cnZlVG8oY3R4LCBwcmV2aW91cywgdGFyZ2V0LCBmbGlwKSB7XG4gICAgaWYgKCFwcmV2aW91cykge1xuICAgICAgICByZXR1cm4gY3R4LmxpbmVUbyh0YXJnZXQueCwgdGFyZ2V0LnkpO1xuICAgIH1cbiAgICBjdHguYmV6aWVyQ3VydmVUbyhmbGlwID8gcHJldmlvdXMuY3AxeCA6IHByZXZpb3VzLmNwMngsIGZsaXAgPyBwcmV2aW91cy5jcDF5IDogcHJldmlvdXMuY3AyeSwgZmxpcCA/IHRhcmdldC5jcDJ4IDogdGFyZ2V0LmNwMXgsIGZsaXAgPyB0YXJnZXQuY3AyeSA6IHRhcmdldC5jcDF5LCB0YXJnZXQueCwgdGFyZ2V0LnkpO1xufVxuZnVuY3Rpb24gc2V0UmVuZGVyT3B0cyhjdHgsIG9wdHMpIHtcbiAgICBpZiAob3B0cy50cmFuc2xhdGlvbikge1xuICAgICAgICBjdHgudHJhbnNsYXRlKG9wdHMudHJhbnNsYXRpb25bMF0sIG9wdHMudHJhbnNsYXRpb25bMV0pO1xuICAgIH1cbiAgICBpZiAoIWlzTnVsbE9yVW5kZWYob3B0cy5yb3RhdGlvbikpIHtcbiAgICAgICAgY3R4LnJvdGF0ZShvcHRzLnJvdGF0aW9uKTtcbiAgICB9XG4gICAgaWYgKG9wdHMuY29sb3IpIHtcbiAgICAgICAgY3R4LmZpbGxTdHlsZSA9IG9wdHMuY29sb3I7XG4gICAgfVxuICAgIGlmIChvcHRzLnRleHRBbGlnbikge1xuICAgICAgICBjdHgudGV4dEFsaWduID0gb3B0cy50ZXh0QWxpZ247XG4gICAgfVxuICAgIGlmIChvcHRzLnRleHRCYXNlbGluZSkge1xuICAgICAgICBjdHgudGV4dEJhc2VsaW5lID0gb3B0cy50ZXh0QmFzZWxpbmU7XG4gICAgfVxufVxuZnVuY3Rpb24gZGVjb3JhdGVUZXh0KGN0eCwgeCwgeSwgbGluZSwgb3B0cykge1xuICAgIGlmIChvcHRzLnN0cmlrZXRocm91Z2ggfHwgb3B0cy51bmRlcmxpbmUpIHtcbiAgICAgICAgLyoqXG4gICAgICogTm93IHRoYXQgSUUxMSBzdXBwb3J0IGhhcyBiZWVuIGRyb3BwZWQsIHdlIGNhbiB1c2UgbW9yZVxuICAgICAqIG9mIHRoZSBUZXh0TWV0cmljcyBvYmplY3QuIFRoZSBhY3R1YWwgYm91bmRpbmcgYm94ZXNcbiAgICAgKiBhcmUgdW5mbGFnZ2VkIGluIENocm9tZSwgRmlyZWZveCwgRWRnZSwgYW5kIFNhZmFyaSBzbyB0aGV5XG4gICAgICogY2FuIGJlIHNhZmVseSB1c2VkLlxuICAgICAqIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvVGV4dE1ldHJpY3MjQnJvd3Nlcl9jb21wYXRpYmlsaXR5XG4gICAgICovIGNvbnN0IG1ldHJpY3MgPSBjdHgubWVhc3VyZVRleHQobGluZSk7XG4gICAgICAgIGNvbnN0IGxlZnQgPSB4IC0gbWV0cmljcy5hY3R1YWxCb3VuZGluZ0JveExlZnQ7XG4gICAgICAgIGNvbnN0IHJpZ2h0ID0geCArIG1ldHJpY3MuYWN0dWFsQm91bmRpbmdCb3hSaWdodDtcbiAgICAgICAgY29uc3QgdG9wID0geSAtIG1ldHJpY3MuYWN0dWFsQm91bmRpbmdCb3hBc2NlbnQ7XG4gICAgICAgIGNvbnN0IGJvdHRvbSA9IHkgKyBtZXRyaWNzLmFjdHVhbEJvdW5kaW5nQm94RGVzY2VudDtcbiAgICAgICAgY29uc3QgeURlY29yYXRpb24gPSBvcHRzLnN0cmlrZXRocm91Z2ggPyAodG9wICsgYm90dG9tKSAvIDIgOiBib3R0b207XG4gICAgICAgIGN0eC5zdHJva2VTdHlsZSA9IGN0eC5maWxsU3R5bGU7XG4gICAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgICAgY3R4LmxpbmVXaWR0aCA9IG9wdHMuZGVjb3JhdGlvbldpZHRoIHx8IDI7XG4gICAgICAgIGN0eC5tb3ZlVG8obGVmdCwgeURlY29yYXRpb24pO1xuICAgICAgICBjdHgubGluZVRvKHJpZ2h0LCB5RGVjb3JhdGlvbik7XG4gICAgICAgIGN0eC5zdHJva2UoKTtcbiAgICB9XG59XG5mdW5jdGlvbiBkcmF3QmFja2Ryb3AoY3R4LCBvcHRzKSB7XG4gICAgY29uc3Qgb2xkQ29sb3IgPSBjdHguZmlsbFN0eWxlO1xuICAgIGN0eC5maWxsU3R5bGUgPSBvcHRzLmNvbG9yO1xuICAgIGN0eC5maWxsUmVjdChvcHRzLmxlZnQsIG9wdHMudG9wLCBvcHRzLndpZHRoLCBvcHRzLmhlaWdodCk7XG4gICAgY3R4LmZpbGxTdHlsZSA9IG9sZENvbG9yO1xufVxuLyoqXG4gKiBSZW5kZXIgdGV4dCBvbnRvIHRoZSBjYW52YXNcbiAqLyBmdW5jdGlvbiByZW5kZXJUZXh0KGN0eCwgdGV4dCwgeCwgeSwgZm9udCwgb3B0cyA9IHt9KSB7XG4gICAgY29uc3QgbGluZXMgPSBpc0FycmF5KHRleHQpID8gdGV4dCA6IFtcbiAgICAgICAgdGV4dFxuICAgIF07XG4gICAgY29uc3Qgc3Ryb2tlID0gb3B0cy5zdHJva2VXaWR0aCA+IDAgJiYgb3B0cy5zdHJva2VDb2xvciAhPT0gJyc7XG4gICAgbGV0IGksIGxpbmU7XG4gICAgY3R4LnNhdmUoKTtcbiAgICBjdHguZm9udCA9IGZvbnQuc3RyaW5nO1xuICAgIHNldFJlbmRlck9wdHMoY3R4LCBvcHRzKTtcbiAgICBmb3IoaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7ICsraSl7XG4gICAgICAgIGxpbmUgPSBsaW5lc1tpXTtcbiAgICAgICAgaWYgKG9wdHMuYmFja2Ryb3ApIHtcbiAgICAgICAgICAgIGRyYXdCYWNrZHJvcChjdHgsIG9wdHMuYmFja2Ryb3ApO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdHJva2UpIHtcbiAgICAgICAgICAgIGlmIChvcHRzLnN0cm9rZUNvbG9yKSB7XG4gICAgICAgICAgICAgICAgY3R4LnN0cm9rZVN0eWxlID0gb3B0cy5zdHJva2VDb2xvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghaXNOdWxsT3JVbmRlZihvcHRzLnN0cm9rZVdpZHRoKSkge1xuICAgICAgICAgICAgICAgIGN0eC5saW5lV2lkdGggPSBvcHRzLnN0cm9rZVdpZHRoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY3R4LnN0cm9rZVRleHQobGluZSwgeCwgeSwgb3B0cy5tYXhXaWR0aCk7XG4gICAgICAgIH1cbiAgICAgICAgY3R4LmZpbGxUZXh0KGxpbmUsIHgsIHksIG9wdHMubWF4V2lkdGgpO1xuICAgICAgICBkZWNvcmF0ZVRleHQoY3R4LCB4LCB5LCBsaW5lLCBvcHRzKTtcbiAgICAgICAgeSArPSBOdW1iZXIoZm9udC5saW5lSGVpZ2h0KTtcbiAgICB9XG4gICAgY3R4LnJlc3RvcmUoKTtcbn1cbi8qKlxuICogQWRkIGEgcGF0aCBvZiBhIHJlY3RhbmdsZSB3aXRoIHJvdW5kZWQgY29ybmVycyB0byB0aGUgY3VycmVudCBzdWItcGF0aFxuICogQHBhcmFtIGN0eCAtIENvbnRleHRcbiAqIEBwYXJhbSByZWN0IC0gQm91bmRpbmcgcmVjdFxuICovIGZ1bmN0aW9uIGFkZFJvdW5kZWRSZWN0UGF0aChjdHgsIHJlY3QpIHtcbiAgICBjb25zdCB7IHggLCB5ICwgdyAsIGggLCByYWRpdXMgIH0gPSByZWN0O1xuICAgIC8vIHRvcCBsZWZ0IGFyY1xuICAgIGN0eC5hcmMoeCArIHJhZGl1cy50b3BMZWZ0LCB5ICsgcmFkaXVzLnRvcExlZnQsIHJhZGl1cy50b3BMZWZ0LCAxLjUgKiBQSSwgUEksIHRydWUpO1xuICAgIC8vIGxpbmUgZnJvbSB0b3AgbGVmdCB0byBib3R0b20gbGVmdFxuICAgIGN0eC5saW5lVG8oeCwgeSArIGggLSByYWRpdXMuYm90dG9tTGVmdCk7XG4gICAgLy8gYm90dG9tIGxlZnQgYXJjXG4gICAgY3R4LmFyYyh4ICsgcmFkaXVzLmJvdHRvbUxlZnQsIHkgKyBoIC0gcmFkaXVzLmJvdHRvbUxlZnQsIHJhZGl1cy5ib3R0b21MZWZ0LCBQSSwgSEFMRl9QSSwgdHJ1ZSk7XG4gICAgLy8gbGluZSBmcm9tIGJvdHRvbSBsZWZ0IHRvIGJvdHRvbSByaWdodFxuICAgIGN0eC5saW5lVG8oeCArIHcgLSByYWRpdXMuYm90dG9tUmlnaHQsIHkgKyBoKTtcbiAgICAvLyBib3R0b20gcmlnaHQgYXJjXG4gICAgY3R4LmFyYyh4ICsgdyAtIHJhZGl1cy5ib3R0b21SaWdodCwgeSArIGggLSByYWRpdXMuYm90dG9tUmlnaHQsIHJhZGl1cy5ib3R0b21SaWdodCwgSEFMRl9QSSwgMCwgdHJ1ZSk7XG4gICAgLy8gbGluZSBmcm9tIGJvdHRvbSByaWdodCB0byB0b3AgcmlnaHRcbiAgICBjdHgubGluZVRvKHggKyB3LCB5ICsgcmFkaXVzLnRvcFJpZ2h0KTtcbiAgICAvLyB0b3AgcmlnaHQgYXJjXG4gICAgY3R4LmFyYyh4ICsgdyAtIHJhZGl1cy50b3BSaWdodCwgeSArIHJhZGl1cy50b3BSaWdodCwgcmFkaXVzLnRvcFJpZ2h0LCAwLCAtSEFMRl9QSSwgdHJ1ZSk7XG4gICAgLy8gbGluZSBmcm9tIHRvcCByaWdodCB0byB0b3AgbGVmdFxuICAgIGN0eC5saW5lVG8oeCArIHJhZGl1cy50b3BMZWZ0LCB5KTtcbn1cblxuY29uc3QgTElORV9IRUlHSFQgPSAvXihub3JtYWx8KFxcZCsoPzpcXC5cXGQrKT8pKHB4fGVtfCUpPykkLztcbmNvbnN0IEZPTlRfU1RZTEUgPSAvXihub3JtYWx8aXRhbGljfGluaXRpYWx8aW5oZXJpdHx1bnNldHwob2JsaXF1ZSggLT9bMC05XT9bMC05XWRlZyk/KSkkLztcbi8qKlxuICogQGFsaWFzIENoYXJ0LmhlbHBlcnMub3B0aW9uc1xuICogQG5hbWVzcGFjZVxuICovIC8qKlxuICogQ29udmVydHMgdGhlIGdpdmVuIGxpbmUgaGVpZ2h0IGB2YWx1ZWAgaW4gcGl4ZWxzIGZvciBhIHNwZWNpZmljIGZvbnQgYHNpemVgLlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIGxpbmVIZWlnaHQgdG8gcGFyc2UgKGVnLiAxLjYsICcxNHB4JywgJzc1JScsICcxLjZlbScpLlxuICogQHBhcmFtIHNpemUgLSBUaGUgZm9udCBzaXplIChpbiBwaXhlbHMpIHVzZWQgdG8gcmVzb2x2ZSByZWxhdGl2ZSBgdmFsdWVgLlxuICogQHJldHVybnMgVGhlIGVmZmVjdGl2ZSBsaW5lIGhlaWdodCBpbiBwaXhlbHMgKHNpemUgKiAxLjIgaWYgdmFsdWUgaXMgaW52YWxpZCkuXG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0NTUy9saW5lLWhlaWdodFxuICogQHNpbmNlIDIuNy4wXG4gKi8gZnVuY3Rpb24gdG9MaW5lSGVpZ2h0KHZhbHVlLCBzaXplKSB7XG4gICAgY29uc3QgbWF0Y2hlcyA9ICgnJyArIHZhbHVlKS5tYXRjaChMSU5FX0hFSUdIVCk7XG4gICAgaWYgKCFtYXRjaGVzIHx8IG1hdGNoZXNbMV0gPT09ICdub3JtYWwnKSB7XG4gICAgICAgIHJldHVybiBzaXplICogMS4yO1xuICAgIH1cbiAgICB2YWx1ZSA9ICttYXRjaGVzWzJdO1xuICAgIHN3aXRjaChtYXRjaGVzWzNdKXtcbiAgICAgICAgY2FzZSAncHgnOlxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICBjYXNlICclJzpcbiAgICAgICAgICAgIHZhbHVlIC89IDEwMDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gc2l6ZSAqIHZhbHVlO1xufVxuY29uc3QgbnVtYmVyT3JaZXJvID0gKHYpPT4rdiB8fCAwO1xuZnVuY3Rpb24gX3JlYWRWYWx1ZVRvUHJvcHModmFsdWUsIHByb3BzKSB7XG4gICAgY29uc3QgcmV0ID0ge307XG4gICAgY29uc3Qgb2JqUHJvcHMgPSBpc09iamVjdChwcm9wcyk7XG4gICAgY29uc3Qga2V5cyA9IG9ialByb3BzID8gT2JqZWN0LmtleXMocHJvcHMpIDogcHJvcHM7XG4gICAgY29uc3QgcmVhZCA9IGlzT2JqZWN0KHZhbHVlKSA/IG9ialByb3BzID8gKHByb3ApPT52YWx1ZU9yRGVmYXVsdCh2YWx1ZVtwcm9wXSwgdmFsdWVbcHJvcHNbcHJvcF1dKSA6IChwcm9wKT0+dmFsdWVbcHJvcF0gOiAoKT0+dmFsdWU7XG4gICAgZm9yIChjb25zdCBwcm9wIG9mIGtleXMpe1xuICAgICAgICByZXRbcHJvcF0gPSBudW1iZXJPclplcm8ocmVhZChwcm9wKSk7XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG59XG4vKipcbiAqIENvbnZlcnRzIHRoZSBnaXZlbiB2YWx1ZSBpbnRvIGEgVFJCTCBvYmplY3QuXG4gKiBAcGFyYW0gdmFsdWUgLSBJZiBhIG51bWJlciwgc2V0IHRoZSB2YWx1ZSB0byBhbGwgVFJCTCBjb21wb25lbnQsXG4gKiAgZWxzZSwgaWYgYW4gb2JqZWN0LCB1c2UgZGVmaW5lZCBwcm9wZXJ0aWVzIGFuZCBzZXRzIHVuZGVmaW5lZCBvbmVzIHRvIDAuXG4gKiAgeCAvIHkgYXJlIHNob3J0aGFuZHMgZm9yIHNhbWUgdmFsdWUgZm9yIGxlZnQvcmlnaHQgYW5kIHRvcC9ib3R0b20uXG4gKiBAcmV0dXJucyBUaGUgcGFkZGluZyB2YWx1ZXMgKHRvcCwgcmlnaHQsIGJvdHRvbSwgbGVmdClcbiAqIEBzaW5jZSAzLjAuMFxuICovIGZ1bmN0aW9uIHRvVFJCTCh2YWx1ZSkge1xuICAgIHJldHVybiBfcmVhZFZhbHVlVG9Qcm9wcyh2YWx1ZSwge1xuICAgICAgICB0b3A6ICd5JyxcbiAgICAgICAgcmlnaHQ6ICd4JyxcbiAgICAgICAgYm90dG9tOiAneScsXG4gICAgICAgIGxlZnQ6ICd4J1xuICAgIH0pO1xufVxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgZ2l2ZW4gdmFsdWUgaW50byBhIFRSQkwgY29ybmVycyBvYmplY3QgKHNpbWlsYXIgd2l0aCBjc3MgYm9yZGVyLXJhZGl1cykuXG4gKiBAcGFyYW0gdmFsdWUgLSBJZiBhIG51bWJlciwgc2V0IHRoZSB2YWx1ZSB0byBhbGwgVFJCTCBjb3JuZXIgY29tcG9uZW50cyxcbiAqICBlbHNlLCBpZiBhbiBvYmplY3QsIHVzZSBkZWZpbmVkIHByb3BlcnRpZXMgYW5kIHNldHMgdW5kZWZpbmVkIG9uZXMgdG8gMC5cbiAqIEByZXR1cm5zIFRoZSBUUkJMIGNvcm5lciB2YWx1ZXMgKHRvcExlZnQsIHRvcFJpZ2h0LCBib3R0b21MZWZ0LCBib3R0b21SaWdodClcbiAqIEBzaW5jZSAzLjAuMFxuICovIGZ1bmN0aW9uIHRvVFJCTENvcm5lcnModmFsdWUpIHtcbiAgICByZXR1cm4gX3JlYWRWYWx1ZVRvUHJvcHModmFsdWUsIFtcbiAgICAgICAgJ3RvcExlZnQnLFxuICAgICAgICAndG9wUmlnaHQnLFxuICAgICAgICAnYm90dG9tTGVmdCcsXG4gICAgICAgICdib3R0b21SaWdodCdcbiAgICBdKTtcbn1cbi8qKlxuICogQ29udmVydHMgdGhlIGdpdmVuIHZhbHVlIGludG8gYSBwYWRkaW5nIG9iamVjdCB3aXRoIHByZS1jb21wdXRlZCB3aWR0aC9oZWlnaHQuXG4gKiBAcGFyYW0gdmFsdWUgLSBJZiBhIG51bWJlciwgc2V0IHRoZSB2YWx1ZSB0byBhbGwgVFJCTCBjb21wb25lbnQsXG4gKiAgZWxzZSwgaWYgYW4gb2JqZWN0LCB1c2UgZGVmaW5lZCBwcm9wZXJ0aWVzIGFuZCBzZXRzIHVuZGVmaW5lZCBvbmVzIHRvIDAuXG4gKiAgeCAvIHkgYXJlIHNob3J0aGFuZHMgZm9yIHNhbWUgdmFsdWUgZm9yIGxlZnQvcmlnaHQgYW5kIHRvcC9ib3R0b20uXG4gKiBAcmV0dXJucyBUaGUgcGFkZGluZyB2YWx1ZXMgKHRvcCwgcmlnaHQsIGJvdHRvbSwgbGVmdCwgd2lkdGgsIGhlaWdodClcbiAqIEBzaW5jZSAyLjcuMFxuICovIGZ1bmN0aW9uIHRvUGFkZGluZyh2YWx1ZSkge1xuICAgIGNvbnN0IG9iaiA9IHRvVFJCTCh2YWx1ZSk7XG4gICAgb2JqLndpZHRoID0gb2JqLmxlZnQgKyBvYmoucmlnaHQ7XG4gICAgb2JqLmhlaWdodCA9IG9iai50b3AgKyBvYmouYm90dG9tO1xuICAgIHJldHVybiBvYmo7XG59XG4vKipcbiAqIFBhcnNlcyBmb250IG9wdGlvbnMgYW5kIHJldHVybnMgdGhlIGZvbnQgb2JqZWN0LlxuICogQHBhcmFtIG9wdGlvbnMgLSBBIG9iamVjdCB0aGF0IGNvbnRhaW5zIGZvbnQgb3B0aW9ucyB0byBiZSBwYXJzZWQuXG4gKiBAcGFyYW0gZmFsbGJhY2sgLSBBIG9iamVjdCB0aGF0IGNvbnRhaW5zIGZhbGxiYWNrIGZvbnQgb3B0aW9ucy5cbiAqIEByZXR1cm4gVGhlIGZvbnQgb2JqZWN0LlxuICogQHByaXZhdGVcbiAqLyBmdW5jdGlvbiB0b0ZvbnQob3B0aW9ucywgZmFsbGJhY2spIHtcbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgICBmYWxsYmFjayA9IGZhbGxiYWNrIHx8IGRlZmF1bHRzLmZvbnQ7XG4gICAgbGV0IHNpemUgPSB2YWx1ZU9yRGVmYXVsdChvcHRpb25zLnNpemUsIGZhbGxiYWNrLnNpemUpO1xuICAgIGlmICh0eXBlb2Ygc2l6ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgc2l6ZSA9IHBhcnNlSW50KHNpemUsIDEwKTtcbiAgICB9XG4gICAgbGV0IHN0eWxlID0gdmFsdWVPckRlZmF1bHQob3B0aW9ucy5zdHlsZSwgZmFsbGJhY2suc3R5bGUpO1xuICAgIGlmIChzdHlsZSAmJiAhKCcnICsgc3R5bGUpLm1hdGNoKEZPTlRfU1RZTEUpKSB7XG4gICAgICAgIGNvbnNvbGUud2FybignSW52YWxpZCBmb250IHN0eWxlIHNwZWNpZmllZDogXCInICsgc3R5bGUgKyAnXCInKTtcbiAgICAgICAgc3R5bGUgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGNvbnN0IGZvbnQgPSB7XG4gICAgICAgIGZhbWlseTogdmFsdWVPckRlZmF1bHQob3B0aW9ucy5mYW1pbHksIGZhbGxiYWNrLmZhbWlseSksXG4gICAgICAgIGxpbmVIZWlnaHQ6IHRvTGluZUhlaWdodCh2YWx1ZU9yRGVmYXVsdChvcHRpb25zLmxpbmVIZWlnaHQsIGZhbGxiYWNrLmxpbmVIZWlnaHQpLCBzaXplKSxcbiAgICAgICAgc2l6ZSxcbiAgICAgICAgc3R5bGUsXG4gICAgICAgIHdlaWdodDogdmFsdWVPckRlZmF1bHQob3B0aW9ucy53ZWlnaHQsIGZhbGxiYWNrLndlaWdodCksXG4gICAgICAgIHN0cmluZzogJydcbiAgICB9O1xuICAgIGZvbnQuc3RyaW5nID0gdG9Gb250U3RyaW5nKGZvbnQpO1xuICAgIHJldHVybiBmb250O1xufVxuLyoqXG4gKiBFdmFsdWF0ZXMgdGhlIGdpdmVuIGBpbnB1dHNgIHNlcXVlbnRpYWxseSBhbmQgcmV0dXJucyB0aGUgZmlyc3QgZGVmaW5lZCB2YWx1ZS5cbiAqIEBwYXJhbSBpbnB1dHMgLSBBbiBhcnJheSBvZiB2YWx1ZXMsIGZhbGxpbmcgYmFjayB0byB0aGUgbGFzdCB2YWx1ZS5cbiAqIEBwYXJhbSBjb250ZXh0IC0gSWYgZGVmaW5lZCBhbmQgdGhlIGN1cnJlbnQgdmFsdWUgaXMgYSBmdW5jdGlvbiwgdGhlIHZhbHVlXG4gKiBpcyBjYWxsZWQgd2l0aCBgY29udGV4dGAgYXMgZmlyc3QgYXJndW1lbnQgYW5kIHRoZSByZXN1bHQgYmVjb21lcyB0aGUgbmV3IGlucHV0LlxuICogQHBhcmFtIGluZGV4IC0gSWYgZGVmaW5lZCBhbmQgdGhlIGN1cnJlbnQgdmFsdWUgaXMgYW4gYXJyYXksIHRoZSB2YWx1ZVxuICogYXQgYGluZGV4YCBiZWNvbWUgdGhlIG5ldyBpbnB1dC5cbiAqIEBwYXJhbSBpbmZvIC0gb2JqZWN0IHRvIHJldHVybiBpbmZvcm1hdGlvbiBhYm91dCByZXNvbHV0aW9uIGluXG4gKiBAcGFyYW0gaW5mby5jYWNoZWFibGUgLSBXaWxsIGJlIHNldCB0byBgZmFsc2VgIGlmIG9wdGlvbiBpcyBub3QgY2FjaGVhYmxlLlxuICogQHNpbmNlIDIuNy4wXG4gKi8gZnVuY3Rpb24gcmVzb2x2ZShpbnB1dHMsIGNvbnRleHQsIGluZGV4LCBpbmZvKSB7XG4gICAgbGV0IGNhY2hlYWJsZSA9IHRydWU7XG4gICAgbGV0IGksIGlsZW4sIHZhbHVlO1xuICAgIGZvcihpID0gMCwgaWxlbiA9IGlucHV0cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpe1xuICAgICAgICB2YWx1ZSA9IGlucHV0c1tpXTtcbiAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb250ZXh0ICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHZhbHVlKGNvbnRleHQpO1xuICAgICAgICAgICAgY2FjaGVhYmxlID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGluZGV4ICE9PSB1bmRlZmluZWQgJiYgaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHZhbHVlID0gdmFsdWVbaW5kZXggJSB2YWx1ZS5sZW5ndGhdO1xuICAgICAgICAgICAgY2FjaGVhYmxlID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGlmIChpbmZvICYmICFjYWNoZWFibGUpIHtcbiAgICAgICAgICAgICAgICBpbmZvLmNhY2hlYWJsZSA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgfVxufVxuLyoqXG4gKiBAcGFyYW0gbWlubWF4XG4gKiBAcGFyYW0gZ3JhY2VcbiAqIEBwYXJhbSBiZWdpbkF0WmVyb1xuICogQHByaXZhdGVcbiAqLyBmdW5jdGlvbiBfYWRkR3JhY2UobWlubWF4LCBncmFjZSwgYmVnaW5BdFplcm8pIHtcbiAgICBjb25zdCB7IG1pbiAsIG1heCAgfSA9IG1pbm1heDtcbiAgICBjb25zdCBjaGFuZ2UgPSB0b0RpbWVuc2lvbihncmFjZSwgKG1heCAtIG1pbikgLyAyKTtcbiAgICBjb25zdCBrZWVwWmVybyA9ICh2YWx1ZSwgYWRkKT0+YmVnaW5BdFplcm8gJiYgdmFsdWUgPT09IDAgPyAwIDogdmFsdWUgKyBhZGQ7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbWluOiBrZWVwWmVybyhtaW4sIC1NYXRoLmFicyhjaGFuZ2UpKSxcbiAgICAgICAgbWF4OiBrZWVwWmVybyhtYXgsIGNoYW5nZSlcbiAgICB9O1xufVxuZnVuY3Rpb24gY3JlYXRlQ29udGV4dChwYXJlbnRDb250ZXh0LCBjb250ZXh0KSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oT2JqZWN0LmNyZWF0ZShwYXJlbnRDb250ZXh0KSwgY29udGV4dCk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIFByb3h5IGZvciByZXNvbHZpbmcgcmF3IHZhbHVlcyBmb3Igb3B0aW9ucy5cbiAqIEBwYXJhbSBzY29wZXMgLSBUaGUgb3B0aW9uIHNjb3BlcyB0byBsb29rIGZvciB2YWx1ZXMsIGluIHJlc29sdXRpb24gb3JkZXJcbiAqIEBwYXJhbSBwcmVmaXhlcyAtIFRoZSBwcmVmaXhlcyBmb3IgdmFsdWVzLCBpbiByZXNvbHV0aW9uIG9yZGVyLlxuICogQHBhcmFtIHJvb3RTY29wZXMgLSBUaGUgcm9vdCBvcHRpb24gc2NvcGVzXG4gKiBAcGFyYW0gZmFsbGJhY2sgLSBQYXJlbnQgc2NvcGVzIGZhbGxiYWNrXG4gKiBAcGFyYW0gZ2V0VGFyZ2V0IC0gY2FsbGJhY2sgZm9yIGdldHRpbmcgdGhlIHRhcmdldCBmb3IgY2hhbmdlZCB2YWx1ZXNcbiAqIEByZXR1cm5zIFByb3h5XG4gKiBAcHJpdmF0ZVxuICovIGZ1bmN0aW9uIF9jcmVhdGVSZXNvbHZlcihzY29wZXMsIHByZWZpeGVzID0gW1xuICAgICcnXG5dLCByb290U2NvcGVzLCBmYWxsYmFjaywgZ2V0VGFyZ2V0ID0gKCk9PnNjb3Blc1swXSkge1xuICAgIGNvbnN0IGZpbmFsUm9vdFNjb3BlcyA9IHJvb3RTY29wZXMgfHwgc2NvcGVzO1xuICAgIGlmICh0eXBlb2YgZmFsbGJhY2sgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGZhbGxiYWNrID0gX3Jlc29sdmUoJ19mYWxsYmFjaycsIHNjb3Blcyk7XG4gICAgfVxuICAgIGNvbnN0IGNhY2hlID0ge1xuICAgICAgICBbU3ltYm9sLnRvU3RyaW5nVGFnXTogJ09iamVjdCcsXG4gICAgICAgIF9jYWNoZWFibGU6IHRydWUsXG4gICAgICAgIF9zY29wZXM6IHNjb3BlcyxcbiAgICAgICAgX3Jvb3RTY29wZXM6IGZpbmFsUm9vdFNjb3BlcyxcbiAgICAgICAgX2ZhbGxiYWNrOiBmYWxsYmFjayxcbiAgICAgICAgX2dldFRhcmdldDogZ2V0VGFyZ2V0LFxuICAgICAgICBvdmVycmlkZTogKHNjb3BlKT0+X2NyZWF0ZVJlc29sdmVyKFtcbiAgICAgICAgICAgICAgICBzY29wZSxcbiAgICAgICAgICAgICAgICAuLi5zY29wZXNcbiAgICAgICAgICAgIF0sIHByZWZpeGVzLCBmaW5hbFJvb3RTY29wZXMsIGZhbGxiYWNrKVxuICAgIH07XG4gICAgcmV0dXJuIG5ldyBQcm94eShjYWNoZSwge1xuICAgICAgICAvKipcbiAgICAgKiBBIHRyYXAgZm9yIHRoZSBkZWxldGUgb3BlcmF0b3IuXG4gICAgICovIGRlbGV0ZVByb3BlcnR5ICh0YXJnZXQsIHByb3ApIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0YXJnZXRbcHJvcF07IC8vIHJlbW92ZSBmcm9tIGNhY2hlXG4gICAgICAgICAgICBkZWxldGUgdGFyZ2V0Ll9rZXlzOyAvLyByZW1vdmUgY2FjaGVkIGtleXNcbiAgICAgICAgICAgIGRlbGV0ZSBzY29wZXNbMF1bcHJvcF07IC8vIHJlbW92ZSBmcm9tIHRvcCBsZXZlbCBzY29wZVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0sXG4gICAgICAgIC8qKlxuICAgICAqIEEgdHJhcCBmb3IgZ2V0dGluZyBwcm9wZXJ0eSB2YWx1ZXMuXG4gICAgICovIGdldCAodGFyZ2V0LCBwcm9wKSB7XG4gICAgICAgICAgICByZXR1cm4gX2NhY2hlZCh0YXJnZXQsIHByb3AsICgpPT5fcmVzb2x2ZVdpdGhQcmVmaXhlcyhwcm9wLCBwcmVmaXhlcywgc2NvcGVzLCB0YXJnZXQpKTtcbiAgICAgICAgfSxcbiAgICAgICAgLyoqXG4gICAgICogQSB0cmFwIGZvciBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yLlxuICAgICAqIEFsc28gdXNlZCBieSBPYmplY3QuaGFzT3duUHJvcGVydHkuXG4gICAgICovIGdldE93blByb3BlcnR5RGVzY3JpcHRvciAodGFyZ2V0LCBwcm9wKSB7XG4gICAgICAgICAgICByZXR1cm4gUmVmbGVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0Ll9zY29wZXNbMF0sIHByb3ApO1xuICAgICAgICB9LFxuICAgICAgICAvKipcbiAgICAgKiBBIHRyYXAgZm9yIE9iamVjdC5nZXRQcm90b3R5cGVPZi5cbiAgICAgKi8gZ2V0UHJvdG90eXBlT2YgKCkge1xuICAgICAgICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0UHJvdG90eXBlT2Yoc2NvcGVzWzBdKTtcbiAgICAgICAgfSxcbiAgICAgICAgLyoqXG4gICAgICogQSB0cmFwIGZvciB0aGUgaW4gb3BlcmF0b3IuXG4gICAgICovIGhhcyAodGFyZ2V0LCBwcm9wKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0S2V5c0Zyb21BbGxTY29wZXModGFyZ2V0KS5pbmNsdWRlcyhwcm9wKTtcbiAgICAgICAgfSxcbiAgICAgICAgLyoqXG4gICAgICogQSB0cmFwIGZvciBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyBhbmQgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scy5cbiAgICAgKi8gb3duS2V5cyAodGFyZ2V0KSB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0S2V5c0Zyb21BbGxTY29wZXModGFyZ2V0KTtcbiAgICAgICAgfSxcbiAgICAgICAgLyoqXG4gICAgICogQSB0cmFwIGZvciBzZXR0aW5nIHByb3BlcnR5IHZhbHVlcy5cbiAgICAgKi8gc2V0ICh0YXJnZXQsIHByb3AsIHZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCBzdG9yYWdlID0gdGFyZ2V0Ll9zdG9yYWdlIHx8ICh0YXJnZXQuX3N0b3JhZ2UgPSBnZXRUYXJnZXQoKSk7XG4gICAgICAgICAgICB0YXJnZXRbcHJvcF0gPSBzdG9yYWdlW3Byb3BdID0gdmFsdWU7IC8vIHNldCB0byB0b3AgbGV2ZWwgc2NvcGUgKyBjYWNoZVxuICAgICAgICAgICAgZGVsZXRlIHRhcmdldC5fa2V5czsgLy8gcmVtb3ZlIGNhY2hlZCBrZXlzXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuLyoqXG4gKiBSZXR1cm5zIGFuIFByb3h5IGZvciByZXNvbHZpbmcgb3B0aW9uIHZhbHVlcyB3aXRoIGNvbnRleHQuXG4gKiBAcGFyYW0gcHJveHkgLSBUaGUgUHJveHkgcmV0dXJuZWQgYnkgYF9jcmVhdGVSZXNvbHZlcmBcbiAqIEBwYXJhbSBjb250ZXh0IC0gQ29udGV4dCBvYmplY3QgZm9yIHNjcmlwdGFibGUvaW5kZXhhYmxlIG9wdGlvbnNcbiAqIEBwYXJhbSBzdWJQcm94eSAtIFRoZSBwcm94eSBwcm92aWRlZCBmb3Igc2NyaXB0YWJsZSBvcHRpb25zXG4gKiBAcGFyYW0gZGVzY3JpcHRvckRlZmF1bHRzIC0gRGVmYXVsdHMgZm9yIGRlc2NyaXB0b3JzXG4gKiBAcHJpdmF0ZVxuICovIGZ1bmN0aW9uIF9hdHRhY2hDb250ZXh0KHByb3h5LCBjb250ZXh0LCBzdWJQcm94eSwgZGVzY3JpcHRvckRlZmF1bHRzKSB7XG4gICAgY29uc3QgY2FjaGUgPSB7XG4gICAgICAgIF9jYWNoZWFibGU6IGZhbHNlLFxuICAgICAgICBfcHJveHk6IHByb3h5LFxuICAgICAgICBfY29udGV4dDogY29udGV4dCxcbiAgICAgICAgX3N1YlByb3h5OiBzdWJQcm94eSxcbiAgICAgICAgX3N0YWNrOiBuZXcgU2V0KCksXG4gICAgICAgIF9kZXNjcmlwdG9yczogX2Rlc2NyaXB0b3JzKHByb3h5LCBkZXNjcmlwdG9yRGVmYXVsdHMpLFxuICAgICAgICBzZXRDb250ZXh0OiAoY3R4KT0+X2F0dGFjaENvbnRleHQocHJveHksIGN0eCwgc3ViUHJveHksIGRlc2NyaXB0b3JEZWZhdWx0cyksXG4gICAgICAgIG92ZXJyaWRlOiAoc2NvcGUpPT5fYXR0YWNoQ29udGV4dChwcm94eS5vdmVycmlkZShzY29wZSksIGNvbnRleHQsIHN1YlByb3h5LCBkZXNjcmlwdG9yRGVmYXVsdHMpXG4gICAgfTtcbiAgICByZXR1cm4gbmV3IFByb3h5KGNhY2hlLCB7XG4gICAgICAgIC8qKlxuICAgICAqIEEgdHJhcCBmb3IgdGhlIGRlbGV0ZSBvcGVyYXRvci5cbiAgICAgKi8gZGVsZXRlUHJvcGVydHkgKHRhcmdldCwgcHJvcCkge1xuICAgICAgICAgICAgZGVsZXRlIHRhcmdldFtwcm9wXTsgLy8gcmVtb3ZlIGZyb20gY2FjaGVcbiAgICAgICAgICAgIGRlbGV0ZSBwcm94eVtwcm9wXTsgLy8gcmVtb3ZlIGZyb20gcHJveHlcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9LFxuICAgICAgICAvKipcbiAgICAgKiBBIHRyYXAgZm9yIGdldHRpbmcgcHJvcGVydHkgdmFsdWVzLlxuICAgICAqLyBnZXQgKHRhcmdldCwgcHJvcCwgcmVjZWl2ZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBfY2FjaGVkKHRhcmdldCwgcHJvcCwgKCk9Pl9yZXNvbHZlV2l0aENvbnRleHQodGFyZ2V0LCBwcm9wLCByZWNlaXZlcikpO1xuICAgICAgICB9LFxuICAgICAgICAvKipcbiAgICAgKiBBIHRyYXAgZm9yIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IuXG4gICAgICogQWxzbyB1c2VkIGJ5IE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5cbiAgICAgKi8gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yICh0YXJnZXQsIHByb3ApIHtcbiAgICAgICAgICAgIHJldHVybiB0YXJnZXQuX2Rlc2NyaXB0b3JzLmFsbEtleXMgPyBSZWZsZWN0Lmhhcyhwcm94eSwgcHJvcCkgPyB7XG4gICAgICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgICAgICAgIH0gOiB1bmRlZmluZWQgOiBSZWZsZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihwcm94eSwgcHJvcCk7XG4gICAgICAgIH0sXG4gICAgICAgIC8qKlxuICAgICAqIEEgdHJhcCBmb3IgT2JqZWN0LmdldFByb3RvdHlwZU9mLlxuICAgICAqLyBnZXRQcm90b3R5cGVPZiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gUmVmbGVjdC5nZXRQcm90b3R5cGVPZihwcm94eSk7XG4gICAgICAgIH0sXG4gICAgICAgIC8qKlxuICAgICAqIEEgdHJhcCBmb3IgdGhlIGluIG9wZXJhdG9yLlxuICAgICAqLyBoYXMgKHRhcmdldCwgcHJvcCkge1xuICAgICAgICAgICAgcmV0dXJuIFJlZmxlY3QuaGFzKHByb3h5LCBwcm9wKTtcbiAgICAgICAgfSxcbiAgICAgICAgLyoqXG4gICAgICogQSB0cmFwIGZvciBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyBhbmQgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scy5cbiAgICAgKi8gb3duS2V5cyAoKSB7XG4gICAgICAgICAgICByZXR1cm4gUmVmbGVjdC5vd25LZXlzKHByb3h5KTtcbiAgICAgICAgfSxcbiAgICAgICAgLyoqXG4gICAgICogQSB0cmFwIGZvciBzZXR0aW5nIHByb3BlcnR5IHZhbHVlcy5cbiAgICAgKi8gc2V0ICh0YXJnZXQsIHByb3AsIHZhbHVlKSB7XG4gICAgICAgICAgICBwcm94eVtwcm9wXSA9IHZhbHVlOyAvLyBzZXQgdG8gcHJveHlcbiAgICAgICAgICAgIGRlbGV0ZSB0YXJnZXRbcHJvcF07IC8vIHJlbW92ZSBmcm9tIGNhY2hlXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuLyoqXG4gKiBAcHJpdmF0ZVxuICovIGZ1bmN0aW9uIF9kZXNjcmlwdG9ycyhwcm94eSwgZGVmYXVsdHMgPSB7XG4gICAgc2NyaXB0YWJsZTogdHJ1ZSxcbiAgICBpbmRleGFibGU6IHRydWVcbn0pIHtcbiAgICBjb25zdCB7IF9zY3JpcHRhYmxlID1kZWZhdWx0cy5zY3JpcHRhYmxlICwgX2luZGV4YWJsZSA9ZGVmYXVsdHMuaW5kZXhhYmxlICwgX2FsbEtleXMgPWRlZmF1bHRzLmFsbEtleXMgIH0gPSBwcm94eTtcbiAgICByZXR1cm4ge1xuICAgICAgICBhbGxLZXlzOiBfYWxsS2V5cyxcbiAgICAgICAgc2NyaXB0YWJsZTogX3NjcmlwdGFibGUsXG4gICAgICAgIGluZGV4YWJsZTogX2luZGV4YWJsZSxcbiAgICAgICAgaXNTY3JpcHRhYmxlOiBpc0Z1bmN0aW9uKF9zY3JpcHRhYmxlKSA/IF9zY3JpcHRhYmxlIDogKCk9Pl9zY3JpcHRhYmxlLFxuICAgICAgICBpc0luZGV4YWJsZTogaXNGdW5jdGlvbihfaW5kZXhhYmxlKSA/IF9pbmRleGFibGUgOiAoKT0+X2luZGV4YWJsZVxuICAgIH07XG59XG5jb25zdCByZWFkS2V5ID0gKHByZWZpeCwgbmFtZSk9PnByZWZpeCA/IHByZWZpeCArIF9jYXBpdGFsaXplKG5hbWUpIDogbmFtZTtcbmNvbnN0IG5lZWRzU3ViUmVzb2x2ZXIgPSAocHJvcCwgdmFsdWUpPT5pc09iamVjdCh2YWx1ZSkgJiYgcHJvcCAhPT0gJ2FkYXB0ZXJzJyAmJiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKHZhbHVlKSA9PT0gbnVsbCB8fCB2YWx1ZS5jb25zdHJ1Y3RvciA9PT0gT2JqZWN0KTtcbmZ1bmN0aW9uIF9jYWNoZWQodGFyZ2V0LCBwcm9wLCByZXNvbHZlKSB7XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0YXJnZXQsIHByb3ApIHx8IHByb3AgPT09ICdjb25zdHJ1Y3RvcicpIHtcbiAgICAgICAgcmV0dXJuIHRhcmdldFtwcm9wXTtcbiAgICB9XG4gICAgY29uc3QgdmFsdWUgPSByZXNvbHZlKCk7XG4gICAgLy8gY2FjaGUgdGhlIHJlc29sdmVkIHZhbHVlXG4gICAgdGFyZ2V0W3Byb3BdID0gdmFsdWU7XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuZnVuY3Rpb24gX3Jlc29sdmVXaXRoQ29udGV4dCh0YXJnZXQsIHByb3AsIHJlY2VpdmVyKSB7XG4gICAgY29uc3QgeyBfcHJveHkgLCBfY29udGV4dCAsIF9zdWJQcm94eSAsIF9kZXNjcmlwdG9yczogZGVzY3JpcHRvcnMgIH0gPSB0YXJnZXQ7XG4gICAgbGV0IHZhbHVlID0gX3Byb3h5W3Byb3BdOyAvLyByZXNvbHZlIGZyb20gcHJveHlcbiAgICAvLyByZXNvbHZlIHdpdGggY29udGV4dFxuICAgIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSAmJiBkZXNjcmlwdG9ycy5pc1NjcmlwdGFibGUocHJvcCkpIHtcbiAgICAgICAgdmFsdWUgPSBfcmVzb2x2ZVNjcmlwdGFibGUocHJvcCwgdmFsdWUsIHRhcmdldCwgcmVjZWl2ZXIpO1xuICAgIH1cbiAgICBpZiAoaXNBcnJheSh2YWx1ZSkgJiYgdmFsdWUubGVuZ3RoKSB7XG4gICAgICAgIHZhbHVlID0gX3Jlc29sdmVBcnJheShwcm9wLCB2YWx1ZSwgdGFyZ2V0LCBkZXNjcmlwdG9ycy5pc0luZGV4YWJsZSk7XG4gICAgfVxuICAgIGlmIChuZWVkc1N1YlJlc29sdmVyKHByb3AsIHZhbHVlKSkge1xuICAgICAgICAvLyBpZiB0aGUgcmVzb2x2ZWQgdmFsdWUgaXMgYW4gb2JqZWN0LCBjcmVhdGUgYSBzdWIgcmVzb2x2ZXIgZm9yIGl0XG4gICAgICAgIHZhbHVlID0gX2F0dGFjaENvbnRleHQodmFsdWUsIF9jb250ZXh0LCBfc3ViUHJveHkgJiYgX3N1YlByb3h5W3Byb3BdLCBkZXNjcmlwdG9ycyk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbn1cbmZ1bmN0aW9uIF9yZXNvbHZlU2NyaXB0YWJsZShwcm9wLCBnZXRWYWx1ZSwgdGFyZ2V0LCByZWNlaXZlcikge1xuICAgIGNvbnN0IHsgX3Byb3h5ICwgX2NvbnRleHQgLCBfc3ViUHJveHkgLCBfc3RhY2sgIH0gPSB0YXJnZXQ7XG4gICAgaWYgKF9zdGFjay5oYXMocHJvcCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZWN1cnNpb24gZGV0ZWN0ZWQ6ICcgKyBBcnJheS5mcm9tKF9zdGFjaykuam9pbignLT4nKSArICctPicgKyBwcm9wKTtcbiAgICB9XG4gICAgX3N0YWNrLmFkZChwcm9wKTtcbiAgICBsZXQgdmFsdWUgPSBnZXRWYWx1ZShfY29udGV4dCwgX3N1YlByb3h5IHx8IHJlY2VpdmVyKTtcbiAgICBfc3RhY2suZGVsZXRlKHByb3ApO1xuICAgIGlmIChuZWVkc1N1YlJlc29sdmVyKHByb3AsIHZhbHVlKSkge1xuICAgICAgICAvLyBXaGVuIHNjcmlwdGFibGUgb3B0aW9uIHJldHVybnMgYW4gb2JqZWN0LCBjcmVhdGUgYSByZXNvbHZlciBvbiB0aGF0LlxuICAgICAgICB2YWx1ZSA9IGNyZWF0ZVN1YlJlc29sdmVyKF9wcm94eS5fc2NvcGVzLCBfcHJveHksIHByb3AsIHZhbHVlKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuZnVuY3Rpb24gX3Jlc29sdmVBcnJheShwcm9wLCB2YWx1ZSwgdGFyZ2V0LCBpc0luZGV4YWJsZSkge1xuICAgIGNvbnN0IHsgX3Byb3h5ICwgX2NvbnRleHQgLCBfc3ViUHJveHkgLCBfZGVzY3JpcHRvcnM6IGRlc2NyaXB0b3JzICB9ID0gdGFyZ2V0O1xuICAgIGlmICh0eXBlb2YgX2NvbnRleHQuaW5kZXggIT09ICd1bmRlZmluZWQnICYmIGlzSW5kZXhhYmxlKHByb3ApKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZVtfY29udGV4dC5pbmRleCAlIHZhbHVlLmxlbmd0aF07XG4gICAgfSBlbHNlIGlmIChpc09iamVjdCh2YWx1ZVswXSkpIHtcbiAgICAgICAgLy8gQXJyYXkgb2Ygb2JqZWN0cywgcmV0dXJuIGFycmF5IG9yIHJlc29sdmVyc1xuICAgICAgICBjb25zdCBhcnIgPSB2YWx1ZTtcbiAgICAgICAgY29uc3Qgc2NvcGVzID0gX3Byb3h5Ll9zY29wZXMuZmlsdGVyKChzKT0+cyAhPT0gYXJyKTtcbiAgICAgICAgdmFsdWUgPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGFycil7XG4gICAgICAgICAgICBjb25zdCByZXNvbHZlciA9IGNyZWF0ZVN1YlJlc29sdmVyKHNjb3BlcywgX3Byb3h5LCBwcm9wLCBpdGVtKTtcbiAgICAgICAgICAgIHZhbHVlLnB1c2goX2F0dGFjaENvbnRleHQocmVzb2x2ZXIsIF9jb250ZXh0LCBfc3ViUHJveHkgJiYgX3N1YlByb3h5W3Byb3BdLCBkZXNjcmlwdG9ycykpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbn1cbmZ1bmN0aW9uIHJlc29sdmVGYWxsYmFjayhmYWxsYmFjaywgcHJvcCwgdmFsdWUpIHtcbiAgICByZXR1cm4gaXNGdW5jdGlvbihmYWxsYmFjaykgPyBmYWxsYmFjayhwcm9wLCB2YWx1ZSkgOiBmYWxsYmFjaztcbn1cbmNvbnN0IGdldFNjb3BlID0gKGtleSwgcGFyZW50KT0+a2V5ID09PSB0cnVlID8gcGFyZW50IDogdHlwZW9mIGtleSA9PT0gJ3N0cmluZycgPyByZXNvbHZlT2JqZWN0S2V5KHBhcmVudCwga2V5KSA6IHVuZGVmaW5lZDtcbmZ1bmN0aW9uIGFkZFNjb3BlcyhzZXQsIHBhcmVudFNjb3Blcywga2V5LCBwYXJlbnRGYWxsYmFjaywgdmFsdWUpIHtcbiAgICBmb3IgKGNvbnN0IHBhcmVudCBvZiBwYXJlbnRTY29wZXMpe1xuICAgICAgICBjb25zdCBzY29wZSA9IGdldFNjb3BlKGtleSwgcGFyZW50KTtcbiAgICAgICAgaWYgKHNjb3BlKSB7XG4gICAgICAgICAgICBzZXQuYWRkKHNjb3BlKTtcbiAgICAgICAgICAgIGNvbnN0IGZhbGxiYWNrID0gcmVzb2x2ZUZhbGxiYWNrKHNjb3BlLl9mYWxsYmFjaywga2V5LCB2YWx1ZSk7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGZhbGxiYWNrICE9PSAndW5kZWZpbmVkJyAmJiBmYWxsYmFjayAhPT0ga2V5ICYmIGZhbGxiYWNrICE9PSBwYXJlbnRGYWxsYmFjaykge1xuICAgICAgICAgICAgICAgIC8vIFdoZW4gd2UgcmVhY2ggdGhlIGRlc2NyaXB0b3IgdGhhdCBkZWZpbmVzIGEgbmV3IF9mYWxsYmFjaywgcmV0dXJuIHRoYXQuXG4gICAgICAgICAgICAgICAgLy8gVGhlIGZhbGxiYWNrIHdpbGwgcmVzdW1lIHRvIHRoYXQgbmV3IHNjb3BlLlxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxsYmFjaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChzY29wZSA9PT0gZmFsc2UgJiYgdHlwZW9mIHBhcmVudEZhbGxiYWNrICE9PSAndW5kZWZpbmVkJyAmJiBrZXkgIT09IHBhcmVudEZhbGxiYWNrKSB7XG4gICAgICAgICAgICAvLyBGYWxsYmFjayB0byBgZmFsc2VgIHJlc3VsdHMgdG8gYGZhbHNlYCwgd2hlbiBmYWxsaW5nIGJhY2sgdG8gZGlmZmVyZW50IGtleS5cbiAgICAgICAgICAgIC8vIEZvciBleGFtcGxlIGBpbnRlcmFjdGlvbmAgZnJvbSBgaG92ZXJgIG9yIGBwbHVnaW5zLnRvb2x0aXBgIGFuZCBgYW5pbWF0aW9uYCBmcm9tIGBhbmltYXRpb25zYFxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuZnVuY3Rpb24gY3JlYXRlU3ViUmVzb2x2ZXIocGFyZW50U2NvcGVzLCByZXNvbHZlciwgcHJvcCwgdmFsdWUpIHtcbiAgICBjb25zdCByb290U2NvcGVzID0gcmVzb2x2ZXIuX3Jvb3RTY29wZXM7XG4gICAgY29uc3QgZmFsbGJhY2sgPSByZXNvbHZlRmFsbGJhY2socmVzb2x2ZXIuX2ZhbGxiYWNrLCBwcm9wLCB2YWx1ZSk7XG4gICAgY29uc3QgYWxsU2NvcGVzID0gW1xuICAgICAgICAuLi5wYXJlbnRTY29wZXMsXG4gICAgICAgIC4uLnJvb3RTY29wZXNcbiAgICBdO1xuICAgIGNvbnN0IHNldCA9IG5ldyBTZXQoKTtcbiAgICBzZXQuYWRkKHZhbHVlKTtcbiAgICBsZXQga2V5ID0gYWRkU2NvcGVzRnJvbUtleShzZXQsIGFsbFNjb3BlcywgcHJvcCwgZmFsbGJhY2sgfHwgcHJvcCwgdmFsdWUpO1xuICAgIGlmIChrZXkgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGZhbGxiYWNrICE9PSAndW5kZWZpbmVkJyAmJiBmYWxsYmFjayAhPT0gcHJvcCkge1xuICAgICAgICBrZXkgPSBhZGRTY29wZXNGcm9tS2V5KHNldCwgYWxsU2NvcGVzLCBmYWxsYmFjaywga2V5LCB2YWx1ZSk7XG4gICAgICAgIGlmIChrZXkgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gX2NyZWF0ZVJlc29sdmVyKEFycmF5LmZyb20oc2V0KSwgW1xuICAgICAgICAnJ1xuICAgIF0sIHJvb3RTY29wZXMsIGZhbGxiYWNrLCAoKT0+c3ViR2V0VGFyZ2V0KHJlc29sdmVyLCBwcm9wLCB2YWx1ZSkpO1xufVxuZnVuY3Rpb24gYWRkU2NvcGVzRnJvbUtleShzZXQsIGFsbFNjb3Blcywga2V5LCBmYWxsYmFjaywgaXRlbSkge1xuICAgIHdoaWxlKGtleSl7XG4gICAgICAgIGtleSA9IGFkZFNjb3BlcyhzZXQsIGFsbFNjb3Blcywga2V5LCBmYWxsYmFjaywgaXRlbSk7XG4gICAgfVxuICAgIHJldHVybiBrZXk7XG59XG5mdW5jdGlvbiBzdWJHZXRUYXJnZXQocmVzb2x2ZXIsIHByb3AsIHZhbHVlKSB7XG4gICAgY29uc3QgcGFyZW50ID0gcmVzb2x2ZXIuX2dldFRhcmdldCgpO1xuICAgIGlmICghKHByb3AgaW4gcGFyZW50KSkge1xuICAgICAgICBwYXJlbnRbcHJvcF0gPSB7fTtcbiAgICB9XG4gICAgY29uc3QgdGFyZ2V0ID0gcGFyZW50W3Byb3BdO1xuICAgIGlmIChpc0FycmF5KHRhcmdldCkgJiYgaXNPYmplY3QodmFsdWUpKSB7XG4gICAgICAgIC8vIEZvciBhcnJheSBvZiBvYmplY3RzLCB0aGUgb2JqZWN0IGlzIHVzZWQgdG8gc3RvcmUgdXBkYXRlZCB2YWx1ZXNcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4gdGFyZ2V0IHx8IHt9O1xufVxuZnVuY3Rpb24gX3Jlc29sdmVXaXRoUHJlZml4ZXMocHJvcCwgcHJlZml4ZXMsIHNjb3BlcywgcHJveHkpIHtcbiAgICBsZXQgdmFsdWU7XG4gICAgZm9yIChjb25zdCBwcmVmaXggb2YgcHJlZml4ZXMpe1xuICAgICAgICB2YWx1ZSA9IF9yZXNvbHZlKHJlYWRLZXkocHJlZml4LCBwcm9wKSwgc2NvcGVzKTtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHJldHVybiBuZWVkc1N1YlJlc29sdmVyKHByb3AsIHZhbHVlKSA/IGNyZWF0ZVN1YlJlc29sdmVyKHNjb3BlcywgcHJveHksIHByb3AsIHZhbHVlKSA6IHZhbHVlO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gX3Jlc29sdmUoa2V5LCBzY29wZXMpIHtcbiAgICBmb3IgKGNvbnN0IHNjb3BlIG9mIHNjb3Blcyl7XG4gICAgICAgIGlmICghc2NvcGUpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHZhbHVlID0gc2NvcGVba2V5XTtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmZ1bmN0aW9uIGdldEtleXNGcm9tQWxsU2NvcGVzKHRhcmdldCkge1xuICAgIGxldCBrZXlzID0gdGFyZ2V0Ll9rZXlzO1xuICAgIGlmICgha2V5cykge1xuICAgICAgICBrZXlzID0gdGFyZ2V0Ll9rZXlzID0gcmVzb2x2ZUtleXNGcm9tQWxsU2NvcGVzKHRhcmdldC5fc2NvcGVzKTtcbiAgICB9XG4gICAgcmV0dXJuIGtleXM7XG59XG5mdW5jdGlvbiByZXNvbHZlS2V5c0Zyb21BbGxTY29wZXMoc2NvcGVzKSB7XG4gICAgY29uc3Qgc2V0ID0gbmV3IFNldCgpO1xuICAgIGZvciAoY29uc3Qgc2NvcGUgb2Ygc2NvcGVzKXtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoc2NvcGUpLmZpbHRlcigoayk9PiFrLnN0YXJ0c1dpdGgoJ18nKSkpe1xuICAgICAgICAgICAgc2V0LmFkZChrZXkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBBcnJheS5mcm9tKHNldCk7XG59XG5mdW5jdGlvbiBfcGFyc2VPYmplY3REYXRhUmFkaWFsU2NhbGUobWV0YSwgZGF0YSwgc3RhcnQsIGNvdW50KSB7XG4gICAgY29uc3QgeyBpU2NhbGUgIH0gPSBtZXRhO1xuICAgIGNvbnN0IHsga2V5ID0ncicgIH0gPSB0aGlzLl9wYXJzaW5nO1xuICAgIGNvbnN0IHBhcnNlZCA9IG5ldyBBcnJheShjb3VudCk7XG4gICAgbGV0IGksIGlsZW4sIGluZGV4LCBpdGVtO1xuICAgIGZvcihpID0gMCwgaWxlbiA9IGNvdW50OyBpIDwgaWxlbjsgKytpKXtcbiAgICAgICAgaW5kZXggPSBpICsgc3RhcnQ7XG4gICAgICAgIGl0ZW0gPSBkYXRhW2luZGV4XTtcbiAgICAgICAgcGFyc2VkW2ldID0ge1xuICAgICAgICAgICAgcjogaVNjYWxlLnBhcnNlKHJlc29sdmVPYmplY3RLZXkoaXRlbSwga2V5KSwgaW5kZXgpXG4gICAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiBwYXJzZWQ7XG59XG5cbmNvbnN0IEVQU0lMT04gPSBOdW1iZXIuRVBTSUxPTiB8fCAxZS0xNDtcbmNvbnN0IGdldFBvaW50ID0gKHBvaW50cywgaSk9PmkgPCBwb2ludHMubGVuZ3RoICYmICFwb2ludHNbaV0uc2tpcCAmJiBwb2ludHNbaV07XG5jb25zdCBnZXRWYWx1ZUF4aXMgPSAoaW5kZXhBeGlzKT0+aW5kZXhBeGlzID09PSAneCcgPyAneScgOiAneCc7XG5mdW5jdGlvbiBzcGxpbmVDdXJ2ZShmaXJzdFBvaW50LCBtaWRkbGVQb2ludCwgYWZ0ZXJQb2ludCwgdCkge1xuICAgIC8vIFByb3BzIHRvIFJvYiBTcGVuY2VyIGF0IHNjYWxlZCBpbm5vdmF0aW9uIGZvciBoaXMgcG9zdCBvbiBzcGxpbmluZyBiZXR3ZWVuIHBvaW50c1xuICAgIC8vIGh0dHA6Ly9zY2FsZWRpbm5vdmF0aW9uLmNvbS9hbmFseXRpY3Mvc3BsaW5lcy9hYm91dFNwbGluZXMuaHRtbFxuICAgIC8vIFRoaXMgZnVuY3Rpb24gbXVzdCBhbHNvIHJlc3BlY3QgXCJza2lwcGVkXCIgcG9pbnRzXG4gICAgY29uc3QgcHJldmlvdXMgPSBmaXJzdFBvaW50LnNraXAgPyBtaWRkbGVQb2ludCA6IGZpcnN0UG9pbnQ7XG4gICAgY29uc3QgY3VycmVudCA9IG1pZGRsZVBvaW50O1xuICAgIGNvbnN0IG5leHQgPSBhZnRlclBvaW50LnNraXAgPyBtaWRkbGVQb2ludCA6IGFmdGVyUG9pbnQ7XG4gICAgY29uc3QgZDAxID0gZGlzdGFuY2VCZXR3ZWVuUG9pbnRzKGN1cnJlbnQsIHByZXZpb3VzKTtcbiAgICBjb25zdCBkMTIgPSBkaXN0YW5jZUJldHdlZW5Qb2ludHMobmV4dCwgY3VycmVudCk7XG4gICAgbGV0IHMwMSA9IGQwMSAvIChkMDEgKyBkMTIpO1xuICAgIGxldCBzMTIgPSBkMTIgLyAoZDAxICsgZDEyKTtcbiAgICAvLyBJZiBhbGwgcG9pbnRzIGFyZSB0aGUgc2FtZSwgczAxICYgczAyIHdpbGwgYmUgaW5mXG4gICAgczAxID0gaXNOYU4oczAxKSA/IDAgOiBzMDE7XG4gICAgczEyID0gaXNOYU4oczEyKSA/IDAgOiBzMTI7XG4gICAgY29uc3QgZmEgPSB0ICogczAxOyAvLyBzY2FsaW5nIGZhY3RvciBmb3IgdHJpYW5nbGUgVGFcbiAgICBjb25zdCBmYiA9IHQgKiBzMTI7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgcHJldmlvdXM6IHtcbiAgICAgICAgICAgIHg6IGN1cnJlbnQueCAtIGZhICogKG5leHQueCAtIHByZXZpb3VzLngpLFxuICAgICAgICAgICAgeTogY3VycmVudC55IC0gZmEgKiAobmV4dC55IC0gcHJldmlvdXMueSlcbiAgICAgICAgfSxcbiAgICAgICAgbmV4dDoge1xuICAgICAgICAgICAgeDogY3VycmVudC54ICsgZmIgKiAobmV4dC54IC0gcHJldmlvdXMueCksXG4gICAgICAgICAgICB5OiBjdXJyZW50LnkgKyBmYiAqIChuZXh0LnkgLSBwcmV2aW91cy55KVxuICAgICAgICB9XG4gICAgfTtcbn1cbi8qKlxuICogQWRqdXN0IHRhbmdlbnRzIHRvIGVuc3VyZSBtb25vdG9uaWMgcHJvcGVydGllc1xuICovIGZ1bmN0aW9uIG1vbm90b25lQWRqdXN0KHBvaW50cywgZGVsdGFLLCBtSykge1xuICAgIGNvbnN0IHBvaW50c0xlbiA9IHBvaW50cy5sZW5ndGg7XG4gICAgbGV0IGFscGhhSywgYmV0YUssIHRhdUssIHNxdWFyZWRNYWduaXR1ZGUsIHBvaW50Q3VycmVudDtcbiAgICBsZXQgcG9pbnRBZnRlciA9IGdldFBvaW50KHBvaW50cywgMCk7XG4gICAgZm9yKGxldCBpID0gMDsgaSA8IHBvaW50c0xlbiAtIDE7ICsraSl7XG4gICAgICAgIHBvaW50Q3VycmVudCA9IHBvaW50QWZ0ZXI7XG4gICAgICAgIHBvaW50QWZ0ZXIgPSBnZXRQb2ludChwb2ludHMsIGkgKyAxKTtcbiAgICAgICAgaWYgKCFwb2ludEN1cnJlbnQgfHwgIXBvaW50QWZ0ZXIpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChhbG1vc3RFcXVhbHMoZGVsdGFLW2ldLCAwLCBFUFNJTE9OKSkge1xuICAgICAgICAgICAgbUtbaV0gPSBtS1tpICsgMV0gPSAwO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgYWxwaGFLID0gbUtbaV0gLyBkZWx0YUtbaV07XG4gICAgICAgIGJldGFLID0gbUtbaSArIDFdIC8gZGVsdGFLW2ldO1xuICAgICAgICBzcXVhcmVkTWFnbml0dWRlID0gTWF0aC5wb3coYWxwaGFLLCAyKSArIE1hdGgucG93KGJldGFLLCAyKTtcbiAgICAgICAgaWYgKHNxdWFyZWRNYWduaXR1ZGUgPD0gOSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdGF1SyA9IDMgLyBNYXRoLnNxcnQoc3F1YXJlZE1hZ25pdHVkZSk7XG4gICAgICAgIG1LW2ldID0gYWxwaGFLICogdGF1SyAqIGRlbHRhS1tpXTtcbiAgICAgICAgbUtbaSArIDFdID0gYmV0YUsgKiB0YXVLICogZGVsdGFLW2ldO1xuICAgIH1cbn1cbmZ1bmN0aW9uIG1vbm90b25lQ29tcHV0ZShwb2ludHMsIG1LLCBpbmRleEF4aXMgPSAneCcpIHtcbiAgICBjb25zdCB2YWx1ZUF4aXMgPSBnZXRWYWx1ZUF4aXMoaW5kZXhBeGlzKTtcbiAgICBjb25zdCBwb2ludHNMZW4gPSBwb2ludHMubGVuZ3RoO1xuICAgIGxldCBkZWx0YSwgcG9pbnRCZWZvcmUsIHBvaW50Q3VycmVudDtcbiAgICBsZXQgcG9pbnRBZnRlciA9IGdldFBvaW50KHBvaW50cywgMCk7XG4gICAgZm9yKGxldCBpID0gMDsgaSA8IHBvaW50c0xlbjsgKytpKXtcbiAgICAgICAgcG9pbnRCZWZvcmUgPSBwb2ludEN1cnJlbnQ7XG4gICAgICAgIHBvaW50Q3VycmVudCA9IHBvaW50QWZ0ZXI7XG4gICAgICAgIHBvaW50QWZ0ZXIgPSBnZXRQb2ludChwb2ludHMsIGkgKyAxKTtcbiAgICAgICAgaWYgKCFwb2ludEN1cnJlbnQpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGlQaXhlbCA9IHBvaW50Q3VycmVudFtpbmRleEF4aXNdO1xuICAgICAgICBjb25zdCB2UGl4ZWwgPSBwb2ludEN1cnJlbnRbdmFsdWVBeGlzXTtcbiAgICAgICAgaWYgKHBvaW50QmVmb3JlKSB7XG4gICAgICAgICAgICBkZWx0YSA9IChpUGl4ZWwgLSBwb2ludEJlZm9yZVtpbmRleEF4aXNdKSAvIDM7XG4gICAgICAgICAgICBwb2ludEN1cnJlbnRbYGNwMSR7aW5kZXhBeGlzfWBdID0gaVBpeGVsIC0gZGVsdGE7XG4gICAgICAgICAgICBwb2ludEN1cnJlbnRbYGNwMSR7dmFsdWVBeGlzfWBdID0gdlBpeGVsIC0gZGVsdGEgKiBtS1tpXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocG9pbnRBZnRlcikge1xuICAgICAgICAgICAgZGVsdGEgPSAocG9pbnRBZnRlcltpbmRleEF4aXNdIC0gaVBpeGVsKSAvIDM7XG4gICAgICAgICAgICBwb2ludEN1cnJlbnRbYGNwMiR7aW5kZXhBeGlzfWBdID0gaVBpeGVsICsgZGVsdGE7XG4gICAgICAgICAgICBwb2ludEN1cnJlbnRbYGNwMiR7dmFsdWVBeGlzfWBdID0gdlBpeGVsICsgZGVsdGEgKiBtS1tpXTtcbiAgICAgICAgfVxuICAgIH1cbn1cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBjYWxjdWxhdGVzIELDqXppZXIgY29udHJvbCBwb2ludHMgaW4gYSBzaW1pbGFyIHdheSB0aGFuIHxzcGxpbmVDdXJ2ZXwsXG4gKiBidXQgcHJlc2VydmVzIG1vbm90b25pY2l0eSBvZiB0aGUgcHJvdmlkZWQgZGF0YSBhbmQgZW5zdXJlcyBubyBsb2NhbCBleHRyZW11bXMgYXJlIGFkZGVkXG4gKiBiZXR3ZWVuIHRoZSBkYXRhc2V0IGRpc2NyZXRlIHBvaW50cyBkdWUgdG8gdGhlIGludGVycG9sYXRpb24uXG4gKiBTZWUgOiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Nb25vdG9uZV9jdWJpY19pbnRlcnBvbGF0aW9uXG4gKi8gZnVuY3Rpb24gc3BsaW5lQ3VydmVNb25vdG9uZShwb2ludHMsIGluZGV4QXhpcyA9ICd4Jykge1xuICAgIGNvbnN0IHZhbHVlQXhpcyA9IGdldFZhbHVlQXhpcyhpbmRleEF4aXMpO1xuICAgIGNvbnN0IHBvaW50c0xlbiA9IHBvaW50cy5sZW5ndGg7XG4gICAgY29uc3QgZGVsdGFLID0gQXJyYXkocG9pbnRzTGVuKS5maWxsKDApO1xuICAgIGNvbnN0IG1LID0gQXJyYXkocG9pbnRzTGVuKTtcbiAgICAvLyBDYWxjdWxhdGUgc2xvcGVzIChkZWx0YUspIGFuZCBpbml0aWFsaXplIHRhbmdlbnRzIChtSylcbiAgICBsZXQgaSwgcG9pbnRCZWZvcmUsIHBvaW50Q3VycmVudDtcbiAgICBsZXQgcG9pbnRBZnRlciA9IGdldFBvaW50KHBvaW50cywgMCk7XG4gICAgZm9yKGkgPSAwOyBpIDwgcG9pbnRzTGVuOyArK2kpe1xuICAgICAgICBwb2ludEJlZm9yZSA9IHBvaW50Q3VycmVudDtcbiAgICAgICAgcG9pbnRDdXJyZW50ID0gcG9pbnRBZnRlcjtcbiAgICAgICAgcG9pbnRBZnRlciA9IGdldFBvaW50KHBvaW50cywgaSArIDEpO1xuICAgICAgICBpZiAoIXBvaW50Q3VycmVudCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBvaW50QWZ0ZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IHNsb3BlRGVsdGEgPSBwb2ludEFmdGVyW2luZGV4QXhpc10gLSBwb2ludEN1cnJlbnRbaW5kZXhBeGlzXTtcbiAgICAgICAgICAgIC8vIEluIHRoZSBjYXNlIG9mIHR3byBwb2ludHMgdGhhdCBhcHBlYXIgYXQgdGhlIHNhbWUgeCBwaXhlbCwgc2xvcGVEZWx0YVggaXMgMFxuICAgICAgICAgICAgZGVsdGFLW2ldID0gc2xvcGVEZWx0YSAhPT0gMCA/IChwb2ludEFmdGVyW3ZhbHVlQXhpc10gLSBwb2ludEN1cnJlbnRbdmFsdWVBeGlzXSkgLyBzbG9wZURlbHRhIDogMDtcbiAgICAgICAgfVxuICAgICAgICBtS1tpXSA9ICFwb2ludEJlZm9yZSA/IGRlbHRhS1tpXSA6ICFwb2ludEFmdGVyID8gZGVsdGFLW2kgLSAxXSA6IHNpZ24oZGVsdGFLW2kgLSAxXSkgIT09IHNpZ24oZGVsdGFLW2ldKSA/IDAgOiAoZGVsdGFLW2kgLSAxXSArIGRlbHRhS1tpXSkgLyAyO1xuICAgIH1cbiAgICBtb25vdG9uZUFkanVzdChwb2ludHMsIGRlbHRhSywgbUspO1xuICAgIG1vbm90b25lQ29tcHV0ZShwb2ludHMsIG1LLCBpbmRleEF4aXMpO1xufVxuZnVuY3Rpb24gY2FwQ29udHJvbFBvaW50KHB0LCBtaW4sIG1heCkge1xuICAgIHJldHVybiBNYXRoLm1heChNYXRoLm1pbihwdCwgbWF4KSwgbWluKTtcbn1cbmZ1bmN0aW9uIGNhcEJlemllclBvaW50cyhwb2ludHMsIGFyZWEpIHtcbiAgICBsZXQgaSwgaWxlbiwgcG9pbnQsIGluQXJlYSwgaW5BcmVhUHJldjtcbiAgICBsZXQgaW5BcmVhTmV4dCA9IF9pc1BvaW50SW5BcmVhKHBvaW50c1swXSwgYXJlYSk7XG4gICAgZm9yKGkgPSAwLCBpbGVuID0gcG9pbnRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSl7XG4gICAgICAgIGluQXJlYVByZXYgPSBpbkFyZWE7XG4gICAgICAgIGluQXJlYSA9IGluQXJlYU5leHQ7XG4gICAgICAgIGluQXJlYU5leHQgPSBpIDwgaWxlbiAtIDEgJiYgX2lzUG9pbnRJbkFyZWEocG9pbnRzW2kgKyAxXSwgYXJlYSk7XG4gICAgICAgIGlmICghaW5BcmVhKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBwb2ludCA9IHBvaW50c1tpXTtcbiAgICAgICAgaWYgKGluQXJlYVByZXYpIHtcbiAgICAgICAgICAgIHBvaW50LmNwMXggPSBjYXBDb250cm9sUG9pbnQocG9pbnQuY3AxeCwgYXJlYS5sZWZ0LCBhcmVhLnJpZ2h0KTtcbiAgICAgICAgICAgIHBvaW50LmNwMXkgPSBjYXBDb250cm9sUG9pbnQocG9pbnQuY3AxeSwgYXJlYS50b3AsIGFyZWEuYm90dG9tKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaW5BcmVhTmV4dCkge1xuICAgICAgICAgICAgcG9pbnQuY3AyeCA9IGNhcENvbnRyb2xQb2ludChwb2ludC5jcDJ4LCBhcmVhLmxlZnQsIGFyZWEucmlnaHQpO1xuICAgICAgICAgICAgcG9pbnQuY3AyeSA9IGNhcENvbnRyb2xQb2ludChwb2ludC5jcDJ5LCBhcmVhLnRvcCwgYXJlYS5ib3R0b20pO1xuICAgICAgICB9XG4gICAgfVxufVxuLyoqXG4gKiBAcHJpdmF0ZVxuICovIGZ1bmN0aW9uIF91cGRhdGVCZXppZXJDb250cm9sUG9pbnRzKHBvaW50cywgb3B0aW9ucywgYXJlYSwgbG9vcCwgaW5kZXhBeGlzKSB7XG4gICAgbGV0IGksIGlsZW4sIHBvaW50LCBjb250cm9sUG9pbnRzO1xuICAgIC8vIE9ubHkgY29uc2lkZXIgcG9pbnRzIHRoYXQgYXJlIGRyYXduIGluIGNhc2UgdGhlIHNwYW5HYXBzIG9wdGlvbiBpcyB1c2VkXG4gICAgaWYgKG9wdGlvbnMuc3BhbkdhcHMpIHtcbiAgICAgICAgcG9pbnRzID0gcG9pbnRzLmZpbHRlcigocHQpPT4hcHQuc2tpcCk7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLmN1YmljSW50ZXJwb2xhdGlvbk1vZGUgPT09ICdtb25vdG9uZScpIHtcbiAgICAgICAgc3BsaW5lQ3VydmVNb25vdG9uZShwb2ludHMsIGluZGV4QXhpcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgbGV0IHByZXYgPSBsb29wID8gcG9pbnRzW3BvaW50cy5sZW5ndGggLSAxXSA6IHBvaW50c1swXTtcbiAgICAgICAgZm9yKGkgPSAwLCBpbGVuID0gcG9pbnRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSl7XG4gICAgICAgICAgICBwb2ludCA9IHBvaW50c1tpXTtcbiAgICAgICAgICAgIGNvbnRyb2xQb2ludHMgPSBzcGxpbmVDdXJ2ZShwcmV2LCBwb2ludCwgcG9pbnRzW01hdGgubWluKGkgKyAxLCBpbGVuIC0gKGxvb3AgPyAwIDogMSkpICUgaWxlbl0sIG9wdGlvbnMudGVuc2lvbik7XG4gICAgICAgICAgICBwb2ludC5jcDF4ID0gY29udHJvbFBvaW50cy5wcmV2aW91cy54O1xuICAgICAgICAgICAgcG9pbnQuY3AxeSA9IGNvbnRyb2xQb2ludHMucHJldmlvdXMueTtcbiAgICAgICAgICAgIHBvaW50LmNwMnggPSBjb250cm9sUG9pbnRzLm5leHQueDtcbiAgICAgICAgICAgIHBvaW50LmNwMnkgPSBjb250cm9sUG9pbnRzLm5leHQueTtcbiAgICAgICAgICAgIHByZXYgPSBwb2ludDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAob3B0aW9ucy5jYXBCZXppZXJQb2ludHMpIHtcbiAgICAgICAgY2FwQmV6aWVyUG9pbnRzKHBvaW50cywgYXJlYSk7XG4gICAgfVxufVxuXG4vKipcbiAqIE5vdGU6IHR5cGVkZWZzIGFyZSBhdXRvLWV4cG9ydGVkLCBzbyB1c2UgYSBtYWRlLXVwIGBkb21gIG5hbWVzcGFjZSB3aGVyZVxuICogbmVjZXNzYXJ5IHRvIGF2b2lkIGR1cGxpY2F0ZXMgd2l0aCBgZXhwb3J0ICogZnJvbSAnLi9oZWxwZXJzYDsgc2VlXG4gKiBodHRwczovL2dpdGh1Yi5jb20vbWljcm9zb2Z0L1R5cGVTY3JpcHQvaXNzdWVzLzQ2MDExXG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vY29yZS9jb3JlLmNvbnRyb2xsZXIuanMnKS5kZWZhdWx0IH0gZG9tLkNoYXJ0XG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vLi4vdHlwZXMnKS5DaGFydEV2ZW50IH0gQ2hhcnRFdmVudFxuICovIC8qKlxuICogQHByaXZhdGVcbiAqLyBmdW5jdGlvbiBfaXNEb21TdXBwb3J0ZWQoKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCc7XG59XG4vKipcbiAqIEBwcml2YXRlXG4gKi8gZnVuY3Rpb24gX2dldFBhcmVudE5vZGUoZG9tTm9kZSkge1xuICAgIGxldCBwYXJlbnQgPSBkb21Ob2RlLnBhcmVudE5vZGU7XG4gICAgaWYgKHBhcmVudCAmJiBwYXJlbnQudG9TdHJpbmcoKSA9PT0gJ1tvYmplY3QgU2hhZG93Um9vdF0nKSB7XG4gICAgICAgIHBhcmVudCA9IHBhcmVudC5ob3N0O1xuICAgIH1cbiAgICByZXR1cm4gcGFyZW50O1xufVxuLyoqXG4gKiBjb252ZXJ0IG1heC13aWR0aC9tYXgtaGVpZ2h0IHZhbHVlcyB0aGF0IG1heSBiZSBwZXJjZW50YWdlcyBpbnRvIGEgbnVtYmVyXG4gKiBAcHJpdmF0ZVxuICovIGZ1bmN0aW9uIHBhcnNlTWF4U3R5bGUoc3R5bGVWYWx1ZSwgbm9kZSwgcGFyZW50UHJvcGVydHkpIHtcbiAgICBsZXQgdmFsdWVJblBpeGVscztcbiAgICBpZiAodHlwZW9mIHN0eWxlVmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHZhbHVlSW5QaXhlbHMgPSBwYXJzZUludChzdHlsZVZhbHVlLCAxMCk7XG4gICAgICAgIGlmIChzdHlsZVZhbHVlLmluZGV4T2YoJyUnKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIC8vIHBlcmNlbnRhZ2UgKiBzaXplIGluIGRpbWVuc2lvblxuICAgICAgICAgICAgdmFsdWVJblBpeGVscyA9IHZhbHVlSW5QaXhlbHMgLyAxMDAgKiBub2RlLnBhcmVudE5vZGVbcGFyZW50UHJvcGVydHldO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmFsdWVJblBpeGVscyA9IHN0eWxlVmFsdWU7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZUluUGl4ZWxzO1xufVxuY29uc3QgZ2V0Q29tcHV0ZWRTdHlsZSA9IChlbGVtZW50KT0+ZWxlbWVudC5vd25lckRvY3VtZW50LmRlZmF1bHRWaWV3LmdldENvbXB1dGVkU3R5bGUoZWxlbWVudCwgbnVsbCk7XG5mdW5jdGlvbiBnZXRTdHlsZShlbCwgcHJvcGVydHkpIHtcbiAgICByZXR1cm4gZ2V0Q29tcHV0ZWRTdHlsZShlbCkuZ2V0UHJvcGVydHlWYWx1ZShwcm9wZXJ0eSk7XG59XG5jb25zdCBwb3NpdGlvbnMgPSBbXG4gICAgJ3RvcCcsXG4gICAgJ3JpZ2h0JyxcbiAgICAnYm90dG9tJyxcbiAgICAnbGVmdCdcbl07XG5mdW5jdGlvbiBnZXRQb3NpdGlvbmVkU3R5bGUoc3R5bGVzLCBzdHlsZSwgc3VmZml4KSB7XG4gICAgY29uc3QgcmVzdWx0ID0ge307XG4gICAgc3VmZml4ID0gc3VmZml4ID8gJy0nICsgc3VmZml4IDogJyc7XG4gICAgZm9yKGxldCBpID0gMDsgaSA8IDQ7IGkrKyl7XG4gICAgICAgIGNvbnN0IHBvcyA9IHBvc2l0aW9uc1tpXTtcbiAgICAgICAgcmVzdWx0W3Bvc10gPSBwYXJzZUZsb2F0KHN0eWxlc1tzdHlsZSArICctJyArIHBvcyArIHN1ZmZpeF0pIHx8IDA7XG4gICAgfVxuICAgIHJlc3VsdC53aWR0aCA9IHJlc3VsdC5sZWZ0ICsgcmVzdWx0LnJpZ2h0O1xuICAgIHJlc3VsdC5oZWlnaHQgPSByZXN1bHQudG9wICsgcmVzdWx0LmJvdHRvbTtcbiAgICByZXR1cm4gcmVzdWx0O1xufVxuY29uc3QgdXNlT2Zmc2V0UG9zID0gKHgsIHksIHRhcmdldCk9Pih4ID4gMCB8fCB5ID4gMCkgJiYgKCF0YXJnZXQgfHwgIXRhcmdldC5zaGFkb3dSb290KTtcbi8qKlxuICogQHBhcmFtIGVcbiAqIEBwYXJhbSBjYW52YXNcbiAqIEByZXR1cm5zIENhbnZhcyBwb3NpdGlvblxuICovIGZ1bmN0aW9uIGdldENhbnZhc1Bvc2l0aW9uKGUsIGNhbnZhcykge1xuICAgIGNvbnN0IHRvdWNoZXMgPSBlLnRvdWNoZXM7XG4gICAgY29uc3Qgc291cmNlID0gdG91Y2hlcyAmJiB0b3VjaGVzLmxlbmd0aCA/IHRvdWNoZXNbMF0gOiBlO1xuICAgIGNvbnN0IHsgb2Zmc2V0WCAsIG9mZnNldFkgIH0gPSBzb3VyY2U7XG4gICAgbGV0IGJveCA9IGZhbHNlO1xuICAgIGxldCB4LCB5O1xuICAgIGlmICh1c2VPZmZzZXRQb3Mob2Zmc2V0WCwgb2Zmc2V0WSwgZS50YXJnZXQpKSB7XG4gICAgICAgIHggPSBvZmZzZXRYO1xuICAgICAgICB5ID0gb2Zmc2V0WTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCByZWN0ID0gY2FudmFzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICB4ID0gc291cmNlLmNsaWVudFggLSByZWN0LmxlZnQ7XG4gICAgICAgIHkgPSBzb3VyY2UuY2xpZW50WSAtIHJlY3QudG9wO1xuICAgICAgICBib3ggPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICB4LFxuICAgICAgICB5LFxuICAgICAgICBib3hcbiAgICB9O1xufVxuLyoqXG4gKiBHZXRzIGFuIGV2ZW50J3MgeCwgeSBjb29yZGluYXRlcywgcmVsYXRpdmUgdG8gdGhlIGNoYXJ0IGFyZWFcbiAqIEBwYXJhbSBldmVudFxuICogQHBhcmFtIGNoYXJ0XG4gKiBAcmV0dXJucyB4IGFuZCB5IGNvb3JkaW5hdGVzIG9mIHRoZSBldmVudFxuICovIGZ1bmN0aW9uIGdldFJlbGF0aXZlUG9zaXRpb24oZXZlbnQsIGNoYXJ0KSB7XG4gICAgaWYgKCduYXRpdmUnIGluIGV2ZW50KSB7XG4gICAgICAgIHJldHVybiBldmVudDtcbiAgICB9XG4gICAgY29uc3QgeyBjYW52YXMgLCBjdXJyZW50RGV2aWNlUGl4ZWxSYXRpbyAgfSA9IGNoYXJ0O1xuICAgIGNvbnN0IHN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShjYW52YXMpO1xuICAgIGNvbnN0IGJvcmRlckJveCA9IHN0eWxlLmJveFNpemluZyA9PT0gJ2JvcmRlci1ib3gnO1xuICAgIGNvbnN0IHBhZGRpbmdzID0gZ2V0UG9zaXRpb25lZFN0eWxlKHN0eWxlLCAncGFkZGluZycpO1xuICAgIGNvbnN0IGJvcmRlcnMgPSBnZXRQb3NpdGlvbmVkU3R5bGUoc3R5bGUsICdib3JkZXInLCAnd2lkdGgnKTtcbiAgICBjb25zdCB7IHggLCB5ICwgYm94ICB9ID0gZ2V0Q2FudmFzUG9zaXRpb24oZXZlbnQsIGNhbnZhcyk7XG4gICAgY29uc3QgeE9mZnNldCA9IHBhZGRpbmdzLmxlZnQgKyAoYm94ICYmIGJvcmRlcnMubGVmdCk7XG4gICAgY29uc3QgeU9mZnNldCA9IHBhZGRpbmdzLnRvcCArIChib3ggJiYgYm9yZGVycy50b3ApO1xuICAgIGxldCB7IHdpZHRoICwgaGVpZ2h0ICB9ID0gY2hhcnQ7XG4gICAgaWYgKGJvcmRlckJveCkge1xuICAgICAgICB3aWR0aCAtPSBwYWRkaW5ncy53aWR0aCArIGJvcmRlcnMud2lkdGg7XG4gICAgICAgIGhlaWdodCAtPSBwYWRkaW5ncy5oZWlnaHQgKyBib3JkZXJzLmhlaWdodDtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgeDogTWF0aC5yb3VuZCgoeCAtIHhPZmZzZXQpIC8gd2lkdGggKiBjYW52YXMud2lkdGggLyBjdXJyZW50RGV2aWNlUGl4ZWxSYXRpbyksXG4gICAgICAgIHk6IE1hdGgucm91bmQoKHkgLSB5T2Zmc2V0KSAvIGhlaWdodCAqIGNhbnZhcy5oZWlnaHQgLyBjdXJyZW50RGV2aWNlUGl4ZWxSYXRpbylcbiAgICB9O1xufVxuZnVuY3Rpb24gZ2V0Q29udGFpbmVyU2l6ZShjYW52YXMsIHdpZHRoLCBoZWlnaHQpIHtcbiAgICBsZXQgbWF4V2lkdGgsIG1heEhlaWdodDtcbiAgICBpZiAod2lkdGggPT09IHVuZGVmaW5lZCB8fCBoZWlnaHQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCBjb250YWluZXIgPSBjYW52YXMgJiYgX2dldFBhcmVudE5vZGUoY2FudmFzKTtcbiAgICAgICAgaWYgKCFjb250YWluZXIpIHtcbiAgICAgICAgICAgIHdpZHRoID0gY2FudmFzLmNsaWVudFdpZHRoO1xuICAgICAgICAgICAgaGVpZ2h0ID0gY2FudmFzLmNsaWVudEhlaWdodDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHJlY3QgPSBjb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7IC8vIHRoaXMgaXMgdGhlIGJvcmRlciBib3ggb2YgdGhlIGNvbnRhaW5lclxuICAgICAgICAgICAgY29uc3QgY29udGFpbmVyU3R5bGUgPSBnZXRDb21wdXRlZFN0eWxlKGNvbnRhaW5lcik7XG4gICAgICAgICAgICBjb25zdCBjb250YWluZXJCb3JkZXIgPSBnZXRQb3NpdGlvbmVkU3R5bGUoY29udGFpbmVyU3R5bGUsICdib3JkZXInLCAnd2lkdGgnKTtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRhaW5lclBhZGRpbmcgPSBnZXRQb3NpdGlvbmVkU3R5bGUoY29udGFpbmVyU3R5bGUsICdwYWRkaW5nJyk7XG4gICAgICAgICAgICB3aWR0aCA9IHJlY3Qud2lkdGggLSBjb250YWluZXJQYWRkaW5nLndpZHRoIC0gY29udGFpbmVyQm9yZGVyLndpZHRoO1xuICAgICAgICAgICAgaGVpZ2h0ID0gcmVjdC5oZWlnaHQgLSBjb250YWluZXJQYWRkaW5nLmhlaWdodCAtIGNvbnRhaW5lckJvcmRlci5oZWlnaHQ7XG4gICAgICAgICAgICBtYXhXaWR0aCA9IHBhcnNlTWF4U3R5bGUoY29udGFpbmVyU3R5bGUubWF4V2lkdGgsIGNvbnRhaW5lciwgJ2NsaWVudFdpZHRoJyk7XG4gICAgICAgICAgICBtYXhIZWlnaHQgPSBwYXJzZU1heFN0eWxlKGNvbnRhaW5lclN0eWxlLm1heEhlaWdodCwgY29udGFpbmVyLCAnY2xpZW50SGVpZ2h0Jyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgd2lkdGgsXG4gICAgICAgIGhlaWdodCxcbiAgICAgICAgbWF4V2lkdGg6IG1heFdpZHRoIHx8IElORklOSVRZLFxuICAgICAgICBtYXhIZWlnaHQ6IG1heEhlaWdodCB8fCBJTkZJTklUWVxuICAgIH07XG59XG5jb25zdCByb3VuZDEgPSAodik9Pk1hdGgucm91bmQodiAqIDEwKSAvIDEwO1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNvbXBsZXhpdHlcbmZ1bmN0aW9uIGdldE1heGltdW1TaXplKGNhbnZhcywgYmJXaWR0aCwgYmJIZWlnaHQsIGFzcGVjdFJhdGlvKSB7XG4gICAgY29uc3Qgc3R5bGUgPSBnZXRDb21wdXRlZFN0eWxlKGNhbnZhcyk7XG4gICAgY29uc3QgbWFyZ2lucyA9IGdldFBvc2l0aW9uZWRTdHlsZShzdHlsZSwgJ21hcmdpbicpO1xuICAgIGNvbnN0IG1heFdpZHRoID0gcGFyc2VNYXhTdHlsZShzdHlsZS5tYXhXaWR0aCwgY2FudmFzLCAnY2xpZW50V2lkdGgnKSB8fCBJTkZJTklUWTtcbiAgICBjb25zdCBtYXhIZWlnaHQgPSBwYXJzZU1heFN0eWxlKHN0eWxlLm1heEhlaWdodCwgY2FudmFzLCAnY2xpZW50SGVpZ2h0JykgfHwgSU5GSU5JVFk7XG4gICAgY29uc3QgY29udGFpbmVyU2l6ZSA9IGdldENvbnRhaW5lclNpemUoY2FudmFzLCBiYldpZHRoLCBiYkhlaWdodCk7XG4gICAgbGV0IHsgd2lkdGggLCBoZWlnaHQgIH0gPSBjb250YWluZXJTaXplO1xuICAgIGlmIChzdHlsZS5ib3hTaXppbmcgPT09ICdjb250ZW50LWJveCcpIHtcbiAgICAgICAgY29uc3QgYm9yZGVycyA9IGdldFBvc2l0aW9uZWRTdHlsZShzdHlsZSwgJ2JvcmRlcicsICd3aWR0aCcpO1xuICAgICAgICBjb25zdCBwYWRkaW5ncyA9IGdldFBvc2l0aW9uZWRTdHlsZShzdHlsZSwgJ3BhZGRpbmcnKTtcbiAgICAgICAgd2lkdGggLT0gcGFkZGluZ3Mud2lkdGggKyBib3JkZXJzLndpZHRoO1xuICAgICAgICBoZWlnaHQgLT0gcGFkZGluZ3MuaGVpZ2h0ICsgYm9yZGVycy5oZWlnaHQ7XG4gICAgfVxuICAgIHdpZHRoID0gTWF0aC5tYXgoMCwgd2lkdGggLSBtYXJnaW5zLndpZHRoKTtcbiAgICBoZWlnaHQgPSBNYXRoLm1heCgwLCBhc3BlY3RSYXRpbyA/IHdpZHRoIC8gYXNwZWN0UmF0aW8gOiBoZWlnaHQgLSBtYXJnaW5zLmhlaWdodCk7XG4gICAgd2lkdGggPSByb3VuZDEoTWF0aC5taW4od2lkdGgsIG1heFdpZHRoLCBjb250YWluZXJTaXplLm1heFdpZHRoKSk7XG4gICAgaGVpZ2h0ID0gcm91bmQxKE1hdGgubWluKGhlaWdodCwgbWF4SGVpZ2h0LCBjb250YWluZXJTaXplLm1heEhlaWdodCkpO1xuICAgIGlmICh3aWR0aCAmJiAhaGVpZ2h0KSB7XG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy80NjU5XG4gICAgICAgIC8vIElmIHRoZSBjYW52YXMgaGFzIHdpZHRoLCBidXQgbm8gaGVpZ2h0LCBkZWZhdWx0IHRvIGFzcGVjdFJhdGlvIG9mIDIgKGNhbnZhcyBkZWZhdWx0KVxuICAgICAgICBoZWlnaHQgPSByb3VuZDEod2lkdGggLyAyKTtcbiAgICB9XG4gICAgY29uc3QgbWFpbnRhaW5IZWlnaHQgPSBiYldpZHRoICE9PSB1bmRlZmluZWQgfHwgYmJIZWlnaHQgIT09IHVuZGVmaW5lZDtcbiAgICBpZiAobWFpbnRhaW5IZWlnaHQgJiYgYXNwZWN0UmF0aW8gJiYgY29udGFpbmVyU2l6ZS5oZWlnaHQgJiYgaGVpZ2h0ID4gY29udGFpbmVyU2l6ZS5oZWlnaHQpIHtcbiAgICAgICAgaGVpZ2h0ID0gY29udGFpbmVyU2l6ZS5oZWlnaHQ7XG4gICAgICAgIHdpZHRoID0gcm91bmQxKE1hdGguZmxvb3IoaGVpZ2h0ICogYXNwZWN0UmF0aW8pKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgd2lkdGgsXG4gICAgICAgIGhlaWdodFxuICAgIH07XG59XG4vKipcbiAqIEBwYXJhbSBjaGFydFxuICogQHBhcmFtIGZvcmNlUmF0aW9cbiAqIEBwYXJhbSBmb3JjZVN0eWxlXG4gKiBAcmV0dXJucyBUcnVlIGlmIHRoZSBjYW52YXMgY29udGV4dCBzaXplIG9yIHRyYW5zZm9ybWF0aW9uIGhhcyBjaGFuZ2VkLlxuICovIGZ1bmN0aW9uIHJldGluYVNjYWxlKGNoYXJ0LCBmb3JjZVJhdGlvLCBmb3JjZVN0eWxlKSB7XG4gICAgY29uc3QgcGl4ZWxSYXRpbyA9IGZvcmNlUmF0aW8gfHwgMTtcbiAgICBjb25zdCBkZXZpY2VIZWlnaHQgPSBNYXRoLmZsb29yKGNoYXJ0LmhlaWdodCAqIHBpeGVsUmF0aW8pO1xuICAgIGNvbnN0IGRldmljZVdpZHRoID0gTWF0aC5mbG9vcihjaGFydC53aWR0aCAqIHBpeGVsUmF0aW8pO1xuICAgIGNoYXJ0LmhlaWdodCA9IE1hdGguZmxvb3IoY2hhcnQuaGVpZ2h0KTtcbiAgICBjaGFydC53aWR0aCA9IE1hdGguZmxvb3IoY2hhcnQud2lkdGgpO1xuICAgIGNvbnN0IGNhbnZhcyA9IGNoYXJ0LmNhbnZhcztcbiAgICAvLyBJZiBubyBzdHlsZSBoYXMgYmVlbiBzZXQgb24gdGhlIGNhbnZhcywgdGhlIHJlbmRlciBzaXplIGlzIHVzZWQgYXMgZGlzcGxheSBzaXplLFxuICAgIC8vIG1ha2luZyB0aGUgY2hhcnQgdmlzdWFsbHkgYmlnZ2VyLCBzbyBsZXQncyBlbmZvcmNlIGl0IHRvIHRoZSBcImNvcnJlY3RcIiB2YWx1ZXMuXG4gICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy8zNTc1XG4gICAgaWYgKGNhbnZhcy5zdHlsZSAmJiAoZm9yY2VTdHlsZSB8fCAhY2FudmFzLnN0eWxlLmhlaWdodCAmJiAhY2FudmFzLnN0eWxlLndpZHRoKSkge1xuICAgICAgICBjYW52YXMuc3R5bGUuaGVpZ2h0ID0gYCR7Y2hhcnQuaGVpZ2h0fXB4YDtcbiAgICAgICAgY2FudmFzLnN0eWxlLndpZHRoID0gYCR7Y2hhcnQud2lkdGh9cHhgO1xuICAgIH1cbiAgICBpZiAoY2hhcnQuY3VycmVudERldmljZVBpeGVsUmF0aW8gIT09IHBpeGVsUmF0aW8gfHwgY2FudmFzLmhlaWdodCAhPT0gZGV2aWNlSGVpZ2h0IHx8IGNhbnZhcy53aWR0aCAhPT0gZGV2aWNlV2lkdGgpIHtcbiAgICAgICAgY2hhcnQuY3VycmVudERldmljZVBpeGVsUmF0aW8gPSBwaXhlbFJhdGlvO1xuICAgICAgICBjYW52YXMuaGVpZ2h0ID0gZGV2aWNlSGVpZ2h0O1xuICAgICAgICBjYW52YXMud2lkdGggPSBkZXZpY2VXaWR0aDtcbiAgICAgICAgY2hhcnQuY3R4LnNldFRyYW5zZm9ybShwaXhlbFJhdGlvLCAwLCAwLCBwaXhlbFJhdGlvLCAwLCAwKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbi8qKlxuICogRGV0ZWN0cyBzdXBwb3J0IGZvciBvcHRpb25zIG9iamVjdCBhcmd1bWVudCBpbiBhZGRFdmVudExpc3RlbmVyLlxuICogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0V2ZW50VGFyZ2V0L2FkZEV2ZW50TGlzdGVuZXIjU2FmZWx5X2RldGVjdGluZ19vcHRpb25fc3VwcG9ydFxuICogQHByaXZhdGVcbiAqLyBjb25zdCBzdXBwb3J0c0V2ZW50TGlzdGVuZXJPcHRpb25zID0gZnVuY3Rpb24oKSB7XG4gICAgbGV0IHBhc3NpdmVTdXBwb3J0ZWQgPSBmYWxzZTtcbiAgICB0cnkge1xuICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgZ2V0IHBhc3NpdmUgKCkge1xuICAgICAgICAgICAgICAgIHBhc3NpdmVTdXBwb3J0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgaWYgKF9pc0RvbVN1cHBvcnRlZCgpKSB7XG4gICAgICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigndGVzdCcsIG51bGwsIG9wdGlvbnMpO1xuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Rlc3QnLCBudWxsLCBvcHRpb25zKTtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBjb250aW51ZSByZWdhcmRsZXNzIG9mIGVycm9yXG4gICAgfVxuICAgIHJldHVybiBwYXNzaXZlU3VwcG9ydGVkO1xufSgpO1xuLyoqXG4gKiBUaGUgXCJ1c2VkXCIgc2l6ZSBpcyB0aGUgZmluYWwgdmFsdWUgb2YgYSBkaW1lbnNpb24gcHJvcGVydHkgYWZ0ZXIgYWxsIGNhbGN1bGF0aW9ucyBoYXZlXG4gKiBiZWVuIHBlcmZvcm1lZC4gVGhpcyBtZXRob2QgdXNlcyB0aGUgY29tcHV0ZWQgc3R5bGUgb2YgYGVsZW1lbnRgIGJ1dCByZXR1cm5zIHVuZGVmaW5lZFxuICogaWYgdGhlIGNvbXB1dGVkIHN0eWxlIGlzIG5vdCBleHByZXNzZWQgaW4gcGl4ZWxzLiBUaGF0IGNhbiBoYXBwZW4gaW4gc29tZSBjYXNlcyB3aGVyZVxuICogYGVsZW1lbnRgIGhhcyBhIHNpemUgcmVsYXRpdmUgdG8gaXRzIHBhcmVudCBhbmQgdGhpcyBsYXN0IG9uZSBpcyBub3QgeWV0IGRpc3BsYXllZCxcbiAqIGZvciBleGFtcGxlIGJlY2F1c2Ugb2YgYGRpc3BsYXk6IG5vbmVgIG9uIGEgcGFyZW50IG5vZGUuXG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0NTUy91c2VkX3ZhbHVlXG4gKiBAcmV0dXJucyBTaXplIGluIHBpeGVscyBvciB1bmRlZmluZWQgaWYgdW5rbm93bi5cbiAqLyBmdW5jdGlvbiByZWFkVXNlZFNpemUoZWxlbWVudCwgcHJvcGVydHkpIHtcbiAgICBjb25zdCB2YWx1ZSA9IGdldFN0eWxlKGVsZW1lbnQsIHByb3BlcnR5KTtcbiAgICBjb25zdCBtYXRjaGVzID0gdmFsdWUgJiYgdmFsdWUubWF0Y2goL14oXFxkKykoXFwuXFxkKyk/cHgkLyk7XG4gICAgcmV0dXJuIG1hdGNoZXMgPyArbWF0Y2hlc1sxXSA6IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovIGZ1bmN0aW9uIF9wb2ludEluTGluZShwMSwgcDIsIHQsIG1vZGUpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICB4OiBwMS54ICsgdCAqIChwMi54IC0gcDEueCksXG4gICAgICAgIHk6IHAxLnkgKyB0ICogKHAyLnkgLSBwMS55KVxuICAgIH07XG59XG4vKipcbiAqIEBwcml2YXRlXG4gKi8gZnVuY3Rpb24gX3N0ZXBwZWRJbnRlcnBvbGF0aW9uKHAxLCBwMiwgdCwgbW9kZSkge1xuICAgIHJldHVybiB7XG4gICAgICAgIHg6IHAxLnggKyB0ICogKHAyLnggLSBwMS54KSxcbiAgICAgICAgeTogbW9kZSA9PT0gJ21pZGRsZScgPyB0IDwgMC41ID8gcDEueSA6IHAyLnkgOiBtb2RlID09PSAnYWZ0ZXInID8gdCA8IDEgPyBwMS55IDogcDIueSA6IHQgPiAwID8gcDIueSA6IHAxLnlcbiAgICB9O1xufVxuLyoqXG4gKiBAcHJpdmF0ZVxuICovIGZ1bmN0aW9uIF9iZXppZXJJbnRlcnBvbGF0aW9uKHAxLCBwMiwgdCwgbW9kZSkge1xuICAgIGNvbnN0IGNwMSA9IHtcbiAgICAgICAgeDogcDEuY3AyeCxcbiAgICAgICAgeTogcDEuY3AyeVxuICAgIH07XG4gICAgY29uc3QgY3AyID0ge1xuICAgICAgICB4OiBwMi5jcDF4LFxuICAgICAgICB5OiBwMi5jcDF5XG4gICAgfTtcbiAgICBjb25zdCBhID0gX3BvaW50SW5MaW5lKHAxLCBjcDEsIHQpO1xuICAgIGNvbnN0IGIgPSBfcG9pbnRJbkxpbmUoY3AxLCBjcDIsIHQpO1xuICAgIGNvbnN0IGMgPSBfcG9pbnRJbkxpbmUoY3AyLCBwMiwgdCk7XG4gICAgY29uc3QgZCA9IF9wb2ludEluTGluZShhLCBiLCB0KTtcbiAgICBjb25zdCBlID0gX3BvaW50SW5MaW5lKGIsIGMsIHQpO1xuICAgIHJldHVybiBfcG9pbnRJbkxpbmUoZCwgZSwgdCk7XG59XG5cbmNvbnN0IGdldFJpZ2h0VG9MZWZ0QWRhcHRlciA9IGZ1bmN0aW9uKHJlY3RYLCB3aWR0aCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIHggKHgpIHtcbiAgICAgICAgICAgIHJldHVybiByZWN0WCArIHJlY3RYICsgd2lkdGggLSB4O1xuICAgICAgICB9LFxuICAgICAgICBzZXRXaWR0aCAodykge1xuICAgICAgICAgICAgd2lkdGggPSB3O1xuICAgICAgICB9LFxuICAgICAgICB0ZXh0QWxpZ24gKGFsaWduKSB7XG4gICAgICAgICAgICBpZiAoYWxpZ24gPT09ICdjZW50ZXInKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFsaWduO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGFsaWduID09PSAncmlnaHQnID8gJ2xlZnQnIDogJ3JpZ2h0JztcbiAgICAgICAgfSxcbiAgICAgICAgeFBsdXMgKHgsIHZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4geCAtIHZhbHVlO1xuICAgICAgICB9LFxuICAgICAgICBsZWZ0Rm9yTHRyICh4LCBpdGVtV2lkdGgpIHtcbiAgICAgICAgICAgIHJldHVybiB4IC0gaXRlbVdpZHRoO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5jb25zdCBnZXRMZWZ0VG9SaWdodEFkYXB0ZXIgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICB4ICh4KSB7XG4gICAgICAgICAgICByZXR1cm4geDtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0V2lkdGggKHcpIHt9LFxuICAgICAgICB0ZXh0QWxpZ24gKGFsaWduKSB7XG4gICAgICAgICAgICByZXR1cm4gYWxpZ247XG4gICAgICAgIH0sXG4gICAgICAgIHhQbHVzICh4LCB2YWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIHggKyB2YWx1ZTtcbiAgICAgICAgfSxcbiAgICAgICAgbGVmdEZvckx0ciAoeCwgX2l0ZW1XaWR0aCkge1xuICAgICAgICAgICAgcmV0dXJuIHg7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbmZ1bmN0aW9uIGdldFJ0bEFkYXB0ZXIocnRsLCByZWN0WCwgd2lkdGgpIHtcbiAgICByZXR1cm4gcnRsID8gZ2V0UmlnaHRUb0xlZnRBZGFwdGVyKHJlY3RYLCB3aWR0aCkgOiBnZXRMZWZ0VG9SaWdodEFkYXB0ZXIoKTtcbn1cbmZ1bmN0aW9uIG92ZXJyaWRlVGV4dERpcmVjdGlvbihjdHgsIGRpcmVjdGlvbikge1xuICAgIGxldCBzdHlsZSwgb3JpZ2luYWw7XG4gICAgaWYgKGRpcmVjdGlvbiA9PT0gJ2x0cicgfHwgZGlyZWN0aW9uID09PSAncnRsJykge1xuICAgICAgICBzdHlsZSA9IGN0eC5jYW52YXMuc3R5bGU7XG4gICAgICAgIG9yaWdpbmFsID0gW1xuICAgICAgICAgICAgc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZSgnZGlyZWN0aW9uJyksXG4gICAgICAgICAgICBzdHlsZS5nZXRQcm9wZXJ0eVByaW9yaXR5KCdkaXJlY3Rpb24nKVxuICAgICAgICBdO1xuICAgICAgICBzdHlsZS5zZXRQcm9wZXJ0eSgnZGlyZWN0aW9uJywgZGlyZWN0aW9uLCAnaW1wb3J0YW50Jyk7XG4gICAgICAgIGN0eC5wcmV2VGV4dERpcmVjdGlvbiA9IG9yaWdpbmFsO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHJlc3RvcmVUZXh0RGlyZWN0aW9uKGN0eCwgb3JpZ2luYWwpIHtcbiAgICBpZiAob3JpZ2luYWwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBkZWxldGUgY3R4LnByZXZUZXh0RGlyZWN0aW9uO1xuICAgICAgICBjdHguY2FudmFzLnN0eWxlLnNldFByb3BlcnR5KCdkaXJlY3Rpb24nLCBvcmlnaW5hbFswXSwgb3JpZ2luYWxbMV0pO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gcHJvcGVydHlGbihwcm9wZXJ0eSkge1xuICAgIGlmIChwcm9wZXJ0eSA9PT0gJ2FuZ2xlJykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgYmV0d2VlbjogX2FuZ2xlQmV0d2VlbixcbiAgICAgICAgICAgIGNvbXBhcmU6IF9hbmdsZURpZmYsXG4gICAgICAgICAgICBub3JtYWxpemU6IF9ub3JtYWxpemVBbmdsZVxuICAgICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBiZXR3ZWVuOiBfaXNCZXR3ZWVuLFxuICAgICAgICBjb21wYXJlOiAoYSwgYik9PmEgLSBiLFxuICAgICAgICBub3JtYWxpemU6ICh4KT0+eFxuICAgIH07XG59XG5mdW5jdGlvbiBub3JtYWxpemVTZWdtZW50KHsgc3RhcnQgLCBlbmQgLCBjb3VudCAsIGxvb3AgLCBzdHlsZSAgfSkge1xuICAgIHJldHVybiB7XG4gICAgICAgIHN0YXJ0OiBzdGFydCAlIGNvdW50LFxuICAgICAgICBlbmQ6IGVuZCAlIGNvdW50LFxuICAgICAgICBsb29wOiBsb29wICYmIChlbmQgLSBzdGFydCArIDEpICUgY291bnQgPT09IDAsXG4gICAgICAgIHN0eWxlXG4gICAgfTtcbn1cbmZ1bmN0aW9uIGdldFNlZ21lbnQoc2VnbWVudCwgcG9pbnRzLCBib3VuZHMpIHtcbiAgICBjb25zdCB7IHByb3BlcnR5ICwgc3RhcnQ6IHN0YXJ0Qm91bmQgLCBlbmQ6IGVuZEJvdW5kICB9ID0gYm91bmRzO1xuICAgIGNvbnN0IHsgYmV0d2VlbiAsIG5vcm1hbGl6ZSAgfSA9IHByb3BlcnR5Rm4ocHJvcGVydHkpO1xuICAgIGNvbnN0IGNvdW50ID0gcG9pbnRzLmxlbmd0aDtcbiAgICBsZXQgeyBzdGFydCAsIGVuZCAsIGxvb3AgIH0gPSBzZWdtZW50O1xuICAgIGxldCBpLCBpbGVuO1xuICAgIGlmIChsb29wKSB7XG4gICAgICAgIHN0YXJ0ICs9IGNvdW50O1xuICAgICAgICBlbmQgKz0gY291bnQ7XG4gICAgICAgIGZvcihpID0gMCwgaWxlbiA9IGNvdW50OyBpIDwgaWxlbjsgKytpKXtcbiAgICAgICAgICAgIGlmICghYmV0d2Vlbihub3JtYWxpemUocG9pbnRzW3N0YXJ0ICUgY291bnRdW3Byb3BlcnR5XSksIHN0YXJ0Qm91bmQsIGVuZEJvdW5kKSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3RhcnQtLTtcbiAgICAgICAgICAgIGVuZC0tO1xuICAgICAgICB9XG4gICAgICAgIHN0YXJ0ICU9IGNvdW50O1xuICAgICAgICBlbmQgJT0gY291bnQ7XG4gICAgfVxuICAgIGlmIChlbmQgPCBzdGFydCkge1xuICAgICAgICBlbmQgKz0gY291bnQ7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHN0YXJ0LFxuICAgICAgICBlbmQsXG4gICAgICAgIGxvb3AsXG4gICAgICAgIHN0eWxlOiBzZWdtZW50LnN0eWxlXG4gICAgfTtcbn1cbiBmdW5jdGlvbiBfYm91bmRTZWdtZW50KHNlZ21lbnQsIHBvaW50cywgYm91bmRzKSB7XG4gICAgaWYgKCFib3VuZHMpIHtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIHNlZ21lbnRcbiAgICAgICAgXTtcbiAgICB9XG4gICAgY29uc3QgeyBwcm9wZXJ0eSAsIHN0YXJ0OiBzdGFydEJvdW5kICwgZW5kOiBlbmRCb3VuZCAgfSA9IGJvdW5kcztcbiAgICBjb25zdCBjb3VudCA9IHBvaW50cy5sZW5ndGg7XG4gICAgY29uc3QgeyBjb21wYXJlICwgYmV0d2VlbiAsIG5vcm1hbGl6ZSAgfSA9IHByb3BlcnR5Rm4ocHJvcGVydHkpO1xuICAgIGNvbnN0IHsgc3RhcnQgLCBlbmQgLCBsb29wICwgc3R5bGUgIH0gPSBnZXRTZWdtZW50KHNlZ21lbnQsIHBvaW50cywgYm91bmRzKTtcbiAgICBjb25zdCByZXN1bHQgPSBbXTtcbiAgICBsZXQgaW5zaWRlID0gZmFsc2U7XG4gICAgbGV0IHN1YlN0YXJ0ID0gbnVsbDtcbiAgICBsZXQgdmFsdWUsIHBvaW50LCBwcmV2VmFsdWU7XG4gICAgY29uc3Qgc3RhcnRJc0JlZm9yZSA9ICgpPT5iZXR3ZWVuKHN0YXJ0Qm91bmQsIHByZXZWYWx1ZSwgdmFsdWUpICYmIGNvbXBhcmUoc3RhcnRCb3VuZCwgcHJldlZhbHVlKSAhPT0gMDtcbiAgICBjb25zdCBlbmRJc0JlZm9yZSA9ICgpPT5jb21wYXJlKGVuZEJvdW5kLCB2YWx1ZSkgPT09IDAgfHwgYmV0d2VlbihlbmRCb3VuZCwgcHJldlZhbHVlLCB2YWx1ZSk7XG4gICAgY29uc3Qgc2hvdWxkU3RhcnQgPSAoKT0+aW5zaWRlIHx8IHN0YXJ0SXNCZWZvcmUoKTtcbiAgICBjb25zdCBzaG91bGRTdG9wID0gKCk9PiFpbnNpZGUgfHwgZW5kSXNCZWZvcmUoKTtcbiAgICBmb3IobGV0IGkgPSBzdGFydCwgcHJldiA9IHN0YXJ0OyBpIDw9IGVuZDsgKytpKXtcbiAgICAgICAgcG9pbnQgPSBwb2ludHNbaSAlIGNvdW50XTtcbiAgICAgICAgaWYgKHBvaW50LnNraXApIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHZhbHVlID0gbm9ybWFsaXplKHBvaW50W3Byb3BlcnR5XSk7XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gcHJldlZhbHVlKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpbnNpZGUgPSBiZXR3ZWVuKHZhbHVlLCBzdGFydEJvdW5kLCBlbmRCb3VuZCk7XG4gICAgICAgIGlmIChzdWJTdGFydCA9PT0gbnVsbCAmJiBzaG91bGRTdGFydCgpKSB7XG4gICAgICAgICAgICBzdWJTdGFydCA9IGNvbXBhcmUodmFsdWUsIHN0YXJ0Qm91bmQpID09PSAwID8gaSA6IHByZXY7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN1YlN0YXJ0ICE9PSBudWxsICYmIHNob3VsZFN0b3AoKSkge1xuICAgICAgICAgICAgcmVzdWx0LnB1c2gobm9ybWFsaXplU2VnbWVudCh7XG4gICAgICAgICAgICAgICAgc3RhcnQ6IHN1YlN0YXJ0LFxuICAgICAgICAgICAgICAgIGVuZDogaSxcbiAgICAgICAgICAgICAgICBsb29wLFxuICAgICAgICAgICAgICAgIGNvdW50LFxuICAgICAgICAgICAgICAgIHN0eWxlXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICBzdWJTdGFydCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcHJldiA9IGk7XG4gICAgICAgIHByZXZWYWx1ZSA9IHZhbHVlO1xuICAgIH1cbiAgICBpZiAoc3ViU3RhcnQgIT09IG51bGwpIHtcbiAgICAgICAgcmVzdWx0LnB1c2gobm9ybWFsaXplU2VnbWVudCh7XG4gICAgICAgICAgICBzdGFydDogc3ViU3RhcnQsXG4gICAgICAgICAgICBlbmQsXG4gICAgICAgICAgICBsb29wLFxuICAgICAgICAgICAgY291bnQsXG4gICAgICAgICAgICBzdHlsZVxuICAgICAgICB9KSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG4gZnVuY3Rpb24gX2JvdW5kU2VnbWVudHMobGluZSwgYm91bmRzKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgY29uc3Qgc2VnbWVudHMgPSBsaW5lLnNlZ21lbnRzO1xuICAgIGZvcihsZXQgaSA9IDA7IGkgPCBzZWdtZW50cy5sZW5ndGg7IGkrKyl7XG4gICAgICAgIGNvbnN0IHN1YiA9IF9ib3VuZFNlZ21lbnQoc2VnbWVudHNbaV0sIGxpbmUucG9pbnRzLCBib3VuZHMpO1xuICAgICAgICBpZiAoc3ViLmxlbmd0aCkge1xuICAgICAgICAgICAgcmVzdWx0LnB1c2goLi4uc3ViKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuIGZ1bmN0aW9uIGZpbmRTdGFydEFuZEVuZChwb2ludHMsIGNvdW50LCBsb29wLCBzcGFuR2Fwcykge1xuICAgIGxldCBzdGFydCA9IDA7XG4gICAgbGV0IGVuZCA9IGNvdW50IC0gMTtcbiAgICBpZiAobG9vcCAmJiAhc3BhbkdhcHMpIHtcbiAgICAgICAgd2hpbGUoc3RhcnQgPCBjb3VudCAmJiAhcG9pbnRzW3N0YXJ0XS5za2lwKXtcbiAgICAgICAgICAgIHN0YXJ0Kys7XG4gICAgICAgIH1cbiAgICB9XG4gICAgd2hpbGUoc3RhcnQgPCBjb3VudCAmJiBwb2ludHNbc3RhcnRdLnNraXApe1xuICAgICAgICBzdGFydCsrO1xuICAgIH1cbiAgICBzdGFydCAlPSBjb3VudDtcbiAgICBpZiAobG9vcCkge1xuICAgICAgICBlbmQgKz0gc3RhcnQ7XG4gICAgfVxuICAgIHdoaWxlKGVuZCA+IHN0YXJ0ICYmIHBvaW50c1tlbmQgJSBjb3VudF0uc2tpcCl7XG4gICAgICAgIGVuZC0tO1xuICAgIH1cbiAgICBlbmQgJT0gY291bnQ7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgc3RhcnQsXG4gICAgICAgIGVuZFxuICAgIH07XG59XG4gZnVuY3Rpb24gc29saWRTZWdtZW50cyhwb2ludHMsIHN0YXJ0LCBtYXgsIGxvb3ApIHtcbiAgICBjb25zdCBjb3VudCA9IHBvaW50cy5sZW5ndGg7XG4gICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgbGV0IGxhc3QgPSBzdGFydDtcbiAgICBsZXQgcHJldiA9IHBvaW50c1tzdGFydF07XG4gICAgbGV0IGVuZDtcbiAgICBmb3IoZW5kID0gc3RhcnQgKyAxOyBlbmQgPD0gbWF4OyArK2VuZCl7XG4gICAgICAgIGNvbnN0IGN1ciA9IHBvaW50c1tlbmQgJSBjb3VudF07XG4gICAgICAgIGlmIChjdXIuc2tpcCB8fCBjdXIuc3RvcCkge1xuICAgICAgICAgICAgaWYgKCFwcmV2LnNraXApIHtcbiAgICAgICAgICAgICAgICBsb29wID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBzdGFydDogc3RhcnQgJSBjb3VudCxcbiAgICAgICAgICAgICAgICAgICAgZW5kOiAoZW5kIC0gMSkgJSBjb3VudCxcbiAgICAgICAgICAgICAgICAgICAgbG9vcFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHN0YXJ0ID0gbGFzdCA9IGN1ci5zdG9wID8gZW5kIDogbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxhc3QgPSBlbmQ7XG4gICAgICAgICAgICBpZiAocHJldi5za2lwKSB7XG4gICAgICAgICAgICAgICAgc3RhcnQgPSBlbmQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcHJldiA9IGN1cjtcbiAgICB9XG4gICAgaWYgKGxhc3QgIT09IG51bGwpIHtcbiAgICAgICAgcmVzdWx0LnB1c2goe1xuICAgICAgICAgICAgc3RhcnQ6IHN0YXJ0ICUgY291bnQsXG4gICAgICAgICAgICBlbmQ6IGxhc3QgJSBjb3VudCxcbiAgICAgICAgICAgIGxvb3BcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG4gZnVuY3Rpb24gX2NvbXB1dGVTZWdtZW50cyhsaW5lLCBzZWdtZW50T3B0aW9ucykge1xuICAgIGNvbnN0IHBvaW50cyA9IGxpbmUucG9pbnRzO1xuICAgIGNvbnN0IHNwYW5HYXBzID0gbGluZS5vcHRpb25zLnNwYW5HYXBzO1xuICAgIGNvbnN0IGNvdW50ID0gcG9pbnRzLmxlbmd0aDtcbiAgICBpZiAoIWNvdW50KSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgY29uc3QgbG9vcCA9ICEhbGluZS5fbG9vcDtcbiAgICBjb25zdCB7IHN0YXJ0ICwgZW5kICB9ID0gZmluZFN0YXJ0QW5kRW5kKHBvaW50cywgY291bnQsIGxvb3AsIHNwYW5HYXBzKTtcbiAgICBpZiAoc3BhbkdhcHMgPT09IHRydWUpIHtcbiAgICAgICAgcmV0dXJuIHNwbGl0QnlTdHlsZXMobGluZSwgW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHN0YXJ0LFxuICAgICAgICAgICAgICAgIGVuZCxcbiAgICAgICAgICAgICAgICBsb29wXG4gICAgICAgICAgICB9XG4gICAgICAgIF0sIHBvaW50cywgc2VnbWVudE9wdGlvbnMpO1xuICAgIH1cbiAgICBjb25zdCBtYXggPSBlbmQgPCBzdGFydCA/IGVuZCArIGNvdW50IDogZW5kO1xuICAgIGNvbnN0IGNvbXBsZXRlTG9vcCA9ICEhbGluZS5fZnVsbExvb3AgJiYgc3RhcnQgPT09IDAgJiYgZW5kID09PSBjb3VudCAtIDE7XG4gICAgcmV0dXJuIHNwbGl0QnlTdHlsZXMobGluZSwgc29saWRTZWdtZW50cyhwb2ludHMsIHN0YXJ0LCBtYXgsIGNvbXBsZXRlTG9vcCksIHBvaW50cywgc2VnbWVudE9wdGlvbnMpO1xufVxuIGZ1bmN0aW9uIHNwbGl0QnlTdHlsZXMobGluZSwgc2VnbWVudHMsIHBvaW50cywgc2VnbWVudE9wdGlvbnMpIHtcbiAgICBpZiAoIXNlZ21lbnRPcHRpb25zIHx8ICFzZWdtZW50T3B0aW9ucy5zZXRDb250ZXh0IHx8ICFwb2ludHMpIHtcbiAgICAgICAgcmV0dXJuIHNlZ21lbnRzO1xuICAgIH1cbiAgICByZXR1cm4gZG9TcGxpdEJ5U3R5bGVzKGxpbmUsIHNlZ21lbnRzLCBwb2ludHMsIHNlZ21lbnRPcHRpb25zKTtcbn1cbiBmdW5jdGlvbiBkb1NwbGl0QnlTdHlsZXMobGluZSwgc2VnbWVudHMsIHBvaW50cywgc2VnbWVudE9wdGlvbnMpIHtcbiAgICBjb25zdCBjaGFydENvbnRleHQgPSBsaW5lLl9jaGFydC5nZXRDb250ZXh0KCk7XG4gICAgY29uc3QgYmFzZVN0eWxlID0gcmVhZFN0eWxlKGxpbmUub3B0aW9ucyk7XG4gICAgY29uc3QgeyBfZGF0YXNldEluZGV4OiBkYXRhc2V0SW5kZXggLCBvcHRpb25zOiB7IHNwYW5HYXBzICB9ICB9ID0gbGluZTtcbiAgICBjb25zdCBjb3VudCA9IHBvaW50cy5sZW5ndGg7XG4gICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgbGV0IHByZXZTdHlsZSA9IGJhc2VTdHlsZTtcbiAgICBsZXQgc3RhcnQgPSBzZWdtZW50c1swXS5zdGFydDtcbiAgICBsZXQgaSA9IHN0YXJ0O1xuICAgIGZ1bmN0aW9uIGFkZFN0eWxlKHMsIGUsIGwsIHN0KSB7XG4gICAgICAgIGNvbnN0IGRpciA9IHNwYW5HYXBzID8gLTEgOiAxO1xuICAgICAgICBpZiAocyA9PT0gZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHMgKz0gY291bnQ7XG4gICAgICAgIHdoaWxlKHBvaW50c1tzICUgY291bnRdLnNraXApe1xuICAgICAgICAgICAgcyAtPSBkaXI7XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUocG9pbnRzW2UgJSBjb3VudF0uc2tpcCl7XG4gICAgICAgICAgICBlICs9IGRpcjtcbiAgICAgICAgfVxuICAgICAgICBpZiAocyAlIGNvdW50ICE9PSBlICUgY291bnQpIHtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKHtcbiAgICAgICAgICAgICAgICBzdGFydDogcyAlIGNvdW50LFxuICAgICAgICAgICAgICAgIGVuZDogZSAlIGNvdW50LFxuICAgICAgICAgICAgICAgIGxvb3A6IGwsXG4gICAgICAgICAgICAgICAgc3R5bGU6IHN0XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHByZXZTdHlsZSA9IHN0O1xuICAgICAgICAgICAgc3RhcnQgPSBlICUgY291bnQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZm9yIChjb25zdCBzZWdtZW50IG9mIHNlZ21lbnRzKXtcbiAgICAgICAgc3RhcnQgPSBzcGFuR2FwcyA/IHN0YXJ0IDogc2VnbWVudC5zdGFydDtcbiAgICAgICAgbGV0IHByZXYgPSBwb2ludHNbc3RhcnQgJSBjb3VudF07XG4gICAgICAgIGxldCBzdHlsZTtcbiAgICAgICAgZm9yKGkgPSBzdGFydCArIDE7IGkgPD0gc2VnbWVudC5lbmQ7IGkrKyl7XG4gICAgICAgICAgICBjb25zdCBwdCA9IHBvaW50c1tpICUgY291bnRdO1xuICAgICAgICAgICAgc3R5bGUgPSByZWFkU3R5bGUoc2VnbWVudE9wdGlvbnMuc2V0Q29udGV4dChjcmVhdGVDb250ZXh0KGNoYXJ0Q29udGV4dCwge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdzZWdtZW50JyxcbiAgICAgICAgICAgICAgICBwMDogcHJldixcbiAgICAgICAgICAgICAgICBwMTogcHQsXG4gICAgICAgICAgICAgICAgcDBEYXRhSW5kZXg6IChpIC0gMSkgJSBjb3VudCxcbiAgICAgICAgICAgICAgICBwMURhdGFJbmRleDogaSAlIGNvdW50LFxuICAgICAgICAgICAgICAgIGRhdGFzZXRJbmRleFxuICAgICAgICAgICAgfSkpKTtcbiAgICAgICAgICAgIGlmIChzdHlsZUNoYW5nZWQoc3R5bGUsIHByZXZTdHlsZSkpIHtcbiAgICAgICAgICAgICAgICBhZGRTdHlsZShzdGFydCwgaSAtIDEsIHNlZ21lbnQubG9vcCwgcHJldlN0eWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHByZXYgPSBwdDtcbiAgICAgICAgICAgIHByZXZTdHlsZSA9IHN0eWxlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdGFydCA8IGkgLSAxKSB7XG4gICAgICAgICAgICBhZGRTdHlsZShzdGFydCwgaSAtIDEsIHNlZ21lbnQubG9vcCwgcHJldlN0eWxlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuZnVuY3Rpb24gcmVhZFN0eWxlKG9wdGlvbnMpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IG9wdGlvbnMuYmFja2dyb3VuZENvbG9yLFxuICAgICAgICBib3JkZXJDYXBTdHlsZTogb3B0aW9ucy5ib3JkZXJDYXBTdHlsZSxcbiAgICAgICAgYm9yZGVyRGFzaDogb3B0aW9ucy5ib3JkZXJEYXNoLFxuICAgICAgICBib3JkZXJEYXNoT2Zmc2V0OiBvcHRpb25zLmJvcmRlckRhc2hPZmZzZXQsXG4gICAgICAgIGJvcmRlckpvaW5TdHlsZTogb3B0aW9ucy5ib3JkZXJKb2luU3R5bGUsXG4gICAgICAgIGJvcmRlcldpZHRoOiBvcHRpb25zLmJvcmRlcldpZHRoLFxuICAgICAgICBib3JkZXJDb2xvcjogb3B0aW9ucy5ib3JkZXJDb2xvclxuICAgIH07XG59XG5mdW5jdGlvbiBzdHlsZUNoYW5nZWQoc3R5bGUsIHByZXZTdHlsZSkge1xuICAgIGlmICghcHJldlN0eWxlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgY2FjaGUgPSBbXTtcbiAgICBjb25zdCByZXBsYWNlciA9IGZ1bmN0aW9uKGtleSwgdmFsdWUpIHtcbiAgICAgICAgaWYgKCFpc1BhdHRlcm5PckdyYWRpZW50KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGlmICghY2FjaGUuaW5jbHVkZXModmFsdWUpKSB7XG4gICAgICAgICAgICBjYWNoZS5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FjaGUuaW5kZXhPZih2YWx1ZSk7XG4gICAgfTtcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoc3R5bGUsIHJlcGxhY2VyKSAhPT0gSlNPTi5zdHJpbmdpZnkocHJldlN0eWxlLCByZXBsYWNlcik7XG59XG5cbmV4cG9ydCB7IHVuY2xpcEFyZWEgYXMgJCwgX3Jsb29rdXBCeUtleSBhcyBBLCBfbG9va3VwQnlLZXkgYXMgQiwgX2lzUG9pbnRJbkFyZWEgYXMgQywgZ2V0QW5nbGVGcm9tUG9pbnQgYXMgRCwgdG9QYWRkaW5nIGFzIEUsIGVhY2ggYXMgRiwgZ2V0TWF4aW11bVNpemUgYXMgRywgSEFMRl9QSSBhcyBILCBfZ2V0UGFyZW50Tm9kZSBhcyBJLCByZWFkVXNlZFNpemUgYXMgSiwgc3VwcG9ydHNFdmVudExpc3RlbmVyT3B0aW9ucyBhcyBLLCB0aHJvdHRsZWQgYXMgTCwgX2lzRG9tU3VwcG9ydGVkIGFzIE0sIF9mYWN0b3JpemUgYXMgTiwgZmluaXRlT3JEZWZhdWx0IGFzIE8sIFBJIGFzIFAsIGNhbGxiYWNrIGFzIFEsIF9hZGRHcmFjZSBhcyBSLCBfbGltaXRWYWx1ZSBhcyBTLCBUQVUgYXMgVCwgdG9EZWdyZWVzIGFzIFUsIF9tZWFzdXJlVGV4dCBhcyBWLCBfaW50MTZSYW5nZSBhcyBXLCBfYWxpZ25QaXhlbCBhcyBYLCBjbGlwQXJlYSBhcyBZLCByZW5kZXJUZXh0IGFzIFosIF9hcnJheVVuaXF1ZSBhcyBfLCByZXNvbHZlIGFzIGEsIGZvbnRTdHJpbmcgYXMgYSQsIHRvRm9udCBhcyBhMCwgX3RvTGVmdFJpZ2h0Q2VudGVyIGFzIGExLCBfYWxpZ25TdGFydEVuZCBhcyBhMiwgb3ZlcnJpZGVzIGFzIGEzLCBtZXJnZSBhcyBhNCwgX2NhcGl0YWxpemUgYXMgYTUsIGRlc2NyaXB0b3JzIGFzIGE2LCBpc0Z1bmN0aW9uIGFzIGE3LCBfYXR0YWNoQ29udGV4dCBhcyBhOCwgX2NyZWF0ZVJlc29sdmVyIGFzIGE5LCBvdmVycmlkZVRleHREaXJlY3Rpb24gYXMgYUEsIF90ZXh0WCBhcyBhQiwgcmVzdG9yZVRleHREaXJlY3Rpb24gYXMgYUMsIGRyYXdQb2ludExlZ2VuZCBhcyBhRCwgZGlzdGFuY2VCZXR3ZWVuUG9pbnRzIGFzIGFFLCBub29wIGFzIGFGLCBfc2V0TWluQW5kTWF4QnlLZXkgYXMgYUcsIG5pY2VOdW0gYXMgYUgsIGFsbW9zdFdob2xlIGFzIGFJLCBhbG1vc3RFcXVhbHMgYXMgYUosIF9kZWNpbWFsUGxhY2VzIGFzIGFLLCBUaWNrcyBhcyBhTCwgbG9nMTAgYXMgYU0sIF9sb25nZXN0VGV4dCBhcyBhTiwgX2ZpbHRlckJldHdlZW4gYXMgYU8sIF9sb29rdXAgYXMgYVAsIGlzUGF0dGVybk9yR3JhZGllbnQgYXMgYVEsIGdldEhvdmVyQ29sb3IgYXMgYVIsIGNsb25lIGFzIGFTLCBfbWVyZ2VyIGFzIGFULCBfbWVyZ2VySWYgYXMgYVUsIF9kZXByZWNhdGVkIGFzIGFWLCBfc3BsaXRLZXkgYXMgYVcsIHRvRm9udFN0cmluZyBhcyBhWCwgc3BsaW5lQ3VydmUgYXMgYVksIHNwbGluZUN1cnZlTW9ub3RvbmUgYXMgYVosIGdldFN0eWxlIGFzIGFfLCBfZGVzY3JpcHRvcnMgYXMgYWEsIG1lcmdlSWYgYXMgYWIsIHVpZCBhcyBhYywgZGVib3VuY2UgYXMgYWQsIHJldGluYVNjYWxlIGFzIGFlLCBjbGVhckNhbnZhcyBhcyBhZiwgc2V0c0VxdWFsIGFzIGFnLCBfZWxlbWVudHNFcXVhbCBhcyBhaCwgX2lzQ2xpY2tFdmVudCBhcyBhaSwgX2lzQmV0d2VlbiBhcyBhaiwgX3JlYWRWYWx1ZVRvUHJvcHMgYXMgYWssIF91cGRhdGVCZXppZXJDb250cm9sUG9pbnRzIGFzIGFsLCBfY29tcHV0ZVNlZ21lbnRzIGFzIGFtLCBfYm91bmRTZWdtZW50cyBhcyBhbiwgX3N0ZXBwZWRJbnRlcnBvbGF0aW9uIGFzIGFvLCBfYmV6aWVySW50ZXJwb2xhdGlvbiBhcyBhcCwgX3BvaW50SW5MaW5lIGFzIGFxLCBfc3RlcHBlZExpbmVUbyBhcyBhciwgX2JlemllckN1cnZlVG8gYXMgYXMsIGRyYXdQb2ludCBhcyBhdCwgYWRkUm91bmRlZFJlY3RQYXRoIGFzIGF1LCB0b1RSQkwgYXMgYXYsIHRvVFJCTENvcm5lcnMgYXMgYXcsIF9ib3VuZFNlZ21lbnQgYXMgYXgsIF9ub3JtYWxpemVBbmdsZSBhcyBheSwgZ2V0UnRsQWRhcHRlciBhcyBheiwgaXNBcnJheSBhcyBiLCB0b0xpbmVIZWlnaHQgYXMgYjAsIFBJVEFVIGFzIGIxLCBJTkZJTklUWSBhcyBiMiwgUkFEX1BFUl9ERUcgYXMgYjMsIFFVQVJURVJfUEkgYXMgYjQsIFRXT19USElSRFNfUEkgYXMgYjUsIF9hbmdsZURpZmYgYXMgYjYsIGNvbG9yIGFzIGMsIGRlZmF1bHRzIGFzIGQsIGVmZmVjdHMgYXMgZSwgcmVzb2x2ZU9iamVjdEtleSBhcyBmLCBpc051bWJlckZpbml0ZSBhcyBnLCBkZWZpbmVkIGFzIGgsIGlzT2JqZWN0IGFzIGksIGNyZWF0ZUNvbnRleHQgYXMgaiwgaXNOdWxsT3JVbmRlZiBhcyBrLCBsaXN0ZW5BcnJheUV2ZW50cyBhcyBsLCB0b1BlcmNlbnRhZ2UgYXMgbSwgdG9EaW1lbnNpb24gYXMgbiwgZm9ybWF0TnVtYmVyIGFzIG8sIF9hbmdsZUJldHdlZW4gYXMgcCwgX2dldFN0YXJ0QW5kQ291bnRPZlZpc2libGVQb2ludHMgYXMgcSwgcmVxdWVzdEFuaW1GcmFtZSBhcyByLCBzaWduIGFzIHMsIHRvUmFkaWFucyBhcyB0LCB1bmxpc3RlbkFycmF5RXZlbnRzIGFzIHUsIHZhbHVlT3JEZWZhdWx0IGFzIHYsIF9zY2FsZVJhbmdlc0NoYW5nZWQgYXMgdywgaXNOdW1iZXIgYXMgeCwgX3BhcnNlT2JqZWN0RGF0YVJhZGlhbFNjYWxlIGFzIHksIGdldFJlbGF0aXZlUG9zaXRpb24gYXMgeiB9O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aGVscGVycy5zZWdtZW50LmpzLm1hcFxuIiwiLyohXG4gKiBDaGFydC5qcyB2NC40LjRcbiAqIGh0dHBzOi8vd3d3LmNoYXJ0anMub3JnXG4gKiAoYykgMjAyNCBDaGFydC5qcyBDb250cmlidXRvcnNcbiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZVxuICovXG5pbXBvcnQgeyByIGFzIHJlcXVlc3RBbmltRnJhbWUsIGEgYXMgcmVzb2x2ZSwgZSBhcyBlZmZlY3RzLCBjIGFzIGNvbG9yLCBpIGFzIGlzT2JqZWN0LCBkIGFzIGRlZmF1bHRzLCBiIGFzIGlzQXJyYXksIHYgYXMgdmFsdWVPckRlZmF1bHQsIHUgYXMgdW5saXN0ZW5BcnJheUV2ZW50cywgbCBhcyBsaXN0ZW5BcnJheUV2ZW50cywgZiBhcyByZXNvbHZlT2JqZWN0S2V5LCBnIGFzIGlzTnVtYmVyRmluaXRlLCBoIGFzIGRlZmluZWQsIHMgYXMgc2lnbiwgaiBhcyBjcmVhdGVDb250ZXh0LCBrIGFzIGlzTnVsbE9yVW5kZWYsIF8gYXMgX2FycmF5VW5pcXVlLCB0IGFzIHRvUmFkaWFucywgbSBhcyB0b1BlcmNlbnRhZ2UsIG4gYXMgdG9EaW1lbnNpb24sIFQgYXMgVEFVLCBvIGFzIGZvcm1hdE51bWJlciwgcCBhcyBfYW5nbGVCZXR3ZWVuLCBIIGFzIEhBTEZfUEksIFAgYXMgUEksIHEgYXMgX2dldFN0YXJ0QW5kQ291bnRPZlZpc2libGVQb2ludHMsIHcgYXMgX3NjYWxlUmFuZ2VzQ2hhbmdlZCwgeCBhcyBpc051bWJlciwgeSBhcyBfcGFyc2VPYmplY3REYXRhUmFkaWFsU2NhbGUsIHogYXMgZ2V0UmVsYXRpdmVQb3NpdGlvbiwgQSBhcyBfcmxvb2t1cEJ5S2V5LCBCIGFzIF9sb29rdXBCeUtleSwgQyBhcyBfaXNQb2ludEluQXJlYSwgRCBhcyBnZXRBbmdsZUZyb21Qb2ludCwgRSBhcyB0b1BhZGRpbmcsIEYgYXMgZWFjaCwgRyBhcyBnZXRNYXhpbXVtU2l6ZSwgSSBhcyBfZ2V0UGFyZW50Tm9kZSwgSiBhcyByZWFkVXNlZFNpemUsIEsgYXMgc3VwcG9ydHNFdmVudExpc3RlbmVyT3B0aW9ucywgTCBhcyB0aHJvdHRsZWQsIE0gYXMgX2lzRG9tU3VwcG9ydGVkLCBOIGFzIF9mYWN0b3JpemUsIE8gYXMgZmluaXRlT3JEZWZhdWx0LCBRIGFzIGNhbGxiYWNrLCBSIGFzIF9hZGRHcmFjZSwgUyBhcyBfbGltaXRWYWx1ZSwgVSBhcyB0b0RlZ3JlZXMsIFYgYXMgX21lYXN1cmVUZXh0LCBXIGFzIF9pbnQxNlJhbmdlLCBYIGFzIF9hbGlnblBpeGVsLCBZIGFzIGNsaXBBcmVhLCBaIGFzIHJlbmRlclRleHQsICQgYXMgdW5jbGlwQXJlYSwgYTAgYXMgdG9Gb250LCBhMSBhcyBfdG9MZWZ0UmlnaHRDZW50ZXIsIGEyIGFzIF9hbGlnblN0YXJ0RW5kLCBhMyBhcyBvdmVycmlkZXMsIGE0IGFzIG1lcmdlLCBhNSBhcyBfY2FwaXRhbGl6ZSwgYTYgYXMgZGVzY3JpcHRvcnMsIGE3IGFzIGlzRnVuY3Rpb24sIGE4IGFzIF9hdHRhY2hDb250ZXh0LCBhOSBhcyBfY3JlYXRlUmVzb2x2ZXIsIGFhIGFzIF9kZXNjcmlwdG9ycywgYWIgYXMgbWVyZ2VJZiwgYWMgYXMgdWlkLCBhZCBhcyBkZWJvdW5jZSwgYWUgYXMgcmV0aW5hU2NhbGUsIGFmIGFzIGNsZWFyQ2FudmFzLCBhZyBhcyBzZXRzRXF1YWwsIGFoIGFzIF9lbGVtZW50c0VxdWFsLCBhaSBhcyBfaXNDbGlja0V2ZW50LCBhaiBhcyBfaXNCZXR3ZWVuLCBhayBhcyBfcmVhZFZhbHVlVG9Qcm9wcywgYWwgYXMgX3VwZGF0ZUJlemllckNvbnRyb2xQb2ludHMsIGFtIGFzIF9jb21wdXRlU2VnbWVudHMsIGFuIGFzIF9ib3VuZFNlZ21lbnRzLCBhbyBhcyBfc3RlcHBlZEludGVycG9sYXRpb24sIGFwIGFzIF9iZXppZXJJbnRlcnBvbGF0aW9uLCBhcSBhcyBfcG9pbnRJbkxpbmUsIGFyIGFzIF9zdGVwcGVkTGluZVRvLCBhcyBhcyBfYmV6aWVyQ3VydmVUbywgYXQgYXMgZHJhd1BvaW50LCBhdSBhcyBhZGRSb3VuZGVkUmVjdFBhdGgsIGF2IGFzIHRvVFJCTCwgYXcgYXMgdG9UUkJMQ29ybmVycywgYXggYXMgX2JvdW5kU2VnbWVudCwgYXkgYXMgX25vcm1hbGl6ZUFuZ2xlLCBheiBhcyBnZXRSdGxBZGFwdGVyLCBhQSBhcyBvdmVycmlkZVRleHREaXJlY3Rpb24sIGFCIGFzIF90ZXh0WCwgYUMgYXMgcmVzdG9yZVRleHREaXJlY3Rpb24sIGFEIGFzIGRyYXdQb2ludExlZ2VuZCwgYUUgYXMgZGlzdGFuY2VCZXR3ZWVuUG9pbnRzLCBhRiBhcyBub29wLCBhRyBhcyBfc2V0TWluQW5kTWF4QnlLZXksIGFIIGFzIG5pY2VOdW0sIGFJIGFzIGFsbW9zdFdob2xlLCBhSiBhcyBhbG1vc3RFcXVhbHMsIGFLIGFzIF9kZWNpbWFsUGxhY2VzLCBhTCBhcyBUaWNrcywgYU0gYXMgbG9nMTAsIGFOIGFzIF9sb25nZXN0VGV4dCwgYU8gYXMgX2ZpbHRlckJldHdlZW4sIGFQIGFzIF9sb29rdXAgfSBmcm9tICcuL2NodW5rcy9oZWxwZXJzLnNlZ21lbnQuanMnO1xuaW1wb3J0ICdAa3Vya2xlL2NvbG9yJztcblxuY2xhc3MgQW5pbWF0b3Ige1xuICAgIGNvbnN0cnVjdG9yKCl7XG4gICAgICAgIHRoaXMuX3JlcXVlc3QgPSBudWxsO1xuICAgICAgICB0aGlzLl9jaGFydHMgPSBuZXcgTWFwKCk7XG4gICAgICAgIHRoaXMuX3J1bm5pbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fbGFzdERhdGUgPSB1bmRlZmluZWQ7XG4gICAgfVxuIF9ub3RpZnkoY2hhcnQsIGFuaW1zLCBkYXRlLCB0eXBlKSB7XG4gICAgICAgIGNvbnN0IGNhbGxiYWNrcyA9IGFuaW1zLmxpc3RlbmVyc1t0eXBlXTtcbiAgICAgICAgY29uc3QgbnVtU3RlcHMgPSBhbmltcy5kdXJhdGlvbjtcbiAgICAgICAgY2FsbGJhY2tzLmZvckVhY2goKGZuKT0+Zm4oe1xuICAgICAgICAgICAgICAgIGNoYXJ0LFxuICAgICAgICAgICAgICAgIGluaXRpYWw6IGFuaW1zLmluaXRpYWwsXG4gICAgICAgICAgICAgICAgbnVtU3RlcHMsXG4gICAgICAgICAgICAgICAgY3VycmVudFN0ZXA6IE1hdGgubWluKGRhdGUgLSBhbmltcy5zdGFydCwgbnVtU3RlcHMpXG4gICAgICAgICAgICB9KSk7XG4gICAgfVxuIF9yZWZyZXNoKCkge1xuICAgICAgICBpZiAodGhpcy5fcmVxdWVzdCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3J1bm5pbmcgPSB0cnVlO1xuICAgICAgICB0aGlzLl9yZXF1ZXN0ID0gcmVxdWVzdEFuaW1GcmFtZS5jYWxsKHdpbmRvdywgKCk9PntcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZSgpO1xuICAgICAgICAgICAgdGhpcy5fcmVxdWVzdCA9IG51bGw7XG4gICAgICAgICAgICBpZiAodGhpcy5fcnVubmluZykge1xuICAgICAgICAgICAgICAgIHRoaXMuX3JlZnJlc2goKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuIF91cGRhdGUoZGF0ZSA9IERhdGUubm93KCkpIHtcbiAgICAgICAgbGV0IHJlbWFpbmluZyA9IDA7XG4gICAgICAgIHRoaXMuX2NoYXJ0cy5mb3JFYWNoKChhbmltcywgY2hhcnQpPT57XG4gICAgICAgICAgICBpZiAoIWFuaW1zLnJ1bm5pbmcgfHwgIWFuaW1zLml0ZW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGl0ZW1zID0gYW5pbXMuaXRlbXM7XG4gICAgICAgICAgICBsZXQgaSA9IGl0ZW1zLmxlbmd0aCAtIDE7XG4gICAgICAgICAgICBsZXQgZHJhdyA9IGZhbHNlO1xuICAgICAgICAgICAgbGV0IGl0ZW07XG4gICAgICAgICAgICBmb3IoOyBpID49IDA7IC0taSl7XG4gICAgICAgICAgICAgICAgaXRlbSA9IGl0ZW1zW2ldO1xuICAgICAgICAgICAgICAgIGlmIChpdGVtLl9hY3RpdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW0uX3RvdGFsID4gYW5pbXMuZHVyYXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFuaW1zLmR1cmF0aW9uID0gaXRlbS5fdG90YWw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaXRlbS50aWNrKGRhdGUpO1xuICAgICAgICAgICAgICAgICAgICBkcmF3ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpdGVtc1tpXSA9IGl0ZW1zW2l0ZW1zLmxlbmd0aCAtIDFdO1xuICAgICAgICAgICAgICAgICAgICBpdGVtcy5wb3AoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZHJhdykge1xuICAgICAgICAgICAgICAgIGNoYXJ0LmRyYXcoKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9ub3RpZnkoY2hhcnQsIGFuaW1zLCBkYXRlLCAncHJvZ3Jlc3MnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghaXRlbXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgYW5pbXMucnVubmluZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRoaXMuX25vdGlmeShjaGFydCwgYW5pbXMsIGRhdGUsICdjb21wbGV0ZScpO1xuICAgICAgICAgICAgICAgIGFuaW1zLmluaXRpYWwgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbWFpbmluZyArPSBpdGVtcy5sZW5ndGg7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9sYXN0RGF0ZSA9IGRhdGU7XG4gICAgICAgIGlmIChyZW1haW5pbmcgPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMuX3J1bm5pbmcgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbiBfZ2V0QW5pbXMoY2hhcnQpIHtcbiAgICAgICAgY29uc3QgY2hhcnRzID0gdGhpcy5fY2hhcnRzO1xuICAgICAgICBsZXQgYW5pbXMgPSBjaGFydHMuZ2V0KGNoYXJ0KTtcbiAgICAgICAgaWYgKCFhbmltcykge1xuICAgICAgICAgICAgYW5pbXMgPSB7XG4gICAgICAgICAgICAgICAgcnVubmluZzogZmFsc2UsXG4gICAgICAgICAgICAgICAgaW5pdGlhbDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBpdGVtczogW10sXG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzOiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlOiBbXSxcbiAgICAgICAgICAgICAgICAgICAgcHJvZ3Jlc3M6IFtdXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNoYXJ0cy5zZXQoY2hhcnQsIGFuaW1zKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYW5pbXM7XG4gICAgfVxuIGxpc3RlbihjaGFydCwgZXZlbnQsIGNiKSB7XG4gICAgICAgIHRoaXMuX2dldEFuaW1zKGNoYXJ0KS5saXN0ZW5lcnNbZXZlbnRdLnB1c2goY2IpO1xuICAgIH1cbiBhZGQoY2hhcnQsIGl0ZW1zKSB7XG4gICAgICAgIGlmICghaXRlbXMgfHwgIWl0ZW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2dldEFuaW1zKGNoYXJ0KS5pdGVtcy5wdXNoKC4uLml0ZW1zKTtcbiAgICB9XG4gaGFzKGNoYXJ0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRBbmltcyhjaGFydCkuaXRlbXMubGVuZ3RoID4gMDtcbiAgICB9XG4gc3RhcnQoY2hhcnQpIHtcbiAgICAgICAgY29uc3QgYW5pbXMgPSB0aGlzLl9jaGFydHMuZ2V0KGNoYXJ0KTtcbiAgICAgICAgaWYgKCFhbmltcykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGFuaW1zLnJ1bm5pbmcgPSB0cnVlO1xuICAgICAgICBhbmltcy5zdGFydCA9IERhdGUubm93KCk7XG4gICAgICAgIGFuaW1zLmR1cmF0aW9uID0gYW5pbXMuaXRlbXMucmVkdWNlKChhY2MsIGN1cik9Pk1hdGgubWF4KGFjYywgY3VyLl9kdXJhdGlvbiksIDApO1xuICAgICAgICB0aGlzLl9yZWZyZXNoKCk7XG4gICAgfVxuICAgIHJ1bm5pbmcoY2hhcnQpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9ydW5uaW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYW5pbXMgPSB0aGlzLl9jaGFydHMuZ2V0KGNoYXJ0KTtcbiAgICAgICAgaWYgKCFhbmltcyB8fCAhYW5pbXMucnVubmluZyB8fCAhYW5pbXMuaXRlbXMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuIHN0b3AoY2hhcnQpIHtcbiAgICAgICAgY29uc3QgYW5pbXMgPSB0aGlzLl9jaGFydHMuZ2V0KGNoYXJ0KTtcbiAgICAgICAgaWYgKCFhbmltcyB8fCAhYW5pbXMuaXRlbXMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaXRlbXMgPSBhbmltcy5pdGVtcztcbiAgICAgICAgbGV0IGkgPSBpdGVtcy5sZW5ndGggLSAxO1xuICAgICAgICBmb3IoOyBpID49IDA7IC0taSl7XG4gICAgICAgICAgICBpdGVtc1tpXS5jYW5jZWwoKTtcbiAgICAgICAgfVxuICAgICAgICBhbmltcy5pdGVtcyA9IFtdO1xuICAgICAgICB0aGlzLl9ub3RpZnkoY2hhcnQsIGFuaW1zLCBEYXRlLm5vdygpLCAnY29tcGxldGUnKTtcbiAgICB9XG4gcmVtb3ZlKGNoYXJ0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jaGFydHMuZGVsZXRlKGNoYXJ0KTtcbiAgICB9XG59XG52YXIgYW5pbWF0b3IgPSAvKiAjX19QVVJFX18gKi8gbmV3IEFuaW1hdG9yKCk7XG5cbmNvbnN0IHRyYW5zcGFyZW50ID0gJ3RyYW5zcGFyZW50JztcbmNvbnN0IGludGVycG9sYXRvcnMgPSB7XG4gICAgYm9vbGVhbiAoZnJvbSwgdG8sIGZhY3Rvcikge1xuICAgICAgICByZXR1cm4gZmFjdG9yID4gMC41ID8gdG8gOiBmcm9tO1xuICAgIH0sXG4gY29sb3IgKGZyb20sIHRvLCBmYWN0b3IpIHtcbiAgICAgICAgY29uc3QgYzAgPSBjb2xvcihmcm9tIHx8IHRyYW5zcGFyZW50KTtcbiAgICAgICAgY29uc3QgYzEgPSBjMC52YWxpZCAmJiBjb2xvcih0byB8fCB0cmFuc3BhcmVudCk7XG4gICAgICAgIHJldHVybiBjMSAmJiBjMS52YWxpZCA/IGMxLm1peChjMCwgZmFjdG9yKS5oZXhTdHJpbmcoKSA6IHRvO1xuICAgIH0sXG4gICAgbnVtYmVyIChmcm9tLCB0bywgZmFjdG9yKSB7XG4gICAgICAgIHJldHVybiBmcm9tICsgKHRvIC0gZnJvbSkgKiBmYWN0b3I7XG4gICAgfVxufTtcbmNsYXNzIEFuaW1hdGlvbiB7XG4gICAgY29uc3RydWN0b3IoY2ZnLCB0YXJnZXQsIHByb3AsIHRvKXtcbiAgICAgICAgY29uc3QgY3VycmVudFZhbHVlID0gdGFyZ2V0W3Byb3BdO1xuICAgICAgICB0byA9IHJlc29sdmUoW1xuICAgICAgICAgICAgY2ZnLnRvLFxuICAgICAgICAgICAgdG8sXG4gICAgICAgICAgICBjdXJyZW50VmFsdWUsXG4gICAgICAgICAgICBjZmcuZnJvbVxuICAgICAgICBdKTtcbiAgICAgICAgY29uc3QgZnJvbSA9IHJlc29sdmUoW1xuICAgICAgICAgICAgY2ZnLmZyb20sXG4gICAgICAgICAgICBjdXJyZW50VmFsdWUsXG4gICAgICAgICAgICB0b1xuICAgICAgICBdKTtcbiAgICAgICAgdGhpcy5fYWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fZm4gPSBjZmcuZm4gfHwgaW50ZXJwb2xhdG9yc1tjZmcudHlwZSB8fCB0eXBlb2YgZnJvbV07XG4gICAgICAgIHRoaXMuX2Vhc2luZyA9IGVmZmVjdHNbY2ZnLmVhc2luZ10gfHwgZWZmZWN0cy5saW5lYXI7XG4gICAgICAgIHRoaXMuX3N0YXJ0ID0gTWF0aC5mbG9vcihEYXRlLm5vdygpICsgKGNmZy5kZWxheSB8fCAwKSk7XG4gICAgICAgIHRoaXMuX2R1cmF0aW9uID0gdGhpcy5fdG90YWwgPSBNYXRoLmZsb29yKGNmZy5kdXJhdGlvbik7XG4gICAgICAgIHRoaXMuX2xvb3AgPSAhIWNmZy5sb29wO1xuICAgICAgICB0aGlzLl90YXJnZXQgPSB0YXJnZXQ7XG4gICAgICAgIHRoaXMuX3Byb3AgPSBwcm9wO1xuICAgICAgICB0aGlzLl9mcm9tID0gZnJvbTtcbiAgICAgICAgdGhpcy5fdG8gPSB0bztcbiAgICAgICAgdGhpcy5fcHJvbWlzZXMgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGFjdGl2ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FjdGl2ZTtcbiAgICB9XG4gICAgdXBkYXRlKGNmZywgdG8sIGRhdGUpIHtcbiAgICAgICAgaWYgKHRoaXMuX2FjdGl2ZSkge1xuICAgICAgICAgICAgdGhpcy5fbm90aWZ5KGZhbHNlKTtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRWYWx1ZSA9IHRoaXMuX3RhcmdldFt0aGlzLl9wcm9wXTtcbiAgICAgICAgICAgIGNvbnN0IGVsYXBzZWQgPSBkYXRlIC0gdGhpcy5fc3RhcnQ7XG4gICAgICAgICAgICBjb25zdCByZW1haW4gPSB0aGlzLl9kdXJhdGlvbiAtIGVsYXBzZWQ7XG4gICAgICAgICAgICB0aGlzLl9zdGFydCA9IGRhdGU7XG4gICAgICAgICAgICB0aGlzLl9kdXJhdGlvbiA9IE1hdGguZmxvb3IoTWF0aC5tYXgocmVtYWluLCBjZmcuZHVyYXRpb24pKTtcbiAgICAgICAgICAgIHRoaXMuX3RvdGFsICs9IGVsYXBzZWQ7XG4gICAgICAgICAgICB0aGlzLl9sb29wID0gISFjZmcubG9vcDtcbiAgICAgICAgICAgIHRoaXMuX3RvID0gcmVzb2x2ZShbXG4gICAgICAgICAgICAgICAgY2ZnLnRvLFxuICAgICAgICAgICAgICAgIHRvLFxuICAgICAgICAgICAgICAgIGN1cnJlbnRWYWx1ZSxcbiAgICAgICAgICAgICAgICBjZmcuZnJvbVxuICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICB0aGlzLl9mcm9tID0gcmVzb2x2ZShbXG4gICAgICAgICAgICAgICAgY2ZnLmZyb20sXG4gICAgICAgICAgICAgICAgY3VycmVudFZhbHVlLFxuICAgICAgICAgICAgICAgIHRvXG4gICAgICAgICAgICBdKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjYW5jZWwoKSB7XG4gICAgICAgIGlmICh0aGlzLl9hY3RpdmUpIHtcbiAgICAgICAgICAgIHRoaXMudGljayhEYXRlLm5vdygpKTtcbiAgICAgICAgICAgIHRoaXMuX2FjdGl2ZSA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5fbm90aWZ5KGZhbHNlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICB0aWNrKGRhdGUpIHtcbiAgICAgICAgY29uc3QgZWxhcHNlZCA9IGRhdGUgLSB0aGlzLl9zdGFydDtcbiAgICAgICAgY29uc3QgZHVyYXRpb24gPSB0aGlzLl9kdXJhdGlvbjtcbiAgICAgICAgY29uc3QgcHJvcCA9IHRoaXMuX3Byb3A7XG4gICAgICAgIGNvbnN0IGZyb20gPSB0aGlzLl9mcm9tO1xuICAgICAgICBjb25zdCBsb29wID0gdGhpcy5fbG9vcDtcbiAgICAgICAgY29uc3QgdG8gPSB0aGlzLl90bztcbiAgICAgICAgbGV0IGZhY3RvcjtcbiAgICAgICAgdGhpcy5fYWN0aXZlID0gZnJvbSAhPT0gdG8gJiYgKGxvb3AgfHwgZWxhcHNlZCA8IGR1cmF0aW9uKTtcbiAgICAgICAgaWYgKCF0aGlzLl9hY3RpdmUpIHtcbiAgICAgICAgICAgIHRoaXMuX3RhcmdldFtwcm9wXSA9IHRvO1xuICAgICAgICAgICAgdGhpcy5fbm90aWZ5KHRydWUpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChlbGFwc2VkIDwgMCkge1xuICAgICAgICAgICAgdGhpcy5fdGFyZ2V0W3Byb3BdID0gZnJvbTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBmYWN0b3IgPSBlbGFwc2VkIC8gZHVyYXRpb24gJSAyO1xuICAgICAgICBmYWN0b3IgPSBsb29wICYmIGZhY3RvciA+IDEgPyAyIC0gZmFjdG9yIDogZmFjdG9yO1xuICAgICAgICBmYWN0b3IgPSB0aGlzLl9lYXNpbmcoTWF0aC5taW4oMSwgTWF0aC5tYXgoMCwgZmFjdG9yKSkpO1xuICAgICAgICB0aGlzLl90YXJnZXRbcHJvcF0gPSB0aGlzLl9mbihmcm9tLCB0bywgZmFjdG9yKTtcbiAgICB9XG4gICAgd2FpdCgpIHtcbiAgICAgICAgY29uc3QgcHJvbWlzZXMgPSB0aGlzLl9wcm9taXNlcyB8fCAodGhpcy5fcHJvbWlzZXMgPSBbXSk7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzLCByZWopPT57XG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICByZXMsXG4gICAgICAgICAgICAgICAgcmVqXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIF9ub3RpZnkocmVzb2x2ZWQpIHtcbiAgICAgICAgY29uc3QgbWV0aG9kID0gcmVzb2x2ZWQgPyAncmVzJyA6ICdyZWonO1xuICAgICAgICBjb25zdCBwcm9taXNlcyA9IHRoaXMuX3Byb21pc2VzIHx8IFtdO1xuICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgcHJvbWlzZXMubGVuZ3RoOyBpKyspe1xuICAgICAgICAgICAgcHJvbWlzZXNbaV1bbWV0aG9kXSgpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5jbGFzcyBBbmltYXRpb25zIHtcbiAgICBjb25zdHJ1Y3RvcihjaGFydCwgY29uZmlnKXtcbiAgICAgICAgdGhpcy5fY2hhcnQgPSBjaGFydDtcbiAgICAgICAgdGhpcy5fcHJvcGVydGllcyA9IG5ldyBNYXAoKTtcbiAgICAgICAgdGhpcy5jb25maWd1cmUoY29uZmlnKTtcbiAgICB9XG4gICAgY29uZmlndXJlKGNvbmZpZykge1xuICAgICAgICBpZiAoIWlzT2JqZWN0KGNvbmZpZykpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhbmltYXRpb25PcHRpb25zID0gT2JqZWN0LmtleXMoZGVmYXVsdHMuYW5pbWF0aW9uKTtcbiAgICAgICAgY29uc3QgYW5pbWF0ZWRQcm9wcyA9IHRoaXMuX3Byb3BlcnRpZXM7XG4gICAgICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGNvbmZpZykuZm9yRWFjaCgoa2V5KT0+e1xuICAgICAgICAgICAgY29uc3QgY2ZnID0gY29uZmlnW2tleV07XG4gICAgICAgICAgICBpZiAoIWlzT2JqZWN0KGNmZykpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCByZXNvbHZlZCA9IHt9O1xuICAgICAgICAgICAgZm9yIChjb25zdCBvcHRpb24gb2YgYW5pbWF0aW9uT3B0aW9ucyl7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZWRbb3B0aW9uXSA9IGNmZ1tvcHRpb25dO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgKGlzQXJyYXkoY2ZnLnByb3BlcnRpZXMpICYmIGNmZy5wcm9wZXJ0aWVzIHx8IFtcbiAgICAgICAgICAgICAgICBrZXlcbiAgICAgICAgICAgIF0pLmZvckVhY2goKHByb3ApPT57XG4gICAgICAgICAgICAgICAgaWYgKHByb3AgPT09IGtleSB8fCAhYW5pbWF0ZWRQcm9wcy5oYXMocHJvcCkpIHtcbiAgICAgICAgICAgICAgICAgICAgYW5pbWF0ZWRQcm9wcy5zZXQocHJvcCwgcmVzb2x2ZWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gX2FuaW1hdGVPcHRpb25zKHRhcmdldCwgdmFsdWVzKSB7XG4gICAgICAgIGNvbnN0IG5ld09wdGlvbnMgPSB2YWx1ZXMub3B0aW9ucztcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHJlc29sdmVUYXJnZXRPcHRpb25zKHRhcmdldCwgbmV3T3B0aW9ucyk7XG4gICAgICAgIGlmICghb3B0aW9ucykge1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFuaW1hdGlvbnMgPSB0aGlzLl9jcmVhdGVBbmltYXRpb25zKG9wdGlvbnMsIG5ld09wdGlvbnMpO1xuICAgICAgICBpZiAobmV3T3B0aW9ucy4kc2hhcmVkKSB7XG4gICAgICAgICAgICBhd2FpdEFsbCh0YXJnZXQub3B0aW9ucy4kYW5pbWF0aW9ucywgbmV3T3B0aW9ucykudGhlbigoKT0+e1xuICAgICAgICAgICAgICAgIHRhcmdldC5vcHRpb25zID0gbmV3T3B0aW9ucztcbiAgICAgICAgICAgIH0sICgpPT57XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYW5pbWF0aW9ucztcbiAgICB9XG4gX2NyZWF0ZUFuaW1hdGlvbnModGFyZ2V0LCB2YWx1ZXMpIHtcbiAgICAgICAgY29uc3QgYW5pbWF0ZWRQcm9wcyA9IHRoaXMuX3Byb3BlcnRpZXM7XG4gICAgICAgIGNvbnN0IGFuaW1hdGlvbnMgPSBbXTtcbiAgICAgICAgY29uc3QgcnVubmluZyA9IHRhcmdldC4kYW5pbWF0aW9ucyB8fCAodGFyZ2V0LiRhbmltYXRpb25zID0ge30pO1xuICAgICAgICBjb25zdCBwcm9wcyA9IE9iamVjdC5rZXlzKHZhbHVlcyk7XG4gICAgICAgIGNvbnN0IGRhdGUgPSBEYXRlLm5vdygpO1xuICAgICAgICBsZXQgaTtcbiAgICAgICAgZm9yKGkgPSBwcm9wcy5sZW5ndGggLSAxOyBpID49IDA7IC0taSl7XG4gICAgICAgICAgICBjb25zdCBwcm9wID0gcHJvcHNbaV07XG4gICAgICAgICAgICBpZiAocHJvcC5jaGFyQXQoMCkgPT09ICckJykge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHByb3AgPT09ICdvcHRpb25zJykge1xuICAgICAgICAgICAgICAgIGFuaW1hdGlvbnMucHVzaCguLi50aGlzLl9hbmltYXRlT3B0aW9ucyh0YXJnZXQsIHZhbHVlcykpO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSB2YWx1ZXNbcHJvcF07XG4gICAgICAgICAgICBsZXQgYW5pbWF0aW9uID0gcnVubmluZ1twcm9wXTtcbiAgICAgICAgICAgIGNvbnN0IGNmZyA9IGFuaW1hdGVkUHJvcHMuZ2V0KHByb3ApO1xuICAgICAgICAgICAgaWYgKGFuaW1hdGlvbikge1xuICAgICAgICAgICAgICAgIGlmIChjZmcgJiYgYW5pbWF0aW9uLmFjdGl2ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIGFuaW1hdGlvbi51cGRhdGUoY2ZnLCB2YWx1ZSwgZGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGFuaW1hdGlvbi5jYW5jZWwoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWNmZyB8fCAhY2ZnLmR1cmF0aW9uKSB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0W3Byb3BdID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBydW5uaW5nW3Byb3BdID0gYW5pbWF0aW9uID0gbmV3IEFuaW1hdGlvbihjZmcsIHRhcmdldCwgcHJvcCwgdmFsdWUpO1xuICAgICAgICAgICAgYW5pbWF0aW9ucy5wdXNoKGFuaW1hdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFuaW1hdGlvbnM7XG4gICAgfVxuIHVwZGF0ZSh0YXJnZXQsIHZhbHVlcykge1xuICAgICAgICBpZiAodGhpcy5fcHJvcGVydGllcy5zaXplID09PSAwKSB7XG4gICAgICAgICAgICBPYmplY3QuYXNzaWduKHRhcmdldCwgdmFsdWVzKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhbmltYXRpb25zID0gdGhpcy5fY3JlYXRlQW5pbWF0aW9ucyh0YXJnZXQsIHZhbHVlcyk7XG4gICAgICAgIGlmIChhbmltYXRpb25zLmxlbmd0aCkge1xuICAgICAgICAgICAgYW5pbWF0b3IuYWRkKHRoaXMuX2NoYXJ0LCBhbmltYXRpb25zKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gYXdhaXRBbGwoYW5pbWF0aW9ucywgcHJvcGVydGllcykge1xuICAgIGNvbnN0IHJ1bm5pbmcgPSBbXTtcbiAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyk7XG4gICAgZm9yKGxldCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspe1xuICAgICAgICBjb25zdCBhbmltID0gYW5pbWF0aW9uc1trZXlzW2ldXTtcbiAgICAgICAgaWYgKGFuaW0gJiYgYW5pbS5hY3RpdmUoKSkge1xuICAgICAgICAgICAgcnVubmluZy5wdXNoKGFuaW0ud2FpdCgpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwocnVubmluZyk7XG59XG5mdW5jdGlvbiByZXNvbHZlVGFyZ2V0T3B0aW9ucyh0YXJnZXQsIG5ld09wdGlvbnMpIHtcbiAgICBpZiAoIW5ld09wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgb3B0aW9ucyA9IHRhcmdldC5vcHRpb25zO1xuICAgIGlmICghb3B0aW9ucykge1xuICAgICAgICB0YXJnZXQub3B0aW9ucyA9IG5ld09wdGlvbnM7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnMuJHNoYXJlZCkge1xuICAgICAgICB0YXJnZXQub3B0aW9ucyA9IG9wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCBvcHRpb25zLCB7XG4gICAgICAgICAgICAkc2hhcmVkOiBmYWxzZSxcbiAgICAgICAgICAgICRhbmltYXRpb25zOiB7fVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIG9wdGlvbnM7XG59XG5cbmZ1bmN0aW9uIHNjYWxlQ2xpcChzY2FsZSwgYWxsb3dlZE92ZXJmbG93KSB7XG4gICAgY29uc3Qgb3B0cyA9IHNjYWxlICYmIHNjYWxlLm9wdGlvbnMgfHwge307XG4gICAgY29uc3QgcmV2ZXJzZSA9IG9wdHMucmV2ZXJzZTtcbiAgICBjb25zdCBtaW4gPSBvcHRzLm1pbiA9PT0gdW5kZWZpbmVkID8gYWxsb3dlZE92ZXJmbG93IDogMDtcbiAgICBjb25zdCBtYXggPSBvcHRzLm1heCA9PT0gdW5kZWZpbmVkID8gYWxsb3dlZE92ZXJmbG93IDogMDtcbiAgICByZXR1cm4ge1xuICAgICAgICBzdGFydDogcmV2ZXJzZSA/IG1heCA6IG1pbixcbiAgICAgICAgZW5kOiByZXZlcnNlID8gbWluIDogbWF4XG4gICAgfTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRDbGlwKHhTY2FsZSwgeVNjYWxlLCBhbGxvd2VkT3ZlcmZsb3cpIHtcbiAgICBpZiAoYWxsb3dlZE92ZXJmbG93ID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IHggPSBzY2FsZUNsaXAoeFNjYWxlLCBhbGxvd2VkT3ZlcmZsb3cpO1xuICAgIGNvbnN0IHkgPSBzY2FsZUNsaXAoeVNjYWxlLCBhbGxvd2VkT3ZlcmZsb3cpO1xuICAgIHJldHVybiB7XG4gICAgICAgIHRvcDogeS5lbmQsXG4gICAgICAgIHJpZ2h0OiB4LmVuZCxcbiAgICAgICAgYm90dG9tOiB5LnN0YXJ0LFxuICAgICAgICBsZWZ0OiB4LnN0YXJ0XG4gICAgfTtcbn1cbmZ1bmN0aW9uIHRvQ2xpcCh2YWx1ZSkge1xuICAgIGxldCB0LCByLCBiLCBsO1xuICAgIGlmIChpc09iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgdCA9IHZhbHVlLnRvcDtcbiAgICAgICAgciA9IHZhbHVlLnJpZ2h0O1xuICAgICAgICBiID0gdmFsdWUuYm90dG9tO1xuICAgICAgICBsID0gdmFsdWUubGVmdDtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0ID0gciA9IGIgPSBsID0gdmFsdWU7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHRvcDogdCxcbiAgICAgICAgcmlnaHQ6IHIsXG4gICAgICAgIGJvdHRvbTogYixcbiAgICAgICAgbGVmdDogbCxcbiAgICAgICAgZGlzYWJsZWQ6IHZhbHVlID09PSBmYWxzZVxuICAgIH07XG59XG5mdW5jdGlvbiBnZXRTb3J0ZWREYXRhc2V0SW5kaWNlcyhjaGFydCwgZmlsdGVyVmlzaWJsZSkge1xuICAgIGNvbnN0IGtleXMgPSBbXTtcbiAgICBjb25zdCBtZXRhc2V0cyA9IGNoYXJ0Ll9nZXRTb3J0ZWREYXRhc2V0TWV0YXMoZmlsdGVyVmlzaWJsZSk7XG4gICAgbGV0IGksIGlsZW47XG4gICAgZm9yKGkgPSAwLCBpbGVuID0gbWV0YXNldHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKXtcbiAgICAgICAga2V5cy5wdXNoKG1ldGFzZXRzW2ldLmluZGV4KTtcbiAgICB9XG4gICAgcmV0dXJuIGtleXM7XG59XG5mdW5jdGlvbiBhcHBseVN0YWNrKHN0YWNrLCB2YWx1ZSwgZHNJbmRleCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3Qga2V5cyA9IHN0YWNrLmtleXM7XG4gICAgY29uc3Qgc2luZ2xlTW9kZSA9IG9wdGlvbnMubW9kZSA9PT0gJ3NpbmdsZSc7XG4gICAgbGV0IGksIGlsZW4sIGRhdGFzZXRJbmRleCwgb3RoZXJWYWx1ZTtcbiAgICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IoaSA9IDAsIGlsZW4gPSBrZXlzLmxlbmd0aDsgaSA8IGlsZW47ICsraSl7XG4gICAgICAgIGRhdGFzZXRJbmRleCA9ICtrZXlzW2ldO1xuICAgICAgICBpZiAoZGF0YXNldEluZGV4ID09PSBkc0luZGV4KSB7XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5hbGwpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIG90aGVyVmFsdWUgPSBzdGFjay52YWx1ZXNbZGF0YXNldEluZGV4XTtcbiAgICAgICAgaWYgKGlzTnVtYmVyRmluaXRlKG90aGVyVmFsdWUpICYmIChzaW5nbGVNb2RlIHx8IHZhbHVlID09PSAwIHx8IHNpZ24odmFsdWUpID09PSBzaWduKG90aGVyVmFsdWUpKSkge1xuICAgICAgICAgICAgdmFsdWUgKz0gb3RoZXJWYWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG59XG5mdW5jdGlvbiBjb252ZXJ0T2JqZWN0RGF0YVRvQXJyYXkoZGF0YSwgbWV0YSkge1xuICAgIGNvbnN0IHsgaVNjYWxlICwgdlNjYWxlICB9ID0gbWV0YTtcbiAgICBjb25zdCBpQXhpc0tleSA9IGlTY2FsZS5heGlzID09PSAneCcgPyAneCcgOiAneSc7XG4gICAgY29uc3QgdkF4aXNLZXkgPSB2U2NhbGUuYXhpcyA9PT0gJ3gnID8gJ3gnIDogJ3knO1xuICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhkYXRhKTtcbiAgICBjb25zdCBhZGF0YSA9IG5ldyBBcnJheShrZXlzLmxlbmd0aCk7XG4gICAgbGV0IGksIGlsZW4sIGtleTtcbiAgICBmb3IoaSA9IDAsIGlsZW4gPSBrZXlzLmxlbmd0aDsgaSA8IGlsZW47ICsraSl7XG4gICAgICAgIGtleSA9IGtleXNbaV07XG4gICAgICAgIGFkYXRhW2ldID0ge1xuICAgICAgICAgICAgW2lBeGlzS2V5XToga2V5LFxuICAgICAgICAgICAgW3ZBeGlzS2V5XTogZGF0YVtrZXldXG4gICAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiBhZGF0YTtcbn1cbmZ1bmN0aW9uIGlzU3RhY2tlZChzY2FsZSwgbWV0YSkge1xuICAgIGNvbnN0IHN0YWNrZWQgPSBzY2FsZSAmJiBzY2FsZS5vcHRpb25zLnN0YWNrZWQ7XG4gICAgcmV0dXJuIHN0YWNrZWQgfHwgc3RhY2tlZCA9PT0gdW5kZWZpbmVkICYmIG1ldGEuc3RhY2sgIT09IHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIGdldFN0YWNrS2V5KGluZGV4U2NhbGUsIHZhbHVlU2NhbGUsIG1ldGEpIHtcbiAgICByZXR1cm4gYCR7aW5kZXhTY2FsZS5pZH0uJHt2YWx1ZVNjYWxlLmlkfS4ke21ldGEuc3RhY2sgfHwgbWV0YS50eXBlfWA7XG59XG5mdW5jdGlvbiBnZXRVc2VyQm91bmRzKHNjYWxlKSB7XG4gICAgY29uc3QgeyBtaW4gLCBtYXggLCBtaW5EZWZpbmVkICwgbWF4RGVmaW5lZCAgfSA9IHNjYWxlLmdldFVzZXJCb3VuZHMoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBtaW46IG1pbkRlZmluZWQgPyBtaW4gOiBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFksXG4gICAgICAgIG1heDogbWF4RGVmaW5lZCA/IG1heCA6IE51bWJlci5QT1NJVElWRV9JTkZJTklUWVxuICAgIH07XG59XG5mdW5jdGlvbiBnZXRPckNyZWF0ZVN0YWNrKHN0YWNrcywgc3RhY2tLZXksIGluZGV4VmFsdWUpIHtcbiAgICBjb25zdCBzdWJTdGFjayA9IHN0YWNrc1tzdGFja0tleV0gfHwgKHN0YWNrc1tzdGFja0tleV0gPSB7fSk7XG4gICAgcmV0dXJuIHN1YlN0YWNrW2luZGV4VmFsdWVdIHx8IChzdWJTdGFja1tpbmRleFZhbHVlXSA9IHt9KTtcbn1cbmZ1bmN0aW9uIGdldExhc3RJbmRleEluU3RhY2soc3RhY2ssIHZTY2FsZSwgcG9zaXRpdmUsIHR5cGUpIHtcbiAgICBmb3IgKGNvbnN0IG1ldGEgb2YgdlNjYWxlLmdldE1hdGNoaW5nVmlzaWJsZU1ldGFzKHR5cGUpLnJldmVyc2UoKSl7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gc3RhY2tbbWV0YS5pbmRleF07XG4gICAgICAgIGlmIChwb3NpdGl2ZSAmJiB2YWx1ZSA+IDAgfHwgIXBvc2l0aXZlICYmIHZhbHVlIDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIG1ldGEuaW5kZXg7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5mdW5jdGlvbiB1cGRhdGVTdGFja3MoY29udHJvbGxlciwgcGFyc2VkKSB7XG4gICAgY29uc3QgeyBjaGFydCAsIF9jYWNoZWRNZXRhOiBtZXRhICB9ID0gY29udHJvbGxlcjtcbiAgICBjb25zdCBzdGFja3MgPSBjaGFydC5fc3RhY2tzIHx8IChjaGFydC5fc3RhY2tzID0ge30pO1xuICAgIGNvbnN0IHsgaVNjYWxlICwgdlNjYWxlICwgaW5kZXg6IGRhdGFzZXRJbmRleCAgfSA9IG1ldGE7XG4gICAgY29uc3QgaUF4aXMgPSBpU2NhbGUuYXhpcztcbiAgICBjb25zdCB2QXhpcyA9IHZTY2FsZS5heGlzO1xuICAgIGNvbnN0IGtleSA9IGdldFN0YWNrS2V5KGlTY2FsZSwgdlNjYWxlLCBtZXRhKTtcbiAgICBjb25zdCBpbGVuID0gcGFyc2VkLmxlbmd0aDtcbiAgICBsZXQgc3RhY2s7XG4gICAgZm9yKGxldCBpID0gMDsgaSA8IGlsZW47ICsraSl7XG4gICAgICAgIGNvbnN0IGl0ZW0gPSBwYXJzZWRbaV07XG4gICAgICAgIGNvbnN0IHsgW2lBeGlzXTogaW5kZXggLCBbdkF4aXNdOiB2YWx1ZSAgfSA9IGl0ZW07XG4gICAgICAgIGNvbnN0IGl0ZW1TdGFja3MgPSBpdGVtLl9zdGFja3MgfHwgKGl0ZW0uX3N0YWNrcyA9IHt9KTtcbiAgICAgICAgc3RhY2sgPSBpdGVtU3RhY2tzW3ZBeGlzXSA9IGdldE9yQ3JlYXRlU3RhY2soc3RhY2tzLCBrZXksIGluZGV4KTtcbiAgICAgICAgc3RhY2tbZGF0YXNldEluZGV4XSA9IHZhbHVlO1xuICAgICAgICBzdGFjay5fdG9wID0gZ2V0TGFzdEluZGV4SW5TdGFjayhzdGFjaywgdlNjYWxlLCB0cnVlLCBtZXRhLnR5cGUpO1xuICAgICAgICBzdGFjay5fYm90dG9tID0gZ2V0TGFzdEluZGV4SW5TdGFjayhzdGFjaywgdlNjYWxlLCBmYWxzZSwgbWV0YS50eXBlKTtcbiAgICAgICAgY29uc3QgdmlzdWFsVmFsdWVzID0gc3RhY2suX3Zpc3VhbFZhbHVlcyB8fCAoc3RhY2suX3Zpc3VhbFZhbHVlcyA9IHt9KTtcbiAgICAgICAgdmlzdWFsVmFsdWVzW2RhdGFzZXRJbmRleF0gPSB2YWx1ZTtcbiAgICB9XG59XG5mdW5jdGlvbiBnZXRGaXJzdFNjYWxlSWQoY2hhcnQsIGF4aXMpIHtcbiAgICBjb25zdCBzY2FsZXMgPSBjaGFydC5zY2FsZXM7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKHNjYWxlcykuZmlsdGVyKChrZXkpPT5zY2FsZXNba2V5XS5heGlzID09PSBheGlzKS5zaGlmdCgpO1xufVxuZnVuY3Rpb24gY3JlYXRlRGF0YXNldENvbnRleHQocGFyZW50LCBpbmRleCkge1xuICAgIHJldHVybiBjcmVhdGVDb250ZXh0KHBhcmVudCwge1xuICAgICAgICBhY3RpdmU6IGZhbHNlLFxuICAgICAgICBkYXRhc2V0OiB1bmRlZmluZWQsXG4gICAgICAgIGRhdGFzZXRJbmRleDogaW5kZXgsXG4gICAgICAgIGluZGV4LFxuICAgICAgICBtb2RlOiAnZGVmYXVsdCcsXG4gICAgICAgIHR5cGU6ICdkYXRhc2V0J1xuICAgIH0pO1xufVxuZnVuY3Rpb24gY3JlYXRlRGF0YUNvbnRleHQocGFyZW50LCBpbmRleCwgZWxlbWVudCkge1xuICAgIHJldHVybiBjcmVhdGVDb250ZXh0KHBhcmVudCwge1xuICAgICAgICBhY3RpdmU6IGZhbHNlLFxuICAgICAgICBkYXRhSW5kZXg6IGluZGV4LFxuICAgICAgICBwYXJzZWQ6IHVuZGVmaW5lZCxcbiAgICAgICAgcmF3OiB1bmRlZmluZWQsXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICAgIGluZGV4LFxuICAgICAgICBtb2RlOiAnZGVmYXVsdCcsXG4gICAgICAgIHR5cGU6ICdkYXRhJ1xuICAgIH0pO1xufVxuZnVuY3Rpb24gY2xlYXJTdGFja3MobWV0YSwgaXRlbXMpIHtcbiAgICBjb25zdCBkYXRhc2V0SW5kZXggPSBtZXRhLmNvbnRyb2xsZXIuaW5kZXg7XG4gICAgY29uc3QgYXhpcyA9IG1ldGEudlNjYWxlICYmIG1ldGEudlNjYWxlLmF4aXM7XG4gICAgaWYgKCFheGlzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaXRlbXMgPSBpdGVtcyB8fCBtZXRhLl9wYXJzZWQ7XG4gICAgZm9yIChjb25zdCBwYXJzZWQgb2YgaXRlbXMpe1xuICAgICAgICBjb25zdCBzdGFja3MgPSBwYXJzZWQuX3N0YWNrcztcbiAgICAgICAgaWYgKCFzdGFja3MgfHwgc3RhY2tzW2F4aXNdID09PSB1bmRlZmluZWQgfHwgc3RhY2tzW2F4aXNdW2RhdGFzZXRJbmRleF0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGRlbGV0ZSBzdGFja3NbYXhpc11bZGF0YXNldEluZGV4XTtcbiAgICAgICAgaWYgKHN0YWNrc1theGlzXS5fdmlzdWFsVmFsdWVzICE9PSB1bmRlZmluZWQgJiYgc3RhY2tzW2F4aXNdLl92aXN1YWxWYWx1ZXNbZGF0YXNldEluZGV4XSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBkZWxldGUgc3RhY2tzW2F4aXNdLl92aXN1YWxWYWx1ZXNbZGF0YXNldEluZGV4XTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmNvbnN0IGlzRGlyZWN0VXBkYXRlTW9kZSA9IChtb2RlKT0+bW9kZSA9PT0gJ3Jlc2V0JyB8fCBtb2RlID09PSAnbm9uZSc7XG5jb25zdCBjbG9uZUlmTm90U2hhcmVkID0gKGNhY2hlZCwgc2hhcmVkKT0+c2hhcmVkID8gY2FjaGVkIDogT2JqZWN0LmFzc2lnbih7fSwgY2FjaGVkKTtcbmNvbnN0IGNyZWF0ZVN0YWNrID0gKGNhblN0YWNrLCBtZXRhLCBjaGFydCk9PmNhblN0YWNrICYmICFtZXRhLmhpZGRlbiAmJiBtZXRhLl9zdGFja2VkICYmIHtcbiAgICAgICAga2V5czogZ2V0U29ydGVkRGF0YXNldEluZGljZXMoY2hhcnQsIHRydWUpLFxuICAgICAgICB2YWx1ZXM6IG51bGxcbiAgICB9O1xuY2xhc3MgRGF0YXNldENvbnRyb2xsZXIge1xuIHN0YXRpYyBkZWZhdWx0cyA9IHt9O1xuIHN0YXRpYyBkYXRhc2V0RWxlbWVudFR5cGUgPSBudWxsO1xuIHN0YXRpYyBkYXRhRWxlbWVudFR5cGUgPSBudWxsO1xuIGNvbnN0cnVjdG9yKGNoYXJ0LCBkYXRhc2V0SW5kZXgpe1xuICAgICAgICB0aGlzLmNoYXJ0ID0gY2hhcnQ7XG4gICAgICAgIHRoaXMuX2N0eCA9IGNoYXJ0LmN0eDtcbiAgICAgICAgdGhpcy5pbmRleCA9IGRhdGFzZXRJbmRleDtcbiAgICAgICAgdGhpcy5fY2FjaGVkRGF0YU9wdHMgPSB7fTtcbiAgICAgICAgdGhpcy5fY2FjaGVkTWV0YSA9IHRoaXMuZ2V0TWV0YSgpO1xuICAgICAgICB0aGlzLl90eXBlID0gdGhpcy5fY2FjaGVkTWV0YS50eXBlO1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSB1bmRlZmluZWQ7XG4gICAgICAgICB0aGlzLl9wYXJzaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX2RhdGEgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuX29iamVjdERhdGEgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuX3NoYXJlZE9wdGlvbnMgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuX2RyYXdTdGFydCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fZHJhd0NvdW50ID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLmVuYWJsZU9wdGlvblNoYXJpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5zdXBwb3J0c0RlY2ltYXRpb24gPSBmYWxzZTtcbiAgICAgICAgdGhpcy4kY29udGV4dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fc3luY0xpc3QgPSBbXTtcbiAgICAgICAgdGhpcy5kYXRhc2V0RWxlbWVudFR5cGUgPSBuZXcudGFyZ2V0LmRhdGFzZXRFbGVtZW50VHlwZTtcbiAgICAgICAgdGhpcy5kYXRhRWxlbWVudFR5cGUgPSBuZXcudGFyZ2V0LmRhdGFFbGVtZW50VHlwZTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplKCk7XG4gICAgfVxuICAgIGluaXRpYWxpemUoKSB7XG4gICAgICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgICAgICB0aGlzLmNvbmZpZ3VyZSgpO1xuICAgICAgICB0aGlzLmxpbmtTY2FsZXMoKTtcbiAgICAgICAgbWV0YS5fc3RhY2tlZCA9IGlzU3RhY2tlZChtZXRhLnZTY2FsZSwgbWV0YSk7XG4gICAgICAgIHRoaXMuYWRkRWxlbWVudHMoKTtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5maWxsICYmICF0aGlzLmNoYXJ0LmlzUGx1Z2luRW5hYmxlZCgnZmlsbGVyJykpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihcIlRyaWVkIHRvIHVzZSB0aGUgJ2ZpbGwnIG9wdGlvbiB3aXRob3V0IHRoZSAnRmlsbGVyJyBwbHVnaW4gZW5hYmxlZC4gUGxlYXNlIGltcG9ydCBhbmQgcmVnaXN0ZXIgdGhlICdGaWxsZXInIHBsdWdpbiBhbmQgbWFrZSBzdXJlIGl0IGlzIG5vdCBkaXNhYmxlZCBpbiB0aGUgb3B0aW9uc1wiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICB1cGRhdGVJbmRleChkYXRhc2V0SW5kZXgpIHtcbiAgICAgICAgaWYgKHRoaXMuaW5kZXggIT09IGRhdGFzZXRJbmRleCkge1xuICAgICAgICAgICAgY2xlYXJTdGFja3ModGhpcy5fY2FjaGVkTWV0YSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pbmRleCA9IGRhdGFzZXRJbmRleDtcbiAgICB9XG4gICAgbGlua1NjYWxlcygpIHtcbiAgICAgICAgY29uc3QgY2hhcnQgPSB0aGlzLmNoYXJ0O1xuICAgICAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICAgICAgY29uc3QgZGF0YXNldCA9IHRoaXMuZ2V0RGF0YXNldCgpO1xuICAgICAgICBjb25zdCBjaG9vc2VJZCA9IChheGlzLCB4LCB5LCByKT0+YXhpcyA9PT0gJ3gnID8geCA6IGF4aXMgPT09ICdyJyA/IHIgOiB5O1xuICAgICAgICBjb25zdCB4aWQgPSBtZXRhLnhBeGlzSUQgPSB2YWx1ZU9yRGVmYXVsdChkYXRhc2V0LnhBeGlzSUQsIGdldEZpcnN0U2NhbGVJZChjaGFydCwgJ3gnKSk7XG4gICAgICAgIGNvbnN0IHlpZCA9IG1ldGEueUF4aXNJRCA9IHZhbHVlT3JEZWZhdWx0KGRhdGFzZXQueUF4aXNJRCwgZ2V0Rmlyc3RTY2FsZUlkKGNoYXJ0LCAneScpKTtcbiAgICAgICAgY29uc3QgcmlkID0gbWV0YS5yQXhpc0lEID0gdmFsdWVPckRlZmF1bHQoZGF0YXNldC5yQXhpc0lELCBnZXRGaXJzdFNjYWxlSWQoY2hhcnQsICdyJykpO1xuICAgICAgICBjb25zdCBpbmRleEF4aXMgPSBtZXRhLmluZGV4QXhpcztcbiAgICAgICAgY29uc3QgaWlkID0gbWV0YS5pQXhpc0lEID0gY2hvb3NlSWQoaW5kZXhBeGlzLCB4aWQsIHlpZCwgcmlkKTtcbiAgICAgICAgY29uc3QgdmlkID0gbWV0YS52QXhpc0lEID0gY2hvb3NlSWQoaW5kZXhBeGlzLCB5aWQsIHhpZCwgcmlkKTtcbiAgICAgICAgbWV0YS54U2NhbGUgPSB0aGlzLmdldFNjYWxlRm9ySWQoeGlkKTtcbiAgICAgICAgbWV0YS55U2NhbGUgPSB0aGlzLmdldFNjYWxlRm9ySWQoeWlkKTtcbiAgICAgICAgbWV0YS5yU2NhbGUgPSB0aGlzLmdldFNjYWxlRm9ySWQocmlkKTtcbiAgICAgICAgbWV0YS5pU2NhbGUgPSB0aGlzLmdldFNjYWxlRm9ySWQoaWlkKTtcbiAgICAgICAgbWV0YS52U2NhbGUgPSB0aGlzLmdldFNjYWxlRm9ySWQodmlkKTtcbiAgICB9XG4gICAgZ2V0RGF0YXNldCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2hhcnQuZGF0YS5kYXRhc2V0c1t0aGlzLmluZGV4XTtcbiAgICB9XG4gICAgZ2V0TWV0YSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2hhcnQuZ2V0RGF0YXNldE1ldGEodGhpcy5pbmRleCk7XG4gICAgfVxuIGdldFNjYWxlRm9ySWQoc2NhbGVJRCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jaGFydC5zY2FsZXNbc2NhbGVJRF07XG4gICAgfVxuIF9nZXRPdGhlclNjYWxlKHNjYWxlKSB7XG4gICAgICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgICAgICByZXR1cm4gc2NhbGUgPT09IG1ldGEuaVNjYWxlID8gbWV0YS52U2NhbGUgOiBtZXRhLmlTY2FsZTtcbiAgICB9XG4gICAgcmVzZXQoKSB7XG4gICAgICAgIHRoaXMuX3VwZGF0ZSgncmVzZXQnKTtcbiAgICB9XG4gX2Rlc3Ryb3koKSB7XG4gICAgICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgICAgICBpZiAodGhpcy5fZGF0YSkge1xuICAgICAgICAgICAgdW5saXN0ZW5BcnJheUV2ZW50cyh0aGlzLl9kYXRhLCB0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWV0YS5fc3RhY2tlZCkge1xuICAgICAgICAgICAgY2xlYXJTdGFja3MobWV0YSk7XG4gICAgICAgIH1cbiAgICB9XG4gX2RhdGFDaGVjaygpIHtcbiAgICAgICAgY29uc3QgZGF0YXNldCA9IHRoaXMuZ2V0RGF0YXNldCgpO1xuICAgICAgICBjb25zdCBkYXRhID0gZGF0YXNldC5kYXRhIHx8IChkYXRhc2V0LmRhdGEgPSBbXSk7XG4gICAgICAgIGNvbnN0IF9kYXRhID0gdGhpcy5fZGF0YTtcbiAgICAgICAgaWYgKGlzT2JqZWN0KGRhdGEpKSB7XG4gICAgICAgICAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICAgICAgICAgIHRoaXMuX2RhdGEgPSBjb252ZXJ0T2JqZWN0RGF0YVRvQXJyYXkoZGF0YSwgbWV0YSk7XG4gICAgICAgIH0gZWxzZSBpZiAoX2RhdGEgIT09IGRhdGEpIHtcbiAgICAgICAgICAgIGlmIChfZGF0YSkge1xuICAgICAgICAgICAgICAgIHVubGlzdGVuQXJyYXlFdmVudHMoX2RhdGEsIHRoaXMpO1xuICAgICAgICAgICAgICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgICAgICAgICAgICAgIGNsZWFyU3RhY2tzKG1ldGEpO1xuICAgICAgICAgICAgICAgIG1ldGEuX3BhcnNlZCA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRhdGEgJiYgT2JqZWN0LmlzRXh0ZW5zaWJsZShkYXRhKSkge1xuICAgICAgICAgICAgICAgIGxpc3RlbkFycmF5RXZlbnRzKGRhdGEsIHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fc3luY0xpc3QgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX2RhdGEgPSBkYXRhO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFkZEVsZW1lbnRzKCkge1xuICAgICAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICAgICAgdGhpcy5fZGF0YUNoZWNrKCk7XG4gICAgICAgIGlmICh0aGlzLmRhdGFzZXRFbGVtZW50VHlwZSkge1xuICAgICAgICAgICAgbWV0YS5kYXRhc2V0ID0gbmV3IHRoaXMuZGF0YXNldEVsZW1lbnRUeXBlKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYnVpbGRPclVwZGF0ZUVsZW1lbnRzKHJlc2V0TmV3RWxlbWVudHMpIHtcbiAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgICAgIGNvbnN0IGRhdGFzZXQgPSB0aGlzLmdldERhdGFzZXQoKTtcbiAgICAgICAgbGV0IHN0YWNrQ2hhbmdlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9kYXRhQ2hlY2soKTtcbiAgICAgICAgY29uc3Qgb2xkU3RhY2tlZCA9IG1ldGEuX3N0YWNrZWQ7XG4gICAgICAgIG1ldGEuX3N0YWNrZWQgPSBpc1N0YWNrZWQobWV0YS52U2NhbGUsIG1ldGEpO1xuICAgICAgICBpZiAobWV0YS5zdGFjayAhPT0gZGF0YXNldC5zdGFjaykge1xuICAgICAgICAgICAgc3RhY2tDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIGNsZWFyU3RhY2tzKG1ldGEpO1xuICAgICAgICAgICAgbWV0YS5zdGFjayA9IGRhdGFzZXQuc3RhY2s7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fcmVzeW5jRWxlbWVudHMocmVzZXROZXdFbGVtZW50cyk7XG4gICAgICAgIGlmIChzdGFja0NoYW5nZWQgfHwgb2xkU3RhY2tlZCAhPT0gbWV0YS5fc3RhY2tlZCkge1xuICAgICAgICAgICAgdXBkYXRlU3RhY2tzKHRoaXMsIG1ldGEuX3BhcnNlZCk7XG4gICAgICAgIH1cbiAgICB9XG4gY29uZmlndXJlKCkge1xuICAgICAgICBjb25zdCBjb25maWcgPSB0aGlzLmNoYXJ0LmNvbmZpZztcbiAgICAgICAgY29uc3Qgc2NvcGVLZXlzID0gY29uZmlnLmRhdGFzZXRTY29wZUtleXModGhpcy5fdHlwZSk7XG4gICAgICAgIGNvbnN0IHNjb3BlcyA9IGNvbmZpZy5nZXRPcHRpb25TY29wZXModGhpcy5nZXREYXRhc2V0KCksIHNjb3BlS2V5cywgdHJ1ZSk7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IGNvbmZpZy5jcmVhdGVSZXNvbHZlcihzY29wZXMsIHRoaXMuZ2V0Q29udGV4dCgpKTtcbiAgICAgICAgdGhpcy5fcGFyc2luZyA9IHRoaXMub3B0aW9ucy5wYXJzaW5nO1xuICAgICAgICB0aGlzLl9jYWNoZWREYXRhT3B0cyA9IHt9O1xuICAgIH1cbiBwYXJzZShzdGFydCwgY291bnQpIHtcbiAgICAgICAgY29uc3QgeyBfY2FjaGVkTWV0YTogbWV0YSAsIF9kYXRhOiBkYXRhICB9ID0gdGhpcztcbiAgICAgICAgY29uc3QgeyBpU2NhbGUgLCBfc3RhY2tlZCAgfSA9IG1ldGE7XG4gICAgICAgIGNvbnN0IGlBeGlzID0gaVNjYWxlLmF4aXM7XG4gICAgICAgIGxldCBzb3J0ZWQgPSBzdGFydCA9PT0gMCAmJiBjb3VudCA9PT0gZGF0YS5sZW5ndGggPyB0cnVlIDogbWV0YS5fc29ydGVkO1xuICAgICAgICBsZXQgcHJldiA9IHN0YXJ0ID4gMCAmJiBtZXRhLl9wYXJzZWRbc3RhcnQgLSAxXTtcbiAgICAgICAgbGV0IGksIGN1ciwgcGFyc2VkO1xuICAgICAgICBpZiAodGhpcy5fcGFyc2luZyA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIG1ldGEuX3BhcnNlZCA9IGRhdGE7XG4gICAgICAgICAgICBtZXRhLl9zb3J0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgcGFyc2VkID0gZGF0YTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChpc0FycmF5KGRhdGFbc3RhcnRdKSkge1xuICAgICAgICAgICAgICAgIHBhcnNlZCA9IHRoaXMucGFyc2VBcnJheURhdGEobWV0YSwgZGF0YSwgc3RhcnQsIGNvdW50KTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNPYmplY3QoZGF0YVtzdGFydF0pKSB7XG4gICAgICAgICAgICAgICAgcGFyc2VkID0gdGhpcy5wYXJzZU9iamVjdERhdGEobWV0YSwgZGF0YSwgc3RhcnQsIGNvdW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcGFyc2VkID0gdGhpcy5wYXJzZVByaW1pdGl2ZURhdGEobWV0YSwgZGF0YSwgc3RhcnQsIGNvdW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGlzTm90SW5PcmRlckNvbXBhcmVkVG9QcmV2ID0gKCk9PmN1cltpQXhpc10gPT09IG51bGwgfHwgcHJldiAmJiBjdXJbaUF4aXNdIDwgcHJldltpQXhpc107XG4gICAgICAgICAgICBmb3IoaSA9IDA7IGkgPCBjb3VudDsgKytpKXtcbiAgICAgICAgICAgICAgICBtZXRhLl9wYXJzZWRbaSArIHN0YXJ0XSA9IGN1ciA9IHBhcnNlZFtpXTtcbiAgICAgICAgICAgICAgICBpZiAoc29ydGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc05vdEluT3JkZXJDb21wYXJlZFRvUHJldigpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzb3J0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBwcmV2ID0gY3VyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG1ldGEuX3NvcnRlZCA9IHNvcnRlZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoX3N0YWNrZWQpIHtcbiAgICAgICAgICAgIHVwZGF0ZVN0YWNrcyh0aGlzLCBwYXJzZWQpO1xuICAgICAgICB9XG4gICAgfVxuIHBhcnNlUHJpbWl0aXZlRGF0YShtZXRhLCBkYXRhLCBzdGFydCwgY291bnQpIHtcbiAgICAgICAgY29uc3QgeyBpU2NhbGUgLCB2U2NhbGUgIH0gPSBtZXRhO1xuICAgICAgICBjb25zdCBpQXhpcyA9IGlTY2FsZS5heGlzO1xuICAgICAgICBjb25zdCB2QXhpcyA9IHZTY2FsZS5heGlzO1xuICAgICAgICBjb25zdCBsYWJlbHMgPSBpU2NhbGUuZ2V0TGFiZWxzKCk7XG4gICAgICAgIGNvbnN0IHNpbmdsZVNjYWxlID0gaVNjYWxlID09PSB2U2NhbGU7XG4gICAgICAgIGNvbnN0IHBhcnNlZCA9IG5ldyBBcnJheShjb3VudCk7XG4gICAgICAgIGxldCBpLCBpbGVuLCBpbmRleDtcbiAgICAgICAgZm9yKGkgPSAwLCBpbGVuID0gY291bnQ7IGkgPCBpbGVuOyArK2kpe1xuICAgICAgICAgICAgaW5kZXggPSBpICsgc3RhcnQ7XG4gICAgICAgICAgICBwYXJzZWRbaV0gPSB7XG4gICAgICAgICAgICAgICAgW2lBeGlzXTogc2luZ2xlU2NhbGUgfHwgaVNjYWxlLnBhcnNlKGxhYmVsc1tpbmRleF0sIGluZGV4KSxcbiAgICAgICAgICAgICAgICBbdkF4aXNdOiB2U2NhbGUucGFyc2UoZGF0YVtpbmRleF0sIGluZGV4KVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGFyc2VkO1xuICAgIH1cbiBwYXJzZUFycmF5RGF0YShtZXRhLCBkYXRhLCBzdGFydCwgY291bnQpIHtcbiAgICAgICAgY29uc3QgeyB4U2NhbGUgLCB5U2NhbGUgIH0gPSBtZXRhO1xuICAgICAgICBjb25zdCBwYXJzZWQgPSBuZXcgQXJyYXkoY291bnQpO1xuICAgICAgICBsZXQgaSwgaWxlbiwgaW5kZXgsIGl0ZW07XG4gICAgICAgIGZvcihpID0gMCwgaWxlbiA9IGNvdW50OyBpIDwgaWxlbjsgKytpKXtcbiAgICAgICAgICAgIGluZGV4ID0gaSArIHN0YXJ0O1xuICAgICAgICAgICAgaXRlbSA9IGRhdGFbaW5kZXhdO1xuICAgICAgICAgICAgcGFyc2VkW2ldID0ge1xuICAgICAgICAgICAgICAgIHg6IHhTY2FsZS5wYXJzZShpdGVtWzBdLCBpbmRleCksXG4gICAgICAgICAgICAgICAgeTogeVNjYWxlLnBhcnNlKGl0ZW1bMV0sIGluZGV4KVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGFyc2VkO1xuICAgIH1cbiBwYXJzZU9iamVjdERhdGEobWV0YSwgZGF0YSwgc3RhcnQsIGNvdW50KSB7XG4gICAgICAgIGNvbnN0IHsgeFNjYWxlICwgeVNjYWxlICB9ID0gbWV0YTtcbiAgICAgICAgY29uc3QgeyB4QXhpc0tleSA9J3gnICwgeUF4aXNLZXkgPSd5JyAgfSA9IHRoaXMuX3BhcnNpbmc7XG4gICAgICAgIGNvbnN0IHBhcnNlZCA9IG5ldyBBcnJheShjb3VudCk7XG4gICAgICAgIGxldCBpLCBpbGVuLCBpbmRleCwgaXRlbTtcbiAgICAgICAgZm9yKGkgPSAwLCBpbGVuID0gY291bnQ7IGkgPCBpbGVuOyArK2kpe1xuICAgICAgICAgICAgaW5kZXggPSBpICsgc3RhcnQ7XG4gICAgICAgICAgICBpdGVtID0gZGF0YVtpbmRleF07XG4gICAgICAgICAgICBwYXJzZWRbaV0gPSB7XG4gICAgICAgICAgICAgICAgeDogeFNjYWxlLnBhcnNlKHJlc29sdmVPYmplY3RLZXkoaXRlbSwgeEF4aXNLZXkpLCBpbmRleCksXG4gICAgICAgICAgICAgICAgeTogeVNjYWxlLnBhcnNlKHJlc29sdmVPYmplY3RLZXkoaXRlbSwgeUF4aXNLZXkpLCBpbmRleClcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBhcnNlZDtcbiAgICB9XG4gZ2V0UGFyc2VkKGluZGV4KSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYWNoZWRNZXRhLl9wYXJzZWRbaW5kZXhdO1xuICAgIH1cbiBnZXREYXRhRWxlbWVudChpbmRleCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2FjaGVkTWV0YS5kYXRhW2luZGV4XTtcbiAgICB9XG4gYXBwbHlTdGFjayhzY2FsZSwgcGFyc2VkLCBtb2RlKSB7XG4gICAgICAgIGNvbnN0IGNoYXJ0ID0gdGhpcy5jaGFydDtcbiAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gcGFyc2VkW3NjYWxlLmF4aXNdO1xuICAgICAgICBjb25zdCBzdGFjayA9IHtcbiAgICAgICAgICAgIGtleXM6IGdldFNvcnRlZERhdGFzZXRJbmRpY2VzKGNoYXJ0LCB0cnVlKSxcbiAgICAgICAgICAgIHZhbHVlczogcGFyc2VkLl9zdGFja3Nbc2NhbGUuYXhpc10uX3Zpc3VhbFZhbHVlc1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gYXBwbHlTdGFjayhzdGFjaywgdmFsdWUsIG1ldGEuaW5kZXgsIHtcbiAgICAgICAgICAgIG1vZGVcbiAgICAgICAgfSk7XG4gICAgfVxuIHVwZGF0ZVJhbmdlRnJvbVBhcnNlZChyYW5nZSwgc2NhbGUsIHBhcnNlZCwgc3RhY2spIHtcbiAgICAgICAgY29uc3QgcGFyc2VkVmFsdWUgPSBwYXJzZWRbc2NhbGUuYXhpc107XG4gICAgICAgIGxldCB2YWx1ZSA9IHBhcnNlZFZhbHVlID09PSBudWxsID8gTmFOIDogcGFyc2VkVmFsdWU7XG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IHN0YWNrICYmIHBhcnNlZC5fc3RhY2tzW3NjYWxlLmF4aXNdO1xuICAgICAgICBpZiAoc3RhY2sgJiYgdmFsdWVzKSB7XG4gICAgICAgICAgICBzdGFjay52YWx1ZXMgPSB2YWx1ZXM7XG4gICAgICAgICAgICB2YWx1ZSA9IGFwcGx5U3RhY2soc3RhY2ssIHBhcnNlZFZhbHVlLCB0aGlzLl9jYWNoZWRNZXRhLmluZGV4KTtcbiAgICAgICAgfVxuICAgICAgICByYW5nZS5taW4gPSBNYXRoLm1pbihyYW5nZS5taW4sIHZhbHVlKTtcbiAgICAgICAgcmFuZ2UubWF4ID0gTWF0aC5tYXgocmFuZ2UubWF4LCB2YWx1ZSk7XG4gICAgfVxuIGdldE1pbk1heChzY2FsZSwgY2FuU3RhY2spIHtcbiAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgICAgIGNvbnN0IF9wYXJzZWQgPSBtZXRhLl9wYXJzZWQ7XG4gICAgICAgIGNvbnN0IHNvcnRlZCA9IG1ldGEuX3NvcnRlZCAmJiBzY2FsZSA9PT0gbWV0YS5pU2NhbGU7XG4gICAgICAgIGNvbnN0IGlsZW4gPSBfcGFyc2VkLmxlbmd0aDtcbiAgICAgICAgY29uc3Qgb3RoZXJTY2FsZSA9IHRoaXMuX2dldE90aGVyU2NhbGUoc2NhbGUpO1xuICAgICAgICBjb25zdCBzdGFjayA9IGNyZWF0ZVN0YWNrKGNhblN0YWNrLCBtZXRhLCB0aGlzLmNoYXJ0KTtcbiAgICAgICAgY29uc3QgcmFuZ2UgPSB7XG4gICAgICAgICAgICBtaW46IE51bWJlci5QT1NJVElWRV9JTkZJTklUWSxcbiAgICAgICAgICAgIG1heDogTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHsgbWluOiBvdGhlck1pbiAsIG1heDogb3RoZXJNYXggIH0gPSBnZXRVc2VyQm91bmRzKG90aGVyU2NhbGUpO1xuICAgICAgICBsZXQgaSwgcGFyc2VkO1xuICAgICAgICBmdW5jdGlvbiBfc2tpcCgpIHtcbiAgICAgICAgICAgIHBhcnNlZCA9IF9wYXJzZWRbaV07XG4gICAgICAgICAgICBjb25zdCBvdGhlclZhbHVlID0gcGFyc2VkW290aGVyU2NhbGUuYXhpc107XG4gICAgICAgICAgICByZXR1cm4gIWlzTnVtYmVyRmluaXRlKHBhcnNlZFtzY2FsZS5heGlzXSkgfHwgb3RoZXJNaW4gPiBvdGhlclZhbHVlIHx8IG90aGVyTWF4IDwgb3RoZXJWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBmb3IoaSA9IDA7IGkgPCBpbGVuOyArK2kpe1xuICAgICAgICAgICAgaWYgKF9za2lwKCkpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMudXBkYXRlUmFuZ2VGcm9tUGFyc2VkKHJhbmdlLCBzY2FsZSwgcGFyc2VkLCBzdGFjayk7XG4gICAgICAgICAgICBpZiAoc29ydGVkKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNvcnRlZCkge1xuICAgICAgICAgICAgZm9yKGkgPSBpbGVuIC0gMTsgaSA+PSAwOyAtLWkpe1xuICAgICAgICAgICAgICAgIGlmIChfc2tpcCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVJhbmdlRnJvbVBhcnNlZChyYW5nZSwgc2NhbGUsIHBhcnNlZCwgc3RhY2spO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByYW5nZTtcbiAgICB9XG4gICAgZ2V0QWxsUGFyc2VkVmFsdWVzKHNjYWxlKSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZCA9IHRoaXMuX2NhY2hlZE1ldGEuX3BhcnNlZDtcbiAgICAgICAgY29uc3QgdmFsdWVzID0gW107XG4gICAgICAgIGxldCBpLCBpbGVuLCB2YWx1ZTtcbiAgICAgICAgZm9yKGkgPSAwLCBpbGVuID0gcGFyc2VkLmxlbmd0aDsgaSA8IGlsZW47ICsraSl7XG4gICAgICAgICAgICB2YWx1ZSA9IHBhcnNlZFtpXVtzY2FsZS5heGlzXTtcbiAgICAgICAgICAgIGlmIChpc051bWJlckZpbml0ZSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZXMucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlcztcbiAgICB9XG4gZ2V0TWF4T3ZlcmZsb3coKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gZ2V0TGFiZWxBbmRWYWx1ZShpbmRleCkge1xuICAgICAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICAgICAgY29uc3QgaVNjYWxlID0gbWV0YS5pU2NhbGU7XG4gICAgICAgIGNvbnN0IHZTY2FsZSA9IG1ldGEudlNjYWxlO1xuICAgICAgICBjb25zdCBwYXJzZWQgPSB0aGlzLmdldFBhcnNlZChpbmRleCk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBsYWJlbDogaVNjYWxlID8gJycgKyBpU2NhbGUuZ2V0TGFiZWxGb3JWYWx1ZShwYXJzZWRbaVNjYWxlLmF4aXNdKSA6ICcnLFxuICAgICAgICAgICAgdmFsdWU6IHZTY2FsZSA/ICcnICsgdlNjYWxlLmdldExhYmVsRm9yVmFsdWUocGFyc2VkW3ZTY2FsZS5heGlzXSkgOiAnJ1xuICAgICAgICB9O1xuICAgIH1cbiBfdXBkYXRlKG1vZGUpIHtcbiAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgICAgIHRoaXMudXBkYXRlKG1vZGUgfHwgJ2RlZmF1bHQnKTtcbiAgICAgICAgbWV0YS5fY2xpcCA9IHRvQ2xpcCh2YWx1ZU9yRGVmYXVsdCh0aGlzLm9wdGlvbnMuY2xpcCwgZGVmYXVsdENsaXAobWV0YS54U2NhbGUsIG1ldGEueVNjYWxlLCB0aGlzLmdldE1heE92ZXJmbG93KCkpKSk7XG4gICAgfVxuIHVwZGF0ZShtb2RlKSB7fVxuICAgIGRyYXcoKSB7XG4gICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2N0eDtcbiAgICAgICAgY29uc3QgY2hhcnQgPSB0aGlzLmNoYXJ0O1xuICAgICAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICAgICAgY29uc3QgZWxlbWVudHMgPSBtZXRhLmRhdGEgfHwgW107XG4gICAgICAgIGNvbnN0IGFyZWEgPSBjaGFydC5jaGFydEFyZWE7XG4gICAgICAgIGNvbnN0IGFjdGl2ZSA9IFtdO1xuICAgICAgICBjb25zdCBzdGFydCA9IHRoaXMuX2RyYXdTdGFydCB8fCAwO1xuICAgICAgICBjb25zdCBjb3VudCA9IHRoaXMuX2RyYXdDb3VudCB8fCBlbGVtZW50cy5sZW5ndGggLSBzdGFydDtcbiAgICAgICAgY29uc3QgZHJhd0FjdGl2ZUVsZW1lbnRzT25Ub3AgPSB0aGlzLm9wdGlvbnMuZHJhd0FjdGl2ZUVsZW1lbnRzT25Ub3A7XG4gICAgICAgIGxldCBpO1xuICAgICAgICBpZiAobWV0YS5kYXRhc2V0KSB7XG4gICAgICAgICAgICBtZXRhLmRhdGFzZXQuZHJhdyhjdHgsIGFyZWEsIHN0YXJ0LCBjb3VudCk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yKGkgPSBzdGFydDsgaSA8IHN0YXJ0ICsgY291bnQ7ICsraSl7XG4gICAgICAgICAgICBjb25zdCBlbGVtZW50ID0gZWxlbWVudHNbaV07XG4gICAgICAgICAgICBpZiAoZWxlbWVudC5oaWRkZW4pIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChlbGVtZW50LmFjdGl2ZSAmJiBkcmF3QWN0aXZlRWxlbWVudHNPblRvcCkge1xuICAgICAgICAgICAgICAgIGFjdGl2ZS5wdXNoKGVsZW1lbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50LmRyYXcoY3R4LCBhcmVhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmb3IoaSA9IDA7IGkgPCBhY3RpdmUubGVuZ3RoOyArK2kpe1xuICAgICAgICAgICAgYWN0aXZlW2ldLmRyYXcoY3R4LCBhcmVhKTtcbiAgICAgICAgfVxuICAgIH1cbiBnZXRTdHlsZShpbmRleCwgYWN0aXZlKSB7XG4gICAgICAgIGNvbnN0IG1vZGUgPSBhY3RpdmUgPyAnYWN0aXZlJyA6ICdkZWZhdWx0JztcbiAgICAgICAgcmV0dXJuIGluZGV4ID09PSB1bmRlZmluZWQgJiYgdGhpcy5fY2FjaGVkTWV0YS5kYXRhc2V0ID8gdGhpcy5yZXNvbHZlRGF0YXNldEVsZW1lbnRPcHRpb25zKG1vZGUpIDogdGhpcy5yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKGluZGV4IHx8IDAsIG1vZGUpO1xuICAgIH1cbiBnZXRDb250ZXh0KGluZGV4LCBhY3RpdmUsIG1vZGUpIHtcbiAgICAgICAgY29uc3QgZGF0YXNldCA9IHRoaXMuZ2V0RGF0YXNldCgpO1xuICAgICAgICBsZXQgY29udGV4dDtcbiAgICAgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCB0aGlzLl9jYWNoZWRNZXRhLmRhdGEubGVuZ3RoKSB7XG4gICAgICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5fY2FjaGVkTWV0YS5kYXRhW2luZGV4XTtcbiAgICAgICAgICAgIGNvbnRleHQgPSBlbGVtZW50LiRjb250ZXh0IHx8IChlbGVtZW50LiRjb250ZXh0ID0gY3JlYXRlRGF0YUNvbnRleHQodGhpcy5nZXRDb250ZXh0KCksIGluZGV4LCBlbGVtZW50KSk7XG4gICAgICAgICAgICBjb250ZXh0LnBhcnNlZCA9IHRoaXMuZ2V0UGFyc2VkKGluZGV4KTtcbiAgICAgICAgICAgIGNvbnRleHQucmF3ID0gZGF0YXNldC5kYXRhW2luZGV4XTtcbiAgICAgICAgICAgIGNvbnRleHQuaW5kZXggPSBjb250ZXh0LmRhdGFJbmRleCA9IGluZGV4O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29udGV4dCA9IHRoaXMuJGNvbnRleHQgfHwgKHRoaXMuJGNvbnRleHQgPSBjcmVhdGVEYXRhc2V0Q29udGV4dCh0aGlzLmNoYXJ0LmdldENvbnRleHQoKSwgdGhpcy5pbmRleCkpO1xuICAgICAgICAgICAgY29udGV4dC5kYXRhc2V0ID0gZGF0YXNldDtcbiAgICAgICAgICAgIGNvbnRleHQuaW5kZXggPSBjb250ZXh0LmRhdGFzZXRJbmRleCA9IHRoaXMuaW5kZXg7XG4gICAgICAgIH1cbiAgICAgICAgY29udGV4dC5hY3RpdmUgPSAhIWFjdGl2ZTtcbiAgICAgICAgY29udGV4dC5tb2RlID0gbW9kZTtcbiAgICAgICAgcmV0dXJuIGNvbnRleHQ7XG4gICAgfVxuIHJlc29sdmVEYXRhc2V0RWxlbWVudE9wdGlvbnMobW9kZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcmVzb2x2ZUVsZW1lbnRPcHRpb25zKHRoaXMuZGF0YXNldEVsZW1lbnRUeXBlLmlkLCBtb2RlKTtcbiAgICB9XG4gcmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucyhpbmRleCwgbW9kZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcmVzb2x2ZUVsZW1lbnRPcHRpb25zKHRoaXMuZGF0YUVsZW1lbnRUeXBlLmlkLCBtb2RlLCBpbmRleCk7XG4gICAgfVxuIF9yZXNvbHZlRWxlbWVudE9wdGlvbnMoZWxlbWVudFR5cGUsIG1vZGUgPSAnZGVmYXVsdCcsIGluZGV4KSB7XG4gICAgICAgIGNvbnN0IGFjdGl2ZSA9IG1vZGUgPT09ICdhY3RpdmUnO1xuICAgICAgICBjb25zdCBjYWNoZSA9IHRoaXMuX2NhY2hlZERhdGFPcHRzO1xuICAgICAgICBjb25zdCBjYWNoZUtleSA9IGVsZW1lbnRUeXBlICsgJy0nICsgbW9kZTtcbiAgICAgICAgY29uc3QgY2FjaGVkID0gY2FjaGVbY2FjaGVLZXldO1xuICAgICAgICBjb25zdCBzaGFyaW5nID0gdGhpcy5lbmFibGVPcHRpb25TaGFyaW5nICYmIGRlZmluZWQoaW5kZXgpO1xuICAgICAgICBpZiAoY2FjaGVkKSB7XG4gICAgICAgICAgICByZXR1cm4gY2xvbmVJZk5vdFNoYXJlZChjYWNoZWQsIHNoYXJpbmcpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuY2hhcnQuY29uZmlnO1xuICAgICAgICBjb25zdCBzY29wZUtleXMgPSBjb25maWcuZGF0YXNldEVsZW1lbnRTY29wZUtleXModGhpcy5fdHlwZSwgZWxlbWVudFR5cGUpO1xuICAgICAgICBjb25zdCBwcmVmaXhlcyA9IGFjdGl2ZSA/IFtcbiAgICAgICAgICAgIGAke2VsZW1lbnRUeXBlfUhvdmVyYCxcbiAgICAgICAgICAgICdob3ZlcicsXG4gICAgICAgICAgICBlbGVtZW50VHlwZSxcbiAgICAgICAgICAgICcnXG4gICAgICAgIF0gOiBbXG4gICAgICAgICAgICBlbGVtZW50VHlwZSxcbiAgICAgICAgICAgICcnXG4gICAgICAgIF07XG4gICAgICAgIGNvbnN0IHNjb3BlcyA9IGNvbmZpZy5nZXRPcHRpb25TY29wZXModGhpcy5nZXREYXRhc2V0KCksIHNjb3BlS2V5cyk7XG4gICAgICAgIGNvbnN0IG5hbWVzID0gT2JqZWN0LmtleXMoZGVmYXVsdHMuZWxlbWVudHNbZWxlbWVudFR5cGVdKTtcbiAgICAgICAgY29uc3QgY29udGV4dCA9ICgpPT50aGlzLmdldENvbnRleHQoaW5kZXgsIGFjdGl2ZSwgbW9kZSk7XG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IGNvbmZpZy5yZXNvbHZlTmFtZWRPcHRpb25zKHNjb3BlcywgbmFtZXMsIGNvbnRleHQsIHByZWZpeGVzKTtcbiAgICAgICAgaWYgKHZhbHVlcy4kc2hhcmVkKSB7XG4gICAgICAgICAgICB2YWx1ZXMuJHNoYXJlZCA9IHNoYXJpbmc7XG4gICAgICAgICAgICBjYWNoZVtjYWNoZUtleV0gPSBPYmplY3QuZnJlZXplKGNsb25lSWZOb3RTaGFyZWQodmFsdWVzLCBzaGFyaW5nKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlcztcbiAgICB9XG4gX3Jlc29sdmVBbmltYXRpb25zKGluZGV4LCB0cmFuc2l0aW9uLCBhY3RpdmUpIHtcbiAgICAgICAgY29uc3QgY2hhcnQgPSB0aGlzLmNoYXJ0O1xuICAgICAgICBjb25zdCBjYWNoZSA9IHRoaXMuX2NhY2hlZERhdGFPcHRzO1xuICAgICAgICBjb25zdCBjYWNoZUtleSA9IGBhbmltYXRpb24tJHt0cmFuc2l0aW9ufWA7XG4gICAgICAgIGNvbnN0IGNhY2hlZCA9IGNhY2hlW2NhY2hlS2V5XTtcbiAgICAgICAgaWYgKGNhY2hlZCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgb3B0aW9ucztcbiAgICAgICAgaWYgKGNoYXJ0Lm9wdGlvbnMuYW5pbWF0aW9uICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgY29uc3QgY29uZmlnID0gdGhpcy5jaGFydC5jb25maWc7XG4gICAgICAgICAgICBjb25zdCBzY29wZUtleXMgPSBjb25maWcuZGF0YXNldEFuaW1hdGlvblNjb3BlS2V5cyh0aGlzLl90eXBlLCB0cmFuc2l0aW9uKTtcbiAgICAgICAgICAgIGNvbnN0IHNjb3BlcyA9IGNvbmZpZy5nZXRPcHRpb25TY29wZXModGhpcy5nZXREYXRhc2V0KCksIHNjb3BlS2V5cyk7XG4gICAgICAgICAgICBvcHRpb25zID0gY29uZmlnLmNyZWF0ZVJlc29sdmVyKHNjb3BlcywgdGhpcy5nZXRDb250ZXh0KGluZGV4LCBhY3RpdmUsIHRyYW5zaXRpb24pKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhbmltYXRpb25zID0gbmV3IEFuaW1hdGlvbnMoY2hhcnQsIG9wdGlvbnMgJiYgb3B0aW9ucy5hbmltYXRpb25zKTtcbiAgICAgICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5fY2FjaGVhYmxlKSB7XG4gICAgICAgICAgICBjYWNoZVtjYWNoZUtleV0gPSBPYmplY3QuZnJlZXplKGFuaW1hdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhbmltYXRpb25zO1xuICAgIH1cbiBnZXRTaGFyZWRPcHRpb25zKG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKCFvcHRpb25zLiRzaGFyZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fc2hhcmVkT3B0aW9ucyB8fCAodGhpcy5fc2hhcmVkT3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oe30sIG9wdGlvbnMpKTtcbiAgICB9XG4gaW5jbHVkZU9wdGlvbnMobW9kZSwgc2hhcmVkT3B0aW9ucykge1xuICAgICAgICByZXR1cm4gIXNoYXJlZE9wdGlvbnMgfHwgaXNEaXJlY3RVcGRhdGVNb2RlKG1vZGUpIHx8IHRoaXMuY2hhcnQuX2FuaW1hdGlvbnNEaXNhYmxlZDtcbiAgICB9XG4gX2dldFNoYXJlZE9wdGlvbnMoc3RhcnQsIG1vZGUpIHtcbiAgICAgICAgY29uc3QgZmlyc3RPcHRzID0gdGhpcy5yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKHN0YXJ0LCBtb2RlKTtcbiAgICAgICAgY29uc3QgcHJldmlvdXNseVNoYXJlZE9wdGlvbnMgPSB0aGlzLl9zaGFyZWRPcHRpb25zO1xuICAgICAgICBjb25zdCBzaGFyZWRPcHRpb25zID0gdGhpcy5nZXRTaGFyZWRPcHRpb25zKGZpcnN0T3B0cyk7XG4gICAgICAgIGNvbnN0IGluY2x1ZGVPcHRpb25zID0gdGhpcy5pbmNsdWRlT3B0aW9ucyhtb2RlLCBzaGFyZWRPcHRpb25zKSB8fCBzaGFyZWRPcHRpb25zICE9PSBwcmV2aW91c2x5U2hhcmVkT3B0aW9ucztcbiAgICAgICAgdGhpcy51cGRhdGVTaGFyZWRPcHRpb25zKHNoYXJlZE9wdGlvbnMsIG1vZGUsIGZpcnN0T3B0cyk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzaGFyZWRPcHRpb25zLFxuICAgICAgICAgICAgaW5jbHVkZU9wdGlvbnNcbiAgICAgICAgfTtcbiAgICB9XG4gdXBkYXRlRWxlbWVudChlbGVtZW50LCBpbmRleCwgcHJvcGVydGllcywgbW9kZSkge1xuICAgICAgICBpZiAoaXNEaXJlY3RVcGRhdGVNb2RlKG1vZGUpKSB7XG4gICAgICAgICAgICBPYmplY3QuYXNzaWduKGVsZW1lbnQsIHByb3BlcnRpZXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fcmVzb2x2ZUFuaW1hdGlvbnMoaW5kZXgsIG1vZGUpLnVwZGF0ZShlbGVtZW50LCBwcm9wZXJ0aWVzKTtcbiAgICAgICAgfVxuICAgIH1cbiB1cGRhdGVTaGFyZWRPcHRpb25zKHNoYXJlZE9wdGlvbnMsIG1vZGUsIG5ld09wdGlvbnMpIHtcbiAgICAgICAgaWYgKHNoYXJlZE9wdGlvbnMgJiYgIWlzRGlyZWN0VXBkYXRlTW9kZShtb2RlKSkge1xuICAgICAgICAgICAgdGhpcy5fcmVzb2x2ZUFuaW1hdGlvbnModW5kZWZpbmVkLCBtb2RlKS51cGRhdGUoc2hhcmVkT3B0aW9ucywgbmV3T3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICB9XG4gX3NldFN0eWxlKGVsZW1lbnQsIGluZGV4LCBtb2RlLCBhY3RpdmUpIHtcbiAgICAgICAgZWxlbWVudC5hY3RpdmUgPSBhY3RpdmU7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLmdldFN0eWxlKGluZGV4LCBhY3RpdmUpO1xuICAgICAgICB0aGlzLl9yZXNvbHZlQW5pbWF0aW9ucyhpbmRleCwgbW9kZSwgYWN0aXZlKS51cGRhdGUoZWxlbWVudCwge1xuICAgICAgICAgICAgb3B0aW9uczogIWFjdGl2ZSAmJiB0aGlzLmdldFNoYXJlZE9wdGlvbnMob3B0aW9ucykgfHwgb3B0aW9uc1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmVtb3ZlSG92ZXJTdHlsZShlbGVtZW50LCBkYXRhc2V0SW5kZXgsIGluZGV4KSB7XG4gICAgICAgIHRoaXMuX3NldFN0eWxlKGVsZW1lbnQsIGluZGV4LCAnYWN0aXZlJywgZmFsc2UpO1xuICAgIH1cbiAgICBzZXRIb3ZlclN0eWxlKGVsZW1lbnQsIGRhdGFzZXRJbmRleCwgaW5kZXgpIHtcbiAgICAgICAgdGhpcy5fc2V0U3R5bGUoZWxlbWVudCwgaW5kZXgsICdhY3RpdmUnLCB0cnVlKTtcbiAgICB9XG4gX3JlbW92ZURhdGFzZXRIb3ZlclN0eWxlKCkge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5fY2FjaGVkTWV0YS5kYXRhc2V0O1xuICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5fc2V0U3R5bGUoZWxlbWVudCwgdW5kZWZpbmVkLCAnYWN0aXZlJywgZmFsc2UpO1xuICAgICAgICB9XG4gICAgfVxuIF9zZXREYXRhc2V0SG92ZXJTdHlsZSgpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2NhY2hlZE1ldGEuZGF0YXNldDtcbiAgICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX3NldFN0eWxlKGVsZW1lbnQsIHVuZGVmaW5lZCwgJ2FjdGl2ZScsIHRydWUpO1xuICAgICAgICB9XG4gICAgfVxuIF9yZXN5bmNFbGVtZW50cyhyZXNldE5ld0VsZW1lbnRzKSB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhO1xuICAgICAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuX2NhY2hlZE1ldGEuZGF0YTtcbiAgICAgICAgZm9yIChjb25zdCBbbWV0aG9kLCBhcmcxLCBhcmcyXSBvZiB0aGlzLl9zeW5jTGlzdCl7XG4gICAgICAgICAgICB0aGlzW21ldGhvZF0oYXJnMSwgYXJnMik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc3luY0xpc3QgPSBbXTtcbiAgICAgICAgY29uc3QgbnVtTWV0YSA9IGVsZW1lbnRzLmxlbmd0aDtcbiAgICAgICAgY29uc3QgbnVtRGF0YSA9IGRhdGEubGVuZ3RoO1xuICAgICAgICBjb25zdCBjb3VudCA9IE1hdGgubWluKG51bURhdGEsIG51bU1ldGEpO1xuICAgICAgICBpZiAoY291bnQpIHtcbiAgICAgICAgICAgIHRoaXMucGFyc2UoMCwgY291bnQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChudW1EYXRhID4gbnVtTWV0YSkge1xuICAgICAgICAgICAgdGhpcy5faW5zZXJ0RWxlbWVudHMobnVtTWV0YSwgbnVtRGF0YSAtIG51bU1ldGEsIHJlc2V0TmV3RWxlbWVudHMpO1xuICAgICAgICB9IGVsc2UgaWYgKG51bURhdGEgPCBudW1NZXRhKSB7XG4gICAgICAgICAgICB0aGlzLl9yZW1vdmVFbGVtZW50cyhudW1EYXRhLCBudW1NZXRhIC0gbnVtRGF0YSk7XG4gICAgICAgIH1cbiAgICB9XG4gX2luc2VydEVsZW1lbnRzKHN0YXJ0LCBjb3VudCwgcmVzZXROZXdFbGVtZW50cyA9IHRydWUpIHtcbiAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBtZXRhLmRhdGE7XG4gICAgICAgIGNvbnN0IGVuZCA9IHN0YXJ0ICsgY291bnQ7XG4gICAgICAgIGxldCBpO1xuICAgICAgICBjb25zdCBtb3ZlID0gKGFycik9PntcbiAgICAgICAgICAgIGFyci5sZW5ndGggKz0gY291bnQ7XG4gICAgICAgICAgICBmb3IoaSA9IGFyci5sZW5ndGggLSAxOyBpID49IGVuZDsgaS0tKXtcbiAgICAgICAgICAgICAgICBhcnJbaV0gPSBhcnJbaSAtIGNvdW50XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgbW92ZShkYXRhKTtcbiAgICAgICAgZm9yKGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKXtcbiAgICAgICAgICAgIGRhdGFbaV0gPSBuZXcgdGhpcy5kYXRhRWxlbWVudFR5cGUoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fcGFyc2luZykge1xuICAgICAgICAgICAgbW92ZShtZXRhLl9wYXJzZWQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucGFyc2Uoc3RhcnQsIGNvdW50KTtcbiAgICAgICAgaWYgKHJlc2V0TmV3RWxlbWVudHMpIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlRWxlbWVudHMoZGF0YSwgc3RhcnQsIGNvdW50LCAncmVzZXQnKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICB1cGRhdGVFbGVtZW50cyhlbGVtZW50LCBzdGFydCwgY291bnQsIG1vZGUpIHt9XG4gX3JlbW92ZUVsZW1lbnRzKHN0YXJ0LCBjb3VudCkge1xuICAgICAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICAgICAgaWYgKHRoaXMuX3BhcnNpbmcpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlbW92ZWQgPSBtZXRhLl9wYXJzZWQuc3BsaWNlKHN0YXJ0LCBjb3VudCk7XG4gICAgICAgICAgICBpZiAobWV0YS5fc3RhY2tlZCkge1xuICAgICAgICAgICAgICAgIGNsZWFyU3RhY2tzKG1ldGEsIHJlbW92ZWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIG1ldGEuZGF0YS5zcGxpY2Uoc3RhcnQsIGNvdW50KTtcbiAgICB9XG4gX3N5bmMoYXJncykge1xuICAgICAgICBpZiAodGhpcy5fcGFyc2luZykge1xuICAgICAgICAgICAgdGhpcy5fc3luY0xpc3QucHVzaChhcmdzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IFttZXRob2QsIGFyZzEsIGFyZzJdID0gYXJncztcbiAgICAgICAgICAgIHRoaXNbbWV0aG9kXShhcmcxLCBhcmcyKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNoYXJ0Ll9kYXRhQ2hhbmdlcy5wdXNoKFtcbiAgICAgICAgICAgIHRoaXMuaW5kZXgsXG4gICAgICAgICAgICAuLi5hcmdzXG4gICAgICAgIF0pO1xuICAgIH1cbiAgICBfb25EYXRhUHVzaCgpIHtcbiAgICAgICAgY29uc3QgY291bnQgPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgICAgICB0aGlzLl9zeW5jKFtcbiAgICAgICAgICAgICdfaW5zZXJ0RWxlbWVudHMnLFxuICAgICAgICAgICAgdGhpcy5nZXREYXRhc2V0KCkuZGF0YS5sZW5ndGggLSBjb3VudCxcbiAgICAgICAgICAgIGNvdW50XG4gICAgICAgIF0pO1xuICAgIH1cbiAgICBfb25EYXRhUG9wKCkge1xuICAgICAgICB0aGlzLl9zeW5jKFtcbiAgICAgICAgICAgICdfcmVtb3ZlRWxlbWVudHMnLFxuICAgICAgICAgICAgdGhpcy5fY2FjaGVkTWV0YS5kYXRhLmxlbmd0aCAtIDEsXG4gICAgICAgICAgICAxXG4gICAgICAgIF0pO1xuICAgIH1cbiAgICBfb25EYXRhU2hpZnQoKSB7XG4gICAgICAgIHRoaXMuX3N5bmMoW1xuICAgICAgICAgICAgJ19yZW1vdmVFbGVtZW50cycsXG4gICAgICAgICAgICAwLFxuICAgICAgICAgICAgMVxuICAgICAgICBdKTtcbiAgICB9XG4gICAgX29uRGF0YVNwbGljZShzdGFydCwgY291bnQpIHtcbiAgICAgICAgaWYgKGNvdW50KSB7XG4gICAgICAgICAgICB0aGlzLl9zeW5jKFtcbiAgICAgICAgICAgICAgICAnX3JlbW92ZUVsZW1lbnRzJyxcbiAgICAgICAgICAgICAgICBzdGFydCxcbiAgICAgICAgICAgICAgICBjb3VudFxuICAgICAgICAgICAgXSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV3Q291bnQgPSBhcmd1bWVudHMubGVuZ3RoIC0gMjtcbiAgICAgICAgaWYgKG5ld0NvdW50KSB7XG4gICAgICAgICAgICB0aGlzLl9zeW5jKFtcbiAgICAgICAgICAgICAgICAnX2luc2VydEVsZW1lbnRzJyxcbiAgICAgICAgICAgICAgICBzdGFydCxcbiAgICAgICAgICAgICAgICBuZXdDb3VudFxuICAgICAgICAgICAgXSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgX29uRGF0YVVuc2hpZnQoKSB7XG4gICAgICAgIHRoaXMuX3N5bmMoW1xuICAgICAgICAgICAgJ19pbnNlcnRFbGVtZW50cycsXG4gICAgICAgICAgICAwLFxuICAgICAgICAgICAgYXJndW1lbnRzLmxlbmd0aFxuICAgICAgICBdKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGdldEFsbFNjYWxlVmFsdWVzKHNjYWxlLCB0eXBlKSB7XG4gICAgaWYgKCFzY2FsZS5fY2FjaGUuJGJhcikge1xuICAgICAgICBjb25zdCB2aXNpYmxlTWV0YXMgPSBzY2FsZS5nZXRNYXRjaGluZ1Zpc2libGVNZXRhcyh0eXBlKTtcbiAgICAgICAgbGV0IHZhbHVlcyA9IFtdO1xuICAgICAgICBmb3IobGV0IGkgPSAwLCBpbGVuID0gdmlzaWJsZU1ldGFzLmxlbmd0aDsgaSA8IGlsZW47IGkrKyl7XG4gICAgICAgICAgICB2YWx1ZXMgPSB2YWx1ZXMuY29uY2F0KHZpc2libGVNZXRhc1tpXS5jb250cm9sbGVyLmdldEFsbFBhcnNlZFZhbHVlcyhzY2FsZSkpO1xuICAgICAgICB9XG4gICAgICAgIHNjYWxlLl9jYWNoZS4kYmFyID0gX2FycmF5VW5pcXVlKHZhbHVlcy5zb3J0KChhLCBiKT0+YSAtIGIpKTtcbiAgICB9XG4gICAgcmV0dXJuIHNjYWxlLl9jYWNoZS4kYmFyO1xufVxuIGZ1bmN0aW9uIGNvbXB1dGVNaW5TYW1wbGVTaXplKG1ldGEpIHtcbiAgICBjb25zdCBzY2FsZSA9IG1ldGEuaVNjYWxlO1xuICAgIGNvbnN0IHZhbHVlcyA9IGdldEFsbFNjYWxlVmFsdWVzKHNjYWxlLCBtZXRhLnR5cGUpO1xuICAgIGxldCBtaW4gPSBzY2FsZS5fbGVuZ3RoO1xuICAgIGxldCBpLCBpbGVuLCBjdXJyLCBwcmV2O1xuICAgIGNvbnN0IHVwZGF0ZU1pbkFuZFByZXYgPSAoKT0+e1xuICAgICAgICBpZiAoY3VyciA9PT0gMzI3NjcgfHwgY3VyciA9PT0gLTMyNzY4KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRlZmluZWQocHJldikpIHtcbiAgICAgICAgICAgIG1pbiA9IE1hdGgubWluKG1pbiwgTWF0aC5hYnMoY3VyciAtIHByZXYpIHx8IG1pbik7XG4gICAgICAgIH1cbiAgICAgICAgcHJldiA9IGN1cnI7XG4gICAgfTtcbiAgICBmb3IoaSA9IDAsIGlsZW4gPSB2YWx1ZXMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKXtcbiAgICAgICAgY3VyciA9IHNjYWxlLmdldFBpeGVsRm9yVmFsdWUodmFsdWVzW2ldKTtcbiAgICAgICAgdXBkYXRlTWluQW5kUHJldigpO1xuICAgIH1cbiAgICBwcmV2ID0gdW5kZWZpbmVkO1xuICAgIGZvcihpID0gMCwgaWxlbiA9IHNjYWxlLnRpY2tzLmxlbmd0aDsgaSA8IGlsZW47ICsraSl7XG4gICAgICAgIGN1cnIgPSBzY2FsZS5nZXRQaXhlbEZvclRpY2soaSk7XG4gICAgICAgIHVwZGF0ZU1pbkFuZFByZXYoKTtcbiAgICB9XG4gICAgcmV0dXJuIG1pbjtcbn1cbiBmdW5jdGlvbiBjb21wdXRlRml0Q2F0ZWdvcnlUcmFpdHMoaW5kZXgsIHJ1bGVyLCBvcHRpb25zLCBzdGFja0NvdW50KSB7XG4gICAgY29uc3QgdGhpY2tuZXNzID0gb3B0aW9ucy5iYXJUaGlja25lc3M7XG4gICAgbGV0IHNpemUsIHJhdGlvO1xuICAgIGlmIChpc051bGxPclVuZGVmKHRoaWNrbmVzcykpIHtcbiAgICAgICAgc2l6ZSA9IHJ1bGVyLm1pbiAqIG9wdGlvbnMuY2F0ZWdvcnlQZXJjZW50YWdlO1xuICAgICAgICByYXRpbyA9IG9wdGlvbnMuYmFyUGVyY2VudGFnZTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBzaXplID0gdGhpY2tuZXNzICogc3RhY2tDb3VudDtcbiAgICAgICAgcmF0aW8gPSAxO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBjaHVuazogc2l6ZSAvIHN0YWNrQ291bnQsXG4gICAgICAgIHJhdGlvLFxuICAgICAgICBzdGFydDogcnVsZXIucGl4ZWxzW2luZGV4XSAtIHNpemUgLyAyXG4gICAgfTtcbn1cbiBmdW5jdGlvbiBjb21wdXRlRmxleENhdGVnb3J5VHJhaXRzKGluZGV4LCBydWxlciwgb3B0aW9ucywgc3RhY2tDb3VudCkge1xuICAgIGNvbnN0IHBpeGVscyA9IHJ1bGVyLnBpeGVscztcbiAgICBjb25zdCBjdXJyID0gcGl4ZWxzW2luZGV4XTtcbiAgICBsZXQgcHJldiA9IGluZGV4ID4gMCA/IHBpeGVsc1tpbmRleCAtIDFdIDogbnVsbDtcbiAgICBsZXQgbmV4dCA9IGluZGV4IDwgcGl4ZWxzLmxlbmd0aCAtIDEgPyBwaXhlbHNbaW5kZXggKyAxXSA6IG51bGw7XG4gICAgY29uc3QgcGVyY2VudCA9IG9wdGlvbnMuY2F0ZWdvcnlQZXJjZW50YWdlO1xuICAgIGlmIChwcmV2ID09PSBudWxsKSB7XG4gICAgICAgIHByZXYgPSBjdXJyIC0gKG5leHQgPT09IG51bGwgPyBydWxlci5lbmQgLSBydWxlci5zdGFydCA6IG5leHQgLSBjdXJyKTtcbiAgICB9XG4gICAgaWYgKG5leHQgPT09IG51bGwpIHtcbiAgICAgICAgbmV4dCA9IGN1cnIgKyBjdXJyIC0gcHJldjtcbiAgICB9XG4gICAgY29uc3Qgc3RhcnQgPSBjdXJyIC0gKGN1cnIgLSBNYXRoLm1pbihwcmV2LCBuZXh0KSkgLyAyICogcGVyY2VudDtcbiAgICBjb25zdCBzaXplID0gTWF0aC5hYnMobmV4dCAtIHByZXYpIC8gMiAqIHBlcmNlbnQ7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgY2h1bms6IHNpemUgLyBzdGFja0NvdW50LFxuICAgICAgICByYXRpbzogb3B0aW9ucy5iYXJQZXJjZW50YWdlLFxuICAgICAgICBzdGFydFxuICAgIH07XG59XG5mdW5jdGlvbiBwYXJzZUZsb2F0QmFyKGVudHJ5LCBpdGVtLCB2U2NhbGUsIGkpIHtcbiAgICBjb25zdCBzdGFydFZhbHVlID0gdlNjYWxlLnBhcnNlKGVudHJ5WzBdLCBpKTtcbiAgICBjb25zdCBlbmRWYWx1ZSA9IHZTY2FsZS5wYXJzZShlbnRyeVsxXSwgaSk7XG4gICAgY29uc3QgbWluID0gTWF0aC5taW4oc3RhcnRWYWx1ZSwgZW5kVmFsdWUpO1xuICAgIGNvbnN0IG1heCA9IE1hdGgubWF4KHN0YXJ0VmFsdWUsIGVuZFZhbHVlKTtcbiAgICBsZXQgYmFyU3RhcnQgPSBtaW47XG4gICAgbGV0IGJhckVuZCA9IG1heDtcbiAgICBpZiAoTWF0aC5hYnMobWluKSA+IE1hdGguYWJzKG1heCkpIHtcbiAgICAgICAgYmFyU3RhcnQgPSBtYXg7XG4gICAgICAgIGJhckVuZCA9IG1pbjtcbiAgICB9XG4gICAgaXRlbVt2U2NhbGUuYXhpc10gPSBiYXJFbmQ7XG4gICAgaXRlbS5fY3VzdG9tID0ge1xuICAgICAgICBiYXJTdGFydCxcbiAgICAgICAgYmFyRW5kLFxuICAgICAgICBzdGFydDogc3RhcnRWYWx1ZSxcbiAgICAgICAgZW5kOiBlbmRWYWx1ZSxcbiAgICAgICAgbWluLFxuICAgICAgICBtYXhcbiAgICB9O1xufVxuZnVuY3Rpb24gcGFyc2VWYWx1ZShlbnRyeSwgaXRlbSwgdlNjYWxlLCBpKSB7XG4gICAgaWYgKGlzQXJyYXkoZW50cnkpKSB7XG4gICAgICAgIHBhcnNlRmxvYXRCYXIoZW50cnksIGl0ZW0sIHZTY2FsZSwgaSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgaXRlbVt2U2NhbGUuYXhpc10gPSB2U2NhbGUucGFyc2UoZW50cnksIGkpO1xuICAgIH1cbiAgICByZXR1cm4gaXRlbTtcbn1cbmZ1bmN0aW9uIHBhcnNlQXJyYXlPclByaW1pdGl2ZShtZXRhLCBkYXRhLCBzdGFydCwgY291bnQpIHtcbiAgICBjb25zdCBpU2NhbGUgPSBtZXRhLmlTY2FsZTtcbiAgICBjb25zdCB2U2NhbGUgPSBtZXRhLnZTY2FsZTtcbiAgICBjb25zdCBsYWJlbHMgPSBpU2NhbGUuZ2V0TGFiZWxzKCk7XG4gICAgY29uc3Qgc2luZ2xlU2NhbGUgPSBpU2NhbGUgPT09IHZTY2FsZTtcbiAgICBjb25zdCBwYXJzZWQgPSBbXTtcbiAgICBsZXQgaSwgaWxlbiwgaXRlbSwgZW50cnk7XG4gICAgZm9yKGkgPSBzdGFydCwgaWxlbiA9IHN0YXJ0ICsgY291bnQ7IGkgPCBpbGVuOyArK2kpe1xuICAgICAgICBlbnRyeSA9IGRhdGFbaV07XG4gICAgICAgIGl0ZW0gPSB7fTtcbiAgICAgICAgaXRlbVtpU2NhbGUuYXhpc10gPSBzaW5nbGVTY2FsZSB8fCBpU2NhbGUucGFyc2UobGFiZWxzW2ldLCBpKTtcbiAgICAgICAgcGFyc2VkLnB1c2gocGFyc2VWYWx1ZShlbnRyeSwgaXRlbSwgdlNjYWxlLCBpKSk7XG4gICAgfVxuICAgIHJldHVybiBwYXJzZWQ7XG59XG5mdW5jdGlvbiBpc0Zsb2F0QmFyKGN1c3RvbSkge1xuICAgIHJldHVybiBjdXN0b20gJiYgY3VzdG9tLmJhclN0YXJ0ICE9PSB1bmRlZmluZWQgJiYgY3VzdG9tLmJhckVuZCAhPT0gdW5kZWZpbmVkO1xufVxuZnVuY3Rpb24gYmFyU2lnbihzaXplLCB2U2NhbGUsIGFjdHVhbEJhc2UpIHtcbiAgICBpZiAoc2l6ZSAhPT0gMCkge1xuICAgICAgICByZXR1cm4gc2lnbihzaXplKTtcbiAgICB9XG4gICAgcmV0dXJuICh2U2NhbGUuaXNIb3Jpem9udGFsKCkgPyAxIDogLTEpICogKHZTY2FsZS5taW4gPj0gYWN0dWFsQmFzZSA/IDEgOiAtMSk7XG59XG5mdW5jdGlvbiBib3JkZXJQcm9wcyhwcm9wZXJ0aWVzKSB7XG4gICAgbGV0IHJldmVyc2UsIHN0YXJ0LCBlbmQsIHRvcCwgYm90dG9tO1xuICAgIGlmIChwcm9wZXJ0aWVzLmhvcml6b250YWwpIHtcbiAgICAgICAgcmV2ZXJzZSA9IHByb3BlcnRpZXMuYmFzZSA+IHByb3BlcnRpZXMueDtcbiAgICAgICAgc3RhcnQgPSAnbGVmdCc7XG4gICAgICAgIGVuZCA9ICdyaWdodCc7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV2ZXJzZSA9IHByb3BlcnRpZXMuYmFzZSA8IHByb3BlcnRpZXMueTtcbiAgICAgICAgc3RhcnQgPSAnYm90dG9tJztcbiAgICAgICAgZW5kID0gJ3RvcCc7XG4gICAgfVxuICAgIGlmIChyZXZlcnNlKSB7XG4gICAgICAgIHRvcCA9ICdlbmQnO1xuICAgICAgICBib3R0b20gPSAnc3RhcnQnO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRvcCA9ICdzdGFydCc7XG4gICAgICAgIGJvdHRvbSA9ICdlbmQnO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBzdGFydCxcbiAgICAgICAgZW5kLFxuICAgICAgICByZXZlcnNlLFxuICAgICAgICB0b3AsXG4gICAgICAgIGJvdHRvbVxuICAgIH07XG59XG5mdW5jdGlvbiBzZXRCb3JkZXJTa2lwcGVkKHByb3BlcnRpZXMsIG9wdGlvbnMsIHN0YWNrLCBpbmRleCkge1xuICAgIGxldCBlZGdlID0gb3B0aW9ucy5ib3JkZXJTa2lwcGVkO1xuICAgIGNvbnN0IHJlcyA9IHt9O1xuICAgIGlmICghZWRnZSkge1xuICAgICAgICBwcm9wZXJ0aWVzLmJvcmRlclNraXBwZWQgPSByZXM7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGVkZ2UgPT09IHRydWUpIHtcbiAgICAgICAgcHJvcGVydGllcy5ib3JkZXJTa2lwcGVkID0ge1xuICAgICAgICAgICAgdG9wOiB0cnVlLFxuICAgICAgICAgICAgcmlnaHQ6IHRydWUsXG4gICAgICAgICAgICBib3R0b206IHRydWUsXG4gICAgICAgICAgICBsZWZ0OiB0cnVlXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgeyBzdGFydCAsIGVuZCAsIHJldmVyc2UgLCB0b3AgLCBib3R0b20gIH0gPSBib3JkZXJQcm9wcyhwcm9wZXJ0aWVzKTtcbiAgICBpZiAoZWRnZSA9PT0gJ21pZGRsZScgJiYgc3RhY2spIHtcbiAgICAgICAgcHJvcGVydGllcy5lbmFibGVCb3JkZXJSYWRpdXMgPSB0cnVlO1xuICAgICAgICBpZiAoKHN0YWNrLl90b3AgfHwgMCkgPT09IGluZGV4KSB7XG4gICAgICAgICAgICBlZGdlID0gdG9wO1xuICAgICAgICB9IGVsc2UgaWYgKChzdGFjay5fYm90dG9tIHx8IDApID09PSBpbmRleCkge1xuICAgICAgICAgICAgZWRnZSA9IGJvdHRvbTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc1twYXJzZUVkZ2UoYm90dG9tLCBzdGFydCwgZW5kLCByZXZlcnNlKV0gPSB0cnVlO1xuICAgICAgICAgICAgZWRnZSA9IHRvcDtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXNbcGFyc2VFZGdlKGVkZ2UsIHN0YXJ0LCBlbmQsIHJldmVyc2UpXSA9IHRydWU7XG4gICAgcHJvcGVydGllcy5ib3JkZXJTa2lwcGVkID0gcmVzO1xufVxuZnVuY3Rpb24gcGFyc2VFZGdlKGVkZ2UsIGEsIGIsIHJldmVyc2UpIHtcbiAgICBpZiAocmV2ZXJzZSkge1xuICAgICAgICBlZGdlID0gc3dhcChlZGdlLCBhLCBiKTtcbiAgICAgICAgZWRnZSA9IHN0YXJ0RW5kKGVkZ2UsIGIsIGEpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGVkZ2UgPSBzdGFydEVuZChlZGdlLCBhLCBiKTtcbiAgICB9XG4gICAgcmV0dXJuIGVkZ2U7XG59XG5mdW5jdGlvbiBzd2FwKG9yaWcsIHYxLCB2Mikge1xuICAgIHJldHVybiBvcmlnID09PSB2MSA/IHYyIDogb3JpZyA9PT0gdjIgPyB2MSA6IG9yaWc7XG59XG5mdW5jdGlvbiBzdGFydEVuZCh2LCBzdGFydCwgZW5kKSB7XG4gICAgcmV0dXJuIHYgPT09ICdzdGFydCcgPyBzdGFydCA6IHYgPT09ICdlbmQnID8gZW5kIDogdjtcbn1cbmZ1bmN0aW9uIHNldEluZmxhdGVBbW91bnQocHJvcGVydGllcywgeyBpbmZsYXRlQW1vdW50ICB9LCByYXRpbykge1xuICAgIHByb3BlcnRpZXMuaW5mbGF0ZUFtb3VudCA9IGluZmxhdGVBbW91bnQgPT09ICdhdXRvJyA/IHJhdGlvID09PSAxID8gMC4zMyA6IDAgOiBpbmZsYXRlQW1vdW50O1xufVxuY2xhc3MgQmFyQ29udHJvbGxlciBleHRlbmRzIERhdGFzZXRDb250cm9sbGVyIHtcbiAgICBzdGF0aWMgaWQgPSAnYmFyJztcbiBzdGF0aWMgZGVmYXVsdHMgPSB7XG4gICAgICAgIGRhdGFzZXRFbGVtZW50VHlwZTogZmFsc2UsXG4gICAgICAgIGRhdGFFbGVtZW50VHlwZTogJ2JhcicsXG4gICAgICAgIGNhdGVnb3J5UGVyY2VudGFnZTogMC44LFxuICAgICAgICBiYXJQZXJjZW50YWdlOiAwLjksXG4gICAgICAgIGdyb3VwZWQ6IHRydWUsXG4gICAgICAgIGFuaW1hdGlvbnM6IHtcbiAgICAgICAgICAgIG51bWJlcnM6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiBbXG4gICAgICAgICAgICAgICAgICAgICd4JyxcbiAgICAgICAgICAgICAgICAgICAgJ3knLFxuICAgICAgICAgICAgICAgICAgICAnYmFzZScsXG4gICAgICAgICAgICAgICAgICAgICd3aWR0aCcsXG4gICAgICAgICAgICAgICAgICAgICdoZWlnaHQnXG4gICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiBzdGF0aWMgb3ZlcnJpZGVzID0ge1xuICAgICAgICBzY2FsZXM6IHtcbiAgICAgICAgICAgIF9pbmRleF86IHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnY2F0ZWdvcnknLFxuICAgICAgICAgICAgICAgIG9mZnNldDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBncmlkOiB7XG4gICAgICAgICAgICAgICAgICAgIG9mZnNldDogdHJ1ZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBfdmFsdWVfOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2xpbmVhcicsXG4gICAgICAgICAgICAgICAgYmVnaW5BdFplcm86IHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gcGFyc2VQcmltaXRpdmVEYXRhKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCkge1xuICAgICAgICByZXR1cm4gcGFyc2VBcnJheU9yUHJpbWl0aXZlKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCk7XG4gICAgfVxuIHBhcnNlQXJyYXlEYXRhKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCkge1xuICAgICAgICByZXR1cm4gcGFyc2VBcnJheU9yUHJpbWl0aXZlKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCk7XG4gICAgfVxuIHBhcnNlT2JqZWN0RGF0YShtZXRhLCBkYXRhLCBzdGFydCwgY291bnQpIHtcbiAgICAgICAgY29uc3QgeyBpU2NhbGUgLCB2U2NhbGUgIH0gPSBtZXRhO1xuICAgICAgICBjb25zdCB7IHhBeGlzS2V5ID0neCcgLCB5QXhpc0tleSA9J3knICB9ID0gdGhpcy5fcGFyc2luZztcbiAgICAgICAgY29uc3QgaUF4aXNLZXkgPSBpU2NhbGUuYXhpcyA9PT0gJ3gnID8geEF4aXNLZXkgOiB5QXhpc0tleTtcbiAgICAgICAgY29uc3QgdkF4aXNLZXkgPSB2U2NhbGUuYXhpcyA9PT0gJ3gnID8geEF4aXNLZXkgOiB5QXhpc0tleTtcbiAgICAgICAgY29uc3QgcGFyc2VkID0gW107XG4gICAgICAgIGxldCBpLCBpbGVuLCBpdGVtLCBvYmo7XG4gICAgICAgIGZvcihpID0gc3RhcnQsIGlsZW4gPSBzdGFydCArIGNvdW50OyBpIDwgaWxlbjsgKytpKXtcbiAgICAgICAgICAgIG9iaiA9IGRhdGFbaV07XG4gICAgICAgICAgICBpdGVtID0ge307XG4gICAgICAgICAgICBpdGVtW2lTY2FsZS5heGlzXSA9IGlTY2FsZS5wYXJzZShyZXNvbHZlT2JqZWN0S2V5KG9iaiwgaUF4aXNLZXkpLCBpKTtcbiAgICAgICAgICAgIHBhcnNlZC5wdXNoKHBhcnNlVmFsdWUocmVzb2x2ZU9iamVjdEtleShvYmosIHZBeGlzS2V5KSwgaXRlbSwgdlNjYWxlLCBpKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBhcnNlZDtcbiAgICB9XG4gdXBkYXRlUmFuZ2VGcm9tUGFyc2VkKHJhbmdlLCBzY2FsZSwgcGFyc2VkLCBzdGFjaykge1xuICAgICAgICBzdXBlci51cGRhdGVSYW5nZUZyb21QYXJzZWQocmFuZ2UsIHNjYWxlLCBwYXJzZWQsIHN0YWNrKTtcbiAgICAgICAgY29uc3QgY3VzdG9tID0gcGFyc2VkLl9jdXN0b207XG4gICAgICAgIGlmIChjdXN0b20gJiYgc2NhbGUgPT09IHRoaXMuX2NhY2hlZE1ldGEudlNjYWxlKSB7XG4gICAgICAgICAgICByYW5nZS5taW4gPSBNYXRoLm1pbihyYW5nZS5taW4sIGN1c3RvbS5taW4pO1xuICAgICAgICAgICAgcmFuZ2UubWF4ID0gTWF0aC5tYXgocmFuZ2UubWF4LCBjdXN0b20ubWF4KTtcbiAgICAgICAgfVxuICAgIH1cbiBnZXRNYXhPdmVyZmxvdygpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuIGdldExhYmVsQW5kVmFsdWUoaW5kZXgpIHtcbiAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgICAgIGNvbnN0IHsgaVNjYWxlICwgdlNjYWxlICB9ID0gbWV0YTtcbiAgICAgICAgY29uc3QgcGFyc2VkID0gdGhpcy5nZXRQYXJzZWQoaW5kZXgpO1xuICAgICAgICBjb25zdCBjdXN0b20gPSBwYXJzZWQuX2N1c3RvbTtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBpc0Zsb2F0QmFyKGN1c3RvbSkgPyAnWycgKyBjdXN0b20uc3RhcnQgKyAnLCAnICsgY3VzdG9tLmVuZCArICddJyA6ICcnICsgdlNjYWxlLmdldExhYmVsRm9yVmFsdWUocGFyc2VkW3ZTY2FsZS5heGlzXSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBsYWJlbDogJycgKyBpU2NhbGUuZ2V0TGFiZWxGb3JWYWx1ZShwYXJzZWRbaVNjYWxlLmF4aXNdKSxcbiAgICAgICAgICAgIHZhbHVlXG4gICAgICAgIH07XG4gICAgfVxuICAgIGluaXRpYWxpemUoKSB7XG4gICAgICAgIHRoaXMuZW5hYmxlT3B0aW9uU2hhcmluZyA9IHRydWU7XG4gICAgICAgIHN1cGVyLmluaXRpYWxpemUoKTtcbiAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgICAgIG1ldGEuc3RhY2sgPSB0aGlzLmdldERhdGFzZXQoKS5zdGFjaztcbiAgICB9XG4gICAgdXBkYXRlKG1vZGUpIHtcbiAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgICAgIHRoaXMudXBkYXRlRWxlbWVudHMobWV0YS5kYXRhLCAwLCBtZXRhLmRhdGEubGVuZ3RoLCBtb2RlKTtcbiAgICB9XG4gICAgdXBkYXRlRWxlbWVudHMoYmFycywgc3RhcnQsIGNvdW50LCBtb2RlKSB7XG4gICAgICAgIGNvbnN0IHJlc2V0ID0gbW9kZSA9PT0gJ3Jlc2V0JztcbiAgICAgICAgY29uc3QgeyBpbmRleCAsIF9jYWNoZWRNZXRhOiB7IHZTY2FsZSAgfSAgfSA9IHRoaXM7XG4gICAgICAgIGNvbnN0IGJhc2UgPSB2U2NhbGUuZ2V0QmFzZVBpeGVsKCk7XG4gICAgICAgIGNvbnN0IGhvcml6b250YWwgPSB2U2NhbGUuaXNIb3Jpem9udGFsKCk7XG4gICAgICAgIGNvbnN0IHJ1bGVyID0gdGhpcy5fZ2V0UnVsZXIoKTtcbiAgICAgICAgY29uc3QgeyBzaGFyZWRPcHRpb25zICwgaW5jbHVkZU9wdGlvbnMgIH0gPSB0aGlzLl9nZXRTaGFyZWRPcHRpb25zKHN0YXJ0LCBtb2RlKTtcbiAgICAgICAgZm9yKGxldCBpID0gc3RhcnQ7IGkgPCBzdGFydCArIGNvdW50OyBpKyspe1xuICAgICAgICAgICAgY29uc3QgcGFyc2VkID0gdGhpcy5nZXRQYXJzZWQoaSk7XG4gICAgICAgICAgICBjb25zdCB2cGl4ZWxzID0gcmVzZXQgfHwgaXNOdWxsT3JVbmRlZihwYXJzZWRbdlNjYWxlLmF4aXNdKSA/IHtcbiAgICAgICAgICAgICAgICBiYXNlLFxuICAgICAgICAgICAgICAgIGhlYWQ6IGJhc2VcbiAgICAgICAgICAgIH0gOiB0aGlzLl9jYWxjdWxhdGVCYXJWYWx1ZVBpeGVscyhpKTtcbiAgICAgICAgICAgIGNvbnN0IGlwaXhlbHMgPSB0aGlzLl9jYWxjdWxhdGVCYXJJbmRleFBpeGVscyhpLCBydWxlcik7XG4gICAgICAgICAgICBjb25zdCBzdGFjayA9IChwYXJzZWQuX3N0YWNrcyB8fCB7fSlbdlNjYWxlLmF4aXNdO1xuICAgICAgICAgICAgY29uc3QgcHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgICAgICBob3Jpem9udGFsLFxuICAgICAgICAgICAgICAgIGJhc2U6IHZwaXhlbHMuYmFzZSxcbiAgICAgICAgICAgICAgICBlbmFibGVCb3JkZXJSYWRpdXM6ICFzdGFjayB8fCBpc0Zsb2F0QmFyKHBhcnNlZC5fY3VzdG9tKSB8fCBpbmRleCA9PT0gc3RhY2suX3RvcCB8fCBpbmRleCA9PT0gc3RhY2suX2JvdHRvbSxcbiAgICAgICAgICAgICAgICB4OiBob3Jpem9udGFsID8gdnBpeGVscy5oZWFkIDogaXBpeGVscy5jZW50ZXIsXG4gICAgICAgICAgICAgICAgeTogaG9yaXpvbnRhbCA/IGlwaXhlbHMuY2VudGVyIDogdnBpeGVscy5oZWFkLFxuICAgICAgICAgICAgICAgIGhlaWdodDogaG9yaXpvbnRhbCA/IGlwaXhlbHMuc2l6ZSA6IE1hdGguYWJzKHZwaXhlbHMuc2l6ZSksXG4gICAgICAgICAgICAgICAgd2lkdGg6IGhvcml6b250YWwgPyBNYXRoLmFicyh2cGl4ZWxzLnNpemUpIDogaXBpeGVscy5zaXplXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGluY2x1ZGVPcHRpb25zKSB7XG4gICAgICAgICAgICAgICAgcHJvcGVydGllcy5vcHRpb25zID0gc2hhcmVkT3B0aW9ucyB8fCB0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaSwgYmFyc1tpXS5hY3RpdmUgPyAnYWN0aXZlJyA6IG1vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHByb3BlcnRpZXMub3B0aW9ucyB8fCBiYXJzW2ldLm9wdGlvbnM7XG4gICAgICAgICAgICBzZXRCb3JkZXJTa2lwcGVkKHByb3BlcnRpZXMsIG9wdGlvbnMsIHN0YWNrLCBpbmRleCk7XG4gICAgICAgICAgICBzZXRJbmZsYXRlQW1vdW50KHByb3BlcnRpZXMsIG9wdGlvbnMsIHJ1bGVyLnJhdGlvKTtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlRWxlbWVudChiYXJzW2ldLCBpLCBwcm9wZXJ0aWVzLCBtb2RlKTtcbiAgICAgICAgfVxuICAgIH1cbiBfZ2V0U3RhY2tzKGxhc3QsIGRhdGFJbmRleCkge1xuICAgICAgICBjb25zdCB7IGlTY2FsZSAgfSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgICAgIGNvbnN0IG1ldGFzZXRzID0gaVNjYWxlLmdldE1hdGNoaW5nVmlzaWJsZU1ldGFzKHRoaXMuX3R5cGUpLmZpbHRlcigobWV0YSk9Pm1ldGEuY29udHJvbGxlci5vcHRpb25zLmdyb3VwZWQpO1xuICAgICAgICBjb25zdCBzdGFja2VkID0gaVNjYWxlLm9wdGlvbnMuc3RhY2tlZDtcbiAgICAgICAgY29uc3Qgc3RhY2tzID0gW107XG4gICAgICAgIGNvbnN0IGN1cnJlbnRQYXJzZWQgPSB0aGlzLl9jYWNoZWRNZXRhLmNvbnRyb2xsZXIuZ2V0UGFyc2VkKGRhdGFJbmRleCk7XG4gICAgICAgIGNvbnN0IGlTY2FsZVZhbHVlID0gY3VycmVudFBhcnNlZCAmJiBjdXJyZW50UGFyc2VkW2lTY2FsZS5heGlzXTtcbiAgICAgICAgY29uc3Qgc2tpcE51bGwgPSAobWV0YSk9PntcbiAgICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IG1ldGEuX3BhcnNlZC5maW5kKChpdGVtKT0+aXRlbVtpU2NhbGUuYXhpc10gPT09IGlTY2FsZVZhbHVlKTtcbiAgICAgICAgICAgIGNvbnN0IHZhbCA9IHBhcnNlZCAmJiBwYXJzZWRbbWV0YS52U2NhbGUuYXhpc107XG4gICAgICAgICAgICBpZiAoaXNOdWxsT3JVbmRlZih2YWwpIHx8IGlzTmFOKHZhbCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgZm9yIChjb25zdCBtZXRhIG9mIG1ldGFzZXRzKXtcbiAgICAgICAgICAgIGlmIChkYXRhSW5kZXggIT09IHVuZGVmaW5lZCAmJiBza2lwTnVsbChtZXRhKSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHN0YWNrZWQgPT09IGZhbHNlIHx8IHN0YWNrcy5pbmRleE9mKG1ldGEuc3RhY2spID09PSAtMSB8fCBzdGFja2VkID09PSB1bmRlZmluZWQgJiYgbWV0YS5zdGFjayA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgc3RhY2tzLnB1c2gobWV0YS5zdGFjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWV0YS5pbmRleCA9PT0gbGFzdCkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICghc3RhY2tzLmxlbmd0aCkge1xuICAgICAgICAgICAgc3RhY2tzLnB1c2godW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3RhY2tzO1xuICAgIH1cbiBfZ2V0U3RhY2tDb3VudChpbmRleCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0U3RhY2tzKHVuZGVmaW5lZCwgaW5kZXgpLmxlbmd0aDtcbiAgICB9XG4gX2dldFN0YWNrSW5kZXgoZGF0YXNldEluZGV4LCBuYW1lLCBkYXRhSW5kZXgpIHtcbiAgICAgICAgY29uc3Qgc3RhY2tzID0gdGhpcy5fZ2V0U3RhY2tzKGRhdGFzZXRJbmRleCwgZGF0YUluZGV4KTtcbiAgICAgICAgY29uc3QgaW5kZXggPSBuYW1lICE9PSB1bmRlZmluZWQgPyBzdGFja3MuaW5kZXhPZihuYW1lKSA6IC0xO1xuICAgICAgICByZXR1cm4gaW5kZXggPT09IC0xID8gc3RhY2tzLmxlbmd0aCAtIDEgOiBpbmRleDtcbiAgICB9XG4gX2dldFJ1bGVyKCkge1xuICAgICAgICBjb25zdCBvcHRzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICAgICAgY29uc3QgaVNjYWxlID0gbWV0YS5pU2NhbGU7XG4gICAgICAgIGNvbnN0IHBpeGVscyA9IFtdO1xuICAgICAgICBsZXQgaSwgaWxlbjtcbiAgICAgICAgZm9yKGkgPSAwLCBpbGVuID0gbWV0YS5kYXRhLmxlbmd0aDsgaSA8IGlsZW47ICsraSl7XG4gICAgICAgICAgICBwaXhlbHMucHVzaChpU2NhbGUuZ2V0UGl4ZWxGb3JWYWx1ZSh0aGlzLmdldFBhcnNlZChpKVtpU2NhbGUuYXhpc10sIGkpKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBiYXJUaGlja25lc3MgPSBvcHRzLmJhclRoaWNrbmVzcztcbiAgICAgICAgY29uc3QgbWluID0gYmFyVGhpY2tuZXNzIHx8IGNvbXB1dGVNaW5TYW1wbGVTaXplKG1ldGEpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbWluLFxuICAgICAgICAgICAgcGl4ZWxzLFxuICAgICAgICAgICAgc3RhcnQ6IGlTY2FsZS5fc3RhcnRQaXhlbCxcbiAgICAgICAgICAgIGVuZDogaVNjYWxlLl9lbmRQaXhlbCxcbiAgICAgICAgICAgIHN0YWNrQ291bnQ6IHRoaXMuX2dldFN0YWNrQ291bnQoKSxcbiAgICAgICAgICAgIHNjYWxlOiBpU2NhbGUsXG4gICAgICAgICAgICBncm91cGVkOiBvcHRzLmdyb3VwZWQsXG4gICAgICAgICAgICByYXRpbzogYmFyVGhpY2tuZXNzID8gMSA6IG9wdHMuY2F0ZWdvcnlQZXJjZW50YWdlICogb3B0cy5iYXJQZXJjZW50YWdlXG4gICAgICAgIH07XG4gICAgfVxuIF9jYWxjdWxhdGVCYXJWYWx1ZVBpeGVscyhpbmRleCkge1xuICAgICAgICBjb25zdCB7IF9jYWNoZWRNZXRhOiB7IHZTY2FsZSAsIF9zdGFja2VkICwgaW5kZXg6IGRhdGFzZXRJbmRleCAgfSAsIG9wdGlvbnM6IHsgYmFzZTogYmFzZVZhbHVlICwgbWluQmFyTGVuZ3RoICB9ICB9ID0gdGhpcztcbiAgICAgICAgY29uc3QgYWN0dWFsQmFzZSA9IGJhc2VWYWx1ZSB8fCAwO1xuICAgICAgICBjb25zdCBwYXJzZWQgPSB0aGlzLmdldFBhcnNlZChpbmRleCk7XG4gICAgICAgIGNvbnN0IGN1c3RvbSA9IHBhcnNlZC5fY3VzdG9tO1xuICAgICAgICBjb25zdCBmbG9hdGluZyA9IGlzRmxvYXRCYXIoY3VzdG9tKTtcbiAgICAgICAgbGV0IHZhbHVlID0gcGFyc2VkW3ZTY2FsZS5heGlzXTtcbiAgICAgICAgbGV0IHN0YXJ0ID0gMDtcbiAgICAgICAgbGV0IGxlbmd0aCA9IF9zdGFja2VkID8gdGhpcy5hcHBseVN0YWNrKHZTY2FsZSwgcGFyc2VkLCBfc3RhY2tlZCkgOiB2YWx1ZTtcbiAgICAgICAgbGV0IGhlYWQsIHNpemU7XG4gICAgICAgIGlmIChsZW5ndGggIT09IHZhbHVlKSB7XG4gICAgICAgICAgICBzdGFydCA9IGxlbmd0aCAtIHZhbHVlO1xuICAgICAgICAgICAgbGVuZ3RoID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZsb2F0aW5nKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IGN1c3RvbS5iYXJTdGFydDtcbiAgICAgICAgICAgIGxlbmd0aCA9IGN1c3RvbS5iYXJFbmQgLSBjdXN0b20uYmFyU3RhcnQ7XG4gICAgICAgICAgICBpZiAodmFsdWUgIT09IDAgJiYgc2lnbih2YWx1ZSkgIT09IHNpZ24oY3VzdG9tLmJhckVuZCkpIHtcbiAgICAgICAgICAgICAgICBzdGFydCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdGFydCArPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzdGFydFZhbHVlID0gIWlzTnVsbE9yVW5kZWYoYmFzZVZhbHVlKSAmJiAhZmxvYXRpbmcgPyBiYXNlVmFsdWUgOiBzdGFydDtcbiAgICAgICAgbGV0IGJhc2UgPSB2U2NhbGUuZ2V0UGl4ZWxGb3JWYWx1ZShzdGFydFZhbHVlKTtcbiAgICAgICAgaWYgKHRoaXMuY2hhcnQuZ2V0RGF0YVZpc2liaWxpdHkoaW5kZXgpKSB7XG4gICAgICAgICAgICBoZWFkID0gdlNjYWxlLmdldFBpeGVsRm9yVmFsdWUoc3RhcnQgKyBsZW5ndGgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaGVhZCA9IGJhc2U7XG4gICAgICAgIH1cbiAgICAgICAgc2l6ZSA9IGhlYWQgLSBiYXNlO1xuICAgICAgICBpZiAoTWF0aC5hYnMoc2l6ZSkgPCBtaW5CYXJMZW5ndGgpIHtcbiAgICAgICAgICAgIHNpemUgPSBiYXJTaWduKHNpemUsIHZTY2FsZSwgYWN0dWFsQmFzZSkgKiBtaW5CYXJMZW5ndGg7XG4gICAgICAgICAgICBpZiAodmFsdWUgPT09IGFjdHVhbEJhc2UpIHtcbiAgICAgICAgICAgICAgICBiYXNlIC09IHNpemUgLyAyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qgc3RhcnRQaXhlbCA9IHZTY2FsZS5nZXRQaXhlbEZvckRlY2ltYWwoMCk7XG4gICAgICAgICAgICBjb25zdCBlbmRQaXhlbCA9IHZTY2FsZS5nZXRQaXhlbEZvckRlY2ltYWwoMSk7XG4gICAgICAgICAgICBjb25zdCBtaW4gPSBNYXRoLm1pbihzdGFydFBpeGVsLCBlbmRQaXhlbCk7XG4gICAgICAgICAgICBjb25zdCBtYXggPSBNYXRoLm1heChzdGFydFBpeGVsLCBlbmRQaXhlbCk7XG4gICAgICAgICAgICBiYXNlID0gTWF0aC5tYXgoTWF0aC5taW4oYmFzZSwgbWF4KSwgbWluKTtcbiAgICAgICAgICAgIGhlYWQgPSBiYXNlICsgc2l6ZTtcbiAgICAgICAgICAgIGlmIChfc3RhY2tlZCAmJiAhZmxvYXRpbmcpIHtcbiAgICAgICAgICAgICAgICBwYXJzZWQuX3N0YWNrc1t2U2NhbGUuYXhpc10uX3Zpc3VhbFZhbHVlc1tkYXRhc2V0SW5kZXhdID0gdlNjYWxlLmdldFZhbHVlRm9yUGl4ZWwoaGVhZCkgLSB2U2NhbGUuZ2V0VmFsdWVGb3JQaXhlbChiYXNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoYmFzZSA9PT0gdlNjYWxlLmdldFBpeGVsRm9yVmFsdWUoYWN0dWFsQmFzZSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGhhbGZHcmlkID0gc2lnbihzaXplKSAqIHZTY2FsZS5nZXRMaW5lV2lkdGhGb3JWYWx1ZShhY3R1YWxCYXNlKSAvIDI7XG4gICAgICAgICAgICBiYXNlICs9IGhhbGZHcmlkO1xuICAgICAgICAgICAgc2l6ZSAtPSBoYWxmR3JpZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc2l6ZSxcbiAgICAgICAgICAgIGJhc2UsXG4gICAgICAgICAgICBoZWFkLFxuICAgICAgICAgICAgY2VudGVyOiBoZWFkICsgc2l6ZSAvIDJcbiAgICAgICAgfTtcbiAgICB9XG4gX2NhbGN1bGF0ZUJhckluZGV4UGl4ZWxzKGluZGV4LCBydWxlcikge1xuICAgICAgICBjb25zdCBzY2FsZSA9IHJ1bGVyLnNjYWxlO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBjb25zdCBza2lwTnVsbCA9IG9wdGlvbnMuc2tpcE51bGw7XG4gICAgICAgIGNvbnN0IG1heEJhclRoaWNrbmVzcyA9IHZhbHVlT3JEZWZhdWx0KG9wdGlvbnMubWF4QmFyVGhpY2tuZXNzLCBJbmZpbml0eSk7XG4gICAgICAgIGxldCBjZW50ZXIsIHNpemU7XG4gICAgICAgIGlmIChydWxlci5ncm91cGVkKSB7XG4gICAgICAgICAgICBjb25zdCBzdGFja0NvdW50ID0gc2tpcE51bGwgPyB0aGlzLl9nZXRTdGFja0NvdW50KGluZGV4KSA6IHJ1bGVyLnN0YWNrQ291bnQ7XG4gICAgICAgICAgICBjb25zdCByYW5nZSA9IG9wdGlvbnMuYmFyVGhpY2tuZXNzID09PSAnZmxleCcgPyBjb21wdXRlRmxleENhdGVnb3J5VHJhaXRzKGluZGV4LCBydWxlciwgb3B0aW9ucywgc3RhY2tDb3VudCkgOiBjb21wdXRlRml0Q2F0ZWdvcnlUcmFpdHMoaW5kZXgsIHJ1bGVyLCBvcHRpb25zLCBzdGFja0NvdW50KTtcbiAgICAgICAgICAgIGNvbnN0IHN0YWNrSW5kZXggPSB0aGlzLl9nZXRTdGFja0luZGV4KHRoaXMuaW5kZXgsIHRoaXMuX2NhY2hlZE1ldGEuc3RhY2ssIHNraXBOdWxsID8gaW5kZXggOiB1bmRlZmluZWQpO1xuICAgICAgICAgICAgY2VudGVyID0gcmFuZ2Uuc3RhcnQgKyByYW5nZS5jaHVuayAqIHN0YWNrSW5kZXggKyByYW5nZS5jaHVuayAvIDI7XG4gICAgICAgICAgICBzaXplID0gTWF0aC5taW4obWF4QmFyVGhpY2tuZXNzLCByYW5nZS5jaHVuayAqIHJhbmdlLnJhdGlvKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNlbnRlciA9IHNjYWxlLmdldFBpeGVsRm9yVmFsdWUodGhpcy5nZXRQYXJzZWQoaW5kZXgpW3NjYWxlLmF4aXNdLCBpbmRleCk7XG4gICAgICAgICAgICBzaXplID0gTWF0aC5taW4obWF4QmFyVGhpY2tuZXNzLCBydWxlci5taW4gKiBydWxlci5yYXRpbyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGJhc2U6IGNlbnRlciAtIHNpemUgLyAyLFxuICAgICAgICAgICAgaGVhZDogY2VudGVyICsgc2l6ZSAvIDIsXG4gICAgICAgICAgICBjZW50ZXIsXG4gICAgICAgICAgICBzaXplXG4gICAgICAgIH07XG4gICAgfVxuICAgIGRyYXcoKSB7XG4gICAgICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgICAgICBjb25zdCB2U2NhbGUgPSBtZXRhLnZTY2FsZTtcbiAgICAgICAgY29uc3QgcmVjdHMgPSBtZXRhLmRhdGE7XG4gICAgICAgIGNvbnN0IGlsZW4gPSByZWN0cy5sZW5ndGg7XG4gICAgICAgIGxldCBpID0gMDtcbiAgICAgICAgZm9yKDsgaSA8IGlsZW47ICsraSl7XG4gICAgICAgICAgICBpZiAodGhpcy5nZXRQYXJzZWQoaSlbdlNjYWxlLmF4aXNdICE9PSBudWxsICYmICFyZWN0c1tpXS5oaWRkZW4pIHtcbiAgICAgICAgICAgICAgICByZWN0c1tpXS5kcmF3KHRoaXMuX2N0eCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIEJ1YmJsZUNvbnRyb2xsZXIgZXh0ZW5kcyBEYXRhc2V0Q29udHJvbGxlciB7XG4gICAgc3RhdGljIGlkID0gJ2J1YmJsZSc7XG4gc3RhdGljIGRlZmF1bHRzID0ge1xuICAgICAgICBkYXRhc2V0RWxlbWVudFR5cGU6IGZhbHNlLFxuICAgICAgICBkYXRhRWxlbWVudFR5cGU6ICdwb2ludCcsXG4gICAgICAgIGFuaW1hdGlvbnM6IHtcbiAgICAgICAgICAgIG51bWJlcnM6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiBbXG4gICAgICAgICAgICAgICAgICAgICd4JyxcbiAgICAgICAgICAgICAgICAgICAgJ3knLFxuICAgICAgICAgICAgICAgICAgICAnYm9yZGVyV2lkdGgnLFxuICAgICAgICAgICAgICAgICAgICAncmFkaXVzJ1xuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gc3RhdGljIG92ZXJyaWRlcyA9IHtcbiAgICAgICAgc2NhbGVzOiB7XG4gICAgICAgICAgICB4OiB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2xpbmVhcidcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB5OiB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2xpbmVhcidcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgaW5pdGlhbGl6ZSgpIHtcbiAgICAgICAgdGhpcy5lbmFibGVPcHRpb25TaGFyaW5nID0gdHJ1ZTtcbiAgICAgICAgc3VwZXIuaW5pdGlhbGl6ZSgpO1xuICAgIH1cbiBwYXJzZVByaW1pdGl2ZURhdGEobWV0YSwgZGF0YSwgc3RhcnQsIGNvdW50KSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZCA9IHN1cGVyLnBhcnNlUHJpbWl0aXZlRGF0YShtZXRhLCBkYXRhLCBzdGFydCwgY291bnQpO1xuICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgcGFyc2VkLmxlbmd0aDsgaSsrKXtcbiAgICAgICAgICAgIHBhcnNlZFtpXS5fY3VzdG9tID0gdGhpcy5yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKGkgKyBzdGFydCkucmFkaXVzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwYXJzZWQ7XG4gICAgfVxuIHBhcnNlQXJyYXlEYXRhKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCkge1xuICAgICAgICBjb25zdCBwYXJzZWQgPSBzdXBlci5wYXJzZUFycmF5RGF0YShtZXRhLCBkYXRhLCBzdGFydCwgY291bnQpO1xuICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgcGFyc2VkLmxlbmd0aDsgaSsrKXtcbiAgICAgICAgICAgIGNvbnN0IGl0ZW0gPSBkYXRhW3N0YXJ0ICsgaV07XG4gICAgICAgICAgICBwYXJzZWRbaV0uX2N1c3RvbSA9IHZhbHVlT3JEZWZhdWx0KGl0ZW1bMl0sIHRoaXMucmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucyhpICsgc3RhcnQpLnJhZGl1cyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBhcnNlZDtcbiAgICB9XG4gcGFyc2VPYmplY3REYXRhKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCkge1xuICAgICAgICBjb25zdCBwYXJzZWQgPSBzdXBlci5wYXJzZU9iamVjdERhdGEobWV0YSwgZGF0YSwgc3RhcnQsIGNvdW50KTtcbiAgICAgICAgZm9yKGxldCBpID0gMDsgaSA8IHBhcnNlZC5sZW5ndGg7IGkrKyl7XG4gICAgICAgICAgICBjb25zdCBpdGVtID0gZGF0YVtzdGFydCArIGldO1xuICAgICAgICAgICAgcGFyc2VkW2ldLl9jdXN0b20gPSB2YWx1ZU9yRGVmYXVsdChpdGVtICYmIGl0ZW0uciAmJiAraXRlbS5yLCB0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaSArIHN0YXJ0KS5yYWRpdXMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwYXJzZWQ7XG4gICAgfVxuIGdldE1heE92ZXJmbG93KCkge1xuICAgICAgICBjb25zdCBkYXRhID0gdGhpcy5fY2FjaGVkTWV0YS5kYXRhO1xuICAgICAgICBsZXQgbWF4ID0gMDtcbiAgICAgICAgZm9yKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IC0taSl7XG4gICAgICAgICAgICBtYXggPSBNYXRoLm1heChtYXgsIGRhdGFbaV0uc2l6ZSh0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaSkpIC8gMik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1heCA+IDAgJiYgbWF4O1xuICAgIH1cbiBnZXRMYWJlbEFuZFZhbHVlKGluZGV4KSB7XG4gICAgICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgICAgICBjb25zdCBsYWJlbHMgPSB0aGlzLmNoYXJ0LmRhdGEubGFiZWxzIHx8IFtdO1xuICAgICAgICBjb25zdCB7IHhTY2FsZSAsIHlTY2FsZSAgfSA9IG1ldGE7XG4gICAgICAgIGNvbnN0IHBhcnNlZCA9IHRoaXMuZ2V0UGFyc2VkKGluZGV4KTtcbiAgICAgICAgY29uc3QgeCA9IHhTY2FsZS5nZXRMYWJlbEZvclZhbHVlKHBhcnNlZC54KTtcbiAgICAgICAgY29uc3QgeSA9IHlTY2FsZS5nZXRMYWJlbEZvclZhbHVlKHBhcnNlZC55KTtcbiAgICAgICAgY29uc3QgciA9IHBhcnNlZC5fY3VzdG9tO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbGFiZWw6IGxhYmVsc1tpbmRleF0gfHwgJycsXG4gICAgICAgICAgICB2YWx1ZTogJygnICsgeCArICcsICcgKyB5ICsgKHIgPyAnLCAnICsgciA6ICcnKSArICcpJ1xuICAgICAgICB9O1xuICAgIH1cbiAgICB1cGRhdGUobW9kZSkge1xuICAgICAgICBjb25zdCBwb2ludHMgPSB0aGlzLl9jYWNoZWRNZXRhLmRhdGE7XG4gICAgICAgIHRoaXMudXBkYXRlRWxlbWVudHMocG9pbnRzLCAwLCBwb2ludHMubGVuZ3RoLCBtb2RlKTtcbiAgICB9XG4gICAgdXBkYXRlRWxlbWVudHMocG9pbnRzLCBzdGFydCwgY291bnQsIG1vZGUpIHtcbiAgICAgICAgY29uc3QgcmVzZXQgPSBtb2RlID09PSAncmVzZXQnO1xuICAgICAgICBjb25zdCB7IGlTY2FsZSAsIHZTY2FsZSAgfSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgICAgIGNvbnN0IHsgc2hhcmVkT3B0aW9ucyAsIGluY2x1ZGVPcHRpb25zICB9ID0gdGhpcy5fZ2V0U2hhcmVkT3B0aW9ucyhzdGFydCwgbW9kZSk7XG4gICAgICAgIGNvbnN0IGlBeGlzID0gaVNjYWxlLmF4aXM7XG4gICAgICAgIGNvbnN0IHZBeGlzID0gdlNjYWxlLmF4aXM7XG4gICAgICAgIGZvcihsZXQgaSA9IHN0YXJ0OyBpIDwgc3RhcnQgKyBjb3VudDsgaSsrKXtcbiAgICAgICAgICAgIGNvbnN0IHBvaW50ID0gcG9pbnRzW2ldO1xuICAgICAgICAgICAgY29uc3QgcGFyc2VkID0gIXJlc2V0ICYmIHRoaXMuZ2V0UGFyc2VkKGkpO1xuICAgICAgICAgICAgY29uc3QgcHJvcGVydGllcyA9IHt9O1xuICAgICAgICAgICAgY29uc3QgaVBpeGVsID0gcHJvcGVydGllc1tpQXhpc10gPSByZXNldCA/IGlTY2FsZS5nZXRQaXhlbEZvckRlY2ltYWwoMC41KSA6IGlTY2FsZS5nZXRQaXhlbEZvclZhbHVlKHBhcnNlZFtpQXhpc10pO1xuICAgICAgICAgICAgY29uc3QgdlBpeGVsID0gcHJvcGVydGllc1t2QXhpc10gPSByZXNldCA/IHZTY2FsZS5nZXRCYXNlUGl4ZWwoKSA6IHZTY2FsZS5nZXRQaXhlbEZvclZhbHVlKHBhcnNlZFt2QXhpc10pO1xuICAgICAgICAgICAgcHJvcGVydGllcy5za2lwID0gaXNOYU4oaVBpeGVsKSB8fCBpc05hTih2UGl4ZWwpO1xuICAgICAgICAgICAgaWYgKGluY2x1ZGVPcHRpb25zKSB7XG4gICAgICAgICAgICAgICAgcHJvcGVydGllcy5vcHRpb25zID0gc2hhcmVkT3B0aW9ucyB8fCB0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaSwgcG9pbnQuYWN0aXZlID8gJ2FjdGl2ZScgOiBtb2RlKTtcbiAgICAgICAgICAgICAgICBpZiAocmVzZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJvcGVydGllcy5vcHRpb25zLnJhZGl1cyA9IDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy51cGRhdGVFbGVtZW50KHBvaW50LCBpLCBwcm9wZXJ0aWVzLCBtb2RlKTtcbiAgICAgICAgfVxuICAgIH1cbiByZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKGluZGV4LCBtb2RlKSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZCA9IHRoaXMuZ2V0UGFyc2VkKGluZGV4KTtcbiAgICAgICAgbGV0IHZhbHVlcyA9IHN1cGVyLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaW5kZXgsIG1vZGUpO1xuICAgICAgICBpZiAodmFsdWVzLiRzaGFyZWQpIHtcbiAgICAgICAgICAgIHZhbHVlcyA9IE9iamVjdC5hc3NpZ24oe30sIHZhbHVlcywge1xuICAgICAgICAgICAgICAgICRzaGFyZWQ6IGZhbHNlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByYWRpdXMgPSB2YWx1ZXMucmFkaXVzO1xuICAgICAgICBpZiAobW9kZSAhPT0gJ2FjdGl2ZScpIHtcbiAgICAgICAgICAgIHZhbHVlcy5yYWRpdXMgPSAwO1xuICAgICAgICB9XG4gICAgICAgIHZhbHVlcy5yYWRpdXMgKz0gdmFsdWVPckRlZmF1bHQocGFyc2VkICYmIHBhcnNlZC5fY3VzdG9tLCByYWRpdXMpO1xuICAgICAgICByZXR1cm4gdmFsdWVzO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZ2V0UmF0aW9BbmRPZmZzZXQocm90YXRpb24sIGNpcmN1bWZlcmVuY2UsIGN1dG91dCkge1xuICAgIGxldCByYXRpb1ggPSAxO1xuICAgIGxldCByYXRpb1kgPSAxO1xuICAgIGxldCBvZmZzZXRYID0gMDtcbiAgICBsZXQgb2Zmc2V0WSA9IDA7XG4gICAgaWYgKGNpcmN1bWZlcmVuY2UgPCBUQVUpIHtcbiAgICAgICAgY29uc3Qgc3RhcnRBbmdsZSA9IHJvdGF0aW9uO1xuICAgICAgICBjb25zdCBlbmRBbmdsZSA9IHN0YXJ0QW5nbGUgKyBjaXJjdW1mZXJlbmNlO1xuICAgICAgICBjb25zdCBzdGFydFggPSBNYXRoLmNvcyhzdGFydEFuZ2xlKTtcbiAgICAgICAgY29uc3Qgc3RhcnRZID0gTWF0aC5zaW4oc3RhcnRBbmdsZSk7XG4gICAgICAgIGNvbnN0IGVuZFggPSBNYXRoLmNvcyhlbmRBbmdsZSk7XG4gICAgICAgIGNvbnN0IGVuZFkgPSBNYXRoLnNpbihlbmRBbmdsZSk7XG4gICAgICAgIGNvbnN0IGNhbGNNYXggPSAoYW5nbGUsIGEsIGIpPT5fYW5nbGVCZXR3ZWVuKGFuZ2xlLCBzdGFydEFuZ2xlLCBlbmRBbmdsZSwgdHJ1ZSkgPyAxIDogTWF0aC5tYXgoYSwgYSAqIGN1dG91dCwgYiwgYiAqIGN1dG91dCk7XG4gICAgICAgIGNvbnN0IGNhbGNNaW4gPSAoYW5nbGUsIGEsIGIpPT5fYW5nbGVCZXR3ZWVuKGFuZ2xlLCBzdGFydEFuZ2xlLCBlbmRBbmdsZSwgdHJ1ZSkgPyAtMSA6IE1hdGgubWluKGEsIGEgKiBjdXRvdXQsIGIsIGIgKiBjdXRvdXQpO1xuICAgICAgICBjb25zdCBtYXhYID0gY2FsY01heCgwLCBzdGFydFgsIGVuZFgpO1xuICAgICAgICBjb25zdCBtYXhZID0gY2FsY01heChIQUxGX1BJLCBzdGFydFksIGVuZFkpO1xuICAgICAgICBjb25zdCBtaW5YID0gY2FsY01pbihQSSwgc3RhcnRYLCBlbmRYKTtcbiAgICAgICAgY29uc3QgbWluWSA9IGNhbGNNaW4oUEkgKyBIQUxGX1BJLCBzdGFydFksIGVuZFkpO1xuICAgICAgICByYXRpb1ggPSAobWF4WCAtIG1pblgpIC8gMjtcbiAgICAgICAgcmF0aW9ZID0gKG1heFkgLSBtaW5ZKSAvIDI7XG4gICAgICAgIG9mZnNldFggPSAtKG1heFggKyBtaW5YKSAvIDI7XG4gICAgICAgIG9mZnNldFkgPSAtKG1heFkgKyBtaW5ZKSAvIDI7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHJhdGlvWCxcbiAgICAgICAgcmF0aW9ZLFxuICAgICAgICBvZmZzZXRYLFxuICAgICAgICBvZmZzZXRZXG4gICAgfTtcbn1cbmNsYXNzIERvdWdobnV0Q29udHJvbGxlciBleHRlbmRzIERhdGFzZXRDb250cm9sbGVyIHtcbiAgICBzdGF0aWMgaWQgPSAnZG91Z2hudXQnO1xuIHN0YXRpYyBkZWZhdWx0cyA9IHtcbiAgICAgICAgZGF0YXNldEVsZW1lbnRUeXBlOiBmYWxzZSxcbiAgICAgICAgZGF0YUVsZW1lbnRUeXBlOiAnYXJjJyxcbiAgICAgICAgYW5pbWF0aW9uOiB7XG4gICAgICAgICAgICBhbmltYXRlUm90YXRlOiB0cnVlLFxuICAgICAgICAgICAgYW5pbWF0ZVNjYWxlOiBmYWxzZVxuICAgICAgICB9LFxuICAgICAgICBhbmltYXRpb25zOiB7XG4gICAgICAgICAgICBudW1iZXJzOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICAgICAgICAgICAgcHJvcGVydGllczogW1xuICAgICAgICAgICAgICAgICAgICAnY2lyY3VtZmVyZW5jZScsXG4gICAgICAgICAgICAgICAgICAgICdlbmRBbmdsZScsXG4gICAgICAgICAgICAgICAgICAgICdpbm5lclJhZGl1cycsXG4gICAgICAgICAgICAgICAgICAgICdvdXRlclJhZGl1cycsXG4gICAgICAgICAgICAgICAgICAgICdzdGFydEFuZ2xlJyxcbiAgICAgICAgICAgICAgICAgICAgJ3gnLFxuICAgICAgICAgICAgICAgICAgICAneScsXG4gICAgICAgICAgICAgICAgICAgICdvZmZzZXQnLFxuICAgICAgICAgICAgICAgICAgICAnYm9yZGVyV2lkdGgnLFxuICAgICAgICAgICAgICAgICAgICAnc3BhY2luZydcbiAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGN1dG91dDogJzUwJScsXG4gICAgICAgIHJvdGF0aW9uOiAwLFxuICAgICAgICBjaXJjdW1mZXJlbmNlOiAzNjAsXG4gICAgICAgIHJhZGl1czogJzEwMCUnLFxuICAgICAgICBzcGFjaW5nOiAwLFxuICAgICAgICBpbmRleEF4aXM6ICdyJ1xuICAgIH07XG4gICAgc3RhdGljIGRlc2NyaXB0b3JzID0ge1xuICAgICAgICBfc2NyaXB0YWJsZTogKG5hbWUpPT5uYW1lICE9PSAnc3BhY2luZycsXG4gICAgICAgIF9pbmRleGFibGU6IChuYW1lKT0+bmFtZSAhPT0gJ3NwYWNpbmcnICYmICFuYW1lLnN0YXJ0c1dpdGgoJ2JvcmRlckRhc2gnKSAmJiAhbmFtZS5zdGFydHNXaXRoKCdob3ZlckJvcmRlckRhc2gnKVxuICAgIH07XG4gc3RhdGljIG92ZXJyaWRlcyA9IHtcbiAgICAgICAgYXNwZWN0UmF0aW86IDEsXG4gICAgICAgIHBsdWdpbnM6IHtcbiAgICAgICAgICAgIGxlZ2VuZDoge1xuICAgICAgICAgICAgICAgIGxhYmVsczoge1xuICAgICAgICAgICAgICAgICAgICBnZW5lcmF0ZUxhYmVscyAoY2hhcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBjaGFydC5kYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEubGFiZWxzLmxlbmd0aCAmJiBkYXRhLmRhdGFzZXRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgbGFiZWxzOiB7IHBvaW50U3R5bGUgLCBjb2xvciAgfSAgfSA9IGNoYXJ0LmxlZ2VuZC5vcHRpb25zO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmxhYmVscy5tYXAoKGxhYmVsLCBpKT0+e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRhID0gY2hhcnQuZ2V0RGF0YXNldE1ldGEoMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0eWxlID0gbWV0YS5jb250cm9sbGVyLmdldFN0eWxlKGkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dDogbGFiZWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsU3R5bGU6IHN0eWxlLmJhY2tncm91bmRDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZVN0eWxlOiBzdHlsZS5ib3JkZXJDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvbnRDb2xvcjogY29sb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IHN0eWxlLmJvcmRlcldpZHRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRTdHlsZTogcG9pbnRTdHlsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZGRlbjogIWNoYXJ0LmdldERhdGFWaXNpYmlsaXR5KGkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXg6IGlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgb25DbGljayAoZSwgbGVnZW5kSXRlbSwgbGVnZW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIGxlZ2VuZC5jaGFydC50b2dnbGVEYXRhVmlzaWJpbGl0eShsZWdlbmRJdGVtLmluZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgbGVnZW5kLmNoYXJ0LnVwZGF0ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgY29uc3RydWN0b3IoY2hhcnQsIGRhdGFzZXRJbmRleCl7XG4gICAgICAgIHN1cGVyKGNoYXJ0LCBkYXRhc2V0SW5kZXgpO1xuICAgICAgICB0aGlzLmVuYWJsZU9wdGlvblNoYXJpbmcgPSB0cnVlO1xuICAgICAgICB0aGlzLmlubmVyUmFkaXVzID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLm91dGVyUmFkaXVzID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLm9mZnNldFggPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMub2Zmc2V0WSA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgbGlua1NjYWxlcygpIHt9XG4gcGFyc2Uoc3RhcnQsIGNvdW50KSB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmdldERhdGFzZXQoKS5kYXRhO1xuICAgICAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICAgICAgaWYgKHRoaXMuX3BhcnNpbmcgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBtZXRhLl9wYXJzZWQgPSBkYXRhO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IGdldHRlciA9IChpKT0+K2RhdGFbaV07XG4gICAgICAgICAgICBpZiAoaXNPYmplY3QoZGF0YVtzdGFydF0pKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeyBrZXkgPSd2YWx1ZScgIH0gPSB0aGlzLl9wYXJzaW5nO1xuICAgICAgICAgICAgICAgIGdldHRlciA9IChpKT0+K3Jlc29sdmVPYmplY3RLZXkoZGF0YVtpXSwga2V5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBpLCBpbGVuO1xuICAgICAgICAgICAgZm9yKGkgPSBzdGFydCwgaWxlbiA9IHN0YXJ0ICsgY291bnQ7IGkgPCBpbGVuOyArK2kpe1xuICAgICAgICAgICAgICAgIG1ldGEuX3BhcnNlZFtpXSA9IGdldHRlcihpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiBfZ2V0Um90YXRpb24oKSB7XG4gICAgICAgIHJldHVybiB0b1JhZGlhbnModGhpcy5vcHRpb25zLnJvdGF0aW9uIC0gOTApO1xuICAgIH1cbiBfZ2V0Q2lyY3VtZmVyZW5jZSgpIHtcbiAgICAgICAgcmV0dXJuIHRvUmFkaWFucyh0aGlzLm9wdGlvbnMuY2lyY3VtZmVyZW5jZSk7XG4gICAgfVxuIF9nZXRSb3RhdGlvbkV4dGVudHMoKSB7XG4gICAgICAgIGxldCBtaW4gPSBUQVU7XG4gICAgICAgIGxldCBtYXggPSAtVEFVO1xuICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgdGhpcy5jaGFydC5kYXRhLmRhdGFzZXRzLmxlbmd0aDsgKytpKXtcbiAgICAgICAgICAgIGlmICh0aGlzLmNoYXJ0LmlzRGF0YXNldFZpc2libGUoaSkgJiYgdGhpcy5jaGFydC5nZXREYXRhc2V0TWV0YShpKS50eXBlID09PSB0aGlzLl90eXBlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29udHJvbGxlciA9IHRoaXMuY2hhcnQuZ2V0RGF0YXNldE1ldGEoaSkuY29udHJvbGxlcjtcbiAgICAgICAgICAgICAgICBjb25zdCByb3RhdGlvbiA9IGNvbnRyb2xsZXIuX2dldFJvdGF0aW9uKCk7XG4gICAgICAgICAgICAgICAgY29uc3QgY2lyY3VtZmVyZW5jZSA9IGNvbnRyb2xsZXIuX2dldENpcmN1bWZlcmVuY2UoKTtcbiAgICAgICAgICAgICAgICBtaW4gPSBNYXRoLm1pbihtaW4sIHJvdGF0aW9uKTtcbiAgICAgICAgICAgICAgICBtYXggPSBNYXRoLm1heChtYXgsIHJvdGF0aW9uICsgY2lyY3VtZmVyZW5jZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJvdGF0aW9uOiBtaW4sXG4gICAgICAgICAgICBjaXJjdW1mZXJlbmNlOiBtYXggLSBtaW5cbiAgICAgICAgfTtcbiAgICB9XG4gdXBkYXRlKG1vZGUpIHtcbiAgICAgICAgY29uc3QgY2hhcnQgPSB0aGlzLmNoYXJ0O1xuICAgICAgICBjb25zdCB7IGNoYXJ0QXJlYSAgfSA9IGNoYXJ0O1xuICAgICAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICAgICAgY29uc3QgYXJjcyA9IG1ldGEuZGF0YTtcbiAgICAgICAgY29uc3Qgc3BhY2luZyA9IHRoaXMuZ2V0TWF4Qm9yZGVyV2lkdGgoKSArIHRoaXMuZ2V0TWF4T2Zmc2V0KGFyY3MpICsgdGhpcy5vcHRpb25zLnNwYWNpbmc7XG4gICAgICAgIGNvbnN0IG1heFNpemUgPSBNYXRoLm1heCgoTWF0aC5taW4oY2hhcnRBcmVhLndpZHRoLCBjaGFydEFyZWEuaGVpZ2h0KSAtIHNwYWNpbmcpIC8gMiwgMCk7XG4gICAgICAgIGNvbnN0IGN1dG91dCA9IE1hdGgubWluKHRvUGVyY2VudGFnZSh0aGlzLm9wdGlvbnMuY3V0b3V0LCBtYXhTaXplKSwgMSk7XG4gICAgICAgIGNvbnN0IGNoYXJ0V2VpZ2h0ID0gdGhpcy5fZ2V0UmluZ1dlaWdodCh0aGlzLmluZGV4KTtcbiAgICAgICAgY29uc3QgeyBjaXJjdW1mZXJlbmNlICwgcm90YXRpb24gIH0gPSB0aGlzLl9nZXRSb3RhdGlvbkV4dGVudHMoKTtcbiAgICAgICAgY29uc3QgeyByYXRpb1ggLCByYXRpb1kgLCBvZmZzZXRYICwgb2Zmc2V0WSAgfSA9IGdldFJhdGlvQW5kT2Zmc2V0KHJvdGF0aW9uLCBjaXJjdW1mZXJlbmNlLCBjdXRvdXQpO1xuICAgICAgICBjb25zdCBtYXhXaWR0aCA9IChjaGFydEFyZWEud2lkdGggLSBzcGFjaW5nKSAvIHJhdGlvWDtcbiAgICAgICAgY29uc3QgbWF4SGVpZ2h0ID0gKGNoYXJ0QXJlYS5oZWlnaHQgLSBzcGFjaW5nKSAvIHJhdGlvWTtcbiAgICAgICAgY29uc3QgbWF4UmFkaXVzID0gTWF0aC5tYXgoTWF0aC5taW4obWF4V2lkdGgsIG1heEhlaWdodCkgLyAyLCAwKTtcbiAgICAgICAgY29uc3Qgb3V0ZXJSYWRpdXMgPSB0b0RpbWVuc2lvbih0aGlzLm9wdGlvbnMucmFkaXVzLCBtYXhSYWRpdXMpO1xuICAgICAgICBjb25zdCBpbm5lclJhZGl1cyA9IE1hdGgubWF4KG91dGVyUmFkaXVzICogY3V0b3V0LCAwKTtcbiAgICAgICAgY29uc3QgcmFkaXVzTGVuZ3RoID0gKG91dGVyUmFkaXVzIC0gaW5uZXJSYWRpdXMpIC8gdGhpcy5fZ2V0VmlzaWJsZURhdGFzZXRXZWlnaHRUb3RhbCgpO1xuICAgICAgICB0aGlzLm9mZnNldFggPSBvZmZzZXRYICogb3V0ZXJSYWRpdXM7XG4gICAgICAgIHRoaXMub2Zmc2V0WSA9IG9mZnNldFkgKiBvdXRlclJhZGl1cztcbiAgICAgICAgbWV0YS50b3RhbCA9IHRoaXMuY2FsY3VsYXRlVG90YWwoKTtcbiAgICAgICAgdGhpcy5vdXRlclJhZGl1cyA9IG91dGVyUmFkaXVzIC0gcmFkaXVzTGVuZ3RoICogdGhpcy5fZ2V0UmluZ1dlaWdodE9mZnNldCh0aGlzLmluZGV4KTtcbiAgICAgICAgdGhpcy5pbm5lclJhZGl1cyA9IE1hdGgubWF4KHRoaXMub3V0ZXJSYWRpdXMgLSByYWRpdXNMZW5ndGggKiBjaGFydFdlaWdodCwgMCk7XG4gICAgICAgIHRoaXMudXBkYXRlRWxlbWVudHMoYXJjcywgMCwgYXJjcy5sZW5ndGgsIG1vZGUpO1xuICAgIH1cbiBfY2lyY3VtZmVyZW5jZShpLCByZXNldCkge1xuICAgICAgICBjb25zdCBvcHRzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICAgICAgY29uc3QgY2lyY3VtZmVyZW5jZSA9IHRoaXMuX2dldENpcmN1bWZlcmVuY2UoKTtcbiAgICAgICAgaWYgKHJlc2V0ICYmIG9wdHMuYW5pbWF0aW9uLmFuaW1hdGVSb3RhdGUgfHwgIXRoaXMuY2hhcnQuZ2V0RGF0YVZpc2liaWxpdHkoaSkgfHwgbWV0YS5fcGFyc2VkW2ldID09PSBudWxsIHx8IG1ldGEuZGF0YVtpXS5oaWRkZW4pIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmNhbGN1bGF0ZUNpcmN1bWZlcmVuY2UobWV0YS5fcGFyc2VkW2ldICogY2lyY3VtZmVyZW5jZSAvIFRBVSk7XG4gICAgfVxuICAgIHVwZGF0ZUVsZW1lbnRzKGFyY3MsIHN0YXJ0LCBjb3VudCwgbW9kZSkge1xuICAgICAgICBjb25zdCByZXNldCA9IG1vZGUgPT09ICdyZXNldCc7XG4gICAgICAgIGNvbnN0IGNoYXJ0ID0gdGhpcy5jaGFydDtcbiAgICAgICAgY29uc3QgY2hhcnRBcmVhID0gY2hhcnQuY2hhcnRBcmVhO1xuICAgICAgICBjb25zdCBvcHRzID0gY2hhcnQub3B0aW9ucztcbiAgICAgICAgY29uc3QgYW5pbWF0aW9uT3B0cyA9IG9wdHMuYW5pbWF0aW9uO1xuICAgICAgICBjb25zdCBjZW50ZXJYID0gKGNoYXJ0QXJlYS5sZWZ0ICsgY2hhcnRBcmVhLnJpZ2h0KSAvIDI7XG4gICAgICAgIGNvbnN0IGNlbnRlclkgPSAoY2hhcnRBcmVhLnRvcCArIGNoYXJ0QXJlYS5ib3R0b20pIC8gMjtcbiAgICAgICAgY29uc3QgYW5pbWF0ZVNjYWxlID0gcmVzZXQgJiYgYW5pbWF0aW9uT3B0cy5hbmltYXRlU2NhbGU7XG4gICAgICAgIGNvbnN0IGlubmVyUmFkaXVzID0gYW5pbWF0ZVNjYWxlID8gMCA6IHRoaXMuaW5uZXJSYWRpdXM7XG4gICAgICAgIGNvbnN0IG91dGVyUmFkaXVzID0gYW5pbWF0ZVNjYWxlID8gMCA6IHRoaXMub3V0ZXJSYWRpdXM7XG4gICAgICAgIGNvbnN0IHsgc2hhcmVkT3B0aW9ucyAsIGluY2x1ZGVPcHRpb25zICB9ID0gdGhpcy5fZ2V0U2hhcmVkT3B0aW9ucyhzdGFydCwgbW9kZSk7XG4gICAgICAgIGxldCBzdGFydEFuZ2xlID0gdGhpcy5fZ2V0Um90YXRpb24oKTtcbiAgICAgICAgbGV0IGk7XG4gICAgICAgIGZvcihpID0gMDsgaSA8IHN0YXJ0OyArK2kpe1xuICAgICAgICAgICAgc3RhcnRBbmdsZSArPSB0aGlzLl9jaXJjdW1mZXJlbmNlKGksIHJlc2V0KTtcbiAgICAgICAgfVxuICAgICAgICBmb3IoaSA9IHN0YXJ0OyBpIDwgc3RhcnQgKyBjb3VudDsgKytpKXtcbiAgICAgICAgICAgIGNvbnN0IGNpcmN1bWZlcmVuY2UgPSB0aGlzLl9jaXJjdW1mZXJlbmNlKGksIHJlc2V0KTtcbiAgICAgICAgICAgIGNvbnN0IGFyYyA9IGFyY3NbaV07XG4gICAgICAgICAgICBjb25zdCBwcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgICAgIHg6IGNlbnRlclggKyB0aGlzLm9mZnNldFgsXG4gICAgICAgICAgICAgICAgeTogY2VudGVyWSArIHRoaXMub2Zmc2V0WSxcbiAgICAgICAgICAgICAgICBzdGFydEFuZ2xlLFxuICAgICAgICAgICAgICAgIGVuZEFuZ2xlOiBzdGFydEFuZ2xlICsgY2lyY3VtZmVyZW5jZSxcbiAgICAgICAgICAgICAgICBjaXJjdW1mZXJlbmNlLFxuICAgICAgICAgICAgICAgIG91dGVyUmFkaXVzLFxuICAgICAgICAgICAgICAgIGlubmVyUmFkaXVzXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGluY2x1ZGVPcHRpb25zKSB7XG4gICAgICAgICAgICAgICAgcHJvcGVydGllcy5vcHRpb25zID0gc2hhcmVkT3B0aW9ucyB8fCB0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaSwgYXJjLmFjdGl2ZSA/ICdhY3RpdmUnIDogbW9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdGFydEFuZ2xlICs9IGNpcmN1bWZlcmVuY2U7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUVsZW1lbnQoYXJjLCBpLCBwcm9wZXJ0aWVzLCBtb2RlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjYWxjdWxhdGVUb3RhbCgpIHtcbiAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgICAgIGNvbnN0IG1ldGFEYXRhID0gbWV0YS5kYXRhO1xuICAgICAgICBsZXQgdG90YWwgPSAwO1xuICAgICAgICBsZXQgaTtcbiAgICAgICAgZm9yKGkgPSAwOyBpIDwgbWV0YURhdGEubGVuZ3RoOyBpKyspe1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBtZXRhLl9wYXJzZWRbaV07XG4gICAgICAgICAgICBpZiAodmFsdWUgIT09IG51bGwgJiYgIWlzTmFOKHZhbHVlKSAmJiB0aGlzLmNoYXJ0LmdldERhdGFWaXNpYmlsaXR5KGkpICYmICFtZXRhRGF0YVtpXS5oaWRkZW4pIHtcbiAgICAgICAgICAgICAgICB0b3RhbCArPSBNYXRoLmFicyh2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRvdGFsO1xuICAgIH1cbiAgICBjYWxjdWxhdGVDaXJjdW1mZXJlbmNlKHZhbHVlKSB7XG4gICAgICAgIGNvbnN0IHRvdGFsID0gdGhpcy5fY2FjaGVkTWV0YS50b3RhbDtcbiAgICAgICAgaWYgKHRvdGFsID4gMCAmJiAhaXNOYU4odmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gVEFVICogKE1hdGguYWJzKHZhbHVlKSAvIHRvdGFsKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgZ2V0TGFiZWxBbmRWYWx1ZShpbmRleCkge1xuICAgICAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICAgICAgY29uc3QgY2hhcnQgPSB0aGlzLmNoYXJ0O1xuICAgICAgICBjb25zdCBsYWJlbHMgPSBjaGFydC5kYXRhLmxhYmVscyB8fCBbXTtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBmb3JtYXROdW1iZXIobWV0YS5fcGFyc2VkW2luZGV4XSwgY2hhcnQub3B0aW9ucy5sb2NhbGUpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbGFiZWw6IGxhYmVsc1tpbmRleF0gfHwgJycsXG4gICAgICAgICAgICB2YWx1ZVxuICAgICAgICB9O1xuICAgIH1cbiAgICBnZXRNYXhCb3JkZXJXaWR0aChhcmNzKSB7XG4gICAgICAgIGxldCBtYXggPSAwO1xuICAgICAgICBjb25zdCBjaGFydCA9IHRoaXMuY2hhcnQ7XG4gICAgICAgIGxldCBpLCBpbGVuLCBtZXRhLCBjb250cm9sbGVyLCBvcHRpb25zO1xuICAgICAgICBpZiAoIWFyY3MpIHtcbiAgICAgICAgICAgIGZvcihpID0gMCwgaWxlbiA9IGNoYXJ0LmRhdGEuZGF0YXNldHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKXtcbiAgICAgICAgICAgICAgICBpZiAoY2hhcnQuaXNEYXRhc2V0VmlzaWJsZShpKSkge1xuICAgICAgICAgICAgICAgICAgICBtZXRhID0gY2hhcnQuZ2V0RGF0YXNldE1ldGEoaSk7XG4gICAgICAgICAgICAgICAgICAgIGFyY3MgPSBtZXRhLmRhdGE7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIgPSBtZXRhLmNvbnRyb2xsZXI7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoIWFyY3MpIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIGZvcihpID0gMCwgaWxlbiA9IGFyY3MubGVuZ3RoOyBpIDwgaWxlbjsgKytpKXtcbiAgICAgICAgICAgIG9wdGlvbnMgPSBjb250cm9sbGVyLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaSk7XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5ib3JkZXJBbGlnbiAhPT0gJ2lubmVyJykge1xuICAgICAgICAgICAgICAgIG1heCA9IE1hdGgubWF4KG1heCwgb3B0aW9ucy5ib3JkZXJXaWR0aCB8fCAwLCBvcHRpb25zLmhvdmVyQm9yZGVyV2lkdGggfHwgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1heDtcbiAgICB9XG4gICAgZ2V0TWF4T2Zmc2V0KGFyY3MpIHtcbiAgICAgICAgbGV0IG1heCA9IDA7XG4gICAgICAgIGZvcihsZXQgaSA9IDAsIGlsZW4gPSBhcmNzLmxlbmd0aDsgaSA8IGlsZW47ICsraSl7XG4gICAgICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKGkpO1xuICAgICAgICAgICAgbWF4ID0gTWF0aC5tYXgobWF4LCBvcHRpb25zLm9mZnNldCB8fCAwLCBvcHRpb25zLmhvdmVyT2Zmc2V0IHx8IDApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtYXg7XG4gICAgfVxuIF9nZXRSaW5nV2VpZ2h0T2Zmc2V0KGRhdGFzZXRJbmRleCkge1xuICAgICAgICBsZXQgcmluZ1dlaWdodE9mZnNldCA9IDA7XG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBkYXRhc2V0SW5kZXg7ICsraSl7XG4gICAgICAgICAgICBpZiAodGhpcy5jaGFydC5pc0RhdGFzZXRWaXNpYmxlKGkpKSB7XG4gICAgICAgICAgICAgICAgcmluZ1dlaWdodE9mZnNldCArPSB0aGlzLl9nZXRSaW5nV2VpZ2h0KGkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByaW5nV2VpZ2h0T2Zmc2V0O1xuICAgIH1cbiBfZ2V0UmluZ1dlaWdodChkYXRhc2V0SW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIE1hdGgubWF4KHZhbHVlT3JEZWZhdWx0KHRoaXMuY2hhcnQuZGF0YS5kYXRhc2V0c1tkYXRhc2V0SW5kZXhdLndlaWdodCwgMSksIDApO1xuICAgIH1cbiBfZ2V0VmlzaWJsZURhdGFzZXRXZWlnaHRUb3RhbCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldFJpbmdXZWlnaHRPZmZzZXQodGhpcy5jaGFydC5kYXRhLmRhdGFzZXRzLmxlbmd0aCkgfHwgMTtcbiAgICB9XG59XG5cbmNsYXNzIExpbmVDb250cm9sbGVyIGV4dGVuZHMgRGF0YXNldENvbnRyb2xsZXIge1xuICAgIHN0YXRpYyBpZCA9ICdsaW5lJztcbiBzdGF0aWMgZGVmYXVsdHMgPSB7XG4gICAgICAgIGRhdGFzZXRFbGVtZW50VHlwZTogJ2xpbmUnLFxuICAgICAgICBkYXRhRWxlbWVudFR5cGU6ICdwb2ludCcsXG4gICAgICAgIHNob3dMaW5lOiB0cnVlLFxuICAgICAgICBzcGFuR2FwczogZmFsc2VcbiAgICB9O1xuIHN0YXRpYyBvdmVycmlkZXMgPSB7XG4gICAgICAgIHNjYWxlczoge1xuICAgICAgICAgICAgX2luZGV4Xzoge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdjYXRlZ29yeSdcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBfdmFsdWVfOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2xpbmVhcidcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgaW5pdGlhbGl6ZSgpIHtcbiAgICAgICAgdGhpcy5lbmFibGVPcHRpb25TaGFyaW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5zdXBwb3J0c0RlY2ltYXRpb24gPSB0cnVlO1xuICAgICAgICBzdXBlci5pbml0aWFsaXplKCk7XG4gICAgfVxuICAgIHVwZGF0ZShtb2RlKSB7XG4gICAgICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgICAgICBjb25zdCB7IGRhdGFzZXQ6IGxpbmUgLCBkYXRhOiBwb2ludHMgPSBbXSAsIF9kYXRhc2V0ICB9ID0gbWV0YTtcbiAgICAgICAgY29uc3QgYW5pbWF0aW9uc0Rpc2FibGVkID0gdGhpcy5jaGFydC5fYW5pbWF0aW9uc0Rpc2FibGVkO1xuICAgICAgICBsZXQgeyBzdGFydCAsIGNvdW50ICB9ID0gX2dldFN0YXJ0QW5kQ291bnRPZlZpc2libGVQb2ludHMobWV0YSwgcG9pbnRzLCBhbmltYXRpb25zRGlzYWJsZWQpO1xuICAgICAgICB0aGlzLl9kcmF3U3RhcnQgPSBzdGFydDtcbiAgICAgICAgdGhpcy5fZHJhd0NvdW50ID0gY291bnQ7XG4gICAgICAgIGlmIChfc2NhbGVSYW5nZXNDaGFuZ2VkKG1ldGEpKSB7XG4gICAgICAgICAgICBzdGFydCA9IDA7XG4gICAgICAgICAgICBjb3VudCA9IHBvaW50cy5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgbGluZS5fY2hhcnQgPSB0aGlzLmNoYXJ0O1xuICAgICAgICBsaW5lLl9kYXRhc2V0SW5kZXggPSB0aGlzLmluZGV4O1xuICAgICAgICBsaW5lLl9kZWNpbWF0ZWQgPSAhIV9kYXRhc2V0Ll9kZWNpbWF0ZWQ7XG4gICAgICAgIGxpbmUucG9pbnRzID0gcG9pbnRzO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5yZXNvbHZlRGF0YXNldEVsZW1lbnRPcHRpb25zKG1vZGUpO1xuICAgICAgICBpZiAoIXRoaXMub3B0aW9ucy5zaG93TGluZSkge1xuICAgICAgICAgICAgb3B0aW9ucy5ib3JkZXJXaWR0aCA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgb3B0aW9ucy5zZWdtZW50ID0gdGhpcy5vcHRpb25zLnNlZ21lbnQ7XG4gICAgICAgIHRoaXMudXBkYXRlRWxlbWVudChsaW5lLCB1bmRlZmluZWQsIHtcbiAgICAgICAgICAgIGFuaW1hdGVkOiAhYW5pbWF0aW9uc0Rpc2FibGVkLFxuICAgICAgICAgICAgb3B0aW9uc1xuICAgICAgICB9LCBtb2RlKTtcbiAgICAgICAgdGhpcy51cGRhdGVFbGVtZW50cyhwb2ludHMsIHN0YXJ0LCBjb3VudCwgbW9kZSk7XG4gICAgfVxuICAgIHVwZGF0ZUVsZW1lbnRzKHBvaW50cywgc3RhcnQsIGNvdW50LCBtb2RlKSB7XG4gICAgICAgIGNvbnN0IHJlc2V0ID0gbW9kZSA9PT0gJ3Jlc2V0JztcbiAgICAgICAgY29uc3QgeyBpU2NhbGUgLCB2U2NhbGUgLCBfc3RhY2tlZCAsIF9kYXRhc2V0ICB9ID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICAgICAgY29uc3QgeyBzaGFyZWRPcHRpb25zICwgaW5jbHVkZU9wdGlvbnMgIH0gPSB0aGlzLl9nZXRTaGFyZWRPcHRpb25zKHN0YXJ0LCBtb2RlKTtcbiAgICAgICAgY29uc3QgaUF4aXMgPSBpU2NhbGUuYXhpcztcbiAgICAgICAgY29uc3QgdkF4aXMgPSB2U2NhbGUuYXhpcztcbiAgICAgICAgY29uc3QgeyBzcGFuR2FwcyAsIHNlZ21lbnQgIH0gPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGNvbnN0IG1heEdhcExlbmd0aCA9IGlzTnVtYmVyKHNwYW5HYXBzKSA/IHNwYW5HYXBzIDogTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO1xuICAgICAgICBjb25zdCBkaXJlY3RVcGRhdGUgPSB0aGlzLmNoYXJ0Ll9hbmltYXRpb25zRGlzYWJsZWQgfHwgcmVzZXQgfHwgbW9kZSA9PT0gJ25vbmUnO1xuICAgICAgICBjb25zdCBlbmQgPSBzdGFydCArIGNvdW50O1xuICAgICAgICBjb25zdCBwb2ludHNDb3VudCA9IHBvaW50cy5sZW5ndGg7XG4gICAgICAgIGxldCBwcmV2UGFyc2VkID0gc3RhcnQgPiAwICYmIHRoaXMuZ2V0UGFyc2VkKHN0YXJ0IC0gMSk7XG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBwb2ludHNDb3VudDsgKytpKXtcbiAgICAgICAgICAgIGNvbnN0IHBvaW50ID0gcG9pbnRzW2ldO1xuICAgICAgICAgICAgY29uc3QgcHJvcGVydGllcyA9IGRpcmVjdFVwZGF0ZSA/IHBvaW50IDoge307XG4gICAgICAgICAgICBpZiAoaSA8IHN0YXJ0IHx8IGkgPj0gZW5kKSB7XG4gICAgICAgICAgICAgICAgcHJvcGVydGllcy5za2lwID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IHRoaXMuZ2V0UGFyc2VkKGkpO1xuICAgICAgICAgICAgY29uc3QgbnVsbERhdGEgPSBpc051bGxPclVuZGVmKHBhcnNlZFt2QXhpc10pO1xuICAgICAgICAgICAgY29uc3QgaVBpeGVsID0gcHJvcGVydGllc1tpQXhpc10gPSBpU2NhbGUuZ2V0UGl4ZWxGb3JWYWx1ZShwYXJzZWRbaUF4aXNdLCBpKTtcbiAgICAgICAgICAgIGNvbnN0IHZQaXhlbCA9IHByb3BlcnRpZXNbdkF4aXNdID0gcmVzZXQgfHwgbnVsbERhdGEgPyB2U2NhbGUuZ2V0QmFzZVBpeGVsKCkgOiB2U2NhbGUuZ2V0UGl4ZWxGb3JWYWx1ZShfc3RhY2tlZCA/IHRoaXMuYXBwbHlTdGFjayh2U2NhbGUsIHBhcnNlZCwgX3N0YWNrZWQpIDogcGFyc2VkW3ZBeGlzXSwgaSk7XG4gICAgICAgICAgICBwcm9wZXJ0aWVzLnNraXAgPSBpc05hTihpUGl4ZWwpIHx8IGlzTmFOKHZQaXhlbCkgfHwgbnVsbERhdGE7XG4gICAgICAgICAgICBwcm9wZXJ0aWVzLnN0b3AgPSBpID4gMCAmJiBNYXRoLmFicyhwYXJzZWRbaUF4aXNdIC0gcHJldlBhcnNlZFtpQXhpc10pID4gbWF4R2FwTGVuZ3RoO1xuICAgICAgICAgICAgaWYgKHNlZ21lbnQpIHtcbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzLnBhcnNlZCA9IHBhcnNlZDtcbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzLnJhdyA9IF9kYXRhc2V0LmRhdGFbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaW5jbHVkZU9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzLm9wdGlvbnMgPSBzaGFyZWRPcHRpb25zIHx8IHRoaXMucmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucyhpLCBwb2ludC5hY3RpdmUgPyAnYWN0aXZlJyA6IG1vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFkaXJlY3RVcGRhdGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUVsZW1lbnQocG9pbnQsIGksIHByb3BlcnRpZXMsIG1vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcHJldlBhcnNlZCA9IHBhcnNlZDtcbiAgICAgICAgfVxuICAgIH1cbiBnZXRNYXhPdmVyZmxvdygpIHtcbiAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgICAgIGNvbnN0IGRhdGFzZXQgPSBtZXRhLmRhdGFzZXQ7XG4gICAgICAgIGNvbnN0IGJvcmRlciA9IGRhdGFzZXQub3B0aW9ucyAmJiBkYXRhc2V0Lm9wdGlvbnMuYm9yZGVyV2lkdGggfHwgMDtcbiAgICAgICAgY29uc3QgZGF0YSA9IG1ldGEuZGF0YSB8fCBbXTtcbiAgICAgICAgaWYgKCFkYXRhLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGJvcmRlcjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBmaXJzdFBvaW50ID0gZGF0YVswXS5zaXplKHRoaXMucmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucygwKSk7XG4gICAgICAgIGNvbnN0IGxhc3RQb2ludCA9IGRhdGFbZGF0YS5sZW5ndGggLSAxXS5zaXplKHRoaXMucmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucyhkYXRhLmxlbmd0aCAtIDEpKTtcbiAgICAgICAgcmV0dXJuIE1hdGgubWF4KGJvcmRlciwgZmlyc3RQb2ludCwgbGFzdFBvaW50KSAvIDI7XG4gICAgfVxuICAgIGRyYXcoKSB7XG4gICAgICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgICAgICBtZXRhLmRhdGFzZXQudXBkYXRlQ29udHJvbFBvaW50cyh0aGlzLmNoYXJ0LmNoYXJ0QXJlYSwgbWV0YS5pU2NhbGUuYXhpcyk7XG4gICAgICAgIHN1cGVyLmRyYXcoKTtcbiAgICB9XG59XG5cbmNsYXNzIFBvbGFyQXJlYUNvbnRyb2xsZXIgZXh0ZW5kcyBEYXRhc2V0Q29udHJvbGxlciB7XG4gICAgc3RhdGljIGlkID0gJ3BvbGFyQXJlYSc7XG4gc3RhdGljIGRlZmF1bHRzID0ge1xuICAgICAgICBkYXRhRWxlbWVudFR5cGU6ICdhcmMnLFxuICAgICAgICBhbmltYXRpb246IHtcbiAgICAgICAgICAgIGFuaW1hdGVSb3RhdGU6IHRydWUsXG4gICAgICAgICAgICBhbmltYXRlU2NhbGU6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgYW5pbWF0aW9uczoge1xuICAgICAgICAgICAgbnVtYmVyczoge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgICAgICAgICAgIHByb3BlcnRpZXM6IFtcbiAgICAgICAgICAgICAgICAgICAgJ3gnLFxuICAgICAgICAgICAgICAgICAgICAneScsXG4gICAgICAgICAgICAgICAgICAgICdzdGFydEFuZ2xlJyxcbiAgICAgICAgICAgICAgICAgICAgJ2VuZEFuZ2xlJyxcbiAgICAgICAgICAgICAgICAgICAgJ2lubmVyUmFkaXVzJyxcbiAgICAgICAgICAgICAgICAgICAgJ291dGVyUmFkaXVzJ1xuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgaW5kZXhBeGlzOiAncicsXG4gICAgICAgIHN0YXJ0QW5nbGU6IDBcbiAgICB9O1xuIHN0YXRpYyBvdmVycmlkZXMgPSB7XG4gICAgICAgIGFzcGVjdFJhdGlvOiAxLFxuICAgICAgICBwbHVnaW5zOiB7XG4gICAgICAgICAgICBsZWdlbmQ6IHtcbiAgICAgICAgICAgICAgICBsYWJlbHM6IHtcbiAgICAgICAgICAgICAgICAgICAgZ2VuZXJhdGVMYWJlbHMgKGNoYXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gY2hhcnQuZGF0YTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkYXRhLmxhYmVscy5sZW5ndGggJiYgZGF0YS5kYXRhc2V0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IGxhYmVsczogeyBwb2ludFN0eWxlICwgY29sb3IgIH0gIH0gPSBjaGFydC5sZWdlbmQub3B0aW9ucztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5sYWJlbHMubWFwKChsYWJlbCwgaSk9PntcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0YSA9IGNoYXJ0LmdldERhdGFzZXRNZXRhKDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHlsZSA9IG1ldGEuY29udHJvbGxlci5nZXRTdHlsZShpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQ6IGxhYmVsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbFN0eWxlOiBzdHlsZS5iYWNrZ3JvdW5kQ29sb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2VTdHlsZTogc3R5bGUuYm9yZGVyQ29sb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb250Q29sb3I6IGNvbG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiBzdHlsZS5ib3JkZXJXaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvaW50U3R5bGU6IHBvaW50U3R5bGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRkZW46ICFjaGFydC5nZXREYXRhVmlzaWJpbGl0eShpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4OiBpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIG9uQ2xpY2sgKGUsIGxlZ2VuZEl0ZW0sIGxlZ2VuZCkge1xuICAgICAgICAgICAgICAgICAgICBsZWdlbmQuY2hhcnQudG9nZ2xlRGF0YVZpc2liaWxpdHkobGVnZW5kSXRlbS5pbmRleCk7XG4gICAgICAgICAgICAgICAgICAgIGxlZ2VuZC5jaGFydC51cGRhdGUoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHNjYWxlczoge1xuICAgICAgICAgICAgcjoge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdyYWRpYWxMaW5lYXInLFxuICAgICAgICAgICAgICAgIGFuZ2xlTGluZXM6IHtcbiAgICAgICAgICAgICAgICAgICAgZGlzcGxheTogZmFsc2VcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGJlZ2luQXRaZXJvOiB0cnVlLFxuICAgICAgICAgICAgICAgIGdyaWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgY2lyY3VsYXI6IHRydWVcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHBvaW50TGFiZWxzOiB7XG4gICAgICAgICAgICAgICAgICAgIGRpc3BsYXk6IGZhbHNlXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzdGFydEFuZ2xlOiAwXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIGNvbnN0cnVjdG9yKGNoYXJ0LCBkYXRhc2V0SW5kZXgpe1xuICAgICAgICBzdXBlcihjaGFydCwgZGF0YXNldEluZGV4KTtcbiAgICAgICAgdGhpcy5pbm5lclJhZGl1cyA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5vdXRlclJhZGl1cyA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgZ2V0TGFiZWxBbmRWYWx1ZShpbmRleCkge1xuICAgICAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICAgICAgY29uc3QgY2hhcnQgPSB0aGlzLmNoYXJ0O1xuICAgICAgICBjb25zdCBsYWJlbHMgPSBjaGFydC5kYXRhLmxhYmVscyB8fCBbXTtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBmb3JtYXROdW1iZXIobWV0YS5fcGFyc2VkW2luZGV4XS5yLCBjaGFydC5vcHRpb25zLmxvY2FsZSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBsYWJlbDogbGFiZWxzW2luZGV4XSB8fCAnJyxcbiAgICAgICAgICAgIHZhbHVlXG4gICAgICAgIH07XG4gICAgfVxuICAgIHBhcnNlT2JqZWN0RGF0YShtZXRhLCBkYXRhLCBzdGFydCwgY291bnQpIHtcbiAgICAgICAgcmV0dXJuIF9wYXJzZU9iamVjdERhdGFSYWRpYWxTY2FsZS5iaW5kKHRoaXMpKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCk7XG4gICAgfVxuICAgIHVwZGF0ZShtb2RlKSB7XG4gICAgICAgIGNvbnN0IGFyY3MgPSB0aGlzLl9jYWNoZWRNZXRhLmRhdGE7XG4gICAgICAgIHRoaXMuX3VwZGF0ZVJhZGl1cygpO1xuICAgICAgICB0aGlzLnVwZGF0ZUVsZW1lbnRzKGFyY3MsIDAsIGFyY3MubGVuZ3RoLCBtb2RlKTtcbiAgICB9XG4gZ2V0TWluTWF4KCkge1xuICAgICAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICAgICAgY29uc3QgcmFuZ2UgPSB7XG4gICAgICAgICAgICBtaW46IE51bWJlci5QT1NJVElWRV9JTkZJTklUWSxcbiAgICAgICAgICAgIG1heDogTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZXG4gICAgICAgIH07XG4gICAgICAgIG1ldGEuZGF0YS5mb3JFYWNoKChlbGVtZW50LCBpbmRleCk9PntcbiAgICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IHRoaXMuZ2V0UGFyc2VkKGluZGV4KS5yO1xuICAgICAgICAgICAgaWYgKCFpc05hTihwYXJzZWQpICYmIHRoaXMuY2hhcnQuZ2V0RGF0YVZpc2liaWxpdHkoaW5kZXgpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHBhcnNlZCA8IHJhbmdlLm1pbikge1xuICAgICAgICAgICAgICAgICAgICByYW5nZS5taW4gPSBwYXJzZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChwYXJzZWQgPiByYW5nZS5tYXgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmFuZ2UubWF4ID0gcGFyc2VkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiByYW5nZTtcbiAgICB9XG4gX3VwZGF0ZVJhZGl1cygpIHtcbiAgICAgICAgY29uc3QgY2hhcnQgPSB0aGlzLmNoYXJ0O1xuICAgICAgICBjb25zdCBjaGFydEFyZWEgPSBjaGFydC5jaGFydEFyZWE7XG4gICAgICAgIGNvbnN0IG9wdHMgPSBjaGFydC5vcHRpb25zO1xuICAgICAgICBjb25zdCBtaW5TaXplID0gTWF0aC5taW4oY2hhcnRBcmVhLnJpZ2h0IC0gY2hhcnRBcmVhLmxlZnQsIGNoYXJ0QXJlYS5ib3R0b20gLSBjaGFydEFyZWEudG9wKTtcbiAgICAgICAgY29uc3Qgb3V0ZXJSYWRpdXMgPSBNYXRoLm1heChtaW5TaXplIC8gMiwgMCk7XG4gICAgICAgIGNvbnN0IGlubmVyUmFkaXVzID0gTWF0aC5tYXgob3B0cy5jdXRvdXRQZXJjZW50YWdlID8gb3V0ZXJSYWRpdXMgLyAxMDAgKiBvcHRzLmN1dG91dFBlcmNlbnRhZ2UgOiAxLCAwKTtcbiAgICAgICAgY29uc3QgcmFkaXVzTGVuZ3RoID0gKG91dGVyUmFkaXVzIC0gaW5uZXJSYWRpdXMpIC8gY2hhcnQuZ2V0VmlzaWJsZURhdGFzZXRDb3VudCgpO1xuICAgICAgICB0aGlzLm91dGVyUmFkaXVzID0gb3V0ZXJSYWRpdXMgLSByYWRpdXNMZW5ndGggKiB0aGlzLmluZGV4O1xuICAgICAgICB0aGlzLmlubmVyUmFkaXVzID0gdGhpcy5vdXRlclJhZGl1cyAtIHJhZGl1c0xlbmd0aDtcbiAgICB9XG4gICAgdXBkYXRlRWxlbWVudHMoYXJjcywgc3RhcnQsIGNvdW50LCBtb2RlKSB7XG4gICAgICAgIGNvbnN0IHJlc2V0ID0gbW9kZSA9PT0gJ3Jlc2V0JztcbiAgICAgICAgY29uc3QgY2hhcnQgPSB0aGlzLmNoYXJ0O1xuICAgICAgICBjb25zdCBvcHRzID0gY2hhcnQub3B0aW9ucztcbiAgICAgICAgY29uc3QgYW5pbWF0aW9uT3B0cyA9IG9wdHMuYW5pbWF0aW9uO1xuICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX2NhY2hlZE1ldGEuclNjYWxlO1xuICAgICAgICBjb25zdCBjZW50ZXJYID0gc2NhbGUueENlbnRlcjtcbiAgICAgICAgY29uc3QgY2VudGVyWSA9IHNjYWxlLnlDZW50ZXI7XG4gICAgICAgIGNvbnN0IGRhdGFzZXRTdGFydEFuZ2xlID0gc2NhbGUuZ2V0SW5kZXhBbmdsZSgwKSAtIDAuNSAqIFBJO1xuICAgICAgICBsZXQgYW5nbGUgPSBkYXRhc2V0U3RhcnRBbmdsZTtcbiAgICAgICAgbGV0IGk7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRBbmdsZSA9IDM2MCAvIHRoaXMuY291bnRWaXNpYmxlRWxlbWVudHMoKTtcbiAgICAgICAgZm9yKGkgPSAwOyBpIDwgc3RhcnQ7ICsraSl7XG4gICAgICAgICAgICBhbmdsZSArPSB0aGlzLl9jb21wdXRlQW5nbGUoaSwgbW9kZSwgZGVmYXVsdEFuZ2xlKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IoaSA9IHN0YXJ0OyBpIDwgc3RhcnQgKyBjb3VudDsgaSsrKXtcbiAgICAgICAgICAgIGNvbnN0IGFyYyA9IGFyY3NbaV07XG4gICAgICAgICAgICBsZXQgc3RhcnRBbmdsZSA9IGFuZ2xlO1xuICAgICAgICAgICAgbGV0IGVuZEFuZ2xlID0gYW5nbGUgKyB0aGlzLl9jb21wdXRlQW5nbGUoaSwgbW9kZSwgZGVmYXVsdEFuZ2xlKTtcbiAgICAgICAgICAgIGxldCBvdXRlclJhZGl1cyA9IGNoYXJ0LmdldERhdGFWaXNpYmlsaXR5KGkpID8gc2NhbGUuZ2V0RGlzdGFuY2VGcm9tQ2VudGVyRm9yVmFsdWUodGhpcy5nZXRQYXJzZWQoaSkucikgOiAwO1xuICAgICAgICAgICAgYW5nbGUgPSBlbmRBbmdsZTtcbiAgICAgICAgICAgIGlmIChyZXNldCkge1xuICAgICAgICAgICAgICAgIGlmIChhbmltYXRpb25PcHRzLmFuaW1hdGVTY2FsZSkge1xuICAgICAgICAgICAgICAgICAgICBvdXRlclJhZGl1cyA9IDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChhbmltYXRpb25PcHRzLmFuaW1hdGVSb3RhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRBbmdsZSA9IGVuZEFuZ2xlID0gZGF0YXNldFN0YXJ0QW5nbGU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgcHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgICAgICB4OiBjZW50ZXJYLFxuICAgICAgICAgICAgICAgIHk6IGNlbnRlclksXG4gICAgICAgICAgICAgICAgaW5uZXJSYWRpdXM6IDAsXG4gICAgICAgICAgICAgICAgb3V0ZXJSYWRpdXMsXG4gICAgICAgICAgICAgICAgc3RhcnRBbmdsZSxcbiAgICAgICAgICAgICAgICBlbmRBbmdsZSxcbiAgICAgICAgICAgICAgICBvcHRpb25zOiB0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaSwgYXJjLmFjdGl2ZSA/ICdhY3RpdmUnIDogbW9kZSlcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUVsZW1lbnQoYXJjLCBpLCBwcm9wZXJ0aWVzLCBtb2RlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb3VudFZpc2libGVFbGVtZW50cygpIHtcbiAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgICAgIGxldCBjb3VudCA9IDA7XG4gICAgICAgIG1ldGEuZGF0YS5mb3JFYWNoKChlbGVtZW50LCBpbmRleCk9PntcbiAgICAgICAgICAgIGlmICghaXNOYU4odGhpcy5nZXRQYXJzZWQoaW5kZXgpLnIpICYmIHRoaXMuY2hhcnQuZ2V0RGF0YVZpc2liaWxpdHkoaW5kZXgpKSB7XG4gICAgICAgICAgICAgICAgY291bnQrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBjb3VudDtcbiAgICB9XG4gX2NvbXB1dGVBbmdsZShpbmRleCwgbW9kZSwgZGVmYXVsdEFuZ2xlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNoYXJ0LmdldERhdGFWaXNpYmlsaXR5KGluZGV4KSA/IHRvUmFkaWFucyh0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaW5kZXgsIG1vZGUpLmFuZ2xlIHx8IGRlZmF1bHRBbmdsZSkgOiAwO1xuICAgIH1cbn1cblxuY2xhc3MgUGllQ29udHJvbGxlciBleHRlbmRzIERvdWdobnV0Q29udHJvbGxlciB7XG4gICAgc3RhdGljIGlkID0gJ3BpZSc7XG4gc3RhdGljIGRlZmF1bHRzID0ge1xuICAgICAgICBjdXRvdXQ6IDAsXG4gICAgICAgIHJvdGF0aW9uOiAwLFxuICAgICAgICBjaXJjdW1mZXJlbmNlOiAzNjAsXG4gICAgICAgIHJhZGl1czogJzEwMCUnXG4gICAgfTtcbn1cblxuY2xhc3MgUmFkYXJDb250cm9sbGVyIGV4dGVuZHMgRGF0YXNldENvbnRyb2xsZXIge1xuICAgIHN0YXRpYyBpZCA9ICdyYWRhcic7XG4gc3RhdGljIGRlZmF1bHRzID0ge1xuICAgICAgICBkYXRhc2V0RWxlbWVudFR5cGU6ICdsaW5lJyxcbiAgICAgICAgZGF0YUVsZW1lbnRUeXBlOiAncG9pbnQnLFxuICAgICAgICBpbmRleEF4aXM6ICdyJyxcbiAgICAgICAgc2hvd0xpbmU6IHRydWUsXG4gICAgICAgIGVsZW1lbnRzOiB7XG4gICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgZmlsbDogJ3N0YXJ0J1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiBzdGF0aWMgb3ZlcnJpZGVzID0ge1xuICAgICAgICBhc3BlY3RSYXRpbzogMSxcbiAgICAgICAgc2NhbGVzOiB7XG4gICAgICAgICAgICByOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ3JhZGlhbExpbmVhcidcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gZ2V0TGFiZWxBbmRWYWx1ZShpbmRleCkge1xuICAgICAgICBjb25zdCB2U2NhbGUgPSB0aGlzLl9jYWNoZWRNZXRhLnZTY2FsZTtcbiAgICAgICAgY29uc3QgcGFyc2VkID0gdGhpcy5nZXRQYXJzZWQoaW5kZXgpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbGFiZWw6IHZTY2FsZS5nZXRMYWJlbHMoKVtpbmRleF0sXG4gICAgICAgICAgICB2YWx1ZTogJycgKyB2U2NhbGUuZ2V0TGFiZWxGb3JWYWx1ZShwYXJzZWRbdlNjYWxlLmF4aXNdKVxuICAgICAgICB9O1xuICAgIH1cbiAgICBwYXJzZU9iamVjdERhdGEobWV0YSwgZGF0YSwgc3RhcnQsIGNvdW50KSB7XG4gICAgICAgIHJldHVybiBfcGFyc2VPYmplY3REYXRhUmFkaWFsU2NhbGUuYmluZCh0aGlzKShtZXRhLCBkYXRhLCBzdGFydCwgY291bnQpO1xuICAgIH1cbiAgICB1cGRhdGUobW9kZSkge1xuICAgICAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICAgICAgY29uc3QgbGluZSA9IG1ldGEuZGF0YXNldDtcbiAgICAgICAgY29uc3QgcG9pbnRzID0gbWV0YS5kYXRhIHx8IFtdO1xuICAgICAgICBjb25zdCBsYWJlbHMgPSBtZXRhLmlTY2FsZS5nZXRMYWJlbHMoKTtcbiAgICAgICAgbGluZS5wb2ludHMgPSBwb2ludHM7XG4gICAgICAgIGlmIChtb2RlICE9PSAncmVzaXplJykge1xuICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMucmVzb2x2ZURhdGFzZXRFbGVtZW50T3B0aW9ucyhtb2RlKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5vcHRpb25zLnNob3dMaW5lKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucy5ib3JkZXJXaWR0aCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBwcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgICAgIF9sb29wOiB0cnVlLFxuICAgICAgICAgICAgICAgIF9mdWxsTG9vcDogbGFiZWxzLmxlbmd0aCA9PT0gcG9pbnRzLmxlbmd0aCxcbiAgICAgICAgICAgICAgICBvcHRpb25zXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdGhpcy51cGRhdGVFbGVtZW50KGxpbmUsIHVuZGVmaW5lZCwgcHJvcGVydGllcywgbW9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy51cGRhdGVFbGVtZW50cyhwb2ludHMsIDAsIHBvaW50cy5sZW5ndGgsIG1vZGUpO1xuICAgIH1cbiAgICB1cGRhdGVFbGVtZW50cyhwb2ludHMsIHN0YXJ0LCBjb3VudCwgbW9kZSkge1xuICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX2NhY2hlZE1ldGEuclNjYWxlO1xuICAgICAgICBjb25zdCByZXNldCA9IG1vZGUgPT09ICdyZXNldCc7XG4gICAgICAgIGZvcihsZXQgaSA9IHN0YXJ0OyBpIDwgc3RhcnQgKyBjb3VudDsgaSsrKXtcbiAgICAgICAgICAgIGNvbnN0IHBvaW50ID0gcG9pbnRzW2ldO1xuICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMucmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucyhpLCBwb2ludC5hY3RpdmUgPyAnYWN0aXZlJyA6IG1vZGUpO1xuICAgICAgICAgICAgY29uc3QgcG9pbnRQb3NpdGlvbiA9IHNjYWxlLmdldFBvaW50UG9zaXRpb25Gb3JWYWx1ZShpLCB0aGlzLmdldFBhcnNlZChpKS5yKTtcbiAgICAgICAgICAgIGNvbnN0IHggPSByZXNldCA/IHNjYWxlLnhDZW50ZXIgOiBwb2ludFBvc2l0aW9uLng7XG4gICAgICAgICAgICBjb25zdCB5ID0gcmVzZXQgPyBzY2FsZS55Q2VudGVyIDogcG9pbnRQb3NpdGlvbi55O1xuICAgICAgICAgICAgY29uc3QgcHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgICAgICB4LFxuICAgICAgICAgICAgICAgIHksXG4gICAgICAgICAgICAgICAgYW5nbGU6IHBvaW50UG9zaXRpb24uYW5nbGUsXG4gICAgICAgICAgICAgICAgc2tpcDogaXNOYU4oeCkgfHwgaXNOYU4oeSksXG4gICAgICAgICAgICAgICAgb3B0aW9uc1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlRWxlbWVudChwb2ludCwgaSwgcHJvcGVydGllcywgbW9kZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIFNjYXR0ZXJDb250cm9sbGVyIGV4dGVuZHMgRGF0YXNldENvbnRyb2xsZXIge1xuICAgIHN0YXRpYyBpZCA9ICdzY2F0dGVyJztcbiBzdGF0aWMgZGVmYXVsdHMgPSB7XG4gICAgICAgIGRhdGFzZXRFbGVtZW50VHlwZTogZmFsc2UsXG4gICAgICAgIGRhdGFFbGVtZW50VHlwZTogJ3BvaW50JyxcbiAgICAgICAgc2hvd0xpbmU6IGZhbHNlLFxuICAgICAgICBmaWxsOiBmYWxzZVxuICAgIH07XG4gc3RhdGljIG92ZXJyaWRlcyA9IHtcbiAgICAgICAgaW50ZXJhY3Rpb246IHtcbiAgICAgICAgICAgIG1vZGU6ICdwb2ludCdcbiAgICAgICAgfSxcbiAgICAgICAgc2NhbGVzOiB7XG4gICAgICAgICAgICB4OiB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2xpbmVhcidcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB5OiB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2xpbmVhcidcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gZ2V0TGFiZWxBbmRWYWx1ZShpbmRleCkge1xuICAgICAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICAgICAgY29uc3QgbGFiZWxzID0gdGhpcy5jaGFydC5kYXRhLmxhYmVscyB8fCBbXTtcbiAgICAgICAgY29uc3QgeyB4U2NhbGUgLCB5U2NhbGUgIH0gPSBtZXRhO1xuICAgICAgICBjb25zdCBwYXJzZWQgPSB0aGlzLmdldFBhcnNlZChpbmRleCk7XG4gICAgICAgIGNvbnN0IHggPSB4U2NhbGUuZ2V0TGFiZWxGb3JWYWx1ZShwYXJzZWQueCk7XG4gICAgICAgIGNvbnN0IHkgPSB5U2NhbGUuZ2V0TGFiZWxGb3JWYWx1ZShwYXJzZWQueSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBsYWJlbDogbGFiZWxzW2luZGV4XSB8fCAnJyxcbiAgICAgICAgICAgIHZhbHVlOiAnKCcgKyB4ICsgJywgJyArIHkgKyAnKSdcbiAgICAgICAgfTtcbiAgICB9XG4gICAgdXBkYXRlKG1vZGUpIHtcbiAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgICAgIGNvbnN0IHsgZGF0YTogcG9pbnRzID0gW10gIH0gPSBtZXRhO1xuICAgICAgICBjb25zdCBhbmltYXRpb25zRGlzYWJsZWQgPSB0aGlzLmNoYXJ0Ll9hbmltYXRpb25zRGlzYWJsZWQ7XG4gICAgICAgIGxldCB7IHN0YXJ0ICwgY291bnQgIH0gPSBfZ2V0U3RhcnRBbmRDb3VudE9mVmlzaWJsZVBvaW50cyhtZXRhLCBwb2ludHMsIGFuaW1hdGlvbnNEaXNhYmxlZCk7XG4gICAgICAgIHRoaXMuX2RyYXdTdGFydCA9IHN0YXJ0O1xuICAgICAgICB0aGlzLl9kcmF3Q291bnQgPSBjb3VudDtcbiAgICAgICAgaWYgKF9zY2FsZVJhbmdlc0NoYW5nZWQobWV0YSkpIHtcbiAgICAgICAgICAgIHN0YXJ0ID0gMDtcbiAgICAgICAgICAgIGNvdW50ID0gcG9pbnRzLmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNob3dMaW5lKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZGF0YXNldEVsZW1lbnRUeXBlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRFbGVtZW50cygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgeyBkYXRhc2V0OiBsaW5lICwgX2RhdGFzZXQgIH0gPSBtZXRhO1xuICAgICAgICAgICAgbGluZS5fY2hhcnQgPSB0aGlzLmNoYXJ0O1xuICAgICAgICAgICAgbGluZS5fZGF0YXNldEluZGV4ID0gdGhpcy5pbmRleDtcbiAgICAgICAgICAgIGxpbmUuX2RlY2ltYXRlZCA9ICEhX2RhdGFzZXQuX2RlY2ltYXRlZDtcbiAgICAgICAgICAgIGxpbmUucG9pbnRzID0gcG9pbnRzO1xuICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMucmVzb2x2ZURhdGFzZXRFbGVtZW50T3B0aW9ucyhtb2RlKTtcbiAgICAgICAgICAgIG9wdGlvbnMuc2VnbWVudCA9IHRoaXMub3B0aW9ucy5zZWdtZW50O1xuICAgICAgICAgICAgdGhpcy51cGRhdGVFbGVtZW50KGxpbmUsIHVuZGVmaW5lZCwge1xuICAgICAgICAgICAgICAgIGFuaW1hdGVkOiAhYW5pbWF0aW9uc0Rpc2FibGVkLFxuICAgICAgICAgICAgICAgIG9wdGlvbnNcbiAgICAgICAgICAgIH0sIG1vZGUpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZGF0YXNldEVsZW1lbnRUeXBlKSB7XG4gICAgICAgICAgICBkZWxldGUgbWV0YS5kYXRhc2V0O1xuICAgICAgICAgICAgdGhpcy5kYXRhc2V0RWxlbWVudFR5cGUgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnVwZGF0ZUVsZW1lbnRzKHBvaW50cywgc3RhcnQsIGNvdW50LCBtb2RlKTtcbiAgICB9XG4gICAgYWRkRWxlbWVudHMoKSB7XG4gICAgICAgIGNvbnN0IHsgc2hvd0xpbmUgIH0gPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGlmICghdGhpcy5kYXRhc2V0RWxlbWVudFR5cGUgJiYgc2hvd0xpbmUpIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YXNldEVsZW1lbnRUeXBlID0gdGhpcy5jaGFydC5yZWdpc3RyeS5nZXRFbGVtZW50KCdsaW5lJyk7XG4gICAgICAgIH1cbiAgICAgICAgc3VwZXIuYWRkRWxlbWVudHMoKTtcbiAgICB9XG4gICAgdXBkYXRlRWxlbWVudHMocG9pbnRzLCBzdGFydCwgY291bnQsIG1vZGUpIHtcbiAgICAgICAgY29uc3QgcmVzZXQgPSBtb2RlID09PSAncmVzZXQnO1xuICAgICAgICBjb25zdCB7IGlTY2FsZSAsIHZTY2FsZSAsIF9zdGFja2VkICwgX2RhdGFzZXQgIH0gPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgICAgICBjb25zdCBmaXJzdE9wdHMgPSB0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoc3RhcnQsIG1vZGUpO1xuICAgICAgICBjb25zdCBzaGFyZWRPcHRpb25zID0gdGhpcy5nZXRTaGFyZWRPcHRpb25zKGZpcnN0T3B0cyk7XG4gICAgICAgIGNvbnN0IGluY2x1ZGVPcHRpb25zID0gdGhpcy5pbmNsdWRlT3B0aW9ucyhtb2RlLCBzaGFyZWRPcHRpb25zKTtcbiAgICAgICAgY29uc3QgaUF4aXMgPSBpU2NhbGUuYXhpcztcbiAgICAgICAgY29uc3QgdkF4aXMgPSB2U2NhbGUuYXhpcztcbiAgICAgICAgY29uc3QgeyBzcGFuR2FwcyAsIHNlZ21lbnQgIH0gPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGNvbnN0IG1heEdhcExlbmd0aCA9IGlzTnVtYmVyKHNwYW5HYXBzKSA/IHNwYW5HYXBzIDogTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO1xuICAgICAgICBjb25zdCBkaXJlY3RVcGRhdGUgPSB0aGlzLmNoYXJ0Ll9hbmltYXRpb25zRGlzYWJsZWQgfHwgcmVzZXQgfHwgbW9kZSA9PT0gJ25vbmUnO1xuICAgICAgICBsZXQgcHJldlBhcnNlZCA9IHN0YXJ0ID4gMCAmJiB0aGlzLmdldFBhcnNlZChzdGFydCAtIDEpO1xuICAgICAgICBmb3IobGV0IGkgPSBzdGFydDsgaSA8IHN0YXJ0ICsgY291bnQ7ICsraSl7XG4gICAgICAgICAgICBjb25zdCBwb2ludCA9IHBvaW50c1tpXTtcbiAgICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IHRoaXMuZ2V0UGFyc2VkKGkpO1xuICAgICAgICAgICAgY29uc3QgcHJvcGVydGllcyA9IGRpcmVjdFVwZGF0ZSA/IHBvaW50IDoge307XG4gICAgICAgICAgICBjb25zdCBudWxsRGF0YSA9IGlzTnVsbE9yVW5kZWYocGFyc2VkW3ZBeGlzXSk7XG4gICAgICAgICAgICBjb25zdCBpUGl4ZWwgPSBwcm9wZXJ0aWVzW2lBeGlzXSA9IGlTY2FsZS5nZXRQaXhlbEZvclZhbHVlKHBhcnNlZFtpQXhpc10sIGkpO1xuICAgICAgICAgICAgY29uc3QgdlBpeGVsID0gcHJvcGVydGllc1t2QXhpc10gPSByZXNldCB8fCBudWxsRGF0YSA/IHZTY2FsZS5nZXRCYXNlUGl4ZWwoKSA6IHZTY2FsZS5nZXRQaXhlbEZvclZhbHVlKF9zdGFja2VkID8gdGhpcy5hcHBseVN0YWNrKHZTY2FsZSwgcGFyc2VkLCBfc3RhY2tlZCkgOiBwYXJzZWRbdkF4aXNdLCBpKTtcbiAgICAgICAgICAgIHByb3BlcnRpZXMuc2tpcCA9IGlzTmFOKGlQaXhlbCkgfHwgaXNOYU4odlBpeGVsKSB8fCBudWxsRGF0YTtcbiAgICAgICAgICAgIHByb3BlcnRpZXMuc3RvcCA9IGkgPiAwICYmIE1hdGguYWJzKHBhcnNlZFtpQXhpc10gLSBwcmV2UGFyc2VkW2lBeGlzXSkgPiBtYXhHYXBMZW5ndGg7XG4gICAgICAgICAgICBpZiAoc2VnbWVudCkge1xuICAgICAgICAgICAgICAgIHByb3BlcnRpZXMucGFyc2VkID0gcGFyc2VkO1xuICAgICAgICAgICAgICAgIHByb3BlcnRpZXMucmF3ID0gX2RhdGFzZXQuZGF0YVtpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpbmNsdWRlT3B0aW9ucykge1xuICAgICAgICAgICAgICAgIHByb3BlcnRpZXMub3B0aW9ucyA9IHNoYXJlZE9wdGlvbnMgfHwgdGhpcy5yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKGksIHBvaW50LmFjdGl2ZSA/ICdhY3RpdmUnIDogbW9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWRpcmVjdFVwZGF0ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlRWxlbWVudChwb2ludCwgaSwgcHJvcGVydGllcywgbW9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwcmV2UGFyc2VkID0gcGFyc2VkO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudXBkYXRlU2hhcmVkT3B0aW9ucyhzaGFyZWRPcHRpb25zLCBtb2RlLCBmaXJzdE9wdHMpO1xuICAgIH1cbiBnZXRNYXhPdmVyZmxvdygpIHtcbiAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBtZXRhLmRhdGEgfHwgW107XG4gICAgICAgIGlmICghdGhpcy5vcHRpb25zLnNob3dMaW5lKSB7XG4gICAgICAgICAgICBsZXQgbWF4ID0gMDtcbiAgICAgICAgICAgIGZvcihsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpe1xuICAgICAgICAgICAgICAgIG1heCA9IE1hdGgubWF4KG1heCwgZGF0YVtpXS5zaXplKHRoaXMucmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucyhpKSkgLyAyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtYXggPiAwICYmIG1heDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkYXRhc2V0ID0gbWV0YS5kYXRhc2V0O1xuICAgICAgICBjb25zdCBib3JkZXIgPSBkYXRhc2V0Lm9wdGlvbnMgJiYgZGF0YXNldC5vcHRpb25zLmJvcmRlcldpZHRoIHx8IDA7XG4gICAgICAgIGlmICghZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiBib3JkZXI7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZmlyc3RQb2ludCA9IGRhdGFbMF0uc2l6ZSh0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoMCkpO1xuICAgICAgICBjb25zdCBsYXN0UG9pbnQgPSBkYXRhW2RhdGEubGVuZ3RoIC0gMV0uc2l6ZSh0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoZGF0YS5sZW5ndGggLSAxKSk7XG4gICAgICAgIHJldHVybiBNYXRoLm1heChib3JkZXIsIGZpcnN0UG9pbnQsIGxhc3RQb2ludCkgLyAyO1xuICAgIH1cbn1cblxudmFyIGNvbnRyb2xsZXJzID0gLyojX19QVVJFX18qL09iamVjdC5mcmVlemUoe1xuX19wcm90b19fOiBudWxsLFxuQmFyQ29udHJvbGxlcjogQmFyQ29udHJvbGxlcixcbkJ1YmJsZUNvbnRyb2xsZXI6IEJ1YmJsZUNvbnRyb2xsZXIsXG5Eb3VnaG51dENvbnRyb2xsZXI6IERvdWdobnV0Q29udHJvbGxlcixcbkxpbmVDb250cm9sbGVyOiBMaW5lQ29udHJvbGxlcixcblBpZUNvbnRyb2xsZXI6IFBpZUNvbnRyb2xsZXIsXG5Qb2xhckFyZWFDb250cm9sbGVyOiBQb2xhckFyZWFDb250cm9sbGVyLFxuUmFkYXJDb250cm9sbGVyOiBSYWRhckNvbnRyb2xsZXIsXG5TY2F0dGVyQ29udHJvbGxlcjogU2NhdHRlckNvbnRyb2xsZXJcbn0pO1xuXG4vKipcbiAqIEBuYW1lc3BhY2UgQ2hhcnQuX2FkYXB0ZXJzXG4gKiBAc2luY2UgMi44LjBcbiAqIEBwcml2YXRlXG4gKi8gZnVuY3Rpb24gYWJzdHJhY3QoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaGlzIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQ6IENoZWNrIHRoYXQgYSBjb21wbGV0ZSBkYXRlIGFkYXB0ZXIgaXMgcHJvdmlkZWQuJyk7XG59XG4vKipcbiAqIERhdGUgYWRhcHRlciAoY3VycmVudCB1c2VkIGJ5IHRoZSB0aW1lIHNjYWxlKVxuICogQG5hbWVzcGFjZSBDaGFydC5fYWRhcHRlcnMuX2RhdGVcbiAqIEBtZW1iZXJvZiBDaGFydC5fYWRhcHRlcnNcbiAqIEBwcml2YXRlXG4gKi8gY2xhc3MgRGF0ZUFkYXB0ZXJCYXNlIHtcbiAgICAvKipcbiAgICogT3ZlcnJpZGUgZGVmYXVsdCBkYXRlIGFkYXB0ZXIgbWV0aG9kcy5cbiAgICogQWNjZXB0cyB0eXBlIHBhcmFtZXRlciB0byBkZWZpbmUgb3B0aW9ucyB0eXBlLlxuICAgKiBAZXhhbXBsZVxuICAgKiBDaGFydC5fYWRhcHRlcnMuX2RhdGUub3ZlcnJpZGU8e215QWRhcHRlck9wdGlvbjogc3RyaW5nfT4oe1xuICAgKiAgIGluaXQoKSB7XG4gICAqICAgICBjb25zb2xlLmxvZyh0aGlzLm9wdGlvbnMubXlBZGFwdGVyT3B0aW9uKTtcbiAgICogICB9XG4gICAqIH0pXG4gICAqLyBzdGF0aWMgb3ZlcnJpZGUobWVtYmVycykge1xuICAgICAgICBPYmplY3QuYXNzaWduKERhdGVBZGFwdGVyQmFzZS5wcm90b3R5cGUsIG1lbWJlcnMpO1xuICAgIH1cbiAgICBvcHRpb25zO1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpe1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICAgIH1cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWVtcHR5LWZ1bmN0aW9uXG4gICAgaW5pdCgpIHt9XG4gICAgZm9ybWF0cygpIHtcbiAgICAgICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gICAgfVxuICAgIHBhcnNlKCkge1xuICAgICAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgICB9XG4gICAgZm9ybWF0KCkge1xuICAgICAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgICB9XG4gICAgYWRkKCkge1xuICAgICAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgICB9XG4gICAgZGlmZigpIHtcbiAgICAgICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gICAgfVxuICAgIHN0YXJ0T2YoKSB7XG4gICAgICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICAgIH1cbiAgICBlbmRPZigpIHtcbiAgICAgICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gICAgfVxufVxudmFyIGFkYXB0ZXJzID0ge1xuICAgIF9kYXRlOiBEYXRlQWRhcHRlckJhc2Vcbn07XG5cbmZ1bmN0aW9uIGJpbmFyeVNlYXJjaChtZXRhc2V0LCBheGlzLCB2YWx1ZSwgaW50ZXJzZWN0KSB7XG4gICAgY29uc3QgeyBjb250cm9sbGVyICwgZGF0YSAsIF9zb3J0ZWQgIH0gPSBtZXRhc2V0O1xuICAgIGNvbnN0IGlTY2FsZSA9IGNvbnRyb2xsZXIuX2NhY2hlZE1ldGEuaVNjYWxlO1xuICAgIGlmIChpU2NhbGUgJiYgYXhpcyA9PT0gaVNjYWxlLmF4aXMgJiYgYXhpcyAhPT0gJ3InICYmIF9zb3J0ZWQgJiYgZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgY29uc3QgbG9va3VwTWV0aG9kID0gaVNjYWxlLl9yZXZlcnNlUGl4ZWxzID8gX3Jsb29rdXBCeUtleSA6IF9sb29rdXBCeUtleTtcbiAgICAgICAgaWYgKCFpbnRlcnNlY3QpIHtcbiAgICAgICAgICAgIHJldHVybiBsb29rdXBNZXRob2QoZGF0YSwgYXhpcywgdmFsdWUpO1xuICAgICAgICB9IGVsc2UgaWYgKGNvbnRyb2xsZXIuX3NoYXJlZE9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IGVsID0gZGF0YVswXTtcbiAgICAgICAgICAgIGNvbnN0IHJhbmdlID0gdHlwZW9mIGVsLmdldFJhbmdlID09PSAnZnVuY3Rpb24nICYmIGVsLmdldFJhbmdlKGF4aXMpO1xuICAgICAgICAgICAgaWYgKHJhbmdlKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RhcnQgPSBsb29rdXBNZXRob2QoZGF0YSwgYXhpcywgdmFsdWUgLSByYW5nZSk7XG4gICAgICAgICAgICAgICAgY29uc3QgZW5kID0gbG9va3VwTWV0aG9kKGRhdGEsIGF4aXMsIHZhbHVlICsgcmFuZ2UpO1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIGxvOiBzdGFydC5sbyxcbiAgICAgICAgICAgICAgICAgICAgaGk6IGVuZC5oaVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG86IDAsXG4gICAgICAgIGhpOiBkYXRhLmxlbmd0aCAtIDFcbiAgICB9O1xufVxuIGZ1bmN0aW9uIGV2YWx1YXRlSW50ZXJhY3Rpb25JdGVtcyhjaGFydCwgYXhpcywgcG9zaXRpb24sIGhhbmRsZXIsIGludGVyc2VjdCkge1xuICAgIGNvbnN0IG1ldGFzZXRzID0gY2hhcnQuZ2V0U29ydGVkVmlzaWJsZURhdGFzZXRNZXRhcygpO1xuICAgIGNvbnN0IHZhbHVlID0gcG9zaXRpb25bYXhpc107XG4gICAgZm9yKGxldCBpID0gMCwgaWxlbiA9IG1ldGFzZXRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSl7XG4gICAgICAgIGNvbnN0IHsgaW5kZXggLCBkYXRhICB9ID0gbWV0YXNldHNbaV07XG4gICAgICAgIGNvbnN0IHsgbG8gLCBoaSAgfSA9IGJpbmFyeVNlYXJjaChtZXRhc2V0c1tpXSwgYXhpcywgdmFsdWUsIGludGVyc2VjdCk7XG4gICAgICAgIGZvcihsZXQgaiA9IGxvOyBqIDw9IGhpOyArK2ope1xuICAgICAgICAgICAgY29uc3QgZWxlbWVudCA9IGRhdGFbal07XG4gICAgICAgICAgICBpZiAoIWVsZW1lbnQuc2tpcCkge1xuICAgICAgICAgICAgICAgIGhhbmRsZXIoZWxlbWVudCwgaW5kZXgsIGopO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuIGZ1bmN0aW9uIGdldERpc3RhbmNlTWV0cmljRm9yQXhpcyhheGlzKSB7XG4gICAgY29uc3QgdXNlWCA9IGF4aXMuaW5kZXhPZigneCcpICE9PSAtMTtcbiAgICBjb25zdCB1c2VZID0gYXhpcy5pbmRleE9mKCd5JykgIT09IC0xO1xuICAgIHJldHVybiBmdW5jdGlvbihwdDEsIHB0Mikge1xuICAgICAgICBjb25zdCBkZWx0YVggPSB1c2VYID8gTWF0aC5hYnMocHQxLnggLSBwdDIueCkgOiAwO1xuICAgICAgICBjb25zdCBkZWx0YVkgPSB1c2VZID8gTWF0aC5hYnMocHQxLnkgLSBwdDIueSkgOiAwO1xuICAgICAgICByZXR1cm4gTWF0aC5zcXJ0KE1hdGgucG93KGRlbHRhWCwgMikgKyBNYXRoLnBvdyhkZWx0YVksIDIpKTtcbiAgICB9O1xufVxuIGZ1bmN0aW9uIGdldEludGVyc2VjdEl0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgYXhpcywgdXNlRmluYWxQb3NpdGlvbiwgaW5jbHVkZUludmlzaWJsZSkge1xuICAgIGNvbnN0IGl0ZW1zID0gW107XG4gICAgaWYgKCFpbmNsdWRlSW52aXNpYmxlICYmICFjaGFydC5pc1BvaW50SW5BcmVhKHBvc2l0aW9uKSkge1xuICAgICAgICByZXR1cm4gaXRlbXM7XG4gICAgfVxuICAgIGNvbnN0IGV2YWx1YXRpb25GdW5jID0gZnVuY3Rpb24oZWxlbWVudCwgZGF0YXNldEluZGV4LCBpbmRleCkge1xuICAgICAgICBpZiAoIWluY2x1ZGVJbnZpc2libGUgJiYgIV9pc1BvaW50SW5BcmVhKGVsZW1lbnQsIGNoYXJ0LmNoYXJ0QXJlYSwgMCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZWxlbWVudC5pblJhbmdlKHBvc2l0aW9uLngsIHBvc2l0aW9uLnksIHVzZUZpbmFsUG9zaXRpb24pKSB7XG4gICAgICAgICAgICBpdGVtcy5wdXNoKHtcbiAgICAgICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgICAgIGRhdGFzZXRJbmRleCxcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIGV2YWx1YXRlSW50ZXJhY3Rpb25JdGVtcyhjaGFydCwgYXhpcywgcG9zaXRpb24sIGV2YWx1YXRpb25GdW5jLCB0cnVlKTtcbiAgICByZXR1cm4gaXRlbXM7XG59XG4gZnVuY3Rpb24gZ2V0TmVhcmVzdFJhZGlhbEl0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgYXhpcywgdXNlRmluYWxQb3NpdGlvbikge1xuICAgIGxldCBpdGVtcyA9IFtdO1xuICAgIGZ1bmN0aW9uIGV2YWx1YXRpb25GdW5jKGVsZW1lbnQsIGRhdGFzZXRJbmRleCwgaW5kZXgpIHtcbiAgICAgICAgY29uc3QgeyBzdGFydEFuZ2xlICwgZW5kQW5nbGUgIH0gPSBlbGVtZW50LmdldFByb3BzKFtcbiAgICAgICAgICAgICdzdGFydEFuZ2xlJyxcbiAgICAgICAgICAgICdlbmRBbmdsZSdcbiAgICAgICAgXSwgdXNlRmluYWxQb3NpdGlvbik7XG4gICAgICAgIGNvbnN0IHsgYW5nbGUgIH0gPSBnZXRBbmdsZUZyb21Qb2ludChlbGVtZW50LCB7XG4gICAgICAgICAgICB4OiBwb3NpdGlvbi54LFxuICAgICAgICAgICAgeTogcG9zaXRpb24ueVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKF9hbmdsZUJldHdlZW4oYW5nbGUsIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlKSkge1xuICAgICAgICAgICAgaXRlbXMucHVzaCh7XG4gICAgICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgICAgICBkYXRhc2V0SW5kZXgsXG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIGV2YWx1YXRlSW50ZXJhY3Rpb25JdGVtcyhjaGFydCwgYXhpcywgcG9zaXRpb24sIGV2YWx1YXRpb25GdW5jKTtcbiAgICByZXR1cm4gaXRlbXM7XG59XG4gZnVuY3Rpb24gZ2V0TmVhcmVzdENhcnRlc2lhbkl0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgYXhpcywgaW50ZXJzZWN0LCB1c2VGaW5hbFBvc2l0aW9uLCBpbmNsdWRlSW52aXNpYmxlKSB7XG4gICAgbGV0IGl0ZW1zID0gW107XG4gICAgY29uc3QgZGlzdGFuY2VNZXRyaWMgPSBnZXREaXN0YW5jZU1ldHJpY0ZvckF4aXMoYXhpcyk7XG4gICAgbGV0IG1pbkRpc3RhbmNlID0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO1xuICAgIGZ1bmN0aW9uIGV2YWx1YXRpb25GdW5jKGVsZW1lbnQsIGRhdGFzZXRJbmRleCwgaW5kZXgpIHtcbiAgICAgICAgY29uc3QgaW5SYW5nZSA9IGVsZW1lbnQuaW5SYW5nZShwb3NpdGlvbi54LCBwb3NpdGlvbi55LCB1c2VGaW5hbFBvc2l0aW9uKTtcbiAgICAgICAgaWYgKGludGVyc2VjdCAmJiAhaW5SYW5nZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNlbnRlciA9IGVsZW1lbnQuZ2V0Q2VudGVyUG9pbnQodXNlRmluYWxQb3NpdGlvbik7XG4gICAgICAgIGNvbnN0IHBvaW50SW5BcmVhID0gISFpbmNsdWRlSW52aXNpYmxlIHx8IGNoYXJ0LmlzUG9pbnRJbkFyZWEoY2VudGVyKTtcbiAgICAgICAgaWYgKCFwb2ludEluQXJlYSAmJiAhaW5SYW5nZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGRpc3RhbmNlID0gZGlzdGFuY2VNZXRyaWMocG9zaXRpb24sIGNlbnRlcik7XG4gICAgICAgIGlmIChkaXN0YW5jZSA8IG1pbkRpc3RhbmNlKSB7XG4gICAgICAgICAgICBpdGVtcyA9IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgICAgICAgICAgIGRhdGFzZXRJbmRleCxcbiAgICAgICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdO1xuICAgICAgICAgICAgbWluRGlzdGFuY2UgPSBkaXN0YW5jZTtcbiAgICAgICAgfSBlbHNlIGlmIChkaXN0YW5jZSA9PT0gbWluRGlzdGFuY2UpIHtcbiAgICAgICAgICAgIGl0ZW1zLnB1c2goe1xuICAgICAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgICAgICAgZGF0YXNldEluZGV4LFxuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBldmFsdWF0ZUludGVyYWN0aW9uSXRlbXMoY2hhcnQsIGF4aXMsIHBvc2l0aW9uLCBldmFsdWF0aW9uRnVuYyk7XG4gICAgcmV0dXJuIGl0ZW1zO1xufVxuIGZ1bmN0aW9uIGdldE5lYXJlc3RJdGVtcyhjaGFydCwgcG9zaXRpb24sIGF4aXMsIGludGVyc2VjdCwgdXNlRmluYWxQb3NpdGlvbiwgaW5jbHVkZUludmlzaWJsZSkge1xuICAgIGlmICghaW5jbHVkZUludmlzaWJsZSAmJiAhY2hhcnQuaXNQb2ludEluQXJlYShwb3NpdGlvbikpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICByZXR1cm4gYXhpcyA9PT0gJ3InICYmICFpbnRlcnNlY3QgPyBnZXROZWFyZXN0UmFkaWFsSXRlbXMoY2hhcnQsIHBvc2l0aW9uLCBheGlzLCB1c2VGaW5hbFBvc2l0aW9uKSA6IGdldE5lYXJlc3RDYXJ0ZXNpYW5JdGVtcyhjaGFydCwgcG9zaXRpb24sIGF4aXMsIGludGVyc2VjdCwgdXNlRmluYWxQb3NpdGlvbiwgaW5jbHVkZUludmlzaWJsZSk7XG59XG4gZnVuY3Rpb24gZ2V0QXhpc0l0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgYXhpcywgaW50ZXJzZWN0LCB1c2VGaW5hbFBvc2l0aW9uKSB7XG4gICAgY29uc3QgaXRlbXMgPSBbXTtcbiAgICBjb25zdCByYW5nZU1ldGhvZCA9IGF4aXMgPT09ICd4JyA/ICdpblhSYW5nZScgOiAnaW5ZUmFuZ2UnO1xuICAgIGxldCBpbnRlcnNlY3RzSXRlbSA9IGZhbHNlO1xuICAgIGV2YWx1YXRlSW50ZXJhY3Rpb25JdGVtcyhjaGFydCwgYXhpcywgcG9zaXRpb24sIChlbGVtZW50LCBkYXRhc2V0SW5kZXgsIGluZGV4KT0+e1xuICAgICAgICBpZiAoZWxlbWVudFtyYW5nZU1ldGhvZF0gJiYgZWxlbWVudFtyYW5nZU1ldGhvZF0ocG9zaXRpb25bYXhpc10sIHVzZUZpbmFsUG9zaXRpb24pKSB7XG4gICAgICAgICAgICBpdGVtcy5wdXNoKHtcbiAgICAgICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgICAgIGRhdGFzZXRJbmRleCxcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpbnRlcnNlY3RzSXRlbSA9IGludGVyc2VjdHNJdGVtIHx8IGVsZW1lbnQuaW5SYW5nZShwb3NpdGlvbi54LCBwb3NpdGlvbi55LCB1c2VGaW5hbFBvc2l0aW9uKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIGlmIChpbnRlcnNlY3QgJiYgIWludGVyc2VjdHNJdGVtKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgcmV0dXJuIGl0ZW1zO1xufVxuIHZhciBJbnRlcmFjdGlvbiA9IHtcbiAgICBldmFsdWF0ZUludGVyYWN0aW9uSXRlbXMsXG4gICAgbW9kZXM6IHtcbiBpbmRleCAoY2hhcnQsIGUsIG9wdGlvbnMsIHVzZUZpbmFsUG9zaXRpb24pIHtcbiAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uID0gZ2V0UmVsYXRpdmVQb3NpdGlvbihlLCBjaGFydCk7XG4gICAgICAgICAgICBjb25zdCBheGlzID0gb3B0aW9ucy5heGlzIHx8ICd4JztcbiAgICAgICAgICAgIGNvbnN0IGluY2x1ZGVJbnZpc2libGUgPSBvcHRpb25zLmluY2x1ZGVJbnZpc2libGUgfHwgZmFsc2U7XG4gICAgICAgICAgICBjb25zdCBpdGVtcyA9IG9wdGlvbnMuaW50ZXJzZWN0ID8gZ2V0SW50ZXJzZWN0SXRlbXMoY2hhcnQsIHBvc2l0aW9uLCBheGlzLCB1c2VGaW5hbFBvc2l0aW9uLCBpbmNsdWRlSW52aXNpYmxlKSA6IGdldE5lYXJlc3RJdGVtcyhjaGFydCwgcG9zaXRpb24sIGF4aXMsIGZhbHNlLCB1c2VGaW5hbFBvc2l0aW9uLCBpbmNsdWRlSW52aXNpYmxlKTtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRzID0gW107XG4gICAgICAgICAgICBpZiAoIWl0ZW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNoYXJ0LmdldFNvcnRlZFZpc2libGVEYXRhc2V0TWV0YXMoKS5mb3JFYWNoKChtZXRhKT0+e1xuICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gaXRlbXNbMF0uaW5kZXg7XG4gICAgICAgICAgICAgICAgY29uc3QgZWxlbWVudCA9IG1ldGEuZGF0YVtpbmRleF07XG4gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQgJiYgIWVsZW1lbnQuc2tpcCkge1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50cy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhc2V0SW5kZXg6IG1ldGEuaW5kZXgsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBlbGVtZW50cztcbiAgICAgICAgfSxcbiBkYXRhc2V0IChjaGFydCwgZSwgb3B0aW9ucywgdXNlRmluYWxQb3NpdGlvbikge1xuICAgICAgICAgICAgY29uc3QgcG9zaXRpb24gPSBnZXRSZWxhdGl2ZVBvc2l0aW9uKGUsIGNoYXJ0KTtcbiAgICAgICAgICAgIGNvbnN0IGF4aXMgPSBvcHRpb25zLmF4aXMgfHwgJ3h5JztcbiAgICAgICAgICAgIGNvbnN0IGluY2x1ZGVJbnZpc2libGUgPSBvcHRpb25zLmluY2x1ZGVJbnZpc2libGUgfHwgZmFsc2U7XG4gICAgICAgICAgICBsZXQgaXRlbXMgPSBvcHRpb25zLmludGVyc2VjdCA/IGdldEludGVyc2VjdEl0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgYXhpcywgdXNlRmluYWxQb3NpdGlvbiwgaW5jbHVkZUludmlzaWJsZSkgOiBnZXROZWFyZXN0SXRlbXMoY2hhcnQsIHBvc2l0aW9uLCBheGlzLCBmYWxzZSwgdXNlRmluYWxQb3NpdGlvbiwgaW5jbHVkZUludmlzaWJsZSk7XG4gICAgICAgICAgICBpZiAoaXRlbXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGFzZXRJbmRleCA9IGl0ZW1zWzBdLmRhdGFzZXRJbmRleDtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gY2hhcnQuZ2V0RGF0YXNldE1ldGEoZGF0YXNldEluZGV4KS5kYXRhO1xuICAgICAgICAgICAgICAgIGl0ZW1zID0gW107XG4gICAgICAgICAgICAgICAgZm9yKGxldCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyArK2kpe1xuICAgICAgICAgICAgICAgICAgICBpdGVtcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQ6IGRhdGFbaV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhc2V0SW5kZXgsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmRleDogaVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaXRlbXM7XG4gICAgICAgIH0sXG4gcG9pbnQgKGNoYXJ0LCBlLCBvcHRpb25zLCB1c2VGaW5hbFBvc2l0aW9uKSB7XG4gICAgICAgICAgICBjb25zdCBwb3NpdGlvbiA9IGdldFJlbGF0aXZlUG9zaXRpb24oZSwgY2hhcnQpO1xuICAgICAgICAgICAgY29uc3QgYXhpcyA9IG9wdGlvbnMuYXhpcyB8fCAneHknO1xuICAgICAgICAgICAgY29uc3QgaW5jbHVkZUludmlzaWJsZSA9IG9wdGlvbnMuaW5jbHVkZUludmlzaWJsZSB8fCBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybiBnZXRJbnRlcnNlY3RJdGVtcyhjaGFydCwgcG9zaXRpb24sIGF4aXMsIHVzZUZpbmFsUG9zaXRpb24sIGluY2x1ZGVJbnZpc2libGUpO1xuICAgICAgICB9LFxuIG5lYXJlc3QgKGNoYXJ0LCBlLCBvcHRpb25zLCB1c2VGaW5hbFBvc2l0aW9uKSB7XG4gICAgICAgICAgICBjb25zdCBwb3NpdGlvbiA9IGdldFJlbGF0aXZlUG9zaXRpb24oZSwgY2hhcnQpO1xuICAgICAgICAgICAgY29uc3QgYXhpcyA9IG9wdGlvbnMuYXhpcyB8fCAneHknO1xuICAgICAgICAgICAgY29uc3QgaW5jbHVkZUludmlzaWJsZSA9IG9wdGlvbnMuaW5jbHVkZUludmlzaWJsZSB8fCBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybiBnZXROZWFyZXN0SXRlbXMoY2hhcnQsIHBvc2l0aW9uLCBheGlzLCBvcHRpb25zLmludGVyc2VjdCwgdXNlRmluYWxQb3NpdGlvbiwgaW5jbHVkZUludmlzaWJsZSk7XG4gICAgICAgIH0sXG4geCAoY2hhcnQsIGUsIG9wdGlvbnMsIHVzZUZpbmFsUG9zaXRpb24pIHtcbiAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uID0gZ2V0UmVsYXRpdmVQb3NpdGlvbihlLCBjaGFydCk7XG4gICAgICAgICAgICByZXR1cm4gZ2V0QXhpc0l0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgJ3gnLCBvcHRpb25zLmludGVyc2VjdCwgdXNlRmluYWxQb3NpdGlvbik7XG4gICAgICAgIH0sXG4geSAoY2hhcnQsIGUsIG9wdGlvbnMsIHVzZUZpbmFsUG9zaXRpb24pIHtcbiAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uID0gZ2V0UmVsYXRpdmVQb3NpdGlvbihlLCBjaGFydCk7XG4gICAgICAgICAgICByZXR1cm4gZ2V0QXhpc0l0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgJ3knLCBvcHRpb25zLmludGVyc2VjdCwgdXNlRmluYWxQb3NpdGlvbik7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5jb25zdCBTVEFUSUNfUE9TSVRJT05TID0gW1xuICAgICdsZWZ0JyxcbiAgICAndG9wJyxcbiAgICAncmlnaHQnLFxuICAgICdib3R0b20nXG5dO1xuZnVuY3Rpb24gZmlsdGVyQnlQb3NpdGlvbihhcnJheSwgcG9zaXRpb24pIHtcbiAgICByZXR1cm4gYXJyYXkuZmlsdGVyKCh2KT0+di5wb3MgPT09IHBvc2l0aW9uKTtcbn1cbmZ1bmN0aW9uIGZpbHRlckR5bmFtaWNQb3NpdGlvbkJ5QXhpcyhhcnJheSwgYXhpcykge1xuICAgIHJldHVybiBhcnJheS5maWx0ZXIoKHYpPT5TVEFUSUNfUE9TSVRJT05TLmluZGV4T2Yodi5wb3MpID09PSAtMSAmJiB2LmJveC5heGlzID09PSBheGlzKTtcbn1cbmZ1bmN0aW9uIHNvcnRCeVdlaWdodChhcnJheSwgcmV2ZXJzZSkge1xuICAgIHJldHVybiBhcnJheS5zb3J0KChhLCBiKT0+e1xuICAgICAgICBjb25zdCB2MCA9IHJldmVyc2UgPyBiIDogYTtcbiAgICAgICAgY29uc3QgdjEgPSByZXZlcnNlID8gYSA6IGI7XG4gICAgICAgIHJldHVybiB2MC53ZWlnaHQgPT09IHYxLndlaWdodCA/IHYwLmluZGV4IC0gdjEuaW5kZXggOiB2MC53ZWlnaHQgLSB2MS53ZWlnaHQ7XG4gICAgfSk7XG59XG5mdW5jdGlvbiB3cmFwQm94ZXMoYm94ZXMpIHtcbiAgICBjb25zdCBsYXlvdXRCb3hlcyA9IFtdO1xuICAgIGxldCBpLCBpbGVuLCBib3gsIHBvcywgc3RhY2ssIHN0YWNrV2VpZ2h0O1xuICAgIGZvcihpID0gMCwgaWxlbiA9IChib3hlcyB8fCBbXSkubGVuZ3RoOyBpIDwgaWxlbjsgKytpKXtcbiAgICAgICAgYm94ID0gYm94ZXNbaV07XG4gICAgICAgICh7IHBvc2l0aW9uOiBwb3MgLCBvcHRpb25zOiB7IHN0YWNrICwgc3RhY2tXZWlnaHQgPTEgIH0gIH0gPSBib3gpO1xuICAgICAgICBsYXlvdXRCb3hlcy5wdXNoKHtcbiAgICAgICAgICAgIGluZGV4OiBpLFxuICAgICAgICAgICAgYm94LFxuICAgICAgICAgICAgcG9zLFxuICAgICAgICAgICAgaG9yaXpvbnRhbDogYm94LmlzSG9yaXpvbnRhbCgpLFxuICAgICAgICAgICAgd2VpZ2h0OiBib3gud2VpZ2h0LFxuICAgICAgICAgICAgc3RhY2s6IHN0YWNrICYmIHBvcyArIHN0YWNrLFxuICAgICAgICAgICAgc3RhY2tXZWlnaHRcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBsYXlvdXRCb3hlcztcbn1cbmZ1bmN0aW9uIGJ1aWxkU3RhY2tzKGxheW91dHMpIHtcbiAgICBjb25zdCBzdGFja3MgPSB7fTtcbiAgICBmb3IgKGNvbnN0IHdyYXAgb2YgbGF5b3V0cyl7XG4gICAgICAgIGNvbnN0IHsgc3RhY2sgLCBwb3MgLCBzdGFja1dlaWdodCAgfSA9IHdyYXA7XG4gICAgICAgIGlmICghc3RhY2sgfHwgIVNUQVRJQ19QT1NJVElPTlMuaW5jbHVkZXMocG9zKSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgX3N0YWNrID0gc3RhY2tzW3N0YWNrXSB8fCAoc3RhY2tzW3N0YWNrXSA9IHtcbiAgICAgICAgICAgIGNvdW50OiAwLFxuICAgICAgICAgICAgcGxhY2VkOiAwLFxuICAgICAgICAgICAgd2VpZ2h0OiAwLFxuICAgICAgICAgICAgc2l6ZTogMFxuICAgICAgICB9KTtcbiAgICAgICAgX3N0YWNrLmNvdW50Kys7XG4gICAgICAgIF9zdGFjay53ZWlnaHQgKz0gc3RhY2tXZWlnaHQ7XG4gICAgfVxuICAgIHJldHVybiBzdGFja3M7XG59XG4gZnVuY3Rpb24gc2V0TGF5b3V0RGltcyhsYXlvdXRzLCBwYXJhbXMpIHtcbiAgICBjb25zdCBzdGFja3MgPSBidWlsZFN0YWNrcyhsYXlvdXRzKTtcbiAgICBjb25zdCB7IHZCb3hNYXhXaWR0aCAsIGhCb3hNYXhIZWlnaHQgIH0gPSBwYXJhbXM7XG4gICAgbGV0IGksIGlsZW4sIGxheW91dDtcbiAgICBmb3IoaSA9IDAsIGlsZW4gPSBsYXlvdXRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSl7XG4gICAgICAgIGxheW91dCA9IGxheW91dHNbaV07XG4gICAgICAgIGNvbnN0IHsgZnVsbFNpemUgIH0gPSBsYXlvdXQuYm94O1xuICAgICAgICBjb25zdCBzdGFjayA9IHN0YWNrc1tsYXlvdXQuc3RhY2tdO1xuICAgICAgICBjb25zdCBmYWN0b3IgPSBzdGFjayAmJiBsYXlvdXQuc3RhY2tXZWlnaHQgLyBzdGFjay53ZWlnaHQ7XG4gICAgICAgIGlmIChsYXlvdXQuaG9yaXpvbnRhbCkge1xuICAgICAgICAgICAgbGF5b3V0LndpZHRoID0gZmFjdG9yID8gZmFjdG9yICogdkJveE1heFdpZHRoIDogZnVsbFNpemUgJiYgcGFyYW1zLmF2YWlsYWJsZVdpZHRoO1xuICAgICAgICAgICAgbGF5b3V0LmhlaWdodCA9IGhCb3hNYXhIZWlnaHQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsYXlvdXQud2lkdGggPSB2Qm94TWF4V2lkdGg7XG4gICAgICAgICAgICBsYXlvdXQuaGVpZ2h0ID0gZmFjdG9yID8gZmFjdG9yICogaEJveE1heEhlaWdodCA6IGZ1bGxTaXplICYmIHBhcmFtcy5hdmFpbGFibGVIZWlnaHQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHN0YWNrcztcbn1cbmZ1bmN0aW9uIGJ1aWxkTGF5b3V0Qm94ZXMoYm94ZXMpIHtcbiAgICBjb25zdCBsYXlvdXRCb3hlcyA9IHdyYXBCb3hlcyhib3hlcyk7XG4gICAgY29uc3QgZnVsbFNpemUgPSBzb3J0QnlXZWlnaHQobGF5b3V0Qm94ZXMuZmlsdGVyKCh3cmFwKT0+d3JhcC5ib3guZnVsbFNpemUpLCB0cnVlKTtcbiAgICBjb25zdCBsZWZ0ID0gc29ydEJ5V2VpZ2h0KGZpbHRlckJ5UG9zaXRpb24obGF5b3V0Qm94ZXMsICdsZWZ0JyksIHRydWUpO1xuICAgIGNvbnN0IHJpZ2h0ID0gc29ydEJ5V2VpZ2h0KGZpbHRlckJ5UG9zaXRpb24obGF5b3V0Qm94ZXMsICdyaWdodCcpKTtcbiAgICBjb25zdCB0b3AgPSBzb3J0QnlXZWlnaHQoZmlsdGVyQnlQb3NpdGlvbihsYXlvdXRCb3hlcywgJ3RvcCcpLCB0cnVlKTtcbiAgICBjb25zdCBib3R0b20gPSBzb3J0QnlXZWlnaHQoZmlsdGVyQnlQb3NpdGlvbihsYXlvdXRCb3hlcywgJ2JvdHRvbScpKTtcbiAgICBjb25zdCBjZW50ZXJIb3Jpem9udGFsID0gZmlsdGVyRHluYW1pY1Bvc2l0aW9uQnlBeGlzKGxheW91dEJveGVzLCAneCcpO1xuICAgIGNvbnN0IGNlbnRlclZlcnRpY2FsID0gZmlsdGVyRHluYW1pY1Bvc2l0aW9uQnlBeGlzKGxheW91dEJveGVzLCAneScpO1xuICAgIHJldHVybiB7XG4gICAgICAgIGZ1bGxTaXplLFxuICAgICAgICBsZWZ0QW5kVG9wOiBsZWZ0LmNvbmNhdCh0b3ApLFxuICAgICAgICByaWdodEFuZEJvdHRvbTogcmlnaHQuY29uY2F0KGNlbnRlclZlcnRpY2FsKS5jb25jYXQoYm90dG9tKS5jb25jYXQoY2VudGVySG9yaXpvbnRhbCksXG4gICAgICAgIGNoYXJ0QXJlYTogZmlsdGVyQnlQb3NpdGlvbihsYXlvdXRCb3hlcywgJ2NoYXJ0QXJlYScpLFxuICAgICAgICB2ZXJ0aWNhbDogbGVmdC5jb25jYXQocmlnaHQpLmNvbmNhdChjZW50ZXJWZXJ0aWNhbCksXG4gICAgICAgIGhvcml6b250YWw6IHRvcC5jb25jYXQoYm90dG9tKS5jb25jYXQoY2VudGVySG9yaXpvbnRhbClcbiAgICB9O1xufVxuZnVuY3Rpb24gZ2V0Q29tYmluZWRNYXgobWF4UGFkZGluZywgY2hhcnRBcmVhLCBhLCBiKSB7XG4gICAgcmV0dXJuIE1hdGgubWF4KG1heFBhZGRpbmdbYV0sIGNoYXJ0QXJlYVthXSkgKyBNYXRoLm1heChtYXhQYWRkaW5nW2JdLCBjaGFydEFyZWFbYl0pO1xufVxuZnVuY3Rpb24gdXBkYXRlTWF4UGFkZGluZyhtYXhQYWRkaW5nLCBib3hQYWRkaW5nKSB7XG4gICAgbWF4UGFkZGluZy50b3AgPSBNYXRoLm1heChtYXhQYWRkaW5nLnRvcCwgYm94UGFkZGluZy50b3ApO1xuICAgIG1heFBhZGRpbmcubGVmdCA9IE1hdGgubWF4KG1heFBhZGRpbmcubGVmdCwgYm94UGFkZGluZy5sZWZ0KTtcbiAgICBtYXhQYWRkaW5nLmJvdHRvbSA9IE1hdGgubWF4KG1heFBhZGRpbmcuYm90dG9tLCBib3hQYWRkaW5nLmJvdHRvbSk7XG4gICAgbWF4UGFkZGluZy5yaWdodCA9IE1hdGgubWF4KG1heFBhZGRpbmcucmlnaHQsIGJveFBhZGRpbmcucmlnaHQpO1xufVxuZnVuY3Rpb24gdXBkYXRlRGltcyhjaGFydEFyZWEsIHBhcmFtcywgbGF5b3V0LCBzdGFja3MpIHtcbiAgICBjb25zdCB7IHBvcyAsIGJveCAgfSA9IGxheW91dDtcbiAgICBjb25zdCBtYXhQYWRkaW5nID0gY2hhcnRBcmVhLm1heFBhZGRpbmc7XG4gICAgaWYgKCFpc09iamVjdChwb3MpKSB7XG4gICAgICAgIGlmIChsYXlvdXQuc2l6ZSkge1xuICAgICAgICAgICAgY2hhcnRBcmVhW3Bvc10gLT0gbGF5b3V0LnNpemU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RhY2sgPSBzdGFja3NbbGF5b3V0LnN0YWNrXSB8fCB7XG4gICAgICAgICAgICBzaXplOiAwLFxuICAgICAgICAgICAgY291bnQ6IDFcbiAgICAgICAgfTtcbiAgICAgICAgc3RhY2suc2l6ZSA9IE1hdGgubWF4KHN0YWNrLnNpemUsIGxheW91dC5ob3Jpem9udGFsID8gYm94LmhlaWdodCA6IGJveC53aWR0aCk7XG4gICAgICAgIGxheW91dC5zaXplID0gc3RhY2suc2l6ZSAvIHN0YWNrLmNvdW50O1xuICAgICAgICBjaGFydEFyZWFbcG9zXSArPSBsYXlvdXQuc2l6ZTtcbiAgICB9XG4gICAgaWYgKGJveC5nZXRQYWRkaW5nKSB7XG4gICAgICAgIHVwZGF0ZU1heFBhZGRpbmcobWF4UGFkZGluZywgYm94LmdldFBhZGRpbmcoKSk7XG4gICAgfVxuICAgIGNvbnN0IG5ld1dpZHRoID0gTWF0aC5tYXgoMCwgcGFyYW1zLm91dGVyV2lkdGggLSBnZXRDb21iaW5lZE1heChtYXhQYWRkaW5nLCBjaGFydEFyZWEsICdsZWZ0JywgJ3JpZ2h0JykpO1xuICAgIGNvbnN0IG5ld0hlaWdodCA9IE1hdGgubWF4KDAsIHBhcmFtcy5vdXRlckhlaWdodCAtIGdldENvbWJpbmVkTWF4KG1heFBhZGRpbmcsIGNoYXJ0QXJlYSwgJ3RvcCcsICdib3R0b20nKSk7XG4gICAgY29uc3Qgd2lkdGhDaGFuZ2VkID0gbmV3V2lkdGggIT09IGNoYXJ0QXJlYS53O1xuICAgIGNvbnN0IGhlaWdodENoYW5nZWQgPSBuZXdIZWlnaHQgIT09IGNoYXJ0QXJlYS5oO1xuICAgIGNoYXJ0QXJlYS53ID0gbmV3V2lkdGg7XG4gICAgY2hhcnRBcmVhLmggPSBuZXdIZWlnaHQ7XG4gICAgcmV0dXJuIGxheW91dC5ob3Jpem9udGFsID8ge1xuICAgICAgICBzYW1lOiB3aWR0aENoYW5nZWQsXG4gICAgICAgIG90aGVyOiBoZWlnaHRDaGFuZ2VkXG4gICAgfSA6IHtcbiAgICAgICAgc2FtZTogaGVpZ2h0Q2hhbmdlZCxcbiAgICAgICAgb3RoZXI6IHdpZHRoQ2hhbmdlZFxuICAgIH07XG59XG5mdW5jdGlvbiBoYW5kbGVNYXhQYWRkaW5nKGNoYXJ0QXJlYSkge1xuICAgIGNvbnN0IG1heFBhZGRpbmcgPSBjaGFydEFyZWEubWF4UGFkZGluZztcbiAgICBmdW5jdGlvbiB1cGRhdGVQb3MocG9zKSB7XG4gICAgICAgIGNvbnN0IGNoYW5nZSA9IE1hdGgubWF4KG1heFBhZGRpbmdbcG9zXSAtIGNoYXJ0QXJlYVtwb3NdLCAwKTtcbiAgICAgICAgY2hhcnRBcmVhW3Bvc10gKz0gY2hhbmdlO1xuICAgICAgICByZXR1cm4gY2hhbmdlO1xuICAgIH1cbiAgICBjaGFydEFyZWEueSArPSB1cGRhdGVQb3MoJ3RvcCcpO1xuICAgIGNoYXJ0QXJlYS54ICs9IHVwZGF0ZVBvcygnbGVmdCcpO1xuICAgIHVwZGF0ZVBvcygncmlnaHQnKTtcbiAgICB1cGRhdGVQb3MoJ2JvdHRvbScpO1xufVxuZnVuY3Rpb24gZ2V0TWFyZ2lucyhob3Jpem9udGFsLCBjaGFydEFyZWEpIHtcbiAgICBjb25zdCBtYXhQYWRkaW5nID0gY2hhcnRBcmVhLm1heFBhZGRpbmc7XG4gICAgZnVuY3Rpb24gbWFyZ2luRm9yUG9zaXRpb25zKHBvc2l0aW9ucykge1xuICAgICAgICBjb25zdCBtYXJnaW4gPSB7XG4gICAgICAgICAgICBsZWZ0OiAwLFxuICAgICAgICAgICAgdG9wOiAwLFxuICAgICAgICAgICAgcmlnaHQ6IDAsXG4gICAgICAgICAgICBib3R0b206IDBcbiAgICAgICAgfTtcbiAgICAgICAgcG9zaXRpb25zLmZvckVhY2goKHBvcyk9PntcbiAgICAgICAgICAgIG1hcmdpbltwb3NdID0gTWF0aC5tYXgoY2hhcnRBcmVhW3Bvc10sIG1heFBhZGRpbmdbcG9zXSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbWFyZ2luO1xuICAgIH1cbiAgICByZXR1cm4gaG9yaXpvbnRhbCA/IG1hcmdpbkZvclBvc2l0aW9ucyhbXG4gICAgICAgICdsZWZ0JyxcbiAgICAgICAgJ3JpZ2h0J1xuICAgIF0pIDogbWFyZ2luRm9yUG9zaXRpb25zKFtcbiAgICAgICAgJ3RvcCcsXG4gICAgICAgICdib3R0b20nXG4gICAgXSk7XG59XG5mdW5jdGlvbiBmaXRCb3hlcyhib3hlcywgY2hhcnRBcmVhLCBwYXJhbXMsIHN0YWNrcykge1xuICAgIGNvbnN0IHJlZml0Qm94ZXMgPSBbXTtcbiAgICBsZXQgaSwgaWxlbiwgbGF5b3V0LCBib3gsIHJlZml0LCBjaGFuZ2VkO1xuICAgIGZvcihpID0gMCwgaWxlbiA9IGJveGVzLmxlbmd0aCwgcmVmaXQgPSAwOyBpIDwgaWxlbjsgKytpKXtcbiAgICAgICAgbGF5b3V0ID0gYm94ZXNbaV07XG4gICAgICAgIGJveCA9IGxheW91dC5ib3g7XG4gICAgICAgIGJveC51cGRhdGUobGF5b3V0LndpZHRoIHx8IGNoYXJ0QXJlYS53LCBsYXlvdXQuaGVpZ2h0IHx8IGNoYXJ0QXJlYS5oLCBnZXRNYXJnaW5zKGxheW91dC5ob3Jpem9udGFsLCBjaGFydEFyZWEpKTtcbiAgICAgICAgY29uc3QgeyBzYW1lICwgb3RoZXIgIH0gPSB1cGRhdGVEaW1zKGNoYXJ0QXJlYSwgcGFyYW1zLCBsYXlvdXQsIHN0YWNrcyk7XG4gICAgICAgIHJlZml0IHw9IHNhbWUgJiYgcmVmaXRCb3hlcy5sZW5ndGg7XG4gICAgICAgIGNoYW5nZWQgPSBjaGFuZ2VkIHx8IG90aGVyO1xuICAgICAgICBpZiAoIWJveC5mdWxsU2l6ZSkge1xuICAgICAgICAgICAgcmVmaXRCb3hlcy5wdXNoKGxheW91dCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlZml0ICYmIGZpdEJveGVzKHJlZml0Qm94ZXMsIGNoYXJ0QXJlYSwgcGFyYW1zLCBzdGFja3MpIHx8IGNoYW5nZWQ7XG59XG5mdW5jdGlvbiBzZXRCb3hEaW1zKGJveCwgbGVmdCwgdG9wLCB3aWR0aCwgaGVpZ2h0KSB7XG4gICAgYm94LnRvcCA9IHRvcDtcbiAgICBib3gubGVmdCA9IGxlZnQ7XG4gICAgYm94LnJpZ2h0ID0gbGVmdCArIHdpZHRoO1xuICAgIGJveC5ib3R0b20gPSB0b3AgKyBoZWlnaHQ7XG4gICAgYm94LndpZHRoID0gd2lkdGg7XG4gICAgYm94LmhlaWdodCA9IGhlaWdodDtcbn1cbmZ1bmN0aW9uIHBsYWNlQm94ZXMoYm94ZXMsIGNoYXJ0QXJlYSwgcGFyYW1zLCBzdGFja3MpIHtcbiAgICBjb25zdCB1c2VyUGFkZGluZyA9IHBhcmFtcy5wYWRkaW5nO1xuICAgIGxldCB7IHggLCB5ICB9ID0gY2hhcnRBcmVhO1xuICAgIGZvciAoY29uc3QgbGF5b3V0IG9mIGJveGVzKXtcbiAgICAgICAgY29uc3QgYm94ID0gbGF5b3V0LmJveDtcbiAgICAgICAgY29uc3Qgc3RhY2sgPSBzdGFja3NbbGF5b3V0LnN0YWNrXSB8fCB7XG4gICAgICAgICAgICBjb3VudDogMSxcbiAgICAgICAgICAgIHBsYWNlZDogMCxcbiAgICAgICAgICAgIHdlaWdodDogMVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCB3ZWlnaHQgPSBsYXlvdXQuc3RhY2tXZWlnaHQgLyBzdGFjay53ZWlnaHQgfHwgMTtcbiAgICAgICAgaWYgKGxheW91dC5ob3Jpem9udGFsKSB7XG4gICAgICAgICAgICBjb25zdCB3aWR0aCA9IGNoYXJ0QXJlYS53ICogd2VpZ2h0O1xuICAgICAgICAgICAgY29uc3QgaGVpZ2h0ID0gc3RhY2suc2l6ZSB8fCBib3guaGVpZ2h0O1xuICAgICAgICAgICAgaWYgKGRlZmluZWQoc3RhY2suc3RhcnQpKSB7XG4gICAgICAgICAgICAgICAgeSA9IHN0YWNrLnN0YXJ0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGJveC5mdWxsU2l6ZSkge1xuICAgICAgICAgICAgICAgIHNldEJveERpbXMoYm94LCB1c2VyUGFkZGluZy5sZWZ0LCB5LCBwYXJhbXMub3V0ZXJXaWR0aCAtIHVzZXJQYWRkaW5nLnJpZ2h0IC0gdXNlclBhZGRpbmcubGVmdCwgaGVpZ2h0KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc2V0Qm94RGltcyhib3gsIGNoYXJ0QXJlYS5sZWZ0ICsgc3RhY2sucGxhY2VkLCB5LCB3aWR0aCwgaGVpZ2h0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN0YWNrLnN0YXJ0ID0geTtcbiAgICAgICAgICAgIHN0YWNrLnBsYWNlZCArPSB3aWR0aDtcbiAgICAgICAgICAgIHkgPSBib3guYm90dG9tO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgaGVpZ2h0ID0gY2hhcnRBcmVhLmggKiB3ZWlnaHQ7XG4gICAgICAgICAgICBjb25zdCB3aWR0aCA9IHN0YWNrLnNpemUgfHwgYm94LndpZHRoO1xuICAgICAgICAgICAgaWYgKGRlZmluZWQoc3RhY2suc3RhcnQpKSB7XG4gICAgICAgICAgICAgICAgeCA9IHN0YWNrLnN0YXJ0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGJveC5mdWxsU2l6ZSkge1xuICAgICAgICAgICAgICAgIHNldEJveERpbXMoYm94LCB4LCB1c2VyUGFkZGluZy50b3AsIHdpZHRoLCBwYXJhbXMub3V0ZXJIZWlnaHQgLSB1c2VyUGFkZGluZy5ib3R0b20gLSB1c2VyUGFkZGluZy50b3ApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXRCb3hEaW1zKGJveCwgeCwgY2hhcnRBcmVhLnRvcCArIHN0YWNrLnBsYWNlZCwgd2lkdGgsIGhlaWdodCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdGFjay5zdGFydCA9IHg7XG4gICAgICAgICAgICBzdGFjay5wbGFjZWQgKz0gaGVpZ2h0O1xuICAgICAgICAgICAgeCA9IGJveC5yaWdodDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjaGFydEFyZWEueCA9IHg7XG4gICAgY2hhcnRBcmVhLnkgPSB5O1xufVxudmFyIGxheW91dHMgPSB7XG4gYWRkQm94IChjaGFydCwgaXRlbSkge1xuICAgICAgICBpZiAoIWNoYXJ0LmJveGVzKSB7XG4gICAgICAgICAgICBjaGFydC5ib3hlcyA9IFtdO1xuICAgICAgICB9XG4gICAgICAgIGl0ZW0uZnVsbFNpemUgPSBpdGVtLmZ1bGxTaXplIHx8IGZhbHNlO1xuICAgICAgICBpdGVtLnBvc2l0aW9uID0gaXRlbS5wb3NpdGlvbiB8fCAndG9wJztcbiAgICAgICAgaXRlbS53ZWlnaHQgPSBpdGVtLndlaWdodCB8fCAwO1xuICAgICAgICBpdGVtLl9sYXllcnMgPSBpdGVtLl9sYXllcnMgfHwgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgejogMCxcbiAgICAgICAgICAgICAgICAgICAgZHJhdyAoY2hhcnRBcmVhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVtLmRyYXcoY2hhcnRBcmVhKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF07XG4gICAgICAgIH07XG4gICAgICAgIGNoYXJ0LmJveGVzLnB1c2goaXRlbSk7XG4gICAgfSxcbiByZW1vdmVCb3ggKGNoYXJ0LCBsYXlvdXRJdGVtKSB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gY2hhcnQuYm94ZXMgPyBjaGFydC5ib3hlcy5pbmRleE9mKGxheW91dEl0ZW0pIDogLTE7XG4gICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgIGNoYXJ0LmJveGVzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgIH1cbiAgICB9LFxuIGNvbmZpZ3VyZSAoY2hhcnQsIGl0ZW0sIG9wdGlvbnMpIHtcbiAgICAgICAgaXRlbS5mdWxsU2l6ZSA9IG9wdGlvbnMuZnVsbFNpemU7XG4gICAgICAgIGl0ZW0ucG9zaXRpb24gPSBvcHRpb25zLnBvc2l0aW9uO1xuICAgICAgICBpdGVtLndlaWdodCA9IG9wdGlvbnMud2VpZ2h0O1xuICAgIH0sXG4gdXBkYXRlIChjaGFydCwgd2lkdGgsIGhlaWdodCwgbWluUGFkZGluZykge1xuICAgICAgICBpZiAoIWNoYXJ0KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGFkZGluZyA9IHRvUGFkZGluZyhjaGFydC5vcHRpb25zLmxheW91dC5wYWRkaW5nKTtcbiAgICAgICAgY29uc3QgYXZhaWxhYmxlV2lkdGggPSBNYXRoLm1heCh3aWR0aCAtIHBhZGRpbmcud2lkdGgsIDApO1xuICAgICAgICBjb25zdCBhdmFpbGFibGVIZWlnaHQgPSBNYXRoLm1heChoZWlnaHQgLSBwYWRkaW5nLmhlaWdodCwgMCk7XG4gICAgICAgIGNvbnN0IGJveGVzID0gYnVpbGRMYXlvdXRCb3hlcyhjaGFydC5ib3hlcyk7XG4gICAgICAgIGNvbnN0IHZlcnRpY2FsQm94ZXMgPSBib3hlcy52ZXJ0aWNhbDtcbiAgICAgICAgY29uc3QgaG9yaXpvbnRhbEJveGVzID0gYm94ZXMuaG9yaXpvbnRhbDtcbiAgICAgICAgZWFjaChjaGFydC5ib3hlcywgKGJveCk9PntcbiAgICAgICAgICAgIGlmICh0eXBlb2YgYm94LmJlZm9yZUxheW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIGJveC5iZWZvcmVMYXlvdXQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHZpc2libGVWZXJ0aWNhbEJveENvdW50ID0gdmVydGljYWxCb3hlcy5yZWR1Y2UoKHRvdGFsLCB3cmFwKT0+d3JhcC5ib3gub3B0aW9ucyAmJiB3cmFwLmJveC5vcHRpb25zLmRpc3BsYXkgPT09IGZhbHNlID8gdG90YWwgOiB0b3RhbCArIDEsIDApIHx8IDE7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IE9iamVjdC5mcmVlemUoe1xuICAgICAgICAgICAgb3V0ZXJXaWR0aDogd2lkdGgsXG4gICAgICAgICAgICBvdXRlckhlaWdodDogaGVpZ2h0LFxuICAgICAgICAgICAgcGFkZGluZyxcbiAgICAgICAgICAgIGF2YWlsYWJsZVdpZHRoLFxuICAgICAgICAgICAgYXZhaWxhYmxlSGVpZ2h0LFxuICAgICAgICAgICAgdkJveE1heFdpZHRoOiBhdmFpbGFibGVXaWR0aCAvIDIgLyB2aXNpYmxlVmVydGljYWxCb3hDb3VudCxcbiAgICAgICAgICAgIGhCb3hNYXhIZWlnaHQ6IGF2YWlsYWJsZUhlaWdodCAvIDJcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG1heFBhZGRpbmcgPSBPYmplY3QuYXNzaWduKHt9LCBwYWRkaW5nKTtcbiAgICAgICAgdXBkYXRlTWF4UGFkZGluZyhtYXhQYWRkaW5nLCB0b1BhZGRpbmcobWluUGFkZGluZykpO1xuICAgICAgICBjb25zdCBjaGFydEFyZWEgPSBPYmplY3QuYXNzaWduKHtcbiAgICAgICAgICAgIG1heFBhZGRpbmcsXG4gICAgICAgICAgICB3OiBhdmFpbGFibGVXaWR0aCxcbiAgICAgICAgICAgIGg6IGF2YWlsYWJsZUhlaWdodCxcbiAgICAgICAgICAgIHg6IHBhZGRpbmcubGVmdCxcbiAgICAgICAgICAgIHk6IHBhZGRpbmcudG9wXG4gICAgICAgIH0sIHBhZGRpbmcpO1xuICAgICAgICBjb25zdCBzdGFja3MgPSBzZXRMYXlvdXREaW1zKHZlcnRpY2FsQm94ZXMuY29uY2F0KGhvcml6b250YWxCb3hlcyksIHBhcmFtcyk7XG4gICAgICAgIGZpdEJveGVzKGJveGVzLmZ1bGxTaXplLCBjaGFydEFyZWEsIHBhcmFtcywgc3RhY2tzKTtcbiAgICAgICAgZml0Qm94ZXModmVydGljYWxCb3hlcywgY2hhcnRBcmVhLCBwYXJhbXMsIHN0YWNrcyk7XG4gICAgICAgIGlmIChmaXRCb3hlcyhob3Jpem9udGFsQm94ZXMsIGNoYXJ0QXJlYSwgcGFyYW1zLCBzdGFja3MpKSB7XG4gICAgICAgICAgICBmaXRCb3hlcyh2ZXJ0aWNhbEJveGVzLCBjaGFydEFyZWEsIHBhcmFtcywgc3RhY2tzKTtcbiAgICAgICAgfVxuICAgICAgICBoYW5kbGVNYXhQYWRkaW5nKGNoYXJ0QXJlYSk7XG4gICAgICAgIHBsYWNlQm94ZXMoYm94ZXMubGVmdEFuZFRvcCwgY2hhcnRBcmVhLCBwYXJhbXMsIHN0YWNrcyk7XG4gICAgICAgIGNoYXJ0QXJlYS54ICs9IGNoYXJ0QXJlYS53O1xuICAgICAgICBjaGFydEFyZWEueSArPSBjaGFydEFyZWEuaDtcbiAgICAgICAgcGxhY2VCb3hlcyhib3hlcy5yaWdodEFuZEJvdHRvbSwgY2hhcnRBcmVhLCBwYXJhbXMsIHN0YWNrcyk7XG4gICAgICAgIGNoYXJ0LmNoYXJ0QXJlYSA9IHtcbiAgICAgICAgICAgIGxlZnQ6IGNoYXJ0QXJlYS5sZWZ0LFxuICAgICAgICAgICAgdG9wOiBjaGFydEFyZWEudG9wLFxuICAgICAgICAgICAgcmlnaHQ6IGNoYXJ0QXJlYS5sZWZ0ICsgY2hhcnRBcmVhLncsXG4gICAgICAgICAgICBib3R0b206IGNoYXJ0QXJlYS50b3AgKyBjaGFydEFyZWEuaCxcbiAgICAgICAgICAgIGhlaWdodDogY2hhcnRBcmVhLmgsXG4gICAgICAgICAgICB3aWR0aDogY2hhcnRBcmVhLndcbiAgICAgICAgfTtcbiAgICAgICAgZWFjaChib3hlcy5jaGFydEFyZWEsIChsYXlvdXQpPT57XG4gICAgICAgICAgICBjb25zdCBib3ggPSBsYXlvdXQuYm94O1xuICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihib3gsIGNoYXJ0LmNoYXJ0QXJlYSk7XG4gICAgICAgICAgICBib3gudXBkYXRlKGNoYXJ0QXJlYS53LCBjaGFydEFyZWEuaCwge1xuICAgICAgICAgICAgICAgIGxlZnQ6IDAsXG4gICAgICAgICAgICAgICAgdG9wOiAwLFxuICAgICAgICAgICAgICAgIHJpZ2h0OiAwLFxuICAgICAgICAgICAgICAgIGJvdHRvbTogMFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cbn07XG5cbmNsYXNzIEJhc2VQbGF0Zm9ybSB7XG4gYWNxdWlyZUNvbnRleHQoY2FudmFzLCBhc3BlY3RSYXRpbykge31cbiByZWxlYXNlQ29udGV4dChjb250ZXh0KSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gYWRkRXZlbnRMaXN0ZW5lcihjaGFydCwgdHlwZSwgbGlzdGVuZXIpIHt9XG4gcmVtb3ZlRXZlbnRMaXN0ZW5lcihjaGFydCwgdHlwZSwgbGlzdGVuZXIpIHt9XG4gZ2V0RGV2aWNlUGl4ZWxSYXRpbygpIHtcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgfVxuIGdldE1heGltdW1TaXplKGVsZW1lbnQsIHdpZHRoLCBoZWlnaHQsIGFzcGVjdFJhdGlvKSB7XG4gICAgICAgIHdpZHRoID0gTWF0aC5tYXgoMCwgd2lkdGggfHwgZWxlbWVudC53aWR0aCk7XG4gICAgICAgIGhlaWdodCA9IGhlaWdodCB8fCBlbGVtZW50LmhlaWdodDtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHdpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiBNYXRoLm1heCgwLCBhc3BlY3RSYXRpbyA/IE1hdGguZmxvb3Iod2lkdGggLyBhc3BlY3RSYXRpbykgOiBoZWlnaHQpXG4gICAgICAgIH07XG4gICAgfVxuIGlzQXR0YWNoZWQoY2FudmFzKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiB1cGRhdGVDb25maWcoY29uZmlnKSB7XG4gICAgfVxufVxuXG5jbGFzcyBCYXNpY1BsYXRmb3JtIGV4dGVuZHMgQmFzZVBsYXRmb3JtIHtcbiAgICBhY3F1aXJlQ29udGV4dChpdGVtKSB7XG4gICAgICAgIHJldHVybiBpdGVtICYmIGl0ZW0uZ2V0Q29udGV4dCAmJiBpdGVtLmdldENvbnRleHQoJzJkJykgfHwgbnVsbDtcbiAgICB9XG4gICAgdXBkYXRlQ29uZmlnKGNvbmZpZykge1xuICAgICAgICBjb25maWcub3B0aW9ucy5hbmltYXRpb24gPSBmYWxzZTtcbiAgICB9XG59XG5cbmNvbnN0IEVYUEFORE9fS0VZID0gJyRjaGFydGpzJztcbiBjb25zdCBFVkVOVF9UWVBFUyA9IHtcbiAgICB0b3VjaHN0YXJ0OiAnbW91c2Vkb3duJyxcbiAgICB0b3VjaG1vdmU6ICdtb3VzZW1vdmUnLFxuICAgIHRvdWNoZW5kOiAnbW91c2V1cCcsXG4gICAgcG9pbnRlcmVudGVyOiAnbW91c2VlbnRlcicsXG4gICAgcG9pbnRlcmRvd246ICdtb3VzZWRvd24nLFxuICAgIHBvaW50ZXJtb3ZlOiAnbW91c2Vtb3ZlJyxcbiAgICBwb2ludGVydXA6ICdtb3VzZXVwJyxcbiAgICBwb2ludGVybGVhdmU6ICdtb3VzZW91dCcsXG4gICAgcG9pbnRlcm91dDogJ21vdXNlb3V0J1xufTtcbmNvbnN0IGlzTnVsbE9yRW1wdHkgPSAodmFsdWUpPT52YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gJyc7XG4gZnVuY3Rpb24gaW5pdENhbnZhcyhjYW52YXMsIGFzcGVjdFJhdGlvKSB7XG4gICAgY29uc3Qgc3R5bGUgPSBjYW52YXMuc3R5bGU7XG4gICAgY29uc3QgcmVuZGVySGVpZ2h0ID0gY2FudmFzLmdldEF0dHJpYnV0ZSgnaGVpZ2h0Jyk7XG4gICAgY29uc3QgcmVuZGVyV2lkdGggPSBjYW52YXMuZ2V0QXR0cmlidXRlKCd3aWR0aCcpO1xuICAgIGNhbnZhc1tFWFBBTkRPX0tFWV0gPSB7XG4gICAgICAgIGluaXRpYWw6IHtcbiAgICAgICAgICAgIGhlaWdodDogcmVuZGVySGVpZ2h0LFxuICAgICAgICAgICAgd2lkdGg6IHJlbmRlcldpZHRoLFxuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICBkaXNwbGF5OiBzdHlsZS5kaXNwbGF5LFxuICAgICAgICAgICAgICAgIGhlaWdodDogc3R5bGUuaGVpZ2h0LFxuICAgICAgICAgICAgICAgIHdpZHRoOiBzdHlsZS53aWR0aFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICBzdHlsZS5kaXNwbGF5ID0gc3R5bGUuZGlzcGxheSB8fCAnYmxvY2snO1xuICAgIHN0eWxlLmJveFNpemluZyA9IHN0eWxlLmJveFNpemluZyB8fCAnYm9yZGVyLWJveCc7XG4gICAgaWYgKGlzTnVsbE9yRW1wdHkocmVuZGVyV2lkdGgpKSB7XG4gICAgICAgIGNvbnN0IGRpc3BsYXlXaWR0aCA9IHJlYWRVc2VkU2l6ZShjYW52YXMsICd3aWR0aCcpO1xuICAgICAgICBpZiAoZGlzcGxheVdpZHRoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGNhbnZhcy53aWR0aCA9IGRpc3BsYXlXaWR0aDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoaXNOdWxsT3JFbXB0eShyZW5kZXJIZWlnaHQpKSB7XG4gICAgICAgIGlmIChjYW52YXMuc3R5bGUuaGVpZ2h0ID09PSAnJykge1xuICAgICAgICAgICAgY2FudmFzLmhlaWdodCA9IGNhbnZhcy53aWR0aCAvIChhc3BlY3RSYXRpbyB8fCAyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGRpc3BsYXlIZWlnaHQgPSByZWFkVXNlZFNpemUoY2FudmFzLCAnaGVpZ2h0Jyk7XG4gICAgICAgICAgICBpZiAoZGlzcGxheUhlaWdodCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgY2FudmFzLmhlaWdodCA9IGRpc3BsYXlIZWlnaHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGNhbnZhcztcbn1cbmNvbnN0IGV2ZW50TGlzdGVuZXJPcHRpb25zID0gc3VwcG9ydHNFdmVudExpc3RlbmVyT3B0aW9ucyA/IHtcbiAgICBwYXNzaXZlOiB0cnVlXG59IDogZmFsc2U7XG5mdW5jdGlvbiBhZGRMaXN0ZW5lcihub2RlLCB0eXBlLCBsaXN0ZW5lcikge1xuICAgIGlmIChub2RlKSB7XG4gICAgICAgIG5vZGUuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lciwgZXZlbnRMaXN0ZW5lck9wdGlvbnMpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVyKGNoYXJ0LCB0eXBlLCBsaXN0ZW5lcikge1xuICAgIGlmIChjaGFydCAmJiBjaGFydC5jYW52YXMpIHtcbiAgICAgICAgY2hhcnQuY2FudmFzLnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgbGlzdGVuZXIsIGV2ZW50TGlzdGVuZXJPcHRpb25zKTtcbiAgICB9XG59XG5mdW5jdGlvbiBmcm9tTmF0aXZlRXZlbnQoZXZlbnQsIGNoYXJ0KSB7XG4gICAgY29uc3QgdHlwZSA9IEVWRU5UX1RZUEVTW2V2ZW50LnR5cGVdIHx8IGV2ZW50LnR5cGU7XG4gICAgY29uc3QgeyB4ICwgeSAgfSA9IGdldFJlbGF0aXZlUG9zaXRpb24oZXZlbnQsIGNoYXJ0KTtcbiAgICByZXR1cm4ge1xuICAgICAgICB0eXBlLFxuICAgICAgICBjaGFydCxcbiAgICAgICAgbmF0aXZlOiBldmVudCxcbiAgICAgICAgeDogeCAhPT0gdW5kZWZpbmVkID8geCA6IG51bGwsXG4gICAgICAgIHk6IHkgIT09IHVuZGVmaW5lZCA/IHkgOiBudWxsXG4gICAgfTtcbn1cbmZ1bmN0aW9uIG5vZGVMaXN0Q29udGFpbnMobm9kZUxpc3QsIGNhbnZhcykge1xuICAgIGZvciAoY29uc3Qgbm9kZSBvZiBub2RlTGlzdCl7XG4gICAgICAgIGlmIChub2RlID09PSBjYW52YXMgfHwgbm9kZS5jb250YWlucyhjYW52YXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmZ1bmN0aW9uIGNyZWF0ZUF0dGFjaE9ic2VydmVyKGNoYXJ0LCB0eXBlLCBsaXN0ZW5lcikge1xuICAgIGNvbnN0IGNhbnZhcyA9IGNoYXJ0LmNhbnZhcztcbiAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKChlbnRyaWVzKT0+e1xuICAgICAgICBsZXQgdHJpZ2dlciA9IGZhbHNlO1xuICAgICAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpe1xuICAgICAgICAgICAgdHJpZ2dlciA9IHRyaWdnZXIgfHwgbm9kZUxpc3RDb250YWlucyhlbnRyeS5hZGRlZE5vZGVzLCBjYW52YXMpO1xuICAgICAgICAgICAgdHJpZ2dlciA9IHRyaWdnZXIgJiYgIW5vZGVMaXN0Q29udGFpbnMoZW50cnkucmVtb3ZlZE5vZGVzLCBjYW52YXMpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0cmlnZ2VyKSB7XG4gICAgICAgICAgICBsaXN0ZW5lcigpO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgb2JzZXJ2ZXIub2JzZXJ2ZShkb2N1bWVudCwge1xuICAgICAgICBjaGlsZExpc3Q6IHRydWUsXG4gICAgICAgIHN1YnRyZWU6IHRydWVcbiAgICB9KTtcbiAgICByZXR1cm4gb2JzZXJ2ZXI7XG59XG5mdW5jdGlvbiBjcmVhdGVEZXRhY2hPYnNlcnZlcihjaGFydCwgdHlwZSwgbGlzdGVuZXIpIHtcbiAgICBjb25zdCBjYW52YXMgPSBjaGFydC5jYW52YXM7XG4gICAgY29uc3Qgb2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcigoZW50cmllcyk9PntcbiAgICAgICAgbGV0IHRyaWdnZXIgPSBmYWxzZTtcbiAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKXtcbiAgICAgICAgICAgIHRyaWdnZXIgPSB0cmlnZ2VyIHx8IG5vZGVMaXN0Q29udGFpbnMoZW50cnkucmVtb3ZlZE5vZGVzLCBjYW52YXMpO1xuICAgICAgICAgICAgdHJpZ2dlciA9IHRyaWdnZXIgJiYgIW5vZGVMaXN0Q29udGFpbnMoZW50cnkuYWRkZWROb2RlcywgY2FudmFzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHJpZ2dlcikge1xuICAgICAgICAgICAgbGlzdGVuZXIoKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIG9ic2VydmVyLm9ic2VydmUoZG9jdW1lbnQsIHtcbiAgICAgICAgY2hpbGRMaXN0OiB0cnVlLFxuICAgICAgICBzdWJ0cmVlOiB0cnVlXG4gICAgfSk7XG4gICAgcmV0dXJuIG9ic2VydmVyO1xufVxuY29uc3QgZHJwTGlzdGVuaW5nQ2hhcnRzID0gbmV3IE1hcCgpO1xubGV0IG9sZERldmljZVBpeGVsUmF0aW8gPSAwO1xuZnVuY3Rpb24gb25XaW5kb3dSZXNpemUoKSB7XG4gICAgY29uc3QgZHByID0gd2luZG93LmRldmljZVBpeGVsUmF0aW87XG4gICAgaWYgKGRwciA9PT0gb2xkRGV2aWNlUGl4ZWxSYXRpbykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIG9sZERldmljZVBpeGVsUmF0aW8gPSBkcHI7XG4gICAgZHJwTGlzdGVuaW5nQ2hhcnRzLmZvckVhY2goKHJlc2l6ZSwgY2hhcnQpPT57XG4gICAgICAgIGlmIChjaGFydC5jdXJyZW50RGV2aWNlUGl4ZWxSYXRpbyAhPT0gZHByKSB7XG4gICAgICAgICAgICByZXNpemUoKTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuZnVuY3Rpb24gbGlzdGVuRGV2aWNlUGl4ZWxSYXRpb0NoYW5nZXMoY2hhcnQsIHJlc2l6ZSkge1xuICAgIGlmICghZHJwTGlzdGVuaW5nQ2hhcnRzLnNpemUpIHtcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIG9uV2luZG93UmVzaXplKTtcbiAgICB9XG4gICAgZHJwTGlzdGVuaW5nQ2hhcnRzLnNldChjaGFydCwgcmVzaXplKTtcbn1cbmZ1bmN0aW9uIHVubGlzdGVuRGV2aWNlUGl4ZWxSYXRpb0NoYW5nZXMoY2hhcnQpIHtcbiAgICBkcnBMaXN0ZW5pbmdDaGFydHMuZGVsZXRlKGNoYXJ0KTtcbiAgICBpZiAoIWRycExpc3RlbmluZ0NoYXJ0cy5zaXplKSB7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCBvbldpbmRvd1Jlc2l6ZSk7XG4gICAgfVxufVxuZnVuY3Rpb24gY3JlYXRlUmVzaXplT2JzZXJ2ZXIoY2hhcnQsIHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgY29uc3QgY2FudmFzID0gY2hhcnQuY2FudmFzO1xuICAgIGNvbnN0IGNvbnRhaW5lciA9IGNhbnZhcyAmJiBfZ2V0UGFyZW50Tm9kZShjYW52YXMpO1xuICAgIGlmICghY29udGFpbmVyKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcmVzaXplID0gdGhyb3R0bGVkKCh3aWR0aCwgaGVpZ2h0KT0+e1xuICAgICAgICBjb25zdCB3ID0gY29udGFpbmVyLmNsaWVudFdpZHRoO1xuICAgICAgICBsaXN0ZW5lcih3aWR0aCwgaGVpZ2h0KTtcbiAgICAgICAgaWYgKHcgPCBjb250YWluZXIuY2xpZW50V2lkdGgpIHtcbiAgICAgICAgICAgIGxpc3RlbmVyKCk7XG4gICAgICAgIH1cbiAgICB9LCB3aW5kb3cpO1xuICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKChlbnRyaWVzKT0+e1xuICAgICAgICBjb25zdCBlbnRyeSA9IGVudHJpZXNbMF07XG4gICAgICAgIGNvbnN0IHdpZHRoID0gZW50cnkuY29udGVudFJlY3Qud2lkdGg7XG4gICAgICAgIGNvbnN0IGhlaWdodCA9IGVudHJ5LmNvbnRlbnRSZWN0LmhlaWdodDtcbiAgICAgICAgaWYgKHdpZHRoID09PSAwICYmIGhlaWdodCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHJlc2l6ZSh3aWR0aCwgaGVpZ2h0KTtcbiAgICB9KTtcbiAgICBvYnNlcnZlci5vYnNlcnZlKGNvbnRhaW5lcik7XG4gICAgbGlzdGVuRGV2aWNlUGl4ZWxSYXRpb0NoYW5nZXMoY2hhcnQsIHJlc2l6ZSk7XG4gICAgcmV0dXJuIG9ic2VydmVyO1xufVxuZnVuY3Rpb24gcmVsZWFzZU9ic2VydmVyKGNoYXJ0LCB0eXBlLCBvYnNlcnZlcikge1xuICAgIGlmIChvYnNlcnZlcikge1xuICAgICAgICBvYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gICAgfVxuICAgIGlmICh0eXBlID09PSAncmVzaXplJykge1xuICAgICAgICB1bmxpc3RlbkRldmljZVBpeGVsUmF0aW9DaGFuZ2VzKGNoYXJ0KTtcbiAgICB9XG59XG5mdW5jdGlvbiBjcmVhdGVQcm94eUFuZExpc3RlbihjaGFydCwgdHlwZSwgbGlzdGVuZXIpIHtcbiAgICBjb25zdCBjYW52YXMgPSBjaGFydC5jYW52YXM7XG4gICAgY29uc3QgcHJveHkgPSB0aHJvdHRsZWQoKGV2ZW50KT0+e1xuICAgICAgICBpZiAoY2hhcnQuY3R4ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBsaXN0ZW5lcihmcm9tTmF0aXZlRXZlbnQoZXZlbnQsIGNoYXJ0KSk7XG4gICAgICAgIH1cbiAgICB9LCBjaGFydCk7XG4gICAgYWRkTGlzdGVuZXIoY2FudmFzLCB0eXBlLCBwcm94eSk7XG4gICAgcmV0dXJuIHByb3h5O1xufVxuIGNsYXNzIERvbVBsYXRmb3JtIGV4dGVuZHMgQmFzZVBsYXRmb3JtIHtcbiBhY3F1aXJlQ29udGV4dChjYW52YXMsIGFzcGVjdFJhdGlvKSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBjYW52YXMgJiYgY2FudmFzLmdldENvbnRleHQgJiYgY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgICAgIGlmIChjb250ZXh0ICYmIGNvbnRleHQuY2FudmFzID09PSBjYW52YXMpIHtcbiAgICAgICAgICAgIGluaXRDYW52YXMoY2FudmFzLCBhc3BlY3RSYXRpbyk7XG4gICAgICAgICAgICByZXR1cm4gY29udGV4dDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gcmVsZWFzZUNvbnRleHQoY29udGV4dCkge1xuICAgICAgICBjb25zdCBjYW52YXMgPSBjb250ZXh0LmNhbnZhcztcbiAgICAgICAgaWYgKCFjYW52YXNbRVhQQU5ET19LRVldKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaW5pdGlhbCA9IGNhbnZhc1tFWFBBTkRPX0tFWV0uaW5pdGlhbDtcbiAgICAgICAgW1xuICAgICAgICAgICAgJ2hlaWdodCcsXG4gICAgICAgICAgICAnd2lkdGgnXG4gICAgICAgIF0uZm9yRWFjaCgocHJvcCk9PntcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gaW5pdGlhbFtwcm9wXTtcbiAgICAgICAgICAgIGlmIChpc051bGxPclVuZGVmKHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIGNhbnZhcy5yZW1vdmVBdHRyaWJ1dGUocHJvcCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNhbnZhcy5zZXRBdHRyaWJ1dGUocHJvcCwgdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3Qgc3R5bGUgPSBpbml0aWFsLnN0eWxlIHx8IHt9O1xuICAgICAgICBPYmplY3Qua2V5cyhzdHlsZSkuZm9yRWFjaCgoa2V5KT0+e1xuICAgICAgICAgICAgY2FudmFzLnN0eWxlW2tleV0gPSBzdHlsZVtrZXldO1xuICAgICAgICB9KTtcbiAgICAgICAgY2FudmFzLndpZHRoID0gY2FudmFzLndpZHRoO1xuICAgICAgICBkZWxldGUgY2FudmFzW0VYUEFORE9fS0VZXTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuIGFkZEV2ZW50TGlzdGVuZXIoY2hhcnQsIHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcihjaGFydCwgdHlwZSk7XG4gICAgICAgIGNvbnN0IHByb3hpZXMgPSBjaGFydC4kcHJveGllcyB8fCAoY2hhcnQuJHByb3hpZXMgPSB7fSk7XG4gICAgICAgIGNvbnN0IGhhbmRsZXJzID0ge1xuICAgICAgICAgICAgYXR0YWNoOiBjcmVhdGVBdHRhY2hPYnNlcnZlcixcbiAgICAgICAgICAgIGRldGFjaDogY3JlYXRlRGV0YWNoT2JzZXJ2ZXIsXG4gICAgICAgICAgICByZXNpemU6IGNyZWF0ZVJlc2l6ZU9ic2VydmVyXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGhhbmRsZXIgPSBoYW5kbGVyc1t0eXBlXSB8fCBjcmVhdGVQcm94eUFuZExpc3RlbjtcbiAgICAgICAgcHJveGllc1t0eXBlXSA9IGhhbmRsZXIoY2hhcnQsIHR5cGUsIGxpc3RlbmVyKTtcbiAgICB9XG4gcmVtb3ZlRXZlbnRMaXN0ZW5lcihjaGFydCwgdHlwZSkge1xuICAgICAgICBjb25zdCBwcm94aWVzID0gY2hhcnQuJHByb3hpZXMgfHwgKGNoYXJ0LiRwcm94aWVzID0ge30pO1xuICAgICAgICBjb25zdCBwcm94eSA9IHByb3hpZXNbdHlwZV07XG4gICAgICAgIGlmICghcHJveHkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBoYW5kbGVycyA9IHtcbiAgICAgICAgICAgIGF0dGFjaDogcmVsZWFzZU9ic2VydmVyLFxuICAgICAgICAgICAgZGV0YWNoOiByZWxlYXNlT2JzZXJ2ZXIsXG4gICAgICAgICAgICByZXNpemU6IHJlbGVhc2VPYnNlcnZlclxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBoYW5kbGVyID0gaGFuZGxlcnNbdHlwZV0gfHwgcmVtb3ZlTGlzdGVuZXI7XG4gICAgICAgIGhhbmRsZXIoY2hhcnQsIHR5cGUsIHByb3h5KTtcbiAgICAgICAgcHJveGllc1t0eXBlXSA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgZ2V0RGV2aWNlUGl4ZWxSYXRpbygpIHtcbiAgICAgICAgcmV0dXJuIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuICAgIH1cbiBnZXRNYXhpbXVtU2l6ZShjYW52YXMsIHdpZHRoLCBoZWlnaHQsIGFzcGVjdFJhdGlvKSB7XG4gICAgICAgIHJldHVybiBnZXRNYXhpbXVtU2l6ZShjYW52YXMsIHdpZHRoLCBoZWlnaHQsIGFzcGVjdFJhdGlvKTtcbiAgICB9XG4gaXNBdHRhY2hlZChjYW52YXMpIHtcbiAgICAgICAgY29uc3QgY29udGFpbmVyID0gY2FudmFzICYmIF9nZXRQYXJlbnROb2RlKGNhbnZhcyk7XG4gICAgICAgIHJldHVybiAhIShjb250YWluZXIgJiYgY29udGFpbmVyLmlzQ29ubmVjdGVkKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIF9kZXRlY3RQbGF0Zm9ybShjYW52YXMpIHtcbiAgICBpZiAoIV9pc0RvbVN1cHBvcnRlZCgpIHx8IHR5cGVvZiBPZmZzY3JlZW5DYW52YXMgIT09ICd1bmRlZmluZWQnICYmIGNhbnZhcyBpbnN0YW5jZW9mIE9mZnNjcmVlbkNhbnZhcykge1xuICAgICAgICByZXR1cm4gQmFzaWNQbGF0Zm9ybTtcbiAgICB9XG4gICAgcmV0dXJuIERvbVBsYXRmb3JtO1xufVxuXG5jbGFzcyBFbGVtZW50IHtcbiAgICBzdGF0aWMgZGVmYXVsdHMgPSB7fTtcbiAgICBzdGF0aWMgZGVmYXVsdFJvdXRlcyA9IHVuZGVmaW5lZDtcbiAgICB4O1xuICAgIHk7XG4gICAgYWN0aXZlID0gZmFsc2U7XG4gICAgb3B0aW9ucztcbiAgICAkYW5pbWF0aW9ucztcbiAgICB0b29sdGlwUG9zaXRpb24odXNlRmluYWxQb3NpdGlvbikge1xuICAgICAgICBjb25zdCB7IHggLCB5ICB9ID0gdGhpcy5nZXRQcm9wcyhbXG4gICAgICAgICAgICAneCcsXG4gICAgICAgICAgICAneSdcbiAgICAgICAgXSwgdXNlRmluYWxQb3NpdGlvbik7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4LFxuICAgICAgICAgICAgeVxuICAgICAgICB9O1xuICAgIH1cbiAgICBoYXNWYWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIGlzTnVtYmVyKHRoaXMueCkgJiYgaXNOdW1iZXIodGhpcy55KTtcbiAgICB9XG4gICAgZ2V0UHJvcHMocHJvcHMsIGZpbmFsKSB7XG4gICAgICAgIGNvbnN0IGFuaW1zID0gdGhpcy4kYW5pbWF0aW9ucztcbiAgICAgICAgaWYgKCFmaW5hbCB8fCAhYW5pbXMpIHtcbiAgICAgICAgICAgIC8vIGxldCdzIG5vdCBjcmVhdGUgYW4gb2JqZWN0LCBpZiBub3QgbmVlZGVkXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByZXQgPSB7fTtcbiAgICAgICAgcHJvcHMuZm9yRWFjaCgocHJvcCk9PntcbiAgICAgICAgICAgIHJldFtwcm9wXSA9IGFuaW1zW3Byb3BdICYmIGFuaW1zW3Byb3BdLmFjdGl2ZSgpID8gYW5pbXNbcHJvcF0uX3RvIDogdGhpc1twcm9wXTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBhdXRvU2tpcChzY2FsZSwgdGlja3MpIHtcbiAgICBjb25zdCB0aWNrT3B0cyA9IHNjYWxlLm9wdGlvbnMudGlja3M7XG4gICAgY29uc3QgZGV0ZXJtaW5lZE1heFRpY2tzID0gZGV0ZXJtaW5lTWF4VGlja3Moc2NhbGUpO1xuICAgIGNvbnN0IHRpY2tzTGltaXQgPSBNYXRoLm1pbih0aWNrT3B0cy5tYXhUaWNrc0xpbWl0IHx8IGRldGVybWluZWRNYXhUaWNrcywgZGV0ZXJtaW5lZE1heFRpY2tzKTtcbiAgICBjb25zdCBtYWpvckluZGljZXMgPSB0aWNrT3B0cy5tYWpvci5lbmFibGVkID8gZ2V0TWFqb3JJbmRpY2VzKHRpY2tzKSA6IFtdO1xuICAgIGNvbnN0IG51bU1ham9ySW5kaWNlcyA9IG1ham9ySW5kaWNlcy5sZW5ndGg7XG4gICAgY29uc3QgZmlyc3QgPSBtYWpvckluZGljZXNbMF07XG4gICAgY29uc3QgbGFzdCA9IG1ham9ySW5kaWNlc1tudW1NYWpvckluZGljZXMgLSAxXTtcbiAgICBjb25zdCBuZXdUaWNrcyA9IFtdO1xuICAgIGlmIChudW1NYWpvckluZGljZXMgPiB0aWNrc0xpbWl0KSB7XG4gICAgICAgIHNraXBNYWpvcnModGlja3MsIG5ld1RpY2tzLCBtYWpvckluZGljZXMsIG51bU1ham9ySW5kaWNlcyAvIHRpY2tzTGltaXQpO1xuICAgICAgICByZXR1cm4gbmV3VGlja3M7XG4gICAgfVxuICAgIGNvbnN0IHNwYWNpbmcgPSBjYWxjdWxhdGVTcGFjaW5nKG1ham9ySW5kaWNlcywgdGlja3MsIHRpY2tzTGltaXQpO1xuICAgIGlmIChudW1NYWpvckluZGljZXMgPiAwKSB7XG4gICAgICAgIGxldCBpLCBpbGVuO1xuICAgICAgICBjb25zdCBhdmdNYWpvclNwYWNpbmcgPSBudW1NYWpvckluZGljZXMgPiAxID8gTWF0aC5yb3VuZCgobGFzdCAtIGZpcnN0KSAvIChudW1NYWpvckluZGljZXMgLSAxKSkgOiBudWxsO1xuICAgICAgICBza2lwKHRpY2tzLCBuZXdUaWNrcywgc3BhY2luZywgaXNOdWxsT3JVbmRlZihhdmdNYWpvclNwYWNpbmcpID8gMCA6IGZpcnN0IC0gYXZnTWFqb3JTcGFjaW5nLCBmaXJzdCk7XG4gICAgICAgIGZvcihpID0gMCwgaWxlbiA9IG51bU1ham9ySW5kaWNlcyAtIDE7IGkgPCBpbGVuOyBpKyspe1xuICAgICAgICAgICAgc2tpcCh0aWNrcywgbmV3VGlja3MsIHNwYWNpbmcsIG1ham9ySW5kaWNlc1tpXSwgbWFqb3JJbmRpY2VzW2kgKyAxXSk7XG4gICAgICAgIH1cbiAgICAgICAgc2tpcCh0aWNrcywgbmV3VGlja3MsIHNwYWNpbmcsIGxhc3QsIGlzTnVsbE9yVW5kZWYoYXZnTWFqb3JTcGFjaW5nKSA/IHRpY2tzLmxlbmd0aCA6IGxhc3QgKyBhdmdNYWpvclNwYWNpbmcpO1xuICAgICAgICByZXR1cm4gbmV3VGlja3M7XG4gICAgfVxuICAgIHNraXAodGlja3MsIG5ld1RpY2tzLCBzcGFjaW5nKTtcbiAgICByZXR1cm4gbmV3VGlja3M7XG59XG5mdW5jdGlvbiBkZXRlcm1pbmVNYXhUaWNrcyhzY2FsZSkge1xuICAgIGNvbnN0IG9mZnNldCA9IHNjYWxlLm9wdGlvbnMub2Zmc2V0O1xuICAgIGNvbnN0IHRpY2tMZW5ndGggPSBzY2FsZS5fdGlja1NpemUoKTtcbiAgICBjb25zdCBtYXhTY2FsZSA9IHNjYWxlLl9sZW5ndGggLyB0aWNrTGVuZ3RoICsgKG9mZnNldCA/IDAgOiAxKTtcbiAgICBjb25zdCBtYXhDaGFydCA9IHNjYWxlLl9tYXhMZW5ndGggLyB0aWNrTGVuZ3RoO1xuICAgIHJldHVybiBNYXRoLmZsb29yKE1hdGgubWluKG1heFNjYWxlLCBtYXhDaGFydCkpO1xufVxuIGZ1bmN0aW9uIGNhbGN1bGF0ZVNwYWNpbmcobWFqb3JJbmRpY2VzLCB0aWNrcywgdGlja3NMaW1pdCkge1xuICAgIGNvbnN0IGV2ZW5NYWpvclNwYWNpbmcgPSBnZXRFdmVuU3BhY2luZyhtYWpvckluZGljZXMpO1xuICAgIGNvbnN0IHNwYWNpbmcgPSB0aWNrcy5sZW5ndGggLyB0aWNrc0xpbWl0O1xuICAgIGlmICghZXZlbk1ham9yU3BhY2luZykge1xuICAgICAgICByZXR1cm4gTWF0aC5tYXgoc3BhY2luZywgMSk7XG4gICAgfVxuICAgIGNvbnN0IGZhY3RvcnMgPSBfZmFjdG9yaXplKGV2ZW5NYWpvclNwYWNpbmcpO1xuICAgIGZvcihsZXQgaSA9IDAsIGlsZW4gPSBmYWN0b3JzLmxlbmd0aCAtIDE7IGkgPCBpbGVuOyBpKyspe1xuICAgICAgICBjb25zdCBmYWN0b3IgPSBmYWN0b3JzW2ldO1xuICAgICAgICBpZiAoZmFjdG9yID4gc3BhY2luZykge1xuICAgICAgICAgICAgcmV0dXJuIGZhY3RvcjtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gTWF0aC5tYXgoc3BhY2luZywgMSk7XG59XG4gZnVuY3Rpb24gZ2V0TWFqb3JJbmRpY2VzKHRpY2tzKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgbGV0IGksIGlsZW47XG4gICAgZm9yKGkgPSAwLCBpbGVuID0gdGlja3MubGVuZ3RoOyBpIDwgaWxlbjsgaSsrKXtcbiAgICAgICAgaWYgKHRpY2tzW2ldLm1ham9yKSB7XG4gICAgICAgICAgICByZXN1bHQucHVzaChpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuIGZ1bmN0aW9uIHNraXBNYWpvcnModGlja3MsIG5ld1RpY2tzLCBtYWpvckluZGljZXMsIHNwYWNpbmcpIHtcbiAgICBsZXQgY291bnQgPSAwO1xuICAgIGxldCBuZXh0ID0gbWFqb3JJbmRpY2VzWzBdO1xuICAgIGxldCBpO1xuICAgIHNwYWNpbmcgPSBNYXRoLmNlaWwoc3BhY2luZyk7XG4gICAgZm9yKGkgPSAwOyBpIDwgdGlja3MubGVuZ3RoOyBpKyspe1xuICAgICAgICBpZiAoaSA9PT0gbmV4dCkge1xuICAgICAgICAgICAgbmV3VGlja3MucHVzaCh0aWNrc1tpXSk7XG4gICAgICAgICAgICBjb3VudCsrO1xuICAgICAgICAgICAgbmV4dCA9IG1ham9ySW5kaWNlc1tjb3VudCAqIHNwYWNpbmddO1xuICAgICAgICB9XG4gICAgfVxufVxuIGZ1bmN0aW9uIHNraXAodGlja3MsIG5ld1RpY2tzLCBzcGFjaW5nLCBtYWpvclN0YXJ0LCBtYWpvckVuZCkge1xuICAgIGNvbnN0IHN0YXJ0ID0gdmFsdWVPckRlZmF1bHQobWFqb3JTdGFydCwgMCk7XG4gICAgY29uc3QgZW5kID0gTWF0aC5taW4odmFsdWVPckRlZmF1bHQobWFqb3JFbmQsIHRpY2tzLmxlbmd0aCksIHRpY2tzLmxlbmd0aCk7XG4gICAgbGV0IGNvdW50ID0gMDtcbiAgICBsZXQgbGVuZ3RoLCBpLCBuZXh0O1xuICAgIHNwYWNpbmcgPSBNYXRoLmNlaWwoc3BhY2luZyk7XG4gICAgaWYgKG1ham9yRW5kKSB7XG4gICAgICAgIGxlbmd0aCA9IG1ham9yRW5kIC0gbWFqb3JTdGFydDtcbiAgICAgICAgc3BhY2luZyA9IGxlbmd0aCAvIE1hdGguZmxvb3IobGVuZ3RoIC8gc3BhY2luZyk7XG4gICAgfVxuICAgIG5leHQgPSBzdGFydDtcbiAgICB3aGlsZShuZXh0IDwgMCl7XG4gICAgICAgIGNvdW50Kys7XG4gICAgICAgIG5leHQgPSBNYXRoLnJvdW5kKHN0YXJ0ICsgY291bnQgKiBzcGFjaW5nKTtcbiAgICB9XG4gICAgZm9yKGkgPSBNYXRoLm1heChzdGFydCwgMCk7IGkgPCBlbmQ7IGkrKyl7XG4gICAgICAgIGlmIChpID09PSBuZXh0KSB7XG4gICAgICAgICAgICBuZXdUaWNrcy5wdXNoKHRpY2tzW2ldKTtcbiAgICAgICAgICAgIGNvdW50Kys7XG4gICAgICAgICAgICBuZXh0ID0gTWF0aC5yb3VuZChzdGFydCArIGNvdW50ICogc3BhY2luZyk7XG4gICAgICAgIH1cbiAgICB9XG59XG4gZnVuY3Rpb24gZ2V0RXZlblNwYWNpbmcoYXJyKSB7XG4gICAgY29uc3QgbGVuID0gYXJyLmxlbmd0aDtcbiAgICBsZXQgaSwgZGlmZjtcbiAgICBpZiAobGVuIDwgMikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZvcihkaWZmID0gYXJyWzBdLCBpID0gMTsgaSA8IGxlbjsgKytpKXtcbiAgICAgICAgaWYgKGFycltpXSAtIGFycltpIC0gMV0gIT09IGRpZmYpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGlmZjtcbn1cblxuY29uc3QgcmV2ZXJzZUFsaWduID0gKGFsaWduKT0+YWxpZ24gPT09ICdsZWZ0JyA/ICdyaWdodCcgOiBhbGlnbiA9PT0gJ3JpZ2h0JyA/ICdsZWZ0JyA6IGFsaWduO1xuY29uc3Qgb2Zmc2V0RnJvbUVkZ2UgPSAoc2NhbGUsIGVkZ2UsIG9mZnNldCk9PmVkZ2UgPT09ICd0b3AnIHx8IGVkZ2UgPT09ICdsZWZ0JyA/IHNjYWxlW2VkZ2VdICsgb2Zmc2V0IDogc2NhbGVbZWRnZV0gLSBvZmZzZXQ7XG5jb25zdCBnZXRUaWNrc0xpbWl0ID0gKHRpY2tzTGVuZ3RoLCBtYXhUaWNrc0xpbWl0KT0+TWF0aC5taW4obWF4VGlja3NMaW1pdCB8fCB0aWNrc0xlbmd0aCwgdGlja3NMZW5ndGgpO1xuIGZ1bmN0aW9uIHNhbXBsZShhcnIsIG51bUl0ZW1zKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgY29uc3QgaW5jcmVtZW50ID0gYXJyLmxlbmd0aCAvIG51bUl0ZW1zO1xuICAgIGNvbnN0IGxlbiA9IGFyci5sZW5ndGg7XG4gICAgbGV0IGkgPSAwO1xuICAgIGZvcig7IGkgPCBsZW47IGkgKz0gaW5jcmVtZW50KXtcbiAgICAgICAgcmVzdWx0LnB1c2goYXJyW01hdGguZmxvb3IoaSldKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbiBmdW5jdGlvbiBnZXRQaXhlbEZvckdyaWRMaW5lKHNjYWxlLCBpbmRleCwgb2Zmc2V0R3JpZExpbmVzKSB7XG4gICAgY29uc3QgbGVuZ3RoID0gc2NhbGUudGlja3MubGVuZ3RoO1xuICAgIGNvbnN0IHZhbGlkSW5kZXggPSBNYXRoLm1pbihpbmRleCwgbGVuZ3RoIC0gMSk7XG4gICAgY29uc3Qgc3RhcnQgPSBzY2FsZS5fc3RhcnRQaXhlbDtcbiAgICBjb25zdCBlbmQgPSBzY2FsZS5fZW5kUGl4ZWw7XG4gICAgY29uc3QgZXBzaWxvbiA9IDFlLTY7XG4gICAgbGV0IGxpbmVWYWx1ZSA9IHNjYWxlLmdldFBpeGVsRm9yVGljayh2YWxpZEluZGV4KTtcbiAgICBsZXQgb2Zmc2V0O1xuICAgIGlmIChvZmZzZXRHcmlkTGluZXMpIHtcbiAgICAgICAgaWYgKGxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgb2Zmc2V0ID0gTWF0aC5tYXgobGluZVZhbHVlIC0gc3RhcnQsIGVuZCAtIGxpbmVWYWx1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICAgIG9mZnNldCA9IChzY2FsZS5nZXRQaXhlbEZvclRpY2soMSkgLSBsaW5lVmFsdWUpIC8gMjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG9mZnNldCA9IChsaW5lVmFsdWUgLSBzY2FsZS5nZXRQaXhlbEZvclRpY2sodmFsaWRJbmRleCAtIDEpKSAvIDI7XG4gICAgICAgIH1cbiAgICAgICAgbGluZVZhbHVlICs9IHZhbGlkSW5kZXggPCBpbmRleCA/IG9mZnNldCA6IC1vZmZzZXQ7XG4gICAgICAgIGlmIChsaW5lVmFsdWUgPCBzdGFydCAtIGVwc2lsb24gfHwgbGluZVZhbHVlID4gZW5kICsgZXBzaWxvbikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBsaW5lVmFsdWU7XG59XG4gZnVuY3Rpb24gZ2FyYmFnZUNvbGxlY3QoY2FjaGVzLCBsZW5ndGgpIHtcbiAgICBlYWNoKGNhY2hlcywgKGNhY2hlKT0+e1xuICAgICAgICBjb25zdCBnYyA9IGNhY2hlLmdjO1xuICAgICAgICBjb25zdCBnY0xlbiA9IGdjLmxlbmd0aCAvIDI7XG4gICAgICAgIGxldCBpO1xuICAgICAgICBpZiAoZ2NMZW4gPiBsZW5ndGgpIHtcbiAgICAgICAgICAgIGZvcihpID0gMDsgaSA8IGdjTGVuOyArK2kpe1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBjYWNoZS5kYXRhW2djW2ldXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGdjLnNwbGljZSgwLCBnY0xlbik7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbiBmdW5jdGlvbiBnZXRUaWNrTWFya0xlbmd0aChvcHRpb25zKSB7XG4gICAgcmV0dXJuIG9wdGlvbnMuZHJhd1RpY2tzID8gb3B0aW9ucy50aWNrTGVuZ3RoIDogMDtcbn1cbiBmdW5jdGlvbiBnZXRUaXRsZUhlaWdodChvcHRpb25zLCBmYWxsYmFjaykge1xuICAgIGlmICghb3B0aW9ucy5kaXNwbGF5KSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBjb25zdCBmb250ID0gdG9Gb250KG9wdGlvbnMuZm9udCwgZmFsbGJhY2spO1xuICAgIGNvbnN0IHBhZGRpbmcgPSB0b1BhZGRpbmcob3B0aW9ucy5wYWRkaW5nKTtcbiAgICBjb25zdCBsaW5lcyA9IGlzQXJyYXkob3B0aW9ucy50ZXh0KSA/IG9wdGlvbnMudGV4dC5sZW5ndGggOiAxO1xuICAgIHJldHVybiBsaW5lcyAqIGZvbnQubGluZUhlaWdodCArIHBhZGRpbmcuaGVpZ2h0O1xufVxuZnVuY3Rpb24gY3JlYXRlU2NhbGVDb250ZXh0KHBhcmVudCwgc2NhbGUpIHtcbiAgICByZXR1cm4gY3JlYXRlQ29udGV4dChwYXJlbnQsIHtcbiAgICAgICAgc2NhbGUsXG4gICAgICAgIHR5cGU6ICdzY2FsZSdcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIGNyZWF0ZVRpY2tDb250ZXh0KHBhcmVudCwgaW5kZXgsIHRpY2spIHtcbiAgICByZXR1cm4gY3JlYXRlQ29udGV4dChwYXJlbnQsIHtcbiAgICAgICAgdGljayxcbiAgICAgICAgaW5kZXgsXG4gICAgICAgIHR5cGU6ICd0aWNrJ1xuICAgIH0pO1xufVxuZnVuY3Rpb24gdGl0bGVBbGlnbihhbGlnbiwgcG9zaXRpb24sIHJldmVyc2UpIHtcbiAgICAgbGV0IHJldCA9IF90b0xlZnRSaWdodENlbnRlcihhbGlnbik7XG4gICAgaWYgKHJldmVyc2UgJiYgcG9zaXRpb24gIT09ICdyaWdodCcgfHwgIXJldmVyc2UgJiYgcG9zaXRpb24gPT09ICdyaWdodCcpIHtcbiAgICAgICAgcmV0ID0gcmV2ZXJzZUFsaWduKHJldCk7XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG59XG5mdW5jdGlvbiB0aXRsZUFyZ3Moc2NhbGUsIG9mZnNldCwgcG9zaXRpb24sIGFsaWduKSB7XG4gICAgY29uc3QgeyB0b3AgLCBsZWZ0ICwgYm90dG9tICwgcmlnaHQgLCBjaGFydCAgfSA9IHNjYWxlO1xuICAgIGNvbnN0IHsgY2hhcnRBcmVhICwgc2NhbGVzICB9ID0gY2hhcnQ7XG4gICAgbGV0IHJvdGF0aW9uID0gMDtcbiAgICBsZXQgbWF4V2lkdGgsIHRpdGxlWCwgdGl0bGVZO1xuICAgIGNvbnN0IGhlaWdodCA9IGJvdHRvbSAtIHRvcDtcbiAgICBjb25zdCB3aWR0aCA9IHJpZ2h0IC0gbGVmdDtcbiAgICBpZiAoc2NhbGUuaXNIb3Jpem9udGFsKCkpIHtcbiAgICAgICAgdGl0bGVYID0gX2FsaWduU3RhcnRFbmQoYWxpZ24sIGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKGlzT2JqZWN0KHBvc2l0aW9uKSkge1xuICAgICAgICAgICAgY29uc3QgcG9zaXRpb25BeGlzSUQgPSBPYmplY3Qua2V5cyhwb3NpdGlvbilbMF07XG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHBvc2l0aW9uW3Bvc2l0aW9uQXhpc0lEXTtcbiAgICAgICAgICAgIHRpdGxlWSA9IHNjYWxlc1twb3NpdGlvbkF4aXNJRF0uZ2V0UGl4ZWxGb3JWYWx1ZSh2YWx1ZSkgKyBoZWlnaHQgLSBvZmZzZXQ7XG4gICAgICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPT09ICdjZW50ZXInKSB7XG4gICAgICAgICAgICB0aXRsZVkgPSAoY2hhcnRBcmVhLmJvdHRvbSArIGNoYXJ0QXJlYS50b3ApIC8gMiArIGhlaWdodCAtIG9mZnNldDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRpdGxlWSA9IG9mZnNldEZyb21FZGdlKHNjYWxlLCBwb3NpdGlvbiwgb2Zmc2V0KTtcbiAgICAgICAgfVxuICAgICAgICBtYXhXaWR0aCA9IHJpZ2h0IC0gbGVmdDtcbiAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoaXNPYmplY3QocG9zaXRpb24pKSB7XG4gICAgICAgICAgICBjb25zdCBwb3NpdGlvbkF4aXNJRCA9IE9iamVjdC5rZXlzKHBvc2l0aW9uKVswXTtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gcG9zaXRpb25bcG9zaXRpb25BeGlzSURdO1xuICAgICAgICAgICAgdGl0bGVYID0gc2NhbGVzW3Bvc2l0aW9uQXhpc0lEXS5nZXRQaXhlbEZvclZhbHVlKHZhbHVlKSAtIHdpZHRoICsgb2Zmc2V0O1xuICAgICAgICB9IGVsc2UgaWYgKHBvc2l0aW9uID09PSAnY2VudGVyJykge1xuICAgICAgICAgICAgdGl0bGVYID0gKGNoYXJ0QXJlYS5sZWZ0ICsgY2hhcnRBcmVhLnJpZ2h0KSAvIDIgLSB3aWR0aCArIG9mZnNldDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRpdGxlWCA9IG9mZnNldEZyb21FZGdlKHNjYWxlLCBwb3NpdGlvbiwgb2Zmc2V0KTtcbiAgICAgICAgfVxuICAgICAgICB0aXRsZVkgPSBfYWxpZ25TdGFydEVuZChhbGlnbiwgYm90dG9tLCB0b3ApO1xuICAgICAgICByb3RhdGlvbiA9IHBvc2l0aW9uID09PSAnbGVmdCcgPyAtSEFMRl9QSSA6IEhBTEZfUEk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHRpdGxlWCxcbiAgICAgICAgdGl0bGVZLFxuICAgICAgICBtYXhXaWR0aCxcbiAgICAgICAgcm90YXRpb25cbiAgICB9O1xufVxuY2xhc3MgU2NhbGUgZXh0ZW5kcyBFbGVtZW50IHtcbiAgICBjb25zdHJ1Y3RvcihjZmcpe1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICAgdGhpcy5pZCA9IGNmZy5pZDtcbiAgICAgICAgIHRoaXMudHlwZSA9IGNmZy50eXBlO1xuICAgICAgICAgdGhpcy5vcHRpb25zID0gdW5kZWZpbmVkO1xuICAgICAgICAgdGhpcy5jdHggPSBjZmcuY3R4O1xuICAgICAgICAgdGhpcy5jaGFydCA9IGNmZy5jaGFydDtcbiAgICAgICAgIHRoaXMudG9wID0gdW5kZWZpbmVkO1xuICAgICAgICAgdGhpcy5ib3R0b20gPSB1bmRlZmluZWQ7XG4gICAgICAgICB0aGlzLmxlZnQgPSB1bmRlZmluZWQ7XG4gICAgICAgICB0aGlzLnJpZ2h0ID0gdW5kZWZpbmVkO1xuICAgICAgICAgdGhpcy53aWR0aCA9IHVuZGVmaW5lZDtcbiAgICAgICAgIHRoaXMuaGVpZ2h0ID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl9tYXJnaW5zID0ge1xuICAgICAgICAgICAgbGVmdDogMCxcbiAgICAgICAgICAgIHJpZ2h0OiAwLFxuICAgICAgICAgICAgdG9wOiAwLFxuICAgICAgICAgICAgYm90dG9tOiAwXG4gICAgICAgIH07XG4gICAgICAgICB0aGlzLm1heFdpZHRoID0gdW5kZWZpbmVkO1xuICAgICAgICAgdGhpcy5tYXhIZWlnaHQgPSB1bmRlZmluZWQ7XG4gICAgICAgICB0aGlzLnBhZGRpbmdUb3AgPSB1bmRlZmluZWQ7XG4gICAgICAgICB0aGlzLnBhZGRpbmdCb3R0b20gPSB1bmRlZmluZWQ7XG4gICAgICAgICB0aGlzLnBhZGRpbmdMZWZ0ID0gdW5kZWZpbmVkO1xuICAgICAgICAgdGhpcy5wYWRkaW5nUmlnaHQgPSB1bmRlZmluZWQ7XG4gICAgICAgICB0aGlzLmF4aXMgPSB1bmRlZmluZWQ7XG4gICAgICAgICB0aGlzLmxhYmVsUm90YXRpb24gPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMubWluID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLm1heCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fcmFuZ2UgPSB1bmRlZmluZWQ7XG4gICAgICAgICB0aGlzLnRpY2tzID0gW107XG4gICAgICAgICB0aGlzLl9ncmlkTGluZUl0ZW1zID0gbnVsbDtcbiAgICAgICAgIHRoaXMuX2xhYmVsSXRlbXMgPSBudWxsO1xuICAgICAgICAgdGhpcy5fbGFiZWxTaXplcyA9IG51bGw7XG4gICAgICAgIHRoaXMuX2xlbmd0aCA9IDA7XG4gICAgICAgIHRoaXMuX21heExlbmd0aCA9IDA7XG4gICAgICAgIHRoaXMuX2xvbmdlc3RUZXh0Q2FjaGUgPSB7fTtcbiAgICAgICAgIHRoaXMuX3N0YXJ0UGl4ZWwgPSB1bmRlZmluZWQ7XG4gICAgICAgICB0aGlzLl9lbmRQaXhlbCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fcmV2ZXJzZVBpeGVscyA9IGZhbHNlO1xuICAgICAgICB0aGlzLl91c2VyTWF4ID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl91c2VyTWluID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl9zdWdnZXN0ZWRNYXggPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuX3N1Z2dlc3RlZE1pbiA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fdGlja3NMZW5ndGggPSAwO1xuICAgICAgICB0aGlzLl9ib3JkZXJWYWx1ZSA9IDA7XG4gICAgICAgIHRoaXMuX2NhY2hlID0ge307XG4gICAgICAgIHRoaXMuX2RhdGFMaW1pdHNDYWNoZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy4kY29udGV4dCA9IHVuZGVmaW5lZDtcbiAgICB9XG4gaW5pdChvcHRpb25zKSB7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnMuc2V0Q29udGV4dCh0aGlzLmdldENvbnRleHQoKSk7XG4gICAgICAgIHRoaXMuYXhpcyA9IG9wdGlvbnMuYXhpcztcbiAgICAgICAgdGhpcy5fdXNlck1pbiA9IHRoaXMucGFyc2Uob3B0aW9ucy5taW4pO1xuICAgICAgICB0aGlzLl91c2VyTWF4ID0gdGhpcy5wYXJzZShvcHRpb25zLm1heCk7XG4gICAgICAgIHRoaXMuX3N1Z2dlc3RlZE1pbiA9IHRoaXMucGFyc2Uob3B0aW9ucy5zdWdnZXN0ZWRNaW4pO1xuICAgICAgICB0aGlzLl9zdWdnZXN0ZWRNYXggPSB0aGlzLnBhcnNlKG9wdGlvbnMuc3VnZ2VzdGVkTWF4KTtcbiAgICB9XG4gcGFyc2UocmF3LCBpbmRleCkge1xuICAgICAgICByZXR1cm4gcmF3O1xuICAgIH1cbiBnZXRVc2VyQm91bmRzKCkge1xuICAgICAgICBsZXQgeyBfdXNlck1pbiAsIF91c2VyTWF4ICwgX3N1Z2dlc3RlZE1pbiAsIF9zdWdnZXN0ZWRNYXggIH0gPSB0aGlzO1xuICAgICAgICBfdXNlck1pbiA9IGZpbml0ZU9yRGVmYXVsdChfdXNlck1pbiwgTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZKTtcbiAgICAgICAgX3VzZXJNYXggPSBmaW5pdGVPckRlZmF1bHQoX3VzZXJNYXgsIE51bWJlci5ORUdBVElWRV9JTkZJTklUWSk7XG4gICAgICAgIF9zdWdnZXN0ZWRNaW4gPSBmaW5pdGVPckRlZmF1bHQoX3N1Z2dlc3RlZE1pbiwgTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZKTtcbiAgICAgICAgX3N1Z2dlc3RlZE1heCA9IGZpbml0ZU9yRGVmYXVsdChfc3VnZ2VzdGVkTWF4LCBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFkpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbWluOiBmaW5pdGVPckRlZmF1bHQoX3VzZXJNaW4sIF9zdWdnZXN0ZWRNaW4pLFxuICAgICAgICAgICAgbWF4OiBmaW5pdGVPckRlZmF1bHQoX3VzZXJNYXgsIF9zdWdnZXN0ZWRNYXgpLFxuICAgICAgICAgICAgbWluRGVmaW5lZDogaXNOdW1iZXJGaW5pdGUoX3VzZXJNaW4pLFxuICAgICAgICAgICAgbWF4RGVmaW5lZDogaXNOdW1iZXJGaW5pdGUoX3VzZXJNYXgpXG4gICAgICAgIH07XG4gICAgfVxuIGdldE1pbk1heChjYW5TdGFjaykge1xuICAgICAgICBsZXQgeyBtaW4gLCBtYXggLCBtaW5EZWZpbmVkICwgbWF4RGVmaW5lZCAgfSA9IHRoaXMuZ2V0VXNlckJvdW5kcygpO1xuICAgICAgICBsZXQgcmFuZ2U7XG4gICAgICAgIGlmIChtaW5EZWZpbmVkICYmIG1heERlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgbWluLFxuICAgICAgICAgICAgICAgIG1heFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBtZXRhcyA9IHRoaXMuZ2V0TWF0Y2hpbmdWaXNpYmxlTWV0YXMoKTtcbiAgICAgICAgZm9yKGxldCBpID0gMCwgaWxlbiA9IG1ldGFzLmxlbmd0aDsgaSA8IGlsZW47ICsraSl7XG4gICAgICAgICAgICByYW5nZSA9IG1ldGFzW2ldLmNvbnRyb2xsZXIuZ2V0TWluTWF4KHRoaXMsIGNhblN0YWNrKTtcbiAgICAgICAgICAgIGlmICghbWluRGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIG1pbiA9IE1hdGgubWluKG1pbiwgcmFuZ2UubWluKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghbWF4RGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIG1heCA9IE1hdGgubWF4KG1heCwgcmFuZ2UubWF4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBtaW4gPSBtYXhEZWZpbmVkICYmIG1pbiA+IG1heCA/IG1heCA6IG1pbjtcbiAgICAgICAgbWF4ID0gbWluRGVmaW5lZCAmJiBtaW4gPiBtYXggPyBtaW4gOiBtYXg7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBtaW46IGZpbml0ZU9yRGVmYXVsdChtaW4sIGZpbml0ZU9yRGVmYXVsdChtYXgsIG1pbikpLFxuICAgICAgICAgICAgbWF4OiBmaW5pdGVPckRlZmF1bHQobWF4LCBmaW5pdGVPckRlZmF1bHQobWluLCBtYXgpKVxuICAgICAgICB9O1xuICAgIH1cbiBnZXRQYWRkaW5nKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbGVmdDogdGhpcy5wYWRkaW5nTGVmdCB8fCAwLFxuICAgICAgICAgICAgdG9wOiB0aGlzLnBhZGRpbmdUb3AgfHwgMCxcbiAgICAgICAgICAgIHJpZ2h0OiB0aGlzLnBhZGRpbmdSaWdodCB8fCAwLFxuICAgICAgICAgICAgYm90dG9tOiB0aGlzLnBhZGRpbmdCb3R0b20gfHwgMFxuICAgICAgICB9O1xuICAgIH1cbiBnZXRUaWNrcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGlja3M7XG4gICAgfVxuIGdldExhYmVscygpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IHRoaXMuY2hhcnQuZGF0YTtcbiAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy5sYWJlbHMgfHwgKHRoaXMuaXNIb3Jpem9udGFsKCkgPyBkYXRhLnhMYWJlbHMgOiBkYXRhLnlMYWJlbHMpIHx8IGRhdGEubGFiZWxzIHx8IFtdO1xuICAgIH1cbiBnZXRMYWJlbEl0ZW1zKGNoYXJ0QXJlYSA9IHRoaXMuY2hhcnQuY2hhcnRBcmVhKSB7XG4gICAgICAgIGNvbnN0IGl0ZW1zID0gdGhpcy5fbGFiZWxJdGVtcyB8fCAodGhpcy5fbGFiZWxJdGVtcyA9IHRoaXMuX2NvbXB1dGVMYWJlbEl0ZW1zKGNoYXJ0QXJlYSkpO1xuICAgICAgICByZXR1cm4gaXRlbXM7XG4gICAgfVxuICAgIGJlZm9yZUxheW91dCgpIHtcbiAgICAgICAgdGhpcy5fY2FjaGUgPSB7fTtcbiAgICAgICAgdGhpcy5fZGF0YUxpbWl0c0NhY2hlZCA9IGZhbHNlO1xuICAgIH1cbiAgICBiZWZvcmVVcGRhdGUoKSB7XG4gICAgICAgIGNhbGxiYWNrKHRoaXMub3B0aW9ucy5iZWZvcmVVcGRhdGUsIFtcbiAgICAgICAgICAgIHRoaXNcbiAgICAgICAgXSk7XG4gICAgfVxuIHVwZGF0ZShtYXhXaWR0aCwgbWF4SGVpZ2h0LCBtYXJnaW5zKSB7XG4gICAgICAgIGNvbnN0IHsgYmVnaW5BdFplcm8gLCBncmFjZSAsIHRpY2tzOiB0aWNrT3B0cyAgfSA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgY29uc3Qgc2FtcGxlU2l6ZSA9IHRpY2tPcHRzLnNhbXBsZVNpemU7XG4gICAgICAgIHRoaXMuYmVmb3JlVXBkYXRlKCk7XG4gICAgICAgIHRoaXMubWF4V2lkdGggPSBtYXhXaWR0aDtcbiAgICAgICAgdGhpcy5tYXhIZWlnaHQgPSBtYXhIZWlnaHQ7XG4gICAgICAgIHRoaXMuX21hcmdpbnMgPSBtYXJnaW5zID0gT2JqZWN0LmFzc2lnbih7XG4gICAgICAgICAgICBsZWZ0OiAwLFxuICAgICAgICAgICAgcmlnaHQ6IDAsXG4gICAgICAgICAgICB0b3A6IDAsXG4gICAgICAgICAgICBib3R0b206IDBcbiAgICAgICAgfSwgbWFyZ2lucyk7XG4gICAgICAgIHRoaXMudGlja3MgPSBudWxsO1xuICAgICAgICB0aGlzLl9sYWJlbFNpemVzID0gbnVsbDtcbiAgICAgICAgdGhpcy5fZ3JpZExpbmVJdGVtcyA9IG51bGw7XG4gICAgICAgIHRoaXMuX2xhYmVsSXRlbXMgPSBudWxsO1xuICAgICAgICB0aGlzLmJlZm9yZVNldERpbWVuc2lvbnMoKTtcbiAgICAgICAgdGhpcy5zZXREaW1lbnNpb25zKCk7XG4gICAgICAgIHRoaXMuYWZ0ZXJTZXREaW1lbnNpb25zKCk7XG4gICAgICAgIHRoaXMuX21heExlbmd0aCA9IHRoaXMuaXNIb3Jpem9udGFsKCkgPyB0aGlzLndpZHRoICsgbWFyZ2lucy5sZWZ0ICsgbWFyZ2lucy5yaWdodCA6IHRoaXMuaGVpZ2h0ICsgbWFyZ2lucy50b3AgKyBtYXJnaW5zLmJvdHRvbTtcbiAgICAgICAgaWYgKCF0aGlzLl9kYXRhTGltaXRzQ2FjaGVkKSB7XG4gICAgICAgICAgICB0aGlzLmJlZm9yZURhdGFMaW1pdHMoKTtcbiAgICAgICAgICAgIHRoaXMuZGV0ZXJtaW5lRGF0YUxpbWl0cygpO1xuICAgICAgICAgICAgdGhpcy5hZnRlckRhdGFMaW1pdHMoKTtcbiAgICAgICAgICAgIHRoaXMuX3JhbmdlID0gX2FkZEdyYWNlKHRoaXMsIGdyYWNlLCBiZWdpbkF0WmVybyk7XG4gICAgICAgICAgICB0aGlzLl9kYXRhTGltaXRzQ2FjaGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmJlZm9yZUJ1aWxkVGlja3MoKTtcbiAgICAgICAgdGhpcy50aWNrcyA9IHRoaXMuYnVpbGRUaWNrcygpIHx8IFtdO1xuICAgICAgICB0aGlzLmFmdGVyQnVpbGRUaWNrcygpO1xuICAgICAgICBjb25zdCBzYW1wbGluZ0VuYWJsZWQgPSBzYW1wbGVTaXplIDwgdGhpcy50aWNrcy5sZW5ndGg7XG4gICAgICAgIHRoaXMuX2NvbnZlcnRUaWNrc1RvTGFiZWxzKHNhbXBsaW5nRW5hYmxlZCA/IHNhbXBsZSh0aGlzLnRpY2tzLCBzYW1wbGVTaXplKSA6IHRoaXMudGlja3MpO1xuICAgICAgICB0aGlzLmNvbmZpZ3VyZSgpO1xuICAgICAgICB0aGlzLmJlZm9yZUNhbGN1bGF0ZUxhYmVsUm90YXRpb24oKTtcbiAgICAgICAgdGhpcy5jYWxjdWxhdGVMYWJlbFJvdGF0aW9uKCk7XG4gICAgICAgIHRoaXMuYWZ0ZXJDYWxjdWxhdGVMYWJlbFJvdGF0aW9uKCk7XG4gICAgICAgIGlmICh0aWNrT3B0cy5kaXNwbGF5ICYmICh0aWNrT3B0cy5hdXRvU2tpcCB8fCB0aWNrT3B0cy5zb3VyY2UgPT09ICdhdXRvJykpIHtcbiAgICAgICAgICAgIHRoaXMudGlja3MgPSBhdXRvU2tpcCh0aGlzLCB0aGlzLnRpY2tzKTtcbiAgICAgICAgICAgIHRoaXMuX2xhYmVsU2l6ZXMgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5hZnRlckF1dG9Ta2lwKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNhbXBsaW5nRW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5fY29udmVydFRpY2tzVG9MYWJlbHModGhpcy50aWNrcyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5iZWZvcmVGaXQoKTtcbiAgICAgICAgdGhpcy5maXQoKTtcbiAgICAgICAgdGhpcy5hZnRlckZpdCgpO1xuICAgICAgICB0aGlzLmFmdGVyVXBkYXRlKCk7XG4gICAgfVxuIGNvbmZpZ3VyZSgpIHtcbiAgICAgICAgbGV0IHJldmVyc2VQaXhlbHMgPSB0aGlzLm9wdGlvbnMucmV2ZXJzZTtcbiAgICAgICAgbGV0IHN0YXJ0UGl4ZWwsIGVuZFBpeGVsO1xuICAgICAgICBpZiAodGhpcy5pc0hvcml6b250YWwoKSkge1xuICAgICAgICAgICAgc3RhcnRQaXhlbCA9IHRoaXMubGVmdDtcbiAgICAgICAgICAgIGVuZFBpeGVsID0gdGhpcy5yaWdodDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN0YXJ0UGl4ZWwgPSB0aGlzLnRvcDtcbiAgICAgICAgICAgIGVuZFBpeGVsID0gdGhpcy5ib3R0b207XG4gICAgICAgICAgICByZXZlcnNlUGl4ZWxzID0gIXJldmVyc2VQaXhlbHM7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc3RhcnRQaXhlbCA9IHN0YXJ0UGl4ZWw7XG4gICAgICAgIHRoaXMuX2VuZFBpeGVsID0gZW5kUGl4ZWw7XG4gICAgICAgIHRoaXMuX3JldmVyc2VQaXhlbHMgPSByZXZlcnNlUGl4ZWxzO1xuICAgICAgICB0aGlzLl9sZW5ndGggPSBlbmRQaXhlbCAtIHN0YXJ0UGl4ZWw7XG4gICAgICAgIHRoaXMuX2FsaWduVG9QaXhlbHMgPSB0aGlzLm9wdGlvbnMuYWxpZ25Ub1BpeGVscztcbiAgICB9XG4gICAgYWZ0ZXJVcGRhdGUoKSB7XG4gICAgICAgIGNhbGxiYWNrKHRoaXMub3B0aW9ucy5hZnRlclVwZGF0ZSwgW1xuICAgICAgICAgICAgdGhpc1xuICAgICAgICBdKTtcbiAgICB9XG4gICAgYmVmb3JlU2V0RGltZW5zaW9ucygpIHtcbiAgICAgICAgY2FsbGJhY2sodGhpcy5vcHRpb25zLmJlZm9yZVNldERpbWVuc2lvbnMsIFtcbiAgICAgICAgICAgIHRoaXNcbiAgICAgICAgXSk7XG4gICAgfVxuICAgIHNldERpbWVuc2lvbnMoKSB7XG4gICAgICAgIGlmICh0aGlzLmlzSG9yaXpvbnRhbCgpKSB7XG4gICAgICAgICAgICB0aGlzLndpZHRoID0gdGhpcy5tYXhXaWR0aDtcbiAgICAgICAgICAgIHRoaXMubGVmdCA9IDA7XG4gICAgICAgICAgICB0aGlzLnJpZ2h0ID0gdGhpcy53aWR0aDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gdGhpcy5tYXhIZWlnaHQ7XG4gICAgICAgICAgICB0aGlzLnRvcCA9IDA7XG4gICAgICAgICAgICB0aGlzLmJvdHRvbSA9IHRoaXMuaGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucGFkZGluZ0xlZnQgPSAwO1xuICAgICAgICB0aGlzLnBhZGRpbmdUb3AgPSAwO1xuICAgICAgICB0aGlzLnBhZGRpbmdSaWdodCA9IDA7XG4gICAgICAgIHRoaXMucGFkZGluZ0JvdHRvbSA9IDA7XG4gICAgfVxuICAgIGFmdGVyU2V0RGltZW5zaW9ucygpIHtcbiAgICAgICAgY2FsbGJhY2sodGhpcy5vcHRpb25zLmFmdGVyU2V0RGltZW5zaW9ucywgW1xuICAgICAgICAgICAgdGhpc1xuICAgICAgICBdKTtcbiAgICB9XG4gICAgX2NhbGxIb29rcyhuYW1lKSB7XG4gICAgICAgIHRoaXMuY2hhcnQubm90aWZ5UGx1Z2lucyhuYW1lLCB0aGlzLmdldENvbnRleHQoKSk7XG4gICAgICAgIGNhbGxiYWNrKHRoaXMub3B0aW9uc1tuYW1lXSwgW1xuICAgICAgICAgICAgdGhpc1xuICAgICAgICBdKTtcbiAgICB9XG4gICAgYmVmb3JlRGF0YUxpbWl0cygpIHtcbiAgICAgICAgdGhpcy5fY2FsbEhvb2tzKCdiZWZvcmVEYXRhTGltaXRzJyk7XG4gICAgfVxuICAgIGRldGVybWluZURhdGFMaW1pdHMoKSB7fVxuICAgIGFmdGVyRGF0YUxpbWl0cygpIHtcbiAgICAgICAgdGhpcy5fY2FsbEhvb2tzKCdhZnRlckRhdGFMaW1pdHMnKTtcbiAgICB9XG4gICAgYmVmb3JlQnVpbGRUaWNrcygpIHtcbiAgICAgICAgdGhpcy5fY2FsbEhvb2tzKCdiZWZvcmVCdWlsZFRpY2tzJyk7XG4gICAgfVxuIGJ1aWxkVGlja3MoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgYWZ0ZXJCdWlsZFRpY2tzKCkge1xuICAgICAgICB0aGlzLl9jYWxsSG9va3MoJ2FmdGVyQnVpbGRUaWNrcycpO1xuICAgIH1cbiAgICBiZWZvcmVUaWNrVG9MYWJlbENvbnZlcnNpb24oKSB7XG4gICAgICAgIGNhbGxiYWNrKHRoaXMub3B0aW9ucy5iZWZvcmVUaWNrVG9MYWJlbENvbnZlcnNpb24sIFtcbiAgICAgICAgICAgIHRoaXNcbiAgICAgICAgXSk7XG4gICAgfVxuIGdlbmVyYXRlVGlja0xhYmVscyh0aWNrcykge1xuICAgICAgICBjb25zdCB0aWNrT3B0cyA9IHRoaXMub3B0aW9ucy50aWNrcztcbiAgICAgICAgbGV0IGksIGlsZW4sIHRpY2s7XG4gICAgICAgIGZvcihpID0gMCwgaWxlbiA9IHRpY2tzLmxlbmd0aDsgaSA8IGlsZW47IGkrKyl7XG4gICAgICAgICAgICB0aWNrID0gdGlja3NbaV07XG4gICAgICAgICAgICB0aWNrLmxhYmVsID0gY2FsbGJhY2sodGlja09wdHMuY2FsbGJhY2ssIFtcbiAgICAgICAgICAgICAgICB0aWNrLnZhbHVlLFxuICAgICAgICAgICAgICAgIGksXG4gICAgICAgICAgICAgICAgdGlja3NcbiAgICAgICAgICAgIF0sIHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFmdGVyVGlja1RvTGFiZWxDb252ZXJzaW9uKCkge1xuICAgICAgICBjYWxsYmFjayh0aGlzLm9wdGlvbnMuYWZ0ZXJUaWNrVG9MYWJlbENvbnZlcnNpb24sIFtcbiAgICAgICAgICAgIHRoaXNcbiAgICAgICAgXSk7XG4gICAgfVxuICAgIGJlZm9yZUNhbGN1bGF0ZUxhYmVsUm90YXRpb24oKSB7XG4gICAgICAgIGNhbGxiYWNrKHRoaXMub3B0aW9ucy5iZWZvcmVDYWxjdWxhdGVMYWJlbFJvdGF0aW9uLCBbXG4gICAgICAgICAgICB0aGlzXG4gICAgICAgIF0pO1xuICAgIH1cbiAgICBjYWxjdWxhdGVMYWJlbFJvdGF0aW9uKCkge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBjb25zdCB0aWNrT3B0cyA9IG9wdGlvbnMudGlja3M7XG4gICAgICAgIGNvbnN0IG51bVRpY2tzID0gZ2V0VGlja3NMaW1pdCh0aGlzLnRpY2tzLmxlbmd0aCwgb3B0aW9ucy50aWNrcy5tYXhUaWNrc0xpbWl0KTtcbiAgICAgICAgY29uc3QgbWluUm90YXRpb24gPSB0aWNrT3B0cy5taW5Sb3RhdGlvbiB8fCAwO1xuICAgICAgICBjb25zdCBtYXhSb3RhdGlvbiA9IHRpY2tPcHRzLm1heFJvdGF0aW9uO1xuICAgICAgICBsZXQgbGFiZWxSb3RhdGlvbiA9IG1pblJvdGF0aW9uO1xuICAgICAgICBsZXQgdGlja1dpZHRoLCBtYXhIZWlnaHQsIG1heExhYmVsRGlhZ29uYWw7XG4gICAgICAgIGlmICghdGhpcy5faXNWaXNpYmxlKCkgfHwgIXRpY2tPcHRzLmRpc3BsYXkgfHwgbWluUm90YXRpb24gPj0gbWF4Um90YXRpb24gfHwgbnVtVGlja3MgPD0gMSB8fCAhdGhpcy5pc0hvcml6b250YWwoKSkge1xuICAgICAgICAgICAgdGhpcy5sYWJlbFJvdGF0aW9uID0gbWluUm90YXRpb247XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbGFiZWxTaXplcyA9IHRoaXMuX2dldExhYmVsU2l6ZXMoKTtcbiAgICAgICAgY29uc3QgbWF4TGFiZWxXaWR0aCA9IGxhYmVsU2l6ZXMud2lkZXN0LndpZHRoO1xuICAgICAgICBjb25zdCBtYXhMYWJlbEhlaWdodCA9IGxhYmVsU2l6ZXMuaGlnaGVzdC5oZWlnaHQ7XG4gICAgICAgIGNvbnN0IG1heFdpZHRoID0gX2xpbWl0VmFsdWUodGhpcy5jaGFydC53aWR0aCAtIG1heExhYmVsV2lkdGgsIDAsIHRoaXMubWF4V2lkdGgpO1xuICAgICAgICB0aWNrV2lkdGggPSBvcHRpb25zLm9mZnNldCA/IHRoaXMubWF4V2lkdGggLyBudW1UaWNrcyA6IG1heFdpZHRoIC8gKG51bVRpY2tzIC0gMSk7XG4gICAgICAgIGlmIChtYXhMYWJlbFdpZHRoICsgNiA+IHRpY2tXaWR0aCkge1xuICAgICAgICAgICAgdGlja1dpZHRoID0gbWF4V2lkdGggLyAobnVtVGlja3MgLSAob3B0aW9ucy5vZmZzZXQgPyAwLjUgOiAxKSk7XG4gICAgICAgICAgICBtYXhIZWlnaHQgPSB0aGlzLm1heEhlaWdodCAtIGdldFRpY2tNYXJrTGVuZ3RoKG9wdGlvbnMuZ3JpZCkgLSB0aWNrT3B0cy5wYWRkaW5nIC0gZ2V0VGl0bGVIZWlnaHQob3B0aW9ucy50aXRsZSwgdGhpcy5jaGFydC5vcHRpb25zLmZvbnQpO1xuICAgICAgICAgICAgbWF4TGFiZWxEaWFnb25hbCA9IE1hdGguc3FydChtYXhMYWJlbFdpZHRoICogbWF4TGFiZWxXaWR0aCArIG1heExhYmVsSGVpZ2h0ICogbWF4TGFiZWxIZWlnaHQpO1xuICAgICAgICAgICAgbGFiZWxSb3RhdGlvbiA9IHRvRGVncmVlcyhNYXRoLm1pbihNYXRoLmFzaW4oX2xpbWl0VmFsdWUoKGxhYmVsU2l6ZXMuaGlnaGVzdC5oZWlnaHQgKyA2KSAvIHRpY2tXaWR0aCwgLTEsIDEpKSwgTWF0aC5hc2luKF9saW1pdFZhbHVlKG1heEhlaWdodCAvIG1heExhYmVsRGlhZ29uYWwsIC0xLCAxKSkgLSBNYXRoLmFzaW4oX2xpbWl0VmFsdWUobWF4TGFiZWxIZWlnaHQgLyBtYXhMYWJlbERpYWdvbmFsLCAtMSwgMSkpKSk7XG4gICAgICAgICAgICBsYWJlbFJvdGF0aW9uID0gTWF0aC5tYXgobWluUm90YXRpb24sIE1hdGgubWluKG1heFJvdGF0aW9uLCBsYWJlbFJvdGF0aW9uKSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5sYWJlbFJvdGF0aW9uID0gbGFiZWxSb3RhdGlvbjtcbiAgICB9XG4gICAgYWZ0ZXJDYWxjdWxhdGVMYWJlbFJvdGF0aW9uKCkge1xuICAgICAgICBjYWxsYmFjayh0aGlzLm9wdGlvbnMuYWZ0ZXJDYWxjdWxhdGVMYWJlbFJvdGF0aW9uLCBbXG4gICAgICAgICAgICB0aGlzXG4gICAgICAgIF0pO1xuICAgIH1cbiAgICBhZnRlckF1dG9Ta2lwKCkge31cbiAgICBiZWZvcmVGaXQoKSB7XG4gICAgICAgIGNhbGxiYWNrKHRoaXMub3B0aW9ucy5iZWZvcmVGaXQsIFtcbiAgICAgICAgICAgIHRoaXNcbiAgICAgICAgXSk7XG4gICAgfVxuICAgIGZpdCgpIHtcbiAgICAgICAgY29uc3QgbWluU2l6ZSA9IHtcbiAgICAgICAgICAgIHdpZHRoOiAwLFxuICAgICAgICAgICAgaGVpZ2h0OiAwXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHsgY2hhcnQgLCBvcHRpb25zOiB7IHRpY2tzOiB0aWNrT3B0cyAsIHRpdGxlOiB0aXRsZU9wdHMgLCBncmlkOiBncmlkT3B0cyAgfSAgfSA9IHRoaXM7XG4gICAgICAgIGNvbnN0IGRpc3BsYXkgPSB0aGlzLl9pc1Zpc2libGUoKTtcbiAgICAgICAgY29uc3QgaXNIb3Jpem9udGFsID0gdGhpcy5pc0hvcml6b250YWwoKTtcbiAgICAgICAgaWYgKGRpc3BsYXkpIHtcbiAgICAgICAgICAgIGNvbnN0IHRpdGxlSGVpZ2h0ID0gZ2V0VGl0bGVIZWlnaHQodGl0bGVPcHRzLCBjaGFydC5vcHRpb25zLmZvbnQpO1xuICAgICAgICAgICAgaWYgKGlzSG9yaXpvbnRhbCkge1xuICAgICAgICAgICAgICAgIG1pblNpemUud2lkdGggPSB0aGlzLm1heFdpZHRoO1xuICAgICAgICAgICAgICAgIG1pblNpemUuaGVpZ2h0ID0gZ2V0VGlja01hcmtMZW5ndGgoZ3JpZE9wdHMpICsgdGl0bGVIZWlnaHQ7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG1pblNpemUuaGVpZ2h0ID0gdGhpcy5tYXhIZWlnaHQ7XG4gICAgICAgICAgICAgICAgbWluU2l6ZS53aWR0aCA9IGdldFRpY2tNYXJrTGVuZ3RoKGdyaWRPcHRzKSArIHRpdGxlSGVpZ2h0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRpY2tPcHRzLmRpc3BsYXkgJiYgdGhpcy50aWNrcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB7IGZpcnN0ICwgbGFzdCAsIHdpZGVzdCAsIGhpZ2hlc3QgIH0gPSB0aGlzLl9nZXRMYWJlbFNpemVzKCk7XG4gICAgICAgICAgICAgICAgY29uc3QgdGlja1BhZGRpbmcgPSB0aWNrT3B0cy5wYWRkaW5nICogMjtcbiAgICAgICAgICAgICAgICBjb25zdCBhbmdsZVJhZGlhbnMgPSB0b1JhZGlhbnModGhpcy5sYWJlbFJvdGF0aW9uKTtcbiAgICAgICAgICAgICAgICBjb25zdCBjb3MgPSBNYXRoLmNvcyhhbmdsZVJhZGlhbnMpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHNpbiA9IE1hdGguc2luKGFuZ2xlUmFkaWFucyk7XG4gICAgICAgICAgICAgICAgaWYgKGlzSG9yaXpvbnRhbCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBsYWJlbEhlaWdodCA9IHRpY2tPcHRzLm1pcnJvciA/IDAgOiBzaW4gKiB3aWRlc3Qud2lkdGggKyBjb3MgKiBoaWdoZXN0LmhlaWdodDtcbiAgICAgICAgICAgICAgICAgICAgbWluU2l6ZS5oZWlnaHQgPSBNYXRoLm1pbih0aGlzLm1heEhlaWdodCwgbWluU2l6ZS5oZWlnaHQgKyBsYWJlbEhlaWdodCArIHRpY2tQYWRkaW5nKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBsYWJlbFdpZHRoID0gdGlja09wdHMubWlycm9yID8gMCA6IGNvcyAqIHdpZGVzdC53aWR0aCArIHNpbiAqIGhpZ2hlc3QuaGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICBtaW5TaXplLndpZHRoID0gTWF0aC5taW4odGhpcy5tYXhXaWR0aCwgbWluU2l6ZS53aWR0aCArIGxhYmVsV2lkdGggKyB0aWNrUGFkZGluZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX2NhbGN1bGF0ZVBhZGRpbmcoZmlyc3QsIGxhc3QsIHNpbiwgY29zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9oYW5kbGVNYXJnaW5zKCk7XG4gICAgICAgIGlmIChpc0hvcml6b250YWwpIHtcbiAgICAgICAgICAgIHRoaXMud2lkdGggPSB0aGlzLl9sZW5ndGggPSBjaGFydC53aWR0aCAtIHRoaXMuX21hcmdpbnMubGVmdCAtIHRoaXMuX21hcmdpbnMucmlnaHQ7XG4gICAgICAgICAgICB0aGlzLmhlaWdodCA9IG1pblNpemUuaGVpZ2h0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy53aWR0aCA9IG1pblNpemUud2lkdGg7XG4gICAgICAgICAgICB0aGlzLmhlaWdodCA9IHRoaXMuX2xlbmd0aCA9IGNoYXJ0LmhlaWdodCAtIHRoaXMuX21hcmdpbnMudG9wIC0gdGhpcy5fbWFyZ2lucy5ib3R0b207XG4gICAgICAgIH1cbiAgICB9XG4gICAgX2NhbGN1bGF0ZVBhZGRpbmcoZmlyc3QsIGxhc3QsIHNpbiwgY29zKSB7XG4gICAgICAgIGNvbnN0IHsgdGlja3M6IHsgYWxpZ24gLCBwYWRkaW5nICB9ICwgcG9zaXRpb24gIH0gPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGNvbnN0IGlzUm90YXRlZCA9IHRoaXMubGFiZWxSb3RhdGlvbiAhPT0gMDtcbiAgICAgICAgY29uc3QgbGFiZWxzQmVsb3dUaWNrcyA9IHBvc2l0aW9uICE9PSAndG9wJyAmJiB0aGlzLmF4aXMgPT09ICd4JztcbiAgICAgICAgaWYgKHRoaXMuaXNIb3Jpem9udGFsKCkpIHtcbiAgICAgICAgICAgIGNvbnN0IG9mZnNldExlZnQgPSB0aGlzLmdldFBpeGVsRm9yVGljaygwKSAtIHRoaXMubGVmdDtcbiAgICAgICAgICAgIGNvbnN0IG9mZnNldFJpZ2h0ID0gdGhpcy5yaWdodCAtIHRoaXMuZ2V0UGl4ZWxGb3JUaWNrKHRoaXMudGlja3MubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgICBsZXQgcGFkZGluZ0xlZnQgPSAwO1xuICAgICAgICAgICAgbGV0IHBhZGRpbmdSaWdodCA9IDA7XG4gICAgICAgICAgICBpZiAoaXNSb3RhdGVkKSB7XG4gICAgICAgICAgICAgICAgaWYgKGxhYmVsc0JlbG93VGlja3MpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFkZGluZ0xlZnQgPSBjb3MgKiBmaXJzdC53aWR0aDtcbiAgICAgICAgICAgICAgICAgICAgcGFkZGluZ1JpZ2h0ID0gc2luICogbGFzdC5oZWlnaHQ7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcGFkZGluZ0xlZnQgPSBzaW4gKiBmaXJzdC5oZWlnaHQ7XG4gICAgICAgICAgICAgICAgICAgIHBhZGRpbmdSaWdodCA9IGNvcyAqIGxhc3Qud2lkdGg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChhbGlnbiA9PT0gJ3N0YXJ0Jykge1xuICAgICAgICAgICAgICAgIHBhZGRpbmdSaWdodCA9IGxhc3Qud2lkdGg7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGFsaWduID09PSAnZW5kJykge1xuICAgICAgICAgICAgICAgIHBhZGRpbmdMZWZ0ID0gZmlyc3Qud2lkdGg7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGFsaWduICE9PSAnaW5uZXInKSB7XG4gICAgICAgICAgICAgICAgcGFkZGluZ0xlZnQgPSBmaXJzdC53aWR0aCAvIDI7XG4gICAgICAgICAgICAgICAgcGFkZGluZ1JpZ2h0ID0gbGFzdC53aWR0aCAvIDI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnBhZGRpbmdMZWZ0ID0gTWF0aC5tYXgoKHBhZGRpbmdMZWZ0IC0gb2Zmc2V0TGVmdCArIHBhZGRpbmcpICogdGhpcy53aWR0aCAvICh0aGlzLndpZHRoIC0gb2Zmc2V0TGVmdCksIDApO1xuICAgICAgICAgICAgdGhpcy5wYWRkaW5nUmlnaHQgPSBNYXRoLm1heCgocGFkZGluZ1JpZ2h0IC0gb2Zmc2V0UmlnaHQgKyBwYWRkaW5nKSAqIHRoaXMud2lkdGggLyAodGhpcy53aWR0aCAtIG9mZnNldFJpZ2h0KSwgMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsZXQgcGFkZGluZ1RvcCA9IGxhc3QuaGVpZ2h0IC8gMjtcbiAgICAgICAgICAgIGxldCBwYWRkaW5nQm90dG9tID0gZmlyc3QuaGVpZ2h0IC8gMjtcbiAgICAgICAgICAgIGlmIChhbGlnbiA9PT0gJ3N0YXJ0Jykge1xuICAgICAgICAgICAgICAgIHBhZGRpbmdUb3AgPSAwO1xuICAgICAgICAgICAgICAgIHBhZGRpbmdCb3R0b20gPSBmaXJzdC5oZWlnaHQ7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGFsaWduID09PSAnZW5kJykge1xuICAgICAgICAgICAgICAgIHBhZGRpbmdUb3AgPSBsYXN0LmhlaWdodDtcbiAgICAgICAgICAgICAgICBwYWRkaW5nQm90dG9tID0gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMucGFkZGluZ1RvcCA9IHBhZGRpbmdUb3AgKyBwYWRkaW5nO1xuICAgICAgICAgICAgdGhpcy5wYWRkaW5nQm90dG9tID0gcGFkZGluZ0JvdHRvbSArIHBhZGRpbmc7XG4gICAgICAgIH1cbiAgICB9XG4gX2hhbmRsZU1hcmdpbnMoKSB7XG4gICAgICAgIGlmICh0aGlzLl9tYXJnaW5zKSB7XG4gICAgICAgICAgICB0aGlzLl9tYXJnaW5zLmxlZnQgPSBNYXRoLm1heCh0aGlzLnBhZGRpbmdMZWZ0LCB0aGlzLl9tYXJnaW5zLmxlZnQpO1xuICAgICAgICAgICAgdGhpcy5fbWFyZ2lucy50b3AgPSBNYXRoLm1heCh0aGlzLnBhZGRpbmdUb3AsIHRoaXMuX21hcmdpbnMudG9wKTtcbiAgICAgICAgICAgIHRoaXMuX21hcmdpbnMucmlnaHQgPSBNYXRoLm1heCh0aGlzLnBhZGRpbmdSaWdodCwgdGhpcy5fbWFyZ2lucy5yaWdodCk7XG4gICAgICAgICAgICB0aGlzLl9tYXJnaW5zLmJvdHRvbSA9IE1hdGgubWF4KHRoaXMucGFkZGluZ0JvdHRvbSwgdGhpcy5fbWFyZ2lucy5ib3R0b20pO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFmdGVyRml0KCkge1xuICAgICAgICBjYWxsYmFjayh0aGlzLm9wdGlvbnMuYWZ0ZXJGaXQsIFtcbiAgICAgICAgICAgIHRoaXNcbiAgICAgICAgXSk7XG4gICAgfVxuIGlzSG9yaXpvbnRhbCgpIHtcbiAgICAgICAgY29uc3QgeyBheGlzICwgcG9zaXRpb24gIH0gPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHJldHVybiBwb3NpdGlvbiA9PT0gJ3RvcCcgfHwgcG9zaXRpb24gPT09ICdib3R0b20nIHx8IGF4aXMgPT09ICd4JztcbiAgICB9XG4gaXNGdWxsU2l6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy5mdWxsU2l6ZTtcbiAgICB9XG4gX2NvbnZlcnRUaWNrc1RvTGFiZWxzKHRpY2tzKSB7XG4gICAgICAgIHRoaXMuYmVmb3JlVGlja1RvTGFiZWxDb252ZXJzaW9uKCk7XG4gICAgICAgIHRoaXMuZ2VuZXJhdGVUaWNrTGFiZWxzKHRpY2tzKTtcbiAgICAgICAgbGV0IGksIGlsZW47XG4gICAgICAgIGZvcihpID0gMCwgaWxlbiA9IHRpY2tzLmxlbmd0aDsgaSA8IGlsZW47IGkrKyl7XG4gICAgICAgICAgICBpZiAoaXNOdWxsT3JVbmRlZih0aWNrc1tpXS5sYWJlbCkpIHtcbiAgICAgICAgICAgICAgICB0aWNrcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgaWxlbi0tO1xuICAgICAgICAgICAgICAgIGktLTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmFmdGVyVGlja1RvTGFiZWxDb252ZXJzaW9uKCk7XG4gICAgfVxuIF9nZXRMYWJlbFNpemVzKCkge1xuICAgICAgICBsZXQgbGFiZWxTaXplcyA9IHRoaXMuX2xhYmVsU2l6ZXM7XG4gICAgICAgIGlmICghbGFiZWxTaXplcykge1xuICAgICAgICAgICAgY29uc3Qgc2FtcGxlU2l6ZSA9IHRoaXMub3B0aW9ucy50aWNrcy5zYW1wbGVTaXplO1xuICAgICAgICAgICAgbGV0IHRpY2tzID0gdGhpcy50aWNrcztcbiAgICAgICAgICAgIGlmIChzYW1wbGVTaXplIDwgdGlja3MubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGlja3MgPSBzYW1wbGUodGlja3MsIHNhbXBsZVNpemUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fbGFiZWxTaXplcyA9IGxhYmVsU2l6ZXMgPSB0aGlzLl9jb21wdXRlTGFiZWxTaXplcyh0aWNrcywgdGlja3MubGVuZ3RoLCB0aGlzLm9wdGlvbnMudGlja3MubWF4VGlja3NMaW1pdCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGxhYmVsU2l6ZXM7XG4gICAgfVxuIF9jb21wdXRlTGFiZWxTaXplcyh0aWNrcywgbGVuZ3RoLCBtYXhUaWNrc0xpbWl0KSB7XG4gICAgICAgIGNvbnN0IHsgY3R4ICwgX2xvbmdlc3RUZXh0Q2FjaGU6IGNhY2hlcyAgfSA9IHRoaXM7XG4gICAgICAgIGNvbnN0IHdpZHRocyA9IFtdO1xuICAgICAgICBjb25zdCBoZWlnaHRzID0gW107XG4gICAgICAgIGNvbnN0IGluY3JlbWVudCA9IE1hdGguZmxvb3IobGVuZ3RoIC8gZ2V0VGlja3NMaW1pdChsZW5ndGgsIG1heFRpY2tzTGltaXQpKTtcbiAgICAgICAgbGV0IHdpZGVzdExhYmVsU2l6ZSA9IDA7XG4gICAgICAgIGxldCBoaWdoZXN0TGFiZWxTaXplID0gMDtcbiAgICAgICAgbGV0IGksIGosIGpsZW4sIGxhYmVsLCB0aWNrRm9udCwgZm9udFN0cmluZywgY2FjaGUsIGxpbmVIZWlnaHQsIHdpZHRoLCBoZWlnaHQsIG5lc3RlZExhYmVsO1xuICAgICAgICBmb3IoaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gaW5jcmVtZW50KXtcbiAgICAgICAgICAgIGxhYmVsID0gdGlja3NbaV0ubGFiZWw7XG4gICAgICAgICAgICB0aWNrRm9udCA9IHRoaXMuX3Jlc29sdmVUaWNrRm9udE9wdGlvbnMoaSk7XG4gICAgICAgICAgICBjdHguZm9udCA9IGZvbnRTdHJpbmcgPSB0aWNrRm9udC5zdHJpbmc7XG4gICAgICAgICAgICBjYWNoZSA9IGNhY2hlc1tmb250U3RyaW5nXSA9IGNhY2hlc1tmb250U3RyaW5nXSB8fCB7XG4gICAgICAgICAgICAgICAgZGF0YToge30sXG4gICAgICAgICAgICAgICAgZ2M6IFtdXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgbGluZUhlaWdodCA9IHRpY2tGb250LmxpbmVIZWlnaHQ7XG4gICAgICAgICAgICB3aWR0aCA9IGhlaWdodCA9IDA7XG4gICAgICAgICAgICBpZiAoIWlzTnVsbE9yVW5kZWYobGFiZWwpICYmICFpc0FycmF5KGxhYmVsKSkge1xuICAgICAgICAgICAgICAgIHdpZHRoID0gX21lYXN1cmVUZXh0KGN0eCwgY2FjaGUuZGF0YSwgY2FjaGUuZ2MsIHdpZHRoLCBsYWJlbCk7XG4gICAgICAgICAgICAgICAgaGVpZ2h0ID0gbGluZUhlaWdodDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNBcnJheShsYWJlbCkpIHtcbiAgICAgICAgICAgICAgICBmb3IoaiA9IDAsIGpsZW4gPSBsYWJlbC5sZW5ndGg7IGogPCBqbGVuOyArK2ope1xuICAgICAgICAgICAgICAgICAgICBuZXN0ZWRMYWJlbCA9ICBsYWJlbFtqXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc051bGxPclVuZGVmKG5lc3RlZExhYmVsKSAmJiAhaXNBcnJheShuZXN0ZWRMYWJlbCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoID0gX21lYXN1cmVUZXh0KGN0eCwgY2FjaGUuZGF0YSwgY2FjaGUuZ2MsIHdpZHRoLCBuZXN0ZWRMYWJlbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQgKz0gbGluZUhlaWdodDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHdpZHRocy5wdXNoKHdpZHRoKTtcbiAgICAgICAgICAgIGhlaWdodHMucHVzaChoZWlnaHQpO1xuICAgICAgICAgICAgd2lkZXN0TGFiZWxTaXplID0gTWF0aC5tYXgod2lkdGgsIHdpZGVzdExhYmVsU2l6ZSk7XG4gICAgICAgICAgICBoaWdoZXN0TGFiZWxTaXplID0gTWF0aC5tYXgoaGVpZ2h0LCBoaWdoZXN0TGFiZWxTaXplKTtcbiAgICAgICAgfVxuICAgICAgICBnYXJiYWdlQ29sbGVjdChjYWNoZXMsIGxlbmd0aCk7XG4gICAgICAgIGNvbnN0IHdpZGVzdCA9IHdpZHRocy5pbmRleE9mKHdpZGVzdExhYmVsU2l6ZSk7XG4gICAgICAgIGNvbnN0IGhpZ2hlc3QgPSBoZWlnaHRzLmluZGV4T2YoaGlnaGVzdExhYmVsU2l6ZSk7XG4gICAgICAgIGNvbnN0IHZhbHVlQXQgPSAoaWR4KT0+KHtcbiAgICAgICAgICAgICAgICB3aWR0aDogd2lkdGhzW2lkeF0gfHwgMCxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IGhlaWdodHNbaWR4XSB8fCAwXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGZpcnN0OiB2YWx1ZUF0KDApLFxuICAgICAgICAgICAgbGFzdDogdmFsdWVBdChsZW5ndGggLSAxKSxcbiAgICAgICAgICAgIHdpZGVzdDogdmFsdWVBdCh3aWRlc3QpLFxuICAgICAgICAgICAgaGlnaGVzdDogdmFsdWVBdChoaWdoZXN0KSxcbiAgICAgICAgICAgIHdpZHRocyxcbiAgICAgICAgICAgIGhlaWdodHNcbiAgICAgICAgfTtcbiAgICB9XG4gZ2V0TGFiZWxGb3JWYWx1ZSh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuIGdldFBpeGVsRm9yVmFsdWUodmFsdWUsIGluZGV4KSB7XG4gICAgICAgIHJldHVybiBOYU47XG4gICAgfVxuIGdldFZhbHVlRm9yUGl4ZWwocGl4ZWwpIHt9XG4gZ2V0UGl4ZWxGb3JUaWNrKGluZGV4KSB7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy50aWNrcztcbiAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+IHRpY2tzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBpeGVsRm9yVmFsdWUodGlja3NbaW5kZXhdLnZhbHVlKTtcbiAgICB9XG4gZ2V0UGl4ZWxGb3JEZWNpbWFsKGRlY2ltYWwpIHtcbiAgICAgICAgaWYgKHRoaXMuX3JldmVyc2VQaXhlbHMpIHtcbiAgICAgICAgICAgIGRlY2ltYWwgPSAxIC0gZGVjaW1hbDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwaXhlbCA9IHRoaXMuX3N0YXJ0UGl4ZWwgKyBkZWNpbWFsICogdGhpcy5fbGVuZ3RoO1xuICAgICAgICByZXR1cm4gX2ludDE2UmFuZ2UodGhpcy5fYWxpZ25Ub1BpeGVscyA/IF9hbGlnblBpeGVsKHRoaXMuY2hhcnQsIHBpeGVsLCAwKSA6IHBpeGVsKTtcbiAgICB9XG4gZ2V0RGVjaW1hbEZvclBpeGVsKHBpeGVsKSB7XG4gICAgICAgIGNvbnN0IGRlY2ltYWwgPSAocGl4ZWwgLSB0aGlzLl9zdGFydFBpeGVsKSAvIHRoaXMuX2xlbmd0aDtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JldmVyc2VQaXhlbHMgPyAxIC0gZGVjaW1hbCA6IGRlY2ltYWw7XG4gICAgfVxuIGdldEJhc2VQaXhlbCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGl4ZWxGb3JWYWx1ZSh0aGlzLmdldEJhc2VWYWx1ZSgpKTtcbiAgICB9XG4gZ2V0QmFzZVZhbHVlKCkge1xuICAgICAgICBjb25zdCB7IG1pbiAsIG1heCAgfSA9IHRoaXM7XG4gICAgICAgIHJldHVybiBtaW4gPCAwICYmIG1heCA8IDAgPyBtYXggOiBtaW4gPiAwICYmIG1heCA+IDAgPyBtaW4gOiAwO1xuICAgIH1cbiBnZXRDb250ZXh0KGluZGV4KSB7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy50aWNrcyB8fCBbXTtcbiAgICAgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCB0aWNrcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNvbnN0IHRpY2sgPSB0aWNrc1tpbmRleF07XG4gICAgICAgICAgICByZXR1cm4gdGljay4kY29udGV4dCB8fCAodGljay4kY29udGV4dCA9IGNyZWF0ZVRpY2tDb250ZXh0KHRoaXMuZ2V0Q29udGV4dCgpLCBpbmRleCwgdGljaykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLiRjb250ZXh0IHx8ICh0aGlzLiRjb250ZXh0ID0gY3JlYXRlU2NhbGVDb250ZXh0KHRoaXMuY2hhcnQuZ2V0Q29udGV4dCgpLCB0aGlzKSk7XG4gICAgfVxuIF90aWNrU2l6ZSgpIHtcbiAgICAgICAgY29uc3Qgb3B0aW9uVGlja3MgPSB0aGlzLm9wdGlvbnMudGlja3M7XG4gICAgICAgIGNvbnN0IHJvdCA9IHRvUmFkaWFucyh0aGlzLmxhYmVsUm90YXRpb24pO1xuICAgICAgICBjb25zdCBjb3MgPSBNYXRoLmFicyhNYXRoLmNvcyhyb3QpKTtcbiAgICAgICAgY29uc3Qgc2luID0gTWF0aC5hYnMoTWF0aC5zaW4ocm90KSk7XG4gICAgICAgIGNvbnN0IGxhYmVsU2l6ZXMgPSB0aGlzLl9nZXRMYWJlbFNpemVzKCk7XG4gICAgICAgIGNvbnN0IHBhZGRpbmcgPSBvcHRpb25UaWNrcy5hdXRvU2tpcFBhZGRpbmcgfHwgMDtcbiAgICAgICAgY29uc3QgdyA9IGxhYmVsU2l6ZXMgPyBsYWJlbFNpemVzLndpZGVzdC53aWR0aCArIHBhZGRpbmcgOiAwO1xuICAgICAgICBjb25zdCBoID0gbGFiZWxTaXplcyA/IGxhYmVsU2l6ZXMuaGlnaGVzdC5oZWlnaHQgKyBwYWRkaW5nIDogMDtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNIb3Jpem9udGFsKCkgPyBoICogY29zID4gdyAqIHNpbiA/IHcgLyBjb3MgOiBoIC8gc2luIDogaCAqIHNpbiA8IHcgKiBjb3MgPyBoIC8gY29zIDogdyAvIHNpbjtcbiAgICB9XG4gX2lzVmlzaWJsZSgpIHtcbiAgICAgICAgY29uc3QgZGlzcGxheSA9IHRoaXMub3B0aW9ucy5kaXNwbGF5O1xuICAgICAgICBpZiAoZGlzcGxheSAhPT0gJ2F1dG8nKSB7XG4gICAgICAgICAgICByZXR1cm4gISFkaXNwbGF5O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmdldE1hdGNoaW5nVmlzaWJsZU1ldGFzKCkubGVuZ3RoID4gMDtcbiAgICB9XG4gX2NvbXB1dGVHcmlkTGluZUl0ZW1zKGNoYXJ0QXJlYSkge1xuICAgICAgICBjb25zdCBheGlzID0gdGhpcy5heGlzO1xuICAgICAgICBjb25zdCBjaGFydCA9IHRoaXMuY2hhcnQ7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGNvbnN0IHsgZ3JpZCAsIHBvc2l0aW9uICwgYm9yZGVyICB9ID0gb3B0aW9ucztcbiAgICAgICAgY29uc3Qgb2Zmc2V0ID0gZ3JpZC5vZmZzZXQ7XG4gICAgICAgIGNvbnN0IGlzSG9yaXpvbnRhbCA9IHRoaXMuaXNIb3Jpem9udGFsKCk7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy50aWNrcztcbiAgICAgICAgY29uc3QgdGlja3NMZW5ndGggPSB0aWNrcy5sZW5ndGggKyAob2Zmc2V0ID8gMSA6IDApO1xuICAgICAgICBjb25zdCB0bCA9IGdldFRpY2tNYXJrTGVuZ3RoKGdyaWQpO1xuICAgICAgICBjb25zdCBpdGVtcyA9IFtdO1xuICAgICAgICBjb25zdCBib3JkZXJPcHRzID0gYm9yZGVyLnNldENvbnRleHQodGhpcy5nZXRDb250ZXh0KCkpO1xuICAgICAgICBjb25zdCBheGlzV2lkdGggPSBib3JkZXJPcHRzLmRpc3BsYXkgPyBib3JkZXJPcHRzLndpZHRoIDogMDtcbiAgICAgICAgY29uc3QgYXhpc0hhbGZXaWR0aCA9IGF4aXNXaWR0aCAvIDI7XG4gICAgICAgIGNvbnN0IGFsaWduQm9yZGVyVmFsdWUgPSBmdW5jdGlvbihwaXhlbCkge1xuICAgICAgICAgICAgcmV0dXJuIF9hbGlnblBpeGVsKGNoYXJ0LCBwaXhlbCwgYXhpc1dpZHRoKTtcbiAgICAgICAgfTtcbiAgICAgICAgbGV0IGJvcmRlclZhbHVlLCBpLCBsaW5lVmFsdWUsIGFsaWduZWRMaW5lVmFsdWU7XG4gICAgICAgIGxldCB0eDEsIHR5MSwgdHgyLCB0eTIsIHgxLCB5MSwgeDIsIHkyO1xuICAgICAgICBpZiAocG9zaXRpb24gPT09ICd0b3AnKSB7XG4gICAgICAgICAgICBib3JkZXJWYWx1ZSA9IGFsaWduQm9yZGVyVmFsdWUodGhpcy5ib3R0b20pO1xuICAgICAgICAgICAgdHkxID0gdGhpcy5ib3R0b20gLSB0bDtcbiAgICAgICAgICAgIHR5MiA9IGJvcmRlclZhbHVlIC0gYXhpc0hhbGZXaWR0aDtcbiAgICAgICAgICAgIHkxID0gYWxpZ25Cb3JkZXJWYWx1ZShjaGFydEFyZWEudG9wKSArIGF4aXNIYWxmV2lkdGg7XG4gICAgICAgICAgICB5MiA9IGNoYXJ0QXJlYS5ib3R0b207XG4gICAgICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPT09ICdib3R0b20nKSB7XG4gICAgICAgICAgICBib3JkZXJWYWx1ZSA9IGFsaWduQm9yZGVyVmFsdWUodGhpcy50b3ApO1xuICAgICAgICAgICAgeTEgPSBjaGFydEFyZWEudG9wO1xuICAgICAgICAgICAgeTIgPSBhbGlnbkJvcmRlclZhbHVlKGNoYXJ0QXJlYS5ib3R0b20pIC0gYXhpc0hhbGZXaWR0aDtcbiAgICAgICAgICAgIHR5MSA9IGJvcmRlclZhbHVlICsgYXhpc0hhbGZXaWR0aDtcbiAgICAgICAgICAgIHR5MiA9IHRoaXMudG9wICsgdGw7XG4gICAgICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPT09ICdsZWZ0Jykge1xuICAgICAgICAgICAgYm9yZGVyVmFsdWUgPSBhbGlnbkJvcmRlclZhbHVlKHRoaXMucmlnaHQpO1xuICAgICAgICAgICAgdHgxID0gdGhpcy5yaWdodCAtIHRsO1xuICAgICAgICAgICAgdHgyID0gYm9yZGVyVmFsdWUgLSBheGlzSGFsZldpZHRoO1xuICAgICAgICAgICAgeDEgPSBhbGlnbkJvcmRlclZhbHVlKGNoYXJ0QXJlYS5sZWZ0KSArIGF4aXNIYWxmV2lkdGg7XG4gICAgICAgICAgICB4MiA9IGNoYXJ0QXJlYS5yaWdodDtcbiAgICAgICAgfSBlbHNlIGlmIChwb3NpdGlvbiA9PT0gJ3JpZ2h0Jykge1xuICAgICAgICAgICAgYm9yZGVyVmFsdWUgPSBhbGlnbkJvcmRlclZhbHVlKHRoaXMubGVmdCk7XG4gICAgICAgICAgICB4MSA9IGNoYXJ0QXJlYS5sZWZ0O1xuICAgICAgICAgICAgeDIgPSBhbGlnbkJvcmRlclZhbHVlKGNoYXJ0QXJlYS5yaWdodCkgLSBheGlzSGFsZldpZHRoO1xuICAgICAgICAgICAgdHgxID0gYm9yZGVyVmFsdWUgKyBheGlzSGFsZldpZHRoO1xuICAgICAgICAgICAgdHgyID0gdGhpcy5sZWZ0ICsgdGw7XG4gICAgICAgIH0gZWxzZSBpZiAoYXhpcyA9PT0gJ3gnKSB7XG4gICAgICAgICAgICBpZiAocG9zaXRpb24gPT09ICdjZW50ZXInKSB7XG4gICAgICAgICAgICAgICAgYm9yZGVyVmFsdWUgPSBhbGlnbkJvcmRlclZhbHVlKChjaGFydEFyZWEudG9wICsgY2hhcnRBcmVhLmJvdHRvbSkgLyAyICsgMC41KTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNPYmplY3QocG9zaXRpb24pKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcG9zaXRpb25BeGlzSUQgPSBPYmplY3Qua2V5cyhwb3NpdGlvbilbMF07XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBwb3NpdGlvbltwb3NpdGlvbkF4aXNJRF07XG4gICAgICAgICAgICAgICAgYm9yZGVyVmFsdWUgPSBhbGlnbkJvcmRlclZhbHVlKHRoaXMuY2hhcnQuc2NhbGVzW3Bvc2l0aW9uQXhpc0lEXS5nZXRQaXhlbEZvclZhbHVlKHZhbHVlKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB5MSA9IGNoYXJ0QXJlYS50b3A7XG4gICAgICAgICAgICB5MiA9IGNoYXJ0QXJlYS5ib3R0b207XG4gICAgICAgICAgICB0eTEgPSBib3JkZXJWYWx1ZSArIGF4aXNIYWxmV2lkdGg7XG4gICAgICAgICAgICB0eTIgPSB0eTEgKyB0bDtcbiAgICAgICAgfSBlbHNlIGlmIChheGlzID09PSAneScpIHtcbiAgICAgICAgICAgIGlmIChwb3NpdGlvbiA9PT0gJ2NlbnRlcicpIHtcbiAgICAgICAgICAgICAgICBib3JkZXJWYWx1ZSA9IGFsaWduQm9yZGVyVmFsdWUoKGNoYXJ0QXJlYS5sZWZ0ICsgY2hhcnRBcmVhLnJpZ2h0KSAvIDIpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChpc09iamVjdChwb3NpdGlvbikpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwb3NpdGlvbkF4aXNJRCA9IE9iamVjdC5rZXlzKHBvc2l0aW9uKVswXTtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHBvc2l0aW9uW3Bvc2l0aW9uQXhpc0lEXTtcbiAgICAgICAgICAgICAgICBib3JkZXJWYWx1ZSA9IGFsaWduQm9yZGVyVmFsdWUodGhpcy5jaGFydC5zY2FsZXNbcG9zaXRpb25BeGlzSURdLmdldFBpeGVsRm9yVmFsdWUodmFsdWUpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHR4MSA9IGJvcmRlclZhbHVlIC0gYXhpc0hhbGZXaWR0aDtcbiAgICAgICAgICAgIHR4MiA9IHR4MSAtIHRsO1xuICAgICAgICAgICAgeDEgPSBjaGFydEFyZWEubGVmdDtcbiAgICAgICAgICAgIHgyID0gY2hhcnRBcmVhLnJpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGxpbWl0ID0gdmFsdWVPckRlZmF1bHQob3B0aW9ucy50aWNrcy5tYXhUaWNrc0xpbWl0LCB0aWNrc0xlbmd0aCk7XG4gICAgICAgIGNvbnN0IHN0ZXAgPSBNYXRoLm1heCgxLCBNYXRoLmNlaWwodGlja3NMZW5ndGggLyBsaW1pdCkpO1xuICAgICAgICBmb3IoaSA9IDA7IGkgPCB0aWNrc0xlbmd0aDsgaSArPSBzdGVwKXtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmdldENvbnRleHQoaSk7XG4gICAgICAgICAgICBjb25zdCBvcHRzQXRJbmRleCA9IGdyaWQuc2V0Q29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG9wdHNBdEluZGV4Qm9yZGVyID0gYm9yZGVyLnNldENvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBsaW5lV2lkdGggPSBvcHRzQXRJbmRleC5saW5lV2lkdGg7XG4gICAgICAgICAgICBjb25zdCBsaW5lQ29sb3IgPSBvcHRzQXRJbmRleC5jb2xvcjtcbiAgICAgICAgICAgIGNvbnN0IGJvcmRlckRhc2ggPSBvcHRzQXRJbmRleEJvcmRlci5kYXNoIHx8IFtdO1xuICAgICAgICAgICAgY29uc3QgYm9yZGVyRGFzaE9mZnNldCA9IG9wdHNBdEluZGV4Qm9yZGVyLmRhc2hPZmZzZXQ7XG4gICAgICAgICAgICBjb25zdCB0aWNrV2lkdGggPSBvcHRzQXRJbmRleC50aWNrV2lkdGg7XG4gICAgICAgICAgICBjb25zdCB0aWNrQ29sb3IgPSBvcHRzQXRJbmRleC50aWNrQ29sb3I7XG4gICAgICAgICAgICBjb25zdCB0aWNrQm9yZGVyRGFzaCA9IG9wdHNBdEluZGV4LnRpY2tCb3JkZXJEYXNoIHx8IFtdO1xuICAgICAgICAgICAgY29uc3QgdGlja0JvcmRlckRhc2hPZmZzZXQgPSBvcHRzQXRJbmRleC50aWNrQm9yZGVyRGFzaE9mZnNldDtcbiAgICAgICAgICAgIGxpbmVWYWx1ZSA9IGdldFBpeGVsRm9yR3JpZExpbmUodGhpcywgaSwgb2Zmc2V0KTtcbiAgICAgICAgICAgIGlmIChsaW5lVmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYWxpZ25lZExpbmVWYWx1ZSA9IF9hbGlnblBpeGVsKGNoYXJ0LCBsaW5lVmFsdWUsIGxpbmVXaWR0aCk7XG4gICAgICAgICAgICBpZiAoaXNIb3Jpem9udGFsKSB7XG4gICAgICAgICAgICAgICAgdHgxID0gdHgyID0geDEgPSB4MiA9IGFsaWduZWRMaW5lVmFsdWU7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHR5MSA9IHR5MiA9IHkxID0geTIgPSBhbGlnbmVkTGluZVZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaXRlbXMucHVzaCh7XG4gICAgICAgICAgICAgICAgdHgxLFxuICAgICAgICAgICAgICAgIHR5MSxcbiAgICAgICAgICAgICAgICB0eDIsXG4gICAgICAgICAgICAgICAgdHkyLFxuICAgICAgICAgICAgICAgIHgxLFxuICAgICAgICAgICAgICAgIHkxLFxuICAgICAgICAgICAgICAgIHgyLFxuICAgICAgICAgICAgICAgIHkyLFxuICAgICAgICAgICAgICAgIHdpZHRoOiBsaW5lV2lkdGgsXG4gICAgICAgICAgICAgICAgY29sb3I6IGxpbmVDb2xvcixcbiAgICAgICAgICAgICAgICBib3JkZXJEYXNoLFxuICAgICAgICAgICAgICAgIGJvcmRlckRhc2hPZmZzZXQsXG4gICAgICAgICAgICAgICAgdGlja1dpZHRoLFxuICAgICAgICAgICAgICAgIHRpY2tDb2xvcixcbiAgICAgICAgICAgICAgICB0aWNrQm9yZGVyRGFzaCxcbiAgICAgICAgICAgICAgICB0aWNrQm9yZGVyRGFzaE9mZnNldFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fdGlja3NMZW5ndGggPSB0aWNrc0xlbmd0aDtcbiAgICAgICAgdGhpcy5fYm9yZGVyVmFsdWUgPSBib3JkZXJWYWx1ZTtcbiAgICAgICAgcmV0dXJuIGl0ZW1zO1xuICAgIH1cbiBfY29tcHV0ZUxhYmVsSXRlbXMoY2hhcnRBcmVhKSB7XG4gICAgICAgIGNvbnN0IGF4aXMgPSB0aGlzLmF4aXM7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGNvbnN0IHsgcG9zaXRpb24gLCB0aWNrczogb3B0aW9uVGlja3MgIH0gPSBvcHRpb25zO1xuICAgICAgICBjb25zdCBpc0hvcml6b250YWwgPSB0aGlzLmlzSG9yaXpvbnRhbCgpO1xuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMudGlja3M7XG4gICAgICAgIGNvbnN0IHsgYWxpZ24gLCBjcm9zc0FsaWduICwgcGFkZGluZyAsIG1pcnJvciAgfSA9IG9wdGlvblRpY2tzO1xuICAgICAgICBjb25zdCB0bCA9IGdldFRpY2tNYXJrTGVuZ3RoKG9wdGlvbnMuZ3JpZCk7XG4gICAgICAgIGNvbnN0IHRpY2tBbmRQYWRkaW5nID0gdGwgKyBwYWRkaW5nO1xuICAgICAgICBjb25zdCBoVGlja0FuZFBhZGRpbmcgPSBtaXJyb3IgPyAtcGFkZGluZyA6IHRpY2tBbmRQYWRkaW5nO1xuICAgICAgICBjb25zdCByb3RhdGlvbiA9IC10b1JhZGlhbnModGhpcy5sYWJlbFJvdGF0aW9uKTtcbiAgICAgICAgY29uc3QgaXRlbXMgPSBbXTtcbiAgICAgICAgbGV0IGksIGlsZW4sIHRpY2ssIGxhYmVsLCB4LCB5LCB0ZXh0QWxpZ24sIHBpeGVsLCBmb250LCBsaW5lSGVpZ2h0LCBsaW5lQ291bnQsIHRleHRPZmZzZXQ7XG4gICAgICAgIGxldCB0ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJztcbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSAndG9wJykge1xuICAgICAgICAgICAgeSA9IHRoaXMuYm90dG9tIC0gaFRpY2tBbmRQYWRkaW5nO1xuICAgICAgICAgICAgdGV4dEFsaWduID0gdGhpcy5fZ2V0WEF4aXNMYWJlbEFsaWdubWVudCgpO1xuICAgICAgICB9IGVsc2UgaWYgKHBvc2l0aW9uID09PSAnYm90dG9tJykge1xuICAgICAgICAgICAgeSA9IHRoaXMudG9wICsgaFRpY2tBbmRQYWRkaW5nO1xuICAgICAgICAgICAgdGV4dEFsaWduID0gdGhpcy5fZ2V0WEF4aXNMYWJlbEFsaWdubWVudCgpO1xuICAgICAgICB9IGVsc2UgaWYgKHBvc2l0aW9uID09PSAnbGVmdCcpIHtcbiAgICAgICAgICAgIGNvbnN0IHJldCA9IHRoaXMuX2dldFlBeGlzTGFiZWxBbGlnbm1lbnQodGwpO1xuICAgICAgICAgICAgdGV4dEFsaWduID0gcmV0LnRleHRBbGlnbjtcbiAgICAgICAgICAgIHggPSByZXQueDtcbiAgICAgICAgfSBlbHNlIGlmIChwb3NpdGlvbiA9PT0gJ3JpZ2h0Jykge1xuICAgICAgICAgICAgY29uc3QgcmV0ID0gdGhpcy5fZ2V0WUF4aXNMYWJlbEFsaWdubWVudCh0bCk7XG4gICAgICAgICAgICB0ZXh0QWxpZ24gPSByZXQudGV4dEFsaWduO1xuICAgICAgICAgICAgeCA9IHJldC54O1xuICAgICAgICB9IGVsc2UgaWYgKGF4aXMgPT09ICd4Jykge1xuICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09PSAnY2VudGVyJykge1xuICAgICAgICAgICAgICAgIHkgPSAoY2hhcnRBcmVhLnRvcCArIGNoYXJ0QXJlYS5ib3R0b20pIC8gMiArIHRpY2tBbmRQYWRkaW5nO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChpc09iamVjdChwb3NpdGlvbikpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwb3NpdGlvbkF4aXNJRCA9IE9iamVjdC5rZXlzKHBvc2l0aW9uKVswXTtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHBvc2l0aW9uW3Bvc2l0aW9uQXhpc0lEXTtcbiAgICAgICAgICAgICAgICB5ID0gdGhpcy5jaGFydC5zY2FsZXNbcG9zaXRpb25BeGlzSURdLmdldFBpeGVsRm9yVmFsdWUodmFsdWUpICsgdGlja0FuZFBhZGRpbmc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0ZXh0QWxpZ24gPSB0aGlzLl9nZXRYQXhpc0xhYmVsQWxpZ25tZW50KCk7XG4gICAgICAgIH0gZWxzZSBpZiAoYXhpcyA9PT0gJ3knKSB7XG4gICAgICAgICAgICBpZiAocG9zaXRpb24gPT09ICdjZW50ZXInKSB7XG4gICAgICAgICAgICAgICAgeCA9IChjaGFydEFyZWEubGVmdCArIGNoYXJ0QXJlYS5yaWdodCkgLyAyIC0gdGlja0FuZFBhZGRpbmc7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGlzT2JqZWN0KHBvc2l0aW9uKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uQXhpc0lEID0gT2JqZWN0LmtleXMocG9zaXRpb24pWzBdO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gcG9zaXRpb25bcG9zaXRpb25BeGlzSURdO1xuICAgICAgICAgICAgICAgIHggPSB0aGlzLmNoYXJ0LnNjYWxlc1twb3NpdGlvbkF4aXNJRF0uZ2V0UGl4ZWxGb3JWYWx1ZSh2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0ZXh0QWxpZ24gPSB0aGlzLl9nZXRZQXhpc0xhYmVsQWxpZ25tZW50KHRsKS50ZXh0QWxpZ247XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGF4aXMgPT09ICd5Jykge1xuICAgICAgICAgICAgaWYgKGFsaWduID09PSAnc3RhcnQnKSB7XG4gICAgICAgICAgICAgICAgdGV4dEJhc2VsaW5lID0gJ3RvcCc7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGFsaWduID09PSAnZW5kJykge1xuICAgICAgICAgICAgICAgIHRleHRCYXNlbGluZSA9ICdib3R0b20nO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGxhYmVsU2l6ZXMgPSB0aGlzLl9nZXRMYWJlbFNpemVzKCk7XG4gICAgICAgIGZvcihpID0gMCwgaWxlbiA9IHRpY2tzLmxlbmd0aDsgaSA8IGlsZW47ICsraSl7XG4gICAgICAgICAgICB0aWNrID0gdGlja3NbaV07XG4gICAgICAgICAgICBsYWJlbCA9IHRpY2subGFiZWw7XG4gICAgICAgICAgICBjb25zdCBvcHRzQXRJbmRleCA9IG9wdGlvblRpY2tzLnNldENvbnRleHQodGhpcy5nZXRDb250ZXh0KGkpKTtcbiAgICAgICAgICAgIHBpeGVsID0gdGhpcy5nZXRQaXhlbEZvclRpY2soaSkgKyBvcHRpb25UaWNrcy5sYWJlbE9mZnNldDtcbiAgICAgICAgICAgIGZvbnQgPSB0aGlzLl9yZXNvbHZlVGlja0ZvbnRPcHRpb25zKGkpO1xuICAgICAgICAgICAgbGluZUhlaWdodCA9IGZvbnQubGluZUhlaWdodDtcbiAgICAgICAgICAgIGxpbmVDb3VudCA9IGlzQXJyYXkobGFiZWwpID8gbGFiZWwubGVuZ3RoIDogMTtcbiAgICAgICAgICAgIGNvbnN0IGhhbGZDb3VudCA9IGxpbmVDb3VudCAvIDI7XG4gICAgICAgICAgICBjb25zdCBjb2xvciA9IG9wdHNBdEluZGV4LmNvbG9yO1xuICAgICAgICAgICAgY29uc3Qgc3Ryb2tlQ29sb3IgPSBvcHRzQXRJbmRleC50ZXh0U3Ryb2tlQ29sb3I7XG4gICAgICAgICAgICBjb25zdCBzdHJva2VXaWR0aCA9IG9wdHNBdEluZGV4LnRleHRTdHJva2VXaWR0aDtcbiAgICAgICAgICAgIGxldCB0aWNrVGV4dEFsaWduID0gdGV4dEFsaWduO1xuICAgICAgICAgICAgaWYgKGlzSG9yaXpvbnRhbCkge1xuICAgICAgICAgICAgICAgIHggPSBwaXhlbDtcbiAgICAgICAgICAgICAgICBpZiAodGV4dEFsaWduID09PSAnaW5uZXInKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpID09PSBpbGVuIC0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGlja1RleHRBbGlnbiA9ICF0aGlzLm9wdGlvbnMucmV2ZXJzZSA/ICdyaWdodCcgOiAnbGVmdCc7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGlja1RleHRBbGlnbiA9ICF0aGlzLm9wdGlvbnMucmV2ZXJzZSA/ICdsZWZ0JyA6ICdyaWdodCc7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aWNrVGV4dEFsaWduID0gJ2NlbnRlcic7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09PSAndG9wJykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY3Jvc3NBbGlnbiA9PT0gJ25lYXInIHx8IHJvdGF0aW9uICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0T2Zmc2V0ID0gLWxpbmVDb3VudCAqIGxpbmVIZWlnaHQgKyBsaW5lSGVpZ2h0IC8gMjtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjcm9zc0FsaWduID09PSAnY2VudGVyJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dE9mZnNldCA9IC1sYWJlbFNpemVzLmhpZ2hlc3QuaGVpZ2h0IC8gMiAtIGhhbGZDb3VudCAqIGxpbmVIZWlnaHQgKyBsaW5lSGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dE9mZnNldCA9IC1sYWJlbFNpemVzLmhpZ2hlc3QuaGVpZ2h0ICsgbGluZUhlaWdodCAvIDI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY3Jvc3NBbGlnbiA9PT0gJ25lYXInIHx8IHJvdGF0aW9uICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0T2Zmc2V0ID0gbGluZUhlaWdodCAvIDI7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY3Jvc3NBbGlnbiA9PT0gJ2NlbnRlcicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHRPZmZzZXQgPSBsYWJlbFNpemVzLmhpZ2hlc3QuaGVpZ2h0IC8gMiAtIGhhbGZDb3VudCAqIGxpbmVIZWlnaHQ7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0T2Zmc2V0ID0gbGFiZWxTaXplcy5oaWdoZXN0LmhlaWdodCAtIGxpbmVDb3VudCAqIGxpbmVIZWlnaHQ7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG1pcnJvcikge1xuICAgICAgICAgICAgICAgICAgICB0ZXh0T2Zmc2V0ICo9IC0xO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocm90YXRpb24gIT09IDAgJiYgIW9wdHNBdEluZGV4LnNob3dMYWJlbEJhY2tkcm9wKSB7XG4gICAgICAgICAgICAgICAgICAgIHggKz0gbGluZUhlaWdodCAvIDIgKiBNYXRoLnNpbihyb3RhdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB5ID0gcGl4ZWw7XG4gICAgICAgICAgICAgICAgdGV4dE9mZnNldCA9ICgxIC0gbGluZUNvdW50KSAqIGxpbmVIZWlnaHQgLyAyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IGJhY2tkcm9wO1xuICAgICAgICAgICAgaWYgKG9wdHNBdEluZGV4LnNob3dMYWJlbEJhY2tkcm9wKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbGFiZWxQYWRkaW5nID0gdG9QYWRkaW5nKG9wdHNBdEluZGV4LmJhY2tkcm9wUGFkZGluZyk7XG4gICAgICAgICAgICAgICAgY29uc3QgaGVpZ2h0ID0gbGFiZWxTaXplcy5oZWlnaHRzW2ldO1xuICAgICAgICAgICAgICAgIGNvbnN0IHdpZHRoID0gbGFiZWxTaXplcy53aWR0aHNbaV07XG4gICAgICAgICAgICAgICAgbGV0IHRvcCA9IHRleHRPZmZzZXQgLSBsYWJlbFBhZGRpbmcudG9wO1xuICAgICAgICAgICAgICAgIGxldCBsZWZ0ID0gMCAtIGxhYmVsUGFkZGluZy5sZWZ0O1xuICAgICAgICAgICAgICAgIHN3aXRjaCh0ZXh0QmFzZWxpbmUpe1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdtaWRkbGUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgdG9wIC09IGhlaWdodCAvIDI7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYm90dG9tJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvcCAtPSBoZWlnaHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc3dpdGNoKHRleHRBbGlnbil7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2NlbnRlcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBsZWZ0IC09IHdpZHRoIC8gMjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdyaWdodCc6XG4gICAgICAgICAgICAgICAgICAgICAgICBsZWZ0IC09IHdpZHRoO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2lubmVyJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpID09PSBpbGVuIC0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZnQgLT0gd2lkdGg7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGkgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVmdCAtPSB3aWR0aCAvIDI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYmFja2Ryb3AgPSB7XG4gICAgICAgICAgICAgICAgICAgIGxlZnQsXG4gICAgICAgICAgICAgICAgICAgIHRvcCxcbiAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHdpZHRoICsgbGFiZWxQYWRkaW5nLndpZHRoLFxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCArIGxhYmVsUGFkZGluZy5oZWlnaHQsXG4gICAgICAgICAgICAgICAgICAgIGNvbG9yOiBvcHRzQXRJbmRleC5iYWNrZHJvcENvbG9yXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGl0ZW1zLnB1c2goe1xuICAgICAgICAgICAgICAgIGxhYmVsLFxuICAgICAgICAgICAgICAgIGZvbnQsXG4gICAgICAgICAgICAgICAgdGV4dE9mZnNldCxcbiAgICAgICAgICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgICAgICAgICAgIHJvdGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBjb2xvcixcbiAgICAgICAgICAgICAgICAgICAgc3Ryb2tlQ29sb3IsXG4gICAgICAgICAgICAgICAgICAgIHN0cm9rZVdpZHRoLFxuICAgICAgICAgICAgICAgICAgICB0ZXh0QWxpZ246IHRpY2tUZXh0QWxpZ24sXG4gICAgICAgICAgICAgICAgICAgIHRleHRCYXNlbGluZSxcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRpb246IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIHgsXG4gICAgICAgICAgICAgICAgICAgICAgICB5XG4gICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgICAgIGJhY2tkcm9wXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGl0ZW1zO1xuICAgIH1cbiAgICBfZ2V0WEF4aXNMYWJlbEFsaWdubWVudCgpIHtcbiAgICAgICAgY29uc3QgeyBwb3NpdGlvbiAsIHRpY2tzICB9ID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBjb25zdCByb3RhdGlvbiA9IC10b1JhZGlhbnModGhpcy5sYWJlbFJvdGF0aW9uKTtcbiAgICAgICAgaWYgKHJvdGF0aW9uKSB7XG4gICAgICAgICAgICByZXR1cm4gcG9zaXRpb24gPT09ICd0b3AnID8gJ2xlZnQnIDogJ3JpZ2h0JztcbiAgICAgICAgfVxuICAgICAgICBsZXQgYWxpZ24gPSAnY2VudGVyJztcbiAgICAgICAgaWYgKHRpY2tzLmFsaWduID09PSAnc3RhcnQnKSB7XG4gICAgICAgICAgICBhbGlnbiA9ICdsZWZ0JztcbiAgICAgICAgfSBlbHNlIGlmICh0aWNrcy5hbGlnbiA9PT0gJ2VuZCcpIHtcbiAgICAgICAgICAgIGFsaWduID0gJ3JpZ2h0JztcbiAgICAgICAgfSBlbHNlIGlmICh0aWNrcy5hbGlnbiA9PT0gJ2lubmVyJykge1xuICAgICAgICAgICAgYWxpZ24gPSAnaW5uZXInO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhbGlnbjtcbiAgICB9XG4gICAgX2dldFlBeGlzTGFiZWxBbGlnbm1lbnQodGwpIHtcbiAgICAgICAgY29uc3QgeyBwb3NpdGlvbiAsIHRpY2tzOiB7IGNyb3NzQWxpZ24gLCBtaXJyb3IgLCBwYWRkaW5nICB9ICB9ID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBjb25zdCBsYWJlbFNpemVzID0gdGhpcy5fZ2V0TGFiZWxTaXplcygpO1xuICAgICAgICBjb25zdCB0aWNrQW5kUGFkZGluZyA9IHRsICsgcGFkZGluZztcbiAgICAgICAgY29uc3Qgd2lkZXN0ID0gbGFiZWxTaXplcy53aWRlc3Qud2lkdGg7XG4gICAgICAgIGxldCB0ZXh0QWxpZ247XG4gICAgICAgIGxldCB4O1xuICAgICAgICBpZiAocG9zaXRpb24gPT09ICdsZWZ0Jykge1xuICAgICAgICAgICAgaWYgKG1pcnJvcikge1xuICAgICAgICAgICAgICAgIHggPSB0aGlzLnJpZ2h0ICsgcGFkZGluZztcbiAgICAgICAgICAgICAgICBpZiAoY3Jvc3NBbGlnbiA9PT0gJ25lYXInKSB7XG4gICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbiA9ICdsZWZ0JztcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNyb3NzQWxpZ24gPT09ICdjZW50ZXInKSB7XG4gICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbiA9ICdjZW50ZXInO1xuICAgICAgICAgICAgICAgICAgICB4ICs9IHdpZGVzdCAvIDI7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGV4dEFsaWduID0gJ3JpZ2h0JztcbiAgICAgICAgICAgICAgICAgICAgeCArPSB3aWRlc3Q7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB4ID0gdGhpcy5yaWdodCAtIHRpY2tBbmRQYWRkaW5nO1xuICAgICAgICAgICAgICAgIGlmIChjcm9zc0FsaWduID09PSAnbmVhcicpIHtcbiAgICAgICAgICAgICAgICAgICAgdGV4dEFsaWduID0gJ3JpZ2h0JztcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNyb3NzQWxpZ24gPT09ICdjZW50ZXInKSB7XG4gICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbiA9ICdjZW50ZXInO1xuICAgICAgICAgICAgICAgICAgICB4IC09IHdpZGVzdCAvIDI7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGV4dEFsaWduID0gJ2xlZnQnO1xuICAgICAgICAgICAgICAgICAgICB4ID0gdGhpcy5sZWZ0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChwb3NpdGlvbiA9PT0gJ3JpZ2h0Jykge1xuICAgICAgICAgICAgaWYgKG1pcnJvcikge1xuICAgICAgICAgICAgICAgIHggPSB0aGlzLmxlZnQgKyBwYWRkaW5nO1xuICAgICAgICAgICAgICAgIGlmIChjcm9zc0FsaWduID09PSAnbmVhcicpIHtcbiAgICAgICAgICAgICAgICAgICAgdGV4dEFsaWduID0gJ3JpZ2h0JztcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNyb3NzQWxpZ24gPT09ICdjZW50ZXInKSB7XG4gICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbiA9ICdjZW50ZXInO1xuICAgICAgICAgICAgICAgICAgICB4IC09IHdpZGVzdCAvIDI7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGV4dEFsaWduID0gJ2xlZnQnO1xuICAgICAgICAgICAgICAgICAgICB4IC09IHdpZGVzdDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHggPSB0aGlzLmxlZnQgKyB0aWNrQW5kUGFkZGluZztcbiAgICAgICAgICAgICAgICBpZiAoY3Jvc3NBbGlnbiA9PT0gJ25lYXInKSB7XG4gICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbiA9ICdsZWZ0JztcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNyb3NzQWxpZ24gPT09ICdjZW50ZXInKSB7XG4gICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbiA9ICdjZW50ZXInO1xuICAgICAgICAgICAgICAgICAgICB4ICs9IHdpZGVzdCAvIDI7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGV4dEFsaWduID0gJ3JpZ2h0JztcbiAgICAgICAgICAgICAgICAgICAgeCA9IHRoaXMucmlnaHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGV4dEFsaWduID0gJ3JpZ2h0JztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdGV4dEFsaWduLFxuICAgICAgICAgICAgeFxuICAgICAgICB9O1xuICAgIH1cbiBfY29tcHV0ZUxhYmVsQXJlYSgpIHtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy50aWNrcy5taXJyb3IpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjaGFydCA9IHRoaXMuY2hhcnQ7XG4gICAgICAgIGNvbnN0IHBvc2l0aW9uID0gdGhpcy5vcHRpb25zLnBvc2l0aW9uO1xuICAgICAgICBpZiAocG9zaXRpb24gPT09ICdsZWZ0JyB8fCBwb3NpdGlvbiA9PT0gJ3JpZ2h0Jykge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB0b3A6IDAsXG4gICAgICAgICAgICAgICAgbGVmdDogdGhpcy5sZWZ0LFxuICAgICAgICAgICAgICAgIGJvdHRvbTogY2hhcnQuaGVpZ2h0LFxuICAgICAgICAgICAgICAgIHJpZ2h0OiB0aGlzLnJpZ2h0XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGlmIChwb3NpdGlvbiA9PT0gJ3RvcCcgfHwgcG9zaXRpb24gPT09ICdib3R0b20nKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHRvcDogdGhpcy50b3AsXG4gICAgICAgICAgICAgICAgbGVmdDogMCxcbiAgICAgICAgICAgICAgICBib3R0b206IHRoaXMuYm90dG9tLFxuICAgICAgICAgICAgICAgIHJpZ2h0OiBjaGFydC53aWR0aFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH1cbiBkcmF3QmFja2dyb3VuZCgpIHtcbiAgICAgICAgY29uc3QgeyBjdHggLCBvcHRpb25zOiB7IGJhY2tncm91bmRDb2xvciAgfSAsIGxlZnQgLCB0b3AgLCB3aWR0aCAsIGhlaWdodCAgfSA9IHRoaXM7XG4gICAgICAgIGlmIChiYWNrZ3JvdW5kQ29sb3IpIHtcbiAgICAgICAgICAgIGN0eC5zYXZlKCk7XG4gICAgICAgICAgICBjdHguZmlsbFN0eWxlID0gYmFja2dyb3VuZENvbG9yO1xuICAgICAgICAgICAgY3R4LmZpbGxSZWN0KGxlZnQsIHRvcCwgd2lkdGgsIGhlaWdodCk7XG4gICAgICAgICAgICBjdHgucmVzdG9yZSgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldExpbmVXaWR0aEZvclZhbHVlKHZhbHVlKSB7XG4gICAgICAgIGNvbnN0IGdyaWQgPSB0aGlzLm9wdGlvbnMuZ3JpZDtcbiAgICAgICAgaWYgKCF0aGlzLl9pc1Zpc2libGUoKSB8fCAhZ3JpZC5kaXNwbGF5KSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMudGlja3M7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGlja3MuZmluZEluZGV4KCh0KT0+dC52YWx1ZSA9PT0gdmFsdWUpO1xuICAgICAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgICAgICAgY29uc3Qgb3B0cyA9IGdyaWQuc2V0Q29udGV4dCh0aGlzLmdldENvbnRleHQoaW5kZXgpKTtcbiAgICAgICAgICAgIHJldHVybiBvcHRzLmxpbmVXaWR0aDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gZHJhd0dyaWQoY2hhcnRBcmVhKSB7XG4gICAgICAgIGNvbnN0IGdyaWQgPSB0aGlzLm9wdGlvbnMuZ3JpZDtcbiAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgICAgIGNvbnN0IGl0ZW1zID0gdGhpcy5fZ3JpZExpbmVJdGVtcyB8fCAodGhpcy5fZ3JpZExpbmVJdGVtcyA9IHRoaXMuX2NvbXB1dGVHcmlkTGluZUl0ZW1zKGNoYXJ0QXJlYSkpO1xuICAgICAgICBsZXQgaSwgaWxlbjtcbiAgICAgICAgY29uc3QgZHJhd0xpbmUgPSAocDEsIHAyLCBzdHlsZSk9PntcbiAgICAgICAgICAgIGlmICghc3R5bGUud2lkdGggfHwgIXN0eWxlLmNvbG9yKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY3R4LnNhdmUoKTtcbiAgICAgICAgICAgIGN0eC5saW5lV2lkdGggPSBzdHlsZS53aWR0aDtcbiAgICAgICAgICAgIGN0eC5zdHJva2VTdHlsZSA9IHN0eWxlLmNvbG9yO1xuICAgICAgICAgICAgY3R4LnNldExpbmVEYXNoKHN0eWxlLmJvcmRlckRhc2ggfHwgW10pO1xuICAgICAgICAgICAgY3R4LmxpbmVEYXNoT2Zmc2V0ID0gc3R5bGUuYm9yZGVyRGFzaE9mZnNldDtcbiAgICAgICAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgICAgICAgIGN0eC5tb3ZlVG8ocDEueCwgcDEueSk7XG4gICAgICAgICAgICBjdHgubGluZVRvKHAyLngsIHAyLnkpO1xuICAgICAgICAgICAgY3R4LnN0cm9rZSgpO1xuICAgICAgICAgICAgY3R4LnJlc3RvcmUoKTtcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGdyaWQuZGlzcGxheSkge1xuICAgICAgICAgICAgZm9yKGkgPSAwLCBpbGVuID0gaXRlbXMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKXtcbiAgICAgICAgICAgICAgICBjb25zdCBpdGVtID0gaXRlbXNbaV07XG4gICAgICAgICAgICAgICAgaWYgKGdyaWQuZHJhd09uQ2hhcnRBcmVhKSB7XG4gICAgICAgICAgICAgICAgICAgIGRyYXdMaW5lKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHg6IGl0ZW0ueDEsXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiBpdGVtLnkxXG4gICAgICAgICAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHg6IGl0ZW0ueDIsXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiBpdGVtLnkyXG4gICAgICAgICAgICAgICAgICAgIH0sIGl0ZW0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoZ3JpZC5kcmF3VGlja3MpIHtcbiAgICAgICAgICAgICAgICAgICAgZHJhd0xpbmUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgeDogaXRlbS50eDEsXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiBpdGVtLnR5MVxuICAgICAgICAgICAgICAgICAgICB9LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICB4OiBpdGVtLnR4MixcbiAgICAgICAgICAgICAgICAgICAgICAgIHk6IGl0ZW0udHkyXG4gICAgICAgICAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yOiBpdGVtLnRpY2tDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiBpdGVtLnRpY2tXaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGJvcmRlckRhc2g6IGl0ZW0udGlja0JvcmRlckRhc2gsXG4gICAgICAgICAgICAgICAgICAgICAgICBib3JkZXJEYXNoT2Zmc2V0OiBpdGVtLnRpY2tCb3JkZXJEYXNoT2Zmc2V0XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiBkcmF3Qm9yZGVyKCkge1xuICAgICAgICBjb25zdCB7IGNoYXJ0ICwgY3R4ICwgb3B0aW9uczogeyBib3JkZXIgLCBncmlkICB9ICB9ID0gdGhpcztcbiAgICAgICAgY29uc3QgYm9yZGVyT3B0cyA9IGJvcmRlci5zZXRDb250ZXh0KHRoaXMuZ2V0Q29udGV4dCgpKTtcbiAgICAgICAgY29uc3QgYXhpc1dpZHRoID0gYm9yZGVyLmRpc3BsYXkgPyBib3JkZXJPcHRzLndpZHRoIDogMDtcbiAgICAgICAgaWYgKCFheGlzV2lkdGgpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBsYXN0TGluZVdpZHRoID0gZ3JpZC5zZXRDb250ZXh0KHRoaXMuZ2V0Q29udGV4dCgwKSkubGluZVdpZHRoO1xuICAgICAgICBjb25zdCBib3JkZXJWYWx1ZSA9IHRoaXMuX2JvcmRlclZhbHVlO1xuICAgICAgICBsZXQgeDEsIHgyLCB5MSwgeTI7XG4gICAgICAgIGlmICh0aGlzLmlzSG9yaXpvbnRhbCgpKSB7XG4gICAgICAgICAgICB4MSA9IF9hbGlnblBpeGVsKGNoYXJ0LCB0aGlzLmxlZnQsIGF4aXNXaWR0aCkgLSBheGlzV2lkdGggLyAyO1xuICAgICAgICAgICAgeDIgPSBfYWxpZ25QaXhlbChjaGFydCwgdGhpcy5yaWdodCwgbGFzdExpbmVXaWR0aCkgKyBsYXN0TGluZVdpZHRoIC8gMjtcbiAgICAgICAgICAgIHkxID0geTIgPSBib3JkZXJWYWx1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHkxID0gX2FsaWduUGl4ZWwoY2hhcnQsIHRoaXMudG9wLCBheGlzV2lkdGgpIC0gYXhpc1dpZHRoIC8gMjtcbiAgICAgICAgICAgIHkyID0gX2FsaWduUGl4ZWwoY2hhcnQsIHRoaXMuYm90dG9tLCBsYXN0TGluZVdpZHRoKSArIGxhc3RMaW5lV2lkdGggLyAyO1xuICAgICAgICAgICAgeDEgPSB4MiA9IGJvcmRlclZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGN0eC5zYXZlKCk7XG4gICAgICAgIGN0eC5saW5lV2lkdGggPSBib3JkZXJPcHRzLndpZHRoO1xuICAgICAgICBjdHguc3Ryb2tlU3R5bGUgPSBib3JkZXJPcHRzLmNvbG9yO1xuICAgICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICAgIGN0eC5tb3ZlVG8oeDEsIHkxKTtcbiAgICAgICAgY3R4LmxpbmVUbyh4MiwgeTIpO1xuICAgICAgICBjdHguc3Ryb2tlKCk7XG4gICAgICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgfVxuIGRyYXdMYWJlbHMoY2hhcnRBcmVhKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvblRpY2tzID0gdGhpcy5vcHRpb25zLnRpY2tzO1xuICAgICAgICBpZiAoIW9wdGlvblRpY2tzLmRpc3BsYXkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjdHggPSB0aGlzLmN0eDtcbiAgICAgICAgY29uc3QgYXJlYSA9IHRoaXMuX2NvbXB1dGVMYWJlbEFyZWEoKTtcbiAgICAgICAgaWYgKGFyZWEpIHtcbiAgICAgICAgICAgIGNsaXBBcmVhKGN0eCwgYXJlYSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaXRlbXMgPSB0aGlzLmdldExhYmVsSXRlbXMoY2hhcnRBcmVhKTtcbiAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGl0ZW1zKXtcbiAgICAgICAgICAgIGNvbnN0IHJlbmRlclRleHRPcHRpb25zID0gaXRlbS5vcHRpb25zO1xuICAgICAgICAgICAgY29uc3QgdGlja0ZvbnQgPSBpdGVtLmZvbnQ7XG4gICAgICAgICAgICBjb25zdCBsYWJlbCA9IGl0ZW0ubGFiZWw7XG4gICAgICAgICAgICBjb25zdCB5ID0gaXRlbS50ZXh0T2Zmc2V0O1xuICAgICAgICAgICAgcmVuZGVyVGV4dChjdHgsIGxhYmVsLCAwLCB5LCB0aWNrRm9udCwgcmVuZGVyVGV4dE9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChhcmVhKSB7XG4gICAgICAgICAgICB1bmNsaXBBcmVhKGN0eCk7XG4gICAgICAgIH1cbiAgICB9XG4gZHJhd1RpdGxlKCkge1xuICAgICAgICBjb25zdCB7IGN0eCAsIG9wdGlvbnM6IHsgcG9zaXRpb24gLCB0aXRsZSAsIHJldmVyc2UgIH0gIH0gPSB0aGlzO1xuICAgICAgICBpZiAoIXRpdGxlLmRpc3BsYXkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBmb250ID0gdG9Gb250KHRpdGxlLmZvbnQpO1xuICAgICAgICBjb25zdCBwYWRkaW5nID0gdG9QYWRkaW5nKHRpdGxlLnBhZGRpbmcpO1xuICAgICAgICBjb25zdCBhbGlnbiA9IHRpdGxlLmFsaWduO1xuICAgICAgICBsZXQgb2Zmc2V0ID0gZm9udC5saW5lSGVpZ2h0IC8gMjtcbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSAnYm90dG9tJyB8fCBwb3NpdGlvbiA9PT0gJ2NlbnRlcicgfHwgaXNPYmplY3QocG9zaXRpb24pKSB7XG4gICAgICAgICAgICBvZmZzZXQgKz0gcGFkZGluZy5ib3R0b207XG4gICAgICAgICAgICBpZiAoaXNBcnJheSh0aXRsZS50ZXh0KSkge1xuICAgICAgICAgICAgICAgIG9mZnNldCArPSBmb250LmxpbmVIZWlnaHQgKiAodGl0bGUudGV4dC5sZW5ndGggLSAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG9mZnNldCArPSBwYWRkaW5nLnRvcDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IHRpdGxlWCAsIHRpdGxlWSAsIG1heFdpZHRoICwgcm90YXRpb24gIH0gPSB0aXRsZUFyZ3ModGhpcywgb2Zmc2V0LCBwb3NpdGlvbiwgYWxpZ24pO1xuICAgICAgICByZW5kZXJUZXh0KGN0eCwgdGl0bGUudGV4dCwgMCwgMCwgZm9udCwge1xuICAgICAgICAgICAgY29sb3I6IHRpdGxlLmNvbG9yLFxuICAgICAgICAgICAgbWF4V2lkdGgsXG4gICAgICAgICAgICByb3RhdGlvbixcbiAgICAgICAgICAgIHRleHRBbGlnbjogdGl0bGVBbGlnbihhbGlnbiwgcG9zaXRpb24sIHJldmVyc2UpLFxuICAgICAgICAgICAgdGV4dEJhc2VsaW5lOiAnbWlkZGxlJyxcbiAgICAgICAgICAgIHRyYW5zbGF0aW9uOiBbXG4gICAgICAgICAgICAgICAgdGl0bGVYLFxuICAgICAgICAgICAgICAgIHRpdGxlWVxuICAgICAgICAgICAgXVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZHJhdyhjaGFydEFyZWEpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9pc1Zpc2libGUoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZHJhd0JhY2tncm91bmQoKTtcbiAgICAgICAgdGhpcy5kcmF3R3JpZChjaGFydEFyZWEpO1xuICAgICAgICB0aGlzLmRyYXdCb3JkZXIoKTtcbiAgICAgICAgdGhpcy5kcmF3VGl0bGUoKTtcbiAgICAgICAgdGhpcy5kcmF3TGFiZWxzKGNoYXJ0QXJlYSk7XG4gICAgfVxuIF9sYXllcnMoKSB7XG4gICAgICAgIGNvbnN0IG9wdHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGNvbnN0IHR6ID0gb3B0cy50aWNrcyAmJiBvcHRzLnRpY2tzLnogfHwgMDtcbiAgICAgICAgY29uc3QgZ3ogPSB2YWx1ZU9yRGVmYXVsdChvcHRzLmdyaWQgJiYgb3B0cy5ncmlkLnosIC0xKTtcbiAgICAgICAgY29uc3QgYnogPSB2YWx1ZU9yRGVmYXVsdChvcHRzLmJvcmRlciAmJiBvcHRzLmJvcmRlci56LCAwKTtcbiAgICAgICAgaWYgKCF0aGlzLl9pc1Zpc2libGUoKSB8fCB0aGlzLmRyYXcgIT09IFNjYWxlLnByb3RvdHlwZS5kcmF3KSB7XG4gICAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgejogdHosXG4gICAgICAgICAgICAgICAgICAgIGRyYXc6IChjaGFydEFyZWEpPT57XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYXcoY2hhcnRBcmVhKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB6OiBneixcbiAgICAgICAgICAgICAgICBkcmF3OiAoY2hhcnRBcmVhKT0+e1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYXdCYWNrZ3JvdW5kKCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhd0dyaWQoY2hhcnRBcmVhKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmF3VGl0bGUoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHo6IGJ6LFxuICAgICAgICAgICAgICAgIGRyYXc6ICgpPT57XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhd0JvcmRlcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgejogdHosXG4gICAgICAgICAgICAgICAgZHJhdzogKGNoYXJ0QXJlYSk9PntcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmF3TGFiZWxzKGNoYXJ0QXJlYSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICBdO1xuICAgIH1cbiBnZXRNYXRjaGluZ1Zpc2libGVNZXRhcyh0eXBlKSB7XG4gICAgICAgIGNvbnN0IG1ldGFzID0gdGhpcy5jaGFydC5nZXRTb3J0ZWRWaXNpYmxlRGF0YXNldE1ldGFzKCk7XG4gICAgICAgIGNvbnN0IGF4aXNJRCA9IHRoaXMuYXhpcyArICdBeGlzSUQnO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBbXTtcbiAgICAgICAgbGV0IGksIGlsZW47XG4gICAgICAgIGZvcihpID0gMCwgaWxlbiA9IG1ldGFzLmxlbmd0aDsgaSA8IGlsZW47ICsraSl7XG4gICAgICAgICAgICBjb25zdCBtZXRhID0gbWV0YXNbaV07XG4gICAgICAgICAgICBpZiAobWV0YVtheGlzSURdID09PSB0aGlzLmlkICYmICghdHlwZSB8fCBtZXRhLnR5cGUgPT09IHR5cGUpKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2gobWV0YSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gX3Jlc29sdmVUaWNrRm9udE9wdGlvbnMoaW5kZXgpIHtcbiAgICAgICAgY29uc3Qgb3B0cyA9IHRoaXMub3B0aW9ucy50aWNrcy5zZXRDb250ZXh0KHRoaXMuZ2V0Q29udGV4dChpbmRleCkpO1xuICAgICAgICByZXR1cm4gdG9Gb250KG9wdHMuZm9udCk7XG4gICAgfVxuIF9tYXhEaWdpdHMoKSB7XG4gICAgICAgIGNvbnN0IGZvbnRTaXplID0gdGhpcy5fcmVzb2x2ZVRpY2tGb250T3B0aW9ucygwKS5saW5lSGVpZ2h0O1xuICAgICAgICByZXR1cm4gKHRoaXMuaXNIb3Jpem9udGFsKCkgPyB0aGlzLndpZHRoIDogdGhpcy5oZWlnaHQpIC8gZm9udFNpemU7XG4gICAgfVxufVxuXG5jbGFzcyBUeXBlZFJlZ2lzdHJ5IHtcbiAgICBjb25zdHJ1Y3Rvcih0eXBlLCBzY29wZSwgb3ZlcnJpZGUpe1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLnNjb3BlID0gc2NvcGU7XG4gICAgICAgIHRoaXMub3ZlcnJpZGUgPSBvdmVycmlkZTtcbiAgICAgICAgdGhpcy5pdGVtcyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgfVxuICAgIGlzRm9yVHlwZSh0eXBlKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLmlzUHJvdG90eXBlT2YuY2FsbCh0aGlzLnR5cGUucHJvdG90eXBlLCB0eXBlLnByb3RvdHlwZSk7XG4gICAgfVxuIHJlZ2lzdGVyKGl0ZW0pIHtcbiAgICAgICAgY29uc3QgcHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoaXRlbSk7XG4gICAgICAgIGxldCBwYXJlbnRTY29wZTtcbiAgICAgICAgaWYgKGlzSUNoYXJ0Q29tcG9uZW50KHByb3RvKSkge1xuICAgICAgICAgICAgcGFyZW50U2NvcGUgPSB0aGlzLnJlZ2lzdGVyKHByb3RvKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpdGVtcyA9IHRoaXMuaXRlbXM7XG4gICAgICAgIGNvbnN0IGlkID0gaXRlbS5pZDtcbiAgICAgICAgY29uc3Qgc2NvcGUgPSB0aGlzLnNjb3BlICsgJy4nICsgaWQ7XG4gICAgICAgIGlmICghaWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignY2xhc3MgZG9lcyBub3QgaGF2ZSBpZDogJyArIGl0ZW0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpZCBpbiBpdGVtcykge1xuICAgICAgICAgICAgcmV0dXJuIHNjb3BlO1xuICAgICAgICB9XG4gICAgICAgIGl0ZW1zW2lkXSA9IGl0ZW07XG4gICAgICAgIHJlZ2lzdGVyRGVmYXVsdHMoaXRlbSwgc2NvcGUsIHBhcmVudFNjb3BlKTtcbiAgICAgICAgaWYgKHRoaXMub3ZlcnJpZGUpIHtcbiAgICAgICAgICAgIGRlZmF1bHRzLm92ZXJyaWRlKGl0ZW0uaWQsIGl0ZW0ub3ZlcnJpZGVzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2NvcGU7XG4gICAgfVxuIGdldChpZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pdGVtc1tpZF07XG4gICAgfVxuIHVucmVnaXN0ZXIoaXRlbSkge1xuICAgICAgICBjb25zdCBpdGVtcyA9IHRoaXMuaXRlbXM7XG4gICAgICAgIGNvbnN0IGlkID0gaXRlbS5pZDtcbiAgICAgICAgY29uc3Qgc2NvcGUgPSB0aGlzLnNjb3BlO1xuICAgICAgICBpZiAoaWQgaW4gaXRlbXMpIHtcbiAgICAgICAgICAgIGRlbGV0ZSBpdGVtc1tpZF07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNjb3BlICYmIGlkIGluIGRlZmF1bHRzW3Njb3BlXSkge1xuICAgICAgICAgICAgZGVsZXRlIGRlZmF1bHRzW3Njb3BlXVtpZF07XG4gICAgICAgICAgICBpZiAodGhpcy5vdmVycmlkZSkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBvdmVycmlkZXNbaWRdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gcmVnaXN0ZXJEZWZhdWx0cyhpdGVtLCBzY29wZSwgcGFyZW50U2NvcGUpIHtcbiAgICBjb25zdCBpdGVtRGVmYXVsdHMgPSBtZXJnZShPYmplY3QuY3JlYXRlKG51bGwpLCBbXG4gICAgICAgIHBhcmVudFNjb3BlID8gZGVmYXVsdHMuZ2V0KHBhcmVudFNjb3BlKSA6IHt9LFxuICAgICAgICBkZWZhdWx0cy5nZXQoc2NvcGUpLFxuICAgICAgICBpdGVtLmRlZmF1bHRzXG4gICAgXSk7XG4gICAgZGVmYXVsdHMuc2V0KHNjb3BlLCBpdGVtRGVmYXVsdHMpO1xuICAgIGlmIChpdGVtLmRlZmF1bHRSb3V0ZXMpIHtcbiAgICAgICAgcm91dGVEZWZhdWx0cyhzY29wZSwgaXRlbS5kZWZhdWx0Um91dGVzKTtcbiAgICB9XG4gICAgaWYgKGl0ZW0uZGVzY3JpcHRvcnMpIHtcbiAgICAgICAgZGVmYXVsdHMuZGVzY3JpYmUoc2NvcGUsIGl0ZW0uZGVzY3JpcHRvcnMpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHJvdXRlRGVmYXVsdHMoc2NvcGUsIHJvdXRlcykge1xuICAgIE9iamVjdC5rZXlzKHJvdXRlcykuZm9yRWFjaCgocHJvcGVydHkpPT57XG4gICAgICAgIGNvbnN0IHByb3BlcnR5UGFydHMgPSBwcm9wZXJ0eS5zcGxpdCgnLicpO1xuICAgICAgICBjb25zdCBzb3VyY2VOYW1lID0gcHJvcGVydHlQYXJ0cy5wb3AoKTtcbiAgICAgICAgY29uc3Qgc291cmNlU2NvcGUgPSBbXG4gICAgICAgICAgICBzY29wZVxuICAgICAgICBdLmNvbmNhdChwcm9wZXJ0eVBhcnRzKS5qb2luKCcuJyk7XG4gICAgICAgIGNvbnN0IHBhcnRzID0gcm91dGVzW3Byb3BlcnR5XS5zcGxpdCgnLicpO1xuICAgICAgICBjb25zdCB0YXJnZXROYW1lID0gcGFydHMucG9wKCk7XG4gICAgICAgIGNvbnN0IHRhcmdldFNjb3BlID0gcGFydHMuam9pbignLicpO1xuICAgICAgICBkZWZhdWx0cy5yb3V0ZShzb3VyY2VTY29wZSwgc291cmNlTmFtZSwgdGFyZ2V0U2NvcGUsIHRhcmdldE5hbWUpO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gaXNJQ2hhcnRDb21wb25lbnQocHJvdG8pIHtcbiAgICByZXR1cm4gJ2lkJyBpbiBwcm90byAmJiAnZGVmYXVsdHMnIGluIHByb3RvO1xufVxuXG5jbGFzcyBSZWdpc3RyeSB7XG4gICAgY29uc3RydWN0b3IoKXtcbiAgICAgICAgdGhpcy5jb250cm9sbGVycyA9IG5ldyBUeXBlZFJlZ2lzdHJ5KERhdGFzZXRDb250cm9sbGVyLCAnZGF0YXNldHMnLCB0cnVlKTtcbiAgICAgICAgdGhpcy5lbGVtZW50cyA9IG5ldyBUeXBlZFJlZ2lzdHJ5KEVsZW1lbnQsICdlbGVtZW50cycpO1xuICAgICAgICB0aGlzLnBsdWdpbnMgPSBuZXcgVHlwZWRSZWdpc3RyeShPYmplY3QsICdwbHVnaW5zJyk7XG4gICAgICAgIHRoaXMuc2NhbGVzID0gbmV3IFR5cGVkUmVnaXN0cnkoU2NhbGUsICdzY2FsZXMnKTtcbiAgICAgICAgdGhpcy5fdHlwZWRSZWdpc3RyaWVzID0gW1xuICAgICAgICAgICAgdGhpcy5jb250cm9sbGVycyxcbiAgICAgICAgICAgIHRoaXMuc2NhbGVzLFxuICAgICAgICAgICAgdGhpcy5lbGVtZW50c1xuICAgICAgICBdO1xuICAgIH1cbiBhZGQoLi4uYXJncykge1xuICAgICAgICB0aGlzLl9lYWNoKCdyZWdpc3RlcicsIGFyZ3MpO1xuICAgIH1cbiAgICByZW1vdmUoLi4uYXJncykge1xuICAgICAgICB0aGlzLl9lYWNoKCd1bnJlZ2lzdGVyJywgYXJncyk7XG4gICAgfVxuIGFkZENvbnRyb2xsZXJzKC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5fZWFjaCgncmVnaXN0ZXInLCBhcmdzLCB0aGlzLmNvbnRyb2xsZXJzKTtcbiAgICB9XG4gYWRkRWxlbWVudHMoLi4uYXJncykge1xuICAgICAgICB0aGlzLl9lYWNoKCdyZWdpc3RlcicsIGFyZ3MsIHRoaXMuZWxlbWVudHMpO1xuICAgIH1cbiBhZGRQbHVnaW5zKC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5fZWFjaCgncmVnaXN0ZXInLCBhcmdzLCB0aGlzLnBsdWdpbnMpO1xuICAgIH1cbiBhZGRTY2FsZXMoLi4uYXJncykge1xuICAgICAgICB0aGlzLl9lYWNoKCdyZWdpc3RlcicsIGFyZ3MsIHRoaXMuc2NhbGVzKTtcbiAgICB9XG4gZ2V0Q29udHJvbGxlcihpZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0KGlkLCB0aGlzLmNvbnRyb2xsZXJzLCAnY29udHJvbGxlcicpO1xuICAgIH1cbiBnZXRFbGVtZW50KGlkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXQoaWQsIHRoaXMuZWxlbWVudHMsICdlbGVtZW50Jyk7XG4gICAgfVxuIGdldFBsdWdpbihpZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0KGlkLCB0aGlzLnBsdWdpbnMsICdwbHVnaW4nKTtcbiAgICB9XG4gZ2V0U2NhbGUoaWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldChpZCwgdGhpcy5zY2FsZXMsICdzY2FsZScpO1xuICAgIH1cbiByZW1vdmVDb250cm9sbGVycyguLi5hcmdzKSB7XG4gICAgICAgIHRoaXMuX2VhY2goJ3VucmVnaXN0ZXInLCBhcmdzLCB0aGlzLmNvbnRyb2xsZXJzKTtcbiAgICB9XG4gcmVtb3ZlRWxlbWVudHMoLi4uYXJncykge1xuICAgICAgICB0aGlzLl9lYWNoKCd1bnJlZ2lzdGVyJywgYXJncywgdGhpcy5lbGVtZW50cyk7XG4gICAgfVxuIHJlbW92ZVBsdWdpbnMoLi4uYXJncykge1xuICAgICAgICB0aGlzLl9lYWNoKCd1bnJlZ2lzdGVyJywgYXJncywgdGhpcy5wbHVnaW5zKTtcbiAgICB9XG4gcmVtb3ZlU2NhbGVzKC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5fZWFjaCgndW5yZWdpc3RlcicsIGFyZ3MsIHRoaXMuc2NhbGVzKTtcbiAgICB9XG4gX2VhY2gobWV0aG9kLCBhcmdzLCB0eXBlZFJlZ2lzdHJ5KSB7XG4gICAgICAgIFtcbiAgICAgICAgICAgIC4uLmFyZ3NcbiAgICAgICAgXS5mb3JFYWNoKChhcmcpPT57XG4gICAgICAgICAgICBjb25zdCByZWcgPSB0eXBlZFJlZ2lzdHJ5IHx8IHRoaXMuX2dldFJlZ2lzdHJ5Rm9yVHlwZShhcmcpO1xuICAgICAgICAgICAgaWYgKHR5cGVkUmVnaXN0cnkgfHwgcmVnLmlzRm9yVHlwZShhcmcpIHx8IHJlZyA9PT0gdGhpcy5wbHVnaW5zICYmIGFyZy5pZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2V4ZWMobWV0aG9kLCByZWcsIGFyZyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGVhY2goYXJnLCAoaXRlbSk9PntcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaXRlbVJlZyA9IHR5cGVkUmVnaXN0cnkgfHwgdGhpcy5fZ2V0UmVnaXN0cnlGb3JUeXBlKGl0ZW0pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9leGVjKG1ldGhvZCwgaXRlbVJlZywgaXRlbSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiBfZXhlYyhtZXRob2QsIHJlZ2lzdHJ5LCBjb21wb25lbnQpIHtcbiAgICAgICAgY29uc3QgY2FtZWxNZXRob2QgPSBfY2FwaXRhbGl6ZShtZXRob2QpO1xuICAgICAgICBjYWxsYmFjayhjb21wb25lbnRbJ2JlZm9yZScgKyBjYW1lbE1ldGhvZF0sIFtdLCBjb21wb25lbnQpO1xuICAgICAgICByZWdpc3RyeVttZXRob2RdKGNvbXBvbmVudCk7XG4gICAgICAgIGNhbGxiYWNrKGNvbXBvbmVudFsnYWZ0ZXInICsgY2FtZWxNZXRob2RdLCBbXSwgY29tcG9uZW50KTtcbiAgICB9XG4gX2dldFJlZ2lzdHJ5Rm9yVHlwZSh0eXBlKSB7XG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCB0aGlzLl90eXBlZFJlZ2lzdHJpZXMubGVuZ3RoOyBpKyspe1xuICAgICAgICAgICAgY29uc3QgcmVnID0gdGhpcy5fdHlwZWRSZWdpc3RyaWVzW2ldO1xuICAgICAgICAgICAgaWYgKHJlZy5pc0ZvclR5cGUodHlwZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVnO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnBsdWdpbnM7XG4gICAgfVxuIF9nZXQoaWQsIHR5cGVkUmVnaXN0cnksIHR5cGUpIHtcbiAgICAgICAgY29uc3QgaXRlbSA9IHR5cGVkUmVnaXN0cnkuZ2V0KGlkKTtcbiAgICAgICAgaWYgKGl0ZW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdcIicgKyBpZCArICdcIiBpcyBub3QgYSByZWdpc3RlcmVkICcgKyB0eXBlICsgJy4nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXRlbTtcbiAgICB9XG59XG52YXIgcmVnaXN0cnkgPSAvKiAjX19QVVJFX18gKi8gbmV3IFJlZ2lzdHJ5KCk7XG5cbmNsYXNzIFBsdWdpblNlcnZpY2Uge1xuICAgIGNvbnN0cnVjdG9yKCl7XG4gICAgICAgIHRoaXMuX2luaXQgPSBbXTtcbiAgICB9XG4gbm90aWZ5KGNoYXJ0LCBob29rLCBhcmdzLCBmaWx0ZXIpIHtcbiAgICAgICAgaWYgKGhvb2sgPT09ICdiZWZvcmVJbml0Jykge1xuICAgICAgICAgICAgdGhpcy5faW5pdCA9IHRoaXMuX2NyZWF0ZURlc2NyaXB0b3JzKGNoYXJ0LCB0cnVlKTtcbiAgICAgICAgICAgIHRoaXMuX25vdGlmeSh0aGlzLl9pbml0LCBjaGFydCwgJ2luc3RhbGwnKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkZXNjcmlwdG9ycyA9IGZpbHRlciA/IHRoaXMuX2Rlc2NyaXB0b3JzKGNoYXJ0KS5maWx0ZXIoZmlsdGVyKSA6IHRoaXMuX2Rlc2NyaXB0b3JzKGNoYXJ0KTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fbm90aWZ5KGRlc2NyaXB0b3JzLCBjaGFydCwgaG9vaywgYXJncyk7XG4gICAgICAgIGlmIChob29rID09PSAnYWZ0ZXJEZXN0cm95Jykge1xuICAgICAgICAgICAgdGhpcy5fbm90aWZ5KGRlc2NyaXB0b3JzLCBjaGFydCwgJ3N0b3AnKTtcbiAgICAgICAgICAgIHRoaXMuX25vdGlmeSh0aGlzLl9pbml0LCBjaGFydCwgJ3VuaW5zdGFsbCcpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuIF9ub3RpZnkoZGVzY3JpcHRvcnMsIGNoYXJ0LCBob29rLCBhcmdzKSB7XG4gICAgICAgIGFyZ3MgPSBhcmdzIHx8IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IGRlc2NyaXB0b3Igb2YgZGVzY3JpcHRvcnMpe1xuICAgICAgICAgICAgY29uc3QgcGx1Z2luID0gZGVzY3JpcHRvci5wbHVnaW47XG4gICAgICAgICAgICBjb25zdCBtZXRob2QgPSBwbHVnaW5baG9va107XG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSBbXG4gICAgICAgICAgICAgICAgY2hhcnQsXG4gICAgICAgICAgICAgICAgYXJncyxcbiAgICAgICAgICAgICAgICBkZXNjcmlwdG9yLm9wdGlvbnNcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgICBpZiAoY2FsbGJhY2sobWV0aG9kLCBwYXJhbXMsIHBsdWdpbikgPT09IGZhbHNlICYmIGFyZ3MuY2FuY2VsYWJsZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaW52YWxpZGF0ZSgpIHtcbiAgICAgICAgaWYgKCFpc051bGxPclVuZGVmKHRoaXMuX2NhY2hlKSkge1xuICAgICAgICAgICAgdGhpcy5fb2xkQ2FjaGUgPSB0aGlzLl9jYWNoZTtcbiAgICAgICAgICAgIHRoaXMuX2NhY2hlID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuIF9kZXNjcmlwdG9ycyhjaGFydCkge1xuICAgICAgICBpZiAodGhpcy5fY2FjaGUpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jYWNoZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkZXNjcmlwdG9ycyA9IHRoaXMuX2NhY2hlID0gdGhpcy5fY3JlYXRlRGVzY3JpcHRvcnMoY2hhcnQpO1xuICAgICAgICB0aGlzLl9ub3RpZnlTdGF0ZUNoYW5nZXMoY2hhcnQpO1xuICAgICAgICByZXR1cm4gZGVzY3JpcHRvcnM7XG4gICAgfVxuICAgIF9jcmVhdGVEZXNjcmlwdG9ycyhjaGFydCwgYWxsKSB7XG4gICAgICAgIGNvbnN0IGNvbmZpZyA9IGNoYXJ0ICYmIGNoYXJ0LmNvbmZpZztcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHZhbHVlT3JEZWZhdWx0KGNvbmZpZy5vcHRpb25zICYmIGNvbmZpZy5vcHRpb25zLnBsdWdpbnMsIHt9KTtcbiAgICAgICAgY29uc3QgcGx1Z2lucyA9IGFsbFBsdWdpbnMoY29uZmlnKTtcbiAgICAgICAgcmV0dXJuIG9wdGlvbnMgPT09IGZhbHNlICYmICFhbGwgPyBbXSA6IGNyZWF0ZURlc2NyaXB0b3JzKGNoYXJ0LCBwbHVnaW5zLCBvcHRpb25zLCBhbGwpO1xuICAgIH1cbiBfbm90aWZ5U3RhdGVDaGFuZ2VzKGNoYXJ0KSB7XG4gICAgICAgIGNvbnN0IHByZXZpb3VzRGVzY3JpcHRvcnMgPSB0aGlzLl9vbGRDYWNoZSB8fCBbXTtcbiAgICAgICAgY29uc3QgZGVzY3JpcHRvcnMgPSB0aGlzLl9jYWNoZTtcbiAgICAgICAgY29uc3QgZGlmZiA9IChhLCBiKT0+YS5maWx0ZXIoKHgpPT4hYi5zb21lKCh5KT0+eC5wbHVnaW4uaWQgPT09IHkucGx1Z2luLmlkKSk7XG4gICAgICAgIHRoaXMuX25vdGlmeShkaWZmKHByZXZpb3VzRGVzY3JpcHRvcnMsIGRlc2NyaXB0b3JzKSwgY2hhcnQsICdzdG9wJyk7XG4gICAgICAgIHRoaXMuX25vdGlmeShkaWZmKGRlc2NyaXB0b3JzLCBwcmV2aW91c0Rlc2NyaXB0b3JzKSwgY2hhcnQsICdzdGFydCcpO1xuICAgIH1cbn1cbiBmdW5jdGlvbiBhbGxQbHVnaW5zKGNvbmZpZykge1xuICAgIGNvbnN0IGxvY2FsSWRzID0ge307XG4gICAgY29uc3QgcGx1Z2lucyA9IFtdO1xuICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhyZWdpc3RyeS5wbHVnaW5zLml0ZW1zKTtcbiAgICBmb3IobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKyl7XG4gICAgICAgIHBsdWdpbnMucHVzaChyZWdpc3RyeS5nZXRQbHVnaW4oa2V5c1tpXSkpO1xuICAgIH1cbiAgICBjb25zdCBsb2NhbCA9IGNvbmZpZy5wbHVnaW5zIHx8IFtdO1xuICAgIGZvcihsZXQgaSA9IDA7IGkgPCBsb2NhbC5sZW5ndGg7IGkrKyl7XG4gICAgICAgIGNvbnN0IHBsdWdpbiA9IGxvY2FsW2ldO1xuICAgICAgICBpZiAocGx1Z2lucy5pbmRleE9mKHBsdWdpbikgPT09IC0xKSB7XG4gICAgICAgICAgICBwbHVnaW5zLnB1c2gocGx1Z2luKTtcbiAgICAgICAgICAgIGxvY2FsSWRzW3BsdWdpbi5pZF0gPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHBsdWdpbnMsXG4gICAgICAgIGxvY2FsSWRzXG4gICAgfTtcbn1cbmZ1bmN0aW9uIGdldE9wdHMob3B0aW9ucywgYWxsKSB7XG4gICAgaWYgKCFhbGwgJiYgb3B0aW9ucyA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGlmIChvcHRpb25zID09PSB0cnVlKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgcmV0dXJuIG9wdGlvbnM7XG59XG5mdW5jdGlvbiBjcmVhdGVEZXNjcmlwdG9ycyhjaGFydCwgeyBwbHVnaW5zICwgbG9jYWxJZHMgIH0sIG9wdGlvbnMsIGFsbCkge1xuICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuICAgIGNvbnN0IGNvbnRleHQgPSBjaGFydC5nZXRDb250ZXh0KCk7XG4gICAgZm9yIChjb25zdCBwbHVnaW4gb2YgcGx1Z2lucyl7XG4gICAgICAgIGNvbnN0IGlkID0gcGx1Z2luLmlkO1xuICAgICAgICBjb25zdCBvcHRzID0gZ2V0T3B0cyhvcHRpb25zW2lkXSwgYWxsKTtcbiAgICAgICAgaWYgKG9wdHMgPT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHJlc3VsdC5wdXNoKHtcbiAgICAgICAgICAgIHBsdWdpbixcbiAgICAgICAgICAgIG9wdGlvbnM6IHBsdWdpbk9wdHMoY2hhcnQuY29uZmlnLCB7XG4gICAgICAgICAgICAgICAgcGx1Z2luLFxuICAgICAgICAgICAgICAgIGxvY2FsOiBsb2NhbElkc1tpZF1cbiAgICAgICAgICAgIH0sIG9wdHMsIGNvbnRleHQpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuZnVuY3Rpb24gcGx1Z2luT3B0cyhjb25maWcsIHsgcGx1Z2luICwgbG9jYWwgIH0sIG9wdHMsIGNvbnRleHQpIHtcbiAgICBjb25zdCBrZXlzID0gY29uZmlnLnBsdWdpblNjb3BlS2V5cyhwbHVnaW4pO1xuICAgIGNvbnN0IHNjb3BlcyA9IGNvbmZpZy5nZXRPcHRpb25TY29wZXMob3B0cywga2V5cyk7XG4gICAgaWYgKGxvY2FsICYmIHBsdWdpbi5kZWZhdWx0cykge1xuICAgICAgICBzY29wZXMucHVzaChwbHVnaW4uZGVmYXVsdHMpO1xuICAgIH1cbiAgICByZXR1cm4gY29uZmlnLmNyZWF0ZVJlc29sdmVyKHNjb3BlcywgY29udGV4dCwgW1xuICAgICAgICAnJ1xuICAgIF0sIHtcbiAgICAgICAgc2NyaXB0YWJsZTogZmFsc2UsXG4gICAgICAgIGluZGV4YWJsZTogZmFsc2UsXG4gICAgICAgIGFsbEtleXM6IHRydWVcbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0SW5kZXhBeGlzKHR5cGUsIG9wdGlvbnMpIHtcbiAgICBjb25zdCBkYXRhc2V0RGVmYXVsdHMgPSBkZWZhdWx0cy5kYXRhc2V0c1t0eXBlXSB8fCB7fTtcbiAgICBjb25zdCBkYXRhc2V0T3B0aW9ucyA9IChvcHRpb25zLmRhdGFzZXRzIHx8IHt9KVt0eXBlXSB8fCB7fTtcbiAgICByZXR1cm4gZGF0YXNldE9wdGlvbnMuaW5kZXhBeGlzIHx8IG9wdGlvbnMuaW5kZXhBeGlzIHx8IGRhdGFzZXREZWZhdWx0cy5pbmRleEF4aXMgfHwgJ3gnO1xufVxuZnVuY3Rpb24gZ2V0QXhpc0Zyb21EZWZhdWx0U2NhbGVJRChpZCwgaW5kZXhBeGlzKSB7XG4gICAgbGV0IGF4aXMgPSBpZDtcbiAgICBpZiAoaWQgPT09ICdfaW5kZXhfJykge1xuICAgICAgICBheGlzID0gaW5kZXhBeGlzO1xuICAgIH0gZWxzZSBpZiAoaWQgPT09ICdfdmFsdWVfJykge1xuICAgICAgICBheGlzID0gaW5kZXhBeGlzID09PSAneCcgPyAneScgOiAneCc7XG4gICAgfVxuICAgIHJldHVybiBheGlzO1xufVxuZnVuY3Rpb24gZ2V0RGVmYXVsdFNjYWxlSURGcm9tQXhpcyhheGlzLCBpbmRleEF4aXMpIHtcbiAgICByZXR1cm4gYXhpcyA9PT0gaW5kZXhBeGlzID8gJ19pbmRleF8nIDogJ192YWx1ZV8nO1xufVxuZnVuY3Rpb24gaWRNYXRjaGVzQXhpcyhpZCkge1xuICAgIGlmIChpZCA9PT0gJ3gnIHx8IGlkID09PSAneScgfHwgaWQgPT09ICdyJykge1xuICAgICAgICByZXR1cm4gaWQ7XG4gICAgfVxufVxuZnVuY3Rpb24gYXhpc0Zyb21Qb3NpdGlvbihwb3NpdGlvbikge1xuICAgIGlmIChwb3NpdGlvbiA9PT0gJ3RvcCcgfHwgcG9zaXRpb24gPT09ICdib3R0b20nKSB7XG4gICAgICAgIHJldHVybiAneCc7XG4gICAgfVxuICAgIGlmIChwb3NpdGlvbiA9PT0gJ2xlZnQnIHx8IHBvc2l0aW9uID09PSAncmlnaHQnKSB7XG4gICAgICAgIHJldHVybiAneSc7XG4gICAgfVxufVxuZnVuY3Rpb24gZGV0ZXJtaW5lQXhpcyhpZCwgLi4uc2NhbGVPcHRpb25zKSB7XG4gICAgaWYgKGlkTWF0Y2hlc0F4aXMoaWQpKSB7XG4gICAgICAgIHJldHVybiBpZDtcbiAgICB9XG4gICAgZm9yIChjb25zdCBvcHRzIG9mIHNjYWxlT3B0aW9ucyl7XG4gICAgICAgIGNvbnN0IGF4aXMgPSBvcHRzLmF4aXMgfHwgYXhpc0Zyb21Qb3NpdGlvbihvcHRzLnBvc2l0aW9uKSB8fCBpZC5sZW5ndGggPiAxICYmIGlkTWF0Y2hlc0F4aXMoaWRbMF0udG9Mb3dlckNhc2UoKSk7XG4gICAgICAgIGlmIChheGlzKSB7XG4gICAgICAgICAgICByZXR1cm4gYXhpcztcbiAgICAgICAgfVxuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBkZXRlcm1pbmUgdHlwZSBvZiAnJHtpZH0nIGF4aXMuIFBsZWFzZSBwcm92aWRlICdheGlzJyBvciAncG9zaXRpb24nIG9wdGlvbi5gKTtcbn1cbmZ1bmN0aW9uIGdldEF4aXNGcm9tRGF0YXNldChpZCwgYXhpcywgZGF0YXNldCkge1xuICAgIGlmIChkYXRhc2V0W2F4aXMgKyAnQXhpc0lEJ10gPT09IGlkKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBheGlzXG4gICAgICAgIH07XG4gICAgfVxufVxuZnVuY3Rpb24gcmV0cmlldmVBeGlzRnJvbURhdGFzZXRzKGlkLCBjb25maWcpIHtcbiAgICBpZiAoY29uZmlnLmRhdGEgJiYgY29uZmlnLmRhdGEuZGF0YXNldHMpIHtcbiAgICAgICAgY29uc3QgYm91bmREcyA9IGNvbmZpZy5kYXRhLmRhdGFzZXRzLmZpbHRlcigoZCk9PmQueEF4aXNJRCA9PT0gaWQgfHwgZC55QXhpc0lEID09PSBpZCk7XG4gICAgICAgIGlmIChib3VuZERzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGdldEF4aXNGcm9tRGF0YXNldChpZCwgJ3gnLCBib3VuZERzWzBdKSB8fCBnZXRBeGlzRnJvbURhdGFzZXQoaWQsICd5JywgYm91bmREc1swXSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHt9O1xufVxuZnVuY3Rpb24gbWVyZ2VTY2FsZUNvbmZpZyhjb25maWcsIG9wdGlvbnMpIHtcbiAgICBjb25zdCBjaGFydERlZmF1bHRzID0gb3ZlcnJpZGVzW2NvbmZpZy50eXBlXSB8fCB7XG4gICAgICAgIHNjYWxlczoge31cbiAgICB9O1xuICAgIGNvbnN0IGNvbmZpZ1NjYWxlcyA9IG9wdGlvbnMuc2NhbGVzIHx8IHt9O1xuICAgIGNvbnN0IGNoYXJ0SW5kZXhBeGlzID0gZ2V0SW5kZXhBeGlzKGNvbmZpZy50eXBlLCBvcHRpb25zKTtcbiAgICBjb25zdCBzY2FsZXMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIE9iamVjdC5rZXlzKGNvbmZpZ1NjYWxlcykuZm9yRWFjaCgoaWQpPT57XG4gICAgICAgIGNvbnN0IHNjYWxlQ29uZiA9IGNvbmZpZ1NjYWxlc1tpZF07XG4gICAgICAgIGlmICghaXNPYmplY3Qoc2NhbGVDb25mKSkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnNvbGUuZXJyb3IoYEludmFsaWQgc2NhbGUgY29uZmlndXJhdGlvbiBmb3Igc2NhbGU6ICR7aWR9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNjYWxlQ29uZi5fcHJveHkpIHtcbiAgICAgICAgICAgIHJldHVybiBjb25zb2xlLndhcm4oYElnbm9yaW5nIHJlc29sdmVyIHBhc3NlZCBhcyBvcHRpb25zIGZvciBzY2FsZTogJHtpZH1gKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBheGlzID0gZGV0ZXJtaW5lQXhpcyhpZCwgc2NhbGVDb25mLCByZXRyaWV2ZUF4aXNGcm9tRGF0YXNldHMoaWQsIGNvbmZpZyksIGRlZmF1bHRzLnNjYWxlc1tzY2FsZUNvbmYudHlwZV0pO1xuICAgICAgICBjb25zdCBkZWZhdWx0SWQgPSBnZXREZWZhdWx0U2NhbGVJREZyb21BeGlzKGF4aXMsIGNoYXJ0SW5kZXhBeGlzKTtcbiAgICAgICAgY29uc3QgZGVmYXVsdFNjYWxlT3B0aW9ucyA9IGNoYXJ0RGVmYXVsdHMuc2NhbGVzIHx8IHt9O1xuICAgICAgICBzY2FsZXNbaWRdID0gbWVyZ2VJZihPYmplY3QuY3JlYXRlKG51bGwpLCBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYXhpc1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNjYWxlQ29uZixcbiAgICAgICAgICAgIGRlZmF1bHRTY2FsZU9wdGlvbnNbYXhpc10sXG4gICAgICAgICAgICBkZWZhdWx0U2NhbGVPcHRpb25zW2RlZmF1bHRJZF1cbiAgICAgICAgXSk7XG4gICAgfSk7XG4gICAgY29uZmlnLmRhdGEuZGF0YXNldHMuZm9yRWFjaCgoZGF0YXNldCk9PntcbiAgICAgICAgY29uc3QgdHlwZSA9IGRhdGFzZXQudHlwZSB8fCBjb25maWcudHlwZTtcbiAgICAgICAgY29uc3QgaW5kZXhBeGlzID0gZGF0YXNldC5pbmRleEF4aXMgfHwgZ2V0SW5kZXhBeGlzKHR5cGUsIG9wdGlvbnMpO1xuICAgICAgICBjb25zdCBkYXRhc2V0RGVmYXVsdHMgPSBvdmVycmlkZXNbdHlwZV0gfHwge307XG4gICAgICAgIGNvbnN0IGRlZmF1bHRTY2FsZU9wdGlvbnMgPSBkYXRhc2V0RGVmYXVsdHMuc2NhbGVzIHx8IHt9O1xuICAgICAgICBPYmplY3Qua2V5cyhkZWZhdWx0U2NhbGVPcHRpb25zKS5mb3JFYWNoKChkZWZhdWx0SUQpPT57XG4gICAgICAgICAgICBjb25zdCBheGlzID0gZ2V0QXhpc0Zyb21EZWZhdWx0U2NhbGVJRChkZWZhdWx0SUQsIGluZGV4QXhpcyk7XG4gICAgICAgICAgICBjb25zdCBpZCA9IGRhdGFzZXRbYXhpcyArICdBeGlzSUQnXSB8fCBheGlzO1xuICAgICAgICAgICAgc2NhbGVzW2lkXSA9IHNjYWxlc1tpZF0gfHwgT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgICAgIG1lcmdlSWYoc2NhbGVzW2lkXSwgW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgYXhpc1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgY29uZmlnU2NhbGVzW2lkXSxcbiAgICAgICAgICAgICAgICBkZWZhdWx0U2NhbGVPcHRpb25zW2RlZmF1bHRJRF1cbiAgICAgICAgICAgIF0pO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgICBPYmplY3Qua2V5cyhzY2FsZXMpLmZvckVhY2goKGtleSk9PntcbiAgICAgICAgY29uc3Qgc2NhbGUgPSBzY2FsZXNba2V5XTtcbiAgICAgICAgbWVyZ2VJZihzY2FsZSwgW1xuICAgICAgICAgICAgZGVmYXVsdHMuc2NhbGVzW3NjYWxlLnR5cGVdLFxuICAgICAgICAgICAgZGVmYXVsdHMuc2NhbGVcbiAgICAgICAgXSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHNjYWxlcztcbn1cbmZ1bmN0aW9uIGluaXRPcHRpb25zKGNvbmZpZykge1xuICAgIGNvbnN0IG9wdGlvbnMgPSBjb25maWcub3B0aW9ucyB8fCAoY29uZmlnLm9wdGlvbnMgPSB7fSk7XG4gICAgb3B0aW9ucy5wbHVnaW5zID0gdmFsdWVPckRlZmF1bHQob3B0aW9ucy5wbHVnaW5zLCB7fSk7XG4gICAgb3B0aW9ucy5zY2FsZXMgPSBtZXJnZVNjYWxlQ29uZmlnKGNvbmZpZywgb3B0aW9ucyk7XG59XG5mdW5jdGlvbiBpbml0RGF0YShkYXRhKSB7XG4gICAgZGF0YSA9IGRhdGEgfHwge307XG4gICAgZGF0YS5kYXRhc2V0cyA9IGRhdGEuZGF0YXNldHMgfHwgW107XG4gICAgZGF0YS5sYWJlbHMgPSBkYXRhLmxhYmVscyB8fCBbXTtcbiAgICByZXR1cm4gZGF0YTtcbn1cbmZ1bmN0aW9uIGluaXRDb25maWcoY29uZmlnKSB7XG4gICAgY29uZmlnID0gY29uZmlnIHx8IHt9O1xuICAgIGNvbmZpZy5kYXRhID0gaW5pdERhdGEoY29uZmlnLmRhdGEpO1xuICAgIGluaXRPcHRpb25zKGNvbmZpZyk7XG4gICAgcmV0dXJuIGNvbmZpZztcbn1cbmNvbnN0IGtleUNhY2hlID0gbmV3IE1hcCgpO1xuY29uc3Qga2V5c0NhY2hlZCA9IG5ldyBTZXQoKTtcbmZ1bmN0aW9uIGNhY2hlZEtleXMoY2FjaGVLZXksIGdlbmVyYXRlKSB7XG4gICAgbGV0IGtleXMgPSBrZXlDYWNoZS5nZXQoY2FjaGVLZXkpO1xuICAgIGlmICgha2V5cykge1xuICAgICAgICBrZXlzID0gZ2VuZXJhdGUoKTtcbiAgICAgICAga2V5Q2FjaGUuc2V0KGNhY2hlS2V5LCBrZXlzKTtcbiAgICAgICAga2V5c0NhY2hlZC5hZGQoa2V5cyk7XG4gICAgfVxuICAgIHJldHVybiBrZXlzO1xufVxuY29uc3QgYWRkSWZGb3VuZCA9IChzZXQsIG9iaiwga2V5KT0+e1xuICAgIGNvbnN0IG9wdHMgPSByZXNvbHZlT2JqZWN0S2V5KG9iaiwga2V5KTtcbiAgICBpZiAob3B0cyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHNldC5hZGQob3B0cyk7XG4gICAgfVxufTtcbmNsYXNzIENvbmZpZyB7XG4gICAgY29uc3RydWN0b3IoY29uZmlnKXtcbiAgICAgICAgdGhpcy5fY29uZmlnID0gaW5pdENvbmZpZyhjb25maWcpO1xuICAgICAgICB0aGlzLl9zY29wZUNhY2hlID0gbmV3IE1hcCgpO1xuICAgICAgICB0aGlzLl9yZXNvbHZlckNhY2hlID0gbmV3IE1hcCgpO1xuICAgIH1cbiAgICBnZXQgcGxhdGZvcm0oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb25maWcucGxhdGZvcm07XG4gICAgfVxuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29uZmlnLnR5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fY29uZmlnLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICBnZXQgZGF0YSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbmZpZy5kYXRhO1xuICAgIH1cbiAgICBzZXQgZGF0YShkYXRhKSB7XG4gICAgICAgIHRoaXMuX2NvbmZpZy5kYXRhID0gaW5pdERhdGEoZGF0YSk7XG4gICAgfVxuICAgIGdldCBvcHRpb25zKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29uZmlnLm9wdGlvbnM7XG4gICAgfVxuICAgIHNldCBvcHRpb25zKG9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy5fY29uZmlnLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgIH1cbiAgICBnZXQgcGx1Z2lucygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbmZpZy5wbHVnaW5zO1xuICAgIH1cbiAgICB1cGRhdGUoKSB7XG4gICAgICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuX2NvbmZpZztcbiAgICAgICAgdGhpcy5jbGVhckNhY2hlKCk7XG4gICAgICAgIGluaXRPcHRpb25zKGNvbmZpZyk7XG4gICAgfVxuICAgIGNsZWFyQ2FjaGUoKSB7XG4gICAgICAgIHRoaXMuX3Njb3BlQ2FjaGUuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5fcmVzb2x2ZXJDYWNoZS5jbGVhcigpO1xuICAgIH1cbiBkYXRhc2V0U2NvcGVLZXlzKGRhdGFzZXRUeXBlKSB7XG4gICAgICAgIHJldHVybiBjYWNoZWRLZXlzKGRhdGFzZXRUeXBlLCAoKT0+W1xuICAgICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICAgICAgYGRhdGFzZXRzLiR7ZGF0YXNldFR5cGV9YCxcbiAgICAgICAgICAgICAgICAgICAgJydcbiAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICBdKTtcbiAgICB9XG4gZGF0YXNldEFuaW1hdGlvblNjb3BlS2V5cyhkYXRhc2V0VHlwZSwgdHJhbnNpdGlvbikge1xuICAgICAgICByZXR1cm4gY2FjaGVkS2V5cyhgJHtkYXRhc2V0VHlwZX0udHJhbnNpdGlvbi4ke3RyYW5zaXRpb259YCwgKCk9PltcbiAgICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgICAgIGBkYXRhc2V0cy4ke2RhdGFzZXRUeXBlfS50cmFuc2l0aW9ucy4ke3RyYW5zaXRpb259YCxcbiAgICAgICAgICAgICAgICAgICAgYHRyYW5zaXRpb25zLiR7dHJhbnNpdGlvbn1gXG4gICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgICAgIGBkYXRhc2V0cy4ke2RhdGFzZXRUeXBlfWAsXG4gICAgICAgICAgICAgICAgICAgICcnXG4gICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgXSk7XG4gICAgfVxuIGRhdGFzZXRFbGVtZW50U2NvcGVLZXlzKGRhdGFzZXRUeXBlLCBlbGVtZW50VHlwZSkge1xuICAgICAgICByZXR1cm4gY2FjaGVkS2V5cyhgJHtkYXRhc2V0VHlwZX0tJHtlbGVtZW50VHlwZX1gLCAoKT0+W1xuICAgICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICAgICAgYGRhdGFzZXRzLiR7ZGF0YXNldFR5cGV9LmVsZW1lbnRzLiR7ZWxlbWVudFR5cGV9YCxcbiAgICAgICAgICAgICAgICAgICAgYGRhdGFzZXRzLiR7ZGF0YXNldFR5cGV9YCxcbiAgICAgICAgICAgICAgICAgICAgYGVsZW1lbnRzLiR7ZWxlbWVudFR5cGV9YCxcbiAgICAgICAgICAgICAgICAgICAgJydcbiAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICBdKTtcbiAgICB9XG4gcGx1Z2luU2NvcGVLZXlzKHBsdWdpbikge1xuICAgICAgICBjb25zdCBpZCA9IHBsdWdpbi5pZDtcbiAgICAgICAgY29uc3QgdHlwZSA9IHRoaXMudHlwZTtcbiAgICAgICAgcmV0dXJuIGNhY2hlZEtleXMoYCR7dHlwZX0tcGx1Z2luLSR7aWR9YCwgKCk9PltcbiAgICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgICAgIGBwbHVnaW5zLiR7aWR9YCxcbiAgICAgICAgICAgICAgICAgICAgLi4ucGx1Z2luLmFkZGl0aW9uYWxPcHRpb25TY29wZXMgfHwgW11cbiAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICBdKTtcbiAgICB9XG4gX2NhY2hlZFNjb3BlcyhtYWluU2NvcGUsIHJlc2V0Q2FjaGUpIHtcbiAgICAgICAgY29uc3QgX3Njb3BlQ2FjaGUgPSB0aGlzLl9zY29wZUNhY2hlO1xuICAgICAgICBsZXQgY2FjaGUgPSBfc2NvcGVDYWNoZS5nZXQobWFpblNjb3BlKTtcbiAgICAgICAgaWYgKCFjYWNoZSB8fCByZXNldENhY2hlKSB7XG4gICAgICAgICAgICBjYWNoZSA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIF9zY29wZUNhY2hlLnNldChtYWluU2NvcGUsIGNhY2hlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FjaGU7XG4gICAgfVxuIGdldE9wdGlvblNjb3BlcyhtYWluU2NvcGUsIGtleUxpc3RzLCByZXNldENhY2hlKSB7XG4gICAgICAgIGNvbnN0IHsgb3B0aW9ucyAsIHR5cGUgIH0gPSB0aGlzO1xuICAgICAgICBjb25zdCBjYWNoZSA9IHRoaXMuX2NhY2hlZFNjb3BlcyhtYWluU2NvcGUsIHJlc2V0Q2FjaGUpO1xuICAgICAgICBjb25zdCBjYWNoZWQgPSBjYWNoZS5nZXQoa2V5TGlzdHMpO1xuICAgICAgICBpZiAoY2FjaGVkKSB7XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNjb3BlcyA9IG5ldyBTZXQoKTtcbiAgICAgICAga2V5TGlzdHMuZm9yRWFjaCgoa2V5cyk9PntcbiAgICAgICAgICAgIGlmIChtYWluU2NvcGUpIHtcbiAgICAgICAgICAgICAgICBzY29wZXMuYWRkKG1haW5TY29wZSk7XG4gICAgICAgICAgICAgICAga2V5cy5mb3JFYWNoKChrZXkpPT5hZGRJZkZvdW5kKHNjb3BlcywgbWFpblNjb3BlLCBrZXkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGtleXMuZm9yRWFjaCgoa2V5KT0+YWRkSWZGb3VuZChzY29wZXMsIG9wdGlvbnMsIGtleSkpO1xuICAgICAgICAgICAga2V5cy5mb3JFYWNoKChrZXkpPT5hZGRJZkZvdW5kKHNjb3Blcywgb3ZlcnJpZGVzW3R5cGVdIHx8IHt9LCBrZXkpKTtcbiAgICAgICAgICAgIGtleXMuZm9yRWFjaCgoa2V5KT0+YWRkSWZGb3VuZChzY29wZXMsIGRlZmF1bHRzLCBrZXkpKTtcbiAgICAgICAgICAgIGtleXMuZm9yRWFjaCgoa2V5KT0+YWRkSWZGb3VuZChzY29wZXMsIGRlc2NyaXB0b3JzLCBrZXkpKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGFycmF5ID0gQXJyYXkuZnJvbShzY29wZXMpO1xuICAgICAgICBpZiAoYXJyYXkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBhcnJheS5wdXNoKE9iamVjdC5jcmVhdGUobnVsbCkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChrZXlzQ2FjaGVkLmhhcyhrZXlMaXN0cykpIHtcbiAgICAgICAgICAgIGNhY2hlLnNldChrZXlMaXN0cywgYXJyYXkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhcnJheTtcbiAgICB9XG4gY2hhcnRPcHRpb25TY29wZXMoKSB7XG4gICAgICAgIGNvbnN0IHsgb3B0aW9ucyAsIHR5cGUgIH0gPSB0aGlzO1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgICAgIG92ZXJyaWRlc1t0eXBlXSB8fCB7fSxcbiAgICAgICAgICAgIGRlZmF1bHRzLmRhdGFzZXRzW3R5cGVdIHx8IHt9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR5cGVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkZWZhdWx0cyxcbiAgICAgICAgICAgIGRlc2NyaXB0b3JzXG4gICAgICAgIF07XG4gICAgfVxuIHJlc29sdmVOYW1lZE9wdGlvbnMoc2NvcGVzLCBuYW1lcywgY29udGV4dCwgcHJlZml4ZXMgPSBbXG4gICAgICAgICcnXG4gICAgXSkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSB7XG4gICAgICAgICAgICAkc2hhcmVkOiB0cnVlXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHsgcmVzb2x2ZXIgLCBzdWJQcmVmaXhlcyAgfSA9IGdldFJlc29sdmVyKHRoaXMuX3Jlc29sdmVyQ2FjaGUsIHNjb3BlcywgcHJlZml4ZXMpO1xuICAgICAgICBsZXQgb3B0aW9ucyA9IHJlc29sdmVyO1xuICAgICAgICBpZiAobmVlZENvbnRleHQocmVzb2x2ZXIsIG5hbWVzKSkge1xuICAgICAgICAgICAgcmVzdWx0LiRzaGFyZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGNvbnRleHQgPSBpc0Z1bmN0aW9uKGNvbnRleHQpID8gY29udGV4dCgpIDogY29udGV4dDtcbiAgICAgICAgICAgIGNvbnN0IHN1YlJlc29sdmVyID0gdGhpcy5jcmVhdGVSZXNvbHZlcihzY29wZXMsIGNvbnRleHQsIHN1YlByZWZpeGVzKTtcbiAgICAgICAgICAgIG9wdGlvbnMgPSBfYXR0YWNoQ29udGV4dChyZXNvbHZlciwgY29udGV4dCwgc3ViUmVzb2x2ZXIpO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgcHJvcCBvZiBuYW1lcyl7XG4gICAgICAgICAgICByZXN1bHRbcHJvcF0gPSBvcHRpb25zW3Byb3BdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuIGNyZWF0ZVJlc29sdmVyKHNjb3BlcywgY29udGV4dCwgcHJlZml4ZXMgPSBbXG4gICAgICAgICcnXG4gICAgXSwgZGVzY3JpcHRvckRlZmF1bHRzKSB7XG4gICAgICAgIGNvbnN0IHsgcmVzb2x2ZXIgIH0gPSBnZXRSZXNvbHZlcih0aGlzLl9yZXNvbHZlckNhY2hlLCBzY29wZXMsIHByZWZpeGVzKTtcbiAgICAgICAgcmV0dXJuIGlzT2JqZWN0KGNvbnRleHQpID8gX2F0dGFjaENvbnRleHQocmVzb2x2ZXIsIGNvbnRleHQsIHVuZGVmaW5lZCwgZGVzY3JpcHRvckRlZmF1bHRzKSA6IHJlc29sdmVyO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGdldFJlc29sdmVyKHJlc29sdmVyQ2FjaGUsIHNjb3BlcywgcHJlZml4ZXMpIHtcbiAgICBsZXQgY2FjaGUgPSByZXNvbHZlckNhY2hlLmdldChzY29wZXMpO1xuICAgIGlmICghY2FjaGUpIHtcbiAgICAgICAgY2FjaGUgPSBuZXcgTWFwKCk7XG4gICAgICAgIHJlc29sdmVyQ2FjaGUuc2V0KHNjb3BlcywgY2FjaGUpO1xuICAgIH1cbiAgICBjb25zdCBjYWNoZUtleSA9IHByZWZpeGVzLmpvaW4oKTtcbiAgICBsZXQgY2FjaGVkID0gY2FjaGUuZ2V0KGNhY2hlS2V5KTtcbiAgICBpZiAoIWNhY2hlZCkge1xuICAgICAgICBjb25zdCByZXNvbHZlciA9IF9jcmVhdGVSZXNvbHZlcihzY29wZXMsIHByZWZpeGVzKTtcbiAgICAgICAgY2FjaGVkID0ge1xuICAgICAgICAgICAgcmVzb2x2ZXIsXG4gICAgICAgICAgICBzdWJQcmVmaXhlczogcHJlZml4ZXMuZmlsdGVyKChwKT0+IXAudG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnaG92ZXInKSlcbiAgICAgICAgfTtcbiAgICAgICAgY2FjaGUuc2V0KGNhY2hlS2V5LCBjYWNoZWQpO1xuICAgIH1cbiAgICByZXR1cm4gY2FjaGVkO1xufVxuY29uc3QgaGFzRnVuY3Rpb24gPSAodmFsdWUpPT5pc09iamVjdCh2YWx1ZSkgJiYgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModmFsdWUpLnNvbWUoKGtleSk9PmlzRnVuY3Rpb24odmFsdWVba2V5XSkpO1xuZnVuY3Rpb24gbmVlZENvbnRleHQocHJveHksIG5hbWVzKSB7XG4gICAgY29uc3QgeyBpc1NjcmlwdGFibGUgLCBpc0luZGV4YWJsZSAgfSA9IF9kZXNjcmlwdG9ycyhwcm94eSk7XG4gICAgZm9yIChjb25zdCBwcm9wIG9mIG5hbWVzKXtcbiAgICAgICAgY29uc3Qgc2NyaXB0YWJsZSA9IGlzU2NyaXB0YWJsZShwcm9wKTtcbiAgICAgICAgY29uc3QgaW5kZXhhYmxlID0gaXNJbmRleGFibGUocHJvcCk7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gKGluZGV4YWJsZSB8fCBzY3JpcHRhYmxlKSAmJiBwcm94eVtwcm9wXTtcbiAgICAgICAgaWYgKHNjcmlwdGFibGUgJiYgKGlzRnVuY3Rpb24odmFsdWUpIHx8IGhhc0Z1bmN0aW9uKHZhbHVlKSkgfHwgaW5kZXhhYmxlICYmIGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbnZhciB2ZXJzaW9uID0gXCI0LjQuNFwiO1xuXG5jb25zdCBLTk9XTl9QT1NJVElPTlMgPSBbXG4gICAgJ3RvcCcsXG4gICAgJ2JvdHRvbScsXG4gICAgJ2xlZnQnLFxuICAgICdyaWdodCcsXG4gICAgJ2NoYXJ0QXJlYSdcbl07XG5mdW5jdGlvbiBwb3NpdGlvbklzSG9yaXpvbnRhbChwb3NpdGlvbiwgYXhpcykge1xuICAgIHJldHVybiBwb3NpdGlvbiA9PT0gJ3RvcCcgfHwgcG9zaXRpb24gPT09ICdib3R0b20nIHx8IEtOT1dOX1BPU0lUSU9OUy5pbmRleE9mKHBvc2l0aW9uKSA9PT0gLTEgJiYgYXhpcyA9PT0gJ3gnO1xufVxuZnVuY3Rpb24gY29tcGFyZTJMZXZlbChsMSwgbDIpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oYSwgYikge1xuICAgICAgICByZXR1cm4gYVtsMV0gPT09IGJbbDFdID8gYVtsMl0gLSBiW2wyXSA6IGFbbDFdIC0gYltsMV07XG4gICAgfTtcbn1cbmZ1bmN0aW9uIG9uQW5pbWF0aW9uc0NvbXBsZXRlKGNvbnRleHQpIHtcbiAgICBjb25zdCBjaGFydCA9IGNvbnRleHQuY2hhcnQ7XG4gICAgY29uc3QgYW5pbWF0aW9uT3B0aW9ucyA9IGNoYXJ0Lm9wdGlvbnMuYW5pbWF0aW9uO1xuICAgIGNoYXJ0Lm5vdGlmeVBsdWdpbnMoJ2FmdGVyUmVuZGVyJyk7XG4gICAgY2FsbGJhY2soYW5pbWF0aW9uT3B0aW9ucyAmJiBhbmltYXRpb25PcHRpb25zLm9uQ29tcGxldGUsIFtcbiAgICAgICAgY29udGV4dFxuICAgIF0sIGNoYXJ0KTtcbn1cbmZ1bmN0aW9uIG9uQW5pbWF0aW9uUHJvZ3Jlc3MoY29udGV4dCkge1xuICAgIGNvbnN0IGNoYXJ0ID0gY29udGV4dC5jaGFydDtcbiAgICBjb25zdCBhbmltYXRpb25PcHRpb25zID0gY2hhcnQub3B0aW9ucy5hbmltYXRpb247XG4gICAgY2FsbGJhY2soYW5pbWF0aW9uT3B0aW9ucyAmJiBhbmltYXRpb25PcHRpb25zLm9uUHJvZ3Jlc3MsIFtcbiAgICAgICAgY29udGV4dFxuICAgIF0sIGNoYXJ0KTtcbn1cbiBmdW5jdGlvbiBnZXRDYW52YXMoaXRlbSkge1xuICAgIGlmIChfaXNEb21TdXBwb3J0ZWQoKSAmJiB0eXBlb2YgaXRlbSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgaXRlbSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGl0ZW0pO1xuICAgIH0gZWxzZSBpZiAoaXRlbSAmJiBpdGVtLmxlbmd0aCkge1xuICAgICAgICBpdGVtID0gaXRlbVswXTtcbiAgICB9XG4gICAgaWYgKGl0ZW0gJiYgaXRlbS5jYW52YXMpIHtcbiAgICAgICAgaXRlbSA9IGl0ZW0uY2FudmFzO1xuICAgIH1cbiAgICByZXR1cm4gaXRlbTtcbn1cbmNvbnN0IGluc3RhbmNlcyA9IHt9O1xuY29uc3QgZ2V0Q2hhcnQgPSAoa2V5KT0+e1xuICAgIGNvbnN0IGNhbnZhcyA9IGdldENhbnZhcyhrZXkpO1xuICAgIHJldHVybiBPYmplY3QudmFsdWVzKGluc3RhbmNlcykuZmlsdGVyKChjKT0+Yy5jYW52YXMgPT09IGNhbnZhcykucG9wKCk7XG59O1xuZnVuY3Rpb24gbW92ZU51bWVyaWNLZXlzKG9iaiwgc3RhcnQsIG1vdmUpIHtcbiAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMob2JqKTtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKXtcbiAgICAgICAgY29uc3QgaW50S2V5ID0gK2tleTtcbiAgICAgICAgaWYgKGludEtleSA+PSBzdGFydCkge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBvYmpba2V5XTtcbiAgICAgICAgICAgIGRlbGV0ZSBvYmpba2V5XTtcbiAgICAgICAgICAgIGlmIChtb3ZlID4gMCB8fCBpbnRLZXkgPiBzdGFydCkge1xuICAgICAgICAgICAgICAgIG9ialtpbnRLZXkgKyBtb3ZlXSA9IHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuIGZ1bmN0aW9uIGRldGVybWluZUxhc3RFdmVudChlLCBsYXN0RXZlbnQsIGluQ2hhcnRBcmVhLCBpc0NsaWNrKSB7XG4gICAgaWYgKCFpbkNoYXJ0QXJlYSB8fCBlLnR5cGUgPT09ICdtb3VzZW91dCcpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGlmIChpc0NsaWNrKSB7XG4gICAgICAgIHJldHVybiBsYXN0RXZlbnQ7XG4gICAgfVxuICAgIHJldHVybiBlO1xufVxuZnVuY3Rpb24gZ2V0U2l6ZUZvckFyZWEoc2NhbGUsIGNoYXJ0QXJlYSwgZmllbGQpIHtcbiAgICByZXR1cm4gc2NhbGUub3B0aW9ucy5jbGlwID8gc2NhbGVbZmllbGRdIDogY2hhcnRBcmVhW2ZpZWxkXTtcbn1cbmZ1bmN0aW9uIGdldERhdGFzZXRBcmVhKG1ldGEsIGNoYXJ0QXJlYSkge1xuICAgIGNvbnN0IHsgeFNjYWxlICwgeVNjYWxlICB9ID0gbWV0YTtcbiAgICBpZiAoeFNjYWxlICYmIHlTY2FsZSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbGVmdDogZ2V0U2l6ZUZvckFyZWEoeFNjYWxlLCBjaGFydEFyZWEsICdsZWZ0JyksXG4gICAgICAgICAgICByaWdodDogZ2V0U2l6ZUZvckFyZWEoeFNjYWxlLCBjaGFydEFyZWEsICdyaWdodCcpLFxuICAgICAgICAgICAgdG9wOiBnZXRTaXplRm9yQXJlYSh5U2NhbGUsIGNoYXJ0QXJlYSwgJ3RvcCcpLFxuICAgICAgICAgICAgYm90dG9tOiBnZXRTaXplRm9yQXJlYSh5U2NhbGUsIGNoYXJ0QXJlYSwgJ2JvdHRvbScpXG4gICAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiBjaGFydEFyZWE7XG59XG5jbGFzcyBDaGFydCB7XG4gICAgc3RhdGljIGRlZmF1bHRzID0gZGVmYXVsdHM7XG4gICAgc3RhdGljIGluc3RhbmNlcyA9IGluc3RhbmNlcztcbiAgICBzdGF0aWMgb3ZlcnJpZGVzID0gb3ZlcnJpZGVzO1xuICAgIHN0YXRpYyByZWdpc3RyeSA9IHJlZ2lzdHJ5O1xuICAgIHN0YXRpYyB2ZXJzaW9uID0gdmVyc2lvbjtcbiAgICBzdGF0aWMgZ2V0Q2hhcnQgPSBnZXRDaGFydDtcbiAgICBzdGF0aWMgcmVnaXN0ZXIoLi4uaXRlbXMpIHtcbiAgICAgICAgcmVnaXN0cnkuYWRkKC4uLml0ZW1zKTtcbiAgICAgICAgaW52YWxpZGF0ZVBsdWdpbnMoKTtcbiAgICB9XG4gICAgc3RhdGljIHVucmVnaXN0ZXIoLi4uaXRlbXMpIHtcbiAgICAgICAgcmVnaXN0cnkucmVtb3ZlKC4uLml0ZW1zKTtcbiAgICAgICAgaW52YWxpZGF0ZVBsdWdpbnMoKTtcbiAgICB9XG4gICAgY29uc3RydWN0b3IoaXRlbSwgdXNlckNvbmZpZyl7XG4gICAgICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuY29uZmlnID0gbmV3IENvbmZpZyh1c2VyQ29uZmlnKTtcbiAgICAgICAgY29uc3QgaW5pdGlhbENhbnZhcyA9IGdldENhbnZhcyhpdGVtKTtcbiAgICAgICAgY29uc3QgZXhpc3RpbmdDaGFydCA9IGdldENoYXJ0KGluaXRpYWxDYW52YXMpO1xuICAgICAgICBpZiAoZXhpc3RpbmdDaGFydCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW52YXMgaXMgYWxyZWFkeSBpbiB1c2UuIENoYXJ0IHdpdGggSUQgXFwnJyArIGV4aXN0aW5nQ2hhcnQuaWQgKyAnXFwnJyArICcgbXVzdCBiZSBkZXN0cm95ZWQgYmVmb3JlIHRoZSBjYW52YXMgd2l0aCBJRCBcXCcnICsgZXhpc3RpbmdDaGFydC5jYW52YXMuaWQgKyAnXFwnIGNhbiBiZSByZXVzZWQuJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IGNvbmZpZy5jcmVhdGVSZXNvbHZlcihjb25maWcuY2hhcnRPcHRpb25TY29wZXMoKSwgdGhpcy5nZXRDb250ZXh0KCkpO1xuICAgICAgICB0aGlzLnBsYXRmb3JtID0gbmV3IChjb25maWcucGxhdGZvcm0gfHwgX2RldGVjdFBsYXRmb3JtKGluaXRpYWxDYW52YXMpKSgpO1xuICAgICAgICB0aGlzLnBsYXRmb3JtLnVwZGF0ZUNvbmZpZyhjb25maWcpO1xuICAgICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5wbGF0Zm9ybS5hY3F1aXJlQ29udGV4dChpbml0aWFsQ2FudmFzLCBvcHRpb25zLmFzcGVjdFJhdGlvKTtcbiAgICAgICAgY29uc3QgY2FudmFzID0gY29udGV4dCAmJiBjb250ZXh0LmNhbnZhcztcbiAgICAgICAgY29uc3QgaGVpZ2h0ID0gY2FudmFzICYmIGNhbnZhcy5oZWlnaHQ7XG4gICAgICAgIGNvbnN0IHdpZHRoID0gY2FudmFzICYmIGNhbnZhcy53aWR0aDtcbiAgICAgICAgdGhpcy5pZCA9IHVpZCgpO1xuICAgICAgICB0aGlzLmN0eCA9IGNvbnRleHQ7XG4gICAgICAgIHRoaXMuY2FudmFzID0gY2FudmFzO1xuICAgICAgICB0aGlzLndpZHRoID0gd2lkdGg7XG4gICAgICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgICAgICB0aGlzLl9vcHRpb25zID0gb3B0aW9ucztcbiAgICAgICAgdGhpcy5fYXNwZWN0UmF0aW8gPSB0aGlzLmFzcGVjdFJhdGlvO1xuICAgICAgICB0aGlzLl9sYXllcnMgPSBbXTtcbiAgICAgICAgdGhpcy5fbWV0YXNldHMgPSBbXTtcbiAgICAgICAgdGhpcy5fc3RhY2tzID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLmJveGVzID0gW107XG4gICAgICAgIHRoaXMuY3VycmVudERldmljZVBpeGVsUmF0aW8gPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuY2hhcnRBcmVhID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl9hY3RpdmUgPSBbXTtcbiAgICAgICAgdGhpcy5fbGFzdEV2ZW50ID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl9saXN0ZW5lcnMgPSB7fTtcbiAgICAgICAgIHRoaXMuX3Jlc3BvbnNpdmVMaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuX3NvcnRlZE1ldGFzZXRzID0gW107XG4gICAgICAgIHRoaXMuc2NhbGVzID0ge307XG4gICAgICAgIHRoaXMuX3BsdWdpbnMgPSBuZXcgUGx1Z2luU2VydmljZSgpO1xuICAgICAgICB0aGlzLiRwcm94aWVzID0ge307XG4gICAgICAgIHRoaXMuX2hpZGRlbkluZGljZXMgPSB7fTtcbiAgICAgICAgdGhpcy5hdHRhY2hlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9hbmltYXRpb25zRGlzYWJsZWQgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuJGNvbnRleHQgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuX2RvUmVzaXplID0gZGVib3VuY2UoKG1vZGUpPT50aGlzLnVwZGF0ZShtb2RlKSwgb3B0aW9ucy5yZXNpemVEZWxheSB8fCAwKTtcbiAgICAgICAgdGhpcy5fZGF0YUNoYW5nZXMgPSBbXTtcbiAgICAgICAgaW5zdGFuY2VzW3RoaXMuaWRdID0gdGhpcztcbiAgICAgICAgaWYgKCFjb250ZXh0IHx8ICFjYW52YXMpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJGYWlsZWQgdG8gY3JlYXRlIGNoYXJ0OiBjYW4ndCBhY3F1aXJlIGNvbnRleHQgZnJvbSB0aGUgZ2l2ZW4gaXRlbVwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBhbmltYXRvci5saXN0ZW4odGhpcywgJ2NvbXBsZXRlJywgb25BbmltYXRpb25zQ29tcGxldGUpO1xuICAgICAgICBhbmltYXRvci5saXN0ZW4odGhpcywgJ3Byb2dyZXNzJywgb25BbmltYXRpb25Qcm9ncmVzcyk7XG4gICAgICAgIHRoaXMuX2luaXRpYWxpemUoKTtcbiAgICAgICAgaWYgKHRoaXMuYXR0YWNoZWQpIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IGFzcGVjdFJhdGlvKCkge1xuICAgICAgICBjb25zdCB7IG9wdGlvbnM6IHsgYXNwZWN0UmF0aW8gLCBtYWludGFpbkFzcGVjdFJhdGlvICB9ICwgd2lkdGggLCBoZWlnaHQgLCBfYXNwZWN0UmF0aW8gIH0gPSB0aGlzO1xuICAgICAgICBpZiAoIWlzTnVsbE9yVW5kZWYoYXNwZWN0UmF0aW8pKSB7XG4gICAgICAgICAgICByZXR1cm4gYXNwZWN0UmF0aW87XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1haW50YWluQXNwZWN0UmF0aW8gJiYgX2FzcGVjdFJhdGlvKSB7XG4gICAgICAgICAgICByZXR1cm4gX2FzcGVjdFJhdGlvO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBoZWlnaHQgPyB3aWR0aCAvIGhlaWdodCA6IG51bGw7XG4gICAgfVxuICAgIGdldCBkYXRhKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YTtcbiAgICB9XG4gICAgc2V0IGRhdGEoZGF0YSkge1xuICAgICAgICB0aGlzLmNvbmZpZy5kYXRhID0gZGF0YTtcbiAgICB9XG4gICAgZ2V0IG9wdGlvbnMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vcHRpb25zO1xuICAgIH1cbiAgICBzZXQgb3B0aW9ucyhvcHRpb25zKSB7XG4gICAgICAgIHRoaXMuY29uZmlnLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgIH1cbiAgICBnZXQgcmVnaXN0cnkoKSB7XG4gICAgICAgIHJldHVybiByZWdpc3RyeTtcbiAgICB9XG4gX2luaXRpYWxpemUoKSB7XG4gICAgICAgIHRoaXMubm90aWZ5UGx1Z2lucygnYmVmb3JlSW5pdCcpO1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnJlc3BvbnNpdmUpIHtcbiAgICAgICAgICAgIHRoaXMucmVzaXplKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXRpbmFTY2FsZSh0aGlzLCB0aGlzLm9wdGlvbnMuZGV2aWNlUGl4ZWxSYXRpbyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5iaW5kRXZlbnRzKCk7XG4gICAgICAgIHRoaXMubm90aWZ5UGx1Z2lucygnYWZ0ZXJJbml0Jyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBjbGVhcigpIHtcbiAgICAgICAgY2xlYXJDYW52YXModGhpcy5jYW52YXMsIHRoaXMuY3R4KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHN0b3AoKSB7XG4gICAgICAgIGFuaW1hdG9yLnN0b3AodGhpcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiByZXNpemUod2lkdGgsIGhlaWdodCkge1xuICAgICAgICBpZiAoIWFuaW1hdG9yLnJ1bm5pbmcodGhpcykpIHtcbiAgICAgICAgICAgIHRoaXMuX3Jlc2l6ZSh3aWR0aCwgaGVpZ2h0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3Jlc2l6ZUJlZm9yZURyYXcgPSB7XG4gICAgICAgICAgICAgICAgd2lkdGgsXG4gICAgICAgICAgICAgICAgaGVpZ2h0XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfVxuICAgIF9yZXNpemUod2lkdGgsIGhlaWdodCkge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBjb25zdCBjYW52YXMgPSB0aGlzLmNhbnZhcztcbiAgICAgICAgY29uc3QgYXNwZWN0UmF0aW8gPSBvcHRpb25zLm1haW50YWluQXNwZWN0UmF0aW8gJiYgdGhpcy5hc3BlY3RSYXRpbztcbiAgICAgICAgY29uc3QgbmV3U2l6ZSA9IHRoaXMucGxhdGZvcm0uZ2V0TWF4aW11bVNpemUoY2FudmFzLCB3aWR0aCwgaGVpZ2h0LCBhc3BlY3RSYXRpbyk7XG4gICAgICAgIGNvbnN0IG5ld1JhdGlvID0gb3B0aW9ucy5kZXZpY2VQaXhlbFJhdGlvIHx8IHRoaXMucGxhdGZvcm0uZ2V0RGV2aWNlUGl4ZWxSYXRpbygpO1xuICAgICAgICBjb25zdCBtb2RlID0gdGhpcy53aWR0aCA/ICdyZXNpemUnIDogJ2F0dGFjaCc7XG4gICAgICAgIHRoaXMud2lkdGggPSBuZXdTaXplLndpZHRoO1xuICAgICAgICB0aGlzLmhlaWdodCA9IG5ld1NpemUuaGVpZ2h0O1xuICAgICAgICB0aGlzLl9hc3BlY3RSYXRpbyA9IHRoaXMuYXNwZWN0UmF0aW87XG4gICAgICAgIGlmICghcmV0aW5hU2NhbGUodGhpcywgbmV3UmF0aW8sIHRydWUpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5ub3RpZnlQbHVnaW5zKCdyZXNpemUnLCB7XG4gICAgICAgICAgICBzaXplOiBuZXdTaXplXG4gICAgICAgIH0pO1xuICAgICAgICBjYWxsYmFjayhvcHRpb25zLm9uUmVzaXplLCBbXG4gICAgICAgICAgICB0aGlzLFxuICAgICAgICAgICAgbmV3U2l6ZVxuICAgICAgICBdLCB0aGlzKTtcbiAgICAgICAgaWYgKHRoaXMuYXR0YWNoZWQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9kb1Jlc2l6ZShtb2RlKSkge1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgZW5zdXJlU2NhbGVzSGF2ZUlEcygpIHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgY29uc3Qgc2NhbGVzT3B0aW9ucyA9IG9wdGlvbnMuc2NhbGVzIHx8IHt9O1xuICAgICAgICBlYWNoKHNjYWxlc09wdGlvbnMsIChheGlzT3B0aW9ucywgYXhpc0lEKT0+e1xuICAgICAgICAgICAgYXhpc09wdGlvbnMuaWQgPSBheGlzSUQ7XG4gICAgICAgIH0pO1xuICAgIH1cbiBidWlsZE9yVXBkYXRlU2NhbGVzKCkge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBjb25zdCBzY2FsZU9wdHMgPSBvcHRpb25zLnNjYWxlcztcbiAgICAgICAgY29uc3Qgc2NhbGVzID0gdGhpcy5zY2FsZXM7XG4gICAgICAgIGNvbnN0IHVwZGF0ZWQgPSBPYmplY3Qua2V5cyhzY2FsZXMpLnJlZHVjZSgob2JqLCBpZCk9PntcbiAgICAgICAgICAgIG9ialtpZF0gPSBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybiBvYmo7XG4gICAgICAgIH0sIHt9KTtcbiAgICAgICAgbGV0IGl0ZW1zID0gW107XG4gICAgICAgIGlmIChzY2FsZU9wdHMpIHtcbiAgICAgICAgICAgIGl0ZW1zID0gaXRlbXMuY29uY2F0KE9iamVjdC5rZXlzKHNjYWxlT3B0cykubWFwKChpZCk9PntcbiAgICAgICAgICAgICAgICBjb25zdCBzY2FsZU9wdGlvbnMgPSBzY2FsZU9wdHNbaWRdO1xuICAgICAgICAgICAgICAgIGNvbnN0IGF4aXMgPSBkZXRlcm1pbmVBeGlzKGlkLCBzY2FsZU9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGlzUmFkaWFsID0gYXhpcyA9PT0gJ3InO1xuICAgICAgICAgICAgICAgIGNvbnN0IGlzSG9yaXpvbnRhbCA9IGF4aXMgPT09ICd4JztcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zOiBzY2FsZU9wdGlvbnMsXG4gICAgICAgICAgICAgICAgICAgIGRwb3NpdGlvbjogaXNSYWRpYWwgPyAnY2hhcnRBcmVhJyA6IGlzSG9yaXpvbnRhbCA/ICdib3R0b20nIDogJ2xlZnQnLFxuICAgICAgICAgICAgICAgICAgICBkdHlwZTogaXNSYWRpYWwgPyAncmFkaWFsTGluZWFyJyA6IGlzSG9yaXpvbnRhbCA/ICdjYXRlZ29yeScgOiAnbGluZWFyJ1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9KSk7XG4gICAgICAgIH1cbiAgICAgICAgZWFjaChpdGVtcywgKGl0ZW0pPT57XG4gICAgICAgICAgICBjb25zdCBzY2FsZU9wdGlvbnMgPSBpdGVtLm9wdGlvbnM7XG4gICAgICAgICAgICBjb25zdCBpZCA9IHNjYWxlT3B0aW9ucy5pZDtcbiAgICAgICAgICAgIGNvbnN0IGF4aXMgPSBkZXRlcm1pbmVBeGlzKGlkLCBzY2FsZU9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3Qgc2NhbGVUeXBlID0gdmFsdWVPckRlZmF1bHQoc2NhbGVPcHRpb25zLnR5cGUsIGl0ZW0uZHR5cGUpO1xuICAgICAgICAgICAgaWYgKHNjYWxlT3B0aW9ucy5wb3NpdGlvbiA9PT0gdW5kZWZpbmVkIHx8IHBvc2l0aW9uSXNIb3Jpem9udGFsKHNjYWxlT3B0aW9ucy5wb3NpdGlvbiwgYXhpcykgIT09IHBvc2l0aW9uSXNIb3Jpem9udGFsKGl0ZW0uZHBvc2l0aW9uKSkge1xuICAgICAgICAgICAgICAgIHNjYWxlT3B0aW9ucy5wb3NpdGlvbiA9IGl0ZW0uZHBvc2l0aW9uO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdXBkYXRlZFtpZF0gPSB0cnVlO1xuICAgICAgICAgICAgbGV0IHNjYWxlID0gbnVsbDtcbiAgICAgICAgICAgIGlmIChpZCBpbiBzY2FsZXMgJiYgc2NhbGVzW2lkXS50eXBlID09PSBzY2FsZVR5cGUpIHtcbiAgICAgICAgICAgICAgICBzY2FsZSA9IHNjYWxlc1tpZF07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNjYWxlQ2xhc3MgPSByZWdpc3RyeS5nZXRTY2FsZShzY2FsZVR5cGUpO1xuICAgICAgICAgICAgICAgIHNjYWxlID0gbmV3IHNjYWxlQ2xhc3Moe1xuICAgICAgICAgICAgICAgICAgICBpZCxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogc2NhbGVUeXBlLFxuICAgICAgICAgICAgICAgICAgICBjdHg6IHRoaXMuY3R4LFxuICAgICAgICAgICAgICAgICAgICBjaGFydDogdGhpc1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHNjYWxlc1tzY2FsZS5pZF0gPSBzY2FsZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNjYWxlLmluaXQoc2NhbGVPcHRpb25zLCBvcHRpb25zKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGVhY2godXBkYXRlZCwgKGhhc1VwZGF0ZWQsIGlkKT0+e1xuICAgICAgICAgICAgaWYgKCFoYXNVcGRhdGVkKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHNjYWxlc1tpZF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBlYWNoKHNjYWxlcywgKHNjYWxlKT0+e1xuICAgICAgICAgICAgbGF5b3V0cy5jb25maWd1cmUodGhpcywgc2NhbGUsIHNjYWxlLm9wdGlvbnMpO1xuICAgICAgICAgICAgbGF5b3V0cy5hZGRCb3godGhpcywgc2NhbGUpO1xuICAgICAgICB9KTtcbiAgICB9XG4gX3VwZGF0ZU1ldGFzZXRzKCkge1xuICAgICAgICBjb25zdCBtZXRhc2V0cyA9IHRoaXMuX21ldGFzZXRzO1xuICAgICAgICBjb25zdCBudW1EYXRhID0gdGhpcy5kYXRhLmRhdGFzZXRzLmxlbmd0aDtcbiAgICAgICAgY29uc3QgbnVtTWV0YSA9IG1ldGFzZXRzLmxlbmd0aDtcbiAgICAgICAgbWV0YXNldHMuc29ydCgoYSwgYik9PmEuaW5kZXggLSBiLmluZGV4KTtcbiAgICAgICAgaWYgKG51bU1ldGEgPiBudW1EYXRhKSB7XG4gICAgICAgICAgICBmb3IobGV0IGkgPSBudW1EYXRhOyBpIDwgbnVtTWV0YTsgKytpKXtcbiAgICAgICAgICAgICAgICB0aGlzLl9kZXN0cm95RGF0YXNldE1ldGEoaSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBtZXRhc2V0cy5zcGxpY2UobnVtRGF0YSwgbnVtTWV0YSAtIG51bURhdGEpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3NvcnRlZE1ldGFzZXRzID0gbWV0YXNldHMuc2xpY2UoMCkuc29ydChjb21wYXJlMkxldmVsKCdvcmRlcicsICdpbmRleCcpKTtcbiAgICB9XG4gX3JlbW92ZVVucmVmZXJlbmNlZE1ldGFzZXRzKCkge1xuICAgICAgICBjb25zdCB7IF9tZXRhc2V0czogbWV0YXNldHMgLCBkYXRhOiB7IGRhdGFzZXRzICB9ICB9ID0gdGhpcztcbiAgICAgICAgaWYgKG1ldGFzZXRzLmxlbmd0aCA+IGRhdGFzZXRzLmxlbmd0aCkge1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuX3N0YWNrcztcbiAgICAgICAgfVxuICAgICAgICBtZXRhc2V0cy5mb3JFYWNoKChtZXRhLCBpbmRleCk9PntcbiAgICAgICAgICAgIGlmIChkYXRhc2V0cy5maWx0ZXIoKHgpPT54ID09PSBtZXRhLl9kYXRhc2V0KS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9kZXN0cm95RGF0YXNldE1ldGEoaW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgYnVpbGRPclVwZGF0ZUNvbnRyb2xsZXJzKCkge1xuICAgICAgICBjb25zdCBuZXdDb250cm9sbGVycyA9IFtdO1xuICAgICAgICBjb25zdCBkYXRhc2V0cyA9IHRoaXMuZGF0YS5kYXRhc2V0cztcbiAgICAgICAgbGV0IGksIGlsZW47XG4gICAgICAgIHRoaXMuX3JlbW92ZVVucmVmZXJlbmNlZE1ldGFzZXRzKCk7XG4gICAgICAgIGZvcihpID0gMCwgaWxlbiA9IGRhdGFzZXRzLmxlbmd0aDsgaSA8IGlsZW47IGkrKyl7XG4gICAgICAgICAgICBjb25zdCBkYXRhc2V0ID0gZGF0YXNldHNbaV07XG4gICAgICAgICAgICBsZXQgbWV0YSA9IHRoaXMuZ2V0RGF0YXNldE1ldGEoaSk7XG4gICAgICAgICAgICBjb25zdCB0eXBlID0gZGF0YXNldC50eXBlIHx8IHRoaXMuY29uZmlnLnR5cGU7XG4gICAgICAgICAgICBpZiAobWV0YS50eXBlICYmIG1ldGEudHlwZSAhPT0gdHlwZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2Rlc3Ryb3lEYXRhc2V0TWV0YShpKTtcbiAgICAgICAgICAgICAgICBtZXRhID0gdGhpcy5nZXREYXRhc2V0TWV0YShpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG1ldGEudHlwZSA9IHR5cGU7XG4gICAgICAgICAgICBtZXRhLmluZGV4QXhpcyA9IGRhdGFzZXQuaW5kZXhBeGlzIHx8IGdldEluZGV4QXhpcyh0eXBlLCB0aGlzLm9wdGlvbnMpO1xuICAgICAgICAgICAgbWV0YS5vcmRlciA9IGRhdGFzZXQub3JkZXIgfHwgMDtcbiAgICAgICAgICAgIG1ldGEuaW5kZXggPSBpO1xuICAgICAgICAgICAgbWV0YS5sYWJlbCA9ICcnICsgZGF0YXNldC5sYWJlbDtcbiAgICAgICAgICAgIG1ldGEudmlzaWJsZSA9IHRoaXMuaXNEYXRhc2V0VmlzaWJsZShpKTtcbiAgICAgICAgICAgIGlmIChtZXRhLmNvbnRyb2xsZXIpIHtcbiAgICAgICAgICAgICAgICBtZXRhLmNvbnRyb2xsZXIudXBkYXRlSW5kZXgoaSk7XG4gICAgICAgICAgICAgICAgbWV0YS5jb250cm9sbGVyLmxpbmtTY2FsZXMoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgQ29udHJvbGxlckNsYXNzID0gcmVnaXN0cnkuZ2V0Q29udHJvbGxlcih0eXBlKTtcbiAgICAgICAgICAgICAgICBjb25zdCB7IGRhdGFzZXRFbGVtZW50VHlwZSAsIGRhdGFFbGVtZW50VHlwZSAgfSA9IGRlZmF1bHRzLmRhdGFzZXRzW3R5cGVdO1xuICAgICAgICAgICAgICAgIE9iamVjdC5hc3NpZ24oQ29udHJvbGxlckNsYXNzLCB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGFFbGVtZW50VHlwZTogcmVnaXN0cnkuZ2V0RWxlbWVudChkYXRhRWxlbWVudFR5cGUpLFxuICAgICAgICAgICAgICAgICAgICBkYXRhc2V0RWxlbWVudFR5cGU6IGRhdGFzZXRFbGVtZW50VHlwZSAmJiByZWdpc3RyeS5nZXRFbGVtZW50KGRhdGFzZXRFbGVtZW50VHlwZSlcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBtZXRhLmNvbnRyb2xsZXIgPSBuZXcgQ29udHJvbGxlckNsYXNzKHRoaXMsIGkpO1xuICAgICAgICAgICAgICAgIG5ld0NvbnRyb2xsZXJzLnB1c2gobWV0YS5jb250cm9sbGVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLl91cGRhdGVNZXRhc2V0cygpO1xuICAgICAgICByZXR1cm4gbmV3Q29udHJvbGxlcnM7XG4gICAgfVxuIF9yZXNldEVsZW1lbnRzKCkge1xuICAgICAgICBlYWNoKHRoaXMuZGF0YS5kYXRhc2V0cywgKGRhdGFzZXQsIGRhdGFzZXRJbmRleCk9PntcbiAgICAgICAgICAgIHRoaXMuZ2V0RGF0YXNldE1ldGEoZGF0YXNldEluZGV4KS5jb250cm9sbGVyLnJlc2V0KCk7XG4gICAgICAgIH0sIHRoaXMpO1xuICAgIH1cbiByZXNldCgpIHtcbiAgICAgICAgdGhpcy5fcmVzZXRFbGVtZW50cygpO1xuICAgICAgICB0aGlzLm5vdGlmeVBsdWdpbnMoJ3Jlc2V0Jyk7XG4gICAgfVxuICAgIHVwZGF0ZShtb2RlKSB7XG4gICAgICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuY29uZmlnO1xuICAgICAgICBjb25maWcudXBkYXRlKCk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLl9vcHRpb25zID0gY29uZmlnLmNyZWF0ZVJlc29sdmVyKGNvbmZpZy5jaGFydE9wdGlvblNjb3BlcygpLCB0aGlzLmdldENvbnRleHQoKSk7XG4gICAgICAgIGNvbnN0IGFuaW1zRGlzYWJsZWQgPSB0aGlzLl9hbmltYXRpb25zRGlzYWJsZWQgPSAhb3B0aW9ucy5hbmltYXRpb247XG4gICAgICAgIHRoaXMuX3VwZGF0ZVNjYWxlcygpO1xuICAgICAgICB0aGlzLl9jaGVja0V2ZW50QmluZGluZ3MoKTtcbiAgICAgICAgdGhpcy5fdXBkYXRlSGlkZGVuSW5kaWNlcygpO1xuICAgICAgICB0aGlzLl9wbHVnaW5zLmludmFsaWRhdGUoKTtcbiAgICAgICAgaWYgKHRoaXMubm90aWZ5UGx1Z2lucygnYmVmb3JlVXBkYXRlJywge1xuICAgICAgICAgICAgbW9kZSxcbiAgICAgICAgICAgIGNhbmNlbGFibGU6IHRydWVcbiAgICAgICAgfSkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV3Q29udHJvbGxlcnMgPSB0aGlzLmJ1aWxkT3JVcGRhdGVDb250cm9sbGVycygpO1xuICAgICAgICB0aGlzLm5vdGlmeVBsdWdpbnMoJ2JlZm9yZUVsZW1lbnRzVXBkYXRlJyk7XG4gICAgICAgIGxldCBtaW5QYWRkaW5nID0gMDtcbiAgICAgICAgZm9yKGxldCBpID0gMCwgaWxlbiA9IHRoaXMuZGF0YS5kYXRhc2V0cy5sZW5ndGg7IGkgPCBpbGVuOyBpKyspe1xuICAgICAgICAgICAgY29uc3QgeyBjb250cm9sbGVyICB9ID0gdGhpcy5nZXREYXRhc2V0TWV0YShpKTtcbiAgICAgICAgICAgIGNvbnN0IHJlc2V0ID0gIWFuaW1zRGlzYWJsZWQgJiYgbmV3Q29udHJvbGxlcnMuaW5kZXhPZihjb250cm9sbGVyKSA9PT0gLTE7XG4gICAgICAgICAgICBjb250cm9sbGVyLmJ1aWxkT3JVcGRhdGVFbGVtZW50cyhyZXNldCk7XG4gICAgICAgICAgICBtaW5QYWRkaW5nID0gTWF0aC5tYXgoK2NvbnRyb2xsZXIuZ2V0TWF4T3ZlcmZsb3coKSwgbWluUGFkZGluZyk7XG4gICAgICAgIH1cbiAgICAgICAgbWluUGFkZGluZyA9IHRoaXMuX21pblBhZGRpbmcgPSBvcHRpb25zLmxheW91dC5hdXRvUGFkZGluZyA/IG1pblBhZGRpbmcgOiAwO1xuICAgICAgICB0aGlzLl91cGRhdGVMYXlvdXQobWluUGFkZGluZyk7XG4gICAgICAgIGlmICghYW5pbXNEaXNhYmxlZCkge1xuICAgICAgICAgICAgZWFjaChuZXdDb250cm9sbGVycywgKGNvbnRyb2xsZXIpPT57XG4gICAgICAgICAgICAgICAgY29udHJvbGxlci5yZXNldCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fdXBkYXRlRGF0YXNldHMobW9kZSk7XG4gICAgICAgIHRoaXMubm90aWZ5UGx1Z2lucygnYWZ0ZXJVcGRhdGUnLCB7XG4gICAgICAgICAgICBtb2RlXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9sYXllcnMuc29ydChjb21wYXJlMkxldmVsKCd6JywgJ19pZHgnKSk7XG4gICAgICAgIGNvbnN0IHsgX2FjdGl2ZSAsIF9sYXN0RXZlbnQgIH0gPSB0aGlzO1xuICAgICAgICBpZiAoX2xhc3RFdmVudCkge1xuICAgICAgICAgICAgdGhpcy5fZXZlbnRIYW5kbGVyKF9sYXN0RXZlbnQsIHRydWUpO1xuICAgICAgICB9IGVsc2UgaWYgKF9hY3RpdmUubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLl91cGRhdGVIb3ZlclN0eWxlcyhfYWN0aXZlLCBfYWN0aXZlLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cbiBfdXBkYXRlU2NhbGVzKCkge1xuICAgICAgICBlYWNoKHRoaXMuc2NhbGVzLCAoc2NhbGUpPT57XG4gICAgICAgICAgICBsYXlvdXRzLnJlbW92ZUJveCh0aGlzLCBzY2FsZSk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmVuc3VyZVNjYWxlc0hhdmVJRHMoKTtcbiAgICAgICAgdGhpcy5idWlsZE9yVXBkYXRlU2NhbGVzKCk7XG4gICAgfVxuIF9jaGVja0V2ZW50QmluZGluZ3MoKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nRXZlbnRzID0gbmV3IFNldChPYmplY3Qua2V5cyh0aGlzLl9saXN0ZW5lcnMpKTtcbiAgICAgICAgY29uc3QgbmV3RXZlbnRzID0gbmV3IFNldChvcHRpb25zLmV2ZW50cyk7XG4gICAgICAgIGlmICghc2V0c0VxdWFsKGV4aXN0aW5nRXZlbnRzLCBuZXdFdmVudHMpIHx8ICEhdGhpcy5fcmVzcG9uc2l2ZUxpc3RlbmVycyAhPT0gb3B0aW9ucy5yZXNwb25zaXZlKSB7XG4gICAgICAgICAgICB0aGlzLnVuYmluZEV2ZW50cygpO1xuICAgICAgICAgICAgdGhpcy5iaW5kRXZlbnRzKCk7XG4gICAgICAgIH1cbiAgICB9XG4gX3VwZGF0ZUhpZGRlbkluZGljZXMoKSB7XG4gICAgICAgIGNvbnN0IHsgX2hpZGRlbkluZGljZXMgIH0gPSB0aGlzO1xuICAgICAgICBjb25zdCBjaGFuZ2VzID0gdGhpcy5fZ2V0VW5pZm9ybURhdGFDaGFuZ2VzKCkgfHwgW107XG4gICAgICAgIGZvciAoY29uc3QgeyBtZXRob2QgLCBzdGFydCAsIGNvdW50ICB9IG9mIGNoYW5nZXMpe1xuICAgICAgICAgICAgY29uc3QgbW92ZSA9IG1ldGhvZCA9PT0gJ19yZW1vdmVFbGVtZW50cycgPyAtY291bnQgOiBjb3VudDtcbiAgICAgICAgICAgIG1vdmVOdW1lcmljS2V5cyhfaGlkZGVuSW5kaWNlcywgc3RhcnQsIG1vdmUpO1xuICAgICAgICB9XG4gICAgfVxuIF9nZXRVbmlmb3JtRGF0YUNoYW5nZXMoKSB7XG4gICAgICAgIGNvbnN0IF9kYXRhQ2hhbmdlcyA9IHRoaXMuX2RhdGFDaGFuZ2VzO1xuICAgICAgICBpZiAoIV9kYXRhQ2hhbmdlcyB8fCAhX2RhdGFDaGFuZ2VzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2RhdGFDaGFuZ2VzID0gW107XG4gICAgICAgIGNvbnN0IGRhdGFzZXRDb3VudCA9IHRoaXMuZGF0YS5kYXRhc2V0cy5sZW5ndGg7XG4gICAgICAgIGNvbnN0IG1ha2VTZXQgPSAoaWR4KT0+bmV3IFNldChfZGF0YUNoYW5nZXMuZmlsdGVyKChjKT0+Y1swXSA9PT0gaWR4KS5tYXAoKGMsIGkpPT5pICsgJywnICsgYy5zcGxpY2UoMSkuam9pbignLCcpKSk7XG4gICAgICAgIGNvbnN0IGNoYW5nZVNldCA9IG1ha2VTZXQoMCk7XG4gICAgICAgIGZvcihsZXQgaSA9IDE7IGkgPCBkYXRhc2V0Q291bnQ7IGkrKyl7XG4gICAgICAgICAgICBpZiAoIXNldHNFcXVhbChjaGFuZ2VTZXQsIG1ha2VTZXQoaSkpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBBcnJheS5mcm9tKGNoYW5nZVNldCkubWFwKChjKT0+Yy5zcGxpdCgnLCcpKS5tYXAoKGEpPT4oe1xuICAgICAgICAgICAgICAgIG1ldGhvZDogYVsxXSxcbiAgICAgICAgICAgICAgICBzdGFydDogK2FbMl0sXG4gICAgICAgICAgICAgICAgY291bnQ6ICthWzNdXG4gICAgICAgICAgICB9KSk7XG4gICAgfVxuIF91cGRhdGVMYXlvdXQobWluUGFkZGluZykge1xuICAgICAgICBpZiAodGhpcy5ub3RpZnlQbHVnaW5zKCdiZWZvcmVMYXlvdXQnLCB7XG4gICAgICAgICAgICBjYW5jZWxhYmxlOiB0cnVlXG4gICAgICAgIH0pID09PSBmYWxzZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGxheW91dHMudXBkYXRlKHRoaXMsIHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0LCBtaW5QYWRkaW5nKTtcbiAgICAgICAgY29uc3QgYXJlYSA9IHRoaXMuY2hhcnRBcmVhO1xuICAgICAgICBjb25zdCBub0FyZWEgPSBhcmVhLndpZHRoIDw9IDAgfHwgYXJlYS5oZWlnaHQgPD0gMDtcbiAgICAgICAgdGhpcy5fbGF5ZXJzID0gW107XG4gICAgICAgIGVhY2godGhpcy5ib3hlcywgKGJveCk9PntcbiAgICAgICAgICAgIGlmIChub0FyZWEgJiYgYm94LnBvc2l0aW9uID09PSAnY2hhcnRBcmVhJykge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChib3guY29uZmlndXJlKSB7XG4gICAgICAgICAgICAgICAgYm94LmNvbmZpZ3VyZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fbGF5ZXJzLnB1c2goLi4uYm94Ll9sYXllcnMoKSk7XG4gICAgICAgIH0sIHRoaXMpO1xuICAgICAgICB0aGlzLl9sYXllcnMuZm9yRWFjaCgoaXRlbSwgaW5kZXgpPT57XG4gICAgICAgICAgICBpdGVtLl9pZHggPSBpbmRleDtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubm90aWZ5UGx1Z2lucygnYWZ0ZXJMYXlvdXQnKTtcbiAgICB9XG4gX3VwZGF0ZURhdGFzZXRzKG1vZGUpIHtcbiAgICAgICAgaWYgKHRoaXMubm90aWZ5UGx1Z2lucygnYmVmb3JlRGF0YXNldHNVcGRhdGUnLCB7XG4gICAgICAgICAgICBtb2RlLFxuICAgICAgICAgICAgY2FuY2VsYWJsZTogdHJ1ZVxuICAgICAgICB9KSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBmb3IobGV0IGkgPSAwLCBpbGVuID0gdGhpcy5kYXRhLmRhdGFzZXRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSl7XG4gICAgICAgICAgICB0aGlzLmdldERhdGFzZXRNZXRhKGkpLmNvbnRyb2xsZXIuY29uZmlndXJlKCk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yKGxldCBpID0gMCwgaWxlbiA9IHRoaXMuZGF0YS5kYXRhc2V0cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpe1xuICAgICAgICAgICAgdGhpcy5fdXBkYXRlRGF0YXNldChpLCBpc0Z1bmN0aW9uKG1vZGUpID8gbW9kZSh7XG4gICAgICAgICAgICAgICAgZGF0YXNldEluZGV4OiBpXG4gICAgICAgICAgICB9KSA6IG1vZGUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubm90aWZ5UGx1Z2lucygnYWZ0ZXJEYXRhc2V0c1VwZGF0ZScsIHtcbiAgICAgICAgICAgIG1vZGVcbiAgICAgICAgfSk7XG4gICAgfVxuIF91cGRhdGVEYXRhc2V0KGluZGV4LCBtb2RlKSB7XG4gICAgICAgIGNvbnN0IG1ldGEgPSB0aGlzLmdldERhdGFzZXRNZXRhKGluZGV4KTtcbiAgICAgICAgY29uc3QgYXJncyA9IHtcbiAgICAgICAgICAgIG1ldGEsXG4gICAgICAgICAgICBpbmRleCxcbiAgICAgICAgICAgIG1vZGUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiB0cnVlXG4gICAgICAgIH07XG4gICAgICAgIGlmICh0aGlzLm5vdGlmeVBsdWdpbnMoJ2JlZm9yZURhdGFzZXRVcGRhdGUnLCBhcmdzKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBtZXRhLmNvbnRyb2xsZXIuX3VwZGF0ZShtb2RlKTtcbiAgICAgICAgYXJncy5jYW5jZWxhYmxlID0gZmFsc2U7XG4gICAgICAgIHRoaXMubm90aWZ5UGx1Z2lucygnYWZ0ZXJEYXRhc2V0VXBkYXRlJywgYXJncyk7XG4gICAgfVxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgaWYgKHRoaXMubm90aWZ5UGx1Z2lucygnYmVmb3JlUmVuZGVyJywge1xuICAgICAgICAgICAgY2FuY2VsYWJsZTogdHJ1ZVxuICAgICAgICB9KSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYW5pbWF0b3IuaGFzKHRoaXMpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hdHRhY2hlZCAmJiAhYW5pbWF0b3IucnVubmluZyh0aGlzKSkge1xuICAgICAgICAgICAgICAgIGFuaW1hdG9yLnN0YXJ0KHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5kcmF3KCk7XG4gICAgICAgICAgICBvbkFuaW1hdGlvbnNDb21wbGV0ZSh7XG4gICAgICAgICAgICAgICAgY2hhcnQ6IHRoaXNcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIGRyYXcoKSB7XG4gICAgICAgIGxldCBpO1xuICAgICAgICBpZiAodGhpcy5fcmVzaXplQmVmb3JlRHJhdykge1xuICAgICAgICAgICAgY29uc3QgeyB3aWR0aCAsIGhlaWdodCAgfSA9IHRoaXMuX3Jlc2l6ZUJlZm9yZURyYXc7XG4gICAgICAgICAgICB0aGlzLl9yZXNpemVCZWZvcmVEcmF3ID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX3Jlc2l6ZSh3aWR0aCwgaGVpZ2h0KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNsZWFyKCk7XG4gICAgICAgIGlmICh0aGlzLndpZHRoIDw9IDAgfHwgdGhpcy5oZWlnaHQgPD0gMCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLm5vdGlmeVBsdWdpbnMoJ2JlZm9yZURyYXcnLCB7XG4gICAgICAgICAgICBjYW5jZWxhYmxlOiB0cnVlXG4gICAgICAgIH0pID09PSBmYWxzZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGxheWVycyA9IHRoaXMuX2xheWVycztcbiAgICAgICAgZm9yKGkgPSAwOyBpIDwgbGF5ZXJzLmxlbmd0aCAmJiBsYXllcnNbaV0ueiA8PSAwOyArK2kpe1xuICAgICAgICAgICAgbGF5ZXJzW2ldLmRyYXcodGhpcy5jaGFydEFyZWEpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2RyYXdEYXRhc2V0cygpO1xuICAgICAgICBmb3IoOyBpIDwgbGF5ZXJzLmxlbmd0aDsgKytpKXtcbiAgICAgICAgICAgIGxheWVyc1tpXS5kcmF3KHRoaXMuY2hhcnRBcmVhKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm5vdGlmeVBsdWdpbnMoJ2FmdGVyRHJhdycpO1xuICAgIH1cbiBfZ2V0U29ydGVkRGF0YXNldE1ldGFzKGZpbHRlclZpc2libGUpIHtcbiAgICAgICAgY29uc3QgbWV0YXNldHMgPSB0aGlzLl9zb3J0ZWRNZXRhc2V0cztcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgICAgIGxldCBpLCBpbGVuO1xuICAgICAgICBmb3IoaSA9IDAsIGlsZW4gPSBtZXRhc2V0cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpe1xuICAgICAgICAgICAgY29uc3QgbWV0YSA9IG1ldGFzZXRzW2ldO1xuICAgICAgICAgICAgaWYgKCFmaWx0ZXJWaXNpYmxlIHx8IG1ldGEudmlzaWJsZSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKG1ldGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuIGdldFNvcnRlZFZpc2libGVEYXRhc2V0TWV0YXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRTb3J0ZWREYXRhc2V0TWV0YXModHJ1ZSk7XG4gICAgfVxuIF9kcmF3RGF0YXNldHMoKSB7XG4gICAgICAgIGlmICh0aGlzLm5vdGlmeVBsdWdpbnMoJ2JlZm9yZURhdGFzZXRzRHJhdycsIHtcbiAgICAgICAgICAgIGNhbmNlbGFibGU6IHRydWVcbiAgICAgICAgfSkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbWV0YXNldHMgPSB0aGlzLmdldFNvcnRlZFZpc2libGVEYXRhc2V0TWV0YXMoKTtcbiAgICAgICAgZm9yKGxldCBpID0gbWV0YXNldHMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpe1xuICAgICAgICAgICAgdGhpcy5fZHJhd0RhdGFzZXQobWV0YXNldHNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubm90aWZ5UGx1Z2lucygnYWZ0ZXJEYXRhc2V0c0RyYXcnKTtcbiAgICB9XG4gX2RyYXdEYXRhc2V0KG1ldGEpIHtcbiAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgICAgIGNvbnN0IGNsaXAgPSBtZXRhLl9jbGlwO1xuICAgICAgICBjb25zdCB1c2VDbGlwID0gIWNsaXAuZGlzYWJsZWQ7XG4gICAgICAgIGNvbnN0IGFyZWEgPSBnZXREYXRhc2V0QXJlYShtZXRhLCB0aGlzLmNoYXJ0QXJlYSk7XG4gICAgICAgIGNvbnN0IGFyZ3MgPSB7XG4gICAgICAgICAgICBtZXRhLFxuICAgICAgICAgICAgaW5kZXg6IG1ldGEuaW5kZXgsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiB0cnVlXG4gICAgICAgIH07XG4gICAgICAgIGlmICh0aGlzLm5vdGlmeVBsdWdpbnMoJ2JlZm9yZURhdGFzZXREcmF3JywgYXJncykgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHVzZUNsaXApIHtcbiAgICAgICAgICAgIGNsaXBBcmVhKGN0eCwge1xuICAgICAgICAgICAgICAgIGxlZnQ6IGNsaXAubGVmdCA9PT0gZmFsc2UgPyAwIDogYXJlYS5sZWZ0IC0gY2xpcC5sZWZ0LFxuICAgICAgICAgICAgICAgIHJpZ2h0OiBjbGlwLnJpZ2h0ID09PSBmYWxzZSA/IHRoaXMud2lkdGggOiBhcmVhLnJpZ2h0ICsgY2xpcC5yaWdodCxcbiAgICAgICAgICAgICAgICB0b3A6IGNsaXAudG9wID09PSBmYWxzZSA/IDAgOiBhcmVhLnRvcCAtIGNsaXAudG9wLFxuICAgICAgICAgICAgICAgIGJvdHRvbTogY2xpcC5ib3R0b20gPT09IGZhbHNlID8gdGhpcy5oZWlnaHQgOiBhcmVhLmJvdHRvbSArIGNsaXAuYm90dG9tXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBtZXRhLmNvbnRyb2xsZXIuZHJhdygpO1xuICAgICAgICBpZiAodXNlQ2xpcCkge1xuICAgICAgICAgICAgdW5jbGlwQXJlYShjdHgpO1xuICAgICAgICB9XG4gICAgICAgIGFyZ3MuY2FuY2VsYWJsZSA9IGZhbHNlO1xuICAgICAgICB0aGlzLm5vdGlmeVBsdWdpbnMoJ2FmdGVyRGF0YXNldERyYXcnLCBhcmdzKTtcbiAgICB9XG4gaXNQb2ludEluQXJlYShwb2ludCkge1xuICAgICAgICByZXR1cm4gX2lzUG9pbnRJbkFyZWEocG9pbnQsIHRoaXMuY2hhcnRBcmVhLCB0aGlzLl9taW5QYWRkaW5nKTtcbiAgICB9XG4gICAgZ2V0RWxlbWVudHNBdEV2ZW50Rm9yTW9kZShlLCBtb2RlLCBvcHRpb25zLCB1c2VGaW5hbFBvc2l0aW9uKSB7XG4gICAgICAgIGNvbnN0IG1ldGhvZCA9IEludGVyYWN0aW9uLm1vZGVzW21vZGVdO1xuICAgICAgICBpZiAodHlwZW9mIG1ldGhvZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcmV0dXJuIG1ldGhvZCh0aGlzLCBlLCBvcHRpb25zLCB1c2VGaW5hbFBvc2l0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGdldERhdGFzZXRNZXRhKGRhdGFzZXRJbmRleCkge1xuICAgICAgICBjb25zdCBkYXRhc2V0ID0gdGhpcy5kYXRhLmRhdGFzZXRzW2RhdGFzZXRJbmRleF07XG4gICAgICAgIGNvbnN0IG1ldGFzZXRzID0gdGhpcy5fbWV0YXNldHM7XG4gICAgICAgIGxldCBtZXRhID0gbWV0YXNldHMuZmlsdGVyKCh4KT0+eCAmJiB4Ll9kYXRhc2V0ID09PSBkYXRhc2V0KS5wb3AoKTtcbiAgICAgICAgaWYgKCFtZXRhKSB7XG4gICAgICAgICAgICBtZXRhID0ge1xuICAgICAgICAgICAgICAgIHR5cGU6IG51bGwsXG4gICAgICAgICAgICAgICAgZGF0YTogW10sXG4gICAgICAgICAgICAgICAgZGF0YXNldDogbnVsbCxcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyOiBudWxsLFxuICAgICAgICAgICAgICAgIGhpZGRlbjogbnVsbCxcbiAgICAgICAgICAgICAgICB4QXhpc0lEOiBudWxsLFxuICAgICAgICAgICAgICAgIHlBeGlzSUQ6IG51bGwsXG4gICAgICAgICAgICAgICAgb3JkZXI6IGRhdGFzZXQgJiYgZGF0YXNldC5vcmRlciB8fCAwLFxuICAgICAgICAgICAgICAgIGluZGV4OiBkYXRhc2V0SW5kZXgsXG4gICAgICAgICAgICAgICAgX2RhdGFzZXQ6IGRhdGFzZXQsXG4gICAgICAgICAgICAgICAgX3BhcnNlZDogW10sXG4gICAgICAgICAgICAgICAgX3NvcnRlZDogZmFsc2VcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBtZXRhc2V0cy5wdXNoKG1ldGEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZXRhO1xuICAgIH1cbiAgICBnZXRDb250ZXh0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy4kY29udGV4dCB8fCAodGhpcy4kY29udGV4dCA9IGNyZWF0ZUNvbnRleHQobnVsbCwge1xuICAgICAgICAgICAgY2hhcnQ6IHRoaXMsXG4gICAgICAgICAgICB0eXBlOiAnY2hhcnQnXG4gICAgICAgIH0pKTtcbiAgICB9XG4gICAgZ2V0VmlzaWJsZURhdGFzZXRDb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0U29ydGVkVmlzaWJsZURhdGFzZXRNZXRhcygpLmxlbmd0aDtcbiAgICB9XG4gICAgaXNEYXRhc2V0VmlzaWJsZShkYXRhc2V0SW5kZXgpIHtcbiAgICAgICAgY29uc3QgZGF0YXNldCA9IHRoaXMuZGF0YS5kYXRhc2V0c1tkYXRhc2V0SW5kZXhdO1xuICAgICAgICBpZiAoIWRhdGFzZXQpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBtZXRhID0gdGhpcy5nZXREYXRhc2V0TWV0YShkYXRhc2V0SW5kZXgpO1xuICAgICAgICByZXR1cm4gdHlwZW9mIG1ldGEuaGlkZGVuID09PSAnYm9vbGVhbicgPyAhbWV0YS5oaWRkZW4gOiAhZGF0YXNldC5oaWRkZW47XG4gICAgfVxuICAgIHNldERhdGFzZXRWaXNpYmlsaXR5KGRhdGFzZXRJbmRleCwgdmlzaWJsZSkge1xuICAgICAgICBjb25zdCBtZXRhID0gdGhpcy5nZXREYXRhc2V0TWV0YShkYXRhc2V0SW5kZXgpO1xuICAgICAgICBtZXRhLmhpZGRlbiA9ICF2aXNpYmxlO1xuICAgIH1cbiAgICB0b2dnbGVEYXRhVmlzaWJpbGl0eShpbmRleCkge1xuICAgICAgICB0aGlzLl9oaWRkZW5JbmRpY2VzW2luZGV4XSA9ICF0aGlzLl9oaWRkZW5JbmRpY2VzW2luZGV4XTtcbiAgICB9XG4gICAgZ2V0RGF0YVZpc2liaWxpdHkoaW5kZXgpIHtcbiAgICAgICAgcmV0dXJuICF0aGlzLl9oaWRkZW5JbmRpY2VzW2luZGV4XTtcbiAgICB9XG4gX3VwZGF0ZVZpc2liaWxpdHkoZGF0YXNldEluZGV4LCBkYXRhSW5kZXgsIHZpc2libGUpIHtcbiAgICAgICAgY29uc3QgbW9kZSA9IHZpc2libGUgPyAnc2hvdycgOiAnaGlkZSc7XG4gICAgICAgIGNvbnN0IG1ldGEgPSB0aGlzLmdldERhdGFzZXRNZXRhKGRhdGFzZXRJbmRleCk7XG4gICAgICAgIGNvbnN0IGFuaW1zID0gbWV0YS5jb250cm9sbGVyLl9yZXNvbHZlQW5pbWF0aW9ucyh1bmRlZmluZWQsIG1vZGUpO1xuICAgICAgICBpZiAoZGVmaW5lZChkYXRhSW5kZXgpKSB7XG4gICAgICAgICAgICBtZXRhLmRhdGFbZGF0YUluZGV4XS5oaWRkZW4gPSAhdmlzaWJsZTtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNldERhdGFzZXRWaXNpYmlsaXR5KGRhdGFzZXRJbmRleCwgdmlzaWJsZSk7XG4gICAgICAgICAgICBhbmltcy51cGRhdGUobWV0YSwge1xuICAgICAgICAgICAgICAgIHZpc2libGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy51cGRhdGUoKGN0eCk9PmN0eC5kYXRhc2V0SW5kZXggPT09IGRhdGFzZXRJbmRleCA/IG1vZGUgOiB1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGhpZGUoZGF0YXNldEluZGV4LCBkYXRhSW5kZXgpIHtcbiAgICAgICAgdGhpcy5fdXBkYXRlVmlzaWJpbGl0eShkYXRhc2V0SW5kZXgsIGRhdGFJbmRleCwgZmFsc2UpO1xuICAgIH1cbiAgICBzaG93KGRhdGFzZXRJbmRleCwgZGF0YUluZGV4KSB7XG4gICAgICAgIHRoaXMuX3VwZGF0ZVZpc2liaWxpdHkoZGF0YXNldEluZGV4LCBkYXRhSW5kZXgsIHRydWUpO1xuICAgIH1cbiBfZGVzdHJveURhdGFzZXRNZXRhKGRhdGFzZXRJbmRleCkge1xuICAgICAgICBjb25zdCBtZXRhID0gdGhpcy5fbWV0YXNldHNbZGF0YXNldEluZGV4XTtcbiAgICAgICAgaWYgKG1ldGEgJiYgbWV0YS5jb250cm9sbGVyKSB7XG4gICAgICAgICAgICBtZXRhLmNvbnRyb2xsZXIuX2Rlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgICBkZWxldGUgdGhpcy5fbWV0YXNldHNbZGF0YXNldEluZGV4XTtcbiAgICB9XG4gICAgX3N0b3AoKSB7XG4gICAgICAgIGxldCBpLCBpbGVuO1xuICAgICAgICB0aGlzLnN0b3AoKTtcbiAgICAgICAgYW5pbWF0b3IucmVtb3ZlKHRoaXMpO1xuICAgICAgICBmb3IoaSA9IDAsIGlsZW4gPSB0aGlzLmRhdGEuZGF0YXNldHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKXtcbiAgICAgICAgICAgIHRoaXMuX2Rlc3Ryb3lEYXRhc2V0TWV0YShpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBkZXN0cm95KCkge1xuICAgICAgICB0aGlzLm5vdGlmeVBsdWdpbnMoJ2JlZm9yZURlc3Ryb3knKTtcbiAgICAgICAgY29uc3QgeyBjYW52YXMgLCBjdHggIH0gPSB0aGlzO1xuICAgICAgICB0aGlzLl9zdG9wKCk7XG4gICAgICAgIHRoaXMuY29uZmlnLmNsZWFyQ2FjaGUoKTtcbiAgICAgICAgaWYgKGNhbnZhcykge1xuICAgICAgICAgICAgdGhpcy51bmJpbmRFdmVudHMoKTtcbiAgICAgICAgICAgIGNsZWFyQ2FudmFzKGNhbnZhcywgY3R4KTtcbiAgICAgICAgICAgIHRoaXMucGxhdGZvcm0ucmVsZWFzZUNvbnRleHQoY3R4KTtcbiAgICAgICAgICAgIHRoaXMuY2FudmFzID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuY3R4ID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBkZWxldGUgaW5zdGFuY2VzW3RoaXMuaWRdO1xuICAgICAgICB0aGlzLm5vdGlmeVBsdWdpbnMoJ2FmdGVyRGVzdHJveScpO1xuICAgIH1cbiAgICB0b0Jhc2U2NEltYWdlKC4uLmFyZ3MpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FudmFzLnRvRGF0YVVSTCguLi5hcmdzKTtcbiAgICB9XG4gYmluZEV2ZW50cygpIHtcbiAgICAgICAgdGhpcy5iaW5kVXNlckV2ZW50cygpO1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnJlc3BvbnNpdmUpIHtcbiAgICAgICAgICAgIHRoaXMuYmluZFJlc3BvbnNpdmVFdmVudHMoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuYXR0YWNoZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuIGJpbmRVc2VyRXZlbnRzKCkge1xuICAgICAgICBjb25zdCBsaXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnM7XG4gICAgICAgIGNvbnN0IHBsYXRmb3JtID0gdGhpcy5wbGF0Zm9ybTtcbiAgICAgICAgY29uc3QgX2FkZCA9ICh0eXBlLCBsaXN0ZW5lcik9PntcbiAgICAgICAgICAgIHBsYXRmb3JtLmFkZEV2ZW50TGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIpO1xuICAgICAgICAgICAgbGlzdGVuZXJzW3R5cGVdID0gbGlzdGVuZXI7XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGxpc3RlbmVyID0gKGUsIHgsIHkpPT57XG4gICAgICAgICAgICBlLm9mZnNldFggPSB4O1xuICAgICAgICAgICAgZS5vZmZzZXRZID0geTtcbiAgICAgICAgICAgIHRoaXMuX2V2ZW50SGFuZGxlcihlKTtcbiAgICAgICAgfTtcbiAgICAgICAgZWFjaCh0aGlzLm9wdGlvbnMuZXZlbnRzLCAodHlwZSk9Pl9hZGQodHlwZSwgbGlzdGVuZXIpKTtcbiAgICB9XG4gYmluZFJlc3BvbnNpdmVFdmVudHMoKSB7XG4gICAgICAgIGlmICghdGhpcy5fcmVzcG9uc2l2ZUxpc3RlbmVycykge1xuICAgICAgICAgICAgdGhpcy5fcmVzcG9uc2l2ZUxpc3RlbmVycyA9IHt9O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGxpc3RlbmVycyA9IHRoaXMuX3Jlc3BvbnNpdmVMaXN0ZW5lcnM7XG4gICAgICAgIGNvbnN0IHBsYXRmb3JtID0gdGhpcy5wbGF0Zm9ybTtcbiAgICAgICAgY29uc3QgX2FkZCA9ICh0eXBlLCBsaXN0ZW5lcik9PntcbiAgICAgICAgICAgIHBsYXRmb3JtLmFkZEV2ZW50TGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIpO1xuICAgICAgICAgICAgbGlzdGVuZXJzW3R5cGVdID0gbGlzdGVuZXI7XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IF9yZW1vdmUgPSAodHlwZSwgbGlzdGVuZXIpPT57XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzW3R5cGVdKSB7XG4gICAgICAgICAgICAgICAgcGxhdGZvcm0ucmVtb3ZlRXZlbnRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgZGVsZXRlIGxpc3RlbmVyc1t0eXBlXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgbGlzdGVuZXIgPSAod2lkdGgsIGhlaWdodCk9PntcbiAgICAgICAgICAgIGlmICh0aGlzLmNhbnZhcykge1xuICAgICAgICAgICAgICAgIHRoaXMucmVzaXplKHdpZHRoLCBoZWlnaHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBsZXQgZGV0YWNoZWQ7XG4gICAgICAgIGNvbnN0IGF0dGFjaGVkID0gKCk9PntcbiAgICAgICAgICAgIF9yZW1vdmUoJ2F0dGFjaCcsIGF0dGFjaGVkKTtcbiAgICAgICAgICAgIHRoaXMuYXR0YWNoZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5yZXNpemUoKTtcbiAgICAgICAgICAgIF9hZGQoJ3Jlc2l6ZScsIGxpc3RlbmVyKTtcbiAgICAgICAgICAgIF9hZGQoJ2RldGFjaCcsIGRldGFjaGVkKTtcbiAgICAgICAgfTtcbiAgICAgICAgZGV0YWNoZWQgPSAoKT0+e1xuICAgICAgICAgICAgdGhpcy5hdHRhY2hlZCA9IGZhbHNlO1xuICAgICAgICAgICAgX3JlbW92ZSgncmVzaXplJywgbGlzdGVuZXIpO1xuICAgICAgICAgICAgdGhpcy5fc3RvcCgpO1xuICAgICAgICAgICAgdGhpcy5fcmVzaXplKDAsIDApO1xuICAgICAgICAgICAgX2FkZCgnYXR0YWNoJywgYXR0YWNoZWQpO1xuICAgICAgICB9O1xuICAgICAgICBpZiAocGxhdGZvcm0uaXNBdHRhY2hlZCh0aGlzLmNhbnZhcykpIHtcbiAgICAgICAgICAgIGF0dGFjaGVkKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkZXRhY2hlZCgpO1xuICAgICAgICB9XG4gICAgfVxuIHVuYmluZEV2ZW50cygpIHtcbiAgICAgICAgZWFjaCh0aGlzLl9saXN0ZW5lcnMsIChsaXN0ZW5lciwgdHlwZSk9PntcbiAgICAgICAgICAgIHRoaXMucGxhdGZvcm0ucmVtb3ZlRXZlbnRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lcik7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9saXN0ZW5lcnMgPSB7fTtcbiAgICAgICAgZWFjaCh0aGlzLl9yZXNwb25zaXZlTGlzdGVuZXJzLCAobGlzdGVuZXIsIHR5cGUpPT57XG4gICAgICAgICAgICB0aGlzLnBsYXRmb3JtLnJlbW92ZUV2ZW50TGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcmVzcG9uc2l2ZUxpc3RlbmVycyA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgdXBkYXRlSG92ZXJTdHlsZShpdGVtcywgbW9kZSwgZW5hYmxlZCkge1xuICAgICAgICBjb25zdCBwcmVmaXggPSBlbmFibGVkID8gJ3NldCcgOiAncmVtb3ZlJztcbiAgICAgICAgbGV0IG1ldGEsIGl0ZW0sIGksIGlsZW47XG4gICAgICAgIGlmIChtb2RlID09PSAnZGF0YXNldCcpIHtcbiAgICAgICAgICAgIG1ldGEgPSB0aGlzLmdldERhdGFzZXRNZXRhKGl0ZW1zWzBdLmRhdGFzZXRJbmRleCk7XG4gICAgICAgICAgICBtZXRhLmNvbnRyb2xsZXJbJ18nICsgcHJlZml4ICsgJ0RhdGFzZXRIb3ZlclN0eWxlJ10oKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IoaSA9IDAsIGlsZW4gPSBpdGVtcy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpe1xuICAgICAgICAgICAgaXRlbSA9IGl0ZW1zW2ldO1xuICAgICAgICAgICAgY29uc3QgY29udHJvbGxlciA9IGl0ZW0gJiYgdGhpcy5nZXREYXRhc2V0TWV0YShpdGVtLmRhdGFzZXRJbmRleCkuY29udHJvbGxlcjtcbiAgICAgICAgICAgIGlmIChjb250cm9sbGVyKSB7XG4gICAgICAgICAgICAgICAgY29udHJvbGxlcltwcmVmaXggKyAnSG92ZXJTdHlsZSddKGl0ZW0uZWxlbWVudCwgaXRlbS5kYXRhc2V0SW5kZXgsIGl0ZW0uaW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuIGdldEFjdGl2ZUVsZW1lbnRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWN0aXZlIHx8IFtdO1xuICAgIH1cbiBzZXRBY3RpdmVFbGVtZW50cyhhY3RpdmVFbGVtZW50cykge1xuICAgICAgICBjb25zdCBsYXN0QWN0aXZlID0gdGhpcy5fYWN0aXZlIHx8IFtdO1xuICAgICAgICBjb25zdCBhY3RpdmUgPSBhY3RpdmVFbGVtZW50cy5tYXAoKHsgZGF0YXNldEluZGV4ICwgaW5kZXggIH0pPT57XG4gICAgICAgICAgICBjb25zdCBtZXRhID0gdGhpcy5nZXREYXRhc2V0TWV0YShkYXRhc2V0SW5kZXgpO1xuICAgICAgICAgICAgaWYgKCFtZXRhKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBkYXRhc2V0IGZvdW5kIGF0IGluZGV4ICcgKyBkYXRhc2V0SW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBkYXRhc2V0SW5kZXgsXG4gICAgICAgICAgICAgICAgZWxlbWVudDogbWV0YS5kYXRhW2luZGV4XSxcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGNoYW5nZWQgPSAhX2VsZW1lbnRzRXF1YWwoYWN0aXZlLCBsYXN0QWN0aXZlKTtcbiAgICAgICAgaWYgKGNoYW5nZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX2FjdGl2ZSA9IGFjdGl2ZTtcbiAgICAgICAgICAgIHRoaXMuX2xhc3RFdmVudCA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLl91cGRhdGVIb3ZlclN0eWxlcyhhY3RpdmUsIGxhc3RBY3RpdmUpO1xuICAgICAgICB9XG4gICAgfVxuIG5vdGlmeVBsdWdpbnMoaG9vaywgYXJncywgZmlsdGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wbHVnaW5zLm5vdGlmeSh0aGlzLCBob29rLCBhcmdzLCBmaWx0ZXIpO1xuICAgIH1cbiBpc1BsdWdpbkVuYWJsZWQocGx1Z2luSWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BsdWdpbnMuX2NhY2hlLmZpbHRlcigocCk9PnAucGx1Z2luLmlkID09PSBwbHVnaW5JZCkubGVuZ3RoID09PSAxO1xuICAgIH1cbiBfdXBkYXRlSG92ZXJTdHlsZXMoYWN0aXZlLCBsYXN0QWN0aXZlLCByZXBsYXkpIHtcbiAgICAgICAgY29uc3QgaG92ZXJPcHRpb25zID0gdGhpcy5vcHRpb25zLmhvdmVyO1xuICAgICAgICBjb25zdCBkaWZmID0gKGEsIGIpPT5hLmZpbHRlcigoeCk9PiFiLnNvbWUoKHkpPT54LmRhdGFzZXRJbmRleCA9PT0geS5kYXRhc2V0SW5kZXggJiYgeC5pbmRleCA9PT0geS5pbmRleCkpO1xuICAgICAgICBjb25zdCBkZWFjdGl2YXRlZCA9IGRpZmYobGFzdEFjdGl2ZSwgYWN0aXZlKTtcbiAgICAgICAgY29uc3QgYWN0aXZhdGVkID0gcmVwbGF5ID8gYWN0aXZlIDogZGlmZihhY3RpdmUsIGxhc3RBY3RpdmUpO1xuICAgICAgICBpZiAoZGVhY3RpdmF0ZWQubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUhvdmVyU3R5bGUoZGVhY3RpdmF0ZWQsIGhvdmVyT3B0aW9ucy5tb2RlLCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFjdGl2YXRlZC5sZW5ndGggJiYgaG92ZXJPcHRpb25zLm1vZGUpIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlSG92ZXJTdHlsZShhY3RpdmF0ZWQsIGhvdmVyT3B0aW9ucy5tb2RlLCB0cnVlKTtcbiAgICAgICAgfVxuICAgIH1cbiBfZXZlbnRIYW5kbGVyKGUsIHJlcGxheSkge1xuICAgICAgICBjb25zdCBhcmdzID0ge1xuICAgICAgICAgICAgZXZlbnQ6IGUsXG4gICAgICAgICAgICByZXBsYXksXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiB0cnVlLFxuICAgICAgICAgICAgaW5DaGFydEFyZWE6IHRoaXMuaXNQb2ludEluQXJlYShlKVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBldmVudEZpbHRlciA9IChwbHVnaW4pPT4ocGx1Z2luLm9wdGlvbnMuZXZlbnRzIHx8IHRoaXMub3B0aW9ucy5ldmVudHMpLmluY2x1ZGVzKGUubmF0aXZlLnR5cGUpO1xuICAgICAgICBpZiAodGhpcy5ub3RpZnlQbHVnaW5zKCdiZWZvcmVFdmVudCcsIGFyZ3MsIGV2ZW50RmlsdGVyKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjaGFuZ2VkID0gdGhpcy5faGFuZGxlRXZlbnQoZSwgcmVwbGF5LCBhcmdzLmluQ2hhcnRBcmVhKTtcbiAgICAgICAgYXJncy5jYW5jZWxhYmxlID0gZmFsc2U7XG4gICAgICAgIHRoaXMubm90aWZ5UGx1Z2lucygnYWZ0ZXJFdmVudCcsIGFyZ3MsIGV2ZW50RmlsdGVyKTtcbiAgICAgICAgaWYgKGNoYW5nZWQgfHwgYXJncy5jaGFuZ2VkKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiBfaGFuZGxlRXZlbnQoZSwgcmVwbGF5LCBpbkNoYXJ0QXJlYSkge1xuICAgICAgICBjb25zdCB7IF9hY3RpdmU6IGxhc3RBY3RpdmUgPSBbXSAsIG9wdGlvbnMgIH0gPSB0aGlzO1xuICAgICAgICBjb25zdCB1c2VGaW5hbFBvc2l0aW9uID0gcmVwbGF5O1xuICAgICAgICBjb25zdCBhY3RpdmUgPSB0aGlzLl9nZXRBY3RpdmVFbGVtZW50cyhlLCBsYXN0QWN0aXZlLCBpbkNoYXJ0QXJlYSwgdXNlRmluYWxQb3NpdGlvbik7XG4gICAgICAgIGNvbnN0IGlzQ2xpY2sgPSBfaXNDbGlja0V2ZW50KGUpO1xuICAgICAgICBjb25zdCBsYXN0RXZlbnQgPSBkZXRlcm1pbmVMYXN0RXZlbnQoZSwgdGhpcy5fbGFzdEV2ZW50LCBpbkNoYXJ0QXJlYSwgaXNDbGljayk7XG4gICAgICAgIGlmIChpbkNoYXJ0QXJlYSkge1xuICAgICAgICAgICAgdGhpcy5fbGFzdEV2ZW50ID0gbnVsbDtcbiAgICAgICAgICAgIGNhbGxiYWNrKG9wdGlvbnMub25Ib3ZlciwgW1xuICAgICAgICAgICAgICAgIGUsXG4gICAgICAgICAgICAgICAgYWN0aXZlLFxuICAgICAgICAgICAgICAgIHRoaXNcbiAgICAgICAgICAgIF0sIHRoaXMpO1xuICAgICAgICAgICAgaWYgKGlzQ2xpY2spIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhvcHRpb25zLm9uQ2xpY2ssIFtcbiAgICAgICAgICAgICAgICAgICAgZSxcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB0aGlzXG4gICAgICAgICAgICAgICAgXSwgdGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2hhbmdlZCA9ICFfZWxlbWVudHNFcXVhbChhY3RpdmUsIGxhc3RBY3RpdmUpO1xuICAgICAgICBpZiAoY2hhbmdlZCB8fCByZXBsYXkpIHtcbiAgICAgICAgICAgIHRoaXMuX2FjdGl2ZSA9IGFjdGl2ZTtcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUhvdmVyU3R5bGVzKGFjdGl2ZSwgbGFzdEFjdGl2ZSwgcmVwbGF5KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9sYXN0RXZlbnQgPSBsYXN0RXZlbnQ7XG4gICAgICAgIHJldHVybiBjaGFuZ2VkO1xuICAgIH1cbiBfZ2V0QWN0aXZlRWxlbWVudHMoZSwgbGFzdEFjdGl2ZSwgaW5DaGFydEFyZWEsIHVzZUZpbmFsUG9zaXRpb24pIHtcbiAgICAgICAgaWYgKGUudHlwZSA9PT0gJ21vdXNlb3V0Jykge1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaW5DaGFydEFyZWEpIHtcbiAgICAgICAgICAgIHJldHVybiBsYXN0QWN0aXZlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGhvdmVyT3B0aW9ucyA9IHRoaXMub3B0aW9ucy5ob3ZlcjtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudHNBdEV2ZW50Rm9yTW9kZShlLCBob3Zlck9wdGlvbnMubW9kZSwgaG92ZXJPcHRpb25zLCB1c2VGaW5hbFBvc2l0aW9uKTtcbiAgICB9XG59XG5mdW5jdGlvbiBpbnZhbGlkYXRlUGx1Z2lucygpIHtcbiAgICByZXR1cm4gZWFjaChDaGFydC5pbnN0YW5jZXMsIChjaGFydCk9PmNoYXJ0Ll9wbHVnaW5zLmludmFsaWRhdGUoKSk7XG59XG5cbmZ1bmN0aW9uIGNsaXBBcmMoY3R4LCBlbGVtZW50LCBlbmRBbmdsZSkge1xuICAgIGNvbnN0IHsgc3RhcnRBbmdsZSAsIHBpeGVsTWFyZ2luICwgeCAsIHkgLCBvdXRlclJhZGl1cyAsIGlubmVyUmFkaXVzICB9ID0gZWxlbWVudDtcbiAgICBsZXQgYW5nbGVNYXJnaW4gPSBwaXhlbE1hcmdpbiAvIG91dGVyUmFkaXVzO1xuICAgIC8vIERyYXcgYW4gaW5uZXIgYm9yZGVyIGJ5IGNsaXBwaW5nIHRoZSBhcmMgYW5kIGRyYXdpbmcgYSBkb3VibGUtd2lkdGggYm9yZGVyXG4gICAgLy8gRW5sYXJnZSB0aGUgY2xpcHBpbmcgYXJjIGJ5IDAuMzMgcGl4ZWxzIHRvIGVsaW1pbmF0ZSBnbGl0Y2hlcyBiZXR3ZWVuIGJvcmRlcnNcbiAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgY3R4LmFyYyh4LCB5LCBvdXRlclJhZGl1cywgc3RhcnRBbmdsZSAtIGFuZ2xlTWFyZ2luLCBlbmRBbmdsZSArIGFuZ2xlTWFyZ2luKTtcbiAgICBpZiAoaW5uZXJSYWRpdXMgPiBwaXhlbE1hcmdpbikge1xuICAgICAgICBhbmdsZU1hcmdpbiA9IHBpeGVsTWFyZ2luIC8gaW5uZXJSYWRpdXM7XG4gICAgICAgIGN0eC5hcmMoeCwgeSwgaW5uZXJSYWRpdXMsIGVuZEFuZ2xlICsgYW5nbGVNYXJnaW4sIHN0YXJ0QW5nbGUgLSBhbmdsZU1hcmdpbiwgdHJ1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgY3R4LmFyYyh4LCB5LCBwaXhlbE1hcmdpbiwgZW5kQW5nbGUgKyBIQUxGX1BJLCBzdGFydEFuZ2xlIC0gSEFMRl9QSSk7XG4gICAgfVxuICAgIGN0eC5jbG9zZVBhdGgoKTtcbiAgICBjdHguY2xpcCgpO1xufVxuZnVuY3Rpb24gdG9SYWRpdXNDb3JuZXJzKHZhbHVlKSB7XG4gICAgcmV0dXJuIF9yZWFkVmFsdWVUb1Byb3BzKHZhbHVlLCBbXG4gICAgICAgICdvdXRlclN0YXJ0JyxcbiAgICAgICAgJ291dGVyRW5kJyxcbiAgICAgICAgJ2lubmVyU3RhcnQnLFxuICAgICAgICAnaW5uZXJFbmQnXG4gICAgXSk7XG59XG4vKipcbiAqIFBhcnNlIGJvcmRlciByYWRpdXMgZnJvbSB0aGUgcHJvdmlkZWQgb3B0aW9uc1xuICovIGZ1bmN0aW9uIHBhcnNlQm9yZGVyUmFkaXVzJDEoYXJjLCBpbm5lclJhZGl1cywgb3V0ZXJSYWRpdXMsIGFuZ2xlRGVsdGEpIHtcbiAgICBjb25zdCBvID0gdG9SYWRpdXNDb3JuZXJzKGFyYy5vcHRpb25zLmJvcmRlclJhZGl1cyk7XG4gICAgY29uc3QgaGFsZlRoaWNrbmVzcyA9IChvdXRlclJhZGl1cyAtIGlubmVyUmFkaXVzKSAvIDI7XG4gICAgY29uc3QgaW5uZXJMaW1pdCA9IE1hdGgubWluKGhhbGZUaGlja25lc3MsIGFuZ2xlRGVsdGEgKiBpbm5lclJhZGl1cyAvIDIpO1xuICAgIC8vIE91dGVyIGxpbWl0cyBhcmUgY29tcGxpY2F0ZWQuIFdlIHdhbnQgdG8gY29tcHV0ZSB0aGUgYXZhaWxhYmxlIGFuZ3VsYXIgZGlzdGFuY2UgYXRcbiAgICAvLyBhIHJhZGl1cyBvZiBvdXRlclJhZGl1cyAtIGJvcmRlclJhZGl1cyBiZWNhdXNlIGZvciBzbWFsbCBhbmd1bGFyIGRpc3RhbmNlcywgdGhpcyB0ZXJtIGxpbWl0cy5cbiAgICAvLyBXZSBjb21wdXRlIGF0IHIgPSBvdXRlclJhZGl1cyAtIGJvcmRlclJhZGl1cyBiZWNhdXNlIHRoaXMgY2lyY2xlIGRlZmluZXMgdGhlIGNlbnRlciBvZiB0aGUgYm9yZGVyIGNvcm5lcnMuXG4gICAgLy9cbiAgICAvLyBJZiB0aGUgYm9yZGVyUmFkaXVzIGlzIGxhcmdlLCB0aGF0IHZhbHVlIGNhbiBiZWNvbWUgbmVnYXRpdmUuXG4gICAgLy8gVGhpcyBjYXVzZXMgdGhlIG91dGVyIGJvcmRlcnMgdG8gbG9zZSB0aGVpciByYWRpdXMgZW50aXJlbHksIHdoaWNoIGlzIHJhdGhlciB1bmV4cGVjdGVkLiBUbyBzb2x2ZSB0aGF0LCBpZiBib3JkZXJSYWRpdXMgPiBvdXRlclJhZGl1c1xuICAgIC8vIHdlIGtub3cgdGhhdCB0aGUgdGhpY2tuZXNzIHRlcm0gd2lsbCBkb21pbmF0ZSBhbmQgY29tcHV0ZSB0aGUgbGltaXRzIGF0IHRoYXQgcG9pbnRcbiAgICBjb25zdCBjb21wdXRlT3V0ZXJMaW1pdCA9ICh2YWwpPT57XG4gICAgICAgIGNvbnN0IG91dGVyQXJjTGltaXQgPSAob3V0ZXJSYWRpdXMgLSBNYXRoLm1pbihoYWxmVGhpY2tuZXNzLCB2YWwpKSAqIGFuZ2xlRGVsdGEgLyAyO1xuICAgICAgICByZXR1cm4gX2xpbWl0VmFsdWUodmFsLCAwLCBNYXRoLm1pbihoYWxmVGhpY2tuZXNzLCBvdXRlckFyY0xpbWl0KSk7XG4gICAgfTtcbiAgICByZXR1cm4ge1xuICAgICAgICBvdXRlclN0YXJ0OiBjb21wdXRlT3V0ZXJMaW1pdChvLm91dGVyU3RhcnQpLFxuICAgICAgICBvdXRlckVuZDogY29tcHV0ZU91dGVyTGltaXQoby5vdXRlckVuZCksXG4gICAgICAgIGlubmVyU3RhcnQ6IF9saW1pdFZhbHVlKG8uaW5uZXJTdGFydCwgMCwgaW5uZXJMaW1pdCksXG4gICAgICAgIGlubmVyRW5kOiBfbGltaXRWYWx1ZShvLmlubmVyRW5kLCAwLCBpbm5lckxpbWl0KVxuICAgIH07XG59XG4vKipcbiAqIENvbnZlcnQgKHIsIPCdnIMpIHRvICh4LCB5KVxuICovIGZ1bmN0aW9uIHJUaGV0YVRvWFkociwgdGhldGEsIHgsIHkpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICB4OiB4ICsgciAqIE1hdGguY29zKHRoZXRhKSxcbiAgICAgICAgeTogeSArIHIgKiBNYXRoLnNpbih0aGV0YSlcbiAgICB9O1xufVxuLyoqXG4gKiBQYXRoIHRoZSBhcmMsIHJlc3BlY3RpbmcgYm9yZGVyIHJhZGl1cyBieSBzZXBhcmF0aW5nIGludG8gbGVmdCBhbmQgcmlnaHQgaGFsdmVzLlxuICpcbiAqICAgU3RhcnQgICAgICBFbmRcbiAqXG4gKiAgICAxLS0tPmEtLS0+MiAgICBPdXRlclxuICogICAvICAgICAgICAgICBcXFxuICogICA4ICAgICAgICAgICAzXG4gKiAgIHwgICAgICAgICAgIHxcbiAqICAgfCAgICAgICAgICAgfFxuICogICA3ICAgICAgICAgICA0XG4gKiAgIFxcICAgICAgICAgICAvXG4gKiAgICA2PC0tLWI8LS0tNSAgICBJbm5lclxuICovIGZ1bmN0aW9uIHBhdGhBcmMoY3R4LCBlbGVtZW50LCBvZmZzZXQsIHNwYWNpbmcsIGVuZCwgY2lyY3VsYXIpIHtcbiAgICBjb25zdCB7IHggLCB5ICwgc3RhcnRBbmdsZTogc3RhcnQgLCBwaXhlbE1hcmdpbiAsIGlubmVyUmFkaXVzOiBpbm5lclIgIH0gPSBlbGVtZW50O1xuICAgIGNvbnN0IG91dGVyUmFkaXVzID0gTWF0aC5tYXgoZWxlbWVudC5vdXRlclJhZGl1cyArIHNwYWNpbmcgKyBvZmZzZXQgLSBwaXhlbE1hcmdpbiwgMCk7XG4gICAgY29uc3QgaW5uZXJSYWRpdXMgPSBpbm5lclIgPiAwID8gaW5uZXJSICsgc3BhY2luZyArIG9mZnNldCArIHBpeGVsTWFyZ2luIDogMDtcbiAgICBsZXQgc3BhY2luZ09mZnNldCA9IDA7XG4gICAgY29uc3QgYWxwaGEgPSBlbmQgLSBzdGFydDtcbiAgICBpZiAoc3BhY2luZykge1xuICAgICAgICAvLyBXaGVuIHNwYWNpbmcgaXMgcHJlc2VudCwgaXQgaXMgdGhlIHNhbWUgZm9yIGFsbCBpdGVtc1xuICAgICAgICAvLyBTbyB3ZSBhZGp1c3QgdGhlIHN0YXJ0IGFuZCBlbmQgYW5nbGUgb2YgdGhlIGFyYyBzdWNoIHRoYXRcbiAgICAgICAgLy8gdGhlIGRpc3RhbmNlIGlzIHRoZSBzYW1lIGFzIGl0IHdvdWxkIGJlIHdpdGhvdXQgdGhlIHNwYWNpbmdcbiAgICAgICAgY29uc3Qgbm9TcGFjaW5nSW5uZXJSYWRpdXMgPSBpbm5lclIgPiAwID8gaW5uZXJSIC0gc3BhY2luZyA6IDA7XG4gICAgICAgIGNvbnN0IG5vU3BhY2luZ091dGVyUmFkaXVzID0gb3V0ZXJSYWRpdXMgPiAwID8gb3V0ZXJSYWRpdXMgLSBzcGFjaW5nIDogMDtcbiAgICAgICAgY29uc3QgYXZOb2dTcGFjaW5nUmFkaXVzID0gKG5vU3BhY2luZ0lubmVyUmFkaXVzICsgbm9TcGFjaW5nT3V0ZXJSYWRpdXMpIC8gMjtcbiAgICAgICAgY29uc3QgYWRqdXN0ZWRBbmdsZSA9IGF2Tm9nU3BhY2luZ1JhZGl1cyAhPT0gMCA/IGFscGhhICogYXZOb2dTcGFjaW5nUmFkaXVzIC8gKGF2Tm9nU3BhY2luZ1JhZGl1cyArIHNwYWNpbmcpIDogYWxwaGE7XG4gICAgICAgIHNwYWNpbmdPZmZzZXQgPSAoYWxwaGEgLSBhZGp1c3RlZEFuZ2xlKSAvIDI7XG4gICAgfVxuICAgIGNvbnN0IGJldGEgPSBNYXRoLm1heCgwLjAwMSwgYWxwaGEgKiBvdXRlclJhZGl1cyAtIG9mZnNldCAvIFBJKSAvIG91dGVyUmFkaXVzO1xuICAgIGNvbnN0IGFuZ2xlT2Zmc2V0ID0gKGFscGhhIC0gYmV0YSkgLyAyO1xuICAgIGNvbnN0IHN0YXJ0QW5nbGUgPSBzdGFydCArIGFuZ2xlT2Zmc2V0ICsgc3BhY2luZ09mZnNldDtcbiAgICBjb25zdCBlbmRBbmdsZSA9IGVuZCAtIGFuZ2xlT2Zmc2V0IC0gc3BhY2luZ09mZnNldDtcbiAgICBjb25zdCB7IG91dGVyU3RhcnQgLCBvdXRlckVuZCAsIGlubmVyU3RhcnQgLCBpbm5lckVuZCAgfSA9IHBhcnNlQm9yZGVyUmFkaXVzJDEoZWxlbWVudCwgaW5uZXJSYWRpdXMsIG91dGVyUmFkaXVzLCBlbmRBbmdsZSAtIHN0YXJ0QW5nbGUpO1xuICAgIGNvbnN0IG91dGVyU3RhcnRBZGp1c3RlZFJhZGl1cyA9IG91dGVyUmFkaXVzIC0gb3V0ZXJTdGFydDtcbiAgICBjb25zdCBvdXRlckVuZEFkanVzdGVkUmFkaXVzID0gb3V0ZXJSYWRpdXMgLSBvdXRlckVuZDtcbiAgICBjb25zdCBvdXRlclN0YXJ0QWRqdXN0ZWRBbmdsZSA9IHN0YXJ0QW5nbGUgKyBvdXRlclN0YXJ0IC8gb3V0ZXJTdGFydEFkanVzdGVkUmFkaXVzO1xuICAgIGNvbnN0IG91dGVyRW5kQWRqdXN0ZWRBbmdsZSA9IGVuZEFuZ2xlIC0gb3V0ZXJFbmQgLyBvdXRlckVuZEFkanVzdGVkUmFkaXVzO1xuICAgIGNvbnN0IGlubmVyU3RhcnRBZGp1c3RlZFJhZGl1cyA9IGlubmVyUmFkaXVzICsgaW5uZXJTdGFydDtcbiAgICBjb25zdCBpbm5lckVuZEFkanVzdGVkUmFkaXVzID0gaW5uZXJSYWRpdXMgKyBpbm5lckVuZDtcbiAgICBjb25zdCBpbm5lclN0YXJ0QWRqdXN0ZWRBbmdsZSA9IHN0YXJ0QW5nbGUgKyBpbm5lclN0YXJ0IC8gaW5uZXJTdGFydEFkanVzdGVkUmFkaXVzO1xuICAgIGNvbnN0IGlubmVyRW5kQWRqdXN0ZWRBbmdsZSA9IGVuZEFuZ2xlIC0gaW5uZXJFbmQgLyBpbm5lckVuZEFkanVzdGVkUmFkaXVzO1xuICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICBpZiAoY2lyY3VsYXIpIHtcbiAgICAgICAgLy8gVGhlIGZpcnN0IGFyYyBzZWdtZW50cyBmcm9tIHBvaW50IDEgdG8gcG9pbnQgYSB0byBwb2ludCAyXG4gICAgICAgIGNvbnN0IG91dGVyTWlkQWRqdXN0ZWRBbmdsZSA9IChvdXRlclN0YXJ0QWRqdXN0ZWRBbmdsZSArIG91dGVyRW5kQWRqdXN0ZWRBbmdsZSkgLyAyO1xuICAgICAgICBjdHguYXJjKHgsIHksIG91dGVyUmFkaXVzLCBvdXRlclN0YXJ0QWRqdXN0ZWRBbmdsZSwgb3V0ZXJNaWRBZGp1c3RlZEFuZ2xlKTtcbiAgICAgICAgY3R4LmFyYyh4LCB5LCBvdXRlclJhZGl1cywgb3V0ZXJNaWRBZGp1c3RlZEFuZ2xlLCBvdXRlckVuZEFkanVzdGVkQW5nbGUpO1xuICAgICAgICAvLyBUaGUgY29ybmVyIHNlZ21lbnQgZnJvbSBwb2ludCAyIHRvIHBvaW50IDNcbiAgICAgICAgaWYgKG91dGVyRW5kID4gMCkge1xuICAgICAgICAgICAgY29uc3QgcENlbnRlciA9IHJUaGV0YVRvWFkob3V0ZXJFbmRBZGp1c3RlZFJhZGl1cywgb3V0ZXJFbmRBZGp1c3RlZEFuZ2xlLCB4LCB5KTtcbiAgICAgICAgICAgIGN0eC5hcmMocENlbnRlci54LCBwQ2VudGVyLnksIG91dGVyRW5kLCBvdXRlckVuZEFkanVzdGVkQW5nbGUsIGVuZEFuZ2xlICsgSEFMRl9QSSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gVGhlIGxpbmUgZnJvbSBwb2ludCAzIHRvIHBvaW50IDRcbiAgICAgICAgY29uc3QgcDQgPSByVGhldGFUb1hZKGlubmVyRW5kQWRqdXN0ZWRSYWRpdXMsIGVuZEFuZ2xlLCB4LCB5KTtcbiAgICAgICAgY3R4LmxpbmVUbyhwNC54LCBwNC55KTtcbiAgICAgICAgLy8gVGhlIGNvcm5lciBzZWdtZW50IGZyb20gcG9pbnQgNCB0byBwb2ludCA1XG4gICAgICAgIGlmIChpbm5lckVuZCA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IHBDZW50ZXIgPSByVGhldGFUb1hZKGlubmVyRW5kQWRqdXN0ZWRSYWRpdXMsIGlubmVyRW5kQWRqdXN0ZWRBbmdsZSwgeCwgeSk7XG4gICAgICAgICAgICBjdHguYXJjKHBDZW50ZXIueCwgcENlbnRlci55LCBpbm5lckVuZCwgZW5kQW5nbGUgKyBIQUxGX1BJLCBpbm5lckVuZEFkanVzdGVkQW5nbGUgKyBNYXRoLlBJKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBUaGUgaW5uZXIgYXJjIGZyb20gcG9pbnQgNSB0byBwb2ludCBiIHRvIHBvaW50IDZcbiAgICAgICAgY29uc3QgaW5uZXJNaWRBZGp1c3RlZEFuZ2xlID0gKGVuZEFuZ2xlIC0gaW5uZXJFbmQgLyBpbm5lclJhZGl1cyArIChzdGFydEFuZ2xlICsgaW5uZXJTdGFydCAvIGlubmVyUmFkaXVzKSkgLyAyO1xuICAgICAgICBjdHguYXJjKHgsIHksIGlubmVyUmFkaXVzLCBlbmRBbmdsZSAtIGlubmVyRW5kIC8gaW5uZXJSYWRpdXMsIGlubmVyTWlkQWRqdXN0ZWRBbmdsZSwgdHJ1ZSk7XG4gICAgICAgIGN0eC5hcmMoeCwgeSwgaW5uZXJSYWRpdXMsIGlubmVyTWlkQWRqdXN0ZWRBbmdsZSwgc3RhcnRBbmdsZSArIGlubmVyU3RhcnQgLyBpbm5lclJhZGl1cywgdHJ1ZSk7XG4gICAgICAgIC8vIFRoZSBjb3JuZXIgc2VnbWVudCBmcm9tIHBvaW50IDYgdG8gcG9pbnQgN1xuICAgICAgICBpZiAoaW5uZXJTdGFydCA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IHBDZW50ZXIgPSByVGhldGFUb1hZKGlubmVyU3RhcnRBZGp1c3RlZFJhZGl1cywgaW5uZXJTdGFydEFkanVzdGVkQW5nbGUsIHgsIHkpO1xuICAgICAgICAgICAgY3R4LmFyYyhwQ2VudGVyLngsIHBDZW50ZXIueSwgaW5uZXJTdGFydCwgaW5uZXJTdGFydEFkanVzdGVkQW5nbGUgKyBNYXRoLlBJLCBzdGFydEFuZ2xlIC0gSEFMRl9QSSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gVGhlIGxpbmUgZnJvbSBwb2ludCA3IHRvIHBvaW50IDhcbiAgICAgICAgY29uc3QgcDggPSByVGhldGFUb1hZKG91dGVyU3RhcnRBZGp1c3RlZFJhZGl1cywgc3RhcnRBbmdsZSwgeCwgeSk7XG4gICAgICAgIGN0eC5saW5lVG8ocDgueCwgcDgueSk7XG4gICAgICAgIC8vIFRoZSBjb3JuZXIgc2VnbWVudCBmcm9tIHBvaW50IDggdG8gcG9pbnQgMVxuICAgICAgICBpZiAob3V0ZXJTdGFydCA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IHBDZW50ZXIgPSByVGhldGFUb1hZKG91dGVyU3RhcnRBZGp1c3RlZFJhZGl1cywgb3V0ZXJTdGFydEFkanVzdGVkQW5nbGUsIHgsIHkpO1xuICAgICAgICAgICAgY3R4LmFyYyhwQ2VudGVyLngsIHBDZW50ZXIueSwgb3V0ZXJTdGFydCwgc3RhcnRBbmdsZSAtIEhBTEZfUEksIG91dGVyU3RhcnRBZGp1c3RlZEFuZ2xlKTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIGN0eC5tb3ZlVG8oeCwgeSk7XG4gICAgICAgIGNvbnN0IG91dGVyU3RhcnRYID0gTWF0aC5jb3Mob3V0ZXJTdGFydEFkanVzdGVkQW5nbGUpICogb3V0ZXJSYWRpdXMgKyB4O1xuICAgICAgICBjb25zdCBvdXRlclN0YXJ0WSA9IE1hdGguc2luKG91dGVyU3RhcnRBZGp1c3RlZEFuZ2xlKSAqIG91dGVyUmFkaXVzICsgeTtcbiAgICAgICAgY3R4LmxpbmVUbyhvdXRlclN0YXJ0WCwgb3V0ZXJTdGFydFkpO1xuICAgICAgICBjb25zdCBvdXRlckVuZFggPSBNYXRoLmNvcyhvdXRlckVuZEFkanVzdGVkQW5nbGUpICogb3V0ZXJSYWRpdXMgKyB4O1xuICAgICAgICBjb25zdCBvdXRlckVuZFkgPSBNYXRoLnNpbihvdXRlckVuZEFkanVzdGVkQW5nbGUpICogb3V0ZXJSYWRpdXMgKyB5O1xuICAgICAgICBjdHgubGluZVRvKG91dGVyRW5kWCwgb3V0ZXJFbmRZKTtcbiAgICB9XG4gICAgY3R4LmNsb3NlUGF0aCgpO1xufVxuZnVuY3Rpb24gZHJhd0FyYyhjdHgsIGVsZW1lbnQsIG9mZnNldCwgc3BhY2luZywgY2lyY3VsYXIpIHtcbiAgICBjb25zdCB7IGZ1bGxDaXJjbGVzICwgc3RhcnRBbmdsZSAsIGNpcmN1bWZlcmVuY2UgIH0gPSBlbGVtZW50O1xuICAgIGxldCBlbmRBbmdsZSA9IGVsZW1lbnQuZW5kQW5nbGU7XG4gICAgaWYgKGZ1bGxDaXJjbGVzKSB7XG4gICAgICAgIHBhdGhBcmMoY3R4LCBlbGVtZW50LCBvZmZzZXQsIHNwYWNpbmcsIGVuZEFuZ2xlLCBjaXJjdWxhcik7XG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBmdWxsQ2lyY2xlczsgKytpKXtcbiAgICAgICAgICAgIGN0eC5maWxsKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc05hTihjaXJjdW1mZXJlbmNlKSkge1xuICAgICAgICAgICAgZW5kQW5nbGUgPSBzdGFydEFuZ2xlICsgKGNpcmN1bWZlcmVuY2UgJSBUQVUgfHwgVEFVKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBwYXRoQXJjKGN0eCwgZWxlbWVudCwgb2Zmc2V0LCBzcGFjaW5nLCBlbmRBbmdsZSwgY2lyY3VsYXIpO1xuICAgIGN0eC5maWxsKCk7XG4gICAgcmV0dXJuIGVuZEFuZ2xlO1xufVxuZnVuY3Rpb24gZHJhd0JvcmRlcihjdHgsIGVsZW1lbnQsIG9mZnNldCwgc3BhY2luZywgY2lyY3VsYXIpIHtcbiAgICBjb25zdCB7IGZ1bGxDaXJjbGVzICwgc3RhcnRBbmdsZSAsIGNpcmN1bWZlcmVuY2UgLCBvcHRpb25zICB9ID0gZWxlbWVudDtcbiAgICBjb25zdCB7IGJvcmRlcldpZHRoICwgYm9yZGVySm9pblN0eWxlICwgYm9yZGVyRGFzaCAsIGJvcmRlckRhc2hPZmZzZXQgIH0gPSBvcHRpb25zO1xuICAgIGNvbnN0IGlubmVyID0gb3B0aW9ucy5ib3JkZXJBbGlnbiA9PT0gJ2lubmVyJztcbiAgICBpZiAoIWJvcmRlcldpZHRoKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY3R4LnNldExpbmVEYXNoKGJvcmRlckRhc2ggfHwgW10pO1xuICAgIGN0eC5saW5lRGFzaE9mZnNldCA9IGJvcmRlckRhc2hPZmZzZXQ7XG4gICAgaWYgKGlubmVyKSB7XG4gICAgICAgIGN0eC5saW5lV2lkdGggPSBib3JkZXJXaWR0aCAqIDI7XG4gICAgICAgIGN0eC5saW5lSm9pbiA9IGJvcmRlckpvaW5TdHlsZSB8fCAncm91bmQnO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGN0eC5saW5lV2lkdGggPSBib3JkZXJXaWR0aDtcbiAgICAgICAgY3R4LmxpbmVKb2luID0gYm9yZGVySm9pblN0eWxlIHx8ICdiZXZlbCc7XG4gICAgfVxuICAgIGxldCBlbmRBbmdsZSA9IGVsZW1lbnQuZW5kQW5nbGU7XG4gICAgaWYgKGZ1bGxDaXJjbGVzKSB7XG4gICAgICAgIHBhdGhBcmMoY3R4LCBlbGVtZW50LCBvZmZzZXQsIHNwYWNpbmcsIGVuZEFuZ2xlLCBjaXJjdWxhcik7XG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBmdWxsQ2lyY2xlczsgKytpKXtcbiAgICAgICAgICAgIGN0eC5zdHJva2UoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzTmFOKGNpcmN1bWZlcmVuY2UpKSB7XG4gICAgICAgICAgICBlbmRBbmdsZSA9IHN0YXJ0QW5nbGUgKyAoY2lyY3VtZmVyZW5jZSAlIFRBVSB8fCBUQVUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChpbm5lcikge1xuICAgICAgICBjbGlwQXJjKGN0eCwgZWxlbWVudCwgZW5kQW5nbGUpO1xuICAgIH1cbiAgICBpZiAoIWZ1bGxDaXJjbGVzKSB7XG4gICAgICAgIHBhdGhBcmMoY3R4LCBlbGVtZW50LCBvZmZzZXQsIHNwYWNpbmcsIGVuZEFuZ2xlLCBjaXJjdWxhcik7XG4gICAgICAgIGN0eC5zdHJva2UoKTtcbiAgICB9XG59XG5jbGFzcyBBcmNFbGVtZW50IGV4dGVuZHMgRWxlbWVudCB7XG4gICAgc3RhdGljIGlkID0gJ2FyYyc7XG4gICAgc3RhdGljIGRlZmF1bHRzID0ge1xuICAgICAgICBib3JkZXJBbGlnbjogJ2NlbnRlcicsXG4gICAgICAgIGJvcmRlckNvbG9yOiAnI2ZmZicsXG4gICAgICAgIGJvcmRlckRhc2g6IFtdLFxuICAgICAgICBib3JkZXJEYXNoT2Zmc2V0OiAwLFxuICAgICAgICBib3JkZXJKb2luU3R5bGU6IHVuZGVmaW5lZCxcbiAgICAgICAgYm9yZGVyUmFkaXVzOiAwLFxuICAgICAgICBib3JkZXJXaWR0aDogMixcbiAgICAgICAgb2Zmc2V0OiAwLFxuICAgICAgICBzcGFjaW5nOiAwLFxuICAgICAgICBhbmdsZTogdW5kZWZpbmVkLFxuICAgICAgICBjaXJjdWxhcjogdHJ1ZVxuICAgIH07XG4gICAgc3RhdGljIGRlZmF1bHRSb3V0ZXMgPSB7XG4gICAgICAgIGJhY2tncm91bmRDb2xvcjogJ2JhY2tncm91bmRDb2xvcidcbiAgICB9O1xuICAgIHN0YXRpYyBkZXNjcmlwdG9ycyA9IHtcbiAgICAgICAgX3NjcmlwdGFibGU6IHRydWUsXG4gICAgICAgIF9pbmRleGFibGU6IChuYW1lKT0+bmFtZSAhPT0gJ2JvcmRlckRhc2gnXG4gICAgfTtcbiAgICBjaXJjdW1mZXJlbmNlO1xuICAgIGVuZEFuZ2xlO1xuICAgIGZ1bGxDaXJjbGVzO1xuICAgIGlubmVyUmFkaXVzO1xuICAgIG91dGVyUmFkaXVzO1xuICAgIHBpeGVsTWFyZ2luO1xuICAgIHN0YXJ0QW5nbGU7XG4gICAgY29uc3RydWN0b3IoY2ZnKXtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLmNpcmN1bWZlcmVuY2UgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuc3RhcnRBbmdsZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5lbmRBbmdsZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5pbm5lclJhZGl1cyA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5vdXRlclJhZGl1cyA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5waXhlbE1hcmdpbiA9IDA7XG4gICAgICAgIHRoaXMuZnVsbENpcmNsZXMgPSAwO1xuICAgICAgICBpZiAoY2ZnKSB7XG4gICAgICAgICAgICBPYmplY3QuYXNzaWduKHRoaXMsIGNmZyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaW5SYW5nZShjaGFydFgsIGNoYXJ0WSwgdXNlRmluYWxQb3NpdGlvbikge1xuICAgICAgICBjb25zdCBwb2ludCA9IHRoaXMuZ2V0UHJvcHMoW1xuICAgICAgICAgICAgJ3gnLFxuICAgICAgICAgICAgJ3knXG4gICAgICAgIF0sIHVzZUZpbmFsUG9zaXRpb24pO1xuICAgICAgICBjb25zdCB7IGFuZ2xlICwgZGlzdGFuY2UgIH0gPSBnZXRBbmdsZUZyb21Qb2ludChwb2ludCwge1xuICAgICAgICAgICAgeDogY2hhcnRYLFxuICAgICAgICAgICAgeTogY2hhcnRZXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCB7IHN0YXJ0QW5nbGUgLCBlbmRBbmdsZSAsIGlubmVyUmFkaXVzICwgb3V0ZXJSYWRpdXMgLCBjaXJjdW1mZXJlbmNlICB9ID0gdGhpcy5nZXRQcm9wcyhbXG4gICAgICAgICAgICAnc3RhcnRBbmdsZScsXG4gICAgICAgICAgICAnZW5kQW5nbGUnLFxuICAgICAgICAgICAgJ2lubmVyUmFkaXVzJyxcbiAgICAgICAgICAgICdvdXRlclJhZGl1cycsXG4gICAgICAgICAgICAnY2lyY3VtZmVyZW5jZSdcbiAgICAgICAgXSwgdXNlRmluYWxQb3NpdGlvbik7XG4gICAgICAgIGNvbnN0IHJBZGp1c3QgPSAodGhpcy5vcHRpb25zLnNwYWNpbmcgKyB0aGlzLm9wdGlvbnMuYm9yZGVyV2lkdGgpIC8gMjtcbiAgICAgICAgY29uc3QgX2NpcmN1bWZlcmVuY2UgPSB2YWx1ZU9yRGVmYXVsdChjaXJjdW1mZXJlbmNlLCBlbmRBbmdsZSAtIHN0YXJ0QW5nbGUpO1xuICAgICAgICBjb25zdCBub25aZXJvQmV0d2VlbiA9IF9hbmdsZUJldHdlZW4oYW5nbGUsIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlKSAmJiBzdGFydEFuZ2xlICE9PSBlbmRBbmdsZTtcbiAgICAgICAgY29uc3QgYmV0d2VlbkFuZ2xlcyA9IF9jaXJjdW1mZXJlbmNlID49IFRBVSB8fCBub25aZXJvQmV0d2VlbjtcbiAgICAgICAgY29uc3Qgd2l0aGluUmFkaXVzID0gX2lzQmV0d2VlbihkaXN0YW5jZSwgaW5uZXJSYWRpdXMgKyByQWRqdXN0LCBvdXRlclJhZGl1cyArIHJBZGp1c3QpO1xuICAgICAgICByZXR1cm4gYmV0d2VlbkFuZ2xlcyAmJiB3aXRoaW5SYWRpdXM7XG4gICAgfVxuICAgIGdldENlbnRlclBvaW50KHVzZUZpbmFsUG9zaXRpb24pIHtcbiAgICAgICAgY29uc3QgeyB4ICwgeSAsIHN0YXJ0QW5nbGUgLCBlbmRBbmdsZSAsIGlubmVyUmFkaXVzICwgb3V0ZXJSYWRpdXMgIH0gPSB0aGlzLmdldFByb3BzKFtcbiAgICAgICAgICAgICd4JyxcbiAgICAgICAgICAgICd5JyxcbiAgICAgICAgICAgICdzdGFydEFuZ2xlJyxcbiAgICAgICAgICAgICdlbmRBbmdsZScsXG4gICAgICAgICAgICAnaW5uZXJSYWRpdXMnLFxuICAgICAgICAgICAgJ291dGVyUmFkaXVzJ1xuICAgICAgICBdLCB1c2VGaW5hbFBvc2l0aW9uKTtcbiAgICAgICAgY29uc3QgeyBvZmZzZXQgLCBzcGFjaW5nICB9ID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBjb25zdCBoYWxmQW5nbGUgPSAoc3RhcnRBbmdsZSArIGVuZEFuZ2xlKSAvIDI7XG4gICAgICAgIGNvbnN0IGhhbGZSYWRpdXMgPSAoaW5uZXJSYWRpdXMgKyBvdXRlclJhZGl1cyArIHNwYWNpbmcgKyBvZmZzZXQpIC8gMjtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IHggKyBNYXRoLmNvcyhoYWxmQW5nbGUpICogaGFsZlJhZGl1cyxcbiAgICAgICAgICAgIHk6IHkgKyBNYXRoLnNpbihoYWxmQW5nbGUpICogaGFsZlJhZGl1c1xuICAgICAgICB9O1xuICAgIH1cbiAgICB0b29sdGlwUG9zaXRpb24odXNlRmluYWxQb3NpdGlvbikge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRDZW50ZXJQb2ludCh1c2VGaW5hbFBvc2l0aW9uKTtcbiAgICB9XG4gICAgZHJhdyhjdHgpIHtcbiAgICAgICAgY29uc3QgeyBvcHRpb25zICwgY2lyY3VtZmVyZW5jZSAgfSA9IHRoaXM7XG4gICAgICAgIGNvbnN0IG9mZnNldCA9IChvcHRpb25zLm9mZnNldCB8fCAwKSAvIDQ7XG4gICAgICAgIGNvbnN0IHNwYWNpbmcgPSAob3B0aW9ucy5zcGFjaW5nIHx8IDApIC8gMjtcbiAgICAgICAgY29uc3QgY2lyY3VsYXIgPSBvcHRpb25zLmNpcmN1bGFyO1xuICAgICAgICB0aGlzLnBpeGVsTWFyZ2luID0gb3B0aW9ucy5ib3JkZXJBbGlnbiA9PT0gJ2lubmVyJyA/IDAuMzMgOiAwO1xuICAgICAgICB0aGlzLmZ1bGxDaXJjbGVzID0gY2lyY3VtZmVyZW5jZSA+IFRBVSA/IE1hdGguZmxvb3IoY2lyY3VtZmVyZW5jZSAvIFRBVSkgOiAwO1xuICAgICAgICBpZiAoY2lyY3VtZmVyZW5jZSA9PT0gMCB8fCB0aGlzLmlubmVyUmFkaXVzIDwgMCB8fCB0aGlzLm91dGVyUmFkaXVzIDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGN0eC5zYXZlKCk7XG4gICAgICAgIGNvbnN0IGhhbGZBbmdsZSA9ICh0aGlzLnN0YXJ0QW5nbGUgKyB0aGlzLmVuZEFuZ2xlKSAvIDI7XG4gICAgICAgIGN0eC50cmFuc2xhdGUoTWF0aC5jb3MoaGFsZkFuZ2xlKSAqIG9mZnNldCwgTWF0aC5zaW4oaGFsZkFuZ2xlKSAqIG9mZnNldCk7XG4gICAgICAgIGNvbnN0IGZpeCA9IDEgLSBNYXRoLnNpbihNYXRoLm1pbihQSSwgY2lyY3VtZmVyZW5jZSB8fCAwKSk7XG4gICAgICAgIGNvbnN0IHJhZGl1c09mZnNldCA9IG9mZnNldCAqIGZpeDtcbiAgICAgICAgY3R4LmZpbGxTdHlsZSA9IG9wdGlvbnMuYmFja2dyb3VuZENvbG9yO1xuICAgICAgICBjdHguc3Ryb2tlU3R5bGUgPSBvcHRpb25zLmJvcmRlckNvbG9yO1xuICAgICAgICBkcmF3QXJjKGN0eCwgdGhpcywgcmFkaXVzT2Zmc2V0LCBzcGFjaW5nLCBjaXJjdWxhcik7XG4gICAgICAgIGRyYXdCb3JkZXIoY3R4LCB0aGlzLCByYWRpdXNPZmZzZXQsIHNwYWNpbmcsIGNpcmN1bGFyKTtcbiAgICAgICAgY3R4LnJlc3RvcmUoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHNldFN0eWxlKGN0eCwgb3B0aW9ucywgc3R5bGUgPSBvcHRpb25zKSB7XG4gICAgY3R4LmxpbmVDYXAgPSB2YWx1ZU9yRGVmYXVsdChzdHlsZS5ib3JkZXJDYXBTdHlsZSwgb3B0aW9ucy5ib3JkZXJDYXBTdHlsZSk7XG4gICAgY3R4LnNldExpbmVEYXNoKHZhbHVlT3JEZWZhdWx0KHN0eWxlLmJvcmRlckRhc2gsIG9wdGlvbnMuYm9yZGVyRGFzaCkpO1xuICAgIGN0eC5saW5lRGFzaE9mZnNldCA9IHZhbHVlT3JEZWZhdWx0KHN0eWxlLmJvcmRlckRhc2hPZmZzZXQsIG9wdGlvbnMuYm9yZGVyRGFzaE9mZnNldCk7XG4gICAgY3R4LmxpbmVKb2luID0gdmFsdWVPckRlZmF1bHQoc3R5bGUuYm9yZGVySm9pblN0eWxlLCBvcHRpb25zLmJvcmRlckpvaW5TdHlsZSk7XG4gICAgY3R4LmxpbmVXaWR0aCA9IHZhbHVlT3JEZWZhdWx0KHN0eWxlLmJvcmRlcldpZHRoLCBvcHRpb25zLmJvcmRlcldpZHRoKTtcbiAgICBjdHguc3Ryb2tlU3R5bGUgPSB2YWx1ZU9yRGVmYXVsdChzdHlsZS5ib3JkZXJDb2xvciwgb3B0aW9ucy5ib3JkZXJDb2xvcik7XG59XG5mdW5jdGlvbiBsaW5lVG8oY3R4LCBwcmV2aW91cywgdGFyZ2V0KSB7XG4gICAgY3R4LmxpbmVUbyh0YXJnZXQueCwgdGFyZ2V0LnkpO1xufVxuIGZ1bmN0aW9uIGdldExpbmVNZXRob2Qob3B0aW9ucykge1xuICAgIGlmIChvcHRpb25zLnN0ZXBwZWQpIHtcbiAgICAgICAgcmV0dXJuIF9zdGVwcGVkTGluZVRvO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy50ZW5zaW9uIHx8IG9wdGlvbnMuY3ViaWNJbnRlcnBvbGF0aW9uTW9kZSA9PT0gJ21vbm90b25lJykge1xuICAgICAgICByZXR1cm4gX2JlemllckN1cnZlVG87XG4gICAgfVxuICAgIHJldHVybiBsaW5lVG87XG59XG5mdW5jdGlvbiBwYXRoVmFycyhwb2ludHMsIHNlZ21lbnQsIHBhcmFtcyA9IHt9KSB7XG4gICAgY29uc3QgY291bnQgPSBwb2ludHMubGVuZ3RoO1xuICAgIGNvbnN0IHsgc3RhcnQ6IHBhcmFtc1N0YXJ0ID0gMCAsIGVuZDogcGFyYW1zRW5kID0gY291bnQgLSAxICB9ID0gcGFyYW1zO1xuICAgIGNvbnN0IHsgc3RhcnQ6IHNlZ21lbnRTdGFydCAsIGVuZDogc2VnbWVudEVuZCAgfSA9IHNlZ21lbnQ7XG4gICAgY29uc3Qgc3RhcnQgPSBNYXRoLm1heChwYXJhbXNTdGFydCwgc2VnbWVudFN0YXJ0KTtcbiAgICBjb25zdCBlbmQgPSBNYXRoLm1pbihwYXJhbXNFbmQsIHNlZ21lbnRFbmQpO1xuICAgIGNvbnN0IG91dHNpZGUgPSBwYXJhbXNTdGFydCA8IHNlZ21lbnRTdGFydCAmJiBwYXJhbXNFbmQgPCBzZWdtZW50U3RhcnQgfHwgcGFyYW1zU3RhcnQgPiBzZWdtZW50RW5kICYmIHBhcmFtc0VuZCA+IHNlZ21lbnRFbmQ7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgY291bnQsXG4gICAgICAgIHN0YXJ0LFxuICAgICAgICBsb29wOiBzZWdtZW50Lmxvb3AsXG4gICAgICAgIGlsZW46IGVuZCA8IHN0YXJ0ICYmICFvdXRzaWRlID8gY291bnQgKyBlbmQgLSBzdGFydCA6IGVuZCAtIHN0YXJ0XG4gICAgfTtcbn1cbiBmdW5jdGlvbiBwYXRoU2VnbWVudChjdHgsIGxpbmUsIHNlZ21lbnQsIHBhcmFtcykge1xuICAgIGNvbnN0IHsgcG9pbnRzICwgb3B0aW9ucyAgfSA9IGxpbmU7XG4gICAgY29uc3QgeyBjb3VudCAsIHN0YXJ0ICwgbG9vcCAsIGlsZW4gIH0gPSBwYXRoVmFycyhwb2ludHMsIHNlZ21lbnQsIHBhcmFtcyk7XG4gICAgY29uc3QgbGluZU1ldGhvZCA9IGdldExpbmVNZXRob2Qob3B0aW9ucyk7XG4gICAgbGV0IHsgbW92ZSA9dHJ1ZSAsIHJldmVyc2UgIH0gPSBwYXJhbXMgfHwge307XG4gICAgbGV0IGksIHBvaW50LCBwcmV2O1xuICAgIGZvcihpID0gMDsgaSA8PSBpbGVuOyArK2kpe1xuICAgICAgICBwb2ludCA9IHBvaW50c1soc3RhcnQgKyAocmV2ZXJzZSA/IGlsZW4gLSBpIDogaSkpICUgY291bnRdO1xuICAgICAgICBpZiAocG9pbnQuc2tpcCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH0gZWxzZSBpZiAobW92ZSkge1xuICAgICAgICAgICAgY3R4Lm1vdmVUbyhwb2ludC54LCBwb2ludC55KTtcbiAgICAgICAgICAgIG1vdmUgPSBmYWxzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxpbmVNZXRob2QoY3R4LCBwcmV2LCBwb2ludCwgcmV2ZXJzZSwgb3B0aW9ucy5zdGVwcGVkKTtcbiAgICAgICAgfVxuICAgICAgICBwcmV2ID0gcG9pbnQ7XG4gICAgfVxuICAgIGlmIChsb29wKSB7XG4gICAgICAgIHBvaW50ID0gcG9pbnRzWyhzdGFydCArIChyZXZlcnNlID8gaWxlbiA6IDApKSAlIGNvdW50XTtcbiAgICAgICAgbGluZU1ldGhvZChjdHgsIHByZXYsIHBvaW50LCByZXZlcnNlLCBvcHRpb25zLnN0ZXBwZWQpO1xuICAgIH1cbiAgICByZXR1cm4gISFsb29wO1xufVxuIGZ1bmN0aW9uIGZhc3RQYXRoU2VnbWVudChjdHgsIGxpbmUsIHNlZ21lbnQsIHBhcmFtcykge1xuICAgIGNvbnN0IHBvaW50cyA9IGxpbmUucG9pbnRzO1xuICAgIGNvbnN0IHsgY291bnQgLCBzdGFydCAsIGlsZW4gIH0gPSBwYXRoVmFycyhwb2ludHMsIHNlZ21lbnQsIHBhcmFtcyk7XG4gICAgY29uc3QgeyBtb3ZlID10cnVlICwgcmV2ZXJzZSAgfSA9IHBhcmFtcyB8fCB7fTtcbiAgICBsZXQgYXZnWCA9IDA7XG4gICAgbGV0IGNvdW50WCA9IDA7XG4gICAgbGV0IGksIHBvaW50LCBwcmV2WCwgbWluWSwgbWF4WSwgbGFzdFk7XG4gICAgY29uc3QgcG9pbnRJbmRleCA9IChpbmRleCk9PihzdGFydCArIChyZXZlcnNlID8gaWxlbiAtIGluZGV4IDogaW5kZXgpKSAlIGNvdW50O1xuICAgIGNvbnN0IGRyYXdYID0gKCk9PntcbiAgICAgICAgaWYgKG1pblkgIT09IG1heFkpIHtcbiAgICAgICAgICAgIGN0eC5saW5lVG8oYXZnWCwgbWF4WSk7XG4gICAgICAgICAgICBjdHgubGluZVRvKGF2Z1gsIG1pblkpO1xuICAgICAgICAgICAgY3R4LmxpbmVUbyhhdmdYLCBsYXN0WSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIGlmIChtb3ZlKSB7XG4gICAgICAgIHBvaW50ID0gcG9pbnRzW3BvaW50SW5kZXgoMCldO1xuICAgICAgICBjdHgubW92ZVRvKHBvaW50LngsIHBvaW50LnkpO1xuICAgIH1cbiAgICBmb3IoaSA9IDA7IGkgPD0gaWxlbjsgKytpKXtcbiAgICAgICAgcG9pbnQgPSBwb2ludHNbcG9pbnRJbmRleChpKV07XG4gICAgICAgIGlmIChwb2ludC5za2lwKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB4ID0gcG9pbnQueDtcbiAgICAgICAgY29uc3QgeSA9IHBvaW50Lnk7XG4gICAgICAgIGNvbnN0IHRydW5jWCA9IHggfCAwO1xuICAgICAgICBpZiAodHJ1bmNYID09PSBwcmV2WCkge1xuICAgICAgICAgICAgaWYgKHkgPCBtaW5ZKSB7XG4gICAgICAgICAgICAgICAgbWluWSA9IHk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHkgPiBtYXhZKSB7XG4gICAgICAgICAgICAgICAgbWF4WSA9IHk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhdmdYID0gKGNvdW50WCAqIGF2Z1ggKyB4KSAvICsrY291bnRYO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZHJhd1goKTtcbiAgICAgICAgICAgIGN0eC5saW5lVG8oeCwgeSk7XG4gICAgICAgICAgICBwcmV2WCA9IHRydW5jWDtcbiAgICAgICAgICAgIGNvdW50WCA9IDA7XG4gICAgICAgICAgICBtaW5ZID0gbWF4WSA9IHk7XG4gICAgICAgIH1cbiAgICAgICAgbGFzdFkgPSB5O1xuICAgIH1cbiAgICBkcmF3WCgpO1xufVxuIGZ1bmN0aW9uIF9nZXRTZWdtZW50TWV0aG9kKGxpbmUpIHtcbiAgICBjb25zdCBvcHRzID0gbGluZS5vcHRpb25zO1xuICAgIGNvbnN0IGJvcmRlckRhc2ggPSBvcHRzLmJvcmRlckRhc2ggJiYgb3B0cy5ib3JkZXJEYXNoLmxlbmd0aDtcbiAgICBjb25zdCB1c2VGYXN0UGF0aCA9ICFsaW5lLl9kZWNpbWF0ZWQgJiYgIWxpbmUuX2xvb3AgJiYgIW9wdHMudGVuc2lvbiAmJiBvcHRzLmN1YmljSW50ZXJwb2xhdGlvbk1vZGUgIT09ICdtb25vdG9uZScgJiYgIW9wdHMuc3RlcHBlZCAmJiAhYm9yZGVyRGFzaDtcbiAgICByZXR1cm4gdXNlRmFzdFBhdGggPyBmYXN0UGF0aFNlZ21lbnQgOiBwYXRoU2VnbWVudDtcbn1cbiBmdW5jdGlvbiBfZ2V0SW50ZXJwb2xhdGlvbk1ldGhvZChvcHRpb25zKSB7XG4gICAgaWYgKG9wdGlvbnMuc3RlcHBlZCkge1xuICAgICAgICByZXR1cm4gX3N0ZXBwZWRJbnRlcnBvbGF0aW9uO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy50ZW5zaW9uIHx8IG9wdGlvbnMuY3ViaWNJbnRlcnBvbGF0aW9uTW9kZSA9PT0gJ21vbm90b25lJykge1xuICAgICAgICByZXR1cm4gX2JlemllckludGVycG9sYXRpb247XG4gICAgfVxuICAgIHJldHVybiBfcG9pbnRJbkxpbmU7XG59XG5mdW5jdGlvbiBzdHJva2VQYXRoV2l0aENhY2hlKGN0eCwgbGluZSwgc3RhcnQsIGNvdW50KSB7XG4gICAgbGV0IHBhdGggPSBsaW5lLl9wYXRoO1xuICAgIGlmICghcGF0aCkge1xuICAgICAgICBwYXRoID0gbGluZS5fcGF0aCA9IG5ldyBQYXRoMkQoKTtcbiAgICAgICAgaWYgKGxpbmUucGF0aChwYXRoLCBzdGFydCwgY291bnQpKSB7XG4gICAgICAgICAgICBwYXRoLmNsb3NlUGF0aCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldFN0eWxlKGN0eCwgbGluZS5vcHRpb25zKTtcbiAgICBjdHguc3Ryb2tlKHBhdGgpO1xufVxuZnVuY3Rpb24gc3Ryb2tlUGF0aERpcmVjdChjdHgsIGxpbmUsIHN0YXJ0LCBjb3VudCkge1xuICAgIGNvbnN0IHsgc2VnbWVudHMgLCBvcHRpb25zICB9ID0gbGluZTtcbiAgICBjb25zdCBzZWdtZW50TWV0aG9kID0gX2dldFNlZ21lbnRNZXRob2QobGluZSk7XG4gICAgZm9yIChjb25zdCBzZWdtZW50IG9mIHNlZ21lbnRzKXtcbiAgICAgICAgc2V0U3R5bGUoY3R4LCBvcHRpb25zLCBzZWdtZW50LnN0eWxlKTtcbiAgICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgICBpZiAoc2VnbWVudE1ldGhvZChjdHgsIGxpbmUsIHNlZ21lbnQsIHtcbiAgICAgICAgICAgIHN0YXJ0LFxuICAgICAgICAgICAgZW5kOiBzdGFydCArIGNvdW50IC0gMVxuICAgICAgICB9KSkge1xuICAgICAgICAgICAgY3R4LmNsb3NlUGF0aCgpO1xuICAgICAgICB9XG4gICAgICAgIGN0eC5zdHJva2UoKTtcbiAgICB9XG59XG5jb25zdCB1c2VQYXRoMkQgPSB0eXBlb2YgUGF0aDJEID09PSAnZnVuY3Rpb24nO1xuZnVuY3Rpb24gZHJhdyhjdHgsIGxpbmUsIHN0YXJ0LCBjb3VudCkge1xuICAgIGlmICh1c2VQYXRoMkQgJiYgIWxpbmUub3B0aW9ucy5zZWdtZW50KSB7XG4gICAgICAgIHN0cm9rZVBhdGhXaXRoQ2FjaGUoY3R4LCBsaW5lLCBzdGFydCwgY291bnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHN0cm9rZVBhdGhEaXJlY3QoY3R4LCBsaW5lLCBzdGFydCwgY291bnQpO1xuICAgIH1cbn1cbmNsYXNzIExpbmVFbGVtZW50IGV4dGVuZHMgRWxlbWVudCB7XG4gICAgc3RhdGljIGlkID0gJ2xpbmUnO1xuIHN0YXRpYyBkZWZhdWx0cyA9IHtcbiAgICAgICAgYm9yZGVyQ2FwU3R5bGU6ICdidXR0JyxcbiAgICAgICAgYm9yZGVyRGFzaDogW10sXG4gICAgICAgIGJvcmRlckRhc2hPZmZzZXQ6IDAsXG4gICAgICAgIGJvcmRlckpvaW5TdHlsZTogJ21pdGVyJyxcbiAgICAgICAgYm9yZGVyV2lkdGg6IDMsXG4gICAgICAgIGNhcEJlemllclBvaW50czogdHJ1ZSxcbiAgICAgICAgY3ViaWNJbnRlcnBvbGF0aW9uTW9kZTogJ2RlZmF1bHQnLFxuICAgICAgICBmaWxsOiBmYWxzZSxcbiAgICAgICAgc3BhbkdhcHM6IGZhbHNlLFxuICAgICAgICBzdGVwcGVkOiBmYWxzZSxcbiAgICAgICAgdGVuc2lvbjogMFxuICAgIH07XG4gc3RhdGljIGRlZmF1bHRSb3V0ZXMgPSB7XG4gICAgICAgIGJhY2tncm91bmRDb2xvcjogJ2JhY2tncm91bmRDb2xvcicsXG4gICAgICAgIGJvcmRlckNvbG9yOiAnYm9yZGVyQ29sb3InXG4gICAgfTtcbiAgICBzdGF0aWMgZGVzY3JpcHRvcnMgPSB7XG4gICAgICAgIF9zY3JpcHRhYmxlOiB0cnVlLFxuICAgICAgICBfaW5kZXhhYmxlOiAobmFtZSk9Pm5hbWUgIT09ICdib3JkZXJEYXNoJyAmJiBuYW1lICE9PSAnZmlsbCdcbiAgICB9O1xuICAgIGNvbnN0cnVjdG9yKGNmZyl7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuYW5pbWF0ZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuX2NoYXJ0ID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl9sb29wID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl9mdWxsTG9vcCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fcGF0aCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fcG9pbnRzID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl9zZWdtZW50cyA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fZGVjaW1hdGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX3BvaW50c1VwZGF0ZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fZGF0YXNldEluZGV4ID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAoY2ZnKSB7XG4gICAgICAgICAgICBPYmplY3QuYXNzaWduKHRoaXMsIGNmZyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgdXBkYXRlQ29udHJvbFBvaW50cyhjaGFydEFyZWEsIGluZGV4QXhpcykge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBpZiAoKG9wdGlvbnMudGVuc2lvbiB8fCBvcHRpb25zLmN1YmljSW50ZXJwb2xhdGlvbk1vZGUgPT09ICdtb25vdG9uZScpICYmICFvcHRpb25zLnN0ZXBwZWQgJiYgIXRoaXMuX3BvaW50c1VwZGF0ZWQpIHtcbiAgICAgICAgICAgIGNvbnN0IGxvb3AgPSBvcHRpb25zLnNwYW5HYXBzID8gdGhpcy5fbG9vcCA6IHRoaXMuX2Z1bGxMb29wO1xuICAgICAgICAgICAgX3VwZGF0ZUJlemllckNvbnRyb2xQb2ludHModGhpcy5fcG9pbnRzLCBvcHRpb25zLCBjaGFydEFyZWEsIGxvb3AsIGluZGV4QXhpcyk7XG4gICAgICAgICAgICB0aGlzLl9wb2ludHNVcGRhdGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzZXQgcG9pbnRzKHBvaW50cykge1xuICAgICAgICB0aGlzLl9wb2ludHMgPSBwb2ludHM7XG4gICAgICAgIGRlbGV0ZSB0aGlzLl9zZWdtZW50cztcbiAgICAgICAgZGVsZXRlIHRoaXMuX3BhdGg7XG4gICAgICAgIHRoaXMuX3BvaW50c1VwZGF0ZWQgPSBmYWxzZTtcbiAgICB9XG4gICAgZ2V0IHBvaW50cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BvaW50cztcbiAgICB9XG4gICAgZ2V0IHNlZ21lbnRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2VnbWVudHMgfHwgKHRoaXMuX3NlZ21lbnRzID0gX2NvbXB1dGVTZWdtZW50cyh0aGlzLCB0aGlzLm9wdGlvbnMuc2VnbWVudCkpO1xuICAgIH1cbiBmaXJzdCgpIHtcbiAgICAgICAgY29uc3Qgc2VnbWVudHMgPSB0aGlzLnNlZ21lbnRzO1xuICAgICAgICBjb25zdCBwb2ludHMgPSB0aGlzLnBvaW50cztcbiAgICAgICAgcmV0dXJuIHNlZ21lbnRzLmxlbmd0aCAmJiBwb2ludHNbc2VnbWVudHNbMF0uc3RhcnRdO1xuICAgIH1cbiBsYXN0KCkge1xuICAgICAgICBjb25zdCBzZWdtZW50cyA9IHRoaXMuc2VnbWVudHM7XG4gICAgICAgIGNvbnN0IHBvaW50cyA9IHRoaXMucG9pbnRzO1xuICAgICAgICBjb25zdCBjb3VudCA9IHNlZ21lbnRzLmxlbmd0aDtcbiAgICAgICAgcmV0dXJuIGNvdW50ICYmIHBvaW50c1tzZWdtZW50c1tjb3VudCAtIDFdLmVuZF07XG4gICAgfVxuIGludGVycG9sYXRlKHBvaW50LCBwcm9wZXJ0eSkge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHBvaW50W3Byb3BlcnR5XTtcbiAgICAgICAgY29uc3QgcG9pbnRzID0gdGhpcy5wb2ludHM7XG4gICAgICAgIGNvbnN0IHNlZ21lbnRzID0gX2JvdW5kU2VnbWVudHModGhpcywge1xuICAgICAgICAgICAgcHJvcGVydHksXG4gICAgICAgICAgICBzdGFydDogdmFsdWUsXG4gICAgICAgICAgICBlbmQ6IHZhbHVlXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIXNlZ21lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuICAgICAgICBjb25zdCBfaW50ZXJwb2xhdGUgPSBfZ2V0SW50ZXJwb2xhdGlvbk1ldGhvZChvcHRpb25zKTtcbiAgICAgICAgbGV0IGksIGlsZW47XG4gICAgICAgIGZvcihpID0gMCwgaWxlbiA9IHNlZ21lbnRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSl7XG4gICAgICAgICAgICBjb25zdCB7IHN0YXJ0ICwgZW5kICB9ID0gc2VnbWVudHNbaV07XG4gICAgICAgICAgICBjb25zdCBwMSA9IHBvaW50c1tzdGFydF07XG4gICAgICAgICAgICBjb25zdCBwMiA9IHBvaW50c1tlbmRdO1xuICAgICAgICAgICAgaWYgKHAxID09PSBwMikge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHAxKTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHQgPSBNYXRoLmFicygodmFsdWUgLSBwMVtwcm9wZXJ0eV0pIC8gKHAyW3Byb3BlcnR5XSAtIHAxW3Byb3BlcnR5XSkpO1xuICAgICAgICAgICAgY29uc3QgaW50ZXJwb2xhdGVkID0gX2ludGVycG9sYXRlKHAxLCBwMiwgdCwgb3B0aW9ucy5zdGVwcGVkKTtcbiAgICAgICAgICAgIGludGVycG9sYXRlZFtwcm9wZXJ0eV0gPSBwb2ludFtwcm9wZXJ0eV07XG4gICAgICAgICAgICByZXN1bHQucHVzaChpbnRlcnBvbGF0ZWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQubGVuZ3RoID09PSAxID8gcmVzdWx0WzBdIDogcmVzdWx0O1xuICAgIH1cbiBwYXRoU2VnbWVudChjdHgsIHNlZ21lbnQsIHBhcmFtcykge1xuICAgICAgICBjb25zdCBzZWdtZW50TWV0aG9kID0gX2dldFNlZ21lbnRNZXRob2QodGhpcyk7XG4gICAgICAgIHJldHVybiBzZWdtZW50TWV0aG9kKGN0eCwgdGhpcywgc2VnbWVudCwgcGFyYW1zKTtcbiAgICB9XG4gcGF0aChjdHgsIHN0YXJ0LCBjb3VudCkge1xuICAgICAgICBjb25zdCBzZWdtZW50cyA9IHRoaXMuc2VnbWVudHM7XG4gICAgICAgIGNvbnN0IHNlZ21lbnRNZXRob2QgPSBfZ2V0U2VnbWVudE1ldGhvZCh0aGlzKTtcbiAgICAgICAgbGV0IGxvb3AgPSB0aGlzLl9sb29wO1xuICAgICAgICBzdGFydCA9IHN0YXJ0IHx8IDA7XG4gICAgICAgIGNvdW50ID0gY291bnQgfHwgdGhpcy5wb2ludHMubGVuZ3RoIC0gc3RhcnQ7XG4gICAgICAgIGZvciAoY29uc3Qgc2VnbWVudCBvZiBzZWdtZW50cyl7XG4gICAgICAgICAgICBsb29wICY9IHNlZ21lbnRNZXRob2QoY3R4LCB0aGlzLCBzZWdtZW50LCB7XG4gICAgICAgICAgICAgICAgc3RhcnQsXG4gICAgICAgICAgICAgICAgZW5kOiBzdGFydCArIGNvdW50IC0gMVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICEhbG9vcDtcbiAgICB9XG4gZHJhdyhjdHgsIGNoYXJ0QXJlYSwgc3RhcnQsIGNvdW50KSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLm9wdGlvbnMgfHwge307XG4gICAgICAgIGNvbnN0IHBvaW50cyA9IHRoaXMucG9pbnRzIHx8IFtdO1xuICAgICAgICBpZiAocG9pbnRzLmxlbmd0aCAmJiBvcHRpb25zLmJvcmRlcldpZHRoKSB7XG4gICAgICAgICAgICBjdHguc2F2ZSgpO1xuICAgICAgICAgICAgZHJhdyhjdHgsIHRoaXMsIHN0YXJ0LCBjb3VudCk7XG4gICAgICAgICAgICBjdHgucmVzdG9yZSgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmFuaW1hdGVkKSB7XG4gICAgICAgICAgICB0aGlzLl9wb2ludHNVcGRhdGVkID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLl9wYXRoID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBpblJhbmdlJDEoZWwsIHBvcywgYXhpcywgdXNlRmluYWxQb3NpdGlvbikge1xuICAgIGNvbnN0IG9wdGlvbnMgPSBlbC5vcHRpb25zO1xuICAgIGNvbnN0IHsgW2F4aXNdOiB2YWx1ZSAgfSA9IGVsLmdldFByb3BzKFtcbiAgICAgICAgYXhpc1xuICAgIF0sIHVzZUZpbmFsUG9zaXRpb24pO1xuICAgIHJldHVybiBNYXRoLmFicyhwb3MgLSB2YWx1ZSkgPCBvcHRpb25zLnJhZGl1cyArIG9wdGlvbnMuaGl0UmFkaXVzO1xufVxuY2xhc3MgUG9pbnRFbGVtZW50IGV4dGVuZHMgRWxlbWVudCB7XG4gICAgc3RhdGljIGlkID0gJ3BvaW50JztcbiAgICBwYXJzZWQ7XG4gICAgc2tpcDtcbiAgICBzdG9wO1xuICAgIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi8gc3RhdGljIGRlZmF1bHRzID0ge1xuICAgICAgICBib3JkZXJXaWR0aDogMSxcbiAgICAgICAgaGl0UmFkaXVzOiAxLFxuICAgICAgICBob3ZlckJvcmRlcldpZHRoOiAxLFxuICAgICAgICBob3ZlclJhZGl1czogNCxcbiAgICAgICAgcG9pbnRTdHlsZTogJ2NpcmNsZScsXG4gICAgICAgIHJhZGl1czogMyxcbiAgICAgICAgcm90YXRpb246IDBcbiAgICB9O1xuICAgIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi8gc3RhdGljIGRlZmF1bHRSb3V0ZXMgPSB7XG4gICAgICAgIGJhY2tncm91bmRDb2xvcjogJ2JhY2tncm91bmRDb2xvcicsXG4gICAgICAgIGJvcmRlckNvbG9yOiAnYm9yZGVyQ29sb3InXG4gICAgfTtcbiAgICBjb25zdHJ1Y3RvcihjZmcpe1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMucGFyc2VkID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLnNraXAgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuc3RvcCA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKGNmZykge1xuICAgICAgICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLCBjZmcpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGluUmFuZ2UobW91c2VYLCBtb3VzZVksIHVzZUZpbmFsUG9zaXRpb24pIHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgY29uc3QgeyB4ICwgeSAgfSA9IHRoaXMuZ2V0UHJvcHMoW1xuICAgICAgICAgICAgJ3gnLFxuICAgICAgICAgICAgJ3knXG4gICAgICAgIF0sIHVzZUZpbmFsUG9zaXRpb24pO1xuICAgICAgICByZXR1cm4gTWF0aC5wb3cobW91c2VYIC0geCwgMikgKyBNYXRoLnBvdyhtb3VzZVkgLSB5LCAyKSA8IE1hdGgucG93KG9wdGlvbnMuaGl0UmFkaXVzICsgb3B0aW9ucy5yYWRpdXMsIDIpO1xuICAgIH1cbiAgICBpblhSYW5nZShtb3VzZVgsIHVzZUZpbmFsUG9zaXRpb24pIHtcbiAgICAgICAgcmV0dXJuIGluUmFuZ2UkMSh0aGlzLCBtb3VzZVgsICd4JywgdXNlRmluYWxQb3NpdGlvbik7XG4gICAgfVxuICAgIGluWVJhbmdlKG1vdXNlWSwgdXNlRmluYWxQb3NpdGlvbikge1xuICAgICAgICByZXR1cm4gaW5SYW5nZSQxKHRoaXMsIG1vdXNlWSwgJ3knLCB1c2VGaW5hbFBvc2l0aW9uKTtcbiAgICB9XG4gICAgZ2V0Q2VudGVyUG9pbnQodXNlRmluYWxQb3NpdGlvbikge1xuICAgICAgICBjb25zdCB7IHggLCB5ICB9ID0gdGhpcy5nZXRQcm9wcyhbXG4gICAgICAgICAgICAneCcsXG4gICAgICAgICAgICAneSdcbiAgICAgICAgXSwgdXNlRmluYWxQb3NpdGlvbik7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4LFxuICAgICAgICAgICAgeVxuICAgICAgICB9O1xuICAgIH1cbiAgICBzaXplKG9wdGlvbnMpIHtcbiAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwgdGhpcy5vcHRpb25zIHx8IHt9O1xuICAgICAgICBsZXQgcmFkaXVzID0gb3B0aW9ucy5yYWRpdXMgfHwgMDtcbiAgICAgICAgcmFkaXVzID0gTWF0aC5tYXgocmFkaXVzLCByYWRpdXMgJiYgb3B0aW9ucy5ob3ZlclJhZGl1cyB8fCAwKTtcbiAgICAgICAgY29uc3QgYm9yZGVyV2lkdGggPSByYWRpdXMgJiYgb3B0aW9ucy5ib3JkZXJXaWR0aCB8fCAwO1xuICAgICAgICByZXR1cm4gKHJhZGl1cyArIGJvcmRlcldpZHRoKSAqIDI7XG4gICAgfVxuICAgIGRyYXcoY3R4LCBhcmVhKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGlmICh0aGlzLnNraXAgfHwgb3B0aW9ucy5yYWRpdXMgPCAwLjEgfHwgIV9pc1BvaW50SW5BcmVhKHRoaXMsIGFyZWEsIHRoaXMuc2l6ZShvcHRpb25zKSAvIDIpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY3R4LnN0cm9rZVN0eWxlID0gb3B0aW9ucy5ib3JkZXJDb2xvcjtcbiAgICAgICAgY3R4LmxpbmVXaWR0aCA9IG9wdGlvbnMuYm9yZGVyV2lkdGg7XG4gICAgICAgIGN0eC5maWxsU3R5bGUgPSBvcHRpb25zLmJhY2tncm91bmRDb2xvcjtcbiAgICAgICAgZHJhd1BvaW50KGN0eCwgb3B0aW9ucywgdGhpcy54LCB0aGlzLnkpO1xuICAgIH1cbiAgICBnZXRSYW5nZSgpIHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucyB8fCB7fTtcbiAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBGYWxsYmFja3Mgc2hvdWxkIG5ldmVyIGJlIGhpdCBpbiBwcmFjdGljZVxuICAgICAgICByZXR1cm4gb3B0aW9ucy5yYWRpdXMgKyBvcHRpb25zLmhpdFJhZGl1cztcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGdldEJhckJvdW5kcyhiYXIsIHVzZUZpbmFsUG9zaXRpb24pIHtcbiAgICBjb25zdCB7IHggLCB5ICwgYmFzZSAsIHdpZHRoICwgaGVpZ2h0ICB9ID0gIGJhci5nZXRQcm9wcyhbXG4gICAgICAgICd4JyxcbiAgICAgICAgJ3knLFxuICAgICAgICAnYmFzZScsXG4gICAgICAgICd3aWR0aCcsXG4gICAgICAgICdoZWlnaHQnXG4gICAgXSwgdXNlRmluYWxQb3NpdGlvbik7XG4gICAgbGV0IGxlZnQsIHJpZ2h0LCB0b3AsIGJvdHRvbSwgaGFsZjtcbiAgICBpZiAoYmFyLmhvcml6b250YWwpIHtcbiAgICAgICAgaGFsZiA9IGhlaWdodCAvIDI7XG4gICAgICAgIGxlZnQgPSBNYXRoLm1pbih4LCBiYXNlKTtcbiAgICAgICAgcmlnaHQgPSBNYXRoLm1heCh4LCBiYXNlKTtcbiAgICAgICAgdG9wID0geSAtIGhhbGY7XG4gICAgICAgIGJvdHRvbSA9IHkgKyBoYWxmO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGhhbGYgPSB3aWR0aCAvIDI7XG4gICAgICAgIGxlZnQgPSB4IC0gaGFsZjtcbiAgICAgICAgcmlnaHQgPSB4ICsgaGFsZjtcbiAgICAgICAgdG9wID0gTWF0aC5taW4oeSwgYmFzZSk7XG4gICAgICAgIGJvdHRvbSA9IE1hdGgubWF4KHksIGJhc2UpO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBsZWZ0LFxuICAgICAgICB0b3AsXG4gICAgICAgIHJpZ2h0LFxuICAgICAgICBib3R0b21cbiAgICB9O1xufVxuZnVuY3Rpb24gc2tpcE9yTGltaXQoc2tpcCwgdmFsdWUsIG1pbiwgbWF4KSB7XG4gICAgcmV0dXJuIHNraXAgPyAwIDogX2xpbWl0VmFsdWUodmFsdWUsIG1pbiwgbWF4KTtcbn1cbmZ1bmN0aW9uIHBhcnNlQm9yZGVyV2lkdGgoYmFyLCBtYXhXLCBtYXhIKSB7XG4gICAgY29uc3QgdmFsdWUgPSBiYXIub3B0aW9ucy5ib3JkZXJXaWR0aDtcbiAgICBjb25zdCBza2lwID0gYmFyLmJvcmRlclNraXBwZWQ7XG4gICAgY29uc3QgbyA9IHRvVFJCTCh2YWx1ZSk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgdDogc2tpcE9yTGltaXQoc2tpcC50b3AsIG8udG9wLCAwLCBtYXhIKSxcbiAgICAgICAgcjogc2tpcE9yTGltaXQoc2tpcC5yaWdodCwgby5yaWdodCwgMCwgbWF4VyksXG4gICAgICAgIGI6IHNraXBPckxpbWl0KHNraXAuYm90dG9tLCBvLmJvdHRvbSwgMCwgbWF4SCksXG4gICAgICAgIGw6IHNraXBPckxpbWl0KHNraXAubGVmdCwgby5sZWZ0LCAwLCBtYXhXKVxuICAgIH07XG59XG5mdW5jdGlvbiBwYXJzZUJvcmRlclJhZGl1cyhiYXIsIG1heFcsIG1heEgpIHtcbiAgICBjb25zdCB7IGVuYWJsZUJvcmRlclJhZGl1cyAgfSA9IGJhci5nZXRQcm9wcyhbXG4gICAgICAgICdlbmFibGVCb3JkZXJSYWRpdXMnXG4gICAgXSk7XG4gICAgY29uc3QgdmFsdWUgPSBiYXIub3B0aW9ucy5ib3JkZXJSYWRpdXM7XG4gICAgY29uc3QgbyA9IHRvVFJCTENvcm5lcnModmFsdWUpO1xuICAgIGNvbnN0IG1heFIgPSBNYXRoLm1pbihtYXhXLCBtYXhIKTtcbiAgICBjb25zdCBza2lwID0gYmFyLmJvcmRlclNraXBwZWQ7XG4gICAgY29uc3QgZW5hYmxlQm9yZGVyID0gZW5hYmxlQm9yZGVyUmFkaXVzIHx8IGlzT2JqZWN0KHZhbHVlKTtcbiAgICByZXR1cm4ge1xuICAgICAgICB0b3BMZWZ0OiBza2lwT3JMaW1pdCghZW5hYmxlQm9yZGVyIHx8IHNraXAudG9wIHx8IHNraXAubGVmdCwgby50b3BMZWZ0LCAwLCBtYXhSKSxcbiAgICAgICAgdG9wUmlnaHQ6IHNraXBPckxpbWl0KCFlbmFibGVCb3JkZXIgfHwgc2tpcC50b3AgfHwgc2tpcC5yaWdodCwgby50b3BSaWdodCwgMCwgbWF4UiksXG4gICAgICAgIGJvdHRvbUxlZnQ6IHNraXBPckxpbWl0KCFlbmFibGVCb3JkZXIgfHwgc2tpcC5ib3R0b20gfHwgc2tpcC5sZWZ0LCBvLmJvdHRvbUxlZnQsIDAsIG1heFIpLFxuICAgICAgICBib3R0b21SaWdodDogc2tpcE9yTGltaXQoIWVuYWJsZUJvcmRlciB8fCBza2lwLmJvdHRvbSB8fCBza2lwLnJpZ2h0LCBvLmJvdHRvbVJpZ2h0LCAwLCBtYXhSKVxuICAgIH07XG59XG5mdW5jdGlvbiBib3VuZGluZ1JlY3RzKGJhcikge1xuICAgIGNvbnN0IGJvdW5kcyA9IGdldEJhckJvdW5kcyhiYXIpO1xuICAgIGNvbnN0IHdpZHRoID0gYm91bmRzLnJpZ2h0IC0gYm91bmRzLmxlZnQ7XG4gICAgY29uc3QgaGVpZ2h0ID0gYm91bmRzLmJvdHRvbSAtIGJvdW5kcy50b3A7XG4gICAgY29uc3QgYm9yZGVyID0gcGFyc2VCb3JkZXJXaWR0aChiYXIsIHdpZHRoIC8gMiwgaGVpZ2h0IC8gMik7XG4gICAgY29uc3QgcmFkaXVzID0gcGFyc2VCb3JkZXJSYWRpdXMoYmFyLCB3aWR0aCAvIDIsIGhlaWdodCAvIDIpO1xuICAgIHJldHVybiB7XG4gICAgICAgIG91dGVyOiB7XG4gICAgICAgICAgICB4OiBib3VuZHMubGVmdCxcbiAgICAgICAgICAgIHk6IGJvdW5kcy50b3AsXG4gICAgICAgICAgICB3OiB3aWR0aCxcbiAgICAgICAgICAgIGg6IGhlaWdodCxcbiAgICAgICAgICAgIHJhZGl1c1xuICAgICAgICB9LFxuICAgICAgICBpbm5lcjoge1xuICAgICAgICAgICAgeDogYm91bmRzLmxlZnQgKyBib3JkZXIubCxcbiAgICAgICAgICAgIHk6IGJvdW5kcy50b3AgKyBib3JkZXIudCxcbiAgICAgICAgICAgIHc6IHdpZHRoIC0gYm9yZGVyLmwgLSBib3JkZXIucixcbiAgICAgICAgICAgIGg6IGhlaWdodCAtIGJvcmRlci50IC0gYm9yZGVyLmIsXG4gICAgICAgICAgICByYWRpdXM6IHtcbiAgICAgICAgICAgICAgICB0b3BMZWZ0OiBNYXRoLm1heCgwLCByYWRpdXMudG9wTGVmdCAtIE1hdGgubWF4KGJvcmRlci50LCBib3JkZXIubCkpLFxuICAgICAgICAgICAgICAgIHRvcFJpZ2h0OiBNYXRoLm1heCgwLCByYWRpdXMudG9wUmlnaHQgLSBNYXRoLm1heChib3JkZXIudCwgYm9yZGVyLnIpKSxcbiAgICAgICAgICAgICAgICBib3R0b21MZWZ0OiBNYXRoLm1heCgwLCByYWRpdXMuYm90dG9tTGVmdCAtIE1hdGgubWF4KGJvcmRlci5iLCBib3JkZXIubCkpLFxuICAgICAgICAgICAgICAgIGJvdHRvbVJpZ2h0OiBNYXRoLm1heCgwLCByYWRpdXMuYm90dG9tUmlnaHQgLSBNYXRoLm1heChib3JkZXIuYiwgYm9yZGVyLnIpKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn1cbmZ1bmN0aW9uIGluUmFuZ2UoYmFyLCB4LCB5LCB1c2VGaW5hbFBvc2l0aW9uKSB7XG4gICAgY29uc3Qgc2tpcFggPSB4ID09PSBudWxsO1xuICAgIGNvbnN0IHNraXBZID0geSA9PT0gbnVsbDtcbiAgICBjb25zdCBza2lwQm90aCA9IHNraXBYICYmIHNraXBZO1xuICAgIGNvbnN0IGJvdW5kcyA9IGJhciAmJiAhc2tpcEJvdGggJiYgZ2V0QmFyQm91bmRzKGJhciwgdXNlRmluYWxQb3NpdGlvbik7XG4gICAgcmV0dXJuIGJvdW5kcyAmJiAoc2tpcFggfHwgX2lzQmV0d2Vlbih4LCBib3VuZHMubGVmdCwgYm91bmRzLnJpZ2h0KSkgJiYgKHNraXBZIHx8IF9pc0JldHdlZW4oeSwgYm91bmRzLnRvcCwgYm91bmRzLmJvdHRvbSkpO1xufVxuZnVuY3Rpb24gaGFzUmFkaXVzKHJhZGl1cykge1xuICAgIHJldHVybiByYWRpdXMudG9wTGVmdCB8fCByYWRpdXMudG9wUmlnaHQgfHwgcmFkaXVzLmJvdHRvbUxlZnQgfHwgcmFkaXVzLmJvdHRvbVJpZ2h0O1xufVxuIGZ1bmN0aW9uIGFkZE5vcm1hbFJlY3RQYXRoKGN0eCwgcmVjdCkge1xuICAgIGN0eC5yZWN0KHJlY3QueCwgcmVjdC55LCByZWN0LncsIHJlY3QuaCk7XG59XG5mdW5jdGlvbiBpbmZsYXRlUmVjdChyZWN0LCBhbW91bnQsIHJlZlJlY3QgPSB7fSkge1xuICAgIGNvbnN0IHggPSByZWN0LnggIT09IHJlZlJlY3QueCA/IC1hbW91bnQgOiAwO1xuICAgIGNvbnN0IHkgPSByZWN0LnkgIT09IHJlZlJlY3QueSA/IC1hbW91bnQgOiAwO1xuICAgIGNvbnN0IHcgPSAocmVjdC54ICsgcmVjdC53ICE9PSByZWZSZWN0LnggKyByZWZSZWN0LncgPyBhbW91bnQgOiAwKSAtIHg7XG4gICAgY29uc3QgaCA9IChyZWN0LnkgKyByZWN0LmggIT09IHJlZlJlY3QueSArIHJlZlJlY3QuaCA/IGFtb3VudCA6IDApIC0geTtcbiAgICByZXR1cm4ge1xuICAgICAgICB4OiByZWN0LnggKyB4LFxuICAgICAgICB5OiByZWN0LnkgKyB5LFxuICAgICAgICB3OiByZWN0LncgKyB3LFxuICAgICAgICBoOiByZWN0LmggKyBoLFxuICAgICAgICByYWRpdXM6IHJlY3QucmFkaXVzXG4gICAgfTtcbn1cbmNsYXNzIEJhckVsZW1lbnQgZXh0ZW5kcyBFbGVtZW50IHtcbiAgICBzdGF0aWMgaWQgPSAnYmFyJztcbiBzdGF0aWMgZGVmYXVsdHMgPSB7XG4gICAgICAgIGJvcmRlclNraXBwZWQ6ICdzdGFydCcsXG4gICAgICAgIGJvcmRlcldpZHRoOiAwLFxuICAgICAgICBib3JkZXJSYWRpdXM6IDAsXG4gICAgICAgIGluZmxhdGVBbW91bnQ6ICdhdXRvJyxcbiAgICAgICAgcG9pbnRTdHlsZTogdW5kZWZpbmVkXG4gICAgfTtcbiBzdGF0aWMgZGVmYXVsdFJvdXRlcyA9IHtcbiAgICAgICAgYmFja2dyb3VuZENvbG9yOiAnYmFja2dyb3VuZENvbG9yJyxcbiAgICAgICAgYm9yZGVyQ29sb3I6ICdib3JkZXJDb2xvcidcbiAgICB9O1xuICAgIGNvbnN0cnVjdG9yKGNmZyl7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5ob3Jpem9udGFsID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLmJhc2UgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMud2lkdGggPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuaGVpZ2h0ID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLmluZmxhdGVBbW91bnQgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChjZmcpIHtcbiAgICAgICAgICAgIE9iamVjdC5hc3NpZ24odGhpcywgY2ZnKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBkcmF3KGN0eCkge1xuICAgICAgICBjb25zdCB7IGluZmxhdGVBbW91bnQgLCBvcHRpb25zOiB7IGJvcmRlckNvbG9yICwgYmFja2dyb3VuZENvbG9yICB9ICB9ID0gdGhpcztcbiAgICAgICAgY29uc3QgeyBpbm5lciAsIG91dGVyICB9ID0gYm91bmRpbmdSZWN0cyh0aGlzKTtcbiAgICAgICAgY29uc3QgYWRkUmVjdFBhdGggPSBoYXNSYWRpdXMob3V0ZXIucmFkaXVzKSA/IGFkZFJvdW5kZWRSZWN0UGF0aCA6IGFkZE5vcm1hbFJlY3RQYXRoO1xuICAgICAgICBjdHguc2F2ZSgpO1xuICAgICAgICBpZiAob3V0ZXIudyAhPT0gaW5uZXIudyB8fCBvdXRlci5oICE9PSBpbm5lci5oKSB7XG4gICAgICAgICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICAgICAgICBhZGRSZWN0UGF0aChjdHgsIGluZmxhdGVSZWN0KG91dGVyLCBpbmZsYXRlQW1vdW50LCBpbm5lcikpO1xuICAgICAgICAgICAgY3R4LmNsaXAoKTtcbiAgICAgICAgICAgIGFkZFJlY3RQYXRoKGN0eCwgaW5mbGF0ZVJlY3QoaW5uZXIsIC1pbmZsYXRlQW1vdW50LCBvdXRlcikpO1xuICAgICAgICAgICAgY3R4LmZpbGxTdHlsZSA9IGJvcmRlckNvbG9yO1xuICAgICAgICAgICAgY3R4LmZpbGwoJ2V2ZW5vZGQnKTtcbiAgICAgICAgfVxuICAgICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICAgIGFkZFJlY3RQYXRoKGN0eCwgaW5mbGF0ZVJlY3QoaW5uZXIsIGluZmxhdGVBbW91bnQpKTtcbiAgICAgICAgY3R4LmZpbGxTdHlsZSA9IGJhY2tncm91bmRDb2xvcjtcbiAgICAgICAgY3R4LmZpbGwoKTtcbiAgICAgICAgY3R4LnJlc3RvcmUoKTtcbiAgICB9XG4gICAgaW5SYW5nZShtb3VzZVgsIG1vdXNlWSwgdXNlRmluYWxQb3NpdGlvbikge1xuICAgICAgICByZXR1cm4gaW5SYW5nZSh0aGlzLCBtb3VzZVgsIG1vdXNlWSwgdXNlRmluYWxQb3NpdGlvbik7XG4gICAgfVxuICAgIGluWFJhbmdlKG1vdXNlWCwgdXNlRmluYWxQb3NpdGlvbikge1xuICAgICAgICByZXR1cm4gaW5SYW5nZSh0aGlzLCBtb3VzZVgsIG51bGwsIHVzZUZpbmFsUG9zaXRpb24pO1xuICAgIH1cbiAgICBpbllSYW5nZShtb3VzZVksIHVzZUZpbmFsUG9zaXRpb24pIHtcbiAgICAgICAgcmV0dXJuIGluUmFuZ2UodGhpcywgbnVsbCwgbW91c2VZLCB1c2VGaW5hbFBvc2l0aW9uKTtcbiAgICB9XG4gICAgZ2V0Q2VudGVyUG9pbnQodXNlRmluYWxQb3NpdGlvbikge1xuICAgICAgICBjb25zdCB7IHggLCB5ICwgYmFzZSAsIGhvcml6b250YWwgIH0gPSAgdGhpcy5nZXRQcm9wcyhbXG4gICAgICAgICAgICAneCcsXG4gICAgICAgICAgICAneScsXG4gICAgICAgICAgICAnYmFzZScsXG4gICAgICAgICAgICAnaG9yaXpvbnRhbCdcbiAgICAgICAgXSwgdXNlRmluYWxQb3NpdGlvbik7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiBob3Jpem9udGFsID8gKHggKyBiYXNlKSAvIDIgOiB4LFxuICAgICAgICAgICAgeTogaG9yaXpvbnRhbCA/IHkgOiAoeSArIGJhc2UpIC8gMlxuICAgICAgICB9O1xuICAgIH1cbiAgICBnZXRSYW5nZShheGlzKSB7XG4gICAgICAgIHJldHVybiBheGlzID09PSAneCcgPyB0aGlzLndpZHRoIC8gMiA6IHRoaXMuaGVpZ2h0IC8gMjtcbiAgICB9XG59XG5cbnZhciBlbGVtZW50cyA9IC8qI19fUFVSRV9fKi9PYmplY3QuZnJlZXplKHtcbl9fcHJvdG9fXzogbnVsbCxcbkFyY0VsZW1lbnQ6IEFyY0VsZW1lbnQsXG5CYXJFbGVtZW50OiBCYXJFbGVtZW50LFxuTGluZUVsZW1lbnQ6IExpbmVFbGVtZW50LFxuUG9pbnRFbGVtZW50OiBQb2ludEVsZW1lbnRcbn0pO1xuXG5jb25zdCBCT1JERVJfQ09MT1JTID0gW1xuICAgICdyZ2IoNTQsIDE2MiwgMjM1KScsXG4gICAgJ3JnYigyNTUsIDk5LCAxMzIpJyxcbiAgICAncmdiKDI1NSwgMTU5LCA2NCknLFxuICAgICdyZ2IoMjU1LCAyMDUsIDg2KScsXG4gICAgJ3JnYig3NSwgMTkyLCAxOTIpJyxcbiAgICAncmdiKDE1MywgMTAyLCAyNTUpJyxcbiAgICAncmdiKDIwMSwgMjAzLCAyMDcpJyAvLyBncmV5XG5dO1xuLy8gQm9yZGVyIGNvbG9ycyB3aXRoIDUwJSB0cmFuc3BhcmVuY3lcbmNvbnN0IEJBQ0tHUk9VTkRfQ09MT1JTID0gLyogI19fUFVSRV9fICovIEJPUkRFUl9DT0xPUlMubWFwKChjb2xvcik9PmNvbG9yLnJlcGxhY2UoJ3JnYignLCAncmdiYSgnKS5yZXBsYWNlKCcpJywgJywgMC41KScpKTtcbmZ1bmN0aW9uIGdldEJvcmRlckNvbG9yKGkpIHtcbiAgICByZXR1cm4gQk9SREVSX0NPTE9SU1tpICUgQk9SREVSX0NPTE9SUy5sZW5ndGhdO1xufVxuZnVuY3Rpb24gZ2V0QmFja2dyb3VuZENvbG9yKGkpIHtcbiAgICByZXR1cm4gQkFDS0dST1VORF9DT0xPUlNbaSAlIEJBQ0tHUk9VTkRfQ09MT1JTLmxlbmd0aF07XG59XG5mdW5jdGlvbiBjb2xvcml6ZURlZmF1bHREYXRhc2V0KGRhdGFzZXQsIGkpIHtcbiAgICBkYXRhc2V0LmJvcmRlckNvbG9yID0gZ2V0Qm9yZGVyQ29sb3IoaSk7XG4gICAgZGF0YXNldC5iYWNrZ3JvdW5kQ29sb3IgPSBnZXRCYWNrZ3JvdW5kQ29sb3IoaSk7XG4gICAgcmV0dXJuICsraTtcbn1cbmZ1bmN0aW9uIGNvbG9yaXplRG91Z2hudXREYXRhc2V0KGRhdGFzZXQsIGkpIHtcbiAgICBkYXRhc2V0LmJhY2tncm91bmRDb2xvciA9IGRhdGFzZXQuZGF0YS5tYXAoKCk9PmdldEJvcmRlckNvbG9yKGkrKykpO1xuICAgIHJldHVybiBpO1xufVxuZnVuY3Rpb24gY29sb3JpemVQb2xhckFyZWFEYXRhc2V0KGRhdGFzZXQsIGkpIHtcbiAgICBkYXRhc2V0LmJhY2tncm91bmRDb2xvciA9IGRhdGFzZXQuZGF0YS5tYXAoKCk9PmdldEJhY2tncm91bmRDb2xvcihpKyspKTtcbiAgICByZXR1cm4gaTtcbn1cbmZ1bmN0aW9uIGdldENvbG9yaXplcihjaGFydCkge1xuICAgIGxldCBpID0gMDtcbiAgICByZXR1cm4gKGRhdGFzZXQsIGRhdGFzZXRJbmRleCk9PntcbiAgICAgICAgY29uc3QgY29udHJvbGxlciA9IGNoYXJ0LmdldERhdGFzZXRNZXRhKGRhdGFzZXRJbmRleCkuY29udHJvbGxlcjtcbiAgICAgICAgaWYgKGNvbnRyb2xsZXIgaW5zdGFuY2VvZiBEb3VnaG51dENvbnRyb2xsZXIpIHtcbiAgICAgICAgICAgIGkgPSBjb2xvcml6ZURvdWdobnV0RGF0YXNldChkYXRhc2V0LCBpKTtcbiAgICAgICAgfSBlbHNlIGlmIChjb250cm9sbGVyIGluc3RhbmNlb2YgUG9sYXJBcmVhQ29udHJvbGxlcikge1xuICAgICAgICAgICAgaSA9IGNvbG9yaXplUG9sYXJBcmVhRGF0YXNldChkYXRhc2V0LCBpKTtcbiAgICAgICAgfSBlbHNlIGlmIChjb250cm9sbGVyKSB7XG4gICAgICAgICAgICBpID0gY29sb3JpemVEZWZhdWx0RGF0YXNldChkYXRhc2V0LCBpKTtcbiAgICAgICAgfVxuICAgIH07XG59XG5mdW5jdGlvbiBjb250YWluc0NvbG9yc0RlZmluaXRpb25zKGRlc2NyaXB0b3JzKSB7XG4gICAgbGV0IGs7XG4gICAgZm9yKGsgaW4gZGVzY3JpcHRvcnMpe1xuICAgICAgICBpZiAoZGVzY3JpcHRvcnNba10uYm9yZGVyQ29sb3IgfHwgZGVzY3JpcHRvcnNba10uYmFja2dyb3VuZENvbG9yKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBjb250YWluc0NvbG9yc0RlZmluaXRpb24oZGVzY3JpcHRvcikge1xuICAgIHJldHVybiBkZXNjcmlwdG9yICYmIChkZXNjcmlwdG9yLmJvcmRlckNvbG9yIHx8IGRlc2NyaXB0b3IuYmFja2dyb3VuZENvbG9yKTtcbn1cbnZhciBwbHVnaW5fY29sb3JzID0ge1xuICAgIGlkOiAnY29sb3JzJyxcbiAgICBkZWZhdWx0czoge1xuICAgICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgICBmb3JjZU92ZXJyaWRlOiBmYWxzZVxuICAgIH0sXG4gICAgYmVmb3JlTGF5b3V0IChjaGFydCwgX2FyZ3MsIG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKCFvcHRpb25zLmVuYWJsZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IGRhdGE6IHsgZGF0YXNldHMgIH0gLCBvcHRpb25zOiBjaGFydE9wdGlvbnMgIH0gPSBjaGFydC5jb25maWc7XG4gICAgICAgIGNvbnN0IHsgZWxlbWVudHMgIH0gPSBjaGFydE9wdGlvbnM7XG4gICAgICAgIGlmICghb3B0aW9ucy5mb3JjZU92ZXJyaWRlICYmIChjb250YWluc0NvbG9yc0RlZmluaXRpb25zKGRhdGFzZXRzKSB8fCBjb250YWluc0NvbG9yc0RlZmluaXRpb24oY2hhcnRPcHRpb25zKSB8fCBlbGVtZW50cyAmJiBjb250YWluc0NvbG9yc0RlZmluaXRpb25zKGVsZW1lbnRzKSkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjb2xvcml6ZXIgPSBnZXRDb2xvcml6ZXIoY2hhcnQpO1xuICAgICAgICBkYXRhc2V0cy5mb3JFYWNoKGNvbG9yaXplcik7XG4gICAgfVxufTtcblxuZnVuY3Rpb24gbHR0YkRlY2ltYXRpb24oZGF0YSwgc3RhcnQsIGNvdW50LCBhdmFpbGFibGVXaWR0aCwgb3B0aW9ucykge1xuIGNvbnN0IHNhbXBsZXMgPSBvcHRpb25zLnNhbXBsZXMgfHwgYXZhaWxhYmxlV2lkdGg7XG4gICAgaWYgKHNhbXBsZXMgPj0gY291bnQpIHtcbiAgICAgICAgcmV0dXJuIGRhdGEuc2xpY2Uoc3RhcnQsIHN0YXJ0ICsgY291bnQpO1xuICAgIH1cbiAgICBjb25zdCBkZWNpbWF0ZWQgPSBbXTtcbiAgICBjb25zdCBidWNrZXRXaWR0aCA9IChjb3VudCAtIDIpIC8gKHNhbXBsZXMgLSAyKTtcbiAgICBsZXQgc2FtcGxlZEluZGV4ID0gMDtcbiAgICBjb25zdCBlbmRJbmRleCA9IHN0YXJ0ICsgY291bnQgLSAxO1xuICAgIGxldCBhID0gc3RhcnQ7XG4gICAgbGV0IGksIG1heEFyZWFQb2ludCwgbWF4QXJlYSwgYXJlYSwgbmV4dEE7XG4gICAgZGVjaW1hdGVkW3NhbXBsZWRJbmRleCsrXSA9IGRhdGFbYV07XG4gICAgZm9yKGkgPSAwOyBpIDwgc2FtcGxlcyAtIDI7IGkrKyl7XG4gICAgICAgIGxldCBhdmdYID0gMDtcbiAgICAgICAgbGV0IGF2Z1kgPSAwO1xuICAgICAgICBsZXQgajtcbiAgICAgICAgY29uc3QgYXZnUmFuZ2VTdGFydCA9IE1hdGguZmxvb3IoKGkgKyAxKSAqIGJ1Y2tldFdpZHRoKSArIDEgKyBzdGFydDtcbiAgICAgICAgY29uc3QgYXZnUmFuZ2VFbmQgPSBNYXRoLm1pbihNYXRoLmZsb29yKChpICsgMikgKiBidWNrZXRXaWR0aCkgKyAxLCBjb3VudCkgKyBzdGFydDtcbiAgICAgICAgY29uc3QgYXZnUmFuZ2VMZW5ndGggPSBhdmdSYW5nZUVuZCAtIGF2Z1JhbmdlU3RhcnQ7XG4gICAgICAgIGZvcihqID0gYXZnUmFuZ2VTdGFydDsgaiA8IGF2Z1JhbmdlRW5kOyBqKyspe1xuICAgICAgICAgICAgYXZnWCArPSBkYXRhW2pdLng7XG4gICAgICAgICAgICBhdmdZICs9IGRhdGFbal0ueTtcbiAgICAgICAgfVxuICAgICAgICBhdmdYIC89IGF2Z1JhbmdlTGVuZ3RoO1xuICAgICAgICBhdmdZIC89IGF2Z1JhbmdlTGVuZ3RoO1xuICAgICAgICBjb25zdCByYW5nZU9mZnMgPSBNYXRoLmZsb29yKGkgKiBidWNrZXRXaWR0aCkgKyAxICsgc3RhcnQ7XG4gICAgICAgIGNvbnN0IHJhbmdlVG8gPSBNYXRoLm1pbihNYXRoLmZsb29yKChpICsgMSkgKiBidWNrZXRXaWR0aCkgKyAxLCBjb3VudCkgKyBzdGFydDtcbiAgICAgICAgY29uc3QgeyB4OiBwb2ludEF4ICwgeTogcG9pbnRBeSAgfSA9IGRhdGFbYV07XG4gICAgICAgIG1heEFyZWEgPSBhcmVhID0gLTE7XG4gICAgICAgIGZvcihqID0gcmFuZ2VPZmZzOyBqIDwgcmFuZ2VUbzsgaisrKXtcbiAgICAgICAgICAgIGFyZWEgPSAwLjUgKiBNYXRoLmFicygocG9pbnRBeCAtIGF2Z1gpICogKGRhdGFbal0ueSAtIHBvaW50QXkpIC0gKHBvaW50QXggLSBkYXRhW2pdLngpICogKGF2Z1kgLSBwb2ludEF5KSk7XG4gICAgICAgICAgICBpZiAoYXJlYSA+IG1heEFyZWEpIHtcbiAgICAgICAgICAgICAgICBtYXhBcmVhID0gYXJlYTtcbiAgICAgICAgICAgICAgICBtYXhBcmVhUG9pbnQgPSBkYXRhW2pdO1xuICAgICAgICAgICAgICAgIG5leHRBID0gajtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBkZWNpbWF0ZWRbc2FtcGxlZEluZGV4KytdID0gbWF4QXJlYVBvaW50O1xuICAgICAgICBhID0gbmV4dEE7XG4gICAgfVxuICAgIGRlY2ltYXRlZFtzYW1wbGVkSW5kZXgrK10gPSBkYXRhW2VuZEluZGV4XTtcbiAgICByZXR1cm4gZGVjaW1hdGVkO1xufVxuZnVuY3Rpb24gbWluTWF4RGVjaW1hdGlvbihkYXRhLCBzdGFydCwgY291bnQsIGF2YWlsYWJsZVdpZHRoKSB7XG4gICAgbGV0IGF2Z1ggPSAwO1xuICAgIGxldCBjb3VudFggPSAwO1xuICAgIGxldCBpLCBwb2ludCwgeCwgeSwgcHJldlgsIG1pbkluZGV4LCBtYXhJbmRleCwgc3RhcnRJbmRleCwgbWluWSwgbWF4WTtcbiAgICBjb25zdCBkZWNpbWF0ZWQgPSBbXTtcbiAgICBjb25zdCBlbmRJbmRleCA9IHN0YXJ0ICsgY291bnQgLSAxO1xuICAgIGNvbnN0IHhNaW4gPSBkYXRhW3N0YXJ0XS54O1xuICAgIGNvbnN0IHhNYXggPSBkYXRhW2VuZEluZGV4XS54O1xuICAgIGNvbnN0IGR4ID0geE1heCAtIHhNaW47XG4gICAgZm9yKGkgPSBzdGFydDsgaSA8IHN0YXJ0ICsgY291bnQ7ICsraSl7XG4gICAgICAgIHBvaW50ID0gZGF0YVtpXTtcbiAgICAgICAgeCA9IChwb2ludC54IC0geE1pbikgLyBkeCAqIGF2YWlsYWJsZVdpZHRoO1xuICAgICAgICB5ID0gcG9pbnQueTtcbiAgICAgICAgY29uc3QgdHJ1bmNYID0geCB8IDA7XG4gICAgICAgIGlmICh0cnVuY1ggPT09IHByZXZYKSB7XG4gICAgICAgICAgICBpZiAoeSA8IG1pblkpIHtcbiAgICAgICAgICAgICAgICBtaW5ZID0geTtcbiAgICAgICAgICAgICAgICBtaW5JbmRleCA9IGk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHkgPiBtYXhZKSB7XG4gICAgICAgICAgICAgICAgbWF4WSA9IHk7XG4gICAgICAgICAgICAgICAgbWF4SW5kZXggPSBpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXZnWCA9IChjb3VudFggKiBhdmdYICsgcG9pbnQueCkgLyArK2NvdW50WDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGxhc3RJbmRleCA9IGkgLSAxO1xuICAgICAgICAgICAgaWYgKCFpc051bGxPclVuZGVmKG1pbkluZGV4KSAmJiAhaXNOdWxsT3JVbmRlZihtYXhJbmRleCkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBpbnRlcm1lZGlhdGVJbmRleDEgPSBNYXRoLm1pbihtaW5JbmRleCwgbWF4SW5kZXgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGludGVybWVkaWF0ZUluZGV4MiA9IE1hdGgubWF4KG1pbkluZGV4LCBtYXhJbmRleCk7XG4gICAgICAgICAgICAgICAgaWYgKGludGVybWVkaWF0ZUluZGV4MSAhPT0gc3RhcnRJbmRleCAmJiBpbnRlcm1lZGlhdGVJbmRleDEgIT09IGxhc3RJbmRleCkge1xuICAgICAgICAgICAgICAgICAgICBkZWNpbWF0ZWQucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAuLi5kYXRhW2ludGVybWVkaWF0ZUluZGV4MV0sXG4gICAgICAgICAgICAgICAgICAgICAgICB4OiBhdmdYXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoaW50ZXJtZWRpYXRlSW5kZXgyICE9PSBzdGFydEluZGV4ICYmIGludGVybWVkaWF0ZUluZGV4MiAhPT0gbGFzdEluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgIGRlY2ltYXRlZC5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC4uLmRhdGFbaW50ZXJtZWRpYXRlSW5kZXgyXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHg6IGF2Z1hcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGkgPiAwICYmIGxhc3RJbmRleCAhPT0gc3RhcnRJbmRleCkge1xuICAgICAgICAgICAgICAgIGRlY2ltYXRlZC5wdXNoKGRhdGFbbGFzdEluZGV4XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWNpbWF0ZWQucHVzaChwb2ludCk7XG4gICAgICAgICAgICBwcmV2WCA9IHRydW5jWDtcbiAgICAgICAgICAgIGNvdW50WCA9IDA7XG4gICAgICAgICAgICBtaW5ZID0gbWF4WSA9IHk7XG4gICAgICAgICAgICBtaW5JbmRleCA9IG1heEluZGV4ID0gc3RhcnRJbmRleCA9IGk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGRlY2ltYXRlZDtcbn1cbmZ1bmN0aW9uIGNsZWFuRGVjaW1hdGVkRGF0YXNldChkYXRhc2V0KSB7XG4gICAgaWYgKGRhdGFzZXQuX2RlY2ltYXRlZCkge1xuICAgICAgICBjb25zdCBkYXRhID0gZGF0YXNldC5fZGF0YTtcbiAgICAgICAgZGVsZXRlIGRhdGFzZXQuX2RlY2ltYXRlZDtcbiAgICAgICAgZGVsZXRlIGRhdGFzZXQuX2RhdGE7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShkYXRhc2V0LCAnZGF0YScsIHtcbiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIHZhbHVlOiBkYXRhXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGNsZWFuRGVjaW1hdGVkRGF0YShjaGFydCkge1xuICAgIGNoYXJ0LmRhdGEuZGF0YXNldHMuZm9yRWFjaCgoZGF0YXNldCk9PntcbiAgICAgICAgY2xlYW5EZWNpbWF0ZWREYXRhc2V0KGRhdGFzZXQpO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gZ2V0U3RhcnRBbmRDb3VudE9mVmlzaWJsZVBvaW50c1NpbXBsaWZpZWQobWV0YSwgcG9pbnRzKSB7XG4gICAgY29uc3QgcG9pbnRDb3VudCA9IHBvaW50cy5sZW5ndGg7XG4gICAgbGV0IHN0YXJ0ID0gMDtcbiAgICBsZXQgY291bnQ7XG4gICAgY29uc3QgeyBpU2NhbGUgIH0gPSBtZXRhO1xuICAgIGNvbnN0IHsgbWluICwgbWF4ICwgbWluRGVmaW5lZCAsIG1heERlZmluZWQgIH0gPSBpU2NhbGUuZ2V0VXNlckJvdW5kcygpO1xuICAgIGlmIChtaW5EZWZpbmVkKSB7XG4gICAgICAgIHN0YXJ0ID0gX2xpbWl0VmFsdWUoX2xvb2t1cEJ5S2V5KHBvaW50cywgaVNjYWxlLmF4aXMsIG1pbikubG8sIDAsIHBvaW50Q291bnQgLSAxKTtcbiAgICB9XG4gICAgaWYgKG1heERlZmluZWQpIHtcbiAgICAgICAgY291bnQgPSBfbGltaXRWYWx1ZShfbG9va3VwQnlLZXkocG9pbnRzLCBpU2NhbGUuYXhpcywgbWF4KS5oaSArIDEsIHN0YXJ0LCBwb2ludENvdW50KSAtIHN0YXJ0O1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGNvdW50ID0gcG9pbnRDb3VudCAtIHN0YXJ0O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBzdGFydCxcbiAgICAgICAgY291bnRcbiAgICB9O1xufVxudmFyIHBsdWdpbl9kZWNpbWF0aW9uID0ge1xuICAgIGlkOiAnZGVjaW1hdGlvbicsXG4gICAgZGVmYXVsdHM6IHtcbiAgICAgICAgYWxnb3JpdGhtOiAnbWluLW1heCcsXG4gICAgICAgIGVuYWJsZWQ6IGZhbHNlXG4gICAgfSxcbiAgICBiZWZvcmVFbGVtZW50c1VwZGF0ZTogKGNoYXJ0LCBhcmdzLCBvcHRpb25zKT0+e1xuICAgICAgICBpZiAoIW9wdGlvbnMuZW5hYmxlZCkge1xuICAgICAgICAgICAgY2xlYW5EZWNpbWF0ZWREYXRhKGNoYXJ0KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhdmFpbGFibGVXaWR0aCA9IGNoYXJ0LndpZHRoO1xuICAgICAgICBjaGFydC5kYXRhLmRhdGFzZXRzLmZvckVhY2goKGRhdGFzZXQsIGRhdGFzZXRJbmRleCk9PntcbiAgICAgICAgICAgIGNvbnN0IHsgX2RhdGEgLCBpbmRleEF4aXMgIH0gPSBkYXRhc2V0O1xuICAgICAgICAgICAgY29uc3QgbWV0YSA9IGNoYXJ0LmdldERhdGFzZXRNZXRhKGRhdGFzZXRJbmRleCk7XG4gICAgICAgICAgICBjb25zdCBkYXRhID0gX2RhdGEgfHwgZGF0YXNldC5kYXRhO1xuICAgICAgICAgICAgaWYgKHJlc29sdmUoW1xuICAgICAgICAgICAgICAgIGluZGV4QXhpcyxcbiAgICAgICAgICAgICAgICBjaGFydC5vcHRpb25zLmluZGV4QXhpc1xuICAgICAgICAgICAgXSkgPT09ICd5Jykge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghbWV0YS5jb250cm9sbGVyLnN1cHBvcnRzRGVjaW1hdGlvbikge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHhBeGlzID0gY2hhcnQuc2NhbGVzW21ldGEueEF4aXNJRF07XG4gICAgICAgICAgICBpZiAoeEF4aXMudHlwZSAhPT0gJ2xpbmVhcicgJiYgeEF4aXMudHlwZSAhPT0gJ3RpbWUnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNoYXJ0Lm9wdGlvbnMucGFyc2luZykge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCB7IHN0YXJ0ICwgY291bnQgIH0gPSBnZXRTdGFydEFuZENvdW50T2ZWaXNpYmxlUG9pbnRzU2ltcGxpZmllZChtZXRhLCBkYXRhKTtcbiAgICAgICAgICAgIGNvbnN0IHRocmVzaG9sZCA9IG9wdGlvbnMudGhyZXNob2xkIHx8IDQgKiBhdmFpbGFibGVXaWR0aDtcbiAgICAgICAgICAgIGlmIChjb3VudCA8PSB0aHJlc2hvbGQpIHtcbiAgICAgICAgICAgICAgICBjbGVhbkRlY2ltYXRlZERhdGFzZXQoZGF0YXNldCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzTnVsbE9yVW5kZWYoX2RhdGEpKSB7XG4gICAgICAgICAgICAgICAgZGF0YXNldC5fZGF0YSA9IGRhdGE7XG4gICAgICAgICAgICAgICAgZGVsZXRlIGRhdGFzZXQuZGF0YTtcbiAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZGF0YXNldCwgJ2RhdGEnLCB7XG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZWNpbWF0ZWQ7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHNldDogZnVuY3Rpb24oZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fZGF0YSA9IGQ7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBkZWNpbWF0ZWQ7XG4gICAgICAgICAgICBzd2l0Y2gob3B0aW9ucy5hbGdvcml0aG0pe1xuICAgICAgICAgICAgICAgIGNhc2UgJ2x0dGInOlxuICAgICAgICAgICAgICAgICAgICBkZWNpbWF0ZWQgPSBsdHRiRGVjaW1hdGlvbihkYXRhLCBzdGFydCwgY291bnQsIGF2YWlsYWJsZVdpZHRoLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnbWluLW1heCc6XG4gICAgICAgICAgICAgICAgICAgIGRlY2ltYXRlZCA9IG1pbk1heERlY2ltYXRpb24oZGF0YSwgc3RhcnQsIGNvdW50LCBhdmFpbGFibGVXaWR0aCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgZGVjaW1hdGlvbiBhbGdvcml0aG0gJyR7b3B0aW9ucy5hbGdvcml0aG19J2ApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGF0YXNldC5fZGVjaW1hdGVkID0gZGVjaW1hdGVkO1xuICAgICAgICB9KTtcbiAgICB9LFxuICAgIGRlc3Ryb3kgKGNoYXJ0KSB7XG4gICAgICAgIGNsZWFuRGVjaW1hdGVkRGF0YShjaGFydCk7XG4gICAgfVxufTtcblxuZnVuY3Rpb24gX3NlZ21lbnRzKGxpbmUsIHRhcmdldCwgcHJvcGVydHkpIHtcbiAgICBjb25zdCBzZWdtZW50cyA9IGxpbmUuc2VnbWVudHM7XG4gICAgY29uc3QgcG9pbnRzID0gbGluZS5wb2ludHM7XG4gICAgY29uc3QgdHBvaW50cyA9IHRhcmdldC5wb2ludHM7XG4gICAgY29uc3QgcGFydHMgPSBbXTtcbiAgICBmb3IgKGNvbnN0IHNlZ21lbnQgb2Ygc2VnbWVudHMpe1xuICAgICAgICBsZXQgeyBzdGFydCAsIGVuZCAgfSA9IHNlZ21lbnQ7XG4gICAgICAgIGVuZCA9IF9maW5kU2VnbWVudEVuZChzdGFydCwgZW5kLCBwb2ludHMpO1xuICAgICAgICBjb25zdCBib3VuZHMgPSBfZ2V0Qm91bmRzKHByb3BlcnR5LCBwb2ludHNbc3RhcnRdLCBwb2ludHNbZW5kXSwgc2VnbWVudC5sb29wKTtcbiAgICAgICAgaWYgKCF0YXJnZXQuc2VnbWVudHMpIHtcbiAgICAgICAgICAgIHBhcnRzLnB1c2goe1xuICAgICAgICAgICAgICAgIHNvdXJjZTogc2VnbWVudCxcbiAgICAgICAgICAgICAgICB0YXJnZXQ6IGJvdW5kcyxcbiAgICAgICAgICAgICAgICBzdGFydDogcG9pbnRzW3N0YXJ0XSxcbiAgICAgICAgICAgICAgICBlbmQ6IHBvaW50c1tlbmRdXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHRhcmdldFNlZ21lbnRzID0gX2JvdW5kU2VnbWVudHModGFyZ2V0LCBib3VuZHMpO1xuICAgICAgICBmb3IgKGNvbnN0IHRndCBvZiB0YXJnZXRTZWdtZW50cyl7XG4gICAgICAgICAgICBjb25zdCBzdWJCb3VuZHMgPSBfZ2V0Qm91bmRzKHByb3BlcnR5LCB0cG9pbnRzW3RndC5zdGFydF0sIHRwb2ludHNbdGd0LmVuZF0sIHRndC5sb29wKTtcbiAgICAgICAgICAgIGNvbnN0IGZpbGxTb3VyY2VzID0gX2JvdW5kU2VnbWVudChzZWdtZW50LCBwb2ludHMsIHN1YkJvdW5kcyk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGZpbGxTb3VyY2Ugb2YgZmlsbFNvdXJjZXMpe1xuICAgICAgICAgICAgICAgIHBhcnRzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBzb3VyY2U6IGZpbGxTb3VyY2UsXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldDogdGd0LFxuICAgICAgICAgICAgICAgICAgICBzdGFydDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgW3Byb3BlcnR5XTogX2dldEVkZ2UoYm91bmRzLCBzdWJCb3VuZHMsICdzdGFydCcsIE1hdGgubWF4KVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBlbmQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9wZXJ0eV06IF9nZXRFZGdlKGJvdW5kcywgc3ViQm91bmRzLCAnZW5kJywgTWF0aC5taW4pXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcGFydHM7XG59XG5mdW5jdGlvbiBfZ2V0Qm91bmRzKHByb3BlcnR5LCBmaXJzdCwgbGFzdCwgbG9vcCkge1xuICAgIGlmIChsb29wKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IHN0YXJ0ID0gZmlyc3RbcHJvcGVydHldO1xuICAgIGxldCBlbmQgPSBsYXN0W3Byb3BlcnR5XTtcbiAgICBpZiAocHJvcGVydHkgPT09ICdhbmdsZScpIHtcbiAgICAgICAgc3RhcnQgPSBfbm9ybWFsaXplQW5nbGUoc3RhcnQpO1xuICAgICAgICBlbmQgPSBfbm9ybWFsaXplQW5nbGUoZW5kKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgcHJvcGVydHksXG4gICAgICAgIHN0YXJ0LFxuICAgICAgICBlbmRcbiAgICB9O1xufVxuZnVuY3Rpb24gX3BvaW50c0Zyb21TZWdtZW50cyhib3VuZGFyeSwgbGluZSkge1xuICAgIGNvbnN0IHsgeCA9bnVsbCAsIHkgPW51bGwgIH0gPSBib3VuZGFyeSB8fCB7fTtcbiAgICBjb25zdCBsaW5lUG9pbnRzID0gbGluZS5wb2ludHM7XG4gICAgY29uc3QgcG9pbnRzID0gW107XG4gICAgbGluZS5zZWdtZW50cy5mb3JFYWNoKCh7IHN0YXJ0ICwgZW5kICB9KT0+e1xuICAgICAgICBlbmQgPSBfZmluZFNlZ21lbnRFbmQoc3RhcnQsIGVuZCwgbGluZVBvaW50cyk7XG4gICAgICAgIGNvbnN0IGZpcnN0ID0gbGluZVBvaW50c1tzdGFydF07XG4gICAgICAgIGNvbnN0IGxhc3QgPSBsaW5lUG9pbnRzW2VuZF07XG4gICAgICAgIGlmICh5ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBwb2ludHMucHVzaCh7XG4gICAgICAgICAgICAgICAgeDogZmlyc3QueCxcbiAgICAgICAgICAgICAgICB5XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKHtcbiAgICAgICAgICAgICAgICB4OiBsYXN0LngsXG4gICAgICAgICAgICAgICAgeVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoeCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgcG9pbnRzLnB1c2goe1xuICAgICAgICAgICAgICAgIHgsXG4gICAgICAgICAgICAgICAgeTogZmlyc3QueVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBwb2ludHMucHVzaCh7XG4gICAgICAgICAgICAgICAgeCxcbiAgICAgICAgICAgICAgICB5OiBsYXN0LnlcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHBvaW50cztcbn1cbmZ1bmN0aW9uIF9maW5kU2VnbWVudEVuZChzdGFydCwgZW5kLCBwb2ludHMpIHtcbiAgICBmb3IoOyBlbmQgPiBzdGFydDsgZW5kLS0pe1xuICAgICAgICBjb25zdCBwb2ludCA9IHBvaW50c1tlbmRdO1xuICAgICAgICBpZiAoIWlzTmFOKHBvaW50LngpICYmICFpc05hTihwb2ludC55KSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGVuZDtcbn1cbmZ1bmN0aW9uIF9nZXRFZGdlKGEsIGIsIHByb3AsIGZuKSB7XG4gICAgaWYgKGEgJiYgYikge1xuICAgICAgICByZXR1cm4gZm4oYVtwcm9wXSwgYltwcm9wXSk7XG4gICAgfVxuICAgIHJldHVybiBhID8gYVtwcm9wXSA6IGIgPyBiW3Byb3BdIDogMDtcbn1cblxuZnVuY3Rpb24gX2NyZWF0ZUJvdW5kYXJ5TGluZShib3VuZGFyeSwgbGluZSkge1xuICAgIGxldCBwb2ludHMgPSBbXTtcbiAgICBsZXQgX2xvb3AgPSBmYWxzZTtcbiAgICBpZiAoaXNBcnJheShib3VuZGFyeSkpIHtcbiAgICAgICAgX2xvb3AgPSB0cnVlO1xuICAgICAgICBwb2ludHMgPSBib3VuZGFyeTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBwb2ludHMgPSBfcG9pbnRzRnJvbVNlZ21lbnRzKGJvdW5kYXJ5LCBsaW5lKTtcbiAgICB9XG4gICAgcmV0dXJuIHBvaW50cy5sZW5ndGggPyBuZXcgTGluZUVsZW1lbnQoe1xuICAgICAgICBwb2ludHMsXG4gICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICAgIHRlbnNpb246IDBcbiAgICAgICAgfSxcbiAgICAgICAgX2xvb3AsXG4gICAgICAgIF9mdWxsTG9vcDogX2xvb3BcbiAgICB9KSA6IG51bGw7XG59XG5mdW5jdGlvbiBfc2hvdWxkQXBwbHlGaWxsKHNvdXJjZSkge1xuICAgIHJldHVybiBzb3VyY2UgJiYgc291cmNlLmZpbGwgIT09IGZhbHNlO1xufVxuXG5mdW5jdGlvbiBfcmVzb2x2ZVRhcmdldChzb3VyY2VzLCBpbmRleCwgcHJvcGFnYXRlKSB7XG4gICAgY29uc3Qgc291cmNlID0gc291cmNlc1tpbmRleF07XG4gICAgbGV0IGZpbGwgPSBzb3VyY2UuZmlsbDtcbiAgICBjb25zdCB2aXNpdGVkID0gW1xuICAgICAgICBpbmRleFxuICAgIF07XG4gICAgbGV0IHRhcmdldDtcbiAgICBpZiAoIXByb3BhZ2F0ZSkge1xuICAgICAgICByZXR1cm4gZmlsbDtcbiAgICB9XG4gICAgd2hpbGUoZmlsbCAhPT0gZmFsc2UgJiYgdmlzaXRlZC5pbmRleE9mKGZpbGwpID09PSAtMSl7XG4gICAgICAgIGlmICghaXNOdW1iZXJGaW5pdGUoZmlsbCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmaWxsO1xuICAgICAgICB9XG4gICAgICAgIHRhcmdldCA9IHNvdXJjZXNbZmlsbF07XG4gICAgICAgIGlmICghdGFyZ2V0KSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRhcmdldC52aXNpYmxlKSB7XG4gICAgICAgICAgICByZXR1cm4gZmlsbDtcbiAgICAgICAgfVxuICAgICAgICB2aXNpdGVkLnB1c2goZmlsbCk7XG4gICAgICAgIGZpbGwgPSB0YXJnZXQuZmlsbDtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuIGZ1bmN0aW9uIF9kZWNvZGVGaWxsKGxpbmUsIGluZGV4LCBjb3VudCkge1xuICAgICBjb25zdCBmaWxsID0gcGFyc2VGaWxsT3B0aW9uKGxpbmUpO1xuICAgIGlmIChpc09iamVjdChmaWxsKSkge1xuICAgICAgICByZXR1cm4gaXNOYU4oZmlsbC52YWx1ZSkgPyBmYWxzZSA6IGZpbGw7XG4gICAgfVxuICAgIGxldCB0YXJnZXQgPSBwYXJzZUZsb2F0KGZpbGwpO1xuICAgIGlmIChpc051bWJlckZpbml0ZSh0YXJnZXQpICYmIE1hdGguZmxvb3IodGFyZ2V0KSA9PT0gdGFyZ2V0KSB7XG4gICAgICAgIHJldHVybiBkZWNvZGVUYXJnZXRJbmRleChmaWxsWzBdLCBpbmRleCwgdGFyZ2V0LCBjb3VudCk7XG4gICAgfVxuICAgIHJldHVybiBbXG4gICAgICAgICdvcmlnaW4nLFxuICAgICAgICAnc3RhcnQnLFxuICAgICAgICAnZW5kJyxcbiAgICAgICAgJ3N0YWNrJyxcbiAgICAgICAgJ3NoYXBlJ1xuICAgIF0uaW5kZXhPZihmaWxsKSA+PSAwICYmIGZpbGw7XG59XG5mdW5jdGlvbiBkZWNvZGVUYXJnZXRJbmRleChmaXJzdENoLCBpbmRleCwgdGFyZ2V0LCBjb3VudCkge1xuICAgIGlmIChmaXJzdENoID09PSAnLScgfHwgZmlyc3RDaCA9PT0gJysnKSB7XG4gICAgICAgIHRhcmdldCA9IGluZGV4ICsgdGFyZ2V0O1xuICAgIH1cbiAgICBpZiAodGFyZ2V0ID09PSBpbmRleCB8fCB0YXJnZXQgPCAwIHx8IHRhcmdldCA+PSBjb3VudCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0YXJnZXQ7XG59XG4gZnVuY3Rpb24gX2dldFRhcmdldFBpeGVsKGZpbGwsIHNjYWxlKSB7XG4gICAgbGV0IHBpeGVsID0gbnVsbDtcbiAgICBpZiAoZmlsbCA9PT0gJ3N0YXJ0Jykge1xuICAgICAgICBwaXhlbCA9IHNjYWxlLmJvdHRvbTtcbiAgICB9IGVsc2UgaWYgKGZpbGwgPT09ICdlbmQnKSB7XG4gICAgICAgIHBpeGVsID0gc2NhbGUudG9wO1xuICAgIH0gZWxzZSBpZiAoaXNPYmplY3QoZmlsbCkpIHtcbiAgICAgICAgcGl4ZWwgPSBzY2FsZS5nZXRQaXhlbEZvclZhbHVlKGZpbGwudmFsdWUpO1xuICAgIH0gZWxzZSBpZiAoc2NhbGUuZ2V0QmFzZVBpeGVsKSB7XG4gICAgICAgIHBpeGVsID0gc2NhbGUuZ2V0QmFzZVBpeGVsKCk7XG4gICAgfVxuICAgIHJldHVybiBwaXhlbDtcbn1cbiBmdW5jdGlvbiBfZ2V0VGFyZ2V0VmFsdWUoZmlsbCwgc2NhbGUsIHN0YXJ0VmFsdWUpIHtcbiAgICBsZXQgdmFsdWU7XG4gICAgaWYgKGZpbGwgPT09ICdzdGFydCcpIHtcbiAgICAgICAgdmFsdWUgPSBzdGFydFZhbHVlO1xuICAgIH0gZWxzZSBpZiAoZmlsbCA9PT0gJ2VuZCcpIHtcbiAgICAgICAgdmFsdWUgPSBzY2FsZS5vcHRpb25zLnJldmVyc2UgPyBzY2FsZS5taW4gOiBzY2FsZS5tYXg7XG4gICAgfSBlbHNlIGlmIChpc09iamVjdChmaWxsKSkge1xuICAgICAgICB2YWx1ZSA9IGZpbGwudmFsdWU7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmFsdWUgPSBzY2FsZS5nZXRCYXNlVmFsdWUoKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuIGZ1bmN0aW9uIHBhcnNlRmlsbE9wdGlvbihsaW5lKSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IGxpbmUub3B0aW9ucztcbiAgICBjb25zdCBmaWxsT3B0aW9uID0gb3B0aW9ucy5maWxsO1xuICAgIGxldCBmaWxsID0gdmFsdWVPckRlZmF1bHQoZmlsbE9wdGlvbiAmJiBmaWxsT3B0aW9uLnRhcmdldCwgZmlsbE9wdGlvbik7XG4gICAgaWYgKGZpbGwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBmaWxsID0gISFvcHRpb25zLmJhY2tncm91bmRDb2xvcjtcbiAgICB9XG4gICAgaWYgKGZpbGwgPT09IGZhbHNlIHx8IGZpbGwgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoZmlsbCA9PT0gdHJ1ZSkge1xuICAgICAgICByZXR1cm4gJ29yaWdpbic7XG4gICAgfVxuICAgIHJldHVybiBmaWxsO1xufVxuXG5mdW5jdGlvbiBfYnVpbGRTdGFja0xpbmUoc291cmNlKSB7XG4gICAgY29uc3QgeyBzY2FsZSAsIGluZGV4ICwgbGluZSAgfSA9IHNvdXJjZTtcbiAgICBjb25zdCBwb2ludHMgPSBbXTtcbiAgICBjb25zdCBzZWdtZW50cyA9IGxpbmUuc2VnbWVudHM7XG4gICAgY29uc3Qgc291cmNlUG9pbnRzID0gbGluZS5wb2ludHM7XG4gICAgY29uc3QgbGluZXNCZWxvdyA9IGdldExpbmVzQmVsb3coc2NhbGUsIGluZGV4KTtcbiAgICBsaW5lc0JlbG93LnB1c2goX2NyZWF0ZUJvdW5kYXJ5TGluZSh7XG4gICAgICAgIHg6IG51bGwsXG4gICAgICAgIHk6IHNjYWxlLmJvdHRvbVxuICAgIH0sIGxpbmUpKTtcbiAgICBmb3IobGV0IGkgPSAwOyBpIDwgc2VnbWVudHMubGVuZ3RoOyBpKyspe1xuICAgICAgICBjb25zdCBzZWdtZW50ID0gc2VnbWVudHNbaV07XG4gICAgICAgIGZvcihsZXQgaiA9IHNlZ21lbnQuc3RhcnQ7IGogPD0gc2VnbWVudC5lbmQ7IGorKyl7XG4gICAgICAgICAgICBhZGRQb2ludHNCZWxvdyhwb2ludHMsIHNvdXJjZVBvaW50c1tqXSwgbGluZXNCZWxvdyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5ldyBMaW5lRWxlbWVudCh7XG4gICAgICAgIHBvaW50cyxcbiAgICAgICAgb3B0aW9uczoge31cbiAgICB9KTtcbn1cbiBmdW5jdGlvbiBnZXRMaW5lc0JlbG93KHNjYWxlLCBpbmRleCkge1xuICAgIGNvbnN0IGJlbG93ID0gW107XG4gICAgY29uc3QgbWV0YXMgPSBzY2FsZS5nZXRNYXRjaGluZ1Zpc2libGVNZXRhcygnbGluZScpO1xuICAgIGZvcihsZXQgaSA9IDA7IGkgPCBtZXRhcy5sZW5ndGg7IGkrKyl7XG4gICAgICAgIGNvbnN0IG1ldGEgPSBtZXRhc1tpXTtcbiAgICAgICAgaWYgKG1ldGEuaW5kZXggPT09IGluZGV4KSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoIW1ldGEuaGlkZGVuKSB7XG4gICAgICAgICAgICBiZWxvdy51bnNoaWZ0KG1ldGEuZGF0YXNldCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGJlbG93O1xufVxuIGZ1bmN0aW9uIGFkZFBvaW50c0JlbG93KHBvaW50cywgc291cmNlUG9pbnQsIGxpbmVzQmVsb3cpIHtcbiAgICBjb25zdCBwb3N0cG9uZWQgPSBbXTtcbiAgICBmb3IobGV0IGogPSAwOyBqIDwgbGluZXNCZWxvdy5sZW5ndGg7IGorKyl7XG4gICAgICAgIGNvbnN0IGxpbmUgPSBsaW5lc0JlbG93W2pdO1xuICAgICAgICBjb25zdCB7IGZpcnN0ICwgbGFzdCAsIHBvaW50ICB9ID0gZmluZFBvaW50KGxpbmUsIHNvdXJjZVBvaW50LCAneCcpO1xuICAgICAgICBpZiAoIXBvaW50IHx8IGZpcnN0ICYmIGxhc3QpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmaXJzdCkge1xuICAgICAgICAgICAgcG9zdHBvbmVkLnVuc2hpZnQocG9pbnQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcG9pbnRzLnB1c2gocG9pbnQpO1xuICAgICAgICAgICAgaWYgKCFsYXN0KSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcG9pbnRzLnB1c2goLi4ucG9zdHBvbmVkKTtcbn1cbiBmdW5jdGlvbiBmaW5kUG9pbnQobGluZSwgc291cmNlUG9pbnQsIHByb3BlcnR5KSB7XG4gICAgY29uc3QgcG9pbnQgPSBsaW5lLmludGVycG9sYXRlKHNvdXJjZVBvaW50LCBwcm9wZXJ0eSk7XG4gICAgaWYgKCFwb2ludCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNvbnN0IHBvaW50VmFsdWUgPSBwb2ludFtwcm9wZXJ0eV07XG4gICAgY29uc3Qgc2VnbWVudHMgPSBsaW5lLnNlZ21lbnRzO1xuICAgIGNvbnN0IGxpbmVQb2ludHMgPSBsaW5lLnBvaW50cztcbiAgICBsZXQgZmlyc3QgPSBmYWxzZTtcbiAgICBsZXQgbGFzdCA9IGZhbHNlO1xuICAgIGZvcihsZXQgaSA9IDA7IGkgPCBzZWdtZW50cy5sZW5ndGg7IGkrKyl7XG4gICAgICAgIGNvbnN0IHNlZ21lbnQgPSBzZWdtZW50c1tpXTtcbiAgICAgICAgY29uc3QgZmlyc3RWYWx1ZSA9IGxpbmVQb2ludHNbc2VnbWVudC5zdGFydF1bcHJvcGVydHldO1xuICAgICAgICBjb25zdCBsYXN0VmFsdWUgPSBsaW5lUG9pbnRzW3NlZ21lbnQuZW5kXVtwcm9wZXJ0eV07XG4gICAgICAgIGlmIChfaXNCZXR3ZWVuKHBvaW50VmFsdWUsIGZpcnN0VmFsdWUsIGxhc3RWYWx1ZSkpIHtcbiAgICAgICAgICAgIGZpcnN0ID0gcG9pbnRWYWx1ZSA9PT0gZmlyc3RWYWx1ZTtcbiAgICAgICAgICAgIGxhc3QgPSBwb2ludFZhbHVlID09PSBsYXN0VmFsdWU7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBmaXJzdCxcbiAgICAgICAgbGFzdCxcbiAgICAgICAgcG9pbnRcbiAgICB9O1xufVxuXG5jbGFzcyBzaW1wbGVBcmMge1xuICAgIGNvbnN0cnVjdG9yKG9wdHMpe1xuICAgICAgICB0aGlzLnggPSBvcHRzLng7XG4gICAgICAgIHRoaXMueSA9IG9wdHMueTtcbiAgICAgICAgdGhpcy5yYWRpdXMgPSBvcHRzLnJhZGl1cztcbiAgICB9XG4gICAgcGF0aFNlZ21lbnQoY3R4LCBib3VuZHMsIG9wdHMpIHtcbiAgICAgICAgY29uc3QgeyB4ICwgeSAsIHJhZGl1cyAgfSA9IHRoaXM7XG4gICAgICAgIGJvdW5kcyA9IGJvdW5kcyB8fCB7XG4gICAgICAgICAgICBzdGFydDogMCxcbiAgICAgICAgICAgIGVuZDogVEFVXG4gICAgICAgIH07XG4gICAgICAgIGN0eC5hcmMoeCwgeSwgcmFkaXVzLCBib3VuZHMuZW5kLCBib3VuZHMuc3RhcnQsIHRydWUpO1xuICAgICAgICByZXR1cm4gIW9wdHMuYm91bmRzO1xuICAgIH1cbiAgICBpbnRlcnBvbGF0ZShwb2ludCkge1xuICAgICAgICBjb25zdCB7IHggLCB5ICwgcmFkaXVzICB9ID0gdGhpcztcbiAgICAgICAgY29uc3QgYW5nbGUgPSBwb2ludC5hbmdsZTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IHggKyBNYXRoLmNvcyhhbmdsZSkgKiByYWRpdXMsXG4gICAgICAgICAgICB5OiB5ICsgTWF0aC5zaW4oYW5nbGUpICogcmFkaXVzLFxuICAgICAgICAgICAgYW5nbGVcbiAgICAgICAgfTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIF9nZXRUYXJnZXQoc291cmNlKSB7XG4gICAgY29uc3QgeyBjaGFydCAsIGZpbGwgLCBsaW5lICB9ID0gc291cmNlO1xuICAgIGlmIChpc051bWJlckZpbml0ZShmaWxsKSkge1xuICAgICAgICByZXR1cm4gZ2V0TGluZUJ5SW5kZXgoY2hhcnQsIGZpbGwpO1xuICAgIH1cbiAgICBpZiAoZmlsbCA9PT0gJ3N0YWNrJykge1xuICAgICAgICByZXR1cm4gX2J1aWxkU3RhY2tMaW5lKHNvdXJjZSk7XG4gICAgfVxuICAgIGlmIChmaWxsID09PSAnc2hhcGUnKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjb25zdCBib3VuZGFyeSA9IGNvbXB1dGVCb3VuZGFyeShzb3VyY2UpO1xuICAgIGlmIChib3VuZGFyeSBpbnN0YW5jZW9mIHNpbXBsZUFyYykge1xuICAgICAgICByZXR1cm4gYm91bmRhcnk7XG4gICAgfVxuICAgIHJldHVybiBfY3JlYXRlQm91bmRhcnlMaW5lKGJvdW5kYXJ5LCBsaW5lKTtcbn1cbiBmdW5jdGlvbiBnZXRMaW5lQnlJbmRleChjaGFydCwgaW5kZXgpIHtcbiAgICBjb25zdCBtZXRhID0gY2hhcnQuZ2V0RGF0YXNldE1ldGEoaW5kZXgpO1xuICAgIGNvbnN0IHZpc2libGUgPSBtZXRhICYmIGNoYXJ0LmlzRGF0YXNldFZpc2libGUoaW5kZXgpO1xuICAgIHJldHVybiB2aXNpYmxlID8gbWV0YS5kYXRhc2V0IDogbnVsbDtcbn1cbmZ1bmN0aW9uIGNvbXB1dGVCb3VuZGFyeShzb3VyY2UpIHtcbiAgICBjb25zdCBzY2FsZSA9IHNvdXJjZS5zY2FsZSB8fCB7fTtcbiAgICBpZiAoc2NhbGUuZ2V0UG9pbnRQb3NpdGlvbkZvclZhbHVlKSB7XG4gICAgICAgIHJldHVybiBjb21wdXRlQ2lyY3VsYXJCb3VuZGFyeShzb3VyY2UpO1xuICAgIH1cbiAgICByZXR1cm4gY29tcHV0ZUxpbmVhckJvdW5kYXJ5KHNvdXJjZSk7XG59XG5mdW5jdGlvbiBjb21wdXRlTGluZWFyQm91bmRhcnkoc291cmNlKSB7XG4gICAgY29uc3QgeyBzY2FsZSA9e30gLCBmaWxsICB9ID0gc291cmNlO1xuICAgIGNvbnN0IHBpeGVsID0gX2dldFRhcmdldFBpeGVsKGZpbGwsIHNjYWxlKTtcbiAgICBpZiAoaXNOdW1iZXJGaW5pdGUocGl4ZWwpKSB7XG4gICAgICAgIGNvbnN0IGhvcml6b250YWwgPSBzY2FsZS5pc0hvcml6b250YWwoKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IGhvcml6b250YWwgPyBwaXhlbCA6IG51bGwsXG4gICAgICAgICAgICB5OiBob3Jpem9udGFsID8gbnVsbCA6IHBpeGVsXG4gICAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuZnVuY3Rpb24gY29tcHV0ZUNpcmN1bGFyQm91bmRhcnkoc291cmNlKSB7XG4gICAgY29uc3QgeyBzY2FsZSAsIGZpbGwgIH0gPSBzb3VyY2U7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHNjYWxlLm9wdGlvbnM7XG4gICAgY29uc3QgbGVuZ3RoID0gc2NhbGUuZ2V0TGFiZWxzKCkubGVuZ3RoO1xuICAgIGNvbnN0IHN0YXJ0ID0gb3B0aW9ucy5yZXZlcnNlID8gc2NhbGUubWF4IDogc2NhbGUubWluO1xuICAgIGNvbnN0IHZhbHVlID0gX2dldFRhcmdldFZhbHVlKGZpbGwsIHNjYWxlLCBzdGFydCk7XG4gICAgY29uc3QgdGFyZ2V0ID0gW107XG4gICAgaWYgKG9wdGlvbnMuZ3JpZC5jaXJjdWxhcikge1xuICAgICAgICBjb25zdCBjZW50ZXIgPSBzY2FsZS5nZXRQb2ludFBvc2l0aW9uRm9yVmFsdWUoMCwgc3RhcnQpO1xuICAgICAgICByZXR1cm4gbmV3IHNpbXBsZUFyYyh7XG4gICAgICAgICAgICB4OiBjZW50ZXIueCxcbiAgICAgICAgICAgIHk6IGNlbnRlci55LFxuICAgICAgICAgICAgcmFkaXVzOiBzY2FsZS5nZXREaXN0YW5jZUZyb21DZW50ZXJGb3JWYWx1ZSh2YWx1ZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGZvcihsZXQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSl7XG4gICAgICAgIHRhcmdldC5wdXNoKHNjYWxlLmdldFBvaW50UG9zaXRpb25Gb3JWYWx1ZShpLCB2YWx1ZSkpO1xuICAgIH1cbiAgICByZXR1cm4gdGFyZ2V0O1xufVxuXG5mdW5jdGlvbiBfZHJhd2ZpbGwoY3R4LCBzb3VyY2UsIGFyZWEpIHtcbiAgICBjb25zdCB0YXJnZXQgPSBfZ2V0VGFyZ2V0KHNvdXJjZSk7XG4gICAgY29uc3QgeyBsaW5lICwgc2NhbGUgLCBheGlzICB9ID0gc291cmNlO1xuICAgIGNvbnN0IGxpbmVPcHRzID0gbGluZS5vcHRpb25zO1xuICAgIGNvbnN0IGZpbGxPcHRpb24gPSBsaW5lT3B0cy5maWxsO1xuICAgIGNvbnN0IGNvbG9yID0gbGluZU9wdHMuYmFja2dyb3VuZENvbG9yO1xuICAgIGNvbnN0IHsgYWJvdmUgPWNvbG9yICwgYmVsb3cgPWNvbG9yICB9ID0gZmlsbE9wdGlvbiB8fCB7fTtcbiAgICBpZiAodGFyZ2V0ICYmIGxpbmUucG9pbnRzLmxlbmd0aCkge1xuICAgICAgICBjbGlwQXJlYShjdHgsIGFyZWEpO1xuICAgICAgICBkb0ZpbGwoY3R4LCB7XG4gICAgICAgICAgICBsaW5lLFxuICAgICAgICAgICAgdGFyZ2V0LFxuICAgICAgICAgICAgYWJvdmUsXG4gICAgICAgICAgICBiZWxvdyxcbiAgICAgICAgICAgIGFyZWEsXG4gICAgICAgICAgICBzY2FsZSxcbiAgICAgICAgICAgIGF4aXNcbiAgICAgICAgfSk7XG4gICAgICAgIHVuY2xpcEFyZWEoY3R4KTtcbiAgICB9XG59XG5mdW5jdGlvbiBkb0ZpbGwoY3R4LCBjZmcpIHtcbiAgICBjb25zdCB7IGxpbmUgLCB0YXJnZXQgLCBhYm92ZSAsIGJlbG93ICwgYXJlYSAsIHNjYWxlICB9ID0gY2ZnO1xuICAgIGNvbnN0IHByb3BlcnR5ID0gbGluZS5fbG9vcCA/ICdhbmdsZScgOiBjZmcuYXhpcztcbiAgICBjdHguc2F2ZSgpO1xuICAgIGlmIChwcm9wZXJ0eSA9PT0gJ3gnICYmIGJlbG93ICE9PSBhYm92ZSkge1xuICAgICAgICBjbGlwVmVydGljYWwoY3R4LCB0YXJnZXQsIGFyZWEudG9wKTtcbiAgICAgICAgZmlsbChjdHgsIHtcbiAgICAgICAgICAgIGxpbmUsXG4gICAgICAgICAgICB0YXJnZXQsXG4gICAgICAgICAgICBjb2xvcjogYWJvdmUsXG4gICAgICAgICAgICBzY2FsZSxcbiAgICAgICAgICAgIHByb3BlcnR5XG4gICAgICAgIH0pO1xuICAgICAgICBjdHgucmVzdG9yZSgpO1xuICAgICAgICBjdHguc2F2ZSgpO1xuICAgICAgICBjbGlwVmVydGljYWwoY3R4LCB0YXJnZXQsIGFyZWEuYm90dG9tKTtcbiAgICB9XG4gICAgZmlsbChjdHgsIHtcbiAgICAgICAgbGluZSxcbiAgICAgICAgdGFyZ2V0LFxuICAgICAgICBjb2xvcjogYmVsb3csXG4gICAgICAgIHNjYWxlLFxuICAgICAgICBwcm9wZXJ0eVxuICAgIH0pO1xuICAgIGN0eC5yZXN0b3JlKCk7XG59XG5mdW5jdGlvbiBjbGlwVmVydGljYWwoY3R4LCB0YXJnZXQsIGNsaXBZKSB7XG4gICAgY29uc3QgeyBzZWdtZW50cyAsIHBvaW50cyAgfSA9IHRhcmdldDtcbiAgICBsZXQgZmlyc3QgPSB0cnVlO1xuICAgIGxldCBsaW5lTG9vcCA9IGZhbHNlO1xuICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICBmb3IgKGNvbnN0IHNlZ21lbnQgb2Ygc2VnbWVudHMpe1xuICAgICAgICBjb25zdCB7IHN0YXJ0ICwgZW5kICB9ID0gc2VnbWVudDtcbiAgICAgICAgY29uc3QgZmlyc3RQb2ludCA9IHBvaW50c1tzdGFydF07XG4gICAgICAgIGNvbnN0IGxhc3RQb2ludCA9IHBvaW50c1tfZmluZFNlZ21lbnRFbmQoc3RhcnQsIGVuZCwgcG9pbnRzKV07XG4gICAgICAgIGlmIChmaXJzdCkge1xuICAgICAgICAgICAgY3R4Lm1vdmVUbyhmaXJzdFBvaW50LngsIGZpcnN0UG9pbnQueSk7XG4gICAgICAgICAgICBmaXJzdCA9IGZhbHNlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY3R4LmxpbmVUbyhmaXJzdFBvaW50LngsIGNsaXBZKTtcbiAgICAgICAgICAgIGN0eC5saW5lVG8oZmlyc3RQb2ludC54LCBmaXJzdFBvaW50LnkpO1xuICAgICAgICB9XG4gICAgICAgIGxpbmVMb29wID0gISF0YXJnZXQucGF0aFNlZ21lbnQoY3R4LCBzZWdtZW50LCB7XG4gICAgICAgICAgICBtb3ZlOiBsaW5lTG9vcFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGxpbmVMb29wKSB7XG4gICAgICAgICAgICBjdHguY2xvc2VQYXRoKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjdHgubGluZVRvKGxhc3RQb2ludC54LCBjbGlwWSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY3R4LmxpbmVUbyh0YXJnZXQuZmlyc3QoKS54LCBjbGlwWSk7XG4gICAgY3R4LmNsb3NlUGF0aCgpO1xuICAgIGN0eC5jbGlwKCk7XG59XG5mdW5jdGlvbiBmaWxsKGN0eCwgY2ZnKSB7XG4gICAgY29uc3QgeyBsaW5lICwgdGFyZ2V0ICwgcHJvcGVydHkgLCBjb2xvciAsIHNjYWxlICB9ID0gY2ZnO1xuICAgIGNvbnN0IHNlZ21lbnRzID0gX3NlZ21lbnRzKGxpbmUsIHRhcmdldCwgcHJvcGVydHkpO1xuICAgIGZvciAoY29uc3QgeyBzb3VyY2U6IHNyYyAsIHRhcmdldDogdGd0ICwgc3RhcnQgLCBlbmQgIH0gb2Ygc2VnbWVudHMpe1xuICAgICAgICBjb25zdCB7IHN0eWxlOiB7IGJhY2tncm91bmRDb2xvciA9Y29sb3IgIH0gPSB7fSAgfSA9IHNyYztcbiAgICAgICAgY29uc3Qgbm90U2hhcGUgPSB0YXJnZXQgIT09IHRydWU7XG4gICAgICAgIGN0eC5zYXZlKCk7XG4gICAgICAgIGN0eC5maWxsU3R5bGUgPSBiYWNrZ3JvdW5kQ29sb3I7XG4gICAgICAgIGNsaXBCb3VuZHMoY3R4LCBzY2FsZSwgbm90U2hhcGUgJiYgX2dldEJvdW5kcyhwcm9wZXJ0eSwgc3RhcnQsIGVuZCkpO1xuICAgICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICAgIGNvbnN0IGxpbmVMb29wID0gISFsaW5lLnBhdGhTZWdtZW50KGN0eCwgc3JjKTtcbiAgICAgICAgbGV0IGxvb3A7XG4gICAgICAgIGlmIChub3RTaGFwZSkge1xuICAgICAgICAgICAgaWYgKGxpbmVMb29wKSB7XG4gICAgICAgICAgICAgICAgY3R4LmNsb3NlUGF0aCgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpbnRlcnBvbGF0ZWRMaW5lVG8oY3R4LCB0YXJnZXQsIGVuZCwgcHJvcGVydHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgdGFyZ2V0TG9vcCA9ICEhdGFyZ2V0LnBhdGhTZWdtZW50KGN0eCwgdGd0LCB7XG4gICAgICAgICAgICAgICAgbW92ZTogbGluZUxvb3AsXG4gICAgICAgICAgICAgICAgcmV2ZXJzZTogdHJ1ZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBsb29wID0gbGluZUxvb3AgJiYgdGFyZ2V0TG9vcDtcbiAgICAgICAgICAgIGlmICghbG9vcCkge1xuICAgICAgICAgICAgICAgIGludGVycG9sYXRlZExpbmVUbyhjdHgsIHRhcmdldCwgc3RhcnQsIHByb3BlcnR5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjdHguY2xvc2VQYXRoKCk7XG4gICAgICAgIGN0eC5maWxsKGxvb3AgPyAnZXZlbm9kZCcgOiAnbm9uemVybycpO1xuICAgICAgICBjdHgucmVzdG9yZSgpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGNsaXBCb3VuZHMoY3R4LCBzY2FsZSwgYm91bmRzKSB7XG4gICAgY29uc3QgeyB0b3AgLCBib3R0b20gIH0gPSBzY2FsZS5jaGFydC5jaGFydEFyZWE7XG4gICAgY29uc3QgeyBwcm9wZXJ0eSAsIHN0YXJ0ICwgZW5kICB9ID0gYm91bmRzIHx8IHt9O1xuICAgIGlmIChwcm9wZXJ0eSA9PT0gJ3gnKSB7XG4gICAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgICAgY3R4LnJlY3Qoc3RhcnQsIHRvcCwgZW5kIC0gc3RhcnQsIGJvdHRvbSAtIHRvcCk7XG4gICAgICAgIGN0eC5jbGlwKCk7XG4gICAgfVxufVxuZnVuY3Rpb24gaW50ZXJwb2xhdGVkTGluZVRvKGN0eCwgdGFyZ2V0LCBwb2ludCwgcHJvcGVydHkpIHtcbiAgICBjb25zdCBpbnRlcnBvbGF0ZWRQb2ludCA9IHRhcmdldC5pbnRlcnBvbGF0ZShwb2ludCwgcHJvcGVydHkpO1xuICAgIGlmIChpbnRlcnBvbGF0ZWRQb2ludCkge1xuICAgICAgICBjdHgubGluZVRvKGludGVycG9sYXRlZFBvaW50LngsIGludGVycG9sYXRlZFBvaW50LnkpO1xuICAgIH1cbn1cblxudmFyIGluZGV4ID0ge1xuICAgIGlkOiAnZmlsbGVyJyxcbiAgICBhZnRlckRhdGFzZXRzVXBkYXRlIChjaGFydCwgX2FyZ3MsIG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgY291bnQgPSAoY2hhcnQuZGF0YS5kYXRhc2V0cyB8fCBbXSkubGVuZ3RoO1xuICAgICAgICBjb25zdCBzb3VyY2VzID0gW107XG4gICAgICAgIGxldCBtZXRhLCBpLCBsaW5lLCBzb3VyY2U7XG4gICAgICAgIGZvcihpID0gMDsgaSA8IGNvdW50OyArK2kpe1xuICAgICAgICAgICAgbWV0YSA9IGNoYXJ0LmdldERhdGFzZXRNZXRhKGkpO1xuICAgICAgICAgICAgbGluZSA9IG1ldGEuZGF0YXNldDtcbiAgICAgICAgICAgIHNvdXJjZSA9IG51bGw7XG4gICAgICAgICAgICBpZiAobGluZSAmJiBsaW5lLm9wdGlvbnMgJiYgbGluZSBpbnN0YW5jZW9mIExpbmVFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgc291cmNlID0ge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiBjaGFydC5pc0RhdGFzZXRWaXNpYmxlKGkpLFxuICAgICAgICAgICAgICAgICAgICBpbmRleDogaSxcbiAgICAgICAgICAgICAgICAgICAgZmlsbDogX2RlY29kZUZpbGwobGluZSwgaSwgY291bnQpLFxuICAgICAgICAgICAgICAgICAgICBjaGFydCxcbiAgICAgICAgICAgICAgICAgICAgYXhpczogbWV0YS5jb250cm9sbGVyLm9wdGlvbnMuaW5kZXhBeGlzLFxuICAgICAgICAgICAgICAgICAgICBzY2FsZTogbWV0YS52U2NhbGUsXG4gICAgICAgICAgICAgICAgICAgIGxpbmVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbWV0YS4kZmlsbGVyID0gc291cmNlO1xuICAgICAgICAgICAgc291cmNlcy5wdXNoKHNvdXJjZSk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yKGkgPSAwOyBpIDwgY291bnQ7ICsraSl7XG4gICAgICAgICAgICBzb3VyY2UgPSBzb3VyY2VzW2ldO1xuICAgICAgICAgICAgaWYgKCFzb3VyY2UgfHwgc291cmNlLmZpbGwgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzb3VyY2UuZmlsbCA9IF9yZXNvbHZlVGFyZ2V0KHNvdXJjZXMsIGksIG9wdGlvbnMucHJvcGFnYXRlKTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgYmVmb3JlRHJhdyAoY2hhcnQsIF9hcmdzLCBvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IGRyYXcgPSBvcHRpb25zLmRyYXdUaW1lID09PSAnYmVmb3JlRHJhdyc7XG4gICAgICAgIGNvbnN0IG1ldGFzZXRzID0gY2hhcnQuZ2V0U29ydGVkVmlzaWJsZURhdGFzZXRNZXRhcygpO1xuICAgICAgICBjb25zdCBhcmVhID0gY2hhcnQuY2hhcnRBcmVhO1xuICAgICAgICBmb3IobGV0IGkgPSBtZXRhc2V0cy5sZW5ndGggLSAxOyBpID49IDA7IC0taSl7XG4gICAgICAgICAgICBjb25zdCBzb3VyY2UgPSBtZXRhc2V0c1tpXS4kZmlsbGVyO1xuICAgICAgICAgICAgaWYgKCFzb3VyY2UpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNvdXJjZS5saW5lLnVwZGF0ZUNvbnRyb2xQb2ludHMoYXJlYSwgc291cmNlLmF4aXMpO1xuICAgICAgICAgICAgaWYgKGRyYXcgJiYgc291cmNlLmZpbGwpIHtcbiAgICAgICAgICAgICAgICBfZHJhd2ZpbGwoY2hhcnQuY3R4LCBzb3VyY2UsIGFyZWEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSxcbiAgICBiZWZvcmVEYXRhc2V0c0RyYXcgKGNoYXJ0LCBfYXJncywgb3B0aW9ucykge1xuICAgICAgICBpZiAob3B0aW9ucy5kcmF3VGltZSAhPT0gJ2JlZm9yZURhdGFzZXRzRHJhdycpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBtZXRhc2V0cyA9IGNoYXJ0LmdldFNvcnRlZFZpc2libGVEYXRhc2V0TWV0YXMoKTtcbiAgICAgICAgZm9yKGxldCBpID0gbWV0YXNldHMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpe1xuICAgICAgICAgICAgY29uc3Qgc291cmNlID0gbWV0YXNldHNbaV0uJGZpbGxlcjtcbiAgICAgICAgICAgIGlmIChfc2hvdWxkQXBwbHlGaWxsKHNvdXJjZSkpIHtcbiAgICAgICAgICAgICAgICBfZHJhd2ZpbGwoY2hhcnQuY3R4LCBzb3VyY2UsIGNoYXJ0LmNoYXJ0QXJlYSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGJlZm9yZURhdGFzZXREcmF3IChjaGFydCwgYXJncywgb3B0aW9ucykge1xuICAgICAgICBjb25zdCBzb3VyY2UgPSBhcmdzLm1ldGEuJGZpbGxlcjtcbiAgICAgICAgaWYgKCFfc2hvdWxkQXBwbHlGaWxsKHNvdXJjZSkgfHwgb3B0aW9ucy5kcmF3VGltZSAhPT0gJ2JlZm9yZURhdGFzZXREcmF3Jykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIF9kcmF3ZmlsbChjaGFydC5jdHgsIHNvdXJjZSwgY2hhcnQuY2hhcnRBcmVhKTtcbiAgICB9LFxuICAgIGRlZmF1bHRzOiB7XG4gICAgICAgIHByb3BhZ2F0ZTogdHJ1ZSxcbiAgICAgICAgZHJhd1RpbWU6ICdiZWZvcmVEYXRhc2V0RHJhdydcbiAgICB9XG59O1xuXG5jb25zdCBnZXRCb3hTaXplID0gKGxhYmVsT3B0cywgZm9udFNpemUpPT57XG4gICAgbGV0IHsgYm94SGVpZ2h0ID1mb250U2l6ZSAsIGJveFdpZHRoID1mb250U2l6ZSAgfSA9IGxhYmVsT3B0cztcbiAgICBpZiAobGFiZWxPcHRzLnVzZVBvaW50U3R5bGUpIHtcbiAgICAgICAgYm94SGVpZ2h0ID0gTWF0aC5taW4oYm94SGVpZ2h0LCBmb250U2l6ZSk7XG4gICAgICAgIGJveFdpZHRoID0gbGFiZWxPcHRzLnBvaW50U3R5bGVXaWR0aCB8fCBNYXRoLm1pbihib3hXaWR0aCwgZm9udFNpemUpO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBib3hXaWR0aCxcbiAgICAgICAgYm94SGVpZ2h0LFxuICAgICAgICBpdGVtSGVpZ2h0OiBNYXRoLm1heChmb250U2l6ZSwgYm94SGVpZ2h0KVxuICAgIH07XG59O1xuY29uc3QgaXRlbXNFcXVhbCA9IChhLCBiKT0+YSAhPT0gbnVsbCAmJiBiICE9PSBudWxsICYmIGEuZGF0YXNldEluZGV4ID09PSBiLmRhdGFzZXRJbmRleCAmJiBhLmluZGV4ID09PSBiLmluZGV4O1xuY2xhc3MgTGVnZW5kIGV4dGVuZHMgRWxlbWVudCB7XG4gY29uc3RydWN0b3IoY29uZmlnKXtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5fYWRkZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5sZWdlbmRIaXRCb3hlcyA9IFtdO1xuIHRoaXMuX2hvdmVyZWRJdGVtID0gbnVsbDtcbiAgICAgICAgdGhpcy5kb3VnaG51dE1vZGUgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5jaGFydCA9IGNvbmZpZy5jaGFydDtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gY29uZmlnLm9wdGlvbnM7XG4gICAgICAgIHRoaXMuY3R4ID0gY29uZmlnLmN0eDtcbiAgICAgICAgdGhpcy5sZWdlbmRJdGVtcyA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5jb2x1bW5TaXplcyA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5saW5lV2lkdGhzID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLm1heEhlaWdodCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5tYXhXaWR0aCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy50b3AgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuYm90dG9tID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLmxlZnQgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMucmlnaHQgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuaGVpZ2h0ID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLndpZHRoID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl9tYXJnaW5zID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLnBvc2l0aW9uID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLndlaWdodCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5mdWxsU2l6ZSA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgdXBkYXRlKG1heFdpZHRoLCBtYXhIZWlnaHQsIG1hcmdpbnMpIHtcbiAgICAgICAgdGhpcy5tYXhXaWR0aCA9IG1heFdpZHRoO1xuICAgICAgICB0aGlzLm1heEhlaWdodCA9IG1heEhlaWdodDtcbiAgICAgICAgdGhpcy5fbWFyZ2lucyA9IG1hcmdpbnM7XG4gICAgICAgIHRoaXMuc2V0RGltZW5zaW9ucygpO1xuICAgICAgICB0aGlzLmJ1aWxkTGFiZWxzKCk7XG4gICAgICAgIHRoaXMuZml0KCk7XG4gICAgfVxuICAgIHNldERpbWVuc2lvbnMoKSB7XG4gICAgICAgIGlmICh0aGlzLmlzSG9yaXpvbnRhbCgpKSB7XG4gICAgICAgICAgICB0aGlzLndpZHRoID0gdGhpcy5tYXhXaWR0aDtcbiAgICAgICAgICAgIHRoaXMubGVmdCA9IHRoaXMuX21hcmdpbnMubGVmdDtcbiAgICAgICAgICAgIHRoaXMucmlnaHQgPSB0aGlzLndpZHRoO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSB0aGlzLm1heEhlaWdodDtcbiAgICAgICAgICAgIHRoaXMudG9wID0gdGhpcy5fbWFyZ2lucy50b3A7XG4gICAgICAgICAgICB0aGlzLmJvdHRvbSA9IHRoaXMuaGVpZ2h0O1xuICAgICAgICB9XG4gICAgfVxuICAgIGJ1aWxkTGFiZWxzKCkge1xuICAgICAgICBjb25zdCBsYWJlbE9wdHMgPSB0aGlzLm9wdGlvbnMubGFiZWxzIHx8IHt9O1xuICAgICAgICBsZXQgbGVnZW5kSXRlbXMgPSBjYWxsYmFjayhsYWJlbE9wdHMuZ2VuZXJhdGVMYWJlbHMsIFtcbiAgICAgICAgICAgIHRoaXMuY2hhcnRcbiAgICAgICAgXSwgdGhpcykgfHwgW107XG4gICAgICAgIGlmIChsYWJlbE9wdHMuZmlsdGVyKSB7XG4gICAgICAgICAgICBsZWdlbmRJdGVtcyA9IGxlZ2VuZEl0ZW1zLmZpbHRlcigoaXRlbSk9PmxhYmVsT3B0cy5maWx0ZXIoaXRlbSwgdGhpcy5jaGFydC5kYXRhKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxhYmVsT3B0cy5zb3J0KSB7XG4gICAgICAgICAgICBsZWdlbmRJdGVtcyA9IGxlZ2VuZEl0ZW1zLnNvcnQoKGEsIGIpPT5sYWJlbE9wdHMuc29ydChhLCBiLCB0aGlzLmNoYXJ0LmRhdGEpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnJldmVyc2UpIHtcbiAgICAgICAgICAgIGxlZ2VuZEl0ZW1zLnJldmVyc2UoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxlZ2VuZEl0ZW1zID0gbGVnZW5kSXRlbXM7XG4gICAgfVxuICAgIGZpdCgpIHtcbiAgICAgICAgY29uc3QgeyBvcHRpb25zICwgY3R4ICB9ID0gdGhpcztcbiAgICAgICAgaWYgKCFvcHRpb25zLmRpc3BsYXkpIHtcbiAgICAgICAgICAgIHRoaXMud2lkdGggPSB0aGlzLmhlaWdodCA9IDA7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbGFiZWxPcHRzID0gb3B0aW9ucy5sYWJlbHM7XG4gICAgICAgIGNvbnN0IGxhYmVsRm9udCA9IHRvRm9udChsYWJlbE9wdHMuZm9udCk7XG4gICAgICAgIGNvbnN0IGZvbnRTaXplID0gbGFiZWxGb250LnNpemU7XG4gICAgICAgIGNvbnN0IHRpdGxlSGVpZ2h0ID0gdGhpcy5fY29tcHV0ZVRpdGxlSGVpZ2h0KCk7XG4gICAgICAgIGNvbnN0IHsgYm94V2lkdGggLCBpdGVtSGVpZ2h0ICB9ID0gZ2V0Qm94U2l6ZShsYWJlbE9wdHMsIGZvbnRTaXplKTtcbiAgICAgICAgbGV0IHdpZHRoLCBoZWlnaHQ7XG4gICAgICAgIGN0eC5mb250ID0gbGFiZWxGb250LnN0cmluZztcbiAgICAgICAgaWYgKHRoaXMuaXNIb3Jpem9udGFsKCkpIHtcbiAgICAgICAgICAgIHdpZHRoID0gdGhpcy5tYXhXaWR0aDtcbiAgICAgICAgICAgIGhlaWdodCA9IHRoaXMuX2ZpdFJvd3ModGl0bGVIZWlnaHQsIGZvbnRTaXplLCBib3hXaWR0aCwgaXRlbUhlaWdodCkgKyAxMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGhlaWdodCA9IHRoaXMubWF4SGVpZ2h0O1xuICAgICAgICAgICAgd2lkdGggPSB0aGlzLl9maXRDb2xzKHRpdGxlSGVpZ2h0LCBsYWJlbEZvbnQsIGJveFdpZHRoLCBpdGVtSGVpZ2h0KSArIDEwO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMud2lkdGggPSBNYXRoLm1pbih3aWR0aCwgb3B0aW9ucy5tYXhXaWR0aCB8fCB0aGlzLm1heFdpZHRoKTtcbiAgICAgICAgdGhpcy5oZWlnaHQgPSBNYXRoLm1pbihoZWlnaHQsIG9wdGlvbnMubWF4SGVpZ2h0IHx8IHRoaXMubWF4SGVpZ2h0KTtcbiAgICB9XG4gX2ZpdFJvd3ModGl0bGVIZWlnaHQsIGZvbnRTaXplLCBib3hXaWR0aCwgaXRlbUhlaWdodCkge1xuICAgICAgICBjb25zdCB7IGN0eCAsIG1heFdpZHRoICwgb3B0aW9uczogeyBsYWJlbHM6IHsgcGFkZGluZyAgfSAgfSAgfSA9IHRoaXM7XG4gICAgICAgIGNvbnN0IGhpdGJveGVzID0gdGhpcy5sZWdlbmRIaXRCb3hlcyA9IFtdO1xuICAgICAgICBjb25zdCBsaW5lV2lkdGhzID0gdGhpcy5saW5lV2lkdGhzID0gW1xuICAgICAgICAgICAgMFxuICAgICAgICBdO1xuICAgICAgICBjb25zdCBsaW5lSGVpZ2h0ID0gaXRlbUhlaWdodCArIHBhZGRpbmc7XG4gICAgICAgIGxldCB0b3RhbEhlaWdodCA9IHRpdGxlSGVpZ2h0O1xuICAgICAgICBjdHgudGV4dEFsaWduID0gJ2xlZnQnO1xuICAgICAgICBjdHgudGV4dEJhc2VsaW5lID0gJ21pZGRsZSc7XG4gICAgICAgIGxldCByb3cgPSAtMTtcbiAgICAgICAgbGV0IHRvcCA9IC1saW5lSGVpZ2h0O1xuICAgICAgICB0aGlzLmxlZ2VuZEl0ZW1zLmZvckVhY2goKGxlZ2VuZEl0ZW0sIGkpPT57XG4gICAgICAgICAgICBjb25zdCBpdGVtV2lkdGggPSBib3hXaWR0aCArIGZvbnRTaXplIC8gMiArIGN0eC5tZWFzdXJlVGV4dChsZWdlbmRJdGVtLnRleHQpLndpZHRoO1xuICAgICAgICAgICAgaWYgKGkgPT09IDAgfHwgbGluZVdpZHRoc1tsaW5lV2lkdGhzLmxlbmd0aCAtIDFdICsgaXRlbVdpZHRoICsgMiAqIHBhZGRpbmcgPiBtYXhXaWR0aCkge1xuICAgICAgICAgICAgICAgIHRvdGFsSGVpZ2h0ICs9IGxpbmVIZWlnaHQ7XG4gICAgICAgICAgICAgICAgbGluZVdpZHRoc1tsaW5lV2lkdGhzLmxlbmd0aCAtIChpID4gMCA/IDAgOiAxKV0gPSAwO1xuICAgICAgICAgICAgICAgIHRvcCArPSBsaW5lSGVpZ2h0O1xuICAgICAgICAgICAgICAgIHJvdysrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaGl0Ym94ZXNbaV0gPSB7XG4gICAgICAgICAgICAgICAgbGVmdDogMCxcbiAgICAgICAgICAgICAgICB0b3AsXG4gICAgICAgICAgICAgICAgcm93LFxuICAgICAgICAgICAgICAgIHdpZHRoOiBpdGVtV2lkdGgsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiBpdGVtSGVpZ2h0XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgbGluZVdpZHRoc1tsaW5lV2lkdGhzLmxlbmd0aCAtIDFdICs9IGl0ZW1XaWR0aCArIHBhZGRpbmc7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdG90YWxIZWlnaHQ7XG4gICAgfVxuICAgIF9maXRDb2xzKHRpdGxlSGVpZ2h0LCBsYWJlbEZvbnQsIGJveFdpZHRoLCBfaXRlbUhlaWdodCkge1xuICAgICAgICBjb25zdCB7IGN0eCAsIG1heEhlaWdodCAsIG9wdGlvbnM6IHsgbGFiZWxzOiB7IHBhZGRpbmcgIH0gIH0gIH0gPSB0aGlzO1xuICAgICAgICBjb25zdCBoaXRib3hlcyA9IHRoaXMubGVnZW5kSGl0Qm94ZXMgPSBbXTtcbiAgICAgICAgY29uc3QgY29sdW1uU2l6ZXMgPSB0aGlzLmNvbHVtblNpemVzID0gW107XG4gICAgICAgIGNvbnN0IGhlaWdodExpbWl0ID0gbWF4SGVpZ2h0IC0gdGl0bGVIZWlnaHQ7XG4gICAgICAgIGxldCB0b3RhbFdpZHRoID0gcGFkZGluZztcbiAgICAgICAgbGV0IGN1cnJlbnRDb2xXaWR0aCA9IDA7XG4gICAgICAgIGxldCBjdXJyZW50Q29sSGVpZ2h0ID0gMDtcbiAgICAgICAgbGV0IGxlZnQgPSAwO1xuICAgICAgICBsZXQgY29sID0gMDtcbiAgICAgICAgdGhpcy5sZWdlbmRJdGVtcy5mb3JFYWNoKChsZWdlbmRJdGVtLCBpKT0+e1xuICAgICAgICAgICAgY29uc3QgeyBpdGVtV2lkdGggLCBpdGVtSGVpZ2h0ICB9ID0gY2FsY3VsYXRlSXRlbVNpemUoYm94V2lkdGgsIGxhYmVsRm9udCwgY3R4LCBsZWdlbmRJdGVtLCBfaXRlbUhlaWdodCk7XG4gICAgICAgICAgICBpZiAoaSA+IDAgJiYgY3VycmVudENvbEhlaWdodCArIGl0ZW1IZWlnaHQgKyAyICogcGFkZGluZyA+IGhlaWdodExpbWl0KSB7XG4gICAgICAgICAgICAgICAgdG90YWxXaWR0aCArPSBjdXJyZW50Q29sV2lkdGggKyBwYWRkaW5nO1xuICAgICAgICAgICAgICAgIGNvbHVtblNpemVzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICB3aWR0aDogY3VycmVudENvbFdpZHRoLFxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGN1cnJlbnRDb2xIZWlnaHRcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBsZWZ0ICs9IGN1cnJlbnRDb2xXaWR0aCArIHBhZGRpbmc7XG4gICAgICAgICAgICAgICAgY29sKys7XG4gICAgICAgICAgICAgICAgY3VycmVudENvbFdpZHRoID0gY3VycmVudENvbEhlaWdodCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoaXRib3hlc1tpXSA9IHtcbiAgICAgICAgICAgICAgICBsZWZ0LFxuICAgICAgICAgICAgICAgIHRvcDogY3VycmVudENvbEhlaWdodCxcbiAgICAgICAgICAgICAgICBjb2wsXG4gICAgICAgICAgICAgICAgd2lkdGg6IGl0ZW1XaWR0aCxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IGl0ZW1IZWlnaHRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjdXJyZW50Q29sV2lkdGggPSBNYXRoLm1heChjdXJyZW50Q29sV2lkdGgsIGl0ZW1XaWR0aCk7XG4gICAgICAgICAgICBjdXJyZW50Q29sSGVpZ2h0ICs9IGl0ZW1IZWlnaHQgKyBwYWRkaW5nO1xuICAgICAgICB9KTtcbiAgICAgICAgdG90YWxXaWR0aCArPSBjdXJyZW50Q29sV2lkdGg7XG4gICAgICAgIGNvbHVtblNpemVzLnB1c2goe1xuICAgICAgICAgICAgd2lkdGg6IGN1cnJlbnRDb2xXaWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogY3VycmVudENvbEhlaWdodFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRvdGFsV2lkdGg7XG4gICAgfVxuICAgIGFkanVzdEhpdEJveGVzKCkge1xuICAgICAgICBpZiAoIXRoaXMub3B0aW9ucy5kaXNwbGF5KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGl0bGVIZWlnaHQgPSB0aGlzLl9jb21wdXRlVGl0bGVIZWlnaHQoKTtcbiAgICAgICAgY29uc3QgeyBsZWdlbmRIaXRCb3hlczogaGl0Ym94ZXMgLCBvcHRpb25zOiB7IGFsaWduICwgbGFiZWxzOiB7IHBhZGRpbmcgIH0gLCBydGwgIH0gIH0gPSB0aGlzO1xuICAgICAgICBjb25zdCBydGxIZWxwZXIgPSBnZXRSdGxBZGFwdGVyKHJ0bCwgdGhpcy5sZWZ0LCB0aGlzLndpZHRoKTtcbiAgICAgICAgaWYgKHRoaXMuaXNIb3Jpem9udGFsKCkpIHtcbiAgICAgICAgICAgIGxldCByb3cgPSAwO1xuICAgICAgICAgICAgbGV0IGxlZnQgPSBfYWxpZ25TdGFydEVuZChhbGlnbiwgdGhpcy5sZWZ0ICsgcGFkZGluZywgdGhpcy5yaWdodCAtIHRoaXMubGluZVdpZHRoc1tyb3ddKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgaGl0Ym94IG9mIGhpdGJveGVzKXtcbiAgICAgICAgICAgICAgICBpZiAocm93ICE9PSBoaXRib3gucm93KSB7XG4gICAgICAgICAgICAgICAgICAgIHJvdyA9IGhpdGJveC5yb3c7XG4gICAgICAgICAgICAgICAgICAgIGxlZnQgPSBfYWxpZ25TdGFydEVuZChhbGlnbiwgdGhpcy5sZWZ0ICsgcGFkZGluZywgdGhpcy5yaWdodCAtIHRoaXMubGluZVdpZHRoc1tyb3ddKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaGl0Ym94LnRvcCArPSB0aGlzLnRvcCArIHRpdGxlSGVpZ2h0ICsgcGFkZGluZztcbiAgICAgICAgICAgICAgICBoaXRib3gubGVmdCA9IHJ0bEhlbHBlci5sZWZ0Rm9yTHRyKHJ0bEhlbHBlci54KGxlZnQpLCBoaXRib3gud2lkdGgpO1xuICAgICAgICAgICAgICAgIGxlZnQgKz0gaGl0Ym94LndpZHRoICsgcGFkZGluZztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxldCBjb2wgPSAwO1xuICAgICAgICAgICAgbGV0IHRvcCA9IF9hbGlnblN0YXJ0RW5kKGFsaWduLCB0aGlzLnRvcCArIHRpdGxlSGVpZ2h0ICsgcGFkZGluZywgdGhpcy5ib3R0b20gLSB0aGlzLmNvbHVtblNpemVzW2NvbF0uaGVpZ2h0KTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgaGl0Ym94IG9mIGhpdGJveGVzKXtcbiAgICAgICAgICAgICAgICBpZiAoaGl0Ym94LmNvbCAhPT0gY29sKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbCA9IGhpdGJveC5jb2w7XG4gICAgICAgICAgICAgICAgICAgIHRvcCA9IF9hbGlnblN0YXJ0RW5kKGFsaWduLCB0aGlzLnRvcCArIHRpdGxlSGVpZ2h0ICsgcGFkZGluZywgdGhpcy5ib3R0b20gLSB0aGlzLmNvbHVtblNpemVzW2NvbF0uaGVpZ2h0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaGl0Ym94LnRvcCA9IHRvcDtcbiAgICAgICAgICAgICAgICBoaXRib3gubGVmdCArPSB0aGlzLmxlZnQgKyBwYWRkaW5nO1xuICAgICAgICAgICAgICAgIGhpdGJveC5sZWZ0ID0gcnRsSGVscGVyLmxlZnRGb3JMdHIocnRsSGVscGVyLngoaGl0Ym94LmxlZnQpLCBoaXRib3gud2lkdGgpO1xuICAgICAgICAgICAgICAgIHRvcCArPSBoaXRib3guaGVpZ2h0ICsgcGFkZGluZztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBpc0hvcml6b250YWwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMucG9zaXRpb24gPT09ICd0b3AnIHx8IHRoaXMub3B0aW9ucy5wb3NpdGlvbiA9PT0gJ2JvdHRvbSc7XG4gICAgfVxuICAgIGRyYXcoKSB7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuZGlzcGxheSkge1xuICAgICAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgICAgICAgICBjbGlwQXJlYShjdHgsIHRoaXMpO1xuICAgICAgICAgICAgdGhpcy5fZHJhdygpO1xuICAgICAgICAgICAgdW5jbGlwQXJlYShjdHgpO1xuICAgICAgICB9XG4gICAgfVxuIF9kcmF3KCkge1xuICAgICAgICBjb25zdCB7IG9wdGlvbnM6IG9wdHMgLCBjb2x1bW5TaXplcyAsIGxpbmVXaWR0aHMgLCBjdHggIH0gPSB0aGlzO1xuICAgICAgICBjb25zdCB7IGFsaWduICwgbGFiZWxzOiBsYWJlbE9wdHMgIH0gPSBvcHRzO1xuICAgICAgICBjb25zdCBkZWZhdWx0Q29sb3IgPSBkZWZhdWx0cy5jb2xvcjtcbiAgICAgICAgY29uc3QgcnRsSGVscGVyID0gZ2V0UnRsQWRhcHRlcihvcHRzLnJ0bCwgdGhpcy5sZWZ0LCB0aGlzLndpZHRoKTtcbiAgICAgICAgY29uc3QgbGFiZWxGb250ID0gdG9Gb250KGxhYmVsT3B0cy5mb250KTtcbiAgICAgICAgY29uc3QgeyBwYWRkaW5nICB9ID0gbGFiZWxPcHRzO1xuICAgICAgICBjb25zdCBmb250U2l6ZSA9IGxhYmVsRm9udC5zaXplO1xuICAgICAgICBjb25zdCBoYWxmRm9udFNpemUgPSBmb250U2l6ZSAvIDI7XG4gICAgICAgIGxldCBjdXJzb3I7XG4gICAgICAgIHRoaXMuZHJhd1RpdGxlKCk7XG4gICAgICAgIGN0eC50ZXh0QWxpZ24gPSBydGxIZWxwZXIudGV4dEFsaWduKCdsZWZ0Jyk7XG4gICAgICAgIGN0eC50ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJztcbiAgICAgICAgY3R4LmxpbmVXaWR0aCA9IDAuNTtcbiAgICAgICAgY3R4LmZvbnQgPSBsYWJlbEZvbnQuc3RyaW5nO1xuICAgICAgICBjb25zdCB7IGJveFdpZHRoICwgYm94SGVpZ2h0ICwgaXRlbUhlaWdodCAgfSA9IGdldEJveFNpemUobGFiZWxPcHRzLCBmb250U2l6ZSk7XG4gICAgICAgIGNvbnN0IGRyYXdMZWdlbmRCb3ggPSBmdW5jdGlvbih4LCB5LCBsZWdlbmRJdGVtKSB7XG4gICAgICAgICAgICBpZiAoaXNOYU4oYm94V2lkdGgpIHx8IGJveFdpZHRoIDw9IDAgfHwgaXNOYU4oYm94SGVpZ2h0KSB8fCBib3hIZWlnaHQgPCAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY3R4LnNhdmUoKTtcbiAgICAgICAgICAgIGNvbnN0IGxpbmVXaWR0aCA9IHZhbHVlT3JEZWZhdWx0KGxlZ2VuZEl0ZW0ubGluZVdpZHRoLCAxKTtcbiAgICAgICAgICAgIGN0eC5maWxsU3R5bGUgPSB2YWx1ZU9yRGVmYXVsdChsZWdlbmRJdGVtLmZpbGxTdHlsZSwgZGVmYXVsdENvbG9yKTtcbiAgICAgICAgICAgIGN0eC5saW5lQ2FwID0gdmFsdWVPckRlZmF1bHQobGVnZW5kSXRlbS5saW5lQ2FwLCAnYnV0dCcpO1xuICAgICAgICAgICAgY3R4LmxpbmVEYXNoT2Zmc2V0ID0gdmFsdWVPckRlZmF1bHQobGVnZW5kSXRlbS5saW5lRGFzaE9mZnNldCwgMCk7XG4gICAgICAgICAgICBjdHgubGluZUpvaW4gPSB2YWx1ZU9yRGVmYXVsdChsZWdlbmRJdGVtLmxpbmVKb2luLCAnbWl0ZXInKTtcbiAgICAgICAgICAgIGN0eC5saW5lV2lkdGggPSBsaW5lV2lkdGg7XG4gICAgICAgICAgICBjdHguc3Ryb2tlU3R5bGUgPSB2YWx1ZU9yRGVmYXVsdChsZWdlbmRJdGVtLnN0cm9rZVN0eWxlLCBkZWZhdWx0Q29sb3IpO1xuICAgICAgICAgICAgY3R4LnNldExpbmVEYXNoKHZhbHVlT3JEZWZhdWx0KGxlZ2VuZEl0ZW0ubGluZURhc2gsIFtdKSk7XG4gICAgICAgICAgICBpZiAobGFiZWxPcHRzLnVzZVBvaW50U3R5bGUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBkcmF3T3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgcmFkaXVzOiBib3hIZWlnaHQgKiBNYXRoLlNRUlQyIC8gMixcbiAgICAgICAgICAgICAgICAgICAgcG9pbnRTdHlsZTogbGVnZW5kSXRlbS5wb2ludFN0eWxlLFxuICAgICAgICAgICAgICAgICAgICByb3RhdGlvbjogbGVnZW5kSXRlbS5yb3RhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgYm9yZGVyV2lkdGg6IGxpbmVXaWR0aFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgY29uc3QgY2VudGVyWCA9IHJ0bEhlbHBlci54UGx1cyh4LCBib3hXaWR0aCAvIDIpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNlbnRlclkgPSB5ICsgaGFsZkZvbnRTaXplO1xuICAgICAgICAgICAgICAgIGRyYXdQb2ludExlZ2VuZChjdHgsIGRyYXdPcHRpb25zLCBjZW50ZXJYLCBjZW50ZXJZLCBsYWJlbE9wdHMucG9pbnRTdHlsZVdpZHRoICYmIGJveFdpZHRoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeUJveFRvcCA9IHkgKyBNYXRoLm1heCgoZm9udFNpemUgLSBib3hIZWlnaHQpIC8gMiwgMCk7XG4gICAgICAgICAgICAgICAgY29uc3QgeEJveExlZnQgPSBydGxIZWxwZXIubGVmdEZvckx0cih4LCBib3hXaWR0aCk7XG4gICAgICAgICAgICAgICAgY29uc3QgYm9yZGVyUmFkaXVzID0gdG9UUkJMQ29ybmVycyhsZWdlbmRJdGVtLmJvcmRlclJhZGl1cyk7XG4gICAgICAgICAgICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgICAgICAgICAgIGlmIChPYmplY3QudmFsdWVzKGJvcmRlclJhZGl1cykuc29tZSgodik9PnYgIT09IDApKSB7XG4gICAgICAgICAgICAgICAgICAgIGFkZFJvdW5kZWRSZWN0UGF0aChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHg6IHhCb3hMZWZ0LFxuICAgICAgICAgICAgICAgICAgICAgICAgeTogeUJveFRvcCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHc6IGJveFdpZHRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgaDogYm94SGVpZ2h0LFxuICAgICAgICAgICAgICAgICAgICAgICAgcmFkaXVzOiBib3JkZXJSYWRpdXNcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4LnJlY3QoeEJveExlZnQsIHlCb3hUb3AsIGJveFdpZHRoLCBib3hIZWlnaHQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjdHguZmlsbCgpO1xuICAgICAgICAgICAgICAgIGlmIChsaW5lV2lkdGggIT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4LnN0cm9rZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGZpbGxUZXh0ID0gZnVuY3Rpb24oeCwgeSwgbGVnZW5kSXRlbSkge1xuICAgICAgICAgICAgcmVuZGVyVGV4dChjdHgsIGxlZ2VuZEl0ZW0udGV4dCwgeCwgeSArIGl0ZW1IZWlnaHQgLyAyLCBsYWJlbEZvbnQsIHtcbiAgICAgICAgICAgICAgICBzdHJpa2V0aHJvdWdoOiBsZWdlbmRJdGVtLmhpZGRlbixcbiAgICAgICAgICAgICAgICB0ZXh0QWxpZ246IHJ0bEhlbHBlci50ZXh0QWxpZ24obGVnZW5kSXRlbS50ZXh0QWxpZ24pXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgaXNIb3Jpem9udGFsID0gdGhpcy5pc0hvcml6b250YWwoKTtcbiAgICAgICAgY29uc3QgdGl0bGVIZWlnaHQgPSB0aGlzLl9jb21wdXRlVGl0bGVIZWlnaHQoKTtcbiAgICAgICAgaWYgKGlzSG9yaXpvbnRhbCkge1xuICAgICAgICAgICAgY3Vyc29yID0ge1xuICAgICAgICAgICAgICAgIHg6IF9hbGlnblN0YXJ0RW5kKGFsaWduLCB0aGlzLmxlZnQgKyBwYWRkaW5nLCB0aGlzLnJpZ2h0IC0gbGluZVdpZHRoc1swXSksXG4gICAgICAgICAgICAgICAgeTogdGhpcy50b3AgKyBwYWRkaW5nICsgdGl0bGVIZWlnaHQsXG4gICAgICAgICAgICAgICAgbGluZTogMFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGN1cnNvciA9IHtcbiAgICAgICAgICAgICAgICB4OiB0aGlzLmxlZnQgKyBwYWRkaW5nLFxuICAgICAgICAgICAgICAgIHk6IF9hbGlnblN0YXJ0RW5kKGFsaWduLCB0aGlzLnRvcCArIHRpdGxlSGVpZ2h0ICsgcGFkZGluZywgdGhpcy5ib3R0b20gLSBjb2x1bW5TaXplc1swXS5oZWlnaHQpLFxuICAgICAgICAgICAgICAgIGxpbmU6IDBcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgb3ZlcnJpZGVUZXh0RGlyZWN0aW9uKHRoaXMuY3R4LCBvcHRzLnRleHREaXJlY3Rpb24pO1xuICAgICAgICBjb25zdCBsaW5lSGVpZ2h0ID0gaXRlbUhlaWdodCArIHBhZGRpbmc7XG4gICAgICAgIHRoaXMubGVnZW5kSXRlbXMuZm9yRWFjaCgobGVnZW5kSXRlbSwgaSk9PntcbiAgICAgICAgICAgIGN0eC5zdHJva2VTdHlsZSA9IGxlZ2VuZEl0ZW0uZm9udENvbG9yO1xuICAgICAgICAgICAgY3R4LmZpbGxTdHlsZSA9IGxlZ2VuZEl0ZW0uZm9udENvbG9yO1xuICAgICAgICAgICAgY29uc3QgdGV4dFdpZHRoID0gY3R4Lm1lYXN1cmVUZXh0KGxlZ2VuZEl0ZW0udGV4dCkud2lkdGg7XG4gICAgICAgICAgICBjb25zdCB0ZXh0QWxpZ24gPSBydGxIZWxwZXIudGV4dEFsaWduKGxlZ2VuZEl0ZW0udGV4dEFsaWduIHx8IChsZWdlbmRJdGVtLnRleHRBbGlnbiA9IGxhYmVsT3B0cy50ZXh0QWxpZ24pKTtcbiAgICAgICAgICAgIGNvbnN0IHdpZHRoID0gYm94V2lkdGggKyBoYWxmRm9udFNpemUgKyB0ZXh0V2lkdGg7XG4gICAgICAgICAgICBsZXQgeCA9IGN1cnNvci54O1xuICAgICAgICAgICAgbGV0IHkgPSBjdXJzb3IueTtcbiAgICAgICAgICAgIHJ0bEhlbHBlci5zZXRXaWR0aCh0aGlzLndpZHRoKTtcbiAgICAgICAgICAgIGlmIChpc0hvcml6b250YWwpIHtcbiAgICAgICAgICAgICAgICBpZiAoaSA+IDAgJiYgeCArIHdpZHRoICsgcGFkZGluZyA+IHRoaXMucmlnaHQpIHtcbiAgICAgICAgICAgICAgICAgICAgeSA9IGN1cnNvci55ICs9IGxpbmVIZWlnaHQ7XG4gICAgICAgICAgICAgICAgICAgIGN1cnNvci5saW5lKys7XG4gICAgICAgICAgICAgICAgICAgIHggPSBjdXJzb3IueCA9IF9hbGlnblN0YXJ0RW5kKGFsaWduLCB0aGlzLmxlZnQgKyBwYWRkaW5nLCB0aGlzLnJpZ2h0IC0gbGluZVdpZHRoc1tjdXJzb3IubGluZV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA+IDAgJiYgeSArIGxpbmVIZWlnaHQgPiB0aGlzLmJvdHRvbSkge1xuICAgICAgICAgICAgICAgIHggPSBjdXJzb3IueCA9IHggKyBjb2x1bW5TaXplc1tjdXJzb3IubGluZV0ud2lkdGggKyBwYWRkaW5nO1xuICAgICAgICAgICAgICAgIGN1cnNvci5saW5lKys7XG4gICAgICAgICAgICAgICAgeSA9IGN1cnNvci55ID0gX2FsaWduU3RhcnRFbmQoYWxpZ24sIHRoaXMudG9wICsgdGl0bGVIZWlnaHQgKyBwYWRkaW5nLCB0aGlzLmJvdHRvbSAtIGNvbHVtblNpemVzW2N1cnNvci5saW5lXS5oZWlnaHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgcmVhbFggPSBydGxIZWxwZXIueCh4KTtcbiAgICAgICAgICAgIGRyYXdMZWdlbmRCb3gocmVhbFgsIHksIGxlZ2VuZEl0ZW0pO1xuICAgICAgICAgICAgeCA9IF90ZXh0WCh0ZXh0QWxpZ24sIHggKyBib3hXaWR0aCArIGhhbGZGb250U2l6ZSwgaXNIb3Jpem9udGFsID8geCArIHdpZHRoIDogdGhpcy5yaWdodCwgb3B0cy5ydGwpO1xuICAgICAgICAgICAgZmlsbFRleHQocnRsSGVscGVyLngoeCksIHksIGxlZ2VuZEl0ZW0pO1xuICAgICAgICAgICAgaWYgKGlzSG9yaXpvbnRhbCkge1xuICAgICAgICAgICAgICAgIGN1cnNvci54ICs9IHdpZHRoICsgcGFkZGluZztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGxlZ2VuZEl0ZW0udGV4dCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmb250TGluZUhlaWdodCA9IGxhYmVsRm9udC5saW5lSGVpZ2h0O1xuICAgICAgICAgICAgICAgIGN1cnNvci55ICs9IGNhbGN1bGF0ZUxlZ2VuZEl0ZW1IZWlnaHQobGVnZW5kSXRlbSwgZm9udExpbmVIZWlnaHQpICsgcGFkZGluZztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY3Vyc29yLnkgKz0gbGluZUhlaWdodDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJlc3RvcmVUZXh0RGlyZWN0aW9uKHRoaXMuY3R4LCBvcHRzLnRleHREaXJlY3Rpb24pO1xuICAgIH1cbiBkcmF3VGl0bGUoKSB7XG4gICAgICAgIGNvbnN0IG9wdHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGNvbnN0IHRpdGxlT3B0cyA9IG9wdHMudGl0bGU7XG4gICAgICAgIGNvbnN0IHRpdGxlRm9udCA9IHRvRm9udCh0aXRsZU9wdHMuZm9udCk7XG4gICAgICAgIGNvbnN0IHRpdGxlUGFkZGluZyA9IHRvUGFkZGluZyh0aXRsZU9wdHMucGFkZGluZyk7XG4gICAgICAgIGlmICghdGl0bGVPcHRzLmRpc3BsYXkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBydGxIZWxwZXIgPSBnZXRSdGxBZGFwdGVyKG9wdHMucnRsLCB0aGlzLmxlZnQsIHRoaXMud2lkdGgpO1xuICAgICAgICBjb25zdCBjdHggPSB0aGlzLmN0eDtcbiAgICAgICAgY29uc3QgcG9zaXRpb24gPSB0aXRsZU9wdHMucG9zaXRpb247XG4gICAgICAgIGNvbnN0IGhhbGZGb250U2l6ZSA9IHRpdGxlRm9udC5zaXplIC8gMjtcbiAgICAgICAgY29uc3QgdG9wUGFkZGluZ1BsdXNIYWxmRm9udFNpemUgPSB0aXRsZVBhZGRpbmcudG9wICsgaGFsZkZvbnRTaXplO1xuICAgICAgICBsZXQgeTtcbiAgICAgICAgbGV0IGxlZnQgPSB0aGlzLmxlZnQ7XG4gICAgICAgIGxldCBtYXhXaWR0aCA9IHRoaXMud2lkdGg7XG4gICAgICAgIGlmICh0aGlzLmlzSG9yaXpvbnRhbCgpKSB7XG4gICAgICAgICAgICBtYXhXaWR0aCA9IE1hdGgubWF4KC4uLnRoaXMubGluZVdpZHRocyk7XG4gICAgICAgICAgICB5ID0gdGhpcy50b3AgKyB0b3BQYWRkaW5nUGx1c0hhbGZGb250U2l6ZTtcbiAgICAgICAgICAgIGxlZnQgPSBfYWxpZ25TdGFydEVuZChvcHRzLmFsaWduLCBsZWZ0LCB0aGlzLnJpZ2h0IC0gbWF4V2lkdGgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgbWF4SGVpZ2h0ID0gdGhpcy5jb2x1bW5TaXplcy5yZWR1Y2UoKGFjYywgc2l6ZSk9Pk1hdGgubWF4KGFjYywgc2l6ZS5oZWlnaHQpLCAwKTtcbiAgICAgICAgICAgIHkgPSB0b3BQYWRkaW5nUGx1c0hhbGZGb250U2l6ZSArIF9hbGlnblN0YXJ0RW5kKG9wdHMuYWxpZ24sIHRoaXMudG9wLCB0aGlzLmJvdHRvbSAtIG1heEhlaWdodCAtIG9wdHMubGFiZWxzLnBhZGRpbmcgLSB0aGlzLl9jb21wdXRlVGl0bGVIZWlnaHQoKSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeCA9IF9hbGlnblN0YXJ0RW5kKHBvc2l0aW9uLCBsZWZ0LCBsZWZ0ICsgbWF4V2lkdGgpO1xuICAgICAgICBjdHgudGV4dEFsaWduID0gcnRsSGVscGVyLnRleHRBbGlnbihfdG9MZWZ0UmlnaHRDZW50ZXIocG9zaXRpb24pKTtcbiAgICAgICAgY3R4LnRleHRCYXNlbGluZSA9ICdtaWRkbGUnO1xuICAgICAgICBjdHguc3Ryb2tlU3R5bGUgPSB0aXRsZU9wdHMuY29sb3I7XG4gICAgICAgIGN0eC5maWxsU3R5bGUgPSB0aXRsZU9wdHMuY29sb3I7XG4gICAgICAgIGN0eC5mb250ID0gdGl0bGVGb250LnN0cmluZztcbiAgICAgICAgcmVuZGVyVGV4dChjdHgsIHRpdGxlT3B0cy50ZXh0LCB4LCB5LCB0aXRsZUZvbnQpO1xuICAgIH1cbiBfY29tcHV0ZVRpdGxlSGVpZ2h0KCkge1xuICAgICAgICBjb25zdCB0aXRsZU9wdHMgPSB0aGlzLm9wdGlvbnMudGl0bGU7XG4gICAgICAgIGNvbnN0IHRpdGxlRm9udCA9IHRvRm9udCh0aXRsZU9wdHMuZm9udCk7XG4gICAgICAgIGNvbnN0IHRpdGxlUGFkZGluZyA9IHRvUGFkZGluZyh0aXRsZU9wdHMucGFkZGluZyk7XG4gICAgICAgIHJldHVybiB0aXRsZU9wdHMuZGlzcGxheSA/IHRpdGxlRm9udC5saW5lSGVpZ2h0ICsgdGl0bGVQYWRkaW5nLmhlaWdodCA6IDA7XG4gICAgfVxuIF9nZXRMZWdlbmRJdGVtQXQoeCwgeSkge1xuICAgICAgICBsZXQgaSwgaGl0Qm94LCBsaDtcbiAgICAgICAgaWYgKF9pc0JldHdlZW4oeCwgdGhpcy5sZWZ0LCB0aGlzLnJpZ2h0KSAmJiBfaXNCZXR3ZWVuKHksIHRoaXMudG9wLCB0aGlzLmJvdHRvbSkpIHtcbiAgICAgICAgICAgIGxoID0gdGhpcy5sZWdlbmRIaXRCb3hlcztcbiAgICAgICAgICAgIGZvcihpID0gMDsgaSA8IGxoLmxlbmd0aDsgKytpKXtcbiAgICAgICAgICAgICAgICBoaXRCb3ggPSBsaFtpXTtcbiAgICAgICAgICAgICAgICBpZiAoX2lzQmV0d2Vlbih4LCBoaXRCb3gubGVmdCwgaGl0Qm94LmxlZnQgKyBoaXRCb3gud2lkdGgpICYmIF9pc0JldHdlZW4oeSwgaGl0Qm94LnRvcCwgaGl0Qm94LnRvcCArIGhpdEJveC5oZWlnaHQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmxlZ2VuZEl0ZW1zW2ldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gaGFuZGxlRXZlbnQoZSkge1xuICAgICAgICBjb25zdCBvcHRzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBpZiAoIWlzTGlzdGVuZWQoZS50eXBlLCBvcHRzKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGhvdmVyZWRJdGVtID0gdGhpcy5fZ2V0TGVnZW5kSXRlbUF0KGUueCwgZS55KTtcbiAgICAgICAgaWYgKGUudHlwZSA9PT0gJ21vdXNlbW92ZScgfHwgZS50eXBlID09PSAnbW91c2VvdXQnKSB7XG4gICAgICAgICAgICBjb25zdCBwcmV2aW91cyA9IHRoaXMuX2hvdmVyZWRJdGVtO1xuICAgICAgICAgICAgY29uc3Qgc2FtZUl0ZW0gPSBpdGVtc0VxdWFsKHByZXZpb3VzLCBob3ZlcmVkSXRlbSk7XG4gICAgICAgICAgICBpZiAocHJldmlvdXMgJiYgIXNhbWVJdGVtKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sob3B0cy5vbkxlYXZlLCBbXG4gICAgICAgICAgICAgICAgICAgIGUsXG4gICAgICAgICAgICAgICAgICAgIHByZXZpb3VzLFxuICAgICAgICAgICAgICAgICAgICB0aGlzXG4gICAgICAgICAgICAgICAgXSwgdGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9ob3ZlcmVkSXRlbSA9IGhvdmVyZWRJdGVtO1xuICAgICAgICAgICAgaWYgKGhvdmVyZWRJdGVtICYmICFzYW1lSXRlbSkge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKG9wdHMub25Ib3ZlciwgW1xuICAgICAgICAgICAgICAgICAgICBlLFxuICAgICAgICAgICAgICAgICAgICBob3ZlcmVkSXRlbSxcbiAgICAgICAgICAgICAgICAgICAgdGhpc1xuICAgICAgICAgICAgICAgIF0sIHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGhvdmVyZWRJdGVtKSB7XG4gICAgICAgICAgICBjYWxsYmFjayhvcHRzLm9uQ2xpY2ssIFtcbiAgICAgICAgICAgICAgICBlLFxuICAgICAgICAgICAgICAgIGhvdmVyZWRJdGVtLFxuICAgICAgICAgICAgICAgIHRoaXNcbiAgICAgICAgICAgIF0sIHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gY2FsY3VsYXRlSXRlbVNpemUoYm94V2lkdGgsIGxhYmVsRm9udCwgY3R4LCBsZWdlbmRJdGVtLCBfaXRlbUhlaWdodCkge1xuICAgIGNvbnN0IGl0ZW1XaWR0aCA9IGNhbGN1bGF0ZUl0ZW1XaWR0aChsZWdlbmRJdGVtLCBib3hXaWR0aCwgbGFiZWxGb250LCBjdHgpO1xuICAgIGNvbnN0IGl0ZW1IZWlnaHQgPSBjYWxjdWxhdGVJdGVtSGVpZ2h0KF9pdGVtSGVpZ2h0LCBsZWdlbmRJdGVtLCBsYWJlbEZvbnQubGluZUhlaWdodCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgaXRlbVdpZHRoLFxuICAgICAgICBpdGVtSGVpZ2h0XG4gICAgfTtcbn1cbmZ1bmN0aW9uIGNhbGN1bGF0ZUl0ZW1XaWR0aChsZWdlbmRJdGVtLCBib3hXaWR0aCwgbGFiZWxGb250LCBjdHgpIHtcbiAgICBsZXQgbGVnZW5kSXRlbVRleHQgPSBsZWdlbmRJdGVtLnRleHQ7XG4gICAgaWYgKGxlZ2VuZEl0ZW1UZXh0ICYmIHR5cGVvZiBsZWdlbmRJdGVtVGV4dCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgbGVnZW5kSXRlbVRleHQgPSBsZWdlbmRJdGVtVGV4dC5yZWR1Y2UoKGEsIGIpPT5hLmxlbmd0aCA+IGIubGVuZ3RoID8gYSA6IGIpO1xuICAgIH1cbiAgICByZXR1cm4gYm94V2lkdGggKyBsYWJlbEZvbnQuc2l6ZSAvIDIgKyBjdHgubWVhc3VyZVRleHQobGVnZW5kSXRlbVRleHQpLndpZHRoO1xufVxuZnVuY3Rpb24gY2FsY3VsYXRlSXRlbUhlaWdodChfaXRlbUhlaWdodCwgbGVnZW5kSXRlbSwgZm9udExpbmVIZWlnaHQpIHtcbiAgICBsZXQgaXRlbUhlaWdodCA9IF9pdGVtSGVpZ2h0O1xuICAgIGlmICh0eXBlb2YgbGVnZW5kSXRlbS50ZXh0ICE9PSAnc3RyaW5nJykge1xuICAgICAgICBpdGVtSGVpZ2h0ID0gY2FsY3VsYXRlTGVnZW5kSXRlbUhlaWdodChsZWdlbmRJdGVtLCBmb250TGluZUhlaWdodCk7XG4gICAgfVxuICAgIHJldHVybiBpdGVtSGVpZ2h0O1xufVxuZnVuY3Rpb24gY2FsY3VsYXRlTGVnZW5kSXRlbUhlaWdodChsZWdlbmRJdGVtLCBmb250TGluZUhlaWdodCkge1xuICAgIGNvbnN0IGxhYmVsSGVpZ2h0ID0gbGVnZW5kSXRlbS50ZXh0ID8gbGVnZW5kSXRlbS50ZXh0Lmxlbmd0aCA6IDA7XG4gICAgcmV0dXJuIGZvbnRMaW5lSGVpZ2h0ICogbGFiZWxIZWlnaHQ7XG59XG5mdW5jdGlvbiBpc0xpc3RlbmVkKHR5cGUsIG9wdHMpIHtcbiAgICBpZiAoKHR5cGUgPT09ICdtb3VzZW1vdmUnIHx8IHR5cGUgPT09ICdtb3VzZW91dCcpICYmIChvcHRzLm9uSG92ZXIgfHwgb3B0cy5vbkxlYXZlKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKG9wdHMub25DbGljayAmJiAodHlwZSA9PT0gJ2NsaWNrJyB8fCB0eXBlID09PSAnbW91c2V1cCcpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG52YXIgcGx1Z2luX2xlZ2VuZCA9IHtcbiAgICBpZDogJ2xlZ2VuZCcsXG4gX2VsZW1lbnQ6IExlZ2VuZCxcbiAgICBzdGFydCAoY2hhcnQsIF9hcmdzLCBvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IGxlZ2VuZCA9IGNoYXJ0LmxlZ2VuZCA9IG5ldyBMZWdlbmQoe1xuICAgICAgICAgICAgY3R4OiBjaGFydC5jdHgsXG4gICAgICAgICAgICBvcHRpb25zLFxuICAgICAgICAgICAgY2hhcnRcbiAgICAgICAgfSk7XG4gICAgICAgIGxheW91dHMuY29uZmlndXJlKGNoYXJ0LCBsZWdlbmQsIG9wdGlvbnMpO1xuICAgICAgICBsYXlvdXRzLmFkZEJveChjaGFydCwgbGVnZW5kKTtcbiAgICB9LFxuICAgIHN0b3AgKGNoYXJ0KSB7XG4gICAgICAgIGxheW91dHMucmVtb3ZlQm94KGNoYXJ0LCBjaGFydC5sZWdlbmQpO1xuICAgICAgICBkZWxldGUgY2hhcnQubGVnZW5kO1xuICAgIH0sXG4gICAgYmVmb3JlVXBkYXRlIChjaGFydCwgX2FyZ3MsIG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgbGVnZW5kID0gY2hhcnQubGVnZW5kO1xuICAgICAgICBsYXlvdXRzLmNvbmZpZ3VyZShjaGFydCwgbGVnZW5kLCBvcHRpb25zKTtcbiAgICAgICAgbGVnZW5kLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgIH0sXG4gICAgYWZ0ZXJVcGRhdGUgKGNoYXJ0KSB7XG4gICAgICAgIGNvbnN0IGxlZ2VuZCA9IGNoYXJ0LmxlZ2VuZDtcbiAgICAgICAgbGVnZW5kLmJ1aWxkTGFiZWxzKCk7XG4gICAgICAgIGxlZ2VuZC5hZGp1c3RIaXRCb3hlcygpO1xuICAgIH0sXG4gICAgYWZ0ZXJFdmVudCAoY2hhcnQsIGFyZ3MpIHtcbiAgICAgICAgaWYgKCFhcmdzLnJlcGxheSkge1xuICAgICAgICAgICAgY2hhcnQubGVnZW5kLmhhbmRsZUV2ZW50KGFyZ3MuZXZlbnQpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBkZWZhdWx0czoge1xuICAgICAgICBkaXNwbGF5OiB0cnVlLFxuICAgICAgICBwb3NpdGlvbjogJ3RvcCcsXG4gICAgICAgIGFsaWduOiAnY2VudGVyJyxcbiAgICAgICAgZnVsbFNpemU6IHRydWUsXG4gICAgICAgIHJldmVyc2U6IGZhbHNlLFxuICAgICAgICB3ZWlnaHQ6IDEwMDAsXG4gICAgICAgIG9uQ2xpY2sgKGUsIGxlZ2VuZEl0ZW0sIGxlZ2VuZCkge1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSBsZWdlbmRJdGVtLmRhdGFzZXRJbmRleDtcbiAgICAgICAgICAgIGNvbnN0IGNpID0gbGVnZW5kLmNoYXJ0O1xuICAgICAgICAgICAgaWYgKGNpLmlzRGF0YXNldFZpc2libGUoaW5kZXgpKSB7XG4gICAgICAgICAgICAgICAgY2kuaGlkZShpbmRleCk7XG4gICAgICAgICAgICAgICAgbGVnZW5kSXRlbS5oaWRkZW4gPSB0cnVlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjaS5zaG93KGluZGV4KTtcbiAgICAgICAgICAgICAgICBsZWdlbmRJdGVtLmhpZGRlbiA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBvbkhvdmVyOiBudWxsLFxuICAgICAgICBvbkxlYXZlOiBudWxsLFxuICAgICAgICBsYWJlbHM6IHtcbiAgICAgICAgICAgIGNvbG9yOiAoY3R4KT0+Y3R4LmNoYXJ0Lm9wdGlvbnMuY29sb3IsXG4gICAgICAgICAgICBib3hXaWR0aDogNDAsXG4gICAgICAgICAgICBwYWRkaW5nOiAxMCxcbiAgICAgICAgICAgIGdlbmVyYXRlTGFiZWxzIChjaGFydCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGFzZXRzID0gY2hhcnQuZGF0YS5kYXRhc2V0cztcbiAgICAgICAgICAgICAgICBjb25zdCB7IGxhYmVsczogeyB1c2VQb2ludFN0eWxlICwgcG9pbnRTdHlsZSAsIHRleHRBbGlnbiAsIGNvbG9yICwgdXNlQm9yZGVyUmFkaXVzICwgYm9yZGVyUmFkaXVzICB9ICB9ID0gY2hhcnQubGVnZW5kLm9wdGlvbnM7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNoYXJ0Ll9nZXRTb3J0ZWREYXRhc2V0TWV0YXMoKS5tYXAoKG1ldGEpPT57XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0eWxlID0gbWV0YS5jb250cm9sbGVyLmdldFN0eWxlKHVzZVBvaW50U3R5bGUgPyAwIDogdW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYm9yZGVyV2lkdGggPSB0b1BhZGRpbmcoc3R5bGUuYm9yZGVyV2lkdGgpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dDogZGF0YXNldHNbbWV0YS5pbmRleF0ubGFiZWwsXG4gICAgICAgICAgICAgICAgICAgICAgICBmaWxsU3R5bGU6IHN0eWxlLmJhY2tncm91bmRDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvbnRDb2xvcjogY29sb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICBoaWRkZW46ICFtZXRhLnZpc2libGUsXG4gICAgICAgICAgICAgICAgICAgICAgICBsaW5lQ2FwOiBzdHlsZS5ib3JkZXJDYXBTdHlsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVEYXNoOiBzdHlsZS5ib3JkZXJEYXNoLFxuICAgICAgICAgICAgICAgICAgICAgICAgbGluZURhc2hPZmZzZXQ6IHN0eWxlLmJvcmRlckRhc2hPZmZzZXQsXG4gICAgICAgICAgICAgICAgICAgICAgICBsaW5lSm9pbjogc3R5bGUuYm9yZGVySm9pblN0eWxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiAoYm9yZGVyV2lkdGgud2lkdGggKyBib3JkZXJXaWR0aC5oZWlnaHQpIC8gNCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZVN0eWxlOiBzdHlsZS5ib3JkZXJDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvaW50U3R5bGU6IHBvaW50U3R5bGUgfHwgc3R5bGUucG9pbnRTdHlsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJvdGF0aW9uOiBzdHlsZS5yb3RhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbjogdGV4dEFsaWduIHx8IHN0eWxlLnRleHRBbGlnbixcbiAgICAgICAgICAgICAgICAgICAgICAgIGJvcmRlclJhZGl1czogdXNlQm9yZGVyUmFkaXVzICYmIChib3JkZXJSYWRpdXMgfHwgc3R5bGUuYm9yZGVyUmFkaXVzKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFzZXRJbmRleDogbWV0YS5pbmRleFxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0sIHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB0aXRsZToge1xuICAgICAgICAgICAgY29sb3I6IChjdHgpPT5jdHguY2hhcnQub3B0aW9ucy5jb2xvcixcbiAgICAgICAgICAgIGRpc3BsYXk6IGZhbHNlLFxuICAgICAgICAgICAgcG9zaXRpb246ICdjZW50ZXInLFxuICAgICAgICAgICAgdGV4dDogJydcbiAgICAgICAgfVxuICAgIH0sXG4gICAgZGVzY3JpcHRvcnM6IHtcbiAgICAgICAgX3NjcmlwdGFibGU6IChuYW1lKT0+IW5hbWUuc3RhcnRzV2l0aCgnb24nKSxcbiAgICAgICAgbGFiZWxzOiB7XG4gICAgICAgICAgICBfc2NyaXB0YWJsZTogKG5hbWUpPT4hW1xuICAgICAgICAgICAgICAgICAgICAnZ2VuZXJhdGVMYWJlbHMnLFxuICAgICAgICAgICAgICAgICAgICAnZmlsdGVyJyxcbiAgICAgICAgICAgICAgICAgICAgJ3NvcnQnXG4gICAgICAgICAgICAgICAgXS5pbmNsdWRlcyhuYW1lKVxuICAgICAgICB9XG4gICAgfVxufTtcblxuY2xhc3MgVGl0bGUgZXh0ZW5kcyBFbGVtZW50IHtcbiBjb25zdHJ1Y3Rvcihjb25maWcpe1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLmNoYXJ0ID0gY29uZmlnLmNoYXJ0O1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBjb25maWcub3B0aW9ucztcbiAgICAgICAgdGhpcy5jdHggPSBjb25maWcuY3R4O1xuICAgICAgICB0aGlzLl9wYWRkaW5nID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLnRvcCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5ib3R0b20gPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMubGVmdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5yaWdodCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy53aWR0aCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5oZWlnaHQgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMucG9zaXRpb24gPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMud2VpZ2h0ID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLmZ1bGxTaXplID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICB1cGRhdGUobWF4V2lkdGgsIG1heEhlaWdodCkge1xuICAgICAgICBjb25zdCBvcHRzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB0aGlzLmxlZnQgPSAwO1xuICAgICAgICB0aGlzLnRvcCA9IDA7XG4gICAgICAgIGlmICghb3B0cy5kaXNwbGF5KSB7XG4gICAgICAgICAgICB0aGlzLndpZHRoID0gdGhpcy5oZWlnaHQgPSB0aGlzLnJpZ2h0ID0gdGhpcy5ib3R0b20gPSAwO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMud2lkdGggPSB0aGlzLnJpZ2h0ID0gbWF4V2lkdGg7XG4gICAgICAgIHRoaXMuaGVpZ2h0ID0gdGhpcy5ib3R0b20gPSBtYXhIZWlnaHQ7XG4gICAgICAgIGNvbnN0IGxpbmVDb3VudCA9IGlzQXJyYXkob3B0cy50ZXh0KSA/IG9wdHMudGV4dC5sZW5ndGggOiAxO1xuICAgICAgICB0aGlzLl9wYWRkaW5nID0gdG9QYWRkaW5nKG9wdHMucGFkZGluZyk7XG4gICAgICAgIGNvbnN0IHRleHRTaXplID0gbGluZUNvdW50ICogdG9Gb250KG9wdHMuZm9udCkubGluZUhlaWdodCArIHRoaXMuX3BhZGRpbmcuaGVpZ2h0O1xuICAgICAgICBpZiAodGhpcy5pc0hvcml6b250YWwoKSkge1xuICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSB0ZXh0U2l6ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMud2lkdGggPSB0ZXh0U2l6ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpc0hvcml6b250YWwoKSB7XG4gICAgICAgIGNvbnN0IHBvcyA9IHRoaXMub3B0aW9ucy5wb3NpdGlvbjtcbiAgICAgICAgcmV0dXJuIHBvcyA9PT0gJ3RvcCcgfHwgcG9zID09PSAnYm90dG9tJztcbiAgICB9XG4gICAgX2RyYXdBcmdzKG9mZnNldCkge1xuICAgICAgICBjb25zdCB7IHRvcCAsIGxlZnQgLCBib3R0b20gLCByaWdodCAsIG9wdGlvbnMgIH0gPSB0aGlzO1xuICAgICAgICBjb25zdCBhbGlnbiA9IG9wdGlvbnMuYWxpZ247XG4gICAgICAgIGxldCByb3RhdGlvbiA9IDA7XG4gICAgICAgIGxldCBtYXhXaWR0aCwgdGl0bGVYLCB0aXRsZVk7XG4gICAgICAgIGlmICh0aGlzLmlzSG9yaXpvbnRhbCgpKSB7XG4gICAgICAgICAgICB0aXRsZVggPSBfYWxpZ25TdGFydEVuZChhbGlnbiwgbGVmdCwgcmlnaHQpO1xuICAgICAgICAgICAgdGl0bGVZID0gdG9wICsgb2Zmc2V0O1xuICAgICAgICAgICAgbWF4V2lkdGggPSByaWdodCAtIGxlZnQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5wb3NpdGlvbiA9PT0gJ2xlZnQnKSB7XG4gICAgICAgICAgICAgICAgdGl0bGVYID0gbGVmdCArIG9mZnNldDtcbiAgICAgICAgICAgICAgICB0aXRsZVkgPSBfYWxpZ25TdGFydEVuZChhbGlnbiwgYm90dG9tLCB0b3ApO1xuICAgICAgICAgICAgICAgIHJvdGF0aW9uID0gUEkgKiAtMC41O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aXRsZVggPSByaWdodCAtIG9mZnNldDtcbiAgICAgICAgICAgICAgICB0aXRsZVkgPSBfYWxpZ25TdGFydEVuZChhbGlnbiwgdG9wLCBib3R0b20pO1xuICAgICAgICAgICAgICAgIHJvdGF0aW9uID0gUEkgKiAwLjU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBtYXhXaWR0aCA9IGJvdHRvbSAtIHRvcDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdGl0bGVYLFxuICAgICAgICAgICAgdGl0bGVZLFxuICAgICAgICAgICAgbWF4V2lkdGgsXG4gICAgICAgICAgICByb3RhdGlvblxuICAgICAgICB9O1xuICAgIH1cbiAgICBkcmF3KCkge1xuICAgICAgICBjb25zdCBjdHggPSB0aGlzLmN0eDtcbiAgICAgICAgY29uc3Qgb3B0cyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgaWYgKCFvcHRzLmRpc3BsYXkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBmb250T3B0cyA9IHRvRm9udChvcHRzLmZvbnQpO1xuICAgICAgICBjb25zdCBsaW5lSGVpZ2h0ID0gZm9udE9wdHMubGluZUhlaWdodDtcbiAgICAgICAgY29uc3Qgb2Zmc2V0ID0gbGluZUhlaWdodCAvIDIgKyB0aGlzLl9wYWRkaW5nLnRvcDtcbiAgICAgICAgY29uc3QgeyB0aXRsZVggLCB0aXRsZVkgLCBtYXhXaWR0aCAsIHJvdGF0aW9uICB9ID0gdGhpcy5fZHJhd0FyZ3Mob2Zmc2V0KTtcbiAgICAgICAgcmVuZGVyVGV4dChjdHgsIG9wdHMudGV4dCwgMCwgMCwgZm9udE9wdHMsIHtcbiAgICAgICAgICAgIGNvbG9yOiBvcHRzLmNvbG9yLFxuICAgICAgICAgICAgbWF4V2lkdGgsXG4gICAgICAgICAgICByb3RhdGlvbixcbiAgICAgICAgICAgIHRleHRBbGlnbjogX3RvTGVmdFJpZ2h0Q2VudGVyKG9wdHMuYWxpZ24pLFxuICAgICAgICAgICAgdGV4dEJhc2VsaW5lOiAnbWlkZGxlJyxcbiAgICAgICAgICAgIHRyYW5zbGF0aW9uOiBbXG4gICAgICAgICAgICAgICAgdGl0bGVYLFxuICAgICAgICAgICAgICAgIHRpdGxlWVxuICAgICAgICAgICAgXVxuICAgICAgICB9KTtcbiAgICB9XG59XG5mdW5jdGlvbiBjcmVhdGVUaXRsZShjaGFydCwgdGl0bGVPcHRzKSB7XG4gICAgY29uc3QgdGl0bGUgPSBuZXcgVGl0bGUoe1xuICAgICAgICBjdHg6IGNoYXJ0LmN0eCxcbiAgICAgICAgb3B0aW9uczogdGl0bGVPcHRzLFxuICAgICAgICBjaGFydFxuICAgIH0pO1xuICAgIGxheW91dHMuY29uZmlndXJlKGNoYXJ0LCB0aXRsZSwgdGl0bGVPcHRzKTtcbiAgICBsYXlvdXRzLmFkZEJveChjaGFydCwgdGl0bGUpO1xuICAgIGNoYXJ0LnRpdGxlQmxvY2sgPSB0aXRsZTtcbn1cbnZhciBwbHVnaW5fdGl0bGUgPSB7XG4gICAgaWQ6ICd0aXRsZScsXG4gX2VsZW1lbnQ6IFRpdGxlLFxuICAgIHN0YXJ0IChjaGFydCwgX2FyZ3MsIG9wdGlvbnMpIHtcbiAgICAgICAgY3JlYXRlVGl0bGUoY2hhcnQsIG9wdGlvbnMpO1xuICAgIH0sXG4gICAgc3RvcCAoY2hhcnQpIHtcbiAgICAgICAgY29uc3QgdGl0bGVCbG9jayA9IGNoYXJ0LnRpdGxlQmxvY2s7XG4gICAgICAgIGxheW91dHMucmVtb3ZlQm94KGNoYXJ0LCB0aXRsZUJsb2NrKTtcbiAgICAgICAgZGVsZXRlIGNoYXJ0LnRpdGxlQmxvY2s7XG4gICAgfSxcbiAgICBiZWZvcmVVcGRhdGUgKGNoYXJ0LCBfYXJncywgb3B0aW9ucykge1xuICAgICAgICBjb25zdCB0aXRsZSA9IGNoYXJ0LnRpdGxlQmxvY2s7XG4gICAgICAgIGxheW91dHMuY29uZmlndXJlKGNoYXJ0LCB0aXRsZSwgb3B0aW9ucyk7XG4gICAgICAgIHRpdGxlLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgIH0sXG4gICAgZGVmYXVsdHM6IHtcbiAgICAgICAgYWxpZ246ICdjZW50ZXInLFxuICAgICAgICBkaXNwbGF5OiBmYWxzZSxcbiAgICAgICAgZm9udDoge1xuICAgICAgICAgICAgd2VpZ2h0OiAnYm9sZCdcbiAgICAgICAgfSxcbiAgICAgICAgZnVsbFNpemU6IHRydWUsXG4gICAgICAgIHBhZGRpbmc6IDEwLFxuICAgICAgICBwb3NpdGlvbjogJ3RvcCcsXG4gICAgICAgIHRleHQ6ICcnLFxuICAgICAgICB3ZWlnaHQ6IDIwMDBcbiAgICB9LFxuICAgIGRlZmF1bHRSb3V0ZXM6IHtcbiAgICAgICAgY29sb3I6ICdjb2xvcidcbiAgICB9LFxuICAgIGRlc2NyaXB0b3JzOiB7XG4gICAgICAgIF9zY3JpcHRhYmxlOiB0cnVlLFxuICAgICAgICBfaW5kZXhhYmxlOiBmYWxzZVxuICAgIH1cbn07XG5cbmNvbnN0IG1hcCA9IG5ldyBXZWFrTWFwKCk7XG52YXIgcGx1Z2luX3N1YnRpdGxlID0ge1xuICAgIGlkOiAnc3VidGl0bGUnLFxuICAgIHN0YXJ0IChjaGFydCwgX2FyZ3MsIG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgdGl0bGUgPSBuZXcgVGl0bGUoe1xuICAgICAgICAgICAgY3R4OiBjaGFydC5jdHgsXG4gICAgICAgICAgICBvcHRpb25zLFxuICAgICAgICAgICAgY2hhcnRcbiAgICAgICAgfSk7XG4gICAgICAgIGxheW91dHMuY29uZmlndXJlKGNoYXJ0LCB0aXRsZSwgb3B0aW9ucyk7XG4gICAgICAgIGxheW91dHMuYWRkQm94KGNoYXJ0LCB0aXRsZSk7XG4gICAgICAgIG1hcC5zZXQoY2hhcnQsIHRpdGxlKTtcbiAgICB9LFxuICAgIHN0b3AgKGNoYXJ0KSB7XG4gICAgICAgIGxheW91dHMucmVtb3ZlQm94KGNoYXJ0LCBtYXAuZ2V0KGNoYXJ0KSk7XG4gICAgICAgIG1hcC5kZWxldGUoY2hhcnQpO1xuICAgIH0sXG4gICAgYmVmb3JlVXBkYXRlIChjaGFydCwgX2FyZ3MsIG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgdGl0bGUgPSBtYXAuZ2V0KGNoYXJ0KTtcbiAgICAgICAgbGF5b3V0cy5jb25maWd1cmUoY2hhcnQsIHRpdGxlLCBvcHRpb25zKTtcbiAgICAgICAgdGl0bGUub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgfSxcbiAgICBkZWZhdWx0czoge1xuICAgICAgICBhbGlnbjogJ2NlbnRlcicsXG4gICAgICAgIGRpc3BsYXk6IGZhbHNlLFxuICAgICAgICBmb250OiB7XG4gICAgICAgICAgICB3ZWlnaHQ6ICdub3JtYWwnXG4gICAgICAgIH0sXG4gICAgICAgIGZ1bGxTaXplOiB0cnVlLFxuICAgICAgICBwYWRkaW5nOiAwLFxuICAgICAgICBwb3NpdGlvbjogJ3RvcCcsXG4gICAgICAgIHRleHQ6ICcnLFxuICAgICAgICB3ZWlnaHQ6IDE1MDBcbiAgICB9LFxuICAgIGRlZmF1bHRSb3V0ZXM6IHtcbiAgICAgICAgY29sb3I6ICdjb2xvcidcbiAgICB9LFxuICAgIGRlc2NyaXB0b3JzOiB7XG4gICAgICAgIF9zY3JpcHRhYmxlOiB0cnVlLFxuICAgICAgICBfaW5kZXhhYmxlOiBmYWxzZVxuICAgIH1cbn07XG5cbmNvbnN0IHBvc2l0aW9uZXJzID0ge1xuIGF2ZXJhZ2UgKGl0ZW1zKSB7XG4gICAgICAgIGlmICghaXRlbXMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGksIGxlbjtcbiAgICAgICAgbGV0IHhTZXQgPSBuZXcgU2V0KCk7XG4gICAgICAgIGxldCB5ID0gMDtcbiAgICAgICAgbGV0IGNvdW50ID0gMDtcbiAgICAgICAgZm9yKGkgPSAwLCBsZW4gPSBpdGVtcy5sZW5ndGg7IGkgPCBsZW47ICsraSl7XG4gICAgICAgICAgICBjb25zdCBlbCA9IGl0ZW1zW2ldLmVsZW1lbnQ7XG4gICAgICAgICAgICBpZiAoZWwgJiYgZWwuaGFzVmFsdWUoKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBvcyA9IGVsLnRvb2x0aXBQb3NpdGlvbigpO1xuICAgICAgICAgICAgICAgIHhTZXQuYWRkKHBvcy54KTtcbiAgICAgICAgICAgICAgICB5ICs9IHBvcy55O1xuICAgICAgICAgICAgICAgICsrY291bnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvdW50ID09PSAwIHx8IHhTZXQuc2l6ZSA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHhBdmVyYWdlID0gW1xuICAgICAgICAgICAgLi4ueFNldFxuICAgICAgICBdLnJlZHVjZSgoYSwgYik9PmEgKyBiKSAvIHhTZXQuc2l6ZTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IHhBdmVyYWdlLFxuICAgICAgICAgICAgeTogeSAvIGNvdW50XG4gICAgICAgIH07XG4gICAgfSxcbiBuZWFyZXN0IChpdGVtcywgZXZlbnRQb3NpdGlvbikge1xuICAgICAgICBpZiAoIWl0ZW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGxldCB4ID0gZXZlbnRQb3NpdGlvbi54O1xuICAgICAgICBsZXQgeSA9IGV2ZW50UG9zaXRpb24ueTtcbiAgICAgICAgbGV0IG1pbkRpc3RhbmNlID0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO1xuICAgICAgICBsZXQgaSwgbGVuLCBuZWFyZXN0RWxlbWVudDtcbiAgICAgICAgZm9yKGkgPSAwLCBsZW4gPSBpdGVtcy5sZW5ndGg7IGkgPCBsZW47ICsraSl7XG4gICAgICAgICAgICBjb25zdCBlbCA9IGl0ZW1zW2ldLmVsZW1lbnQ7XG4gICAgICAgICAgICBpZiAoZWwgJiYgZWwuaGFzVmFsdWUoKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNlbnRlciA9IGVsLmdldENlbnRlclBvaW50KCk7XG4gICAgICAgICAgICAgICAgY29uc3QgZCA9IGRpc3RhbmNlQmV0d2VlblBvaW50cyhldmVudFBvc2l0aW9uLCBjZW50ZXIpO1xuICAgICAgICAgICAgICAgIGlmIChkIDwgbWluRGlzdGFuY2UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWluRGlzdGFuY2UgPSBkO1xuICAgICAgICAgICAgICAgICAgICBuZWFyZXN0RWxlbWVudCA9IGVsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAobmVhcmVzdEVsZW1lbnQpIHtcbiAgICAgICAgICAgIGNvbnN0IHRwID0gbmVhcmVzdEVsZW1lbnQudG9vbHRpcFBvc2l0aW9uKCk7XG4gICAgICAgICAgICB4ID0gdHAueDtcbiAgICAgICAgICAgIHkgPSB0cC55O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4LFxuICAgICAgICAgICAgeVxuICAgICAgICB9O1xuICAgIH1cbn07XG5mdW5jdGlvbiBwdXNoT3JDb25jYXQoYmFzZSwgdG9QdXNoKSB7XG4gICAgaWYgKHRvUHVzaCkge1xuICAgICAgICBpZiAoaXNBcnJheSh0b1B1c2gpKSB7XG4gICAgICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShiYXNlLCB0b1B1c2gpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYmFzZS5wdXNoKHRvUHVzaCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGJhc2U7XG59XG4gZnVuY3Rpb24gc3BsaXROZXdsaW5lcyhzdHIpIHtcbiAgICBpZiAoKHR5cGVvZiBzdHIgPT09ICdzdHJpbmcnIHx8IHN0ciBpbnN0YW5jZW9mIFN0cmluZykgJiYgc3RyLmluZGV4T2YoJ1xcbicpID4gLTEpIHtcbiAgICAgICAgcmV0dXJuIHN0ci5zcGxpdCgnXFxuJyk7XG4gICAgfVxuICAgIHJldHVybiBzdHI7XG59XG4gZnVuY3Rpb24gY3JlYXRlVG9vbHRpcEl0ZW0oY2hhcnQsIGl0ZW0pIHtcbiAgICBjb25zdCB7IGVsZW1lbnQgLCBkYXRhc2V0SW5kZXggLCBpbmRleCAgfSA9IGl0ZW07XG4gICAgY29uc3QgY29udHJvbGxlciA9IGNoYXJ0LmdldERhdGFzZXRNZXRhKGRhdGFzZXRJbmRleCkuY29udHJvbGxlcjtcbiAgICBjb25zdCB7IGxhYmVsICwgdmFsdWUgIH0gPSBjb250cm9sbGVyLmdldExhYmVsQW5kVmFsdWUoaW5kZXgpO1xuICAgIHJldHVybiB7XG4gICAgICAgIGNoYXJ0LFxuICAgICAgICBsYWJlbCxcbiAgICAgICAgcGFyc2VkOiBjb250cm9sbGVyLmdldFBhcnNlZChpbmRleCksXG4gICAgICAgIHJhdzogY2hhcnQuZGF0YS5kYXRhc2V0c1tkYXRhc2V0SW5kZXhdLmRhdGFbaW5kZXhdLFxuICAgICAgICBmb3JtYXR0ZWRWYWx1ZTogdmFsdWUsXG4gICAgICAgIGRhdGFzZXQ6IGNvbnRyb2xsZXIuZ2V0RGF0YXNldCgpLFxuICAgICAgICBkYXRhSW5kZXg6IGluZGV4LFxuICAgICAgICBkYXRhc2V0SW5kZXgsXG4gICAgICAgIGVsZW1lbnRcbiAgICB9O1xufVxuIGZ1bmN0aW9uIGdldFRvb2x0aXBTaXplKHRvb2x0aXAsIG9wdGlvbnMpIHtcbiAgICBjb25zdCBjdHggPSB0b29sdGlwLmNoYXJ0LmN0eDtcbiAgICBjb25zdCB7IGJvZHkgLCBmb290ZXIgLCB0aXRsZSAgfSA9IHRvb2x0aXA7XG4gICAgY29uc3QgeyBib3hXaWR0aCAsIGJveEhlaWdodCAgfSA9IG9wdGlvbnM7XG4gICAgY29uc3QgYm9keUZvbnQgPSB0b0ZvbnQob3B0aW9ucy5ib2R5Rm9udCk7XG4gICAgY29uc3QgdGl0bGVGb250ID0gdG9Gb250KG9wdGlvbnMudGl0bGVGb250KTtcbiAgICBjb25zdCBmb290ZXJGb250ID0gdG9Gb250KG9wdGlvbnMuZm9vdGVyRm9udCk7XG4gICAgY29uc3QgdGl0bGVMaW5lQ291bnQgPSB0aXRsZS5sZW5ndGg7XG4gICAgY29uc3QgZm9vdGVyTGluZUNvdW50ID0gZm9vdGVyLmxlbmd0aDtcbiAgICBjb25zdCBib2R5TGluZUl0ZW1Db3VudCA9IGJvZHkubGVuZ3RoO1xuICAgIGNvbnN0IHBhZGRpbmcgPSB0b1BhZGRpbmcob3B0aW9ucy5wYWRkaW5nKTtcbiAgICBsZXQgaGVpZ2h0ID0gcGFkZGluZy5oZWlnaHQ7XG4gICAgbGV0IHdpZHRoID0gMDtcbiAgICBsZXQgY29tYmluZWRCb2R5TGVuZ3RoID0gYm9keS5yZWR1Y2UoKGNvdW50LCBib2R5SXRlbSk9PmNvdW50ICsgYm9keUl0ZW0uYmVmb3JlLmxlbmd0aCArIGJvZHlJdGVtLmxpbmVzLmxlbmd0aCArIGJvZHlJdGVtLmFmdGVyLmxlbmd0aCwgMCk7XG4gICAgY29tYmluZWRCb2R5TGVuZ3RoICs9IHRvb2x0aXAuYmVmb3JlQm9keS5sZW5ndGggKyB0b29sdGlwLmFmdGVyQm9keS5sZW5ndGg7XG4gICAgaWYgKHRpdGxlTGluZUNvdW50KSB7XG4gICAgICAgIGhlaWdodCArPSB0aXRsZUxpbmVDb3VudCAqIHRpdGxlRm9udC5saW5lSGVpZ2h0ICsgKHRpdGxlTGluZUNvdW50IC0gMSkgKiBvcHRpb25zLnRpdGxlU3BhY2luZyArIG9wdGlvbnMudGl0bGVNYXJnaW5Cb3R0b207XG4gICAgfVxuICAgIGlmIChjb21iaW5lZEJvZHlMZW5ndGgpIHtcbiAgICAgICAgY29uc3QgYm9keUxpbmVIZWlnaHQgPSBvcHRpb25zLmRpc3BsYXlDb2xvcnMgPyBNYXRoLm1heChib3hIZWlnaHQsIGJvZHlGb250LmxpbmVIZWlnaHQpIDogYm9keUZvbnQubGluZUhlaWdodDtcbiAgICAgICAgaGVpZ2h0ICs9IGJvZHlMaW5lSXRlbUNvdW50ICogYm9keUxpbmVIZWlnaHQgKyAoY29tYmluZWRCb2R5TGVuZ3RoIC0gYm9keUxpbmVJdGVtQ291bnQpICogYm9keUZvbnQubGluZUhlaWdodCArIChjb21iaW5lZEJvZHlMZW5ndGggLSAxKSAqIG9wdGlvbnMuYm9keVNwYWNpbmc7XG4gICAgfVxuICAgIGlmIChmb290ZXJMaW5lQ291bnQpIHtcbiAgICAgICAgaGVpZ2h0ICs9IG9wdGlvbnMuZm9vdGVyTWFyZ2luVG9wICsgZm9vdGVyTGluZUNvdW50ICogZm9vdGVyRm9udC5saW5lSGVpZ2h0ICsgKGZvb3RlckxpbmVDb3VudCAtIDEpICogb3B0aW9ucy5mb290ZXJTcGFjaW5nO1xuICAgIH1cbiAgICBsZXQgd2lkdGhQYWRkaW5nID0gMDtcbiAgICBjb25zdCBtYXhMaW5lV2lkdGggPSBmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgIHdpZHRoID0gTWF0aC5tYXgod2lkdGgsIGN0eC5tZWFzdXJlVGV4dChsaW5lKS53aWR0aCArIHdpZHRoUGFkZGluZyk7XG4gICAgfTtcbiAgICBjdHguc2F2ZSgpO1xuICAgIGN0eC5mb250ID0gdGl0bGVGb250LnN0cmluZztcbiAgICBlYWNoKHRvb2x0aXAudGl0bGUsIG1heExpbmVXaWR0aCk7XG4gICAgY3R4LmZvbnQgPSBib2R5Rm9udC5zdHJpbmc7XG4gICAgZWFjaCh0b29sdGlwLmJlZm9yZUJvZHkuY29uY2F0KHRvb2x0aXAuYWZ0ZXJCb2R5KSwgbWF4TGluZVdpZHRoKTtcbiAgICB3aWR0aFBhZGRpbmcgPSBvcHRpb25zLmRpc3BsYXlDb2xvcnMgPyBib3hXaWR0aCArIDIgKyBvcHRpb25zLmJveFBhZGRpbmcgOiAwO1xuICAgIGVhY2goYm9keSwgKGJvZHlJdGVtKT0+e1xuICAgICAgICBlYWNoKGJvZHlJdGVtLmJlZm9yZSwgbWF4TGluZVdpZHRoKTtcbiAgICAgICAgZWFjaChib2R5SXRlbS5saW5lcywgbWF4TGluZVdpZHRoKTtcbiAgICAgICAgZWFjaChib2R5SXRlbS5hZnRlciwgbWF4TGluZVdpZHRoKTtcbiAgICB9KTtcbiAgICB3aWR0aFBhZGRpbmcgPSAwO1xuICAgIGN0eC5mb250ID0gZm9vdGVyRm9udC5zdHJpbmc7XG4gICAgZWFjaCh0b29sdGlwLmZvb3RlciwgbWF4TGluZVdpZHRoKTtcbiAgICBjdHgucmVzdG9yZSgpO1xuICAgIHdpZHRoICs9IHBhZGRpbmcud2lkdGg7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgd2lkdGgsXG4gICAgICAgIGhlaWdodFxuICAgIH07XG59XG5mdW5jdGlvbiBkZXRlcm1pbmVZQWxpZ24oY2hhcnQsIHNpemUpIHtcbiAgICBjb25zdCB7IHkgLCBoZWlnaHQgIH0gPSBzaXplO1xuICAgIGlmICh5IDwgaGVpZ2h0IC8gMikge1xuICAgICAgICByZXR1cm4gJ3RvcCc7XG4gICAgfSBlbHNlIGlmICh5ID4gY2hhcnQuaGVpZ2h0IC0gaGVpZ2h0IC8gMikge1xuICAgICAgICByZXR1cm4gJ2JvdHRvbSc7XG4gICAgfVxuICAgIHJldHVybiAnY2VudGVyJztcbn1cbmZ1bmN0aW9uIGRvZXNOb3RGaXRXaXRoQWxpZ24oeEFsaWduLCBjaGFydCwgb3B0aW9ucywgc2l6ZSkge1xuICAgIGNvbnN0IHsgeCAsIHdpZHRoICB9ID0gc2l6ZTtcbiAgICBjb25zdCBjYXJldCA9IG9wdGlvbnMuY2FyZXRTaXplICsgb3B0aW9ucy5jYXJldFBhZGRpbmc7XG4gICAgaWYgKHhBbGlnbiA9PT0gJ2xlZnQnICYmIHggKyB3aWR0aCArIGNhcmV0ID4gY2hhcnQud2lkdGgpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmICh4QWxpZ24gPT09ICdyaWdodCcgJiYgeCAtIHdpZHRoIC0gY2FyZXQgPCAwKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGRldGVybWluZVhBbGlnbihjaGFydCwgb3B0aW9ucywgc2l6ZSwgeUFsaWduKSB7XG4gICAgY29uc3QgeyB4ICwgd2lkdGggIH0gPSBzaXplO1xuICAgIGNvbnN0IHsgd2lkdGg6IGNoYXJ0V2lkdGggLCBjaGFydEFyZWE6IHsgbGVmdCAsIHJpZ2h0ICB9ICB9ID0gY2hhcnQ7XG4gICAgbGV0IHhBbGlnbiA9ICdjZW50ZXInO1xuICAgIGlmICh5QWxpZ24gPT09ICdjZW50ZXInKSB7XG4gICAgICAgIHhBbGlnbiA9IHggPD0gKGxlZnQgKyByaWdodCkgLyAyID8gJ2xlZnQnIDogJ3JpZ2h0JztcbiAgICB9IGVsc2UgaWYgKHggPD0gd2lkdGggLyAyKSB7XG4gICAgICAgIHhBbGlnbiA9ICdsZWZ0JztcbiAgICB9IGVsc2UgaWYgKHggPj0gY2hhcnRXaWR0aCAtIHdpZHRoIC8gMikge1xuICAgICAgICB4QWxpZ24gPSAncmlnaHQnO1xuICAgIH1cbiAgICBpZiAoZG9lc05vdEZpdFdpdGhBbGlnbih4QWxpZ24sIGNoYXJ0LCBvcHRpb25zLCBzaXplKSkge1xuICAgICAgICB4QWxpZ24gPSAnY2VudGVyJztcbiAgICB9XG4gICAgcmV0dXJuIHhBbGlnbjtcbn1cbiBmdW5jdGlvbiBkZXRlcm1pbmVBbGlnbm1lbnQoY2hhcnQsIG9wdGlvbnMsIHNpemUpIHtcbiAgICBjb25zdCB5QWxpZ24gPSBzaXplLnlBbGlnbiB8fCBvcHRpb25zLnlBbGlnbiB8fCBkZXRlcm1pbmVZQWxpZ24oY2hhcnQsIHNpemUpO1xuICAgIHJldHVybiB7XG4gICAgICAgIHhBbGlnbjogc2l6ZS54QWxpZ24gfHwgb3B0aW9ucy54QWxpZ24gfHwgZGV0ZXJtaW5lWEFsaWduKGNoYXJ0LCBvcHRpb25zLCBzaXplLCB5QWxpZ24pLFxuICAgICAgICB5QWxpZ25cbiAgICB9O1xufVxuZnVuY3Rpb24gYWxpZ25YKHNpemUsIHhBbGlnbikge1xuICAgIGxldCB7IHggLCB3aWR0aCAgfSA9IHNpemU7XG4gICAgaWYgKHhBbGlnbiA9PT0gJ3JpZ2h0Jykge1xuICAgICAgICB4IC09IHdpZHRoO1xuICAgIH0gZWxzZSBpZiAoeEFsaWduID09PSAnY2VudGVyJykge1xuICAgICAgICB4IC09IHdpZHRoIC8gMjtcbiAgICB9XG4gICAgcmV0dXJuIHg7XG59XG5mdW5jdGlvbiBhbGlnblkoc2l6ZSwgeUFsaWduLCBwYWRkaW5nQW5kU2l6ZSkge1xuICAgIGxldCB7IHkgLCBoZWlnaHQgIH0gPSBzaXplO1xuICAgIGlmICh5QWxpZ24gPT09ICd0b3AnKSB7XG4gICAgICAgIHkgKz0gcGFkZGluZ0FuZFNpemU7XG4gICAgfSBlbHNlIGlmICh5QWxpZ24gPT09ICdib3R0b20nKSB7XG4gICAgICAgIHkgLT0gaGVpZ2h0ICsgcGFkZGluZ0FuZFNpemU7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgeSAtPSBoZWlnaHQgLyAyO1xuICAgIH1cbiAgICByZXR1cm4geTtcbn1cbiBmdW5jdGlvbiBnZXRCYWNrZ3JvdW5kUG9pbnQob3B0aW9ucywgc2l6ZSwgYWxpZ25tZW50LCBjaGFydCkge1xuICAgIGNvbnN0IHsgY2FyZXRTaXplICwgY2FyZXRQYWRkaW5nICwgY29ybmVyUmFkaXVzICB9ID0gb3B0aW9ucztcbiAgICBjb25zdCB7IHhBbGlnbiAsIHlBbGlnbiAgfSA9IGFsaWdubWVudDtcbiAgICBjb25zdCBwYWRkaW5nQW5kU2l6ZSA9IGNhcmV0U2l6ZSArIGNhcmV0UGFkZGluZztcbiAgICBjb25zdCB7IHRvcExlZnQgLCB0b3BSaWdodCAsIGJvdHRvbUxlZnQgLCBib3R0b21SaWdodCAgfSA9IHRvVFJCTENvcm5lcnMoY29ybmVyUmFkaXVzKTtcbiAgICBsZXQgeCA9IGFsaWduWChzaXplLCB4QWxpZ24pO1xuICAgIGNvbnN0IHkgPSBhbGlnblkoc2l6ZSwgeUFsaWduLCBwYWRkaW5nQW5kU2l6ZSk7XG4gICAgaWYgKHlBbGlnbiA9PT0gJ2NlbnRlcicpIHtcbiAgICAgICAgaWYgKHhBbGlnbiA9PT0gJ2xlZnQnKSB7XG4gICAgICAgICAgICB4ICs9IHBhZGRpbmdBbmRTaXplO1xuICAgICAgICB9IGVsc2UgaWYgKHhBbGlnbiA9PT0gJ3JpZ2h0Jykge1xuICAgICAgICAgICAgeCAtPSBwYWRkaW5nQW5kU2l6ZTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAoeEFsaWduID09PSAnbGVmdCcpIHtcbiAgICAgICAgeCAtPSBNYXRoLm1heCh0b3BMZWZ0LCBib3R0b21MZWZ0KSArIGNhcmV0U2l6ZTtcbiAgICB9IGVsc2UgaWYgKHhBbGlnbiA9PT0gJ3JpZ2h0Jykge1xuICAgICAgICB4ICs9IE1hdGgubWF4KHRvcFJpZ2h0LCBib3R0b21SaWdodCkgKyBjYXJldFNpemU7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHg6IF9saW1pdFZhbHVlKHgsIDAsIGNoYXJ0LndpZHRoIC0gc2l6ZS53aWR0aCksXG4gICAgICAgIHk6IF9saW1pdFZhbHVlKHksIDAsIGNoYXJ0LmhlaWdodCAtIHNpemUuaGVpZ2h0KVxuICAgIH07XG59XG5mdW5jdGlvbiBnZXRBbGlnbmVkWCh0b29sdGlwLCBhbGlnbiwgb3B0aW9ucykge1xuICAgIGNvbnN0IHBhZGRpbmcgPSB0b1BhZGRpbmcob3B0aW9ucy5wYWRkaW5nKTtcbiAgICByZXR1cm4gYWxpZ24gPT09ICdjZW50ZXInID8gdG9vbHRpcC54ICsgdG9vbHRpcC53aWR0aCAvIDIgOiBhbGlnbiA9PT0gJ3JpZ2h0JyA/IHRvb2x0aXAueCArIHRvb2x0aXAud2lkdGggLSBwYWRkaW5nLnJpZ2h0IDogdG9vbHRpcC54ICsgcGFkZGluZy5sZWZ0O1xufVxuIGZ1bmN0aW9uIGdldEJlZm9yZUFmdGVyQm9keUxpbmVzKGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIHB1c2hPckNvbmNhdChbXSwgc3BsaXROZXdsaW5lcyhjYWxsYmFjaykpO1xufVxuZnVuY3Rpb24gY3JlYXRlVG9vbHRpcENvbnRleHQocGFyZW50LCB0b29sdGlwLCB0b29sdGlwSXRlbXMpIHtcbiAgICByZXR1cm4gY3JlYXRlQ29udGV4dChwYXJlbnQsIHtcbiAgICAgICAgdG9vbHRpcCxcbiAgICAgICAgdG9vbHRpcEl0ZW1zLFxuICAgICAgICB0eXBlOiAndG9vbHRpcCdcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIG92ZXJyaWRlQ2FsbGJhY2tzKGNhbGxiYWNrcywgY29udGV4dCkge1xuICAgIGNvbnN0IG92ZXJyaWRlID0gY29udGV4dCAmJiBjb250ZXh0LmRhdGFzZXQgJiYgY29udGV4dC5kYXRhc2V0LnRvb2x0aXAgJiYgY29udGV4dC5kYXRhc2V0LnRvb2x0aXAuY2FsbGJhY2tzO1xuICAgIHJldHVybiBvdmVycmlkZSA/IGNhbGxiYWNrcy5vdmVycmlkZShvdmVycmlkZSkgOiBjYWxsYmFja3M7XG59XG5jb25zdCBkZWZhdWx0Q2FsbGJhY2tzID0ge1xuICAgIGJlZm9yZVRpdGxlOiBub29wLFxuICAgIHRpdGxlICh0b29sdGlwSXRlbXMpIHtcbiAgICAgICAgaWYgKHRvb2x0aXBJdGVtcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb25zdCBpdGVtID0gdG9vbHRpcEl0ZW1zWzBdO1xuICAgICAgICAgICAgY29uc3QgbGFiZWxzID0gaXRlbS5jaGFydC5kYXRhLmxhYmVscztcbiAgICAgICAgICAgIGNvbnN0IGxhYmVsQ291bnQgPSBsYWJlbHMgPyBsYWJlbHMubGVuZ3RoIDogMDtcbiAgICAgICAgICAgIGlmICh0aGlzICYmIHRoaXMub3B0aW9ucyAmJiB0aGlzLm9wdGlvbnMubW9kZSA9PT0gJ2RhdGFzZXQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW0uZGF0YXNldC5sYWJlbCB8fCAnJztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXRlbS5sYWJlbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpdGVtLmxhYmVsO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChsYWJlbENvdW50ID4gMCAmJiBpdGVtLmRhdGFJbmRleCA8IGxhYmVsQ291bnQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbGFiZWxzW2l0ZW0uZGF0YUluZGV4XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gJyc7XG4gICAgfSxcbiAgICBhZnRlclRpdGxlOiBub29wLFxuICAgIGJlZm9yZUJvZHk6IG5vb3AsXG4gICAgYmVmb3JlTGFiZWw6IG5vb3AsXG4gICAgbGFiZWwgKHRvb2x0aXBJdGVtKSB7XG4gICAgICAgIGlmICh0aGlzICYmIHRoaXMub3B0aW9ucyAmJiB0aGlzLm9wdGlvbnMubW9kZSA9PT0gJ2RhdGFzZXQnKSB7XG4gICAgICAgICAgICByZXR1cm4gdG9vbHRpcEl0ZW0ubGFiZWwgKyAnOiAnICsgdG9vbHRpcEl0ZW0uZm9ybWF0dGVkVmFsdWUgfHwgdG9vbHRpcEl0ZW0uZm9ybWF0dGVkVmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGxhYmVsID0gdG9vbHRpcEl0ZW0uZGF0YXNldC5sYWJlbCB8fCAnJztcbiAgICAgICAgaWYgKGxhYmVsKSB7XG4gICAgICAgICAgICBsYWJlbCArPSAnOiAnO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHZhbHVlID0gdG9vbHRpcEl0ZW0uZm9ybWF0dGVkVmFsdWU7XG4gICAgICAgIGlmICghaXNOdWxsT3JVbmRlZih2YWx1ZSkpIHtcbiAgICAgICAgICAgIGxhYmVsICs9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBsYWJlbDtcbiAgICB9LFxuICAgIGxhYmVsQ29sb3IgKHRvb2x0aXBJdGVtKSB7XG4gICAgICAgIGNvbnN0IG1ldGEgPSB0b29sdGlwSXRlbS5jaGFydC5nZXREYXRhc2V0TWV0YSh0b29sdGlwSXRlbS5kYXRhc2V0SW5kZXgpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gbWV0YS5jb250cm9sbGVyLmdldFN0eWxlKHRvb2x0aXBJdGVtLmRhdGFJbmRleCk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBib3JkZXJDb2xvcjogb3B0aW9ucy5ib3JkZXJDb2xvcixcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogb3B0aW9ucy5iYWNrZ3JvdW5kQ29sb3IsXG4gICAgICAgICAgICBib3JkZXJXaWR0aDogb3B0aW9ucy5ib3JkZXJXaWR0aCxcbiAgICAgICAgICAgIGJvcmRlckRhc2g6IG9wdGlvbnMuYm9yZGVyRGFzaCxcbiAgICAgICAgICAgIGJvcmRlckRhc2hPZmZzZXQ6IG9wdGlvbnMuYm9yZGVyRGFzaE9mZnNldCxcbiAgICAgICAgICAgIGJvcmRlclJhZGl1czogMFxuICAgICAgICB9O1xuICAgIH0sXG4gICAgbGFiZWxUZXh0Q29sb3IgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLmJvZHlDb2xvcjtcbiAgICB9LFxuICAgIGxhYmVsUG9pbnRTdHlsZSAodG9vbHRpcEl0ZW0pIHtcbiAgICAgICAgY29uc3QgbWV0YSA9IHRvb2x0aXBJdGVtLmNoYXJ0LmdldERhdGFzZXRNZXRhKHRvb2x0aXBJdGVtLmRhdGFzZXRJbmRleCk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBtZXRhLmNvbnRyb2xsZXIuZ2V0U3R5bGUodG9vbHRpcEl0ZW0uZGF0YUluZGV4KTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHBvaW50U3R5bGU6IG9wdGlvbnMucG9pbnRTdHlsZSxcbiAgICAgICAgICAgIHJvdGF0aW9uOiBvcHRpb25zLnJvdGF0aW9uXG4gICAgICAgIH07XG4gICAgfSxcbiAgICBhZnRlckxhYmVsOiBub29wLFxuICAgIGFmdGVyQm9keTogbm9vcCxcbiAgICBiZWZvcmVGb290ZXI6IG5vb3AsXG4gICAgZm9vdGVyOiBub29wLFxuICAgIGFmdGVyRm9vdGVyOiBub29wXG59O1xuIGZ1bmN0aW9uIGludm9rZUNhbGxiYWNrV2l0aEZhbGxiYWNrKGNhbGxiYWNrcywgbmFtZSwgY3R4LCBhcmcpIHtcbiAgICBjb25zdCByZXN1bHQgPSBjYWxsYmFja3NbbmFtZV0uY2FsbChjdHgsIGFyZyk7XG4gICAgaWYgKHR5cGVvZiByZXN1bHQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHJldHVybiBkZWZhdWx0Q2FsbGJhY2tzW25hbWVdLmNhbGwoY3R4LCBhcmcpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuY2xhc3MgVG9vbHRpcCBleHRlbmRzIEVsZW1lbnQge1xuIHN0YXRpYyBwb3NpdGlvbmVycyA9IHBvc2l0aW9uZXJzO1xuICAgIGNvbnN0cnVjdG9yKGNvbmZpZyl7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMub3BhY2l0eSA9IDA7XG4gICAgICAgIHRoaXMuX2FjdGl2ZSA9IFtdO1xuICAgICAgICB0aGlzLl9ldmVudFBvc2l0aW9uID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl9zaXplID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl9jYWNoZWRBbmltYXRpb25zID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl90b29sdGlwSXRlbXMgPSBbXTtcbiAgICAgICAgdGhpcy4kYW5pbWF0aW9ucyA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy4kY29udGV4dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5jaGFydCA9IGNvbmZpZy5jaGFydDtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gY29uZmlnLm9wdGlvbnM7XG4gICAgICAgIHRoaXMuZGF0YVBvaW50cyA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy50aXRsZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5iZWZvcmVCb2R5ID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLmJvZHkgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuYWZ0ZXJCb2R5ID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLmZvb3RlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy54QWxpZ24gPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMueUFsaWduID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLnggPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMueSA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5oZWlnaHQgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMud2lkdGggPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuY2FyZXRYID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLmNhcmV0WSA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5sYWJlbENvbG9ycyA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5sYWJlbFBvaW50U3R5bGVzID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLmxhYmVsVGV4dENvbG9ycyA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgaW5pdGlhbGl6ZShvcHRpb25zKSB7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgICAgIHRoaXMuX2NhY2hlZEFuaW1hdGlvbnMgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuJGNvbnRleHQgPSB1bmRlZmluZWQ7XG4gICAgfVxuIF9yZXNvbHZlQW5pbWF0aW9ucygpIHtcbiAgICAgICAgY29uc3QgY2FjaGVkID0gdGhpcy5fY2FjaGVkQW5pbWF0aW9ucztcbiAgICAgICAgaWYgKGNhY2hlZCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjaGFydCA9IHRoaXMuY2hhcnQ7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLm9wdGlvbnMuc2V0Q29udGV4dCh0aGlzLmdldENvbnRleHQoKSk7XG4gICAgICAgIGNvbnN0IG9wdHMgPSBvcHRpb25zLmVuYWJsZWQgJiYgY2hhcnQub3B0aW9ucy5hbmltYXRpb24gJiYgb3B0aW9ucy5hbmltYXRpb25zO1xuICAgICAgICBjb25zdCBhbmltYXRpb25zID0gbmV3IEFuaW1hdGlvbnModGhpcy5jaGFydCwgb3B0cyk7XG4gICAgICAgIGlmIChvcHRzLl9jYWNoZWFibGUpIHtcbiAgICAgICAgICAgIHRoaXMuX2NhY2hlZEFuaW1hdGlvbnMgPSBPYmplY3QuZnJlZXplKGFuaW1hdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhbmltYXRpb25zO1xuICAgIH1cbiBnZXRDb250ZXh0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy4kY29udGV4dCB8fCAodGhpcy4kY29udGV4dCA9IGNyZWF0ZVRvb2x0aXBDb250ZXh0KHRoaXMuY2hhcnQuZ2V0Q29udGV4dCgpLCB0aGlzLCB0aGlzLl90b29sdGlwSXRlbXMpKTtcbiAgICB9XG4gICAgZ2V0VGl0bGUoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICBjb25zdCB7IGNhbGxiYWNrcyAgfSA9IG9wdGlvbnM7XG4gICAgICAgIGNvbnN0IGJlZm9yZVRpdGxlID0gaW52b2tlQ2FsbGJhY2tXaXRoRmFsbGJhY2soY2FsbGJhY2tzLCAnYmVmb3JlVGl0bGUnLCB0aGlzLCBjb250ZXh0KTtcbiAgICAgICAgY29uc3QgdGl0bGUgPSBpbnZva2VDYWxsYmFja1dpdGhGYWxsYmFjayhjYWxsYmFja3MsICd0aXRsZScsIHRoaXMsIGNvbnRleHQpO1xuICAgICAgICBjb25zdCBhZnRlclRpdGxlID0gaW52b2tlQ2FsbGJhY2tXaXRoRmFsbGJhY2soY2FsbGJhY2tzLCAnYWZ0ZXJUaXRsZScsIHRoaXMsIGNvbnRleHQpO1xuICAgICAgICBsZXQgbGluZXMgPSBbXTtcbiAgICAgICAgbGluZXMgPSBwdXNoT3JDb25jYXQobGluZXMsIHNwbGl0TmV3bGluZXMoYmVmb3JlVGl0bGUpKTtcbiAgICAgICAgbGluZXMgPSBwdXNoT3JDb25jYXQobGluZXMsIHNwbGl0TmV3bGluZXModGl0bGUpKTtcbiAgICAgICAgbGluZXMgPSBwdXNoT3JDb25jYXQobGluZXMsIHNwbGl0TmV3bGluZXMoYWZ0ZXJUaXRsZSkpO1xuICAgICAgICByZXR1cm4gbGluZXM7XG4gICAgfVxuICAgIGdldEJlZm9yZUJvZHkodG9vbHRpcEl0ZW1zLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiBnZXRCZWZvcmVBZnRlckJvZHlMaW5lcyhpbnZva2VDYWxsYmFja1dpdGhGYWxsYmFjayhvcHRpb25zLmNhbGxiYWNrcywgJ2JlZm9yZUJvZHknLCB0aGlzLCB0b29sdGlwSXRlbXMpKTtcbiAgICB9XG4gICAgZ2V0Qm9keSh0b29sdGlwSXRlbXMsIG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgeyBjYWxsYmFja3MgIH0gPSBvcHRpb25zO1xuICAgICAgICBjb25zdCBib2R5SXRlbXMgPSBbXTtcbiAgICAgICAgZWFjaCh0b29sdGlwSXRlbXMsIChjb250ZXh0KT0+e1xuICAgICAgICAgICAgY29uc3QgYm9keUl0ZW0gPSB7XG4gICAgICAgICAgICAgICAgYmVmb3JlOiBbXSxcbiAgICAgICAgICAgICAgICBsaW5lczogW10sXG4gICAgICAgICAgICAgICAgYWZ0ZXI6IFtdXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3Qgc2NvcGVkID0gb3ZlcnJpZGVDYWxsYmFja3MoY2FsbGJhY2tzLCBjb250ZXh0KTtcbiAgICAgICAgICAgIHB1c2hPckNvbmNhdChib2R5SXRlbS5iZWZvcmUsIHNwbGl0TmV3bGluZXMoaW52b2tlQ2FsbGJhY2tXaXRoRmFsbGJhY2soc2NvcGVkLCAnYmVmb3JlTGFiZWwnLCB0aGlzLCBjb250ZXh0KSkpO1xuICAgICAgICAgICAgcHVzaE9yQ29uY2F0KGJvZHlJdGVtLmxpbmVzLCBpbnZva2VDYWxsYmFja1dpdGhGYWxsYmFjayhzY29wZWQsICdsYWJlbCcsIHRoaXMsIGNvbnRleHQpKTtcbiAgICAgICAgICAgIHB1c2hPckNvbmNhdChib2R5SXRlbS5hZnRlciwgc3BsaXROZXdsaW5lcyhpbnZva2VDYWxsYmFja1dpdGhGYWxsYmFjayhzY29wZWQsICdhZnRlckxhYmVsJywgdGhpcywgY29udGV4dCkpKTtcbiAgICAgICAgICAgIGJvZHlJdGVtcy5wdXNoKGJvZHlJdGVtKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBib2R5SXRlbXM7XG4gICAgfVxuICAgIGdldEFmdGVyQm9keSh0b29sdGlwSXRlbXMsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIGdldEJlZm9yZUFmdGVyQm9keUxpbmVzKGludm9rZUNhbGxiYWNrV2l0aEZhbGxiYWNrKG9wdGlvbnMuY2FsbGJhY2tzLCAnYWZ0ZXJCb2R5JywgdGhpcywgdG9vbHRpcEl0ZW1zKSk7XG4gICAgfVxuICAgIGdldEZvb3Rlcih0b29sdGlwSXRlbXMsIG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgeyBjYWxsYmFja3MgIH0gPSBvcHRpb25zO1xuICAgICAgICBjb25zdCBiZWZvcmVGb290ZXIgPSBpbnZva2VDYWxsYmFja1dpdGhGYWxsYmFjayhjYWxsYmFja3MsICdiZWZvcmVGb290ZXInLCB0aGlzLCB0b29sdGlwSXRlbXMpO1xuICAgICAgICBjb25zdCBmb290ZXIgPSBpbnZva2VDYWxsYmFja1dpdGhGYWxsYmFjayhjYWxsYmFja3MsICdmb290ZXInLCB0aGlzLCB0b29sdGlwSXRlbXMpO1xuICAgICAgICBjb25zdCBhZnRlckZvb3RlciA9IGludm9rZUNhbGxiYWNrV2l0aEZhbGxiYWNrKGNhbGxiYWNrcywgJ2FmdGVyRm9vdGVyJywgdGhpcywgdG9vbHRpcEl0ZW1zKTtcbiAgICAgICAgbGV0IGxpbmVzID0gW107XG4gICAgICAgIGxpbmVzID0gcHVzaE9yQ29uY2F0KGxpbmVzLCBzcGxpdE5ld2xpbmVzKGJlZm9yZUZvb3RlcikpO1xuICAgICAgICBsaW5lcyA9IHB1c2hPckNvbmNhdChsaW5lcywgc3BsaXROZXdsaW5lcyhmb290ZXIpKTtcbiAgICAgICAgbGluZXMgPSBwdXNoT3JDb25jYXQobGluZXMsIHNwbGl0TmV3bGluZXMoYWZ0ZXJGb290ZXIpKTtcbiAgICAgICAgcmV0dXJuIGxpbmVzO1xuICAgIH1cbiBfY3JlYXRlSXRlbXMob3B0aW9ucykge1xuICAgICAgICBjb25zdCBhY3RpdmUgPSB0aGlzLl9hY3RpdmU7XG4gICAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmNoYXJ0LmRhdGE7XG4gICAgICAgIGNvbnN0IGxhYmVsQ29sb3JzID0gW107XG4gICAgICAgIGNvbnN0IGxhYmVsUG9pbnRTdHlsZXMgPSBbXTtcbiAgICAgICAgY29uc3QgbGFiZWxUZXh0Q29sb3JzID0gW107XG4gICAgICAgIGxldCB0b29sdGlwSXRlbXMgPSBbXTtcbiAgICAgICAgbGV0IGksIGxlbjtcbiAgICAgICAgZm9yKGkgPSAwLCBsZW4gPSBhY3RpdmUubGVuZ3RoOyBpIDwgbGVuOyArK2kpe1xuICAgICAgICAgICAgdG9vbHRpcEl0ZW1zLnB1c2goY3JlYXRlVG9vbHRpcEl0ZW0odGhpcy5jaGFydCwgYWN0aXZlW2ldKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdGlvbnMuZmlsdGVyKSB7XG4gICAgICAgICAgICB0b29sdGlwSXRlbXMgPSB0b29sdGlwSXRlbXMuZmlsdGVyKChlbGVtZW50LCBpbmRleCwgYXJyYXkpPT5vcHRpb25zLmZpbHRlcihlbGVtZW50LCBpbmRleCwgYXJyYXksIGRhdGEpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0aW9ucy5pdGVtU29ydCkge1xuICAgICAgICAgICAgdG9vbHRpcEl0ZW1zID0gdG9vbHRpcEl0ZW1zLnNvcnQoKGEsIGIpPT5vcHRpb25zLml0ZW1Tb3J0KGEsIGIsIGRhdGEpKTtcbiAgICAgICAgfVxuICAgICAgICBlYWNoKHRvb2x0aXBJdGVtcywgKGNvbnRleHQpPT57XG4gICAgICAgICAgICBjb25zdCBzY29wZWQgPSBvdmVycmlkZUNhbGxiYWNrcyhvcHRpb25zLmNhbGxiYWNrcywgY29udGV4dCk7XG4gICAgICAgICAgICBsYWJlbENvbG9ycy5wdXNoKGludm9rZUNhbGxiYWNrV2l0aEZhbGxiYWNrKHNjb3BlZCwgJ2xhYmVsQ29sb3InLCB0aGlzLCBjb250ZXh0KSk7XG4gICAgICAgICAgICBsYWJlbFBvaW50U3R5bGVzLnB1c2goaW52b2tlQ2FsbGJhY2tXaXRoRmFsbGJhY2soc2NvcGVkLCAnbGFiZWxQb2ludFN0eWxlJywgdGhpcywgY29udGV4dCkpO1xuICAgICAgICAgICAgbGFiZWxUZXh0Q29sb3JzLnB1c2goaW52b2tlQ2FsbGJhY2tXaXRoRmFsbGJhY2soc2NvcGVkLCAnbGFiZWxUZXh0Q29sb3InLCB0aGlzLCBjb250ZXh0KSk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmxhYmVsQ29sb3JzID0gbGFiZWxDb2xvcnM7XG4gICAgICAgIHRoaXMubGFiZWxQb2ludFN0eWxlcyA9IGxhYmVsUG9pbnRTdHlsZXM7XG4gICAgICAgIHRoaXMubGFiZWxUZXh0Q29sb3JzID0gbGFiZWxUZXh0Q29sb3JzO1xuICAgICAgICB0aGlzLmRhdGFQb2ludHMgPSB0b29sdGlwSXRlbXM7XG4gICAgICAgIHJldHVybiB0b29sdGlwSXRlbXM7XG4gICAgfVxuICAgIHVwZGF0ZShjaGFuZ2VkLCByZXBsYXkpIHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucy5zZXRDb250ZXh0KHRoaXMuZ2V0Q29udGV4dCgpKTtcbiAgICAgICAgY29uc3QgYWN0aXZlID0gdGhpcy5fYWN0aXZlO1xuICAgICAgICBsZXQgcHJvcGVydGllcztcbiAgICAgICAgbGV0IHRvb2x0aXBJdGVtcyA9IFtdO1xuICAgICAgICBpZiAoIWFjdGl2ZS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLm9wYWNpdHkgIT09IDApIHtcbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgICAgICAgICBvcGFjaXR5OiAwXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uID0gcG9zaXRpb25lcnNbb3B0aW9ucy5wb3NpdGlvbl0uY2FsbCh0aGlzLCBhY3RpdmUsIHRoaXMuX2V2ZW50UG9zaXRpb24pO1xuICAgICAgICAgICAgdG9vbHRpcEl0ZW1zID0gdGhpcy5fY3JlYXRlSXRlbXMob3B0aW9ucyk7XG4gICAgICAgICAgICB0aGlzLnRpdGxlID0gdGhpcy5nZXRUaXRsZSh0b29sdGlwSXRlbXMsIG9wdGlvbnMpO1xuICAgICAgICAgICAgdGhpcy5iZWZvcmVCb2R5ID0gdGhpcy5nZXRCZWZvcmVCb2R5KHRvb2x0aXBJdGVtcywgb3B0aW9ucyk7XG4gICAgICAgICAgICB0aGlzLmJvZHkgPSB0aGlzLmdldEJvZHkodG9vbHRpcEl0ZW1zLCBvcHRpb25zKTtcbiAgICAgICAgICAgIHRoaXMuYWZ0ZXJCb2R5ID0gdGhpcy5nZXRBZnRlckJvZHkodG9vbHRpcEl0ZW1zLCBvcHRpb25zKTtcbiAgICAgICAgICAgIHRoaXMuZm9vdGVyID0gdGhpcy5nZXRGb290ZXIodG9vbHRpcEl0ZW1zLCBvcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IHNpemUgPSB0aGlzLl9zaXplID0gZ2V0VG9vbHRpcFNpemUodGhpcywgb3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBwb3NpdGlvbkFuZFNpemUgPSBPYmplY3QuYXNzaWduKHt9LCBwb3NpdGlvbiwgc2l6ZSk7XG4gICAgICAgICAgICBjb25zdCBhbGlnbm1lbnQgPSBkZXRlcm1pbmVBbGlnbm1lbnQodGhpcy5jaGFydCwgb3B0aW9ucywgcG9zaXRpb25BbmRTaXplKTtcbiAgICAgICAgICAgIGNvbnN0IGJhY2tncm91bmRQb2ludCA9IGdldEJhY2tncm91bmRQb2ludChvcHRpb25zLCBwb3NpdGlvbkFuZFNpemUsIGFsaWdubWVudCwgdGhpcy5jaGFydCk7XG4gICAgICAgICAgICB0aGlzLnhBbGlnbiA9IGFsaWdubWVudC54QWxpZ247XG4gICAgICAgICAgICB0aGlzLnlBbGlnbiA9IGFsaWdubWVudC55QWxpZ247XG4gICAgICAgICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgICAgIG9wYWNpdHk6IDEsXG4gICAgICAgICAgICAgICAgeDogYmFja2dyb3VuZFBvaW50LngsXG4gICAgICAgICAgICAgICAgeTogYmFja2dyb3VuZFBvaW50LnksXG4gICAgICAgICAgICAgICAgd2lkdGg6IHNpemUud2lkdGgsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiBzaXplLmhlaWdodCxcbiAgICAgICAgICAgICAgICBjYXJldFg6IHBvc2l0aW9uLngsXG4gICAgICAgICAgICAgICAgY2FyZXRZOiBwb3NpdGlvbi55XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3Rvb2x0aXBJdGVtcyA9IHRvb2x0aXBJdGVtcztcbiAgICAgICAgdGhpcy4kY29udGV4dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIHRoaXMuX3Jlc29sdmVBbmltYXRpb25zKCkudXBkYXRlKHRoaXMsIHByb3BlcnRpZXMpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjaGFuZ2VkICYmIG9wdGlvbnMuZXh0ZXJuYWwpIHtcbiAgICAgICAgICAgIG9wdGlvbnMuZXh0ZXJuYWwuY2FsbCh0aGlzLCB7XG4gICAgICAgICAgICAgICAgY2hhcnQ6IHRoaXMuY2hhcnQsXG4gICAgICAgICAgICAgICAgdG9vbHRpcDogdGhpcyxcbiAgICAgICAgICAgICAgICByZXBsYXlcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIGRyYXdDYXJldCh0b29sdGlwUG9pbnQsIGN0eCwgc2l6ZSwgb3B0aW9ucykge1xuICAgICAgICBjb25zdCBjYXJldFBvc2l0aW9uID0gdGhpcy5nZXRDYXJldFBvc2l0aW9uKHRvb2x0aXBQb2ludCwgc2l6ZSwgb3B0aW9ucyk7XG4gICAgICAgIGN0eC5saW5lVG8oY2FyZXRQb3NpdGlvbi54MSwgY2FyZXRQb3NpdGlvbi55MSk7XG4gICAgICAgIGN0eC5saW5lVG8oY2FyZXRQb3NpdGlvbi54MiwgY2FyZXRQb3NpdGlvbi55Mik7XG4gICAgICAgIGN0eC5saW5lVG8oY2FyZXRQb3NpdGlvbi54MywgY2FyZXRQb3NpdGlvbi55Myk7XG4gICAgfVxuICAgIGdldENhcmV0UG9zaXRpb24odG9vbHRpcFBvaW50LCBzaXplLCBvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IHsgeEFsaWduICwgeUFsaWduICB9ID0gdGhpcztcbiAgICAgICAgY29uc3QgeyBjYXJldFNpemUgLCBjb3JuZXJSYWRpdXMgIH0gPSBvcHRpb25zO1xuICAgICAgICBjb25zdCB7IHRvcExlZnQgLCB0b3BSaWdodCAsIGJvdHRvbUxlZnQgLCBib3R0b21SaWdodCAgfSA9IHRvVFJCTENvcm5lcnMoY29ybmVyUmFkaXVzKTtcbiAgICAgICAgY29uc3QgeyB4OiBwdFggLCB5OiBwdFkgIH0gPSB0b29sdGlwUG9pbnQ7XG4gICAgICAgIGNvbnN0IHsgd2lkdGggLCBoZWlnaHQgIH0gPSBzaXplO1xuICAgICAgICBsZXQgeDEsIHgyLCB4MywgeTEsIHkyLCB5MztcbiAgICAgICAgaWYgKHlBbGlnbiA9PT0gJ2NlbnRlcicpIHtcbiAgICAgICAgICAgIHkyID0gcHRZICsgaGVpZ2h0IC8gMjtcbiAgICAgICAgICAgIGlmICh4QWxpZ24gPT09ICdsZWZ0Jykge1xuICAgICAgICAgICAgICAgIHgxID0gcHRYO1xuICAgICAgICAgICAgICAgIHgyID0geDEgLSBjYXJldFNpemU7XG4gICAgICAgICAgICAgICAgeTEgPSB5MiArIGNhcmV0U2l6ZTtcbiAgICAgICAgICAgICAgICB5MyA9IHkyIC0gY2FyZXRTaXplO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB4MSA9IHB0WCArIHdpZHRoO1xuICAgICAgICAgICAgICAgIHgyID0geDEgKyBjYXJldFNpemU7XG4gICAgICAgICAgICAgICAgeTEgPSB5MiAtIGNhcmV0U2l6ZTtcbiAgICAgICAgICAgICAgICB5MyA9IHkyICsgY2FyZXRTaXplO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgeDMgPSB4MTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICh4QWxpZ24gPT09ICdsZWZ0Jykge1xuICAgICAgICAgICAgICAgIHgyID0gcHRYICsgTWF0aC5tYXgodG9wTGVmdCwgYm90dG9tTGVmdCkgKyBjYXJldFNpemU7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHhBbGlnbiA9PT0gJ3JpZ2h0Jykge1xuICAgICAgICAgICAgICAgIHgyID0gcHRYICsgd2lkdGggLSBNYXRoLm1heCh0b3BSaWdodCwgYm90dG9tUmlnaHQpIC0gY2FyZXRTaXplO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB4MiA9IHRoaXMuY2FyZXRYO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHlBbGlnbiA9PT0gJ3RvcCcpIHtcbiAgICAgICAgICAgICAgICB5MSA9IHB0WTtcbiAgICAgICAgICAgICAgICB5MiA9IHkxIC0gY2FyZXRTaXplO1xuICAgICAgICAgICAgICAgIHgxID0geDIgLSBjYXJldFNpemU7XG4gICAgICAgICAgICAgICAgeDMgPSB4MiArIGNhcmV0U2l6ZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgeTEgPSBwdFkgKyBoZWlnaHQ7XG4gICAgICAgICAgICAgICAgeTIgPSB5MSArIGNhcmV0U2l6ZTtcbiAgICAgICAgICAgICAgICB4MSA9IHgyICsgY2FyZXRTaXplO1xuICAgICAgICAgICAgICAgIHgzID0geDIgLSBjYXJldFNpemU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB5MyA9IHkxO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4MSxcbiAgICAgICAgICAgIHgyLFxuICAgICAgICAgICAgeDMsXG4gICAgICAgICAgICB5MSxcbiAgICAgICAgICAgIHkyLFxuICAgICAgICAgICAgeTNcbiAgICAgICAgfTtcbiAgICB9XG4gICAgZHJhd1RpdGxlKHB0LCBjdHgsIG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgdGl0bGUgPSB0aGlzLnRpdGxlO1xuICAgICAgICBjb25zdCBsZW5ndGggPSB0aXRsZS5sZW5ndGg7XG4gICAgICAgIGxldCB0aXRsZUZvbnQsIHRpdGxlU3BhY2luZywgaTtcbiAgICAgICAgaWYgKGxlbmd0aCkge1xuICAgICAgICAgICAgY29uc3QgcnRsSGVscGVyID0gZ2V0UnRsQWRhcHRlcihvcHRpb25zLnJ0bCwgdGhpcy54LCB0aGlzLndpZHRoKTtcbiAgICAgICAgICAgIHB0LnggPSBnZXRBbGlnbmVkWCh0aGlzLCBvcHRpb25zLnRpdGxlQWxpZ24sIG9wdGlvbnMpO1xuICAgICAgICAgICAgY3R4LnRleHRBbGlnbiA9IHJ0bEhlbHBlci50ZXh0QWxpZ24ob3B0aW9ucy50aXRsZUFsaWduKTtcbiAgICAgICAgICAgIGN0eC50ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJztcbiAgICAgICAgICAgIHRpdGxlRm9udCA9IHRvRm9udChvcHRpb25zLnRpdGxlRm9udCk7XG4gICAgICAgICAgICB0aXRsZVNwYWNpbmcgPSBvcHRpb25zLnRpdGxlU3BhY2luZztcbiAgICAgICAgICAgIGN0eC5maWxsU3R5bGUgPSBvcHRpb25zLnRpdGxlQ29sb3I7XG4gICAgICAgICAgICBjdHguZm9udCA9IHRpdGxlRm9udC5zdHJpbmc7XG4gICAgICAgICAgICBmb3IoaSA9IDA7IGkgPCBsZW5ndGg7ICsraSl7XG4gICAgICAgICAgICAgICAgY3R4LmZpbGxUZXh0KHRpdGxlW2ldLCBydGxIZWxwZXIueChwdC54KSwgcHQueSArIHRpdGxlRm9udC5saW5lSGVpZ2h0IC8gMik7XG4gICAgICAgICAgICAgICAgcHQueSArPSB0aXRsZUZvbnQubGluZUhlaWdodCArIHRpdGxlU3BhY2luZztcbiAgICAgICAgICAgICAgICBpZiAoaSArIDEgPT09IGxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICBwdC55ICs9IG9wdGlvbnMudGl0bGVNYXJnaW5Cb3R0b20gLSB0aXRsZVNwYWNpbmc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuIF9kcmF3Q29sb3JCb3goY3R4LCBwdCwgaSwgcnRsSGVscGVyLCBvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IGxhYmVsQ29sb3IgPSB0aGlzLmxhYmVsQ29sb3JzW2ldO1xuICAgICAgICBjb25zdCBsYWJlbFBvaW50U3R5bGUgPSB0aGlzLmxhYmVsUG9pbnRTdHlsZXNbaV07XG4gICAgICAgIGNvbnN0IHsgYm94SGVpZ2h0ICwgYm94V2lkdGggIH0gPSBvcHRpb25zO1xuICAgICAgICBjb25zdCBib2R5Rm9udCA9IHRvRm9udChvcHRpb25zLmJvZHlGb250KTtcbiAgICAgICAgY29uc3QgY29sb3JYID0gZ2V0QWxpZ25lZFgodGhpcywgJ2xlZnQnLCBvcHRpb25zKTtcbiAgICAgICAgY29uc3QgcnRsQ29sb3JYID0gcnRsSGVscGVyLngoY29sb3JYKTtcbiAgICAgICAgY29uc3QgeU9mZlNldCA9IGJveEhlaWdodCA8IGJvZHlGb250LmxpbmVIZWlnaHQgPyAoYm9keUZvbnQubGluZUhlaWdodCAtIGJveEhlaWdodCkgLyAyIDogMDtcbiAgICAgICAgY29uc3QgY29sb3JZID0gcHQueSArIHlPZmZTZXQ7XG4gICAgICAgIGlmIChvcHRpb25zLnVzZVBvaW50U3R5bGUpIHtcbiAgICAgICAgICAgIGNvbnN0IGRyYXdPcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIHJhZGl1czogTWF0aC5taW4oYm94V2lkdGgsIGJveEhlaWdodCkgLyAyLFxuICAgICAgICAgICAgICAgIHBvaW50U3R5bGU6IGxhYmVsUG9pbnRTdHlsZS5wb2ludFN0eWxlLFxuICAgICAgICAgICAgICAgIHJvdGF0aW9uOiBsYWJlbFBvaW50U3R5bGUucm90YXRpb24sXG4gICAgICAgICAgICAgICAgYm9yZGVyV2lkdGg6IDFcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBjZW50ZXJYID0gcnRsSGVscGVyLmxlZnRGb3JMdHIocnRsQ29sb3JYLCBib3hXaWR0aCkgKyBib3hXaWR0aCAvIDI7XG4gICAgICAgICAgICBjb25zdCBjZW50ZXJZID0gY29sb3JZICsgYm94SGVpZ2h0IC8gMjtcbiAgICAgICAgICAgIGN0eC5zdHJva2VTdHlsZSA9IG9wdGlvbnMubXVsdGlLZXlCYWNrZ3JvdW5kO1xuICAgICAgICAgICAgY3R4LmZpbGxTdHlsZSA9IG9wdGlvbnMubXVsdGlLZXlCYWNrZ3JvdW5kO1xuICAgICAgICAgICAgZHJhd1BvaW50KGN0eCwgZHJhd09wdGlvbnMsIGNlbnRlclgsIGNlbnRlclkpO1xuICAgICAgICAgICAgY3R4LnN0cm9rZVN0eWxlID0gbGFiZWxDb2xvci5ib3JkZXJDb2xvcjtcbiAgICAgICAgICAgIGN0eC5maWxsU3R5bGUgPSBsYWJlbENvbG9yLmJhY2tncm91bmRDb2xvcjtcbiAgICAgICAgICAgIGRyYXdQb2ludChjdHgsIGRyYXdPcHRpb25zLCBjZW50ZXJYLCBjZW50ZXJZKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGN0eC5saW5lV2lkdGggPSBpc09iamVjdChsYWJlbENvbG9yLmJvcmRlcldpZHRoKSA/IE1hdGgubWF4KC4uLk9iamVjdC52YWx1ZXMobGFiZWxDb2xvci5ib3JkZXJXaWR0aCkpIDogbGFiZWxDb2xvci5ib3JkZXJXaWR0aCB8fCAxO1xuICAgICAgICAgICAgY3R4LnN0cm9rZVN0eWxlID0gbGFiZWxDb2xvci5ib3JkZXJDb2xvcjtcbiAgICAgICAgICAgIGN0eC5zZXRMaW5lRGFzaChsYWJlbENvbG9yLmJvcmRlckRhc2ggfHwgW10pO1xuICAgICAgICAgICAgY3R4LmxpbmVEYXNoT2Zmc2V0ID0gbGFiZWxDb2xvci5ib3JkZXJEYXNoT2Zmc2V0IHx8IDA7XG4gICAgICAgICAgICBjb25zdCBvdXRlclggPSBydGxIZWxwZXIubGVmdEZvckx0cihydGxDb2xvclgsIGJveFdpZHRoKTtcbiAgICAgICAgICAgIGNvbnN0IGlubmVyWCA9IHJ0bEhlbHBlci5sZWZ0Rm9yTHRyKHJ0bEhlbHBlci54UGx1cyhydGxDb2xvclgsIDEpLCBib3hXaWR0aCAtIDIpO1xuICAgICAgICAgICAgY29uc3QgYm9yZGVyUmFkaXVzID0gdG9UUkJMQ29ybmVycyhsYWJlbENvbG9yLmJvcmRlclJhZGl1cyk7XG4gICAgICAgICAgICBpZiAoT2JqZWN0LnZhbHVlcyhib3JkZXJSYWRpdXMpLnNvbWUoKHYpPT52ICE9PSAwKSkge1xuICAgICAgICAgICAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgICAgICAgICAgICBjdHguZmlsbFN0eWxlID0gb3B0aW9ucy5tdWx0aUtleUJhY2tncm91bmQ7XG4gICAgICAgICAgICAgICAgYWRkUm91bmRlZFJlY3RQYXRoKGN0eCwge1xuICAgICAgICAgICAgICAgICAgICB4OiBvdXRlclgsXG4gICAgICAgICAgICAgICAgICAgIHk6IGNvbG9yWSxcbiAgICAgICAgICAgICAgICAgICAgdzogYm94V2lkdGgsXG4gICAgICAgICAgICAgICAgICAgIGg6IGJveEhlaWdodCxcbiAgICAgICAgICAgICAgICAgICAgcmFkaXVzOiBib3JkZXJSYWRpdXNcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjdHguZmlsbCgpO1xuICAgICAgICAgICAgICAgIGN0eC5zdHJva2UoKTtcbiAgICAgICAgICAgICAgICBjdHguZmlsbFN0eWxlID0gbGFiZWxDb2xvci5iYWNrZ3JvdW5kQ29sb3I7XG4gICAgICAgICAgICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgICAgICAgICAgIGFkZFJvdW5kZWRSZWN0UGF0aChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgeDogaW5uZXJYLFxuICAgICAgICAgICAgICAgICAgICB5OiBjb2xvclkgKyAxLFxuICAgICAgICAgICAgICAgICAgICB3OiBib3hXaWR0aCAtIDIsXG4gICAgICAgICAgICAgICAgICAgIGg6IGJveEhlaWdodCAtIDIsXG4gICAgICAgICAgICAgICAgICAgIHJhZGl1czogYm9yZGVyUmFkaXVzXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgY3R4LmZpbGwoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY3R4LmZpbGxTdHlsZSA9IG9wdGlvbnMubXVsdGlLZXlCYWNrZ3JvdW5kO1xuICAgICAgICAgICAgICAgIGN0eC5maWxsUmVjdChvdXRlclgsIGNvbG9yWSwgYm94V2lkdGgsIGJveEhlaWdodCk7XG4gICAgICAgICAgICAgICAgY3R4LnN0cm9rZVJlY3Qob3V0ZXJYLCBjb2xvclksIGJveFdpZHRoLCBib3hIZWlnaHQpO1xuICAgICAgICAgICAgICAgIGN0eC5maWxsU3R5bGUgPSBsYWJlbENvbG9yLmJhY2tncm91bmRDb2xvcjtcbiAgICAgICAgICAgICAgICBjdHguZmlsbFJlY3QoaW5uZXJYLCBjb2xvclkgKyAxLCBib3hXaWR0aCAtIDIsIGJveEhlaWdodCAtIDIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGN0eC5maWxsU3R5bGUgPSB0aGlzLmxhYmVsVGV4dENvbG9yc1tpXTtcbiAgICB9XG4gICAgZHJhd0JvZHkocHQsIGN0eCwgb3B0aW9ucykge1xuICAgICAgICBjb25zdCB7IGJvZHkgIH0gPSB0aGlzO1xuICAgICAgICBjb25zdCB7IGJvZHlTcGFjaW5nICwgYm9keUFsaWduICwgZGlzcGxheUNvbG9ycyAsIGJveEhlaWdodCAsIGJveFdpZHRoICwgYm94UGFkZGluZyAgfSA9IG9wdGlvbnM7XG4gICAgICAgIGNvbnN0IGJvZHlGb250ID0gdG9Gb250KG9wdGlvbnMuYm9keUZvbnQpO1xuICAgICAgICBsZXQgYm9keUxpbmVIZWlnaHQgPSBib2R5Rm9udC5saW5lSGVpZ2h0O1xuICAgICAgICBsZXQgeExpbmVQYWRkaW5nID0gMDtcbiAgICAgICAgY29uc3QgcnRsSGVscGVyID0gZ2V0UnRsQWRhcHRlcihvcHRpb25zLnJ0bCwgdGhpcy54LCB0aGlzLndpZHRoKTtcbiAgICAgICAgY29uc3QgZmlsbExpbmVPZlRleHQgPSBmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgICAgICBjdHguZmlsbFRleHQobGluZSwgcnRsSGVscGVyLngocHQueCArIHhMaW5lUGFkZGluZyksIHB0LnkgKyBib2R5TGluZUhlaWdodCAvIDIpO1xuICAgICAgICAgICAgcHQueSArPSBib2R5TGluZUhlaWdodCArIGJvZHlTcGFjaW5nO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCBib2R5QWxpZ25Gb3JDYWxjdWxhdGlvbiA9IHJ0bEhlbHBlci50ZXh0QWxpZ24oYm9keUFsaWduKTtcbiAgICAgICAgbGV0IGJvZHlJdGVtLCB0ZXh0Q29sb3IsIGxpbmVzLCBpLCBqLCBpbGVuLCBqbGVuO1xuICAgICAgICBjdHgudGV4dEFsaWduID0gYm9keUFsaWduO1xuICAgICAgICBjdHgudGV4dEJhc2VsaW5lID0gJ21pZGRsZSc7XG4gICAgICAgIGN0eC5mb250ID0gYm9keUZvbnQuc3RyaW5nO1xuICAgICAgICBwdC54ID0gZ2V0QWxpZ25lZFgodGhpcywgYm9keUFsaWduRm9yQ2FsY3VsYXRpb24sIG9wdGlvbnMpO1xuICAgICAgICBjdHguZmlsbFN0eWxlID0gb3B0aW9ucy5ib2R5Q29sb3I7XG4gICAgICAgIGVhY2godGhpcy5iZWZvcmVCb2R5LCBmaWxsTGluZU9mVGV4dCk7XG4gICAgICAgIHhMaW5lUGFkZGluZyA9IGRpc3BsYXlDb2xvcnMgJiYgYm9keUFsaWduRm9yQ2FsY3VsYXRpb24gIT09ICdyaWdodCcgPyBib2R5QWxpZ24gPT09ICdjZW50ZXInID8gYm94V2lkdGggLyAyICsgYm94UGFkZGluZyA6IGJveFdpZHRoICsgMiArIGJveFBhZGRpbmcgOiAwO1xuICAgICAgICBmb3IoaSA9IDAsIGlsZW4gPSBib2R5Lmxlbmd0aDsgaSA8IGlsZW47ICsraSl7XG4gICAgICAgICAgICBib2R5SXRlbSA9IGJvZHlbaV07XG4gICAgICAgICAgICB0ZXh0Q29sb3IgPSB0aGlzLmxhYmVsVGV4dENvbG9yc1tpXTtcbiAgICAgICAgICAgIGN0eC5maWxsU3R5bGUgPSB0ZXh0Q29sb3I7XG4gICAgICAgICAgICBlYWNoKGJvZHlJdGVtLmJlZm9yZSwgZmlsbExpbmVPZlRleHQpO1xuICAgICAgICAgICAgbGluZXMgPSBib2R5SXRlbS5saW5lcztcbiAgICAgICAgICAgIGlmIChkaXNwbGF5Q29sb3JzICYmIGxpbmVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2RyYXdDb2xvckJveChjdHgsIHB0LCBpLCBydGxIZWxwZXIsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIGJvZHlMaW5lSGVpZ2h0ID0gTWF0aC5tYXgoYm9keUZvbnQubGluZUhlaWdodCwgYm94SGVpZ2h0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvcihqID0gMCwgamxlbiA9IGxpbmVzLmxlbmd0aDsgaiA8IGpsZW47ICsrail7XG4gICAgICAgICAgICAgICAgZmlsbExpbmVPZlRleHQobGluZXNbal0pO1xuICAgICAgICAgICAgICAgIGJvZHlMaW5lSGVpZ2h0ID0gYm9keUZvbnQubGluZUhlaWdodDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVhY2goYm9keUl0ZW0uYWZ0ZXIsIGZpbGxMaW5lT2ZUZXh0KTtcbiAgICAgICAgfVxuICAgICAgICB4TGluZVBhZGRpbmcgPSAwO1xuICAgICAgICBib2R5TGluZUhlaWdodCA9IGJvZHlGb250LmxpbmVIZWlnaHQ7XG4gICAgICAgIGVhY2godGhpcy5hZnRlckJvZHksIGZpbGxMaW5lT2ZUZXh0KTtcbiAgICAgICAgcHQueSAtPSBib2R5U3BhY2luZztcbiAgICB9XG4gICAgZHJhd0Zvb3RlcihwdCwgY3R4LCBvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IGZvb3RlciA9IHRoaXMuZm9vdGVyO1xuICAgICAgICBjb25zdCBsZW5ndGggPSBmb290ZXIubGVuZ3RoO1xuICAgICAgICBsZXQgZm9vdGVyRm9udCwgaTtcbiAgICAgICAgaWYgKGxlbmd0aCkge1xuICAgICAgICAgICAgY29uc3QgcnRsSGVscGVyID0gZ2V0UnRsQWRhcHRlcihvcHRpb25zLnJ0bCwgdGhpcy54LCB0aGlzLndpZHRoKTtcbiAgICAgICAgICAgIHB0LnggPSBnZXRBbGlnbmVkWCh0aGlzLCBvcHRpb25zLmZvb3RlckFsaWduLCBvcHRpb25zKTtcbiAgICAgICAgICAgIHB0LnkgKz0gb3B0aW9ucy5mb290ZXJNYXJnaW5Ub3A7XG4gICAgICAgICAgICBjdHgudGV4dEFsaWduID0gcnRsSGVscGVyLnRleHRBbGlnbihvcHRpb25zLmZvb3RlckFsaWduKTtcbiAgICAgICAgICAgIGN0eC50ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJztcbiAgICAgICAgICAgIGZvb3RlckZvbnQgPSB0b0ZvbnQob3B0aW9ucy5mb290ZXJGb250KTtcbiAgICAgICAgICAgIGN0eC5maWxsU3R5bGUgPSBvcHRpb25zLmZvb3RlckNvbG9yO1xuICAgICAgICAgICAgY3R4LmZvbnQgPSBmb290ZXJGb250LnN0cmluZztcbiAgICAgICAgICAgIGZvcihpID0gMDsgaSA8IGxlbmd0aDsgKytpKXtcbiAgICAgICAgICAgICAgICBjdHguZmlsbFRleHQoZm9vdGVyW2ldLCBydGxIZWxwZXIueChwdC54KSwgcHQueSArIGZvb3RlckZvbnQubGluZUhlaWdodCAvIDIpO1xuICAgICAgICAgICAgICAgIHB0LnkgKz0gZm9vdGVyRm9udC5saW5lSGVpZ2h0ICsgb3B0aW9ucy5mb290ZXJTcGFjaW5nO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGRyYXdCYWNrZ3JvdW5kKHB0LCBjdHgsIHRvb2x0aXBTaXplLCBvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IHsgeEFsaWduICwgeUFsaWduICB9ID0gdGhpcztcbiAgICAgICAgY29uc3QgeyB4ICwgeSAgfSA9IHB0O1xuICAgICAgICBjb25zdCB7IHdpZHRoICwgaGVpZ2h0ICB9ID0gdG9vbHRpcFNpemU7XG4gICAgICAgIGNvbnN0IHsgdG9wTGVmdCAsIHRvcFJpZ2h0ICwgYm90dG9tTGVmdCAsIGJvdHRvbVJpZ2h0ICB9ID0gdG9UUkJMQ29ybmVycyhvcHRpb25zLmNvcm5lclJhZGl1cyk7XG4gICAgICAgIGN0eC5maWxsU3R5bGUgPSBvcHRpb25zLmJhY2tncm91bmRDb2xvcjtcbiAgICAgICAgY3R4LnN0cm9rZVN0eWxlID0gb3B0aW9ucy5ib3JkZXJDb2xvcjtcbiAgICAgICAgY3R4LmxpbmVXaWR0aCA9IG9wdGlvbnMuYm9yZGVyV2lkdGg7XG4gICAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgICAgY3R4Lm1vdmVUbyh4ICsgdG9wTGVmdCwgeSk7XG4gICAgICAgIGlmICh5QWxpZ24gPT09ICd0b3AnKSB7XG4gICAgICAgICAgICB0aGlzLmRyYXdDYXJldChwdCwgY3R4LCB0b29sdGlwU2l6ZSwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgY3R4LmxpbmVUbyh4ICsgd2lkdGggLSB0b3BSaWdodCwgeSk7XG4gICAgICAgIGN0eC5xdWFkcmF0aWNDdXJ2ZVRvKHggKyB3aWR0aCwgeSwgeCArIHdpZHRoLCB5ICsgdG9wUmlnaHQpO1xuICAgICAgICBpZiAoeUFsaWduID09PSAnY2VudGVyJyAmJiB4QWxpZ24gPT09ICdyaWdodCcpIHtcbiAgICAgICAgICAgIHRoaXMuZHJhd0NhcmV0KHB0LCBjdHgsIHRvb2x0aXBTaXplLCBvcHRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICBjdHgubGluZVRvKHggKyB3aWR0aCwgeSArIGhlaWdodCAtIGJvdHRvbVJpZ2h0KTtcbiAgICAgICAgY3R4LnF1YWRyYXRpY0N1cnZlVG8oeCArIHdpZHRoLCB5ICsgaGVpZ2h0LCB4ICsgd2lkdGggLSBib3R0b21SaWdodCwgeSArIGhlaWdodCk7XG4gICAgICAgIGlmICh5QWxpZ24gPT09ICdib3R0b20nKSB7XG4gICAgICAgICAgICB0aGlzLmRyYXdDYXJldChwdCwgY3R4LCB0b29sdGlwU2l6ZSwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgY3R4LmxpbmVUbyh4ICsgYm90dG9tTGVmdCwgeSArIGhlaWdodCk7XG4gICAgICAgIGN0eC5xdWFkcmF0aWNDdXJ2ZVRvKHgsIHkgKyBoZWlnaHQsIHgsIHkgKyBoZWlnaHQgLSBib3R0b21MZWZ0KTtcbiAgICAgICAgaWYgKHlBbGlnbiA9PT0gJ2NlbnRlcicgJiYgeEFsaWduID09PSAnbGVmdCcpIHtcbiAgICAgICAgICAgIHRoaXMuZHJhd0NhcmV0KHB0LCBjdHgsIHRvb2x0aXBTaXplLCBvcHRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICBjdHgubGluZVRvKHgsIHkgKyB0b3BMZWZ0KTtcbiAgICAgICAgY3R4LnF1YWRyYXRpY0N1cnZlVG8oeCwgeSwgeCArIHRvcExlZnQsIHkpO1xuICAgICAgICBjdHguY2xvc2VQYXRoKCk7XG4gICAgICAgIGN0eC5maWxsKCk7XG4gICAgICAgIGlmIChvcHRpb25zLmJvcmRlcldpZHRoID4gMCkge1xuICAgICAgICAgICAgY3R4LnN0cm9rZSgpO1xuICAgICAgICB9XG4gICAgfVxuIF91cGRhdGVBbmltYXRpb25UYXJnZXQob3B0aW9ucykge1xuICAgICAgICBjb25zdCBjaGFydCA9IHRoaXMuY2hhcnQ7XG4gICAgICAgIGNvbnN0IGFuaW1zID0gdGhpcy4kYW5pbWF0aW9ucztcbiAgICAgICAgY29uc3QgYW5pbVggPSBhbmltcyAmJiBhbmltcy54O1xuICAgICAgICBjb25zdCBhbmltWSA9IGFuaW1zICYmIGFuaW1zLnk7XG4gICAgICAgIGlmIChhbmltWCB8fCBhbmltWSkge1xuICAgICAgICAgICAgY29uc3QgcG9zaXRpb24gPSBwb3NpdGlvbmVyc1tvcHRpb25zLnBvc2l0aW9uXS5jYWxsKHRoaXMsIHRoaXMuX2FjdGl2ZSwgdGhpcy5fZXZlbnRQb3NpdGlvbik7XG4gICAgICAgICAgICBpZiAoIXBvc2l0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qgc2l6ZSA9IHRoaXMuX3NpemUgPSBnZXRUb29sdGlwU2l6ZSh0aGlzLCBvcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uQW5kU2l6ZSA9IE9iamVjdC5hc3NpZ24oe30sIHBvc2l0aW9uLCB0aGlzLl9zaXplKTtcbiAgICAgICAgICAgIGNvbnN0IGFsaWdubWVudCA9IGRldGVybWluZUFsaWdubWVudChjaGFydCwgb3B0aW9ucywgcG9zaXRpb25BbmRTaXplKTtcbiAgICAgICAgICAgIGNvbnN0IHBvaW50ID0gZ2V0QmFja2dyb3VuZFBvaW50KG9wdGlvbnMsIHBvc2l0aW9uQW5kU2l6ZSwgYWxpZ25tZW50LCBjaGFydCk7XG4gICAgICAgICAgICBpZiAoYW5pbVguX3RvICE9PSBwb2ludC54IHx8IGFuaW1ZLl90byAhPT0gcG9pbnQueSkge1xuICAgICAgICAgICAgICAgIHRoaXMueEFsaWduID0gYWxpZ25tZW50LnhBbGlnbjtcbiAgICAgICAgICAgICAgICB0aGlzLnlBbGlnbiA9IGFsaWdubWVudC55QWxpZ247XG4gICAgICAgICAgICAgICAgdGhpcy53aWR0aCA9IHNpemUud2lkdGg7XG4gICAgICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSBzaXplLmhlaWdodDtcbiAgICAgICAgICAgICAgICB0aGlzLmNhcmV0WCA9IHBvc2l0aW9uLng7XG4gICAgICAgICAgICAgICAgdGhpcy5jYXJldFkgPSBwb3NpdGlvbi55O1xuICAgICAgICAgICAgICAgIHRoaXMuX3Jlc29sdmVBbmltYXRpb25zKCkudXBkYXRlKHRoaXMsIHBvaW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiBfd2lsbFJlbmRlcigpIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5vcGFjaXR5O1xuICAgIH1cbiAgICBkcmF3KGN0eCkge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zLnNldENvbnRleHQodGhpcy5nZXRDb250ZXh0KCkpO1xuICAgICAgICBsZXQgb3BhY2l0eSA9IHRoaXMub3BhY2l0eTtcbiAgICAgICAgaWYgKCFvcGFjaXR5KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fdXBkYXRlQW5pbWF0aW9uVGFyZ2V0KG9wdGlvbnMpO1xuICAgICAgICBjb25zdCB0b29sdGlwU2l6ZSA9IHtcbiAgICAgICAgICAgIHdpZHRoOiB0aGlzLndpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLmhlaWdodFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBwdCA9IHtcbiAgICAgICAgICAgIHg6IHRoaXMueCxcbiAgICAgICAgICAgIHk6IHRoaXMueVxuICAgICAgICB9O1xuICAgICAgICBvcGFjaXR5ID0gTWF0aC5hYnMob3BhY2l0eSkgPCAxZS0zID8gMCA6IG9wYWNpdHk7XG4gICAgICAgIGNvbnN0IHBhZGRpbmcgPSB0b1BhZGRpbmcob3B0aW9ucy5wYWRkaW5nKTtcbiAgICAgICAgY29uc3QgaGFzVG9vbHRpcENvbnRlbnQgPSB0aGlzLnRpdGxlLmxlbmd0aCB8fCB0aGlzLmJlZm9yZUJvZHkubGVuZ3RoIHx8IHRoaXMuYm9keS5sZW5ndGggfHwgdGhpcy5hZnRlckJvZHkubGVuZ3RoIHx8IHRoaXMuZm9vdGVyLmxlbmd0aDtcbiAgICAgICAgaWYgKG9wdGlvbnMuZW5hYmxlZCAmJiBoYXNUb29sdGlwQ29udGVudCkge1xuICAgICAgICAgICAgY3R4LnNhdmUoKTtcbiAgICAgICAgICAgIGN0eC5nbG9iYWxBbHBoYSA9IG9wYWNpdHk7XG4gICAgICAgICAgICB0aGlzLmRyYXdCYWNrZ3JvdW5kKHB0LCBjdHgsIHRvb2x0aXBTaXplLCBvcHRpb25zKTtcbiAgICAgICAgICAgIG92ZXJyaWRlVGV4dERpcmVjdGlvbihjdHgsIG9wdGlvbnMudGV4dERpcmVjdGlvbik7XG4gICAgICAgICAgICBwdC55ICs9IHBhZGRpbmcudG9wO1xuICAgICAgICAgICAgdGhpcy5kcmF3VGl0bGUocHQsIGN0eCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB0aGlzLmRyYXdCb2R5KHB0LCBjdHgsIG9wdGlvbnMpO1xuICAgICAgICAgICAgdGhpcy5kcmF3Rm9vdGVyKHB0LCBjdHgsIG9wdGlvbnMpO1xuICAgICAgICAgICAgcmVzdG9yZVRleHREaXJlY3Rpb24oY3R4LCBvcHRpb25zLnRleHREaXJlY3Rpb24pO1xuICAgICAgICAgICAgY3R4LnJlc3RvcmUoKTtcbiAgICAgICAgfVxuICAgIH1cbiBnZXRBY3RpdmVFbGVtZW50cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FjdGl2ZSB8fCBbXTtcbiAgICB9XG4gc2V0QWN0aXZlRWxlbWVudHMoYWN0aXZlRWxlbWVudHMsIGV2ZW50UG9zaXRpb24pIHtcbiAgICAgICAgY29uc3QgbGFzdEFjdGl2ZSA9IHRoaXMuX2FjdGl2ZTtcbiAgICAgICAgY29uc3QgYWN0aXZlID0gYWN0aXZlRWxlbWVudHMubWFwKCh7IGRhdGFzZXRJbmRleCAsIGluZGV4ICB9KT0+e1xuICAgICAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMuY2hhcnQuZ2V0RGF0YXNldE1ldGEoZGF0YXNldEluZGV4KTtcbiAgICAgICAgICAgIGlmICghbWV0YSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGZpbmQgYSBkYXRhc2V0IGF0IGluZGV4ICcgKyBkYXRhc2V0SW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBkYXRhc2V0SW5kZXgsXG4gICAgICAgICAgICAgICAgZWxlbWVudDogbWV0YS5kYXRhW2luZGV4XSxcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGNoYW5nZWQgPSAhX2VsZW1lbnRzRXF1YWwobGFzdEFjdGl2ZSwgYWN0aXZlKTtcbiAgICAgICAgY29uc3QgcG9zaXRpb25DaGFuZ2VkID0gdGhpcy5fcG9zaXRpb25DaGFuZ2VkKGFjdGl2ZSwgZXZlbnRQb3NpdGlvbik7XG4gICAgICAgIGlmIChjaGFuZ2VkIHx8IHBvc2l0aW9uQ2hhbmdlZCkge1xuICAgICAgICAgICAgdGhpcy5fYWN0aXZlID0gYWN0aXZlO1xuICAgICAgICAgICAgdGhpcy5fZXZlbnRQb3NpdGlvbiA9IGV2ZW50UG9zaXRpb247XG4gICAgICAgICAgICB0aGlzLl9pZ25vcmVSZXBsYXlFdmVudHMgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy51cGRhdGUodHJ1ZSk7XG4gICAgICAgIH1cbiAgICB9XG4gaGFuZGxlRXZlbnQoZSwgcmVwbGF5LCBpbkNoYXJ0QXJlYSA9IHRydWUpIHtcbiAgICAgICAgaWYgKHJlcGxheSAmJiB0aGlzLl9pZ25vcmVSZXBsYXlFdmVudHMpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9pZ25vcmVSZXBsYXlFdmVudHMgPSBmYWxzZTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgY29uc3QgbGFzdEFjdGl2ZSA9IHRoaXMuX2FjdGl2ZSB8fCBbXTtcbiAgICAgICAgY29uc3QgYWN0aXZlID0gdGhpcy5fZ2V0QWN0aXZlRWxlbWVudHMoZSwgbGFzdEFjdGl2ZSwgcmVwbGF5LCBpbkNoYXJ0QXJlYSk7XG4gICAgICAgIGNvbnN0IHBvc2l0aW9uQ2hhbmdlZCA9IHRoaXMuX3Bvc2l0aW9uQ2hhbmdlZChhY3RpdmUsIGUpO1xuICAgICAgICBjb25zdCBjaGFuZ2VkID0gcmVwbGF5IHx8ICFfZWxlbWVudHNFcXVhbChhY3RpdmUsIGxhc3RBY3RpdmUpIHx8IHBvc2l0aW9uQ2hhbmdlZDtcbiAgICAgICAgaWYgKGNoYW5nZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX2FjdGl2ZSA9IGFjdGl2ZTtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLmVuYWJsZWQgfHwgb3B0aW9ucy5leHRlcm5hbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50UG9zaXRpb24gPSB7XG4gICAgICAgICAgICAgICAgICAgIHg6IGUueCxcbiAgICAgICAgICAgICAgICAgICAgeTogZS55XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZSh0cnVlLCByZXBsYXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjaGFuZ2VkO1xuICAgIH1cbiBfZ2V0QWN0aXZlRWxlbWVudHMoZSwgbGFzdEFjdGl2ZSwgcmVwbGF5LCBpbkNoYXJ0QXJlYSkge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBpZiAoZS50eXBlID09PSAnbW91c2VvdXQnKSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpbkNoYXJ0QXJlYSkge1xuICAgICAgICAgICAgcmV0dXJuIGxhc3RBY3RpdmUuZmlsdGVyKChpKT0+dGhpcy5jaGFydC5kYXRhLmRhdGFzZXRzW2kuZGF0YXNldEluZGV4XSAmJiB0aGlzLmNoYXJ0LmdldERhdGFzZXRNZXRhKGkuZGF0YXNldEluZGV4KS5jb250cm9sbGVyLmdldFBhcnNlZChpLmluZGV4KSAhPT0gdW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhY3RpdmUgPSB0aGlzLmNoYXJ0LmdldEVsZW1lbnRzQXRFdmVudEZvck1vZGUoZSwgb3B0aW9ucy5tb2RlLCBvcHRpb25zLCByZXBsYXkpO1xuICAgICAgICBpZiAob3B0aW9ucy5yZXZlcnNlKSB7XG4gICAgICAgICAgICBhY3RpdmUucmV2ZXJzZSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhY3RpdmU7XG4gICAgfVxuIF9wb3NpdGlvbkNoYW5nZWQoYWN0aXZlLCBlKSB7XG4gICAgICAgIGNvbnN0IHsgY2FyZXRYICwgY2FyZXRZICwgb3B0aW9ucyAgfSA9IHRoaXM7XG4gICAgICAgIGNvbnN0IHBvc2l0aW9uID0gcG9zaXRpb25lcnNbb3B0aW9ucy5wb3NpdGlvbl0uY2FsbCh0aGlzLCBhY3RpdmUsIGUpO1xuICAgICAgICByZXR1cm4gcG9zaXRpb24gIT09IGZhbHNlICYmIChjYXJldFggIT09IHBvc2l0aW9uLnggfHwgY2FyZXRZICE9PSBwb3NpdGlvbi55KTtcbiAgICB9XG59XG52YXIgcGx1Z2luX3Rvb2x0aXAgPSB7XG4gICAgaWQ6ICd0b29sdGlwJyxcbiAgICBfZWxlbWVudDogVG9vbHRpcCxcbiAgICBwb3NpdGlvbmVycyxcbiAgICBhZnRlckluaXQgKGNoYXJ0LCBfYXJncywgb3B0aW9ucykge1xuICAgICAgICBpZiAob3B0aW9ucykge1xuICAgICAgICAgICAgY2hhcnQudG9vbHRpcCA9IG5ldyBUb29sdGlwKHtcbiAgICAgICAgICAgICAgICBjaGFydCxcbiAgICAgICAgICAgICAgICBvcHRpb25zXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgYmVmb3JlVXBkYXRlIChjaGFydCwgX2FyZ3MsIG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKGNoYXJ0LnRvb2x0aXApIHtcbiAgICAgICAgICAgIGNoYXJ0LnRvb2x0aXAuaW5pdGlhbGl6ZShvcHRpb25zKTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgcmVzZXQgKGNoYXJ0LCBfYXJncywgb3B0aW9ucykge1xuICAgICAgICBpZiAoY2hhcnQudG9vbHRpcCkge1xuICAgICAgICAgICAgY2hhcnQudG9vbHRpcC5pbml0aWFsaXplKG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBhZnRlckRyYXcgKGNoYXJ0KSB7XG4gICAgICAgIGNvbnN0IHRvb2x0aXAgPSBjaGFydC50b29sdGlwO1xuICAgICAgICBpZiAodG9vbHRpcCAmJiB0b29sdGlwLl93aWxsUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIGNvbnN0IGFyZ3MgPSB7XG4gICAgICAgICAgICAgICAgdG9vbHRpcFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChjaGFydC5ub3RpZnlQbHVnaW5zKCdiZWZvcmVUb29sdGlwRHJhdycsIHtcbiAgICAgICAgICAgICAgICAuLi5hcmdzLFxuICAgICAgICAgICAgICAgIGNhbmNlbGFibGU6IHRydWVcbiAgICAgICAgICAgIH0pID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRvb2x0aXAuZHJhdyhjaGFydC5jdHgpO1xuICAgICAgICAgICAgY2hhcnQubm90aWZ5UGx1Z2lucygnYWZ0ZXJUb29sdGlwRHJhdycsIGFyZ3MpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBhZnRlckV2ZW50IChjaGFydCwgYXJncykge1xuICAgICAgICBpZiAoY2hhcnQudG9vbHRpcCkge1xuICAgICAgICAgICAgY29uc3QgdXNlRmluYWxQb3NpdGlvbiA9IGFyZ3MucmVwbGF5O1xuICAgICAgICAgICAgaWYgKGNoYXJ0LnRvb2x0aXAuaGFuZGxlRXZlbnQoYXJncy5ldmVudCwgdXNlRmluYWxQb3NpdGlvbiwgYXJncy5pbkNoYXJ0QXJlYSkpIHtcbiAgICAgICAgICAgICAgICBhcmdzLmNoYW5nZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSxcbiAgICBkZWZhdWx0czoge1xuICAgICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgICBleHRlcm5hbDogbnVsbCxcbiAgICAgICAgcG9zaXRpb246ICdhdmVyYWdlJyxcbiAgICAgICAgYmFja2dyb3VuZENvbG9yOiAncmdiYSgwLDAsMCwwLjgpJyxcbiAgICAgICAgdGl0bGVDb2xvcjogJyNmZmYnLFxuICAgICAgICB0aXRsZUZvbnQ6IHtcbiAgICAgICAgICAgIHdlaWdodDogJ2JvbGQnXG4gICAgICAgIH0sXG4gICAgICAgIHRpdGxlU3BhY2luZzogMixcbiAgICAgICAgdGl0bGVNYXJnaW5Cb3R0b206IDYsXG4gICAgICAgIHRpdGxlQWxpZ246ICdsZWZ0JyxcbiAgICAgICAgYm9keUNvbG9yOiAnI2ZmZicsXG4gICAgICAgIGJvZHlTcGFjaW5nOiAyLFxuICAgICAgICBib2R5Rm9udDoge30sXG4gICAgICAgIGJvZHlBbGlnbjogJ2xlZnQnLFxuICAgICAgICBmb290ZXJDb2xvcjogJyNmZmYnLFxuICAgICAgICBmb290ZXJTcGFjaW5nOiAyLFxuICAgICAgICBmb290ZXJNYXJnaW5Ub3A6IDYsXG4gICAgICAgIGZvb3RlckZvbnQ6IHtcbiAgICAgICAgICAgIHdlaWdodDogJ2JvbGQnXG4gICAgICAgIH0sXG4gICAgICAgIGZvb3RlckFsaWduOiAnbGVmdCcsXG4gICAgICAgIHBhZGRpbmc6IDYsXG4gICAgICAgIGNhcmV0UGFkZGluZzogMixcbiAgICAgICAgY2FyZXRTaXplOiA1LFxuICAgICAgICBjb3JuZXJSYWRpdXM6IDYsXG4gICAgICAgIGJveEhlaWdodDogKGN0eCwgb3B0cyk9Pm9wdHMuYm9keUZvbnQuc2l6ZSxcbiAgICAgICAgYm94V2lkdGg6IChjdHgsIG9wdHMpPT5vcHRzLmJvZHlGb250LnNpemUsXG4gICAgICAgIG11bHRpS2V5QmFja2dyb3VuZDogJyNmZmYnLFxuICAgICAgICBkaXNwbGF5Q29sb3JzOiB0cnVlLFxuICAgICAgICBib3hQYWRkaW5nOiAwLFxuICAgICAgICBib3JkZXJDb2xvcjogJ3JnYmEoMCwwLDAsMCknLFxuICAgICAgICBib3JkZXJXaWR0aDogMCxcbiAgICAgICAgYW5pbWF0aW9uOiB7XG4gICAgICAgICAgICBkdXJhdGlvbjogNDAwLFxuICAgICAgICAgICAgZWFzaW5nOiAnZWFzZU91dFF1YXJ0J1xuICAgICAgICB9LFxuICAgICAgICBhbmltYXRpb25zOiB7XG4gICAgICAgICAgICBudW1iZXJzOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICAgICAgICAgICAgcHJvcGVydGllczogW1xuICAgICAgICAgICAgICAgICAgICAneCcsXG4gICAgICAgICAgICAgICAgICAgICd5JyxcbiAgICAgICAgICAgICAgICAgICAgJ3dpZHRoJyxcbiAgICAgICAgICAgICAgICAgICAgJ2hlaWdodCcsXG4gICAgICAgICAgICAgICAgICAgICdjYXJldFgnLFxuICAgICAgICAgICAgICAgICAgICAnY2FyZXRZJ1xuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvcGFjaXR5OiB7XG4gICAgICAgICAgICAgICAgZWFzaW5nOiAnbGluZWFyJyxcbiAgICAgICAgICAgICAgICBkdXJhdGlvbjogMjAwXG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGNhbGxiYWNrczogZGVmYXVsdENhbGxiYWNrc1xuICAgIH0sXG4gICAgZGVmYXVsdFJvdXRlczoge1xuICAgICAgICBib2R5Rm9udDogJ2ZvbnQnLFxuICAgICAgICBmb290ZXJGb250OiAnZm9udCcsXG4gICAgICAgIHRpdGxlRm9udDogJ2ZvbnQnXG4gICAgfSxcbiAgICBkZXNjcmlwdG9yczoge1xuICAgICAgICBfc2NyaXB0YWJsZTogKG5hbWUpPT5uYW1lICE9PSAnZmlsdGVyJyAmJiBuYW1lICE9PSAnaXRlbVNvcnQnICYmIG5hbWUgIT09ICdleHRlcm5hbCcsXG4gICAgICAgIF9pbmRleGFibGU6IGZhbHNlLFxuICAgICAgICBjYWxsYmFja3M6IHtcbiAgICAgICAgICAgIF9zY3JpcHRhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIF9pbmRleGFibGU6IGZhbHNlXG4gICAgICAgIH0sXG4gICAgICAgIGFuaW1hdGlvbjoge1xuICAgICAgICAgICAgX2ZhbGxiYWNrOiBmYWxzZVxuICAgICAgICB9LFxuICAgICAgICBhbmltYXRpb25zOiB7XG4gICAgICAgICAgICBfZmFsbGJhY2s6ICdhbmltYXRpb24nXG4gICAgICAgIH1cbiAgICB9LFxuICAgIGFkZGl0aW9uYWxPcHRpb25TY29wZXM6IFtcbiAgICAgICAgJ2ludGVyYWN0aW9uJ1xuICAgIF1cbn07XG5cbnZhciBwbHVnaW5zID0gLyojX19QVVJFX18qL09iamVjdC5mcmVlemUoe1xuX19wcm90b19fOiBudWxsLFxuQ29sb3JzOiBwbHVnaW5fY29sb3JzLFxuRGVjaW1hdGlvbjogcGx1Z2luX2RlY2ltYXRpb24sXG5GaWxsZXI6IGluZGV4LFxuTGVnZW5kOiBwbHVnaW5fbGVnZW5kLFxuU3ViVGl0bGU6IHBsdWdpbl9zdWJ0aXRsZSxcblRpdGxlOiBwbHVnaW5fdGl0bGUsXG5Ub29sdGlwOiBwbHVnaW5fdG9vbHRpcFxufSk7XG5cbmNvbnN0IGFkZElmU3RyaW5nID0gKGxhYmVscywgcmF3LCBpbmRleCwgYWRkZWRMYWJlbHMpPT57XG4gICAgaWYgKHR5cGVvZiByYXcgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGluZGV4ID0gbGFiZWxzLnB1c2gocmF3KSAtIDE7XG4gICAgICAgIGFkZGVkTGFiZWxzLnVuc2hpZnQoe1xuICAgICAgICAgICAgaW5kZXgsXG4gICAgICAgICAgICBsYWJlbDogcmF3XG4gICAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAoaXNOYU4ocmF3KSkge1xuICAgICAgICBpbmRleCA9IG51bGw7XG4gICAgfVxuICAgIHJldHVybiBpbmRleDtcbn07XG5mdW5jdGlvbiBmaW5kT3JBZGRMYWJlbChsYWJlbHMsIHJhdywgaW5kZXgsIGFkZGVkTGFiZWxzKSB7XG4gICAgY29uc3QgZmlyc3QgPSBsYWJlbHMuaW5kZXhPZihyYXcpO1xuICAgIGlmIChmaXJzdCA9PT0gLTEpIHtcbiAgICAgICAgcmV0dXJuIGFkZElmU3RyaW5nKGxhYmVscywgcmF3LCBpbmRleCwgYWRkZWRMYWJlbHMpO1xuICAgIH1cbiAgICBjb25zdCBsYXN0ID0gbGFiZWxzLmxhc3RJbmRleE9mKHJhdyk7XG4gICAgcmV0dXJuIGZpcnN0ICE9PSBsYXN0ID8gaW5kZXggOiBmaXJzdDtcbn1cbmNvbnN0IHZhbGlkSW5kZXggPSAoaW5kZXgsIG1heCk9PmluZGV4ID09PSBudWxsID8gbnVsbCA6IF9saW1pdFZhbHVlKE1hdGgucm91bmQoaW5kZXgpLCAwLCBtYXgpO1xuZnVuY3Rpb24gX2dldExhYmVsRm9yVmFsdWUodmFsdWUpIHtcbiAgICBjb25zdCBsYWJlbHMgPSB0aGlzLmdldExhYmVscygpO1xuICAgIGlmICh2YWx1ZSA+PSAwICYmIHZhbHVlIDwgbGFiZWxzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gbGFiZWxzW3ZhbHVlXTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuY2xhc3MgQ2F0ZWdvcnlTY2FsZSBleHRlbmRzIFNjYWxlIHtcbiAgICBzdGF0aWMgaWQgPSAnY2F0ZWdvcnknO1xuIHN0YXRpYyBkZWZhdWx0cyA9IHtcbiAgICAgICAgdGlja3M6IHtcbiAgICAgICAgICAgIGNhbGxiYWNrOiBfZ2V0TGFiZWxGb3JWYWx1ZVxuICAgICAgICB9XG4gICAgfTtcbiAgICBjb25zdHJ1Y3RvcihjZmcpe1xuICAgICAgICBzdXBlcihjZmcpO1xuICAgICAgICAgdGhpcy5fc3RhcnRWYWx1ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fdmFsdWVSYW5nZSA9IDA7XG4gICAgICAgIHRoaXMuX2FkZGVkTGFiZWxzID0gW107XG4gICAgfVxuICAgIGluaXQoc2NhbGVPcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IGFkZGVkID0gdGhpcy5fYWRkZWRMYWJlbHM7XG4gICAgICAgIGlmIChhZGRlZC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNvbnN0IGxhYmVscyA9IHRoaXMuZ2V0TGFiZWxzKCk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHsgaW5kZXggLCBsYWJlbCAgfSBvZiBhZGRlZCl7XG4gICAgICAgICAgICAgICAgaWYgKGxhYmVsc1tpbmRleF0gPT09IGxhYmVsKSB7XG4gICAgICAgICAgICAgICAgICAgIGxhYmVscy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX2FkZGVkTGFiZWxzID0gW107XG4gICAgICAgIH1cbiAgICAgICAgc3VwZXIuaW5pdChzY2FsZU9wdGlvbnMpO1xuICAgIH1cbiAgICBwYXJzZShyYXcsIGluZGV4KSB7XG4gICAgICAgIGlmIChpc051bGxPclVuZGVmKHJhdykpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGxhYmVscyA9IHRoaXMuZ2V0TGFiZWxzKCk7XG4gICAgICAgIGluZGV4ID0gaXNGaW5pdGUoaW5kZXgpICYmIGxhYmVsc1tpbmRleF0gPT09IHJhdyA/IGluZGV4IDogZmluZE9yQWRkTGFiZWwobGFiZWxzLCByYXcsIHZhbHVlT3JEZWZhdWx0KGluZGV4LCByYXcpLCB0aGlzLl9hZGRlZExhYmVscyk7XG4gICAgICAgIHJldHVybiB2YWxpZEluZGV4KGluZGV4LCBsYWJlbHMubGVuZ3RoIC0gMSk7XG4gICAgfVxuICAgIGRldGVybWluZURhdGFMaW1pdHMoKSB7XG4gICAgICAgIGNvbnN0IHsgbWluRGVmaW5lZCAsIG1heERlZmluZWQgIH0gPSB0aGlzLmdldFVzZXJCb3VuZHMoKTtcbiAgICAgICAgbGV0IHsgbWluICwgbWF4ICB9ID0gdGhpcy5nZXRNaW5NYXgodHJ1ZSk7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuYm91bmRzID09PSAndGlja3MnKSB7XG4gICAgICAgICAgICBpZiAoIW1pbkRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBtaW4gPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFtYXhEZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgbWF4ID0gdGhpcy5nZXRMYWJlbHMoKS5sZW5ndGggLSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMubWluID0gbWluO1xuICAgICAgICB0aGlzLm1heCA9IG1heDtcbiAgICB9XG4gICAgYnVpbGRUaWNrcygpIHtcbiAgICAgICAgY29uc3QgbWluID0gdGhpcy5taW47XG4gICAgICAgIGNvbnN0IG1heCA9IHRoaXMubWF4O1xuICAgICAgICBjb25zdCBvZmZzZXQgPSB0aGlzLm9wdGlvbnMub2Zmc2V0O1xuICAgICAgICBjb25zdCB0aWNrcyA9IFtdO1xuICAgICAgICBsZXQgbGFiZWxzID0gdGhpcy5nZXRMYWJlbHMoKTtcbiAgICAgICAgbGFiZWxzID0gbWluID09PSAwICYmIG1heCA9PT0gbGFiZWxzLmxlbmd0aCAtIDEgPyBsYWJlbHMgOiBsYWJlbHMuc2xpY2UobWluLCBtYXggKyAxKTtcbiAgICAgICAgdGhpcy5fdmFsdWVSYW5nZSA9IE1hdGgubWF4KGxhYmVscy5sZW5ndGggLSAob2Zmc2V0ID8gMCA6IDEpLCAxKTtcbiAgICAgICAgdGhpcy5fc3RhcnRWYWx1ZSA9IHRoaXMubWluIC0gKG9mZnNldCA/IDAuNSA6IDApO1xuICAgICAgICBmb3IobGV0IHZhbHVlID0gbWluOyB2YWx1ZSA8PSBtYXg7IHZhbHVlKyspe1xuICAgICAgICAgICAgdGlja3MucHVzaCh7XG4gICAgICAgICAgICAgICAgdmFsdWVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aWNrcztcbiAgICB9XG4gICAgZ2V0TGFiZWxGb3JWYWx1ZSh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gX2dldExhYmVsRm9yVmFsdWUuY2FsbCh0aGlzLCB2YWx1ZSk7XG4gICAgfVxuIGNvbmZpZ3VyZSgpIHtcbiAgICAgICAgc3VwZXIuY29uZmlndXJlKCk7XG4gICAgICAgIGlmICghdGhpcy5pc0hvcml6b250YWwoKSkge1xuICAgICAgICAgICAgdGhpcy5fcmV2ZXJzZVBpeGVscyA9ICF0aGlzLl9yZXZlcnNlUGl4ZWxzO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldFBpeGVsRm9yVmFsdWUodmFsdWUpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIHZhbHVlID0gdGhpcy5wYXJzZSh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsID8gTmFOIDogdGhpcy5nZXRQaXhlbEZvckRlY2ltYWwoKHZhbHVlIC0gdGhpcy5fc3RhcnRWYWx1ZSkgLyB0aGlzLl92YWx1ZVJhbmdlKTtcbiAgICB9XG4gICAgZ2V0UGl4ZWxGb3JUaWNrKGluZGV4KSB7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy50aWNrcztcbiAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+IHRpY2tzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBpeGVsRm9yVmFsdWUodGlja3NbaW5kZXhdLnZhbHVlKTtcbiAgICB9XG4gICAgZ2V0VmFsdWVGb3JQaXhlbChwaXhlbCkge1xuICAgICAgICByZXR1cm4gTWF0aC5yb3VuZCh0aGlzLl9zdGFydFZhbHVlICsgdGhpcy5nZXREZWNpbWFsRm9yUGl4ZWwocGl4ZWwpICogdGhpcy5fdmFsdWVSYW5nZSk7XG4gICAgfVxuICAgIGdldEJhc2VQaXhlbCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYm90dG9tO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZ2VuZXJhdGVUaWNrcyQxKGdlbmVyYXRpb25PcHRpb25zLCBkYXRhUmFuZ2UpIHtcbiAgICBjb25zdCB0aWNrcyA9IFtdO1xuICAgIGNvbnN0IE1JTl9TUEFDSU5HID0gMWUtMTQ7XG4gICAgY29uc3QgeyBib3VuZHMgLCBzdGVwICwgbWluICwgbWF4ICwgcHJlY2lzaW9uICwgY291bnQgLCBtYXhUaWNrcyAsIG1heERpZ2l0cyAsIGluY2x1ZGVCb3VuZHMgIH0gPSBnZW5lcmF0aW9uT3B0aW9ucztcbiAgICBjb25zdCB1bml0ID0gc3RlcCB8fCAxO1xuICAgIGNvbnN0IG1heFNwYWNlcyA9IG1heFRpY2tzIC0gMTtcbiAgICBjb25zdCB7IG1pbjogcm1pbiAsIG1heDogcm1heCAgfSA9IGRhdGFSYW5nZTtcbiAgICBjb25zdCBtaW5EZWZpbmVkID0gIWlzTnVsbE9yVW5kZWYobWluKTtcbiAgICBjb25zdCBtYXhEZWZpbmVkID0gIWlzTnVsbE9yVW5kZWYobWF4KTtcbiAgICBjb25zdCBjb3VudERlZmluZWQgPSAhaXNOdWxsT3JVbmRlZihjb3VudCk7XG4gICAgY29uc3QgbWluU3BhY2luZyA9IChybWF4IC0gcm1pbikgLyAobWF4RGlnaXRzICsgMSk7XG4gICAgbGV0IHNwYWNpbmcgPSBuaWNlTnVtKChybWF4IC0gcm1pbikgLyBtYXhTcGFjZXMgLyB1bml0KSAqIHVuaXQ7XG4gICAgbGV0IGZhY3RvciwgbmljZU1pbiwgbmljZU1heCwgbnVtU3BhY2VzO1xuICAgIGlmIChzcGFjaW5nIDwgTUlOX1NQQUNJTkcgJiYgIW1pbkRlZmluZWQgJiYgIW1heERlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogcm1pblxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogcm1heFxuICAgICAgICAgICAgfVxuICAgICAgICBdO1xuICAgIH1cbiAgICBudW1TcGFjZXMgPSBNYXRoLmNlaWwocm1heCAvIHNwYWNpbmcpIC0gTWF0aC5mbG9vcihybWluIC8gc3BhY2luZyk7XG4gICAgaWYgKG51bVNwYWNlcyA+IG1heFNwYWNlcykge1xuICAgICAgICBzcGFjaW5nID0gbmljZU51bShudW1TcGFjZXMgKiBzcGFjaW5nIC8gbWF4U3BhY2VzIC8gdW5pdCkgKiB1bml0O1xuICAgIH1cbiAgICBpZiAoIWlzTnVsbE9yVW5kZWYocHJlY2lzaW9uKSkge1xuICAgICAgICBmYWN0b3IgPSBNYXRoLnBvdygxMCwgcHJlY2lzaW9uKTtcbiAgICAgICAgc3BhY2luZyA9IE1hdGguY2VpbChzcGFjaW5nICogZmFjdG9yKSAvIGZhY3RvcjtcbiAgICB9XG4gICAgaWYgKGJvdW5kcyA9PT0gJ3RpY2tzJykge1xuICAgICAgICBuaWNlTWluID0gTWF0aC5mbG9vcihybWluIC8gc3BhY2luZykgKiBzcGFjaW5nO1xuICAgICAgICBuaWNlTWF4ID0gTWF0aC5jZWlsKHJtYXggLyBzcGFjaW5nKSAqIHNwYWNpbmc7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgbmljZU1pbiA9IHJtaW47XG4gICAgICAgIG5pY2VNYXggPSBybWF4O1xuICAgIH1cbiAgICBpZiAobWluRGVmaW5lZCAmJiBtYXhEZWZpbmVkICYmIHN0ZXAgJiYgYWxtb3N0V2hvbGUoKG1heCAtIG1pbikgLyBzdGVwLCBzcGFjaW5nIC8gMTAwMCkpIHtcbiAgICAgICAgbnVtU3BhY2VzID0gTWF0aC5yb3VuZChNYXRoLm1pbigobWF4IC0gbWluKSAvIHNwYWNpbmcsIG1heFRpY2tzKSk7XG4gICAgICAgIHNwYWNpbmcgPSAobWF4IC0gbWluKSAvIG51bVNwYWNlcztcbiAgICAgICAgbmljZU1pbiA9IG1pbjtcbiAgICAgICAgbmljZU1heCA9IG1heDtcbiAgICB9IGVsc2UgaWYgKGNvdW50RGVmaW5lZCkge1xuICAgICAgICBuaWNlTWluID0gbWluRGVmaW5lZCA/IG1pbiA6IG5pY2VNaW47XG4gICAgICAgIG5pY2VNYXggPSBtYXhEZWZpbmVkID8gbWF4IDogbmljZU1heDtcbiAgICAgICAgbnVtU3BhY2VzID0gY291bnQgLSAxO1xuICAgICAgICBzcGFjaW5nID0gKG5pY2VNYXggLSBuaWNlTWluKSAvIG51bVNwYWNlcztcbiAgICB9IGVsc2Uge1xuICAgICAgICBudW1TcGFjZXMgPSAobmljZU1heCAtIG5pY2VNaW4pIC8gc3BhY2luZztcbiAgICAgICAgaWYgKGFsbW9zdEVxdWFscyhudW1TcGFjZXMsIE1hdGgucm91bmQobnVtU3BhY2VzKSwgc3BhY2luZyAvIDEwMDApKSB7XG4gICAgICAgICAgICBudW1TcGFjZXMgPSBNYXRoLnJvdW5kKG51bVNwYWNlcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBudW1TcGFjZXMgPSBNYXRoLmNlaWwobnVtU3BhY2VzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBkZWNpbWFsUGxhY2VzID0gTWF0aC5tYXgoX2RlY2ltYWxQbGFjZXMoc3BhY2luZyksIF9kZWNpbWFsUGxhY2VzKG5pY2VNaW4pKTtcbiAgICBmYWN0b3IgPSBNYXRoLnBvdygxMCwgaXNOdWxsT3JVbmRlZihwcmVjaXNpb24pID8gZGVjaW1hbFBsYWNlcyA6IHByZWNpc2lvbik7XG4gICAgbmljZU1pbiA9IE1hdGgucm91bmQobmljZU1pbiAqIGZhY3RvcikgLyBmYWN0b3I7XG4gICAgbmljZU1heCA9IE1hdGgucm91bmQobmljZU1heCAqIGZhY3RvcikgLyBmYWN0b3I7XG4gICAgbGV0IGogPSAwO1xuICAgIGlmIChtaW5EZWZpbmVkKSB7XG4gICAgICAgIGlmIChpbmNsdWRlQm91bmRzICYmIG5pY2VNaW4gIT09IG1pbikge1xuICAgICAgICAgICAgdGlja3MucHVzaCh7XG4gICAgICAgICAgICAgICAgdmFsdWU6IG1pblxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAobmljZU1pbiA8IG1pbikge1xuICAgICAgICAgICAgICAgIGorKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChhbG1vc3RFcXVhbHMoTWF0aC5yb3VuZCgobmljZU1pbiArIGogKiBzcGFjaW5nKSAqIGZhY3RvcikgLyBmYWN0b3IsIG1pbiwgcmVsYXRpdmVMYWJlbFNpemUobWluLCBtaW5TcGFjaW5nLCBnZW5lcmF0aW9uT3B0aW9ucykpKSB7XG4gICAgICAgICAgICAgICAgaisrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKG5pY2VNaW4gPCBtaW4pIHtcbiAgICAgICAgICAgIGorKztcbiAgICAgICAgfVxuICAgIH1cbiAgICBmb3IoOyBqIDwgbnVtU3BhY2VzOyArK2ope1xuICAgICAgICBjb25zdCB0aWNrVmFsdWUgPSBNYXRoLnJvdW5kKChuaWNlTWluICsgaiAqIHNwYWNpbmcpICogZmFjdG9yKSAvIGZhY3RvcjtcbiAgICAgICAgaWYgKG1heERlZmluZWQgJiYgdGlja1ZhbHVlID4gbWF4KSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICB0aWNrcy5wdXNoKHtcbiAgICAgICAgICAgIHZhbHVlOiB0aWNrVmFsdWVcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChtYXhEZWZpbmVkICYmIGluY2x1ZGVCb3VuZHMgJiYgbmljZU1heCAhPT0gbWF4KSB7XG4gICAgICAgIGlmICh0aWNrcy5sZW5ndGggJiYgYWxtb3N0RXF1YWxzKHRpY2tzW3RpY2tzLmxlbmd0aCAtIDFdLnZhbHVlLCBtYXgsIHJlbGF0aXZlTGFiZWxTaXplKG1heCwgbWluU3BhY2luZywgZ2VuZXJhdGlvbk9wdGlvbnMpKSkge1xuICAgICAgICAgICAgdGlja3NbdGlja3MubGVuZ3RoIC0gMV0udmFsdWUgPSBtYXg7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aWNrcy5wdXNoKHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogbWF4XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIW1heERlZmluZWQgfHwgbmljZU1heCA9PT0gbWF4KSB7XG4gICAgICAgIHRpY2tzLnB1c2goe1xuICAgICAgICAgICAgdmFsdWU6IG5pY2VNYXhcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiB0aWNrcztcbn1cbmZ1bmN0aW9uIHJlbGF0aXZlTGFiZWxTaXplKHZhbHVlLCBtaW5TcGFjaW5nLCB7IGhvcml6b250YWwgLCBtaW5Sb3RhdGlvbiAgfSkge1xuICAgIGNvbnN0IHJhZCA9IHRvUmFkaWFucyhtaW5Sb3RhdGlvbik7XG4gICAgY29uc3QgcmF0aW8gPSAoaG9yaXpvbnRhbCA/IE1hdGguc2luKHJhZCkgOiBNYXRoLmNvcyhyYWQpKSB8fCAwLjAwMTtcbiAgICBjb25zdCBsZW5ndGggPSAwLjc1ICogbWluU3BhY2luZyAqICgnJyArIHZhbHVlKS5sZW5ndGg7XG4gICAgcmV0dXJuIE1hdGgubWluKG1pblNwYWNpbmcgLyByYXRpbywgbGVuZ3RoKTtcbn1cbmNsYXNzIExpbmVhclNjYWxlQmFzZSBleHRlbmRzIFNjYWxlIHtcbiAgICBjb25zdHJ1Y3RvcihjZmcpe1xuICAgICAgICBzdXBlcihjZmcpO1xuICAgICAgICAgdGhpcy5zdGFydCA9IHVuZGVmaW5lZDtcbiAgICAgICAgIHRoaXMuZW5kID0gdW5kZWZpbmVkO1xuICAgICAgICAgdGhpcy5fc3RhcnRWYWx1ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgIHRoaXMuX2VuZFZhbHVlID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl92YWx1ZVJhbmdlID0gMDtcbiAgICB9XG4gICAgcGFyc2UocmF3LCBpbmRleCkge1xuICAgICAgICBpZiAoaXNOdWxsT3JVbmRlZihyYXcpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoKHR5cGVvZiByYXcgPT09ICdudW1iZXInIHx8IHJhdyBpbnN0YW5jZW9mIE51bWJlcikgJiYgIWlzRmluaXRlKCtyYXcpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gK3JhdztcbiAgICB9XG4gICAgaGFuZGxlVGlja1JhbmdlT3B0aW9ucygpIHtcbiAgICAgICAgY29uc3QgeyBiZWdpbkF0WmVybyAgfSA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgY29uc3QgeyBtaW5EZWZpbmVkICwgbWF4RGVmaW5lZCAgfSA9IHRoaXMuZ2V0VXNlckJvdW5kcygpO1xuICAgICAgICBsZXQgeyBtaW4gLCBtYXggIH0gPSB0aGlzO1xuICAgICAgICBjb25zdCBzZXRNaW4gPSAodik9Pm1pbiA9IG1pbkRlZmluZWQgPyBtaW4gOiB2O1xuICAgICAgICBjb25zdCBzZXRNYXggPSAodik9Pm1heCA9IG1heERlZmluZWQgPyBtYXggOiB2O1xuICAgICAgICBpZiAoYmVnaW5BdFplcm8pIHtcbiAgICAgICAgICAgIGNvbnN0IG1pblNpZ24gPSBzaWduKG1pbik7XG4gICAgICAgICAgICBjb25zdCBtYXhTaWduID0gc2lnbihtYXgpO1xuICAgICAgICAgICAgaWYgKG1pblNpZ24gPCAwICYmIG1heFNpZ24gPCAwKSB7XG4gICAgICAgICAgICAgICAgc2V0TWF4KDApO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChtaW5TaWduID4gMCAmJiBtYXhTaWduID4gMCkge1xuICAgICAgICAgICAgICAgIHNldE1pbigwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAobWluID09PSBtYXgpIHtcbiAgICAgICAgICAgIGxldCBvZmZzZXQgPSBtYXggPT09IDAgPyAxIDogTWF0aC5hYnMobWF4ICogMC4wNSk7XG4gICAgICAgICAgICBzZXRNYXgobWF4ICsgb2Zmc2V0KTtcbiAgICAgICAgICAgIGlmICghYmVnaW5BdFplcm8pIHtcbiAgICAgICAgICAgICAgICBzZXRNaW4obWluIC0gb2Zmc2V0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLm1pbiA9IG1pbjtcbiAgICAgICAgdGhpcy5tYXggPSBtYXg7XG4gICAgfVxuICAgIGdldFRpY2tMaW1pdCgpIHtcbiAgICAgICAgY29uc3QgdGlja09wdHMgPSB0aGlzLm9wdGlvbnMudGlja3M7XG4gICAgICAgIGxldCB7IG1heFRpY2tzTGltaXQgLCBzdGVwU2l6ZSAgfSA9IHRpY2tPcHRzO1xuICAgICAgICBsZXQgbWF4VGlja3M7XG4gICAgICAgIGlmIChzdGVwU2l6ZSkge1xuICAgICAgICAgICAgbWF4VGlja3MgPSBNYXRoLmNlaWwodGhpcy5tYXggLyBzdGVwU2l6ZSkgLSBNYXRoLmZsb29yKHRoaXMubWluIC8gc3RlcFNpemUpICsgMTtcbiAgICAgICAgICAgIGlmIChtYXhUaWNrcyA+IDEwMDApIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYHNjYWxlcy4ke3RoaXMuaWR9LnRpY2tzLnN0ZXBTaXplOiAke3N0ZXBTaXplfSB3b3VsZCByZXN1bHQgZ2VuZXJhdGluZyB1cCB0byAke21heFRpY2tzfSB0aWNrcy4gTGltaXRpbmcgdG8gMTAwMC5gKTtcbiAgICAgICAgICAgICAgICBtYXhUaWNrcyA9IDEwMDA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBtYXhUaWNrcyA9IHRoaXMuY29tcHV0ZVRpY2tMaW1pdCgpO1xuICAgICAgICAgICAgbWF4VGlja3NMaW1pdCA9IG1heFRpY2tzTGltaXQgfHwgMTE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1heFRpY2tzTGltaXQpIHtcbiAgICAgICAgICAgIG1heFRpY2tzID0gTWF0aC5taW4obWF4VGlja3NMaW1pdCwgbWF4VGlja3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtYXhUaWNrcztcbiAgICB9XG4gY29tcHV0ZVRpY2tMaW1pdCgpIHtcbiAgICAgICAgcmV0dXJuIE51bWJlci5QT1NJVElWRV9JTkZJTklUWTtcbiAgICB9XG4gICAgYnVpbGRUaWNrcygpIHtcbiAgICAgICAgY29uc3Qgb3B0cyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgY29uc3QgdGlja09wdHMgPSBvcHRzLnRpY2tzO1xuICAgICAgICBsZXQgbWF4VGlja3MgPSB0aGlzLmdldFRpY2tMaW1pdCgpO1xuICAgICAgICBtYXhUaWNrcyA9IE1hdGgubWF4KDIsIG1heFRpY2tzKTtcbiAgICAgICAgY29uc3QgbnVtZXJpY0dlbmVyYXRvck9wdGlvbnMgPSB7XG4gICAgICAgICAgICBtYXhUaWNrcyxcbiAgICAgICAgICAgIGJvdW5kczogb3B0cy5ib3VuZHMsXG4gICAgICAgICAgICBtaW46IG9wdHMubWluLFxuICAgICAgICAgICAgbWF4OiBvcHRzLm1heCxcbiAgICAgICAgICAgIHByZWNpc2lvbjogdGlja09wdHMucHJlY2lzaW9uLFxuICAgICAgICAgICAgc3RlcDogdGlja09wdHMuc3RlcFNpemUsXG4gICAgICAgICAgICBjb3VudDogdGlja09wdHMuY291bnQsXG4gICAgICAgICAgICBtYXhEaWdpdHM6IHRoaXMuX21heERpZ2l0cygpLFxuICAgICAgICAgICAgaG9yaXpvbnRhbDogdGhpcy5pc0hvcml6b250YWwoKSxcbiAgICAgICAgICAgIG1pblJvdGF0aW9uOiB0aWNrT3B0cy5taW5Sb3RhdGlvbiB8fCAwLFxuICAgICAgICAgICAgaW5jbHVkZUJvdW5kczogdGlja09wdHMuaW5jbHVkZUJvdW5kcyAhPT0gZmFsc2VcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZGF0YVJhbmdlID0gdGhpcy5fcmFuZ2UgfHwgdGhpcztcbiAgICAgICAgY29uc3QgdGlja3MgPSBnZW5lcmF0ZVRpY2tzJDEobnVtZXJpY0dlbmVyYXRvck9wdGlvbnMsIGRhdGFSYW5nZSk7XG4gICAgICAgIGlmIChvcHRzLmJvdW5kcyA9PT0gJ3RpY2tzJykge1xuICAgICAgICAgICAgX3NldE1pbkFuZE1heEJ5S2V5KHRpY2tzLCB0aGlzLCAndmFsdWUnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0cy5yZXZlcnNlKSB7XG4gICAgICAgICAgICB0aWNrcy5yZXZlcnNlKCk7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0ID0gdGhpcy5tYXg7XG4gICAgICAgICAgICB0aGlzLmVuZCA9IHRoaXMubWluO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zdGFydCA9IHRoaXMubWluO1xuICAgICAgICAgICAgdGhpcy5lbmQgPSB0aGlzLm1heDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGlja3M7XG4gICAgfVxuIGNvbmZpZ3VyZSgpIHtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLnRpY2tzO1xuICAgICAgICBsZXQgc3RhcnQgPSB0aGlzLm1pbjtcbiAgICAgICAgbGV0IGVuZCA9IHRoaXMubWF4O1xuICAgICAgICBzdXBlci5jb25maWd1cmUoKTtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5vZmZzZXQgJiYgdGlja3MubGVuZ3RoKSB7XG4gICAgICAgICAgICBjb25zdCBvZmZzZXQgPSAoZW5kIC0gc3RhcnQpIC8gTWF0aC5tYXgodGlja3MubGVuZ3RoIC0gMSwgMSkgLyAyO1xuICAgICAgICAgICAgc3RhcnQgLT0gb2Zmc2V0O1xuICAgICAgICAgICAgZW5kICs9IG9mZnNldDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9zdGFydFZhbHVlID0gc3RhcnQ7XG4gICAgICAgIHRoaXMuX2VuZFZhbHVlID0gZW5kO1xuICAgICAgICB0aGlzLl92YWx1ZVJhbmdlID0gZW5kIC0gc3RhcnQ7XG4gICAgfVxuICAgIGdldExhYmVsRm9yVmFsdWUodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGZvcm1hdE51bWJlcih2YWx1ZSwgdGhpcy5jaGFydC5vcHRpb25zLmxvY2FsZSwgdGhpcy5vcHRpb25zLnRpY2tzLmZvcm1hdCk7XG4gICAgfVxufVxuXG5jbGFzcyBMaW5lYXJTY2FsZSBleHRlbmRzIExpbmVhclNjYWxlQmFzZSB7XG4gICAgc3RhdGljIGlkID0gJ2xpbmVhcic7XG4gc3RhdGljIGRlZmF1bHRzID0ge1xuICAgICAgICB0aWNrczoge1xuICAgICAgICAgICAgY2FsbGJhY2s6IFRpY2tzLmZvcm1hdHRlcnMubnVtZXJpY1xuICAgICAgICB9XG4gICAgfTtcbiAgICBkZXRlcm1pbmVEYXRhTGltaXRzKCkge1xuICAgICAgICBjb25zdCB7IG1pbiAsIG1heCAgfSA9IHRoaXMuZ2V0TWluTWF4KHRydWUpO1xuICAgICAgICB0aGlzLm1pbiA9IGlzTnVtYmVyRmluaXRlKG1pbikgPyBtaW4gOiAwO1xuICAgICAgICB0aGlzLm1heCA9IGlzTnVtYmVyRmluaXRlKG1heCkgPyBtYXggOiAxO1xuICAgICAgICB0aGlzLmhhbmRsZVRpY2tSYW5nZU9wdGlvbnMoKTtcbiAgICB9XG4gY29tcHV0ZVRpY2tMaW1pdCgpIHtcbiAgICAgICAgY29uc3QgaG9yaXpvbnRhbCA9IHRoaXMuaXNIb3Jpem9udGFsKCk7XG4gICAgICAgIGNvbnN0IGxlbmd0aCA9IGhvcml6b250YWwgPyB0aGlzLndpZHRoIDogdGhpcy5oZWlnaHQ7XG4gICAgICAgIGNvbnN0IG1pblJvdGF0aW9uID0gdG9SYWRpYW5zKHRoaXMub3B0aW9ucy50aWNrcy5taW5Sb3RhdGlvbik7XG4gICAgICAgIGNvbnN0IHJhdGlvID0gKGhvcml6b250YWwgPyBNYXRoLnNpbihtaW5Sb3RhdGlvbikgOiBNYXRoLmNvcyhtaW5Sb3RhdGlvbikpIHx8IDAuMDAxO1xuICAgICAgICBjb25zdCB0aWNrRm9udCA9IHRoaXMuX3Jlc29sdmVUaWNrRm9udE9wdGlvbnMoMCk7XG4gICAgICAgIHJldHVybiBNYXRoLmNlaWwobGVuZ3RoIC8gTWF0aC5taW4oNDAsIHRpY2tGb250LmxpbmVIZWlnaHQgLyByYXRpbykpO1xuICAgIH1cbiAgICBnZXRQaXhlbEZvclZhbHVlKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZSA9PT0gbnVsbCA/IE5hTiA6IHRoaXMuZ2V0UGl4ZWxGb3JEZWNpbWFsKCh2YWx1ZSAtIHRoaXMuX3N0YXJ0VmFsdWUpIC8gdGhpcy5fdmFsdWVSYW5nZSk7XG4gICAgfVxuICAgIGdldFZhbHVlRm9yUGl4ZWwocGl4ZWwpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXJ0VmFsdWUgKyB0aGlzLmdldERlY2ltYWxGb3JQaXhlbChwaXhlbCkgKiB0aGlzLl92YWx1ZVJhbmdlO1xuICAgIH1cbn1cblxuY29uc3QgbG9nMTBGbG9vciA9ICh2KT0+TWF0aC5mbG9vcihsb2cxMCh2KSk7XG5jb25zdCBjaGFuZ2VFeHBvbmVudCA9ICh2LCBtKT0+TWF0aC5wb3coMTAsIGxvZzEwRmxvb3IodikgKyBtKTtcbmZ1bmN0aW9uIGlzTWFqb3IodGlja1ZhbCkge1xuICAgIGNvbnN0IHJlbWFpbiA9IHRpY2tWYWwgLyBNYXRoLnBvdygxMCwgbG9nMTBGbG9vcih0aWNrVmFsKSk7XG4gICAgcmV0dXJuIHJlbWFpbiA9PT0gMTtcbn1cbmZ1bmN0aW9uIHN0ZXBzKG1pbiwgbWF4LCByYW5nZUV4cCkge1xuICAgIGNvbnN0IHJhbmdlU3RlcCA9IE1hdGgucG93KDEwLCByYW5nZUV4cCk7XG4gICAgY29uc3Qgc3RhcnQgPSBNYXRoLmZsb29yKG1pbiAvIHJhbmdlU3RlcCk7XG4gICAgY29uc3QgZW5kID0gTWF0aC5jZWlsKG1heCAvIHJhbmdlU3RlcCk7XG4gICAgcmV0dXJuIGVuZCAtIHN0YXJ0O1xufVxuZnVuY3Rpb24gc3RhcnRFeHAobWluLCBtYXgpIHtcbiAgICBjb25zdCByYW5nZSA9IG1heCAtIG1pbjtcbiAgICBsZXQgcmFuZ2VFeHAgPSBsb2cxMEZsb29yKHJhbmdlKTtcbiAgICB3aGlsZShzdGVwcyhtaW4sIG1heCwgcmFuZ2VFeHApID4gMTApe1xuICAgICAgICByYW5nZUV4cCsrO1xuICAgIH1cbiAgICB3aGlsZShzdGVwcyhtaW4sIG1heCwgcmFuZ2VFeHApIDwgMTApe1xuICAgICAgICByYW5nZUV4cC0tO1xuICAgIH1cbiAgICByZXR1cm4gTWF0aC5taW4ocmFuZ2VFeHAsIGxvZzEwRmxvb3IobWluKSk7XG59XG4gZnVuY3Rpb24gZ2VuZXJhdGVUaWNrcyhnZW5lcmF0aW9uT3B0aW9ucywgeyBtaW4gLCBtYXggIH0pIHtcbiAgICBtaW4gPSBmaW5pdGVPckRlZmF1bHQoZ2VuZXJhdGlvbk9wdGlvbnMubWluLCBtaW4pO1xuICAgIGNvbnN0IHRpY2tzID0gW107XG4gICAgY29uc3QgbWluRXhwID0gbG9nMTBGbG9vcihtaW4pO1xuICAgIGxldCBleHAgPSBzdGFydEV4cChtaW4sIG1heCk7XG4gICAgbGV0IHByZWNpc2lvbiA9IGV4cCA8IDAgPyBNYXRoLnBvdygxMCwgTWF0aC5hYnMoZXhwKSkgOiAxO1xuICAgIGNvbnN0IHN0ZXBTaXplID0gTWF0aC5wb3coMTAsIGV4cCk7XG4gICAgY29uc3QgYmFzZSA9IG1pbkV4cCA+IGV4cCA/IE1hdGgucG93KDEwLCBtaW5FeHApIDogMDtcbiAgICBjb25zdCBzdGFydCA9IE1hdGgucm91bmQoKG1pbiAtIGJhc2UpICogcHJlY2lzaW9uKSAvIHByZWNpc2lvbjtcbiAgICBjb25zdCBvZmZzZXQgPSBNYXRoLmZsb29yKChtaW4gLSBiYXNlKSAvIHN0ZXBTaXplIC8gMTApICogc3RlcFNpemUgKiAxMDtcbiAgICBsZXQgc2lnbmlmaWNhbmQgPSBNYXRoLmZsb29yKChzdGFydCAtIG9mZnNldCkgLyBNYXRoLnBvdygxMCwgZXhwKSk7XG4gICAgbGV0IHZhbHVlID0gZmluaXRlT3JEZWZhdWx0KGdlbmVyYXRpb25PcHRpb25zLm1pbiwgTWF0aC5yb3VuZCgoYmFzZSArIG9mZnNldCArIHNpZ25pZmljYW5kICogTWF0aC5wb3coMTAsIGV4cCkpICogcHJlY2lzaW9uKSAvIHByZWNpc2lvbik7XG4gICAgd2hpbGUodmFsdWUgPCBtYXgpe1xuICAgICAgICB0aWNrcy5wdXNoKHtcbiAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgbWFqb3I6IGlzTWFqb3IodmFsdWUpLFxuICAgICAgICAgICAgc2lnbmlmaWNhbmRcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChzaWduaWZpY2FuZCA+PSAxMCkge1xuICAgICAgICAgICAgc2lnbmlmaWNhbmQgPSBzaWduaWZpY2FuZCA8IDE1ID8gMTUgOiAyMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNpZ25pZmljYW5kKys7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNpZ25pZmljYW5kID49IDIwKSB7XG4gICAgICAgICAgICBleHArKztcbiAgICAgICAgICAgIHNpZ25pZmljYW5kID0gMjtcbiAgICAgICAgICAgIHByZWNpc2lvbiA9IGV4cCA+PSAwID8gMSA6IHByZWNpc2lvbjtcbiAgICAgICAgfVxuICAgICAgICB2YWx1ZSA9IE1hdGgucm91bmQoKGJhc2UgKyBvZmZzZXQgKyBzaWduaWZpY2FuZCAqIE1hdGgucG93KDEwLCBleHApKSAqIHByZWNpc2lvbikgLyBwcmVjaXNpb247XG4gICAgfVxuICAgIGNvbnN0IGxhc3RUaWNrID0gZmluaXRlT3JEZWZhdWx0KGdlbmVyYXRpb25PcHRpb25zLm1heCwgdmFsdWUpO1xuICAgIHRpY2tzLnB1c2goe1xuICAgICAgICB2YWx1ZTogbGFzdFRpY2ssXG4gICAgICAgIG1ham9yOiBpc01ham9yKGxhc3RUaWNrKSxcbiAgICAgICAgc2lnbmlmaWNhbmRcbiAgICB9KTtcbiAgICByZXR1cm4gdGlja3M7XG59XG5jbGFzcyBMb2dhcml0aG1pY1NjYWxlIGV4dGVuZHMgU2NhbGUge1xuICAgIHN0YXRpYyBpZCA9ICdsb2dhcml0aG1pYyc7XG4gc3RhdGljIGRlZmF1bHRzID0ge1xuICAgICAgICB0aWNrczoge1xuICAgICAgICAgICAgY2FsbGJhY2s6IFRpY2tzLmZvcm1hdHRlcnMubG9nYXJpdGhtaWMsXG4gICAgICAgICAgICBtYWpvcjoge1xuICAgICAgICAgICAgICAgIGVuYWJsZWQ6IHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgY29uc3RydWN0b3IoY2ZnKXtcbiAgICAgICAgc3VwZXIoY2ZnKTtcbiAgICAgICAgIHRoaXMuc3RhcnQgPSB1bmRlZmluZWQ7XG4gICAgICAgICB0aGlzLmVuZCA9IHVuZGVmaW5lZDtcbiAgICAgICAgIHRoaXMuX3N0YXJ0VmFsdWUgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuX3ZhbHVlUmFuZ2UgPSAwO1xuICAgIH1cbiAgICBwYXJzZShyYXcsIGluZGV4KSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gTGluZWFyU2NhbGVCYXNlLnByb3RvdHlwZS5wYXJzZS5hcHBseSh0aGlzLCBbXG4gICAgICAgICAgICByYXcsXG4gICAgICAgICAgICBpbmRleFxuICAgICAgICBdKTtcbiAgICAgICAgaWYgKHZhbHVlID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLl96ZXJvID0gdHJ1ZTtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGlzTnVtYmVyRmluaXRlKHZhbHVlKSAmJiB2YWx1ZSA+IDAgPyB2YWx1ZSA6IG51bGw7XG4gICAgfVxuICAgIGRldGVybWluZURhdGFMaW1pdHMoKSB7XG4gICAgICAgIGNvbnN0IHsgbWluICwgbWF4ICB9ID0gdGhpcy5nZXRNaW5NYXgodHJ1ZSk7XG4gICAgICAgIHRoaXMubWluID0gaXNOdW1iZXJGaW5pdGUobWluKSA/IE1hdGgubWF4KDAsIG1pbikgOiBudWxsO1xuICAgICAgICB0aGlzLm1heCA9IGlzTnVtYmVyRmluaXRlKG1heCkgPyBNYXRoLm1heCgwLCBtYXgpIDogbnVsbDtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5iZWdpbkF0WmVybykge1xuICAgICAgICAgICAgdGhpcy5femVybyA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX3plcm8gJiYgdGhpcy5taW4gIT09IHRoaXMuX3N1Z2dlc3RlZE1pbiAmJiAhaXNOdW1iZXJGaW5pdGUodGhpcy5fdXNlck1pbikpIHtcbiAgICAgICAgICAgIHRoaXMubWluID0gbWluID09PSBjaGFuZ2VFeHBvbmVudCh0aGlzLm1pbiwgMCkgPyBjaGFuZ2VFeHBvbmVudCh0aGlzLm1pbiwgLTEpIDogY2hhbmdlRXhwb25lbnQodGhpcy5taW4sIDApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaGFuZGxlVGlja1JhbmdlT3B0aW9ucygpO1xuICAgIH1cbiAgICBoYW5kbGVUaWNrUmFuZ2VPcHRpb25zKCkge1xuICAgICAgICBjb25zdCB7IG1pbkRlZmluZWQgLCBtYXhEZWZpbmVkICB9ID0gdGhpcy5nZXRVc2VyQm91bmRzKCk7XG4gICAgICAgIGxldCBtaW4gPSB0aGlzLm1pbjtcbiAgICAgICAgbGV0IG1heCA9IHRoaXMubWF4O1xuICAgICAgICBjb25zdCBzZXRNaW4gPSAodik9Pm1pbiA9IG1pbkRlZmluZWQgPyBtaW4gOiB2O1xuICAgICAgICBjb25zdCBzZXRNYXggPSAodik9Pm1heCA9IG1heERlZmluZWQgPyBtYXggOiB2O1xuICAgICAgICBpZiAobWluID09PSBtYXgpIHtcbiAgICAgICAgICAgIGlmIChtaW4gPD0gMCkge1xuICAgICAgICAgICAgICAgIHNldE1pbigxKTtcbiAgICAgICAgICAgICAgICBzZXRNYXgoMTApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXRNaW4oY2hhbmdlRXhwb25lbnQobWluLCAtMSkpO1xuICAgICAgICAgICAgICAgIHNldE1heChjaGFuZ2VFeHBvbmVudChtYXgsICsxKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1pbiA8PSAwKSB7XG4gICAgICAgICAgICBzZXRNaW4oY2hhbmdlRXhwb25lbnQobWF4LCAtMSkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtYXggPD0gMCkge1xuICAgICAgICAgICAgc2V0TWF4KGNoYW5nZUV4cG9uZW50KG1pbiwgKzEpKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm1pbiA9IG1pbjtcbiAgICAgICAgdGhpcy5tYXggPSBtYXg7XG4gICAgfVxuICAgIGJ1aWxkVGlja3MoKSB7XG4gICAgICAgIGNvbnN0IG9wdHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGNvbnN0IGdlbmVyYXRpb25PcHRpb25zID0ge1xuICAgICAgICAgICAgbWluOiB0aGlzLl91c2VyTWluLFxuICAgICAgICAgICAgbWF4OiB0aGlzLl91c2VyTWF4XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHRpY2tzID0gZ2VuZXJhdGVUaWNrcyhnZW5lcmF0aW9uT3B0aW9ucywgdGhpcyk7XG4gICAgICAgIGlmIChvcHRzLmJvdW5kcyA9PT0gJ3RpY2tzJykge1xuICAgICAgICAgICAgX3NldE1pbkFuZE1heEJ5S2V5KHRpY2tzLCB0aGlzLCAndmFsdWUnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0cy5yZXZlcnNlKSB7XG4gICAgICAgICAgICB0aWNrcy5yZXZlcnNlKCk7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0ID0gdGhpcy5tYXg7XG4gICAgICAgICAgICB0aGlzLmVuZCA9IHRoaXMubWluO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zdGFydCA9IHRoaXMubWluO1xuICAgICAgICAgICAgdGhpcy5lbmQgPSB0aGlzLm1heDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGlja3M7XG4gICAgfVxuIGdldExhYmVsRm9yVmFsdWUodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQgPyAnMCcgOiBmb3JtYXROdW1iZXIodmFsdWUsIHRoaXMuY2hhcnQub3B0aW9ucy5sb2NhbGUsIHRoaXMub3B0aW9ucy50aWNrcy5mb3JtYXQpO1xuICAgIH1cbiBjb25maWd1cmUoKSB7XG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5taW47XG4gICAgICAgIHN1cGVyLmNvbmZpZ3VyZSgpO1xuICAgICAgICB0aGlzLl9zdGFydFZhbHVlID0gbG9nMTAoc3RhcnQpO1xuICAgICAgICB0aGlzLl92YWx1ZVJhbmdlID0gbG9nMTAodGhpcy5tYXgpIC0gbG9nMTAoc3RhcnQpO1xuICAgIH1cbiAgICBnZXRQaXhlbEZvclZhbHVlKHZhbHVlKSB7XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSAwKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHRoaXMubWluO1xuICAgICAgICB9XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCBpc05hTih2YWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBOYU47XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGl4ZWxGb3JEZWNpbWFsKHZhbHVlID09PSB0aGlzLm1pbiA/IDAgOiAobG9nMTAodmFsdWUpIC0gdGhpcy5fc3RhcnRWYWx1ZSkgLyB0aGlzLl92YWx1ZVJhbmdlKTtcbiAgICB9XG4gICAgZ2V0VmFsdWVGb3JQaXhlbChwaXhlbCkge1xuICAgICAgICBjb25zdCBkZWNpbWFsID0gdGhpcy5nZXREZWNpbWFsRm9yUGl4ZWwocGl4ZWwpO1xuICAgICAgICByZXR1cm4gTWF0aC5wb3coMTAsIHRoaXMuX3N0YXJ0VmFsdWUgKyBkZWNpbWFsICogdGhpcy5fdmFsdWVSYW5nZSk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBnZXRUaWNrQmFja2Ryb3BIZWlnaHQob3B0cykge1xuICAgIGNvbnN0IHRpY2tPcHRzID0gb3B0cy50aWNrcztcbiAgICBpZiAodGlja09wdHMuZGlzcGxheSAmJiBvcHRzLmRpc3BsYXkpIHtcbiAgICAgICAgY29uc3QgcGFkZGluZyA9IHRvUGFkZGluZyh0aWNrT3B0cy5iYWNrZHJvcFBhZGRpbmcpO1xuICAgICAgICByZXR1cm4gdmFsdWVPckRlZmF1bHQodGlja09wdHMuZm9udCAmJiB0aWNrT3B0cy5mb250LnNpemUsIGRlZmF1bHRzLmZvbnQuc2l6ZSkgKyBwYWRkaW5nLmhlaWdodDtcbiAgICB9XG4gICAgcmV0dXJuIDA7XG59XG5mdW5jdGlvbiBtZWFzdXJlTGFiZWxTaXplKGN0eCwgZm9udCwgbGFiZWwpIHtcbiAgICBsYWJlbCA9IGlzQXJyYXkobGFiZWwpID8gbGFiZWwgOiBbXG4gICAgICAgIGxhYmVsXG4gICAgXTtcbiAgICByZXR1cm4ge1xuICAgICAgICB3OiBfbG9uZ2VzdFRleHQoY3R4LCBmb250LnN0cmluZywgbGFiZWwpLFxuICAgICAgICBoOiBsYWJlbC5sZW5ndGggKiBmb250LmxpbmVIZWlnaHRcbiAgICB9O1xufVxuZnVuY3Rpb24gZGV0ZXJtaW5lTGltaXRzKGFuZ2xlLCBwb3MsIHNpemUsIG1pbiwgbWF4KSB7XG4gICAgaWYgKGFuZ2xlID09PSBtaW4gfHwgYW5nbGUgPT09IG1heCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3RhcnQ6IHBvcyAtIHNpemUgLyAyLFxuICAgICAgICAgICAgZW5kOiBwb3MgKyBzaXplIC8gMlxuICAgICAgICB9O1xuICAgIH0gZWxzZSBpZiAoYW5nbGUgPCBtaW4gfHwgYW5nbGUgPiBtYXgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXJ0OiBwb3MgLSBzaXplLFxuICAgICAgICAgICAgZW5kOiBwb3NcbiAgICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgc3RhcnQ6IHBvcyxcbiAgICAgICAgZW5kOiBwb3MgKyBzaXplXG4gICAgfTtcbn1cbiBmdW5jdGlvbiBmaXRXaXRoUG9pbnRMYWJlbHMoc2NhbGUpIHtcbiAgICBjb25zdCBvcmlnID0ge1xuICAgICAgICBsOiBzY2FsZS5sZWZ0ICsgc2NhbGUuX3BhZGRpbmcubGVmdCxcbiAgICAgICAgcjogc2NhbGUucmlnaHQgLSBzY2FsZS5fcGFkZGluZy5yaWdodCxcbiAgICAgICAgdDogc2NhbGUudG9wICsgc2NhbGUuX3BhZGRpbmcudG9wLFxuICAgICAgICBiOiBzY2FsZS5ib3R0b20gLSBzY2FsZS5fcGFkZGluZy5ib3R0b21cbiAgICB9O1xuICAgIGNvbnN0IGxpbWl0cyA9IE9iamVjdC5hc3NpZ24oe30sIG9yaWcpO1xuICAgIGNvbnN0IGxhYmVsU2l6ZXMgPSBbXTtcbiAgICBjb25zdCBwYWRkaW5nID0gW107XG4gICAgY29uc3QgdmFsdWVDb3VudCA9IHNjYWxlLl9wb2ludExhYmVscy5sZW5ndGg7XG4gICAgY29uc3QgcG9pbnRMYWJlbE9wdHMgPSBzY2FsZS5vcHRpb25zLnBvaW50TGFiZWxzO1xuICAgIGNvbnN0IGFkZGl0aW9uYWxBbmdsZSA9IHBvaW50TGFiZWxPcHRzLmNlbnRlclBvaW50TGFiZWxzID8gUEkgLyB2YWx1ZUNvdW50IDogMDtcbiAgICBmb3IobGV0IGkgPSAwOyBpIDwgdmFsdWVDb3VudDsgaSsrKXtcbiAgICAgICAgY29uc3Qgb3B0cyA9IHBvaW50TGFiZWxPcHRzLnNldENvbnRleHQoc2NhbGUuZ2V0UG9pbnRMYWJlbENvbnRleHQoaSkpO1xuICAgICAgICBwYWRkaW5nW2ldID0gb3B0cy5wYWRkaW5nO1xuICAgICAgICBjb25zdCBwb2ludFBvc2l0aW9uID0gc2NhbGUuZ2V0UG9pbnRQb3NpdGlvbihpLCBzY2FsZS5kcmF3aW5nQXJlYSArIHBhZGRpbmdbaV0sIGFkZGl0aW9uYWxBbmdsZSk7XG4gICAgICAgIGNvbnN0IHBsRm9udCA9IHRvRm9udChvcHRzLmZvbnQpO1xuICAgICAgICBjb25zdCB0ZXh0U2l6ZSA9IG1lYXN1cmVMYWJlbFNpemUoc2NhbGUuY3R4LCBwbEZvbnQsIHNjYWxlLl9wb2ludExhYmVsc1tpXSk7XG4gICAgICAgIGxhYmVsU2l6ZXNbaV0gPSB0ZXh0U2l6ZTtcbiAgICAgICAgY29uc3QgYW5nbGVSYWRpYW5zID0gX25vcm1hbGl6ZUFuZ2xlKHNjYWxlLmdldEluZGV4QW5nbGUoaSkgKyBhZGRpdGlvbmFsQW5nbGUpO1xuICAgICAgICBjb25zdCBhbmdsZSA9IE1hdGgucm91bmQodG9EZWdyZWVzKGFuZ2xlUmFkaWFucykpO1xuICAgICAgICBjb25zdCBoTGltaXRzID0gZGV0ZXJtaW5lTGltaXRzKGFuZ2xlLCBwb2ludFBvc2l0aW9uLngsIHRleHRTaXplLncsIDAsIDE4MCk7XG4gICAgICAgIGNvbnN0IHZMaW1pdHMgPSBkZXRlcm1pbmVMaW1pdHMoYW5nbGUsIHBvaW50UG9zaXRpb24ueSwgdGV4dFNpemUuaCwgOTAsIDI3MCk7XG4gICAgICAgIHVwZGF0ZUxpbWl0cyhsaW1pdHMsIG9yaWcsIGFuZ2xlUmFkaWFucywgaExpbWl0cywgdkxpbWl0cyk7XG4gICAgfVxuICAgIHNjYWxlLnNldENlbnRlclBvaW50KG9yaWcubCAtIGxpbWl0cy5sLCBsaW1pdHMuciAtIG9yaWcuciwgb3JpZy50IC0gbGltaXRzLnQsIGxpbWl0cy5iIC0gb3JpZy5iKTtcbiAgICBzY2FsZS5fcG9pbnRMYWJlbEl0ZW1zID0gYnVpbGRQb2ludExhYmVsSXRlbXMoc2NhbGUsIGxhYmVsU2l6ZXMsIHBhZGRpbmcpO1xufVxuZnVuY3Rpb24gdXBkYXRlTGltaXRzKGxpbWl0cywgb3JpZywgYW5nbGUsIGhMaW1pdHMsIHZMaW1pdHMpIHtcbiAgICBjb25zdCBzaW4gPSBNYXRoLmFicyhNYXRoLnNpbihhbmdsZSkpO1xuICAgIGNvbnN0IGNvcyA9IE1hdGguYWJzKE1hdGguY29zKGFuZ2xlKSk7XG4gICAgbGV0IHggPSAwO1xuICAgIGxldCB5ID0gMDtcbiAgICBpZiAoaExpbWl0cy5zdGFydCA8IG9yaWcubCkge1xuICAgICAgICB4ID0gKG9yaWcubCAtIGhMaW1pdHMuc3RhcnQpIC8gc2luO1xuICAgICAgICBsaW1pdHMubCA9IE1hdGgubWluKGxpbWl0cy5sLCBvcmlnLmwgLSB4KTtcbiAgICB9IGVsc2UgaWYgKGhMaW1pdHMuZW5kID4gb3JpZy5yKSB7XG4gICAgICAgIHggPSAoaExpbWl0cy5lbmQgLSBvcmlnLnIpIC8gc2luO1xuICAgICAgICBsaW1pdHMuciA9IE1hdGgubWF4KGxpbWl0cy5yLCBvcmlnLnIgKyB4KTtcbiAgICB9XG4gICAgaWYgKHZMaW1pdHMuc3RhcnQgPCBvcmlnLnQpIHtcbiAgICAgICAgeSA9IChvcmlnLnQgLSB2TGltaXRzLnN0YXJ0KSAvIGNvcztcbiAgICAgICAgbGltaXRzLnQgPSBNYXRoLm1pbihsaW1pdHMudCwgb3JpZy50IC0geSk7XG4gICAgfSBlbHNlIGlmICh2TGltaXRzLmVuZCA+IG9yaWcuYikge1xuICAgICAgICB5ID0gKHZMaW1pdHMuZW5kIC0gb3JpZy5iKSAvIGNvcztcbiAgICAgICAgbGltaXRzLmIgPSBNYXRoLm1heChsaW1pdHMuYiwgb3JpZy5iICsgeSk7XG4gICAgfVxufVxuZnVuY3Rpb24gY3JlYXRlUG9pbnRMYWJlbEl0ZW0oc2NhbGUsIGluZGV4LCBpdGVtT3B0cykge1xuICAgIGNvbnN0IG91dGVyRGlzdGFuY2UgPSBzY2FsZS5kcmF3aW5nQXJlYTtcbiAgICBjb25zdCB7IGV4dHJhICwgYWRkaXRpb25hbEFuZ2xlICwgcGFkZGluZyAsIHNpemUgIH0gPSBpdGVtT3B0cztcbiAgICBjb25zdCBwb2ludExhYmVsUG9zaXRpb24gPSBzY2FsZS5nZXRQb2ludFBvc2l0aW9uKGluZGV4LCBvdXRlckRpc3RhbmNlICsgZXh0cmEgKyBwYWRkaW5nLCBhZGRpdGlvbmFsQW5nbGUpO1xuICAgIGNvbnN0IGFuZ2xlID0gTWF0aC5yb3VuZCh0b0RlZ3JlZXMoX25vcm1hbGl6ZUFuZ2xlKHBvaW50TGFiZWxQb3NpdGlvbi5hbmdsZSArIEhBTEZfUEkpKSk7XG4gICAgY29uc3QgeSA9IHlGb3JBbmdsZShwb2ludExhYmVsUG9zaXRpb24ueSwgc2l6ZS5oLCBhbmdsZSk7XG4gICAgY29uc3QgdGV4dEFsaWduID0gZ2V0VGV4dEFsaWduRm9yQW5nbGUoYW5nbGUpO1xuICAgIGNvbnN0IGxlZnQgPSBsZWZ0Rm9yVGV4dEFsaWduKHBvaW50TGFiZWxQb3NpdGlvbi54LCBzaXplLncsIHRleHRBbGlnbik7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgeDogcG9pbnRMYWJlbFBvc2l0aW9uLngsXG4gICAgICAgIHksXG4gICAgICAgIHRleHRBbGlnbixcbiAgICAgICAgbGVmdCxcbiAgICAgICAgdG9wOiB5LFxuICAgICAgICByaWdodDogbGVmdCArIHNpemUudyxcbiAgICAgICAgYm90dG9tOiB5ICsgc2l6ZS5oXG4gICAgfTtcbn1cbmZ1bmN0aW9uIGlzTm90T3ZlcmxhcHBlZChpdGVtLCBhcmVhKSB7XG4gICAgaWYgKCFhcmVhKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjb25zdCB7IGxlZnQgLCB0b3AgLCByaWdodCAsIGJvdHRvbSAgfSA9IGl0ZW07XG4gICAgY29uc3QgYXBleGVzSW5BcmVhID0gX2lzUG9pbnRJbkFyZWEoe1xuICAgICAgICB4OiBsZWZ0LFxuICAgICAgICB5OiB0b3BcbiAgICB9LCBhcmVhKSB8fCBfaXNQb2ludEluQXJlYSh7XG4gICAgICAgIHg6IGxlZnQsXG4gICAgICAgIHk6IGJvdHRvbVxuICAgIH0sIGFyZWEpIHx8IF9pc1BvaW50SW5BcmVhKHtcbiAgICAgICAgeDogcmlnaHQsXG4gICAgICAgIHk6IHRvcFxuICAgIH0sIGFyZWEpIHx8IF9pc1BvaW50SW5BcmVhKHtcbiAgICAgICAgeDogcmlnaHQsXG4gICAgICAgIHk6IGJvdHRvbVxuICAgIH0sIGFyZWEpO1xuICAgIHJldHVybiAhYXBleGVzSW5BcmVhO1xufVxuZnVuY3Rpb24gYnVpbGRQb2ludExhYmVsSXRlbXMoc2NhbGUsIGxhYmVsU2l6ZXMsIHBhZGRpbmcpIHtcbiAgICBjb25zdCBpdGVtcyA9IFtdO1xuICAgIGNvbnN0IHZhbHVlQ291bnQgPSBzY2FsZS5fcG9pbnRMYWJlbHMubGVuZ3RoO1xuICAgIGNvbnN0IG9wdHMgPSBzY2FsZS5vcHRpb25zO1xuICAgIGNvbnN0IHsgY2VudGVyUG9pbnRMYWJlbHMgLCBkaXNwbGF5ICB9ID0gb3B0cy5wb2ludExhYmVscztcbiAgICBjb25zdCBpdGVtT3B0cyA9IHtcbiAgICAgICAgZXh0cmE6IGdldFRpY2tCYWNrZHJvcEhlaWdodChvcHRzKSAvIDIsXG4gICAgICAgIGFkZGl0aW9uYWxBbmdsZTogY2VudGVyUG9pbnRMYWJlbHMgPyBQSSAvIHZhbHVlQ291bnQgOiAwXG4gICAgfTtcbiAgICBsZXQgYXJlYTtcbiAgICBmb3IobGV0IGkgPSAwOyBpIDwgdmFsdWVDb3VudDsgaSsrKXtcbiAgICAgICAgaXRlbU9wdHMucGFkZGluZyA9IHBhZGRpbmdbaV07XG4gICAgICAgIGl0ZW1PcHRzLnNpemUgPSBsYWJlbFNpemVzW2ldO1xuICAgICAgICBjb25zdCBpdGVtID0gY3JlYXRlUG9pbnRMYWJlbEl0ZW0oc2NhbGUsIGksIGl0ZW1PcHRzKTtcbiAgICAgICAgaXRlbXMucHVzaChpdGVtKTtcbiAgICAgICAgaWYgKGRpc3BsYXkgPT09ICdhdXRvJykge1xuICAgICAgICAgICAgaXRlbS52aXNpYmxlID0gaXNOb3RPdmVybGFwcGVkKGl0ZW0sIGFyZWEpO1xuICAgICAgICAgICAgaWYgKGl0ZW0udmlzaWJsZSkge1xuICAgICAgICAgICAgICAgIGFyZWEgPSBpdGVtO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBpdGVtcztcbn1cbmZ1bmN0aW9uIGdldFRleHRBbGlnbkZvckFuZ2xlKGFuZ2xlKSB7XG4gICAgaWYgKGFuZ2xlID09PSAwIHx8IGFuZ2xlID09PSAxODApIHtcbiAgICAgICAgcmV0dXJuICdjZW50ZXInO1xuICAgIH0gZWxzZSBpZiAoYW5nbGUgPCAxODApIHtcbiAgICAgICAgcmV0dXJuICdsZWZ0JztcbiAgICB9XG4gICAgcmV0dXJuICdyaWdodCc7XG59XG5mdW5jdGlvbiBsZWZ0Rm9yVGV4dEFsaWduKHgsIHcsIGFsaWduKSB7XG4gICAgaWYgKGFsaWduID09PSAncmlnaHQnKSB7XG4gICAgICAgIHggLT0gdztcbiAgICB9IGVsc2UgaWYgKGFsaWduID09PSAnY2VudGVyJykge1xuICAgICAgICB4IC09IHcgLyAyO1xuICAgIH1cbiAgICByZXR1cm4geDtcbn1cbmZ1bmN0aW9uIHlGb3JBbmdsZSh5LCBoLCBhbmdsZSkge1xuICAgIGlmIChhbmdsZSA9PT0gOTAgfHwgYW5nbGUgPT09IDI3MCkge1xuICAgICAgICB5IC09IGggLyAyO1xuICAgIH0gZWxzZSBpZiAoYW5nbGUgPiAyNzAgfHwgYW5nbGUgPCA5MCkge1xuICAgICAgICB5IC09IGg7XG4gICAgfVxuICAgIHJldHVybiB5O1xufVxuZnVuY3Rpb24gZHJhd1BvaW50TGFiZWxCb3goY3R4LCBvcHRzLCBpdGVtKSB7XG4gICAgY29uc3QgeyBsZWZ0ICwgdG9wICwgcmlnaHQgLCBib3R0b20gIH0gPSBpdGVtO1xuICAgIGNvbnN0IHsgYmFja2Ryb3BDb2xvciAgfSA9IG9wdHM7XG4gICAgaWYgKCFpc051bGxPclVuZGVmKGJhY2tkcm9wQ29sb3IpKSB7XG4gICAgICAgIGNvbnN0IGJvcmRlclJhZGl1cyA9IHRvVFJCTENvcm5lcnMob3B0cy5ib3JkZXJSYWRpdXMpO1xuICAgICAgICBjb25zdCBwYWRkaW5nID0gdG9QYWRkaW5nKG9wdHMuYmFja2Ryb3BQYWRkaW5nKTtcbiAgICAgICAgY3R4LmZpbGxTdHlsZSA9IGJhY2tkcm9wQ29sb3I7XG4gICAgICAgIGNvbnN0IGJhY2tkcm9wTGVmdCA9IGxlZnQgLSBwYWRkaW5nLmxlZnQ7XG4gICAgICAgIGNvbnN0IGJhY2tkcm9wVG9wID0gdG9wIC0gcGFkZGluZy50b3A7XG4gICAgICAgIGNvbnN0IGJhY2tkcm9wV2lkdGggPSByaWdodCAtIGxlZnQgKyBwYWRkaW5nLndpZHRoO1xuICAgICAgICBjb25zdCBiYWNrZHJvcEhlaWdodCA9IGJvdHRvbSAtIHRvcCArIHBhZGRpbmcuaGVpZ2h0O1xuICAgICAgICBpZiAoT2JqZWN0LnZhbHVlcyhib3JkZXJSYWRpdXMpLnNvbWUoKHYpPT52ICE9PSAwKSkge1xuICAgICAgICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgICAgICAgYWRkUm91bmRlZFJlY3RQYXRoKGN0eCwge1xuICAgICAgICAgICAgICAgIHg6IGJhY2tkcm9wTGVmdCxcbiAgICAgICAgICAgICAgICB5OiBiYWNrZHJvcFRvcCxcbiAgICAgICAgICAgICAgICB3OiBiYWNrZHJvcFdpZHRoLFxuICAgICAgICAgICAgICAgIGg6IGJhY2tkcm9wSGVpZ2h0LFxuICAgICAgICAgICAgICAgIHJhZGl1czogYm9yZGVyUmFkaXVzXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGN0eC5maWxsKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjdHguZmlsbFJlY3QoYmFja2Ryb3BMZWZ0LCBiYWNrZHJvcFRvcCwgYmFja2Ryb3BXaWR0aCwgYmFja2Ryb3BIZWlnaHQpO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gZHJhd1BvaW50TGFiZWxzKHNjYWxlLCBsYWJlbENvdW50KSB7XG4gICAgY29uc3QgeyBjdHggLCBvcHRpb25zOiB7IHBvaW50TGFiZWxzICB9ICB9ID0gc2NhbGU7XG4gICAgZm9yKGxldCBpID0gbGFiZWxDb3VudCAtIDE7IGkgPj0gMDsgaS0tKXtcbiAgICAgICAgY29uc3QgaXRlbSA9IHNjYWxlLl9wb2ludExhYmVsSXRlbXNbaV07XG4gICAgICAgIGlmICghaXRlbS52aXNpYmxlKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvcHRzQXRJbmRleCA9IHBvaW50TGFiZWxzLnNldENvbnRleHQoc2NhbGUuZ2V0UG9pbnRMYWJlbENvbnRleHQoaSkpO1xuICAgICAgICBkcmF3UG9pbnRMYWJlbEJveChjdHgsIG9wdHNBdEluZGV4LCBpdGVtKTtcbiAgICAgICAgY29uc3QgcGxGb250ID0gdG9Gb250KG9wdHNBdEluZGV4LmZvbnQpO1xuICAgICAgICBjb25zdCB7IHggLCB5ICwgdGV4dEFsaWduICB9ID0gaXRlbTtcbiAgICAgICAgcmVuZGVyVGV4dChjdHgsIHNjYWxlLl9wb2ludExhYmVsc1tpXSwgeCwgeSArIHBsRm9udC5saW5lSGVpZ2h0IC8gMiwgcGxGb250LCB7XG4gICAgICAgICAgICBjb2xvcjogb3B0c0F0SW5kZXguY29sb3IsXG4gICAgICAgICAgICB0ZXh0QWxpZ246IHRleHRBbGlnbixcbiAgICAgICAgICAgIHRleHRCYXNlbGluZTogJ21pZGRsZSdcbiAgICAgICAgfSk7XG4gICAgfVxufVxuZnVuY3Rpb24gcGF0aFJhZGl1c0xpbmUoc2NhbGUsIHJhZGl1cywgY2lyY3VsYXIsIGxhYmVsQ291bnQpIHtcbiAgICBjb25zdCB7IGN0eCAgfSA9IHNjYWxlO1xuICAgIGlmIChjaXJjdWxhcikge1xuICAgICAgICBjdHguYXJjKHNjYWxlLnhDZW50ZXIsIHNjYWxlLnlDZW50ZXIsIHJhZGl1cywgMCwgVEFVKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBsZXQgcG9pbnRQb3NpdGlvbiA9IHNjYWxlLmdldFBvaW50UG9zaXRpb24oMCwgcmFkaXVzKTtcbiAgICAgICAgY3R4Lm1vdmVUbyhwb2ludFBvc2l0aW9uLngsIHBvaW50UG9zaXRpb24ueSk7XG4gICAgICAgIGZvcihsZXQgaSA9IDE7IGkgPCBsYWJlbENvdW50OyBpKyspe1xuICAgICAgICAgICAgcG9pbnRQb3NpdGlvbiA9IHNjYWxlLmdldFBvaW50UG9zaXRpb24oaSwgcmFkaXVzKTtcbiAgICAgICAgICAgIGN0eC5saW5lVG8ocG9pbnRQb3NpdGlvbi54LCBwb2ludFBvc2l0aW9uLnkpO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gZHJhd1JhZGl1c0xpbmUoc2NhbGUsIGdyaWRMaW5lT3B0cywgcmFkaXVzLCBsYWJlbENvdW50LCBib3JkZXJPcHRzKSB7XG4gICAgY29uc3QgY3R4ID0gc2NhbGUuY3R4O1xuICAgIGNvbnN0IGNpcmN1bGFyID0gZ3JpZExpbmVPcHRzLmNpcmN1bGFyO1xuICAgIGNvbnN0IHsgY29sb3IgLCBsaW5lV2lkdGggIH0gPSBncmlkTGluZU9wdHM7XG4gICAgaWYgKCFjaXJjdWxhciAmJiAhbGFiZWxDb3VudCB8fCAhY29sb3IgfHwgIWxpbmVXaWR0aCB8fCByYWRpdXMgPCAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY3R4LnNhdmUoKTtcbiAgICBjdHguc3Ryb2tlU3R5bGUgPSBjb2xvcjtcbiAgICBjdHgubGluZVdpZHRoID0gbGluZVdpZHRoO1xuICAgIGN0eC5zZXRMaW5lRGFzaChib3JkZXJPcHRzLmRhc2gpO1xuICAgIGN0eC5saW5lRGFzaE9mZnNldCA9IGJvcmRlck9wdHMuZGFzaE9mZnNldDtcbiAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgcGF0aFJhZGl1c0xpbmUoc2NhbGUsIHJhZGl1cywgY2lyY3VsYXIsIGxhYmVsQ291bnQpO1xuICAgIGN0eC5jbG9zZVBhdGgoKTtcbiAgICBjdHguc3Ryb2tlKCk7XG4gICAgY3R4LnJlc3RvcmUoKTtcbn1cbmZ1bmN0aW9uIGNyZWF0ZVBvaW50TGFiZWxDb250ZXh0KHBhcmVudCwgaW5kZXgsIGxhYmVsKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUNvbnRleHQocGFyZW50LCB7XG4gICAgICAgIGxhYmVsLFxuICAgICAgICBpbmRleCxcbiAgICAgICAgdHlwZTogJ3BvaW50TGFiZWwnXG4gICAgfSk7XG59XG5jbGFzcyBSYWRpYWxMaW5lYXJTY2FsZSBleHRlbmRzIExpbmVhclNjYWxlQmFzZSB7XG4gICAgc3RhdGljIGlkID0gJ3JhZGlhbExpbmVhcic7XG4gc3RhdGljIGRlZmF1bHRzID0ge1xuICAgICAgICBkaXNwbGF5OiB0cnVlLFxuICAgICAgICBhbmltYXRlOiB0cnVlLFxuICAgICAgICBwb3NpdGlvbjogJ2NoYXJ0QXJlYScsXG4gICAgICAgIGFuZ2xlTGluZXM6IHtcbiAgICAgICAgICAgIGRpc3BsYXk6IHRydWUsXG4gICAgICAgICAgICBsaW5lV2lkdGg6IDEsXG4gICAgICAgICAgICBib3JkZXJEYXNoOiBbXSxcbiAgICAgICAgICAgIGJvcmRlckRhc2hPZmZzZXQ6IDAuMFxuICAgICAgICB9LFxuICAgICAgICBncmlkOiB7XG4gICAgICAgICAgICBjaXJjdWxhcjogZmFsc2VcbiAgICAgICAgfSxcbiAgICAgICAgc3RhcnRBbmdsZTogMCxcbiAgICAgICAgdGlja3M6IHtcbiAgICAgICAgICAgIHNob3dMYWJlbEJhY2tkcm9wOiB0cnVlLFxuICAgICAgICAgICAgY2FsbGJhY2s6IFRpY2tzLmZvcm1hdHRlcnMubnVtZXJpY1xuICAgICAgICB9LFxuICAgICAgICBwb2ludExhYmVsczoge1xuICAgICAgICAgICAgYmFja2Ryb3BDb2xvcjogdW5kZWZpbmVkLFxuICAgICAgICAgICAgYmFja2Ryb3BQYWRkaW5nOiAyLFxuICAgICAgICAgICAgZGlzcGxheTogdHJ1ZSxcbiAgICAgICAgICAgIGZvbnQ6IHtcbiAgICAgICAgICAgICAgICBzaXplOiAxMFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNhbGxiYWNrIChsYWJlbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBsYWJlbDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwYWRkaW5nOiA1LFxuICAgICAgICAgICAgY2VudGVyUG9pbnRMYWJlbHM6IGZhbHNlXG4gICAgICAgIH1cbiAgICB9O1xuICAgIHN0YXRpYyBkZWZhdWx0Um91dGVzID0ge1xuICAgICAgICAnYW5nbGVMaW5lcy5jb2xvcic6ICdib3JkZXJDb2xvcicsXG4gICAgICAgICdwb2ludExhYmVscy5jb2xvcic6ICdjb2xvcicsXG4gICAgICAgICd0aWNrcy5jb2xvcic6ICdjb2xvcidcbiAgICB9O1xuICAgIHN0YXRpYyBkZXNjcmlwdG9ycyA9IHtcbiAgICAgICAgYW5nbGVMaW5lczoge1xuICAgICAgICAgICAgX2ZhbGxiYWNrOiAnZ3JpZCdcbiAgICAgICAgfVxuICAgIH07XG4gICAgY29uc3RydWN0b3IoY2ZnKXtcbiAgICAgICAgc3VwZXIoY2ZnKTtcbiAgICAgICAgIHRoaXMueENlbnRlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgIHRoaXMueUNlbnRlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgIHRoaXMuZHJhd2luZ0FyZWEgPSB1bmRlZmluZWQ7XG4gICAgICAgICB0aGlzLl9wb2ludExhYmVscyA9IFtdO1xuICAgICAgICB0aGlzLl9wb2ludExhYmVsSXRlbXMgPSBbXTtcbiAgICB9XG4gICAgc2V0RGltZW5zaW9ucygpIHtcbiAgICAgICAgY29uc3QgcGFkZGluZyA9IHRoaXMuX3BhZGRpbmcgPSB0b1BhZGRpbmcoZ2V0VGlja0JhY2tkcm9wSGVpZ2h0KHRoaXMub3B0aW9ucykgLyAyKTtcbiAgICAgICAgY29uc3QgdyA9IHRoaXMud2lkdGggPSB0aGlzLm1heFdpZHRoIC0gcGFkZGluZy53aWR0aDtcbiAgICAgICAgY29uc3QgaCA9IHRoaXMuaGVpZ2h0ID0gdGhpcy5tYXhIZWlnaHQgLSBwYWRkaW5nLmhlaWdodDtcbiAgICAgICAgdGhpcy54Q2VudGVyID0gTWF0aC5mbG9vcih0aGlzLmxlZnQgKyB3IC8gMiArIHBhZGRpbmcubGVmdCk7XG4gICAgICAgIHRoaXMueUNlbnRlciA9IE1hdGguZmxvb3IodGhpcy50b3AgKyBoIC8gMiArIHBhZGRpbmcudG9wKTtcbiAgICAgICAgdGhpcy5kcmF3aW5nQXJlYSA9IE1hdGguZmxvb3IoTWF0aC5taW4odywgaCkgLyAyKTtcbiAgICB9XG4gICAgZGV0ZXJtaW5lRGF0YUxpbWl0cygpIHtcbiAgICAgICAgY29uc3QgeyBtaW4gLCBtYXggIH0gPSB0aGlzLmdldE1pbk1heChmYWxzZSk7XG4gICAgICAgIHRoaXMubWluID0gaXNOdW1iZXJGaW5pdGUobWluKSAmJiAhaXNOYU4obWluKSA/IG1pbiA6IDA7XG4gICAgICAgIHRoaXMubWF4ID0gaXNOdW1iZXJGaW5pdGUobWF4KSAmJiAhaXNOYU4obWF4KSA/IG1heCA6IDA7XG4gICAgICAgIHRoaXMuaGFuZGxlVGlja1JhbmdlT3B0aW9ucygpO1xuICAgIH1cbiBjb21wdXRlVGlja0xpbWl0KCkge1xuICAgICAgICByZXR1cm4gTWF0aC5jZWlsKHRoaXMuZHJhd2luZ0FyZWEgLyBnZXRUaWNrQmFja2Ryb3BIZWlnaHQodGhpcy5vcHRpb25zKSk7XG4gICAgfVxuICAgIGdlbmVyYXRlVGlja0xhYmVscyh0aWNrcykge1xuICAgICAgICBMaW5lYXJTY2FsZUJhc2UucHJvdG90eXBlLmdlbmVyYXRlVGlja0xhYmVscy5jYWxsKHRoaXMsIHRpY2tzKTtcbiAgICAgICAgdGhpcy5fcG9pbnRMYWJlbHMgPSB0aGlzLmdldExhYmVscygpLm1hcCgodmFsdWUsIGluZGV4KT0+e1xuICAgICAgICAgICAgY29uc3QgbGFiZWwgPSBjYWxsYmFjayh0aGlzLm9wdGlvbnMucG9pbnRMYWJlbHMuY2FsbGJhY2ssIFtcbiAgICAgICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgXSwgdGhpcyk7XG4gICAgICAgICAgICByZXR1cm4gbGFiZWwgfHwgbGFiZWwgPT09IDAgPyBsYWJlbCA6ICcnO1xuICAgICAgICB9KS5maWx0ZXIoKHYsIGkpPT50aGlzLmNoYXJ0LmdldERhdGFWaXNpYmlsaXR5KGkpKTtcbiAgICB9XG4gICAgZml0KCkge1xuICAgICAgICBjb25zdCBvcHRzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBpZiAob3B0cy5kaXNwbGF5ICYmIG9wdHMucG9pbnRMYWJlbHMuZGlzcGxheSkge1xuICAgICAgICAgICAgZml0V2l0aFBvaW50TGFiZWxzKHRoaXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXRDZW50ZXJQb2ludCgwLCAwLCAwLCAwKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzZXRDZW50ZXJQb2ludChsZWZ0TW92ZW1lbnQsIHJpZ2h0TW92ZW1lbnQsIHRvcE1vdmVtZW50LCBib3R0b21Nb3ZlbWVudCkge1xuICAgICAgICB0aGlzLnhDZW50ZXIgKz0gTWF0aC5mbG9vcigobGVmdE1vdmVtZW50IC0gcmlnaHRNb3ZlbWVudCkgLyAyKTtcbiAgICAgICAgdGhpcy55Q2VudGVyICs9IE1hdGguZmxvb3IoKHRvcE1vdmVtZW50IC0gYm90dG9tTW92ZW1lbnQpIC8gMik7XG4gICAgICAgIHRoaXMuZHJhd2luZ0FyZWEgLT0gTWF0aC5taW4odGhpcy5kcmF3aW5nQXJlYSAvIDIsIE1hdGgubWF4KGxlZnRNb3ZlbWVudCwgcmlnaHRNb3ZlbWVudCwgdG9wTW92ZW1lbnQsIGJvdHRvbU1vdmVtZW50KSk7XG4gICAgfVxuICAgIGdldEluZGV4QW5nbGUoaW5kZXgpIHtcbiAgICAgICAgY29uc3QgYW5nbGVNdWx0aXBsaWVyID0gVEFVIC8gKHRoaXMuX3BvaW50TGFiZWxzLmxlbmd0aCB8fCAxKTtcbiAgICAgICAgY29uc3Qgc3RhcnRBbmdsZSA9IHRoaXMub3B0aW9ucy5zdGFydEFuZ2xlIHx8IDA7XG4gICAgICAgIHJldHVybiBfbm9ybWFsaXplQW5nbGUoaW5kZXggKiBhbmdsZU11bHRpcGxpZXIgKyB0b1JhZGlhbnMoc3RhcnRBbmdsZSkpO1xuICAgIH1cbiAgICBnZXREaXN0YW5jZUZyb21DZW50ZXJGb3JWYWx1ZSh2YWx1ZSkge1xuICAgICAgICBpZiAoaXNOdWxsT3JVbmRlZih2YWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBOYU47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc2NhbGluZ0ZhY3RvciA9IHRoaXMuZHJhd2luZ0FyZWEgLyAodGhpcy5tYXggLSB0aGlzLm1pbik7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMucmV2ZXJzZSkge1xuICAgICAgICAgICAgcmV0dXJuICh0aGlzLm1heCAtIHZhbHVlKSAqIHNjYWxpbmdGYWN0b3I7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICh2YWx1ZSAtIHRoaXMubWluKSAqIHNjYWxpbmdGYWN0b3I7XG4gICAgfVxuICAgIGdldFZhbHVlRm9yRGlzdGFuY2VGcm9tQ2VudGVyKGRpc3RhbmNlKSB7XG4gICAgICAgIGlmIChpc051bGxPclVuZGVmKGRpc3RhbmNlKSkge1xuICAgICAgICAgICAgcmV0dXJuIE5hTjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzY2FsZWREaXN0YW5jZSA9IGRpc3RhbmNlIC8gKHRoaXMuZHJhd2luZ0FyZWEgLyAodGhpcy5tYXggLSB0aGlzLm1pbikpO1xuICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLnJldmVyc2UgPyB0aGlzLm1heCAtIHNjYWxlZERpc3RhbmNlIDogdGhpcy5taW4gKyBzY2FsZWREaXN0YW5jZTtcbiAgICB9XG4gICAgZ2V0UG9pbnRMYWJlbENvbnRleHQoaW5kZXgpIHtcbiAgICAgICAgY29uc3QgcG9pbnRMYWJlbHMgPSB0aGlzLl9wb2ludExhYmVscyB8fCBbXTtcbiAgICAgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCBwb2ludExhYmVscy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNvbnN0IHBvaW50TGFiZWwgPSBwb2ludExhYmVsc1tpbmRleF07XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlUG9pbnRMYWJlbENvbnRleHQodGhpcy5nZXRDb250ZXh0KCksIGluZGV4LCBwb2ludExhYmVsKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXRQb2ludFBvc2l0aW9uKGluZGV4LCBkaXN0YW5jZUZyb21DZW50ZXIsIGFkZGl0aW9uYWxBbmdsZSA9IDApIHtcbiAgICAgICAgY29uc3QgYW5nbGUgPSB0aGlzLmdldEluZGV4QW5nbGUoaW5kZXgpIC0gSEFMRl9QSSArIGFkZGl0aW9uYWxBbmdsZTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IE1hdGguY29zKGFuZ2xlKSAqIGRpc3RhbmNlRnJvbUNlbnRlciArIHRoaXMueENlbnRlcixcbiAgICAgICAgICAgIHk6IE1hdGguc2luKGFuZ2xlKSAqIGRpc3RhbmNlRnJvbUNlbnRlciArIHRoaXMueUNlbnRlcixcbiAgICAgICAgICAgIGFuZ2xlXG4gICAgICAgIH07XG4gICAgfVxuICAgIGdldFBvaW50UG9zaXRpb25Gb3JWYWx1ZShpbmRleCwgdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UG9pbnRQb3NpdGlvbihpbmRleCwgdGhpcy5nZXREaXN0YW5jZUZyb21DZW50ZXJGb3JWYWx1ZSh2YWx1ZSkpO1xuICAgIH1cbiAgICBnZXRCYXNlUG9zaXRpb24oaW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UG9pbnRQb3NpdGlvbkZvclZhbHVlKGluZGV4IHx8IDAsIHRoaXMuZ2V0QmFzZVZhbHVlKCkpO1xuICAgIH1cbiAgICBnZXRQb2ludExhYmVsUG9zaXRpb24oaW5kZXgpIHtcbiAgICAgICAgY29uc3QgeyBsZWZ0ICwgdG9wICwgcmlnaHQgLCBib3R0b20gIH0gPSB0aGlzLl9wb2ludExhYmVsSXRlbXNbaW5kZXhdO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbGVmdCxcbiAgICAgICAgICAgIHRvcCxcbiAgICAgICAgICAgIHJpZ2h0LFxuICAgICAgICAgICAgYm90dG9tXG4gICAgICAgIH07XG4gICAgfVxuIGRyYXdCYWNrZ3JvdW5kKCkge1xuICAgICAgICBjb25zdCB7IGJhY2tncm91bmRDb2xvciAsIGdyaWQ6IHsgY2lyY3VsYXIgIH0gIH0gPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGlmIChiYWNrZ3JvdW5kQ29sb3IpIHtcbiAgICAgICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuY3R4O1xuICAgICAgICAgICAgY3R4LnNhdmUoKTtcbiAgICAgICAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgICAgICAgIHBhdGhSYWRpdXNMaW5lKHRoaXMsIHRoaXMuZ2V0RGlzdGFuY2VGcm9tQ2VudGVyRm9yVmFsdWUodGhpcy5fZW5kVmFsdWUpLCBjaXJjdWxhciwgdGhpcy5fcG9pbnRMYWJlbHMubGVuZ3RoKTtcbiAgICAgICAgICAgIGN0eC5jbG9zZVBhdGgoKTtcbiAgICAgICAgICAgIGN0eC5maWxsU3R5bGUgPSBiYWNrZ3JvdW5kQ29sb3I7XG4gICAgICAgICAgICBjdHguZmlsbCgpO1xuICAgICAgICAgICAgY3R4LnJlc3RvcmUoKTtcbiAgICAgICAgfVxuICAgIH1cbiBkcmF3R3JpZCgpIHtcbiAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgICAgIGNvbnN0IG9wdHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGNvbnN0IHsgYW5nbGVMaW5lcyAsIGdyaWQgLCBib3JkZXIgIH0gPSBvcHRzO1xuICAgICAgICBjb25zdCBsYWJlbENvdW50ID0gdGhpcy5fcG9pbnRMYWJlbHMubGVuZ3RoO1xuICAgICAgICBsZXQgaSwgb2Zmc2V0LCBwb3NpdGlvbjtcbiAgICAgICAgaWYgKG9wdHMucG9pbnRMYWJlbHMuZGlzcGxheSkge1xuICAgICAgICAgICAgZHJhd1BvaW50TGFiZWxzKHRoaXMsIGxhYmVsQ291bnQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChncmlkLmRpc3BsYXkpIHtcbiAgICAgICAgICAgIHRoaXMudGlja3MuZm9yRWFjaCgodGljaywgaW5kZXgpPT57XG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ICE9PSAwIHx8IGluZGV4ID09PSAwICYmIHRoaXMubWluIDwgMCkge1xuICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSB0aGlzLmdldERpc3RhbmNlRnJvbUNlbnRlckZvclZhbHVlKHRpY2sudmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5nZXRDb250ZXh0KGluZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3B0c0F0SW5kZXggPSBncmlkLnNldENvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9wdHNBdEluZGV4Qm9yZGVyID0gYm9yZGVyLnNldENvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICAgICAgICAgIGRyYXdSYWRpdXNMaW5lKHRoaXMsIG9wdHNBdEluZGV4LCBvZmZzZXQsIGxhYmVsQ291bnQsIG9wdHNBdEluZGV4Qm9yZGVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYW5nbGVMaW5lcy5kaXNwbGF5KSB7XG4gICAgICAgICAgICBjdHguc2F2ZSgpO1xuICAgICAgICAgICAgZm9yKGkgPSBsYWJlbENvdW50IC0gMTsgaSA+PSAwOyBpLS0pe1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wdHNBdEluZGV4ID0gYW5nbGVMaW5lcy5zZXRDb250ZXh0KHRoaXMuZ2V0UG9pbnRMYWJlbENvbnRleHQoaSkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgY29sb3IgLCBsaW5lV2lkdGggIH0gPSBvcHRzQXRJbmRleDtcbiAgICAgICAgICAgICAgICBpZiAoIWxpbmVXaWR0aCB8fCAhY29sb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGN0eC5saW5lV2lkdGggPSBsaW5lV2lkdGg7XG4gICAgICAgICAgICAgICAgY3R4LnN0cm9rZVN0eWxlID0gY29sb3I7XG4gICAgICAgICAgICAgICAgY3R4LnNldExpbmVEYXNoKG9wdHNBdEluZGV4LmJvcmRlckRhc2gpO1xuICAgICAgICAgICAgICAgIGN0eC5saW5lRGFzaE9mZnNldCA9IG9wdHNBdEluZGV4LmJvcmRlckRhc2hPZmZzZXQ7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ID0gdGhpcy5nZXREaXN0YW5jZUZyb21DZW50ZXJGb3JWYWx1ZShvcHRzLnJldmVyc2UgPyB0aGlzLm1pbiA6IHRoaXMubWF4KTtcbiAgICAgICAgICAgICAgICBwb3NpdGlvbiA9IHRoaXMuZ2V0UG9pbnRQb3NpdGlvbihpLCBvZmZzZXQpO1xuICAgICAgICAgICAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgICAgICAgICAgICBjdHgubW92ZVRvKHRoaXMueENlbnRlciwgdGhpcy55Q2VudGVyKTtcbiAgICAgICAgICAgICAgICBjdHgubGluZVRvKHBvc2l0aW9uLngsIHBvc2l0aW9uLnkpO1xuICAgICAgICAgICAgICAgIGN0eC5zdHJva2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgICAgIH1cbiAgICB9XG4gZHJhd0JvcmRlcigpIHt9XG4gZHJhd0xhYmVscygpIHtcbiAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgICAgIGNvbnN0IG9wdHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGNvbnN0IHRpY2tPcHRzID0gb3B0cy50aWNrcztcbiAgICAgICAgaWYgKCF0aWNrT3B0cy5kaXNwbGF5KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RhcnRBbmdsZSA9IHRoaXMuZ2V0SW5kZXhBbmdsZSgwKTtcbiAgICAgICAgbGV0IG9mZnNldCwgd2lkdGg7XG4gICAgICAgIGN0eC5zYXZlKCk7XG4gICAgICAgIGN0eC50cmFuc2xhdGUodGhpcy54Q2VudGVyLCB0aGlzLnlDZW50ZXIpO1xuICAgICAgICBjdHgucm90YXRlKHN0YXJ0QW5nbGUpO1xuICAgICAgICBjdHgudGV4dEFsaWduID0gJ2NlbnRlcic7XG4gICAgICAgIGN0eC50ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJztcbiAgICAgICAgdGhpcy50aWNrcy5mb3JFYWNoKCh0aWNrLCBpbmRleCk9PntcbiAgICAgICAgICAgIGlmIChpbmRleCA9PT0gMCAmJiB0aGlzLm1pbiA+PSAwICYmICFvcHRzLnJldmVyc2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBvcHRzQXRJbmRleCA9IHRpY2tPcHRzLnNldENvbnRleHQodGhpcy5nZXRDb250ZXh0KGluZGV4KSk7XG4gICAgICAgICAgICBjb25zdCB0aWNrRm9udCA9IHRvRm9udChvcHRzQXRJbmRleC5mb250KTtcbiAgICAgICAgICAgIG9mZnNldCA9IHRoaXMuZ2V0RGlzdGFuY2VGcm9tQ2VudGVyRm9yVmFsdWUodGhpcy50aWNrc1tpbmRleF0udmFsdWUpO1xuICAgICAgICAgICAgaWYgKG9wdHNBdEluZGV4LnNob3dMYWJlbEJhY2tkcm9wKSB7XG4gICAgICAgICAgICAgICAgY3R4LmZvbnQgPSB0aWNrRm9udC5zdHJpbmc7XG4gICAgICAgICAgICAgICAgd2lkdGggPSBjdHgubWVhc3VyZVRleHQodGljay5sYWJlbCkud2lkdGg7XG4gICAgICAgICAgICAgICAgY3R4LmZpbGxTdHlsZSA9IG9wdHNBdEluZGV4LmJhY2tkcm9wQ29sb3I7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFkZGluZyA9IHRvUGFkZGluZyhvcHRzQXRJbmRleC5iYWNrZHJvcFBhZGRpbmcpO1xuICAgICAgICAgICAgICAgIGN0eC5maWxsUmVjdCgtd2lkdGggLyAyIC0gcGFkZGluZy5sZWZ0LCAtb2Zmc2V0IC0gdGlja0ZvbnQuc2l6ZSAvIDIgLSBwYWRkaW5nLnRvcCwgd2lkdGggKyBwYWRkaW5nLndpZHRoLCB0aWNrRm9udC5zaXplICsgcGFkZGluZy5oZWlnaHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyVGV4dChjdHgsIHRpY2subGFiZWwsIDAsIC1vZmZzZXQsIHRpY2tGb250LCB7XG4gICAgICAgICAgICAgICAgY29sb3I6IG9wdHNBdEluZGV4LmNvbG9yLFxuICAgICAgICAgICAgICAgIHN0cm9rZUNvbG9yOiBvcHRzQXRJbmRleC50ZXh0U3Ryb2tlQ29sb3IsXG4gICAgICAgICAgICAgICAgc3Ryb2tlV2lkdGg6IG9wdHNBdEluZGV4LnRleHRTdHJva2VXaWR0aFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICBjdHgucmVzdG9yZSgpO1xuICAgIH1cbiBkcmF3VGl0bGUoKSB7fVxufVxuXG5jb25zdCBJTlRFUlZBTFMgPSB7XG4gICAgbWlsbGlzZWNvbmQ6IHtcbiAgICAgICAgY29tbW9uOiB0cnVlLFxuICAgICAgICBzaXplOiAxLFxuICAgICAgICBzdGVwczogMTAwMFxuICAgIH0sXG4gICAgc2Vjb25kOiB7XG4gICAgICAgIGNvbW1vbjogdHJ1ZSxcbiAgICAgICAgc2l6ZTogMTAwMCxcbiAgICAgICAgc3RlcHM6IDYwXG4gICAgfSxcbiAgICBtaW51dGU6IHtcbiAgICAgICAgY29tbW9uOiB0cnVlLFxuICAgICAgICBzaXplOiA2MDAwMCxcbiAgICAgICAgc3RlcHM6IDYwXG4gICAgfSxcbiAgICBob3VyOiB7XG4gICAgICAgIGNvbW1vbjogdHJ1ZSxcbiAgICAgICAgc2l6ZTogMzYwMDAwMCxcbiAgICAgICAgc3RlcHM6IDI0XG4gICAgfSxcbiAgICBkYXk6IHtcbiAgICAgICAgY29tbW9uOiB0cnVlLFxuICAgICAgICBzaXplOiA4NjQwMDAwMCxcbiAgICAgICAgc3RlcHM6IDMwXG4gICAgfSxcbiAgICB3ZWVrOiB7XG4gICAgICAgIGNvbW1vbjogZmFsc2UsXG4gICAgICAgIHNpemU6IDYwNDgwMDAwMCxcbiAgICAgICAgc3RlcHM6IDRcbiAgICB9LFxuICAgIG1vbnRoOiB7XG4gICAgICAgIGNvbW1vbjogdHJ1ZSxcbiAgICAgICAgc2l6ZTogMi42MjhlOSxcbiAgICAgICAgc3RlcHM6IDEyXG4gICAgfSxcbiAgICBxdWFydGVyOiB7XG4gICAgICAgIGNvbW1vbjogZmFsc2UsXG4gICAgICAgIHNpemU6IDcuODg0ZTksXG4gICAgICAgIHN0ZXBzOiA0XG4gICAgfSxcbiAgICB5ZWFyOiB7XG4gICAgICAgIGNvbW1vbjogdHJ1ZSxcbiAgICAgICAgc2l6ZTogMy4xNTRlMTBcbiAgICB9XG59O1xuIGNvbnN0IFVOSVRTID0gIC8qICNfX1BVUkVfXyAqLyBPYmplY3Qua2V5cyhJTlRFUlZBTFMpO1xuIGZ1bmN0aW9uIHNvcnRlcihhLCBiKSB7XG4gICAgcmV0dXJuIGEgLSBiO1xufVxuIGZ1bmN0aW9uIHBhcnNlKHNjYWxlLCBpbnB1dCkge1xuICAgIGlmIChpc051bGxPclVuZGVmKGlucHV0KSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgYWRhcHRlciA9IHNjYWxlLl9hZGFwdGVyO1xuICAgIGNvbnN0IHsgcGFyc2VyICwgcm91bmQgLCBpc29XZWVrZGF5ICB9ID0gc2NhbGUuX3BhcnNlT3B0cztcbiAgICBsZXQgdmFsdWUgPSBpbnB1dDtcbiAgICBpZiAodHlwZW9mIHBhcnNlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB2YWx1ZSA9IHBhcnNlcih2YWx1ZSk7XG4gICAgfVxuICAgIGlmICghaXNOdW1iZXJGaW5pdGUodmFsdWUpKSB7XG4gICAgICAgIHZhbHVlID0gdHlwZW9mIHBhcnNlciA9PT0gJ3N0cmluZycgPyBhZGFwdGVyLnBhcnNlKHZhbHVlLCAgcGFyc2VyKSA6IGFkYXB0ZXIucGFyc2UodmFsdWUpO1xuICAgIH1cbiAgICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGlmIChyb3VuZCkge1xuICAgICAgICB2YWx1ZSA9IHJvdW5kID09PSAnd2VlaycgJiYgKGlzTnVtYmVyKGlzb1dlZWtkYXkpIHx8IGlzb1dlZWtkYXkgPT09IHRydWUpID8gYWRhcHRlci5zdGFydE9mKHZhbHVlLCAnaXNvV2VlaycsIGlzb1dlZWtkYXkpIDogYWRhcHRlci5zdGFydE9mKHZhbHVlLCByb3VuZCk7XG4gICAgfVxuICAgIHJldHVybiArdmFsdWU7XG59XG4gZnVuY3Rpb24gZGV0ZXJtaW5lVW5pdEZvckF1dG9UaWNrcyhtaW5Vbml0LCBtaW4sIG1heCwgY2FwYWNpdHkpIHtcbiAgICBjb25zdCBpbGVuID0gVU5JVFMubGVuZ3RoO1xuICAgIGZvcihsZXQgaSA9IFVOSVRTLmluZGV4T2YobWluVW5pdCk7IGkgPCBpbGVuIC0gMTsgKytpKXtcbiAgICAgICAgY29uc3QgaW50ZXJ2YWwgPSBJTlRFUlZBTFNbVU5JVFNbaV1dO1xuICAgICAgICBjb25zdCBmYWN0b3IgPSBpbnRlcnZhbC5zdGVwcyA/IGludGVydmFsLnN0ZXBzIDogTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVI7XG4gICAgICAgIGlmIChpbnRlcnZhbC5jb21tb24gJiYgTWF0aC5jZWlsKChtYXggLSBtaW4pIC8gKGZhY3RvciAqIGludGVydmFsLnNpemUpKSA8PSBjYXBhY2l0eSkge1xuICAgICAgICAgICAgcmV0dXJuIFVOSVRTW2ldO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBVTklUU1tpbGVuIC0gMV07XG59XG4gZnVuY3Rpb24gZGV0ZXJtaW5lVW5pdEZvckZvcm1hdHRpbmcoc2NhbGUsIG51bVRpY2tzLCBtaW5Vbml0LCBtaW4sIG1heCkge1xuICAgIGZvcihsZXQgaSA9IFVOSVRTLmxlbmd0aCAtIDE7IGkgPj0gVU5JVFMuaW5kZXhPZihtaW5Vbml0KTsgaS0tKXtcbiAgICAgICAgY29uc3QgdW5pdCA9IFVOSVRTW2ldO1xuICAgICAgICBpZiAoSU5URVJWQUxTW3VuaXRdLmNvbW1vbiAmJiBzY2FsZS5fYWRhcHRlci5kaWZmKG1heCwgbWluLCB1bml0KSA+PSBudW1UaWNrcyAtIDEpIHtcbiAgICAgICAgICAgIHJldHVybiB1bml0O1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBVTklUU1ttaW5Vbml0ID8gVU5JVFMuaW5kZXhPZihtaW5Vbml0KSA6IDBdO1xufVxuIGZ1bmN0aW9uIGRldGVybWluZU1ham9yVW5pdCh1bml0KSB7XG4gICAgZm9yKGxldCBpID0gVU5JVFMuaW5kZXhPZih1bml0KSArIDEsIGlsZW4gPSBVTklUUy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpe1xuICAgICAgICBpZiAoSU5URVJWQUxTW1VOSVRTW2ldXS5jb21tb24pIHtcbiAgICAgICAgICAgIHJldHVybiBVTklUU1tpXTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiBmdW5jdGlvbiBhZGRUaWNrKHRpY2tzLCB0aW1lLCB0aW1lc3RhbXBzKSB7XG4gICAgaWYgKCF0aW1lc3RhbXBzKSB7XG4gICAgICAgIHRpY2tzW3RpbWVdID0gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKHRpbWVzdGFtcHMubGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IHsgbG8gLCBoaSAgfSA9IF9sb29rdXAodGltZXN0YW1wcywgdGltZSk7XG4gICAgICAgIGNvbnN0IHRpbWVzdGFtcCA9IHRpbWVzdGFtcHNbbG9dID49IHRpbWUgPyB0aW1lc3RhbXBzW2xvXSA6IHRpbWVzdGFtcHNbaGldO1xuICAgICAgICB0aWNrc1t0aW1lc3RhbXBdID0gdHJ1ZTtcbiAgICB9XG59XG4gZnVuY3Rpb24gc2V0TWFqb3JUaWNrcyhzY2FsZSwgdGlja3MsIG1hcCwgbWFqb3JVbml0KSB7XG4gICAgY29uc3QgYWRhcHRlciA9IHNjYWxlLl9hZGFwdGVyO1xuICAgIGNvbnN0IGZpcnN0ID0gK2FkYXB0ZXIuc3RhcnRPZih0aWNrc1swXS52YWx1ZSwgbWFqb3JVbml0KTtcbiAgICBjb25zdCBsYXN0ID0gdGlja3NbdGlja3MubGVuZ3RoIC0gMV0udmFsdWU7XG4gICAgbGV0IG1ham9yLCBpbmRleDtcbiAgICBmb3IobWFqb3IgPSBmaXJzdDsgbWFqb3IgPD0gbGFzdDsgbWFqb3IgPSArYWRhcHRlci5hZGQobWFqb3IsIDEsIG1ham9yVW5pdCkpe1xuICAgICAgICBpbmRleCA9IG1hcFttYWpvcl07XG4gICAgICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICAgICAgICB0aWNrc1tpbmRleF0ubWFqb3IgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aWNrcztcbn1cbiBmdW5jdGlvbiB0aWNrc0Zyb21UaW1lc3RhbXBzKHNjYWxlLCB2YWx1ZXMsIG1ham9yVW5pdCkge1xuICAgIGNvbnN0IHRpY2tzID0gW107XG4gICAgIGNvbnN0IG1hcCA9IHt9O1xuICAgIGNvbnN0IGlsZW4gPSB2YWx1ZXMubGVuZ3RoO1xuICAgIGxldCBpLCB2YWx1ZTtcbiAgICBmb3IoaSA9IDA7IGkgPCBpbGVuOyArK2kpe1xuICAgICAgICB2YWx1ZSA9IHZhbHVlc1tpXTtcbiAgICAgICAgbWFwW3ZhbHVlXSA9IGk7XG4gICAgICAgIHRpY2tzLnB1c2goe1xuICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICBtYWpvcjogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBpbGVuID09PSAwIHx8ICFtYWpvclVuaXQgPyB0aWNrcyA6IHNldE1ham9yVGlja3Moc2NhbGUsIHRpY2tzLCBtYXAsIG1ham9yVW5pdCk7XG59XG5jbGFzcyBUaW1lU2NhbGUgZXh0ZW5kcyBTY2FsZSB7XG4gICAgc3RhdGljIGlkID0gJ3RpbWUnO1xuIHN0YXRpYyBkZWZhdWx0cyA9IHtcbiBib3VuZHM6ICdkYXRhJyxcbiAgICAgICAgYWRhcHRlcnM6IHt9LFxuICAgICAgICB0aW1lOiB7XG4gICAgICAgICAgICBwYXJzZXI6IGZhbHNlLFxuICAgICAgICAgICAgdW5pdDogZmFsc2UsXG4gICAgICAgICAgICByb3VuZDogZmFsc2UsXG4gICAgICAgICAgICBpc29XZWVrZGF5OiBmYWxzZSxcbiAgICAgICAgICAgIG1pblVuaXQ6ICdtaWxsaXNlY29uZCcsXG4gICAgICAgICAgICBkaXNwbGF5Rm9ybWF0czoge31cbiAgICAgICAgfSxcbiAgICAgICAgdGlja3M6IHtcbiBzb3VyY2U6ICdhdXRvJyxcbiAgICAgICAgICAgIGNhbGxiYWNrOiBmYWxzZSxcbiAgICAgICAgICAgIG1ham9yOiB7XG4gICAgICAgICAgICAgICAgZW5hYmxlZDogZmFsc2VcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gY29uc3RydWN0b3IocHJvcHMpe1xuICAgICAgICBzdXBlcihwcm9wcyk7XG4gICAgICAgICB0aGlzLl9jYWNoZSA9IHtcbiAgICAgICAgICAgIGRhdGE6IFtdLFxuICAgICAgICAgICAgbGFiZWxzOiBbXSxcbiAgICAgICAgICAgIGFsbDogW11cbiAgICAgICAgfTtcbiAgICAgICAgIHRoaXMuX3VuaXQgPSAnZGF5JztcbiAgICAgICAgIHRoaXMuX21ham9yVW5pdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fb2Zmc2V0cyA9IHt9O1xuICAgICAgICB0aGlzLl9ub3JtYWxpemVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX3BhcnNlT3B0cyA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgaW5pdChzY2FsZU9wdHMsIG9wdHMgPSB7fSkge1xuICAgICAgICBjb25zdCB0aW1lID0gc2NhbGVPcHRzLnRpbWUgfHwgKHNjYWxlT3B0cy50aW1lID0ge30pO1xuICAgICAgICAgY29uc3QgYWRhcHRlciA9IHRoaXMuX2FkYXB0ZXIgPSBuZXcgYWRhcHRlcnMuX2RhdGUoc2NhbGVPcHRzLmFkYXB0ZXJzLmRhdGUpO1xuICAgICAgICBhZGFwdGVyLmluaXQob3B0cyk7XG4gICAgICAgIG1lcmdlSWYodGltZS5kaXNwbGF5Rm9ybWF0cywgYWRhcHRlci5mb3JtYXRzKCkpO1xuICAgICAgICB0aGlzLl9wYXJzZU9wdHMgPSB7XG4gICAgICAgICAgICBwYXJzZXI6IHRpbWUucGFyc2VyLFxuICAgICAgICAgICAgcm91bmQ6IHRpbWUucm91bmQsXG4gICAgICAgICAgICBpc29XZWVrZGF5OiB0aW1lLmlzb1dlZWtkYXlcbiAgICAgICAgfTtcbiAgICAgICAgc3VwZXIuaW5pdChzY2FsZU9wdHMpO1xuICAgICAgICB0aGlzLl9ub3JtYWxpemVkID0gb3B0cy5ub3JtYWxpemVkO1xuICAgIH1cbiBwYXJzZShyYXcsIGluZGV4KSB7XG4gICAgICAgIGlmIChyYXcgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBhcnNlKHRoaXMsIHJhdyk7XG4gICAgfVxuICAgIGJlZm9yZUxheW91dCgpIHtcbiAgICAgICAgc3VwZXIuYmVmb3JlTGF5b3V0KCk7XG4gICAgICAgIHRoaXMuX2NhY2hlID0ge1xuICAgICAgICAgICAgZGF0YTogW10sXG4gICAgICAgICAgICBsYWJlbHM6IFtdLFxuICAgICAgICAgICAgYWxsOiBbXVxuICAgICAgICB9O1xuICAgIH1cbiAgICBkZXRlcm1pbmVEYXRhTGltaXRzKCkge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBjb25zdCBhZGFwdGVyID0gdGhpcy5fYWRhcHRlcjtcbiAgICAgICAgY29uc3QgdW5pdCA9IG9wdGlvbnMudGltZS51bml0IHx8ICdkYXknO1xuICAgICAgICBsZXQgeyBtaW4gLCBtYXggLCBtaW5EZWZpbmVkICwgbWF4RGVmaW5lZCAgfSA9IHRoaXMuZ2V0VXNlckJvdW5kcygpO1xuIGZ1bmN0aW9uIF9hcHBseUJvdW5kcyhib3VuZHMpIHtcbiAgICAgICAgICAgIGlmICghbWluRGVmaW5lZCAmJiAhaXNOYU4oYm91bmRzLm1pbikpIHtcbiAgICAgICAgICAgICAgICBtaW4gPSBNYXRoLm1pbihtaW4sIGJvdW5kcy5taW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFtYXhEZWZpbmVkICYmICFpc05hTihib3VuZHMubWF4KSkge1xuICAgICAgICAgICAgICAgIG1heCA9IE1hdGgubWF4KG1heCwgYm91bmRzLm1heCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFtaW5EZWZpbmVkIHx8ICFtYXhEZWZpbmVkKSB7XG4gICAgICAgICAgICBfYXBwbHlCb3VuZHModGhpcy5fZ2V0TGFiZWxCb3VuZHMoKSk7XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5ib3VuZHMgIT09ICd0aWNrcycgfHwgb3B0aW9ucy50aWNrcy5zb3VyY2UgIT09ICdsYWJlbHMnKSB7XG4gICAgICAgICAgICAgICAgX2FwcGx5Qm91bmRzKHRoaXMuZ2V0TWluTWF4KGZhbHNlKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbWluID0gaXNOdW1iZXJGaW5pdGUobWluKSAmJiAhaXNOYU4obWluKSA/IG1pbiA6ICthZGFwdGVyLnN0YXJ0T2YoRGF0ZS5ub3coKSwgdW5pdCk7XG4gICAgICAgIG1heCA9IGlzTnVtYmVyRmluaXRlKG1heCkgJiYgIWlzTmFOKG1heCkgPyBtYXggOiArYWRhcHRlci5lbmRPZihEYXRlLm5vdygpLCB1bml0KSArIDE7XG4gICAgICAgIHRoaXMubWluID0gTWF0aC5taW4obWluLCBtYXggLSAxKTtcbiAgICAgICAgdGhpcy5tYXggPSBNYXRoLm1heChtaW4gKyAxLCBtYXgpO1xuICAgIH1cbiBfZ2V0TGFiZWxCb3VuZHMoKSB7XG4gICAgICAgIGNvbnN0IGFyciA9IHRoaXMuZ2V0TGFiZWxUaW1lc3RhbXBzKCk7XG4gICAgICAgIGxldCBtaW4gPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG4gICAgICAgIGxldCBtYXggPSBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFk7XG4gICAgICAgIGlmIChhcnIubGVuZ3RoKSB7XG4gICAgICAgICAgICBtaW4gPSBhcnJbMF07XG4gICAgICAgICAgICBtYXggPSBhcnJbYXJyLmxlbmd0aCAtIDFdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBtaW4sXG4gICAgICAgICAgICBtYXhcbiAgICAgICAgfTtcbiAgICB9XG4gYnVpbGRUaWNrcygpIHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgY29uc3QgdGltZU9wdHMgPSBvcHRpb25zLnRpbWU7XG4gICAgICAgIGNvbnN0IHRpY2tPcHRzID0gb3B0aW9ucy50aWNrcztcbiAgICAgICAgY29uc3QgdGltZXN0YW1wcyA9IHRpY2tPcHRzLnNvdXJjZSA9PT0gJ2xhYmVscycgPyB0aGlzLmdldExhYmVsVGltZXN0YW1wcygpIDogdGhpcy5fZ2VuZXJhdGUoKTtcbiAgICAgICAgaWYgKG9wdGlvbnMuYm91bmRzID09PSAndGlja3MnICYmIHRpbWVzdGFtcHMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLm1pbiA9IHRoaXMuX3VzZXJNaW4gfHwgdGltZXN0YW1wc1swXTtcbiAgICAgICAgICAgIHRoaXMubWF4ID0gdGhpcy5fdXNlck1heCB8fCB0aW1lc3RhbXBzW3RpbWVzdGFtcHMubGVuZ3RoIC0gMV07XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbWluID0gdGhpcy5taW47XG4gICAgICAgIGNvbnN0IG1heCA9IHRoaXMubWF4O1xuICAgICAgICBjb25zdCB0aWNrcyA9IF9maWx0ZXJCZXR3ZWVuKHRpbWVzdGFtcHMsIG1pbiwgbWF4KTtcbiAgICAgICAgdGhpcy5fdW5pdCA9IHRpbWVPcHRzLnVuaXQgfHwgKHRpY2tPcHRzLmF1dG9Ta2lwID8gZGV0ZXJtaW5lVW5pdEZvckF1dG9UaWNrcyh0aW1lT3B0cy5taW5Vbml0LCB0aGlzLm1pbiwgdGhpcy5tYXgsIHRoaXMuX2dldExhYmVsQ2FwYWNpdHkobWluKSkgOiBkZXRlcm1pbmVVbml0Rm9yRm9ybWF0dGluZyh0aGlzLCB0aWNrcy5sZW5ndGgsIHRpbWVPcHRzLm1pblVuaXQsIHRoaXMubWluLCB0aGlzLm1heCkpO1xuICAgICAgICB0aGlzLl9tYWpvclVuaXQgPSAhdGlja09wdHMubWFqb3IuZW5hYmxlZCB8fCB0aGlzLl91bml0ID09PSAneWVhcicgPyB1bmRlZmluZWQgOiBkZXRlcm1pbmVNYWpvclVuaXQodGhpcy5fdW5pdCk7XG4gICAgICAgIHRoaXMuaW5pdE9mZnNldHModGltZXN0YW1wcyk7XG4gICAgICAgIGlmIChvcHRpb25zLnJldmVyc2UpIHtcbiAgICAgICAgICAgIHRpY2tzLnJldmVyc2UoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGlja3NGcm9tVGltZXN0YW1wcyh0aGlzLCB0aWNrcywgdGhpcy5fbWFqb3JVbml0KTtcbiAgICB9XG4gICAgYWZ0ZXJBdXRvU2tpcCgpIHtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5vZmZzZXRBZnRlckF1dG9za2lwKSB7XG4gICAgICAgICAgICB0aGlzLmluaXRPZmZzZXRzKHRoaXMudGlja3MubWFwKCh0aWNrKT0+K3RpY2sudmFsdWUpKTtcbiAgICAgICAgfVxuICAgIH1cbiBpbml0T2Zmc2V0cyh0aW1lc3RhbXBzID0gW10pIHtcbiAgICAgICAgbGV0IHN0YXJ0ID0gMDtcbiAgICAgICAgbGV0IGVuZCA9IDA7XG4gICAgICAgIGxldCBmaXJzdCwgbGFzdDtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5vZmZzZXQgJiYgdGltZXN0YW1wcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGZpcnN0ID0gdGhpcy5nZXREZWNpbWFsRm9yVmFsdWUodGltZXN0YW1wc1swXSk7XG4gICAgICAgICAgICBpZiAodGltZXN0YW1wcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgICBzdGFydCA9IDEgLSBmaXJzdDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RhcnQgPSAodGhpcy5nZXREZWNpbWFsRm9yVmFsdWUodGltZXN0YW1wc1sxXSkgLSBmaXJzdCkgLyAyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGFzdCA9IHRoaXMuZ2V0RGVjaW1hbEZvclZhbHVlKHRpbWVzdGFtcHNbdGltZXN0YW1wcy5sZW5ndGggLSAxXSk7XG4gICAgICAgICAgICBpZiAodGltZXN0YW1wcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgICBlbmQgPSBsYXN0O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBlbmQgPSAobGFzdCAtIHRoaXMuZ2V0RGVjaW1hbEZvclZhbHVlKHRpbWVzdGFtcHNbdGltZXN0YW1wcy5sZW5ndGggLSAyXSkpIC8gMjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBsaW1pdCA9IHRpbWVzdGFtcHMubGVuZ3RoIDwgMyA/IDAuNSA6IDAuMjU7XG4gICAgICAgIHN0YXJ0ID0gX2xpbWl0VmFsdWUoc3RhcnQsIDAsIGxpbWl0KTtcbiAgICAgICAgZW5kID0gX2xpbWl0VmFsdWUoZW5kLCAwLCBsaW1pdCk7XG4gICAgICAgIHRoaXMuX29mZnNldHMgPSB7XG4gICAgICAgICAgICBzdGFydCxcbiAgICAgICAgICAgIGVuZCxcbiAgICAgICAgICAgIGZhY3RvcjogMSAvIChzdGFydCArIDEgKyBlbmQpXG4gICAgICAgIH07XG4gICAgfVxuIF9nZW5lcmF0ZSgpIHtcbiAgICAgICAgY29uc3QgYWRhcHRlciA9IHRoaXMuX2FkYXB0ZXI7XG4gICAgICAgIGNvbnN0IG1pbiA9IHRoaXMubWluO1xuICAgICAgICBjb25zdCBtYXggPSB0aGlzLm1heDtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgY29uc3QgdGltZU9wdHMgPSBvcHRpb25zLnRpbWU7XG4gICAgICAgIGNvbnN0IG1pbm9yID0gdGltZU9wdHMudW5pdCB8fCBkZXRlcm1pbmVVbml0Rm9yQXV0b1RpY2tzKHRpbWVPcHRzLm1pblVuaXQsIG1pbiwgbWF4LCB0aGlzLl9nZXRMYWJlbENhcGFjaXR5KG1pbikpO1xuICAgICAgICBjb25zdCBzdGVwU2l6ZSA9IHZhbHVlT3JEZWZhdWx0KG9wdGlvbnMudGlja3Muc3RlcFNpemUsIDEpO1xuICAgICAgICBjb25zdCB3ZWVrZGF5ID0gbWlub3IgPT09ICd3ZWVrJyA/IHRpbWVPcHRzLmlzb1dlZWtkYXkgOiBmYWxzZTtcbiAgICAgICAgY29uc3QgaGFzV2Vla2RheSA9IGlzTnVtYmVyKHdlZWtkYXkpIHx8IHdlZWtkYXkgPT09IHRydWU7XG4gICAgICAgIGNvbnN0IHRpY2tzID0ge307XG4gICAgICAgIGxldCBmaXJzdCA9IG1pbjtcbiAgICAgICAgbGV0IHRpbWUsIGNvdW50O1xuICAgICAgICBpZiAoaGFzV2Vla2RheSkge1xuICAgICAgICAgICAgZmlyc3QgPSArYWRhcHRlci5zdGFydE9mKGZpcnN0LCAnaXNvV2VlaycsIHdlZWtkYXkpO1xuICAgICAgICB9XG4gICAgICAgIGZpcnN0ID0gK2FkYXB0ZXIuc3RhcnRPZihmaXJzdCwgaGFzV2Vla2RheSA/ICdkYXknIDogbWlub3IpO1xuICAgICAgICBpZiAoYWRhcHRlci5kaWZmKG1heCwgbWluLCBtaW5vcikgPiAxMDAwMDAgKiBzdGVwU2l6ZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1pbiArICcgYW5kICcgKyBtYXggKyAnIGFyZSB0b28gZmFyIGFwYXJ0IHdpdGggc3RlcFNpemUgb2YgJyArIHN0ZXBTaXplICsgJyAnICsgbWlub3IpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHRpbWVzdGFtcHMgPSBvcHRpb25zLnRpY2tzLnNvdXJjZSA9PT0gJ2RhdGEnICYmIHRoaXMuZ2V0RGF0YVRpbWVzdGFtcHMoKTtcbiAgICAgICAgZm9yKHRpbWUgPSBmaXJzdCwgY291bnQgPSAwOyB0aW1lIDwgbWF4OyB0aW1lID0gK2FkYXB0ZXIuYWRkKHRpbWUsIHN0ZXBTaXplLCBtaW5vciksIGNvdW50Kyspe1xuICAgICAgICAgICAgYWRkVGljayh0aWNrcywgdGltZSwgdGltZXN0YW1wcyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRpbWUgPT09IG1heCB8fCBvcHRpb25zLmJvdW5kcyA9PT0gJ3RpY2tzJyB8fCBjb3VudCA9PT0gMSkge1xuICAgICAgICAgICAgYWRkVGljayh0aWNrcywgdGltZSwgdGltZXN0YW1wcyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKHRpY2tzKS5zb3J0KHNvcnRlcikubWFwKCh4KT0+K3gpO1xuICAgIH1cbiBnZXRMYWJlbEZvclZhbHVlKHZhbHVlKSB7XG4gICAgICAgIGNvbnN0IGFkYXB0ZXIgPSB0aGlzLl9hZGFwdGVyO1xuICAgICAgICBjb25zdCB0aW1lT3B0cyA9IHRoaXMub3B0aW9ucy50aW1lO1xuICAgICAgICBpZiAodGltZU9wdHMudG9vbHRpcEZvcm1hdCkge1xuICAgICAgICAgICAgcmV0dXJuIGFkYXB0ZXIuZm9ybWF0KHZhbHVlLCB0aW1lT3B0cy50b29sdGlwRm9ybWF0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWRhcHRlci5mb3JtYXQodmFsdWUsIHRpbWVPcHRzLmRpc3BsYXlGb3JtYXRzLmRhdGV0aW1lKTtcbiAgICB9XG4gZm9ybWF0KHZhbHVlLCBmb3JtYXQpIHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgY29uc3QgZm9ybWF0cyA9IG9wdGlvbnMudGltZS5kaXNwbGF5Rm9ybWF0cztcbiAgICAgICAgY29uc3QgdW5pdCA9IHRoaXMuX3VuaXQ7XG4gICAgICAgIGNvbnN0IGZtdCA9IGZvcm1hdCB8fCBmb3JtYXRzW3VuaXRdO1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRhcHRlci5mb3JtYXQodmFsdWUsIGZtdCk7XG4gICAgfVxuIF90aWNrRm9ybWF0RnVuY3Rpb24odGltZSwgaW5kZXgsIHRpY2tzLCBmb3JtYXQpIHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgY29uc3QgZm9ybWF0dGVyID0gb3B0aW9ucy50aWNrcy5jYWxsYmFjaztcbiAgICAgICAgaWYgKGZvcm1hdHRlcikge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGZvcm1hdHRlciwgW1xuICAgICAgICAgICAgICAgIHRpbWUsXG4gICAgICAgICAgICAgICAgaW5kZXgsXG4gICAgICAgICAgICAgICAgdGlja3NcbiAgICAgICAgICAgIF0sIHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGZvcm1hdHMgPSBvcHRpb25zLnRpbWUuZGlzcGxheUZvcm1hdHM7XG4gICAgICAgIGNvbnN0IHVuaXQgPSB0aGlzLl91bml0O1xuICAgICAgICBjb25zdCBtYWpvclVuaXQgPSB0aGlzLl9tYWpvclVuaXQ7XG4gICAgICAgIGNvbnN0IG1pbm9yRm9ybWF0ID0gdW5pdCAmJiBmb3JtYXRzW3VuaXRdO1xuICAgICAgICBjb25zdCBtYWpvckZvcm1hdCA9IG1ham9yVW5pdCAmJiBmb3JtYXRzW21ham9yVW5pdF07XG4gICAgICAgIGNvbnN0IHRpY2sgPSB0aWNrc1tpbmRleF07XG4gICAgICAgIGNvbnN0IG1ham9yID0gbWFqb3JVbml0ICYmIG1ham9yRm9ybWF0ICYmIHRpY2sgJiYgdGljay5tYWpvcjtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkYXB0ZXIuZm9ybWF0KHRpbWUsIGZvcm1hdCB8fCAobWFqb3IgPyBtYWpvckZvcm1hdCA6IG1pbm9yRm9ybWF0KSk7XG4gICAgfVxuIGdlbmVyYXRlVGlja0xhYmVscyh0aWNrcykge1xuICAgICAgICBsZXQgaSwgaWxlbiwgdGljaztcbiAgICAgICAgZm9yKGkgPSAwLCBpbGVuID0gdGlja3MubGVuZ3RoOyBpIDwgaWxlbjsgKytpKXtcbiAgICAgICAgICAgIHRpY2sgPSB0aWNrc1tpXTtcbiAgICAgICAgICAgIHRpY2subGFiZWwgPSB0aGlzLl90aWNrRm9ybWF0RnVuY3Rpb24odGljay52YWx1ZSwgaSwgdGlja3MpO1xuICAgICAgICB9XG4gICAgfVxuIGdldERlY2ltYWxGb3JWYWx1ZSh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdmFsdWUgPT09IG51bGwgPyBOYU4gOiAodmFsdWUgLSB0aGlzLm1pbikgLyAodGhpcy5tYXggLSB0aGlzLm1pbik7XG4gICAgfVxuIGdldFBpeGVsRm9yVmFsdWUodmFsdWUpIHtcbiAgICAgICAgY29uc3Qgb2Zmc2V0cyA9IHRoaXMuX29mZnNldHM7XG4gICAgICAgIGNvbnN0IHBvcyA9IHRoaXMuZ2V0RGVjaW1hbEZvclZhbHVlKHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGl4ZWxGb3JEZWNpbWFsKChvZmZzZXRzLnN0YXJ0ICsgcG9zKSAqIG9mZnNldHMuZmFjdG9yKTtcbiAgICB9XG4gZ2V0VmFsdWVGb3JQaXhlbChwaXhlbCkge1xuICAgICAgICBjb25zdCBvZmZzZXRzID0gdGhpcy5fb2Zmc2V0cztcbiAgICAgICAgY29uc3QgcG9zID0gdGhpcy5nZXREZWNpbWFsRm9yUGl4ZWwocGl4ZWwpIC8gb2Zmc2V0cy5mYWN0b3IgLSBvZmZzZXRzLmVuZDtcbiAgICAgICAgcmV0dXJuIHRoaXMubWluICsgcG9zICogKHRoaXMubWF4IC0gdGhpcy5taW4pO1xuICAgIH1cbiBfZ2V0TGFiZWxTaXplKGxhYmVsKSB7XG4gICAgICAgIGNvbnN0IHRpY2tzT3B0cyA9IHRoaXMub3B0aW9ucy50aWNrcztcbiAgICAgICAgY29uc3QgdGlja0xhYmVsV2lkdGggPSB0aGlzLmN0eC5tZWFzdXJlVGV4dChsYWJlbCkud2lkdGg7XG4gICAgICAgIGNvbnN0IGFuZ2xlID0gdG9SYWRpYW5zKHRoaXMuaXNIb3Jpem9udGFsKCkgPyB0aWNrc09wdHMubWF4Um90YXRpb24gOiB0aWNrc09wdHMubWluUm90YXRpb24pO1xuICAgICAgICBjb25zdCBjb3NSb3RhdGlvbiA9IE1hdGguY29zKGFuZ2xlKTtcbiAgICAgICAgY29uc3Qgc2luUm90YXRpb24gPSBNYXRoLnNpbihhbmdsZSk7XG4gICAgICAgIGNvbnN0IHRpY2tGb250U2l6ZSA9IHRoaXMuX3Jlc29sdmVUaWNrRm9udE9wdGlvbnMoMCkuc2l6ZTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHc6IHRpY2tMYWJlbFdpZHRoICogY29zUm90YXRpb24gKyB0aWNrRm9udFNpemUgKiBzaW5Sb3RhdGlvbixcbiAgICAgICAgICAgIGg6IHRpY2tMYWJlbFdpZHRoICogc2luUm90YXRpb24gKyB0aWNrRm9udFNpemUgKiBjb3NSb3RhdGlvblxuICAgICAgICB9O1xuICAgIH1cbiBfZ2V0TGFiZWxDYXBhY2l0eShleGFtcGxlVGltZSkge1xuICAgICAgICBjb25zdCB0aW1lT3B0cyA9IHRoaXMub3B0aW9ucy50aW1lO1xuICAgICAgICBjb25zdCBkaXNwbGF5Rm9ybWF0cyA9IHRpbWVPcHRzLmRpc3BsYXlGb3JtYXRzO1xuICAgICAgICBjb25zdCBmb3JtYXQgPSBkaXNwbGF5Rm9ybWF0c1t0aW1lT3B0cy51bml0XSB8fCBkaXNwbGF5Rm9ybWF0cy5taWxsaXNlY29uZDtcbiAgICAgICAgY29uc3QgZXhhbXBsZUxhYmVsID0gdGhpcy5fdGlja0Zvcm1hdEZ1bmN0aW9uKGV4YW1wbGVUaW1lLCAwLCB0aWNrc0Zyb21UaW1lc3RhbXBzKHRoaXMsIFtcbiAgICAgICAgICAgIGV4YW1wbGVUaW1lXG4gICAgICAgIF0sIHRoaXMuX21ham9yVW5pdCksIGZvcm1hdCk7XG4gICAgICAgIGNvbnN0IHNpemUgPSB0aGlzLl9nZXRMYWJlbFNpemUoZXhhbXBsZUxhYmVsKTtcbiAgICAgICAgY29uc3QgY2FwYWNpdHkgPSBNYXRoLmZsb29yKHRoaXMuaXNIb3Jpem9udGFsKCkgPyB0aGlzLndpZHRoIC8gc2l6ZS53IDogdGhpcy5oZWlnaHQgLyBzaXplLmgpIC0gMTtcbiAgICAgICAgcmV0dXJuIGNhcGFjaXR5ID4gMCA/IGNhcGFjaXR5IDogMTtcbiAgICB9XG4gZ2V0RGF0YVRpbWVzdGFtcHMoKSB7XG4gICAgICAgIGxldCB0aW1lc3RhbXBzID0gdGhpcy5fY2FjaGUuZGF0YSB8fCBbXTtcbiAgICAgICAgbGV0IGksIGlsZW47XG4gICAgICAgIGlmICh0aW1lc3RhbXBzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIHRpbWVzdGFtcHM7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbWV0YXMgPSB0aGlzLmdldE1hdGNoaW5nVmlzaWJsZU1ldGFzKCk7XG4gICAgICAgIGlmICh0aGlzLl9ub3JtYWxpemVkICYmIG1ldGFzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlLmRhdGEgPSBtZXRhc1swXS5jb250cm9sbGVyLmdldEFsbFBhcnNlZFZhbHVlcyh0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IoaSA9IDAsIGlsZW4gPSBtZXRhcy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpe1xuICAgICAgICAgICAgdGltZXN0YW1wcyA9IHRpbWVzdGFtcHMuY29uY2F0KG1ldGFzW2ldLmNvbnRyb2xsZXIuZ2V0QWxsUGFyc2VkVmFsdWVzKHRoaXMpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fY2FjaGUuZGF0YSA9IHRoaXMubm9ybWFsaXplKHRpbWVzdGFtcHMpO1xuICAgIH1cbiBnZXRMYWJlbFRpbWVzdGFtcHMoKSB7XG4gICAgICAgIGNvbnN0IHRpbWVzdGFtcHMgPSB0aGlzLl9jYWNoZS5sYWJlbHMgfHwgW107XG4gICAgICAgIGxldCBpLCBpbGVuO1xuICAgICAgICBpZiAodGltZXN0YW1wcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aW1lc3RhbXBzO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGxhYmVscyA9IHRoaXMuZ2V0TGFiZWxzKCk7XG4gICAgICAgIGZvcihpID0gMCwgaWxlbiA9IGxhYmVscy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpe1xuICAgICAgICAgICAgdGltZXN0YW1wcy5wdXNoKHBhcnNlKHRoaXMsIGxhYmVsc1tpXSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9jYWNoZS5sYWJlbHMgPSB0aGlzLl9ub3JtYWxpemVkID8gdGltZXN0YW1wcyA6IHRoaXMubm9ybWFsaXplKHRpbWVzdGFtcHMpO1xuICAgIH1cbiBub3JtYWxpemUodmFsdWVzKSB7XG4gICAgICAgIHJldHVybiBfYXJyYXlVbmlxdWUodmFsdWVzLnNvcnQoc29ydGVyKSk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBpbnRlcnBvbGF0ZSh0YWJsZSwgdmFsLCByZXZlcnNlKSB7XG4gICAgbGV0IGxvID0gMDtcbiAgICBsZXQgaGkgPSB0YWJsZS5sZW5ndGggLSAxO1xuICAgIGxldCBwcmV2U291cmNlLCBuZXh0U291cmNlLCBwcmV2VGFyZ2V0LCBuZXh0VGFyZ2V0O1xuICAgIGlmIChyZXZlcnNlKSB7XG4gICAgICAgIGlmICh2YWwgPj0gdGFibGVbbG9dLnBvcyAmJiB2YWwgPD0gdGFibGVbaGldLnBvcykge1xuICAgICAgICAgICAgKHsgbG8gLCBoaSAgfSA9IF9sb29rdXBCeUtleSh0YWJsZSwgJ3BvcycsIHZhbCkpO1xuICAgICAgICB9XG4gICAgICAgICh7IHBvczogcHJldlNvdXJjZSAsIHRpbWU6IHByZXZUYXJnZXQgIH0gPSB0YWJsZVtsb10pO1xuICAgICAgICAoeyBwb3M6IG5leHRTb3VyY2UgLCB0aW1lOiBuZXh0VGFyZ2V0ICB9ID0gdGFibGVbaGldKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBpZiAodmFsID49IHRhYmxlW2xvXS50aW1lICYmIHZhbCA8PSB0YWJsZVtoaV0udGltZSkge1xuICAgICAgICAgICAgKHsgbG8gLCBoaSAgfSA9IF9sb29rdXBCeUtleSh0YWJsZSwgJ3RpbWUnLCB2YWwpKTtcbiAgICAgICAgfVxuICAgICAgICAoeyB0aW1lOiBwcmV2U291cmNlICwgcG9zOiBwcmV2VGFyZ2V0ICB9ID0gdGFibGVbbG9dKTtcbiAgICAgICAgKHsgdGltZTogbmV4dFNvdXJjZSAsIHBvczogbmV4dFRhcmdldCAgfSA9IHRhYmxlW2hpXSk7XG4gICAgfVxuICAgIGNvbnN0IHNwYW4gPSBuZXh0U291cmNlIC0gcHJldlNvdXJjZTtcbiAgICByZXR1cm4gc3BhbiA/IHByZXZUYXJnZXQgKyAobmV4dFRhcmdldCAtIHByZXZUYXJnZXQpICogKHZhbCAtIHByZXZTb3VyY2UpIC8gc3BhbiA6IHByZXZUYXJnZXQ7XG59XG5jbGFzcyBUaW1lU2VyaWVzU2NhbGUgZXh0ZW5kcyBUaW1lU2NhbGUge1xuICAgIHN0YXRpYyBpZCA9ICd0aW1lc2VyaWVzJztcbiBzdGF0aWMgZGVmYXVsdHMgPSBUaW1lU2NhbGUuZGVmYXVsdHM7XG4gY29uc3RydWN0b3IocHJvcHMpe1xuICAgICAgICBzdXBlcihwcm9wcyk7XG4gICAgICAgICB0aGlzLl90YWJsZSA9IFtdO1xuICAgICAgICAgdGhpcy5fbWluUG9zID0gdW5kZWZpbmVkO1xuICAgICAgICAgdGhpcy5fdGFibGVSYW5nZSA9IHVuZGVmaW5lZDtcbiAgICB9XG4gaW5pdE9mZnNldHMoKSB7XG4gICAgICAgIGNvbnN0IHRpbWVzdGFtcHMgPSB0aGlzLl9nZXRUaW1lc3RhbXBzRm9yVGFibGUoKTtcbiAgICAgICAgY29uc3QgdGFibGUgPSB0aGlzLl90YWJsZSA9IHRoaXMuYnVpbGRMb29rdXBUYWJsZSh0aW1lc3RhbXBzKTtcbiAgICAgICAgdGhpcy5fbWluUG9zID0gaW50ZXJwb2xhdGUodGFibGUsIHRoaXMubWluKTtcbiAgICAgICAgdGhpcy5fdGFibGVSYW5nZSA9IGludGVycG9sYXRlKHRhYmxlLCB0aGlzLm1heCkgLSB0aGlzLl9taW5Qb3M7XG4gICAgICAgIHN1cGVyLmluaXRPZmZzZXRzKHRpbWVzdGFtcHMpO1xuICAgIH1cbiBidWlsZExvb2t1cFRhYmxlKHRpbWVzdGFtcHMpIHtcbiAgICAgICAgY29uc3QgeyBtaW4gLCBtYXggIH0gPSB0aGlzO1xuICAgICAgICBjb25zdCBpdGVtcyA9IFtdO1xuICAgICAgICBjb25zdCB0YWJsZSA9IFtdO1xuICAgICAgICBsZXQgaSwgaWxlbiwgcHJldiwgY3VyciwgbmV4dDtcbiAgICAgICAgZm9yKGkgPSAwLCBpbGVuID0gdGltZXN0YW1wcy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpe1xuICAgICAgICAgICAgY3VyciA9IHRpbWVzdGFtcHNbaV07XG4gICAgICAgICAgICBpZiAoY3VyciA+PSBtaW4gJiYgY3VyciA8PSBtYXgpIHtcbiAgICAgICAgICAgICAgICBpdGVtcy5wdXNoKGN1cnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChpdGVtcy5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgdGltZTogbWluLFxuICAgICAgICAgICAgICAgICAgICBwb3M6IDBcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgdGltZTogbWF4LFxuICAgICAgICAgICAgICAgICAgICBwb3M6IDFcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdO1xuICAgICAgICB9XG4gICAgICAgIGZvcihpID0gMCwgaWxlbiA9IGl0ZW1zLmxlbmd0aDsgaSA8IGlsZW47ICsraSl7XG4gICAgICAgICAgICBuZXh0ID0gaXRlbXNbaSArIDFdO1xuICAgICAgICAgICAgcHJldiA9IGl0ZW1zW2kgLSAxXTtcbiAgICAgICAgICAgIGN1cnIgPSBpdGVtc1tpXTtcbiAgICAgICAgICAgIGlmIChNYXRoLnJvdW5kKChuZXh0ICsgcHJldikgLyAyKSAhPT0gY3Vycikge1xuICAgICAgICAgICAgICAgIHRhYmxlLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICB0aW1lOiBjdXJyLFxuICAgICAgICAgICAgICAgICAgICBwb3M6IGkgLyAoaWxlbiAtIDEpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRhYmxlO1xuICAgIH1cbiBfZ2VuZXJhdGUoKSB7XG4gICAgICAgIGNvbnN0IG1pbiA9IHRoaXMubWluO1xuICAgICAgICBjb25zdCBtYXggPSB0aGlzLm1heDtcbiAgICAgICAgbGV0IHRpbWVzdGFtcHMgPSBzdXBlci5nZXREYXRhVGltZXN0YW1wcygpO1xuICAgICAgICBpZiAoIXRpbWVzdGFtcHMuaW5jbHVkZXMobWluKSB8fCAhdGltZXN0YW1wcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRpbWVzdGFtcHMuc3BsaWNlKDAsIDAsIG1pbik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aW1lc3RhbXBzLmluY2x1ZGVzKG1heCkgfHwgdGltZXN0YW1wcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIHRpbWVzdGFtcHMucHVzaChtYXgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aW1lc3RhbXBzLnNvcnQoKGEsIGIpPT5hIC0gYik7XG4gICAgfVxuIF9nZXRUaW1lc3RhbXBzRm9yVGFibGUoKSB7XG4gICAgICAgIGxldCB0aW1lc3RhbXBzID0gdGhpcy5fY2FjaGUuYWxsIHx8IFtdO1xuICAgICAgICBpZiAodGltZXN0YW1wcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aW1lc3RhbXBzO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmdldERhdGFUaW1lc3RhbXBzKCk7XG4gICAgICAgIGNvbnN0IGxhYmVsID0gdGhpcy5nZXRMYWJlbFRpbWVzdGFtcHMoKTtcbiAgICAgICAgaWYgKGRhdGEubGVuZ3RoICYmIGxhYmVsLmxlbmd0aCkge1xuICAgICAgICAgICAgdGltZXN0YW1wcyA9IHRoaXMubm9ybWFsaXplKGRhdGEuY29uY2F0KGxhYmVsKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aW1lc3RhbXBzID0gZGF0YS5sZW5ndGggPyBkYXRhIDogbGFiZWw7XG4gICAgICAgIH1cbiAgICAgICAgdGltZXN0YW1wcyA9IHRoaXMuX2NhY2hlLmFsbCA9IHRpbWVzdGFtcHM7XG4gICAgICAgIHJldHVybiB0aW1lc3RhbXBzO1xuICAgIH1cbiBnZXREZWNpbWFsRm9yVmFsdWUodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIChpbnRlcnBvbGF0ZSh0aGlzLl90YWJsZSwgdmFsdWUpIC0gdGhpcy5fbWluUG9zKSAvIHRoaXMuX3RhYmxlUmFuZ2U7XG4gICAgfVxuIGdldFZhbHVlRm9yUGl4ZWwocGl4ZWwpIHtcbiAgICAgICAgY29uc3Qgb2Zmc2V0cyA9IHRoaXMuX29mZnNldHM7XG4gICAgICAgIGNvbnN0IGRlY2ltYWwgPSB0aGlzLmdldERlY2ltYWxGb3JQaXhlbChwaXhlbCkgLyBvZmZzZXRzLmZhY3RvciAtIG9mZnNldHMuZW5kO1xuICAgICAgICByZXR1cm4gaW50ZXJwb2xhdGUodGhpcy5fdGFibGUsIGRlY2ltYWwgKiB0aGlzLl90YWJsZVJhbmdlICsgdGhpcy5fbWluUG9zLCB0cnVlKTtcbiAgICB9XG59XG5cbnZhciBzY2FsZXMgPSAvKiNfX1BVUkVfXyovT2JqZWN0LmZyZWV6ZSh7XG5fX3Byb3RvX186IG51bGwsXG5DYXRlZ29yeVNjYWxlOiBDYXRlZ29yeVNjYWxlLFxuTGluZWFyU2NhbGU6IExpbmVhclNjYWxlLFxuTG9nYXJpdGhtaWNTY2FsZTogTG9nYXJpdGhtaWNTY2FsZSxcblJhZGlhbExpbmVhclNjYWxlOiBSYWRpYWxMaW5lYXJTY2FsZSxcblRpbWVTY2FsZTogVGltZVNjYWxlLFxuVGltZVNlcmllc1NjYWxlOiBUaW1lU2VyaWVzU2NhbGVcbn0pO1xuXG5jb25zdCByZWdpc3RlcmFibGVzID0gW1xuICAgIGNvbnRyb2xsZXJzLFxuICAgIGVsZW1lbnRzLFxuICAgIHBsdWdpbnMsXG4gICAgc2NhbGVzXG5dO1xuXG5leHBvcnQgeyBBbmltYXRpb24sIEFuaW1hdGlvbnMsIEFyY0VsZW1lbnQsIEJhckNvbnRyb2xsZXIsIEJhckVsZW1lbnQsIEJhc2VQbGF0Zm9ybSwgQmFzaWNQbGF0Zm9ybSwgQnViYmxlQ29udHJvbGxlciwgQ2F0ZWdvcnlTY2FsZSwgQ2hhcnQsIHBsdWdpbl9jb2xvcnMgYXMgQ29sb3JzLCBEYXRhc2V0Q29udHJvbGxlciwgcGx1Z2luX2RlY2ltYXRpb24gYXMgRGVjaW1hdGlvbiwgRG9tUGxhdGZvcm0sIERvdWdobnV0Q29udHJvbGxlciwgRWxlbWVudCwgaW5kZXggYXMgRmlsbGVyLCBJbnRlcmFjdGlvbiwgcGx1Z2luX2xlZ2VuZCBhcyBMZWdlbmQsIExpbmVDb250cm9sbGVyLCBMaW5lRWxlbWVudCwgTGluZWFyU2NhbGUsIExvZ2FyaXRobWljU2NhbGUsIFBpZUNvbnRyb2xsZXIsIFBvaW50RWxlbWVudCwgUG9sYXJBcmVhQ29udHJvbGxlciwgUmFkYXJDb250cm9sbGVyLCBSYWRpYWxMaW5lYXJTY2FsZSwgU2NhbGUsIFNjYXR0ZXJDb250cm9sbGVyLCBwbHVnaW5fc3VidGl0bGUgYXMgU3ViVGl0bGUsIFRpY2tzLCBUaW1lU2NhbGUsIFRpbWVTZXJpZXNTY2FsZSwgcGx1Z2luX3RpdGxlIGFzIFRpdGxlLCBwbHVnaW5fdG9vbHRpcCBhcyBUb29sdGlwLCBhZGFwdGVycyBhcyBfYWRhcHRlcnMsIF9kZXRlY3RQbGF0Zm9ybSwgYW5pbWF0b3IsIGNvbnRyb2xsZXJzLCBkZWZhdWx0cywgZWxlbWVudHMsIGxheW91dHMsIHBsdWdpbnMsIHJlZ2lzdGVyYWJsZXMsIHJlZ2lzdHJ5LCBzY2FsZXMgfTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNoYXJ0LmpzLm1hcFxuIiwiaW1wb3J0IHtDaGFydCwgcmVnaXN0ZXJhYmxlc30gZnJvbSAnLi4vZGlzdC9jaGFydC5qcyc7XG5cbkNoYXJ0LnJlZ2lzdGVyKC4uLnJlZ2lzdGVyYWJsZXMpO1xuXG5leHBvcnQgKiBmcm9tICcuLi9kaXN0L2NoYXJ0LmpzJztcbmV4cG9ydCBkZWZhdWx0IENoYXJ0O1xuIiwiLyohXG4gKiBjaGFydGpzLXBsdWdpbi1kYXRhbGFiZWxzIHYyLjIuMFxuICogaHR0cHM6Ly9jaGFydGpzLXBsdWdpbi1kYXRhbGFiZWxzLm5ldGxpZnkuYXBwXG4gKiAoYykgMjAxNy0yMDIyIGNoYXJ0anMtcGx1Z2luLWRhdGFsYWJlbHMgY29udHJpYnV0b3JzXG4gKiBSZWxlYXNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2VcbiAqL1xuaW1wb3J0IHsgaXNOdWxsT3JVbmRlZiwgbWVyZ2UsIHRvRm9udCwgcmVzb2x2ZSwgdG9QYWRkaW5nLCB2YWx1ZU9yRGVmYXVsdCwgY2FsbGJhY2ssIGlzT2JqZWN0LCBlYWNoIH0gZnJvbSAnY2hhcnQuanMvaGVscGVycyc7XG5pbXBvcnQgeyBkZWZhdWx0cyBhcyBkZWZhdWx0cyQxLCBBcmNFbGVtZW50LCBQb2ludEVsZW1lbnQsIEJhckVsZW1lbnQgfSBmcm9tICdjaGFydC5qcyc7XG5cbnZhciBkZXZpY2VQaXhlbFJhdGlvID0gKGZ1bmN0aW9uKCkge1xuICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZiAod2luZG93LmRldmljZVBpeGVsUmF0aW8pIHtcbiAgICAgIHJldHVybiB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbiAgICB9XG5cbiAgICAvLyBkZXZpY2VQaXhlbFJhdGlvIGlzIHVuZGVmaW5lZCBvbiBJRTEwXG4gICAgLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIwMjA0MTgwLzg4Mzc4ODdcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9jaGFydGpzLXBsdWdpbi1kYXRhbGFiZWxzL2lzc3Vlcy84NVxuICAgIHZhciBzY3JlZW4gPSB3aW5kb3cuc2NyZWVuO1xuICAgIGlmIChzY3JlZW4pIHtcbiAgICAgIHJldHVybiAoc2NyZWVuLmRldmljZVhEUEkgfHwgMSkgLyAoc2NyZWVuLmxvZ2ljYWxYRFBJIHx8IDEpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAxO1xufSgpKTtcblxudmFyIHV0aWxzID0ge1xuICAvLyBAdG9kbyBtb3ZlIHRoaXMgaW4gQ2hhcnQuaGVscGVycy50b1RleHRMaW5lc1xuICB0b1RleHRMaW5lczogZnVuY3Rpb24oaW5wdXRzKSB7XG4gICAgdmFyIGxpbmVzID0gW107XG4gICAgdmFyIGlucHV0O1xuXG4gICAgaW5wdXRzID0gW10uY29uY2F0KGlucHV0cyk7XG4gICAgd2hpbGUgKGlucHV0cy5sZW5ndGgpIHtcbiAgICAgIGlucHV0ID0gaW5wdXRzLnBvcCgpO1xuICAgICAgaWYgKHR5cGVvZiBpbnB1dCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgbGluZXMudW5zaGlmdC5hcHBseShsaW5lcywgaW5wdXQuc3BsaXQoJ1xcbicpKTtcbiAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShpbnB1dCkpIHtcbiAgICAgICAgaW5wdXRzLnB1c2guYXBwbHkoaW5wdXRzLCBpbnB1dCk7XG4gICAgICB9IGVsc2UgaWYgKCFpc051bGxPclVuZGVmKGlucHV0cykpIHtcbiAgICAgICAgbGluZXMudW5zaGlmdCgnJyArIGlucHV0KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbGluZXM7XG4gIH0sXG5cbiAgLy8gQHRvZG8gbW92ZSB0aGlzIGluIENoYXJ0LmhlbHBlcnMuY2FudmFzLnRleHRTaXplXG4gIC8vIEB0b2RvIGNhY2hlIGNhbGxzIG9mIG1lYXN1cmVUZXh0IGlmIGZvbnQgZG9lc24ndCBjaGFuZ2U/IVxuICB0ZXh0U2l6ZTogZnVuY3Rpb24oY3R4LCBsaW5lcywgZm9udCkge1xuICAgIHZhciBpdGVtcyA9IFtdLmNvbmNhdChsaW5lcyk7XG4gICAgdmFyIGlsZW4gPSBpdGVtcy5sZW5ndGg7XG4gICAgdmFyIHByZXYgPSBjdHguZm9udDtcbiAgICB2YXIgd2lkdGggPSAwO1xuICAgIHZhciBpO1xuXG4gICAgY3R4LmZvbnQgPSBmb250LnN0cmluZztcblxuICAgIGZvciAoaSA9IDA7IGkgPCBpbGVuOyArK2kpIHtcbiAgICAgIHdpZHRoID0gTWF0aC5tYXgoY3R4Lm1lYXN1cmVUZXh0KGl0ZW1zW2ldKS53aWR0aCwgd2lkdGgpO1xuICAgIH1cblxuICAgIGN0eC5mb250ID0gcHJldjtcblxuICAgIHJldHVybiB7XG4gICAgICBoZWlnaHQ6IGlsZW4gKiBmb250LmxpbmVIZWlnaHQsXG4gICAgICB3aWR0aDogd2lkdGhcbiAgICB9O1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHZhbHVlIGJvdW5kZWQgYnkgbWluIGFuZCBtYXguIFRoaXMgaXMgZXF1aXZhbGVudCB0byBtYXgobWluLCBtaW4odmFsdWUsIG1heCkpLlxuICAgKiBAdG9kbyBtb3ZlIHRoaXMgbWV0aG9kIGluIENoYXJ0LmhlbHBlcnMuYm91bmRcbiAgICogaHR0cHM6Ly9kb2MucXQuaW8vcXQtNS9xdGdsb2JhbC5odG1sI3FCb3VuZFxuICAgKi9cbiAgYm91bmQ6IGZ1bmN0aW9uKG1pbiwgdmFsdWUsIG1heCkge1xuICAgIHJldHVybiBNYXRoLm1heChtaW4sIE1hdGgubWluKHZhbHVlLCBtYXgpKTtcbiAgfSxcblxuICAvKipcbiAgICogUmV0dXJucyBhbiBhcnJheSBvZiBwYWlyIFt2YWx1ZSwgc3RhdGVdIHdoZXJlIHN0YXRlIGlzOlxuICAgKiAqIC0xOiB2YWx1ZSBpcyBvbmx5IGluIGEwIChyZW1vdmVkKVxuICAgKiAqICAxOiB2YWx1ZSBpcyBvbmx5IGluIGExIChhZGRlZClcbiAgICovXG4gIGFycmF5RGlmZjogZnVuY3Rpb24oYTAsIGExKSB7XG4gICAgdmFyIHByZXYgPSBhMC5zbGljZSgpO1xuICAgIHZhciB1cGRhdGVzID0gW107XG4gICAgdmFyIGksIGosIGlsZW4sIHY7XG5cbiAgICBmb3IgKGkgPSAwLCBpbGVuID0gYTEubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgICB2ID0gYTFbaV07XG4gICAgICBqID0gcHJldi5pbmRleE9mKHYpO1xuXG4gICAgICBpZiAoaiA9PT0gLTEpIHtcbiAgICAgICAgdXBkYXRlcy5wdXNoKFt2LCAxXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwcmV2LnNwbGljZShqLCAxKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGkgPSAwLCBpbGVuID0gcHJldi5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICAgIHVwZGF0ZXMucHVzaChbcHJldltpXSwgLTFdKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdXBkYXRlcztcbiAgfSxcblxuICAvKipcbiAgICogaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvY2hhcnRqcy1wbHVnaW4tZGF0YWxhYmVscy9pc3N1ZXMvNzBcbiAgICovXG4gIHJhc3Rlcml6ZTogZnVuY3Rpb24odikge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKHYgKiBkZXZpY2VQaXhlbFJhdGlvKSAvIGRldmljZVBpeGVsUmF0aW87XG4gIH1cbn07XG5cbmZ1bmN0aW9uIG9yaWVudChwb2ludCwgb3JpZ2luKSB7XG4gIHZhciB4MCA9IG9yaWdpbi54O1xuICB2YXIgeTAgPSBvcmlnaW4ueTtcblxuICBpZiAoeDAgPT09IG51bGwpIHtcbiAgICByZXR1cm4ge3g6IDAsIHk6IC0xfTtcbiAgfVxuICBpZiAoeTAgPT09IG51bGwpIHtcbiAgICByZXR1cm4ge3g6IDEsIHk6IDB9O1xuICB9XG5cbiAgdmFyIGR4ID0gcG9pbnQueCAtIHgwO1xuICB2YXIgZHkgPSBwb2ludC55IC0geTA7XG4gIHZhciBsbiA9IE1hdGguc3FydChkeCAqIGR4ICsgZHkgKiBkeSk7XG5cbiAgcmV0dXJuIHtcbiAgICB4OiBsbiA/IGR4IC8gbG4gOiAwLFxuICAgIHk6IGxuID8gZHkgLyBsbiA6IC0xXG4gIH07XG59XG5cbmZ1bmN0aW9uIGFsaWduZWQoeCwgeSwgdngsIHZ5LCBhbGlnbikge1xuICBzd2l0Y2ggKGFsaWduKSB7XG4gIGNhc2UgJ2NlbnRlcic6XG4gICAgdnggPSB2eSA9IDA7XG4gICAgYnJlYWs7XG4gIGNhc2UgJ2JvdHRvbSc6XG4gICAgdnggPSAwO1xuICAgIHZ5ID0gMTtcbiAgICBicmVhaztcbiAgY2FzZSAncmlnaHQnOlxuICAgIHZ4ID0gMTtcbiAgICB2eSA9IDA7XG4gICAgYnJlYWs7XG4gIGNhc2UgJ2xlZnQnOlxuICAgIHZ4ID0gLTE7XG4gICAgdnkgPSAwO1xuICAgIGJyZWFrO1xuICBjYXNlICd0b3AnOlxuICAgIHZ4ID0gMDtcbiAgICB2eSA9IC0xO1xuICAgIGJyZWFrO1xuICBjYXNlICdzdGFydCc6XG4gICAgdnggPSAtdng7XG4gICAgdnkgPSAtdnk7XG4gICAgYnJlYWs7XG4gIGNhc2UgJ2VuZCc6XG4gICAgLy8ga2VlcCBuYXR1cmFsIG9yaWVudGF0aW9uXG4gICAgYnJlYWs7XG4gIGRlZmF1bHQ6XG4gICAgLy8gY2xvY2t3aXNlIHJvdGF0aW9uIChpbiBkZWdyZWUpXG4gICAgYWxpZ24gKj0gKE1hdGguUEkgLyAxODApO1xuICAgIHZ4ID0gTWF0aC5jb3MoYWxpZ24pO1xuICAgIHZ5ID0gTWF0aC5zaW4oYWxpZ24pO1xuICAgIGJyZWFrO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB4OiB4LFxuICAgIHk6IHksXG4gICAgdng6IHZ4LFxuICAgIHZ5OiB2eVxuICB9O1xufVxuXG4vLyBMaW5lIGNsaXBwaW5nIChDb2hlbuKAk1N1dGhlcmxhbmQgYWxnb3JpdGhtKVxuLy8gaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ29oZW7igJNTdXRoZXJsYW5kX2FsZ29yaXRobVxuXG52YXIgUl9JTlNJREUgPSAwO1xudmFyIFJfTEVGVCA9IDE7XG52YXIgUl9SSUdIVCA9IDI7XG52YXIgUl9CT1RUT00gPSA0O1xudmFyIFJfVE9QID0gODtcblxuZnVuY3Rpb24gcmVnaW9uKHgsIHksIHJlY3QpIHtcbiAgdmFyIHJlcyA9IFJfSU5TSURFO1xuXG4gIGlmICh4IDwgcmVjdC5sZWZ0KSB7XG4gICAgcmVzIHw9IFJfTEVGVDtcbiAgfSBlbHNlIGlmICh4ID4gcmVjdC5yaWdodCkge1xuICAgIHJlcyB8PSBSX1JJR0hUO1xuICB9XG4gIGlmICh5IDwgcmVjdC50b3ApIHtcbiAgICByZXMgfD0gUl9UT1A7XG4gIH0gZWxzZSBpZiAoeSA+IHJlY3QuYm90dG9tKSB7XG4gICAgcmVzIHw9IFJfQk9UVE9NO1xuICB9XG5cbiAgcmV0dXJuIHJlcztcbn1cblxuZnVuY3Rpb24gY2xpcHBlZChzZWdtZW50LCBhcmVhKSB7XG4gIHZhciB4MCA9IHNlZ21lbnQueDA7XG4gIHZhciB5MCA9IHNlZ21lbnQueTA7XG4gIHZhciB4MSA9IHNlZ21lbnQueDE7XG4gIHZhciB5MSA9IHNlZ21lbnQueTE7XG4gIHZhciByMCA9IHJlZ2lvbih4MCwgeTAsIGFyZWEpO1xuICB2YXIgcjEgPSByZWdpb24oeDEsIHkxLCBhcmVhKTtcbiAgdmFyIHIsIHgsIHk7XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnN0YW50LWNvbmRpdGlvblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIGlmICghKHIwIHwgcjEpIHx8IChyMCAmIHIxKSkge1xuICAgICAgLy8gYm90aCBwb2ludHMgaW5zaWRlIG9yIG9uIHRoZSBzYW1lIHNpZGU6IG5vIGNsaXBwaW5nXG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICAvLyBhdCBsZWFzdCBvbmUgcG9pbnQgaXMgb3V0c2lkZVxuICAgIHIgPSByMCB8fCByMTtcblxuICAgIGlmIChyICYgUl9UT1ApIHtcbiAgICAgIHggPSB4MCArICh4MSAtIHgwKSAqIChhcmVhLnRvcCAtIHkwKSAvICh5MSAtIHkwKTtcbiAgICAgIHkgPSBhcmVhLnRvcDtcbiAgICB9IGVsc2UgaWYgKHIgJiBSX0JPVFRPTSkge1xuICAgICAgeCA9IHgwICsgKHgxIC0geDApICogKGFyZWEuYm90dG9tIC0geTApIC8gKHkxIC0geTApO1xuICAgICAgeSA9IGFyZWEuYm90dG9tO1xuICAgIH0gZWxzZSBpZiAociAmIFJfUklHSFQpIHtcbiAgICAgIHkgPSB5MCArICh5MSAtIHkwKSAqIChhcmVhLnJpZ2h0IC0geDApIC8gKHgxIC0geDApO1xuICAgICAgeCA9IGFyZWEucmlnaHQ7XG4gICAgfSBlbHNlIGlmIChyICYgUl9MRUZUKSB7XG4gICAgICB5ID0geTAgKyAoeTEgLSB5MCkgKiAoYXJlYS5sZWZ0IC0geDApIC8gKHgxIC0geDApO1xuICAgICAgeCA9IGFyZWEubGVmdDtcbiAgICB9XG5cbiAgICBpZiAociA9PT0gcjApIHtcbiAgICAgIHgwID0geDtcbiAgICAgIHkwID0geTtcbiAgICAgIHIwID0gcmVnaW9uKHgwLCB5MCwgYXJlYSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHgxID0geDtcbiAgICAgIHkxID0geTtcbiAgICAgIHIxID0gcmVnaW9uKHgxLCB5MSwgYXJlYSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB4MDogeDAsXG4gICAgeDE6IHgxLFxuICAgIHkwOiB5MCxcbiAgICB5MTogeTFcbiAgfTtcbn1cblxuZnVuY3Rpb24gY29tcHV0ZSQxKHJhbmdlLCBjb25maWcpIHtcbiAgdmFyIGFuY2hvciA9IGNvbmZpZy5hbmNob3I7XG4gIHZhciBzZWdtZW50ID0gcmFuZ2U7XG4gIHZhciB4LCB5O1xuXG4gIGlmIChjb25maWcuY2xhbXApIHtcbiAgICBzZWdtZW50ID0gY2xpcHBlZChzZWdtZW50LCBjb25maWcuYXJlYSk7XG4gIH1cblxuICBpZiAoYW5jaG9yID09PSAnc3RhcnQnKSB7XG4gICAgeCA9IHNlZ21lbnQueDA7XG4gICAgeSA9IHNlZ21lbnQueTA7XG4gIH0gZWxzZSBpZiAoYW5jaG9yID09PSAnZW5kJykge1xuICAgIHggPSBzZWdtZW50LngxO1xuICAgIHkgPSBzZWdtZW50LnkxO1xuICB9IGVsc2Uge1xuICAgIHggPSAoc2VnbWVudC54MCArIHNlZ21lbnQueDEpIC8gMjtcbiAgICB5ID0gKHNlZ21lbnQueTAgKyBzZWdtZW50LnkxKSAvIDI7XG4gIH1cblxuICByZXR1cm4gYWxpZ25lZCh4LCB5LCByYW5nZS52eCwgcmFuZ2UudnksIGNvbmZpZy5hbGlnbik7XG59XG5cbnZhciBwb3NpdGlvbmVycyA9IHtcbiAgYXJjOiBmdW5jdGlvbihlbCwgY29uZmlnKSB7XG4gICAgdmFyIGFuZ2xlID0gKGVsLnN0YXJ0QW5nbGUgKyBlbC5lbmRBbmdsZSkgLyAyO1xuICAgIHZhciB2eCA9IE1hdGguY29zKGFuZ2xlKTtcbiAgICB2YXIgdnkgPSBNYXRoLnNpbihhbmdsZSk7XG4gICAgdmFyIHIwID0gZWwuaW5uZXJSYWRpdXM7XG4gICAgdmFyIHIxID0gZWwub3V0ZXJSYWRpdXM7XG5cbiAgICByZXR1cm4gY29tcHV0ZSQxKHtcbiAgICAgIHgwOiBlbC54ICsgdnggKiByMCxcbiAgICAgIHkwOiBlbC55ICsgdnkgKiByMCxcbiAgICAgIHgxOiBlbC54ICsgdnggKiByMSxcbiAgICAgIHkxOiBlbC55ICsgdnkgKiByMSxcbiAgICAgIHZ4OiB2eCxcbiAgICAgIHZ5OiB2eVxuICAgIH0sIGNvbmZpZyk7XG4gIH0sXG5cbiAgcG9pbnQ6IGZ1bmN0aW9uKGVsLCBjb25maWcpIHtcbiAgICB2YXIgdiA9IG9yaWVudChlbCwgY29uZmlnLm9yaWdpbik7XG4gICAgdmFyIHJ4ID0gdi54ICogZWwub3B0aW9ucy5yYWRpdXM7XG4gICAgdmFyIHJ5ID0gdi55ICogZWwub3B0aW9ucy5yYWRpdXM7XG5cbiAgICByZXR1cm4gY29tcHV0ZSQxKHtcbiAgICAgIHgwOiBlbC54IC0gcngsXG4gICAgICB5MDogZWwueSAtIHJ5LFxuICAgICAgeDE6IGVsLnggKyByeCxcbiAgICAgIHkxOiBlbC55ICsgcnksXG4gICAgICB2eDogdi54LFxuICAgICAgdnk6IHYueVxuICAgIH0sIGNvbmZpZyk7XG4gIH0sXG5cbiAgYmFyOiBmdW5jdGlvbihlbCwgY29uZmlnKSB7XG4gICAgdmFyIHYgPSBvcmllbnQoZWwsIGNvbmZpZy5vcmlnaW4pO1xuICAgIHZhciB4ID0gZWwueDtcbiAgICB2YXIgeSA9IGVsLnk7XG4gICAgdmFyIHN4ID0gMDtcbiAgICB2YXIgc3kgPSAwO1xuXG4gICAgaWYgKGVsLmhvcml6b250YWwpIHtcbiAgICAgIHggPSBNYXRoLm1pbihlbC54LCBlbC5iYXNlKTtcbiAgICAgIHN4ID0gTWF0aC5hYnMoZWwuYmFzZSAtIGVsLngpO1xuICAgIH0gZWxzZSB7XG4gICAgICB5ID0gTWF0aC5taW4oZWwueSwgZWwuYmFzZSk7XG4gICAgICBzeSA9IE1hdGguYWJzKGVsLmJhc2UgLSBlbC55KTtcbiAgICB9XG5cbiAgICByZXR1cm4gY29tcHV0ZSQxKHtcbiAgICAgIHgwOiB4LFxuICAgICAgeTA6IHkgKyBzeSxcbiAgICAgIHgxOiB4ICsgc3gsXG4gICAgICB5MTogeSxcbiAgICAgIHZ4OiB2LngsXG4gICAgICB2eTogdi55XG4gICAgfSwgY29uZmlnKTtcbiAgfSxcblxuICBmYWxsYmFjazogZnVuY3Rpb24oZWwsIGNvbmZpZykge1xuICAgIHZhciB2ID0gb3JpZW50KGVsLCBjb25maWcub3JpZ2luKTtcblxuICAgIHJldHVybiBjb21wdXRlJDEoe1xuICAgICAgeDA6IGVsLngsXG4gICAgICB5MDogZWwueSxcbiAgICAgIHgxOiBlbC54ICsgKGVsLndpZHRoIHx8IDApLFxuICAgICAgeTE6IGVsLnkgKyAoZWwuaGVpZ2h0IHx8IDApLFxuICAgICAgdng6IHYueCxcbiAgICAgIHZ5OiB2LnlcbiAgICB9LCBjb25maWcpO1xuICB9XG59O1xuXG52YXIgcmFzdGVyaXplID0gdXRpbHMucmFzdGVyaXplO1xuXG5mdW5jdGlvbiBib3VuZGluZ1JlY3RzKG1vZGVsKSB7XG4gIHZhciBib3JkZXJXaWR0aCA9IG1vZGVsLmJvcmRlcldpZHRoIHx8IDA7XG4gIHZhciBwYWRkaW5nID0gbW9kZWwucGFkZGluZztcbiAgdmFyIHRoID0gbW9kZWwuc2l6ZS5oZWlnaHQ7XG4gIHZhciB0dyA9IG1vZGVsLnNpemUud2lkdGg7XG4gIHZhciB0eCA9IC10dyAvIDI7XG4gIHZhciB0eSA9IC10aCAvIDI7XG5cbiAgcmV0dXJuIHtcbiAgICBmcmFtZToge1xuICAgICAgeDogdHggLSBwYWRkaW5nLmxlZnQgLSBib3JkZXJXaWR0aCxcbiAgICAgIHk6IHR5IC0gcGFkZGluZy50b3AgLSBib3JkZXJXaWR0aCxcbiAgICAgIHc6IHR3ICsgcGFkZGluZy53aWR0aCArIGJvcmRlcldpZHRoICogMixcbiAgICAgIGg6IHRoICsgcGFkZGluZy5oZWlnaHQgKyBib3JkZXJXaWR0aCAqIDJcbiAgICB9LFxuICAgIHRleHQ6IHtcbiAgICAgIHg6IHR4LFxuICAgICAgeTogdHksXG4gICAgICB3OiB0dyxcbiAgICAgIGg6IHRoXG4gICAgfVxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRTY2FsZU9yaWdpbihlbCwgY29udGV4dCkge1xuICB2YXIgc2NhbGUgPSBjb250ZXh0LmNoYXJ0LmdldERhdGFzZXRNZXRhKGNvbnRleHQuZGF0YXNldEluZGV4KS52U2NhbGU7XG5cbiAgaWYgKCFzY2FsZSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKHNjYWxlLnhDZW50ZXIgIT09IHVuZGVmaW5lZCAmJiBzY2FsZS55Q2VudGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4ge3g6IHNjYWxlLnhDZW50ZXIsIHk6IHNjYWxlLnlDZW50ZXJ9O1xuICB9XG5cbiAgdmFyIHBpeGVsID0gc2NhbGUuZ2V0QmFzZVBpeGVsKCk7XG4gIHJldHVybiBlbC5ob3Jpem9udGFsID9cbiAgICB7eDogcGl4ZWwsIHk6IG51bGx9IDpcbiAgICB7eDogbnVsbCwgeTogcGl4ZWx9O1xufVxuXG5mdW5jdGlvbiBnZXRQb3NpdGlvbmVyKGVsKSB7XG4gIGlmIChlbCBpbnN0YW5jZW9mIEFyY0VsZW1lbnQpIHtcbiAgICByZXR1cm4gcG9zaXRpb25lcnMuYXJjO1xuICB9XG4gIGlmIChlbCBpbnN0YW5jZW9mIFBvaW50RWxlbWVudCkge1xuICAgIHJldHVybiBwb3NpdGlvbmVycy5wb2ludDtcbiAgfVxuICBpZiAoZWwgaW5zdGFuY2VvZiBCYXJFbGVtZW50KSB7XG4gICAgcmV0dXJuIHBvc2l0aW9uZXJzLmJhcjtcbiAgfVxuICByZXR1cm4gcG9zaXRpb25lcnMuZmFsbGJhY2s7XG59XG5cbmZ1bmN0aW9uIGRyYXdSb3VuZGVkUmVjdChjdHgsIHgsIHksIHcsIGgsIHJhZGl1cykge1xuICB2YXIgSEFMRl9QSSA9IE1hdGguUEkgLyAyO1xuXG4gIGlmIChyYWRpdXMpIHtcbiAgICB2YXIgciA9IE1hdGgubWluKHJhZGl1cywgaCAvIDIsIHcgLyAyKTtcbiAgICB2YXIgbGVmdCA9IHggKyByO1xuICAgIHZhciB0b3AgPSB5ICsgcjtcbiAgICB2YXIgcmlnaHQgPSB4ICsgdyAtIHI7XG4gICAgdmFyIGJvdHRvbSA9IHkgKyBoIC0gcjtcblxuICAgIGN0eC5tb3ZlVG8oeCwgdG9wKTtcbiAgICBpZiAobGVmdCA8IHJpZ2h0ICYmIHRvcCA8IGJvdHRvbSkge1xuICAgICAgY3R4LmFyYyhsZWZ0LCB0b3AsIHIsIC1NYXRoLlBJLCAtSEFMRl9QSSk7XG4gICAgICBjdHguYXJjKHJpZ2h0LCB0b3AsIHIsIC1IQUxGX1BJLCAwKTtcbiAgICAgIGN0eC5hcmMocmlnaHQsIGJvdHRvbSwgciwgMCwgSEFMRl9QSSk7XG4gICAgICBjdHguYXJjKGxlZnQsIGJvdHRvbSwgciwgSEFMRl9QSSwgTWF0aC5QSSk7XG4gICAgfSBlbHNlIGlmIChsZWZ0IDwgcmlnaHQpIHtcbiAgICAgIGN0eC5tb3ZlVG8obGVmdCwgeSk7XG4gICAgICBjdHguYXJjKHJpZ2h0LCB0b3AsIHIsIC1IQUxGX1BJLCBIQUxGX1BJKTtcbiAgICAgIGN0eC5hcmMobGVmdCwgdG9wLCByLCBIQUxGX1BJLCBNYXRoLlBJICsgSEFMRl9QSSk7XG4gICAgfSBlbHNlIGlmICh0b3AgPCBib3R0b20pIHtcbiAgICAgIGN0eC5hcmMobGVmdCwgdG9wLCByLCAtTWF0aC5QSSwgMCk7XG4gICAgICBjdHguYXJjKGxlZnQsIGJvdHRvbSwgciwgMCwgTWF0aC5QSSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGN0eC5hcmMobGVmdCwgdG9wLCByLCAtTWF0aC5QSSwgTWF0aC5QSSk7XG4gICAgfVxuICAgIGN0eC5jbG9zZVBhdGgoKTtcbiAgICBjdHgubW92ZVRvKHgsIHkpO1xuICB9IGVsc2Uge1xuICAgIGN0eC5yZWN0KHgsIHksIHcsIGgpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGRyYXdGcmFtZShjdHgsIHJlY3QsIG1vZGVsKSB7XG4gIHZhciBiZ0NvbG9yID0gbW9kZWwuYmFja2dyb3VuZENvbG9yO1xuICB2YXIgYm9yZGVyQ29sb3IgPSBtb2RlbC5ib3JkZXJDb2xvcjtcbiAgdmFyIGJvcmRlcldpZHRoID0gbW9kZWwuYm9yZGVyV2lkdGg7XG5cbiAgaWYgKCFiZ0NvbG9yICYmICghYm9yZGVyQ29sb3IgfHwgIWJvcmRlcldpZHRoKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGN0eC5iZWdpblBhdGgoKTtcblxuICBkcmF3Um91bmRlZFJlY3QoXG4gICAgY3R4LFxuICAgIHJhc3Rlcml6ZShyZWN0LngpICsgYm9yZGVyV2lkdGggLyAyLFxuICAgIHJhc3Rlcml6ZShyZWN0LnkpICsgYm9yZGVyV2lkdGggLyAyLFxuICAgIHJhc3Rlcml6ZShyZWN0LncpIC0gYm9yZGVyV2lkdGgsXG4gICAgcmFzdGVyaXplKHJlY3QuaCkgLSBib3JkZXJXaWR0aCxcbiAgICBtb2RlbC5ib3JkZXJSYWRpdXMpO1xuXG4gIGN0eC5jbG9zZVBhdGgoKTtcblxuICBpZiAoYmdDb2xvcikge1xuICAgIGN0eC5maWxsU3R5bGUgPSBiZ0NvbG9yO1xuICAgIGN0eC5maWxsKCk7XG4gIH1cblxuICBpZiAoYm9yZGVyQ29sb3IgJiYgYm9yZGVyV2lkdGgpIHtcbiAgICBjdHguc3Ryb2tlU3R5bGUgPSBib3JkZXJDb2xvcjtcbiAgICBjdHgubGluZVdpZHRoID0gYm9yZGVyV2lkdGg7XG4gICAgY3R4LmxpbmVKb2luID0gJ21pdGVyJztcbiAgICBjdHguc3Ryb2tlKCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gdGV4dEdlb21ldHJ5KHJlY3QsIGFsaWduLCBmb250KSB7XG4gIHZhciBoID0gZm9udC5saW5lSGVpZ2h0O1xuICB2YXIgdyA9IHJlY3QudztcbiAgdmFyIHggPSByZWN0Lng7XG4gIHZhciB5ID0gcmVjdC55ICsgaCAvIDI7XG5cbiAgaWYgKGFsaWduID09PSAnY2VudGVyJykge1xuICAgIHggKz0gdyAvIDI7XG4gIH0gZWxzZSBpZiAoYWxpZ24gPT09ICdlbmQnIHx8IGFsaWduID09PSAncmlnaHQnKSB7XG4gICAgeCArPSB3O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBoOiBoLFxuICAgIHc6IHcsXG4gICAgeDogeCxcbiAgICB5OiB5XG4gIH07XG59XG5cbmZ1bmN0aW9uIGRyYXdUZXh0TGluZShjdHgsIHRleHQsIGNmZykge1xuICB2YXIgc2hhZG93ID0gY3R4LnNoYWRvd0JsdXI7XG4gIHZhciBzdHJva2VkID0gY2ZnLnN0cm9rZWQ7XG4gIHZhciB4ID0gcmFzdGVyaXplKGNmZy54KTtcbiAgdmFyIHkgPSByYXN0ZXJpemUoY2ZnLnkpO1xuICB2YXIgdyA9IHJhc3Rlcml6ZShjZmcudyk7XG5cbiAgaWYgKHN0cm9rZWQpIHtcbiAgICBjdHguc3Ryb2tlVGV4dCh0ZXh0LCB4LCB5LCB3KTtcbiAgfVxuXG4gIGlmIChjZmcuZmlsbGVkKSB7XG4gICAgaWYgKHNoYWRvdyAmJiBzdHJva2VkKSB7XG4gICAgICAvLyBQcmV2ZW50IGRyYXdpbmcgc2hhZG93IG9uIGJvdGggdGhlIHRleHQgc3Ryb2tlIGFuZCBmaWxsLCBzb1xuICAgICAgLy8gaWYgdGhlIHRleHQgaXMgc3Ryb2tlZCwgcmVtb3ZlIHRoZSBzaGFkb3cgZm9yIHRoZSB0ZXh0IGZpbGwuXG4gICAgICBjdHguc2hhZG93Qmx1ciA9IDA7XG4gICAgfVxuXG4gICAgY3R4LmZpbGxUZXh0KHRleHQsIHgsIHksIHcpO1xuXG4gICAgaWYgKHNoYWRvdyAmJiBzdHJva2VkKSB7XG4gICAgICBjdHguc2hhZG93Qmx1ciA9IHNoYWRvdztcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZHJhd1RleHQoY3R4LCBsaW5lcywgcmVjdCwgbW9kZWwpIHtcbiAgdmFyIGFsaWduID0gbW9kZWwudGV4dEFsaWduO1xuICB2YXIgY29sb3IgPSBtb2RlbC5jb2xvcjtcbiAgdmFyIGZpbGxlZCA9ICEhY29sb3I7XG4gIHZhciBmb250ID0gbW9kZWwuZm9udDtcbiAgdmFyIGlsZW4gPSBsaW5lcy5sZW5ndGg7XG4gIHZhciBzdHJva2VDb2xvciA9IG1vZGVsLnRleHRTdHJva2VDb2xvcjtcbiAgdmFyIHN0cm9rZVdpZHRoID0gbW9kZWwudGV4dFN0cm9rZVdpZHRoO1xuICB2YXIgc3Ryb2tlZCA9IHN0cm9rZUNvbG9yICYmIHN0cm9rZVdpZHRoO1xuICB2YXIgaTtcblxuICBpZiAoIWlsZW4gfHwgKCFmaWxsZWQgJiYgIXN0cm9rZWQpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gQWRqdXN0IGNvb3JkaW5hdGVzIGJhc2VkIG9uIHRleHQgYWxpZ25tZW50IGFuZCBsaW5lIGhlaWdodFxuICByZWN0ID0gdGV4dEdlb21ldHJ5KHJlY3QsIGFsaWduLCBmb250KTtcblxuICBjdHguZm9udCA9IGZvbnQuc3RyaW5nO1xuICBjdHgudGV4dEFsaWduID0gYWxpZ247XG4gIGN0eC50ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJztcbiAgY3R4LnNoYWRvd0JsdXIgPSBtb2RlbC50ZXh0U2hhZG93Qmx1cjtcbiAgY3R4LnNoYWRvd0NvbG9yID0gbW9kZWwudGV4dFNoYWRvd0NvbG9yO1xuXG4gIGlmIChmaWxsZWQpIHtcbiAgICBjdHguZmlsbFN0eWxlID0gY29sb3I7XG4gIH1cbiAgaWYgKHN0cm9rZWQpIHtcbiAgICBjdHgubGluZUpvaW4gPSAncm91bmQnO1xuICAgIGN0eC5saW5lV2lkdGggPSBzdHJva2VXaWR0aDtcbiAgICBjdHguc3Ryb2tlU3R5bGUgPSBzdHJva2VDb2xvcjtcbiAgfVxuXG4gIGZvciAoaSA9IDAsIGlsZW4gPSBsaW5lcy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICBkcmF3VGV4dExpbmUoY3R4LCBsaW5lc1tpXSwge1xuICAgICAgc3Ryb2tlZDogc3Ryb2tlZCxcbiAgICAgIGZpbGxlZDogZmlsbGVkLFxuICAgICAgdzogcmVjdC53LFxuICAgICAgeDogcmVjdC54LFxuICAgICAgeTogcmVjdC55ICsgcmVjdC5oICogaVxuICAgIH0pO1xuICB9XG59XG5cbnZhciBMYWJlbCA9IGZ1bmN0aW9uKGNvbmZpZywgY3R4LCBlbCwgaW5kZXgpIHtcbiAgdmFyIG1lID0gdGhpcztcblxuICBtZS5fY29uZmlnID0gY29uZmlnO1xuICBtZS5faW5kZXggPSBpbmRleDtcbiAgbWUuX21vZGVsID0gbnVsbDtcbiAgbWUuX3JlY3RzID0gbnVsbDtcbiAgbWUuX2N0eCA9IGN0eDtcbiAgbWUuX2VsID0gZWw7XG59O1xuXG5tZXJnZShMYWJlbC5wcm90b3R5cGUsIHtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBfbW9kZWxpemU6IGZ1bmN0aW9uKGRpc3BsYXksIGxpbmVzLCBjb25maWcsIGNvbnRleHQpIHtcbiAgICB2YXIgbWUgPSB0aGlzO1xuICAgIHZhciBpbmRleCA9IG1lLl9pbmRleDtcbiAgICB2YXIgZm9udCA9IHRvRm9udChyZXNvbHZlKFtjb25maWcuZm9udCwge31dLCBjb250ZXh0LCBpbmRleCkpO1xuICAgIHZhciBjb2xvciA9IHJlc29sdmUoW2NvbmZpZy5jb2xvciwgZGVmYXVsdHMkMS5jb2xvcl0sIGNvbnRleHQsIGluZGV4KTtcblxuICAgIHJldHVybiB7XG4gICAgICBhbGlnbjogcmVzb2x2ZShbY29uZmlnLmFsaWduLCAnY2VudGVyJ10sIGNvbnRleHQsIGluZGV4KSxcbiAgICAgIGFuY2hvcjogcmVzb2x2ZShbY29uZmlnLmFuY2hvciwgJ2NlbnRlciddLCBjb250ZXh0LCBpbmRleCksXG4gICAgICBhcmVhOiBjb250ZXh0LmNoYXJ0LmNoYXJ0QXJlYSxcbiAgICAgIGJhY2tncm91bmRDb2xvcjogcmVzb2x2ZShbY29uZmlnLmJhY2tncm91bmRDb2xvciwgbnVsbF0sIGNvbnRleHQsIGluZGV4KSxcbiAgICAgIGJvcmRlckNvbG9yOiByZXNvbHZlKFtjb25maWcuYm9yZGVyQ29sb3IsIG51bGxdLCBjb250ZXh0LCBpbmRleCksXG4gICAgICBib3JkZXJSYWRpdXM6IHJlc29sdmUoW2NvbmZpZy5ib3JkZXJSYWRpdXMsIDBdLCBjb250ZXh0LCBpbmRleCksXG4gICAgICBib3JkZXJXaWR0aDogcmVzb2x2ZShbY29uZmlnLmJvcmRlcldpZHRoLCAwXSwgY29udGV4dCwgaW5kZXgpLFxuICAgICAgY2xhbXA6IHJlc29sdmUoW2NvbmZpZy5jbGFtcCwgZmFsc2VdLCBjb250ZXh0LCBpbmRleCksXG4gICAgICBjbGlwOiByZXNvbHZlKFtjb25maWcuY2xpcCwgZmFsc2VdLCBjb250ZXh0LCBpbmRleCksXG4gICAgICBjb2xvcjogY29sb3IsXG4gICAgICBkaXNwbGF5OiBkaXNwbGF5LFxuICAgICAgZm9udDogZm9udCxcbiAgICAgIGxpbmVzOiBsaW5lcyxcbiAgICAgIG9mZnNldDogcmVzb2x2ZShbY29uZmlnLm9mZnNldCwgNF0sIGNvbnRleHQsIGluZGV4KSxcbiAgICAgIG9wYWNpdHk6IHJlc29sdmUoW2NvbmZpZy5vcGFjaXR5LCAxXSwgY29udGV4dCwgaW5kZXgpLFxuICAgICAgb3JpZ2luOiBnZXRTY2FsZU9yaWdpbihtZS5fZWwsIGNvbnRleHQpLFxuICAgICAgcGFkZGluZzogdG9QYWRkaW5nKHJlc29sdmUoW2NvbmZpZy5wYWRkaW5nLCA0XSwgY29udGV4dCwgaW5kZXgpKSxcbiAgICAgIHBvc2l0aW9uZXI6IGdldFBvc2l0aW9uZXIobWUuX2VsKSxcbiAgICAgIHJvdGF0aW9uOiByZXNvbHZlKFtjb25maWcucm90YXRpb24sIDBdLCBjb250ZXh0LCBpbmRleCkgKiAoTWF0aC5QSSAvIDE4MCksXG4gICAgICBzaXplOiB1dGlscy50ZXh0U2l6ZShtZS5fY3R4LCBsaW5lcywgZm9udCksXG4gICAgICB0ZXh0QWxpZ246IHJlc29sdmUoW2NvbmZpZy50ZXh0QWxpZ24sICdzdGFydCddLCBjb250ZXh0LCBpbmRleCksXG4gICAgICB0ZXh0U2hhZG93Qmx1cjogcmVzb2x2ZShbY29uZmlnLnRleHRTaGFkb3dCbHVyLCAwXSwgY29udGV4dCwgaW5kZXgpLFxuICAgICAgdGV4dFNoYWRvd0NvbG9yOiByZXNvbHZlKFtjb25maWcudGV4dFNoYWRvd0NvbG9yLCBjb2xvcl0sIGNvbnRleHQsIGluZGV4KSxcbiAgICAgIHRleHRTdHJva2VDb2xvcjogcmVzb2x2ZShbY29uZmlnLnRleHRTdHJva2VDb2xvciwgY29sb3JdLCBjb250ZXh0LCBpbmRleCksXG4gICAgICB0ZXh0U3Ryb2tlV2lkdGg6IHJlc29sdmUoW2NvbmZpZy50ZXh0U3Ryb2tlV2lkdGgsIDBdLCBjb250ZXh0LCBpbmRleClcbiAgICB9O1xuICB9LFxuXG4gIHVwZGF0ZTogZnVuY3Rpb24oY29udGV4dCkge1xuICAgIHZhciBtZSA9IHRoaXM7XG4gICAgdmFyIG1vZGVsID0gbnVsbDtcbiAgICB2YXIgcmVjdHMgPSBudWxsO1xuICAgIHZhciBpbmRleCA9IG1lLl9pbmRleDtcbiAgICB2YXIgY29uZmlnID0gbWUuX2NvbmZpZztcbiAgICB2YXIgdmFsdWUsIGxhYmVsLCBsaW5lcztcblxuICAgIC8vIFdlIGZpcnN0IHJlc29sdmUgdGhlIGRpc3BsYXkgb3B0aW9uIChzZXBhcmF0ZWx5KSB0byBhdm9pZCBjb21wdXRpbmdcbiAgICAvLyBvdGhlciBvcHRpb25zIGluIGNhc2UgdGhlIGxhYmVsIGlzIGhpZGRlbiAoaS5lLiBkaXNwbGF5OiBmYWxzZSkuXG4gICAgdmFyIGRpc3BsYXkgPSByZXNvbHZlKFtjb25maWcuZGlzcGxheSwgdHJ1ZV0sIGNvbnRleHQsIGluZGV4KTtcblxuICAgIGlmIChkaXNwbGF5KSB7XG4gICAgICB2YWx1ZSA9IGNvbnRleHQuZGF0YXNldC5kYXRhW2luZGV4XTtcbiAgICAgIGxhYmVsID0gdmFsdWVPckRlZmF1bHQoY2FsbGJhY2soY29uZmlnLmZvcm1hdHRlciwgW3ZhbHVlLCBjb250ZXh0XSksIHZhbHVlKTtcbiAgICAgIGxpbmVzID0gaXNOdWxsT3JVbmRlZihsYWJlbCkgPyBbXSA6IHV0aWxzLnRvVGV4dExpbmVzKGxhYmVsKTtcblxuICAgICAgaWYgKGxpbmVzLmxlbmd0aCkge1xuICAgICAgICBtb2RlbCA9IG1lLl9tb2RlbGl6ZShkaXNwbGF5LCBsaW5lcywgY29uZmlnLCBjb250ZXh0KTtcbiAgICAgICAgcmVjdHMgPSBib3VuZGluZ1JlY3RzKG1vZGVsKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBtZS5fbW9kZWwgPSBtb2RlbDtcbiAgICBtZS5fcmVjdHMgPSByZWN0cztcbiAgfSxcblxuICBnZW9tZXRyeTogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX3JlY3RzID8gdGhpcy5fcmVjdHMuZnJhbWUgOiB7fTtcbiAgfSxcblxuICByb3RhdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX21vZGVsID8gdGhpcy5fbW9kZWwucm90YXRpb24gOiAwO1xuICB9LFxuXG4gIHZpc2libGU6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLl9tb2RlbCAmJiB0aGlzLl9tb2RlbC5vcGFjaXR5O1xuICB9LFxuXG4gIG1vZGVsOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5fbW9kZWw7XG4gIH0sXG5cbiAgZHJhdzogZnVuY3Rpb24oY2hhcnQsIGNlbnRlcikge1xuICAgIHZhciBtZSA9IHRoaXM7XG4gICAgdmFyIGN0eCA9IGNoYXJ0LmN0eDtcbiAgICB2YXIgbW9kZWwgPSBtZS5fbW9kZWw7XG4gICAgdmFyIHJlY3RzID0gbWUuX3JlY3RzO1xuICAgIHZhciBhcmVhO1xuXG4gICAgaWYgKCF0aGlzLnZpc2libGUoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGN0eC5zYXZlKCk7XG5cbiAgICBpZiAobW9kZWwuY2xpcCkge1xuICAgICAgYXJlYSA9IG1vZGVsLmFyZWE7XG4gICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICBjdHgucmVjdChcbiAgICAgICAgYXJlYS5sZWZ0LFxuICAgICAgICBhcmVhLnRvcCxcbiAgICAgICAgYXJlYS5yaWdodCAtIGFyZWEubGVmdCxcbiAgICAgICAgYXJlYS5ib3R0b20gLSBhcmVhLnRvcCk7XG4gICAgICBjdHguY2xpcCgpO1xuICAgIH1cblxuICAgIGN0eC5nbG9iYWxBbHBoYSA9IHV0aWxzLmJvdW5kKDAsIG1vZGVsLm9wYWNpdHksIDEpO1xuICAgIGN0eC50cmFuc2xhdGUocmFzdGVyaXplKGNlbnRlci54KSwgcmFzdGVyaXplKGNlbnRlci55KSk7XG4gICAgY3R4LnJvdGF0ZShtb2RlbC5yb3RhdGlvbik7XG5cbiAgICBkcmF3RnJhbWUoY3R4LCByZWN0cy5mcmFtZSwgbW9kZWwpO1xuICAgIGRyYXdUZXh0KGN0eCwgbW9kZWwubGluZXMsIHJlY3RzLnRleHQsIG1vZGVsKTtcblxuICAgIGN0eC5yZXN0b3JlKCk7XG4gIH1cbn0pO1xuXG52YXIgTUlOX0lOVEVHRVIgPSBOdW1iZXIuTUlOX1NBRkVfSU5URUdFUiB8fCAtOTAwNzE5OTI1NDc0MDk5MTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBlcy9uby1udW1iZXItbWluc2FmZWludGVnZXJcbnZhciBNQVhfSU5URUdFUiA9IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSIHx8IDkwMDcxOTkyNTQ3NDA5OTE7ICAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGVzL25vLW51bWJlci1tYXhzYWZlaW50ZWdlclxuXG5mdW5jdGlvbiByb3RhdGVkKHBvaW50LCBjZW50ZXIsIGFuZ2xlKSB7XG4gIHZhciBjb3MgPSBNYXRoLmNvcyhhbmdsZSk7XG4gIHZhciBzaW4gPSBNYXRoLnNpbihhbmdsZSk7XG4gIHZhciBjeCA9IGNlbnRlci54O1xuICB2YXIgY3kgPSBjZW50ZXIueTtcblxuICByZXR1cm4ge1xuICAgIHg6IGN4ICsgY29zICogKHBvaW50LnggLSBjeCkgLSBzaW4gKiAocG9pbnQueSAtIGN5KSxcbiAgICB5OiBjeSArIHNpbiAqIChwb2ludC54IC0gY3gpICsgY29zICogKHBvaW50LnkgLSBjeSlcbiAgfTtcbn1cblxuZnVuY3Rpb24gcHJvamVjdGVkKHBvaW50cywgYXhpcykge1xuICB2YXIgbWluID0gTUFYX0lOVEVHRVI7XG4gIHZhciBtYXggPSBNSU5fSU5URUdFUjtcbiAgdmFyIG9yaWdpbiA9IGF4aXMub3JpZ2luO1xuICB2YXIgaSwgcHQsIHZ4LCB2eSwgZHA7XG5cbiAgZm9yIChpID0gMDsgaSA8IHBvaW50cy5sZW5ndGg7ICsraSkge1xuICAgIHB0ID0gcG9pbnRzW2ldO1xuICAgIHZ4ID0gcHQueCAtIG9yaWdpbi54O1xuICAgIHZ5ID0gcHQueSAtIG9yaWdpbi55O1xuICAgIGRwID0gYXhpcy52eCAqIHZ4ICsgYXhpcy52eSAqIHZ5O1xuICAgIG1pbiA9IE1hdGgubWluKG1pbiwgZHApO1xuICAgIG1heCA9IE1hdGgubWF4KG1heCwgZHApO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBtaW46IG1pbixcbiAgICBtYXg6IG1heFxuICB9O1xufVxuXG5mdW5jdGlvbiB0b0F4aXMocDAsIHAxKSB7XG4gIHZhciB2eCA9IHAxLnggLSBwMC54O1xuICB2YXIgdnkgPSBwMS55IC0gcDAueTtcbiAgdmFyIGxuID0gTWF0aC5zcXJ0KHZ4ICogdnggKyB2eSAqIHZ5KTtcblxuICByZXR1cm4ge1xuICAgIHZ4OiAocDEueCAtIHAwLngpIC8gbG4sXG4gICAgdnk6IChwMS55IC0gcDAueSkgLyBsbixcbiAgICBvcmlnaW46IHAwLFxuICAgIGxuOiBsblxuICB9O1xufVxuXG52YXIgSGl0Qm94ID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuX3JvdGF0aW9uID0gMDtcbiAgdGhpcy5fcmVjdCA9IHtcbiAgICB4OiAwLFxuICAgIHk6IDAsXG4gICAgdzogMCxcbiAgICBoOiAwXG4gIH07XG59O1xuXG5tZXJnZShIaXRCb3gucHJvdG90eXBlLCB7XG4gIGNlbnRlcjogZnVuY3Rpb24oKSB7XG4gICAgdmFyIHIgPSB0aGlzLl9yZWN0O1xuICAgIHJldHVybiB7XG4gICAgICB4OiByLnggKyByLncgLyAyLFxuICAgICAgeTogci55ICsgci5oIC8gMlxuICAgIH07XG4gIH0sXG5cbiAgdXBkYXRlOiBmdW5jdGlvbihjZW50ZXIsIHJlY3QsIHJvdGF0aW9uKSB7XG4gICAgdGhpcy5fcm90YXRpb24gPSByb3RhdGlvbjtcbiAgICB0aGlzLl9yZWN0ID0ge1xuICAgICAgeDogcmVjdC54ICsgY2VudGVyLngsXG4gICAgICB5OiByZWN0LnkgKyBjZW50ZXIueSxcbiAgICAgIHc6IHJlY3QudyxcbiAgICAgIGg6IHJlY3QuaFxuICAgIH07XG4gIH0sXG5cbiAgY29udGFpbnM6IGZ1bmN0aW9uKHBvaW50KSB7XG4gICAgdmFyIG1lID0gdGhpcztcbiAgICB2YXIgbWFyZ2luID0gMTtcbiAgICB2YXIgcmVjdCA9IG1lLl9yZWN0O1xuXG4gICAgcG9pbnQgPSByb3RhdGVkKHBvaW50LCBtZS5jZW50ZXIoKSwgLW1lLl9yb3RhdGlvbik7XG5cbiAgICByZXR1cm4gIShwb2ludC54IDwgcmVjdC54IC0gbWFyZ2luXG4gICAgICB8fCBwb2ludC55IDwgcmVjdC55IC0gbWFyZ2luXG4gICAgICB8fCBwb2ludC54ID4gcmVjdC54ICsgcmVjdC53ICsgbWFyZ2luICogMlxuICAgICAgfHwgcG9pbnQueSA+IHJlY3QueSArIHJlY3QuaCArIG1hcmdpbiAqIDIpO1xuICB9LFxuXG4gIC8vIFNlcGFyYXRpbmcgQXhpcyBUaGVvcmVtXG4gIC8vIGh0dHBzOi8vZ2FtZWRldmVsb3BtZW50LnR1dHNwbHVzLmNvbS90dXRvcmlhbHMvY29sbGlzaW9uLWRldGVjdGlvbi11c2luZy10aGUtc2VwYXJhdGluZy1heGlzLXRoZW9yZW0tLWdhbWVkZXYtMTY5XG4gIGludGVyc2VjdHM6IGZ1bmN0aW9uKG90aGVyKSB7XG4gICAgdmFyIHIwID0gdGhpcy5fcG9pbnRzKCk7XG4gICAgdmFyIHIxID0gb3RoZXIuX3BvaW50cygpO1xuICAgIHZhciBheGVzID0gW1xuICAgICAgdG9BeGlzKHIwWzBdLCByMFsxXSksXG4gICAgICB0b0F4aXMocjBbMF0sIHIwWzNdKVxuICAgIF07XG4gICAgdmFyIGksIHByMCwgcHIxO1xuXG4gICAgaWYgKHRoaXMuX3JvdGF0aW9uICE9PSBvdGhlci5fcm90YXRpb24pIHtcbiAgICAgIC8vIE9ubHkgc2VwYXJhdGUgd2l0aCByMSBheGlzIGlmIHRoZSByb3RhdGlvbiBpcyBkaWZmZXJlbnQsXG4gICAgICAvLyBlbHNlIGl0J3MgZW5vdWdoIHRvIHNlcGFyYXRlIHIwIGFuZCByMSB3aXRoIHIwIGF4aXMgb25seSFcbiAgICAgIGF4ZXMucHVzaChcbiAgICAgICAgdG9BeGlzKHIxWzBdLCByMVsxXSksXG4gICAgICAgIHRvQXhpcyhyMVswXSwgcjFbM10pXG4gICAgICApO1xuICAgIH1cblxuICAgIGZvciAoaSA9IDA7IGkgPCBheGVzLmxlbmd0aDsgKytpKSB7XG4gICAgICBwcjAgPSBwcm9qZWN0ZWQocjAsIGF4ZXNbaV0pO1xuICAgICAgcHIxID0gcHJvamVjdGVkKHIxLCBheGVzW2ldKTtcblxuICAgICAgaWYgKHByMC5tYXggPCBwcjEubWluIHx8IHByMS5tYXggPCBwcjAubWluKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSxcblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIF9wb2ludHM6IGZ1bmN0aW9uKCkge1xuICAgIHZhciBtZSA9IHRoaXM7XG4gICAgdmFyIHJlY3QgPSBtZS5fcmVjdDtcbiAgICB2YXIgYW5nbGUgPSBtZS5fcm90YXRpb247XG4gICAgdmFyIGNlbnRlciA9IG1lLmNlbnRlcigpO1xuXG4gICAgcmV0dXJuIFtcbiAgICAgIHJvdGF0ZWQoe3g6IHJlY3QueCwgeTogcmVjdC55fSwgY2VudGVyLCBhbmdsZSksXG4gICAgICByb3RhdGVkKHt4OiByZWN0LnggKyByZWN0LncsIHk6IHJlY3QueX0sIGNlbnRlciwgYW5nbGUpLFxuICAgICAgcm90YXRlZCh7eDogcmVjdC54ICsgcmVjdC53LCB5OiByZWN0LnkgKyByZWN0Lmh9LCBjZW50ZXIsIGFuZ2xlKSxcbiAgICAgIHJvdGF0ZWQoe3g6IHJlY3QueCwgeTogcmVjdC55ICsgcmVjdC5ofSwgY2VudGVyLCBhbmdsZSlcbiAgICBdO1xuICB9XG59KTtcblxuZnVuY3Rpb24gY29vcmRpbmF0ZXMoZWwsIG1vZGVsLCBnZW9tZXRyeSkge1xuICB2YXIgcG9pbnQgPSBtb2RlbC5wb3NpdGlvbmVyKGVsLCBtb2RlbCk7XG4gIHZhciB2eCA9IHBvaW50LnZ4O1xuICB2YXIgdnkgPSBwb2ludC52eTtcblxuICBpZiAoIXZ4ICYmICF2eSkge1xuICAgIC8vIGlmIGFsaWduZWQgY2VudGVyLCB3ZSBkb24ndCB3YW50IHRvIG9mZnNldCB0aGUgY2VudGVyIHBvaW50XG4gICAgcmV0dXJuIHt4OiBwb2ludC54LCB5OiBwb2ludC55fTtcbiAgfVxuXG4gIHZhciB3ID0gZ2VvbWV0cnkudztcbiAgdmFyIGggPSBnZW9tZXRyeS5oO1xuXG4gIC8vIHRha2UgaW4gYWNjb3VudCB0aGUgbGFiZWwgcm90YXRpb25cbiAgdmFyIHJvdGF0aW9uID0gbW9kZWwucm90YXRpb247XG4gIHZhciBkeCA9IE1hdGguYWJzKHcgLyAyICogTWF0aC5jb3Mocm90YXRpb24pKSArIE1hdGguYWJzKGggLyAyICogTWF0aC5zaW4ocm90YXRpb24pKTtcbiAgdmFyIGR5ID0gTWF0aC5hYnModyAvIDIgKiBNYXRoLnNpbihyb3RhdGlvbikpICsgTWF0aC5hYnMoaCAvIDIgKiBNYXRoLmNvcyhyb3RhdGlvbikpO1xuXG4gIC8vIHNjYWxlIHRoZSB1bml0IHZlY3RvciAodngsIHZ5KSB0byBnZXQgYXQgbGVhc3QgZHggb3IgZHkgZXF1YWwgdG9cbiAgLy8gdyBvciBoIHJlc3BlY3RpdmVseSAoZWxzZSB3ZSB3b3VsZCBjYWxjdWxhdGUgdGhlIGRpc3RhbmNlIHRvIHRoZVxuICAvLyBlbGxpcHNlIGluc2NyaWJlZCBpbiB0aGUgYm91bmRpbmcgcmVjdClcbiAgdmFyIHZzID0gMSAvIE1hdGgubWF4KE1hdGguYWJzKHZ4KSwgTWF0aC5hYnModnkpKTtcbiAgZHggKj0gdnggKiB2cztcbiAgZHkgKj0gdnkgKiB2cztcblxuICAvLyBmaW5hbGx5LCBpbmNsdWRlIHRoZSBleHBsaWNpdCBvZmZzZXRcbiAgZHggKz0gbW9kZWwub2Zmc2V0ICogdng7XG4gIGR5ICs9IG1vZGVsLm9mZnNldCAqIHZ5O1xuXG4gIHJldHVybiB7XG4gICAgeDogcG9pbnQueCArIGR4LFxuICAgIHk6IHBvaW50LnkgKyBkeVxuICB9O1xufVxuXG5mdW5jdGlvbiBjb2xsaWRlKGxhYmVscywgY29sbGlkZXIpIHtcbiAgdmFyIGksIGosIHMwLCBzMTtcblxuICAvLyBJTVBPUlRBTlQgSXRlcmF0ZSBpbiB0aGUgcmV2ZXJzZSBvcmRlciBzaW5jZSBpdGVtcyBhdCB0aGUgZW5kIG9mIHRoZVxuICAvLyBsaXN0IGhhdmUgYW4gaGlnaGVyIHdlaWdodC9wcmlvcml0eSBhbmQgdGh1cyBzaG91bGQgYmUgbGVzcyBpbXBhY3RlZFxuICAvLyBieSB0aGUgb3ZlcmxhcHBpbmcgc3RyYXRlZ3kuXG5cbiAgZm9yIChpID0gbGFiZWxzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgczAgPSBsYWJlbHNbaV0uJGxheW91dDtcblxuICAgIGZvciAoaiA9IGkgLSAxOyBqID49IDAgJiYgczAuX3Zpc2libGU7IC0taikge1xuICAgICAgczEgPSBsYWJlbHNbal0uJGxheW91dDtcblxuICAgICAgaWYgKHMxLl92aXNpYmxlICYmIHMwLl9ib3guaW50ZXJzZWN0cyhzMS5fYm94KSkge1xuICAgICAgICBjb2xsaWRlcihzMCwgczEpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBsYWJlbHM7XG59XG5cbmZ1bmN0aW9uIGNvbXB1dGUobGFiZWxzKSB7XG4gIHZhciBpLCBpbGVuLCBsYWJlbCwgc3RhdGUsIGdlb21ldHJ5LCBjZW50ZXIsIHByb3h5O1xuXG4gIC8vIEluaXRpYWxpemUgbGFiZWxzIGZvciBvdmVybGFwIGRldGVjdGlvblxuICBmb3IgKGkgPSAwLCBpbGVuID0gbGFiZWxzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgIGxhYmVsID0gbGFiZWxzW2ldO1xuICAgIHN0YXRlID0gbGFiZWwuJGxheW91dDtcblxuICAgIGlmIChzdGF0ZS5fdmlzaWJsZSkge1xuICAgICAgLy8gQ2hhcnQuanMgMyByZW1vdmVkIGVsLl9tb2RlbCBpbiBmYXZvciBvZiBnZXRQcm9wcygpLCBtYWtpbmcgaGFyZGVyIHRvXG4gICAgICAvLyBhYnN0cmFjdCByZWFkaW5nIHZhbHVlcyBpbiBwb3NpdGlvbmVycy4gQWxzbywgdXNpbmcgc3RyaW5nIGFycmF5cyB0b1xuICAgICAgLy8gcmVhZCB2YWx1ZXMgKGkuZS4gdmFyIHthLGIsY30gPSBlbC5nZXRQcm9wcyhbXCJhXCIsXCJiXCIsXCJjXCJdKSkgd291bGQgbWFrZVxuICAgICAgLy8gcG9zaXRpb25lcnMgaW5lZmZpY2llbnQgaW4gdGhlIG5vcm1hbCBjYXNlIChpLmUuIG5vdCB0aGUgZmluYWwgdmFsdWVzKVxuICAgICAgLy8gYW5kIHRoZSBjb2RlIGEgYml0IHVnbHksIHNvIGxldCdzIHVzZSBhIFByb3h5IGluc3RlYWQuXG4gICAgICBwcm94eSA9IG5ldyBQcm94eShsYWJlbC5fZWwsIHtnZXQ6IChlbCwgcCkgPT4gZWwuZ2V0UHJvcHMoW3BdLCB0cnVlKVtwXX0pO1xuXG4gICAgICBnZW9tZXRyeSA9IGxhYmVsLmdlb21ldHJ5KCk7XG4gICAgICBjZW50ZXIgPSBjb29yZGluYXRlcyhwcm94eSwgbGFiZWwubW9kZWwoKSwgZ2VvbWV0cnkpO1xuICAgICAgc3RhdGUuX2JveC51cGRhdGUoY2VudGVyLCBnZW9tZXRyeSwgbGFiZWwucm90YXRpb24oKSk7XG4gICAgfVxuICB9XG5cbiAgLy8gQXV0byBoaWRlIG92ZXJsYXBwaW5nIGxhYmVsc1xuICByZXR1cm4gY29sbGlkZShsYWJlbHMsIGZ1bmN0aW9uKHMwLCBzMSkge1xuICAgIHZhciBoMCA9IHMwLl9oaWRhYmxlO1xuICAgIHZhciBoMSA9IHMxLl9oaWRhYmxlO1xuXG4gICAgaWYgKChoMCAmJiBoMSkgfHwgaDEpIHtcbiAgICAgIHMxLl92aXNpYmxlID0gZmFsc2U7XG4gICAgfSBlbHNlIGlmIChoMCkge1xuICAgICAgczAuX3Zpc2libGUgPSBmYWxzZTtcbiAgICB9XG4gIH0pO1xufVxuXG52YXIgbGF5b3V0ID0ge1xuICBwcmVwYXJlOiBmdW5jdGlvbihkYXRhc2V0cykge1xuICAgIHZhciBsYWJlbHMgPSBbXTtcbiAgICB2YXIgaSwgaiwgaWxlbiwgamxlbiwgbGFiZWw7XG5cbiAgICBmb3IgKGkgPSAwLCBpbGVuID0gZGF0YXNldHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgICBmb3IgKGogPSAwLCBqbGVuID0gZGF0YXNldHNbaV0ubGVuZ3RoOyBqIDwgamxlbjsgKytqKSB7XG4gICAgICAgIGxhYmVsID0gZGF0YXNldHNbaV1bal07XG4gICAgICAgIGxhYmVscy5wdXNoKGxhYmVsKTtcbiAgICAgICAgbGFiZWwuJGxheW91dCA9IHtcbiAgICAgICAgICBfYm94OiBuZXcgSGl0Qm94KCksXG4gICAgICAgICAgX2hpZGFibGU6IGZhbHNlLFxuICAgICAgICAgIF92aXNpYmxlOiB0cnVlLFxuICAgICAgICAgIF9zZXQ6IGksXG4gICAgICAgICAgX2lkeDogbGFiZWwuX2luZGV4XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gVE9ETyBOZXcgYHpgIG9wdGlvbjogbGFiZWxzIHdpdGggYSBoaWdoZXIgei1pbmRleCBhcmUgZHJhd25cbiAgICAvLyBvZiB0b3Agb2YgdGhlIG9uZXMgd2l0aCBhIGxvd2VyIGluZGV4LiBMb3dlc3Qgei1pbmRleCBsYWJlbHNcbiAgICAvLyBhcmUgYWxzbyBkaXNjYXJkZWQgZmlyc3Qgd2hlbiBoaWRpbmcgb3ZlcmxhcHBpbmcgbGFiZWxzLlxuICAgIGxhYmVscy5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcbiAgICAgIHZhciBzYSA9IGEuJGxheW91dDtcbiAgICAgIHZhciBzYiA9IGIuJGxheW91dDtcblxuICAgICAgcmV0dXJuIHNhLl9pZHggPT09IHNiLl9pZHhcbiAgICAgICAgPyBzYi5fc2V0IC0gc2EuX3NldFxuICAgICAgICA6IHNiLl9pZHggLSBzYS5faWR4O1xuICAgIH0pO1xuXG4gICAgdGhpcy51cGRhdGUobGFiZWxzKTtcblxuICAgIHJldHVybiBsYWJlbHM7XG4gIH0sXG5cbiAgdXBkYXRlOiBmdW5jdGlvbihsYWJlbHMpIHtcbiAgICB2YXIgZGlydHkgPSBmYWxzZTtcbiAgICB2YXIgaSwgaWxlbiwgbGFiZWwsIG1vZGVsLCBzdGF0ZTtcblxuICAgIGZvciAoaSA9IDAsIGlsZW4gPSBsYWJlbHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgICBsYWJlbCA9IGxhYmVsc1tpXTtcbiAgICAgIG1vZGVsID0gbGFiZWwubW9kZWwoKTtcbiAgICAgIHN0YXRlID0gbGFiZWwuJGxheW91dDtcbiAgICAgIHN0YXRlLl9oaWRhYmxlID0gbW9kZWwgJiYgbW9kZWwuZGlzcGxheSA9PT0gJ2F1dG8nO1xuICAgICAgc3RhdGUuX3Zpc2libGUgPSBsYWJlbC52aXNpYmxlKCk7XG4gICAgICBkaXJ0eSB8PSBzdGF0ZS5faGlkYWJsZTtcbiAgICB9XG5cbiAgICBpZiAoZGlydHkpIHtcbiAgICAgIGNvbXB1dGUobGFiZWxzKTtcbiAgICB9XG4gIH0sXG5cbiAgbG9va3VwOiBmdW5jdGlvbihsYWJlbHMsIHBvaW50KSB7XG4gICAgdmFyIGksIHN0YXRlO1xuXG4gICAgLy8gSU1QT1JUQU5UIEl0ZXJhdGUgaW4gdGhlIHJldmVyc2Ugb3JkZXIgc2luY2UgaXRlbXMgYXQgdGhlIGVuZCBvZlxuICAgIC8vIHRoZSBsaXN0IGhhdmUgYW4gaGlnaGVyIHotaW5kZXgsIHRodXMgc2hvdWxkIGJlIHBpY2tlZCBmaXJzdC5cblxuICAgIGZvciAoaSA9IGxhYmVscy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgc3RhdGUgPSBsYWJlbHNbaV0uJGxheW91dDtcblxuICAgICAgaWYgKHN0YXRlICYmIHN0YXRlLl92aXNpYmxlICYmIHN0YXRlLl9ib3guY29udGFpbnMocG9pbnQpKSB7XG4gICAgICAgIHJldHVybiBsYWJlbHNbaV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH0sXG5cbiAgZHJhdzogZnVuY3Rpb24oY2hhcnQsIGxhYmVscykge1xuICAgIHZhciBpLCBpbGVuLCBsYWJlbCwgc3RhdGUsIGdlb21ldHJ5LCBjZW50ZXI7XG5cbiAgICBmb3IgKGkgPSAwLCBpbGVuID0gbGFiZWxzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgbGFiZWwgPSBsYWJlbHNbaV07XG4gICAgICBzdGF0ZSA9IGxhYmVsLiRsYXlvdXQ7XG5cbiAgICAgIGlmIChzdGF0ZS5fdmlzaWJsZSkge1xuICAgICAgICBnZW9tZXRyeSA9IGxhYmVsLmdlb21ldHJ5KCk7XG4gICAgICAgIGNlbnRlciA9IGNvb3JkaW5hdGVzKGxhYmVsLl9lbCwgbGFiZWwubW9kZWwoKSwgZ2VvbWV0cnkpO1xuICAgICAgICBzdGF0ZS5fYm94LnVwZGF0ZShjZW50ZXIsIGdlb21ldHJ5LCBsYWJlbC5yb3RhdGlvbigpKTtcbiAgICAgICAgbGFiZWwuZHJhdyhjaGFydCwgY2VudGVyKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn07XG5cbnZhciBmb3JtYXR0ZXIgPSBmdW5jdGlvbih2YWx1ZSkge1xuICBpZiAoaXNOdWxsT3JVbmRlZih2YWx1ZSkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHZhciBsYWJlbCA9IHZhbHVlO1xuICB2YXIga2V5cywga2xlbiwgaztcbiAgaWYgKGlzT2JqZWN0KHZhbHVlKSkge1xuICAgIGlmICghaXNOdWxsT3JVbmRlZih2YWx1ZS5sYWJlbCkpIHtcbiAgICAgIGxhYmVsID0gdmFsdWUubGFiZWw7XG4gICAgfSBlbHNlIGlmICghaXNOdWxsT3JVbmRlZih2YWx1ZS5yKSkge1xuICAgICAgbGFiZWwgPSB2YWx1ZS5yO1xuICAgIH0gZWxzZSB7XG4gICAgICBsYWJlbCA9ICcnO1xuICAgICAga2V5cyA9IE9iamVjdC5rZXlzKHZhbHVlKTtcbiAgICAgIGZvciAoayA9IDAsIGtsZW4gPSBrZXlzLmxlbmd0aDsgayA8IGtsZW47ICsraykge1xuICAgICAgICBsYWJlbCArPSAoayAhPT0gMCA/ICcsICcgOiAnJykgKyBrZXlzW2tdICsgJzogJyArIHZhbHVlW2tleXNba11dO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiAnJyArIGxhYmVsO1xufTtcblxuLyoqXG4gKiBJTVBPUlRBTlQ6IG1ha2Ugc3VyZSB0byBhbHNvIHVwZGF0ZSB0ZXN0cyBhbmQgVHlwZVNjcmlwdCBkZWZpbml0aW9uXG4gKiBmaWxlcyAoYC90ZXN0L3NwZWNzL2RlZmF1bHRzLnNwZWMuanNgIGFuZCBgL3R5cGVzL29wdGlvbnMuZC50c2ApXG4gKi9cblxudmFyIGRlZmF1bHRzID0ge1xuICBhbGlnbjogJ2NlbnRlcicsXG4gIGFuY2hvcjogJ2NlbnRlcicsXG4gIGJhY2tncm91bmRDb2xvcjogbnVsbCxcbiAgYm9yZGVyQ29sb3I6IG51bGwsXG4gIGJvcmRlclJhZGl1czogMCxcbiAgYm9yZGVyV2lkdGg6IDAsXG4gIGNsYW1wOiBmYWxzZSxcbiAgY2xpcDogZmFsc2UsXG4gIGNvbG9yOiB1bmRlZmluZWQsXG4gIGRpc3BsYXk6IHRydWUsXG4gIGZvbnQ6IHtcbiAgICBmYW1pbHk6IHVuZGVmaW5lZCxcbiAgICBsaW5lSGVpZ2h0OiAxLjIsXG4gICAgc2l6ZTogdW5kZWZpbmVkLFxuICAgIHN0eWxlOiB1bmRlZmluZWQsXG4gICAgd2VpZ2h0OiBudWxsXG4gIH0sXG4gIGZvcm1hdHRlcjogZm9ybWF0dGVyLFxuICBsYWJlbHM6IHVuZGVmaW5lZCxcbiAgbGlzdGVuZXJzOiB7fSxcbiAgb2Zmc2V0OiA0LFxuICBvcGFjaXR5OiAxLFxuICBwYWRkaW5nOiB7XG4gICAgdG9wOiA0LFxuICAgIHJpZ2h0OiA0LFxuICAgIGJvdHRvbTogNCxcbiAgICBsZWZ0OiA0XG4gIH0sXG4gIHJvdGF0aW9uOiAwLFxuICB0ZXh0QWxpZ246ICdzdGFydCcsXG4gIHRleHRTdHJva2VDb2xvcjogdW5kZWZpbmVkLFxuICB0ZXh0U3Ryb2tlV2lkdGg6IDAsXG4gIHRleHRTaGFkb3dCbHVyOiAwLFxuICB0ZXh0U2hhZG93Q29sb3I6IHVuZGVmaW5lZFxufTtcblxuLyoqXG4gKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy80MTc2XG4gKi9cblxudmFyIEVYUEFORE9fS0VZID0gJyRkYXRhbGFiZWxzJztcbnZhciBERUZBVUxUX0tFWSA9ICckZGVmYXVsdCc7XG5cbmZ1bmN0aW9uIGNvbmZpZ3VyZShkYXRhc2V0LCBvcHRpb25zKSB7XG4gIHZhciBvdmVycmlkZSA9IGRhdGFzZXQuZGF0YWxhYmVscztcbiAgdmFyIGxpc3RlbmVycyA9IHt9O1xuICB2YXIgY29uZmlncyA9IFtdO1xuICB2YXIgbGFiZWxzLCBrZXlzO1xuXG4gIGlmIChvdmVycmlkZSA9PT0gZmFsc2UpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBpZiAob3ZlcnJpZGUgPT09IHRydWUpIHtcbiAgICBvdmVycmlkZSA9IHt9O1xuICB9XG5cbiAgb3B0aW9ucyA9IG1lcmdlKHt9LCBbb3B0aW9ucywgb3ZlcnJpZGVdKTtcbiAgbGFiZWxzID0gb3B0aW9ucy5sYWJlbHMgfHwge307XG4gIGtleXMgPSBPYmplY3Qua2V5cyhsYWJlbHMpO1xuICBkZWxldGUgb3B0aW9ucy5sYWJlbHM7XG5cbiAgaWYgKGtleXMubGVuZ3RoKSB7XG4gICAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgICAgaWYgKGxhYmVsc1trZXldKSB7XG4gICAgICAgIGNvbmZpZ3MucHVzaChtZXJnZSh7fSwgW1xuICAgICAgICAgIG9wdGlvbnMsXG4gICAgICAgICAgbGFiZWxzW2tleV0sXG4gICAgICAgICAge19rZXk6IGtleX1cbiAgICAgICAgXSkpO1xuICAgICAgfVxuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIC8vIERlZmF1bHQgbGFiZWwgaWYgbm8gXCJuYW1lZFwiIGxhYmVsIGRlZmluZWQuXG4gICAgY29uZmlncy5wdXNoKG9wdGlvbnMpO1xuICB9XG5cbiAgLy8gbGlzdGVuZXJzOiB7PGV2ZW50LXR5cGU+OiB7PGxhYmVsLWtleT46IDxmbj59fVxuICBsaXN0ZW5lcnMgPSBjb25maWdzLnJlZHVjZShmdW5jdGlvbih0YXJnZXQsIGNvbmZpZykge1xuICAgIGVhY2goY29uZmlnLmxpc3RlbmVycyB8fCB7fSwgZnVuY3Rpb24oZm4sIGV2ZW50KSB7XG4gICAgICB0YXJnZXRbZXZlbnRdID0gdGFyZ2V0W2V2ZW50XSB8fCB7fTtcbiAgICAgIHRhcmdldFtldmVudF1bY29uZmlnLl9rZXkgfHwgREVGQVVMVF9LRVldID0gZm47XG4gICAgfSk7XG5cbiAgICBkZWxldGUgY29uZmlnLmxpc3RlbmVycztcbiAgICByZXR1cm4gdGFyZ2V0O1xuICB9LCB7fSk7XG5cbiAgcmV0dXJuIHtcbiAgICBsYWJlbHM6IGNvbmZpZ3MsXG4gICAgbGlzdGVuZXJzOiBsaXN0ZW5lcnNcbiAgfTtcbn1cblxuZnVuY3Rpb24gZGlzcGF0Y2hFdmVudChjaGFydCwgbGlzdGVuZXJzLCBsYWJlbCwgZXZlbnQpIHtcbiAgaWYgKCFsaXN0ZW5lcnMpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgY29udGV4dCA9IGxhYmVsLiRjb250ZXh0O1xuICB2YXIgZ3JvdXBzID0gbGFiZWwuJGdyb3VwcztcbiAgdmFyIGNhbGxiYWNrJDE7XG5cbiAgaWYgKCFsaXN0ZW5lcnNbZ3JvdXBzLl9zZXRdKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY2FsbGJhY2skMSA9IGxpc3RlbmVyc1tncm91cHMuX3NldF1bZ3JvdXBzLl9rZXldO1xuICBpZiAoIWNhbGxiYWNrJDEpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoY2FsbGJhY2soY2FsbGJhY2skMSwgW2NvbnRleHQsIGV2ZW50XSkgPT09IHRydWUpIHtcbiAgICAvLyBVc2VycyBhcmUgYWxsb3dlZCB0byB0d2VhayB0aGUgZ2l2ZW4gY29udGV4dCBieSBpbmplY3RpbmcgdmFsdWVzIHRoYXQgY2FuIGJlXG4gICAgLy8gdXNlZCBpbiBzY3JpcHRhYmxlIG9wdGlvbnMgdG8gZGlzcGxheSBsYWJlbHMgZGlmZmVyZW50bHkgYmFzZWQgb24gdGhlIGN1cnJlbnRcbiAgICAvLyBldmVudCAoZS5nLiBoaWdobGlnaHQgYW4gaG92ZXJlZCBsYWJlbCkuIFRoYXQncyB3aHkgd2UgdXBkYXRlIHRoZSBsYWJlbCB3aXRoXG4gICAgLy8gdGhlIG91dHB1dCBjb250ZXh0IGFuZCBzY2hlZHVsZSBhIG5ldyBjaGFydCByZW5kZXIgYnkgc2V0dGluZyBpdCBkaXJ0eS5cbiAgICBjaGFydFtFWFBBTkRPX0tFWV0uX2RpcnR5ID0gdHJ1ZTtcbiAgICBsYWJlbC51cGRhdGUoY29udGV4dCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZGlzcGF0Y2hNb3ZlRXZlbnRzKGNoYXJ0LCBsaXN0ZW5lcnMsIHByZXZpb3VzLCBsYWJlbCwgZXZlbnQpIHtcbiAgdmFyIGVudGVyLCBsZWF2ZTtcblxuICBpZiAoIXByZXZpb3VzICYmICFsYWJlbCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICghcHJldmlvdXMpIHtcbiAgICBlbnRlciA9IHRydWU7XG4gIH0gZWxzZSBpZiAoIWxhYmVsKSB7XG4gICAgbGVhdmUgPSB0cnVlO1xuICB9IGVsc2UgaWYgKHByZXZpb3VzICE9PSBsYWJlbCkge1xuICAgIGxlYXZlID0gZW50ZXIgPSB0cnVlO1xuICB9XG5cbiAgaWYgKGxlYXZlKSB7XG4gICAgZGlzcGF0Y2hFdmVudChjaGFydCwgbGlzdGVuZXJzLmxlYXZlLCBwcmV2aW91cywgZXZlbnQpO1xuICB9XG4gIGlmIChlbnRlcikge1xuICAgIGRpc3BhdGNoRXZlbnQoY2hhcnQsIGxpc3RlbmVycy5lbnRlciwgbGFiZWwsIGV2ZW50KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBoYW5kbGVNb3ZlRXZlbnRzKGNoYXJ0LCBldmVudCkge1xuICB2YXIgZXhwYW5kbyA9IGNoYXJ0W0VYUEFORE9fS0VZXTtcbiAgdmFyIGxpc3RlbmVycyA9IGV4cGFuZG8uX2xpc3RlbmVycztcbiAgdmFyIHByZXZpb3VzLCBsYWJlbDtcblxuICBpZiAoIWxpc3RlbmVycy5lbnRlciAmJiAhbGlzdGVuZXJzLmxlYXZlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGV2ZW50LnR5cGUgPT09ICdtb3VzZW1vdmUnKSB7XG4gICAgbGFiZWwgPSBsYXlvdXQubG9va3VwKGV4cGFuZG8uX2xhYmVscywgZXZlbnQpO1xuICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgIT09ICdtb3VzZW91dCcpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBwcmV2aW91cyA9IGV4cGFuZG8uX2hvdmVyZWQ7XG4gIGV4cGFuZG8uX2hvdmVyZWQgPSBsYWJlbDtcbiAgZGlzcGF0Y2hNb3ZlRXZlbnRzKGNoYXJ0LCBsaXN0ZW5lcnMsIHByZXZpb3VzLCBsYWJlbCwgZXZlbnQpO1xufVxuXG5mdW5jdGlvbiBoYW5kbGVDbGlja0V2ZW50cyhjaGFydCwgZXZlbnQpIHtcbiAgdmFyIGV4cGFuZG8gPSBjaGFydFtFWFBBTkRPX0tFWV07XG4gIHZhciBoYW5kbGVycyA9IGV4cGFuZG8uX2xpc3RlbmVycy5jbGljaztcbiAgdmFyIGxhYmVsID0gaGFuZGxlcnMgJiYgbGF5b3V0Lmxvb2t1cChleHBhbmRvLl9sYWJlbHMsIGV2ZW50KTtcbiAgaWYgKGxhYmVsKSB7XG4gICAgZGlzcGF0Y2hFdmVudChjaGFydCwgaGFuZGxlcnMsIGxhYmVsLCBldmVudCk7XG4gIH1cbn1cblxudmFyIHBsdWdpbiA9IHtcbiAgaWQ6ICdkYXRhbGFiZWxzJyxcblxuICBkZWZhdWx0czogZGVmYXVsdHMsXG5cbiAgYmVmb3JlSW5pdDogZnVuY3Rpb24oY2hhcnQpIHtcbiAgICBjaGFydFtFWFBBTkRPX0tFWV0gPSB7XG4gICAgICBfYWN0aXZlczogW11cbiAgICB9O1xuICB9LFxuXG4gIGJlZm9yZVVwZGF0ZTogZnVuY3Rpb24oY2hhcnQpIHtcbiAgICB2YXIgZXhwYW5kbyA9IGNoYXJ0W0VYUEFORE9fS0VZXTtcbiAgICBleHBhbmRvLl9saXN0ZW5lZCA9IGZhbHNlO1xuICAgIGV4cGFuZG8uX2xpc3RlbmVycyA9IHt9OyAgICAgLy8gezxldmVudC10eXBlPjogezxkYXRhc2V0LWluZGV4PjogezxsYWJlbC1rZXk+OiA8Zm4+fX19XG4gICAgZXhwYW5kby5fZGF0YXNldHMgPSBbXTsgICAgICAvLyBwZXIgZGF0YXNldCBsYWJlbHM6IFtMYWJlbFtdXVxuICAgIGV4cGFuZG8uX2xhYmVscyA9IFtdOyAgICAgICAgLy8gbGF5b3V0ZWQgbGFiZWxzOiBMYWJlbFtdXG4gIH0sXG5cbiAgYWZ0ZXJEYXRhc2V0VXBkYXRlOiBmdW5jdGlvbihjaGFydCwgYXJncywgb3B0aW9ucykge1xuICAgIHZhciBkYXRhc2V0SW5kZXggPSBhcmdzLmluZGV4O1xuICAgIHZhciBleHBhbmRvID0gY2hhcnRbRVhQQU5ET19LRVldO1xuICAgIHZhciBsYWJlbHMgPSBleHBhbmRvLl9kYXRhc2V0c1tkYXRhc2V0SW5kZXhdID0gW107XG4gICAgdmFyIHZpc2libGUgPSBjaGFydC5pc0RhdGFzZXRWaXNpYmxlKGRhdGFzZXRJbmRleCk7XG4gICAgdmFyIGRhdGFzZXQgPSBjaGFydC5kYXRhLmRhdGFzZXRzW2RhdGFzZXRJbmRleF07XG4gICAgdmFyIGNvbmZpZyA9IGNvbmZpZ3VyZShkYXRhc2V0LCBvcHRpb25zKTtcbiAgICB2YXIgZWxlbWVudHMgPSBhcmdzLm1ldGEuZGF0YSB8fCBbXTtcbiAgICB2YXIgY3R4ID0gY2hhcnQuY3R4O1xuICAgIHZhciBpLCBqLCBpbGVuLCBqbGVuLCBjZmcsIGtleSwgZWwsIGxhYmVsO1xuXG4gICAgY3R4LnNhdmUoKTtcblxuICAgIGZvciAoaSA9IDAsIGlsZW4gPSBlbGVtZW50cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICAgIGVsID0gZWxlbWVudHNbaV07XG4gICAgICBlbFtFWFBBTkRPX0tFWV0gPSBbXTtcblxuICAgICAgaWYgKHZpc2libGUgJiYgZWwgJiYgY2hhcnQuZ2V0RGF0YVZpc2liaWxpdHkoaSkgJiYgIWVsLnNraXApIHtcbiAgICAgICAgZm9yIChqID0gMCwgamxlbiA9IGNvbmZpZy5sYWJlbHMubGVuZ3RoOyBqIDwgamxlbjsgKytqKSB7XG4gICAgICAgICAgY2ZnID0gY29uZmlnLmxhYmVsc1tqXTtcbiAgICAgICAgICBrZXkgPSBjZmcuX2tleTtcblxuICAgICAgICAgIGxhYmVsID0gbmV3IExhYmVsKGNmZywgY3R4LCBlbCwgaSk7XG4gICAgICAgICAgbGFiZWwuJGdyb3VwcyA9IHtcbiAgICAgICAgICAgIF9zZXQ6IGRhdGFzZXRJbmRleCxcbiAgICAgICAgICAgIF9rZXk6IGtleSB8fCBERUZBVUxUX0tFWVxuICAgICAgICAgIH07XG4gICAgICAgICAgbGFiZWwuJGNvbnRleHQgPSB7XG4gICAgICAgICAgICBhY3RpdmU6IGZhbHNlLFxuICAgICAgICAgICAgY2hhcnQ6IGNoYXJ0LFxuICAgICAgICAgICAgZGF0YUluZGV4OiBpLFxuICAgICAgICAgICAgZGF0YXNldDogZGF0YXNldCxcbiAgICAgICAgICAgIGRhdGFzZXRJbmRleDogZGF0YXNldEluZGV4XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGxhYmVsLnVwZGF0ZShsYWJlbC4kY29udGV4dCk7XG4gICAgICAgICAgZWxbRVhQQU5ET19LRVldLnB1c2gobGFiZWwpO1xuICAgICAgICAgIGxhYmVscy5wdXNoKGxhYmVsKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGN0eC5yZXN0b3JlKCk7XG5cbiAgICAvLyBTdG9yZSBsaXN0ZW5lcnMgYXQgdGhlIGNoYXJ0IGxldmVsIGFuZCBwZXIgZXZlbnQgdHlwZSB0byBvcHRpbWl6ZVxuICAgIC8vIGNhc2VzIHdoZXJlIG5vIGxpc3RlbmVycyBhcmUgcmVnaXN0ZXJlZCBmb3IgYSBzcGVjaWZpYyBldmVudC5cbiAgICBtZXJnZShleHBhbmRvLl9saXN0ZW5lcnMsIGNvbmZpZy5saXN0ZW5lcnMsIHtcbiAgICAgIG1lcmdlcjogZnVuY3Rpb24oZXZlbnQsIHRhcmdldCwgc291cmNlKSB7XG4gICAgICAgIHRhcmdldFtldmVudF0gPSB0YXJnZXRbZXZlbnRdIHx8IHt9O1xuICAgICAgICB0YXJnZXRbZXZlbnRdW2FyZ3MuaW5kZXhdID0gc291cmNlW2V2ZW50XTtcbiAgICAgICAgZXhwYW5kby5fbGlzdGVuZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH0pO1xuICB9LFxuXG4gIGFmdGVyVXBkYXRlOiBmdW5jdGlvbihjaGFydCkge1xuICAgIGNoYXJ0W0VYUEFORE9fS0VZXS5fbGFiZWxzID0gbGF5b3V0LnByZXBhcmUoY2hhcnRbRVhQQU5ET19LRVldLl9kYXRhc2V0cyk7XG4gIH0sXG5cbiAgLy8gRHJhdyBsYWJlbHMgb24gdG9wIG9mIGFsbCBkYXRhc2V0IGVsZW1lbnRzXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL2NoYXJ0anMtcGx1Z2luLWRhdGFsYWJlbHMvaXNzdWVzLzI5XG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL2NoYXJ0anMtcGx1Z2luLWRhdGFsYWJlbHMvaXNzdWVzLzMyXG4gIGFmdGVyRGF0YXNldHNEcmF3OiBmdW5jdGlvbihjaGFydCkge1xuICAgIGxheW91dC5kcmF3KGNoYXJ0LCBjaGFydFtFWFBBTkRPX0tFWV0uX2xhYmVscyk7XG4gIH0sXG5cbiAgYmVmb3JlRXZlbnQ6IGZ1bmN0aW9uKGNoYXJ0LCBhcmdzKSB7XG4gICAgLy8gSWYgdGhlcmUgaXMgbm8gbGlzdGVuZXIgcmVnaXN0ZXJlZCBmb3IgdGhpcyBjaGFydCwgYGxpc3RlbmVkYCB3aWxsIGJlIGZhbHNlLFxuICAgIC8vIG1lYW5pbmcgd2UgY2FuIGltbWVkaWF0ZWx5IGlnbm9yZSB0aGUgaW5jb21pbmcgZXZlbnQgYW5kIGF2b2lkIHVzZWxlc3MgZXh0cmFcbiAgICAvLyBjb21wdXRhdGlvbiBmb3IgdXNlcnMgd2hvIGRvbid0IGltcGxlbWVudCBsYWJlbCBpbnRlcmFjdGlvbnMuXG4gICAgaWYgKGNoYXJ0W0VYUEFORE9fS0VZXS5fbGlzdGVuZWQpIHtcbiAgICAgIHZhciBldmVudCA9IGFyZ3MuZXZlbnQ7XG4gICAgICBzd2l0Y2ggKGV2ZW50LnR5cGUpIHtcbiAgICAgIGNhc2UgJ21vdXNlbW92ZSc6XG4gICAgICBjYXNlICdtb3VzZW91dCc6XG4gICAgICAgIGhhbmRsZU1vdmVFdmVudHMoY2hhcnQsIGV2ZW50KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdjbGljayc6XG4gICAgICAgIGhhbmRsZUNsaWNrRXZlbnRzKGNoYXJ0LCBldmVudCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICBhZnRlckV2ZW50OiBmdW5jdGlvbihjaGFydCkge1xuICAgIHZhciBleHBhbmRvID0gY2hhcnRbRVhQQU5ET19LRVldO1xuICAgIHZhciBwcmV2aW91cyA9IGV4cGFuZG8uX2FjdGl2ZXM7XG4gICAgdmFyIGFjdGl2ZXMgPSBleHBhbmRvLl9hY3RpdmVzID0gY2hhcnQuZ2V0QWN0aXZlRWxlbWVudHMoKTtcbiAgICB2YXIgdXBkYXRlcyA9IHV0aWxzLmFycmF5RGlmZihwcmV2aW91cywgYWN0aXZlcyk7XG4gICAgdmFyIGksIGlsZW4sIGosIGpsZW4sIHVwZGF0ZSwgbGFiZWwsIGxhYmVscztcblxuICAgIGZvciAoaSA9IDAsIGlsZW4gPSB1cGRhdGVzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgdXBkYXRlID0gdXBkYXRlc1tpXTtcbiAgICAgIGlmICh1cGRhdGVbMV0pIHtcbiAgICAgICAgbGFiZWxzID0gdXBkYXRlWzBdLmVsZW1lbnRbRVhQQU5ET19LRVldIHx8IFtdO1xuICAgICAgICBmb3IgKGogPSAwLCBqbGVuID0gbGFiZWxzLmxlbmd0aDsgaiA8IGpsZW47ICsraikge1xuICAgICAgICAgIGxhYmVsID0gbGFiZWxzW2pdO1xuICAgICAgICAgIGxhYmVsLiRjb250ZXh0LmFjdGl2ZSA9ICh1cGRhdGVbMV0gPT09IDEpO1xuICAgICAgICAgIGxhYmVsLnVwZGF0ZShsYWJlbC4kY29udGV4dCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZXhwYW5kby5fZGlydHkgfHwgdXBkYXRlcy5sZW5ndGgpIHtcbiAgICAgIGxheW91dC51cGRhdGUoZXhwYW5kby5fbGFiZWxzKTtcbiAgICAgIGNoYXJ0LnJlbmRlcigpO1xuICAgIH1cblxuICAgIGRlbGV0ZSBleHBhbmRvLl9kaXJ0eTtcbiAgfVxufTtcblxuZXhwb3J0IHsgcGx1Z2luIGFzIGRlZmF1bHQgfTtcbiIsImltcG9ydCBcIi4vbm9ybWFsaXplLmNzc1wiXG5pbXBvcnQgXCIuL3N0eWxlcy5jc3NcIlxuaW1wb3J0IENoYXJ0IGZyb20gJ2NoYXJ0LmpzL2F1dG8nO1xuaW1wb3J0IE11dGVkIGZyb20gXCIuL2Fzc2V0cy9pbWFnZXMvbXV0ZWQucG5nXCJcbmltcG9ydCBVbm11dGVkIGZyb20gXCIuL2Fzc2V0cy9pbWFnZXMvdW5tdXRlZC5wbmdcIlxuaW1wb3J0IENoYXJ0RGF0YUxhYmVscyBmcm9tICdjaGFydGpzLXBsdWdpbi1kYXRhbGFiZWxzJztcblxuLyoqQ09VTlRVUCBBTklNQVRJT04gKi9cbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJET01Db250ZW50TG9hZGVkXCIsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IGNvdW50dXBFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJjb3VudHVwXCIpO1xuICAgIGNvbnN0IHRhcmdldCA9IDM0OyAvLyBUaGUgZmluYWwgdmFsdWUgdG8gY291bnQgdXAgdG9cbiAgICBjb25zdCBkdXJhdGlvbiA9IDI1MDA7IC8vIER1cmF0aW9uIG9mIHRoZSBjb3VudC11cCBhbmltYXRpb24gaW4gbWlsbGlzZWNvbmRzICgxIHNlY29uZClcbiAgICBsZXQgc3RhcnQgPSBudWxsOyAvLyBUaW1lc3RhbXAgd2hlbiB0aGUgYW5pbWF0aW9uIHN0YXJ0cywgaW5pdGlhbGl6ZWQgdG8gbnVsbFxuXG4gICAgLy8gRWFzaW5nIGZ1bmN0aW9uIGZvciBlYXNlLW91dCBlZmZlY3RcbiAgICAvLyBUaGlzIGZ1bmN0aW9uIGNyZWF0ZXMgYW4gZWFzZS1vdXQgZWZmZWN0LCB3aGVyZSB0aGUgYW5pbWF0aW9uIHN0YXJ0cyBmYXN0IGFuZCBzbG93cyBkb3duIHRvd2FyZCB0aGUgZW5kXG4gICAgZnVuY3Rpb24gZWFzZU91dFF1YWQodCkge1xuICAgICAgICByZXR1cm4gdCAqICgyIC0gdCk7XG4gICAgfVxuXG4gICAgLy8gVGhlIGZ1bmN0aW9uIHRoYXQgcGVyZm9ybXMgdGhlIGNvdW50LXVwIGFuaW1hdGlvblxuICAgIGZ1bmN0aW9uIGNvdW50VXAodGltZXN0YW1wKSB7XG4gICAgICAgIGlmICghc3RhcnQpIHN0YXJ0ID0gdGltZXN0YW1wOyAvLyBTZXQgdGhlIHN0YXJ0IHRpbWUgaWYgaXQncyBub3Qgc2V0IHlldFxuICAgICAgICBjb25zdCBwcm9ncmVzcyA9IE1hdGgubWluKCh0aW1lc3RhbXAgLSBzdGFydCkgLyBkdXJhdGlvbiwgMSk7IC8vIENhbGN1bGF0ZSB0aGUgcHJvZ3Jlc3MgZnJvbSAwIHRvIDFcbiAgICAgICAgY29uc3QgZWFzZWRQcm9ncmVzcyA9IGVhc2VPdXRRdWFkKHByb2dyZXNzKTsgLy8gQXBwbHkgdGhlIGVhc2luZyBmdW5jdGlvbiB0byB0aGUgcHJvZ3Jlc3NcbiAgICAgICAgY291bnR1cEVsZW1lbnQudGV4dENvbnRlbnQgPSBNYXRoLmZsb29yKGVhc2VkUHJvZ3Jlc3MgKiB0YXJnZXQpOyAvLyBVcGRhdGUgdGhlIGRpc3BsYXllZCBjb3VudCBiYXNlZCBvbiBwcm9ncmVzc1xuXG4gICAgICAgIGlmIChwcm9ncmVzcyA8IDEpIHtcbiAgICAgICAgICAgIC8vIElmIHRoZSBhbmltYXRpb24gaXMgbm90IHlldCBjb21wbGV0ZSwgcmVxdWVzdCB0aGUgbmV4dCBhbmltYXRpb24gZnJhbWVcbiAgICAgICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZShjb3VudFVwKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFdoZW4gdGhlIGFuaW1hdGlvbiBpcyBjb21wbGV0ZSwgc2V0IHRoZSBmaW5hbCB2YWx1ZSB3aXRoIHRoZSBsYWJlbFxuICAgICAgICAgICAgY291bnR1cEVsZW1lbnQudGV4dENvbnRlbnQgPSB0YXJnZXQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBTdGFydCB0aGUgYW5pbWF0aW9uIGJ5IHJlcXVlc3RpbmcgdGhlIGZpcnN0IGFuaW1hdGlvbiBmcmFtZVxuICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZShjb3VudFVwKTtcbn0pO1xuXG5cbi8qKkdSQUZJQ08gQSBUT1JUQSAqL1xuY29uc3QgY3R4ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Nob2lyQ2hhcnQnKS5nZXRDb250ZXh0KCcyZCcpO1xuY29uc3QgY2hvaXJDaGFydCA9IG5ldyBDaGFydChjdHgsIHtcbiAgICB0eXBlOiAncGllJyxcbiAgICBkYXRhOiB7XG4gICAgICAgIGxhYmVsczogWydCYXNzaScsICdUZW5vcmknLCAnQ29udHJhbHRpJywgJ1NvcHJhbmknXSxcbiAgICAgICAgZGF0YXNldHM6IFt7XG4gICAgICAgICAgICBsYWJlbDogJyAnLFxuICAgICAgICAgICAgZGF0YTogWzcsIDYsIDE0LCA3XSxcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogW1xuICAgICAgICAgICAgICAgICcjZTQzYjNiZmYnLCAvLyBCYXNzXG4gICAgICAgICAgICAgICAgJyM1NjhlYTNmZicsIC8vIFRlbm9yc1xuICAgICAgICAgICAgICAgICcjNWZiNzVmJywgLy8gQWx0b3NcbiAgICAgICAgICAgICAgICAnI2RiYTE1OWZmJyAgLy8gU29wcmFub3NcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBib3JkZXJDb2xvcjogJyNmZmZmZmYnLFxuICAgICAgICAgICAgYm9yZGVyV2lkdGg6IDJcbiAgICAgICAgfV1cbiAgICB9LFxuICAgIG9wdGlvbnM6IHtcbiAgICAgICAgcmVzcG9uc2l2ZTogdHJ1ZSxcbiAgICAgICAgYW5pbWF0aW9uOiB7XG4gICAgICAgICAgICBkdXJhdGlvbjogMTAwMCxcbiAgICAgICAgICAgIGVhc2luZzogJ2Vhc2VPdXRRdWFkJyxcbiAgICAgICAgICAgIGFuaW1hdGVTY2FsZTogdHJ1ZVxuICAgICAgICB9LFxuICAgICAgICBwbHVnaW5zOiB7XG4gICAgICAgICAgICBsZWdlbmQ6IHtcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogJ2JvdHRvbScsXG4gICAgICAgICAgICAgICAgbGFiZWxzOiB7XG4gICAgICAgICAgICAgICAgICAgIGJveFdpZHRoOiAyMCxcbiAgICAgICAgICAgICAgICAgICAgZm9udDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZTogMTQsXG4gICAgICAgICAgICAgICAgICAgICAgICB3ZWlnaHQ6ICdib2xkJ1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBjb2xvcjogJyMzMzMnLFxuICAgICAgICAgICAgICAgICAgICBwYWRkaW5nOiAxNSxcbiAgICAgICAgICAgICAgICAgICAgdXNlUG9pbnRTdHlsZTogdHJ1ZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0b29sdGlwOiB7XG4gICAgICAgICAgICAgICAgZW5hYmxlZDogdHJ1ZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRhdGFsYWJlbHM6IHtcbiAgICAgICAgICAgICAgICBjb2xvcjogJyMwMDAnLFxuICAgICAgICAgICAgICAgIGZvcm1hdHRlcjogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGFuY2hvcjogJ2NlbnRlcicsXG4gICAgICAgICAgICAgICAgYWxpZ246ICdjZW50ZXInLFxuICAgICAgICAgICAgICAgIG9mZnNldDogMCxcbiAgICAgICAgICAgICAgICBib3JkZXJSYWRpdXM6IDUsXG4gICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiAncmdiYSgyNTUsIDI1NSwgMjU1LCAwLjgpJyxcbiAgICAgICAgICAgICAgICBib3JkZXJXaWR0aDogMSxcbiAgICAgICAgICAgICAgICBib3JkZXJDb2xvcjogJyNjY2MnXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59KTtcblxuLyoqQVBQRUFSSU5HIFRFWFQgQU5JTUFUSU9OIFwiSUwgQ09OVFJPQ09STyDDiC4uLlwiICovXG5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwiRE9NQ29udGVudExvYWRlZFwiLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBwaHJhc2VzID0gW1xuICAgICAgICBcImlsIGNvcm8gZGkgU3BpbiBUaW1lIExhYnMuXCIsXG4gICAgICAgIFwiYXBlcnRvIGEgdHV0dMmZLlwiLFxuICAgICAgICBcInBlciBtdXNpY2lzdGkgZSBuby5cIixcbiAgICAgICAgXCJkaSBzaW5pc3RyYS5cIixcbiAgICAgICAgXCJkaXZlcnRlbnRlIGVkIGVjb25vbWljby5cIixcbiAgICAgICAgXCJpbmNsdXNpdm8uXCIsXG4gICAgXTtcblxuICAgIGNvbnN0IHRleHRFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJjb250cm9jb3JvVGV4dFwiKTtcbiAgICBsZXQgY3VycmVudFBocmFzZUluZGV4ID0gMDtcbiAgICBjb25zdCBhbmltYXRpb25EdXJhdGlvbiA9IDM1MDA7IC8vIER1cmF0aW9uIGZvciBlYWNoIHBocmFzZSBpbiBtaWxsaXNlY29uZHMgKDUgc2Vjb25kcylcblxuICAgIC8vIEZ1bmN0aW9uIHRvIGRpc3BsYXkgdGhlIG5leHQgcGhyYXNlIHdpdGggYSB0eXBld3JpdGVyIGFuaW1hdGlvblxuICAgIGZ1bmN0aW9uIHR5cGVQaHJhc2UocGhyYXNlKSB7XG4gICAgICAgIHRleHRFbGVtZW50LmlubmVySFRNTCA9IFwiXCI7IC8vIENsZWFyIGV4aXN0aW5nIHRleHRcbiAgICAgICAgbGV0IGNoYXJJbmRleCA9IDA7XG5cbiAgICAgICAgZnVuY3Rpb24gdHlwZU5leHRDaGFyKCkge1xuICAgICAgICAgICAgaWYgKGNoYXJJbmRleCA8IHBocmFzZS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB0ZXh0RWxlbWVudC5pbm5lckhUTUwgKz0gcGhyYXNlW2NoYXJJbmRleF0ucmVwbGFjZSgvJmx0Oy9nLCAnPCcpLnJlcGxhY2UoLyZndDsvZywgJz4nKTtcbiAgICAgICAgICAgICAgICBjaGFySW5kZXgrKztcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KHR5cGVOZXh0Q2hhciwgMTAwKTsgLy8gU2V0IGRlbGF5IGZvciB0eXBpbmcgbmV4dCBjaGFyYWN0ZXJcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0eXBlTmV4dENoYXIoKTtcbiAgICB9XG5cbiAgICAvLyBGdW5jdGlvbiB0byBjaGFuZ2UgdG8gdGhlIG5leHQgcGhyYXNlXG4gICAgZnVuY3Rpb24gY2hhbmdlUGhyYXNlKCkge1xuICAgICAgICBjdXJyZW50UGhyYXNlSW5kZXggPSAoY3VycmVudFBocmFzZUluZGV4ICsgMSkgJSBwaHJhc2VzLmxlbmd0aDtcbiAgICAgICAgdHlwZVBocmFzZShwaHJhc2VzW2N1cnJlbnRQaHJhc2VJbmRleF0pO1xuICAgIH1cblxuICAgIC8vIFN0YXJ0IHRoZSB0eXBld3JpdGVyIGFuaW1hdGlvbiBmb3IgdGhlIGluaXRpYWwgcGhyYXNlXG4gICAgdHlwZVBocmFzZShwaHJhc2VzW2N1cnJlbnRQaHJhc2VJbmRleF0pO1xuXG4gICAgLy8gU2V0IGludGVydmFsIHRvIGNoYW5nZSB0aGUgcGhyYXNlIGV2ZXJ5IDUgc2Vjb25kc1xuICAgIHNldEludGVydmFsKGNoYW5nZVBocmFzZSwgYW5pbWF0aW9uRHVyYXRpb24pO1xufSk7XG5cbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJET01Db250ZW50TG9hZGVkXCIsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IHNlY3Rpb25zID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIi5mYWRlaW5cIik7XG4gICAgXG4gICAgY29uc3Qgb2JzZXJ2ZXIgPSBuZXcgSW50ZXJzZWN0aW9uT2JzZXJ2ZXIoKGVudHJpZXMsIG9ic2VydmVyKSA9PiB7XG4gICAgICAgIGVudHJpZXMuZm9yRWFjaChlbnRyeSA9PiB7XG4gICAgICAgICAgICBpZiAoZW50cnkuaXNJbnRlcnNlY3RpbmcpIHtcbiAgICAgICAgICAgICAgICBlbnRyeS50YXJnZXQuc3R5bGUub3BhY2l0eSA9IDE7XG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIudW5vYnNlcnZlKGVudHJ5LnRhcmdldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH0sIHtcbiAgICAgICAgdGhyZXNob2xkOiAxLjBcbiAgICB9KTtcblxuICAgIHNlY3Rpb25zLmZvckVhY2goc2VjdGlvbiA9PiB7XG4gICAgICAgIG9ic2VydmVyLm9ic2VydmUoc2VjdGlvbik7XG4gICAgfSk7XG59KTtcblxuLyoqVE9HR0xFIE1VVEUgVklERU8gKi9cbmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwidW5tdXRlQnV0dG9uXCIpLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBtdXRlZCA9IFwiPGltZyBzcmM9J2h0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9uaWNjb3N0YW50aW5pL2NvbnRyb2Nvcm8tbGFuZGluZy1wYWdlL3JlZnMvaGVhZHMvbWFpbi9zcmMvYXNzZXRzL2ltYWdlcy9tdXRlZC5wbmcnPlwiO1xuICAgIGNvbnN0IHVubXV0ZWQgPSBcIjxpbWcgc3JjPSdodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vbmljY29zdGFudGluaS9jb250cm9jb3JvLWxhbmRpbmctcGFnZS9yZWZzL2hlYWRzL21haW4vc3JjL2Fzc2V0cy9pbWFnZXMvdW5tdXRlZC5wbmcnPlwiO1xuICAgIGNvbnN0IHZpZGVvID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJiYWNrZ3JvdW5kVmlkZW9cIik7XG4gICAgaWYgKHZpZGVvLm11dGVkKSB7XG4gICAgICAgIHZpZGVvLm11dGVkID0gIXZpZGVvLm11dGVkO1xuICAgICAgICB0aGlzLmlubmVySFRNTCA9IHVubXV0ZWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmlkZW8ubXV0ZWQgPSAhdmlkZW8ubXV0ZWQ7XG4gICAgICAgIHRoaXMuaW5uZXJIVE1MID0gbXV0ZWQ7XG4gICAgfVxufSk7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///318\n")},953:(g,I,C)=>{g.exports=C.p+"7e687123cd4528224ce5.ttf"}},__webpack_module_cache__={};function __webpack_require__(g){var I=__webpack_module_cache__[g];if(void 0!==I)return I.exports;var C=__webpack_module_cache__[g]={id:g,exports:{}};return __webpack_modules__[g](C,C.exports,__webpack_require__),C.exports}__webpack_require__.m=__webpack_modules__,__webpack_require__.n=g=>{var I=g&&g.__esModule?()=>g.default:()=>g;return __webpack_require__.d(I,{a:I}),I},__webpack_require__.d=(g,I)=>{for(var C in I)__webpack_require__.o(I,C)&&!__webpack_require__.o(g,C)&&Object.defineProperty(g,C,{enumerable:!0,get:I[C]})},__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(g){if("object"==typeof window)return window}}(),__webpack_require__.o=(g,I)=>Object.prototype.hasOwnProperty.call(g,I),(()=>{var g;__webpack_require__.g.importScripts&&(g=__webpack_require__.g.location+"");var I=__webpack_require__.g.document;if(!g&&I&&(I.currentScript&&"SCRIPT"===I.currentScript.tagName.toUpperCase()&&(g=I.currentScript.src),!g)){var C=I.getElementsByTagName("script");if(C.length)for(var t=C.length-1;t>-1&&(!g||!/^http(s?):/.test(g));)g=C[t--].src}if(!g)throw new Error("Automatic publicPath is not supported in this browser");g=g.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),__webpack_require__.p=g})(),__webpack_require__.b=document.baseURI||self.location.href,__webpack_require__.nc=void 0;var __webpack_exports__=__webpack_require__(318)})(); \ No newline at end of file From cb0486875cdc3e1addc298f4e8d72b3034dbc794 Mon Sep 17 00:00:00 2001 From: niccostantini <65295160+niccostantini@users.noreply.github.com> Date: Wed, 9 Oct 2024 23:51:53 +0200 Subject: [PATCH 3/3] Style gmail button Make all buttons in the mobile view equally wide --- src/styles.css | 31 +++++++++++++++++++++++++++++++ src/template.html | 6 +++--- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/styles.css b/src/styles.css index c4a8aca..1785a47 100644 --- a/src/styles.css +++ b/src/styles.css @@ -40,6 +40,10 @@ r { font-weight: 700; } +.mail { + svg path { fill: #c71610 } +} + header { box-shadow: 0px 5px 18px -6px rgba(0,0,0,0.75); } @@ -266,6 +270,7 @@ footer div:last-child { flex-direction: row; align-items: center; height: 75px; + width: 290px; background-color: var(--air-force-blue); color: var(--creamy-white); @@ -305,6 +310,19 @@ footer div:last-child { box-shadow: -6px 7px 5px #0000008f; } + .card.mail { + border-top: 3px solid #c71610; + border-right: 3px solid #f2a60c; + border-bottom: 3px solid #3b60c4; + border-left: 3px solid #08851b; + + background-color: var(--jet); + } + + .card.mail:hover { + background-color: #0a0000; + } + .ig { background: #833ab4; background: linear-gradient( @@ -580,6 +598,19 @@ footer div:last-child { box-shadow: -6px 7px 5px #0000008f; } + .card.mail { + border-top: 3px solid #c71610; + border-right: 3px solid #f2a60c; + border-bottom: 3px solid #3b60c4; + border-left: 3px solid #08851b; + + background-color: var(--jet); + } + + .card.mail:hover { + background-color: #0a0000; + } + .ig { background: #833ab4; background: linear-gradient( diff --git a/src/template.html b/src/template.html index 7fb1062..27cefc2 100644 --- a/src/template.html +++ b/src/template.html @@ -67,9 +67,9 @@

Unisciti all'armonia

-
- -
+
+ +

controcoro.spintime@gmail.com