The Skip button awaited saveConfigToServer() which fails with 403 when TOTP is required, preventing the wizard from dismissing. Fix: hide wizard FIRST (localStorage-only), then fire server save as fire-and-forget with .catch().
1986 lines
1.2 MiB
Plaintext
1986 lines
1.2 MiB
Plaintext
(function(){injectModal("logo-modal",`<div id="logo-modal" class="weather-modal">
|
|
<div class="weather-modal-content" style="min-width: 400px; max-width: 520px;">
|
|
<h3>Dashboard Settings</h3>
|
|
<p style="font-size: 0.85rem; color: var(--muted); margin: 0 0 16px;">
|
|
Customize your dashboard's appearance and system preferences.
|
|
</p>
|
|
|
|
<div class="mb-16">
|
|
<label for="dashboard-title" class="form-label-bold">Dashboard Title:</label>
|
|
<input type="text" id="dashboard-title" placeholder="DashCaddy" maxlength="50" style="width: 100%; padding: 10px 12px; border: 1px solid var(--border); border-radius: 4px; background: var(--card-bg); color: var(--fg); font-size: 1rem;" />
|
|
<p class="tiny-hint">Shown in browser tab and header (max 50 characters)</p>
|
|
</div>
|
|
|
|
<hr class="hr-divider" />
|
|
|
|
<div class="mb-16">
|
|
<label class="form-label-bold">Logo:</label>
|
|
<p class="tiny-hint" style="margin-top: 2px;">Separate logos for dark and light themes, or use the same for both.</p>
|
|
</div>
|
|
|
|
<div style="display: flex; gap: 12px; margin-bottom: 12px;">
|
|
<div style="flex: 1; text-align: center; padding: 16px 10px; border-radius: 8px; background: #1a1a2e; border: 1px solid rgba(255,255,255,.1);">
|
|
<img id="logo-preview-dark" src="/assets/dashcaddy-logo-dark.png" alt="Dark theme logo" style="max-height: 60px; max-width: 100%;" />
|
|
<p style="font-size: 0.65rem; color: #9aa6bf; margin-top: 6px;">Dark themes</p>
|
|
</div>
|
|
<div style="flex: 1; text-align: center; padding: 16px 10px; border-radius: 8px; background: #f0f0f0; border: 1px solid rgba(0,0,0,.1);">
|
|
<img id="logo-preview-light" src="/assets/dashcaddy-logo-light.png" alt="Light theme logo" style="max-height: 60px; max-width: 100%;" />
|
|
<p style="font-size: 0.65rem; color: #5f6b7a; margin-top: 6px;">Light themes</p>
|
|
</div>
|
|
</div>
|
|
<p id="logo-status" style="font-size: 0.75rem; color: var(--muted); margin-bottom: 12px; text-align: center;">Using default logos</p>
|
|
|
|
<div class="mb-16">
|
|
<label style="display: flex; align-items: center; gap: 8px; font-size: 0.82rem; cursor: pointer; user-select: none;">
|
|
<input type="checkbox" id="logo-same-both" /> Use same logo for both
|
|
</label>
|
|
</div>
|
|
|
|
<div id="logo-dual-uploads" class="mb-16" style="display: flex; gap: 12px;">
|
|
<div style="flex: 1;">
|
|
<label for="logo-upload-dark" style="display: block; margin-bottom: 6px; font-size: 0.8rem;">Dark theme logo:</label>
|
|
<input type="file" id="logo-upload-dark" accept="image/*" class="input-card-alt" style="font-size: 0.75rem;" />
|
|
</div>
|
|
<div style="flex: 1;">
|
|
<label for="logo-upload-light" style="display: block; margin-bottom: 6px; font-size: 0.8rem;">Light theme logo:</label>
|
|
<input type="file" id="logo-upload-light" accept="image/*" class="input-card-alt" style="font-size: 0.75rem;" />
|
|
</div>
|
|
</div>
|
|
|
|
<div id="logo-single-upload" class="mb-16" style="display: none;">
|
|
<label for="logo-upload-single" style="display: block; margin-bottom: 6px; font-size: 0.8rem;">Upload logo:</label>
|
|
<input type="file" id="logo-upload-single" accept="image/*" class="input-card-alt" />
|
|
<p class="tiny-hint">This logo will be used on all themes</p>
|
|
</div>
|
|
|
|
<div class="mb-16">
|
|
<label style="display: block; margin-bottom: 8px;">Logo Position:</label>
|
|
<div id="logo-position-btns" class="flex-row-gap">
|
|
<button type="button" data-pos="left" class="logo-pos-btn btn-option">Left</button>
|
|
<button type="button" data-pos="center" class="logo-pos-btn btn-option">Center</button>
|
|
<button type="button" data-pos="right" class="logo-pos-btn btn-option">Right</button>
|
|
</div>
|
|
</div>
|
|
|
|
<hr class="hr-divider" />
|
|
|
|
<div class="mb-16">
|
|
<label class="form-label-bold">Favicon (Browser Tab Icon):</label>
|
|
<div id="favicon-preview-container" style="display: flex; align-items: center; gap: 12px; margin-bottom: 8px; padding: 12px; border-radius: 6px; background: var(--card-bg);">
|
|
<img id="favicon-preview" src="/assets/dashcaddy-favicon.ico" alt="Current favicon" style="width: 32px; height: 32px; image-rendering: pixelated;" onerror="this.src='data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 32 32%22><rect fill=%22%23667%22 width=%2232%22 height=%2232%22 rx=%224%22/></svg>'" />
|
|
<span id="favicon-status" class="text-tiny-muted">Using DashCaddy favicon</span>
|
|
</div>
|
|
<input type="file" id="favicon-upload" accept="image/png,image/svg+xml" class="input-card-alt" />
|
|
<p class="tiny-hint">Upload PNG or SVG - automatically converted to ICO</p>
|
|
</div>
|
|
|
|
<hr class="hr-divider" />
|
|
|
|
<div class="mb-16">
|
|
<label for="settings-timezone" class="form-label-bold">Timezone:</label>
|
|
<select id="settings-timezone" style="width: 100%; padding: 10px 12px; border: 1px solid var(--border); border-radius: 4px; background: var(--card-bg); color: var(--fg); font-size: 1rem;">
|
|
<!-- Populated by JS with IANA timezones -->
|
|
</select>
|
|
<p class="tiny-hint">Used by all deployed containers. Changes apply to new deployments.</p>
|
|
</div>
|
|
|
|
<div class="weather-modal-buttons">
|
|
<button id="logo-reset" style="background: color-mix(in srgb, #ef4444 20%, transparent); border-color: #ef4444; color: #ef4444;">Reset to Default</button>
|
|
<button id="logo-cancel">Cancel</button>
|
|
<button id="logo-save" class="btn-accent">Save</button>
|
|
</div>
|
|
</div>
|
|
</div>`);const h=document.getElementById("logo-modal"),L=document.getElementById("logo-preview-dark"),A=document.getElementById("logo-preview-light"),I=document.getElementById("logo-status"),D=document.getElementById("logo-same-both"),R=document.getElementById("logo-dual-uploads"),H=document.getElementById("logo-single-upload"),P=document.getElementById("logo-upload-dark"),v=document.getElementById("logo-upload-light"),C=document.getElementById("logo-upload-single"),x=document.querySelector("#brand .brand-logo-dark"),$=document.querySelector("#brand .brand-logo-light"),E=document.querySelector(".top-row"),M=document.getElementById("dashboard-title"),S=DC.NAME;let B=null,U=null,T=null,b="left",N=S;D?.addEventListener("change",()=>{D.checked?(R.style.display="none",H.style.display="",B=null,U=null):(R.style.display="flex",H.style.display="none",T=null)});function O(t,e){if(!t||!t.type.startsWith("image/")){showNotification("Please select an image file","warning");return}const a=new FileReader;a.onload=o=>e(o.target.result),a.readAsDataURL(t)}P?.addEventListener("change",t=>{O(t.target.files[0],e=>{B=e,L.src=e,I.textContent="New dark logo ready to save"})}),v?.addEventListener("change",t=>{O(t.target.files[0],e=>{U=e,A.src=e,I.textContent="New light logo ready to save"})}),C?.addEventListener("change",t=>{O(t.target.files[0],e=>{T=e,L.src=e,A.src=e,I.textContent="New logo ready to save (both themes)"})});function p(t){E.setAttribute("data-logo-pos",t),document.querySelectorAll(".logo-pos-btn").forEach(e=>{e.style.background=e.dataset.pos===t?"var(--accent)":"var(--card-bg)",e.style.color=e.dataset.pos===t?"white":"var(--fg)"})}function u(t){N=t||S,document.title=N;const e=document.querySelector(".dashboard-title");e&&(e.textContent=N)}async function f(){try{const t=await fetch("/api/v1/logo");if(t.ok){const e=await t.json();e.customLogoDark&&(x.src=e.customLogoDark,L.src=e.customLogoDark),e.customLogoLight&&($.src=e.customLogoLight,A.src=e.customLogoLight),!e.customLogoDark&&!e.customLogoLight&&e.customLogo&&(x.src=e.customLogo,$.src=e.customLogo,L.src=e.customLogo,A.src=e.customLogo),e.isDefault||(I.textContent="Using custom logo"),e.position&&(b=e.position,p(e.position)),e.dashboardTitle&&u(e.dashboardTitle)}}catch(t){console.warn("Could not load custom logo:",t.message)}}document.querySelectorAll(".logo-pos-btn").forEach(t=>{t.addEventListener("click",()=>{b=t.dataset.pos,p(b)})}),document.getElementById("brand")?.addEventListener("click",()=>{B=null,U=null,T=null,P&&(P.value=""),v&&(v.value=""),C&&(C.value=""),D&&(D.checked=!1),R.style.display="flex",H.style.display="none",L.src=x.src,A.src=$.src;const t=x.src.includes("custom-logo")||$.src.includes("custom-logo");I.textContent=t?"Using custom logo":"Using default logos",p(b),M.value=N,h.classList.add("show")}),document.getElementById("logo-save")?.addEventListener("click",async()=>{try{const t=M.value.trim()||S,e={position:b,dashboardTitle:t};D?.checked&&T?(e.dataDark=T,e.dataLight=T):(B&&(e.dataDark=B),U&&(e.dataLight=U));const a=await secureFetch("/api/v1/logo",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(a.ok){const o=await a.json(),i="?t="+Date.now();o.pathDark&&(x.src=o.pathDark+i,L.src=o.pathDark+i),o.pathLight&&($.src=o.pathLight+i,A.src=o.pathLight+i),p(b),u(t),h.classList.remove("show")}else{const o=await a.json();showNotification("Failed to save: "+o.error,"error")}}catch(t){showNotification("Error saving: "+t.message,"error")}}),document.getElementById("logo-reset")?.addEventListener("click",async()=>{if(confirm(`Reset all branding to DashCaddy defaults?
|
|
|
|
This will reset the logo, favicon, title, and position.`))try{if((await secureFetch("/api/v1/logo",{method:"DELETE"})).ok&&(x.src="/assets/dashcaddy-logo-dark.png",$.src="/assets/dashcaddy-logo-light.png",L.src="/assets/dashcaddy-logo-dark.png",A.src="/assets/dashcaddy-logo-light.png",I.textContent="Using default logos",B=null,U=null,T=null,M.value=S,u(S),b="left",p("left")),(await secureFetch("/api/v1/favicon",{method:"DELETE"})).ok){const a=document.querySelector('link[rel="icon"]'),o=document.getElementById("favicon-preview"),i=document.getElementById("favicon-status");a&&(a.href="/assets/dashcaddy-favicon.ico?t="+Date.now()),o&&(o.src="/assets/dashcaddy-favicon.ico?t="+Date.now()),i&&(i.textContent="Using DashCaddy favicon"),d=null}}catch(t){showNotification("Error resetting branding: "+t.message,"error")}}),wireModal(h,document.getElementById("logo-cancel"));const g=document.getElementById("favicon-preview"),z=document.getElementById("favicon-status"),r=document.getElementById("favicon-upload"),c=document.querySelector('link[rel="icon"]')||document.createElement("link");let d=null;document.querySelector('link[rel="icon"]')||(c.rel="icon",c.href="/assets/dashcaddy-favicon.ico",document.head.appendChild(c));async function w(){try{const t=await fetch("/api/v1/favicon");if(t.ok){const e=await t.json();e.customFavicon&&(c.href=e.customFavicon+"?t="+Date.now(),g.src=e.customFavicon+"?t="+Date.now(),z.textContent="Using custom favicon")}}catch(t){console.warn("Could not load custom favicon:",t.message)}}r?.addEventListener("change",t=>{const e=t.target.files[0];if(!e)return;if(!e.type.match(/^image\/(png|svg\+xml)$/)){showNotification("Please select a PNG or SVG file","warning"),r.value="";return}const a=new FileReader;a.onload=o=>{d=o.target.result,g.src=d,z.textContent="New favicon ready to save"},a.readAsDataURL(e)}),document.getElementById("logo-save")?.addEventListener("click",async()=>{if(d)try{const t=await secureFetch("/api/v1/favicon",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({data:d})});if(t.ok){const e=await t.json();c.href=e.path+"?t="+Date.now(),g.src=e.path+"?t="+Date.now(),z.textContent="Using custom favicon",d=null}else{const e=await t.json();showNotification("Failed to save favicon: "+e.error,"error")}}catch(t){showNotification("Error saving favicon: "+t.message,"error")}}),w(),f();const y=document.getElementById("settings-timezone");y&&(new MutationObserver(()=>{h.classList.contains("show")&&y.options.length===0&&(async()=>{let e;try{const a=await fetch("/api/v1/config");a.ok&&(e=(await a.json()).timezone)}catch{}window.populateTimezoneSelect(y,e)})()}).observe(h,{attributes:!0,attributeFilter:["class"]}),document.getElementById("logo-save")?.addEventListener("click",async()=>{const e=y.value;if(e)try{const a=await fetch("/api/v1/config");if(!a.ok)return;const o=await a.json();o.timezone=e,o.updatedAt=new Date().toISOString(),await secureFetch("/api/v1/config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)})}catch(a){console.warn("Failed to save timezone:",a.message)}}))})(),window.populateTimezoneSelect=function(h,L){const A=Intl.supportedValuesOf("timeZone"),I=L||Intl.DateTimeFormat().resolvedOptions().timeZone||"UTC";h.innerHTML="";for(const D of A){const R=document.createElement("option");R.value=D,R.textContent=D.replace(/_/g," "),D===I&&(R.selected=!0),h.appendChild(R)}},(function(){let h="homelab",L=null;async function A(){try{const u=await fetch("/api/v1/config");if(u.ok&&(L=await u.json(),L&&L.setupComplete))return document.getElementById("setup-wizard").style.display="none",!0}catch(u){console.warn("Could not fetch server config, checking localStorage fallback:",u.message)}return safeGet("dashcaddy-setup")?(document.getElementById("setup-wizard").style.display="none",!0):(document.getElementById("setup-wizard").style.display="flex",!1)}A();const I=document.getElementById("setup-timezone");I&&window.populateTimezoneSelect(I);function D(p){document.querySelectorAll(".setup-step").forEach(f=>{f.style.display="none"});const u=document.getElementById(p);u&&(u.style.display="block")}function R(){const p=document.getElementById("setup-summary-content");if(!p)return;let u='<div style="display: grid; gap: 20px;">';if(h==="homelab"){const g=document.getElementById("setup-tld")?.value?.trim()||".home",z=document.getElementById("setup-ca-name")?.value?.trim()||"",r=document.getElementById("setup-dns-ip")?.value?.trim()||"",c=document.getElementById("setup-dns-port")?.value?.trim()||DC.DEFAULTS.DNS_PORT;u+=`
|
|
<div>
|
|
<h3 style="margin: 0 0 12px; color: var(--accent);">Home Lab Configuration</h3>
|
|
<div style="display: grid; gap: 12px; font-size: 0.95rem;">
|
|
<div><strong>TLD:</strong> ${g}</div>
|
|
<div><strong>Certificate Authority:</strong> ${z}</div>
|
|
<div><strong>DNS Server:</strong> ${r}:${c}</div>
|
|
<div><strong>Example URLs:</strong> https://uptime${g}, https://nextcloud${g}</div>
|
|
</div>
|
|
</div>
|
|
`}else if(h==="simple"){const g=document.getElementById("setup-simple-ip")?.value?.trim()||"localhost";u+=`
|
|
<div>
|
|
<h3 style="margin: 0 0 12px; color: var(--accent);">Simple Setup</h3>
|
|
<div style="display: grid; gap: 12px; font-size: 0.95rem;">
|
|
<div><strong>Access Method:</strong> IP:Port only</div>
|
|
<div><strong>Default IP:</strong> ${g}</div>
|
|
<div><strong>SSL:</strong> None (HTTP only)</div>
|
|
<div><strong>Example URLs:</strong> http://${g}:8080, http://${g}:3000</div>
|
|
</div>
|
|
</div>
|
|
`}else if(h==="public"){const g=document.getElementById("setup-public-domain")?.value?.trim()||"",z=document.getElementById("setup-public-email")?.value?.trim()||"",r=document.querySelector('input[name="routing-mode"]:checked')?.value||"subdirectory",c=r==="subdirectory"?`https://${g}/sonarr, https://${g}/grafana`:`https://sonarr.${g}, https://grafana.${g}`;u+=`
|
|
<div>
|
|
<h3 style="margin: 0 0 12px; color: var(--accent);">Public Server</h3>
|
|
<div style="display: grid; gap: 12px; font-size: 0.95rem;">
|
|
<div><strong>Domain:</strong> ${g}</div>
|
|
<div><strong>SSL:</strong> Let's Encrypt</div>
|
|
<div><strong>Email:</strong> ${z}</div>
|
|
<div><strong>Routing:</strong> ${r==="subdirectory"?"Subdirectory (domain.com/app)":"Subdomain (app.domain.com)"}</div>
|
|
<div><strong>Example URLs:</strong> ${c}</div>
|
|
</div>
|
|
</div>
|
|
`}const f=document.getElementById("setup-timezone")?.value||Intl.DateTimeFormat().resolvedOptions().timeZone||"UTC";u+=`
|
|
<div style="margin-top: 8px; padding-top: 12px; border-top: 1px solid var(--border);">
|
|
<div style="font-size: 0.95rem;"><strong>Timezone:</strong> ${f.replace(/_/g," ")}</div>
|
|
</div>
|
|
`,u+="</div>",p.innerHTML=u,D("setup-step-summary")}async function H(p){try{const u=await secureFetch("/api/v1/config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(p)});return u.ok?(await u.json(),!0):(errorHandler.logError("[SetupWizard] Save Config",new Error(`Server returned ${u.status}`),{function:"saveConfigToServer"}),!1)}catch(u){return errorHandler.logError("[SetupWizard] Save Config",u,{function:"saveConfigToServer"}),!1}}async function P(){const p={setupComplete:!0,configurationType:h,timestamp:new Date().toISOString(),timezone:document.getElementById("setup-timezone")?.value||Intl.DateTimeFormat().resolvedOptions().timeZone||"UTC"};if(h==="homelab"){p.tld=document.getElementById("setup-tld")?.value?.trim()||".home",p.caName=document.getElementById("setup-ca-name")?.value?.trim()||"";const z=document.getElementById("setup-dns-provider")?.value||"technitium";p.dns={provider:z,ip:document.getElementById("setup-dns-ip")?.value?.trim()||"",port:document.getElementById("setup-dns-port")?.value?.trim()||DC.DEFAULTS.DNS_PORT,token:document.getElementById("setup-dns-token")?.value?.trim()||""},p.defaults={dnsType:"private",sslType:"internal",targetIP:"localhost"}}else h==="simple"?(p.defaultIP=document.getElementById("setup-simple-ip")?.value?.trim()||"localhost",p.defaults={dnsType:"none",sslType:"none",targetIP:p.defaultIP}):h==="public"&&(p.domain=document.getElementById("setup-public-domain")?.value?.trim()||"",p.email=document.getElementById("setup-public-email")?.value?.trim()||"",p.routingMode=document.querySelector('input[name="routing-mode"]:checked')?.value||"subdirectory",p.defaults={dnsType:p.routingMode==="subdirectory"?"none":"public",sslType:"letsencrypt",targetIP:"localhost"});const u=await H(p);safeSet("dashcaddy-config",JSON.stringify(p)),safeSet("dashcaddy-setup","completed"),document.getElementById("setup-wizard").style.display="none";const f=h==="homelab"?"Professional Home Lab":h==="simple"?"Simple Setup":"Public Server",g=u?"server (shared across all devices)":"locally (this browser only)";showNotification(`Setup Complete! Configured for: ${f}. Settings saved to: ${g}`,"success",5e3),setTimeout(()=>location.reload(),500)}const v=document.getElementById("setup-step-1-next");v&&(v.onclick=function(p){p.preventDefault();const u=document.querySelector('input[name="config-type"]:checked');u&&(h=u.value),D(h==="homelab"?"setup-step-homelab":h==="simple"?"setup-step-simple":h==="public"?"setup-step-public":"setup-step-homelab")});const C=document.getElementById("setup-skip");C&&(C.onclick=async function(p){p.preventDefault(),confirm("Skip setup? You can run it later from Settings.")&&(safeSet("dashcaddy-setup","skipped"),document.getElementById("setup-wizard").style.display="none",H({setupComplete:!0,skipped:!0,timestamp:new Date().toISOString()}).catch(()=>{}))});const x=document.getElementById("setup-tld");x&&(x.oninput=function(p){const u=p.target.value||".home",f=document.getElementById("tld-preview"),g=document.getElementById("tld-preview-2");f&&(f.textContent=u),g&&(g.textContent=u)});const $=document.getElementById("setup-homelab-back");$&&($.onclick=function(p){p.preventDefault(),D("setup-step-1")});const E=document.getElementById("setup-homelab-next");E&&(E.onclick=function(p){p.preventDefault();const u=document.getElementById("setup-tld")?.value?.trim()||"",f=document.getElementById("setup-ca-name")?.value?.trim()||"",g=document.getElementById("setup-dns-ip")?.value?.trim()||"";if(!u||!u.startsWith(".")){showNotification("Please enter a valid TLD starting with a dot (e.g., .home)","warning");return}if(!f){showNotification("Please enter a Certificate Authority name","warning");return}if(!g){showNotification("Please enter your DNS server IP address","warning");return}R()});const M=document.getElementById("setup-simple-back");M&&(M.onclick=function(p){p.preventDefault(),D("setup-step-1")});const S=document.getElementById("setup-simple-next");S&&(S.onclick=function(p){p.preventDefault(),R()}),document.querySelectorAll('input[name="routing-mode"]').forEach(function(p){p.onchange=function(){var u=document.getElementById("dns-requirement-note");u&&(u.textContent=this.value==="subdirectory"?"Only one DNS record needed (for the main domain)":"You'll need to configure DNS manually for each subdomain")}});const B=document.getElementById("setup-public-back");B&&(B.onclick=function(p){p.preventDefault(),D("setup-step-1")});const U=document.getElementById("setup-public-next");U&&(U.onclick=function(p){p.preventDefault();const u=document.getElementById("setup-public-domain")?.value?.trim()||"",f=document.getElementById("setup-public-email")?.value?.trim()||"";if(!u){showNotification("Please enter your domain name","warning");return}if(!f||!f.includes("@")){showNotification("Please enter a valid email address","warning");return}R()});const T=document.getElementById("setup-summary-back");T&&(T.onclick=function(p){p.preventDefault(),h==="homelab"?D("setup-step-homelab"):h==="simple"?D("setup-step-simple"):h==="public"&&D("setup-step-public")});const b=document.getElementById("setup-summary-next");b&&(b.onclick=function(p){p.preventDefault(),D("setup-step-disk-safety")});const N=document.getElementById("setup-disk-safety-back");N&&(N.onclick=function(p){p.preventDefault(),D("setup-step-summary")});const O=document.getElementById("setup-disk-safety-finish");O&&(O.onclick=function(p){p.preventDefault(),P()}),window.getGlobalConfig=async function(){try{const u=await fetch("/api/v1/config");if(u.ok){const f=await u.json();if(f&&f.setupComplete)return f}}catch{console.warn("Could not fetch config from server")}const p=safeGet("dashcaddy-config");return p?JSON.parse(p):{setupComplete:!1,configurationType:"homelab",tld:".home",caName:"",defaults:{dnsType:"private",sslType:"internal",targetIP:"localhost"}}},window.resetSetupWizard=async function(){if(confirm("Reset DashCaddy configuration? This will show the setup wizard again.")){try{await secureFetch("/api/v1/config",{method:"DELETE"})}catch{console.warn("Could not delete server config")}safeRemove("dashcaddy-setup"),safeRemove("dashcaddy-config"),location.reload()}}})(),(function(){const h=new ErrorHandler;injectModal("app-selector-modal",`<div id="app-selector-modal" class="weather-modal">
|
|
<div class="app-selector-content">
|
|
<h2 style="margin: 0 0 24px; color: var(--fg); text-align: center;">Choose an App</h2>
|
|
<div id="app-selector-grid" class="app-selector-grid"></div>
|
|
<div style="text-align: center; margin-top: 24px;">
|
|
<button id="app-selector-cancel">Cancel</button>
|
|
</div>
|
|
</div>
|
|
</div>`),injectModal("app-deploy-modal",`<div id="app-deploy-modal" class="weather-modal">
|
|
<div class="weather-modal-content" style="min-width: 600px; max-width: 700px;">
|
|
<h3 id="app-deploy-title">Deploy Application</h3>
|
|
|
|
<div style="display: grid; grid-template-columns: 1fr; gap: 16px; margin-top: 16px;">
|
|
<!-- Subdomain/Domain -->
|
|
<div>
|
|
<label for="deploy-subdomain" class="form-label-accent-sm">
|
|
\u{1F310} Subdomain or Domain
|
|
</label>
|
|
<input type="text" id="deploy-subdomain" placeholder="uptime"
|
|
style="width: 100%; padding: 10px; background: var(--card-bg); color: var(--fg); border: 1px solid var(--border); border-radius: 6px; font-size: 0.95rem;" />
|
|
<div class="form-hint-sm">
|
|
Your app will be available at: <span id="deploy-url-preview" style="color: var(--accent); font-weight: 500;">uptime.home</span>
|
|
</div>
|
|
<div id="subpath-compat-warning" style="display: none; padding: 8px 12px; border-radius: 6px; background: color-mix(in srgb, #ff9800 10%, var(--card-bg)); border: 1px solid color-mix(in srgb, #ff9800 30%, transparent); margin-top: 8px; font-size: 0.85rem;"></div>
|
|
</div>
|
|
|
|
<!-- DNS Configuration -->
|
|
<div>
|
|
<label class="form-label-accent">
|
|
\u{1F5C2}\uFE0F DNS Configuration
|
|
</label>
|
|
<div class="flex-col-gap">
|
|
<label class="radio-option">
|
|
<input type="radio" name="dns-type" value="private" checked style="margin-right: 10px;" />
|
|
<div>
|
|
<div class="fw-500">Private DNS (Technitium)</div>
|
|
<div class="text-hint">Use your local DNS server with custom TLD (.sami, .home, etc.)</div>
|
|
</div>
|
|
</label>
|
|
<label class="radio-option">
|
|
<input type="radio" name="dns-type" value="public" style="margin-right: 10px;" />
|
|
<div>
|
|
<div class="fw-500">Public DNS</div>
|
|
<div class="text-hint">Use a real domain (example.com) - requires DNS provider setup</div>
|
|
</div>
|
|
</label>
|
|
<label class="radio-option">
|
|
<input type="radio" name="dns-type" value="none" style="margin-right: 10px;" />
|
|
<div>
|
|
<div class="fw-500">No DNS (IP:Port only)</div>
|
|
<div class="text-hint">Access via IP address and port - no domain setup</div>
|
|
</div>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- SSL Configuration -->
|
|
<div>
|
|
<label class="form-label-accent">
|
|
\u{1F512} SSL/TLS Certificate
|
|
</label>
|
|
<div class="flex-col-gap">
|
|
<label class="radio-option">
|
|
<input type="radio" name="ssl-type" value="internal" checked style="margin-right: 10px;" />
|
|
<div>
|
|
<div class="fw-500">Internal CA</div>
|
|
<div class="text-hint">Use Caddy's internal certificate authority (self-signed)</div>
|
|
</div>
|
|
</label>
|
|
<label class="radio-option">
|
|
<input type="radio" name="ssl-type" value="letsencrypt" style="margin-right: 10px;" />
|
|
<div>
|
|
<div class="fw-500">Let's Encrypt</div>
|
|
<div class="text-hint">Free public SSL certificate (requires public domain)</div>
|
|
</div>
|
|
</label>
|
|
<label class="radio-option">
|
|
<input type="radio" name="ssl-type" value="none" style="margin-right: 10px;" />
|
|
<div>
|
|
<div class="fw-500">No SSL (HTTP only)</div>
|
|
<div class="text-hint">\u26A0\uFE0F Not recommended - traffic will be unencrypted</div>
|
|
</div>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Media Library Path (shown for media apps) -->
|
|
<div id="media-path-section" style="display: none;">
|
|
<label class="form-label-accent">
|
|
\u{1F4C1} Media Library Location
|
|
</label>
|
|
<div style="display: flex; flex-direction: column; gap: 10px;">
|
|
<!-- Detected mounts from existing media servers -->
|
|
<div id="detected-mounts-container" style="display: none;">
|
|
<div style="font-size: 0.85rem; color: var(--success); margin-bottom: 6px;">
|
|
\u2713 Detected from existing media servers:
|
|
</div>
|
|
<div id="detected-mounts-list" style="display: flex; gap: 8px; flex-wrap: wrap;"></div>
|
|
</div>
|
|
|
|
<!-- Path input with browse button -->
|
|
<div class="flex-row-gap">
|
|
<input type="text" id="deploy-media-path" placeholder="/media/Movies, /media/TVShows"
|
|
class="input-flex" style="font-size: 0.95rem;" />
|
|
<button type="button" id="browse-media-btn" style="padding: 10px 16px; background: var(--accent); color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: 500; white-space: nowrap;">
|
|
\u{1F4C2} Browse
|
|
</button>
|
|
</div>
|
|
|
|
<div id="media-path-description" class="text-hint">
|
|
Select folders from existing servers, browse, or type paths manually. Separate multiple with commas.
|
|
</div>
|
|
|
|
<!-- Selected paths display -->
|
|
<div id="selected-media-paths" style="display: none; flex-wrap: wrap; gap: 6px;"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Plex Claim Token (shown only for Plex deployments) -->
|
|
<div id="plex-claim-section" style="display: none;">
|
|
<label class="form-label-accent">
|
|
\u{1F511} Plex Claim Token
|
|
</label>
|
|
<div class="flex-row-gap">
|
|
<input type="text" id="deploy-plex-claim" placeholder="claim-xxxxxxxxxxxxxxxxxxxx"
|
|
class="input-flex" style="font-size: 0.95rem;" />
|
|
<a href="https://plex.tv/claim" target="_blank" rel="noopener noreferrer"
|
|
style="padding: 10px 16px; background: #e5a00d; color: #000; border: none; border-radius: 6px; cursor: pointer; font-weight: 500; white-space: nowrap; text-decoration: none; display: flex; align-items: center;">
|
|
Get Token
|
|
</a>
|
|
</div>
|
|
<div style="font-size: 0.8rem; color: #e5a00d; margin-top: 4px;">
|
|
Token expires in 4 minutes! Get it right before clicking Deploy. Leave empty to configure Plex manually later.
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tailscale Security -->
|
|
<div id="tailscale-section">
|
|
<label class="form-label-accent">
|
|
\u{1F510} Tailscale Security
|
|
</label>
|
|
<div class="flex-col-gap">
|
|
<label class="radio-option">
|
|
<input type="checkbox" id="deploy-tailscale-only" style="margin-right: 10px; width: 18px; height: 18px;" />
|
|
<div>
|
|
<div class="fw-500">Tailscale-Only Access</div>
|
|
<div class="text-hint">Restrict this service to Tailscale users only (100.x.x.x IPs)</div>
|
|
</div>
|
|
</label>
|
|
<div id="tailscale-status" style="padding: 8px 12px; background: var(--card-bg); border-radius: 6px; font-size: 0.85rem;">
|
|
<span style="color: var(--muted);">Checking Tailscale status...</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Advanced Options (Collapsible) -->
|
|
<details>
|
|
<summary style="cursor: pointer; color: var(--accent); font-weight: 500; margin-bottom: 8px;">\u2699\uFE0F Advanced Options</summary>
|
|
<div style="margin-top: 12px; display: grid; gap: 12px;">
|
|
<div>
|
|
<label for="deploy-port" style="display: block; margin-bottom: 6px;">Custom Port (optional)</label>
|
|
<input type="number" id="deploy-port" placeholder="Leave empty for default"
|
|
class="form-input-card" />
|
|
</div>
|
|
<div>
|
|
<label for="deploy-ip" style="display: block; margin-bottom: 6px;">Target IP Address</label>
|
|
<input type="text" id="deploy-ip" value="localhost"
|
|
class="form-input-card" />
|
|
<div class="form-hint-sm">
|
|
Use 'localhost' for same-host containers, or specific IP for remote services
|
|
</div>
|
|
</div>
|
|
<div id="volume-mounts-section" style="display: none;">
|
|
<label class="form-label-accent-sm">\u{1F4C2} Volume Mounts</label>
|
|
<div style="font-size: 0.8rem; color: var(--muted); margin-bottom: 8px;">
|
|
Customize where container data is stored on the host. Media volumes are configured above.
|
|
</div>
|
|
<div id="volume-mounts-list" style="display: grid; gap: 8px;"></div>
|
|
</div>
|
|
<div style="margin-top: 12px;">
|
|
<label class="form-label-accent-sm">\u2699\uFE0F Resource Limits</label>
|
|
<div style="font-size: 0.8rem; color: var(--muted); margin-bottom: 8px;">
|
|
Optional CPU and memory constraints. Leave at 0 for unlimited.
|
|
</div>
|
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px;">
|
|
<div>
|
|
<label for="deploy-cpu-limit" style="display: block; font-size: 0.78rem; color: var(--muted); margin-bottom: 4px;">CPU Cores</label>
|
|
<input type="number" id="deploy-cpu-limit" value="0" min="0" max="64" step="0.25" class="form-input-card" style="width: 100%;" placeholder="0 = unlimited" />
|
|
</div>
|
|
<div>
|
|
<label for="deploy-memory-limit" style="display: block; font-size: 0.78rem; color: var(--muted); margin-bottom: 4px;">Memory (MB)</label>
|
|
<input type="number" id="deploy-memory-limit" value="0" min="0" max="131072" step="64" class="form-input-card" style="width: 100%;" placeholder="0 = unlimited" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</details>
|
|
</div>
|
|
|
|
<div class="weather-modal-buttons" style="margin-top: 24px;">
|
|
<button id="app-deploy-cancel">Cancel</button>
|
|
<button id="app-deploy-confirm" class="btn-accent">
|
|
\u{1F680} Deploy
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>`);const L="custom-apps";let A=null,I=null;const D=document.getElementById("app-selector-modal"),R=document.getElementById("app-selector-grid");async function H(){try{const c=await(await fetch("/api/v1/apps/templates")).json();if(c.success)return A=c.templates,I=c.categories,!0}catch(r){h.logError("[AppSelector] Fetch Templates",r,{function:"fetchApiTemplates"})}return!1}async function P(r){try{return await(await fetch(`/api/v1/apps/ports/${r}/check`)).json()}catch(c){return h.logError("[AppSelector] Check Port",c,{function:"checkPortAvailability"}),{available:!0}}}async function v(r){try{const d=await(await fetch(`/api/v1/apps/ports/${r}/suggest`)).json();if(d.success)return d.suggestedPort}catch(c){h.logError("[AppSelector] Get Suggested Port",c,{function:"getSuggestedPort"})}return r}async function C(){if(R.innerHTML='<div style="text-align: center; padding: 40px; color: var(--muted);">Loading app templates...</div>',!A&&!await H()){R.innerHTML='<div style="text-align: center; padding: 40px; color: var(--error);">Failed to load app templates. Please try again.</div>';return}R.innerHTML="";const r={};for(const[d,w]of Object.entries(A)){const y=w.category||"Other";r[y]||(r[y]=[]),r[y].push({id:d,...w})}const c=I?Object.keys(I):Object.keys(r).sort();for(const d of c){const w=r[d];if(!w||w.length===0)continue;w.sort((e,a)=>(a.popularity||0)-(e.popularity||0));const y=document.createElement("div");y.className="app-category-header";const t=I?.[d]||{};y.innerHTML=`${escapeHtml(t.icon||"")} ${escapeHtml(d)}`,t.color&&(y.style.borderBottomColor=t.color),R.appendChild(y),w.forEach(e=>{const a=document.createElement("div");a.className="app-option";const o=e.isDashboardWidget,i=o&&safeGet("widget-"+e.id+"-enabled")!=="false",n=o?`<div style="font-size: 0.65rem; padding: 2px 6px; border-radius: 4px; margin-top: 4px; background: ${i?"#2ecc7130":"#e74c3c30"}; color: ${i?"#2ecc71":"#e74c3c"}; font-weight: 600;">${i?"ON":"OFF"}</div>`:"",s=!o&&e.difficulty?`<div style="font-size: 0.65rem; padding: 2px 6px; border-radius: 4px; margin-top: 4px; background: ${e.difficulty==="Easy"?"#2ecc71":e.difficulty==="Intermediate"?"#f39c12":"#e74c3c"}20; color: ${e.difficulty==="Easy"?"#2ecc71":e.difficulty==="Intermediate"?"#f39c12":"#e74c3c"};">${escapeHtml(e.difficulty)}</div>`:"";a.innerHTML=`
|
|
<div class="app-option-icon">${escapeHtml(e.icon||"\u{1F4E6}")}</div>
|
|
<div class="app-option-name">${escapeHtml(e.name)}</div>
|
|
<div class="app-option-desc">${escapeHtml(e.description||"")}</div>
|
|
${n}${s}
|
|
`,o?a.onclick=()=>x(e,a):a.onclick=()=>$(e),R.appendChild(a)})}window.renderRecipeCards&&await window.renderRecipeCards(R)}function x(r,c){const d="widget-"+r.id+"-enabled",y=!(safeGet(d)!=="false");safeSet(d,String(y));const t=r.widgetSelector;if(t){const a=document.querySelector(t);a&&(a.style.display=y?"":"none")}const e=c.querySelector('div[style*="border-radius: 4px"]');e&&(e.textContent=y?"ON":"OFF",e.style.background=y?"#2ecc7130":"#e74c3c30",e.style.color=y?"#2ecc71":"#e74c3c"),showNotification(`${r.name} widget ${y?"enabled":"disabled"}`,"success",2e3)}async function $(r){const c=document.getElementById("app-deploy-modal"),d=document.getElementById("app-deploy-title"),w=document.getElementById("deploy-subdomain"),y=document.getElementById("deploy-url-preview"),t=document.getElementById("deploy-ip"),e=document.getElementById("deploy-port"),a=document.getElementById("deploy-tailscale-only"),o=document.getElementById("tailscale-status");try{const W=await(await secureFetch("/api/v1/apps/check-existing",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({appId:r.id})})).json();if(W.success&&W.exists){const V=W.container;confirm(`Found existing ${r.name} container:
|
|
|
|
Container: ${V.name}
|
|
Status: ${V.status}
|
|
Port: ${V.primaryPort||"N/A"}
|
|
|
|
Would you like to use this existing container?
|
|
|
|
Click OK to configure DNS/Caddy for the existing container.
|
|
Click Cancel to deploy a new container.`)&&(r._useExisting=!0,r._existingContainer=V)}}catch{}d.textContent=`Deploy ${r.name}`;const i=r.subdomain||r.id.replace(/-/g,"");w.value=i;const n=document.getElementById("subpath-compat-warning");if(n)if(SITE.routingMode==="subdirectory"){const G=r.subpathSupport||"strip";G==="none"?(n.style.display="block",n.innerHTML='<span style="color: #ff9800;">⚠ <strong>'+r.name+"</strong> does not support subdirectory mode. It may not work correctly at a subpath.</span>"):G==="strip"?(n.style.display="block",n.innerHTML='<span style="color: var(--muted);">ⓘ '+r.name+" has unverified subdirectory support. It may require additional configuration.</span>"):n.style.display="none"}else n.style.display="none";const s=SITE.defaults.dnsType||(SITE.configurationType==="public"?"public":"private"),l=SITE.defaults.sslType||(SITE.configurationType==="public"?"letsencrypt":"internal"),m=document.querySelector(`input[name="dns-type"][value="${s}"]`),k=document.querySelector(`input[name="ssl-type"][value="${l}"]`);m?m.checked=!0:document.querySelector('input[name="dns-type"][value="private"]').checked=!0,k?k.checked=!0:document.querySelector('input[name="ssl-type"][value="internal"]').checked=!0,t.value=SITE.defaults.targetIP||"localhost",a.checked=!1;const j=document.querySelector("#app-deploy-modal .flex-col-gap")?.closest("div"),_=document.querySelector("#app-deploy-modal details"),F=_?.querySelector("div");if(_&&F&&(SITE.configurationType==="public"||SITE.configurationType==="homelab")){const G=document.querySelectorAll('#app-deploy-modal input[name="dns-type"]')[0]?.closest("div.flex-col-gap")?.parentElement,W=document.querySelectorAll('#app-deploy-modal input[name="ssl-type"]')[0]?.closest("div.flex-col-gap")?.parentElement;G&&!G.dataset.moved&&(F.appendChild(G),G.dataset.moved="1"),W&&!W.dataset.moved&&(F.appendChild(W),W.dataset.moved="1")}const q=document.getElementById("media-path-section"),J=document.getElementById("deploy-media-path"),X=document.getElementById("media-path-description");if(r.mediaMount){q.style.display="block",J.value="",J.placeholder="/media/Movies, /media/TVShows or click Browse";const G=document.getElementById("detected-mounts-container"),W=document.getElementById("detected-mounts-list");try{const K=await(await fetch("/api/v1/media/detected-mounts")).json();if(K.success&&K.mounts.length>0){G.style.display="block",W.innerHTML="";const te=[...new Set(K.mounts.map(ee=>ee.hostPath))];J.value=te.join(", "),K.mounts.forEach(ee=>{const Z=document.createElement("button");Z.type="button";const de=te.includes(ee.hostPath);Z.style.cssText=`padding: 8px 14px; font-size: 0.85rem; background: color-mix(in srgb, var(--success) ${de?"40%":"15%"}, var(--card-bg)); border: 1px solid var(--success); border-radius: 6px; cursor: pointer; color: var(--fg);`,Z.innerHTML=`<span style="font-weight: 500;">${escapeHtml(ee.folderName)}</span><br><span style="font-size: 0.7rem; color: var(--muted);">from ${escapeHtml(ee.sourceImage)}</span>`,Z.title=`${ee.hostPath} (from ${ee.sourceContainer})`,Z.onclick=()=>{const le=J.value.split(",").map(ce=>ce.trim()).filter(ce=>ce),pe=le.indexOf(ee.hostPath);pe>=0?(le.splice(pe,1),Z.style.background="color-mix(in srgb, var(--success) 15%, var(--card-bg))"):(le.push(ee.hostPath),Z.style.background="color-mix(in srgb, var(--success) 40%, var(--card-bg))"),J.value=le.join(", ")},W.appendChild(Z)})}else G.style.display="none"}catch{G.style.display="none"}document.getElementById("browse-media-btn").onclick=()=>{openFolderBrowser(J)}}else q.style.display="none",J.value="",document.getElementById("detected-mounts-container").style.display="none";const Q=document.getElementById("plex-claim-section");Q&&(r.id==="plex"||r.claimToken?(Q.style.display="block",document.getElementById("deploy-plex-claim").value=""):Q.style.display="none");const ne=document.getElementById("volume-mounts-section"),oe=document.getElementById("volume-mounts-list");if(oe.innerHTML="",r.docker?.volumes?.length){const G=r.mediaMount?.containerPath,W=r.docker.volumes.filter(V=>!V.includes("{{MEDIA_PATH}}")&&!(G&&V.endsWith(":"+G)));W.length>0?(ne.style.display="block",W.forEach((V,K)=>{const[te,ee]=V.split(":"),Z=document.createElement("div");Z.style.cssText="display: flex; gap: 6px; align-items: center;",Z.innerHTML=`
|
|
<input type="text" class="vol-host-path" data-container-path="${ee}" value="${te}"
|
|
style="flex: 1; padding: 8px; background: var(--card-bg); color: var(--fg); border: 1px solid var(--border); border-radius: 6px; font-size: 0.85rem;" />
|
|
<span style="color: var(--muted); font-size: 0.85rem; white-space: nowrap;">\u2192 ${ee}</span>
|
|
<button type="button" class="vol-browse-btn" style="padding: 8px 10px; background: var(--accent); color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 0.8rem;">\u{1F4C2}</button>
|
|
`,oe.appendChild(Z),Z.querySelector(".vol-browse-btn").onclick=()=>{const de=Z.querySelector(".vol-host-path");openFolderBrowser(de)}})):ne.style.display="none"}else ne.style.display="none";const se=r.defaultPort||8080;e.value="",e.placeholder=`Default: ${se}`;let Y=document.getElementById("deploy-port-status");Y||(Y=document.createElement("div"),Y.id="deploy-port-status",Y.style.cssText="font-size: 0.8rem; margin-top: 4px;",e.parentNode.appendChild(Y));async function ie(){const G=e.value||se;Y.innerHTML='<span style="color: var(--muted);">Checking port...</span>';const W=await P(G);if(W.available)Y.innerHTML=`<span style="color: #4caf50;">Port ${escapeHtml(String(G))} is available</span>`;else{const V=await v(se);Y.innerHTML=`
|
|
<span style="color: #e74c3c;">Port ${escapeHtml(G)} in use by ${escapeHtml(W.conflict?.usedBy||"unknown")}</span>
|
|
`;const K=document.createElement("button");K.type="button",K.textContent=`Use ${V}`,K.style.cssText="margin-left: 8px; padding: 2px 8px; font-size: 0.75rem; cursor: pointer;",K.onclick=()=>{document.getElementById("deploy-port").value=V,Y.innerHTML=`<span style="color: #4caf50;">Using suggested port ${escapeHtml(String(V))}</span>`},Y.appendChild(K)}}let re;e.oninput=function(){clearTimeout(re),re=setTimeout(ie,500)},ie();try{const W=await(await fetch("/api/v1/tailscale/status")).json();W.success&&W.installed&&W.connected?o.innerHTML=`
|
|
<span style="color: #4caf50;">Connected</span>
|
|
<span style="color: var(--muted); margin-left: 8px;">${W.self?.hostname} (${W.self?.ip})</span>
|
|
<span style="color: var(--muted); margin-left: 8px;">| ${W.deviceCount} devices</span>
|
|
`:W.installed?o.innerHTML='<span style="color: #ff9800;">Not connected</span>':(o.innerHTML='<span style="color: var(--muted);">Not available</span>',a.disabled=!0)}catch{o.innerHTML='<span style="color: var(--muted);">Could not check status</span>'}function ae(){const G=w.value||"subdomain",W=document.querySelector('input[name="dns-type"]:checked').value,V=document.querySelector('input[name="ssl-type"]:checked').value;let K="";if(SITE.routingMode==="subdirectory"&&SITE.domain)K=`https://${SITE.domain}/${G}`;else if(W==="private")K=`${V==="none"?"http":"https"}://${buildDomain(G)}`;else if(W==="public"){const te=V==="none"?"http":"https",ee=SITE.domain||G;K=SITE.domain?`${te}://${G}.${SITE.domain}`:`${te}://${G}`}else{const te=e.value||r.defaultPort||DC.DEFAULTS.SERVICE_PORT;K=`http://${t.value}:${te}`}y.textContent=K}w.oninput=ae,t.oninput=ae,e.oninput=ae,document.querySelectorAll('input[name="dns-type"]').forEach(G=>{G.onchange=ae}),document.querySelectorAll('input[name="ssl-type"]').forEach(G=>{G.onchange=ae}),ae(),D.classList.remove("show"),c.classList.add("show"),c.dataset.appTemplate=JSON.stringify(r)}async function E(r){const c=r.appTemplate,d=safeGetJSON(L,[]),w=c._useExisting&&c._existingContainer,y=d.find(t=>t.id===r.subdomain);if(!(y&&!w&&!confirm(`An app with subdomain "${r.subdomain}" already exists. Redeploy?`))){if(y){const t=d.indexOf(y);d.splice(t,1),safeSet(L,JSON.stringify(d))}if(w)r.port=c._existingContainer.primaryPort;else{const t=r.port||c.defaultPort||8080;showNotification(`Checking port ${t} availability...`,"info",0);const e=await P(t);if(!e.available){const a=await v(c.defaultPort||8080);if(confirm(`Port ${t} is already in use by ${e.conflict?.usedBy||"another container"}.
|
|
|
|
Would you like to use port ${a} instead?`))r.port=a;else{showNotification("Deployment cancelled - port conflict","error",5e3);return}}}showNotification(w?`Configuring ${c.name} with existing container...`:`Deploying ${c.name}...`,"info",0);try{const t={appId:c.id,config:{subdomain:r.subdomain,ip:r.ip,createDns:r.dnsType==="private",port:r.port||c.defaultPort||null,sslType:r.sslType,dnsType:r.dnsType,tailscaleOnly:r.tailscaleOnly||!1,mediaPath:r.mediaPath||null,plexClaimToken:r.plexClaimToken||null,customVolumes:r.customVolumes||null}};w&&(t.config.useExisting=!0,t.config.existingContainerId=c._existingContainer.id,t.config.existingPort=c._existingContainer.primaryPort,!r.port&&c._existingContainer.primaryPort&&(t.config.port=c._existingContainer.primaryPort));const a=await(await secureFetch("/api/v1/apps/deploy",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})).json();if(a.success){const o={id:r.subdomain,name:c.name,logo:`/assets/${c.id}.png`,containerId:a.containerId,url:a.url,ip:r.ip,appTemplate:c.id,tailscaleOnly:r.tailscaleOnly||!1};d.push(o),safeSet(L,JSON.stringify(d)),window.APPS&&!window.APPS.some(n=>n.id===c.id)&&(window.APPS.push(o),typeof window.buildGrid=="function"&&window.buildGrid(),typeof window.refreshAll=="function"&&setTimeout(()=>window.refreshAll(),500));let i=a.usedExisting?`${c.name} configured with existing container!
|
|
URL: ${a.url}`:`${c.name} deployed successfully!
|
|
URL: ${a.url}`;a.warning&&(i+=`
|
|
|
|
\u26A0 Warning: ${a.warning}`),showNotification(i,"success",8e3),delete c._useExisting,delete c._existingContainer,a.url&&a.url.startsWith("https://")&&M(a.url,c.name),a.setupInstructions&&a.setupInstructions.length>0&&setTimeout(()=>{const n=a.setupInstructions.join(`
|
|
`);showNotification(`Setup Instructions for ${c.name}: ${n}`,"info",1e4)},1e3)}else throw new Error(a.error||"Deployment failed")}catch(t){h.logError("[AppSelector] Deployment",t,{function:"deploy"}),showNotification(`Failed to deploy ${c.name}: ${t.message}`,"error",8e3)}}}async function M(r,c){showNotification(`\u23F3 Generating SSL certificate for ${c}...`,"warning",6e4);let d=0;const w=12,y=async()=>{d++;try{const t=await fetch(r,{method:"HEAD",mode:"no-cors"});return showNotification(`\u2705 ${c} is ready! SSL certificate generated.`,"success",5e3),!0}catch{return d<w?setTimeout(y,5e3):showNotification(`\u26A0\uFE0F ${c} deployed but SSL certificate may still be generating.
|
|
Try refreshing in a moment if you see a certificate error.`,"warning",1e4),!1}};setTimeout(y,3e3)}function S(){safeGetJSON(L,[]).forEach(c=>{window.APPS.some(d=>d.id===c.id)||window.APPS.push(c)})}document.getElementById("add-service-btn")?.addEventListener("click",()=>{C(),D.classList.add("show")}),wireModal(D,document.getElementById("app-selector-cancel"));const B=document.getElementById("app-deploy-modal");document.getElementById("app-deploy-cancel")?.addEventListener("click",()=>{B.classList.remove("show")}),document.getElementById("app-deploy-confirm")?.addEventListener("click",()=>{const r=JSON.parse(B.dataset.appTemplate),c=document.getElementById("deploy-media-path").value.trim(),d=[];document.querySelectorAll("#volume-mounts-list .vol-host-path").forEach(y=>{d.push({hostPath:y.value.trim(),containerPath:y.dataset.containerPath})});const w={appTemplate:r,subdomain:document.getElementById("deploy-subdomain").value.trim(),dnsType:document.querySelector('input[name="dns-type"]:checked').value,sslType:document.querySelector('input[name="ssl-type"]:checked').value,ip:document.getElementById("deploy-ip").value.trim(),port:document.getElementById("deploy-port").value.trim(),tailscaleOnly:document.getElementById("deploy-tailscale-only").checked,mediaPath:c||null,plexClaimToken:document.getElementById("deploy-plex-claim")?.value.trim()||null,customVolumes:d.length>0?d:null,resources:{cpus:parseFloat(document.getElementById("deploy-cpu-limit").value)||0,memory:parseFloat(document.getElementById("deploy-memory-limit").value)||0}};if(!w.subdomain){showNotification("Please enter a subdomain or domain name","warning");return}if(r.mediaMount?.required&&!c){showNotification("Please enter a media library path for this application","warning");return}B.classList.remove("show"),E(w)}),wireModal(B);const U=document.getElementById("folder-browser-modal"),T=document.getElementById("folder-browser-path"),b=document.getElementById("folder-browser-list"),N=document.getElementById("folder-browser-selected"),O=document.getElementById("folder-browser-selected-list");let p="",u=[],f=null;window.openFolderBrowser=function(r){f=r,u=r.value.split(",").map(c=>c.trim()).filter(c=>c),p="",z(),g(""),U.classList.add("show")};async function g(r){T.textContent=r||"Select a drive...",b.innerHTML='<div style="padding: 20px; text-align: center; color: var(--muted);">Loading...</div>';try{const d=await(await fetch(`/api/v1/browse/directories?path=${encodeURIComponent(r)}`)).json();if(!d.success){b.innerHTML=`<div style="padding: 20px; text-align: center; color: var(--error);">Error: ${escapeHtml(d.error)}</div>`;return}p=d.path||"",T.textContent=p||"Select a drive...";let w="";d.parent&&d.parent!==d.path&&(w+=`<div class="folder-item" data-path="${escapeHtml(d.parent)}" style="padding: 12px 16px; border-bottom: 1px solid var(--border); cursor: pointer; display: flex; align-items: center; gap: 10px;">
|
|
<span style="font-size: 1.2rem;">\u2B06\uFE0F</span>
|
|
<span style="color: var(--muted);">.. Parent Directory</span>
|
|
</div>`),d.items.length===0&&!d.parent?w+='<div style="padding: 20px; text-align: center; color: var(--muted);">No browseable drives configured. Check your docker-compose.yml volume mounts.</div>':d.items.length===0?w+='<div style="padding: 20px; text-align: center; color: var(--muted);">No subfolders found</div>':d.items.forEach(y=>{const t=y.type==="drive"?"\u{1F4BE}":"\u{1F4C1}",e=u.includes(y.path),a=e?"background: color-mix(in srgb, var(--success) 20%, transparent);":"";w+=`<div class="folder-item" data-path="${escapeHtml(y.path)}" style="padding: 12px 16px; border-bottom: 1px solid var(--border); cursor: pointer; display: flex; align-items: center; gap: 10px; ${a}">
|
|
<span style="font-size: 1.2rem;">${t}</span>
|
|
<span style="flex: 1;">${escapeHtml(y.name)}</span>
|
|
${e?'<span style="color: var(--success);">\u2713</span>':""}
|
|
</div>`}),b.innerHTML=w,b.querySelectorAll(".folder-item").forEach(y=>{y.addEventListener("click",()=>{g(y.dataset.path)}),y.addEventListener("mouseenter",()=>{y.style.background="var(--card-bg)"}),y.addEventListener("mouseleave",()=>{const t=u.includes(y.dataset.path);y.style.background=t?"color-mix(in srgb, var(--success) 20%, transparent)":""})})}catch(c){b.innerHTML=`<div style="padding: 20px; text-align: center; color: var(--error);">Failed to load: ${escapeHtml(c.message)}</div>`}}function z(){if(u.length===0){N.style.display="none";return}N.style.display="block",O.innerHTML=u.map(r=>`
|
|
<span style="padding: 6px 12px; background: var(--card-bg); border: 1px solid var(--success); border-radius: 4px; display: flex; align-items: center; gap: 6px;">
|
|
${escapeHtml(r)}
|
|
<button type="button" onclick="removeSelectedFolder('${escapeHtml(r)}')" style="background: none; border: none; cursor: pointer; color: var(--error); font-size: 1rem; padding: 0;">\xD7</button>
|
|
</span>
|
|
`).join("")}window.removeSelectedFolder=function(r){u=u.filter(c=>c!==r),z(),g(p)},document.getElementById("folder-browser-select-current").addEventListener("click",()=>{p&&!u.includes(p)&&(u.push(p),z(),g(p))}),wireModal(U,document.getElementById("folder-browser-cancel")),document.getElementById("folder-browser-done").addEventListener("click",()=>{f&&(f.value=u.join(", ")),U.classList.remove("show")}),S()})(),(function(){injectModal("recipe-deploy-modal",`<div id="recipe-deploy-modal" class="weather-modal">
|
|
<div class="weather-modal-content" style="min-width: 620px; max-width: 740px;">
|
|
<h3 id="recipe-deploy-title">Deploy Recipe</h3>
|
|
|
|
<!-- Step indicator -->
|
|
<div id="recipe-steps" style="display: flex; gap: 4px; margin: 16px 0 24px;">
|
|
<div class="recipe-step active" data-step="1"><span>1</span> Components</div>
|
|
<div class="recipe-step" data-step="2"><span>2</span> Configuration</div>
|
|
<div class="recipe-step" data-step="3"><span>3</span> Review</div>
|
|
<div class="recipe-step" data-step="4"><span>4</span> Progress</div>
|
|
</div>
|
|
|
|
<!-- Step 1: Component Selection -->
|
|
<div id="recipe-step-1" class="recipe-step-panel">
|
|
<label class="form-label-accent-sm">Select Components:</label>
|
|
<div id="recipe-component-list" style="display: grid; gap: 10px; margin-top: 8px;"></div>
|
|
</div>
|
|
|
|
<!-- Step 2: Shared Configuration -->
|
|
<div id="recipe-step-2" class="recipe-step-panel" style="display:none;">
|
|
<div style="display: grid; gap: 16px;">
|
|
<!-- Shared volumes -->
|
|
<div id="recipe-volumes-section" style="display:none;">
|
|
<label class="form-label-accent-sm">Shared Volumes:</label>
|
|
<div id="recipe-volume-list" style="display: grid; gap: 10px; margin-top: 8px;"></div>
|
|
</div>
|
|
|
|
<!-- Timezone -->
|
|
<div>
|
|
<label class="form-label-accent-sm">Timezone:</label>
|
|
<input type="text" id="recipe-timezone" value="UTC" placeholder="e.g. America/New_York"
|
|
style="width: 100%; padding: 8px 12px; background: var(--card-bg); color: var(--fg); border: 1px solid var(--border); border-radius: 6px;" />
|
|
</div>
|
|
|
|
<!-- Target IP -->
|
|
<div>
|
|
<label class="form-label-accent-sm">Target IP Address:</label>
|
|
<input type="text" id="recipe-ip" value="host.docker.internal" placeholder="localhost or IP"
|
|
style="width: 100%; padding: 8px 12px; background: var(--card-bg); color: var(--fg); border: 1px solid var(--border); border-radius: 6px;" />
|
|
<div class="form-hint-sm">IP where containers expose ports</div>
|
|
</div>
|
|
|
|
<!-- Tailscale -->
|
|
<label class="checkbox-label">
|
|
<input type="checkbox" id="recipe-tailscale" />
|
|
<span>Restrict to Tailscale network only</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Step 3: Review -->
|
|
<div id="recipe-step-3" class="recipe-step-panel" style="display:none;">
|
|
<div id="recipe-review-content" style="font-size: 0.9rem; line-height: 1.7;"></div>
|
|
</div>
|
|
|
|
<!-- Step 4: Progress -->
|
|
<div id="recipe-step-4" class="recipe-step-panel" style="display:none;">
|
|
<div id="recipe-progress-list" style="display: grid; gap: 8px;"></div>
|
|
<div id="recipe-deploy-result" style="margin-top: 16px; display:none;"></div>
|
|
</div>
|
|
|
|
<div class="weather-modal-buttons" style="margin-top: 20px;">
|
|
<button id="recipe-cancel">Cancel</button>
|
|
<button id="recipe-prev" class="btn-accent" style="display:none;">Back</button>
|
|
<button id="recipe-next" class="btn-accent-solid">Next</button>
|
|
</div>
|
|
</div>
|
|
</div>`);let h=null,L=null,A=null,I=1,D=!1;const R=document.getElementById("recipe-deploy-modal"),H=document.getElementById("recipe-cancel"),P=document.getElementById("recipe-prev"),v=document.getElementById("recipe-next");wireModal(R,H);async function C(){try{const p=await fetch("/api/v1/recipes/templates"),u=await p.json();if(u.success)return h=u.templates,L=u.categories,!0;if(p.status===403)return D=!1,!1}catch(p){console.warn("Failed to fetch recipe templates:",p.message)}return!1}async function x(){try{D=(await(await fetch("/api/v1/license/feature/recipes")).json()).available}catch{D=!1}return D}window.renderRecipeCards=async function(p){await x();let u;if(D&&h?u=h:u=$(),!u||u.length===0)return;const f=document.createElement("div");f.className="app-category-header",f.innerHTML="\u{1F9EA} Recipes",f.style.borderBottomColor="#8e44ad",p.appendChild(f);const g=Array.isArray(u)?u:Object.values(u);g.sort((z,r)=>(r.popularity||0)-(z.popularity||0));for(const z of g){const r=document.createElement("div");r.className="app-option",r.style.position="relative";const c=`<div style="font-size: 0.65rem; padding: 2px 6px; border-radius: 4px; margin-top: 4px; background: rgba(142,68,173,0.2); color: #a855f7;">${z.componentCount||z.components?.length||"?"} apps</div>`,d=D?"":'<div style="position: absolute; top: 6px; right: 6px; font-size: 0.65rem; padding: 2px 8px; border-radius: 10px; background: rgba(241,196,15,0.2); color: #f1c40f; font-weight: 600;">PREMIUM</div>';r.innerHTML=`
|
|
${d}
|
|
<div class="app-option-icon">${escapeHtml(z.icon||"\u{1F9EA}")}</div>
|
|
<div class="app-option-name">${escapeHtml(z.name)}</div>
|
|
<div class="app-option-desc">${escapeHtml(z.description||"")}</div>
|
|
${c}
|
|
`,r.onclick=()=>{if(!D){showNotification("Recipes require a DashCaddy Premium license. Click the License button to activate.","warning",5e3),window.openLicenseModal&&window.openLicenseModal();return}E(z)},p.appendChild(r)}};function $(){return[{id:"htpc-suite",name:"HTPC Suite",icon:"\u{1F3AC}",description:"Complete media automation: find, download, organize, and stream",componentCount:6,popularity:98},{id:"nextcloud-complete",name:"Nextcloud Complete",icon:"\u2601\uFE0F",description:"Full productivity suite: cloud storage, office editing, and collaboration",componentCount:4,popularity:90},{id:"smart-home",name:"Smart Home Hub",icon:"\u{1F3E0}",description:"Home automation: control, automate, and monitor IoT devices",componentCount:4,popularity:88},{id:"dev-environment",name:"Dev Environment",icon:"\u{1F4BB}",description:"Self-hosted development workflow: Git, CI/CD, IDE, and database",componentCount:4,popularity:82}]}function E(p){A=p,I=1;const u=document.getElementById("app-selector-modal");u&&u.classList.remove("show"),document.getElementById("recipe-deploy-title").textContent=`Deploy ${p.name}`,M(),S(),R.classList.add("show")}function M(){document.querySelectorAll("#recipe-steps .recipe-step").forEach(p=>{const u=parseInt(p.dataset.step);p.classList.toggle("active",u===I),p.classList.toggle("completed",u<I)});for(let p=1;p<=4;p++){const u=document.getElementById(`recipe-step-${p}`);u&&(u.style.display=p===I?"":"none")}P.style.display=I>1&&I<4?"":"none",I===4?(v.style.display="none",H.textContent="Close"):I===3?(v.textContent="\u{1F680} Deploy",v.style.display="",H.textContent="Cancel"):(v.textContent="Next",v.style.display="",H.textContent="Cancel")}function S(){const p=document.getElementById("recipe-component-list");p.innerHTML="";const u=A.components||[];for(const f of u){const g=document.createElement("div");g.style.cssText="display: flex; align-items: center; gap: 12px; padding: 12px; border-radius: 8px; background: var(--card-bg); border: 1px solid var(--border);";const z=f.required,r=f.internal;g.innerHTML=`
|
|
<input type="checkbox" ${z?"checked disabled":"checked"} data-component-id="${f.id}"
|
|
style="width: 18px; height: 18px; accent-color: var(--accent);" />
|
|
<div style="flex: 1;">
|
|
<div style="font-weight: 600; font-size: 0.9rem;">${escapeHtml(f.role||f.id)}</div>
|
|
<div style="font-size: 0.78rem; color: var(--muted);">
|
|
${f.templateRef?escapeHtml(f.templateRef):"Built-in"}
|
|
${z?'<span style="color: var(--accent); margin-left: 6px;">Required</span>':'<span style="color: var(--muted); margin-left: 6px;">Optional</span>'}
|
|
${r?'<span style="color: var(--muted); margin-left: 6px;">(Internal)</span>':""}
|
|
</div>
|
|
${f.note?`<div style="font-size: 0.75rem; color: var(--warn-fg); margin-top: 4px;">\u26A0 ${escapeHtml(f.note)}</div>`:""}
|
|
</div>
|
|
`,p.appendChild(g)}}function B(){const p=document.getElementById("recipe-volumes-section"),u=document.getElementById("recipe-volume-list"),f=A.sharedVolumes;if(f&&Object.keys(f).length>0){p.style.display="",u.innerHTML="";for(const[g,z]of Object.entries(f)){const r=document.createElement("div");r.style.cssText="display: grid; gap: 4px;",r.innerHTML=`
|
|
<label style="font-weight: 500; font-size: 0.85rem;">${escapeHtml(z.label||g)}</label>
|
|
<input type="text" data-volume-key="${g}" value="${escapeHtml(z.defaultPath||"")}"
|
|
placeholder="${escapeHtml(z.defaultPath||"/path")}"
|
|
style="width: 100%; padding: 8px 12px; background: var(--card-bg); color: var(--fg); border: 1px solid var(--border); border-radius: 6px; font-family: monospace; font-size: 0.85rem;" />
|
|
<div class="form-hint-sm">${escapeHtml(z.description||"")}</div>
|
|
`,u.appendChild(r)}}else p.style.display="none"}function U(){const p=document.getElementById("recipe-review-content"),u=T(),f=document.querySelectorAll("#recipe-volume-list input[data-volume-key]"),g={};f.forEach(d=>{g[d.dataset.volumeKey]=d.value});const z=document.getElementById("recipe-timezone").value||"UTC",r=document.getElementById("recipe-ip").value||"host.docker.internal",c=document.getElementById("recipe-tailscale").checked;p.innerHTML=`
|
|
<div style="font-weight: 600; font-size: 1rem; margin-bottom: 12px;">${escapeHtml(A.name)}</div>
|
|
<div style="color: var(--muted); margin-bottom: 16px;">${escapeHtml(A.description||"")}</div>
|
|
|
|
<div style="margin-bottom: 12px;">
|
|
<strong>Components (${u.length}):</strong>
|
|
<div style="display: grid; gap: 4px; margin-top: 6px;">
|
|
${u.map(d=>`<div style="padding: 4px 0; font-size: 0.85rem;">
|
|
\u2022 <strong>${escapeHtml(d.role||d.id)}</strong> ${d.internal?'<span style="color:var(--muted)">(internal)</span>':""}
|
|
</div>`).join("")}
|
|
</div>
|
|
</div>
|
|
|
|
${Object.keys(g).length>0?`<div style="margin-bottom: 12px;">
|
|
<strong>Volumes:</strong>
|
|
${Object.entries(g).map(([d,w])=>`<div style="font-size: 0.85rem; font-family: monospace; color: var(--muted);">${d}: ${escapeHtml(w)}</div>`).join("")}
|
|
</div>`:""}
|
|
|
|
<div style="font-size: 0.85rem; color: var(--muted);">
|
|
Timezone: ${escapeHtml(z)} • IP: ${escapeHtml(r)} ${c?"• Tailscale only":""}
|
|
</div>
|
|
|
|
${A.network?`<div style="font-size: 0.85rem; color: var(--muted); margin-top: 4px;">Docker network: <code>${escapeHtml(A.network.name)}</code></div>`:""}
|
|
`}function T(){const p=document.querySelectorAll("#recipe-component-list input[data-component-id]"),u=new Set;p.forEach(g=>{g.checked&&u.add(g.dataset.componentId)});const f=A.components||[];return f.filter(g=>g.required).forEach(g=>u.add(g.id)),f.filter(g=>u.has(g.id))}async function b(){const p=document.getElementById("recipe-progress-list"),u=document.getElementById("recipe-deploy-result");u.style.display="none",p.innerHTML="";const f=T();for(const c of f){const d=document.createElement("div");d.id=`recipe-progress-${c.id}`,d.style.cssText="display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 6px; background: var(--card-bg); border: 1px solid var(--border); font-size: 0.85rem;",d.innerHTML=`
|
|
<span class="recipe-progress-icon" style="font-size: 1.1rem;">\u23F3</span>
|
|
<span style="flex:1; font-weight: 500;">${escapeHtml(c.role||c.id)}</span>
|
|
<span class="recipe-progress-status" style="color: var(--muted);">Queued</span>
|
|
`,p.appendChild(d)}const g=document.querySelectorAll("#recipe-volume-list input[data-volume-key]"),z={};g.forEach(c=>{z[c.dataset.volumeKey]=c.value});const r={selectedComponents:f.map(c=>c.id),sharedConfig:{ip:document.getElementById("recipe-ip").value||"host.docker.internal",timezone:document.getElementById("recipe-timezone").value||"UTC",tailscaleOnly:document.getElementById("recipe-tailscale").checked,volumes:z},componentOverrides:{}};for(const c of f)N(c.id,"deploying","Deploying...");try{const d=await(await secureFetch("/api/v1/recipes/deploy",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({recipeId:A.id,config:r})})).json();if(d.success){for(const w of d.deployed||[])N(w.id,"success",w.url?`Running \u2192 ${w.url}`:"Running");for(const w of d.errors||[])N(w.componentId,"error",w.error);u.style.display="",u.innerHTML=`
|
|
<div style="padding: 14px; border-radius: 8px; background: rgba(46,204,113,0.1); border: 1px solid rgba(46,204,113,0.3);">
|
|
<div style="font-weight: 600; color: var(--ok-fg); margin-bottom: 6px;">${escapeHtml(d.message||"Deployed!")}</div>
|
|
${d.setupInstructions?`<div style="font-size: 0.8rem; color: var(--muted); margin-top: 8px;">
|
|
<strong>Setup tips:</strong>
|
|
<ul style="margin: 4px 0 0 16px; padding: 0;">${d.setupInstructions.map(w=>`<li>${escapeHtml(w)}</li>`).join("")}</ul>
|
|
</div>`:""}
|
|
</div>
|
|
`,showNotification(`${A.name} recipe deployed successfully!`,"success",5e3),window.loadServices&&window.loadServices()}else u.style.display="",u.innerHTML=`<div style="padding: 14px; border-radius: 8px; background: rgba(231,76,60,0.1); border: 1px solid rgba(231,76,60,0.3); color: var(--bad-fg);">
|
|
<strong>Deployment failed:</strong> ${escapeHtml(d.error||"Unknown error")}
|
|
</div>`,showNotification(`Recipe deployment failed: ${d.error}`,"error",5e3)}catch(c){u.style.display="",u.innerHTML=`<div style="padding: 14px; border-radius: 8px; background: rgba(231,76,60,0.1); border: 1px solid rgba(231,76,60,0.3); color: var(--bad-fg);">
|
|
<strong>Network error:</strong> ${escapeHtml(c.message)}
|
|
</div>`}}function N(p,u,f){const g=document.getElementById(`recipe-progress-${p}`);if(!g)return;const z=g.querySelector(".recipe-progress-icon"),r=g.querySelector(".recipe-progress-status");u==="deploying"?(z.textContent="\u23F3",r.style.color="var(--accent)"):u==="success"?(z.textContent="\u2705",r.style.color="var(--ok-fg)"):u==="error"&&(z.textContent="\u274C",r.style.color="var(--bad-fg)"),r.textContent=f}v.addEventListener("click",()=>{if(I===3){I=4,M(),b();return}I<3&&(I++,M(),I===2&&B(),I===3&&U())}),P.addEventListener("click",()=>{I>1&&I<4&&(I--,M())}),window.groupRecipeCards=function(){const p=document.querySelectorAll(".service-card[data-recipe-id]");if(p.length===0)return;const u={};p.forEach(f=>{const g=f.dataset.recipeId;u[g]||(u[g]=[]),u[g].push(f)});for(const[f,g]of Object.entries(u))g.length<2||g.forEach((z,r)=>{if(z.style.borderLeft="3px solid rgba(142,68,173,0.5)",r===0){let c=z.querySelector(".recipe-group-label");c||(c=document.createElement("div"),c.className="recipe-group-label",c.style.cssText="position: absolute; top: -8px; left: 12px; font-size: 0.6rem; padding: 1px 8px; border-radius: 8px; background: rgba(142,68,173,0.3); color: #d4a5ff; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px;",c.textContent=f.replace(/-/g," "),z.style.position="relative",z.appendChild(c))}})},window.manageRecipe=async function(p,u){const f=`/api/v1/recipes/${p}/${u}`,g=u==="remove"?"DELETE":"POST",z=u==="remove"?`/api/v1/recipes/${p}`:f;if(!(u==="remove"&&!confirm(`Remove the entire ${p} recipe? This will delete all containers and configuration.`)))try{const c=await(await secureFetch(z,{method:g})).json();c.success?(showNotification(`Recipe ${u}: ${c.results?.filter(d=>d.status!=="failed").length||0} components processed`,"success",4e3),window.loadServices&&window.loadServices()):showNotification(`Recipe ${u} failed: ${c.error}`,"error",5e3)}catch(r){showNotification(`Network error: ${r.message}`,"error",5e3)}};const O=document.createElement("style");O.textContent=`
|
|
.recipe-step {
|
|
flex: 1;
|
|
text-align: center;
|
|
padding: 8px 4px;
|
|
font-size: 0.78rem;
|
|
color: var(--muted);
|
|
border-bottom: 2px solid var(--border);
|
|
transition: all 0.2s;
|
|
}
|
|
.recipe-step span {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 20px;
|
|
height: 20px;
|
|
border-radius: 50%;
|
|
background: var(--border);
|
|
color: var(--muted);
|
|
font-size: 0.7rem;
|
|
font-weight: 700;
|
|
margin-right: 4px;
|
|
}
|
|
.recipe-step.active {
|
|
color: var(--accent);
|
|
border-bottom-color: var(--accent);
|
|
}
|
|
.recipe-step.active span {
|
|
background: var(--accent);
|
|
color: #fff;
|
|
}
|
|
.recipe-step.completed {
|
|
color: var(--ok-fg);
|
|
border-bottom-color: var(--ok-fg);
|
|
}
|
|
.recipe-step.completed span {
|
|
background: var(--ok-fg);
|
|
color: #fff;
|
|
}
|
|
.recipe-step-panel {
|
|
min-height: 180px;
|
|
}
|
|
`,document.head.appendChild(O),x()})(),(function(){document.getElementById("reload-caddy-top")?.addEventListener("click",async()=>{const h=document.getElementById("reload-caddy-top"),L=h.textContent;try{h.textContent="\u23F3 Reloading...",h.disabled=!0;const A=await secureFetch("/api/v1/caddy/reload",{method:"POST",headers:{"Content-Type":"application/json"}}),I=await A.json();if(A.ok&&I.success)h.textContent="\u2705 Reloaded!",setTimeout(()=>{h.textContent=L,h.disabled=!1},2e3);else throw new Error(I.error||"Reload failed")}catch(A){h.textContent="\u274C Failed",showNotification(`Failed to reload Caddy: ${A.message}`,"error"),setTimeout(()=>{h.textContent=L,h.disabled=!1},2e3)}})})(),(function(){injectModal("error-log-modal",'<div id="error-log-modal" class="logs-modal"><div class="logs-modal-content"><div class="logs-header"><h3>\u{1F4CB} Error Logs</h3><div class="logs-controls"><button id="error-log-refresh" style="padding:4px 12px!important;font-size:.85rem!important">\u{1F504} Refresh</button><button id="error-log-clear" style="padding:4px 12px!important;font-size:.85rem!important;background:color-mix(in srgb,var(--bad-fg) 15%,transparent)!important;border-color:var(--bad-fg)!important;color:var(--bad-fg)!important">\u{1F5D1}\uFE0F Clear</button><button id="error-log-close" class="close-btn">\u2715</button></div></div><div class="logs-container"><div id="error-log-content" class="logs-content"><div class="logs-loading">Loading error logs...</div></div></div></div></div>');const h=document.getElementById("error-log-modal"),L=document.getElementById("error-log-content"),A=document.getElementById("view-error-logs"),I=document.getElementById("error-log-refresh"),D=document.getElementById("error-log-clear"),R=document.getElementById("error-log-close");async function H(){L.innerHTML='<div class="logs-loading">Loading error logs...</div>';try{const C=await(await fetch("/api/v1/error-logs")).json();C.success&&C.logs?C.logs.length===0?L.innerHTML='<div style="padding: 20px; text-align: center; color: var(--muted);">\u2705 No errors logged! Everything is working smoothly.</div>':L.innerHTML=C.logs.map(x=>`
|
|
<div class="log-entry error">
|
|
<span class="log-timestamp">${new Date(x.timestamp).toLocaleString()}</span>
|
|
<span class="log-level">ERROR</span>
|
|
<div class="log-message">
|
|
<strong>${escapeHtml(x.context)}</strong>: ${escapeHtml(x.error)}
|
|
${x.details?`<br><small style="opacity: 0.7;">${escapeHtml(x.details)}</small>`:""}
|
|
</div>
|
|
</div>
|
|
`).join(""):L.innerHTML='<div style="padding: 20px; color: var(--bad-fg);">\u274C Failed to load error logs</div>'}catch(v){L.innerHTML=`<div style="padding: 20px; color: var(--bad-fg);">\u274C Error loading logs: ${escapeHtml(v.message)}</div>`}}async function P(){if(confirm("Clear all error logs?"))try{(await(await secureFetch("/api/v1/error-logs",{method:"DELETE"})).json()).success?(showNotification("\u2705 Error logs cleared","success",3e3),H()):showNotification("\u274C Failed to clear logs","error",3e3)}catch(v){showNotification(`\u274C Error: ${v.message}`,"error",3e3)}}A?.addEventListener("click",()=>{h.classList.add("show"),H()}),I?.addEventListener("click",H),D?.addEventListener("click",P),wireModal(h,R)})(),(function(){injectModal("container-logs-modal",`<div id="container-logs-modal" class="weather-modal" style="z-index: 1001;">
|
|
<div class="weather-modal-content" style="min-width: 900px; max-width: 95vw; height: 80vh; display: flex; flex-direction: column;">
|
|
<div class="logs-header" style="display: flex; justify-content: space-between; align-items: center; padding-bottom: 12px; border-bottom: 1px solid var(--border); margin-bottom: 12px;">
|
|
<div>
|
|
<h3 style="margin: 0;">\u{1F4DC} Container Logs</h3>
|
|
<p class="modal-subtitle" style="margin: 4px 0 0 0; font-size: 0.85rem; opacity: 0.7;">View and stream Docker container logs</p>
|
|
</div>
|
|
<div class="logs-controls" style="display: flex; gap: 8px; align-items: center;">
|
|
<select id="cl-container-select" style="padding: 6px 10px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg); color: var(--fg); min-width: 200px;">
|
|
<option value="">Select a container...</option>
|
|
</select>
|
|
<input type="text" id="cl-log-search" placeholder="Search logs..." style="padding: 6px 10px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg); color: var(--fg); width: 150px;" />
|
|
<select id="cl-log-tail" style="padding: 6px 10px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg); color: var(--fg);">
|
|
<option value="50">Last 50 lines</option>
|
|
<option value="100" selected>Last 100 lines</option>
|
|
<option value="500">Last 500 lines</option>
|
|
<option value="1000">Last 1000 lines</option>
|
|
<option value="all">All logs</option>
|
|
</select>
|
|
<button id="cl-refresh" class="btn-accent-solid" style="padding: 6px 14px; font-size: 0.85rem;">\u{1F504} Refresh</button>
|
|
<button id="cl-stream" class="btn-accent-solid" style="padding: 6px 14px; font-size: 0.85rem;">\u25B6 Stream</button>
|
|
<button id="cl-download" style="padding: 6px 14px; font-size: 0.85rem;">\u{1F4BE} Download</button>
|
|
<button id="cl-clear-search" style="padding: 6px 10px; font-size: 0.85rem;" title="Clear search">\u2715</button>
|
|
<button id="cl-close" class="close-btn" style="padding: 6px 10px;">\u2715</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="cl-container-info" style="display: flex; gap: 16px; margin-bottom: 12px; padding: 8px 12px; background: var(--bg-secondary, var(--bg)); border-radius: 6px; font-size: 0.82rem;">
|
|
<span><strong>Image:</strong> <span id="cl-image">-</span></span>
|
|
<span><strong>Status:</strong> <span id="cl-status">-</span></span>
|
|
<span><strong>Created:</strong> <span id="cl-created">-</span></span>
|
|
</div>
|
|
|
|
<div id="cl-log-content" class="logs-content scroll-container" style="flex: 1; min-height: 0; background: #1a1a1a; border-radius: 6px; padding: 12px; font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; font-size: 0.78rem; overflow: auto;">
|
|
<div class="logs-loading" style="color: var(--muted); text-align: center; padding: 40px;">Select a container to view logs</div>
|
|
</div>
|
|
|
|
<div id="cl-stream-status" style="display: none; padding: 8px 12px; background: var(--ok-bg, #1a3a1a); color: var(--ok-fg, #4ade80); border-radius: 6px; margin-top: 8px; font-size: 0.82rem;">
|
|
<span id="cl-stream-indicator">\u{1F534}</span> <span id="cl-stream-text">Disconnected</span>
|
|
</div>
|
|
|
|
<div class="weather-modal-buttons modal-footer-bar" style="margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border);">
|
|
<div style="display: flex; gap: 8px; font-size: 0.78rem; color: var(--muted);">
|
|
<span id="cl-line-count">0 lines</span>
|
|
<span>|</span>
|
|
<span id="cl-filter-count">0 filtered</span>
|
|
</div>
|
|
<button id="cl-close-btn" class="btn-secondary">Close</button>
|
|
</div>
|
|
</div>
|
|
</div>`);const h=document.getElementById("container-logs-modal"),L=document.getElementById("cl-container-select"),A=document.getElementById("cl-log-content"),I=document.getElementById("cl-log-search"),D=document.getElementById("cl-log-tail"),R=document.getElementById("cl-refresh"),H=document.getElementById("cl-stream"),P=document.getElementById("cl-download"),v=document.getElementById("cl-clear-search"),C=document.getElementById("cl-close"),x=document.getElementById("cl-close-btn"),$=document.getElementById("cl-stream-status"),E=document.getElementById("cl-stream-indicator"),M=document.getElementById("cl-stream-text"),S=document.getElementById("cl-line-count"),B=document.getElementById("cl-filter-count"),U=document.getElementById("cl-image"),T=document.getElementById("cl-status"),b=document.getElementById("cl-created");let N=null,O=[],p=[],u=null,f=!1,g=null;function z(s){if(!s)return"-";const l=new Date(s);return isNaN(l.getTime())?s:l.toLocaleString()}function r(s){if(!s)return"";const l=document.createElement("div");return l.textContent=s,l.innerHTML}function c(s,l){const m=s.stream==="stderr"?"log-stderr":"log-stdout",k=s.stream==="stderr"?"\u26A0\uFE0F":"\u{1F4E4}";return`
|
|
<div class="log-entry ${m}" data-index="${l}" style="padding: 4px 8px; border-bottom: 1px solid #333; display: flex; gap: 8px;">
|
|
<span class="log-line-num" style="color: #666; min-width: 40px; text-align: right; user-select: none;">${l+1}</span>
|
|
<span class="log-stream-icon" style="color: ${s.stream==="stderr"?"#f59e0b":"#22c55e"};">${k}</span>
|
|
<span class="log-text" style="flex: 1; white-space: pre-wrap; word-break: break-all; color: #e5e5e5;">${r(s.text)}</span>
|
|
</div>
|
|
`}function d(s,l=""){if(!s||s.length===0){A.innerHTML='<div class="logs-loading" style="color: var(--muted); text-align: center; padding: 40px;">No logs available</div>',S.textContent="0 lines",B.textContent="0 filtered";return}if(O=s,p=l?s.filter(m=>m.text&&m.text.toLowerCase().includes(l.toLowerCase())):s,S.textContent=`${s.length} lines`,B.textContent=l?`${p.length} of ${s.length} shown`:`${s.length} shown`,p.length===0){A.innerHTML=`<div class="logs-loading" style="color: var(--muted); text-align: center; padding: 40px;">No logs match "${r(l)}"</div>`;return}A.innerHTML=p.map((m,k)=>c(m,k)).join(""),A.scrollTop=A.scrollHeight}async function w(){try{const l=(await getJSON("/api/v1/logs/containers")).containers||[],m=L.value;L.innerHTML='<option value="">Select a container...</option>',l.forEach(k=>{const j=document.createElement("option");j.value=k.id,j.textContent=`${k.name} (${k.image.split(":")[0]}) - ${k.status}`,j.dataset.name=k.name,j.dataset.image=k.image,j.dataset.status=k.status,j.dataset.created=k.created,L.appendChild(j)}),m&&L.querySelector(`option[value="${m}"]`)&&(L.value=m,y(m))}catch(s){console.error("Failed to load containers:",s)}}function y(s){const l=L.querySelector(`option[value="${s}"]`);l&&(U.textContent=l.dataset.image||"-",T.textContent=l.dataset.status||"-",T.style.color=l.dataset.status==="running"?"var(--ok-fg, #4ade80)":"var(--bad-fg, #ef4444)",b.textContent=z(l.dataset.created))}async function t(){const s=L.value;if(!s){A.innerHTML='<div class="logs-loading" style="color: var(--muted); text-align: center; padding: 40px;">Select a container to view logs</div>';return}a(),N=s,y(s);const l=D.value,m=I.value.trim();A.innerHTML='<div class="logs-loading" style="color: var(--muted); text-align: center; padding: 40px;">Loading logs...</div>';try{const k=`/api/v1/logs/container/${s}${l!=="all"?`?tail=${l}`:""}`,j=await getJSON(k);j.logs&&j.logs.length>0?d(j.logs,m):(A.innerHTML='<div class="logs-loading" style="color: var(--muted); text-align: center; padding: 40px;">No logs found for this container</div>',S.textContent="0 lines",B.textContent="0 filtered")}catch(k){A.innerHTML=`<div class="logs-loading" style="color: var(--bad-fg, #ef4444); text-align: center; padding: 40px;">Error loading logs: ${r(k.message)}</div>`}}function e(){const s=L.value;if(!s)return;a(),f=!0,H.textContent="\u23F9 Stop",$.style.display="flex",E.textContent="\u{1F7E2}",M.textContent="Connecting...";const l=`/api/v1/logs/stream/${s}`;u=new EventSource(l),u.onopen=()=>{E.textContent="\u{1F7E2}",M.textContent="Connected - streaming logs"},u.onmessage=m=>{try{const k=JSON.parse(m.data);if(k.error){E.textContent="\u{1F534}",M.textContent=`Error: ${k.error}`;return}O.push(k),p.push(k),S.textContent=`${O.length} lines`,B.textContent=`${p.length} shown`;const j=I.value.trim();if(!j||k.text&&k.text.toLowerCase().includes(j.toLowerCase())){const _=document.createElement("div");_.innerHTML=c(k,p.length-1);const F=_.firstElementChild;F.style.background="#1a3a1a",A.appendChild(F),A.scrollTop=A.scrollHeight}}catch(k){console.error("Error parsing log:",k)}},u.onerror=()=>{E.textContent="\u{1F534}",M.textContent="Disconnected",f=!1,H.textContent="\u25B6 Stream"},h._eventSource=u}function a(){u&&(u.close(),u=null),h._eventSource&&(h._eventSource.close(),h._eventSource=null),f=!1,H.textContent="\u25B6 Stream",$.style.display="none"}function o(){if(!O||O.length===0){showNotification("No logs to download","error");return}const s=L.querySelector(`option[value="${N}"]`)?.dataset.name||N,l=new Date().toISOString().replace(/[:.]/g,"-"),m=`${s}-logs-${l}.txt`,k=O.map(q=>{const J=q.timestamp||"",X=q.stream==="stderr"?"[ERR]":"[OUT]";return`${J?J+" ":""}${X} ${q.text}`}).join(`
|
|
`),j=new Blob([k],{type:"text/plain"}),_=URL.createObjectURL(j),F=document.createElement("a");F.href=_,F.download=m,document.body.appendChild(F),F.click(),document.body.removeChild(F),URL.revokeObjectURL(_),showNotification(`Downloaded ${O.length} log lines`,"success")}L?.addEventListener("change",()=>{t()}),D?.addEventListener("change",()=>{t()}),R?.addEventListener("click",()=>{t()}),H?.addEventListener("click",()=>{f?a():e()}),P?.addEventListener("click",()=>{o()}),v?.addEventListener("click",()=>{I.value="",d(O,"")}),I?.addEventListener("input",()=>{clearTimeout(g),g=setTimeout(()=>{d(O,I.value.trim())},300)}),I?.addEventListener("keydown",s=>{s.key==="Escape"&&(I.value="",d(O,""))}),document.getElementById("view-container-logs")?.addEventListener("click",()=>{h.classList.add("show"),w()});function n(){a(),h.classList.remove("show")}C?.addEventListener("click",n),x?.addEventListener("click",n),document.addEventListener("keydown",s=>{s.key==="Escape"&&h.classList.contains("show")&&n()}),h.addEventListener("click",s=>{s.target===h&&n()}),window.openContainerLogsModal=function(s,l){h.classList.add("show"),w().then(()=>{const m=Array.from(L.options).find(k=>k.value===s||k.dataset.name===l);m?(L.value=m.value,y(m.value),t()):s?(N=s,U.textContent=l||s,T.textContent="-",b.textContent="-",t()):A.innerHTML='<div class="logs-loading" style="color: var(--muted); text-align: center; padding: 40px;">Select a container to view logs</div>'})}})(),(function(){injectModal("snapshot-modal",`<div id="snapshot-modal" class="weather-modal">
|
|
<div class="weather-modal-content" style="min-width: 700px; max-width: 850px;">
|
|
<h3>\u{1F4BE} Container Snapshots</h3>
|
|
<p class="modal-subtitle">
|
|
Create and manage Docker container checkpoints for instant state recovery.
|
|
</p>
|
|
|
|
<div id="snapshot-container-select-wrapper" style="margin-bottom: 16px;">
|
|
<label style="font-size: 0.85rem; color: var(--muted);">Select Container:</label>
|
|
<select id="snapshot-container-select" style="width: 100%; padding: 8px 12px; margin-top: 4px; background: var(--bg); border: 1px solid var(--border); border-radius: 6px; color: var(--fg); font-size: 0.9rem;">
|
|
<option value="">-- Select a container --</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div id="snapshot-details" style="display: none; margin-bottom: 16px; padding: 12px; border: 1px solid var(--border); border-radius: 8px; background: var(--card-hover);">
|
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 8px; font-size: 0.85rem;">
|
|
<div><span style="color: var(--muted);">Image:</span> <span id="snapshot-image"></span></div>
|
|
<div><span style="color: var(--muted);">Status:</span> <span id="snapshot-status"></span></div>
|
|
<div><span style="color: var(--muted);">Created:</span> <span id="snapshot-created"></span></div>
|
|
<div><span style="color: var(--muted);">Container ID:</span> <span id="snapshot-id" style="font-family: monospace;"></span></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel-tabs" style="margin-bottom: 12px;">
|
|
<button class="panel-tab active" data-panel="snapshot-create">Create Snapshot</button>
|
|
<button class="panel-tab" data-panel="snapshot-list">Manage Snapshots</button>
|
|
</div>
|
|
|
|
<div id="snapshot-create" class="panel-section active">
|
|
<div style="margin-bottom: 12px;">
|
|
<label style="font-size: 0.85rem; color: var(--muted);">Snapshot Name:</label>
|
|
<input type="text" id="snapshot-name" placeholder="e.g., before-update-2024"
|
|
style="width: 100%; padding: 8px 12px; margin-top: 4px; background: var(--bg); border: 1px solid var(--border); border-radius: 6px; color: var(--fg); font-size: 0.9rem; box-sizing: border-box;" />
|
|
</div>
|
|
<div style="margin-bottom: 12px;">
|
|
<label class="checkbox-label" style="font-size: 0.85rem;">
|
|
<input type="checkbox" id="snapshot-leave-running" checked />
|
|
Leave container running after checkpoint (resume without restart)
|
|
</label>
|
|
</div>
|
|
<button id="snapshot-create-btn" class="btn-accent-solid" style="width: 100%;">\u{1F4BE} Create Snapshot</button>
|
|
<div id="snapshot-create-status" style="margin-top: 12px; text-align: center; font-size: 0.85rem;"></div>
|
|
</div>
|
|
|
|
<div id="snapshot-list" class="panel-section" style="display: none;">
|
|
<div id="snapshot-list-container" class="scroll-container" style="max-height: 300px;">
|
|
<div class="panel-empty"><span class="empty-icon">\u{1F4BE}</span>Select a container to view its snapshots</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="weather-modal-buttons modal-footer-bar">
|
|
<button id="snapshot-close">Close</button>
|
|
</div>
|
|
</div>
|
|
</div>`);const h=document.getElementById("snapshot-modal"),L=document.getElementById("snapshot-btn"),A=document.getElementById("snapshot-close"),I=document.getElementById("snapshot-container-select"),D=document.getElementById("snapshot-details"),R=document.getElementById("snapshot-create-btn"),H=document.getElementById("snapshot-create-status");let P=null;async function v(){try{const S=await(await fetch("/api/v1/containers")).json();if(!S.success||!S.containers)return;I.innerHTML='<option value="">-- Select a container --</option>';for(const B of S.containers){const U=document.createElement("option");U.value=B.id,U.textContent=`${B.name||B.id} (${B.image||"unknown"})`,U.dataset.name=B.name,U.dataset.image=B.image,U.dataset.status=B.status,U.dataset.created=B.created,I.appendChild(U)}}catch(M){console.error("Failed to load containers:",M)}}function C(M){if(!M||!M.value){D.style.display="none",P=null;return}P=M.value,document.getElementById("snapshot-image").textContent=M.dataset.image||"-",document.getElementById("snapshot-status").textContent=M.dataset.status||"-",document.getElementById("snapshot-created").textContent=M.dataset.created?new Date(M.dataset.created*1e3).toLocaleString():"-",document.getElementById("snapshot-id").textContent=M.value.substring(0,12),D.style.display=""}async function x(){if(!P){H.textContent="Please select a container first",H.style.color="var(--bad-fg)";return}const M=document.getElementById("snapshot-name").value.trim();if(!M){H.textContent="Please enter a snapshot name",H.style.color="var(--bad-fg)";return}const S=document.getElementById("snapshot-leave-running").checked;R.disabled=!0,R.textContent="Creating...",H.textContent="";try{const U=await(await fetch(`/api/v1/containers/${encodeURIComponent(P)}/checkpoint`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:M,leaveRunning:S})})).json();U.success?(H.textContent=`\u2713 Snapshot "${M}" created successfully`,H.style.color="var(--ok-fg)",document.getElementById("snapshot-name").value=""):(H.textContent=`\u2717 Failed: ${U.error||"Unknown error"}`,H.style.color="var(--bad-fg)")}catch(B){H.textContent=`\u2717 Error: ${B.message}`,H.style.color="var(--bad-fg)"}finally{R.disabled=!1,R.textContent="\u{1F4BE} Create Snapshot"}}function $(){h.classList.add("show"),v()}function E(){h.classList.remove("show"),D.style.display="none",P=null,I.selectedIndex=0}L?.addEventListener("click",$),A?.addEventListener("click",E),wireModal(h,A),I?.addEventListener("change",M=>{const S=I.options[I.selectedIndex];C(S)}),R?.addEventListener("click",x),h?.querySelectorAll(".panel-tab").forEach(M=>{M.addEventListener("click",()=>{h.querySelectorAll(".panel-tab").forEach(S=>S.classList.remove("active")),h.querySelectorAll(".panel-section").forEach(S=>S.classList.remove("active")),M.classList.add("active"),h.querySelector(`#${M.dataset.panel}`).classList.add("active")})})})(),(function(){injectModal("arr-setup-modal",`<div id="arr-setup-modal" class="weather-modal">
|
|
<div class="weather-modal-content" style="min-width: 600px; max-width: 720px;">
|
|
<h3>\u{1F3AC} Smart Arr Connect</h3>
|
|
<p style="color: var(--muted); margin: 0 0 16px; font-size: 0.9rem;">
|
|
Auto-discover and connect your entire media stack.
|
|
</p>
|
|
|
|
<!-- Phase 1: Detection -->
|
|
<div id="smart-phase-detect">
|
|
<div style="text-align: center; padding: 20px;">
|
|
<span class="brand-spinner" style="margin-bottom: 12px; display: inline-block;"></span>
|
|
<div style="color: var(--muted); font-size: 0.9rem;">Scanning for services...</div>
|
|
</div>
|
|
<div id="smart-detect-results" style="display: none;"></div>
|
|
</div>
|
|
|
|
<!-- Phase 2: Credential Input (only for services needing keys) -->
|
|
<div id="smart-phase-credentials" style="display: none;">
|
|
<h4 class="heading-accent-section">Enter Missing API Keys</h4>
|
|
<div id="smart-credential-inputs"></div>
|
|
|
|
<!-- Connection Options -->
|
|
<div style="margin-top: 16px; padding: 12px; background: var(--card-base); border-radius: 8px; border: 1px solid var(--border);">
|
|
<h4 style="margin: 0 0 10px; font-size: 0.85rem; color: var(--accent);">Connection Options</h4>
|
|
<label class="option-label">
|
|
<input type="checkbox" id="smart-opt-seerr" checked class="checkbox-sm" />
|
|
Configure Seerr with Radarr + Sonarr
|
|
</label>
|
|
<label class="option-label">
|
|
<input type="checkbox" id="smart-opt-plex" checked class="checkbox-sm" />
|
|
Connect Plex to Seerr
|
|
</label>
|
|
<label class="option-label">
|
|
<input type="checkbox" id="smart-opt-prowlarr" checked class="checkbox-sm" />
|
|
Connect Prowlarr to Radarr + Sonarr
|
|
</label>
|
|
<label style="display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 0.85rem;">
|
|
<input type="checkbox" id="smart-opt-save" checked class="checkbox-sm" />
|
|
Save API keys for one-click reconnect
|
|
</label>
|
|
</div>
|
|
|
|
<button id="smart-connect-btn" style="width: 100%; margin-top: 16px; padding: 12px; background: linear-gradient(135deg, #e74c3c 0%, #9b59b6 100%); border: none; color: white; font-weight: 600; font-size: 1rem; border-radius: 8px; cursor: pointer;">
|
|
Smart Connect
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Phase 3: Connection Progress -->
|
|
<div id="smart-phase-progress" style="display: none;">
|
|
<h4 class="heading-accent-section">Connecting Everything...</h4>
|
|
<div id="smart-progress-steps" style="display: flex; flex-direction: column; gap: 6px;"></div>
|
|
</div>
|
|
|
|
<!-- Phase 4: Results -->
|
|
<div id="smart-phase-results" style="display: none;">
|
|
<div id="smart-results-content"></div>
|
|
<div id="smart-plex-libraries" style="display: none; margin-top: 12px;"></div>
|
|
<div style="display: flex; gap: 8px; margin-top: 16px;">
|
|
<button id="smart-retry-btn" style="display: none; flex: 1; padding: 10px; background: #f39c12; border: none; color: white; font-weight: 500; border-radius: 8px; cursor: pointer;">
|
|
Retry Failed Steps
|
|
</button>
|
|
<a id="smart-open-seerr" href="#" target="_blank" rel="noopener noreferrer"
|
|
style="flex: 1; padding: 10px; background: var(--accent); color: white; border: none; border-radius: 8px; cursor: pointer; font-weight: 500; text-decoration: none; text-align: center;">
|
|
Open Seerr
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Help Text -->
|
|
<div style="font-size: 0.75rem; color: var(--muted); margin-top: 12px; padding: 10px; background: color-mix(in srgb, var(--accent) 5%, transparent); border-radius: 6px;">
|
|
<strong>Where to find API keys:</strong><br>
|
|
Radarr/Sonarr/Prowlarr: Settings -> General -> Security -> API Key
|
|
</div>
|
|
|
|
<!-- Close Button -->
|
|
<div class="weather-modal-buttons modal-footer-bar">
|
|
<button id="arr-setup-cancel">Close</button>
|
|
</div>
|
|
</div>
|
|
</div>`);const h=document.getElementById("arr-setup-modal"),L=document.getElementById("arr-setup-btn"),A=document.getElementById("arr-setup-cancel"),I=document.getElementById("smart-connect-btn"),D=document.getElementById("smart-phase-detect"),R=document.getElementById("smart-phase-credentials"),H=document.getElementById("smart-phase-progress"),P=document.getElementById("smart-phase-results"),v=document.getElementById("smart-detect-results"),C=document.getElementById("smart-credential-inputs"),x=document.getElementById("smart-progress-steps"),$=document.getElementById("smart-results-content"),E=document.getElementById("smart-plex-libraries"),M=document.getElementById("smart-retry-btn");let S=null;const B={plex:"\u{1F3AC}",radarr:"\u{1F3AC}",sonarr:"\u{1F4FA}",prowlarr:"\u{1F50D}",seerr:"\u{1F4CB}"},U={plex:"Plex",radarr:"Radarr (Movies)",sonarr:"Sonarr (TV)",prowlarr:"Prowlarr (Indexers)",seerr:"Seerr"};function T(g){D.style.display=g==="detect"?"block":"none",R.style.display=g==="credentials"?"block":"none",H.style.display=g==="progress"?"block":"none",P.style.display=g==="results"?"block":"none"}function b(g){const z={connected:{bg:"var(--ok-fg)",icon:"✓",text:"Connected"},needs_key:{bg:"#f39c12",icon:"🔑",text:"Needs API Key"},not_found:{bg:"var(--muted)",icon:"—",text:"Not Found"},error:{bg:"var(--bad-fg)",icon:"✗",text:"Error"}},r=z[g]||z.not_found;return`<span style="display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border-radius: 4px; font-size: 0.75rem; background: color-mix(in srgb, ${r.bg} 20%, transparent); color: ${r.bg};">${r.icon} ${r.text}</span>`}async function N(){T("detect"),v.style.display="none";try{if(S=await(await fetch("/api/v1/arr/smart-detect")).json(),!S.success){v.innerHTML=`<div style="padding: 12px; color: var(--bad-fg);">Detection failed: ${escapeHtml(S.error)}</div>`,v.style.display="block";return}let z='<div style="display: flex; flex-direction: column; gap: 8px;">';for(const[c,d]of Object.entries(S.services)){const w=B[c]||"\u{1F4E6}",y=U[c]||c,t=d.source?`<span style="font-size: 0.7rem; color: var(--muted); padding: 1px 6px; background: var(--card-bg); border-radius: 3px;">${escapeHtml(d.source)}</span>`:"",e=d.version?`<span style="font-size: 0.7rem; color: var(--muted);">v${escapeHtml(d.version)}</span>`:"",a=(d.hasApiKey||d.hasToken)&&d.status==="connected"?'<span style="font-size: 0.7rem; color: var(--ok-fg);">Key saved</span>':"";z+=`<div style="display: flex; align-items: center; gap: 10px; padding: 10px 12px; background: var(--card-base); border-radius: 8px; border: 1px solid var(--border);">
|
|
<span style="font-size: 1.1rem;">${w}</span>
|
|
<div style="flex: 1;">
|
|
<div style="font-weight: 500; font-size: 0.9rem;">${y}</div>
|
|
<div style="display: flex; gap: 6px; align-items: center; flex-wrap: wrap;">
|
|
${t} ${e} ${a}
|
|
</div>
|
|
</div>
|
|
${b(d.status)}
|
|
</div>`}z+="</div>";const r=S.summary;z+=`<div style="margin-top: 12px; padding: 10px; background: color-mix(in srgb, var(--accent) 8%, transparent); border-radius: 8px; font-size: 0.85rem;">
|
|
${escapeHtml(String(r.fullyConnected))}/${escapeHtml(String(r.totalDetected+(5-r.totalDetected)))} services detected ·
|
|
${escapeHtml(String(r.fullyConnected))} connected${r.needsApiKey>0?` · <strong>${escapeHtml(String(r.needsApiKey))} needs API key</strong>`:""}
|
|
</div>`,v.innerHTML=z,v.style.display="block",O(S),setTimeout(()=>{T("credentials")},800)}catch(g){v.innerHTML=`<div style="padding: 12px; color: var(--bad-fg);">Error: ${escapeHtml(g.message)}</div>`,v.style.display="block"}}function O(g){let z="";const r=g.services,c=["radarr","sonarr","prowlarr"];for(const y of c){const t=r[y];if(!t||t.status==="not_found"&&!t.url)continue;const e=B[y],a=U[y],o=t.status==="connected";z+=`<div style="margin-bottom: 10px; padding: 12px; background: var(--card-base); border-radius: 8px; border: 1px solid ${o?"var(--ok-fg)":"var(--border)"};">
|
|
<div style="display: flex; align-items: center; gap: 8px; margin-bottom: 8px;">
|
|
<span style="font-size: 1.1rem;">${e}</span>
|
|
<span style="font-weight: 500;">${a}</span>
|
|
<span id="smart-${y}-status" style="margin-left: auto; font-size: 0.75rem;">
|
|
${o?'<span style="color: var(--ok-fg);">✓ Connected</span>':""}
|
|
</span>
|
|
</div>
|
|
<div style="display: grid; grid-template-columns: 2fr 1fr; gap: 8px;">
|
|
<div>
|
|
<label style="font-size: 0.75rem; color: var(--muted);">URL:</label>
|
|
<input type="text" id="smart-${y}-url" value="${escapeHtml(t.url||"")}" placeholder="https://seedbox.com/${y}/"
|
|
style="width: 100%; font-size: 0.85rem; padding: 6px 8px; background: var(--card-bg); color: var(--fg); border: 1px solid var(--border); border-radius: 4px;" />
|
|
</div>
|
|
<div>
|
|
<label style="font-size: 0.75rem; color: var(--muted);">API Key:</label>
|
|
<input type="password" id="smart-${y}-key" placeholder="${o?"(saved)":"Paste API key"}"
|
|
style="width: 100%; font-size: 0.85rem; padding: 6px 8px; background: var(--card-bg); color: var(--fg); border: 1px solid var(--border); border-radius: 4px;" />
|
|
</div>
|
|
</div>
|
|
<button onclick="smartTestConnection('${y}')" style="margin-top: 8px; padding: 4px 12px; font-size: 0.75rem; cursor: pointer;">Test</button>
|
|
</div>`}const d=r.plex;if(d){const y=d.status==="connected";z+=`<div style="padding: 10px 12px; background: var(--card-base); border-radius: 8px; border: 1px solid ${y?"var(--ok-fg)":"var(--border)"}; margin-bottom: 10px;">
|
|
<div style="display: flex; align-items: center; gap: 8px;">
|
|
<span style="font-size: 1.1rem;">\u{1F3AC}</span>
|
|
<span style="font-weight: 500;">Plex</span>
|
|
${b(d.status)}
|
|
<span style="margin-left: auto; font-size: 0.75rem; color: var(--muted);">${escapeHtml(d.source||"")}</span>
|
|
</div>
|
|
</div>`}const w=r.seerr;if(w){const y=w.status==="connected";let t="";if(w.configuredServices){const e=w.configuredServices;t=`<div style="font-size: 0.75rem; color: var(--muted); margin-top: 4px;">
|
|
Configured: ${e.radarr?"✓ Radarr":"✗ Radarr"} ·
|
|
${e.sonarr?"✓ Sonarr":"✗ Sonarr"} ·
|
|
${e.plex?"✓ Plex":"✗ Plex"}
|
|
</div>`}z+=`<div style="padding: 10px 12px; background: var(--card-base); border-radius: 8px; border: 1px solid ${y?"var(--ok-fg)":"var(--border)"};">
|
|
<div style="display: flex; align-items: center; gap: 8px;">
|
|
<span style="font-size: 1.1rem;">\u{1F4CB}</span>
|
|
<span style="font-weight: 500;">Seerr</span>
|
|
${b(w.status)}
|
|
</div>
|
|
${t}
|
|
</div>`}C.innerHTML=z}window.smartTestConnection=async function(g){const z=document.getElementById(`smart-${g}-url`),r=document.getElementById(`smart-${g}-key`),c=document.getElementById(`smart-${g}-status`),d=z?.value.trim(),w=r?.value.trim();if(!d||!w){c.innerHTML='<span style="color: var(--bad-fg);">Enter URL and API key</span>';return}c.innerHTML='<span class="brand-spinner"></span>';try{const t=await(await secureFetch("/api/v1/arr/test-connection",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({service:g,url:d,apiKey:w})})).json();t.success?c.innerHTML=`<span style="color: var(--ok-fg);">✓ ${escapeHtml(t.appName||"Connected")} v${escapeHtml(t.version||"")}</span>`:c.innerHTML=`<span style="color: var(--bad-fg);">✗ ${escapeHtml(t.error)}</span>`}catch(y){c.innerHTML=`<span style="color: var(--bad-fg);">✗ ${escapeHtml(y.message)}</span>`}};async function p(){T("progress"),x.innerHTML='<div style="text-align: center; padding: 20px;"><span class="brand-spinner"></span><div style="color: var(--muted); margin-top: 8px;">Connecting services...</div></div>';const g={};for(const r of["radarr","sonarr","prowlarr"]){const c=document.getElementById(`smart-${r}-url`)?.value.trim(),d=document.getElementById(`smart-${r}-key`)?.value.trim();d&&c?g[r]={apiKey:d,url:c}:d&&(g[r]={apiKey:d})}const z={services:Object.keys(g).length>0?g:void 0,configurePlex:document.getElementById("smart-opt-plex")?.checked,configureProwlarr:document.getElementById("smart-opt-prowlarr")?.checked,configureSeerr:document.getElementById("smart-opt-seerr")?.checked,saveCredentials:document.getElementById("smart-opt-save")?.checked};try{const c=await(await secureFetch("/api/v1/arr/smart-connect",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(z)})).json();let d="";for(const w of c.steps||[]){const y=w.status==="success"?'<span style="color: var(--ok-fg);">✓</span>':'<span style="color: var(--bad-fg);">✗</span>',t=w.status==="success"?"var(--muted)":"var(--bad-fg)";d+=`<div style="display: flex; align-items: center; gap: 8px; padding: 6px 10px; background: var(--card-base); border-radius: 6px; font-size: 0.85rem;">
|
|
${y}
|
|
<span>${escapeHtml(w.step)}</span>
|
|
<span style="margin-left: auto; font-size: 0.75rem; color: ${t};">${escapeHtml(w.details||"")}</span>
|
|
</div>`}x.innerHTML=d,setTimeout(()=>u(c),500)}catch(r){x.innerHTML=`<div style="padding: 12px; color: var(--bad-fg);">Connection error: ${escapeHtml(r.message)}</div>`}}function u(g){T("results");const z=g.summary||{},r=z.failed===0&&z.succeeded>0,c=r?"var(--ok-fg)":"#f39c12",d=r?"✓":"⚠",w=r?"All Connected!":`${escapeHtml(String(z.succeeded))}/${escapeHtml(String(z.totalSteps))} Steps Succeeded`;let y=`<div style="text-align: center; padding: 16px; background: color-mix(in srgb, ${c} 12%, transparent); border-radius: 10px; border: 1px solid ${c}; margin-bottom: 12px;">
|
|
<div style="font-size: 1.5rem; color: ${c};">${d}</div>
|
|
<div style="font-size: 1.1rem; font-weight: 600; color: ${c};">${w}</div>
|
|
<div style="font-size: 0.85rem; color: var(--muted); margin-top: 4px;">${escapeHtml(String(z.succeeded))} succeeded, ${escapeHtml(String(z.failed))} failed</div>
|
|
</div>`;y+='<div style="display: flex; flex-direction: column; gap: 4px;">';for(const t of g.steps||[]){const e=t.status==="success"?'<span style="color: var(--ok-fg);">✓</span>':'<span style="color: var(--bad-fg);">✗</span>';y+=`<div style="display: flex; align-items: center; gap: 8px; padding: 4px 8px; font-size: 0.8rem;">
|
|
${e} ${escapeHtml(t.step)} <span style="margin-left: auto; color: var(--muted); font-size: 0.75rem;">${escapeHtml(t.details||"")}</span>
|
|
</div>`}y+="</div>",$.innerHTML=y,M.style.display=z.failed>0?"block":"none",g.steps?.some(t=>t.step.includes("Plex")&&t.status==="success")&&f()}async function f(){try{const z=await(await fetch("/api/v1/plex/libraries")).json();if(z.success&&z.libraries?.length>0){let r=`<div style="padding: 12px; background: var(--card-base); border-radius: 8px; border: 1px solid var(--border);">
|
|
<h4 style="margin: 0 0 8px; font-size: 0.85rem; color: var(--accent);">\u{1F3AC} ${escapeHtml(z.serverName)} Libraries</h4>
|
|
<div style="display: flex; flex-wrap: wrap; gap: 8px;">`;for(const c of z.libraries){const d=c.type==="movie"?"\u{1F3AC}":c.type==="show"?"\u{1F4FA}":"\u{1F3B5}";r+=`<div style="padding: 8px 12px; background: var(--card-bg); border-radius: 6px; font-size: 0.85rem;">
|
|
${d} <strong>${escapeHtml(c.title)}</strong>
|
|
<span style="color: var(--muted); font-size: 0.75rem;">${escapeHtml(String(c.count))} items</span>
|
|
</div>`}r+="</div></div>",E.innerHTML=r,E.style.display="block"}}catch{}}L?.addEventListener("click",()=>{h.classList.add("show"),E.style.display="none",N()}),wireModal(h,A),I?.addEventListener("click",p),M?.addEventListener("click",p)})(),(function(){const h=new ErrorHandler;injectModal("notifications-modal",`<div id="notifications-modal" class="weather-modal">
|
|
<div class="weather-modal-content" style="min-width: 550px; max-width: 650px;">
|
|
<h3>\u{1F514} Notification Settings</h3>
|
|
|
|
<!-- Master Toggle -->
|
|
<div class="accent-info-box">
|
|
<label style="display: flex; align-items: center; gap: 10px; cursor: pointer;">
|
|
<input type="checkbox" id="notifications-enabled" />
|
|
<div>
|
|
<span style="font-weight: 600; color: var(--accent);">Enable Notifications</span>
|
|
<div class="text-tiny-muted">Receive alerts when containers go up/down</div>
|
|
</div>
|
|
</label>
|
|
</div>
|
|
|
|
<!-- Providers Section -->
|
|
<h4 class="section-heading">Notification Providers</h4>
|
|
|
|
<!-- Discord -->
|
|
<div class="notification-provider provider-card">
|
|
<div class="provider-header">
|
|
<label class="checkbox-label">
|
|
<input type="checkbox" id="discord-enabled" />
|
|
<span class="fw-500">Discord</span>
|
|
</label>
|
|
<button id="discord-test" class="test-btn btn-xs">Test</button>
|
|
</div>
|
|
<div id="discord-config" style="display: none;">
|
|
<label class="field-label-sm">Webhook URL:</label>
|
|
<input type="text" id="discord-webhook" placeholder="https://discord.com/api/v1/webhooks/..." style="width: 100%;" />
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Telegram -->
|
|
<div class="notification-provider provider-card">
|
|
<div class="provider-header">
|
|
<label class="checkbox-label">
|
|
<input type="checkbox" id="telegram-enabled" />
|
|
<span class="fw-500">Telegram</span>
|
|
</label>
|
|
<button id="telegram-test" class="test-btn btn-xs">Test</button>
|
|
</div>
|
|
<div id="telegram-config" style="display: none;">
|
|
<div class="grid-2col">
|
|
<div>
|
|
<label class="field-label-sm">Bot Token:</label>
|
|
<input type="text" id="telegram-bot-token" placeholder="123456:ABC..." />
|
|
</div>
|
|
<div>
|
|
<label class="field-label-sm">Chat ID:</label>
|
|
<input type="text" id="telegram-chat-id" placeholder="-1001234567890" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ntfy.sh -->
|
|
<div class="notification-provider provider-card">
|
|
<div class="provider-header">
|
|
<label class="checkbox-label">
|
|
<input type="checkbox" id="ntfy-enabled" />
|
|
<span class="fw-500">ntfy.sh</span>
|
|
</label>
|
|
<button id="ntfy-test" class="test-btn btn-xs">Test</button>
|
|
</div>
|
|
<div id="ntfy-config" style="display: none;">
|
|
<div style="display: grid; grid-template-columns: 2fr 1fr; gap: 8px;">
|
|
<div>
|
|
<label class="field-label-sm">Server URL:</label>
|
|
<input type="text" id="ntfy-server" placeholder="https://ntfy.sh" value="https://ntfy.sh" />
|
|
</div>
|
|
<div>
|
|
<label class="field-label-sm">Topic:</label>
|
|
<input type="text" id="ntfy-topic" placeholder="dashcaddy-alerts" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Email -->
|
|
<div class="notification-provider provider-card">
|
|
<div class="provider-header">
|
|
<label class="checkbox-label">
|
|
<input type="checkbox" id="email-enabled" />
|
|
<span class="fw-500">Email (SMTP)</span>
|
|
</label>
|
|
<button id="email-test" class="test-btn btn-xs">Test</button>
|
|
</div>
|
|
<div id="email-config" style="display: none;">
|
|
<div style="display: grid; grid-template-columns: 2fr 1fr; gap: 8px; margin-bottom: 8px;">
|
|
<div>
|
|
<label class="field-label-sm">SMTP Host:</label>
|
|
<input type="text" id="email-host" placeholder="smtp.gmail.com" />
|
|
</div>
|
|
<div>
|
|
<label class="field-label-sm">Port:</label>
|
|
<input type="number" id="email-port" value="587" placeholder="587" />
|
|
</div>
|
|
</div>
|
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 8px;">
|
|
<div>
|
|
<label class="field-label-sm">Username:</label>
|
|
<input type="text" id="email-user" placeholder="user@gmail.com" />
|
|
</div>
|
|
<div>
|
|
<label class="field-label-sm">Password:</label>
|
|
<input type="password" id="email-pass" placeholder="app password" />
|
|
</div>
|
|
</div>
|
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 8px;">
|
|
<div>
|
|
<label class="field-label-sm">From:</label>
|
|
<input type="text" id="email-from" placeholder="DashCaddy <noreply@example.com>" />
|
|
</div>
|
|
<div>
|
|
<label class="field-label-sm">To:</label>
|
|
<input type="text" id="email-to" placeholder="admin@example.com" />
|
|
</div>
|
|
</div>
|
|
<label style="display: flex; align-items: center; gap: 6px; margin-top: 8px; font-size: 0.8rem;">
|
|
<input type="checkbox" id="email-secure" /> Use TLS (port 465)
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Health Check Settings -->
|
|
<h4 class="section-heading">Health Monitoring</h4>
|
|
<div style="padding: 12px; background: var(--card-base); border-radius: 8px; border: 1px solid var(--border);">
|
|
<label style="display: flex; align-items: center; gap: 10px; cursor: pointer; margin-bottom: 10px;">
|
|
<input type="checkbox" id="health-check-enabled" />
|
|
<div>
|
|
<span class="fw-500">Enable Health Monitoring</span>
|
|
<div class="text-tiny-muted">Periodically check container status</div>
|
|
</div>
|
|
</label>
|
|
<div id="health-check-config" style="display: flex; align-items: center; gap: 10px;">
|
|
<label class="field-label-sm">Check interval:</label>
|
|
<select id="health-check-interval" style="width: auto;">
|
|
<option value="1">1 minute</option>
|
|
<option value="5" selected>5 minutes</option>
|
|
<option value="15">15 minutes</option>
|
|
<option value="30">30 minutes</option>
|
|
<option value="60">1 hour</option>
|
|
</select>
|
|
<button id="health-check-now" style="padding: 4px 10px; font-size: 0.75rem; margin-left: auto;">Check Now</button>
|
|
</div>
|
|
<div id="health-check-status" style="font-size: 0.75rem; color: var(--muted); margin-top: 8px;">
|
|
Last check: Never
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Event Types -->
|
|
<h4 class="section-heading">Events to Notify</h4>
|
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 6px; padding: 12px; background: var(--card-base); border-radius: 8px; border: 1px solid var(--border);">
|
|
<label class="checkbox-label-sm">
|
|
<input type="checkbox" id="event-container-down" checked /> Container Down
|
|
</label>
|
|
<label class="checkbox-label-sm">
|
|
<input type="checkbox" id="event-container-up" checked /> Container Recovered
|
|
</label>
|
|
<label class="checkbox-label-sm">
|
|
<input type="checkbox" id="event-deploy-success" checked /> Deployment Success
|
|
</label>
|
|
<label class="checkbox-label-sm">
|
|
<input type="checkbox" id="event-deploy-failed" checked /> Deployment Failed
|
|
</label>
|
|
<label class="checkbox-label-sm" style="grid-column: 1 / -1;">
|
|
<input type="checkbox" id="event-resource-alert" checked /> Resource Alerts
|
|
</label>
|
|
</div>
|
|
|
|
<!-- History -->
|
|
<h4 class="section-heading">Notification History</h4>
|
|
<div id="notification-history" style="max-height: 150px; overflow-y: auto; padding: 8px; background: var(--card-base); border-radius: 8px; border: 1px solid var(--border); font-size: 0.8rem;">
|
|
<div style="color: var(--muted); text-align: center; padding: 20px;">No notifications yet</div>
|
|
</div>
|
|
<div id="last-notification-sent" style="font-size: 0.75rem; color: var(--muted); text-align: center; margin-top: 6px;"></div>
|
|
|
|
<!-- Buttons -->
|
|
<div class="weather-modal-buttons modal-footer-bar">
|
|
<button id="notifications-send-test" class="btn-secondary" style="margin-right: auto;">Send Test</button>
|
|
<button id="notifications-cancel">Cancel</button>
|
|
<button id="notifications-save" class="btn-accent">Save Settings</button>
|
|
</div>
|
|
</div>
|
|
</div>`);const L=document.getElementById("notifications-modal"),A=document.getElementById("manage-notifications"),I=document.getElementById("notifications-save"),D=document.getElementById("notifications-cancel");["discord","telegram","ntfy","email"].forEach(E=>{const M=document.getElementById(`${E}-enabled`),S=document.getElementById(`${E}-config`);M?.addEventListener("change",()=>{S.style.display=M.checked?"block":"none"})});const R=document.getElementById("health-check-enabled"),H=document.getElementById("health-check-config");R?.addEventListener("change",()=>{H.style.opacity=R.checked?"1":"0.5"});async function P(){try{const M=await(await fetch("/api/v1/notifications/config")).json();if(M.success){const S=M.config;document.getElementById("notifications-enabled").checked=S.enabled,document.getElementById("discord-enabled").checked=S.providers?.discord?.enabled||!1,document.getElementById("telegram-enabled").checked=S.providers?.telegram?.enabled||!1,document.getElementById("ntfy-enabled").checked=S.providers?.ntfy?.enabled||!1,document.getElementById("email-enabled").checked=S.providers?.email?.enabled||!1,document.getElementById("discord-config").style.display=S.providers?.discord?.enabled?"block":"none",document.getElementById("telegram-config").style.display=S.providers?.telegram?.enabled?"block":"none",document.getElementById("ntfy-config").style.display=S.providers?.ntfy?.enabled?"block":"none",document.getElementById("email-config").style.display=S.providers?.email?.enabled?"block":"none",S.providers?.ntfy?.serverUrl&&(document.getElementById("ntfy-server").value=S.providers.ntfy.serverUrl),S.providers?.email?.host&&(document.getElementById("email-host").value=S.providers.email.host),S.providers?.email?.from&&(document.getElementById("email-from").value=S.providers.email.from),document.getElementById("health-check-enabled").checked=S.healthCheck?.enabled||!1,S.healthCheck?.intervalMinutes&&(document.getElementById("health-check-interval").value=S.healthCheck.intervalMinutes),S.healthCheck?.lastCheck&&(document.getElementById("health-check-status").textContent=`Last check: ${new Date(S.healthCheck.lastCheck).toLocaleString()}`),document.getElementById("event-container-down").checked=S.events?.containerDown!==!1,document.getElementById("event-container-up").checked=S.events?.containerUp!==!1,document.getElementById("event-deploy-success").checked=S.events?.deploymentSuccess!==!1,document.getElementById("event-deploy-failed").checked=S.events?.deploymentFailed!==!1,document.getElementById("event-resource-alert").checked=S.events?.resourceAlert!==!1}}catch(E){h.logError("[Notifications] Load Config",E,{function:"loadConfig"})}}async function v(){try{const M=await(await fetch("/api/v1/notifications/history?limit=10")).json(),S=document.getElementById("notification-history");M.success&&M.history?.length>0?S.innerHTML=M.history.map(B=>{const U=new Date(B.timestamp).toLocaleString();return`
|
|
<div style="padding: 6px 8px; border-bottom: 1px solid var(--border); display: flex; gap: 8px; align-items: flex-start;">
|
|
<span style="color: ${{success:"var(--ok-fg)",error:"var(--bad-fg)",warning:"#f39c12",info:"var(--accent)"}[B.type]||"var(--muted)"}">${B.type==="success"?"\u2713":B.type==="error"?"\u2717":"\u2139"}</span>
|
|
<div style="flex: 1; min-width: 0;">
|
|
<div style="font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">${escapeHtml(B.title)}</div>
|
|
<div style="font-size: 0.7rem; color: var(--muted);">${U}</div>
|
|
</div>
|
|
</div>
|
|
`}).join(""):S.innerHTML='<div style="color: var(--muted); text-align: center; padding: 20px;">No notifications yet</div>'}catch(E){h.logError("[Notifications] Load History",E,{function:"loadHistory"})}}async function C(){try{const E={enabled:document.getElementById("notifications-enabled").checked,providers:{discord:{enabled:document.getElementById("discord-enabled").checked,webhookUrl:document.getElementById("discord-webhook").value.trim()},telegram:{enabled:document.getElementById("telegram-enabled").checked,botToken:document.getElementById("telegram-bot-token").value.trim(),chatId:document.getElementById("telegram-chat-id").value.trim()},ntfy:{enabled:document.getElementById("ntfy-enabled").checked,serverUrl:document.getElementById("ntfy-server").value.trim()||"https://ntfy.sh",topic:document.getElementById("ntfy-topic").value.trim()},email:{enabled:document.getElementById("email-enabled").checked,host:document.getElementById("email-host").value.trim(),port:parseInt(document.getElementById("email-port").value)||587,secure:document.getElementById("email-secure").checked,user:document.getElementById("email-user").value.trim(),pass:document.getElementById("email-pass").value.trim(),from:document.getElementById("email-from").value.trim(),to:document.getElementById("email-to").value.trim()}},events:{containerDown:document.getElementById("event-container-down").checked,containerUp:document.getElementById("event-container-up").checked,deploymentSuccess:document.getElementById("event-deploy-success").checked,deploymentFailed:document.getElementById("event-deploy-failed").checked,resourceAlert:document.getElementById("event-resource-alert").checked},healthCheck:{enabled:document.getElementById("health-check-enabled").checked,intervalMinutes:parseInt(document.getElementById("health-check-interval").value)||5}},S=await(await secureFetch("/api/v1/notifications/config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(E)})).json();S.success?(showNotification("Notification settings saved","success",3e3),L.classList.remove("show")):showNotification(`Failed to save: ${S.error}`,"error",3e3)}catch(E){showNotification(`Error: ${E.message}`,"error",3e3)}}async function x(E){try{const S=await(await secureFetch("/api/v1/notifications/test",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({provider:E})})).json();S.success?showNotification(`Test ${E} notification sent!`,"success",3e3):showNotification(`Test failed: ${S.error}`,"error",3e3)}catch(M){showNotification(`Error: ${M.message}`,"error",3e3)}}document.getElementById("discord-test")?.addEventListener("click",()=>x("discord")),document.getElementById("telegram-test")?.addEventListener("click",()=>x("telegram")),document.getElementById("ntfy-test")?.addEventListener("click",()=>x("ntfy")),document.getElementById("email-test")?.addEventListener("click",()=>x("email")),document.getElementById("health-check-now")?.addEventListener("click",async()=>{try{const M=await(await secureFetch("/api/v1/notifications/health-check",{method:"POST"})).json();M.success&&(document.getElementById("health-check-status").textContent=`Last check: ${new Date(M.lastCheck).toLocaleString()} (${M.containersMonitored} containers)`,showNotification("Health check completed","success",2e3))}catch(E){showNotification(`Error: ${E.message}`,"error",3e3)}}),A?.addEventListener("click",()=>{L.classList.add("show"),P(),v()}),I?.addEventListener("click",C),document.getElementById("notifications-send-test")?.addEventListener("click",async()=>{const E=document.getElementById("notifications-send-test"),M=E.textContent;E.textContent="Sending...",E.disabled=!0;try{const B=await(await secureFetch("/api/v1/notifications/send",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({event:"test",data:{message:"This is a test notification from DashCaddy."},type:"info"})})).json();B.success?(showNotification("Test notification sent!","success",3e3),$()):showNotification(`Test failed: ${B.results?.map(U=>`${U.provider}: ${U.error||"ok"}`).join(", ")}`,"error",5e3)}catch(S){showNotification(`Error: ${S.message}`,"error",3e3)}finally{E.textContent=M,E.disabled=!1}});async function $(){try{const M=await(await fetch("/api/v1/notifications/status")).json();if(M.success&&M.lastSent){const S=document.getElementById("last-notification-sent");S&&(S.textContent=`Last sent: ${new Date(M.lastSent).toLocaleString()}`)}}catch{}}wireModal(L,D)})(),(function(){document.addEventListener("click",h=>{const L=h.target.closest(".panel-tab");if(!L)return;const A=L.dataset.panel;if(!A)return;const I=L.closest(".panel-tabs"),D=I.closest(".weather-modal-content");I.querySelectorAll(".panel-tab").forEach(H=>H.classList.remove("active")),L.classList.add("active"),D.querySelectorAll(".panel-section").forEach(H=>H.classList.remove("active"));const R=D.querySelector("#"+A);R&&R.classList.add("active")})})(),(function(){var h=["dashcaddy_site_config","dashcaddy_onboarding","dashcaddy-encryption-key","dashcaddy-setup","dashcaddy-config","theme","user-themes","custom-theme","custom-apps","custom-services","toolbar-sections","weather-location","weather-zip","weather-geo","weather-unit","clock-style","clock-chimes","clock-chime-volume"];function L(){for(var e={},a=0;a<h.length;a++){var o=h[a],i=safeGet(o);i!=null&&(e[o]=i)}try{for(var n=0;n<localStorage.length;n++){var s=localStorage.key(n);/^widget-.+-enabled$/.test(s)&&(e[s]=localStorage.getItem(s))}}catch{}return e}function A(e){if(!e||typeof e!="object")return 0;var a=0;for(var o in e)e.hasOwnProperty(o)&&(safeSet(o,e[o]),a++);return a}function I(e){return e.version&&!e.files&&e.services}function D(e){var a={};e.customServices&&(a["custom-services"]=JSON.stringify(e.customServices)),e.customApps&&(a["custom-apps"]=JSON.stringify(e.customApps)),e.weatherZip&&(a["weather-zip"]=e.weatherZip),e.theme&&(a.theme=e.theme),e.userThemes&&Object.keys(e.userThemes).length&&(a["user-themes"]=JSON.stringify(e.userThemes)),A(a),e.services&&Array.isArray(e.services)&&secureFetch("/api/v1/services",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(e.services)}).catch(function(){}),e.userThemes&&Object.keys(e.userThemes).forEach(function(o){var i=e.userThemes[o],n={};(window.THEME_PROPS||[]).forEach(function(s){i[s]&&(n[s]=i[s])}),secureFetch("/api/v1/themes/"+o,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:i.name||o,colors:n})}).catch(function(){})})}injectModal("backup-modal",`<div id="backup-modal" class="weather-modal">
|
|
<div class="weather-modal-content" style="min-width: 550px; max-width: 650px;">
|
|
<h3>\u{1F4BE} Backup & Restore</h3>
|
|
<p class="modal-subtitle">
|
|
Full backup of your entire DashCaddy setup \u2014 server config, credentials, themes, and browser preferences in one file.
|
|
</p>
|
|
|
|
<!-- Tab bar -->
|
|
<div class="panel-tabs">
|
|
<button class="panel-tab active" data-panel="backup-manual">Manual</button>
|
|
<button class="panel-tab" data-panel="backup-schedules-tab">Schedules</button>
|
|
<button class="panel-tab" data-panel="backup-disk-tab">Backups on Disk</button>
|
|
<button class="panel-tab" data-panel="backup-pointintime-tab">Point-in-Time</button>
|
|
<button class="panel-tab" data-panel="backup-history-tab">History</button>
|
|
</div>
|
|
|
|
<!-- Tab: Manual -->
|
|
<div id="backup-manual" class="panel-section active">
|
|
<!-- Export Section -->
|
|
<div style="margin-bottom: 20px; padding: 16px; background: linear-gradient(135deg, color-mix(in srgb, #27ae60 15%, transparent), color-mix(in srgb, #2ecc71 10%, transparent)); border-radius: 10px; border: 1px solid #27ae60;">
|
|
<h4 style="margin: 0 0 8px; color: #2ecc71; font-size: 0.95rem;">\u{1F4E4} Export Backup</h4>
|
|
<p style="font-size: 0.8rem; color: var(--muted); margin: 0 0 12px;">
|
|
Downloads everything \u2014 services, Caddyfile, credentials, encryption key, themes, and all browser preferences.
|
|
</p>
|
|
<button id="backup-export-btn" style="width: 100%; padding: 10px; background: linear-gradient(135deg, #27ae60 0%, #2ecc71 100%); border: none; color: white; font-weight: 600; border-radius: 8px; cursor: pointer;">
|
|
\u2B07\uFE0F Download Full Backup
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Import Section -->
|
|
<div style="padding: 16px; background: linear-gradient(135deg, color-mix(in srgb, #3498db 15%, transparent), color-mix(in srgb, #2980b9 10%, transparent)); border-radius: 10px; border: 1px solid #3498db;">
|
|
<h4 style="margin: 0 0 8px; color: #3498db; font-size: 0.95rem;">\u{1F4E5} Restore Backup</h4>
|
|
<p style="font-size: 0.8rem; color: var(--muted); margin: 0 0 12px;">
|
|
Upload a backup file to restore your entire configuration \u2014 drag and drop ready.
|
|
</p>
|
|
<input type="file" id="backup-file-input" accept=".json" style="display: none;" />
|
|
<button id="backup-select-file" style="width: 100%; padding: 10px; background: linear-gradient(135deg, #3498db 0%, #2980b9 100%); border: none; color: white; font-weight: 600; border-radius: 8px; cursor: pointer;">
|
|
\u{1F4C1} Select Backup File
|
|
</button>
|
|
<div id="backup-file-name" style="display: none; margin-top: 8px; padding: 8px; background: var(--card-base); border-radius: 6px; font-size: 0.85rem;"></div>
|
|
</div>
|
|
|
|
<!-- Preview Section (shown after file selected) -->
|
|
<div id="backup-preview" style="display: none; margin-top: 16px; padding: 16px; background: var(--card-base); border-radius: 10px; border: 1px solid var(--border);">
|
|
<h4 style="margin: 0 0 12px; font-size: 0.9rem;">\u{1F4CB} Backup Contents</h4>
|
|
<div id="backup-preview-content" style="font-size: 0.85rem;"></div>
|
|
<div style="margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border);">
|
|
<label class="checkbox-label" style="font-size: 0.85rem;">
|
|
<input type="checkbox" id="backup-reload-caddy" checked />
|
|
Reload Caddy after restore
|
|
</label>
|
|
</div>
|
|
<button id="backup-do-restore-btn" style="width: 100%; margin-top: 12px; padding: 10px; background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%); border: none; color: white; font-weight: 600; border-radius: 8px; cursor: pointer;">
|
|
\u26A1 Restore Everything
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Result Message -->
|
|
<div id="backup-result" style="display: none; margin-top: 16px; padding: 12px; border-radius: 8px;"></div>
|
|
</div>
|
|
|
|
<!-- Tab: Schedules (Premium) -->
|
|
<div id="backup-schedules-tab" class="panel-section">
|
|
<div id="backup-schedules-container">
|
|
<div class="panel-empty">
|
|
<span class="empty-icon">\u23F0</span>
|
|
<span class="brand-spinner"></span> Loading schedules...
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tab: Backups on Disk -->
|
|
<div id="backup-disk-tab" class="panel-section">
|
|
<div id="backup-disk-container">
|
|
<div class="panel-empty">
|
|
<span class="empty-icon">\u{1F4BE}</span>
|
|
<span class="brand-spinner"></span> Loading backup files...
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tab: Point-in-Time Restore -->
|
|
<div id="backup-pointintime-tab" class="panel-section">
|
|
<div id="pointintime-container">
|
|
<div class="panel-empty">
|
|
<span class="empty-icon">\u23EA</span>
|
|
<span class="brand-spinner"></span> Loading...
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tab: Backup History -->
|
|
<div id="backup-history-tab" class="panel-section">
|
|
<div id="backup-history-container" style="max-height: 400px; overflow-y: auto;">
|
|
<div class="panel-empty">
|
|
<span class="empty-icon">\u{1F4CB}</span>
|
|
<span class="brand-spinner"></span> Loading backup history...
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Close Button -->
|
|
<div class="weather-modal-buttons modal-footer-bar">
|
|
<button id="backup-cancel">Close</button>
|
|
</div>
|
|
</div>
|
|
</div>`);var R=document.getElementById("backup-modal"),H=document.getElementById("backup-restore-btn"),P=document.getElementById("backup-cancel"),v=document.getElementById("backup-export-btn"),C=document.getElementById("backup-select-file"),x=document.getElementById("backup-file-input"),$=document.getElementById("backup-file-name"),E=document.getElementById("backup-preview"),M=document.getElementById("backup-preview-content"),S=document.getElementById("backup-do-restore-btn"),B=document.getElementById("backup-result"),U=document.getElementById("backup-schedules-container"),T=document.getElementById("backup-history-container"),b=document.getElementById("backup-disk-container"),N=document.getElementById("pointintime-container"),O=null;H?.addEventListener("click",function(){R.classList.add("show"),B&&(B.style.display="none"),E&&(E.style.display="none"),$&&($.style.display="none"),O=null}),wireModal(R,P),v?.addEventListener("click",async function(){v.disabled=!0,v.innerHTML='<span class="brand-spinner"></span> Exporting...';try{var e=await fetch("/api/v1/backup/export"),a=await e.json();a.browserState=L();var o=new Blob([JSON.stringify(a,null,2)],{type:"application/json"}),i=URL.createObjectURL(o),n=document.createElement("a");n.href=i,n.download="dashcaddy-backup-"+new Date().toISOString().split("T")[0]+".json",document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(i);var s=Object.keys(a.browserState).length,l=a.themes?Object.keys(a.themes).length:0;B.innerHTML="\u2705 Full backup downloaded \u2014 server config + "+s+" browser settings"+(l?" + "+l+" themes":""),B.style.display="block",B.style.background="color-mix(in srgb, var(--ok-fg) 15%, transparent)",B.style.border="1px solid var(--ok-fg)"}catch(m){B.innerHTML="\u274C Export failed: "+escapeHtml(m.message),B.style.display="block",B.style.background="color-mix(in srgb, var(--bad-fg) 15%, transparent)",B.style.border="1px solid var(--bad-fg)"}v.disabled=!1,v.innerHTML="\u2B07\uFE0F Download Full Backup"}),C?.addEventListener("click",function(){x.click()}),x?.addEventListener("change",async function(e){var a=e.target.files[0];if(a){$.textContent="\u{1F4C4} "+a.name,$.style.display="block",B.style.display="none";try{var o=await a.text(),i=JSON.parse(o);if(I(i)){O=i;var n='<div style="margin-bottom: 8px; color: var(--muted); font-size: 0.8rem;">Legacy format (v'+escapeHtml(i.version)+")</div>";n+='<div style="display: flex; flex-wrap: wrap; gap: 6px;">',i.services?.length&&(n+='<span style="padding: 4px 8px; background: var(--base); border-radius: 4px; font-size: 0.8rem;">\u{1F4CB} '+i.services.length+" services</span>"),i.customApps?.length&&(n+='<span style="padding: 4px 8px; background: var(--base); border-radius: 4px; font-size: 0.8rem;">\u{1F4E6} '+i.customApps.length+" custom apps</span>"),i.theme&&(n+='<span style="padding: 4px 8px; background: var(--base); border-radius: 4px; font-size: 0.8rem;">\u{1F3A8} Theme: '+escapeHtml(i.theme)+"</span>"),i.userThemes&&(n+='<span style="padding: 4px 8px; background: var(--base); border-radius: 4px; font-size: 0.8rem;">\u{1F3A8} '+Object.keys(i.userThemes).length+" custom themes</span>"),n+="</div>",M.innerHTML=n,E.style.display="block";return}var s=await secureFetch("/api/v1/backup/preview",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)}),l=await s.json();if(l.success){O=i;var n='<div style="margin-bottom: 8px; color: var(--muted); font-size: 0.8rem;">Exported: '+new Date(i.exportedAt).toLocaleString()+" (v"+escapeHtml(i.version)+")</div>";n+='<div style="margin-bottom: 6px; font-size: 0.75rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.5px;">Server Config</div>',n+='<div style="display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px;">';for(var m in l.preview.files){var k=l.preview.files[m],j=k.action==="create"?"\u{1F195}":"\u{1F4DD}";n+='<span style="padding: 4px 8px; background: var(--base); border-radius: 4px; font-size: 0.8rem;">'+j+" "+escapeHtml(k.description)+"</span>"}n+="</div>",l.preview.serviceCount&&(n+='<div style="font-size: 0.8rem; color: var(--accent); margin-bottom: 6px;">'+l.preview.serviceCount+" services</div>"),l.preview.themeCount&&(n+='<div style="font-size: 0.8rem; color: var(--accent); margin-bottom: 6px;">\u{1F3A8} '+l.preview.themeCount+" custom themes</div>"),l.preview.browserStateCount&&(n+='<div style="margin-top: 6px; font-size: 0.75rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.5px;">Browser Preferences</div>',n+='<div style="font-size: 0.8rem; color: var(--accent);">\u{1F5A5}\uFE0F '+l.preview.browserStateCount+" saved settings (theme, weather, clock, widgets, etc.)</div>"),M.innerHTML=n,E.style.display="block"}else B.innerHTML="\u26A0\uFE0F Invalid backup file: "+escapeHtml(l.error),B.style.display="block",B.style.background="color-mix(in srgb, #f39c12 15%, transparent)",B.style.border="1px solid #f39c12",E.style.display="none"}catch(_){B.innerHTML="\u274C Could not read file: "+escapeHtml(_.message),B.style.display="block",B.style.background="color-mix(in srgb, var(--bad-fg) 15%, transparent)",B.style.border="1px solid var(--bad-fg)",E.style.display="none"}}}),S?.addEventListener("click",async function(){if(O&&confirm("This will overwrite your current configuration and browser preferences. Continue?")){S.disabled=!0,S.innerHTML='<span class="brand-spinner"></span> Restoring...';try{if(I(O)){D(O),B.innerHTML="\u2705 Legacy backup restored \u2014 browser settings and services imported.",B.style.background="color-mix(in srgb, var(--ok-fg) 15%, transparent)",B.style.border="1px solid var(--ok-fg)",B.style.display="block",setTimeout(function(){location.reload()},2e3),S.disabled=!1,S.innerHTML="\u26A1 Restore Everything";return}var e=document.getElementById("backup-reload-caddy")?.checked??!0,a=await secureFetch("/api/v1/backup/restore",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({backup:O,options:{reloadCaddy:e}})}),o=await a.json(),i=0;if(O.browserState&&(i=A(O.browserState)),o.success){var n="\u2705 "+o.message;i>0&&(n+='<br><small style="color: var(--muted);">'+i+" browser settings restored</small>"),o.results.caddyReloaded&&(n+='<br><small style="color: var(--muted);">Caddy configuration reloaded</small>'),B.innerHTML=n,B.style.background="color-mix(in srgb, var(--ok-fg) 15%, transparent)",B.style.border="1px solid var(--ok-fg)",setTimeout(function(){location.reload()},2e3)}else B.innerHTML="\u26A0\uFE0F "+escapeHtml(o.message),i>0&&(B.innerHTML+='<br><small style="color: var(--muted);">'+i+" browser settings were restored</small>"),o.results?.errors?.length>0&&(B.innerHTML+="<br><small>"+o.results.errors.map(function(s){return escapeHtml(s.file)+": "+escapeHtml(s.error)}).join(", ")+"</small>"),B.style.background="color-mix(in srgb, #f39c12 15%, transparent)",B.style.border="1px solid #f39c12";B.style.display="block"}catch(s){B.innerHTML="\u274C Restore failed: "+escapeHtml(s.message),B.style.display="block",B.style.background="color-mix(in srgb, var(--bad-fg) 15%, transparent)",B.style.border="1px solid var(--bad-fg)"}S.disabled=!1,S.innerHTML="\u26A1 Restore Everything"}});async function p(){if(U){U.innerHTML='<div class="panel-empty"><span class="brand-spinner"></span> Loading...</div>';try{var e=await fetch("/api/v1/backups/schedule"),a=await e.json();if(a.premiumRequired){U.innerHTML=`<div class="panel-empty" style="padding: 24px; text-align: center;"><div style="font-size: 2rem; margin-bottom: 12px;">\u2B50</div><div style="font-weight: 600; margin-bottom: 8px;">Premium Feature</div><div style="font-size: 0.85rem; color: var(--muted);">Auto-backup scheduling requires a DashCaddy Premium subscription.</div><button onclick="showNotification('Upgrade to Premium to enable auto-backups!', 'info'); scrollToSection('license');" style="margin-top: 16px; padding: 8px 20px; background: linear-gradient(135deg, #f39c12, #e67e22); border: none; color: white; border-radius: 8px; cursor: pointer; font-weight: 600;">Upgrade to Premium</button></div>`;return}if(!a.success)throw new Error(a.error||"Failed to load schedules");var o=a.schedules||[];if(o.length===0){U.innerHTML='<div class="panel-empty"><span class="empty-icon">\u23F0</span><div>No backup schedules configured</div><div style="font-size: 0.8rem; color: var(--muted); margin-top: 4px;">Select apps below to enable auto-backup</div></div>';return}for(var i='<div style="display: flex; flex-direction: column; gap: 8px;">',n=0;n<o.length;n++){var s=o[n],l=s.nextRun?new Date(s.nextRun).toLocaleString():"Not scheduled",m=s.lastRun?new Date(s.lastRun).toLocaleString():"Never";i+='<div style="padding: 12px 14px; background: var(--card-base); border-radius: 8px; border: 1px solid var(--border);"><div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;"> <div style="font-weight: 600; font-size: 0.9rem;">'+escapeHtml(s.appId)+'</div> <label class="toggle-switch" style="display: flex; align-items: center; gap: 6px;"> <input type="checkbox" class="schedule-toggle" data-appid="'+escapeHtml(s.appId)+'"'+(s.enabled?" checked":"")+' /> <span style="font-size: 0.75rem; color: var(--muted);">'+(s.enabled?"ON":"OFF")+'</span> </label></div><div style="display: grid; grid-template-columns: 1fr 1fr; gap: 8px; font-size: 0.8rem; margin-bottom: 10px;"> <div><span style="color: var(--muted);">Schedule:</span> <select class="schedule-select" data-appid="'+escapeHtml(s.appId)+'" style="background: var(--base); border: 1px solid var(--border); border-radius: 4px; padding: 2px 6px;"> <option value="hourly"'+(s.schedule==="hourly"?" selected":"")+'>Hourly</option> <option value="daily"'+(s.schedule==="daily"?" selected":"")+'>Daily</option> <option value="weekly"'+(s.schedule==="weekly"?" selected":"")+'>Weekly</option> <option value="monthly"'+(s.schedule==="monthly"?" selected":"")+'>Monthly</option> </select></div> <div><span style="color: var(--muted);">Keep last:</span> <input type="number" class="retention-input" data-appid="'+escapeHtml(s.appId)+'" value="'+(s.retention?.keep||7)+'" min="1" max="100" style="width: 50px; background: var(--base); border: 1px solid var(--border); border-radius: 4px; padding: 2px 6px;" /></div></div><div style="font-size: 0.75rem; color: var(--muted); margin-bottom: 10px;"> <div>Next run: '+escapeHtml(l)+"</div> <div>Last run: "+escapeHtml(m)+'</div></div><div style="display: flex; gap: 6px;"> <button class="schedule-run-now" data-appid="'+escapeHtml(s.appId)+'" style="padding: 5px 12px; font-size: 0.8rem; background: color-mix(in srgb, var(--ok-fg) 20%, transparent); border: 1px solid var(--ok-fg); color: var(--ok-fg); border-radius: 6px; cursor: pointer;">\u25B6\uFE0F Run Now</button> <button class="schedule-delete" data-appid="'+escapeHtml(s.appId)+'" style="padding: 5px 12px; font-size: 0.8rem; background: transparent; border: 1px solid var(--bad-fg); color: var(--bad-fg); border-radius: 6px; cursor: pointer;">\u{1F5D1}\uFE0F Remove</button></div></div>'}i+="</div>",i+='<div style="margin-top: 16px; padding: 16px; background: color-mix(in srgb, var(--accent) 5%, transparent); border-radius: 10px; border: 1px dashed var(--border);"><h4 style="margin: 0 0 12px; font-size: 0.85rem; color: var(--muted);">\u2795 Add New Schedule</h4><div style="display: flex; gap: 8px; flex-wrap: wrap;"> <input type="text" id="new-schedule-appid" placeholder="App ID (e.g., plex, sonarr)" style="flex: 1; min-width: 150px; padding: 8px; border-radius: 6px; border: 1px solid var(--border); background: var(--base);" /> <select id="new-schedule-interval" style="padding: 8px; border-radius: 6px; border: 1px solid var(--border); background: var(--base);"> <option value="hourly">Hourly</option> <option value="daily" selected>Daily</option> <option value="weekly">Weekly</option> <option value="monthly">Monthly</option> <option value="6h">Every 6 hours</option> <option value="30m">Every 30 minutes</option> </select> <input type="number" id="new-schedule-retention" value="7" min="1" max="100" placeholder="Keep" style="width: 70px; padding: 8px; border-radius: 6px; border: 1px solid var(--border); background: var(--base);" /> <button id="add-schedule-btn" style="padding: 8px 16px; background: var(--accent); border: none; color: white; border-radius: 6px; cursor: pointer; font-weight: 500;">Add Schedule</button></div></div>',U.innerHTML=i,U.querySelectorAll(".schedule-toggle").forEach(function(k){k.addEventListener("change",function(){u(k.dataset.appid,{enabled:k.checked})})}),U.querySelectorAll(".schedule-select").forEach(function(k){k.addEventListener("change",function(){u(k.dataset.appid,{schedule:k.value})})}),U.querySelectorAll(".retention-input").forEach(function(k){k.addEventListener("change",function(){u(k.dataset.appid,{retention:{keep:parseInt(k.value)||7}})})}),U.querySelectorAll(".schedule-run-now").forEach(function(k){k.addEventListener("click",function(){f(k.dataset.appid)})}),U.querySelectorAll(".schedule-delete").forEach(function(k){k.addEventListener("click",function(){g(k.dataset.appid)})}),document.getElementById("add-schedule-btn")?.addEventListener("click",z)}catch(k){U.innerHTML='<div class="panel-empty" style="color: var(--bad-fg);">Failed to load: '+escapeHtml(k.message)+"</div>"}}}async function u(e,a){try{var o=await secureFetch("/api/v1/backups/schedule",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({appId:e,...a})}),i=await o.json();i.success?showNotification("Schedule updated for "+e,"success"):(showNotification("Update failed: "+(i.error||"Unknown"),"error"),p())}catch(n){showNotification("Error: "+n.message,"error")}}async function f(e){try{var a=await secureFetch("/api/v1/backups/backup/"+encodeURIComponent(e),{method:"POST",headers:{"Content-Type":"application/json"}}),o=await a.json();o.success?showNotification("Backup started for "+e+"!","success"):showNotification("Backup failed: "+(o.error||"Unknown"),"error")}catch(i){showNotification("Error: "+i.message,"error")}}async function g(e){if(confirm("Remove backup schedule for "+e+"?"))try{var a=await secureFetch("/api/v1/backups/schedule/"+encodeURIComponent(e),{method:"DELETE"}),o=await a.json();o.success?(showNotification("Schedule removed for "+e,"success"),p()):showNotification("Delete failed: "+(o.error||"Unknown"),"error")}catch(i){showNotification("Error: "+i.message,"error")}}async function z(){var e=document.getElementById("new-schedule-appid")?.value?.trim(),a=document.getElementById("new-schedule-interval")?.value||"daily",o=parseInt(document.getElementById("new-schedule-retention")?.value)||7;if(!e){showNotification("Please enter an App ID","warning");return}try{var i=await secureFetch("/api/v1/backups/schedule",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({appId:e,schedule:a,retention:{keep:o},enabled:!0})}),n=await i.json();if(n.success){showNotification("Schedule created for "+e,"success"),p();var s=document.getElementById("new-schedule-appid");s&&(s.value="")}else showNotification("Failed: "+(n.error||"Unknown"),"error")}catch(l){showNotification("Error: "+l.message,"error")}}async function r(){if(b){b.innerHTML='<div class="panel-empty"><span class="brand-spinner"></span> Loading...</div>';try{var e=await fetch("/api/v1/backups/files"),a=await e.json();if(!a.success)throw new Error(a.error||"Failed to load");var o=a.files||[];if(o.length===0){b.innerHTML='<div class="panel-empty"><span class="empty-icon">\u{1F4BE}</span><div>No backup files on disk</div><div style="font-size: 0.8rem; color: var(--muted); margin-top: 4px;">Run a backup to create backup files</div></div>';return}for(var i={},n=0;n<o.length;n++){var s=o[n],l=s.appId||"unknown";i[l]||(i[l]=[]),i[l].push(s)}var m='<div style="font-size: 0.75rem; color: var(--muted); margin-bottom: 12px;">'+o.length+" backup file(s) across "+Object.keys(i).length+" app(s)</div>";m+='<div style="display: flex; flex-direction: column; gap: 12px;">';for(var k=Object.keys(i).sort(),j=0;j<k.length;j++){var l=k[j],_=i[l];m+='<div style="background: var(--card-base); border-radius: 8px; border: 1px solid var(--border); overflow: hidden;"><div style="padding: 8px 12px; background: color-mix(in srgb, var(--accent) 8%, transparent); border-bottom: 1px solid var(--border); font-weight: 600; font-size: 0.85rem;">'+escapeHtml(l)+' <span style="font-weight: normal; color: var(--muted); font-size: 0.75rem;">('+_.length+" backup(s))</span></div>";for(var F=0;F<_.length;F++){var s=_[F],q=new Date(s.timestamp).toLocaleString();m+='<div style="padding: 10px 12px; border-bottom: 1px solid var(--border);"><div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px;"> <div style="font-weight: 500; font-size: 0.85rem;">'+escapeHtml(s.name)+'</div> <div style="font-size: 0.75rem; color: var(--muted);">'+s.sizeFormatted+'</div></div><div style="font-size: 0.75rem; color: var(--muted); margin-bottom: 8px;">'+q+'</div><div style="display: flex; gap: 6px;"> <button class="disk-compare-btn" data-appid="'+escapeHtml(l)+'" data-filename="'+escapeHtml(s.name)+'" style="padding: 3px 8px; font-size: 0.75rem; background: transparent; border: 1px solid var(--accent); color: var(--accent); border-radius: 5px; cursor: pointer;">Compare</button> <button class="disk-restore-btn" data-appid="'+escapeHtml(l)+'" data-filename="'+escapeHtml(s.name)+'" style="padding: 3px 8px; font-size: 0.75rem; background: linear-gradient(135deg, var(--ok-fg), #27ae60); border: none; color: white; border-radius: 5px; cursor: pointer; font-weight: 500;">Restore</button></div></div>'}m+="</div>"}m+="</div>",b.innerHTML=m,b.querySelectorAll(".disk-compare-btn").forEach(function(J){J.addEventListener("click",function(){y(J.dataset.appid,J.dataset.filename)})}),b.querySelectorAll(".disk-restore-btn").forEach(function(J){J.addEventListener("click",function(){t(J.dataset.appid,J.dataset.filename)})})}catch(J){b.innerHTML='<div class="panel-empty" style="color: var(--bad-fg);">Failed: '+escapeHtml(J.message)+"</div>"}}}async function c(){if(T){T.innerHTML='<div class="panel-empty"><span class="brand-spinner"></span> Loading...</div>';try{var e=await fetch("/api/v1/backups/history?limit=50"),a=await e.json();if(!a.success||!a.history?.length){T.innerHTML='<div class="panel-empty"><span class="empty-icon">\u{1F4CB}</span> No backup history yet</div>';return}for(var o='<div style="display: flex; flex-direction: column; gap: 6px;">',i=0;i<a.history.length;i++){var n=a.history[i],s=n.size?(n.size/1024/1024).toFixed(2):"?";o+='<div style="padding: 10px 12px; background: var(--card-base); border-radius: 6px; border: 1px solid var(--border); font-size: 0.85rem;">',o+=' <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px;">',o+=' <span style="font-weight: 500;">'+escapeHtml(n.name||"backup")+"</span>",o+=' <div style="display: flex; align-items: center; gap: 8px;">',o+=' <span class="status-badge '+(n.status==="success"?"success":"down")+'">'+escapeHtml(n.status)+"</span>",n.status==="success"&&(o+=' <button class="backup-restore-btn" data-backup-id="'+escapeHtml(n.id)+'" style="padding: 3px 8px; font-size: 0.75rem;">Restore</button>'),o+=" </div>",o+=" </div>",o+=' <div style="font-size: 0.75rem; color: var(--muted);">',o+=" "+new Date(n.timestamp).toLocaleString()+" | "+s+" MB | "+(n.duration?(n.duration/1e3).toFixed(1)+"s":"--"),n.encrypted&&(o+=" | \u{1F512}"),o+=" </div>",o+="</div>"}o+="</div>",T.innerHTML=o,T.querySelectorAll(".backup-restore-btn").forEach(function(l){l.addEventListener("click",function(){window.__restoreServerBackup(l.dataset.backupId)})})}catch(l){T.innerHTML='<div class="panel-empty" style="color: var(--bad-fg);">Failed: '+escapeHtml(l.message)+"</div>"}}}window.__restoreServerBackup=async function(e){if(confirm("Restore from this server backup? This will overwrite current configuration."))try{var a=await secureFetch("/api/v1/backups/restore/"+e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({restoreServices:!0,restoreConfig:!0})}),o=await a.json();o.success?(showNotification("Restore completed successfully!","success"),location.reload()):showNotification("Restore failed: "+(o.error||"Unknown error"),"error")}catch(i){showNotification("Restore error: "+i.message,"error")}},document.querySelector('[data-panel="backup-schedules-tab"]')?.addEventListener("click",p),document.querySelector('[data-panel="backup-disk-tab"]')?.addEventListener("click",r),document.querySelector('[data-panel="backup-pointintime-tab"]')?.addEventListener("click",d),document.querySelector('[data-panel="backup-history-tab"]')?.addEventListener("click",c);async function d(){if(N){try{var e=await fetch("/api/v1/license/status"),a=await e.json();if(a.tier!=="premium"){N.innerHTML=`<div class="panel-empty" style="padding: 24px; text-align: center;"><div style="font-size: 2rem; margin-bottom: 12px;">\u2B50</div><div style="font-weight: 600; margin-bottom: 8px;">Premium Feature</div><div style="font-size: 0.85rem; color: var(--muted);">Point-in-time restore requires DashCaddy Premium with auto-backup enabled.</div><button onclick="showNotification('Upgrade to Premium for point-in-time restore!', 'info'); scrollToSection('license');" style="margin-top: 16px; padding: 8px 20px; background: linear-gradient(135deg, #f39c12, #e67e22); border: none; color: white; border-radius: 8px; cursor: pointer; font-weight: 600;">Upgrade to Premium</button></div>`;return}}catch{}N.innerHTML='<div class="panel-empty"><span class="brand-spinner"></span> Loading...</div>';try{var o=await fetch("/api/v1/services"),i=await o.json(),n=i.services||[];if(n.length===0){N.innerHTML='<div class="panel-empty"><span class="empty-icon">\u{1F4E6}</span> No apps deployed yet</div>';return}for(var s='<div style="padding: 8px 0 12px;"><div style="display: flex; gap: 8px; align-items: center; margin-bottom: 12px;"> <label style="font-size: 0.85rem; color: var(--muted); white-space: nowrap;">App:</label> <select id="pit-app-select" style="flex: 1; padding: 8px; border-radius: 6px; border: 1px solid var(--border); background: var(--base); max-width: 240px;">',l=0;l<n.length;l++)s+='<option value="'+escapeHtml(n[l].id||n[l].name||"")+'">'+escapeHtml(n[l].name||n[l].id||"")+"</option>";s+='</select> <button id="pit-load-btn" style="padding: 8px 16px; background: var(--accent); border: none; color: white; border-radius: 6px; cursor: pointer; font-weight: 500;">Load Backups</button></div><div id="pit-backups-list" style="max-height: 320px; overflow-y: auto;"></div></div>',N.innerHTML=s,document.getElementById("pit-load-btn")?.addEventListener("click",function(){var m=document.getElementById("pit-app-select")?.value;m&&w(m)})}catch(m){N.innerHTML='<div class="panel-empty" style="color: var(--bad-fg);">Failed: '+escapeHtml(m.message)+"</div>"}}}async function w(e){var a=document.getElementById("pit-backups-list");if(a){a.innerHTML='<div style="padding: 20px; text-align: center;"><span class="brand-spinner"></span> Loading backups...</div>';try{var o=await fetch("/api/v1/backups/files/"+encodeURIComponent(e)),i=await o.json();if(!i.success||!i.files||i.files.length===0){a.innerHTML='<div class="panel-empty"><span class="empty-icon">\u{1F4BE}</span> No backup files for '+escapeHtml(e)+"</div>";return}for(var n='<div style="font-size: 0.75rem; color: var(--muted); margin-bottom: 8px;">'+i.files.length+' backup(s)</div><div style="display: flex; flex-direction: column; gap: 6px;">',s=0;s<i.files.length;s++){var l=i.files[s],m=new Date(l.timestamp).toLocaleString();n+='<div style="padding: 10px 12px; background: var(--card-base); border-radius: 8px; border: 1px solid var(--border);"><div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px;"> <div style="font-weight: 500; font-size: 0.85rem;">'+escapeHtml(l.name)+'</div> <div style="font-size: 0.75rem; color: var(--muted);">'+l.sizeFormatted+'</div></div><div style="font-size: 0.75rem; color: var(--muted); margin-bottom: 8px;">'+m+'</div><div style="display: flex; gap: 6px;"> <button class="pit-compare-btn" data-appid="'+escapeHtml(e)+'" data-filename="'+escapeHtml(l.name)+'" style="padding: 4px 10px; font-size: 0.75rem; background: transparent; border: 1px solid var(--accent); color: var(--accent); border-radius: 5px; cursor: pointer;">Compare</button> <button class="pit-restore-btn" data-appid="'+escapeHtml(e)+'" data-filename="'+escapeHtml(l.name)+'" style="padding: 4px 10px; font-size: 0.75rem; background: linear-gradient(135deg, var(--ok-fg), #27ae60); border: none; color: white; border-radius: 5px; cursor: pointer; font-weight: 500;">Restore</button></div></div>'}n+="</div>",a.innerHTML=n,a.querySelectorAll(".pit-compare-btn").forEach(function(k){k.addEventListener("click",function(){y(k.dataset.appid,k.dataset.filename)})}),a.querySelectorAll(".pit-restore-btn").forEach(function(k){k.addEventListener("click",function(){t(k.dataset.appid,k.dataset.filename)})})}catch(k){a.innerHTML='<div class="panel-empty" style="color: var(--bad-fg);">Failed: '+escapeHtml(k.message)+"</div>"}}}async function y(e,a){try{var o=await secureFetch("/api/v1/backups/compare/"+encodeURIComponent(a),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({})}),i=await o.json();if(!i.success){showNotification("Compare failed: "+(i.error||"Unknown"),"error");return}var n=i.diff,s='<div style="position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.5); z-index: 10000; display: flex; align-items: center; justify-content: center;" id="compare-overlay"><div style="background: var(--base); border-radius: 12px; max-width: 600px; width: 90%; max-height: 80vh; overflow: auto; padding: 20px; border: 1px solid var(--border);"><h4 style="margin: 0 0 16px;">\u{1F4CA} Compare: '+escapeHtml(a)+'</h4><div style="font-size: 0.8rem; color: var(--muted); margin-bottom: 16px;">Size: '+(n.sizeFormatted||"?")+" | Created: "+new Date(n.timestamp).toLocaleString()+"</div>";if(n.services){var l=n.services.hasChanges?"\u{1F534}":"\u{1F7E2}";s+='<div style="margin-bottom: 12px; padding: 10px; background: var(--card-base); border-radius: 6px; border: 1px solid var(--border);"><div style="font-weight: 600; font-size: 0.85rem; margin-bottom: 4px;">'+l+' Services (backup vs current)</div><div style="font-size: 0.8rem; color: var(--muted);">Backup: '+n.services.backupCount+" services | Current: "+n.services.currentCount+" services</div>",n.services.hasChanges&&(s+='<div style="margin-top: 6px; font-size: 0.8rem; color: #f39c12;">Services differ \u2014 restoring will replace current configuration</div>'),s+="</div>"}if(n.config){var m=n.config.hasChanges?"\u{1F534}":"\u{1F7E2}";s+='<div style="margin-bottom: 12px; padding: 10px; background: var(--card-base); border-radius: 6px; border: 1px solid var(--border);"><div style="font-weight: 600; font-size: 0.85rem; margin-bottom: 4px;">'+m+" Configuration</div>",n.config.hasChanges?s+='<div style="font-size: 0.8rem; color: #f39c12;">Configuration differs \u2014 restoring will replace current settings</div>':s+='<div style="font-size: 0.8rem; color: var(--ok-fg);">No changes</div>',s+="</div>"}s+='<button id="compare-close-btn" style="padding: 8px 20px; background: var(--accent); border: none; color: white; border-radius: 6px; cursor: pointer; font-weight: 500;">Close</button></div></div>',document.body.insertAdjacentHTML("beforeend",s),document.getElementById("compare-close-btn")?.addEventListener("click",function(){document.getElementById("compare-overlay")?.remove()}),document.getElementById("compare-overlay")?.addEventListener("click",function(k){k.target===this&&this.remove()})}catch(k){showNotification("Compare error: "+k.message,"error")}}async function t(e,a){if(confirm("Restore "+a+" for "+e+`?
|
|
|
|
This will replace current configuration, credentials, and data. Containers will be restarted.`))try{var o=await secureFetch("/api/v1/apps/"+encodeURIComponent(e)+"/revert/"+encodeURIComponent(a),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({restartContainers:!0})}),i=await o.json();i.success?(showNotification(e+" restored to "+a,"success"),setTimeout(function(){location.reload()},1500)):showNotification("Restore failed: "+(i.error||"Unknown"),"error")}catch(n){showNotification("Restore error: "+n.message,"error")}}})(),(function(){injectModal("stats-modal",`<div id="stats-modal" class="weather-modal">
|
|
<div class="weather-modal-content" style="min-width: 750px; max-width: 950px;">
|
|
<h3>\u{1F4CA} Resource Monitor</h3>
|
|
<p class="modal-subtitle">
|
|
Real-time and historical CPU, memory, network, and disk usage for containers.
|
|
</p>
|
|
|
|
<!-- Tab bar -->
|
|
<div class="panel-tabs">
|
|
<button class="panel-tab active" data-panel="stats-live">Live Stats</button>
|
|
<button class="panel-tab" data-panel="stats-aggregated">24h Summary</button>
|
|
<button class="panel-tab" data-panel="stats-history">History</button>
|
|
<button class="panel-tab" data-panel="stats-alerts">Alerts</button>
|
|
</div>
|
|
|
|
<!-- Tab: Live Stats -->
|
|
<div id="stats-live" class="panel-section active">
|
|
<div id="stats-container" class="scroll-container">
|
|
<div style="text-align: center; padding: 40px; color: var(--muted);">
|
|
<span class="brand-spinner"></span> Loading container stats...
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tab: 24h Aggregated Summary -->
|
|
<div id="stats-aggregated" class="panel-section">
|
|
<div id="stats-aggregated-container" class="scroll-container">
|
|
<div class="panel-empty">
|
|
<span class="empty-icon">\u{1F4C8}</span>
|
|
Loading 24-hour aggregated metrics...
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tab: Long-term History -->
|
|
<div id="stats-history" class="panel-section">
|
|
<div style="display: flex; gap: 8px; align-items: center; margin-bottom: 12px; flex-wrap: wrap;">
|
|
<label style="font-size: 0.85rem; color: var(--muted);">Container:</label>
|
|
<select id="stats-history-container" style="padding: 4px 8px; background: var(--card-base); border: 1px solid var(--border); color: var(--fg); border-radius: 4px; font-size: 0.85rem; flex: 1; min-width: 180px;"></select>
|
|
<div id="stats-history-range-buttons" style="display: flex; gap: 4px;">
|
|
<button class="stats-range-btn active" data-range="1h">1h</button>
|
|
<button class="stats-range-btn" data-range="24h">24h</button>
|
|
<button class="stats-range-btn" data-range="7d">7d</button>
|
|
<button class="stats-range-btn" data-range="30d">30d</button>
|
|
<button class="stats-range-btn" data-range="1y">1y</button>
|
|
</div>
|
|
</div>
|
|
<div id="stats-history-container-area" class="scroll-container">
|
|
<div class="panel-empty">
|
|
<span class="empty-icon">\u{1F4CA}</span>
|
|
Choose a container and time range to view history.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tab: Alert Configuration -->
|
|
<div id="stats-alerts" class="panel-section">
|
|
<div id="stats-alerts-container" class="scroll-container">
|
|
<div class="panel-empty">
|
|
<span class="empty-icon">\u{1F514}</span>
|
|
Loading alert configurations...
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Auto-refresh toggle (bottom bar) -->
|
|
<div class="panel-bottom-bar">
|
|
<label class="checkbox-label" style="font-size: 0.85rem;">
|
|
<input type="checkbox" id="stats-auto-refresh" checked />
|
|
Auto-refresh every 5s
|
|
</label>
|
|
<button id="stats-refresh-btn" class="btn-sm">\u{1F504} Refresh Now</button>
|
|
<span id="stats-last-update" class="text-auto-right"></span>
|
|
</div>
|
|
|
|
<!-- Close Button -->
|
|
<div class="weather-modal-buttons modal-footer-bar">
|
|
<button id="stats-cancel">Close</button>
|
|
</div>
|
|
</div>
|
|
</div>`);const h=document.getElementById("stats-modal"),L=document.getElementById("container-stats-btn"),A=document.getElementById("stats-cancel"),I=document.getElementById("stats-refresh-btn"),D=document.getElementById("stats-auto-refresh"),R=document.getElementById("stats-container"),H=document.getElementById("stats-aggregated-container"),P=document.getElementById("stats-alerts-container"),v=document.getElementById("stats-last-update");let C=null,x=null;function $(d){if(d===0||!d)return"0 B";const w=1024,y=["B","KB","MB","GB"],t=Math.floor(Math.log(d)/Math.log(w));return parseFloat((d/Math.pow(w,t)).toFixed(1))+" "+y[t]}function E(d){return d<30?"#2ecc71":d<70?"#f39c12":"#e74c3c"}function M(d){return d<50?"#2ecc71":d<80?"#f39c12":"#e74c3c"}async function S(){try{let d=null,w=!1;try{const e=await(await fetch("/api/v1/monitoring/stats")).json();e.success&&e.stats&&(d=e.stats,w=!0,x=e.stats)}catch{}if(!w){const e=await(await fetch("/api/v1/stats/containers")).json();if(e.success&&e.stats){d={};for(const a of e.stats)d[a.name]={name:a.name,current:{cpu:a.cpu,memory:{percent:a.memory.percent,usage:a.memory.used,limit:a.memory.limit,usageMB:Math.round(a.memory.used/1048576),limitMB:Math.round(a.memory.limit/1048576)},network:{rxBytes:a.network.rx,txBytes:a.network.tx,rxMB:(a.network.rx/1048576).toFixed(1),txMB:(a.network.tx/1048576).toFixed(1)},disk:{readMB:0,writeMB:0}},status:a.status};x=d}}if(!d||Object.keys(d).length===0){R.innerHTML='<div style="text-align: center; padding: 40px; color: var(--muted);">No running containers found</div>';return}let y='<div style="display: flex; flex-direction: column; gap: 8px;">';for(const[t,e]of Object.entries(d)){const a=e.current||e,o=a.cpu?.percent||0,i=a.memory?.percent||0,n=E(o),s=M(i),l=a.memory?.usage||a.memory?.used||0,m=a.memory?.limit||0,k=a.network?.rxBytes||a.network?.rx||0,j=a.network?.txBytes||a.network?.tx||0,_=e.aggregated;y+=`
|
|
<div style="padding: 12px; background: var(--card-base); border-radius: 8px; border: 1px solid var(--border);">
|
|
<div style="display: flex; align-items: center; gap: 12px; margin-bottom: 10px;">
|
|
<span style="font-weight: 600; flex: 1;">${e.name||t}</span>
|
|
${_?`<span style="font-size: 0.65rem; color: var(--muted); padding: 2px 6px; background: color-mix(in srgb, var(--accent) 10%, transparent); border-radius: 4px;">avg ${_.cpu?.avg?.toFixed(0)||0}% cpu</span>`:""}
|
|
<span style="font-size: 0.75rem; color: var(--muted); background: var(--base); padding: 2px 8px; border-radius: 4px;">${e.status||"running"}</span>
|
|
</div>
|
|
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px;">
|
|
<div>
|
|
<div style="font-size: 0.7rem; color: var(--muted); margin-bottom: 4px;">CPU</div>
|
|
<div style="display: flex; align-items: center; gap: 8px;">
|
|
<div style="flex: 1; height: 6px; background: var(--base); border-radius: 3px; overflow: hidden;">
|
|
<div style="height: 100%; width: ${Math.min(o,100)}%; background: ${n}; border-radius: 3px; transition: width 0.3s;"></div>
|
|
</div>
|
|
<span style="font-size: 0.8rem; font-weight: 500; color: ${n}; min-width: 45px; text-align: right;">${o.toFixed(1)}%</span>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div style="font-size: 0.7rem; color: var(--muted); margin-bottom: 4px;">Memory</div>
|
|
<div style="display: flex; align-items: center; gap: 8px;">
|
|
<div style="flex: 1; height: 6px; background: var(--base); border-radius: 3px; overflow: hidden;">
|
|
<div style="height: 100%; width: ${Math.min(i,100)}%; background: ${s}; border-radius: 3px; transition: width 0.3s;"></div>
|
|
</div>
|
|
<span style="font-size: 0.8rem; font-weight: 500; color: ${s}; min-width: 45px; text-align: right;">${i.toFixed(1)}%</span>
|
|
</div>
|
|
<div style="font-size: 0.65rem; color: var(--muted); margin-top: 2px;">${$(l)} / ${$(m)}</div>
|
|
</div>
|
|
<div>
|
|
<div style="font-size: 0.7rem; color: var(--muted); margin-bottom: 4px;">Network</div>
|
|
<div style="font-size: 0.8rem;">
|
|
<span style="color: #3498db;">\u2193 ${$(k)}</span>
|
|
<span style="color: var(--muted); margin: 0 4px;">/</span>
|
|
<span style="color: #e74c3c;">\u2191 ${$(j)}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>`}y+="</div>",R.innerHTML=y,v.textContent="Updated: "+new Date().toLocaleTimeString()}catch(d){R.innerHTML=`<div style="text-align: center; padding: 40px; color: var(--bad-fg);">\u274C Failed to load stats: ${escapeHtml(d.message)}</div>`}}async function B(){if(!H)return;const d=x;if(!d||Object.keys(d).length===0){H.innerHTML='<div class="panel-empty"><span class="empty-icon">\u{1F4C8}</span>No monitoring data available. Open the Live Stats tab first.</div>';return}let w='<div style="display: flex; flex-direction: column; gap: 12px;">';for(const[y,t]of Object.entries(d)){const e=t.aggregated;e&&(w+=`<div style="padding: 12px; background: var(--card-base); border-radius: 8px; border: 1px solid var(--border);">
|
|
<div style="font-weight: 600; margin-bottom: 10px;">${t.name||y}</div>
|
|
<div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px;">
|
|
<div class="stat-mini-card"><span class="stat-val">${e.cpu?.avg?.toFixed(1)||0}%</span><span class="stat-lbl">Avg CPU</span></div>
|
|
<div class="stat-mini-card"><span class="stat-val">${e.cpu?.max?.toFixed(1)||0}%</span><span class="stat-lbl">Max CPU</span></div>
|
|
<div class="stat-mini-card"><span class="stat-val">${e.memory?.avg?.toFixed(1)||0}%</span><span class="stat-lbl">Avg Mem</span></div>
|
|
<div class="stat-mini-card"><span class="stat-val">${e.memory?.max?.toFixed(1)||0}%</span><span class="stat-lbl">Max Mem</span></div>
|
|
</div>
|
|
${e.dataPoints?`<div style="font-size: 0.7rem; color: var(--muted); margin-top: 6px;">${e.dataPoints} data points over ${e.timeRange||24}h</div>`:""}
|
|
</div>`)}w+="</div>",H.innerHTML=w}async function U(){if(!P)return;P.innerHTML='<div class="panel-empty"><span class="brand-spinner"></span> Loading alerts...</div>';const d=x;if(!d||Object.keys(d).length===0){P.innerHTML='<div class="panel-empty"><span class="empty-icon">\u{1F514}</span>No containers found. Open the Live Stats tab first.</div>';return}let w=!1;try{w=(await(await fetch("/api/v1/license/feature/resource-alerts")).json()).available}catch{w=!1}let y=[];try{const s=await(await fetch("/api/v1/monitoring/alerts?limit=50")).json();s.success&&(y=s.history||[])}catch{}let t={};try{const s=await(await fetch("/api/v1/monitoring/alerts/config")).json();s.success&&(t=s.configs||{})}catch{}const a=Object.entries(d).map(([n,s])=>{const l=t[n]||{cpuThreshold:80,memoryThreshold:90,diskIOThreshold:50,autoRestart:!1,enabled:!1};return`
|
|
<tr data-container="${n}">
|
|
<td style="font-weight: 600; padding: 8px;">${s.name||n}</td>
|
|
<td style="padding: 4px 8px;"><input type="number" class="alert-cpu" value="${l.cpuThreshold??80}" min="0" max="100" style="width: 60px; font-size: 0.8rem; padding: 2px 4px;" ${w?"":"disabled"} /></td>
|
|
<td style="padding: 4px 8px;"><input type="number" class="alert-mem" value="${l.memoryThreshold??90}" min="0" max="100" style="width: 60px; font-size: 0.8rem; padding: 2px 4px;" ${w?"":"disabled"} /></td>
|
|
<td style="padding: 4px 8px;"><input type="number" class="alert-disk" value="${l.diskIOThreshold??50}" min="0" max="1000" style="width: 70px; font-size: 0.8rem; padding: 2px 4px;" ${w?"":"disabled"} /></td>
|
|
<td style="padding: 4px 8px;"><input type="checkbox" class="alert-autorestart" ${l.autoRestart?"checked":""} ${w?"":"disabled"} /></td>
|
|
<td style="padding: 4px 8px;">
|
|
<button class="alert-test-btn btn-xs" data-container="${n}" data-name="${s.name||n}" style="padding: 2px 8px; font-size: 0.75rem; background: var(--card-base); border: 1px solid var(--border); border-radius: 4px; cursor: pointer;">Test</button>
|
|
</td>
|
|
</tr>
|
|
`}).join(""),o=y.map(n=>{const s=new Date(n.timestamp).toLocaleString(),l=n.notified?"\u2713":"\u2014";return`
|
|
<tr>
|
|
<td style="padding: 6px 8px; font-size: 0.8rem; color: var(--muted);">${s}</td>
|
|
<td style="padding: 6px 8px; font-weight: 500;">${n.containerName||n.containerId}</td>
|
|
<td style="padding: 6px 8px; text-transform: capitalize;">${n.metric||n.type}</td>
|
|
<td style="padding: 6px 8px;">${typeof n.value=="number"?n.value.toFixed(1):n.value}${n.metric==="disk"?" MB/s":"%"}</td>
|
|
<td style="padding: 6px 8px; text-align: center;">${l}</td>
|
|
<td style="padding: 6px 8px; font-size: 0.75rem; color: ${n.autoRestartTriggered?"#f39c12":"var(--muted)"};">${n.autoRestartTriggered?"\u21BB":""}</td>
|
|
</tr>
|
|
`}).join(""),i=w?`
|
|
<div style="margin-bottom: 20px;">
|
|
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px;">
|
|
<h4 style="margin: 0; font-size: 0.9rem;">\u2699\uFE0F Alert Configuration</h4>
|
|
<a href="#" id="go-to-notifications" style="font-size: 0.8rem; color: var(--accent); text-decoration: none;">Configure notifications \u2192</a>
|
|
</div>
|
|
<div style="overflow-x: auto;">
|
|
<table style="width: 100%; border-collapse: collapse; font-size: 0.85rem;">
|
|
<thead>
|
|
<tr style="border-bottom: 1px solid var(--border);">
|
|
<th style="text-align: left; padding: 6px 8px; color: var(--muted);">Container</th>
|
|
<th style="text-align: left; padding: 6px 8px; color: var(--muted);">CPU %</th>
|
|
<th style="text-align: left; padding: 6px 8px; color: var(--muted);">Mem %</th>
|
|
<th style="text-align: left; padding: 6px 8px; color: var(--muted);">Disk I/O MB/s</th>
|
|
<th style="text-align: center; padding: 6px 8px; color: var(--muted);">Auto-Restart</th>
|
|
<th style="padding: 6px 8px;"></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>${a}</tbody>
|
|
</table>
|
|
</div>
|
|
<div style="margin-top: 12px; display: flex; justify-content: flex-end;">
|
|
<button id="save-all-alerts" style="padding: 6px 16px; font-size: 0.85rem; background: var(--accent); color: var(--base); border: none; border-radius: 4px; cursor: pointer; font-weight: 600;">Save All</button>
|
|
</div>
|
|
</div>
|
|
`:`
|
|
<div style="margin-bottom: 20px; padding: 12px; background: rgba(241,196,15,0.1); border: 1px solid rgba(241,196,15,0.3); border-radius: 8px; text-align: center;">
|
|
<span style="color: #f1c40f; font-weight: 600; font-size: 0.85rem;">\u2B50 Premium Feature</span>
|
|
<p style="margin: 6px 0 0; font-size: 0.75rem; color: var(--muted);">Upgrade to configure resource alert thresholds per container.</p>
|
|
<button id="upgrade-for-alerts" style="margin-top: 8px; padding: 4px 12px; font-size: 0.75rem; background: #f1c40f; color: #000; border: none; border-radius: 4px; cursor: pointer; font-weight: 600;">Upgrade Now</button>
|
|
</div>
|
|
`;P.innerHTML=`
|
|
${i}
|
|
<div>
|
|
<h4 style="margin: 0 0 10px; font-size: 0.9rem;">\u{1F4CB} Recent Alerts</h4>
|
|
${o?`
|
|
<div style="overflow-x: auto;">
|
|
<table style="width: 100%; border-collapse: collapse; font-size: 0.8rem;">
|
|
<thead>
|
|
<tr style="border-bottom: 1px solid var(--border);">
|
|
<th style="text-align: left; padding: 6px 8px; color: var(--muted);">Time</th>
|
|
<th style="text-align: left; padding: 6px 8px; color: var(--muted);">Container</th>
|
|
<th style="text-align: left; padding: 6px 8px; color: var(--muted);">Metric</th>
|
|
<th style="text-align: left; padding: 6px 8px; color: var(--muted);">Value</th>
|
|
<th style="text-align: center; padding: 6px 8px; color: var(--muted);">\u2713?</th>
|
|
<th style="padding: 6px 8px;"></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>${o}</tbody>
|
|
</table>
|
|
</div>
|
|
`:'<div style="color: var(--muted); text-align: center; padding: 20px;">No alerts recorded yet.</div>'}
|
|
</div>
|
|
`,document.getElementById("save-all-alerts")?.addEventListener("click",async()=>{const n={};document.querySelectorAll("#stats-alerts-container tr[data-container]").forEach(s=>{const l=s.dataset.container;n[l]={cpuThreshold:parseInt(s.querySelector(".alert-cpu")?.value)||80,memoryThreshold:parseInt(s.querySelector(".alert-mem")?.value)||90,diskIOThreshold:parseInt(s.querySelector(".alert-disk")?.value)||50,autoRestart:!!s.querySelector(".alert-autorestart")?.checked,enabled:!0}});try{const l=await(await secureFetch("/api/v1/monitoring/alerts/config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({configs:n})})).json(),m=document.getElementById("save-all-alerts");m.textContent=l.success?"\u2705 Saved":"\u274C Failed",setTimeout(()=>{m.textContent="Save All"},2e3)}catch{const l=document.getElementById("save-all-alerts");l.textContent="\u274C Error",setTimeout(()=>{l.textContent="Save All"},2e3)}}),document.getElementById("go-to-notifications")?.addEventListener("click",n=>{n.preventDefault(),h.classList.remove("show"),b(),document.getElementById("manage-notifications")?.click()}),document.querySelectorAll(".alert-test-btn").forEach(n=>{n.addEventListener("click",async()=>{const s=n.textContent;n.textContent="...";try{await secureFetch(`/api/v1/monitoring/alerts/${n.dataset.container}/test`,{method:"POST"}),n.textContent="\u2705",showNotification("Test alert sent for "+n.dataset.name,"success",3e3)}catch{n.textContent="\u274C"}setTimeout(()=>{n.textContent=s},2e3)})}),document.getElementById("upgrade-for-alerts")?.addEventListener("click",()=>{h.classList.remove("show"),b(),typeof openLicenseModal=="function"&&openLicenseModal()})}function T(){C&&clearInterval(C),D?.checked&&(C=setInterval(S,DC.POLL.STATS))}function b(){C&&(clearInterval(C),C=null)}L?.addEventListener("click",()=>{h.classList.add("show"),S(),T()}),A?.addEventListener("click",()=>{h.classList.remove("show"),b()}),h?.addEventListener("click",d=>{d.target===h&&(h.classList.remove("show"),b())}),I?.addEventListener("click",S),D?.addEventListener("change",()=>{D.checked?T():b()}),document.querySelector('[data-panel="stats-aggregated"]')?.addEventListener("click",B),document.querySelector('[data-panel="stats-alerts"]')?.addEventListener("click",U);const N=document.getElementById("stats-history-container"),O=document.getElementById("stats-history-container-area"),p=document.querySelectorAll(".stats-range-btn");let u="1h";function f(d){switch(d){case"1h":return 3600*1e3;case"24h":return 1440*60*1e3;case"7d":return 10080*60*1e3;case"30d":return 720*60*60*1e3;case"1y":return 365*24*60*60*1e3;default:return 3600*1e3}}function g(d){return d==="raw"?"live (10s samples)":d==="hourly"?"hourly average":d==="daily"?"daily average":d}function z(d,w,y,t,e){if(!d||d.length===0)return`<div style="text-align: center; color: var(--muted); padding: 20px;">No data for ${escapeHtml(t)}</div>`;const a=d.map(w).filter(q=>q!=null);if(a.length===0)return`<div style="text-align: center; color: var(--muted); padding: 20px;">No data for ${escapeHtml(t)}</div>`;const o=Math.max(...a,1),i=Math.min(...a,0),n=o-i||1,s=600,l=80,m=4,k=(s-m*2)/Math.max(a.length-1,1),j=a.map((q,J)=>{const X=m+J*k,Q=l-m-(q-i)/n*(l-m*2);return`${X.toFixed(1)},${Q.toFixed(1)}`}).join(" "),_=a[a.length-1],F=a.reduce((q,J)=>q+J,0)/a.length;return`
|
|
<div style="margin-bottom: 14px;">
|
|
<div style="display: flex; align-items: baseline; gap: 12px; margin-bottom: 4px;">
|
|
<span style="font-weight: 600; font-size: 0.9rem;">${escapeHtml(t)}</span>
|
|
<span style="font-size: 0.75rem; color: var(--muted);">last ${_.toFixed(1)}${e} \xB7 avg ${F.toFixed(1)}${e} \xB7 max ${o.toFixed(1)}${e}</span>
|
|
</div>
|
|
<svg viewBox="0 0 ${s} ${l}" preserveAspectRatio="none" style="width: 100%; height: ${l}px; background: var(--base); border-radius: 4px;">
|
|
<polyline fill="none" stroke="${y}" stroke-width="1.5" points="${j}" />
|
|
</svg>
|
|
</div>
|
|
`}function r(){if(!N)return;const d=x||{},w=N.value,y=Object.entries(d);if(y.length===0){N.innerHTML='<option value="">No containers</option>';return}N.innerHTML=y.map(([t,e])=>`<option value="${escapeHtml(t)}">${escapeHtml(e.name||t)}</option>`).join(""),w&&d[w]&&(N.value=w)}async function c(){if(!O||!N)return;const d=N.value;if(!d){O.innerHTML='<div class="panel-empty"><span class="empty-icon">\u{1F4CA}</span>No container selected.</div>';return}const w=Date.now(),y=w-f(u);O.innerHTML='<div class="panel-empty"><span class="brand-spinner"></span> Loading history...</div>';try{const e=await(await fetch(`/api/v1/monitoring/history/${encodeURIComponent(d)}?startTime=${y}&endTime=${w}`)).json();if(!e.success)throw new Error(e.error||"Failed to load history");const a=e.samples||[],o=e.tier||"raw";if(a.length===0){O.innerHTML=`<div class="panel-empty"><span class="empty-icon">\u{1F4CA}</span>No data for the last ${u}. Tier: ${g(o)}.</div>`;return}const i=o==="raw",n=i?j=>j.cpu?.percent:j=>j.cpu?.avg,s=i?j=>j.memory?.percent:j=>j.memory?.avgPercent,l=i?j=>j.network?.rxMB||0:j=>j.network?.rxMB||0,m=i?j=>j.network?.txMB||0:j=>j.network?.txMB||0;let k=`
|
|
<div style="font-size: 0.75rem; color: var(--muted); margin-bottom: 8px;">
|
|
${a.length} samples \xB7 ${escapeHtml(g(o))} \xB7 ${new Date(y).toLocaleString()} \u2192 ${new Date(w).toLocaleString()}
|
|
</div>
|
|
`;k+=z(a,n,"#2ecc71","CPU","%"),k+=z(a,s,"#3498db","Memory","%"),k+=z(a,l,"#9b59b6","Network RX"," MB"),k+=z(a,m,"#e67e22","Network TX"," MB"),O.innerHTML=k}catch(t){O.innerHTML=`<div class="panel-empty"><span class="empty-icon">\u26A0\uFE0F</span>Failed to load history: ${escapeHtml(t.message)}</div>`}}p.forEach(d=>{d.addEventListener("click",()=>{p.forEach(w=>w.classList.remove("active")),d.classList.add("active"),u=d.dataset.range,c()})}),N?.addEventListener("change",c),document.querySelector('[data-panel="stats-history"]')?.addEventListener("click",()=>{r(),c()})})(),(function(){injectModal("health-modal",`<div id="health-modal" class="weather-modal">
|
|
<div class="weather-modal-content" style="min-width: 800px; max-width: 1000px;">
|
|
<h3>\u{1F3E5} Health Check Dashboard</h3>
|
|
<p class="modal-subtitle">
|
|
Service uptime tracking, SLA monitoring, and incident management.
|
|
</p>
|
|
|
|
<div class="panel-tabs">
|
|
<button class="panel-tab active" data-panel="health-status">Status</button>
|
|
<button class="panel-tab" data-panel="health-incidents">Incidents</button>
|
|
<button class="panel-tab" data-panel="health-config">Configure</button>
|
|
</div>
|
|
|
|
<!-- Tab: Status -->
|
|
<div id="health-status" class="panel-section active">
|
|
<div id="health-status-container" class="scroll-container">
|
|
<div class="panel-empty"><span class="brand-spinner"></span> Loading health status...</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tab: Incidents -->
|
|
<div id="health-incidents" class="panel-section">
|
|
<div id="health-incidents-container" class="scroll-container">
|
|
<div class="panel-empty"><span class="empty-icon">\u{1F6A8}</span> Loading incidents...</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tab: Configure -->
|
|
<div id="health-config" class="panel-section">
|
|
<div id="health-config-container" class="scroll-container">
|
|
<div class="panel-empty"><span class="empty-icon">\u2699\uFE0F</span> Loading configuration...</div>
|
|
</div>
|
|
|
|
<!-- Global Settings: retention, polling intervals, max entries, disk-usage threshold -->
|
|
<div id="health-global-settings" style="margin-top: 16px; padding: 16px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--card-base);">
|
|
<h4 style="margin: 0 0 4px;">\u{1F30D} Global Settings</h4>
|
|
<p class="text-muted-sm" style="margin: 0 0 12px;">Applies to all health checks. Settings are stored locally in this browser.</p>
|
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px;">
|
|
<div>
|
|
<label class="text-muted-sm">Health Check Polling Interval (seconds)</label>
|
|
<input type="number" id="health-setting-interval" value="60" min="5" max="3600" class="form-input" />
|
|
<div style="font-size: 0.72rem; color: var(--muted); margin-top: 2px;">How often each service's health endpoint is checked.</div>
|
|
</div>
|
|
<div>
|
|
<label class="text-muted-sm">Stats Polling Interval (seconds)</label>
|
|
<input type="number" id="health-setting-stats-interval" value="30" min="5" max="3600" class="form-input" />
|
|
<div style="font-size: 0.72rem; color: var(--muted); margin-top: 2px;">How often container statistics (CPU/memory) are sampled.</div>
|
|
</div>
|
|
<div>
|
|
<label class="text-muted-sm">Max Entries Per Service</label>
|
|
<input type="number" id="health-setting-max-entries" value="500" min="10" max="100000" class="form-input" />
|
|
<div style="font-size: 0.72rem; color: var(--muted); margin-top: 2px;">Cap on stored history records per service.</div>
|
|
</div>
|
|
<div>
|
|
<label class="text-muted-sm">Data Retention (days)</label>
|
|
<input type="number" id="health-setting-retention" value="30" min="1" max="3650" class="form-input" />
|
|
<div style="font-size: 0.72rem; color: var(--muted); margin-top: 2px;">Health history older than this is pruned.</div>
|
|
</div>
|
|
<div>
|
|
<label class="text-muted-sm">Disk-Usage Warning (%)</label>
|
|
<input type="number" id="health-setting-disk-threshold" value="80" min="50" max="99" class="form-input" />
|
|
<div style="font-size: 0.72rem; color: var(--muted); margin-top: 2px;">Warn when disk usage exceeds this level.</div>
|
|
</div>
|
|
</div>
|
|
<div style="margin-top: 12px; display: flex; gap: 8px; align-items: center;">
|
|
<button id="health-global-save" class="btn-accent-solid">Save Global Settings</button>
|
|
<button id="health-global-reset" class="btn-sm">Reset to Defaults</button>
|
|
<span id="health-global-status" style="font-size: 0.8rem; color: var(--muted);"></span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Add/Edit Health Check Form -->
|
|
<div id="health-config-form" style="display: none; margin-top: 16px; padding: 16px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--card-base);">
|
|
<h4 id="health-form-title" style="margin: 0 0 12px;">Add Health Check</h4>
|
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px;">
|
|
<div>
|
|
<label class="text-muted-sm">Service ID</label>
|
|
<input type="text" id="health-form-id" placeholder="e.g. plex" class="form-input" />
|
|
</div>
|
|
<div>
|
|
<label class="text-muted-sm">Display Name</label>
|
|
<input type="text" id="health-form-name" placeholder="e.g. Plex Media Server" class="form-input" />
|
|
</div>
|
|
<div style="grid-column: span 2;">
|
|
<label class="text-muted-sm">URL</label>
|
|
<input type="text" id="health-form-url" placeholder="https://plex.home" class="form-input" />
|
|
</div>
|
|
<div>
|
|
<label class="text-muted-sm">Timeout (ms)</label>
|
|
<input type="number" id="health-form-timeout" value="10000" class="form-input" />
|
|
</div>
|
|
<div>
|
|
<label class="text-muted-sm">Expected Status Codes</label>
|
|
<input type="text" id="health-form-codes" value="200" placeholder="200, 301, 302" class="form-input" />
|
|
</div>
|
|
<div>
|
|
<label class="text-muted-sm">SLA Target (%)</label>
|
|
<input type="number" id="health-form-sla" value="99.9" step="0.1" class="form-input" />
|
|
</div>
|
|
<div>
|
|
<label class="text-muted-sm">Slow Response Threshold (ms)</label>
|
|
<input type="number" id="health-form-slow" value="5000" class="form-input" />
|
|
</div>
|
|
</div>
|
|
<div style="margin-top: 12px; display: flex; gap: 8px; justify-content: flex-end;">
|
|
<button id="health-form-cancel">Cancel</button>
|
|
<button id="health-form-save" class="btn-accent-solid">Save</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div style="margin-top: 12px;">
|
|
<button id="health-add-btn" class="btn-accent-solid">+ Add Health Check</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel-bottom-bar">
|
|
<button id="health-refresh-btn" class="btn-sm">\u{1F504} Refresh</button>
|
|
<span id="health-last-update" class="text-auto-right"></span>
|
|
</div>
|
|
|
|
<div class="weather-modal-buttons modal-footer-bar">
|
|
<button id="health-cancel">Close</button>
|
|
</div>
|
|
</div>
|
|
</div>`);const h=document.getElementById("health-modal"),L=document.getElementById("health-check-btn"),A=document.getElementById("health-cancel"),I=document.getElementById("health-refresh-btn"),D=document.getElementById("health-status-container"),R=document.getElementById("health-incidents-container"),H=document.getElementById("health-config-container"),P=document.getElementById("health-last-update"),v=document.getElementById("health-add-btn"),C=document.getElementById("health-config-form"),x=document.getElementById("health-form-title"),$=document.getElementById("health-form-cancel"),E=document.getElementById("health-form-save"),M="dashcaddy-health-settings",S={retentionDays:30,pollingInterval:60,statsPollingInterval:30,maxEntriesPerService:500,diskUsageThreshold:80},B=document.getElementById("health-global-save"),U=document.getElementById("health-global-reset"),T=document.getElementById("health-global-status"),b=document.getElementById("health-setting-retention"),N=document.getElementById("health-setting-interval"),O=document.getElementById("health-setting-stats-interval"),p=document.getElementById("health-setting-max-entries"),u=document.getElementById("health-setting-disk-threshold");function f(){try{const i=safeGet(M),n=i?JSON.parse(i):{};return Object.assign({},S,n)}catch{return Object.assign({},S)}}function g(){const i=f();b&&(b.value=i.retentionDays),N&&(N.value=i.pollingInterval),O&&(O.value=i.statsPollingInterval),p&&(p.value=i.maxEntriesPerService),u&&(u.value=i.diskUsageThreshold)}function z(){const i={retentionDays:Math.max(1,Math.min(3650,parseInt(b?.value)||S.retentionDays)),pollingInterval:Math.max(5,Math.min(3600,parseInt(N?.value)||S.pollingInterval)),statsPollingInterval:Math.max(5,Math.min(3600,parseInt(O?.value)||S.statsPollingInterval)),maxEntriesPerService:Math.max(10,Math.min(1e5,parseInt(p?.value)||S.maxEntriesPerService)),diskUsageThreshold:Math.max(50,Math.min(99,parseInt(u?.value)||S.diskUsageThreshold))};try{safeSet(M,JSON.stringify(i)),g(),T&&(T.textContent="Saved \u2713",T.style.color="var(--ok-fg)",setTimeout(()=>{T&&(T.textContent="")},2500)),typeof showNotification=="function"&&showNotification("Global health settings saved","success")}catch(n){T&&(T.textContent="Save failed",T.style.color="var(--bad-fg)"),typeof showNotification=="function"&&showNotification("Failed to save settings: "+n.message,"error")}}function r(){try{safeSet(M,JSON.stringify(S))}catch{}g(),T&&(T.textContent="Reset to defaults \u2713",T.style.color="var(--ok-fg)",setTimeout(()=>{T&&(T.textContent="")},2500))}g(),B?.addEventListener("click",z),U?.addEventListener("click",r);let c=null;function d(i){return i>=99.9?"var(--ok-fg)":i>=95?"#f39c12":"var(--bad-fg)"}function w(i){const n={critical:"var(--bad-fg)",high:"#ff6b6b",medium:"#f39c12",low:"var(--muted)"};return`<span style="padding: 2px 8px; border-radius: 4px; font-size: 0.75rem; background: ${n[i]||"var(--muted)"}20; color: ${n[i]||"var(--muted)"};">${i}</span>`}async function y(){try{const n=await(await fetch("/api/v1/health-checks/status")).json();if(!n.success||!n.status||Object.keys(n.status).length===0){D.innerHTML='<div class="panel-empty"><span class="empty-icon">\u{1F3E5}</span>No health checks configured. Go to the Configure tab to add services.</div>';return}const s=Object.values(n.status);let l='<table style="width: 100%; border-collapse: collapse; font-size: 0.85rem;">';l+='<tr style="border-bottom: 1px solid var(--border); color: var(--muted); text-align: left;">',l+='<th style="padding: 8px;">Service</th><th style="padding: 8px;">Status</th>',l+='<th style="padding: 8px;">Uptime 24h</th><th style="padding: 8px;">Uptime 7d</th>',l+='<th style="padding: 8px;">Avg Response</th><th style="padding: 8px;">Last Check</th></tr>';for(const m of s){const k=m.status==="up",j=k?"var(--dot-ok)":"var(--dot-bad)",_=m.uptime?.["24h"]??"-",F=m.uptime?.["7d"]??"-",q=m.avgResponseTime!=null?Math.round(m.avgResponseTime)+"ms":"-",J=m.timestamp?timeAgo(m.timestamp):"-";l+=`<tr style="border-bottom: 1px solid var(--border); cursor: pointer;" data-health-id="${escapeHtml(m.serviceId)}">`,l+=`<td style="padding: 8px; font-weight: 500;">${escapeHtml(m.name||m.serviceId)}</td>`,l+=`<td style="padding: 8px;"><span style="display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: ${j}; margin-right: 6px;"></span>${k?"Up":"Down"}</td>`,l+=`<td style="padding: 8px; color: ${typeof _=="number"?d(_):"var(--muted)"};">${typeof _=="number"?_.toFixed(1)+"%":_}</td>`,l+=`<td style="padding: 8px; color: ${typeof F=="number"?d(F):"var(--muted)"};">${typeof F=="number"?F.toFixed(1)+"%":F}</td>`,l+=`<td style="padding: 8px;">${q}</td>`,l+=`<td style="padding: 8px; color: var(--muted);">${J}</td>`,l+="</tr>",l+=`<tr id="health-detail-${escapeHtml(m.serviceId)}" style="display: none;"><td colspan="6" style="padding: 12px; background: var(--bg); border-bottom: 1px solid var(--border);"><div class="panel-empty"><span class="brand-spinner"></span> Loading details...</div></td></tr>`}l+="</table>",D.innerHTML=l,P.textContent="Updated "+new Date().toLocaleTimeString(),D.querySelectorAll("tr[data-health-id]").forEach(m=>{m.addEventListener("click",async()=>{const k=m.dataset.healthId,j=document.getElementById("health-detail-"+k);if(j){if(j.style.display!=="none"){j.style.display="none";return}j.style.display="";try{const F=await(await fetch(`/api/v1/health-checks/${k}/stats?hours=24`)).json();if(F.success&&F.stats){const q=F.stats,J=q.responseTime||{};j.querySelector("td").innerHTML=`
|
|
<div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; font-size: 0.82rem;">
|
|
<div><span style="color: var(--muted);">Total Checks</span><br><strong>${q.totalChecks||0}</strong></div>
|
|
<div><span style="color: var(--muted);">Uptime</span><br><strong style="color: ${d(q.uptime||0)};">${(q.uptime||0).toFixed(2)}%</strong></div>
|
|
<div><span style="color: var(--muted);">Avg Response</span><br><strong>${Math.round(J.avg||0)}ms</strong></div>
|
|
<div><span style="color: var(--muted);">P95 / P99</span><br><strong>${Math.round(J.p95||0)}ms / ${Math.round(J.p99||0)}ms</strong></div>
|
|
<div><span style="color: var(--muted);">Min Response</span><br><strong>${Math.round(J.min||0)}ms</strong></div>
|
|
<div><span style="color: var(--muted);">Max Response</span><br><strong>${Math.round(J.max||0)}ms</strong></div>
|
|
<div><span style="color: var(--muted);">Up Checks</span><br><strong style="color: var(--ok-fg);">${q.upChecks||0}</strong></div>
|
|
<div><span style="color: var(--muted);">Down Checks</span><br><strong style="color: var(--bad-fg);">${q.downChecks||0}</strong></div>
|
|
</div>`}else j.querySelector("td").innerHTML='<div class="panel-empty">No detailed stats available for this period.</div>'}catch(_){j.querySelector("td").innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Failed: ${escapeHtml(_.message)}</div>`}}})})}catch(i){D.innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Failed to load health status: ${escapeHtml(i.message)}</div>`}}async function t(){try{const[i,n]=await Promise.all([fetch("/api/v1/health-checks/incidents"),fetch("/api/v1/health-checks/incidents/history?limit=50")]),s=await i.json(),l=await n.json();let m="";const k=s.success&&s.incidents?s.incidents:[];if(k.length>0){m+='<div style="margin-bottom: 16px;"><h4 style="color: var(--bad-fg); margin: 0 0 8px;">Open Incidents ('+k.length+")</h4>";for(const _ of k)m+=`<div style="padding: 10px 12px; margin-bottom: 8px; border: 1px solid var(--bad-fg)30; border-radius: 8px; background: var(--bad-bg);">
|
|
<div style="display: flex; justify-content: space-between; align-items: center;">
|
|
<span style="font-weight: 500;">${escapeHtml(_.serviceId)}</span>
|
|
<span>${w(_.severity)}</span>
|
|
</div>
|
|
<div style="font-size: 0.82rem; color: var(--muted); margin-top: 4px;">${escapeHtml(_.message)}</div>
|
|
<div style="font-size: 0.75rem; color: var(--muted); margin-top: 4px;">Started ${timeAgo(_.createdAt)} \xB7 ${_.occurrences||1} occurrence(s)</div>
|
|
</div>`;m+="</div>"}else m+='<div style="padding: 12px; margin-bottom: 16px; border: 1px solid var(--ok-fg)30; border-radius: 8px; background: var(--ok-bg); text-align: center; color: var(--ok-fg); font-size: 0.9rem;">All services operational \u2014 no open incidents</div>';const j=l.success&&l.history?l.history:[];if(j.length>0){m+='<h4 style="margin: 0 0 8px; color: var(--muted);">Incident History</h4>',m+='<table style="width: 100%; border-collapse: collapse; font-size: 0.82rem;">',m+='<tr style="border-bottom: 1px solid var(--border); color: var(--muted);"><th style="padding: 6px; text-align: left;">Service</th><th style="padding: 6px; text-align: left;">Type</th><th style="padding: 6px; text-align: left;">Severity</th><th style="padding: 6px; text-align: left;">Status</th><th style="padding: 6px; text-align: left;">Duration</th><th style="padding: 6px; text-align: left;">When</th></tr>';for(const _ of j){const F=_.status==="resolved",q=F&&_.duration?_.duration<6e4?Math.round(_.duration/1e3)+"s":Math.round(_.duration/6e4)+"m":"-";m+='<tr style="border-bottom: 1px solid var(--border);">',m+=`<td style="padding: 6px;">${escapeHtml(_.serviceId)}</td>`,m+=`<td style="padding: 6px;">${escapeHtml(_.type)}</td>`,m+=`<td style="padding: 6px;">${w(_.severity)}</td>`,m+=`<td style="padding: 6px;"><span style="color: ${F?"var(--ok-fg)":"var(--bad-fg)"};">${_.status}</span></td>`,m+=`<td style="padding: 6px;">${q}</td>`,m+=`<td style="padding: 6px; color: var(--muted);">${timeAgo(_.createdAt)}</td>`,m+="</tr>"}m+="</table>"}R.innerHTML=m||'<div class="panel-empty"><span class="empty-icon">\u{1F6A8}</span>No incidents recorded yet.</div>'}catch(i){R.innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Failed: ${escapeHtml(i.message)}</div>`}}async function e(){try{const n=await(await fetch("/api/v1/health-checks/status")).json(),s=n.success&&n.status?Object.values(n.status):[];if(s.length===0){H.innerHTML='<div class="panel-empty"><span class="empty-icon">\u2699\uFE0F</span>No health checks configured yet. Click "Add Health Check" below.</div>';return}let l='<table style="width: 100%; border-collapse: collapse; font-size: 0.85rem;">';l+='<tr style="border-bottom: 1px solid var(--border); color: var(--muted);"><th style="padding: 8px; text-align: left;">Service</th><th style="padding: 8px; text-align: left;">Status</th><th style="padding: 8px; text-align: left;">SLA Target</th><th style="padding: 8px; text-align: right;">Actions</th></tr>';for(const m of s){const k=m.status==="up";l+='<tr style="border-bottom: 1px solid var(--border);">',l+=`<td style="padding: 8px; font-weight: 500;">${escapeHtml(m.name||m.serviceId)}</td>`,l+=`<td style="padding: 8px; color: ${k?"var(--ok-fg)":"var(--bad-fg)"};">${k?"Up":"Down"}</td>`,l+=`<td style="padding: 8px;">${m.sla?.target?m.sla.target+"%":"-"}</td>`,l+='<td style="padding: 8px; text-align: right;">',l+=`<button onclick="document.dispatchEvent(new CustomEvent('health-edit', {detail:'${escapeHtml(m.serviceId)}'}))" style="padding: 4px 10px; font-size: 0.78rem; margin-right: 4px;">Edit</button>`,l+=`<button onclick="document.dispatchEvent(new CustomEvent('health-delete', {detail:'${escapeHtml(m.serviceId)}'}))" style="padding: 4px 10px; font-size: 0.78rem; color: var(--bad-fg); border-color: var(--bad-fg);">Delete</button>`,l+="</td></tr>"}l+="</table>",H.innerHTML=l}catch(i){H.innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Failed: ${escapeHtml(i.message)}</div>`}}function a(i,n,s,l,m,k,j){c=i||null,x.textContent=i?"Edit Health Check":"Add Health Check",document.getElementById("health-form-id").value=i||"",document.getElementById("health-form-id").disabled=!!i,document.getElementById("health-form-name").value=n||"",document.getElementById("health-form-url").value=s||"",document.getElementById("health-form-timeout").value=l||1e4,document.getElementById("health-form-codes").value=m||"200",document.getElementById("health-form-sla").value=k||99.9,document.getElementById("health-form-slow").value=j||5e3,C.style.display="",v.style.display="none"}function o(){C.style.display="none",v.style.display="",c=null}v?.addEventListener("click",()=>a("","","",1e4,"200",99.9,5e3)),$?.addEventListener("click",o),E?.addEventListener("click",async()=>{const i=c||document.getElementById("health-form-id").value.trim();if(!i)return showNotification("Service ID is required","warning");const n=document.getElementById("health-form-url").value.trim();if(!n)return showNotification("URL is required","warning");const s=document.getElementById("health-form-codes").value.split(",").map(m=>parseInt(m.trim())).filter(Boolean),l={name:document.getElementById("health-form-name").value.trim()||i,url:n,timeout:parseInt(document.getElementById("health-form-timeout").value)||1e4,expectedStatusCodes:s.length?s:[200],sla:{target:parseFloat(document.getElementById("health-form-sla").value)||99.9},slowResponseThreshold:parseInt(document.getElementById("health-form-slow").value)||5e3};try{E.textContent="Saving...",E.disabled=!0;const k=await(await secureFetch(`/api/v1/health-checks/${encodeURIComponent(i)}/configure`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(l)})).json();if(!k.success)throw new Error(k.error||"Save failed");o(),e(),y()}catch(m){showNotification("Error: "+m.message,"error")}finally{E.textContent="Save",E.disabled=!1}}),document.addEventListener("health-edit",async i=>{const n=i.detail;a(n,"","",1e4,"200",99.9,5e3)}),document.addEventListener("health-delete",async i=>{const n=i.detail;if(confirm(`Delete health check for "${n}"?`))try{const l=await(await secureFetch(`/api/v1/health-checks/${encodeURIComponent(n)}/configure`,{method:"DELETE"})).json();if(!l.success)throw new Error(l.error);e(),y()}catch(s){showNotification("Error: "+s.message,"error")}}),L?.addEventListener("click",()=>{h?.classList.add("show"),y()}),wireModal(h,A),I?.addEventListener("click",y),document.querySelector('[data-panel="health-incidents"]')?.addEventListener("click",t),document.querySelector('[data-panel="health-config"]')?.addEventListener("click",e)})(),(function(){injectModal("updates-modal",`<div id="updates-modal" class="weather-modal">
|
|
<div class="weather-modal-content" style="min-width: 750px; max-width: 950px;">
|
|
<h3>\u2B06\uFE0F Update Management</h3>
|
|
<p class="modal-subtitle">
|
|
Check for container image updates, apply them, and manage rollbacks.
|
|
</p>
|
|
|
|
<div class="panel-tabs">
|
|
<button class="panel-tab active" data-panel="updates-available">Available</button>
|
|
<button class="panel-tab" data-panel="updates-history">History</button>
|
|
<button class="panel-tab" data-panel="updates-auto">Auto-Update</button>
|
|
<button class="panel-tab" data-panel="updates-dashcaddy" id="updates-dashcaddy-tab">DashCaddy</button>
|
|
</div>
|
|
|
|
<!-- Tab: Available Updates -->
|
|
<div id="updates-available" class="panel-section active">
|
|
<div style="margin-bottom: 12px; display: flex; gap: 8px; align-items: center;">
|
|
<button id="updates-check-btn" class="btn-accent-solid">\u{1F50D} Check for Updates</button>
|
|
<button id="updates-update-all-btn" style="display: none; padding: 6px 14px; font-size: 0.82rem; background: #f97316; color: #fff; border: 1px solid #f97316; border-radius: 6px; cursor: pointer;">\u2B06\uFE0F Update All</button>
|
|
<span id="updates-count-badge" style="display: none; padding: 4px 10px; border-radius: 12px; font-size: 0.78rem; font-weight: 600; background: var(--accent); color: var(--bg);"></span>
|
|
</div>
|
|
<div id="updates-available-container" style="max-height: 450px; overflow-y: auto;">
|
|
<div class="panel-empty"><span class="empty-icon">\u{1F4E6}</span> Click "Check for Updates" to scan containers.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tab: History -->
|
|
<div id="updates-history" class="panel-section">
|
|
<div id="updates-history-container" class="scroll-container">
|
|
<div class="panel-empty"><span class="brand-spinner"></span> Loading update history...</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tab: Auto-Update -->
|
|
<div id="updates-auto" class="panel-section">
|
|
<div id="updates-auto-container" class="scroll-container">
|
|
<div class="panel-empty"><span class="empty-icon">\u{1F916}</span> Loading auto-update configuration...</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tab: DashCaddy Self-Update -->
|
|
<div id="updates-dashcaddy" class="panel-section">
|
|
<div id="dashcaddy-version-info" style="display: flex; align-items: center; gap: 16px; margin-bottom: 16px; padding: 12px; border-radius: 8px; background: var(--bg);">
|
|
<div style="flex: 1;">
|
|
<div style="font-weight: 600; font-size: 1rem;">DashCaddy</div>
|
|
<div id="dashcaddy-current-version" style="color: var(--muted); font-size: 0.85rem;">Loading...</div>
|
|
</div>
|
|
<div id="dashcaddy-update-badge" style="display: none; padding: 4px 12px; border-radius: 12px; font-size: 0.78rem; font-weight: 600; background: var(--accent); color: var(--bg);">Update available</div>
|
|
</div>
|
|
<div id="dashcaddy-update-details" style="display: none; margin-bottom: 16px; padding: 12px; border-radius: 8px; border: 1px solid var(--border);">
|
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;">
|
|
<span style="font-weight: 600;">New version: <span id="dashcaddy-new-version"></span></span>
|
|
<button id="dashcaddy-apply-btn" class="btn-accent-solid" style="padding: 6px 16px; font-size: 0.85rem;">Update Now</button>
|
|
</div>
|
|
<div id="dashcaddy-changelog" style="font-size: 0.8rem; color: var(--muted); max-height: 120px; overflow-y: auto; white-space: pre-wrap; font-family: var(--font-mono); line-height: 1.5;"></div>
|
|
</div>
|
|
<div id="dashcaddy-status-bar" style="display: none; margin-bottom: 16px; padding: 10px 12px; border-radius: 8px; font-size: 0.85rem;"></div>
|
|
<div style="margin-bottom: 12px;">
|
|
<button id="dashcaddy-check-btn" style="padding: 6px 14px; font-size: 0.82rem;">Check for Updates</button>
|
|
<button id="dashcaddy-rollback-btn" style="padding: 6px 14px; font-size: 0.82rem; margin-left: 6px;">Rollback</button>
|
|
</div>
|
|
<div id="dashcaddy-history-container" style="max-height: 250px; overflow-y: auto;">
|
|
<div class="panel-empty"><span class="empty-icon">\u{1F4E6}</span>No self-update history.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel-bottom-bar">
|
|
<span id="updates-last-check" class="text-auto-right"></span>
|
|
</div>
|
|
|
|
<div class="weather-modal-buttons modal-footer-bar">
|
|
<button id="updates-cancel">Close</button>
|
|
</div>
|
|
</div>
|
|
</div>`);const h=document.getElementById("updates-modal"),L=document.getElementById("updates-btn"),A=document.getElementById("updates-cancel"),I=document.getElementById("updates-check-btn"),D=document.getElementById("updates-available-container"),R=document.getElementById("updates-history-container"),H=document.getElementById("updates-auto-container"),P=document.getElementById("updates-last-check");async function v(){try{const t=await(await fetch("/api/v1/updates/available")).json();if(!t.success)throw new Error(t.error);const e=t.updates||[];if(e.length===0){D.innerHTML='<div class="panel-empty"><span class="empty-icon">\u2705</span>All containers are up to date.</div>',P.textContent="",document.getElementById("updates-update-all-btn").style.display="none",document.getElementById("updates-count-badge").style.display="none",window._pendingUpdates=[];return}let a='<table style="width: 100%; border-collapse: collapse; font-size: 0.85rem;">';a+='<tr style="border-bottom: 1px solid var(--border); color: var(--muted);"><th style="padding: 8px; text-align: left;">Container</th><th style="padding: 8px; text-align: left;">Image</th><th style="padding: 8px; text-align: left;">Current</th><th style="padding: 8px; text-align: left;">Latest</th><th style="padding: 8px; text-align: right;">Actions</th></tr>';for(const n of e){const s=(()=>{const l=window.APPS||[];for(const m of l)if(m.containerId===n.containerId||m.name===n.containerName||m.id===n.containerName)return m.id;return n.containerName})();a+=`<tr data-app-id="${escapeHtml(s)}" style="border-bottom: 1px solid var(--border);">`,a+=`<td style="padding: 8px; font-weight: 500;">${escapeHtml(n.containerName)}</td>`,a+=`<td style="padding: 8px; color: var(--muted);">${escapeHtml(n.imageName)}</td>`,a+=`<td style="padding: 8px;"><code style="font-size: 0.78rem; background: var(--bg); padding: 2px 6px; border-radius: 4px;">${escapeHtml(n.currentDigest)}</code></td>`,a+=`<td style="padding: 8px;"><code style="font-size: 0.78rem; background: var(--ok-bg); color: var(--ok-fg); padding: 2px 6px; border-radius: 4px;">${escapeHtml(n.latestDigest)}</code></td>`,a+='<td style="padding: 8px; text-align: right;">',a+=`<button class="update-now-btn" data-id="${escapeHtml(n.containerId)}" data-name="${escapeHtml(n.containerName)}" style="padding: 4px 10px; font-size: 0.78rem; background: var(--accent); color: var(--bg); border-color: var(--accent); margin-right: 4px;">Update</button>`,a+=`<button class="rollback-btn" data-id="${escapeHtml(n.containerId)}" data-name="${escapeHtml(n.containerName)}" style="padding: 4px 10px; font-size: 0.78rem;">Rollback</button>`,a+="</td></tr>"}a+="</table>",D.innerHTML=a,P.textContent=e.length+" update(s) available";const o=document.getElementById("updates-count-badge"),i=document.getElementById("updates-update-all-btn");o&&(o.textContent=e.length+" pending",o.style.display=""),i&&e.length>0&&(i.style.display=""),window._pendingUpdates=e,D.querySelectorAll(".update-now-btn").forEach(n=>{n.addEventListener("click",async()=>{const s=n.dataset.id,l=n.dataset.name;if(confirm(`Update "${l}" to the latest version? The container will restart.`)){n.textContent="Updating...",n.disabled=!0;try{const k=await(await secureFetch(`/api/v1/updates/update/${encodeURIComponent(s)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({autoRollback:!0})})).json();if(k.success)n.textContent="Done!",n.style.background="var(--ok-fg)",setTimeout(()=>v(),2e3);else throw new Error(k.error||"Update failed")}catch(m){n.textContent="Failed",n.style.color="var(--bad-fg)",showNotification("Update error: "+m.message,"error"),setTimeout(()=>{n.textContent="Update",n.disabled=!1,n.style.color="",n.style.background=""},3e3)}}})}),D.querySelectorAll(".rollback-btn").forEach(n=>{n.addEventListener("click",async()=>{const s=n.dataset.id,l=n.dataset.name;if(confirm(`Rollback "${l}" to its previous version?`)){n.textContent="Rolling back...",n.disabled=!0;try{const k=await(await secureFetch(`/api/v1/updates/rollback/${encodeURIComponent(s)}`,{method:"POST"})).json();if(k.success)n.textContent="Rolled back!",setTimeout(()=>v(),2e3);else throw new Error(k.error||"Rollback failed")}catch(m){n.textContent="Failed",showNotification("Rollback error: "+m.message,"error"),setTimeout(()=>{n.textContent="Rollback",n.disabled=!1},3e3)}}})})}catch(y){D.innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Failed: ${escapeHtml(y.message)}</div>`}}async function C(){const y=window._pendingUpdates||[];if(!y.length)return;const t=document.getElementById("updates-update-all-btn");if(!confirm(`Update all ${y.length} containers? Each will restart.`))return;t.textContent="\u23F3 Updating...",t.disabled=!0;let e=0,a=0;for(const o of y)try{(await(await secureFetch(`/api/v1/updates/update/${encodeURIComponent(o.containerId)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({autoRollback:!0})})).json()).success?e++:a++}catch{a++}t.textContent="\u2705 Done",showNotification(`Update all: ${e} succeeded, ${a} failed.`,e>0&&a===0?"success":"error"),setTimeout(()=>{t.textContent="\u2B06\uFE0F Update All",t.disabled=!1,v()},3e3)}document.getElementById("updates-update-all-btn")?.addEventListener("click",C);async function x(){I.textContent="\u{1F50D} Checking...",I.disabled=!0;try{const t=await(await secureFetch("/api/v1/updates/check",{method:"POST"})).json();if(!t.success)throw new Error(t.error);I.textContent="\u2705 Done!",await v()}catch(y){I.textContent="\u274C Failed",showNotification("Check error: "+y.message,"error")}setTimeout(()=>{I.textContent="\u{1F50D} Check for Updates",I.disabled=!1},3e3)}async function $(){try{R.innerHTML='<div class="panel-empty"><span class="brand-spinner"></span> Loading...</div>';const t=await(await fetch("/api/v1/updates/history?limit=50")).json(),e=t.success&&t.history?t.history:[];if(e.length===0){R.innerHTML='<div class="panel-empty"><span class="empty-icon">\u{1F4CB}</span>No update history yet.</div>';return}let a='<table style="width: 100%; border-collapse: collapse; font-size: 0.82rem;">';a+='<tr style="border-bottom: 1px solid var(--border); color: var(--muted);"><th style="padding: 6px; text-align: left;">When</th><th style="padding: 6px; text-align: left;">Container</th><th style="padding: 6px; text-align: left;">Image</th><th style="padding: 6px; text-align: left;">Duration</th><th style="padding: 6px; text-align: left;">Status</th></tr>';for(const o of e){const i=o.status==="success",n=o.duration?o.duration<1e3?o.duration+"ms":Math.round(o.duration/1e3)+"s":"-";a+='<tr style="border-bottom: 1px solid var(--border);">',a+=`<td style="padding: 6px; color: var(--muted);">${timeAgo(o.timestamp)}</td>`,a+=`<td style="padding: 6px; font-weight: 500;">${escapeHtml(o.containerName)}</td>`,a+=`<td style="padding: 6px; color: var(--muted);">${escapeHtml(o.imageName)}</td>`,a+=`<td style="padding: 6px;">${n}</td>`,a+=`<td style="padding: 6px;"><span style="color: ${i?"var(--ok-fg)":"var(--bad-fg)"};">${i?"\u2713 success":"\u2717 failed"}</span></td>`,a+="</tr>",!i&&o.error&&(a+=`<tr><td colspan="5" style="padding: 4px 6px 8px; font-size: 0.78rem; color: var(--bad-fg);">${escapeHtml(o.error)}</td></tr>`)}a+="</table>",R.innerHTML=a}catch(y){R.innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Failed: ${escapeHtml(y.message)}</div>`}}async function E(){try{H.innerHTML='<div class="panel-empty"><span class="brand-spinner"></span> Loading...</div>';const[y,t]=await Promise.all([fetch("/api/v1/stats/containers"),fetch("/api/v1/updates/auto-update")]),e=await y.json(),a=await t.json(),o=e.success&&e.stats?e.stats:[],i=a.success&&a.config?a.config:{};if(o.length===0){H.innerHTML='<div class="panel-empty"><span class="empty-icon">\u{1F916}</span>No running containers found.</div>';return}let n='<div style="margin-bottom: 12px; font-size: 0.8rem; color: var(--muted);">Auto-updates run during maintenance window (default 2AM-4AM). Daily = every day, Weekly = Sundays, Monthly = 1st of month.</div>';n+='<table style="width: 100%; border-collapse: collapse; font-size: 0.85rem;">',n+='<tr style="border-bottom: 1px solid var(--border); color: var(--muted);"><th style="padding: 8px; text-align: left;">Container</th><th style="padding: 8px; text-align: left;">Schedule</th><th style="padding: 8px; text-align: left;">Window</th><th style="padding: 8px; text-align: left;">Rollback</th><th style="padding: 8px; text-align: left;">Last Run</th><th style="padding: 8px; text-align: right;">Actions</th></tr>';for(const s of o){const l=s.name||s.Names?.[0]?.replace(/^\//,"")||s.Id?.substring(0,12),m=s.containerId||s.Id,k=i[m]||{},j=k.enabled?k.schedule||"weekly":"",_=k.autoRollback!==!1,F=k.maintenanceWindow||"",q=k.lastAutoUpdate?timeAgo(k.lastAutoUpdate):"Never";n+=`<tr style="border-bottom: 1px solid var(--border);" data-container-id="${escapeHtml(m)}">`,n+=`<td style="padding: 8px; font-weight: 500;">${escapeHtml(l)}</td>`,n+=`<td style="padding: 8px;">
|
|
<select class="auto-schedule" data-id="${escapeHtml(m)}" style="padding: 4px 8px; border-radius: 4px; border: 1px solid var(--border); background: var(--bg); color: var(--fg); font-size: 0.82rem;">
|
|
<option value=""${j?"":" selected"}>Disabled</option>
|
|
<option value="daily"${j==="daily"?" selected":""}>Daily</option>
|
|
<option value="weekly"${j==="weekly"?" selected":""}>Weekly</option>
|
|
<option value="monthly"${j==="monthly"?" selected":""}>Monthly</option>
|
|
</select></td>`,n+=`<td style="padding: 8px;"><input type="text" class="auto-window" data-id="${escapeHtml(m)}" value="${escapeHtml(F)}" placeholder="02:00-04:00" style="width: 90px; padding: 3px 6px; font-size: 0.78rem; border: 1px solid var(--border); border-radius: 4px; background: var(--bg); color: var(--fg);" /></td>`,n+=`<td style="padding: 8px;"><input type="checkbox" class="auto-rollback" data-id="${escapeHtml(m)}"${_?" checked":""} /></td>`,n+=`<td style="padding: 8px; font-size: 0.78rem; color: var(--muted);">${q}</td>`,n+=`<td style="padding: 8px; text-align: right;"><button class="save-auto-btn" data-id="${escapeHtml(m)}" data-name="${escapeHtml(l)}" style="padding: 4px 10px; font-size: 0.78rem;">Save</button></td>`,n+="</tr>"}n+="</table>",H.innerHTML=n,H.querySelectorAll(".save-auto-btn").forEach(s=>{s.addEventListener("click",async()=>{const l=s.dataset.id,m=s.closest("tr"),k=m.querySelector(".auto-schedule").value,j=m.querySelector(".auto-rollback").checked,_=m.querySelector(".auto-window").value.trim();s.textContent="Saving...",s.disabled=!0;try{const q=await(await secureFetch(`/api/v1/updates/auto-update/${encodeURIComponent(l)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({enabled:!!k,schedule:k||"weekly",autoRollback:j,maintenanceWindow:_||void 0})})).json();if(q.success)s.textContent="\u2713 Saved";else throw new Error(q.error)}catch(F){s.textContent="\u2717 Error",showNotification("Save error: "+F.message,"error")}setTimeout(()=>{s.textContent="Save",s.disabled=!1},2e3)})})}catch(y){H.innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Failed: ${escapeHtml(y.message)}</div>`}}const M=document.getElementById("dashcaddy-current-version"),S=document.getElementById("dashcaddy-update-badge"),B=document.getElementById("dashcaddy-update-details"),U=document.getElementById("dashcaddy-new-version"),T=document.getElementById("dashcaddy-changelog"),b=document.getElementById("dashcaddy-apply-btn"),N=document.getElementById("dashcaddy-check-btn"),O=document.getElementById("dashcaddy-rollback-btn"),p=document.getElementById("dashcaddy-status-bar"),u=document.getElementById("dashcaddy-history-container");let f=null;function g(y,t){p&&(p.style.display="block",p.style.background=t==="error"?"var(--bad-bg)":t==="success"?"var(--ok-bg)":"var(--bg)",p.style.color=t==="error"?"var(--bad-fg)":t==="success"?"var(--ok-fg)":"var(--fg)",p.textContent=y)}async function z(){try{const t=await(await fetch("/api/v1/system/version")).json();if(t.success){const e=t.commit&&t.commit!=="unknown"?t.commit:null;M.textContent="v"+t.version+(e?" ("+e.substring(0,7)+")":"")}}catch{M.textContent="Unable to fetch version"}}async function r(y){y||(N.textContent="Checking...",N.disabled=!0);try{const e=await(await fetch("/api/v1/system/update-check")).json();if(f=e,e.success&&e.available&&e.remote){S.style.display="",B.style.display="",U.textContent="v"+e.remote.version,T.textContent=e.remote.changelog||"No changelog available.";const a=document.getElementById("updates-btn");if(a&&!a.querySelector(".update-dot")){const i=document.createElement("span");i.className="update-dot",i.style.cssText="position:absolute;top:2px;right:2px;width:8px;height:8px;border-radius:50%;background:var(--accent);",a.style.position="relative",a.appendChild(i)}const o=document.getElementById("updates-dashcaddy-tab");if(o&&!o.querySelector(".update-dot")){const i=document.createElement("span");i.className="update-dot",i.style.cssText="display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--accent);margin-left:4px;vertical-align:middle;",o.appendChild(i)}}else S.style.display="none",B.style.display="none",await z(),y||g("You are running the latest version.","success");y||(N.textContent="Check for Updates",N.disabled=!1)}catch(t){y||(g("Failed to check: "+t.message,"error"),N.textContent="Check for Updates",N.disabled=!1)}}async function c(){if(!confirm("Apply DashCaddy update? The API container will restart."))return!1;b.textContent="Updating...",b.disabled=!0,g("Downloading and applying update...","info");try{const t=await(await secureFetch("/api/v1/system/update-apply",{method:"POST"})).json();if(t.success)return g("Update initiated: v"+(t.fromVersion||"?")+" \u2192 v"+(t.toVersion||"?")+". The container will restart shortly.","success"),b.textContent="Applied!",document.querySelectorAll(".update-dot").forEach(e=>e.remove()),!0;throw new Error(t.error||"Update failed")}catch(y){throw g("Update failed: "+y.message,"error"),b.textContent="Update Now",b.disabled=!1,y}}async function d(){try{const t=await(await fetch("/api/v1/system/update-history")).json(),e=t.success&&t.history?t.history:[];if(e.length===0){u.innerHTML='<div class="panel-empty"><span class="empty-icon">\u{1F4E6}</span>No self-update history.</div>';return}let a='<table style="width: 100%; border-collapse: collapse; font-size: 0.82rem;">';a+='<tr style="border-bottom: 1px solid var(--border); color: var(--muted);"><th style="padding: 6px; text-align: left;">When</th><th style="padding: 6px; text-align: left;">Version</th><th style="padding: 6px; text-align: left;">From</th><th style="padding: 6px; text-align: left;">Status</th></tr>';for(const o of e){const i=o.status==="success"?"\u2713 success":o.status==="pending"?"\u23F3 pending":o.status==="partial"?"\u26A0 partial":"\u2717 "+o.status,n=o.status==="success"?"var(--ok-fg)":o.status==="pending"?"var(--muted)":"var(--bad-fg)";a+='<tr style="border-bottom: 1px solid var(--border);">',a+='<td style="padding: 6px; color: var(--muted);">'+timeAgo(o.timestamp)+"</td>",a+='<td style="padding: 6px; font-weight: 500;">v'+escapeHtml(o.version)+(o.rollback?" (rollback)":"")+"</td>",a+='<td style="padding: 6px; color: var(--muted);">v'+escapeHtml(o.fromVersion||"?")+"</td>",a+='<td style="padding: 6px;"><span style="color: '+n+';">'+i+"</span></td>",a+="</tr>",o.error&&(a+='<tr><td colspan="4" style="padding: 4px 6px 8px; font-size: 0.78rem; color: var(--bad-fg);">'+escapeHtml(o.error)+"</td></tr>"),o.note&&(a+='<tr><td colspan="4" style="padding: 4px 6px 8px; font-size: 0.78rem; color: var(--muted);">'+escapeHtml(o.note)+"</td></tr>")}a+="</table>",u.innerHTML=a}catch(y){u.innerHTML='<div class="panel-empty" style="color: var(--bad-fg);">Failed: '+escapeHtml(y.message)+"</div>"}}async function w(){try{const t=await(await fetch("/api/v1/system/rollback-versions")).json(),e=t.success&&t.versions?t.versions:[];if(e.length===0){showNotification("No rollback versions available.","info");return}const a=prompt(`Available rollback versions:
|
|
`+e.join(`
|
|
`)+`
|
|
|
|
Enter version to rollback to:`);if(!a)return;if(!e.includes(a)){showNotification("Invalid version: "+a,"error");return}if(!confirm("Rollback DashCaddy to v"+a+"? The container will restart."))return;g("Rolling back to v"+a+"...","info");const i=await(await secureFetch("/api/v1/system/rollback",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({version:a})})).json();if(i.success)g("Rollback to v"+a+" initiated. Container will restart.","success");else throw new Error(i.error||"Rollback failed")}catch(y){g("Rollback failed: "+y.message,"error")}}N?.addEventListener("click",()=>r(!1)),b?.addEventListener("click",()=>c().catch(()=>{})),O?.addEventListener("click",w),I?.addEventListener("click",x),L?.addEventListener("click",()=>{h?.classList.add("show"),v()}),wireModal(h,A),window.openUpdateModal=function(y){h?.classList.add("show"),v().then(()=>{if(!y)return;const t=D.querySelector(`[data-app-id="${y}"]`);t&&(t.scrollIntoView({behavior:"smooth",block:"center"}),t.style.background="rgba(249,115,22,0.15)",setTimeout(()=>{t.style.background=""},3e3))})},document.querySelector('[data-panel="updates-history"]')?.addEventListener("click",$),document.querySelector('[data-panel="updates-auto"]')?.addEventListener("click",E),document.querySelector('[data-panel="updates-dashcaddy"]')?.addEventListener("click",()=>{z(),d(),f||r(!0)}),window.dcApplyUpdate=c,window.dcCheckForUpdate=r,setTimeout(()=>r(!0),5e3)})(),(function(){injectModal("docker-resources-modal",`<div id="docker-resources-modal" class="weather-modal">
|
|
<div class="weather-modal-content" style="min-width: 750px; max-width: 950px;">
|
|
<h3>\u{1F433} Docker Resources</h3>
|
|
<p class="modal-subtitle">Manage volumes, networks, and view disk usage.</p>
|
|
|
|
<div class="panel-tabs">
|
|
<button class="panel-tab active" data-panel="dr-volumes">Volumes</button>
|
|
<button class="panel-tab" data-panel="dr-networks">Networks</button>
|
|
<button class="panel-tab" data-panel="dr-disk">Disk Usage</button>
|
|
</div>
|
|
|
|
<!-- Volumes -->
|
|
<div id="dr-volumes" class="panel-section active">
|
|
<div style="display: flex; gap: 8px; margin-bottom: 12px;">
|
|
<input type="text" id="dr-vol-name" placeholder="Volume name" style="flex: 1; padding: 6px 10px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg); color: var(--fg);" />
|
|
<button id="dr-vol-create" class="btn-accent-solid" style="padding: 6px 14px; font-size: 0.82rem;">Create</button>
|
|
</div>
|
|
<div id="dr-vol-list" class="scroll-container" style="max-height: 400px;">
|
|
<div class="panel-empty"><span class="brand-spinner"></span> Loading...</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Networks -->
|
|
<div id="dr-networks" class="panel-section">
|
|
<div style="display: flex; gap: 8px; margin-bottom: 12px;">
|
|
<input type="text" id="dr-net-name" placeholder="Network name" style="flex: 1; padding: 6px 10px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg); color: var(--fg);" />
|
|
<select id="dr-net-driver" style="padding: 6px 10px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg); color: var(--fg);">
|
|
<option value="bridge">bridge</option>
|
|
<option value="overlay">overlay</option>
|
|
<option value="host">host</option>
|
|
</select>
|
|
<button id="dr-net-create" class="btn-accent-solid" style="padding: 6px 14px; font-size: 0.82rem;">Create</button>
|
|
</div>
|
|
<div id="dr-net-list" class="scroll-container" style="max-height: 400px;">
|
|
<div class="panel-empty"><span class="brand-spinner"></span> Loading...</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Disk Usage -->
|
|
<div id="dr-disk" class="panel-section">
|
|
<div id="dr-disk-content">
|
|
<div class="panel-empty"><span class="brand-spinner"></span> Loading...</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="weather-modal-buttons modal-footer-bar">
|
|
<button id="dr-close">Close</button>
|
|
</div>
|
|
</div>
|
|
</div>`);const h=document.getElementById("docker-resources-modal"),L=document.getElementById("docker-resources-btn"),A=document.getElementById("dr-close");function I(P){if(!P||P===0)return"0 B";const v=["B","KB","MB","GB","TB"],C=Math.floor(Math.log(Math.abs(P))/Math.log(1024));return(P/Math.pow(1024,C)).toFixed(1)+" "+v[C]}async function D(){const P=document.getElementById("dr-vol-list");try{const C=(await getJSON("/api/v1/docker/volumes")).volumes||[];if(C.length===0){P.innerHTML='<div class="panel-empty"><span class="empty-icon">\u{1F4E6}</span>No volumes found.</div>';return}let x='<table style="width: 100%; border-collapse: collapse; font-size: 0.82rem;">';x+='<tr style="border-bottom: 1px solid var(--border); color: var(--muted);"><th style="padding: 6px; text-align: left;">Name</th><th style="padding: 6px;">Driver</th><th style="padding: 6px;">Scope</th><th style="padding: 6px; text-align: right;">Actions</th></tr>';for(const $ of C){const E=$.name==="buildkit"||$.name.length===64;x+='<tr style="border-bottom: 1px solid var(--border);">',x+=`<td style="padding: 6px; font-weight: 500; max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;" title="${escapeHtml($.name)}">${escapeHtml($.name.length>40?$.name.substring(0,37)+"...":$.name)}</td>`,x+=`<td style="padding: 6px; text-align: center; color: var(--muted);">${escapeHtml($.driver)}</td>`,x+=`<td style="padding: 6px; text-align: center; color: var(--muted);">${escapeHtml($.scope)}</td>`,x+='<td style="padding: 6px; text-align: right;">',E||(x+=`<button class="dr-vol-del" data-name="${escapeHtml($.name)}" style="padding: 3px 8px; font-size: 0.75rem; color: var(--bad-fg);">Delete</button>`),x+="</td></tr>"}x+="</table>",P.innerHTML=x,P.querySelectorAll(".dr-vol-del").forEach($=>{$.addEventListener("click",async()=>{if(confirm(`Delete volume "${$.dataset.name}"? Data will be lost.`)){$.textContent="...",$.disabled=!0;try{await deleteAPI(`/api/v1/docker/volumes/${encodeURIComponent($.dataset.name)}?force=true`),D()}catch(E){showNotification("Delete failed: "+E.message,"error"),$.textContent="Delete",$.disabled=!1}}})})}catch(v){P.innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Failed: ${escapeHtml(v.message)}</div>`}}document.getElementById("dr-vol-create")?.addEventListener("click",async()=>{const P=document.getElementById("dr-vol-name"),v=P.value.trim();if(!v){showNotification("Enter a volume name","warning");return}try{await postJSON("/api/v1/docker/volumes",{name:v}),P.value="",showNotification(`Volume "${v}" created`,"success"),D()}catch(C){showNotification("Create failed: "+C.message,"error")}});async function R(){const P=document.getElementById("dr-net-list");try{const C=(await getJSON("/api/v1/docker/networks")).networks||[];if(C.length===0){P.innerHTML='<div class="panel-empty"><span class="empty-icon">\u{1F310}</span>No networks found.</div>';return}let x='<table style="width: 100%; border-collapse: collapse; font-size: 0.82rem;">';x+='<tr style="border-bottom: 1px solid var(--border); color: var(--muted);"><th style="padding: 6px; text-align: left;">Name</th><th style="padding: 6px;">Driver</th><th style="padding: 6px;">Scope</th><th style="padding: 6px;">Containers</th><th style="padding: 6px; text-align: right;">Actions</th></tr>';for(const $ of C){const E=["bridge","host","none"].includes($.name);x+='<tr style="border-bottom: 1px solid var(--border);">',x+=`<td style="padding: 6px; font-weight: 500;">${escapeHtml($.name)}</td>`,x+=`<td style="padding: 6px; text-align: center; color: var(--muted);">${escapeHtml($.driver)}</td>`,x+=`<td style="padding: 6px; text-align: center; color: var(--muted);">${escapeHtml($.scope)}</td>`,x+=`<td style="padding: 6px; text-align: center;">${$.containers}</td>`,x+='<td style="padding: 6px; text-align: right;">',E||(x+=`<button class="dr-net-del" data-id="${escapeHtml($.id)}" data-name="${escapeHtml($.name)}" style="padding: 3px 8px; font-size: 0.75rem; color: var(--bad-fg);">Delete</button>`),x+="</td></tr>"}x+="</table>",P.innerHTML=x,P.querySelectorAll(".dr-net-del").forEach($=>{$.addEventListener("click",async()=>{if(confirm(`Delete network "${$.dataset.name}"?`)){$.textContent="...",$.disabled=!0;try{await deleteAPI(`/api/v1/docker/networks/${encodeURIComponent($.dataset.id)}`),R()}catch(E){showNotification("Delete failed: "+E.message,"error"),$.textContent="Delete",$.disabled=!1}}})})}catch(v){P.innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Failed: ${escapeHtml(v.message)}</div>`}}document.getElementById("dr-net-create")?.addEventListener("click",async()=>{const P=document.getElementById("dr-net-name"),v=document.getElementById("dr-net-driver"),C=P.value.trim();if(!C){showNotification("Enter a network name","warning");return}try{await postJSON("/api/v1/docker/networks",{name:C,driver:v.value}),P.value="",showNotification(`Network "${C}" created`,"success"),R()}catch(x){showNotification("Create failed: "+x.message,"error")}});async function H(){const P=document.getElementById("dr-disk-content");try{const v=await getJSON("/api/v1/docker/disk-usage"),C=[{label:"Images",icon:"\u{1F4C0}",count:v.images.count,size:v.images.size,reclaimable:v.images.reclaimable},{label:"Containers",icon:"\u{1F4E6}",count:v.containers.count,size:v.containers.size,extra:`${v.containers.running} running`},{label:"Volumes",icon:"\u{1F4BE}",count:v.volumes.count,size:v.volumes.size,reclaimable:v.volumes.reclaimable},{label:"Build Cache",icon:"\u{1F527}",count:v.buildCache.count,size:v.buildCache.size,reclaimable:v.buildCache.reclaimable}];let x=`<div style="font-size: 1.1rem; font-weight: 600; margin-bottom: 16px;">Total: ${I(v.totalSize)}</div>`;x+='<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px;">';for(const $ of C)x+='<div style="padding: 14px; background: var(--bg); border-radius: 8px; border: 1px solid var(--border);">',x+=`<div style="font-weight: 600; margin-bottom: 6px;">${$.icon} ${$.label} <span style="color: var(--muted); font-weight: 400; font-size: 0.82rem;">(${$.count})</span></div>`,x+=`<div style="font-size: 1.1rem; font-weight: 600; color: var(--accent);">${I($.size)}</div>`,$.reclaimable>0&&(x+=`<div style="font-size: 0.78rem; color: var(--muted);">Reclaimable: ${I($.reclaimable)}</div>`),$.extra&&(x+=`<div style="font-size: 0.78rem; color: var(--muted);">${$.extra}</div>`),x+="</div>";x+="</div>",P.innerHTML=x}catch(v){P.innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Failed: ${escapeHtml(v.message)}</div>`}}L?.addEventListener("click",()=>{h?.classList.add("show"),D()}),wireModal(h,A),document.querySelector('[data-panel="dr-networks"]')?.addEventListener("click",R),document.querySelector('[data-panel="dr-disk"]')?.addEventListener("click",H)})(),(function(){injectModal("compose-import-modal",`<div id="compose-import-modal" class="weather-modal">
|
|
<div class="weather-modal-content" style="min-width: 650px; max-width: 800px;">
|
|
<h3>\u{1F4E6} Import Docker Compose</h3>
|
|
<p class="modal-subtitle">Paste a docker-compose.yml to import and deploy services.</p>
|
|
|
|
<!-- Step 1: Paste YAML -->
|
|
<div id="compose-step-paste">
|
|
<div style="margin-bottom: 12px;">
|
|
<label class="form-label-accent-sm">Stack Name</label>
|
|
<input type="text" id="compose-stack-name" placeholder="my-stack" value="" style="width: 100%; padding: 8px 10px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg); color: var(--fg);" />
|
|
</div>
|
|
<div style="margin-bottom: 12px;">
|
|
<label class="form-label-accent-sm">docker-compose.yml</label>
|
|
<textarea id="compose-yaml" rows="14" placeholder="version: '3' services: web: image: nginx:latest ports: - '8080:80'" style="width: 100%; padding: 10px; font-family: monospace; font-size: 0.82rem; border: 1px solid var(--border); border-radius: 6px; background: var(--bg); color: var(--fg); resize: vertical;"></textarea>
|
|
<div style="margin-top: 6px;">
|
|
<label style="display: inline-flex; align-items: center; gap: 6px; cursor: pointer; font-size: 0.82rem; color: var(--muted);">
|
|
<input type="file" id="compose-file-upload" accept=".yml,.yaml" style="display: none;" />
|
|
<span style="text-decoration: underline;">or upload a file</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="weather-modal-buttons modal-footer-bar">
|
|
<button id="compose-parse-btn" class="btn-accent-solid" style="padding: 8px 20px;">Parse & Preview</button>
|
|
<button id="compose-cancel">Cancel</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Step 2: Preview -->
|
|
<div id="compose-step-preview" style="display: none;">
|
|
<div id="compose-preview-content"></div>
|
|
<div class="weather-modal-buttons modal-footer-bar" style="margin-top: 16px;">
|
|
<button id="compose-deploy-btn" class="btn-accent-solid" style="padding: 8px 20px;">Deploy All</button>
|
|
<button id="compose-back-btn">Back</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Step 3: Progress -->
|
|
<div id="compose-step-progress" style="display: none;">
|
|
<div id="compose-progress-content"></div>
|
|
</div>
|
|
</div>
|
|
</div>`);const h=document.getElementById("compose-import-modal"),L=document.getElementById("compose-import-btn"),A=document.getElementById("compose-cancel");wireModal(h,A);let I=null;function D(H){document.getElementById("compose-step-paste").style.display=H==="paste"?"":"none",document.getElementById("compose-step-preview").style.display=H==="preview"?"":"none",document.getElementById("compose-step-progress").style.display=H==="progress"?"":"none"}L?.addEventListener("click",()=>{D("paste"),I=null,document.getElementById("compose-yaml").value="",document.getElementById("compose-stack-name").value="",h?.classList.add("show")}),document.getElementById("compose-file-upload")?.addEventListener("change",H=>{const P=H.target.files[0];if(!P)return;const v=new FileReader;v.onload=()=>{document.getElementById("compose-yaml").value=v.result},v.readAsText(P)}),document.getElementById("compose-parse-btn")?.addEventListener("click",async()=>{const H=document.getElementById("compose-yaml").value.trim(),P=document.getElementById("compose-stack-name").value.trim()||"stack";if(!H){showNotification("Paste a docker-compose.yml","warning");return}const v=document.getElementById("compose-parse-btn"),C=v.textContent;v.textContent="Parsing...",v.disabled=!0;try{const x=await postJSON("/api/v1/apps/import-compose",{yaml:H,stackName:P});I=x,I.stackName=P,R(x),D("preview")}catch(x){showNotification("Parse failed: "+x.message,"error")}finally{v.textContent=C,v.disabled=!1}});function R(H){const P=document.getElementById("compose-preview-content");let v="";H.networks&&H.networks.length>0&&(v+=`<div style="margin-bottom: 12px; font-size: 0.82rem; color: var(--muted);">Networks: ${H.networks.map(C=>`<code>${escapeHtml(C)}</code>`).join(", ")}</div>`),H.volumes&&H.volumes.length>0&&(v+=`<div style="margin-bottom: 12px; font-size: 0.82rem; color: var(--muted);">Volumes: ${H.volumes.map(C=>`<code>${escapeHtml(C)}</code>`).join(", ")}</div>`),v+=`<div style="font-weight: 600; margin-bottom: 8px;">${H.services.length} service(s)</div>`,v+='<div class="scroll-container" style="max-height: 350px;">';for(const C of H.services){const x=C.skip?"var(--bad-fg)":"var(--border)";if(v+=`<div style="padding: 10px 14px; border: 1px solid ${x}; border-radius: 8px; margin-bottom: 8px; background: var(--bg);">`,v+=`<div style="font-weight: 600; font-size: 0.9rem;">${escapeHtml(C.name)}`,C.skip&&(v+=` <span style="color: var(--bad-fg); font-weight: 400; font-size: 0.78rem;">\u2014 skipped: ${escapeHtml(C.reason)}</span>`),v+="</div>",!C.skip&&(v+=`<div style="font-size: 0.8rem; color: var(--muted); margin-top: 4px;">Image: <code>${escapeHtml(C.image)}</code></div>`,C.ports?.length&&(v+=`<div style="font-size: 0.8rem; color: var(--muted);">Ports: ${C.ports.map($=>`${$.host}:${$.container}`).join(", ")}</div>`),C.volumes?.length&&(v+=`<div style="font-size: 0.8rem; color: var(--muted);">Volumes: ${C.volumes.length}</div>`),Object.keys(C.environment||{}).length&&(v+=`<div style="font-size: 0.8rem; color: var(--muted);">Env vars: ${Object.keys(C.environment).length}</div>`),C.envFileWarning&&(v+=`<div style="font-size: 0.78rem; color: var(--bad-fg);">\u26A0 ${escapeHtml(C.envFileWarning)}</div>`),C.resources?.cpus||C.resources?.memory)){const $=[];C.resources.cpus&&$.push(`CPU: ${C.resources.cpus}`),C.resources.memory&&$.push(`Mem: ${C.resources.memory}MB`),v+=`<div style="font-size: 0.8rem; color: var(--muted);">Limits: ${$.join(", ")}</div>`}v+="</div>"}v+="</div>",P.innerHTML=v}document.getElementById("compose-back-btn")?.addEventListener("click",()=>D("paste")),document.getElementById("compose-deploy-btn")?.addEventListener("click",async()=>{if(!I)return;const H=document.getElementById("compose-deploy-btn");H.textContent="Deploying...",H.disabled=!0,D("progress");const P=document.getElementById("compose-progress-content");P.innerHTML='<div class="panel-empty"><span class="brand-spinner"></span> Deploying services...</div>';try{const v=await postJSON("/api/v1/apps/deploy-compose",{services:I.services,networks:I.networks,stackName:I.stackName});let C=`<div style="font-weight: 600; margin-bottom: 12px;">Stack "${escapeHtml(v.stackName)}" \u2014 Deployment Complete</div>`;C+='<div class="scroll-container" style="max-height: 350px;">';for(const x of v.results){const $=x.status==="deployed"||x.status==="created"?"\u2705":x.status==="exists"?"\u26A1":x.status==="skipped"?"\u23ED":"\u274C";C+='<div style="padding: 8px 12px; border-bottom: 1px solid var(--border); font-size: 0.85rem;">',C+=`${$} <strong>${escapeHtml(x.name)}</strong> (${x.type}) \u2014 ${escapeHtml(x.status)}`,x.error&&(C+=` <span style="color: var(--bad-fg);">${escapeHtml(x.error)}</span>`),x.subdomain&&(C+=` \u2192 <code>${escapeHtml(x.subdomain)}</code>`),x.reason&&(C+=` <span style="color: var(--muted);">(${escapeHtml(x.reason)})</span>`),C+="</div>"}C+="</div>",C+='<div class="weather-modal-buttons modal-footer-bar" style="margin-top: 16px;"><button id="compose-done-btn">Done</button></div>',P.innerHTML=C,document.getElementById("compose-done-btn")?.addEventListener("click",()=>{h?.classList.remove("show"),typeof window.loadServices=="function"&&window.loadServices().then(()=>{typeof window.buildGrid=="function"&&window.buildGrid()})}),showNotification(`Stack "${v.stackName}" deployed`,"success")}catch(v){P.innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Deployment failed: ${escapeHtml(v.message)}</div>
|
|
<div class="weather-modal-buttons modal-footer-bar" style="margin-top: 16px;"><button id="compose-retry-btn">Back</button></div>`,document.getElementById("compose-retry-btn")?.addEventListener("click",()=>D("paste"))}finally{H.textContent="Deploy All",H.disabled=!1}})})(),(function(){injectModal("exec-modal",`<div id="exec-modal" class="weather-modal">
|
|
<div class="weather-modal-content" style="min-width: 700px; max-width: 900px; padding-bottom: 0;">
|
|
<h3 id="exec-title">Terminal</h3>
|
|
<div id="exec-terminal" style="height: 420px; border-radius: 6px; overflow: hidden; background: #1e1e1e;"></div>
|
|
<div class="weather-modal-buttons modal-footer-bar" style="margin-top: 8px; padding-bottom: 12px;">
|
|
<button id="exec-close">Close</button>
|
|
</div>
|
|
</div>
|
|
</div>`);const h=document.getElementById("exec-modal"),L=document.getElementById("exec-terminal"),A=document.getElementById("exec-close");let I=null,D=null,R=null;function H(){if(D){try{D.close()}catch{}D=null}if(I){try{I.dispose()}catch{}I=null}R=null,L.innerHTML=""}function P(v,C){if(H(),document.getElementById("exec-title").textContent=`Terminal \u2014 ${C||v}`,h?.classList.add("show"),typeof Terminal>"u"){L.innerHTML='<div style="color: #f44; padding: 20px; font-family: monospace;">xterm.js not loaded</div>';return}I=new Terminal({cursorBlink:!0,fontSize:14,fontFamily:"'Cascadia Code', 'Fira Code', 'Consolas', monospace",theme:{background:"#1e1e1e",foreground:"#d4d4d4",cursor:"#aeafad",selectionBackground:"#264f78"},scrollback:5e3}),typeof FitAddon<"u"&&(R=new FitAddon.FitAddon,I.loadAddon(R)),I.open(L),R&&setTimeout(()=>R.fit(),50);const x=location.protocol==="https:"?"wss:":"ws:";D=new WebSocket(`${x}//${location.host}/ws/exec/${encodeURIComponent(v)}`),D.binaryType="arraybuffer",D.onopen=()=>{if(I.writeln("\x1B[32mConnecting...\x1B[0m"),R){const E=R.proposeDimensions();E&&D.send(JSON.stringify({type:"resize",cols:E.cols,rows:E.rows}))}},D.onmessage=E=>{if(typeof E.data=="string"){try{const M=JSON.parse(E.data);if(M.type==="connected"){I.writeln(`\x1B[32mConnected (${M.shell})\x1B[0m\r
|
|
`);return}if(M.type==="error"){I.writeln(`\x1B[31mError: ${M.message}\x1B[0m`);return}if(M.type==="exit"){I.writeln(`\r
|
|
\x1B[33mSession ended.\x1B[0m`);return}}catch{}I.write(E.data)}else I.write(new Uint8Array(E.data))},D.onclose=()=>{I&&I.writeln(`\r
|
|
\x1B[33mDisconnected.\x1B[0m`)},D.onerror=()=>{I&&I.writeln(`\r
|
|
\x1B[31mConnection error.\x1B[0m`)},I.onData(E=>{D&&D.readyState===WebSocket.OPEN&&D.send(E)}),I.onResize(({cols:E,rows:M})=>{D&&D.readyState===WebSocket.OPEN&&D.send(JSON.stringify({type:"resize",cols:E,rows:M}))});const $=()=>{R&&R.fit()};window.addEventListener("resize",$),h._resizeHandler=$}A?.addEventListener("click",()=>{H(),h._resizeHandler&&window.removeEventListener("resize",h._resizeHandler),h?.classList.remove("show")}),h?.addEventListener("click",v=>{v.target===h&&(H(),h._resizeHandler&&window.removeEventListener("resize",h._resizeHandler),h?.classList.remove("show"))}),window.openExecModal=P})(),(function(){injectModal("audit-modal",`<div id="audit-modal" class="weather-modal">
|
|
<div class="weather-modal-content" style="min-width: 850px; max-width: 1050px;">
|
|
<h3>\u{1F4DC} Audit Log</h3>
|
|
<p class="modal-subtitle">
|
|
Track all actions performed through the API.
|
|
</p>
|
|
|
|
<div style="display: flex; gap: 12px; margin-bottom: 16px; align-items: center;">
|
|
<label class="text-muted-sm">Filter:</label>
|
|
<select id="audit-filter" style="padding: 6px 10px; border-radius: 6px; border: 1px solid var(--border); background: var(--bg); color: var(--fg); font-size: 0.85rem;">
|
|
<option value="">All Actions</option>
|
|
<option value="service">Services</option>
|
|
<option value="container">Containers</option>
|
|
<option value="caddy">Caddy</option>
|
|
<option value="dns">DNS</option>
|
|
<option value="backup">Backups</option>
|
|
<option value="config">Config</option>
|
|
<option value="auth">Auth</option>
|
|
</select>
|
|
<button id="audit-refresh-btn" class="btn-sm">\u{1F504} Refresh</button>
|
|
<span style="flex: 1;"></span>
|
|
<button id="audit-clear-btn" style="padding: 6px 12px; font-size: 0.8rem; color: var(--bad-fg); border-color: var(--bad-fg);">\u{1F5D1}\uFE0F Clear Log</button>
|
|
</div>
|
|
|
|
<div id="audit-log-container" class="scroll-container">
|
|
<div class="panel-empty"><span class="brand-spinner"></span> Loading audit log...</div>
|
|
</div>
|
|
|
|
<div style="margin-top: 12px; text-align: center;">
|
|
<button id="audit-load-more" style="display: none; padding: 6px 16px; font-size: 0.8rem;">Load More</button>
|
|
</div>
|
|
|
|
<div class="weather-modal-buttons modal-footer-bar">
|
|
<button id="audit-cancel">Close</button>
|
|
</div>
|
|
</div>
|
|
</div>`);const h=document.getElementById("audit-modal"),L=document.getElementById("audit-log-btn"),A=document.getElementById("audit-cancel"),I=document.getElementById("audit-refresh-btn"),D=document.getElementById("audit-clear-btn"),R=document.getElementById("audit-filter"),H=document.getElementById("audit-log-container"),P=document.getElementById("audit-load-more");let v=0;const C=50;async function x($){try{$||(v=0,H.innerHTML='<div class="panel-empty"><span class="brand-spinner"></span> Loading...</div>');const E=R.value;let M=`/api/v1/audit-logs?limit=${C}&offset=${v}`;E&&(M+=`&action=${encodeURIComponent(E)}`);const B=await(await fetch(M)).json(),U=B.success&&B.entries?B.entries:[];if(U.length===0&&!$){H.innerHTML='<div class="panel-empty"><span class="empty-icon">\u{1F4DC}</span>No audit log entries yet. Actions will be logged automatically.</div>',P.style.display="none";return}let T="";$||(T='<table style="width: 100%; border-collapse: collapse; font-size: 0.82rem;">',T+='<tr style="border-bottom: 1px solid var(--border); color: var(--muted);"><th style="padding: 6px; text-align: left;">When</th><th style="padding: 6px; text-align: left;">IP</th><th style="padding: 6px; text-align: left;">Action</th><th style="padding: 6px; text-align: left;">Resource</th><th style="padding: 6px; text-align: left;">Result</th></tr>');for(const b of U){const N=b.outcome==="success";T+='<tr style="border-bottom: 1px solid var(--border); cursor: pointer;" class="audit-row">',T+=`<td style="padding: 6px; color: var(--muted);">${timeAgo(b.timestamp)}</td>`,T+=`<td style="padding: 6px; font-family: monospace; font-size: 0.78rem;">${escapeHtml(b.ip||"-")}</td>`,T+=`<td style="padding: 6px; font-weight: 500;">${escapeHtml(b.action||"-")}</td>`,T+=`<td style="padding: 6px;">${escapeHtml(b.resource||"-")}</td>`,T+=`<td style="padding: 6px;"><span style="color: ${N?"var(--ok-fg)":"var(--bad-fg)"};">${N?"\u2713":"\u2717"}</span></td>`,T+="</tr>",b.details&&Object.keys(b.details).length>0&&(T+=`<tr class="audit-detail" style="display: none;"><td colspan="5" style="padding: 6px 6px 10px; font-size: 0.78rem; color: var(--muted);"><pre style="margin: 0; white-space: pre-wrap; font-family: monospace;">${escapeHtml(JSON.stringify(b.details,null,2))}</pre></td></tr>`)}if(!$)T+="</table>",H.innerHTML=T;else{const b=H.querySelector("table");b&&b.insertAdjacentHTML("beforeend",T)}v+=U.length,P.style.display=U.length>=C?"":"none",H.querySelectorAll(".audit-row").forEach(b=>{b.dataset.wired||(b.dataset.wired="true",b.addEventListener("click",()=>{const N=b.nextElementSibling;N&&N.classList.contains("audit-detail")&&(N.style.display=N.style.display==="none"?"":"none")}))})}catch(E){H.innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Failed: ${escapeHtml(E.message)}</div>`}}L?.addEventListener("click",()=>{h?.classList.add("show"),x(!1)}),wireModal(h,A),I?.addEventListener("click",()=>x(!1)),R?.addEventListener("change",()=>x(!1)),P?.addEventListener("click",()=>x(!0)),D?.addEventListener("click",async()=>{if(confirm("Clear the entire audit log? This cannot be undone."))try{const E=await(await secureFetch("/api/v1/audit-logs",{method:"DELETE"})).json();E.success?x(!1):showNotification("Error: "+(E.error||"Clear failed"),"error")}catch($){showNotification("Error: "+$.message,"error")}})})(),(function(){injectModal("security-modal",`<div id="security-modal" class="weather-modal">
|
|
<div class="weather-modal-content" style="min-width: 980px; max-width: 1280px;">
|
|
<h3>\u{1F6E1}\uFE0F Security Center</h3>
|
|
<p class="modal-subtitle">
|
|
Live events from API, Caddy, fail2ban & shared_bans. Live-tail via SSE.
|
|
</p>
|
|
|
|
<div class="sec-tabs" style="display:flex;gap:8px;margin-bottom:14px;border-bottom:1px solid var(--border);">
|
|
<button class="sec-tab active" data-tab="overview">Overview</button>
|
|
<button class="sec-tab" data-tab="events">Events</button>
|
|
<button class="sec-tab" data-tab="hosts">Hosts</button>
|
|
</div>
|
|
|
|
<!-- OVERVIEW TAB -->
|
|
<div class="sec-panel" data-panel="overview">
|
|
<div class="sec-stats" id="sec-stats" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;margin-bottom:18px;">
|
|
<div class="sec-stat" data-key="total">\u2014 events</div>
|
|
<div class="sec-stat" data-key="warn">\u2014 warnings</div>
|
|
<div class="sec-stat" data-key="error">\u2014 errors</div>
|
|
<div class="sec-stat" data-key="denied">\u2014 denied</div>
|
|
<div class="sec-stat" data-key="hosts">\u2014 hosts</div>
|
|
</div>
|
|
<div style="display:grid;grid-template-columns:1fr 1fr;gap:14px;">
|
|
<div>
|
|
<h4 style="margin:8px 0 6px;">Top Actors (24h)</h4>
|
|
<div id="sec-top-actors" class="scroll-container" style="max-height:240px;">\u2014</div>
|
|
</div>
|
|
<div>
|
|
<h4 style="margin:8px 0 6px;">Top Targets (24h)</h4>
|
|
<div id="sec-top-targets" class="scroll-container" style="max-height:240px;">\u2014</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- EVENTS TAB -->
|
|
<div class="sec-panel" data-panel="events" style="display:none;">
|
|
<div style="display:flex;gap:8px;margin-bottom:12px;align-items:center;flex-wrap:wrap;">
|
|
<select id="sec-filter-source" class="sec-filter">
|
|
<option value="">All sources</option>
|
|
<option value="api">API</option>
|
|
<option value="caddy">Caddy</option>
|
|
<option value="fail2ban">fail2ban</option>
|
|
<option value="shared-bans">shared_bans</option>
|
|
<option value="agent">Agent</option>
|
|
</select>
|
|
<select id="sec-filter-severity" class="sec-filter">
|
|
<option value="">All severities</option>
|
|
<option value="critical">critical</option>
|
|
<option value="error">error</option>
|
|
<option value="warn">warn</option>
|
|
<option value="notice">notice</option>
|
|
<option value="info">info</option>
|
|
</select>
|
|
<select id="sec-filter-host" class="sec-filter">
|
|
<option value="">All hosts</option>
|
|
</select>
|
|
<input id="sec-filter-actor" class="sec-filter" placeholder="actor (IP or user)" style="padding:6px 10px;">
|
|
<button id="sec-refresh-btn" class="btn-sm">\u{1F504} Refresh</button>
|
|
<label style="margin-left:auto;display:flex;align-items:center;gap:6px;">
|
|
<input type="checkbox" id="sec-live-tail" checked>
|
|
<span>Live tail</span>
|
|
</label>
|
|
</div>
|
|
<div id="sec-events-container" class="scroll-container" style="max-height:480px;">Loading\u2026</div>
|
|
</div>
|
|
|
|
<!-- HOSTS TAB -->
|
|
<div class="sec-panel" data-panel="hosts" style="display:none;">
|
|
<div style="display:flex;gap:8px;margin-bottom:12px;">
|
|
<button id="sec-host-register-btn" class="btn-sm">\u2795 Register Host</button>
|
|
<button id="sec-hosts-refresh" class="btn-sm">\u{1F504} Refresh</button>
|
|
</div>
|
|
<div id="sec-hosts-container" class="scroll-container" style="max-height:480px;">Loading\u2026</div>
|
|
</div>
|
|
|
|
<div class="weather-modal-buttons modal-footer-bar">
|
|
<button id="sec-cancel">Close</button>
|
|
</div>
|
|
</div>
|
|
</div>`);const h=document.getElementById("security-modal"),L=document.getElementById("security-center-btn"),A=document.getElementById("sec-cancel"),I=h.querySelectorAll(".sec-tab"),D=h.querySelectorAll(".sec-panel");let R=[],H=[],P=null;I.forEach(r=>{r.addEventListener("click",()=>{I.forEach(c=>c.classList.toggle("active",c===r)),D.forEach(c=>c.style.display=c.dataset.panel===r.dataset.tab?"":"none"),r.dataset.tab==="overview"&&$(),r.dataset.tab==="events"&&b(),r.dataset.tab==="hosts"&&u()})}),L&&L.addEventListener("click",()=>{h.classList.add("show"),$(),C()}),A.addEventListener("click",v),h.addEventListener("click",r=>{r.target===h&&v()});function v(){h.classList.remove("show"),x()}function C(){if(x(),!!document.getElementById("sec-live-tail").checked&&!(typeof EventSource>"u"))try{P=new EventSource("/api/v1/security/events/stream"),P.addEventListener("init",r=>{try{R=JSON.parse(r.data).events||[],N()}catch{}}),P.addEventListener("security",r=>{try{const c=JSON.parse(r.data);R.unshift(c),R.length>500&&(R.length=500);const d=h.querySelector(".sec-tab.active")?.dataset?.tab;d==="events"?N():d==="overview"&&$()}catch{}}),P.onerror=()=>{}}catch(r){console.warn("[security] SSE failed:",r.message)}}function x(){if(P){try{P.close()}catch{}P=null}}document.getElementById("sec-live-tail").addEventListener("change",()=>{h.classList.contains("show")&&C()});async function $(){try{const r=new Date(Date.now()-864e5).toISOString(),[c,d,w]=await Promise.all([fetch(`/api/v1/security/events/stats?since=${encodeURIComponent(r)}`),fetch("/api/v1/security/hosts"),fetch(`/api/v1/security/events?limit=1&since=${encodeURIComponent(r)}`)]),y=(await c.json()).data||{},t=(await d.json()).data?.hosts||[],e=(await w.json()).data?.total||0;document.querySelector('#sec-stats [data-key="total"]').textContent=`${e} events (24h)`,document.querySelector('#sec-stats [data-key="warn"]').textContent=`${y.by_severity?.warn||0} warnings`,document.querySelector('#sec-stats [data-key="error"]').textContent=`${y.by_severity?.error||0} errors`,document.querySelector('#sec-stats [data-key="denied"]').textContent=`${y.by_outcome?.denied||0} denied`,document.querySelector('#sec-stats [data-key="hosts"]').textContent=`${t.length} hosts`,E("sec-top-actors",y.top_actors||[]),E("sec-top-targets",y.top_targets||[])}catch(r){console.warn("[security] refreshOverview failed:",r.message)}}function E(r,c){const d=document.getElementById(r);if(!c.length){d.innerHTML='<div class="panel-empty">No data</div>';return}d.innerHTML='<table style="width:100%;font-size:0.85rem;">'+c.map(w=>`<tr><td style="padding:3px 0;word-break:break-all;">${g(String(w.key))}</td><td style="text-align:right;color:var(--muted);">${w.count}</td></tr>`).join("")+"</table>"}const M=document.getElementById("sec-filter-source"),S=document.getElementById("sec-filter-severity"),B=document.getElementById("sec-filter-host"),U=document.getElementById("sec-filter-actor"),T=document.getElementById("sec-refresh-btn");[M,S,B].forEach(r=>r.addEventListener("change",b)),U.addEventListener("input",z(b,250)),T.addEventListener("click",b);async function b(){try{const r=new URLSearchParams;r.set("limit","200"),M.value&&r.set("source_type",M.value),S.value&&r.set("severity",S.value),B.value&&r.set("source_host",B.value),U.value&&r.set("actor_prefix",U.value),R=(await(await fetch(`/api/v1/security/events?${r}`)).json()).data.events||[],N(),(!B.options.length||B.options.length===1)&&await p()}catch(r){document.getElementById("sec-events-container").innerHTML='<div class="panel-empty">Load failed: '+g(r.message)+"</div>"}}function N(){const r=document.getElementById("sec-events-container");if(!R.length){r.innerHTML='<div class="panel-empty">No events</div>';return}r.innerHTML=R.slice(0,200).map(O).join("")}function O(r){const c=r.severity||"info",d={critical:"#c0392b",error:"#e74c3c",warn:"#f39c12",notice:"#3498db",info:"#7f8c8d"}[c]||"#7f8c8d",w=r.ts?new Date(r.ts).toLocaleTimeString():"",y=r.source_type||"",t=r.actor||"\u2014",e=r.target||"",a=r.action||"",o=r.outcome||"";return`<div class="sec-event-row" style="display:grid;grid-template-columns:84px 80px 1fr 1fr 100px 90px;gap:8px;padding:5px 8px;border-bottom:1px solid var(--border);font-size:0.82rem;align-items:center;">
|
|
<span style="color:${d};font-weight:600;">${g(c)}</span>
|
|
<span style="color:var(--muted);font-size:0.75rem;">${g(y)}</span>
|
|
<span title="${g(t)}" style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">${g(t)}</span>
|
|
<span title="${g(e)}" style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">${g(a)} ${g(e)}</span>
|
|
<span style="color:var(--muted);font-size:0.75rem;">${g(o)}</span>
|
|
<span style="color:var(--muted);font-size:0.75rem;text-align:right;">${g(w)}</span>
|
|
</div>`}async function p(){try{const c=(await(await fetch("/api/v1/security/hosts")).json()).data?.hosts||[],d=B.value;B.innerHTML='<option value="">All hosts</option>'+c.map(w=>`<option value="${g(w.id)}">${g(w.label||w.id)}</option>`).join(""),d&&(B.value=d)}catch{}}document.getElementById("sec-host-register-btn").addEventListener("click",f),document.getElementById("sec-hosts-refresh").addEventListener("click",u);async function u(){try{const c=(await(await fetch("/api/v1/security/hosts")).json()).data?.hosts||[];H=c;const d=document.getElementById("sec-hosts-container");if(!c.length){d.innerHTML='<div class="panel-empty">No hosts registered. Click \u2795 Register Host to add one.</div>';return}d.innerHTML=c.map(w=>{const y=w.enabled?w.last_seen_at?Date.now()-Date.parse(w.last_seen_at)>18e5?"\u{1F7E1} stale":"\u{1F7E2} online":"\u26AA registered":"\u{1F534} disabled";return`<div style="padding:10px 12px;border-bottom:1px solid var(--border);display:flex;justify-content:space-between;align-items:center;">
|
|
<div>
|
|
<strong>${g(w.label||w.id)}</strong>
|
|
<span style="color:var(--muted);margin-left:8px;font-size:0.8rem;">${g(w.type)}</span>
|
|
<div style="color:var(--muted);font-size:0.78rem;margin-top:2px;">
|
|
id: ${g(w.id)} \xB7
|
|
registered ${new Date(w.registered_at).toLocaleDateString()} \xB7
|
|
last seen ${w.last_seen_at?new Date(w.last_seen_at).toLocaleString():"never"}
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<span style="font-size:0.85rem;margin-right:12px;">${y}</span>
|
|
${w.id==="self"?"":`<button class="btn-sm sec-host-del" data-id="${g(w.id)}" style="color:var(--bad-fg);">Remove</button>`}
|
|
</div>
|
|
</div>`}).join(""),d.querySelectorAll(".sec-host-del").forEach(w=>{w.addEventListener("click",async()=>{confirm(`Remove host ${w.dataset.id}? Events already received will remain in the store.`)&&(await fetch(`/api/v1/security/hosts/${encodeURIComponent(w.dataset.id)}`,{method:"DELETE"}),u())})})}catch(r){document.getElementById("sec-hosts-container").innerHTML='<div class="panel-empty">Load failed: '+g(r.message)+"</div>"}}async function f(){const r=prompt("Host id (lowercase, no spaces):");if(!r)return;const c=prompt("Display label:",r)||r,d=prompt('Type ("dashcaddy", "service", or "agent"):',"agent")||"agent";try{const w=await fetch("/api/v1/security/hosts",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({id:r,label:c,type:d})}),y=await w.json();if(!w.ok){alert("Failed: "+(y?.error?.message||w.statusText));return}alert(`\u2705 Host registered!
|
|
|
|
id: ${y.data.host.id}
|
|
label: ${y.data.host.label}
|
|
type: ${y.data.host.type}
|
|
|
|
\u{1F511} API KEY (save this NOW \u2014 won't be shown again):
|
|
|
|
${y.data.api_key}
|
|
|
|
Send this key as: Authorization: Bearer <api_key>
|
|
To endpoint: POST /api/v1/security/events/ingest or /events/batch`),u()}catch(w){alert("Failed: "+w.message)}}function g(r){return String(r).replace(/[&<>"']/g,c=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[c])}function z(r,c){let d;return function(){clearTimeout(d),d=setTimeout(()=>r.apply(this,arguments),c)}}})(),(function(){const h=new ErrorHandler;injectModal("weather-modal",`<div id="weather-modal" class="weather-modal"><div class="weather-modal-content"><h3>Weather Settings</h3>
|
|
<label for="weather-location-input">Location:</label>
|
|
<input type="text" id="weather-location-input" placeholder="City name or ZIP (e.g., Hamburg, 90210)" maxlength="100">
|
|
<div style="font-size: 0.78rem; color: var(--muted); margin-top: 4px;">Enter a city name, postal code, or “City, Country”</div>
|
|
<div style="margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border);">
|
|
<label style="display: block; margin-bottom: 8px; font-weight: 600; color: var(--fg);">Units</label>
|
|
<div style="display: flex; gap: 8px;">
|
|
<label class="weather-unit-option"><input type="radio" name="weather-unit-radio" value="imperial"><span class="weather-unit-card">°F / mph</span></label>
|
|
<label class="weather-unit-option"><input type="radio" name="weather-unit-radio" value="metric"><span class="weather-unit-card">°C / km/h</span></label>
|
|
</div>
|
|
</div>
|
|
<div class="weather-modal-buttons"><button id="weather-cancel">Cancel</button><button id="weather-save">Save</button></div></div></div>`);const L="weather-location",A="weather-zip",I="weather-geo",D="weather-unit";!safeGet(L)&&safeGet(A)&&safeSet(L,safeGet(A));function R(){return safeGet(D)||"imperial"}function H(){return{icon:document.querySelector(".weather-icon"),temp:document.querySelector(".weather-temp"),condition:document.querySelector(".weather-condition"),location:document.querySelector(".weather-location"),wind:document.querySelector(".weather-wind")}}const P={0:"Clear sky",1:"Mainly clear",2:"Partly cloudy",3:"Overcast",45:"Fog",48:"Rime fog",51:"Light drizzle",53:"Drizzle",55:"Dense drizzle",56:"Freezing drizzle",57:"Dense freezing drizzle",61:"Light rain",63:"Moderate rain",65:"Heavy rain",66:"Light freezing rain",67:"Heavy freezing rain",71:"Light snow",73:"Moderate snow",75:"Heavy snow",77:"Snow grains",80:"Light showers",81:"Moderate showers",82:"Violent showers",85:"Light snow showers",86:"Heavy snow showers",95:"Thunderstorm",96:"Thunderstorm with hail",99:"Severe thunderstorm"},v={0:"\u2600\uFE0F",1:"\u{1F324}\uFE0F",2:"\u26C5",3:"\u2601\uFE0F",45:"\u{1F32B}\uFE0F",48:"\u{1F32B}\uFE0F",51:"\u{1F326}\uFE0F",53:"\u{1F326}\uFE0F",55:"\u{1F326}\uFE0F",56:"\u{1F328}\uFE0F",57:"\u{1F328}\uFE0F",61:"\u{1F326}\uFE0F",63:"\u{1F327}\uFE0F",65:"\u{1F327}\uFE0F",66:"\u{1F328}\uFE0F",67:"\u{1F328}\uFE0F",71:"\u{1F328}\uFE0F",73:"\u2744\uFE0F",75:"\u2744\uFE0F",77:"\u2744\uFE0F",80:"\u{1F326}\uFE0F",81:"\u{1F327}\uFE0F",82:"\u{1F327}\uFE0F",85:"\u{1F328}\uFE0F",86:"\u2744\uFE0F",95:"\u26C8\uFE0F",96:"\u26C8\uFE0F",99:"\u26C8\uFE0F"},C=["N","NNE","NE","ENE","E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW","NW","NNW"];function x(T){return C[Math.round(T/22.5)%16]}async function $(T){const b=safeGet(I);if(b)try{const f=JSON.parse(b);if(f.query===T)return f}catch{}const N=await fetch(`https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(T)}&count=1&language=en&format=json`);if(!N.ok)throw new Error("Geocoding failed");const O=await N.json();if(!O.results||!O.results.length)throw new Error("Location not found");const p=O.results[0],u={query:T,lat:p.latitude,lon:p.longitude,city:p.name,state:p.admin1||"",country:p.country||"",countryCode:p.country_code||""};return safeSet(I,JSON.stringify(u)),u}function E(T){return T.countryCode==="US"&&T.state?`${T.city}, ${T.state}`:T.country?`${T.city}, ${T.country}`:T.city}async function M(T){try{const b=await $(T),N=R(),O=N==="metric"?"celsius":"fahrenheit",p=N==="metric"?"kmh":"mph",u=`https://api.open-meteo.com/v1/forecast?latitude=${b.lat}&longitude=${b.lon}¤t=temperature_2m,weather_code,wind_speed_10m,wind_direction_10m&temperature_unit=${O}&wind_speed_unit=${p}`,f=await fetch(u);if(!f.ok)throw new Error("Weather fetch failed");const z=(await f.json()).current,r=z.weather_code;return{temp:Math.round(z.temperature_2m),condition:P[r]||"Unknown",icon:v[r]||"\u{1F324}\uFE0F",locationStr:E(b),windSpeed:Math.round(z.wind_speed_10m),windDir:x(z.wind_direction_10m),unit:N}}catch(b){return console.warn("Weather fetch failed:",b),null}}async function S(){const T=H();if(!T.icon||!T.temp||!T.condition||!T.location||!T.wind){console.warn("Weather widget elements not found");return}const b=safeGet(L);if(!b){T.location.textContent="Set Location",T.temp.textContent="--\xB0",T.condition.textContent="Click \u2699\uFE0F to configure",T.wind.textContent="--",T.icon.innerHTML='<span class="weather-emoji">\u{1F324}\uFE0F</span>';return}try{const N=await M(b);if(N){const O=N.unit==="metric"?"\xB0C":"\xB0F",p=N.unit==="metric"?"km/h":"mph";T.location.textContent=N.locationStr,T.temp.textContent=`${N.temp}${O}`,T.condition.textContent=N.condition,T.wind.textContent=`Wind: ${N.windSpeed} ${p} ${N.windDir}`,T.icon.innerHTML=`<span class="weather-emoji">${escapeHtml(N.icon)}</span>`}}catch(N){h.logError("[Weather] Update Error",N,{function:"updateWeather"}),T.location.textContent="Weather Error",T.temp.textContent="Error",T.condition.textContent="Failed to load",T.wind.textContent="--"}}const B=document.getElementById("weather-modal"),U=document.getElementById("weather-location-input");document.getElementById("weather-settings")?.addEventListener("click",()=>{U.value=safeGet(L)||"";const T=R(),b=B.querySelector(`input[name="weather-unit-radio"][value="${T}"]`);b&&(b.checked=!0),B.classList.add("show"),U.focus()}),document.getElementById("weather-cancel")?.addEventListener("click",()=>{B.classList.remove("show")}),document.getElementById("weather-save")?.addEventListener("click",()=>{const T=U.value.trim();if(T){safeGet(L)!==T&&safeSet(I,""),safeSet(L,T);const N=B.querySelector('input[name="weather-unit-radio"]:checked'),O=N?N.value:"imperial",p=R();safeSet(D,O),p!==O&&safeSet(I,""),B.classList.remove("show"),S()}else showNotification("Please enter a location (e.g., Hamburg, London, 90210)","warning")}),wireModal(B),document.addEventListener("keydown",T=>{T.key==="Escape"&&B.classList.contains("show")&&B.classList.remove("show")}),S(),setInterval(S,DC.POLL.WEATHER)})(),(function(){const h=document.getElementById("clock-widget"),L=document.getElementById("clock-render");if(!h||!L)return;const A=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],I=["January","February","March","April","May","June","July","August","September","October","November","December"],D=["XII","I","II","III","IV","V","VI","VII","VIII","IX","X","XI"];let R=safeGet("clock-style")||"default",H=-1,P=!1,v="",C="",x=null,$=null;function E(t){if(P||safeGet("clock-chimes")!=="true")return;P=!0;const e=parseInt(safeGet("clock-chime-volume")||"50",10)/100;let a=0;function o(){if(a>=t){P=!1;return}const i=new Audio("/assets/sounds/church-bell.mp3");i.volume=e,i.play().catch(()=>{}),a++,a<t?setTimeout(o,2500):setTimeout(()=>{P=!1},2500)}o()}function M(t){return A[t.getDay()]+", "+I[t.getMonth()]+" "+t.getDate()+", "+t.getFullYear()}function S(){C="",x=null}function B(){return C!=="digital"&&(L.innerHTML='<div class="clock-time"><span class="clock-main"></span><span class="clock-seconds"></span><span class="clock-ampm"></span></div><div class="clock-date"></div>',x={main:L.querySelector(".clock-main"),seconds:L.querySelector(".clock-seconds"),ampm:L.querySelector(".clock-ampm"),date:L.querySelector(".clock-date")},C="digital"),x}function U(t){const e=t.getHours(),a=t.getMinutes(),o=t.getSeconds(),i=e>=12?"PM":"AM",n=e%12||12,s=B();s.main.textContent=`${n}:${String(a).padStart(2,"0")}`,s.seconds.textContent=`:${String(o).padStart(2,"0")}`,s.ampm.textContent=i,s.date.textContent=M(t)}function T(t,e){const a=t.getHours(),o=t.getMinutes(),i=t.getSeconds(),n=a>=12?"PM":"AM",s=a%12||12,l=B();l.main.textContent=`${String(s).padStart(2,"0")}:${String(o).padStart(2,"0")}`,l.seconds.textContent=`:${String(i).padStart(2,"0")}`,l.ampm.textContent=n,l.date.textContent=M(t)}function b(t){const e=t.getHours(),a=t.getMinutes(),o=t.getSeconds(),i=e>=12?"PM":"AM",n=e%12||12,s=String(n).padStart(2," ")+String(a).padStart(2,"0")+String(o).padStart(2,"0");let l='<div class="flip-clock-row">';if(l+=N(s[0],0),l+=N(s[1],1),l+='<span class="flip-colon">:</span>',l+=N(s[2],2),l+=N(s[3],3),l+='<span class="flip-colon">:</span>',l+=N(s[4],4),l+=N(s[5],5),l+=`<span class="flip-ampm">${i}</span>`,l+="</div>",l+=`<div class="clock-date">${M(t)}</div>`,L.innerHTML=l,C="flip",v){for(let m=0;m<6;m++)if(s[m]!==v[m]){const k=L.querySelector(`.flip-card[data-idx="${m}"]`);k&&k.classList.add("flipping")}}v=s}function N(t,e){const a=t===" "?"":t;return`<div class="flip-card" data-idx="${e}"><div class="flip-top">${a}</div><div class="flip-bottom">${a}</div></div>`}function O(t){const e=t.getHours(),a=t.getMinutes(),o=t.getSeconds(),i=e%12||12,n=e>=12?"PM":"AM",s=[Math.floor(i/10),i%10,Math.floor(a/10),a%10,Math.floor(o/10),o%10];let l='<div class="binary-clock">';l+='<div class="binary-labels"><span>H</span><span>H</span><span>M</span><span>M</span><span>S</span><span>S</span></div>';for(let m=3;m>=0;m--){l+='<div class="binary-row">';for(let k=0;k<6;k++){const j=s[k]>>m&1;l+=`<div class="binary-dot ${j?"on":""}"></div>`}l+="</div>"}l+='<div class="binary-values">';for(let m=0;m<6;m++)l+=`<span>${s[m]}</span>`;l+="</div>",l+=`<div class="binary-ampm">${n}</div>`,l+="</div>",l+=`<div class="clock-date">${M(t)}</div>`,L.innerHTML=l,C="binary"}function p(t,e){const a=t.getHours(),o=t.getMinutes(),i=t.getSeconds(),n=120,s=n/2,l=n/2,m=i/60*360-90,k=(o+i/60)/60*360-90,j=(a%12+o/60)/12*360-90;let _="";for(let X=1;X<=12;X++){const Q=X/12*2*Math.PI-Math.PI/2,ne=47,oe=s+ne*Math.cos(Q),se=l+ne*Math.sin(Q),Y=e?D[X%12]:X;_+=`<text x="${oe}" y="${se}" text-anchor="middle" dominant-baseline="central" fill="var(--fg)" font-size="${e?"7":"9"}" font-weight="600" font-family="'Sami Grotesk',sans-serif">${Y}</text>`}let F="";for(let X=0;X<60;X++){const Q=X/60*2*Math.PI-Math.PI/2,ne=56,oe=X%5===0?52:54,se=s+oe*Math.cos(Q),Y=l+oe*Math.sin(Q),ie=s+ne*Math.cos(Q),re=l+ne*Math.sin(Q),ae=X%5===0?1.5:.5;F+=`<line x1="${se}" y1="${Y}" x2="${ie}" y2="${re}" stroke="var(--muted)" stroke-width="${ae}" stroke-linecap="round"/>`}const q=`<svg class="analog-clock-svg" viewBox="0 0 ${n} ${n}" width="${n}" height="${n}">
|
|
<circle cx="${s}" cy="${l}" r="58" fill="none" stroke="var(--border)" stroke-width="2"/>
|
|
${F}
|
|
${_}
|
|
<line x1="${s}" y1="${l}" x2="${s+28*Math.cos(j*Math.PI/180)}" y2="${l+28*Math.sin(j*Math.PI/180)}" stroke="var(--fg)" stroke-width="3" stroke-linecap="round"/>
|
|
<line x1="${s}" y1="${l}" x2="${s+38*Math.cos(k*Math.PI/180)}" y2="${l+38*Math.sin(k*Math.PI/180)}" stroke="var(--fg)" stroke-width="2" stroke-linecap="round"/>
|
|
<line x1="${s}" y1="${l}" x2="${s+42*Math.cos(m*Math.PI/180)}" y2="${l+42*Math.sin(m*Math.PI/180)}" stroke="#e74c3c" stroke-width="1" stroke-linecap="round"/>
|
|
<circle cx="${s}" cy="${l}" r="3" fill="var(--fg)"/>
|
|
</svg>`,J=t.getHours()>=12?"PM":"AM";L.innerHTML=`<div class="analog-clock-wrap">${q}<div class="analog-info"><span class="analog-digital">${t.getHours()%12||12}:${String(o).padStart(2,"0")} ${J}</span><span class="analog-date-sm">${M(t)}</span></div></div>`,C="analog"}function u(){const t=new Date,e=t.getHours()%12||12,a=t.getMinutes(),o=t.getSeconds(),i="clock-widget"+(R!=="default"?" "+R:"");switch(h.className!==i&&(h.className=i),R){case"lcd":T(t);break;case"lcd-blue":T(t);break;case"lcd-amber":T(t);break;case"lcd-retro":T(t);break;case"lcd-taxi":T(t);break;case"flip":b(t);break;case"binary":O(t);break;case"analog":p(t,!1);break;case"roman":p(t,!0);break;default:U(t)}a===0&&o===0&&e!==H&&(H=e,E(e)),a!==0&&(H=-1)}function f(){clearTimeout($);const t=document.hidden?6e4:1e3,e=t-Date.now()%t+25;$=setTimeout(()=>{u(),f()},e)}document.addEventListener("visibilitychange",()=>{v="",S(),u(),f()}),u(),f();const g=[{id:"default",label:"Default",icon:"\u{1F550}"},{id:"lcd",label:"LCD Green",icon:"\u{1F49A}"},{id:"lcd-blue",label:"LCD Blue",icon:"\u{1F499}"},{id:"lcd-amber",label:"LCD Amber",icon:"\u{1F7E0}"},{id:"lcd-retro",label:"LCD Retro",icon:"\u{1F7E9}"},{id:"lcd-taxi",label:"LCD Taxi",icon:"\u{1F7E1}"},{id:"flip",label:"Flip Clock",icon:"\u{1F4DF}"},{id:"binary",label:"Binary",icon:"\u{1F4BB}"},{id:"analog",label:"Analog",icon:"\u23F0"},{id:"roman",label:"Roman",icon:"\u{1F3DB}\uFE0F"}];let z='<div class="clock-style-grid">';g.forEach(t=>{z+=`<label class="clock-style-option">
|
|
<input type="radio" name="clock-style-radio" value="${t.id}">
|
|
<span class="clock-style-card"><span class="clock-style-icon">${t.icon}</span><span class="clock-style-label">${t.label}</span></span>
|
|
</label>`}),z+="</div>",injectModal("clock-settings-modal",`<div id="clock-settings-modal" class="weather-modal">
|
|
<div class="weather-modal-content" style="max-width: 420px;">
|
|
<h3>Clock Settings</h3>
|
|
<div style="margin-bottom: 16px;">
|
|
<label style="display: block; margin-bottom: 8px; font-weight: 600; color: var(--fg);">Style</label>
|
|
${z}
|
|
</div>
|
|
<div style="margin-bottom: 16px; padding-top: 12px; border-top: 1px solid var(--border);">
|
|
<label style="display: flex; align-items: center; gap: 8px; cursor: pointer; font-weight: 600; color: var(--fg);">
|
|
<input type="checkbox" id="clock-chimes-toggle"> Hourly church bell chimes
|
|
</label>
|
|
<div style="font-size: 0.78rem; color: var(--muted); margin-top: 4px; margin-left: 24px;">
|
|
Strikes the number of the hour (e.g., 3 bells at 3:00)
|
|
</div>
|
|
</div>
|
|
<div style="margin-bottom: 16px;" id="clock-volume-section">
|
|
<label style="display: block; margin-bottom: 6px; font-weight: 600; color: var(--fg);">Volume</label>
|
|
<div style="display: flex; align-items: center; gap: 10px;">
|
|
<span style="font-size: 0.85rem;">\u{1F508}</span>
|
|
<input type="range" id="clock-chime-volume" min="0" max="100" value="50" style="flex: 1; accent-color: var(--ok-fg);">
|
|
<span style="font-size: 0.85rem;">\u{1F50A}</span>
|
|
<button id="clock-chime-test" style="padding: 4px 10px; font-size: 0.78rem; border-radius: 4px; cursor: pointer;">Test</button>
|
|
</div>
|
|
</div>
|
|
<div class="weather-modal-buttons">
|
|
<button id="clock-settings-cancel">Cancel</button>
|
|
<button id="clock-settings-save">Save</button>
|
|
</div>
|
|
</div>
|
|
</div>`);const r=document.getElementById("clock-settings-modal"),c=document.getElementById("clock-chimes-toggle"),d=document.getElementById("clock-chime-volume"),w=document.getElementById("clock-volume-section");function y(){const t=safeGet("clock-style")||"default",e=r.querySelector(`input[value="${t}"]`);e&&(e.checked=!0),c.checked=safeGet("clock-chimes")==="true",d.value=safeGet("clock-chime-volume")||"50",w.style.opacity=c.checked?"1":"0.4"}c?.addEventListener("change",()=>{w.style.opacity=c.checked?"1":"0.4"}),document.getElementById("clock-settings")?.addEventListener("click",()=>{y(),r.classList.add("show")}),document.getElementById("clock-chime-test")?.addEventListener("click",()=>{const t=parseInt(d.value,10)/100,e=new Audio("/assets/sounds/church-bell.mp3");e.volume=t,e.play().catch(()=>{})}),document.getElementById("clock-settings-save")?.addEventListener("click",()=>{const t=r.querySelector('input[name="clock-style-radio"]:checked'),e=t?t.value:"default";safeSet("clock-style",e),safeSet("clock-chimes",String(c.checked)),safeSet("clock-chime-volume",d.value),R=e,v="",S(),u(),f(),r.classList.remove("show"),showNotification("Clock settings saved","success",2e3)}),document.getElementById("clock-settings-cancel")?.addEventListener("click",()=>{r.classList.remove("show")}),wireModal(r),r?.querySelectorAll('input[name="clock-style-radio"]').forEach(t=>{t.addEventListener("change",()=>{R=t.value,v="",S(),u()})})})(),(function(){async function h(){try{const P=await(await fetch("/api/v1/health-checks/status")).json();if(!P.success||!P.status)return;for(const[v,C]of Object.entries(P.status)){const x=document.getElementById("uptime-"+v),$=document.getElementById("uptime-bar-"+v);if(!x)continue;const E=C.uptime?.["24h"];if(E!=null){const M=E.toFixed(1);x.textContent=`${M}% uptime`,x.className="uptime-chip",E>=99.9?x.classList.add("excellent"):E>=99?x.classList.add("good"):E>=95?x.classList.add("degraded"):x.classList.add("poor"),$&&($.style.width=M+"%")}}}catch{console.warn("[Card Badges] Health check API unavailable")}}let L;try{L=new Set(JSON.parse(safeSessionGet("dismissed-updates")||"[]"))}catch{L=new Set}let A=[];async function I(H){try{const v=await(await fetch("/api/v1/updates/available")).json();if(!v.success)return;document.querySelectorAll(".update-available-badge").forEach(x=>x.classList.remove("visible"));const C=v.updates||[];if(A=C,H&&C.length>0){const x=window._lastKnownUpdateCount||0;x>0&&C.length>x&&showNotification(`${C.length} container update(s) available \u2014 click Update Management to review.`,"info"),window._lastKnownUpdateCount=C.length}if(!C.length)return;for(const x of C){const $=window.APPS||[];for(const E of $)if(E.containerId===x.containerId||E.id===x.containerName||E.name===x.containerName){if(L.has(E.id))break;const M=document.getElementById("update-badge-"+E.id),S=document.getElementById("update-btn-"+E.id);M&&(M.classList.add("visible"),M.title="Update available \u2014 click to open Update Management.",M.style.cursor="pointer",M.onclick=B=>{B.stopPropagation(),window.openUpdateModal&&window.openUpdateModal(E.id)}),S&&(S.style.background="#f97316",S.style.borderColor="#f97316",S.style.boxShadow="0 0 6px #f9731688",S.title="Update available \u2014 click to open Update Management.");break}}}catch{console.warn("[Card Badges] Updates API unavailable")}}function D(){setTimeout(()=>{h(),I()},5e3),setInterval(()=>{h(),I(!0)},6e4)}const R=window.refreshAll;R&&(window.refreshAll=async function(){try{await R(),setTimeout(h,1e3)}catch(H){console.warn("[Card Badges] Error in refreshAll hook:",H.message)}}),D()})(),(function(){var h=null,L=null,A={},I={dark:"Dark",light:"Light",blue:"Blue",black:"Black",nord:"Nord",dracula:"Dracula","solarized-dark":"Solarized Dark","solarized-light":"Solarized Light",taxi:"Taxi",ocean:"Ocean"},D=[["bg","Background","base"],["card-base","Card","base"],["fg","Text","base"],["muted","Muted Text","base"],["border","Border","base"],["accent","Accent","accent"],["accent-strong","Accent Strong","accent"],["ok-bg","OK Background","status"],["ok-fg","OK Text","status"],["bad-bg","Error Bg","status"],["bad-fg","Error Text","status"],["dot-ok","Dot OK","status"],["dot-bad","Dot Error","status"],["uptime","Uptime Bar","status"],["hover","Hover","advanced"],["card-hover","Card Hover","advanced"],["base","Tags/Badges","advanced"],["fg-muted","Dim Text","advanced"],["success","Success","advanced"],["error","Error","advanced"],["warning","Warning","advanced"]],R=document.getElementById("theme");if(!R)return;var H=document.getElementById("theme-label");function P(o){if(I[o])return I[o];var i=safeGetJSON(window.USER_THEMES_KEY,{});return i[o]&&i[o].name||o}function v(){H&&(H.textContent=P(window.getActiveTheme()))}R.addEventListener("click",function(){var o=window.THEMES.slice(),i=window.getActiveTheme(),n=o.indexOf(i),s=o[(n+1)%o.length];window.applyTheme(s),v()}),v();function C(){var o={base:"Base Colors",accent:"Accent",status:"Status",advanced:"Advanced (auto-derived)"},i={};D.forEach(function(s){i[s[2]]||(i[s[2]]=[]),i[s[2]].push(s)});var n="";return Object.keys(o).forEach(function(s){s==="advanced"?(n+='<div id="theme-builder-advanced-toggle" class="theme-builder-advanced-toggle" style="margin:12px 0 4px;cursor:pointer;color:var(--accent);font-size:.85rem;user-select:none;">Show advanced colors ▼</div>',n+='<div id="theme-builder-advanced" class="theme-builder-section" style="display:none;">'):n+='<div class="theme-builder-section">',n+='<div class="theme-builder-section-title">'+o[s]+"</div>",(i[s]||[]).forEach(function(l){n+='<div class="theme-builder-row"><span class="theme-builder-label">'+l[1]+'</span><input type="color" class="theme-builder-color" data-prop="'+l[0]+'"'+(s==="advanced"?' data-advanced="1"':"")+' value="#000000" /><span class="theme-builder-hex" data-hex="'+l[0]+'">#000000</span></div>'}),n+="</div>"}),n}function x(){return window.THEMES.map(function(o){return'<option value="'+o+'">'+P(o)+"</option>"}).join("")}var $='<div id="theme-builder-modal" class="weather-modal"><div class="weather-modal-content" style="min-width:420px;max-width:560px;"><h3>Theme Builder</h3><div id="theme-builder-existing" style="margin-bottom:16px;display:none;"><label style="font-size:.85rem;color:var(--muted);margin-right:8px;">Edit:</label><select id="theme-builder-edit-select" style="padding:6px 10px;background:var(--card-bg);color:var(--fg);border:1px solid var(--border);border-radius:6px;font-size:.85rem;margin-right:8px;"><option value="">\u2014 New Theme \u2014</option></select><button id="theme-builder-delete" style="padding:4px 10px;background:color-mix(in srgb,var(--bad-fg) 15%,transparent);border:1px solid var(--bad-fg);color:var(--bad-fg);border-radius:6px;font-size:.8rem;cursor:pointer;">Delete</button></div><div style="margin-bottom:16px;"><label style="font-size:.85rem;color:var(--muted);margin-right:8px;">Name:</label><input type="text" id="theme-builder-name" maxlength="20" placeholder="My Theme" style="padding:6px 10px;background:var(--card-bg);color:var(--fg);border:1px solid var(--border);border-radius:6px;font-size:.85rem;width:140px;" /></div><div style="margin-bottom:16px;display:flex;align-items:center;"><label style="font-size:.85rem;color:var(--muted);margin-right:8px;cursor:pointer;" for="theme-builder-lightbg"><input type="checkbox" id="theme-builder-lightbg" style="margin-right:6px;cursor:pointer;vertical-align:middle;" />Light background (use dark logo)</label></div><div style="margin-bottom:16px;"><label style="font-size:.85rem;color:var(--muted);margin-right:8px;">Start from:</label><select id="theme-builder-start" style="padding:6px 10px;background:var(--card-bg);color:var(--fg);border:1px solid var(--border);border-radius:6px;font-size:.85rem;">'+x()+'</select></div><div class="theme-builder-preview" id="theme-builder-preview"><div class="theme-builder-card" id="theme-preview-card"><div class="preview-title">Sample Card</div><div class="preview-muted">Secondary text preview</div><div class="preview-badges"><span class="preview-badge" id="preview-badge-ok">ON</span><span class="preview-badge" id="preview-badge-bad">OFF</span></div><div class="preview-dots"><span><span class="preview-dot" id="preview-dot-ok"></span> Online</span><span><span class="preview-dot" id="preview-dot-bad"></span> Offline</span></div><button class="preview-btn" id="preview-accent-btn">Accent Button</button></div></div>'+C()+'<div class="weather-modal-buttons"><button id="theme-builder-cancel">Cancel</button><button id="theme-builder-import" style="margin-left:auto;" title="Import theme from JSON file">Import</button><button id="theme-builder-export" title="Export theme as JSON file">Export</button><button id="theme-builder-save" class="btn-accent">Save Theme</button></div></div></div>';injectModal("theme-builder-modal",$);var E=document.getElementById("theme-builder-modal"),M=document.getElementById("theme-builder-start"),S=document.getElementById("theme-builder-name"),B=document.getElementById("theme-builder-edit-select"),U=document.getElementById("theme-builder-existing"),T=document.getElementById("theme-builder-lightbg"),b=E.querySelectorAll(".theme-builder-color"),N=document.getElementById("theme-builder-advanced"),O=document.getElementById("theme-builder-advanced-toggle"),p=document.getElementById("theme-builder-export"),u=!1;O.addEventListener("click",function(){u=!u,N.style.display=u?"":"none",O.innerHTML=u?"Hide advanced colors ▲":"Show advanced colors ▼"});function f(){var o={};return b.forEach(function(i){o[i.dataset.prop]=i.value}),o["card-bg"]=o["card-base"],o}function g(){var o={};return b.forEach(function(i){i.dataset.advanced||(o[i.dataset.prop]=i.value)}),o["card-bg"]=o["card-base"],T.checked&&(o.lightBg=!0),o}function z(){var o=g(),i=window.deriveExtendedColors?window.deriveExtendedColors(o):{};b.forEach(function(n){if(n.dataset.advanced&&!A[n.dataset.prop]){var s=i[n.dataset.prop]||"#333333";n.value=s;var l=E.querySelector('[data-hex="'+n.dataset.prop+'"]');l&&(l.textContent=s.toUpperCase())}})}function r(o){var i=window.THEME_COLORS[o];i&&(A={},b.forEach(function(n){var s=i[n.dataset.prop]||"#000000";(s.startsWith("rgba")||s.startsWith("color-mix"))&&(s="#333333"),n.value=s;var l=E.querySelector('[data-hex="'+n.dataset.prop+'"]');l&&(l.textContent=s.toUpperCase())}),T.checked=!!i.lightBg,d())}function c(o){var i=safeGetJSON(window.USER_THEMES_KEY,{}),n=i[o];n&&(A={},b.forEach(function(s){var l=n[s.dataset.prop]||"#000000";s.value=l;var m=E.querySelector('[data-hex="'+s.dataset.prop+'"]');m&&(m.textContent=l.toUpperCase()),s.dataset.advanced&&n[s.dataset.prop]&&(A[s.dataset.prop]=!0)}),S.value=n.name||"",T.checked=!!n.lightBg,z(),d())}function d(){var o=f(),i=document.getElementById("theme-builder-preview"),n=document.getElementById("theme-preview-card"),s=n.querySelector(".preview-title"),l=n.querySelector(".preview-muted"),m=document.getElementById("preview-badge-ok"),k=document.getElementById("preview-badge-bad"),j=document.getElementById("preview-dot-ok"),_=document.getElementById("preview-dot-bad"),F=document.getElementById("preview-accent-btn"),q=n.querySelector(".preview-dots");i.style.background=o.bg,n.style.background=o["card-base"],n.style.borderColor=o.border,s.style.color=o.fg,l.style.color=o.muted,m.style.background=o["ok-bg"],m.style.color=o["ok-fg"],k.style.background=o["bad-bg"],k.style.color=o["bad-fg"],j.style.background=o["dot-ok"],_.style.background=o["dot-bad"],q.style.color=o.fg,F.style.background=o.accent,F.style.color=o.bg}function w(o){var i=window.deriveExtendedColors?window.deriveExtendedColors(o):{};window.THEME_PROPS.forEach(function(n){var s=o[n]||i[n];s&&document.documentElement.style.setProperty("--"+n,s)})}b.forEach(function(o){o.addEventListener("input",function(){var i=E.querySelector('[data-hex="'+o.dataset.prop+'"]');i&&(i.textContent=o.value.toUpperCase()),o.dataset.advanced?A[o.dataset.prop]=!0:z(),d(),w(f())})}),T.addEventListener("change",function(){z(),d(),w(f())}),M.addEventListener("change",function(){A={},r(M.value),w(f())});function y(){var o=safeGetJSON(window.USER_THEMES_KEY,{}),i=Object.keys(o);B.innerHTML='<option value="">\u2014 New Theme \u2014</option>',i.forEach(function(n){var s=document.createElement("option");s.value=n,s.textContent=o[n].name||n,B.appendChild(s)}),U.style.display=i.length?"":"none"}function t(){M.innerHTML=x()}B.addEventListener("change",function(){var o=this.value;o?(L=o,c(o),w(f())):(L=null,A={},S.value="",M.value=window.getActiveTheme(),r(M.value)),p.style.display=L?"":"none"});function e(){h=window.getActiveTheme(),L=null,A={},u=!1,N.style.display="none",O.innerHTML="Show advanced colors ▼",y(),t();var o=safeGetJSON(window.USER_THEMES_KEY,{});o[h]?(B.value=h,L=h,c(h)):(B.value="",S.value="",M.value=h,r(h)),p.style.display=L?"":"none",E.classList.add("show")}var a=document.getElementById("theme-customize-btn");a&&a.addEventListener("click",function(){e()}),document.getElementById("theme-builder-save").addEventListener("click",function(){var o=f(),i=S.value.trim();if(!i){showNotification("Please enter a theme name","warning",3e3),S.focus();return}var n=safeGetJSON(window.USER_THEMES_KEY,{}),s,l=null;if(L){s=L;var m=window.slugifyThemeName(i,L);if(m!==L){l=L,delete n[L];var k=window.THEMES.indexOf(L);k!==-1&&window.THEMES.splice(k,1),delete window.THEME_COLORS[L],s=m}}else s=window.slugifyThemeName(i);var j={name:i};T.checked&&(j.lightBg=!0),window.THEME_PROPS.forEach(function(F){o[F]&&(j[F]=o[F])}),n[s]=j,safeSet(window.USER_THEMES_KEY,JSON.stringify(n)),window.clearCustomProperties(),window.injectUserThemeStyles(),window.applyTheme(s),E.classList.remove("show"),v();var _={};window.THEME_PROPS.forEach(function(F){o[F]&&(_[F]=o[F])}),l&&secureFetch("/api/v1/themes/"+l,{method:"DELETE"}).catch(function(){}),secureFetch("/api/v1/themes/"+s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:i,colors:_,lightBg:T.checked})}).then(function(){showNotification(i+" theme saved","success",3e3)}).catch(function(){showNotification(i+" theme saved locally (server sync failed)","warning",3e3)})}),document.getElementById("theme-builder-cancel").addEventListener("click",function(){E.classList.remove("show"),window.clearCustomProperties(),h&&window.applyTheme(h)}),document.getElementById("theme-builder-delete").addEventListener("click",function(){if(L){var o=safeGetJSON(window.USER_THEMES_KEY,{}),i=o[L]?o[L].name:L;if(confirm('Delete "'+i+'" theme?')){var n=L;delete o[n],safeSet(window.USER_THEMES_KEY,JSON.stringify(o));var s=window.THEMES.indexOf(n);s!==-1&&window.THEMES.splice(s,1),delete window.THEME_COLORS[n],window.clearCustomProperties(),window.injectUserThemeStyles();var l=h&&h!==n?h:"dark";window.applyTheme(l),L=null,E.classList.remove("show"),v(),secureFetch("/api/v1/themes/"+n,{method:"DELETE"}).then(function(){showNotification(i+" theme deleted","success",3e3)}).catch(function(){showNotification(i+" theme deleted locally (server sync failed)","warning",3e3)})}}}),document.getElementById("theme-builder-export").addEventListener("click",function(){if(!L){showNotification("Save the theme first, then export","warning",3e3);return}var o=safeGetJSON(window.USER_THEMES_KEY,{}),i=o[L];if(i){var n={_dashcaddy_theme:!0,version:"1.0",exportDate:new Date().toISOString(),slug:L,name:i.name,lightBg:i.lightBg||!1,colors:{}};window.THEME_PROPS.forEach(function(k){i[k]&&(n.colors[k]=i[k])});var s=new Blob([JSON.stringify(n,null,2)],{type:"application/json"}),l=URL.createObjectURL(s),m=document.createElement("a");m.href=l,m.download=L+"-theme.json",document.body.appendChild(m),m.click(),document.body.removeChild(m),URL.revokeObjectURL(l),showNotification("Theme exported as "+L+"-theme.json","success",3e3)}}),document.getElementById("theme-builder-import").addEventListener("click",function(){var o=document.createElement("input");o.type="file",o.accept=".json",o.onchange=function(i){var n=i.target.files[0];if(n){var s=new FileReader;s.onload=function(l){try{var m=JSON.parse(l.target.result),k,j,_;if(m._dashcaddy_theme&&m.colors)k=m.name||"Imported",j=m.colors,_=m.lightBg||!1;else if(m.name&&(m.bg||m["card-base"]))k=m.name,j={},window.THEME_PROPS.forEach(function(F){m[F]&&(j[F]=m[F])}),_=m.lightBg||!1;else throw new Error("Not a valid DashCaddy theme file");S.value=k,T.checked=!!_,L=null,B.value="",A={},b.forEach(function(F){var q=j[F.dataset.prop]||"#000000";F.value=q;var J=E.querySelector('[data-hex="'+F.dataset.prop+'"]');J&&(J.textContent=q.toUpperCase()),F.dataset.advanced&&j[F.dataset.prop]&&(A[F.dataset.prop]=!0)}),z(),d(),w(f()),p.style.display="none",showNotification('"'+k+'" loaded into builder. Click Save to keep it.',"success",5e3)}catch(F){showNotification("Import failed: "+F.message,"error",5e3)}},s.readAsText(n)}},o.click()}),wireModal(E),E.addEventListener("click",function(o){o.target===E&&(window.clearCustomProperties(),h&&window.applyTheme(h))})})(),(function(){injectModal("license-modal",`<div id="license-modal" class="weather-modal">
|
|
<div class="weather-modal-content" style="min-width: 420px; max-width: 520px;">
|
|
<h3>DashCaddy License</h3>
|
|
<p style="font-size: 0.85rem; color: var(--muted); margin: 0 0 16px;">
|
|
Activate a license code to unlock premium features.
|
|
</p>
|
|
|
|
<div id="license-status-section" style="margin-bottom: 16px;">
|
|
<div id="license-badge" style="display: inline-flex; align-items: center; gap: 6px; padding: 6px 14px; border-radius: 20px; font-size: 0.85rem; font-weight: 600; margin-bottom: 12px;">
|
|
<span id="license-badge-icon"></span>
|
|
<span id="license-badge-text"></span>
|
|
</div>
|
|
<div id="license-details" style="font-size: 0.85rem; color: var(--muted); line-height: 1.6;"></div>
|
|
</div>
|
|
|
|
<div id="license-activate-section">
|
|
<label class="form-label-bold">License Code:</label>
|
|
<input type="text" id="license-code-input" placeholder="DC-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX"
|
|
maxlength="35" spellcheck="false" autocomplete="off"
|
|
style="width: 100%; padding: 10px 12px; border: 1px solid var(--border); border-radius: 4px; background: var(--card-bg); color: var(--fg); font-size: 1rem; font-family: monospace; letter-spacing: 1px;" />
|
|
<p class="tiny-hint">Enter your license code to activate premium features</p>
|
|
</div>
|
|
|
|
<div id="license-features" style="margin-top: 16px;">
|
|
<label class="form-label-bold" style="margin-bottom: 8px; display: block;">Premium Features:</label>
|
|
<div id="license-feature-list" style="display: grid; gap: 8px;"></div>
|
|
</div>
|
|
|
|
<div id="license-error" style="display: none; margin-top: 12px; padding: 10px; border-radius: 4px; background: rgba(231,76,60,0.15); color: var(--bad-fg); font-size: 0.85rem;"></div>
|
|
<div id="license-success" style="display: none; margin-top: 12px; padding: 10px; border-radius: 4px; background: rgba(46,204,113,0.15); color: var(--ok-fg); font-size: 0.85rem;"></div>
|
|
|
|
<div class="weather-modal-buttons" style="margin-top: 16px;">
|
|
<button id="license-cancel">Close</button>
|
|
<button id="license-deactivate" class="btn-accent" style="display: none; background: var(--bad-bg); border-color: var(--bad-fg); color: var(--bad-fg);">Deactivate</button>
|
|
<button id="license-activate" class="btn-accent">Activate</button>
|
|
</div>
|
|
</div>
|
|
</div>`);const h=document.getElementById("license-modal"),L=document.getElementById("license-code-input"),A=document.getElementById("license-activate"),I=document.getElementById("license-deactivate"),D=document.getElementById("license-error"),R=document.getElementById("license-success"),H=document.getElementById("license-badge-icon"),P=document.getElementById("license-badge-text"),v=document.getElementById("license-badge"),C=document.getElementById("license-details"),x=document.getElementById("license-feature-list"),$=document.getElementById("license-activate-section");let E=null;function M(){D.style.display="none",R.style.display="none"}function S(f){M(),D.textContent=f,D.style.display="block"}function B(f){M(),R.textContent=f,R.style.display="block"}function U(f){if(E=f,f.active){v.style.background="rgba(46,204,113,0.15)",v.style.color="var(--ok-fg)",H.textContent="\u2605",P.textContent="Premium Active";const r=f.lifetime?"<div>License: <strong>LIFETIME</strong></div>":`<div>Expires: <strong>${new Date(f.expiresAt).toLocaleDateString()}</strong> (${f.daysRemaining} days remaining)</div>`;C.innerHTML=`
|
|
<div>Code: <code style="font-family: monospace;">${f.code||"***"}</code></div>
|
|
${r}
|
|
`,$.style.display="none",A.style.display="none",I.style.display=""}else v.style.background="rgba(149,165,166,0.15)",v.style.color="var(--muted)",H.textContent="\u2606",P.textContent=f.expired?"License Expired":"Free Tier",C.innerHTML=f.expired?"<div>Your license has expired. Enter a new code to renew.</div>":"<div>Enter a license code to unlock premium features.</div>",$.style.display="",A.style.display="",I.style.display="none";const g=f.premiumFeatures||{},z=new Set(f.features||[]);x.innerHTML=Object.entries(g).map(([r,c])=>`<div style="display: flex; align-items: center; gap: 8px; padding: 8px 12px; border-radius: 6px; background: var(--card-bg); border: 1px solid var(--border);">
|
|
<span style="font-size: 1.1rem;">${z.has(r)?"\u2705":"\u{1F512}"}</span>
|
|
<div>
|
|
<div style="font-weight: 600; font-size: 0.9rem;">${c.name}</div>
|
|
<div style="font-size: 0.78rem; color: var(--muted);">${c.description}</div>
|
|
</div>
|
|
</div>`).join("")}async function T(){try{const g=await(await fetch("/api/v1/license/status")).json();g.success&&(U(g.license),O(g.license))}catch(f){console.warn("Failed to load license status:",f.message)}}async function b(){const f=L.value.trim();if(!f){S("Please enter a license code.");return}M(),A.disabled=!0,A.textContent="Activating...";try{const z=await(await secureFetch("/api/v1/license/activate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:f})})).json();z.success?(B(z.message),L.value="",U(z.license),showNotification("License activated! Premium features unlocked.","success",5e3),O(z.license)):S(z.error||"Activation failed")}catch(g){S("Network error: "+g.message)}finally{A.disabled=!1,A.textContent="Activate"}}async function N(){if(confirm("Deactivate your license? You can reuse the code on another machine.")){I.disabled=!0,I.textContent="Deactivating...";try{const g=await(await secureFetch("/api/v1/license/deactivate",{method:"POST"})).json();g.success?(B(g.message),await T(),showNotification("License deactivated.","info",3e3),O({active:!1})):S(g.error||"Deactivation failed")}catch(f){S("Network error: "+f.message)}finally{I.disabled=!1,I.textContent="Deactivate"}}}function O(f){const g=document.getElementById("license-status-topbar"),z=document.getElementById("license-topbar-icon"),r=document.getElementById("license-topbar-text"),c=document.getElementById("license-topbar-time");if(g)if(g.className="license-status-topbar "+(f.active?"premium":"free"),f.active)if(z.textContent="\u2605",r.textContent="PREMIUM",f.lifetime)c.textContent="\xB7 LIFETIME";else{const d=f.daysRemaining;c.textContent=d!=null?"\xB7 "+d+"d remaining":""}else z.textContent="\u2606",r.textContent=f.expired?"EXPIRED":"FREE TIER",c.textContent=""}function p(){M(),T(),h.classList.add("show")}L.addEventListener("input",function(){let f=this.value.toUpperCase().replace(/[^A-Z0-9-]/g,"");if(f.length>this._prevLength&&(f=f.replace(/-/g,""),f.length>2&&!f.startsWith("DC")&&(f="DC"+f),f.startsWith("DC")&&f.length>2)){const g=["DC"],z=f.substring(2);for(let r=0;r<z.length;r+=5)g.push(z.substring(r,r+5));f=g.join("-")}this._prevLength=f.length,this.value=f}),A.addEventListener("click",b),I.addEventListener("click",N),L.addEventListener("keydown",f=>{f.key==="Enter"&&b()}),wireModal(h,document.getElementById("license-cancel"));const u=document.getElementById("license-status-topbar");u&&u.addEventListener("click",()=>window.openLicenseModal&&window.openLicenseModal()),window.openLicenseModal=p,window.checkPremiumFeature=async function(f){try{return(await(await fetch(`/api/v1/license/feature/${f}`)).json()).available}catch{return!1}},T().then(f=>{E&&O(E)})})(),(function(){"use strict";if(window.__dc_058_share_modal_loaded)return;window.__dc_058_share_modal_loaded=!0;const h=[{ms:3600*1e3,label:"1 hour"},{ms:1440*60*1e3,label:"24 hours"},{ms:10080*60*1e3,label:"7 days"}];injectModal("share-modal",`
|
|
<div id="share-modal" class="weather-modal" role="dialog" aria-labelledby="share-modal-title">
|
|
<div class="weather-modal-content" style="min-width: 460px; max-width: 580px;">
|
|
<h3 id="share-modal-title">Share <span id="share-modal-service-name">\u2026</span></h3>
|
|
<p style="font-size: 0.85rem; color: var(--muted); margin: 0 0 16px;">
|
|
Create a public link or Tailscale invite so someone outside your network can access this service.
|
|
</p>
|
|
|
|
<div class="share-tabs" style="display: flex; gap: 4px; margin-bottom: 16px; border-bottom: 1px solid var(--border);">
|
|
<button class="share-tab active" data-tab="public" type="button"
|
|
style="background: transparent; border: 0; border-bottom: 2px solid var(--accent); padding: 8px 14px; color: var(--fg); font-weight: 600; cursor: pointer;">
|
|
Public link
|
|
</button>
|
|
<button class="share-tab" data-tab="tailscale" type="button"
|
|
style="background: transparent; border: 0; border-bottom: 2px solid transparent; padding: 8px 14px; color: var(--muted); cursor: pointer;">
|
|
Tailscale invite
|
|
</button>
|
|
</div>
|
|
|
|
<div class="share-tab-panel" data-panel="public">
|
|
<label class="form-label-bold" for="share-public-ttl">Link duration:</label>
|
|
<select id="share-public-ttl" style="width: 100%; padding: 8px 10px; margin: 6px 0 12px; background: var(--input-bg); color: var(--fg); border: 1px solid var(--border); border-radius: 4px;">
|
|
${h.map(t=>`<option value="${t.ms}">${t.label}</option>`).join("")}
|
|
</select>
|
|
<button id="share-public-create" class="btn-accent" type="button"
|
|
style="width: 100%; padding: 10px; background: var(--accent); color: #04141f; border: 0; border-radius: 4px; font-weight: 600; cursor: pointer;">
|
|
Create share link
|
|
</button>
|
|
</div>
|
|
|
|
<div class="share-tab-panel" data-panel="tailscale" style="display: none;">
|
|
<label class="form-label-bold" for="share-ts-email">Recipient email:</label>
|
|
<input id="share-ts-email" type="email" placeholder="alice@example.com" autocomplete="off"
|
|
style="width: 100%; padding: 10px 12px; margin: 6px 0 12px; background: var(--card-bg); color: var(--fg); border: 1px solid var(--border); border-radius: 4px; font-size: 0.95rem;" />
|
|
<p style="font-size: 0.8rem; color: var(--muted); margin: 0 0 12px;">
|
|
A single-use Tailscale pre-auth key is generated and emailed. The device joins your tailnet and is routed to this service via Caddy.
|
|
</p>
|
|
<button id="share-ts-create" class="btn-accent" type="button"
|
|
style="width: 100%; padding: 10px; background: var(--accent); color: #04141f; border: 0; border-radius: 4px; font-weight: 600; cursor: pointer;">
|
|
Create Tailscale invite
|
|
</button>
|
|
</div>
|
|
|
|
<div id="share-issued" style="display: none; margin-top: 16px; padding: 12px; background: var(--card-bg); border: 1px solid var(--border); border-radius: 6px;">
|
|
<div style="font-size: 0.8rem; color: var(--muted); margin-bottom: 6px;">Share link:</div>
|
|
<div style="display: flex; gap: 6px; align-items: center;">
|
|
<input id="share-issued-url" type="text" readonly
|
|
style="flex: 1; padding: 8px 10px; background: var(--bg); color: var(--fg); border: 1px solid var(--border); border-radius: 4px; font-family: monospace; font-size: 0.85rem;" />
|
|
<button id="share-issued-copy" type="button"
|
|
style="padding: 8px 14px; background: var(--accent); color: #04141f; border: 0; border-radius: 4px; font-weight: 600; cursor: pointer;">
|
|
Copy
|
|
</button>
|
|
</div>
|
|
<div id="share-issued-meta" style="font-size: 0.8rem; color: var(--muted); margin-top: 8px;"></div>
|
|
</div>
|
|
|
|
<div id="share-error" style="display: none; margin-top: 12px; padding: 10px; border-radius: 4px; background: rgba(231,76,60,0.15); color: var(--bad-fg); font-size: 0.85rem;"></div>
|
|
<div id="share-success" style="display: none; margin-top: 12px; padding: 10px; border-radius: 4px; background: rgba(46,204,113,0.15); color: var(--ok-fg); font-size: 0.85rem;"></div>
|
|
|
|
<div id="share-outstanding" style="margin-top: 16px;">
|
|
<label class="form-label-bold">Outstanding shares for this service</label>
|
|
<div id="share-outstanding-list" style="margin-top: 6px; font-size: 0.85rem;"></div>
|
|
</div>
|
|
|
|
<div class="weather-modal-buttons" style="margin-top: 18px;">
|
|
<button id="share-cancel" type="button">Close</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`);const L=document.getElementById("share-modal"),A=document.getElementById("share-modal-service-name"),I=document.getElementById("share-issued"),D=document.getElementById("share-issued-url"),R=document.getElementById("share-issued-copy"),H=document.getElementById("share-issued-meta"),P=document.getElementById("share-error"),v=document.getElementById("share-success"),C=document.getElementById("share-outstanding-list"),x=document.getElementById("share-cancel"),$=document.getElementById("share-public-create"),E=document.getElementById("share-ts-create"),M=document.getElementById("share-ts-email"),S=document.getElementById("share-public-ttl");let B=null,U="public";function T(){P.style.display="none",v.style.display="none",I.style.display="none"}function b(t){v.style.display="none",I.style.display="none",P.textContent=t,P.style.display="block"}function N(t){P.style.display="none",v.textContent=t,v.style.display="block"}function O(){return window.location.origin}function p(t){return t.startsWith("http")?t:O()+t}function u(t){if(!t)return"";const e=new Date(t);return Number.isNaN(e.getTime())?"":e.toLocaleString()}function f(t){if(t<=0)return"expired";const e=Math.floor(t/36e5);if(e>=24)return`${Math.floor(e/24)}d ${e%24}h left`;const a=Math.floor(t%36e5/6e4);return`${e}h ${a}m left`}function g(t){U=t,T(),L.querySelectorAll(".share-tab").forEach(e=>{const a=e.dataset.tab===t;e.classList.toggle("active",a),e.style.borderBottomColor=a?"var(--accent)":"transparent",e.style.color=a?"var(--fg)":"var(--muted)",e.style.fontWeight=a?"600":"400"}),L.querySelectorAll(".share-tab-panel").forEach(e=>{e.style.display=e.dataset.panel===t?"":"none"})}async function z(){C.innerHTML='<span style="color: var(--muted);">Loading\u2026</span>';try{const t=await fetch("/api/v1/share",{credentials:"same-origin"});if(!t.ok){C.innerHTML='<span style="color: var(--muted);">No shares listed.</span>';return}const e=await t.json(),o=(e&&e.data||[]).filter(i=>i.serviceId===B.id);if(o.length===0){C.innerHTML='<span style="color: var(--muted);">No outstanding shares for this service.</span>';return}C.innerHTML=o.map(i=>{const n=i.expiresAt?f(new Date(i.expiresAt).getTime()-Date.now()):"";return`
|
|
<div class="share-row" data-share-id="${escapeHtml(i.id)}"
|
|
style="display: flex; align-items: center; gap: 8px; padding: 6px 0; border-bottom: 1px dashed var(--border);">
|
|
<span style="flex: 1;">
|
|
<strong>${i.kind==="tailscale"?"Tailscale":"Public"}</strong>
|
|
<span style="color: var(--muted);"> \xB7 expires ${escapeHtml(u(i.expiresAt))} (${n})</span>
|
|
</span>
|
|
<button class="share-revoke" data-share-id="${escapeHtml(i.id)}" type="button"
|
|
style="padding: 4px 10px; background: transparent; color: var(--bad-fg); border: 1px solid var(--bad-fg); border-radius: 4px; cursor: pointer; font-size: 0.8rem;">
|
|
Revoke
|
|
</button>
|
|
</div>
|
|
`}).join(""),C.querySelectorAll(".share-revoke").forEach(i=>{i.addEventListener("click",()=>r(i.dataset.shareId))})}catch{C.innerHTML='<span style="color: var(--muted);">Could not load outstanding shares.</span>'}}async function r(t){try{const e=await fetch(`/api/v1/share/${encodeURIComponent(t)}`,{method:"DELETE",credentials:"same-origin"});if(!e.ok){const a=await e.json().catch(()=>({}));b(a&&a.error||`Revoke failed (HTTP ${e.status}).`);return}N("Share revoked."),z()}catch{b("Network error while revoking.")}}async function c(){if(!B)return;T(),$.disabled=!0;const t=$.textContent;$.textContent="Creating\u2026";try{const e=parseInt(S.value,10),a=await fetch("/api/v1/share",{method:"POST",credentials:"same-origin",headers:{"Content-Type":"application/json"},body:JSON.stringify({serviceId:B.id,ttlMs:e})}),o=await a.json().catch(()=>({}));if(!a.ok||!o.success){w(a.status,o);return}const i=o.data.urlPath;D.value=p(i),H.textContent=`Public link \xB7 expires ${u(o.data.expiresAt)}`,I.style.display="block",N("Share link created."),z()}catch{b("Network error while creating share.")}finally{$.disabled=!1,$.textContent=t}}async function d(){if(!B)return;const t=(M.value||"").trim();if(!t||!t.includes("@")){b("A valid recipient email is required.");return}T(),E.disabled=!0;const e=E.textContent;E.textContent="Creating\u2026";try{const a=await fetch("/api/v1/share/tailscale",{method:"POST",credentials:"same-origin",headers:{"Content-Type":"application/json"},body:JSON.stringify({serviceId:B.id,email:t})}),o=await a.json().catch(()=>({}));if(!a.ok||!o.success){w(a.status,o);return}const i=o.data&&o.data.urlPath;i?(D.value=p(i),H.textContent=`Tailscale invite \xB7 emailed to ${t} (or use this URL manually if delivery failed).`):(D.value="",H.textContent=`Tailscale invite sent to ${t}.`),I.style.display="block",N("Tailscale invite created."),M.value="",z()}catch{b("Network error while creating Tailscale invite.")}finally{E.disabled=!1,E.textContent=e}}function w(t,e){const a=e&&e.error||"";if(t===402){b("Share is a Pro feature. Activate a license to unlock.");return}if(t===400&&/tailscale/i.test(a)){b("Tailscale is not configured on this host. Set up Tailscale in the dashboard first.");return}if(t===403){b("You do not have permission to share services.");return}if(t===404){b("Service not found. It may have been deleted.");return}b(a||`Request failed (HTTP ${t}).`)}function y(t){!t||!t.id||(B={id:t.id,name:t.name||t.id},A.textContent=B.name,T(),g("public"),M.value="",S.value=String(h[1].ms),L.classList.add("show"),z())}L.querySelectorAll(".share-tab").forEach(t=>{t.addEventListener("click",()=>g(t.dataset.tab))}),$.addEventListener("click",c),E.addEventListener("click",d),x.addEventListener("click",()=>L.classList.remove("show")),wireModal(L,x),R.addEventListener("click",async()=>{const t=D.value;if(t)try{navigator.clipboard&&navigator.clipboard.writeText?await navigator.clipboard.writeText(t):(D.select(),document.execCommand("copy"));const e=R.textContent;R.textContent="Copied!",setTimeout(()=>{R.textContent=e},1200)}catch{b("Could not copy to clipboard. Select the URL manually.")}}),window.openShareModal=y})(),(function(){"use strict";const h="dashcaddy-language",A=["en","ar","bn","cs","da","de","el","es","fa","fi","fr","hi","hu","id","it","ja","ko","ms","nl","no","pl","pt","ro","ru","sv","th","tr","uk","ur","vi","zh"],I={en:"English",ar:"\u0627\u0644\u0639\u0631\u0628\u064A\u0629",bn:"\u09AC\u09BE\u0982\u09B2\u09BE",cs:"\u010Ce\u0161tina",da:"Dansk",de:"Deutsch",el:"\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC",es:"Espa\xF1ol",fa:"\u0641\u0627\u0631\u0633\u06CC",fi:"Suomi",fr:"Fran\xE7ais",hi:"\u0939\u093F\u0928\u094D\u0926\u0940",hu:"Magyar",id:"Bahasa Indonesia",it:"Italiano",ja:"\u65E5\u672C\u8A9E",ko:"\uD55C\uAD6D\uC5B4",ms:"Bahasa Melayu",nl:"Nederlands",no:"Norsk",pl:"Polski",pt:"Portugu\xEAs",ro:"Rom\xE2n\u0103",ru:"\u0420\u0443\u0441\u0441\u043A\u0438\u0439",sv:"Svenska",th:"\u0E44\u0E17\u0E22",tr:"T\xFCrk\xE7e",uk:"\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430",ur:"\u0627\u0631\u062F\u0648",vi:"Ti\u1EBFng Vi\u1EC7t",zh:"\u4E2D\u6587"},D=new Set(["ar","fa","ur"]);function R(){try{const b=localStorage.getItem(h);if(b&&A.includes(b))return b}catch{}return"en"}let H=R(),P={},v=!1,C=0;async function x(b,N){if(N===void 0&&(N=++C),b==="en"){P={},v=!0;return}try{const O=await fetch(`/api/v1/i18n/translations/${b}`);if(N!==C)return;if(O.ok){const p=await O.json();if(N!==C)return;P=p.translations||{},v=!0}else P={},v=!1}catch(O){console.warn("[i18n] Failed to load translations for",b,O),N===C&&(P={},v=!1)}}function $(b){return H==="en"?b:P[b]||b}function E(b){if(!A.includes(b))return;H=b;try{localStorage.setItem(h,b)}catch{}const N=D.has(b);document.documentElement.dir=N?"rtl":"ltr",document.documentElement.lang=b;const O=++C;x(b,O).then(()=>{O===C&&S()})}function M(){return H}function S(){document.querySelectorAll("[data-i18n]").forEach(b=>{const N=b.getAttribute("data-i18n");b.textContent=$(N)}),document.querySelectorAll("[data-i18n-placeholder]").forEach(b=>{const N=b.getAttribute("data-i18n-placeholder");b.placeholder=$(N)}),document.querySelectorAll("[data-i18n-title]").forEach(b=>{const N=b.getAttribute("data-i18n-title");b.title=$(N)})}function B(){const b=document.querySelector(".header-actions")||document.querySelector("#auth-settings-btn")?.parentElement||document.querySelector(".top-bar-actions");if(!b){const N=document.getElementById("auth-settings-btn");return N&&N.parentElement?U(N.parentElement):null}return U(b)}function U(b){if(document.getElementById("dc-lang-selector"))return;const N=document.createElement("div");N.id="dc-lang-selector",N.style.cssText="display: inline-flex; align-items: center; gap: 4px; margin: 0 8px; position: relative;";const O=document.createElement("button");O.id="dc-lang-btn",O.className="lang-selector-btn",O.style.cssText="background: var(--card-base, #2a2a3e); border: 1px solid var(--border, #3a3a4e); color: var(--text-primary, #e0e0e0); padding: 6px 10px; border-radius: 6px; cursor: pointer; font-size: 0.8rem; display: flex; align-items: center; gap: 4px;",O.innerHTML=`\u{1F310} <span class="lang-current">${H.toUpperCase()}</span>`,O.title="Select Language";const p=document.createElement("div");return p.id="dc-lang-dropdown",p.style.cssText="display: none; position: absolute; top: 100%; right: 0; margin-top: 4px; background: var(--card-base, #2a2a3e); border: 1px solid var(--border, #3a3a4e); border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.3); z-index: 9999; min-width: 160px; max-height: 320px; overflow-y: auto;",A.forEach(u=>{const f=document.createElement("div");f.className="lang-option",f.style.cssText="padding: 8px 14px; cursor: pointer; display: flex; align-items: center; gap: 8px; font-size: 0.85rem; color: var(--text-primary, #e0e0e0);",f.onmouseenter=()=>f.style.background="var(--card-hover, rgba(255,255,255,0.05))",f.onmouseleave=()=>f.style.background="transparent";const g=document.createElement("span");g.textContent=u===H?"\u2713":"",g.style.cssText="width: 16px; color: var(--ok-fg, #4ade80);";const z=document.createElement("span");z.textContent=I[u],f.appendChild(g),f.appendChild(z),f.onclick=()=>{E(u),p.style.display="none",O.querySelector(".lang-current").textContent=u.toUpperCase(),p.querySelectorAll(".lang-option").forEach((r,c)=>{r.querySelector("span").textContent=A[c]===u?"\u2713":""}),window.showNotification&&window.showNotification(`Language: ${I[u]}`,"info")},p.appendChild(f)}),O.onclick=u=>{u.stopPropagation(),p.style.display=p.style.display==="none"?"block":"none"},document.addEventListener("click",u=>{N.contains(u.target)||(p.style.display="none")}),N.appendChild(O),N.appendChild(p),b.insertBefore(N,b.firstChild),N}function T(){const b=D.has(H);document.documentElement.dir=b?"rtl":"ltr",document.documentElement.lang=H;function N(){if(B(),H!=="en"){const O=++C;x(H,O).then(()=>{O===C&&S()})}}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",N):N()}window.DCI18n={t:$,setLanguage:E,getLanguage:M,applyTranslations:S,loadTranslations:x},T()})();
|
|
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiPHN0ZGluPiJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLy8gTG9nbyBDdXN0b21pemF0aW9uIFN5c3RlbVxuKGZ1bmN0aW9uKCkge1xuICAvLyBJbmplY3QgbW9kYWwgSFRNTFxuICBpbmplY3RNb2RhbCgnbG9nby1tb2RhbCcsIGA8ZGl2IGlkPVwibG9nby1tb2RhbFwiIGNsYXNzPVwid2VhdGhlci1tb2RhbFwiPlxuICAgIDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsLWNvbnRlbnRcIiBzdHlsZT1cIm1pbi13aWR0aDogNDAwcHg7IG1heC13aWR0aDogNTIwcHg7XCI+XG4gICAgICA8aDM+RGFzaGJvYXJkIFNldHRpbmdzPC9oMz5cbiAgICAgIDxwIHN0eWxlPVwiZm9udC1zaXplOiAwLjg1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW46IDAgMCAxNnB4O1wiPlxuICAgICAgICBDdXN0b21pemUgeW91ciBkYXNoYm9hcmQncyBhcHBlYXJhbmNlIGFuZCBzeXN0ZW0gcHJlZmVyZW5jZXMuXG4gICAgICA8L3A+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJtYi0xNlwiPlxuICAgICAgICA8bGFiZWwgZm9yPVwiZGFzaGJvYXJkLXRpdGxlXCIgY2xhc3M9XCJmb3JtLWxhYmVsLWJvbGRcIj5EYXNoYm9hcmQgVGl0bGU6PC9sYWJlbD5cbiAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgaWQ9XCJkYXNoYm9hcmQtdGl0bGVcIiBwbGFjZWhvbGRlcj1cIkRhc2hDYWRkeVwiIG1heGxlbmd0aD1cIjUwXCIgc3R5bGU9XCJ3aWR0aDogMTAwJTsgcGFkZGluZzogMTBweCAxMnB4OyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBib3JkZXItcmFkaXVzOiA0cHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmcpOyBjb2xvcjogdmFyKC0tZmcpOyBmb250LXNpemU6IDFyZW07XCIgLz5cbiAgICAgICAgPHAgY2xhc3M9XCJ0aW55LWhpbnRcIj5TaG93biBpbiBicm93c2VyIHRhYiBhbmQgaGVhZGVyIChtYXggNTAgY2hhcmFjdGVycyk8L3A+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGhyIGNsYXNzPVwiaHItZGl2aWRlclwiIC8+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJtYi0xNlwiPlxuICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsLWJvbGRcIj5Mb2dvOjwvbGFiZWw+XG4gICAgICAgIDxwIGNsYXNzPVwidGlueS1oaW50XCIgc3R5bGU9XCJtYXJnaW4tdG9wOiAycHg7XCI+U2VwYXJhdGUgbG9nb3MgZm9yIGRhcmsgYW5kIGxpZ2h0IHRoZW1lcywgb3IgdXNlIHRoZSBzYW1lIGZvciBib3RoLjwvcD5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgZ2FwOiAxMnB4OyBtYXJnaW4tYm90dG9tOiAxMnB4O1wiPlxuICAgICAgICA8ZGl2IHN0eWxlPVwiZmxleDogMTsgdGV4dC1hbGlnbjogY2VudGVyOyBwYWRkaW5nOiAxNnB4IDEwcHg7IGJvcmRlci1yYWRpdXM6IDhweDsgYmFja2dyb3VuZDogIzFhMWEyZTsgYm9yZGVyOiAxcHggc29saWQgcmdiYSgyNTUsMjU1LDI1NSwuMSk7XCI+XG4gICAgICAgICAgPGltZyBpZD1cImxvZ28tcHJldmlldy1kYXJrXCIgc3JjPVwiL2Fzc2V0cy9kYXNoY2FkZHktbG9nby1kYXJrLnBuZ1wiIGFsdD1cIkRhcmsgdGhlbWUgbG9nb1wiIHN0eWxlPVwibWF4LWhlaWdodDogNjBweDsgbWF4LXdpZHRoOiAxMDAlO1wiIC8+XG4gICAgICAgICAgPHAgc3R5bGU9XCJmb250LXNpemU6IDAuNjVyZW07IGNvbG9yOiAjOWFhNmJmOyBtYXJnaW4tdG9wOiA2cHg7XCI+RGFyayB0aGVtZXM8L3A+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IHN0eWxlPVwiZmxleDogMTsgdGV4dC1hbGlnbjogY2VudGVyOyBwYWRkaW5nOiAxNnB4IDEwcHg7IGJvcmRlci1yYWRpdXM6IDhweDsgYmFja2dyb3VuZDogI2YwZjBmMDsgYm9yZGVyOiAxcHggc29saWQgcmdiYSgwLDAsMCwuMSk7XCI+XG4gICAgICAgICAgPGltZyBpZD1cImxvZ28tcHJldmlldy1saWdodFwiIHNyYz1cIi9hc3NldHMvZGFzaGNhZGR5LWxvZ28tbGlnaHQucG5nXCIgYWx0PVwiTGlnaHQgdGhlbWUgbG9nb1wiIHN0eWxlPVwibWF4LWhlaWdodDogNjBweDsgbWF4LXdpZHRoOiAxMDAlO1wiIC8+XG4gICAgICAgICAgPHAgc3R5bGU9XCJmb250LXNpemU6IDAuNjVyZW07IGNvbG9yOiAjNWY2YjdhOyBtYXJnaW4tdG9wOiA2cHg7XCI+TGlnaHQgdGhlbWVzPC9wPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICAgPHAgaWQ9XCJsb2dvLXN0YXR1c1wiIHN0eWxlPVwiZm9udC1zaXplOiAwLjc1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW4tYm90dG9tOiAxMnB4OyB0ZXh0LWFsaWduOiBjZW50ZXI7XCI+VXNpbmcgZGVmYXVsdCBsb2dvczwvcD5cblxuICAgICAgPGRpdiBjbGFzcz1cIm1iLTE2XCI+XG4gICAgICAgIDxsYWJlbCBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogOHB4OyBmb250LXNpemU6IDAuODJyZW07IGN1cnNvcjogcG9pbnRlcjsgdXNlci1zZWxlY3Q6IG5vbmU7XCI+XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGlkPVwibG9nby1zYW1lLWJvdGhcIiAvPiBVc2Ugc2FtZSBsb2dvIGZvciBib3RoXG4gICAgICAgIDwvbGFiZWw+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBpZD1cImxvZ28tZHVhbC11cGxvYWRzXCIgY2xhc3M9XCJtYi0xNlwiIHN0eWxlPVwiZGlzcGxheTogZmxleDsgZ2FwOiAxMnB4O1wiPlxuICAgICAgICA8ZGl2IHN0eWxlPVwiZmxleDogMTtcIj5cbiAgICAgICAgICA8bGFiZWwgZm9yPVwibG9nby11cGxvYWQtZGFya1wiIHN0eWxlPVwiZGlzcGxheTogYmxvY2s7IG1hcmdpbi1ib3R0b206IDZweDsgZm9udC1zaXplOiAwLjhyZW07XCI+RGFyayB0aGVtZSBsb2dvOjwvbGFiZWw+XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJmaWxlXCIgaWQ9XCJsb2dvLXVwbG9hZC1kYXJrXCIgYWNjZXB0PVwiaW1hZ2UvKlwiIGNsYXNzPVwiaW5wdXQtY2FyZC1hbHRcIiBzdHlsZT1cImZvbnQtc2l6ZTogMC43NXJlbTtcIiAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBzdHlsZT1cImZsZXg6IDE7XCI+XG4gICAgICAgICAgPGxhYmVsIGZvcj1cImxvZ28tdXBsb2FkLWxpZ2h0XCIgc3R5bGU9XCJkaXNwbGF5OiBibG9jazsgbWFyZ2luLWJvdHRvbTogNnB4OyBmb250LXNpemU6IDAuOHJlbTtcIj5MaWdodCB0aGVtZSBsb2dvOjwvbGFiZWw+XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJmaWxlXCIgaWQ9XCJsb2dvLXVwbG9hZC1saWdodFwiIGFjY2VwdD1cImltYWdlLypcIiBjbGFzcz1cImlucHV0LWNhcmQtYWx0XCIgc3R5bGU9XCJmb250LXNpemU6IDAuNzVyZW07XCIgLz5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBpZD1cImxvZ28tc2luZ2xlLXVwbG9hZFwiIGNsYXNzPVwibWItMTZcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCI+XG4gICAgICAgIDxsYWJlbCBmb3I9XCJsb2dvLXVwbG9hZC1zaW5nbGVcIiBzdHlsZT1cImRpc3BsYXk6IGJsb2NrOyBtYXJnaW4tYm90dG9tOiA2cHg7IGZvbnQtc2l6ZTogMC44cmVtO1wiPlVwbG9hZCBsb2dvOjwvbGFiZWw+XG4gICAgICAgIDxpbnB1dCB0eXBlPVwiZmlsZVwiIGlkPVwibG9nby11cGxvYWQtc2luZ2xlXCIgYWNjZXB0PVwiaW1hZ2UvKlwiIGNsYXNzPVwiaW5wdXQtY2FyZC1hbHRcIiAvPlxuICAgICAgICA8cCBjbGFzcz1cInRpbnktaGludFwiPlRoaXMgbG9nbyB3aWxsIGJlIHVzZWQgb24gYWxsIHRoZW1lczwvcD5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGNsYXNzPVwibWItMTZcIj5cbiAgICAgICAgPGxhYmVsIHN0eWxlPVwiZGlzcGxheTogYmxvY2s7IG1hcmdpbi1ib3R0b206IDhweDtcIj5Mb2dvIFBvc2l0aW9uOjwvbGFiZWw+XG4gICAgICAgIDxkaXYgaWQ9XCJsb2dvLXBvc2l0aW9uLWJ0bnNcIiBjbGFzcz1cImZsZXgtcm93LWdhcFwiPlxuICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGRhdGEtcG9zPVwibGVmdFwiIGNsYXNzPVwibG9nby1wb3MtYnRuIGJ0bi1vcHRpb25cIj5MZWZ0PC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgZGF0YS1wb3M9XCJjZW50ZXJcIiBjbGFzcz1cImxvZ28tcG9zLWJ0biBidG4tb3B0aW9uXCI+Q2VudGVyPC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgZGF0YS1wb3M9XCJyaWdodFwiIGNsYXNzPVwibG9nby1wb3MtYnRuIGJ0bi1vcHRpb25cIj5SaWdodDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8aHIgY2xhc3M9XCJoci1kaXZpZGVyXCIgLz5cblxuICAgICAgPGRpdiBjbGFzcz1cIm1iLTE2XCI+XG4gICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwtYm9sZFwiPkZhdmljb24gKEJyb3dzZXIgVGFiIEljb24pOjwvbGFiZWw+XG4gICAgICAgIDxkaXYgaWQ9XCJmYXZpY29uLXByZXZpZXctY29udGFpbmVyXCIgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDEycHg7IG1hcmdpbi1ib3R0b206IDhweDsgcGFkZGluZzogMTJweDsgYm9yZGVyLXJhZGl1czogNnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJnKTtcIj5cbiAgICAgICAgICA8aW1nIGlkPVwiZmF2aWNvbi1wcmV2aWV3XCIgc3JjPVwiL2Fzc2V0cy9kYXNoY2FkZHktZmF2aWNvbi5pY29cIiBhbHQ9XCJDdXJyZW50IGZhdmljb25cIiBzdHlsZT1cIndpZHRoOiAzMnB4OyBoZWlnaHQ6IDMycHg7IGltYWdlLXJlbmRlcmluZzogcGl4ZWxhdGVkO1wiIG9uZXJyb3I9XCJ0aGlzLnNyYz0nZGF0YTppbWFnZS9zdmcreG1sLDxzdmcgeG1sbnM9JTIyaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmclMjIgdmlld0JveD0lMjIwIDAgMzIgMzIlMjI+PHJlY3QgZmlsbD0lMjIlMjM2NjclMjIgd2lkdGg9JTIyMzIlMjIgaGVpZ2h0PSUyMjMyJTIyIHJ4PSUyMjQlMjIvPjwvc3ZnPidcIiAvPlxuICAgICAgICAgIDxzcGFuIGlkPVwiZmF2aWNvbi1zdGF0dXNcIiBjbGFzcz1cInRleHQtdGlueS1tdXRlZFwiPlVzaW5nIERhc2hDYWRkeSBmYXZpY29uPC9zcGFuPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGlucHV0IHR5cGU9XCJmaWxlXCIgaWQ9XCJmYXZpY29uLXVwbG9hZFwiIGFjY2VwdD1cImltYWdlL3BuZyxpbWFnZS9zdmcreG1sXCIgY2xhc3M9XCJpbnB1dC1jYXJkLWFsdFwiIC8+XG4gICAgICAgIDxwIGNsYXNzPVwidGlueS1oaW50XCI+VXBsb2FkIFBORyBvciBTVkcgLSBhdXRvbWF0aWNhbGx5IGNvbnZlcnRlZCB0byBJQ088L3A+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGhyIGNsYXNzPVwiaHItZGl2aWRlclwiIC8+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJtYi0xNlwiPlxuICAgICAgICA8bGFiZWwgZm9yPVwic2V0dGluZ3MtdGltZXpvbmVcIiBjbGFzcz1cImZvcm0tbGFiZWwtYm9sZFwiPlRpbWV6b25lOjwvbGFiZWw+XG4gICAgICAgIDxzZWxlY3QgaWQ9XCJzZXR0aW5ncy10aW1lem9uZVwiIHN0eWxlPVwid2lkdGg6IDEwMCU7IHBhZGRpbmc6IDEwcHggMTJweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgYm9yZGVyLXJhZGl1czogNHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJnKTsgY29sb3I6IHZhcigtLWZnKTsgZm9udC1zaXplOiAxcmVtO1wiPlxuICAgICAgICAgIDwhLS0gUG9wdWxhdGVkIGJ5IEpTIHdpdGggSUFOQSB0aW1lem9uZXMgLS0+XG4gICAgICAgIDwvc2VsZWN0PlxuICAgICAgICA8cCBjbGFzcz1cInRpbnktaGludFwiPlVzZWQgYnkgYWxsIGRlcGxveWVkIGNvbnRhaW5lcnMuIENoYW5nZXMgYXBwbHkgdG8gbmV3IGRlcGxveW1lbnRzLjwvcD5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGNsYXNzPVwid2VhdGhlci1tb2RhbC1idXR0b25zXCI+XG4gICAgICAgIDxidXR0b24gaWQ9XCJsb2dvLXJlc2V0XCIgc3R5bGU9XCJiYWNrZ3JvdW5kOiBjb2xvci1taXgoaW4gc3JnYiwgI2VmNDQ0NCAyMCUsIHRyYW5zcGFyZW50KTsgYm9yZGVyLWNvbG9yOiAjZWY0NDQ0OyBjb2xvcjogI2VmNDQ0NDtcIj5SZXNldCB0byBEZWZhdWx0PC9idXR0b24+XG4gICAgICAgIDxidXR0b24gaWQ9XCJsb2dvLWNhbmNlbFwiPkNhbmNlbDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIGlkPVwibG9nby1zYXZlXCIgY2xhc3M9XCJidG4tYWNjZW50XCI+U2F2ZTwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PmApO1xuXG4gIGNvbnN0IGxvZ29Nb2RhbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsb2dvLW1vZGFsJyk7XG4gIGNvbnN0IHByZXZpZXdEYXJrID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2xvZ28tcHJldmlldy1kYXJrJyk7XG4gIGNvbnN0IHByZXZpZXdMaWdodCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsb2dvLXByZXZpZXctbGlnaHQnKTtcbiAgY29uc3QgbG9nb1N0YXR1cyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsb2dvLXN0YXR1cycpO1xuICBjb25zdCBzYW1lQm90aENoZWNrYm94ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2xvZ28tc2FtZS1ib3RoJyk7XG4gIGNvbnN0IGR1YWxVcGxvYWRzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2xvZ28tZHVhbC11cGxvYWRzJyk7XG4gIGNvbnN0IHNpbmdsZVVwbG9hZCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsb2dvLXNpbmdsZS11cGxvYWQnKTtcbiAgY29uc3QgdXBsb2FkRGFyayA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsb2dvLXVwbG9hZC1kYXJrJyk7XG4gIGNvbnN0IHVwbG9hZExpZ2h0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2xvZ28tdXBsb2FkLWxpZ2h0Jyk7XG4gIGNvbnN0IHVwbG9hZFNpbmdsZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsb2dvLXVwbG9hZC1zaW5nbGUnKTtcbiAgY29uc3QgYnJhbmRMb2dvRGFyayA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNicmFuZCAuYnJhbmQtbG9nby1kYXJrJyk7XG4gIGNvbnN0IGJyYW5kTG9nb0xpZ2h0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JyYW5kIC5icmFuZC1sb2dvLWxpZ2h0Jyk7XG4gIGNvbnN0IHRvcFJvdyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy50b3Atcm93Jyk7XG4gIGNvbnN0IGRhc2hib2FyZFRpdGxlSW5wdXQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGFzaGJvYXJkLXRpdGxlJyk7XG4gIGNvbnN0IERFRkFVTFRfVElUTEUgPSBEQy5OQU1FO1xuXG4gIGxldCBwZW5kaW5nRGFya0RhdGEgPSBudWxsO1xuICBsZXQgcGVuZGluZ0xpZ2h0RGF0YSA9IG51bGw7XG4gIGxldCBwZW5kaW5nU2luZ2xlRGF0YSA9IG51bGw7XG4gIGxldCBjdXJyZW50UG9zaXRpb24gPSAnbGVmdCc7XG4gIGxldCBjdXJyZW50VGl0bGUgPSBERUZBVUxUX1RJVExFO1xuXG4gIC8vIFRvZ2dsZSBiZXR3ZWVuIGR1YWwgYW5kIHNpbmdsZSB1cGxvYWQgbW9kZVxuICBzYW1lQm90aENoZWNrYm94Py5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCAoKSA9PiB7XG4gICAgaWYgKHNhbWVCb3RoQ2hlY2tib3guY2hlY2tlZCkge1xuICAgICAgZHVhbFVwbG9hZHMuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgIHNpbmdsZVVwbG9hZC5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gICAgICAvLyBDbGVhciBpbmRpdmlkdWFsIHBlbmRpbmcgZGF0YVxuICAgICAgcGVuZGluZ0RhcmtEYXRhID0gbnVsbDtcbiAgICAgIHBlbmRpbmdMaWdodERhdGEgPSBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICBkdWFsVXBsb2Fkcy5zdHlsZS5kaXNwbGF5ID0gJ2ZsZXgnO1xuICAgICAgc2luZ2xlVXBsb2FkLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICBwZW5kaW5nU2luZ2xlRGF0YSA9IG51bGw7XG4gICAgfVxuICB9KTtcblxuICAvLyBSZWFkIGZpbGUgYXMgZGF0YSBVUkwgaGVscGVyXG4gIGZ1bmN0aW9uIHJlYWRGaWxlQXNEYXRhVVJMKGZpbGUsIGNhbGxiYWNrKSB7XG4gICAgaWYgKCFmaWxlIHx8ICFmaWxlLnR5cGUuc3RhcnRzV2l0aCgnaW1hZ2UvJykpIHtcbiAgICAgIHNob3dOb3RpZmljYXRpb24oJ1BsZWFzZSBzZWxlY3QgYW4gaW1hZ2UgZmlsZScsICd3YXJuaW5nJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgcmVhZGVyLm9ubG9hZCA9IChlKSA9PiBjYWxsYmFjayhlLnRhcmdldC5yZXN1bHQpO1xuICAgIHJlYWRlci5yZWFkQXNEYXRhVVJMKGZpbGUpO1xuICB9XG5cbiAgLy8gVXBsb2FkIGhhbmRsZXJzXG4gIHVwbG9hZERhcms/LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIChlKSA9PiB7XG4gICAgcmVhZEZpbGVBc0RhdGFVUkwoZS50YXJnZXQuZmlsZXNbMF0sIChkYXRhKSA9PiB7XG4gICAgICBwZW5kaW5nRGFya0RhdGEgPSBkYXRhO1xuICAgICAgcHJldmlld0Rhcmsuc3JjID0gZGF0YTtcbiAgICAgIGxvZ29TdGF0dXMudGV4dENvbnRlbnQgPSAnTmV3IGRhcmsgbG9nbyByZWFkeSB0byBzYXZlJztcbiAgICB9KTtcbiAgfSk7XG5cbiAgdXBsb2FkTGlnaHQ/LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIChlKSA9PiB7XG4gICAgcmVhZEZpbGVBc0RhdGFVUkwoZS50YXJnZXQuZmlsZXNbMF0sIChkYXRhKSA9PiB7XG4gICAgICBwZW5kaW5nTGlnaHREYXRhID0gZGF0YTtcbiAgICAgIHByZXZpZXdMaWdodC5zcmMgPSBkYXRhO1xuICAgICAgbG9nb1N0YXR1cy50ZXh0Q29udGVudCA9ICdOZXcgbGlnaHQgbG9nbyByZWFkeSB0byBzYXZlJztcbiAgICB9KTtcbiAgfSk7XG5cbiAgdXBsb2FkU2luZ2xlPy5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCAoZSkgPT4ge1xuICAgIHJlYWRGaWxlQXNEYXRhVVJMKGUudGFyZ2V0LmZpbGVzWzBdLCAoZGF0YSkgPT4ge1xuICAgICAgcGVuZGluZ1NpbmdsZURhdGEgPSBkYXRhO1xuICAgICAgcHJldmlld0Rhcmsuc3JjID0gZGF0YTtcbiAgICAgIHByZXZpZXdMaWdodC5zcmMgPSBkYXRhO1xuICAgICAgbG9nb1N0YXR1cy50ZXh0Q29udGVudCA9ICdOZXcgbG9nbyByZWFkeSB0byBzYXZlIChib3RoIHRoZW1lcyknO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyBBcHBseSBsb2dvIHBvc2l0aW9uXG4gIGZ1bmN0aW9uIGFwcGx5TG9nb1Bvc2l0aW9uKHBvcykge1xuICAgIHRvcFJvdy5zZXRBdHRyaWJ1dGUoJ2RhdGEtbG9nby1wb3MnLCBwb3MpO1xuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5sb2dvLXBvcy1idG4nKS5mb3JFYWNoKGJ0biA9PiB7XG4gICAgICBidG4uc3R5bGUuYmFja2dyb3VuZCA9IGJ0bi5kYXRhc2V0LnBvcyA9PT0gcG9zID8gJ3ZhcigtLWFjY2VudCknIDogJ3ZhcigtLWNhcmQtYmcpJztcbiAgICAgIGJ0bi5zdHlsZS5jb2xvciA9IGJ0bi5kYXRhc2V0LnBvcyA9PT0gcG9zID8gJ3doaXRlJyA6ICd2YXIoLS1mZyknO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gQXBwbHkgZGFzaGJvYXJkIHRpdGxlXG4gIGZ1bmN0aW9uIGFwcGx5RGFzaGJvYXJkVGl0bGUodGl0bGUpIHtcbiAgICBjdXJyZW50VGl0bGUgPSB0aXRsZSB8fCBERUZBVUxUX1RJVExFO1xuICAgIGRvY3VtZW50LnRpdGxlID0gY3VycmVudFRpdGxlO1xuICAgIGNvbnN0IGhlYWRlclRpdGxlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmRhc2hib2FyZC10aXRsZScpO1xuICAgIGlmIChoZWFkZXJUaXRsZSkgaGVhZGVyVGl0bGUudGV4dENvbnRlbnQgPSBjdXJyZW50VGl0bGU7XG4gIH1cblxuICAvLyBMb2FkIGN1c3RvbSBsb2dvLCBwb3NpdGlvbiwgYW5kIHRpdGxlIG9uIHN0YXJ0dXBcbiAgYXN5bmMgZnVuY3Rpb24gbG9hZEN1c3RvbUxvZ28oKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goJy9hcGkvdjEvbG9nbycpO1xuICAgICAgaWYgKHJlc3BvbnNlLm9rKSB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgIC8vIEFwcGx5IGRhcmsvbGlnaHQgdmFyaWFudHNcbiAgICAgICAgaWYgKGRhdGEuY3VzdG9tTG9nb0RhcmspIHtcbiAgICAgICAgICBicmFuZExvZ29EYXJrLnNyYyA9IGRhdGEuY3VzdG9tTG9nb0Rhcms7XG4gICAgICAgICAgcHJldmlld0Rhcmsuc3JjID0gZGF0YS5jdXN0b21Mb2dvRGFyaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGF0YS5jdXN0b21Mb2dvTGlnaHQpIHtcbiAgICAgICAgICBicmFuZExvZ29MaWdodC5zcmMgPSBkYXRhLmN1c3RvbUxvZ29MaWdodDtcbiAgICAgICAgICBwcmV2aWV3TGlnaHQuc3JjID0gZGF0YS5jdXN0b21Mb2dvTGlnaHQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gTGVnYWN5IHNpbmdsZS1sb2dvIGZhbGxiYWNrXG4gICAgICAgIGlmICghZGF0YS5jdXN0b21Mb2dvRGFyayAmJiAhZGF0YS5jdXN0b21Mb2dvTGlnaHQgJiYgZGF0YS5jdXN0b21Mb2dvKSB7XG4gICAgICAgICAgYnJhbmRMb2dvRGFyay5zcmMgPSBkYXRhLmN1c3RvbUxvZ287XG4gICAgICAgICAgYnJhbmRMb2dvTGlnaHQuc3JjID0gZGF0YS5jdXN0b21Mb2dvO1xuICAgICAgICAgIHByZXZpZXdEYXJrLnNyYyA9IGRhdGEuY3VzdG9tTG9nbztcbiAgICAgICAgICBwcmV2aWV3TGlnaHQuc3JjID0gZGF0YS5jdXN0b21Mb2dvO1xuICAgICAgICB9XG4gICAgICAgIGlmICghZGF0YS5pc0RlZmF1bHQpIHtcbiAgICAgICAgICBsb2dvU3RhdHVzLnRleHRDb250ZW50ID0gJ1VzaW5nIGN1c3RvbSBsb2dvJztcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGF0YS5wb3NpdGlvbikge1xuICAgICAgICAgIGN1cnJlbnRQb3NpdGlvbiA9IGRhdGEucG9zaXRpb247XG4gICAgICAgICAgYXBwbHlMb2dvUG9zaXRpb24oZGF0YS5wb3NpdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRhdGEuZGFzaGJvYXJkVGl0bGUpIHtcbiAgICAgICAgICBhcHBseURhc2hib2FyZFRpdGxlKGRhdGEuZGFzaGJvYXJkVGl0bGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUud2FybignQ291bGQgbm90IGxvYWQgY3VzdG9tIGxvZ286JywgZXJyb3IubWVzc2FnZSk7XG4gICAgfVxuICB9XG5cbiAgLy8gUG9zaXRpb24gYnV0dG9uIGhhbmRsZXJzXG4gIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5sb2dvLXBvcy1idG4nKS5mb3JFYWNoKGJ0biA9PiB7XG4gICAgYnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgY3VycmVudFBvc2l0aW9uID0gYnRuLmRhdGFzZXQucG9zO1xuICAgICAgYXBwbHlMb2dvUG9zaXRpb24oY3VycmVudFBvc2l0aW9uKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gT3BlbiBsb2dvIG1vZGFsIG9uIGJyYW5kIGNsaWNrXG4gIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdicmFuZCcpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICBwZW5kaW5nRGFya0RhdGEgPSBudWxsO1xuICAgIHBlbmRpbmdMaWdodERhdGEgPSBudWxsO1xuICAgIHBlbmRpbmdTaW5nbGVEYXRhID0gbnVsbDtcbiAgICBpZiAodXBsb2FkRGFyaykgdXBsb2FkRGFyay52YWx1ZSA9ICcnO1xuICAgIGlmICh1cGxvYWRMaWdodCkgdXBsb2FkTGlnaHQudmFsdWUgPSAnJztcbiAgICBpZiAodXBsb2FkU2luZ2xlKSB1cGxvYWRTaW5nbGUudmFsdWUgPSAnJztcbiAgICAvLyBSZXNldCBjaGVja2JveCB0byBkdWFsIG1vZGVcbiAgICBpZiAoc2FtZUJvdGhDaGVja2JveCkgc2FtZUJvdGhDaGVja2JveC5jaGVja2VkID0gZmFsc2U7XG4gICAgZHVhbFVwbG9hZHMuc3R5bGUuZGlzcGxheSA9ICdmbGV4JztcbiAgICBzaW5nbGVVcGxvYWQuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAvLyBSZXNldCBwcmV2aWV3cyB0byBjdXJyZW50IGhlYWRlciBsb2dvc1xuICAgIHByZXZpZXdEYXJrLnNyYyA9IGJyYW5kTG9nb0Rhcmsuc3JjO1xuICAgIHByZXZpZXdMaWdodC5zcmMgPSBicmFuZExvZ29MaWdodC5zcmM7XG4gICAgY29uc3QgaXNDdXN0b20gPSBicmFuZExvZ29EYXJrLnNyYy5pbmNsdWRlcygnY3VzdG9tLWxvZ28nKSB8fCBicmFuZExvZ29MaWdodC5zcmMuaW5jbHVkZXMoJ2N1c3RvbS1sb2dvJyk7XG4gICAgbG9nb1N0YXR1cy50ZXh0Q29udGVudCA9IGlzQ3VzdG9tID8gJ1VzaW5nIGN1c3RvbSBsb2dvJyA6ICdVc2luZyBkZWZhdWx0IGxvZ29zJztcbiAgICBhcHBseUxvZ29Qb3NpdGlvbihjdXJyZW50UG9zaXRpb24pO1xuICAgIGRhc2hib2FyZFRpdGxlSW5wdXQudmFsdWUgPSBjdXJyZW50VGl0bGU7XG4gICAgbG9nb01vZGFsLmNsYXNzTGlzdC5hZGQoJ3Nob3cnKTtcbiAgfSk7XG5cbiAgLy8gU2F2ZSBsb2dvLCBwb3NpdGlvbiwgYW5kIHRpdGxlXG4gIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsb2dvLXNhdmUnKT8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyAoKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IG5ld1RpdGxlID0gZGFzaGJvYXJkVGl0bGVJbnB1dC52YWx1ZS50cmltKCkgfHwgREVGQVVMVF9USVRMRTtcbiAgICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICAgIHBvc2l0aW9uOiBjdXJyZW50UG9zaXRpb24sXG4gICAgICAgIGRhc2hib2FyZFRpdGxlOiBuZXdUaXRsZVxuICAgICAgfTtcblxuICAgICAgLy8gRGV0ZXJtaW5lIHdoaWNoIGxvZ28gZGF0YSB0byBzZW5kXG4gICAgICBpZiAoc2FtZUJvdGhDaGVja2JveD8uY2hlY2tlZCAmJiBwZW5kaW5nU2luZ2xlRGF0YSkge1xuICAgICAgICAvLyBTaW5nbGUgbG9nbyBmb3IgYm90aCB2YXJpYW50c1xuICAgICAgICBwYXlsb2FkLmRhdGFEYXJrID0gcGVuZGluZ1NpbmdsZURhdGE7XG4gICAgICAgIHBheWxvYWQuZGF0YUxpZ2h0ID0gcGVuZGluZ1NpbmdsZURhdGE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAocGVuZGluZ0RhcmtEYXRhKSBwYXlsb2FkLmRhdGFEYXJrID0gcGVuZGluZ0RhcmtEYXRhO1xuICAgICAgICBpZiAocGVuZGluZ0xpZ2h0RGF0YSkgcGF5bG9hZC5kYXRhTGlnaHQgPSBwZW5kaW5nTGlnaHREYXRhO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHNlY3VyZUZldGNoKCcvYXBpL3YxL2xvZ28nLCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkocGF5bG9hZClcbiAgICAgIH0pO1xuXG4gICAgICBpZiAocmVzcG9uc2Uub2spIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgY29uc3QgdCA9ICc/dD0nICsgRGF0ZS5ub3coKTtcbiAgICAgICAgaWYgKGRhdGEucGF0aERhcmspIHtcbiAgICAgICAgICBicmFuZExvZ29EYXJrLnNyYyA9IGRhdGEucGF0aERhcmsgKyB0O1xuICAgICAgICAgIHByZXZpZXdEYXJrLnNyYyA9IGRhdGEucGF0aERhcmsgKyB0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChkYXRhLnBhdGhMaWdodCkge1xuICAgICAgICAgIGJyYW5kTG9nb0xpZ2h0LnNyYyA9IGRhdGEucGF0aExpZ2h0ICsgdDtcbiAgICAgICAgICBwcmV2aWV3TGlnaHQuc3JjID0gZGF0YS5wYXRoTGlnaHQgKyB0O1xuICAgICAgICB9XG4gICAgICAgIGFwcGx5TG9nb1Bvc2l0aW9uKGN1cnJlbnRQb3NpdGlvbik7XG4gICAgICAgIGFwcGx5RGFzaGJvYXJkVGl0bGUobmV3VGl0bGUpO1xuICAgICAgICBsb2dvTW9kYWwuY2xhc3NMaXN0LnJlbW92ZSgnc2hvdycpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgZXJyb3IgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oJ0ZhaWxlZCB0byBzYXZlOiAnICsgZXJyb3IuZXJyb3IsICdlcnJvcicpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBzaG93Tm90aWZpY2F0aW9uKCdFcnJvciBzYXZpbmc6ICcgKyBlcnJvci5tZXNzYWdlLCAnZXJyb3InKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIFJlc2V0IGFsbCBicmFuZGluZyB0byBkZWZhdWx0c1xuICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbG9nby1yZXNldCcpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICBpZiAoIWNvbmZpcm0oJ1Jlc2V0IGFsbCBicmFuZGluZyB0byBEYXNoQ2FkZHkgZGVmYXVsdHM/XFxuXFxuVGhpcyB3aWxsIHJlc2V0IHRoZSBsb2dvLCBmYXZpY29uLCB0aXRsZSwgYW5kIHBvc2l0aW9uLicpKSByZXR1cm47XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgbG9nb1Jlc3BvbnNlID0gYXdhaXQgc2VjdXJlRmV0Y2goJy9hcGkvdjEvbG9nbycsIHsgbWV0aG9kOiAnREVMRVRFJyB9KTtcbiAgICAgIGlmIChsb2dvUmVzcG9uc2Uub2spIHtcbiAgICAgICAgYnJhbmRMb2dvRGFyay5zcmMgPSAnL2Fzc2V0cy9kYXNoY2FkZHktbG9nby1kYXJrLnBuZyc7XG4gICAgICAgIGJyYW5kTG9nb0xpZ2h0LnNyYyA9ICcvYXNzZXRzL2Rhc2hjYWRkeS1sb2dvLWxpZ2h0LnBuZyc7XG4gICAgICAgIHByZXZpZXdEYXJrLnNyYyA9ICcvYXNzZXRzL2Rhc2hjYWRkeS1sb2dvLWRhcmsucG5nJztcbiAgICAgICAgcHJldmlld0xpZ2h0LnNyYyA9ICcvYXNzZXRzL2Rhc2hjYWRkeS1sb2dvLWxpZ2h0LnBuZyc7XG4gICAgICAgIGxvZ29TdGF0dXMudGV4dENvbnRlbnQgPSAnVXNpbmcgZGVmYXVsdCBsb2dvcyc7XG4gICAgICAgIHBlbmRpbmdEYXJrRGF0YSA9IG51bGw7XG4gICAgICAgIHBlbmRpbmdMaWdodERhdGEgPSBudWxsO1xuICAgICAgICBwZW5kaW5nU2luZ2xlRGF0YSA9IG51bGw7XG4gICAgICAgIGRhc2hib2FyZFRpdGxlSW5wdXQudmFsdWUgPSBERUZBVUxUX1RJVExFO1xuICAgICAgICBhcHBseURhc2hib2FyZFRpdGxlKERFRkFVTFRfVElUTEUpO1xuICAgICAgICBjdXJyZW50UG9zaXRpb24gPSAnbGVmdCc7XG4gICAgICAgIGFwcGx5TG9nb1Bvc2l0aW9uKCdsZWZ0Jyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZhdmljb25SZXNwb25zZSA9IGF3YWl0IHNlY3VyZUZldGNoKCcvYXBpL3YxL2Zhdmljb24nLCB7IG1ldGhvZDogJ0RFTEVURScgfSk7XG4gICAgICBpZiAoZmF2aWNvblJlc3BvbnNlLm9rKSB7XG4gICAgICAgIGNvbnN0IGZhdmljb25MaW5rID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignbGlua1tyZWw9XCJpY29uXCJdJyk7XG4gICAgICAgIGNvbnN0IGZhdmljb25QcmV2aWV3ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Zhdmljb24tcHJldmlldycpO1xuICAgICAgICBjb25zdCBmYXZpY29uU3RhdHVzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Zhdmljb24tc3RhdHVzJyk7XG4gICAgICAgIGlmIChmYXZpY29uTGluaykgZmF2aWNvbkxpbmsuaHJlZiA9ICcvYXNzZXRzL2Rhc2hjYWRkeS1mYXZpY29uLmljbz90PScgKyBEYXRlLm5vdygpO1xuICAgICAgICBpZiAoZmF2aWNvblByZXZpZXcpIGZhdmljb25QcmV2aWV3LnNyYyA9ICcvYXNzZXRzL2Rhc2hjYWRkeS1mYXZpY29uLmljbz90PScgKyBEYXRlLm5vdygpO1xuICAgICAgICBpZiAoZmF2aWNvblN0YXR1cykgZmF2aWNvblN0YXR1cy50ZXh0Q29udGVudCA9ICdVc2luZyBEYXNoQ2FkZHkgZmF2aWNvbic7XG4gICAgICAgIHBlbmRpbmdGYXZpY29uRGF0YSA9IG51bGw7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHNob3dOb3RpZmljYXRpb24oJ0Vycm9yIHJlc2V0dGluZyBicmFuZGluZzogJyArIGVycm9yLm1lc3NhZ2UsICdlcnJvcicpO1xuICAgIH1cbiAgfSk7XG5cbiAgd2lyZU1vZGFsKGxvZ29Nb2RhbCwgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2xvZ28tY2FuY2VsJykpO1xuXG4gIC8vID09PT09IEZBVklDT04gSEFORExJTkcgPT09PT1cbiAgY29uc3QgZmF2aWNvblByZXZpZXcgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZmF2aWNvbi1wcmV2aWV3Jyk7XG4gIGNvbnN0IGZhdmljb25TdGF0dXMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZmF2aWNvbi1zdGF0dXMnKTtcbiAgY29uc3QgZmF2aWNvblVwbG9hZCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmYXZpY29uLXVwbG9hZCcpO1xuICBjb25zdCBmYXZpY29uTGluayA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2xpbmtbcmVsPVwiaWNvblwiXScpIHx8IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xpbmsnKTtcbiAgbGV0IHBlbmRpbmdGYXZpY29uRGF0YSA9IG51bGw7XG5cbiAgaWYgKCFkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdsaW5rW3JlbD1cImljb25cIl0nKSkge1xuICAgIGZhdmljb25MaW5rLnJlbCA9ICdpY29uJztcbiAgICBmYXZpY29uTGluay5ocmVmID0gJy9hc3NldHMvZGFzaGNhZGR5LWZhdmljb24uaWNvJztcbiAgICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKGZhdmljb25MaW5rKTtcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGxvYWRDdXN0b21GYXZpY29uKCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL2Zhdmljb24nKTtcbiAgICAgIGlmIChyZXNwb25zZS5vaykge1xuICAgICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgICBpZiAoZGF0YS5jdXN0b21GYXZpY29uKSB7XG4gICAgICAgICAgZmF2aWNvbkxpbmsuaHJlZiA9IGRhdGEuY3VzdG9tRmF2aWNvbiArICc/dD0nICsgRGF0ZS5ub3coKTtcbiAgICAgICAgICBmYXZpY29uUHJldmlldy5zcmMgPSBkYXRhLmN1c3RvbUZhdmljb24gKyAnP3Q9JyArIERhdGUubm93KCk7XG4gICAgICAgICAgZmF2aWNvblN0YXR1cy50ZXh0Q29udGVudCA9ICdVc2luZyBjdXN0b20gZmF2aWNvbic7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS53YXJuKCdDb3VsZCBub3QgbG9hZCBjdXN0b20gZmF2aWNvbjonLCBlcnJvci5tZXNzYWdlKTtcbiAgICB9XG4gIH1cblxuICBmYXZpY29uVXBsb2FkPy5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCAoZSkgPT4ge1xuICAgIGNvbnN0IGZpbGUgPSBlLnRhcmdldC5maWxlc1swXTtcbiAgICBpZiAoIWZpbGUpIHJldHVybjtcbiAgICBpZiAoIWZpbGUudHlwZS5tYXRjaCgvXmltYWdlXFwvKHBuZ3xzdmdcXCt4bWwpJC8pKSB7XG4gICAgICBzaG93Tm90aWZpY2F0aW9uKCdQbGVhc2Ugc2VsZWN0IGEgUE5HIG9yIFNWRyBmaWxlJywgJ3dhcm5pbmcnKTtcbiAgICAgIGZhdmljb25VcGxvYWQudmFsdWUgPSAnJztcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcbiAgICByZWFkZXIub25sb2FkID0gKGV2ZW50KSA9PiB7XG4gICAgICBwZW5kaW5nRmF2aWNvbkRhdGEgPSBldmVudC50YXJnZXQucmVzdWx0O1xuICAgICAgZmF2aWNvblByZXZpZXcuc3JjID0gcGVuZGluZ0Zhdmljb25EYXRhO1xuICAgICAgZmF2aWNvblN0YXR1cy50ZXh0Q29udGVudCA9ICdOZXcgZmF2aWNvbiByZWFkeSB0byBzYXZlJztcbiAgICB9O1xuICAgIHJlYWRlci5yZWFkQXNEYXRhVVJMKGZpbGUpO1xuICB9KTtcblxuICAvLyBTYXZlIGZhdmljb24gYWxvbmdzaWRlIGxvZ28gc2F2ZVxuICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbG9nby1zYXZlJyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xuICAgIGlmIChwZW5kaW5nRmF2aWNvbkRhdGEpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgc2VjdXJlRmV0Y2goJy9hcGkvdjEvZmF2aWNvbicsIHtcbiAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7IGRhdGE6IHBlbmRpbmdGYXZpY29uRGF0YSB9KVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgICBmYXZpY29uTGluay5ocmVmID0gZGF0YS5wYXRoICsgJz90PScgKyBEYXRlLm5vdygpO1xuICAgICAgICAgIGZhdmljb25QcmV2aWV3LnNyYyA9IGRhdGEucGF0aCArICc/dD0nICsgRGF0ZS5ub3coKTtcbiAgICAgICAgICBmYXZpY29uU3RhdHVzLnRleHRDb250ZW50ID0gJ1VzaW5nIGN1c3RvbSBmYXZpY29uJztcbiAgICAgICAgICBwZW5kaW5nRmF2aWNvbkRhdGEgPSBudWxsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGVycm9yID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgICAgIHNob3dOb3RpZmljYXRpb24oJ0ZhaWxlZCB0byBzYXZlIGZhdmljb246ICcgKyBlcnJvci5lcnJvciwgJ2Vycm9yJyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oJ0Vycm9yIHNhdmluZyBmYXZpY29uOiAnICsgZXJyb3IubWVzc2FnZSwgJ2Vycm9yJyk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBsb2FkQ3VzdG9tRmF2aWNvbigpO1xuICBsb2FkQ3VzdG9tTG9nbygpO1xuXG4gIC8vID09PT09IFRJTUVaT05FIFNFVFRJTkcgPT09PT1cbiAgY29uc3Qgc2V0dGluZ3NUelNlbGVjdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXR0aW5ncy10aW1lem9uZScpO1xuICBpZiAoc2V0dGluZ3NUelNlbGVjdCkge1xuICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgaWYgKGxvZ29Nb2RhbC5jbGFzc0xpc3QuY29udGFpbnMoJ3Nob3cnKSAmJiBzZXR0aW5nc1R6U2VsZWN0Lm9wdGlvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgbGV0IGN1cnJlbnRUejtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2goJy9hcGkvdjEvY29uZmlnJyk7XG4gICAgICAgICAgICBpZiAocmVzLm9rKSB7IGNvbnN0IGNmZyA9IGF3YWl0IHJlcy5qc29uKCk7IGN1cnJlbnRUeiA9IGNmZy50aW1lem9uZTsgfVxuICAgICAgICAgIH0gY2F0Y2ggKGUpIHsgLyogaWdub3JlICovIH1cbiAgICAgICAgICB3aW5kb3cucG9wdWxhdGVUaW1lem9uZVNlbGVjdChzZXR0aW5nc1R6U2VsZWN0LCBjdXJyZW50VHopO1xuICAgICAgICB9KSgpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIG9ic2VydmVyLm9ic2VydmUobG9nb01vZGFsLCB7IGF0dHJpYnV0ZXM6IHRydWUsIGF0dHJpYnV0ZUZpbHRlcjogWydjbGFzcyddIH0pO1xuXG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2xvZ28tc2F2ZScpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHR6ID0gc2V0dGluZ3NUelNlbGVjdC52YWx1ZTtcbiAgICAgIGlmICghdHopIHJldHVybjtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL2NvbmZpZycpO1xuICAgICAgICBpZiAoIXJlcy5vaykgcmV0dXJuO1xuICAgICAgICBjb25zdCBjZmcgPSBhd2FpdCByZXMuanNvbigpO1xuICAgICAgICBjZmcudGltZXpvbmUgPSB0ejtcbiAgICAgICAgY2ZnLnVwZGF0ZWRBdCA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKTtcbiAgICAgICAgYXdhaXQgc2VjdXJlRmV0Y2goJy9hcGkvdjEvY29uZmlnJywge1xuICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGNmZylcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnNvbGUud2FybignRmFpbGVkIHRvIHNhdmUgdGltZXpvbmU6JywgZS5tZXNzYWdlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufSkoKTtcbjtcbi8vIFNoYXJlZCB0aW1lem9uZSB1dGlsaXR5IFx1MjAxNCB1c2VkIGJ5IHNldHVwIHdpemFyZCBhbmQgc2V0dGluZ3MgbW9kYWxcbi8vIGVycm9ySGFuZGxlciBpcyBkZWNsYXJlZCBnbG9iYWxseSBpbiBnbG9iYWxzLmpzIChjb3JlLmpzIGJ1bmRsZSk7IHJldXNpbmcgaXRcbi8vIGhlcmUgc28gd2UgZG9uJ3QgZ2V0IFwicmVkZWNsYXJhdGlvbiBvZiBjb25zdCBlcnJvckhhbmRsZXJcIiBhdCBzY3JpcHQgc2NvcGUuXG5cbndpbmRvdy5wb3B1bGF0ZVRpbWV6b25lU2VsZWN0ID0gZnVuY3Rpb24oc2VsZWN0RWwsIHNlbGVjdGVkVHopIHtcbiAgY29uc3QgdGltZXpvbmVzID0gSW50bC5zdXBwb3J0ZWRWYWx1ZXNPZigndGltZVpvbmUnKTtcbiAgY29uc3QgZGV0ZWN0ZWQgPSBzZWxlY3RlZFR6IHx8IEludGwuRGF0ZVRpbWVGb3JtYXQoKS5yZXNvbHZlZE9wdGlvbnMoKS50aW1lWm9uZSB8fCAnVVRDJztcbiAgc2VsZWN0RWwuaW5uZXJIVE1MID0gJyc7XG4gIGZvciAoY29uc3QgdHogb2YgdGltZXpvbmVzKSB7XG4gICAgY29uc3Qgb3B0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnb3B0aW9uJyk7XG4gICAgb3B0LnZhbHVlID0gdHo7XG4gICAgb3B0LnRleHRDb250ZW50ID0gdHoucmVwbGFjZSgvXy9nLCAnICcpO1xuICAgIGlmICh0eiA9PT0gZGV0ZWN0ZWQpIG9wdC5zZWxlY3RlZCA9IHRydWU7XG4gICAgc2VsZWN0RWwuYXBwZW5kQ2hpbGQob3B0KTtcbiAgfVxufTtcblxuLy8gU2V0dXAgV2l6YXJkIFN5c3RlbSAtIFNlcnZlci1zaWRlIGNvbmZpZyBzdG9yYWdlXG4oZnVuY3Rpb24gKCkge1xuICBsZXQgY3VycmVudENvbmZpZ1R5cGUgPSAnaG9tZWxhYic7XG4gIGxldCBzZXJ2ZXJDb25maWcgPSBudWxsO1xuXG4gIC8vIENoZWNrIHNlcnZlciBmb3IgZXhpc3RpbmcgY29uZmlnIG9uIHBhZ2UgbG9hZFxuICBhc3luYyBmdW5jdGlvbiBjaGVja1NlcnZlckNvbmZpZygpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS9jb25maWcnKTtcbiAgICAgIGlmIChyZXNwb25zZS5vaykge1xuICAgICAgICBzZXJ2ZXJDb25maWcgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgIGlmIChzZXJ2ZXJDb25maWcgJiYgc2VydmVyQ29uZmlnLnNldHVwQ29tcGxldGUpIHtcbiAgICAgICAgICAvLyBDb25maWcgZXhpc3RzIG9uIHNlcnZlciAtIGRvbid0IHNob3cgd2l6YXJkXG4gICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NldHVwLXdpemFyZCcpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS53YXJuKCdDb3VsZCBub3QgZmV0Y2ggc2VydmVyIGNvbmZpZywgY2hlY2tpbmcgbG9jYWxTdG9yYWdlIGZhbGxiYWNrOicsIGVycm9yLm1lc3NhZ2UpO1xuICAgIH1cblxuICAgIC8vIEZhbGxiYWNrOiBjaGVjayBsb2NhbFN0b3JhZ2UgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG4gICAgY29uc3QgbG9jYWxTZXR1cCA9IHNhZmVHZXQoJ2Rhc2hjYWRkeS1zZXR1cCcpO1xuICAgIGlmIChsb2NhbFNldHVwKSB7XG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtd2l6YXJkJykuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8vIE5vIGNvbmZpZyBmb3VuZCAtIHNob3cgd2l6YXJkXG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NldHVwLXdpemFyZCcpLnN0eWxlLmRpc3BsYXkgPSAnZmxleCc7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gSW5pdGlhbGl6ZSBvbiBwYWdlIGxvYWRcbiAgY2hlY2tTZXJ2ZXJDb25maWcoKTtcblxuICAvLyBQb3B1bGF0ZSB0aW1lem9uZSBkcm9wZG93biB3aXRoIGF1dG8tZGV0ZWN0aW9uXG4gIGNvbnN0IHNldHVwVHpTZWxlY3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtdGltZXpvbmUnKTtcbiAgaWYgKHNldHVwVHpTZWxlY3QpIHdpbmRvdy5wb3B1bGF0ZVRpbWV6b25lU2VsZWN0KHNldHVwVHpTZWxlY3QpO1xuXG4gIC8vIFN0ZXAgbmF2aWdhdGlvblxuICBmdW5jdGlvbiBzaG93U3RlcChzdGVwSWQpIHtcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuc2V0dXAtc3RlcCcpLmZvckVhY2goc3RlcCA9PiB7XG4gICAgICBzdGVwLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgfSk7XG4gICAgY29uc3QgdGFyZ2V0U3RlcCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHN0ZXBJZCk7XG4gICAgaWYgKHRhcmdldFN0ZXApIHtcbiAgICAgIHRhcmdldFN0ZXAuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgfVxuICB9XG5cbiAgLy8gU2hvdyBzdW1tYXJ5XG4gIGZ1bmN0aW9uIHNob3dTdW1tYXJ5KCkge1xuICAgIGNvbnN0IHN1bW1hcnlDb250ZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NldHVwLXN1bW1hcnktY29udGVudCcpO1xuICAgIGlmICghc3VtbWFyeUNvbnRlbnQpIHJldHVybjtcblxuICAgIGxldCBodG1sID0gJzxkaXYgc3R5bGU9XCJkaXNwbGF5OiBncmlkOyBnYXA6IDIwcHg7XCI+JztcblxuICAgIGlmIChjdXJyZW50Q29uZmlnVHlwZSA9PT0gJ2hvbWVsYWInKSB7XG4gICAgICBjb25zdCB0bGQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtdGxkJyk/LnZhbHVlPy50cmltKCkgfHwgJy5ob21lJztcbiAgICAgIGNvbnN0IGNhTmFtZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXR1cC1jYS1uYW1lJyk/LnZhbHVlPy50cmltKCkgfHwgJyc7XG4gICAgICBjb25zdCBkbnNJUCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXR1cC1kbnMtaXAnKT8udmFsdWU/LnRyaW0oKSB8fCAnJztcbiAgICAgIGNvbnN0IGRuc1BvcnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtZG5zLXBvcnQnKT8udmFsdWU/LnRyaW0oKSB8fCBEQy5ERUZBVUxUUy5ETlNfUE9SVDtcblxuICAgICAgaHRtbCArPSBgXG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgPGgzIHN0eWxlPVwibWFyZ2luOiAwIDAgMTJweDsgY29sb3I6IHZhcigtLWFjY2VudCk7XCI+SG9tZSBMYWIgQ29uZmlndXJhdGlvbjwvaDM+XG4gICAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGdyaWQ7IGdhcDogMTJweDsgZm9udC1zaXplOiAwLjk1cmVtO1wiPlxuICAgICAgICAgICAgPGRpdj48c3Ryb25nPlRMRDo8L3N0cm9uZz4gJHt0bGR9PC9kaXY+XG4gICAgICAgICAgICA8ZGl2PjxzdHJvbmc+Q2VydGlmaWNhdGUgQXV0aG9yaXR5Ojwvc3Ryb25nPiAke2NhTmFtZX08L2Rpdj5cbiAgICAgICAgICAgIDxkaXY+PHN0cm9uZz5ETlMgU2VydmVyOjwvc3Ryb25nPiAke2Ruc0lQfToke2Ruc1BvcnR9PC9kaXY+XG4gICAgICAgICAgICA8ZGl2PjxzdHJvbmc+RXhhbXBsZSBVUkxzOjwvc3Ryb25nPiBodHRwczovL3VwdGltZSR7dGxkfSwgaHR0cHM6Ly9uZXh0Y2xvdWQke3RsZH08L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICBgO1xuICAgIH0gZWxzZSBpZiAoY3VycmVudENvbmZpZ1R5cGUgPT09ICdzaW1wbGUnKSB7XG4gICAgICBjb25zdCBpcCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXR1cC1zaW1wbGUtaXAnKT8udmFsdWU/LnRyaW0oKSB8fCAnbG9jYWxob3N0JztcblxuICAgICAgaHRtbCArPSBgXG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgPGgzIHN0eWxlPVwibWFyZ2luOiAwIDAgMTJweDsgY29sb3I6IHZhcigtLWFjY2VudCk7XCI+U2ltcGxlIFNldHVwPC9oMz5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZ3JpZDsgZ2FwOiAxMnB4OyBmb250LXNpemU6IDAuOTVyZW07XCI+XG4gICAgICAgICAgICA8ZGl2PjxzdHJvbmc+QWNjZXNzIE1ldGhvZDo8L3N0cm9uZz4gSVA6UG9ydCBvbmx5PC9kaXY+XG4gICAgICAgICAgICA8ZGl2PjxzdHJvbmc+RGVmYXVsdCBJUDo8L3N0cm9uZz4gJHtpcH08L2Rpdj5cbiAgICAgICAgICAgIDxkaXY+PHN0cm9uZz5TU0w6PC9zdHJvbmc+IE5vbmUgKEhUVFAgb25seSk8L2Rpdj5cbiAgICAgICAgICAgIDxkaXY+PHN0cm9uZz5FeGFtcGxlIFVSTHM6PC9zdHJvbmc+IGh0dHA6Ly8ke2lwfTo4MDgwLCBodHRwOi8vJHtpcH06MzAwMDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIGA7XG4gICAgfSBlbHNlIGlmIChjdXJyZW50Q29uZmlnVHlwZSA9PT0gJ3B1YmxpYycpIHtcbiAgICAgIGNvbnN0IGRvbWFpbiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXR1cC1wdWJsaWMtZG9tYWluJyk/LnZhbHVlPy50cmltKCkgfHwgJyc7XG4gICAgICBjb25zdCBlbWFpbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXR1cC1wdWJsaWMtZW1haWwnKT8udmFsdWU/LnRyaW0oKSB8fCAnJztcbiAgICAgIGNvbnN0IHJvdXRpbmdNb2RlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaW5wdXRbbmFtZT1cInJvdXRpbmctbW9kZVwiXTpjaGVja2VkJyk/LnZhbHVlIHx8ICdzdWJkaXJlY3RvcnknO1xuICAgICAgY29uc3QgZXhhbXBsZVVybHMgPSByb3V0aW5nTW9kZSA9PT0gJ3N1YmRpcmVjdG9yeSdcbiAgICAgICAgPyBgaHR0cHM6Ly8ke2RvbWFpbn0vc29uYXJyLCBodHRwczovLyR7ZG9tYWlufS9ncmFmYW5hYFxuICAgICAgICA6IGBodHRwczovL3NvbmFyci4ke2RvbWFpbn0sIGh0dHBzOi8vZ3JhZmFuYS4ke2RvbWFpbn1gO1xuICAgICAgY29uc3Qgcm91dGluZ0xhYmVsID0gcm91dGluZ01vZGUgPT09ICdzdWJkaXJlY3RvcnknID8gJ1N1YmRpcmVjdG9yeSAoZG9tYWluLmNvbS9hcHApJyA6ICdTdWJkb21haW4gKGFwcC5kb21haW4uY29tKSc7XG5cbiAgICAgIGh0bWwgKz0gYFxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIDxoMyBzdHlsZT1cIm1hcmdpbjogMCAwIDEycHg7IGNvbG9yOiB2YXIoLS1hY2NlbnQpO1wiPlB1YmxpYyBTZXJ2ZXI8L2gzPlxuICAgICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBncmlkOyBnYXA6IDEycHg7IGZvbnQtc2l6ZTogMC45NXJlbTtcIj5cbiAgICAgICAgICAgIDxkaXY+PHN0cm9uZz5Eb21haW46PC9zdHJvbmc+ICR7ZG9tYWlufTwvZGl2PlxuICAgICAgICAgICAgPGRpdj48c3Ryb25nPlNTTDo8L3N0cm9uZz4gTGV0J3MgRW5jcnlwdDwvZGl2PlxuICAgICAgICAgICAgPGRpdj48c3Ryb25nPkVtYWlsOjwvc3Ryb25nPiAke2VtYWlsfTwvZGl2PlxuICAgICAgICAgICAgPGRpdj48c3Ryb25nPlJvdXRpbmc6PC9zdHJvbmc+ICR7cm91dGluZ0xhYmVsfTwvZGl2PlxuICAgICAgICAgICAgPGRpdj48c3Ryb25nPkV4YW1wbGUgVVJMczo8L3N0cm9uZz4gJHtleGFtcGxlVXJsc308L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICBgO1xuICAgIH1cblxuICAgIC8vIFRpbWV6b25lICh1bml2ZXJzYWwgYWNyb3NzIGFsbCBjb25maWcgdHlwZXMpXG4gICAgY29uc3QgdHogPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtdGltZXpvbmUnKT8udmFsdWUgfHwgSW50bC5EYXRlVGltZUZvcm1hdCgpLnJlc29sdmVkT3B0aW9ucygpLnRpbWVab25lIHx8ICdVVEMnO1xuICAgIGh0bWwgKz0gYFxuICAgICAgPGRpdiBzdHlsZT1cIm1hcmdpbi10b3A6IDhweDsgcGFkZGluZy10b3A6IDEycHg7IGJvcmRlci10b3A6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1wiPlxuICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjk1cmVtO1wiPjxzdHJvbmc+VGltZXpvbmU6PC9zdHJvbmc+ICR7dHoucmVwbGFjZSgvXy9nLCAnICcpfTwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgYDtcblxuICAgIGh0bWwgKz0gJzwvZGl2Pic7XG4gICAgc3VtbWFyeUNvbnRlbnQuaW5uZXJIVE1MID0gaHRtbDtcbiAgICBzaG93U3RlcCgnc2V0dXAtc3RlcC1zdW1tYXJ5Jyk7XG4gIH1cblxuICAvLyBTYXZlIGNvbmZpZyB0byBzZXJ2ZXJcbiAgYXN5bmMgZnVuY3Rpb24gc2F2ZUNvbmZpZ1RvU2VydmVyKGNvbmZpZykge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHNlY3VyZUZldGNoKCcvYXBpL3YxL2NvbmZpZycsIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeShjb25maWcpXG4gICAgICB9KTtcblxuICAgICAgaWYgKHJlc3BvbnNlLm9rKSB7XG4gICAgICAgIGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlcnJvckhhbmRsZXIubG9nRXJyb3IoJ1tTZXR1cFdpemFyZF0gU2F2ZSBDb25maWcnLCBuZXcgRXJyb3IoYFNlcnZlciByZXR1cm5lZCAke3Jlc3BvbnNlLnN0YXR1c31gKSwgeyBmdW5jdGlvbjogJ3NhdmVDb25maWdUb1NlcnZlcicgfSk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgZXJyb3JIYW5kbGVyLmxvZ0Vycm9yKCdbU2V0dXBXaXphcmRdIFNhdmUgQ29uZmlnJywgZXJyb3IsIHsgZnVuY3Rpb246ICdzYXZlQ29uZmlnVG9TZXJ2ZXInIH0pO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8vIEZpbmlzaCBzZXR1cCBoYW5kbGVyXG4gIGFzeW5jIGZ1bmN0aW9uIGZpbmlzaFNldHVwKCkge1xuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgIHNldHVwQ29tcGxldGU6IHRydWUsXG4gICAgICBjb25maWd1cmF0aW9uVHlwZTogY3VycmVudENvbmZpZ1R5cGUsXG4gICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgIHRpbWV6b25lOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtdGltZXpvbmUnKT8udmFsdWUgfHwgSW50bC5EYXRlVGltZUZvcm1hdCgpLnJlc29sdmVkT3B0aW9ucygpLnRpbWVab25lIHx8ICdVVEMnXG4gICAgfTtcblxuICAgIGlmIChjdXJyZW50Q29uZmlnVHlwZSA9PT0gJ2hvbWVsYWInKSB7XG4gICAgICBjb25maWcudGxkID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NldHVwLXRsZCcpPy52YWx1ZT8udHJpbSgpIHx8ICcuaG9tZSc7XG4gICAgICBjb25maWcuY2FOYW1lID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NldHVwLWNhLW5hbWUnKT8udmFsdWU/LnRyaW0oKSB8fCAnJztcbiAgICAgIGNvbnN0IHNlbGVjdGVkUHJvdmlkZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtZG5zLXByb3ZpZGVyJyk/LnZhbHVlIHx8ICd0ZWNobml0aXVtJztcbiAgICAgIGNvbmZpZy5kbnMgPSB7XG4gICAgICAgIHByb3ZpZGVyOiBzZWxlY3RlZFByb3ZpZGVyLFxuICAgICAgICBpcDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NldHVwLWRucy1pcCcpPy52YWx1ZT8udHJpbSgpIHx8ICcnLFxuICAgICAgICBwb3J0OiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtZG5zLXBvcnQnKT8udmFsdWU/LnRyaW0oKSB8fCBEQy5ERUZBVUxUUy5ETlNfUE9SVCxcbiAgICAgICAgdG9rZW46IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXR1cC1kbnMtdG9rZW4nKT8udmFsdWU/LnRyaW0oKSB8fCAnJ1xuICAgICAgfTtcbiAgICAgIGNvbmZpZy5kZWZhdWx0cyA9IHtcbiAgICAgICAgZG5zVHlwZTogJ3ByaXZhdGUnLFxuICAgICAgICBzc2xUeXBlOiAnaW50ZXJuYWwnLFxuICAgICAgICB0YXJnZXRJUDogJ2xvY2FsaG9zdCdcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChjdXJyZW50Q29uZmlnVHlwZSA9PT0gJ3NpbXBsZScpIHtcbiAgICAgIGNvbmZpZy5kZWZhdWx0SVAgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtc2ltcGxlLWlwJyk/LnZhbHVlPy50cmltKCkgfHwgJ2xvY2FsaG9zdCc7XG4gICAgICBjb25maWcuZGVmYXVsdHMgPSB7XG4gICAgICAgIGRuc1R5cGU6ICdub25lJyxcbiAgICAgICAgc3NsVHlwZTogJ25vbmUnLFxuICAgICAgICB0YXJnZXRJUDogY29uZmlnLmRlZmF1bHRJUFxuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKGN1cnJlbnRDb25maWdUeXBlID09PSAncHVibGljJykge1xuICAgICAgY29uZmlnLmRvbWFpbiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXR1cC1wdWJsaWMtZG9tYWluJyk/LnZhbHVlPy50cmltKCkgfHwgJyc7XG4gICAgICBjb25maWcuZW1haWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtcHVibGljLWVtYWlsJyk/LnZhbHVlPy50cmltKCkgfHwgJyc7XG4gICAgICBjb25maWcucm91dGluZ01vZGUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdpbnB1dFtuYW1lPVwicm91dGluZy1tb2RlXCJdOmNoZWNrZWQnKT8udmFsdWUgfHwgJ3N1YmRpcmVjdG9yeSc7XG4gICAgICBjb25maWcuZGVmYXVsdHMgPSB7XG4gICAgICAgIGRuc1R5cGU6IGNvbmZpZy5yb3V0aW5nTW9kZSA9PT0gJ3N1YmRpcmVjdG9yeScgPyAnbm9uZScgOiAncHVibGljJyxcbiAgICAgICAgc3NsVHlwZTogJ2xldHNlbmNyeXB0JyxcbiAgICAgICAgdGFyZ2V0SVA6ICdsb2NhbGhvc3QnXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIFNhdmUgdG8gc2VydmVyIChwcmltYXJ5KSBhbmQgbG9jYWxTdG9yYWdlIChmYWxsYmFjaylcbiAgICBjb25zdCBzYXZlZFRvU2VydmVyID0gYXdhaXQgc2F2ZUNvbmZpZ1RvU2VydmVyKGNvbmZpZyk7XG4gICAgc2FmZVNldCgnZGFzaGNhZGR5LWNvbmZpZycsIEpTT04uc3RyaW5naWZ5KGNvbmZpZykpO1xuICAgIHNhZmVTZXQoJ2Rhc2hjYWRkeS1zZXR1cCcsICdjb21wbGV0ZWQnKTtcblxuICAgIC8vIEhpZGUgd2l6YXJkXG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NldHVwLXdpemFyZCcpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG5cbiAgICAvLyBTaG93IHN1Y2Nlc3Mgbm90aWZpY2F0aW9uXG4gICAgY29uc3QgY29uZmlnTmFtZSA9IGN1cnJlbnRDb25maWdUeXBlID09PSAnaG9tZWxhYicgPyAnUHJvZmVzc2lvbmFsIEhvbWUgTGFiJyA6XG4gICAgICAgICAgICAgICAgICAgICAgY3VycmVudENvbmZpZ1R5cGUgPT09ICdzaW1wbGUnID8gJ1NpbXBsZSBTZXR1cCcgOiAnUHVibGljIFNlcnZlcic7XG4gICAgY29uc3Qgc2F2ZUxvY2F0aW9uID0gc2F2ZWRUb1NlcnZlciA/ICdzZXJ2ZXIgKHNoYXJlZCBhY3Jvc3MgYWxsIGRldmljZXMpJyA6ICdsb2NhbGx5ICh0aGlzIGJyb3dzZXIgb25seSknO1xuXG4gICAgc2hvd05vdGlmaWNhdGlvbihgU2V0dXAgQ29tcGxldGUhIENvbmZpZ3VyZWQgZm9yOiAke2NvbmZpZ05hbWV9LiBTZXR0aW5ncyBzYXZlZCB0bzogJHtzYXZlTG9jYXRpb259YCwgJ3N1Y2Nlc3MnLCA1MDAwKTtcblxuICAgIC8vIFJlbG9hZCBwYWdlIHRvIGFwcGx5IGNvbmZpZ3VyYXRpb25cbiAgICBzZXRUaW1lb3V0KCgpID0+IGxvY2F0aW9uLnJlbG9hZCgpLCA1MDApO1xuICB9XG5cbiAgLy8gPT09PT0gRXZlbnQgSGFuZGxlcnMgdXNpbmcgZGlyZWN0IG9uY2xpY2sgZm9yIHJlbGlhYmlsaXR5ID09PT09XG5cbiAgLy8gU3RlcCAxOiBDb250aW51ZSBidXR0b25cbiAgY29uc3Qgc3RlcDFOZXh0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NldHVwLXN0ZXAtMS1uZXh0Jyk7XG4gIGlmIChzdGVwMU5leHQpIHtcbiAgICBzdGVwMU5leHQub25jbGljayA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGNvbnN0IHNlbGVjdGVkID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaW5wdXRbbmFtZT1cImNvbmZpZy10eXBlXCJdOmNoZWNrZWQnKTtcbiAgICAgIGlmIChzZWxlY3RlZCkge1xuICAgICAgICBjdXJyZW50Q29uZmlnVHlwZSA9IHNlbGVjdGVkLnZhbHVlO1xuICAgICAgfVxuICAgICAgaWYgKGN1cnJlbnRDb25maWdUeXBlID09PSAnaG9tZWxhYicpIHtcbiAgICAgICAgc2hvd1N0ZXAoJ3NldHVwLXN0ZXAtaG9tZWxhYicpO1xuICAgICAgfSBlbHNlIGlmIChjdXJyZW50Q29uZmlnVHlwZSA9PT0gJ3NpbXBsZScpIHtcbiAgICAgICAgc2hvd1N0ZXAoJ3NldHVwLXN0ZXAtc2ltcGxlJyk7XG4gICAgICB9IGVsc2UgaWYgKGN1cnJlbnRDb25maWdUeXBlID09PSAncHVibGljJykge1xuICAgICAgICBzaG93U3RlcCgnc2V0dXAtc3RlcC1wdWJsaWMnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNob3dTdGVwKCdzZXR1cC1zdGVwLWhvbWVsYWInKTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLy8gU2tpcCBzZXR1cCBidXR0b25cbiAgY29uc3Qgc2tpcEJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXR1cC1za2lwJyk7XG4gIGlmIChza2lwQnRuKSB7XG4gICAgc2tpcEJ0bi5vbmNsaWNrID0gYXN5bmMgZnVuY3Rpb24oZSkge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgaWYgKGNvbmZpcm0oJ1NraXAgc2V0dXA/IFlvdSBjYW4gcnVuIGl0IGxhdGVyIGZyb20gU2V0dGluZ3MuJykpIHtcbiAgICAgICAgLy8gU2F2ZSBza2lwIHN0YXR1cyBcdTIwMTQgaGlkZSB3aXphcmQgRklSU1Qgc28gaXQgYWx3YXlzIGRpc21pc3NlcyxcbiAgICAgICAgLy8gdGhlbiBhdHRlbXB0IHNlcnZlciBzYXZlIChmaXJlLWFuZC1mb3JnZXQsIG5ldmVyIGJsb2NrcyBVSSlcbiAgICAgICAgc2FmZVNldCgnZGFzaGNhZGR5LXNldHVwJywgJ3NraXBwZWQnKTtcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NldHVwLXdpemFyZCcpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIHNhdmVDb25maWdUb1NlcnZlcih7IHNldHVwQ29tcGxldGU6IHRydWUsIHNraXBwZWQ6IHRydWUsIHRpbWVzdGFtcDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpIH0pLmNhdGNoKCgpID0+IHt9KTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLy8gSG9tZSBMYWI6IFRMRCBQcmV2aWV3XG4gIGNvbnN0IHRsZElucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NldHVwLXRsZCcpO1xuICBpZiAodGxkSW5wdXQpIHtcbiAgICB0bGRJbnB1dC5vbmlucHV0ID0gZnVuY3Rpb24oZSkge1xuICAgICAgY29uc3QgdGxkID0gZS50YXJnZXQudmFsdWUgfHwgJy5ob21lJztcbiAgICAgIGNvbnN0IHByZXZpZXcxID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RsZC1wcmV2aWV3Jyk7XG4gICAgICBjb25zdCBwcmV2aWV3MiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0bGQtcHJldmlldy0yJyk7XG4gICAgICBpZiAocHJldmlldzEpIHByZXZpZXcxLnRleHRDb250ZW50ID0gdGxkO1xuICAgICAgaWYgKHByZXZpZXcyKSBwcmV2aWV3Mi50ZXh0Q29udGVudCA9IHRsZDtcbiAgICB9O1xuICB9XG5cbiAgLy8gSG9tZSBMYWIgbmF2aWdhdGlvblxuICBjb25zdCBob21lbGFiQmFjayA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXR1cC1ob21lbGFiLWJhY2snKTtcbiAgaWYgKGhvbWVsYWJCYWNrKSB7XG4gICAgaG9tZWxhYkJhY2sub25jbGljayA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHNob3dTdGVwKCdzZXR1cC1zdGVwLTEnKTtcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgaG9tZWxhYk5leHQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtaG9tZWxhYi1uZXh0Jyk7XG4gIGlmIChob21lbGFiTmV4dCkge1xuICAgIGhvbWVsYWJOZXh0Lm9uY2xpY2sgPSBmdW5jdGlvbihlKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBjb25zdCB0bGQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtdGxkJyk/LnZhbHVlPy50cmltKCkgfHwgJyc7XG4gICAgICBjb25zdCBjYU5hbWUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtY2EtbmFtZScpPy52YWx1ZT8udHJpbSgpIHx8ICcnO1xuICAgICAgY29uc3QgZG5zSVAgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtZG5zLWlwJyk/LnZhbHVlPy50cmltKCkgfHwgJyc7XG5cbiAgICAgIGlmICghdGxkIHx8ICF0bGQuc3RhcnRzV2l0aCgnLicpKSB7XG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oJ1BsZWFzZSBlbnRlciBhIHZhbGlkIFRMRCBzdGFydGluZyB3aXRoIGEgZG90IChlLmcuLCAuaG9tZSknLCAnd2FybmluZycpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoIWNhTmFtZSkge1xuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKCdQbGVhc2UgZW50ZXIgYSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgbmFtZScsICd3YXJuaW5nJyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICghZG5zSVApIHtcbiAgICAgICAgc2hvd05vdGlmaWNhdGlvbignUGxlYXNlIGVudGVyIHlvdXIgRE5TIHNlcnZlciBJUCBhZGRyZXNzJywgJ3dhcm5pbmcnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgc2hvd1N1bW1hcnkoKTtcbiAgICB9O1xuICB9XG5cbiAgLy8gU2ltcGxlIG5hdmlnYXRpb25cbiAgY29uc3Qgc2ltcGxlQmFjayA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXR1cC1zaW1wbGUtYmFjaycpO1xuICBpZiAoc2ltcGxlQmFjaykge1xuICAgIHNpbXBsZUJhY2sub25jbGljayA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHNob3dTdGVwKCdzZXR1cC1zdGVwLTEnKTtcbiAgICB9O1xuICB9XG5cbiAgY29uc3Qgc2ltcGxlTmV4dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXR1cC1zaW1wbGUtbmV4dCcpO1xuICBpZiAoc2ltcGxlTmV4dCkge1xuICAgIHNpbXBsZU5leHQub25jbGljayA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHNob3dTdW1tYXJ5KCk7XG4gICAgfTtcbiAgfVxuXG4gIC8vIFB1YmxpYyByb3V0aW5nIG1vZGUgdG9nZ2xlIFx1MjAxNCB1cGRhdGUgcmVxdWlyZW1lbnQgdGV4dFxuICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdpbnB1dFtuYW1lPVwicm91dGluZy1tb2RlXCJdJykuZm9yRWFjaChmdW5jdGlvbihyYWRpbykge1xuICAgIHJhZGlvLm9uY2hhbmdlID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgbm90ZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkbnMtcmVxdWlyZW1lbnQtbm90ZScpO1xuICAgICAgaWYgKG5vdGUpIHtcbiAgICAgICAgbm90ZS50ZXh0Q29udGVudCA9IHRoaXMudmFsdWUgPT09ICdzdWJkaXJlY3RvcnknXG4gICAgICAgICAgPyAnT25seSBvbmUgRE5TIHJlY29yZCBuZWVkZWQgKGZvciB0aGUgbWFpbiBkb21haW4pJ1xuICAgICAgICAgIDogJ1lvdVxcJ2xsIG5lZWQgdG8gY29uZmlndXJlIEROUyBtYW51YWxseSBmb3IgZWFjaCBzdWJkb21haW4nO1xuICAgICAgfVxuICAgIH07XG4gIH0pO1xuXG4gIC8vIFB1YmxpYyBuYXZpZ2F0aW9uXG4gIGNvbnN0IHB1YmxpY0JhY2sgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtcHVibGljLWJhY2snKTtcbiAgaWYgKHB1YmxpY0JhY2spIHtcbiAgICBwdWJsaWNCYWNrLm9uY2xpY2sgPSBmdW5jdGlvbihlKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBzaG93U3RlcCgnc2V0dXAtc3RlcC0xJyk7XG4gICAgfTtcbiAgfVxuXG4gIGNvbnN0IHB1YmxpY05leHQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtcHVibGljLW5leHQnKTtcbiAgaWYgKHB1YmxpY05leHQpIHtcbiAgICBwdWJsaWNOZXh0Lm9uY2xpY2sgPSBmdW5jdGlvbihlKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBjb25zdCBkb21haW4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtcHVibGljLWRvbWFpbicpPy52YWx1ZT8udHJpbSgpIHx8ICcnO1xuICAgICAgY29uc3QgZW1haWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtcHVibGljLWVtYWlsJyk/LnZhbHVlPy50cmltKCkgfHwgJyc7XG5cbiAgICAgIGlmICghZG9tYWluKSB7XG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oJ1BsZWFzZSBlbnRlciB5b3VyIGRvbWFpbiBuYW1lJywgJ3dhcm5pbmcnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKCFlbWFpbCB8fCAhZW1haWwuaW5jbHVkZXMoJ0AnKSkge1xuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKCdQbGVhc2UgZW50ZXIgYSB2YWxpZCBlbWFpbCBhZGRyZXNzJywgJ3dhcm5pbmcnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgc2hvd1N1bW1hcnkoKTtcbiAgICB9O1xuICB9XG5cbiAgLy8gU3VtbWFyeSBuYXZpZ2F0aW9uXG4gIGNvbnN0IHN1bW1hcnlCYWNrID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NldHVwLXN1bW1hcnktYmFjaycpO1xuICBpZiAoc3VtbWFyeUJhY2spIHtcbiAgICBzdW1tYXJ5QmFjay5vbmNsaWNrID0gZnVuY3Rpb24oZSkge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgaWYgKGN1cnJlbnRDb25maWdUeXBlID09PSAnaG9tZWxhYicpIHtcbiAgICAgICAgc2hvd1N0ZXAoJ3NldHVwLXN0ZXAtaG9tZWxhYicpO1xuICAgICAgfSBlbHNlIGlmIChjdXJyZW50Q29uZmlnVHlwZSA9PT0gJ3NpbXBsZScpIHtcbiAgICAgICAgc2hvd1N0ZXAoJ3NldHVwLXN0ZXAtc2ltcGxlJyk7XG4gICAgICB9IGVsc2UgaWYgKGN1cnJlbnRDb25maWdUeXBlID09PSAncHVibGljJykge1xuICAgICAgICBzaG93U3RlcCgnc2V0dXAtc3RlcC1wdWJsaWMnKTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLy8gU3VtbWFyeSBcIkNvbnRpbnVlIFx1MjE5MlwiIFx1MjAxNCBhZHZhbmNlIHRvIHRoZSBkaXNrLXNhZmV0eSB3YXJuaW5nIHN0ZXBcbiAgY29uc3Qgc3VtbWFyeU5leHQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtc3VtbWFyeS1uZXh0Jyk7XG4gIGlmIChzdW1tYXJ5TmV4dCkge1xuICAgIHN1bW1hcnlOZXh0Lm9uY2xpY2sgPSBmdW5jdGlvbihlKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBzaG93U3RlcCgnc2V0dXAtc3RlcC1kaXNrLXNhZmV0eScpO1xuICAgIH07XG4gIH1cblxuICAvLyBEaXNrLXNhZmV0eSBzdGVwIG5hdmlnYXRpb25cbiAgY29uc3QgZGlza1NhZmV0eUJhY2sgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtZGlzay1zYWZldHktYmFjaycpO1xuICBpZiAoZGlza1NhZmV0eUJhY2spIHtcbiAgICBkaXNrU2FmZXR5QmFjay5vbmNsaWNrID0gZnVuY3Rpb24oZSkge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgc2hvd1N0ZXAoJ3NldHVwLXN0ZXAtc3VtbWFyeScpO1xuICAgIH07XG4gIH1cblxuICAvLyBGaW5pc2ggc2V0dXAgYnV0dG9uIChub3cgb24gdGhlIGRpc2stc2FmZXR5IHN0ZXApXG4gIGNvbnN0IGZpbmlzaEJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXR1cC1kaXNrLXNhZmV0eS1maW5pc2gnKTtcbiAgaWYgKGZpbmlzaEJ0bikge1xuICAgIGZpbmlzaEJ0bi5vbmNsaWNrID0gZnVuY3Rpb24oZSkge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgZmluaXNoU2V0dXAoKTtcbiAgICB9O1xuICB9XG5cbiAgLy8gRXhwb3NlIGZ1bmN0aW9uIHRvIGdldCBnbG9iYWwgY29uZmlnIChmcm9tIHNlcnZlciBvciBsb2NhbFN0b3JhZ2UpXG4gIHdpbmRvdy5nZXRHbG9iYWxDb25maWcgPSBhc3luYyBmdW5jdGlvbigpIHtcbiAgICAvLyBUcnkgc2VydmVyIGZpcnN0XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goJy9hcGkvdjEvY29uZmlnJyk7XG4gICAgICBpZiAocmVzcG9uc2Uub2spIHtcbiAgICAgICAgY29uc3QgY29uZmlnID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgICBpZiAoY29uZmlnICYmIGNvbmZpZy5zZXR1cENvbXBsZXRlKSB7XG4gICAgICAgICAgcmV0dXJuIGNvbmZpZztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUud2FybignQ291bGQgbm90IGZldGNoIGNvbmZpZyBmcm9tIHNlcnZlcicpO1xuICAgIH1cblxuICAgIC8vIEZhbGxiYWNrIHRvIGxvY2FsU3RvcmFnZVxuICAgIGNvbnN0IGNvbmZpZ1N0ciA9IHNhZmVHZXQoJ2Rhc2hjYWRkeS1jb25maWcnKTtcbiAgICBpZiAoY29uZmlnU3RyKSB7XG4gICAgICByZXR1cm4gSlNPTi5wYXJzZShjb25maWdTdHIpO1xuICAgIH1cblxuICAgIC8vIFJldHVybiBkZWZhdWx0IGNvbmZpZyBpZiBub3Qgc2V0XG4gICAgcmV0dXJuIHtcbiAgICAgIHNldHVwQ29tcGxldGU6IGZhbHNlLFxuICAgICAgY29uZmlndXJhdGlvblR5cGU6ICdob21lbGFiJyxcbiAgICAgIHRsZDogJy5ob21lJyxcbiAgICAgIGNhTmFtZTogJycsXG4gICAgICBkZWZhdWx0czoge1xuICAgICAgICBkbnNUeXBlOiAncHJpdmF0ZScsXG4gICAgICAgIHNzbFR5cGU6ICdpbnRlcm5hbCcsXG4gICAgICAgIHRhcmdldElQOiAnbG9jYWxob3N0J1xuICAgICAgfVxuICAgIH07XG4gIH07XG5cbiAgLy8gRXhwb3NlIHJlc2V0IGZ1bmN0aW9uIGZvciBzZXR0aW5nc1xuICB3aW5kb3cucmVzZXRTZXR1cFdpemFyZCA9IGFzeW5jIGZ1bmN0aW9uKCkge1xuICAgIGlmIChjb25maXJtKCdSZXNldCBEYXNoQ2FkZHkgY29uZmlndXJhdGlvbj8gVGhpcyB3aWxsIHNob3cgdGhlIHNldHVwIHdpemFyZCBhZ2Fpbi4nKSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc2VjdXJlRmV0Y2goJy9hcGkvdjEvY29uZmlnJywgeyBtZXRob2Q6ICdERUxFVEUnIH0pO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb25zb2xlLndhcm4oJ0NvdWxkIG5vdCBkZWxldGUgc2VydmVyIGNvbmZpZycpO1xuICAgICAgfVxuICAgICAgc2FmZVJlbW92ZSgnZGFzaGNhZGR5LXNldHVwJyk7XG4gICAgICBzYWZlUmVtb3ZlKCdkYXNoY2FkZHktY29uZmlnJyk7XG4gICAgICBsb2NhdGlvbi5yZWxvYWQoKTtcbiAgICB9XG4gIH07XG59KSgpO1xuO1xuLy8gQXBwIFNlbGVjdG9yIFN5c3RlbVxuKGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgZXJyb3JIYW5kbGVyID0gbmV3IEVycm9ySGFuZGxlcigpO1xuICBpbmplY3RNb2RhbCgnYXBwLXNlbGVjdG9yLW1vZGFsJywgYDxkaXYgaWQ9XCJhcHAtc2VsZWN0b3ItbW9kYWxcIiBjbGFzcz1cIndlYXRoZXItbW9kYWxcIj5cbiAgICA8ZGl2IGNsYXNzPVwiYXBwLXNlbGVjdG9yLWNvbnRlbnRcIj5cbiAgICAgIDxoMiBzdHlsZT1cIm1hcmdpbjogMCAwIDI0cHg7IGNvbG9yOiB2YXIoLS1mZyk7IHRleHQtYWxpZ246IGNlbnRlcjtcIj5DaG9vc2UgYW4gQXBwPC9oMj5cbiAgICAgIDxkaXYgaWQ9XCJhcHAtc2VsZWN0b3ItZ3JpZFwiIGNsYXNzPVwiYXBwLXNlbGVjdG9yLWdyaWRcIj48L2Rpdj5cbiAgICAgIDxkaXYgc3R5bGU9XCJ0ZXh0LWFsaWduOiBjZW50ZXI7IG1hcmdpbi10b3A6IDI0cHg7XCI+XG4gICAgICAgIDxidXR0b24gaWQ9XCJhcHAtc2VsZWN0b3ItY2FuY2VsXCI+Q2FuY2VsPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+YCk7XG5cbiAgaW5qZWN0TW9kYWwoJ2FwcC1kZXBsb3ktbW9kYWwnLCBgPGRpdiBpZD1cImFwcC1kZXBsb3ktbW9kYWxcIiBjbGFzcz1cIndlYXRoZXItbW9kYWxcIj5cbiAgICA8ZGl2IGNsYXNzPVwid2VhdGhlci1tb2RhbC1jb250ZW50XCIgc3R5bGU9XCJtaW4td2lkdGg6IDYwMHB4OyBtYXgtd2lkdGg6IDcwMHB4O1wiPlxuICAgICAgPGgzIGlkPVwiYXBwLWRlcGxveS10aXRsZVwiPkRlcGxveSBBcHBsaWNhdGlvbjwvaDM+XG5cbiAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBncmlkOyBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IDFmcjsgZ2FwOiAxNnB4OyBtYXJnaW4tdG9wOiAxNnB4O1wiPlxuICAgICAgICA8IS0tIFN1YmRvbWFpbi9Eb21haW4gLS0+XG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgPGxhYmVsIGZvcj1cImRlcGxveS1zdWJkb21haW5cIiBjbGFzcz1cImZvcm0tbGFiZWwtYWNjZW50LXNtXCI+XG4gICAgICAgICAgICBcdUQ4M0NcdURGMTAgU3ViZG9tYWluIG9yIERvbWFpblxuICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgaWQ9XCJkZXBsb3ktc3ViZG9tYWluXCIgcGxhY2Vob2xkZXI9XCJ1cHRpbWVcIlxuICAgICAgICAgICAgICAgICBzdHlsZT1cIndpZHRoOiAxMDAlOyBwYWRkaW5nOiAxMHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJnKTsgY29sb3I6IHZhcigtLWZnKTsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgYm9yZGVyLXJhZGl1czogNnB4OyBmb250LXNpemU6IDAuOTVyZW07XCIgLz5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1oaW50LXNtXCI+XG4gICAgICAgICAgICBZb3VyIGFwcCB3aWxsIGJlIGF2YWlsYWJsZSBhdDogPHNwYW4gaWQ9XCJkZXBsb3ktdXJsLXByZXZpZXdcIiBzdHlsZT1cImNvbG9yOiB2YXIoLS1hY2NlbnQpOyBmb250LXdlaWdodDogNTAwO1wiPnVwdGltZS5ob21lPC9zcGFuPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgaWQ9XCJzdWJwYXRoLWNvbXBhdC13YXJuaW5nXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lOyBwYWRkaW5nOiA4cHggMTJweDsgYm9yZGVyLXJhZGl1czogNnB4OyBiYWNrZ3JvdW5kOiBjb2xvci1taXgoaW4gc3JnYiwgI2ZmOTgwMCAxMCUsIHZhcigtLWNhcmQtYmcpKTsgYm9yZGVyOiAxcHggc29saWQgY29sb3ItbWl4KGluIHNyZ2IsICNmZjk4MDAgMzAlLCB0cmFuc3BhcmVudCk7IG1hcmdpbi10b3A6IDhweDsgZm9udC1zaXplOiAwLjg1cmVtO1wiPjwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIEROUyBDb25maWd1cmF0aW9uIC0tPlxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwtYWNjZW50XCI+XG4gICAgICAgICAgICBcdUQ4M0RcdUREQzJcdUZFMEYgRE5TIENvbmZpZ3VyYXRpb25cbiAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4LWNvbC1nYXBcIj5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInJhZGlvLW9wdGlvblwiPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInJhZGlvXCIgbmFtZT1cImRucy10eXBlXCIgdmFsdWU9XCJwcml2YXRlXCIgY2hlY2tlZCBzdHlsZT1cIm1hcmdpbi1yaWdodDogMTBweDtcIiAvPlxuICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmdy01MDBcIj5Qcml2YXRlIEROUyAoVGVjaG5pdGl1bSk8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1oaW50XCI+VXNlIHlvdXIgbG9jYWwgRE5TIHNlcnZlciB3aXRoIGN1c3RvbSBUTEQgKC5zYW1pLCAuaG9tZSwgZXRjLik8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwicmFkaW8tb3B0aW9uXCI+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwicmFkaW9cIiBuYW1lPVwiZG5zLXR5cGVcIiB2YWx1ZT1cInB1YmxpY1wiIHN0eWxlPVwibWFyZ2luLXJpZ2h0OiAxMHB4O1wiIC8+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZ3LTUwMFwiPlB1YmxpYyBETlM8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1oaW50XCI+VXNlIGEgcmVhbCBkb21haW4gKGV4YW1wbGUuY29tKSAtIHJlcXVpcmVzIEROUyBwcm92aWRlciBzZXR1cDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJyYWRpby1vcHRpb25cIj5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJyYWRpb1wiIG5hbWU9XCJkbnMtdHlwZVwiIHZhbHVlPVwibm9uZVwiIHN0eWxlPVwibWFyZ2luLXJpZ2h0OiAxMHB4O1wiIC8+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZ3LTUwMFwiPk5vIEROUyAoSVA6UG9ydCBvbmx5KTwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LWhpbnRcIj5BY2Nlc3MgdmlhIElQIGFkZHJlc3MgYW5kIHBvcnQgLSBubyBkb21haW4gc2V0dXA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIFNTTCBDb25maWd1cmF0aW9uIC0tPlxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwtYWNjZW50XCI+XG4gICAgICAgICAgICBcdUQ4M0RcdUREMTIgU1NML1RMUyBDZXJ0aWZpY2F0ZVxuICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgtY29sLWdhcFwiPlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwicmFkaW8tb3B0aW9uXCI+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwicmFkaW9cIiBuYW1lPVwic3NsLXR5cGVcIiB2YWx1ZT1cImludGVybmFsXCIgY2hlY2tlZCBzdHlsZT1cIm1hcmdpbi1yaWdodDogMTBweDtcIiAvPlxuICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmdy01MDBcIj5JbnRlcm5hbCBDQTwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LWhpbnRcIj5Vc2UgQ2FkZHkncyBpbnRlcm5hbCBjZXJ0aWZpY2F0ZSBhdXRob3JpdHkgKHNlbGYtc2lnbmVkKTwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJyYWRpby1vcHRpb25cIj5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJyYWRpb1wiIG5hbWU9XCJzc2wtdHlwZVwiIHZhbHVlPVwibGV0c2VuY3J5cHRcIiBzdHlsZT1cIm1hcmdpbi1yaWdodDogMTBweDtcIiAvPlxuICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmdy01MDBcIj5MZXQncyBFbmNyeXB0PC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtaGludFwiPkZyZWUgcHVibGljIFNTTCBjZXJ0aWZpY2F0ZSAocmVxdWlyZXMgcHVibGljIGRvbWFpbik8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwicmFkaW8tb3B0aW9uXCI+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwicmFkaW9cIiBuYW1lPVwic3NsLXR5cGVcIiB2YWx1ZT1cIm5vbmVcIiBzdHlsZT1cIm1hcmdpbi1yaWdodDogMTBweDtcIiAvPlxuICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmdy01MDBcIj5ObyBTU0wgKEhUVFAgb25seSk8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1oaW50XCI+XHUyNkEwXHVGRTBGIE5vdCByZWNvbW1lbmRlZCAtIHRyYWZmaWMgd2lsbCBiZSB1bmVuY3J5cHRlZDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gTWVkaWEgTGlicmFyeSBQYXRoIChzaG93biBmb3IgbWVkaWEgYXBwcykgLS0+XG4gICAgICAgIDxkaXYgaWQ9XCJtZWRpYS1wYXRoLXNlY3Rpb25cIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCI+XG4gICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbC1hY2NlbnRcIj5cbiAgICAgICAgICAgIFx1RDgzRFx1RENDMSBNZWRpYSBMaWJyYXJ5IExvY2F0aW9uXG4gICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsgZ2FwOiAxMHB4O1wiPlxuICAgICAgICAgICAgPCEtLSBEZXRlY3RlZCBtb3VudHMgZnJvbSBleGlzdGluZyBtZWRpYSBzZXJ2ZXJzIC0tPlxuICAgICAgICAgICAgPGRpdiBpZD1cImRldGVjdGVkLW1vdW50cy1jb250YWluZXJcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCI+XG4gICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuODVyZW07IGNvbG9yOiB2YXIoLS1zdWNjZXNzKTsgbWFyZ2luLWJvdHRvbTogNnB4O1wiPlxuICAgICAgICAgICAgICAgIFx1MjcxMyBEZXRlY3RlZCBmcm9tIGV4aXN0aW5nIG1lZGlhIHNlcnZlcnM6XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IGlkPVwiZGV0ZWN0ZWQtbW91bnRzLWxpc3RcIiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGdhcDogOHB4OyBmbGV4LXdyYXA6IHdyYXA7XCI+PC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPCEtLSBQYXRoIGlucHV0IHdpdGggYnJvd3NlIGJ1dHRvbiAtLT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4LXJvdy1nYXBcIj5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgaWQ9XCJkZXBsb3ktbWVkaWEtcGF0aFwiIHBsYWNlaG9sZGVyPVwiL21lZGlhL01vdmllcywgL21lZGlhL1RWU2hvd3NcIlxuICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJpbnB1dC1mbGV4XCIgc3R5bGU9XCJmb250LXNpemU6IDAuOTVyZW07XCIgLz5cbiAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgaWQ9XCJicm93c2UtbWVkaWEtYnRuXCIgc3R5bGU9XCJwYWRkaW5nOiAxMHB4IDE2cHg7IGJhY2tncm91bmQ6IHZhcigtLWFjY2VudCk7IGNvbG9yOiB3aGl0ZTsgYm9yZGVyOiBub25lOyBib3JkZXItcmFkaXVzOiA2cHg7IGN1cnNvcjogcG9pbnRlcjsgZm9udC13ZWlnaHQ6IDUwMDsgd2hpdGUtc3BhY2U6IG5vd3JhcDtcIj5cbiAgICAgICAgICAgICAgICBcdUQ4M0RcdURDQzIgQnJvd3NlXG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgaWQ9XCJtZWRpYS1wYXRoLWRlc2NyaXB0aW9uXCIgY2xhc3M9XCJ0ZXh0LWhpbnRcIj5cbiAgICAgICAgICAgICAgU2VsZWN0IGZvbGRlcnMgZnJvbSBleGlzdGluZyBzZXJ2ZXJzLCBicm93c2UsIG9yIHR5cGUgcGF0aHMgbWFudWFsbHkuIFNlcGFyYXRlIG11bHRpcGxlIHdpdGggY29tbWFzLlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDwhLS0gU2VsZWN0ZWQgcGF0aHMgZGlzcGxheSAtLT5cbiAgICAgICAgICAgIDxkaXYgaWQ9XCJzZWxlY3RlZC1tZWRpYS1wYXRoc1wiIHN0eWxlPVwiZGlzcGxheTogbm9uZTsgZmxleC13cmFwOiB3cmFwOyBnYXA6IDZweDtcIj48L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBQbGV4IENsYWltIFRva2VuIChzaG93biBvbmx5IGZvciBQbGV4IGRlcGxveW1lbnRzKSAtLT5cbiAgICAgICAgPGRpdiBpZD1cInBsZXgtY2xhaW0tc2VjdGlvblwiIHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIj5cbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsLWFjY2VudFwiPlxuICAgICAgICAgICAgXHVEODNEXHVERDExIFBsZXggQ2xhaW0gVG9rZW5cbiAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4LXJvdy1nYXBcIj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGlkPVwiZGVwbG95LXBsZXgtY2xhaW1cIiBwbGFjZWhvbGRlcj1cImNsYWltLXh4eHh4eHh4eHh4eHh4eHh4eHh4XCJcbiAgICAgICAgICAgICAgICAgICBjbGFzcz1cImlucHV0LWZsZXhcIiBzdHlsZT1cImZvbnQtc2l6ZTogMC45NXJlbTtcIiAvPlxuICAgICAgICAgICAgPGEgaHJlZj1cImh0dHBzOi8vcGxleC50di9jbGFpbVwiIHRhcmdldD1cIl9ibGFua1wiIHJlbD1cIm5vb3BlbmVyIG5vcmVmZXJyZXJcIlxuICAgICAgICAgICAgICAgc3R5bGU9XCJwYWRkaW5nOiAxMHB4IDE2cHg7IGJhY2tncm91bmQ6ICNlNWEwMGQ7IGNvbG9yOiAjMDAwOyBib3JkZXI6IG5vbmU7IGJvcmRlci1yYWRpdXM6IDZweDsgY3Vyc29yOiBwb2ludGVyOyBmb250LXdlaWdodDogNTAwOyB3aGl0ZS1zcGFjZTogbm93cmFwOyB0ZXh0LWRlY29yYXRpb246IG5vbmU7IGRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7XCI+XG4gICAgICAgICAgICAgIEdldCBUb2tlblxuICAgICAgICAgICAgPC9hPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuOHJlbTsgY29sb3I6ICNlNWEwMGQ7IG1hcmdpbi10b3A6IDRweDtcIj5cbiAgICAgICAgICAgIFRva2VuIGV4cGlyZXMgaW4gNCBtaW51dGVzISBHZXQgaXQgcmlnaHQgYmVmb3JlIGNsaWNraW5nIERlcGxveS4gTGVhdmUgZW1wdHkgdG8gY29uZmlndXJlIFBsZXggbWFudWFsbHkgbGF0ZXIuXG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gVGFpbHNjYWxlIFNlY3VyaXR5IC0tPlxuICAgICAgICA8ZGl2IGlkPVwidGFpbHNjYWxlLXNlY3Rpb25cIj5cbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsLWFjY2VudFwiPlxuICAgICAgICAgICAgXHVEODNEXHVERDEwIFRhaWxzY2FsZSBTZWN1cml0eVxuICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgtY29sLWdhcFwiPlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwicmFkaW8tb3B0aW9uXCI+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBpZD1cImRlcGxveS10YWlsc2NhbGUtb25seVwiIHN0eWxlPVwibWFyZ2luLXJpZ2h0OiAxMHB4OyB3aWR0aDogMThweDsgaGVpZ2h0OiAxOHB4O1wiIC8+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZ3LTUwMFwiPlRhaWxzY2FsZS1Pbmx5IEFjY2VzczwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LWhpbnRcIj5SZXN0cmljdCB0aGlzIHNlcnZpY2UgdG8gVGFpbHNjYWxlIHVzZXJzIG9ubHkgKDEwMC54LngueCBJUHMpPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgIDxkaXYgaWQ9XCJ0YWlsc2NhbGUtc3RhdHVzXCIgc3R5bGU9XCJwYWRkaW5nOiA4cHggMTJweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iZyk7IGJvcmRlci1yYWRpdXM6IDZweDsgZm9udC1zaXplOiAwLjg1cmVtO1wiPlxuICAgICAgICAgICAgICA8c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+Q2hlY2tpbmcgVGFpbHNjYWxlIHN0YXR1cy4uLjwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIEFkdmFuY2VkIE9wdGlvbnMgKENvbGxhcHNpYmxlKSAtLT5cbiAgICAgICAgPGRldGFpbHM+XG4gICAgICAgICAgPHN1bW1hcnkgc3R5bGU9XCJjdXJzb3I6IHBvaW50ZXI7IGNvbG9yOiB2YXIoLS1hY2NlbnQpOyBmb250LXdlaWdodDogNTAwOyBtYXJnaW4tYm90dG9tOiA4cHg7XCI+XHUyNjk5XHVGRTBGIEFkdmFuY2VkIE9wdGlvbnM8L3N1bW1hcnk+XG4gICAgICAgICAgPGRpdiBzdHlsZT1cIm1hcmdpbi10b3A6IDEycHg7IGRpc3BsYXk6IGdyaWQ7IGdhcDogMTJweDtcIj5cbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxsYWJlbCBmb3I9XCJkZXBsb3ktcG9ydFwiIHN0eWxlPVwiZGlzcGxheTogYmxvY2s7IG1hcmdpbi1ib3R0b206IDZweDtcIj5DdXN0b20gUG9ydCAob3B0aW9uYWwpPC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBpZD1cImRlcGxveS1wb3J0XCIgcGxhY2Vob2xkZXI9XCJMZWF2ZSBlbXB0eSBmb3IgZGVmYXVsdFwiXG4gICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0taW5wdXQtY2FyZFwiIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxsYWJlbCBmb3I9XCJkZXBsb3ktaXBcIiBzdHlsZT1cImRpc3BsYXk6IGJsb2NrOyBtYXJnaW4tYm90dG9tOiA2cHg7XCI+VGFyZ2V0IElQIEFkZHJlc3M8L2xhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBpZD1cImRlcGxveS1pcFwiIHZhbHVlPVwibG9jYWxob3N0XCJcbiAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1pbnB1dC1jYXJkXCIgLz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0taGludC1zbVwiPlxuICAgICAgICAgICAgICAgIFVzZSAnbG9jYWxob3N0JyBmb3Igc2FtZS1ob3N0IGNvbnRhaW5lcnMsIG9yIHNwZWNpZmljIElQIGZvciByZW1vdGUgc2VydmljZXNcbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgaWQ9XCJ2b2x1bWUtbW91bnRzLXNlY3Rpb25cIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCI+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwtYWNjZW50LXNtXCI+XHVEODNEXHVEQ0MyIFZvbHVtZSBNb3VudHM8L2xhYmVsPlxuICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjhyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi1ib3R0b206IDhweDtcIj5cbiAgICAgICAgICAgICAgICBDdXN0b21pemUgd2hlcmUgY29udGFpbmVyIGRhdGEgaXMgc3RvcmVkIG9uIHRoZSBob3N0LiBNZWRpYSB2b2x1bWVzIGFyZSBjb25maWd1cmVkIGFib3ZlLlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBpZD1cInZvbHVtZS1tb3VudHMtbGlzdFwiIHN0eWxlPVwiZGlzcGxheTogZ3JpZDsgZ2FwOiA4cHg7XCI+PC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJtYXJnaW4tdG9wOiAxMnB4O1wiPlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsLWFjY2VudC1zbVwiPlx1MjY5OVx1RkUwRiBSZXNvdXJjZSBMaW1pdHM8L2xhYmVsPlxuICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjhyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi1ib3R0b206IDhweDtcIj5cbiAgICAgICAgICAgICAgICBPcHRpb25hbCBDUFUgYW5kIG1lbW9yeSBjb25zdHJhaW50cy4gTGVhdmUgYXQgMCBmb3IgdW5saW1pdGVkLlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGdyaWQ7IGdyaWQtdGVtcGxhdGUtY29sdW1uczogMWZyIDFmcjsgZ2FwOiAxMHB4O1wiPlxuICAgICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgICA8bGFiZWwgZm9yPVwiZGVwbG95LWNwdS1saW1pdFwiIHN0eWxlPVwiZGlzcGxheTogYmxvY2s7IGZvbnQtc2l6ZTogMC43OHJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLWJvdHRvbTogNHB4O1wiPkNQVSBDb3JlczwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIGlkPVwiZGVwbG95LWNwdS1saW1pdFwiIHZhbHVlPVwiMFwiIG1pbj1cIjBcIiBtYXg9XCI2NFwiIHN0ZXA9XCIwLjI1XCIgY2xhc3M9XCJmb3JtLWlucHV0LWNhcmRcIiBzdHlsZT1cIndpZHRoOiAxMDAlO1wiIHBsYWNlaG9sZGVyPVwiMCA9IHVubGltaXRlZFwiIC8+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgIDxsYWJlbCBmb3I9XCJkZXBsb3ktbWVtb3J5LWxpbWl0XCIgc3R5bGU9XCJkaXNwbGF5OiBibG9jazsgZm9udC1zaXplOiAwLjc4cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW4tYm90dG9tOiA0cHg7XCI+TWVtb3J5IChNQik8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBpZD1cImRlcGxveS1tZW1vcnktbGltaXRcIiB2YWx1ZT1cIjBcIiBtaW49XCIwXCIgbWF4PVwiMTMxMDcyXCIgc3RlcD1cIjY0XCIgY2xhc3M9XCJmb3JtLWlucHV0LWNhcmRcIiBzdHlsZT1cIndpZHRoOiAxMDAlO1wiIHBsYWNlaG9sZGVyPVwiMCA9IHVubGltaXRlZFwiIC8+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGV0YWlscz5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGNsYXNzPVwid2VhdGhlci1tb2RhbC1idXR0b25zXCIgc3R5bGU9XCJtYXJnaW4tdG9wOiAyNHB4O1wiPlxuICAgICAgICA8YnV0dG9uIGlkPVwiYXBwLWRlcGxveS1jYW5jZWxcIj5DYW5jZWw8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBpZD1cImFwcC1kZXBsb3ktY29uZmlybVwiIGNsYXNzPVwiYnRuLWFjY2VudFwiPlxuICAgICAgICAgIFx1RDgzRFx1REU4MCBEZXBsb3lcbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+YCk7XG5cbiAgY29uc3QgQVBQU19LRVkgPSAnY3VzdG9tLWFwcHMnO1xuXG4gIC8vIENhY2hlIGZvciBBUEkgdGVtcGxhdGVzXG4gIGxldCBhcGlUZW1wbGF0ZXMgPSBudWxsO1xuICBsZXQgYXBpQ2F0ZWdvcmllcyA9IG51bGw7XG5cbiAgY29uc3QgbW9kYWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXBwLXNlbGVjdG9yLW1vZGFsJyk7XG4gIGNvbnN0IGdyaWQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXBwLXNlbGVjdG9yLWdyaWQnKTtcblxuICAvLyBGZXRjaCBhcHAgdGVtcGxhdGVzIGZyb20gQVBJXG4gIGFzeW5jIGZ1bmN0aW9uIGZldGNoQXBwVGVtcGxhdGVzKCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL2FwcHMvdGVtcGxhdGVzJyk7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgaWYgKGRhdGEuc3VjY2Vzcykge1xuICAgICAgICBhcGlUZW1wbGF0ZXMgPSBkYXRhLnRlbXBsYXRlcztcbiAgICAgICAgYXBpQ2F0ZWdvcmllcyA9IGRhdGEuY2F0ZWdvcmllcztcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgZXJyb3JIYW5kbGVyLmxvZ0Vycm9yKCdbQXBwU2VsZWN0b3JdIEZldGNoIFRlbXBsYXRlcycsIGUsIHsgZnVuY3Rpb246ICdmZXRjaEFwaVRlbXBsYXRlcycgfSk7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIENoZWNrIHBvcnQgYXZhaWxhYmlsaXR5XG4gIGFzeW5jIGZ1bmN0aW9uIGNoZWNrUG9ydEF2YWlsYWJpbGl0eShwb3J0KSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYC9hcGkvdjEvYXBwcy9wb3J0cy8ke3BvcnR9L2NoZWNrYCk7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgZXJyb3JIYW5kbGVyLmxvZ0Vycm9yKCdbQXBwU2VsZWN0b3JdIENoZWNrIFBvcnQnLCBlLCB7IGZ1bmN0aW9uOiAnY2hlY2tQb3J0QXZhaWxhYmlsaXR5JyB9KTtcbiAgICAgIHJldHVybiB7IGF2YWlsYWJsZTogdHJ1ZSB9OyAvLyBBc3N1bWUgYXZhaWxhYmxlIG9uIGVycm9yXG4gICAgfVxuICB9XG5cbiAgLy8gR2V0IHN1Z2dlc3RlZCBhdmFpbGFibGUgcG9ydFxuICBhc3luYyBmdW5jdGlvbiBnZXRTdWdnZXN0ZWRQb3J0KGJhc2VQb3J0KSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYC9hcGkvdjEvYXBwcy9wb3J0cy8ke2Jhc2VQb3J0fS9zdWdnZXN0YCk7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgaWYgKGRhdGEuc3VjY2Vzcykge1xuICAgICAgICByZXR1cm4gZGF0YS5zdWdnZXN0ZWRQb3J0O1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGVycm9ySGFuZGxlci5sb2dFcnJvcignW0FwcFNlbGVjdG9yXSBHZXQgU3VnZ2VzdGVkIFBvcnQnLCBlLCB7IGZ1bmN0aW9uOiAnZ2V0U3VnZ2VzdGVkUG9ydCcgfSk7XG4gICAgfVxuICAgIHJldHVybiBiYXNlUG9ydDtcbiAgfVxuXG4gIC8vIEJ1aWxkIGFwcCBzZWxlY3RvciBncmlkIGZyb20gQVBJIHRlbXBsYXRlc1xuICBhc3luYyBmdW5jdGlvbiBidWlsZEFwcFNlbGVjdG9yKCkge1xuICAgIGdyaWQuaW5uZXJIVE1MID0gJzxkaXYgc3R5bGU9XCJ0ZXh0LWFsaWduOiBjZW50ZXI7IHBhZGRpbmc6IDQwcHg7IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+TG9hZGluZyBhcHAgdGVtcGxhdGVzLi4uPC9kaXY+JztcblxuICAgIC8vIEZldGNoIHRlbXBsYXRlcyBpZiBub3QgY2FjaGVkXG4gICAgaWYgKCFhcGlUZW1wbGF0ZXMpIHtcbiAgICAgIGNvbnN0IHN1Y2Nlc3MgPSBhd2FpdCBmZXRjaEFwcFRlbXBsYXRlcygpO1xuICAgICAgaWYgKCFzdWNjZXNzKSB7XG4gICAgICAgIGdyaWQuaW5uZXJIVE1MID0gJzxkaXYgc3R5bGU9XCJ0ZXh0LWFsaWduOiBjZW50ZXI7IHBhZGRpbmc6IDQwcHg7IGNvbG9yOiB2YXIoLS1lcnJvcik7XCI+RmFpbGVkIHRvIGxvYWQgYXBwIHRlbXBsYXRlcy4gUGxlYXNlIHRyeSBhZ2Fpbi48L2Rpdj4nO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgZ3JpZC5pbm5lckhUTUwgPSAnJztcblxuICAgIC8vIEdyb3VwIHRlbXBsYXRlcyBieSBjYXRlZ29yeVxuICAgIGNvbnN0IGJ5Q2F0ZWdvcnkgPSB7fTtcbiAgICBmb3IgKGNvbnN0IFthcHBJZCwgdGVtcGxhdGVdIG9mIE9iamVjdC5lbnRyaWVzKGFwaVRlbXBsYXRlcykpIHtcbiAgICAgIGNvbnN0IGNhdGVnb3J5ID0gdGVtcGxhdGUuY2F0ZWdvcnkgfHwgJ090aGVyJztcbiAgICAgIGlmICghYnlDYXRlZ29yeVtjYXRlZ29yeV0pIHtcbiAgICAgICAgYnlDYXRlZ29yeVtjYXRlZ29yeV0gPSBbXTtcbiAgICAgIH1cbiAgICAgIGJ5Q2F0ZWdvcnlbY2F0ZWdvcnldLnB1c2goeyBpZDogYXBwSWQsIC4uLnRlbXBsYXRlIH0pO1xuICAgIH1cblxuICAgIC8vIFNvcnQgY2F0ZWdvcmllcyBieSB0aGUgb3JkZXIgaW4gYXBpQ2F0ZWdvcmllcyBpZiBhdmFpbGFibGVcbiAgICBjb25zdCBjYXRlZ29yeU9yZGVyID0gYXBpQ2F0ZWdvcmllcyA/IE9iamVjdC5rZXlzKGFwaUNhdGVnb3JpZXMpIDogT2JqZWN0LmtleXMoYnlDYXRlZ29yeSkuc29ydCgpO1xuXG4gICAgZm9yIChjb25zdCBjYXRlZ29yeSBvZiBjYXRlZ29yeU9yZGVyKSB7XG4gICAgICBjb25zdCBhcHBzID0gYnlDYXRlZ29yeVtjYXRlZ29yeV07XG4gICAgICBpZiAoIWFwcHMgfHwgYXBwcy5sZW5ndGggPT09IDApIGNvbnRpbnVlO1xuXG4gICAgICAvLyBTb3J0IGFwcHMgYnkgcG9wdWxhcml0eSAoZGVzY2VuZGluZylcbiAgICAgIGFwcHMuc29ydCgoYSwgYikgPT4gKGIucG9wdWxhcml0eSB8fCAwKSAtIChhLnBvcHVsYXJpdHkgfHwgMCkpO1xuXG4gICAgICAvLyBDYXRlZ29yeSBoZWFkZXIgd2l0aCBpY29uIGFuZCBjb2xvciBmcm9tIEFQSVxuICAgICAgY29uc3QgaGVhZGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICBoZWFkZXIuY2xhc3NOYW1lID0gJ2FwcC1jYXRlZ29yeS1oZWFkZXInO1xuICAgICAgY29uc3QgY2F0ZWdvcnlJbmZvID0gYXBpQ2F0ZWdvcmllcz8uW2NhdGVnb3J5XSB8fCB7fTtcbiAgICAgIGhlYWRlci5pbm5lckhUTUwgPSBgJHtlc2NhcGVIdG1sKGNhdGVnb3J5SW5mby5pY29uIHx8ICcnKX0gJHtlc2NhcGVIdG1sKGNhdGVnb3J5KX1gO1xuICAgICAgaWYgKGNhdGVnb3J5SW5mby5jb2xvcikge1xuICAgICAgICBoZWFkZXIuc3R5bGUuYm9yZGVyQm90dG9tQ29sb3IgPSBjYXRlZ29yeUluZm8uY29sb3I7XG4gICAgICB9XG4gICAgICBncmlkLmFwcGVuZENoaWxkKGhlYWRlcik7XG5cbiAgICAgIC8vIEFwcCBvcHRpb25zXG4gICAgICBhcHBzLmZvckVhY2goYXBwID0+IHtcbiAgICAgICAgY29uc3Qgb3B0aW9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIG9wdGlvbi5jbGFzc05hbWUgPSAnYXBwLW9wdGlvbic7XG5cbiAgICAgICAgLy8gV2lkZ2V0IGVuYWJsZWQgYmFkZ2VcbiAgICAgICAgY29uc3QgaXNXaWRnZXQgPSBhcHAuaXNEYXNoYm9hcmRXaWRnZXQ7XG4gICAgICAgIGNvbnN0IHdpZGdldEVuYWJsZWQgPSBpc1dpZGdldCAmJiBzYWZlR2V0KCd3aWRnZXQtJyArIGFwcC5pZCArICctZW5hYmxlZCcpICE9PSAnZmFsc2UnO1xuICAgICAgICBjb25zdCB3aWRnZXRCYWRnZSA9IGlzV2lkZ2V0XG4gICAgICAgICAgPyBgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC42NXJlbTsgcGFkZGluZzogMnB4IDZweDsgYm9yZGVyLXJhZGl1czogNHB4OyBtYXJnaW4tdG9wOiA0cHg7IGJhY2tncm91bmQ6ICR7d2lkZ2V0RW5hYmxlZCA/ICcjMmVjYzcxMzAnIDogJyNlNzRjM2MzMCd9OyBjb2xvcjogJHt3aWRnZXRFbmFibGVkID8gJyMyZWNjNzEnIDogJyNlNzRjM2MnfTsgZm9udC13ZWlnaHQ6IDYwMDtcIj4ke3dpZGdldEVuYWJsZWQgPyAnT04nIDogJ09GRid9PC9kaXY+YFxuICAgICAgICAgIDogJyc7XG5cbiAgICAgICAgLy8gU2hvdyBkaWZmaWN1bHR5IGJhZGdlIChub24td2lkZ2V0cyBvbmx5KVxuICAgICAgICBjb25zdCBkaWZmaWN1bHR5QmFkZ2UgPSAhaXNXaWRnZXQgJiYgYXBwLmRpZmZpY3VsdHkgP1xuICAgICAgICAgIGA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjY1cmVtOyBwYWRkaW5nOiAycHggNnB4OyBib3JkZXItcmFkaXVzOiA0cHg7IG1hcmdpbi10b3A6IDRweDsgYmFja2dyb3VuZDogJHtcbiAgICAgICAgICAgIGFwcC5kaWZmaWN1bHR5ID09PSAnRWFzeScgPyAnIzJlY2M3MScgOlxuICAgICAgICAgICAgYXBwLmRpZmZpY3VsdHkgPT09ICdJbnRlcm1lZGlhdGUnID8gJyNmMzljMTInIDogJyNlNzRjM2MnXG4gICAgICAgICAgfTIwOyBjb2xvcjogJHtcbiAgICAgICAgICAgIGFwcC5kaWZmaWN1bHR5ID09PSAnRWFzeScgPyAnIzJlY2M3MScgOlxuICAgICAgICAgICAgYXBwLmRpZmZpY3VsdHkgPT09ICdJbnRlcm1lZGlhdGUnID8gJyNmMzljMTInIDogJyNlNzRjM2MnXG4gICAgICAgICAgfTtcIj4ke2VzY2FwZUh0bWwoYXBwLmRpZmZpY3VsdHkpfTwvZGl2PmAgOiAnJztcblxuICAgICAgICBvcHRpb24uaW5uZXJIVE1MID0gYFxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJhcHAtb3B0aW9uLWljb25cIj4ke2VzY2FwZUh0bWwoYXBwLmljb24gfHwgJ1x1RDgzRFx1RENFNicpfTwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJhcHAtb3B0aW9uLW5hbWVcIj4ke2VzY2FwZUh0bWwoYXBwLm5hbWUpfTwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJhcHAtb3B0aW9uLWRlc2NcIj4ke2VzY2FwZUh0bWwoYXBwLmRlc2NyaXB0aW9uIHx8ICcnKX08L2Rpdj5cbiAgICAgICAgICAke3dpZGdldEJhZGdlfSR7ZGlmZmljdWx0eUJhZGdlfVxuICAgICAgICBgO1xuXG4gICAgICAgIGlmIChpc1dpZGdldCkge1xuICAgICAgICAgIG9wdGlvbi5vbmNsaWNrID0gKCkgPT4gdG9nZ2xlRGFzaGJvYXJkV2lkZ2V0KGFwcCwgb3B0aW9uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvcHRpb24ub25jbGljayA9ICgpID0+IHNob3dEZXBsb3lDb25maWcoYXBwKTtcbiAgICAgICAgfVxuICAgICAgICBncmlkLmFwcGVuZENoaWxkKG9wdGlvbik7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBSZW5kZXIgcmVjaXBlIGNhcmRzIGF0IHRoZSBlbmQgb2YgdGhlIGdyaWRcbiAgICBpZiAod2luZG93LnJlbmRlclJlY2lwZUNhcmRzKSB7XG4gICAgICBhd2FpdCB3aW5kb3cucmVuZGVyUmVjaXBlQ2FyZHMoZ3JpZCk7XG4gICAgfVxuICB9XG5cbiAgLy8gVG9nZ2xlIGEgZGFzaGJvYXJkIHdpZGdldCBvbi9vZmZcbiAgZnVuY3Rpb24gdG9nZ2xlRGFzaGJvYXJkV2lkZ2V0KGFwcCwgb3B0aW9uRWwpIHtcbiAgICBjb25zdCBrZXkgPSAnd2lkZ2V0LScgKyBhcHAuaWQgKyAnLWVuYWJsZWQnO1xuICAgIGNvbnN0IGN1cnJlbnRseUVuYWJsZWQgPSBzYWZlR2V0KGtleSkgIT09ICdmYWxzZSc7XG4gICAgY29uc3QgbmV3U3RhdGUgPSAhY3VycmVudGx5RW5hYmxlZDtcbiAgICBzYWZlU2V0KGtleSwgU3RyaW5nKG5ld1N0YXRlKSk7XG5cbiAgICAvLyBVcGRhdGUgdmlzaWJpbGl0eSBpbW1lZGlhdGVseVxuICAgIGNvbnN0IHNlbGVjdG9yID0gYXBwLndpZGdldFNlbGVjdG9yO1xuICAgIGlmIChzZWxlY3Rvcikge1xuICAgICAgY29uc3QgZWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcbiAgICAgIGlmIChlbCkgZWwuc3R5bGUuZGlzcGxheSA9IG5ld1N0YXRlID8gJycgOiAnbm9uZSc7XG4gICAgfVxuXG4gICAgLy8gVXBkYXRlIHRoZSBiYWRnZSBpbiB0aGUgYXBwIHNlbGVjdG9yIGNhcmRcbiAgICBjb25zdCBiYWRnZSA9IG9wdGlvbkVsLnF1ZXJ5U2VsZWN0b3IoJ2RpdltzdHlsZSo9XCJib3JkZXItcmFkaXVzOiA0cHhcIl0nKTtcbiAgICBpZiAoYmFkZ2UpIHtcbiAgICAgIGJhZGdlLnRleHRDb250ZW50ID0gbmV3U3RhdGUgPyAnT04nIDogJ09GRic7XG4gICAgICBiYWRnZS5zdHlsZS5iYWNrZ3JvdW5kID0gbmV3U3RhdGUgPyAnIzJlY2M3MTMwJyA6ICcjZTc0YzNjMzAnO1xuICAgICAgYmFkZ2Uuc3R5bGUuY29sb3IgPSBuZXdTdGF0ZSA/ICcjMmVjYzcxJyA6ICcjZTc0YzNjJztcbiAgICB9XG5cbiAgICBzaG93Tm90aWZpY2F0aW9uKGAke2FwcC5uYW1lfSB3aWRnZXQgJHtuZXdTdGF0ZSA/ICdlbmFibGVkJyA6ICdkaXNhYmxlZCd9YCwgJ3N1Y2Nlc3MnLCAyMDAwKTtcbiAgfVxuXG4gIC8vIFNob3cgZGVwbG95bWVudCBjb25maWd1cmF0aW9uIG1vZGFsXG4gIGFzeW5jIGZ1bmN0aW9uIHNob3dEZXBsb3lDb25maWcoYXBwVGVtcGxhdGUpIHtcbiAgICBjb25zdCBkZXBsb3lNb2RhbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhcHAtZGVwbG95LW1vZGFsJyk7XG4gICAgY29uc3QgdGl0bGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXBwLWRlcGxveS10aXRsZScpO1xuICAgIGNvbnN0IHN1YmRvbWFpbklucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RlcGxveS1zdWJkb21haW4nKTtcbiAgICBjb25zdCB1cmxQcmV2aWV3ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RlcGxveS11cmwtcHJldmlldycpO1xuICAgIGNvbnN0IGlwSW5wdXQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGVwbG95LWlwJyk7XG4gICAgY29uc3QgcG9ydElucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RlcGxveS1wb3J0Jyk7XG4gICAgY29uc3QgdGFpbHNjYWxlQ2hlY2tib3ggPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGVwbG95LXRhaWxzY2FsZS1vbmx5Jyk7XG4gICAgY29uc3QgdGFpbHNjYWxlU3RhdHVzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RhaWxzY2FsZS1zdGF0dXMnKTtcblxuICAgIC8vIENoZWNrIGZvciBleGlzdGluZyBjb250YWluZXIgd2l0aCBzYW1lIGltYWdlXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNoZWNrUmVzcG9uc2UgPSBhd2FpdCBzZWN1cmVGZXRjaCgnL2FwaS92MS9hcHBzL2NoZWNrLWV4aXN0aW5nJywge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsgYXBwSWQ6IGFwcFRlbXBsYXRlLmlkIH0pXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGNoZWNrUmVzdWx0ID0gYXdhaXQgY2hlY2tSZXNwb25zZS5qc29uKCk7XG5cbiAgICAgIGlmIChjaGVja1Jlc3VsdC5zdWNjZXNzICYmIGNoZWNrUmVzdWx0LmV4aXN0cykge1xuICAgICAgICBjb25zdCBjb250YWluZXIgPSBjaGVja1Jlc3VsdC5jb250YWluZXI7XG4gICAgICAgIGNvbnN0IHVzZUV4aXN0aW5nID0gY29uZmlybShcbiAgICAgICAgICBgRm91bmQgZXhpc3RpbmcgJHthcHBUZW1wbGF0ZS5uYW1lfSBjb250YWluZXI6XFxuXFxuYCArXG4gICAgICAgICAgYENvbnRhaW5lcjogJHtjb250YWluZXIubmFtZX1cXG5gICtcbiAgICAgICAgICBgU3RhdHVzOiAke2NvbnRhaW5lci5zdGF0dXN9XFxuYCArXG4gICAgICAgICAgYFBvcnQ6ICR7Y29udGFpbmVyLnByaW1hcnlQb3J0IHx8ICdOL0EnfVxcblxcbmAgK1xuICAgICAgICAgIGBXb3VsZCB5b3UgbGlrZSB0byB1c2UgdGhpcyBleGlzdGluZyBjb250YWluZXI/XFxuXFxuYCArXG4gICAgICAgICAgYENsaWNrIE9LIHRvIGNvbmZpZ3VyZSBETlMvQ2FkZHkgZm9yIHRoZSBleGlzdGluZyBjb250YWluZXIuXFxuYCArXG4gICAgICAgICAgYENsaWNrIENhbmNlbCB0byBkZXBsb3kgYSBuZXcgY29udGFpbmVyLmBcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAodXNlRXhpc3RpbmcpIHtcbiAgICAgICAgICAvLyBTdG9yZSBleGlzdGluZyBjb250YWluZXIgaW5mbyBmb3IgZGVwbG95bWVudFxuICAgICAgICAgIGFwcFRlbXBsYXRlLl91c2VFeGlzdGluZyA9IHRydWU7XG4gICAgICAgICAgYXBwVGVtcGxhdGUuX2V4aXN0aW5nQ29udGFpbmVyID0gY29udGFpbmVyO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gSWdub3JlIGNvbnRhaW5lciBjaGVjayBlcnJvcnNcbiAgICB9XG5cbiAgICAvLyBTZXQgdGl0bGUgd2l0aCBhcHAgaW5mb1xuICAgIHRpdGxlLnRleHRDb250ZW50ID0gYERlcGxveSAke2FwcFRlbXBsYXRlLm5hbWV9YDtcblxuICAgIC8vIFByZS1maWxsIHN1YmRvbWFpbiBmcm9tIHRlbXBsYXRlIG9yIGFwcCBJRFxuICAgIGNvbnN0IGRlZmF1bHRTdWJkb21haW4gPSBhcHBUZW1wbGF0ZS5zdWJkb21haW4gfHwgYXBwVGVtcGxhdGUuaWQucmVwbGFjZSgvLS9nLCAnJyk7XG4gICAgc3ViZG9tYWluSW5wdXQudmFsdWUgPSBkZWZhdWx0U3ViZG9tYWluO1xuXG4gICAgLy8gU2hvdyBzdWJwYXRoIGNvbXBhdGliaWxpdHkgd2FybmluZyBpbiBzdWJkaXJlY3RvcnkgbW9kZVxuICAgIGNvbnN0IHN1YnBhdGhXYXJuaW5nID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N1YnBhdGgtY29tcGF0LXdhcm5pbmcnKTtcbiAgICBpZiAoc3VicGF0aFdhcm5pbmcpIHtcbiAgICAgIGlmIChTSVRFLnJvdXRpbmdNb2RlID09PSAnc3ViZGlyZWN0b3J5Jykge1xuICAgICAgICBjb25zdCBzdXBwb3J0ID0gYXBwVGVtcGxhdGUuc3VicGF0aFN1cHBvcnQgfHwgJ3N0cmlwJztcbiAgICAgICAgaWYgKHN1cHBvcnQgPT09ICdub25lJykge1xuICAgICAgICAgIHN1YnBhdGhXYXJuaW5nLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgICAgIHN1YnBhdGhXYXJuaW5nLmlubmVySFRNTCA9ICc8c3BhbiBzdHlsZT1cImNvbG9yOiAjZmY5ODAwO1wiPiYjOTg4ODsgPHN0cm9uZz4nICsgYXBwVGVtcGxhdGUubmFtZSArICc8L3N0cm9uZz4gZG9lcyBub3Qgc3VwcG9ydCBzdWJkaXJlY3RvcnkgbW9kZS4gSXQgbWF5IG5vdCB3b3JrIGNvcnJlY3RseSBhdCBhIHN1YnBhdGguPC9zcGFuPic7XG4gICAgICAgIH0gZWxzZSBpZiAoc3VwcG9ydCA9PT0gJ3N0cmlwJykge1xuICAgICAgICAgIHN1YnBhdGhXYXJuaW5nLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgICAgIHN1YnBhdGhXYXJuaW5nLmlubmVySFRNTCA9ICc8c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+JiM5NDMyOyAnICsgYXBwVGVtcGxhdGUubmFtZSArICcgaGFzIHVudmVyaWZpZWQgc3ViZGlyZWN0b3J5IHN1cHBvcnQuIEl0IG1heSByZXF1aXJlIGFkZGl0aW9uYWwgY29uZmlndXJhdGlvbi48L3NwYW4+JztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzdWJwYXRoV2FybmluZy5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdWJwYXRoV2FybmluZy5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFByZS1zZWxlY3QgRE5TL1NTTCBmcm9tIHNpdGUgY29uZmlnIChzZXQgZHVyaW5nIHNldHVwIHdpemFyZClcbiAgICBjb25zdCBjZmdEbnNUeXBlID0gU0lURS5kZWZhdWx0cy5kbnNUeXBlIHx8IChTSVRFLmNvbmZpZ3VyYXRpb25UeXBlID09PSAncHVibGljJyA/ICdwdWJsaWMnIDogJ3ByaXZhdGUnKTtcbiAgICBjb25zdCBjZmdTc2xUeXBlID0gU0lURS5kZWZhdWx0cy5zc2xUeXBlIHx8IChTSVRFLmNvbmZpZ3VyYXRpb25UeXBlID09PSAncHVibGljJyA/ICdsZXRzZW5jcnlwdCcgOiAnaW50ZXJuYWwnKTtcbiAgICBjb25zdCBkbnNSYWRpbyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYGlucHV0W25hbWU9XCJkbnMtdHlwZVwiXVt2YWx1ZT1cIiR7Y2ZnRG5zVHlwZX1cIl1gKTtcbiAgICBjb25zdCBzc2xSYWRpbyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYGlucHV0W25hbWU9XCJzc2wtdHlwZVwiXVt2YWx1ZT1cIiR7Y2ZnU3NsVHlwZX1cIl1gKTtcbiAgICBpZiAoZG5zUmFkaW8pIGRuc1JhZGlvLmNoZWNrZWQgPSB0cnVlO1xuICAgIGVsc2UgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaW5wdXRbbmFtZT1cImRucy10eXBlXCJdW3ZhbHVlPVwicHJpdmF0ZVwiXScpLmNoZWNrZWQgPSB0cnVlO1xuICAgIGlmIChzc2xSYWRpbykgc3NsUmFkaW8uY2hlY2tlZCA9IHRydWU7XG4gICAgZWxzZSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdpbnB1dFtuYW1lPVwic3NsLXR5cGVcIl1bdmFsdWU9XCJpbnRlcm5hbFwiXScpLmNoZWNrZWQgPSB0cnVlO1xuICAgIGlwSW5wdXQudmFsdWUgPSBTSVRFLmRlZmF1bHRzLnRhcmdldElQIHx8ICdsb2NhbGhvc3QnO1xuICAgIHRhaWxzY2FsZUNoZWNrYm94LmNoZWNrZWQgPSBmYWxzZTtcblxuICAgIC8vIE1vdmUgRE5TL1NTTCBpbnRvIEFkdmFuY2VkIHNlY3Rpb24gd2hlbiBhbHJlYWR5IGNvbmZpZ3VyZWRcbiAgICBjb25zdCBkbnNTZWN0aW9uID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2FwcC1kZXBsb3ktbW9kYWwgLmZsZXgtY29sLWdhcCcpPy5jbG9zZXN0KCdkaXYnKTtcbiAgICBjb25zdCBhZHZhbmNlZERldGFpbHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYXBwLWRlcGxveS1tb2RhbCBkZXRhaWxzJyk7XG4gICAgY29uc3QgYWR2YW5jZWRDb250ZW50ID0gYWR2YW5jZWREZXRhaWxzPy5xdWVyeVNlbGVjdG9yKCdkaXYnKTtcbiAgICBpZiAoYWR2YW5jZWREZXRhaWxzICYmIGFkdmFuY2VkQ29udGVudCAmJiAoU0lURS5jb25maWd1cmF0aW9uVHlwZSA9PT0gJ3B1YmxpYycgfHwgU0lURS5jb25maWd1cmF0aW9uVHlwZSA9PT0gJ2hvbWVsYWInKSkge1xuICAgICAgLy8gTW92ZSBETlMgYW5kIFNTTCBzZWN0aW9ucyBpbnNpZGUgQWR2YW5jZWRcbiAgICAgIGNvbnN0IGRuc1NlY3Rpb25FbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJyNhcHAtZGVwbG95LW1vZGFsIGlucHV0W25hbWU9XCJkbnMtdHlwZVwiXScpWzBdPy5jbG9zZXN0KCdkaXYuZmxleC1jb2wtZ2FwJyk/LnBhcmVudEVsZW1lbnQ7XG4gICAgICBjb25zdCBzc2xTZWN0aW9uRWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcjYXBwLWRlcGxveS1tb2RhbCBpbnB1dFtuYW1lPVwic3NsLXR5cGVcIl0nKVswXT8uY2xvc2VzdCgnZGl2LmZsZXgtY29sLWdhcCcpPy5wYXJlbnRFbGVtZW50O1xuICAgICAgaWYgKGRuc1NlY3Rpb25FbCAmJiAhZG5zU2VjdGlvbkVsLmRhdGFzZXQubW92ZWQpIHtcbiAgICAgICAgYWR2YW5jZWRDb250ZW50LmFwcGVuZENoaWxkKGRuc1NlY3Rpb25FbCk7XG4gICAgICAgIGRuc1NlY3Rpb25FbC5kYXRhc2V0Lm1vdmVkID0gJzEnO1xuICAgICAgfVxuICAgICAgaWYgKHNzbFNlY3Rpb25FbCAmJiAhc3NsU2VjdGlvbkVsLmRhdGFzZXQubW92ZWQpIHtcbiAgICAgICAgYWR2YW5jZWRDb250ZW50LmFwcGVuZENoaWxkKHNzbFNlY3Rpb25FbCk7XG4gICAgICAgIHNzbFNlY3Rpb25FbC5kYXRhc2V0Lm1vdmVkID0gJzEnO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEhhbmRsZSBtZWRpYSBwYXRoIHNlY3Rpb24gZm9yIG1lZGlhIGFwcHNcbiAgICBjb25zdCBtZWRpYVBhdGhTZWN0aW9uID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21lZGlhLXBhdGgtc2VjdGlvbicpO1xuICAgIGNvbnN0IG1lZGlhUGF0aElucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RlcGxveS1tZWRpYS1wYXRoJyk7XG4gICAgY29uc3QgbWVkaWFQYXRoRGVzY3JpcHRpb24gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWVkaWEtcGF0aC1kZXNjcmlwdGlvbicpO1xuXG4gICAgaWYgKGFwcFRlbXBsYXRlLm1lZGlhTW91bnQpIHtcbiAgICAgIG1lZGlhUGF0aFNlY3Rpb24uc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICBtZWRpYVBhdGhJbnB1dC52YWx1ZSA9ICcnO1xuICAgICAgbWVkaWFQYXRoSW5wdXQucGxhY2Vob2xkZXIgPSAnL21lZGlhL01vdmllcywgL21lZGlhL1RWU2hvd3Mgb3IgY2xpY2sgQnJvd3NlJztcblxuICAgICAgLy8gRmV0Y2ggZGV0ZWN0ZWQgbW91bnRzIGZyb20gZXhpc3RpbmcgbWVkaWEgc2VydmVyc1xuICAgICAgY29uc3QgZGV0ZWN0ZWRNb3VudHNDb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGV0ZWN0ZWQtbW91bnRzLWNvbnRhaW5lcicpO1xuICAgICAgY29uc3QgZGV0ZWN0ZWRNb3VudHNMaXN0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RldGVjdGVkLW1vdW50cy1saXN0Jyk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IG1vdW50c1Jlc3BvbnNlID0gYXdhaXQgZmV0Y2goJy9hcGkvdjEvbWVkaWEvZGV0ZWN0ZWQtbW91bnRzJyk7XG4gICAgICAgIGNvbnN0IG1vdW50c1Jlc3VsdCA9IGF3YWl0IG1vdW50c1Jlc3BvbnNlLmpzb24oKTtcblxuICAgICAgICBpZiAobW91bnRzUmVzdWx0LnN1Y2Nlc3MgJiYgbW91bnRzUmVzdWx0Lm1vdW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgZGV0ZWN0ZWRNb3VudHNDb250YWluZXIuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICAgICAgZGV0ZWN0ZWRNb3VudHNMaXN0LmlubmVySFRNTCA9ICcnO1xuXG4gICAgICAgICAgLy8gQXV0by1maWxsIG1lZGlhIHBhdGggd2l0aCBhbGwgZGV0ZWN0ZWQgbW91bnRzXG4gICAgICAgICAgY29uc3QgYXV0b1BhdGhzID0gWy4uLm5ldyBTZXQobW91bnRzUmVzdWx0Lm1vdW50cy5tYXAobSA9PiBtLmhvc3RQYXRoKSldO1xuICAgICAgICAgIG1lZGlhUGF0aElucHV0LnZhbHVlID0gYXV0b1BhdGhzLmpvaW4oJywgJyk7XG5cbiAgICAgICAgICBtb3VudHNSZXN1bHQubW91bnRzLmZvckVhY2gobW91bnQgPT4ge1xuICAgICAgICAgICAgY29uc3QgYnRuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYnV0dG9uJyk7XG4gICAgICAgICAgICBidG4udHlwZSA9ICdidXR0b24nO1xuICAgICAgICAgICAgY29uc3QgaXNTZWxlY3RlZCA9IGF1dG9QYXRocy5pbmNsdWRlcyhtb3VudC5ob3N0UGF0aCk7XG4gICAgICAgICAgICBidG4uc3R5bGUuY3NzVGV4dCA9IGBwYWRkaW5nOiA4cHggMTRweDsgZm9udC1zaXplOiAwLjg1cmVtOyBiYWNrZ3JvdW5kOiBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tc3VjY2VzcykgJHtpc1NlbGVjdGVkID8gJzQwJScgOiAnMTUlJ30sIHZhcigtLWNhcmQtYmcpKTsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tc3VjY2Vzcyk7IGJvcmRlci1yYWRpdXM6IDZweDsgY3Vyc29yOiBwb2ludGVyOyBjb2xvcjogdmFyKC0tZmcpO2A7XG4gICAgICAgICAgICBidG4uaW5uZXJIVE1MID0gYDxzcGFuIHN0eWxlPVwiZm9udC13ZWlnaHQ6IDUwMDtcIj4ke2VzY2FwZUh0bWwobW91bnQuZm9sZGVyTmFtZSl9PC9zcGFuPjxicj48c3BhbiBzdHlsZT1cImZvbnQtc2l6ZTogMC43cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPmZyb20gJHtlc2NhcGVIdG1sKG1vdW50LnNvdXJjZUltYWdlKX08L3NwYW4+YDtcbiAgICAgICAgICAgIGJ0bi50aXRsZSA9IGAke21vdW50Lmhvc3RQYXRofSAoZnJvbSAke21vdW50LnNvdXJjZUNvbnRhaW5lcn0pYDtcbiAgICAgICAgICAgIGJ0bi5vbmNsaWNrID0gKCkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBjdXJyZW50UGF0aHMgPSBtZWRpYVBhdGhJbnB1dC52YWx1ZS5zcGxpdCgnLCcpLm1hcChwID0+IHAudHJpbSgpKS5maWx0ZXIocCA9PiBwKTtcbiAgICAgICAgICAgICAgY29uc3QgaWR4ID0gY3VycmVudFBhdGhzLmluZGV4T2YobW91bnQuaG9zdFBhdGgpO1xuICAgICAgICAgICAgICBpZiAoaWR4ID49IDApIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50UGF0aHMuc3BsaWNlKGlkeCwgMSk7XG4gICAgICAgICAgICAgICAgYnRuLnN0eWxlLmJhY2tncm91bmQgPSAnY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLXN1Y2Nlc3MpIDE1JSwgdmFyKC0tY2FyZC1iZykpJztcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50UGF0aHMucHVzaChtb3VudC5ob3N0UGF0aCk7XG4gICAgICAgICAgICAgICAgYnRuLnN0eWxlLmJhY2tncm91bmQgPSAnY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLXN1Y2Nlc3MpIDQwJSwgdmFyKC0tY2FyZC1iZykpJztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBtZWRpYVBhdGhJbnB1dC52YWx1ZSA9IGN1cnJlbnRQYXRocy5qb2luKCcsICcpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGRldGVjdGVkTW91bnRzTGlzdC5hcHBlbmRDaGlsZChidG4pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRldGVjdGVkTW91bnRzQ29udGFpbmVyLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgZGV0ZWN0ZWRNb3VudHNDb250YWluZXIuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgIH1cblxuICAgICAgLy8gU2V0IHVwIGJyb3dzZSBidXR0b25cbiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdicm93c2UtbWVkaWEtYnRuJykub25jbGljayA9ICgpID0+IHtcbiAgICAgICAgb3BlbkZvbGRlckJyb3dzZXIobWVkaWFQYXRoSW5wdXQpO1xuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgbWVkaWFQYXRoU2VjdGlvbi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgbWVkaWFQYXRoSW5wdXQudmFsdWUgPSAnJztcbiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkZXRlY3RlZC1tb3VudHMtY29udGFpbmVyJykuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICB9XG5cbiAgICAvLyBTaG93IFBsZXggY2xhaW0gdG9rZW4gc2VjdGlvbiBmb3IgUGxleCBkZXBsb3ltZW50c1xuICAgIGNvbnN0IHBsZXhDbGFpbVNlY3Rpb24gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncGxleC1jbGFpbS1zZWN0aW9uJyk7XG4gICAgaWYgKHBsZXhDbGFpbVNlY3Rpb24pIHtcbiAgICAgIGlmIChhcHBUZW1wbGF0ZS5pZCA9PT0gJ3BsZXgnIHx8IGFwcFRlbXBsYXRlLmNsYWltVG9rZW4pIHtcbiAgICAgICAgcGxleENsYWltU2VjdGlvbi5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RlcGxveS1wbGV4LWNsYWltJykudmFsdWUgPSAnJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBsZXhDbGFpbVNlY3Rpb24uc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBQb3B1bGF0ZSB2b2x1bWUgbW91bnRzIGluIEFkdmFuY2VkIE9wdGlvbnNcbiAgICBjb25zdCB2b2x1bWVTZWN0aW9uID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3ZvbHVtZS1tb3VudHMtc2VjdGlvbicpO1xuICAgIGNvbnN0IHZvbHVtZUxpc3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndm9sdW1lLW1vdW50cy1saXN0Jyk7XG4gICAgdm9sdW1lTGlzdC5pbm5lckhUTUwgPSAnJztcblxuICAgIGlmIChhcHBUZW1wbGF0ZS5kb2NrZXI/LnZvbHVtZXM/Lmxlbmd0aCkge1xuICAgICAgY29uc3QgbWVkaWFDb250YWluZXJQYXRoID0gYXBwVGVtcGxhdGUubWVkaWFNb3VudD8uY29udGFpbmVyUGF0aDtcbiAgICAgIGNvbnN0IG5vbk1lZGlhVm9sdW1lcyA9IGFwcFRlbXBsYXRlLmRvY2tlci52b2x1bWVzLmZpbHRlcih2ID0+ICF2LmluY2x1ZGVzKCd7e01FRElBX1BBVEh9fScpICYmICEobWVkaWFDb250YWluZXJQYXRoICYmIHYuZW5kc1dpdGgoJzonICsgbWVkaWFDb250YWluZXJQYXRoKSkpO1xuXG4gICAgICBpZiAobm9uTWVkaWFWb2x1bWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdm9sdW1lU2VjdGlvbi5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgICAgbm9uTWVkaWFWb2x1bWVzLmZvckVhY2goKHZvbCwgaSkgPT4ge1xuICAgICAgICAgIGNvbnN0IFtob3N0RGVmYXVsdCwgY29udGFpbmVyUGF0aF0gPSB2b2wuc3BsaXQoJzonKTtcbiAgICAgICAgICBjb25zdCByb3cgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICByb3cuc3R5bGUuY3NzVGV4dCA9ICdkaXNwbGF5OiBmbGV4OyBnYXA6IDZweDsgYWxpZ24taXRlbXM6IGNlbnRlcjsnO1xuICAgICAgICAgIHJvdy5pbm5lckhUTUwgPSBgXG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cInZvbC1ob3N0LXBhdGhcIiBkYXRhLWNvbnRhaW5lci1wYXRoPVwiJHtjb250YWluZXJQYXRofVwiIHZhbHVlPVwiJHtob3N0RGVmYXVsdH1cIlxuICAgICAgICAgICAgICAgICAgIHN0eWxlPVwiZmxleDogMTsgcGFkZGluZzogOHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJnKTsgY29sb3I6IHZhcigtLWZnKTsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgYm9yZGVyLXJhZGl1czogNnB4OyBmb250LXNpemU6IDAuODVyZW07XCIgLz5cbiAgICAgICAgICAgIDxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTsgZm9udC1zaXplOiAwLjg1cmVtOyB3aGl0ZS1zcGFjZTogbm93cmFwO1wiPlx1MjE5MiAke2NvbnRhaW5lclBhdGh9PC9zcGFuPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJ2b2wtYnJvd3NlLWJ0blwiIHN0eWxlPVwicGFkZGluZzogOHB4IDEwcHg7IGJhY2tncm91bmQ6IHZhcigtLWFjY2VudCk7IGNvbG9yOiB3aGl0ZTsgYm9yZGVyOiBub25lOyBib3JkZXItcmFkaXVzOiA2cHg7IGN1cnNvcjogcG9pbnRlcjsgZm9udC1zaXplOiAwLjhyZW07XCI+XHVEODNEXHVEQ0MyPC9idXR0b24+XG4gICAgICAgICAgYDtcbiAgICAgICAgICB2b2x1bWVMaXN0LmFwcGVuZENoaWxkKHJvdyk7XG4gICAgICAgICAgcm93LnF1ZXJ5U2VsZWN0b3IoJy52b2wtYnJvd3NlLWJ0bicpLm9uY2xpY2sgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBpbnB1dCA9IHJvdy5xdWVyeVNlbGVjdG9yKCcudm9sLWhvc3QtcGF0aCcpO1xuICAgICAgICAgICAgb3BlbkZvbGRlckJyb3dzZXIoaW5wdXQpO1xuICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdm9sdW1lU2VjdGlvbi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB2b2x1bWVTZWN0aW9uLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgfVxuXG4gICAgLy8gU2V0IGRlZmF1bHQgcG9ydCBmcm9tIHRlbXBsYXRlIGFuZCBjaGVjayBhdmFpbGFiaWxpdHlcbiAgICBjb25zdCBkZWZhdWx0UG9ydCA9IGFwcFRlbXBsYXRlLmRlZmF1bHRQb3J0IHx8IDgwODA7XG4gICAgcG9ydElucHV0LnZhbHVlID0gJyc7XG4gICAgcG9ydElucHV0LnBsYWNlaG9sZGVyID0gYERlZmF1bHQ6ICR7ZGVmYXVsdFBvcnR9YDtcblxuICAgIC8vIEFkZCBwb3J0IHN0YXR1cyBlbGVtZW50IGlmIG5vdCBleGlzdHNcbiAgICBsZXQgcG9ydFN0YXR1cyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkZXBsb3ktcG9ydC1zdGF0dXMnKTtcbiAgICBpZiAoIXBvcnRTdGF0dXMpIHtcbiAgICAgIHBvcnRTdGF0dXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIHBvcnRTdGF0dXMuaWQgPSAnZGVwbG95LXBvcnQtc3RhdHVzJztcbiAgICAgIHBvcnRTdGF0dXMuc3R5bGUuY3NzVGV4dCA9ICdmb250LXNpemU6IDAuOHJlbTsgbWFyZ2luLXRvcDogNHB4Oyc7XG4gICAgICBwb3J0SW5wdXQucGFyZW50Tm9kZS5hcHBlbmRDaGlsZChwb3J0U3RhdHVzKTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBkZWZhdWx0IHBvcnQgYXZhaWxhYmlsaXR5XG4gICAgYXN5bmMgZnVuY3Rpb24gY2hlY2tBbmRVcGRhdGVQb3J0U3RhdHVzKCkge1xuICAgICAgY29uc3QgcG9ydFRvQ2hlY2sgPSBwb3J0SW5wdXQudmFsdWUgfHwgZGVmYXVsdFBvcnQ7XG4gICAgICBwb3J0U3RhdHVzLmlubmVySFRNTCA9ICc8c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+Q2hlY2tpbmcgcG9ydC4uLjwvc3Bhbj4nO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjaGVja1BvcnRBdmFpbGFiaWxpdHkocG9ydFRvQ2hlY2spO1xuICAgICAgaWYgKHJlc3VsdC5hdmFpbGFibGUpIHtcbiAgICAgICAgcG9ydFN0YXR1cy5pbm5lckhUTUwgPSBgPHNwYW4gc3R5bGU9XCJjb2xvcjogIzRjYWY1MDtcIj5Qb3J0ICR7ZXNjYXBlSHRtbChTdHJpbmcocG9ydFRvQ2hlY2spKX0gaXMgYXZhaWxhYmxlPC9zcGFuPmA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBzdWdnZXN0ZWRQb3J0ID0gYXdhaXQgZ2V0U3VnZ2VzdGVkUG9ydChkZWZhdWx0UG9ydCk7XG4gICAgICAgIHBvcnRTdGF0dXMuaW5uZXJIVE1MID0gYFxuICAgICAgICAgIDxzcGFuIHN0eWxlPVwiY29sb3I6ICNlNzRjM2M7XCI+UG9ydCAke2VzY2FwZUh0bWwocG9ydFRvQ2hlY2spfSBpbiB1c2UgYnkgJHtlc2NhcGVIdG1sKHJlc3VsdC5jb25mbGljdD8udXNlZEJ5IHx8ICd1bmtub3duJyl9PC9zcGFuPlxuICAgICAgICBgO1xuICAgICAgICBjb25zdCB1c2VCdG4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdidXR0b24nKTtcbiAgICAgICAgdXNlQnRuLnR5cGUgPSAnYnV0dG9uJztcbiAgICAgICAgdXNlQnRuLnRleHRDb250ZW50ID0gYFVzZSAke3N1Z2dlc3RlZFBvcnR9YDtcbiAgICAgICAgdXNlQnRuLnN0eWxlLmNzc1RleHQgPSAnbWFyZ2luLWxlZnQ6IDhweDsgcGFkZGluZzogMnB4IDhweDsgZm9udC1zaXplOiAwLjc1cmVtOyBjdXJzb3I6IHBvaW50ZXI7JztcbiAgICAgICAgdXNlQnRuLm9uY2xpY2sgPSAoKSA9PiB7XG4gICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RlcGxveS1wb3J0JykudmFsdWUgPSBzdWdnZXN0ZWRQb3J0O1xuICAgICAgICAgIHBvcnRTdGF0dXMuaW5uZXJIVE1MID0gYDxzcGFuIHN0eWxlPVwiY29sb3I6ICM0Y2FmNTA7XCI+VXNpbmcgc3VnZ2VzdGVkIHBvcnQgJHtlc2NhcGVIdG1sKFN0cmluZyhzdWdnZXN0ZWRQb3J0KSl9PC9zcGFuPmA7XG4gICAgICAgIH07XG4gICAgICAgIHBvcnRTdGF0dXMuYXBwZW5kQ2hpbGQodXNlQnRuKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDaGVjayBwb3J0IG9uIGlucHV0IGNoYW5nZSAoZGVib3VuY2VkKVxuICAgIGxldCBwb3J0Q2hlY2tUaW1lb3V0O1xuICAgIHBvcnRJbnB1dC5vbmlucHV0ID0gZnVuY3Rpb24oKSB7XG4gICAgICBjbGVhclRpbWVvdXQocG9ydENoZWNrVGltZW91dCk7XG4gICAgICBwb3J0Q2hlY2tUaW1lb3V0ID0gc2V0VGltZW91dChjaGVja0FuZFVwZGF0ZVBvcnRTdGF0dXMsIDUwMCk7XG4gICAgfTtcblxuICAgIC8vIEluaXRpYWwgcG9ydCBjaGVja1xuICAgIGNoZWNrQW5kVXBkYXRlUG9ydFN0YXR1cygpO1xuXG4gICAgLy8gRmV0Y2ggVGFpbHNjYWxlIHN0YXR1c1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL3RhaWxzY2FsZS9zdGF0dXMnKTtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICBpZiAoZGF0YS5zdWNjZXNzICYmIGRhdGEuaW5zdGFsbGVkICYmIGRhdGEuY29ubmVjdGVkKSB7XG4gICAgICAgIHRhaWxzY2FsZVN0YXR1cy5pbm5lckhUTUwgPSBgXG4gICAgICAgICAgPHNwYW4gc3R5bGU9XCJjb2xvcjogIzRjYWY1MDtcIj5Db25uZWN0ZWQ8L3NwYW4+XG4gICAgICAgICAgPHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW4tbGVmdDogOHB4O1wiPiR7ZGF0YS5zZWxmPy5ob3N0bmFtZX0gKCR7ZGF0YS5zZWxmPy5pcH0pPC9zcGFuPlxuICAgICAgICAgIDxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLWxlZnQ6IDhweDtcIj58ICR7ZGF0YS5kZXZpY2VDb3VudH0gZGV2aWNlczwvc3Bhbj5cbiAgICAgICAgYDtcbiAgICAgIH0gZWxzZSBpZiAoZGF0YS5pbnN0YWxsZWQpIHtcbiAgICAgICAgdGFpbHNjYWxlU3RhdHVzLmlubmVySFRNTCA9IGA8c3BhbiBzdHlsZT1cImNvbG9yOiAjZmY5ODAwO1wiPk5vdCBjb25uZWN0ZWQ8L3NwYW4+YDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRhaWxzY2FsZVN0YXR1cy5pbm5lckhUTUwgPSBgPHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPk5vdCBhdmFpbGFibGU8L3NwYW4+YDtcbiAgICAgICAgdGFpbHNjYWxlQ2hlY2tib3guZGlzYWJsZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRhaWxzY2FsZVN0YXR1cy5pbm5lckhUTUwgPSBgPHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPkNvdWxkIG5vdCBjaGVjayBzdGF0dXM8L3NwYW4+YDtcbiAgICB9XG5cbiAgICAvLyBVcGRhdGUgVVJMIHByZXZpZXcgaW4gcmVhbC10aW1lXG4gICAgZnVuY3Rpb24gdXBkYXRlVXJsUHJldmlldygpIHtcbiAgICAgIGNvbnN0IHN1YmRvbWFpbiA9IHN1YmRvbWFpbklucHV0LnZhbHVlIHx8ICdzdWJkb21haW4nO1xuICAgICAgY29uc3QgZG5zVHlwZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0W25hbWU9XCJkbnMtdHlwZVwiXTpjaGVja2VkJykudmFsdWU7XG4gICAgICBjb25zdCBzc2xUeXBlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaW5wdXRbbmFtZT1cInNzbC10eXBlXCJdOmNoZWNrZWQnKS52YWx1ZTtcblxuICAgICAgbGV0IHVybCA9ICcnO1xuICAgICAgaWYgKFNJVEUucm91dGluZ01vZGUgPT09ICdzdWJkaXJlY3RvcnknICYmIFNJVEUuZG9tYWluKSB7XG4gICAgICAgIC8vIFN1YmRpcmVjdG9yeSBtb2RlOiBkb21haW4uY29tL2FwcFxuICAgICAgICB1cmwgPSBgaHR0cHM6Ly8ke1NJVEUuZG9tYWlufS8ke3N1YmRvbWFpbn1gO1xuICAgICAgfSBlbHNlIGlmIChkbnNUeXBlID09PSAncHJpdmF0ZScpIHtcbiAgICAgICAgY29uc3QgcHJvdG9jb2wgPSBzc2xUeXBlID09PSAnbm9uZScgPyAnaHR0cCcgOiAnaHR0cHMnO1xuICAgICAgICB1cmwgPSBgJHtwcm90b2NvbH06Ly8ke2J1aWxkRG9tYWluKHN1YmRvbWFpbil9YDtcbiAgICAgIH0gZWxzZSBpZiAoZG5zVHlwZSA9PT0gJ3B1YmxpYycpIHtcbiAgICAgICAgY29uc3QgcHJvdG9jb2wgPSBzc2xUeXBlID09PSAnbm9uZScgPyAnaHR0cCcgOiAnaHR0cHMnO1xuICAgICAgICBjb25zdCBkb21haW4gPSBTSVRFLmRvbWFpbiB8fCBzdWJkb21haW47XG4gICAgICAgIHVybCA9IFNJVEUuZG9tYWluID8gYCR7cHJvdG9jb2x9Oi8vJHtzdWJkb21haW59LiR7U0lURS5kb21haW59YCA6IGAke3Byb3RvY29sfTovLyR7c3ViZG9tYWlufWA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBwb3J0ID0gcG9ydElucHV0LnZhbHVlIHx8IGFwcFRlbXBsYXRlLmRlZmF1bHRQb3J0IHx8IERDLkRFRkFVTFRTLlNFUlZJQ0VfUE9SVDtcbiAgICAgICAgdXJsID0gYGh0dHA6Ly8ke2lwSW5wdXQudmFsdWV9OiR7cG9ydH1gO1xuICAgICAgfVxuICAgICAgdXJsUHJldmlldy50ZXh0Q29udGVudCA9IHVybDtcbiAgICB9XG5cbiAgICAvLyBBdHRhY2ggbGlzdGVuZXJzXG4gICAgc3ViZG9tYWluSW5wdXQub25pbnB1dCA9IHVwZGF0ZVVybFByZXZpZXc7XG4gICAgaXBJbnB1dC5vbmlucHV0ID0gdXBkYXRlVXJsUHJldmlldztcbiAgICBwb3J0SW5wdXQub25pbnB1dCA9IHVwZGF0ZVVybFByZXZpZXc7XG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnaW5wdXRbbmFtZT1cImRucy10eXBlXCJdJykuZm9yRWFjaChyYWRpbyA9PiB7XG4gICAgICByYWRpby5vbmNoYW5nZSA9IHVwZGF0ZVVybFByZXZpZXc7XG4gICAgfSk7XG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnaW5wdXRbbmFtZT1cInNzbC10eXBlXCJdJykuZm9yRWFjaChyYWRpbyA9PiB7XG4gICAgICByYWRpby5vbmNoYW5nZSA9IHVwZGF0ZVVybFByZXZpZXc7XG4gICAgfSk7XG5cbiAgICB1cGRhdGVVcmxQcmV2aWV3KCk7XG5cbiAgICAvLyBDbG9zZSBhcHAgc2VsZWN0b3IsIG9wZW4gZGVwbG95IGNvbmZpZ1xuICAgIG1vZGFsLmNsYXNzTGlzdC5yZW1vdmUoJ3Nob3cnKTtcbiAgICBkZXBsb3lNb2RhbC5jbGFzc0xpc3QuYWRkKCdzaG93Jyk7XG5cbiAgICAvLyBTdG9yZSBhcHAgdGVtcGxhdGUgZm9yIGRlcGxveW1lbnRcbiAgICBkZXBsb3lNb2RhbC5kYXRhc2V0LmFwcFRlbXBsYXRlID0gSlNPTi5zdHJpbmdpZnkoYXBwVGVtcGxhdGUpO1xuICB9XG5cbiAgLy8gQWRkIGFwcCB0byBncmlkIHdpdGggZnVsbCBEb2NrZXIgZGVwbG95bWVudFxuICBhc3luYyBmdW5jdGlvbiBhZGRBcHBUb0dyaWQoZGVwbG95Q29uZmlnKSB7XG4gICAgY29uc3QgYXBwVGVtcGxhdGUgPSBkZXBsb3lDb25maWcuYXBwVGVtcGxhdGU7XG4gICAgY29uc3QgY3VzdG9tQXBwcyA9IHNhZmVHZXRKU09OKEFQUFNfS0VZLCBbXSk7XG5cbiAgICAvLyBDaGVjayBpZiB1c2luZyBleGlzdGluZyBjb250YWluZXJcbiAgICBjb25zdCB1c2luZ0V4aXN0aW5nID0gYXBwVGVtcGxhdGUuX3VzZUV4aXN0aW5nICYmIGFwcFRlbXBsYXRlLl9leGlzdGluZ0NvbnRhaW5lcjtcblxuICAgIC8vIENoZWNrIGlmIGFwcCBhbHJlYWR5IGV4aXN0cyAtIHNraXAgaWYgdXNpbmcgZXhpc3RpbmcgY29udGFpbmVyICh1c2VyIGFscmVhZHkgY29uZmlybWVkKVxuICAgIGNvbnN0IGV4aXN0aW5nQXBwID0gY3VzdG9tQXBwcy5maW5kKGEgPT4gYS5pZCA9PT0gZGVwbG95Q29uZmlnLnN1YmRvbWFpbik7XG4gICAgaWYgKGV4aXN0aW5nQXBwICYmICF1c2luZ0V4aXN0aW5nKSB7XG4gICAgICBjb25zdCBjb25maXJtZWQgPSBjb25maXJtKGBBbiBhcHAgd2l0aCBzdWJkb21haW4gXCIke2RlcGxveUNvbmZpZy5zdWJkb21haW59XCIgYWxyZWFkeSBleGlzdHMuIFJlZGVwbG95P2ApO1xuICAgICAgaWYgKCFjb25maXJtZWQpIHJldHVybjtcbiAgICB9XG4gICAgLy8gUmVtb3ZlIGZyb20gbG9jYWxTdG9yYWdlIHRvIGFsbG93IHJlZGVwbG95bWVudC91cGRhdGVcbiAgICBpZiAoZXhpc3RpbmdBcHApIHtcbiAgICAgIGNvbnN0IGluZGV4ID0gY3VzdG9tQXBwcy5pbmRleE9mKGV4aXN0aW5nQXBwKTtcbiAgICAgIGN1c3RvbUFwcHMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgIHNhZmVTZXQoQVBQU19LRVksIEpTT04uc3RyaW5naWZ5KGN1c3RvbUFwcHMpKTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBwb3J0IGF2YWlsYWJpbGl0eSBiZWZvcmUgZGVwbG95bWVudCAoc2tpcCBpZiB1c2luZyBleGlzdGluZyBjb250YWluZXIpXG4gICAgaWYgKCF1c2luZ0V4aXN0aW5nKSB7XG4gICAgICBjb25zdCBwb3J0VG9Vc2UgPSBkZXBsb3lDb25maWcucG9ydCB8fCBhcHBUZW1wbGF0ZS5kZWZhdWx0UG9ydCB8fCA4MDgwO1xuICAgICAgc2hvd05vdGlmaWNhdGlvbihgQ2hlY2tpbmcgcG9ydCAke3BvcnRUb1VzZX0gYXZhaWxhYmlsaXR5Li4uYCwgJ2luZm8nLCAwKTtcblxuICAgICAgY29uc3QgcG9ydENoZWNrID0gYXdhaXQgY2hlY2tQb3J0QXZhaWxhYmlsaXR5KHBvcnRUb1VzZSk7XG4gICAgICBpZiAoIXBvcnRDaGVjay5hdmFpbGFibGUpIHtcbiAgICAgICAgY29uc3Qgc3VnZ2VzdGVkUG9ydCA9IGF3YWl0IGdldFN1Z2dlc3RlZFBvcnQoYXBwVGVtcGxhdGUuZGVmYXVsdFBvcnQgfHwgODA4MCk7XG4gICAgICAgIGNvbnN0IHVzZUFsdGVybmF0ZSA9IGNvbmZpcm0oXG4gICAgICAgICAgYFBvcnQgJHtwb3J0VG9Vc2V9IGlzIGFscmVhZHkgaW4gdXNlIGJ5ICR7cG9ydENoZWNrLmNvbmZsaWN0Py51c2VkQnkgfHwgJ2Fub3RoZXIgY29udGFpbmVyJ30uXFxuXFxuYCArXG4gICAgICAgICAgYFdvdWxkIHlvdSBsaWtlIHRvIHVzZSBwb3J0ICR7c3VnZ2VzdGVkUG9ydH0gaW5zdGVhZD9gXG4gICAgICAgICk7XG4gICAgICAgIGlmICh1c2VBbHRlcm5hdGUpIHtcbiAgICAgICAgICBkZXBsb3lDb25maWcucG9ydCA9IHN1Z2dlc3RlZFBvcnQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2hvd05vdGlmaWNhdGlvbignRGVwbG95bWVudCBjYW5jZWxsZWQgLSBwb3J0IGNvbmZsaWN0JywgJ2Vycm9yJywgNTAwMCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFVzZSBleGlzdGluZyBjb250YWluZXIncyBwb3J0XG4gICAgICBkZXBsb3lDb25maWcucG9ydCA9IGFwcFRlbXBsYXRlLl9leGlzdGluZ0NvbnRhaW5lci5wcmltYXJ5UG9ydDtcbiAgICB9XG4gICAgc2hvd05vdGlmaWNhdGlvbihcbiAgICAgIHVzaW5nRXhpc3RpbmdcbiAgICAgICAgPyBgQ29uZmlndXJpbmcgJHthcHBUZW1wbGF0ZS5uYW1lfSB3aXRoIGV4aXN0aW5nIGNvbnRhaW5lci4uLmBcbiAgICAgICAgOiBgRGVwbG95aW5nICR7YXBwVGVtcGxhdGUubmFtZX0uLi5gLFxuICAgICAgJ2luZm8nLCAwXG4gICAgKTtcblxuICAgIHRyeSB7XG4gICAgICAvLyBQcmVwYXJlIGRlcGxveW1lbnQgY29uZmlnIGZyb20gdXNlcidzIGNob2ljZXNcbiAgICAgIGNvbnN0IGFwaURlcGxveUNvbmZpZyA9IHtcbiAgICAgICAgYXBwSWQ6IGFwcFRlbXBsYXRlLmlkLFxuICAgICAgICBjb25maWc6IHtcbiAgICAgICAgICBzdWJkb21haW46IGRlcGxveUNvbmZpZy5zdWJkb21haW4sXG4gICAgICAgICAgaXA6IGRlcGxveUNvbmZpZy5pcCxcbiAgICAgICAgICBjcmVhdGVEbnM6IGRlcGxveUNvbmZpZy5kbnNUeXBlID09PSAncHJpdmF0ZScsICAvLyBPbmx5IGNyZWF0ZSBETlMgZm9yIHByaXZhdGVcbiAgICAgICAgICBwb3J0OiBkZXBsb3lDb25maWcucG9ydCB8fCBhcHBUZW1wbGF0ZS5kZWZhdWx0UG9ydCB8fCBudWxsLCAgLy8gVXNlIGN1c3RvbSwgdGVtcGxhdGUgZGVmYXVsdCwgb3IgbnVsbFxuICAgICAgICAgIHNzbFR5cGU6IGRlcGxveUNvbmZpZy5zc2xUeXBlLFxuICAgICAgICAgIGRuc1R5cGU6IGRlcGxveUNvbmZpZy5kbnNUeXBlLFxuICAgICAgICAgIHRhaWxzY2FsZU9ubHk6IGRlcGxveUNvbmZpZy50YWlsc2NhbGVPbmx5IHx8IGZhbHNlLCAgLy8gVGFpbHNjYWxlLW9ubHkgYWNjZXNzIHJlc3RyaWN0aW9uXG4gICAgICAgICAgbWVkaWFQYXRoOiBkZXBsb3lDb25maWcubWVkaWFQYXRoIHx8IG51bGwsICAvLyBNZWRpYSBmb2xkZXIgcGF0aCBmb3IgbWVkaWEgYXBwc1xuICAgICAgICAgIHBsZXhDbGFpbVRva2VuOiBkZXBsb3lDb25maWcucGxleENsYWltVG9rZW4gfHwgbnVsbCwgIC8vIFBsZXggY2xhaW0gdG9rZW4gZm9yIGF1dG8tY2xhaW1cbiAgICAgICAgICBjdXN0b21Wb2x1bWVzOiBkZXBsb3lDb25maWcuY3VzdG9tVm9sdW1lcyB8fCBudWxsICAvLyBDdXN0b20gdm9sdW1lIG1vdW50IG92ZXJyaWRlc1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICAvLyBBZGQgZXhpc3RpbmcgY29udGFpbmVyIGluZm8gaWYgdXNpbmcgZXhpc3RpbmdcbiAgICAgIGlmICh1c2luZ0V4aXN0aW5nKSB7XG4gICAgICAgIGFwaURlcGxveUNvbmZpZy5jb25maWcudXNlRXhpc3RpbmcgPSB0cnVlO1xuICAgICAgICBhcGlEZXBsb3lDb25maWcuY29uZmlnLmV4aXN0aW5nQ29udGFpbmVySWQgPSBhcHBUZW1wbGF0ZS5fZXhpc3RpbmdDb250YWluZXIuaWQ7XG4gICAgICAgIGFwaURlcGxveUNvbmZpZy5jb25maWcuZXhpc3RpbmdQb3J0ID0gYXBwVGVtcGxhdGUuX2V4aXN0aW5nQ29udGFpbmVyLnByaW1hcnlQb3J0O1xuICAgICAgICAvLyBVc2UgZXhpc3RpbmcgY29udGFpbmVyJ3MgcG9ydCBpZiBubyBjdXN0b20gcG9ydCBzcGVjaWZpZWRcbiAgICAgICAgaWYgKCFkZXBsb3lDb25maWcucG9ydCAmJiBhcHBUZW1wbGF0ZS5fZXhpc3RpbmdDb250YWluZXIucHJpbWFyeVBvcnQpIHtcbiAgICAgICAgICBhcGlEZXBsb3lDb25maWcuY29uZmlnLnBvcnQgPSBhcHBUZW1wbGF0ZS5fZXhpc3RpbmdDb250YWluZXIucHJpbWFyeVBvcnQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gQ2FsbCBkZXBsb3ltZW50IEFQSVxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBzZWN1cmVGZXRjaCgnL2FwaS92MS9hcHBzL2RlcGxveScsIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeShhcGlEZXBsb3lDb25maWcpXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuXG4gICAgICBpZiAocmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgICAgLy8gQWRkIHRvIHNhdmVkIGFwcHMgKHN0b3JlIElQIGZvciBsYXRlciBkZWxldGlvbilcbiAgICAgICAgY29uc3QgbmV3QXBwID0ge1xuICAgICAgICAgIGlkOiBkZXBsb3lDb25maWcuc3ViZG9tYWluLCAgLy8gVXNlIHN1YmRvbWFpbiBhcyBJRFxuICAgICAgICAgIG5hbWU6IGFwcFRlbXBsYXRlLm5hbWUsXG4gICAgICAgICAgbG9nbzogYC9hc3NldHMvJHthcHBUZW1wbGF0ZS5pZH0ucG5nYCxcbiAgICAgICAgICBjb250YWluZXJJZDogcmVzdWx0LmNvbnRhaW5lcklkLFxuICAgICAgICAgIHVybDogcmVzdWx0LnVybCxcbiAgICAgICAgICBpcDogZGVwbG95Q29uZmlnLmlwLCAgLy8gU3RvcmUgSVAgZm9yIEROUyByZWNvcmQgZGVsZXRpb25cbiAgICAgICAgICBhcHBUZW1wbGF0ZTogYXBwVGVtcGxhdGUuaWQsICAvLyBTdG9yZSBvcmlnaW5hbCB0ZW1wbGF0ZSBJRFxuICAgICAgICAgIHRhaWxzY2FsZU9ubHk6IGRlcGxveUNvbmZpZy50YWlsc2NhbGVPbmx5IHx8IGZhbHNlICAvLyBUYWlsc2NhbGUgcHJvdGVjdGlvbiBzdGF0dXNcbiAgICAgICAgfTtcbiAgICAgICAgY3VzdG9tQXBwcy5wdXNoKG5ld0FwcCk7XG4gICAgICAgIHNhZmVTZXQoQVBQU19LRVksIEpTT04uc3RyaW5naWZ5KGN1c3RvbUFwcHMpKTtcblxuICAgICAgICAvLyBBZGQgdG8gQVBQUyBhcnJheSBhbmQgcmVidWlsZCBncmlkXG4gICAgICAgIC8vIEFjY2VzcyBBUFBTIGZyb20gcGFyZW50IHNjb3BlIHZpYSB3aW5kb3dcbiAgICAgICAgaWYgKHdpbmRvdy5BUFBTICYmICF3aW5kb3cuQVBQUy5zb21lKGEgPT4gYS5pZCA9PT0gYXBwVGVtcGxhdGUuaWQpKSB7XG4gICAgICAgICAgd2luZG93LkFQUFMucHVzaChuZXdBcHApO1xuICAgICAgICAgIGlmICh0eXBlb2Ygd2luZG93LmJ1aWxkR3JpZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgd2luZG93LmJ1aWxkR3JpZCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodHlwZW9mIHdpbmRvdy5yZWZyZXNoQWxsID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHdpbmRvdy5yZWZyZXNoQWxsKCksIDUwMCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2hvdyBzdWNjZXNzIHdpdGggVVJMIChhbmQgd2FybmluZyBpZiBETlMgZmFpbGVkKVxuICAgICAgICBsZXQgbWVzc2FnZSA9IHJlc3VsdC51c2VkRXhpc3RpbmdcbiAgICAgICAgICA/IGAke2FwcFRlbXBsYXRlLm5hbWV9IGNvbmZpZ3VyZWQgd2l0aCBleGlzdGluZyBjb250YWluZXIhXFxuVVJMOiAke3Jlc3VsdC51cmx9YFxuICAgICAgICAgIDogYCR7YXBwVGVtcGxhdGUubmFtZX0gZGVwbG95ZWQgc3VjY2Vzc2Z1bGx5IVxcblVSTDogJHtyZXN1bHQudXJsfWA7XG4gICAgICAgIGlmIChyZXN1bHQud2FybmluZykge1xuICAgICAgICAgIG1lc3NhZ2UgKz0gYFxcblxcblx1MjZBMCBXYXJuaW5nOiAke3Jlc3VsdC53YXJuaW5nfWA7XG4gICAgICAgIH1cblxuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKG1lc3NhZ2UsICdzdWNjZXNzJywgODAwMCk7XG5cbiAgICAgICAgLy8gQ2xlYW4gdXAgdGVtcG9yYXJ5IHByb3BlcnRpZXNcbiAgICAgICAgZGVsZXRlIGFwcFRlbXBsYXRlLl91c2VFeGlzdGluZztcbiAgICAgICAgZGVsZXRlIGFwcFRlbXBsYXRlLl9leGlzdGluZ0NvbnRhaW5lcjtcbiAgICAgICAgXG4gICAgICAgIC8vIEZvciBIVFRQUyBVUkxzLCBjaGVjayBTU0wgY2VydGlmaWNhdGUgc3RhdHVzXG4gICAgICAgIGlmIChyZXN1bHQudXJsICYmIHJlc3VsdC51cmwuc3RhcnRzV2l0aCgnaHR0cHM6Ly8nKSkge1xuICAgICAgICAgIGNoZWNrU1NMQ2VydGlmaWNhdGUocmVzdWx0LnVybCwgYXBwVGVtcGxhdGUubmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTaG93IHNldHVwIGluc3RydWN0aW9ucyBpZiBhdmFpbGFibGVcbiAgICAgICAgaWYgKHJlc3VsdC5zZXR1cEluc3RydWN0aW9ucyAmJiByZXN1bHQuc2V0dXBJbnN0cnVjdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgaW5zdHJ1Y3Rpb25zID0gcmVzdWx0LnNldHVwSW5zdHJ1Y3Rpb25zLmpvaW4oJ1xcbicpO1xuICAgICAgICAgICAgc2hvd05vdGlmaWNhdGlvbihgU2V0dXAgSW5zdHJ1Y3Rpb25zIGZvciAke2FwcFRlbXBsYXRlLm5hbWV9OiAke2luc3RydWN0aW9uc31gLCAnaW5mbycsIDEwMDAwKTtcbiAgICAgICAgICB9LCAxMDAwKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKHJlc3VsdC5lcnJvciB8fCAnRGVwbG95bWVudCBmYWlsZWQnKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgZXJyb3JIYW5kbGVyLmxvZ0Vycm9yKCdbQXBwU2VsZWN0b3JdIERlcGxveW1lbnQnLCBlcnJvciwgeyBmdW5jdGlvbjogJ2RlcGxveScgfSk7XG4gICAgICBzaG93Tm90aWZpY2F0aW9uKFxuICAgICAgICBgRmFpbGVkIHRvIGRlcGxveSAke2FwcFRlbXBsYXRlLm5hbWV9OiAke2Vycm9yLm1lc3NhZ2V9YCxcbiAgICAgICAgJ2Vycm9yJyxcbiAgICAgICAgODAwMFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvLyBDaGVjayBTU0wgY2VydGlmaWNhdGUgc3RhdHVzIGFuZCBub3RpZnkgd2hlbiByZWFkeVxuICBhc3luYyBmdW5jdGlvbiBjaGVja1NTTENlcnRpZmljYXRlKHVybCwgYXBwTmFtZSkge1xuICAgIHNob3dOb3RpZmljYXRpb24oYFx1MjNGMyBHZW5lcmF0aW5nIFNTTCBjZXJ0aWZpY2F0ZSBmb3IgJHthcHBOYW1lfS4uLmAsICd3YXJuaW5nJywgNjAwMDApO1xuICAgIFxuICAgIGxldCBhdHRlbXB0cyA9IDA7XG4gICAgY29uc3QgbWF4QXR0ZW1wdHMgPSAxMjsgLy8gNjAgc2Vjb25kcyB0b3RhbCAoNSBzZWNvbmQgaW50ZXJ2YWxzKVxuICAgIFxuICAgIGNvbnN0IGNoZWNrQ2VydCA9IGFzeW5jICgpID0+IHtcbiAgICAgIGF0dGVtcHRzKys7XG4gICAgICBcbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIFRyeSB0byBmZXRjaCB0aGUgVVJMIC0gaWYgU1NMIHdvcmtzLCB0aGlzIHdpbGwgc3VjY2VlZFxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCwgeyBcbiAgICAgICAgICBtZXRob2Q6ICdIRUFEJyxcbiAgICAgICAgICBtb2RlOiAnbm8tY29ycycgLy8gQXZvaWQgQ09SUyBpc3N1ZXNcbiAgICAgICAgfSk7XG4gICAgICAgIFxuICAgICAgICAvLyBJZiB3ZSBnZXQgaGVyZSwgU1NMIGlzIHdvcmtpbmdcbiAgICAgICAgc2hvd05vdGlmaWNhdGlvbihgXHUyNzA1ICR7YXBwTmFtZX0gaXMgcmVhZHkhIFNTTCBjZXJ0aWZpY2F0ZSBnZW5lcmF0ZWQuYCwgJ3N1Y2Nlc3MnLCA1MDAwKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBTU0wgbm90IHJlYWR5IHlldFxuICAgICAgICBpZiAoYXR0ZW1wdHMgPCBtYXhBdHRlbXB0cykge1xuICAgICAgICAgIHNldFRpbWVvdXQoY2hlY2tDZXJ0LCA1MDAwKTsgLy8gQ2hlY2sgYWdhaW4gaW4gNSBzZWNvbmRzXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2hvd05vdGlmaWNhdGlvbihcbiAgICAgICAgICAgIGBcdTI2QTBcdUZFMEYgJHthcHBOYW1lfSBkZXBsb3llZCBidXQgU1NMIGNlcnRpZmljYXRlIG1heSBzdGlsbCBiZSBnZW5lcmF0aW5nLlxcblRyeSByZWZyZXNoaW5nIGluIGEgbW9tZW50IGlmIHlvdSBzZWUgYSBjZXJ0aWZpY2F0ZSBlcnJvci5gLFxuICAgICAgICAgICAgJ3dhcm5pbmcnLFxuICAgICAgICAgICAgMTAwMDBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9O1xuICAgIFxuICAgIC8vIFN0YXJ0IGNoZWNraW5nIGFmdGVyIDMgc2Vjb25kcyAoZ2l2ZSBDYWRkeSB0aW1lIHRvIHN0YXJ0KVxuICAgIHNldFRpbWVvdXQoY2hlY2tDZXJ0LCAzMDAwKTtcbiAgfVxuXG4gIC8vIExvYWQgY3VzdG9tIGFwcHMgb24gc3RhcnR1cFxuICBmdW5jdGlvbiBsb2FkQ3VzdG9tQXBwcygpIHtcbiAgICBjb25zdCBjdXN0b21BcHBzID0gc2FmZUdldEpTT04oQVBQU19LRVksIFtdKTtcbiAgICBjdXN0b21BcHBzLmZvckVhY2goYXBwID0+IHtcbiAgICAgIGlmICghd2luZG93LkFQUFMuc29tZShhID0+IGEuaWQgPT09IGFwcC5pZCkpIHtcbiAgICAgICAgd2luZG93LkFQUFMucHVzaChhcHApO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gRXZlbnQgbGlzdGVuZXJzXG4gIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhZGQtc2VydmljZS1idG4nKT8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgYnVpbGRBcHBTZWxlY3RvcigpO1xuICAgIG1vZGFsLmNsYXNzTGlzdC5hZGQoJ3Nob3cnKTtcbiAgfSk7XG5cbiAgd2lyZU1vZGFsKG1vZGFsLCBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXBwLXNlbGVjdG9yLWNhbmNlbCcpKTtcblxuICAvLyBEZXBsb3kgbW9kYWwgZXZlbnQgbGlzdGVuZXJzXG4gIGNvbnN0IGRlcGxveU1vZGFsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2FwcC1kZXBsb3ktbW9kYWwnKTtcblxuICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXBwLWRlcGxveS1jYW5jZWwnKT8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgZGVwbG95TW9kYWwuY2xhc3NMaXN0LnJlbW92ZSgnc2hvdycpO1xuICB9KTtcblxuICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXBwLWRlcGxveS1jb25maXJtJyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgIC8vIEdldCB1c2VyIGNvbmZpZ3VyYXRpb25cbiAgICBjb25zdCBhcHBUZW1wbGF0ZSA9IEpTT04ucGFyc2UoZGVwbG95TW9kYWwuZGF0YXNldC5hcHBUZW1wbGF0ZSk7XG4gICAgY29uc3QgbWVkaWFQYXRoID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RlcGxveS1tZWRpYS1wYXRoJykudmFsdWUudHJpbSgpO1xuXG4gICAgLy8gQ29sbGVjdCBjdXN0b20gdm9sdW1lIG92ZXJyaWRlc1xuICAgIGNvbnN0IGN1c3RvbVZvbHVtZXMgPSBbXTtcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcjdm9sdW1lLW1vdW50cy1saXN0IC52b2wtaG9zdC1wYXRoJykuZm9yRWFjaChpbnB1dCA9PiB7XG4gICAgICBjdXN0b21Wb2x1bWVzLnB1c2goeyBob3N0UGF0aDogaW5wdXQudmFsdWUudHJpbSgpLCBjb250YWluZXJQYXRoOiBpbnB1dC5kYXRhc2V0LmNvbnRhaW5lclBhdGggfSk7XG4gICAgfSk7XG5cbiAgICBjb25zdCBkZXBsb3lDb25maWcgPSB7XG4gICAgICBhcHBUZW1wbGF0ZTogYXBwVGVtcGxhdGUsXG4gICAgICBzdWJkb21haW46IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkZXBsb3ktc3ViZG9tYWluJykudmFsdWUudHJpbSgpLFxuICAgICAgZG5zVHlwZTogZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaW5wdXRbbmFtZT1cImRucy10eXBlXCJdOmNoZWNrZWQnKS52YWx1ZSxcbiAgICAgIHNzbFR5cGU6IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0W25hbWU9XCJzc2wtdHlwZVwiXTpjaGVja2VkJykudmFsdWUsXG4gICAgICBpcDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RlcGxveS1pcCcpLnZhbHVlLnRyaW0oKSxcbiAgICAgIHBvcnQ6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkZXBsb3ktcG9ydCcpLnZhbHVlLnRyaW0oKSxcbiAgICAgIHRhaWxzY2FsZU9ubHk6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkZXBsb3ktdGFpbHNjYWxlLW9ubHknKS5jaGVja2VkLFxuICAgICAgbWVkaWFQYXRoOiBtZWRpYVBhdGggfHwgbnVsbCxcbiAgICAgIHBsZXhDbGFpbVRva2VuOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGVwbG95LXBsZXgtY2xhaW0nKT8udmFsdWUudHJpbSgpIHx8IG51bGwsXG4gICAgICBjdXN0b21Wb2x1bWVzOiBjdXN0b21Wb2x1bWVzLmxlbmd0aCA+IDAgPyBjdXN0b21Wb2x1bWVzIDogbnVsbCxcbiAgICAgIHJlc291cmNlczoge1xuICAgICAgICBjcHVzOiBwYXJzZUZsb2F0KGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkZXBsb3ktY3B1LWxpbWl0JykudmFsdWUpIHx8IDAsXG4gICAgICAgIG1lbW9yeTogcGFyc2VGbG9hdChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGVwbG95LW1lbW9yeS1saW1pdCcpLnZhbHVlKSB8fCAwLFxuICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBWYWxpZGF0ZSBzdWJkb21haW5cbiAgICBpZiAoIWRlcGxveUNvbmZpZy5zdWJkb21haW4pIHtcbiAgICAgIHNob3dOb3RpZmljYXRpb24oJ1BsZWFzZSBlbnRlciBhIHN1YmRvbWFpbiBvciBkb21haW4gbmFtZScsICd3YXJuaW5nJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgbWVkaWEgcGF0aCBmb3IgbWVkaWEgYXBwc1xuICAgIGlmIChhcHBUZW1wbGF0ZS5tZWRpYU1vdW50Py5yZXF1aXJlZCAmJiAhbWVkaWFQYXRoKSB7XG4gICAgICBzaG93Tm90aWZpY2F0aW9uKCdQbGVhc2UgZW50ZXIgYSBtZWRpYSBsaWJyYXJ5IHBhdGggZm9yIHRoaXMgYXBwbGljYXRpb24nLCAnd2FybmluZycpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIENsb3NlIGRlcGxveSBtb2RhbFxuICAgIGRlcGxveU1vZGFsLmNsYXNzTGlzdC5yZW1vdmUoJ3Nob3cnKTtcblxuICAgIC8vIFN0YXJ0IGRlcGxveW1lbnRcbiAgICBhZGRBcHBUb0dyaWQoZGVwbG95Q29uZmlnKTtcbiAgfSk7XG5cbiAgd2lyZU1vZGFsKGRlcGxveU1vZGFsKTtcblxuICAvLyA9PT09PSBGT0xERVIgQlJPV1NFUiBGVU5DVElPTkFMSVRZID09PT09XG4gIGNvbnN0IGZvbGRlckJyb3dzZXJNb2RhbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmb2xkZXItYnJvd3Nlci1tb2RhbCcpO1xuICBjb25zdCBmb2xkZXJCcm93c2VyUGF0aCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmb2xkZXItYnJvd3Nlci1wYXRoJyk7XG4gIGNvbnN0IGZvbGRlckJyb3dzZXJMaXN0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZvbGRlci1icm93c2VyLWxpc3QnKTtcbiAgY29uc3QgZm9sZGVyQnJvd3NlclNlbGVjdGVkID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZvbGRlci1icm93c2VyLXNlbGVjdGVkJyk7XG4gIGNvbnN0IGZvbGRlckJyb3dzZXJTZWxlY3RlZExpc3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZm9sZGVyLWJyb3dzZXItc2VsZWN0ZWQtbGlzdCcpO1xuICBsZXQgY3VycmVudEJyb3dzZXJQYXRoID0gJyc7XG4gIGxldCBzZWxlY3RlZEZvbGRlcnMgPSBbXTtcbiAgbGV0IHRhcmdldE1lZGlhSW5wdXQgPSBudWxsO1xuXG4gIHdpbmRvdy5vcGVuRm9sZGVyQnJvd3NlciA9IGZ1bmN0aW9uKG1lZGlhSW5wdXQpIHtcbiAgICB0YXJnZXRNZWRpYUlucHV0ID0gbWVkaWFJbnB1dDtcbiAgICBzZWxlY3RlZEZvbGRlcnMgPSBtZWRpYUlucHV0LnZhbHVlLnNwbGl0KCcsJykubWFwKHAgPT4gcC50cmltKCkpLmZpbHRlcihwID0+IHApO1xuICAgIGN1cnJlbnRCcm93c2VyUGF0aCA9ICcnO1xuICAgIHVwZGF0ZVNlbGVjdGVkRm9sZGVyc0Rpc3BsYXkoKTtcbiAgICBsb2FkRm9sZGVyQ29udGVudHMoJycpO1xuICAgIGZvbGRlckJyb3dzZXJNb2RhbC5jbGFzc0xpc3QuYWRkKCdzaG93Jyk7XG4gIH07XG5cbiAgYXN5bmMgZnVuY3Rpb24gbG9hZEZvbGRlckNvbnRlbnRzKHBhdGgpIHtcbiAgICBmb2xkZXJCcm93c2VyUGF0aC50ZXh0Q29udGVudCA9IHBhdGggfHwgJ1NlbGVjdCBhIGRyaXZlLi4uJztcbiAgICBmb2xkZXJCcm93c2VyTGlzdC5pbm5lckhUTUwgPSAnPGRpdiBzdHlsZT1cInBhZGRpbmc6IDIwcHg7IHRleHQtYWxpZ246IGNlbnRlcjsgY29sb3I6IHZhcigtLW11dGVkKTtcIj5Mb2FkaW5nLi4uPC9kaXY+JztcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGAvYXBpL3YxL2Jyb3dzZS9kaXJlY3Rvcmllcz9wYXRoPSR7ZW5jb2RlVVJJQ29tcG9uZW50KHBhdGgpfWApO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuXG4gICAgICBpZiAoIXJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICAgIGZvbGRlckJyb3dzZXJMaXN0LmlubmVySFRNTCA9IGA8ZGl2IHN0eWxlPVwicGFkZGluZzogMjBweDsgdGV4dC1hbGlnbjogY2VudGVyOyBjb2xvcjogdmFyKC0tZXJyb3IpO1wiPkVycm9yOiAke2VzY2FwZUh0bWwocmVzdWx0LmVycm9yKX08L2Rpdj5gO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGN1cnJlbnRCcm93c2VyUGF0aCA9IHJlc3VsdC5wYXRoIHx8ICcnO1xuICAgICAgZm9sZGVyQnJvd3NlclBhdGgudGV4dENvbnRlbnQgPSBjdXJyZW50QnJvd3NlclBhdGggfHwgJ1NlbGVjdCBhIGRyaXZlLi4uJztcblxuICAgICAgbGV0IGh0bWwgPSAnJztcblxuICAgICAgLy8gQWRkIHBhcmVudCBmb2xkZXIgbmF2aWdhdGlvblxuICAgICAgaWYgKHJlc3VsdC5wYXJlbnQgJiYgcmVzdWx0LnBhcmVudCAhPT0gcmVzdWx0LnBhdGgpIHtcbiAgICAgICAgaHRtbCArPSBgPGRpdiBjbGFzcz1cImZvbGRlci1pdGVtXCIgZGF0YS1wYXRoPVwiJHtlc2NhcGVIdG1sKHJlc3VsdC5wYXJlbnQpfVwiIHN0eWxlPVwicGFkZGluZzogMTJweCAxNnB4OyBib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgY3Vyc29yOiBwb2ludGVyOyBkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDEwcHg7XCI+XG4gICAgICAgICAgPHNwYW4gc3R5bGU9XCJmb250LXNpemU6IDEuMnJlbTtcIj5cdTJCMDZcdUZFMEY8L3NwYW4+XG4gICAgICAgICAgPHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPi4uIFBhcmVudCBEaXJlY3Rvcnk8L3NwYW4+XG4gICAgICAgIDwvZGl2PmA7XG4gICAgICB9XG5cbiAgICAgIC8vIEFkZCBmb2xkZXJzXG4gICAgICBpZiAocmVzdWx0Lml0ZW1zLmxlbmd0aCA9PT0gMCAmJiAhcmVzdWx0LnBhcmVudCkge1xuICAgICAgICBodG1sICs9ICc8ZGl2IHN0eWxlPVwicGFkZGluZzogMjBweDsgdGV4dC1hbGlnbjogY2VudGVyOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPk5vIGJyb3dzZWFibGUgZHJpdmVzIGNvbmZpZ3VyZWQuIENoZWNrIHlvdXIgZG9ja2VyLWNvbXBvc2UueW1sIHZvbHVtZSBtb3VudHMuPC9kaXY+JztcbiAgICAgIH0gZWxzZSBpZiAocmVzdWx0Lml0ZW1zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBodG1sICs9ICc8ZGl2IHN0eWxlPVwicGFkZGluZzogMjBweDsgdGV4dC1hbGlnbjogY2VudGVyOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPk5vIHN1YmZvbGRlcnMgZm91bmQ8L2Rpdj4nO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0Lml0ZW1zLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgICAgY29uc3QgaWNvbiA9IGl0ZW0udHlwZSA9PT0gJ2RyaXZlJyA/ICdcdUQ4M0RcdURDQkUnIDogJ1x1RDgzRFx1RENDMSc7XG4gICAgICAgICAgY29uc3QgaXNTZWxlY3RlZCA9IHNlbGVjdGVkRm9sZGVycy5pbmNsdWRlcyhpdGVtLnBhdGgpO1xuICAgICAgICAgIGNvbnN0IHNlbGVjdGVkU3R5bGUgPSBpc1NlbGVjdGVkID8gJ2JhY2tncm91bmQ6IGNvbG9yLW1peChpbiBzcmdiLCB2YXIoLS1zdWNjZXNzKSAyMCUsIHRyYW5zcGFyZW50KTsnIDogJyc7XG4gICAgICAgICAgaHRtbCArPSBgPGRpdiBjbGFzcz1cImZvbGRlci1pdGVtXCIgZGF0YS1wYXRoPVwiJHtlc2NhcGVIdG1sKGl0ZW0ucGF0aCl9XCIgc3R5bGU9XCJwYWRkaW5nOiAxMnB4IDE2cHg7IGJvcmRlci1ib3R0b206IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBjdXJzb3I6IHBvaW50ZXI7IGRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogMTBweDsgJHtzZWxlY3RlZFN0eWxlfVwiPlxuICAgICAgICAgICAgPHNwYW4gc3R5bGU9XCJmb250LXNpemU6IDEuMnJlbTtcIj4ke2ljb259PC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gc3R5bGU9XCJmbGV4OiAxO1wiPiR7ZXNjYXBlSHRtbChpdGVtLm5hbWUpfTwvc3Bhbj5cbiAgICAgICAgICAgICR7aXNTZWxlY3RlZCA/ICc8c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1zdWNjZXNzKTtcIj5cdTI3MTM8L3NwYW4+JyA6ICcnfVxuICAgICAgICAgIDwvZGl2PmA7XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBmb2xkZXJCcm93c2VyTGlzdC5pbm5lckhUTUwgPSBodG1sO1xuXG4gICAgICAvLyBBZGQgY2xpY2sgaGFuZGxlcnNcbiAgICAgIGZvbGRlckJyb3dzZXJMaXN0LnF1ZXJ5U2VsZWN0b3JBbGwoJy5mb2xkZXItaXRlbScpLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgIGl0ZW0uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgbG9hZEZvbGRlckNvbnRlbnRzKGl0ZW0uZGF0YXNldC5wYXRoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGl0ZW0uYWRkRXZlbnRMaXN0ZW5lcignbW91c2VlbnRlcicsICgpID0+IHtcbiAgICAgICAgICBpdGVtLnN0eWxlLmJhY2tncm91bmQgPSAndmFyKC0tY2FyZC1iZyknO1xuICAgICAgICB9KTtcbiAgICAgICAgaXRlbS5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGlzU2VsZWN0ZWQgPSBzZWxlY3RlZEZvbGRlcnMuaW5jbHVkZXMoaXRlbS5kYXRhc2V0LnBhdGgpO1xuICAgICAgICAgIGl0ZW0uc3R5bGUuYmFja2dyb3VuZCA9IGlzU2VsZWN0ZWQgPyAnY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLXN1Y2Nlc3MpIDIwJSwgdHJhbnNwYXJlbnQpJyA6ICcnO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGZvbGRlckJyb3dzZXJMaXN0LmlubmVySFRNTCA9IGA8ZGl2IHN0eWxlPVwicGFkZGluZzogMjBweDsgdGV4dC1hbGlnbjogY2VudGVyOyBjb2xvcjogdmFyKC0tZXJyb3IpO1wiPkZhaWxlZCB0byBsb2FkOiAke2VzY2FwZUh0bWwoZXJyb3IubWVzc2FnZSl9PC9kaXY+YDtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVTZWxlY3RlZEZvbGRlcnNEaXNwbGF5KCkge1xuICAgIGlmIChzZWxlY3RlZEZvbGRlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICBmb2xkZXJCcm93c2VyU2VsZWN0ZWQuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZm9sZGVyQnJvd3NlclNlbGVjdGVkLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgIGZvbGRlckJyb3dzZXJTZWxlY3RlZExpc3QuaW5uZXJIVE1MID0gc2VsZWN0ZWRGb2xkZXJzLm1hcChwYXRoID0+IGBcbiAgICAgIDxzcGFuIHN0eWxlPVwicGFkZGluZzogNnB4IDEycHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmcpOyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1zdWNjZXNzKTsgYm9yZGVyLXJhZGl1czogNHB4OyBkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDZweDtcIj5cbiAgICAgICAgJHtlc2NhcGVIdG1sKHBhdGgpfVxuICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBvbmNsaWNrPVwicmVtb3ZlU2VsZWN0ZWRGb2xkZXIoJyR7ZXNjYXBlSHRtbChwYXRoKX0nKVwiIHN0eWxlPVwiYmFja2dyb3VuZDogbm9uZTsgYm9yZGVyOiBub25lOyBjdXJzb3I6IHBvaW50ZXI7IGNvbG9yOiB2YXIoLS1lcnJvcik7IGZvbnQtc2l6ZTogMXJlbTsgcGFkZGluZzogMDtcIj5cdTAwRDc8L2J1dHRvbj5cbiAgICAgIDwvc3Bhbj5cbiAgICBgKS5qb2luKCcnKTtcbiAgfVxuXG4gIHdpbmRvdy5yZW1vdmVTZWxlY3RlZEZvbGRlciA9IGZ1bmN0aW9uKHBhdGgpIHtcbiAgICBzZWxlY3RlZEZvbGRlcnMgPSBzZWxlY3RlZEZvbGRlcnMuZmlsdGVyKHAgPT4gcCAhPT0gcGF0aCk7XG4gICAgdXBkYXRlU2VsZWN0ZWRGb2xkZXJzRGlzcGxheSgpO1xuICAgIGxvYWRGb2xkZXJDb250ZW50cyhjdXJyZW50QnJvd3NlclBhdGgpOyAvLyBSZWZyZXNoIHRvIHVwZGF0ZSBjaGVja21hcmtzXG4gIH07XG5cbiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZvbGRlci1icm93c2VyLXNlbGVjdC1jdXJyZW50JykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgaWYgKGN1cnJlbnRCcm93c2VyUGF0aCAmJiAhc2VsZWN0ZWRGb2xkZXJzLmluY2x1ZGVzKGN1cnJlbnRCcm93c2VyUGF0aCkpIHtcbiAgICAgIHNlbGVjdGVkRm9sZGVycy5wdXNoKGN1cnJlbnRCcm93c2VyUGF0aCk7XG4gICAgICB1cGRhdGVTZWxlY3RlZEZvbGRlcnNEaXNwbGF5KCk7XG4gICAgICBsb2FkRm9sZGVyQ29udGVudHMoY3VycmVudEJyb3dzZXJQYXRoKTsgLy8gUmVmcmVzaCB0byBzaG93IGNoZWNrbWFya1xuICAgIH1cbiAgfSk7XG5cbiAgd2lyZU1vZGFsKGZvbGRlckJyb3dzZXJNb2RhbCwgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZvbGRlci1icm93c2VyLWNhbmNlbCcpKTtcblxuICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZm9sZGVyLWJyb3dzZXItZG9uZScpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgIGlmICh0YXJnZXRNZWRpYUlucHV0KSB7XG4gICAgICB0YXJnZXRNZWRpYUlucHV0LnZhbHVlID0gc2VsZWN0ZWRGb2xkZXJzLmpvaW4oJywgJyk7XG4gICAgfVxuICAgIGZvbGRlckJyb3dzZXJNb2RhbC5jbGFzc0xpc3QucmVtb3ZlKCdzaG93Jyk7XG4gIH0pO1xuXG4gIC8vIExvYWQgY3VzdG9tIGFwcHMgb24gcGFnZSBsb2FkXG4gIGxvYWRDdXN0b21BcHBzKCk7XG59KSgpO1xuO1xuLy8gUmVjaXBlIFN5c3RlbSBcdTIwMTQgbXVsdGktY29udGFpbmVyIHN0YWNrIGRlcGxveW1lbnRcbihmdW5jdGlvbigpIHtcbiAgLy8gPT09IFJFQ0lQRSBERVBMT1kgV0laQVJEIE1PREFMID09PVxuICBpbmplY3RNb2RhbCgncmVjaXBlLWRlcGxveS1tb2RhbCcsIGA8ZGl2IGlkPVwicmVjaXBlLWRlcGxveS1tb2RhbFwiIGNsYXNzPVwid2VhdGhlci1tb2RhbFwiPlxuICAgIDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsLWNvbnRlbnRcIiBzdHlsZT1cIm1pbi13aWR0aDogNjIwcHg7IG1heC13aWR0aDogNzQwcHg7XCI+XG4gICAgICA8aDMgaWQ9XCJyZWNpcGUtZGVwbG95LXRpdGxlXCI+RGVwbG95IFJlY2lwZTwvaDM+XG5cbiAgICAgIDwhLS0gU3RlcCBpbmRpY2F0b3IgLS0+XG4gICAgICA8ZGl2IGlkPVwicmVjaXBlLXN0ZXBzXCIgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBnYXA6IDRweDsgbWFyZ2luOiAxNnB4IDAgMjRweDtcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInJlY2lwZS1zdGVwIGFjdGl2ZVwiIGRhdGEtc3RlcD1cIjFcIj48c3Bhbj4xPC9zcGFuPiBDb21wb25lbnRzPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJyZWNpcGUtc3RlcFwiIGRhdGEtc3RlcD1cIjJcIj48c3Bhbj4yPC9zcGFuPiBDb25maWd1cmF0aW9uPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJyZWNpcGUtc3RlcFwiIGRhdGEtc3RlcD1cIjNcIj48c3Bhbj4zPC9zcGFuPiBSZXZpZXc8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInJlY2lwZS1zdGVwXCIgZGF0YS1zdGVwPVwiNFwiPjxzcGFuPjQ8L3NwYW4+IFByb2dyZXNzPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBTdGVwIDE6IENvbXBvbmVudCBTZWxlY3Rpb24gLS0+XG4gICAgICA8ZGl2IGlkPVwicmVjaXBlLXN0ZXAtMVwiIGNsYXNzPVwicmVjaXBlLXN0ZXAtcGFuZWxcIj5cbiAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbC1hY2NlbnQtc21cIj5TZWxlY3QgQ29tcG9uZW50czo8L2xhYmVsPlxuICAgICAgICA8ZGl2IGlkPVwicmVjaXBlLWNvbXBvbmVudC1saXN0XCIgc3R5bGU9XCJkaXNwbGF5OiBncmlkOyBnYXA6IDEwcHg7IG1hcmdpbi10b3A6IDhweDtcIj48L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIFN0ZXAgMjogU2hhcmVkIENvbmZpZ3VyYXRpb24gLS0+XG4gICAgICA8ZGl2IGlkPVwicmVjaXBlLXN0ZXAtMlwiIGNsYXNzPVwicmVjaXBlLXN0ZXAtcGFuZWxcIiBzdHlsZT1cImRpc3BsYXk6bm9uZTtcIj5cbiAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGdyaWQ7IGdhcDogMTZweDtcIj5cbiAgICAgICAgICA8IS0tIFNoYXJlZCB2b2x1bWVzIC0tPlxuICAgICAgICAgIDxkaXYgaWQ9XCJyZWNpcGUtdm9sdW1lcy1zZWN0aW9uXCIgc3R5bGU9XCJkaXNwbGF5Om5vbmU7XCI+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsLWFjY2VudC1zbVwiPlNoYXJlZCBWb2x1bWVzOjwvbGFiZWw+XG4gICAgICAgICAgICA8ZGl2IGlkPVwicmVjaXBlLXZvbHVtZS1saXN0XCIgc3R5bGU9XCJkaXNwbGF5OiBncmlkOyBnYXA6IDEwcHg7IG1hcmdpbi10b3A6IDhweDtcIj48L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDwhLS0gVGltZXpvbmUgLS0+XG4gICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwtYWNjZW50LXNtXCI+VGltZXpvbmU6PC9sYWJlbD5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGlkPVwicmVjaXBlLXRpbWV6b25lXCIgdmFsdWU9XCJVVENcIiBwbGFjZWhvbGRlcj1cImUuZy4gQW1lcmljYS9OZXdfWW9ya1wiXG4gICAgICAgICAgICAgIHN0eWxlPVwid2lkdGg6IDEwMCU7IHBhZGRpbmc6IDhweCAxMnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJnKTsgY29sb3I6IHZhcigtLWZnKTsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgYm9yZGVyLXJhZGl1czogNnB4O1wiIC8+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8IS0tIFRhcmdldCBJUCAtLT5cbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbC1hY2NlbnQtc21cIj5UYXJnZXQgSVAgQWRkcmVzczo8L2xhYmVsPlxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgaWQ9XCJyZWNpcGUtaXBcIiB2YWx1ZT1cImhvc3QuZG9ja2VyLmludGVybmFsXCIgcGxhY2Vob2xkZXI9XCJsb2NhbGhvc3Qgb3IgSVBcIlxuICAgICAgICAgICAgICBzdHlsZT1cIndpZHRoOiAxMDAlOyBwYWRkaW5nOiA4cHggMTJweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iZyk7IGNvbG9yOiB2YXIoLS1mZyk7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJvcmRlci1yYWRpdXM6IDZweDtcIiAvPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0taGludC1zbVwiPklQIHdoZXJlIGNvbnRhaW5lcnMgZXhwb3NlIHBvcnRzPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8IS0tIFRhaWxzY2FsZSAtLT5cbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjaGVja2JveC1sYWJlbFwiPlxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGlkPVwicmVjaXBlLXRhaWxzY2FsZVwiIC8+XG4gICAgICAgICAgICA8c3Bhbj5SZXN0cmljdCB0byBUYWlsc2NhbGUgbmV0d29yayBvbmx5PC9zcGFuPlxuICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gU3RlcCAzOiBSZXZpZXcgLS0+XG4gICAgICA8ZGl2IGlkPVwicmVjaXBlLXN0ZXAtM1wiIGNsYXNzPVwicmVjaXBlLXN0ZXAtcGFuZWxcIiBzdHlsZT1cImRpc3BsYXk6bm9uZTtcIj5cbiAgICAgICAgPGRpdiBpZD1cInJlY2lwZS1yZXZpZXctY29udGVudFwiIHN0eWxlPVwiZm9udC1zaXplOiAwLjlyZW07IGxpbmUtaGVpZ2h0OiAxLjc7XCI+PC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBTdGVwIDQ6IFByb2dyZXNzIC0tPlxuICAgICAgPGRpdiBpZD1cInJlY2lwZS1zdGVwLTRcIiBjbGFzcz1cInJlY2lwZS1zdGVwLXBhbmVsXCIgc3R5bGU9XCJkaXNwbGF5Om5vbmU7XCI+XG4gICAgICAgIDxkaXYgaWQ9XCJyZWNpcGUtcHJvZ3Jlc3MtbGlzdFwiIHN0eWxlPVwiZGlzcGxheTogZ3JpZDsgZ2FwOiA4cHg7XCI+PC9kaXY+XG4gICAgICAgIDxkaXYgaWQ9XCJyZWNpcGUtZGVwbG95LXJlc3VsdFwiIHN0eWxlPVwibWFyZ2luLXRvcDogMTZweDsgZGlzcGxheTpub25lO1wiPjwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsLWJ1dHRvbnNcIiBzdHlsZT1cIm1hcmdpbi10b3A6IDIwcHg7XCI+XG4gICAgICAgIDxidXR0b24gaWQ9XCJyZWNpcGUtY2FuY2VsXCI+Q2FuY2VsPC9idXR0b24+XG4gICAgICAgIDxidXR0b24gaWQ9XCJyZWNpcGUtcHJldlwiIGNsYXNzPVwiYnRuLWFjY2VudFwiIHN0eWxlPVwiZGlzcGxheTpub25lO1wiPkJhY2s8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBpZD1cInJlY2lwZS1uZXh0XCIgY2xhc3M9XCJidG4tYWNjZW50LXNvbGlkXCI+TmV4dDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PmApO1xuXG4gIC8vID09PSBTVEFURSA9PT1cbiAgbGV0IHJlY2lwZVRlbXBsYXRlcyA9IG51bGw7XG4gIGxldCByZWNpcGVDYXRlZ29yaWVzID0gbnVsbDtcbiAgbGV0IGN1cnJlbnRSZWNpcGUgPSBudWxsO1xuICBsZXQgY3VycmVudFN0ZXAgPSAxO1xuICBsZXQgaXNQcmVtaXVtID0gZmFsc2U7XG5cbiAgY29uc3QgZGVwbG95TW9kYWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncmVjaXBlLWRlcGxveS1tb2RhbCcpO1xuICBjb25zdCBjYW5jZWxCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncmVjaXBlLWNhbmNlbCcpO1xuICBjb25zdCBwcmV2QnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3JlY2lwZS1wcmV2Jyk7XG4gIGNvbnN0IG5leHRCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncmVjaXBlLW5leHQnKTtcblxuICB3aXJlTW9kYWwoZGVwbG95TW9kYWwsIGNhbmNlbEJ0bik7XG5cbiAgLy8gPT09IEZFVENIIFJFQ0lQRSBURU1QTEFURVMgPT09XG4gIGFzeW5jIGZ1bmN0aW9uIGZldGNoUmVjaXBlVGVtcGxhdGVzKCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwID0gYXdhaXQgZmV0Y2goJy9hcGkvdjEvcmVjaXBlcy90ZW1wbGF0ZXMnKTtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwLmpzb24oKTtcbiAgICAgIGlmIChkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgcmVjaXBlVGVtcGxhdGVzID0gZGF0YS50ZW1wbGF0ZXM7XG4gICAgICAgIHJlY2lwZUNhdGVnb3JpZXMgPSBkYXRhLmNhdGVnb3JpZXM7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgLy8gUHJlbWl1bSByZXF1aXJlZCBcdTIwMTQgdGVtcGxhdGVzIEFQSSBnYXRlZFxuICAgICAgaWYgKHJlc3Auc3RhdHVzID09PSA0MDMpIHtcbiAgICAgICAgaXNQcmVtaXVtID0gZmFsc2U7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ0ZhaWxlZCB0byBmZXRjaCByZWNpcGUgdGVtcGxhdGVzOicsIGUubWVzc2FnZSk7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vID09PSBDSEVDSyBQUkVNSVVNID09PVxuICBhc3luYyBmdW5jdGlvbiBjaGVja1JlY2lwZVByZW1pdW0oKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3AgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS9saWNlbnNlL2ZlYXR1cmUvcmVjaXBlcycpO1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3AuanNvbigpO1xuICAgICAgaXNQcmVtaXVtID0gZGF0YS5hdmFpbGFibGU7XG4gICAgfSBjYXRjaCB7XG4gICAgICBpc1ByZW1pdW0gPSBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIGlzUHJlbWl1bTtcbiAgfVxuXG4gIC8vID09PSBSRU5ERVIgUkVDSVBFIENBUkRTIElOVE8gQVBQIFNFTEVDVE9SID09PVxuICAvLyBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBieSB0aGUgYXBwIHNlbGVjdG9yIHRvIGluamVjdCByZWNpcGUgY2FyZHNcbiAgd2luZG93LnJlbmRlclJlY2lwZUNhcmRzID0gYXN5bmMgZnVuY3Rpb24oZ3JpZCkge1xuICAgIGF3YWl0IGNoZWNrUmVjaXBlUHJlbWl1bSgpO1xuXG4gICAgLy8gQnVpbGQgcmVjaXBlIGRhdGEgXHUyMDE0IHdlIGNhbiBzaG93IGNhcmQgbWV0YWRhdGEgZXZlbiB3aXRob3V0IHByZW1pdW1cbiAgICAvLyAoY2FyZHMganVzdCBzaG93IGEgbG9jayBhbmQgcHJvbXB0IHRvIHVwZ3JhZGUpXG4gICAgbGV0IHJlY2lwZXM7XG4gICAgaWYgKGlzUHJlbWl1bSAmJiByZWNpcGVUZW1wbGF0ZXMpIHtcbiAgICAgIHJlY2lwZXMgPSByZWNpcGVUZW1wbGF0ZXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFNob3cgaGFyZGNvZGVkIHByZXZpZXcgY2FyZHMgd2hlbiBub3QgcHJlbWl1bVxuICAgICAgcmVjaXBlcyA9IGdldFByZXZpZXdSZWNpcGVzKCk7XG4gICAgfVxuXG4gICAgaWYgKCFyZWNpcGVzIHx8IHJlY2lwZXMubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICAvLyBDYXRlZ29yeSBoZWFkZXJcbiAgICBjb25zdCBoZWFkZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBoZWFkZXIuY2xhc3NOYW1lID0gJ2FwcC1jYXRlZ29yeS1oZWFkZXInO1xuICAgIGhlYWRlci5pbm5lckhUTUwgPSBgXFx1RDgzRVxcdURERUEgUmVjaXBlc2A7XG4gICAgaGVhZGVyLnN0eWxlLmJvcmRlckJvdHRvbUNvbG9yID0gJyM4ZTQ0YWQnO1xuICAgIGdyaWQuYXBwZW5kQ2hpbGQoaGVhZGVyKTtcblxuICAgIGNvbnN0IHJlY2lwZUxpc3QgPSBBcnJheS5pc0FycmF5KHJlY2lwZXMpID8gcmVjaXBlcyA6IE9iamVjdC52YWx1ZXMocmVjaXBlcyk7XG4gICAgcmVjaXBlTGlzdC5zb3J0KChhLCBiKSA9PiAoYi5wb3B1bGFyaXR5IHx8IDApIC0gKGEucG9wdWxhcml0eSB8fCAwKSk7XG5cbiAgICBmb3IgKGNvbnN0IHJlY2lwZSBvZiByZWNpcGVMaXN0KSB7XG4gICAgICBjb25zdCBvcHRpb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIG9wdGlvbi5jbGFzc05hbWUgPSAnYXBwLW9wdGlvbic7XG4gICAgICBvcHRpb24uc3R5bGUucG9zaXRpb24gPSAncmVsYXRpdmUnO1xuXG4gICAgICBjb25zdCBjb21wb25lbnRCYWRnZSA9IGA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjY1cmVtOyBwYWRkaW5nOiAycHggNnB4OyBib3JkZXItcmFkaXVzOiA0cHg7IG1hcmdpbi10b3A6IDRweDsgYmFja2dyb3VuZDogcmdiYSgxNDIsNjgsMTczLDAuMik7IGNvbG9yOiAjYTg1NWY3O1wiPiR7cmVjaXBlLmNvbXBvbmVudENvdW50IHx8IHJlY2lwZS5jb21wb25lbnRzPy5sZW5ndGggfHwgJz8nfSBhcHBzPC9kaXY+YDtcblxuICAgICAgY29uc3QgbG9ja092ZXJsYXkgPSAhaXNQcmVtaXVtID8gYDxkaXYgc3R5bGU9XCJwb3NpdGlvbjogYWJzb2x1dGU7IHRvcDogNnB4OyByaWdodDogNnB4OyBmb250LXNpemU6IDAuNjVyZW07IHBhZGRpbmc6IDJweCA4cHg7IGJvcmRlci1yYWRpdXM6IDEwcHg7IGJhY2tncm91bmQ6IHJnYmEoMjQxLDE5NiwxNSwwLjIpOyBjb2xvcjogI2YxYzQwZjsgZm9udC13ZWlnaHQ6IDYwMDtcIj5QUkVNSVVNPC9kaXY+YCA6ICcnO1xuXG4gICAgICBvcHRpb24uaW5uZXJIVE1MID0gYFxuICAgICAgICAke2xvY2tPdmVybGF5fVxuICAgICAgICA8ZGl2IGNsYXNzPVwiYXBwLW9wdGlvbi1pY29uXCI+JHtlc2NhcGVIdG1sKHJlY2lwZS5pY29uIHx8ICdcXHVEODNFXFx1RERFQScpfTwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiYXBwLW9wdGlvbi1uYW1lXCI+JHtlc2NhcGVIdG1sKHJlY2lwZS5uYW1lKX08L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImFwcC1vcHRpb24tZGVzY1wiPiR7ZXNjYXBlSHRtbChyZWNpcGUuZGVzY3JpcHRpb24gfHwgJycpfTwvZGl2PlxuICAgICAgICAke2NvbXBvbmVudEJhZGdlfVxuICAgICAgYDtcblxuICAgICAgb3B0aW9uLm9uY2xpY2sgPSAoKSA9PiB7XG4gICAgICAgIGlmICghaXNQcmVtaXVtKSB7XG4gICAgICAgICAgc2hvd05vdGlmaWNhdGlvbignUmVjaXBlcyByZXF1aXJlIGEgRGFzaENhZGR5IFByZW1pdW0gbGljZW5zZS4gQ2xpY2sgdGhlIExpY2Vuc2UgYnV0dG9uIHRvIGFjdGl2YXRlLicsICd3YXJuaW5nJywgNTAwMCk7XG4gICAgICAgICAgaWYgKHdpbmRvdy5vcGVuTGljZW5zZU1vZGFsKSB3aW5kb3cub3BlbkxpY2Vuc2VNb2RhbCgpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBvcGVuUmVjaXBlRGVwbG95V2l6YXJkKHJlY2lwZSk7XG4gICAgICB9O1xuXG4gICAgICBncmlkLmFwcGVuZENoaWxkKG9wdGlvbik7XG4gICAgfVxuICB9O1xuXG4gIGZ1bmN0aW9uIGdldFByZXZpZXdSZWNpcGVzKCkge1xuICAgIHJldHVybiBbXG4gICAgICB7IGlkOiAnaHRwYy1zdWl0ZScsIG5hbWU6ICdIVFBDIFN1aXRlJywgaWNvbjogJ1xcdUQ4M0NcXHVERkFDJywgZGVzY3JpcHRpb246ICdDb21wbGV0ZSBtZWRpYSBhdXRvbWF0aW9uOiBmaW5kLCBkb3dubG9hZCwgb3JnYW5pemUsIGFuZCBzdHJlYW0nLCBjb21wb25lbnRDb3VudDogNiwgcG9wdWxhcml0eTogOTggfSxcbiAgICAgIHsgaWQ6ICduZXh0Y2xvdWQtY29tcGxldGUnLCBuYW1lOiAnTmV4dGNsb3VkIENvbXBsZXRlJywgaWNvbjogJ1xcdTI2MDFcXHVGRTBGJywgZGVzY3JpcHRpb246ICdGdWxsIHByb2R1Y3Rpdml0eSBzdWl0ZTogY2xvdWQgc3RvcmFnZSwgb2ZmaWNlIGVkaXRpbmcsIGFuZCBjb2xsYWJvcmF0aW9uJywgY29tcG9uZW50Q291bnQ6IDQsIHBvcHVsYXJpdHk6IDkwIH0sXG4gICAgICB7IGlkOiAnc21hcnQtaG9tZScsIG5hbWU6ICdTbWFydCBIb21lIEh1YicsIGljb246ICdcXHVEODNDXFx1REZFMCcsIGRlc2NyaXB0aW9uOiAnSG9tZSBhdXRvbWF0aW9uOiBjb250cm9sLCBhdXRvbWF0ZSwgYW5kIG1vbml0b3IgSW9UIGRldmljZXMnLCBjb21wb25lbnRDb3VudDogNCwgcG9wdWxhcml0eTogODggfSxcbiAgICAgIHsgaWQ6ICdkZXYtZW52aXJvbm1lbnQnLCBuYW1lOiAnRGV2IEVudmlyb25tZW50JywgaWNvbjogJ1xcdUQ4M0RcXHVEQ0JCJywgZGVzY3JpcHRpb246ICdTZWxmLWhvc3RlZCBkZXZlbG9wbWVudCB3b3JrZmxvdzogR2l0LCBDSS9DRCwgSURFLCBhbmQgZGF0YWJhc2UnLCBjb21wb25lbnRDb3VudDogNCwgcG9wdWxhcml0eTogODIgfVxuICAgIF07XG4gIH1cblxuICAvLyA9PT0gUkVDSVBFIERFUExPWSBXSVpBUkQgPT09XG4gIGZ1bmN0aW9uIG9wZW5SZWNpcGVEZXBsb3lXaXphcmQocmVjaXBlKSB7XG4gICAgY3VycmVudFJlY2lwZSA9IHJlY2lwZTtcbiAgICBjdXJyZW50U3RlcCA9IDE7XG5cbiAgICAvLyBDbG9zZSBhcHAgc2VsZWN0b3JcbiAgICBjb25zdCBhcHBTZWxlY3Rvck1vZGFsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2FwcC1zZWxlY3Rvci1tb2RhbCcpO1xuICAgIGlmIChhcHBTZWxlY3Rvck1vZGFsKSBhcHBTZWxlY3Rvck1vZGFsLmNsYXNzTGlzdC5yZW1vdmUoJ3Nob3cnKTtcblxuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdyZWNpcGUtZGVwbG95LXRpdGxlJykudGV4dENvbnRlbnQgPSBgRGVwbG95ICR7cmVjaXBlLm5hbWV9YDtcblxuICAgIC8vIFJlc2V0IHN0ZXBzXG4gICAgdXBkYXRlU3RlcFVJKCk7XG4gICAgcmVuZGVyU3RlcDEoKTtcblxuICAgIGRlcGxveU1vZGFsLmNsYXNzTGlzdC5hZGQoJ3Nob3cnKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZVN0ZXBVSSgpIHtcbiAgICAvLyBTdGVwIGluZGljYXRvcnNcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcjcmVjaXBlLXN0ZXBzIC5yZWNpcGUtc3RlcCcpLmZvckVhY2goZWwgPT4ge1xuICAgICAgY29uc3Qgc3RlcCA9IHBhcnNlSW50KGVsLmRhdGFzZXQuc3RlcCk7XG4gICAgICBlbC5jbGFzc0xpc3QudG9nZ2xlKCdhY3RpdmUnLCBzdGVwID09PSBjdXJyZW50U3RlcCk7XG4gICAgICBlbC5jbGFzc0xpc3QudG9nZ2xlKCdjb21wbGV0ZWQnLCBzdGVwIDwgY3VycmVudFN0ZXApO1xuICAgIH0pO1xuXG4gICAgLy8gU3RlcCBwYW5lbHNcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8PSA0OyBpKyspIHtcbiAgICAgIGNvbnN0IHBhbmVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYHJlY2lwZS1zdGVwLSR7aX1gKTtcbiAgICAgIGlmIChwYW5lbCkgcGFuZWwuc3R5bGUuZGlzcGxheSA9IGkgPT09IGN1cnJlbnRTdGVwID8gJycgOiAnbm9uZSc7XG4gICAgfVxuXG4gICAgLy8gTmF2aWdhdGlvbiBidXR0b25zXG4gICAgcHJldkJ0bi5zdHlsZS5kaXNwbGF5ID0gY3VycmVudFN0ZXAgPiAxICYmIGN1cnJlbnRTdGVwIDwgNCA/ICcnIDogJ25vbmUnO1xuICAgIGlmIChjdXJyZW50U3RlcCA9PT0gNCkge1xuICAgICAgbmV4dEJ0bi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgY2FuY2VsQnRuLnRleHRDb250ZW50ID0gJ0Nsb3NlJztcbiAgICB9IGVsc2UgaWYgKGN1cnJlbnRTdGVwID09PSAzKSB7XG4gICAgICBuZXh0QnRuLnRleHRDb250ZW50ID0gJ1xcdUQ4M0RcXHVERTgwIERlcGxveSc7XG4gICAgICBuZXh0QnRuLnN0eWxlLmRpc3BsYXkgPSAnJztcbiAgICAgIGNhbmNlbEJ0bi50ZXh0Q29udGVudCA9ICdDYW5jZWwnO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXh0QnRuLnRleHRDb250ZW50ID0gJ05leHQnO1xuICAgICAgbmV4dEJ0bi5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gICAgICBjYW5jZWxCdG4udGV4dENvbnRlbnQgPSAnQ2FuY2VsJztcbiAgICB9XG4gIH1cblxuICAvLyBTdGVwIDE6IENvbXBvbmVudCBzZWxlY3Rpb25cbiAgZnVuY3Rpb24gcmVuZGVyU3RlcDEoKSB7XG4gICAgY29uc3QgbGlzdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdyZWNpcGUtY29tcG9uZW50LWxpc3QnKTtcbiAgICBsaXN0LmlubmVySFRNTCA9ICcnO1xuXG4gICAgY29uc3QgY29tcG9uZW50cyA9IGN1cnJlbnRSZWNpcGUuY29tcG9uZW50cyB8fCBbXTtcbiAgICBmb3IgKGNvbnN0IGNvbXAgb2YgY29tcG9uZW50cykge1xuICAgICAgY29uc3QgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIGVsLnN0eWxlLmNzc1RleHQgPSAnZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiAxMnB4OyBwYWRkaW5nOiAxMnB4OyBib3JkZXItcmFkaXVzOiA4cHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmcpOyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyc7XG5cbiAgICAgIGNvbnN0IGlzUmVxdWlyZWQgPSBjb21wLnJlcXVpcmVkO1xuICAgICAgY29uc3QgaXNJbnRlcm5hbCA9IGNvbXAuaW50ZXJuYWw7XG5cbiAgICAgIGVsLmlubmVySFRNTCA9IGBcbiAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiICR7aXNSZXF1aXJlZCA/ICdjaGVja2VkIGRpc2FibGVkJyA6ICdjaGVja2VkJ30gZGF0YS1jb21wb25lbnQtaWQ9XCIke2NvbXAuaWR9XCJcbiAgICAgICAgICBzdHlsZT1cIndpZHRoOiAxOHB4OyBoZWlnaHQ6IDE4cHg7IGFjY2VudC1jb2xvcjogdmFyKC0tYWNjZW50KTtcIiAvPlxuICAgICAgICA8ZGl2IHN0eWxlPVwiZmxleDogMTtcIj5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC13ZWlnaHQ6IDYwMDsgZm9udC1zaXplOiAwLjlyZW07XCI+JHtlc2NhcGVIdG1sKGNvbXAucm9sZSB8fCBjb21wLmlkKX08L2Rpdj5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjc4cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPlxuICAgICAgICAgICAgJHtjb21wLnRlbXBsYXRlUmVmID8gZXNjYXBlSHRtbChjb21wLnRlbXBsYXRlUmVmKSA6ICdCdWlsdC1pbid9XG4gICAgICAgICAgICAke2lzUmVxdWlyZWQgPyAnPHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tYWNjZW50KTsgbWFyZ2luLWxlZnQ6IDZweDtcIj5SZXF1aXJlZDwvc3Bhbj4nIDogJzxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLWxlZnQ6IDZweDtcIj5PcHRpb25hbDwvc3Bhbj4nfVxuICAgICAgICAgICAgJHtpc0ludGVybmFsID8gJzxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLWxlZnQ6IDZweDtcIj4oSW50ZXJuYWwpPC9zcGFuPicgOiAnJ31cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAke2NvbXAubm90ZSA/IGA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjc1cmVtOyBjb2xvcjogdmFyKC0td2Fybi1mZyk7IG1hcmdpbi10b3A6IDRweDtcIj5cXHUyNkEwICR7ZXNjYXBlSHRtbChjb21wLm5vdGUpfTwvZGl2PmAgOiAnJ31cbiAgICAgICAgPC9kaXY+XG4gICAgICBgO1xuICAgICAgbGlzdC5hcHBlbmRDaGlsZChlbCk7XG4gICAgfVxuICB9XG5cbiAgLy8gU3RlcCAyOiBTaGFyZWQgY29uZmlndXJhdGlvblxuICBmdW5jdGlvbiByZW5kZXJTdGVwMigpIHtcbiAgICBjb25zdCB2b2x1bWVTZWN0aW9uID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3JlY2lwZS12b2x1bWVzLXNlY3Rpb24nKTtcbiAgICBjb25zdCB2b2x1bWVMaXN0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3JlY2lwZS12b2x1bWUtbGlzdCcpO1xuXG4gICAgY29uc3Qgc2hhcmVkVm9sdW1lcyA9IGN1cnJlbnRSZWNpcGUuc2hhcmVkVm9sdW1lcztcbiAgICBpZiAoc2hhcmVkVm9sdW1lcyAmJiBPYmplY3Qua2V5cyhzaGFyZWRWb2x1bWVzKS5sZW5ndGggPiAwKSB7XG4gICAgICB2b2x1bWVTZWN0aW9uLnN0eWxlLmRpc3BsYXkgPSAnJztcbiAgICAgIHZvbHVtZUxpc3QuaW5uZXJIVE1MID0gJyc7XG5cbiAgICAgIGZvciAoY29uc3QgW2tleSwgdm9sXSBvZiBPYmplY3QuZW50cmllcyhzaGFyZWRWb2x1bWVzKSkge1xuICAgICAgICBjb25zdCBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBlbC5zdHlsZS5jc3NUZXh0ID0gJ2Rpc3BsYXk6IGdyaWQ7IGdhcDogNHB4Oyc7XG4gICAgICAgIGVsLmlubmVySFRNTCA9IGBcbiAgICAgICAgICA8bGFiZWwgc3R5bGU9XCJmb250LXdlaWdodDogNTAwOyBmb250LXNpemU6IDAuODVyZW07XCI+JHtlc2NhcGVIdG1sKHZvbC5sYWJlbCB8fCBrZXkpfTwvbGFiZWw+XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgZGF0YS12b2x1bWUta2V5PVwiJHtrZXl9XCIgdmFsdWU9XCIke2VzY2FwZUh0bWwodm9sLmRlZmF1bHRQYXRoIHx8ICcnKX1cIlxuICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCIke2VzY2FwZUh0bWwodm9sLmRlZmF1bHRQYXRoIHx8ICcvcGF0aCcpfVwiXG4gICAgICAgICAgICBzdHlsZT1cIndpZHRoOiAxMDAlOyBwYWRkaW5nOiA4cHggMTJweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iZyk7IGNvbG9yOiB2YXIoLS1mZyk7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJvcmRlci1yYWRpdXM6IDZweDsgZm9udC1mYW1pbHk6IG1vbm9zcGFjZTsgZm9udC1zaXplOiAwLjg1cmVtO1wiIC8+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0taGludC1zbVwiPiR7ZXNjYXBlSHRtbCh2b2wuZGVzY3JpcHRpb24gfHwgJycpfTwvZGl2PlxuICAgICAgICBgO1xuICAgICAgICB2b2x1bWVMaXN0LmFwcGVuZENoaWxkKGVsKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdm9sdW1lU2VjdGlvbi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIH1cbiAgfVxuXG4gIC8vIFN0ZXAgMzogUmV2aWV3XG4gIGZ1bmN0aW9uIHJlbmRlclN0ZXAzKCkge1xuICAgIGNvbnN0IGNvbnRlbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncmVjaXBlLXJldmlldy1jb250ZW50Jyk7XG4gICAgY29uc3Qgc2VsZWN0ZWRDb21wb25lbnRzID0gZ2V0U2VsZWN0ZWRDb21wb25lbnRzKCk7XG5cbiAgICBjb25zdCB2b2x1bWVJbnB1dHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcjcmVjaXBlLXZvbHVtZS1saXN0IGlucHV0W2RhdGEtdm9sdW1lLWtleV0nKTtcbiAgICBjb25zdCB2b2x1bWVzID0ge307XG4gICAgdm9sdW1lSW5wdXRzLmZvckVhY2goaW5wdXQgPT4ge1xuICAgICAgdm9sdW1lc1tpbnB1dC5kYXRhc2V0LnZvbHVtZUtleV0gPSBpbnB1dC52YWx1ZTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHR6ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3JlY2lwZS10aW1lem9uZScpLnZhbHVlIHx8ICdVVEMnO1xuICAgIGNvbnN0IGlwID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3JlY2lwZS1pcCcpLnZhbHVlIHx8ICdob3N0LmRvY2tlci5pbnRlcm5hbCc7XG4gICAgY29uc3QgdGFpbHNjYWxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3JlY2lwZS10YWlsc2NhbGUnKS5jaGVja2VkO1xuXG4gICAgY29udGVudC5pbm5lckhUTUwgPSBgXG4gICAgICA8ZGl2IHN0eWxlPVwiZm9udC13ZWlnaHQ6IDYwMDsgZm9udC1zaXplOiAxcmVtOyBtYXJnaW4tYm90dG9tOiAxMnB4O1wiPiR7ZXNjYXBlSHRtbChjdXJyZW50UmVjaXBlLm5hbWUpfTwvZGl2PlxuICAgICAgPGRpdiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi1ib3R0b206IDE2cHg7XCI+JHtlc2NhcGVIdG1sKGN1cnJlbnRSZWNpcGUuZGVzY3JpcHRpb24gfHwgJycpfTwvZGl2PlxuXG4gICAgICA8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMTJweDtcIj5cbiAgICAgICAgPHN0cm9uZz5Db21wb25lbnRzICgke3NlbGVjdGVkQ29tcG9uZW50cy5sZW5ndGh9KTo8L3N0cm9uZz5cbiAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGdyaWQ7IGdhcDogNHB4OyBtYXJnaW4tdG9wOiA2cHg7XCI+XG4gICAgICAgICAgJHtzZWxlY3RlZENvbXBvbmVudHMubWFwKGMgPT4gYDxkaXYgc3R5bGU9XCJwYWRkaW5nOiA0cHggMDsgZm9udC1zaXplOiAwLjg1cmVtO1wiPlxuICAgICAgICAgICAgXFx1MjAyMiA8c3Ryb25nPiR7ZXNjYXBlSHRtbChjLnJvbGUgfHwgYy5pZCl9PC9zdHJvbmc+ICR7Yy5pbnRlcm5hbCA/ICc8c3BhbiBzdHlsZT1cImNvbG9yOnZhcigtLW11dGVkKVwiPihpbnRlcm5hbCk8L3NwYW4+JyA6ICcnfVxuICAgICAgICAgIDwvZGl2PmApLmpvaW4oJycpfVxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICAke09iamVjdC5rZXlzKHZvbHVtZXMpLmxlbmd0aCA+IDAgPyBgPGRpdiBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDEycHg7XCI+XG4gICAgICAgIDxzdHJvbmc+Vm9sdW1lczo8L3N0cm9uZz5cbiAgICAgICAgJHtPYmplY3QuZW50cmllcyh2b2x1bWVzKS5tYXAoKFtrLCB2XSkgPT4gYDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuODVyZW07IGZvbnQtZmFtaWx5OiBtb25vc3BhY2U7IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+JHtrfTogJHtlc2NhcGVIdG1sKHYpfTwvZGl2PmApLmpvaW4oJycpfVxuICAgICAgPC9kaXY+YCA6ICcnfVxuXG4gICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjg1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPlxuICAgICAgICBUaW1lem9uZTogJHtlc2NhcGVIdG1sKHR6KX0gJmJ1bGw7IElQOiAke2VzY2FwZUh0bWwoaXApfSAke3RhaWxzY2FsZSA/ICcmYnVsbDsgVGFpbHNjYWxlIG9ubHknIDogJyd9XG4gICAgICA8L2Rpdj5cblxuICAgICAgJHtjdXJyZW50UmVjaXBlLm5ldHdvcmsgPyBgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC44NXJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLXRvcDogNHB4O1wiPkRvY2tlciBuZXR3b3JrOiA8Y29kZT4ke2VzY2FwZUh0bWwoY3VycmVudFJlY2lwZS5uZXR3b3JrLm5hbWUpfTwvY29kZT48L2Rpdj5gIDogJyd9XG4gICAgYDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldFNlbGVjdGVkQ29tcG9uZW50cygpIHtcbiAgICBjb25zdCBjaGVja2JveGVzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnI3JlY2lwZS1jb21wb25lbnQtbGlzdCBpbnB1dFtkYXRhLWNvbXBvbmVudC1pZF0nKTtcbiAgICBjb25zdCBzZWxlY3RlZElkcyA9IG5ldyBTZXQoKTtcbiAgICBjaGVja2JveGVzLmZvckVhY2goY2IgPT4ge1xuICAgICAgaWYgKGNiLmNoZWNrZWQpIHNlbGVjdGVkSWRzLmFkZChjYi5kYXRhc2V0LmNvbXBvbmVudElkKTtcbiAgICB9KTtcblxuICAgIC8vIEFsd2F5cyBpbmNsdWRlIHJlcXVpcmVkIGNvbXBvbmVudHNcbiAgICBjb25zdCBjb21wb25lbnRzID0gY3VycmVudFJlY2lwZS5jb21wb25lbnRzIHx8IFtdO1xuICAgIGNvbXBvbmVudHMuZmlsdGVyKGMgPT4gYy5yZXF1aXJlZCkuZm9yRWFjaChjID0+IHNlbGVjdGVkSWRzLmFkZChjLmlkKSk7XG5cbiAgICByZXR1cm4gY29tcG9uZW50cy5maWx0ZXIoYyA9PiBzZWxlY3RlZElkcy5oYXMoYy5pZCkpO1xuICB9XG5cbiAgLy8gU3RlcCA0OiBEZXBsb3lcbiAgYXN5bmMgZnVuY3Rpb24gZXhlY3V0ZURlcGxveSgpIHtcbiAgICBjb25zdCBwcm9ncmVzc0xpc3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncmVjaXBlLXByb2dyZXNzLWxpc3QnKTtcbiAgICBjb25zdCByZXN1bHRFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdyZWNpcGUtZGVwbG95LXJlc3VsdCcpO1xuICAgIHJlc3VsdEVsLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgcHJvZ3Jlc3NMaXN0LmlubmVySFRNTCA9ICcnO1xuXG4gICAgY29uc3Qgc2VsZWN0ZWRDb21wb25lbnRzID0gZ2V0U2VsZWN0ZWRDb21wb25lbnRzKCk7XG5cbiAgICAvLyBTaG93IHByb2dyZXNzIGl0ZW1zXG4gICAgZm9yIChjb25zdCBjb21wIG9mIHNlbGVjdGVkQ29tcG9uZW50cykge1xuICAgICAgY29uc3QgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIGVsLmlkID0gYHJlY2lwZS1wcm9ncmVzcy0ke2NvbXAuaWR9YDtcbiAgICAgIGVsLnN0eWxlLmNzc1RleHQgPSAnZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiAxMHB4OyBwYWRkaW5nOiAxMHB4IDEycHg7IGJvcmRlci1yYWRpdXM6IDZweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iZyk7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGZvbnQtc2l6ZTogMC44NXJlbTsnO1xuICAgICAgZWwuaW5uZXJIVE1MID0gYFxuICAgICAgICA8c3BhbiBjbGFzcz1cInJlY2lwZS1wcm9ncmVzcy1pY29uXCIgc3R5bGU9XCJmb250LXNpemU6IDEuMXJlbTtcIj5cXHUyM0YzPC9zcGFuPlxuICAgICAgICA8c3BhbiBzdHlsZT1cImZsZXg6MTsgZm9udC13ZWlnaHQ6IDUwMDtcIj4ke2VzY2FwZUh0bWwoY29tcC5yb2xlIHx8IGNvbXAuaWQpfTwvc3Bhbj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJyZWNpcGUtcHJvZ3Jlc3Mtc3RhdHVzXCIgc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPlF1ZXVlZDwvc3Bhbj5cbiAgICAgIGA7XG4gICAgICBwcm9ncmVzc0xpc3QuYXBwZW5kQ2hpbGQoZWwpO1xuICAgIH1cblxuICAgIC8vIENvbGxlY3QgY29uZmlnXG4gICAgY29uc3Qgdm9sdW1lSW5wdXRzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnI3JlY2lwZS12b2x1bWUtbGlzdCBpbnB1dFtkYXRhLXZvbHVtZS1rZXldJyk7XG4gICAgY29uc3Qgdm9sdW1lcyA9IHt9O1xuICAgIHZvbHVtZUlucHV0cy5mb3JFYWNoKGlucHV0ID0+IHtcbiAgICAgIHZvbHVtZXNbaW5wdXQuZGF0YXNldC52b2x1bWVLZXldID0gaW5wdXQudmFsdWU7XG4gICAgfSk7XG5cbiAgICBjb25zdCBjb25maWcgPSB7XG4gICAgICBzZWxlY3RlZENvbXBvbmVudHM6IHNlbGVjdGVkQ29tcG9uZW50cy5tYXAoYyA9PiBjLmlkKSxcbiAgICAgIHNoYXJlZENvbmZpZzoge1xuICAgICAgICBpcDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3JlY2lwZS1pcCcpLnZhbHVlIHx8ICdob3N0LmRvY2tlci5pbnRlcm5hbCcsXG4gICAgICAgIHRpbWV6b25lOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncmVjaXBlLXRpbWV6b25lJykudmFsdWUgfHwgJ1VUQycsXG4gICAgICAgIHRhaWxzY2FsZU9ubHk6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdyZWNpcGUtdGFpbHNjYWxlJykuY2hlY2tlZCxcbiAgICAgICAgdm9sdW1lc1xuICAgICAgfSxcbiAgICAgIGNvbXBvbmVudE92ZXJyaWRlczoge31cbiAgICB9O1xuXG4gICAgLy8gTWFyayBhbGwgYXMgZGVwbG95aW5nXG4gICAgZm9yIChjb25zdCBjb21wIG9mIHNlbGVjdGVkQ29tcG9uZW50cykge1xuICAgICAgdXBkYXRlUHJvZ3Jlc3NJdGVtKGNvbXAuaWQsICdkZXBsb3lpbmcnLCAnRGVwbG95aW5nLi4uJyk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3AgPSBhd2FpdCBzZWN1cmVGZXRjaCgnL2FwaS92MS9yZWNpcGVzL2RlcGxveScsIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7IHJlY2lwZUlkOiBjdXJyZW50UmVjaXBlLmlkLCBjb25maWcgfSlcbiAgICAgIH0pO1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3AuanNvbigpO1xuXG4gICAgICBpZiAoZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgIC8vIE1hcmsgZGVwbG95ZWQgY29tcG9uZW50c1xuICAgICAgICBmb3IgKGNvbnN0IGRlcGxveWVkIG9mIChkYXRhLmRlcGxveWVkIHx8IFtdKSkge1xuICAgICAgICAgIHVwZGF0ZVByb2dyZXNzSXRlbShkZXBsb3llZC5pZCwgJ3N1Y2Nlc3MnLCBkZXBsb3llZC51cmwgPyBgUnVubmluZyBcXHUyMTkyICR7ZGVwbG95ZWQudXJsfWAgOiAnUnVubmluZycpO1xuICAgICAgICB9XG4gICAgICAgIC8vIE1hcmsgZXJyb3JzXG4gICAgICAgIGZvciAoY29uc3QgZXJyIG9mIChkYXRhLmVycm9ycyB8fCBbXSkpIHtcbiAgICAgICAgICB1cGRhdGVQcm9ncmVzc0l0ZW0oZXJyLmNvbXBvbmVudElkLCAnZXJyb3InLCBlcnIuZXJyb3IpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVzdWx0RWwuc3R5bGUuZGlzcGxheSA9ICcnO1xuICAgICAgICByZXN1bHRFbC5pbm5lckhUTUwgPSBgXG4gICAgICAgICAgPGRpdiBzdHlsZT1cInBhZGRpbmc6IDE0cHg7IGJvcmRlci1yYWRpdXM6IDhweDsgYmFja2dyb3VuZDogcmdiYSg0NiwyMDQsMTEzLDAuMSk7IGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoNDYsMjA0LDExMywwLjMpO1wiPlxuICAgICAgICAgICAgPGRpdiBzdHlsZT1cImZvbnQtd2VpZ2h0OiA2MDA7IGNvbG9yOiB2YXIoLS1vay1mZyk7IG1hcmdpbi1ib3R0b206IDZweDtcIj4ke2VzY2FwZUh0bWwoZGF0YS5tZXNzYWdlIHx8ICdEZXBsb3llZCEnKX08L2Rpdj5cbiAgICAgICAgICAgICR7ZGF0YS5zZXR1cEluc3RydWN0aW9ucyA/IGA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjhyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi10b3A6IDhweDtcIj5cbiAgICAgICAgICAgICAgPHN0cm9uZz5TZXR1cCB0aXBzOjwvc3Ryb25nPlxuICAgICAgICAgICAgICA8dWwgc3R5bGU9XCJtYXJnaW46IDRweCAwIDAgMTZweDsgcGFkZGluZzogMDtcIj4ke2RhdGEuc2V0dXBJbnN0cnVjdGlvbnMubWFwKHMgPT4gYDxsaT4ke2VzY2FwZUh0bWwocyl9PC9saT5gKS5qb2luKCcnKX08L3VsPlxuICAgICAgICAgICAgPC9kaXY+YCA6ICcnfVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICBgO1xuXG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oYCR7Y3VycmVudFJlY2lwZS5uYW1lfSByZWNpcGUgZGVwbG95ZWQgc3VjY2Vzc2Z1bGx5IWAsICdzdWNjZXNzJywgNTAwMCk7XG5cbiAgICAgICAgLy8gUmVmcmVzaCBkYXNoYm9hcmRcbiAgICAgICAgaWYgKHdpbmRvdy5sb2FkU2VydmljZXMpIHdpbmRvdy5sb2FkU2VydmljZXMoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdEVsLnN0eWxlLmRpc3BsYXkgPSAnJztcbiAgICAgICAgcmVzdWx0RWwuaW5uZXJIVE1MID0gYDxkaXYgc3R5bGU9XCJwYWRkaW5nOiAxNHB4OyBib3JkZXItcmFkaXVzOiA4cHg7IGJhY2tncm91bmQ6IHJnYmEoMjMxLDc2LDYwLDAuMSk7IGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoMjMxLDc2LDYwLDAuMyk7IGNvbG9yOiB2YXIoLS1iYWQtZmcpO1wiPlxuICAgICAgICAgIDxzdHJvbmc+RGVwbG95bWVudCBmYWlsZWQ6PC9zdHJvbmc+ICR7ZXNjYXBlSHRtbChkYXRhLmVycm9yIHx8ICdVbmtub3duIGVycm9yJyl9XG4gICAgICAgIDwvZGl2PmA7XG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oYFJlY2lwZSBkZXBsb3ltZW50IGZhaWxlZDogJHtkYXRhLmVycm9yfWAsICdlcnJvcicsIDUwMDApO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJlc3VsdEVsLnN0eWxlLmRpc3BsYXkgPSAnJztcbiAgICAgIHJlc3VsdEVsLmlubmVySFRNTCA9IGA8ZGl2IHN0eWxlPVwicGFkZGluZzogMTRweDsgYm9yZGVyLXJhZGl1czogOHB4OyBiYWNrZ3JvdW5kOiByZ2JhKDIzMSw3Niw2MCwwLjEpOyBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDIzMSw3Niw2MCwwLjMpOyBjb2xvcjogdmFyKC0tYmFkLWZnKTtcIj5cbiAgICAgICAgPHN0cm9uZz5OZXR3b3JrIGVycm9yOjwvc3Ryb25nPiAke2VzY2FwZUh0bWwoZS5tZXNzYWdlKX1cbiAgICAgIDwvZGl2PmA7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlUHJvZ3Jlc3NJdGVtKGNvbXBvbmVudElkLCBzdGF0dXMsIHRleHQpIHtcbiAgICBjb25zdCBlbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGByZWNpcGUtcHJvZ3Jlc3MtJHtjb21wb25lbnRJZH1gKTtcbiAgICBpZiAoIWVsKSByZXR1cm47XG4gICAgY29uc3QgaWNvbiA9IGVsLnF1ZXJ5U2VsZWN0b3IoJy5yZWNpcGUtcHJvZ3Jlc3MtaWNvbicpO1xuICAgIGNvbnN0IHN0YXR1c0VsID0gZWwucXVlcnlTZWxlY3RvcignLnJlY2lwZS1wcm9ncmVzcy1zdGF0dXMnKTtcblxuICAgIGlmIChzdGF0dXMgPT09ICdkZXBsb3lpbmcnKSB7XG4gICAgICBpY29uLnRleHRDb250ZW50ID0gJ1xcdTIzRjMnO1xuICAgICAgc3RhdHVzRWwuc3R5bGUuY29sb3IgPSAndmFyKC0tYWNjZW50KSc7XG4gICAgfSBlbHNlIGlmIChzdGF0dXMgPT09ICdzdWNjZXNzJykge1xuICAgICAgaWNvbi50ZXh0Q29udGVudCA9ICdcXHUyNzA1JztcbiAgICAgIHN0YXR1c0VsLnN0eWxlLmNvbG9yID0gJ3ZhcigtLW9rLWZnKSc7XG4gICAgfSBlbHNlIGlmIChzdGF0dXMgPT09ICdlcnJvcicpIHtcbiAgICAgIGljb24udGV4dENvbnRlbnQgPSAnXFx1Mjc0Qyc7XG4gICAgICBzdGF0dXNFbC5zdHlsZS5jb2xvciA9ICd2YXIoLS1iYWQtZmcpJztcbiAgICB9XG4gICAgc3RhdHVzRWwudGV4dENvbnRlbnQgPSB0ZXh0O1xuICB9XG5cbiAgLy8gPT09IFNURVAgTkFWSUdBVElPTiA9PT1cbiAgbmV4dEJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICBpZiAoY3VycmVudFN0ZXAgPT09IDMpIHtcbiAgICAgIGN1cnJlbnRTdGVwID0gNDtcbiAgICAgIHVwZGF0ZVN0ZXBVSSgpO1xuICAgICAgZXhlY3V0ZURlcGxveSgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY3VycmVudFN0ZXAgPCAzKSB7XG4gICAgICBjdXJyZW50U3RlcCsrO1xuICAgICAgdXBkYXRlU3RlcFVJKCk7XG4gICAgICBpZiAoY3VycmVudFN0ZXAgPT09IDIpIHJlbmRlclN0ZXAyKCk7XG4gICAgICBpZiAoY3VycmVudFN0ZXAgPT09IDMpIHJlbmRlclN0ZXAzKCk7XG4gICAgfVxuICB9KTtcblxuICBwcmV2QnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgIGlmIChjdXJyZW50U3RlcCA+IDEgJiYgY3VycmVudFN0ZXAgPCA0KSB7XG4gICAgICBjdXJyZW50U3RlcC0tO1xuICAgICAgdXBkYXRlU3RlcFVJKCk7XG4gICAgfVxuICB9KTtcblxuICAvLyA9PT0gUkVDSVBFIENBUkQgR1JPVVBJTkcgT04gREFTSEJPQVJEID09PVxuICAvLyBBZnRlciBkYXNoYm9hcmQgbG9hZHMsIGdyb3VwIGNhcmRzIHRoYXQgc2hhcmUgYSByZWNpcGVJZFxuICB3aW5kb3cuZ3JvdXBSZWNpcGVDYXJkcyA9IGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IGNhcmRzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnNlcnZpY2UtY2FyZFtkYXRhLXJlY2lwZS1pZF0nKTtcbiAgICBpZiAoY2FyZHMubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICBjb25zdCBncm91cHMgPSB7fTtcbiAgICBjYXJkcy5mb3JFYWNoKGNhcmQgPT4ge1xuICAgICAgY29uc3QgcmVjaXBlSWQgPSBjYXJkLmRhdGFzZXQucmVjaXBlSWQ7XG4gICAgICBpZiAoIWdyb3Vwc1tyZWNpcGVJZF0pIGdyb3Vwc1tyZWNpcGVJZF0gPSBbXTtcbiAgICAgIGdyb3Vwc1tyZWNpcGVJZF0ucHVzaChjYXJkKTtcbiAgICB9KTtcblxuICAgIGZvciAoY29uc3QgW3JlY2lwZUlkLCBncm91cENhcmRzXSBvZiBPYmplY3QuZW50cmllcyhncm91cHMpKSB7XG4gICAgICBpZiAoZ3JvdXBDYXJkcy5sZW5ndGggPCAyKSBjb250aW51ZTtcblxuICAgICAgLy8gQXBwbHkgc3VidGxlIHZpc3VhbCBncm91cGluZ1xuICAgICAgZ3JvdXBDYXJkcy5mb3JFYWNoKChjYXJkLCBpKSA9PiB7XG4gICAgICAgIGNhcmQuc3R5bGUuYm9yZGVyTGVmdCA9ICczcHggc29saWQgcmdiYSgxNDIsNjgsMTczLDAuNSknO1xuICAgICAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgICAgIC8vIEFkZCBhIHJlY2lwZSBsYWJlbCB0byB0aGUgZmlyc3QgY2FyZFxuICAgICAgICAgIGxldCBsYWJlbCA9IGNhcmQucXVlcnlTZWxlY3RvcignLnJlY2lwZS1ncm91cC1sYWJlbCcpO1xuICAgICAgICAgIGlmICghbGFiZWwpIHtcbiAgICAgICAgICAgIGxhYmVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBsYWJlbC5jbGFzc05hbWUgPSAncmVjaXBlLWdyb3VwLWxhYmVsJztcbiAgICAgICAgICAgIGxhYmVsLnN0eWxlLmNzc1RleHQgPSAncG9zaXRpb246IGFic29sdXRlOyB0b3A6IC04cHg7IGxlZnQ6IDEycHg7IGZvbnQtc2l6ZTogMC42cmVtOyBwYWRkaW5nOiAxcHggOHB4OyBib3JkZXItcmFkaXVzOiA4cHg7IGJhY2tncm91bmQ6IHJnYmEoMTQyLDY4LDE3MywwLjMpOyBjb2xvcjogI2Q0YTVmZjsgZm9udC13ZWlnaHQ6IDYwMDsgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTsgbGV0dGVyLXNwYWNpbmc6IDAuNXB4Oyc7XG4gICAgICAgICAgICBsYWJlbC50ZXh0Q29udGVudCA9IHJlY2lwZUlkLnJlcGxhY2UoLy0vZywgJyAnKTtcbiAgICAgICAgICAgIGNhcmQuc3R5bGUucG9zaXRpb24gPSAncmVsYXRpdmUnO1xuICAgICAgICAgICAgY2FyZC5hcHBlbmRDaGlsZChsYWJlbCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgLy8gPT09IFJFQ0lQRSBNQU5BR0VNRU5UIEFDVElPTlMgPT09XG4gIHdpbmRvdy5tYW5hZ2VSZWNpcGUgPSBhc3luYyBmdW5jdGlvbihyZWNpcGVJZCwgYWN0aW9uKSB7XG4gICAgY29uc3QgZW5kcG9pbnQgPSBgL2FwaS92MS9yZWNpcGVzLyR7cmVjaXBlSWR9LyR7YWN0aW9ufWA7XG4gICAgY29uc3QgbWV0aG9kID0gYWN0aW9uID09PSAncmVtb3ZlJyA/ICdERUxFVEUnIDogJ1BPU1QnO1xuICAgIGNvbnN0IHVybCA9IGFjdGlvbiA9PT0gJ3JlbW92ZScgPyBgL2FwaS92MS9yZWNpcGVzLyR7cmVjaXBlSWR9YCA6IGVuZHBvaW50O1xuXG4gICAgaWYgKGFjdGlvbiA9PT0gJ3JlbW92ZScgJiYgIWNvbmZpcm0oYFJlbW92ZSB0aGUgZW50aXJlICR7cmVjaXBlSWR9IHJlY2lwZT8gVGhpcyB3aWxsIGRlbGV0ZSBhbGwgY29udGFpbmVycyBhbmQgY29uZmlndXJhdGlvbi5gKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwID0gYXdhaXQgc2VjdXJlRmV0Y2godXJsLCB7IG1ldGhvZCB9KTtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwLmpzb24oKTtcbiAgICAgIGlmIChkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgc2hvd05vdGlmaWNhdGlvbihgUmVjaXBlICR7YWN0aW9ufTogJHtkYXRhLnJlc3VsdHM/LmZpbHRlcihyID0+IHIuc3RhdHVzICE9PSAnZmFpbGVkJykubGVuZ3RoIHx8IDB9IGNvbXBvbmVudHMgcHJvY2Vzc2VkYCwgJ3N1Y2Nlc3MnLCA0MDAwKTtcbiAgICAgICAgaWYgKHdpbmRvdy5sb2FkU2VydmljZXMpIHdpbmRvdy5sb2FkU2VydmljZXMoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oYFJlY2lwZSAke2FjdGlvbn0gZmFpbGVkOiAke2RhdGEuZXJyb3J9YCwgJ2Vycm9yJywgNTAwMCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgc2hvd05vdGlmaWNhdGlvbihgTmV0d29yayBlcnJvcjogJHtlLm1lc3NhZ2V9YCwgJ2Vycm9yJywgNTAwMCk7XG4gICAgfVxuICB9O1xuXG4gIC8vID09PSBJTkpFQ1QgQ1NTID09PVxuICBjb25zdCBzdHlsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJyk7XG4gIHN0eWxlLnRleHRDb250ZW50ID0gYFxuICAgIC5yZWNpcGUtc3RlcCB7XG4gICAgICBmbGV4OiAxO1xuICAgICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgICAgcGFkZGluZzogOHB4IDRweDtcbiAgICAgIGZvbnQtc2l6ZTogMC43OHJlbTtcbiAgICAgIGNvbG9yOiB2YXIoLS1tdXRlZCk7XG4gICAgICBib3JkZXItYm90dG9tOiAycHggc29saWQgdmFyKC0tYm9yZGVyKTtcbiAgICAgIHRyYW5zaXRpb246IGFsbCAwLjJzO1xuICAgIH1cbiAgICAucmVjaXBlLXN0ZXAgc3BhbiB7XG4gICAgICBkaXNwbGF5OiBpbmxpbmUtZmxleDtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICAgIHdpZHRoOiAyMHB4O1xuICAgICAgaGVpZ2h0OiAyMHB4O1xuICAgICAgYm9yZGVyLXJhZGl1czogNTAlO1xuICAgICAgYmFja2dyb3VuZDogdmFyKC0tYm9yZGVyKTtcbiAgICAgIGNvbG9yOiB2YXIoLS1tdXRlZCk7XG4gICAgICBmb250LXNpemU6IDAuN3JlbTtcbiAgICAgIGZvbnQtd2VpZ2h0OiA3MDA7XG4gICAgICBtYXJnaW4tcmlnaHQ6IDRweDtcbiAgICB9XG4gICAgLnJlY2lwZS1zdGVwLmFjdGl2ZSB7XG4gICAgICBjb2xvcjogdmFyKC0tYWNjZW50KTtcbiAgICAgIGJvcmRlci1ib3R0b20tY29sb3I6IHZhcigtLWFjY2VudCk7XG4gICAgfVxuICAgIC5yZWNpcGUtc3RlcC5hY3RpdmUgc3BhbiB7XG4gICAgICBiYWNrZ3JvdW5kOiB2YXIoLS1hY2NlbnQpO1xuICAgICAgY29sb3I6ICNmZmY7XG4gICAgfVxuICAgIC5yZWNpcGUtc3RlcC5jb21wbGV0ZWQge1xuICAgICAgY29sb3I6IHZhcigtLW9rLWZnKTtcbiAgICAgIGJvcmRlci1ib3R0b20tY29sb3I6IHZhcigtLW9rLWZnKTtcbiAgICB9XG4gICAgLnJlY2lwZS1zdGVwLmNvbXBsZXRlZCBzcGFuIHtcbiAgICAgIGJhY2tncm91bmQ6IHZhcigtLW9rLWZnKTtcbiAgICAgIGNvbG9yOiAjZmZmO1xuICAgIH1cbiAgICAucmVjaXBlLXN0ZXAtcGFuZWwge1xuICAgICAgbWluLWhlaWdodDogMTgwcHg7XG4gICAgfVxuICBgO1xuICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHN0eWxlKTtcblxuICAvLyA9PT0gSU5JVCA9PT1cbiAgLy8gUHJlLWZldGNoIHByZW1pdW0gc3RhdHVzIG9uIGxvYWRcbiAgY2hlY2tSZWNpcGVQcmVtaXVtKCk7XG59KSgpO1xuO1xuLy8gPT09PT09PT09PSBDQUREWSBSRUxPQUQgQlVUVE9OID09PT09PT09PT1cbihmdW5jdGlvbigpIHtcbiAgLy8gUmVsb2FkIENhZGR5IGJ1dHRvbiBoYW5kbGVyXG4gIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdyZWxvYWQtY2FkZHktdG9wJyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGJ1dHRvbiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdyZWxvYWQtY2FkZHktdG9wJyk7XG4gICAgY29uc3Qgb3JpZ2luYWxUZXh0ID0gYnV0dG9uLnRleHRDb250ZW50O1xuXG4gICAgdHJ5IHtcbiAgICAgIGJ1dHRvbi50ZXh0Q29udGVudCA9ICdcdTIzRjMgUmVsb2FkaW5nLi4uJztcbiAgICAgIGJ1dHRvbi5kaXNhYmxlZCA9IHRydWU7XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgc2VjdXJlRmV0Y2goJy9hcGkvdjEvY2FkZHkvcmVsb2FkJywge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH1cbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG5cbiAgICAgIGlmIChyZXNwb25zZS5vayAmJiByZXN1bHQuc3VjY2Vzcykge1xuICAgICAgICBidXR0b24udGV4dENvbnRlbnQgPSAnXHUyNzA1IFJlbG9hZGVkISc7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIGJ1dHRvbi50ZXh0Q29udGVudCA9IG9yaWdpbmFsVGV4dDtcbiAgICAgICAgICBidXR0b24uZGlzYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgfSwgMjAwMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IocmVzdWx0LmVycm9yIHx8ICdSZWxvYWQgZmFpbGVkJyk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGJ1dHRvbi50ZXh0Q29udGVudCA9ICdcdTI3NEMgRmFpbGVkJztcbiAgICAgIHNob3dOb3RpZmljYXRpb24oYEZhaWxlZCB0byByZWxvYWQgQ2FkZHk6ICR7ZXJyb3IubWVzc2FnZX1gLCAnZXJyb3InKTtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBidXR0b24udGV4dENvbnRlbnQgPSBvcmlnaW5hbFRleHQ7XG4gICAgICAgIGJ1dHRvbi5kaXNhYmxlZCA9IGZhbHNlO1xuICAgICAgfSwgMjAwMCk7XG4gICAgfVxuICB9KTtcbn0pKCk7XG47XG4vLyA9PT09PT09PT09IEVSUk9SIExPRyBWSUVXRVIgPT09PT09PT09PVxuKGZ1bmN0aW9uKCkge1xuICAvLyBJbmplY3QgbW9kYWwgSFRNTFxuICBpbmplY3RNb2RhbCgnZXJyb3ItbG9nLW1vZGFsJywgJzxkaXYgaWQ9XCJlcnJvci1sb2ctbW9kYWxcIiBjbGFzcz1cImxvZ3MtbW9kYWxcIj48ZGl2IGNsYXNzPVwibG9ncy1tb2RhbC1jb250ZW50XCI+PGRpdiBjbGFzcz1cImxvZ3MtaGVhZGVyXCI+PGgzPlx1RDgzRFx1RENDQiBFcnJvciBMb2dzPC9oMz48ZGl2IGNsYXNzPVwibG9ncy1jb250cm9sc1wiPjxidXR0b24gaWQ9XCJlcnJvci1sb2ctcmVmcmVzaFwiIHN0eWxlPVwicGFkZGluZzo0cHggMTJweCFpbXBvcnRhbnQ7Zm9udC1zaXplOi44NXJlbSFpbXBvcnRhbnRcIj5cdUQ4M0RcdUREMDQgUmVmcmVzaDwvYnV0dG9uPjxidXR0b24gaWQ9XCJlcnJvci1sb2ctY2xlYXJcIiBzdHlsZT1cInBhZGRpbmc6NHB4IDEycHghaW1wb3J0YW50O2ZvbnQtc2l6ZTouODVyZW0haW1wb3J0YW50O2JhY2tncm91bmQ6Y29sb3ItbWl4KGluIHNyZ2IsdmFyKC0tYmFkLWZnKSAxNSUsdHJhbnNwYXJlbnQpIWltcG9ydGFudDtib3JkZXItY29sb3I6dmFyKC0tYmFkLWZnKSFpbXBvcnRhbnQ7Y29sb3I6dmFyKC0tYmFkLWZnKSFpbXBvcnRhbnRcIj5cdUQ4M0RcdURERDFcdUZFMEYgQ2xlYXI8L2J1dHRvbj48YnV0dG9uIGlkPVwiZXJyb3ItbG9nLWNsb3NlXCIgY2xhc3M9XCJjbG9zZS1idG5cIj5cdTI3MTU8L2J1dHRvbj48L2Rpdj48L2Rpdj48ZGl2IGNsYXNzPVwibG9ncy1jb250YWluZXJcIj48ZGl2IGlkPVwiZXJyb3ItbG9nLWNvbnRlbnRcIiBjbGFzcz1cImxvZ3MtY29udGVudFwiPjxkaXYgY2xhc3M9XCJsb2dzLWxvYWRpbmdcIj5Mb2FkaW5nIGVycm9yIGxvZ3MuLi48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj4nKTtcblxuICBjb25zdCBtb2RhbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdlcnJvci1sb2ctbW9kYWwnKTtcbiAgY29uc3QgY29udGVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdlcnJvci1sb2ctY29udGVudCcpO1xuICBjb25zdCB2aWV3QnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3ZpZXctZXJyb3ItbG9ncycpO1xuICBjb25zdCByZWZyZXNoQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Vycm9yLWxvZy1yZWZyZXNoJyk7XG4gIGNvbnN0IGNsZWFyQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Vycm9yLWxvZy1jbGVhcicpO1xuICBjb25zdCBjbG9zZUJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdlcnJvci1sb2ctY2xvc2UnKTtcblxuICBhc3luYyBmdW5jdGlvbiBsb2FkRXJyb3JMb2dzKCkge1xuICAgIGNvbnRlbnQuaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9XCJsb2dzLWxvYWRpbmdcIj5Mb2FkaW5nIGVycm9yIGxvZ3MuLi48L2Rpdj4nO1xuICAgIFxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL2Vycm9yLWxvZ3MnKTtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICBcbiAgICAgIGlmIChkYXRhLnN1Y2Nlc3MgJiYgZGF0YS5sb2dzKSB7XG4gICAgICAgIGlmIChkYXRhLmxvZ3MubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgY29udGVudC5pbm5lckhUTUwgPSAnPGRpdiBzdHlsZT1cInBhZGRpbmc6IDIwcHg7IHRleHQtYWxpZ246IGNlbnRlcjsgY29sb3I6IHZhcigtLW11dGVkKTtcIj5cdTI3MDUgTm8gZXJyb3JzIGxvZ2dlZCEgRXZlcnl0aGluZyBpcyB3b3JraW5nIHNtb290aGx5LjwvZGl2Pic7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29udGVudC5pbm5lckhUTUwgPSBkYXRhLmxvZ3MubWFwKGxvZyA9PiB7XG4gICAgICAgICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUobG9nLnRpbWVzdGFtcCkudG9Mb2NhbGVTdHJpbmcoKTtcbiAgICAgICAgICAgIHJldHVybiBgXG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsb2ctZW50cnkgZXJyb3JcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImxvZy10aW1lc3RhbXBcIj4ke2RhdGV9PC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibG9nLWxldmVsXCI+RVJST1I8L3NwYW4+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxvZy1tZXNzYWdlXCI+XG4gICAgICAgICAgICAgICAgICA8c3Ryb25nPiR7ZXNjYXBlSHRtbChsb2cuY29udGV4dCl9PC9zdHJvbmc+OiAke2VzY2FwZUh0bWwobG9nLmVycm9yKX1cbiAgICAgICAgICAgICAgICAgICR7bG9nLmRldGFpbHMgPyBgPGJyPjxzbWFsbCBzdHlsZT1cIm9wYWNpdHk6IDAuNztcIj4ke2VzY2FwZUh0bWwobG9nLmRldGFpbHMpfTwvc21hbGw+YCA6ICcnfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIGA7XG4gICAgICAgICAgfSkuam9pbignJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnRlbnQuaW5uZXJIVE1MID0gJzxkaXYgc3R5bGU9XCJwYWRkaW5nOiAyMHB4OyBjb2xvcjogdmFyKC0tYmFkLWZnKTtcIj5cdTI3NEMgRmFpbGVkIHRvIGxvYWQgZXJyb3IgbG9nczwvZGl2Pic7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnRlbnQuaW5uZXJIVE1MID0gYDxkaXYgc3R5bGU9XCJwYWRkaW5nOiAyMHB4OyBjb2xvcjogdmFyKC0tYmFkLWZnKTtcIj5cdTI3NEMgRXJyb3IgbG9hZGluZyBsb2dzOiAke2VzY2FwZUh0bWwoZXJyb3IubWVzc2FnZSl9PC9kaXY+YDtcbiAgICB9XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBjbGVhckVycm9yTG9ncygpIHtcbiAgICBpZiAoIWNvbmZpcm0oJ0NsZWFyIGFsbCBlcnJvciBsb2dzPycpKSByZXR1cm47XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBzZWN1cmVGZXRjaCgnL2FwaS92MS9lcnJvci1sb2dzJywgeyBtZXRob2Q6ICdERUxFVEUnIH0pO1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgIFxuICAgICAgaWYgKGRhdGEuc3VjY2Vzcykge1xuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKCdcdTI3MDUgRXJyb3IgbG9ncyBjbGVhcmVkJywgJ3N1Y2Nlc3MnLCAzMDAwKTtcbiAgICAgICAgbG9hZEVycm9yTG9ncygpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2hvd05vdGlmaWNhdGlvbignXHUyNzRDIEZhaWxlZCB0byBjbGVhciBsb2dzJywgJ2Vycm9yJywgMzAwMCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHNob3dOb3RpZmljYXRpb24oYFx1Mjc0QyBFcnJvcjogJHtlcnJvci5tZXNzYWdlfWAsICdlcnJvcicsIDMwMDApO1xuICAgIH1cbiAgfVxuXG4gIHZpZXdCdG4/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgIG1vZGFsLmNsYXNzTGlzdC5hZGQoJ3Nob3cnKTtcbiAgICBsb2FkRXJyb3JMb2dzKCk7XG4gIH0pO1xuXG4gIHJlZnJlc2hCdG4/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgbG9hZEVycm9yTG9ncyk7XG4gIGNsZWFyQnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGNsZWFyRXJyb3JMb2dzKTtcbiAgd2lyZU1vZGFsKG1vZGFsLCBjbG9zZUJ0bik7XG59KSgpO1xuO1xuLy8gPT09PT09PT09PSBDT05UQUlORVIgTE9HIFZJRVdFUiA9PT09PT09PT09XG4oZnVuY3Rpb24oKSB7XG4gIC8vIEluamVjdCBtb2RhbCBIVE1MXG4gIGluamVjdE1vZGFsKCdjb250YWluZXItbG9ncy1tb2RhbCcsIGA8ZGl2IGlkPVwiY29udGFpbmVyLWxvZ3MtbW9kYWxcIiBjbGFzcz1cIndlYXRoZXItbW9kYWxcIiBzdHlsZT1cInotaW5kZXg6IDEwMDE7XCI+XG4gICAgPGRpdiBjbGFzcz1cIndlYXRoZXItbW9kYWwtY29udGVudFwiIHN0eWxlPVwibWluLXdpZHRoOiA5MDBweDsgbWF4LXdpZHRoOiA5NXZ3OyBoZWlnaHQ6IDgwdmg7IGRpc3BsYXk6IGZsZXg7IGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XCI+XG4gICAgICA8ZGl2IGNsYXNzPVwibG9ncy1oZWFkZXJcIiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjsgYWxpZ24taXRlbXM6IGNlbnRlcjsgcGFkZGluZy1ib3R0b206IDEycHg7IGJvcmRlci1ib3R0b206IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBtYXJnaW4tYm90dG9tOiAxMnB4O1wiPlxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIDxoMyBzdHlsZT1cIm1hcmdpbjogMDtcIj5cdUQ4M0RcdURDREMgQ29udGFpbmVyIExvZ3M8L2gzPlxuICAgICAgICAgIDxwIGNsYXNzPVwibW9kYWwtc3VidGl0bGVcIiBzdHlsZT1cIm1hcmdpbjogNHB4IDAgMCAwOyBmb250LXNpemU6IDAuODVyZW07IG9wYWNpdHk6IDAuNztcIj5WaWV3IGFuZCBzdHJlYW0gRG9ja2VyIGNvbnRhaW5lciBsb2dzPC9wPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImxvZ3MtY29udHJvbHNcIiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGdhcDogOHB4OyBhbGlnbi1pdGVtczogY2VudGVyO1wiPlxuICAgICAgICAgIDxzZWxlY3QgaWQ9XCJjbC1jb250YWluZXItc2VsZWN0XCIgc3R5bGU9XCJwYWRkaW5nOiA2cHggMTBweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgYm9yZGVyLXJhZGl1czogNnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1iZyk7IGNvbG9yOiB2YXIoLS1mZyk7IG1pbi13aWR0aDogMjAwcHg7XCI+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+U2VsZWN0IGEgY29udGFpbmVyLi4uPC9vcHRpb24+XG4gICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgaWQ9XCJjbC1sb2ctc2VhcmNoXCIgcGxhY2Vob2xkZXI9XCJTZWFyY2ggbG9ncy4uLlwiIHN0eWxlPVwicGFkZGluZzogNnB4IDEwcHg7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJvcmRlci1yYWRpdXM6IDZweDsgYmFja2dyb3VuZDogdmFyKC0tYmcpOyBjb2xvcjogdmFyKC0tZmcpOyB3aWR0aDogMTUwcHg7XCIgLz5cbiAgICAgICAgICA8c2VsZWN0IGlkPVwiY2wtbG9nLXRhaWxcIiBzdHlsZT1cInBhZGRpbmc6IDZweCAxMHB4OyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBib3JkZXItcmFkaXVzOiA2cHg7IGJhY2tncm91bmQ6IHZhcigtLWJnKTsgY29sb3I6IHZhcigtLWZnKTtcIj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCI1MFwiPkxhc3QgNTAgbGluZXM8L29wdGlvbj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCIxMDBcIiBzZWxlY3RlZD5MYXN0IDEwMCBsaW5lczwvb3B0aW9uPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIjUwMFwiPkxhc3QgNTAwIGxpbmVzPC9vcHRpb24+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiMTAwMFwiPkxhc3QgMTAwMCBsaW5lczwvb3B0aW9uPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cImFsbFwiPkFsbCBsb2dzPC9vcHRpb24+XG4gICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgPGJ1dHRvbiBpZD1cImNsLXJlZnJlc2hcIiBjbGFzcz1cImJ0bi1hY2NlbnQtc29saWRcIiBzdHlsZT1cInBhZGRpbmc6IDZweCAxNHB4OyBmb250LXNpemU6IDAuODVyZW07XCI+XHVEODNEXHVERDA0IFJlZnJlc2g8L2J1dHRvbj5cbiAgICAgICAgICA8YnV0dG9uIGlkPVwiY2wtc3RyZWFtXCIgY2xhc3M9XCJidG4tYWNjZW50LXNvbGlkXCIgc3R5bGU9XCJwYWRkaW5nOiA2cHggMTRweDsgZm9udC1zaXplOiAwLjg1cmVtO1wiPlx1MjVCNiBTdHJlYW08L2J1dHRvbj5cbiAgICAgICAgICA8YnV0dG9uIGlkPVwiY2wtZG93bmxvYWRcIiBzdHlsZT1cInBhZGRpbmc6IDZweCAxNHB4OyBmb250LXNpemU6IDAuODVyZW07XCI+XHVEODNEXHVEQ0JFIERvd25sb2FkPC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvbiBpZD1cImNsLWNsZWFyLXNlYXJjaFwiIHN0eWxlPVwicGFkZGluZzogNnB4IDEwcHg7IGZvbnQtc2l6ZTogMC44NXJlbTtcIiB0aXRsZT1cIkNsZWFyIHNlYXJjaFwiPlx1MjcxNTwvYnV0dG9uPlxuICAgICAgICAgIDxidXR0b24gaWQ9XCJjbC1jbG9zZVwiIGNsYXNzPVwiY2xvc2UtYnRuXCIgc3R5bGU9XCJwYWRkaW5nOiA2cHggMTBweDtcIj5cdTI3MTU8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICAgIFxuICAgICAgPGRpdiBpZD1cImNsLWNvbnRhaW5lci1pbmZvXCIgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBnYXA6IDE2cHg7IG1hcmdpbi1ib3R0b206IDEycHg7IHBhZGRpbmc6IDhweCAxMnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1iZy1zZWNvbmRhcnksIHZhcigtLWJnKSk7IGJvcmRlci1yYWRpdXM6IDZweDsgZm9udC1zaXplOiAwLjgycmVtO1wiPlxuICAgICAgICA8c3Bhbj48c3Ryb25nPkltYWdlOjwvc3Ryb25nPiA8c3BhbiBpZD1cImNsLWltYWdlXCI+LTwvc3Bhbj48L3NwYW4+XG4gICAgICAgIDxzcGFuPjxzdHJvbmc+U3RhdHVzOjwvc3Ryb25nPiA8c3BhbiBpZD1cImNsLXN0YXR1c1wiPi08L3NwYW4+PC9zcGFuPlxuICAgICAgICA8c3Bhbj48c3Ryb25nPkNyZWF0ZWQ6PC9zdHJvbmc+IDxzcGFuIGlkPVwiY2wtY3JlYXRlZFwiPi08L3NwYW4+PC9zcGFuPlxuICAgICAgPC9kaXY+XG4gICAgICBcbiAgICAgIDxkaXYgaWQ9XCJjbC1sb2ctY29udGVudFwiIGNsYXNzPVwibG9ncy1jb250ZW50IHNjcm9sbC1jb250YWluZXJcIiBzdHlsZT1cImZsZXg6IDE7IG1pbi1oZWlnaHQ6IDA7IGJhY2tncm91bmQ6ICMxYTFhMWE7IGJvcmRlci1yYWRpdXM6IDZweDsgcGFkZGluZzogMTJweDsgZm9udC1mYW1pbHk6ICdNb25hY28nLCAnTWVubG8nLCAnVWJ1bnR1IE1vbm8nLCBtb25vc3BhY2U7IGZvbnQtc2l6ZTogMC43OHJlbTsgb3ZlcmZsb3c6IGF1dG87XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJsb2dzLWxvYWRpbmdcIiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7IHRleHQtYWxpZ246IGNlbnRlcjsgcGFkZGluZzogNDBweDtcIj5TZWxlY3QgYSBjb250YWluZXIgdG8gdmlldyBsb2dzPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICAgIFxuICAgICAgPGRpdiBpZD1cImNsLXN0cmVhbS1zdGF0dXNcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7IHBhZGRpbmc6IDhweCAxMnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1vay1iZywgIzFhM2ExYSk7IGNvbG9yOiB2YXIoLS1vay1mZywgIzRhZGU4MCk7IGJvcmRlci1yYWRpdXM6IDZweDsgbWFyZ2luLXRvcDogOHB4OyBmb250LXNpemU6IDAuODJyZW07XCI+XG4gICAgICAgIDxzcGFuIGlkPVwiY2wtc3RyZWFtLWluZGljYXRvclwiPlx1RDgzRFx1REQzNDwvc3Bhbj4gPHNwYW4gaWQ9XCJjbC1zdHJlYW0tdGV4dFwiPkRpc2Nvbm5lY3RlZDwvc3Bhbj5cbiAgICAgIDwvZGl2PlxuICAgICAgXG4gICAgICA8ZGl2IGNsYXNzPVwid2VhdGhlci1tb2RhbC1idXR0b25zIG1vZGFsLWZvb3Rlci1iYXJcIiBzdHlsZT1cIm1hcmdpbi10b3A6IDEycHg7IHBhZGRpbmctdG9wOiAxMnB4OyBib3JkZXItdG9wOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcIj5cbiAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGdhcDogOHB4OyBmb250LXNpemU6IDAuNzhyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+XG4gICAgICAgICAgPHNwYW4gaWQ9XCJjbC1saW5lLWNvdW50XCI+MCBsaW5lczwvc3Bhbj5cbiAgICAgICAgICA8c3Bhbj58PC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGlkPVwiY2wtZmlsdGVyLWNvdW50XCI+MCBmaWx0ZXJlZDwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxidXR0b24gaWQ9XCJjbC1jbG9zZS1idG5cIiBjbGFzcz1cImJ0bi1zZWNvbmRhcnlcIj5DbG9zZTwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PmApO1xuXG4gIGNvbnN0IG1vZGFsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NvbnRhaW5lci1sb2dzLW1vZGFsJyk7XG4gIGNvbnN0IGNvbnRhaW5lclNlbGVjdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjbC1jb250YWluZXItc2VsZWN0Jyk7XG4gIGNvbnN0IGxvZ0NvbnRlbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2wtbG9nLWNvbnRlbnQnKTtcbiAgY29uc3QgbG9nU2VhcmNoID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NsLWxvZy1zZWFyY2gnKTtcbiAgY29uc3QgbG9nVGFpbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjbC1sb2ctdGFpbCcpO1xuICBjb25zdCByZWZyZXNoQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NsLXJlZnJlc2gnKTtcbiAgY29uc3Qgc3RyZWFtQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NsLXN0cmVhbScpO1xuICBjb25zdCBkb3dubG9hZEJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjbC1kb3dubG9hZCcpO1xuICBjb25zdCBjbGVhclNlYXJjaEJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjbC1jbGVhci1zZWFyY2gnKTtcbiAgY29uc3QgY2xvc2VCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2wtY2xvc2UnKTtcbiAgY29uc3QgY2xvc2VCdG4yID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NsLWNsb3NlLWJ0bicpO1xuICBjb25zdCBzdHJlYW1TdGF0dXMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2wtc3RyZWFtLXN0YXR1cycpO1xuICBjb25zdCBzdHJlYW1JbmRpY2F0b3IgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2wtc3RyZWFtLWluZGljYXRvcicpO1xuICBjb25zdCBzdHJlYW1UZXh0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NsLXN0cmVhbS10ZXh0Jyk7XG4gIGNvbnN0IGxpbmVDb3VudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjbC1saW5lLWNvdW50Jyk7XG4gIGNvbnN0IGZpbHRlckNvdW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NsLWZpbHRlci1jb3VudCcpO1xuICBcbiAgLy8gQ29udGFpbmVyIGluZm8gZWxlbWVudHNcbiAgY29uc3QgaW1hZ2VFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjbC1pbWFnZScpO1xuICBjb25zdCBzdGF0dXNFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjbC1zdGF0dXMnKTtcbiAgY29uc3QgY3JlYXRlZEVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NsLWNyZWF0ZWQnKTtcblxuICBsZXQgY3VycmVudENvbnRhaW5lcklkID0gbnVsbDtcbiAgbGV0IGN1cnJlbnRMb2dzID0gW107XG4gIGxldCBmaWx0ZXJlZExvZ3MgPSBbXTtcbiAgbGV0IGV2ZW50U291cmNlID0gbnVsbDtcbiAgbGV0IGlzU3RyZWFtaW5nID0gZmFsc2U7XG4gIGxldCBzZWFyY2hUaW1lb3V0ID0gbnVsbDtcblxuICAvLyBGb3JtYXQgZGF0ZVxuICBmdW5jdGlvbiBmb3JtYXREYXRlKGRhdGVTdHIpIHtcbiAgICBpZiAoIWRhdGVTdHIpIHJldHVybiAnLSc7XG4gICAgY29uc3QgZCA9IG5ldyBEYXRlKGRhdGVTdHIpO1xuICAgIGlmIChpc05hTihkLmdldFRpbWUoKSkpIHJldHVybiBkYXRlU3RyO1xuICAgIHJldHVybiBkLnRvTG9jYWxlU3RyaW5nKCk7XG4gIH1cblxuICAvLyBFc2NhcGUgSFRNTFxuICBmdW5jdGlvbiBlc2NhcGVIdG1sKHN0cikge1xuICAgIGlmICghc3RyKSByZXR1cm4gJyc7XG4gICAgY29uc3QgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgZGl2LnRleHRDb250ZW50ID0gc3RyO1xuICAgIHJldHVybiBkaXYuaW5uZXJIVE1MO1xuICB9XG5cbiAgLy8gRm9ybWF0IGxvZyBlbnRyeSBmb3IgZGlzcGxheVxuICBmdW5jdGlvbiBmb3JtYXRMb2dFbnRyeShsb2csIGluZGV4KSB7XG4gICAgY29uc3Qgc3RyZWFtQ2xhc3MgPSBsb2cuc3RyZWFtID09PSAnc3RkZXJyJyA/ICdsb2ctc3RkZXJyJyA6ICdsb2ctc3Rkb3V0JztcbiAgICBjb25zdCBzdHJlYW1JY29uID0gbG9nLnN0cmVhbSA9PT0gJ3N0ZGVycicgPyAnXHUyNkEwXHVGRTBGJyA6ICdcdUQ4M0RcdURDRTQnO1xuICAgIHJldHVybiBgXG4gICAgICA8ZGl2IGNsYXNzPVwibG9nLWVudHJ5ICR7c3RyZWFtQ2xhc3N9XCIgZGF0YS1pbmRleD1cIiR7aW5kZXh9XCIgc3R5bGU9XCJwYWRkaW5nOiA0cHggOHB4OyBib3JkZXItYm90dG9tOiAxcHggc29saWQgIzMzMzsgZGlzcGxheTogZmxleDsgZ2FwOiA4cHg7XCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwibG9nLWxpbmUtbnVtXCIgc3R5bGU9XCJjb2xvcjogIzY2NjsgbWluLXdpZHRoOiA0MHB4OyB0ZXh0LWFsaWduOiByaWdodDsgdXNlci1zZWxlY3Q6IG5vbmU7XCI+JHtpbmRleCArIDF9PC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImxvZy1zdHJlYW0taWNvblwiIHN0eWxlPVwiY29sb3I6ICR7bG9nLnN0cmVhbSA9PT0gJ3N0ZGVycicgPyAnI2Y1OWUwYicgOiAnIzIyYzU1ZSd9O1wiPiR7c3RyZWFtSWNvbn08L3NwYW4+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwibG9nLXRleHRcIiBzdHlsZT1cImZsZXg6IDE7IHdoaXRlLXNwYWNlOiBwcmUtd3JhcDsgd29yZC1icmVhazogYnJlYWstYWxsOyBjb2xvcjogI2U1ZTVlNTtcIj4ke2VzY2FwZUh0bWwobG9nLnRleHQpfTwvc3Bhbj5cbiAgICAgIDwvZGl2PlxuICAgIGA7XG4gIH1cblxuICAvLyBSZW5kZXIgbG9ncyB0byB0aGUgY29udGVudCBhcmVhXG4gIGZ1bmN0aW9uIHJlbmRlckxvZ3MobG9ncywgc2VhcmNoVGVybSA9ICcnKSB7XG4gICAgaWYgKCFsb2dzIHx8IGxvZ3MubGVuZ3RoID09PSAwKSB7XG4gICAgICBsb2dDb250ZW50LmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwibG9ncy1sb2FkaW5nXCIgc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpOyB0ZXh0LWFsaWduOiBjZW50ZXI7IHBhZGRpbmc6IDQwcHg7XCI+Tm8gbG9ncyBhdmFpbGFibGU8L2Rpdj4nO1xuICAgICAgbGluZUNvdW50LnRleHRDb250ZW50ID0gJzAgbGluZXMnO1xuICAgICAgZmlsdGVyQ291bnQudGV4dENvbnRlbnQgPSAnMCBmaWx0ZXJlZCc7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY3VycmVudExvZ3MgPSBsb2dzO1xuICAgIGZpbHRlcmVkTG9ncyA9IHNlYXJjaFRlcm0gPyBsb2dzLmZpbHRlcihsb2cgPT4gXG4gICAgICBsb2cudGV4dCAmJiBsb2cudGV4dC50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHNlYXJjaFRlcm0udG9Mb3dlckNhc2UoKSlcbiAgICApIDogbG9ncztcblxuICAgIGxpbmVDb3VudC50ZXh0Q29udGVudCA9IGAke2xvZ3MubGVuZ3RofSBsaW5lc2A7XG4gICAgZmlsdGVyQ291bnQudGV4dENvbnRlbnQgPSBzZWFyY2hUZXJtID8gYCR7ZmlsdGVyZWRMb2dzLmxlbmd0aH0gb2YgJHtsb2dzLmxlbmd0aH0gc2hvd25gIDogYCR7bG9ncy5sZW5ndGh9IHNob3duYDtcblxuICAgIGlmIChmaWx0ZXJlZExvZ3MubGVuZ3RoID09PSAwKSB7XG4gICAgICBsb2dDb250ZW50LmlubmVySFRNTCA9IGA8ZGl2IGNsYXNzPVwibG9ncy1sb2FkaW5nXCIgc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpOyB0ZXh0LWFsaWduOiBjZW50ZXI7IHBhZGRpbmc6IDQwcHg7XCI+Tm8gbG9ncyBtYXRjaCBcIiR7ZXNjYXBlSHRtbChzZWFyY2hUZXJtKX1cIjwvZGl2PmA7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbG9nQ29udGVudC5pbm5lckhUTUwgPSBmaWx0ZXJlZExvZ3MubWFwKChsb2csIGkpID0+IGZvcm1hdExvZ0VudHJ5KGxvZywgaSkpLmpvaW4oJycpO1xuICAgIFxuICAgIC8vIFNjcm9sbCB0byBib3R0b21cbiAgICBsb2dDb250ZW50LnNjcm9sbFRvcCA9IGxvZ0NvbnRlbnQuc2Nyb2xsSGVpZ2h0O1xuICB9XG5cbiAgLy8gTG9hZCBjb250YWluZXIgbGlzdFxuICBhc3luYyBmdW5jdGlvbiBsb2FkQ29udGFpbmVycygpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IGdldEpTT04oJy9hcGkvdjEvbG9ncy9jb250YWluZXJzJyk7XG4gICAgICBjb25zdCBjb250YWluZXJzID0gZGF0YS5jb250YWluZXJzIHx8IFtdO1xuICAgICAgXG4gICAgICAvLyBTdG9yZSBjdXJyZW50IHNlbGVjdGlvblxuICAgICAgY29uc3QgY3VycmVudFZhbCA9IGNvbnRhaW5lclNlbGVjdC52YWx1ZTtcbiAgICAgIFxuICAgICAgY29udGFpbmVyU2VsZWN0LmlubmVySFRNTCA9ICc8b3B0aW9uIHZhbHVlPVwiXCI+U2VsZWN0IGEgY29udGFpbmVyLi4uPC9vcHRpb24+JztcbiAgICAgIFxuICAgICAgY29udGFpbmVycy5mb3JFYWNoKGMgPT4ge1xuICAgICAgICBjb25zdCBvcHRpb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdvcHRpb24nKTtcbiAgICAgICAgb3B0aW9uLnZhbHVlID0gYy5pZDtcbiAgICAgICAgb3B0aW9uLnRleHRDb250ZW50ID0gYCR7Yy5uYW1lfSAoJHtjLmltYWdlLnNwbGl0KCc6JylbMF19KSAtICR7Yy5zdGF0dXN9YDtcbiAgICAgICAgb3B0aW9uLmRhdGFzZXQubmFtZSA9IGMubmFtZTtcbiAgICAgICAgb3B0aW9uLmRhdGFzZXQuaW1hZ2UgPSBjLmltYWdlO1xuICAgICAgICBvcHRpb24uZGF0YXNldC5zdGF0dXMgPSBjLnN0YXR1cztcbiAgICAgICAgb3B0aW9uLmRhdGFzZXQuY3JlYXRlZCA9IGMuY3JlYXRlZDtcbiAgICAgICAgY29udGFpbmVyU2VsZWN0LmFwcGVuZENoaWxkKG9wdGlvbik7XG4gICAgICB9KTtcbiAgICAgIFxuICAgICAgLy8gUmVzdG9yZSBzZWxlY3Rpb24gaWYgc3RpbGwgdmFsaWRcbiAgICAgIGlmIChjdXJyZW50VmFsICYmIGNvbnRhaW5lclNlbGVjdC5xdWVyeVNlbGVjdG9yKGBvcHRpb25bdmFsdWU9XCIke2N1cnJlbnRWYWx9XCJdYCkpIHtcbiAgICAgICAgY29udGFpbmVyU2VsZWN0LnZhbHVlID0gY3VycmVudFZhbDtcbiAgICAgICAgbG9hZENvbnRhaW5lckluZm8oY3VycmVudFZhbCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gbG9hZCBjb250YWluZXJzOicsIGVycik7XG4gICAgfVxuICB9XG5cbiAgLy8gTG9hZCBjb250YWluZXIgaW5mb1xuICBmdW5jdGlvbiBsb2FkQ29udGFpbmVySW5mbyhjb250YWluZXJJZCkge1xuICAgIGNvbnN0IG9wdGlvbiA9IGNvbnRhaW5lclNlbGVjdC5xdWVyeVNlbGVjdG9yKGBvcHRpb25bdmFsdWU9XCIke2NvbnRhaW5lcklkfVwiXWApO1xuICAgIGlmIChvcHRpb24pIHtcbiAgICAgIGltYWdlRWwudGV4dENvbnRlbnQgPSBvcHRpb24uZGF0YXNldC5pbWFnZSB8fCAnLSc7XG4gICAgICBzdGF0dXNFbC50ZXh0Q29udGVudCA9IG9wdGlvbi5kYXRhc2V0LnN0YXR1cyB8fCAnLSc7XG4gICAgICBzdGF0dXNFbC5zdHlsZS5jb2xvciA9IG9wdGlvbi5kYXRhc2V0LnN0YXR1cyA9PT0gJ3J1bm5pbmcnID8gJ3ZhcigtLW9rLWZnLCAjNGFkZTgwKScgOiAndmFyKC0tYmFkLWZnLCAjZWY0NDQ0KSc7XG4gICAgICBjcmVhdGVkRWwudGV4dENvbnRlbnQgPSBmb3JtYXREYXRlKG9wdGlvbi5kYXRhc2V0LmNyZWF0ZWQpO1xuICAgIH1cbiAgfVxuXG4gIC8vIExvYWQgbG9ncyBmb3Igc2VsZWN0ZWQgY29udGFpbmVyXG4gIGFzeW5jIGZ1bmN0aW9uIGxvYWRMb2dzKCkge1xuICAgIGNvbnN0IGNvbnRhaW5lcklkID0gY29udGFpbmVyU2VsZWN0LnZhbHVlO1xuICAgIGlmICghY29udGFpbmVySWQpIHtcbiAgICAgIGxvZ0NvbnRlbnQuaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9XCJsb2dzLWxvYWRpbmdcIiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7IHRleHQtYWxpZ246IGNlbnRlcjsgcGFkZGluZzogNDBweDtcIj5TZWxlY3QgYSBjb250YWluZXIgdG8gdmlldyBsb2dzPC9kaXY+JztcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBTdG9wIGFueSBleGlzdGluZyBzdHJlYW1cbiAgICBzdG9wU3RyZWFtKCk7XG5cbiAgICBjdXJyZW50Q29udGFpbmVySWQgPSBjb250YWluZXJJZDtcbiAgICBsb2FkQ29udGFpbmVySW5mbyhjb250YWluZXJJZCk7XG5cbiAgICBjb25zdCB0YWlsID0gbG9nVGFpbC52YWx1ZTtcbiAgICBjb25zdCBzZWFyY2hUZXJtID0gbG9nU2VhcmNoLnZhbHVlLnRyaW0oKTtcblxuICAgIGxvZ0NvbnRlbnQuaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9XCJsb2dzLWxvYWRpbmdcIiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7IHRleHQtYWxpZ246IGNlbnRlcjsgcGFkZGluZzogNDBweDtcIj5Mb2FkaW5nIGxvZ3MuLi48L2Rpdj4nO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHVybCA9IGAvYXBpL3YxL2xvZ3MvY29udGFpbmVyLyR7Y29udGFpbmVySWR9JHt0YWlsICE9PSAnYWxsJyA/IGA/dGFpbD0ke3RhaWx9YCA6ICcnfWA7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgZ2V0SlNPTih1cmwpO1xuXG4gICAgICBpZiAoZGF0YS5sb2dzICYmIGRhdGEubG9ncy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJlbmRlckxvZ3MoZGF0YS5sb2dzLCBzZWFyY2hUZXJtKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvZ0NvbnRlbnQuaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9XCJsb2dzLWxvYWRpbmdcIiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7IHRleHQtYWxpZ246IGNlbnRlcjsgcGFkZGluZzogNDBweDtcIj5ObyBsb2dzIGZvdW5kIGZvciB0aGlzIGNvbnRhaW5lcjwvZGl2Pic7XG4gICAgICAgIGxpbmVDb3VudC50ZXh0Q29udGVudCA9ICcwIGxpbmVzJztcbiAgICAgICAgZmlsdGVyQ291bnQudGV4dENvbnRlbnQgPSAnMCBmaWx0ZXJlZCc7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBsb2dDb250ZW50LmlubmVySFRNTCA9IGA8ZGl2IGNsYXNzPVwibG9ncy1sb2FkaW5nXCIgc3R5bGU9XCJjb2xvcjogdmFyKC0tYmFkLWZnLCAjZWY0NDQ0KTsgdGV4dC1hbGlnbjogY2VudGVyOyBwYWRkaW5nOiA0MHB4O1wiPkVycm9yIGxvYWRpbmcgbG9nczogJHtlc2NhcGVIdG1sKGVyci5tZXNzYWdlKX08L2Rpdj5gO1xuICAgIH1cbiAgfVxuXG4gIC8vIFN0YXJ0IHN0cmVhbWluZyBsb2dzXG4gIGZ1bmN0aW9uIHN0YXJ0U3RyZWFtKCkge1xuICAgIGNvbnN0IGNvbnRhaW5lcklkID0gY29udGFpbmVyU2VsZWN0LnZhbHVlO1xuICAgIGlmICghY29udGFpbmVySWQpIHJldHVybjtcblxuICAgIC8vIFN0b3AgYW55IGV4aXN0aW5nIHN0cmVhbVxuICAgIHN0b3BTdHJlYW0oKTtcblxuICAgIGlzU3RyZWFtaW5nID0gdHJ1ZTtcbiAgICBzdHJlYW1CdG4udGV4dENvbnRlbnQgPSAnXHUyM0Y5IFN0b3AnO1xuICAgIHN0cmVhbVN0YXR1cy5zdHlsZS5kaXNwbGF5ID0gJ2ZsZXgnO1xuICAgIHN0cmVhbUluZGljYXRvci50ZXh0Q29udGVudCA9ICdcdUQ4M0RcdURGRTInO1xuICAgIHN0cmVhbVRleHQudGV4dENvbnRlbnQgPSAnQ29ubmVjdGluZy4uLic7XG5cbiAgICBjb25zdCB1cmwgPSBgL2FwaS92MS9sb2dzL3N0cmVhbS8ke2NvbnRhaW5lcklkfWA7XG4gICAgZXZlbnRTb3VyY2UgPSBuZXcgRXZlbnRTb3VyY2UodXJsKTtcblxuICAgIGV2ZW50U291cmNlLm9ub3BlbiA9ICgpID0+IHtcbiAgICAgIHN0cmVhbUluZGljYXRvci50ZXh0Q29udGVudCA9ICdcdUQ4M0RcdURGRTInO1xuICAgICAgc3RyZWFtVGV4dC50ZXh0Q29udGVudCA9ICdDb25uZWN0ZWQgLSBzdHJlYW1pbmcgbG9ncyc7XG4gICAgfTtcblxuICAgIGV2ZW50U291cmNlLm9ubWVzc2FnZSA9IChldmVudCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgbG9nID0gSlNPTi5wYXJzZShldmVudC5kYXRhKTtcbiAgICAgICAgXG4gICAgICAgIGlmIChsb2cuZXJyb3IpIHtcbiAgICAgICAgICBzdHJlYW1JbmRpY2F0b3IudGV4dENvbnRlbnQgPSAnXHVEODNEXHVERDM0JztcbiAgICAgICAgICBzdHJlYW1UZXh0LnRleHRDb250ZW50ID0gYEVycm9yOiAke2xvZy5lcnJvcn1gO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFkZCB0byBjdXJyZW50IGxvZ3NcbiAgICAgICAgY3VycmVudExvZ3MucHVzaChsb2cpO1xuICAgICAgICBmaWx0ZXJlZExvZ3MucHVzaChsb2cpO1xuICAgICAgICBcbiAgICAgICAgLy8gVXBkYXRlIGNvdW50c1xuICAgICAgICBsaW5lQ291bnQudGV4dENvbnRlbnQgPSBgJHtjdXJyZW50TG9ncy5sZW5ndGh9IGxpbmVzYDtcbiAgICAgICAgZmlsdGVyQ291bnQudGV4dENvbnRlbnQgPSBgJHtmaWx0ZXJlZExvZ3MubGVuZ3RofSBzaG93bmA7XG4gICAgICAgIFxuICAgICAgICAvLyBBcHBlbmQgbmV3IGxvZyBlbnRyeVxuICAgICAgICBjb25zdCBzZWFyY2hUZXJtID0gbG9nU2VhcmNoLnZhbHVlLnRyaW0oKTtcbiAgICAgICAgaWYgKCFzZWFyY2hUZXJtIHx8IChsb2cudGV4dCAmJiBsb2cudGV4dC50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHNlYXJjaFRlcm0udG9Mb3dlckNhc2UoKSkpKSB7XG4gICAgICAgICAgY29uc3QgZW50cnkgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICBlbnRyeS5pbm5lckhUTUwgPSBmb3JtYXRMb2dFbnRyeShsb2csIGZpbHRlcmVkTG9ncy5sZW5ndGggLSAxKTtcbiAgICAgICAgICBjb25zdCBlbnRyeURpdiA9IGVudHJ5LmZpcnN0RWxlbWVudENoaWxkO1xuICAgICAgICAgIGVudHJ5RGl2LnN0eWxlLmJhY2tncm91bmQgPSAnIzFhM2ExYSc7XG4gICAgICAgICAgbG9nQ29udGVudC5hcHBlbmRDaGlsZChlbnRyeURpdik7XG4gICAgICAgICAgXG4gICAgICAgICAgLy8gQXV0by1zY3JvbGwgdG8gYm90dG9tXG4gICAgICAgICAgbG9nQ29udGVudC5zY3JvbGxUb3AgPSBsb2dDb250ZW50LnNjcm9sbEhlaWdodDtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBwYXJzaW5nIGxvZzonLCBlKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZXZlbnRTb3VyY2Uub25lcnJvciA9ICgpID0+IHtcbiAgICAgIHN0cmVhbUluZGljYXRvci50ZXh0Q29udGVudCA9ICdcdUQ4M0RcdUREMzQnO1xuICAgICAgc3RyZWFtVGV4dC50ZXh0Q29udGVudCA9ICdEaXNjb25uZWN0ZWQnO1xuICAgICAgaXNTdHJlYW1pbmcgPSBmYWxzZTtcbiAgICAgIHN0cmVhbUJ0bi50ZXh0Q29udGVudCA9ICdcdTI1QjYgU3RyZWFtJztcbiAgICB9O1xuXG4gICAgLy8gU3RvcmUgdGhlIEV2ZW50U291cmNlIGZvciBjbGVhbnVwXG4gICAgbW9kYWwuX2V2ZW50U291cmNlID0gZXZlbnRTb3VyY2U7XG4gIH1cblxuICAvLyBTdG9wIHN0cmVhbWluZyBsb2dzXG4gIGZ1bmN0aW9uIHN0b3BTdHJlYW0oKSB7XG4gICAgaWYgKGV2ZW50U291cmNlKSB7XG4gICAgICBldmVudFNvdXJjZS5jbG9zZSgpO1xuICAgICAgZXZlbnRTb3VyY2UgPSBudWxsO1xuICAgIH1cbiAgICBpZiAobW9kYWwuX2V2ZW50U291cmNlKSB7XG4gICAgICBtb2RhbC5fZXZlbnRTb3VyY2UuY2xvc2UoKTtcbiAgICAgIG1vZGFsLl9ldmVudFNvdXJjZSA9IG51bGw7XG4gICAgfVxuICAgIGlzU3RyZWFtaW5nID0gZmFsc2U7XG4gICAgc3RyZWFtQnRuLnRleHRDb250ZW50ID0gJ1x1MjVCNiBTdHJlYW0nO1xuICAgIHN0cmVhbVN0YXR1cy5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICB9XG5cbiAgLy8gRG93bmxvYWQgbG9ncyBhcyBmaWxlXG4gIGZ1bmN0aW9uIGRvd25sb2FkTG9ncygpIHtcbiAgICBpZiAoIWN1cnJlbnRMb2dzIHx8IGN1cnJlbnRMb2dzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgc2hvd05vdGlmaWNhdGlvbignTm8gbG9ncyB0byBkb3dubG9hZCcsICdlcnJvcicpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbnRhaW5lck5hbWUgPSBjb250YWluZXJTZWxlY3QucXVlcnlTZWxlY3Rvcihgb3B0aW9uW3ZhbHVlPVwiJHtjdXJyZW50Q29udGFpbmVySWR9XCJdYCk/LmRhdGFzZXQubmFtZSB8fCBjdXJyZW50Q29udGFpbmVySWQ7XG4gICAgY29uc3QgdGltZXN0YW1wID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpLnJlcGxhY2UoL1s6Ll0vZywgJy0nKTtcbiAgICBjb25zdCBmaWxlbmFtZSA9IGAke2NvbnRhaW5lck5hbWV9LWxvZ3MtJHt0aW1lc3RhbXB9LnR4dGA7XG5cbiAgICBjb25zdCBjb250ZW50ID0gY3VycmVudExvZ3MubWFwKGxvZyA9PiB7XG4gICAgICBjb25zdCB0aW1lc3RhbXAgPSBsb2cudGltZXN0YW1wIHx8ICcnO1xuICAgICAgY29uc3Qgc3RyZWFtID0gbG9nLnN0cmVhbSA9PT0gJ3N0ZGVycicgPyAnW0VSUl0nIDogJ1tPVVRdJztcbiAgICAgIHJldHVybiBgJHt0aW1lc3RhbXAgPyB0aW1lc3RhbXAgKyAnICcgOiAnJ30ke3N0cmVhbX0gJHtsb2cudGV4dH1gO1xuICAgIH0pLmpvaW4oJ1xcbicpO1xuXG4gICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFtjb250ZW50XSwgeyB0eXBlOiAndGV4dC9wbGFpbicgfSk7XG4gICAgY29uc3QgdXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICBjb25zdCBhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xuICAgIGEuaHJlZiA9IHVybDtcbiAgICBhLmRvd25sb2FkID0gZmlsZW5hbWU7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChhKTtcbiAgICBhLmNsaWNrKCk7XG4gICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChhKTtcbiAgICBVUkwucmV2b2tlT2JqZWN0VVJMKHVybCk7XG5cbiAgICBzaG93Tm90aWZpY2F0aW9uKGBEb3dubG9hZGVkICR7Y3VycmVudExvZ3MubGVuZ3RofSBsb2cgbGluZXNgLCAnc3VjY2VzcycpO1xuICB9XG5cbiAgLy8gRXZlbnQgbGlzdGVuZXJzXG4gIGNvbnRhaW5lclNlbGVjdD8uYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgKCkgPT4ge1xuICAgIGxvYWRMb2dzKCk7XG4gIH0pO1xuXG4gIGxvZ1RhaWw/LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsICgpID0+IHtcbiAgICBsb2FkTG9ncygpO1xuICB9KTtcblxuICByZWZyZXNoQnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICBsb2FkTG9ncygpO1xuICB9KTtcblxuICBzdHJlYW1CdG4/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgIGlmIChpc1N0cmVhbWluZykge1xuICAgICAgc3RvcFN0cmVhbSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdGFydFN0cmVhbSgpO1xuICAgIH1cbiAgfSk7XG5cbiAgZG93bmxvYWRCdG4/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgIGRvd25sb2FkTG9ncygpO1xuICB9KTtcblxuICBjbGVhclNlYXJjaEJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgbG9nU2VhcmNoLnZhbHVlID0gJyc7XG4gICAgcmVuZGVyTG9ncyhjdXJyZW50TG9ncywgJycpO1xuICB9KTtcblxuICBsb2dTZWFyY2g/LmFkZEV2ZW50TGlzdGVuZXIoJ2lucHV0JywgKCkgPT4ge1xuICAgIC8vIERlYm91bmNlIHNlYXJjaFxuICAgIGNsZWFyVGltZW91dChzZWFyY2hUaW1lb3V0KTtcbiAgICBzZWFyY2hUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICByZW5kZXJMb2dzKGN1cnJlbnRMb2dzLCBsb2dTZWFyY2gudmFsdWUudHJpbSgpKTtcbiAgICB9LCAzMDApO1xuICB9KTtcblxuICBsb2dTZWFyY2g/LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCAoZSkgPT4ge1xuICAgIGlmIChlLmtleSA9PT0gJ0VzY2FwZScpIHtcbiAgICAgIGxvZ1NlYXJjaC52YWx1ZSA9ICcnO1xuICAgICAgcmVuZGVyTG9ncyhjdXJyZW50TG9ncywgJycpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gT3BlbiBtb2RhbFxuICBjb25zdCBvcGVuQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3ZpZXctY29udGFpbmVyLWxvZ3MnKTtcbiAgb3BlbkJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgbW9kYWwuY2xhc3NMaXN0LmFkZCgnc2hvdycpO1xuICAgIGxvYWRDb250YWluZXJzKCk7XG4gIH0pO1xuXG4gIC8vIENsb3NlIG1vZGFsIGhhbmRsZXJzXG4gIGZ1bmN0aW9uIGNsb3NlTW9kYWwoKSB7XG4gICAgc3RvcFN0cmVhbSgpO1xuICAgIG1vZGFsLmNsYXNzTGlzdC5yZW1vdmUoJ3Nob3cnKTtcbiAgfVxuXG4gIGNsb3NlQnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGNsb3NlTW9kYWwpO1xuICBjbG9zZUJ0bjI/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgY2xvc2VNb2RhbCk7XG5cbiAgLy8gQ2xvc2Ugb24gZXNjYXBlIGtleVxuICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgKGUpID0+IHtcbiAgICBpZiAoZS5rZXkgPT09ICdFc2NhcGUnICYmIG1vZGFsLmNsYXNzTGlzdC5jb250YWlucygnc2hvdycpKSB7XG4gICAgICBjbG9zZU1vZGFsKCk7XG4gICAgfVxuICB9KTtcblxuICAvLyBXaXJlIGJhY2tkcm9wIGNsaWNrIHRvIGNsb3NlTW9kYWwgc28gdGhlIGxvZyBzdHJlYW0gc3RvcHMgdG9vLlxuICAvLyAoQ2FuJ3QgdXNlIHdpcmVNb2RhbCBoZXJlIFx1MjAxNCBpdCBvbmx5IGRvZXMgbW9kYWwuY2xhc3NMaXN0LnJlbW92ZSgnc2hvdycpXG4gIC8vIG9uIGJhY2tkcm9wIGNsaWNrLCB3aGljaCB3b3VsZCBsZWFrIHRoZSBTU0Uvc3RyZWFtIGNvbm5lY3Rpb24uKVxuICBtb2RhbC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIChlKSA9PiB7IGlmIChlLnRhcmdldCA9PT0gbW9kYWwpIGNsb3NlTW9kYWwoKTsgfSk7XG5cbiAgLy8gRXhwb3NlIGZvciB1c2UgYnkgc2VydmljZSBjYXJkIGJ1dHRvbnMgKGdyaWQuanMgY2FsbHMgb3BlbkNvbnRhaW5lckxvZ3NNb2RhbClcbiAgd2luZG93Lm9wZW5Db250YWluZXJMb2dzTW9kYWwgPSBmdW5jdGlvbihjb250YWluZXJJZCwgY29udGFpbmVyTmFtZSkge1xuICAgIG1vZGFsLmNsYXNzTGlzdC5hZGQoJ3Nob3cnKTtcbiAgICBsb2FkQ29udGFpbmVycygpLnRoZW4oKCkgPT4ge1xuICAgICAgLy8gVHJ5IHRvIGZpbmQgYW5kIHNlbGVjdCB0aGUgY29udGFpbmVyXG4gICAgICBjb25zdCBvcHRpb24gPSBBcnJheS5mcm9tKGNvbnRhaW5lclNlbGVjdC5vcHRpb25zKS5maW5kKG9wdCA9PiBcbiAgICAgICAgb3B0LnZhbHVlID09PSBjb250YWluZXJJZCB8fCBvcHQuZGF0YXNldC5uYW1lID09PSBjb250YWluZXJOYW1lXG4gICAgICApO1xuICAgICAgaWYgKG9wdGlvbikge1xuICAgICAgICBjb250YWluZXJTZWxlY3QudmFsdWUgPSBvcHRpb24udmFsdWU7XG4gICAgICAgIGxvYWRDb250YWluZXJJbmZvKG9wdGlvbi52YWx1ZSk7XG4gICAgICAgIGxvYWRMb2dzKCk7XG4gICAgICB9IGVsc2UgaWYgKGNvbnRhaW5lcklkKSB7XG4gICAgICAgIC8vIElmIGNvbnRhaW5lciBub3QgZm91bmQgaW4gbGlzdCBidXQgd2UgaGF2ZSBhbiBJRCwgdHJ5IGxvYWRpbmcgZGlyZWN0bHlcbiAgICAgICAgY3VycmVudENvbnRhaW5lcklkID0gY29udGFpbmVySWQ7XG4gICAgICAgIGltYWdlRWwudGV4dENvbnRlbnQgPSBjb250YWluZXJOYW1lIHx8IGNvbnRhaW5lcklkO1xuICAgICAgICBzdGF0dXNFbC50ZXh0Q29udGVudCA9ICctJztcbiAgICAgICAgY3JlYXRlZEVsLnRleHRDb250ZW50ID0gJy0nO1xuICAgICAgICBsb2FkTG9ncygpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gTm8gY29udGFpbmVyIElELCBqdXN0IHNob3cgbW9kYWwgd2l0aCBjb250YWluZXIgbGlzdFxuICAgICAgICBsb2dDb250ZW50LmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwibG9ncy1sb2FkaW5nXCIgc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpOyB0ZXh0LWFsaWduOiBjZW50ZXI7IHBhZGRpbmc6IDQwcHg7XCI+U2VsZWN0IGEgY29udGFpbmVyIHRvIHZpZXcgbG9nczwvZGl2Pic7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG59KSgpO1xuO1xuLy8gPT09PT09PT09PSBDT05UQUlORVIgU05BUFNIT1QgLyBDSEVDS1BPSU5UID09PT09PT09PT1cbihmdW5jdGlvbigpIHtcbiAgLy8gSW5qZWN0IG1vZGFsIEhUTUxcbiAgaW5qZWN0TW9kYWwoJ3NuYXBzaG90LW1vZGFsJywgYDxkaXYgaWQ9XCJzbmFwc2hvdC1tb2RhbFwiIGNsYXNzPVwid2VhdGhlci1tb2RhbFwiPlxuICAgIDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsLWNvbnRlbnRcIiBzdHlsZT1cIm1pbi13aWR0aDogNzAwcHg7IG1heC13aWR0aDogODUwcHg7XCI+XG4gICAgICA8aDM+XHVEODNEXHVEQ0JFIENvbnRhaW5lciBTbmFwc2hvdHM8L2gzPlxuICAgICAgPHAgY2xhc3M9XCJtb2RhbC1zdWJ0aXRsZVwiPlxuICAgICAgICBDcmVhdGUgYW5kIG1hbmFnZSBEb2NrZXIgY29udGFpbmVyIGNoZWNrcG9pbnRzIGZvciBpbnN0YW50IHN0YXRlIHJlY292ZXJ5LlxuICAgICAgPC9wPlxuXG4gICAgICA8ZGl2IGlkPVwic25hcHNob3QtY29udGFpbmVyLXNlbGVjdC13cmFwcGVyXCIgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiAxNnB4O1wiPlxuICAgICAgICA8bGFiZWwgc3R5bGU9XCJmb250LXNpemU6IDAuODVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+U2VsZWN0IENvbnRhaW5lcjo8L2xhYmVsPlxuICAgICAgICA8c2VsZWN0IGlkPVwic25hcHNob3QtY29udGFpbmVyLXNlbGVjdFwiIHN0eWxlPVwid2lkdGg6IDEwMCU7IHBhZGRpbmc6IDhweCAxMnB4OyBtYXJnaW4tdG9wOiA0cHg7IGJhY2tncm91bmQ6IHZhcigtLWJnKTsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgYm9yZGVyLXJhZGl1czogNnB4OyBjb2xvcjogdmFyKC0tZmcpOyBmb250LXNpemU6IDAuOXJlbTtcIj5cbiAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+LS0gU2VsZWN0IGEgY29udGFpbmVyIC0tPC9vcHRpb24+XG4gICAgICAgIDwvc2VsZWN0PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgaWQ9XCJzbmFwc2hvdC1kZXRhaWxzXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lOyBtYXJnaW4tYm90dG9tOiAxNnB4OyBwYWRkaW5nOiAxMnB4OyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBib3JkZXItcmFkaXVzOiA4cHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtaG92ZXIpO1wiPlxuICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZ3JpZDsgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiAxZnIgMWZyOyBnYXA6IDhweDsgZm9udC1zaXplOiAwLjg1cmVtO1wiPlxuICAgICAgICAgIDxkaXY+PHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPkltYWdlOjwvc3Bhbj4gPHNwYW4gaWQ9XCJzbmFwc2hvdC1pbWFnZVwiPjwvc3Bhbj48L2Rpdj5cbiAgICAgICAgICA8ZGl2PjxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTtcIj5TdGF0dXM6PC9zcGFuPiA8c3BhbiBpZD1cInNuYXBzaG90LXN0YXR1c1wiPjwvc3Bhbj48L2Rpdj5cbiAgICAgICAgICA8ZGl2PjxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTtcIj5DcmVhdGVkOjwvc3Bhbj4gPHNwYW4gaWQ9XCJzbmFwc2hvdC1jcmVhdGVkXCI+PC9zcGFuPjwvZGl2PlxuICAgICAgICAgIDxkaXY+PHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPkNvbnRhaW5lciBJRDo8L3NwYW4+IDxzcGFuIGlkPVwic25hcHNob3QtaWRcIiBzdHlsZT1cImZvbnQtZmFtaWx5OiBtb25vc3BhY2U7XCI+PC9zcGFuPjwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGNsYXNzPVwicGFuZWwtdGFic1wiIHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMTJweDtcIj5cbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInBhbmVsLXRhYiBhY3RpdmVcIiBkYXRhLXBhbmVsPVwic25hcHNob3QtY3JlYXRlXCI+Q3JlYXRlIFNuYXBzaG90PC9idXR0b24+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJwYW5lbC10YWJcIiBkYXRhLXBhbmVsPVwic25hcHNob3QtbGlzdFwiPk1hbmFnZSBTbmFwc2hvdHM8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGlkPVwic25hcHNob3QtY3JlYXRlXCIgY2xhc3M9XCJwYW5lbC1zZWN0aW9uIGFjdGl2ZVwiPlxuICAgICAgICA8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMTJweDtcIj5cbiAgICAgICAgICA8bGFiZWwgc3R5bGU9XCJmb250LXNpemU6IDAuODVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+U25hcHNob3QgTmFtZTo8L2xhYmVsPlxuICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGlkPVwic25hcHNob3QtbmFtZVwiIHBsYWNlaG9sZGVyPVwiZS5nLiwgYmVmb3JlLXVwZGF0ZS0yMDI0XCIgXG4gICAgICAgICAgICBzdHlsZT1cIndpZHRoOiAxMDAlOyBwYWRkaW5nOiA4cHggMTJweDsgbWFyZ2luLXRvcDogNHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1iZyk7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJvcmRlci1yYWRpdXM6IDZweDsgY29sb3I6IHZhcigtLWZnKTsgZm9udC1zaXplOiAwLjlyZW07IGJveC1zaXppbmc6IGJvcmRlci1ib3g7XCIgLz5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiAxMnB4O1wiPlxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNoZWNrYm94LWxhYmVsXCIgc3R5bGU9XCJmb250LXNpemU6IDAuODVyZW07XCI+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgaWQ9XCJzbmFwc2hvdC1sZWF2ZS1ydW5uaW5nXCIgY2hlY2tlZCAvPlxuICAgICAgICAgICAgTGVhdmUgY29udGFpbmVyIHJ1bm5pbmcgYWZ0ZXIgY2hlY2twb2ludCAocmVzdW1lIHdpdGhvdXQgcmVzdGFydClcbiAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGJ1dHRvbiBpZD1cInNuYXBzaG90LWNyZWF0ZS1idG5cIiBjbGFzcz1cImJ0bi1hY2NlbnQtc29saWRcIiBzdHlsZT1cIndpZHRoOiAxMDAlO1wiPlx1RDgzRFx1RENCRSBDcmVhdGUgU25hcHNob3Q8L2J1dHRvbj5cbiAgICAgICAgPGRpdiBpZD1cInNuYXBzaG90LWNyZWF0ZS1zdGF0dXNcIiBzdHlsZT1cIm1hcmdpbi10b3A6IDEycHg7IHRleHQtYWxpZ246IGNlbnRlcjsgZm9udC1zaXplOiAwLjg1cmVtO1wiPjwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgaWQ9XCJzbmFwc2hvdC1saXN0XCIgY2xhc3M9XCJwYW5lbC1zZWN0aW9uXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lO1wiPlxuICAgICAgICA8ZGl2IGlkPVwic25hcHNob3QtbGlzdC1jb250YWluZXJcIiBjbGFzcz1cInNjcm9sbC1jb250YWluZXJcIiBzdHlsZT1cIm1heC1oZWlnaHQ6IDMwMHB4O1wiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPjxzcGFuIGNsYXNzPVwiZW1wdHktaWNvblwiPlx1RDgzRFx1RENCRTwvc3Bhbj5TZWxlY3QgYSBjb250YWluZXIgdG8gdmlldyBpdHMgc25hcHNob3RzPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsLWJ1dHRvbnMgbW9kYWwtZm9vdGVyLWJhclwiPlxuICAgICAgICA8YnV0dG9uIGlkPVwic25hcHNob3QtY2xvc2VcIj5DbG9zZTwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PmApO1xuXG4gIGNvbnN0IG1vZGFsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NuYXBzaG90LW1vZGFsJyk7XG4gIGNvbnN0IG9wZW5CdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc25hcHNob3QtYnRuJyk7XG4gIGNvbnN0IGNsb3NlQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NuYXBzaG90LWNsb3NlJyk7XG4gIGNvbnN0IGNvbnRhaW5lclNlbGVjdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbmFwc2hvdC1jb250YWluZXItc2VsZWN0Jyk7XG4gIGNvbnN0IGRldGFpbHNEaXYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc25hcHNob3QtZGV0YWlscycpO1xuICBjb25zdCBjcmVhdGVCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc25hcHNob3QtY3JlYXRlLWJ0bicpO1xuICBjb25zdCBjcmVhdGVTdGF0dXMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc25hcHNob3QtY3JlYXRlLXN0YXR1cycpO1xuXG4gIGxldCBjdXJyZW50Q29udGFpbmVySWQgPSBudWxsO1xuXG4gIGFzeW5jIGZ1bmN0aW9uIGxvYWRDb250YWluZXJzKCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS9jb250YWluZXJzJyk7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzLmpzb24oKTtcbiAgICAgIGlmICghZGF0YS5zdWNjZXNzIHx8ICFkYXRhLmNvbnRhaW5lcnMpIHJldHVybjtcbiAgICAgIFxuICAgICAgY29udGFpbmVyU2VsZWN0LmlubmVySFRNTCA9ICc8b3B0aW9uIHZhbHVlPVwiXCI+LS0gU2VsZWN0IGEgY29udGFpbmVyIC0tPC9vcHRpb24+JztcbiAgICAgIGZvciAoY29uc3QgYyBvZiBkYXRhLmNvbnRhaW5lcnMpIHtcbiAgICAgICAgY29uc3Qgb3B0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnb3B0aW9uJyk7XG4gICAgICAgIG9wdC52YWx1ZSA9IGMuaWQ7XG4gICAgICAgIG9wdC50ZXh0Q29udGVudCA9IGAke2MubmFtZSB8fCBjLmlkfSAoJHtjLmltYWdlIHx8ICd1bmtub3duJ30pYDtcbiAgICAgICAgb3B0LmRhdGFzZXQubmFtZSA9IGMubmFtZTtcbiAgICAgICAgb3B0LmRhdGFzZXQuaW1hZ2UgPSBjLmltYWdlO1xuICAgICAgICBvcHQuZGF0YXNldC5zdGF0dXMgPSBjLnN0YXR1cztcbiAgICAgICAgb3B0LmRhdGFzZXQuY3JlYXRlZCA9IGMuY3JlYXRlZDtcbiAgICAgICAgY29udGFpbmVyU2VsZWN0LmFwcGVuZENoaWxkKG9wdCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIGxvYWQgY29udGFpbmVyczonLCBlKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBzaG93Q29udGFpbmVyRGV0YWlscyhvcHQpIHtcbiAgICBpZiAoIW9wdCB8fCAhb3B0LnZhbHVlKSB7XG4gICAgICBkZXRhaWxzRGl2LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICBjdXJyZW50Q29udGFpbmVySWQgPSBudWxsO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjdXJyZW50Q29udGFpbmVySWQgPSBvcHQudmFsdWU7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NuYXBzaG90LWltYWdlJykudGV4dENvbnRlbnQgPSBvcHQuZGF0YXNldC5pbWFnZSB8fCAnLSc7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NuYXBzaG90LXN0YXR1cycpLnRleHRDb250ZW50ID0gb3B0LmRhdGFzZXQuc3RhdHVzIHx8ICctJztcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc25hcHNob3QtY3JlYXRlZCcpLnRleHRDb250ZW50ID0gb3B0LmRhdGFzZXQuY3JlYXRlZCA/IG5ldyBEYXRlKG9wdC5kYXRhc2V0LmNyZWF0ZWQgKiAxMDAwKS50b0xvY2FsZVN0cmluZygpIDogJy0nO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbmFwc2hvdC1pZCcpLnRleHRDb250ZW50ID0gb3B0LnZhbHVlLnN1YnN0cmluZygwLCAxMik7XG4gICAgZGV0YWlsc0Rpdi5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBjcmVhdGVTbmFwc2hvdCgpIHtcbiAgICBpZiAoIWN1cnJlbnRDb250YWluZXJJZCkge1xuICAgICAgY3JlYXRlU3RhdHVzLnRleHRDb250ZW50ID0gJ1BsZWFzZSBzZWxlY3QgYSBjb250YWluZXIgZmlyc3QnO1xuICAgICAgY3JlYXRlU3RhdHVzLnN0eWxlLmNvbG9yID0gJ3ZhcigtLWJhZC1mZyknO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBuYW1lID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NuYXBzaG90LW5hbWUnKS52YWx1ZS50cmltKCk7XG4gICAgaWYgKCFuYW1lKSB7XG4gICAgICBjcmVhdGVTdGF0dXMudGV4dENvbnRlbnQgPSAnUGxlYXNlIGVudGVyIGEgc25hcHNob3QgbmFtZSc7XG4gICAgICBjcmVhdGVTdGF0dXMuc3R5bGUuY29sb3IgPSAndmFyKC0tYmFkLWZnKSc7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGxlYXZlUnVubmluZyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbmFwc2hvdC1sZWF2ZS1ydW5uaW5nJykuY2hlY2tlZDtcbiAgICBcbiAgICBjcmVhdGVCdG4uZGlzYWJsZWQgPSB0cnVlO1xuICAgIGNyZWF0ZUJ0bi50ZXh0Q29udGVudCA9ICdDcmVhdGluZy4uLic7XG4gICAgY3JlYXRlU3RhdHVzLnRleHRDb250ZW50ID0gJyc7XG4gICAgXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKGAvYXBpL3YxL2NvbnRhaW5lcnMvJHtlbmNvZGVVUklDb21wb25lbnQoY3VycmVudENvbnRhaW5lcklkKX0vY2hlY2twb2ludGAsIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7IG5hbWUsIGxlYXZlUnVubmluZyB9KVxuICAgICAgfSk7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzLmpzb24oKTtcbiAgICAgIGlmIChkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgY3JlYXRlU3RhdHVzLnRleHRDb250ZW50ID0gYFx1MjcxMyBTbmFwc2hvdCBcIiR7bmFtZX1cIiBjcmVhdGVkIHN1Y2Nlc3NmdWxseWA7XG4gICAgICAgIGNyZWF0ZVN0YXR1cy5zdHlsZS5jb2xvciA9ICd2YXIoLS1vay1mZyknO1xuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc25hcHNob3QtbmFtZScpLnZhbHVlID0gJyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjcmVhdGVTdGF0dXMudGV4dENvbnRlbnQgPSBgXHUyNzE3IEZhaWxlZDogJHtkYXRhLmVycm9yIHx8ICdVbmtub3duIGVycm9yJ31gO1xuICAgICAgICBjcmVhdGVTdGF0dXMuc3R5bGUuY29sb3IgPSAndmFyKC0tYmFkLWZnKSc7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY3JlYXRlU3RhdHVzLnRleHRDb250ZW50ID0gYFx1MjcxNyBFcnJvcjogJHtlLm1lc3NhZ2V9YDtcbiAgICAgIGNyZWF0ZVN0YXR1cy5zdHlsZS5jb2xvciA9ICd2YXIoLS1iYWQtZmcpJztcbiAgICB9IGZpbmFsbHkge1xuICAgICAgY3JlYXRlQnRuLmRpc2FibGVkID0gZmFsc2U7XG4gICAgICBjcmVhdGVCdG4udGV4dENvbnRlbnQgPSAnXHVEODNEXHVEQ0JFIENyZWF0ZSBTbmFwc2hvdCc7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gb3Blbk1vZGFsKCkge1xuICAgIG1vZGFsLmNsYXNzTGlzdC5hZGQoJ3Nob3cnKTtcbiAgICBsb2FkQ29udGFpbmVycygpO1xuICB9XG5cbiAgZnVuY3Rpb24gY2xvc2VNb2RhbCgpIHtcbiAgICBtb2RhbC5jbGFzc0xpc3QucmVtb3ZlKCdzaG93Jyk7XG4gICAgZGV0YWlsc0Rpdi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIGN1cnJlbnRDb250YWluZXJJZCA9IG51bGw7XG4gICAgY29udGFpbmVyU2VsZWN0LnNlbGVjdGVkSW5kZXggPSAwO1xuICB9XG5cbiAgb3BlbkJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBvcGVuTW9kYWwpO1xuICBjbG9zZUJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBjbG9zZU1vZGFsKTtcbiAgd2lyZU1vZGFsKG1vZGFsLCBjbG9zZUJ0bik7XG4gIFxuICBjb250YWluZXJTZWxlY3Q/LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIChlKSA9PiB7XG4gICAgY29uc3Qgb3B0ID0gY29udGFpbmVyU2VsZWN0Lm9wdGlvbnNbY29udGFpbmVyU2VsZWN0LnNlbGVjdGVkSW5kZXhdO1xuICAgIHNob3dDb250YWluZXJEZXRhaWxzKG9wdCk7XG4gIH0pO1xuICBcbiAgY3JlYXRlQnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGNyZWF0ZVNuYXBzaG90KTtcbiAgXG4gIC8vIFRhYiBzd2l0Y2hpbmdcbiAgbW9kYWw/LnF1ZXJ5U2VsZWN0b3JBbGwoJy5wYW5lbC10YWInKS5mb3JFYWNoKHRhYiA9PiB7XG4gICAgdGFiLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgbW9kYWwucXVlcnlTZWxlY3RvckFsbCgnLnBhbmVsLXRhYicpLmZvckVhY2godCA9PiB0LmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpKTtcbiAgICAgIG1vZGFsLnF1ZXJ5U2VsZWN0b3JBbGwoJy5wYW5lbC1zZWN0aW9uJykuZm9yRWFjaChzID0+IHMuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJykpO1xuICAgICAgdGFiLmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZScpO1xuICAgICAgbW9kYWwucXVlcnlTZWxlY3RvcihgIyR7dGFiLmRhdGFzZXQucGFuZWx9YCkuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG4gICAgfSk7XG4gIH0pO1xufSkoKTtcbjtcbi8vID09PT09PT09PT0gU01BUlQgQVJSIENPTk5FQ1QgPT09PT09PT09PVxuKGZ1bmN0aW9uKCkge1xuICBpbmplY3RNb2RhbCgnYXJyLXNldHVwLW1vZGFsJywgYDxkaXYgaWQ9XCJhcnItc2V0dXAtbW9kYWxcIiBjbGFzcz1cIndlYXRoZXItbW9kYWxcIj5cbiAgICA8ZGl2IGNsYXNzPVwid2VhdGhlci1tb2RhbC1jb250ZW50XCIgc3R5bGU9XCJtaW4td2lkdGg6IDYwMHB4OyBtYXgtd2lkdGg6IDcyMHB4O1wiPlxuICAgICAgPGgzPlx1RDgzQ1x1REZBQyBTbWFydCBBcnIgQ29ubmVjdDwvaDM+XG4gICAgICA8cCBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbjogMCAwIDE2cHg7IGZvbnQtc2l6ZTogMC45cmVtO1wiPlxuICAgICAgICBBdXRvLWRpc2NvdmVyIGFuZCBjb25uZWN0IHlvdXIgZW50aXJlIG1lZGlhIHN0YWNrLlxuICAgICAgPC9wPlxuXG4gICAgICA8IS0tIFBoYXNlIDE6IERldGVjdGlvbiAtLT5cbiAgICAgIDxkaXYgaWQ9XCJzbWFydC1waGFzZS1kZXRlY3RcIj5cbiAgICAgICAgPGRpdiBzdHlsZT1cInRleHQtYWxpZ246IGNlbnRlcjsgcGFkZGluZzogMjBweDtcIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImJyYW5kLXNwaW5uZXJcIiBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDEycHg7IGRpc3BsYXk6IGlubGluZS1ibG9jaztcIj48L3NwYW4+XG4gICAgICAgICAgPGRpdiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7IGZvbnQtc2l6ZTogMC45cmVtO1wiPlNjYW5uaW5nIGZvciBzZXJ2aWNlcy4uLjwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBpZD1cInNtYXJ0LWRldGVjdC1yZXN1bHRzXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lO1wiPjwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gUGhhc2UgMjogQ3JlZGVudGlhbCBJbnB1dCAob25seSBmb3Igc2VydmljZXMgbmVlZGluZyBrZXlzKSAtLT5cbiAgICAgIDxkaXYgaWQ9XCJzbWFydC1waGFzZS1jcmVkZW50aWFsc1wiIHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIj5cbiAgICAgICAgPGg0IGNsYXNzPVwiaGVhZGluZy1hY2NlbnQtc2VjdGlvblwiPkVudGVyIE1pc3NpbmcgQVBJIEtleXM8L2g0PlxuICAgICAgICA8ZGl2IGlkPVwic21hcnQtY3JlZGVudGlhbC1pbnB1dHNcIj48L2Rpdj5cblxuICAgICAgICA8IS0tIENvbm5lY3Rpb24gT3B0aW9ucyAtLT5cbiAgICAgICAgPGRpdiBzdHlsZT1cIm1hcmdpbi10b3A6IDE2cHg7IHBhZGRpbmc6IDEycHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmFzZSk7IGJvcmRlci1yYWRpdXM6IDhweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcIj5cbiAgICAgICAgICA8aDQgc3R5bGU9XCJtYXJnaW46IDAgMCAxMHB4OyBmb250LXNpemU6IDAuODVyZW07IGNvbG9yOiB2YXIoLS1hY2NlbnQpO1wiPkNvbm5lY3Rpb24gT3B0aW9uczwvaDQ+XG4gICAgICAgICAgPGxhYmVsIGNsYXNzPVwib3B0aW9uLWxhYmVsXCI+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgaWQ9XCJzbWFydC1vcHQtc2VlcnJcIiBjaGVja2VkIGNsYXNzPVwiY2hlY2tib3gtc21cIiAvPlxuICAgICAgICAgICAgQ29uZmlndXJlIFNlZXJyIHdpdGggUmFkYXJyICsgU29uYXJyXG4gICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJvcHRpb24tbGFiZWxcIj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBpZD1cInNtYXJ0LW9wdC1wbGV4XCIgY2hlY2tlZCBjbGFzcz1cImNoZWNrYm94LXNtXCIgLz5cbiAgICAgICAgICAgIENvbm5lY3QgUGxleCB0byBTZWVyclxuICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgPGxhYmVsIGNsYXNzPVwib3B0aW9uLWxhYmVsXCI+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgaWQ9XCJzbWFydC1vcHQtcHJvd2xhcnJcIiBjaGVja2VkIGNsYXNzPVwiY2hlY2tib3gtc21cIiAvPlxuICAgICAgICAgICAgQ29ubmVjdCBQcm93bGFyciB0byBSYWRhcnIgKyBTb25hcnJcbiAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgIDxsYWJlbCBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogOHB4OyBjdXJzb3I6IHBvaW50ZXI7IGZvbnQtc2l6ZTogMC44NXJlbTtcIj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBpZD1cInNtYXJ0LW9wdC1zYXZlXCIgY2hlY2tlZCBjbGFzcz1cImNoZWNrYm94LXNtXCIgLz5cbiAgICAgICAgICAgIFNhdmUgQVBJIGtleXMgZm9yIG9uZS1jbGljayByZWNvbm5lY3RcbiAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8YnV0dG9uIGlkPVwic21hcnQtY29ubmVjdC1idG5cIiBzdHlsZT1cIndpZHRoOiAxMDAlOyBtYXJnaW4tdG9wOiAxNnB4OyBwYWRkaW5nOiAxMnB4OyBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTM1ZGVnLCAjZTc0YzNjIDAlLCAjOWI1OWI2IDEwMCUpOyBib3JkZXI6IG5vbmU7IGNvbG9yOiB3aGl0ZTsgZm9udC13ZWlnaHQ6IDYwMDsgZm9udC1zaXplOiAxcmVtOyBib3JkZXItcmFkaXVzOiA4cHg7IGN1cnNvcjogcG9pbnRlcjtcIj5cbiAgICAgICAgICBTbWFydCBDb25uZWN0XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gUGhhc2UgMzogQ29ubmVjdGlvbiBQcm9ncmVzcyAtLT5cbiAgICAgIDxkaXYgaWQ9XCJzbWFydC1waGFzZS1wcm9ncmVzc1wiIHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIj5cbiAgICAgICAgPGg0IGNsYXNzPVwiaGVhZGluZy1hY2NlbnQtc2VjdGlvblwiPkNvbm5lY3RpbmcgRXZlcnl0aGluZy4uLjwvaDQ+XG4gICAgICAgIDxkaXYgaWQ9XCJzbWFydC1wcm9ncmVzcy1zdGVwc1wiIHN0eWxlPVwiZGlzcGxheTogZmxleDsgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsgZ2FwOiA2cHg7XCI+PC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBQaGFzZSA0OiBSZXN1bHRzIC0tPlxuICAgICAgPGRpdiBpZD1cInNtYXJ0LXBoYXNlLXJlc3VsdHNcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCI+XG4gICAgICAgIDxkaXYgaWQ9XCJzbWFydC1yZXN1bHRzLWNvbnRlbnRcIj48L2Rpdj5cbiAgICAgICAgPGRpdiBpZD1cInNtYXJ0LXBsZXgtbGlicmFyaWVzXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lOyBtYXJnaW4tdG9wOiAxMnB4O1wiPjwvZGl2PlxuICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgZ2FwOiA4cHg7IG1hcmdpbi10b3A6IDE2cHg7XCI+XG4gICAgICAgICAgPGJ1dHRvbiBpZD1cInNtYXJ0LXJldHJ5LWJ0blwiIHN0eWxlPVwiZGlzcGxheTogbm9uZTsgZmxleDogMTsgcGFkZGluZzogMTBweDsgYmFja2dyb3VuZDogI2YzOWMxMjsgYm9yZGVyOiBub25lOyBjb2xvcjogd2hpdGU7IGZvbnQtd2VpZ2h0OiA1MDA7IGJvcmRlci1yYWRpdXM6IDhweDsgY3Vyc29yOiBwb2ludGVyO1wiPlxuICAgICAgICAgICAgUmV0cnkgRmFpbGVkIFN0ZXBzXG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPGEgaWQ9XCJzbWFydC1vcGVuLXNlZXJyXCIgaHJlZj1cIiNcIiB0YXJnZXQ9XCJfYmxhbmtcIiByZWw9XCJub29wZW5lciBub3JlZmVycmVyXCJcbiAgICAgICAgICAgICBzdHlsZT1cImZsZXg6IDE7IHBhZGRpbmc6IDEwcHg7IGJhY2tncm91bmQ6IHZhcigtLWFjY2VudCk7IGNvbG9yOiB3aGl0ZTsgYm9yZGVyOiBub25lOyBib3JkZXItcmFkaXVzOiA4cHg7IGN1cnNvcjogcG9pbnRlcjsgZm9udC13ZWlnaHQ6IDUwMDsgdGV4dC1kZWNvcmF0aW9uOiBub25lOyB0ZXh0LWFsaWduOiBjZW50ZXI7XCI+XG4gICAgICAgICAgICBPcGVuIFNlZXJyXG4gICAgICAgICAgPC9hPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIEhlbHAgVGV4dCAtLT5cbiAgICAgIDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuNzVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi10b3A6IDEycHg7IHBhZGRpbmc6IDEwcHg7IGJhY2tncm91bmQ6IGNvbG9yLW1peChpbiBzcmdiLCB2YXIoLS1hY2NlbnQpIDUlLCB0cmFuc3BhcmVudCk7IGJvcmRlci1yYWRpdXM6IDZweDtcIj5cbiAgICAgICAgPHN0cm9uZz5XaGVyZSB0byBmaW5kIEFQSSBrZXlzOjwvc3Ryb25nPjxicj5cbiAgICAgICAgUmFkYXJyL1NvbmFyci9Qcm93bGFycjogU2V0dGluZ3MgLT4gR2VuZXJhbCAtPiBTZWN1cml0eSAtPiBBUEkgS2V5XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBDbG9zZSBCdXR0b24gLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwid2VhdGhlci1tb2RhbC1idXR0b25zIG1vZGFsLWZvb3Rlci1iYXJcIj5cbiAgICAgICAgPGJ1dHRvbiBpZD1cImFyci1zZXR1cC1jYW5jZWxcIj5DbG9zZTwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PmApO1xuXG4gIGNvbnN0IG1vZGFsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Fyci1zZXR1cC1tb2RhbCcpO1xuICBjb25zdCBvcGVuQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Fyci1zZXR1cC1idG4nKTtcbiAgY29uc3QgY2FuY2VsQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Fyci1zZXR1cC1jYW5jZWwnKTtcbiAgY29uc3QgY29ubmVjdEJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbWFydC1jb25uZWN0LWJ0bicpO1xuXG4gIC8vIFBoYXNlIGVsZW1lbnRzXG4gIGNvbnN0IHBoYXNlRGV0ZWN0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NtYXJ0LXBoYXNlLWRldGVjdCcpO1xuICBjb25zdCBwaGFzZUNyZWRlbnRpYWxzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NtYXJ0LXBoYXNlLWNyZWRlbnRpYWxzJyk7XG4gIGNvbnN0IHBoYXNlUHJvZ3Jlc3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc21hcnQtcGhhc2UtcHJvZ3Jlc3MnKTtcbiAgY29uc3QgcGhhc2VSZXN1bHRzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NtYXJ0LXBoYXNlLXJlc3VsdHMnKTtcblxuICBjb25zdCBkZXRlY3RSZXN1bHRzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NtYXJ0LWRldGVjdC1yZXN1bHRzJyk7XG4gIGNvbnN0IGNyZWRlbnRpYWxJbnB1dHMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc21hcnQtY3JlZGVudGlhbC1pbnB1dHMnKTtcbiAgY29uc3QgcHJvZ3Jlc3NTdGVwcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbWFydC1wcm9ncmVzcy1zdGVwcycpO1xuICBjb25zdCByZXN1bHRzQ29udGVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbWFydC1yZXN1bHRzLWNvbnRlbnQnKTtcbiAgY29uc3QgcGxleExpYnJhcmllcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbWFydC1wbGV4LWxpYnJhcmllcycpO1xuICBjb25zdCByZXRyeUJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbWFydC1yZXRyeS1idG4nKTtcblxuICBsZXQgZGV0ZWN0ZWREYXRhID0gbnVsbDsgLy8gU3RvcmUgZGV0ZWN0aW9uIHJlc3VsdHMgZm9yIHNtYXJ0LWNvbm5lY3RcblxuICBjb25zdCBzZXJ2aWNlSWNvbnMgPSB7IHBsZXg6ICdcdUQ4M0NcdURGQUMnLCByYWRhcnI6ICdcdUQ4M0NcdURGQUMnLCBzb25hcnI6ICdcdUQ4M0RcdURDRkEnLCBwcm93bGFycjogJ1x1RDgzRFx1REQwRCcsIHNlZXJyOiAnXHVEODNEXHVEQ0NCJyB9O1xuICBjb25zdCBzZXJ2aWNlTGFiZWxzID0geyBwbGV4OiAnUGxleCcsIHJhZGFycjogJ1JhZGFyciAoTW92aWVzKScsIHNvbmFycjogJ1NvbmFyciAoVFYpJywgcHJvd2xhcnI6ICdQcm93bGFyciAoSW5kZXhlcnMpJywgc2VlcnI6ICdTZWVycicgfTtcblxuICBmdW5jdGlvbiBzaG93UGhhc2UocGhhc2UpIHtcbiAgICBwaGFzZURldGVjdC5zdHlsZS5kaXNwbGF5ID0gcGhhc2UgPT09ICdkZXRlY3QnID8gJ2Jsb2NrJyA6ICdub25lJztcbiAgICBwaGFzZUNyZWRlbnRpYWxzLnN0eWxlLmRpc3BsYXkgPSBwaGFzZSA9PT0gJ2NyZWRlbnRpYWxzJyA/ICdibG9jaycgOiAnbm9uZSc7XG4gICAgcGhhc2VQcm9ncmVzcy5zdHlsZS5kaXNwbGF5ID0gcGhhc2UgPT09ICdwcm9ncmVzcycgPyAnYmxvY2snIDogJ25vbmUnO1xuICAgIHBoYXNlUmVzdWx0cy5zdHlsZS5kaXNwbGF5ID0gcGhhc2UgPT09ICdyZXN1bHRzJyA/ICdibG9jaycgOiAnbm9uZSc7XG4gIH1cblxuICBmdW5jdGlvbiBzdGF0dXNCYWRnZShzdGF0dXMpIHtcbiAgICBjb25zdCBjb2xvcnMgPSB7XG4gICAgICBjb25uZWN0ZWQ6IHsgYmc6ICd2YXIoLS1vay1mZyknLCBpY29uOiAnJiMxMDAwMzsnLCB0ZXh0OiAnQ29ubmVjdGVkJyB9LFxuICAgICAgbmVlZHNfa2V5OiB7IGJnOiAnI2YzOWMxMicsIGljb246ICcmIzEyODI3MzsnLCB0ZXh0OiAnTmVlZHMgQVBJIEtleScgfSxcbiAgICAgIG5vdF9mb3VuZDogeyBiZzogJ3ZhcigtLW11dGVkKScsIGljb246ICcmbWRhc2g7JywgdGV4dDogJ05vdCBGb3VuZCcgfSxcbiAgICAgIGVycm9yOiB7IGJnOiAndmFyKC0tYmFkLWZnKScsIGljb246ICcmIzEwMDA3OycsIHRleHQ6ICdFcnJvcicgfVxuICAgIH07XG4gICAgY29uc3QgYyA9IGNvbG9yc1tzdGF0dXNdIHx8IGNvbG9ycy5ub3RfZm91bmQ7XG4gICAgcmV0dXJuIGA8c3BhbiBzdHlsZT1cImRpc3BsYXk6IGlubGluZS1mbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDRweDsgcGFkZGluZzogMnB4IDhweDsgYm9yZGVyLXJhZGl1czogNHB4OyBmb250LXNpemU6IDAuNzVyZW07IGJhY2tncm91bmQ6IGNvbG9yLW1peChpbiBzcmdiLCAke2MuYmd9IDIwJSwgdHJhbnNwYXJlbnQpOyBjb2xvcjogJHtjLmJnfTtcIj4ke2MuaWNvbn0gJHtjLnRleHR9PC9zcGFuPmA7XG4gIH1cblxuICAvLyBQaGFzZSAxOiBTbWFydCBEZXRlY3Rpb25cbiAgYXN5bmMgZnVuY3Rpb24gc21hcnREZXRlY3QoKSB7XG4gICAgc2hvd1BoYXNlKCdkZXRlY3QnKTtcbiAgICBkZXRlY3RSZXN1bHRzLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS9hcnIvc21hcnQtZGV0ZWN0Jyk7XG4gICAgICBkZXRlY3RlZERhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG5cbiAgICAgIGlmICghZGV0ZWN0ZWREYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgZGV0ZWN0UmVzdWx0cy5pbm5lckhUTUwgPSBgPGRpdiBzdHlsZT1cInBhZGRpbmc6IDEycHg7IGNvbG9yOiB2YXIoLS1iYWQtZmcpO1wiPkRldGVjdGlvbiBmYWlsZWQ6ICR7ZXNjYXBlSHRtbChkZXRlY3RlZERhdGEuZXJyb3IpfTwvZGl2PmA7XG4gICAgICAgIGRldGVjdFJlc3VsdHMuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gUmVuZGVyIGRldGVjdGlvbiByZXN1bHRzXG4gICAgICBsZXQgaHRtbCA9ICc8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsgZ2FwOiA4cHg7XCI+JztcblxuICAgICAgZm9yIChjb25zdCBbc3ZjLCBpbmZvXSBvZiBPYmplY3QuZW50cmllcyhkZXRlY3RlZERhdGEuc2VydmljZXMpKSB7XG4gICAgICAgIGNvbnN0IGljb24gPSBzZXJ2aWNlSWNvbnNbc3ZjXSB8fCAnXHVEODNEXHVEQ0U2JztcbiAgICAgICAgY29uc3QgbGFiZWwgPSBzZXJ2aWNlTGFiZWxzW3N2Y10gfHwgc3ZjO1xuICAgICAgICBjb25zdCBzb3VyY2UgPSBpbmZvLnNvdXJjZSA/IGA8c3BhbiBzdHlsZT1cImZvbnQtc2l6ZTogMC43cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBwYWRkaW5nOiAxcHggNnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJnKTsgYm9yZGVyLXJhZGl1czogM3B4O1wiPiR7ZXNjYXBlSHRtbChpbmZvLnNvdXJjZSl9PC9zcGFuPmAgOiAnJztcbiAgICAgICAgY29uc3QgdmVyc2lvbiA9IGluZm8udmVyc2lvbiA/IGA8c3BhbiBzdHlsZT1cImZvbnQtc2l6ZTogMC43cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPnYke2VzY2FwZUh0bWwoaW5mby52ZXJzaW9uKX08L3NwYW4+YCA6ICcnO1xuICAgICAgICBjb25zdCBrZXlTYXZlZCA9IChpbmZvLmhhc0FwaUtleSB8fCBpbmZvLmhhc1Rva2VuKSAmJiBpbmZvLnN0YXR1cyA9PT0gJ2Nvbm5lY3RlZCdcbiAgICAgICAgICA/ICc8c3BhbiBzdHlsZT1cImZvbnQtc2l6ZTogMC43cmVtOyBjb2xvcjogdmFyKC0tb2stZmcpO1wiPktleSBzYXZlZDwvc3Bhbj4nIDogJyc7XG5cbiAgICAgICAgaHRtbCArPSBgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogMTBweDsgcGFkZGluZzogMTBweCAxMnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJhc2UpOyBib3JkZXItcmFkaXVzOiA4cHg7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XCI+XG4gICAgICAgICAgPHNwYW4gc3R5bGU9XCJmb250LXNpemU6IDEuMXJlbTtcIj4ke2ljb259PC9zcGFuPlxuICAgICAgICAgIDxkaXYgc3R5bGU9XCJmbGV4OiAxO1wiPlxuICAgICAgICAgICAgPGRpdiBzdHlsZT1cImZvbnQtd2VpZ2h0OiA1MDA7IGZvbnQtc2l6ZTogMC45cmVtO1wiPiR7bGFiZWx9PC9kaXY+XG4gICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgZ2FwOiA2cHg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGZsZXgtd3JhcDogd3JhcDtcIj5cbiAgICAgICAgICAgICAgJHtzb3VyY2V9ICR7dmVyc2lvbn0gJHtrZXlTYXZlZH1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICR7c3RhdHVzQmFkZ2UoaW5mby5zdGF0dXMpfVxuICAgICAgICA8L2Rpdj5gO1xuICAgICAgfVxuXG4gICAgICBodG1sICs9ICc8L2Rpdj4nO1xuXG4gICAgICAvLyBTdW1tYXJ5XG4gICAgICBjb25zdCBzID0gZGV0ZWN0ZWREYXRhLnN1bW1hcnk7XG4gICAgICBodG1sICs9IGA8ZGl2IHN0eWxlPVwibWFyZ2luLXRvcDogMTJweDsgcGFkZGluZzogMTBweDsgYmFja2dyb3VuZDogY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLWFjY2VudCkgOCUsIHRyYW5zcGFyZW50KTsgYm9yZGVyLXJhZGl1czogOHB4OyBmb250LXNpemU6IDAuODVyZW07XCI+XG4gICAgICAgICR7ZXNjYXBlSHRtbChTdHJpbmcocy5mdWxseUNvbm5lY3RlZCkpfS8ke2VzY2FwZUh0bWwoU3RyaW5nKHMudG90YWxEZXRlY3RlZCArICg1IC0gcy50b3RhbERldGVjdGVkKSkpfSBzZXJ2aWNlcyBkZXRlY3RlZCAmbWlkZG90O1xuICAgICAgICAke2VzY2FwZUh0bWwoU3RyaW5nKHMuZnVsbHlDb25uZWN0ZWQpKX0gY29ubmVjdGVkJHtzLm5lZWRzQXBpS2V5ID4gMCA/IGAgJm1pZGRvdDsgPHN0cm9uZz4ke2VzY2FwZUh0bWwoU3RyaW5nKHMubmVlZHNBcGlLZXkpKX0gbmVlZHMgQVBJIGtleTwvc3Ryb25nPmAgOiAnJ31cbiAgICAgIDwvZGl2PmA7XG5cbiAgICAgIGRldGVjdFJlc3VsdHMuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgIGRldGVjdFJlc3VsdHMuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG5cbiAgICAgIC8vIEJ1aWxkIGNyZWRlbnRpYWwgaW5wdXRzIGZvciBzZXJ2aWNlcyB0aGF0IG5lZWQga2V5c1xuICAgICAgYnVpbGRDcmVkZW50aWFsSW5wdXRzKGRldGVjdGVkRGF0YSk7XG5cbiAgICAgIC8vIEF1dG8tYWR2YW5jZSBhZnRlciBhIHNob3J0IGRlbGF5XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgc2hvd1BoYXNlKCdjcmVkZW50aWFscycpO1xuICAgICAgfSwgODAwKTtcblxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGRldGVjdFJlc3VsdHMuaW5uZXJIVE1MID0gYDxkaXYgc3R5bGU9XCJwYWRkaW5nOiAxMnB4OyBjb2xvcjogdmFyKC0tYmFkLWZnKTtcIj5FcnJvcjogJHtlc2NhcGVIdG1sKGUubWVzc2FnZSl9PC9kaXY+YDtcbiAgICAgIGRldGVjdFJlc3VsdHMuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgfVxuICB9XG5cbiAgLy8gQnVpbGQgY3JlZGVudGlhbCBpbnB1dCBmaWVsZHNcbiAgZnVuY3Rpb24gYnVpbGRDcmVkZW50aWFsSW5wdXRzKGRhdGEpIHtcbiAgICBsZXQgaHRtbCA9ICcnO1xuICAgIGNvbnN0IHNlcnZpY2VzID0gZGF0YS5zZXJ2aWNlcztcbiAgICBjb25zdCBhcnJTZXJ2aWNlcyA9IFsncmFkYXJyJywgJ3NvbmFycicsICdwcm93bGFyciddO1xuXG4gICAgZm9yIChjb25zdCBzdmMgb2YgYXJyU2VydmljZXMpIHtcbiAgICAgIGNvbnN0IGluZm8gPSBzZXJ2aWNlc1tzdmNdO1xuICAgICAgaWYgKCFpbmZvIHx8IGluZm8uc3RhdHVzID09PSAnbm90X2ZvdW5kJyAmJiAhaW5mby51cmwpIGNvbnRpbnVlO1xuXG4gICAgICBjb25zdCBpY29uID0gc2VydmljZUljb25zW3N2Y107XG4gICAgICBjb25zdCBsYWJlbCA9IHNlcnZpY2VMYWJlbHNbc3ZjXTtcbiAgICAgIGNvbnN0IGlzQ29ubmVjdGVkID0gaW5mby5zdGF0dXMgPT09ICdjb25uZWN0ZWQnO1xuICAgICAgY29uc3QgYm9yZGVyQ29sb3IgPSBpc0Nvbm5lY3RlZCA/ICd2YXIoLS1vay1mZyknIDogJ3ZhcigtLWJvcmRlciknO1xuXG4gICAgICBodG1sICs9IGA8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMTBweDsgcGFkZGluZzogMTJweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iYXNlKTsgYm9yZGVyLXJhZGl1czogOHB4OyBib3JkZXI6IDFweCBzb2xpZCAke2JvcmRlckNvbG9yfTtcIj5cbiAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogOHB4OyBtYXJnaW4tYm90dG9tOiA4cHg7XCI+XG4gICAgICAgICAgPHNwYW4gc3R5bGU9XCJmb250LXNpemU6IDEuMXJlbTtcIj4ke2ljb259PC9zcGFuPlxuICAgICAgICAgIDxzcGFuIHN0eWxlPVwiZm9udC13ZWlnaHQ6IDUwMDtcIj4ke2xhYmVsfTwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBpZD1cInNtYXJ0LSR7c3ZjfS1zdGF0dXNcIiBzdHlsZT1cIm1hcmdpbi1sZWZ0OiBhdXRvOyBmb250LXNpemU6IDAuNzVyZW07XCI+XG4gICAgICAgICAgICAke2lzQ29ubmVjdGVkID8gJzxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLW9rLWZnKTtcIj4mIzEwMDAzOyBDb25uZWN0ZWQ8L3NwYW4+JyA6ICcnfVxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBncmlkOyBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IDJmciAxZnI7IGdhcDogOHB4O1wiPlxuICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICA8bGFiZWwgc3R5bGU9XCJmb250LXNpemU6IDAuNzVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+VVJMOjwvbGFiZWw+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBpZD1cInNtYXJ0LSR7c3ZjfS11cmxcIiB2YWx1ZT1cIiR7ZXNjYXBlSHRtbChpbmZvLnVybCB8fCAnJyl9XCIgcGxhY2Vob2xkZXI9XCJodHRwczovL3NlZWRib3guY29tLyR7c3ZjfS9cIlxuICAgICAgICAgICAgICAgICAgIHN0eWxlPVwid2lkdGg6IDEwMCU7IGZvbnQtc2l6ZTogMC44NXJlbTsgcGFkZGluZzogNnB4IDhweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iZyk7IGNvbG9yOiB2YXIoLS1mZyk7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJvcmRlci1yYWRpdXM6IDRweDtcIiAvPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICA8bGFiZWwgc3R5bGU9XCJmb250LXNpemU6IDAuNzVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+QVBJIEtleTo8L2xhYmVsPlxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJwYXNzd29yZFwiIGlkPVwic21hcnQtJHtzdmN9LWtleVwiIHBsYWNlaG9sZGVyPVwiJHtpc0Nvbm5lY3RlZCA/ICcoc2F2ZWQpJyA6ICdQYXN0ZSBBUEkga2V5J31cIlxuICAgICAgICAgICAgICAgICAgIHN0eWxlPVwid2lkdGg6IDEwMCU7IGZvbnQtc2l6ZTogMC44NXJlbTsgcGFkZGluZzogNnB4IDhweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iZyk7IGNvbG9yOiB2YXIoLS1mZyk7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJvcmRlci1yYWRpdXM6IDRweDtcIiAvPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGJ1dHRvbiBvbmNsaWNrPVwic21hcnRUZXN0Q29ubmVjdGlvbignJHtzdmN9JylcIiBzdHlsZT1cIm1hcmdpbi10b3A6IDhweDsgcGFkZGluZzogNHB4IDEycHg7IGZvbnQtc2l6ZTogMC43NXJlbTsgY3Vyc29yOiBwb2ludGVyO1wiPlRlc3Q8L2J1dHRvbj5cbiAgICAgIDwvZGl2PmA7XG4gICAgfVxuXG4gICAgLy8gUGxleCBzdGF0dXMgKG5vbi1lZGl0YWJsZSwganVzdCBzaG93cyBzdGF0dXMpXG4gICAgY29uc3QgcGxleCA9IHNlcnZpY2VzLnBsZXg7XG4gICAgaWYgKHBsZXgpIHtcbiAgICAgIGNvbnN0IHBsZXhDb25uZWN0ZWQgPSBwbGV4LnN0YXR1cyA9PT0gJ2Nvbm5lY3RlZCc7XG4gICAgICBodG1sICs9IGA8ZGl2IHN0eWxlPVwicGFkZGluZzogMTBweCAxMnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJhc2UpOyBib3JkZXItcmFkaXVzOiA4cHg7IGJvcmRlcjogMXB4IHNvbGlkICR7cGxleENvbm5lY3RlZCA/ICd2YXIoLS1vay1mZyknIDogJ3ZhcigtLWJvcmRlciknfTsgbWFyZ2luLWJvdHRvbTogMTBweDtcIj5cbiAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogOHB4O1wiPlxuICAgICAgICAgIDxzcGFuIHN0eWxlPVwiZm9udC1zaXplOiAxLjFyZW07XCI+XHVEODNDXHVERkFDPC9zcGFuPlxuICAgICAgICAgIDxzcGFuIHN0eWxlPVwiZm9udC13ZWlnaHQ6IDUwMDtcIj5QbGV4PC9zcGFuPlxuICAgICAgICAgICR7c3RhdHVzQmFkZ2UocGxleC5zdGF0dXMpfVxuICAgICAgICAgIDxzcGFuIHN0eWxlPVwibWFyZ2luLWxlZnQ6IGF1dG87IGZvbnQtc2l6ZTogMC43NXJlbTsgY29sb3I6IHZhcigtLW11dGVkKTtcIj4ke2VzY2FwZUh0bWwocGxleC5zb3VyY2UgfHwgJycpfTwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5gO1xuICAgIH1cblxuICAgIC8vIFNlZXJyIHN0YXR1c1xuICAgIGNvbnN0IHNlZXJyID0gc2VydmljZXMuc2VlcnI7XG4gICAgaWYgKHNlZXJyKSB7XG4gICAgICBjb25zdCBzZWVyck9rID0gc2VlcnIuc3RhdHVzID09PSAnY29ubmVjdGVkJztcbiAgICAgIGxldCBjb25maWd1cmVkSHRtbCA9ICcnO1xuICAgICAgaWYgKHNlZXJyLmNvbmZpZ3VyZWRTZXJ2aWNlcykge1xuICAgICAgICBjb25zdCBjcyA9IHNlZXJyLmNvbmZpZ3VyZWRTZXJ2aWNlcztcbiAgICAgICAgY29uZmlndXJlZEh0bWwgPSBgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC43NXJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLXRvcDogNHB4O1wiPlxuICAgICAgICAgIENvbmZpZ3VyZWQ6ICR7Y3MucmFkYXJyID8gJyYjMTAwMDM7IFJhZGFycicgOiAnJiMxMDAwNzsgUmFkYXJyJ30gJm1pZGRvdDtcbiAgICAgICAgICAke2NzLnNvbmFyciA/ICcmIzEwMDAzOyBTb25hcnInIDogJyYjMTAwMDc7IFNvbmFycid9ICZtaWRkb3Q7XG4gICAgICAgICAgJHtjcy5wbGV4ID8gJyYjMTAwMDM7IFBsZXgnIDogJyYjMTAwMDc7IFBsZXgnfVxuICAgICAgICA8L2Rpdj5gO1xuICAgICAgfVxuICAgICAgaHRtbCArPSBgPGRpdiBzdHlsZT1cInBhZGRpbmc6IDEwcHggMTJweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iYXNlKTsgYm9yZGVyLXJhZGl1czogOHB4OyBib3JkZXI6IDFweCBzb2xpZCAke3NlZXJyT2sgPyAndmFyKC0tb2stZmcpJyA6ICd2YXIoLS1ib3JkZXIpJ307XCI+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDhweDtcIj5cbiAgICAgICAgICA8c3BhbiBzdHlsZT1cImZvbnQtc2l6ZTogMS4xcmVtO1wiPlx1RDgzRFx1RENDQjwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBzdHlsZT1cImZvbnQtd2VpZ2h0OiA1MDA7XCI+U2VlcnI8L3NwYW4+XG4gICAgICAgICAgJHtzdGF0dXNCYWRnZShzZWVyci5zdGF0dXMpfVxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgJHtjb25maWd1cmVkSHRtbH1cbiAgICAgIDwvZGl2PmA7XG4gICAgfVxuXG4gICAgY3JlZGVudGlhbElucHV0cy5pbm5lckhUTUwgPSBodG1sO1xuICB9XG5cbiAgLy8gVGVzdCBjb25uZWN0aW9uIChnbG9iYWwgZm9yIG9uY2xpY2spXG4gIHdpbmRvdy5zbWFydFRlc3RDb25uZWN0aW9uID0gYXN5bmMgZnVuY3Rpb24oc2VydmljZSkge1xuICAgIGNvbnN0IHVybElucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYHNtYXJ0LSR7c2VydmljZX0tdXJsYCk7XG4gICAgY29uc3Qga2V5SW5wdXQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChgc21hcnQtJHtzZXJ2aWNlfS1rZXlgKTtcbiAgICBjb25zdCBzdGF0dXNTcGFuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYHNtYXJ0LSR7c2VydmljZX0tc3RhdHVzYCk7XG5cbiAgICBjb25zdCB1cmwgPSB1cmxJbnB1dD8udmFsdWUudHJpbSgpO1xuICAgIGNvbnN0IGFwaUtleSA9IGtleUlucHV0Py52YWx1ZS50cmltKCk7XG5cbiAgICBpZiAoIXVybCB8fCAhYXBpS2V5KSB7XG4gICAgICBzdGF0dXNTcGFuLmlubmVySFRNTCA9ICc8c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1iYWQtZmcpO1wiPkVudGVyIFVSTCBhbmQgQVBJIGtleTwvc3Bhbj4nO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHN0YXR1c1NwYW4uaW5uZXJIVE1MID0gJzxzcGFuIGNsYXNzPVwiYnJhbmQtc3Bpbm5lclwiPjwvc3Bhbj4nO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgc2VjdXJlRmV0Y2goJy9hcGkvdjEvYXJyL3Rlc3QtY29ubmVjdGlvbicsIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7IHNlcnZpY2UsIHVybCwgYXBpS2V5IH0pXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICBpZiAoZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgIHN0YXR1c1NwYW4uaW5uZXJIVE1MID0gYDxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLW9rLWZnKTtcIj4mIzEwMDAzOyAke2VzY2FwZUh0bWwoZGF0YS5hcHBOYW1lIHx8ICdDb25uZWN0ZWQnKX0gdiR7ZXNjYXBlSHRtbChkYXRhLnZlcnNpb24gfHwgJycpfTwvc3Bhbj5gO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhdHVzU3Bhbi5pbm5lckhUTUwgPSBgPHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tYmFkLWZnKTtcIj4mIzEwMDA3OyAke2VzY2FwZUh0bWwoZGF0YS5lcnJvcil9PC9zcGFuPmA7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgc3RhdHVzU3Bhbi5pbm5lckhUTUwgPSBgPHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tYmFkLWZnKTtcIj4mIzEwMDA3OyAke2VzY2FwZUh0bWwoZS5tZXNzYWdlKX08L3NwYW4+YDtcbiAgICB9XG4gIH07XG5cbiAgLy8gUGhhc2UgMzogU21hcnQgQ29ubmVjdFxuICBhc3luYyBmdW5jdGlvbiBzbWFydENvbm5lY3QoKSB7XG4gICAgc2hvd1BoYXNlKCdwcm9ncmVzcycpO1xuICAgIHByb2dyZXNzU3RlcHMuaW5uZXJIVE1MID0gJzxkaXYgc3R5bGU9XCJ0ZXh0LWFsaWduOiBjZW50ZXI7IHBhZGRpbmc6IDIwcHg7XCI+PHNwYW4gY2xhc3M9XCJicmFuZC1zcGlubmVyXCI+PC9zcGFuPjxkaXYgc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW4tdG9wOiA4cHg7XCI+Q29ubmVjdGluZyBzZXJ2aWNlcy4uLjwvZGl2PjwvZGl2Pic7XG5cbiAgICAvLyBHYXRoZXIgaW5wdXRcbiAgICBjb25zdCBzZXJ2aWNlcyA9IHt9O1xuICAgIGZvciAoY29uc3Qgc3ZjIG9mIFsncmFkYXJyJywgJ3NvbmFycicsICdwcm93bGFyciddKSB7XG4gICAgICBjb25zdCB1cmwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChgc21hcnQtJHtzdmN9LXVybGApPy52YWx1ZS50cmltKCk7XG4gICAgICBjb25zdCBhcGlLZXkgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChgc21hcnQtJHtzdmN9LWtleWApPy52YWx1ZS50cmltKCk7XG4gICAgICBpZiAoYXBpS2V5ICYmIHVybCkge1xuICAgICAgICBzZXJ2aWNlc1tzdmNdID0geyBhcGlLZXksIHVybCB9O1xuICAgICAgfSBlbHNlIGlmIChhcGlLZXkpIHtcbiAgICAgICAgLy8gS2V5IHByb3ZpZGVkIHdpdGhvdXQgVVJMIC0gbGV0IGJhY2tlbmQgcmVzb2x2ZVxuICAgICAgICBzZXJ2aWNlc1tzdmNdID0geyBhcGlLZXkgfTtcbiAgICAgIH1cbiAgICAgIC8vIElmIG5vIGtleSBlbnRlcmVkIGJ1dCBzZXJ2aWNlIHdhcyBhbHJlYWR5IGNvbm5lY3RlZCwgYmFja2VuZCB1c2VzIHN0b3JlZCBjcmVkZW50aWFsc1xuICAgIH1cblxuICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICBzZXJ2aWNlczogT2JqZWN0LmtleXMoc2VydmljZXMpLmxlbmd0aCA+IDAgPyBzZXJ2aWNlcyA6IHVuZGVmaW5lZCxcbiAgICAgIGNvbmZpZ3VyZVBsZXg6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbWFydC1vcHQtcGxleCcpPy5jaGVja2VkLFxuICAgICAgY29uZmlndXJlUHJvd2xhcnI6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbWFydC1vcHQtcHJvd2xhcnInKT8uY2hlY2tlZCxcbiAgICAgIGNvbmZpZ3VyZVNlZXJyOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc21hcnQtb3B0LXNlZXJyJyk/LmNoZWNrZWQsXG4gICAgICBzYXZlQ3JlZGVudGlhbHM6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbWFydC1vcHQtc2F2ZScpPy5jaGVja2VkXG4gICAgfTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHNlY3VyZUZldGNoKCcvYXBpL3YxL2Fyci9zbWFydC1jb25uZWN0Jywge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHBheWxvYWQpXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcblxuICAgICAgLy8gUmVuZGVyIHByb2dyZXNzIHN0ZXBzXG4gICAgICBsZXQgc3RlcHNIdG1sID0gJyc7XG4gICAgICBmb3IgKGNvbnN0IHN0ZXAgb2YgKGRhdGEuc3RlcHMgfHwgW10pKSB7XG4gICAgICAgIGNvbnN0IGljb24gPSBzdGVwLnN0YXR1cyA9PT0gJ3N1Y2Nlc3MnID8gJzxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLW9rLWZnKTtcIj4mIzEwMDAzOzwvc3Bhbj4nXG4gICAgICAgICAgICAgICAgICAgOiAnPHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tYmFkLWZnKTtcIj4mIzEwMDA3Ozwvc3Bhbj4nO1xuICAgICAgICBjb25zdCBkZXRhaWxDb2xvciA9IHN0ZXAuc3RhdHVzID09PSAnc3VjY2VzcycgPyAndmFyKC0tbXV0ZWQpJyA6ICd2YXIoLS1iYWQtZmcpJztcbiAgICAgICAgc3RlcHNIdG1sICs9IGA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA4cHg7IHBhZGRpbmc6IDZweCAxMHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJhc2UpOyBib3JkZXItcmFkaXVzOiA2cHg7IGZvbnQtc2l6ZTogMC44NXJlbTtcIj5cbiAgICAgICAgICAke2ljb259XG4gICAgICAgICAgPHNwYW4+JHtlc2NhcGVIdG1sKHN0ZXAuc3RlcCl9PC9zcGFuPlxuICAgICAgICAgIDxzcGFuIHN0eWxlPVwibWFyZ2luLWxlZnQ6IGF1dG87IGZvbnQtc2l6ZTogMC43NXJlbTsgY29sb3I6ICR7ZGV0YWlsQ29sb3J9O1wiPiR7ZXNjYXBlSHRtbChzdGVwLmRldGFpbHMgfHwgJycpfTwvc3Bhbj5cbiAgICAgICAgPC9kaXY+YDtcbiAgICAgIH1cbiAgICAgIHByb2dyZXNzU3RlcHMuaW5uZXJIVE1MID0gc3RlcHNIdG1sO1xuXG4gICAgICAvLyBTaG93IHJlc3VsdHMgYWZ0ZXIgYnJpZWYgZGVsYXlcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gc2hvd1Jlc3VsdHMoZGF0YSksIDUwMCk7XG5cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBwcm9ncmVzc1N0ZXBzLmlubmVySFRNTCA9IGA8ZGl2IHN0eWxlPVwicGFkZGluZzogMTJweDsgY29sb3I6IHZhcigtLWJhZC1mZyk7XCI+Q29ubmVjdGlvbiBlcnJvcjogJHtlc2NhcGVIdG1sKGUubWVzc2FnZSl9PC9kaXY+YDtcbiAgICB9XG4gIH1cblxuICAvLyBQaGFzZSA0OiBSZXN1bHRzXG4gIGZ1bmN0aW9uIHNob3dSZXN1bHRzKGRhdGEpIHtcbiAgICBzaG93UGhhc2UoJ3Jlc3VsdHMnKTtcblxuICAgIGNvbnN0IHMgPSBkYXRhLnN1bW1hcnkgfHwge307XG4gICAgY29uc3QgYWxsR29vZCA9IHMuZmFpbGVkID09PSAwICYmIHMuc3VjY2VlZGVkID4gMDtcbiAgICBjb25zdCBoZWFkZXJDb2xvciA9IGFsbEdvb2QgPyAndmFyKC0tb2stZmcpJyA6ICcjZjM5YzEyJztcbiAgICBjb25zdCBoZWFkZXJJY29uID0gYWxsR29vZCA/ICcmIzEwMDAzOycgOiAnJiM5ODg4Oyc7XG4gICAgY29uc3QgaGVhZGVyVGV4dCA9IGFsbEdvb2QgPyAnQWxsIENvbm5lY3RlZCEnIDogYCR7ZXNjYXBlSHRtbChTdHJpbmcocy5zdWNjZWVkZWQpKX0vJHtlc2NhcGVIdG1sKFN0cmluZyhzLnRvdGFsU3RlcHMpKX0gU3RlcHMgU3VjY2VlZGVkYDtcblxuICAgIGxldCBodG1sID0gYDxkaXYgc3R5bGU9XCJ0ZXh0LWFsaWduOiBjZW50ZXI7IHBhZGRpbmc6IDE2cHg7IGJhY2tncm91bmQ6IGNvbG9yLW1peChpbiBzcmdiLCAke2hlYWRlckNvbG9yfSAxMiUsIHRyYW5zcGFyZW50KTsgYm9yZGVyLXJhZGl1czogMTBweDsgYm9yZGVyOiAxcHggc29saWQgJHtoZWFkZXJDb2xvcn07IG1hcmdpbi1ib3R0b206IDEycHg7XCI+XG4gICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAxLjVyZW07IGNvbG9yOiAke2hlYWRlckNvbG9yfTtcIj4ke2hlYWRlckljb259PC9kaXY+XG4gICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAxLjFyZW07IGZvbnQtd2VpZ2h0OiA2MDA7IGNvbG9yOiAke2hlYWRlckNvbG9yfTtcIj4ke2hlYWRlclRleHR9PC9kaXY+XG4gICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjg1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW4tdG9wOiA0cHg7XCI+JHtlc2NhcGVIdG1sKFN0cmluZyhzLnN1Y2NlZWRlZCkpfSBzdWNjZWVkZWQsICR7ZXNjYXBlSHRtbChTdHJpbmcocy5mYWlsZWQpKX0gZmFpbGVkPC9kaXY+XG4gICAgPC9kaXY+YDtcblxuICAgIC8vIFN0ZXBzIGRldGFpbFxuICAgIGh0bWwgKz0gJzxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBmbGV4LWRpcmVjdGlvbjogY29sdW1uOyBnYXA6IDRweDtcIj4nO1xuICAgIGZvciAoY29uc3Qgc3RlcCBvZiAoZGF0YS5zdGVwcyB8fCBbXSkpIHtcbiAgICAgIGNvbnN0IGljb24gPSBzdGVwLnN0YXR1cyA9PT0gJ3N1Y2Nlc3MnID8gJzxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLW9rLWZnKTtcIj4mIzEwMDAzOzwvc3Bhbj4nXG4gICAgICAgICAgICAgICAgIDogJzxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLWJhZC1mZyk7XCI+JiMxMDAwNzs8L3NwYW4+JztcbiAgICAgIGh0bWwgKz0gYDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDhweDsgcGFkZGluZzogNHB4IDhweDsgZm9udC1zaXplOiAwLjhyZW07XCI+XG4gICAgICAgICR7aWNvbn0gJHtlc2NhcGVIdG1sKHN0ZXAuc3RlcCl9IDxzcGFuIHN0eWxlPVwibWFyZ2luLWxlZnQ6IGF1dG87IGNvbG9yOiB2YXIoLS1tdXRlZCk7IGZvbnQtc2l6ZTogMC43NXJlbTtcIj4ke2VzY2FwZUh0bWwoc3RlcC5kZXRhaWxzIHx8ICcnKX08L3NwYW4+XG4gICAgICA8L2Rpdj5gO1xuICAgIH1cbiAgICBodG1sICs9ICc8L2Rpdj4nO1xuXG4gICAgcmVzdWx0c0NvbnRlbnQuaW5uZXJIVE1MID0gaHRtbDtcblxuICAgIC8vIFNob3cgcmV0cnkgYnV0dG9uIGlmIGFueSBmYWlsdXJlc1xuICAgIHJldHJ5QnRuLnN0eWxlLmRpc3BsYXkgPSBzLmZhaWxlZCA+IDAgPyAnYmxvY2snIDogJ25vbmUnO1xuXG4gICAgLy8gRmV0Y2ggUGxleCBsaWJyYXJpZXMgaWYgUGxleCB3YXMgY29ubmVjdGVkXG4gICAgaWYgKGRhdGEuc3RlcHM/LnNvbWUoc3QgPT4gc3Quc3RlcC5pbmNsdWRlcygnUGxleCcpICYmIHN0LnN0YXR1cyA9PT0gJ3N1Y2Nlc3MnKSkge1xuICAgICAgZmV0Y2hQbGV4TGlicmFyaWVzKCk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gZmV0Y2hQbGV4TGlicmFyaWVzKCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS9wbGV4L2xpYnJhcmllcycpO1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlcy5qc29uKCk7XG4gICAgICBpZiAoZGF0YS5zdWNjZXNzICYmIGRhdGEubGlicmFyaWVzPy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGxldCBodG1sID0gYDxkaXYgc3R5bGU9XCJwYWRkaW5nOiAxMnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJhc2UpOyBib3JkZXItcmFkaXVzOiA4cHg7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XCI+XG4gICAgICAgICAgPGg0IHN0eWxlPVwibWFyZ2luOiAwIDAgOHB4OyBmb250LXNpemU6IDAuODVyZW07IGNvbG9yOiB2YXIoLS1hY2NlbnQpO1wiPlx1RDgzQ1x1REZBQyAke2VzY2FwZUh0bWwoZGF0YS5zZXJ2ZXJOYW1lKX0gTGlicmFyaWVzPC9oND5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgZmxleC13cmFwOiB3cmFwOyBnYXA6IDhweDtcIj5gO1xuICAgICAgICBmb3IgKGNvbnN0IGxpYiBvZiBkYXRhLmxpYnJhcmllcykge1xuICAgICAgICAgIGNvbnN0IHR5cGVJY29uID0gbGliLnR5cGUgPT09ICdtb3ZpZScgPyAnXHVEODNDXHVERkFDJyA6IGxpYi50eXBlID09PSAnc2hvdycgPyAnXHVEODNEXHVEQ0ZBJyA6ICdcdUQ4M0NcdURGQjUnO1xuICAgICAgICAgIGh0bWwgKz0gYDxkaXYgc3R5bGU9XCJwYWRkaW5nOiA4cHggMTJweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iZyk7IGJvcmRlci1yYWRpdXM6IDZweDsgZm9udC1zaXplOiAwLjg1cmVtO1wiPlxuICAgICAgICAgICAgJHt0eXBlSWNvbn0gPHN0cm9uZz4ke2VzY2FwZUh0bWwobGliLnRpdGxlKX08L3N0cm9uZz5cbiAgICAgICAgICAgIDxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTsgZm9udC1zaXplOiAwLjc1cmVtO1wiPiR7ZXNjYXBlSHRtbChTdHJpbmcobGliLmNvdW50KSl9IGl0ZW1zPC9zcGFuPlxuICAgICAgICAgIDwvZGl2PmA7XG4gICAgICAgIH1cbiAgICAgICAgaHRtbCArPSAnPC9kaXY+PC9kaXY+JztcbiAgICAgICAgcGxleExpYnJhcmllcy5pbm5lckhUTUwgPSBodG1sO1xuICAgICAgICBwbGV4TGlicmFyaWVzLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8vIElnbm9yZSBQbGV4IGxpYnJhcnkgZmV0Y2ggZXJyb3JzXG4gICAgfVxuICB9XG5cbiAgLy8gRXZlbnQgbGlzdGVuZXJzXG4gIG9wZW5CdG4/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgIG1vZGFsLmNsYXNzTGlzdC5hZGQoJ3Nob3cnKTtcbiAgICBwbGV4TGlicmFyaWVzLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgc21hcnREZXRlY3QoKTtcbiAgfSk7XG5cbiAgd2lyZU1vZGFsKG1vZGFsLCBjYW5jZWxCdG4pO1xuICBjb25uZWN0QnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHNtYXJ0Q29ubmVjdCk7XG4gIHJldHJ5QnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHNtYXJ0Q29ubmVjdCk7XG59KSgpO1xuO1xuLy8gPT09PT09PT09PSBOT1RJRklDQVRJT04gU0VUVElOR1MgPT09PT09PT09PVxuKGZ1bmN0aW9uKCkge1xuICBjb25zdCBlcnJvckhhbmRsZXIgPSBuZXcgRXJyb3JIYW5kbGVyKCk7XG4gIC8vIEluamVjdCBtb2RhbCBIVE1MXG4gIGluamVjdE1vZGFsKCdub3RpZmljYXRpb25zLW1vZGFsJywgYDxkaXYgaWQ9XCJub3RpZmljYXRpb25zLW1vZGFsXCIgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsXCI+XG4gICAgPGRpdiBjbGFzcz1cIndlYXRoZXItbW9kYWwtY29udGVudFwiIHN0eWxlPVwibWluLXdpZHRoOiA1NTBweDsgbWF4LXdpZHRoOiA2NTBweDtcIj5cbiAgICAgIDxoMz5cdUQ4M0RcdUREMTQgTm90aWZpY2F0aW9uIFNldHRpbmdzPC9oMz5cblxuICAgICAgPCEtLSBNYXN0ZXIgVG9nZ2xlIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cImFjY2VudC1pbmZvLWJveFwiPlxuICAgICAgICA8bGFiZWwgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDEwcHg7IGN1cnNvcjogcG9pbnRlcjtcIj5cbiAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgaWQ9XCJub3RpZmljYXRpb25zLWVuYWJsZWRcIiAvPlxuICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICA8c3BhbiBzdHlsZT1cImZvbnQtd2VpZ2h0OiA2MDA7IGNvbG9yOiB2YXIoLS1hY2NlbnQpO1wiPkVuYWJsZSBOb3RpZmljYXRpb25zPC9zcGFuPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtdGlueS1tdXRlZFwiPlJlY2VpdmUgYWxlcnRzIHdoZW4gY29udGFpbmVycyBnbyB1cC9kb3duPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbGFiZWw+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBQcm92aWRlcnMgU2VjdGlvbiAtLT5cbiAgICAgIDxoNCBjbGFzcz1cInNlY3Rpb24taGVhZGluZ1wiPk5vdGlmaWNhdGlvbiBQcm92aWRlcnM8L2g0PlxuXG4gICAgICA8IS0tIERpc2NvcmQgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwibm90aWZpY2F0aW9uLXByb3ZpZGVyIHByb3ZpZGVyLWNhcmRcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInByb3ZpZGVyLWhlYWRlclwiPlxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNoZWNrYm94LWxhYmVsXCI+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgaWQ9XCJkaXNjb3JkLWVuYWJsZWRcIiAvPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmdy01MDBcIj5EaXNjb3JkPC9zcGFuPlxuICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgPGJ1dHRvbiBpZD1cImRpc2NvcmQtdGVzdFwiIGNsYXNzPVwidGVzdC1idG4gYnRuLXhzXCI+VGVzdDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBpZD1cImRpc2NvcmQtY29uZmlnXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lO1wiPlxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZpZWxkLWxhYmVsLXNtXCI+V2ViaG9vayBVUkw6PC9sYWJlbD5cbiAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBpZD1cImRpc2NvcmQtd2ViaG9va1wiIHBsYWNlaG9sZGVyPVwiaHR0cHM6Ly9kaXNjb3JkLmNvbS9hcGkvdjEvd2ViaG9va3MvLi4uXCIgc3R5bGU9XCJ3aWR0aDogMTAwJTtcIiAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIFRlbGVncmFtIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cIm5vdGlmaWNhdGlvbi1wcm92aWRlciBwcm92aWRlci1jYXJkXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJwcm92aWRlci1oZWFkZXJcIj5cbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjaGVja2JveC1sYWJlbFwiPlxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGlkPVwidGVsZWdyYW0tZW5hYmxlZFwiIC8+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImZ3LTUwMFwiPlRlbGVncmFtPC9zcGFuPlxuICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgPGJ1dHRvbiBpZD1cInRlbGVncmFtLXRlc3RcIiBjbGFzcz1cInRlc3QtYnRuIGJ0bi14c1wiPlRlc3Q8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgaWQ9XCJ0ZWxlZ3JhbS1jb25maWdcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImdyaWQtMmNvbFwiPlxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmllbGQtbGFiZWwtc21cIj5Cb3QgVG9rZW46PC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgaWQ9XCJ0ZWxlZ3JhbS1ib3QtdG9rZW5cIiBwbGFjZWhvbGRlcj1cIjEyMzQ1NjpBQkMuLi5cIiAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmaWVsZC1sYWJlbC1zbVwiPkNoYXQgSUQ6PC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgaWQ9XCJ0ZWxlZ3JhbS1jaGF0LWlkXCIgcGxhY2Vob2xkZXI9XCItMTAwMTIzNDU2Nzg5MFwiIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBudGZ5LnNoIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cIm5vdGlmaWNhdGlvbi1wcm92aWRlciBwcm92aWRlci1jYXJkXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJwcm92aWRlci1oZWFkZXJcIj5cbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjaGVja2JveC1sYWJlbFwiPlxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGlkPVwibnRmeS1lbmFibGVkXCIgLz5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZnctNTAwXCI+bnRmeS5zaDwvc3Bhbj5cbiAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgIDxidXR0b24gaWQ9XCJudGZ5LXRlc3RcIiBjbGFzcz1cInRlc3QtYnRuIGJ0bi14c1wiPlRlc3Q8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgaWQ9XCJudGZ5LWNvbmZpZ1wiIHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIj5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZ3JpZDsgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiAyZnIgMWZyOyBnYXA6IDhweDtcIj5cbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZpZWxkLWxhYmVsLXNtXCI+U2VydmVyIFVSTDo8L2xhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBpZD1cIm50Znktc2VydmVyXCIgcGxhY2Vob2xkZXI9XCJodHRwczovL250Znkuc2hcIiB2YWx1ZT1cImh0dHBzOi8vbnRmeS5zaFwiIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZpZWxkLWxhYmVsLXNtXCI+VG9waWM6PC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgaWQ9XCJudGZ5LXRvcGljXCIgcGxhY2Vob2xkZXI9XCJkYXNoY2FkZHktYWxlcnRzXCIgLz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIEVtYWlsIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cIm5vdGlmaWNhdGlvbi1wcm92aWRlciBwcm92aWRlci1jYXJkXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJwcm92aWRlci1oZWFkZXJcIj5cbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjaGVja2JveC1sYWJlbFwiPlxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGlkPVwiZW1haWwtZW5hYmxlZFwiIC8+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImZ3LTUwMFwiPkVtYWlsIChTTVRQKTwvc3Bhbj5cbiAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgIDxidXR0b24gaWQ9XCJlbWFpbC10ZXN0XCIgY2xhc3M9XCJ0ZXN0LWJ0biBidG4teHNcIj5UZXN0PC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGlkPVwiZW1haWwtY29uZmlnXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lO1wiPlxuICAgICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBncmlkOyBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IDJmciAxZnI7IGdhcDogOHB4OyBtYXJnaW4tYm90dG9tOiA4cHg7XCI+XG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmaWVsZC1sYWJlbC1zbVwiPlNNVFAgSG9zdDo8L2xhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBpZD1cImVtYWlsLWhvc3RcIiBwbGFjZWhvbGRlcj1cInNtdHAuZ21haWwuY29tXCIgLz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmllbGQtbGFiZWwtc21cIj5Qb3J0OjwvbGFiZWw+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgaWQ9XCJlbWFpbC1wb3J0XCIgdmFsdWU9XCI1ODdcIiBwbGFjZWhvbGRlcj1cIjU4N1wiIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZ3JpZDsgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiAxZnIgMWZyOyBnYXA6IDhweDsgbWFyZ2luLWJvdHRvbTogOHB4O1wiPlxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmllbGQtbGFiZWwtc21cIj5Vc2VybmFtZTo8L2xhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBpZD1cImVtYWlsLXVzZXJcIiBwbGFjZWhvbGRlcj1cInVzZXJAZ21haWwuY29tXCIgLz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmllbGQtbGFiZWwtc21cIj5QYXNzd29yZDo8L2xhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInBhc3N3b3JkXCIgaWQ9XCJlbWFpbC1wYXNzXCIgcGxhY2Vob2xkZXI9XCJhcHAgcGFzc3dvcmRcIiAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGdyaWQ7IGdyaWQtdGVtcGxhdGUtY29sdW1uczogMWZyIDFmcjsgZ2FwOiA4cHg7XCI+XG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmaWVsZC1sYWJlbC1zbVwiPkZyb206PC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgaWQ9XCJlbWFpbC1mcm9tXCIgcGxhY2Vob2xkZXI9XCJEYXNoQ2FkZHkgJmx0O25vcmVwbHlAZXhhbXBsZS5jb20mZ3Q7XCIgLz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmllbGQtbGFiZWwtc21cIj5Ubzo8L2xhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBpZD1cImVtYWlsLXRvXCIgcGxhY2Vob2xkZXI9XCJhZG1pbkBleGFtcGxlLmNvbVwiIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8bGFiZWwgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDZweDsgbWFyZ2luLXRvcDogOHB4OyBmb250LXNpemU6IDAuOHJlbTtcIj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBpZD1cImVtYWlsLXNlY3VyZVwiIC8+IFVzZSBUTFMgKHBvcnQgNDY1KVxuICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gSGVhbHRoIENoZWNrIFNldHRpbmdzIC0tPlxuICAgICAgPGg0IGNsYXNzPVwic2VjdGlvbi1oZWFkaW5nXCI+SGVhbHRoIE1vbml0b3Jpbmc8L2g0PlxuICAgICAgPGRpdiBzdHlsZT1cInBhZGRpbmc6IDEycHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmFzZSk7IGJvcmRlci1yYWRpdXM6IDhweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcIj5cbiAgICAgICAgPGxhYmVsIHN0eWxlPVwiZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiAxMHB4OyBjdXJzb3I6IHBvaW50ZXI7IG1hcmdpbi1ib3R0b206IDEwcHg7XCI+XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGlkPVwiaGVhbHRoLWNoZWNrLWVuYWJsZWRcIiAvPlxuICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImZ3LTUwMFwiPkVuYWJsZSBIZWFsdGggTW9uaXRvcmluZzwvc3Bhbj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXRpbnktbXV0ZWRcIj5QZXJpb2RpY2FsbHkgY2hlY2sgY29udGFpbmVyIHN0YXR1czwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2xhYmVsPlxuICAgICAgICA8ZGl2IGlkPVwiaGVhbHRoLWNoZWNrLWNvbmZpZ1wiIHN0eWxlPVwiZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiAxMHB4O1wiPlxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZpZWxkLWxhYmVsLXNtXCI+Q2hlY2sgaW50ZXJ2YWw6PC9sYWJlbD5cbiAgICAgICAgICA8c2VsZWN0IGlkPVwiaGVhbHRoLWNoZWNrLWludGVydmFsXCIgc3R5bGU9XCJ3aWR0aDogYXV0bztcIj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCIxXCI+MSBtaW51dGU8L29wdGlvbj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCI1XCIgc2VsZWN0ZWQ+NSBtaW51dGVzPC9vcHRpb24+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiMTVcIj4xNSBtaW51dGVzPC9vcHRpb24+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiMzBcIj4zMCBtaW51dGVzPC9vcHRpb24+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiNjBcIj4xIGhvdXI8L29wdGlvbj5cbiAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICA8YnV0dG9uIGlkPVwiaGVhbHRoLWNoZWNrLW5vd1wiIHN0eWxlPVwicGFkZGluZzogNHB4IDEwcHg7IGZvbnQtc2l6ZTogMC43NXJlbTsgbWFyZ2luLWxlZnQ6IGF1dG87XCI+Q2hlY2sgTm93PC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGlkPVwiaGVhbHRoLWNoZWNrLXN0YXR1c1wiIHN0eWxlPVwiZm9udC1zaXplOiAwLjc1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW4tdG9wOiA4cHg7XCI+XG4gICAgICAgICAgTGFzdCBjaGVjazogTmV2ZXJcbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBFdmVudCBUeXBlcyAtLT5cbiAgICAgIDxoNCBjbGFzcz1cInNlY3Rpb24taGVhZGluZ1wiPkV2ZW50cyB0byBOb3RpZnk8L2g0PlxuICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGdyaWQ7IGdyaWQtdGVtcGxhdGUtY29sdW1uczogMWZyIDFmcjsgZ2FwOiA2cHg7IHBhZGRpbmc6IDEycHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmFzZSk7IGJvcmRlci1yYWRpdXM6IDhweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcIj5cbiAgICAgICAgPGxhYmVsIGNsYXNzPVwiY2hlY2tib3gtbGFiZWwtc21cIj5cbiAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgaWQ9XCJldmVudC1jb250YWluZXItZG93blwiIGNoZWNrZWQgLz4gQ29udGFpbmVyIERvd25cbiAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgPGxhYmVsIGNsYXNzPVwiY2hlY2tib3gtbGFiZWwtc21cIj5cbiAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgaWQ9XCJldmVudC1jb250YWluZXItdXBcIiBjaGVja2VkIC8+IENvbnRhaW5lciBSZWNvdmVyZWRcbiAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgPGxhYmVsIGNsYXNzPVwiY2hlY2tib3gtbGFiZWwtc21cIj5cbiAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgaWQ9XCJldmVudC1kZXBsb3ktc3VjY2Vzc1wiIGNoZWNrZWQgLz4gRGVwbG95bWVudCBTdWNjZXNzXG4gICAgICAgIDwvbGFiZWw+XG4gICAgICAgIDxsYWJlbCBjbGFzcz1cImNoZWNrYm94LWxhYmVsLXNtXCI+XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGlkPVwiZXZlbnQtZGVwbG95LWZhaWxlZFwiIGNoZWNrZWQgLz4gRGVwbG95bWVudCBGYWlsZWRcbiAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgPGxhYmVsIGNsYXNzPVwiY2hlY2tib3gtbGFiZWwtc21cIiBzdHlsZT1cImdyaWQtY29sdW1uOiAxIC8gLTE7XCI+XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGlkPVwiZXZlbnQtcmVzb3VyY2UtYWxlcnRcIiBjaGVja2VkIC8+IFJlc291cmNlIEFsZXJ0c1xuICAgICAgICA8L2xhYmVsPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gSGlzdG9yeSAtLT5cbiAgICAgIDxoNCBjbGFzcz1cInNlY3Rpb24taGVhZGluZ1wiPk5vdGlmaWNhdGlvbiBIaXN0b3J5PC9oND5cbiAgICAgIDxkaXYgaWQ9XCJub3RpZmljYXRpb24taGlzdG9yeVwiIHN0eWxlPVwibWF4LWhlaWdodDogMTUwcHg7IG92ZXJmbG93LXk6IGF1dG87IHBhZGRpbmc6IDhweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iYXNlKTsgYm9yZGVyLXJhZGl1czogOHB4OyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBmb250LXNpemU6IDAuOHJlbTtcIj5cbiAgICAgICAgPGRpdiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7IHRleHQtYWxpZ246IGNlbnRlcjsgcGFkZGluZzogMjBweDtcIj5ObyBub3RpZmljYXRpb25zIHlldDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGlkPVwibGFzdC1ub3RpZmljYXRpb24tc2VudFwiIHN0eWxlPVwiZm9udC1zaXplOiAwLjc1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyB0ZXh0LWFsaWduOiBjZW50ZXI7IG1hcmdpbi10b3A6IDZweDtcIj48L2Rpdj5cblxuICAgICAgPCEtLSBCdXR0b25zIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cIndlYXRoZXItbW9kYWwtYnV0dG9ucyBtb2RhbC1mb290ZXItYmFyXCI+XG4gICAgICAgIDxidXR0b24gaWQ9XCJub3RpZmljYXRpb25zLXNlbmQtdGVzdFwiIGNsYXNzPVwiYnRuLXNlY29uZGFyeVwiIHN0eWxlPVwibWFyZ2luLXJpZ2h0OiBhdXRvO1wiPlNlbmQgVGVzdDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIGlkPVwibm90aWZpY2F0aW9ucy1jYW5jZWxcIj5DYW5jZWw8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBpZD1cIm5vdGlmaWNhdGlvbnMtc2F2ZVwiIGNsYXNzPVwiYnRuLWFjY2VudFwiPlNhdmUgU2V0dGluZ3M8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5gKTtcblxuICBjb25zdCBtb2RhbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdub3RpZmljYXRpb25zLW1vZGFsJyk7XG4gIGNvbnN0IG9wZW5CdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWFuYWdlLW5vdGlmaWNhdGlvbnMnKTtcbiAgY29uc3Qgc2F2ZUJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdub3RpZmljYXRpb25zLXNhdmUnKTtcbiAgY29uc3QgY2FuY2VsQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ25vdGlmaWNhdGlvbnMtY2FuY2VsJyk7XG5cbiAgLy8gUHJvdmlkZXIgdG9nZ2xlIGhhbmRsZXJzXG4gIFsnZGlzY29yZCcsICd0ZWxlZ3JhbScsICdudGZ5JywgJ2VtYWlsJ10uZm9yRWFjaChwcm92aWRlciA9PiB7XG4gICAgY29uc3QgY2hlY2tib3ggPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChgJHtwcm92aWRlcn0tZW5hYmxlZGApO1xuICAgIGNvbnN0IGNvbmZpZyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGAke3Byb3ZpZGVyfS1jb25maWdgKTtcblxuICAgIGNoZWNrYm94Py5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCAoKSA9PiB7XG4gICAgICBjb25maWcuc3R5bGUuZGlzcGxheSA9IGNoZWNrYm94LmNoZWNrZWQgPyAnYmxvY2snIDogJ25vbmUnO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyBIZWFsdGggY2hlY2sgdG9nZ2xlXG4gIGNvbnN0IGhlYWx0aENoZWNrRW5hYmxlZCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtY2hlY2stZW5hYmxlZCcpO1xuICBjb25zdCBoZWFsdGhDaGVja0NvbmZpZyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtY2hlY2stY29uZmlnJyk7XG4gIGhlYWx0aENoZWNrRW5hYmxlZD8uYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgKCkgPT4ge1xuICAgIGhlYWx0aENoZWNrQ29uZmlnLnN0eWxlLm9wYWNpdHkgPSBoZWFsdGhDaGVja0VuYWJsZWQuY2hlY2tlZCA/ICcxJyA6ICcwLjUnO1xuICB9KTtcblxuICAvLyBMb2FkIG5vdGlmaWNhdGlvbiBjb25maWcgZnJvbSBBUElcbiAgYXN5bmMgZnVuY3Rpb24gbG9hZE5vdGlmaWNhdGlvbkNvbmZpZygpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS9ub3RpZmljYXRpb25zL2NvbmZpZycpO1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcblxuICAgICAgaWYgKGRhdGEuc3VjY2Vzcykge1xuICAgICAgICBjb25zdCBjb25maWcgPSBkYXRhLmNvbmZpZztcblxuICAgICAgICAvLyBNYXN0ZXIgdG9nZ2xlXG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdub3RpZmljYXRpb25zLWVuYWJsZWQnKS5jaGVja2VkID0gY29uZmlnLmVuYWJsZWQ7XG5cbiAgICAgICAgLy8gUHJvdmlkZXJzXG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkaXNjb3JkLWVuYWJsZWQnKS5jaGVja2VkID0gY29uZmlnLnByb3ZpZGVycz8uZGlzY29yZD8uZW5hYmxlZCB8fCBmYWxzZTtcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RlbGVncmFtLWVuYWJsZWQnKS5jaGVja2VkID0gY29uZmlnLnByb3ZpZGVycz8udGVsZWdyYW0/LmVuYWJsZWQgfHwgZmFsc2U7XG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdudGZ5LWVuYWJsZWQnKS5jaGVja2VkID0gY29uZmlnLnByb3ZpZGVycz8ubnRmeT8uZW5hYmxlZCB8fCBmYWxzZTtcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2VtYWlsLWVuYWJsZWQnKS5jaGVja2VkID0gY29uZmlnLnByb3ZpZGVycz8uZW1haWw/LmVuYWJsZWQgfHwgZmFsc2U7XG5cbiAgICAgICAgLy8gU2hvdy9oaWRlIGNvbmZpZyBzZWN0aW9uc1xuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGlzY29yZC1jb25maWcnKS5zdHlsZS5kaXNwbGF5ID0gY29uZmlnLnByb3ZpZGVycz8uZGlzY29yZD8uZW5hYmxlZCA/ICdibG9jaycgOiAnbm9uZSc7XG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZWxlZ3JhbS1jb25maWcnKS5zdHlsZS5kaXNwbGF5ID0gY29uZmlnLnByb3ZpZGVycz8udGVsZWdyYW0/LmVuYWJsZWQgPyAnYmxvY2snIDogJ25vbmUnO1xuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbnRmeS1jb25maWcnKS5zdHlsZS5kaXNwbGF5ID0gY29uZmlnLnByb3ZpZGVycz8ubnRmeT8uZW5hYmxlZCA/ICdibG9jaycgOiAnbm9uZSc7XG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdlbWFpbC1jb25maWcnKS5zdHlsZS5kaXNwbGF5ID0gY29uZmlnLnByb3ZpZGVycz8uZW1haWw/LmVuYWJsZWQgPyAnYmxvY2snIDogJ25vbmUnO1xuXG4gICAgICAgIC8vIG50Znkgc2VydmVyIFVSTFxuICAgICAgICBpZiAoY29uZmlnLnByb3ZpZGVycz8ubnRmeT8uc2VydmVyVXJsKSB7XG4gICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ250Znktc2VydmVyJykudmFsdWUgPSBjb25maWcucHJvdmlkZXJzLm50Znkuc2VydmVyVXJsO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gZW1haWwgZmllbGRzXG4gICAgICAgIGlmIChjb25maWcucHJvdmlkZXJzPy5lbWFpbD8uaG9zdCkgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2VtYWlsLWhvc3QnKS52YWx1ZSA9IGNvbmZpZy5wcm92aWRlcnMuZW1haWwuaG9zdDtcbiAgICAgICAgaWYgKGNvbmZpZy5wcm92aWRlcnM/LmVtYWlsPy5mcm9tKSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZW1haWwtZnJvbScpLnZhbHVlID0gY29uZmlnLnByb3ZpZGVycy5lbWFpbC5mcm9tO1xuXG4gICAgICAgIC8vIEhlYWx0aCBjaGVja1xuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhbHRoLWNoZWNrLWVuYWJsZWQnKS5jaGVja2VkID0gY29uZmlnLmhlYWx0aENoZWNrPy5lbmFibGVkIHx8IGZhbHNlO1xuICAgICAgICBpZiAoY29uZmlnLmhlYWx0aENoZWNrPy5pbnRlcnZhbE1pbnV0ZXMpIHtcbiAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhbHRoLWNoZWNrLWludGVydmFsJykudmFsdWUgPSBjb25maWcuaGVhbHRoQ2hlY2suaW50ZXJ2YWxNaW51dGVzO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb25maWcuaGVhbHRoQ2hlY2s/Lmxhc3RDaGVjaykge1xuICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtY2hlY2stc3RhdHVzJykudGV4dENvbnRlbnQgPVxuICAgICAgICAgICAgYExhc3QgY2hlY2s6ICR7bmV3IERhdGUoY29uZmlnLmhlYWx0aENoZWNrLmxhc3RDaGVjaykudG9Mb2NhbGVTdHJpbmcoKX1gO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRXZlbnRzXG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdldmVudC1jb250YWluZXItZG93bicpLmNoZWNrZWQgPSBjb25maWcuZXZlbnRzPy5jb250YWluZXJEb3duICE9PSBmYWxzZTtcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2V2ZW50LWNvbnRhaW5lci11cCcpLmNoZWNrZWQgPSBjb25maWcuZXZlbnRzPy5jb250YWluZXJVcCAhPT0gZmFsc2U7XG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdldmVudC1kZXBsb3ktc3VjY2VzcycpLmNoZWNrZWQgPSBjb25maWcuZXZlbnRzPy5kZXBsb3ltZW50U3VjY2VzcyAhPT0gZmFsc2U7XG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdldmVudC1kZXBsb3ktZmFpbGVkJykuY2hlY2tlZCA9IGNvbmZpZy5ldmVudHM/LmRlcGxveW1lbnRGYWlsZWQgIT09IGZhbHNlO1xuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZXZlbnQtcmVzb3VyY2UtYWxlcnQnKS5jaGVja2VkID0gY29uZmlnLmV2ZW50cz8ucmVzb3VyY2VBbGVydCAhPT0gZmFsc2U7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGVycm9ySGFuZGxlci5sb2dFcnJvcignW05vdGlmaWNhdGlvbnNdIExvYWQgQ29uZmlnJywgZXJyb3IsIHsgZnVuY3Rpb246ICdsb2FkQ29uZmlnJyB9KTtcbiAgICB9XG4gIH1cblxuICAvLyBMb2FkIG5vdGlmaWNhdGlvbiBoaXN0b3J5XG4gIGFzeW5jIGZ1bmN0aW9uIGxvYWROb3RpZmljYXRpb25IaXN0b3J5KCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL25vdGlmaWNhdGlvbnMvaGlzdG9yeT9saW1pdD0xMCcpO1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcblxuICAgICAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ25vdGlmaWNhdGlvbi1oaXN0b3J5Jyk7XG4gICAgICBpZiAoZGF0YS5zdWNjZXNzICYmIGRhdGEuaGlzdG9yeT8ubGVuZ3RoID4gMCkge1xuICAgICAgICBjb250YWluZXIuaW5uZXJIVE1MID0gZGF0YS5oaXN0b3J5Lm1hcChpdGVtID0+IHtcbiAgICAgICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoaXRlbS50aW1lc3RhbXApLnRvTG9jYWxlU3RyaW5nKCk7XG4gICAgICAgICAgY29uc3QgdHlwZUNvbG9ycyA9IHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6ICd2YXIoLS1vay1mZyknLFxuICAgICAgICAgICAgZXJyb3I6ICd2YXIoLS1iYWQtZmcpJyxcbiAgICAgICAgICAgIHdhcm5pbmc6ICcjZjM5YzEyJyxcbiAgICAgICAgICAgIGluZm86ICd2YXIoLS1hY2NlbnQpJ1xuICAgICAgICAgIH07XG4gICAgICAgICAgcmV0dXJuIGBcbiAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJwYWRkaW5nOiA2cHggOHB4OyBib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgZGlzcGxheTogZmxleDsgZ2FwOiA4cHg7IGFsaWduLWl0ZW1zOiBmbGV4LXN0YXJ0O1wiPlxuICAgICAgICAgICAgICA8c3BhbiBzdHlsZT1cImNvbG9yOiAke3R5cGVDb2xvcnNbaXRlbS50eXBlXSB8fCAndmFyKC0tbXV0ZWQpJ31cIj4ke2l0ZW0udHlwZSA9PT0gJ3N1Y2Nlc3MnID8gJ1x1MjcxMycgOiBpdGVtLnR5cGUgPT09ICdlcnJvcicgPyAnXHUyNzE3JyA6ICdcdTIxMzknfTwvc3Bhbj5cbiAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImZsZXg6IDE7IG1pbi13aWR0aDogMDtcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC13ZWlnaHQ6IDUwMDsgd2hpdGUtc3BhY2U6IG5vd3JhcDsgb3ZlcmZsb3c6IGhpZGRlbjsgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XCI+JHtlc2NhcGVIdG1sKGl0ZW0udGl0bGUpfTwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuN3JlbTsgY29sb3I6IHZhcigtLW11dGVkKTtcIj4ke2RhdGV9PC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgYDtcbiAgICAgICAgfSkuam9pbignJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb250YWluZXIuaW5uZXJIVE1MID0gJzxkaXYgc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpOyB0ZXh0LWFsaWduOiBjZW50ZXI7IHBhZGRpbmc6IDIwcHg7XCI+Tm8gbm90aWZpY2F0aW9ucyB5ZXQ8L2Rpdj4nO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBlcnJvckhhbmRsZXIubG9nRXJyb3IoJ1tOb3RpZmljYXRpb25zXSBMb2FkIEhpc3RvcnknLCBlcnJvciwgeyBmdW5jdGlvbjogJ2xvYWRIaXN0b3J5JyB9KTtcbiAgICB9XG4gIH1cblxuICAvLyBTYXZlIG5vdGlmaWNhdGlvbiBjb25maWdcbiAgYXN5bmMgZnVuY3Rpb24gc2F2ZU5vdGlmaWNhdGlvbkNvbmZpZygpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgY29uZmlnID0ge1xuICAgICAgICBlbmFibGVkOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbm90aWZpY2F0aW9ucy1lbmFibGVkJykuY2hlY2tlZCxcbiAgICAgICAgcHJvdmlkZXJzOiB7XG4gICAgICAgICAgZGlzY29yZDoge1xuICAgICAgICAgICAgZW5hYmxlZDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Rpc2NvcmQtZW5hYmxlZCcpLmNoZWNrZWQsXG4gICAgICAgICAgICB3ZWJob29rVXJsOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGlzY29yZC13ZWJob29rJykudmFsdWUudHJpbSgpXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0ZWxlZ3JhbToge1xuICAgICAgICAgICAgZW5hYmxlZDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RlbGVncmFtLWVuYWJsZWQnKS5jaGVja2VkLFxuICAgICAgICAgICAgYm90VG9rZW46IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZWxlZ3JhbS1ib3QtdG9rZW4nKS52YWx1ZS50cmltKCksXG4gICAgICAgICAgICBjaGF0SWQ6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZWxlZ3JhbS1jaGF0LWlkJykudmFsdWUudHJpbSgpXG4gICAgICAgICAgfSxcbiAgICAgICAgICBudGZ5OiB7XG4gICAgICAgICAgICBlbmFibGVkOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbnRmeS1lbmFibGVkJykuY2hlY2tlZCxcbiAgICAgICAgICAgIHNlcnZlclVybDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ250Znktc2VydmVyJykudmFsdWUudHJpbSgpIHx8ICdodHRwczovL250Znkuc2gnLFxuICAgICAgICAgICAgdG9waWM6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdudGZ5LXRvcGljJykudmFsdWUudHJpbSgpXG4gICAgICAgICAgfSxcbiAgICAgICAgICBlbWFpbDoge1xuICAgICAgICAgICAgZW5hYmxlZDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2VtYWlsLWVuYWJsZWQnKS5jaGVja2VkLFxuICAgICAgICAgICAgaG9zdDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2VtYWlsLWhvc3QnKS52YWx1ZS50cmltKCksXG4gICAgICAgICAgICBwb3J0OiBwYXJzZUludChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZW1haWwtcG9ydCcpLnZhbHVlKSB8fCA1ODcsXG4gICAgICAgICAgICBzZWN1cmU6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdlbWFpbC1zZWN1cmUnKS5jaGVja2VkLFxuICAgICAgICAgICAgdXNlcjogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2VtYWlsLXVzZXInKS52YWx1ZS50cmltKCksXG4gICAgICAgICAgICBwYXNzOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZW1haWwtcGFzcycpLnZhbHVlLnRyaW0oKSxcbiAgICAgICAgICAgIGZyb206IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdlbWFpbC1mcm9tJykudmFsdWUudHJpbSgpLFxuICAgICAgICAgICAgdG86IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdlbWFpbC10bycpLnZhbHVlLnRyaW0oKVxuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZXZlbnRzOiB7XG4gICAgICAgICAgY29udGFpbmVyRG93bjogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2V2ZW50LWNvbnRhaW5lci1kb3duJykuY2hlY2tlZCxcbiAgICAgICAgICBjb250YWluZXJVcDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2V2ZW50LWNvbnRhaW5lci11cCcpLmNoZWNrZWQsXG4gICAgICAgICAgZGVwbG95bWVudFN1Y2Nlc3M6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdldmVudC1kZXBsb3ktc3VjY2VzcycpLmNoZWNrZWQsXG4gICAgICAgICAgZGVwbG95bWVudEZhaWxlZDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2V2ZW50LWRlcGxveS1mYWlsZWQnKS5jaGVja2VkLFxuICAgICAgICAgIHJlc291cmNlQWxlcnQ6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdldmVudC1yZXNvdXJjZS1hbGVydCcpLmNoZWNrZWRcbiAgICAgICAgfSxcbiAgICAgICAgaGVhbHRoQ2hlY2s6IHtcbiAgICAgICAgICBlbmFibGVkOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhbHRoLWNoZWNrLWVuYWJsZWQnKS5jaGVja2VkLFxuICAgICAgICAgIGludGVydmFsTWludXRlczogcGFyc2VJbnQoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1jaGVjay1pbnRlcnZhbCcpLnZhbHVlKSB8fCA1XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgc2VjdXJlRmV0Y2goJy9hcGkvdjEvbm90aWZpY2F0aW9ucy9jb25maWcnLCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoY29uZmlnKVxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICBpZiAoZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oJ05vdGlmaWNhdGlvbiBzZXR0aW5ncyBzYXZlZCcsICdzdWNjZXNzJywgMzAwMCk7XG4gICAgICAgIG1vZGFsLmNsYXNzTGlzdC5yZW1vdmUoJ3Nob3cnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oYEZhaWxlZCB0byBzYXZlOiAke2RhdGEuZXJyb3J9YCwgJ2Vycm9yJywgMzAwMCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHNob3dOb3RpZmljYXRpb24oYEVycm9yOiAke2Vycm9yLm1lc3NhZ2V9YCwgJ2Vycm9yJywgMzAwMCk7XG4gICAgfVxuICB9XG5cbiAgLy8gVGVzdCBub3RpZmljYXRpb24gaGFuZGxlcnNcbiAgYXN5bmMgZnVuY3Rpb24gdGVzdFByb3ZpZGVyKHByb3ZpZGVyKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgc2VjdXJlRmV0Y2goJy9hcGkvdjEvbm90aWZpY2F0aW9ucy90ZXN0Jywge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsgcHJvdmlkZXIgfSlcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgaWYgKGRhdGEuc3VjY2Vzcykge1xuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKGBUZXN0ICR7cHJvdmlkZXJ9IG5vdGlmaWNhdGlvbiBzZW50IWAsICdzdWNjZXNzJywgMzAwMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKGBUZXN0IGZhaWxlZDogJHtkYXRhLmVycm9yfWAsICdlcnJvcicsIDMwMDApO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBzaG93Tm90aWZpY2F0aW9uKGBFcnJvcjogJHtlcnJvci5tZXNzYWdlfWAsICdlcnJvcicsIDMwMDApO1xuICAgIH1cbiAgfVxuXG4gIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkaXNjb3JkLXRlc3QnKT8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB0ZXN0UHJvdmlkZXIoJ2Rpc2NvcmQnKSk7XG4gIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZWxlZ3JhbS10ZXN0Jyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4gdGVzdFByb3ZpZGVyKCd0ZWxlZ3JhbScpKTtcbiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ250ZnktdGVzdCcpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHRlc3RQcm92aWRlcignbnRmeScpKTtcbiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2VtYWlsLXRlc3QnKT8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB0ZXN0UHJvdmlkZXIoJ2VtYWlsJykpO1xuXG4gIC8vIEhlYWx0aCBjaGVjayBub3cgYnV0dG9uXG4gIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtY2hlY2stbm93Jyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHNlY3VyZUZldGNoKCcvYXBpL3YxL25vdGlmaWNhdGlvbnMvaGVhbHRoLWNoZWNrJywgeyBtZXRob2Q6ICdQT1NUJyB9KTtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG5cbiAgICAgIGlmIChkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1jaGVjay1zdGF0dXMnKS50ZXh0Q29udGVudCA9XG4gICAgICAgICAgYExhc3QgY2hlY2s6ICR7bmV3IERhdGUoZGF0YS5sYXN0Q2hlY2spLnRvTG9jYWxlU3RyaW5nKCl9ICgke2RhdGEuY29udGFpbmVyc01vbml0b3JlZH0gY29udGFpbmVycylgO1xuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKCdIZWFsdGggY2hlY2sgY29tcGxldGVkJywgJ3N1Y2Nlc3MnLCAyMDAwKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgc2hvd05vdGlmaWNhdGlvbihgRXJyb3I6ICR7ZXJyb3IubWVzc2FnZX1gLCAnZXJyb3InLCAzMDAwKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIE1vZGFsIGhhbmRsZXJzXG4gIG9wZW5CdG4/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgIG1vZGFsLmNsYXNzTGlzdC5hZGQoJ3Nob3cnKTtcbiAgICBsb2FkTm90aWZpY2F0aW9uQ29uZmlnKCk7XG4gICAgbG9hZE5vdGlmaWNhdGlvbkhpc3RvcnkoKTtcbiAgfSk7XG5cbiAgc2F2ZUJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBzYXZlTm90aWZpY2F0aW9uQ29uZmlnKTtcblxuICAvLyBTZW5kIFRlc3QgYnV0dG9uIC0gc2VuZHMgdGVzdCBub3RpZmljYXRpb24gdG8gYWxsIGVuYWJsZWQgcHJvdmlkZXJzXG4gIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdub3RpZmljYXRpb25zLXNlbmQtdGVzdCcpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBidG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbm90aWZpY2F0aW9ucy1zZW5kLXRlc3QnKTtcbiAgICBjb25zdCBvcmlnaW5hbFRleHQgPSBidG4udGV4dENvbnRlbnQ7XG4gICAgYnRuLnRleHRDb250ZW50ID0gJ1NlbmRpbmcuLi4nO1xuICAgIGJ0bi5kaXNhYmxlZCA9IHRydWU7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBzZWN1cmVGZXRjaCgnL2FwaS92MS9ub3RpZmljYXRpb25zL3NlbmQnLCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoeyBcbiAgICAgICAgICBldmVudDogJ3Rlc3QnLFxuICAgICAgICAgIGRhdGE6IHsgbWVzc2FnZTogJ1RoaXMgaXMgYSB0ZXN0IG5vdGlmaWNhdGlvbiBmcm9tIERhc2hDYWRkeS4nIH0sXG4gICAgICAgICAgdHlwZTogJ2luZm8nXG4gICAgICAgIH0pXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgIGlmIChkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgc2hvd05vdGlmaWNhdGlvbignVGVzdCBub3RpZmljYXRpb24gc2VudCEnLCAnc3VjY2VzcycsIDMwMDApO1xuICAgICAgICAvLyBVcGRhdGUgbGFzdCBzZW50IHRpbWVzdGFtcFxuICAgICAgICBsb2FkTm90aWZpY2F0aW9uU3RhdHVzKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKGBUZXN0IGZhaWxlZDogJHtkYXRhLnJlc3VsdHM/Lm1hcChyID0+IGAke3IucHJvdmlkZXJ9OiAke3IuZXJyb3IgfHwgJ29rJ31gKS5qb2luKCcsICcpfWAsICdlcnJvcicsIDUwMDApO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBzaG93Tm90aWZpY2F0aW9uKGBFcnJvcjogJHtlcnJvci5tZXNzYWdlfWAsICdlcnJvcicsIDMwMDApO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBidG4udGV4dENvbnRlbnQgPSBvcmlnaW5hbFRleHQ7XG4gICAgICBidG4uZGlzYWJsZWQgPSBmYWxzZTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIExvYWQgbm90aWZpY2F0aW9uIHN0YXR1cyAobGFzdCBzZW50IHRpbWVzdGFtcClcbiAgYXN5bmMgZnVuY3Rpb24gbG9hZE5vdGlmaWNhdGlvblN0YXR1cygpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS9ub3RpZmljYXRpb25zL3N0YXR1cycpO1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgIGlmIChkYXRhLnN1Y2Nlc3MgJiYgZGF0YS5sYXN0U2VudCkge1xuICAgICAgICBjb25zdCBsYXN0U2VudEVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2xhc3Qtbm90aWZpY2F0aW9uLXNlbnQnKTtcbiAgICAgICAgaWYgKGxhc3RTZW50RWwpIHtcbiAgICAgICAgICBsYXN0U2VudEVsLnRleHRDb250ZW50ID0gYExhc3Qgc2VudDogJHtuZXcgRGF0ZShkYXRhLmxhc3RTZW50KS50b0xvY2FsZVN0cmluZygpfWA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gU2lsZW50bHkgZmFpbCAtIHN0YXR1cyBpcyBub3QgY3JpdGljYWxcbiAgICB9XG4gIH1cblxuICB3aXJlTW9kYWwobW9kYWwsIGNhbmNlbEJ0bik7XG59KSgpO1xuO1xuLy8gPT09PT09PT09PSBQQU5FTCBUQUIgU1dJVENISU5HIChzaGFyZWQgdXRpbGl0eSkgPT09PT09PT09PVxuKGZ1bmN0aW9uKCkge1xuICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIChlKSA9PiB7XG4gICAgY29uc3QgdGFiID0gZS50YXJnZXQuY2xvc2VzdCgnLnBhbmVsLXRhYicpO1xuICAgIGlmICghdGFiKSByZXR1cm47XG4gICAgY29uc3QgcGFuZWxJZCA9IHRhYi5kYXRhc2V0LnBhbmVsO1xuICAgIGlmICghcGFuZWxJZCkgcmV0dXJuO1xuICAgIGNvbnN0IHRhYkJhciA9IHRhYi5jbG9zZXN0KCcucGFuZWwtdGFicycpO1xuICAgIGNvbnN0IG1vZGFsQ29udGVudCA9IHRhYkJhci5jbG9zZXN0KCcud2VhdGhlci1tb2RhbC1jb250ZW50Jyk7XG4gICAgdGFiQmFyLnF1ZXJ5U2VsZWN0b3JBbGwoJy5wYW5lbC10YWInKS5mb3JFYWNoKHQgPT4gdC5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKSk7XG4gICAgdGFiLmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZScpO1xuICAgIG1vZGFsQ29udGVudC5xdWVyeVNlbGVjdG9yQWxsKCcucGFuZWwtc2VjdGlvbicpLmZvckVhY2gocyA9PiBzLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpKTtcbiAgICBjb25zdCB0YXJnZXQgPSBtb2RhbENvbnRlbnQucXVlcnlTZWxlY3RvcignIycgKyBwYW5lbElkKTtcbiAgICBpZiAodGFyZ2V0KSB0YXJnZXQuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG4gIH0pO1xufSkoKTtcbjtcbi8vID09PT09PT09PT0gVU5JRklFRCBCQUNLVVAvUkVTVE9SRSB2Mi4wID09PT09PT09PT1cbi8vIFNpbmdsZSBmaWxlIGNhcHR1cmVzIGV2ZXJ5dGhpbmc6IHNlcnZlciBjb25maWcgKyBicm93c2VyIHN0YXRlICsgdGhlbWVzICsgZW5jcnlwdGlvbiBrZXlcbihmdW5jdGlvbigpIHtcbiAgLy8gQWxsIERhc2hDYWRkeSBsb2NhbFN0b3JhZ2Uga2V5cyB0byBpbmNsdWRlIGluIGJhY2t1cFxuICB2YXIgQlJPV1NFUl9TVEFURV9LRVlTID0gW1xuICAgICdkYXNoY2FkZHlfc2l0ZV9jb25maWcnLCAnZGFzaGNhZGR5X29uYm9hcmRpbmcnLCAnZGFzaGNhZGR5LWVuY3J5cHRpb24ta2V5JyxcbiAgICAnZGFzaGNhZGR5LXNldHVwJywgJ2Rhc2hjYWRkeS1jb25maWcnLFxuICAgICd0aGVtZScsICd1c2VyLXRoZW1lcycsICdjdXN0b20tdGhlbWUnLFxuICAgICdjdXN0b20tYXBwcycsICdjdXN0b20tc2VydmljZXMnLCAndG9vbGJhci1zZWN0aW9ucycsXG4gICAgJ3dlYXRoZXItbG9jYXRpb24nLCAnd2VhdGhlci16aXAnLCAnd2VhdGhlci1nZW8nLCAnd2VhdGhlci11bml0JyxcbiAgICAnY2xvY2stc3R5bGUnLCAnY2xvY2stY2hpbWVzJywgJ2Nsb2NrLWNoaW1lLXZvbHVtZSdcbiAgXTtcblxuICAvLyBDb2xsZWN0IGFsbCBEYXNoQ2FkZHkgYnJvd3NlciBzdGF0ZSBmcm9tIGxvY2FsU3RvcmFnZVxuICBmdW5jdGlvbiBjb2xsZWN0QnJvd3NlclN0YXRlKCkge1xuICAgIHZhciBzdGF0ZSA9IHt9O1xuICAgIC8vIEdyYWIgYWxsIHdoaXRlbGlzdGVkIGtleXNcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IEJST1dTRVJfU1RBVEVfS0VZUy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGtleSA9IEJST1dTRVJfU1RBVEVfS0VZU1tpXTtcbiAgICAgIHZhciB2YWwgPSBzYWZlR2V0KGtleSk7XG4gICAgICBpZiAodmFsICE9PSBudWxsICYmIHZhbCAhPT0gdW5kZWZpbmVkKSBzdGF0ZVtrZXldID0gdmFsO1xuICAgIH1cbiAgICAvLyBHcmFiIGR5bmFtaWMgd2lkZ2V0LSotZW5hYmxlZCBrZXlzXG4gICAgdHJ5IHtcbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbG9jYWxTdG9yYWdlLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIHZhciBrID0gbG9jYWxTdG9yYWdlLmtleShqKTtcbiAgICAgICAgaWYgKC9ed2lkZ2V0LS4rLWVuYWJsZWQkLy50ZXN0KGspKSB7XG4gICAgICAgICAgc3RhdGVba10gPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbShrKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHsgLyogcHJpdmF0ZSBicm93c2luZyAqLyB9XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG5cbiAgLy8gUmVzdG9yZSBicm93c2VyIHN0YXRlIGZyb20gYmFja3VwIGludG8gbG9jYWxTdG9yYWdlXG4gIGZ1bmN0aW9uIHJlc3RvcmVCcm93c2VyU3RhdGUoYnJvd3NlclN0YXRlKSB7XG4gICAgaWYgKCFicm93c2VyU3RhdGUgfHwgdHlwZW9mIGJyb3dzZXJTdGF0ZSAhPT0gJ29iamVjdCcpIHJldHVybiAwO1xuICAgIHZhciBjb3VudCA9IDA7XG4gICAgZm9yICh2YXIga2V5IGluIGJyb3dzZXJTdGF0ZSkge1xuICAgICAgaWYgKCFicm93c2VyU3RhdGUuaGFzT3duUHJvcGVydHkoa2V5KSkgY29udGludWU7XG4gICAgICBzYWZlU2V0KGtleSwgYnJvd3NlclN0YXRlW2tleV0pO1xuICAgICAgY291bnQrKztcbiAgICB9XG4gICAgcmV0dXJuIGNvdW50O1xuICB9XG5cbiAgLy8gSGFuZGxlIGxlZ2FjeSB2MS4wLjAgaW1wb3J0LWV4cG9ydCBmb3JtYXQgKHByZS1iYWNrdXAgbW9kYWwpXG4gIGZ1bmN0aW9uIGlzTGVnYWN5Rm9ybWF0KGRhdGEpIHtcbiAgICByZXR1cm4gZGF0YS52ZXJzaW9uICYmICFkYXRhLmZpbGVzICYmIGRhdGEuc2VydmljZXM7XG4gIH1cblxuICBmdW5jdGlvbiByZXN0b3JlTGVnYWN5Rm9ybWF0KGRhdGEpIHtcbiAgICAvLyBNYXAgdGhlIG9sZCBmbGF0IGtleXMgaW50byBicm93c2VyU3RhdGUgZm9yIGxvY2FsU3RvcmFnZSByZXN0b3JlXG4gICAgdmFyIGJyb3dzZXJTdGF0ZSA9IHt9O1xuICAgIGlmIChkYXRhLmN1c3RvbVNlcnZpY2VzKSBicm93c2VyU3RhdGVbJ2N1c3RvbS1zZXJ2aWNlcyddID0gSlNPTi5zdHJpbmdpZnkoZGF0YS5jdXN0b21TZXJ2aWNlcyk7XG4gICAgaWYgKGRhdGEuY3VzdG9tQXBwcykgYnJvd3NlclN0YXRlWydjdXN0b20tYXBwcyddID0gSlNPTi5zdHJpbmdpZnkoZGF0YS5jdXN0b21BcHBzKTtcbiAgICBpZiAoZGF0YS53ZWF0aGVyWmlwKSBicm93c2VyU3RhdGVbJ3dlYXRoZXItemlwJ10gPSBkYXRhLndlYXRoZXJaaXA7XG4gICAgaWYgKGRhdGEudGhlbWUpIGJyb3dzZXJTdGF0ZVsndGhlbWUnXSA9IGRhdGEudGhlbWU7XG4gICAgaWYgKGRhdGEudXNlclRoZW1lcyAmJiBPYmplY3Qua2V5cyhkYXRhLnVzZXJUaGVtZXMpLmxlbmd0aCkgYnJvd3NlclN0YXRlWyd1c2VyLXRoZW1lcyddID0gSlNPTi5zdHJpbmdpZnkoZGF0YS51c2VyVGhlbWVzKTtcbiAgICByZXN0b3JlQnJvd3NlclN0YXRlKGJyb3dzZXJTdGF0ZSk7XG5cbiAgICAvLyBQdXNoIHNlcnZpY2VzIHRvIHNlcnZlciBpZiBhdmFpbGFibGVcbiAgICBpZiAoZGF0YS5zZXJ2aWNlcyAmJiBBcnJheS5pc0FycmF5KGRhdGEuc2VydmljZXMpKSB7XG4gICAgICBzZWN1cmVGZXRjaCgnL2FwaS92MS9zZXJ2aWNlcycsIHtcbiAgICAgICAgbWV0aG9kOiAnUFVUJyxcbiAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGRhdGEuc2VydmljZXMpXG4gICAgICB9KS5jYXRjaChmdW5jdGlvbigpIHt9KTtcbiAgICB9XG5cbiAgICAvLyBQdXNoIHRoZW1lcyB0byBzZXJ2ZXIgaWYgYXZhaWxhYmxlXG4gICAgaWYgKGRhdGEudXNlclRoZW1lcykge1xuICAgICAgT2JqZWN0LmtleXMoZGF0YS51c2VyVGhlbWVzKS5mb3JFYWNoKGZ1bmN0aW9uKHNsdWcpIHtcbiAgICAgICAgdmFyIHQgPSBkYXRhLnVzZXJUaGVtZXNbc2x1Z107XG4gICAgICAgIHZhciBjb2xvcnMgPSB7fTtcbiAgICAgICAgKHdpbmRvdy5USEVNRV9QUk9QUyB8fCBbXSkuZm9yRWFjaChmdW5jdGlvbihwKSB7IGlmICh0W3BdKSBjb2xvcnNbcF0gPSB0W3BdOyB9KTtcbiAgICAgICAgc2VjdXJlRmV0Y2goJy9hcGkvdjEvdGhlbWVzLycgKyBzbHVnLCB7XG4gICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoeyBuYW1lOiB0Lm5hbWUgfHwgc2x1ZywgY29sb3JzOiBjb2xvcnMgfSlcbiAgICAgICAgfSkuY2F0Y2goZnVuY3Rpb24oKSB7fSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvLyBJbmplY3QgbW9kYWwgSFRNTFxuICBpbmplY3RNb2RhbCgnYmFja3VwLW1vZGFsJywgYDxkaXYgaWQ9XCJiYWNrdXAtbW9kYWxcIiBjbGFzcz1cIndlYXRoZXItbW9kYWxcIj5cbiAgICA8ZGl2IGNsYXNzPVwid2VhdGhlci1tb2RhbC1jb250ZW50XCIgc3R5bGU9XCJtaW4td2lkdGg6IDU1MHB4OyBtYXgtd2lkdGg6IDY1MHB4O1wiPlxuICAgICAgPGgzPlx1RDgzRFx1RENCRSBCYWNrdXAgJiBSZXN0b3JlPC9oMz5cbiAgICAgIDxwIGNsYXNzPVwibW9kYWwtc3VidGl0bGVcIj5cbiAgICAgICAgRnVsbCBiYWNrdXAgb2YgeW91ciBlbnRpcmUgRGFzaENhZGR5IHNldHVwIFx1MjAxNCBzZXJ2ZXIgY29uZmlnLCBjcmVkZW50aWFscywgdGhlbWVzLCBhbmQgYnJvd3NlciBwcmVmZXJlbmNlcyBpbiBvbmUgZmlsZS5cbiAgICAgIDwvcD5cblxuICAgICAgPCEtLSBUYWIgYmFyIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cInBhbmVsLXRhYnNcIj5cbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInBhbmVsLXRhYiBhY3RpdmVcIiBkYXRhLXBhbmVsPVwiYmFja3VwLW1hbnVhbFwiPk1hbnVhbDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwicGFuZWwtdGFiXCIgZGF0YS1wYW5lbD1cImJhY2t1cC1zY2hlZHVsZXMtdGFiXCI+U2NoZWR1bGVzPC9idXR0b24+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJwYW5lbC10YWJcIiBkYXRhLXBhbmVsPVwiYmFja3VwLWRpc2stdGFiXCI+QmFja3VwcyBvbiBEaXNrPC9idXR0b24+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJwYW5lbC10YWJcIiBkYXRhLXBhbmVsPVwiYmFja3VwLXBvaW50aW50aW1lLXRhYlwiPlBvaW50LWluLVRpbWU8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInBhbmVsLXRhYlwiIGRhdGEtcGFuZWw9XCJiYWNrdXAtaGlzdG9yeS10YWJcIj5IaXN0b3J5PC9idXR0b24+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBUYWI6IE1hbnVhbCAtLT5cbiAgICAgIDxkaXYgaWQ9XCJiYWNrdXAtbWFudWFsXCIgY2xhc3M9XCJwYW5lbC1zZWN0aW9uIGFjdGl2ZVwiPlxuICAgICAgICA8IS0tIEV4cG9ydCBTZWN0aW9uIC0tPlxuICAgICAgICA8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMjBweDsgcGFkZGluZzogMTZweDsgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgY29sb3ItbWl4KGluIHNyZ2IsICMyN2FlNjAgMTUlLCB0cmFuc3BhcmVudCksIGNvbG9yLW1peChpbiBzcmdiLCAjMmVjYzcxIDEwJSwgdHJhbnNwYXJlbnQpKTsgYm9yZGVyLXJhZGl1czogMTBweDsgYm9yZGVyOiAxcHggc29saWQgIzI3YWU2MDtcIj5cbiAgICAgICAgICA8aDQgc3R5bGU9XCJtYXJnaW46IDAgMCA4cHg7IGNvbG9yOiAjMmVjYzcxOyBmb250LXNpemU6IDAuOTVyZW07XCI+XHVEODNEXHVEQ0U0IEV4cG9ydCBCYWNrdXA8L2g0PlxuICAgICAgICAgIDxwIHN0eWxlPVwiZm9udC1zaXplOiAwLjhyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbjogMCAwIDEycHg7XCI+XG4gICAgICAgICAgICBEb3dubG9hZHMgZXZlcnl0aGluZyBcdTIwMTQgc2VydmljZXMsIENhZGR5ZmlsZSwgY3JlZGVudGlhbHMsIGVuY3J5cHRpb24ga2V5LCB0aGVtZXMsIGFuZCBhbGwgYnJvd3NlciBwcmVmZXJlbmNlcy5cbiAgICAgICAgICA8L3A+XG4gICAgICAgICAgPGJ1dHRvbiBpZD1cImJhY2t1cC1leHBvcnQtYnRuXCIgc3R5bGU9XCJ3aWR0aDogMTAwJTsgcGFkZGluZzogMTBweDsgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgIzI3YWU2MCAwJSwgIzJlY2M3MSAxMDAlKTsgYm9yZGVyOiBub25lOyBjb2xvcjogd2hpdGU7IGZvbnQtd2VpZ2h0OiA2MDA7IGJvcmRlci1yYWRpdXM6IDhweDsgY3Vyc29yOiBwb2ludGVyO1wiPlxuICAgICAgICAgICAgXHUyQjA3XHVGRTBGIERvd25sb2FkIEZ1bGwgQmFja3VwXG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gSW1wb3J0IFNlY3Rpb24gLS0+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJwYWRkaW5nOiAxNnB4OyBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTM1ZGVnLCBjb2xvci1taXgoaW4gc3JnYiwgIzM0OThkYiAxNSUsIHRyYW5zcGFyZW50KSwgY29sb3ItbWl4KGluIHNyZ2IsICMyOTgwYjkgMTAlLCB0cmFuc3BhcmVudCkpOyBib3JkZXItcmFkaXVzOiAxMHB4OyBib3JkZXI6IDFweCBzb2xpZCAjMzQ5OGRiO1wiPlxuICAgICAgICAgIDxoNCBzdHlsZT1cIm1hcmdpbjogMCAwIDhweDsgY29sb3I6ICMzNDk4ZGI7IGZvbnQtc2l6ZTogMC45NXJlbTtcIj5cdUQ4M0RcdURDRTUgUmVzdG9yZSBCYWNrdXA8L2g0PlxuICAgICAgICAgIDxwIHN0eWxlPVwiZm9udC1zaXplOiAwLjhyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbjogMCAwIDEycHg7XCI+XG4gICAgICAgICAgICBVcGxvYWQgYSBiYWNrdXAgZmlsZSB0byByZXN0b3JlIHlvdXIgZW50aXJlIGNvbmZpZ3VyYXRpb24gXHUyMDE0IGRyYWcgYW5kIGRyb3AgcmVhZHkuXG4gICAgICAgICAgPC9wPlxuICAgICAgICAgIDxpbnB1dCB0eXBlPVwiZmlsZVwiIGlkPVwiYmFja3VwLWZpbGUtaW5wdXRcIiBhY2NlcHQ9XCIuanNvblwiIHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIiAvPlxuICAgICAgICAgIDxidXR0b24gaWQ9XCJiYWNrdXAtc2VsZWN0LWZpbGVcIiBzdHlsZT1cIndpZHRoOiAxMDAlOyBwYWRkaW5nOiAxMHB4OyBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTM1ZGVnLCAjMzQ5OGRiIDAlLCAjMjk4MGI5IDEwMCUpOyBib3JkZXI6IG5vbmU7IGNvbG9yOiB3aGl0ZTsgZm9udC13ZWlnaHQ6IDYwMDsgYm9yZGVyLXJhZGl1czogOHB4OyBjdXJzb3I6IHBvaW50ZXI7XCI+XG4gICAgICAgICAgICBcdUQ4M0RcdURDQzEgU2VsZWN0IEJhY2t1cCBGaWxlXG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPGRpdiBpZD1cImJhY2t1cC1maWxlLW5hbWVcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7IG1hcmdpbi10b3A6IDhweDsgcGFkZGluZzogOHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJhc2UpOyBib3JkZXItcmFkaXVzOiA2cHg7IGZvbnQtc2l6ZTogMC44NXJlbTtcIj48L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBQcmV2aWV3IFNlY3Rpb24gKHNob3duIGFmdGVyIGZpbGUgc2VsZWN0ZWQpIC0tPlxuICAgICAgICA8ZGl2IGlkPVwiYmFja3VwLXByZXZpZXdcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7IG1hcmdpbi10b3A6IDE2cHg7IHBhZGRpbmc6IDE2cHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmFzZSk7IGJvcmRlci1yYWRpdXM6IDEwcHg7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XCI+XG4gICAgICAgICAgPGg0IHN0eWxlPVwibWFyZ2luOiAwIDAgMTJweDsgZm9udC1zaXplOiAwLjlyZW07XCI+XHVEODNEXHVEQ0NCIEJhY2t1cCBDb250ZW50czwvaDQ+XG4gICAgICAgICAgPGRpdiBpZD1cImJhY2t1cC1wcmV2aWV3LWNvbnRlbnRcIiBzdHlsZT1cImZvbnQtc2l6ZTogMC44NXJlbTtcIj48L2Rpdj5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwibWFyZ2luLXRvcDogMTJweDsgcGFkZGluZy10b3A6IDEycHg7IGJvcmRlci10b3A6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1wiPlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY2hlY2tib3gtbGFiZWxcIiBzdHlsZT1cImZvbnQtc2l6ZTogMC44NXJlbTtcIj5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGlkPVwiYmFja3VwLXJlbG9hZC1jYWRkeVwiIGNoZWNrZWQgLz5cbiAgICAgICAgICAgICAgUmVsb2FkIENhZGR5IGFmdGVyIHJlc3RvcmVcbiAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGJ1dHRvbiBpZD1cImJhY2t1cC1kby1yZXN0b3JlLWJ0blwiIHN0eWxlPVwid2lkdGg6IDEwMCU7IG1hcmdpbi10b3A6IDEycHg7IHBhZGRpbmc6IDEwcHg7IGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsICNlNzRjM2MgMCUsICNjMDM5MmIgMTAwJSk7IGJvcmRlcjogbm9uZTsgY29sb3I6IHdoaXRlOyBmb250LXdlaWdodDogNjAwOyBib3JkZXItcmFkaXVzOiA4cHg7IGN1cnNvcjogcG9pbnRlcjtcIj5cbiAgICAgICAgICAgIFx1MjZBMSBSZXN0b3JlIEV2ZXJ5dGhpbmdcbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBSZXN1bHQgTWVzc2FnZSAtLT5cbiAgICAgICAgPGRpdiBpZD1cImJhY2t1cC1yZXN1bHRcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7IG1hcmdpbi10b3A6IDE2cHg7IHBhZGRpbmc6IDEycHg7IGJvcmRlci1yYWRpdXM6IDhweDtcIj48L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIFRhYjogU2NoZWR1bGVzIChQcmVtaXVtKSAtLT5cbiAgICAgIDxkaXYgaWQ9XCJiYWNrdXAtc2NoZWR1bGVzLXRhYlwiIGNsYXNzPVwicGFuZWwtc2VjdGlvblwiPlxuICAgICAgICA8ZGl2IGlkPVwiYmFja3VwLXNjaGVkdWxlcy1jb250YWluZXJcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZW1wdHktaWNvblwiPlx1MjNGMDwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYnJhbmQtc3Bpbm5lclwiPjwvc3Bhbj4gTG9hZGluZyBzY2hlZHVsZXMuLi5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBUYWI6IEJhY2t1cHMgb24gRGlzayAtLT5cbiAgICAgIDxkaXYgaWQ9XCJiYWNrdXAtZGlzay10YWJcIiBjbGFzcz1cInBhbmVsLXNlY3Rpb25cIj5cbiAgICAgICAgPGRpdiBpZD1cImJhY2t1cC1kaXNrLWNvbnRhaW5lclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJlbXB0eS1pY29uXCI+XHVEODNEXHVEQ0JFPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJicmFuZC1zcGlubmVyXCI+PC9zcGFuPiBMb2FkaW5nIGJhY2t1cCBmaWxlcy4uLlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIFRhYjogUG9pbnQtaW4tVGltZSBSZXN0b3JlIC0tPlxuICAgICAgPGRpdiBpZD1cImJhY2t1cC1wb2ludGludGltZS10YWJcIiBjbGFzcz1cInBhbmVsLXNlY3Rpb25cIj5cbiAgICAgICAgPGRpdiBpZD1cInBvaW50aW50aW1lLWNvbnRhaW5lclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJlbXB0eS1pY29uXCI+XHUyM0VBPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJicmFuZC1zcGlubmVyXCI+PC9zcGFuPiBMb2FkaW5nLi4uXG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gVGFiOiBCYWNrdXAgSGlzdG9yeSAtLT5cbiAgICAgIDxkaXYgaWQ9XCJiYWNrdXAtaGlzdG9yeS10YWJcIiBjbGFzcz1cInBhbmVsLXNlY3Rpb25cIj5cbiAgICAgICAgPGRpdiBpZD1cImJhY2t1cC1oaXN0b3J5LWNvbnRhaW5lclwiIHN0eWxlPVwibWF4LWhlaWdodDogNDAwcHg7IG92ZXJmbG93LXk6IGF1dG87XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImVtcHR5LWljb25cIj5cdUQ4M0RcdURDQ0I8L3NwYW4+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJyYW5kLXNwaW5uZXJcIj48L3NwYW4+IExvYWRpbmcgYmFja3VwIGhpc3RvcnkuLi5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBDbG9zZSBCdXR0b24gLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwid2VhdGhlci1tb2RhbC1idXR0b25zIG1vZGFsLWZvb3Rlci1iYXJcIj5cbiAgICAgICAgPGJ1dHRvbiBpZD1cImJhY2t1cC1jYW5jZWxcIj5DbG9zZTwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PmApO1xuXG4gIHZhciBtb2RhbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiYWNrdXAtbW9kYWwnKTtcbiAgdmFyIG9wZW5CdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYmFja3VwLXJlc3RvcmUtYnRuJyk7XG4gIHZhciBjYW5jZWxCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYmFja3VwLWNhbmNlbCcpO1xuICB2YXIgZXhwb3J0QnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2JhY2t1cC1leHBvcnQtYnRuJyk7XG4gIHZhciBzZWxlY3RGaWxlQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2JhY2t1cC1zZWxlY3QtZmlsZScpO1xuICB2YXIgZmlsZUlucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2JhY2t1cC1maWxlLWlucHV0Jyk7XG4gIHZhciBmaWxlTmFtZURpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiYWNrdXAtZmlsZS1uYW1lJyk7XG4gIHZhciBwcmV2aWV3RGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2JhY2t1cC1wcmV2aWV3Jyk7XG4gIHZhciBwcmV2aWV3Q29udGVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiYWNrdXAtcHJldmlldy1jb250ZW50Jyk7XG4gIHZhciByZXN0b3JlQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2JhY2t1cC1kby1yZXN0b3JlLWJ0bicpO1xuICB2YXIgcmVzdWx0RGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2JhY2t1cC1yZXN1bHQnKTtcbiAgdmFyIHNjaGVkdWxlQ29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2JhY2t1cC1zY2hlZHVsZXMtY29udGFpbmVyJyk7XG4gIHZhciBoaXN0b3J5Q29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2JhY2t1cC1oaXN0b3J5LWNvbnRhaW5lcicpO1xuICB2YXIgZGlza0NvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiYWNrdXAtZGlzay1jb250YWluZXInKTtcbiAgdmFyIHBvaW50aW50aW1lQ29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BvaW50aW50aW1lLWNvbnRhaW5lcicpO1xuXG4gIHZhciBzZWxlY3RlZEJhY2t1cCA9IG51bGw7XG5cbiAgLy8gT3BlbiBtb2RhbFxuICBvcGVuQnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgIG1vZGFsLmNsYXNzTGlzdC5hZGQoJ3Nob3cnKTtcbiAgICBpZiAocmVzdWx0RGl2KSByZXN1bHREaXYuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICBpZiAocHJldmlld0RpdikgcHJldmlld0Rpdi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIGlmIChmaWxlTmFtZURpdikgZmlsZU5hbWVEaXYuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICBzZWxlY3RlZEJhY2t1cCA9IG51bGw7XG4gIH0pO1xuXG4gIHdpcmVNb2RhbChtb2RhbCwgY2FuY2VsQnRuKTtcblxuICAvLyA9PT0gRVhQT1JUOiBTZXJ2ZXIgYmFja3VwICsgYnJvd3NlciBzdGF0ZSBpbiBvbmUgZmlsZSA9PT1cbiAgZXhwb3J0QnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jIGZ1bmN0aW9uKCkge1xuICAgIGV4cG9ydEJ0bi5kaXNhYmxlZCA9IHRydWU7XG4gICAgZXhwb3J0QnRuLmlubmVySFRNTCA9ICc8c3BhbiBjbGFzcz1cImJyYW5kLXNwaW5uZXJcIj48L3NwYW4+IEV4cG9ydGluZy4uLic7XG4gICAgdHJ5IHtcbiAgICAgIC8vIEZldGNoIHNlcnZlci1zaWRlIGJhY2t1cCAoY29uZmlnLCBzZXJ2aWNlcywgY2FkZHlmaWxlLCBjcmVkZW50aWFscywgZW5jcnlwdGlvbiBrZXksIHRoZW1lcywgZXRjLilcbiAgICAgIHZhciByZXNwb25zZSA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL2JhY2t1cC9leHBvcnQnKTtcbiAgICAgIHZhciBkYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuXG4gICAgICAvLyBBZGQgYWxsIGJyb3dzZXIgbG9jYWxTdG9yYWdlIHN0YXRlXG4gICAgICBkYXRhLmJyb3dzZXJTdGF0ZSA9IGNvbGxlY3RCcm93c2VyU3RhdGUoKTtcblxuICAgICAgLy8gRG93bmxvYWQgdW5pZmllZCBiYWNrdXBcbiAgICAgIHZhciBibG9iID0gbmV3IEJsb2IoW0pTT04uc3RyaW5naWZ5KGRhdGEsIG51bGwsIDIpXSwgeyB0eXBlOiAnYXBwbGljYXRpb24vanNvbicgfSk7XG4gICAgICB2YXIgdXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICAgIHZhciBhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xuICAgICAgYS5ocmVmID0gdXJsO1xuICAgICAgYS5kb3dubG9hZCA9ICdkYXNoY2FkZHktYmFja3VwLScgKyBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCkuc3BsaXQoJ1QnKVswXSArICcuanNvbic7XG4gICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGEpO1xuICAgICAgYS5jbGljaygpO1xuICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChhKTtcbiAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwodXJsKTtcblxuICAgICAgdmFyIHN0YXRlQ291bnQgPSBPYmplY3Qua2V5cyhkYXRhLmJyb3dzZXJTdGF0ZSkubGVuZ3RoO1xuICAgICAgdmFyIHRoZW1lQ291bnQgPSBkYXRhLnRoZW1lcyA/IE9iamVjdC5rZXlzKGRhdGEudGhlbWVzKS5sZW5ndGggOiAwO1xuICAgICAgcmVzdWx0RGl2LmlubmVySFRNTCA9ICdcdTI3MDUgRnVsbCBiYWNrdXAgZG93bmxvYWRlZCBcdTIwMTQgc2VydmVyIGNvbmZpZyArICcgKyBzdGF0ZUNvdW50ICsgJyBicm93c2VyIHNldHRpbmdzJyArICh0aGVtZUNvdW50ID8gJyArICcgKyB0aGVtZUNvdW50ICsgJyB0aGVtZXMnIDogJycpO1xuICAgICAgcmVzdWx0RGl2LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgcmVzdWx0RGl2LnN0eWxlLmJhY2tncm91bmQgPSAnY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLW9rLWZnKSAxNSUsIHRyYW5zcGFyZW50KSc7XG4gICAgICByZXN1bHREaXYuc3R5bGUuYm9yZGVyID0gJzFweCBzb2xpZCB2YXIoLS1vay1mZyknO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJlc3VsdERpdi5pbm5lckhUTUwgPSAnXHUyNzRDIEV4cG9ydCBmYWlsZWQ6ICcgKyBlc2NhcGVIdG1sKGUubWVzc2FnZSk7XG4gICAgICByZXN1bHREaXYuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICByZXN1bHREaXYuc3R5bGUuYmFja2dyb3VuZCA9ICdjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tYmFkLWZnKSAxNSUsIHRyYW5zcGFyZW50KSc7XG4gICAgICByZXN1bHREaXYuc3R5bGUuYm9yZGVyID0gJzFweCBzb2xpZCB2YXIoLS1iYWQtZmcpJztcbiAgICB9XG4gICAgZXhwb3J0QnRuLmRpc2FibGVkID0gZmFsc2U7XG4gICAgZXhwb3J0QnRuLmlubmVySFRNTCA9ICdcdTJCMDdcdUZFMEYgRG93bmxvYWQgRnVsbCBCYWNrdXAnO1xuICB9KTtcblxuICAvLyBTZWxlY3QgZmlsZSBidXR0b25cbiAgc2VsZWN0RmlsZUJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbigpIHsgZmlsZUlucHV0LmNsaWNrKCk7IH0pO1xuXG4gIC8vID09PSBGSUxFIFNFTEVDVEVEOiBQcmV2aWV3IGNvbnRlbnRzID09PVxuICBmaWxlSW5wdXQ/LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIGFzeW5jIGZ1bmN0aW9uKGUpIHtcbiAgICB2YXIgZmlsZSA9IGUudGFyZ2V0LmZpbGVzWzBdO1xuICAgIGlmICghZmlsZSkgcmV0dXJuO1xuICAgIGZpbGVOYW1lRGl2LnRleHRDb250ZW50ID0gJ1x1RDgzRFx1RENDNCAnICsgZmlsZS5uYW1lO1xuICAgIGZpbGVOYW1lRGl2LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgIHJlc3VsdERpdi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIHRyeSB7XG4gICAgICB2YXIgdGV4dCA9IGF3YWl0IGZpbGUudGV4dCgpO1xuICAgICAgdmFyIGJhY2t1cCA9IEpTT04ucGFyc2UodGV4dCk7XG5cbiAgICAgIC8vIEhhbmRsZSBsZWdhY3kgdjEuMC4wIGZvcm1hdCAoZnJvbSBvbGQgaW1wb3J0LWV4cG9ydC5qcylcbiAgICAgIGlmIChpc0xlZ2FjeUZvcm1hdChiYWNrdXApKSB7XG4gICAgICAgIHNlbGVjdGVkQmFja3VwID0gYmFja3VwO1xuICAgICAgICB2YXIgaHRtbCA9ICc8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbTogOHB4OyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBmb250LXNpemU6IDAuOHJlbTtcIj5MZWdhY3kgZm9ybWF0ICh2JyArIGVzY2FwZUh0bWwoYmFja3VwLnZlcnNpb24pICsgJyk8L2Rpdj4nO1xuICAgICAgICBodG1sICs9ICc8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgZmxleC13cmFwOiB3cmFwOyBnYXA6IDZweDtcIj4nO1xuICAgICAgICBpZiAoYmFja3VwLnNlcnZpY2VzPy5sZW5ndGgpIGh0bWwgKz0gJzxzcGFuIHN0eWxlPVwicGFkZGluZzogNHB4IDhweDsgYmFja2dyb3VuZDogdmFyKC0tYmFzZSk7IGJvcmRlci1yYWRpdXM6IDRweDsgZm9udC1zaXplOiAwLjhyZW07XCI+XHVEODNEXHVEQ0NCICcgKyBiYWNrdXAuc2VydmljZXMubGVuZ3RoICsgJyBzZXJ2aWNlczwvc3Bhbj4nO1xuICAgICAgICBpZiAoYmFja3VwLmN1c3RvbUFwcHM/Lmxlbmd0aCkgaHRtbCArPSAnPHNwYW4gc3R5bGU9XCJwYWRkaW5nOiA0cHggOHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1iYXNlKTsgYm9yZGVyLXJhZGl1czogNHB4OyBmb250LXNpemU6IDAuOHJlbTtcIj5cdUQ4M0RcdURDRTYgJyArIGJhY2t1cC5jdXN0b21BcHBzLmxlbmd0aCArICcgY3VzdG9tIGFwcHM8L3NwYW4+JztcbiAgICAgICAgaWYgKGJhY2t1cC50aGVtZSkgaHRtbCArPSAnPHNwYW4gc3R5bGU9XCJwYWRkaW5nOiA0cHggOHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1iYXNlKTsgYm9yZGVyLXJhZGl1czogNHB4OyBmb250LXNpemU6IDAuOHJlbTtcIj5cdUQ4M0NcdURGQTggVGhlbWU6ICcgKyBlc2NhcGVIdG1sKGJhY2t1cC50aGVtZSkgKyAnPC9zcGFuPic7XG4gICAgICAgIGlmIChiYWNrdXAudXNlclRoZW1lcykgaHRtbCArPSAnPHNwYW4gc3R5bGU9XCJwYWRkaW5nOiA0cHggOHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1iYXNlKTsgYm9yZGVyLXJhZGl1czogNHB4OyBmb250LXNpemU6IDAuOHJlbTtcIj5cdUQ4M0NcdURGQTggJyArIE9iamVjdC5rZXlzKGJhY2t1cC51c2VyVGhlbWVzKS5sZW5ndGggKyAnIGN1c3RvbSB0aGVtZXM8L3NwYW4+JztcbiAgICAgICAgaHRtbCArPSAnPC9kaXY+JztcbiAgICAgICAgcHJldmlld0NvbnRlbnQuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgICAgcHJldmlld0Rpdi5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyB2MS4xKyAvIHYyLjAgZm9ybWF0IFx1MjAxNCBzZW5kIHRvIHNlcnZlciBmb3IgcHJldmlld1xuICAgICAgdmFyIHJlc3BvbnNlID0gYXdhaXQgc2VjdXJlRmV0Y2goJy9hcGkvdjEvYmFja3VwL3ByZXZpZXcnLCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoYmFja3VwKVxuICAgICAgfSk7XG4gICAgICB2YXIgcHJldmlldyA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgIGlmIChwcmV2aWV3LnN1Y2Nlc3MpIHtcbiAgICAgICAgc2VsZWN0ZWRCYWNrdXAgPSBiYWNrdXA7XG4gICAgICAgIHZhciBodG1sID0gJzxkaXYgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiA4cHg7IGNvbG9yOiB2YXIoLS1tdXRlZCk7IGZvbnQtc2l6ZTogMC44cmVtO1wiPkV4cG9ydGVkOiAnICsgbmV3IERhdGUoYmFja3VwLmV4cG9ydGVkQXQpLnRvTG9jYWxlU3RyaW5nKCkgKyAnICh2JyArIGVzY2FwZUh0bWwoYmFja3VwLnZlcnNpb24pICsgJyk8L2Rpdj4nO1xuXG4gICAgICAgIC8vIFNlcnZlciBmaWxlc1xuICAgICAgICBodG1sICs9ICc8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbTogNnB4OyBmb250LXNpemU6IDAuNzVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IHRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7IGxldHRlci1zcGFjaW5nOiAwLjVweDtcIj5TZXJ2ZXIgQ29uZmlnPC9kaXY+JztcbiAgICAgICAgaHRtbCArPSAnPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGZsZXgtd3JhcDogd3JhcDsgZ2FwOiA2cHg7IG1hcmdpbi1ib3R0b206IDEwcHg7XCI+JztcbiAgICAgICAgZm9yICh2YXIga2V5IGluIHByZXZpZXcucHJldmlldy5maWxlcykge1xuICAgICAgICAgIHZhciBpbmZvID0gcHJldmlldy5wcmV2aWV3LmZpbGVzW2tleV07XG4gICAgICAgICAgdmFyIGljb24gPSBpbmZvLmFjdGlvbiA9PT0gJ2NyZWF0ZScgPyAnXHVEODNDXHVERDk1JyA6ICdcdUQ4M0RcdURDREQnO1xuICAgICAgICAgIGh0bWwgKz0gJzxzcGFuIHN0eWxlPVwicGFkZGluZzogNHB4IDhweDsgYmFja2dyb3VuZDogdmFyKC0tYmFzZSk7IGJvcmRlci1yYWRpdXM6IDRweDsgZm9udC1zaXplOiAwLjhyZW07XCI+JyArIGljb24gKyAnICcgKyBlc2NhcGVIdG1sKGluZm8uZGVzY3JpcHRpb24pICsgJzwvc3Bhbj4nO1xuICAgICAgICB9XG4gICAgICAgIGh0bWwgKz0gJzwvZGl2Pic7XG5cbiAgICAgICAgLy8gU2VydmljZXMgY291bnRcbiAgICAgICAgaWYgKHByZXZpZXcucHJldmlldy5zZXJ2aWNlQ291bnQpIHtcbiAgICAgICAgICBodG1sICs9ICc8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjhyZW07IGNvbG9yOiB2YXIoLS1hY2NlbnQpOyBtYXJnaW4tYm90dG9tOiA2cHg7XCI+JyArIHByZXZpZXcucHJldmlldy5zZXJ2aWNlQ291bnQgKyAnIHNlcnZpY2VzPC9kaXY+JztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRoZW1lc1xuICAgICAgICBpZiAocHJldmlldy5wcmV2aWV3LnRoZW1lQ291bnQpIHtcbiAgICAgICAgICBodG1sICs9ICc8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjhyZW07IGNvbG9yOiB2YXIoLS1hY2NlbnQpOyBtYXJnaW4tYm90dG9tOiA2cHg7XCI+XHVEODNDXHVERkE4ICcgKyBwcmV2aWV3LnByZXZpZXcudGhlbWVDb3VudCArICcgY3VzdG9tIHRoZW1lczwvZGl2Pic7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBCcm93c2VyIHN0YXRlXG4gICAgICAgIGlmIChwcmV2aWV3LnByZXZpZXcuYnJvd3NlclN0YXRlQ291bnQpIHtcbiAgICAgICAgICBodG1sICs9ICc8ZGl2IHN0eWxlPVwibWFyZ2luLXRvcDogNnB4OyBmb250LXNpemU6IDAuNzVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IHRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7IGxldHRlci1zcGFjaW5nOiAwLjVweDtcIj5Ccm93c2VyIFByZWZlcmVuY2VzPC9kaXY+JztcbiAgICAgICAgICBodG1sICs9ICc8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjhyZW07IGNvbG9yOiB2YXIoLS1hY2NlbnQpO1wiPlx1RDgzRFx1RERBNVx1RkUwRiAnICsgcHJldmlldy5wcmV2aWV3LmJyb3dzZXJTdGF0ZUNvdW50ICsgJyBzYXZlZCBzZXR0aW5ncyAodGhlbWUsIHdlYXRoZXIsIGNsb2NrLCB3aWRnZXRzLCBldGMuKTwvZGl2Pic7XG4gICAgICAgIH1cblxuICAgICAgICBwcmV2aWV3Q29udGVudC5pbm5lckhUTUwgPSBodG1sO1xuICAgICAgICBwcmV2aWV3RGl2LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0RGl2LmlubmVySFRNTCA9ICdcdTI2QTBcdUZFMEYgSW52YWxpZCBiYWNrdXAgZmlsZTogJyArIGVzY2FwZUh0bWwocHJldmlldy5lcnJvcik7XG4gICAgICAgIHJlc3VsdERpdi5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgICAgcmVzdWx0RGl2LnN0eWxlLmJhY2tncm91bmQgPSAnY29sb3ItbWl4KGluIHNyZ2IsICNmMzljMTIgMTUlLCB0cmFuc3BhcmVudCknO1xuICAgICAgICByZXN1bHREaXYuc3R5bGUuYm9yZGVyID0gJzFweCBzb2xpZCAjZjM5YzEyJztcbiAgICAgICAgcHJldmlld0Rpdi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJlc3VsdERpdi5pbm5lckhUTUwgPSAnXHUyNzRDIENvdWxkIG5vdCByZWFkIGZpbGU6ICcgKyBlc2NhcGVIdG1sKGUubWVzc2FnZSk7XG4gICAgICByZXN1bHREaXYuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICByZXN1bHREaXYuc3R5bGUuYmFja2dyb3VuZCA9ICdjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tYmFkLWZnKSAxNSUsIHRyYW5zcGFyZW50KSc7XG4gICAgICByZXN1bHREaXYuc3R5bGUuYm9yZGVyID0gJzFweCBzb2xpZCB2YXIoLS1iYWQtZmcpJztcbiAgICAgIHByZXZpZXdEaXYuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICB9XG4gIH0pO1xuXG4gIC8vID09PSBSRVNUT1JFOiBTZXJ2ZXIgKyBicm93c2VyIHN0YXRlID09PVxuICByZXN0b3JlQnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jIGZ1bmN0aW9uKCkge1xuICAgIGlmICghc2VsZWN0ZWRCYWNrdXApIHJldHVybjtcbiAgICBpZiAoIWNvbmZpcm0oJ1RoaXMgd2lsbCBvdmVyd3JpdGUgeW91ciBjdXJyZW50IGNvbmZpZ3VyYXRpb24gYW5kIGJyb3dzZXIgcHJlZmVyZW5jZXMuIENvbnRpbnVlPycpKSByZXR1cm47XG4gICAgcmVzdG9yZUJ0bi5kaXNhYmxlZCA9IHRydWU7XG4gICAgcmVzdG9yZUJ0bi5pbm5lckhUTUwgPSAnPHNwYW4gY2xhc3M9XCJicmFuZC1zcGlubmVyXCI+PC9zcGFuPiBSZXN0b3JpbmcuLi4nO1xuICAgIHRyeSB7XG4gICAgICAvLyBIYW5kbGUgbGVnYWN5IGZvcm1hdFxuICAgICAgaWYgKGlzTGVnYWN5Rm9ybWF0KHNlbGVjdGVkQmFja3VwKSkge1xuICAgICAgICByZXN0b3JlTGVnYWN5Rm9ybWF0KHNlbGVjdGVkQmFja3VwKTtcbiAgICAgICAgcmVzdWx0RGl2LmlubmVySFRNTCA9ICdcdTI3MDUgTGVnYWN5IGJhY2t1cCByZXN0b3JlZCBcdTIwMTQgYnJvd3NlciBzZXR0aW5ncyBhbmQgc2VydmljZXMgaW1wb3J0ZWQuJztcbiAgICAgICAgcmVzdWx0RGl2LnN0eWxlLmJhY2tncm91bmQgPSAnY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLW9rLWZnKSAxNSUsIHRyYW5zcGFyZW50KSc7XG4gICAgICAgIHJlc3VsdERpdi5zdHlsZS5ib3JkZXIgPSAnMXB4IHNvbGlkIHZhcigtLW9rLWZnKSc7XG4gICAgICAgIHJlc3VsdERpdi5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHsgbG9jYXRpb24ucmVsb2FkKCk7IH0sIDIwMDApO1xuICAgICAgICByZXN0b3JlQnRuLmRpc2FibGVkID0gZmFsc2U7XG4gICAgICAgIHJlc3RvcmVCdG4uaW5uZXJIVE1MID0gJ1x1MjZBMSBSZXN0b3JlIEV2ZXJ5dGhpbmcnO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIHYxLjErIC8gdjIuMCBcdTIwMTQgcmVzdG9yZSBzZXJ2ZXItc2lkZSBmaXJzdFxuICAgICAgdmFyIHJlbG9hZENhZGR5ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2JhY2t1cC1yZWxvYWQtY2FkZHknKT8uY2hlY2tlZCA/PyB0cnVlO1xuICAgICAgdmFyIHJlc3BvbnNlID0gYXdhaXQgc2VjdXJlRmV0Y2goJy9hcGkvdjEvYmFja3VwL3Jlc3RvcmUnLCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoeyBiYWNrdXA6IHNlbGVjdGVkQmFja3VwLCBvcHRpb25zOiB7IHJlbG9hZENhZGR5OiByZWxvYWRDYWRkeSB9IH0pXG4gICAgICB9KTtcbiAgICAgIHZhciBkYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuXG4gICAgICAvLyBUaGVuIHJlc3RvcmUgYnJvd3NlciBzdGF0ZVxuICAgICAgdmFyIGJyb3dzZXJDb3VudCA9IDA7XG4gICAgICBpZiAoc2VsZWN0ZWRCYWNrdXAuYnJvd3NlclN0YXRlKSB7XG4gICAgICAgIGJyb3dzZXJDb3VudCA9IHJlc3RvcmVCcm93c2VyU3RhdGUoc2VsZWN0ZWRCYWNrdXAuYnJvd3NlclN0YXRlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGRhdGEuc3VjY2Vzcykge1xuICAgICAgICB2YXIgbXNnID0gJ1x1MjcwNSAnICsgZGF0YS5tZXNzYWdlO1xuICAgICAgICBpZiAoYnJvd3NlckNvdW50ID4gMCkgbXNnICs9ICc8YnI+PHNtYWxsIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTtcIj4nICsgYnJvd3NlckNvdW50ICsgJyBicm93c2VyIHNldHRpbmdzIHJlc3RvcmVkPC9zbWFsbD4nO1xuICAgICAgICBpZiAoZGF0YS5yZXN1bHRzLmNhZGR5UmVsb2FkZWQpIG1zZyArPSAnPGJyPjxzbWFsbCBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+Q2FkZHkgY29uZmlndXJhdGlvbiByZWxvYWRlZDwvc21hbGw+JztcbiAgICAgICAgcmVzdWx0RGl2LmlubmVySFRNTCA9IG1zZztcbiAgICAgICAgcmVzdWx0RGl2LnN0eWxlLmJhY2tncm91bmQgPSAnY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLW9rLWZnKSAxNSUsIHRyYW5zcGFyZW50KSc7XG4gICAgICAgIHJlc3VsdERpdi5zdHlsZS5ib3JkZXIgPSAnMXB4IHNvbGlkIHZhcigtLW9rLWZnKSc7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IGxvY2F0aW9uLnJlbG9hZCgpOyB9LCAyMDAwKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdERpdi5pbm5lckhUTUwgPSAnXHUyNkEwXHVGRTBGICcgKyBlc2NhcGVIdG1sKGRhdGEubWVzc2FnZSk7XG4gICAgICAgIGlmIChicm93c2VyQ291bnQgPiAwKSByZXN1bHREaXYuaW5uZXJIVE1MICs9ICc8YnI+PHNtYWxsIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTtcIj4nICsgYnJvd3NlckNvdW50ICsgJyBicm93c2VyIHNldHRpbmdzIHdlcmUgcmVzdG9yZWQ8L3NtYWxsPic7XG4gICAgICAgIGlmIChkYXRhLnJlc3VsdHM/LmVycm9ycz8ubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHJlc3VsdERpdi5pbm5lckhUTUwgKz0gJzxicj48c21hbGw+JyArIGRhdGEucmVzdWx0cy5lcnJvcnMubWFwKGZ1bmN0aW9uKGUpIHsgcmV0dXJuIGVzY2FwZUh0bWwoZS5maWxlKSArICc6ICcgKyBlc2NhcGVIdG1sKGUuZXJyb3IpOyB9KS5qb2luKCcsICcpICsgJzwvc21hbGw+JztcbiAgICAgICAgfVxuICAgICAgICByZXN1bHREaXYuc3R5bGUuYmFja2dyb3VuZCA9ICdjb2xvci1taXgoaW4gc3JnYiwgI2YzOWMxMiAxNSUsIHRyYW5zcGFyZW50KSc7XG4gICAgICAgIHJlc3VsdERpdi5zdHlsZS5ib3JkZXIgPSAnMXB4IHNvbGlkICNmMzljMTInO1xuICAgICAgfVxuICAgICAgcmVzdWx0RGl2LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJlc3VsdERpdi5pbm5lckhUTUwgPSAnXHUyNzRDIFJlc3RvcmUgZmFpbGVkOiAnICsgZXNjYXBlSHRtbChlLm1lc3NhZ2UpO1xuICAgICAgcmVzdWx0RGl2LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgcmVzdWx0RGl2LnN0eWxlLmJhY2tncm91bmQgPSAnY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLWJhZC1mZykgMTUlLCB0cmFuc3BhcmVudCknO1xuICAgICAgcmVzdWx0RGl2LnN0eWxlLmJvcmRlciA9ICcxcHggc29saWQgdmFyKC0tYmFkLWZnKSc7XG4gICAgfVxuICAgIHJlc3RvcmVCdG4uZGlzYWJsZWQgPSBmYWxzZTtcbiAgICByZXN0b3JlQnRuLmlubmVySFRNTCA9ICdcdTI2QTEgUmVzdG9yZSBFdmVyeXRoaW5nJztcbiAgfSk7XG5cbiAgLy8gPT09IFNjaGVkdWxlcyBUYWIgKFByZW1pdW0pID09PVxuICBhc3luYyBmdW5jdGlvbiBsb2FkU2NoZWR1bGVzVGFiKCkge1xuICAgIGlmICghc2NoZWR1bGVDb250YWluZXIpIHJldHVybjtcbiAgICBzY2hlZHVsZUNvbnRhaW5lci5pbm5lckhUTUwgPSAnPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+PHNwYW4gY2xhc3M9XCJicmFuZC1zcGlubmVyXCI+PC9zcGFuPiBMb2FkaW5nLi4uPC9kaXY+JztcbiAgICB0cnkge1xuICAgICAgdmFyIHJlcyA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL2JhY2t1cHMvc2NoZWR1bGUnKTtcbiAgICAgIHZhciBkYXRhID0gYXdhaXQgcmVzLmpzb24oKTtcbiAgICAgIFxuICAgICAgaWYgKGRhdGEucHJlbWl1bVJlcXVpcmVkKSB7XG4gICAgICAgIHNjaGVkdWxlQ29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIiBzdHlsZT1cInBhZGRpbmc6IDI0cHg7IHRleHQtYWxpZ246IGNlbnRlcjtcIj4nICtcbiAgICAgICAgICAnPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMnJlbTsgbWFyZ2luLWJvdHRvbTogMTJweDtcIj5cdTJCNTA8L2Rpdj4nICtcbiAgICAgICAgICAnPGRpdiBzdHlsZT1cImZvbnQtd2VpZ2h0OiA2MDA7IG1hcmdpbi1ib3R0b206IDhweDtcIj5QcmVtaXVtIEZlYXR1cmU8L2Rpdj4nICtcbiAgICAgICAgICAnPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC44NXJlbTsgY29sb3I6IHZhcigtLW11dGVkKTtcIj5BdXRvLWJhY2t1cCBzY2hlZHVsaW5nIHJlcXVpcmVzIGEgRGFzaENhZGR5IFByZW1pdW0gc3Vic2NyaXB0aW9uLjwvZGl2PicgK1xuICAgICAgICAgICc8YnV0dG9uIG9uY2xpY2s9XCJzaG93Tm90aWZpY2F0aW9uKFxcJ1VwZ3JhZGUgdG8gUHJlbWl1bSB0byBlbmFibGUgYXV0by1iYWNrdXBzIVxcJywgXFwnaW5mb1xcJyk7IHNjcm9sbFRvU2VjdGlvbihcXCdsaWNlbnNlXFwnKTtcIiBzdHlsZT1cIm1hcmdpbi10b3A6IDE2cHg7IHBhZGRpbmc6IDhweCAyMHB4OyBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTM1ZGVnLCAjZjM5YzEyLCAjZTY3ZTIyKTsgYm9yZGVyOiBub25lOyBjb2xvcjogd2hpdGU7IGJvcmRlci1yYWRpdXM6IDhweDsgY3Vyc29yOiBwb2ludGVyOyBmb250LXdlaWdodDogNjAwO1wiPlVwZ3JhZGUgdG8gUHJlbWl1bTwvYnV0dG9uPicgK1xuICAgICAgICAgICc8L2Rpdj4nO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBcbiAgICAgIGlmICghZGF0YS5zdWNjZXNzKSB0aHJvdyBuZXcgRXJyb3IoZGF0YS5lcnJvciB8fCAnRmFpbGVkIHRvIGxvYWQgc2NoZWR1bGVzJyk7XG4gICAgICBcbiAgICAgIHZhciBzY2hlZHVsZXMgPSBkYXRhLnNjaGVkdWxlcyB8fCBbXTtcbiAgICAgIFxuICAgICAgaWYgKHNjaGVkdWxlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgc2NoZWR1bGVDb250YWluZXIuaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPicgK1xuICAgICAgICAgICc8c3BhbiBjbGFzcz1cImVtcHR5LWljb25cIj5cdTIzRjA8L3NwYW4+JyArXG4gICAgICAgICAgJzxkaXY+Tm8gYmFja3VwIHNjaGVkdWxlcyBjb25maWd1cmVkPC9kaXY+JyArXG4gICAgICAgICAgJzxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuOHJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLXRvcDogNHB4O1wiPlNlbGVjdCBhcHBzIGJlbG93IHRvIGVuYWJsZSBhdXRvLWJhY2t1cDwvZGl2PicgK1xuICAgICAgICAgICc8L2Rpdj4nO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBcbiAgICAgIHZhciBodG1sID0gJzxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBmbGV4LWRpcmVjdGlvbjogY29sdW1uOyBnYXA6IDhweDtcIj4nO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzY2hlZHVsZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIHNjaCA9IHNjaGVkdWxlc1tpXTtcbiAgICAgICAgdmFyIG5leHRSdW5TdHIgPSBzY2gubmV4dFJ1biA/IG5ldyBEYXRlKHNjaC5uZXh0UnVuKS50b0xvY2FsZVN0cmluZygpIDogJ05vdCBzY2hlZHVsZWQnO1xuICAgICAgICB2YXIgbGFzdFJ1blN0ciA9IHNjaC5sYXN0UnVuID8gbmV3IERhdGUoc2NoLmxhc3RSdW4pLnRvTG9jYWxlU3RyaW5nKCkgOiAnTmV2ZXInO1xuICAgICAgICBcbiAgICAgICAgaHRtbCArPSAnPGRpdiBzdHlsZT1cInBhZGRpbmc6IDEycHggMTRweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iYXNlKTsgYm9yZGVyLXJhZGl1czogOHB4OyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1wiPicgK1xuICAgICAgICAgICc8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuOyBhbGlnbi1pdGVtczogY2VudGVyOyBtYXJnaW4tYm90dG9tOiA4cHg7XCI+JyArXG4gICAgICAgICAgJyAgPGRpdiBzdHlsZT1cImZvbnQtd2VpZ2h0OiA2MDA7IGZvbnQtc2l6ZTogMC45cmVtO1wiPicgKyBlc2NhcGVIdG1sKHNjaC5hcHBJZCkgKyAnPC9kaXY+JyArXG4gICAgICAgICAgJyAgPGxhYmVsIGNsYXNzPVwidG9nZ2xlLXN3aXRjaFwiIHN0eWxlPVwiZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA2cHg7XCI+JyArXG4gICAgICAgICAgJyAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJzY2hlZHVsZS10b2dnbGVcIiBkYXRhLWFwcGlkPVwiJyArIGVzY2FwZUh0bWwoc2NoLmFwcElkKSArICdcIicgKyAoc2NoLmVuYWJsZWQgPyAnIGNoZWNrZWQnIDogJycpICsgJyAvPicgK1xuICAgICAgICAgICcgICAgPHNwYW4gc3R5bGU9XCJmb250LXNpemU6IDAuNzVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+JyArIChzY2guZW5hYmxlZCA/ICdPTicgOiAnT0ZGJykgKyAnPC9zcGFuPicgK1xuICAgICAgICAgICcgIDwvbGFiZWw+JyArXG4gICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAgICc8ZGl2IHN0eWxlPVwiZGlzcGxheTogZ3JpZDsgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiAxZnIgMWZyOyBnYXA6IDhweDsgZm9udC1zaXplOiAwLjhyZW07IG1hcmdpbi1ib3R0b206IDEwcHg7XCI+JyArXG4gICAgICAgICAgJyAgPGRpdj48c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+U2NoZWR1bGU6PC9zcGFuPiA8c2VsZWN0IGNsYXNzPVwic2NoZWR1bGUtc2VsZWN0XCIgZGF0YS1hcHBpZD1cIicgKyBlc2NhcGVIdG1sKHNjaC5hcHBJZCkgKyAnXCIgc3R5bGU9XCJiYWNrZ3JvdW5kOiB2YXIoLS1iYXNlKTsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgYm9yZGVyLXJhZGl1czogNHB4OyBwYWRkaW5nOiAycHggNnB4O1wiPicgK1xuICAgICAgICAgICcgICAgPG9wdGlvbiB2YWx1ZT1cImhvdXJseVwiJyArIChzY2guc2NoZWR1bGUgPT09ICdob3VybHknID8gJyBzZWxlY3RlZCcgOiAnJykgKyAnPkhvdXJseTwvb3B0aW9uPicgK1xuICAgICAgICAgICcgICAgPG9wdGlvbiB2YWx1ZT1cImRhaWx5XCInICsgKHNjaC5zY2hlZHVsZSA9PT0gJ2RhaWx5JyA/ICcgc2VsZWN0ZWQnIDogJycpICsgJz5EYWlseTwvb3B0aW9uPicgK1xuICAgICAgICAgICcgICAgPG9wdGlvbiB2YWx1ZT1cIndlZWtseVwiJyArIChzY2guc2NoZWR1bGUgPT09ICd3ZWVrbHknID8gJyBzZWxlY3RlZCcgOiAnJykgKyAnPldlZWtseTwvb3B0aW9uPicgK1xuICAgICAgICAgICcgICAgPG9wdGlvbiB2YWx1ZT1cIm1vbnRobHlcIicgKyAoc2NoLnNjaGVkdWxlID09PSAnbW9udGhseScgPyAnIHNlbGVjdGVkJyA6ICcnKSArICc+TW9udGhseTwvb3B0aW9uPicgK1xuICAgICAgICAgICcgIDwvc2VsZWN0PjwvZGl2PicgK1xuICAgICAgICAgICcgIDxkaXY+PHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPktlZXAgbGFzdDo8L3NwYW4+IDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgY2xhc3M9XCJyZXRlbnRpb24taW5wdXRcIiBkYXRhLWFwcGlkPVwiJyArIGVzY2FwZUh0bWwoc2NoLmFwcElkKSArICdcIiB2YWx1ZT1cIicgKyAoc2NoLnJldGVudGlvbj8ua2VlcCB8fCA3KSArICdcIiBtaW49XCIxXCIgbWF4PVwiMTAwXCIgc3R5bGU9XCJ3aWR0aDogNTBweDsgYmFja2dyb3VuZDogdmFyKC0tYmFzZSk7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJvcmRlci1yYWRpdXM6IDRweDsgcGFkZGluZzogMnB4IDZweDtcIiAvPjwvZGl2PicgK1xuICAgICAgICAgICc8L2Rpdj4nICtcbiAgICAgICAgICAnPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC43NXJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLWJvdHRvbTogMTBweDtcIj4nICtcbiAgICAgICAgICAnICA8ZGl2Pk5leHQgcnVuOiAnICsgZXNjYXBlSHRtbChuZXh0UnVuU3RyKSArICc8L2Rpdj4nICtcbiAgICAgICAgICAnICA8ZGl2Pkxhc3QgcnVuOiAnICsgZXNjYXBlSHRtbChsYXN0UnVuU3RyKSArICc8L2Rpdj4nICtcbiAgICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICAgJzxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBnYXA6IDZweDtcIj4nICtcbiAgICAgICAgICAnICA8YnV0dG9uIGNsYXNzPVwic2NoZWR1bGUtcnVuLW5vd1wiIGRhdGEtYXBwaWQ9XCInICsgZXNjYXBlSHRtbChzY2guYXBwSWQpICsgJ1wiIHN0eWxlPVwicGFkZGluZzogNXB4IDEycHg7IGZvbnQtc2l6ZTogMC44cmVtOyBiYWNrZ3JvdW5kOiBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tb2stZmcpIDIwJSwgdHJhbnNwYXJlbnQpOyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1vay1mZyk7IGNvbG9yOiB2YXIoLS1vay1mZyk7IGJvcmRlci1yYWRpdXM6IDZweDsgY3Vyc29yOiBwb2ludGVyO1wiPlx1MjVCNlx1RkUwRiBSdW4gTm93PC9idXR0b24+JyArXG4gICAgICAgICAgJyAgPGJ1dHRvbiBjbGFzcz1cInNjaGVkdWxlLWRlbGV0ZVwiIGRhdGEtYXBwaWQ9XCInICsgZXNjYXBlSHRtbChzY2guYXBwSWQpICsgJ1wiIHN0eWxlPVwicGFkZGluZzogNXB4IDEycHg7IGZvbnQtc2l6ZTogMC44cmVtOyBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYmFkLWZnKTsgY29sb3I6IHZhcigtLWJhZC1mZyk7IGJvcmRlci1yYWRpdXM6IDZweDsgY3Vyc29yOiBwb2ludGVyO1wiPlx1RDgzRFx1REREMVx1RkUwRiBSZW1vdmU8L2J1dHRvbj4nICtcbiAgICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICAgJzwvZGl2Pic7XG4gICAgICB9XG4gICAgICBodG1sICs9ICc8L2Rpdj4nO1xuICAgICAgXG4gICAgICAvLyBBZGQgXCJBZGQgU2NoZWR1bGVcIiBzZWN0aW9uIGF0IGJvdHRvbVxuICAgICAgaHRtbCArPSAnPGRpdiBzdHlsZT1cIm1hcmdpbi10b3A6IDE2cHg7IHBhZGRpbmc6IDE2cHg7IGJhY2tncm91bmQ6IGNvbG9yLW1peChpbiBzcmdiLCB2YXIoLS1hY2NlbnQpIDUlLCB0cmFuc3BhcmVudCk7IGJvcmRlci1yYWRpdXM6IDEwcHg7IGJvcmRlcjogMXB4IGRhc2hlZCB2YXIoLS1ib3JkZXIpO1wiPicgK1xuICAgICAgICAnPGg0IHN0eWxlPVwibWFyZ2luOiAwIDAgMTJweDsgZm9udC1zaXplOiAwLjg1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPlx1Mjc5NSBBZGQgTmV3IFNjaGVkdWxlPC9oND4nICtcbiAgICAgICAgJzxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBnYXA6IDhweDsgZmxleC13cmFwOiB3cmFwO1wiPicgK1xuICAgICAgICAnICA8aW5wdXQgdHlwZT1cInRleHRcIiBpZD1cIm5ldy1zY2hlZHVsZS1hcHBpZFwiIHBsYWNlaG9sZGVyPVwiQXBwIElEIChlLmcuLCBwbGV4LCBzb25hcnIpXCIgc3R5bGU9XCJmbGV4OiAxOyBtaW4td2lkdGg6IDE1MHB4OyBwYWRkaW5nOiA4cHg7IGJvcmRlci1yYWRpdXM6IDZweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgYmFja2dyb3VuZDogdmFyKC0tYmFzZSk7XCIgLz4nICtcbiAgICAgICAgJyAgPHNlbGVjdCBpZD1cIm5ldy1zY2hlZHVsZS1pbnRlcnZhbFwiIHN0eWxlPVwicGFkZGluZzogOHB4OyBib3JkZXItcmFkaXVzOiA2cHg7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJhY2tncm91bmQ6IHZhcigtLWJhc2UpO1wiPicgK1xuICAgICAgICAnICAgIDxvcHRpb24gdmFsdWU9XCJob3VybHlcIj5Ib3VybHk8L29wdGlvbj4nICtcbiAgICAgICAgJyAgICA8b3B0aW9uIHZhbHVlPVwiZGFpbHlcIiBzZWxlY3RlZD5EYWlseTwvb3B0aW9uPicgK1xuICAgICAgICAnICAgIDxvcHRpb24gdmFsdWU9XCJ3ZWVrbHlcIj5XZWVrbHk8L29wdGlvbj4nICtcbiAgICAgICAgJyAgICA8b3B0aW9uIHZhbHVlPVwibW9udGhseVwiPk1vbnRobHk8L29wdGlvbj4nICtcbiAgICAgICAgJyAgICA8b3B0aW9uIHZhbHVlPVwiNmhcIj5FdmVyeSA2IGhvdXJzPC9vcHRpb24+JyArXG4gICAgICAgICcgICAgPG9wdGlvbiB2YWx1ZT1cIjMwbVwiPkV2ZXJ5IDMwIG1pbnV0ZXM8L29wdGlvbj4nICtcbiAgICAgICAgJyAgPC9zZWxlY3Q+JyArXG4gICAgICAgICcgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgaWQ9XCJuZXctc2NoZWR1bGUtcmV0ZW50aW9uXCIgdmFsdWU9XCI3XCIgbWluPVwiMVwiIG1heD1cIjEwMFwiIHBsYWNlaG9sZGVyPVwiS2VlcFwiIHN0eWxlPVwid2lkdGg6IDcwcHg7IHBhZGRpbmc6IDhweDsgYm9yZGVyLXJhZGl1czogNnB4OyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBiYWNrZ3JvdW5kOiB2YXIoLS1iYXNlKTtcIiAvPicgK1xuICAgICAgICAnICA8YnV0dG9uIGlkPVwiYWRkLXNjaGVkdWxlLWJ0blwiIHN0eWxlPVwicGFkZGluZzogOHB4IDE2cHg7IGJhY2tncm91bmQ6IHZhcigtLWFjY2VudCk7IGJvcmRlcjogbm9uZTsgY29sb3I6IHdoaXRlOyBib3JkZXItcmFkaXVzOiA2cHg7IGN1cnNvcjogcG9pbnRlcjsgZm9udC13ZWlnaHQ6IDUwMDtcIj5BZGQgU2NoZWR1bGU8L2J1dHRvbj4nICtcbiAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAnPC9kaXY+JztcbiAgICAgIFxuICAgICAgc2NoZWR1bGVDb250YWluZXIuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgIFxuICAgICAgLy8gV2lyZSB1cCBldmVudCBsaXN0ZW5lcnNcbiAgICAgIHNjaGVkdWxlQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoJy5zY2hlZHVsZS10b2dnbGUnKS5mb3JFYWNoKGZ1bmN0aW9uKHRvZ2dsZSkge1xuICAgICAgICB0b2dnbGUuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgZnVuY3Rpb24oKSB7IHVwZGF0ZVNjaGVkdWxlKHRvZ2dsZS5kYXRhc2V0LmFwcGlkLCB7IGVuYWJsZWQ6IHRvZ2dsZS5jaGVja2VkIH0pOyB9KTtcbiAgICAgIH0pO1xuICAgICAgc2NoZWR1bGVDb250YWluZXIucXVlcnlTZWxlY3RvckFsbCgnLnNjaGVkdWxlLXNlbGVjdCcpLmZvckVhY2goZnVuY3Rpb24oc2VsKSB7XG4gICAgICAgIHNlbC5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCBmdW5jdGlvbigpIHsgdXBkYXRlU2NoZWR1bGUoc2VsLmRhdGFzZXQuYXBwaWQsIHsgc2NoZWR1bGU6IHNlbC52YWx1ZSB9KTsgfSk7XG4gICAgICB9KTtcbiAgICAgIHNjaGVkdWxlQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoJy5yZXRlbnRpb24taW5wdXQnKS5mb3JFYWNoKGZ1bmN0aW9uKGlucCkge1xuICAgICAgICBpbnAuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgZnVuY3Rpb24oKSB7IHVwZGF0ZVNjaGVkdWxlKGlucC5kYXRhc2V0LmFwcGlkLCB7IHJldGVudGlvbjogeyBrZWVwOiBwYXJzZUludChpbnAudmFsdWUpIHx8IDcgfSB9KTsgfSk7XG4gICAgICB9KTtcbiAgICAgIHNjaGVkdWxlQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoJy5zY2hlZHVsZS1ydW4tbm93JykuZm9yRWFjaChmdW5jdGlvbihidG4pIHtcbiAgICAgICAgYnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oKSB7IHJ1bkJhY2t1cE5vdyhidG4uZGF0YXNldC5hcHBpZCk7IH0pO1xuICAgICAgfSk7XG4gICAgICBzY2hlZHVsZUNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCcuc2NoZWR1bGUtZGVsZXRlJykuZm9yRWFjaChmdW5jdGlvbihidG4pIHtcbiAgICAgICAgYnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oKSB7IGRlbGV0ZVNjaGVkdWxlKGJ0bi5kYXRhc2V0LmFwcGlkKTsgfSk7XG4gICAgICB9KTtcbiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhZGQtc2NoZWR1bGUtYnRuJyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYWRkTmV3U2NoZWR1bGUpO1xuICAgICAgXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgc2NoZWR1bGVDb250YWluZXIuaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiIHN0eWxlPVwiY29sb3I6IHZhcigtLWJhZC1mZyk7XCI+RmFpbGVkIHRvIGxvYWQ6ICcgKyBlc2NhcGVIdG1sKGUubWVzc2FnZSkgKyAnPC9kaXY+JztcbiAgICB9XG4gIH1cbiAgXG4gIGFzeW5jIGZ1bmN0aW9uIHVwZGF0ZVNjaGVkdWxlKGFwcElkLCB1cGRhdGVzKSB7XG4gICAgdHJ5IHtcbiAgICAgIHZhciByZXMgPSBhd2FpdCBzZWN1cmVGZXRjaCgnL2FwaS92MS9iYWNrdXBzL3NjaGVkdWxlJywge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsgYXBwSWQsIC4uLnVwZGF0ZXMgfSlcbiAgICAgIH0pO1xuICAgICAgdmFyIGRhdGEgPSBhd2FpdCByZXMuanNvbigpO1xuICAgICAgaWYgKGRhdGEuc3VjY2Vzcykge1xuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKCdTY2hlZHVsZSB1cGRhdGVkIGZvciAnICsgYXBwSWQsICdzdWNjZXNzJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKCdVcGRhdGUgZmFpbGVkOiAnICsgKGRhdGEuZXJyb3IgfHwgJ1Vua25vd24nKSwgJ2Vycm9yJyk7XG4gICAgICAgIGxvYWRTY2hlZHVsZXNUYWIoKTsgLy8gUmVmcmVzaCBvbiBmYWlsdXJlXG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgc2hvd05vdGlmaWNhdGlvbignRXJyb3I6ICcgKyBlLm1lc3NhZ2UsICdlcnJvcicpO1xuICAgIH1cbiAgfVxuICBcbiAgYXN5bmMgZnVuY3Rpb24gcnVuQmFja3VwTm93KGFwcElkKSB7XG4gICAgdHJ5IHtcbiAgICAgIHZhciByZXMgPSBhd2FpdCBzZWN1cmVGZXRjaCgnL2FwaS92MS9iYWNrdXBzL2JhY2t1cC8nICsgZW5jb2RlVVJJQ29tcG9uZW50KGFwcElkKSwge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH1cbiAgICAgIH0pO1xuICAgICAgdmFyIGRhdGEgPSBhd2FpdCByZXMuanNvbigpO1xuICAgICAgaWYgKGRhdGEuc3VjY2Vzcykge1xuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKCdCYWNrdXAgc3RhcnRlZCBmb3IgJyArIGFwcElkICsgJyEnLCAnc3VjY2VzcycpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2hvd05vdGlmaWNhdGlvbignQmFja3VwIGZhaWxlZDogJyArIChkYXRhLmVycm9yIHx8ICdVbmtub3duJyksICdlcnJvcicpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHNob3dOb3RpZmljYXRpb24oJ0Vycm9yOiAnICsgZS5tZXNzYWdlLCAnZXJyb3InKTtcbiAgICB9XG4gIH1cbiAgXG4gIGFzeW5jIGZ1bmN0aW9uIGRlbGV0ZVNjaGVkdWxlKGFwcElkKSB7XG4gICAgaWYgKCFjb25maXJtKCdSZW1vdmUgYmFja3VwIHNjaGVkdWxlIGZvciAnICsgYXBwSWQgKyAnPycpKSByZXR1cm47XG4gICAgdHJ5IHtcbiAgICAgIHZhciByZXMgPSBhd2FpdCBzZWN1cmVGZXRjaCgnL2FwaS92MS9iYWNrdXBzL3NjaGVkdWxlLycgKyBlbmNvZGVVUklDb21wb25lbnQoYXBwSWQpLCB7IG1ldGhvZDogJ0RFTEVURScgfSk7XG4gICAgICB2YXIgZGF0YSA9IGF3YWl0IHJlcy5qc29uKCk7XG4gICAgICBpZiAoZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oJ1NjaGVkdWxlIHJlbW92ZWQgZm9yICcgKyBhcHBJZCwgJ3N1Y2Nlc3MnKTtcbiAgICAgICAgbG9hZFNjaGVkdWxlc1RhYigpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2hvd05vdGlmaWNhdGlvbignRGVsZXRlIGZhaWxlZDogJyArIChkYXRhLmVycm9yIHx8ICdVbmtub3duJyksICdlcnJvcicpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHNob3dOb3RpZmljYXRpb24oJ0Vycm9yOiAnICsgZS5tZXNzYWdlLCAnZXJyb3InKTtcbiAgICB9XG4gIH1cbiAgXG4gIGFzeW5jIGZ1bmN0aW9uIGFkZE5ld1NjaGVkdWxlKCkge1xuICAgIHZhciBhcHBJZCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCduZXctc2NoZWR1bGUtYXBwaWQnKT8udmFsdWU/LnRyaW0oKTtcbiAgICB2YXIgaW50ZXJ2YWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbmV3LXNjaGVkdWxlLWludGVydmFsJyk/LnZhbHVlIHx8ICdkYWlseSc7XG4gICAgdmFyIHJldGVudGlvbiA9IHBhcnNlSW50KGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCduZXctc2NoZWR1bGUtcmV0ZW50aW9uJyk/LnZhbHVlKSB8fCA3O1xuICAgIFxuICAgIGlmICghYXBwSWQpIHtcbiAgICAgIHNob3dOb3RpZmljYXRpb24oJ1BsZWFzZSBlbnRlciBhbiBBcHAgSUQnLCAnd2FybmluZycpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBcbiAgICB0cnkge1xuICAgICAgdmFyIHJlcyA9IGF3YWl0IHNlY3VyZUZldGNoKCcvYXBpL3YxL2JhY2t1cHMvc2NoZWR1bGUnLCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoeyBhcHBJZCwgc2NoZWR1bGU6IGludGVydmFsLCByZXRlbnRpb246IHsga2VlcDogcmV0ZW50aW9uIH0sIGVuYWJsZWQ6IHRydWUgfSlcbiAgICAgIH0pO1xuICAgICAgdmFyIGRhdGEgPSBhd2FpdCByZXMuanNvbigpO1xuICAgICAgaWYgKGRhdGEuc3VjY2Vzcykge1xuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKCdTY2hlZHVsZSBjcmVhdGVkIGZvciAnICsgYXBwSWQsICdzdWNjZXNzJyk7XG4gICAgICAgIGxvYWRTY2hlZHVsZXNUYWIoKTtcbiAgICAgICAgLy8gQ2xlYXIgaW5wdXRzXG4gICAgICAgIHZhciBhcHBJZElucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ25ldy1zY2hlZHVsZS1hcHBpZCcpO1xuICAgICAgICBpZiAoYXBwSWRJbnB1dCkgYXBwSWRJbnB1dC52YWx1ZSA9ICcnO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2hvd05vdGlmaWNhdGlvbignRmFpbGVkOiAnICsgKGRhdGEuZXJyb3IgfHwgJ1Vua25vd24nKSwgJ2Vycm9yJyk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgc2hvd05vdGlmaWNhdGlvbignRXJyb3I6ICcgKyBlLm1lc3NhZ2UsICdlcnJvcicpO1xuICAgIH1cbiAgfVxuICBcbiAgLy8gPT09IEJhY2t1cHMgb24gRGlzayBUYWIgPT09XG4gIGFzeW5jIGZ1bmN0aW9uIGxvYWREaXNrQmFja3VwcygpIHtcbiAgICBpZiAoIWRpc2tDb250YWluZXIpIHJldHVybjtcbiAgICBkaXNrQ29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj48c3BhbiBjbGFzcz1cImJyYW5kLXNwaW5uZXJcIj48L3NwYW4+IExvYWRpbmcuLi48L2Rpdj4nO1xuICAgIHRyeSB7XG4gICAgICB2YXIgcmVzID0gYXdhaXQgZmV0Y2goJy9hcGkvdjEvYmFja3Vwcy9maWxlcycpO1xuICAgICAgdmFyIGRhdGEgPSBhd2FpdCByZXMuanNvbigpO1xuICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHRocm93IG5ldyBFcnJvcihkYXRhLmVycm9yIHx8ICdGYWlsZWQgdG8gbG9hZCcpO1xuXG4gICAgICB2YXIgZmlsZXMgPSBkYXRhLmZpbGVzIHx8IFtdO1xuXG4gICAgICBpZiAoZmlsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGRpc2tDb250YWluZXIuaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPicgK1xuICAgICAgICAgICc8c3BhbiBjbGFzcz1cImVtcHR5LWljb25cIj5cdUQ4M0RcdURDQkU8L3NwYW4+JyArXG4gICAgICAgICAgJzxkaXY+Tm8gYmFja3VwIGZpbGVzIG9uIGRpc2s8L2Rpdj4nICtcbiAgICAgICAgICAnPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC44cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW4tdG9wOiA0cHg7XCI+UnVuIGEgYmFja3VwIHRvIGNyZWF0ZSBiYWNrdXAgZmlsZXM8L2Rpdj4nICtcbiAgICAgICAgICAnPC9kaXY+JztcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBHcm91cCBieSBhcHBJZFxuICAgICAgdmFyIGJ5QXBwID0ge307XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZpbGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBmID0gZmlsZXNbaV07XG4gICAgICAgIHZhciBhcHBJZCA9IGYuYXBwSWQgfHwgJ3Vua25vd24nO1xuICAgICAgICBpZiAoIWJ5QXBwW2FwcElkXSkgYnlBcHBbYXBwSWRdID0gW107XG4gICAgICAgIGJ5QXBwW2FwcElkXS5wdXNoKGYpO1xuICAgICAgfVxuXG4gICAgICB2YXIgaHRtbCA9ICc8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjc1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW4tYm90dG9tOiAxMnB4O1wiPicgKyBmaWxlcy5sZW5ndGggKyAnIGJhY2t1cCBmaWxlKHMpIGFjcm9zcyAnICsgT2JqZWN0LmtleXMoYnlBcHApLmxlbmd0aCArICcgYXBwKHMpPC9kaXY+JztcbiAgICAgIGh0bWwgKz0gJzxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBmbGV4LWRpcmVjdGlvbjogY29sdW1uOyBnYXA6IDEycHg7XCI+JztcblxuICAgICAgdmFyIGFwcElkcyA9IE9iamVjdC5rZXlzKGJ5QXBwKS5zb3J0KCk7XG4gICAgICBmb3IgKHZhciBhID0gMDsgYSA8IGFwcElkcy5sZW5ndGg7IGErKykge1xuICAgICAgICB2YXIgYXBwSWQgPSBhcHBJZHNbYV07XG4gICAgICAgIHZhciBhcHBGaWxlcyA9IGJ5QXBwW2FwcElkXTtcbiAgICAgICAgaHRtbCArPSAnPGRpdiBzdHlsZT1cImJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmFzZSk7IGJvcmRlci1yYWRpdXM6IDhweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgb3ZlcmZsb3c6IGhpZGRlbjtcIj4nICtcbiAgICAgICAgICAnPGRpdiBzdHlsZT1cInBhZGRpbmc6IDhweCAxMnB4OyBiYWNrZ3JvdW5kOiBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tYWNjZW50KSA4JSwgdHJhbnNwYXJlbnQpOyBib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgZm9udC13ZWlnaHQ6IDYwMDsgZm9udC1zaXplOiAwLjg1cmVtO1wiPicgK1xuICAgICAgICAgIGVzY2FwZUh0bWwoYXBwSWQpICsgJyA8c3BhbiBzdHlsZT1cImZvbnQtd2VpZ2h0OiBub3JtYWw7IGNvbG9yOiB2YXIoLS1tdXRlZCk7IGZvbnQtc2l6ZTogMC43NXJlbTtcIj4oJyArIGFwcEZpbGVzLmxlbmd0aCArICcgYmFja3VwKHMpKTwvc3Bhbj4nICtcbiAgICAgICAgICAnPC9kaXY+JztcblxuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGFwcEZpbGVzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgdmFyIGYgPSBhcHBGaWxlc1tqXTtcbiAgICAgICAgICB2YXIgZGF0ZVN0ciA9IG5ldyBEYXRlKGYudGltZXN0YW1wKS50b0xvY2FsZVN0cmluZygpO1xuICAgICAgICAgIGh0bWwgKz0gJzxkaXYgc3R5bGU9XCJwYWRkaW5nOiAxMHB4IDEycHg7IGJvcmRlci1ib3R0b206IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1wiPicgK1xuICAgICAgICAgICAgJzxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47IGFsaWduLWl0ZW1zOiBjZW50ZXI7IG1hcmdpbi1ib3R0b206IDRweDtcIj4nICtcbiAgICAgICAgICAgICcgIDxkaXYgc3R5bGU9XCJmb250LXdlaWdodDogNTAwOyBmb250LXNpemU6IDAuODVyZW07XCI+JyArIGVzY2FwZUh0bWwoZi5uYW1lKSArICc8L2Rpdj4nICtcbiAgICAgICAgICAgICcgIDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuNzVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+JyArIGYuc2l6ZUZvcm1hdHRlZCArICc8L2Rpdj4nICtcbiAgICAgICAgICAgICc8L2Rpdj4nICtcbiAgICAgICAgICAgICc8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjc1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW4tYm90dG9tOiA4cHg7XCI+JyArIGRhdGVTdHIgKyAnPC9kaXY+JyArXG4gICAgICAgICAgICAnPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGdhcDogNnB4O1wiPicgK1xuICAgICAgICAgICAgJyAgPGJ1dHRvbiBjbGFzcz1cImRpc2stY29tcGFyZS1idG5cIiBkYXRhLWFwcGlkPVwiJyArIGVzY2FwZUh0bWwoYXBwSWQpICsgJ1wiIGRhdGEtZmlsZW5hbWU9XCInICsgZXNjYXBlSHRtbChmLm5hbWUpICsgJ1wiIHN0eWxlPVwicGFkZGluZzogM3B4IDhweDsgZm9udC1zaXplOiAwLjc1cmVtOyBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYWNjZW50KTsgY29sb3I6IHZhcigtLWFjY2VudCk7IGJvcmRlci1yYWRpdXM6IDVweDsgY3Vyc29yOiBwb2ludGVyO1wiPkNvbXBhcmU8L2J1dHRvbj4nICtcbiAgICAgICAgICAgICcgIDxidXR0b24gY2xhc3M9XCJkaXNrLXJlc3RvcmUtYnRuXCIgZGF0YS1hcHBpZD1cIicgKyBlc2NhcGVIdG1sKGFwcElkKSArICdcIiBkYXRhLWZpbGVuYW1lPVwiJyArIGVzY2FwZUh0bWwoZi5uYW1lKSArICdcIiBzdHlsZT1cInBhZGRpbmc6IDNweCA4cHg7IGZvbnQtc2l6ZTogMC43NXJlbTsgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgdmFyKC0tb2stZmcpLCAjMjdhZTYwKTsgYm9yZGVyOiBub25lOyBjb2xvcjogd2hpdGU7IGJvcmRlci1yYWRpdXM6IDVweDsgY3Vyc29yOiBwb2ludGVyOyBmb250LXdlaWdodDogNTAwO1wiPlJlc3RvcmU8L2J1dHRvbj4nICtcbiAgICAgICAgICAgICc8L2Rpdj4nICtcbiAgICAgICAgICAgICc8L2Rpdj4nO1xuICAgICAgICB9XG4gICAgICAgIGh0bWwgKz0gJzwvZGl2Pic7XG4gICAgICB9XG4gICAgICBodG1sICs9ICc8L2Rpdj4nO1xuXG4gICAgICBkaXNrQ29udGFpbmVyLmlubmVySFRNTCA9IGh0bWw7XG5cbiAgICAgIC8vIFdpcmUgdXAgYnV0dG9uc1xuICAgICAgZGlza0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCcuZGlzay1jb21wYXJlLWJ0bicpLmZvckVhY2goZnVuY3Rpb24oYnRuKSB7XG4gICAgICAgIGJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCkgeyBjb21wYXJlQmFja3VwRmlsZShidG4uZGF0YXNldC5hcHBpZCwgYnRuLmRhdGFzZXQuZmlsZW5hbWUpOyB9KTtcbiAgICAgIH0pO1xuICAgICAgZGlza0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCcuZGlzay1yZXN0b3JlLWJ0bicpLmZvckVhY2goZnVuY3Rpb24oYnRuKSB7XG4gICAgICAgIGJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCkgeyByZXN0b3JlQmFja3VwRmlsZShidG4uZGF0YXNldC5hcHBpZCwgYnRuLmRhdGFzZXQuZmlsZW5hbWUpOyB9KTtcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGRpc2tDb250YWluZXIuaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiIHN0eWxlPVwiY29sb3I6IHZhcigtLWJhZC1mZyk7XCI+RmFpbGVkOiAnICsgZXNjYXBlSHRtbChlLm1lc3NhZ2UpICsgJzwvZGl2Pic7XG4gICAgfVxuICB9XG4gIFxuICAvLyA9PT0gQmFja3VwIEhpc3RvcnkgVGFiID09PVxuICBhc3luYyBmdW5jdGlvbiBsb2FkQmFja3VwSGlzdG9yeSgpIHtcbiAgICBpZiAoIWhpc3RvcnlDb250YWluZXIpIHJldHVybjtcbiAgICBoaXN0b3J5Q29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj48c3BhbiBjbGFzcz1cImJyYW5kLXNwaW5uZXJcIj48L3NwYW4+IExvYWRpbmcuLi48L2Rpdj4nO1xuICAgIHRyeSB7XG4gICAgICB2YXIgcmVzID0gYXdhaXQgZmV0Y2goJy9hcGkvdjEvYmFja3Vwcy9oaXN0b3J5P2xpbWl0PTUwJyk7XG4gICAgICB2YXIgZGF0YSA9IGF3YWl0IHJlcy5qc29uKCk7XG4gICAgICBpZiAoIWRhdGEuc3VjY2VzcyB8fCAhZGF0YS5oaXN0b3J5Py5sZW5ndGgpIHtcbiAgICAgICAgaGlzdG9yeUNvbnRhaW5lci5pbm5lckhUTUwgPSAnPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+PHNwYW4gY2xhc3M9XCJlbXB0eS1pY29uXCI+XHVEODNEXHVEQ0NCPC9zcGFuPiBObyBiYWNrdXAgaGlzdG9yeSB5ZXQ8L2Rpdj4nO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB2YXIgaHRtbCA9ICc8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsgZ2FwOiA2cHg7XCI+JztcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5oaXN0b3J5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBiayA9IGRhdGEuaGlzdG9yeVtpXTtcbiAgICAgICAgdmFyIHNpemVNQiA9IGJrLnNpemUgPyAoYmsuc2l6ZSAvIDEwMjQgLyAxMDI0KS50b0ZpeGVkKDIpIDogJz8nO1xuICAgICAgICBodG1sICs9ICc8ZGl2IHN0eWxlPVwicGFkZGluZzogMTBweCAxMnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJhc2UpOyBib3JkZXItcmFkaXVzOiA2cHg7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGZvbnQtc2l6ZTogMC44NXJlbTtcIj4nO1xuICAgICAgICBodG1sICs9ICcgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47IGFsaWduLWl0ZW1zOiBjZW50ZXI7IG1hcmdpbi1ib3R0b206IDRweDtcIj4nO1xuICAgICAgICBodG1sICs9ICcgICAgPHNwYW4gc3R5bGU9XCJmb250LXdlaWdodDogNTAwO1wiPicgKyBlc2NhcGVIdG1sKGJrLm5hbWUgfHwgJ2JhY2t1cCcpICsgJzwvc3Bhbj4nO1xuICAgICAgICBodG1sICs9ICcgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogOHB4O1wiPic7XG4gICAgICAgIGh0bWwgKz0gJyAgICAgIDxzcGFuIGNsYXNzPVwic3RhdHVzLWJhZGdlICcgKyAoYmsuc3RhdHVzID09PSAnc3VjY2VzcycgPyAnc3VjY2VzcycgOiAnZG93bicpICsgJ1wiPicgKyBlc2NhcGVIdG1sKGJrLnN0YXR1cykgKyAnPC9zcGFuPic7XG4gICAgICAgIGlmIChiay5zdGF0dXMgPT09ICdzdWNjZXNzJykgaHRtbCArPSAnICAgICAgPGJ1dHRvbiBjbGFzcz1cImJhY2t1cC1yZXN0b3JlLWJ0blwiIGRhdGEtYmFja3VwLWlkPVwiJyArIGVzY2FwZUh0bWwoYmsuaWQpICsgJ1wiIHN0eWxlPVwicGFkZGluZzogM3B4IDhweDsgZm9udC1zaXplOiAwLjc1cmVtO1wiPlJlc3RvcmU8L2J1dHRvbj4nO1xuICAgICAgICBodG1sICs9ICcgICAgPC9kaXY+JztcbiAgICAgICAgaHRtbCArPSAnICA8L2Rpdj4nO1xuICAgICAgICBodG1sICs9ICcgIDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuNzVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+JztcbiAgICAgICAgaHRtbCArPSAnICAgICcgKyBuZXcgRGF0ZShiay50aW1lc3RhbXApLnRvTG9jYWxlU3RyaW5nKCkgKyAnIHwgJyArIHNpemVNQiArICcgTUIgfCAnICsgKGJrLmR1cmF0aW9uID8gKGJrLmR1cmF0aW9uIC8gMTAwMCkudG9GaXhlZCgxKSArICdzJyA6ICctLScpO1xuICAgICAgICBpZiAoYmsuZW5jcnlwdGVkKSBodG1sICs9ICcgfCBcdUQ4M0RcdUREMTInO1xuICAgICAgICBodG1sICs9ICcgIDwvZGl2Pic7XG4gICAgICAgIGh0bWwgKz0gJzwvZGl2Pic7XG4gICAgICB9XG4gICAgICBodG1sICs9ICc8L2Rpdj4nO1xuICAgICAgaGlzdG9yeUNvbnRhaW5lci5pbm5lckhUTUwgPSBodG1sO1xuICAgICAgaGlzdG9yeUNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCcuYmFja3VwLXJlc3RvcmUtYnRuJykuZm9yRWFjaChmdW5jdGlvbihidG4pIHtcbiAgICAgICAgYnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oKSB7IHdpbmRvdy5fX3Jlc3RvcmVTZXJ2ZXJCYWNrdXAoYnRuLmRhdGFzZXQuYmFja3VwSWQpOyB9KTtcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGhpc3RvcnlDb250YWluZXIuaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiIHN0eWxlPVwiY29sb3I6IHZhcigtLWJhZC1mZyk7XCI+RmFpbGVkOiAnICsgZXNjYXBlSHRtbChlLm1lc3NhZ2UpICsgJzwvZGl2Pic7XG4gICAgfVxuICB9XG5cbiAgd2luZG93Ll9fcmVzdG9yZVNlcnZlckJhY2t1cCA9IGFzeW5jIGZ1bmN0aW9uKGJhY2t1cElkKSB7XG4gICAgaWYgKCFjb25maXJtKCdSZXN0b3JlIGZyb20gdGhpcyBzZXJ2ZXIgYmFja3VwPyBUaGlzIHdpbGwgb3ZlcndyaXRlIGN1cnJlbnQgY29uZmlndXJhdGlvbi4nKSkgcmV0dXJuO1xuICAgIHRyeSB7XG4gICAgICB2YXIgcmVzID0gYXdhaXQgc2VjdXJlRmV0Y2goJy9hcGkvdjEvYmFja3Vwcy9yZXN0b3JlLycgKyBiYWNrdXBJZCwge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsgcmVzdG9yZVNlcnZpY2VzOiB0cnVlLCByZXN0b3JlQ29uZmlnOiB0cnVlIH0pXG4gICAgICB9KTtcbiAgICAgIHZhciBkYXRhID0gYXdhaXQgcmVzLmpzb24oKTtcbiAgICAgIGlmIChkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgc2hvd05vdGlmaWNhdGlvbignUmVzdG9yZSBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5IScsICdzdWNjZXNzJyk7XG4gICAgICAgIGxvY2F0aW9uLnJlbG9hZCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2hvd05vdGlmaWNhdGlvbignUmVzdG9yZSBmYWlsZWQ6ICcgKyAoZGF0YS5lcnJvciB8fCAnVW5rbm93biBlcnJvcicpLCAnZXJyb3InKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7IHNob3dOb3RpZmljYXRpb24oJ1Jlc3RvcmUgZXJyb3I6ICcgKyBlLm1lc3NhZ2UsICdlcnJvcicpOyB9XG4gIH07XG5cbiAgLy8gTGF6eS1sb2FkIHRhYnNcbiAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW2RhdGEtcGFuZWw9XCJiYWNrdXAtc2NoZWR1bGVzLXRhYlwiXScpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGxvYWRTY2hlZHVsZXNUYWIpO1xuICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1wYW5lbD1cImJhY2t1cC1kaXNrLXRhYlwiXScpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGxvYWREaXNrQmFja3Vwcyk7XG4gIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLXBhbmVsPVwiYmFja3VwLXBvaW50aW50aW1lLXRhYlwiXScpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGxvYWRQb2ludEluVGltZVRhYik7XG4gIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLXBhbmVsPVwiYmFja3VwLWhpc3RvcnktdGFiXCJdJyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgbG9hZEJhY2t1cEhpc3RvcnkpO1xuXG4gIC8vID09PT09IFBvaW50LWluLVRpbWUgUmVzdG9yZSBUYWIgPT09PT1cbiAgYXN5bmMgZnVuY3Rpb24gbG9hZFBvaW50SW5UaW1lVGFiKCkge1xuICAgIGlmICghcG9pbnRpbnRpbWVDb250YWluZXIpIHJldHVybjtcblxuICAgIC8vIENoZWNrIHByZW1pdW1cbiAgICB0cnkge1xuICAgICAgdmFyIGxpY2Vuc2VSZXMgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS9saWNlbnNlL3N0YXR1cycpO1xuICAgICAgdmFyIGxpY2Vuc2VEYXRhID0gYXdhaXQgbGljZW5zZVJlcy5qc29uKCk7XG4gICAgICBpZiAobGljZW5zZURhdGEudGllciAhPT0gJ3ByZW1pdW0nKSB7XG4gICAgICAgIHBvaW50aW50aW1lQ29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIiBzdHlsZT1cInBhZGRpbmc6IDI0cHg7IHRleHQtYWxpZ246IGNlbnRlcjtcIj4nICtcbiAgICAgICAgICAnPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMnJlbTsgbWFyZ2luLWJvdHRvbTogMTJweDtcIj5cdTJCNTA8L2Rpdj4nICtcbiAgICAgICAgICAnPGRpdiBzdHlsZT1cImZvbnQtd2VpZ2h0OiA2MDA7IG1hcmdpbi1ib3R0b206IDhweDtcIj5QcmVtaXVtIEZlYXR1cmU8L2Rpdj4nICtcbiAgICAgICAgICAnPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC44NXJlbTsgY29sb3I6IHZhcigtLW11dGVkKTtcIj5Qb2ludC1pbi10aW1lIHJlc3RvcmUgcmVxdWlyZXMgRGFzaENhZGR5IFByZW1pdW0gd2l0aCBhdXRvLWJhY2t1cCBlbmFibGVkLjwvZGl2PicgK1xuICAgICAgICAgICc8YnV0dG9uIG9uY2xpY2s9XCJzaG93Tm90aWZpY2F0aW9uKFxcJ1VwZ3JhZGUgdG8gUHJlbWl1bSBmb3IgcG9pbnQtaW4tdGltZSByZXN0b3JlIVxcJywgXFwnaW5mb1xcJyk7IHNjcm9sbFRvU2VjdGlvbihcXCdsaWNlbnNlXFwnKTtcIiBzdHlsZT1cIm1hcmdpbi10b3A6IDE2cHg7IHBhZGRpbmc6IDhweCAyMHB4OyBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTM1ZGVnLCAjZjM5YzEyLCAjZTY3ZTIyKTsgYm9yZGVyOiBub25lOyBjb2xvcjogd2hpdGU7IGJvcmRlci1yYWRpdXM6IDhweDsgY3Vyc29yOiBwb2ludGVyOyBmb250LXdlaWdodDogNjAwO1wiPlVwZ3JhZGUgdG8gUHJlbWl1bTwvYnV0dG9uPicgK1xuICAgICAgICAgICc8L2Rpdj4nO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkgeyAvKiBpZ25vcmUgKi8gfVxuXG4gICAgcG9pbnRpbnRpbWVDb250YWluZXIuaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPjxzcGFuIGNsYXNzPVwiYnJhbmQtc3Bpbm5lclwiPjwvc3Bhbj4gTG9hZGluZy4uLjwvZGl2Pic7XG5cbiAgICB0cnkge1xuICAgICAgLy8gRmV0Y2ggc2VydmljZXMgZm9yIGRyb3Bkb3duXG4gICAgICB2YXIgc2VydmljZXNSZXMgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS9zZXJ2aWNlcycpO1xuICAgICAgdmFyIHNlcnZpY2VzRGF0YSA9IGF3YWl0IHNlcnZpY2VzUmVzLmpzb24oKTtcbiAgICAgIHZhciBzZXJ2aWNlcyA9IHNlcnZpY2VzRGF0YS5zZXJ2aWNlcyB8fCBbXTtcblxuICAgICAgaWYgKHNlcnZpY2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBwb2ludGludGltZUNvbnRhaW5lci5pbm5lckhUTUwgPSAnPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+PHNwYW4gY2xhc3M9XCJlbXB0eS1pY29uXCI+XHVEODNEXHVEQ0U2PC9zcGFuPiBObyBhcHBzIGRlcGxveWVkIHlldDwvZGl2Pic7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGh0bWwgPSAnPGRpdiBzdHlsZT1cInBhZGRpbmc6IDhweCAwIDEycHg7XCI+JyArXG4gICAgICAgICc8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgZ2FwOiA4cHg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IG1hcmdpbi1ib3R0b206IDEycHg7XCI+JyArXG4gICAgICAgICcgIDxsYWJlbCBzdHlsZT1cImZvbnQtc2l6ZTogMC44NXJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgd2hpdGUtc3BhY2U6IG5vd3JhcDtcIj5BcHA6PC9sYWJlbD4nICtcbiAgICAgICAgJyAgPHNlbGVjdCBpZD1cInBpdC1hcHAtc2VsZWN0XCIgc3R5bGU9XCJmbGV4OiAxOyBwYWRkaW5nOiA4cHg7IGJvcmRlci1yYWRpdXM6IDZweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgYmFja2dyb3VuZDogdmFyKC0tYmFzZSk7IG1heC13aWR0aDogMjQwcHg7XCI+JztcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2VydmljZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaHRtbCArPSAnPG9wdGlvbiB2YWx1ZT1cIicgKyBlc2NhcGVIdG1sKHNlcnZpY2VzW2ldLmlkIHx8IHNlcnZpY2VzW2ldLm5hbWUgfHwgJycpICsgJ1wiPicgK1xuICAgICAgICAgIGVzY2FwZUh0bWwoc2VydmljZXNbaV0ubmFtZSB8fCBzZXJ2aWNlc1tpXS5pZCB8fCAnJykgKyAnPC9vcHRpb24+JztcbiAgICAgIH1cbiAgICAgIGh0bWwgKz0gJzwvc2VsZWN0PicgK1xuICAgICAgICAnICA8YnV0dG9uIGlkPVwicGl0LWxvYWQtYnRuXCIgc3R5bGU9XCJwYWRkaW5nOiA4cHggMTZweDsgYmFja2dyb3VuZDogdmFyKC0tYWNjZW50KTsgYm9yZGVyOiBub25lOyBjb2xvcjogd2hpdGU7IGJvcmRlci1yYWRpdXM6IDZweDsgY3Vyc29yOiBwb2ludGVyOyBmb250LXdlaWdodDogNTAwO1wiPkxvYWQgQmFja3VwczwvYnV0dG9uPicgK1xuICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICc8ZGl2IGlkPVwicGl0LWJhY2t1cHMtbGlzdFwiIHN0eWxlPVwibWF4LWhlaWdodDogMzIwcHg7IG92ZXJmbG93LXk6IGF1dG87XCI+PC9kaXY+JyArXG4gICAgICAgICc8L2Rpdj4nO1xuXG4gICAgICBwb2ludGludGltZUNvbnRhaW5lci5pbm5lckhUTUwgPSBodG1sO1xuXG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncGl0LWxvYWQtYnRuJyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBhcHBJZCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwaXQtYXBwLXNlbGVjdCcpPy52YWx1ZTtcbiAgICAgICAgaWYgKGFwcElkKSBsb2FkUG9pbnRJblRpbWVCYWNrdXBzKGFwcElkKTtcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHBvaW50aW50aW1lQ29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIiBzdHlsZT1cImNvbG9yOiB2YXIoLS1iYWQtZmcpO1wiPkZhaWxlZDogJyArIGVzY2FwZUh0bWwoZS5tZXNzYWdlKSArICc8L2Rpdj4nO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGxvYWRQb2ludEluVGltZUJhY2t1cHMoYXBwSWQpIHtcbiAgICB2YXIgbGlzdEVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BpdC1iYWNrdXBzLWxpc3QnKTtcbiAgICBpZiAoIWxpc3RFbCkgcmV0dXJuO1xuXG4gICAgbGlzdEVsLmlubmVySFRNTCA9ICc8ZGl2IHN0eWxlPVwicGFkZGluZzogMjBweDsgdGV4dC1hbGlnbjogY2VudGVyO1wiPjxzcGFuIGNsYXNzPVwiYnJhbmQtc3Bpbm5lclwiPjwvc3Bhbj4gTG9hZGluZyBiYWNrdXBzLi4uPC9kaXY+JztcblxuICAgIHRyeSB7XG4gICAgICB2YXIgcmVzID0gYXdhaXQgZmV0Y2goJy9hcGkvdjEvYmFja3Vwcy9maWxlcy8nICsgZW5jb2RlVVJJQ29tcG9uZW50KGFwcElkKSk7XG4gICAgICB2YXIgZGF0YSA9IGF3YWl0IHJlcy5qc29uKCk7XG5cbiAgICAgIGlmICghZGF0YS5zdWNjZXNzIHx8ICFkYXRhLmZpbGVzIHx8IGRhdGEuZmlsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGxpc3RFbC5pbm5lckhUTUwgPSAnPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+PHNwYW4gY2xhc3M9XCJlbXB0eS1pY29uXCI+XHVEODNEXHVEQ0JFPC9zcGFuPiBObyBiYWNrdXAgZmlsZXMgZm9yICcgKyBlc2NhcGVIdG1sKGFwcElkKSArICc8L2Rpdj4nO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBodG1sID0gJzxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuNzVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi1ib3R0b206IDhweDtcIj4nICsgZGF0YS5maWxlcy5sZW5ndGggKyAnIGJhY2t1cChzKTwvZGl2PicgK1xuICAgICAgICAnPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47IGdhcDogNnB4O1wiPic7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5maWxlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgZiA9IGRhdGEuZmlsZXNbaV07XG4gICAgICAgIHZhciBkYXRlU3RyID0gbmV3IERhdGUoZi50aW1lc3RhbXApLnRvTG9jYWxlU3RyaW5nKCk7XG4gICAgICAgIGh0bWwgKz0gJzxkaXYgc3R5bGU9XCJwYWRkaW5nOiAxMHB4IDEycHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmFzZSk7IGJvcmRlci1yYWRpdXM6IDhweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcIj4nICtcbiAgICAgICAgICAnPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjsgYWxpZ24taXRlbXM6IGNlbnRlcjsgbWFyZ2luLWJvdHRvbTogNHB4O1wiPicgK1xuICAgICAgICAgICcgIDxkaXYgc3R5bGU9XCJmb250LXdlaWdodDogNTAwOyBmb250LXNpemU6IDAuODVyZW07XCI+JyArIGVzY2FwZUh0bWwoZi5uYW1lKSArICc8L2Rpdj4nICtcbiAgICAgICAgICAnICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjc1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPicgKyBmLnNpemVGb3JtYXR0ZWQgKyAnPC9kaXY+JyArXG4gICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAgICc8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjc1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW4tYm90dG9tOiA4cHg7XCI+JyArIGRhdGVTdHIgKyAnPC9kaXY+JyArXG4gICAgICAgICAgJzxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBnYXA6IDZweDtcIj4nICtcbiAgICAgICAgICAnICA8YnV0dG9uIGNsYXNzPVwicGl0LWNvbXBhcmUtYnRuXCIgZGF0YS1hcHBpZD1cIicgKyBlc2NhcGVIdG1sKGFwcElkKSArICdcIiBkYXRhLWZpbGVuYW1lPVwiJyArIGVzY2FwZUh0bWwoZi5uYW1lKSArICdcIiBzdHlsZT1cInBhZGRpbmc6IDRweCAxMHB4OyBmb250LXNpemU6IDAuNzVyZW07IGJhY2tncm91bmQ6IHRyYW5zcGFyZW50OyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1hY2NlbnQpOyBjb2xvcjogdmFyKC0tYWNjZW50KTsgYm9yZGVyLXJhZGl1czogNXB4OyBjdXJzb3I6IHBvaW50ZXI7XCI+Q29tcGFyZTwvYnV0dG9uPicgK1xuICAgICAgICAgICcgIDxidXR0b24gY2xhc3M9XCJwaXQtcmVzdG9yZS1idG5cIiBkYXRhLWFwcGlkPVwiJyArIGVzY2FwZUh0bWwoYXBwSWQpICsgJ1wiIGRhdGEtZmlsZW5hbWU9XCInICsgZXNjYXBlSHRtbChmLm5hbWUpICsgJ1wiIHN0eWxlPVwicGFkZGluZzogNHB4IDEwcHg7IGZvbnQtc2l6ZTogMC43NXJlbTsgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgdmFyKC0tb2stZmcpLCAjMjdhZTYwKTsgYm9yZGVyOiBub25lOyBjb2xvcjogd2hpdGU7IGJvcmRlci1yYWRpdXM6IDVweDsgY3Vyc29yOiBwb2ludGVyOyBmb250LXdlaWdodDogNTAwO1wiPlJlc3RvcmU8L2J1dHRvbj4nICtcbiAgICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICAgJzwvZGl2Pic7XG4gICAgICB9XG4gICAgICBodG1sICs9ICc8L2Rpdj4nO1xuICAgICAgbGlzdEVsLmlubmVySFRNTCA9IGh0bWw7XG5cbiAgICAgIC8vIFdpcmUgdXAgYnV0dG9uc1xuICAgICAgbGlzdEVsLnF1ZXJ5U2VsZWN0b3JBbGwoJy5waXQtY29tcGFyZS1idG4nKS5mb3JFYWNoKGZ1bmN0aW9uKGJ0bikge1xuICAgICAgICBidG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbigpIHsgY29tcGFyZUJhY2t1cEZpbGUoYnRuLmRhdGFzZXQuYXBwaWQsIGJ0bi5kYXRhc2V0LmZpbGVuYW1lKTsgfSk7XG4gICAgICB9KTtcbiAgICAgIGxpc3RFbC5xdWVyeVNlbGVjdG9yQWxsKCcucGl0LXJlc3RvcmUtYnRuJykuZm9yRWFjaChmdW5jdGlvbihidG4pIHtcbiAgICAgICAgYnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oKSB7IHJlc3RvcmVCYWNrdXBGaWxlKGJ0bi5kYXRhc2V0LmFwcGlkLCBidG4uZGF0YXNldC5maWxlbmFtZSk7IH0pO1xuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgbGlzdEVsLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIiBzdHlsZT1cImNvbG9yOiB2YXIoLS1iYWQtZmcpO1wiPkZhaWxlZDogJyArIGVzY2FwZUh0bWwoZS5tZXNzYWdlKSArICc8L2Rpdj4nO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGNvbXBhcmVCYWNrdXBGaWxlKGFwcElkLCBmaWxlbmFtZSkge1xuICAgIHRyeSB7XG4gICAgICB2YXIgcmVzID0gYXdhaXQgc2VjdXJlRmV0Y2goJy9hcGkvdjEvYmFja3Vwcy9jb21wYXJlLycgKyBlbmNvZGVVUklDb21wb25lbnQoZmlsZW5hbWUpLCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe30pXG4gICAgICB9KTtcbiAgICAgIHZhciBkYXRhID0gYXdhaXQgcmVzLmpzb24oKTtcbiAgICAgIGlmICghZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oJ0NvbXBhcmUgZmFpbGVkOiAnICsgKGRhdGEuZXJyb3IgfHwgJ1Vua25vd24nKSwgJ2Vycm9yJyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGRpZmYgPSBkYXRhLmRpZmY7XG4gICAgICB2YXIgaHRtbCA9ICc8ZGl2IHN0eWxlPVwicG9zaXRpb246IGZpeGVkOyB0b3A6IDA7IGxlZnQ6IDA7IHJpZ2h0OiAwOyBib3R0b206IDA7IGJhY2tncm91bmQ6IHJnYmEoMCwwLDAsMC41KTsgei1pbmRleDogMTAwMDA7IGRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGp1c3RpZnktY29udGVudDogY2VudGVyO1wiIGlkPVwiY29tcGFyZS1vdmVybGF5XCI+JyArXG4gICAgICAgICc8ZGl2IHN0eWxlPVwiYmFja2dyb3VuZDogdmFyKC0tYmFzZSk7IGJvcmRlci1yYWRpdXM6IDEycHg7IG1heC13aWR0aDogNjAwcHg7IHdpZHRoOiA5MCU7IG1heC1oZWlnaHQ6IDgwdmg7IG92ZXJmbG93OiBhdXRvOyBwYWRkaW5nOiAyMHB4OyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1wiPicgK1xuICAgICAgICAnPGg0IHN0eWxlPVwibWFyZ2luOiAwIDAgMTZweDtcIj5cdUQ4M0RcdURDQ0EgQ29tcGFyZTogJyArIGVzY2FwZUh0bWwoZmlsZW5hbWUpICsgJzwvaDQ+JyArXG4gICAgICAgICc8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjhyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi1ib3R0b206IDE2cHg7XCI+U2l6ZTogJyArIChkaWZmLnNpemVGb3JtYXR0ZWQgfHwgJz8nKSArICcgfCBDcmVhdGVkOiAnICsgbmV3IERhdGUoZGlmZi50aW1lc3RhbXApLnRvTG9jYWxlU3RyaW5nKCkgKyAnPC9kaXY+JztcblxuICAgICAgaWYgKGRpZmYuc2VydmljZXMpIHtcbiAgICAgICAgdmFyIHN2Y0NoYW5nZWQgPSBkaWZmLnNlcnZpY2VzLmhhc0NoYW5nZXMgPyAnXHVEODNEXHVERDM0JyA6ICdcdUQ4M0RcdURGRTInO1xuICAgICAgICBodG1sICs9ICc8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMTJweDsgcGFkZGluZzogMTBweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iYXNlKTsgYm9yZGVyLXJhZGl1czogNnB4OyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1wiPicgK1xuICAgICAgICAgICc8ZGl2IHN0eWxlPVwiZm9udC13ZWlnaHQ6IDYwMDsgZm9udC1zaXplOiAwLjg1cmVtOyBtYXJnaW4tYm90dG9tOiA0cHg7XCI+JyArIHN2Y0NoYW5nZWQgKyAnIFNlcnZpY2VzIChiYWNrdXAgdnMgY3VycmVudCk8L2Rpdj4nICtcbiAgICAgICAgICAnPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC44cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPkJhY2t1cDogJyArIGRpZmYuc2VydmljZXMuYmFja3VwQ291bnQgKyAnIHNlcnZpY2VzIHwgQ3VycmVudDogJyArIGRpZmYuc2VydmljZXMuY3VycmVudENvdW50ICsgJyBzZXJ2aWNlczwvZGl2Pic7XG4gICAgICAgIGlmIChkaWZmLnNlcnZpY2VzLmhhc0NoYW5nZXMpIHtcbiAgICAgICAgICBodG1sICs9ICc8ZGl2IHN0eWxlPVwibWFyZ2luLXRvcDogNnB4OyBmb250LXNpemU6IDAuOHJlbTsgY29sb3I6ICNmMzljMTI7XCI+U2VydmljZXMgZGlmZmVyIFx1MjAxNCByZXN0b3Jpbmcgd2lsbCByZXBsYWNlIGN1cnJlbnQgY29uZmlndXJhdGlvbjwvZGl2Pic7XG4gICAgICAgIH1cbiAgICAgICAgaHRtbCArPSAnPC9kaXY+JztcbiAgICAgIH1cblxuICAgICAgaWYgKGRpZmYuY29uZmlnKSB7XG4gICAgICAgIHZhciBjZmdDaGFuZ2VkID0gZGlmZi5jb25maWcuaGFzQ2hhbmdlcyA/ICdcdUQ4M0RcdUREMzQnIDogJ1x1RDgzRFx1REZFMic7XG4gICAgICAgIGh0bWwgKz0gJzxkaXYgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiAxMnB4OyBwYWRkaW5nOiAxMHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJhc2UpOyBib3JkZXItcmFkaXVzOiA2cHg7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XCI+JyArXG4gICAgICAgICAgJzxkaXYgc3R5bGU9XCJmb250LXdlaWdodDogNjAwOyBmb250LXNpemU6IDAuODVyZW07IG1hcmdpbi1ib3R0b206IDRweDtcIj4nICsgY2ZnQ2hhbmdlZCArICcgQ29uZmlndXJhdGlvbjwvZGl2Pic7XG4gICAgICAgIGlmIChkaWZmLmNvbmZpZy5oYXNDaGFuZ2VzKSB7XG4gICAgICAgICAgaHRtbCArPSAnPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC44cmVtOyBjb2xvcjogI2YzOWMxMjtcIj5Db25maWd1cmF0aW9uIGRpZmZlcnMgXHUyMDE0IHJlc3RvcmluZyB3aWxsIHJlcGxhY2UgY3VycmVudCBzZXR0aW5nczwvZGl2Pic7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaHRtbCArPSAnPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC44cmVtOyBjb2xvcjogdmFyKC0tb2stZmcpO1wiPk5vIGNoYW5nZXM8L2Rpdj4nO1xuICAgICAgICB9XG4gICAgICAgIGh0bWwgKz0gJzwvZGl2Pic7XG4gICAgICB9XG5cbiAgICAgIGh0bWwgKz0gJzxidXR0b24gaWQ9XCJjb21wYXJlLWNsb3NlLWJ0blwiIHN0eWxlPVwicGFkZGluZzogOHB4IDIwcHg7IGJhY2tncm91bmQ6IHZhcigtLWFjY2VudCk7IGJvcmRlcjogbm9uZTsgY29sb3I6IHdoaXRlOyBib3JkZXItcmFkaXVzOiA2cHg7IGN1cnNvcjogcG9pbnRlcjsgZm9udC13ZWlnaHQ6IDUwMDtcIj5DbG9zZTwvYnV0dG9uPicgK1xuICAgICAgICAnPC9kaXY+PC9kaXY+JztcblxuICAgICAgZG9jdW1lbnQuYm9keS5pbnNlcnRBZGphY2VudEhUTUwoJ2JlZm9yZWVuZCcsIGh0bWwpO1xuICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NvbXBhcmUtY2xvc2UtYnRuJyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjb21wYXJlLW92ZXJsYXknKT8ucmVtb3ZlKCk7XG4gICAgICB9KTtcbiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjb21wYXJlLW92ZXJsYXknKT8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbihlKSB7XG4gICAgICAgIGlmIChlLnRhcmdldCA9PT0gdGhpcykgdGhpcy5yZW1vdmUoKTtcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHNob3dOb3RpZmljYXRpb24oJ0NvbXBhcmUgZXJyb3I6ICcgKyBlLm1lc3NhZ2UsICdlcnJvcicpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIHJlc3RvcmVCYWNrdXBGaWxlKGFwcElkLCBmaWxlbmFtZSkge1xuICAgIGlmICghY29uZmlybSgnUmVzdG9yZSAnICsgZmlsZW5hbWUgKyAnIGZvciAnICsgYXBwSWQgKyAnP1xcblxcblRoaXMgd2lsbCByZXBsYWNlIGN1cnJlbnQgY29uZmlndXJhdGlvbiwgY3JlZGVudGlhbHMsIGFuZCBkYXRhLiBDb250YWluZXJzIHdpbGwgYmUgcmVzdGFydGVkLicpKSByZXR1cm47XG5cbiAgICB0cnkge1xuICAgICAgdmFyIHJlcyA9IGF3YWl0IHNlY3VyZUZldGNoKCcvYXBpL3YxL2FwcHMvJyArIGVuY29kZVVSSUNvbXBvbmVudChhcHBJZCkgKyAnL3JldmVydC8nICsgZW5jb2RlVVJJQ29tcG9uZW50KGZpbGVuYW1lKSwge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsgcmVzdGFydENvbnRhaW5lcnM6IHRydWUgfSlcbiAgICAgIH0pO1xuICAgICAgdmFyIGRhdGEgPSBhd2FpdCByZXMuanNvbigpO1xuICAgICAgaWYgKGRhdGEuc3VjY2Vzcykge1xuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKGFwcElkICsgJyByZXN0b3JlZCB0byAnICsgZmlsZW5hbWUsICdzdWNjZXNzJyk7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IGxvY2F0aW9uLnJlbG9hZCgpOyB9LCAxNTAwKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oJ1Jlc3RvcmUgZmFpbGVkOiAnICsgKGRhdGEuZXJyb3IgfHwgJ1Vua25vd24nKSwgJ2Vycm9yJyk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgc2hvd05vdGlmaWNhdGlvbignUmVzdG9yZSBlcnJvcjogJyArIGUubWVzc2FnZSwgJ2Vycm9yJyk7XG4gICAgfVxuICB9XG59KSgpO1xuO1xuLy8gPT09PT09PT09PSBSRVNPVVJDRSBNT05JVE9SIChFbmhhbmNlZCkgPT09PT09PT09PVxuKGZ1bmN0aW9uKCkge1xuICAvLyBJbmplY3QgbW9kYWwgSFRNTFxuICBpbmplY3RNb2RhbCgnc3RhdHMtbW9kYWwnLCBgPGRpdiBpZD1cInN0YXRzLW1vZGFsXCIgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsXCI+XG4gICAgPGRpdiBjbGFzcz1cIndlYXRoZXItbW9kYWwtY29udGVudFwiIHN0eWxlPVwibWluLXdpZHRoOiA3NTBweDsgbWF4LXdpZHRoOiA5NTBweDtcIj5cbiAgICAgIDxoMz5cdUQ4M0RcdURDQ0EgUmVzb3VyY2UgTW9uaXRvcjwvaDM+XG4gICAgICA8cCBjbGFzcz1cIm1vZGFsLXN1YnRpdGxlXCI+XG4gICAgICAgIFJlYWwtdGltZSBhbmQgaGlzdG9yaWNhbCBDUFUsIG1lbW9yeSwgbmV0d29yaywgYW5kIGRpc2sgdXNhZ2UgZm9yIGNvbnRhaW5lcnMuXG4gICAgICA8L3A+XG5cbiAgICAgIDwhLS0gVGFiIGJhciAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJwYW5lbC10YWJzXCI+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJwYW5lbC10YWIgYWN0aXZlXCIgZGF0YS1wYW5lbD1cInN0YXRzLWxpdmVcIj5MaXZlIFN0YXRzPC9idXR0b24+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJwYW5lbC10YWJcIiBkYXRhLXBhbmVsPVwic3RhdHMtYWdncmVnYXRlZFwiPjI0aCBTdW1tYXJ5PC9idXR0b24+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJwYW5lbC10YWJcIiBkYXRhLXBhbmVsPVwic3RhdHMtaGlzdG9yeVwiPkhpc3Rvcnk8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInBhbmVsLXRhYlwiIGRhdGEtcGFuZWw9XCJzdGF0cy1hbGVydHNcIj5BbGVydHM8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIFRhYjogTGl2ZSBTdGF0cyAtLT5cbiAgICAgIDxkaXYgaWQ9XCJzdGF0cy1saXZlXCIgY2xhc3M9XCJwYW5lbC1zZWN0aW9uIGFjdGl2ZVwiPlxuICAgICAgICA8ZGl2IGlkPVwic3RhdHMtY29udGFpbmVyXCIgY2xhc3M9XCJzY3JvbGwtY29udGFpbmVyXCI+XG4gICAgICAgICAgPGRpdiBzdHlsZT1cInRleHQtYWxpZ246IGNlbnRlcjsgcGFkZGluZzogNDBweDsgY29sb3I6IHZhcigtLW11dGVkKTtcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYnJhbmQtc3Bpbm5lclwiPjwvc3Bhbj4gTG9hZGluZyBjb250YWluZXIgc3RhdHMuLi5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBUYWI6IDI0aCBBZ2dyZWdhdGVkIFN1bW1hcnkgLS0+XG4gICAgICA8ZGl2IGlkPVwic3RhdHMtYWdncmVnYXRlZFwiIGNsYXNzPVwicGFuZWwtc2VjdGlvblwiPlxuICAgICAgICA8ZGl2IGlkPVwic3RhdHMtYWdncmVnYXRlZC1jb250YWluZXJcIiBjbGFzcz1cInNjcm9sbC1jb250YWluZXJcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZW1wdHktaWNvblwiPlx1RDgzRFx1RENDODwvc3Bhbj5cbiAgICAgICAgICAgIExvYWRpbmcgMjQtaG91ciBhZ2dyZWdhdGVkIG1ldHJpY3MuLi5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBUYWI6IExvbmctdGVybSBIaXN0b3J5IC0tPlxuICAgICAgPGRpdiBpZD1cInN0YXRzLWhpc3RvcnlcIiBjbGFzcz1cInBhbmVsLXNlY3Rpb25cIj5cbiAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGdhcDogOHB4OyBhbGlnbi1pdGVtczogY2VudGVyOyBtYXJnaW4tYm90dG9tOiAxMnB4OyBmbGV4LXdyYXA6IHdyYXA7XCI+XG4gICAgICAgICAgPGxhYmVsIHN0eWxlPVwiZm9udC1zaXplOiAwLjg1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPkNvbnRhaW5lcjo8L2xhYmVsPlxuICAgICAgICAgIDxzZWxlY3QgaWQ9XCJzdGF0cy1oaXN0b3J5LWNvbnRhaW5lclwiIHN0eWxlPVwicGFkZGluZzogNHB4IDhweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iYXNlKTsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgY29sb3I6IHZhcigtLWZnKTsgYm9yZGVyLXJhZGl1czogNHB4OyBmb250LXNpemU6IDAuODVyZW07IGZsZXg6IDE7IG1pbi13aWR0aDogMTgwcHg7XCI+PC9zZWxlY3Q+XG4gICAgICAgICAgPGRpdiBpZD1cInN0YXRzLWhpc3RvcnktcmFuZ2UtYnV0dG9uc1wiIHN0eWxlPVwiZGlzcGxheTogZmxleDsgZ2FwOiA0cHg7XCI+XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwic3RhdHMtcmFuZ2UtYnRuIGFjdGl2ZVwiIGRhdGEtcmFuZ2U9XCIxaFwiPjFoPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwic3RhdHMtcmFuZ2UtYnRuXCIgZGF0YS1yYW5nZT1cIjI0aFwiPjI0aDwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInN0YXRzLXJhbmdlLWJ0blwiIGRhdGEtcmFuZ2U9XCI3ZFwiPjdkPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwic3RhdHMtcmFuZ2UtYnRuXCIgZGF0YS1yYW5nZT1cIjMwZFwiPjMwZDwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInN0YXRzLXJhbmdlLWJ0blwiIGRhdGEtcmFuZ2U9XCIxeVwiPjF5PC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGlkPVwic3RhdHMtaGlzdG9yeS1jb250YWluZXItYXJlYVwiIGNsYXNzPVwic2Nyb2xsLWNvbnRhaW5lclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJlbXB0eS1pY29uXCI+XHVEODNEXHVEQ0NBPC9zcGFuPlxuICAgICAgICAgICAgQ2hvb3NlIGEgY29udGFpbmVyIGFuZCB0aW1lIHJhbmdlIHRvIHZpZXcgaGlzdG9yeS5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBUYWI6IEFsZXJ0IENvbmZpZ3VyYXRpb24gLS0+XG4gICAgICA8ZGl2IGlkPVwic3RhdHMtYWxlcnRzXCIgY2xhc3M9XCJwYW5lbC1zZWN0aW9uXCI+XG4gICAgICAgIDxkaXYgaWQ9XCJzdGF0cy1hbGVydHMtY29udGFpbmVyXCIgY2xhc3M9XCJzY3JvbGwtY29udGFpbmVyXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImVtcHR5LWljb25cIj5cdUQ4M0RcdUREMTQ8L3NwYW4+XG4gICAgICAgICAgICBMb2FkaW5nIGFsZXJ0IGNvbmZpZ3VyYXRpb25zLi4uXG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gQXV0by1yZWZyZXNoIHRvZ2dsZSAoYm90dG9tIGJhcikgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwicGFuZWwtYm90dG9tLWJhclwiPlxuICAgICAgICA8bGFiZWwgY2xhc3M9XCJjaGVja2JveC1sYWJlbFwiIHN0eWxlPVwiZm9udC1zaXplOiAwLjg1cmVtO1wiPlxuICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBpZD1cInN0YXRzLWF1dG8tcmVmcmVzaFwiIGNoZWNrZWQgLz5cbiAgICAgICAgICBBdXRvLXJlZnJlc2ggZXZlcnkgNXNcbiAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgPGJ1dHRvbiBpZD1cInN0YXRzLXJlZnJlc2gtYnRuXCIgY2xhc3M9XCJidG4tc21cIj5cdUQ4M0RcdUREMDQgUmVmcmVzaCBOb3c8L2J1dHRvbj5cbiAgICAgICAgPHNwYW4gaWQ9XCJzdGF0cy1sYXN0LXVwZGF0ZVwiIGNsYXNzPVwidGV4dC1hdXRvLXJpZ2h0XCI+PC9zcGFuPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gQ2xvc2UgQnV0dG9uIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cIndlYXRoZXItbW9kYWwtYnV0dG9ucyBtb2RhbC1mb290ZXItYmFyXCI+XG4gICAgICAgIDxidXR0b24gaWQ9XCJzdGF0cy1jYW5jZWxcIj5DbG9zZTwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PmApO1xuXG4gIGNvbnN0IG1vZGFsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N0YXRzLW1vZGFsJyk7XG4gIGNvbnN0IG9wZW5CdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29udGFpbmVyLXN0YXRzLWJ0bicpO1xuICBjb25zdCBjYW5jZWxCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc3RhdHMtY2FuY2VsJyk7XG4gIGNvbnN0IHJlZnJlc2hCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc3RhdHMtcmVmcmVzaC1idG4nKTtcbiAgY29uc3QgYXV0b1JlZnJlc2hDaGVja2JveCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdGF0cy1hdXRvLXJlZnJlc2gnKTtcbiAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N0YXRzLWNvbnRhaW5lcicpO1xuICBjb25zdCBhZ2dyZWdhdGVkQ29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N0YXRzLWFnZ3JlZ2F0ZWQtY29udGFpbmVyJyk7XG4gIGNvbnN0IGFsZXJ0c0NvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdGF0cy1hbGVydHMtY29udGFpbmVyJyk7XG4gIGNvbnN0IGxhc3RVcGRhdGVTcGFuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N0YXRzLWxhc3QtdXBkYXRlJyk7XG5cbiAgbGV0IHJlZnJlc2hJbnRlcnZhbCA9IG51bGw7XG4gIGxldCBjYWNoZWRNb25pdG9yaW5nRGF0YSA9IG51bGw7XG5cbiAgZnVuY3Rpb24gZm9ybWF0Qnl0ZXMoYnl0ZXMpIHtcbiAgICBpZiAoYnl0ZXMgPT09IDAgfHwgIWJ5dGVzKSByZXR1cm4gJzAgQic7XG4gICAgY29uc3QgayA9IDEwMjQ7XG4gICAgY29uc3Qgc2l6ZXMgPSBbJ0InLCAnS0InLCAnTUInLCAnR0InXTtcbiAgICBjb25zdCBpID0gTWF0aC5mbG9vcihNYXRoLmxvZyhieXRlcykgLyBNYXRoLmxvZyhrKSk7XG4gICAgcmV0dXJuIHBhcnNlRmxvYXQoKGJ5dGVzIC8gTWF0aC5wb3coaywgaSkpLnRvRml4ZWQoMSkpICsgJyAnICsgc2l6ZXNbaV07XG4gIH1cblxuICBmdW5jdGlvbiBnZXRDcHVDb2xvcihwZXJjZW50KSB7XG4gICAgaWYgKHBlcmNlbnQgPCAzMCkgcmV0dXJuICcjMmVjYzcxJztcbiAgICBpZiAocGVyY2VudCA8IDcwKSByZXR1cm4gJyNmMzljMTInO1xuICAgIHJldHVybiAnI2U3NGMzYyc7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRNZW1Db2xvcihwZXJjZW50KSB7XG4gICAgaWYgKHBlcmNlbnQgPCA1MCkgcmV0dXJuICcjMmVjYzcxJztcbiAgICBpZiAocGVyY2VudCA8IDgwKSByZXR1cm4gJyNmMzljMTInO1xuICAgIHJldHVybiAnI2U3NGMzYyc7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBsb2FkU3RhdHMoKSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIFRyeSBuZXcgbW9uaXRvcmluZyBBUEkgZmlyc3QsIGZhbGwgYmFjayB0byBvbGRcbiAgICAgIGxldCBzdGF0cyA9IG51bGw7XG4gICAgICBsZXQgaXNOZXdBcGkgPSBmYWxzZTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL21vbml0b3Jpbmcvc3RhdHMnKTtcbiAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlcy5qc29uKCk7XG4gICAgICAgIGlmIChkYXRhLnN1Y2Nlc3MgJiYgZGF0YS5zdGF0cykgeyBzdGF0cyA9IGRhdGEuc3RhdHM7IGlzTmV3QXBpID0gdHJ1ZTsgY2FjaGVkTW9uaXRvcmluZ0RhdGEgPSBkYXRhLnN0YXRzOyB9XG4gICAgICB9IGNhdGNoIChfKSB7fVxuXG4gICAgICBpZiAoIWlzTmV3QXBpKSB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goJy9hcGkvdjEvc3RhdHMvY29udGFpbmVycycpO1xuICAgICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgICBpZiAoZGF0YS5zdWNjZXNzICYmIGRhdGEuc3RhdHMpIHtcbiAgICAgICAgICAvLyBDb252ZXJ0IGFycmF5IGZvcm1hdCB0byBvYmplY3QgZm9ybWF0XG4gICAgICAgICAgc3RhdHMgPSB7fTtcbiAgICAgICAgICBmb3IgKGNvbnN0IHMgb2YgZGF0YS5zdGF0cykge1xuICAgICAgICAgICAgc3RhdHNbcy5uYW1lXSA9IHsgbmFtZTogcy5uYW1lLCBjdXJyZW50OiB7IGNwdTogcy5jcHUsIG1lbW9yeTogeyBwZXJjZW50OiBzLm1lbW9yeS5wZXJjZW50LCB1c2FnZTogcy5tZW1vcnkudXNlZCwgbGltaXQ6IHMubWVtb3J5LmxpbWl0LCB1c2FnZU1COiBNYXRoLnJvdW5kKHMubWVtb3J5LnVzZWQgLyAxMDQ4NTc2KSwgbGltaXRNQjogTWF0aC5yb3VuZChzLm1lbW9yeS5saW1pdCAvIDEwNDg1NzYpIH0sIG5ldHdvcms6IHsgcnhCeXRlczogcy5uZXR3b3JrLnJ4LCB0eEJ5dGVzOiBzLm5ldHdvcmsudHgsIHJ4TUI6IChzLm5ldHdvcmsucnggLyAxMDQ4NTc2KS50b0ZpeGVkKDEpLCB0eE1COiAocy5uZXR3b3JrLnR4IC8gMTA0ODU3NikudG9GaXhlZCgxKSB9LCBkaXNrOiB7IHJlYWRNQjogMCwgd3JpdGVNQjogMCB9IH0sIHN0YXR1czogcy5zdGF0dXMgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FjaGVkTW9uaXRvcmluZ0RhdGEgPSBzdGF0cztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoIXN0YXRzIHx8IE9iamVjdC5rZXlzKHN0YXRzKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgY29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IHN0eWxlPVwidGV4dC1hbGlnbjogY2VudGVyOyBwYWRkaW5nOiA0MHB4OyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPk5vIHJ1bm5pbmcgY29udGFpbmVycyBmb3VuZDwvZGl2Pic7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgbGV0IGh0bWwgPSAnPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47IGdhcDogOHB4O1wiPic7XG5cbiAgICAgIGZvciAoY29uc3QgW2lkLCBpbmZvXSBvZiBPYmplY3QuZW50cmllcyhzdGF0cykpIHtcbiAgICAgICAgY29uc3QgY3VyID0gaW5mby5jdXJyZW50IHx8IGluZm87XG4gICAgICAgIGNvbnN0IGNwdSA9IGN1ci5jcHU/LnBlcmNlbnQgfHwgMDtcbiAgICAgICAgY29uc3QgbWVtID0gY3VyLm1lbW9yeT8ucGVyY2VudCB8fCAwO1xuICAgICAgICBjb25zdCBjcHVDb2xvciA9IGdldENwdUNvbG9yKGNwdSk7XG4gICAgICAgIGNvbnN0IG1lbUNvbG9yID0gZ2V0TWVtQ29sb3IobWVtKTtcbiAgICAgICAgY29uc3QgbWVtVXNlZCA9IGN1ci5tZW1vcnk/LnVzYWdlIHx8IGN1ci5tZW1vcnk/LnVzZWQgfHwgMDtcbiAgICAgICAgY29uc3QgbWVtTGltaXQgPSBjdXIubWVtb3J5Py5saW1pdCB8fCAwO1xuICAgICAgICBjb25zdCBuZXRSeCA9IGN1ci5uZXR3b3JrPy5yeEJ5dGVzIHx8IGN1ci5uZXR3b3JrPy5yeCB8fCAwO1xuICAgICAgICBjb25zdCBuZXRUeCA9IGN1ci5uZXR3b3JrPy50eEJ5dGVzIHx8IGN1ci5uZXR3b3JrPy50eCB8fCAwO1xuICAgICAgICBjb25zdCBhZ2cgPSBpbmZvLmFnZ3JlZ2F0ZWQ7XG5cbiAgICAgICAgaHRtbCArPSBgXG4gICAgICAgICAgPGRpdiBzdHlsZT1cInBhZGRpbmc6IDEycHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmFzZSk7IGJvcmRlci1yYWRpdXM6IDhweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcIj5cbiAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDEycHg7IG1hcmdpbi1ib3R0b206IDEwcHg7XCI+XG4gICAgICAgICAgICAgIDxzcGFuIHN0eWxlPVwiZm9udC13ZWlnaHQ6IDYwMDsgZmxleDogMTtcIj4ke2luZm8ubmFtZSB8fCBpZH08L3NwYW4+XG4gICAgICAgICAgICAgICR7YWdnID8gYDxzcGFuIHN0eWxlPVwiZm9udC1zaXplOiAwLjY1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBwYWRkaW5nOiAycHggNnB4OyBiYWNrZ3JvdW5kOiBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tYWNjZW50KSAxMCUsIHRyYW5zcGFyZW50KTsgYm9yZGVyLXJhZGl1czogNHB4O1wiPmF2ZyAke2FnZy5jcHU/LmF2Zz8udG9GaXhlZCgwKSB8fCAwfSUgY3B1PC9zcGFuPmAgOiAnJ31cbiAgICAgICAgICAgICAgPHNwYW4gc3R5bGU9XCJmb250LXNpemU6IDAuNzVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IGJhY2tncm91bmQ6IHZhcigtLWJhc2UpOyBwYWRkaW5nOiAycHggOHB4OyBib3JkZXItcmFkaXVzOiA0cHg7XCI+JHtpbmZvLnN0YXR1cyB8fCAncnVubmluZyd9PC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZ3JpZDsgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiByZXBlYXQoMywgMWZyKTsgZ2FwOiAxMnB4O1wiPlxuICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuN3JlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLWJvdHRvbTogNHB4O1wiPkNQVTwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDhweDtcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJmbGV4OiAxOyBoZWlnaHQ6IDZweDsgYmFja2dyb3VuZDogdmFyKC0tYmFzZSk7IGJvcmRlci1yYWRpdXM6IDNweDsgb3ZlcmZsb3c6IGhpZGRlbjtcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImhlaWdodDogMTAwJTsgd2lkdGg6ICR7TWF0aC5taW4oY3B1LCAxMDApfSU7IGJhY2tncm91bmQ6ICR7Y3B1Q29sb3J9OyBib3JkZXItcmFkaXVzOiAzcHg7IHRyYW5zaXRpb246IHdpZHRoIDAuM3M7XCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPVwiZm9udC1zaXplOiAwLjhyZW07IGZvbnQtd2VpZ2h0OiA1MDA7IGNvbG9yOiAke2NwdUNvbG9yfTsgbWluLXdpZHRoOiA0NXB4OyB0ZXh0LWFsaWduOiByaWdodDtcIj4ke2NwdS50b0ZpeGVkKDEpfSU8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuN3JlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLWJvdHRvbTogNHB4O1wiPk1lbW9yeTwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDhweDtcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJmbGV4OiAxOyBoZWlnaHQ6IDZweDsgYmFja2dyb3VuZDogdmFyKC0tYmFzZSk7IGJvcmRlci1yYWRpdXM6IDNweDsgb3ZlcmZsb3c6IGhpZGRlbjtcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImhlaWdodDogMTAwJTsgd2lkdGg6ICR7TWF0aC5taW4obWVtLCAxMDApfSU7IGJhY2tncm91bmQ6ICR7bWVtQ29sb3J9OyBib3JkZXItcmFkaXVzOiAzcHg7IHRyYW5zaXRpb246IHdpZHRoIDAuM3M7XCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPVwiZm9udC1zaXplOiAwLjhyZW07IGZvbnQtd2VpZ2h0OiA1MDA7IGNvbG9yOiAke21lbUNvbG9yfTsgbWluLXdpZHRoOiA0NXB4OyB0ZXh0LWFsaWduOiByaWdodDtcIj4ke21lbS50b0ZpeGVkKDEpfSU8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC42NXJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLXRvcDogMnB4O1wiPiR7Zm9ybWF0Qnl0ZXMobWVtVXNlZCl9IC8gJHtmb3JtYXRCeXRlcyhtZW1MaW1pdCl9PC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuN3JlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLWJvdHRvbTogNHB4O1wiPk5ldHdvcms8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjhyZW07XCI+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBzdHlsZT1cImNvbG9yOiAjMzQ5OGRiO1wiPlx1MjE5MyAke2Zvcm1hdEJ5dGVzKG5ldFJ4KX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbjogMCA0cHg7XCI+Lzwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPVwiY29sb3I6ICNlNzRjM2M7XCI+XHUyMTkxICR7Zm9ybWF0Qnl0ZXMobmV0VHgpfTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgfVxuICAgICAgaHRtbCArPSAnPC9kaXY+JztcbiAgICAgIGNvbnRhaW5lci5pbm5lckhUTUwgPSBodG1sO1xuICAgICAgbGFzdFVwZGF0ZVNwYW4udGV4dENvbnRlbnQgPSAnVXBkYXRlZDogJyArIG5ldyBEYXRlKCkudG9Mb2NhbGVUaW1lU3RyaW5nKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29udGFpbmVyLmlubmVySFRNTCA9IGA8ZGl2IHN0eWxlPVwidGV4dC1hbGlnbjogY2VudGVyOyBwYWRkaW5nOiA0MHB4OyBjb2xvcjogdmFyKC0tYmFkLWZnKTtcIj5cdTI3NEMgRmFpbGVkIHRvIGxvYWQgc3RhdHM6ICR7ZXNjYXBlSHRtbChlLm1lc3NhZ2UpfTwvZGl2PmA7XG4gICAgfVxuICB9XG5cbiAgLy8gPT09IDI0aCBBZ2dyZWdhdGVkIFRhYiA9PT1cbiAgYXN5bmMgZnVuY3Rpb24gbG9hZEFnZ3JlZ2F0ZWQoKSB7XG4gICAgaWYgKCFhZ2dyZWdhdGVkQ29udGFpbmVyKSByZXR1cm47XG4gICAgY29uc3QgZGF0YSA9IGNhY2hlZE1vbml0b3JpbmdEYXRhO1xuICAgIGlmICghZGF0YSB8fCBPYmplY3Qua2V5cyhkYXRhKS5sZW5ndGggPT09IDApIHtcbiAgICAgIGFnZ3JlZ2F0ZWRDb250YWluZXIuaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPjxzcGFuIGNsYXNzPVwiZW1wdHktaWNvblwiPlx1RDgzRFx1RENDODwvc3Bhbj5ObyBtb25pdG9yaW5nIGRhdGEgYXZhaWxhYmxlLiBPcGVuIHRoZSBMaXZlIFN0YXRzIHRhYiBmaXJzdC48L2Rpdj4nO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgaHRtbCA9ICc8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsgZ2FwOiAxMnB4O1wiPic7XG4gICAgZm9yIChjb25zdCBbaWQsIGluZm9dIG9mIE9iamVjdC5lbnRyaWVzKGRhdGEpKSB7XG4gICAgICBjb25zdCBhZ2cgPSBpbmZvLmFnZ3JlZ2F0ZWQ7XG4gICAgICBpZiAoIWFnZykgY29udGludWU7XG4gICAgICBodG1sICs9IGA8ZGl2IHN0eWxlPVwicGFkZGluZzogMTJweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iYXNlKTsgYm9yZGVyLXJhZGl1czogOHB4OyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1wiPlxuICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC13ZWlnaHQ6IDYwMDsgbWFyZ2luLWJvdHRvbTogMTBweDtcIj4ke2luZm8ubmFtZSB8fCBpZH08L2Rpdj5cbiAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGdyaWQ7IGdyaWQtdGVtcGxhdGUtY29sdW1uczogcmVwZWF0KDQsIDFmcik7IGdhcDogOHB4O1wiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGF0LW1pbmktY2FyZFwiPjxzcGFuIGNsYXNzPVwic3RhdC12YWxcIj4ke2FnZy5jcHU/LmF2Zz8udG9GaXhlZCgxKSB8fCAwfSU8L3NwYW4+PHNwYW4gY2xhc3M9XCJzdGF0LWxibFwiPkF2ZyBDUFU8L3NwYW4+PC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInN0YXQtbWluaS1jYXJkXCI+PHNwYW4gY2xhc3M9XCJzdGF0LXZhbFwiPiR7YWdnLmNwdT8ubWF4Py50b0ZpeGVkKDEpIHx8IDB9JTwvc3Bhbj48c3BhbiBjbGFzcz1cInN0YXQtbGJsXCI+TWF4IENQVTwvc3Bhbj48L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RhdC1taW5pLWNhcmRcIj48c3BhbiBjbGFzcz1cInN0YXQtdmFsXCI+JHthZ2cubWVtb3J5Py5hdmc/LnRvRml4ZWQoMSkgfHwgMH0lPC9zcGFuPjxzcGFuIGNsYXNzPVwic3RhdC1sYmxcIj5BdmcgTWVtPC9zcGFuPjwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGF0LW1pbmktY2FyZFwiPjxzcGFuIGNsYXNzPVwic3RhdC12YWxcIj4ke2FnZy5tZW1vcnk/Lm1heD8udG9GaXhlZCgxKSB8fCAwfSU8L3NwYW4+PHNwYW4gY2xhc3M9XCJzdGF0LWxibFwiPk1heCBNZW08L3NwYW4+PC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICAke2FnZy5kYXRhUG9pbnRzID8gYDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuN3JlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLXRvcDogNnB4O1wiPiR7YWdnLmRhdGFQb2ludHN9IGRhdGEgcG9pbnRzIG92ZXIgJHthZ2cudGltZVJhbmdlIHx8IDI0fWg8L2Rpdj5gIDogJyd9XG4gICAgICA8L2Rpdj5gO1xuICAgIH1cbiAgICBodG1sICs9ICc8L2Rpdj4nO1xuICAgIGFnZ3JlZ2F0ZWRDb250YWluZXIuaW5uZXJIVE1MID0gaHRtbDtcbiAgfVxuXG4gIC8vID09PSBBbGVydHMgVGFiID09PVxuICBhc3luYyBmdW5jdGlvbiBsb2FkQWxlcnRzKCkge1xuICAgIGlmICghYWxlcnRzQ29udGFpbmVyKSByZXR1cm47XG4gICAgYWxlcnRzQ29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj48c3BhbiBjbGFzcz1cImJyYW5kLXNwaW5uZXJcIj48L3NwYW4+IExvYWRpbmcgYWxlcnRzLi4uPC9kaXY+JztcblxuICAgIGNvbnN0IGRhdGEgPSBjYWNoZWRNb25pdG9yaW5nRGF0YTtcbiAgICBpZiAoIWRhdGEgfHwgT2JqZWN0LmtleXMoZGF0YSkubGVuZ3RoID09PSAwKSB7XG4gICAgICBhbGVydHNDb250YWluZXIuaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPjxzcGFuIGNsYXNzPVwiZW1wdHktaWNvblwiPlx1RDgzRFx1REQxNDwvc3Bhbj5ObyBjb250YWluZXJzIGZvdW5kLiBPcGVuIHRoZSBMaXZlIFN0YXRzIHRhYiBmaXJzdC48L2Rpdj4nO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIENoZWNrIHByZW1pdW0gc3RhdHVzIGZvciBjb25maWcgc2VjdGlvbiB2aXNpYmlsaXR5XG4gICAgbGV0IGlzUHJlbWl1bSA9IGZhbHNlO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwID0gYXdhaXQgZmV0Y2goJy9hcGkvdjEvbGljZW5zZS9mZWF0dXJlL3Jlc291cmNlLWFsZXJ0cycpO1xuICAgICAgY29uc3QgbGQgPSBhd2FpdCByZXNwLmpzb24oKTtcbiAgICAgIGlzUHJlbWl1bSA9IGxkLmF2YWlsYWJsZTtcbiAgICB9IGNhdGNoIChfKSB7IGlzUHJlbWl1bSA9IGZhbHNlOyB9XG5cbiAgICAvLyBGZXRjaCBhbGVydCBoaXN0b3J5XG4gICAgbGV0IGFsZXJ0SGlzdG9yeSA9IFtdO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBociA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL21vbml0b3JpbmcvYWxlcnRzP2xpbWl0PTUwJyk7XG4gICAgICBjb25zdCBoZCA9IGF3YWl0IGhyLmpzb24oKTtcbiAgICAgIGlmIChoZC5zdWNjZXNzKSBhbGVydEhpc3RvcnkgPSBoZC5oaXN0b3J5IHx8IFtdO1xuICAgIH0gY2F0Y2ggKF8pIHt9XG5cbiAgICAvLyBGZXRjaCBhbGwgYWxlcnQgY29uZmlnc1xuICAgIGxldCBhbGxDb25maWdzID0ge307XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNyID0gYXdhaXQgZmV0Y2goJy9hcGkvdjEvbW9uaXRvcmluZy9hbGVydHMvY29uZmlnJyk7XG4gICAgICBjb25zdCBjZCA9IGF3YWl0IGNyLmpzb24oKTtcbiAgICAgIGlmIChjZC5zdWNjZXNzKSBhbGxDb25maWdzID0gY2QuY29uZmlncyB8fCB7fTtcbiAgICB9IGNhdGNoIChfKSB7fVxuXG4gICAgY29uc3QgY29udGFpbmVycyA9IE9iamVjdC5lbnRyaWVzKGRhdGEpO1xuICAgIGNvbnN0IGNvbnRhaW5lclJvd3MgPSBjb250YWluZXJzLm1hcCgoW2lkLCBpbmZvXSkgPT4ge1xuICAgICAgY29uc3QgY2ZnID0gYWxsQ29uZmlnc1tpZF0gfHwgeyBjcHVUaHJlc2hvbGQ6IDgwLCBtZW1vcnlUaHJlc2hvbGQ6IDkwLCBkaXNrSU9UaHJlc2hvbGQ6IDUwLCBhdXRvUmVzdGFydDogZmFsc2UsIGVuYWJsZWQ6IGZhbHNlIH07XG4gICAgICByZXR1cm4gYFxuICAgICAgICA8dHIgZGF0YS1jb250YWluZXI9XCIke2lkfVwiPlxuICAgICAgICAgIDx0ZCBzdHlsZT1cImZvbnQtd2VpZ2h0OiA2MDA7IHBhZGRpbmc6IDhweDtcIj4ke2luZm8ubmFtZSB8fCBpZH08L3RkPlxuICAgICAgICAgIDx0ZCBzdHlsZT1cInBhZGRpbmc6IDRweCA4cHg7XCI+PGlucHV0IHR5cGU9XCJudW1iZXJcIiBjbGFzcz1cImFsZXJ0LWNwdVwiIHZhbHVlPVwiJHtjZmcuY3B1VGhyZXNob2xkID8/IDgwfVwiIG1pbj1cIjBcIiBtYXg9XCIxMDBcIiBzdHlsZT1cIndpZHRoOiA2MHB4OyBmb250LXNpemU6IDAuOHJlbTsgcGFkZGluZzogMnB4IDRweDtcIiAke2lzUHJlbWl1bSA/ICcnIDogJ2Rpc2FibGVkJ30gLz48L3RkPlxuICAgICAgICAgIDx0ZCBzdHlsZT1cInBhZGRpbmc6IDRweCA4cHg7XCI+PGlucHV0IHR5cGU9XCJudW1iZXJcIiBjbGFzcz1cImFsZXJ0LW1lbVwiIHZhbHVlPVwiJHtjZmcubWVtb3J5VGhyZXNob2xkID8/IDkwfVwiIG1pbj1cIjBcIiBtYXg9XCIxMDBcIiBzdHlsZT1cIndpZHRoOiA2MHB4OyBmb250LXNpemU6IDAuOHJlbTsgcGFkZGluZzogMnB4IDRweDtcIiAke2lzUHJlbWl1bSA/ICcnIDogJ2Rpc2FibGVkJ30gLz48L3RkPlxuICAgICAgICAgIDx0ZCBzdHlsZT1cInBhZGRpbmc6IDRweCA4cHg7XCI+PGlucHV0IHR5cGU9XCJudW1iZXJcIiBjbGFzcz1cImFsZXJ0LWRpc2tcIiB2YWx1ZT1cIiR7Y2ZnLmRpc2tJT1RocmVzaG9sZCA/PyA1MH1cIiBtaW49XCIwXCIgbWF4PVwiMTAwMFwiIHN0eWxlPVwid2lkdGg6IDcwcHg7IGZvbnQtc2l6ZTogMC44cmVtOyBwYWRkaW5nOiAycHggNHB4O1wiICR7aXNQcmVtaXVtID8gJycgOiAnZGlzYWJsZWQnfSAvPjwvdGQ+XG4gICAgICAgICAgPHRkIHN0eWxlPVwicGFkZGluZzogNHB4IDhweDtcIj48aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJhbGVydC1hdXRvcmVzdGFydFwiICR7Y2ZnLmF1dG9SZXN0YXJ0ID8gJ2NoZWNrZWQnIDogJyd9ICR7aXNQcmVtaXVtID8gJycgOiAnZGlzYWJsZWQnfSAvPjwvdGQ+XG4gICAgICAgICAgPHRkIHN0eWxlPVwicGFkZGluZzogNHB4IDhweDtcIj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJhbGVydC10ZXN0LWJ0biBidG4teHNcIiBkYXRhLWNvbnRhaW5lcj1cIiR7aWR9XCIgZGF0YS1uYW1lPVwiJHtpbmZvLm5hbWUgfHwgaWR9XCIgc3R5bGU9XCJwYWRkaW5nOiAycHggOHB4OyBmb250LXNpemU6IDAuNzVyZW07IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmFzZSk7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJvcmRlci1yYWRpdXM6IDRweDsgY3Vyc29yOiBwb2ludGVyO1wiPlRlc3Q8L2J1dHRvbj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L3RyPlxuICAgICAgYDtcbiAgICB9KS5qb2luKCcnKTtcblxuICAgIGNvbnN0IGhpc3RvcnlSb3dzID0gYWxlcnRIaXN0b3J5Lm1hcChlbnRyeSA9PiB7XG4gICAgICBjb25zdCB0aW1lID0gbmV3IERhdGUoZW50cnkudGltZXN0YW1wKS50b0xvY2FsZVN0cmluZygpO1xuICAgICAgY29uc3Qgbm90aWZpZWRNYXJrID0gZW50cnkubm90aWZpZWQgPyAnXHUyNzEzJyA6ICdcdTIwMTQnO1xuICAgICAgcmV0dXJuIGBcbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0ZCBzdHlsZT1cInBhZGRpbmc6IDZweCA4cHg7IGZvbnQtc2l6ZTogMC44cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPiR7dGltZX08L3RkPlxuICAgICAgICAgIDx0ZCBzdHlsZT1cInBhZGRpbmc6IDZweCA4cHg7IGZvbnQtd2VpZ2h0OiA1MDA7XCI+JHtlbnRyeS5jb250YWluZXJOYW1lIHx8IGVudHJ5LmNvbnRhaW5lcklkfTwvdGQ+XG4gICAgICAgICAgPHRkIHN0eWxlPVwicGFkZGluZzogNnB4IDhweDsgdGV4dC10cmFuc2Zvcm06IGNhcGl0YWxpemU7XCI+JHtlbnRyeS5tZXRyaWMgfHwgZW50cnkudHlwZX08L3RkPlxuICAgICAgICAgIDx0ZCBzdHlsZT1cInBhZGRpbmc6IDZweCA4cHg7XCI+JHt0eXBlb2YgZW50cnkudmFsdWUgPT09ICdudW1iZXInID8gZW50cnkudmFsdWUudG9GaXhlZCgxKSA6IGVudHJ5LnZhbHVlfSR7ZW50cnkubWV0cmljID09PSAnZGlzaycgPyAnIE1CL3MnIDogJyUnfTwvdGQ+XG4gICAgICAgICAgPHRkIHN0eWxlPVwicGFkZGluZzogNnB4IDhweDsgdGV4dC1hbGlnbjogY2VudGVyO1wiPiR7bm90aWZpZWRNYXJrfTwvdGQ+XG4gICAgICAgICAgPHRkIHN0eWxlPVwicGFkZGluZzogNnB4IDhweDsgZm9udC1zaXplOiAwLjc1cmVtOyBjb2xvcjogJHtlbnRyeS5hdXRvUmVzdGFydFRyaWdnZXJlZCA/ICcjZjM5YzEyJyA6ICd2YXIoLS1tdXRlZCknfTtcIj4ke2VudHJ5LmF1dG9SZXN0YXJ0VHJpZ2dlcmVkID8gJ1x1MjFCQicgOiAnJ308L3RkPlxuICAgICAgICA8L3RyPlxuICAgICAgYDtcbiAgICB9KS5qb2luKCcnKTtcblxuICAgIGNvbnN0IGNvbmZpZ1NlY3Rpb24gPSBpc1ByZW1pdW0gPyBgXG4gICAgICA8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMjBweDtcIj5cbiAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjsgbWFyZ2luLWJvdHRvbTogMTBweDtcIj5cbiAgICAgICAgICA8aDQgc3R5bGU9XCJtYXJnaW46IDA7IGZvbnQtc2l6ZTogMC45cmVtO1wiPlx1MjY5OVx1RkUwRiBBbGVydCBDb25maWd1cmF0aW9uPC9oND5cbiAgICAgICAgICA8YSBocmVmPVwiI1wiIGlkPVwiZ28tdG8tbm90aWZpY2F0aW9uc1wiIHN0eWxlPVwiZm9udC1zaXplOiAwLjhyZW07IGNvbG9yOiB2YXIoLS1hY2NlbnQpOyB0ZXh0LWRlY29yYXRpb246IG5vbmU7XCI+Q29uZmlndXJlIG5vdGlmaWNhdGlvbnMgXHUyMTkyPC9hPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBzdHlsZT1cIm92ZXJmbG93LXg6IGF1dG87XCI+XG4gICAgICAgICAgPHRhYmxlIHN0eWxlPVwid2lkdGg6IDEwMCU7IGJvcmRlci1jb2xsYXBzZTogY29sbGFwc2U7IGZvbnQtc2l6ZTogMC44NXJlbTtcIj5cbiAgICAgICAgICAgIDx0aGVhZD5cbiAgICAgICAgICAgICAgPHRyIHN0eWxlPVwiYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XCI+XG4gICAgICAgICAgICAgICAgPHRoIHN0eWxlPVwidGV4dC1hbGlnbjogbGVmdDsgcGFkZGluZzogNnB4IDhweDsgY29sb3I6IHZhcigtLW11dGVkKTtcIj5Db250YWluZXI8L3RoPlxuICAgICAgICAgICAgICAgIDx0aCBzdHlsZT1cInRleHQtYWxpZ246IGxlZnQ7IHBhZGRpbmc6IDZweCA4cHg7IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+Q1BVICU8L3RoPlxuICAgICAgICAgICAgICAgIDx0aCBzdHlsZT1cInRleHQtYWxpZ246IGxlZnQ7IHBhZGRpbmc6IDZweCA4cHg7IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+TWVtICU8L3RoPlxuICAgICAgICAgICAgICAgIDx0aCBzdHlsZT1cInRleHQtYWxpZ246IGxlZnQ7IHBhZGRpbmc6IDZweCA4cHg7IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+RGlzayBJL08gTUIvczwvdGg+XG4gICAgICAgICAgICAgICAgPHRoIHN0eWxlPVwidGV4dC1hbGlnbjogY2VudGVyOyBwYWRkaW5nOiA2cHggOHB4OyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPkF1dG8tUmVzdGFydDwvdGg+XG4gICAgICAgICAgICAgICAgPHRoIHN0eWxlPVwicGFkZGluZzogNnB4IDhweDtcIj48L3RoPlxuICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgPC90aGVhZD5cbiAgICAgICAgICAgIDx0Ym9keT4ke2NvbnRhaW5lclJvd3N9PC90Ym9keT5cbiAgICAgICAgICA8L3RhYmxlPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBzdHlsZT1cIm1hcmdpbi10b3A6IDEycHg7IGRpc3BsYXk6IGZsZXg7IGp1c3RpZnktY29udGVudDogZmxleC1lbmQ7XCI+XG4gICAgICAgICAgPGJ1dHRvbiBpZD1cInNhdmUtYWxsLWFsZXJ0c1wiIHN0eWxlPVwicGFkZGluZzogNnB4IDE2cHg7IGZvbnQtc2l6ZTogMC44NXJlbTsgYmFja2dyb3VuZDogdmFyKC0tYWNjZW50KTsgY29sb3I6IHZhcigtLWJhc2UpOyBib3JkZXI6IG5vbmU7IGJvcmRlci1yYWRpdXM6IDRweDsgY3Vyc29yOiBwb2ludGVyOyBmb250LXdlaWdodDogNjAwO1wiPlNhdmUgQWxsPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgYCA6IGBcbiAgICAgIDxkaXYgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiAyMHB4OyBwYWRkaW5nOiAxMnB4OyBiYWNrZ3JvdW5kOiByZ2JhKDI0MSwxOTYsMTUsMC4xKTsgYm9yZGVyOiAxcHggc29saWQgcmdiYSgyNDEsMTk2LDE1LDAuMyk7IGJvcmRlci1yYWRpdXM6IDhweDsgdGV4dC1hbGlnbjogY2VudGVyO1wiPlxuICAgICAgICA8c3BhbiBzdHlsZT1cImNvbG9yOiAjZjFjNDBmOyBmb250LXdlaWdodDogNjAwOyBmb250LXNpemU6IDAuODVyZW07XCI+XHUyQjUwIFByZW1pdW0gRmVhdHVyZTwvc3Bhbj5cbiAgICAgICAgPHAgc3R5bGU9XCJtYXJnaW46IDZweCAwIDA7IGZvbnQtc2l6ZTogMC43NXJlbTsgY29sb3I6IHZhcigtLW11dGVkKTtcIj5VcGdyYWRlIHRvIGNvbmZpZ3VyZSByZXNvdXJjZSBhbGVydCB0aHJlc2hvbGRzIHBlciBjb250YWluZXIuPC9wPlxuICAgICAgICA8YnV0dG9uIGlkPVwidXBncmFkZS1mb3ItYWxlcnRzXCIgc3R5bGU9XCJtYXJnaW4tdG9wOiA4cHg7IHBhZGRpbmc6IDRweCAxMnB4OyBmb250LXNpemU6IDAuNzVyZW07IGJhY2tncm91bmQ6ICNmMWM0MGY7IGNvbG9yOiAjMDAwOyBib3JkZXI6IG5vbmU7IGJvcmRlci1yYWRpdXM6IDRweDsgY3Vyc29yOiBwb2ludGVyOyBmb250LXdlaWdodDogNjAwO1wiPlVwZ3JhZGUgTm93PC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICBgO1xuXG4gICAgYWxlcnRzQ29udGFpbmVyLmlubmVySFRNTCA9IGBcbiAgICAgICR7Y29uZmlnU2VjdGlvbn1cbiAgICAgIDxkaXY+XG4gICAgICAgIDxoNCBzdHlsZT1cIm1hcmdpbjogMCAwIDEwcHg7IGZvbnQtc2l6ZTogMC45cmVtO1wiPlx1RDgzRFx1RENDQiBSZWNlbnQgQWxlcnRzPC9oND5cbiAgICAgICAgJHtoaXN0b3J5Um93cyA/IGBcbiAgICAgICAgICA8ZGl2IHN0eWxlPVwib3ZlcmZsb3cteDogYXV0bztcIj5cbiAgICAgICAgICAgIDx0YWJsZSBzdHlsZT1cIndpZHRoOiAxMDAlOyBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlOyBmb250LXNpemU6IDAuOHJlbTtcIj5cbiAgICAgICAgICAgICAgPHRoZWFkPlxuICAgICAgICAgICAgICAgIDx0ciBzdHlsZT1cImJvcmRlci1ib3R0b206IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1wiPlxuICAgICAgICAgICAgICAgICAgPHRoIHN0eWxlPVwidGV4dC1hbGlnbjogbGVmdDsgcGFkZGluZzogNnB4IDhweDsgY29sb3I6IHZhcigtLW11dGVkKTtcIj5UaW1lPC90aD5cbiAgICAgICAgICAgICAgICAgIDx0aCBzdHlsZT1cInRleHQtYWxpZ246IGxlZnQ7IHBhZGRpbmc6IDZweCA4cHg7IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+Q29udGFpbmVyPC90aD5cbiAgICAgICAgICAgICAgICAgIDx0aCBzdHlsZT1cInRleHQtYWxpZ246IGxlZnQ7IHBhZGRpbmc6IDZweCA4cHg7IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+TWV0cmljPC90aD5cbiAgICAgICAgICAgICAgICAgIDx0aCBzdHlsZT1cInRleHQtYWxpZ246IGxlZnQ7IHBhZGRpbmc6IDZweCA4cHg7IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+VmFsdWU8L3RoPlxuICAgICAgICAgICAgICAgICAgPHRoIHN0eWxlPVwidGV4dC1hbGlnbjogY2VudGVyOyBwYWRkaW5nOiA2cHggOHB4OyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPlx1MjcxMz88L3RoPlxuICAgICAgICAgICAgICAgICAgPHRoIHN0eWxlPVwicGFkZGluZzogNnB4IDhweDtcIj48L3RoPlxuICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgIDwvdGhlYWQ+XG4gICAgICAgICAgICAgIDx0Ym9keT4ke2hpc3RvcnlSb3dzfTwvdGJvZHk+XG4gICAgICAgICAgICA8L3RhYmxlPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICBgIDogJzxkaXYgc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpOyB0ZXh0LWFsaWduOiBjZW50ZXI7IHBhZGRpbmc6IDIwcHg7XCI+Tm8gYWxlcnRzIHJlY29yZGVkIHlldC48L2Rpdj4nfVxuICAgICAgPC9kaXY+XG4gICAgYDtcblxuICAgIC8vIFdpcmUgdXAgc2F2ZS1hbGwgYnV0dG9uXG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NhdmUtYWxsLWFsZXJ0cycpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbmZpZ3MgPSB7fTtcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJyNzdGF0cy1hbGVydHMtY29udGFpbmVyIHRyW2RhdGEtY29udGFpbmVyXScpLmZvckVhY2gocm93ID0+IHtcbiAgICAgICAgY29uc3QgY0lkID0gcm93LmRhdGFzZXQuY29udGFpbmVyO1xuICAgICAgICBjb25maWdzW2NJZF0gPSB7XG4gICAgICAgICAgY3B1VGhyZXNob2xkOiBwYXJzZUludChyb3cucXVlcnlTZWxlY3RvcignLmFsZXJ0LWNwdScpPy52YWx1ZSkgfHwgODAsXG4gICAgICAgICAgbWVtb3J5VGhyZXNob2xkOiBwYXJzZUludChyb3cucXVlcnlTZWxlY3RvcignLmFsZXJ0LW1lbScpPy52YWx1ZSkgfHwgOTAsXG4gICAgICAgICAgZGlza0lPVGhyZXNob2xkOiBwYXJzZUludChyb3cucXVlcnlTZWxlY3RvcignLmFsZXJ0LWRpc2snKT8udmFsdWUpIHx8IDUwLFxuICAgICAgICAgIGF1dG9SZXN0YXJ0OiAhIXJvdy5xdWVyeVNlbGVjdG9yKCcuYWxlcnQtYXV0b3Jlc3RhcnQnKT8uY2hlY2tlZCxcbiAgICAgICAgICBlbmFibGVkOiB0cnVlXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHNlY3VyZUZldGNoKCcvYXBpL3YxL21vbml0b3JpbmcvYWxlcnRzL2NvbmZpZycsIHtcbiAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7IGNvbmZpZ3MgfSlcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGQgPSBhd2FpdCByZXMuanNvbigpO1xuICAgICAgICBjb25zdCBidG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2F2ZS1hbGwtYWxlcnRzJyk7XG4gICAgICAgIGJ0bi50ZXh0Q29udGVudCA9IGQuc3VjY2VzcyA/ICdcdTI3MDUgU2F2ZWQnIDogJ1x1Mjc0QyBGYWlsZWQnO1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHsgYnRuLnRleHRDb250ZW50ID0gJ1NhdmUgQWxsJzsgfSwgMjAwMCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnN0IGJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzYXZlLWFsbC1hbGVydHMnKTtcbiAgICAgICAgYnRuLnRleHRDb250ZW50ID0gJ1x1Mjc0QyBFcnJvcic7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4geyBidG4udGV4dENvbnRlbnQgPSAnU2F2ZSBBbGwnOyB9LCAyMDAwKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIFdpcmUgdXAgbm90aWZpY2F0aW9uIHNldHRpbmdzIGxpbmtcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZ28tdG8tbm90aWZpY2F0aW9ucycpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIChlKSA9PiB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBtb2RhbC5jbGFzc0xpc3QucmVtb3ZlKCdzaG93Jyk7XG4gICAgICBzdG9wQXV0b1JlZnJlc2goKTtcbiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtYW5hZ2Utbm90aWZpY2F0aW9ucycpPy5jbGljaygpO1xuICAgIH0pO1xuXG4gICAgLy8gV2lyZSB1cCB0ZXN0IGJ1dHRvbnNcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuYWxlcnQtdGVzdC1idG4nKS5mb3JFYWNoKGJ0biA9PiB7XG4gICAgICBidG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IG9yaWcgPSBidG4udGV4dENvbnRlbnQ7XG4gICAgICAgIGJ0bi50ZXh0Q29udGVudCA9ICcuLi4nO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IHNlY3VyZUZldGNoKGAvYXBpL3YxL21vbml0b3JpbmcvYWxlcnRzLyR7YnRuLmRhdGFzZXQuY29udGFpbmVyfS90ZXN0YCwgeyBtZXRob2Q6ICdQT1NUJyB9KTtcbiAgICAgICAgICBidG4udGV4dENvbnRlbnQgPSAnXHUyNzA1JztcbiAgICAgICAgICBzaG93Tm90aWZpY2F0aW9uKCdUZXN0IGFsZXJ0IHNlbnQgZm9yICcgKyBidG4uZGF0YXNldC5uYW1lLCAnc3VjY2VzcycsIDMwMDApO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgYnRuLnRleHRDb250ZW50ID0gJ1x1Mjc0Qyc7XG4gICAgICAgIH1cbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7IGJ0bi50ZXh0Q29udGVudCA9IG9yaWc7IH0sIDIwMDApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvLyBXaXJlIHVwIHVwZ3JhZGUgYnV0dG9uXG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3VwZ3JhZGUtZm9yLWFsZXJ0cycpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICAgIG1vZGFsLmNsYXNzTGlzdC5yZW1vdmUoJ3Nob3cnKTtcbiAgICAgIHN0b3BBdXRvUmVmcmVzaCgpO1xuICAgICAgaWYgKHR5cGVvZiBvcGVuTGljZW5zZU1vZGFsID09PSAnZnVuY3Rpb24nKSBvcGVuTGljZW5zZU1vZGFsKCk7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBzdGFydEF1dG9SZWZyZXNoKCkge1xuICAgIGlmIChyZWZyZXNoSW50ZXJ2YWwpIGNsZWFySW50ZXJ2YWwocmVmcmVzaEludGVydmFsKTtcbiAgICBpZiAoYXV0b1JlZnJlc2hDaGVja2JveD8uY2hlY2tlZCkge1xuICAgICAgcmVmcmVzaEludGVydmFsID0gc2V0SW50ZXJ2YWwobG9hZFN0YXRzLCBEQy5QT0xMLlNUQVRTKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBzdG9wQXV0b1JlZnJlc2goKSB7XG4gICAgaWYgKHJlZnJlc2hJbnRlcnZhbCkge1xuICAgICAgY2xlYXJJbnRlcnZhbChyZWZyZXNoSW50ZXJ2YWwpO1xuICAgICAgcmVmcmVzaEludGVydmFsID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvLyBPcGVuIG1vZGFsXG4gIG9wZW5CdG4/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgIG1vZGFsLmNsYXNzTGlzdC5hZGQoJ3Nob3cnKTtcbiAgICBsb2FkU3RhdHMoKTtcbiAgICBzdGFydEF1dG9SZWZyZXNoKCk7XG4gIH0pO1xuXG4gIC8vIENsb3NlIG1vZGFsXG4gIGNhbmNlbEJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgbW9kYWwuY2xhc3NMaXN0LnJlbW92ZSgnc2hvdycpO1xuICAgIHN0b3BBdXRvUmVmcmVzaCgpO1xuICB9KTtcblxuICBtb2RhbD8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZSkgPT4ge1xuICAgIGlmIChlLnRhcmdldCA9PT0gbW9kYWwpIHtcbiAgICAgIG1vZGFsLmNsYXNzTGlzdC5yZW1vdmUoJ3Nob3cnKTtcbiAgICAgIHN0b3BBdXRvUmVmcmVzaCgpO1xuICAgIH1cbiAgfSk7XG5cbiAgcmVmcmVzaEJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBsb2FkU3RhdHMpO1xuXG4gIGF1dG9SZWZyZXNoQ2hlY2tib3g/LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsICgpID0+IHtcbiAgICBpZiAoYXV0b1JlZnJlc2hDaGVja2JveC5jaGVja2VkKSBzdGFydEF1dG9SZWZyZXNoKCk7XG4gICAgZWxzZSBzdG9wQXV0b1JlZnJlc2goKTtcbiAgfSk7XG5cbiAgLy8gTGF6eS1sb2FkIHRhYnNcbiAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW2RhdGEtcGFuZWw9XCJzdGF0cy1hZ2dyZWdhdGVkXCJdJyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgbG9hZEFnZ3JlZ2F0ZWQpO1xuICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1wYW5lbD1cInN0YXRzLWFsZXJ0c1wiXScpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGxvYWRBbGVydHMpO1xuXG4gIC8vID09PSBIaXN0b3J5IFRhYiA9PT1cbiAgY29uc3QgaGlzdG9yeUNvbnRhaW5lclNlbGVjdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdGF0cy1oaXN0b3J5LWNvbnRhaW5lcicpO1xuICBjb25zdCBoaXN0b3J5QXJlYSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdGF0cy1oaXN0b3J5LWNvbnRhaW5lci1hcmVhJyk7XG4gIGNvbnN0IHJhbmdlQnV0dG9ucyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5zdGF0cy1yYW5nZS1idG4nKTtcblxuICBsZXQgY3VycmVudFJhbmdlID0gJzFoJztcblxuICBmdW5jdGlvbiByYW5nZVRvTXMocmFuZ2UpIHtcbiAgICBzd2l0Y2ggKHJhbmdlKSB7XG4gICAgICBjYXNlICcxaCc6ICByZXR1cm4gNjAgKiA2MCAqIDEwMDA7XG4gICAgICBjYXNlICcyNGgnOiByZXR1cm4gMjQgKiA2MCAqIDYwICogMTAwMDtcbiAgICAgIGNhc2UgJzdkJzogIHJldHVybiA3ICogMjQgKiA2MCAqIDYwICogMTAwMDtcbiAgICAgIGNhc2UgJzMwZCc6IHJldHVybiAzMCAqIDI0ICogNjAgKiA2MCAqIDEwMDA7XG4gICAgICBjYXNlICcxeSc6ICByZXR1cm4gMzY1ICogMjQgKiA2MCAqIDYwICogMTAwMDtcbiAgICAgIGRlZmF1bHQ6ICAgIHJldHVybiA2MCAqIDYwICogMTAwMDtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB0aWVyTGFiZWwodGllcikge1xuICAgIGlmICh0aWVyID09PSAncmF3JykgcmV0dXJuICdsaXZlICgxMHMgc2FtcGxlcyknO1xuICAgIGlmICh0aWVyID09PSAnaG91cmx5JykgcmV0dXJuICdob3VybHkgYXZlcmFnZSc7XG4gICAgaWYgKHRpZXIgPT09ICdkYWlseScpIHJldHVybiAnZGFpbHkgYXZlcmFnZSc7XG4gICAgcmV0dXJuIHRpZXI7XG4gIH1cblxuICAvLyBTaW1wbGUgU1ZHIHNwYXJrbGluZSBcdTIwMTQgbm8gZXh0ZXJuYWwgbGliXG4gIGZ1bmN0aW9uIHJlbmRlclNwYXJrbGluZShzYW1wbGVzLCBhY2Nlc3NvciwgY29sb3IsIGxhYmVsLCB1bml0KSB7XG4gICAgaWYgKCFzYW1wbGVzIHx8IHNhbXBsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gYDxkaXYgc3R5bGU9XCJ0ZXh0LWFsaWduOiBjZW50ZXI7IGNvbG9yOiB2YXIoLS1tdXRlZCk7IHBhZGRpbmc6IDIwcHg7XCI+Tm8gZGF0YSBmb3IgJHtlc2NhcGVIdG1sKGxhYmVsKX08L2Rpdj5gO1xuICAgIH1cbiAgICBjb25zdCB2YWx1ZXMgPSBzYW1wbGVzLm1hcChhY2Nlc3NvcikuZmlsdGVyKHYgPT4gdiAhPSBudWxsKTtcbiAgICBpZiAodmFsdWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGA8ZGl2IHN0eWxlPVwidGV4dC1hbGlnbjogY2VudGVyOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBwYWRkaW5nOiAyMHB4O1wiPk5vIGRhdGEgZm9yICR7ZXNjYXBlSHRtbChsYWJlbCl9PC9kaXY+YDtcbiAgICB9XG4gICAgY29uc3QgbWF4ID0gTWF0aC5tYXgoLi4udmFsdWVzLCAxKTtcbiAgICBjb25zdCBtaW4gPSBNYXRoLm1pbiguLi52YWx1ZXMsIDApO1xuICAgIGNvbnN0IHJhbmdlID0gbWF4IC0gbWluIHx8IDE7XG4gICAgY29uc3QgdyA9IDYwMCwgaCA9IDgwLCBwYWQgPSA0O1xuICAgIGNvbnN0IHN0ZXBYID0gKHcgLSBwYWQgKiAyKSAvIE1hdGgubWF4KHZhbHVlcy5sZW5ndGggLSAxLCAxKTtcbiAgICBjb25zdCBwb2ludHMgPSB2YWx1ZXMubWFwKCh2LCBpKSA9PiB7XG4gICAgICBjb25zdCB4ID0gcGFkICsgaSAqIHN0ZXBYO1xuICAgICAgY29uc3QgeSA9IGggLSBwYWQgLSAoKHYgLSBtaW4pIC8gcmFuZ2UpICogKGggLSBwYWQgKiAyKTtcbiAgICAgIHJldHVybiBgJHt4LnRvRml4ZWQoMSl9LCR7eS50b0ZpeGVkKDEpfWA7XG4gICAgfSkuam9pbignICcpO1xuICAgIGNvbnN0IGxhc3QgPSB2YWx1ZXNbdmFsdWVzLmxlbmd0aCAtIDFdO1xuICAgIGNvbnN0IGF2ZyA9IHZhbHVlcy5yZWR1Y2UoKGEsIGIpID0+IGEgKyBiLCAwKSAvIHZhbHVlcy5sZW5ndGg7XG4gICAgcmV0dXJuIGBcbiAgICAgIDxkaXYgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiAxNHB4O1wiPlxuICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGJhc2VsaW5lOyBnYXA6IDEycHg7IG1hcmdpbi1ib3R0b206IDRweDtcIj5cbiAgICAgICAgICA8c3BhbiBzdHlsZT1cImZvbnQtd2VpZ2h0OiA2MDA7IGZvbnQtc2l6ZTogMC45cmVtO1wiPiR7ZXNjYXBlSHRtbChsYWJlbCl9PC9zcGFuPlxuICAgICAgICAgIDxzcGFuIHN0eWxlPVwiZm9udC1zaXplOiAwLjc1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPmxhc3QgJHtsYXN0LnRvRml4ZWQoMSl9JHt1bml0fSBcdTAwQjcgYXZnICR7YXZnLnRvRml4ZWQoMSl9JHt1bml0fSBcdTAwQjcgbWF4ICR7bWF4LnRvRml4ZWQoMSl9JHt1bml0fTwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxzdmcgdmlld0JveD1cIjAgMCAke3d9ICR7aH1cIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPVwibm9uZVwiIHN0eWxlPVwid2lkdGg6IDEwMCU7IGhlaWdodDogJHtofXB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1iYXNlKTsgYm9yZGVyLXJhZGl1czogNHB4O1wiPlxuICAgICAgICAgIDxwb2x5bGluZSBmaWxsPVwibm9uZVwiIHN0cm9rZT1cIiR7Y29sb3J9XCIgc3Ryb2tlLXdpZHRoPVwiMS41XCIgcG9pbnRzPVwiJHtwb2ludHN9XCIgLz5cbiAgICAgICAgPC9zdmc+XG4gICAgICA8L2Rpdj5cbiAgICBgO1xuICB9XG5cbiAgZnVuY3Rpb24gcG9wdWxhdGVIaXN0b3J5Q29udGFpbmVyU2VsZWN0KCkge1xuICAgIGlmICghaGlzdG9yeUNvbnRhaW5lclNlbGVjdCkgcmV0dXJuO1xuICAgIGNvbnN0IGRhdGEgPSBjYWNoZWRNb25pdG9yaW5nRGF0YSB8fCB7fTtcbiAgICBjb25zdCBwcmV2aW91cyA9IGhpc3RvcnlDb250YWluZXJTZWxlY3QudmFsdWU7XG4gICAgY29uc3QgZW50cmllcyA9IE9iamVjdC5lbnRyaWVzKGRhdGEpO1xuICAgIGlmIChlbnRyaWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaGlzdG9yeUNvbnRhaW5lclNlbGVjdC5pbm5lckhUTUwgPSAnPG9wdGlvbiB2YWx1ZT1cIlwiPk5vIGNvbnRhaW5lcnM8L29wdGlvbj4nO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBoaXN0b3J5Q29udGFpbmVyU2VsZWN0LmlubmVySFRNTCA9IGVudHJpZXNcbiAgICAgIC5tYXAoKFtpZCwgaW5mb10pID0+IGA8b3B0aW9uIHZhbHVlPVwiJHtlc2NhcGVIdG1sKGlkKX1cIj4ke2VzY2FwZUh0bWwoaW5mby5uYW1lIHx8IGlkKX08L29wdGlvbj5gKVxuICAgICAgLmpvaW4oJycpO1xuICAgIGlmIChwcmV2aW91cyAmJiBkYXRhW3ByZXZpb3VzXSkgaGlzdG9yeUNvbnRhaW5lclNlbGVjdC52YWx1ZSA9IHByZXZpb3VzO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gbG9hZEhpc3RvcnkoKSB7XG4gICAgaWYgKCFoaXN0b3J5QXJlYSB8fCAhaGlzdG9yeUNvbnRhaW5lclNlbGVjdCkgcmV0dXJuO1xuICAgIGNvbnN0IGNvbnRhaW5lcklkID0gaGlzdG9yeUNvbnRhaW5lclNlbGVjdC52YWx1ZTtcbiAgICBpZiAoIWNvbnRhaW5lcklkKSB7XG4gICAgICBoaXN0b3J5QXJlYS5pbm5lckhUTUwgPSAnPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+PHNwYW4gY2xhc3M9XCJlbXB0eS1pY29uXCI+XHVEODNEXHVEQ0NBPC9zcGFuPk5vIGNvbnRhaW5lciBzZWxlY3RlZC48L2Rpdj4nO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBlbmRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICBjb25zdCBzdGFydFRpbWUgPSBlbmRUaW1lIC0gcmFuZ2VUb01zKGN1cnJlbnRSYW5nZSk7XG4gICAgaGlzdG9yeUFyZWEuaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPjxzcGFuIGNsYXNzPVwiYnJhbmQtc3Bpbm5lclwiPjwvc3Bhbj4gTG9hZGluZyBoaXN0b3J5Li4uPC9kaXY+JztcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaChgL2FwaS92MS9tb25pdG9yaW5nL2hpc3RvcnkvJHtlbmNvZGVVUklDb21wb25lbnQoY29udGFpbmVySWQpfT9zdGFydFRpbWU9JHtzdGFydFRpbWV9JmVuZFRpbWU9JHtlbmRUaW1lfWApO1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlcy5qc29uKCk7XG4gICAgICBpZiAoIWRhdGEuc3VjY2VzcykgdGhyb3cgbmV3IEVycm9yKGRhdGEuZXJyb3IgfHwgJ0ZhaWxlZCB0byBsb2FkIGhpc3RvcnknKTtcblxuICAgICAgY29uc3Qgc2FtcGxlcyA9IGRhdGEuc2FtcGxlcyB8fCBbXTtcbiAgICAgIGNvbnN0IHRpZXIgPSBkYXRhLnRpZXIgfHwgJ3Jhdyc7XG5cbiAgICAgIGlmIChzYW1wbGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBoaXN0b3J5QXJlYS5pbm5lckhUTUwgPSBgPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+PHNwYW4gY2xhc3M9XCJlbXB0eS1pY29uXCI+XHVEODNEXHVEQ0NBPC9zcGFuPk5vIGRhdGEgZm9yIHRoZSBsYXN0ICR7Y3VycmVudFJhbmdlfS4gVGllcjogJHt0aWVyTGFiZWwodGllcil9LjwvZGl2PmA7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gRGlmZmVyZW50IHNoYXBlIGJldHdlZW4gcmF3IHZzIHJvbGxlZC11cCBzYW1wbGVzXG4gICAgICBjb25zdCBpc1JhdyA9IHRpZXIgPT09ICdyYXcnO1xuICAgICAgY29uc3QgY3B1QWNjZXNzb3IgPSBpc1JhdyA/IChzKSA9PiBzLmNwdT8ucGVyY2VudCA6IChzKSA9PiBzLmNwdT8uYXZnO1xuICAgICAgY29uc3QgbWVtQWNjZXNzb3IgPSBpc1JhdyA/IChzKSA9PiBzLm1lbW9yeT8ucGVyY2VudCA6IChzKSA9PiBzLm1lbW9yeT8uYXZnUGVyY2VudDtcbiAgICAgIGNvbnN0IG5ldFJ4QWNjZXNzb3IgPSBpc1JhdyA/IChzKSA9PiAocy5uZXR3b3JrPy5yeE1CIHx8IDApIDogKHMpID0+IChzLm5ldHdvcms/LnJ4TUIgfHwgMCk7XG4gICAgICBjb25zdCBuZXRUeEFjY2Vzc29yID0gaXNSYXcgPyAocykgPT4gKHMubmV0d29yaz8udHhNQiB8fCAwKSA6IChzKSA9PiAocy5uZXR3b3JrPy50eE1CIHx8IDApO1xuXG4gICAgICBsZXQgaHRtbCA9IGBcbiAgICAgICAgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC43NXJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLWJvdHRvbTogOHB4O1wiPlxuICAgICAgICAgICR7c2FtcGxlcy5sZW5ndGh9IHNhbXBsZXMgXHUwMEI3ICR7ZXNjYXBlSHRtbCh0aWVyTGFiZWwodGllcikpfSBcdTAwQjcgJHtuZXcgRGF0ZShzdGFydFRpbWUpLnRvTG9jYWxlU3RyaW5nKCl9IFx1MjE5MiAke25ldyBEYXRlKGVuZFRpbWUpLnRvTG9jYWxlU3RyaW5nKCl9XG4gICAgICAgIDwvZGl2PlxuICAgICAgYDtcbiAgICAgIGh0bWwgKz0gcmVuZGVyU3BhcmtsaW5lKHNhbXBsZXMsIGNwdUFjY2Vzc29yLCAnIzJlY2M3MScsICdDUFUnLCAnJScpO1xuICAgICAgaHRtbCArPSByZW5kZXJTcGFya2xpbmUoc2FtcGxlcywgbWVtQWNjZXNzb3IsICcjMzQ5OGRiJywgJ01lbW9yeScsICclJyk7XG4gICAgICBodG1sICs9IHJlbmRlclNwYXJrbGluZShzYW1wbGVzLCBuZXRSeEFjY2Vzc29yLCAnIzliNTliNicsICdOZXR3b3JrIFJYJywgJyBNQicpO1xuICAgICAgaHRtbCArPSByZW5kZXJTcGFya2xpbmUoc2FtcGxlcywgbmV0VHhBY2Nlc3NvciwgJyNlNjdlMjInLCAnTmV0d29yayBUWCcsICcgTUInKTtcblxuICAgICAgaGlzdG9yeUFyZWEuaW5uZXJIVE1MID0gaHRtbDtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBoaXN0b3J5QXJlYS5pbm5lckhUTUwgPSBgPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+PHNwYW4gY2xhc3M9XCJlbXB0eS1pY29uXCI+XHUyNkEwXHVGRTBGPC9zcGFuPkZhaWxlZCB0byBsb2FkIGhpc3Rvcnk6ICR7ZXNjYXBlSHRtbChlLm1lc3NhZ2UpfTwvZGl2PmA7XG4gICAgfVxuICB9XG5cbiAgcmFuZ2VCdXR0b25zLmZvckVhY2goYnRuID0+IHtcbiAgICBidG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICByYW5nZUJ1dHRvbnMuZm9yRWFjaChiID0+IGIuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJykpO1xuICAgICAgYnRuLmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZScpO1xuICAgICAgY3VycmVudFJhbmdlID0gYnRuLmRhdGFzZXQucmFuZ2U7XG4gICAgICBsb2FkSGlzdG9yeSgpO1xuICAgIH0pO1xuICB9KTtcblxuICBoaXN0b3J5Q29udGFpbmVyU2VsZWN0Py5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCBsb2FkSGlzdG9yeSk7XG5cbiAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW2RhdGEtcGFuZWw9XCJzdGF0cy1oaXN0b3J5XCJdJyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgIHBvcHVsYXRlSGlzdG9yeUNvbnRhaW5lclNlbGVjdCgpO1xuICAgIGxvYWRIaXN0b3J5KCk7XG4gIH0pO1xufSkoKTtcbjtcbi8vID09PT09PT09PT0gSEVBTFRIIENIRUNLIERBU0hCT0FSRCA9PT09PT09PT09XG4oZnVuY3Rpb24oKSB7XG4gIC8vIEluamVjdCBtb2RhbCBIVE1MXG4gIGluamVjdE1vZGFsKCdoZWFsdGgtbW9kYWwnLCBgPGRpdiBpZD1cImhlYWx0aC1tb2RhbFwiIGNsYXNzPVwid2VhdGhlci1tb2RhbFwiPlxuICAgIDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsLWNvbnRlbnRcIiBzdHlsZT1cIm1pbi13aWR0aDogODAwcHg7IG1heC13aWR0aDogMTAwMHB4O1wiPlxuICAgICAgPGgzPlx1RDgzQ1x1REZFNSBIZWFsdGggQ2hlY2sgRGFzaGJvYXJkPC9oMz5cbiAgICAgIDxwIGNsYXNzPVwibW9kYWwtc3VidGl0bGVcIj5cbiAgICAgICAgU2VydmljZSB1cHRpbWUgdHJhY2tpbmcsIFNMQSBtb25pdG9yaW5nLCBhbmQgaW5jaWRlbnQgbWFuYWdlbWVudC5cbiAgICAgIDwvcD5cblxuICAgICAgPGRpdiBjbGFzcz1cInBhbmVsLXRhYnNcIj5cbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInBhbmVsLXRhYiBhY3RpdmVcIiBkYXRhLXBhbmVsPVwiaGVhbHRoLXN0YXR1c1wiPlN0YXR1czwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwicGFuZWwtdGFiXCIgZGF0YS1wYW5lbD1cImhlYWx0aC1pbmNpZGVudHNcIj5JbmNpZGVudHM8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInBhbmVsLXRhYlwiIGRhdGEtcGFuZWw9XCJoZWFsdGgtY29uZmlnXCI+Q29uZmlndXJlPC9idXR0b24+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBUYWI6IFN0YXR1cyAtLT5cbiAgICAgIDxkaXYgaWQ9XCJoZWFsdGgtc3RhdHVzXCIgY2xhc3M9XCJwYW5lbC1zZWN0aW9uIGFjdGl2ZVwiPlxuICAgICAgICA8ZGl2IGlkPVwiaGVhbHRoLXN0YXR1cy1jb250YWluZXJcIiBjbGFzcz1cInNjcm9sbC1jb250YWluZXJcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj48c3BhbiBjbGFzcz1cImJyYW5kLXNwaW5uZXJcIj48L3NwYW4+IExvYWRpbmcgaGVhbHRoIHN0YXR1cy4uLjwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIFRhYjogSW5jaWRlbnRzIC0tPlxuICAgICAgPGRpdiBpZD1cImhlYWx0aC1pbmNpZGVudHNcIiBjbGFzcz1cInBhbmVsLXNlY3Rpb25cIj5cbiAgICAgICAgPGRpdiBpZD1cImhlYWx0aC1pbmNpZGVudHMtY29udGFpbmVyXCIgY2xhc3M9XCJzY3JvbGwtY29udGFpbmVyXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+PHNwYW4gY2xhc3M9XCJlbXB0eS1pY29uXCI+XHVEODNEXHVERUE4PC9zcGFuPiBMb2FkaW5nIGluY2lkZW50cy4uLjwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIFRhYjogQ29uZmlndXJlIC0tPlxuICAgICAgPGRpdiBpZD1cImhlYWx0aC1jb25maWdcIiBjbGFzcz1cInBhbmVsLXNlY3Rpb25cIj5cbiAgICAgICAgPGRpdiBpZD1cImhlYWx0aC1jb25maWctY29udGFpbmVyXCIgY2xhc3M9XCJzY3JvbGwtY29udGFpbmVyXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+PHNwYW4gY2xhc3M9XCJlbXB0eS1pY29uXCI+XHUyNjk5XHVGRTBGPC9zcGFuPiBMb2FkaW5nIGNvbmZpZ3VyYXRpb24uLi48L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBHbG9iYWwgU2V0dGluZ3M6IHJldGVudGlvbiwgcG9sbGluZyBpbnRlcnZhbHMsIG1heCBlbnRyaWVzLCBkaXNrLXVzYWdlIHRocmVzaG9sZCAtLT5cbiAgICAgICAgPGRpdiBpZD1cImhlYWx0aC1nbG9iYWwtc2V0dGluZ3NcIiBzdHlsZT1cIm1hcmdpbi10b3A6IDE2cHg7IHBhZGRpbmc6IDE2cHg7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJvcmRlci1yYWRpdXM6IHZhcigtLXJhZGl1cyk7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmFzZSk7XCI+XG4gICAgICAgICAgPGg0IHN0eWxlPVwibWFyZ2luOiAwIDAgNHB4O1wiPlx1RDgzQ1x1REYwRCBHbG9iYWwgU2V0dGluZ3M8L2g0PlxuICAgICAgICAgIDxwIGNsYXNzPVwidGV4dC1tdXRlZC1zbVwiIHN0eWxlPVwibWFyZ2luOiAwIDAgMTJweDtcIj5BcHBsaWVzIHRvIGFsbCBoZWFsdGggY2hlY2tzLiBTZXR0aW5ncyBhcmUgc3RvcmVkIGxvY2FsbHkgaW4gdGhpcyBicm93c2VyLjwvcD5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZ3JpZDsgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiAxZnIgMWZyOyBnYXA6IDEycHg7XCI+XG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0ZXh0LW11dGVkLXNtXCI+SGVhbHRoIENoZWNrIFBvbGxpbmcgSW50ZXJ2YWwgKHNlY29uZHMpPC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBpZD1cImhlYWx0aC1zZXR0aW5nLWludGVydmFsXCIgdmFsdWU9XCI2MFwiIG1pbj1cIjVcIiBtYXg9XCIzNjAwXCIgY2xhc3M9XCJmb3JtLWlucHV0XCIgLz5cbiAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC43MnJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLXRvcDogMnB4O1wiPkhvdyBvZnRlbiBlYWNoIHNlcnZpY2UncyBoZWFsdGggZW5kcG9pbnQgaXMgY2hlY2tlZC48L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwidGV4dC1tdXRlZC1zbVwiPlN0YXRzIFBvbGxpbmcgSW50ZXJ2YWwgKHNlY29uZHMpPC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBpZD1cImhlYWx0aC1zZXR0aW5nLXN0YXRzLWludGVydmFsXCIgdmFsdWU9XCIzMFwiIG1pbj1cIjVcIiBtYXg9XCIzNjAwXCIgY2xhc3M9XCJmb3JtLWlucHV0XCIgLz5cbiAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC43MnJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLXRvcDogMnB4O1wiPkhvdyBvZnRlbiBjb250YWluZXIgc3RhdGlzdGljcyAoQ1BVL21lbW9yeSkgYXJlIHNhbXBsZWQuPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInRleHQtbXV0ZWQtc21cIj5NYXggRW50cmllcyBQZXIgU2VydmljZTwvbGFiZWw+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgaWQ9XCJoZWFsdGgtc2V0dGluZy1tYXgtZW50cmllc1wiIHZhbHVlPVwiNTAwXCIgbWluPVwiMTBcIiBtYXg9XCIxMDAwMDBcIiBjbGFzcz1cImZvcm0taW5wdXRcIiAvPlxuICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjcycmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW4tdG9wOiAycHg7XCI+Q2FwIG9uIHN0b3JlZCBoaXN0b3J5IHJlY29yZHMgcGVyIHNlcnZpY2UuPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInRleHQtbXV0ZWQtc21cIj5EYXRhIFJldGVudGlvbiAoZGF5cyk8L2xhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIGlkPVwiaGVhbHRoLXNldHRpbmctcmV0ZW50aW9uXCIgdmFsdWU9XCIzMFwiIG1pbj1cIjFcIiBtYXg9XCIzNjUwXCIgY2xhc3M9XCJmb3JtLWlucHV0XCIgLz5cbiAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC43MnJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLXRvcDogMnB4O1wiPkhlYWx0aCBoaXN0b3J5IG9sZGVyIHRoYW4gdGhpcyBpcyBwcnVuZWQuPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInRleHQtbXV0ZWQtc21cIj5EaXNrLVVzYWdlIFdhcm5pbmcgKCUpPC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBpZD1cImhlYWx0aC1zZXR0aW5nLWRpc2stdGhyZXNob2xkXCIgdmFsdWU9XCI4MFwiIG1pbj1cIjUwXCIgbWF4PVwiOTlcIiBjbGFzcz1cImZvcm0taW5wdXRcIiAvPlxuICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjcycmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW4tdG9wOiAycHg7XCI+V2FybiB3aGVuIGRpc2sgdXNhZ2UgZXhjZWVkcyB0aGlzIGxldmVsLjwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdiBzdHlsZT1cIm1hcmdpbi10b3A6IDEycHg7IGRpc3BsYXk6IGZsZXg7IGdhcDogOHB4OyBhbGlnbi1pdGVtczogY2VudGVyO1wiPlxuICAgICAgICAgICAgPGJ1dHRvbiBpZD1cImhlYWx0aC1nbG9iYWwtc2F2ZVwiIGNsYXNzPVwiYnRuLWFjY2VudC1zb2xpZFwiPlNhdmUgR2xvYmFsIFNldHRpbmdzPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uIGlkPVwiaGVhbHRoLWdsb2JhbC1yZXNldFwiIGNsYXNzPVwiYnRuLXNtXCI+UmVzZXQgdG8gRGVmYXVsdHM8L2J1dHRvbj5cbiAgICAgICAgICAgIDxzcGFuIGlkPVwiaGVhbHRoLWdsb2JhbC1zdGF0dXNcIiBzdHlsZT1cImZvbnQtc2l6ZTogMC44cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPjwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBBZGQvRWRpdCBIZWFsdGggQ2hlY2sgRm9ybSAtLT5cbiAgICAgICAgPGRpdiBpZD1cImhlYWx0aC1jb25maWctZm9ybVwiIHN0eWxlPVwiZGlzcGxheTogbm9uZTsgbWFyZ2luLXRvcDogMTZweDsgcGFkZGluZzogMTZweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgYm9yZGVyLXJhZGl1czogdmFyKC0tcmFkaXVzKTsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iYXNlKTtcIj5cbiAgICAgICAgICA8aDQgaWQ9XCJoZWFsdGgtZm9ybS10aXRsZVwiIHN0eWxlPVwibWFyZ2luOiAwIDAgMTJweDtcIj5BZGQgSGVhbHRoIENoZWNrPC9oND5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZ3JpZDsgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiAxZnIgMWZyOyBnYXA6IDEycHg7XCI+XG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0ZXh0LW11dGVkLXNtXCI+U2VydmljZSBJRDwvbGFiZWw+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGlkPVwiaGVhbHRoLWZvcm0taWRcIiBwbGFjZWhvbGRlcj1cImUuZy4gcGxleFwiIGNsYXNzPVwiZm9ybS1pbnB1dFwiIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInRleHQtbXV0ZWQtc21cIj5EaXNwbGF5IE5hbWU8L2xhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBpZD1cImhlYWx0aC1mb3JtLW5hbWVcIiBwbGFjZWhvbGRlcj1cImUuZy4gUGxleCBNZWRpYSBTZXJ2ZXJcIiBjbGFzcz1cImZvcm0taW5wdXRcIiAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZ3JpZC1jb2x1bW46IHNwYW4gMjtcIj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwidGV4dC1tdXRlZC1zbVwiPlVSTDwvbGFiZWw+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGlkPVwiaGVhbHRoLWZvcm0tdXJsXCIgcGxhY2Vob2xkZXI9XCJodHRwczovL3BsZXguaG9tZVwiIGNsYXNzPVwiZm9ybS1pbnB1dFwiIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInRleHQtbXV0ZWQtc21cIj5UaW1lb3V0IChtcyk8L2xhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIGlkPVwiaGVhbHRoLWZvcm0tdGltZW91dFwiIHZhbHVlPVwiMTAwMDBcIiBjbGFzcz1cImZvcm0taW5wdXRcIiAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0ZXh0LW11dGVkLXNtXCI+RXhwZWN0ZWQgU3RhdHVzIENvZGVzPC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgaWQ9XCJoZWFsdGgtZm9ybS1jb2Rlc1wiIHZhbHVlPVwiMjAwXCIgcGxhY2Vob2xkZXI9XCIyMDAsIDMwMSwgMzAyXCIgY2xhc3M9XCJmb3JtLWlucHV0XCIgLz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwidGV4dC1tdXRlZC1zbVwiPlNMQSBUYXJnZXQgKCUpPC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBpZD1cImhlYWx0aC1mb3JtLXNsYVwiIHZhbHVlPVwiOTkuOVwiIHN0ZXA9XCIwLjFcIiBjbGFzcz1cImZvcm0taW5wdXRcIiAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0ZXh0LW11dGVkLXNtXCI+U2xvdyBSZXNwb25zZSBUaHJlc2hvbGQgKG1zKTwvbGFiZWw+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgaWQ9XCJoZWFsdGgtZm9ybS1zbG93XCIgdmFsdWU9XCI1MDAwXCIgY2xhc3M9XCJmb3JtLWlucHV0XCIgLz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgc3R5bGU9XCJtYXJnaW4tdG9wOiAxMnB4OyBkaXNwbGF5OiBmbGV4OyBnYXA6IDhweDsganVzdGlmeS1jb250ZW50OiBmbGV4LWVuZDtcIj5cbiAgICAgICAgICAgIDxidXR0b24gaWQ9XCJoZWFsdGgtZm9ybS1jYW5jZWxcIj5DYW5jZWw8L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gaWQ9XCJoZWFsdGgtZm9ybS1zYXZlXCIgY2xhc3M9XCJidG4tYWNjZW50LXNvbGlkXCI+U2F2ZTwvYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IHN0eWxlPVwibWFyZ2luLXRvcDogMTJweDtcIj5cbiAgICAgICAgICA8YnV0dG9uIGlkPVwiaGVhbHRoLWFkZC1idG5cIiBjbGFzcz1cImJ0bi1hY2NlbnQtc29saWRcIj4rIEFkZCBIZWFsdGggQ2hlY2s8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzcz1cInBhbmVsLWJvdHRvbS1iYXJcIj5cbiAgICAgICAgPGJ1dHRvbiBpZD1cImhlYWx0aC1yZWZyZXNoLWJ0blwiIGNsYXNzPVwiYnRuLXNtXCI+XHVEODNEXHVERDA0IFJlZnJlc2g8L2J1dHRvbj5cbiAgICAgICAgPHNwYW4gaWQ9XCJoZWFsdGgtbGFzdC11cGRhdGVcIiBjbGFzcz1cInRleHQtYXV0by1yaWdodFwiPjwvc3Bhbj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGNsYXNzPVwid2VhdGhlci1tb2RhbC1idXR0b25zIG1vZGFsLWZvb3Rlci1iYXJcIj5cbiAgICAgICAgPGJ1dHRvbiBpZD1cImhlYWx0aC1jYW5jZWxcIj5DbG9zZTwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PmApO1xuXG4gIGNvbnN0IG1vZGFsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1tb2RhbCcpO1xuICBjb25zdCBvcGVuQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1jaGVjay1idG4nKTtcbiAgY29uc3QgY2FuY2VsQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1jYW5jZWwnKTtcbiAgY29uc3QgcmVmcmVzaEJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtcmVmcmVzaC1idG4nKTtcbiAgY29uc3Qgc3RhdHVzQ29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1zdGF0dXMtY29udGFpbmVyJyk7XG4gIGNvbnN0IGluY2lkZW50c0NvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtaW5jaWRlbnRzLWNvbnRhaW5lcicpO1xuICBjb25zdCBjb25maWdDb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhbHRoLWNvbmZpZy1jb250YWluZXInKTtcbiAgY29uc3QgbGFzdFVwZGF0ZVNwYW4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhbHRoLWxhc3QtdXBkYXRlJyk7XG4gIGNvbnN0IGFkZEJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtYWRkLWJ0bicpO1xuICBjb25zdCBmb3JtRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhbHRoLWNvbmZpZy1mb3JtJyk7XG4gIGNvbnN0IGZvcm1UaXRsZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtZm9ybS10aXRsZScpO1xuICBjb25zdCBmb3JtQ2FuY2VsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1mb3JtLWNhbmNlbCcpO1xuICBjb25zdCBmb3JtU2F2ZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtZm9ybS1zYXZlJyk7XG5cbiAgLy8gLS0tLSBHbG9iYWwgaGVhbHRoIHNldHRpbmdzIChyZXRlbnRpb24sIHBvbGxpbmcgaW50ZXJ2YWxzLCBtYXggZW50cmllcywgZGlzayB0aHJlc2hvbGQpIC0tLS1cbiAgY29uc3QgSEVBTFRIX1NFVFRJTkdTX0tFWSA9ICdkYXNoY2FkZHktaGVhbHRoLXNldHRpbmdzJztcbiAgY29uc3QgSEVBTFRIX0RFRkFVTFRTID0geyByZXRlbnRpb25EYXlzOiAzMCwgcG9sbGluZ0ludGVydmFsOiA2MCwgc3RhdHNQb2xsaW5nSW50ZXJ2YWw6IDMwLCBtYXhFbnRyaWVzUGVyU2VydmljZTogNTAwLCBkaXNrVXNhZ2VUaHJlc2hvbGQ6IDgwIH07XG4gIGNvbnN0IGdsb2JhbFNhdmVCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhbHRoLWdsb2JhbC1zYXZlJyk7XG4gIGNvbnN0IGdsb2JhbFJlc2V0QnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1nbG9iYWwtcmVzZXQnKTtcbiAgY29uc3QgZ2xvYmFsU3RhdHVzU3BhbiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtZ2xvYmFsLXN0YXR1cycpO1xuICBjb25zdCByZXRlbnRpb25JbnB1dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtc2V0dGluZy1yZXRlbnRpb24nKTtcbiAgY29uc3QgaW50ZXJ2YWxJbnB1dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtc2V0dGluZy1pbnRlcnZhbCcpO1xuICBjb25zdCBzdGF0c0ludGVydmFsSW5wdXQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhbHRoLXNldHRpbmctc3RhdHMtaW50ZXJ2YWwnKTtcbiAgY29uc3QgbWF4RW50cmllc0lucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1zZXR0aW5nLW1heC1lbnRyaWVzJyk7XG4gIGNvbnN0IGRpc2tUaHJlc2hvbGRJbnB1dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtc2V0dGluZy1kaXNrLXRocmVzaG9sZCcpO1xuXG4gIGZ1bmN0aW9uIGxvYWRIZWFsdGhTZXR0aW5ncygpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmF3ID0gc2FmZUdldChIRUFMVEhfU0VUVElOR1NfS0VZKTtcbiAgICAgIGNvbnN0IHNhdmVkID0gcmF3ID8gSlNPTi5wYXJzZShyYXcpIDoge307XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgSEVBTFRIX0RFRkFVTFRTLCBzYXZlZCk7XG4gICAgfSBjYXRjaCAoXykge1xuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIEhFQUxUSF9ERUZBVUxUUyk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gYXBwbHlIZWFsdGhTZXR0aW5nc1RvVUkoKSB7XG4gICAgY29uc3QgcyA9IGxvYWRIZWFsdGhTZXR0aW5ncygpO1xuICAgIGlmIChyZXRlbnRpb25JbnB1dCkgcmV0ZW50aW9uSW5wdXQudmFsdWUgPSBzLnJldGVudGlvbkRheXM7XG4gICAgaWYgKGludGVydmFsSW5wdXQpIGludGVydmFsSW5wdXQudmFsdWUgPSBzLnBvbGxpbmdJbnRlcnZhbDtcbiAgICBpZiAoc3RhdHNJbnRlcnZhbElucHV0KSBzdGF0c0ludGVydmFsSW5wdXQudmFsdWUgPSBzLnN0YXRzUG9sbGluZ0ludGVydmFsO1xuICAgIGlmIChtYXhFbnRyaWVzSW5wdXQpIG1heEVudHJpZXNJbnB1dC52YWx1ZSA9IHMubWF4RW50cmllc1BlclNlcnZpY2U7XG4gICAgaWYgKGRpc2tUaHJlc2hvbGRJbnB1dCkgZGlza1RocmVzaG9sZElucHV0LnZhbHVlID0gcy5kaXNrVXNhZ2VUaHJlc2hvbGQ7XG4gIH1cblxuICBmdW5jdGlvbiBzYXZlSGVhbHRoU2V0dGluZ3MoKSB7XG4gICAgY29uc3Qgc2V0dGluZ3MgPSB7XG4gICAgICByZXRlbnRpb25EYXlzOiBNYXRoLm1heCgxLCBNYXRoLm1pbigzNjUwLCBwYXJzZUludChyZXRlbnRpb25JbnB1dD8udmFsdWUpIHx8IEhFQUxUSF9ERUZBVUxUUy5yZXRlbnRpb25EYXlzKSksXG4gICAgICBwb2xsaW5nSW50ZXJ2YWw6IE1hdGgubWF4KDUsIE1hdGgubWluKDM2MDAsIHBhcnNlSW50KGludGVydmFsSW5wdXQ/LnZhbHVlKSB8fCBIRUFMVEhfREVGQVVMVFMucG9sbGluZ0ludGVydmFsKSksXG4gICAgICBzdGF0c1BvbGxpbmdJbnRlcnZhbDogTWF0aC5tYXgoNSwgTWF0aC5taW4oMzYwMCwgcGFyc2VJbnQoc3RhdHNJbnRlcnZhbElucHV0Py52YWx1ZSkgfHwgSEVBTFRIX0RFRkFVTFRTLnN0YXRzUG9sbGluZ0ludGVydmFsKSksXG4gICAgICBtYXhFbnRyaWVzUGVyU2VydmljZTogTWF0aC5tYXgoMTAsIE1hdGgubWluKDEwMDAwMCwgcGFyc2VJbnQobWF4RW50cmllc0lucHV0Py52YWx1ZSkgfHwgSEVBTFRIX0RFRkFVTFRTLm1heEVudHJpZXNQZXJTZXJ2aWNlKSksXG4gICAgICBkaXNrVXNhZ2VUaHJlc2hvbGQ6IE1hdGgubWF4KDUwLCBNYXRoLm1pbig5OSwgcGFyc2VJbnQoZGlza1RocmVzaG9sZElucHV0Py52YWx1ZSkgfHwgSEVBTFRIX0RFRkFVTFRTLmRpc2tVc2FnZVRocmVzaG9sZCkpXG4gICAgfTtcbiAgICB0cnkge1xuICAgICAgc2FmZVNldChIRUFMVEhfU0VUVElOR1NfS0VZLCBKU09OLnN0cmluZ2lmeShzZXR0aW5ncykpO1xuICAgICAgYXBwbHlIZWFsdGhTZXR0aW5nc1RvVUkoKTtcbiAgICAgIGlmIChnbG9iYWxTdGF0dXNTcGFuKSB7XG4gICAgICAgIGdsb2JhbFN0YXR1c1NwYW4udGV4dENvbnRlbnQgPSAnU2F2ZWQgXHUyNzEzJztcbiAgICAgICAgZ2xvYmFsU3RhdHVzU3Bhbi5zdHlsZS5jb2xvciA9ICd2YXIoLS1vay1mZyknO1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHsgaWYgKGdsb2JhbFN0YXR1c1NwYW4pIGdsb2JhbFN0YXR1c1NwYW4udGV4dENvbnRlbnQgPSAnJzsgfSwgMjUwMCk7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIHNob3dOb3RpZmljYXRpb24gPT09ICdmdW5jdGlvbicpIHNob3dOb3RpZmljYXRpb24oJ0dsb2JhbCBoZWFsdGggc2V0dGluZ3Mgc2F2ZWQnLCAnc3VjY2VzcycpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmIChnbG9iYWxTdGF0dXNTcGFuKSB7IGdsb2JhbFN0YXR1c1NwYW4udGV4dENvbnRlbnQgPSAnU2F2ZSBmYWlsZWQnOyBnbG9iYWxTdGF0dXNTcGFuLnN0eWxlLmNvbG9yID0gJ3ZhcigtLWJhZC1mZyknOyB9XG4gICAgICBpZiAodHlwZW9mIHNob3dOb3RpZmljYXRpb24gPT09ICdmdW5jdGlvbicpIHNob3dOb3RpZmljYXRpb24oJ0ZhaWxlZCB0byBzYXZlIHNldHRpbmdzOiAnICsgZS5tZXNzYWdlLCAnZXJyb3InKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZXNldEhlYWx0aFNldHRpbmdzKCkge1xuICAgIHRyeSB7XG4gICAgICBzYWZlU2V0KEhFQUxUSF9TRVRUSU5HU19LRVksIEpTT04uc3RyaW5naWZ5KEhFQUxUSF9ERUZBVUxUUykpO1xuICAgIH0gY2F0Y2ggKF8pIHsgLyogaWdub3JlICovIH1cbiAgICBhcHBseUhlYWx0aFNldHRpbmdzVG9VSSgpO1xuICAgIGlmIChnbG9iYWxTdGF0dXNTcGFuKSB7XG4gICAgICBnbG9iYWxTdGF0dXNTcGFuLnRleHRDb250ZW50ID0gJ1Jlc2V0IHRvIGRlZmF1bHRzIFx1MjcxMyc7XG4gICAgICBnbG9iYWxTdGF0dXNTcGFuLnN0eWxlLmNvbG9yID0gJ3ZhcigtLW9rLWZnKSc7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHsgaWYgKGdsb2JhbFN0YXR1c1NwYW4pIGdsb2JhbFN0YXR1c1NwYW4udGV4dENvbnRlbnQgPSAnJzsgfSwgMjUwMCk7XG4gICAgfVxuICB9XG5cbiAgYXBwbHlIZWFsdGhTZXR0aW5nc1RvVUkoKTtcbiAgZ2xvYmFsU2F2ZUJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBzYXZlSGVhbHRoU2V0dGluZ3MpO1xuICBnbG9iYWxSZXNldEJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCByZXNldEhlYWx0aFNldHRpbmdzKTtcbiAgLy8gLS0tLSBFbmQgZ2xvYmFsIGhlYWx0aCBzZXR0aW5ncyAtLS0tXG5cbiAgbGV0IGVkaXRpbmdJZCA9IG51bGw7XG5cbiAgZnVuY3Rpb24gdXB0aW1lQ29sb3IocGN0KSB7XG4gICAgaWYgKHBjdCA+PSA5OS45KSByZXR1cm4gJ3ZhcigtLW9rLWZnKSc7XG4gICAgaWYgKHBjdCA+PSA5NSkgcmV0dXJuICcjZjM5YzEyJztcbiAgICByZXR1cm4gJ3ZhcigtLWJhZC1mZyknO1xuICB9XG5cbiAgZnVuY3Rpb24gc2V2ZXJpdHlCYWRnZShzZXYpIHtcbiAgICBjb25zdCBjb2xvcnMgPSB7IGNyaXRpY2FsOiAndmFyKC0tYmFkLWZnKScsIGhpZ2g6ICcjZmY2YjZiJywgbWVkaXVtOiAnI2YzOWMxMicsIGxvdzogJ3ZhcigtLW11dGVkKScgfTtcbiAgICByZXR1cm4gYDxzcGFuIHN0eWxlPVwicGFkZGluZzogMnB4IDhweDsgYm9yZGVyLXJhZGl1czogNHB4OyBmb250LXNpemU6IDAuNzVyZW07IGJhY2tncm91bmQ6ICR7Y29sb3JzW3Nldl0gfHwgJ3ZhcigtLW11dGVkKSd9MjA7IGNvbG9yOiAke2NvbG9yc1tzZXZdIHx8ICd2YXIoLS1tdXRlZCknfTtcIj4ke3Nldn08L3NwYW4+YDtcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGxvYWRTdGF0dXMoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL2hlYWx0aC1jaGVja3Mvc3RhdHVzJyk7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzLmpzb24oKTtcbiAgICAgIGlmICghZGF0YS5zdWNjZXNzIHx8ICFkYXRhLnN0YXR1cyB8fCBPYmplY3Qua2V5cyhkYXRhLnN0YXR1cykubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHN0YXR1c0NvbnRhaW5lci5pbm5lckhUTUwgPSAnPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+PHNwYW4gY2xhc3M9XCJlbXB0eS1pY29uXCI+XHVEODNDXHVERkU1PC9zcGFuPk5vIGhlYWx0aCBjaGVja3MgY29uZmlndXJlZC4gR28gdG8gdGhlIENvbmZpZ3VyZSB0YWIgdG8gYWRkIHNlcnZpY2VzLjwvZGl2Pic7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHNlcnZpY2VzID0gT2JqZWN0LnZhbHVlcyhkYXRhLnN0YXR1cyk7XG4gICAgICBsZXQgaHRtbCA9ICc8dGFibGUgc3R5bGU9XCJ3aWR0aDogMTAwJTsgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsgZm9udC1zaXplOiAwLjg1cmVtO1wiPic7XG4gICAgICBodG1sICs9ICc8dHIgc3R5bGU9XCJib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgY29sb3I6IHZhcigtLW11dGVkKTsgdGV4dC1hbGlnbjogbGVmdDtcIj4nO1xuICAgICAgaHRtbCArPSAnPHRoIHN0eWxlPVwicGFkZGluZzogOHB4O1wiPlNlcnZpY2U8L3RoPjx0aCBzdHlsZT1cInBhZGRpbmc6IDhweDtcIj5TdGF0dXM8L3RoPic7XG4gICAgICBodG1sICs9ICc8dGggc3R5bGU9XCJwYWRkaW5nOiA4cHg7XCI+VXB0aW1lIDI0aDwvdGg+PHRoIHN0eWxlPVwicGFkZGluZzogOHB4O1wiPlVwdGltZSA3ZDwvdGg+JztcbiAgICAgIGh0bWwgKz0gJzx0aCBzdHlsZT1cInBhZGRpbmc6IDhweDtcIj5BdmcgUmVzcG9uc2U8L3RoPjx0aCBzdHlsZT1cInBhZGRpbmc6IDhweDtcIj5MYXN0IENoZWNrPC90aD48L3RyPic7XG4gICAgICBmb3IgKGNvbnN0IHMgb2Ygc2VydmljZXMpIHtcbiAgICAgICAgY29uc3QgaXNVcCA9IHMuc3RhdHVzID09PSAndXAnO1xuICAgICAgICBjb25zdCBkb3RDb2xvciA9IGlzVXAgPyAndmFyKC0tZG90LW9rKScgOiAndmFyKC0tZG90LWJhZCknO1xuICAgICAgICBjb25zdCB1MjQgPSBzLnVwdGltZT8uWycyNGgnXSA/PyAnLSc7XG4gICAgICAgIGNvbnN0IHU3ZCA9IHMudXB0aW1lPy5bJzdkJ10gPz8gJy0nO1xuICAgICAgICBjb25zdCBhdmdSdCA9IHMuYXZnUmVzcG9uc2VUaW1lICE9IG51bGwgPyBNYXRoLnJvdW5kKHMuYXZnUmVzcG9uc2VUaW1lKSArICdtcycgOiAnLSc7XG4gICAgICAgIGNvbnN0IGxhc3RDaGVjayA9IHMudGltZXN0YW1wID8gdGltZUFnbyhzLnRpbWVzdGFtcCkgOiAnLSc7XG4gICAgICAgIGh0bWwgKz0gYDx0ciBzdHlsZT1cImJvcmRlci1ib3R0b206IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBjdXJzb3I6IHBvaW50ZXI7XCIgZGF0YS1oZWFsdGgtaWQ9XCIke2VzY2FwZUh0bWwocy5zZXJ2aWNlSWQpfVwiPmA7XG4gICAgICAgIGh0bWwgKz0gYDx0ZCBzdHlsZT1cInBhZGRpbmc6IDhweDsgZm9udC13ZWlnaHQ6IDUwMDtcIj4ke2VzY2FwZUh0bWwocy5uYW1lIHx8IHMuc2VydmljZUlkKX08L3RkPmA7XG4gICAgICAgIGh0bWwgKz0gYDx0ZCBzdHlsZT1cInBhZGRpbmc6IDhweDtcIj48c3BhbiBzdHlsZT1cImRpc3BsYXk6IGlubGluZS1ibG9jazsgd2lkdGg6IDhweDsgaGVpZ2h0OiA4cHg7IGJvcmRlci1yYWRpdXM6IDUwJTsgYmFja2dyb3VuZDogJHtkb3RDb2xvcn07IG1hcmdpbi1yaWdodDogNnB4O1wiPjwvc3Bhbj4ke2lzVXAgPyAnVXAnIDogJ0Rvd24nfTwvdGQ+YDtcbiAgICAgICAgaHRtbCArPSBgPHRkIHN0eWxlPVwicGFkZGluZzogOHB4OyBjb2xvcjogJHt0eXBlb2YgdTI0ID09PSAnbnVtYmVyJyA/IHVwdGltZUNvbG9yKHUyNCkgOiAndmFyKC0tbXV0ZWQpJ307XCI+JHt0eXBlb2YgdTI0ID09PSAnbnVtYmVyJyA/IHUyNC50b0ZpeGVkKDEpICsgJyUnIDogdTI0fTwvdGQ+YDtcbiAgICAgICAgaHRtbCArPSBgPHRkIHN0eWxlPVwicGFkZGluZzogOHB4OyBjb2xvcjogJHt0eXBlb2YgdTdkID09PSAnbnVtYmVyJyA/IHVwdGltZUNvbG9yKHU3ZCkgOiAndmFyKC0tbXV0ZWQpJ307XCI+JHt0eXBlb2YgdTdkID09PSAnbnVtYmVyJyA/IHU3ZC50b0ZpeGVkKDEpICsgJyUnIDogdTdkfTwvdGQ+YDtcbiAgICAgICAgaHRtbCArPSBgPHRkIHN0eWxlPVwicGFkZGluZzogOHB4O1wiPiR7YXZnUnR9PC90ZD5gO1xuICAgICAgICBodG1sICs9IGA8dGQgc3R5bGU9XCJwYWRkaW5nOiA4cHg7IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+JHtsYXN0Q2hlY2t9PC90ZD5gO1xuICAgICAgICBodG1sICs9ICc8L3RyPic7XG4gICAgICAgIGh0bWwgKz0gYDx0ciBpZD1cImhlYWx0aC1kZXRhaWwtJHtlc2NhcGVIdG1sKHMuc2VydmljZUlkKX1cIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCI+PHRkIGNvbHNwYW49XCI2XCIgc3R5bGU9XCJwYWRkaW5nOiAxMnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1iZyk7IGJvcmRlci1ib3R0b206IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1wiPjxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPjxzcGFuIGNsYXNzPVwiYnJhbmQtc3Bpbm5lclwiPjwvc3Bhbj4gTG9hZGluZyBkZXRhaWxzLi4uPC9kaXY+PC90ZD48L3RyPmA7XG4gICAgICB9XG4gICAgICBodG1sICs9ICc8L3RhYmxlPic7XG4gICAgICBzdGF0dXNDb250YWluZXIuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgIGxhc3RVcGRhdGVTcGFuLnRleHRDb250ZW50ID0gJ1VwZGF0ZWQgJyArIG5ldyBEYXRlKCkudG9Mb2NhbGVUaW1lU3RyaW5nKCk7XG5cbiAgICAgIC8vIFJvdyBjbGljayB0byBleHBhbmQgZGV0YWlsc1xuICAgICAgc3RhdHVzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoJ3RyW2RhdGEtaGVhbHRoLWlkXScpLmZvckVhY2gocm93ID0+IHtcbiAgICAgICAgcm93LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGlkID0gcm93LmRhdGFzZXQuaGVhbHRoSWQ7XG4gICAgICAgICAgY29uc3QgZGV0YWlsUm93ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1kZXRhaWwtJyArIGlkKTtcbiAgICAgICAgICBpZiAoIWRldGFpbFJvdykgcmV0dXJuO1xuICAgICAgICAgIGlmIChkZXRhaWxSb3cuc3R5bGUuZGlzcGxheSAhPT0gJ25vbmUnKSB7XG4gICAgICAgICAgICBkZXRhaWxSb3cuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgZGV0YWlsUm93LnN0eWxlLmRpc3BsYXkgPSAnJztcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgciA9IGF3YWl0IGZldGNoKGAvYXBpL3YxL2hlYWx0aC1jaGVja3MvJHtpZH0vc3RhdHM/aG91cnM9MjRgKTtcbiAgICAgICAgICAgIGNvbnN0IGQgPSBhd2FpdCByLmpzb24oKTtcbiAgICAgICAgICAgIGlmIChkLnN1Y2Nlc3MgJiYgZC5zdGF0cykge1xuICAgICAgICAgICAgICBjb25zdCBzdCA9IGQuc3RhdHM7XG4gICAgICAgICAgICAgIGNvbnN0IHJ0ID0gc3QucmVzcG9uc2VUaW1lIHx8IHt9O1xuICAgICAgICAgICAgICBkZXRhaWxSb3cucXVlcnlTZWxlY3RvcigndGQnKS5pbm5lckhUTUwgPSBgXG4gICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGdyaWQ7IGdyaWQtdGVtcGxhdGUtY29sdW1uczogcmVwZWF0KDQsIDFmcik7IGdhcDogMTJweDsgZm9udC1zaXplOiAwLjgycmVtO1wiPlxuICAgICAgICAgICAgICAgICAgPGRpdj48c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+VG90YWwgQ2hlY2tzPC9zcGFuPjxicj48c3Ryb25nPiR7c3QudG90YWxDaGVja3MgfHwgMH08L3N0cm9uZz48L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxkaXY+PHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPlVwdGltZTwvc3Bhbj48YnI+PHN0cm9uZyBzdHlsZT1cImNvbG9yOiAke3VwdGltZUNvbG9yKHN0LnVwdGltZSB8fCAwKX07XCI+JHsoc3QudXB0aW1lIHx8IDApLnRvRml4ZWQoMil9JTwvc3Ryb25nPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgPGRpdj48c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+QXZnIFJlc3BvbnNlPC9zcGFuPjxicj48c3Ryb25nPiR7TWF0aC5yb3VuZChydC5hdmcgfHwgMCl9bXM8L3N0cm9uZz48L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxkaXY+PHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPlA5NSAvIFA5OTwvc3Bhbj48YnI+PHN0cm9uZz4ke01hdGgucm91bmQocnQucDk1IHx8IDApfW1zIC8gJHtNYXRoLnJvdW5kKHJ0LnA5OSB8fCAwKX1tczwvc3Ryb25nPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgPGRpdj48c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+TWluIFJlc3BvbnNlPC9zcGFuPjxicj48c3Ryb25nPiR7TWF0aC5yb3VuZChydC5taW4gfHwgMCl9bXM8L3N0cm9uZz48L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxkaXY+PHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPk1heCBSZXNwb25zZTwvc3Bhbj48YnI+PHN0cm9uZz4ke01hdGgucm91bmQocnQubWF4IHx8IDApfW1zPC9zdHJvbmc+PC9kaXY+XG4gICAgICAgICAgICAgICAgICA8ZGl2PjxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTtcIj5VcCBDaGVja3M8L3NwYW4+PGJyPjxzdHJvbmcgc3R5bGU9XCJjb2xvcjogdmFyKC0tb2stZmcpO1wiPiR7c3QudXBDaGVja3MgfHwgMH08L3N0cm9uZz48L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxkaXY+PHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPkRvd24gQ2hlY2tzPC9zcGFuPjxicj48c3Ryb25nIHN0eWxlPVwiY29sb3I6IHZhcigtLWJhZC1mZyk7XCI+JHtzdC5kb3duQ2hlY2tzIHx8IDB9PC9zdHJvbmc+PC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGRldGFpbFJvdy5xdWVyeVNlbGVjdG9yKCd0ZCcpLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj5ObyBkZXRhaWxlZCBzdGF0cyBhdmFpbGFibGUgZm9yIHRoaXMgcGVyaW9kLjwvZGl2Pic7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgZGV0YWlsUm93LnF1ZXJ5U2VsZWN0b3IoJ3RkJykuaW5uZXJIVE1MID0gYDxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiIHN0eWxlPVwiY29sb3I6IHZhcigtLWJhZC1mZyk7XCI+RmFpbGVkOiAke2VzY2FwZUh0bWwoZS5tZXNzYWdlKX08L2Rpdj5gO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBzdGF0dXNDb250YWluZXIuaW5uZXJIVE1MID0gYDxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiIHN0eWxlPVwiY29sb3I6IHZhcigtLWJhZC1mZyk7XCI+RmFpbGVkIHRvIGxvYWQgaGVhbHRoIHN0YXR1czogJHtlc2NhcGVIdG1sKGUubWVzc2FnZSl9PC9kaXY+YDtcbiAgICB9XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBsb2FkSW5jaWRlbnRzKCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBbb3BlblJlcywgaGlzdFJlc10gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgIGZldGNoKCcvYXBpL3YxL2hlYWx0aC1jaGVja3MvaW5jaWRlbnRzJyksXG4gICAgICAgIGZldGNoKCcvYXBpL3YxL2hlYWx0aC1jaGVja3MvaW5jaWRlbnRzL2hpc3Rvcnk/bGltaXQ9NTAnKVxuICAgICAgXSk7XG4gICAgICBjb25zdCBvcGVuRGF0YSA9IGF3YWl0IG9wZW5SZXMuanNvbigpO1xuICAgICAgY29uc3QgaGlzdERhdGEgPSBhd2FpdCBoaXN0UmVzLmpzb24oKTtcbiAgICAgIGxldCBodG1sID0gJyc7XG5cbiAgICAgIC8vIE9wZW4gaW5jaWRlbnRzXG4gICAgICBjb25zdCBvcGVuID0gKG9wZW5EYXRhLnN1Y2Nlc3MgJiYgb3BlbkRhdGEuaW5jaWRlbnRzKSA/IG9wZW5EYXRhLmluY2lkZW50cyA6IFtdO1xuICAgICAgaWYgKG9wZW4ubGVuZ3RoID4gMCkge1xuICAgICAgICBodG1sICs9ICc8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMTZweDtcIj48aDQgc3R5bGU9XCJjb2xvcjogdmFyKC0tYmFkLWZnKTsgbWFyZ2luOiAwIDAgOHB4O1wiPk9wZW4gSW5jaWRlbnRzICgnICsgb3Blbi5sZW5ndGggKyAnKTwvaDQ+JztcbiAgICAgICAgZm9yIChjb25zdCBpbmMgb2Ygb3Blbikge1xuICAgICAgICAgIGh0bWwgKz0gYDxkaXYgc3R5bGU9XCJwYWRkaW5nOiAxMHB4IDEycHg7IG1hcmdpbi1ib3R0b206IDhweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYmFkLWZnKTMwOyBib3JkZXItcmFkaXVzOiA4cHg7IGJhY2tncm91bmQ6IHZhcigtLWJhZC1iZyk7XCI+XG4gICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuOyBhbGlnbi1pdGVtczogY2VudGVyO1wiPlxuICAgICAgICAgICAgICA8c3BhbiBzdHlsZT1cImZvbnQtd2VpZ2h0OiA1MDA7XCI+JHtlc2NhcGVIdG1sKGluYy5zZXJ2aWNlSWQpfTwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4+JHtzZXZlcml0eUJhZGdlKGluYy5zZXZlcml0eSl9PC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjgycmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW4tdG9wOiA0cHg7XCI+JHtlc2NhcGVIdG1sKGluYy5tZXNzYWdlKX08L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuNzVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi10b3A6IDRweDtcIj5TdGFydGVkICR7dGltZUFnbyhpbmMuY3JlYXRlZEF0KX0gXHUwMEI3ICR7aW5jLm9jY3VycmVuY2VzIHx8IDF9IG9jY3VycmVuY2Uocyk8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICB9XG4gICAgICAgIGh0bWwgKz0gJzwvZGl2Pic7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBodG1sICs9ICc8ZGl2IHN0eWxlPVwicGFkZGluZzogMTJweDsgbWFyZ2luLWJvdHRvbTogMTZweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tb2stZmcpMzA7IGJvcmRlci1yYWRpdXM6IDhweDsgYmFja2dyb3VuZDogdmFyKC0tb2stYmcpOyB0ZXh0LWFsaWduOiBjZW50ZXI7IGNvbG9yOiB2YXIoLS1vay1mZyk7IGZvbnQtc2l6ZTogMC45cmVtO1wiPkFsbCBzZXJ2aWNlcyBvcGVyYXRpb25hbCBcdTIwMTQgbm8gb3BlbiBpbmNpZGVudHM8L2Rpdj4nO1xuICAgICAgfVxuXG4gICAgICAvLyBJbmNpZGVudCBoaXN0b3J5XG4gICAgICBjb25zdCBoaXN0b3J5ID0gKGhpc3REYXRhLnN1Y2Nlc3MgJiYgaGlzdERhdGEuaGlzdG9yeSkgPyBoaXN0RGF0YS5oaXN0b3J5IDogW107XG4gICAgICBpZiAoaGlzdG9yeS5sZW5ndGggPiAwKSB7XG4gICAgICAgIGh0bWwgKz0gJzxoNCBzdHlsZT1cIm1hcmdpbjogMCAwIDhweDsgY29sb3I6IHZhcigtLW11dGVkKTtcIj5JbmNpZGVudCBIaXN0b3J5PC9oND4nO1xuICAgICAgICBodG1sICs9ICc8dGFibGUgc3R5bGU9XCJ3aWR0aDogMTAwJTsgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsgZm9udC1zaXplOiAwLjgycmVtO1wiPic7XG4gICAgICAgIGh0bWwgKz0gJzx0ciBzdHlsZT1cImJvcmRlci1ib3R0b206IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPjx0aCBzdHlsZT1cInBhZGRpbmc6IDZweDsgdGV4dC1hbGlnbjogbGVmdDtcIj5TZXJ2aWNlPC90aD48dGggc3R5bGU9XCJwYWRkaW5nOiA2cHg7IHRleHQtYWxpZ246IGxlZnQ7XCI+VHlwZTwvdGg+PHRoIHN0eWxlPVwicGFkZGluZzogNnB4OyB0ZXh0LWFsaWduOiBsZWZ0O1wiPlNldmVyaXR5PC90aD48dGggc3R5bGU9XCJwYWRkaW5nOiA2cHg7IHRleHQtYWxpZ246IGxlZnQ7XCI+U3RhdHVzPC90aD48dGggc3R5bGU9XCJwYWRkaW5nOiA2cHg7IHRleHQtYWxpZ246IGxlZnQ7XCI+RHVyYXRpb248L3RoPjx0aCBzdHlsZT1cInBhZGRpbmc6IDZweDsgdGV4dC1hbGlnbjogbGVmdDtcIj5XaGVuPC90aD48L3RyPic7XG4gICAgICAgIGZvciAoY29uc3QgaW5jIG9mIGhpc3RvcnkpIHtcbiAgICAgICAgICBjb25zdCByZXNvbHZlZCA9IGluYy5zdGF0dXMgPT09ICdyZXNvbHZlZCc7XG4gICAgICAgICAgY29uc3QgZHVyID0gcmVzb2x2ZWQgJiYgaW5jLmR1cmF0aW9uID8gKGluYy5kdXJhdGlvbiA8IDYwMDAwID8gTWF0aC5yb3VuZChpbmMuZHVyYXRpb24gLyAxMDAwKSArICdzJyA6IE1hdGgucm91bmQoaW5jLmR1cmF0aW9uIC8gNjAwMDApICsgJ20nKSA6ICctJztcbiAgICAgICAgICBodG1sICs9IGA8dHIgc3R5bGU9XCJib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcIj5gO1xuICAgICAgICAgIGh0bWwgKz0gYDx0ZCBzdHlsZT1cInBhZGRpbmc6IDZweDtcIj4ke2VzY2FwZUh0bWwoaW5jLnNlcnZpY2VJZCl9PC90ZD5gO1xuICAgICAgICAgIGh0bWwgKz0gYDx0ZCBzdHlsZT1cInBhZGRpbmc6IDZweDtcIj4ke2VzY2FwZUh0bWwoaW5jLnR5cGUpfTwvdGQ+YDtcbiAgICAgICAgICBodG1sICs9IGA8dGQgc3R5bGU9XCJwYWRkaW5nOiA2cHg7XCI+JHtzZXZlcml0eUJhZGdlKGluYy5zZXZlcml0eSl9PC90ZD5gO1xuICAgICAgICAgIGh0bWwgKz0gYDx0ZCBzdHlsZT1cInBhZGRpbmc6IDZweDtcIj48c3BhbiBzdHlsZT1cImNvbG9yOiAke3Jlc29sdmVkID8gJ3ZhcigtLW9rLWZnKScgOiAndmFyKC0tYmFkLWZnKSd9O1wiPiR7aW5jLnN0YXR1c308L3NwYW4+PC90ZD5gO1xuICAgICAgICAgIGh0bWwgKz0gYDx0ZCBzdHlsZT1cInBhZGRpbmc6IDZweDtcIj4ke2R1cn08L3RkPmA7XG4gICAgICAgICAgaHRtbCArPSBgPHRkIHN0eWxlPVwicGFkZGluZzogNnB4OyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPiR7dGltZUFnbyhpbmMuY3JlYXRlZEF0KX08L3RkPmA7XG4gICAgICAgICAgaHRtbCArPSAnPC90cj4nO1xuICAgICAgICB9XG4gICAgICAgIGh0bWwgKz0gJzwvdGFibGU+JztcbiAgICAgIH1cblxuICAgICAgaW5jaWRlbnRzQ29udGFpbmVyLmlubmVySFRNTCA9IGh0bWwgfHwgJzxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPjxzcGFuIGNsYXNzPVwiZW1wdHktaWNvblwiPlx1RDgzRFx1REVBODwvc3Bhbj5ObyBpbmNpZGVudHMgcmVjb3JkZWQgeWV0LjwvZGl2Pic7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaW5jaWRlbnRzQ29udGFpbmVyLmlubmVySFRNTCA9IGA8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIiBzdHlsZT1cImNvbG9yOiB2YXIoLS1iYWQtZmcpO1wiPkZhaWxlZDogJHtlc2NhcGVIdG1sKGUubWVzc2FnZSl9PC9kaXY+YDtcbiAgICB9XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBsb2FkQ29uZmlnKCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS9oZWFsdGgtY2hlY2tzL3N0YXR1cycpO1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlcy5qc29uKCk7XG4gICAgICBjb25zdCBzZXJ2aWNlcyA9IGRhdGEuc3VjY2VzcyAmJiBkYXRhLnN0YXR1cyA/IE9iamVjdC52YWx1ZXMoZGF0YS5zdGF0dXMpIDogW107XG4gICAgICBpZiAoc2VydmljZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGNvbmZpZ0NvbnRhaW5lci5pbm5lckhUTUwgPSAnPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+PHNwYW4gY2xhc3M9XCJlbXB0eS1pY29uXCI+XHUyNjk5XHVGRTBGPC9zcGFuPk5vIGhlYWx0aCBjaGVja3MgY29uZmlndXJlZCB5ZXQuIENsaWNrIFwiQWRkIEhlYWx0aCBDaGVja1wiIGJlbG93LjwvZGl2Pic7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGxldCBodG1sID0gJzx0YWJsZSBzdHlsZT1cIndpZHRoOiAxMDAlOyBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlOyBmb250LXNpemU6IDAuODVyZW07XCI+JztcbiAgICAgIGh0bWwgKz0gJzx0ciBzdHlsZT1cImJvcmRlci1ib3R0b206IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPjx0aCBzdHlsZT1cInBhZGRpbmc6IDhweDsgdGV4dC1hbGlnbjogbGVmdDtcIj5TZXJ2aWNlPC90aD48dGggc3R5bGU9XCJwYWRkaW5nOiA4cHg7IHRleHQtYWxpZ246IGxlZnQ7XCI+U3RhdHVzPC90aD48dGggc3R5bGU9XCJwYWRkaW5nOiA4cHg7IHRleHQtYWxpZ246IGxlZnQ7XCI+U0xBIFRhcmdldDwvdGg+PHRoIHN0eWxlPVwicGFkZGluZzogOHB4OyB0ZXh0LWFsaWduOiByaWdodDtcIj5BY3Rpb25zPC90aD48L3RyPic7XG4gICAgICBmb3IgKGNvbnN0IHMgb2Ygc2VydmljZXMpIHtcbiAgICAgICAgY29uc3QgaXNVcCA9IHMuc3RhdHVzID09PSAndXAnO1xuICAgICAgICBodG1sICs9IGA8dHIgc3R5bGU9XCJib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcIj5gO1xuICAgICAgICBodG1sICs9IGA8dGQgc3R5bGU9XCJwYWRkaW5nOiA4cHg7IGZvbnQtd2VpZ2h0OiA1MDA7XCI+JHtlc2NhcGVIdG1sKHMubmFtZSB8fCBzLnNlcnZpY2VJZCl9PC90ZD5gO1xuICAgICAgICBodG1sICs9IGA8dGQgc3R5bGU9XCJwYWRkaW5nOiA4cHg7IGNvbG9yOiAke2lzVXAgPyAndmFyKC0tb2stZmcpJyA6ICd2YXIoLS1iYWQtZmcpJ307XCI+JHtpc1VwID8gJ1VwJyA6ICdEb3duJ308L3RkPmA7XG4gICAgICAgIGh0bWwgKz0gYDx0ZCBzdHlsZT1cInBhZGRpbmc6IDhweDtcIj4ke3Muc2xhPy50YXJnZXQgPyBzLnNsYS50YXJnZXQgKyAnJScgOiAnLSd9PC90ZD5gO1xuICAgICAgICBodG1sICs9IGA8dGQgc3R5bGU9XCJwYWRkaW5nOiA4cHg7IHRleHQtYWxpZ246IHJpZ2h0O1wiPmA7XG4gICAgICAgIGh0bWwgKz0gYDxidXR0b24gb25jbGljaz1cImRvY3VtZW50LmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KCdoZWFsdGgtZWRpdCcsIHtkZXRhaWw6JyR7ZXNjYXBlSHRtbChzLnNlcnZpY2VJZCl9J30pKVwiIHN0eWxlPVwicGFkZGluZzogNHB4IDEwcHg7IGZvbnQtc2l6ZTogMC43OHJlbTsgbWFyZ2luLXJpZ2h0OiA0cHg7XCI+RWRpdDwvYnV0dG9uPmA7XG4gICAgICAgIGh0bWwgKz0gYDxidXR0b24gb25jbGljaz1cImRvY3VtZW50LmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KCdoZWFsdGgtZGVsZXRlJywge2RldGFpbDonJHtlc2NhcGVIdG1sKHMuc2VydmljZUlkKX0nfSkpXCIgc3R5bGU9XCJwYWRkaW5nOiA0cHggMTBweDsgZm9udC1zaXplOiAwLjc4cmVtOyBjb2xvcjogdmFyKC0tYmFkLWZnKTsgYm9yZGVyLWNvbG9yOiB2YXIoLS1iYWQtZmcpO1wiPkRlbGV0ZTwvYnV0dG9uPmA7XG4gICAgICAgIGh0bWwgKz0gJzwvdGQ+PC90cj4nO1xuICAgICAgfVxuICAgICAgaHRtbCArPSAnPC90YWJsZT4nO1xuICAgICAgY29uZmlnQ29udGFpbmVyLmlubmVySFRNTCA9IGh0bWw7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uZmlnQ29udGFpbmVyLmlubmVySFRNTCA9IGA8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIiBzdHlsZT1cImNvbG9yOiB2YXIoLS1iYWQtZmcpO1wiPkZhaWxlZDogJHtlc2NhcGVIdG1sKGUubWVzc2FnZSl9PC9kaXY+YDtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBzaG93Rm9ybShpZCwgbmFtZSwgdXJsLCB0aW1lb3V0LCBjb2Rlcywgc2xhLCBzbG93KSB7XG4gICAgZWRpdGluZ0lkID0gaWQgfHwgbnVsbDtcbiAgICBmb3JtVGl0bGUudGV4dENvbnRlbnQgPSBpZCA/ICdFZGl0IEhlYWx0aCBDaGVjaycgOiAnQWRkIEhlYWx0aCBDaGVjayc7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1mb3JtLWlkJykudmFsdWUgPSBpZCB8fCAnJztcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhbHRoLWZvcm0taWQnKS5kaXNhYmxlZCA9ICEhaWQ7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1mb3JtLW5hbWUnKS52YWx1ZSA9IG5hbWUgfHwgJyc7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1mb3JtLXVybCcpLnZhbHVlID0gdXJsIHx8ICcnO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtZm9ybS10aW1lb3V0JykudmFsdWUgPSB0aW1lb3V0IHx8IDEwMDAwO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtZm9ybS1jb2RlcycpLnZhbHVlID0gY29kZXMgfHwgJzIwMCc7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1mb3JtLXNsYScpLnZhbHVlID0gc2xhIHx8IDk5Ljk7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1mb3JtLXNsb3cnKS52YWx1ZSA9IHNsb3cgfHwgNTAwMDtcbiAgICBmb3JtRWwuc3R5bGUuZGlzcGxheSA9ICcnO1xuICAgIGFkZEJ0bi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICB9XG5cbiAgZnVuY3Rpb24gaGlkZUZvcm0oKSB7XG4gICAgZm9ybUVsLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgYWRkQnRuLnN0eWxlLmRpc3BsYXkgPSAnJztcbiAgICBlZGl0aW5nSWQgPSBudWxsO1xuICB9XG5cbiAgYWRkQnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHNob3dGb3JtKCcnLCAnJywgJycsIDEwMDAwLCAnMjAwJywgOTkuOSwgNTAwMCkpO1xuICBmb3JtQ2FuY2VsPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGhpZGVGb3JtKTtcblxuICBmb3JtU2F2ZT8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgaWQgPSBlZGl0aW5nSWQgfHwgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1mb3JtLWlkJykudmFsdWUudHJpbSgpO1xuICAgIGlmICghaWQpIHJldHVybiBzaG93Tm90aWZpY2F0aW9uKCdTZXJ2aWNlIElEIGlzIHJlcXVpcmVkJywgJ3dhcm5pbmcnKTtcbiAgICBjb25zdCB1cmwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhbHRoLWZvcm0tdXJsJykudmFsdWUudHJpbSgpO1xuICAgIGlmICghdXJsKSByZXR1cm4gc2hvd05vdGlmaWNhdGlvbignVVJMIGlzIHJlcXVpcmVkJywgJ3dhcm5pbmcnKTtcblxuICAgIGNvbnN0IGNvZGVzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1mb3JtLWNvZGVzJykudmFsdWUuc3BsaXQoJywnKS5tYXAoYyA9PiBwYXJzZUludChjLnRyaW0oKSkpLmZpbHRlcihCb29sZWFuKTtcbiAgICBjb25zdCBib2R5ID0ge1xuICAgICAgbmFtZTogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1mb3JtLW5hbWUnKS52YWx1ZS50cmltKCkgfHwgaWQsXG4gICAgICB1cmwsXG4gICAgICB0aW1lb3V0OiBwYXJzZUludChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhbHRoLWZvcm0tdGltZW91dCcpLnZhbHVlKSB8fCAxMDAwMCxcbiAgICAgIGV4cGVjdGVkU3RhdHVzQ29kZXM6IGNvZGVzLmxlbmd0aCA/IGNvZGVzIDogWzIwMF0sXG4gICAgICBzbGE6IHsgdGFyZ2V0OiBwYXJzZUZsb2F0KGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtZm9ybS1zbGEnKS52YWx1ZSkgfHwgOTkuOSB9LFxuICAgICAgc2xvd1Jlc3BvbnNlVGhyZXNob2xkOiBwYXJzZUludChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhbHRoLWZvcm0tc2xvdycpLnZhbHVlKSB8fCA1MDAwXG4gICAgfTtcblxuICAgIHRyeSB7XG4gICAgICBmb3JtU2F2ZS50ZXh0Q29udGVudCA9ICdTYXZpbmcuLi4nO1xuICAgICAgZm9ybVNhdmUuZGlzYWJsZWQgPSB0cnVlO1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgc2VjdXJlRmV0Y2goYC9hcGkvdjEvaGVhbHRoLWNoZWNrcy8ke2VuY29kZVVSSUNvbXBvbmVudChpZCl9L2NvbmZpZ3VyZWAsIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeShib2R5KVxuICAgICAgfSk7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzLmpzb24oKTtcbiAgICAgIGlmICghZGF0YS5zdWNjZXNzKSB0aHJvdyBuZXcgRXJyb3IoZGF0YS5lcnJvciB8fCAnU2F2ZSBmYWlsZWQnKTtcbiAgICAgIGhpZGVGb3JtKCk7XG4gICAgICBsb2FkQ29uZmlnKCk7XG4gICAgICBsb2FkU3RhdHVzKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgc2hvd05vdGlmaWNhdGlvbignRXJyb3I6ICcgKyBlLm1lc3NhZ2UsICdlcnJvcicpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBmb3JtU2F2ZS50ZXh0Q29udGVudCA9ICdTYXZlJztcbiAgICAgIGZvcm1TYXZlLmRpc2FibGVkID0gZmFsc2U7XG4gICAgfVxuICB9KTtcblxuICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdoZWFsdGgtZWRpdCcsIGFzeW5jIChlKSA9PiB7XG4gICAgY29uc3QgaWQgPSBlLmRldGFpbDtcbiAgICAvLyBMb2FkIGV4aXN0aW5nIGNvbmZpZyB0byBwb3B1bGF0ZSBmb3JtIFx1MjAxNCB1c2UgY3VycmVudCBzdGF0dXMgZGF0YSBhcyBmYWxsYmFja1xuICAgIHNob3dGb3JtKGlkLCAnJywgJycsIDEwMDAwLCAnMjAwJywgOTkuOSwgNTAwMCk7XG4gIH0pO1xuXG4gIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2hlYWx0aC1kZWxldGUnLCBhc3luYyAoZSkgPT4ge1xuICAgIGNvbnN0IGlkID0gZS5kZXRhaWw7XG4gICAgaWYgKCFjb25maXJtKGBEZWxldGUgaGVhbHRoIGNoZWNrIGZvciBcIiR7aWR9XCI/YCkpIHJldHVybjtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgc2VjdXJlRmV0Y2goYC9hcGkvdjEvaGVhbHRoLWNoZWNrcy8ke2VuY29kZVVSSUNvbXBvbmVudChpZCl9L2NvbmZpZ3VyZWAsIHsgbWV0aG9kOiAnREVMRVRFJyB9KTtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXMuanNvbigpO1xuICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHRocm93IG5ldyBFcnJvcihkYXRhLmVycm9yKTtcbiAgICAgIGxvYWRDb25maWcoKTtcbiAgICAgIGxvYWRTdGF0dXMoKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHNob3dOb3RpZmljYXRpb24oJ0Vycm9yOiAnICsgZXJyLm1lc3NhZ2UsICdlcnJvcicpO1xuICAgIH1cbiAgfSk7XG5cbiAgb3BlbkJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgbW9kYWw/LmNsYXNzTGlzdC5hZGQoJ3Nob3cnKTtcbiAgICBsb2FkU3RhdHVzKCk7XG4gIH0pO1xuICB3aXJlTW9kYWwobW9kYWwsIGNhbmNlbEJ0bik7XG4gIHJlZnJlc2hCdG4/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgbG9hZFN0YXR1cyk7XG5cbiAgLy8gTGF6eS1sb2FkIHRhYnNcbiAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW2RhdGEtcGFuZWw9XCJoZWFsdGgtaW5jaWRlbnRzXCJdJyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgbG9hZEluY2lkZW50cyk7XG4gIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLXBhbmVsPVwiaGVhbHRoLWNvbmZpZ1wiXScpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGxvYWRDb25maWcpO1xufSkoKTtcbjtcbi8vID09PT09PT09PT0gVVBEQVRFIE1BTkFHRU1FTlQgPT09PT09PT09PVxuKGZ1bmN0aW9uKCkge1xuICAvLyBJbmplY3QgbW9kYWwgSFRNTFxuICBpbmplY3RNb2RhbCgndXBkYXRlcy1tb2RhbCcsIGA8ZGl2IGlkPVwidXBkYXRlcy1tb2RhbFwiIGNsYXNzPVwid2VhdGhlci1tb2RhbFwiPlxuICAgIDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsLWNvbnRlbnRcIiBzdHlsZT1cIm1pbi13aWR0aDogNzUwcHg7IG1heC13aWR0aDogOTUwcHg7XCI+XG4gICAgICA8aDM+XHUyQjA2XHVGRTBGIFVwZGF0ZSBNYW5hZ2VtZW50PC9oMz5cbiAgICAgIDxwIGNsYXNzPVwibW9kYWwtc3VidGl0bGVcIj5cbiAgICAgICAgQ2hlY2sgZm9yIGNvbnRhaW5lciBpbWFnZSB1cGRhdGVzLCBhcHBseSB0aGVtLCBhbmQgbWFuYWdlIHJvbGxiYWNrcy5cbiAgICAgIDwvcD5cblxuICAgICAgPGRpdiBjbGFzcz1cInBhbmVsLXRhYnNcIj5cbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInBhbmVsLXRhYiBhY3RpdmVcIiBkYXRhLXBhbmVsPVwidXBkYXRlcy1hdmFpbGFibGVcIj5BdmFpbGFibGU8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInBhbmVsLXRhYlwiIGRhdGEtcGFuZWw9XCJ1cGRhdGVzLWhpc3RvcnlcIj5IaXN0b3J5PC9idXR0b24+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJwYW5lbC10YWJcIiBkYXRhLXBhbmVsPVwidXBkYXRlcy1hdXRvXCI+QXV0by1VcGRhdGU8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInBhbmVsLXRhYlwiIGRhdGEtcGFuZWw9XCJ1cGRhdGVzLWRhc2hjYWRkeVwiIGlkPVwidXBkYXRlcy1kYXNoY2FkZHktdGFiXCI+RGFzaENhZGR5PC9idXR0b24+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBUYWI6IEF2YWlsYWJsZSBVcGRhdGVzIC0tPlxuICAgICAgPGRpdiBpZD1cInVwZGF0ZXMtYXZhaWxhYmxlXCIgY2xhc3M9XCJwYW5lbC1zZWN0aW9uIGFjdGl2ZVwiPlxuICAgICAgICA8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMTJweDsgZGlzcGxheTogZmxleDsgZ2FwOiA4cHg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7XCI+XG4gICAgICAgICAgPGJ1dHRvbiBpZD1cInVwZGF0ZXMtY2hlY2stYnRuXCIgY2xhc3M9XCJidG4tYWNjZW50LXNvbGlkXCI+XHVEODNEXHVERDBEIENoZWNrIGZvciBVcGRhdGVzPC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvbiBpZD1cInVwZGF0ZXMtdXBkYXRlLWFsbC1idG5cIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7IHBhZGRpbmc6IDZweCAxNHB4OyBmb250LXNpemU6IDAuODJyZW07IGJhY2tncm91bmQ6ICNmOTczMTY7IGNvbG9yOiAjZmZmOyBib3JkZXI6IDFweCBzb2xpZCAjZjk3MzE2OyBib3JkZXItcmFkaXVzOiA2cHg7IGN1cnNvcjogcG9pbnRlcjtcIj5cdTJCMDZcdUZFMEYgVXBkYXRlIEFsbDwvYnV0dG9uPlxuICAgICAgICAgIDxzcGFuIGlkPVwidXBkYXRlcy1jb3VudC1iYWRnZVwiIHN0eWxlPVwiZGlzcGxheTogbm9uZTsgcGFkZGluZzogNHB4IDEwcHg7IGJvcmRlci1yYWRpdXM6IDEycHg7IGZvbnQtc2l6ZTogMC43OHJlbTsgZm9udC13ZWlnaHQ6IDYwMDsgYmFja2dyb3VuZDogdmFyKC0tYWNjZW50KTsgY29sb3I6IHZhcigtLWJnKTtcIj48L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGlkPVwidXBkYXRlcy1hdmFpbGFibGUtY29udGFpbmVyXCIgc3R5bGU9XCJtYXgtaGVpZ2h0OiA0NTBweDsgb3ZlcmZsb3cteTogYXV0bztcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj48c3BhbiBjbGFzcz1cImVtcHR5LWljb25cIj5cdUQ4M0RcdURDRTY8L3NwYW4+IENsaWNrIFwiQ2hlY2sgZm9yIFVwZGF0ZXNcIiB0byBzY2FuIGNvbnRhaW5lcnMuPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gVGFiOiBIaXN0b3J5IC0tPlxuICAgICAgPGRpdiBpZD1cInVwZGF0ZXMtaGlzdG9yeVwiIGNsYXNzPVwicGFuZWwtc2VjdGlvblwiPlxuICAgICAgICA8ZGl2IGlkPVwidXBkYXRlcy1oaXN0b3J5LWNvbnRhaW5lclwiIGNsYXNzPVwic2Nyb2xsLWNvbnRhaW5lclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPjxzcGFuIGNsYXNzPVwiYnJhbmQtc3Bpbm5lclwiPjwvc3Bhbj4gTG9hZGluZyB1cGRhdGUgaGlzdG9yeS4uLjwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIFRhYjogQXV0by1VcGRhdGUgLS0+XG4gICAgICA8ZGl2IGlkPVwidXBkYXRlcy1hdXRvXCIgY2xhc3M9XCJwYW5lbC1zZWN0aW9uXCI+XG4gICAgICAgIDxkaXYgaWQ9XCJ1cGRhdGVzLWF1dG8tY29udGFpbmVyXCIgY2xhc3M9XCJzY3JvbGwtY29udGFpbmVyXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+PHNwYW4gY2xhc3M9XCJlbXB0eS1pY29uXCI+XHVEODNFXHVERDE2PC9zcGFuPiBMb2FkaW5nIGF1dG8tdXBkYXRlIGNvbmZpZ3VyYXRpb24uLi48L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBUYWI6IERhc2hDYWRkeSBTZWxmLVVwZGF0ZSAtLT5cbiAgICAgIDxkaXYgaWQ9XCJ1cGRhdGVzLWRhc2hjYWRkeVwiIGNsYXNzPVwicGFuZWwtc2VjdGlvblwiPlxuICAgICAgICA8ZGl2IGlkPVwiZGFzaGNhZGR5LXZlcnNpb24taW5mb1wiIHN0eWxlPVwiZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiAxNnB4OyBtYXJnaW4tYm90dG9tOiAxNnB4OyBwYWRkaW5nOiAxMnB4OyBib3JkZXItcmFkaXVzOiA4cHg7IGJhY2tncm91bmQ6IHZhcigtLWJnKTtcIj5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwiZmxleDogMTtcIj5cbiAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJmb250LXdlaWdodDogNjAwOyBmb250LXNpemU6IDFyZW07XCI+RGFzaENhZGR5PC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGlkPVwiZGFzaGNhZGR5LWN1cnJlbnQtdmVyc2lvblwiIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTsgZm9udC1zaXplOiAwLjg1cmVtO1wiPkxvYWRpbmcuLi48L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGlkPVwiZGFzaGNhZGR5LXVwZGF0ZS1iYWRnZVwiIHN0eWxlPVwiZGlzcGxheTogbm9uZTsgcGFkZGluZzogNHB4IDEycHg7IGJvcmRlci1yYWRpdXM6IDEycHg7IGZvbnQtc2l6ZTogMC43OHJlbTsgZm9udC13ZWlnaHQ6IDYwMDsgYmFja2dyb3VuZDogdmFyKC0tYWNjZW50KTsgY29sb3I6IHZhcigtLWJnKTtcIj5VcGRhdGUgYXZhaWxhYmxlPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGlkPVwiZGFzaGNhZGR5LXVwZGF0ZS1kZXRhaWxzXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lOyBtYXJnaW4tYm90dG9tOiAxNnB4OyBwYWRkaW5nOiAxMnB4OyBib3JkZXItcmFkaXVzOiA4cHg7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XCI+XG4gICAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjsgYWxpZ24taXRlbXM6IGNlbnRlcjsgbWFyZ2luLWJvdHRvbTogOHB4O1wiPlxuICAgICAgICAgICAgPHNwYW4gc3R5bGU9XCJmb250LXdlaWdodDogNjAwO1wiPk5ldyB2ZXJzaW9uOiA8c3BhbiBpZD1cImRhc2hjYWRkeS1uZXctdmVyc2lvblwiPjwvc3Bhbj48L3NwYW4+XG4gICAgICAgICAgICA8YnV0dG9uIGlkPVwiZGFzaGNhZGR5LWFwcGx5LWJ0blwiIGNsYXNzPVwiYnRuLWFjY2VudC1zb2xpZFwiIHN0eWxlPVwicGFkZGluZzogNnB4IDE2cHg7IGZvbnQtc2l6ZTogMC44NXJlbTtcIj5VcGRhdGUgTm93PC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdiBpZD1cImRhc2hjYWRkeS1jaGFuZ2Vsb2dcIiBzdHlsZT1cImZvbnQtc2l6ZTogMC44cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXgtaGVpZ2h0OiAxMjBweDsgb3ZlcmZsb3cteTogYXV0bzsgd2hpdGUtc3BhY2U6IHByZS13cmFwOyBmb250LWZhbWlseTogdmFyKC0tZm9udC1tb25vKTsgbGluZS1oZWlnaHQ6IDEuNTtcIj48L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgaWQ9XCJkYXNoY2FkZHktc3RhdHVzLWJhclwiIHN0eWxlPVwiZGlzcGxheTogbm9uZTsgbWFyZ2luLWJvdHRvbTogMTZweDsgcGFkZGluZzogMTBweCAxMnB4OyBib3JkZXItcmFkaXVzOiA4cHg7IGZvbnQtc2l6ZTogMC44NXJlbTtcIj48L2Rpdj5cbiAgICAgICAgPGRpdiBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDEycHg7XCI+XG4gICAgICAgICAgPGJ1dHRvbiBpZD1cImRhc2hjYWRkeS1jaGVjay1idG5cIiBzdHlsZT1cInBhZGRpbmc6IDZweCAxNHB4OyBmb250LXNpemU6IDAuODJyZW07XCI+Q2hlY2sgZm9yIFVwZGF0ZXM8L2J1dHRvbj5cbiAgICAgICAgICA8YnV0dG9uIGlkPVwiZGFzaGNhZGR5LXJvbGxiYWNrLWJ0blwiIHN0eWxlPVwicGFkZGluZzogNnB4IDE0cHg7IGZvbnQtc2l6ZTogMC44MnJlbTsgbWFyZ2luLWxlZnQ6IDZweDtcIj5Sb2xsYmFjazwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBpZD1cImRhc2hjYWRkeS1oaXN0b3J5LWNvbnRhaW5lclwiIHN0eWxlPVwibWF4LWhlaWdodDogMjUwcHg7IG92ZXJmbG93LXk6IGF1dG87XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+PHNwYW4gY2xhc3M9XCJlbXB0eS1pY29uXCI+XHVEODNEXHVEQ0U2PC9zcGFuPk5vIHNlbGYtdXBkYXRlIGhpc3RvcnkuPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJwYW5lbC1ib3R0b20tYmFyXCI+XG4gICAgICAgIDxzcGFuIGlkPVwidXBkYXRlcy1sYXN0LWNoZWNrXCIgY2xhc3M9XCJ0ZXh0LWF1dG8tcmlnaHRcIj48L3NwYW4+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzcz1cIndlYXRoZXItbW9kYWwtYnV0dG9ucyBtb2RhbC1mb290ZXItYmFyXCI+XG4gICAgICAgIDxidXR0b24gaWQ9XCJ1cGRhdGVzLWNhbmNlbFwiPkNsb3NlPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+YCk7XG5cbiAgY29uc3QgbW9kYWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndXBkYXRlcy1tb2RhbCcpO1xuICBjb25zdCBvcGVuQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3VwZGF0ZXMtYnRuJyk7XG4gIGNvbnN0IGNhbmNlbEJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd1cGRhdGVzLWNhbmNlbCcpO1xuICBjb25zdCBjaGVja0J0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd1cGRhdGVzLWNoZWNrLWJ0bicpO1xuICBjb25zdCBhdmFpbGFibGVDb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndXBkYXRlcy1hdmFpbGFibGUtY29udGFpbmVyJyk7XG4gIGNvbnN0IGhpc3RvcnlDb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndXBkYXRlcy1oaXN0b3J5LWNvbnRhaW5lcicpO1xuICBjb25zdCBhdXRvQ29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3VwZGF0ZXMtYXV0by1jb250YWluZXInKTtcbiAgY29uc3QgbGFzdENoZWNrU3BhbiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd1cGRhdGVzLWxhc3QtY2hlY2snKTtcblxuICBhc3luYyBmdW5jdGlvbiBsb2FkQXZhaWxhYmxlKCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS91cGRhdGVzL2F2YWlsYWJsZScpO1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlcy5qc29uKCk7XG4gICAgICBpZiAoIWRhdGEuc3VjY2VzcykgdGhyb3cgbmV3IEVycm9yKGRhdGEuZXJyb3IpO1xuXG4gICAgICBjb25zdCB1cGRhdGVzID0gZGF0YS51cGRhdGVzIHx8IFtdO1xuICAgICAgaWYgKHVwZGF0ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGF2YWlsYWJsZUNvbnRhaW5lci5pbm5lckhUTUwgPSAnPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+PHNwYW4gY2xhc3M9XCJlbXB0eS1pY29uXCI+XHUyNzA1PC9zcGFuPkFsbCBjb250YWluZXJzIGFyZSB1cCB0byBkYXRlLjwvZGl2Pic7XG4gICAgICAgIGxhc3RDaGVja1NwYW4udGV4dENvbnRlbnQgPSAnJztcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3VwZGF0ZXMtdXBkYXRlLWFsbC1idG4nKS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndXBkYXRlcy1jb3VudC1iYWRnZScpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIHdpbmRvdy5fcGVuZGluZ1VwZGF0ZXMgPSBbXTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBsZXQgaHRtbCA9ICc8dGFibGUgc3R5bGU9XCJ3aWR0aDogMTAwJTsgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsgZm9udC1zaXplOiAwLjg1cmVtO1wiPic7XG4gICAgICBodG1sICs9ICc8dHIgc3R5bGU9XCJib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgY29sb3I6IHZhcigtLW11dGVkKTtcIj48dGggc3R5bGU9XCJwYWRkaW5nOiA4cHg7IHRleHQtYWxpZ246IGxlZnQ7XCI+Q29udGFpbmVyPC90aD48dGggc3R5bGU9XCJwYWRkaW5nOiA4cHg7IHRleHQtYWxpZ246IGxlZnQ7XCI+SW1hZ2U8L3RoPjx0aCBzdHlsZT1cInBhZGRpbmc6IDhweDsgdGV4dC1hbGlnbjogbGVmdDtcIj5DdXJyZW50PC90aD48dGggc3R5bGU9XCJwYWRkaW5nOiA4cHg7IHRleHQtYWxpZ246IGxlZnQ7XCI+TGF0ZXN0PC90aD48dGggc3R5bGU9XCJwYWRkaW5nOiA4cHg7IHRleHQtYWxpZ246IHJpZ2h0O1wiPkFjdGlvbnM8L3RoPjwvdHI+JztcbiAgICAgIGZvciAoY29uc3QgdSBvZiB1cGRhdGVzKSB7XG4gICAgICAgIC8vIE1hdGNoIGFwcCBieSBjb250YWluZXJJZCBmaXJzdCwgdGhlbiBuYW1lXG4gICAgICAgIGNvbnN0IGFwcElkID0gKCgpID0+IHtcbiAgICAgICAgICBjb25zdCBhcHBzID0gd2luZG93LkFQUFMgfHwgW107XG4gICAgICAgICAgZm9yIChjb25zdCBhIG9mIGFwcHMpIHtcbiAgICAgICAgICAgIGlmIChhLmNvbnRhaW5lcklkID09PSB1LmNvbnRhaW5lcklkIHx8IGEubmFtZSA9PT0gdS5jb250YWluZXJOYW1lIHx8IGEuaWQgPT09IHUuY29udGFpbmVyTmFtZSkgcmV0dXJuIGEuaWQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB1LmNvbnRhaW5lck5hbWU7XG4gICAgICAgIH0pKCk7XG4gICAgICAgIGh0bWwgKz0gYDx0ciBkYXRhLWFwcC1pZD1cIiR7ZXNjYXBlSHRtbChhcHBJZCl9XCIgc3R5bGU9XCJib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcIj5gO1xuICAgICAgICBodG1sICs9IGA8dGQgc3R5bGU9XCJwYWRkaW5nOiA4cHg7IGZvbnQtd2VpZ2h0OiA1MDA7XCI+JHtlc2NhcGVIdG1sKHUuY29udGFpbmVyTmFtZSl9PC90ZD5gO1xuICAgICAgICBodG1sICs9IGA8dGQgc3R5bGU9XCJwYWRkaW5nOiA4cHg7IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+JHtlc2NhcGVIdG1sKHUuaW1hZ2VOYW1lKX08L3RkPmA7XG4gICAgICAgIGh0bWwgKz0gYDx0ZCBzdHlsZT1cInBhZGRpbmc6IDhweDtcIj48Y29kZSBzdHlsZT1cImZvbnQtc2l6ZTogMC43OHJlbTsgYmFja2dyb3VuZDogdmFyKC0tYmcpOyBwYWRkaW5nOiAycHggNnB4OyBib3JkZXItcmFkaXVzOiA0cHg7XCI+JHtlc2NhcGVIdG1sKHUuY3VycmVudERpZ2VzdCl9PC9jb2RlPjwvdGQ+YDtcbiAgICAgICAgaHRtbCArPSBgPHRkIHN0eWxlPVwicGFkZGluZzogOHB4O1wiPjxjb2RlIHN0eWxlPVwiZm9udC1zaXplOiAwLjc4cmVtOyBiYWNrZ3JvdW5kOiB2YXIoLS1vay1iZyk7IGNvbG9yOiB2YXIoLS1vay1mZyk7IHBhZGRpbmc6IDJweCA2cHg7IGJvcmRlci1yYWRpdXM6IDRweDtcIj4ke2VzY2FwZUh0bWwodS5sYXRlc3REaWdlc3QpfTwvY29kZT48L3RkPmA7XG4gICAgICAgIGh0bWwgKz0gYDx0ZCBzdHlsZT1cInBhZGRpbmc6IDhweDsgdGV4dC1hbGlnbjogcmlnaHQ7XCI+YDtcbiAgICAgICAgaHRtbCArPSBgPGJ1dHRvbiBjbGFzcz1cInVwZGF0ZS1ub3ctYnRuXCIgZGF0YS1pZD1cIiR7ZXNjYXBlSHRtbCh1LmNvbnRhaW5lcklkKX1cIiBkYXRhLW5hbWU9XCIke2VzY2FwZUh0bWwodS5jb250YWluZXJOYW1lKX1cIiBzdHlsZT1cInBhZGRpbmc6IDRweCAxMHB4OyBmb250LXNpemU6IDAuNzhyZW07IGJhY2tncm91bmQ6IHZhcigtLWFjY2VudCk7IGNvbG9yOiB2YXIoLS1iZyk7IGJvcmRlci1jb2xvcjogdmFyKC0tYWNjZW50KTsgbWFyZ2luLXJpZ2h0OiA0cHg7XCI+VXBkYXRlPC9idXR0b24+YDtcbiAgICAgICAgaHRtbCArPSBgPGJ1dHRvbiBjbGFzcz1cInJvbGxiYWNrLWJ0blwiIGRhdGEtaWQ9XCIke2VzY2FwZUh0bWwodS5jb250YWluZXJJZCl9XCIgZGF0YS1uYW1lPVwiJHtlc2NhcGVIdG1sKHUuY29udGFpbmVyTmFtZSl9XCIgc3R5bGU9XCJwYWRkaW5nOiA0cHggMTBweDsgZm9udC1zaXplOiAwLjc4cmVtO1wiPlJvbGxiYWNrPC9idXR0b24+YDtcbiAgICAgICAgaHRtbCArPSAnPC90ZD48L3RyPic7XG4gICAgICB9XG4gICAgICBodG1sICs9ICc8L3RhYmxlPic7XG4gICAgICBhdmFpbGFibGVDb250YWluZXIuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgIGxhc3RDaGVja1NwYW4udGV4dENvbnRlbnQgPSB1cGRhdGVzLmxlbmd0aCArICcgdXBkYXRlKHMpIGF2YWlsYWJsZSc7XG5cbiAgICAgIC8vIFNob3cgY291bnQgYmFkZ2UgYW5kIFVwZGF0ZSBBbGwgYnV0dG9uXG4gICAgICBjb25zdCBjb3VudEJhZGdlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3VwZGF0ZXMtY291bnQtYmFkZ2UnKTtcbiAgICAgIGNvbnN0IHVwZGF0ZUFsbEJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd1cGRhdGVzLXVwZGF0ZS1hbGwtYnRuJyk7XG4gICAgICBpZiAoY291bnRCYWRnZSkge1xuICAgICAgICBjb3VudEJhZGdlLnRleHRDb250ZW50ID0gdXBkYXRlcy5sZW5ndGggKyAnIHBlbmRpbmcnO1xuICAgICAgICBjb3VudEJhZGdlLnN0eWxlLmRpc3BsYXkgPSAnJztcbiAgICAgIH1cbiAgICAgIGlmICh1cGRhdGVBbGxCdG4gJiYgdXBkYXRlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHVwZGF0ZUFsbEJ0bi5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gICAgICB9XG5cbiAgICAgIC8vIFN0b3JlIHVwZGF0ZXMgZm9yIFVwZGF0ZSBBbGwgYnV0dG9uXG4gICAgICB3aW5kb3cuX3BlbmRpbmdVcGRhdGVzID0gdXBkYXRlcztcblxuICAgICAgLy8gV2lyZSB1cGRhdGUgYnV0dG9uc1xuICAgICAgYXZhaWxhYmxlQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoJy51cGRhdGUtbm93LWJ0bicpLmZvckVhY2goYnRuID0+IHtcbiAgICAgICAgYnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGlkID0gYnRuLmRhdGFzZXQuaWQ7XG4gICAgICAgICAgY29uc3QgbmFtZSA9IGJ0bi5kYXRhc2V0Lm5hbWU7XG4gICAgICAgICAgaWYgKCFjb25maXJtKGBVcGRhdGUgXCIke25hbWV9XCIgdG8gdGhlIGxhdGVzdCB2ZXJzaW9uPyBUaGUgY29udGFpbmVyIHdpbGwgcmVzdGFydC5gKSkgcmV0dXJuO1xuICAgICAgICAgIGJ0bi50ZXh0Q29udGVudCA9ICdVcGRhdGluZy4uLic7XG4gICAgICAgICAgYnRuLmRpc2FibGVkID0gdHJ1ZTtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgciA9IGF3YWl0IHNlY3VyZUZldGNoKGAvYXBpL3YxL3VwZGF0ZXMvdXBkYXRlLyR7ZW5jb2RlVVJJQ29tcG9uZW50KGlkKX1gLCB7XG4gICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoeyBhdXRvUm9sbGJhY2s6IHRydWUgfSlcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3QgZCA9IGF3YWl0IHIuanNvbigpO1xuICAgICAgICAgICAgaWYgKGQuc3VjY2Vzcykge1xuICAgICAgICAgICAgICBidG4udGV4dENvbnRlbnQgPSAnRG9uZSEnO1xuICAgICAgICAgICAgICBidG4uc3R5bGUuYmFja2dyb3VuZCA9ICd2YXIoLS1vay1mZyknO1xuICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IGxvYWRBdmFpbGFibGUoKSwgMjAwMCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZC5lcnJvciB8fCAnVXBkYXRlIGZhaWxlZCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGJ0bi50ZXh0Q29udGVudCA9ICdGYWlsZWQnO1xuICAgICAgICAgICAgYnRuLnN0eWxlLmNvbG9yID0gJ3ZhcigtLWJhZC1mZyknO1xuICAgICAgICAgICAgc2hvd05vdGlmaWNhdGlvbignVXBkYXRlIGVycm9yOiAnICsgZS5tZXNzYWdlLCAnZXJyb3InKTtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4geyBidG4udGV4dENvbnRlbnQgPSAnVXBkYXRlJzsgYnRuLmRpc2FibGVkID0gZmFsc2U7IGJ0bi5zdHlsZS5jb2xvciA9ICcnOyBidG4uc3R5bGUuYmFja2dyb3VuZCA9ICcnOyB9LCAzMDAwKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIFdpcmUgcm9sbGJhY2sgYnV0dG9uc1xuICAgICAgYXZhaWxhYmxlQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoJy5yb2xsYmFjay1idG4nKS5mb3JFYWNoKGJ0biA9PiB7XG4gICAgICAgIGJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCBpZCA9IGJ0bi5kYXRhc2V0LmlkO1xuICAgICAgICAgIGNvbnN0IG5hbWUgPSBidG4uZGF0YXNldC5uYW1lO1xuICAgICAgICAgIGlmICghY29uZmlybShgUm9sbGJhY2sgXCIke25hbWV9XCIgdG8gaXRzIHByZXZpb3VzIHZlcnNpb24/YCkpIHJldHVybjtcbiAgICAgICAgICBidG4udGV4dENvbnRlbnQgPSAnUm9sbGluZyBiYWNrLi4uJztcbiAgICAgICAgICBidG4uZGlzYWJsZWQgPSB0cnVlO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCByID0gYXdhaXQgc2VjdXJlRmV0Y2goYC9hcGkvdjEvdXBkYXRlcy9yb2xsYmFjay8ke2VuY29kZVVSSUNvbXBvbmVudChpZCl9YCwgeyBtZXRob2Q6ICdQT1NUJyB9KTtcbiAgICAgICAgICAgIGNvbnN0IGQgPSBhd2FpdCByLmpzb24oKTtcbiAgICAgICAgICAgIGlmIChkLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgYnRuLnRleHRDb250ZW50ID0gJ1JvbGxlZCBiYWNrISc7XG4gICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gbG9hZEF2YWlsYWJsZSgpLCAyMDAwKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihkLmVycm9yIHx8ICdSb2xsYmFjayBmYWlsZWQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBidG4udGV4dENvbnRlbnQgPSAnRmFpbGVkJztcbiAgICAgICAgICAgIHNob3dOb3RpZmljYXRpb24oJ1JvbGxiYWNrIGVycm9yOiAnICsgZS5tZXNzYWdlLCAnZXJyb3InKTtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4geyBidG4udGV4dENvbnRlbnQgPSAnUm9sbGJhY2snOyBidG4uZGlzYWJsZWQgPSBmYWxzZTsgfSwgMzAwMCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGF2YWlsYWJsZUNvbnRhaW5lci5pbm5lckhUTUwgPSBgPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCIgc3R5bGU9XCJjb2xvcjogdmFyKC0tYmFkLWZnKTtcIj5GYWlsZWQ6ICR7ZXNjYXBlSHRtbChlLm1lc3NhZ2UpfTwvZGl2PmA7XG4gICAgfVxuICB9XG5cbiAgLy8gVXBkYXRlIEFsbCBcdTIwMTQgc2VxdWVudGlhbGx5LCBza2lwIGZhaWx1cmVzXG4gIGFzeW5jIGZ1bmN0aW9uIHVwZGF0ZUFsbENvbnRhaW5lcnMoKSB7XG4gICAgY29uc3QgdXBkYXRlcyA9IHdpbmRvdy5fcGVuZGluZ1VwZGF0ZXMgfHwgW107XG4gICAgaWYgKCF1cGRhdGVzLmxlbmd0aCkgcmV0dXJuO1xuICAgIGNvbnN0IGJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd1cGRhdGVzLXVwZGF0ZS1hbGwtYnRuJyk7XG4gICAgaWYgKCFjb25maXJtKGBVcGRhdGUgYWxsICR7dXBkYXRlcy5sZW5ndGh9IGNvbnRhaW5lcnM/IEVhY2ggd2lsbCByZXN0YXJ0LmApKSByZXR1cm47XG4gICAgYnRuLnRleHRDb250ZW50ID0gJ1x1MjNGMyBVcGRhdGluZy4uLic7XG4gICAgYnRuLmRpc2FibGVkID0gdHJ1ZTtcbiAgICBsZXQgc3VjY2VzcyA9IDAsIGZhaWxlZCA9IDA7XG4gICAgZm9yIChjb25zdCB1IG9mIHVwZGF0ZXMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHIgPSBhd2FpdCBzZWN1cmVGZXRjaChgL2FwaS92MS91cGRhdGVzL3VwZGF0ZS8ke2VuY29kZVVSSUNvbXBvbmVudCh1LmNvbnRhaW5lcklkKX1gLCB7XG4gICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoeyBhdXRvUm9sbGJhY2s6IHRydWUgfSlcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGQgPSBhd2FpdCByLmpzb24oKTtcbiAgICAgICAgaWYgKGQuc3VjY2Vzcykgc3VjY2VzcysrO1xuICAgICAgICBlbHNlIGZhaWxlZCsrO1xuICAgICAgfSBjYXRjaCAoXykgeyBmYWlsZWQrKzsgfVxuICAgIH1cbiAgICBidG4udGV4dENvbnRlbnQgPSBgXHUyNzA1IERvbmVgO1xuICAgIHNob3dOb3RpZmljYXRpb24oYFVwZGF0ZSBhbGw6ICR7c3VjY2Vzc30gc3VjY2VlZGVkLCAke2ZhaWxlZH0gZmFpbGVkLmAsIHN1Y2Nlc3MgPiAwICYmIGZhaWxlZCA9PT0gMCA/ICdzdWNjZXNzJyA6ICdlcnJvcicpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgYnRuLnRleHRDb250ZW50ID0gJ1x1MkIwNlx1RkUwRiBVcGRhdGUgQWxsJztcbiAgICAgIGJ0bi5kaXNhYmxlZCA9IGZhbHNlO1xuICAgICAgbG9hZEF2YWlsYWJsZSgpO1xuICAgIH0sIDMwMDApO1xuICB9XG5cbiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3VwZGF0ZXMtdXBkYXRlLWFsbC1idG4nKT8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB1cGRhdGVBbGxDb250YWluZXJzKTtcblxuICBhc3luYyBmdW5jdGlvbiBjaGVja0ZvclVwZGF0ZXMoKSB7XG4gICAgY2hlY2tCdG4udGV4dENvbnRlbnQgPSAnXHVEODNEXHVERDBEIENoZWNraW5nLi4uJztcbiAgICBjaGVja0J0bi5kaXNhYmxlZCA9IHRydWU7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHNlY3VyZUZldGNoKCcvYXBpL3YxL3VwZGF0ZXMvY2hlY2snLCB7IG1ldGhvZDogJ1BPU1QnIH0pO1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlcy5qc29uKCk7XG4gICAgICBpZiAoIWRhdGEuc3VjY2VzcykgdGhyb3cgbmV3IEVycm9yKGRhdGEuZXJyb3IpO1xuICAgICAgY2hlY2tCdG4udGV4dENvbnRlbnQgPSAnXHUyNzA1IERvbmUhJztcbiAgICAgIGF3YWl0IGxvYWRBdmFpbGFibGUoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjaGVja0J0bi50ZXh0Q29udGVudCA9ICdcdTI3NEMgRmFpbGVkJztcbiAgICAgIHNob3dOb3RpZmljYXRpb24oJ0NoZWNrIGVycm9yOiAnICsgZS5tZXNzYWdlLCAnZXJyb3InKTtcbiAgICB9XG4gICAgc2V0VGltZW91dCgoKSA9PiB7IGNoZWNrQnRuLnRleHRDb250ZW50ID0gJ1x1RDgzRFx1REQwRCBDaGVjayBmb3IgVXBkYXRlcyc7IGNoZWNrQnRuLmRpc2FibGVkID0gZmFsc2U7IH0sIDMwMDApO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gbG9hZEhpc3RvcnkoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGhpc3RvcnlDb250YWluZXIuaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPjxzcGFuIGNsYXNzPVwiYnJhbmQtc3Bpbm5lclwiPjwvc3Bhbj4gTG9hZGluZy4uLjwvZGl2Pic7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS91cGRhdGVzL2hpc3Rvcnk/bGltaXQ9NTAnKTtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXMuanNvbigpO1xuICAgICAgY29uc3QgaGlzdG9yeSA9IGRhdGEuc3VjY2VzcyAmJiBkYXRhLmhpc3RvcnkgPyBkYXRhLmhpc3RvcnkgOiBbXTtcbiAgICAgIGlmIChoaXN0b3J5Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBoaXN0b3J5Q29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj48c3BhbiBjbGFzcz1cImVtcHR5LWljb25cIj5cdUQ4M0RcdURDQ0I8L3NwYW4+Tm8gdXBkYXRlIGhpc3RvcnkgeWV0LjwvZGl2Pic7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGxldCBodG1sID0gJzx0YWJsZSBzdHlsZT1cIndpZHRoOiAxMDAlOyBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlOyBmb250LXNpemU6IDAuODJyZW07XCI+JztcbiAgICAgIGh0bWwgKz0gJzx0ciBzdHlsZT1cImJvcmRlci1ib3R0b206IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPjx0aCBzdHlsZT1cInBhZGRpbmc6IDZweDsgdGV4dC1hbGlnbjogbGVmdDtcIj5XaGVuPC90aD48dGggc3R5bGU9XCJwYWRkaW5nOiA2cHg7IHRleHQtYWxpZ246IGxlZnQ7XCI+Q29udGFpbmVyPC90aD48dGggc3R5bGU9XCJwYWRkaW5nOiA2cHg7IHRleHQtYWxpZ246IGxlZnQ7XCI+SW1hZ2U8L3RoPjx0aCBzdHlsZT1cInBhZGRpbmc6IDZweDsgdGV4dC1hbGlnbjogbGVmdDtcIj5EdXJhdGlvbjwvdGg+PHRoIHN0eWxlPVwicGFkZGluZzogNnB4OyB0ZXh0LWFsaWduOiBsZWZ0O1wiPlN0YXR1czwvdGg+PC90cj4nO1xuICAgICAgZm9yIChjb25zdCBoIG9mIGhpc3RvcnkpIHtcbiAgICAgICAgY29uc3Qgb2sgPSBoLnN0YXR1cyA9PT0gJ3N1Y2Nlc3MnO1xuICAgICAgICBjb25zdCBkdXIgPSBoLmR1cmF0aW9uID8gKGguZHVyYXRpb24gPCAxMDAwID8gaC5kdXJhdGlvbiArICdtcycgOiBNYXRoLnJvdW5kKGguZHVyYXRpb24gLyAxMDAwKSArICdzJykgOiAnLSc7XG4gICAgICAgIGh0bWwgKz0gYDx0ciBzdHlsZT1cImJvcmRlci1ib3R0b206IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1wiPmA7XG4gICAgICAgIGh0bWwgKz0gYDx0ZCBzdHlsZT1cInBhZGRpbmc6IDZweDsgY29sb3I6IHZhcigtLW11dGVkKTtcIj4ke3RpbWVBZ28oaC50aW1lc3RhbXApfTwvdGQ+YDtcbiAgICAgICAgaHRtbCArPSBgPHRkIHN0eWxlPVwicGFkZGluZzogNnB4OyBmb250LXdlaWdodDogNTAwO1wiPiR7ZXNjYXBlSHRtbChoLmNvbnRhaW5lck5hbWUpfTwvdGQ+YDtcbiAgICAgICAgaHRtbCArPSBgPHRkIHN0eWxlPVwicGFkZGluZzogNnB4OyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPiR7ZXNjYXBlSHRtbChoLmltYWdlTmFtZSl9PC90ZD5gO1xuICAgICAgICBodG1sICs9IGA8dGQgc3R5bGU9XCJwYWRkaW5nOiA2cHg7XCI+JHtkdXJ9PC90ZD5gO1xuICAgICAgICBodG1sICs9IGA8dGQgc3R5bGU9XCJwYWRkaW5nOiA2cHg7XCI+PHNwYW4gc3R5bGU9XCJjb2xvcjogJHtvayA/ICd2YXIoLS1vay1mZyknIDogJ3ZhcigtLWJhZC1mZyknfTtcIj4ke29rID8gJ1x1MjcxMyBzdWNjZXNzJyA6ICdcdTI3MTcgZmFpbGVkJ308L3NwYW4+PC90ZD5gO1xuICAgICAgICBodG1sICs9ICc8L3RyPic7XG4gICAgICAgIGlmICghb2sgJiYgaC5lcnJvcikge1xuICAgICAgICAgIGh0bWwgKz0gYDx0cj48dGQgY29sc3Bhbj1cIjVcIiBzdHlsZT1cInBhZGRpbmc6IDRweCA2cHggOHB4OyBmb250LXNpemU6IDAuNzhyZW07IGNvbG9yOiB2YXIoLS1iYWQtZmcpO1wiPiR7ZXNjYXBlSHRtbChoLmVycm9yKX08L3RkPjwvdHI+YDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaHRtbCArPSAnPC90YWJsZT4nO1xuICAgICAgaGlzdG9yeUNvbnRhaW5lci5pbm5lckhUTUwgPSBodG1sO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGhpc3RvcnlDb250YWluZXIuaW5uZXJIVE1MID0gYDxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiIHN0eWxlPVwiY29sb3I6IHZhcigtLWJhZC1mZyk7XCI+RmFpbGVkOiAke2VzY2FwZUh0bWwoZS5tZXNzYWdlKX08L2Rpdj5gO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGxvYWRBdXRvQ29uZmlnKCkge1xuICAgIHRyeSB7XG4gICAgICBhdXRvQ29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj48c3BhbiBjbGFzcz1cImJyYW5kLXNwaW5uZXJcIj48L3NwYW4+IExvYWRpbmcuLi48L2Rpdj4nO1xuXG4gICAgICAvLyBGZXRjaCBjb250YWluZXJzIGFuZCBzYXZlZCBhdXRvLXVwZGF0ZSBjb25maWcgaW4gcGFyYWxsZWxcbiAgICAgIGNvbnN0IFtjb250YWluZXJzUmVzLCBjb25maWdSZXNdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICBmZXRjaCgnL2FwaS92MS9zdGF0cy9jb250YWluZXJzJyksXG4gICAgICAgIGZldGNoKCcvYXBpL3YxL3VwZGF0ZXMvYXV0by11cGRhdGUnKVxuICAgICAgXSk7XG4gICAgICBjb25zdCBjb250YWluZXJzRGF0YSA9IGF3YWl0IGNvbnRhaW5lcnNSZXMuanNvbigpO1xuICAgICAgY29uc3QgY29uZmlnRGF0YSA9IGF3YWl0IGNvbmZpZ1Jlcy5qc29uKCk7XG5cbiAgICAgIGNvbnN0IGNvbnRhaW5lcnMgPSBjb250YWluZXJzRGF0YS5zdWNjZXNzICYmIGNvbnRhaW5lcnNEYXRhLnN0YXRzID8gY29udGFpbmVyc0RhdGEuc3RhdHMgOiBbXTtcbiAgICAgIGNvbnN0IHNhdmVkQ29uZmlnID0gY29uZmlnRGF0YS5zdWNjZXNzICYmIGNvbmZpZ0RhdGEuY29uZmlnID8gY29uZmlnRGF0YS5jb25maWcgOiB7fTtcblxuICAgICAgaWYgKGNvbnRhaW5lcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGF1dG9Db250YWluZXIuaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPjxzcGFuIGNsYXNzPVwiZW1wdHktaWNvblwiPlx1RDgzRVx1REQxNjwvc3Bhbj5ObyBydW5uaW5nIGNvbnRhaW5lcnMgZm91bmQuPC9kaXY+JztcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBsZXQgaHRtbCA9ICc8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMTJweDsgZm9udC1zaXplOiAwLjhyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+QXV0by11cGRhdGVzIHJ1biBkdXJpbmcgbWFpbnRlbmFuY2Ugd2luZG93IChkZWZhdWx0IDJBTS00QU0pLiBEYWlseSA9IGV2ZXJ5IGRheSwgV2Vla2x5ID0gU3VuZGF5cywgTW9udGhseSA9IDFzdCBvZiBtb250aC48L2Rpdj4nO1xuICAgICAgaHRtbCArPSAnPHRhYmxlIHN0eWxlPVwid2lkdGg6IDEwMCU7IGJvcmRlci1jb2xsYXBzZTogY29sbGFwc2U7IGZvbnQtc2l6ZTogMC44NXJlbTtcIj4nO1xuICAgICAgaHRtbCArPSAnPHRyIHN0eWxlPVwiYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+PHRoIHN0eWxlPVwicGFkZGluZzogOHB4OyB0ZXh0LWFsaWduOiBsZWZ0O1wiPkNvbnRhaW5lcjwvdGg+PHRoIHN0eWxlPVwicGFkZGluZzogOHB4OyB0ZXh0LWFsaWduOiBsZWZ0O1wiPlNjaGVkdWxlPC90aD48dGggc3R5bGU9XCJwYWRkaW5nOiA4cHg7IHRleHQtYWxpZ246IGxlZnQ7XCI+V2luZG93PC90aD48dGggc3R5bGU9XCJwYWRkaW5nOiA4cHg7IHRleHQtYWxpZ246IGxlZnQ7XCI+Um9sbGJhY2s8L3RoPjx0aCBzdHlsZT1cInBhZGRpbmc6IDhweDsgdGV4dC1hbGlnbjogbGVmdDtcIj5MYXN0IFJ1bjwvdGg+PHRoIHN0eWxlPVwicGFkZGluZzogOHB4OyB0ZXh0LWFsaWduOiByaWdodDtcIj5BY3Rpb25zPC90aD48L3RyPic7XG4gICAgICBmb3IgKGNvbnN0IGMgb2YgY29udGFpbmVycykge1xuICAgICAgICBjb25zdCBuYW1lID0gYy5uYW1lIHx8IGMuTmFtZXM/LlswXT8ucmVwbGFjZSgvXlxcLy8sICcnKSB8fCBjLklkPy5zdWJzdHJpbmcoMCwgMTIpO1xuICAgICAgICBjb25zdCBjaWQgPSBjLmNvbnRhaW5lcklkIHx8IGMuSWQ7XG4gICAgICAgIGNvbnN0IHNhdmVkID0gc2F2ZWRDb25maWdbY2lkXSB8fCB7fTtcbiAgICAgICAgY29uc3Qgc2NoZWR1bGVWYWwgPSBzYXZlZC5lbmFibGVkID8gKHNhdmVkLnNjaGVkdWxlIHx8ICd3ZWVrbHknKSA6ICcnO1xuICAgICAgICBjb25zdCByb2xsYmFja1ZhbCA9IHNhdmVkLmF1dG9Sb2xsYmFjayAhPT0gZmFsc2U7XG4gICAgICAgIGNvbnN0IHdpbmRvd1ZhbCA9IHNhdmVkLm1haW50ZW5hbmNlV2luZG93IHx8ICcnO1xuICAgICAgICBjb25zdCBsYXN0UnVuID0gc2F2ZWQubGFzdEF1dG9VcGRhdGUgPyB0aW1lQWdvKHNhdmVkLmxhc3RBdXRvVXBkYXRlKSA6ICdOZXZlcic7XG5cbiAgICAgICAgaHRtbCArPSBgPHRyIHN0eWxlPVwiYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XCIgZGF0YS1jb250YWluZXItaWQ9XCIke2VzY2FwZUh0bWwoY2lkKX1cIj5gO1xuICAgICAgICBodG1sICs9IGA8dGQgc3R5bGU9XCJwYWRkaW5nOiA4cHg7IGZvbnQtd2VpZ2h0OiA1MDA7XCI+JHtlc2NhcGVIdG1sKG5hbWUpfTwvdGQ+YDtcbiAgICAgICAgaHRtbCArPSBgPHRkIHN0eWxlPVwicGFkZGluZzogOHB4O1wiPlxuICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJhdXRvLXNjaGVkdWxlXCIgZGF0YS1pZD1cIiR7ZXNjYXBlSHRtbChjaWQpfVwiIHN0eWxlPVwicGFkZGluZzogNHB4IDhweDsgYm9yZGVyLXJhZGl1czogNHB4OyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBiYWNrZ3JvdW5kOiB2YXIoLS1iZyk7IGNvbG9yOiB2YXIoLS1mZyk7IGZvbnQtc2l6ZTogMC44MnJlbTtcIj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIiR7IXNjaGVkdWxlVmFsID8gJyBzZWxlY3RlZCcgOiAnJ30+RGlzYWJsZWQ8L29wdGlvbj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJkYWlseVwiJHtzY2hlZHVsZVZhbCA9PT0gJ2RhaWx5JyA/ICcgc2VsZWN0ZWQnIDogJyd9PkRhaWx5PC9vcHRpb24+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwid2Vla2x5XCIke3NjaGVkdWxlVmFsID09PSAnd2Vla2x5JyA/ICcgc2VsZWN0ZWQnIDogJyd9PldlZWtseTwvb3B0aW9uPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIm1vbnRobHlcIiR7c2NoZWR1bGVWYWwgPT09ICdtb250aGx5JyA/ICcgc2VsZWN0ZWQnIDogJyd9Pk1vbnRobHk8L29wdGlvbj5cbiAgICAgICAgICA8L3NlbGVjdD48L3RkPmA7XG4gICAgICAgIGh0bWwgKz0gYDx0ZCBzdHlsZT1cInBhZGRpbmc6IDhweDtcIj48aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImF1dG8td2luZG93XCIgZGF0YS1pZD1cIiR7ZXNjYXBlSHRtbChjaWQpfVwiIHZhbHVlPVwiJHtlc2NhcGVIdG1sKHdpbmRvd1ZhbCl9XCIgcGxhY2Vob2xkZXI9XCIwMjowMC0wNDowMFwiIHN0eWxlPVwid2lkdGg6IDkwcHg7IHBhZGRpbmc6IDNweCA2cHg7IGZvbnQtc2l6ZTogMC43OHJlbTsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgYm9yZGVyLXJhZGl1czogNHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1iZyk7IGNvbG9yOiB2YXIoLS1mZyk7XCIgLz48L3RkPmA7XG4gICAgICAgIGh0bWwgKz0gYDx0ZCBzdHlsZT1cInBhZGRpbmc6IDhweDtcIj48aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJhdXRvLXJvbGxiYWNrXCIgZGF0YS1pZD1cIiR7ZXNjYXBlSHRtbChjaWQpfVwiJHtyb2xsYmFja1ZhbCA/ICcgY2hlY2tlZCcgOiAnJ30gLz48L3RkPmA7XG4gICAgICAgIGh0bWwgKz0gYDx0ZCBzdHlsZT1cInBhZGRpbmc6IDhweDsgZm9udC1zaXplOiAwLjc4cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPiR7bGFzdFJ1bn08L3RkPmA7XG4gICAgICAgIGh0bWwgKz0gYDx0ZCBzdHlsZT1cInBhZGRpbmc6IDhweDsgdGV4dC1hbGlnbjogcmlnaHQ7XCI+PGJ1dHRvbiBjbGFzcz1cInNhdmUtYXV0by1idG5cIiBkYXRhLWlkPVwiJHtlc2NhcGVIdG1sKGNpZCl9XCIgZGF0YS1uYW1lPVwiJHtlc2NhcGVIdG1sKG5hbWUpfVwiIHN0eWxlPVwicGFkZGluZzogNHB4IDEwcHg7IGZvbnQtc2l6ZTogMC43OHJlbTtcIj5TYXZlPC9idXR0b24+PC90ZD5gO1xuICAgICAgICBodG1sICs9ICc8L3RyPic7XG4gICAgICB9XG4gICAgICBodG1sICs9ICc8L3RhYmxlPic7XG4gICAgICBhdXRvQ29udGFpbmVyLmlubmVySFRNTCA9IGh0bWw7XG5cbiAgICAgIC8vIFdpcmUgc2F2ZSBidXR0b25zXG4gICAgICBhdXRvQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoJy5zYXZlLWF1dG8tYnRuJykuZm9yRWFjaChidG4gPT4ge1xuICAgICAgICBidG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgaWQgPSBidG4uZGF0YXNldC5pZDtcbiAgICAgICAgICBjb25zdCByb3cgPSBidG4uY2xvc2VzdCgndHInKTtcbiAgICAgICAgICBjb25zdCBzY2hlZHVsZSA9IHJvdy5xdWVyeVNlbGVjdG9yKCcuYXV0by1zY2hlZHVsZScpLnZhbHVlO1xuICAgICAgICAgIGNvbnN0IHJvbGxiYWNrID0gcm93LnF1ZXJ5U2VsZWN0b3IoJy5hdXRvLXJvbGxiYWNrJykuY2hlY2tlZDtcbiAgICAgICAgICBjb25zdCB3aW5kb3cgPSByb3cucXVlcnlTZWxlY3RvcignLmF1dG8td2luZG93JykudmFsdWUudHJpbSgpO1xuICAgICAgICAgIGJ0bi50ZXh0Q29udGVudCA9ICdTYXZpbmcuLi4nO1xuICAgICAgICAgIGJ0bi5kaXNhYmxlZCA9IHRydWU7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHIgPSBhd2FpdCBzZWN1cmVGZXRjaChgL2FwaS92MS91cGRhdGVzL2F1dG8tdXBkYXRlLyR7ZW5jb2RlVVJJQ29tcG9uZW50KGlkKX1gLCB7XG4gICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoeyBlbmFibGVkOiAhIXNjaGVkdWxlLCBzY2hlZHVsZTogc2NoZWR1bGUgfHwgJ3dlZWtseScsIGF1dG9Sb2xsYmFjazogcm9sbGJhY2ssIG1haW50ZW5hbmNlV2luZG93OiB3aW5kb3cgfHwgdW5kZWZpbmVkIH0pXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGQgPSBhd2FpdCByLmpzb24oKTtcbiAgICAgICAgICAgIGlmIChkLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgYnRuLnRleHRDb250ZW50ID0gJ1x1MjcxMyBTYXZlZCc7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZC5lcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgYnRuLnRleHRDb250ZW50ID0gJ1x1MjcxNyBFcnJvcic7XG4gICAgICAgICAgICBzaG93Tm90aWZpY2F0aW9uKCdTYXZlIGVycm9yOiAnICsgZS5tZXNzYWdlLCAnZXJyb3InKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7IGJ0bi50ZXh0Q29udGVudCA9ICdTYXZlJzsgYnRuLmRpc2FibGVkID0gZmFsc2U7IH0sIDIwMDApO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGF1dG9Db250YWluZXIuaW5uZXJIVE1MID0gYDxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiIHN0eWxlPVwiY29sb3I6IHZhcigtLWJhZC1mZyk7XCI+RmFpbGVkOiAke2VzY2FwZUh0bWwoZS5tZXNzYWdlKX08L2Rpdj5gO1xuICAgIH1cbiAgfVxuXG4gIC8vID09PT09IERBU0hDQUREWSBTRUxGLVVQREFURSA9PT09PVxuXG4gIGNvbnN0IGRjVmVyc2lvbkluZm8gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGFzaGNhZGR5LWN1cnJlbnQtdmVyc2lvbicpO1xuICBjb25zdCBkY1VwZGF0ZUJhZGdlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Rhc2hjYWRkeS11cGRhdGUtYmFkZ2UnKTtcbiAgY29uc3QgZGNVcGRhdGVEZXRhaWxzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Rhc2hjYWRkeS11cGRhdGUtZGV0YWlscycpO1xuICBjb25zdCBkY05ld1ZlcnNpb24gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGFzaGNhZGR5LW5ldy12ZXJzaW9uJyk7XG4gIGNvbnN0IGRjQ2hhbmdlbG9nID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Rhc2hjYWRkeS1jaGFuZ2Vsb2cnKTtcbiAgY29uc3QgZGNBcHBseUJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkYXNoY2FkZHktYXBwbHktYnRuJyk7XG4gIGNvbnN0IGRjQ2hlY2tCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGFzaGNhZGR5LWNoZWNrLWJ0bicpO1xuICBjb25zdCBkY1JvbGxiYWNrQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Rhc2hjYWRkeS1yb2xsYmFjay1idG4nKTtcbiAgY29uc3QgZGNTdGF0dXNCYXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGFzaGNhZGR5LXN0YXR1cy1iYXInKTtcbiAgY29uc3QgZGNIaXN0b3J5Q29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Rhc2hjYWRkeS1oaXN0b3J5LWNvbnRhaW5lcicpO1xuXG4gIGxldCBkY0xhc3RDaGVjayA9IG51bGw7XG5cbiAgZnVuY3Rpb24gZGNTaG93U3RhdHVzKG1zZywgdHlwZSkge1xuICAgIGlmICghZGNTdGF0dXNCYXIpIHJldHVybjtcbiAgICBkY1N0YXR1c0Jhci5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICBkY1N0YXR1c0Jhci5zdHlsZS5iYWNrZ3JvdW5kID0gdHlwZSA9PT0gJ2Vycm9yJyA/ICd2YXIoLS1iYWQtYmcpJyA6IHR5cGUgPT09ICdzdWNjZXNzJyA/ICd2YXIoLS1vay1iZyknIDogJ3ZhcigtLWJnKSc7XG4gICAgZGNTdGF0dXNCYXIuc3R5bGUuY29sb3IgPSB0eXBlID09PSAnZXJyb3InID8gJ3ZhcigtLWJhZC1mZyknIDogdHlwZSA9PT0gJ3N1Y2Nlc3MnID8gJ3ZhcigtLW9rLWZnKScgOiAndmFyKC0tZmcpJztcbiAgICBkY1N0YXR1c0Jhci50ZXh0Q29udGVudCA9IG1zZztcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGRjTG9hZFZlcnNpb24oKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL3N5c3RlbS92ZXJzaW9uJyk7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzLmpzb24oKTtcbiAgICAgIGlmIChkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgY29uc3QgY29tbWl0ID0gZGF0YS5jb21taXQgJiYgZGF0YS5jb21taXQgIT09ICd1bmtub3duJyA/IGRhdGEuY29tbWl0IDogbnVsbDtcbiAgICAgICAgZGNWZXJzaW9uSW5mby50ZXh0Q29udGVudCA9ICd2JyArIGRhdGEudmVyc2lvbiArIChjb21taXQgPyAnICgnICsgY29tbWl0LnN1YnN0cmluZygwLCA3KSArICcpJyA6ICcnKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChfKSB7XG4gICAgICBkY1ZlcnNpb25JbmZvLnRleHRDb250ZW50ID0gJ1VuYWJsZSB0byBmZXRjaCB2ZXJzaW9uJztcbiAgICB9XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBkY0NoZWNrRm9yVXBkYXRlKHNpbGVudCkge1xuICAgIGlmICghc2lsZW50KSB7XG4gICAgICBkY0NoZWNrQnRuLnRleHRDb250ZW50ID0gJ0NoZWNraW5nLi4uJztcbiAgICAgIGRjQ2hlY2tCdG4uZGlzYWJsZWQgPSB0cnVlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2goJy9hcGkvdjEvc3lzdGVtL3VwZGF0ZS1jaGVjaycpO1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlcy5qc29uKCk7XG4gICAgICBkY0xhc3RDaGVjayA9IGRhdGE7XG5cbiAgICAgIGlmIChkYXRhLnN1Y2Nlc3MgJiYgZGF0YS5hdmFpbGFibGUgJiYgZGF0YS5yZW1vdGUpIHtcbiAgICAgICAgZGNVcGRhdGVCYWRnZS5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gICAgICAgIGRjVXBkYXRlRGV0YWlscy5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gICAgICAgIGRjTmV3VmVyc2lvbi50ZXh0Q29udGVudCA9ICd2JyArIGRhdGEucmVtb3RlLnZlcnNpb247XG4gICAgICAgIGRjQ2hhbmdlbG9nLnRleHRDb250ZW50ID0gZGF0YS5yZW1vdGUuY2hhbmdlbG9nIHx8ICdObyBjaGFuZ2Vsb2cgYXZhaWxhYmxlLic7XG5cbiAgICAgICAgLy8gQWRkIG5vdGlmaWNhdGlvbiBkb3QgdG8gdGhlIFVwZGF0ZXMgYnV0dG9uXG4gICAgICAgIGNvbnN0IHVwZGF0ZXNCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndXBkYXRlcy1idG4nKTtcbiAgICAgICAgaWYgKHVwZGF0ZXNCdG4gJiYgIXVwZGF0ZXNCdG4ucXVlcnlTZWxlY3RvcignLnVwZGF0ZS1kb3QnKSkge1xuICAgICAgICAgIGNvbnN0IGRvdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICAgICAgICBkb3QuY2xhc3NOYW1lID0gJ3VwZGF0ZS1kb3QnO1xuICAgICAgICAgIGRvdC5zdHlsZS5jc3NUZXh0ID0gJ3Bvc2l0aW9uOmFic29sdXRlO3RvcDoycHg7cmlnaHQ6MnB4O3dpZHRoOjhweDtoZWlnaHQ6OHB4O2JvcmRlci1yYWRpdXM6NTAlO2JhY2tncm91bmQ6dmFyKC0tYWNjZW50KTsnO1xuICAgICAgICAgIHVwZGF0ZXNCdG4uc3R5bGUucG9zaXRpb24gPSAncmVsYXRpdmUnO1xuICAgICAgICAgIHVwZGF0ZXNCdG4uYXBwZW5kQ2hpbGQoZG90KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBBbHNvIGFkZCBkb3QgdG8gdGhlIERhc2hDYWRkeSB0YWJcbiAgICAgICAgY29uc3QgZGNUYWIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndXBkYXRlcy1kYXNoY2FkZHktdGFiJyk7XG4gICAgICAgIGlmIChkY1RhYiAmJiAhZGNUYWIucXVlcnlTZWxlY3RvcignLnVwZGF0ZS1kb3QnKSkge1xuICAgICAgICAgIGNvbnN0IGRvdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICAgICAgICBkb3QuY2xhc3NOYW1lID0gJ3VwZGF0ZS1kb3QnO1xuICAgICAgICAgIGRvdC5zdHlsZS5jc3NUZXh0ID0gJ2Rpc3BsYXk6aW5saW5lLWJsb2NrO3dpZHRoOjZweDtoZWlnaHQ6NnB4O2JvcmRlci1yYWRpdXM6NTAlO2JhY2tncm91bmQ6dmFyKC0tYWNjZW50KTttYXJnaW4tbGVmdDo0cHg7dmVydGljYWwtYWxpZ246bWlkZGxlOyc7XG4gICAgICAgICAgZGNUYWIuYXBwZW5kQ2hpbGQoZG90KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGNVcGRhdGVCYWRnZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICBkY1VwZGF0ZURldGFpbHMuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgYXdhaXQgZGNMb2FkVmVyc2lvbigpO1xuICAgICAgICBpZiAoIXNpbGVudCkgZGNTaG93U3RhdHVzKCdZb3UgYXJlIHJ1bm5pbmcgdGhlIGxhdGVzdCB2ZXJzaW9uLicsICdzdWNjZXNzJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICghc2lsZW50KSB7XG4gICAgICAgIGRjQ2hlY2tCdG4udGV4dENvbnRlbnQgPSAnQ2hlY2sgZm9yIFVwZGF0ZXMnO1xuICAgICAgICBkY0NoZWNrQnRuLmRpc2FibGVkID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKCFzaWxlbnQpIHtcbiAgICAgICAgZGNTaG93U3RhdHVzKCdGYWlsZWQgdG8gY2hlY2s6ICcgKyBlLm1lc3NhZ2UsICdlcnJvcicpO1xuICAgICAgICBkY0NoZWNrQnRuLnRleHRDb250ZW50ID0gJ0NoZWNrIGZvciBVcGRhdGVzJztcbiAgICAgICAgZGNDaGVja0J0bi5kaXNhYmxlZCA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGRjQXBwbHlVcGRhdGUoKSB7XG4gICAgaWYgKCFjb25maXJtKCdBcHBseSBEYXNoQ2FkZHkgdXBkYXRlPyBUaGUgQVBJIGNvbnRhaW5lciB3aWxsIHJlc3RhcnQuJykpIHJldHVybiBmYWxzZTtcbiAgICBkY0FwcGx5QnRuLnRleHRDb250ZW50ID0gJ1VwZGF0aW5nLi4uJztcbiAgICBkY0FwcGx5QnRuLmRpc2FibGVkID0gdHJ1ZTtcbiAgICBkY1Nob3dTdGF0dXMoJ0Rvd25sb2FkaW5nIGFuZCBhcHBseWluZyB1cGRhdGUuLi4nLCAnaW5mbycpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBzZWN1cmVGZXRjaCgnL2FwaS92MS9zeXN0ZW0vdXBkYXRlLWFwcGx5JywgeyBtZXRob2Q6ICdQT1NUJyB9KTtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXMuanNvbigpO1xuICAgICAgaWYgKGRhdGEuc3VjY2Vzcykge1xuICAgICAgICBkY1Nob3dTdGF0dXMoJ1VwZGF0ZSBpbml0aWF0ZWQ6IHYnICsgKGRhdGEuZnJvbVZlcnNpb24gfHwgJz8nKSArICcgXHUyMTkyIHYnICsgKGRhdGEudG9WZXJzaW9uIHx8ICc/JykgKyAnLiBUaGUgY29udGFpbmVyIHdpbGwgcmVzdGFydCBzaG9ydGx5LicsICdzdWNjZXNzJyk7XG4gICAgICAgIGRjQXBwbHlCdG4udGV4dENvbnRlbnQgPSAnQXBwbGllZCEnO1xuICAgICAgICAvLyBSZW1vdmUgbm90aWZpY2F0aW9uIGRvdHNcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnVwZGF0ZS1kb3QnKS5mb3JFYWNoKGQgPT4gZC5yZW1vdmUoKSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGRhdGEuZXJyb3IgfHwgJ1VwZGF0ZSBmYWlsZWQnKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBkY1Nob3dTdGF0dXMoJ1VwZGF0ZSBmYWlsZWQ6ICcgKyBlLm1lc3NhZ2UsICdlcnJvcicpO1xuICAgICAgZGNBcHBseUJ0bi50ZXh0Q29udGVudCA9ICdVcGRhdGUgTm93JztcbiAgICAgIGRjQXBwbHlCdG4uZGlzYWJsZWQgPSBmYWxzZTtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gZGNMb2FkSGlzdG9yeSgpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2goJy9hcGkvdjEvc3lzdGVtL3VwZGF0ZS1oaXN0b3J5Jyk7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzLmpzb24oKTtcbiAgICAgIGNvbnN0IGhpc3RvcnkgPSBkYXRhLnN1Y2Nlc3MgJiYgZGF0YS5oaXN0b3J5ID8gZGF0YS5oaXN0b3J5IDogW107XG4gICAgICBpZiAoaGlzdG9yeS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgZGNIaXN0b3J5Q29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj48c3BhbiBjbGFzcz1cImVtcHR5LWljb25cIj5cdUQ4M0RcdURDRTY8L3NwYW4+Tm8gc2VsZi11cGRhdGUgaGlzdG9yeS48L2Rpdj4nO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBsZXQgaHRtbCA9ICc8dGFibGUgc3R5bGU9XCJ3aWR0aDogMTAwJTsgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsgZm9udC1zaXplOiAwLjgycmVtO1wiPic7XG4gICAgICBodG1sICs9ICc8dHIgc3R5bGU9XCJib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgY29sb3I6IHZhcigtLW11dGVkKTtcIj48dGggc3R5bGU9XCJwYWRkaW5nOiA2cHg7IHRleHQtYWxpZ246IGxlZnQ7XCI+V2hlbjwvdGg+PHRoIHN0eWxlPVwicGFkZGluZzogNnB4OyB0ZXh0LWFsaWduOiBsZWZ0O1wiPlZlcnNpb248L3RoPjx0aCBzdHlsZT1cInBhZGRpbmc6IDZweDsgdGV4dC1hbGlnbjogbGVmdDtcIj5Gcm9tPC90aD48dGggc3R5bGU9XCJwYWRkaW5nOiA2cHg7IHRleHQtYWxpZ246IGxlZnQ7XCI+U3RhdHVzPC90aD48L3RyPic7XG4gICAgICBmb3IgKGNvbnN0IGggb2YgaGlzdG9yeSkge1xuICAgICAgICBjb25zdCBzdCA9IGguc3RhdHVzID09PSAnc3VjY2VzcycgPyAnXHUyNzEzIHN1Y2Nlc3MnIDogaC5zdGF0dXMgPT09ICdwZW5kaW5nJyA/ICdcdTIzRjMgcGVuZGluZycgOiBoLnN0YXR1cyA9PT0gJ3BhcnRpYWwnID8gJ1x1MjZBMCBwYXJ0aWFsJyA6ICdcdTI3MTcgJyArIGguc3RhdHVzO1xuICAgICAgICBjb25zdCBzdENvbG9yID0gaC5zdGF0dXMgPT09ICdzdWNjZXNzJyA/ICd2YXIoLS1vay1mZyknIDogaC5zdGF0dXMgPT09ICdwZW5kaW5nJyA/ICd2YXIoLS1tdXRlZCknIDogJ3ZhcigtLWJhZC1mZyknO1xuICAgICAgICBodG1sICs9ICc8dHIgc3R5bGU9XCJib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcIj4nO1xuICAgICAgICBodG1sICs9ICc8dGQgc3R5bGU9XCJwYWRkaW5nOiA2cHg7IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+JyArIHRpbWVBZ28oaC50aW1lc3RhbXApICsgJzwvdGQ+JztcbiAgICAgICAgaHRtbCArPSAnPHRkIHN0eWxlPVwicGFkZGluZzogNnB4OyBmb250LXdlaWdodDogNTAwO1wiPnYnICsgZXNjYXBlSHRtbChoLnZlcnNpb24pICsgKGgucm9sbGJhY2sgPyAnIChyb2xsYmFjayknIDogJycpICsgJzwvdGQ+JztcbiAgICAgICAgaHRtbCArPSAnPHRkIHN0eWxlPVwicGFkZGluZzogNnB4OyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPnYnICsgZXNjYXBlSHRtbChoLmZyb21WZXJzaW9uIHx8ICc/JykgKyAnPC90ZD4nO1xuICAgICAgICBodG1sICs9ICc8dGQgc3R5bGU9XCJwYWRkaW5nOiA2cHg7XCI+PHNwYW4gc3R5bGU9XCJjb2xvcjogJyArIHN0Q29sb3IgKyAnO1wiPicgKyBzdCArICc8L3NwYW4+PC90ZD4nO1xuICAgICAgICBodG1sICs9ICc8L3RyPic7XG4gICAgICAgIGlmIChoLmVycm9yKSB7XG4gICAgICAgICAgaHRtbCArPSAnPHRyPjx0ZCBjb2xzcGFuPVwiNFwiIHN0eWxlPVwicGFkZGluZzogNHB4IDZweCA4cHg7IGZvbnQtc2l6ZTogMC43OHJlbTsgY29sb3I6IHZhcigtLWJhZC1mZyk7XCI+JyArIGVzY2FwZUh0bWwoaC5lcnJvcikgKyAnPC90ZD48L3RyPic7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGgubm90ZSkge1xuICAgICAgICAgIGh0bWwgKz0gJzx0cj48dGQgY29sc3Bhbj1cIjRcIiBzdHlsZT1cInBhZGRpbmc6IDRweCA2cHggOHB4OyBmb250LXNpemU6IDAuNzhyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+JyArIGVzY2FwZUh0bWwoaC5ub3RlKSArICc8L3RkPjwvdHI+JztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaHRtbCArPSAnPC90YWJsZT4nO1xuICAgICAgZGNIaXN0b3J5Q29udGFpbmVyLmlubmVySFRNTCA9IGh0bWw7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgZGNIaXN0b3J5Q29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIiBzdHlsZT1cImNvbG9yOiB2YXIoLS1iYWQtZmcpO1wiPkZhaWxlZDogJyArIGVzY2FwZUh0bWwoZS5tZXNzYWdlKSArICc8L2Rpdj4nO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGRjU2hvd1JvbGxiYWNrKCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS9zeXN0ZW0vcm9sbGJhY2stdmVyc2lvbnMnKTtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXMuanNvbigpO1xuICAgICAgY29uc3QgdmVyc2lvbnMgPSBkYXRhLnN1Y2Nlc3MgJiYgZGF0YS52ZXJzaW9ucyA/IGRhdGEudmVyc2lvbnMgOiBbXTtcbiAgICAgIGlmICh2ZXJzaW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgc2hvd05vdGlmaWNhdGlvbignTm8gcm9sbGJhY2sgdmVyc2lvbnMgYXZhaWxhYmxlLicsICdpbmZvJyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHZlcnNpb24gPSBwcm9tcHQoJ0F2YWlsYWJsZSByb2xsYmFjayB2ZXJzaW9uczpcXG4nICsgdmVyc2lvbnMuam9pbignXFxuJykgKyAnXFxuXFxuRW50ZXIgdmVyc2lvbiB0byByb2xsYmFjayB0bzonKTtcbiAgICAgIGlmICghdmVyc2lvbikgcmV0dXJuO1xuICAgICAgaWYgKCF2ZXJzaW9ucy5pbmNsdWRlcyh2ZXJzaW9uKSkge1xuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKCdJbnZhbGlkIHZlcnNpb246ICcgKyB2ZXJzaW9uLCAnZXJyb3InKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKCFjb25maXJtKCdSb2xsYmFjayBEYXNoQ2FkZHkgdG8gdicgKyB2ZXJzaW9uICsgJz8gVGhlIGNvbnRhaW5lciB3aWxsIHJlc3RhcnQuJykpIHJldHVybjtcbiAgICAgIGRjU2hvd1N0YXR1cygnUm9sbGluZyBiYWNrIHRvIHYnICsgdmVyc2lvbiArICcuLi4nLCAnaW5mbycpO1xuICAgICAgY29uc3QgciA9IGF3YWl0IHNlY3VyZUZldGNoKCcvYXBpL3YxL3N5c3RlbS9yb2xsYmFjaycsIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7IHZlcnNpb24gfSlcbiAgICAgIH0pO1xuICAgICAgY29uc3QgZCA9IGF3YWl0IHIuanNvbigpO1xuICAgICAgaWYgKGQuc3VjY2Vzcykge1xuICAgICAgICBkY1Nob3dTdGF0dXMoJ1JvbGxiYWNrIHRvIHYnICsgdmVyc2lvbiArICcgaW5pdGlhdGVkLiBDb250YWluZXIgd2lsbCByZXN0YXJ0LicsICdzdWNjZXNzJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZC5lcnJvciB8fCAnUm9sbGJhY2sgZmFpbGVkJyk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgZGNTaG93U3RhdHVzKCdSb2xsYmFjayBmYWlsZWQ6ICcgKyBlLm1lc3NhZ2UsICdlcnJvcicpO1xuICAgIH1cbiAgfVxuXG4gIGRjQ2hlY2tCdG4/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4gZGNDaGVja0ZvclVwZGF0ZShmYWxzZSkpO1xuICBkY0FwcGx5QnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IGRjQXBwbHlVcGRhdGUoKS5jYXRjaCgoKSA9PiB7fSkpO1xuICBkY1JvbGxiYWNrQnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGRjU2hvd1JvbGxiYWNrKTtcblxuICBjaGVja0J0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBjaGVja0ZvclVwZGF0ZXMpO1xuICBvcGVuQnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICBtb2RhbD8uY2xhc3NMaXN0LmFkZCgnc2hvdycpO1xuICAgIGxvYWRBdmFpbGFibGUoKTtcbiAgfSk7XG4gIHdpcmVNb2RhbChtb2RhbCwgY2FuY2VsQnRuKTtcblxuICAvLyBPcGVuIFVwZGF0ZSBNYW5hZ2VtZW50IG1vZGFsLCBvcHRpb25hbGx5IHNjcm9sbGVkIHRvIGEgc3BlY2lmaWMgYXBwXG4gIHdpbmRvdy5vcGVuVXBkYXRlTW9kYWwgPSBmdW5jdGlvbihhcHBJZCkge1xuICAgIG1vZGFsPy5jbGFzc0xpc3QuYWRkKCdzaG93Jyk7XG4gICAgbG9hZEF2YWlsYWJsZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgaWYgKCFhcHBJZCkgcmV0dXJuO1xuICAgICAgLy8gU2Nyb2xsIHRvIGFuZCBoaWdobGlnaHQgdGhlIG1hdGNoaW5nIHJvd1xuICAgICAgY29uc3Qgcm93ID0gYXZhaWxhYmxlQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoYFtkYXRhLWFwcC1pZD1cIiR7YXBwSWR9XCJdYCk7XG4gICAgICBpZiAocm93KSB7XG4gICAgICAgIHJvdy5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiAnc21vb3RoJywgYmxvY2s6ICdjZW50ZXInIH0pO1xuICAgICAgICByb3cuc3R5bGUuYmFja2dyb3VuZCA9ICdyZ2JhKDI0OSwxMTUsMjIsMC4xNSknO1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHsgcm93LnN0eWxlLmJhY2tncm91bmQgPSAnJzsgfSwgMzAwMCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG5cbiAgLy8gTGF6eS1sb2FkIHRhYnNcbiAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW2RhdGEtcGFuZWw9XCJ1cGRhdGVzLWhpc3RvcnlcIl0nKT8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBsb2FkSGlzdG9yeSk7XG4gIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLXBhbmVsPVwidXBkYXRlcy1hdXRvXCJdJyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgbG9hZEF1dG9Db25maWcpO1xuICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1wYW5lbD1cInVwZGF0ZXMtZGFzaGNhZGR5XCJdJyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgIGRjTG9hZFZlcnNpb24oKTtcbiAgICBkY0xvYWRIaXN0b3J5KCk7XG4gICAgaWYgKCFkY0xhc3RDaGVjaykgZGNDaGVja0ZvclVwZGF0ZSh0cnVlKTtcbiAgfSk7XG5cbiAgd2luZG93LmRjQXBwbHlVcGRhdGUgPSBkY0FwcGx5VXBkYXRlO1xuICB3aW5kb3cuZGNDaGVja0ZvclVwZGF0ZSA9IGRjQ2hlY2tGb3JVcGRhdGU7XG5cbiAgLy8gTm9uLWJsb2NraW5nIGNoZWNrIG9uIHBhZ2UgbG9hZCBcdTIwMTQganVzdCBhZGRzIG5vdGlmaWNhdGlvbiBkb3QgaWYgdXBkYXRlIGF2YWlsYWJsZVxuICBzZXRUaW1lb3V0KCgpID0+IGRjQ2hlY2tGb3JVcGRhdGUodHJ1ZSksIDUwMDApO1xufSkoKTtcbjtcbi8vID09PT09PT09PT0gRE9DS0VSIFJFU09VUkNFUyAoVm9sdW1lcywgTmV0d29ya3MsIERpc2sgVXNhZ2UpID09PT09PT09PT1cbihmdW5jdGlvbigpIHtcbiAgaW5qZWN0TW9kYWwoJ2RvY2tlci1yZXNvdXJjZXMtbW9kYWwnLCBgPGRpdiBpZD1cImRvY2tlci1yZXNvdXJjZXMtbW9kYWxcIiBjbGFzcz1cIndlYXRoZXItbW9kYWxcIj5cbiAgICA8ZGl2IGNsYXNzPVwid2VhdGhlci1tb2RhbC1jb250ZW50XCIgc3R5bGU9XCJtaW4td2lkdGg6IDc1MHB4OyBtYXgtd2lkdGg6IDk1MHB4O1wiPlxuICAgICAgPGgzPlx1RDgzRFx1REMzMyBEb2NrZXIgUmVzb3VyY2VzPC9oMz5cbiAgICAgIDxwIGNsYXNzPVwibW9kYWwtc3VidGl0bGVcIj5NYW5hZ2Ugdm9sdW1lcywgbmV0d29ya3MsIGFuZCB2aWV3IGRpc2sgdXNhZ2UuPC9wPlxuXG4gICAgICA8ZGl2IGNsYXNzPVwicGFuZWwtdGFic1wiPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwicGFuZWwtdGFiIGFjdGl2ZVwiIGRhdGEtcGFuZWw9XCJkci12b2x1bWVzXCI+Vm9sdW1lczwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwicGFuZWwtdGFiXCIgZGF0YS1wYW5lbD1cImRyLW5ldHdvcmtzXCI+TmV0d29ya3M8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInBhbmVsLXRhYlwiIGRhdGEtcGFuZWw9XCJkci1kaXNrXCI+RGlzayBVc2FnZTwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gVm9sdW1lcyAtLT5cbiAgICAgIDxkaXYgaWQ9XCJkci12b2x1bWVzXCIgY2xhc3M9XCJwYW5lbC1zZWN0aW9uIGFjdGl2ZVwiPlxuICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgZ2FwOiA4cHg7IG1hcmdpbi1ib3R0b206IDEycHg7XCI+XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgaWQ9XCJkci12b2wtbmFtZVwiIHBsYWNlaG9sZGVyPVwiVm9sdW1lIG5hbWVcIiBzdHlsZT1cImZsZXg6IDE7IHBhZGRpbmc6IDZweCAxMHB4OyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBib3JkZXItcmFkaXVzOiA2cHg7IGJhY2tncm91bmQ6IHZhcigtLWJnKTsgY29sb3I6IHZhcigtLWZnKTtcIiAvPlxuICAgICAgICAgIDxidXR0b24gaWQ9XCJkci12b2wtY3JlYXRlXCIgY2xhc3M9XCJidG4tYWNjZW50LXNvbGlkXCIgc3R5bGU9XCJwYWRkaW5nOiA2cHggMTRweDsgZm9udC1zaXplOiAwLjgycmVtO1wiPkNyZWF0ZTwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBpZD1cImRyLXZvbC1saXN0XCIgY2xhc3M9XCJzY3JvbGwtY29udGFpbmVyXCIgc3R5bGU9XCJtYXgtaGVpZ2h0OiA0MDBweDtcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj48c3BhbiBjbGFzcz1cImJyYW5kLXNwaW5uZXJcIj48L3NwYW4+IExvYWRpbmcuLi48L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBOZXR3b3JrcyAtLT5cbiAgICAgIDxkaXYgaWQ9XCJkci1uZXR3b3Jrc1wiIGNsYXNzPVwicGFuZWwtc2VjdGlvblwiPlxuICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgZ2FwOiA4cHg7IG1hcmdpbi1ib3R0b206IDEycHg7XCI+XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgaWQ9XCJkci1uZXQtbmFtZVwiIHBsYWNlaG9sZGVyPVwiTmV0d29yayBuYW1lXCIgc3R5bGU9XCJmbGV4OiAxOyBwYWRkaW5nOiA2cHggMTBweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgYm9yZGVyLXJhZGl1czogNnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1iZyk7IGNvbG9yOiB2YXIoLS1mZyk7XCIgLz5cbiAgICAgICAgICA8c2VsZWN0IGlkPVwiZHItbmV0LWRyaXZlclwiIHN0eWxlPVwicGFkZGluZzogNnB4IDEwcHg7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJvcmRlci1yYWRpdXM6IDZweDsgYmFja2dyb3VuZDogdmFyKC0tYmcpOyBjb2xvcjogdmFyKC0tZmcpO1wiPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cImJyaWRnZVwiPmJyaWRnZTwvb3B0aW9uPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIm92ZXJsYXlcIj5vdmVybGF5PC9vcHRpb24+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiaG9zdFwiPmhvc3Q8L29wdGlvbj5cbiAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICA8YnV0dG9uIGlkPVwiZHItbmV0LWNyZWF0ZVwiIGNsYXNzPVwiYnRuLWFjY2VudC1zb2xpZFwiIHN0eWxlPVwicGFkZGluZzogNnB4IDE0cHg7IGZvbnQtc2l6ZTogMC44MnJlbTtcIj5DcmVhdGU8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgaWQ9XCJkci1uZXQtbGlzdFwiIGNsYXNzPVwic2Nyb2xsLWNvbnRhaW5lclwiIHN0eWxlPVwibWF4LWhlaWdodDogNDAwcHg7XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+PHNwYW4gY2xhc3M9XCJicmFuZC1zcGlubmVyXCI+PC9zcGFuPiBMb2FkaW5nLi4uPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gRGlzayBVc2FnZSAtLT5cbiAgICAgIDxkaXYgaWQ9XCJkci1kaXNrXCIgY2xhc3M9XCJwYW5lbC1zZWN0aW9uXCI+XG4gICAgICAgIDxkaXYgaWQ9XCJkci1kaXNrLWNvbnRlbnRcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj48c3BhbiBjbGFzcz1cImJyYW5kLXNwaW5uZXJcIj48L3NwYW4+IExvYWRpbmcuLi48L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzcz1cIndlYXRoZXItbW9kYWwtYnV0dG9ucyBtb2RhbC1mb290ZXItYmFyXCI+XG4gICAgICAgIDxidXR0b24gaWQ9XCJkci1jbG9zZVwiPkNsb3NlPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+YCk7XG5cbiAgY29uc3QgbW9kYWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZG9ja2VyLXJlc291cmNlcy1tb2RhbCcpO1xuICBjb25zdCBvcGVuQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RvY2tlci1yZXNvdXJjZXMtYnRuJyk7XG4gIGNvbnN0IGNsb3NlQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RyLWNsb3NlJyk7XG5cbiAgZnVuY3Rpb24gZm10Qnl0ZXMoYnl0ZXMpIHtcbiAgICBpZiAoIWJ5dGVzIHx8IGJ5dGVzID09PSAwKSByZXR1cm4gJzAgQic7XG4gICAgY29uc3QgdW5pdHMgPSBbJ0InLCAnS0InLCAnTUInLCAnR0InLCAnVEInXTtcbiAgICBjb25zdCBpID0gTWF0aC5mbG9vcihNYXRoLmxvZyhNYXRoLmFicyhieXRlcykpIC8gTWF0aC5sb2coMTAyNCkpO1xuICAgIHJldHVybiAoYnl0ZXMgLyBNYXRoLnBvdygxMDI0LCBpKSkudG9GaXhlZCgxKSArICcgJyArIHVuaXRzW2ldO1xuICB9XG5cbiAgLy8gPT09PT0gVk9MVU1FUyA9PT09PVxuICBhc3luYyBmdW5jdGlvbiBsb2FkVm9sdW1lcygpIHtcbiAgICBjb25zdCBjb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZHItdm9sLWxpc3QnKTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IGdldEpTT04oJy9hcGkvdjEvZG9ja2VyL3ZvbHVtZXMnKTtcbiAgICAgIGNvbnN0IHZvbHMgPSBkYXRhLnZvbHVtZXMgfHwgW107XG4gICAgICBpZiAodm9scy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgY29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj48c3BhbiBjbGFzcz1cImVtcHR5LWljb25cIj5cdUQ4M0RcdURDRTY8L3NwYW4+Tm8gdm9sdW1lcyBmb3VuZC48L2Rpdj4nO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBsZXQgaHRtbCA9ICc8dGFibGUgc3R5bGU9XCJ3aWR0aDogMTAwJTsgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsgZm9udC1zaXplOiAwLjgycmVtO1wiPic7XG4gICAgICBodG1sICs9ICc8dHIgc3R5bGU9XCJib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgY29sb3I6IHZhcigtLW11dGVkKTtcIj48dGggc3R5bGU9XCJwYWRkaW5nOiA2cHg7IHRleHQtYWxpZ246IGxlZnQ7XCI+TmFtZTwvdGg+PHRoIHN0eWxlPVwicGFkZGluZzogNnB4O1wiPkRyaXZlcjwvdGg+PHRoIHN0eWxlPVwicGFkZGluZzogNnB4O1wiPlNjb3BlPC90aD48dGggc3R5bGU9XCJwYWRkaW5nOiA2cHg7IHRleHQtYWxpZ246IHJpZ2h0O1wiPkFjdGlvbnM8L3RoPjwvdHI+JztcbiAgICAgIGZvciAoY29uc3QgdiBvZiB2b2xzKSB7XG4gICAgICAgIGNvbnN0IGlzU3lzdGVtID0gdi5uYW1lID09PSAnYnVpbGRraXQnIHx8IHYubmFtZS5sZW5ndGggPT09IDY0O1xuICAgICAgICBodG1sICs9IGA8dHIgc3R5bGU9XCJib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcIj5gO1xuICAgICAgICBodG1sICs9IGA8dGQgc3R5bGU9XCJwYWRkaW5nOiA2cHg7IGZvbnQtd2VpZ2h0OiA1MDA7IG1heC13aWR0aDogMzAwcHg7IG92ZXJmbG93OiBoaWRkZW47IHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzOyB3aGl0ZS1zcGFjZTogbm93cmFwO1wiIHRpdGxlPVwiJHtlc2NhcGVIdG1sKHYubmFtZSl9XCI+JHtlc2NhcGVIdG1sKHYubmFtZS5sZW5ndGggPiA0MCA/IHYubmFtZS5zdWJzdHJpbmcoMCwgMzcpICsgJy4uLicgOiB2Lm5hbWUpfTwvdGQ+YDtcbiAgICAgICAgaHRtbCArPSBgPHRkIHN0eWxlPVwicGFkZGluZzogNnB4OyB0ZXh0LWFsaWduOiBjZW50ZXI7IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+JHtlc2NhcGVIdG1sKHYuZHJpdmVyKX08L3RkPmA7XG4gICAgICAgIGh0bWwgKz0gYDx0ZCBzdHlsZT1cInBhZGRpbmc6IDZweDsgdGV4dC1hbGlnbjogY2VudGVyOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPiR7ZXNjYXBlSHRtbCh2LnNjb3BlKX08L3RkPmA7XG4gICAgICAgIGh0bWwgKz0gYDx0ZCBzdHlsZT1cInBhZGRpbmc6IDZweDsgdGV4dC1hbGlnbjogcmlnaHQ7XCI+YDtcbiAgICAgICAgaWYgKCFpc1N5c3RlbSkge1xuICAgICAgICAgIGh0bWwgKz0gYDxidXR0b24gY2xhc3M9XCJkci12b2wtZGVsXCIgZGF0YS1uYW1lPVwiJHtlc2NhcGVIdG1sKHYubmFtZSl9XCIgc3R5bGU9XCJwYWRkaW5nOiAzcHggOHB4OyBmb250LXNpemU6IDAuNzVyZW07IGNvbG9yOiB2YXIoLS1iYWQtZmcpO1wiPkRlbGV0ZTwvYnV0dG9uPmA7XG4gICAgICAgIH1cbiAgICAgICAgaHRtbCArPSBgPC90ZD48L3RyPmA7XG4gICAgICB9XG4gICAgICBodG1sICs9ICc8L3RhYmxlPic7XG4gICAgICBjb250YWluZXIuaW5uZXJIVE1MID0gaHRtbDtcblxuICAgICAgY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoJy5kci12b2wtZGVsJykuZm9yRWFjaChidG4gPT4ge1xuICAgICAgICBidG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgaWYgKCFjb25maXJtKGBEZWxldGUgdm9sdW1lIFwiJHtidG4uZGF0YXNldC5uYW1lfVwiPyBEYXRhIHdpbGwgYmUgbG9zdC5gKSkgcmV0dXJuO1xuICAgICAgICAgIGJ0bi50ZXh0Q29udGVudCA9ICcuLi4nO1xuICAgICAgICAgIGJ0bi5kaXNhYmxlZCA9IHRydWU7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IGRlbGV0ZUFQSShgL2FwaS92MS9kb2NrZXIvdm9sdW1lcy8ke2VuY29kZVVSSUNvbXBvbmVudChidG4uZGF0YXNldC5uYW1lKX0/Zm9yY2U9dHJ1ZWApO1xuICAgICAgICAgICAgbG9hZFZvbHVtZXMoKTtcbiAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBzaG93Tm90aWZpY2F0aW9uKCdEZWxldGUgZmFpbGVkOiAnICsgZS5tZXNzYWdlLCAnZXJyb3InKTtcbiAgICAgICAgICAgIGJ0bi50ZXh0Q29udGVudCA9ICdEZWxldGUnO1xuICAgICAgICAgICAgYnRuLmRpc2FibGVkID0gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnRhaW5lci5pbm5lckhUTUwgPSBgPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCIgc3R5bGU9XCJjb2xvcjogdmFyKC0tYmFkLWZnKTtcIj5GYWlsZWQ6ICR7ZXNjYXBlSHRtbChlLm1lc3NhZ2UpfTwvZGl2PmA7XG4gICAgfVxuICB9XG5cbiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RyLXZvbC1jcmVhdGUnKT8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbmFtZUlucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RyLXZvbC1uYW1lJyk7XG4gICAgY29uc3QgbmFtZSA9IG5hbWVJbnB1dC52YWx1ZS50cmltKCk7XG4gICAgaWYgKCFuYW1lKSB7IHNob3dOb3RpZmljYXRpb24oJ0VudGVyIGEgdm9sdW1lIG5hbWUnLCAnd2FybmluZycpOyByZXR1cm47IH1cbiAgICB0cnkge1xuICAgICAgYXdhaXQgcG9zdEpTT04oJy9hcGkvdjEvZG9ja2VyL3ZvbHVtZXMnLCB7IG5hbWUgfSk7XG4gICAgICBuYW1lSW5wdXQudmFsdWUgPSAnJztcbiAgICAgIHNob3dOb3RpZmljYXRpb24oYFZvbHVtZSBcIiR7bmFtZX1cIiBjcmVhdGVkYCwgJ3N1Y2Nlc3MnKTtcbiAgICAgIGxvYWRWb2x1bWVzKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgc2hvd05vdGlmaWNhdGlvbignQ3JlYXRlIGZhaWxlZDogJyArIGUubWVzc2FnZSwgJ2Vycm9yJyk7XG4gICAgfVxuICB9KTtcblxuICAvLyA9PT09PSBORVRXT1JLUyA9PT09PVxuICBhc3luYyBmdW5jdGlvbiBsb2FkTmV0d29ya3MoKSB7XG4gICAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RyLW5ldC1saXN0Jyk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBnZXRKU09OKCcvYXBpL3YxL2RvY2tlci9uZXR3b3JrcycpO1xuICAgICAgY29uc3QgbmV0cyA9IGRhdGEubmV0d29ya3MgfHwgW107XG4gICAgICBpZiAobmV0cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgY29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj48c3BhbiBjbGFzcz1cImVtcHR5LWljb25cIj5cdUQ4M0NcdURGMTA8L3NwYW4+Tm8gbmV0d29ya3MgZm91bmQuPC9kaXY+JztcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgbGV0IGh0bWwgPSAnPHRhYmxlIHN0eWxlPVwid2lkdGg6IDEwMCU7IGJvcmRlci1jb2xsYXBzZTogY29sbGFwc2U7IGZvbnQtc2l6ZTogMC44MnJlbTtcIj4nO1xuICAgICAgaHRtbCArPSAnPHRyIHN0eWxlPVwiYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+PHRoIHN0eWxlPVwicGFkZGluZzogNnB4OyB0ZXh0LWFsaWduOiBsZWZ0O1wiPk5hbWU8L3RoPjx0aCBzdHlsZT1cInBhZGRpbmc6IDZweDtcIj5Ecml2ZXI8L3RoPjx0aCBzdHlsZT1cInBhZGRpbmc6IDZweDtcIj5TY29wZTwvdGg+PHRoIHN0eWxlPVwicGFkZGluZzogNnB4O1wiPkNvbnRhaW5lcnM8L3RoPjx0aCBzdHlsZT1cInBhZGRpbmc6IDZweDsgdGV4dC1hbGlnbjogcmlnaHQ7XCI+QWN0aW9uczwvdGg+PC90cj4nO1xuICAgICAgZm9yIChjb25zdCBuIG9mIG5ldHMpIHtcbiAgICAgICAgY29uc3QgaXNTeXN0ZW0gPSBbJ2JyaWRnZScsICdob3N0JywgJ25vbmUnXS5pbmNsdWRlcyhuLm5hbWUpO1xuICAgICAgICBodG1sICs9IGA8dHIgc3R5bGU9XCJib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcIj5gO1xuICAgICAgICBodG1sICs9IGA8dGQgc3R5bGU9XCJwYWRkaW5nOiA2cHg7IGZvbnQtd2VpZ2h0OiA1MDA7XCI+JHtlc2NhcGVIdG1sKG4ubmFtZSl9PC90ZD5gO1xuICAgICAgICBodG1sICs9IGA8dGQgc3R5bGU9XCJwYWRkaW5nOiA2cHg7IHRleHQtYWxpZ246IGNlbnRlcjsgY29sb3I6IHZhcigtLW11dGVkKTtcIj4ke2VzY2FwZUh0bWwobi5kcml2ZXIpfTwvdGQ+YDtcbiAgICAgICAgaHRtbCArPSBgPHRkIHN0eWxlPVwicGFkZGluZzogNnB4OyB0ZXh0LWFsaWduOiBjZW50ZXI7IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+JHtlc2NhcGVIdG1sKG4uc2NvcGUpfTwvdGQ+YDtcbiAgICAgICAgaHRtbCArPSBgPHRkIHN0eWxlPVwicGFkZGluZzogNnB4OyB0ZXh0LWFsaWduOiBjZW50ZXI7XCI+JHtuLmNvbnRhaW5lcnN9PC90ZD5gO1xuICAgICAgICBodG1sICs9IGA8dGQgc3R5bGU9XCJwYWRkaW5nOiA2cHg7IHRleHQtYWxpZ246IHJpZ2h0O1wiPmA7XG4gICAgICAgIGlmICghaXNTeXN0ZW0pIHtcbiAgICAgICAgICBodG1sICs9IGA8YnV0dG9uIGNsYXNzPVwiZHItbmV0LWRlbFwiIGRhdGEtaWQ9XCIke2VzY2FwZUh0bWwobi5pZCl9XCIgZGF0YS1uYW1lPVwiJHtlc2NhcGVIdG1sKG4ubmFtZSl9XCIgc3R5bGU9XCJwYWRkaW5nOiAzcHggOHB4OyBmb250LXNpemU6IDAuNzVyZW07IGNvbG9yOiB2YXIoLS1iYWQtZmcpO1wiPkRlbGV0ZTwvYnV0dG9uPmA7XG4gICAgICAgIH1cbiAgICAgICAgaHRtbCArPSBgPC90ZD48L3RyPmA7XG4gICAgICB9XG4gICAgICBodG1sICs9ICc8L3RhYmxlPic7XG4gICAgICBjb250YWluZXIuaW5uZXJIVE1MID0gaHRtbDtcblxuICAgICAgY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoJy5kci1uZXQtZGVsJykuZm9yRWFjaChidG4gPT4ge1xuICAgICAgICBidG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgaWYgKCFjb25maXJtKGBEZWxldGUgbmV0d29yayBcIiR7YnRuLmRhdGFzZXQubmFtZX1cIj9gKSkgcmV0dXJuO1xuICAgICAgICAgIGJ0bi50ZXh0Q29udGVudCA9ICcuLi4nO1xuICAgICAgICAgIGJ0bi5kaXNhYmxlZCA9IHRydWU7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IGRlbGV0ZUFQSShgL2FwaS92MS9kb2NrZXIvbmV0d29ya3MvJHtlbmNvZGVVUklDb21wb25lbnQoYnRuLmRhdGFzZXQuaWQpfWApO1xuICAgICAgICAgICAgbG9hZE5ldHdvcmtzKCk7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgc2hvd05vdGlmaWNhdGlvbignRGVsZXRlIGZhaWxlZDogJyArIGUubWVzc2FnZSwgJ2Vycm9yJyk7XG4gICAgICAgICAgICBidG4udGV4dENvbnRlbnQgPSAnRGVsZXRlJztcbiAgICAgICAgICAgIGJ0bi5kaXNhYmxlZCA9IGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb250YWluZXIuaW5uZXJIVE1MID0gYDxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiIHN0eWxlPVwiY29sb3I6IHZhcigtLWJhZC1mZyk7XCI+RmFpbGVkOiAke2VzY2FwZUh0bWwoZS5tZXNzYWdlKX08L2Rpdj5gO1xuICAgIH1cbiAgfVxuXG4gIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkci1uZXQtY3JlYXRlJyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IG5hbWVJbnB1dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkci1uZXQtbmFtZScpO1xuICAgIGNvbnN0IGRyaXZlclNlbGVjdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkci1uZXQtZHJpdmVyJyk7XG4gICAgY29uc3QgbmFtZSA9IG5hbWVJbnB1dC52YWx1ZS50cmltKCk7XG4gICAgaWYgKCFuYW1lKSB7IHNob3dOb3RpZmljYXRpb24oJ0VudGVyIGEgbmV0d29yayBuYW1lJywgJ3dhcm5pbmcnKTsgcmV0dXJuOyB9XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHBvc3RKU09OKCcvYXBpL3YxL2RvY2tlci9uZXR3b3JrcycsIHsgbmFtZSwgZHJpdmVyOiBkcml2ZXJTZWxlY3QudmFsdWUgfSk7XG4gICAgICBuYW1lSW5wdXQudmFsdWUgPSAnJztcbiAgICAgIHNob3dOb3RpZmljYXRpb24oYE5ldHdvcmsgXCIke25hbWV9XCIgY3JlYXRlZGAsICdzdWNjZXNzJyk7XG4gICAgICBsb2FkTmV0d29ya3MoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBzaG93Tm90aWZpY2F0aW9uKCdDcmVhdGUgZmFpbGVkOiAnICsgZS5tZXNzYWdlLCAnZXJyb3InKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vID09PT09IERJU0sgVVNBR0UgPT09PT1cbiAgYXN5bmMgZnVuY3Rpb24gbG9hZERpc2tVc2FnZSgpIHtcbiAgICBjb25zdCBjb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZHItZGlzay1jb250ZW50Jyk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBnZXRKU09OKCcvYXBpL3YxL2RvY2tlci9kaXNrLXVzYWdlJyk7XG4gICAgICBjb25zdCBzZWN0aW9ucyA9IFtcbiAgICAgICAgeyBsYWJlbDogJ0ltYWdlcycsIGljb246ICdcdUQ4M0RcdURDQzAnLCBjb3VudDogZGF0YS5pbWFnZXMuY291bnQsIHNpemU6IGRhdGEuaW1hZ2VzLnNpemUsIHJlY2xhaW1hYmxlOiBkYXRhLmltYWdlcy5yZWNsYWltYWJsZSB9LFxuICAgICAgICB7IGxhYmVsOiAnQ29udGFpbmVycycsIGljb246ICdcdUQ4M0RcdURDRTYnLCBjb3VudDogZGF0YS5jb250YWluZXJzLmNvdW50LCBzaXplOiBkYXRhLmNvbnRhaW5lcnMuc2l6ZSwgZXh0cmE6IGAke2RhdGEuY29udGFpbmVycy5ydW5uaW5nfSBydW5uaW5nYCB9LFxuICAgICAgICB7IGxhYmVsOiAnVm9sdW1lcycsIGljb246ICdcdUQ4M0RcdURDQkUnLCBjb3VudDogZGF0YS52b2x1bWVzLmNvdW50LCBzaXplOiBkYXRhLnZvbHVtZXMuc2l6ZSwgcmVjbGFpbWFibGU6IGRhdGEudm9sdW1lcy5yZWNsYWltYWJsZSB9LFxuICAgICAgICB7IGxhYmVsOiAnQnVpbGQgQ2FjaGUnLCBpY29uOiAnXHVEODNEXHVERDI3JywgY291bnQ6IGRhdGEuYnVpbGRDYWNoZS5jb3VudCwgc2l6ZTogZGF0YS5idWlsZENhY2hlLnNpemUsIHJlY2xhaW1hYmxlOiBkYXRhLmJ1aWxkQ2FjaGUucmVjbGFpbWFibGUgfSxcbiAgICAgIF07XG5cbiAgICAgIGxldCBodG1sID0gYDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDEuMXJlbTsgZm9udC13ZWlnaHQ6IDYwMDsgbWFyZ2luLWJvdHRvbTogMTZweDtcIj5Ub3RhbDogJHtmbXRCeXRlcyhkYXRhLnRvdGFsU2l6ZSl9PC9kaXY+YDtcbiAgICAgIGh0bWwgKz0gJzxkaXYgc3R5bGU9XCJkaXNwbGF5OiBncmlkOyBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IDFmciAxZnI7IGdhcDogMTJweDtcIj4nO1xuICAgICAgZm9yIChjb25zdCBzIG9mIHNlY3Rpb25zKSB7XG4gICAgICAgIGh0bWwgKz0gYDxkaXYgc3R5bGU9XCJwYWRkaW5nOiAxNHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1iZyk7IGJvcmRlci1yYWRpdXM6IDhweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcIj5gO1xuICAgICAgICBodG1sICs9IGA8ZGl2IHN0eWxlPVwiZm9udC13ZWlnaHQ6IDYwMDsgbWFyZ2luLWJvdHRvbTogNnB4O1wiPiR7cy5pY29ufSAke3MubGFiZWx9IDxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTsgZm9udC13ZWlnaHQ6IDQwMDsgZm9udC1zaXplOiAwLjgycmVtO1wiPigke3MuY291bnR9KTwvc3Bhbj48L2Rpdj5gO1xuICAgICAgICBodG1sICs9IGA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAxLjFyZW07IGZvbnQtd2VpZ2h0OiA2MDA7IGNvbG9yOiB2YXIoLS1hY2NlbnQpO1wiPiR7Zm10Qnl0ZXMocy5zaXplKX08L2Rpdj5gO1xuICAgICAgICBpZiAocy5yZWNsYWltYWJsZSA+IDApIGh0bWwgKz0gYDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuNzhyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+UmVjbGFpbWFibGU6ICR7Zm10Qnl0ZXMocy5yZWNsYWltYWJsZSl9PC9kaXY+YDtcbiAgICAgICAgaWYgKHMuZXh0cmEpIGh0bWwgKz0gYDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuNzhyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+JHtzLmV4dHJhfTwvZGl2PmA7XG4gICAgICAgIGh0bWwgKz0gJzwvZGl2Pic7XG4gICAgICB9XG4gICAgICBodG1sICs9ICc8L2Rpdj4nO1xuICAgICAgY29udGFpbmVyLmlubmVySFRNTCA9IGh0bWw7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29udGFpbmVyLmlubmVySFRNTCA9IGA8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIiBzdHlsZT1cImNvbG9yOiB2YXIoLS1iYWQtZmcpO1wiPkZhaWxlZDogJHtlc2NhcGVIdG1sKGUubWVzc2FnZSl9PC9kaXY+YDtcbiAgICB9XG4gIH1cblxuICAvLyBNb2RhbCBldmVudHNcbiAgb3BlbkJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgbW9kYWw/LmNsYXNzTGlzdC5hZGQoJ3Nob3cnKTtcbiAgICBsb2FkVm9sdW1lcygpO1xuICB9KTtcbiAgd2lyZU1vZGFsKG1vZGFsLCBjbG9zZUJ0bik7XG5cbiAgLy8gTGF6eS1sb2FkIHRhYnNcbiAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW2RhdGEtcGFuZWw9XCJkci1uZXR3b3Jrc1wiXScpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGxvYWROZXR3b3Jrcyk7XG4gIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLXBhbmVsPVwiZHItZGlza1wiXScpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGxvYWREaXNrVXNhZ2UpO1xufSkoKTtcbjtcbi8vID09PT09PT09PT0gRE9DS0VSIENPTVBPU0UgSU1QT1JUID09PT09PT09PT1cbihmdW5jdGlvbigpIHtcbiAgaW5qZWN0TW9kYWwoJ2NvbXBvc2UtaW1wb3J0LW1vZGFsJywgYDxkaXYgaWQ9XCJjb21wb3NlLWltcG9ydC1tb2RhbFwiIGNsYXNzPVwid2VhdGhlci1tb2RhbFwiPlxuICAgIDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsLWNvbnRlbnRcIiBzdHlsZT1cIm1pbi13aWR0aDogNjUwcHg7IG1heC13aWR0aDogODAwcHg7XCI+XG4gICAgICA8aDM+XHVEODNEXHVEQ0U2IEltcG9ydCBEb2NrZXIgQ29tcG9zZTwvaDM+XG4gICAgICA8cCBjbGFzcz1cIm1vZGFsLXN1YnRpdGxlXCI+UGFzdGUgYSBkb2NrZXItY29tcG9zZS55bWwgdG8gaW1wb3J0IGFuZCBkZXBsb3kgc2VydmljZXMuPC9wPlxuXG4gICAgICA8IS0tIFN0ZXAgMTogUGFzdGUgWUFNTCAtLT5cbiAgICAgIDxkaXYgaWQ9XCJjb21wb3NlLXN0ZXAtcGFzdGVcIj5cbiAgICAgICAgPGRpdiBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDEycHg7XCI+XG4gICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbC1hY2NlbnQtc21cIj5TdGFjayBOYW1lPC9sYWJlbD5cbiAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBpZD1cImNvbXBvc2Utc3RhY2stbmFtZVwiIHBsYWNlaG9sZGVyPVwibXktc3RhY2tcIiB2YWx1ZT1cIlwiIHN0eWxlPVwid2lkdGg6IDEwMCU7IHBhZGRpbmc6IDhweCAxMHB4OyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBib3JkZXItcmFkaXVzOiA2cHg7IGJhY2tncm91bmQ6IHZhcigtLWJnKTsgY29sb3I6IHZhcigtLWZnKTtcIiAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDEycHg7XCI+XG4gICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbC1hY2NlbnQtc21cIj5kb2NrZXItY29tcG9zZS55bWw8L2xhYmVsPlxuICAgICAgICAgIDx0ZXh0YXJlYSBpZD1cImNvbXBvc2UteWFtbFwiIHJvd3M9XCIxNFwiIHBsYWNlaG9sZGVyPVwidmVyc2lvbjogJzMnJiMxMDtzZXJ2aWNlczomIzEwOyAgd2ViOiYjMTA7ICAgIGltYWdlOiBuZ2lueDpsYXRlc3QmIzEwOyAgICBwb3J0czomIzEwOyAgICAgIC0gJzgwODA6ODAnXCIgc3R5bGU9XCJ3aWR0aDogMTAwJTsgcGFkZGluZzogMTBweDsgZm9udC1mYW1pbHk6IG1vbm9zcGFjZTsgZm9udC1zaXplOiAwLjgycmVtOyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBib3JkZXItcmFkaXVzOiA2cHg7IGJhY2tncm91bmQ6IHZhcigtLWJnKTsgY29sb3I6IHZhcigtLWZnKTsgcmVzaXplOiB2ZXJ0aWNhbDtcIj48L3RleHRhcmVhPlxuICAgICAgICAgIDxkaXYgc3R5bGU9XCJtYXJnaW4tdG9wOiA2cHg7XCI+XG4gICAgICAgICAgICA8bGFiZWwgc3R5bGU9XCJkaXNwbGF5OiBpbmxpbmUtZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA2cHg7IGN1cnNvcjogcG9pbnRlcjsgZm9udC1zaXplOiAwLjgycmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImZpbGVcIiBpZD1cImNvbXBvc2UtZmlsZS11cGxvYWRcIiBhY2NlcHQ9XCIueW1sLC55YW1sXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lO1wiIC8+XG4gICAgICAgICAgICAgIDxzcGFuIHN0eWxlPVwidGV4dC1kZWNvcmF0aW9uOiB1bmRlcmxpbmU7XCI+b3IgdXBsb2FkIGEgZmlsZTwvc3Bhbj5cbiAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwid2VhdGhlci1tb2RhbC1idXR0b25zIG1vZGFsLWZvb3Rlci1iYXJcIj5cbiAgICAgICAgICA8YnV0dG9uIGlkPVwiY29tcG9zZS1wYXJzZS1idG5cIiBjbGFzcz1cImJ0bi1hY2NlbnQtc29saWRcIiBzdHlsZT1cInBhZGRpbmc6IDhweCAyMHB4O1wiPlBhcnNlICYgUHJldmlldzwvYnV0dG9uPlxuICAgICAgICAgIDxidXR0b24gaWQ9XCJjb21wb3NlLWNhbmNlbFwiPkNhbmNlbDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIFN0ZXAgMjogUHJldmlldyAtLT5cbiAgICAgIDxkaXYgaWQ9XCJjb21wb3NlLXN0ZXAtcHJldmlld1wiIHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIj5cbiAgICAgICAgPGRpdiBpZD1cImNvbXBvc2UtcHJldmlldy1jb250ZW50XCI+PC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsLWJ1dHRvbnMgbW9kYWwtZm9vdGVyLWJhclwiIHN0eWxlPVwibWFyZ2luLXRvcDogMTZweDtcIj5cbiAgICAgICAgICA8YnV0dG9uIGlkPVwiY29tcG9zZS1kZXBsb3ktYnRuXCIgY2xhc3M9XCJidG4tYWNjZW50LXNvbGlkXCIgc3R5bGU9XCJwYWRkaW5nOiA4cHggMjBweDtcIj5EZXBsb3kgQWxsPC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvbiBpZD1cImNvbXBvc2UtYmFjay1idG5cIj5CYWNrPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gU3RlcCAzOiBQcm9ncmVzcyAtLT5cbiAgICAgIDxkaXYgaWQ9XCJjb21wb3NlLXN0ZXAtcHJvZ3Jlc3NcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCI+XG4gICAgICAgIDxkaXYgaWQ9XCJjb21wb3NlLXByb2dyZXNzLWNvbnRlbnRcIj48L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5gKTtcblxuICBjb25zdCBtb2RhbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjb21wb3NlLWltcG9ydC1tb2RhbCcpO1xuICBjb25zdCBvcGVuQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NvbXBvc2UtaW1wb3J0LWJ0bicpO1xuICBjb25zdCBjYW5jZWxCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29tcG9zZS1jYW5jZWwnKTtcblxuICB3aXJlTW9kYWwobW9kYWwsIGNhbmNlbEJ0bik7XG5cbiAgbGV0IHBhcnNlZERhdGEgPSBudWxsO1xuXG4gIGZ1bmN0aW9uIHNob3dTdGVwKHN0ZXApIHtcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29tcG9zZS1zdGVwLXBhc3RlJykuc3R5bGUuZGlzcGxheSA9IHN0ZXAgPT09ICdwYXN0ZScgPyAnJyA6ICdub25lJztcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29tcG9zZS1zdGVwLXByZXZpZXcnKS5zdHlsZS5kaXNwbGF5ID0gc3RlcCA9PT0gJ3ByZXZpZXcnID8gJycgOiAnbm9uZSc7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NvbXBvc2Utc3RlcC1wcm9ncmVzcycpLnN0eWxlLmRpc3BsYXkgPSBzdGVwID09PSAncHJvZ3Jlc3MnID8gJycgOiAnbm9uZSc7XG4gIH1cblxuICBvcGVuQnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICBzaG93U3RlcCgncGFzdGUnKTtcbiAgICBwYXJzZWREYXRhID0gbnVsbDtcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29tcG9zZS15YW1sJykudmFsdWUgPSAnJztcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29tcG9zZS1zdGFjay1uYW1lJykudmFsdWUgPSAnJztcbiAgICBtb2RhbD8uY2xhc3NMaXN0LmFkZCgnc2hvdycpO1xuICB9KTtcblxuICAvLyBGaWxlIHVwbG9hZFxuICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29tcG9zZS1maWxlLXVwbG9hZCcpPy5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCAoZSkgPT4ge1xuICAgIGNvbnN0IGZpbGUgPSBlLnRhcmdldC5maWxlc1swXTtcbiAgICBpZiAoIWZpbGUpIHJldHVybjtcbiAgICBjb25zdCByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xuICAgIHJlYWRlci5vbmxvYWQgPSAoKSA9PiB7IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjb21wb3NlLXlhbWwnKS52YWx1ZSA9IHJlYWRlci5yZXN1bHQ7IH07XG4gICAgcmVhZGVyLnJlYWRBc1RleHQoZmlsZSk7XG4gIH0pO1xuXG4gIC8vIFBhcnNlXG4gIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjb21wb3NlLXBhcnNlLWJ0bicpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB5YW1sU3RyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NvbXBvc2UteWFtbCcpLnZhbHVlLnRyaW0oKTtcbiAgICBjb25zdCBzdGFja05hbWUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29tcG9zZS1zdGFjay1uYW1lJykudmFsdWUudHJpbSgpIHx8ICdzdGFjayc7XG4gICAgaWYgKCF5YW1sU3RyKSB7IHNob3dOb3RpZmljYXRpb24oJ1Bhc3RlIGEgZG9ja2VyLWNvbXBvc2UueW1sJywgJ3dhcm5pbmcnKTsgcmV0dXJuOyB9XG5cbiAgICBjb25zdCBidG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29tcG9zZS1wYXJzZS1idG4nKTtcbiAgICBjb25zdCBvcmlnVGV4dCA9IGJ0bi50ZXh0Q29udGVudDtcbiAgICBidG4udGV4dENvbnRlbnQgPSAnUGFyc2luZy4uLic7XG4gICAgYnRuLmRpc2FibGVkID0gdHJ1ZTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcG9zdEpTT04oJy9hcGkvdjEvYXBwcy9pbXBvcnQtY29tcG9zZScsIHsgeWFtbDogeWFtbFN0ciwgc3RhY2tOYW1lIH0pO1xuICAgICAgcGFyc2VkRGF0YSA9IGRhdGE7XG4gICAgICBwYXJzZWREYXRhLnN0YWNrTmFtZSA9IHN0YWNrTmFtZTtcbiAgICAgIHJlbmRlclByZXZpZXcoZGF0YSk7XG4gICAgICBzaG93U3RlcCgncHJldmlldycpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHNob3dOb3RpZmljYXRpb24oJ1BhcnNlIGZhaWxlZDogJyArIGUubWVzc2FnZSwgJ2Vycm9yJyk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGJ0bi50ZXh0Q29udGVudCA9IG9yaWdUZXh0O1xuICAgICAgYnRuLmRpc2FibGVkID0gZmFsc2U7XG4gICAgfVxuICB9KTtcblxuICBmdW5jdGlvbiByZW5kZXJQcmV2aWV3KGRhdGEpIHtcbiAgICBjb25zdCBjb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29tcG9zZS1wcmV2aWV3LWNvbnRlbnQnKTtcbiAgICBsZXQgaHRtbCA9ICcnO1xuXG4gICAgaWYgKGRhdGEubmV0d29ya3MgJiYgZGF0YS5uZXR3b3Jrcy5sZW5ndGggPiAwKSB7XG4gICAgICBodG1sICs9IGA8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMTJweDsgZm9udC1zaXplOiAwLjgycmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPk5ldHdvcmtzOiAke2RhdGEubmV0d29ya3MubWFwKG4gPT4gYDxjb2RlPiR7ZXNjYXBlSHRtbChuKX08L2NvZGU+YCkuam9pbignLCAnKX08L2Rpdj5gO1xuICAgIH1cbiAgICBpZiAoZGF0YS52b2x1bWVzICYmIGRhdGEudm9sdW1lcy5sZW5ndGggPiAwKSB7XG4gICAgICBodG1sICs9IGA8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMTJweDsgZm9udC1zaXplOiAwLjgycmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPlZvbHVtZXM6ICR7ZGF0YS52b2x1bWVzLm1hcCh2ID0+IGA8Y29kZT4ke2VzY2FwZUh0bWwodil9PC9jb2RlPmApLmpvaW4oJywgJyl9PC9kaXY+YDtcbiAgICB9XG5cbiAgICBodG1sICs9IGA8ZGl2IHN0eWxlPVwiZm9udC13ZWlnaHQ6IDYwMDsgbWFyZ2luLWJvdHRvbTogOHB4O1wiPiR7ZGF0YS5zZXJ2aWNlcy5sZW5ndGh9IHNlcnZpY2Uocyk8L2Rpdj5gO1xuICAgIGh0bWwgKz0gJzxkaXYgY2xhc3M9XCJzY3JvbGwtY29udGFpbmVyXCIgc3R5bGU9XCJtYXgtaGVpZ2h0OiAzNTBweDtcIj4nO1xuXG4gICAgZm9yIChjb25zdCBzdmMgb2YgZGF0YS5zZXJ2aWNlcykge1xuICAgICAgY29uc3QgYm9yZGVyQ29sb3IgPSBzdmMuc2tpcCA/ICd2YXIoLS1iYWQtZmcpJyA6ICd2YXIoLS1ib3JkZXIpJztcbiAgICAgIGh0bWwgKz0gYDxkaXYgc3R5bGU9XCJwYWRkaW5nOiAxMHB4IDE0cHg7IGJvcmRlcjogMXB4IHNvbGlkICR7Ym9yZGVyQ29sb3J9OyBib3JkZXItcmFkaXVzOiA4cHg7IG1hcmdpbi1ib3R0b206IDhweDsgYmFja2dyb3VuZDogdmFyKC0tYmcpO1wiPmA7XG4gICAgICBodG1sICs9IGA8ZGl2IHN0eWxlPVwiZm9udC13ZWlnaHQ6IDYwMDsgZm9udC1zaXplOiAwLjlyZW07XCI+JHtlc2NhcGVIdG1sKHN2Yy5uYW1lKX1gO1xuICAgICAgaWYgKHN2Yy5za2lwKSBodG1sICs9IGAgPHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tYmFkLWZnKTsgZm9udC13ZWlnaHQ6IDQwMDsgZm9udC1zaXplOiAwLjc4cmVtO1wiPlx1MjAxNCBza2lwcGVkOiAke2VzY2FwZUh0bWwoc3ZjLnJlYXNvbil9PC9zcGFuPmA7XG4gICAgICBodG1sICs9IGA8L2Rpdj5gO1xuXG4gICAgICBpZiAoIXN2Yy5za2lwKSB7XG4gICAgICAgIGh0bWwgKz0gYDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuOHJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLXRvcDogNHB4O1wiPkltYWdlOiA8Y29kZT4ke2VzY2FwZUh0bWwoc3ZjLmltYWdlKX08L2NvZGU+PC9kaXY+YDtcbiAgICAgICAgaWYgKHN2Yy5wb3J0cz8ubGVuZ3RoKSBodG1sICs9IGA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjhyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+UG9ydHM6ICR7c3ZjLnBvcnRzLm1hcChwID0+IGAke3AuaG9zdH06JHtwLmNvbnRhaW5lcn1gKS5qb2luKCcsICcpfTwvZGl2PmA7XG4gICAgICAgIGlmIChzdmMudm9sdW1lcz8ubGVuZ3RoKSBodG1sICs9IGA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjhyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+Vm9sdW1lczogJHtzdmMudm9sdW1lcy5sZW5ndGh9PC9kaXY+YDtcbiAgICAgICAgaWYgKE9iamVjdC5rZXlzKHN2Yy5lbnZpcm9ubWVudCB8fCB7fSkubGVuZ3RoKSBodG1sICs9IGA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjhyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+RW52IHZhcnM6ICR7T2JqZWN0LmtleXMoc3ZjLmVudmlyb25tZW50KS5sZW5ndGh9PC9kaXY+YDtcbiAgICAgICAgaWYgKHN2Yy5lbnZGaWxlV2FybmluZykgaHRtbCArPSBgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC43OHJlbTsgY29sb3I6IHZhcigtLWJhZC1mZyk7XCI+XHUyNkEwICR7ZXNjYXBlSHRtbChzdmMuZW52RmlsZVdhcm5pbmcpfTwvZGl2PmA7XG4gICAgICAgIGlmIChzdmMucmVzb3VyY2VzPy5jcHVzIHx8IHN2Yy5yZXNvdXJjZXM/Lm1lbW9yeSkge1xuICAgICAgICAgIGNvbnN0IHBhcnRzID0gW107XG4gICAgICAgICAgaWYgKHN2Yy5yZXNvdXJjZXMuY3B1cykgcGFydHMucHVzaChgQ1BVOiAke3N2Yy5yZXNvdXJjZXMuY3B1c31gKTtcbiAgICAgICAgICBpZiAoc3ZjLnJlc291cmNlcy5tZW1vcnkpIHBhcnRzLnB1c2goYE1lbTogJHtzdmMucmVzb3VyY2VzLm1lbW9yeX1NQmApO1xuICAgICAgICAgIGh0bWwgKz0gYDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuOHJlbTsgY29sb3I6IHZhcigtLW11dGVkKTtcIj5MaW1pdHM6ICR7cGFydHMuam9pbignLCAnKX08L2Rpdj5gO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGh0bWwgKz0gJzwvZGl2Pic7XG4gICAgfVxuICAgIGh0bWwgKz0gJzwvZGl2Pic7XG4gICAgY29udGFpbmVyLmlubmVySFRNTCA9IGh0bWw7XG4gIH1cblxuICAvLyBCYWNrIGJ1dHRvblxuICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29tcG9zZS1iYWNrLWJ0bicpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHNob3dTdGVwKCdwYXN0ZScpKTtcblxuICAvLyBEZXBsb3lcbiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NvbXBvc2UtZGVwbG95LWJ0bicpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICBpZiAoIXBhcnNlZERhdGEpIHJldHVybjtcblxuICAgIGNvbnN0IGJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjb21wb3NlLWRlcGxveS1idG4nKTtcbiAgICBidG4udGV4dENvbnRlbnQgPSAnRGVwbG95aW5nLi4uJztcbiAgICBidG4uZGlzYWJsZWQgPSB0cnVlO1xuICAgIHNob3dTdGVwKCdwcm9ncmVzcycpO1xuXG4gICAgY29uc3QgcHJvZ3Jlc3NFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjb21wb3NlLXByb2dyZXNzLWNvbnRlbnQnKTtcbiAgICBwcm9ncmVzc0VsLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj48c3BhbiBjbGFzcz1cImJyYW5kLXNwaW5uZXJcIj48L3NwYW4+IERlcGxveWluZyBzZXJ2aWNlcy4uLjwvZGl2Pic7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcG9zdEpTT04oJy9hcGkvdjEvYXBwcy9kZXBsb3ktY29tcG9zZScsIHtcbiAgICAgICAgc2VydmljZXM6IHBhcnNlZERhdGEuc2VydmljZXMsXG4gICAgICAgIG5ldHdvcmtzOiBwYXJzZWREYXRhLm5ldHdvcmtzLFxuICAgICAgICBzdGFja05hbWU6IHBhcnNlZERhdGEuc3RhY2tOYW1lXG4gICAgICB9KTtcblxuICAgICAgbGV0IGh0bWwgPSBgPGRpdiBzdHlsZT1cImZvbnQtd2VpZ2h0OiA2MDA7IG1hcmdpbi1ib3R0b206IDEycHg7XCI+U3RhY2sgXCIke2VzY2FwZUh0bWwocmVzdWx0LnN0YWNrTmFtZSl9XCIgXHUyMDE0IERlcGxveW1lbnQgQ29tcGxldGU8L2Rpdj5gO1xuICAgICAgaHRtbCArPSAnPGRpdiBjbGFzcz1cInNjcm9sbC1jb250YWluZXJcIiBzdHlsZT1cIm1heC1oZWlnaHQ6IDM1MHB4O1wiPic7XG5cbiAgICAgIGZvciAoY29uc3QgciBvZiByZXN1bHQucmVzdWx0cykge1xuICAgICAgICBjb25zdCBpY29uID0gci5zdGF0dXMgPT09ICdkZXBsb3llZCcgfHwgci5zdGF0dXMgPT09ICdjcmVhdGVkJyA/ICdcdTI3MDUnIDogci5zdGF0dXMgPT09ICdleGlzdHMnID8gJ1x1MjZBMScgOiByLnN0YXR1cyA9PT0gJ3NraXBwZWQnID8gJ1x1MjNFRCcgOiAnXHUyNzRDJztcbiAgICAgICAgaHRtbCArPSBgPGRpdiBzdHlsZT1cInBhZGRpbmc6IDhweCAxMnB4OyBib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgZm9udC1zaXplOiAwLjg1cmVtO1wiPmA7XG4gICAgICAgIGh0bWwgKz0gYCR7aWNvbn0gPHN0cm9uZz4ke2VzY2FwZUh0bWwoci5uYW1lKX08L3N0cm9uZz4gKCR7ci50eXBlfSkgXHUyMDE0ICR7ZXNjYXBlSHRtbChyLnN0YXR1cyl9YDtcbiAgICAgICAgaWYgKHIuZXJyb3IpIGh0bWwgKz0gYCA8c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1iYWQtZmcpO1wiPiR7ZXNjYXBlSHRtbChyLmVycm9yKX08L3NwYW4+YDtcbiAgICAgICAgaWYgKHIuc3ViZG9tYWluKSBodG1sICs9IGAgXHUyMTkyIDxjb2RlPiR7ZXNjYXBlSHRtbChyLnN1YmRvbWFpbil9PC9jb2RlPmA7XG4gICAgICAgIGlmIChyLnJlYXNvbikgaHRtbCArPSBgIDxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTtcIj4oJHtlc2NhcGVIdG1sKHIucmVhc29uKX0pPC9zcGFuPmA7XG4gICAgICAgIGh0bWwgKz0gJzwvZGl2Pic7XG4gICAgICB9XG4gICAgICBodG1sICs9ICc8L2Rpdj4nO1xuICAgICAgaHRtbCArPSAnPGRpdiBjbGFzcz1cIndlYXRoZXItbW9kYWwtYnV0dG9ucyBtb2RhbC1mb290ZXItYmFyXCIgc3R5bGU9XCJtYXJnaW4tdG9wOiAxNnB4O1wiPjxidXR0b24gaWQ9XCJjb21wb3NlLWRvbmUtYnRuXCI+RG9uZTwvYnV0dG9uPjwvZGl2Pic7XG5cbiAgICAgIHByb2dyZXNzRWwuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjb21wb3NlLWRvbmUtYnRuJyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICBtb2RhbD8uY2xhc3NMaXN0LnJlbW92ZSgnc2hvdycpO1xuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdy5sb2FkU2VydmljZXMgPT09ICdmdW5jdGlvbicpIHdpbmRvdy5sb2FkU2VydmljZXMoKS50aGVuKCgpID0+IHsgaWYgKHR5cGVvZiB3aW5kb3cuYnVpbGRHcmlkID09PSAnZnVuY3Rpb24nKSB3aW5kb3cuYnVpbGRHcmlkKCk7IH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNob3dOb3RpZmljYXRpb24oYFN0YWNrIFwiJHtyZXN1bHQuc3RhY2tOYW1lfVwiIGRlcGxveWVkYCwgJ3N1Y2Nlc3MnKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBwcm9ncmVzc0VsLmlubmVySFRNTCA9IGA8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIiBzdHlsZT1cImNvbG9yOiB2YXIoLS1iYWQtZmcpO1wiPkRlcGxveW1lbnQgZmFpbGVkOiAke2VzY2FwZUh0bWwoZS5tZXNzYWdlKX08L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIndlYXRoZXItbW9kYWwtYnV0dG9ucyBtb2RhbC1mb290ZXItYmFyXCIgc3R5bGU9XCJtYXJnaW4tdG9wOiAxNnB4O1wiPjxidXR0b24gaWQ9XCJjb21wb3NlLXJldHJ5LWJ0blwiPkJhY2s8L2J1dHRvbj48L2Rpdj5gO1xuICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NvbXBvc2UtcmV0cnktYnRuJyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4gc2hvd1N0ZXAoJ3Bhc3RlJykpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBidG4udGV4dENvbnRlbnQgPSAnRGVwbG95IEFsbCc7XG4gICAgICBidG4uZGlzYWJsZWQgPSBmYWxzZTtcbiAgICB9XG4gIH0pO1xufSkoKTtcbjtcbi8vID09PT09PT09PT0gQ09OVEFJTkVSIEVYRUMgLyBTSEVMTCAoV2ViU29ja2V0ICsgeHRlcm0uanMpID09PT09PT09PT1cbihmdW5jdGlvbigpIHtcbiAgaW5qZWN0TW9kYWwoJ2V4ZWMtbW9kYWwnLCBgPGRpdiBpZD1cImV4ZWMtbW9kYWxcIiBjbGFzcz1cIndlYXRoZXItbW9kYWxcIj5cbiAgICA8ZGl2IGNsYXNzPVwid2VhdGhlci1tb2RhbC1jb250ZW50XCIgc3R5bGU9XCJtaW4td2lkdGg6IDcwMHB4OyBtYXgtd2lkdGg6IDkwMHB4OyBwYWRkaW5nLWJvdHRvbTogMDtcIj5cbiAgICAgIDxoMyBpZD1cImV4ZWMtdGl0bGVcIj5UZXJtaW5hbDwvaDM+XG4gICAgICA8ZGl2IGlkPVwiZXhlYy10ZXJtaW5hbFwiIHN0eWxlPVwiaGVpZ2h0OiA0MjBweDsgYm9yZGVyLXJhZGl1czogNnB4OyBvdmVyZmxvdzogaGlkZGVuOyBiYWNrZ3JvdW5kOiAjMWUxZTFlO1wiPjwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cIndlYXRoZXItbW9kYWwtYnV0dG9ucyBtb2RhbC1mb290ZXItYmFyXCIgc3R5bGU9XCJtYXJnaW4tdG9wOiA4cHg7IHBhZGRpbmctYm90dG9tOiAxMnB4O1wiPlxuICAgICAgICA8YnV0dG9uIGlkPVwiZXhlYy1jbG9zZVwiPkNsb3NlPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+YCk7XG5cbiAgY29uc3QgbW9kYWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZXhlYy1tb2RhbCcpO1xuICBjb25zdCB0ZXJtRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZXhlYy10ZXJtaW5hbCcpO1xuICBjb25zdCBjbG9zZUJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdleGVjLWNsb3NlJyk7XG5cbiAgbGV0IHRlcm0gPSBudWxsO1xuICBsZXQgd3MgPSBudWxsO1xuICBsZXQgZml0QWRkb24gPSBudWxsO1xuXG4gIGZ1bmN0aW9uIGNsZWFudXAoKSB7XG4gICAgaWYgKHdzKSB7IHRyeSB7IHdzLmNsb3NlKCk7IH0gY2F0Y2ggKF8pIHt9IHdzID0gbnVsbDsgfVxuICAgIGlmICh0ZXJtKSB7IHRyeSB7IHRlcm0uZGlzcG9zZSgpOyB9IGNhdGNoIChfKSB7fSB0ZXJtID0gbnVsbDsgfVxuICAgIGZpdEFkZG9uID0gbnVsbDtcbiAgICB0ZXJtRWwuaW5uZXJIVE1MID0gJyc7XG4gIH1cblxuICBmdW5jdGlvbiBvcGVuRXhlYyhjb250YWluZXJJZCwgY29udGFpbmVyTmFtZSkge1xuICAgIGNsZWFudXAoKTtcblxuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdleGVjLXRpdGxlJykudGV4dENvbnRlbnQgPSBgVGVybWluYWwgXHUyMDE0ICR7Y29udGFpbmVyTmFtZSB8fCBjb250YWluZXJJZH1gO1xuICAgIG1vZGFsPy5jbGFzc0xpc3QuYWRkKCdzaG93Jyk7XG5cbiAgICAvLyBFbnN1cmUgeHRlcm0gaXMgYXZhaWxhYmxlXG4gICAgaWYgKHR5cGVvZiBUZXJtaW5hbCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRlcm1FbC5pbm5lckhUTUwgPSAnPGRpdiBzdHlsZT1cImNvbG9yOiAjZjQ0OyBwYWRkaW5nOiAyMHB4OyBmb250LWZhbWlseTogbW9ub3NwYWNlO1wiPnh0ZXJtLmpzIG5vdCBsb2FkZWQ8L2Rpdj4nO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRlcm0gPSBuZXcgVGVybWluYWwoe1xuICAgICAgY3Vyc29yQmxpbms6IHRydWUsXG4gICAgICBmb250U2l6ZTogMTQsXG4gICAgICBmb250RmFtaWx5OiBcIidDYXNjYWRpYSBDb2RlJywgJ0ZpcmEgQ29kZScsICdDb25zb2xhcycsIG1vbm9zcGFjZVwiLFxuICAgICAgdGhlbWU6IHtcbiAgICAgICAgYmFja2dyb3VuZDogJyMxZTFlMWUnLFxuICAgICAgICBmb3JlZ3JvdW5kOiAnI2Q0ZDRkNCcsXG4gICAgICAgIGN1cnNvcjogJyNhZWFmYWQnLFxuICAgICAgICBzZWxlY3Rpb25CYWNrZ3JvdW5kOiAnIzI2NGY3OCcsXG4gICAgICB9LFxuICAgICAgc2Nyb2xsYmFjazogNTAwMCxcbiAgICB9KTtcblxuICAgIC8vIEZpdCBhZGRvblxuICAgIGlmICh0eXBlb2YgRml0QWRkb24gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBmaXRBZGRvbiA9IG5ldyBGaXRBZGRvbi5GaXRBZGRvbigpO1xuICAgICAgdGVybS5sb2FkQWRkb24oZml0QWRkb24pO1xuICAgIH1cblxuICAgIHRlcm0ub3Blbih0ZXJtRWwpO1xuICAgIGlmIChmaXRBZGRvbikge1xuICAgICAgLy8gU21hbGwgZGVsYXkgZm9yIERPTSB0byBzZXR0bGVcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gZml0QWRkb24uZml0KCksIDUwKTtcbiAgICB9XG5cbiAgICAvLyBDb25uZWN0IFdlYlNvY2tldFxuICAgIGNvbnN0IHByb3RvY29sID0gbG9jYXRpb24ucHJvdG9jb2wgPT09ICdodHRwczonID8gJ3dzczonIDogJ3dzOic7XG4gICAgd3MgPSBuZXcgV2ViU29ja2V0KGAke3Byb3RvY29sfS8vJHtsb2NhdGlvbi5ob3N0fS93cy9leGVjLyR7ZW5jb2RlVVJJQ29tcG9uZW50KGNvbnRhaW5lcklkKX1gKTtcbiAgICB3cy5iaW5hcnlUeXBlID0gJ2FycmF5YnVmZmVyJztcblxuICAgIHdzLm9ub3BlbiA9ICgpID0+IHtcbiAgICAgIHRlcm0ud3JpdGVsbignXFx4MWJbMzJtQ29ubmVjdGluZy4uLlxceDFiWzBtJyk7XG4gICAgICAvLyBTZW5kIGluaXRpYWwgcmVzaXplXG4gICAgICBpZiAoZml0QWRkb24pIHtcbiAgICAgICAgY29uc3QgZGltcyA9IGZpdEFkZG9uLnByb3Bvc2VEaW1lbnNpb25zKCk7XG4gICAgICAgIGlmIChkaW1zKSB7XG4gICAgICAgICAgd3Muc2VuZChKU09OLnN0cmluZ2lmeSh7IHR5cGU6ICdyZXNpemUnLCBjb2xzOiBkaW1zLmNvbHMsIHJvd3M6IGRpbXMucm93cyB9KSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgd3Mub25tZXNzYWdlID0gKGUpID0+IHtcbiAgICAgIGlmICh0eXBlb2YgZS5kYXRhID09PSAnc3RyaW5nJykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IG1zZyA9IEpTT04ucGFyc2UoZS5kYXRhKTtcbiAgICAgICAgICBpZiAobXNnLnR5cGUgPT09ICdjb25uZWN0ZWQnKSB7XG4gICAgICAgICAgICB0ZXJtLndyaXRlbG4oYFxceDFiWzMybUNvbm5lY3RlZCAoJHttc2cuc2hlbGx9KVxceDFiWzBtXFxyXFxuYCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChtc2cudHlwZSA9PT0gJ2Vycm9yJykge1xuICAgICAgICAgICAgdGVybS53cml0ZWxuKGBcXHgxYlszMW1FcnJvcjogJHttc2cubWVzc2FnZX1cXHgxYlswbWApO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAobXNnLnR5cGUgPT09ICdleGl0Jykge1xuICAgICAgICAgICAgdGVybS53cml0ZWxuKCdcXHJcXG5cXHgxYlszM21TZXNzaW9uIGVuZGVkLlxceDFiWzBtJyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChfKSB7fVxuICAgICAgICAvLyBQbGFpbiB0ZXh0XG4gICAgICAgIHRlcm0ud3JpdGUoZS5kYXRhKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEJpbmFyeSBkYXRhXG4gICAgICAgIHRlcm0ud3JpdGUobmV3IFVpbnQ4QXJyYXkoZS5kYXRhKSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHdzLm9uY2xvc2UgPSAoKSA9PiB7XG4gICAgICBpZiAodGVybSkgdGVybS53cml0ZWxuKCdcXHJcXG5cXHgxYlszM21EaXNjb25uZWN0ZWQuXFx4MWJbMG0nKTtcbiAgICB9O1xuXG4gICAgd3Mub25lcnJvciA9ICgpID0+IHtcbiAgICAgIGlmICh0ZXJtKSB0ZXJtLndyaXRlbG4oJ1xcclxcblxceDFiWzMxbUNvbm5lY3Rpb24gZXJyb3IuXFx4MWJbMG0nKTtcbiAgICB9O1xuXG4gICAgLy8gVGVybWluYWwgaW5wdXQgXHUyMTkyIFdlYlNvY2tldFxuICAgIHRlcm0ub25EYXRhKChkYXRhKSA9PiB7XG4gICAgICBpZiAod3MgJiYgd3MucmVhZHlTdGF0ZSA9PT0gV2ViU29ja2V0Lk9QRU4pIHtcbiAgICAgICAgd3Muc2VuZChkYXRhKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIEhhbmRsZSByZXNpemVcbiAgICB0ZXJtLm9uUmVzaXplKCh7IGNvbHMsIHJvd3MgfSkgPT4ge1xuICAgICAgaWYgKHdzICYmIHdzLnJlYWR5U3RhdGUgPT09IFdlYlNvY2tldC5PUEVOKSB7XG4gICAgICAgIHdzLnNlbmQoSlNPTi5zdHJpbmdpZnkoeyB0eXBlOiAncmVzaXplJywgY29scywgcm93cyB9KSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBSZS1maXQgb24gd2luZG93IHJlc2l6ZVxuICAgIGNvbnN0IHJlc2l6ZUhhbmRsZXIgPSAoKSA9PiB7IGlmIChmaXRBZGRvbikgZml0QWRkb24uZml0KCk7IH07XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHJlc2l6ZUhhbmRsZXIpO1xuXG4gICAgLy8gU3RvcmUgaGFuZGxlciBmb3IgY2xlYW51cFxuICAgIG1vZGFsLl9yZXNpemVIYW5kbGVyID0gcmVzaXplSGFuZGxlcjtcbiAgfVxuXG4gIGNsb3NlQnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICBjbGVhbnVwKCk7XG4gICAgaWYgKG1vZGFsLl9yZXNpemVIYW5kbGVyKSB7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVzaXplJywgbW9kYWwuX3Jlc2l6ZUhhbmRsZXIpO1xuICAgIH1cbiAgICBtb2RhbD8uY2xhc3NMaXN0LnJlbW92ZSgnc2hvdycpO1xuICB9KTtcblxuICAvLyBBbHNvIGNsb3NlIG9uIGJhY2tkcm9wIGNsaWNrXG4gIG1vZGFsPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIChlKSA9PiB7XG4gICAgaWYgKGUudGFyZ2V0ID09PSBtb2RhbCkge1xuICAgICAgY2xlYW51cCgpO1xuICAgICAgaWYgKG1vZGFsLl9yZXNpemVIYW5kbGVyKSB7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCBtb2RhbC5fcmVzaXplSGFuZGxlcik7XG4gICAgICB9XG4gICAgICBtb2RhbD8uY2xhc3NMaXN0LnJlbW92ZSgnc2hvdycpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gRXhwb3J0XG4gIHdpbmRvdy5vcGVuRXhlY01vZGFsID0gb3BlbkV4ZWM7XG59KSgpO1xuO1xuLy8gPT09PT09PT09PSBBVURJVCBMT0cgVklFV0VSID09PT09PT09PT1cbihmdW5jdGlvbigpIHtcbiAgLy8gSW5qZWN0IG1vZGFsIEhUTUxcbiAgaW5qZWN0TW9kYWwoJ2F1ZGl0LW1vZGFsJywgYDxkaXYgaWQ9XCJhdWRpdC1tb2RhbFwiIGNsYXNzPVwid2VhdGhlci1tb2RhbFwiPlxuICAgIDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsLWNvbnRlbnRcIiBzdHlsZT1cIm1pbi13aWR0aDogODUwcHg7IG1heC13aWR0aDogMTA1MHB4O1wiPlxuICAgICAgPGgzPlx1RDgzRFx1RENEQyBBdWRpdCBMb2c8L2gzPlxuICAgICAgPHAgY2xhc3M9XCJtb2RhbC1zdWJ0aXRsZVwiPlxuICAgICAgICBUcmFjayBhbGwgYWN0aW9ucyBwZXJmb3JtZWQgdGhyb3VnaCB0aGUgQVBJLlxuICAgICAgPC9wPlxuXG4gICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgZ2FwOiAxMnB4OyBtYXJnaW4tYm90dG9tOiAxNnB4OyBhbGlnbi1pdGVtczogY2VudGVyO1wiPlxuICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0ZXh0LW11dGVkLXNtXCI+RmlsdGVyOjwvbGFiZWw+XG4gICAgICAgIDxzZWxlY3QgaWQ9XCJhdWRpdC1maWx0ZXJcIiBzdHlsZT1cInBhZGRpbmc6IDZweCAxMHB4OyBib3JkZXItcmFkaXVzOiA2cHg7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJhY2tncm91bmQ6IHZhcigtLWJnKTsgY29sb3I6IHZhcigtLWZnKTsgZm9udC1zaXplOiAwLjg1cmVtO1wiPlxuICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj5BbGwgQWN0aW9uczwvb3B0aW9uPlxuICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJzZXJ2aWNlXCI+U2VydmljZXM8L29wdGlvbj5cbiAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiY29udGFpbmVyXCI+Q29udGFpbmVyczwvb3B0aW9uPlxuICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJjYWRkeVwiPkNhZGR5PC9vcHRpb24+XG4gICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cImRuc1wiPkROUzwvb3B0aW9uPlxuICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJiYWNrdXBcIj5CYWNrdXBzPC9vcHRpb24+XG4gICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cImNvbmZpZ1wiPkNvbmZpZzwvb3B0aW9uPlxuICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJhdXRoXCI+QXV0aDwvb3B0aW9uPlxuICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgPGJ1dHRvbiBpZD1cImF1ZGl0LXJlZnJlc2gtYnRuXCIgY2xhc3M9XCJidG4tc21cIj5cdUQ4M0RcdUREMDQgUmVmcmVzaDwvYnV0dG9uPlxuICAgICAgICA8c3BhbiBzdHlsZT1cImZsZXg6IDE7XCI+PC9zcGFuPlxuICAgICAgICA8YnV0dG9uIGlkPVwiYXVkaXQtY2xlYXItYnRuXCIgc3R5bGU9XCJwYWRkaW5nOiA2cHggMTJweDsgZm9udC1zaXplOiAwLjhyZW07IGNvbG9yOiB2YXIoLS1iYWQtZmcpOyBib3JkZXItY29sb3I6IHZhcigtLWJhZC1mZyk7XCI+XHVEODNEXHVEREQxXHVGRTBGIENsZWFyIExvZzwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgaWQ9XCJhdWRpdC1sb2ctY29udGFpbmVyXCIgY2xhc3M9XCJzY3JvbGwtY29udGFpbmVyXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPjxzcGFuIGNsYXNzPVwiYnJhbmQtc3Bpbm5lclwiPjwvc3Bhbj4gTG9hZGluZyBhdWRpdCBsb2cuLi48L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IHN0eWxlPVwibWFyZ2luLXRvcDogMTJweDsgdGV4dC1hbGlnbjogY2VudGVyO1wiPlxuICAgICAgICA8YnV0dG9uIGlkPVwiYXVkaXQtbG9hZC1tb3JlXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lOyBwYWRkaW5nOiA2cHggMTZweDsgZm9udC1zaXplOiAwLjhyZW07XCI+TG9hZCBNb3JlPC9idXR0b24+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzcz1cIndlYXRoZXItbW9kYWwtYnV0dG9ucyBtb2RhbC1mb290ZXItYmFyXCI+XG4gICAgICAgIDxidXR0b24gaWQ9XCJhdWRpdC1jYW5jZWxcIj5DbG9zZTwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PmApO1xuXG4gIGNvbnN0IG1vZGFsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2F1ZGl0LW1vZGFsJyk7XG4gIGNvbnN0IG9wZW5CdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXVkaXQtbG9nLWJ0bicpO1xuICBjb25zdCBjYW5jZWxCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXVkaXQtY2FuY2VsJyk7XG4gIGNvbnN0IHJlZnJlc2hCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXVkaXQtcmVmcmVzaC1idG4nKTtcbiAgY29uc3QgY2xlYXJCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXVkaXQtY2xlYXItYnRuJyk7XG4gIGNvbnN0IGZpbHRlclNlbGVjdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhdWRpdC1maWx0ZXInKTtcbiAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2F1ZGl0LWxvZy1jb250YWluZXInKTtcbiAgY29uc3QgbG9hZE1vcmVCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXVkaXQtbG9hZC1tb3JlJyk7XG4gIGxldCBjdXJyZW50T2Zmc2V0ID0gMDtcbiAgY29uc3QgUEFHRV9TSVpFID0gNTA7XG5cbiAgYXN5bmMgZnVuY3Rpb24gbG9hZEF1ZGl0KGFwcGVuZCkge1xuICAgIHRyeSB7XG4gICAgICBpZiAoIWFwcGVuZCkge1xuICAgICAgICBjdXJyZW50T2Zmc2V0ID0gMDtcbiAgICAgICAgY29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj48c3BhbiBjbGFzcz1cImJyYW5kLXNwaW5uZXJcIj48L3NwYW4+IExvYWRpbmcuLi48L2Rpdj4nO1xuICAgICAgfVxuICAgICAgY29uc3QgZmlsdGVyID0gZmlsdGVyU2VsZWN0LnZhbHVlO1xuICAgICAgbGV0IHVybCA9IGAvYXBpL3YxL2F1ZGl0LWxvZ3M/bGltaXQ9JHtQQUdFX1NJWkV9Jm9mZnNldD0ke2N1cnJlbnRPZmZzZXR9YDtcbiAgICAgIGlmIChmaWx0ZXIpIHVybCArPSBgJmFjdGlvbj0ke2VuY29kZVVSSUNvbXBvbmVudChmaWx0ZXIpfWA7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaCh1cmwpO1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlcy5qc29uKCk7XG4gICAgICBjb25zdCBlbnRyaWVzID0gZGF0YS5zdWNjZXNzICYmIGRhdGEuZW50cmllcyA/IGRhdGEuZW50cmllcyA6IFtdO1xuXG4gICAgICBpZiAoZW50cmllcy5sZW5ndGggPT09IDAgJiYgIWFwcGVuZCkge1xuICAgICAgICBjb250YWluZXIuaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPjxzcGFuIGNsYXNzPVwiZW1wdHktaWNvblwiPlx1RDgzRFx1RENEQzwvc3Bhbj5ObyBhdWRpdCBsb2cgZW50cmllcyB5ZXQuIEFjdGlvbnMgd2lsbCBiZSBsb2dnZWQgYXV0b21hdGljYWxseS48L2Rpdj4nO1xuICAgICAgICBsb2FkTW9yZUJ0bi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGxldCBodG1sID0gJyc7XG4gICAgICBpZiAoIWFwcGVuZCkge1xuICAgICAgICBodG1sID0gJzx0YWJsZSBzdHlsZT1cIndpZHRoOiAxMDAlOyBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlOyBmb250LXNpemU6IDAuODJyZW07XCI+JztcbiAgICAgICAgaHRtbCArPSAnPHRyIHN0eWxlPVwiYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+PHRoIHN0eWxlPVwicGFkZGluZzogNnB4OyB0ZXh0LWFsaWduOiBsZWZ0O1wiPldoZW48L3RoPjx0aCBzdHlsZT1cInBhZGRpbmc6IDZweDsgdGV4dC1hbGlnbjogbGVmdDtcIj5JUDwvdGg+PHRoIHN0eWxlPVwicGFkZGluZzogNnB4OyB0ZXh0LWFsaWduOiBsZWZ0O1wiPkFjdGlvbjwvdGg+PHRoIHN0eWxlPVwicGFkZGluZzogNnB4OyB0ZXh0LWFsaWduOiBsZWZ0O1wiPlJlc291cmNlPC90aD48dGggc3R5bGU9XCJwYWRkaW5nOiA2cHg7IHRleHQtYWxpZ246IGxlZnQ7XCI+UmVzdWx0PC90aD48L3RyPic7XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgZSBvZiBlbnRyaWVzKSB7XG4gICAgICAgIGNvbnN0IG9rID0gZS5vdXRjb21lID09PSAnc3VjY2Vzcyc7XG4gICAgICAgIGh0bWwgKz0gYDx0ciBzdHlsZT1cImJvcmRlci1ib3R0b206IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBjdXJzb3I6IHBvaW50ZXI7XCIgY2xhc3M9XCJhdWRpdC1yb3dcIj5gO1xuICAgICAgICBodG1sICs9IGA8dGQgc3R5bGU9XCJwYWRkaW5nOiA2cHg7IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+JHt0aW1lQWdvKGUudGltZXN0YW1wKX08L3RkPmA7XG4gICAgICAgIGh0bWwgKz0gYDx0ZCBzdHlsZT1cInBhZGRpbmc6IDZweDsgZm9udC1mYW1pbHk6IG1vbm9zcGFjZTsgZm9udC1zaXplOiAwLjc4cmVtO1wiPiR7ZXNjYXBlSHRtbChlLmlwIHx8ICctJyl9PC90ZD5gO1xuICAgICAgICBodG1sICs9IGA8dGQgc3R5bGU9XCJwYWRkaW5nOiA2cHg7IGZvbnQtd2VpZ2h0OiA1MDA7XCI+JHtlc2NhcGVIdG1sKGUuYWN0aW9uIHx8ICctJyl9PC90ZD5gO1xuICAgICAgICBodG1sICs9IGA8dGQgc3R5bGU9XCJwYWRkaW5nOiA2cHg7XCI+JHtlc2NhcGVIdG1sKGUucmVzb3VyY2UgfHwgJy0nKX08L3RkPmA7XG4gICAgICAgIGh0bWwgKz0gYDx0ZCBzdHlsZT1cInBhZGRpbmc6IDZweDtcIj48c3BhbiBzdHlsZT1cImNvbG9yOiAke29rID8gJ3ZhcigtLW9rLWZnKScgOiAndmFyKC0tYmFkLWZnKSd9O1wiPiR7b2sgPyAnXHUyNzEzJyA6ICdcdTI3MTcnfTwvc3Bhbj48L3RkPmA7XG4gICAgICAgIGh0bWwgKz0gJzwvdHI+JztcbiAgICAgICAgaWYgKGUuZGV0YWlscyAmJiBPYmplY3Qua2V5cyhlLmRldGFpbHMpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBodG1sICs9IGA8dHIgY2xhc3M9XCJhdWRpdC1kZXRhaWxcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCI+PHRkIGNvbHNwYW49XCI1XCIgc3R5bGU9XCJwYWRkaW5nOiA2cHggNnB4IDEwcHg7IGZvbnQtc2l6ZTogMC43OHJlbTsgY29sb3I6IHZhcigtLW11dGVkKTtcIj48cHJlIHN0eWxlPVwibWFyZ2luOiAwOyB3aGl0ZS1zcGFjZTogcHJlLXdyYXA7IGZvbnQtZmFtaWx5OiBtb25vc3BhY2U7XCI+JHtlc2NhcGVIdG1sKEpTT04uc3RyaW5naWZ5KGUuZGV0YWlscywgbnVsbCwgMikpfTwvcHJlPjwvdGQ+PC90cj5gO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICghYXBwZW5kKSB7XG4gICAgICAgIGh0bWwgKz0gJzwvdGFibGU+JztcbiAgICAgICAgY29udGFpbmVyLmlubmVySFRNTCA9IGh0bWw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBBcHBlbmQgcm93cyB0byBleGlzdGluZyB0YWJsZVxuICAgICAgICBjb25zdCB0YWJsZSA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCd0YWJsZScpO1xuICAgICAgICBpZiAodGFibGUpIHRhYmxlLmluc2VydEFkamFjZW50SFRNTCgnYmVmb3JlZW5kJywgaHRtbCk7XG4gICAgICB9XG5cbiAgICAgIGN1cnJlbnRPZmZzZXQgKz0gZW50cmllcy5sZW5ndGg7XG4gICAgICBsb2FkTW9yZUJ0bi5zdHlsZS5kaXNwbGF5ID0gZW50cmllcy5sZW5ndGggPj0gUEFHRV9TSVpFID8gJycgOiAnbm9uZSc7XG5cbiAgICAgIC8vIFRvZ2dsZSBkZXRhaWwgcm93cyBvbiBjbGlja1xuICAgICAgY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoJy5hdWRpdC1yb3cnKS5mb3JFYWNoKHJvdyA9PiB7XG4gICAgICAgIGlmIChyb3cuZGF0YXNldC53aXJlZCkgcmV0dXJuO1xuICAgICAgICByb3cuZGF0YXNldC53aXJlZCA9ICd0cnVlJztcbiAgICAgICAgcm93LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGRldGFpbCA9IHJvdy5uZXh0RWxlbWVudFNpYmxpbmc7XG4gICAgICAgICAgaWYgKGRldGFpbCAmJiBkZXRhaWwuY2xhc3NMaXN0LmNvbnRhaW5zKCdhdWRpdC1kZXRhaWwnKSkge1xuICAgICAgICAgICAgZGV0YWlsLnN0eWxlLmRpc3BsYXkgPSBkZXRhaWwuc3R5bGUuZGlzcGxheSA9PT0gJ25vbmUnID8gJycgOiAnbm9uZSc7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnRhaW5lci5pbm5lckhUTUwgPSBgPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCIgc3R5bGU9XCJjb2xvcjogdmFyKC0tYmFkLWZnKTtcIj5GYWlsZWQ6ICR7ZXNjYXBlSHRtbChlLm1lc3NhZ2UpfTwvZGl2PmA7XG4gICAgfVxuICB9XG5cbiAgb3BlbkJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgbW9kYWw/LmNsYXNzTGlzdC5hZGQoJ3Nob3cnKTtcbiAgICBsb2FkQXVkaXQoZmFsc2UpO1xuICB9KTtcbiAgd2lyZU1vZGFsKG1vZGFsLCBjYW5jZWxCdG4pO1xuICByZWZyZXNoQnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IGxvYWRBdWRpdChmYWxzZSkpO1xuICBmaWx0ZXJTZWxlY3Q/LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsICgpID0+IGxvYWRBdWRpdChmYWxzZSkpO1xuICBsb2FkTW9yZUJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiBsb2FkQXVkaXQodHJ1ZSkpO1xuXG4gIGNsZWFyQnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICBpZiAoIWNvbmZpcm0oJ0NsZWFyIHRoZSBlbnRpcmUgYXVkaXQgbG9nPyBUaGlzIGNhbm5vdCBiZSB1bmRvbmUuJykpIHJldHVybjtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgc2VjdXJlRmV0Y2goJy9hcGkvdjEvYXVkaXQtbG9ncycsIHsgbWV0aG9kOiAnREVMRVRFJyB9KTtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXMuanNvbigpO1xuICAgICAgaWYgKGRhdGEuc3VjY2VzcykgbG9hZEF1ZGl0KGZhbHNlKTtcbiAgICAgIGVsc2Ugc2hvd05vdGlmaWNhdGlvbignRXJyb3I6ICcgKyAoZGF0YS5lcnJvciB8fCAnQ2xlYXIgZmFpbGVkJyksICdlcnJvcicpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHNob3dOb3RpZmljYXRpb24oJ0Vycm9yOiAnICsgZS5tZXNzYWdlLCAnZXJyb3InKTtcbiAgICB9XG4gIH0pO1xufSkoKTtcbjtcbi8vID09PT09PT09PT0gU0VDVVJJVFkgQ0VOVEVSID09PT09PT09PT1cbi8vIE11bHRpLXNvdXJjZSBzZWN1cml0eSBldmVudCB2aWV3ZXIgKyBob3N0IHJlZ2lzdHJ5IFVJLlxuLy9cbi8vIFNob3dzIGxpdmUgZXZlbnRzIGZyb20gYW55IHNvdXJjZSAoQVBJIGF1ZGl0LCBDYWRkeSBhY2Nlc3MgbG9nLCBmYWlsMmJhbixcbi8vIHNoYXJlZF9iYW5zKSBvbiBhbnkgcmVnaXN0ZXJlZCBob3N0ICh0aGlzIERhc2hDYWRkeSwgZnV0dXJlIHJlbW90ZSBhZ2VudHMpLlxuLy9cbi8vIExpdmUtdGFpbCB1c2VzIFNTRSAoL2FwaS92MS9zZWN1cml0eS9ldmVudHMvc3RyZWFtKS5cbihmdW5jdGlvbigpIHtcbiAgaW5qZWN0TW9kYWwoJ3NlY3VyaXR5LW1vZGFsJywgYDxkaXYgaWQ9XCJzZWN1cml0eS1tb2RhbFwiIGNsYXNzPVwid2VhdGhlci1tb2RhbFwiPlxuICAgIDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsLWNvbnRlbnRcIiBzdHlsZT1cIm1pbi13aWR0aDogOTgwcHg7IG1heC13aWR0aDogMTI4MHB4O1wiPlxuICAgICAgPGgzPlx1RDgzRFx1REVFMVx1RkUwRiBTZWN1cml0eSBDZW50ZXI8L2gzPlxuICAgICAgPHAgY2xhc3M9XCJtb2RhbC1zdWJ0aXRsZVwiPlxuICAgICAgICBMaXZlIGV2ZW50cyBmcm9tIEFQSSwgQ2FkZHksIGZhaWwyYmFuICYgc2hhcmVkX2JhbnMuIExpdmUtdGFpbCB2aWEgU1NFLlxuICAgICAgPC9wPlxuXG4gICAgICA8ZGl2IGNsYXNzPVwic2VjLXRhYnNcIiBzdHlsZT1cImRpc3BsYXk6ZmxleDtnYXA6OHB4O21hcmdpbi1ib3R0b206MTRweDtib3JkZXItYm90dG9tOjFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1wiPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwic2VjLXRhYiBhY3RpdmVcIiBkYXRhLXRhYj1cIm92ZXJ2aWV3XCI+T3ZlcnZpZXc8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInNlYy10YWJcIiBkYXRhLXRhYj1cImV2ZW50c1wiPkV2ZW50czwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwic2VjLXRhYlwiIGRhdGEtdGFiPVwiaG9zdHNcIj5Ib3N0czwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gT1ZFUlZJRVcgVEFCIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cInNlYy1wYW5lbFwiIGRhdGEtcGFuZWw9XCJvdmVydmlld1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2VjLXN0YXRzXCIgaWQ9XCJzZWMtc3RhdHNcIiBzdHlsZT1cImRpc3BsYXk6Z3JpZDtncmlkLXRlbXBsYXRlLWNvbHVtbnM6cmVwZWF0KGF1dG8tZml0LG1pbm1heCgxODBweCwxZnIpKTtnYXA6MTJweDttYXJnaW4tYm90dG9tOjE4cHg7XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInNlYy1zdGF0XCIgZGF0YS1rZXk9XCJ0b3RhbFwiPlx1MjAxNCBldmVudHM8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VjLXN0YXRcIiBkYXRhLWtleT1cIndhcm5cIj5cdTIwMTQgd2FybmluZ3M8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VjLXN0YXRcIiBkYXRhLWtleT1cImVycm9yXCI+XHUyMDE0IGVycm9yczwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZWMtc3RhdFwiIGRhdGEta2V5PVwiZGVuaWVkXCI+XHUyMDE0IGRlbmllZDwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZWMtc3RhdFwiIGRhdGEta2V5PVwiaG9zdHNcIj5cdTIwMTQgaG9zdHM8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OmdyaWQ7Z3JpZC10ZW1wbGF0ZS1jb2x1bW5zOjFmciAxZnI7Z2FwOjE0cHg7XCI+XG4gICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIDxoNCBzdHlsZT1cIm1hcmdpbjo4cHggMCA2cHg7XCI+VG9wIEFjdG9ycyAoMjRoKTwvaDQ+XG4gICAgICAgICAgICA8ZGl2IGlkPVwic2VjLXRvcC1hY3RvcnNcIiBjbGFzcz1cInNjcm9sbC1jb250YWluZXJcIiBzdHlsZT1cIm1heC1oZWlnaHQ6MjQwcHg7XCI+XHUyMDE0PC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIDxoNCBzdHlsZT1cIm1hcmdpbjo4cHggMCA2cHg7XCI+VG9wIFRhcmdldHMgKDI0aCk8L2g0PlxuICAgICAgICAgICAgPGRpdiBpZD1cInNlYy10b3AtdGFyZ2V0c1wiIGNsYXNzPVwic2Nyb2xsLWNvbnRhaW5lclwiIHN0eWxlPVwibWF4LWhlaWdodDoyNDBweDtcIj5cdTIwMTQ8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBFVkVOVFMgVEFCIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cInNlYy1wYW5lbFwiIGRhdGEtcGFuZWw9XCJldmVudHNcIiBzdHlsZT1cImRpc3BsYXk6bm9uZTtcIj5cbiAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6ZmxleDtnYXA6OHB4O21hcmdpbi1ib3R0b206MTJweDthbGlnbi1pdGVtczpjZW50ZXI7ZmxleC13cmFwOndyYXA7XCI+XG4gICAgICAgICAgPHNlbGVjdCBpZD1cInNlYy1maWx0ZXItc291cmNlXCIgY2xhc3M9XCJzZWMtZmlsdGVyXCI+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+QWxsIHNvdXJjZXM8L29wdGlvbj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJhcGlcIj5BUEk8L29wdGlvbj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJjYWRkeVwiPkNhZGR5PC9vcHRpb24+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiZmFpbDJiYW5cIj5mYWlsMmJhbjwvb3B0aW9uPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cInNoYXJlZC1iYW5zXCI+c2hhcmVkX2JhbnM8L29wdGlvbj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJhZ2VudFwiPkFnZW50PC9vcHRpb24+XG4gICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgPHNlbGVjdCBpZD1cInNlYy1maWx0ZXItc2V2ZXJpdHlcIiBjbGFzcz1cInNlYy1maWx0ZXJcIj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj5BbGwgc2V2ZXJpdGllczwvb3B0aW9uPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cImNyaXRpY2FsXCI+Y3JpdGljYWw8L29wdGlvbj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJlcnJvclwiPmVycm9yPC9vcHRpb24+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwid2FyblwiPndhcm48L29wdGlvbj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJub3RpY2VcIj5ub3RpY2U8L29wdGlvbj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJpbmZvXCI+aW5mbzwvb3B0aW9uPlxuICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgIDxzZWxlY3QgaWQ9XCJzZWMtZmlsdGVyLWhvc3RcIiBjbGFzcz1cInNlYy1maWx0ZXJcIj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj5BbGwgaG9zdHM8L29wdGlvbj5cbiAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICA8aW5wdXQgaWQ9XCJzZWMtZmlsdGVyLWFjdG9yXCIgY2xhc3M9XCJzZWMtZmlsdGVyXCIgcGxhY2Vob2xkZXI9XCJhY3RvciAoSVAgb3IgdXNlcilcIiBzdHlsZT1cInBhZGRpbmc6NnB4IDEwcHg7XCI+XG4gICAgICAgICAgPGJ1dHRvbiBpZD1cInNlYy1yZWZyZXNoLWJ0blwiIGNsYXNzPVwiYnRuLXNtXCI+XHVEODNEXHVERDA0IFJlZnJlc2g8L2J1dHRvbj5cbiAgICAgICAgICA8bGFiZWwgc3R5bGU9XCJtYXJnaW4tbGVmdDphdXRvO2Rpc3BsYXk6ZmxleDthbGlnbi1pdGVtczpjZW50ZXI7Z2FwOjZweDtcIj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBpZD1cInNlYy1saXZlLXRhaWxcIiBjaGVja2VkPlxuICAgICAgICAgICAgPHNwYW4+TGl2ZSB0YWlsPC9zcGFuPlxuICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGlkPVwic2VjLWV2ZW50cy1jb250YWluZXJcIiBjbGFzcz1cInNjcm9sbC1jb250YWluZXJcIiBzdHlsZT1cIm1heC1oZWlnaHQ6NDgwcHg7XCI+TG9hZGluZ1x1MjAyNjwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gSE9TVFMgVEFCIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cInNlYy1wYW5lbFwiIGRhdGEtcGFuZWw9XCJob3N0c1wiIHN0eWxlPVwiZGlzcGxheTpub25lO1wiPlxuICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTpmbGV4O2dhcDo4cHg7bWFyZ2luLWJvdHRvbToxMnB4O1wiPlxuICAgICAgICAgIDxidXR0b24gaWQ9XCJzZWMtaG9zdC1yZWdpc3Rlci1idG5cIiBjbGFzcz1cImJ0bi1zbVwiPlx1Mjc5NSBSZWdpc3RlciBIb3N0PC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvbiBpZD1cInNlYy1ob3N0cy1yZWZyZXNoXCIgY2xhc3M9XCJidG4tc21cIj5cdUQ4M0RcdUREMDQgUmVmcmVzaDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBpZD1cInNlYy1ob3N0cy1jb250YWluZXJcIiBjbGFzcz1cInNjcm9sbC1jb250YWluZXJcIiBzdHlsZT1cIm1heC1oZWlnaHQ6NDgwcHg7XCI+TG9hZGluZ1x1MjAyNjwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsLWJ1dHRvbnMgbW9kYWwtZm9vdGVyLWJhclwiPlxuICAgICAgICA8YnV0dG9uIGlkPVwic2VjLWNhbmNlbFwiPkNsb3NlPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+YCk7XG5cbiAgLy8gPT09PT09PT09PT09PSBTVEFURSA9PT09PT09PT09PT09XG4gIGNvbnN0IG1vZGFsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NlY3VyaXR5LW1vZGFsJyk7XG4gIGNvbnN0IG9wZW5CdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2VjdXJpdHktY2VudGVyLWJ0bicpO1xuICBjb25zdCBjYW5jZWxCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2VjLWNhbmNlbCcpO1xuICBjb25zdCB0YWJzID0gbW9kYWwucXVlcnlTZWxlY3RvckFsbCgnLnNlYy10YWInKTtcbiAgY29uc3QgcGFuZWxzID0gbW9kYWwucXVlcnlTZWxlY3RvckFsbCgnLnNlYy1wYW5lbCcpO1xuXG4gIGxldCBhbGxFdmVudHMgPSBbXTsgLy8gbmV3ZXN0IGZpcnN0XG4gIGxldCBhbGxIb3N0cyA9IFtdO1xuICBsZXQgc3NlU291cmNlID0gbnVsbDtcblxuICAvLyA9PT09PT09PT09PT09IFRBQiBTV0lUQ0hJTkcgPT09PT09PT09PT09PVxuICB0YWJzLmZvckVhY2godGFiID0+IHtcbiAgICB0YWIuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICB0YWJzLmZvckVhY2godCA9PiB0LmNsYXNzTGlzdC50b2dnbGUoJ2FjdGl2ZScsIHQgPT09IHRhYikpO1xuICAgICAgcGFuZWxzLmZvckVhY2gocCA9PiBwLnN0eWxlLmRpc3BsYXkgPSBwLmRhdGFzZXQucGFuZWwgPT09IHRhYi5kYXRhc2V0LnRhYiA/ICcnIDogJ25vbmUnKTtcbiAgICAgIGlmICh0YWIuZGF0YXNldC50YWIgPT09ICdvdmVydmlldycpIHJlZnJlc2hPdmVydmlldygpO1xuICAgICAgaWYgKHRhYi5kYXRhc2V0LnRhYiA9PT0gJ2V2ZW50cycpIHJlZnJlc2hFdmVudHMoKTtcbiAgICAgIGlmICh0YWIuZGF0YXNldC50YWIgPT09ICdob3N0cycpIHJlZnJlc2hIb3N0cygpO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyA9PT09PT09PT09PT09IE9QRU4vQ0xPU0UgPT09PT09PT09PT09PVxuICBpZiAob3BlbkJ0bikge1xuICAgIG9wZW5CdG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICBtb2RhbC5jbGFzc0xpc3QuYWRkKCdzaG93Jyk7XG4gICAgICByZWZyZXNoT3ZlcnZpZXcoKTtcbiAgICAgIHN0YXJ0TGl2ZVRhaWwoKTtcbiAgICB9KTtcbiAgfVxuICBjYW5jZWxCdG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBjbG9zZU1vZGFsKTtcbiAgbW9kYWwuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBlID0+IHsgaWYgKGUudGFyZ2V0ID09PSBtb2RhbCkgY2xvc2VNb2RhbCgpOyB9KTtcbiAgZnVuY3Rpb24gY2xvc2VNb2RhbCgpIHtcbiAgICBtb2RhbC5jbGFzc0xpc3QucmVtb3ZlKCdzaG93Jyk7XG4gICAgc3RvcExpdmVUYWlsKCk7XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09IExJVkUgVEFJTCAoU1NFKSA9PT09PT09PT09PT09XG4gIGZ1bmN0aW9uIHN0YXJ0TGl2ZVRhaWwoKSB7XG4gICAgc3RvcExpdmVUYWlsKCk7XG4gICAgaWYgKCFkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2VjLWxpdmUtdGFpbCcpLmNoZWNrZWQpIHJldHVybjtcbiAgICBpZiAodHlwZW9mIEV2ZW50U291cmNlID09PSAndW5kZWZpbmVkJykgcmV0dXJuOyAvLyBicm93c2VyIGRvZXNuJ3Qgc3VwcG9ydFxuICAgIHRyeSB7XG4gICAgICBzc2VTb3VyY2UgPSBuZXcgRXZlbnRTb3VyY2UoJy9hcGkvdjEvc2VjdXJpdHkvZXZlbnRzL3N0cmVhbScpO1xuICAgICAgc3NlU291cmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2luaXQnLCAoZSkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGRhdGEgPSBKU09OLnBhcnNlKGUuZGF0YSk7XG4gICAgICAgICAgYWxsRXZlbnRzID0gZGF0YS5ldmVudHMgfHwgW107XG4gICAgICAgICAgcmVuZGVyRXZlbnRzKCk7XG4gICAgICAgIH0gY2F0Y2gge31cbiAgICAgIH0pO1xuICAgICAgc3NlU291cmNlLmFkZEV2ZW50TGlzdGVuZXIoJ3NlY3VyaXR5JywgKGUpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBldiA9IEpTT04ucGFyc2UoZS5kYXRhKTtcbiAgICAgICAgICBhbGxFdmVudHMudW5zaGlmdChldik7XG4gICAgICAgICAgaWYgKGFsbEV2ZW50cy5sZW5ndGggPiA1MDApIGFsbEV2ZW50cy5sZW5ndGggPSA1MDA7XG4gICAgICAgICAgLy8gQXV0by1yZWZyZXNoIHdoaWNoZXZlciBwYW5lbCBpcyBzaG93aW5nXG4gICAgICAgICAgY29uc3QgYWN0aXZlID0gbW9kYWwucXVlcnlTZWxlY3RvcignLnNlYy10YWIuYWN0aXZlJyk/LmRhdGFzZXQ/LnRhYjtcbiAgICAgICAgICBpZiAoYWN0aXZlID09PSAnZXZlbnRzJykgcmVuZGVyRXZlbnRzKCk7XG4gICAgICAgICAgZWxzZSBpZiAoYWN0aXZlID09PSAnb3ZlcnZpZXcnKSByZWZyZXNoT3ZlcnZpZXcoKTtcbiAgICAgICAgfSBjYXRjaCB7fVxuICAgICAgfSk7XG4gICAgICBzc2VTb3VyY2Uub25lcnJvciA9ICgpID0+IHsgLyogYnJvd3NlciBhdXRvLXJlY29ubmVjdHMgKi8gfTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1tzZWN1cml0eV0gU1NFIGZhaWxlZDonLCBlLm1lc3NhZ2UpO1xuICAgIH1cbiAgfVxuICBmdW5jdGlvbiBzdG9wTGl2ZVRhaWwoKSB7XG4gICAgaWYgKHNzZVNvdXJjZSkgeyB0cnkgeyBzc2VTb3VyY2UuY2xvc2UoKTsgfSBjYXRjaCB7fSBzc2VTb3VyY2UgPSBudWxsOyB9XG4gIH1cbiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NlYy1saXZlLXRhaWwnKS5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCAoKSA9PiB7XG4gICAgaWYgKG1vZGFsLmNsYXNzTGlzdC5jb250YWlucygnc2hvdycpKSBzdGFydExpdmVUYWlsKCk7XG4gIH0pO1xuXG4gIC8vID09PT09PT09PT09PT0gT1ZFUlZJRVcgPT09PT09PT09PT09PVxuICBhc3luYyBmdW5jdGlvbiByZWZyZXNoT3ZlcnZpZXcoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHNpbmNlID0gbmV3IERhdGUoRGF0ZS5ub3coKSAtIDI0KjYwKjYwKjEwMDApLnRvSVNPU3RyaW5nKCk7XG4gICAgICBjb25zdCBbc3RhdHNSZXMsIGhvc3RzUmVzLCBldmVudHNSZXNdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICBmZXRjaChgL2FwaS92MS9zZWN1cml0eS9ldmVudHMvc3RhdHM/c2luY2U9JHtlbmNvZGVVUklDb21wb25lbnQoc2luY2UpfWApLFxuICAgICAgICBmZXRjaCgnL2FwaS92MS9zZWN1cml0eS9ob3N0cycpLFxuICAgICAgICBmZXRjaChgL2FwaS92MS9zZWN1cml0eS9ldmVudHM/bGltaXQ9MSZzaW5jZT0ke2VuY29kZVVSSUNvbXBvbmVudChzaW5jZSl9YCksXG4gICAgICBdKTtcbiAgICAgIGNvbnN0IHN0YXRzID0gKGF3YWl0IHN0YXRzUmVzLmpzb24oKSkuZGF0YSB8fCB7fTtcbiAgICAgIGNvbnN0IGhvc3RzID0gKGF3YWl0IGhvc3RzUmVzLmpzb24oKSkuZGF0YT8uaG9zdHMgfHwgW107XG4gICAgICBjb25zdCBldmVudHNDb3VudCA9IChhd2FpdCBldmVudHNSZXMuanNvbigpKS5kYXRhPy50b3RhbCB8fCAwO1xuXG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjc2VjLXN0YXRzIFtkYXRhLWtleT1cInRvdGFsXCJdJykudGV4dENvbnRlbnQgPSBgJHtldmVudHNDb3VudH0gZXZlbnRzICgyNGgpYDtcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNzZWMtc3RhdHMgW2RhdGEta2V5PVwid2FyblwiXScpLnRleHRDb250ZW50ID0gYCR7c3RhdHMuYnlfc2V2ZXJpdHk/Lndhcm4gfHwgMH0gd2FybmluZ3NgO1xuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3NlYy1zdGF0cyBbZGF0YS1rZXk9XCJlcnJvclwiXScpLnRleHRDb250ZW50ID0gYCR7c3RhdHMuYnlfc2V2ZXJpdHk/LmVycm9yIHx8IDB9IGVycm9yc2A7XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjc2VjLXN0YXRzIFtkYXRhLWtleT1cImRlbmllZFwiXScpLnRleHRDb250ZW50ID0gYCR7c3RhdHMuYnlfb3V0Y29tZT8uZGVuaWVkIHx8IDB9IGRlbmllZGA7XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjc2VjLXN0YXRzIFtkYXRhLWtleT1cImhvc3RzXCJdJykudGV4dENvbnRlbnQgPSBgJHtob3N0cy5sZW5ndGh9IGhvc3RzYDtcblxuICAgICAgcmVuZGVyVG9wTGlzdCgnc2VjLXRvcC1hY3RvcnMnLCBzdGF0cy50b3BfYWN0b3JzIHx8IFtdKTtcbiAgICAgIHJlbmRlclRvcExpc3QoJ3NlYy10b3AtdGFyZ2V0cycsIHN0YXRzLnRvcF90YXJnZXRzIHx8IFtdKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1tzZWN1cml0eV0gcmVmcmVzaE92ZXJ2aWV3IGZhaWxlZDonLCBlLm1lc3NhZ2UpO1xuICAgIH1cbiAgfVxuICBmdW5jdGlvbiByZW5kZXJUb3BMaXN0KGlkLCBpdGVtcykge1xuICAgIGNvbnN0IGVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICAgIGlmICghaXRlbXMubGVuZ3RoKSB7IGVsLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj5ObyBkYXRhPC9kaXY+JzsgcmV0dXJuOyB9XG4gICAgZWwuaW5uZXJIVE1MID0gJzx0YWJsZSBzdHlsZT1cIndpZHRoOjEwMCU7Zm9udC1zaXplOjAuODVyZW07XCI+JyArXG4gICAgICBpdGVtcy5tYXAoaXQgPT4gYDx0cj48dGQgc3R5bGU9XCJwYWRkaW5nOjNweCAwO3dvcmQtYnJlYWs6YnJlYWstYWxsO1wiPiR7ZXNjYXBlSHRtbChTdHJpbmcoaXQua2V5KSl9PC90ZD48dGQgc3R5bGU9XCJ0ZXh0LWFsaWduOnJpZ2h0O2NvbG9yOnZhcigtLW11dGVkKTtcIj4ke2l0LmNvdW50fTwvdGQ+PC90cj5gKS5qb2luKCcnKSArXG4gICAgICAnPC90YWJsZT4nO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PSBFVkVOVFMgPT09PT09PT09PT09PVxuICBjb25zdCBmaWx0ZXJTb3VyY2UgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2VjLWZpbHRlci1zb3VyY2UnKTtcbiAgY29uc3QgZmlsdGVyU2V2ZXJpdHkgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2VjLWZpbHRlci1zZXZlcml0eScpO1xuICBjb25zdCBmaWx0ZXJIb3N0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NlYy1maWx0ZXItaG9zdCcpO1xuICBjb25zdCBmaWx0ZXJBY3RvciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZWMtZmlsdGVyLWFjdG9yJyk7XG4gIGNvbnN0IHJlZnJlc2hCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2VjLXJlZnJlc2gtYnRuJyk7XG5cbiAgW2ZpbHRlclNvdXJjZSwgZmlsdGVyU2V2ZXJpdHksIGZpbHRlckhvc3RdLmZvckVhY2goZWwgPT4gZWwuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgcmVmcmVzaEV2ZW50cykpO1xuICBmaWx0ZXJBY3Rvci5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIGRlYm91bmNlKHJlZnJlc2hFdmVudHMsIDI1MCkpO1xuICByZWZyZXNoQnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgcmVmcmVzaEV2ZW50cyk7XG5cbiAgYXN5bmMgZnVuY3Rpb24gcmVmcmVzaEV2ZW50cygpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcygpO1xuICAgICAgcGFyYW1zLnNldCgnbGltaXQnLCAnMjAwJyk7XG4gICAgICBpZiAoZmlsdGVyU291cmNlLnZhbHVlKSAgcGFyYW1zLnNldCgnc291cmNlX3R5cGUnLCBmaWx0ZXJTb3VyY2UudmFsdWUpO1xuICAgICAgaWYgKGZpbHRlclNldmVyaXR5LnZhbHVlKSBwYXJhbXMuc2V0KCdzZXZlcml0eScsIGZpbHRlclNldmVyaXR5LnZhbHVlKTtcbiAgICAgIGlmIChmaWx0ZXJIb3N0LnZhbHVlKSAgICBwYXJhbXMuc2V0KCdzb3VyY2VfaG9zdCcsIGZpbHRlckhvc3QudmFsdWUpO1xuICAgICAgaWYgKGZpbHRlckFjdG9yLnZhbHVlKSAgIHBhcmFtcy5zZXQoJ2FjdG9yX3ByZWZpeCcsIGZpbHRlckFjdG9yLnZhbHVlKTtcblxuICAgICAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2goYC9hcGkvdjEvc2VjdXJpdHkvZXZlbnRzPyR7cGFyYW1zfWApO1xuICAgICAgY29uc3QgZGF0YSA9IChhd2FpdCByZXMuanNvbigpKS5kYXRhO1xuICAgICAgYWxsRXZlbnRzID0gZGF0YS5ldmVudHMgfHwgW107XG4gICAgICByZW5kZXJFdmVudHMoKTtcblxuICAgICAgLy8gUmVmcmVzaCBob3N0IGRyb3Bkb3duIGlmIHdlIGRvbid0IGhhdmUgaXQgeWV0XG4gICAgICBpZiAoIWZpbHRlckhvc3Qub3B0aW9ucy5sZW5ndGggfHwgZmlsdGVySG9zdC5vcHRpb25zLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICBhd2FpdCByZWZyZXNoSG9zdEZpbHRlcigpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZWMtZXZlbnRzLWNvbnRhaW5lcicpLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj5Mb2FkIGZhaWxlZDogJytlc2NhcGVIdG1sKGUubWVzc2FnZSkrJzwvZGl2Pic7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVuZGVyRXZlbnRzKCkge1xuICAgIGNvbnN0IGVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NlYy1ldmVudHMtY29udGFpbmVyJyk7XG4gICAgaWYgKCFhbGxFdmVudHMubGVuZ3RoKSB7IGVsLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj5ObyBldmVudHM8L2Rpdj4nOyByZXR1cm47IH1cbiAgICBlbC5pbm5lckhUTUwgPSBhbGxFdmVudHMuc2xpY2UoMCwgMjAwKS5tYXAocmVuZGVyRXZlbnRSb3cpLmpvaW4oJycpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVuZGVyRXZlbnRSb3coZXYpIHtcbiAgICBjb25zdCBzZXYgPSBldi5zZXZlcml0eSB8fCAnaW5mbyc7XG4gICAgY29uc3Qgc2V2Q29sb3IgPSB7XG4gICAgICBjcml0aWNhbDogJyNjMDM5MmInLCBlcnJvcjogJyNlNzRjM2MnLCB3YXJuOiAnI2YzOWMxMicsXG4gICAgICBub3RpY2U6ICcjMzQ5OGRiJywgaW5mbzogJyM3ZjhjOGQnLFxuICAgIH1bc2V2XSB8fCAnIzdmOGM4ZCc7XG4gICAgY29uc3QgdGltZSA9IGV2LnRzID8gbmV3IERhdGUoZXYudHMpLnRvTG9jYWxlVGltZVN0cmluZygpIDogJyc7XG4gICAgY29uc3Qgc291cmNlID0gZXYuc291cmNlX3R5cGUgfHwgJyc7XG4gICAgY29uc3QgYWN0b3IgPSBldi5hY3RvciB8fCAnXHUyMDE0JztcbiAgICBjb25zdCB0YXJnZXQgPSBldi50YXJnZXQgfHwgJyc7XG4gICAgY29uc3QgYWN0aW9uID0gZXYuYWN0aW9uIHx8ICcnO1xuICAgIGNvbnN0IG91dGNvbWUgPSBldi5vdXRjb21lIHx8ICcnO1xuICAgIHJldHVybiBgPGRpdiBjbGFzcz1cInNlYy1ldmVudC1yb3dcIiBzdHlsZT1cImRpc3BsYXk6Z3JpZDtncmlkLXRlbXBsYXRlLWNvbHVtbnM6ODRweCA4MHB4IDFmciAxZnIgMTAwcHggOTBweDtnYXA6OHB4O3BhZGRpbmc6NXB4IDhweDtib3JkZXItYm90dG9tOjFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO2ZvbnQtc2l6ZTowLjgycmVtO2FsaWduLWl0ZW1zOmNlbnRlcjtcIj5cbiAgICAgIDxzcGFuIHN0eWxlPVwiY29sb3I6JHtzZXZDb2xvcn07Zm9udC13ZWlnaHQ6NjAwO1wiPiR7ZXNjYXBlSHRtbChzZXYpfTwvc3Bhbj5cbiAgICAgIDxzcGFuIHN0eWxlPVwiY29sb3I6dmFyKC0tbXV0ZWQpO2ZvbnQtc2l6ZTowLjc1cmVtO1wiPiR7ZXNjYXBlSHRtbChzb3VyY2UpfTwvc3Bhbj5cbiAgICAgIDxzcGFuIHRpdGxlPVwiJHtlc2NhcGVIdG1sKGFjdG9yKX1cIiBzdHlsZT1cIm92ZXJmbG93OmhpZGRlbjt0ZXh0LW92ZXJmbG93OmVsbGlwc2lzO3doaXRlLXNwYWNlOm5vd3JhcDtcIj4ke2VzY2FwZUh0bWwoYWN0b3IpfTwvc3Bhbj5cbiAgICAgIDxzcGFuIHRpdGxlPVwiJHtlc2NhcGVIdG1sKHRhcmdldCl9XCIgc3R5bGU9XCJvdmVyZmxvdzpoaWRkZW47dGV4dC1vdmVyZmxvdzplbGxpcHNpczt3aGl0ZS1zcGFjZTpub3dyYXA7XCI+JHtlc2NhcGVIdG1sKGFjdGlvbil9ICR7ZXNjYXBlSHRtbCh0YXJnZXQpfTwvc3Bhbj5cbiAgICAgIDxzcGFuIHN0eWxlPVwiY29sb3I6dmFyKC0tbXV0ZWQpO2ZvbnQtc2l6ZTowLjc1cmVtO1wiPiR7ZXNjYXBlSHRtbChvdXRjb21lKX08L3NwYW4+XG4gICAgICA8c3BhbiBzdHlsZT1cImNvbG9yOnZhcigtLW11dGVkKTtmb250LXNpemU6MC43NXJlbTt0ZXh0LWFsaWduOnJpZ2h0O1wiPiR7ZXNjYXBlSHRtbCh0aW1lKX08L3NwYW4+XG4gICAgPC9kaXY+YDtcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIHJlZnJlc2hIb3N0RmlsdGVyKCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS9zZWN1cml0eS9ob3N0cycpO1xuICAgICAgY29uc3QgaG9zdHMgPSAoYXdhaXQgcmVzLmpzb24oKSkuZGF0YT8uaG9zdHMgfHwgW107XG4gICAgICBjb25zdCBjdXJyZW50ID0gZmlsdGVySG9zdC52YWx1ZTtcbiAgICAgIGZpbHRlckhvc3QuaW5uZXJIVE1MID0gJzxvcHRpb24gdmFsdWU9XCJcIj5BbGwgaG9zdHM8L29wdGlvbj4nICtcbiAgICAgICAgaG9zdHMubWFwKGggPT4gYDxvcHRpb24gdmFsdWU9XCIke2VzY2FwZUh0bWwoaC5pZCl9XCI+JHtlc2NhcGVIdG1sKGgubGFiZWwgfHwgaC5pZCl9PC9vcHRpb24+YCkuam9pbignJyk7XG4gICAgICBpZiAoY3VycmVudCkgZmlsdGVySG9zdC52YWx1ZSA9IGN1cnJlbnQ7XG4gICAgfSBjYXRjaCB7fVxuICB9XG5cbiAgLy8gPT09PT09PT09PT09PSBIT1NUUyA9PT09PT09PT09PT09XG4gIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZWMtaG9zdC1yZWdpc3Rlci1idG4nKS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHJlZ2lzdGVySG9zdFByb21wdCk7XG4gIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZWMtaG9zdHMtcmVmcmVzaCcpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgcmVmcmVzaEhvc3RzKTtcblxuICBhc3luYyBmdW5jdGlvbiByZWZyZXNoSG9zdHMoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL3NlY3VyaXR5L2hvc3RzJyk7XG4gICAgICBjb25zdCBob3N0cyA9IChhd2FpdCByZXMuanNvbigpKS5kYXRhPy5ob3N0cyB8fCBbXTtcbiAgICAgIGFsbEhvc3RzID0gaG9zdHM7XG4gICAgICBjb25zdCBlbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZWMtaG9zdHMtY29udGFpbmVyJyk7XG4gICAgICBpZiAoIWhvc3RzLmxlbmd0aCkgeyBlbC5pbm5lckhUTUwgPSAnPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+Tm8gaG9zdHMgcmVnaXN0ZXJlZC4gQ2xpY2sgXHUyNzk1IFJlZ2lzdGVyIEhvc3QgdG8gYWRkIG9uZS48L2Rpdj4nOyByZXR1cm47IH1cbiAgICAgIGVsLmlubmVySFRNTCA9IGhvc3RzLm1hcChoID0+IHtcbiAgICAgICAgY29uc3Qgc3RhdHVzID0gIWguZW5hYmxlZCA/ICdcdUQ4M0RcdUREMzQgZGlzYWJsZWQnXG4gICAgICAgICAgICAgICAgICAgICA6ICFoLmxhc3Rfc2Vlbl9hdCA/ICdcdTI2QUEgcmVnaXN0ZXJlZCdcbiAgICAgICAgICAgICAgICAgICAgIDogKERhdGUubm93KCkgLSBEYXRlLnBhcnNlKGgubGFzdF9zZWVuX2F0KSA+IDMwKjYwKjEwMDApID8gJ1x1RDgzRFx1REZFMSBzdGFsZSdcbiAgICAgICAgICAgICAgICAgICAgIDogJ1x1RDgzRFx1REZFMiBvbmxpbmUnO1xuICAgICAgICByZXR1cm4gYDxkaXYgc3R5bGU9XCJwYWRkaW5nOjEwcHggMTJweDtib3JkZXItYm90dG9tOjFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO2Rpc3BsYXk6ZmxleDtqdXN0aWZ5LWNvbnRlbnQ6c3BhY2UtYmV0d2VlbjthbGlnbi1pdGVtczpjZW50ZXI7XCI+XG4gICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIDxzdHJvbmc+JHtlc2NhcGVIdG1sKGgubGFiZWwgfHwgaC5pZCl9PC9zdHJvbmc+XG4gICAgICAgICAgICA8c3BhbiBzdHlsZT1cImNvbG9yOnZhcigtLW11dGVkKTttYXJnaW4tbGVmdDo4cHg7Zm9udC1zaXplOjAuOHJlbTtcIj4ke2VzY2FwZUh0bWwoaC50eXBlKX08L3NwYW4+XG4gICAgICAgICAgICA8ZGl2IHN0eWxlPVwiY29sb3I6dmFyKC0tbXV0ZWQpO2ZvbnQtc2l6ZTowLjc4cmVtO21hcmdpbi10b3A6MnB4O1wiPlxuICAgICAgICAgICAgICBpZDogJHtlc2NhcGVIdG1sKGguaWQpfSBcdTAwQjdcbiAgICAgICAgICAgICAgcmVnaXN0ZXJlZCAke25ldyBEYXRlKGgucmVnaXN0ZXJlZF9hdCkudG9Mb2NhbGVEYXRlU3RyaW5nKCl9IFx1MDBCN1xuICAgICAgICAgICAgICBsYXN0IHNlZW4gJHtoLmxhc3Rfc2Vlbl9hdCA/IG5ldyBEYXRlKGgubGFzdF9zZWVuX2F0KS50b0xvY2FsZVN0cmluZygpIDogJ25ldmVyJ31cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICA8c3BhbiBzdHlsZT1cImZvbnQtc2l6ZTowLjg1cmVtO21hcmdpbi1yaWdodDoxMnB4O1wiPiR7c3RhdHVzfTwvc3Bhbj5cbiAgICAgICAgICAgICR7aC5pZCA9PT0gJ3NlbGYnID8gJycgOiBgPGJ1dHRvbiBjbGFzcz1cImJ0bi1zbSBzZWMtaG9zdC1kZWxcIiBkYXRhLWlkPVwiJHtlc2NhcGVIdG1sKGguaWQpfVwiIHN0eWxlPVwiY29sb3I6dmFyKC0tYmFkLWZnKTtcIj5SZW1vdmU8L2J1dHRvbj5gfVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5gO1xuICAgICAgfSkuam9pbignJyk7XG5cbiAgICAgIGVsLnF1ZXJ5U2VsZWN0b3JBbGwoJy5zZWMtaG9zdC1kZWwnKS5mb3JFYWNoKGJ0biA9PiB7XG4gICAgICAgIGJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICBpZiAoIWNvbmZpcm0oYFJlbW92ZSBob3N0ICR7YnRuLmRhdGFzZXQuaWR9PyBFdmVudHMgYWxyZWFkeSByZWNlaXZlZCB3aWxsIHJlbWFpbiBpbiB0aGUgc3RvcmUuYCkpIHJldHVybjtcbiAgICAgICAgICBhd2FpdCBmZXRjaChgL2FwaS92MS9zZWN1cml0eS9ob3N0cy8ke2VuY29kZVVSSUNvbXBvbmVudChidG4uZGF0YXNldC5pZCl9YCwgeyBtZXRob2Q6ICdERUxFVEUnIH0pO1xuICAgICAgICAgIHJlZnJlc2hIb3N0cygpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZWMtaG9zdHMtY29udGFpbmVyJykuaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPkxvYWQgZmFpbGVkOiAnK2VzY2FwZUh0bWwoZS5tZXNzYWdlKSsnPC9kaXY+JztcbiAgICB9XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiByZWdpc3Rlckhvc3RQcm9tcHQoKSB7XG4gICAgY29uc3QgaWQgPSBwcm9tcHQoJ0hvc3QgaWQgKGxvd2VyY2FzZSwgbm8gc3BhY2VzKTonKTtcbiAgICBpZiAoIWlkKSByZXR1cm47XG4gICAgY29uc3QgbGFiZWwgPSBwcm9tcHQoJ0Rpc3BsYXkgbGFiZWw6JywgaWQpIHx8IGlkO1xuICAgIGNvbnN0IHR5cGUgID0gcHJvbXB0KCdUeXBlIChcImRhc2hjYWRkeVwiLCBcInNlcnZpY2VcIiwgb3IgXCJhZ2VudFwiKTonLCAnYWdlbnQnKSB8fCAnYWdlbnQnO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS9zZWN1cml0eS9ob3N0cycsIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7IGlkLCBsYWJlbCwgdHlwZSB9KSxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlcy5qc29uKCk7XG4gICAgICBpZiAoIXJlcy5vaykgeyBhbGVydCgnRmFpbGVkOiAnICsgKGRhdGE/LmVycm9yPy5tZXNzYWdlIHx8IHJlcy5zdGF0dXNUZXh0KSk7IHJldHVybjsgfVxuICAgICAgLy8gU2hvdyB0aGUgYXBpX2tleSBPTkNFIGluIGEgZGlhbG9nXG4gICAgICBhbGVydChgXHUyNzA1IEhvc3QgcmVnaXN0ZXJlZCFcXG5cXG5pZDogJHtkYXRhLmRhdGEuaG9zdC5pZH1cXG5sYWJlbDogJHtkYXRhLmRhdGEuaG9zdC5sYWJlbH1cXG50eXBlOiAke2RhdGEuZGF0YS5ob3N0LnR5cGV9XFxuXFxuXHVEODNEXHVERDExIEFQSSBLRVkgKHNhdmUgdGhpcyBOT1cgXHUyMDE0IHdvbid0IGJlIHNob3duIGFnYWluKTpcXG5cXG4ke2RhdGEuZGF0YS5hcGlfa2V5fVxcblxcblNlbmQgdGhpcyBrZXkgYXM6IEF1dGhvcml6YXRpb246IEJlYXJlciA8YXBpX2tleT5cXG5UbyBlbmRwb2ludDogUE9TVCAvYXBpL3YxL3NlY3VyaXR5L2V2ZW50cy9pbmdlc3Qgb3IgL2V2ZW50cy9iYXRjaGApO1xuICAgICAgcmVmcmVzaEhvc3RzKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgYWxlcnQoJ0ZhaWxlZDogJyArIGUubWVzc2FnZSk7XG4gICAgfVxuICB9XG5cbiAgLy8gPT09PT09PT09PT09PSBIRUxQRVJTID09PT09PT09PT09PT1cbiAgZnVuY3Rpb24gZXNjYXBlSHRtbChzKSB7XG4gICAgcmV0dXJuIFN0cmluZyhzKS5yZXBsYWNlKC9bJjw+XCInXS9nLCBjID0+ICh7JyYnOicmYW1wOycsJzwnOicmbHQ7JywnPic6JyZndDsnLCdcIic6JyZxdW90OycsXCInXCI6JyYjMzk7J31bY10pKTtcbiAgfVxuICBmdW5jdGlvbiBkZWJvdW5jZShmbiwgbXMpIHtcbiAgICBsZXQgdDsgcmV0dXJuIGZ1bmN0aW9uKCkgeyBjbGVhclRpbWVvdXQodCk7IHQgPSBzZXRUaW1lb3V0KCgpID0+IGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyksIG1zKTsgfTtcbiAgfVxufSkoKTs7XG4vLyA9PT09PT09PT09IFdFQVRIRVIgV0lER0VUID09PT09PT09PT1cbihmdW5jdGlvbigpIHtcbiAgY29uc3QgZXJyb3JIYW5kbGVyID0gbmV3IEVycm9ySGFuZGxlcigpO1xuICAvLyBJbmplY3QgbW9kYWwgSFRNTFxuICBpbmplY3RNb2RhbCgnd2VhdGhlci1tb2RhbCcsIGA8ZGl2IGlkPVwid2VhdGhlci1tb2RhbFwiIGNsYXNzPVwid2VhdGhlci1tb2RhbFwiPjxkaXYgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsLWNvbnRlbnRcIj48aDM+V2VhdGhlciBTZXR0aW5nczwvaDM+XG4gICAgPGxhYmVsIGZvcj1cIndlYXRoZXItbG9jYXRpb24taW5wdXRcIj5Mb2NhdGlvbjo8L2xhYmVsPlxuICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGlkPVwid2VhdGhlci1sb2NhdGlvbi1pbnB1dFwiIHBsYWNlaG9sZGVyPVwiQ2l0eSBuYW1lIG9yIFpJUCAoZS5nLiwgSGFtYnVyZywgOTAyMTApXCIgbWF4bGVuZ3RoPVwiMTAwXCI+XG4gICAgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC43OHJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLXRvcDogNHB4O1wiPkVudGVyIGEgY2l0eSBuYW1lLCBwb3N0YWwgY29kZSwgb3IgJmxkcXVvO0NpdHksIENvdW50cnkmcmRxdW87PC9kaXY+XG4gICAgPGRpdiBzdHlsZT1cIm1hcmdpbi10b3A6IDE0cHg7IHBhZGRpbmctdG9wOiAxMnB4OyBib3JkZXItdG9wOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcIj5cbiAgICAgIDxsYWJlbCBzdHlsZT1cImRpc3BsYXk6IGJsb2NrOyBtYXJnaW4tYm90dG9tOiA4cHg7IGZvbnQtd2VpZ2h0OiA2MDA7IGNvbG9yOiB2YXIoLS1mZyk7XCI+VW5pdHM8L2xhYmVsPlxuICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGdhcDogOHB4O1wiPlxuICAgICAgICA8bGFiZWwgY2xhc3M9XCJ3ZWF0aGVyLXVuaXQtb3B0aW9uXCI+PGlucHV0IHR5cGU9XCJyYWRpb1wiIG5hbWU9XCJ3ZWF0aGVyLXVuaXQtcmFkaW9cIiB2YWx1ZT1cImltcGVyaWFsXCI+PHNwYW4gY2xhc3M9XCJ3ZWF0aGVyLXVuaXQtY2FyZFwiPiZkZWc7RiAvIG1waDwvc3Bhbj48L2xhYmVsPlxuICAgICAgICA8bGFiZWwgY2xhc3M9XCJ3ZWF0aGVyLXVuaXQtb3B0aW9uXCI+PGlucHV0IHR5cGU9XCJyYWRpb1wiIG5hbWU9XCJ3ZWF0aGVyLXVuaXQtcmFkaW9cIiB2YWx1ZT1cIm1ldHJpY1wiPjxzcGFuIGNsYXNzPVwid2VhdGhlci11bml0LWNhcmRcIj4mZGVnO0MgLyBrbS9oPC9zcGFuPjwvbGFiZWw+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwid2VhdGhlci1tb2RhbC1idXR0b25zXCI+PGJ1dHRvbiBpZD1cIndlYXRoZXItY2FuY2VsXCI+Q2FuY2VsPC9idXR0b24+PGJ1dHRvbiBpZD1cIndlYXRoZXItc2F2ZVwiPlNhdmU8L2J1dHRvbj48L2Rpdj48L2Rpdj48L2Rpdj5gKTtcblxuICAvKiBXZWF0aGVyIFdpZGdldCBcdTIwMTQgcG93ZXJlZCBieSBPcGVuLU1ldGVvIChmcmVlLCBubyBBUEkga2V5KSAqL1xuICBjb25zdCBMT0NBVElPTl9LRVkgPSAnd2VhdGhlci1sb2NhdGlvbic7XG4gIGNvbnN0IExFR0FDWV9LRVkgPSAnd2VhdGhlci16aXAnO1xuICBjb25zdCBHRU9fQ0FDSEVfS0VZID0gJ3dlYXRoZXItZ2VvJztcbiAgY29uc3QgVU5JVF9LRVkgPSAnd2VhdGhlci11bml0JztcblxuICAvLyBNaWdyYXRlIGZyb20gb2xkIFpJUC1vbmx5IGtleVxuICBpZiAoIXNhZmVHZXQoTE9DQVRJT05fS0VZKSAmJiBzYWZlR2V0KExFR0FDWV9LRVkpKSB7XG4gICAgc2FmZVNldChMT0NBVElPTl9LRVksIHNhZmVHZXQoTEVHQUNZX0tFWSkpO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0VW5pdCgpIHtcbiAgICByZXR1cm4gc2FmZUdldChVTklUX0tFWSkgfHwgJ2ltcGVyaWFsJztcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldFdlYXRoZXJFbGVtZW50cygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaWNvbjogZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLndlYXRoZXItaWNvbicpLFxuICAgICAgdGVtcDogZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLndlYXRoZXItdGVtcCcpLFxuICAgICAgY29uZGl0aW9uOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcud2VhdGhlci1jb25kaXRpb24nKSxcbiAgICAgIGxvY2F0aW9uOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcud2VhdGhlci1sb2NhdGlvbicpLFxuICAgICAgd2luZDogZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLndlYXRoZXItd2luZCcpXG4gICAgfTtcbiAgfVxuXG4gIC8vIFdNTyBXZWF0aGVyIENvZGUgbWFwcGluZ1xuICBjb25zdCB3bW9EZXNjcmlwdGlvbnMgPSB7XG4gICAgMDogJ0NsZWFyIHNreScsIDE6ICdNYWlubHkgY2xlYXInLCAyOiAnUGFydGx5IGNsb3VkeScsIDM6ICdPdmVyY2FzdCcsXG4gICAgNDU6ICdGb2cnLCA0ODogJ1JpbWUgZm9nJyxcbiAgICA1MTogJ0xpZ2h0IGRyaXp6bGUnLCA1MzogJ0RyaXp6bGUnLCA1NTogJ0RlbnNlIGRyaXp6bGUnLFxuICAgIDU2OiAnRnJlZXppbmcgZHJpenpsZScsIDU3OiAnRGVuc2UgZnJlZXppbmcgZHJpenpsZScsXG4gICAgNjE6ICdMaWdodCByYWluJywgNjM6ICdNb2RlcmF0ZSByYWluJywgNjU6ICdIZWF2eSByYWluJyxcbiAgICA2NjogJ0xpZ2h0IGZyZWV6aW5nIHJhaW4nLCA2NzogJ0hlYXZ5IGZyZWV6aW5nIHJhaW4nLFxuICAgIDcxOiAnTGlnaHQgc25vdycsIDczOiAnTW9kZXJhdGUgc25vdycsIDc1OiAnSGVhdnkgc25vdycsIDc3OiAnU25vdyBncmFpbnMnLFxuICAgIDgwOiAnTGlnaHQgc2hvd2VycycsIDgxOiAnTW9kZXJhdGUgc2hvd2VycycsIDgyOiAnVmlvbGVudCBzaG93ZXJzJyxcbiAgICA4NTogJ0xpZ2h0IHNub3cgc2hvd2VycycsIDg2OiAnSGVhdnkgc25vdyBzaG93ZXJzJyxcbiAgICA5NTogJ1RodW5kZXJzdG9ybScsIDk2OiAnVGh1bmRlcnN0b3JtIHdpdGggaGFpbCcsIDk5OiAnU2V2ZXJlIHRodW5kZXJzdG9ybSdcbiAgfTtcblxuICBjb25zdCB3bW9JY29ucyA9IHtcbiAgICAwOiAnXHUyNjAwXHVGRTBGJywgMTogJ1x1RDgzQ1x1REYyNFx1RkUwRicsIDI6ICdcdTI2QzUnLCAzOiAnXHUyNjAxXHVGRTBGJyxcbiAgICA0NTogJ1x1RDgzQ1x1REYyQlx1RkUwRicsIDQ4OiAnXHVEODNDXHVERjJCXHVGRTBGJyxcbiAgICA1MTogJ1x1RDgzQ1x1REYyNlx1RkUwRicsIDUzOiAnXHVEODNDXHVERjI2XHVGRTBGJywgNTU6ICdcdUQ4M0NcdURGMjZcdUZFMEYnLFxuICAgIDU2OiAnXHVEODNDXHVERjI4XHVGRTBGJywgNTc6ICdcdUQ4M0NcdURGMjhcdUZFMEYnLFxuICAgIDYxOiAnXHVEODNDXHVERjI2XHVGRTBGJywgNjM6ICdcdUQ4M0NcdURGMjdcdUZFMEYnLCA2NTogJ1x1RDgzQ1x1REYyN1x1RkUwRicsXG4gICAgNjY6ICdcdUQ4M0NcdURGMjhcdUZFMEYnLCA2NzogJ1x1RDgzQ1x1REYyOFx1RkUwRicsXG4gICAgNzE6ICdcdUQ4M0NcdURGMjhcdUZFMEYnLCA3MzogJ1x1Mjc0NFx1RkUwRicsIDc1OiAnXHUyNzQ0XHVGRTBGJywgNzc6ICdcdTI3NDRcdUZFMEYnLFxuICAgIDgwOiAnXHVEODNDXHVERjI2XHVGRTBGJywgODE6ICdcdUQ4M0NcdURGMjdcdUZFMEYnLCA4MjogJ1x1RDgzQ1x1REYyN1x1RkUwRicsXG4gICAgODU6ICdcdUQ4M0NcdURGMjhcdUZFMEYnLCA4NjogJ1x1Mjc0NFx1RkUwRicsXG4gICAgOTU6ICdcdTI2QzhcdUZFMEYnLCA5NjogJ1x1MjZDOFx1RkUwRicsIDk5OiAnXHUyNkM4XHVGRTBGJ1xuICB9O1xuXG4gIC8vIFdpbmQgZGlyZWN0aW9uIGZyb20gZGVncmVlc1xuICBjb25zdCB3aW5kRGlycyA9IFsnTicsJ05ORScsJ05FJywnRU5FJywnRScsJ0VTRScsJ1NFJywnU1NFJywnUycsJ1NTVycsJ1NXJywnV1NXJywnVycsJ1dOVycsJ05XJywnTk5XJ107XG4gIGZ1bmN0aW9uIGRlZ1RvRGlyKGRlZykge1xuICAgIHJldHVybiB3aW5kRGlyc1tNYXRoLnJvdW5kKGRlZyAvIDIyLjUpICUgMTZdO1xuICB9XG5cbiAgLy8gR2VvY29kZSBsb2NhdGlvbiB2aWEgT3Blbi1NZXRlbywgd2l0aCBsb2NhbFN0b3JhZ2UgY2FjaGVcbiAgYXN5bmMgZnVuY3Rpb24gZ2VvY29kZUxvY2F0aW9uKHF1ZXJ5KSB7XG4gICAgY29uc3QgY2FjaGVkID0gc2FmZUdldChHRU9fQ0FDSEVfS0VZKTtcbiAgICBpZiAoY2FjaGVkKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBnZW8gPSBKU09OLnBhcnNlKGNhY2hlZCk7XG4gICAgICAgIGlmIChnZW8ucXVlcnkgPT09IHF1ZXJ5KSByZXR1cm4gZ2VvO1xuICAgICAgfSBjYXRjaCB7fVxuICAgIH1cbiAgICBjb25zdCByZXNwID0gYXdhaXQgZmV0Y2goYGh0dHBzOi8vZ2VvY29kaW5nLWFwaS5vcGVuLW1ldGVvLmNvbS92MS9zZWFyY2g/bmFtZT0ke2VuY29kZVVSSUNvbXBvbmVudChxdWVyeSl9JmNvdW50PTEmbGFuZ3VhZ2U9ZW4mZm9ybWF0PWpzb25gKTtcbiAgICBpZiAoIXJlc3Aub2spIHRocm93IG5ldyBFcnJvcignR2VvY29kaW5nIGZhaWxlZCcpO1xuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwLmpzb24oKTtcbiAgICBpZiAoIWRhdGEucmVzdWx0cyB8fCAhZGF0YS5yZXN1bHRzLmxlbmd0aCkgdGhyb3cgbmV3IEVycm9yKCdMb2NhdGlvbiBub3QgZm91bmQnKTtcbiAgICBjb25zdCByID0gZGF0YS5yZXN1bHRzWzBdO1xuICAgIGNvbnN0IGdlbyA9IHtcbiAgICAgIHF1ZXJ5LFxuICAgICAgbGF0OiByLmxhdGl0dWRlLFxuICAgICAgbG9uOiByLmxvbmdpdHVkZSxcbiAgICAgIGNpdHk6IHIubmFtZSxcbiAgICAgIHN0YXRlOiByLmFkbWluMSB8fCAnJyxcbiAgICAgIGNvdW50cnk6IHIuY291bnRyeSB8fCAnJyxcbiAgICAgIGNvdW50cnlDb2RlOiByLmNvdW50cnlfY29kZSB8fCAnJ1xuICAgIH07XG4gICAgc2FmZVNldChHRU9fQ0FDSEVfS0VZLCBKU09OLnN0cmluZ2lmeShnZW8pKTtcbiAgICByZXR1cm4gZ2VvO1xuICB9XG5cbiAgZnVuY3Rpb24gZm9ybWF0TG9jYXRpb24oZ2VvKSB7XG4gICAgLy8gRm9yIFVTIGxvY2F0aW9ucyBzaG93IFwiQ2l0eSwgU3RhdGVcIiwgZm9yIG90aGVycyBzaG93IFwiQ2l0eSwgQ291bnRyeVwiXG4gICAgaWYgKGdlby5jb3VudHJ5Q29kZSA9PT0gJ1VTJyAmJiBnZW8uc3RhdGUpIHtcbiAgICAgIHJldHVybiBgJHtnZW8uY2l0eX0sICR7Z2VvLnN0YXRlfWA7XG4gICAgfVxuICAgIGlmIChnZW8uY291bnRyeSkge1xuICAgICAgcmV0dXJuIGAke2dlby5jaXR5fSwgJHtnZW8uY291bnRyeX1gO1xuICAgIH1cbiAgICByZXR1cm4gZ2VvLmNpdHk7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBmZXRjaFdlYXRoZXIobG9jYXRpb24pIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgZ2VvID0gYXdhaXQgZ2VvY29kZUxvY2F0aW9uKGxvY2F0aW9uKTtcbiAgICAgIGNvbnN0IHVuaXQgPSBnZXRVbml0KCk7XG4gICAgICBjb25zdCB0ZW1wVW5pdCA9IHVuaXQgPT09ICdtZXRyaWMnID8gJ2NlbHNpdXMnIDogJ2ZhaHJlbmhlaXQnO1xuICAgICAgY29uc3Qgd2luZFVuaXQgPSB1bml0ID09PSAnbWV0cmljJyA/ICdrbWgnIDogJ21waCc7XG4gICAgICBjb25zdCB1cmwgPSBgaHR0cHM6Ly9hcGkub3Blbi1tZXRlby5jb20vdjEvZm9yZWNhc3Q/bGF0aXR1ZGU9JHtnZW8ubGF0fSZsb25naXR1ZGU9JHtnZW8ubG9ufSZjdXJyZW50PXRlbXBlcmF0dXJlXzJtLHdlYXRoZXJfY29kZSx3aW5kX3NwZWVkXzEwbSx3aW5kX2RpcmVjdGlvbl8xMG0mdGVtcGVyYXR1cmVfdW5pdD0ke3RlbXBVbml0fSZ3aW5kX3NwZWVkX3VuaXQ9JHt3aW5kVW5pdH1gO1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IGZldGNoKHVybCk7XG4gICAgICBpZiAoIXJlc3Aub2spIHRocm93IG5ldyBFcnJvcignV2VhdGhlciBmZXRjaCBmYWlsZWQnKTtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwLmpzb24oKTtcbiAgICAgIGNvbnN0IGMgPSBkYXRhLmN1cnJlbnQ7XG4gICAgICBjb25zdCBjb2RlID0gYy53ZWF0aGVyX2NvZGU7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0ZW1wOiBNYXRoLnJvdW5kKGMudGVtcGVyYXR1cmVfMm0pLFxuICAgICAgICBjb25kaXRpb246IHdtb0Rlc2NyaXB0aW9uc1tjb2RlXSB8fCAnVW5rbm93bicsXG4gICAgICAgIGljb246IHdtb0ljb25zW2NvZGVdIHx8ICdcdUQ4M0NcdURGMjRcdUZFMEYnLFxuICAgICAgICBsb2NhdGlvblN0cjogZm9ybWF0TG9jYXRpb24oZ2VvKSxcbiAgICAgICAgd2luZFNwZWVkOiBNYXRoLnJvdW5kKGMud2luZF9zcGVlZF8xMG0pLFxuICAgICAgICB3aW5kRGlyOiBkZWdUb0RpcihjLndpbmRfZGlyZWN0aW9uXzEwbSksXG4gICAgICAgIHVuaXRcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUud2FybignV2VhdGhlciBmZXRjaCBmYWlsZWQ6JywgZXJyb3IpO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gdXBkYXRlV2VhdGhlcigpIHtcbiAgICBjb25zdCB3ZWF0aGVyV2lkZ2V0ID0gZ2V0V2VhdGhlckVsZW1lbnRzKCk7XG4gICAgaWYgKCF3ZWF0aGVyV2lkZ2V0Lmljb24gfHwgIXdlYXRoZXJXaWRnZXQudGVtcCB8fCAhd2VhdGhlcldpZGdldC5jb25kaXRpb24gfHwgIXdlYXRoZXJXaWRnZXQubG9jYXRpb24gfHwgIXdlYXRoZXJXaWRnZXQud2luZCkge1xuICAgICAgY29uc29sZS53YXJuKCdXZWF0aGVyIHdpZGdldCBlbGVtZW50cyBub3QgZm91bmQnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBsb2NhdGlvbiA9IHNhZmVHZXQoTE9DQVRJT05fS0VZKTtcbiAgICBpZiAoIWxvY2F0aW9uKSB7XG4gICAgICB3ZWF0aGVyV2lkZ2V0LmxvY2F0aW9uLnRleHRDb250ZW50ID0gJ1NldCBMb2NhdGlvbic7XG4gICAgICB3ZWF0aGVyV2lkZ2V0LnRlbXAudGV4dENvbnRlbnQgPSAnLS1cXHUwMEIwJztcbiAgICAgIHdlYXRoZXJXaWRnZXQuY29uZGl0aW9uLnRleHRDb250ZW50ID0gJ0NsaWNrIFxcdTI2OTlcXHVGRTBGIHRvIGNvbmZpZ3VyZSc7XG4gICAgICB3ZWF0aGVyV2lkZ2V0LndpbmQudGV4dENvbnRlbnQgPSAnLS0nO1xuICAgICAgd2VhdGhlcldpZGdldC5pY29uLmlubmVySFRNTCA9ICc8c3BhbiBjbGFzcz1cIndlYXRoZXItZW1vamlcIj5cXHVEODNDXFx1REYyNFxcdUZFMEY8L3NwYW4+JztcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3Qgd2VhdGhlciA9IGF3YWl0IGZldGNoV2VhdGhlcihsb2NhdGlvbik7XG4gICAgICBpZiAod2VhdGhlcikge1xuICAgICAgICBjb25zdCB0ZW1wU3VmZml4ID0gd2VhdGhlci51bml0ID09PSAnbWV0cmljJyA/ICdcXHUwMEIwQycgOiAnXFx1MDBCMEYnO1xuICAgICAgICBjb25zdCB3aW5kTGFiZWwgPSB3ZWF0aGVyLnVuaXQgPT09ICdtZXRyaWMnID8gJ2ttL2gnIDogJ21waCc7XG4gICAgICAgIHdlYXRoZXJXaWRnZXQubG9jYXRpb24udGV4dENvbnRlbnQgPSB3ZWF0aGVyLmxvY2F0aW9uU3RyO1xuICAgICAgICB3ZWF0aGVyV2lkZ2V0LnRlbXAudGV4dENvbnRlbnQgPSBgJHt3ZWF0aGVyLnRlbXB9JHt0ZW1wU3VmZml4fWA7XG4gICAgICAgIHdlYXRoZXJXaWRnZXQuY29uZGl0aW9uLnRleHRDb250ZW50ID0gd2VhdGhlci5jb25kaXRpb247XG4gICAgICAgIHdlYXRoZXJXaWRnZXQud2luZC50ZXh0Q29udGVudCA9IGBXaW5kOiAke3dlYXRoZXIud2luZFNwZWVkfSAke3dpbmRMYWJlbH0gJHt3ZWF0aGVyLndpbmREaXJ9YDtcbiAgICAgICAgd2VhdGhlcldpZGdldC5pY29uLmlubmVySFRNTCA9IGA8c3BhbiBjbGFzcz1cIndlYXRoZXItZW1vamlcIj4ke2VzY2FwZUh0bWwod2VhdGhlci5pY29uKX08L3NwYW4+YDtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgZXJyb3JIYW5kbGVyLmxvZ0Vycm9yKCdbV2VhdGhlcl0gVXBkYXRlIEVycm9yJywgZXJyb3IsIHsgZnVuY3Rpb246ICd1cGRhdGVXZWF0aGVyJyB9KTtcbiAgICAgIHdlYXRoZXJXaWRnZXQubG9jYXRpb24udGV4dENvbnRlbnQgPSAnV2VhdGhlciBFcnJvcic7XG4gICAgICB3ZWF0aGVyV2lkZ2V0LnRlbXAudGV4dENvbnRlbnQgPSAnRXJyb3InO1xuICAgICAgd2VhdGhlcldpZGdldC5jb25kaXRpb24udGV4dENvbnRlbnQgPSAnRmFpbGVkIHRvIGxvYWQnO1xuICAgICAgd2VhdGhlcldpZGdldC53aW5kLnRleHRDb250ZW50ID0gJy0tJztcbiAgICB9XG4gIH1cblxuICAvLyBXZWF0aGVyIHNldHRpbmdzIG1vZGFsXG4gIGNvbnN0IG1vZGFsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3dlYXRoZXItbW9kYWwnKTtcbiAgY29uc3QgbG9jYXRpb25JbnB1dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd3ZWF0aGVyLWxvY2F0aW9uLWlucHV0Jyk7XG5cbiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3dlYXRoZXItc2V0dGluZ3MnKT8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgbG9jYXRpb25JbnB1dC52YWx1ZSA9IHNhZmVHZXQoTE9DQVRJT05fS0VZKSB8fCAnJztcbiAgICAvLyBTZXQgdW5pdCByYWRpb1xuICAgIGNvbnN0IHVuaXQgPSBnZXRVbml0KCk7XG4gICAgY29uc3QgcmFkaW8gPSBtb2RhbC5xdWVyeVNlbGVjdG9yKGBpbnB1dFtuYW1lPVwid2VhdGhlci11bml0LXJhZGlvXCJdW3ZhbHVlPVwiJHt1bml0fVwiXWApO1xuICAgIGlmIChyYWRpbykgcmFkaW8uY2hlY2tlZCA9IHRydWU7XG4gICAgbW9kYWwuY2xhc3NMaXN0LmFkZCgnc2hvdycpO1xuICAgIGxvY2F0aW9uSW5wdXQuZm9jdXMoKTtcbiAgfSk7XG5cbiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3dlYXRoZXItY2FuY2VsJyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgIG1vZGFsLmNsYXNzTGlzdC5yZW1vdmUoJ3Nob3cnKTtcbiAgfSk7XG5cbiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3dlYXRoZXItc2F2ZScpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICBjb25zdCBsb2MgPSBsb2NhdGlvbklucHV0LnZhbHVlLnRyaW0oKTtcbiAgICBpZiAobG9jKSB7XG4gICAgICAvLyBDbGVhciBnZW8gY2FjaGUgd2hlbiBsb2NhdGlvbiBjaGFuZ2VzIHNvIGl0IHJlLWdlb2NvZGVzXG4gICAgICBjb25zdCBvbGRMb2MgPSBzYWZlR2V0KExPQ0FUSU9OX0tFWSk7XG4gICAgICBpZiAob2xkTG9jICE9PSBsb2MpIHNhZmVTZXQoR0VPX0NBQ0hFX0tFWSwgJycpO1xuICAgICAgc2FmZVNldChMT0NBVElPTl9LRVksIGxvYyk7XG4gICAgICAvLyBTYXZlIHVuaXQgcHJlZmVyZW5jZVxuICAgICAgY29uc3QgdW5pdFJhZGlvID0gbW9kYWwucXVlcnlTZWxlY3RvcignaW5wdXRbbmFtZT1cIndlYXRoZXItdW5pdC1yYWRpb1wiXTpjaGVja2VkJyk7XG4gICAgICBjb25zdCBuZXdVbml0ID0gdW5pdFJhZGlvID8gdW5pdFJhZGlvLnZhbHVlIDogJ2ltcGVyaWFsJztcbiAgICAgIGNvbnN0IG9sZFVuaXQgPSBnZXRVbml0KCk7XG4gICAgICBzYWZlU2V0KFVOSVRfS0VZLCBuZXdVbml0KTtcbiAgICAgIC8vIENsZWFyIGdlbyBjYWNoZSBpZiB1bml0IGNoYW5nZWQgKG5lZWQgZnJlc2ggd2VhdGhlciBkYXRhKVxuICAgICAgaWYgKG9sZFVuaXQgIT09IG5ld1VuaXQpIHNhZmVTZXQoR0VPX0NBQ0hFX0tFWSwgJycpO1xuICAgICAgbW9kYWwuY2xhc3NMaXN0LnJlbW92ZSgnc2hvdycpO1xuICAgICAgdXBkYXRlV2VhdGhlcigpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzaG93Tm90aWZpY2F0aW9uKCdQbGVhc2UgZW50ZXIgYSBsb2NhdGlvbiAoZS5nLiwgSGFtYnVyZywgTG9uZG9uLCA5MDIxMCknLCAnd2FybmluZycpO1xuICAgIH1cbiAgfSk7XG5cbiAgd2lyZU1vZGFsKG1vZGFsKTtcblxuICAvLyBDbG9zZSBtb2RhbCBvbiBFc2NhcGUga2V5XG4gIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCAoZSkgPT4ge1xuICAgIGlmIChlLmtleSA9PT0gJ0VzY2FwZScgJiYgbW9kYWwuY2xhc3NMaXN0LmNvbnRhaW5zKCdzaG93JykpIHtcbiAgICAgIG1vZGFsLmNsYXNzTGlzdC5yZW1vdmUoJ3Nob3cnKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIEluaXRpYWxpemUgd2VhdGhlclxuICB1cGRhdGVXZWF0aGVyKCk7XG4gIC8vIFVwZGF0ZSB3ZWF0aGVyIGV2ZXJ5IDEwIG1pbnV0ZXNcbiAgc2V0SW50ZXJ2YWwodXBkYXRlV2VhdGhlciwgREMuUE9MTC5XRUFUSEVSKTtcbn0pKCk7XG47XG4vLyA9PT09PT09PT09IERJR0lUQUwgQ0xPQ0sgV0lER0VUID09PT09PT09PT1cbihmdW5jdGlvbigpIHtcbiAgY29uc3Qgd2lkZ2V0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Nsb2NrLXdpZGdldCcpO1xuICBjb25zdCByZW5kZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2xvY2stcmVuZGVyJyk7XG4gIGlmICghd2lkZ2V0IHx8ICFyZW5kZXIpIHJldHVybjtcblxuICBjb25zdCBEQVlTID0gWydTdW5kYXknLCdNb25kYXknLCdUdWVzZGF5JywnV2VkbmVzZGF5JywnVGh1cnNkYXknLCdGcmlkYXknLCdTYXR1cmRheSddO1xuICBjb25zdCBNT05USFMgPSBbJ0phbnVhcnknLCdGZWJydWFyeScsJ01hcmNoJywnQXByaWwnLCdNYXknLCdKdW5lJywnSnVseScsJ0F1Z3VzdCcsJ1NlcHRlbWJlcicsJ09jdG9iZXInLCdOb3ZlbWJlcicsJ0RlY2VtYmVyJ107XG4gIGNvbnN0IFJPTUFOID0gWydYSUknLCdJJywnSUknLCdJSUknLCdJVicsJ1YnLCdWSScsJ1ZJSScsJ1ZJSUknLCdJWCcsJ1gnLCdYSSddO1xuXG4gIGxldCBjdXJyZW50U3R5bGUgPSBzYWZlR2V0KCdjbG9jay1zdHlsZScpIHx8ICdkZWZhdWx0JztcbiAgbGV0IGxhc3RDaGltZUhvdXIgPSAtMTtcbiAgbGV0IGNoaW1lUGxheWluZyA9IGZhbHNlO1xuICBsZXQgcHJldkZsaXBEaWdpdHMgPSAnJztcbiAgbGV0IGFjdGl2ZUxheW91dCA9ICcnO1xuICBsZXQgZGlnaXRhbFJlZnMgPSBudWxsO1xuICBsZXQgdGlja1RpbWVyID0gbnVsbDtcblxuICAvLyA9PT09PSBDSElNRVMgPT09PT1cbiAgZnVuY3Rpb24gcGxheUNoaW1lcyhjb3VudCkge1xuICAgIGlmIChjaGltZVBsYXlpbmcpIHJldHVybjtcbiAgICBpZiAoc2FmZUdldCgnY2xvY2stY2hpbWVzJykgIT09ICd0cnVlJykgcmV0dXJuO1xuICAgIGNoaW1lUGxheWluZyA9IHRydWU7XG4gICAgY29uc3Qgdm9sID0gcGFyc2VJbnQoc2FmZUdldCgnY2xvY2stY2hpbWUtdm9sdW1lJykgfHwgJzUwJywgMTApIC8gMTAwO1xuICAgIGxldCBpID0gMDtcbiAgICBmdW5jdGlvbiBzdHJpa2UoKSB7XG4gICAgICBpZiAoaSA+PSBjb3VudCkgeyBjaGltZVBsYXlpbmcgPSBmYWxzZTsgcmV0dXJuOyB9XG4gICAgICBjb25zdCBiZWxsID0gbmV3IEF1ZGlvKCcvYXNzZXRzL3NvdW5kcy9jaHVyY2gtYmVsbC5tcDMnKTtcbiAgICAgIGJlbGwudm9sdW1lID0gdm9sO1xuICAgICAgYmVsbC5wbGF5KCkuY2F0Y2goKCkgPT4ge30pO1xuICAgICAgaSsrO1xuICAgICAgaWYgKGkgPCBjb3VudCkgc2V0VGltZW91dChzdHJpa2UsIDI1MDApO1xuICAgICAgZWxzZSBzZXRUaW1lb3V0KCgpID0+IHsgY2hpbWVQbGF5aW5nID0gZmFsc2U7IH0sIDI1MDApO1xuICAgIH1cbiAgICBzdHJpa2UoKTtcbiAgfVxuXG4gIC8vID09PT09IERBVEUgU1RSSU5HID09PT09XG4gIGZ1bmN0aW9uIGRhdGVTdHIobm93KSB7XG4gICAgcmV0dXJuIERBWVNbbm93LmdldERheSgpXSArICcsICcgKyBNT05USFNbbm93LmdldE1vbnRoKCldICsgJyAnICsgbm93LmdldERhdGUoKSArICcsICcgKyBub3cuZ2V0RnVsbFllYXIoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc2V0UmVuZGVyTGF5b3V0KCkge1xuICAgIGFjdGl2ZUxheW91dCA9ICcnO1xuICAgIGRpZ2l0YWxSZWZzID0gbnVsbDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGVuc3VyZURpZ2l0YWxMYXlvdXQoKSB7XG4gICAgaWYgKGFjdGl2ZUxheW91dCAhPT0gJ2RpZ2l0YWwnKSB7XG4gICAgICByZW5kZXIuaW5uZXJIVE1MID1cbiAgICAgICAgJzxkaXYgY2xhc3M9XCJjbG9jay10aW1lXCI+PHNwYW4gY2xhc3M9XCJjbG9jay1tYWluXCI+PC9zcGFuPjxzcGFuIGNsYXNzPVwiY2xvY2stc2Vjb25kc1wiPjwvc3Bhbj48c3BhbiBjbGFzcz1cImNsb2NrLWFtcG1cIj48L3NwYW4+PC9kaXY+JyArXG4gICAgICAgICc8ZGl2IGNsYXNzPVwiY2xvY2stZGF0ZVwiPjwvZGl2Pic7XG4gICAgICBkaWdpdGFsUmVmcyA9IHtcbiAgICAgICAgbWFpbjogcmVuZGVyLnF1ZXJ5U2VsZWN0b3IoJy5jbG9jay1tYWluJyksXG4gICAgICAgIHNlY29uZHM6IHJlbmRlci5xdWVyeVNlbGVjdG9yKCcuY2xvY2stc2Vjb25kcycpLFxuICAgICAgICBhbXBtOiByZW5kZXIucXVlcnlTZWxlY3RvcignLmNsb2NrLWFtcG0nKSxcbiAgICAgICAgZGF0ZTogcmVuZGVyLnF1ZXJ5U2VsZWN0b3IoJy5jbG9jay1kYXRlJylcbiAgICAgIH07XG4gICAgICBhY3RpdmVMYXlvdXQgPSAnZGlnaXRhbCc7XG4gICAgfVxuICAgIHJldHVybiBkaWdpdGFsUmVmcztcbiAgfVxuXG4gIC8vID09PT09IFNUWUxFIFJFTkRFUkVSUyA9PT09PVxuXG4gIGZ1bmN0aW9uIHJlbmRlckRlZmF1bHQobm93KSB7XG4gICAgY29uc3QgaDI0ID0gbm93LmdldEhvdXJzKCksIG0gPSBub3cuZ2V0TWludXRlcygpLCBzID0gbm93LmdldFNlY29uZHMoKTtcbiAgICBjb25zdCBhbXBtID0gaDI0ID49IDEyID8gJ1BNJyA6ICdBTSc7XG4gICAgY29uc3QgaCA9IGgyNCAlIDEyIHx8IDEyO1xuICAgIGNvbnN0IHJlZnMgPSBlbnN1cmVEaWdpdGFsTGF5b3V0KCk7XG4gICAgcmVmcy5tYWluLnRleHRDb250ZW50ID0gYCR7aH06JHtTdHJpbmcobSkucGFkU3RhcnQoMiwnMCcpfWA7XG4gICAgcmVmcy5zZWNvbmRzLnRleHRDb250ZW50ID0gYDoke1N0cmluZyhzKS5wYWRTdGFydCgyLCcwJyl9YDtcbiAgICByZWZzLmFtcG0udGV4dENvbnRlbnQgPSBhbXBtO1xuICAgIHJlZnMuZGF0ZS50ZXh0Q29udGVudCA9IGRhdGVTdHIobm93KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbmRlckxjZChub3csIGNscykge1xuICAgIGNvbnN0IGgyNCA9IG5vdy5nZXRIb3VycygpLCBtID0gbm93LmdldE1pbnV0ZXMoKSwgcyA9IG5vdy5nZXRTZWNvbmRzKCk7XG4gICAgY29uc3QgYW1wbSA9IGgyNCA+PSAxMiA/ICdQTScgOiAnQU0nO1xuICAgIGNvbnN0IGggPSBoMjQgJSAxMiB8fCAxMjtcbiAgICBjb25zdCByZWZzID0gZW5zdXJlRGlnaXRhbExheW91dCgpO1xuICAgIHJlZnMubWFpbi50ZXh0Q29udGVudCA9IGAke1N0cmluZyhoKS5wYWRTdGFydCgyLCcwJyl9OiR7U3RyaW5nKG0pLnBhZFN0YXJ0KDIsJzAnKX1gO1xuICAgIHJlZnMuc2Vjb25kcy50ZXh0Q29udGVudCA9IGA6JHtTdHJpbmcocykucGFkU3RhcnQoMiwnMCcpfWA7XG4gICAgcmVmcy5hbXBtLnRleHRDb250ZW50ID0gYW1wbTtcbiAgICByZWZzLmRhdGUudGV4dENvbnRlbnQgPSBkYXRlU3RyKG5vdyk7XG4gIH1cblxuICBmdW5jdGlvbiByZW5kZXJGbGlwKG5vdykge1xuICAgIGNvbnN0IGgyNCA9IG5vdy5nZXRIb3VycygpLCBtID0gbm93LmdldE1pbnV0ZXMoKSwgcyA9IG5vdy5nZXRTZWNvbmRzKCk7XG4gICAgY29uc3QgYW1wbSA9IGgyNCA+PSAxMiA/ICdQTScgOiAnQU0nO1xuICAgIGNvbnN0IGggPSBoMjQgJSAxMiB8fCAxMjtcbiAgICBjb25zdCBkaWdpdHMgPSBTdHJpbmcoaCkucGFkU3RhcnQoMiwnICcpICsgU3RyaW5nKG0pLnBhZFN0YXJ0KDIsJzAnKSArIFN0cmluZyhzKS5wYWRTdGFydCgyLCcwJyk7XG5cbiAgICBsZXQgaHRtbCA9ICc8ZGl2IGNsYXNzPVwiZmxpcC1jbG9jay1yb3dcIj4nO1xuICAgIC8vIEhvdXJzXG4gICAgaHRtbCArPSBmbGlwQ2FyZChkaWdpdHNbMF0sIDApO1xuICAgIGh0bWwgKz0gZmxpcENhcmQoZGlnaXRzWzFdLCAxKTtcbiAgICBodG1sICs9ICc8c3BhbiBjbGFzcz1cImZsaXAtY29sb25cIj46PC9zcGFuPic7XG4gICAgLy8gTWludXRlc1xuICAgIGh0bWwgKz0gZmxpcENhcmQoZGlnaXRzWzJdLCAyKTtcbiAgICBodG1sICs9IGZsaXBDYXJkKGRpZ2l0c1szXSwgMyk7XG4gICAgaHRtbCArPSAnPHNwYW4gY2xhc3M9XCJmbGlwLWNvbG9uXCI+Ojwvc3Bhbj4nO1xuICAgIC8vIFNlY29uZHNcbiAgICBodG1sICs9IGZsaXBDYXJkKGRpZ2l0c1s0XSwgNCk7XG4gICAgaHRtbCArPSBmbGlwQ2FyZChkaWdpdHNbNV0sIDUpO1xuICAgIGh0bWwgKz0gYDxzcGFuIGNsYXNzPVwiZmxpcC1hbXBtXCI+JHthbXBtfTwvc3Bhbj5gO1xuICAgIGh0bWwgKz0gJzwvZGl2Pic7XG4gICAgaHRtbCArPSBgPGRpdiBjbGFzcz1cImNsb2NrLWRhdGVcIj4ke2RhdGVTdHIobm93KX08L2Rpdj5gO1xuICAgIHJlbmRlci5pbm5lckhUTUwgPSBodG1sO1xuICAgIGFjdGl2ZUxheW91dCA9ICdmbGlwJztcblxuICAgIC8vIFRyaWdnZXIgZmxpcCBhbmltYXRpb24gb24gY2hhbmdlZCBkaWdpdHNcbiAgICBpZiAocHJldkZsaXBEaWdpdHMpIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgNjsgaSsrKSB7XG4gICAgICAgIGlmIChkaWdpdHNbaV0gIT09IHByZXZGbGlwRGlnaXRzW2ldKSB7XG4gICAgICAgICAgY29uc3QgY2FyZCA9IHJlbmRlci5xdWVyeVNlbGVjdG9yKGAuZmxpcC1jYXJkW2RhdGEtaWR4PVwiJHtpfVwiXWApO1xuICAgICAgICAgIGlmIChjYXJkKSBjYXJkLmNsYXNzTGlzdC5hZGQoJ2ZsaXBwaW5nJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcHJldkZsaXBEaWdpdHMgPSBkaWdpdHM7XG4gIH1cblxuICBmdW5jdGlvbiBmbGlwQ2FyZChkaWdpdCwgaWR4KSB7XG4gICAgY29uc3QgZCA9IGRpZ2l0ID09PSAnICcgPyAnJyA6IGRpZ2l0O1xuICAgIHJldHVybiBgPGRpdiBjbGFzcz1cImZsaXAtY2FyZFwiIGRhdGEtaWR4PVwiJHtpZHh9XCI+PGRpdiBjbGFzcz1cImZsaXAtdG9wXCI+JHtkfTwvZGl2PjxkaXYgY2xhc3M9XCJmbGlwLWJvdHRvbVwiPiR7ZH08L2Rpdj48L2Rpdj5gO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVuZGVyQmluYXJ5KG5vdykge1xuICAgIGNvbnN0IGgyNCA9IG5vdy5nZXRIb3VycygpLCBtID0gbm93LmdldE1pbnV0ZXMoKSwgcyA9IG5vdy5nZXRTZWNvbmRzKCk7XG4gICAgY29uc3QgaCA9IGgyNCAlIDEyIHx8IDEyO1xuICAgIGNvbnN0IGFtcG0gPSBoMjQgPj0gMTIgPyAnUE0nIDogJ0FNJztcbiAgICAvLyA2IGNvbHVtbnM6IEggdGVucywgSCBvbmVzLCBNIHRlbnMsIE0gb25lcywgUyB0ZW5zLCBTIG9uZXNcbiAgICBjb25zdCBjb2xzID0gW1xuICAgICAgTWF0aC5mbG9vcihoIC8gMTApLCBoICUgMTAsXG4gICAgICBNYXRoLmZsb29yKG0gLyAxMCksIG0gJSAxMCxcbiAgICAgIE1hdGguZmxvb3IocyAvIDEwKSwgcyAlIDEwXG4gICAgXTtcblxuICAgIGxldCBodG1sID0gJzxkaXYgY2xhc3M9XCJiaW5hcnktY2xvY2tcIj4nO1xuICAgIC8vIExhYmVsc1xuICAgIGh0bWwgKz0gJzxkaXYgY2xhc3M9XCJiaW5hcnktbGFiZWxzXCI+PHNwYW4+SDwvc3Bhbj48c3Bhbj5IPC9zcGFuPjxzcGFuPk08L3NwYW4+PHNwYW4+TTwvc3Bhbj48c3Bhbj5TPC9zcGFuPjxzcGFuPlM8L3NwYW4+PC9kaXY+JztcbiAgICAvLyA0IHJvd3MgZm9yIGJpdHMgOCw0LDIsMVxuICAgIGZvciAobGV0IGJpdCA9IDM7IGJpdCA+PSAwOyBiaXQtLSkge1xuICAgICAgaHRtbCArPSAnPGRpdiBjbGFzcz1cImJpbmFyeS1yb3dcIj4nO1xuICAgICAgZm9yIChsZXQgY29sID0gMDsgY29sIDwgNjsgY29sKyspIHtcbiAgICAgICAgY29uc3Qgb24gPSAoY29sc1tjb2xdID4+IGJpdCkgJiAxO1xuICAgICAgICBodG1sICs9IGA8ZGl2IGNsYXNzPVwiYmluYXJ5LWRvdCAke29uID8gJ29uJyA6ICcnfVwiPjwvZGl2PmA7XG4gICAgICB9XG4gICAgICBodG1sICs9ICc8L2Rpdj4nO1xuICAgIH1cbiAgICAvLyBWYWx1ZSByb3dcbiAgICBodG1sICs9ICc8ZGl2IGNsYXNzPVwiYmluYXJ5LXZhbHVlc1wiPic7XG4gICAgZm9yIChsZXQgY29sID0gMDsgY29sIDwgNjsgY29sKyspIHtcbiAgICAgIGh0bWwgKz0gYDxzcGFuPiR7Y29sc1tjb2xdfTwvc3Bhbj5gO1xuICAgIH1cbiAgICBodG1sICs9ICc8L2Rpdj4nO1xuICAgIGh0bWwgKz0gYDxkaXYgY2xhc3M9XCJiaW5hcnktYW1wbVwiPiR7YW1wbX08L2Rpdj5gO1xuICAgIGh0bWwgKz0gJzwvZGl2Pic7XG4gICAgaHRtbCArPSBgPGRpdiBjbGFzcz1cImNsb2NrLWRhdGVcIj4ke2RhdGVTdHIobm93KX08L2Rpdj5gO1xuICAgIHJlbmRlci5pbm5lckhUTUwgPSBodG1sO1xuICAgIGFjdGl2ZUxheW91dCA9ICdiaW5hcnknO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVuZGVyQW5hbG9nKG5vdywgdXNlUm9tYW4pIHtcbiAgICBjb25zdCBoID0gbm93LmdldEhvdXJzKCksIG0gPSBub3cuZ2V0TWludXRlcygpLCBzID0gbm93LmdldFNlY29uZHMoKTtcbiAgICBjb25zdCBzaXplID0gMTIwO1xuICAgIGNvbnN0IGN4ID0gc2l6ZSAvIDIsIGN5ID0gc2l6ZSAvIDI7XG5cbiAgICAvLyBBbmdsZXNcbiAgICBjb25zdCBzQW5nbGUgPSAocyAvIDYwKSAqIDM2MCAtIDkwO1xuICAgIGNvbnN0IG1BbmdsZSA9ICgobSArIHMgLyA2MCkgLyA2MCkgKiAzNjAgLSA5MDtcbiAgICBjb25zdCBoQW5nbGUgPSAoKChoICUgMTIpICsgbSAvIDYwKSAvIDEyKSAqIDM2MCAtIDkwO1xuXG4gICAgLy8gTnVtYmVyIGxhYmVsc1xuICAgIGxldCBsYWJlbHMgPSAnJztcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8PSAxMjsgaSsrKSB7XG4gICAgICBjb25zdCBhbmdsZSA9IChpIC8gMTIpICogMiAqIE1hdGguUEkgLSBNYXRoLlBJIC8gMjtcbiAgICAgIGNvbnN0IHIgPSA0NztcbiAgICAgIGNvbnN0IHggPSBjeCArIHIgKiBNYXRoLmNvcyhhbmdsZSk7XG4gICAgICBjb25zdCB5ID0gY3kgKyByICogTWF0aC5zaW4oYW5nbGUpO1xuICAgICAgY29uc3QgbGFiZWwgPSB1c2VSb21hbiA/IFJPTUFOW2kgJSAxMl0gOiBpO1xuICAgICAgY29uc3QgZnMgPSB1c2VSb21hbiA/ICc3JyA6ICc5JztcbiAgICAgIGxhYmVscyArPSBgPHRleHQgeD1cIiR7eH1cIiB5PVwiJHt5fVwiIHRleHQtYW5jaG9yPVwibWlkZGxlXCIgZG9taW5hbnQtYmFzZWxpbmU9XCJjZW50cmFsXCIgZmlsbD1cInZhcigtLWZnKVwiIGZvbnQtc2l6ZT1cIiR7ZnN9XCIgZm9udC13ZWlnaHQ9XCI2MDBcIiBmb250LWZhbWlseT1cIidTYW1pIEdyb3Rlc2snLHNhbnMtc2VyaWZcIj4ke2xhYmVsfTwvdGV4dD5gO1xuICAgIH1cblxuICAgIC8vIFRpY2sgbWFya3NcbiAgICBsZXQgdGlja3MgPSAnJztcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IDYwOyBpKyspIHtcbiAgICAgIGNvbnN0IGFuZ2xlID0gKGkgLyA2MCkgKiAyICogTWF0aC5QSSAtIE1hdGguUEkgLyAyO1xuICAgICAgY29uc3Qgb3V0ZXIgPSA1NjtcbiAgICAgIGNvbnN0IGlubmVyID0gaSAlIDUgPT09IDAgPyA1MiA6IDU0O1xuICAgICAgY29uc3QgeDEgPSBjeCArIGlubmVyICogTWF0aC5jb3MoYW5nbGUpO1xuICAgICAgY29uc3QgeTEgPSBjeSArIGlubmVyICogTWF0aC5zaW4oYW5nbGUpO1xuICAgICAgY29uc3QgeDIgPSBjeCArIG91dGVyICogTWF0aC5jb3MoYW5nbGUpO1xuICAgICAgY29uc3QgeTIgPSBjeSArIG91dGVyICogTWF0aC5zaW4oYW5nbGUpO1xuICAgICAgY29uc3QgdyA9IGkgJSA1ID09PSAwID8gMS41IDogMC41O1xuICAgICAgdGlja3MgKz0gYDxsaW5lIHgxPVwiJHt4MX1cIiB5MT1cIiR7eTF9XCIgeDI9XCIke3gyfVwiIHkyPVwiJHt5Mn1cIiBzdHJva2U9XCJ2YXIoLS1tdXRlZClcIiBzdHJva2Utd2lkdGg9XCIke3d9XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiLz5gO1xuICAgIH1cblxuICAgIGNvbnN0IHN2ZyA9IGA8c3ZnIGNsYXNzPVwiYW5hbG9nLWNsb2NrLXN2Z1wiIHZpZXdCb3g9XCIwIDAgJHtzaXplfSAke3NpemV9XCIgd2lkdGg9XCIke3NpemV9XCIgaGVpZ2h0PVwiJHtzaXplfVwiPlxuICAgICAgPGNpcmNsZSBjeD1cIiR7Y3h9XCIgY3k9XCIke2N5fVwiIHI9XCI1OFwiIGZpbGw9XCJub25lXCIgc3Ryb2tlPVwidmFyKC0tYm9yZGVyKVwiIHN0cm9rZS13aWR0aD1cIjJcIi8+XG4gICAgICAke3RpY2tzfVxuICAgICAgJHtsYWJlbHN9XG4gICAgICA8bGluZSB4MT1cIiR7Y3h9XCIgeTE9XCIke2N5fVwiIHgyPVwiJHtjeCArIDI4ICogTWF0aC5jb3MoaEFuZ2xlICogTWF0aC5QSSAvIDE4MCl9XCIgeTI9XCIke2N5ICsgMjggKiBNYXRoLnNpbihoQW5nbGUgKiBNYXRoLlBJIC8gMTgwKX1cIiBzdHJva2U9XCJ2YXIoLS1mZylcIiBzdHJva2Utd2lkdGg9XCIzXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiLz5cbiAgICAgIDxsaW5lIHgxPVwiJHtjeH1cIiB5MT1cIiR7Y3l9XCIgeDI9XCIke2N4ICsgMzggKiBNYXRoLmNvcyhtQW5nbGUgKiBNYXRoLlBJIC8gMTgwKX1cIiB5Mj1cIiR7Y3kgKyAzOCAqIE1hdGguc2luKG1BbmdsZSAqIE1hdGguUEkgLyAxODApfVwiIHN0cm9rZT1cInZhcigtLWZnKVwiIHN0cm9rZS13aWR0aD1cIjJcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIvPlxuICAgICAgPGxpbmUgeDE9XCIke2N4fVwiIHkxPVwiJHtjeX1cIiB4Mj1cIiR7Y3ggKyA0MiAqIE1hdGguY29zKHNBbmdsZSAqIE1hdGguUEkgLyAxODApfVwiIHkyPVwiJHtjeSArIDQyICogTWF0aC5zaW4oc0FuZ2xlICogTWF0aC5QSSAvIDE4MCl9XCIgc3Ryb2tlPVwiI2U3NGMzY1wiIHN0cm9rZS13aWR0aD1cIjFcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIvPlxuICAgICAgPGNpcmNsZSBjeD1cIiR7Y3h9XCIgY3k9XCIke2N5fVwiIHI9XCIzXCIgZmlsbD1cInZhcigtLWZnKVwiLz5cbiAgICA8L3N2Zz5gO1xuXG4gICAgY29uc3QgYW1wbSA9IG5vdy5nZXRIb3VycygpID49IDEyID8gJ1BNJyA6ICdBTSc7XG4gICAgcmVuZGVyLmlubmVySFRNTCA9IGA8ZGl2IGNsYXNzPVwiYW5hbG9nLWNsb2NrLXdyYXBcIj4ke3N2Z308ZGl2IGNsYXNzPVwiYW5hbG9nLWluZm9cIj48c3BhbiBjbGFzcz1cImFuYWxvZy1kaWdpdGFsXCI+JHsobm93LmdldEhvdXJzKCkgJSAxMiB8fCAxMil9OiR7U3RyaW5nKG0pLnBhZFN0YXJ0KDIsJzAnKX0gJHthbXBtfTwvc3Bhbj48c3BhbiBjbGFzcz1cImFuYWxvZy1kYXRlLXNtXCI+JHtkYXRlU3RyKG5vdyl9PC9zcGFuPjwvZGl2PjwvZGl2PmA7XG4gICAgYWN0aXZlTGF5b3V0ID0gJ2FuYWxvZyc7XG4gIH1cblxuICAvLyA9PT09PSBNQUlOIFRJQ0sgPT09PT1cbiAgZnVuY3Rpb24gdGljaygpIHtcbiAgICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpO1xuICAgIGNvbnN0IGggPSBub3cuZ2V0SG91cnMoKSAlIDEyIHx8IDEyO1xuICAgIGNvbnN0IG0gPSBub3cuZ2V0TWludXRlcygpO1xuICAgIGNvbnN0IHMgPSBub3cuZ2V0U2Vjb25kcygpO1xuXG4gICAgLy8gU2V0IHN0eWxlIGNsYXNzIG9uIHdpZGdldFxuICAgIGNvbnN0IG5leHRDbGFzc05hbWUgPSAnY2xvY2std2lkZ2V0JyArIChjdXJyZW50U3R5bGUgIT09ICdkZWZhdWx0JyA/ICcgJyArIGN1cnJlbnRTdHlsZSA6ICcnKTtcbiAgICBpZiAod2lkZ2V0LmNsYXNzTmFtZSAhPT0gbmV4dENsYXNzTmFtZSkge1xuICAgICAgd2lkZ2V0LmNsYXNzTmFtZSA9IG5leHRDbGFzc05hbWU7XG4gICAgfVxuXG4gICAgc3dpdGNoIChjdXJyZW50U3R5bGUpIHtcbiAgICAgIGNhc2UgJ2xjZCc6IHJlbmRlckxjZChub3cpOyBicmVhaztcbiAgICAgIGNhc2UgJ2xjZC1ibHVlJzogcmVuZGVyTGNkKG5vdyk7IGJyZWFrO1xuICAgICAgY2FzZSAnbGNkLWFtYmVyJzogcmVuZGVyTGNkKG5vdyk7IGJyZWFrO1xuICAgICAgY2FzZSAnbGNkLXJldHJvJzogcmVuZGVyTGNkKG5vdyk7IGJyZWFrO1xuICAgICAgY2FzZSAnbGNkLXRheGknOiByZW5kZXJMY2Qobm93KTsgYnJlYWs7XG4gICAgICBjYXNlICdmbGlwJzogcmVuZGVyRmxpcChub3cpOyBicmVhaztcbiAgICAgIGNhc2UgJ2JpbmFyeSc6IHJlbmRlckJpbmFyeShub3cpOyBicmVhaztcbiAgICAgIGNhc2UgJ2FuYWxvZyc6IHJlbmRlckFuYWxvZyhub3csIGZhbHNlKTsgYnJlYWs7XG4gICAgICBjYXNlICdyb21hbic6IHJlbmRlckFuYWxvZyhub3csIHRydWUpOyBicmVhaztcbiAgICAgIGRlZmF1bHQ6IHJlbmRlckRlZmF1bHQobm93KTtcbiAgICB9XG5cbiAgICAvLyBIb3VybHkgY2hpbWVzXG4gICAgaWYgKG0gPT09IDAgJiYgcyA9PT0gMCAmJiBoICE9PSBsYXN0Q2hpbWVIb3VyKSB7XG4gICAgICBsYXN0Q2hpbWVIb3VyID0gaDtcbiAgICAgIHBsYXlDaGltZXMoaCk7XG4gICAgfVxuICAgIGlmIChtICE9PSAwKSBsYXN0Q2hpbWVIb3VyID0gLTE7XG4gIH1cblxuICBmdW5jdGlvbiBzY2hlZHVsZU5leHRUaWNrKCkge1xuICAgIGNsZWFyVGltZW91dCh0aWNrVGltZXIpO1xuICAgIGNvbnN0IGludGVydmFsID0gZG9jdW1lbnQuaGlkZGVuID8gNjAwMDAgOiAxMDAwO1xuICAgIGNvbnN0IGRlbGF5ID0gaW50ZXJ2YWwgLSAoRGF0ZS5ub3coKSAlIGludGVydmFsKSArIDI1O1xuICAgIHRpY2tUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGljaygpO1xuICAgICAgc2NoZWR1bGVOZXh0VGljaygpO1xuICAgIH0sIGRlbGF5KTtcbiAgfVxuXG4gIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3Zpc2liaWxpdHljaGFuZ2UnLCAoKSA9PiB7XG4gICAgcHJldkZsaXBEaWdpdHMgPSAnJztcbiAgICByZXNldFJlbmRlckxheW91dCgpO1xuICAgIHRpY2soKTtcbiAgICBzY2hlZHVsZU5leHRUaWNrKCk7XG4gIH0pO1xuXG4gIHRpY2soKTtcbiAgc2NoZWR1bGVOZXh0VGljaygpO1xuXG4gIC8vID09PT09IFNFVFRJTkdTIE1PREFMID09PT09XG4gIGNvbnN0IFNUWUxFUyA9IFtcbiAgICB7IGlkOiAnZGVmYXVsdCcsIGxhYmVsOiAnRGVmYXVsdCcsIGljb246ICdcdUQ4M0RcdURENTAnIH0sXG4gICAgeyBpZDogJ2xjZCcsIGxhYmVsOiAnTENEIEdyZWVuJywgaWNvbjogJ1x1RDgzRFx1REM5QScgfSxcbiAgICB7IGlkOiAnbGNkLWJsdWUnLCBsYWJlbDogJ0xDRCBCbHVlJywgaWNvbjogJ1x1RDgzRFx1REM5OScgfSxcbiAgICB7IGlkOiAnbGNkLWFtYmVyJywgbGFiZWw6ICdMQ0QgQW1iZXInLCBpY29uOiAnXHVEODNEXHVERkUwJyB9LFxuICAgIHsgaWQ6ICdsY2QtcmV0cm8nLCBsYWJlbDogJ0xDRCBSZXRybycsIGljb246ICdcdUQ4M0RcdURGRTknIH0sXG4gICAgeyBpZDogJ2xjZC10YXhpJywgbGFiZWw6ICdMQ0QgVGF4aScsIGljb246ICdcdUQ4M0RcdURGRTEnIH0sXG4gICAgeyBpZDogJ2ZsaXAnLCBsYWJlbDogJ0ZsaXAgQ2xvY2snLCBpY29uOiAnXHVEODNEXHVEQ0RGJyB9LFxuICAgIHsgaWQ6ICdiaW5hcnknLCBsYWJlbDogJ0JpbmFyeScsIGljb246ICdcdUQ4M0RcdURDQkInIH0sXG4gICAgeyBpZDogJ2FuYWxvZycsIGxhYmVsOiAnQW5hbG9nJywgaWNvbjogJ1x1MjNGMCcgfSxcbiAgICB7IGlkOiAncm9tYW4nLCBsYWJlbDogJ1JvbWFuJywgaWNvbjogJ1x1RDgzQ1x1REZEQlx1RkUwRicgfSxcbiAgXTtcblxuICBsZXQgc3R5bGVPcHRpb25zSHRtbCA9ICc8ZGl2IGNsYXNzPVwiY2xvY2stc3R5bGUtZ3JpZFwiPic7XG4gIFNUWUxFUy5mb3JFYWNoKHMgPT4ge1xuICAgIHN0eWxlT3B0aW9uc0h0bWwgKz0gYDxsYWJlbCBjbGFzcz1cImNsb2NrLXN0eWxlLW9wdGlvblwiPlxuICAgICAgPGlucHV0IHR5cGU9XCJyYWRpb1wiIG5hbWU9XCJjbG9jay1zdHlsZS1yYWRpb1wiIHZhbHVlPVwiJHtzLmlkfVwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJjbG9jay1zdHlsZS1jYXJkXCI+PHNwYW4gY2xhc3M9XCJjbG9jay1zdHlsZS1pY29uXCI+JHtzLmljb259PC9zcGFuPjxzcGFuIGNsYXNzPVwiY2xvY2stc3R5bGUtbGFiZWxcIj4ke3MubGFiZWx9PC9zcGFuPjwvc3Bhbj5cbiAgICA8L2xhYmVsPmA7XG4gIH0pO1xuICBzdHlsZU9wdGlvbnNIdG1sICs9ICc8L2Rpdj4nO1xuXG4gIGluamVjdE1vZGFsKCdjbG9jay1zZXR0aW5ncy1tb2RhbCcsIGA8ZGl2IGlkPVwiY2xvY2stc2V0dGluZ3MtbW9kYWxcIiBjbGFzcz1cIndlYXRoZXItbW9kYWxcIj5cbiAgICA8ZGl2IGNsYXNzPVwid2VhdGhlci1tb2RhbC1jb250ZW50XCIgc3R5bGU9XCJtYXgtd2lkdGg6IDQyMHB4O1wiPlxuICAgICAgPGgzPkNsb2NrIFNldHRpbmdzPC9oMz5cbiAgICAgIDxkaXYgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiAxNnB4O1wiPlxuICAgICAgICA8bGFiZWwgc3R5bGU9XCJkaXNwbGF5OiBibG9jazsgbWFyZ2luLWJvdHRvbTogOHB4OyBmb250LXdlaWdodDogNjAwOyBjb2xvcjogdmFyKC0tZmcpO1wiPlN0eWxlPC9sYWJlbD5cbiAgICAgICAgJHtzdHlsZU9wdGlvbnNIdG1sfVxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMTZweDsgcGFkZGluZy10b3A6IDEycHg7IGJvcmRlci10b3A6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1wiPlxuICAgICAgICA8bGFiZWwgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDhweDsgY3Vyc29yOiBwb2ludGVyOyBmb250LXdlaWdodDogNjAwOyBjb2xvcjogdmFyKC0tZmcpO1wiPlxuICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBpZD1cImNsb2NrLWNoaW1lcy10b2dnbGVcIj4gSG91cmx5IGNodXJjaCBiZWxsIGNoaW1lc1xuICAgICAgICA8L2xhYmVsPlxuICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjc4cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW4tdG9wOiA0cHg7IG1hcmdpbi1sZWZ0OiAyNHB4O1wiPlxuICAgICAgICAgIFN0cmlrZXMgdGhlIG51bWJlciBvZiB0aGUgaG91ciAoZS5nLiwgMyBiZWxscyBhdCAzOjAwKVxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDE2cHg7XCIgaWQ9XCJjbG9jay12b2x1bWUtc2VjdGlvblwiPlxuICAgICAgICA8bGFiZWwgc3R5bGU9XCJkaXNwbGF5OiBibG9jazsgbWFyZ2luLWJvdHRvbTogNnB4OyBmb250LXdlaWdodDogNjAwOyBjb2xvcjogdmFyKC0tZmcpO1wiPlZvbHVtZTwvbGFiZWw+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDEwcHg7XCI+XG4gICAgICAgICAgPHNwYW4gc3R5bGU9XCJmb250LXNpemU6IDAuODVyZW07XCI+XHVEODNEXHVERDA4PC9zcGFuPlxuICAgICAgICAgIDxpbnB1dCB0eXBlPVwicmFuZ2VcIiBpZD1cImNsb2NrLWNoaW1lLXZvbHVtZVwiIG1pbj1cIjBcIiBtYXg9XCIxMDBcIiB2YWx1ZT1cIjUwXCIgc3R5bGU9XCJmbGV4OiAxOyBhY2NlbnQtY29sb3I6IHZhcigtLW9rLWZnKTtcIj5cbiAgICAgICAgICA8c3BhbiBzdHlsZT1cImZvbnQtc2l6ZTogMC44NXJlbTtcIj5cdUQ4M0RcdUREMEE8L3NwYW4+XG4gICAgICAgICAgPGJ1dHRvbiBpZD1cImNsb2NrLWNoaW1lLXRlc3RcIiBzdHlsZT1cInBhZGRpbmc6IDRweCAxMHB4OyBmb250LXNpemU6IDAuNzhyZW07IGJvcmRlci1yYWRpdXM6IDRweDsgY3Vyc29yOiBwb2ludGVyO1wiPlRlc3Q8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsLWJ1dHRvbnNcIj5cbiAgICAgICAgPGJ1dHRvbiBpZD1cImNsb2NrLXNldHRpbmdzLWNhbmNlbFwiPkNhbmNlbDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIGlkPVwiY2xvY2stc2V0dGluZ3Mtc2F2ZVwiPlNhdmU8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5gKTtcblxuICBjb25zdCBtb2RhbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjbG9jay1zZXR0aW5ncy1tb2RhbCcpO1xuICBjb25zdCBjaGltZXNUb2dnbGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2xvY2stY2hpbWVzLXRvZ2dsZScpO1xuICBjb25zdCB2b2x1bWVTbGlkZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2xvY2stY2hpbWUtdm9sdW1lJyk7XG4gIGNvbnN0IHZvbHVtZVNlY3Rpb24gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2xvY2stdm9sdW1lLXNlY3Rpb24nKTtcblxuICBmdW5jdGlvbiBsb2FkU2V0dGluZ3MoKSB7XG4gICAgY29uc3Qgc3R5bGUgPSBzYWZlR2V0KCdjbG9jay1zdHlsZScpIHx8ICdkZWZhdWx0JztcbiAgICBjb25zdCByYWRpbyA9IG1vZGFsLnF1ZXJ5U2VsZWN0b3IoYGlucHV0W3ZhbHVlPVwiJHtzdHlsZX1cIl1gKTtcbiAgICBpZiAocmFkaW8pIHJhZGlvLmNoZWNrZWQgPSB0cnVlO1xuICAgIGNoaW1lc1RvZ2dsZS5jaGVja2VkID0gc2FmZUdldCgnY2xvY2stY2hpbWVzJykgPT09ICd0cnVlJztcbiAgICB2b2x1bWVTbGlkZXIudmFsdWUgPSBzYWZlR2V0KCdjbG9jay1jaGltZS12b2x1bWUnKSB8fCAnNTAnO1xuICAgIHZvbHVtZVNlY3Rpb24uc3R5bGUub3BhY2l0eSA9IGNoaW1lc1RvZ2dsZS5jaGVja2VkID8gJzEnIDogJzAuNCc7XG4gIH1cblxuICBjaGltZXNUb2dnbGU/LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsICgpID0+IHtcbiAgICB2b2x1bWVTZWN0aW9uLnN0eWxlLm9wYWNpdHkgPSBjaGltZXNUb2dnbGUuY2hlY2tlZCA/ICcxJyA6ICcwLjQnO1xuICB9KTtcblxuICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2xvY2stc2V0dGluZ3MnKT8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgbG9hZFNldHRpbmdzKCk7XG4gICAgbW9kYWwuY2xhc3NMaXN0LmFkZCgnc2hvdycpO1xuICB9KTtcblxuICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2xvY2stY2hpbWUtdGVzdCcpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICBjb25zdCB2b2wgPSBwYXJzZUludCh2b2x1bWVTbGlkZXIudmFsdWUsIDEwKSAvIDEwMDtcbiAgICBjb25zdCBiZWxsID0gbmV3IEF1ZGlvKCcvYXNzZXRzL3NvdW5kcy9jaHVyY2gtYmVsbC5tcDMnKTtcbiAgICBiZWxsLnZvbHVtZSA9IHZvbDtcbiAgICBiZWxsLnBsYXkoKS5jYXRjaCgoKSA9PiB7fSk7XG4gIH0pO1xuXG4gIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjbG9jay1zZXR0aW5ncy1zYXZlJyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgIGNvbnN0IHJhZGlvID0gbW9kYWwucXVlcnlTZWxlY3RvcignaW5wdXRbbmFtZT1cImNsb2NrLXN0eWxlLXJhZGlvXCJdOmNoZWNrZWQnKTtcbiAgICBjb25zdCBzdHlsZSA9IHJhZGlvID8gcmFkaW8udmFsdWUgOiAnZGVmYXVsdCc7XG4gICAgc2FmZVNldCgnY2xvY2stc3R5bGUnLCBzdHlsZSk7XG4gICAgc2FmZVNldCgnY2xvY2stY2hpbWVzJywgU3RyaW5nKGNoaW1lc1RvZ2dsZS5jaGVja2VkKSk7XG4gICAgc2FmZVNldCgnY2xvY2stY2hpbWUtdm9sdW1lJywgdm9sdW1lU2xpZGVyLnZhbHVlKTtcbiAgICBjdXJyZW50U3R5bGUgPSBzdHlsZTtcbiAgICBwcmV2RmxpcERpZ2l0cyA9ICcnO1xuICAgIHJlc2V0UmVuZGVyTGF5b3V0KCk7XG4gICAgdGljaygpO1xuICAgIHNjaGVkdWxlTmV4dFRpY2soKTtcbiAgICBtb2RhbC5jbGFzc0xpc3QucmVtb3ZlKCdzaG93Jyk7XG4gICAgc2hvd05vdGlmaWNhdGlvbignQ2xvY2sgc2V0dGluZ3Mgc2F2ZWQnLCAnc3VjY2VzcycsIDIwMDApO1xuICB9KTtcblxuICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2xvY2stc2V0dGluZ3MtY2FuY2VsJyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgIG1vZGFsLmNsYXNzTGlzdC5yZW1vdmUoJ3Nob3cnKTtcbiAgfSk7XG5cbiAgd2lyZU1vZGFsKG1vZGFsKTtcblxuICAvLyBMaXZlIHByZXZpZXcgd2hlbiBjbGlja2luZyBzdHlsZSBvcHRpb25zXG4gIG1vZGFsPy5xdWVyeVNlbGVjdG9yQWxsKCdpbnB1dFtuYW1lPVwiY2xvY2stc3R5bGUtcmFkaW9cIl0nKS5mb3JFYWNoKHJhZGlvID0+IHtcbiAgICByYWRpby5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCAoKSA9PiB7XG4gICAgICBjdXJyZW50U3R5bGUgPSByYWRpby52YWx1ZTtcbiAgICAgIHByZXZGbGlwRGlnaXRzID0gJyc7XG4gICAgICByZXNldFJlbmRlckxheW91dCgpO1xuICAgICAgdGljaygpO1xuICAgIH0pO1xuICB9KTtcbn0pKCk7XG47XG4vLyA9PT09PT09PT09IENBUkQgSEVBTFRIICYgVVBEQVRFIEJBREdFUyA9PT09PT09PT09XG4oZnVuY3Rpb24oKSB7XG4gIC8vIEZldGNoIGhlYWx0aCBkYXRhIGFuZCB1cGRhdGUgY2FyZCBVSVxuICBhc3luYyBmdW5jdGlvbiByZWZyZXNoQ2FyZEhlYWx0aCgpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2goJy9hcGkvdjEvaGVhbHRoLWNoZWNrcy9zdGF0dXMnKTtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXMuanNvbigpO1xuICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MgfHwgIWRhdGEuc3RhdHVzKSByZXR1cm47XG5cbiAgICAgIGZvciAoY29uc3QgW3NlcnZpY2VJZCwgc3ZjXSBvZiBPYmplY3QuZW50cmllcyhkYXRhLnN0YXR1cykpIHtcbiAgICAgICAgY29uc3QgdXB0aW1lRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndXB0aW1lLScgKyBzZXJ2aWNlSWQpO1xuICAgICAgICBjb25zdCBiYXJFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd1cHRpbWUtYmFyLScgKyBzZXJ2aWNlSWQpO1xuICAgICAgICBpZiAoIXVwdGltZUVsKSBjb250aW51ZTtcblxuICAgICAgICBjb25zdCB1cHRpbWUyNCA9IHN2Yy51cHRpbWU/LlsnMjRoJ107XG4gICAgICAgIGlmICh1cHRpbWUyNCAhPT0gdW5kZWZpbmVkICYmIHVwdGltZTI0ICE9PSBudWxsKSB7XG4gICAgICAgICAgY29uc3QgcGN0ID0gdXB0aW1lMjQudG9GaXhlZCgxKTtcbiAgICAgICAgICB1cHRpbWVFbC50ZXh0Q29udGVudCA9IGAke3BjdH0lIHVwdGltZWA7XG4gICAgICAgICAgLy8gQ29sb3IgY2xhc3NcbiAgICAgICAgICB1cHRpbWVFbC5jbGFzc05hbWUgPSAndXB0aW1lLWNoaXAnO1xuICAgICAgICAgIGlmICh1cHRpbWUyNCA+PSA5OS45KSB1cHRpbWVFbC5jbGFzc0xpc3QuYWRkKCdleGNlbGxlbnQnKTtcbiAgICAgICAgICBlbHNlIGlmICh1cHRpbWUyNCA+PSA5OSkgdXB0aW1lRWwuY2xhc3NMaXN0LmFkZCgnZ29vZCcpO1xuICAgICAgICAgIGVsc2UgaWYgKHVwdGltZTI0ID49IDk1KSB1cHRpbWVFbC5jbGFzc0xpc3QuYWRkKCdkZWdyYWRlZCcpO1xuICAgICAgICAgIGVsc2UgdXB0aW1lRWwuY2xhc3NMaXN0LmFkZCgncG9vcicpO1xuXG4gICAgICAgICAgaWYgKGJhckVsKSBiYXJFbC5zdHlsZS53aWR0aCA9IHBjdCArICclJztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKF8pIHtcbiAgICAgIC8qIEhlYWx0aCBjaGVjayBBUEkgdW5hdmFpbGFibGUgXHUyMDE0IHVwdGltZSBjaGlwcyBzdGF5IGhpZGRlbiAqL1xuICAgICAgY29uc29sZS53YXJuKCdbQ2FyZCBCYWRnZXNdIEhlYWx0aCBjaGVjayBBUEkgdW5hdmFpbGFibGUnKTtcbiAgICB9XG4gIH1cblxuICAvLyBUcmFjayBkaXNtaXNzZWQgdXBkYXRlcyAocGVyIHNlc3Npb24pXG4gIGxldCBkaXNtaXNzZWRVcGRhdGVzO1xuICB0cnkge1xuICAgIGRpc21pc3NlZFVwZGF0ZXMgPSBuZXcgU2V0KEpTT04ucGFyc2Uoc2FmZVNlc3Npb25HZXQoJ2Rpc21pc3NlZC11cGRhdGVzJykgfHwgJ1tdJykpO1xuICB9IGNhdGNoIChfKSB7XG4gICAgLyogU2Vzc2lvbiBzdG9yYWdlIHVuYXZhaWxhYmxlICovXG4gICAgZGlzbWlzc2VkVXBkYXRlcyA9IG5ldyBTZXQoKTtcbiAgfVxuXG4gIC8vIFRyYWNrIGdsb2JhbCB1cGRhdGUgc3RhdGUgZm9yIGNyb3NzLWNvbXBvbmVudCBhY2Nlc3NcbiAgbGV0IGtub3duVXBkYXRlcyA9IFtdO1xuXG4gIC8vIEZldGNoIHVwZGF0ZSBkYXRhIGFuZCBzaG93IGJhZGdlc1xuICBhc3luYyBmdW5jdGlvbiByZWZyZXNoQ2FyZFVwZGF0ZXMobm90aWZ5TmV3KSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL3VwZGF0ZXMvYXZhaWxhYmxlJyk7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzLmpzb24oKTtcbiAgICAgIGlmICghZGF0YS5zdWNjZXNzKSByZXR1cm47XG5cbiAgICAgIC8vIENsZWFyIGFsbCB1cGRhdGUgYmFkZ2VzIGZpcnN0XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcudXBkYXRlLWF2YWlsYWJsZS1iYWRnZScpLmZvckVhY2goZWwgPT4gZWwuY2xhc3NMaXN0LnJlbW92ZSgndmlzaWJsZScpKTtcblxuICAgICAgY29uc3QgdXBkYXRlcyA9IGRhdGEudXBkYXRlcyB8fCBbXTtcbiAgICAgIGtub3duVXBkYXRlcyA9IHVwZGF0ZXM7IC8vIHN0b3JlIGdsb2JhbGx5XG5cbiAgICAgIC8vIE5vdGlmeSBpZiBuZXcgdXBkYXRlcyBhcHBlYXJlZCAocGVyaW9kaWMgY2hlY2sgd2l0aCBub3RpZmljYXRpb24pXG4gICAgICBpZiAobm90aWZ5TmV3ICYmIHVwZGF0ZXMubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCBwcmV2ID0gd2luZG93Ll9sYXN0S25vd25VcGRhdGVDb3VudCB8fCAwO1xuICAgICAgICBpZiAocHJldiA+IDAgJiYgdXBkYXRlcy5sZW5ndGggPiBwcmV2KSB7XG4gICAgICAgICAgc2hvd05vdGlmaWNhdGlvbihgJHt1cGRhdGVzLmxlbmd0aH0gY29udGFpbmVyIHVwZGF0ZShzKSBhdmFpbGFibGUgXHUyMDE0IGNsaWNrIFVwZGF0ZSBNYW5hZ2VtZW50IHRvIHJldmlldy5gLCAnaW5mbycpO1xuICAgICAgICB9XG4gICAgICAgIHdpbmRvdy5fbGFzdEtub3duVXBkYXRlQ291bnQgPSB1cGRhdGVzLmxlbmd0aDtcbiAgICAgIH1cblxuICAgICAgaWYgKCF1cGRhdGVzLmxlbmd0aCkgcmV0dXJuO1xuXG4gICAgICBmb3IgKGNvbnN0IHVwZCBvZiB1cGRhdGVzKSB7XG4gICAgICAgIC8vIFRyeSB0byBtYXRjaCBieSBjb250YWluZXIgbmFtZSB0byBzZXJ2aWNlIGlkXG4gICAgICAgIGNvbnN0IGFwcHMgPSB3aW5kb3cuQVBQUyB8fCBbXTtcbiAgICAgICAgZm9yIChjb25zdCBhcHAgb2YgYXBwcykge1xuICAgICAgICAgIGlmIChhcHAuY29udGFpbmVySWQgPT09IHVwZC5jb250YWluZXJJZCB8fCBhcHAuaWQgPT09IHVwZC5jb250YWluZXJOYW1lIHx8IGFwcC5uYW1lID09PSB1cGQuY29udGFpbmVyTmFtZSkge1xuICAgICAgICAgICAgLy8gU2tpcCBkaXNtaXNzZWQgdXBkYXRlc1xuICAgICAgICAgICAgaWYgKGRpc21pc3NlZFVwZGF0ZXMuaGFzKGFwcC5pZCkpIGJyZWFrO1xuICAgICAgICAgICAgY29uc3QgYmFkZ2UgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndXBkYXRlLWJhZGdlLScgKyBhcHAuaWQpO1xuICAgICAgICAgICAgY29uc3QgdXBkYXRlQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3VwZGF0ZS1idG4tJyArIGFwcC5pZCk7XG4gICAgICAgICAgICBpZiAoYmFkZ2UpIHtcbiAgICAgICAgICAgICAgYmFkZ2UuY2xhc3NMaXN0LmFkZCgndmlzaWJsZScpO1xuICAgICAgICAgICAgICBiYWRnZS50aXRsZSA9IGBVcGRhdGUgYXZhaWxhYmxlIFx1MjAxNCBjbGljayB0byBvcGVuIFVwZGF0ZSBNYW5hZ2VtZW50LmA7XG4gICAgICAgICAgICAgIGJhZGdlLnN0eWxlLmN1cnNvciA9ICdwb2ludGVyJztcbiAgICAgICAgICAgICAgYmFkZ2Uub25jbGljayA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICAvLyBPcGVuIFVwZGF0ZSBNYW5hZ2VtZW50IG1vZGFsIGZvY3VzZWQgb24gdGhpcyBhcHBcbiAgICAgICAgICAgICAgICBpZiAod2luZG93Lm9wZW5VcGRhdGVNb2RhbCkgd2luZG93Lm9wZW5VcGRhdGVNb2RhbChhcHAuaWQpO1xuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gSGlnaGxpZ2h0IHVwZGF0ZSBidXR0b24gaWYgdXBkYXRlIGlzIGF2YWlsYWJsZVxuICAgICAgICAgICAgaWYgKHVwZGF0ZUJ0bikge1xuICAgICAgICAgICAgICB1cGRhdGVCdG4uc3R5bGUuYmFja2dyb3VuZCA9ICcjZjk3MzE2JztcbiAgICAgICAgICAgICAgdXBkYXRlQnRuLnN0eWxlLmJvcmRlckNvbG9yID0gJyNmOTczMTYnO1xuICAgICAgICAgICAgICB1cGRhdGVCdG4uc3R5bGUuYm94U2hhZG93ID0gJzAgMCA2cHggI2Y5NzMxNjg4JztcbiAgICAgICAgICAgICAgdXBkYXRlQnRuLnRpdGxlID0gYFVwZGF0ZSBhdmFpbGFibGUgXHUyMDE0IGNsaWNrIHRvIG9wZW4gVXBkYXRlIE1hbmFnZW1lbnQuYDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKF8pIHtcbiAgICAgIC8qIFVwZGF0ZXMgQVBJIHVuYXZhaWxhYmxlIFx1MjAxNCBiYWRnZXMgc3RheSBoaWRkZW4gKi9cbiAgICAgIGNvbnNvbGUud2FybignW0NhcmQgQmFkZ2VzXSBVcGRhdGVzIEFQSSB1bmF2YWlsYWJsZScpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJ1biBoZWFsdGggYW5kIHVwZGF0ZSBjaGVja3MgYWZ0ZXIgbWFpbiByZWZyZXNoLCBhbmQgcGVyaW9kaWNhbGx5XG4gIGZ1bmN0aW9uIHNjaGVkdWxlQ2FyZEVuaGFuY2VtZW50cygpIHtcbiAgICAvLyBJbml0aWFsIGxvYWQgKGRlbGF5ZWQgdG8gbm90IGNvbXBldGUgd2l0aCBtYWluIHByb2JlIGNoZWNrcylcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHJlZnJlc2hDYXJkSGVhbHRoKCk7XG4gICAgICByZWZyZXNoQ2FyZFVwZGF0ZXMoKTtcbiAgICB9LCA1MDAwKTtcblxuICAgIC8vIFBlcmlvZGljIHJlZnJlc2ggZXZlcnkgNjAgc2Vjb25kcyBcdTIwMTQgbm90aWZ5IG9uIG5ldyB1cGRhdGVzIGRldGVjdGVkXG4gICAgc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgcmVmcmVzaENhcmRIZWFsdGgoKTtcbiAgICAgIHJlZnJlc2hDYXJkVXBkYXRlcyh0cnVlKTsgLy8gdHJ1ZSA9IG5vdGlmeSBpZiBuZXcgdXBkYXRlcyBmb3VuZFxuICAgIH0sIDYwMDAwKTtcbiAgfVxuXG4gIC8vIEhvb2sgaW50byBtYWluIHJlZnJlc2ggY3ljbGVcbiAgY29uc3Qgb3JpZ1JlZnJlc2hBbGwgPSB3aW5kb3cucmVmcmVzaEFsbDtcbiAgaWYgKG9yaWdSZWZyZXNoQWxsKSB7XG4gICAgd2luZG93LnJlZnJlc2hBbGwgPSBhc3luYyBmdW5jdGlvbigpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IG9yaWdSZWZyZXNoQWxsKCk7XG4gICAgICAgIC8vIFJlZnJlc2ggaGVhbHRoIGRhdGEgYWZ0ZXIgbWFpbiBzdGF0dXMgY2hlY2tcbiAgICAgICAgc2V0VGltZW91dChyZWZyZXNoQ2FyZEhlYWx0aCwgMTAwMCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnNvbGUud2FybignW0NhcmQgQmFkZ2VzXSBFcnJvciBpbiByZWZyZXNoQWxsIGhvb2s6JywgZS5tZXNzYWdlKTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgc2NoZWR1bGVDYXJkRW5oYW5jZW1lbnRzKCk7XG59KSgpO1xuO1xuLy8gPT09PT09PT09PSBUSEVNRSBQSUNLRVIgKyBUSEVNRSBCVUlMREVSID09PT09PT09PT1cbihmdW5jdGlvbiAoKSB7XG4gIHZhciB0aGVtZUJlZm9yZUJ1aWxkZXIgPSBudWxsO1xuICB2YXIgZWRpdGluZ1NsdWcgPSBudWxsO1xuICB2YXIgYWR2YW5jZWRPdmVycmlkZXMgPSB7fTsgLy8gdHJhY2tzIHdoaWNoIGFkdmFuY2VkIGZpZWxkcyB1c2VyIG1hbnVhbGx5IGNoYW5nZWRcblxuICAvLyBEaXNwbGF5IG5hbWVzIGZvciBidWlsdC1pbiB0aGVtZXNcbiAgdmFyIFRIRU1FX0xBQkVMUyA9IHtcbiAgICBkYXJrOiAnRGFyaycsXG4gICAgbGlnaHQ6ICdMaWdodCcsXG4gICAgYmx1ZTogJ0JsdWUnLFxuICAgIGJsYWNrOiAnQmxhY2snLFxuICAgIG5vcmQ6ICdOb3JkJyxcbiAgICBkcmFjdWxhOiAnRHJhY3VsYScsXG4gICAgJ3NvbGFyaXplZC1kYXJrJzogJ1NvbGFyaXplZCBEYXJrJyxcbiAgICAnc29sYXJpemVkLWxpZ2h0JzogJ1NvbGFyaXplZCBMaWdodCcsXG4gICAgdGF4aTogJ1RheGknLFxuICAgIG9jZWFuOiAnT2NlYW4nLFxuICB9O1xuXG4gIC8vIENvbG9yIHBpY2tlciBmaWVsZCBkZWZpbml0aW9uczogW2Nzcy1wcm9wLCBsYWJlbCwgc2VjdGlvbl1cbiAgdmFyIEZJRUxEUyA9IFtcbiAgICBbJ2JnJywgICAgICAgICAgICAnQmFja2dyb3VuZCcsICAgICdiYXNlJ10sXG4gICAgWydjYXJkLWJhc2UnLCAgICAgJ0NhcmQnLCAgICAgICAgICAnYmFzZSddLFxuICAgIFsnZmcnLCAgICAgICAgICAgICdUZXh0JywgICAgICAgICAgJ2Jhc2UnXSxcbiAgICBbJ211dGVkJywgICAgICAgICAnTXV0ZWQgVGV4dCcsICAgICdiYXNlJ10sXG4gICAgWydib3JkZXInLCAgICAgICAgJ0JvcmRlcicsICAgICAgICAnYmFzZSddLFxuICAgIFsnYWNjZW50JywgICAgICAgICdBY2NlbnQnLCAgICAgICAgJ2FjY2VudCddLFxuICAgIFsnYWNjZW50LXN0cm9uZycsICdBY2NlbnQgU3Ryb25nJywgJ2FjY2VudCddLFxuICAgIFsnb2stYmcnLCAgICAgICAgICdPSyBCYWNrZ3JvdW5kJywgJ3N0YXR1cyddLFxuICAgIFsnb2stZmcnLCAgICAgICAgICdPSyBUZXh0JywgICAgICAgJ3N0YXR1cyddLFxuICAgIFsnYmFkLWJnJywgICAgICAgICdFcnJvciBCZycsICAgICAgJ3N0YXR1cyddLFxuICAgIFsnYmFkLWZnJywgICAgICAgICdFcnJvciBUZXh0JywgICAgJ3N0YXR1cyddLFxuICAgIFsnZG90LW9rJywgICAgICAgICdEb3QgT0snLCAgICAgICAgJ3N0YXR1cyddLFxuICAgIFsnZG90LWJhZCcsICAgICAgICdEb3QgRXJyb3InLCAgICAgJ3N0YXR1cyddLFxuICAgIFsndXB0aW1lJywgICAgICAgICdVcHRpbWUgQmFyJywgICAgJ3N0YXR1cyddLFxuICAgIFsnaG92ZXInLCAgICAgICAgICdIb3ZlcicsICAgICAgICAgJ2FkdmFuY2VkJ10sXG4gICAgWydjYXJkLWhvdmVyJywgICAgJ0NhcmQgSG92ZXInLCAgICAnYWR2YW5jZWQnXSxcbiAgICBbJ2Jhc2UnLCAgICAgICAgICAnVGFncy9CYWRnZXMnLCAgICdhZHZhbmNlZCddLFxuICAgIFsnZmctbXV0ZWQnLCAgICAgICdEaW0gVGV4dCcsICAgICAgJ2FkdmFuY2VkJ10sXG4gICAgWydzdWNjZXNzJywgICAgICAgJ1N1Y2Nlc3MnLCAgICAgICAnYWR2YW5jZWQnXSxcbiAgICBbJ2Vycm9yJywgICAgICAgICAnRXJyb3InLCAgICAgICAgICdhZHZhbmNlZCddLFxuICAgIFsnd2FybmluZycsICAgICAgICdXYXJuaW5nJywgICAgICAgJ2FkdmFuY2VkJ10sXG4gIF07XG5cbiAgLy8gXHUyNTAwXHUyNTAwXHUyNTAwIFRoZW1lIEN5Y2xlIEJ1dHRvbiBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcblxuICB2YXIgdGhlbWVCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGhlbWUnKTtcbiAgaWYgKCF0aGVtZUJ0bikgcmV0dXJuO1xuICB2YXIgdGhlbWVMYWJlbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0aGVtZS1sYWJlbCcpO1xuXG4gIGZ1bmN0aW9uIGdldExhYmVsRm9yKHQpIHtcbiAgICBpZiAoVEhFTUVfTEFCRUxTW3RdKSByZXR1cm4gVEhFTUVfTEFCRUxTW3RdO1xuICAgIHZhciB1c2VyVGhlbWVzID0gc2FmZUdldEpTT04od2luZG93LlVTRVJfVEhFTUVTX0tFWSwge30pO1xuICAgIGlmICh1c2VyVGhlbWVzW3RdKSByZXR1cm4gdXNlclRoZW1lc1t0XS5uYW1lIHx8IHQ7XG4gICAgcmV0dXJuIHQ7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVMYWJlbCgpIHtcbiAgICBpZiAodGhlbWVMYWJlbCkgdGhlbWVMYWJlbC50ZXh0Q29udGVudCA9IGdldExhYmVsRm9yKHdpbmRvdy5nZXRBY3RpdmVUaGVtZSgpKTtcbiAgfVxuXG4gIHRoZW1lQnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgIHZhciBsaXN0ID0gd2luZG93LlRIRU1FUy5zbGljZSgpO1xuICAgIHZhciBjdXJyZW50ID0gd2luZG93LmdldEFjdGl2ZVRoZW1lKCk7XG4gICAgdmFyIGlkeCA9IGxpc3QuaW5kZXhPZihjdXJyZW50KTtcbiAgICB2YXIgbmV4dCA9IGxpc3RbKGlkeCArIDEpICUgbGlzdC5sZW5ndGhdO1xuICAgIHdpbmRvdy5hcHBseVRoZW1lKG5leHQpO1xuICAgIHVwZGF0ZUxhYmVsKCk7XG4gIH0pO1xuXG4gIHVwZGF0ZUxhYmVsKCk7XG5cbiAgLy8gXHUyNTAwXHUyNTAwXHUyNTAwIFRoZW1lIEJ1aWxkZXIgTW9kYWwgXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXG5cbiAgZnVuY3Rpb24gYnVpbGRGaWVsZHNIVE1MKCkge1xuICAgIHZhciBzZWN0aW9ucyA9IHsgYmFzZTogJ0Jhc2UgQ29sb3JzJywgYWNjZW50OiAnQWNjZW50Jywgc3RhdHVzOiAnU3RhdHVzJywgYWR2YW5jZWQ6ICdBZHZhbmNlZCAoYXV0by1kZXJpdmVkKScgfTtcbiAgICB2YXIgZ3JvdXBlZCA9IHt9O1xuICAgIEZJRUxEUy5mb3JFYWNoKGZ1bmN0aW9uIChmKSB7XG4gICAgICBpZiAoIWdyb3VwZWRbZlsyXV0pIGdyb3VwZWRbZlsyXV0gPSBbXTtcbiAgICAgIGdyb3VwZWRbZlsyXV0ucHVzaChmKTtcbiAgICB9KTtcblxuICAgIHZhciBodG1sID0gJyc7XG4gICAgT2JqZWN0LmtleXMoc2VjdGlvbnMpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgaWYgKGtleSA9PT0gJ2FkdmFuY2VkJykge1xuICAgICAgICBodG1sICs9ICc8ZGl2IGlkPVwidGhlbWUtYnVpbGRlci1hZHZhbmNlZC10b2dnbGVcIiBjbGFzcz1cInRoZW1lLWJ1aWxkZXItYWR2YW5jZWQtdG9nZ2xlXCIgc3R5bGU9XCJtYXJnaW46MTJweCAwIDRweDtjdXJzb3I6cG9pbnRlcjtjb2xvcjp2YXIoLS1hY2NlbnQpO2ZvbnQtc2l6ZTouODVyZW07dXNlci1zZWxlY3Q6bm9uZTtcIj5TaG93IGFkdmFuY2VkIGNvbG9ycyAmIzk2NjA7PC9kaXY+JztcbiAgICAgICAgaHRtbCArPSAnPGRpdiBpZD1cInRoZW1lLWJ1aWxkZXItYWR2YW5jZWRcIiBjbGFzcz1cInRoZW1lLWJ1aWxkZXItc2VjdGlvblwiIHN0eWxlPVwiZGlzcGxheTpub25lO1wiPic7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBodG1sICs9ICc8ZGl2IGNsYXNzPVwidGhlbWUtYnVpbGRlci1zZWN0aW9uXCI+JztcbiAgICAgIH1cbiAgICAgIGh0bWwgKz0gJzxkaXYgY2xhc3M9XCJ0aGVtZS1idWlsZGVyLXNlY3Rpb24tdGl0bGVcIj4nICsgc2VjdGlvbnNba2V5XSArICc8L2Rpdj4nO1xuICAgICAgKGdyb3VwZWRba2V5XSB8fCBbXSkuZm9yRWFjaChmdW5jdGlvbiAoZikge1xuICAgICAgICBodG1sICs9ICc8ZGl2IGNsYXNzPVwidGhlbWUtYnVpbGRlci1yb3dcIj4nICtcbiAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJ0aGVtZS1idWlsZGVyLWxhYmVsXCI+JyArIGZbMV0gKyAnPC9zcGFuPicgK1xuICAgICAgICAgICc8aW5wdXQgdHlwZT1cImNvbG9yXCIgY2xhc3M9XCJ0aGVtZS1idWlsZGVyLWNvbG9yXCIgZGF0YS1wcm9wPVwiJyArIGZbMF0gKyAnXCInICsgKGtleSA9PT0gJ2FkdmFuY2VkJyA/ICcgZGF0YS1hZHZhbmNlZD1cIjFcIicgOiAnJykgKyAnIHZhbHVlPVwiIzAwMDAwMFwiIC8+JyArXG4gICAgICAgICAgJzxzcGFuIGNsYXNzPVwidGhlbWUtYnVpbGRlci1oZXhcIiBkYXRhLWhleD1cIicgKyBmWzBdICsgJ1wiPiMwMDAwMDA8L3NwYW4+JyArXG4gICAgICAgICAgJzwvZGl2Pic7XG4gICAgICB9KTtcbiAgICAgIGh0bWwgKz0gJzwvZGl2Pic7XG4gICAgfSk7XG4gICAgcmV0dXJuIGh0bWw7XG4gIH1cblxuICBmdW5jdGlvbiBidWlsZFN0YXJ0RnJvbU9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHdpbmRvdy5USEVNRVMubWFwKGZ1bmN0aW9uICh0KSB7XG4gICAgICByZXR1cm4gJzxvcHRpb24gdmFsdWU9XCInICsgdCArICdcIj4nICsgZ2V0TGFiZWxGb3IodCkgKyAnPC9vcHRpb24+JztcbiAgICB9KS5qb2luKCcnKTtcbiAgfVxuXG4gIHZhciBtb2RhbEhUTUwgPSAnPGRpdiBpZD1cInRoZW1lLWJ1aWxkZXItbW9kYWxcIiBjbGFzcz1cIndlYXRoZXItbW9kYWxcIj4nICtcbiAgICAnPGRpdiBjbGFzcz1cIndlYXRoZXItbW9kYWwtY29udGVudFwiIHN0eWxlPVwibWluLXdpZHRoOjQyMHB4O21heC13aWR0aDo1NjBweDtcIj4nICtcbiAgICAnPGgzPlRoZW1lIEJ1aWxkZXI8L2gzPicgK1xuXG4gICAgLy8gRWRpdCBleGlzdGluZyB1c2VyIHRoZW1lcyBkcm9wZG93blxuICAgICc8ZGl2IGlkPVwidGhlbWUtYnVpbGRlci1leGlzdGluZ1wiIHN0eWxlPVwibWFyZ2luLWJvdHRvbToxNnB4O2Rpc3BsYXk6bm9uZTtcIj4nICtcbiAgICAnPGxhYmVsIHN0eWxlPVwiZm9udC1zaXplOi44NXJlbTtjb2xvcjp2YXIoLS1tdXRlZCk7bWFyZ2luLXJpZ2h0OjhweDtcIj5FZGl0OjwvbGFiZWw+JyArXG4gICAgJzxzZWxlY3QgaWQ9XCJ0aGVtZS1idWlsZGVyLWVkaXQtc2VsZWN0XCIgc3R5bGU9XCJwYWRkaW5nOjZweCAxMHB4O2JhY2tncm91bmQ6dmFyKC0tY2FyZC1iZyk7Y29sb3I6dmFyKC0tZmcpO2JvcmRlcjoxcHggc29saWQgdmFyKC0tYm9yZGVyKTtib3JkZXItcmFkaXVzOjZweDtmb250LXNpemU6Ljg1cmVtO21hcmdpbi1yaWdodDo4cHg7XCI+JyArXG4gICAgJzxvcHRpb24gdmFsdWU9XCJcIj5cdTIwMTQgTmV3IFRoZW1lIFx1MjAxNDwvb3B0aW9uPicgK1xuICAgICc8L3NlbGVjdD4nICtcbiAgICAnPGJ1dHRvbiBpZD1cInRoZW1lLWJ1aWxkZXItZGVsZXRlXCIgc3R5bGU9XCJwYWRkaW5nOjRweCAxMHB4O2JhY2tncm91bmQ6Y29sb3ItbWl4KGluIHNyZ2IsdmFyKC0tYmFkLWZnKSAxNSUsdHJhbnNwYXJlbnQpO2JvcmRlcjoxcHggc29saWQgdmFyKC0tYmFkLWZnKTtjb2xvcjp2YXIoLS1iYWQtZmcpO2JvcmRlci1yYWRpdXM6NnB4O2ZvbnQtc2l6ZTouOHJlbTtjdXJzb3I6cG9pbnRlcjtcIj5EZWxldGU8L2J1dHRvbj4nICtcbiAgICAnPC9kaXY+JyArXG5cbiAgICAnPGRpdiBzdHlsZT1cIm1hcmdpbi1ib3R0b206MTZweDtcIj4nICtcbiAgICAnPGxhYmVsIHN0eWxlPVwiZm9udC1zaXplOi44NXJlbTtjb2xvcjp2YXIoLS1tdXRlZCk7bWFyZ2luLXJpZ2h0OjhweDtcIj5OYW1lOjwvbGFiZWw+JyArXG4gICAgJzxpbnB1dCB0eXBlPVwidGV4dFwiIGlkPVwidGhlbWUtYnVpbGRlci1uYW1lXCIgbWF4bGVuZ3RoPVwiMjBcIiBwbGFjZWhvbGRlcj1cIk15IFRoZW1lXCIgJyArXG4gICAgJ3N0eWxlPVwicGFkZGluZzo2cHggMTBweDtiYWNrZ3JvdW5kOnZhcigtLWNhcmQtYmcpO2NvbG9yOnZhcigtLWZnKTtib3JkZXI6MXB4IHNvbGlkIHZhcigtLWJvcmRlcik7Ym9yZGVyLXJhZGl1czo2cHg7Zm9udC1zaXplOi44NXJlbTt3aWR0aDoxNDBweDtcIiAvPicgK1xuICAgICc8L2Rpdj4nICtcblxuICAgICc8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbToxNnB4O2Rpc3BsYXk6ZmxleDthbGlnbi1pdGVtczpjZW50ZXI7XCI+JyArXG4gICAgJzxsYWJlbCBzdHlsZT1cImZvbnQtc2l6ZTouODVyZW07Y29sb3I6dmFyKC0tbXV0ZWQpO21hcmdpbi1yaWdodDo4cHg7Y3Vyc29yOnBvaW50ZXI7XCIgZm9yPVwidGhlbWUtYnVpbGRlci1saWdodGJnXCI+JyArXG4gICAgJzxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBpZD1cInRoZW1lLWJ1aWxkZXItbGlnaHRiZ1wiIHN0eWxlPVwibWFyZ2luLXJpZ2h0OjZweDtjdXJzb3I6cG9pbnRlcjt2ZXJ0aWNhbC1hbGlnbjptaWRkbGU7XCIgLz4nICtcbiAgICAnTGlnaHQgYmFja2dyb3VuZCAodXNlIGRhcmsgbG9nbyk8L2xhYmVsPicgK1xuICAgICc8L2Rpdj4nICtcblxuICAgICc8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbToxNnB4O1wiPicgK1xuICAgICc8bGFiZWwgc3R5bGU9XCJmb250LXNpemU6Ljg1cmVtO2NvbG9yOnZhcigtLW11dGVkKTttYXJnaW4tcmlnaHQ6OHB4O1wiPlN0YXJ0IGZyb206PC9sYWJlbD4nICtcbiAgICAnPHNlbGVjdCBpZD1cInRoZW1lLWJ1aWxkZXItc3RhcnRcIiBzdHlsZT1cInBhZGRpbmc6NnB4IDEwcHg7YmFja2dyb3VuZDp2YXIoLS1jYXJkLWJnKTtjb2xvcjp2YXIoLS1mZyk7Ym9yZGVyOjFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO2JvcmRlci1yYWRpdXM6NnB4O2ZvbnQtc2l6ZTouODVyZW07XCI+JyArXG4gICAgYnVpbGRTdGFydEZyb21PcHRpb25zKCkgK1xuICAgICc8L3NlbGVjdD4nICtcbiAgICAnPC9kaXY+JyArXG5cbiAgICAnPGRpdiBjbGFzcz1cInRoZW1lLWJ1aWxkZXItcHJldmlld1wiIGlkPVwidGhlbWUtYnVpbGRlci1wcmV2aWV3XCI+JyArXG4gICAgJzxkaXYgY2xhc3M9XCJ0aGVtZS1idWlsZGVyLWNhcmRcIiBpZD1cInRoZW1lLXByZXZpZXctY2FyZFwiPicgK1xuICAgICc8ZGl2IGNsYXNzPVwicHJldmlldy10aXRsZVwiPlNhbXBsZSBDYXJkPC9kaXY+JyArXG4gICAgJzxkaXYgY2xhc3M9XCJwcmV2aWV3LW11dGVkXCI+U2Vjb25kYXJ5IHRleHQgcHJldmlldzwvZGl2PicgK1xuICAgICc8ZGl2IGNsYXNzPVwicHJldmlldy1iYWRnZXNcIj4nICtcbiAgICAnPHNwYW4gY2xhc3M9XCJwcmV2aWV3LWJhZGdlXCIgaWQ9XCJwcmV2aWV3LWJhZGdlLW9rXCI+T048L3NwYW4+JyArXG4gICAgJzxzcGFuIGNsYXNzPVwicHJldmlldy1iYWRnZVwiIGlkPVwicHJldmlldy1iYWRnZS1iYWRcIj5PRkY8L3NwYW4+JyArXG4gICAgJzwvZGl2PicgK1xuICAgICc8ZGl2IGNsYXNzPVwicHJldmlldy1kb3RzXCI+JyArXG4gICAgJzxzcGFuPjxzcGFuIGNsYXNzPVwicHJldmlldy1kb3RcIiBpZD1cInByZXZpZXctZG90LW9rXCI+PC9zcGFuPiBPbmxpbmU8L3NwYW4+JyArXG4gICAgJzxzcGFuPjxzcGFuIGNsYXNzPVwicHJldmlldy1kb3RcIiBpZD1cInByZXZpZXctZG90LWJhZFwiPjwvc3Bhbj4gT2ZmbGluZTwvc3Bhbj4nICtcbiAgICAnPC9kaXY+JyArXG4gICAgJzxidXR0b24gY2xhc3M9XCJwcmV2aWV3LWJ0blwiIGlkPVwicHJldmlldy1hY2NlbnQtYnRuXCI+QWNjZW50IEJ1dHRvbjwvYnV0dG9uPicgK1xuICAgICc8L2Rpdj4nICtcbiAgICAnPC9kaXY+JyArXG5cbiAgICBidWlsZEZpZWxkc0hUTUwoKSArXG5cbiAgICAnPGRpdiBjbGFzcz1cIndlYXRoZXItbW9kYWwtYnV0dG9uc1wiPicgK1xuICAgICc8YnV0dG9uIGlkPVwidGhlbWUtYnVpbGRlci1jYW5jZWxcIj5DYW5jZWw8L2J1dHRvbj4nICtcbiAgICAnPGJ1dHRvbiBpZD1cInRoZW1lLWJ1aWxkZXItaW1wb3J0XCIgc3R5bGU9XCJtYXJnaW4tbGVmdDphdXRvO1wiIHRpdGxlPVwiSW1wb3J0IHRoZW1lIGZyb20gSlNPTiBmaWxlXCI+SW1wb3J0PC9idXR0b24+JyArXG4gICAgJzxidXR0b24gaWQ9XCJ0aGVtZS1idWlsZGVyLWV4cG9ydFwiIHRpdGxlPVwiRXhwb3J0IHRoZW1lIGFzIEpTT04gZmlsZVwiPkV4cG9ydDwvYnV0dG9uPicgK1xuICAgICc8YnV0dG9uIGlkPVwidGhlbWUtYnVpbGRlci1zYXZlXCIgY2xhc3M9XCJidG4tYWNjZW50XCI+U2F2ZSBUaGVtZTwvYnV0dG9uPicgK1xuICAgICc8L2Rpdj4nICtcbiAgICAnPC9kaXY+PC9kaXY+JztcblxuICBpbmplY3RNb2RhbCgndGhlbWUtYnVpbGRlci1tb2RhbCcsIG1vZGFsSFRNTCk7XG5cbiAgdmFyIG1vZGFsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RoZW1lLWJ1aWxkZXItbW9kYWwnKTtcbiAgdmFyIHN0YXJ0U2VsZWN0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RoZW1lLWJ1aWxkZXItc3RhcnQnKTtcbiAgdmFyIG5hbWVJbnB1dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0aGVtZS1idWlsZGVyLW5hbWUnKTtcbiAgdmFyIGVkaXRTZWxlY3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGhlbWUtYnVpbGRlci1lZGl0LXNlbGVjdCcpO1xuICB2YXIgZXhpc3RpbmdTZWN0aW9uID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RoZW1lLWJ1aWxkZXItZXhpc3RpbmcnKTtcbiAgdmFyIGxpZ2h0QmdDaGVjayA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0aGVtZS1idWlsZGVyLWxpZ2h0YmcnKTtcbiAgdmFyIHBpY2tlcnMgPSBtb2RhbC5xdWVyeVNlbGVjdG9yQWxsKCcudGhlbWUtYnVpbGRlci1jb2xvcicpO1xuICB2YXIgYWR2YW5jZWRTZWN0aW9uID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RoZW1lLWJ1aWxkZXItYWR2YW5jZWQnKTtcbiAgdmFyIGFkdmFuY2VkVG9nZ2xlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RoZW1lLWJ1aWxkZXItYWR2YW5jZWQtdG9nZ2xlJyk7XG4gIHZhciBleHBvcnRCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGhlbWUtYnVpbGRlci1leHBvcnQnKTtcblxuICAvLyBcdTI1MDBcdTI1MDBcdTI1MDAgQWR2YW5jZWQgdG9nZ2xlIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxuXG4gIHZhciBhZHZhbmNlZFZpc2libGUgPSBmYWxzZTtcbiAgYWR2YW5jZWRUb2dnbGUuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgYWR2YW5jZWRWaXNpYmxlID0gIWFkdmFuY2VkVmlzaWJsZTtcbiAgICBhZHZhbmNlZFNlY3Rpb24uc3R5bGUuZGlzcGxheSA9IGFkdmFuY2VkVmlzaWJsZSA/ICcnIDogJ25vbmUnO1xuICAgIGFkdmFuY2VkVG9nZ2xlLmlubmVySFRNTCA9IGFkdmFuY2VkVmlzaWJsZVxuICAgICAgPyAnSGlkZSBhZHZhbmNlZCBjb2xvcnMgJiM5NjUwOydcbiAgICAgIDogJ1Nob3cgYWR2YW5jZWQgY29sb3JzICYjOTY2MDsnO1xuICB9KTtcblxuICAvLyBcdTI1MDBcdTI1MDBcdTI1MDAgQ29sb3IgcGlja2VyIGhlbHBlcnMgXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXG5cbiAgZnVuY3Rpb24gZ2V0Q3VycmVudENvbG9ycygpIHtcbiAgICB2YXIgY29sb3JzID0ge307XG4gICAgcGlja2Vycy5mb3JFYWNoKGZ1bmN0aW9uIChwKSB7XG4gICAgICBjb2xvcnNbcC5kYXRhc2V0LnByb3BdID0gcC52YWx1ZTtcbiAgICB9KTtcbiAgICBjb2xvcnNbJ2NhcmQtYmcnXSA9IGNvbG9yc1snY2FyZC1iYXNlJ107XG4gICAgcmV0dXJuIGNvbG9ycztcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldEJhc2VDb2xvcnMoKSB7XG4gICAgdmFyIGNvbG9ycyA9IHt9O1xuICAgIHBpY2tlcnMuZm9yRWFjaChmdW5jdGlvbiAocCkge1xuICAgICAgaWYgKCFwLmRhdGFzZXQuYWR2YW5jZWQpIGNvbG9yc1twLmRhdGFzZXQucHJvcF0gPSBwLnZhbHVlO1xuICAgIH0pO1xuICAgIGNvbG9yc1snY2FyZC1iZyddID0gY29sb3JzWydjYXJkLWJhc2UnXTtcbiAgICBpZiAobGlnaHRCZ0NoZWNrLmNoZWNrZWQpIGNvbG9ycy5saWdodEJnID0gdHJ1ZTtcbiAgICByZXR1cm4gY29sb3JzO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlQWR2YW5jZWRGcm9tRGVyaXZlZCgpIHtcbiAgICB2YXIgYmFzZSA9IGdldEJhc2VDb2xvcnMoKTtcbiAgICB2YXIgZGVyaXZlZCA9IHdpbmRvdy5kZXJpdmVFeHRlbmRlZENvbG9ycyA/IHdpbmRvdy5kZXJpdmVFeHRlbmRlZENvbG9ycyhiYXNlKSA6IHt9O1xuICAgIHBpY2tlcnMuZm9yRWFjaChmdW5jdGlvbiAocCkge1xuICAgICAgaWYgKHAuZGF0YXNldC5hZHZhbmNlZCAmJiAhYWR2YW5jZWRPdmVycmlkZXNbcC5kYXRhc2V0LnByb3BdKSB7XG4gICAgICAgIHZhciB2YWwgPSBkZXJpdmVkW3AuZGF0YXNldC5wcm9wXSB8fCAnIzMzMzMzMyc7XG4gICAgICAgIHAudmFsdWUgPSB2YWw7XG4gICAgICAgIHZhciBoZXggPSBtb2RhbC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1oZXg9XCInICsgcC5kYXRhc2V0LnByb3AgKyAnXCJdJyk7XG4gICAgICAgIGlmIChoZXgpIGhleC50ZXh0Q29udGVudCA9IHZhbC50b1VwcGVyQ2FzZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gbG9hZFRoZW1lSW50b1BpY2tlcnModGhlbWVOYW1lKSB7XG4gICAgdmFyIGNvbG9ycyA9IHdpbmRvdy5USEVNRV9DT0xPUlNbdGhlbWVOYW1lXTtcbiAgICBpZiAoIWNvbG9ycykgcmV0dXJuO1xuICAgIGFkdmFuY2VkT3ZlcnJpZGVzID0ge307XG4gICAgcGlja2Vycy5mb3JFYWNoKGZ1bmN0aW9uIChwKSB7XG4gICAgICB2YXIgdmFsID0gY29sb3JzW3AuZGF0YXNldC5wcm9wXSB8fCAnIzAwMDAwMCc7XG4gICAgICBpZiAodmFsLnN0YXJ0c1dpdGgoJ3JnYmEnKSB8fCB2YWwuc3RhcnRzV2l0aCgnY29sb3ItbWl4JykpIHZhbCA9ICcjMzMzMzMzJztcbiAgICAgIHAudmFsdWUgPSB2YWw7XG4gICAgICB2YXIgaGV4ID0gbW9kYWwucXVlcnlTZWxlY3RvcignW2RhdGEtaGV4PVwiJyArIHAuZGF0YXNldC5wcm9wICsgJ1wiXScpO1xuICAgICAgaWYgKGhleCkgaGV4LnRleHRDb250ZW50ID0gdmFsLnRvVXBwZXJDYXNlKCk7XG4gICAgfSk7XG4gICAgbGlnaHRCZ0NoZWNrLmNoZWNrZWQgPSAhIWNvbG9ycy5saWdodEJnO1xuICAgIHVwZGF0ZVByZXZpZXcoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGxvYWRVc2VyVGhlbWVJbnRvUGlja2VycyhzbHVnKSB7XG4gICAgdmFyIHVzZXJUaGVtZXMgPSBzYWZlR2V0SlNPTih3aW5kb3cuVVNFUl9USEVNRVNfS0VZLCB7fSk7XG4gICAgdmFyIHRoZW1lID0gdXNlclRoZW1lc1tzbHVnXTtcbiAgICBpZiAoIXRoZW1lKSByZXR1cm47XG4gICAgYWR2YW5jZWRPdmVycmlkZXMgPSB7fTtcbiAgICBwaWNrZXJzLmZvckVhY2goZnVuY3Rpb24gKHApIHtcbiAgICAgIHZhciB2YWwgPSB0aGVtZVtwLmRhdGFzZXQucHJvcF0gfHwgJyMwMDAwMDAnO1xuICAgICAgcC52YWx1ZSA9IHZhbDtcbiAgICAgIHZhciBoZXggPSBtb2RhbC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1oZXg9XCInICsgcC5kYXRhc2V0LnByb3AgKyAnXCJdJyk7XG4gICAgICBpZiAoaGV4KSBoZXgudGV4dENvbnRlbnQgPSB2YWwudG9VcHBlckNhc2UoKTtcbiAgICAgIC8vIElmIHRoZW1lIGhhcyBleHBsaWNpdCBhZHZhbmNlZCB2YWx1ZXMsIG1hcmsgYXMgb3ZlcnJpZGRlblxuICAgICAgaWYgKHAuZGF0YXNldC5hZHZhbmNlZCAmJiB0aGVtZVtwLmRhdGFzZXQucHJvcF0pIHtcbiAgICAgICAgYWR2YW5jZWRPdmVycmlkZXNbcC5kYXRhc2V0LnByb3BdID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBuYW1lSW5wdXQudmFsdWUgPSB0aGVtZS5uYW1lIHx8ICcnO1xuICAgIGxpZ2h0QmdDaGVjay5jaGVja2VkID0gISF0aGVtZS5saWdodEJnO1xuICAgIC8vIEZpbGwgYW55IG1pc3NpbmcgYWR2YW5jZWQgZmllbGRzIGZyb20gZGVyaXZhdGlvblxuICAgIHVwZGF0ZUFkdmFuY2VkRnJvbURlcml2ZWQoKTtcbiAgICB1cGRhdGVQcmV2aWV3KCk7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVQcmV2aWV3KCkge1xuICAgIHZhciBjID0gZ2V0Q3VycmVudENvbG9ycygpO1xuICAgIHZhciBwcmV2aWV3ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RoZW1lLWJ1aWxkZXItcHJldmlldycpO1xuICAgIHZhciBjYXJkID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RoZW1lLXByZXZpZXctY2FyZCcpO1xuICAgIHZhciB0aXRsZSA9IGNhcmQucXVlcnlTZWxlY3RvcignLnByZXZpZXctdGl0bGUnKTtcbiAgICB2YXIgbXV0ZWQgPSBjYXJkLnF1ZXJ5U2VsZWN0b3IoJy5wcmV2aWV3LW11dGVkJyk7XG4gICAgdmFyIGJhZGdlT2sgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHJldmlldy1iYWRnZS1vaycpO1xuICAgIHZhciBiYWRnZUJhZCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwcmV2aWV3LWJhZGdlLWJhZCcpO1xuICAgIHZhciBkb3RPayA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwcmV2aWV3LWRvdC1vaycpO1xuICAgIHZhciBkb3RCYWQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHJldmlldy1kb3QtYmFkJyk7XG4gICAgdmFyIGJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwcmV2aWV3LWFjY2VudC1idG4nKTtcbiAgICB2YXIgZG90cyA9IGNhcmQucXVlcnlTZWxlY3RvcignLnByZXZpZXctZG90cycpO1xuXG4gICAgcHJldmlldy5zdHlsZS5iYWNrZ3JvdW5kID0gY1snYmcnXTtcbiAgICBjYXJkLnN0eWxlLmJhY2tncm91bmQgPSBjWydjYXJkLWJhc2UnXTtcbiAgICBjYXJkLnN0eWxlLmJvcmRlckNvbG9yID0gY1snYm9yZGVyJ107XG4gICAgdGl0bGUuc3R5bGUuY29sb3IgPSBjWydmZyddO1xuICAgIG11dGVkLnN0eWxlLmNvbG9yID0gY1snbXV0ZWQnXTtcbiAgICBiYWRnZU9rLnN0eWxlLmJhY2tncm91bmQgPSBjWydvay1iZyddO1xuICAgIGJhZGdlT2suc3R5bGUuY29sb3IgPSBjWydvay1mZyddO1xuICAgIGJhZGdlQmFkLnN0eWxlLmJhY2tncm91bmQgPSBjWydiYWQtYmcnXTtcbiAgICBiYWRnZUJhZC5zdHlsZS5jb2xvciA9IGNbJ2JhZC1mZyddO1xuICAgIGRvdE9rLnN0eWxlLmJhY2tncm91bmQgPSBjWydkb3Qtb2snXTtcbiAgICBkb3RCYWQuc3R5bGUuYmFja2dyb3VuZCA9IGNbJ2RvdC1iYWQnXTtcbiAgICBkb3RzLnN0eWxlLmNvbG9yID0gY1snZmcnXTtcbiAgICBidG4uc3R5bGUuYmFja2dyb3VuZCA9IGNbJ2FjY2VudCddO1xuICAgIGJ0bi5zdHlsZS5jb2xvciA9IGNbJ2JnJ107XG4gIH1cblxuICBmdW5jdGlvbiBhcHBseUNvbG9yc0xpdmUoY29sb3JzKSB7XG4gICAgLy8gSW5jbHVkZSBkZXJpdmVkIGNvbG9ycyBmb3IgZnVsbCBsaXZlIHByZXZpZXdcbiAgICB2YXIgZGVyaXZlZCA9IHdpbmRvdy5kZXJpdmVFeHRlbmRlZENvbG9ycyA/IHdpbmRvdy5kZXJpdmVFeHRlbmRlZENvbG9ycyhjb2xvcnMpIDoge307XG4gICAgd2luZG93LlRIRU1FX1BST1BTLmZvckVhY2goZnVuY3Rpb24gKHByb3ApIHtcbiAgICAgIHZhciB2YWwgPSBjb2xvcnNbcHJvcF0gfHwgZGVyaXZlZFtwcm9wXTtcbiAgICAgIGlmICh2YWwpIHtcbiAgICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KCctLScgKyBwcm9wLCB2YWwpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gV2lyZSB1cCBjb2xvciBwaWNrZXJzXG4gIHBpY2tlcnMuZm9yRWFjaChmdW5jdGlvbiAocCkge1xuICAgIHAuYWRkRXZlbnRMaXN0ZW5lcignaW5wdXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgaGV4ID0gbW9kYWwucXVlcnlTZWxlY3RvcignW2RhdGEtaGV4PVwiJyArIHAuZGF0YXNldC5wcm9wICsgJ1wiXScpO1xuICAgICAgaWYgKGhleCkgaGV4LnRleHRDb250ZW50ID0gcC52YWx1ZS50b1VwcGVyQ2FzZSgpO1xuXG4gICAgICAvLyBUcmFjayBtYW51YWwgYWR2YW5jZWQgb3ZlcnJpZGVzXG4gICAgICBpZiAocC5kYXRhc2V0LmFkdmFuY2VkKSB7XG4gICAgICAgIGFkdmFuY2VkT3ZlcnJpZGVzW3AuZGF0YXNldC5wcm9wXSA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBCYXNlIGNvbG9yIGNoYW5nZWQgXHUyMDE0IHJlLWRlcml2ZSBhZHZhbmNlZCB2YWx1ZXMgKHVubGVzcyBvdmVycmlkZGVuKVxuICAgICAgICB1cGRhdGVBZHZhbmNlZEZyb21EZXJpdmVkKCk7XG4gICAgICB9XG5cbiAgICAgIHVwZGF0ZVByZXZpZXcoKTtcbiAgICAgIGFwcGx5Q29sb3JzTGl2ZShnZXRDdXJyZW50Q29sb3JzKCkpO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyBMaWdodC1iZyBjaGVja2JveCBzaG91bGQgcmUtZGVyaXZlIGFkdmFuY2VkIGNvbG9yc1xuICBsaWdodEJnQ2hlY2suYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgZnVuY3Rpb24gKCkge1xuICAgIHVwZGF0ZUFkdmFuY2VkRnJvbURlcml2ZWQoKTtcbiAgICB1cGRhdGVQcmV2aWV3KCk7XG4gICAgYXBwbHlDb2xvcnNMaXZlKGdldEN1cnJlbnRDb2xvcnMoKSk7XG4gIH0pO1xuXG4gIHN0YXJ0U2VsZWN0LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIGZ1bmN0aW9uICgpIHtcbiAgICBhZHZhbmNlZE92ZXJyaWRlcyA9IHt9O1xuICAgIGxvYWRUaGVtZUludG9QaWNrZXJzKHN0YXJ0U2VsZWN0LnZhbHVlKTtcbiAgICBhcHBseUNvbG9yc0xpdmUoZ2V0Q3VycmVudENvbG9ycygpKTtcbiAgfSk7XG5cbiAgLy8gUG9wdWxhdGUgYW5kIHJlZnJlc2ggdGhlIGVkaXQtZXhpc3RpbmcgZHJvcGRvd25cbiAgZnVuY3Rpb24gcmVmcmVzaEVkaXREcm9wZG93bigpIHtcbiAgICB2YXIgdXNlclRoZW1lcyA9IHNhZmVHZXRKU09OKHdpbmRvdy5VU0VSX1RIRU1FU19LRVksIHt9KTtcbiAgICB2YXIgc2x1Z3MgPSBPYmplY3Qua2V5cyh1c2VyVGhlbWVzKTtcbiAgICBlZGl0U2VsZWN0LmlubmVySFRNTCA9ICc8b3B0aW9uIHZhbHVlPVwiXCI+XHUyMDE0IE5ldyBUaGVtZSBcdTIwMTQ8L29wdGlvbj4nO1xuICAgIHNsdWdzLmZvckVhY2goZnVuY3Rpb24gKHNsdWcpIHtcbiAgICAgIHZhciBvcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdvcHRpb24nKTtcbiAgICAgIG9wdC52YWx1ZSA9IHNsdWc7XG4gICAgICBvcHQudGV4dENvbnRlbnQgPSB1c2VyVGhlbWVzW3NsdWddLm5hbWUgfHwgc2x1ZztcbiAgICAgIGVkaXRTZWxlY3QuYXBwZW5kQ2hpbGQob3B0KTtcbiAgICB9KTtcbiAgICBleGlzdGluZ1NlY3Rpb24uc3R5bGUuZGlzcGxheSA9IHNsdWdzLmxlbmd0aCA/ICcnIDogJ25vbmUnO1xuICB9XG5cbiAgLy8gQWxzbyByZWZyZXNoIFwiU3RhcnQgZnJvbVwiIG9wdGlvbnNcbiAgZnVuY3Rpb24gcmVmcmVzaFN0YXJ0RnJvbSgpIHtcbiAgICBzdGFydFNlbGVjdC5pbm5lckhUTUwgPSBidWlsZFN0YXJ0RnJvbU9wdGlvbnMoKTtcbiAgfVxuXG4gIC8vIEVkaXQgZHJvcGRvd24gY2hhbmdlXG4gIGVkaXRTZWxlY3QuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgZnVuY3Rpb24gKCkge1xuICAgIHZhciBzbHVnID0gdGhpcy52YWx1ZTtcbiAgICBpZiAoc2x1Zykge1xuICAgICAgZWRpdGluZ1NsdWcgPSBzbHVnO1xuICAgICAgbG9hZFVzZXJUaGVtZUludG9QaWNrZXJzKHNsdWcpO1xuICAgICAgYXBwbHlDb2xvcnNMaXZlKGdldEN1cnJlbnRDb2xvcnMoKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVkaXRpbmdTbHVnID0gbnVsbDtcbiAgICAgIGFkdmFuY2VkT3ZlcnJpZGVzID0ge307XG4gICAgICBuYW1lSW5wdXQudmFsdWUgPSAnJztcbiAgICAgIHN0YXJ0U2VsZWN0LnZhbHVlID0gd2luZG93LmdldEFjdGl2ZVRoZW1lKCk7XG4gICAgICBsb2FkVGhlbWVJbnRvUGlja2VycyhzdGFydFNlbGVjdC52YWx1ZSk7XG4gICAgfVxuICAgIGV4cG9ydEJ0bi5zdHlsZS5kaXNwbGF5ID0gZWRpdGluZ1NsdWcgPyAnJyA6ICdub25lJztcbiAgfSk7XG5cbiAgZnVuY3Rpb24gb3BlbkJ1aWxkZXIoKSB7XG4gICAgdGhlbWVCZWZvcmVCdWlsZGVyID0gd2luZG93LmdldEFjdGl2ZVRoZW1lKCk7XG4gICAgZWRpdGluZ1NsdWcgPSBudWxsO1xuICAgIGFkdmFuY2VkT3ZlcnJpZGVzID0ge307XG5cbiAgICAvLyBSZXNldCBhZHZhbmNlZCBzZWN0aW9uIHRvIGNvbGxhcHNlZFxuICAgIGFkdmFuY2VkVmlzaWJsZSA9IGZhbHNlO1xuICAgIGFkdmFuY2VkU2VjdGlvbi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIGFkdmFuY2VkVG9nZ2xlLmlubmVySFRNTCA9ICdTaG93IGFkdmFuY2VkIGNvbG9ycyAmIzk2NjA7JztcblxuICAgIHJlZnJlc2hFZGl0RHJvcGRvd24oKTtcbiAgICByZWZyZXNoU3RhcnRGcm9tKCk7XG5cbiAgICB2YXIgdXNlclRoZW1lcyA9IHNhZmVHZXRKU09OKHdpbmRvdy5VU0VSX1RIRU1FU19LRVksIHt9KTtcbiAgICBpZiAodXNlclRoZW1lc1t0aGVtZUJlZm9yZUJ1aWxkZXJdKSB7XG4gICAgICAvLyBBY3RpdmUgdGhlbWUgaXMgYSB1c2VyIHRoZW1lIFx1MjAxNCBvcGVuIGl0IGZvciBlZGl0aW5nXG4gICAgICBlZGl0U2VsZWN0LnZhbHVlID0gdGhlbWVCZWZvcmVCdWlsZGVyO1xuICAgICAgZWRpdGluZ1NsdWcgPSB0aGVtZUJlZm9yZUJ1aWxkZXI7XG4gICAgICBsb2FkVXNlclRoZW1lSW50b1BpY2tlcnModGhlbWVCZWZvcmVCdWlsZGVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZWRpdFNlbGVjdC52YWx1ZSA9ICcnO1xuICAgICAgbmFtZUlucHV0LnZhbHVlID0gJyc7XG4gICAgICBzdGFydFNlbGVjdC52YWx1ZSA9IHRoZW1lQmVmb3JlQnVpbGRlcjtcbiAgICAgIGxvYWRUaGVtZUludG9QaWNrZXJzKHRoZW1lQmVmb3JlQnVpbGRlcik7XG4gICAgfVxuXG4gICAgZXhwb3J0QnRuLnN0eWxlLmRpc3BsYXkgPSBlZGl0aW5nU2x1ZyA/ICcnIDogJ25vbmUnO1xuICAgIG1vZGFsLmNsYXNzTGlzdC5hZGQoJ3Nob3cnKTtcbiAgfVxuXG4gIHZhciBjdXN0b21pemVCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGhlbWUtY3VzdG9taXplLWJ0bicpO1xuICBpZiAoY3VzdG9taXplQnRuKSB7XG4gICAgY3VzdG9taXplQnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24gKCkgeyBvcGVuQnVpbGRlcigpOyB9KTtcbiAgfVxuXG4gIC8vIFx1MjUwMFx1MjUwMFx1MjUwMCBTYXZlIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxuXG4gIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0aGVtZS1idWlsZGVyLXNhdmUnKS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgY29sb3JzID0gZ2V0Q3VycmVudENvbG9ycygpO1xuICAgIHZhciBuYW1lID0gbmFtZUlucHV0LnZhbHVlLnRyaW0oKTtcbiAgICBpZiAoIW5hbWUpIHtcbiAgICAgIHNob3dOb3RpZmljYXRpb24oJ1BsZWFzZSBlbnRlciBhIHRoZW1lIG5hbWUnLCAnd2FybmluZycsIDMwMDApO1xuICAgICAgbmFtZUlucHV0LmZvY3VzKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHVzZXJUaGVtZXMgPSBzYWZlR2V0SlNPTih3aW5kb3cuVVNFUl9USEVNRVNfS0VZLCB7fSk7XG4gICAgdmFyIHNsdWc7XG4gICAgdmFyIG9sZFNsdWcgPSBudWxsO1xuXG4gICAgaWYgKGVkaXRpbmdTbHVnKSB7XG4gICAgICBzbHVnID0gZWRpdGluZ1NsdWc7XG4gICAgICAvLyBJZiBuYW1lIGNoYW5nZWQsIHJlLXNsdWdpZnkgYW5kIHBvdGVudGlhbGx5IHJlbmFtZVxuICAgICAgdmFyIG5ld1NsdWcgPSB3aW5kb3cuc2x1Z2lmeVRoZW1lTmFtZShuYW1lLCBlZGl0aW5nU2x1Zyk7XG4gICAgICBpZiAobmV3U2x1ZyAhPT0gZWRpdGluZ1NsdWcpIHtcbiAgICAgICAgb2xkU2x1ZyA9IGVkaXRpbmdTbHVnO1xuICAgICAgICBkZWxldGUgdXNlclRoZW1lc1tlZGl0aW5nU2x1Z107XG4gICAgICAgIHZhciBpZHggPSB3aW5kb3cuVEhFTUVTLmluZGV4T2YoZWRpdGluZ1NsdWcpO1xuICAgICAgICBpZiAoaWR4ICE9PSAtMSkgd2luZG93LlRIRU1FUy5zcGxpY2UoaWR4LCAxKTtcbiAgICAgICAgZGVsZXRlIHdpbmRvdy5USEVNRV9DT0xPUlNbZWRpdGluZ1NsdWddO1xuICAgICAgICBzbHVnID0gbmV3U2x1ZztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc2x1ZyA9IHdpbmRvdy5zbHVnaWZ5VGhlbWVOYW1lKG5hbWUpO1xuICAgIH1cblxuICAgIC8vIEJ1aWxkIHRoZW1lIGRhdGEgd2l0aCBBTEwgY29sb3IgcHJvcGVydGllc1xuICAgIHZhciB0aGVtZURhdGEgPSB7IG5hbWU6IG5hbWUgfTtcbiAgICBpZiAobGlnaHRCZ0NoZWNrLmNoZWNrZWQpIHRoZW1lRGF0YS5saWdodEJnID0gdHJ1ZTtcbiAgICB3aW5kb3cuVEhFTUVfUFJPUFMuZm9yRWFjaChmdW5jdGlvbiAocCkge1xuICAgICAgaWYgKGNvbG9yc1twXSkgdGhlbWVEYXRhW3BdID0gY29sb3JzW3BdO1xuICAgIH0pO1xuXG4gICAgLy8gVXBkYXRlIGxvY2FsU3RvcmFnZSBjYWNoZSBpbW1lZGlhdGVseSBmb3IgaW5zdGFudCBVSVxuICAgIHVzZXJUaGVtZXNbc2x1Z10gPSB0aGVtZURhdGE7XG4gICAgc2FmZVNldCh3aW5kb3cuVVNFUl9USEVNRVNfS0VZLCBKU09OLnN0cmluZ2lmeSh1c2VyVGhlbWVzKSk7XG5cbiAgICAvLyBDbGVhciBpbmxpbmUgcHJldmlldyBwcm9wZXJ0aWVzXG4gICAgd2luZG93LmNsZWFyQ3VzdG9tUHJvcGVydGllcygpO1xuXG4gICAgLy8gUmUtaW5qZWN0IENTUyBhbmQgYXBwbHlcbiAgICB3aW5kb3cuaW5qZWN0VXNlclRoZW1lU3R5bGVzKCk7XG4gICAgd2luZG93LmFwcGx5VGhlbWUoc2x1Zyk7XG4gICAgbW9kYWwuY2xhc3NMaXN0LnJlbW92ZSgnc2hvdycpO1xuICAgIHVwZGF0ZUxhYmVsKCk7XG5cbiAgICAvLyBTYXZlIHRvIHNlcnZlciAoc291cmNlIG9mIHRydXRoKVxuICAgIHZhciBhcGlDb2xvcnMgPSB7fTtcbiAgICB3aW5kb3cuVEhFTUVfUFJPUFMuZm9yRWFjaChmdW5jdGlvbiAocCkgeyBpZiAoY29sb3JzW3BdKSBhcGlDb2xvcnNbcF0gPSBjb2xvcnNbcF07IH0pO1xuXG4gICAgLy8gSWYgc2x1ZyBjaGFuZ2VkLCBkZWxldGUgdGhlIG9sZCBvbmUgZnJvbSBzZXJ2ZXJcbiAgICBpZiAob2xkU2x1Zykge1xuICAgICAgc2VjdXJlRmV0Y2goJy9hcGkvdjEvdGhlbWVzLycgKyBvbGRTbHVnLCB7IG1ldGhvZDogJ0RFTEVURScgfSkuY2F0Y2goZnVuY3Rpb24gKCkge30pO1xuICAgIH1cblxuICAgIHNlY3VyZUZldGNoKCcvYXBpL3YxL3RoZW1lcy8nICsgc2x1Zywge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsgbmFtZTogbmFtZSwgY29sb3JzOiBhcGlDb2xvcnMsIGxpZ2h0Qmc6IGxpZ2h0QmdDaGVjay5jaGVja2VkIH0pXG4gICAgfSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICBzaG93Tm90aWZpY2F0aW9uKG5hbWUgKyAnIHRoZW1lIHNhdmVkJywgJ3N1Y2Nlc3MnLCAzMDAwKTtcbiAgICB9KS5jYXRjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzaG93Tm90aWZpY2F0aW9uKG5hbWUgKyAnIHRoZW1lIHNhdmVkIGxvY2FsbHkgKHNlcnZlciBzeW5jIGZhaWxlZCknLCAnd2FybmluZycsIDMwMDApO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyBcdTI1MDBcdTI1MDBcdTI1MDAgQ2FuY2VsIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxuXG4gIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0aGVtZS1idWlsZGVyLWNhbmNlbCcpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgIG1vZGFsLmNsYXNzTGlzdC5yZW1vdmUoJ3Nob3cnKTtcbiAgICB3aW5kb3cuY2xlYXJDdXN0b21Qcm9wZXJ0aWVzKCk7XG4gICAgaWYgKHRoZW1lQmVmb3JlQnVpbGRlcikge1xuICAgICAgd2luZG93LmFwcGx5VGhlbWUodGhlbWVCZWZvcmVCdWlsZGVyKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIFx1MjUwMFx1MjUwMFx1MjUwMCBEZWxldGUgXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXG5cbiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RoZW1lLWJ1aWxkZXItZGVsZXRlJykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFlZGl0aW5nU2x1ZykgcmV0dXJuO1xuXG4gICAgdmFyIHVzZXJUaGVtZXMgPSBzYWZlR2V0SlNPTih3aW5kb3cuVVNFUl9USEVNRVNfS0VZLCB7fSk7XG4gICAgdmFyIG5hbWUgPSB1c2VyVGhlbWVzW2VkaXRpbmdTbHVnXSA/IHVzZXJUaGVtZXNbZWRpdGluZ1NsdWddLm5hbWUgOiBlZGl0aW5nU2x1ZztcblxuICAgIGlmICghY29uZmlybSgnRGVsZXRlIFwiJyArIG5hbWUgKyAnXCIgdGhlbWU/JykpIHJldHVybjtcblxuICAgIHZhciBzbHVnVG9EZWxldGUgPSBlZGl0aW5nU2x1ZztcblxuICAgIC8vIFVwZGF0ZSBsb2NhbFN0b3JhZ2UgY2FjaGUgaW1tZWRpYXRlbHlcbiAgICBkZWxldGUgdXNlclRoZW1lc1tzbHVnVG9EZWxldGVdO1xuICAgIHNhZmVTZXQod2luZG93LlVTRVJfVEhFTUVTX0tFWSwgSlNPTi5zdHJpbmdpZnkodXNlclRoZW1lcykpO1xuXG4gICAgLy8gUmVtb3ZlIGZyb20gcnVudGltZVxuICAgIHZhciBpZHggPSB3aW5kb3cuVEhFTUVTLmluZGV4T2Yoc2x1Z1RvRGVsZXRlKTtcbiAgICBpZiAoaWR4ICE9PSAtMSkgd2luZG93LlRIRU1FUy5zcGxpY2UoaWR4LCAxKTtcbiAgICBkZWxldGUgd2luZG93LlRIRU1FX0NPTE9SU1tzbHVnVG9EZWxldGVdO1xuXG4gICAgd2luZG93LmNsZWFyQ3VzdG9tUHJvcGVydGllcygpO1xuICAgIHdpbmRvdy5pbmplY3RVc2VyVGhlbWVTdHlsZXMoKTtcblxuICAgIHZhciBmYWxsYmFjayA9IHRoZW1lQmVmb3JlQnVpbGRlciAmJiB0aGVtZUJlZm9yZUJ1aWxkZXIgIT09IHNsdWdUb0RlbGV0ZSA/IHRoZW1lQmVmb3JlQnVpbGRlciA6ICdkYXJrJztcbiAgICB3aW5kb3cuYXBwbHlUaGVtZShmYWxsYmFjayk7XG5cbiAgICBlZGl0aW5nU2x1ZyA9IG51bGw7XG4gICAgbW9kYWwuY2xhc3NMaXN0LnJlbW92ZSgnc2hvdycpO1xuICAgIHVwZGF0ZUxhYmVsKCk7XG5cbiAgICAvLyBEZWxldGUgZnJvbSBzZXJ2ZXJcbiAgICBzZWN1cmVGZXRjaCgnL2FwaS92MS90aGVtZXMvJyArIHNsdWdUb0RlbGV0ZSwgeyBtZXRob2Q6ICdERUxFVEUnIH0pLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgc2hvd05vdGlmaWNhdGlvbihuYW1lICsgJyB0aGVtZSBkZWxldGVkJywgJ3N1Y2Nlc3MnLCAzMDAwKTtcbiAgICB9KS5jYXRjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzaG93Tm90aWZpY2F0aW9uKG5hbWUgKyAnIHRoZW1lIGRlbGV0ZWQgbG9jYWxseSAoc2VydmVyIHN5bmMgZmFpbGVkKScsICd3YXJuaW5nJywgMzAwMCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIFx1MjUwMFx1MjUwMFx1MjUwMCBFeHBvcnQgXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXG5cbiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RoZW1lLWJ1aWxkZXItZXhwb3J0JykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFlZGl0aW5nU2x1Zykge1xuICAgICAgc2hvd05vdGlmaWNhdGlvbignU2F2ZSB0aGUgdGhlbWUgZmlyc3QsIHRoZW4gZXhwb3J0JywgJ3dhcm5pbmcnLCAzMDAwKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHVzZXJUaGVtZXMgPSBzYWZlR2V0SlNPTih3aW5kb3cuVVNFUl9USEVNRVNfS0VZLCB7fSk7XG4gICAgdmFyIHRoZW1lID0gdXNlclRoZW1lc1tlZGl0aW5nU2x1Z107XG4gICAgaWYgKCF0aGVtZSkgcmV0dXJuO1xuXG4gICAgdmFyIGV4cG9ydERhdGEgPSB7XG4gICAgICBfZGFzaGNhZGR5X3RoZW1lOiB0cnVlLFxuICAgICAgdmVyc2lvbjogJzEuMCcsXG4gICAgICBleHBvcnREYXRlOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICBzbHVnOiBlZGl0aW5nU2x1ZyxcbiAgICAgIG5hbWU6IHRoZW1lLm5hbWUsXG4gICAgICBsaWdodEJnOiB0aGVtZS5saWdodEJnIHx8IGZhbHNlLFxuICAgICAgY29sb3JzOiB7fVxuICAgIH07XG4gICAgd2luZG93LlRIRU1FX1BST1BTLmZvckVhY2goZnVuY3Rpb24gKHApIHtcbiAgICAgIGlmICh0aGVtZVtwXSkgZXhwb3J0RGF0YS5jb2xvcnNbcF0gPSB0aGVtZVtwXTtcbiAgICB9KTtcblxuICAgIHZhciBibG9iID0gbmV3IEJsb2IoW0pTT04uc3RyaW5naWZ5KGV4cG9ydERhdGEsIG51bGwsIDIpXSwgeyB0eXBlOiAnYXBwbGljYXRpb24vanNvbicgfSk7XG4gICAgdmFyIHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgdmFyIGEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG4gICAgYS5ocmVmID0gdXJsO1xuICAgIGEuZG93bmxvYWQgPSBlZGl0aW5nU2x1ZyArICctdGhlbWUuanNvbic7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChhKTtcbiAgICBhLmNsaWNrKCk7XG4gICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChhKTtcbiAgICBVUkwucmV2b2tlT2JqZWN0VVJMKHVybCk7XG4gICAgc2hvd05vdGlmaWNhdGlvbignVGhlbWUgZXhwb3J0ZWQgYXMgJyArIGVkaXRpbmdTbHVnICsgJy10aGVtZS5qc29uJywgJ3N1Y2Nlc3MnLCAzMDAwKTtcbiAgfSk7XG5cbiAgLy8gXHUyNTAwXHUyNTAwXHUyNTAwIEltcG9ydCBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcblxuICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGhlbWUtYnVpbGRlci1pbXBvcnQnKS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpO1xuICAgIGlucHV0LnR5cGUgPSAnZmlsZSc7XG4gICAgaW5wdXQuYWNjZXB0ID0gJy5qc29uJztcbiAgICBpbnB1dC5vbmNoYW5nZSA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICB2YXIgZmlsZSA9IGUudGFyZ2V0LmZpbGVzWzBdO1xuICAgICAgaWYgKCFmaWxlKSByZXR1cm47XG4gICAgICB2YXIgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcbiAgICAgIHJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB2YXIgZGF0YSA9IEpTT04ucGFyc2UoZXYudGFyZ2V0LnJlc3VsdCk7XG5cbiAgICAgICAgICAvLyBTdXBwb3J0IGJvdGggd3JhcHBlZCBmb3JtYXQgYW5kIHJhdyB0aGVtZSBmb3JtYXRcbiAgICAgICAgICB2YXIgdGhlbWVOYW1lLCB0aGVtZUNvbG9ycywgdGhlbWVMaWdodEJnO1xuICAgICAgICAgIGlmIChkYXRhLl9kYXNoY2FkZHlfdGhlbWUgJiYgZGF0YS5jb2xvcnMpIHtcbiAgICAgICAgICAgIC8vIFdyYXBwZWQgZXhwb3J0IGZvcm1hdFxuICAgICAgICAgICAgdGhlbWVOYW1lID0gZGF0YS5uYW1lIHx8ICdJbXBvcnRlZCc7XG4gICAgICAgICAgICB0aGVtZUNvbG9ycyA9IGRhdGEuY29sb3JzO1xuICAgICAgICAgICAgdGhlbWVMaWdodEJnID0gZGF0YS5saWdodEJnIHx8IGZhbHNlO1xuICAgICAgICAgIH0gZWxzZSBpZiAoZGF0YS5uYW1lICYmIChkYXRhLmJnIHx8IGRhdGFbJ2NhcmQtYmFzZSddKSkge1xuICAgICAgICAgICAgLy8gUmF3IHRoZW1lIEpTT04gKHNhbWUgZm9ybWF0IGFzIHNlcnZlciBmaWxlcylcbiAgICAgICAgICAgIHRoZW1lTmFtZSA9IGRhdGEubmFtZTtcbiAgICAgICAgICAgIHRoZW1lQ29sb3JzID0ge307XG4gICAgICAgICAgICB3aW5kb3cuVEhFTUVfUFJPUFMuZm9yRWFjaChmdW5jdGlvbiAocCkgeyBpZiAoZGF0YVtwXSkgdGhlbWVDb2xvcnNbcF0gPSBkYXRhW3BdOyB9KTtcbiAgICAgICAgICAgIHRoZW1lTGlnaHRCZyA9IGRhdGEubGlnaHRCZyB8fCBmYWxzZTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgYSB2YWxpZCBEYXNoQ2FkZHkgdGhlbWUgZmlsZScpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIExvYWQgaW50byBidWlsZGVyXG4gICAgICAgICAgbmFtZUlucHV0LnZhbHVlID0gdGhlbWVOYW1lO1xuICAgICAgICAgIGxpZ2h0QmdDaGVjay5jaGVja2VkID0gISF0aGVtZUxpZ2h0Qmc7XG4gICAgICAgICAgZWRpdGluZ1NsdWcgPSBudWxsO1xuICAgICAgICAgIGVkaXRTZWxlY3QudmFsdWUgPSAnJztcbiAgICAgICAgICBhZHZhbmNlZE92ZXJyaWRlcyA9IHt9O1xuXG4gICAgICAgICAgLy8gQXBwbHkgY29sb3JzIHRvIHBpY2tlcnNcbiAgICAgICAgICBwaWNrZXJzLmZvckVhY2goZnVuY3Rpb24gKHApIHtcbiAgICAgICAgICAgIHZhciB2YWwgPSB0aGVtZUNvbG9yc1twLmRhdGFzZXQucHJvcF0gfHwgJyMwMDAwMDAnO1xuICAgICAgICAgICAgcC52YWx1ZSA9IHZhbDtcbiAgICAgICAgICAgIHZhciBoZXggPSBtb2RhbC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1oZXg9XCInICsgcC5kYXRhc2V0LnByb3AgKyAnXCJdJyk7XG4gICAgICAgICAgICBpZiAoaGV4KSBoZXgudGV4dENvbnRlbnQgPSB2YWwudG9VcHBlckNhc2UoKTtcbiAgICAgICAgICAgIGlmIChwLmRhdGFzZXQuYWR2YW5jZWQgJiYgdGhlbWVDb2xvcnNbcC5kYXRhc2V0LnByb3BdKSB7XG4gICAgICAgICAgICAgIGFkdmFuY2VkT3ZlcnJpZGVzW3AuZGF0YXNldC5wcm9wXSA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAvLyBGaWxsIGFueSBtaXNzaW5nIGFkdmFuY2VkIGZpZWxkc1xuICAgICAgICAgIHVwZGF0ZUFkdmFuY2VkRnJvbURlcml2ZWQoKTtcbiAgICAgICAgICB1cGRhdGVQcmV2aWV3KCk7XG4gICAgICAgICAgYXBwbHlDb2xvcnNMaXZlKGdldEN1cnJlbnRDb2xvcnMoKSk7XG4gICAgICAgICAgZXhwb3J0QnRuLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgICAgc2hvd05vdGlmaWNhdGlvbignXCInICsgdGhlbWVOYW1lICsgJ1wiIGxvYWRlZCBpbnRvIGJ1aWxkZXIuIENsaWNrIFNhdmUgdG8ga2VlcCBpdC4nLCAnc3VjY2VzcycsIDUwMDApO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICBzaG93Tm90aWZpY2F0aW9uKCdJbXBvcnQgZmFpbGVkOiAnICsgZXJyLm1lc3NhZ2UsICdlcnJvcicsIDUwMDApO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgcmVhZGVyLnJlYWRBc1RleHQoZmlsZSk7XG4gICAgfTtcbiAgICBpbnB1dC5jbGljaygpO1xuICB9KTtcblxuICAvLyBcdTI1MDBcdTI1MDBcdTI1MDAgTW9kYWwgY2xvc2UgaGFuZGxpbmcgXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXG5cbiAgd2lyZU1vZGFsKG1vZGFsKTtcblxuICBtb2RhbC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgaWYgKGUudGFyZ2V0ID09PSBtb2RhbCkge1xuICAgICAgd2luZG93LmNsZWFyQ3VzdG9tUHJvcGVydGllcygpO1xuICAgICAgaWYgKHRoZW1lQmVmb3JlQnVpbGRlcikgd2luZG93LmFwcGx5VGhlbWUodGhlbWVCZWZvcmVCdWlsZGVyKTtcbiAgICB9XG4gIH0pO1xufSkoKTtcbjtcbi8vIExpY2Vuc2UgTWFuYWdlbWVudCBVSVxuKGZ1bmN0aW9uKCkge1xuICAvLyBJbmplY3QgbGljZW5zZSBtb2RhbCBIVE1MXG4gIGluamVjdE1vZGFsKCdsaWNlbnNlLW1vZGFsJywgYDxkaXYgaWQ9XCJsaWNlbnNlLW1vZGFsXCIgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsXCI+XG4gICAgPGRpdiBjbGFzcz1cIndlYXRoZXItbW9kYWwtY29udGVudFwiIHN0eWxlPVwibWluLXdpZHRoOiA0MjBweDsgbWF4LXdpZHRoOiA1MjBweDtcIj5cbiAgICAgIDxoMz5EYXNoQ2FkZHkgTGljZW5zZTwvaDM+XG4gICAgICA8cCBzdHlsZT1cImZvbnQtc2l6ZTogMC44NXJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luOiAwIDAgMTZweDtcIj5cbiAgICAgICAgQWN0aXZhdGUgYSBsaWNlbnNlIGNvZGUgdG8gdW5sb2NrIHByZW1pdW0gZmVhdHVyZXMuXG4gICAgICA8L3A+XG5cbiAgICAgIDxkaXYgaWQ9XCJsaWNlbnNlLXN0YXR1cy1zZWN0aW9uXCIgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiAxNnB4O1wiPlxuICAgICAgICA8ZGl2IGlkPVwibGljZW5zZS1iYWRnZVwiIHN0eWxlPVwiZGlzcGxheTogaW5saW5lLWZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogNnB4OyBwYWRkaW5nOiA2cHggMTRweDsgYm9yZGVyLXJhZGl1czogMjBweDsgZm9udC1zaXplOiAwLjg1cmVtOyBmb250LXdlaWdodDogNjAwOyBtYXJnaW4tYm90dG9tOiAxMnB4O1wiPlxuICAgICAgICAgIDxzcGFuIGlkPVwibGljZW5zZS1iYWRnZS1pY29uXCI+PC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGlkPVwibGljZW5zZS1iYWRnZS10ZXh0XCI+PC9zcGFuPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBpZD1cImxpY2Vuc2UtZGV0YWlsc1wiIHN0eWxlPVwiZm9udC1zaXplOiAwLjg1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBsaW5lLWhlaWdodDogMS42O1wiPjwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgaWQ9XCJsaWNlbnNlLWFjdGl2YXRlLXNlY3Rpb25cIj5cbiAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbC1ib2xkXCI+TGljZW5zZSBDb2RlOjwvbGFiZWw+XG4gICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGlkPVwibGljZW5zZS1jb2RlLWlucHV0XCIgcGxhY2Vob2xkZXI9XCJEQy1YWFhYWC1YWFhYWC1YWFhYWC1YWFhYWC1YWFhYWFwiXG4gICAgICAgICAgbWF4bGVuZ3RoPVwiMzVcIiBzcGVsbGNoZWNrPVwiZmFsc2VcIiBhdXRvY29tcGxldGU9XCJvZmZcIlxuICAgICAgICAgIHN0eWxlPVwid2lkdGg6IDEwMCU7IHBhZGRpbmc6IDEwcHggMTJweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgYm9yZGVyLXJhZGl1czogNHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJnKTsgY29sb3I6IHZhcigtLWZnKTsgZm9udC1zaXplOiAxcmVtOyBmb250LWZhbWlseTogbW9ub3NwYWNlOyBsZXR0ZXItc3BhY2luZzogMXB4O1wiIC8+XG4gICAgICAgIDxwIGNsYXNzPVwidGlueS1oaW50XCI+RW50ZXIgeW91ciBsaWNlbnNlIGNvZGUgdG8gYWN0aXZhdGUgcHJlbWl1bSBmZWF0dXJlczwvcD5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGlkPVwibGljZW5zZS1mZWF0dXJlc1wiIHN0eWxlPVwibWFyZ2luLXRvcDogMTZweDtcIj5cbiAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbC1ib2xkXCIgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiA4cHg7IGRpc3BsYXk6IGJsb2NrO1wiPlByZW1pdW0gRmVhdHVyZXM6PC9sYWJlbD5cbiAgICAgICAgPGRpdiBpZD1cImxpY2Vuc2UtZmVhdHVyZS1saXN0XCIgc3R5bGU9XCJkaXNwbGF5OiBncmlkOyBnYXA6IDhweDtcIj48L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGlkPVwibGljZW5zZS1lcnJvclwiIHN0eWxlPVwiZGlzcGxheTogbm9uZTsgbWFyZ2luLXRvcDogMTJweDsgcGFkZGluZzogMTBweDsgYm9yZGVyLXJhZGl1czogNHB4OyBiYWNrZ3JvdW5kOiByZ2JhKDIzMSw3Niw2MCwwLjE1KTsgY29sb3I6IHZhcigtLWJhZC1mZyk7IGZvbnQtc2l6ZTogMC44NXJlbTtcIj48L2Rpdj5cbiAgICAgIDxkaXYgaWQ9XCJsaWNlbnNlLXN1Y2Nlc3NcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7IG1hcmdpbi10b3A6IDEycHg7IHBhZGRpbmc6IDEwcHg7IGJvcmRlci1yYWRpdXM6IDRweDsgYmFja2dyb3VuZDogcmdiYSg0NiwyMDQsMTEzLDAuMTUpOyBjb2xvcjogdmFyKC0tb2stZmcpOyBmb250LXNpemU6IDAuODVyZW07XCI+PC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsLWJ1dHRvbnNcIiBzdHlsZT1cIm1hcmdpbi10b3A6IDE2cHg7XCI+XG4gICAgICAgIDxidXR0b24gaWQ9XCJsaWNlbnNlLWNhbmNlbFwiPkNsb3NlPC9idXR0b24+XG4gICAgICAgIDxidXR0b24gaWQ9XCJsaWNlbnNlLWRlYWN0aXZhdGVcIiBjbGFzcz1cImJ0bi1hY2NlbnRcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7IGJhY2tncm91bmQ6IHZhcigtLWJhZC1iZyk7IGJvcmRlci1jb2xvcjogdmFyKC0tYmFkLWZnKTsgY29sb3I6IHZhcigtLWJhZC1mZyk7XCI+RGVhY3RpdmF0ZTwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIGlkPVwibGljZW5zZS1hY3RpdmF0ZVwiIGNsYXNzPVwiYnRuLWFjY2VudFwiPkFjdGl2YXRlPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+YCk7XG5cbiAgY29uc3QgbW9kYWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbGljZW5zZS1tb2RhbCcpO1xuICBjb25zdCBjb2RlSW5wdXQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbGljZW5zZS1jb2RlLWlucHV0Jyk7XG4gIGNvbnN0IGFjdGl2YXRlQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2xpY2Vuc2UtYWN0aXZhdGUnKTtcbiAgY29uc3QgZGVhY3RpdmF0ZUJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsaWNlbnNlLWRlYWN0aXZhdGUnKTtcbiAgY29uc3QgZXJyb3JFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsaWNlbnNlLWVycm9yJyk7XG4gIGNvbnN0IHN1Y2Nlc3NFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsaWNlbnNlLXN1Y2Nlc3MnKTtcbiAgY29uc3QgYmFkZ2VJY29uID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2xpY2Vuc2UtYmFkZ2UtaWNvbicpO1xuICBjb25zdCBiYWRnZVRleHQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbGljZW5zZS1iYWRnZS10ZXh0Jyk7XG4gIGNvbnN0IGJhZGdlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2xpY2Vuc2UtYmFkZ2UnKTtcbiAgY29uc3QgZGV0YWlsc0VsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2xpY2Vuc2UtZGV0YWlscycpO1xuICBjb25zdCBmZWF0dXJlTGlzdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsaWNlbnNlLWZlYXR1cmUtbGlzdCcpO1xuICBjb25zdCBhY3RpdmF0ZVNlY3Rpb24gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbGljZW5zZS1hY3RpdmF0ZS1zZWN0aW9uJyk7XG5cbiAgbGV0IGN1cnJlbnRTdGF0dXMgPSBudWxsO1xuXG4gIGZ1bmN0aW9uIGhpZGVNZXNzYWdlcygpIHtcbiAgICBlcnJvckVsLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgc3VjY2Vzc0VsLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gIH1cblxuICBmdW5jdGlvbiBzaG93RXJyb3IobXNnKSB7XG4gICAgaGlkZU1lc3NhZ2VzKCk7XG4gICAgZXJyb3JFbC50ZXh0Q29udGVudCA9IG1zZztcbiAgICBlcnJvckVsLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICB9XG5cbiAgZnVuY3Rpb24gc2hvd1N1Y2Nlc3MobXNnKSB7XG4gICAgaGlkZU1lc3NhZ2VzKCk7XG4gICAgc3VjY2Vzc0VsLnRleHRDb250ZW50ID0gbXNnO1xuICAgIHN1Y2Nlc3NFbC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbmRlclN0YXR1cyhzdGF0dXMpIHtcbiAgICBjdXJyZW50U3RhdHVzID0gc3RhdHVzO1xuXG4gICAgaWYgKHN0YXR1cy5hY3RpdmUpIHtcbiAgICAgIGJhZGdlLnN0eWxlLmJhY2tncm91bmQgPSAncmdiYSg0NiwyMDQsMTEzLDAuMTUpJztcbiAgICAgIGJhZGdlLnN0eWxlLmNvbG9yID0gJ3ZhcigtLW9rLWZnKSc7XG4gICAgICBiYWRnZUljb24udGV4dENvbnRlbnQgPSAnXFx1MjYwNSc7XG4gICAgICBiYWRnZVRleHQudGV4dENvbnRlbnQgPSAnUHJlbWl1bSBBY3RpdmUnO1xuICAgICAgY29uc3QgZXhwaXJ5TGluZSA9IHN0YXR1cy5saWZldGltZVxuICAgICAgICA/ICc8ZGl2PkxpY2Vuc2U6IDxzdHJvbmc+TElGRVRJTUU8L3N0cm9uZz48L2Rpdj4nXG4gICAgICAgIDogYDxkaXY+RXhwaXJlczogPHN0cm9uZz4ke25ldyBEYXRlKHN0YXR1cy5leHBpcmVzQXQpLnRvTG9jYWxlRGF0ZVN0cmluZygpfTwvc3Ryb25nPiAoJHtzdGF0dXMuZGF5c1JlbWFpbmluZ30gZGF5cyByZW1haW5pbmcpPC9kaXY+YDtcbiAgICAgIGRldGFpbHNFbC5pbm5lckhUTUwgPSBgXG4gICAgICAgIDxkaXY+Q29kZTogPGNvZGUgc3R5bGU9XCJmb250LWZhbWlseTogbW9ub3NwYWNlO1wiPiR7c3RhdHVzLmNvZGUgfHwgJyoqKid9PC9jb2RlPjwvZGl2PlxuICAgICAgICAke2V4cGlyeUxpbmV9XG4gICAgICBgO1xuICAgICAgYWN0aXZhdGVTZWN0aW9uLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICBhY3RpdmF0ZUJ0bi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgZGVhY3RpdmF0ZUJ0bi5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJhZGdlLnN0eWxlLmJhY2tncm91bmQgPSAncmdiYSgxNDksMTY1LDE2NiwwLjE1KSc7XG4gICAgICBiYWRnZS5zdHlsZS5jb2xvciA9ICd2YXIoLS1tdXRlZCknO1xuICAgICAgYmFkZ2VJY29uLnRleHRDb250ZW50ID0gJ1xcdTI2MDYnO1xuICAgICAgYmFkZ2VUZXh0LnRleHRDb250ZW50ID0gc3RhdHVzLmV4cGlyZWQgPyAnTGljZW5zZSBFeHBpcmVkJyA6ICdGcmVlIFRpZXInO1xuICAgICAgZGV0YWlsc0VsLmlubmVySFRNTCA9IHN0YXR1cy5leHBpcmVkXG4gICAgICAgID8gJzxkaXY+WW91ciBsaWNlbnNlIGhhcyBleHBpcmVkLiBFbnRlciBhIG5ldyBjb2RlIHRvIHJlbmV3LjwvZGl2PidcbiAgICAgICAgOiAnPGRpdj5FbnRlciBhIGxpY2Vuc2UgY29kZSB0byB1bmxvY2sgcHJlbWl1bSBmZWF0dXJlcy48L2Rpdj4nO1xuICAgICAgYWN0aXZhdGVTZWN0aW9uLnN0eWxlLmRpc3BsYXkgPSAnJztcbiAgICAgIGFjdGl2YXRlQnRuLnN0eWxlLmRpc3BsYXkgPSAnJztcbiAgICAgIGRlYWN0aXZhdGVCdG4uc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICB9XG5cbiAgICAvLyBSZW5kZXIgZmVhdHVyZSBsaXN0XG4gICAgY29uc3QgZmVhdHVyZXMgPSBzdGF0dXMucHJlbWl1bUZlYXR1cmVzIHx8IHt9O1xuICAgIGNvbnN0IGFjdGl2ZUZlYXR1cmVzID0gbmV3IFNldChzdGF0dXMuZmVhdHVyZXMgfHwgW10pO1xuICAgIGZlYXR1cmVMaXN0LmlubmVySFRNTCA9IE9iamVjdC5lbnRyaWVzKGZlYXR1cmVzKS5tYXAoKFtrZXksIGluZm9dKSA9PiB7XG4gICAgICBjb25zdCBhY3RpdmUgPSBhY3RpdmVGZWF0dXJlcy5oYXMoa2V5KTtcbiAgICAgIHJldHVybiBgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogOHB4OyBwYWRkaW5nOiA4cHggMTJweDsgYm9yZGVyLXJhZGl1czogNnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJnKTsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcIj5cbiAgICAgICAgPHNwYW4gc3R5bGU9XCJmb250LXNpemU6IDEuMXJlbTtcIj4ke2FjdGl2ZSA/ICdcXHUyNzA1JyA6ICdcXHVEODNEXFx1REQxMid9PC9zcGFuPlxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIDxkaXYgc3R5bGU9XCJmb250LXdlaWdodDogNjAwOyBmb250LXNpemU6IDAuOXJlbTtcIj4ke2luZm8ubmFtZX08L2Rpdj5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjc4cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPiR7aW5mby5kZXNjcmlwdGlvbn08L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5gO1xuICAgIH0pLmpvaW4oJycpO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gbG9hZFN0YXR1cygpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL2xpY2Vuc2Uvc3RhdHVzJyk7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcC5qc29uKCk7XG4gICAgICBpZiAoZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgIHJlbmRlclN0YXR1cyhkYXRhLmxpY2Vuc2UpO1xuICAgICAgICB1cGRhdGVIZWFkZXJCYWRnZShkYXRhLmxpY2Vuc2UpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUud2FybignRmFpbGVkIHRvIGxvYWQgbGljZW5zZSBzdGF0dXM6JywgZS5tZXNzYWdlKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBhY3RpdmF0ZUxpY2Vuc2UoKSB7XG4gICAgY29uc3QgY29kZSA9IGNvZGVJbnB1dC52YWx1ZS50cmltKCk7XG4gICAgaWYgKCFjb2RlKSB7XG4gICAgICBzaG93RXJyb3IoJ1BsZWFzZSBlbnRlciBhIGxpY2Vuc2UgY29kZS4nKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBoaWRlTWVzc2FnZXMoKTtcbiAgICBhY3RpdmF0ZUJ0bi5kaXNhYmxlZCA9IHRydWU7XG4gICAgYWN0aXZhdGVCdG4udGV4dENvbnRlbnQgPSAnQWN0aXZhdGluZy4uLic7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IHNlY3VyZUZldGNoKCcvYXBpL3YxL2xpY2Vuc2UvYWN0aXZhdGUnLCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoeyBjb2RlIH0pXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwLmpzb24oKTtcblxuICAgICAgaWYgKGRhdGEuc3VjY2Vzcykge1xuICAgICAgICBzaG93U3VjY2VzcyhkYXRhLm1lc3NhZ2UpO1xuICAgICAgICBjb2RlSW5wdXQudmFsdWUgPSAnJztcbiAgICAgICAgcmVuZGVyU3RhdHVzKGRhdGEubGljZW5zZSk7XG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oJ0xpY2Vuc2UgYWN0aXZhdGVkISBQcmVtaXVtIGZlYXR1cmVzIHVubG9ja2VkLicsICdzdWNjZXNzJywgNTAwMCk7XG4gICAgICAgIHVwZGF0ZUhlYWRlckJhZGdlKGRhdGEubGljZW5zZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzaG93RXJyb3IoZGF0YS5lcnJvciB8fCAnQWN0aXZhdGlvbiBmYWlsZWQnKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBzaG93RXJyb3IoJ05ldHdvcmsgZXJyb3I6ICcgKyBlLm1lc3NhZ2UpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhY3RpdmF0ZUJ0bi5kaXNhYmxlZCA9IGZhbHNlO1xuICAgICAgYWN0aXZhdGVCdG4udGV4dENvbnRlbnQgPSAnQWN0aXZhdGUnO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGRlYWN0aXZhdGVMaWNlbnNlKCkge1xuICAgIGlmICghY29uZmlybSgnRGVhY3RpdmF0ZSB5b3VyIGxpY2Vuc2U/IFlvdSBjYW4gcmV1c2UgdGhlIGNvZGUgb24gYW5vdGhlciBtYWNoaW5lLicpKSByZXR1cm47XG5cbiAgICBkZWFjdGl2YXRlQnRuLmRpc2FibGVkID0gdHJ1ZTtcbiAgICBkZWFjdGl2YXRlQnRuLnRleHRDb250ZW50ID0gJ0RlYWN0aXZhdGluZy4uLic7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IHNlY3VyZUZldGNoKCcvYXBpL3YxL2xpY2Vuc2UvZGVhY3RpdmF0ZScsIHsgbWV0aG9kOiAnUE9TVCcgfSk7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcC5qc29uKCk7XG5cbiAgICAgIGlmIChkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgc2hvd1N1Y2Nlc3MoZGF0YS5tZXNzYWdlKTtcbiAgICAgICAgYXdhaXQgbG9hZFN0YXR1cygpO1xuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKCdMaWNlbnNlIGRlYWN0aXZhdGVkLicsICdpbmZvJywgMzAwMCk7XG4gICAgICAgIHVwZGF0ZUhlYWRlckJhZGdlKHsgYWN0aXZlOiBmYWxzZSB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNob3dFcnJvcihkYXRhLmVycm9yIHx8ICdEZWFjdGl2YXRpb24gZmFpbGVkJyk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgc2hvd0Vycm9yKCdOZXR3b3JrIGVycm9yOiAnICsgZS5tZXNzYWdlKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgZGVhY3RpdmF0ZUJ0bi5kaXNhYmxlZCA9IGZhbHNlO1xuICAgICAgZGVhY3RpdmF0ZUJ0bi50ZXh0Q29udGVudCA9ICdEZWFjdGl2YXRlJztcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVIZWFkZXJCYWRnZShzdGF0dXMpIHtcbiAgICBjb25zdCB0b3BiYXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbGljZW5zZS1zdGF0dXMtdG9wYmFyJyk7XG4gICAgY29uc3QgaWNvbkVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2xpY2Vuc2UtdG9wYmFyLWljb24nKTtcbiAgICBjb25zdCB0ZXh0RWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbGljZW5zZS10b3BiYXItdGV4dCcpO1xuICAgIGNvbnN0IHRpbWVFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsaWNlbnNlLXRvcGJhci10aW1lJyk7XG4gICAgaWYgKCF0b3BiYXIpIHJldHVybjtcblxuICAgIHRvcGJhci5jbGFzc05hbWUgPSAnbGljZW5zZS1zdGF0dXMtdG9wYmFyICcgKyAoc3RhdHVzLmFjdGl2ZSA/ICdwcmVtaXVtJyA6ICdmcmVlJyk7XG5cbiAgICBpZiAoc3RhdHVzLmFjdGl2ZSkge1xuICAgICAgaWNvbkVsLnRleHRDb250ZW50ID0gJ1xcdTI2MDUnO1xuICAgICAgdGV4dEVsLnRleHRDb250ZW50ID0gJ1BSRU1JVU0nO1xuICAgICAgaWYgKHN0YXR1cy5saWZldGltZSkge1xuICAgICAgICB0aW1lRWwudGV4dENvbnRlbnQgPSAnXFx1MDBiNyBMSUZFVElNRSc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBkYXlzID0gc3RhdHVzLmRheXNSZW1haW5pbmc7XG4gICAgICAgIHRpbWVFbC50ZXh0Q29udGVudCA9IGRheXMgIT0gbnVsbCA/ICdcXHUwMGI3ICcgKyBkYXlzICsgJ2QgcmVtYWluaW5nJyA6ICcnO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpY29uRWwudGV4dENvbnRlbnQgPSAnXFx1MjYwNic7XG4gICAgICB0ZXh0RWwudGV4dENvbnRlbnQgPSBzdGF0dXMuZXhwaXJlZCA/ICdFWFBJUkVEJyA6ICdGUkVFIFRJRVInO1xuICAgICAgdGltZUVsLnRleHRDb250ZW50ID0gJyc7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gb3BlbkxpY2Vuc2VNb2RhbCgpIHtcbiAgICBoaWRlTWVzc2FnZXMoKTtcbiAgICBsb2FkU3RhdHVzKCk7XG4gICAgbW9kYWwuY2xhc3NMaXN0LmFkZCgnc2hvdycpO1xuICB9XG5cbiAgLy8gRm9ybWF0IGNvZGUgaW5wdXQgYXMgdXNlciB0eXBlcyAoYXV0by1hZGQgZGFzaGVzKVxuICBjb2RlSW5wdXQuYWRkRXZlbnRMaXN0ZW5lcignaW5wdXQnLCBmdW5jdGlvbigpIHtcbiAgICBsZXQgdmFsID0gdGhpcy52YWx1ZS50b1VwcGVyQ2FzZSgpLnJlcGxhY2UoL1teQS1aMC05LV0vZywgJycpO1xuICAgIC8vIERvbid0IGF1dG8tZm9ybWF0IGlmIHVzZXIgaXMgZGVsZXRpbmdcbiAgICBpZiAodmFsLmxlbmd0aCA+IHRoaXMuX3ByZXZMZW5ndGgpIHtcbiAgICAgIHZhbCA9IHZhbC5yZXBsYWNlKC8tL2csICcnKTtcbiAgICAgIGlmICh2YWwubGVuZ3RoID4gMiAmJiAhdmFsLnN0YXJ0c1dpdGgoJ0RDJykpIHtcbiAgICAgICAgdmFsID0gJ0RDJyArIHZhbDtcbiAgICAgIH1cbiAgICAgIC8vIEFkZCBkYXNoZXMgYWZ0ZXIgREMgYW5kIGV2ZXJ5IDUgY2hhcnNcbiAgICAgIGlmICh2YWwuc3RhcnRzV2l0aCgnREMnKSAmJiB2YWwubGVuZ3RoID4gMikge1xuICAgICAgICBjb25zdCBwYXJ0cyA9IFsnREMnXTtcbiAgICAgICAgY29uc3QgcmVzdCA9IHZhbC5zdWJzdHJpbmcoMik7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVzdC5sZW5ndGg7IGkgKz0gNSkge1xuICAgICAgICAgIHBhcnRzLnB1c2gocmVzdC5zdWJzdHJpbmcoaSwgaSArIDUpKTtcbiAgICAgICAgfVxuICAgICAgICB2YWwgPSBwYXJ0cy5qb2luKCctJyk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuX3ByZXZMZW5ndGggPSB2YWwubGVuZ3RoO1xuICAgIHRoaXMudmFsdWUgPSB2YWw7XG4gIH0pO1xuXG4gIC8vIFdpcmUgdXAgZXZlbnRzXG4gIGFjdGl2YXRlQnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYWN0aXZhdGVMaWNlbnNlKTtcbiAgZGVhY3RpdmF0ZUJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGRlYWN0aXZhdGVMaWNlbnNlKTtcbiAgY29kZUlucHV0LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCAoZSkgPT4ge1xuICAgIGlmIChlLmtleSA9PT0gJ0VudGVyJykgYWN0aXZhdGVMaWNlbnNlKCk7XG4gIH0pO1xuICB3aXJlTW9kYWwobW9kYWwsIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsaWNlbnNlLWNhbmNlbCcpKTtcbiAgY29uc3QgdG9wYmFyRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbGljZW5zZS1zdGF0dXMtdG9wYmFyJyk7XG4gIGlmICh0b3BiYXJFbCkgdG9wYmFyRWwuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB3aW5kb3cub3BlbkxpY2Vuc2VNb2RhbCAmJiB3aW5kb3cub3BlbkxpY2Vuc2VNb2RhbCgpKTtcblxuICAvLyBFeHBvc2UgZm9yIG90aGVyIG1vZHVsZXMgdG8gb3BlblxuICB3aW5kb3cub3BlbkxpY2Vuc2VNb2RhbCA9IG9wZW5MaWNlbnNlTW9kYWw7XG5cbiAgLy8gRXhwb3NlIGZlYXR1cmUgY2hlY2sgZm9yIGZyb250ZW5kIGdhdGluZ1xuICB3aW5kb3cuY2hlY2tQcmVtaXVtRmVhdHVyZSA9IGFzeW5jIGZ1bmN0aW9uKGZlYXR1cmUpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IGZldGNoKGAvYXBpL3YxL2xpY2Vuc2UvZmVhdHVyZS8ke2ZlYXR1cmV9YCk7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcC5qc29uKCk7XG4gICAgICByZXR1cm4gZGF0YS5hdmFpbGFibGU7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9O1xuXG4gIC8vIExvYWQgc3RhdHVzIG9uIHBhZ2UgbG9hZFxuICBsb2FkU3RhdHVzKCkudGhlbihzdGF0dXMgPT4ge1xuICAgIGlmIChjdXJyZW50U3RhdHVzKSB1cGRhdGVIZWFkZXJCYWRnZShjdXJyZW50U3RhdHVzKTtcbiAgfSk7XG59KSgpO1xuO1xuLy8gU2hhcmUgTW9kYWwgXHUyMDE0IERDLTA1OFxuLy9cbi8vIEFkbWluIFVJIGZvciBEQy0wNTMgc2hhcmUgcm91dGVzLiBPcGVuZWQgZnJvbSB0aGUgXCJTaGFyZVwiIGJ1dHRvbiBvbiBlYWNoXG4vLyBzZXJ2aWNlIGNhcmQgKGFkZGVkIGluIGNvcmUvZ3JpZC5qcyBuZXh0IHRvIHRoZSBleGlzdGluZyBvcHRpb25zL2RlbGV0ZVxuLy8gYnV0dG9ucykuIFR3byB0YWJzOlxuLy8gICAtIFB1YmxpYyBsaW5rOiBwaWNrIGEgVFRMICgxaC8yNGgvN2QpLCBQT1NUIC9hcGkvdjEvc2hhcmUsIHJlbmRlciB0aGVcbi8vICAgICByZXR1cm5lZCB1cmxQYXRoIHdpdGggYSBjb3B5IGJ1dHRvbiArIHJldm9rZSBjb250cm9sLlxuLy8gICAtIFRhaWxzY2FsZSBpbnZpdGU6IGVudGVyIGFuIGVtYWlsLCBQT1NUIC9hcGkvdjEvc2hhcmUvdGFpbHNjYWxlLCByZW5kZXJcbi8vICAgICBkZWxpdmVyZWQgc3RhdHVzIChpbmJveCB2cyBkZXYtY29uc29sZSBmYWxsYmFjayB2cyBVUkwgZmFsbGJhY2spLlxuLy9cbi8vIE1vZGFsIGFsc28gbGlzdHMgb3V0c3RhbmRpbmcgc2hhcmVzIGZvciB0aGUgc2VsZWN0ZWQgc2VydmljZSAoR0VUIC9hcGkvdjEvc2hhcmUpXG4vLyB3aXRoIHJldm9rZSBidXR0b25zLiBUaGUgbGlzdCByZWZyZXNoZXMgYWZ0ZXIgZXZlcnkgaXNzdWUvcmV2b2tlLlxuLy9cbi8vIEJvdGggaXNzdWUgZW5kcG9pbnRzIGFyZSBQcm8tZ2F0ZWQgb24gdGhlIHNlcnZlciBcdTIwMTQgdGhlIG1vZGFsIHN1cmZhY2VzIGEgNDAyXG4vLyBhcyBhbiB1cGdyYWRlIHByb21wdCAoXCJTaGFyZSBpcyBhIFBybyBmZWF0dXJlLiBBY3RpdmF0ZSBhIGxpY2Vuc2UgdG8gdW5sb2NrLlwiKS5cbi8vIFRhaWxzY2FsZSBpbnZpdGVzIGFkZGl0aW9uYWxseSByZXF1aXJlIHRhaWxzY2FsZUNvb3JkIGNvbmZpZ3VyZWQgb24gdGhlIGhvc3Q7XG4vLyB0aGUgc2VydmVyIHJldHVybnMgNDAwIHdpdGggYSBjbGVhciBtZXNzYWdlIHdoZW4gbWlzc2luZy5cblxuKGZ1bmN0aW9uKCkge1xuICAndXNlIHN0cmljdCc7XG5cbiAgaWYgKHdpbmRvdy5fX2RjXzA1OF9zaGFyZV9tb2RhbF9sb2FkZWQpIHJldHVybjtcbiAgd2luZG93Ll9fZGNfMDU4X3NoYXJlX21vZGFsX2xvYWRlZCA9IHRydWU7XG5cbiAgY29uc3QgVFRMX09QVElPTlMgPSBbXG4gICAgeyBtczogNjAgKiA2MCAqIDEwMDAsIGxhYmVsOiAnMSBob3VyJyB9LFxuICAgIHsgbXM6IDI0ICogNjAgKiA2MCAqIDEwMDAsIGxhYmVsOiAnMjQgaG91cnMnIH0sXG4gICAgeyBtczogNyAqIDI0ICogNjAgKiA2MCAqIDEwMDAsIGxhYmVsOiAnNyBkYXlzJyB9LFxuICBdO1xuXG4gIGluamVjdE1vZGFsKCdzaGFyZS1tb2RhbCcsIGBcbiAgICA8ZGl2IGlkPVwic2hhcmUtbW9kYWxcIiBjbGFzcz1cIndlYXRoZXItbW9kYWxcIiByb2xlPVwiZGlhbG9nXCIgYXJpYS1sYWJlbGxlZGJ5PVwic2hhcmUtbW9kYWwtdGl0bGVcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsLWNvbnRlbnRcIiBzdHlsZT1cIm1pbi13aWR0aDogNDYwcHg7IG1heC13aWR0aDogNTgwcHg7XCI+XG4gICAgICAgIDxoMyBpZD1cInNoYXJlLW1vZGFsLXRpdGxlXCI+U2hhcmUgPHNwYW4gaWQ9XCJzaGFyZS1tb2RhbC1zZXJ2aWNlLW5hbWVcIj5cdTIwMjY8L3NwYW4+PC9oMz5cbiAgICAgICAgPHAgc3R5bGU9XCJmb250LXNpemU6IDAuODVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbjogMCAwIDE2cHg7XCI+XG4gICAgICAgICAgQ3JlYXRlIGEgcHVibGljIGxpbmsgb3IgVGFpbHNjYWxlIGludml0ZSBzbyBzb21lb25lIG91dHNpZGUgeW91ciBuZXR3b3JrIGNhbiBhY2Nlc3MgdGhpcyBzZXJ2aWNlLlxuICAgICAgICA8L3A+XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cInNoYXJlLXRhYnNcIiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGdhcDogNHB4OyBtYXJnaW4tYm90dG9tOiAxNnB4OyBib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcIj5cbiAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwic2hhcmUtdGFiIGFjdGl2ZVwiIGRhdGEtdGFiPVwicHVibGljXCIgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBzdHlsZT1cImJhY2tncm91bmQ6IHRyYW5zcGFyZW50OyBib3JkZXI6IDA7IGJvcmRlci1ib3R0b206IDJweCBzb2xpZCB2YXIoLS1hY2NlbnQpOyBwYWRkaW5nOiA4cHggMTRweDsgY29sb3I6IHZhcigtLWZnKTsgZm9udC13ZWlnaHQ6IDYwMDsgY3Vyc29yOiBwb2ludGVyO1wiPlxuICAgICAgICAgICAgUHVibGljIGxpbmtcbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwic2hhcmUtdGFiXCIgZGF0YS10YWI9XCJ0YWlsc2NhbGVcIiB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIHN0eWxlPVwiYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7IGJvcmRlcjogMDsgYm9yZGVyLWJvdHRvbTogMnB4IHNvbGlkIHRyYW5zcGFyZW50OyBwYWRkaW5nOiA4cHggMTRweDsgY29sb3I6IHZhcigtLW11dGVkKTsgY3Vyc29yOiBwb2ludGVyO1wiPlxuICAgICAgICAgICAgVGFpbHNjYWxlIGludml0ZVxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwic2hhcmUtdGFiLXBhbmVsXCIgZGF0YS1wYW5lbD1cInB1YmxpY1wiPlxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwtYm9sZFwiIGZvcj1cInNoYXJlLXB1YmxpYy10dGxcIj5MaW5rIGR1cmF0aW9uOjwvbGFiZWw+XG4gICAgICAgICAgPHNlbGVjdCBpZD1cInNoYXJlLXB1YmxpYy10dGxcIiBzdHlsZT1cIndpZHRoOiAxMDAlOyBwYWRkaW5nOiA4cHggMTBweDsgbWFyZ2luOiA2cHggMCAxMnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1pbnB1dC1iZyk7IGNvbG9yOiB2YXIoLS1mZyk7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJvcmRlci1yYWRpdXM6IDRweDtcIj5cbiAgICAgICAgICAgICR7VFRMX09QVElPTlMubWFwKG8gPT4gYDxvcHRpb24gdmFsdWU9XCIke28ubXN9XCI+JHtvLmxhYmVsfTwvb3B0aW9uPmApLmpvaW4oJycpfVxuICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgIDxidXR0b24gaWQ9XCJzaGFyZS1wdWJsaWMtY3JlYXRlXCIgY2xhc3M9XCJidG4tYWNjZW50XCIgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBzdHlsZT1cIndpZHRoOiAxMDAlOyBwYWRkaW5nOiAxMHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1hY2NlbnQpOyBjb2xvcjogIzA0MTQxZjsgYm9yZGVyOiAwOyBib3JkZXItcmFkaXVzOiA0cHg7IGZvbnQtd2VpZ2h0OiA2MDA7IGN1cnNvcjogcG9pbnRlcjtcIj5cbiAgICAgICAgICAgIENyZWF0ZSBzaGFyZSBsaW5rXG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJzaGFyZS10YWItcGFuZWxcIiBkYXRhLXBhbmVsPVwidGFpbHNjYWxlXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lO1wiPlxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwtYm9sZFwiIGZvcj1cInNoYXJlLXRzLWVtYWlsXCI+UmVjaXBpZW50IGVtYWlsOjwvbGFiZWw+XG4gICAgICAgICAgPGlucHV0IGlkPVwic2hhcmUtdHMtZW1haWxcIiB0eXBlPVwiZW1haWxcIiBwbGFjZWhvbGRlcj1cImFsaWNlQGV4YW1wbGUuY29tXCIgYXV0b2NvbXBsZXRlPVwib2ZmXCJcbiAgICAgICAgICAgIHN0eWxlPVwid2lkdGg6IDEwMCU7IHBhZGRpbmc6IDEwcHggMTJweDsgbWFyZ2luOiA2cHggMCAxMnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJnKTsgY29sb3I6IHZhcigtLWZnKTsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgYm9yZGVyLXJhZGl1czogNHB4OyBmb250LXNpemU6IDAuOTVyZW07XCIgLz5cbiAgICAgICAgICA8cCBzdHlsZT1cImZvbnQtc2l6ZTogMC44cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW46IDAgMCAxMnB4O1wiPlxuICAgICAgICAgICAgQSBzaW5nbGUtdXNlIFRhaWxzY2FsZSBwcmUtYXV0aCBrZXkgaXMgZ2VuZXJhdGVkIGFuZCBlbWFpbGVkLiBUaGUgZGV2aWNlIGpvaW5zIHlvdXIgdGFpbG5ldCBhbmQgaXMgcm91dGVkIHRvIHRoaXMgc2VydmljZSB2aWEgQ2FkZHkuXG4gICAgICAgICAgPC9wPlxuICAgICAgICAgIDxidXR0b24gaWQ9XCJzaGFyZS10cy1jcmVhdGVcIiBjbGFzcz1cImJ0bi1hY2NlbnRcIiB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIHN0eWxlPVwid2lkdGg6IDEwMCU7IHBhZGRpbmc6IDEwcHg7IGJhY2tncm91bmQ6IHZhcigtLWFjY2VudCk7IGNvbG9yOiAjMDQxNDFmOyBib3JkZXI6IDA7IGJvcmRlci1yYWRpdXM6IDRweDsgZm9udC13ZWlnaHQ6IDYwMDsgY3Vyc29yOiBwb2ludGVyO1wiPlxuICAgICAgICAgICAgQ3JlYXRlIFRhaWxzY2FsZSBpbnZpdGVcbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGRpdiBpZD1cInNoYXJlLWlzc3VlZFwiIHN0eWxlPVwiZGlzcGxheTogbm9uZTsgbWFyZ2luLXRvcDogMTZweDsgcGFkZGluZzogMTJweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iZyk7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJvcmRlci1yYWRpdXM6IDZweDtcIj5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjhyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi1ib3R0b206IDZweDtcIj5TaGFyZSBsaW5rOjwvZGl2PlxuICAgICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBnYXA6IDZweDsgYWxpZ24taXRlbXM6IGNlbnRlcjtcIj5cbiAgICAgICAgICAgIDxpbnB1dCBpZD1cInNoYXJlLWlzc3VlZC11cmxcIiB0eXBlPVwidGV4dFwiIHJlYWRvbmx5XG4gICAgICAgICAgICAgIHN0eWxlPVwiZmxleDogMTsgcGFkZGluZzogOHB4IDEwcHg7IGJhY2tncm91bmQ6IHZhcigtLWJnKTsgY29sb3I6IHZhcigtLWZnKTsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgYm9yZGVyLXJhZGl1czogNHB4OyBmb250LWZhbWlseTogbW9ub3NwYWNlOyBmb250LXNpemU6IDAuODVyZW07XCIgLz5cbiAgICAgICAgICAgIDxidXR0b24gaWQ9XCJzaGFyZS1pc3N1ZWQtY29weVwiIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBzdHlsZT1cInBhZGRpbmc6IDhweCAxNHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1hY2NlbnQpOyBjb2xvcjogIzA0MTQxZjsgYm9yZGVyOiAwOyBib3JkZXItcmFkaXVzOiA0cHg7IGZvbnQtd2VpZ2h0OiA2MDA7IGN1cnNvcjogcG9pbnRlcjtcIj5cbiAgICAgICAgICAgICAgQ29weVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdiBpZD1cInNoYXJlLWlzc3VlZC1tZXRhXCIgc3R5bGU9XCJmb250LXNpemU6IDAuOHJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLXRvcDogOHB4O1wiPjwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGlkPVwic2hhcmUtZXJyb3JcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7IG1hcmdpbi10b3A6IDEycHg7IHBhZGRpbmc6IDEwcHg7IGJvcmRlci1yYWRpdXM6IDRweDsgYmFja2dyb3VuZDogcmdiYSgyMzEsNzYsNjAsMC4xNSk7IGNvbG9yOiB2YXIoLS1iYWQtZmcpOyBmb250LXNpemU6IDAuODVyZW07XCI+PC9kaXY+XG4gICAgICAgIDxkaXYgaWQ9XCJzaGFyZS1zdWNjZXNzXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lOyBtYXJnaW4tdG9wOiAxMnB4OyBwYWRkaW5nOiAxMHB4OyBib3JkZXItcmFkaXVzOiA0cHg7IGJhY2tncm91bmQ6IHJnYmEoNDYsMjA0LDExMywwLjE1KTsgY29sb3I6IHZhcigtLW9rLWZnKTsgZm9udC1zaXplOiAwLjg1cmVtO1wiPjwvZGl2PlxuXG4gICAgICAgIDxkaXYgaWQ9XCJzaGFyZS1vdXRzdGFuZGluZ1wiIHN0eWxlPVwibWFyZ2luLXRvcDogMTZweDtcIj5cbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsLWJvbGRcIj5PdXRzdGFuZGluZyBzaGFyZXMgZm9yIHRoaXMgc2VydmljZTwvbGFiZWw+XG4gICAgICAgICAgPGRpdiBpZD1cInNoYXJlLW91dHN0YW5kaW5nLWxpc3RcIiBzdHlsZT1cIm1hcmdpbi10b3A6IDZweDsgZm9udC1zaXplOiAwLjg1cmVtO1wiPjwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwid2VhdGhlci1tb2RhbC1idXR0b25zXCIgc3R5bGU9XCJtYXJnaW4tdG9wOiAxOHB4O1wiPlxuICAgICAgICAgIDxidXR0b24gaWQ9XCJzaGFyZS1jYW5jZWxcIiB0eXBlPVwiYnV0dG9uXCI+Q2xvc2U8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgYCk7XG5cbiAgY29uc3QgbW9kYWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2hhcmUtbW9kYWwnKTtcbiAgY29uc3Qgc2VydmljZU5hbWVFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzaGFyZS1tb2RhbC1zZXJ2aWNlLW5hbWUnKTtcbiAgY29uc3QgaXNzdWVkRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2hhcmUtaXNzdWVkJyk7XG4gIGNvbnN0IGlzc3VlZFVybElucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NoYXJlLWlzc3VlZC11cmwnKTtcbiAgY29uc3QgaXNzdWVkQ29weUJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzaGFyZS1pc3N1ZWQtY29weScpO1xuICBjb25zdCBpc3N1ZWRNZXRhRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2hhcmUtaXNzdWVkLW1ldGEnKTtcbiAgY29uc3QgZXJyb3JFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzaGFyZS1lcnJvcicpO1xuICBjb25zdCBzdWNjZXNzRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2hhcmUtc3VjY2VzcycpO1xuICBjb25zdCBvdXRzdGFuZGluZ0xpc3RFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzaGFyZS1vdXRzdGFuZGluZy1saXN0Jyk7XG4gIGNvbnN0IGNhbmNlbEJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzaGFyZS1jYW5jZWwnKTtcbiAgY29uc3QgcHVibGljQ3JlYXRlQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NoYXJlLXB1YmxpYy1jcmVhdGUnKTtcbiAgY29uc3QgdHNDcmVhdGVCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2hhcmUtdHMtY3JlYXRlJyk7XG4gIGNvbnN0IHRzRW1haWxJbnB1dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzaGFyZS10cy1lbWFpbCcpO1xuICBjb25zdCBwdWJsaWNUdGxTZWxlY3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2hhcmUtcHVibGljLXR0bCcpO1xuXG4gIGxldCBjdXJyZW50U2VydmljZSA9IG51bGw7IC8vIHsgaWQsIG5hbWUgfVxuICBsZXQgYWN0aXZlVGFiID0gJ3B1YmxpYyc7XG5cbiAgZnVuY3Rpb24gaGlkZU1lc3NhZ2VzKCkge1xuICAgIGVycm9yRWwuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICBzdWNjZXNzRWwuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICBpc3N1ZWRFbC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICB9XG5cbiAgZnVuY3Rpb24gc2hvd0Vycm9yKG1zZykge1xuICAgIHN1Y2Nlc3NFbC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIGlzc3VlZEVsLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgZXJyb3JFbC50ZXh0Q29udGVudCA9IG1zZztcbiAgICBlcnJvckVsLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICB9XG5cbiAgZnVuY3Rpb24gc2hvd1N1Y2Nlc3MobXNnKSB7XG4gICAgZXJyb3JFbC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIHN1Y2Nlc3NFbC50ZXh0Q29udGVudCA9IG1zZztcbiAgICBzdWNjZXNzRWwuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gIH1cblxuICBmdW5jdGlvbiBfb3JpZ2luRnJvbVBhZ2UoKSB7XG4gICAgLy8gQnVpbGQgdGhlIGFic29sdXRlIHNoYXJlIFVSTCBmcm9tIHRoZSBwYWdlJ3MgY3VycmVudCBvcmlnaW4gc28gdGhlXG4gICAgLy8gbGluayBpcyBjb3JyZWN0IHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGUgdXNlciBpcyBvbiBodHRwOi8vbG9jYWxob3N0XG4gICAgLy8gKGRldikgb3IgaHR0cHM6Ly9zdGF0dXMuc2FtaSAocHJvZCkuIFRoZSB1cmxQYXRoIHJldHVybmVkIGJ5IHRoZSBBUElcbiAgICAvLyBpcyBhIHBhdGgtb25seSBzdHJpbmcgc3RhcnRpbmcgd2l0aCAvc2hhcmUvLlxuICAgIHJldHVybiB3aW5kb3cubG9jYXRpb24ub3JpZ2luO1xuICB9XG5cbiAgZnVuY3Rpb24gX2Fic1VybCh1cmxQYXRoKSB7XG4gICAgaWYgKHVybFBhdGguc3RhcnRzV2l0aCgnaHR0cCcpKSByZXR1cm4gdXJsUGF0aDtcbiAgICByZXR1cm4gX29yaWdpbkZyb21QYWdlKCkgKyB1cmxQYXRoO1xuICB9XG5cbiAgZnVuY3Rpb24gX2Zvcm1hdEV4cGlyeShpc28pIHtcbiAgICBpZiAoIWlzbykgcmV0dXJuICcnO1xuICAgIGNvbnN0IGQgPSBuZXcgRGF0ZShpc28pO1xuICAgIGlmIChOdW1iZXIuaXNOYU4oZC5nZXRUaW1lKCkpKSByZXR1cm4gJyc7XG4gICAgcmV0dXJuIGQudG9Mb2NhbGVTdHJpbmcoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIF9mb3JtYXRSZW1haW5pbmcobXMpIHtcbiAgICBpZiAobXMgPD0gMCkgcmV0dXJuICdleHBpcmVkJztcbiAgICBjb25zdCBoID0gTWF0aC5mbG9vcihtcyAvIDM2MDAwMDApO1xuICAgIGlmIChoID49IDI0KSByZXR1cm4gYCR7TWF0aC5mbG9vcihoIC8gMjQpfWQgJHtoICUgMjR9aCBsZWZ0YDtcbiAgICBjb25zdCBtID0gTWF0aC5mbG9vcigobXMgJSAzNjAwMDAwKSAvIDYwMDAwKTtcbiAgICByZXR1cm4gYCR7aH1oICR7bX1tIGxlZnRgO1xuICB9XG5cbiAgZnVuY3Rpb24gc2V0QWN0aXZlVGFiKG5hbWUpIHtcbiAgICBhY3RpdmVUYWIgPSBuYW1lO1xuICAgIGhpZGVNZXNzYWdlcygpO1xuICAgIG1vZGFsLnF1ZXJ5U2VsZWN0b3JBbGwoJy5zaGFyZS10YWInKS5mb3JFYWNoKGJ0biA9PiB7XG4gICAgICBjb25zdCBpc0FjdGl2ZSA9IGJ0bi5kYXRhc2V0LnRhYiA9PT0gbmFtZTtcbiAgICAgIGJ0bi5jbGFzc0xpc3QudG9nZ2xlKCdhY3RpdmUnLCBpc0FjdGl2ZSk7XG4gICAgICBidG4uc3R5bGUuYm9yZGVyQm90dG9tQ29sb3IgPSBpc0FjdGl2ZSA/ICd2YXIoLS1hY2NlbnQpJyA6ICd0cmFuc3BhcmVudCc7XG4gICAgICBidG4uc3R5bGUuY29sb3IgPSBpc0FjdGl2ZSA/ICd2YXIoLS1mZyknIDogJ3ZhcigtLW11dGVkKSc7XG4gICAgICBidG4uc3R5bGUuZm9udFdlaWdodCA9IGlzQWN0aXZlID8gJzYwMCcgOiAnNDAwJztcbiAgICB9KTtcbiAgICBtb2RhbC5xdWVyeVNlbGVjdG9yQWxsKCcuc2hhcmUtdGFiLXBhbmVsJykuZm9yRWFjaChwID0+IHtcbiAgICAgIHAuc3R5bGUuZGlzcGxheSA9IHAuZGF0YXNldC5wYW5lbCA9PT0gbmFtZSA/ICcnIDogJ25vbmUnO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gbG9hZE91dHN0YW5kaW5nKCkge1xuICAgIG91dHN0YW5kaW5nTGlzdEVsLmlubmVySFRNTCA9ICc8c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+TG9hZGluZ1x1MjAyNjwvc3Bhbj4nO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwID0gYXdhaXQgZmV0Y2goJy9hcGkvdjEvc2hhcmUnLCB7IGNyZWRlbnRpYWxzOiAnc2FtZS1vcmlnaW4nIH0pO1xuICAgICAgaWYgKCFyZXNwLm9rKSB7XG4gICAgICAgIG91dHN0YW5kaW5nTGlzdEVsLmlubmVySFRNTCA9ICc8c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+Tm8gc2hhcmVzIGxpc3RlZC48L3NwYW4+JztcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgYm9keSA9IGF3YWl0IHJlc3AuanNvbigpO1xuICAgICAgY29uc3QgbGlzdCA9IChib2R5ICYmIGJvZHkuZGF0YSkgfHwgW107XG4gICAgICBjb25zdCBmaWx0ZXJlZCA9IGxpc3QuZmlsdGVyKHMgPT4gcy5zZXJ2aWNlSWQgPT09IGN1cnJlbnRTZXJ2aWNlLmlkKTtcbiAgICAgIGlmIChmaWx0ZXJlZC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgb3V0c3RhbmRpbmdMaXN0RWwuaW5uZXJIVE1MID0gJzxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTtcIj5ObyBvdXRzdGFuZGluZyBzaGFyZXMgZm9yIHRoaXMgc2VydmljZS48L3NwYW4+JztcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgb3V0c3RhbmRpbmdMaXN0RWwuaW5uZXJIVE1MID0gZmlsdGVyZWQubWFwKHMgPT4ge1xuICAgICAgICBjb25zdCByZW1haW5pbmcgPSBzLmV4cGlyZXNBdCA/IF9mb3JtYXRSZW1haW5pbmcobmV3IERhdGUocy5leHBpcmVzQXQpLmdldFRpbWUoKSAtIERhdGUubm93KCkpIDogJyc7XG4gICAgICAgIHJldHVybiBgXG4gICAgICAgICAgPGRpdiBjbGFzcz1cInNoYXJlLXJvd1wiIGRhdGEtc2hhcmUtaWQ9XCIke2VzY2FwZUh0bWwocy5pZCl9XCJcbiAgICAgICAgICAgIHN0eWxlPVwiZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA4cHg7IHBhZGRpbmc6IDZweCAwOyBib3JkZXItYm90dG9tOiAxcHggZGFzaGVkIHZhcigtLWJvcmRlcik7XCI+XG4gICAgICAgICAgICA8c3BhbiBzdHlsZT1cImZsZXg6IDE7XCI+XG4gICAgICAgICAgICAgIDxzdHJvbmc+JHtzLmtpbmQgPT09ICd0YWlsc2NhbGUnID8gJ1RhaWxzY2FsZScgOiAnUHVibGljJ308L3N0cm9uZz5cbiAgICAgICAgICAgICAgPHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPiBcdTAwQjcgZXhwaXJlcyAke2VzY2FwZUh0bWwoX2Zvcm1hdEV4cGlyeShzLmV4cGlyZXNBdCkpfSAoJHtyZW1haW5pbmd9KTwvc3Bhbj5cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJzaGFyZS1yZXZva2VcIiBkYXRhLXNoYXJlLWlkPVwiJHtlc2NhcGVIdG1sKHMuaWQpfVwiIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBzdHlsZT1cInBhZGRpbmc6IDRweCAxMHB4OyBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDsgY29sb3I6IHZhcigtLWJhZC1mZyk7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJhZC1mZyk7IGJvcmRlci1yYWRpdXM6IDRweDsgY3Vyc29yOiBwb2ludGVyOyBmb250LXNpemU6IDAuOHJlbTtcIj5cbiAgICAgICAgICAgICAgUmV2b2tlXG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgYDtcbiAgICAgIH0pLmpvaW4oJycpO1xuICAgICAgb3V0c3RhbmRpbmdMaXN0RWwucXVlcnlTZWxlY3RvckFsbCgnLnNoYXJlLXJldm9rZScpLmZvckVhY2goYnRuID0+IHtcbiAgICAgICAgYnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4gcmV2b2tlU2hhcmUoYnRuLmRhdGFzZXQuc2hhcmVJZCkpO1xuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgb3V0c3RhbmRpbmdMaXN0RWwuaW5uZXJIVE1MID0gJzxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTtcIj5Db3VsZCBub3QgbG9hZCBvdXRzdGFuZGluZyBzaGFyZXMuPC9zcGFuPic7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gcmV2b2tlU2hhcmUoaWQpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IGZldGNoKGAvYXBpL3YxL3NoYXJlLyR7ZW5jb2RlVVJJQ29tcG9uZW50KGlkKX1gLCB7XG4gICAgICAgIG1ldGhvZDogJ0RFTEVURScsXG4gICAgICAgIGNyZWRlbnRpYWxzOiAnc2FtZS1vcmlnaW4nLFxuICAgICAgfSk7XG4gICAgICBpZiAoIXJlc3Aub2spIHtcbiAgICAgICAgY29uc3QgYm9keSA9IGF3YWl0IHJlc3AuanNvbigpLmNhdGNoKCgpID0+ICh7fSkpO1xuICAgICAgICBzaG93RXJyb3IoYm9keSAmJiBib2R5LmVycm9yIHx8IGBSZXZva2UgZmFpbGVkIChIVFRQICR7cmVzcC5zdGF0dXN9KS5gKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgc2hvd1N1Y2Nlc3MoJ1NoYXJlIHJldm9rZWQuJyk7XG4gICAgICBsb2FkT3V0c3RhbmRpbmcoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBzaG93RXJyb3IoJ05ldHdvcmsgZXJyb3Igd2hpbGUgcmV2b2tpbmcuJyk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gaXNzdWVQdWJsaWMoKSB7XG4gICAgaWYgKCFjdXJyZW50U2VydmljZSkgcmV0dXJuO1xuICAgIGhpZGVNZXNzYWdlcygpO1xuICAgIHB1YmxpY0NyZWF0ZUJ0bi5kaXNhYmxlZCA9IHRydWU7XG4gICAgY29uc3Qgb3JpZ2luYWwgPSBwdWJsaWNDcmVhdGVCdG4udGV4dENvbnRlbnQ7XG4gICAgcHVibGljQ3JlYXRlQnRuLnRleHRDb250ZW50ID0gJ0NyZWF0aW5nXHUyMDI2JztcbiAgICB0cnkge1xuICAgICAgY29uc3QgdHRsTXMgPSBwYXJzZUludChwdWJsaWNUdGxTZWxlY3QudmFsdWUsIDEwKTtcbiAgICAgIGNvbnN0IHJlc3AgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS9zaGFyZScsIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGNyZWRlbnRpYWxzOiAnc2FtZS1vcmlnaW4nLFxuICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoeyBzZXJ2aWNlSWQ6IGN1cnJlbnRTZXJ2aWNlLmlkLCB0dGxNcyB9KSxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgYm9keSA9IGF3YWl0IHJlc3AuanNvbigpLmNhdGNoKCgpID0+ICh7fSkpO1xuICAgICAgaWYgKCFyZXNwLm9rIHx8ICFib2R5LnN1Y2Nlc3MpIHtcbiAgICAgICAgX3JlbmRlckFwaUVycm9yKHJlc3Auc3RhdHVzLCBib2R5KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgdXJsUGF0aCA9IGJvZHkuZGF0YS51cmxQYXRoO1xuICAgICAgaXNzdWVkVXJsSW5wdXQudmFsdWUgPSBfYWJzVXJsKHVybFBhdGgpO1xuICAgICAgaXNzdWVkTWV0YUVsLnRleHRDb250ZW50ID0gYFB1YmxpYyBsaW5rIFx1MDBCNyBleHBpcmVzICR7X2Zvcm1hdEV4cGlyeShib2R5LmRhdGEuZXhwaXJlc0F0KX1gO1xuICAgICAgaXNzdWVkRWwuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICBzaG93U3VjY2VzcygnU2hhcmUgbGluayBjcmVhdGVkLicpO1xuICAgICAgbG9hZE91dHN0YW5kaW5nKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgc2hvd0Vycm9yKCdOZXR3b3JrIGVycm9yIHdoaWxlIGNyZWF0aW5nIHNoYXJlLicpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBwdWJsaWNDcmVhdGVCdG4uZGlzYWJsZWQgPSBmYWxzZTtcbiAgICAgIHB1YmxpY0NyZWF0ZUJ0bi50ZXh0Q29udGVudCA9IG9yaWdpbmFsO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGlzc3VlVGFpbHNjYWxlKCkge1xuICAgIGlmICghY3VycmVudFNlcnZpY2UpIHJldHVybjtcbiAgICBjb25zdCBlbWFpbCA9ICh0c0VtYWlsSW5wdXQudmFsdWUgfHwgJycpLnRyaW0oKTtcbiAgICBpZiAoIWVtYWlsIHx8ICFlbWFpbC5pbmNsdWRlcygnQCcpKSB7XG4gICAgICBzaG93RXJyb3IoJ0EgdmFsaWQgcmVjaXBpZW50IGVtYWlsIGlzIHJlcXVpcmVkLicpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBoaWRlTWVzc2FnZXMoKTtcbiAgICB0c0NyZWF0ZUJ0bi5kaXNhYmxlZCA9IHRydWU7XG4gICAgY29uc3Qgb3JpZ2luYWwgPSB0c0NyZWF0ZUJ0bi50ZXh0Q29udGVudDtcbiAgICB0c0NyZWF0ZUJ0bi50ZXh0Q29udGVudCA9ICdDcmVhdGluZ1x1MjAyNic7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3AgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS9zaGFyZS90YWlsc2NhbGUnLCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBjcmVkZW50aWFsczogJ3NhbWUtb3JpZ2luJyxcbiAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsgc2VydmljZUlkOiBjdXJyZW50U2VydmljZS5pZCwgZW1haWwgfSksXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGJvZHkgPSBhd2FpdCByZXNwLmpzb24oKS5jYXRjaCgoKSA9PiAoe30pKTtcbiAgICAgIGlmICghcmVzcC5vayB8fCAhYm9keS5zdWNjZXNzKSB7XG4gICAgICAgIF9yZW5kZXJBcGlFcnJvcihyZXNwLnN0YXR1cywgYm9keSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIC8vIFRhaWxzY2FsZSBzaGFyZXMgc2hvdyB0aGUgcmF3IHVybFBhdGggKHdoaWNoIGlzIHRoZSBzaGFyZSBVUkwpIGlmXG4gICAgICAvLyBlbWFpbCBkZWxpdmVyeSBmYWlsZWQuIFRoZSBzaGFyZSBpdHNlbGYgaXMgb25lLXNob3Qgc28gdGhlIGFkbWluXG4gICAgICAvLyBjYW4gbWFudWFsbHkgcGFzdGUgdGhlIGxpbmsgaW50byBhIGNoYXQgaWYgU01UUCBmYWlsZWQuXG4gICAgICBjb25zdCBmYWxsYmFjayA9IGJvZHkuZGF0YSAmJiBib2R5LmRhdGEudXJsUGF0aDtcbiAgICAgIGlmIChmYWxsYmFjaykge1xuICAgICAgICBpc3N1ZWRVcmxJbnB1dC52YWx1ZSA9IF9hYnNVcmwoZmFsbGJhY2spO1xuICAgICAgICBpc3N1ZWRNZXRhRWwudGV4dENvbnRlbnQgPSBgVGFpbHNjYWxlIGludml0ZSBcdTAwQjcgZW1haWxlZCB0byAke2VtYWlsfSAob3IgdXNlIHRoaXMgVVJMIG1hbnVhbGx5IGlmIGRlbGl2ZXJ5IGZhaWxlZCkuYDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlzc3VlZFVybElucHV0LnZhbHVlID0gJyc7XG4gICAgICAgIGlzc3VlZE1ldGFFbC50ZXh0Q29udGVudCA9IGBUYWlsc2NhbGUgaW52aXRlIHNlbnQgdG8gJHtlbWFpbH0uYDtcbiAgICAgIH1cbiAgICAgIGlzc3VlZEVsLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgc2hvd1N1Y2Nlc3MoJ1RhaWxzY2FsZSBpbnZpdGUgY3JlYXRlZC4nKTtcbiAgICAgIHRzRW1haWxJbnB1dC52YWx1ZSA9ICcnO1xuICAgICAgbG9hZE91dHN0YW5kaW5nKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgc2hvd0Vycm9yKCdOZXR3b3JrIGVycm9yIHdoaWxlIGNyZWF0aW5nIFRhaWxzY2FsZSBpbnZpdGUuJyk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRzQ3JlYXRlQnRuLmRpc2FibGVkID0gZmFsc2U7XG4gICAgICB0c0NyZWF0ZUJ0bi50ZXh0Q29udGVudCA9IG9yaWdpbmFsO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIF9yZW5kZXJBcGlFcnJvcihzdGF0dXMsIGJvZHkpIHtcbiAgICBjb25zdCBlcnIgPSAoYm9keSAmJiBib2R5LmVycm9yKSB8fCAnJztcbiAgICBpZiAoc3RhdHVzID09PSA0MDIpIHtcbiAgICAgIHNob3dFcnJvcignU2hhcmUgaXMgYSBQcm8gZmVhdHVyZS4gQWN0aXZhdGUgYSBsaWNlbnNlIHRvIHVubG9jay4nKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHN0YXR1cyA9PT0gNDAwICYmIC90YWlsc2NhbGUvaS50ZXN0KGVycikpIHtcbiAgICAgIHNob3dFcnJvcignVGFpbHNjYWxlIGlzIG5vdCBjb25maWd1cmVkIG9uIHRoaXMgaG9zdC4gU2V0IHVwIFRhaWxzY2FsZSBpbiB0aGUgZGFzaGJvYXJkIGZpcnN0LicpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoc3RhdHVzID09PSA0MDMpIHtcbiAgICAgIHNob3dFcnJvcignWW91IGRvIG5vdCBoYXZlIHBlcm1pc3Npb24gdG8gc2hhcmUgc2VydmljZXMuJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChzdGF0dXMgPT09IDQwNCkge1xuICAgICAgc2hvd0Vycm9yKCdTZXJ2aWNlIG5vdCBmb3VuZC4gSXQgbWF5IGhhdmUgYmVlbiBkZWxldGVkLicpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzaG93RXJyb3IoZXJyIHx8IGBSZXF1ZXN0IGZhaWxlZCAoSFRUUCAke3N0YXR1c30pLmApO1xuICB9XG5cbiAgZnVuY3Rpb24gb3BlblNoYXJlTW9kYWwoc2VydmljZSkge1xuICAgIGlmICghc2VydmljZSB8fCAhc2VydmljZS5pZCkgcmV0dXJuO1xuICAgIGN1cnJlbnRTZXJ2aWNlID0geyBpZDogc2VydmljZS5pZCwgbmFtZTogc2VydmljZS5uYW1lIHx8IHNlcnZpY2UuaWQgfTtcbiAgICBzZXJ2aWNlTmFtZUVsLnRleHRDb250ZW50ID0gY3VycmVudFNlcnZpY2UubmFtZTtcbiAgICBoaWRlTWVzc2FnZXMoKTtcbiAgICBzZXRBY3RpdmVUYWIoJ3B1YmxpYycpO1xuICAgIHRzRW1haWxJbnB1dC52YWx1ZSA9ICcnO1xuICAgIHB1YmxpY1R0bFNlbGVjdC52YWx1ZSA9IFN0cmluZyhUVExfT1BUSU9OU1sxXS5tcyk7IC8vIDI0aCBkZWZhdWx0XG4gICAgbW9kYWwuY2xhc3NMaXN0LmFkZCgnc2hvdycpO1xuICAgIGxvYWRPdXRzdGFuZGluZygpO1xuICB9XG5cbiAgLy8gV2lyZSBldmVudHNcbiAgbW9kYWwucXVlcnlTZWxlY3RvckFsbCgnLnNoYXJlLXRhYicpLmZvckVhY2goYnRuID0+IHtcbiAgICBidG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiBzZXRBY3RpdmVUYWIoYnRuLmRhdGFzZXQudGFiKSk7XG4gIH0pO1xuICBwdWJsaWNDcmVhdGVCdG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBpc3N1ZVB1YmxpYyk7XG4gIHRzQ3JlYXRlQnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgaXNzdWVUYWlsc2NhbGUpO1xuICBjYW5jZWxCdG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiBtb2RhbC5jbGFzc0xpc3QucmVtb3ZlKCdzaG93JykpO1xuICB3aXJlTW9kYWwobW9kYWwsIGNhbmNlbEJ0bik7XG5cbiAgLy8gQ29weS10by1jbGlwYm9hcmQgZm9yIHRoZSBpc3N1ZWQgc2hhcmUgVVJMXG4gIGlzc3VlZENvcHlCdG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdXJsID0gaXNzdWVkVXJsSW5wdXQudmFsdWU7XG4gICAgaWYgKCF1cmwpIHJldHVybjtcbiAgICB0cnkge1xuICAgICAgaWYgKG5hdmlnYXRvci5jbGlwYm9hcmQgJiYgbmF2aWdhdG9yLmNsaXBib2FyZC53cml0ZVRleHQpIHtcbiAgICAgICAgYXdhaXQgbmF2aWdhdG9yLmNsaXBib2FyZC53cml0ZVRleHQodXJsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEZhbGxiYWNrIGZvciBvbGRlciBicm93c2VycyAvIHVuc2FmZSBjb250ZXh0c1xuICAgICAgICBpc3N1ZWRVcmxJbnB1dC5zZWxlY3QoKTtcbiAgICAgICAgZG9jdW1lbnQuZXhlY0NvbW1hbmQoJ2NvcHknKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG9yaWdpbmFsID0gaXNzdWVkQ29weUJ0bi50ZXh0Q29udGVudDtcbiAgICAgIGlzc3VlZENvcHlCdG4udGV4dENvbnRlbnQgPSAnQ29waWVkISc7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHsgaXNzdWVkQ29weUJ0bi50ZXh0Q29udGVudCA9IG9yaWdpbmFsOyB9LCAxMjAwKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBzaG93RXJyb3IoJ0NvdWxkIG5vdCBjb3B5IHRvIGNsaXBib2FyZC4gU2VsZWN0IHRoZSBVUkwgbWFudWFsbHkuJyk7XG4gICAgfVxuICB9KTtcblxuICAvLyBFeHBvc2UgZm9yIG90aGVyIG1vZHVsZXMgdG8gb3BlblxuICB3aW5kb3cub3BlblNoYXJlTW9kYWwgPSBvcGVuU2hhcmVNb2RhbDtcbn0pKCk7XG47XG4vKipcbiAqIERDLTA3NzogaTE4biBGcm9udGVuZCBcdTIwMTQgTGFuZ3VhZ2Ugc2VsZWN0b3IgYW5kIHRyYW5zbGF0aW9uIHN5c3RlbVxuICogXG4gKiBQcm92aWRlcyB3aW5kb3cuRENJMThuLnQoa2V5KSBmb3IgdGhlIGRhc2hib2FyZCBmcm9udGVuZC5cbiAqIExvYWRzIHRyYW5zbGF0aW9ucyBmcm9tIC9hcGkvdjEvaTE4bi90cmFuc2xhdGlvbnMvOmxhbmdcbiAqIExhbmd1YWdlIHByZWZlcmVuY2Ugc3RvcmVkIGluIGxvY2FsU3RvcmFnZS5cbiAqIEhhbmRsZXMgUlRMIGZvciBBcmFiaWMuXG4gKi9cbihmdW5jdGlvbiAoKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICBjb25zdCBTVE9SQUdFX0tFWSA9ICdkYXNoY2FkZHktbGFuZ3VhZ2UnO1xuICBjb25zdCBERUZBVUxUX0xBTkcgPSAnZW4nO1xuICAvLyBNdXN0IG1hdGNoIHRoZSAzMSBsYW5ndWFnZXMgaW4gbGFuZ3VhZ2Utc2VsZWN0b3IuanMgYW5kIHRoZSBiYWNrZW5kIGkxOG4gcm91dGUuXG4gIGNvbnN0IFNVUFBPUlRFRF9MQU5HUyA9IFtcbiAgICAnZW4nLCAnYXInLCAnYm4nLCAnY3MnLCAnZGEnLCAnZGUnLCAnZWwnLCAnZXMnLCAnZmEnLCAnZmknLFxuICAgICdmcicsICdoaScsICdodScsICdpZCcsICdpdCcsICdqYScsICdrbycsICdtcycsICdubCcsICdubycsXG4gICAgJ3BsJywgJ3B0JywgJ3JvJywgJ3J1JywgJ3N2JywgJ3RoJywgJ3RyJywgJ3VrJywgJ3VyJywgJ3ZpJywgJ3poJyxcbiAgXTtcbiAgY29uc3QgTEFOR19OQU1FUyA9IHtcbiAgICBlbjogJ0VuZ2xpc2gnLCBhcjogJ1x1MDYyN1x1MDY0NFx1MDYzOVx1MDYzMVx1MDYyOFx1MDY0QVx1MDYyOScsIGJuOiAnXHUwOUFDXHUwOUJFXHUwOTgyXHUwOUIyXHUwOUJFJywgY3M6ICdcdTAxMENlXHUwMTYxdGluYScsIGRhOiAnRGFuc2snLFxuICAgIGRlOiAnRGV1dHNjaCcsIGVsOiAnXHUwMzk1XHUwM0JCXHUwM0JCXHUwM0I3XHUwM0JEXHUwM0I5XHUwM0JBXHUwM0FDJywgZXM6ICdFc3BhXHUwMEYxb2wnLCBmYTogJ1x1MDY0MVx1MDYyN1x1MDYzMVx1MDYzM1x1MDZDQycsIGZpOiAnU3VvbWknLFxuICAgIGZyOiAnRnJhblx1MDBFN2FpcycsIGhpOiAnXHUwOTM5XHUwOTNGXHUwOTI4XHUwOTREXHUwOTI2XHUwOTQwJywgaHU6ICdNYWd5YXInLCBpZDogJ0JhaGFzYSBJbmRvbmVzaWEnLCBpdDogJ0l0YWxpYW5vJyxcbiAgICBqYTogJ1x1NjVFNVx1NjcyQ1x1OEE5RScsIGtvOiAnXHVENTVDXHVBRDZEXHVDNUI0JywgbXM6ICdCYWhhc2EgTWVsYXl1Jywgbmw6ICdOZWRlcmxhbmRzJywgbm86ICdOb3JzaycsXG4gICAgcGw6ICdQb2xza2knLCBwdDogJ1BvcnR1Z3VcdTAwRUFzJywgcm86ICdSb21cdTAwRTJuXHUwMTAzJywgcnU6ICdcdTA0MjBcdTA0NDNcdTA0NDFcdTA0NDFcdTA0M0FcdTA0MzhcdTA0MzknLCBzdjogJ1N2ZW5za2EnLFxuICAgIHRoOiAnXHUwRTQ0XHUwRTE3XHUwRTIyJywgdHI6ICdUXHUwMEZDcmtcdTAwRTdlJywgdWs6ICdcdTA0MjNcdTA0M0FcdTA0NDBcdTA0MzBcdTA0NTdcdTA0M0RcdTA0NDFcdTA0NENcdTA0M0FcdTA0MzAnLCB1cjogJ1x1MDYyN1x1MDYzMVx1MDYyRlx1MDY0OCcsIHZpOiAnVGlcdTFFQkZuZyBWaVx1MUVDN3QnLCB6aDogJ1x1NEUyRFx1NjU4NycsXG4gIH07XG4gIC8vIFJUTCBsYW5ndWFnZXMgbmVlZCBkaXI9XCJydGxcIiBvbiB0aGUgZG9jdW1lbnQgZWxlbWVudC4gKE5vIEhlYnJldyBwZXIgcHJvamVjdCBwb2xpY3kuKVxuICBjb25zdCBSVExfTEFOR1MgPSBuZXcgU2V0KFsnYXInLCAnZmEnLCAndXInXSk7XG5cbiAgLy8gVmFsaWRhdGUgdGhlIHN0b3JlZCBsYW5ndWFnZSBcdTIwMTQgaWYgaXQncyBpbnZhbGlkIChvbGQvY29ycnVwdCksIGZhbGwgYmFjayB0byBkZWZhdWx0LlxuICAvLyBXcmFwIGluIHRyeS9jYXRjaCBmb3IgZW52aXJvbm1lbnRzIHdoZXJlIGxvY2FsU3RvcmFnZSBpcyBkaXNhYmxlZCAocHJpdmF0ZSBtb2RlKS5cbiAgZnVuY3Rpb24gX3JlYWRWYWxpZExhbmcoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHN0b3JlZCA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKFNUT1JBR0VfS0VZKTtcbiAgICAgIGlmIChzdG9yZWQgJiYgU1VQUE9SVEVEX0xBTkdTLmluY2x1ZGVzKHN0b3JlZCkpIHJldHVybiBzdG9yZWQ7XG4gICAgfSBjYXRjaCAoZSkgeyAvKiBsb2NhbFN0b3JhZ2UgdW5hdmFpbGFibGUgKi8gfVxuICAgIHJldHVybiBERUZBVUxUX0xBTkc7XG4gIH1cblxuICBsZXQgY3VycmVudExhbmcgPSBfcmVhZFZhbGlkTGFuZygpO1xuICBsZXQgdHJhbnNsYXRpb25zID0ge307XG4gIGxldCBsb2FkZWQgPSBmYWxzZTtcbiAgLy8gTW9ub3RvbmljIHRva2VuIHRvIGd1YXJkIGFnYWluc3Qgb3V0LW9mLW9yZGVyIGFzeW5jIHJlc29sdXRpb24uXG4gIC8vIEVhY2ggc2V0TGFuZ3VhZ2UgLyBsb2FkVHJhbnNsYXRpb25zIGNhbGwgY2FwdHVyZXMgdGhlIGN1cnJlbnQgdmFsdWU7IGlmIGl0XG4gIC8vIGNoYW5nZWQgYnkgdGhlIHRpbWUgdGhlIGZldGNoIHJlc29sdmVzLCB0aGUgcmVzdWx0IGlzIGRpc2NhcmRlZC5cbiAgbGV0IF9sYW5nUmVxdWVzdElkID0gMDtcblxuICBhc3luYyBmdW5jdGlvbiBsb2FkVHJhbnNsYXRpb25zKGxhbmcsIHJlcUlkKSB7XG4gICAgLy8gcmVxSWQgaXMgdGhlIG1vbm90b25pYyB0b2tlbiBpbmNyZW1lbnRlZCBieSB0aGUgY2FsbGVyIChzZXRMYW5ndWFnZS9pbml0KS5cbiAgICAvLyBJZiBub3QgcHJvdmlkZWQgKGRpcmVjdCBBUEkgY2FsbCksIGFsbG9jYXRlIG9uZSBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eS5cbiAgICBpZiAocmVxSWQgPT09IHVuZGVmaW5lZCkgcmVxSWQgPSArK19sYW5nUmVxdWVzdElkO1xuICAgIGlmIChsYW5nID09PSBERUZBVUxUX0xBTkcpIHtcbiAgICAgIHRyYW5zbGF0aW9ucyA9IHt9OyAvLyBFbmdsaXNoIGlzIHRoZSBkZWZhdWx0IFx1MjAxNCBubyB0cmFuc2xhdGlvbiBuZWVkZWRcbiAgICAgIGxvYWRlZCA9IHRydWU7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaChgL2FwaS92MS9pMThuL3RyYW5zbGF0aW9ucy8ke2xhbmd9YCk7XG4gICAgICAvLyBHdWFyZCBhZ2FpbnN0IG91dC1vZi1vcmRlciByZXNvbHV0aW9uOiBpZiBhbm90aGVyIGxvYWRUcmFuc2xhdGlvbnNcbiAgICAgIC8vIHN0YXJ0ZWQgYWZ0ZXIgdGhpcyBvbmUgKG9yIHRoZSB1c2VyIHN3aXRjaGVkIGxhbmd1YWdlcyksIGRpc2NhcmQuXG4gICAgICBpZiAocmVxSWQgIT09IF9sYW5nUmVxdWVzdElkKSByZXR1cm47XG4gICAgICBpZiAocmVzLm9rKSB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXMuanNvbigpO1xuICAgICAgICBpZiAocmVxSWQgIT09IF9sYW5nUmVxdWVzdElkKSByZXR1cm47IC8vIGRvdWJsZS1jaGVjayBhZnRlciBzZWNvbmQgYXdhaXRcbiAgICAgICAgdHJhbnNsYXRpb25zID0gZGF0YS50cmFuc2xhdGlvbnMgfHwge307XG4gICAgICAgIGxvYWRlZCA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBIVFRQIGVycm9yIFx1MjAxNCBjbGVhciBzdGFsZSB0cmFuc2xhdGlvbnMgc28gd2UgZG9uJ3Qgc2hvdyB0aGUgd3JvbmcgbGFuZ3VhZ2VcbiAgICAgICAgdHJhbnNsYXRpb25zID0ge307XG4gICAgICAgIGxvYWRlZCA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUud2FybignW2kxOG5dIEZhaWxlZCB0byBsb2FkIHRyYW5zbGF0aW9ucyBmb3InLCBsYW5nLCBlKTtcbiAgICAgIGlmIChyZXFJZCA9PT0gX2xhbmdSZXF1ZXN0SWQpIHtcbiAgICAgICAgdHJhbnNsYXRpb25zID0ge307XG4gICAgICAgIGxvYWRlZCA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHQoa2V5KSB7XG4gICAgaWYgKGN1cnJlbnRMYW5nID09PSBERUZBVUxUX0xBTkcpIHJldHVybiBrZXk7XG4gICAgLy8gSWYgdHJhbnNsYXRpb25zIGRpZG4ndCBsb2FkLCBmYWxsIGJhY2sgdG8gdGhlIEVuZ2xpc2gga2V5XG4gICAgcmV0dXJuIHRyYW5zbGF0aW9uc1trZXldIHx8IGtleTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNldExhbmd1YWdlKGxhbmcpIHtcbiAgICBpZiAoIVNVUFBPUlRFRF9MQU5HUy5pbmNsdWRlcyhsYW5nKSkgcmV0dXJuO1xuICAgIGN1cnJlbnRMYW5nID0gbGFuZztcbiAgICB0cnkgeyBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShTVE9SQUdFX0tFWSwgbGFuZyk7IH0gY2F0Y2ggKGUpIHsgLyogbG9jYWxTdG9yYWdlIHVuYXZhaWxhYmxlICovIH1cblxuICAgIC8vIFJUTCBoYW5kbGluZyBcdTIwMTQgYWx3YXlzIHNldCBkaXIvbGFuZyBleHBsaWNpdGx5IHNvIHN3aXRjaGluZyBiYWNrIHRvIExUUiB3b3Jrcy5cbiAgICBjb25zdCBpc1J0bCA9IFJUTF9MQU5HUy5oYXMobGFuZyk7XG4gICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmRpciA9IGlzUnRsID8gJ3J0bCcgOiAnbHRyJztcbiAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQubGFuZyA9IGxhbmc7XG5cbiAgICBjb25zdCByZXFJZCA9ICsrX2xhbmdSZXF1ZXN0SWQ7IC8vIGluY3JlbWVudCBCRUZPUkUgY2FsbGluZyBsb2FkVHJhbnNsYXRpb25zXG4gICAgbG9hZFRyYW5zbGF0aW9ucyhsYW5nLCByZXFJZCkudGhlbigoKSA9PiB7XG4gICAgICAvLyBPbmx5IGFwcGx5IGlmIHRoaXMgaXMgc3RpbGwgdGhlIGxhdGVzdCByZXF1ZXN0LlxuICAgICAgaWYgKHJlcUlkID09PSBfbGFuZ1JlcXVlc3RJZCkgYXBwbHlUcmFuc2xhdGlvbnMoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldExhbmd1YWdlKCkge1xuICAgIHJldHVybiBjdXJyZW50TGFuZztcbiAgfVxuXG4gIGZ1bmN0aW9uIGFwcGx5VHJhbnNsYXRpb25zKCkge1xuICAgIC8vIEFwcGx5IHRyYW5zbGF0aW9ucyB0byBlbGVtZW50cyB3aXRoIGRhdGEtaTE4biBhdHRyaWJ1dGVzLlxuICAgIC8vIEFsd2F5cyB3cml0ZSB0aGUgcmVzb2x2ZWQgdmFsdWUgXHUyMDE0IHdoZW4gc3dpdGNoaW5nIGJhY2sgdG8gRW5nbGlzaCBvciB3aGVuIGFcbiAgICAvLyBrZXkgaGFzIG5vIHRyYW5zbGF0aW9uLCB0aGlzIHJlc3RvcmVzIHRoZSBvcmlnaW5hbCBFbmdsaXNoIHRleHQgcmF0aGVyIHRoYW5cbiAgICAvLyBsZWF2aW5nIHRoZSBwcmV2aW91cyBsYW5ndWFnZSdzIHRyYW5zbGF0ZWQgdGV4dCB2aXNpYmxlLlxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ1tkYXRhLWkxOG5dJykuZm9yRWFjaChlbCA9PiB7XG4gICAgICBjb25zdCBrZXkgPSBlbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaTE4bicpO1xuICAgICAgZWwudGV4dENvbnRlbnQgPSB0KGtleSk7XG4gICAgfSk7XG4gICAgLy8gQXBwbHkgdG8gcGxhY2Vob2xkZXJzXG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnW2RhdGEtaTE4bi1wbGFjZWhvbGRlcl0nKS5mb3JFYWNoKGVsID0+IHtcbiAgICAgIGNvbnN0IGtleSA9IGVsLmdldEF0dHJpYnV0ZSgnZGF0YS1pMThuLXBsYWNlaG9sZGVyJyk7XG4gICAgICBlbC5wbGFjZWhvbGRlciA9IHQoa2V5KTtcbiAgICB9KTtcbiAgICAvLyBBcHBseSB0byB0aXRsZXNcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdbZGF0YS1pMThuLXRpdGxlXScpLmZvckVhY2goZWwgPT4ge1xuICAgICAgY29uc3Qga2V5ID0gZWwuZ2V0QXR0cmlidXRlKCdkYXRhLWkxOG4tdGl0bGUnKTtcbiAgICAgIGVsLnRpdGxlID0gdChrZXkpO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlTGFuZ3VhZ2VTZWxlY3RvcigpIHtcbiAgICAvLyBGaW5kIHRoZSB0b3AgYmFyIGFyZWEgdG8gaW5zZXJ0IHRoZSBzZWxlY3RvclxuICAgIC8vIExvb2sgZm9yIHRoZSBhdXRoLXNldHRpbmdzIGFyZWEgb3IgdGhlIGhlYWRlciBhY3Rpb25zXG4gICAgY29uc3QgdGFyZ2V0Q29udGFpbmVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmhlYWRlci1hY3Rpb25zJykgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYXV0aC1zZXR0aW5ncy1idG4nKT8ucGFyZW50RWxlbWVudCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy50b3AtYmFyLWFjdGlvbnMnKTtcblxuICAgIGlmICghdGFyZ2V0Q29udGFpbmVyKSB7XG4gICAgICAvLyBJZiB3ZSBjYW4ndCBmaW5kIGEgdGFyZ2V0LCB0cnkgdG8gYWRkIGl0IG5lYXIgdGhlIHNldHRpbmdzIGJ1dHRvblxuICAgICAgY29uc3Qgc2V0dGluZ3NCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXV0aC1zZXR0aW5ncy1idG4nKTtcbiAgICAgIGlmIChzZXR0aW5nc0J0biAmJiBzZXR0aW5nc0J0bi5wYXJlbnRFbGVtZW50KSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVEcm9wZG93bihzZXR0aW5nc0J0bi5wYXJlbnRFbGVtZW50KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBjcmVhdGVEcm9wZG93bih0YXJnZXRDb250YWluZXIpO1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlRHJvcGRvd24oY29udGFpbmVyKSB7XG4gICAgLy8gQ2hlY2sgaWYgc2VsZWN0b3IgYWxyZWFkeSBleGlzdHNcbiAgICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RjLWxhbmctc2VsZWN0b3InKSkgcmV0dXJuO1xuXG4gICAgY29uc3Qgd3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHdyYXBwZXIuaWQgPSAnZGMtbGFuZy1zZWxlY3Rvcic7XG4gICAgd3JhcHBlci5zdHlsZS5jc3NUZXh0ID0gJ2Rpc3BsYXk6IGlubGluZS1mbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDRweDsgbWFyZ2luOiAwIDhweDsgcG9zaXRpb246IHJlbGF0aXZlOyc7XG5cbiAgICBjb25zdCBidG4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdidXR0b24nKTtcbiAgICBidG4uaWQgPSAnZGMtbGFuZy1idG4nO1xuICAgIGJ0bi5jbGFzc05hbWUgPSAnbGFuZy1zZWxlY3Rvci1idG4nO1xuICAgIGJ0bi5zdHlsZS5jc3NUZXh0ID0gJ2JhY2tncm91bmQ6IHZhcigtLWNhcmQtYmFzZSwgIzJhMmEzZSk7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlciwgIzNhM2E0ZSk7IGNvbG9yOiB2YXIoLS10ZXh0LXByaW1hcnksICNlMGUwZTApOyBwYWRkaW5nOiA2cHggMTBweDsgYm9yZGVyLXJhZGl1czogNnB4OyBjdXJzb3I6IHBvaW50ZXI7IGZvbnQtc2l6ZTogMC44cmVtOyBkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDRweDsnO1xuICAgIGJ0bi5pbm5lckhUTUwgPSBgXHVEODNDXHVERjEwIDxzcGFuIGNsYXNzPVwibGFuZy1jdXJyZW50XCI+JHtjdXJyZW50TGFuZy50b1VwcGVyQ2FzZSgpfTwvc3Bhbj5gO1xuICAgIGJ0bi50aXRsZSA9ICdTZWxlY3QgTGFuZ3VhZ2UnO1xuXG4gICAgY29uc3QgZHJvcGRvd24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBkcm9wZG93bi5pZCA9ICdkYy1sYW5nLWRyb3Bkb3duJztcbiAgICBkcm9wZG93bi5zdHlsZS5jc3NUZXh0ID0gJ2Rpc3BsYXk6IG5vbmU7IHBvc2l0aW9uOiBhYnNvbHV0ZTsgdG9wOiAxMDAlOyByaWdodDogMDsgbWFyZ2luLXRvcDogNHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJhc2UsICMyYTJhM2UpOyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIsICMzYTNhNGUpOyBib3JkZXItcmFkaXVzOiA4cHg7IGJveC1zaGFkb3c6IDAgNHB4IDEycHggcmdiYSgwLDAsMCwwLjMpOyB6LWluZGV4OiA5OTk5OyBtaW4td2lkdGg6IDE2MHB4OyBtYXgtaGVpZ2h0OiAzMjBweDsgb3ZlcmZsb3cteTogYXV0bzsnO1xuXG4gICAgU1VQUE9SVEVEX0xBTkdTLmZvckVhY2gobGFuZyA9PiB7XG4gICAgICBjb25zdCBpdGVtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICBpdGVtLmNsYXNzTmFtZSA9ICdsYW5nLW9wdGlvbic7XG4gICAgICBpdGVtLnN0eWxlLmNzc1RleHQgPSAncGFkZGluZzogOHB4IDE0cHg7IGN1cnNvcjogcG9pbnRlcjsgZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA4cHg7IGZvbnQtc2l6ZTogMC44NXJlbTsgY29sb3I6IHZhcigtLXRleHQtcHJpbWFyeSwgI2UwZTBlMCk7JztcbiAgICAgIGl0ZW0ub25tb3VzZWVudGVyID0gKCkgPT4gaXRlbS5zdHlsZS5iYWNrZ3JvdW5kID0gJ3ZhcigtLWNhcmQtaG92ZXIsIHJnYmEoMjU1LDI1NSwyNTUsMC4wNSkpJztcbiAgICAgIGl0ZW0ub25tb3VzZWxlYXZlID0gKCkgPT4gaXRlbS5zdHlsZS5iYWNrZ3JvdW5kID0gJ3RyYW5zcGFyZW50JztcblxuICAgICAgY29uc3QgZmxhZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICAgIGZsYWcudGV4dENvbnRlbnQgPSBsYW5nID09PSBjdXJyZW50TGFuZyA/ICdcdTI3MTMnIDogJyc7XG4gICAgICBmbGFnLnN0eWxlLmNzc1RleHQgPSAnd2lkdGg6IDE2cHg7IGNvbG9yOiB2YXIoLS1vay1mZywgIzRhZGU4MCk7JztcblxuICAgICAgY29uc3QgbmFtZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICAgIG5hbWUudGV4dENvbnRlbnQgPSBMQU5HX05BTUVTW2xhbmddO1xuXG4gICAgICBpdGVtLmFwcGVuZENoaWxkKGZsYWcpO1xuICAgICAgaXRlbS5hcHBlbmRDaGlsZChuYW1lKTtcbiAgICAgIGl0ZW0ub25jbGljayA9ICgpID0+IHtcbiAgICAgICAgc2V0TGFuZ3VhZ2UobGFuZyk7XG4gICAgICAgIGRyb3Bkb3duLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIC8vIFVwZGF0ZSBidXR0b24gdGV4dFxuICAgICAgICBidG4ucXVlcnlTZWxlY3RvcignLmxhbmctY3VycmVudCcpLnRleHRDb250ZW50ID0gbGFuZy50b1VwcGVyQ2FzZSgpO1xuICAgICAgICAvLyBVcGRhdGUgY2hlY2ttYXJrc1xuICAgICAgICBkcm9wZG93bi5xdWVyeVNlbGVjdG9yQWxsKCcubGFuZy1vcHRpb24nKS5mb3JFYWNoKChvcHQsIGkpID0+IHtcbiAgICAgICAgICBvcHQucXVlcnlTZWxlY3Rvcignc3BhbicpLnRleHRDb250ZW50ID0gU1VQUE9SVEVEX0xBTkdTW2ldID09PSBsYW5nID8gJ1x1MjcxMycgOiAnJztcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIFNob3cgbm90aWZpY2F0aW9uXG4gICAgICAgIGlmICh3aW5kb3cuc2hvd05vdGlmaWNhdGlvbikge1xuICAgICAgICAgIHdpbmRvdy5zaG93Tm90aWZpY2F0aW9uKGBMYW5ndWFnZTogJHtMQU5HX05BTUVTW2xhbmddfWAsICdpbmZvJyk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBkcm9wZG93bi5hcHBlbmRDaGlsZChpdGVtKTtcbiAgICB9KTtcblxuICAgIGJ0bi5vbmNsaWNrID0gKGUpID0+IHtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICBkcm9wZG93bi5zdHlsZS5kaXNwbGF5ID0gZHJvcGRvd24uc3R5bGUuZGlzcGxheSA9PT0gJ25vbmUnID8gJ2Jsb2NrJyA6ICdub25lJztcbiAgICB9O1xuXG4gICAgLy8gQ2xvc2Ugb24gb3V0c2lkZSBjbGlja1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGUpID0+IHtcbiAgICAgIGlmICghd3JhcHBlci5jb250YWlucyhlLnRhcmdldCkpIHtcbiAgICAgICAgZHJvcGRvd24uc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHdyYXBwZXIuYXBwZW5kQ2hpbGQoYnRuKTtcbiAgICB3cmFwcGVyLmFwcGVuZENoaWxkKGRyb3Bkb3duKTtcbiAgICBjb250YWluZXIuaW5zZXJ0QmVmb3JlKHdyYXBwZXIsIGNvbnRhaW5lci5maXJzdENoaWxkKTtcblxuICAgIHJldHVybiB3cmFwcGVyO1xuICB9XG5cbiAgLy8gSW5pdGlhbGl6ZSBvbiBwYWdlIGxvYWRcbiAgZnVuY3Rpb24gaW5pdCgpIHtcbiAgICAvLyBBbHdheXMgc2V0IGRpci9sYW5nIGV4cGxpY2l0bHkgXHUyMDE0IGNvdmVycyBMVFIgcmVzZXQgYW5kIFJUTCBzZXR1cC5cbiAgICBjb25zdCBpc1J0bCA9IFJUTF9MQU5HUy5oYXMoY3VycmVudExhbmcpO1xuICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5kaXIgPSBpc1J0bCA/ICdydGwnIDogJ2x0cic7XG4gICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmxhbmcgPSBjdXJyZW50TGFuZztcblxuICAgIGZ1bmN0aW9uIHN0YXJ0KCkge1xuICAgICAgY3JlYXRlTGFuZ3VhZ2VTZWxlY3RvcigpO1xuICAgICAgaWYgKGN1cnJlbnRMYW5nICE9PSBERUZBVUxUX0xBTkcpIHtcbiAgICAgICAgY29uc3QgcmVxSWQgPSArK19sYW5nUmVxdWVzdElkO1xuICAgICAgICBsb2FkVHJhbnNsYXRpb25zKGN1cnJlbnRMYW5nLCByZXFJZCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgaWYgKHJlcUlkID09PSBfbGFuZ1JlcXVlc3RJZCkgYXBwbHlUcmFuc2xhdGlvbnMoKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGRvY3VtZW50LnJlYWR5U3RhdGUgPT09ICdsb2FkaW5nJykge1xuICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignRE9NQ29udGVudExvYWRlZCcsIHN0YXJ0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhcnQoKTtcbiAgICB9XG4gIH1cblxuICAvLyBFeHBvc2UgZ2xvYmFsbHlcbiAgd2luZG93LkRDSTE4biA9IHsgdCwgc2V0TGFuZ3VhZ2UsIGdldExhbmd1YWdlLCBhcHBseVRyYW5zbGF0aW9ucywgbG9hZFRyYW5zbGF0aW9ucyB9O1xuXG4gIC8vIEF1dG8taW5pdFxuICBpbml0KCk7XG59KSgpO1xuIl0sCiAgIm1hcHBpbmdzIjogIkNBQ0MsVUFBVyxDQUVWLFlBQVksYUFBYztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFB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YU0sQ0FBSyxFQUFFLEtBQUssSUFBTSxDQUMxQ0EsSUFBVUgsR0FBZ0JNLEVBQWtCLENBQ2xELENBQUMsQ0FDSCxDQUNGLENBRUksU0FBUyxhQUFlLFVBQzFCLFNBQVMsaUJBQWlCLG1CQUFvQlUsQ0FBSyxFQUVuREEsRUFBTSxDQUVWLENBR0EsT0FBTyxPQUFTLENBQUUsRUFBQS84QixFQUFHLFlBQUFtOEIsRUFBYSxZQUFBRyxFQUFhLGtCQUFBRCxFQUFtQixpQkFBQUwsQ0FBaUIsRUFHbkZjLEVBQUssQ0FDUCxHQUFHIiwKICAibmFtZXMiOiBbImxvZ29Nb2RhbCIsICJwcmV2aWV3RGFyayIsICJwcmV2aWV3TGlnaHQiLCAibG9nb1N0YXR1cyIsICJzYW1lQm90aENoZWNrYm94IiwgImR1YWxVcGxvYWRzIiwgInNpbmdsZVVwbG9hZCIsICJ1cGxvYWREYXJrIiwgInVwbG9hZExpZ2h0IiwgInVwbG9hZFNpbmdsZSIsICJicmFuZExvZ29EYXJrIiwgImJyYW5kTG9nb0xpZ2h0IiwgInRvcFJvdyIsICJkYXNoYm9hcmRUaXRsZUlucHV0IiwgIkRFRkFVTFRfVElUTEUiLCAicGVuZGluZ0RhcmtEYXRhIiwgInBlbmRpbmdMaWdodERhdGEiLCAicGVuZGluZ1NpbmdsZURhdGEiLCAiY3VycmVudFBvc2l0aW9uIiwgImN1cnJlbnRUaXRsZSIsICJyZWFkRmlsZUFzRGF0YVVSTCIsICJmaWxlIiwgImNhbGxiYWNrIiwgInJlYWRlciIsICJlIiwgImRhdGEiLCAiYXBwbHlMb2dvUG9zaXRpb24iLCAicG9zIiwgImJ0biIsICJhcHBseURhc2hib2FyZFRpdGxlIiwgInRpdGxlIiwgImhlYWRlclRpdGxlIiwgImxvYWRDdXN0b21Mb2dvIiwgInJlc3BvbnNlIiwgImVycm9yIiwgImlzQ3VzdG9tIiwgIm5ld1RpdGxlIiwgInBheWxvYWQiLCAidCIsICJmYXZpY29uTGluayIsICJmYXZpY29uUHJldmlldyIsICJmYXZpY29uU3RhdHVzIiwgInBlbmRpbmdGYXZpY29uRGF0YSIsICJmYXZpY29uVXBsb2FkIiwgImxvYWRDdXN0b21GYXZpY29uIiwgImV2ZW50IiwgInNldHRpbmdzVHpTZWxlY3QiLCAiY3VycmVudFR6IiwgInJlcyIsICJ0eiIsICJjZmciLCAic2VsZWN0RWwiLCAic2VsZWN0ZWRUeiIsICJ0aW1lem9uZXMiLCAiZGV0ZWN0ZWQiLCAib3B0IiwgImN1cnJlbnRDb25maWdUeXBlIiwgInNlcnZlckNvbmZpZyIsICJjaGVja1NlcnZlckNvbmZpZyIsICJzZXR1cFR6U2VsZWN0IiwgInNob3dTdGVwIiwgInN0ZXBJZCIsICJzdGVwIiwgInRhcmdldFN0ZXAiLCAic2hvd1N1bW1hcnkiLCAic3VtbWFyeUNvbnRlbnQiLCAiaHRtbCIsICJ0bGQiLCAiY2FOYW1lIiwgImRuc0lQIiwgImRuc1BvcnQiLCAiaXAiLCAiZG9tYWluIiwgImVtYWlsIiwgInJvdXRpbmdNb2RlIiwgImV4YW1wbGVVcmxzIiwgInNhdmVDb25maWdUb1NlcnZlciIsICJjb25maWciLCAiZmluaXNoU2V0dXAiLCAic2VsZWN0ZWRQcm92aWRlciIsICJzYXZlZFRvU2VydmVyIiwgImNvbmZpZ05hbWUiLCAic2F2ZUxvY2F0aW9uIiwgInN0ZXAxTmV4dCIsICJzZWxlY3RlZCIsICJza2lwQnRuIiwgInRsZElucHV0IiwgInByZXZpZXcxIiwgInByZXZpZXcyIiwgImhvbWVsYWJCYWNrIiwgImhvbWVsYWJOZXh0IiwgInNpbXBsZUJhY2siLCAic2ltcGxlTmV4dCIsICJyYWRpbyIsICJub3RlIiwgInB1YmxpY0JhY2siLCAicHVibGljTmV4dCIsICJzdW1tYXJ5QmFjayIsICJzdW1tYXJ5TmV4dCIsICJkaXNrU2FmZXR5QmFjayIsICJmaW5pc2hCdG4iLCAiY29uZmlnU3RyIiwgImVycm9ySGFuZGxlciIsICJBUFBTX0tFWSIsICJhcGlUZW1wbGF0ZXMiLCAiYXBpQ2F0ZWdvcmllcyIsICJtb2RhbCIsICJncmlkIiwgImZldGNoQXBwVGVtcGxhdGVzIiwgImNoZWNrUG9ydEF2YWlsYWJpbGl0eSIsICJwb3J0IiwgImdldFN1Z2dlc3RlZFBvcnQiLCAiYmFzZVBvcnQiLCAiYnVpbGRBcHBTZWxlY3RvciIsICJieUNhdGVnb3J5IiwgImFwcElkIiwgInRlbXBsYXRlIiwgImNhdGVnb3J5IiwgImNhdGVnb3J5T3JkZXIiLCAiYXBwcyIsICJhIiwgImIiLCAiaGVhZGVyIiwgImNhdGVnb3J5SW5mbyIsICJhcHAiLCAib3B0aW9uIiwgImlzV2lkZ2V0IiwgIndpZGdldEVuYWJsZWQiLCAid2lkZ2V0QmFkZ2UiLCAiZGlmZmljdWx0eUJhZGdlIiwgInRvZ2dsZURhc2hib2FyZFdpZGdldCIsICJzaG93RGVwbG95Q29uZmlnIiwgIm9wdGlvbkVsIiwgImtleSIsICJuZXdTdGF0ZSIsICJzZWxlY3RvciIsICJlbCIsICJiYWRnZSIsICJhcHBUZW1wbGF0ZSIsICJkZXBsb3lNb2RhbCIsICJzdWJkb21haW5JbnB1dCIsICJ1cmxQcmV2aWV3IiwgImlwSW5wdXQiLCAicG9ydElucHV0IiwgInRhaWxzY2FsZUNoZWNrYm94IiwgInRhaWxzY2FsZVN0YXR1cyIsICJjaGVja1Jlc3VsdCIsICJjb250YWluZXIiLCAiZGVmYXVsdFN1YmRvbWFpbiIsICJzdWJwYXRoV2FybmluZyIsICJzdXBwb3J0IiwgImNmZ0Ruc1R5cGUiLCAiY2ZnU3NsVHlwZSIsICJkbnNSYWRpbyIsICJzc2xSYWRpbyIsICJkbnNTZWN0aW9uIiwgImFkdmFuY2VkRGV0YWlscyIsICJhZHZhbmNlZENvbnRlbnQiLCAiZG5zU2VjdGlvbkVsIiwgInNzbFNlY3Rpb25FbCIsICJtZWRpYVBhdGhTZWN0aW9uIiwgIm1lZGlhUGF0aElucHV0IiwgIm1lZGlhUGF0aERlc2NyaXB0aW9uIiwgImRldGVjdGVkTW91bnRzQ29udGFpbmVyIiwgImRldGVjdGVkTW91bnRzTGlzdCIsICJtb3VudHNSZXN1bHQiLCAiYXV0b1BhdGhzIiwgIm0iLCAibW91bnQiLCAiaXNTZWxlY3RlZCIsICJjdXJyZW50UGF0aHMiLCAicCIsICJpZHgiLCAicGxleENsYWltU2VjdGlvbiIsICJ2b2x1bWVTZWN0aW9uIiwgInZvbHVtZUxpc3QiLCAibWVkaWFDb250YWluZXJQYXRoIiwgIm5vbk1lZGlhVm9sdW1lcyIsICJ2IiwgInZvbCIsICJpIiwgImhvc3REZWZhdWx0IiwgImNvbnRhaW5lclBhdGgiLCAicm93IiwgImlucHV0IiwgImRlZmF1bHRQb3J0IiwgInBvcnRTdGF0dXMiLCAiY2hlY2tBbmRVcGRhdGVQb3J0U3RhdHVzIiwgInBvcnRUb0NoZWNrIiwgInJlc3VsdCIsICJzdWdnZXN0ZWRQb3J0IiwgInVzZUJ0biIsICJwb3J0Q2hlY2tUaW1lb3V0IiwgInVwZGF0ZVVybFByZXZpZXciLCAic3ViZG9tYWluIiwgImRuc1R5cGUiLCAic3NsVHlwZSIsICJ1cmwiLCAicHJvdG9jb2wiLCAiYWRkQXBwVG9HcmlkIiwgImRlcGxveUNvbmZpZyIsICJjdXN0b21BcHBzIiwgInVzaW5nRXhpc3RpbmciLCAiZXhpc3RpbmdBcHAiLCAiaW5kZXgiLCAicG9ydFRvVXNlIiwgInBvcnRDaGVjayIsICJhcGlEZXBsb3lDb25maWciLCAibmV3QXBwIiwgIm1lc3NhZ2UiLCAiY2hlY2tTU0xDZXJ0aWZpY2F0ZSIsICJpbnN0cnVjdGlvbnMiLCAiYXBwTmFtZSIsICJhdHRlbXB0cyIsICJtYXhBdHRlbXB0cyIsICJjaGVja0NlcnQiLCAibG9hZEN1c3RvbUFwcHMiLCAibWVkaWFQYXRoIiwgImN1c3RvbVZvbHVtZXMiLCAiZm9sZGVyQnJvd3Nlck1vZGFsIiwgImZvbGRlckJyb3dzZXJQYXRoIiwgImZvbGRlckJyb3dzZXJMaXN0IiwgImZvbGRlckJyb3dzZXJTZWxlY3RlZCIsICJmb2xkZXJCcm93c2VyU2VsZWN0ZWRMaXN0IiwgImN1cnJlbnRCcm93c2VyUGF0aCIsICJzZWxlY3RlZEZvbGRlcnMiLCAidGFyZ2V0TWVkaWFJbnB1dCIsICJtZWRpYUlucHV0IiwgInVwZGF0ZVNlbGVjdGVkRm9sZGVyc0Rpc3BsYXkiLCAibG9hZEZvbGRlckNvbnRlbnRzIiwgInBhdGgiLCAiaXRlbSIsICJpY29uIiwgInNlbGVjdGVkU3R5bGUiLCAicmVjaXBlVGVtcGxhdGVzIiwgInJlY2lwZUNhdGVnb3JpZXMiLCAiY3VycmVudFJlY2lwZSIsICJjdXJyZW50U3RlcCIsICJpc1ByZW1pdW0iLCAiY2FuY2VsQnRuIiwgInByZXZCdG4iLCAibmV4dEJ0biIsICJmZXRjaFJlY2lwZVRlbXBsYXRlcyIsICJyZXNwIiwgImNoZWNrUmVjaXBlUHJlbWl1bSIsICJyZWNpcGVzIiwgImdldFByZXZpZXdSZWNpcGVzIiwgInJlY2lwZUxpc3QiLCAicmVjaXBlIiwgImNvbXBvbmVudEJhZGdlIiwgImxvY2tPdmVybGF5IiwgIm9wZW5SZWNpcGVEZXBsb3lXaXphcmQiLCAiYXBwU2VsZWN0b3JNb2RhbCIsICJ1cGRhdGVTdGVwVUkiLCAicmVuZGVyU3RlcDEiLCAicGFuZWwiLCAibGlzdCIsICJjb21wb25lbnRzIiwgImNvbXAiLCAiaXNSZXF1aXJlZCIsICJpc0ludGVybmFsIiwgInJlbmRlclN0ZXAyIiwgInNoYXJlZFZvbHVtZXMiLCAicmVuZGVyU3RlcDMiLCAiY29udGVudCIsICJzZWxlY3RlZENvbXBvbmVudHMiLCAiZ2V0U2VsZWN0ZWRDb21wb25lbnRzIiwgInZvbHVtZUlucHV0cyIsICJ2b2x1bWVzIiwgInRhaWxzY2FsZSIsICJjIiwgImsiLCAiY2hlY2tib3hlcyIsICJzZWxlY3RlZElkcyIsICJjYiIsICJleGVjdXRlRGVwbG95IiwgInByb2dyZXNzTGlzdCIsICJyZXN1bHRFbCIsICJ1cGRhdGVQcm9ncmVzc0l0ZW0iLCAiZGVwbG95ZWQiLCAiZXJyIiwgInMiLCAiY29tcG9uZW50SWQiLCAic3RhdHVzIiwgInRleHQiLCAic3RhdHVzRWwiLCAiY2FyZHMiLCAiZ3JvdXBzIiwgImNhcmQiLCAicmVjaXBlSWQiLCAiZ3JvdXBDYXJkcyIsICJsYWJlbCIsICJhY3Rpb24iLCAiZW5kcG9pbnQiLCAibWV0aG9kIiwgInIiLCAic3R5bGUiLCAiYnV0dG9uIiwgIm9yaWdpbmFsVGV4dCIsICJ2aWV3QnRuIiwgInJlZnJlc2hCdG4iLCAiY2xlYXJCdG4iLCAiY2xvc2VCdG4iLCAibG9hZEVycm9yTG9ncyIsICJsb2ciLCAiY2xlYXJFcnJvckxvZ3MiLCAiY29udGFpbmVyU2VsZWN0IiwgImxvZ0NvbnRlbnQiLCAibG9nU2VhcmNoIiwgImxvZ1RhaWwiLCAic3RyZWFtQnRuIiwgImRvd25sb2FkQnRuIiwgImNsZWFyU2VhcmNoQnRuIiwgImNsb3NlQnRuMiIsICJzdHJlYW1TdGF0dXMiLCAic3RyZWFtSW5kaWNhdG9yIiwgInN0cmVhbVRleHQiLCAibGluZUNvdW50IiwgImZpbHRlckNvdW50IiwgImltYWdlRWwiLCAiY3JlYXRlZEVsIiwgImN1cnJlbnRDb250YWluZXJJZCIsICJjdXJyZW50TG9ncyIsICJmaWx0ZXJlZExvZ3MiLCAiZXZlbnRTb3VyY2UiLCAiaXNTdHJlYW1pbmciLCAic2VhcmNoVGltZW91dCIsICJmb3JtYXREYXRlIiwgImRhdGVTdHIiLCAiZCIsICJlc2NhcGVIdG1sIiwgInN0ciIsICJkaXYiLCAiZm9ybWF0TG9nRW50cnkiLCAic3RyZWFtQ2xhc3MiLCAic3RyZWFtSWNvbiIsICJyZW5kZXJMb2dzIiwgImxvZ3MiLCAic2VhcmNoVGVybSIsICJsb2FkQ29udGFpbmVycyIsICJjb250YWluZXJzIiwgImN1cnJlbnRWYWwiLCAibG9hZENvbnRhaW5lckluZm8iLCAiY29udGFpbmVySWQiLCAibG9hZExvZ3MiLCAic3RvcFN0cmVhbSIsICJ0YWlsIiwgInN0YXJ0U3RyZWFtIiwgImVudHJ5IiwgImVudHJ5RGl2IiwgImRvd25sb2FkTG9ncyIsICJjb250YWluZXJOYW1lIiwgInRpbWVzdGFtcCIsICJmaWxlbmFtZSIsICJzdHJlYW0iLCAiYmxvYiIsICJjbG9zZU1vZGFsIiwgIm9wZW5CdG4iLCAiZGV0YWlsc0RpdiIsICJjcmVhdGVCdG4iLCAiY3JlYXRlU3RhdHVzIiwgInNob3dDb250YWluZXJEZXRhaWxzIiwgImNyZWF0ZVNuYXBzaG90IiwgIm5hbWUiLCAibGVhdmVSdW5uaW5nIiwgIm9wZW5Nb2RhbCIsICJ0YWIiLCAiY29ubmVjdEJ0biIsICJwaGFzZURldGVjdCIsICJwaGFzZUNyZWRlbnRpYWxzIiwgInBoYXNlUHJvZ3Jlc3MiLCAicGhhc2VSZXN1bHRzIiwgImRldGVjdFJlc3VsdHMiLCAiY3JlZGVudGlhbElucHV0cyIsICJwcm9ncmVzc1N0ZXBzIiwgInJlc3VsdHNDb250ZW50IiwgInBsZXhMaWJyYXJpZXMiLCAicmV0cnlCdG4iLCAiZGV0ZWN0ZWREYXRhIiwgInNlcnZpY2VJY29ucyIsICJzZXJ2aWNlTGFiZWxzIiwgInNob3dQaGFzZSIsICJwaGFzZSIsICJzdGF0dXNCYWRnZSIsICJjb2xvcnMiLCAic21hcnREZXRlY3QiLCAic3ZjIiwgImluZm8iLCAic291cmNlIiwgInZlcnNpb24iLCAia2V5U2F2ZWQiLCAiYnVpbGRDcmVkZW50aWFsSW5wdXRzIiwgInNlcnZpY2VzIiwgImFyclNlcnZpY2VzIiwgImlzQ29ubmVjdGVkIiwgInBsZXgiLCAicGxleENvbm5lY3RlZCIsICJzZWVyciIsICJzZWVyck9rIiwgImNvbmZpZ3VyZWRIdG1sIiwgImNzIiwgInNlcnZpY2UiLCAidXJsSW5wdXQiLCAia2V5SW5wdXQiLCAic3RhdHVzU3BhbiIsICJhcGlLZXkiLCAic21hcnRDb25uZWN0IiwgInN0ZXBzSHRtbCIsICJkZXRhaWxDb2xvciIsICJzaG93UmVzdWx0cyIsICJhbGxHb29kIiwgImhlYWRlckNvbG9yIiwgImhlYWRlckljb24iLCAiaGVhZGVyVGV4dCIsICJzdCIsICJmZXRjaFBsZXhMaWJyYXJpZXMiLCAibGliIiwgInR5cGVJY29uIiwgInNhdmVCdG4iLCAicHJvdmlkZXIiLCAiY2hlY2tib3giLCAiaGVhbHRoQ2hlY2tFbmFibGVkIiwgImhlYWx0aENoZWNrQ29uZmlnIiwgImxvYWROb3RpZmljYXRpb25Db25maWciLCAibG9hZE5vdGlmaWNhdGlvbkhpc3RvcnkiLCAiZGF0ZSIsICJzYXZlTm90aWZpY2F0aW9uQ29uZmlnIiwgInRlc3RQcm92aWRlciIsICJsb2FkTm90aWZpY2F0aW9uU3RhdHVzIiwgImxhc3RTZW50RWwiLCAicGFuZWxJZCIsICJ0YWJCYXIiLCAibW9kYWxDb250ZW50IiwgInRhcmdldCIsICJCUk9XU0VSX1NUQVRFX0tFWVMiLCAiY29sbGVjdEJyb3dzZXJTdGF0ZSIsICJzdGF0ZSIsICJ2YWwiLCAiaiIsICJyZXN0b3JlQnJvd3NlclN0YXRlIiwgImJyb3dzZXJTdGF0ZSIsICJjb3VudCIsICJpc0xlZ2FjeUZvcm1hdCIsICJyZXN0b3JlTGVnYWN5Rm9ybWF0IiwgInNsdWciLCAiZXhwb3J0QnRuIiwgInNlbGVjdEZpbGVCdG4iLCAiZmlsZUlucHV0IiwgImZpbGVOYW1lRGl2IiwgInByZXZpZXdEaXYiLCAicHJldmlld0NvbnRlbnQiLCAicmVzdG9yZUJ0biIsICJyZXN1bHREaXYiLCAic2NoZWR1bGVDb250YWluZXIiLCAiaGlzdG9yeUNvbnRhaW5lciIsICJkaXNrQ29udGFpbmVyIiwgInBvaW50aW50aW1lQ29udGFpbmVyIiwgInNlbGVjdGVkQmFja3VwIiwgInN0YXRlQ291bnQiLCAidGhlbWVDb3VudCIsICJiYWNrdXAiLCAicHJldmlldyIsICJyZWxvYWRDYWRkeSIsICJicm93c2VyQ291bnQiLCAibXNnIiwgImxvYWRTY2hlZHVsZXNUYWIiLCAic2NoZWR1bGVzIiwgInNjaCIsICJuZXh0UnVuU3RyIiwgImxhc3RSdW5TdHIiLCAidG9nZ2xlIiwgInVwZGF0ZVNjaGVkdWxlIiwgInNlbCIsICJpbnAiLCAicnVuQmFja3VwTm93IiwgImRlbGV0ZVNjaGVkdWxlIiwgImFkZE5ld1NjaGVkdWxlIiwgInVwZGF0ZXMiLCAiaW50ZXJ2YWwiLCAicmV0ZW50aW9uIiwgImFwcElkSW5wdXQiLCAibG9hZERpc2tCYWNrdXBzIiwgImZpbGVzIiwgImJ5QXBwIiwgImYiLCAiYXBwSWRzIiwgImFwcEZpbGVzIiwgImNvbXBhcmVCYWNrdXBGaWxlIiwgInJlc3RvcmVCYWNrdXBGaWxlIiwgImxvYWRCYWNrdXBIaXN0b3J5IiwgImJrIiwgInNpemVNQiIsICJiYWNrdXBJZCIsICJsb2FkUG9pbnRJblRpbWVUYWIiLCAibGljZW5zZVJlcyIsICJsaWNlbnNlRGF0YSIsICJzZXJ2aWNlc1JlcyIsICJzZXJ2aWNlc0RhdGEiLCAibG9hZFBvaW50SW5UaW1lQmFja3VwcyIsICJsaXN0RWwiLCAiZGlmZiIsICJzdmNDaGFuZ2VkIiwgImNmZ0NoYW5nZWQiLCAiYXV0b1JlZnJlc2hDaGVja2JveCIsICJhZ2dyZWdhdGVkQ29udGFpbmVyIiwgImFsZXJ0c0NvbnRhaW5lciIsICJsYXN0VXBkYXRlU3BhbiIsICJyZWZyZXNoSW50ZXJ2YWwiLCAiY2FjaGVkTW9uaXRvcmluZ0RhdGEiLCAiZm9ybWF0Qnl0ZXMiLCAiYnl0ZXMiLCAic2l6ZXMiLCAiZ2V0Q3B1Q29sb3IiLCAicGVyY2VudCIsICJnZXRNZW1Db2xvciIsICJsb2FkU3RhdHMiLCAic3RhdHMiLCAiaXNOZXdBcGkiLCAiaWQiLCAiY3VyIiwgImNwdSIsICJtZW0iLCAiY3B1Q29sb3IiLCAibWVtQ29sb3IiLCAibWVtVXNlZCIsICJtZW1MaW1pdCIsICJuZXRSeCIsICJuZXRUeCIsICJhZ2ciLCAibG9hZEFnZ3JlZ2F0ZWQiLCAibG9hZEFsZXJ0cyIsICJhbGVydEhpc3RvcnkiLCAiaGQiLCAiYWxsQ29uZmlncyIsICJjZCIsICJjb250YWluZXJSb3dzIiwgImhpc3RvcnlSb3dzIiwgInRpbWUiLCAibm90aWZpZWRNYXJrIiwgImNvbmZpZ1NlY3Rpb24iLCAiY29uZmlncyIsICJjSWQiLCAic3RvcEF1dG9SZWZyZXNoIiwgIm9yaWciLCAic3RhcnRBdXRvUmVmcmVzaCIsICJoaXN0b3J5Q29udGFpbmVyU2VsZWN0IiwgImhpc3RvcnlBcmVhIiwgInJhbmdlQnV0dG9ucyIsICJjdXJyZW50UmFuZ2UiLCAicmFuZ2VUb01zIiwgInJhbmdlIiwgInRpZXJMYWJlbCIsICJ0aWVyIiwgInJlbmRlclNwYXJrbGluZSIsICJzYW1wbGVzIiwgImFjY2Vzc29yIiwgImNvbG9yIiwgInVuaXQiLCAidmFsdWVzIiwgIm1heCIsICJtaW4iLCAidyIsICJoIiwgInBhZCIsICJzdGVwWCIsICJwb2ludHMiLCAieCIsICJ5IiwgImxhc3QiLCAiYXZnIiwgInBvcHVsYXRlSGlzdG9yeUNvbnRhaW5lclNlbGVjdCIsICJwcmV2aW91cyIsICJlbnRyaWVzIiwgImxvYWRIaXN0b3J5IiwgImVuZFRpbWUiLCAic3RhcnRUaW1lIiwgImlzUmF3IiwgImNwdUFjY2Vzc29yIiwgIm1lbUFjY2Vzc29yIiwgIm5ldFJ4QWNjZXNzb3IiLCAibmV0VHhBY2Nlc3NvciIsICJzdGF0dXNDb250YWluZXIiLCAiaW5jaWRlbnRzQ29udGFpbmVyIiwgImNvbmZpZ0NvbnRhaW5lciIsICJhZGRCdG4iLCAiZm9ybUVsIiwgImZvcm1UaXRsZSIsICJmb3JtQ2FuY2VsIiwgImZvcm1TYXZlIiwgIkhFQUxUSF9TRVRUSU5HU19LRVkiLCAiSEVBTFRIX0RFRkFVTFRTIiwgImdsb2JhbFNhdmVCdG4iLCAiZ2xvYmFsUmVzZXRCdG4iLCAiZ2xvYmFsU3RhdHVzU3BhbiIsICJyZXRlbnRpb25JbnB1dCIsICJpbnRlcnZhbElucHV0IiwgInN0YXRzSW50ZXJ2YWxJbnB1dCIsICJtYXhFbnRyaWVzSW5wdXQiLCAiZGlza1RocmVzaG9sZElucHV0IiwgImxvYWRIZWFsdGhTZXR0aW5ncyIsICJyYXciLCAic2F2ZWQiLCAiYXBwbHlIZWFsdGhTZXR0aW5nc1RvVUkiLCAic2F2ZUhlYWx0aFNldHRpbmdzIiwgInNldHRpbmdzIiwgInJlc2V0SGVhbHRoU2V0dGluZ3MiLCAiZWRpdGluZ0lkIiwgInVwdGltZUNvbG9yIiwgInBjdCIsICJzZXZlcml0eUJhZGdlIiwgInNldiIsICJsb2FkU3RhdHVzIiwgImlzVXAiLCAiZG90Q29sb3IiLCAidTI0IiwgInU3ZCIsICJhdmdSdCIsICJsYXN0Q2hlY2siLCAiZGV0YWlsUm93IiwgInJ0IiwgImxvYWRJbmNpZGVudHMiLCAib3BlblJlcyIsICJoaXN0UmVzIiwgIm9wZW5EYXRhIiwgImhpc3REYXRhIiwgIm9wZW4iLCAiaW5jIiwgImhpc3RvcnkiLCAicmVzb2x2ZWQiLCAiZHVyIiwgImxvYWRDb25maWciLCAic2hvd0Zvcm0iLCAidGltZW91dCIsICJjb2RlcyIsICJzbGEiLCAic2xvdyIsICJoaWRlRm9ybSIsICJib2R5IiwgImNoZWNrQnRuIiwgImF2YWlsYWJsZUNvbnRhaW5lciIsICJhdXRvQ29udGFpbmVyIiwgImxhc3RDaGVja1NwYW4iLCAibG9hZEF2YWlsYWJsZSIsICJ1IiwgImNvdW50QmFkZ2UiLCAidXBkYXRlQWxsQnRuIiwgInVwZGF0ZUFsbENvbnRhaW5lcnMiLCAic3VjY2VzcyIsICJmYWlsZWQiLCAiY2hlY2tGb3JVcGRhdGVzIiwgIm9rIiwgImxvYWRBdXRvQ29uZmlnIiwgImNvbnRhaW5lcnNSZXMiLCAiY29uZmlnUmVzIiwgImNvbnRhaW5lcnNEYXRhIiwgImNvbmZpZ0RhdGEiLCAic2F2ZWRDb25maWciLCAiY2lkIiwgInNjaGVkdWxlVmFsIiwgInJvbGxiYWNrVmFsIiwgIndpbmRvd1ZhbCIsICJsYXN0UnVuIiwgInNjaGVkdWxlIiwgInJvbGxiYWNrIiwgIndpbmRvdyIsICJkY1ZlcnNpb25JbmZvIiwgImRjVXBkYXRlQmFkZ2UiLCAiZGNVcGRhdGVEZXRhaWxzIiwgImRjTmV3VmVyc2lvbiIsICJkY0NoYW5nZWxvZyIsICJkY0FwcGx5QnRuIiwgImRjQ2hlY2tCdG4iLCAiZGNSb2xsYmFja0J0biIsICJkY1N0YXR1c0JhciIsICJkY0hpc3RvcnlDb250YWluZXIiLCAiZGNMYXN0Q2hlY2siLCAiZGNTaG93U3RhdHVzIiwgInR5cGUiLCAiZGNMb2FkVmVyc2lvbiIsICJjb21taXQiLCAiZGNDaGVja0ZvclVwZGF0ZSIsICJzaWxlbnQiLCAidXBkYXRlc0J0biIsICJkb3QiLCAiZGNUYWIiLCAiZGNBcHBseVVwZGF0ZSIsICJkY0xvYWRIaXN0b3J5IiwgInN0Q29sb3IiLCAiZGNTaG93Um9sbGJhY2siLCAidmVyc2lvbnMiLCAiZm10Qnl0ZXMiLCAidW5pdHMiLCAibG9hZFZvbHVtZXMiLCAidm9scyIsICJpc1N5c3RlbSIsICJuYW1lSW5wdXQiLCAibG9hZE5ldHdvcmtzIiwgIm5ldHMiLCAibiIsICJkcml2ZXJTZWxlY3QiLCAibG9hZERpc2tVc2FnZSIsICJzZWN0aW9ucyIsICJwYXJzZWREYXRhIiwgInlhbWxTdHIiLCAic3RhY2tOYW1lIiwgIm9yaWdUZXh0IiwgInJlbmRlclByZXZpZXciLCAiYm9yZGVyQ29sb3IiLCAicGFydHMiLCAicHJvZ3Jlc3NFbCIsICJ0ZXJtRWwiLCAidGVybSIsICJ3cyIsICJmaXRBZGRvbiIsICJjbGVhbnVwIiwgIm9wZW5FeGVjIiwgImRpbXMiLCAiY29scyIsICJyb3dzIiwgInJlc2l6ZUhhbmRsZXIiLCAiZmlsdGVyU2VsZWN0IiwgImxvYWRNb3JlQnRuIiwgImN1cnJlbnRPZmZzZXQiLCAiUEFHRV9TSVpFIiwgImxvYWRBdWRpdCIsICJhcHBlbmQiLCAiZmlsdGVyIiwgInRhYmxlIiwgImRldGFpbCIsICJ0YWJzIiwgInBhbmVscyIsICJhbGxFdmVudHMiLCAiYWxsSG9zdHMiLCAic3NlU291cmNlIiwgInJlZnJlc2hPdmVydmlldyIsICJyZWZyZXNoRXZlbnRzIiwgInJlZnJlc2hIb3N0cyIsICJzdGFydExpdmVUYWlsIiwgInN0b3BMaXZlVGFpbCIsICJyZW5kZXJFdmVudHMiLCAiZXYiLCAiYWN0aXZlIiwgInNpbmNlIiwgInN0YXRzUmVzIiwgImhvc3RzUmVzIiwgImV2ZW50c1JlcyIsICJob3N0cyIsICJldmVudHNDb3VudCIsICJyZW5kZXJUb3BMaXN0IiwgIml0ZW1zIiwgIml0IiwgImZpbHRlclNvdXJjZSIsICJmaWx0ZXJTZXZlcml0eSIsICJmaWx0ZXJIb3N0IiwgImZpbHRlckFjdG9yIiwgImRlYm91bmNlIiwgInBhcmFtcyIsICJyZWZyZXNoSG9zdEZpbHRlciIsICJyZW5kZXJFdmVudFJvdyIsICJzZXZDb2xvciIsICJhY3RvciIsICJvdXRjb21lIiwgImN1cnJlbnQiLCAicmVnaXN0ZXJIb3N0UHJvbXB0IiwgImZuIiwgIm1zIiwgIkxPQ0FUSU9OX0tFWSIsICJMRUdBQ1lfS0VZIiwgIkdFT19DQUNIRV9LRVkiLCAiVU5JVF9LRVkiLCAiZ2V0VW5pdCIsICJnZXRXZWF0aGVyRWxlbWVudHMiLCAid21vRGVzY3JpcHRpb25zIiwgIndtb0ljb25zIiwgIndpbmREaXJzIiwgImRlZ1RvRGlyIiwgImRlZyIsICJnZW9jb2RlTG9jYXRpb24iLCAicXVlcnkiLCAiY2FjaGVkIiwgImdlbyIsICJmb3JtYXRMb2NhdGlvbiIsICJmZXRjaFdlYXRoZXIiLCAibG9jYXRpb24iLCAidGVtcFVuaXQiLCAid2luZFVuaXQiLCAiY29kZSIsICJ1cGRhdGVXZWF0aGVyIiwgIndlYXRoZXJXaWRnZXQiLCAid2VhdGhlciIsICJ0ZW1wU3VmZml4IiwgIndpbmRMYWJlbCIsICJsb2NhdGlvbklucHV0IiwgImxvYyIsICJ1bml0UmFkaW8iLCAibmV3VW5pdCIsICJvbGRVbml0IiwgIndpZGdldCIsICJyZW5kZXIiLCAiREFZUyIsICJNT05USFMiLCAiUk9NQU4iLCAiY3VycmVudFN0eWxlIiwgImxhc3RDaGltZUhvdXIiLCAiY2hpbWVQbGF5aW5nIiwgInByZXZGbGlwRGlnaXRzIiwgImFjdGl2ZUxheW91dCIsICJkaWdpdGFsUmVmcyIsICJ0aWNrVGltZXIiLCAicGxheUNoaW1lcyIsICJzdHJpa2UiLCAiYmVsbCIsICJub3ciLCAicmVzZXRSZW5kZXJMYXlvdXQiLCAiZW5zdXJlRGlnaXRhbExheW91dCIsICJyZW5kZXJEZWZhdWx0IiwgImgyNCIsICJhbXBtIiwgInJlZnMiLCAicmVuZGVyTGNkIiwgImNscyIsICJyZW5kZXJGbGlwIiwgImRpZ2l0cyIsICJmbGlwQ2FyZCIsICJkaWdpdCIsICJyZW5kZXJCaW5hcnkiLCAiYml0IiwgImNvbCIsICJvbiIsICJyZW5kZXJBbmFsb2ciLCAidXNlUm9tYW4iLCAic2l6ZSIsICJjeCIsICJjeSIsICJzQW5nbGUiLCAibUFuZ2xlIiwgImhBbmdsZSIsICJsYWJlbHMiLCAiYW5nbGUiLCAidGlja3MiLCAib3V0ZXIiLCAiaW5uZXIiLCAieDEiLCAieTEiLCAieDIiLCAieTIiLCAic3ZnIiwgInRpY2siLCAibmV4dENsYXNzTmFtZSIsICJzY2hlZHVsZU5leHRUaWNrIiwgImRlbGF5IiwgIlNUWUxFUyIsICJzdHlsZU9wdGlvbnNIdG1sIiwgImNoaW1lc1RvZ2dsZSIsICJ2b2x1bWVTbGlkZXIiLCAibG9hZFNldHRpbmdzIiwgInJlZnJlc2hDYXJkSGVhbHRoIiwgInNlcnZpY2VJZCIsICJ1cHRpbWVFbCIsICJiYXJFbCIsICJ1cHRpbWUyNCIsICJkaXNtaXNzZWRVcGRhdGVzIiwgImtub3duVXBkYXRlcyIsICJyZWZyZXNoQ2FyZFVwZGF0ZXMiLCAibm90aWZ5TmV3IiwgInByZXYiLCAidXBkIiwgInVwZGF0ZUJ0biIsICJzY2hlZHVsZUNhcmRFbmhhbmNlbWVudHMiLCAib3JpZ1JlZnJlc2hBbGwiLCAidGhlbWVCZWZvcmVCdWlsZGVyIiwgImVkaXRpbmdTbHVnIiwgImFkdmFuY2VkT3ZlcnJpZGVzIiwgIlRIRU1FX0xBQkVMUyIsICJGSUVMRFMiLCAidGhlbWVCdG4iLCAidGhlbWVMYWJlbCIsICJnZXRMYWJlbEZvciIsICJ1c2VyVGhlbWVzIiwgInVwZGF0ZUxhYmVsIiwgIm5leHQiLCAiYnVpbGRGaWVsZHNIVE1MIiwgImdyb3VwZWQiLCAiYnVpbGRTdGFydEZyb21PcHRpb25zIiwgIm1vZGFsSFRNTCIsICJzdGFydFNlbGVjdCIsICJlZGl0U2VsZWN0IiwgImV4aXN0aW5nU2VjdGlvbiIsICJsaWdodEJnQ2hlY2siLCAicGlja2VycyIsICJhZHZhbmNlZFNlY3Rpb24iLCAiYWR2YW5jZWRUb2dnbGUiLCAiYWR2YW5jZWRWaXNpYmxlIiwgImdldEN1cnJlbnRDb2xvcnMiLCAiZ2V0QmFzZUNvbG9ycyIsICJ1cGRhdGVBZHZhbmNlZEZyb21EZXJpdmVkIiwgImJhc2UiLCAiZGVyaXZlZCIsICJoZXgiLCAibG9hZFRoZW1lSW50b1BpY2tlcnMiLCAidGhlbWVOYW1lIiwgInVwZGF0ZVByZXZpZXciLCAibG9hZFVzZXJUaGVtZUludG9QaWNrZXJzIiwgInRoZW1lIiwgIm11dGVkIiwgImJhZGdlT2siLCAiYmFkZ2VCYWQiLCAiZG90T2siLCAiZG90QmFkIiwgImRvdHMiLCAiYXBwbHlDb2xvcnNMaXZlIiwgInByb3AiLCAicmVmcmVzaEVkaXREcm9wZG93biIsICJzbHVncyIsICJyZWZyZXNoU3RhcnRGcm9tIiwgIm9wZW5CdWlsZGVyIiwgImN1c3RvbWl6ZUJ0biIsICJvbGRTbHVnIiwgIm5ld1NsdWciLCAidGhlbWVEYXRhIiwgImFwaUNvbG9ycyIsICJzbHVnVG9EZWxldGUiLCAiZmFsbGJhY2siLCAiZXhwb3J0RGF0YSIsICJ0aGVtZUNvbG9ycyIsICJ0aGVtZUxpZ2h0QmciLCAiY29kZUlucHV0IiwgImFjdGl2YXRlQnRuIiwgImRlYWN0aXZhdGVCdG4iLCAiZXJyb3JFbCIsICJzdWNjZXNzRWwiLCAiYmFkZ2VJY29uIiwgImJhZGdlVGV4dCIsICJkZXRhaWxzRWwiLCAiZmVhdHVyZUxpc3QiLCAiYWN0aXZhdGVTZWN0aW9uIiwgImN1cnJlbnRTdGF0dXMiLCAiaGlkZU1lc3NhZ2VzIiwgInNob3dFcnJvciIsICJzaG93U3VjY2VzcyIsICJyZW5kZXJTdGF0dXMiLCAiZXhwaXJ5TGluZSIsICJmZWF0dXJlcyIsICJhY3RpdmVGZWF0dXJlcyIsICJ1cGRhdGVIZWFkZXJCYWRnZSIsICJhY3RpdmF0ZUxpY2Vuc2UiLCAiZGVhY3RpdmF0ZUxpY2Vuc2UiLCAidG9wYmFyIiwgImljb25FbCIsICJ0ZXh0RWwiLCAidGltZUVsIiwgImRheXMiLCAib3BlbkxpY2Vuc2VNb2RhbCIsICJyZXN0IiwgInRvcGJhckVsIiwgImZlYXR1cmUiLCAiVFRMX09QVElPTlMiLCAibyIsICJzZXJ2aWNlTmFtZUVsIiwgImlzc3VlZEVsIiwgImlzc3VlZFVybElucHV0IiwgImlzc3VlZENvcHlCdG4iLCAiaXNzdWVkTWV0YUVsIiwgIm91dHN0YW5kaW5nTGlzdEVsIiwgInB1YmxpY0NyZWF0ZUJ0biIsICJ0c0NyZWF0ZUJ0biIsICJ0c0VtYWlsSW5wdXQiLCAicHVibGljVHRsU2VsZWN0IiwgImN1cnJlbnRTZXJ2aWNlIiwgImFjdGl2ZVRhYiIsICJfb3JpZ2luRnJvbVBhZ2UiLCAiX2Fic1VybCIsICJ1cmxQYXRoIiwgIl9mb3JtYXRFeHBpcnkiLCAiaXNvIiwgIl9mb3JtYXRSZW1haW5pbmciLCAic2V0QWN0aXZlVGFiIiwgImlzQWN0aXZlIiwgImxvYWRPdXRzdGFuZGluZyIsICJmaWx0ZXJlZCIsICJyZW1haW5pbmciLCAicmV2b2tlU2hhcmUiLCAiaXNzdWVQdWJsaWMiLCAib3JpZ2luYWwiLCAidHRsTXMiLCAiX3JlbmRlckFwaUVycm9yIiwgImlzc3VlVGFpbHNjYWxlIiwgIm9wZW5TaGFyZU1vZGFsIiwgIlNUT1JBR0VfS0VZIiwgIlNVUFBPUlRFRF9MQU5HUyIsICJMQU5HX05BTUVTIiwgIlJUTF9MQU5HUyIsICJfcmVhZFZhbGlkTGFuZyIsICJzdG9yZWQiLCAiY3VycmVudExhbmciLCAidHJhbnNsYXRpb25zIiwgImxvYWRlZCIsICJfbGFuZ1JlcXVlc3RJZCIsICJsb2FkVHJhbnNsYXRpb25zIiwgImxhbmciLCAicmVxSWQiLCAic2V0TGFuZ3VhZ2UiLCAiaXNSdGwiLCAiYXBwbHlUcmFuc2xhdGlvbnMiLCAiZ2V0TGFuZ3VhZ2UiLCAiY3JlYXRlTGFuZ3VhZ2VTZWxlY3RvciIsICJ0YXJnZXRDb250YWluZXIiLCAic2V0dGluZ3NCdG4iLCAiY3JlYXRlRHJvcGRvd24iLCAid3JhcHBlciIsICJkcm9wZG93biIsICJmbGFnIiwgImluaXQiLCAic3RhcnQiXQp9Cg==
|